From 9d0a22e3bca56c7556aca87e9eaceffeecdba37c Mon Sep 17 00:00:00 2001 From: Dyzer <108179220+iAmNotHomo@users.noreply.github.com> Date: Sun, 2 Jun 2024 16:37:10 +0800 Subject: [PATCH 0001/1065] =?UTF-8?q?=E6=96=B0=E5=A2=9Eu2dmhy=E7=A7=8D?= =?UTF-8?q?=E5=AD=90=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Pagetual/pagetualRules.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 0676e4b57ed..27323cf9aad 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -1,4 +1,11 @@ [ +{ + "name": "u2dmhy 种子页面", + "author": "dyzer", + "url": "^https?://u2\\.dmhy\\.org/torrents\\.php", + "example": "https://u2.dmhy.org/torrents.php", + "pageElement": "body > table.mainouter > tbody > tr:nth-of-type(2) > td.outer > table.main > tbody > tr > td.embedded", +}, { "name": "Qi Xing Blog | 一个互联网角落的秘密基地~🥳", "author": "qi_xing_jk", From 22f64341864f420b4b750ed03159c5b4fbe10263 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 2 Jun 2024 08:44:36 +0000 Subject: [PATCH 0002/1065] Update version of Pagetual rules to 20 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index d6b24041cf0..209e3ef4b62 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -19 +20 From 56e8cba4f66ffedbd01d1bef9fc76e8edc39e02a Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 2 Jun 2024 17:33:54 +0800 Subject: [PATCH 0003/1065] 1.9.37.49 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 82e7a3985fa..e5aa2422529 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.48](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.49](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 8a3966b34d4..f78846aa3f1 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.48 +// @version 1.9.37.49 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -1809,7 +1809,7 @@ } getPageElement(doc, curWin, dontFind) { - if (doc === document && this.docPageElement && document.documentElement.contains(this.docPageElement[0])) { + if (doc === document && this.docElementValid()) { return this.docPageElement; } let pageElement = null; @@ -3385,6 +3385,17 @@ }); } + canListenUrlChange() { + if (this.curSiteRule && typeof this.curSiteRule.listenUrlChange === 'undefined' && this.docElementValid()) { + return false; + } + return true; + } + + docElementValid() { + return (this.docPageElement && document.documentElement.contains(this.docPageElement[0])); + } + urlChanged() { urlChanged = true; this.clearAddedElements(); @@ -7159,6 +7170,9 @@ clearTimeout(checkUrlTimer); checkUrlTimer = setTimeout(checkFunc, checkUrlTime); if (document.hidden) return; + if (!ruleParser.canListenUrlChange()) { + return; + } if ((prevPathname !== window.location.pathname || prevSearch !== window.location.search) && window.location.href != ruleParser.historyUrl) { checkUrlTime = 2000; urlWillChange = true; From f56f56b92b05ffeca5e30401d0c0d724f49ce3ab Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 4 Jun 2024 01:57:35 +0000 Subject: [PATCH 0004/1065] Update items_all.json from http://wedata.net/databases/AutoPagerize/items_all.json --- Pagetual/items_all.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Pagetual/items_all.json b/Pagetual/items_all.json index efbbe5a0146..a378901834a 100644 --- a/Pagetual/items_all.json +++ b/Pagetual/items_all.json @@ -1,4 +1,19 @@ [ +{ + "resource_url": "http://wedata.net/items/86231", + "data": { + "insertBefore": "", + "pageElement": "//div[contains(concat(' ', normalize-space(@class), ' '), ' article-body ')]|//div[contains(concat(' ', normalize-space(@class), ' '), ' gallery-image ')]", + "nextLink": "//a[contains(concat(' ', normalize-space(@class), ' '), ' --next ')]", + "url": "^https://shueisha\\.online/articles/", + "exampleUrl": "https://shueisha.online/articles/-/250383" + }, + "database_resource_url": "http://wedata.net/databases/AutoPagerize", + "created_by": "altpragmatist", + "name": "集英社オンライン", + "created_at": "2024-06-03T11:08:46+09:00", + "updated_at": "2024-06-03T11:08:46+09:00" +}, { "resource_url": "http://wedata.net/items/86228", "data": { From d44a7bbcbd9d00fddba3e0cb44af9b068b24abde Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 4 Jun 2024 01:57:57 +0000 Subject: [PATCH 0005/1065] Update version of Pagetual rules to 21 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 209e3ef4b62..aabe6ec3909 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -20 +21 From 10e1343f2f0e878a634259af06d921d80c301c33 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 5 Jun 2024 08:15:35 +0800 Subject: [PATCH 0006/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 7e39bc9eb28..50f7cb53b55 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -340,6 +340,10 @@ switch (lang) { "name": "谷歌翻译图片", "url": "https://translate.google.com/?op=images#p{input[accept^\\=\"image\"]=%i}" }, + { + "name": "一键抠图", + "url": "https://www.remove.bg/zh/upload#p{sleep(500)&body=%i}" + }, { "name": "WhatAnime", "url": "https://trace.moe/?url=%T", @@ -1281,6 +1285,10 @@ switch (lang) { "name": "Google translate image", "url": "https://translate.google.com/?op=images#p{input[accept^\\=\"image\"]=%i}" }, + { + "name": "Remove bg", + "url": "https://www.remove.bg/upload#p{sleep(500)&body=%i}" + }, { "name": "Google lens", "url": "https://www.google.com/imghp#p{sleep(500)&click([data-propagated-experiment-ids])&[name\\=\"encoded_image\"]=%i}", From 67e455622e88761f074652a4524ac6f1cb2bcc3a Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 5 Jun 2024 20:23:13 +0800 Subject: [PATCH 0007/1065] Update customRule.png --- Picviewer CE+/customRule.png | Bin 23609 -> 41433 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Picviewer CE+/customRule.png b/Picviewer CE+/customRule.png index 301806b7a3846619ec844b05697e6bf1d32bf5d4..b72b9095c23baa5447642a5def71b720d3557f0b 100644 GIT binary patch literal 41433 zcmd43XHb(-+b*gCHk#BRQWQi~sv^Ba1Vp7vmlB%v-g`tuI*5pXGy&;dq?b?v0qGrS zfrJ_e5Fmv>lEeFbd(PQ^&YwMJ?>W!Rnl<#h{(M9-r{pv-^t);Y%i|De?TlE*0sz>Hl1Onok0 zV)p${xV&P|8+hqbzWZxcWrILVG>I{kZ6*guhP*YONK1>8y6-BUNTXpm`Ij=z9L4T< zc2|vMTymnwz#4d_MhgE<31!}H`V#tqFSPYtV;)V_?sur+t8bq{BI6%FyNlj@A#I>> zdGO_1mfy_rGgY;%_<+$&34Cs*JYMJPpqBS>@Daz;fcAN&0ryyDhy<{ummcQ@wZ zD;-iQqA)WtG3f!G)bd??M>nX1{uAek|F4-nDOxJxcCQM0(HW+J03OnQ>b&0{`t%by zz6R^L(2&fad2CYdQUzD{=6JXpd(Fd4(cJ3ZYQgWemTQ_zJaP;wo@WVd;vPFjdvepC z;)7RA7RtAxzN7cVYg)BxssdU9gMt2)fS_j~%r9^6G#r&)kq`H}2>{MY2u{J=N<(ZU zoROi`iwtgkn~Ih}i-1nv7`f;OHa}gKq;~UYZp6oC&;Ey@Uj8&F(e0)f=5hb+*9vkW ztlke+qN4bo*MyzM$W-+FNSe*Z!7A!Jap-~D(u`(|*wLRQ@)mL(v=xRt%kk>cu?lj& zZ$9x^8}YdH7veQvjJgF_`(evCfZpeRm_wuCtY0#DCTiGD<9%7#_rD`)=5bjL z;tmv z9dY7}fw3fqsvxNO0Eon*fDb_4bMQ(PFe+r9F2^))d9W4&+f+ffKgiidL8EwV@3IdeM;Ib3Pgl3S`!DlXQ_LOXz5Fre_wqM{7p6E zt6+eA+)2R>1d))&R%+i`P1s)Lh;v8-!gv=O$CyAH-#=r4eHFq-B@chteX+Y{h~(+< zIm?Y_GI+i3qiH@4sC<3eC8IN7!9^P~i!wij0LT*s+5bvNLr zGK8-nx4SD&PNdE8GW)0MM0u}uEyXu>t+l*n8UZ_R(=aAYr)L@Ag~3e5{u2)rFx+SN zE7bn!`@MG2VAUenGg3SPW&CWSc{E@juWjA^9V+_Pe~`KIP8BG7KKZjQ+hZmy^;M&3 zntubMQ-w#rPh)uu?b4JB0!ZenQ)2#BSpER(O_`9)#V0;wZ`UfNk5YIGope;~yAl4+ zda>q9qWSL24?9-m>kQMc`)*fvC5shUj~NN)fdLN^e>W-K2#9^AbQ?Qb`C#wipE(HE zS>X!8epH%z2+TvWY%T_OYK#Q{{8d{%SO%9c$akJS-2dSf;+S(J`deKZ-IEev6D_bN zzgKDNzvC++B{m-LYmgLXC*hy-YTdG^ET*@udXYz_H4-+1~S(s384Bmee&s)+~gNb^&)R|^B9)s61`ZF`a^Pp=+ky7HcI zAD5TZSW7aktGHbBPPl#K-3s}9Ub)1A{^5*hEigo-_OvvYWFKfc7FjT}?BdD21? z_T-D}y7t%%5~$Yeq=@pzuyR_?B71anK2=wXYRUX58Rg_w3<;Et@Rat#6=z5B0@|HtnPIpFk@=c!VN0&WjZJR^ll?*9ms z-w(4B@|W4SPYcjE=$cjE@B5W9+dBWWfMR2%mJ_gM$YiqZwH~kvXxx~@R5dp}r`D3o zcth#o5)MY(Zf`zQYbT7sVJe_0wtEh0R{Dq6{iCj=M+{Kds3TxnLf#AVzH#Rj7o+G!Lbk-VlZ>*Uo99Zct z!b8KCsEDDLohknJ9)~kk)HEkGf8x*TjC!5CH@@{Bu!cXCsmZibCL zvxf1*d-y5ar-Sv`^KnsqW>u3_Cs|LnQVw?i3}6+K)YPPRZ5^t1>s08fh(Z@j=QSdp z2m^jv=A#B>MLuE@cvu$$`XXes%SZ6ltO>kbL*A9D6ngZW{4I2SEciMcOcuvgPjcV= zgMRT3*$>!i-U(C%{aVZ|kJn2KxKYDH7iIWxVE4I+pEb}34$7a)Ns`WB9UbpY3^gT2u-{&d~Q1i#yDtubu%K)@*uR z#&d33bsIRqZqWnZ#YBzmMD>ew$Co4{GY^)NuVkj{-}Hnuf8h%E6MN$qiQ(Vn?Lu)F zCOy66!lInk&T`PltMF@>r!xu zo0&*^#Kgh=b9C$j^S$*3B4W%K8G$A0e^t7c3?X_TnnioEYX*;PTW>Pw%7=0-zNs8j zU-UtQ5>tX6F!qn2%zwm;MI%t%g!4dIEe7d$W1GLPcCpZ`-fsMAmLMwV$mj4&!?MUhLEH5y;Ri^W^S?fXPD1_@ zi{jT|V=-fg$?ICoZZh7_-c3>B=PAR^Bn#aSFg&+WcWD}X3(sk!MkwgEw3%yoILJnz z_nS9|i5@I8kV#8D!20<7b%qmIFTUn$bSDcLn-QZSb^vv@h)O5t2-c!Kd}aXkQ_mAX zjW>4tO=}jy+o{e}&^+Ex-Y1FH#~N}!thk&vj;!CZd3o(4QhEzzF$)m%xwFimlSyF^%v$Ge34BF;0pL z7Q;A&8;n_d?Ys1odWX;z-4BJ?iXXXk6ykycmXfkHD-^#4A9d&J-?;jYe!hKfsIT(u zI7LzW{IPHgQzURQHEKzID=wgDdnN+FxPQZtY6bMng7QNX%CrY}j^@VO4))B4`EINn z*Jcd;E_`QXHh&cvAB006@?6$04NGhONgj#JXL!R%!UY5m&wk(^+nG==wk=4>XiN`? zdc)uYX`=SAS@sGb`7U{YVzd<^NOcP(VapcF^J*$UZlnzU>A_x)Ld`LV&OguNIgNdA zyI8cSBA+^q49v^BNsrt83p#%~mC;^@Ib!yq=3~o5ZgpGNgY9qyYh&1V;qKm4o7}-> z%EWkPf`wRsHSnCd#A1C*U1!3UFUh-sJ~fXr5)3$^%&83Eua^rW)RzK!^44DQjqQmg zcR|+drg7%~njxDqxY_m?2cF&eWUV*cbd{yYlgD+AXVwbvwIt=N@mlp{8@UHir+`$_ zoEU=83BVv&c3+^Mf19X3{NjGFX2BiER72_!-Du&RI+pV^1)j-&%Ki0Jh_?k(E?zy> zN8N@VbjS3$Ky`NbYJaO#KW_;P^b^=xmWJGp`M4RVT%8(|Xz z2O2W}Zgo<*5DA2QUBZj$&ng}-J@nst`oPP%#nqsw&Rk$2#VklX0mO#K?$T*nM6wkHUQRr)4o zVNETvMHxrCX+IEMDc(=m9j_hd=jgBzcR!J%^oc96E}0oBSspKOG}!%OsUCb;?b>?` zjh6}i%`GCxXj^mhPrtm9yjEH=!mLl{rNKcXNy+zt?O`;c9Va8m)q8_~UJ27E(;I9= zG|Zt79oZLh?@#pN_4}5TP^v|9l@DwgRH_IVoh`8Gw#az)RNr{yo!jb?fc-S^fApK+ ztn~yxzR=27>Z)Zv09BeSc8U{{2|<}#aI%_m2V!)qMCsqazSd~%>6ZN{bQ=eX!7S%2V@1NaeFRi%8bMA!(>&|I-PkNk(HWRUXr=3%q_rv67gK{V~ z4;j;(my*4c@f+hgW87RB;S&87&t1flnsT5k^u)~@`RH+P1A`w$U+g_E@0p;yl$xVY zvwDG#EtSM($Lk-gWaPu-%GtJ568`~{6Q~(p6BGUa{f@q~wHmwNX0je^^TANkr6FQS z6T*%EOYTbG6`Q7r*A{fT&HD~Ns(ZPZyAa)~3-!O)wEQlmkS`T$ZvR8&dNy6`*;UHm z9ZQ9%IbYppB!BL}FzYKkZ~0$JF3bCs&Md!M*Wu=6Fd%-+^2UfL#--okD)NkV=}Cfo z=azNvs|Gz&_2*d3vq(w8(DK4oz~K*lE%)G!f(6s%5aM<_4`#3{#i!OC|N2=ck*~3; zmG>0n3FgeI1>vqqx%07;CC+}MYA%j6UTKa~3BS~-#=O;W7h=WU3vQh8yTTpD(QOmJ z<(}2uUXiY2uqPK9jppY3zAazzBEcPyOLv}yjS6YK3^df|>G>p9%2cSea`!3>p_W z&WYmf{?vP%8#;iQ?$(NoD@(I)X-z%|a954qj1 zuDJ7X?@MpBs02#xV@ofa9ef$1ZKDlPJi5=xw?F!{)k2r?uOzYNN3P5HB#jb<=B&Cy zMaJv#(#Q)tkKIYDB`)W5!{~QRrTso$V}<42RW}Xr&^$=RB!qmIeW%?uq~HorVI?B| zEZQ&7+k%iH!??VdA}T@r?&`&bMlRO+38HKi3;NJ6s8D;2{)P2Vrkf8|kDH>7UAOY7 zuPm~dd6f|F`2cv9XU9t_>fJk+iGu>byt8DO?3`E*)WtvjfoOWt!HcL+?X|tvCL9$) zi4p%Yj#sacUSuEe;!B=?cfC05uF>^>l1KB{avnmfTRA{0TJ!j93rjCxaRR#?zQ zEzH7t2hroS+;1683c-KMWt7>V&1-u3C!%R-<$u5r!I_$>AEF z3ZrzvPGJdqO6xAc?QTNsqRS~(SqH`q9U8bo=94yd5K}?K`b1=9scGxK2NvQC99EC+c|AZFM!-Q&p+taQxBUf-O+$ zaa?k54!S5Spzkf@0>%l3u9`ANg&2Ts?(tw;w}Y6}r9_~G#M8i*3Z9sS_dQ*YBz*6% zV1`a8t}_8takRu??I^>Z=j*`cN4_E0l*u4H-pXJM!ARk^O*;Aah}zCkOA>SGm#ku| zBzHzbv(|Sdn0xE+ec};!=*4V3eT-h2uvKt4C~kRZQ59L;D2N#dc-&5vo}8t7w*0=d zwyh|`B8f)->v3OR*ujD)+u#NAwmXEkInL)8>vpN=-9%)r!A^dS>2=tLY`T0+1kGBY zlYc)6Fm!UvaT`;NdkyLUR0t*i92B}sATa+(+V4XBvsV)7SvY7OJ&iaushx1w2%xUm zYU6R{@n)h222&61`6Y_>P0FUY5qoA_UVOWAW0EqNv4aHer0|Fb%CVEg+BDd?D}&cJ z`qG7J55Wrpg*@vHa}2=&>G{I%dQTXWt&V?;5Y<6s@(D zU$l*RPzg2Sm3aZTc}XxUdwJWxo3&`^F{`9Dx8cRMT3w}P6L7Kv7=6!hMnW#^u4qHf zb2Jbb!R;@WgM3qmr}4TMKLOP3WeGrx9&ie1fI_%ndC7iH*g+pv>b`JTT~-c8a+Zius3IA>w+^k?4KXWu!U+Vy|c zJ$RZ(PjO(~H+QHpB#invh6=xA#PUj6?S2fYC2rxK9z`@TTJO)P^M|bp{2^W7%1Znm zRC69f&)>rvV=NaI%eSnjuT*@h_03b~Kd&Ynvib{?*m)YnmcEAGb)WFnwV3*fm&5UI5R>T0rP?1`z~`0T*S!FLTS2 zIHys!;{l65eo6(J9-}p|^Fwe~RPoaASrjFUd=z#aZSD)Vw8}oX#uUn!X&v?y87|nD zW32RZ>AKQ}th9${G58TT6?fj6@2`>}2fM$Sd{e$V1pCn43S7NP)j@@9eTh}v@N=eb zoumqt(kcdU|0Hh^69w0Cu4I8w&*{BbO`^5T7cg4XOguYckR#dXHH9drKq*x7Jc-}w zJAVo&26}OgWsaH0-vZWt73EopQ|GlrpMIFDb!Bx8yqYYQFje2sd_92~aQW;gt&{jZ z`@C&n=(H%^n7>}!{0TUE6rZ#^9m17N5AQqcZ32pFc z8v;LX6q&KKwuyz{!uGl5ZV$zHJFj z5#;IXIhg$%X(T4iwtBY63sY%QmxYh+cXc3nqUu9oq}v`nNg?ixX;Oc}z-js@B#|pq7c@|F%OaVY{P)v#KHN&zu*!25JX(%zL zUcM!8$vc$-B$&x`JFS!(VsN5@iU_bL}V0fLM`7RA!9 z?ybC(bCi_u4>y0YyB{Uh1FrsSrtI|2<6cGZFE==_(6WXFXo<2LcElma+IZ;iD*^Dp zBN-T3AgV{eMpTwk zaX@|+J742PsRgXFjUo4rwiZdlMf{W+-mdH#Exl#U0a1O14)b^m;7ZNGH%(YJI;5^D zhAm<`=)X#ivgj%M`@R{U!d=&v`DzSS5O+{mxowYARI}*mii?SP3y;#D2a)dkpHonW zsC#Ytpnq>nNSvEm=n*_}X=s)W+^c2ksG=iDbC z%l_P>yZ>N9EpUlBYu9eggm#25L+2sq=x!N1X+^SYqd&4VXy#P(v-b0~=`7FF6U)8R z-t_6M^YavNcX!jtSx#}&Sp*oqp;!b{+RcN|YEbN@jywkYe+ps$4DtTl2&l2y0vfFL z!FQY%2HG?*5PQZR4Y+00*2bp|9c0&B{lv+!QwAkWQX}vFF$nscm_s$eQTq{;pggM=8h6 z=Ub*6@=_XN%A~&2fQ7>wSJxymM`?G{dL_h7LZ6Q1vgM7sOr{7#3ae~7sNTnU-C0Qi zwRmttA?NYDMTXM?w&@7)SYFIM$L@SV@>TfbaE^*uBHzweZ@p8x{c&-N z0w!4IT7H%jeqVltfBSLqK*84KX7_b!&1S>%o>u1%&7Ri|_X@+Z_3+=%mFYcGx z86V6jM{)!I4hPi(5AYtVo~zG9QC#uw*a8Uw9KO5hUrqrw%5_Uo_3BJA_C|%~QNv3L zp-xbGj?g0WmczP?8jK-Va0iW%>7rH!(U`?^By(=!JX6eidi6449XN(C28L;c-fuP5 zF;aWvG-tafU1GZqGG~V!I3Nh7vIQ}q!9u}={?e0fBf}XOz>7Rx!{k_dJo5CR%d`Hi zq@Hn?s&mph=~(7;_mXzI?O4$<{zNE{yU7|6v+I>+0v80kcGrNhH?_gpiS6kHz1cOI;nZ zJ(-}%4oBazWDH~Y)XkqFy<=ntauCLAvv)qx<}Ja$v_W;)diAz|thXRiyHQXEUdylawQ*uDG5ti!% zu^^Cod}cdSfYnj@Q;gX+YC|YROAx8zyN$CEj?34sTVz^z!W9`Ce))!9MBws+jaz`o^&yMo3bn$=dLzPBrft{V-Qn zqKjxeEw%3kj$JR+(Mr!b71e5$QyQJl0ujNErOrl3p zAGQ@8+oa4Pt2cZM(vrEC&SLy?S3R6YqS!88BlZ0@v<8`E_SvQ@#Gy~228op(Lv#!o z$DZzYO;3y-;gs|4#Ahj`>;_Y5C2qAUmZE};*NWv2ZYie`F2(Z92L3l)-aY7Vmr-<}wzT9(T2)Kc^n?z@l-|+&+@O z1(zfCgvQKHk9jFk%Dw$Ie@`+qo?wE{w;t{Kcw+SDY}da%;&`9;_ecUeQ#U|9fysd1 zty4U*FoRfI%#1m|PNYbnaW)6lXFAF9v)|%-!CppxB#|9B`#%=UaG%VVPQ@AcDZX2+ zZ*&D3&U?i$ z{nrqMnLhIN$Y+*{hZ=@jF+j;O=Uz~I@WKzhfm|}TCf9U9F|XXcSy`DoAX3)br5bp; zfSnG7R7gN2+H?pqtfikZt_4<@xc4X$R)8XXs)||ONY>C}32zIVTxob0#+{+ORiARR z5-N6lga6uEYU3QHK92?(wfcu}iwBykcw}?$N`crr-tF!}!5G>zK^gFgLtvR@=&DXU zEv#E{e(J91Bk&VuTlb`}2+}s3vA`bg5~v~?u&T!8dVbxQ;ZEX&%6gk=v(tRu+R^D; z?ZHn%!Iv2k`WowlF>oR+A`(crigA0-oDyOMF;6Eni0Uk{29V}!tb4|V49VvRzg=ec zAs%UVm74QQCE!O#2Gj~AYPr;w3yH=n?5Fb204+N<#eZBA+QJ@IpC3NM&GE1TSTZ4( z+YN-mQ^I`(J|~Sv{WA#fDp_HH`~bc9*)0dSLJ z23;1!?M=X@iIp9MUD`EUXN?d>L0ku)Qq$8f^6~L#hw+on>vYk}>yB`VlX}zUBP4sa ze2L%*EtU8xBO(MXaN6+z5^zOE=wptu3Yks|vJ`0yJrx07gM{j54?g|EVJ}joqz`@o z)R&`dIBXQn9a=v8lcMz8C#!kVQbIM9d~(0;A2bqjfgwOZVlVC|i}wwgNY6T`-gdkxNv-K}N^Q;=|s zt;-wMu|l=0Z>gR>Iod}ClCQB50=x*A*YZgXr6H;Sup`61`qiX_1~tP#oiN(S!D&{wDw> z0{YQ2uy7~vGkl$};ME$_6ux_2=0mRXu?az>V-t_A%qDcv%Io#AJrDp;xNWVAxQt|tX+e;(F9L~vBCA|+&bv<$7=-{Ppz$x&gE@flB z47O0ki0N!=b{;SpCRRXtK(e1rIfTG>+bLIZ2SmVL(DICU3);dE<+s6B2M#rqwn0CiazM6?Eae9(3I6TTRjNXLaE1pi%RLOF#z-z zlaE>^R>Bs~E!z@wpaE>;dK!v*sHG@mv3m3Lo7^T*!mk^fN!%9ZgeJ31g^ak_BOK`F-E2D?#c&;na_C&x{O8RK{LL06hn|pwAt8cfvo_DzNj_g7 z%V5aRsVRATILnb)xlp9;06XNUBsP}jX(pc5@6Y5Jw;Fm#FZYr6>xCQqr(==1oI{g4 zNaYX^{4BR=al`8tB6Oo6ySCz3SUy|~e9qYO#q|`$vm{!9Rl1dT5DQn{DW4oaY^YFs zE>!I+y%L_BJ#nPWvT}VJqf`x|F#;Dq4y45372V$kQFOq}6h^3IBw5p(6}rs}Pj2r3 z5|qgIf#b#?ekI~W=qJX$Ycp%h`02h)luN>t9Quv9UrzJggmyMtL7l$gw$5UAv!srF z)&~{$J40EjnJ;g;Kth*qvpzCLj6uCx&S7}ywaE<<;|u_m1{U?+{|jV+)1-T0I$~Np zF)EVjGX1kI0uMU_`D28>BBfL@d>dkubF1%ebYG-%!ug#kh!9lYB5+V-in-_e>Hbqs=~-^KwL1w-}Aw9_aν+;s%6Sql z6ha~&(Z#Io;{8a!q&TO2ebaukHw!Z;3G4(fnI9qHx290pIiB11CH&?iJBv|LH z=MKHq@+5)MSbVsU!SElXXQurprtS7iWv9DF zK`Fm2qV@*s4~>2Hdn#+fX>1|)&pL^$O3rdM;i|qdduIC}a$iVkJj>k<_;pi9Nyk#* zh7az%Qy;+x#xoysP8_K2f>j>8q@D#p^(ZF}o*QYV1Gh56Frhv&ciWZ{jDonTSuSH% zH4RZd%G9>Y$fx8X;$t*Ny-3Czq`ITa>GNO57NG^Lsm;u$DjP`+1+qs0rf_^P%StNm z+E^$%yslW)i}5LtpB(dZ=Y)3ln`qFPLxz;w5B%Y(ZE*4QWX+WdN~>`10i>(JK9UZ- zQ1O1_I2vI*244Gp{u&RMlUs0m=rs4v?~FJ2n|+jdl*4}!K5kaKm zdDR#!$zm6(pf_}#qBf#*oi9h&OgCo6!p84wgh4$B*?Nz8S-g=ln$2FflmgF;=j%1H zVe&4z$5S0L1P_rl=9Fe7X!H^6lc>mcHsfL2ORqkN6s>gJT74#!=jqbUvx}Uyu6CAUi1N*sb<$4?QhY$#(Zb9DWkLll1+$B2-n@w zNU1;6z^+9I0CbnC-fQUk)_ePLfcwkugjl?#OC@5gdw~4$-z5ubhQj(j3SeUCzEX8w zi!zPr0r~7sv(@=yPVv15bP{*$a4bpvC`gi_*LZ?Y6+#2^nTZ4a(De3);YB6Eqm$nR zJ^)~T)5nns5WlOQWZ-Ve3NT_$JKpE`v)GyoOTG92vU=|F z+;W`Qj#+upuF|nn$}w;LhJl2VIA57E|L0!6Gc~%ciRtr{EeCWtll~L@N=pXul#su& zQNQJRPlm(PR-KO&mps0d;oaop$3n_%UBPC)xf7St+Y4JLE}xvN?j4baf4H2!FuvES zVbRdrikRXEDy+0U&Y#|DCkV&;H3Nr?!}i(jZo|`J!)nY@4a{mIb~wUPWi%*ANSqlp=Ho^=?-*oA0AojTCd4>tXtr5*`)b+hF3s zT1E!=+WsMzyP*K5mO2P_Iut2>R1si}nm03S%Wd}{&T&_J6$Stqa zA1N7@;%v4aOhMUM(H^Wz5qlM?hgc8TnQ}TCcfcAJbk}pApYHGJP5Y6|sGZb}Q=wz` zE5+f3w|pFu`p1RDkR4MsNO~{juo^TYqSPWPMc>}$DGuX(#-Pt;A{^e!}o$dgd$hgs%Zy7C&P; z>wx-xBO_?eU}+u8UqezLA7Tuf$r8pFo_>INaud@iB(gF2+FI-G)zwHTCePi$oVkxk zN-=P#zH;oS3h98zLRR7e?%fEl5h@p%zf0F?L~VD_7~^Bo8WTXdfP~Eb*sg}M-WD(Z zHpkmb2__o;vAzCal%jtA2Ni8n!}+ZS##j*^_m?6|lS#GUb-qJkgiCUM9l~vK_zHE_ z<+CQQ-0Ao;b zJ!Tg(mT2}v-(p*|P3Vb?1WRUb0sW3qBsqB$vAP0UyFmJyt)Y%y=Bi}NW5GYq_F!WS zpAY!Xx2q!O@fFgZWaJ%HtGjnzIM|LCv1b#CD(dx~hJGprhcQV)ZUG;!kf_0!bpEQV z8%;}}?o^XgTP1c^b2%~pCUX39&)C9){?GufnMY^Y@g(1l%IAed&fz*fNv|`;bl)&K z7_=qU8z1(c#y899gJ(ZmCITDUlR83>VY9C3UX7-qos&>hIGi=8yJTBQE|vrYbBlo6 zIaSm=75sgr$a_7z*V{MP*dS#S*eKJg0IS$0489g@=S^E5o zS8;c)t$8EGFoeGXfn5WqHHiIUqUm8<%N2&W1PSRdpeici6?pOQRLo7qZ{>>yP zeO@-~4rBp_i&4#iUQi>%Qg&*~TH?o$ofvlm9qyAGEAph9mgWC$qrUlVjWHlpedZ2! z`2VBd`QJr({7=yTf4GP$TDyC zyetMef4UO9D{_tpQ<`!)EndF7+IhYqX1hL+5_}U&^B+De=Bw2i4$UFu%JD!uJ4Pq$ zad^~3nSP1ET^!m2Y(`@`E&X3F$x!wVquJg2%WasBgD^&_t90Y~$PiRniRZH4oHc5? z>>@jVSKABfZ+b+DxXn+;`K(k$In5W{Fo&2d(jc<^kHTU?C;1}`&9Dj=OcRu2(|S&x zIP!&G#@is-UwLtY-*F0=3q4amaXj#*&O)F6o0iv~M-JQKM@5H^6_VdRe|%t8Vw#sc zq7EHZ^JK-sOE&vm>#K!JG-QYZ>(+G(`8P~RQV=1qIe5za8g2f-xKHbA3?+R zK96)upvSC6#YsQjE(HoRlxs^{IcF0QK7$N-W%j{_t!mmGL?Ab03#4 zzUZ568{U|1ta^MSv1Zv*d(U{is^%6vWNXeshFx;>WJVb~vIz;FAnKKPuCw(8fJ69D zcUVFdcHv+#Pg$L~?lAI1Ct>WvS+>83%f`h~mm~IeiKM@C0|Jr#S(1g=%R9^7$-&;4 zUc4_`%b9$w5%AN$yL3F3^HeXjZzDwSasM0q?e1AO+7uyBbU9-m7vG^cgxXo{ZW`&% zF6lrtp_q3Stn)m)2_{Au5ai+TK{UcT75&KyEeEYop$) zE~vG>;MG0t?x6cktU%BHD7nWI5mmBlYmbf zM%u`bOUH%RaNA=%%#X;5nveLfz16AA$TA!&HF+1#PE z-pZT@Vw?>eDU}NJTgm3?Dyq3ZVA?$K{8`yB<&6ruU+ck&$vKZE&VR(Vmh}_+!i6Q0 z7E5VboJpv#lmL@jVZ_ifUz0Qo{bKJ~>1Y;%`KxsRp_Hae>P$gz@y`2f_@=DQfzHYC zQ+skyd(Esdr^rBUd2P=wGc2$%qa9^UYKgFWi?i;nOIjE~HGa3IB?Ps}XAut-f_}R+TadDKCww0O*H(G!`&9`;Usb@pU_Xk6) z#$K>pUog;pLbW#bVg6;cjG!&0Yurv(qVQfe{An11aG%xSfoCTa4&40_G49}9Lr{o4 z*647EZ38d+jq3i@2#z%jo{&IMe+S9<$41`#T|oB!rm*lJVQ6kwd|32(xG@T!JR8dz z8{dEtkO{v425C?>VfSKI-BP&+2L8mwhoe8{mC|;lM6x}c?;O0oH~FOGh2^vG?dDR} z;lIh2XuLMJa{$1~Os)B*WQSuak*|zCqs1uhJmzj8E90WmoeSZ=m$L9Y`NOLs0Y!P^ z?|K6a@1z=`L(s|vSUIgzC(0H{iK(zZ$qIxHt6ibR@t6D41^^Nof@&(O1l@9c=SPAbbhOrcp@u?xA!+0qr`Q^z-TKU{qlbTt@rR70=jfzs0o z6V3BCoKVmI_>@U0@6R0XfzMRLap}}nIV(0WjuvY)x1}o$+?L}Xu{k($h~@S1km@6d z?kY%#_3Jc*n|x}@Np!uv=bQr5FB$Pa5j1IDMEX>K{%zUqbPD9V{Z){JEZPK@3^GAW z-!H@0ChlJhz#_0MvHUDVR(OT%w51w_^SGrfc4GWS8@3sTS-cd3F8* zC{|vfl0Qr)2`Q$0oj0lM65f=(JNj^oe7|3w0#)-(X&xwLzIU2ivHtL?;oDkE^Dl|< z@0P~2j7Q-~F~JHQ$I@pH_{X;^tBYHxZ1Q;ZI1DYyojz>_4Nq^)+HYi*_fHR1C>wSQ zS}jpMzV)@p*|~+`+scE`&R2T4vHHYvqGe;>BE((6;o$~W*J|TFIIMKlIn3f4?bk}@ zFM^$>%U0>ZeoX@)d~Cf^HqA>my})havIJ_V@S3k(o3kZm=!v-Bh-6LTsA z{Bg0V=E{N3B6Xj;8NkX8=2c@?Uw;2r?yMO`{uHg61i8MFH+wwvl}|qA;MIo>n_MwP z2$(xy#?W{zl2NHkFfX*A-)YF8oF^zp(y?m^($ z6-OGA(Q?^HX9<3#s53tBEhuT}Wcu_DA_v0Fu-CdKUlKBJICON)f)JQ_wi`4&Ok#m) zhV!3!YcD9b->fYl1xi5`L5PDq;!4oeZis1o8(1kv;xiNf%TmkfyfB<;wo=$T#TeO@ z!$}RXvMrkMHCoWPOMd6wvIxV{V1WX~G>bg9rhA8SWh0C~X2hSYJlZEkd3b_97`BPD zVahfJ9++-y&-f2oNqtRoVgcNB0reP)+82(PTrL)zS%JD{JesScqYVK3yesyyYtHb7 z$K0@lm#{`(-2{D>3T)}TsQh3ycJ9lJ0=e8Gxmh8 z<{peXr>|3rZrB{TrY;RDd)L?*`MB}(ROqj#BgaOG< z8r>Gz17w1Z?#IQ&5iV^iJs32Mn5{YOXi{x#NeQTrs`$J|JMwV%J^&I}+4f@Z)Zxn6 zx|l1b4^VL+bVdsjMg}o80lREEW@$8wbt;Wl8cL>$7gC`@oR$srG$DI9$=PM={IC?r zEL2RgUKC!QyYtGc-mu(iGs{q53X6iyGcWDCVgxS9kNNt!mFiUvPj#S@?uJm_-;oH4 zb~yQ5X>&WwIJ;w5bFU$ehz7MY!A7UC=U%+MuH*j6=M8TE{1yZu=!wk>yTC_ zgwDiHinX!PVOiw%N^X1VQzJhoU(AutX7bz<%qZ{7Et8~-Bd6Xj9!lE;#`g;iv!pk)3*TC+uW;9}pC3STg(@>KGt`GWfZgtDftz$aUtBle&qo zmZ?6{ZdY~pjvhtgaw%87+2ttxe^!) zFbVru_g!bGtWmZ3?EnI<36hw?uZ}7zt9j+(;lYUVLQ$X6s$2eHhENGN41nTL8X_rT zW(Ah2Ic*NS`%QVvuYRv%qX)F@yEMLi3|2$>@fGYN4Y4h>L+sN9zRp1U^7e9+9oEgb zt@0k<#l7zvimxIGVXR)#>}cpG9P|M7)QILkzmNETWNTIzKD_EW%YXED|5361e`mh_ z?*4E;(^xeE_tg3qB|5aC}$LORs zqv-TXBVN+r?$0gU$p1y#TLwh+w`-%)iiDtas5Cg+k46}uYP?H5@q;>o#6|mQLb9A0?ss%J)U{BIB%!Eez!Vr=)9d*^^$0~-?e2_eo^@L!AIu&P zFsDv%$$338U|7_^+ZIk1P+m>EU(rpJTv#k}pCashxqUFs|BM+R-{KnoK1rRLo-QZ} z9kM-X|8U*PUfQESCg05A}g%2`6QHLGrqBPl2 z35!lPt9rj2r{*zd-dOxr^{9nVA`!W3$D;eo zYN4wGfgx)mi|Ec#sCz4)_C}Oi7iOH?f|ga9UnyWq%WU6|=1Lwvk}5Uo!@y)IBv}ty zU&QU2!-L?Mtz5HplwkYKH&FL-&VHzsSnDyU@j+C*eNu5m5g0=2V_b$=@%$7s;eS#4 zX1~1gE27f359-P~uqpUsHJprDU0prz6R-xyA^voz#l^w7Lc@YU!5P5wr1GNxdx^MK zVe8b-zcC)I#LgB|+*RqiAm|lO`KDR^`QS@|n|`ZR=F!zqf@s0b zN^H9c;RqM9Nr&=#yNki19*;oS{q1YNVyQnU<35kI)3&E;xbb|Szcn>K2|?J57`90g3M4$K>C7Ntb<}#EMCW>d>SV}nEoT|`wn*tZi-$;qJeEYej= zE4VbmZi`I>RgMktg7?T016DOvM;mWVT$N|d&&4Qq1oMVCyoSaaaELyn!Cjs{=Hg&* z8VbFnl$Sb;RaU!D$>xGTK|Qdpn7yio}3 zyuH9fA`5y8cf)SSG`CD{xR52hx-80n^wx+xE-|t9>{~7UlE-qRND*D)R0EIYQs`Y* zczvm|q9UYyDZ_$97mmzF%J?|1yqhd6NKw{h)r}aD`F8q6qxPy^D;`1Eh2g4fD+omO zDe`Of0d=_>-r0j0^P3B7rUEOxzlWZ7Dk-Rn*ydF{E?V!4s z{9DNz{`q^NBga=8!3tVkI!CWrJip85KYN=BkHf6alUkT3-M2IB6cMlR?o~|lV~mEU zoPXXH9uX%v{Lvah6R#7~yB;hb>Nctii(JAR>AvQ;Sk%R{#xthS?1V;DN9&(@nHN^p7c(lD)0j=|2!xs^WmP%tj*nSWC&wLzrFBFZp#0 z`I=g^MSO2ruBrVvo85U1!`BdKs=?s~svv2fEb90WtAxpMJ4in|h}nRZ&wVh6~pCv=`bO1fHF)wb-L zEG8u5UTk}i{X|}}G!rK{1vft4wq5Wip9rRH^OTKl#onCE=Oto8FukcDzg-_U3_f2u zM~=amHW=P%T@otLx?SEa>dy}J%SMwV7Xj*U-Iq65o+Ii58&1 znyA66=g8hOR<~T?vGJe=HK4o)j>kdMM|nQhA4-O&`axAr0>cJ=nt*BG4&cS@DHU6_ z#~#T+N6vzJ#)jDmMrTA96#}iAlb-w@))6|5@t&uc!jJHJksrYa>`|n;Y)l0k07)LD zn;o5DNdKJ%wg_V{*z&kC021Tn%BH$XX>*==zhDPsztvw5GTgVje}DGS0>@*ob-_71 zoWtc`w~;dcC*`dEt7pIJ2KZ4wbW)C33rda%PYeoxKV%I;#?U?6(*{?U>r@AJQIJ8& zt3dGpI6BDwuXg+em~SpMroIrqFDjC!0o|Ldbx&(v^+8S|**(+sUXdX)&h4wWkUpdH zfPvsA7l*6mh&g>?F?i2BEzIzE=h@J+&45RNvfJt(8iiW&oFQ#!&%$cDkvpLvV4zCnjB@agWx&f@^6e@Y&J+lqNQ<|k8l=y{# zr`Zl%c-wa$q#z?n%Ific7Kghv$6DR}Kl)(e|QU-k*TrgkyOW(c$b*FFPfs@25E> z(n~d#cgJ(3D~;t7kAHn8ke;jrfaa337jP3f%}mC-bRW&_+TBxQ6?@%})3hCV z*p=Et9bEBDZ;B7pLZI!!DV`I@&bXO<5}9#&Z&#LU%MNLe#gR`A54AIQSGng7^v1JE z=KWh57kO%2)j59C+s~H2&p@fO;IOx5s1fnN?*+t=B(fnQZO`Ms=$OKzyg#@lQs7!r z#>uuDDUh7oi)+$Srnndj1!C2+!gB8K8)RFzPsRP(QIzgZWL5gQ$@i9qhlj`8E-j1g z6JUc}i#vSkFjQj&sz$|cblOQUE*QOA!Yg!pWQxZ~W)Uw?h_&p0zk*kyEJeQ0e8Xw{IPalz{8k(sZs)id`~kZ>Tg9 zXfsvOGXI{; zVT3hXbXdbxqHl_S(Tpa@CZ^59fZdY&h9GN&=^c)JZ*KhzJys%GAj`w^aaApu*7wbnuxXQfm`h!i z1)P01_-ALD_X)WI0s_uElaDD3vL$^eli1a?un_cryOwl1=oJxOx(%$uJi&hw}=7@1o`;?H>x5|G;u*+o#3%1`WgpJyJy=q>JO)*}L zMz%ulezfP7X&@u&p9?NtsYxDvQAlqE+qrCozGjY%kd6)Av1g+@e2;!yE8-Du(NLMu zrl7r&4HRYDXhfsADMU6mHcDkce0*xeu0LPrUegDGm)X=JoIYL==T7g1MvA2sXggzs~-0vVLsvazih~isw>L>=cgg-%Yz%#`6 zv)Kg0rHigV+9n6-Mq-G;CaiMB{Gwm(Ro%aA_w~2&i6@4mndK`q( zHu93k(~gOWvHMTcq97-AwsV+JwQU(*WKD;#K(;4ia(2_13?o^v$rOJ~R{1_C-Rm^` zJ`|{ztXeOZ;9xO<4_J@8^Zt|Y7?93g0&5lPbwog49ty9W_QaEKJaWV{Y!{SKNh4)yja$3NybL$f@snO18igJ42#W-ijXsa21n?-di|Z66gS%#D}FB zG-;<_f0+_OZP~y@D?q3c)m@}nW9NJfDl~0v=}{AY^NbFC7a7o81^T4xF6E_gqCEML~ zFCgbRvTH?~!A6cAjCyE!4Zt!v7s~_Lo1-1nEP0={ktw-166L>B8mHnQJ%5WxNr~w1 zt4Y$>cU04zQD<4z-n~4X66FMI5e!e?IE{w?gh{im;)&^mP1gHkt|*`mTw3VP8;|?u z2fXbC-^2jb4h5O~*Z#e*(Qyx;ivj)gMT`vU`mb7&C~P3I2&n3R>q6k_|If?Bxz$z1 z+4b3pEYa8a5B<&({3%x8+J+$j;I{+VMBoR+I4J*}?vT5sWo2F0#~)-QE;_j*uB%W=o`6O+zcl0q$NQa^Afq^{AR6%YtC ztqJsQFvbymmEXAPefK`Qsxn7u;)buQe=|KWSn>m%$cIaR#XF=0H!^2Z#6oU3#rNSf!-{Bv~<(W$!ZLS}M)keA* zxhLf~iL{8ewPl1A`2b_ruEJ;6mJ@rR|8A*PtTaBL*Rh`CdyJvw8}jAVEE=+87`IJ# zj|XC{LjyKig`FK7?ij6i%b~WhnpCGLPwN9scJo*}%C7or!(*LL6|rm|Xba$WF9yUd z#f1zK!{0_;&Szdvg&Lk(7nos;e*J#=;6OK=@K?qAzy_L5qjr_%*pGOH)CR!NoC~yb zRJn=)zAfJJGt==WlCro)uR#s@Ccj7-0yKe;1$E^Bzf%Oo4y;8fxGnsh70RB@&P$R} z4)A`TFVjoc!+sh^hDA-6-x*W@++Wb(uXndIQle+>_a-WVZ-t+`tCvY!-RJ&j7}-8@ zAhh>uw$egu|6*3`QnRwqqe~6#eh=6Pm6J+1s2i0)CKBxmdpnf)(ArA_t41y$mGzp9 zEU|5I108uf3upxyrv`?5y0a%PO{o#%OL2jjHRtw@1|7HiXeU`v_cCeUEizHhyyEQn ztM1&iMxUI>k~|$1;JKMlVsEI4CEnvAP0QwJ3grh5(q*WQ(JwTG4^VO5B`<^FccxDj zKE5o&uYJJfLPJ9%;=Y&ckDwO)U=Rx|u!4Qb07M1(h&J3x%U!Ru9S*BU&JN7FHBdIO z(ydxTw7yzZH%v`#a4&0&T=!#~M%e<3^fr*w4QB@iCXKgQ&h;Z{-t10ud5X2JjTrwH zF!KLlDRDllxzPOD`lIYP`*!NcjYM#3XRb>092<*2%syyP0xEsJXpqa;Z5o+qId!Tn zG=%mMt)EYgr8Rfl0;;3cm)c3zs-zIEo;9t87Df@&w=rHu*adAa#4#^$qrPcv>R%&| zLeZVdwfsJ1x|^bmqz-)HJCV;mkh=aeA{iD*tCAi{VAk)oSY!rPa-6gg}6Ijiyz$ zm56@q!t{isQ{CKsNUxvdim+E|Gty6>ab3COiI0A=Ab^rW)n2-qV6Mwh%Ka>VK;Bd!}RJZZUI@h{lZQ)H7e@!**t&qBA(|!bq`7_u$V~;g#jH+uP?>xhI9! zGaqRHVbZcK0lXEWeuDE?<}`6k^cvMQHim_^H*)uKeB%8H*!R=|g{mKR2EhJ*oc*vG zekp97l1I-cX+nW$t<76+lIe4MK(bjV0pk^FSacWK3c-bsWTk%pHlk{_d_Xw*arSy7 z?JC(bLp{pCf^?=57^2c;mS(}6s3r9>RAhe~Q2cuopI6>Et-M#&Yqws_F> zlsrGww*_qM32t54*uvpA#uXxr40m9? z-B$u$gi4S4^3X{RH-}kZ7F5|CN-bZ|AIpb z{6BC=zM$B1_gM0Xz(dmDrN=S3c6h9$Vc0AQ7mMD4NR17}mvX+2rOTR8(|%U^99-G; zcm0{B7ekAmom-RxF)#A5u<0_RqR7>LzWZ3gg?642C)&GH_nsPqZ`IU4-#BL*tqyV^ zBRUpJg%)KpJrbNpZIN|p6s1ouK&TeIl45`A;;sE$4kb8nBO0MJ_19_pWrON2WBpHT?LTwBU5xyXFat(1?Kk3`-z*14L zeeUE@@EG#IkdR(}^#C7al?H!lrjGH_5ZmHTl$})mWu&O|9B6W&Dgu-N_jx+MA0e#R zp>w@EzJHJj{%o!pPz&#VFicQ+-oJ6|FPKe{|C48N{E-%}bw2Dm(F&0NBZ+i6Wl`}@ z<6Yu0usij;2{)MHiWx2)KMpsQ%VUSh!uCK_HQUmRae6n-6!aFX(h`%xpyL4)o{Rcn z(#T0$|L7SkWS7HlFSvmXabE#Z$}a*z{G7r3+KCXnPX;|s1Uy(0##lWbGdQVy@@;BZ zL;#ie!q?L2n)l4tlzA6u6j~Yagym0cbLn+Hs+cx|{0`4y=QLrJ9Zm$#`dcY_*%fbb z>N?aDW)yce8U(-e&-js;Q|`*-eebCC`*l8K_6A1$4Lar?QhN$$ZsC`eg!IN{Lew6q z+-0FX3fB+Z6PDWVN%J4=T<7Z+6&z)~PMOs?3_B^0DnPj@*QW~5f=2G{TIu##O?*;W zI|}Q0BT?0UtNw0^=%rH1`_e=Szxj-G&nwlDz_woGlUA;WqmPEfQm#VSQIMJH+_g7i z$k79&kz$YU{!e-Qkns71cpntBz)3 z_AwIf0iLdxWER0obP;bpn|>1mx5qitarrQKAVvVEX9p?Z4oxc31GYn``gKuy=~n>v z^Za(vBQLCQ`H>GJW0<0`+Y01x&N28;1k(iop;M`70P&OJrlx=-wQ;E))q3vcZ%O$- zedieKn{W*pzdsmj-ec>y;9sNZso$SE=-;%Re#e1I`oXM^M$L@!js2zP(K;=l2#bY}leHA;>Rp z>ih@2?=G&6O;K{wV1@u6$NE1E`we~2R{F%qM(_ow4iio@KoBoTm`EPb{2gB;b2u(^Xz zW{_RN4%lX7=PGDI7C<5WpO&`&uT1s@^lNP z+^}k)q%Q+HkreRD_g|{Xcy3D>6A2pvC~84YB6a{AKQfopY&Tu`{fZ`QH-Lfzw-W^5 z0RTD#ZK|au$T-KnxyPbZ-M=qnWAWGXlVs_`20TLGmq}s)a4nMl9q8Yycvn`f0oq01 zY@ik13WRuCUL3@KV|uo>6t{QEfI$HdCF-$iB|*rD@cYz3|9o!433IFtbiY>q#eLff5r;Uce9%j1cSxl+vE+rp05}$P zZgT8QTW$$kwFz+lb}~>Oy>v-JPue9GI(6)PIQR0?b5eE4~CE|l4%$@N<)kViB)})QO8=9y_8T~MPN;dJS??&l`5!E41xzXpAFH9 znE9V|d|&>}RXNk5-Lgb<&x1A2D+^4p z%7bY8h^7dkC^tXD+o@gJXwT``E~`cIN|vMTB%8;+0KpN>k(1uG2rb(dB=&vjT;(t8 zm0M9RZGbWl157xABq46&4v7WrdKd-1yayhCqrk#ih8E-G{lN1s*KaLV!#Q#y+BDpP zCA;%XzIU~9YT58`Hs@L-=R)ew$LISm4mZ0;+;BXvSnCa$e|a-1iZM-7O1|p8w%IOI zTur;?0dM&!Rk>Dp{tj*|+vacFO$fcJ_s*GYF|fT{`gFU((!eWa@P|b^FO|JUrQ1?W z8xZVNP52hBowYX5Nsc1n1aGD|FXu&Hr#v^1kegt4@Vnqoj^I=}Y!K1V;!ml-vojL; z%(2LUUZQn+_0%>)FV5jD%r2GuG3iXNtH@MoO6}a?#}0=^=D=IYo9^q(z8Q2-<_3Mi zz6Ew|pZv}l*3xwS2m(1kNm4A*p~y`wTw~- zs9`{}Jc!V~CWeEoh2^mhVTH%|^Gjmj#bVF#T?(9_y5imix*W8&F8PFc;X5jii(?wFqC_=eYESMrE zagC1S;77*^7Iy-3bnBtpxy5;YIBSpR@opZc>n|%#1aN4;p!U=6d#p8))o{GJxa#}r z0FE0SfOvH#?`d)^qN=@$bqSdp*q7gn(xF;6zsQnV3|7#Mx-GJX&W+(5^&e1PejC*1 zp{oU!pI)xvgI2#ZUg9VRi`91Y>qj-FHygA#BJ4s%Nc>GrUj=| z3f*DKM0oUG-ff3}Fh>gG?@rRM_7t$RTi9~rF$oG31qOebAu^ZQMO$Q|I}X>ZrrkQq2CoDJP(TS2 z9Vgf7H33BI&;R5xyH1iqwc0cHzwt_Es$8%?Fp4|BO^afGZQsW6O)+`LXcEJ$FX01j zWDIqXobJopQZW&C^_nlVuux2jb^Ja!9yJ;7Y^3kC_agPZS?-B+KLJ4zc8 zv)eixFZmKaQjnTTVr;RkOD#ZueeG+#@@`g|Ed4UNwuW-+VW4dPz?9X6c-o z)&RJ)-uHy@J=#ZFjpJRy#5LD|;Ce;lT)+7hnYce$*KkVB*PzPWVlf08V=<+=;xP=lUOI1mAow#dmW<@E> zihH8E7ynjRYk_40J=kv`xFGq{hhQ?uSJ-2_(DBK>Hb5GG~Y-*yvO z&WXhM8J%J4@>);zCXi3@Ygr&EBH_QnZwGJm8UCz(=tN(R6m&DKFEi>t^i8fbyygrI zU;oUnR_d+Hptx^3Hg|d}W^-&$R{B z(+C)sqgYNqdeLuOWM3bBdC1D7q(o#8Nq3 z^|I(TK1vP~i{wf75l>=#aQ%+@FxmocA7l5L;%Lg?U_J%%;E216NzsU^z_p{fGJ+em z>=xnXSih`L=8MuUdLxWt$Qpdh%y+8QSX$>9u87IiUgl!Amj-{eJP51k#_ZReHuSy7 zb@vZ%TQN(SjF4C&mkP6>;~R2`ZGk*t#ia03psXV}ET2@JWLIRoVA?lBp{OWOVpYZ8 zIoG>sSPj`}%?(}@I^zku`qV7VwlwK2hdPAk3}%N%qQw&7ug2evMcL&Y+q`#z5x?9s z;|^^5VhcsVPql99#9*N59E)YE7i=iKzK4nw?>A`jG6tT%u+d#9<|@GISe%>SvO&20 z{@ZM{>N4kazOh2QZ29;5gl3K)X9QM)YOYX6%Oh_9yXr4 z>D{D>$k%G8D!n0^2E~fucT0*J{30U7doh(1 zg`lRH7al+`1iTap@+!_mY93&kDm4#Xc6!v{G-Fue&kZq9NfZ$jaG?~ z&djBJk*UihfZ3XGPt9!K_0$&w6ks@T3|E#SXDT}O^&m*0eosM`q()2$Uzf29f$VpK zW67_(n8w%)R_JyW3)R7P$ptA4B4nJZD=MaMbbB~za)+^7s29DJyvB{9HTIb*l8Myy z-h7bo=g!v;%ON|vr*amytN@77(~0CNND+A76uwtr1BVH(kSOA6lX+(E3PU4ccl*lm zqr08f&GCX;V10&r#W-!HZWM*J!HNP$ol$K0mgRZx*$QHkbO|lAnlnZ}qj1`gzkBPt zZ7@BIjyVquv2|QTysrSUhy5WOv=M6}^oZ=7me?lGGUrmWNCly<5&J zAJG&a>6_*NE61A~0`atVHDKI>TDh=vYgp*o6>()NLN}{LXv>rYs@#py?wOp5mxN+A zHA{TE8WaP4(h272VFW0P)_UcE7My*w-DnZNQaicsTi2qlO9sR2mAXoF^r4<}TBXUu^&M6RmEKn^_tEP{gB*WYi&!X?w3 zF^|a-jDgzmVIpGlEPLf_2#-8EV!&+pSM>6~I~dP(GTRMl)FZxNTC(@8^(h0nhiNAM z;)mqD_-X=iY9MyFcTBBQgiSW9VpRC>gznO`^9Bbd2rWe7%i!(rw2H?(T;Xx1#=|%Q`armqXj3M2VDu@mjl5!u^X>u2|J(p)u z?UibxRt=c~{JhD#)6aq5eBiHwsDI~`Srn1P>C*>6Z9cLtta}J|W57AUm?cIBz?n$2 zAIjUJ&w&82VX>wb`bAh!RTG5SM6s^kf2DJiX?B+&STl7BJe5Fd2R z5CXCJ)g^Q@K)&YrYk=n!u-8_H&)TyRH~AQtR0}f`1k*;L^MT^VO~7#Czlogx8$iRT z=;iV}*VCf~ku0yv8@_GGJE#QJ<=g`GUdmWA=m*a(^{{HS`b}fO==q3GBV#m5b;Z&yTayAfWkPwok@lxZSVXut z`^^bYC+QKgxVd}^p*hp-H-0NVfIH2t#GTTW8|{)}nQv|7xnz5F9kl^QCr6u)UgAaB zv-`4BDFTwK&={MKy0NwwnuN&`$;0cE9P>ahM&mvX$|*77slrd=@GNehkFWj(l*qng zR7=w_tNYH3OssW@F{}-bYda&m?a4g- zQ@4e~q+A=9w56&Ih9h+QSP87lbW0;=>ly1mRrm^@B5Ox<%}R!r*hR;LjBP$`oGG7A zx}eh!bfoei_%U6DOM+D&xZQX&wsqfAZ$BY}8ngb(GL%JmSBPo9^O>4lZAEc(4 zY>J+PbVR96Xkxog-gz&Rb3EJHW!nY?t!eC3uY48cD&I6y>qgr$jlJfQ-xHd5y|5pU z2yAzFlj;3u?1#iO{DanL?HnY8zVTErIfWxg{MgY|^t64@O?O~?wK%(Y(!Q%*nS-al zqttE0){4=4%Vi)nDu->otvW7fz`OgpGA^K+(f)eNB`#}Vn0dSTOJ2jw*iED91sK0Y zYW}3wF~ekzmG=h4dVp5=zPjD9`?#Ea_NW){f#vl&;toZDYt+=1-L&8!rO*Ivwk7Rm z)R>2^)-tDyi-N69=D(4W2ZisI&xI>}GE&z85|{m0Q{|Ff7=>lk_G^0yO>>w~=(1bL z3?fWpQNd;m>zk8ErC#*v(bJ=4yG;ybEz3YUpVv&ehr%Y-dj4XL7v|e0EW_fuF z$cI|Dp=QQ?>iI0&+4~>=;v7)8udqv24waYP#RVVAp-}4=0PaZvoK@XfQ1Ve>AVsUJ zcPTAI`)*$mO3E;c${w|%8}1Ot{2L6zvQ&|Sj^1tmge_9lZ{y4`RjiZ=0|h>%iQkc7 zUZb`&Sy~C{99Ia|Jj&+#=I$oiOu81w{5_#w5l=2cNb#LAVR9he_FV#b%8rNW%KT!7&+ud;Y*!=sX2#+(*P5w7R zz0c?j*o!Y$`>gPK7`@6MOD!A#u|5ABQ)qyvE7o*k2fSo<;z`vWtHpIrPKlD~M~wbS z;G$vCQ)G-fF_N@7h~c=E{r=Q9VXX=~8BWOclU8u$T9rFh=E^EaIb|u_e3AJu`s9ft zkNRnMK)43G`?K6*hTJ`2pnj}SWM?Gi9T-f6_I}s#okE(TSF z$|DJ97GP1Mk7f=ipXVAgC?%25%fW-Rs2&}CR!%vK5JKh6E`HAqFMVrfg26e_ z8WC1n3v|#{a~zV5%9YgE*FeOkUJSOj8Q3a~fY;X^?a4o())iYPg?F=Dd~&cB`Vowd zJHi z;iJU+-_;2dJTs6od;vx$eQokFq-Nmr^~EIGzxlA;a|-T0OP7$3arBHlthGAtE+1(SO7S|Vz4_1R*+ zWo3t)#wSFoGwpq^_v(rhF{<&~%4!?-z0G!8xs2LDl5qpqR>zm%*;h9Q*QCQTJ~Np5 z1su3Y_-b2x-aYa?P*bZqTHD_p7uBbW%YU*v@$f+abkynb8AGhU6c4bJ@c&b_(3636 z*8L**&f;uKTvt;s#BDsxl76SXY}%1gzQ|22;HKj z6?+@iU)l-zi=h|3XR8{ofW*t;VaFl~4Exq9AnK<&m?%@L`e1qkxT9S!I=Kl_ZFr~`dRfU*V-uyRl-?^7QIKw3bRV$ zi&XF5reNFTgts}Pmp4HL-_Q4?FL)8Iy`bT;`3)Yj{4R1SH17_j7N;@>lvj)M+j|Z z&03A-lsAJA)51AbZmChs=T+@>Isd)`gunVEEJgAlnKy}AL~Co2<@v(T0bRwkea9Y% zFH{G=*1xFc7>VL`+>3uX)0-1m71h2o z%2|kWR%iDyxr?J*IyrtMPHY9CEHGP$Sb&w!#BdcdYY;Lp7hb4ckFilq4b#xQs0}YhpLWKp<#Rq8Kj+<1xs?L94yy`Os#z5-xrezZ|w#Xw??wsmtTsVF&PIrkUQ0{1 zT@;3FTmh30%KKuq?oxfs^dj2kEDITbt#IVZctd!eBYsAlK} zHxmw<_=2?gaRMM9eo(iAcpC-}hmcoae>Y0C-ewig4qzsO0x{;j{W)clM!G3ED;Mm` z5>Z~X*kE{*^M$GvUCxj_A=HaE{Ih7GAjG(h*-H>KcUUm`Q|YH{SG6vyqX%b(=Vx-4 zu1koyb)1W`S6agyNBtQ{YJ^X-q29*$YIfC=kQWNMu```?c7leo4nw+U zLwHCQOVrX(yp zDAmueyREC@67j;k-8z+)vTC?fpQz~MEZuFLxNaoCXY)VY1k1*nIvde%Xa zCE~8GySl;GQDG5R!!>OWGf&~&TdIFt)xvrG!he+}Ik8;oZUr?@2)we83U8FdNnFy!HPCjhu+T(5(9qPf5`d6l8+YN)4iBsc#8mwR} zvf_{n{RwkzM@A&RFUi>mDpH-{iW_mO#v8#31yVZ8;Qa7=2R8Z)g@bxn>fZ`GVBF(@)c1=nu5w z+%P!!ft$K&m2VxucLPzUXM#5kSfJMN5(Pph9N?*BBFTW8X8}h88Y8Qk!g%vR$gO|d zVJDMIZI5w)aS-~EUB&x113^ZFR@Ut+CBY{n z(ke_Np1ApTNW=D)4md(1iCzo%o4V!UCQLwJRaZU*k;B|!23ynNK(R(i_-S2SrrK8{^v zF7`1o%MGd(uK^FBxr8&n;U$PGqWE@nlb8o-NhUop`08f}8#mS)R#G4#7e&DKL1Jc|%oZn0+Z)?lpo#Ll|Lu|QJ%I`#y#fYDm z@&KMpfa|Y7V0cS?iVPw!X<0;)R(B5gqSAn%Ab6JHUp-&4NG>l|++~r3-uc`a0g>4G z=kJoh--q=Xz)v_rF-O-}r|MU}{5nQAWetYnmtt;)Harmkvw@HPFQ@Zpa8-#J1k?$7 zg_+=Cd*4uTpfx~mC}iY~Xb4ey_lQzXylxh5vRm1G9ieAyY2SOsWp4UhQWf*h3pKc_ zK;VBZ2Z6tw9kL%Rme{C&$Opl;e@{y)V7%e$a3POg_5e}bdmFE@{tjG`j0pnRM?pH? zZ1-(1VG&QFZpOg+y)xWn^(PP+LH7q({j=6Tq05~HAXS0-Z9IU4Y^bYh-@3bN??=^6PWciaL|9+06dEw0s z>*v47d<5>^WP1!heivCM_-j;FvZLboqw&I(1KBh!$=%T26PADht`2D$(1)7A8;OU5rsx8F1tdoLJ_42U}k6I_^Vt8WycM^ zS-X)49DI{vVOG45G!CaH+t68Oh(|D|;P!7=1osb37x@DDdj25+h@jgg3Q6&xlx3r*Z}|$hX!Mk0Ee^?PSKCt3vHRptu(U z#d`NQRN2BZgdC5WazT2t#8XJ4Y6m}E50ox9pgYvNNM#@Ajf9f% zZ7yK#L2Sb2`C#8Ibh%>Jn#@?$>mph9enI07c`R9K*i%`L$WF2 znpk?pJ>JgBVOJ*!_nMvt!tgq3cjpRyt?vlPVTBoZvO&}%D1BDUnrkGOZ{NgNRz#8X zZ##5?!zi2is>M~uFF{*@|Q>DZo&J*#Ll6BYc?WOO#!|pOXCGJ%1^HcNG^g;w_r8*QrcKwN@ms@aD@q zs2TGdtX}9NukEy8JtJTVVK+-C-yit`F4P;>YkYlOQ{qK4n7qllPA0`6QQ@kGx??)|4L~@1ixIBwH3PQ^>v#H~#G|l&j>&(bP?fV7p3RzOz&(9% zJGkX(oI}C@hc!6=g_;lvcmw)sP#X{}tN<%Q{dF-kj>a)C6v&grr4aZUU-Yme9%FQI zb@;ea`NLwAviCg%^2^)DpzTcA)Y&mF!Dj?DAz7SGL8l#wH_LIKzv={PvSI-rqW~?s zByW6|A$Xi1cf5C$2iL}mjMs$U$$&er9w|hmdm%Q;Is>$pl1qc2j{JDvtRj=VYnoCFdO@nmyIdhYiXL0XcVXKA= z!-b<}c_&$|%S4)LHw(Wg@t;ieV-GrEhtB>OIv}O&?a*`?fS;5egC81Xvx`&t5sFT* zzs>|k7691)Bk$}6>?q~RAkEX0`u*a=4Zk%8pm$K!F(UiZI1U>Df%ONdHpAI7^}{A{ z&{5&l2S8%~BL25R1@y*$#Q-Jv_09xyw~^6!9#iqqQd;rLxlSD9rCgt>&&NHHr;o$9 zW@~Dms`?mIu+vy5rj0ue{oIvfFdzO&K2V>}^+OHFAtS)yg1lHgb4@;c)>A5>tgj!6 z^OEqO1tJyR{PoE8#SI)D-hzX}6-K`?O7T`11u>@Coe@(0+3E>Egls~E`*M4n$1I>w}`HG0d}AY(ql zjVtz^!zHx?K!z(Dy6_V00{*@3ivDd%(+qmg%8{tFx6veo=)c53_>8=Rk~RhMTu3|r zMQkQ1Z3Bt}4o_Qcu>X^_j|kY}7tFv|3H)NGjd547)(%(-LXHbA?$#41>bdLn*1a>A zY@wZ~cL3+0R;S#h6vy5Idbq+I2sk|?caZkg2BgaAfIxDadT@%#Jz0J*cP>2IuJyi> z=mo-QfAqA?|R% z4Ob2)1Bh+z60nV&N4RIB9$+cbu+hn`Z3r<9qV1-x;{mT72NM?U%x<4?TYF7fL>FKF zq9@)m2e+?5J&T600yfDytR2 zma&Iv7&DgaOB9t|DvaGE`<5)JP~Go^=a1(-p7*)`di`a7<2d||-&}KD=Xrj<=l8S* znSfxDPqh$_=SyUX{=7xHep1gB5J$toZ%Y*B0)*}gL&84_I#g*B&l zkT0D)+FiXUV%(W(#ME%733h#*wR$X_x|+)Rq3D2tVc#ePwZt|dm5_4hfMn>8IeDE9 z6XiwC;DWL0B6gpZ0)3)c1rb}krXPd(3+RRW-+?cofhkQqgZqTJ_zlZ9!O)%*W!aN1Z^fquPyxLgI5HqGN#A<7>JQHfv2Wy!76IJ zV4{2=IpeGM%657#TQmF1l1J=A1>Xp&t}u1;qww}I^e;sXBdSu11}~v#b^180dS<0s zo!(Jnyc}1rSy5re0m9UdmL_R+lOWrR`PGcc^d{Pnl@eNsk+^Cdv>tnD{L)yhp4`b) zbGM43?`Fc{H--Hev@hb6un_w~L{vaQwm~Vyy`PpCdrj^nQ=qA{gzll2SvUgNKl+sc z+ZXqE$GNLrHvU0K0*$jKN-Tf4n!~J0O(8b=rAD?n zVUe{*cW)lm*}aVQnb*zK@oj1WMZEE`+)>Pdr<7Q zU(|=|vF^utY&S<|PzW6mCFcCcPMJs7K2&HZI=5BA3{uzr7r<_UVOK|A`m2RU2AZ*$ zn}rDn*LNpXDwz9Rl32)k0jzSQ!N&NkquPc$P6X_Ni$HA#R{KAga~-Wu?725hw3+l9 za`p*J%MWD#v3TNw#HKDmfwv?3{igq0vD+)2hD)kxYE@?+EpzpiZu-HoBUt*6+*p;F zwPSPonuPDf3Zb_W1XZWZofB$?#qWdYpK9lnxKTJzdv{R;CO{A0*KGtY>rXQ#-_yp9 z)c>@dJMH488ut1{foM(KSDpLCw^dR2JSoR;-p?E8&74my^z{h*w#uIBIw6kCpY@3S zo@!Y1$*rFg8q?U}DIt+lj%WTvcX0DbU0J#F^FZf-!NynU%v$tS{q(SPMV7#q*mg0u zM)CQmQV5Gp5XANF-~$EIT(VNqPx4W8l-!NXuc9A&`uulqG7^weVxYyZ}s zEV}!m=ST&c?Awut$~R_STrxSRlfB^M|K(Nl(s0ylfIz3t7PM#UhE`JfbOpn|Nw_V|x8Jzvj!P+Z9*GZ*=-yO`HLB%NiKH5!-oE?dOO{PxOz zEnO8xUL1`4^0>ORMleC`@qqmt26h%u$WTXm-K;6JSE6Q$KBwDLc{tEA*XKpe+1frn zm1JIuDYiysw=Axw3c6G74+NIsekr?ZW2Q;*v-VaM{(vtYVIK3 z31yW)R=1pSIM(K?_tWzt-~(PO1-ita-bL~a=&3XTYJJynzpJ2h+|u|rKkR|ctY<2b z*S&U#MZWmVIji(%0(D&!ow`%G6z$E-Ttuuh{1? zbk5Ce7hijWyWrH@{Mi20Wp7tTfH$pMARbq-LD1K!_$e7eAK;?AEXAL#NJD!3(+h)M z$SvxRH%IfZRnrCur}`WqRau8*I8Tl)>B~)jOrczulj25Ez}~-fA}04T6eQ@)#~}^< zyiQ?=i<#;vrc%fdzmgk)$l}X^h1SBtNhBkUTeL^9N1lr_wnX`)b&rrf^W<~IRkk== zc_jC?*fGnGw^n@i&HNotQpM$E(DF-(ML`xUsPi9^#EtFl!M$CI6y|NIZ{`xCi0_{E zcI-Z{7Vx~>8de$*sYOO?1e_VoJ1usile%~=;W8L31IaNXQg{>yrs?3<917DrBYC*# zK?DWyK|m3nUrZf`T+$2vb)4VT%x)zd*Zu`gDDg?McnZ-fl)j2labk8ZPts43F0`fU zi5Cltdt0j*0u=<1T-ivhEhhgY$(w9u`UG>VQMQlu+0lcYSZ=s172^s)q%#dW>;k9R zSu>Ln@1T!Ln^eFN*u(a-b6s^M^_#9`4_-qjLn0AlG4-+!#X1fz)C-0p8nMn%Lr-O^ zIM*qM`oaA`mWSP%UfZ2C#0c<5lOI&I=iCsUD$ok#V*7>`EK`iTl`!{V3IKmf5Rw)JiPI8)5eOc<&;xlq>fa)=_ylD?GL9%H-}>0#287v zQ0T(VX9Z85Et$|`Qb}xqzj}_NQWz>3UY^&Fop(?@?`9+JDhfTThlzJwsgdRHqs0Vl zIP9FBtJYYsUUr|O9h4VzZyVu^`^7!hRv}g-LeW3tQK^*JTz(0ssD@^w97SUIPT$G~ zi-dbu&f&RJw$5A3dzzC}{_OUXF!aZKp7~Q7Ld936 zsXvu*Goml%xV(~_GQ&iSaZth>PGbPO=K;oJe&doCKPqQy^nOlw2o~FWwuMgd#-2 zNxok;*>CgukC!JI$nioK>0+na^4i1#S$^~aNf1^iu3QrdBtZ!$sBhjXZ2oGX(*pA7 zgvaYaPvE|4EndR`;G+}Q=*oi@4>o!t|HsJF#8_s((vQJOgy;;oUXRa@Bv1r;0Z{r_82EVW#?JJg42QYrDzPz-s2OB*|Aj9ee~p@NBG9; zk^E$dLEq*3vF4i#J;rf3%fYqvZch2L6YV;U*{N+7uH$Rb8crD7?v0k@Hf~zDaGOYZ zB+>x+57RJmQls3h@0*#{56@yr*us_$ z_H?!1uOO_om$HJn#T#;ee3vVuM3YKC+n;b5AGn_o@RhFPEtKolq7wd1UM|kCG64FX zx%3M>U%t{Rug%inLN#zKl>8S|1tITbLy)-MbSN!P)+RS9?Ilc*Pf2RFyu=o|4L2yg zJOD?XKlgeisxr`8_zYo`!x|RzCD0muEbrWq-K!VdcN+;`Q%Tf!M!b6!0g9kZ(6ZJetIk68>v@e9M~RduueZ2a}P>${$o>Uc9l zhNGvhnUA%O2|cX!1l7Ng_k5OfhGYTxW8#--qam(x=l*E9jt(D{&)pEqojUverdCNf zeiv^fi}!=WhQ?F^6|`g{!k`Ovxh#nRn7+))itH{yK5k@oJd(%iD&ZlTO*A-2!q zbH)AmR%E=xdOb>vzLn6lwxYxFEdsU)xGnxVX);8N;f!)7m6zbnkM;4sQ)O(`|BVbj zf|RJ!wr+o2YK+ZQu{uxG%I=faQ z`o@|w*sL}KE$&JgHB3-|=%*eHx9aA*EQpkW+M1o#t9T4j^n{r1&?c3gymPS*;fQYF zuEpbX=P%Gy}_)C#P0x6DxV!w0%$u{9OJYTT$#puAYIjC+Qxvha(r zdW8{(Eb%qUDq47pKbd~p*? zcS1`TT+0w*EiG5pR}?b9esoRgu2UwP@Ecl=XgQNMQ_#S8epV7v(bj3c7p8+L&*^jh zC~nL>msoLH=JUpzmVgFxkpKP#viZmUK51NyLW!?34+gVGW95)9&1xbdUQ;He-(WXP z{Dq=xsV)7?C?*MUuf{S;x|UoW`jAe5BOl{uo;Vgwl9USGLX1I?DBXt>G_glBven;+ zo62)xfui)zM(13w&gfMyF_(5AI3}|o;JEY1h8Cgw5%$tlIJ~~5^GVWm5+#sw=3L<6 zXHMCR6WuDp^@|_5b3*$BUYwS@XpR^rHJy>R7MNj8Used8c{eCt+3F;M9&uuEh{!zU z8CSzTph7o@21f%}>0HCI&xB_jGq{Fp`I2v!3I5hjzIN3_KAE__vWT=S+^r^B$>rtx zo=%%Ro}fX@qOI~o9|rA^^Q|;5%QZ?m7Gj_WiS|{1p3)u+7rg3XA{O9u2b+AmmO;Y2 zQGn|+BD+ydCJVR_7Z?-#hki>l514aMi*q{ck^|enUzyDN)5n%zXyR-Fd#cfFnr~*v zNLfixR|ihKkNeydeK}3PT9EEJ#!n;^1hk!O6PtR88~ii>>u^}#i08O@q?q8RE}koO zpFS%n$ySf5F9hjL->h1?AjiKspc+;?r_(Ss?k4UH3Kj_x9vuBsrAI8jh!IHzUw^YQJ7!?;U3haVO58+?mq0UatVr*txW|m! z#DbwkyC&P7GsV89e4RLF^K{(UEl@=Q>beUwn{ZlCzl@nsZu+?7>ey*$rsd!6<%U0wSf5CLGA$>ClyxMEs>gT;W& z-AUCHlehcSbiqjaIqt7&R%gK7lMKgp$&+wAAWwU{dr?-aBTCw{G zvLxxqUXT=s0Mrr4kqiIDAUl)IVmdlL*n`{A>PY4Z#@Jd5^!7>+UEQuABo`ufFJDgq zmv{GJb@`&%-$0b8)$je!{HoVG7z3=hd#A_mdy%hQGnCk^s89oCpLa@Y`^e!_C>nc& zjqG9n|20Yqh1kh>wIv9;E%u7p2=fj$vg=+P2ooPxr-AVdaSwmBJw#897tb+J0lgxT zL@R2w4R>oj>*4(98)@g^F_N0^nN9WyF_fN1yk(&XEz0mu2?;tiNEGgmOGEqj;8o4>qHo&S7YT zqQ$Gm`^tIA7NBbU229$yQR~H^{~~S+OjX(iohZtGwPy$K0z3Kto3H*e(f;4>o(uZ> Zsu$n3gX^b!?E~QFI^003M8h`Ze*jE5(ntUR literal 23609 zcmd41Wl&sE@Gm$(a0$UB5S-wW009C7g1a*e?lMRM3@*V5?gV!NVSpK6aMz#-HaG+b zIyk{?`OAk_TW@#kz1rH^5BJpVuG8JW)2F*noxb<0rn&+l9t|D<03cLSl+^|R(2-Bi z9S+75=jP%*@PEJ;38e=|Z-OcG>p#jmLo};lZ$fkB^i9z~SNCFrx~D;nWc%Lo{c;_ zY(8x9%bGs&0|5M54=_UpHy$774vz*x0If%dHE`I`RMy|aBNxP}007Ya@6kOrEg>_r z)e8X7FGT|gK0XdX^gc+MhmIc}W`RZLj3EihgZqcWDPQ>je>eXE9P095FaUq7FgxHAeCuGjbUaQdFgjrt9u@K>gk01p zM*$Ef0szn}9j*?x`%q%?_%qS7xIb-@NaR-=g(w5s8hGhmcNA=DZ~FA{@pK?9Ej=#K z2|#T`&IMAn|6-&1p(a0?(z|_WsBEFk*2h+*W&NnWwpPg}zcb0UZ1MQ;pbG$L2T+A= zHT%G}4^@7w0u*up0Czj74}O%-_=9@@@4UmP0JJIrOz$nJa4C}I0Fo2{N??|M_x0e? zK0qd!(y30_F-bzp3Ksx8oUa7{cqPO8<2{XkhEm0q)LPrx6n~QD7ZR~}&k_az2zxb} zhQI=|suTdCPDPWCf17@m1XpBvdFnFMROEPxU^}LEolI5Q2YkI83Y-3WP%yYwIxzKk zzRC`Amo{^821x{#4E6Q2cyOab%>g*zQf94qK>~Sja;cO>*|)f;L}`&Ge|c(Zz`)Mf z{Nzt;@%J*MK3Xx|AucA8a*6u5w0Yk&YU+A5)v(k#r0UhABMk!|Sy<}xyZiwF;H8qR zw66EUevWgLsutCtt9r6^vIcXk9BxY3sWwv#2T$wN4FeyToI}fTai|sQM5|(Y8JYp> z%E*|4YX7nx$)1ee9Z3uZ*=j_By__!NZy#&L?GBqSGu;EXGq)wTo2@YM zQX!6Z|1sjhh*HD<*N0Okq$rbKA?n<9kGq0*IeZ5>ctd-B#30+}7@&8!(#X#(n^c>Z zuV!%6DFvxDSnCVc)2b9*SG28YOF&f3Cj>;CulQx1XZGBzr}O(&`yHb14|7TIl%Ce0 zA**=Krl0Q~utT{Tquz$Q$i9hyoCA`|NN*qiW^CuVtfo{}fxke&F*>VN`IE?lv$b5$ zfB&8%@4wG+i&Q5e*&(*y9_Gu%Mi4}ydz$xMY4#qkSahZ8E#fQ>Ct zLRk3=SgI6qJo!J%T8^bd-Iiwo!goSaMs<2^A8=0ec|xzcr`{vL&_|4Gbnv2F9MJOm zVW}(7{PP*`mIUR^9<12&Dtb3qnrYs{6Nm*nOnw=K zFQlenLTrAZ0!`7`$i456f-Artv83c?QafE=4)h~L)XolgZElh~IiiD*ftIhr6WNPML=S$m` z^ap98d><{3!j?XZ+P&&O!r_e@wQ^PqA!JSG4J|!{1*Q?}R)Lr==NmSv-zvZI)EIsR zWEQ4_v(SM@W!J`9N_61uo>lHvqBCeAYnX7)mN24eMzYKrw;@rBcLs7SN1f3rd|UU* zWceR(;9l-j*X~2~$-*%IJymNI;W8h`KEW>8u!Ne#l;7% zMh4E`p!oC3SWa>of_|ZWi|1o??>WrO+bw4K={vvV8St!5<_)bY8t<@q z1s62)t+gfVfLe*SjAh)~I$TAZrDjdd>mUHSk-yzT`#f`CD6u2#8pKcEZHoC3{n=P( zabJr=M%&-aGA7`+_-uZmQs-XI5Fj5PSuw^S7x&9Z@)@$$Cy%vPH1P-@VwKK7c$S7O8{mj`~g)*qf4}-+hKaSjK5ot`zh78@U@^k#k0V< zcA5uy*0jL7G2@ihO9(xAE@i4d(Wju7PWcpT_^#j8B1m2THN39n-ezLV6@bT=dhNos zqR6!drR4qw(@H|H$1XAftu2J5SQcxEEBXUjX%)Y0aZBGE&ta*USdO9k%*5^{Kb99y z#7^{Bdkdkh^Fg^*-j?X$jx?9UU;A=5y^a{|qahvOeMjC#`+)9x#jffjlgA+cJ$$7^ ze@j^`RGt)xs2*;59XZl|IwQo$YYcg~pEzDD0%JS(;jyWhSd0PlYQ9~0q-tWTd77M5I*wDnFko$+eFd^$+P}bmZVRQx7*A2hTuBF7DGOP& zOl(iSy<%@O&aJulbc|gG<+2>0vAfN{l??ch7#&%GrIH;ZBp>JLmLcFg!v6Ljd{fPa z8hN6Aaa%wtP|F2f%f#pC6GD!ek+iL3kSS8tVrSNtN_=eSBF&b#4lIw@a zXy1j`5rETXzx`EZg-3`8+Zd8wh>9fR%shRG+JTI-#&K@vk52 zA%CV6C|UBCAYGUeyf42i9p(9JZ~mSt-_p6s#$&Py^V5PNh!otK6LNV0daza}RK$uC z{b@|OU0E{3BC|(=GH##7z375cSQ2t)_F2(J^qD)1xKQild>|O}HFwS4kiI5IvCX$k zqT;~(xPs-j=XCG}5>BBH0{uovt71Cwcij+ms(ER))@Adt@ctfM-j_|2>6US&6+sa* z$CdSO-vHlq4?>1Qn`(Av?x{L0$COlgz}mRm<1!XX(6vaNk>uzEL`BdUm}6h*BGk(* z1ay~X$zTQHj3C-u-*21O z&hnj>goy%0+@~DodpBUOLsepMTgtk;N~ZZZxn-|cTe7ZXfV5qHA||Ov>(zpgRh%P> z3IF`g>;$>%ZOt5`g{7#`_53Bja_=4M3EDvkAJT^a~m_ZI3$#>{;LEJROc42p+JzXzaE$ z-;DzDhGf&5++%V0ial-20Xh27YepZQ+u<;>U_AT_@85}*Sz0yua>{)~JRjc4H=!k^ z1Ej5WT>09+=8gqslkIGxTKQQ0jIp12rJ>N1v8^280;FjEJwg%NklDpzJ75p(eDt8y z*E(+e?aEmY277IUhhf`OnI8#-%LdhNNm5t7?tZaxPgSZPra+@ud-|%BQ{^3VLKk{Nk zhxcLjP==nPFjlOhR<}(a_W6;&W?MO3E+AG^971jR1HQ`!Hn~B_^5STNW;?d%@R(S-QtgSYg2u69GTlv z1XBl7a=|@tlN>|_U@oM>>(5;d2FB8)KS=zIU*NW&%O`#%l3_`a2%{1(iXT=W#?C6P zT(H(4#0wD`m`MvXfk&!GX*Ut&{tXm4S2WVIB_PfZxSgef@&9f2H{+PYgzkuFWO+ z#YJxllKi?Bo&2dzfbv!jwZ5skuM8U7!{mR+pkrRVlYWlI2aiBpHLb^#O(RJf$!FEP@3OMAfP;$5oIAi6ssT=Y66GVF{y16bzCo+xOG$ zWCco@ejs5Y>YlVNu!{K|2Xl#~QLi=d0W8_`G!A5`#ja(QprRx-OAaYudB0atmNrOV z$0rczbJV2%F=zs`z>oM&L#fd=Ojmu|TrY|&sDK%X8Xw7S%ieCuKjS*o43hVE?B|Pa z?I>0rJsrbARW7;3yV%PFL0d`weUG7Cr3`^2E)bDFXY#mHFb=lI_gOSM{Bz_0bH+x| zWB%H=Vbt7hfkkkVI*_71e4dCxHgxXG;sI%Uk0a|X!RVq*9{x`B~;{LprZxA$Dg zyX(p;!Uy|;)_&FvN!O|yE~o^V`GF;gOc3MgRZ(3mqyT^;Y4J^22Z93j>L(9mkxmRP z(L~@!ki7e%lu3uw7E-fTZQ(DzygqyT74ceL;y}!hJ;LMFq~dQENN5dzun;Tb+sI-7 zDx8;ErGnK8zeBFR`+bCA-@<;m`A`%JxGagB+u#R=GSnsw&{S;z>vDt_>_QQS7bHU||LTd|3WW0NcvBnOuiIEMl2e{vw>l9&JpMgTfsm zEIrF^c3W(qTIe~oWO;lqhRxS}B;te`7GbySKxUCB&D2?=K==E* zzgYQwTv4s8^hy@lAb~)VQ_2bhUIpXaXOHyUC z>+xo_5s-p)dtIzf@pyQgkn&;%#t4?4m&(w_UdlM9$| z>A%Qc_gmn|nXI)iXtP=2DC~EF?jk3()cb_1LXqHvA&~7?q3o)<$|NEKf9sKNsqAnh z_f(O=-T;IuHmM=-+YRG=@AU8iQ`JjCq?`9R-9=lKGD-5|n~>PKQo1^y@~e#8E!AtD z!3Brbx%#}^Xnyri$G44nnWskah*r-8c@w=XcyzRDpzg(XGF|89)8UzsXjC<>jhQZ< zv-`NL?s=DPm223_`{QTG`b+TlgO+k8{AhP*5KLuI7Jwm5fN@<%6ijBe_rCSnzRd3O zdJKMoP3{U$N7FG7`Tr4lB?NBzD+T_>48|JDlCHH)gi^Eo@4fzmKdp*D1`W{v?Eyrm zr>&DK@CEbj8U}VO49@@Qh=gz=i=hg4@_%9QS$LqPJUh)lbQo(ruzINe?tE9~2YR)i z<)EmmMK);mo|wtE-``hzUXb{WTEJ^1{Gvh`<}$f|A7gmr8D*t4m0AtWwHp%I>J#TJ zaWT`hQY`!|C|I@TWt6!Nxa9sZ?gWi5Wxna4rsj%)Z+#JSUzONiaUVZw_d0AJU}-6x za;!3e`NuBO8gfKHREvz(a}KhGf2zNLSON!GhFM)|Fj2ThOnZH>c%@Voqi(T-EuuzA z8?CPw?AB)K9XhvGlixq~9MQseJ*&=HJB(&mI!op-rr?O9>umiSFApH7<#KP*jc~%D z66hDPhk0or<;kw?c6Jo8`4Ca|_s(nZ*XB=Ew}#Vurj(m)7;nzfQ!|juLSpHqLXdu( z*%1yZqKmnsQI|!EW#Y1c$efNY#2#Te_uvYhtspLIIHK;o`OX>vNwsutg=uR}K$hb# zZ*j;Li+`Np?F+JTNf5=owDliUc;_3alWuz4NB$bipkqXkUf4dXMKFP8ahrnr%|KC* zLgc?jh<}!)v3Nnv==dAkRPWll*b)hCy^#KB0}+g+j+IX zk=3Nq@A>ng(hk~^4I@}BanxtuBIE^^J~)dn4ScTW80vJSv7@~rtf^%+o%`pbtn!tn z*Aeq$Z2@=GuYr1EhLJyrzZz?7m(#OD#*%-qGrs3l*lGy=qmHvrT@N`aJ?>V*0|g1w zYlmH}3v5P20LZz^K$yj}gQAi)jbjzFXOLD|Wd`yZMvCv(q|h9j?Voqcs*}WACuAv0 z4Ke3GPUN)@G0ccv;}7g}c^5tjS9NL7SciA-`4JVqjNDe;CEVQgM zZlP8lJj^)CIn)Xl+J0UA)9U}&hHKx(-`Li1=y33-#g%v0Ri*9phX*}b{N~CJ&ZgYd z>;u!C(~PTc168qzm=}*4d=_#w9@jK=mFjH8FT_Y+TD2)P_fIWzCFA>O$DUJpNvqvE zZ!iJc`6(mbboFfo?uhh#EA?O63|FWlWyeLnHOSK|9Vzom*i5%2z!KmN7U0&$%Vm+1 z4-r0y*E$@n=A3h-e(8R2dF<$O!d9nkk=s%DvTR45%JEOiWx#7Br$6OBh`MNI2d|&z zq`Y^Z?^O-Q*j$5IWmDZnTHV|5GDyLz3g1G;BogSoDLyh;tjSDsJ10llKu0Zl!OuR5 zJi)cYHoG4rZf3pbdsBq9DVD6Sq>(XBM|ZN!tBS`X^PU}fR9Msx+#S5xp|_V1Ps>4O zP9uAdLHiE8@UnJb+1Z+epUoci6S{o>&UhX_K5a8I8xtaQm+hT6ZTqr*_j?*eOsoYQ zy|CFlO1JHg{qa4$l6ORXS`oY zxca3e5uHgTsRmfQ$f}+E`eY#i@`+QskvZ=;3mqpm*he7}sCB01+zZ?g)qP~u5J@C= zGr_?^ewv9ELLY@^3wt)JSV)W*WFMK$ps7sPNK_b6f@P?Z@|8MEbsLCuNVRRGhPIogol}USbS9wK z&167RU-tF&KNj)NoQ7)ig6}FT<^+)bQ-^~4pe@-OUHIFVNL+uL4@b6eti1PjN|-@| zuz!U73!zM`U$sr2JOpt{AT8YD)<14qE2y`DDvhrS>tn$ln!Fx1xYgC%aFBR}@l6FG ze|InFZJSB8qp@)Zl{eLHrVP3ls>Py&TsD=CH_F$4P8bKCymHfIR#{t_T=wY(a^X*R zQ+#QFMVWqx%S!gEgK$$QhrlVm%f`qJz(9qR^Ai%2-glRDmKU3G06ZIbMs+_q;e- zidY2D!JZy9b4~#@P}q13)8+0DMD#?ND6~Tkf=kN!_ zPE6+pFw;cuURJrNBMFYAWZAE?7SW0Ig^OFwx-TqipQHHg;I;9HmRGp_E$kvX?^xqqCVNg#zc@!odi1NXm(Y>Sm8ZV*){qxUXqT} zXH#B9eiW|^Db5WXp`zfLW7Ph9%tuYxVttGQw89;T5g>Yf{>2NpFVyd=ssbwu$yJm1 z?p^o%ccLODjG_husKRNU8ZgBbfY#?ast0AD%SqLQX2iwPib`8UjN2&;A0&}^pn$#N z8M9NEwJcfVtS%q5zNW$Z*S(7!?3ig7Zf_eGI*0CmOmtc_@{7XqRcNgjeSfIcN$cTw z5+k$zxe|fr|EM%ty`#H_Ck@1Hs;`Lug)&{tEoP01gWgvZ5K5|=!LXX%I7VZie>63u z=n{5rWvr=pMKEeOA4@x@pHuT$0im%131Uhe5}LIB$3U!vFG9js-sa&#U%EX_hSS)9 z8&=mM1}xBEOOgvShZ;@iW0T+rS6>rHzv`O_f;@$V_5c0Q}lW^;J-bw{F4&k+|Ku6z(7Vj70c^rY0%58@PD|2s08 zHOWfOHc;DX{sW-P^xr8{XHy)DMm!b2NweWu{y~8ku&oV3(ReKd2J9@$g9=EodUTl3 ztIQk@Lj~GYo4T=osMj(q+93#Uy2Ez^DY@9Qk_A-S`r3tz`u1cVvIRw2U(WN%0pWr6~Jwt7s~E^L?nlZ0w-5Rf zl#lwh>+n9{1q(RDS}hTZn=B+<%ch8YHk8F+Nculz*83tCsra^l?@Z0FKMEEX`}TE4BDgOegpzcll|O8DwO*3DVlewD z(JXfuZ7eLihVjb(gSO<=`eWO+L|*3jOQPsEi?^;d+oE=tBd)7?XF2ni-{DB$Y?nP$ z2r0x*1CE0bs*ZJwiOPELFAb&At~i){XSwV;OI^d8eTxhyF+Xs3RdUj&Y8u~qW#8BVG4B(eNO_7NKPqFWf!uH_5B1_#v=WU% z%V2=h0>Y=K4oYu>=IN?l;skxArr(c5??$W%U53pEh%0-Z>>H0%%+Is_n2g@z)H1N5 zYr5+4eSZ|6W0jd^lw#Ig?vH4z6sxd+k6mV5WbT%D+CUAZM#PN7-kCUg%NIr8cxME$ z(9;8J`+DAGQ=-t=(+LI5AAk0X-8HEif6bu6zExckac-GI-#gehcI}8a$iGztcJ6== zV+=C#cCDfFoTh_1@~=5BJXa)opl|or>;2YSN*#$t`w(a017e>}3T4GUS13qApT5Ut zdAkLw&@LK`Bpa1m9LczWS0WaK3?_ze43YCPYK(+L^T6%PE@T$p&Zti0nFSpwd4xcn z;>ue=X*o~o0s*N0Kc;Y{;+Wz@2 z=kss#!UfuUv=>{F(Df@0Q5PMF6s_`Tocd!%7gb?-a-!~m8?6F69+^-GzXMC#E>~GY zGr`x=tAbekL9s&K#^Q|a z4${K)4l^8^TLihri?@Aqg;luO8or!Z{F}xZZ?giFq_xzVMYOcjG~MEG;khg*I4g_D z3wtII*cN-8O`IH`^%a|sHELd1bN5;cdq;L4>%7j1+RZpU77>Zvpmj213YHy3sEPPF~M4hzoQ2VX8ICd$*0l7rvK3deEtYi z8-0K_4mi{@^L0~`dkP3d{w^(&V1FrOQU0RNP(85SrP*#_w?6PC>F>LNjc;I$%a;}X z>GPxe$_mA*z`DOkQZVwDAo4UlsTu>>AnTiVeB3oKJ~UFCZPE_$PVwpXK}OZ=4FxNn zR>eWEXIY*Z+6cq#Z_uDAZ!S{HnU-0#U!1+qLc8D=!76x-%}!TdmM=)5Oa(sb!d0oA zJKGVN6O7sII}UcfvD%z?0hl=Q#=r%N6q+f8Otk{_I3d8Oh{`u@Y2h~k*Em1D3? z0GsLc^k^?e%<89v{q}0MXWSZ_vnOk10%0S+#;X*7ky5Hf=QlpoOE5zX>KTsE86Ej0 zrlnQsk%#Whf5koE;}{b2Z_!4ZI`Vo`KuYByhmq9UW(cV?P}W+rvyuhf=5Bndq3%r+S@PSu`Am*=s4_NQRxMi#wRyh#O#=es)JGtnv=t&E-f5t0 z4Vt?Ajt`@+Sa`{sNOV6>`Iin)ZQQ6!1<``Oll40<8@ib!KF_JmVI|iAyJ`h@&rT=u z0dIeu9bP(I;a5$WPWEa9BRRqet9qS%4)1rS%$M%_l1tAGgt)?EJ4mB}T9;OjX-G+X z!iREs{_kF<66vx~Q04H;SDF0Q+5S~YqY#0h-|@H=ooquhS+?=HmMGKgf~MYjnilX# zwq8u@#eL$B6#0>FT5Dh9tgFHBLI`z|q3$=I#fMX5+j2lXeuju)XL>h_VA10HD}<+? zEpEV#ZhV_`Ym@jb;ftQJQkmFhHaODyM>#n}K=(O=b34xb)^Gf?Lmi2N8Q8lj10s8~ zqKR{{@Xa^L&DH%8NOxbIrFFEFCkvjDOtsLtxS=-rix+2`vZxcNPhB;%z57XkdP34^{k>OHd44EiP zC;PE+ZlQNa0-KCh>21!4cHO$P&(*wbKlUjr=)Xnn{O~ZaKk#HTYAz9yD0MPep?FbT z=~{hVg-qRfTxn0ENT4;-7urd#6iRO9Eqhnjdl#Zn*L>;NwXm5l+uw4$#)j6JARIRK zL-~iGNw)PjbvaMD=*ChId*0v^I!IQ{ZYojV&IPlsS^R5Bsi1T3JnR45fc{LA@ud^_ z(YC6&^Z4XP&;4a7t`s1rv%Xx3YxDBqFZ^-Dwl<0&2AMAO6_I|v`1X}S>g(^^rpUZJ zLQW*Z5QzC{ZGkoCIh3>=2aqWqAEV~)MCZ$D)q!W#@=)YiMsm>i_lBQAgV3*23;UBp zJsq;UDoV{uIoRYW|K*tdx4-(Y9m!Wj&Klkt>M)E8(e`X?v zk80o{wp~=Z0B9sQYi0Y^643xvDnH-wlBYi?AGG0dDJL@k>DXz#b#Z8DxNw{4cW-vp zAgC5B!}8?KGg}YMla(4P`zQ}yNf+EUJ{;V&UKXyKv7wW>@zc=0xJXQ*uS7Jnt$E1| zxbqf|rA_;wFbF#d8JT=rMX%u2DPnS?rqv5t`P)2!fh#mm3DrPEy)8+eaqdP{x8*!G z&?(j0KDs;LKsTN@hHdJnu`O;{FFecgfMvFAH>~kl>vO^DKR>j57pRn%wo0yFH@RN8 zr6EN!Xgmh~e*b_X>+vyDg<$_)nD_v;uX-vB|DD_GFRM&8g`l3oM3XdL5Ogs|LO?wh z02E4w4#FS|Mt=BMAoQEqp78Cn{~a=?>O69i9)IGFngGxUzV9X-TXNL?v)cvu)QT)E zhDN15&#NK;WPlHbVh`riZ2?Uts44-_rC~qd3zC5qJ`=A6`2tA!_F{+NqERy+0K&L1 zt9N-3CodJZtzaYr{)6Y_z|$+Yyh?qG{+p%=?G{w`DQ#-8Q0Nmz1AM=8ya1LdsdP~E+K&**Z1IR+t+dH}KUWM`{2IKjPCs1`yT4c0 zacqbC{1(4stjBu%h;lHbE&ucD`Dn|s`y<6<%V3Z5bw=zES|!qi;N*f)2Q~8VPVq38 zqOLad-;jyImdP(ytG2O3n}NH+X(zJtNuOE#!?#tKRozlE3$b~8;7>vyjM_Dx-RZTJ z2;k=)*iHBz13w#!es8Qm;Os^;0jIq++K<=Tcr4>YdKT!CE0s`mQ@e7LZAUIog)sq% z4^p$~3whCcuXnmvLDEtI5wE%1XVF3ZIE70}Oj--_s9-5$d*xCy4D~y;zs}Xmn9;r= z4MzS6B4E6|>zJYx{Hnt0SpIRqQRpe_K~w3*B$be=8opsd(ez&hGj3eDkhNLCuZxCy zg+f=`pp>8&LFCot=O!qFV5u3gyHKP}6H{(KF;CQlSoBfYmmbM(FYi9jh7Y4e$wwc5 zO6tq2vrW~K5HTu)QN%JaMe8MON2_sT+iqp9_K-9}`VNUg6HBLII5 z$1<057BtkKVx96`Pdf3l<^hOVk^BpYnIz=@rN>eY6B1LFTXW(%p?6JdIff zf2qHAYr^zMM^TS8IL)&hBaEzMiwMiV&;y~E4+~>L%Y{xa>yd4T6qqD|K(`V?ji$=mybFApWfDgbRjd?M}D`Yhvn5mvVm2vcqc%85nnCwSTkPj zs5Wwf{pSxKw)Z5WNZc<8$hFs9mZ6@dw-!>M$>THG{;g<%pAX#>RZORMPTSMffjb1Vk8{b;bp;Ugq^zCPX))!fo;eA@nhBU zF(N@nwbjJ~DPIegTn=vvUQBgU64i!?-y{brdt}z@XN#avlKE7Xe@H^&EVO3^`;#vX zC{MpjX8mRTk?O!>*()nh2;p(i0?>?hqrV74TDDq9PQuW}ag@A0w}TySjrWuHVnK@; zaEyNU4~G1i!YL-5TTO9|U|iVmuzl)QT&;2PuPvosiMTzoe>bu)Jgi)CaIa&us|cU= z?%Qt~$^L}Dd~u+lj;4DE=?sm$x8a42%NQ%D7KYR>Le%M^j zqQ%`+zJx0bFt_M9zsh^pEzh_+bw*8MczpYxK7kseHe|rPu4G>iRAWnp*5-1{K-=n* zpTdU%i;?bIXB&U$tb43{LK1}X=-&3_$U$~E8NV@jF(TQ7Bv z8iVBL<-!#n13+F_x;Sx|0(Q@$+Q266IjV5F4p5ZXtw@=ia0tA znAZ}gcD=+jgcTux_W-x&*}A`Ay=Bl$<=GrL0|~>FR9Q$9m1+cV(wDCyFx7Cj z2DakcATtmu@GW*nRXY*)*Yk_RKP({((M7NG8<_d=bbbRy`(DP5mpX{j78>;OPsL=7 zhzb}-hj4nwP2HTne7L=UG;7kb6{nm(64h7;DjSAEzoz`3x@0axzLA^nv(6=9Iromp zA6udawPgzbV-xK+u3@L^;)NJ2UZ?iq`srdl$YB^n0G0h8=loxF-%eMv3KZ%B*XVnb zptKRph9U$CwJucg*30~NaIY;!5m_yO*Rpl~`^EQWQQjO98W%!F7quwdB%a$mliK&S z*1wWjjTnbJY}r#;jZ#Y!_iJSt<;Eq5-i*$?ZyTgry(Ui(ceh)4)p-B zo>UNMQ-q}+eCneh06Rb9m;&V-_G{sQopEyhoc)K!JF$W1NU<+4WFQQQ7WQ9ODyCXs z+~XC*{~`Qt)tBK{qiq!-BLo!F-6r;AF^tS%42ERu2HkdnuwNh-u#sX>Fr*|5Dg7iL zj38pdax}U2Uy-q~MoVJPzf)e3Sr>UtKzTyE_hmOruvXu~P=G1<3xbGV9_*Yub`#z> zrc-*JE0&CScofh@g~f&-t7nopCVh8huGLW8n{0DTxIok&ivpw%y?$&T*STUOGG<|{ zLawYeTxR{QuuOWh4E3c|0$)n} z+23S!kVpOz2|pc;iY_s)!cg$7cR8!xo(5aMNZ!{U3L7HT>EVUf!28yF?4Jq{{Zump z5j($6uy|vwKtu7${9;6?5txj|*E&{nJ3j6PVrH4QiAH}4oNPX-&;`KOtYv;*8J#!E z(}Wo;GFf@XsUJU!i-?+pl}^kTEF#bYC>9qYOlVC0m-j+|L*3x7WwrXMvNUMm_6YCY@* z+0joHpFhjy))8yy=-e|knQpNRBNz-lw(Fl}>*8=$ULRDD=hyAwkFzFg4uX83s=qKM zwZX>9;EDsa9zBWEOcq0SU0)TCPp4@g-UC*&>WsijU$O&1R=RK4FIZJ5(&}fRvIWU1EZt0@pTUA1t#6{SDFLgh?e4Y>=o5kU$Zh~}4=QWK~7hk!jvL`@Wi)O-FX0)iaUQw7ZsKA&M2@{uvq1XZ@^ha&|70OI9w-E6QH6jZyCV?D9uPJy5~RY9;N36*Oqthd z3>UF+1Fj%~Vi^={y&&+lS^ao9Y>3_J{f_qY6V%&WO7j0^U(D8=UP-Rcex>b5pa)lN z22Hf^b1$5))w@i@2C>&Qn%Y$%o_zpc5_AaqnDNwK5MWjXedEa}r^4Mld`HG^l^-Tr zu61IQ?$Ne%w}sBd?k{z`GS4sD&<>LYZ2Xu``=N|Ofw{Xpw%4o`OUqzq((pNok0JI6 zGAVzRdtlSzqhVh$B#$~E^>?N7JLfI_W=@kf@$Bt4}gb z2j3pz%n<;OZ!3yw)rVJshg9Wqlh_z;y&@7ePbk&ExLcOQMLzUlY4H=o8#A(wZ{IWC zYUXBJV061FI{wyS9jnu~J11`(rUT08<(bPjEZDchbxZRi5V~s$fr|N5gy1T6dyoPG z4jCH@=imD_MHhhC%cWNJ9D^U(%+W#|;Vg!WX4m+`DlK0sM)yh^r(`#NEWG@+qJ?1= zn`pP0?e|L{D*pw4RkvLNa{R**12hD8;n77jHzl#Q<~|_0=2O$Z#vRQ4{%02BAwH+w z?(Eeej8)P>byI%O^Iund_4*cX0woiT6#pdwhcKMSO?C@NzhKx`SE|AaREmaH9q3jm zNNsyTsB6CZG8Tn_DCLwL#kM6w!Iv^IO750sQ>;?2s)Rsxqj}~x>K#x-9)o?{3wh%Q zWAHHVV6XW1zXRpXyIrC)9cfo{+C@u_i)l+`+tQz!$Me2%HC))6_%yEVN+568pM5~_ zvD(R#PdOa4edzP{RVUy+th78(#%8?I*m}BX4hdOnxeb~Ti^aA*75v_Oe2SzBGRwXXzHw5X3@r5^oD}NTOmU6b^9IF}nkLFx>D`xFV zcuOTWn{Vpwr`D{|fZXNYy6H3es>)3i7ZAJ^llz7ditKLQCu( zrjluxu6h58s2<&7R8@#v=i14e5y=p+ErV`nk8s*6S(8JN!X!gpg_(=|)JDaS*CGu! zGVPxcEP)Ql1@pvGi9zzY>dJ$O!c{{51vkd(fuoU(<#Lk@ z&toz82j_cot&3rhreMhd#E)$HxsUO0Ln2(1ll?A%6B$;d%VWX$AGd(dsx^fJf3fs= zG;m4wJE%>Q{c0|_C?P@R5x0bcVEKey`STcH<-564|IEjWrui* zIf;&_&Qci)SFVE3x(vagN(o5OMO0qX5-5K_XWitcxkx{tnb^w;ed*(;bWhdXnM(85 zm(_*d$QPxcae7DD{wjCUQwB)4G;K!d#xLxHZWNNHBk=~e&NN-$>Vj?2DCC*nRKc=` zf-Ve+l|o;o#oF^#aT%0Rp}RL&u4l&Ex4grUa>07C>2xU=OF09{P?fXd zB!DB2!BE8a;_6>|~7nVp3~gg;%X z;GfmbJ&C)t-GYCo;}^;gf4K9gN7}2IFgU31QaSaRx>TJ^3N37}60lM$Kj)<+H?4w; zlsWTj+f_-`d6hAWU|PKN8f9Oz9ho7t5lwBXMV30Tsu;?I{Y)1^VS{Va4`Qs9WM3$+ zg(_NesUTTYQUiDlimw~j2fgnFBs)8F_$nB~}x=TNtIUbg-6vE7oYK(2Ptyx`cG z%TS<*BakqqkMB0LiT7dbG>PK)>n|{fY|3)$sHQV&1s3D7kDYhwagF~fvZDp7tLSIu zk0F4^!Fd~&V^tGUa(f|=ALm}ME$hL|*m(C!4(HD4A7~+4?eNTR7mML@;oe3InTg7D zc*RiFs2HKFuJo|)V(uUDr`@X!ssw=>9gR1&CR^t#bCE(IulYgs>i4LN zrk;d%&n7jpttL$2<9~d&6}}j<%G*aKALV@R9(*#qNZM-qI%UuYbwAzJO`}F}mP25< zUn%nDl3ksXyN^e{C9(%lQavaq37r7(nRn|n5v>r0K=%F_zy?l5@~B=0`UhBD&Bq#- zN4#34|2&Eht-RTnp~&vxRiLwa}fwZuqs#F?TUO;u&yIVX|NV>%!Bv6$GmL!dVe@Za*bf+6U z^$N0@Q_kT=Jz6D zHVdT|&N<4@P)ua}$SJ??_p+yEumz^mKr81pFuZzWGjGzy z%5drNiC!9qh;Zb0@k{3Cm83tx+?IIE=@9d|CE=xt4cwmXOKsw!469X;4)`kmygB!N zX2%zp&{S8sju|@rWpBl}BzsKpT3afM?l%2xEL-OYK2k~x0CWWk_`5ewG2?xt0vq-H z4i@5a)j23~jbJk4mSU?g6u1btO6Wpz!>XsHogF)pmOeaLpThksLLm^o8c`u&mnm^U(61r(hH&@9#w-NfTzT!sCNo2xFvR_9rnjK_YXeMb{#s+>Td->>a9 z6vo2!47#}HEP6e~(Rp58r1L45o1aSFaaV>nm|;lQU*Z?3W#86mIMTW7w>)R zt^3;jW6qj0v)4ZRx7VJtXMVHxrX_|x<-}^Y(^8YGOYY3(Qa}q<499txo3(MQBTX$a zz9m@Tbi$1SJL3C5D{>=6-XUEvN`17FN9#}P63gd;Wm&{`a zaYbMrzu_tUl-X-SNaPU}iqru-O*P;ABKDC_leY+*>_f>>m950N>2B`;s! z?j2bC^C|cJt9|t{NRXwXI1vPJr`(VhTMH?AG8K(sHO zO&eoZ*7op@-50HHEWCvvl;j>R+vSfR1G|HU`Z126z>K;_{^%TsjXfXn7 z0oyPK6v*>cY5{rkIvR+L&oOHvsB$YqLBg>Nh5<9hpxJQfK5E^8t%)x@zQSl;2bGwv zbF)iq_~p@EtYI*jMxO_RW~L895>x$%PrVL*1@u*(Ly8y`cG_XPN@$KSOX1s=J%1gP z0_WCniSsoE4||WG^yxtl#ff7<&6%qJ#Yv$Z-|!?zmdBE$Ek?tN8djZ1(kPM>PubD{ zj$CZ~#wMzyjZHJV_x*GFW7V^!YV%+14#mTa&~84moSnP_6xU}Sm^!o=iM{c~;!yfY zwtv8gN8HO^1}|RNF9oUO^)`LmD3U=~2p-3-x6`6?7wM6dk~R|Vem{WowQRo*oi`?V6ufaDIvyUI;-v;zxiG@OYI z_rAY%P`)QiQ4bcZ=fc!9-y0TfB{~RFXJU0VKpQCVrliq-%2oW`$DfEVxv(pM!nQ~SAY35novOi$PQ7?d_Lta zPxV#*{Z#{l=35O`C{Q)dWPYrEQ-u6t`1Or?pa}fcnRHSW)molc>bH+-aP?cH8wDmV zic$t&^(h#%F&et#U1WcI7y2G>Cv8CrTDy1gxqXdJyvcZ6y!KkC?j^sc8ASm<>`Stm zZIzkOw-vO0-OjyUMgq3)!l3CrYzPtm);~G0Y7J&UzUk!N1Z{=wrLuq_BPeBm<*JTMjNT8qgSNyOTuOXCArVC>&6SA;7Yl`Noq+n^wL1# zwh((7>0ro+6`=QQFXR9)5+=gL71D*F!|rOvq2qZMpWC>vMJj9Scx6d6qg$7FMliT{ zL<7!)R%IZ{fxX!PM@*{_`W_6b4W{IkfU$U@IfJMFZpjTT(!h`iAh8X0TT)^I1eh5; zyS;{&Etu51u>=|gA0c1sHNGnz3k97m1% z8&5^3hn8eM3wj1GXHhV49JRrqT325OQuJV^(vd^3YI&J3FQvV^S1XWSoAL$JiD31Mv14Bo47 zvFUNq$*S^)6$Id<>rmKFStB!Z1`_(=vW~=Lo0o8XQl0^z`#$t#fqht=9enMu|8#8P z_^Po~MD?9jb8K(2ZX}`nEH3Hi0FNFx*i&;|E6u^dT065-8T$A?%A4#nB%ul#R!$s!TX z5M4faczIhIQmYfTu#F=t`*P2yldP7HQur#(g*aowYI4FtcvfCRYTvLwXFe{g_5 zYh4K-?G^+Fh<95#FfA0kVUGQ@HlBHU^hKIPVa@*JR9BOQeVGx5LddewgF*o+;4~3M zgE)9z6M&xdjKP?lFYJ9@@vr3pbsVZ)U8NHpxA^%JMYgzpa%D36p27U49xY5iVAzpZ zx#P@4Wb4M-)kalNN5n@Q&?K&}iB}JH-*Vmh_2FpijmOa`<5tcLteHeVx<^xdn;<~@|&Yl7lxLd(Q z$1dc?D=fuMbpeY)OVEkLz+{i~}VjM(l zO+&40F1QzOq01XrT7?rrtd~O3+7i-MSLjqF!$%i8pCoUyVK~rl7Zb9?X#=$98T&}! zuX?=!#0l+m!TcDXbBn)58UfR4LxPD$=oUV+z7|o(=y*80Vr0gSJ&~mrsg;==$mf7MDkZm0Mr@1PLPIr(5H)Dixjjum9FeNla`jIC@{H-ntWKLL? zPSzAS2@~U+&W!1u{CKzh@X0^7;>KwqD2VNJ_<&R zf-BW2IPgnh+5kiw_y>gr#$3?O^YmKCdlJeh6)=@nqV0qG;1mIP%Y4$1QQNy_q4{U~ zEgA@NXqWmwzkTv?UO(v(k$+UY55eu;sOiJ^a5Sz$6D&Af2j%QT`|7Q)yj}Hut_whf zQ*piN&-L~jZ=PWJbC7m8zo#Z56XDRb(GQxI?4c7*-j1E61?t#$7o?-sP6Nk->bQ4* zq7fHc`Df(mTrD;BI(j=H3u=P(k#}z7X=0Knc54n}rhX^8?ZFb>)=*Y>iVYd3K zlmc82O<#<%%sDp6c_4oOS&+0oPYsXhMpXNcOSNKmMSfj&L;^q14J406Pu`6mbo_I- z>PhXHex$Y^e!?jm*2g0Y0cesAJF(p0MQerHtETk_tR>!3F9YJZT?V(JqBi2{CND74 zO+=KvRv9?g=+O$Nn>lzF$o(*#55=Q$E8YB0H35!3R2;@I)bOLLbGtOuGAM-F-bEut zc^jS5hij@FWiIxb7Mco7Q7p8qSCwqgtW1c()zxiNe8TMtLGU<6*nEKN8P4bk`MQTV``t7ZVXL74h3QA9wX94Z`V`O>2`-oveD$bDqy!5Vo{w_9xC9 zTE5S~_7M`lPA>LS#1vo@It}$MV0TKRGgGqPEH;s^Kqm46a%m0zQ9CI1&hp#v1c?qA z{i0C{C!LP`Qg7zAuMM1(P=g!QgBc1hVPgg;blUL)kb6}rHfEHMPEsdmg>#Cz_$bE% zy%uP75b|TOSe3U9wsKxDJ)4+MN(rO_yqr=;f4!@TS^;|!mK^u}$#5q-{$g?yO9uNx zITJlCn#NZf$-&b6g>+H!y<7MCngt+-Us?ug+_C@ux~jD>pgKSaZI?kv1l7BEa%7efU4}bCBK0%k!`e)*oEp*mdwgZC0 z*LQm7aD|HJ58G9$-TFdsf#-%<2e~;TQAOKedGe%+OJ?BKdo!4A-0W+_d2i#)Gk-_U9F&biLyVW_R?sY{_4Agr) zN>xX}tOc6$OnbI}Cu0^7Qic(XEc3l>i!FaHqGm0!%E_L3`^`euHV+sQZ0#HjtJebk z`o4ncYH%kF)`WSNdFUA&2^K;-ZOVC~VirF-FnAN}Ie{@;Ak9*+UO#1&r2&464G< zw_b@T!n;^geMbVt2qNBU4o!wBFmVuk7fwk|RsXE;mWdL}zL!2AJNtP&BT(qBavHKb z_=$K~F!Zv}M6z5s2MKMX-sn8l)P;<2a`6zX>bU7+be8mKt-=NUIeWvc{1l#B)xOW! zEFkxxQeijyPJqCFC`Z&4*>Hz208jW|pPPoxf6M|EJj5p}C$dO_K0fPS=84Sh*Ku^xy-Mhrk zz(ch-m0#X3Wp$eHxh5*3WJ8bo#QgKVl5g}+*P^kRE zx;63jxyne76fa^YeH+1Y@Qew6DV8g}%1waZJDQ|UbJ8(X+~dNNIGd50KPQYZC&FN^ zyltY0u$Nyu6qsPj-4-)TS?;nyQe<<=*5E1VP~mCBAc`#$MZAozyKtLFP1xypJm5i| zJ{jM^Zuc!8_xye`S~WjyO^ItXaf9@Iwt#_Vz7sZSMEWljW z-OV4m<;FsFCE{ph^=_CJpHJLwxL=t351am;S}>SY#d~G&Ee!p-n#a6 zf&}ua3vt(Kxj@g?=wY#iYu)&LW)Cc0H0C<5*Z9C+>4}|zQ)-20EhVa8cm+b@}50xG#DP~GnnrE7{0YK2tK*E zh+k5^T`!m+KJ8js_h>T9x^BJuL@h6#n^-%gv60ZI4ZYC0-=kQQA1VC3t$NKaX}sz0 z3r$pt=wLOwp9$URfxQWRIZ3D(t^HeE0+g9U$^oV*o(PB@MNin zdB~e_Dj57>Z(7}T+**~bJRwbUyk4Cjnomlj?BDLPibfZGP$eTB#L2Nv7FpIrwU9w< z`>YxK8C;3y?)_w%!@W9r>Jm-gb*{{J|N0yFIcfj6!Ja-Nf&vu?yv6x{&{v$T%~NFB zU1hb*QG0y`Gg-#Q%d|aljFv=^a(uth^Rrnog2=PP8*NdIzph-Z5Ieaf@3l$*!IPlzzp{O9JYA)+Bt#fLEZaFCgHkLI+wX_8mkuztO5_& zOgg$xX|9HPGKjZery?85at3kDgDLEM7#{Wd-UEd0)p=ezZ&e=PR#lp!{Fztv2ZhMb zJR4_OR-jn5KB!jo&6RDZqsN)Lg~#%Je$`m=18y*?zU4HJ4WzX!WnIGe;!_ga#)zEm zMv{BCNI%Sv@bf>`=)*GU8})O5U|$YbZK1x6&;An_-dKs>v%^g0VE8I1lkxjG^@3!n zJv5f3QCt}L#{(2;O8YPsc|h~N{~LUFSlT~BtyD^Z>GZ3Z@&`D^4;NeO3ue5Ca*it#!cwK^ zACY*ajI9FOCXdOi@rFv<_ST+3)|tc+osykb2{6TcRf%))lhN4)8Z-q3=Y8vgpyB!J zX|KT37IrXoQwu_~Al$hF>^2ig+|UE|Zl9dB(ToTv*DE^Azp)m#iBz*HkZ8xH>mTQB zVL9eLP(C?$?yBqg@&eI~4V8oy@r%)pxB2kLn&hcR`gu}p>-is*0$6A_K^T*;!j>?N zG$zKiM|L?^GWC|4KhLevscM6-D~jb^do||pN$Uyh@u~#}|BzFrMIN8@zM1geX8DDf zVb||dKmI(0-wQI_c&+nuVke5ezsi$tcw&I=vhv`I*2RpEwcK>nPK-4 z67zdKfy31>!c{OnPLNpu)x}7?nQ;sF7PFV%lHBs15q`(u& ztVFA)#i_ui$v;u2)g+T9B)5vxm28DApWV=^WhHkLLBX%XP_~DY9yLR-6u;%7~?` z@@AxWBfrLTQxEj(K1^R+PVg18L}}KvV!{GvVIFw(A2&1uoY~VyWu`3u@K^=Ug%(8- z2O^VOxc4XDiTwU``mEY>(MkFcQsO&4yVN(k>7~H0z$xP9%d_u6RB5QisZo&whj#BU zBa-*dy+c^z1NE_|(qtl?Rx3zCBHvqBbmrS<{& zj15sRKZz6VmWz+M|NVqj*t<72uV}GxRejt3Gk(rV?lCD0ZB4QY`->R%Fi4YI|Xn6J+6i^e}CW9XU+NA*r(one#+5o+2ULaC|mtsBabuD zc~ro|ss+jAiU`wFn1j&2XOON(>5tVzn~>=?vm(7|OgJxUoJIyj(ZQr;z#S3Vk`)Kh z95)EDYPrJYMx1Q_A;A9_5Xou82`^81u{{P@a+*lGp{_0WDR*CUUSN6*IOTwX{64i; zKvbpc0JfthoIsbDCj;&xS19yAJ2Va2sFW_SIU)27*_^0Ea&AS#>7cA^D$BMrg}bw^yX zZqjd-w%=L8veQ^{(OEWdX8&pbV8N8Bj~R;ldi{#9prxqs%>Tb`^goM9&jGrX>En24 z+ooDHq)$ From 05e84f091cde936545bb50653130102aae973068 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 5 Jun 2024 20:24:49 +0800 Subject: [PATCH 0008/1065] Update README.md --- Picviewer CE+/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index a692ec881ca..fbfe6d60da6 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -44,7 +44,7 @@ Need more rules for peculiar sites? feel free to pull requests or open issues. ``` json { "name": "Example", - "url": "/xxx\\.com/", + "url": "^https://xxx\\.com/", "r": "/us\\.xxx\\.com/\\d+wm//i", "s": "previews.xxx.com/images/" } @@ -90,7 +90,7 @@ You have the option to use a standalone userscript, which allows you to manage a }, { name: "rule2", - url: /xxx\.com/, + url: /^https://xxx\.com\//, r: /us\.xxx\.com\/\d+wm\//i, s: "previews.xxx.com/images/" } From 4938e355c5327d4790bb8fca6e6870bd1f354c97 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 5 Jun 2024 20:25:17 +0800 Subject: [PATCH 0009/1065] Update README.md --- Picviewer CE+/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index fbfe6d60da6..e2973b1381c 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -90,7 +90,7 @@ You have the option to use a standalone userscript, which allows you to manage a }, { name: "rule2", - url: /^https://xxx\.com\//, + url: /^https:\/\/xxx\.com\//, r: /us\.xxx\.com\/\d+wm\//i, s: "previews.xxx.com/images/" } From 1845a2fe56522f274fbdf040e876e0e1d11ccf2d Mon Sep 17 00:00:00 2001 From: Prankster 199 <74471233+vfggf95565@users.noreply.github.com> Date: Wed, 5 Jun 2024 20:05:27 +0300 Subject: [PATCH 0010/1065] Update pvcep_lang.js Adding Arabic translation for Arabic users. (There are a lot of users in Arabic) --- Picviewer CE+/pvcep_lang.js | 260 +++++++++++++++++++++++++++++++++++- 1 file changed, 259 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_lang.js b/Picviewer CE+/pvcep_lang.js index ebd442dc232..0cd01118772 100644 --- a/Picviewer CE+/pvcep_lang.js +++ b/Picviewer CE+/pvcep_lang.js @@ -1,4 +1,262 @@ -const langData = [ +const langData = [ +{ + name: "Arabic", + match: ["ar"], + lang: { + // Translated by Prankster 199 (vfggf95565). + saveBtn: "حفظ", + saveName: "حفظ الاسم", + saveNameTip: "احفظ الصور بالاسم", + default: "افتراضي", + textFirst: "المعلومات أولاً إذا كانت موجودة", + onlyUrl: "فقط مع الرابط", + urlAndText: "الرابط + المعلومات", + download: "تنزيل", + saveBtnTips: "بعض الخيارات تحتاج إلى تحديث الصفحة لتطبيقها", + additionalFeature: "ميزة إضافية، تأخذ تأثير عند الضغط على مفتاح Alt", + invertAdditionalFeature: "عكس مفاتيح الاختصار، استخدم الميزات الإضافية افتراضيًا", + copy: "نسخ الرابط", + copyImg: "نسخ بيانات الصورة", + openInNewTab: "فتح في علامة تبويب جديدة", + closeBtn: "إلغاء", + invertBtn: "عكس", + compareBtn: "مقارنة", + selectAllBtn: "تحديد الكل", + closeBtnTips: "إلغاء هذا الإعداد واستعادة جميع الخيارات", + resetLink: "استعادة الإعدادات الافتراضية", + resetLinkTips: "استعادة جميع الإعدادات إلى القيم الافتراضية", + share: "مشاركة", + suitLongImg: "تناسب الصور الطويلة في نافذة التمرير", + globalkeys: "المفاتيح العامة للمعاينة: ", + globalkeysPress: "اضغط لتبديل المعاينة", + globalkeysHold: "اضغط مع الاستمرار لتمكين المعاينة", + globalkeysType: "طريقة تمكين المعاينة", + closeAfterPreview: "إغلاق نافذة الصورة بعد المعاينة", + previewMaxSize: "الحجم الأقصى لنافذة المعاينة", + previewMaxSizeTip: "عندما تكون نافذة المعاينة أكبر من الحجم المحدد، قم بتقليص نافذة المعاينة. 0 = معطل", + loadAll: "تحميل المزيد من الصفحات", + loadedAll: "تم التحميل", + loading: "جارٍ التحميل ...", + loadAllTip: "تحميل الصورة في الصفحة التالية", + viewmoreEndless: "تحميل المزيد من الصور عند التمرير إلى الأسفل", + fiddle: "تشغيل", + fiddleTip: "ظهور الصور للعمليات المعقدة", + addImageUrls: "إضافة صورة", + addImageUrlsTips: "إضافة المزيد من الصور عبر الرابط", + openImages: "صورة محلية", + openImagesTips: "انقر لاستيراد الصور المحلية", + closeFirst: "أغلق المعرض الحالي أولاً", + collect: "مجموعة", + collected: "تم الجمع", + exitCollection: "الخروج من المجموعة", + exitCollectionTip: "انقر للخروج من وضع المجموعة", + noCollectionYet: "ليس لديك أي صورة في المجموعة", + collectDetail: "وصف", + collectDetailTip: "أضف بعض الأوصاف إلى صورك المفضلة", + playSlide: "تشغيل الشرائح", + slideGap: "الفاصل (ثواني)", + slideGapTip: "الفاصل، وحدة (ثواني)", + slideBack: "رجوع", + slideBackTip: "التشغيل من الخلف إلى الأمام", + slideWait: "انتظر قراءة الصورة", + slideWaitTip: "يبدأ العد التنازلي بعد قراءة كل صورة بالكامل.", + slideSkipError: "تخطي الصور الخاطئة", + slideSkipErrorTip: "تخطي الصور الخاطئة بسرعة", + type: "الفئة", + typeTip: "اختر فئة الصورة", + showWithRules: "إظهار الأيقونة بالقواعد", + showWithRulesTip: "عرض الأيقونة إذا كانت الصورة تتطابق مع القواعد بغض النظر عن حجمها", + advancedRules: "القواعد المتقدمة", + advancedRulesTip: "مطابقة بالقواعد المتقدمة", + tpRules: "قواعد البدل", + tpRulesTip: "مطابقة بقواعد البدل", + scaleRules: "مكبرة", + scaleRulesTip: "الصورة التي تم العثور عليها تلقائيًا ولكن تم تكبيرها", + noScaleRules: "بدون تكبير", + noScaleRulesTip: "الصورة التي تم العثور عليها تلقائيًا ولكن بدون تكبير", + smallRules: "حجم صغير", + smallRulesTip: "بكسل #t# صورة صغيرة الحجم، الحجم الفعلي للارتفاع والعرض أقل من", + lockSizeTip: "قفل الحجم الأقصى", + command: "أمر", + commandTip: "قائمة الأوامر", + onlineEdit: "تحرير عبر الإنترنت", + onlineEditTip: "#t# تحرير هذه الصورة عبر الإنترنت باستخدام", + openInNewWindow: "فتح في نافذة جديدة", + openInNewWindowTip: "فتح الصورة في نافذة جديدة", + findInPage: "بحث في الصفحة", + findInPageTip: "التمرير إلى الصورة الحالية في الصفحة", + viewCollection: "عرض المجموعة", + viewCollectionTip: "عرض جميع الصور المجمعة", + inCollection: "غير قادر على الاستخدام في وضع المجموعة", + cantFind: "الصورة ليست في الوثيقة، أو مخفية ولا يمكن العثور عليها!", + exportImages: "تصدير جميع الصور", + exportImagesTip: "تصدير جميع الصور الكبيرة المعروضة إلى نافذة جديدة", + downloadImage: "تنزيل جميع المعروض", + downloadImageTip: "تنزيل الصور الحالية المعروضة", + copyImagesUrl: "نسخ روابط جميع الصور", + copyImagesUrlTip: "نسخ روابط جميع الصور الكبيرة المعروضة", + copySuccess: "تم نسخ #t# روابط بنجاح", + autoRefresh: "تحميل الصفحة تلقائيًا", + autoRefreshTip: "عند عرض الصور القليلة الأخيرة، قم بالتمرير إلى الأسفل، بحيث تقوم بعض صفحات الويب بتحميل الصور الجديدة", + enterFullsc: "دخول ملء الشاشة", + exitFullsc: "خروج من ملء الشاشة", + config: "الإعدادات", + openConfig: "فتح الإعدادات", + ruleRequest: "طلب القواعد", + closeGallery: "إغلاق المعرض", + returnToGallery: "العودة إلى المعرض", + picInfo: "انقر لتغيير", + picNote: "تعليق الصورة", + urlFilter: "مرشح الرابط", + urlFilterTip: "أدخل كلمات رئيسية أو تعبيرات منتظمة لتصفية الروابط", + resolution: "دقة الصورة", + picNum: "عدد الصور", + picTips: "CTRL عرض الصور باستخدام", + savePageTips: "احفظ هذه الصفحة لتنزيل جميع الصور", + scaleRatio: "نسبة التكبير", + similarImage: "البحث بالصورة", + scale: "تكبير", + horizontalFlip: "انعكاس أفقي", + verticalFlip: "انعكاس عمودي", + actualBtn: "عرض الأصلي (A)", + searchBtn: "البحث عن الصورة الأصلية (S)", + galleryBtn: "عرض المعرض (G)", + currentBtn: "عرض الحالية (C)", + magnifierBtn: "مكبر/تكبير (M)", + picTitle: "عنوان الصورة", + exportImagesUrl: "تصدير روابط الصور", + exportImagesUrlPop: "Ctrl+C لنسخ روابط الصور", + beginSearchImg: "#t# البدء في البحث عن الصورة ...", + findNoPic: "لم يتم العثور على الصورة الأصلية", + findOverBeginLoad: "#t# نهاية الخريطة، العثور على #t# صور متطابقة، بدء تحميل الأولى", + loadNextSimilar: "فشل تحميل الصورة الأصلية، حاول تحميل النتيجة التالية...", + loadError: "فشل التحميل", + openHomePage: "فتح الصفحة الرئيسية", + position: "وضع العرض", + positionTips: "لإخفاء ALT اضغط مع الاستمرار على", + topLeft: "الزاوية العلوية اليسرى من الصورة", + topRight: "الزاوية العلوية اليمنى من الصورة", + bottomRight: "الزاوية السفلية اليمنى من الصورة", + bottomLeft: "الزاوية السفلية اليسرى من الصورة", + topCenter: "بجانب الصورة", + bottomCenter: "أسفل الصورة", + floatBar: "شريط الأدوات", + previewFollowMouse: "عرض المعاينة بجانب الفأرة", + showDelay: "تأخير العرض", + ms: "مللي ثانية", + hide: "إخفاء", + hideDelay: "تأخير الإخفاء", + forceShow: "عرض شريط الأدوات فوق الصورة غير المكبرة التي تتجاوز هذا الحجم،", + forceShowTip: "عرض شريط الأدوات العائم عندما يتجاوز حجم الصورة غير المكبرة الحجم المحدد أدناه", + sizeLimitOr: "فعال بالطول أو العرض فقط", + px: "بكسل", + minSizeLimit: "عرض شريط الأدوات فوق الصورة المكبرة التي تتجاوز هذا الحجم", + minSizeLimitTip: "بعد تكبير الصورة (لا يتطابق الحجم الأصلي للصورة مع الحجم الفعلي)، يتم عرض شريط الأدوات العائم عندما يكون طول الصورة المعروضة أكبر من القيمة المحددة.", + defaultSizeLimit: "حد الحجم الافتراضي للمعرض", + listenBg: "استماع لصورة الخلفية", + backgroundColor: "لون الخلفية", + listenBgTip: "عرض شريط الأدوات على العنصر الذي يحتوي على صورة خلفية", + butonOrder: "ترتيب رموز شريط الأدوات", + keysEnable: "تمكين الاختصارات", + keysActual: "فتح الصورة الكبيرة", + keysActualTip: "اضغط على هذا الزر لفتح صورة كبيرة عندما يظهر شريط الأدوات العائم", + keysSearch: "البحث عن الصورة الأصلية", + keysSearchTip: "اضغط على هذا الزر للبحث عن الصورة الأصلية عندما يظهر شريط الأدوات العائم", + headSearchTip: "البحث بالصورة", + headSearchAll: "البحث في الكل", + keysCurrent: "فتح الصورة الحالية", + keysCurrentTip: "اضغط على هذا الزر لفتح الصورة الحالية عندما يظهر شريط الأدوات العائم", + keysMagnifier: "فتح المكبر للمراقبة", + keysMagnifierTip: "اضغط على هذا الزر لفتح المكبر عندما يظهر شريط الأدوات العائم", + keysGallery: "فتح المعرض (عالمي مع مفاتيح الوظائف)", + keysGalleryTip: "اضغط على هذا الزر لفتح المعرض عندما يظهر شريط الأدوات العائم", + openGallery: "فتح المعرض", + magnifier: "تكبير", + magnifierRadius: "نصف القطر الافتراضي", + magnifierWheelZoomEnabled: "تمكين تكبير العجلة", + magnifierWheelZoomRange: "نسبة التكبير للمكبر", + magnifierScaleImage: "تكبير الصورة بالعجلة", + gallery: "المعرض", + galleryFitToScreen: "تكبير الصورة لتناسب الشاشة", + galleryFitToScreenSmall: "تكبير الصورة الصغيرة أيضًا", + galleryFitToScreenTip: "التكيف ليكون يحتوي، وليس يغطي", + galleryScrollEndToChange: "تبديل الصورة بعد التمرير إلى نهاية الصورة الطويلة", + galleryScrollEndToChangeTip: "فعال بعد إلغاء الخيار السابق", + galleryExportType: "الترتيب الافتراضي عند تصدير الصور", + grid: "ترتيب البلاط", + gridBig: "الترتيب الأصلي", + list: "ترتيب القائمة", + galleryAutoLoad: "تحميل المزيد من الصور تلقائيًا في الصفحة التالية", + galleryLoadAll: "معالجة جميع الصفحات تلقائيًا عند تحميل المزيد من الصور", + galleryLoadAllTip: "قد تؤثر الصفحات الكثيرة على التجربة", + galleryDownloadWithZip: "ضغط إلى ZIP عند تنزيل الكل", + galleryDownloadWithZipAlert: "جارٍ الضغط، يرجى الانتظار قليلاً", + galleryScaleSmallSize1: "الحجم الفعلي أقل من الارتفاع والعرض", + galleryScaleSmallSize2: "البكسلات مصنفة كصور صغيرة الحجم", + galleryShowSmallSize: "عرض الصور الصغيرة افتراضيًا", + galleryTransition: "عرض التأثيرات عند التبديل بين الصور في المعرض", + gallerySidebarPosition: "وضع شريط الصور المصغرة", + bottom: "الأسفل", + right: "اليمين", + left: "اليسار", + top: "الأعلى", + gallerySidebarSize: "الارتفاع", + gallerySidebarSizeTip: "ارتفاع شريط الصور المصغرة (إذا كان أفقيًا) أو العرض (إذا كان رأسيًا)", + galleryMax1: "التحميل المسبق الأقصى", + galleryMax2: "الصور (قبل وبعد)", + galleryAutoZoom: "التكبير يعود إلى 100% (كروم)", + galleryAutoZoomTip: "إذا قمت بالتكبير، قم بتغيير تكبير الصورة وأجزاء شريط الصور المصغرة إلى 100% وزيادة المساحة القابلة للعرض (صالح فقط في كروم)", + galleryDescriptionLength1: "الحد الأقصى للتعليق هو", + galleryDescriptionLength2: "الأحرف", + galleryAutoOpenSites: "عناوين المواقع لفتح المعرض تلقائيًا، واحد في كل سطر، يبدأ بـ @ لعرض المزيد", + autoOpenViewmore: "عرض المزيد تلقائيًا عند فتح المعرض", + gallerySearchData: "قواعد المواقع للبحث، أفرغها لاستعادة", + galleryEditSite: "تحرير الموقع عبر الإنترنت", + imgWindow: "نافذة الصورة", + imgWindowFitToScreen: "التكيف مع الشاشة", + imgWindowFitToScreenTip: "التكيف ليكون يحتوي، وليس يغطي", + imgWindowFitToScreenWhenSmall: "التكيف مع الشاشة حتى وإن كانت صغيرة", + imgWindowDefaultTool: "الأداة المختارة افتراضيًا عند فتح النافذة", + hand: "اليد", + rotate: "تدوير", + zoom: "مكبر", + imgWindowEscKey: "Esc ، للإغلاق", + imgWindowDblClickImgWindow: "النقر المزدوج للإغلاق", + imgWindowClickOutside: "النقر خارج النافذة للإغلاق", + imgWindowClickOutsideTip: "فعالة فقط عند عرض الطبقة الزائدة", + none: "لا شيء", + click: "نقرة", + dblclick: "نقرة مزدوجة", + imgWindowOverlayerShown: "الطبقة الزائدة", + imgWindowOverlayerColor: "اللون والعتامة", + imgWindowShiftRotateStep1: "Shift تدوير للكل عند الضغط على", + imgWindowShiftRotateStep2: "درجة", + imgWindowMouseWheelZoom: "تكبير باستخدام عجلة الفأرة", + imgWindowZoomRange: "نطاق التكبير", + imgWindowZoomRangeTip: "نسبة التكبير (يجب أن تكون موجبة)", + others: "أخرى", + waitImgLoad: "البدء في تنفيذ العمليات مثل التكبير حتى يتم تحميل الصورة", + waitImgLoadTip: "يمكنك مؤقتًا تنفيذ العكس لهذا الإعداد ،Ctrl عند الضغط مع الاستمرار على", + debug: "وضع التصحيح", + customRules: "القواعد المخصصة للصورة الكبيرة", + firstEngine: "محرك البحث المفضل (الأول)", + refreshWhenError: "خطأ في القراءة، انقر لإعادة التحميل", + switchSlide: "تبديل الشريط الجانبي", + viewmore: "عرض المزيد", + countDown: "العد التنازلي", + customLang: "اللغة المخصصة", + defaultLang: "الكشف التلقائي", + hideIcon: "إخفاء الأيقونة", + initShow: "عكس الاختصار لعرض المعاينة افتراضيًا", + stayOut: "دع شريط الأدوات العائم يبقى خارج الصورة", + galleryDownloadGap: "الفاصل الزمني للتنزيل", + formatConversion: "تحويل تنسيق الصورة عند التنزيل. قاعدة واحدة في كل سطر", + galleryDisableArrow: "تعطيل مفتاح السهم", + positionFixed: "موضع ثابت", + switchStoreLoc: "الاحتفاظ بموقع الذاكرة أثناء التبديل" + } + }, + { name: "English", match: ["en"], From ed2800e64a982163f22b47a24de452b52a3b0709 Mon Sep 17 00:00:00 2001 From: Prankster 199 <74471233+vfggf95565@users.noreply.github.com> Date: Wed, 5 Jun 2024 20:22:08 +0300 Subject: [PATCH 0011/1065] Update pagetual.user.js Adding Arabic translation for Arabic users. (There are a lot of users in Arabic) --- Pagetual/pagetual.user.js | 127 +++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index f78846aa3f1..b0ad473005e 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -111,6 +111,131 @@ const noRuleTest = false; const lang = navigator.appName === "Netscape" ? navigator.language : navigator.userLanguage; const langData = [ + { + name: "Arabic", + match: ["ar"], + lang: { + enableDebug: "تمكين تصحيح الأخطاء", + updateNotification: "إشعار بعد تحديث القواعد", + disable: "معطل", + disableSite: "تبديل حالة التعطيل/التفعيل للموقع", + disableSiteTips: "معطل على هذا الموقع", + enableSiteTips: "مفعل على هذا الموقع", + enable: "مفعل", + toTop: "إلى الأعلى", + toBottom: "إلى الأسفل", + current: "الصفحة الحالية", + forceIframe: "إجبار على الانضمام للصفحة التالية", + cancelForceIframe: "إلغاء الانضمام القسري", + configure: "إعداد", + firstUpdate: "انقر هنا لتفعيل القواعد لأول مرة", + update: "تحديث القواعد عبر الإنترنت", + click2update: "انقر لتحديث القواعد من الرابط الآن", + loadNow: "تحميل التالي تلقائيًا", + loadConfirm: "كم عدد الصفحات التي ترغب تحميلها؟ (0 يعني لانهائي)", + noNext: "لم يتم العثور على رابط الصفحة التالية، يرجى إنشاء قاعدة جديدة", + passSec: "تم التحديث منذ #t# ثانية", + passMin: "تم التحديث منذ #t# دقيقة", + passHour: "تم التحديث منذ #t# ساعة", + passDay: "تم التحديث منذ #t# يوم", + cantDel: "لا يمكن حذف القواعد المدمجة", + confirmDel: "هل أنت متأكد من حذف هذه القاعدة؟", + updateSucc: "تم التحديث بنجاح", + beginUpdate: "بدأ التحديث، يرجى الانتظار لحظة", + customUrls: "استيراد رابط قاعدة Pagetual أو AutoPagerize، رابط واحد لكل سطر", + customRules: "إدخال القواعد المخصصة. ✍️ساهم بالقواعد", + save: "حفظ", + /* From the creator hoothin : + "Shojo Now Loading..." is a meme that refers to the game loading text in the Japanese Touhou (東方) game series. */ + loadingText: "جارٍ التحميل...", + opacity: "الشفافية", + opacityPlaceholder: "0: إخفاء الفاصل", + hideBar: "إخفاء الفاصل التصفحي", + hideBarButNoStop: "إخفاء، لكن لا تتوقف", + dbClick2Stop: "انقر مزدوج على المساحة الفارغة للإيقاف", + sortTitle: "يتم تفعيل الفرز بعد التحديث التالي للقواعد", + autoRun: "تمكين تلقائي (وضع القائمة السوداء)", + autoLoadNum: "عدد صفحات التحميل المسبق", + turnRate: "الانتقال للصفحة التالية عندما تكون المسافة أقل من 【X】 مرات ارتفاع الصفحة من التذييل", + inputPageNum: "أدخل رقم الصفحة للانتقال", + enableHistory: "كتابة سجل التصفح بعد تحويل الصفحة", + enableHistoryAfterInsert: "كتابة سجل التصفح فورًا بعد الدمج، أو بعد التصفح", + contentVisibility: "التنقل التلقائي لرؤية المحتوى, لتحسين أداء العرض", + initRun: "الانتقال بين الصفحات فور الفتح", + preload: "تحميل الصفحة التالية مسبقًا لتسريع الأداء", + click2ImportRule: "انقر لاستيراد رابط القواعد الأساسية، ثم انتظر حتى يكتمل التحديث", + forceAllBody: "دمج كامل الصفحة كإطار؟", + openInNewTab: "فتح الروابط الإضافية في علامة تبويب جديدة", + importSucc: "تم الاستيراد بنجاح", + import: "استيراد", + editCurrent: "تحرير القاعدة للحالية", + editBlacklist: "تحرير عناوين القائمة السوداء، سطر بسطر، دعم؟ * للرموز المتحركة", + upBtnImg: "أيقونة العودة إلى الأعلى", + downBtnImg: "أيقونة الانتقال إلى الأسفل", + sideControllerIcon: "أيقونة الشريط الجانبي", + loadingTextTitle: "تحميل النص", + dbClick2StopCtrl: "مفتاح Ctrl", + dbClick2StopAlt: "مفتاح Alt", + dbClick2StopShift: "مفتاح Shift", + dbClick2StopMeta: "مفتاح Meta", + dbClick2StopKey: "مفاتيح الاختصار", + pageElementCss: "نمط مخصص لعناصر الصفحة الرئيسية", + customCss: "مخصص بالكامل CSS نمط", + firstAlert: "لم تستورد القاعدة الأساسية بعد، يرجى اختيار القاعدة المناسبة للاستيراد", + picker: "محدد عناصر الصفحة Pagetual", + closePicker: "إغلاق محدد Pagetual", + pickerPlaceholder: "محدد العناصر، اتركه فارغًا إذا كنت لا تعرف", + pickerCheck: "تحقق من المحدد ونسخ", + switchSelector: "انقر للتبديل بين العناصر", + gotoEdit: "اذهب لتحرير القاعدة بالمحدد الحالي", + manualMode: "تعطيل الدمج/الربط، واستخدام مفتاح الاتجاه الأيمن يدويًا للتمرير، واستخدام مفتاح السهم الأيسر للرجوع", + clickMode: "تعطيل الدمج/الربط، عند التمرير إلى نهاية الصفحة، سيتم النقر تلقائيًا على الصفحة التالية", + pageBarMenu: "انقر على مركز شريط الصفحة لفتح قائمة التحديد", + nextSwitch: "تبديل الرابط التالي", + arrowToScroll: "انقر على مفتاح السهم الأيمن للتمرير التالي ومفتاح السهم الأيسر للتمرير السابق", + sideController: "عرض شريط التحكم في التصفح الترقيم في الشريط الجانبي", + sideControllerScroll: "تبديل التمرير", + sideControllerAlways: "عرض دائمًا", + hideLoadingIcon: "إخفاء رمز التحميل", + hideBarArrow: "إخفاء سهم شريط الصفحة", + duplicate: "تم تثبيت Pagetual مكرر، تحقق من مدير النصوص البرمجية الخاص بك!", + forceStateIframe: "تضمين الصفحة بالكامل كإطار", + forceStateDynamic: "تحميل المحتوى الديناميكي عبر الإطار", + forceStateDisable: "تعطيل تحويل الصفحات على هذا الموقع", + autoScrollRate: "سرعة التمرير (1~1000)", + disableAutoScroll: "إيقاف التمرير التلقائي", + enableAutoScroll: "تمكين التمرير التلقائي", + toggleAutoScroll: "تبديل التمرير التلقائي", + ruleRequest: "طلب قاعدة", + page: "صفحة ", + prevPage: "الصفحة السابقة", + nextPage: "الصفحة التالية", + errorRulesMustBeArray: "يجب أن تكون القواعد مصفوفة!", + errorJson: "خطأ في JSON، تحقق مرة أخرى!", + editSuccess: "تم التحرير بنجاح", + errorWrongUrl: "عنوان URL خاطئ، تحقق مرة أخرى!", + errorAlreadyExists: "موجود بالفعل!", + settingsSaved: "تم حفظ الإعدادات، قم بالتحديث لعرض", + iframe: "إطار", + dynamic: "ديناميكي", + reloadPage: "اكتمل التحرير، إعادة تحميل الصفحة الآن؟", + copied: "تم النسخ", + noValidContent: "لم يتم الكشف عن محتوى صالح، قد يكون الإجراء Captcha مطلوبًا، انقر لعرض", + outOfDate: "النص البرمجي قديم، قم بالتحديث إلى الإصدار الأحدث في الوقت المناسب!", + hideBarTips: "إخفاء شريط التحكم في التصفح الترقيم ، والتبديل لوضع كامل الصفحة", + setConfigPage: "تعيين الصفحة الحالية كصفحة الإعداد الافتراضية", + wedata2github: "تغيير عنوان الويب داتا إلى العنوان البديل المرآة, في مستودع جيت هاب", + addOtherProp: "إضافة خاصية قاعدة", + addNextSelector: "إضافة محتوى المحدد كـ nextLink", + addPageSelector: "إضافة محتوى المحدد كـ pageElement", + propName: "أدخل اسم خاصية القاعدة", + propValue: "أدخل قيمة خاصية القاعدة", + customFirst: "تجاهل ذاكرة التخزين المؤقت للقواعد المخصصة المحلية", + rulesExample: "مثال على القواعد", + lastPage: "تم الوصول إلى الصفحة الأخيرة", + lastPageTips: "عرض تلميحات عند الوصول إلى الصفحة الأخيرة" + } + }, { name: "English", match: ["en"], @@ -8927,4 +9052,4 @@ init(); } }, 300); -})(); \ No newline at end of file +})(); From 826353d7a65fcab79119480334fe8f1051c94705 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 6 Jun 2024 08:24:41 +0800 Subject: [PATCH 0012/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index b0ad473005e..918bed5bb88 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -112,6 +112,7 @@ const lang = navigator.appName === "Netscape" ? navigator.language : navigator.userLanguage; const langData = [ { + //Translated by Prankster 199 (vfggf95565). name: "Arabic", match: ["ar"], lang: { @@ -2511,6 +2512,7 @@ "[class*=pager]>a.next", "[class*=pagination-next]>a", "[class*=pagination-next]>button", + "[class*=page--current]+li>a", "[class*=Pages]>.curr+a" ]; let next = await this.querySelectorList(body, selectorList, doc.defaultView); From ee01bfb4c5c1338657189efcd8800515040f2464 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 6 Jun 2024 08:27:07 +0800 Subject: [PATCH 0013/1065] Update pvcep_lang.js --- Picviewer CE+/pvcep_lang.js | 513 ++++++++++++++++++------------------ 1 file changed, 256 insertions(+), 257 deletions(-) diff --git a/Picviewer CE+/pvcep_lang.js b/Picviewer CE+/pvcep_lang.js index 0cd01118772..5b6b00ac3a2 100644 --- a/Picviewer CE+/pvcep_lang.js +++ b/Picviewer CE+/pvcep_lang.js @@ -1,262 +1,261 @@ const langData = [ { - name: "Arabic", - match: ["ar"], - lang: { - // Translated by Prankster 199 (vfggf95565). - saveBtn: "حفظ", - saveName: "حفظ الاسم", - saveNameTip: "احفظ الصور بالاسم", - default: "افتراضي", - textFirst: "المعلومات أولاً إذا كانت موجودة", - onlyUrl: "فقط مع الرابط", - urlAndText: "الرابط + المعلومات", - download: "تنزيل", - saveBtnTips: "بعض الخيارات تحتاج إلى تحديث الصفحة لتطبيقها", - additionalFeature: "ميزة إضافية، تأخذ تأثير عند الضغط على مفتاح Alt", - invertAdditionalFeature: "عكس مفاتيح الاختصار، استخدم الميزات الإضافية افتراضيًا", - copy: "نسخ الرابط", - copyImg: "نسخ بيانات الصورة", - openInNewTab: "فتح في علامة تبويب جديدة", - closeBtn: "إلغاء", - invertBtn: "عكس", - compareBtn: "مقارنة", - selectAllBtn: "تحديد الكل", - closeBtnTips: "إلغاء هذا الإعداد واستعادة جميع الخيارات", - resetLink: "استعادة الإعدادات الافتراضية", - resetLinkTips: "استعادة جميع الإعدادات إلى القيم الافتراضية", - share: "مشاركة", - suitLongImg: "تناسب الصور الطويلة في نافذة التمرير", - globalkeys: "المفاتيح العامة للمعاينة: ", - globalkeysPress: "اضغط لتبديل المعاينة", - globalkeysHold: "اضغط مع الاستمرار لتمكين المعاينة", - globalkeysType: "طريقة تمكين المعاينة", - closeAfterPreview: "إغلاق نافذة الصورة بعد المعاينة", - previewMaxSize: "الحجم الأقصى لنافذة المعاينة", - previewMaxSizeTip: "عندما تكون نافذة المعاينة أكبر من الحجم المحدد، قم بتقليص نافذة المعاينة. 0 = معطل", - loadAll: "تحميل المزيد من الصفحات", - loadedAll: "تم التحميل", - loading: "جارٍ التحميل ...", - loadAllTip: "تحميل الصورة في الصفحة التالية", - viewmoreEndless: "تحميل المزيد من الصور عند التمرير إلى الأسفل", - fiddle: "تشغيل", - fiddleTip: "ظهور الصور للعمليات المعقدة", - addImageUrls: "إضافة صورة", - addImageUrlsTips: "إضافة المزيد من الصور عبر الرابط", - openImages: "صورة محلية", - openImagesTips: "انقر لاستيراد الصور المحلية", - closeFirst: "أغلق المعرض الحالي أولاً", - collect: "مجموعة", - collected: "تم الجمع", - exitCollection: "الخروج من المجموعة", - exitCollectionTip: "انقر للخروج من وضع المجموعة", - noCollectionYet: "ليس لديك أي صورة في المجموعة", - collectDetail: "وصف", - collectDetailTip: "أضف بعض الأوصاف إلى صورك المفضلة", - playSlide: "تشغيل الشرائح", - slideGap: "الفاصل (ثواني)", - slideGapTip: "الفاصل، وحدة (ثواني)", - slideBack: "رجوع", - slideBackTip: "التشغيل من الخلف إلى الأمام", - slideWait: "انتظر قراءة الصورة", - slideWaitTip: "يبدأ العد التنازلي بعد قراءة كل صورة بالكامل.", - slideSkipError: "تخطي الصور الخاطئة", - slideSkipErrorTip: "تخطي الصور الخاطئة بسرعة", - type: "الفئة", - typeTip: "اختر فئة الصورة", - showWithRules: "إظهار الأيقونة بالقواعد", - showWithRulesTip: "عرض الأيقونة إذا كانت الصورة تتطابق مع القواعد بغض النظر عن حجمها", - advancedRules: "القواعد المتقدمة", - advancedRulesTip: "مطابقة بالقواعد المتقدمة", - tpRules: "قواعد البدل", - tpRulesTip: "مطابقة بقواعد البدل", - scaleRules: "مكبرة", - scaleRulesTip: "الصورة التي تم العثور عليها تلقائيًا ولكن تم تكبيرها", - noScaleRules: "بدون تكبير", - noScaleRulesTip: "الصورة التي تم العثور عليها تلقائيًا ولكن بدون تكبير", - smallRules: "حجم صغير", - smallRulesTip: "بكسل #t# صورة صغيرة الحجم، الحجم الفعلي للارتفاع والعرض أقل من", - lockSizeTip: "قفل الحجم الأقصى", - command: "أمر", - commandTip: "قائمة الأوامر", - onlineEdit: "تحرير عبر الإنترنت", - onlineEditTip: "#t# تحرير هذه الصورة عبر الإنترنت باستخدام", - openInNewWindow: "فتح في نافذة جديدة", - openInNewWindowTip: "فتح الصورة في نافذة جديدة", - findInPage: "بحث في الصفحة", - findInPageTip: "التمرير إلى الصورة الحالية في الصفحة", - viewCollection: "عرض المجموعة", - viewCollectionTip: "عرض جميع الصور المجمعة", - inCollection: "غير قادر على الاستخدام في وضع المجموعة", - cantFind: "الصورة ليست في الوثيقة، أو مخفية ولا يمكن العثور عليها!", - exportImages: "تصدير جميع الصور", - exportImagesTip: "تصدير جميع الصور الكبيرة المعروضة إلى نافذة جديدة", - downloadImage: "تنزيل جميع المعروض", - downloadImageTip: "تنزيل الصور الحالية المعروضة", - copyImagesUrl: "نسخ روابط جميع الصور", - copyImagesUrlTip: "نسخ روابط جميع الصور الكبيرة المعروضة", - copySuccess: "تم نسخ #t# روابط بنجاح", - autoRefresh: "تحميل الصفحة تلقائيًا", - autoRefreshTip: "عند عرض الصور القليلة الأخيرة، قم بالتمرير إلى الأسفل، بحيث تقوم بعض صفحات الويب بتحميل الصور الجديدة", - enterFullsc: "دخول ملء الشاشة", - exitFullsc: "خروج من ملء الشاشة", - config: "الإعدادات", - openConfig: "فتح الإعدادات", - ruleRequest: "طلب القواعد", - closeGallery: "إغلاق المعرض", - returnToGallery: "العودة إلى المعرض", - picInfo: "انقر لتغيير", - picNote: "تعليق الصورة", - urlFilter: "مرشح الرابط", - urlFilterTip: "أدخل كلمات رئيسية أو تعبيرات منتظمة لتصفية الروابط", - resolution: "دقة الصورة", - picNum: "عدد الصور", - picTips: "CTRL عرض الصور باستخدام", - savePageTips: "احفظ هذه الصفحة لتنزيل جميع الصور", - scaleRatio: "نسبة التكبير", - similarImage: "البحث بالصورة", - scale: "تكبير", - horizontalFlip: "انعكاس أفقي", - verticalFlip: "انعكاس عمودي", - actualBtn: "عرض الأصلي (A)", - searchBtn: "البحث عن الصورة الأصلية (S)", - galleryBtn: "عرض المعرض (G)", - currentBtn: "عرض الحالية (C)", - magnifierBtn: "مكبر/تكبير (M)", - picTitle: "عنوان الصورة", - exportImagesUrl: "تصدير روابط الصور", - exportImagesUrlPop: "Ctrl+C لنسخ روابط الصور", - beginSearchImg: "#t# البدء في البحث عن الصورة ...", - findNoPic: "لم يتم العثور على الصورة الأصلية", - findOverBeginLoad: "#t# نهاية الخريطة، العثور على #t# صور متطابقة، بدء تحميل الأولى", - loadNextSimilar: "فشل تحميل الصورة الأصلية، حاول تحميل النتيجة التالية...", - loadError: "فشل التحميل", - openHomePage: "فتح الصفحة الرئيسية", - position: "وضع العرض", - positionTips: "لإخفاء ALT اضغط مع الاستمرار على", - topLeft: "الزاوية العلوية اليسرى من الصورة", - topRight: "الزاوية العلوية اليمنى من الصورة", - bottomRight: "الزاوية السفلية اليمنى من الصورة", - bottomLeft: "الزاوية السفلية اليسرى من الصورة", - topCenter: "بجانب الصورة", - bottomCenter: "أسفل الصورة", - floatBar: "شريط الأدوات", - previewFollowMouse: "عرض المعاينة بجانب الفأرة", - showDelay: "تأخير العرض", - ms: "مللي ثانية", - hide: "إخفاء", - hideDelay: "تأخير الإخفاء", - forceShow: "عرض شريط الأدوات فوق الصورة غير المكبرة التي تتجاوز هذا الحجم،", - forceShowTip: "عرض شريط الأدوات العائم عندما يتجاوز حجم الصورة غير المكبرة الحجم المحدد أدناه", - sizeLimitOr: "فعال بالطول أو العرض فقط", - px: "بكسل", - minSizeLimit: "عرض شريط الأدوات فوق الصورة المكبرة التي تتجاوز هذا الحجم", - minSizeLimitTip: "بعد تكبير الصورة (لا يتطابق الحجم الأصلي للصورة مع الحجم الفعلي)، يتم عرض شريط الأدوات العائم عندما يكون طول الصورة المعروضة أكبر من القيمة المحددة.", - defaultSizeLimit: "حد الحجم الافتراضي للمعرض", - listenBg: "استماع لصورة الخلفية", - backgroundColor: "لون الخلفية", - listenBgTip: "عرض شريط الأدوات على العنصر الذي يحتوي على صورة خلفية", - butonOrder: "ترتيب رموز شريط الأدوات", - keysEnable: "تمكين الاختصارات", - keysActual: "فتح الصورة الكبيرة", - keysActualTip: "اضغط على هذا الزر لفتح صورة كبيرة عندما يظهر شريط الأدوات العائم", - keysSearch: "البحث عن الصورة الأصلية", - keysSearchTip: "اضغط على هذا الزر للبحث عن الصورة الأصلية عندما يظهر شريط الأدوات العائم", - headSearchTip: "البحث بالصورة", - headSearchAll: "البحث في الكل", - keysCurrent: "فتح الصورة الحالية", - keysCurrentTip: "اضغط على هذا الزر لفتح الصورة الحالية عندما يظهر شريط الأدوات العائم", - keysMagnifier: "فتح المكبر للمراقبة", - keysMagnifierTip: "اضغط على هذا الزر لفتح المكبر عندما يظهر شريط الأدوات العائم", - keysGallery: "فتح المعرض (عالمي مع مفاتيح الوظائف)", - keysGalleryTip: "اضغط على هذا الزر لفتح المعرض عندما يظهر شريط الأدوات العائم", - openGallery: "فتح المعرض", - magnifier: "تكبير", - magnifierRadius: "نصف القطر الافتراضي", - magnifierWheelZoomEnabled: "تمكين تكبير العجلة", - magnifierWheelZoomRange: "نسبة التكبير للمكبر", - magnifierScaleImage: "تكبير الصورة بالعجلة", - gallery: "المعرض", - galleryFitToScreen: "تكبير الصورة لتناسب الشاشة", - galleryFitToScreenSmall: "تكبير الصورة الصغيرة أيضًا", - galleryFitToScreenTip: "التكيف ليكون يحتوي، وليس يغطي", - galleryScrollEndToChange: "تبديل الصورة بعد التمرير إلى نهاية الصورة الطويلة", - galleryScrollEndToChangeTip: "فعال بعد إلغاء الخيار السابق", - galleryExportType: "الترتيب الافتراضي عند تصدير الصور", - grid: "ترتيب البلاط", - gridBig: "الترتيب الأصلي", - list: "ترتيب القائمة", - galleryAutoLoad: "تحميل المزيد من الصور تلقائيًا في الصفحة التالية", - galleryLoadAll: "معالجة جميع الصفحات تلقائيًا عند تحميل المزيد من الصور", - galleryLoadAllTip: "قد تؤثر الصفحات الكثيرة على التجربة", - galleryDownloadWithZip: "ضغط إلى ZIP عند تنزيل الكل", - galleryDownloadWithZipAlert: "جارٍ الضغط، يرجى الانتظار قليلاً", - galleryScaleSmallSize1: "الحجم الفعلي أقل من الارتفاع والعرض", - galleryScaleSmallSize2: "البكسلات مصنفة كصور صغيرة الحجم", - galleryShowSmallSize: "عرض الصور الصغيرة افتراضيًا", - galleryTransition: "عرض التأثيرات عند التبديل بين الصور في المعرض", - gallerySidebarPosition: "وضع شريط الصور المصغرة", - bottom: "الأسفل", - right: "اليمين", - left: "اليسار", - top: "الأعلى", - gallerySidebarSize: "الارتفاع", - gallerySidebarSizeTip: "ارتفاع شريط الصور المصغرة (إذا كان أفقيًا) أو العرض (إذا كان رأسيًا)", - galleryMax1: "التحميل المسبق الأقصى", - galleryMax2: "الصور (قبل وبعد)", - galleryAutoZoom: "التكبير يعود إلى 100% (كروم)", - galleryAutoZoomTip: "إذا قمت بالتكبير، قم بتغيير تكبير الصورة وأجزاء شريط الصور المصغرة إلى 100% وزيادة المساحة القابلة للعرض (صالح فقط في كروم)", - galleryDescriptionLength1: "الحد الأقصى للتعليق هو", - galleryDescriptionLength2: "الأحرف", - galleryAutoOpenSites: "عناوين المواقع لفتح المعرض تلقائيًا، واحد في كل سطر، يبدأ بـ @ لعرض المزيد", - autoOpenViewmore: "عرض المزيد تلقائيًا عند فتح المعرض", - gallerySearchData: "قواعد المواقع للبحث، أفرغها لاستعادة", - galleryEditSite: "تحرير الموقع عبر الإنترنت", - imgWindow: "نافذة الصورة", - imgWindowFitToScreen: "التكيف مع الشاشة", - imgWindowFitToScreenTip: "التكيف ليكون يحتوي، وليس يغطي", - imgWindowFitToScreenWhenSmall: "التكيف مع الشاشة حتى وإن كانت صغيرة", - imgWindowDefaultTool: "الأداة المختارة افتراضيًا عند فتح النافذة", - hand: "اليد", - rotate: "تدوير", - zoom: "مكبر", - imgWindowEscKey: "Esc ، للإغلاق", - imgWindowDblClickImgWindow: "النقر المزدوج للإغلاق", - imgWindowClickOutside: "النقر خارج النافذة للإغلاق", - imgWindowClickOutsideTip: "فعالة فقط عند عرض الطبقة الزائدة", - none: "لا شيء", - click: "نقرة", - dblclick: "نقرة مزدوجة", - imgWindowOverlayerShown: "الطبقة الزائدة", - imgWindowOverlayerColor: "اللون والعتامة", - imgWindowShiftRotateStep1: "Shift تدوير للكل عند الضغط على", - imgWindowShiftRotateStep2: "درجة", - imgWindowMouseWheelZoom: "تكبير باستخدام عجلة الفأرة", - imgWindowZoomRange: "نطاق التكبير", - imgWindowZoomRangeTip: "نسبة التكبير (يجب أن تكون موجبة)", - others: "أخرى", - waitImgLoad: "البدء في تنفيذ العمليات مثل التكبير حتى يتم تحميل الصورة", - waitImgLoadTip: "يمكنك مؤقتًا تنفيذ العكس لهذا الإعداد ،Ctrl عند الضغط مع الاستمرار على", - debug: "وضع التصحيح", - customRules: "القواعد المخصصة للصورة الكبيرة", - firstEngine: "محرك البحث المفضل (الأول)", - refreshWhenError: "خطأ في القراءة، انقر لإعادة التحميل", - switchSlide: "تبديل الشريط الجانبي", - viewmore: "عرض المزيد", - countDown: "العد التنازلي", - customLang: "اللغة المخصصة", - defaultLang: "الكشف التلقائي", - hideIcon: "إخفاء الأيقونة", - initShow: "عكس الاختصار لعرض المعاينة افتراضيًا", - stayOut: "دع شريط الأدوات العائم يبقى خارج الصورة", - galleryDownloadGap: "الفاصل الزمني للتنزيل", - formatConversion: "تحويل تنسيق الصورة عند التنزيل. قاعدة واحدة في كل سطر", - galleryDisableArrow: "تعطيل مفتاح السهم", - positionFixed: "موضع ثابت", - switchStoreLoc: "الاحتفاظ بموقع الذاكرة أثناء التبديل" - } - }, - + name: "Arabic", + match: ["ar"], + lang: { + // Translated by Prankster 199 (vfggf95565). + saveBtn: "حفظ", + saveName: "حفظ الاسم", + saveNameTip: "احفظ الصور بالاسم", + default: "افتراضي", + textFirst: "المعلومات أولاً إذا كانت موجودة", + onlyUrl: "فقط مع الرابط", + urlAndText: "الرابط + المعلومات", + download: "تنزيل", + saveBtnTips: "بعض الخيارات تحتاج إلى تحديث الصفحة لتطبيقها", + additionalFeature: "ميزة إضافية، تأخذ تأثير عند الضغط على مفتاح Alt", + invertAdditionalFeature: "عكس مفاتيح الاختصار، استخدم الميزات الإضافية افتراضيًا", + copy: "نسخ الرابط", + copyImg: "نسخ بيانات الصورة", + openInNewTab: "فتح في علامة تبويب جديدة", + closeBtn: "إلغاء", + invertBtn: "عكس", + compareBtn: "مقارنة", + selectAllBtn: "تحديد الكل", + closeBtnTips: "إلغاء هذا الإعداد واستعادة جميع الخيارات", + resetLink: "استعادة الإعدادات الافتراضية", + resetLinkTips: "استعادة جميع الإعدادات إلى القيم الافتراضية", + share: "مشاركة", + suitLongImg: "تناسب الصور الطويلة في نافذة التمرير", + globalkeys: "المفاتيح العامة للمعاينة: ", + globalkeysPress: "اضغط لتبديل المعاينة", + globalkeysHold: "اضغط مع الاستمرار لتمكين المعاينة", + globalkeysType: "طريقة تمكين المعاينة", + closeAfterPreview: "إغلاق نافذة الصورة بعد المعاينة", + previewMaxSize: "الحجم الأقصى لنافذة المعاينة", + previewMaxSizeTip: "عندما تكون نافذة المعاينة أكبر من الحجم المحدد، قم بتقليص نافذة المعاينة. 0 = معطل", + loadAll: "تحميل المزيد من الصفحات", + loadedAll: "تم التحميل", + loading: "جارٍ التحميل ...", + loadAllTip: "تحميل الصورة في الصفحة التالية", + viewmoreEndless: "تحميل المزيد من الصور عند التمرير إلى الأسفل", + fiddle: "تشغيل", + fiddleTip: "ظهور الصور للعمليات المعقدة", + addImageUrls: "إضافة صورة", + addImageUrlsTips: "إضافة المزيد من الصور عبر الرابط", + openImages: "صورة محلية", + openImagesTips: "انقر لاستيراد الصور المحلية", + closeFirst: "أغلق المعرض الحالي أولاً", + collect: "مجموعة", + collected: "تم الجمع", + exitCollection: "الخروج من المجموعة", + exitCollectionTip: "انقر للخروج من وضع المجموعة", + noCollectionYet: "ليس لديك أي صورة في المجموعة", + collectDetail: "وصف", + collectDetailTip: "أضف بعض الأوصاف إلى صورك المفضلة", + playSlide: "تشغيل الشرائح", + slideGap: "الفاصل (ثواني)", + slideGapTip: "الفاصل، وحدة (ثواني)", + slideBack: "رجوع", + slideBackTip: "التشغيل من الخلف إلى الأمام", + slideWait: "انتظر قراءة الصورة", + slideWaitTip: "يبدأ العد التنازلي بعد قراءة كل صورة بالكامل.", + slideSkipError: "تخطي الصور الخاطئة", + slideSkipErrorTip: "تخطي الصور الخاطئة بسرعة", + type: "الفئة", + typeTip: "اختر فئة الصورة", + showWithRules: "إظهار الأيقونة بالقواعد", + showWithRulesTip: "عرض الأيقونة إذا كانت الصورة تتطابق مع القواعد بغض النظر عن حجمها", + advancedRules: "القواعد المتقدمة", + advancedRulesTip: "مطابقة بالقواعد المتقدمة", + tpRules: "قواعد البدل", + tpRulesTip: "مطابقة بقواعد البدل", + scaleRules: "مكبرة", + scaleRulesTip: "الصورة التي تم العثور عليها تلقائيًا ولكن تم تكبيرها", + noScaleRules: "بدون تكبير", + noScaleRulesTip: "الصورة التي تم العثور عليها تلقائيًا ولكن بدون تكبير", + smallRules: "حجم صغير", + smallRulesTip: "بكسل #t# صورة صغيرة الحجم، الحجم الفعلي للارتفاع والعرض أقل من", + lockSizeTip: "قفل الحجم الأقصى", + command: "أمر", + commandTip: "قائمة الأوامر", + onlineEdit: "تحرير عبر الإنترنت", + onlineEditTip: "#t# تحرير هذه الصورة عبر الإنترنت باستخدام", + openInNewWindow: "فتح في نافذة جديدة", + openInNewWindowTip: "فتح الصورة في نافذة جديدة", + findInPage: "بحث في الصفحة", + findInPageTip: "التمرير إلى الصورة الحالية في الصفحة", + viewCollection: "عرض المجموعة", + viewCollectionTip: "عرض جميع الصور المجمعة", + inCollection: "غير قادر على الاستخدام في وضع المجموعة", + cantFind: "الصورة ليست في الوثيقة، أو مخفية ولا يمكن العثور عليها!", + exportImages: "تصدير جميع الصور", + exportImagesTip: "تصدير جميع الصور الكبيرة المعروضة إلى نافذة جديدة", + downloadImage: "تنزيل جميع المعروض", + downloadImageTip: "تنزيل الصور الحالية المعروضة", + copyImagesUrl: "نسخ روابط جميع الصور", + copyImagesUrlTip: "نسخ روابط جميع الصور الكبيرة المعروضة", + copySuccess: "تم نسخ #t# روابط بنجاح", + autoRefresh: "تحميل الصفحة تلقائيًا", + autoRefreshTip: "عند عرض الصور القليلة الأخيرة، قم بالتمرير إلى الأسفل، بحيث تقوم بعض صفحات الويب بتحميل الصور الجديدة", + enterFullsc: "دخول ملء الشاشة", + exitFullsc: "خروج من ملء الشاشة", + config: "الإعدادات", + openConfig: "فتح الإعدادات", + ruleRequest: "طلب القواعد", + closeGallery: "إغلاق المعرض", + returnToGallery: "العودة إلى المعرض", + picInfo: "انقر لتغيير", + picNote: "تعليق الصورة", + urlFilter: "مرشح الرابط", + urlFilterTip: "أدخل كلمات رئيسية أو تعبيرات منتظمة لتصفية الروابط", + resolution: "دقة الصورة", + picNum: "عدد الصور", + picTips: "CTRL عرض الصور باستخدام", + savePageTips: "احفظ هذه الصفحة لتنزيل جميع الصور", + scaleRatio: "نسبة التكبير", + similarImage: "البحث بالصورة", + scale: "تكبير", + horizontalFlip: "انعكاس أفقي", + verticalFlip: "انعكاس عمودي", + actualBtn: "عرض الأصلي (A)", + searchBtn: "البحث عن الصورة الأصلية (S)", + galleryBtn: "عرض المعرض (G)", + currentBtn: "عرض الحالية (C)", + magnifierBtn: "مكبر/تكبير (M)", + picTitle: "عنوان الصورة", + exportImagesUrl: "تصدير روابط الصور", + exportImagesUrlPop: "Ctrl+C لنسخ روابط الصور", + beginSearchImg: "#t# البدء في البحث عن الصورة ...", + findNoPic: "لم يتم العثور على الصورة الأصلية", + findOverBeginLoad: "#t# نهاية الخريطة، العثور على #t# صور متطابقة، بدء تحميل الأولى", + loadNextSimilar: "فشل تحميل الصورة الأصلية، حاول تحميل النتيجة التالية...", + loadError: "فشل التحميل", + openHomePage: "فتح الصفحة الرئيسية", + position: "وضع العرض", + positionTips: "لإخفاء ALT اضغط مع الاستمرار على", + topLeft: "الزاوية العلوية اليسرى من الصورة", + topRight: "الزاوية العلوية اليمنى من الصورة", + bottomRight: "الزاوية السفلية اليمنى من الصورة", + bottomLeft: "الزاوية السفلية اليسرى من الصورة", + topCenter: "بجانب الصورة", + bottomCenter: "أسفل الصورة", + floatBar: "شريط الأدوات", + previewFollowMouse: "عرض المعاينة بجانب الفأرة", + showDelay: "تأخير العرض", + ms: "مللي ثانية", + hide: "إخفاء", + hideDelay: "تأخير الإخفاء", + forceShow: "عرض شريط الأدوات فوق الصورة غير المكبرة التي تتجاوز هذا الحجم،", + forceShowTip: "عرض شريط الأدوات العائم عندما يتجاوز حجم الصورة غير المكبرة الحجم المحدد أدناه", + sizeLimitOr: "فعال بالطول أو العرض فقط", + px: "بكسل", + minSizeLimit: "عرض شريط الأدوات فوق الصورة المكبرة التي تتجاوز هذا الحجم", + minSizeLimitTip: "بعد تكبير الصورة (لا يتطابق الحجم الأصلي للصورة مع الحجم الفعلي)، يتم عرض شريط الأدوات العائم عندما يكون طول الصورة المعروضة أكبر من القيمة المحددة.", + defaultSizeLimit: "حد الحجم الافتراضي للمعرض", + listenBg: "استماع لصورة الخلفية", + backgroundColor: "لون الخلفية", + listenBgTip: "عرض شريط الأدوات على العنصر الذي يحتوي على صورة خلفية", + butonOrder: "ترتيب رموز شريط الأدوات", + keysEnable: "تمكين الاختصارات", + keysActual: "فتح الصورة الكبيرة", + keysActualTip: "اضغط على هذا الزر لفتح صورة كبيرة عندما يظهر شريط الأدوات العائم", + keysSearch: "البحث عن الصورة الأصلية", + keysSearchTip: "اضغط على هذا الزر للبحث عن الصورة الأصلية عندما يظهر شريط الأدوات العائم", + headSearchTip: "البحث بالصورة", + headSearchAll: "البحث في الكل", + keysCurrent: "فتح الصورة الحالية", + keysCurrentTip: "اضغط على هذا الزر لفتح الصورة الحالية عندما يظهر شريط الأدوات العائم", + keysMagnifier: "فتح المكبر للمراقبة", + keysMagnifierTip: "اضغط على هذا الزر لفتح المكبر عندما يظهر شريط الأدوات العائم", + keysGallery: "فتح المعرض (عالمي مع مفاتيح الوظائف)", + keysGalleryTip: "اضغط على هذا الزر لفتح المعرض عندما يظهر شريط الأدوات العائم", + openGallery: "فتح المعرض", + magnifier: "تكبير", + magnifierRadius: "نصف القطر الافتراضي", + magnifierWheelZoomEnabled: "تمكين تكبير العجلة", + magnifierWheelZoomRange: "نسبة التكبير للمكبر", + magnifierScaleImage: "تكبير الصورة بالعجلة", + gallery: "المعرض", + galleryFitToScreen: "تكبير الصورة لتناسب الشاشة", + galleryFitToScreenSmall: "تكبير الصورة الصغيرة أيضًا", + galleryFitToScreenTip: "التكيف ليكون يحتوي، وليس يغطي", + galleryScrollEndToChange: "تبديل الصورة بعد التمرير إلى نهاية الصورة الطويلة", + galleryScrollEndToChangeTip: "فعال بعد إلغاء الخيار السابق", + galleryExportType: "الترتيب الافتراضي عند تصدير الصور", + grid: "ترتيب البلاط", + gridBig: "الترتيب الأصلي", + list: "ترتيب القائمة", + galleryAutoLoad: "تحميل المزيد من الصور تلقائيًا في الصفحة التالية", + galleryLoadAll: "معالجة جميع الصفحات تلقائيًا عند تحميل المزيد من الصور", + galleryLoadAllTip: "قد تؤثر الصفحات الكثيرة على التجربة", + galleryDownloadWithZip: "ضغط إلى ZIP عند تنزيل الكل", + galleryDownloadWithZipAlert: "جارٍ الضغط، يرجى الانتظار قليلاً", + galleryScaleSmallSize1: "الحجم الفعلي أقل من الارتفاع والعرض", + galleryScaleSmallSize2: "البكسلات مصنفة كصور صغيرة الحجم", + galleryShowSmallSize: "عرض الصور الصغيرة افتراضيًا", + galleryTransition: "عرض التأثيرات عند التبديل بين الصور في المعرض", + gallerySidebarPosition: "وضع شريط الصور المصغرة", + bottom: "الأسفل", + right: "اليمين", + left: "اليسار", + top: "الأعلى", + gallerySidebarSize: "الارتفاع", + gallerySidebarSizeTip: "ارتفاع شريط الصور المصغرة (إذا كان أفقيًا) أو العرض (إذا كان رأسيًا)", + galleryMax1: "التحميل المسبق الأقصى", + galleryMax2: "الصور (قبل وبعد)", + galleryAutoZoom: "التكبير يعود إلى 100% (كروم)", + galleryAutoZoomTip: "إذا قمت بالتكبير، قم بتغيير تكبير الصورة وأجزاء شريط الصور المصغرة إلى 100% وزيادة المساحة القابلة للعرض (صالح فقط في كروم)", + galleryDescriptionLength1: "الحد الأقصى للتعليق هو", + galleryDescriptionLength2: "الأحرف", + galleryAutoOpenSites: "عناوين المواقع لفتح المعرض تلقائيًا، واحد في كل سطر، يبدأ بـ @ لعرض المزيد", + autoOpenViewmore: "عرض المزيد تلقائيًا عند فتح المعرض", + gallerySearchData: "قواعد المواقع للبحث، أفرغها لاستعادة", + galleryEditSite: "تحرير الموقع عبر الإنترنت", + imgWindow: "نافذة الصورة", + imgWindowFitToScreen: "التكيف مع الشاشة", + imgWindowFitToScreenTip: "التكيف ليكون يحتوي، وليس يغطي", + imgWindowFitToScreenWhenSmall: "التكيف مع الشاشة حتى وإن كانت صغيرة", + imgWindowDefaultTool: "الأداة المختارة افتراضيًا عند فتح النافذة", + hand: "اليد", + rotate: "تدوير", + zoom: "مكبر", + imgWindowEscKey: "Esc ، للإغلاق", + imgWindowDblClickImgWindow: "النقر المزدوج للإغلاق", + imgWindowClickOutside: "النقر خارج النافذة للإغلاق", + imgWindowClickOutsideTip: "فعالة فقط عند عرض الطبقة الزائدة", + none: "لا شيء", + click: "نقرة", + dblclick: "نقرة مزدوجة", + imgWindowOverlayerShown: "الطبقة الزائدة", + imgWindowOverlayerColor: "اللون والعتامة", + imgWindowShiftRotateStep1: "Shift تدوير للكل عند الضغط على", + imgWindowShiftRotateStep2: "درجة", + imgWindowMouseWheelZoom: "تكبير باستخدام عجلة الفأرة", + imgWindowZoomRange: "نطاق التكبير", + imgWindowZoomRangeTip: "نسبة التكبير (يجب أن تكون موجبة)", + others: "أخرى", + waitImgLoad: "البدء في تنفيذ العمليات مثل التكبير حتى يتم تحميل الصورة", + waitImgLoadTip: "يمكنك مؤقتًا تنفيذ العكس لهذا الإعداد ،Ctrl عند الضغط مع الاستمرار على", + debug: "وضع التصحيح", + customRules: "القواعد المخصصة للصورة الكبيرة", + firstEngine: "محرك البحث المفضل (الأول)", + refreshWhenError: "خطأ في القراءة، انقر لإعادة التحميل", + switchSlide: "تبديل الشريط الجانبي", + viewmore: "عرض المزيد", + countDown: "العد التنازلي", + customLang: "اللغة المخصصة", + defaultLang: "الكشف التلقائي", + hideIcon: "إخفاء الأيقونة", + initShow: "عكس الاختصار لعرض المعاينة افتراضيًا", + stayOut: "دع شريط الأدوات العائم يبقى خارج الصورة", + galleryDownloadGap: "الفاصل الزمني للتنزيل", + formatConversion: "تحويل تنسيق الصورة عند التنزيل. قاعدة واحدة في كل سطر", + galleryDisableArrow: "تعطيل مفتاح السهم", + positionFixed: "موضع ثابت", + switchStoreLoc: "الاحتفاظ بموقع الذاكرة أثناء التبديل" + } +}, { name: "English", match: ["en"], From 5c276417de2fad9842b05220f39c9ffd3fe4145d Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 6 Jun 2024 08:33:04 +0800 Subject: [PATCH 0014/1065] Update pvcep_lang.js --- Picviewer CE+/pvcep_lang.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_lang.js b/Picviewer CE+/pvcep_lang.js index 5b6b00ac3a2..59129163340 100644 --- a/Picviewer CE+/pvcep_lang.js +++ b/Picviewer CE+/pvcep_lang.js @@ -1,7 +1,7 @@ const langData = [ { name: "Arabic", - match: ["ar"], + match: ["ar", "ar-AE", "ar-BH", "ar-DZ", "ar-EG", "ar-IQ", "ar-JO", "ar-KW", "ar-LB", "ar-LY", "ar-MA", "ar-OM", "ar-QA", "ar-SA", "ar-SY", "ar-TN", "ar-YE"], lang: { // Translated by Prankster 199 (vfggf95565). saveBtn: "حفظ", From 3b59499aab8092a8f41254879074689258b05443 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 6 Jun 2024 08:42:55 +0800 Subject: [PATCH 0015/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 0705a17e094..a2ed9081d3b 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.1.2 +// @version 2024.6.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 @@ -47,7 +47,7 @@ // @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 +// @require https://update.greasyfork.org/scripts/440698/1389633/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 // @match *://*/* From dd550d658f4f418f40b349a8868d88658994f8e6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 6 Jun 2024 08:46:26 +0800 Subject: [PATCH 0016/1065] 1.9.37.50 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index e5aa2422529..25c6fcee22c 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.49](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.50](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 918bed5bb88..a986643bdee 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.49 +// @version 1.9.37.50 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -114,7 +114,7 @@ { //Translated by Prankster 199 (vfggf95565). name: "Arabic", - match: ["ar"], + match: ["ar", "ar-AE", "ar-BH", "ar-DZ", "ar-EG", "ar-IQ", "ar-JO", "ar-KW", "ar-LB", "ar-LY", "ar-MA", "ar-OM", "ar-QA", "ar-SA", "ar-SY", "ar-TN", "ar-YE"], lang: { enableDebug: "تمكين تصحيح الأخطاء", updateNotification: "إشعار بعد تحديث القواعد", From ae5258654f8baf6efa5fd99bd5d67918b609ced3 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 6 Jun 2024 09:10:35 +0800 Subject: [PATCH 0017/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index a986643bdee..9702d168750 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2513,7 +2513,8 @@ "[class*=pagination-next]>a", "[class*=pagination-next]>button", "[class*=page--current]+li>a", - "[class*=Pages]>.curr+a" + "[class*=Pages]>.curr+a", + ".page>em+a" ]; let next = await this.querySelectorList(body, selectorList, doc.defaultView); if (!next) { From e5da024f6a63a1b00662cde0737676fa23c887b5 Mon Sep 17 00:00:00 2001 From: Lemonade <61580921+lemonadeforlife@users.noreply.github.com> Date: Thu, 6 Jun 2024 04:38:28 +0000 Subject: [PATCH 0018/1065] Fixed MAL Top pages content load issue --- Pagetual/pagetualRules.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 27323cf9aad..5689d9e798f 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -7388,7 +7388,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": 1 }, { "name": "MAL - recommendations", From 576e1339dde06c8d638122e0c786a5aad9ab143c Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 6 Jun 2024 14:10:37 +0800 Subject: [PATCH 0019/1065] English default --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 248 +++++++++++++++++++------------------- 2 files changed, 125 insertions(+), 125 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 25c6fcee22c..229d8d56fd0 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.50](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.51](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 9702d168750..e812e0d1afb 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.50 +// @version 1.9.37.51 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -111,6 +111,129 @@ const noRuleTest = false; const lang = navigator.appName === "Netscape" ? navigator.language : navigator.userLanguage; const langData = [ + { + name: "English", + match: ["en"], + lang: { + enableDebug: "Enable debug output", + updateNotification: "Notification after rules updated", + disable: "Disable", + disableSite: "Toggle disabled state", + disableSiteTips: "Disabled on this site", + enableSiteTips: "Enabled on this site", + enable: "Enable", + toTop: "To Top", + toBottom: "To Bottom", + current: "Current Page", + forceIframe: "Force to join next page", + cancelForceIframe: "Cancel Force join", + configure: "Configure", + firstUpdate: "Click here to initialize the rules", + update: "Update online rules", + click2update: "Click to update rules from url now", + loadNow: "Load next automatically", + loadConfirm: "How much pages do you want to load? (0 means infinite)", + noNext: "No next link found, please create a new rule", + passSec: "Updated #t# seconds ago", + passMin: "Updated #t# minutes ago", + passHour: "Updated #t# hours ago", + passDay: "Updated #t# days ago", + cantDel: "Can't delete buildin rules", + confirmDel: "Are you sure you want to delete this rule?", + updateSucc: "Update succeeded", + beginUpdate: "Begin update, wait a minute please", + customUrls: "Import Pagetual or AutoPagerize rule url, One url per line", + customRules: "Input custom rules. ✍️Contribute rules", + save: "Save", + loadingText: "Shojo Now Loading...", + opacity: "Opacity", + opacityPlaceholder: "0: hide spacer", + hideBar: "Hide the paging spacer", + hideBarButNoStop: "Hide but not stop", + dbClick2Stop: "Double-click on the blank space to pause", + sortTitle: "Sorting takes effect after the next rule update", + autoRun: "Auto enable (blacklist mode)", + autoLoadNum: "Amount for preload pages", + turnRate: "Turn the next page when it's less than 【X】 times page height from the footer", + inputPageNum: "Enter page number to jump", + enableHistory: "Write browsing history after page turning", + enableHistoryAfterInsert: "Write browsing history immediately after splicing, otherwise write after browsing", + contentVisibility: "Automatically switch contentVisibility to improve rendering performance", + initRun: "Turn pages immediately after opening", + preload: "Preload next page for speeding up", + click2ImportRule: "Click to import base rules link, then wait until the update is complete: ", + forceAllBody: "Join full body of page?", + openInNewTab: "Open urls of additions in new tab", + importSucc: "Import completed", + import: "Import", + editCurrent: "Edit rule for current", + editBlacklist: "Edit the blacklist urls, line by line, Support ? * for wildcard", + upBtnImg: "Icon of back to top", + downBtnImg: "Icon of go to footer", + sideControllerIcon: "Icon of sidebar", + loadingTextTitle: "Loading text", + dbClick2StopCtrl: "Ctrl key", + dbClick2StopAlt: "Alt key", + dbClick2StopShift: "Shift key", + dbClick2StopMeta: "Meta key", + dbClick2StopKey: "Shortcut key", + pageElementCss: "Custom style for main page elements", + customCss: "Custom complete css", + firstAlert: "You have not imported the base rule, please select the appropriate rule to import", + picker: "Pagetual page element picker", + closePicker: "Close Pagetual picker", + pickerPlaceholder: "Element selector, Leave empty if you have no idea", + pickerCheck: "Check selector and copy", + switchSelector: "Click to switch element", + gotoEdit: "Go to edit rule with current selector", + manualMode: "Disable splicing, manually turn pages with the right arrow keys (or dispatch event 'pagetual.next')", + clickMode: "Disable splicing, automatically click the next page when scrolling to the end of the page", + pageBarMenu: "Click the center of the page bar to open the picker menu", + nextSwitch: "Switch next link", + arrowToScroll: "Press left arrow key to scroll prev and right arrow key to scroll next", + sideController: "Display the paging control bar in the sidebar", + sideControllerScroll: "Scroll toggle", + sideControllerAlways: "Always show", + hideLoadingIcon: "Hide loading animation", + hideBarArrow: "Hide arrow for page bar", + duplicate: "Duplicate Pagetual have been installed, check your script manager!", + forceStateIframe: "Embed full page as iframe", + forceStateDynamic: "Load dynamic content via iframe", + forceStateDisable: "Disable page turning on this site", + autoScrollRate: "Scroll speed (1~1000)", + disableAutoScroll: "Stop Auto Scroll", + enableAutoScroll: "Enable Auto Scroll", + toggleAutoScroll: "Toggle Auto Scroll", + ruleRequest: "Rule Request", + page: "Page ", + prevPage: "Prev page", + nextPage: "Next page", + errorRulesMustBeArray: "Rules must be a Array!", + errorJson: "JSON error, check again!", + editSuccess: "Edit successfully", + errorWrongUrl: "Wrong url, check again!", + errorAlreadyExists: "Already exists!", + settingsSaved: "The settings are saved, refresh to view", + iframe: "Iframe", + dynamic: "Dynamic", + reloadPage: "Edit completed, reload page now?", + copied: "Copied", + noValidContent: "No valid content detected, Captcha action may be required, click to view", + outOfDate: "The script is outdated, update to the latest version in time!", + hideBarTips: "Hide the pagination bar, toggle immersive experience", + setConfigPage: "Set current page as the default configuration page", + wedata2github: "Change the wedata address to the mirror address in the github repository", + addOtherProp: "Add rule property", + addNextSelector: "Add selector content as nextLink", + addPageSelector: "Add selector content as pageElement", + propName: "Enter rule property name", + propValue: "Enter rule property value", + customFirst: "Ignore cache for local custom rules", + rulesExample: "Rules Example", + lastPage: "Reached the last page", + lastPageTips: "Show tips when reaching the last page" + } + }, { //Translated by Prankster 199 (vfggf95565). name: "Arabic", @@ -237,129 +360,6 @@ lastPageTips: "عرض تلميحات عند الوصول إلى الصفحة الأخيرة" } }, - { - name: "English", - match: ["en"], - lang: { - enableDebug: "Enable debug output", - updateNotification: "Notification after rules updated", - disable: "Disable", - disableSite: "Toggle disabled state", - disableSiteTips: "Disabled on this site", - enableSiteTips: "Enabled on this site", - enable: "Enable", - toTop: "To Top", - toBottom: "To Bottom", - current: "Current Page", - forceIframe: "Force to join next page", - cancelForceIframe: "Cancel Force join", - configure: "Configure", - firstUpdate: "Click here to initialize the rules", - update: "Update online rules", - click2update: "Click to update rules from url now", - loadNow: "Load next automatically", - loadConfirm: "How much pages do you want to load? (0 means infinite)", - noNext: "No next link found, please create a new rule", - passSec: "Updated #t# seconds ago", - passMin: "Updated #t# minutes ago", - passHour: "Updated #t# hours ago", - passDay: "Updated #t# days ago", - cantDel: "Can't delete buildin rules", - confirmDel: "Are you sure you want to delete this rule?", - updateSucc: "Update succeeded", - beginUpdate: "Begin update, wait a minute please", - customUrls: "Import Pagetual or AutoPagerize rule url, One url per line", - customRules: "Input custom rules. ✍️Contribute rules", - save: "Save", - loadingText: "Shojo Now Loading...", - opacity: "Opacity", - opacityPlaceholder: "0: hide spacer", - hideBar: "Hide the paging spacer", - hideBarButNoStop: "Hide but not stop", - dbClick2Stop: "Double-click on the blank space to pause", - sortTitle: "Sorting takes effect after the next rule update", - autoRun: "Auto enable (blacklist mode)", - autoLoadNum: "Amount for preload pages", - turnRate: "Turn the next page when it's less than 【X】 times page height from the footer", - inputPageNum: "Enter page number to jump", - enableHistory: "Write browsing history after page turning", - enableHistoryAfterInsert: "Write browsing history immediately after splicing, otherwise write after browsing", - contentVisibility: "Automatically switch contentVisibility to improve rendering performance", - initRun: "Turn pages immediately after opening", - preload: "Preload next page for speeding up", - click2ImportRule: "Click to import base rules link, then wait until the update is complete: ", - forceAllBody: "Join full body of page?", - openInNewTab: "Open urls of additions in new tab", - importSucc: "Import completed", - import: "Import", - editCurrent: "Edit rule for current", - editBlacklist: "Edit the blacklist urls, line by line, Support ? * for wildcard", - upBtnImg: "Icon of back to top", - downBtnImg: "Icon of go to footer", - sideControllerIcon: "Icon of sidebar", - loadingTextTitle: "Loading text", - dbClick2StopCtrl: "Ctrl key", - dbClick2StopAlt: "Alt key", - dbClick2StopShift: "Shift key", - dbClick2StopMeta: "Meta key", - dbClick2StopKey: "Shortcut key", - pageElementCss: "Custom style for main page elements", - customCss: "Custom complete css", - firstAlert: "You have not imported the base rule, please select the appropriate rule to import", - picker: "Pagetual page element picker", - closePicker: "Close Pagetual picker", - pickerPlaceholder: "Element selector, Leave empty if you have no idea", - pickerCheck: "Check selector and copy", - switchSelector: "Click to switch element", - gotoEdit: "Go to edit rule with current selector", - manualMode: "Disable splicing, manually turn pages with the right arrow keys (or dispatch event 'pagetual.next')", - clickMode: "Disable splicing, automatically click the next page when scrolling to the end of the page", - pageBarMenu: "Click the center of the page bar to open the picker menu", - nextSwitch: "Switch next link", - arrowToScroll: "Press left arrow key to scroll prev and right arrow key to scroll next", - sideController: "Display the paging control bar in the sidebar", - sideControllerScroll: "Scroll toggle", - sideControllerAlways: "Always show", - hideLoadingIcon: "Hide loading animation", - hideBarArrow: "Hide arrow for page bar", - duplicate: "Duplicate Pagetual have been installed, check your script manager!", - forceStateIframe: "Embed full page as iframe", - forceStateDynamic: "Load dynamic content via iframe", - forceStateDisable: "Disable page turning on this site", - autoScrollRate: "Scroll speed (1~1000)", - disableAutoScroll: "Stop Auto Scroll", - enableAutoScroll: "Enable Auto Scroll", - toggleAutoScroll: "Toggle Auto Scroll", - ruleRequest: "Rule Request", - page: "Page ", - prevPage: "Prev page", - nextPage: "Next page", - errorRulesMustBeArray: "Rules must be a Array!", - errorJson: "JSON error, check again!", - editSuccess: "Edit successfully", - errorWrongUrl: "Wrong url, check again!", - errorAlreadyExists: "Already exists!", - settingsSaved: "The settings are saved, refresh to view", - iframe: "Iframe", - dynamic: "Dynamic", - reloadPage: "Edit completed, reload page now?", - copied: "Copied", - noValidContent: "No valid content detected, Captcha action may be required, click to view", - outOfDate: "The script is outdated, update to the latest version in time!", - hideBarTips: "Hide the pagination bar, toggle immersive experience", - setConfigPage: "Set current page as the default configuration page", - wedata2github: "Change the wedata address to the mirror address in the github repository", - addOtherProp: "Add rule property", - addNextSelector: "Add selector content as nextLink", - addPageSelector: "Add selector content as pageElement", - propName: "Enter rule property name", - propValue: "Enter rule property value", - customFirst: "Ignore cache for local custom rules", - rulesExample: "Rules Example", - lastPage: "Reached the last page", - lastPageTips: "Show tips when reaching the last page" - } - }, { name: "简体中文", match: ["zh-CN", "zh-SG"], From 1b344df48a22dc209b1acfff56793db9db7d3bfb Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 6 Jun 2024 14:12:31 +0800 Subject: [PATCH 0020/1065] Update pvcep_lang.js --- Picviewer CE+/pvcep_lang.js | 516 ++++++++++++++++++------------------ 1 file changed, 258 insertions(+), 258 deletions(-) diff --git a/Picviewer CE+/pvcep_lang.js b/Picviewer CE+/pvcep_lang.js index 59129163340..507f760decf 100644 --- a/Picviewer CE+/pvcep_lang.js +++ b/Picviewer CE+/pvcep_lang.js @@ -1,261 +1,4 @@ const langData = [ -{ - name: "Arabic", - match: ["ar", "ar-AE", "ar-BH", "ar-DZ", "ar-EG", "ar-IQ", "ar-JO", "ar-KW", "ar-LB", "ar-LY", "ar-MA", "ar-OM", "ar-QA", "ar-SA", "ar-SY", "ar-TN", "ar-YE"], - lang: { - // Translated by Prankster 199 (vfggf95565). - saveBtn: "حفظ", - saveName: "حفظ الاسم", - saveNameTip: "احفظ الصور بالاسم", - default: "افتراضي", - textFirst: "المعلومات أولاً إذا كانت موجودة", - onlyUrl: "فقط مع الرابط", - urlAndText: "الرابط + المعلومات", - download: "تنزيل", - saveBtnTips: "بعض الخيارات تحتاج إلى تحديث الصفحة لتطبيقها", - additionalFeature: "ميزة إضافية، تأخذ تأثير عند الضغط على مفتاح Alt", - invertAdditionalFeature: "عكس مفاتيح الاختصار، استخدم الميزات الإضافية افتراضيًا", - copy: "نسخ الرابط", - copyImg: "نسخ بيانات الصورة", - openInNewTab: "فتح في علامة تبويب جديدة", - closeBtn: "إلغاء", - invertBtn: "عكس", - compareBtn: "مقارنة", - selectAllBtn: "تحديد الكل", - closeBtnTips: "إلغاء هذا الإعداد واستعادة جميع الخيارات", - resetLink: "استعادة الإعدادات الافتراضية", - resetLinkTips: "استعادة جميع الإعدادات إلى القيم الافتراضية", - share: "مشاركة", - suitLongImg: "تناسب الصور الطويلة في نافذة التمرير", - globalkeys: "المفاتيح العامة للمعاينة: ", - globalkeysPress: "اضغط لتبديل المعاينة", - globalkeysHold: "اضغط مع الاستمرار لتمكين المعاينة", - globalkeysType: "طريقة تمكين المعاينة", - closeAfterPreview: "إغلاق نافذة الصورة بعد المعاينة", - previewMaxSize: "الحجم الأقصى لنافذة المعاينة", - previewMaxSizeTip: "عندما تكون نافذة المعاينة أكبر من الحجم المحدد، قم بتقليص نافذة المعاينة. 0 = معطل", - loadAll: "تحميل المزيد من الصفحات", - loadedAll: "تم التحميل", - loading: "جارٍ التحميل ...", - loadAllTip: "تحميل الصورة في الصفحة التالية", - viewmoreEndless: "تحميل المزيد من الصور عند التمرير إلى الأسفل", - fiddle: "تشغيل", - fiddleTip: "ظهور الصور للعمليات المعقدة", - addImageUrls: "إضافة صورة", - addImageUrlsTips: "إضافة المزيد من الصور عبر الرابط", - openImages: "صورة محلية", - openImagesTips: "انقر لاستيراد الصور المحلية", - closeFirst: "أغلق المعرض الحالي أولاً", - collect: "مجموعة", - collected: "تم الجمع", - exitCollection: "الخروج من المجموعة", - exitCollectionTip: "انقر للخروج من وضع المجموعة", - noCollectionYet: "ليس لديك أي صورة في المجموعة", - collectDetail: "وصف", - collectDetailTip: "أضف بعض الأوصاف إلى صورك المفضلة", - playSlide: "تشغيل الشرائح", - slideGap: "الفاصل (ثواني)", - slideGapTip: "الفاصل، وحدة (ثواني)", - slideBack: "رجوع", - slideBackTip: "التشغيل من الخلف إلى الأمام", - slideWait: "انتظر قراءة الصورة", - slideWaitTip: "يبدأ العد التنازلي بعد قراءة كل صورة بالكامل.", - slideSkipError: "تخطي الصور الخاطئة", - slideSkipErrorTip: "تخطي الصور الخاطئة بسرعة", - type: "الفئة", - typeTip: "اختر فئة الصورة", - showWithRules: "إظهار الأيقونة بالقواعد", - showWithRulesTip: "عرض الأيقونة إذا كانت الصورة تتطابق مع القواعد بغض النظر عن حجمها", - advancedRules: "القواعد المتقدمة", - advancedRulesTip: "مطابقة بالقواعد المتقدمة", - tpRules: "قواعد البدل", - tpRulesTip: "مطابقة بقواعد البدل", - scaleRules: "مكبرة", - scaleRulesTip: "الصورة التي تم العثور عليها تلقائيًا ولكن تم تكبيرها", - noScaleRules: "بدون تكبير", - noScaleRulesTip: "الصورة التي تم العثور عليها تلقائيًا ولكن بدون تكبير", - smallRules: "حجم صغير", - smallRulesTip: "بكسل #t# صورة صغيرة الحجم، الحجم الفعلي للارتفاع والعرض أقل من", - lockSizeTip: "قفل الحجم الأقصى", - command: "أمر", - commandTip: "قائمة الأوامر", - onlineEdit: "تحرير عبر الإنترنت", - onlineEditTip: "#t# تحرير هذه الصورة عبر الإنترنت باستخدام", - openInNewWindow: "فتح في نافذة جديدة", - openInNewWindowTip: "فتح الصورة في نافذة جديدة", - findInPage: "بحث في الصفحة", - findInPageTip: "التمرير إلى الصورة الحالية في الصفحة", - viewCollection: "عرض المجموعة", - viewCollectionTip: "عرض جميع الصور المجمعة", - inCollection: "غير قادر على الاستخدام في وضع المجموعة", - cantFind: "الصورة ليست في الوثيقة، أو مخفية ولا يمكن العثور عليها!", - exportImages: "تصدير جميع الصور", - exportImagesTip: "تصدير جميع الصور الكبيرة المعروضة إلى نافذة جديدة", - downloadImage: "تنزيل جميع المعروض", - downloadImageTip: "تنزيل الصور الحالية المعروضة", - copyImagesUrl: "نسخ روابط جميع الصور", - copyImagesUrlTip: "نسخ روابط جميع الصور الكبيرة المعروضة", - copySuccess: "تم نسخ #t# روابط بنجاح", - autoRefresh: "تحميل الصفحة تلقائيًا", - autoRefreshTip: "عند عرض الصور القليلة الأخيرة، قم بالتمرير إلى الأسفل، بحيث تقوم بعض صفحات الويب بتحميل الصور الجديدة", - enterFullsc: "دخول ملء الشاشة", - exitFullsc: "خروج من ملء الشاشة", - config: "الإعدادات", - openConfig: "فتح الإعدادات", - ruleRequest: "طلب القواعد", - closeGallery: "إغلاق المعرض", - returnToGallery: "العودة إلى المعرض", - picInfo: "انقر لتغيير", - picNote: "تعليق الصورة", - urlFilter: "مرشح الرابط", - urlFilterTip: "أدخل كلمات رئيسية أو تعبيرات منتظمة لتصفية الروابط", - resolution: "دقة الصورة", - picNum: "عدد الصور", - picTips: "CTRL عرض الصور باستخدام", - savePageTips: "احفظ هذه الصفحة لتنزيل جميع الصور", - scaleRatio: "نسبة التكبير", - similarImage: "البحث بالصورة", - scale: "تكبير", - horizontalFlip: "انعكاس أفقي", - verticalFlip: "انعكاس عمودي", - actualBtn: "عرض الأصلي (A)", - searchBtn: "البحث عن الصورة الأصلية (S)", - galleryBtn: "عرض المعرض (G)", - currentBtn: "عرض الحالية (C)", - magnifierBtn: "مكبر/تكبير (M)", - picTitle: "عنوان الصورة", - exportImagesUrl: "تصدير روابط الصور", - exportImagesUrlPop: "Ctrl+C لنسخ روابط الصور", - beginSearchImg: "#t# البدء في البحث عن الصورة ...", - findNoPic: "لم يتم العثور على الصورة الأصلية", - findOverBeginLoad: "#t# نهاية الخريطة، العثور على #t# صور متطابقة، بدء تحميل الأولى", - loadNextSimilar: "فشل تحميل الصورة الأصلية، حاول تحميل النتيجة التالية...", - loadError: "فشل التحميل", - openHomePage: "فتح الصفحة الرئيسية", - position: "وضع العرض", - positionTips: "لإخفاء ALT اضغط مع الاستمرار على", - topLeft: "الزاوية العلوية اليسرى من الصورة", - topRight: "الزاوية العلوية اليمنى من الصورة", - bottomRight: "الزاوية السفلية اليمنى من الصورة", - bottomLeft: "الزاوية السفلية اليسرى من الصورة", - topCenter: "بجانب الصورة", - bottomCenter: "أسفل الصورة", - floatBar: "شريط الأدوات", - previewFollowMouse: "عرض المعاينة بجانب الفأرة", - showDelay: "تأخير العرض", - ms: "مللي ثانية", - hide: "إخفاء", - hideDelay: "تأخير الإخفاء", - forceShow: "عرض شريط الأدوات فوق الصورة غير المكبرة التي تتجاوز هذا الحجم،", - forceShowTip: "عرض شريط الأدوات العائم عندما يتجاوز حجم الصورة غير المكبرة الحجم المحدد أدناه", - sizeLimitOr: "فعال بالطول أو العرض فقط", - px: "بكسل", - minSizeLimit: "عرض شريط الأدوات فوق الصورة المكبرة التي تتجاوز هذا الحجم", - minSizeLimitTip: "بعد تكبير الصورة (لا يتطابق الحجم الأصلي للصورة مع الحجم الفعلي)، يتم عرض شريط الأدوات العائم عندما يكون طول الصورة المعروضة أكبر من القيمة المحددة.", - defaultSizeLimit: "حد الحجم الافتراضي للمعرض", - listenBg: "استماع لصورة الخلفية", - backgroundColor: "لون الخلفية", - listenBgTip: "عرض شريط الأدوات على العنصر الذي يحتوي على صورة خلفية", - butonOrder: "ترتيب رموز شريط الأدوات", - keysEnable: "تمكين الاختصارات", - keysActual: "فتح الصورة الكبيرة", - keysActualTip: "اضغط على هذا الزر لفتح صورة كبيرة عندما يظهر شريط الأدوات العائم", - keysSearch: "البحث عن الصورة الأصلية", - keysSearchTip: "اضغط على هذا الزر للبحث عن الصورة الأصلية عندما يظهر شريط الأدوات العائم", - headSearchTip: "البحث بالصورة", - headSearchAll: "البحث في الكل", - keysCurrent: "فتح الصورة الحالية", - keysCurrentTip: "اضغط على هذا الزر لفتح الصورة الحالية عندما يظهر شريط الأدوات العائم", - keysMagnifier: "فتح المكبر للمراقبة", - keysMagnifierTip: "اضغط على هذا الزر لفتح المكبر عندما يظهر شريط الأدوات العائم", - keysGallery: "فتح المعرض (عالمي مع مفاتيح الوظائف)", - keysGalleryTip: "اضغط على هذا الزر لفتح المعرض عندما يظهر شريط الأدوات العائم", - openGallery: "فتح المعرض", - magnifier: "تكبير", - magnifierRadius: "نصف القطر الافتراضي", - magnifierWheelZoomEnabled: "تمكين تكبير العجلة", - magnifierWheelZoomRange: "نسبة التكبير للمكبر", - magnifierScaleImage: "تكبير الصورة بالعجلة", - gallery: "المعرض", - galleryFitToScreen: "تكبير الصورة لتناسب الشاشة", - galleryFitToScreenSmall: "تكبير الصورة الصغيرة أيضًا", - galleryFitToScreenTip: "التكيف ليكون يحتوي، وليس يغطي", - galleryScrollEndToChange: "تبديل الصورة بعد التمرير إلى نهاية الصورة الطويلة", - galleryScrollEndToChangeTip: "فعال بعد إلغاء الخيار السابق", - galleryExportType: "الترتيب الافتراضي عند تصدير الصور", - grid: "ترتيب البلاط", - gridBig: "الترتيب الأصلي", - list: "ترتيب القائمة", - galleryAutoLoad: "تحميل المزيد من الصور تلقائيًا في الصفحة التالية", - galleryLoadAll: "معالجة جميع الصفحات تلقائيًا عند تحميل المزيد من الصور", - galleryLoadAllTip: "قد تؤثر الصفحات الكثيرة على التجربة", - galleryDownloadWithZip: "ضغط إلى ZIP عند تنزيل الكل", - galleryDownloadWithZipAlert: "جارٍ الضغط، يرجى الانتظار قليلاً", - galleryScaleSmallSize1: "الحجم الفعلي أقل من الارتفاع والعرض", - galleryScaleSmallSize2: "البكسلات مصنفة كصور صغيرة الحجم", - galleryShowSmallSize: "عرض الصور الصغيرة افتراضيًا", - galleryTransition: "عرض التأثيرات عند التبديل بين الصور في المعرض", - gallerySidebarPosition: "وضع شريط الصور المصغرة", - bottom: "الأسفل", - right: "اليمين", - left: "اليسار", - top: "الأعلى", - gallerySidebarSize: "الارتفاع", - gallerySidebarSizeTip: "ارتفاع شريط الصور المصغرة (إذا كان أفقيًا) أو العرض (إذا كان رأسيًا)", - galleryMax1: "التحميل المسبق الأقصى", - galleryMax2: "الصور (قبل وبعد)", - galleryAutoZoom: "التكبير يعود إلى 100% (كروم)", - galleryAutoZoomTip: "إذا قمت بالتكبير، قم بتغيير تكبير الصورة وأجزاء شريط الصور المصغرة إلى 100% وزيادة المساحة القابلة للعرض (صالح فقط في كروم)", - galleryDescriptionLength1: "الحد الأقصى للتعليق هو", - galleryDescriptionLength2: "الأحرف", - galleryAutoOpenSites: "عناوين المواقع لفتح المعرض تلقائيًا، واحد في كل سطر، يبدأ بـ @ لعرض المزيد", - autoOpenViewmore: "عرض المزيد تلقائيًا عند فتح المعرض", - gallerySearchData: "قواعد المواقع للبحث، أفرغها لاستعادة", - galleryEditSite: "تحرير الموقع عبر الإنترنت", - imgWindow: "نافذة الصورة", - imgWindowFitToScreen: "التكيف مع الشاشة", - imgWindowFitToScreenTip: "التكيف ليكون يحتوي، وليس يغطي", - imgWindowFitToScreenWhenSmall: "التكيف مع الشاشة حتى وإن كانت صغيرة", - imgWindowDefaultTool: "الأداة المختارة افتراضيًا عند فتح النافذة", - hand: "اليد", - rotate: "تدوير", - zoom: "مكبر", - imgWindowEscKey: "Esc ، للإغلاق", - imgWindowDblClickImgWindow: "النقر المزدوج للإغلاق", - imgWindowClickOutside: "النقر خارج النافذة للإغلاق", - imgWindowClickOutsideTip: "فعالة فقط عند عرض الطبقة الزائدة", - none: "لا شيء", - click: "نقرة", - dblclick: "نقرة مزدوجة", - imgWindowOverlayerShown: "الطبقة الزائدة", - imgWindowOverlayerColor: "اللون والعتامة", - imgWindowShiftRotateStep1: "Shift تدوير للكل عند الضغط على", - imgWindowShiftRotateStep2: "درجة", - imgWindowMouseWheelZoom: "تكبير باستخدام عجلة الفأرة", - imgWindowZoomRange: "نطاق التكبير", - imgWindowZoomRangeTip: "نسبة التكبير (يجب أن تكون موجبة)", - others: "أخرى", - waitImgLoad: "البدء في تنفيذ العمليات مثل التكبير حتى يتم تحميل الصورة", - waitImgLoadTip: "يمكنك مؤقتًا تنفيذ العكس لهذا الإعداد ،Ctrl عند الضغط مع الاستمرار على", - debug: "وضع التصحيح", - customRules: "القواعد المخصصة للصورة الكبيرة", - firstEngine: "محرك البحث المفضل (الأول)", - refreshWhenError: "خطأ في القراءة، انقر لإعادة التحميل", - switchSlide: "تبديل الشريط الجانبي", - viewmore: "عرض المزيد", - countDown: "العد التنازلي", - customLang: "اللغة المخصصة", - defaultLang: "الكشف التلقائي", - hideIcon: "إخفاء الأيقونة", - initShow: "عكس الاختصار لعرض المعاينة افتراضيًا", - stayOut: "دع شريط الأدوات العائم يبقى خارج الصورة", - galleryDownloadGap: "الفاصل الزمني للتنزيل", - formatConversion: "تحويل تنسيق الصورة عند التنزيل. قاعدة واحدة في كل سطر", - galleryDisableArrow: "تعطيل مفتاح السهم", - positionFixed: "موضع ثابت", - switchStoreLoc: "الاحتفاظ بموقع الذاكرة أثناء التبديل" - } -}, { name: "English", match: ["en"], @@ -512,7 +255,264 @@ const langData = [ positionFixed: "Fixed position", switchStoreLoc: "Memory position retention during switching" } -}, +}, +{ + name: "Arabic", + match: ["ar", "ar-AE", "ar-BH", "ar-DZ", "ar-EG", "ar-IQ", "ar-JO", "ar-KW", "ar-LB", "ar-LY", "ar-MA", "ar-OM", "ar-QA", "ar-SA", "ar-SY", "ar-TN", "ar-YE"], + lang: { + // Translated by Prankster 199 (vfggf95565). + saveBtn: "حفظ", + saveName: "حفظ الاسم", + saveNameTip: "احفظ الصور بالاسم", + default: "افتراضي", + textFirst: "المعلومات أولاً إذا كانت موجودة", + onlyUrl: "فقط مع الرابط", + urlAndText: "الرابط + المعلومات", + download: "تنزيل", + saveBtnTips: "بعض الخيارات تحتاج إلى تحديث الصفحة لتطبيقها", + additionalFeature: "ميزة إضافية، تأخذ تأثير عند الضغط على مفتاح Alt", + invertAdditionalFeature: "عكس مفاتيح الاختصار، استخدم الميزات الإضافية افتراضيًا", + copy: "نسخ الرابط", + copyImg: "نسخ بيانات الصورة", + openInNewTab: "فتح في علامة تبويب جديدة", + closeBtn: "إلغاء", + invertBtn: "عكس", + compareBtn: "مقارنة", + selectAllBtn: "تحديد الكل", + closeBtnTips: "إلغاء هذا الإعداد واستعادة جميع الخيارات", + resetLink: "استعادة الإعدادات الافتراضية", + resetLinkTips: "استعادة جميع الإعدادات إلى القيم الافتراضية", + share: "مشاركة", + suitLongImg: "تناسب الصور الطويلة في نافذة التمرير", + globalkeys: "المفاتيح العامة للمعاينة: ", + globalkeysPress: "اضغط لتبديل المعاينة", + globalkeysHold: "اضغط مع الاستمرار لتمكين المعاينة", + globalkeysType: "طريقة تمكين المعاينة", + closeAfterPreview: "إغلاق نافذة الصورة بعد المعاينة", + previewMaxSize: "الحجم الأقصى لنافذة المعاينة", + previewMaxSizeTip: "عندما تكون نافذة المعاينة أكبر من الحجم المحدد، قم بتقليص نافذة المعاينة. 0 = معطل", + loadAll: "تحميل المزيد من الصفحات", + loadedAll: "تم التحميل", + loading: "جارٍ التحميل ...", + loadAllTip: "تحميل الصورة في الصفحة التالية", + viewmoreEndless: "تحميل المزيد من الصور عند التمرير إلى الأسفل", + fiddle: "تشغيل", + fiddleTip: "ظهور الصور للعمليات المعقدة", + addImageUrls: "إضافة صورة", + addImageUrlsTips: "إضافة المزيد من الصور عبر الرابط", + openImages: "صورة محلية", + openImagesTips: "انقر لاستيراد الصور المحلية", + closeFirst: "أغلق المعرض الحالي أولاً", + collect: "مجموعة", + collected: "تم الجمع", + exitCollection: "الخروج من المجموعة", + exitCollectionTip: "انقر للخروج من وضع المجموعة", + noCollectionYet: "ليس لديك أي صورة في المجموعة", + collectDetail: "وصف", + collectDetailTip: "أضف بعض الأوصاف إلى صورك المفضلة", + playSlide: "تشغيل الشرائح", + slideGap: "الفاصل (ثواني)", + slideGapTip: "الفاصل، وحدة (ثواني)", + slideBack: "رجوع", + slideBackTip: "التشغيل من الخلف إلى الأمام", + slideWait: "انتظر قراءة الصورة", + slideWaitTip: "يبدأ العد التنازلي بعد قراءة كل صورة بالكامل.", + slideSkipError: "تخطي الصور الخاطئة", + slideSkipErrorTip: "تخطي الصور الخاطئة بسرعة", + type: "الفئة", + typeTip: "اختر فئة الصورة", + showWithRules: "إظهار الأيقونة بالقواعد", + showWithRulesTip: "عرض الأيقونة إذا كانت الصورة تتطابق مع القواعد بغض النظر عن حجمها", + advancedRules: "القواعد المتقدمة", + advancedRulesTip: "مطابقة بالقواعد المتقدمة", + tpRules: "قواعد البدل", + tpRulesTip: "مطابقة بقواعد البدل", + scaleRules: "مكبرة", + scaleRulesTip: "الصورة التي تم العثور عليها تلقائيًا ولكن تم تكبيرها", + noScaleRules: "بدون تكبير", + noScaleRulesTip: "الصورة التي تم العثور عليها تلقائيًا ولكن بدون تكبير", + smallRules: "حجم صغير", + smallRulesTip: "بكسل #t# صورة صغيرة الحجم، الحجم الفعلي للارتفاع والعرض أقل من", + lockSizeTip: "قفل الحجم الأقصى", + command: "أمر", + commandTip: "قائمة الأوامر", + onlineEdit: "تحرير عبر الإنترنت", + onlineEditTip: "#t# تحرير هذه الصورة عبر الإنترنت باستخدام", + openInNewWindow: "فتح في نافذة جديدة", + openInNewWindowTip: "فتح الصورة في نافذة جديدة", + findInPage: "بحث في الصفحة", + findInPageTip: "التمرير إلى الصورة الحالية في الصفحة", + viewCollection: "عرض المجموعة", + viewCollectionTip: "عرض جميع الصور المجمعة", + inCollection: "غير قادر على الاستخدام في وضع المجموعة", + cantFind: "الصورة ليست في الوثيقة، أو مخفية ولا يمكن العثور عليها!", + exportImages: "تصدير جميع الصور", + exportImagesTip: "تصدير جميع الصور الكبيرة المعروضة إلى نافذة جديدة", + downloadImage: "تنزيل جميع المعروض", + downloadImageTip: "تنزيل الصور الحالية المعروضة", + copyImagesUrl: "نسخ روابط جميع الصور", + copyImagesUrlTip: "نسخ روابط جميع الصور الكبيرة المعروضة", + copySuccess: "تم نسخ #t# روابط بنجاح", + autoRefresh: "تحميل الصفحة تلقائيًا", + autoRefreshTip: "عند عرض الصور القليلة الأخيرة، قم بالتمرير إلى الأسفل، بحيث تقوم بعض صفحات الويب بتحميل الصور الجديدة", + enterFullsc: "دخول ملء الشاشة", + exitFullsc: "خروج من ملء الشاشة", + config: "الإعدادات", + openConfig: "فتح الإعدادات", + ruleRequest: "طلب القواعد", + closeGallery: "إغلاق المعرض", + returnToGallery: "العودة إلى المعرض", + picInfo: "انقر لتغيير", + picNote: "تعليق الصورة", + urlFilter: "مرشح الرابط", + urlFilterTip: "أدخل كلمات رئيسية أو تعبيرات منتظمة لتصفية الروابط", + resolution: "دقة الصورة", + picNum: "عدد الصور", + picTips: "CTRL عرض الصور باستخدام", + savePageTips: "احفظ هذه الصفحة لتنزيل جميع الصور", + scaleRatio: "نسبة التكبير", + similarImage: "البحث بالصورة", + scale: "تكبير", + horizontalFlip: "انعكاس أفقي", + verticalFlip: "انعكاس عمودي", + actualBtn: "عرض الأصلي (A)", + searchBtn: "البحث عن الصورة الأصلية (S)", + galleryBtn: "عرض المعرض (G)", + currentBtn: "عرض الحالية (C)", + magnifierBtn: "مكبر/تكبير (M)", + picTitle: "عنوان الصورة", + exportImagesUrl: "تصدير روابط الصور", + exportImagesUrlPop: "Ctrl+C لنسخ روابط الصور", + beginSearchImg: "#t# البدء في البحث عن الصورة ...", + findNoPic: "لم يتم العثور على الصورة الأصلية", + findOverBeginLoad: "#t# نهاية الخريطة، العثور على #t# صور متطابقة، بدء تحميل الأولى", + loadNextSimilar: "فشل تحميل الصورة الأصلية، حاول تحميل النتيجة التالية...", + loadError: "فشل التحميل", + openHomePage: "فتح الصفحة الرئيسية", + position: "وضع العرض", + positionTips: "لإخفاء ALT اضغط مع الاستمرار على", + topLeft: "الزاوية العلوية اليسرى من الصورة", + topRight: "الزاوية العلوية اليمنى من الصورة", + bottomRight: "الزاوية السفلية اليمنى من الصورة", + bottomLeft: "الزاوية السفلية اليسرى من الصورة", + topCenter: "بجانب الصورة", + bottomCenter: "أسفل الصورة", + floatBar: "شريط الأدوات", + previewFollowMouse: "عرض المعاينة بجانب الفأرة", + showDelay: "تأخير العرض", + ms: "مللي ثانية", + hide: "إخفاء", + hideDelay: "تأخير الإخفاء", + forceShow: "عرض شريط الأدوات فوق الصورة غير المكبرة التي تتجاوز هذا الحجم،", + forceShowTip: "عرض شريط الأدوات العائم عندما يتجاوز حجم الصورة غير المكبرة الحجم المحدد أدناه", + sizeLimitOr: "فعال بالطول أو العرض فقط", + px: "بكسل", + minSizeLimit: "عرض شريط الأدوات فوق الصورة المكبرة التي تتجاوز هذا الحجم", + minSizeLimitTip: "بعد تكبير الصورة (لا يتطابق الحجم الأصلي للصورة مع الحجم الفعلي)، يتم عرض شريط الأدوات العائم عندما يكون طول الصورة المعروضة أكبر من القيمة المحددة.", + defaultSizeLimit: "حد الحجم الافتراضي للمعرض", + listenBg: "استماع لصورة الخلفية", + backgroundColor: "لون الخلفية", + listenBgTip: "عرض شريط الأدوات على العنصر الذي يحتوي على صورة خلفية", + butonOrder: "ترتيب رموز شريط الأدوات", + keysEnable: "تمكين الاختصارات", + keysActual: "فتح الصورة الكبيرة", + keysActualTip: "اضغط على هذا الزر لفتح صورة كبيرة عندما يظهر شريط الأدوات العائم", + keysSearch: "البحث عن الصورة الأصلية", + keysSearchTip: "اضغط على هذا الزر للبحث عن الصورة الأصلية عندما يظهر شريط الأدوات العائم", + headSearchTip: "البحث بالصورة", + headSearchAll: "البحث في الكل", + keysCurrent: "فتح الصورة الحالية", + keysCurrentTip: "اضغط على هذا الزر لفتح الصورة الحالية عندما يظهر شريط الأدوات العائم", + keysMagnifier: "فتح المكبر للمراقبة", + keysMagnifierTip: "اضغط على هذا الزر لفتح المكبر عندما يظهر شريط الأدوات العائم", + keysGallery: "فتح المعرض (عالمي مع مفاتيح الوظائف)", + keysGalleryTip: "اضغط على هذا الزر لفتح المعرض عندما يظهر شريط الأدوات العائم", + openGallery: "فتح المعرض", + magnifier: "تكبير", + magnifierRadius: "نصف القطر الافتراضي", + magnifierWheelZoomEnabled: "تمكين تكبير العجلة", + magnifierWheelZoomRange: "نسبة التكبير للمكبر", + magnifierScaleImage: "تكبير الصورة بالعجلة", + gallery: "المعرض", + galleryFitToScreen: "تكبير الصورة لتناسب الشاشة", + galleryFitToScreenSmall: "تكبير الصورة الصغيرة أيضًا", + galleryFitToScreenTip: "التكيف ليكون يحتوي، وليس يغطي", + galleryScrollEndToChange: "تبديل الصورة بعد التمرير إلى نهاية الصورة الطويلة", + galleryScrollEndToChangeTip: "فعال بعد إلغاء الخيار السابق", + galleryExportType: "الترتيب الافتراضي عند تصدير الصور", + grid: "ترتيب البلاط", + gridBig: "الترتيب الأصلي", + list: "ترتيب القائمة", + galleryAutoLoad: "تحميل المزيد من الصور تلقائيًا في الصفحة التالية", + galleryLoadAll: "معالجة جميع الصفحات تلقائيًا عند تحميل المزيد من الصور", + galleryLoadAllTip: "قد تؤثر الصفحات الكثيرة على التجربة", + galleryDownloadWithZip: "ضغط إلى ZIP عند تنزيل الكل", + galleryDownloadWithZipAlert: "جارٍ الضغط، يرجى الانتظار قليلاً", + galleryScaleSmallSize1: "الحجم الفعلي أقل من الارتفاع والعرض", + galleryScaleSmallSize2: "البكسلات مصنفة كصور صغيرة الحجم", + galleryShowSmallSize: "عرض الصور الصغيرة افتراضيًا", + galleryTransition: "عرض التأثيرات عند التبديل بين الصور في المعرض", + gallerySidebarPosition: "وضع شريط الصور المصغرة", + bottom: "الأسفل", + right: "اليمين", + left: "اليسار", + top: "الأعلى", + gallerySidebarSize: "الارتفاع", + gallerySidebarSizeTip: "ارتفاع شريط الصور المصغرة (إذا كان أفقيًا) أو العرض (إذا كان رأسيًا)", + galleryMax1: "التحميل المسبق الأقصى", + galleryMax2: "الصور (قبل وبعد)", + galleryAutoZoom: "التكبير يعود إلى 100% (كروم)", + galleryAutoZoomTip: "إذا قمت بالتكبير، قم بتغيير تكبير الصورة وأجزاء شريط الصور المصغرة إلى 100% وزيادة المساحة القابلة للعرض (صالح فقط في كروم)", + galleryDescriptionLength1: "الحد الأقصى للتعليق هو", + galleryDescriptionLength2: "الأحرف", + galleryAutoOpenSites: "عناوين المواقع لفتح المعرض تلقائيًا، واحد في كل سطر، يبدأ بـ @ لعرض المزيد", + autoOpenViewmore: "عرض المزيد تلقائيًا عند فتح المعرض", + gallerySearchData: "قواعد المواقع للبحث، أفرغها لاستعادة", + galleryEditSite: "تحرير الموقع عبر الإنترنت", + imgWindow: "نافذة الصورة", + imgWindowFitToScreen: "التكيف مع الشاشة", + imgWindowFitToScreenTip: "التكيف ليكون يحتوي، وليس يغطي", + imgWindowFitToScreenWhenSmall: "التكيف مع الشاشة حتى وإن كانت صغيرة", + imgWindowDefaultTool: "الأداة المختارة افتراضيًا عند فتح النافذة", + hand: "اليد", + rotate: "تدوير", + zoom: "مكبر", + imgWindowEscKey: "Esc ، للإغلاق", + imgWindowDblClickImgWindow: "النقر المزدوج للإغلاق", + imgWindowClickOutside: "النقر خارج النافذة للإغلاق", + imgWindowClickOutsideTip: "فعالة فقط عند عرض الطبقة الزائدة", + none: "لا شيء", + click: "نقرة", + dblclick: "نقرة مزدوجة", + imgWindowOverlayerShown: "الطبقة الزائدة", + imgWindowOverlayerColor: "اللون والعتامة", + imgWindowShiftRotateStep1: "Shift تدوير للكل عند الضغط على", + imgWindowShiftRotateStep2: "درجة", + imgWindowMouseWheelZoom: "تكبير باستخدام عجلة الفأرة", + imgWindowZoomRange: "نطاق التكبير", + imgWindowZoomRangeTip: "نسبة التكبير (يجب أن تكون موجبة)", + others: "أخرى", + waitImgLoad: "البدء في تنفيذ العمليات مثل التكبير حتى يتم تحميل الصورة", + waitImgLoadTip: "يمكنك مؤقتًا تنفيذ العكس لهذا الإعداد ،Ctrl عند الضغط مع الاستمرار على", + debug: "وضع التصحيح", + customRules: "القواعد المخصصة للصورة الكبيرة", + firstEngine: "محرك البحث المفضل (الأول)", + refreshWhenError: "خطأ في القراءة، انقر لإعادة التحميل", + switchSlide: "تبديل الشريط الجانبي", + viewmore: "عرض المزيد", + countDown: "العد التنازلي", + customLang: "اللغة المخصصة", + defaultLang: "الكشف التلقائي", + hideIcon: "إخفاء الأيقونة", + initShow: "عكس الاختصار لعرض المعاينة افتراضيًا", + stayOut: "دع شريط الأدوات العائم يبقى خارج الصورة", + galleryDownloadGap: "الفاصل الزمني للتنزيل", + formatConversion: "تحويل تنسيق الصورة عند التنزيل. قاعدة واحدة في كل سطر", + galleryDisableArrow: "تعطيل مفتاح السهم", + positionFixed: "موضع ثابت", + switchStoreLoc: "الاحتفاظ بموقع الذاكرة أثناء التبديل" + } +}, { name: "简体中文", match: ["zh-CN", "zh-SG"], From d6dea9b8d713ce86a05d3751de0b9a19a5562be2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 6 Jun 2024 14:13:28 +0800 Subject: [PATCH 0021/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index a2ed9081d3b..e8f2c83b897 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.6.1 +// @version 2024.6.6.2 // @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 @@ -47,7 +47,7 @@ // @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/1389633/pvcep_lang.js +// @require https://update.greasyfork.org/scripts/440698/1389914/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 // @match *://*/* From 66808584a5630cda6370db47bc02d7e93ad85141 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 6 Jun 2024 16:20:56 +0800 Subject: [PATCH 0022/1065] zh --- Pagetual/pagetual.user.js | 2 +- Picviewer CE+/pvcep_lang.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index e812e0d1afb..bcaf60a71b9 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -485,7 +485,7 @@ }, { name: "正體中文", - match: ["zh-TW", "zh-HK"], + match: ["zh", "zh-TW", "zh-HK"], lang: { enableDebug: "調試模式,輸出信息至控制台", updateNotification: "規則更新后提示", diff --git a/Picviewer CE+/pvcep_lang.js b/Picviewer CE+/pvcep_lang.js index 507f760decf..7913b98dba2 100644 --- a/Picviewer CE+/pvcep_lang.js +++ b/Picviewer CE+/pvcep_lang.js @@ -771,7 +771,7 @@ const langData = [ }, { name: "正體中文", - match: ["zh-TW", "zh-HK", "zh-MO"], + match: ["zh", "zh-TW", "zh-HK", "zh-MO"], lang: { saveBtn: "確定", saveName: "保存圖片名", From d790624bbd5026f206e244ef5a6d95869b5493e7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 6 Jun 2024 16:22:01 +0800 Subject: [PATCH 0023/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index e8f2c83b897..cdf82ccdd16 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -47,7 +47,7 @@ // @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/1389914/pvcep_lang.js +// @require https://update.greasyfork.org/scripts/440698/1389981/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 // @match *://*/* From ccdecf128ee0023fc61152380bc7df20fd8d9ad7 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 6 Jun 2024 09:17:32 +0000 Subject: [PATCH 0024/1065] Update version of Pagetual rules to 22 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index aabe6ec3909..2bd5a0a98a3 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -21 +22 From c49d9fb92c6e142fea3a3945d843a09ad450e6eb Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 7 Jun 2024 18:09:25 +0800 Subject: [PATCH 0025/1065] 1.9.37.52 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 12 +++++++++--- Pagetual/pagetualRules.json | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 229d8d56fd0..83704dc94da 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.51](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.52](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index bcaf60a71b9..db252bc6c8d 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.51 +// @version 1.9.37.52 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -5313,12 +5313,18 @@ function startAutoScroll() { clearInterval(autoScrollInterval); if (autoScroll <= 0) return; - let scrollRange = 1; + let scrollRange_o = 1; if (autoScroll > 1000) { - scrollRange = parseInt(autoScroll / 1000) + scrollRange_o = parseInt(autoScroll / 1000); } + let devicePixelRatio = window.devicePixelRatio; + let scrollRange = Math.ceil(scrollRange_o / devicePixelRatio); autoScrollInterval = setInterval(() => { if (isPause) return; + if (devicePixelRatio !== window.devicePixelRatio) { + devicePixelRatio = window.devicePixelRatio; + scrollRange = Math.ceil(scrollRange_o / devicePixelRatio); + } window.scroll(window.scrollX, window.scrollY + scrollRange); }, parseInt(1000 / autoScroll)); } diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 5689d9e798f..5152c4850d6 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -3449,7 +3449,8 @@ "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", "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": "doc.getElementById('img').setAttribute('onerror','setTimeout(()=>{this.src=this.src},500)');" }, { "name": "177 漫画/xxiav - 圖片", From ad26e897057f8a81e88933f0ebd8a1e39c912556 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Fri, 7 Jun 2024 10:09:43 +0000 Subject: [PATCH 0026/1065] Update version of Pagetual rules to 23 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 2bd5a0a98a3..409940768f2 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -22 +23 From 1556f8f0ddcc4d0f546f2b1fdbeba7191efbb637 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 7 Jun 2024 20:27:28 +0800 Subject: [PATCH 0027/1065] more time --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 83704dc94da..063538eacfa 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.52](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.53](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index db252bc6c8d..2a2bfc6e8d3 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.52 +// @version 1.9.37.53 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -1318,7 +1318,7 @@ _GM_xmlhttpRequest({ url: url, method: 'GET', - timeout: 20000, + timeout: 1000000, headers: { 'accept': 'application/json,text/html', 'Referer': url, @@ -5460,7 +5460,7 @@ if (!diff) { showTips(i18n("errorAlreadyExists")); setTimeout(() => { - showTips(i18n("beginUpdate"), "", 30000); + showTips(i18n("beginUpdate"), "", 50000); updateRules(() => { showTips(i18n("updateSucc")); location.reload(); @@ -6781,7 +6781,7 @@ data: postParams, overrideMimeType: 'text/html;charset=' + charset, headers: headers, - timeout: 20000, + timeout: 50000, onload: async function(res) { if (isPause) return callback(false); var doc = null, response = res.response; From a7b64875986639d8ad906e5cfde9bf02e4d926e0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 7 Jun 2024 21:36:52 +0800 Subject: [PATCH 0028/1065] Create AppinnComment.user.js --- Appinn Comment/AppinnComment.user.js | 42 ++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Appinn Comment/AppinnComment.user.js diff --git a/Appinn Comment/AppinnComment.user.js b/Appinn Comment/AppinnComment.user.js new file mode 100644 index 00000000000..6231c966a34 --- /dev/null +++ b/Appinn Comment/AppinnComment.user.js @@ -0,0 +1,42 @@ +// ==UserScript== +// @name Appinn comment +// @namespace hoothin +// @version 2024-06-07 +// @description 将小众软件论坛的评论内容显示在主站对应页面下部 +// @author hoothin +// @match https://www.appinn.com/* +// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== +// @grant GM_xmlhttpRequest +// @connect meta.appinn.net +// ==/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; + console.log(dataPreloaded); + let posts = document.createElement("ul"); + posts.style.maxHeight = '100vh'; + posts.style.overflow = 'auto'; + let title = document.createElement("h3"); + title.innerText = "评论内容"; + document.querySelector('article').appendChild(title); + document.querySelector('article').appendChild(posts); + dataPreloaded.forEach(item => { + posts.innerHTML += `
  • ${item.cooked}
  • `; + }); + } catch (e) { + } + } + }); +})(); \ No newline at end of file From 12e1d898399511d65afabc0f03667979aa5c072c Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 7 Jun 2024 21:44:40 +0800 Subject: [PATCH 0029/1065] Update AppinnComment.user.js --- Appinn Comment/AppinnComment.user.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Appinn Comment/AppinnComment.user.js b/Appinn Comment/AppinnComment.user.js index 6231c966a34..a75d8e95d0b 100644 --- a/Appinn Comment/AppinnComment.user.js +++ b/Appinn Comment/AppinnComment.user.js @@ -24,7 +24,6 @@ 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; - console.log(dataPreloaded); let posts = document.createElement("ul"); posts.style.maxHeight = '100vh'; posts.style.overflow = 'auto'; From 8937a1cc1afb4b9dd5dbcdd8b8c8b317d2c74900 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 8 Jun 2024 08:25:41 +0800 Subject: [PATCH 0030/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 5152c4850d6..4117a00170e 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -4,7 +4,7 @@ "author": "dyzer", "url": "^https?://u2\\.dmhy\\.org/torrents\\.php", "example": "https://u2.dmhy.org/torrents.php", - "pageElement": "body > table.mainouter > tbody > tr:nth-of-type(2) > td.outer > table.main > tbody > tr > td.embedded", + "pageElement": "body > table.mainouter > tbody > tr:nth-of-type(2) > td.outer > table.main > tbody > tr > td.embedded" }, { "name": "Qi Xing Blog | 一个互联网角落的秘密基地~🥳", From 2290ac22d0f3b00a6ebcdaffc58bf7d2a7dd6329 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 8 Jun 2024 00:26:01 +0000 Subject: [PATCH 0031/1065] Update version of Pagetual rules to 24 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 409940768f2..a45fd52cc58 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -23 +24 From e72f400b189ea45693b4eb9944fcda4bbb350cab Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 8 Jun 2024 09:38:59 +0800 Subject: [PATCH 0032/1065] Validate JSON --- .github/workflows/json-validator.yml | 21 +++++++++++++++++++++ Pagetual/pagetual.schema.json | 27 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 .github/workflows/json-validator.yml create mode 100644 Pagetual/pagetual.schema.json diff --git a/.github/workflows/json-validator.yml b/.github/workflows/json-validator.yml new file mode 100644 index 00000000000..a726236d040 --- /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@v3.0.0 + id: json-yaml-validate + with: + json_schema: Pagetual/pagetual.schema.json + files: | + Pagetual/pagetualRules.json \ No newline at end of file diff --git a/Pagetual/pagetual.schema.json b/Pagetual/pagetual.schema.json new file mode 100644 index 00000000000..565b8b77851 --- /dev/null +++ b/Pagetual/pagetual.schema.json @@ -0,0 +1,27 @@ +{ + "title": "Sites data", + "description": "Object containing site config", + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "title": "Site Name", + "description": "The site's name.", + "examples": [ + "Google" + ], + "type": "string" + }, + "url": { + "title": "Site Url", + "description": "The Regexp of site's url.", + "examples": [ + "^https:\/\/google\\.com\/" + ], + "type": "string" + } + }, + "required": ["name", "url"] + } +} \ No newline at end of file From 40aa43ca262c466717f1df94d5e4a887691fbff8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 8 Jun 2024 09:54:14 +0800 Subject: [PATCH 0033/1065] Update AppinnComment.user.js --- Appinn Comment/AppinnComment.user.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Appinn Comment/AppinnComment.user.js b/Appinn Comment/AppinnComment.user.js index a75d8e95d0b..902048d3955 100644 --- a/Appinn Comment/AppinnComment.user.js +++ b/Appinn Comment/AppinnComment.user.js @@ -1,13 +1,15 @@ // ==UserScript== // @name Appinn comment // @namespace hoothin -// @version 2024-06-07 +// @version 2024-06-08 // @description 将小众软件论坛的评论内容显示在主站对应页面下部 // @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() { @@ -27,12 +29,13 @@ let posts = document.createElement("ul"); posts.style.maxHeight = '100vh'; 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.cooked}
  • `; + posts.innerHTML += `
  • ${item.display_username || item.username}

    ${item.cooked}
  • `; }); } catch (e) { } From 79cb21bc8e09d6b1f1ff000de42c835f532287e7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 8 Jun 2024 09:55:26 +0800 Subject: [PATCH 0034/1065] Update AppinnComment.user.js --- Appinn Comment/AppinnComment.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Appinn Comment/AppinnComment.user.js b/Appinn Comment/AppinnComment.user.js index 902048d3955..6914dd4cd91 100644 --- a/Appinn Comment/AppinnComment.user.js +++ b/Appinn Comment/AppinnComment.user.js @@ -27,7 +27,7 @@ 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 = '100vh'; + posts.style.maxHeight = '90vh'; posts.style.overflow = 'auto'; posts.style.margin = '0'; let title = document.createElement("h3"); From 0cf43407248b1d9dd1fcb1655da33594fd9c4810 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 8 Jun 2024 01:56:50 +0000 Subject: [PATCH 0035/1065] Update items_all.json from http://wedata.net/databases/AutoPagerize/items_all.json --- Pagetual/items_all.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Pagetual/items_all.json b/Pagetual/items_all.json index a378901834a..48a56ea1815 100644 --- a/Pagetual/items_all.json +++ b/Pagetual/items_all.json @@ -20017,7 +20017,8 @@ { "resource_url": "http://wedata.net/items/77646", "data": { - "pageElement": "//div[@class=\"sd-main\"]//*[./a[@title]]", + "pageElement": "//div[@class=\"sd-main\"]//*[./div/a[@title]]", + "comment": "最後のアイテム内に継ぎ足されていたのを修正", "nextLink": "//a[@rel='next']", "url": "^https://speakerdeck\\.com/.+", "exampleUrl": "https://speakerdeck.com/p/all" @@ -20026,7 +20027,7 @@ "created_by": "Tanookirby", "name": "Speaker Deck", "created_at": "2015-11-08T03:43:39+09:00", - "updated_at": "2022-01-27T09:39:14+09:00" + "updated_at": "2024-06-07T22:14:23+09:00" }, { "resource_url": "http://wedata.net/items/77643", From 3b3f8309f26ec2b5750c48fa30ec7267505cff9d Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 8 Jun 2024 01:57:10 +0000 Subject: [PATCH 0036/1065] Update version of Pagetual rules to 25 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index a45fd52cc58..7273c0fa8c5 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -24 +25 From 288fa4c02991151cedf35078c3cd59c9c1446fb9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 8 Jun 2024 15:44:08 +0800 Subject: [PATCH 0037/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 4117a00170e..27d5f7a46cf 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -3450,7 +3450,7 @@ "pageElement": ".itg>div,.itg>tbody>tr:not(:first-of-type),.gl1t, #gdt>div:not(.c), #img", "replaceElement": ".ptt,.ptb,.sn,.searchnav", "css": "#img {max-width: 100% !important;height: auto !important;min-height: 400px;}", - "pageInit": "doc.getElementById('img').setAttribute('onerror','setTimeout(()=>{this.src=this.src},500)');" + "pageInit": "doc.getElementById('img').setAttribute('onerror','setTimeout(()=>{this.src=this.src},2000)');" }, { "name": "177 漫画/xxiav - 圖片", From f1f6199b4e70596219431ad8aa3ecd3aa4de846e Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 8 Jun 2024 07:44:29 +0000 Subject: [PATCH 0038/1065] Update version of Pagetual rules to 26 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 7273c0fa8c5..6f4247a6255 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -25 +26 From 1122c8c83bfd78b97a756f89174c2ccd3a8b49c6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 8 Jun 2024 19:22:14 +0800 Subject: [PATCH 0039/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 39 +++++++++++++++-------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index cdf82ccdd16..b334ea1a7c3 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.6.2 +// @version 2024.6.8.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 @@ -20591,6 +20591,7 @@ ImgOps | https://imgops.com/#b#`; .pv-pic-window-container>span.pv-pic-search-state:hover{\ overflow:visible;\ background:none;\ + box-shadow:none;\ }\ .pv-pic-window-container>span.pv-pic-search-state:hover>span{\ opacity: 0;\ @@ -20758,23 +20759,23 @@ ImgOps | https://imgops.com/#b#`; box-shadow: inset 0 21px 0 rgba(255,255,255,0.3) ,inset 0 -21px 0 rgba(0,0,0,0.3);\ border-left:2px solid #1771FF;\ }\ - span.pv-pic-window-tb-hand {\ - background-image: url("'+prefs.icons.hand+'");\ + .pv-pic-window-toolbar span.pv-pic-window-tb-hand {\ + background-image: url("'+prefs.icons.hand+'")!important;\ }\ - span.pv-pic-window-tb-rotate {\ - background-image: url("'+prefs.icons.rotate+'");\ + .pv-pic-window-toolbar span.pv-pic-window-tb-rotate {\ + background-image: url("'+prefs.icons.rotate+'")!important;\ }\ - span.pv-pic-window-tb-zoom {\ - background-image: url("'+prefs.icons.zoom+'");\ + .pv-pic-window-toolbar span.pv-pic-window-tb-zoom {\ + background-image: url("'+prefs.icons.zoom+'")!important;\ }\ - span.pv-pic-window-tb-flip-horizontal {\ - background-image: url("'+prefs.icons.flipHorizontal+'");\ + .pv-pic-window-toolbar span.pv-pic-window-tb-flip-horizontal {\ + background-image: url("'+prefs.icons.flipHorizontal+'")!important;\ }\ - span.pv-pic-window-tb-flip-vertical {\ - background-image: url("'+prefs.icons.flipVertical+'");\ + .pv-pic-window-toolbar span.pv-pic-window-tb-flip-vertical {\ + background-image: url("'+prefs.icons.flipVertical+'")!important;\ }\ - span.pv-pic-window-tb-compare {\ - background-image: url("'+prefs.icons.compare+'");\ + .pv-pic-window-toolbar span.pv-pic-window-tb-compare {\ + background-image: url("'+prefs.icons.compare+'")!important;\ }\ .pv-pic-window-tb-tool-badge-container {\ display: block;\ @@ -22837,22 +22838,22 @@ ImgOps | https://imgops.com/#b#`; margin-right: 4px;\ }\ #pv-float-bar-container .pv-float-bar-button-actual {\ - background-image:url("'+ prefs.icons.actual +'");\ + background-image:url("'+ prefs.icons.actual +'")!important;\ }\ #pv-float-bar-container .pv-float-bar-button-search {\ - background-image:url("'+ prefs.icons.search +'");\ + background-image:url("'+ prefs.icons.search +'")!important;\ }\ #pv-float-bar-container .pv-float-bar-button-gallery {\ - background-image:url("'+ prefs.icons.gallery +'");\ + background-image:url("'+ prefs.icons.gallery +'")!important;\ }\ #pv-float-bar-container .pv-float-bar-button-current {\ - background-image:url("'+ prefs.icons.current +'");\ + background-image:url("'+ prefs.icons.current +'")!important;\ }\ #pv-float-bar-container .pv-float-bar-button-magnifier {\ - background-image:url("'+ prefs.icons.magnifier +'");\ + background-image:url("'+ prefs.icons.magnifier +'")!important;\ }\ #pv-float-bar-container .pv-float-bar-button-download {\ - background-image:url("'+ prefs.icons.download +'");\ + background-image:url("'+ prefs.icons.download +'")!important;\ }\ '); }, From 0322c6cc75b886f4be9e78a1355c7963c9c383dd Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 8 Jun 2024 19:44:18 +0800 Subject: [PATCH 0040/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 8066da2bb8f..f0d23536987 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -627,7 +627,7 @@ var siteInfo = [ getImage: function(a, p){ let newsrc = this.src.replace("_normal.",".").replace("_200x200.",".").replace("_mini.",".").replace("_bigger.",".").replace(/_x\d+\./,"."); if (newsrc != this.src)return newsrc; - newsrc=newsrc.replace(/\?format=/i, ".").replace(/\&name=/i, ":").replace(/\.(?=[^.]*$)/, "?format=").replace( /(:large|:medium|:small|:orig|:thumb|:[\dx]+)/i, ""); + newsrc=newsrc.replace(/\?format=/i, ".").replace(/\&name=/i, ":").replace(/\.(?=[^\.\/]*$)/, "?format=").replace( /(:large|:medium|:small|:orig|:thumb|:[\dx]+)/i, ""); if (newsrc != this.src) { if (a && a.role == 'link') { let match = a.href.match(/\/([^\/]+)\/status\/([^\/]+)\/photo\/(\d+)/); From f5944cf1f925bfaaa26897fb38ba6dde8b61a0c9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 8 Jun 2024 21:09:58 +0800 Subject: [PATCH 0041/1065] Update pvcep_lang.js --- Picviewer CE+/pvcep_lang.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Picviewer CE+/pvcep_lang.js b/Picviewer CE+/pvcep_lang.js index 7913b98dba2..d6ae5e36581 100644 --- a/Picviewer CE+/pvcep_lang.js +++ b/Picviewer CE+/pvcep_lang.js @@ -7,6 +7,9 @@ const langData = [ saveBtn: "OK", saveName: "Save name", saveNameTip: "Save images with the name", + aria2Host: "Aria2 server", + aria2Token: "Aria2 token", + post2Aria2: "Post to aria2", default: "Default", textFirst: "Info first if exist", onlyUrl: "Only with URL", @@ -264,6 +267,9 @@ const langData = [ saveBtn: "حفظ", saveName: "حفظ الاسم", saveNameTip: "احفظ الصور بالاسم", + aria2Host: "خادم Aria2", + aria2Token: "رمز Aria2", + post2Aria2: "النشر إلى aria2", default: "افتراضي", textFirst: "المعلومات أولاً إذا كانت موجودة", onlyUrl: "فقط مع الرابط", @@ -520,6 +526,9 @@ const langData = [ saveBtn: "确定", saveName: "保存图片名", saveNameTip: "使用预设模式保存图片", + aria2Host: "aria2 服务器地址", + aria2Token: "aria2 密钥", + post2Aria2: "发送至 aria2", default: "默认", textFirst: "优先使用图片描述", onlyUrl: "仅使用 URL 中的文件名", @@ -776,6 +785,9 @@ const langData = [ saveBtn: "確定", saveName: "保存圖片名", saveNameTip: "使用預設模式保存圖片", + aria2Host: "aria2 伺服器位址", + aria2Token: "aria2 密鑰", + post2Aria2: "寄送至 aria2", default: "默認", textFirst: "優先使用圖片描述", onlyUrl: "僅使用 URL 中的文件名", @@ -1033,6 +1045,9 @@ const langData = [ saveBtn: "Salvar", saveName: "Nome ao salvar", saveNameTip: "Como será definido o nome do arquivo da imagem ao salva-la", + aria2Host: "Servidor aria2", + aria2Token: "Token aria2", + post2Aria2: "Postar em aria2", default: "Padrão", textFirst: "Informações primeiro se existirem", onlyUrl: "Apenas o URL", @@ -1290,6 +1305,9 @@ const langData = [ saveBtn: "Сохранить", saveName: "Сохранять название", saveNameTip: "Используйте для сохранения изображений с оригинальным названием", + aria2Host: "Сервер aria2", + aria2Token: "Токен aria2", + post2Aria2: "Опубликовать в aria2", default: "По умолчанию", textFirst: "Описание изображения", onlyUrl: "Только имя файла у ссылки", @@ -1547,6 +1565,9 @@ const langData = [ saveBtn: "Tamam", saveName: "İsmi kaydet", saveNameTip: "Görüntüleri isimle kaydet", + aria2Host: "Aria2 Sunucusu", + aria2Token: "Aria2 Belirteci", + post2Aria2: "Arya2'ye gönder", default: "Varsayılan", textFirst: "Varsa önce bilgi", onlyUrl: "Yalnızca URL ile", @@ -1803,6 +1824,9 @@ const langData = [ saveBtn: "保存", saveName: "保存名", saveNameTip: "画像を名前で保存", + aria2Host: "Aria2 サーバー", + aria2Token: "Aria2 トークン", + post2Aria2: "Aria2 に投稿", default: "初期設定", textFirst: "情報が存在する場合、先に表示", onlyUrl: "URLのみ", @@ -2060,6 +2084,9 @@ const langData = [ saveBtn: "Зберегти", saveName: "Назва файлу", saveNameTip: "Використовуйте для збереження зображень із оригінальною назвою", + aria2Host: "Сервер Aria2", + aria2Token: "Маркер Aria2", + post2Aria2: "Опублікувати в aria2", default: "За замовчуванням", textFirst: "Опис спочатку (якщо існує)", onlyUrl: "Тільки URL", From 423aeb6e45729cd0f88b4697eb48a55ea85f792a Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 8 Jun 2024 21:17:57 +0800 Subject: [PATCH 0042/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 113 +++++++++++++++++++--------- 1 file changed, 79 insertions(+), 34 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index b334ea1a7c3..12348163b06 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.8.1 +// @version 2024.6.8.2 // @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 @@ -46,8 +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/1389981/pvcep_lang.js +// @require https://update.greasyfork.org/scripts/438080/1391020/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/440698/1391048/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 // @match *://*/* @@ -12389,6 +12389,8 @@ ImgOps | https://imgops.com/#b#`; sidebarSize: 120,//侧栏的高(如果是水平放置)或者宽(如果是垂直放置) backgroundColor: 'rgba(20,20,20,0.75)', formatConversion: "webp>png", + aria2Host: "http://localhost:6800", + aria2Token: "", sidebarToggle: true, // 是否显示隐藏按钮 transition:true,//大图片区的动画。 preload:true,//对附近的图片进行预读。 @@ -13649,6 +13651,7 @@ ImgOps | https://imgops.com/#b#`; ''+i18n("viewCollection")+''+ ''+i18n("onlineEdit")+''+ ''+i18n("downloadImage")+''+ + ''+i18n("post2Aria2")+''+ ''+i18n("exportImages")+''+ ''+i18n("copyImagesUrl")+''+ ''+i18n("findInPage")+''+ @@ -14407,12 +14410,38 @@ ImgOps | https://imgops.com/#b#`; prefs.gallery.scrollEndAndLoad = !!storage.getListItem("scrollEndAndLoad", location.hostname); eleMaps['head-command-drop-list-others'].querySelector('input[data-command="scrollToEndAndReload"]').checked = prefs.gallery.scrollEndAndLoad; - var srcSplit,downloading=false; + let srcSplit, downloading=false, saveParams; + function getSaveParams() { + let nodes = self.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]'); + let saveParams = [],saveIndex=0; + [].forEach.call(nodes, function(node){ + if(unsafeWindow.getComputedStyle(node).display!="none"){ + saveIndex++; + if (node.dataset.src.indexOf('data') === 0) srcSplit = ""; + else { + srcSplit=node.dataset.src || ''; + } + let title = node.title.indexOf('\n') !== -1 ? node.title.split('\n')[0] : node.title; + title = title.indexOf('http') === 0 || title.indexOf('data') === 0 ? '' : title; + title = getRightSaveName(srcSplit, title, prefs.saveName); + let picName = (saveIndex < 10 ? "00" + saveIndex : (saveIndex < 100 ? "0" + saveIndex : saveIndex)) + (title ? "-" + title : ""), hostArr = location.host.split("."); + let host = hostArr[hostArr.length-2]; + saveParams.push([node.dataset.src, picName]); + if (node.dataset.srcs) { + node.dataset.srcs.split(",").forEach(src => { + saveParams.push([src, picName]); + }); + } + //saveAs(node.dataset.src, location.host+"-"+srcSplit[srcSplit.length-1]); + } + }); + return saveParams; + } //命令下拉列表的点击处理 eleMaps['head-command-drop-list-others'].addEventListener('click',function(e){ if(e.button!=0)return;//左键 - var target=e.target; - var command=dataset(target,'command'); + let target=e.target; + let command=dataset(target,'command'); if(!command)return; switch(command){ case 'openInNewWindow':{ @@ -14429,9 +14458,9 @@ ImgOps | https://imgops.com/#b#`; self.showTips(i18n("inCollection")); return; }; - var relatedThumb=self.relatedThumb; - var index=arrayFn.indexOf.call(self.imgSpans,relatedThumb); - var targetImg=self.data[index].img; + let relatedThumb=self.relatedThumb; + let index=arrayFn.indexOf.call(self.imgSpans,relatedThumb); + let targetImg=self.data[index].img; if(targetImg){ if(!document.documentElement.contains(targetImg) || unsafeWindow.getComputedStyle(targetImg).display=='none'){//图片不存在文档中,或者隐藏了。 @@ -14470,32 +14499,36 @@ ImgOps | https://imgops.com/#b#`; case 'exportImages': self.exportImages(); break; + case 'postImagesToAria2': + if (!prefs.gallery.aria2Host) { + self.showTips("Configure aria2 first!", 1000); + return; + } + saveParams = getSaveParams(); + [].forEach.call(saveParams, function(param){ + _GM_xmlhttpRequest({ + method: 'POST', + url: prefs.gallery.aria2Host + "/jsonrpc", + data: JSON.stringify({ + params: [ + "token:" + (prefs.gallery.aria2Token || ""), + [param[0]], + {"out": param[1]} + ], + jsonrpc: "2.0", + method: "aria2.addUri", + id: Math.random() + }), + onload: function(d) { + } + }); + }); + self.showTips("Completed!", 1000); + break; case 'downloadImage': if(downloading)break; downloading=true; - var nodes = self.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]'); - var saveParams = [],saveIndex=0; - [].forEach.call(nodes, function(node){ - if(unsafeWindow.getComputedStyle(node).display!="none"){ - saveIndex++; - if (node.dataset.src.indexOf('data') === 0) srcSplit = ""; - else { - srcSplit=node.dataset.src || ''; - } - var title = node.title.indexOf('\n') !== -1 ? node.title.split('\n')[0] : node.title; - title = title.indexOf('http') === 0 || title.indexOf('data') === 0 ? '' : title; - title = getRightSaveName(srcSplit, title, prefs.saveName); - var picName = (saveIndex < 10 ? "00" + saveIndex : (saveIndex < 100 ? "0" + saveIndex : saveIndex)) + (title ? "-" + title : ""), hostArr = location.host.split("."); - var host = hostArr[hostArr.length-2]; - saveParams.push([node.dataset.src, picName]); - if (node.dataset.srcs) { - node.dataset.srcs.split(",").forEach(src => { - saveParams.push([src, picName]); - }); - } - //saveAs(node.dataset.src, location.host+"-"+srcSplit[srcSplit.length-1]); - } - }); + saveParams = getSaveParams(); self.batchDownload(saveParams, ()=>{ downloading=false; self.showTips("Completed!", 1000); @@ -14579,7 +14612,7 @@ ImgOps | https://imgops.com/#b#`; } break; case 'addImageUrls': - var urls = window.prompt(i18n('addImageUrls') + ": White space to split multi-image, '[01-09]' to generate nine urls from 01 to 09, '$http://xxx' to fetch images from page","https://xxx.xxx/pic-[20-99].jpg https://xxx.xxx/pic-[01-10].png"); + let urls = window.prompt(i18n('addImageUrls') + ": White space to split multi-image, '[01-09]' to generate nine urls from 01 to 09, '$http://xxx' to fetch images from page","https://xxx.xxx/pic-[20-99].jpg https://xxx.xxx/pic-[01-10].png"); if (!urls) return; self.addImageUrls(urls); break; @@ -14742,7 +14775,7 @@ ImgOps | https://imgops.com/#b#`; } } addWheelEvent(eleMaps['body'],function(e){//wheel事件 - if(e.deltaZ!=0)return;//z轴 + if(e.deltaZ!=0 || e.target.nodeName=="TEXTAREA")return;//z轴 if(eleMaps['sidebar-toggle'].style.visibility == 'hidden')return; var target=e.target; //e.preventDefault(); @@ -19014,6 +19047,7 @@ ImgOps | https://imgops.com/#b#`; height: 80vh;\ border: 10px solid #272727;\ background: #ffffffee;\ + color: black;\ }\ span.pv-gallery-urls-textarea-close,\ span.pv-gallery-urls-textarea-download{\ @@ -25333,6 +25367,17 @@ ImgOps | https://imgops.com/#b#`; type: 'textarea', "default": prefs.gallery.formatConversion || '' }, + 'gallery.aria2Host': { + label: i18n("aria2Host"), + type: 'text', + className: 'order', + "default": prefs.gallery.aria2Host || 'http://localhost:6800' + }, + 'gallery.aria2Token': { + label: i18n("aria2Token"), + type: 'text', + "default": prefs.gallery.aria2Token || '' + }, 'gallery.scaleSmallSize': { label: i18n("galleryScaleSmallSize1"), type: 'int', From 46f0d2384e5ee1f53557b7004079db9b655c904e Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 9 Jun 2024 08:39:17 +0800 Subject: [PATCH 0043/1065] Update DownloadAllContent.user.js --- DownloadAllContent/DownloadAllContent.user.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index 4f64692cb00..64f9f092638 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -4,7 +4,7 @@ // @name:zh-TW 怠惰小説下載器 // @name:ja 怠惰者小説ダウンロードツール // @namespace hoothin -// @version 2.8.3.5 +// @version 2.8.3.6 // @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文檔 @@ -816,11 +816,11 @@ if (window.top != window.self) { function saveContent() { if (win.downloadAllContentSaveAsZip && saveAsZip) { win.downloadAllContentSaveAsZip(rCats, i18n.info.replace("#t#", location.href), content => { - saveAs(content, document.title + ".zip"); + saveAs(content, document.title.replace(/[\*\/:<>\?\\\|\r\n,]/g, "_") + ".zip"); }); } else { var blob = new Blob([i18n.info.replace("#t#", location.href) + "\r\n\r\n" + document.title + "\r\n\r\n" + rCats.join("\r\n\r\n")], {type: "text/plain;charset=utf-8"}); - saveAs(blob, document.title + ".txt"); + saveAs(blob, document.title.replace(/[\*\/:<>\?\\\|\r\n,]/g, "_") + ".txt"); } } @@ -843,7 +843,7 @@ if (window.top != window.self) { txt += '\n\n'+cat; }); var blob = new Blob([txt], {type: "text/plain;charset=utf-8"}); - saveAs(blob, document.title+".md"); + saveAs(blob, document.title.replace(/[\*\/:<>\?\\\|\r\n,]/g, "_") + ".md"); } } From e3824c324d9b317c33099c802e353623dafaa4cf Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 9 Jun 2024 09:09:34 +0800 Subject: [PATCH 0044/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 50f7cb53b55..1f8dd4f5cc7 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -342,7 +342,7 @@ switch (lang) { }, { "name": "一键抠图", - "url": "https://www.remove.bg/zh/upload#p{sleep(500)&body=%i}" + "url": "https://www.remove.bg/zh/upload#p{sleep(1000)&body=%i}" }, { "name": "WhatAnime", @@ -1287,7 +1287,7 @@ switch (lang) { }, { "name": "Remove bg", - "url": "https://www.remove.bg/upload#p{sleep(500)&body=%i}" + "url": "https://www.remove.bg/upload#p{sleep(1000)&body=%i}" }, { "name": "Google lens", From de7ea0c9a4bddd68a27d07c9267093a21155901f Mon Sep 17 00:00:00 2001 From: Lemonade <61580921+lemonadeforlife@users.noreply.github.com> Date: Mon, 10 Jun 2024 04:08:39 +0000 Subject: [PATCH 0045/1065] Fixed hover & thumbnail issue It seems like some of the items thumbnails not loading & hovering on those items should return a brief summary which is completely not showing. --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 27d5f7a46cf..c8236951708 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -7390,7 +7390,7 @@ "nextlink": "icon-top-ranking-page-bottom> .link-blue-box.next", "replaceElement": ".link-blue-box", "pageElement": ".top-ranking-table", - "action": 1 + "action": 2 }, { "name": "MAL - recommendations", From c224e137144f2b9635822902e547f6ff5d6251d4 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Mon, 10 Jun 2024 04:08:56 +0000 Subject: [PATCH 0046/1065] Update version of Pagetual rules to 27 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 6f4247a6255..f64f5d8d85a 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -26 +27 From 134b2b3bc7d25b3bd2ec3d4cf4d3d7a46280e0cc Mon Sep 17 00:00:00 2001 From: Lemonade <61580921+lemonadeforlife@users.noreply.github.com> Date: Mon, 10 Jun 2024 16:25:46 +0600 Subject: [PATCH 0047/1065] Added Linux Mint Forums --- Pagetual/pagetualRules.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index c8236951708..6999886d6a7 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -7420,5 +7420,14 @@ "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 } ] From 0c2782cf7f2cc22b71374cd7f54b2839c202c91f Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Mon, 10 Jun 2024 10:26:10 +0000 Subject: [PATCH 0048/1065] Update version of Pagetual rules to 28 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index f64f5d8d85a..9902f17848a 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -27 +28 From 1a132893f5b29227df89e623a95297ae834b9eab Mon Sep 17 00:00:00 2001 From: Prankster 199 <74471233+vfggf95565@users.noreply.github.com> Date: Tue, 11 Jun 2024 16:57:08 +0300 Subject: [PATCH 0049/1065] Update DownloadAllContent.user.js Adding Arabic translation for Arabic users. (There are a lot of users in Arabic) --- DownloadAllContent/DownloadAllContent.user.js | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index 64f9f092638..859ab603323 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -317,49 +317,49 @@ if (window.top != window.self) { downloadCustomShortcut:"自設下載" }; break; - default: - i18n={ - fetch:"Download", - info:"Source: #t#\nThe TXT is downloaded by 'DownloadAllContent'", - error:"Failed in downloading current chapter", - downloading:"%s pages are downloaded, there are still %s pages left
    Downloading %s ......", - complete:"Completed! Get %s pages in total", - del:"Set css selectors for ignore", - custom:"Custom to download", - customInfo:"Input urls OR sss selectors for chapter links", - reSort:"ReSort by title", - reSortUrl:"Resort by URLs", - setting:"Open Setting", - searchRule:"Search rule", - abort:"Abort", - save:"Save", - saveAsMd:"Save as Markdown", - downThreadNum:"Set threadNum for download", - customTitle: "Customize the chapter title, enter the selector on inner page", - reSortDefault: "Default sort by position in the page", - reverseOrder:"Reverse chapter ordering", - saveBtn:"Save Setting", - saveOk:"Save Over", - nextPage:"Check next page in chapter", - nextPageReg:"Custom RegExp of next page", - retainImage:"Keep the URL of image if there are images in the text", - minTxtLength:"Try to crawl again when the length of content is less than this", - showFilterList: "Show chapter filtering and sorting window before downloading", - ok:"OK", - close:"Close", - dacSortByPos:"Sort by position", - dacSortByUrl:"Sort by URL", - dacSortByName:"Sort by name", - reverse:"Reverse selection", - dacUseIframe: "Use iframe to load content (slow)", - dacSaveAsZip: "Save as zip", - dacSetCustomRule:"Modify rules", - dacAddUrl:"Add Chapter", - dacStartDownload:"Download selected", - downloadShortcut:"Download chapter", - downloadSingleShortcut:"Download single page", - downloadCustomShortcut:"Custom download" - }; +default: + i18n={ + fetch: "تحميل", + info: "المصدر: #t#\nتم تنزيل الـ TXT بواسطة 'DownloadAllContent'", + error: "فشل في تحميل الفصل الحالي", + downloading: "......%s تحميل
    صفحات متبقية %s صفحات تم تحميلها، هناك %s", + complete: "صفحات في المجموع %s اكتمل! حصلت على", + del: "لتجاهل CSS تعيين محددات", + custom: "تحميل مخصص", + customInfo: "لروابط الفصول sss إدخال الروابط أو محددات", + reSort: "إعادة الترتيب حسب العنوان", + reSortUrl: "إعادة الترتيب حسب الروابط", + setting: "فتح الإعدادات", + searchRule: "قاعدة البحث", + abort: "إيقاف", + save: "حفظ", + saveAsMd: "Markdown حفظ كـ", + downThreadNum: "تعيين عدد الخيوط للتحميل", + customTitle: "تخصيص عنوان الفصل، إدخال المحدد في الصفحة الداخلية", + reSortDefault: "الترتيب الافتراضي حسب الموقع في الصفحة", + reverseOrder: "عكس ترتيب الفصول", + saveBtn: "حفظ الإعدادات", + saveOk: "تم الحفظ", + nextPage: "التحقق من الصفحة التالية في الفصل", + nextPageReg: "مخصص للصفحة التالية RegExp", + retainImage: "الاحتفاظ بعنوان الصورة إذا كانت هناك صور في النص", + minTxtLength: "المحاولة مرة أخرى عندما يكون طول المحتوى أقل من هذا", + showFilterList: "عرض نافذة التصفية والترتيب قبل التحميل", + ok: "موافق", + close: "إغلاق", + dacSortByPos: "الترتيب حسب الموقع", + dacSortByUrl: "الترتيب حسب الرابط", + dacSortByName: "الترتيب حسب الاسم", + reverse: "عكس الاختيار", + dacUseIframe: "لتحميل المحتوى (بطيء) iframe استخدام", + dacSaveAsZip: "zip حفظ كـ", + dacSetCustomRule: "تعديل القواعد", + dacAddUrl: "إضافة فصل", + dacStartDownload: "تحميل المحدد", + downloadShortcut: "تحميل الفصل", + downloadSingleShortcut: "تحميل صفحة واحدة", + downloadCustomShortcut: "تحميل مخصص" + }; break; } var firefox=navigator.userAgent.toLowerCase().indexOf('firefox')!=-1,curRequests=[],useIframe=false,iframeSandbox=false,iframeInit=false; From 24d46a21cd79b4333448cefdf8b62d1ee14e333c Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 12 Jun 2024 08:16:08 +0800 Subject: [PATCH 0050/1065] Update DownloadAllContent.user.js --- DownloadAllContent/DownloadAllContent.user.js | 153 ++++++++++++------ 1 file changed, 107 insertions(+), 46 deletions(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index 859ab603323..5b2314a1959 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -272,6 +272,7 @@ if (window.top != window.self) { downloadCustomShortcut:"自定义下载" }; break; + case "zh": case "zh-TW": case "zh-HK": i18n={ @@ -317,49 +318,109 @@ if (window.top != window.self) { downloadCustomShortcut:"自設下載" }; break; -default: - i18n={ - fetch: "تحميل", - info: "المصدر: #t#\nتم تنزيل الـ TXT بواسطة 'DownloadAllContent'", - error: "فشل في تحميل الفصل الحالي", - downloading: "......%s تحميل
    صفحات متبقية %s صفحات تم تحميلها، هناك %s", - complete: "صفحات في المجموع %s اكتمل! حصلت على", - del: "لتجاهل CSS تعيين محددات", - custom: "تحميل مخصص", - customInfo: "لروابط الفصول sss إدخال الروابط أو محددات", - reSort: "إعادة الترتيب حسب العنوان", - reSortUrl: "إعادة الترتيب حسب الروابط", - setting: "فتح الإعدادات", - searchRule: "قاعدة البحث", - abort: "إيقاف", - save: "حفظ", - saveAsMd: "Markdown حفظ كـ", - downThreadNum: "تعيين عدد الخيوط للتحميل", - customTitle: "تخصيص عنوان الفصل، إدخال المحدد في الصفحة الداخلية", - reSortDefault: "الترتيب الافتراضي حسب الموقع في الصفحة", - reverseOrder: "عكس ترتيب الفصول", - saveBtn: "حفظ الإعدادات", - saveOk: "تم الحفظ", - nextPage: "التحقق من الصفحة التالية في الفصل", - nextPageReg: "مخصص للصفحة التالية RegExp", - retainImage: "الاحتفاظ بعنوان الصورة إذا كانت هناك صور في النص", - minTxtLength: "المحاولة مرة أخرى عندما يكون طول المحتوى أقل من هذا", - showFilterList: "عرض نافذة التصفية والترتيب قبل التحميل", - ok: "موافق", - close: "إغلاق", - dacSortByPos: "الترتيب حسب الموقع", - dacSortByUrl: "الترتيب حسب الرابط", - dacSortByName: "الترتيب حسب الاسم", - reverse: "عكس الاختيار", - dacUseIframe: "لتحميل المحتوى (بطيء) iframe استخدام", - dacSaveAsZip: "zip حفظ كـ", - dacSetCustomRule: "تعديل القواعد", - dacAddUrl: "إضافة فصل", - dacStartDownload: "تحميل المحدد", - downloadShortcut: "تحميل الفصل", - downloadSingleShortcut: "تحميل صفحة واحدة", - downloadCustomShortcut: "تحميل مخصص" - }; + 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={ + fetch: "تحميل", + info: "المصدر: #t#\nتم تنزيل الـ TXT بواسطة 'DownloadAllContent'", + error: "فشل في تحميل الفصل الحالي", + downloading: "......%s تحميل
    صفحات متبقية %s صفحات تم تحميلها، هناك %s", + complete: "صفحات في المجموع %s اكتمل! حصلت على", + del: "لتجاهل CSS تعيين محددات", + custom: "تحميل مخصص", + customInfo: "لروابط الفصول sss إدخال الروابط أو محددات", + reSort: "إعادة الترتيب حسب العنوان", + reSortUrl: "إعادة الترتيب حسب الروابط", + setting: "فتح الإعدادات", + searchRule: "قاعدة البحث", + abort: "إيقاف", + save: "حفظ", + saveAsMd: "Markdown حفظ كـ", + downThreadNum: "تعيين عدد الخيوط للتحميل", + customTitle: "تخصيص عنوان الفصل، إدخال المحدد في الصفحة الداخلية", + reSortDefault: "الترتيب الافتراضي حسب الموقع في الصفحة", + reverseOrder: "عكس ترتيب الفصول", + saveBtn: "حفظ الإعدادات", + saveOk: "تم الحفظ", + nextPage: "التحقق من الصفحة التالية في الفصل", + nextPageReg: "مخصص للصفحة التالية RegExp", + retainImage: "الاحتفاظ بعنوان الصورة إذا كانت هناك صور في النص", + minTxtLength: "المحاولة مرة أخرى عندما يكون طول المحتوى أقل من هذا", + showFilterList: "عرض نافذة التصفية والترتيب قبل التحميل", + ok: "موافق", + close: "إغلاق", + dacSortByPos: "الترتيب حسب الموقع", + dacSortByUrl: "الترتيب حسب الرابط", + dacSortByName: "الترتيب حسب الاسم", + reverse: "عكس الاختيار", + dacUseIframe: "لتحميل المحتوى (بطيء) iframe استخدام", + dacSaveAsZip: "zip حفظ كـ", + dacSetCustomRule: "تعديل القواعد", + dacAddUrl: "إضافة فصل", + dacStartDownload: "تحميل المحدد", + downloadShortcut: "تحميل الفصل", + downloadSingleShortcut: "تحميل صفحة واحدة", + downloadCustomShortcut: "تحميل مخصص" + }; + break; + default: + i18n={ + fetch:"Download", + info:"Source: #t#\nThe TXT is downloaded by 'DownloadAllContent'", + error:"Failed in downloading current chapter", + downloading:"%s pages are downloaded, there are still %s pages left
    Downloading %s ......", + complete:"Completed! Get %s pages in total", + del:"Set css selectors for ignore", + custom:"Custom to download", + customInfo:"Input urls OR sss selectors for chapter links", + reSort:"ReSort by title", + reSortUrl:"Resort by URLs", + setting:"Open Setting", + searchRule:"Search rule", + abort:"Abort", + save:"Save", + saveAsMd:"Save as Markdown", + downThreadNum:"Set threadNum for download", + customTitle: "Customize the chapter title, enter the selector on inner page", + reSortDefault: "Default sort by position in the page", + reverseOrder:"Reverse chapter ordering", + saveBtn:"Save Setting", + saveOk:"Save Over", + nextPage:"Check next page in chapter", + nextPageReg:"Custom RegExp of next page", + retainImage:"Keep the URL of image if there are images in the text", + minTxtLength:"Try to crawl again when the length of content is less than this", + showFilterList: "Show chapter filtering and sorting window before downloading", + ok:"OK", + close:"Close", + dacSortByPos:"Sort by position", + dacSortByUrl:"Sort by URL", + dacSortByName:"Sort by name", + reverse:"Reverse selection", + dacUseIframe: "Use iframe to load content (slow)", + dacSaveAsZip: "Save as zip", + dacSetCustomRule:"Modify rules", + dacAddUrl:"Add Chapter", + dacStartDownload:"Download selected", + downloadShortcut:"Download chapter", + downloadSingleShortcut:"Download single page", + downloadCustomShortcut:"Custom download" + }; break; } var firefox=navigator.userAgent.toLowerCase().indexOf('firefox')!=-1,curRequests=[],useIframe=false,iframeSandbox=false,iframeInit=false; @@ -458,14 +519,14 @@ default:
    -
    +
    -
    +

    @@ -473,7 +534,7 @@ default: -
    + `); let dacSortByPos = filterListContainer.querySelector("#dacSortByPos"); let dacSortByUrl = filterListContainer.querySelector("#dacSortByUrl"); From 39334f15cb56433785bf74af3501f25e1f4c8d96 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 12 Jun 2024 17:45:01 +0800 Subject: [PATCH 0051/1065] Update README.md --- Pagetual/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Pagetual/README.md b/Pagetual/README.md index 063538eacfa..338bc080943 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -51,6 +51,13 @@ https://raw.githubusercontent.com/hoothin/UserScripts/master/Pagetual/pagetualRu ] ``` +
    +

    Pagetual User-defined rules

    + TerenceCK
    + JPLiu
    + skofkyo +
    + name -- Name of the target site From 1db3ad972985153f032dd2763de992d317f663a5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 12 Jun 2024 20:26:56 +0800 Subject: [PATCH 0052/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 213 +++++++++++----------- 1 file changed, 110 insertions(+), 103 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 1f8dd4f5cc7..62921ea37d0 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -5,6 +5,45 @@ switch (lang) { case "zh-CN": case "zh-SG": sitesConfig = [ + { + "type": "搜索", + "icon": "search", + "description": "搜索引擎主分类", + "sites": [ + { + "name": "百度", + "url": "https://www.baidu.com/s?wd=%s&ie=utf-8", + "keywords": "(?:wd|word)=(.*?)(&|$)", + "match": "https?://(www|m)\\.baidu\\.com/.*(wd|word)=", + "shortcut": "KeyB", + "alt": true + }, + { + "name": "百度高级搜索", + "url": "https://www.baidu.com/s?wd=%s%input{请输入限制文件类型, filetype:doc/ filetype:ppt/ filetype:xls/ filetype:pdf}%input{请输入限制日期/过去一小时/过去一天/过去一周/过去一个月/过去一年,&gpc=stf%3D%date{/1000-3600}%2C%date{/1000}%7Cstftype%3D1/&gpc=stf%3D%date{/1000-86400}%2C%date{/1000}%7Cstftype%3D1/&gpc=stf%3D%date{/1000-604800}%2C%date{/1000}%7Cstftype%3D1/&gpc=stf%3D%date{/1000-2592000}%2C%date{/1000}%7Cstftype%3D1/&gpc=stf%3D%date{/1000-31536000}%2C%date{/1000}%7Cstftype%3D1}", + "match": "https://www\\.baidu\\.com/(s|baidu)", + "nobatch": true, + "hideNotMatch": true, + "openInNewTab": false + }, + { + "name": "必应", + "url": "https://www.bing.com/search?q=%s", + "match": "^https://(www|cn|global)\\.bing\\.com/search" + }, + { + "name": "360", + "url": "https://www.so.com/s?ie=utf-8&q=%s", + "match": "(www|m)\\.so\\.com/s\\?.*[&\\?]q=" + }, + { + "name": "搜狗", + "url": "https://www.sogou.com/web?query=%s", + "keywords": "(?:query|keyword)=(.*?)(&|$)", + "match": "(www|wap|m)\\.sogou\\.com/(web|web/searchList\\.jsp).*(query|keyword)=" + } + ] + }, { "type": "百科", "icon": "book-open-reader", @@ -96,45 +135,6 @@ switch (lang) { } ] }, - { - "type": "搜索", - "icon": "search", - "description": "搜索引擎主分类", - "sites": [ - { - "name": "百度", - "url": "https://www.baidu.com/s?wd=%s&ie=utf-8", - "keywords": "(?:wd|word)=(.*?)(&|$)", - "match": "https?://(www|m)\\.baidu\\.com/.*(wd|word)=", - "shortcut": "KeyB", - "alt": true - }, - { - "name": "百度高级搜索", - "url": "https://www.baidu.com/s?wd=%s%input{请输入限制文件类型, filetype:doc/ filetype:ppt/ filetype:xls/ filetype:pdf}%input{请输入限制日期/过去一小时/过去一天/过去一周/过去一个月/过去一年,&gpc=stf%3D%date{/1000-3600}%2C%date{/1000}%7Cstftype%3D1/&gpc=stf%3D%date{/1000-86400}%2C%date{/1000}%7Cstftype%3D1/&gpc=stf%3D%date{/1000-604800}%2C%date{/1000}%7Cstftype%3D1/&gpc=stf%3D%date{/1000-2592000}%2C%date{/1000}%7Cstftype%3D1/&gpc=stf%3D%date{/1000-31536000}%2C%date{/1000}%7Cstftype%3D1}", - "match": "https://www\\.baidu\\.com/(s|baidu)", - "nobatch": true, - "hideNotMatch": true, - "openInNewTab": false - }, - { - "name": "必应", - "url": "https://www.bing.com/search?q=%s", - "match": "^https://(www|cn|global)\\.bing\\.com/search" - }, - { - "name": "360", - "url": "https://www.so.com/s?ie=utf-8&q=%s", - "match": "(www|m)\\.so\\.com/s\\?.*[&\\?]q=" - }, - { - "name": "搜狗", - "url": "https://www.sogou.com/web?query=%s", - "keywords": "(?:query|keyword)=(.*?)(&|$)", - "match": "(www|wap|m)\\.sogou\\.com/(web|web/searchList\\.jsp).*(query|keyword)=" - } - ] - }, { "type": "词典", "icon": "language", @@ -773,6 +773,77 @@ switch (lang) { break; default: sitesConfig = [ + { + "type": "Search", + "icon": "search", + "sites": [ + { + "name": "Google", + "url": "https://www.google.com/search?q=%s&ie=utf-8&oe=utf-8", + "match": "https://www\\.google\\..*/search", + "charset": "utf-8", + "keywords": "textarea[name='q']", + "shortcut": "g", + "alt": true + }, + { + "name": "Google advanced", + "url": "https://www.google.com/search?q=%s%input{Filetype, filetype:doc/ filetype:ppt/ filetype:xls/ filetype:pdf}%input{Limit lang/zh-CN/zh-TW/zh-ALL/JA/EN,&lr=lang_zh-CN/&lr=lang_zh-TW/&lr=lang_zh-CN|lang_zh-TW/&lr=lang_ja/&lr=lang_en}%input{Limit date/Last hour/Last day/Last week/Last month/Last year,&as_qdr=h1/&as_qdr=d1/&as_qdr=w1/&as_qdr=m1/&as_qdr=y1}&ie=utf-8&oe=utf-8", + "match": "https://www\\.google\\..*/search", + "hideNotMatch": true + }, + { + "name": "SearX", + "url": "https://searx.be/search?q=%s" + }, + { + "name": "You", + "url": "https://you.com/search?q=%s", + "icon": "https://you.com/favicon/favicon-32x32.png" + }, + { + "name": "Bing", + "url": "https://www.bing.com/search?q=%s", + "match": "^https://(www|cn|global)\\.bing\\.com/search" + }, + { + "name": "DuckDuckGo", + "url": "https://duckduckgo.com/?q=%s" + }, + { + "name": "Yahoo", + "url": "https://search.yahoo.com/search;?p=%s" + }, + { + "name": "Yandex", + "url": "https://yandex.com/search/?text=%s" + }, + { + "name": "Baidu", + "url": "https://www.baidu.com/s?wd=%s&ie=utf-8", + "keywords": "(?:wd|word)=(.*?)(&|$)", + "match": "https?://(www|m)\\.baidu\\.com/.*(wd|word)=" + }, + { + "name": "Startpage", + "url": "https://www.startpage.com/sp/search?query=%s", + "icon": "https://www.startpage.com/sp/cdn/favicons/favicon-16x16--default.png" + }, + { + "name": "Qwant", + "url": "https://www.qwant.com/?q=%s" + }, + { + "name": "Ecosia", + "url": "https://www.ecosia.org/search?method=index&q=%s", + "icon": "https://cdn-static.ecosia.org/static/icons/favicon.ico" + }, + { + "name": "Brave", + "url": "https://search.brave.com/search?q=%s" + } + ] + }, { "type": "Image", "icon": "image", @@ -1008,70 +1079,6 @@ switch (lang) { } ] }, - { - "type": "Search", - "icon": "search", - "sites": [ - { - "name": "Google", - "url": "https://www.google.com/search?q=%s&ie=utf-8&oe=utf-8", - "match": "https://www\\.google\\..*/search", - "charset": "utf-8", - "keywords": "textarea[name='q']", - "shortcut": "g", - "alt": true - }, - { - "name": "Google advanced", - "url": "https://www.google.com/search?q=%s%input{Filetype, filetype:doc/ filetype:ppt/ filetype:xls/ filetype:pdf}%input{Limit lang/zh-CN/zh-TW/zh-ALL/JA/EN,&lr=lang_zh-CN/&lr=lang_zh-TW/&lr=lang_zh-CN|lang_zh-TW/&lr=lang_ja/&lr=lang_en}%input{Limit date/Last hour/Last day/Last week/Last month/Last year,&as_qdr=h1/&as_qdr=d1/&as_qdr=w1/&as_qdr=m1/&as_qdr=y1}&ie=utf-8&oe=utf-8", - "match": "https://www\\.google\\..*/search", - "hideNotMatch": true - }, - { - "name": "SearX", - "url": "https://searx.be/search?q=%s" - }, - { - "name": "You", - "url": "https://you.com/search?q=%s", - "icon": "https://you.com/favicon/favicon-32x32.png" - }, - { - "name": "Bing", - "url": "https://www.bing.com/search?q=%s" - }, - { - "name": "DuckDuckGo", - "url": "https://duckduckgo.com/?q=%s" - }, - { - "name": "Yahoo", - "url": "https://search.yahoo.com/search;?p=%s" - }, - { - "name": "Yandex", - "url": "https://yandex.com/search/?text=%s" - }, - { - "name": "Startpage", - "url": "https://www.startpage.com/sp/search?query=%s", - "icon": "https://www.startpage.com/sp/cdn/favicons/favicon-16x16--default.png" - }, - { - "name": "Qwant", - "url": "https://www.qwant.com/?q=%s" - }, - { - "name": "Ecosia", - "url": "https://www.ecosia.org/search?method=index&q=%s", - "icon": "https://cdn-static.ecosia.org/static/icons/favicon.ico" - }, - { - "name": "Brave", - "url": "https://search.brave.com/search?q=%s" - } - ] - }, { "type": "Search in page", "icon": "sitemap", From dd4fdfb977d73e885aee7f68669a7fdbedefdf7c Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 12 Jun 2024 21:14:28 +0800 Subject: [PATCH 0053/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 62921ea37d0..1ddd1e88773 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -113,8 +113,8 @@ switch (lang) { }, { "name": "谷歌图片", - "url": "https://www.google.com/search?q=%s&tbm=isch", - "match": "www\\.google\\..*tbm=isch" + "url": "https://www.google.com/search?q=%s&udm=2", + "match": "www\\.google\\..*udm=2" }, { "name": "图片聚合搜索", @@ -207,7 +207,7 @@ switch (lang) { "name": "Google", "url": "https://www.google.com/search?q=%s&ie=utf-8&oe=utf-8", "keywords": "textarea[name='q']", - "match": "https://www\\.google\\..*/search(?!.*tbm=isch)" + "match": "https://www\\.google\\..*/search((?!udm=2).)*$" }, { "name": "📄 复制", @@ -780,7 +780,7 @@ switch (lang) { { "name": "Google", "url": "https://www.google.com/search?q=%s&ie=utf-8&oe=utf-8", - "match": "https://www\\.google\\..*/search", + "match": "https://www\\.google\\..*/search((?!udm=2).)*$", "charset": "utf-8", "keywords": "textarea[name='q']", "shortcut": "g", @@ -789,7 +789,7 @@ switch (lang) { { "name": "Google advanced", "url": "https://www.google.com/search?q=%s%input{Filetype, filetype:doc/ filetype:ppt/ filetype:xls/ filetype:pdf}%input{Limit lang/zh-CN/zh-TW/zh-ALL/JA/EN,&lr=lang_zh-CN/&lr=lang_zh-TW/&lr=lang_zh-CN|lang_zh-TW/&lr=lang_ja/&lr=lang_en}%input{Limit date/Last hour/Last day/Last week/Last month/Last year,&as_qdr=h1/&as_qdr=d1/&as_qdr=w1/&as_qdr=m1/&as_qdr=y1}&ie=utf-8&oe=utf-8", - "match": "https://www\\.google\\..*/search", + "match": "https://www\\.google\\..*/search((?!udm=2).)*$", "hideNotMatch": true }, { @@ -850,8 +850,8 @@ switch (lang) { "sites": [ { "name": "Google image", - "url": "https://www.google.com/search?q=%s&tbm=isch", - "match": "www\\.google\\..*tbm=isch" + "url": "https://www.google.com/search?q=%s&udm=2", + "match": "www\\.google\\..*udm=2" }, { "name": "Bing image", From 8e55dd7f871d3b80feed05f4b09ab5b13018282f Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 13 Jun 2024 08:44:03 +0800 Subject: [PATCH 0054/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 12348163b06..76b4d2275b0 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.8.2 +// @version 2024.6.13.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 @@ -14339,7 +14339,7 @@ ImgOps | https://imgops.com/#b#`; }, }; - slideShow.setCountdown(slideShow.opts.interval);; + slideShow.setCountdown(slideShow.opts.interval); this.slideShow=slideShow; let filterIcon = container.querySelector(".pv-gallery-head-left-filter-icon"); @@ -14520,6 +14520,9 @@ ImgOps | https://imgops.com/#b#`; id: Math.random() }), onload: function(d) { + }, + onerror: function(e) { + self.showTips("Error! Check aria2 setting!", 1000); } }); }); @@ -15197,7 +15200,7 @@ ImgOps | https://imgops.com/#b#`; }; batchDlBtn.onclick=function(e){ checkBoxs=maximizeContainer.querySelectorAll(".maximizeChild>input:checked"); - if(checkBoxs.length<1)checkBoxs=maximizeContainer.querySelectorAll(".maximizeChild>input");; + if(checkBoxs.length<1)checkBoxs=maximizeContainer.querySelectorAll(".maximizeChild>input"); var saveParams = [],saveIndex=0; [].forEach.call(checkBoxs, function(node){ @@ -19048,6 +19051,7 @@ ImgOps | https://imgops.com/#b#`; border: 10px solid #272727;\ background: #ffffffee;\ color: black;\ + text-wrap: nowrap;\ }\ span.pv-gallery-urls-textarea-close,\ span.pv-gallery-urls-textarea-download{\ From acda12d3e63c571fa7b399c5240d0610de64ceec Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 13 Jun 2024 08:53:10 +0800 Subject: [PATCH 0055/1065] Update randomSexyPic.user.js --- RandomSexyPic/randomSexyPic.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RandomSexyPic/randomSexyPic.user.js b/RandomSexyPic/randomSexyPic.user.js index ae898f23e71..de65eb95786 100644 --- a/RandomSexyPic/randomSexyPic.user.js +++ b/RandomSexyPic/randomSexyPic.user.js @@ -79,7 +79,7 @@ if (window.top != window.self) { } }, "api.nyan.xyz":{ - hide: false, + hide: true, include: /httpapi\/sexphoto/i, name:"Nyan ACG SexyPic", url:"https://api.nyan.xyz/httpapi/sexphoto/?r18=true&num=10", From ff2e36b854274cfd5c8c41a4423646a4a538dac0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 13 Jun 2024 08:55:07 +0800 Subject: [PATCH 0056/1065] Update randomSexyPic.user.js --- RandomSexyPic/randomSexyPic.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RandomSexyPic/randomSexyPic.user.js b/RandomSexyPic/randomSexyPic.user.js index de65eb95786..5363f1e6792 100644 --- a/RandomSexyPic/randomSexyPic.user.js +++ b/RandomSexyPic/randomSexyPic.user.js @@ -6,7 +6,7 @@ // @version 1.3.19 // @description Random Sexy Pictures Parser // @description:zh-TW 隨機色圖 -// @description:ja Random Sexy Pictures Parser +// @description:ja ランダムセクシー画像パーサー // @author hoothin // @match https://api.lolicon.app/setu/v2* // @match https://api.nyan.xyz/httpapi/sexphoto* From 457121b50fc0ddaa95582dca2a209210edb9aeec Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 13 Jun 2024 09:13:34 +0800 Subject: [PATCH 0057/1065] Update randomSexyPic.user.js --- RandomSexyPic/randomSexyPic.user.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/RandomSexyPic/randomSexyPic.user.js b/RandomSexyPic/randomSexyPic.user.js index 5363f1e6792..fe168467cf7 100644 --- a/RandomSexyPic/randomSexyPic.user.js +++ b/RandomSexyPic/randomSexyPic.user.js @@ -122,11 +122,11 @@ if (window.top != window.self) { } }, "buyersShow":{ - include: /api\/(rand|tao|mjx1)/i, + include: /api\/(rand|tao|mjx1|taobaoBuyerShow)/i, name:"Taobao Buyers Show", urls:["https://api.uomg.com/api/rand.img3?format=json&num=15", - "https://api.vvhan.com/api/tao?type=json&num=15", - "https://www.hlapi.cn/api/mjx1?type=json&num=15"], + "https://api.suxun.site/api/tao?type=json&num=15", + "https://api.03c3.cn/api/taobaoBuyerShow?type=json&num=15"], run:()=>{ r18Check.style.display=sfwCheck.style.display=r18CheckLabel.style.display=sfwCheckLabel.style.display="none"; var searchNum=getSearchParam("num"); @@ -238,7 +238,9 @@ if (window.top != window.self) { "api.uomg.com":"buyersShow", "api.vvhan.com":"buyersShow", "www.hlapi.cn":"buyersShow", - "api.ghser.com":"buyersShow" + "api.ghser.com":"buyersShow", + "api.03c3.cn":"buyersShow", + "api.suxun.site":"buyersShow" }; var customRule=GM_getValue("RSPrules") || {}; var customRuleArr=[]; From 8a5580997e6f049fce337caa3c5c94ef036ce4b8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 13 Jun 2024 09:16:51 +0800 Subject: [PATCH 0058/1065] Update randomSexyPic.user.js --- RandomSexyPic/randomSexyPic.user.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/RandomSexyPic/randomSexyPic.user.js b/RandomSexyPic/randomSexyPic.user.js index fe168467cf7..a91bfa58143 100644 --- a/RandomSexyPic/randomSexyPic.user.js +++ b/RandomSexyPic/randomSexyPic.user.js @@ -177,16 +177,15 @@ if (window.top != window.self) { "3650000.xyz":{ include: /\/api\/\?type=json/i, name:"3650000", - url:"https://3650000.xyz/api/?type=json&mode=7&num=15", - luckyUrl:["https://3650000.xyz/api/?type=json&num=15", - "https://3650000.xyz/api/?type=json&mode=1&num=15", - "https://3650000.xyz/api/?type=json&mode=2&num=15", - "https://3650000.xyz/api/?type=json&mode=3&num=15", - "https://3650000.xyz/api/?type=json&mode=66&num=15", - "https://3650000.xyz/api/?type=json&mode=5&num=15", - "https://3650000.xyz/api/?type=json&mode=7&num=15", - "https://3650000.xyz/api/?type=json&mode=8&num=15", - "https://3650000.xyz/api/?type=json&mode=9&num=15"], + url:"https://3650000.xyz/api/?type=json&mode=7&num=6", + luckyUrl:["https://3650000.xyz/api/?type=json&num=6", + "https://3650000.xyz/api/?type=json&mode=1&num=6", + "https://3650000.xyz/api/?type=json&mode=2&num=6", + "https://3650000.xyz/api/?type=json&mode=3&num=6", + "https://3650000.xyz/api/?type=json&mode=5&num=6", + "https://3650000.xyz/api/?type=json&mode=7&num=6", + "https://3650000.xyz/api/?type=json&mode=8&num=6", + "https://3650000.xyz/api/?type=json&mode=9&num=6"], run:()=>{ r18Check.style.display=sfwCheck.style.display=r18CheckLabel.style.display=sfwCheckLabel.style.display="none"; var searchNum=getSearchParam("num"); From 9b5ba0978c943c87d0ffab649a32df263a4de0a0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 13 Jun 2024 09:25:06 +0800 Subject: [PATCH 0059/1065] Update randomSexyPic.user.js --- RandomSexyPic/randomSexyPic.user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RandomSexyPic/randomSexyPic.user.js b/RandomSexyPic/randomSexyPic.user.js index a91bfa58143..dd3d3ecce23 100644 --- a/RandomSexyPic/randomSexyPic.user.js +++ b/RandomSexyPic/randomSexyPic.user.js @@ -183,6 +183,7 @@ if (window.top != window.self) { "https://3650000.xyz/api/?type=json&mode=2&num=6", "https://3650000.xyz/api/?type=json&mode=3&num=6", "https://3650000.xyz/api/?type=json&mode=5&num=6", + "https://3650000.xyz/api/?type=json&mode=6&num=6", "https://3650000.xyz/api/?type=json&mode=7&num=6", "https://3650000.xyz/api/?type=json&mode=8&num=6", "https://3650000.xyz/api/?type=json&mode=9&num=6"], @@ -215,8 +216,8 @@ if (window.top != window.self) { ["Weibo","1"], ["Instagram","2"], ["Cosplay","3"], - ["Nsfw","66"], ["Mtcos","5"], + ["Mtcos2","6"], ["Legs","7"], ["MoreCoser","8"], ["Tuwan","9"] From 6547fd0e7745c3d612c64b2f5683016fa3367bbc Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 13 Jun 2024 15:36:03 +0800 Subject: [PATCH 0060/1065] 1.9.37.54 --- Pagetual/README.md | 4 ++-- Pagetual/pagetual.user.js | 14 +++++++++----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 338bc080943..1cd01c15a9e 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.53](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.54](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* @@ -52,7 +52,7 @@ https://raw.githubusercontent.com/hoothin/UserScripts/master/Pagetual/pagetualRu ```
    -

    Pagetual User-defined rules

    +

    Pagetual User-defined rules cases

    TerenceCK
    JPLiu
    skofkyo diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 2a2bfc6e8d3..8e7374e0b17 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.53 +// @version 1.9.37.54 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -2192,12 +2192,15 @@ ele = img; } } - self.curSiteRule.pageElement = geneSelector(ele); let childrenEnd = self.checkTargetChildren(ele, curWin, articleNum, curHeight); if (childrenEnd) { - self.curSiteRule.pageElement += childrenEnd; + self.curSiteRule.pageElement = geneSelector(ele) + childrenEnd; ele = ele.children; } else { + if (ele.scrollHeight === 0 && ele.parentNode.children.length === 1) { + ele = ele.parentNode; + } + self.curSiteRule.pageElement = geneSelector(ele); ele = [ele]; } debug(self.curSiteRule.pageElement, 'Page element'); @@ -2209,6 +2212,7 @@ while (posEle && !posEle.offsetParent) { posEle = posEle.previousElementSibling || posEle.parentNode; } + if (posEle && posEle.scrollHeight === 0 && posEle.lastElementChild) posEle = posEle.lastElementChild; let lastBottom = forceState !== 2 && forceState !== 3 && posEle && getElementBottom(posEle); if (lastBottom && getElementTop(self.initNext) - lastBottom > 1000) { debug("Stop as too long between next & page element, try to enable Force-Join mode."); @@ -5048,7 +5052,7 @@ delete this.editTemp.type; delete this.editTemp.updatedAt; } - if (this.selectorInput.value && !this.frame.classList.contains("showDetail")) { + if (this.selectorInput.value && (!this.frame.classList.contains("showDetail") || !this.editTemp || !this.editTemp.pageElement)) { if (this.foundEle && this.foundEle.length === 1) { let foundEleRect = this.foundEle[0].getBoundingClientRect(); if (foundEleRect.height < 100) { @@ -5109,7 +5113,7 @@ } fillTempRuleTextarea() { - if (!this.frame.classList.contains("showDetail")) this.tempRule.value = JSON.stringify(this.getTempRule(), null, 4); + if (!this.frame.classList.contains("showDetail") || !this.editTemp || !this.editTemp.pageElement) this.tempRule.value = JSON.stringify(this.getTempRule(), null, 4); } setSelectorDiv(selector) { From 65ad855c46e9865c6d575e48f7088ec0e45ce478 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 13 Jun 2024 16:30:23 +0800 Subject: [PATCH 0061/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 1ddd1e88773..51f9ef03f07 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -555,11 +555,6 @@ switch (lang) { "name": "SEO查询", "url": "http://seo.chinaz.com/?q=%h" }, - { - "name": "自动下载到百度网盘", - "url": "https://pan.baidu.com/disk/main#p{click([data-id\\=downloadLink])&div.nd-download-link div[role\\=dialog] input=%t&click(.nd-download-link button.u-button--primary)}", - "icon": "https://nd-static.bdstatic.com/m-static/v20-main/favicon-main.ico" - }, { "name": "编辑当前网页", "url": "javascript:(function(){document.body.setAttribute('contenteditable', 'true');alert('已开启网页编辑,按ESC键取消');document.onkeydown = function (e) {e = e || window.event;if(e.keyCode==27){document.body.setAttribute('contenteditable', 'false');}}})();", @@ -573,6 +568,10 @@ switch (lang) { "description": "去除网页右键以及复制限制", "nobatch": true }, + { + "name": "🔗 链接预览", + "url": "showTips:\n\n" + }, { "name": "打开链接", "url": "%t", @@ -586,8 +585,9 @@ switch (lang) { "icon": "https://hoothin.com/qrcode/favicon.svg" }, { - "name": "🔗 链接预览", - "url": "showTips:\n\n" + "name": "自动下载到百度网盘", + "url": "https://pan.baidu.com/disk/main#p{click([data-id\\=downloadLink])&div.nd-download-link div[role\\=dialog] input=%t&click(.nd-download-link button.u-button--primary)}", + "icon": "https://nd-static.bdstatic.com/m-static/v20-main/favicon-main.ico" }, { "name": "短网址生成", From f43ba2897db4f10a0209b9af6e705fec87716214 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 14 Jun 2024 13:27:07 +0800 Subject: [PATCH 0062/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 43 ++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 51f9ef03f07..d46e094114a 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -730,10 +730,21 @@ switch (lang) { { "type": "AI", "icon": "robot", + "selectTxt": true, + "openInNewTab": 1, "sites": [ + { + "name": "解释以下内容-秘塔", + "url": "https://metaso.cn/#p{textarea.search-consult-textarea=请解释以下内容\n`%s`&click(button.send-arrow-button)}" + }, + { + "name": "解释以下内容-Gemini", + "url": "https://gemini.google.com/app#p{.ql-editor.textarea=请解释以下内容\n`%s`} ", + "icon": "https://www.gstatic.com/lamda/images/favicon_v1_150160cddff7f294ce30.svg" + }, { "name": "Bard", - "url": "https://bard.google.com/chat#p{.ql-editor.textarea=%s}", + "url": "https://gemini.google.com/app#p{.ql-editor.textarea=%s}", "icon": "https://www.gstatic.com/lamda/images/favicon_v1_150160cddff7f294ce30.svg" }, { @@ -1358,6 +1369,36 @@ switch (lang) { } ] }, + { + "type": "AI", + "icon": "robot", + "selectTxt": true, + "openInNewTab": 1, + "sites": [ + { + "name": "Explain the following-Gemini", + "url": "https://gemini.google.com/app#p{.ql-editor.textarea=Explain the following content please\n`%s`} ", + "icon": "https://www.gstatic.com/lamda/images/favicon_v1_150160cddff7f294ce30.svg" + }, + { + "name": "Bard", + "url": "https://gemini.google.com/app#p{.ql-editor.textarea=%s}", + "icon": "https://www.gstatic.com/lamda/images/favicon_v1_150160cddff7f294ce30.svg" + }, + { + "name": "Poe - Sage AI Chat", + "url": "https://poe.com/#p{sleep(2000)&[class*\\=ChatMessageInputContainer]>textarea=%s&click([class*\\=ChatMessageSendButton])}" + }, + { + "name": "ChatGPT", + "url": "https://chat.openai.com/#p{#prompt-textarea=%s&click(#prompt-textarea+button)}" + }, + { + "name": "Futurepedia - Find The Best AI Tools & Software", + "url": "https://www.futurepedia.io/#p{input[name\\=q]=%s&click(button[type\\=submit]:not([disabled]))}" + } + ] + }, { "type": "Assit", "icon": "list-alt", From 50a028b96fae33d536c37a8ce45d5258240737c7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 14 Jun 2024 14:27:12 +0800 Subject: [PATCH 0063/1065] 1.9.37.55 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 1cd01c15a9e..f79deadff05 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.54](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.55](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 8e7374e0b17..edb76842963 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.54 +// @version 1.9.37.55 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -2126,7 +2126,12 @@ } } if (h < minHeight) { - if (!needCheckNext || h < (windowHeight>>1) || !ele.contains(self.initNext)) { + if (!needCheckNext || h < (windowHeight>>1)) { + continue; + } + if (!ele.contains(self.initNext)) { + continue; + } else if (!curNode.contains(self.initNext) && h < curHeight >> 1) { continue; } } From c2cca9dd1ea3d3291359bb07f9ea2d703e1bde85 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 14 Jun 2024 16:30:07 +0800 Subject: [PATCH 0064/1065] Update custom-rule-request.md --- .github/ISSUE_TEMPLATE/custom-rule-request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/custom-rule-request.md b/.github/ISSUE_TEMPLATE/custom-rule-request.md index f5e42694275..9df3934ffc5 100644 --- a/.github/ISSUE_TEMPLATE/custom-rule-request.md +++ b/.github/ISSUE_TEMPLATE/custom-rule-request.md @@ -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**. **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 [...] From 79bac5d0a374a203bbac544b2ee07d72637f1d72 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 14 Jun 2024 16:31:19 +0800 Subject: [PATCH 0065/1065] Update custom-rule-request.md --- .github/ISSUE_TEMPLATE/custom-rule-request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/custom-rule-request.md b/.github/ISSUE_TEMPLATE/custom-rule-request.md index 9df3934ffc5..9b01bbbcd9e 100644 --- a/.github/ISSUE_TEMPLATE/custom-rule-request.md +++ b/.github/ISSUE_TEMPLATE/custom-rule-request.md @@ -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⚠. **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 [...] From c6065914fa90361249aecf61f996ea8d1cb651ce Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 14 Jun 2024 17:03:36 +0800 Subject: [PATCH 0066/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index edb76842963..cd0f5645d4e 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -1053,7 +1053,8 @@ } function getElementByXpath(xpath, doc, contextNode) { - doc = doc || document; + if (doc && doc.ownerDocument) doc = doc.ownerDocument; + doc = (doc && doc.evaluate) ? doc : document; contextNode = contextNode || doc; try { let result = doc.evaluate(xpath, contextNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); @@ -1065,7 +1066,8 @@ } function getAllElementsByXpath(xpath, contextNode, doc) { - doc = doc || document; + if (doc && doc.ownerDocument) doc = doc.ownerDocument; + doc = (doc && doc.evaluate) ? doc : document; contextNode = contextNode || doc; var result = []; try { @@ -2398,7 +2400,7 @@ for (let i = 0; i < list.length; i++) { await sleep(1); let sel = list[i]; - let result = source.querySelectorAll(sel); + let result = getAllElements(sel, source); if (result.length > 0) { if (defaultView) { for (let i = result.length - 1; i >= 0; i--) { @@ -2523,7 +2525,9 @@ "[class*=pagination-next]>button", "[class*=page--current]+li>a", "[class*=Pages]>.curr+a", - ".page>em+a" + ".page>em+a", + '//button[contains(@class, "Page")][text()="Next"]', + '//button[contains(@class, "page")][text()="next"]' ]; let next = await this.querySelectorList(body, selectorList, doc.defaultView); if (!next) { @@ -8925,7 +8929,7 @@ if (curPage === 1) { if (ruleParser.curSiteRule.pinUrl) { setTimeout(() => {isLoading = false;}, 500); - } else if (tryTimes++ < 3) { + } else if (tryTimes++ < 5) { setTimeout(() => {isLoading = false;}, 1000); } else { ruleParser.findNoNext(); From 12f9c6177679d2213f89887852de97ecff21c068 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 14 Jun 2024 17:46:46 +0800 Subject: [PATCH 0067/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index cd0f5645d4e..41141982061 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2221,7 +2221,7 @@ } if (posEle && posEle.scrollHeight === 0 && posEle.lastElementChild) posEle = posEle.lastElementChild; let lastBottom = forceState !== 2 && forceState !== 3 && posEle && getElementBottom(posEle); - if (lastBottom && getElementTop(self.initNext) - lastBottom > 1000) { + if (doc === document && lastBottom && getElementTop(self.initNext) - lastBottom > 1000) { debug("Stop as too long between next & page element, try to enable Force-Join mode."); isPause = true; pageElement = []; From 2b1e568fb515b75eefe82271e8b2e3fd453ad2c5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 14 Jun 2024 17:49:01 +0800 Subject: [PATCH 0068/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 41141982061..426766efc50 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2214,14 +2214,14 @@ return ele; } pageElement = checkElement(body); - if (pageElement && pageElement.length > 0 && self.initNext) { + if (doc === document && pageElement && pageElement.length > 0 && self.initNext) { let posEle = pageElement[pageElement.length - 1]; while (posEle && !posEle.offsetParent) { posEle = posEle.previousElementSibling || posEle.parentNode; } if (posEle && posEle.scrollHeight === 0 && posEle.lastElementChild) posEle = posEle.lastElementChild; let lastBottom = forceState !== 2 && forceState !== 3 && posEle && getElementBottom(posEle); - if (doc === document && lastBottom && getElementTop(self.initNext) - lastBottom > 1000) { + if (lastBottom && getElementTop(self.initNext) - lastBottom > 1000) { debug("Stop as too long between next & page element, try to enable Force-Join mode."); isPause = true; pageElement = []; From d886ddb633d7028d58a09ca018af0c5691c4dafc Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 14 Jun 2024 18:14:55 +0800 Subject: [PATCH 0069/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index d46e094114a..e42ce972c97 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -570,7 +570,8 @@ switch (lang) { }, { "name": "🔗 链接预览", - "url": "showTips:\n\n" + "url": "showTips:\n\n", + "description": "需要配合扩展“Ignore X-Frame headers”使用" }, { "name": "打开链接", @@ -1198,7 +1199,7 @@ switch (lang) { }, { "name": "🔗 Preview link", - "url": "showTips:\n\n" + "url": "showTips:\n\n" }, { "name": "Copy target svg to base64", From c9f558f707f94d5a821a57aa5cb4000ef824829f Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 15 Jun 2024 01:57:42 +0000 Subject: [PATCH 0070/1065] Update items_all.json from http://wedata.net/databases/AutoPagerize/items_all.json --- Pagetual/items_all.json | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/Pagetual/items_all.json b/Pagetual/items_all.json index 48a56ea1815..c7696b00892 100644 --- a/Pagetual/items_all.json +++ b/Pagetual/items_all.json @@ -1,4 +1,19 @@ [ +{ + "resource_url": "http://wedata.net/items/86233", + "data": { + "insertBefore": "", + "pageElement": "//div[contains(concat(' ', @class, ' '), ' browsetableinside ')]/ul", + "nextLink": "//a[contains(@class, 'active')][number()>0]/following-sibling::a[1]", + "url": "^https://xxxclub\\.(cc|to)/", + "exampleUrl": "https://xxxclub.cc/torrents/browse/0/\r\nhttps://xxxclub.to/torrents/browse/1/" + }, + "database_resource_url": "http://wedata.net/databases/AutoPagerize", + "created_by": "Griever3", + "name": "XXXClub", + "created_at": "2024-06-14T19:18:16+09:00", + "updated_at": "2024-06-14T19:18:16+09:00" +}, { "resource_url": "http://wedata.net/items/86231", "data": { @@ -10230,18 +10245,17 @@ }, { "resource_url": "http://wedata.net/items/82190", - "name": "FRaU", - "created_by": "t_f_m", - "database_resource_url": "http://wedata.net/databases/AutoPagerize", - "updated_at": "2019-06-24T20:28:25+09:00", "data": { - "exampleUrl": "https://gendai.ismedia.jp/articles/-/65430", - "url": "^https://gendai\\.ismedia\\.jp/articles/-/", "pageElement": "//div[@class=\"articleBody\"]", - "insertBefore": "", - "nextLink": "//div[@class=\"nextpageTitle\"]/a" + "nextLink": "//div[@class=\"nextpageTitle\"]/a", + "url": "^https://gendai\\.media/articles/-/", + "exampleUrl": "https://gendai.media/articles/-/65430" }, - "created_at": "2019-06-24T20:28:25+09:00" + "database_resource_url": "http://wedata.net/databases/AutoPagerize", + "created_by": "t_f_m", + "name": "FRaU", + "created_at": "2019-06-24T20:28:25+09:00", + "updated_at": "2024-06-15T08:37:58+09:00" }, { "data": { From cc52e74d20a7769a11d42250690f583144f4981a Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 15 Jun 2024 01:58:03 +0000 Subject: [PATCH 0071/1065] Update version of Pagetual rules to 29 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 9902f17848a..f04c001f3f7 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -28 +29 From 9b3e9bdf5fa33edb91f6b9d8c19b43c72ba9e247 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 15 Jun 2024 12:17:23 +0800 Subject: [PATCH 0072/1065] 1.9.37.56 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index f79deadff05..01f838461f2 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.55](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.56](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 426766efc50..f1b49ebf2a8 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.55 +// @version 1.9.37.56 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -1978,10 +1978,14 @@ } } if (this.curSiteRule.smart && pageElement && pageElement.length && curWin && curWin !== _unsafeWindow) { - let parent = pageElement[0].parentNode; - let loading = parent.querySelector('[class*=loading]'); - if (loading && loading.offsetParent && loading.offsetHeight > parent.offsetHeight>>2) { + if (pageElement.length === 1 && !pageElement[0].src && pageElement[0].innerHTML.trim() === "") { pageElement = null; + } else { + let parent = pageElement[0].parentNode; + let loading = parent.querySelector('[class*=loading]'); + if (loading && loading.offsetParent && loading.offsetHeight > parent.offsetHeight>>2) { + pageElement = null; + } } } } From 8bb05b8612a97db246c8a535f69b4a81d552c40e Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 15 Jun 2024 16:29:57 +0800 Subject: [PATCH 0073/1065] Update README.md --- Picviewer CE+/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index e2973b1381c..ee3c9d4b92a 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -1,4 +1,4 @@ -# 🏞️ Picviewer CE+ +# 🏞️ Picviewer CE+ ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) > Zoom images across all your favorite websites. Pop up, scale, edit, rotate, batch save images, or automatically load pictures from subsequent pages. Simply hover your mouse over any image and click the icons on the float bar. From b39546552fb04d8b117a6e42812aadc5676aca2b Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 15 Jun 2024 16:31:35 +0800 Subject: [PATCH 0074/1065] Update README.md --- DownloadAllContent/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DownloadAllContent/README.md b/DownloadAllContent/README.md index aaf608cc728..958b66c7fed 100644 --- a/DownloadAllContent/README.md +++ b/DownloadAllContent/README.md @@ -7,7 +7,7 @@ 腳本會自動檢索頁面中的主要內容並下載(省得複製完gal攻略還要手動逐條刪除「某某某13級頭銜水龍王發表於X年X月X日來自XX客戶端」)。 如果位於小說目錄頁會遍歷所有章節並排序拼接後存為TXT文檔。 -[![img](https://img.shields.io/github/stars/hoothin/UserScripts?style=social)](https://github.com/hoothin/UserScripts) +[![img](https://img.shields.io/github/stars/hoothin/UserScripts?style=social)](https://github.com/hoothin/UserScripts#StarMe) ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) --- From e54c2226e857d6f29c5053ee2b533f32c8de28c6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 15 Jun 2024 19:29:27 +0800 Subject: [PATCH 0075/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 6999886d6a7..1ef9e45b0f1 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5473,7 +5473,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", From b1fa3f714c135165d91094f3e9d60cbc10500905 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 15 Jun 2024 11:29:54 +0000 Subject: [PATCH 0076/1065] Update version of Pagetual rules to 30 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index f04c001f3f7..64bb6b746dc 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -29 +30 From ba15c2f280f403ec6ec5cdec8743ebe5cecac534 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 15 Jun 2024 20:42:33 +0800 Subject: [PATCH 0077/1065] 1.9.37.57 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 01f838461f2..7574543036b 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.56](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.57](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index f1b49ebf2a8..cb3e25dfa76 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.56 +// @version 1.9.37.57 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -2641,7 +2641,7 @@ } if (!this.verifyElement(aTag)) continue; if (aTag.dataset && aTag.dataset.preview) continue; - let availableHref = aTag.href && aTag.href.length < 250 && /^http/.test(aTag.href); + let availableHref = aTag.href && aTag.href.length < 250 && !/^(javascript:|#)/.test(aTag.href); if (availableHref && /next\-?(page)?$|\/video\/|\/vod\/play\//i.test(aTag.href)) continue; if (compareNodeName(aTag.parentNode, ["blockquote"])) continue; if (aTag.previousElementSibling && /\b(play|volume)\b/.test(aTag.previousElementSibling.className)) continue; @@ -2690,8 +2690,9 @@ } if (urlWillChange) continue; if (!next4 && availableHref) { - if (aTag.href.indexOf(location.hostname) === -1) continue; - let _aHref = aTag.href.replace("?&", "?").replace("index.php?", "?").toLowerCase(); + let aHref = aTag.href.indexOf("http") === 0 ? aTag.href : this.canonicalUri(aTag.href); + if (aHref.indexOf(location.hostname) === -1) continue; + let _aHref = aHref.replace("?&", "?").replace("index.php?", "?"); if (preStr || afterStr) { let _aHrefTrim = _aHref; if (preStr) _aHrefTrim = _aHrefTrim.replace(preStr, ""); @@ -2699,8 +2700,8 @@ if (_aHrefTrim == pageNum + 1) { next4 = aTag; } - } else if (this.curUrl !== aTag.href) { - _aHref = _aHref.replace(/\.s?html?$/i, ""); + } else if (this.curUrl !== aHref) { + _aHref = _aHref.replace(/\.s?html?$/i, "").toLowerCase(); if (_aHref.indexOf(_url) !== -1) { let pageTwoMatch = _aHref.replace(_url, "").match(pageTwoReg); if (pageTwoMatch) { From 076cf6021668119f8bff7ff50a4eba183c31b2b6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 16 Jun 2024 09:06:32 +0800 Subject: [PATCH 0078/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 76b4d2275b0..02ed3f7c15b 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.13.1 +// @version 2024.6.16.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 @@ -16434,7 +16434,7 @@ ImgOps | https://imgops.com/#b#`; var img=this.img; - if(!img || !img.classList)return; + if(!img || !img.classList || !img.parentNode)return; img.classList.remove('pv-gallery-img_zoom-in'); img.classList.remove('pv-gallery-img_zoom-out'); @@ -17520,10 +17520,21 @@ ImgOps | https://imgops.com/#b#`; } else if (/^svg$/i.test(node.nodeName)) { if (node.clientHeight != 0 && (!node.classList || !node.classList.contains("pagetual"))) { try { - const xml = new XMLSerializer().serializeToString(node); - const ImgBase64 = `data:image/svg+xml;base64,${window.btoa(unescape(encodeURIComponent(xml)))}`; - node.src = ImgBase64; - total.push(node); + let images = node.querySelectorAll('image'); + if (images.length) { + arrayFn.forEach.call(images, function(image){ + let src = image.href && image.href.baseVal; + if (src) { + image.src = canonicalUri(src, image.ownerDocument.URL, image.ownerDocument.baseURI); + total.push(image); + } + }); + } else { + const xml = new XMLSerializer().serializeToString(node); + const ImgBase64 = `data:image/svg+xml;base64,${window.btoa(unescape(encodeURIComponent(xml)))}`; + node.src = ImgBase64; + total.push(node); + } } catch(e) { debug(e); } From cd3a0c61e2095e80bcb2383fe9b31a79b05c9789 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 16 Jun 2024 10:57:41 +0800 Subject: [PATCH 0079/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 33 +++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 02ed3f7c15b..7db214f74d5 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.16.1 +// @version 2024.6.16.2 // @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 @@ -24271,6 +24271,7 @@ ImgOps | https://imgops.com/#b#`; }; } } else if (target.nodeName.toUpperCase() != 'IMG') { + let found = false; if (target.nodeName.toUpperCase() == "AREA") target = target.parentNode; var broEle, broImg; if (target.nodeName.toUpperCase() != 'A' && target.parentNode && target.parentNode.style && !/flex|grid|table/.test(getComputedStyle(target.parentNode).display)) { @@ -24302,8 +24303,10 @@ ImgOps | https://imgops.com/#b#`; noActual:noActual, img: target }; + found = true; } else if (broImg) { target = broImg; + found = true; } else if (target.nodeName.toUpperCase() == 'CANVAS') { let src = target.src || target.dataset.src; if (src) { @@ -24315,9 +24318,11 @@ ImgOps | https://imgops.com/#b#`; noActual:noActual, img: target }; + found = true; } } else if (target.children.length == 1 && target.children[0].nodeName == "IMG") { target = target.children[0]; + found = true; } else if (prefs.floatBar.listenBg && broEle && hasBg(broEle)) { let src = targetBg, nsrc = src, noActual = true, type = "scale"; result = { @@ -24327,6 +24332,7 @@ ImgOps | https://imgops.com/#b#`; noActual:noActual, img: target }; + found = true; } else if (target.parentNode) { let imgs; if (target.nodeName == 'A') { @@ -24334,8 +24340,10 @@ ImgOps | https://imgops.com/#b#`; } if (imgs && imgs.length == 1) { target = imgs[0]; + found = true; } else if (target.parentNode.nodeName.toUpperCase() == 'IMG') { target = target.parentNode; + found = true; } else if (prefs.floatBar.listenBg && hasBg(target.parentNode)) { target = target.parentNode; let src = targetBg, nsrc = src, noActual = true, type = "scale"; @@ -24346,14 +24354,16 @@ ImgOps | https://imgops.com/#b#`; noActual:noActual, img: target }; + found = true; } } - if (!result) { + if (!found) { let checkEle = target; while(checkEle && checkEle.children.length === 1) { checkEle = checkEle.children[0]; if (checkEle.nodeName === "IMG") { target = checkEle; + found = true; break; } else if (prefs.floatBar.listenBg && hasBg(checkEle)) { let src = targetBg, nsrc = src, noActual = true, type = "scale"; @@ -24364,11 +24374,24 @@ ImgOps | https://imgops.com/#b#`; noActual:noActual, img: checkEle }; + found = true; break; } } } - if (!result && document.elementsFromPoint) { + if (!found && target.children && target.children[0] && target.children[0].nodeName.toUpperCase() == 'IMG') { + let img = target.children[0]; + while (img.nextElementSibling && img.nextElementSibling.nodeName.toUpperCase() == 'IMG') { + img = img.nextElementSibling; + } + let rect = img.getBoundingClientRect(); + + if (clientY >= rect.top && clientY <= rect.bottom && clientX >= rect.left && clientX <= rect.right) { + target = img; + found = true; + } + } + if (!found && document.elementsFromPoint) { let elements = document.elementsFromPoint(clientX, clientY); let checkLen = Math.min(elements.length, 5); for (let i = 0; i < checkLen; i++) { @@ -24377,6 +24400,7 @@ ImgOps | https://imgops.com/#b#`; if (/img/i.test(ele.nodeName)) { target = ele; result = null; + found = true; break; } else if (prefs.floatBar.listenBg && hasBg(ele)) { target = ele; @@ -24388,11 +24412,12 @@ ImgOps | https://imgops.com/#b#`; noActual:noActual, img: target }; + found = true; break; } } } - if (!result && target.shadowRoot) { + if (!found && target.shadowRoot) { let imgs = target.shadowRoot.querySelectorAll('img'); if (imgs.length === 1) target = imgs[0]; } From 5027ee2f2cdc5366b75683be7bc2dbe019ea471e Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 16 Jun 2024 11:00:09 +0800 Subject: [PATCH 0080/1065] Update custom-rule-request.md --- .github/ISSUE_TEMPLATE/custom-rule-request.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/custom-rule-request.md b/.github/ISSUE_TEMPLATE/custom-rule-request.md index 9b01bbbcd9e..0ceb38d2984 100644 --- a/.github/ISSUE_TEMPLATE/custom-rule-request.md +++ b/.github/ISSUE_TEMPLATE/custom-rule-request.md @@ -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**⚠. **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 [...] From 3cd1ae9f80d46d87b53d3eee50edd504b43a2328 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 17 Jun 2024 16:35:01 +0800 Subject: [PATCH 0081/1065] 1.9.37.58 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 126 +++++++++++++++++++++++++++++++++++++- 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 7574543036b..ac3ff1c59b5 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.57](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.58](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index cb3e25dfa76..f2e20a11302 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.57 +// @version 1.9.37.58 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -234,6 +234,130 @@ lastPageTips: "Show tips when reaching the last page" } }, + { + //Translated by SrKalopsia (srkalopsia@gmail.com). + name: "Español", + match: ["es", "es-ES"], + lang: { + enableDebug: "Habilitar salida de depuración", + updateNotification: "Notificación después de actualizar las reglas", + disable: "Desactivar", + disableSite: "Alternar estado desactivado", + disableSiteTips: "Desactivado en este sitio", + enableSiteTips: "Activado en este sitio", + enable: "Habilitar", + toTop: "Ir al inicio", + toBottom: "Ir al final", + current: "Página actual", + forceIframe: "Forzar para unirse a la siguiente página", + cancelForceIframe: "Cancelar unión forzada", + configure: "Configurar", + firstUpdate: "Haga clic aquí para inicializar las reglas", + update: "Actualizar reglas en línea", + click2update: "Haga clic para actualizar las reglas desde la URL ahora", + loadNow: "Cargar el siguiente automáticamente", + loadConfirm: "¿Cuántas páginas desea cargar? (0 significa infinito)", + noNext: "No se encontró el enlace siguiente, por favor cree una nueva regla", + passSec: "Actualizado hace #t# segundos", + passMin: "Actualizado hace #t# minutos", + passHour: "Actualizado hace #t# horas", + passDay: "Actualizado hace #t# días", + cantDel: "No se pueden eliminar las reglas incorporadas", + confirmDel: "¿Está seguro de que desea eliminar esta regla?", + updateSucc: "Actualización exitosa", + beginUpdate: "Comenzar actualización, espere un momento por favor", + customUrls: "Importar URL de reglas de Pagetual o AutoPagerize, una URL por línea", + customRules: "Introduzca reglas personalizadas. ✍️Contribuir reglas", + save: "Guardar", + loadingText: "Shojo Cargando...", + opacity: "Opacidad", + opacityPlaceholder: "0: ocultar espaciador", + hideBar: "Ocultar el espaciador de paginación", + hideBarButNoStop: "Ocultar pero no detener", + dbClick2Stop: "Haga doble clic en el espacio en blanco para pausar", + sortTitle: "La ordenación surtirá efecto después de la próxima actualización de reglas", + autoRun: "Habilitar automáticamente (modo lista negra)", + autoLoadNum: "Cantidad de páginas para precargar", + turnRate: "Pasar a la siguiente página cuando esté a menos de 【X】 veces la altura de la página desde el pie de página", + inputPageNum: "Ingrese el número de página para saltar", + enableHistory: "Escribir historial de navegación después de pasar la página", + enableHistoryAfterInsert: "Escribir historial de navegación inmediatamente después de unir, de lo contrario escribir después de navegar", + contentVisibility: "Cambiar automáticamente la visibilidad del contenido para mejorar el rendimiento de renderización", + initRun: "Pasar páginas inmediatamente después de abrir", + preload: "Precargar la siguiente página para acelerar", + click2ImportRule: "Haga clic para importar el enlace de reglas base, luego espere hasta que la actualización esté completa: ", + forceAllBody: "¿Unir el cuerpo completo de la página?", + openInNewTab: "Abrir URLs de adiciones en una nueva pestaña", + importSucc: "Importación completada", + import: "Importar", + editCurrent: "Editar regla para la actual", + editBlacklist: "Editar URLs de la lista negra, una por línea, admite ? * para comodín", + upBtnImg: "Icono de volver al inicio", + downBtnImg: "Icono de ir al pie de página", + sideControllerIcon: "Icono de la barra lateral", + loadingTextTitle: "Texto de carga", + dbClick2StopCtrl: "Tecla Ctrl", + dbClick2StopAlt: "Tecla Alt", + dbClick2StopShift: "Tecla Shift", + dbClick2StopMeta: "Tecla Meta", + dbClick2StopKey: "Tecla de acceso rápido", + pageElementCss: "Estilo personalizado para los elementos principales de la página", + customCss: "CSS completo personalizado", + firstAlert: "No ha importado la regla base, por favor seleccione la regla adecuada para importar", + picker: "Selector de elementos de página de Pagetual", + closePicker: "Cerrar selector de Pagetual", + pickerPlaceholder: "Selector de elementos, déjelo vacío si no tiene idea", + pickerCheck: "Comprobar selector y copiar", + switchSelector: "Haga clic para cambiar el elemento", + gotoEdit: "Ir a editar la regla con el selector actual", + manualMode: "Deshabilitar unión, pasar páginas manualmente con las teclas de flecha derecha (o despachar evento 'pagetual.next')", + clickMode: "Deshabilitar unión, hacer clic automáticamente en la siguiente página al desplazarse al final de la página", + pageBarMenu: "Haga clic en el centro de la barra de página para abrir el menú del selector", + nextSwitch: "Cambiar al siguiente enlace", + arrowToScroll: "Presione la tecla de flecha izquierda para desplazarse anterior y la tecla de flecha derecha para desplazarse siguiente", + sideController: "Mostrar la barra de control de paginación en la barra lateral", + sideControllerScroll: "Alternar desplazamiento", + sideControllerAlways: "Mostrar siempre", + hideLoadingIcon: "Ocultar animación de carga", + hideBarArrow: "Ocultar flecha para la barra de página", + duplicate: "Pagetual duplicado ha sido instalado, ¡revise su gestor de scripts!", + forceStateIframe: "Incrustar página completa como iframe", + forceStateDynamic: "Cargar contenido dinámico a través de iframe", + forceStateDisable: "Deshabilitar pasar páginas en este sitio", + autoScrollRate: "Velocidad de desplazamiento (1~1000)", + disableAutoScroll: "Detener desplazamiento automático", + enableAutoScroll: "Habilitar desplazamiento automático", + toggleAutoScroll: "Alternar desplazamiento automático", + ruleRequest: "Solicitud de regla", + page: "Página ", + prevPage: "Página anterior", + nextPage: "Página siguiente", + errorRulesMustBeArray: "¡Las reglas deben ser un array!", + errorJson: "Error JSON, ¡verifique de nuevo!", + editSuccess: "Editado exitosamente", + errorWrongUrl: "URL incorrecta, ¡verifique de nuevo!", + errorAlreadyExists: "¡Ya existe!", + settingsSaved: "La configuración se ha guardado, actualice para ver", + iframe: "Iframe", + dynamic: "Dinámico", + reloadPage: "Edición completada, ¿recargar página ahora?", + copied: "Copiado", + noValidContent: "No se detectó contenido válido, puede ser necesario realizar una acción de Captcha, haga clic para ver", + outOfDate: "El script está desactualizado, ¡actualice a la última versión a tiempo!", + hideBarTips: "Ocultar la barra de paginación, alternar experiencia inmersiva", + setConfigPage: "Establecer la página actual como la página de configuración predeterminada", + wedata2github: "Cambiar la dirección de wedata a la dirección espejo en el repositorio de GitHub", + addOtherProp: "Agregar propiedad de regla", + addNextSelector: "Agregar contenido del selector como nextLink", + addPageSelector: "Agregar contenido del selector como pageElement", + propName: "Ingrese el nombre de la propiedad de la regla", + propValue: "Ingrese el valor de la propiedad de la regla", + customFirst: "Ignorar caché para reglas personalizadas locales", + rulesExample: "Ejemplo de reglas", + lastPage: "Llegó a la última página", + lastPageTips: "Mostrar consejos al llegar a la última página" + } + }, { //Translated by Prankster 199 (vfggf95565). name: "Arabic", From 1eae1851b5cc3d41604a067451706f1e872cebea Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 18 Jun 2024 09:06:12 +0800 Subject: [PATCH 0082/1065] 1.9.37.59 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 60 +++++++++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index ac3ff1c59b5..d7787444996 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.58](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.59](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index f2e20a11302..18726f6bd68 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.58 +// @version 1.9.37.59 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -3188,7 +3188,15 @@ } if (nextLink) { if (!this.checkStopSign(nextLink, doc)) { - if (curPage > 1 && rulesData.lastPageTips) showTips(i18n("lastPage"), "", 800); + if (curPage > 1) { + if (rulesData.lastPageTips) { + showTips(i18n("lastPage"), "", 800); + } + window.postMessage({ + action: "lastPage", + command: 'pagetual' + }, '*'); + } return null; } if (this.curSiteRule.action == 3) { @@ -3997,6 +4005,10 @@ } } isLoading = false; + window.postMessage({ + action: "insert", + command: 'pagetual' + }, '*'); return true; } } @@ -7500,7 +7512,7 @@ return scrollH - scrolly - windowHeight; } - let scrollHandler, clickToResetHandler, dblclickHandler, keydownHandler, hashchangeHandler, manualModeKeyHandler, pagetualNextHandler, keyupHandler; + let scrollHandler, clickToResetHandler, dblclickHandler, keydownHandler, hashchangeHandler, manualModeKeyHandler, pagetualNextHandler, keyupHandler, messageHandler; function initListener () { document.removeEventListener('scroll', scrollHandler, true); document.removeEventListener('wheel', scrollHandler, true); @@ -7510,6 +7522,7 @@ document.removeEventListener('keydown', manualModeKeyHandler); document.removeEventListener('pagetual.next', pagetualNextHandler, false); document.removeEventListener('keyup', keyupHandler); + window.removeEventListener('message', messageHandler, true); let loadmoreBtn, loadingMore = true, lastScroll = 0, checkLoadMoreTimes = 0; if (ruleParser.curSiteRule.smart) { loadingMore = false; @@ -7545,6 +7558,33 @@ nextPage(); } }; + messageHandler = e => { + if (e.data.command === 'pagetual') { + let action = e.data.action; + let detail = e.data.detail; + switch (action) { + case "config": + if (!detail || typeof detail !== 'object') return; + rulesData = { + ...rulesData, + ...detail + } + storage.setItem("rulesData", rulesData); + break; + case "nextPage": + if (detail === "" || detail === null) return; + detail = parseInt(detail) || 0; + if (loadNowNum != detail) { + loadNowNum = detail; + } + autoLoadNum = detail; + nextPage(); + break; + } + } + return true; + } + window.addEventListener('message', messageHandler, true); scrollHandler = e => { if (urlChanged && !isLoading) { ruleParser.initPage(() => {}); @@ -8423,6 +8463,10 @@ function returnFalse(log) { if (curPage > 1) { if (rulesData.lastPageTips) showTips(i18n("lastPage"), "", 800); + window.postMessage({ + action: "lastPage", + command: 'pagetual' + }, '*'); } else { sideController.remove(); } @@ -9063,9 +9107,15 @@ } else { ruleParser.findNoNext(); } - } else if (rulesData.lastPageTips && !showedLastPageTips) { - showTips(i18n("lastPage"), "", 800); + } else if (!showedLastPageTips) { + if (rulesData.lastPageTips) { + showTips(i18n("lastPage"), "", 800); + } showedLastPageTips = true; + window.postMessage({ + action: "lastPage", + command: 'pagetual' + }, '*'); } return; } From 5e7b6fcce9abe9785927fd8e321f372a7a31dbb4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 18 Jun 2024 09:38:22 +0800 Subject: [PATCH 0083/1065] update --- Pagetual/README.md | 52 +++++++++++++++++++++++++++++++++++++++ Pagetual/pagetual.user.js | 14 +++++------ 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index d7787444996..acd4708a8a9 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -58,6 +58,58 @@ https://raw.githubusercontent.com/hoothin/UserScripts/master/Pagetual/pagetualRu skofkyo
    +
    + +

    Call functionality from other extensions

    +
    + +1. **Immediately load next page** + +> Please send the following message body: +``` +command: "pagetual" +action: "nextPage" +detail: The number of pages to turn, 0 for unlimited, -1 to stop +``` + +> For example: +``` +window.postMessage({ action: 'nextPage', command: 'patetual', detail: 5 }, '*'); +``` + +2. **Set configuration** + +> Please send the following message body: +``` +command: "pagetual" +action: "config" +detail: The configuration item to be changed +``` + +> For example: +``` +window.postMessage({ action: 'config', command: 'patetual', detail: {enableWhiteList: true} }, '*'); +``` ++ **Receive messages** + +> When the next page is inserted, the following message body will be sent: +``` +{ + action: 'insert', + command: 'patetual' +} +``` + +> When the last page has been reached, the following message body will be sent: +``` +{ + action: 'lastPage', + command: 'patetual' +} +``` + +
    + name -- Name of the target site diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 18726f6bd68..dfcf33c50de 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3192,7 +3192,7 @@ if (rulesData.lastPageTips) { showTips(i18n("lastPage"), "", 800); } - window.postMessage({ + _unsafeWindow.postMessage({ action: "lastPage", command: 'pagetual' }, '*'); @@ -4005,7 +4005,7 @@ } } isLoading = false; - window.postMessage({ + _unsafeWindow.postMessage({ action: "insert", command: 'pagetual' }, '*'); @@ -6226,7 +6226,7 @@ let dbClick2StopMetaInput = createCheckbox(i18n("dbClick2StopMeta"), rulesData.dbClick2StopMeta, "h4", dbClick2StopInput); let dbClick2StopKeyInput = createCheckbox(i18n("dbClick2StopKey"), rulesData.dbClick2StopKey, "h4", dbClick2StopInput, "key"); - let otherConfigPage = (rulesData.configPage || configPage[0]) != location.href; + let otherConfigPage = (rulesData.configPage || configPage[0]) != location.href.replace(/#.*/, ""); if (!otherConfigPage) { setConfigPageInput.parentNode.parentNode.style.display = "none"; } @@ -7522,7 +7522,7 @@ document.removeEventListener('keydown', manualModeKeyHandler); document.removeEventListener('pagetual.next', pagetualNextHandler, false); document.removeEventListener('keyup', keyupHandler); - window.removeEventListener('message', messageHandler, true); + _unsafeWindow.removeEventListener('message', messageHandler, true); let loadmoreBtn, loadingMore = true, lastScroll = 0, checkLoadMoreTimes = 0; if (ruleParser.curSiteRule.smart) { loadingMore = false; @@ -7584,7 +7584,7 @@ } return true; } - window.addEventListener('message', messageHandler, true); + _unsafeWindow.addEventListener('message', messageHandler, true); scrollHandler = e => { if (urlChanged && !isLoading) { ruleParser.initPage(() => {}); @@ -8463,7 +8463,7 @@ function returnFalse(log) { if (curPage > 1) { if (rulesData.lastPageTips) showTips(i18n("lastPage"), "", 800); - window.postMessage({ + _unsafeWindow.postMessage({ action: "lastPage", command: 'pagetual' }, '*'); @@ -9112,7 +9112,7 @@ showTips(i18n("lastPage"), "", 800); } showedLastPageTips = true; - window.postMessage({ + _unsafeWindow.postMessage({ action: "lastPage", command: 'pagetual' }, '*'); From 9a9a065604ca7b7fbac02826f656009d13c0e933 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 18 Jun 2024 10:09:39 +0800 Subject: [PATCH 0084/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 7db214f74d5..d11570d5d03 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.16.2 +// @version 2024.6.18.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 @@ -15914,8 +15914,10 @@ ImgOps | https://imgops.com/#b#`; if(curSrc.indexOf("data")===0){ defaultDl(); }else{ + let needPack = !img.complete; imgReady(img,{ ready:function(){ + needPack && self.bricksInstance.pack(); if(img.width>=88 && img.height>=88){ self.addDlSpan(img, imgSpan, curNode, e=>{ e.stopPropagation(); @@ -25725,7 +25727,7 @@ ImgOps | https://imgops.com/#b#`; }, { node: "a", - text: "Star Me", + text: "Star Me on Github", attr: { href: "https://github.com/hoothin/UserScripts#StarMe", target: "_blank" From ef8be898cf98eb06bb821bc0f8f2f256758fe9f6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 18 Jun 2024 10:28:49 +0800 Subject: [PATCH 0085/1065] Update README.md --- Pagetual/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index acd4708a8a9..7cd6f094ca5 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -53,9 +53,10 @@ https://raw.githubusercontent.com/hoothin/UserScripts/master/Pagetual/pagetualRu

    Pagetual User-defined rules cases

    - TerenceCK
    - JPLiu
    - skofkyo + ++ [TerenceCK pagetualRules](https://github.com/TerenceCK/pagetualRules/blob/main/happymh.json) ++ [Liu's-Pagetual-Rule](https://github.com/JPLiu/TestFiles/blob/main/UserScripts/Pagetual/Liu's-Pagetual-Rule.json) ++ [skofkyo pagetualRules_EX](https://github.com/skofkyo/AutoPager/blob/main/pagetualRules_EX.json)
    From f9605d9bf20bd3f6b866650415a767a98ab7d66f Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 18 Jun 2024 12:26:23 +0800 Subject: [PATCH 0086/1065] 1.9.37.60 --- Pagetual/README.md | 16 +++++++++++++++- Pagetual/pagetual.user.js | 16 ++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 7cd6f094ca5..3eaa588749a 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.59](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.60](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* @@ -91,6 +91,20 @@ detail: The configuration item to be changed ``` window.postMessage({ action: 'config', command: 'patetual', detail: {enableWhiteList: true} }, '*'); ``` + +3. **Click load more button** + +> Please send the following message body: +``` +command: "pagetual" +action: "loadMore" +detail: null by default, 0 for unlimited checking load more button, -1 to stop +``` + +> For example: +``` +window.postMessage({ action: 'loadMore', command: 'patetual', detail: 0 }, '*'); +``` + **Receive messages** > When the next page is inserted, the following message body will be sent: diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index dfcf33c50de..09b931aea01 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.59 +// @version 1.9.37.60 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -7523,7 +7523,7 @@ document.removeEventListener('pagetual.next', pagetualNextHandler, false); document.removeEventListener('keyup', keyupHandler); _unsafeWindow.removeEventListener('message', messageHandler, true); - let loadmoreBtn, loadingMore = true, lastScroll = 0, checkLoadMoreTimes = 0; + let loadmoreBtn, loadingMore = true, lastScroll = 0, checkLoadMoreTimes = 0, loadMoreInv; if (ruleParser.curSiteRule.smart) { loadingMore = false; } else if (ruleParser.curSiteRule.loadMore) { @@ -7580,6 +7580,18 @@ autoLoadNum = detail; nextPage(); break; + case "loadMore": + clearInterval(loadMoreInv); + if (detail === -1) return; + loadmoreBtn = getLoadMore(document, loadmoreBtn); + loadmoreBtn && emuClick(loadmoreBtn); + if (detail === 0) { + loadMoreInv = setInterval(() => { + loadmoreBtn = getLoadMore(document, loadmoreBtn); + loadmoreBtn && emuClick(loadmoreBtn); + }, 500); + } + break; } } return true; From 6adad3f7334d7ba2d9977ea78100bb8931dbda53 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 18 Jun 2024 15:24:06 +0800 Subject: [PATCH 0087/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 142 +++++++++++----------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index e42ce972c97..fb4368249a2 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -460,77 +460,6 @@ switch (lang) { } ] }, - { - "type": "辅助工具", - "icon": "list-alt", - "selectTxt": true, - "selectImg": true, - "selectAudio": true, - "selectVideo": true, - "selectLink": true, - "selectPage": true, - "openInNewTab": true, - "sites": [ - { - "name": "手机号码聚合搜索", - "url": "[\"360\",\"搜狗\"]", - "icon": "data:image/jpg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD/2wBDAAcFBQYFBAcGBQYIBwcIChELCgkJChUPEAwRGBUaGRgVGBcbHichGx0lHRcYIi4iJSgpKywrGiAvMy8qMicqKyr/2wBDAQcICAoJChQLCxQqHBgcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKir/wAARCABAAEADASIAAhEBAxEB/8QAHAABAAICAwEAAAAAAAAAAAAAAAMIAgcBBQYE/8QAMxAAAQMDAgIIBAYDAAAAAAAAAQIDBAAFEQYSByEIEzFBUWFxgRQyUmIVIzNCkbFyoeH/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AsPSlKBSlKBSo2X2pDfWR3UPI+ptYUP5FSUClKUCo33kRo7j7ytrbSCtZxnAAyf8AQqSsHWkPtLacGUOJKFehGD/dBU2+9JPV0nVZmWFbUK0tL/Kgusoc61Hi4rGcn7SMd3jVotPXpjUel7deY6drU+KiQEZzt3JyU+xyPaqFXSzvWvUsuzyilp6NKVGWpw4CSle3JPh31efQ2mjo/QtrsJkiUuExtU8OxaiSo4+3KiB5YoNbWXTvC3VE5Y4cXuTp2+N5KfgH3WHQR4su8lp8QO6vWaT1beIepTozXoZ/GOrL0C4sJ2s3NodpA/a4O9Pr79XJjwuLFsukOdZ3dPaxsTiercKwXojpG5paHU43IVjs/wCGun1FepWqeAto10W+rvtifbmBSU7T1rboaeH+Khzx2dlBuqlRsPIkR232vkdQFp9CMj+6koFKUoKxdJPh29DvA1pbGSqJL2t3AJH6ToGErPkoADP1D7hXp+CfGy33GzxdNatmIiXGKgMxpT6tqJKBySkqPILA5c/m5d9bvmQ41whPRJzDciM+gtutOp3JWk8iCO8VWriJ0bJ8OS7cNAH4yIolRtzqwHmvJCjyWPI4V60G/NSa40zo8sDUl4jQFyRlpC8qUseOEgnHn2V9tl1BZdRRS/YbnDuLKcbjGdSvbnxA5j3FUKvFrvNrkiPfYc2I80OrCJba0FIHcN3d6VtLo22K+yuIyLzBS41aYbbiJrx5Id3IIS0PqO7ary258MhbalKUClKUClKUGDrTb7ex9CXUH9riQofwa4ZYajtBqO0hptPYhtISB7CpKUClKUH/2Q==" - }, - { - "name": "🧮 计算器", - "url": "calculator://" - }, - { - "name": "🔎 Everything搜索", - "url": "ES://%s" - }, - { - "name": "🦊 打开火狐", - "url": "FirefoxURL-308046B0AF4A39CB://%u" - }, - { - "name": "⏰ 时钟", - "url": "ms-clock://" - }, - { - "name": "✂️ 屏幕截图", - "url": "ms-screenclip://" - }, - { - "name": "☑️ ToDo", - "url": "ms-todo://", - "description": "微软To-Do" - }, - { - "name": "📓 Onenote", - "url": "onenote://" - }, - { - "name": "⌨️ VSCode", - "url": "vscode://%u" - }, - { - "name": "提取文本中链接并打开", - "url": "%sr.replace(/(点|。)/g,\".\").replace(/[^\\w\\-_\\.~!\\*'\\(\\);:@&=\\+\\$,\\/\\?#\\[\\]%]/g,\"\")" - }, - { - "name": "⭐ 查找当前Favicon", - "url": "javascript:let ico=document.querySelector(\"link[rel='shortcut icon'],link[rel='icon']\");if(ico)window.open(ico.href, \"_blank\");else window.open(location.origin + \"/favicon.ico\", \"_blank\")" - }, - { - "name": "🛠️ 扩展", - "url": "chrome://extensions/" - }, - { - "name": "🐞 远程调试", - "url": "chrome://inspect/#devices" - }, - { - "name": "🔖 书签管理器", - "url": "chrome://bookmarks/" - } - ] - }, { "type": "当前网页", "icon": "list", @@ -712,6 +641,77 @@ switch (lang) { } ] }, + { + "type": "辅助工具", + "icon": "list-alt", + "selectTxt": true, + "selectImg": true, + "selectAudio": true, + "selectVideo": true, + "selectLink": true, + "selectPage": true, + "openInNewTab": true, + "sites": [ + { + "name": "手机号码聚合搜索", + "url": "[\"360\",\"搜狗\"]", + "icon": "data:image/jpg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD/2wBDAAcFBQYFBAcGBQYIBwcIChELCgkJChUPEAwRGBUaGRgVGBcbHichGx0lHRcYIi4iJSgpKywrGiAvMy8qMicqKyr/2wBDAQcICAoJChQLCxQqHBgcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKir/wAARCABAAEADASIAAhEBAxEB/8QAHAABAAICAwEAAAAAAAAAAAAAAAMIAgcBBQYE/8QAMxAAAQMDAgIIBAYDAAAAAAAAAQIDBAAFEQYSByEIEzFBUWFxgRQyUmIVIzNCkbFyoeH/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AsPSlKBSlKBSo2X2pDfWR3UPI+ptYUP5FSUClKUCo33kRo7j7ytrbSCtZxnAAyf8AQqSsHWkPtLacGUOJKFehGD/dBU2+9JPV0nVZmWFbUK0tL/Kgusoc61Hi4rGcn7SMd3jVotPXpjUel7deY6drU+KiQEZzt3JyU+xyPaqFXSzvWvUsuzyilp6NKVGWpw4CSle3JPh31efQ2mjo/QtrsJkiUuExtU8OxaiSo4+3KiB5YoNbWXTvC3VE5Y4cXuTp2+N5KfgH3WHQR4su8lp8QO6vWaT1beIepTozXoZ/GOrL0C4sJ2s3NodpA/a4O9Pr79XJjwuLFsukOdZ3dPaxsTiercKwXojpG5paHU43IVjs/wCGun1FepWqeAto10W+rvtifbmBSU7T1rboaeH+Khzx2dlBuqlRsPIkR232vkdQFp9CMj+6koFKUoKxdJPh29DvA1pbGSqJL2t3AJH6ToGErPkoADP1D7hXp+CfGy33GzxdNatmIiXGKgMxpT6tqJKBySkqPILA5c/m5d9bvmQ41whPRJzDciM+gtutOp3JWk8iCO8VWriJ0bJ8OS7cNAH4yIolRtzqwHmvJCjyWPI4V60G/NSa40zo8sDUl4jQFyRlpC8qUseOEgnHn2V9tl1BZdRRS/YbnDuLKcbjGdSvbnxA5j3FUKvFrvNrkiPfYc2I80OrCJba0FIHcN3d6VtLo22K+yuIyLzBS41aYbbiJrx5Id3IIS0PqO7ary258MhbalKUClKUClKUGDrTb7ex9CXUH9riQofwa4ZYajtBqO0hptPYhtISB7CpKUClKUH/2Q==" + }, + { + "name": "🧮 计算器", + "url": "calculator://" + }, + { + "name": "🔎 Everything搜索", + "url": "ES://%s" + }, + { + "name": "🦊 打开火狐", + "url": "FirefoxURL-308046B0AF4A39CB://%u" + }, + { + "name": "⏰ 时钟", + "url": "ms-clock://" + }, + { + "name": "✂️ 屏幕截图", + "url": "ms-screenclip://" + }, + { + "name": "☑️ ToDo", + "url": "ms-todo://", + "description": "微软To-Do" + }, + { + "name": "📓 Onenote", + "url": "onenote://" + }, + { + "name": "⌨️ VSCode", + "url": "vscode://%u" + }, + { + "name": "提取文本中链接并打开", + "url": "%sr.replace(/(点|。)/g,\".\").replace(/[^\\w\\-_\\.~!\\*'\\(\\);:@&=\\+\\$,\\/\\?#\\[\\]%]/g,\"\")" + }, + { + "name": "⭐ 查找当前Favicon", + "url": "javascript:let ico=document.querySelector(\"link[rel='shortcut icon'],link[rel='icon']\");if(ico)window.open(ico.href, \"_blank\");else window.open(location.origin + \"/favicon.ico\", \"_blank\")" + }, + { + "name": "🛠️ 扩展", + "url": "chrome://extensions/" + }, + { + "name": "🐞 远程调试", + "url": "chrome://inspect/#devices" + }, + { + "name": "🔖 书签管理器", + "url": "chrome://bookmarks/" + } + ] + }, { "type": "视频", "icon": "circle-play", From 5308897a3cfd9af26e2568f86dbaeb632dc400d9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 18 Jun 2024 17:08:31 +0800 Subject: [PATCH 0088/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 31 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index d11570d5d03..ea03e60afc0 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.18.1 +// @version 2024.6.18.2 // @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 @@ -20501,15 +20501,19 @@ ImgOps | https://imgops.com/#b#`; -moz-user-select: -moz-none;\ user-select: none;\ }\ - .pv-pic-window-toolbar:hover {\ - opacity: 1;\ - }\ .pv-pic-window-container_focus:not(.preview)>.pv-pic-window-toolbar {\ display: block;\ }\ - .pv-pic-window-container:hover>.pv-pic-window-max,\ - .pv-pic-window-container:hover>.pv-pic-window-close{\ - opacity: 0.5!important;\ + .pv-pic-window-container:hover>.pv-pic-window-max.insert,\ + .pv-pic-window-container:hover>.pv-pic-window-close.insert{\ + opacity: 0.1!important;\ + }\ + .pv-pic-window-container:hover>.pv-pic-window-toolbar.insert{\ + opacity: 0.1;\ + }\ + .pv-pic-window-toolbar:hover,\ + .pv-pic-window-container>.pv-pic-window-toolbar.insert:hover{\ + opacity: 1;\ }\ span.pv-pic-window-close {\ cursor: pointer;\ @@ -20527,10 +20531,6 @@ ImgOps | https://imgops.com/#b#`; display: none;\ z-index: 2;\ }\ - .pv-pic-window-container>.pv-pic-window-close:hover {\ - background-color:red;\ - opacity: 1!important;\ - }\ .pv-pic-window-container_focus:not(.preview)>.pv-pic-window-close {\ display: block;\ }\ @@ -20566,7 +20566,10 @@ ImgOps | https://imgops.com/#b#`; display: none;\ z-index: 2;\ }\ - .pv-pic-window-container>.pv-pic-window-max:hover {\ + .pv-pic-window-container>.pv-pic-window-max:hover,\ + .pv-pic-window-container>.pv-pic-window-close:hover,\ + .pv-pic-window-container>.pv-pic-window-max.insert:hover,\ + .pv-pic-window-container>.pv-pic-window-close.insert:hover {\ background-color:red;\ opacity: 1!important;\ }\ @@ -21004,6 +21007,7 @@ ImgOps | https://imgops.com/#b#`; function keepSI(obj,offsetDirection,defaultValue, out){ var objRect=obj.getBoundingClientRect(); var objStyle=obj.style; + var insert=false; while(offsetDirection.length){ var oD=offsetDirection[0]; @@ -21048,9 +21052,10 @@ ImgOps | https://imgops.com/#b#`; } break; } + insert=insert||newValue!==oDV; objStyle[oD]=newValue + 'px'; - } + insert ? obj.classList.add("insert") : obj.classList.remove("insert"); } keepSI(this.closeButton,['top','right'],[-22,0]); From 1dc51d054c332e013394ce056156cae6e1400d67 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 18 Jun 2024 19:10:25 +0800 Subject: [PATCH 0089/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 09b931aea01..b41a1992a2f 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2647,12 +2647,13 @@ ".btn_next:not([disabled])", ".btn-next:not([disabled])", "a#linkNext", - "a[class*=page__next]", - "[class*=pager]>a.next", - "[class*=pagination-next]>a", - "[class*=pagination-next]>button", - "[class*=page--current]+li>a", - "[class*=Pages]>.curr+a", + "body a[class*=page__next]", + "body [class*=pager]>a.next", + "body [class*=pagination-next]>a", + "body [class*=pagination-next]>button", + "body [class*=page--current]+li>a", + "body [class*=Pages]>.curr+a", + "body [class*=pagination] .next-btn", ".page>em+a", '//button[contains(@class, "Page")][text()="Next"]', '//button[contains(@class, "page")][text()="next"]' From e427438dcd294017e669efb104347c9c3f12cfcd Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 18 Jun 2024 20:03:00 +0800 Subject: [PATCH 0090/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index b41a1992a2f..0fd7766b6a8 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2743,7 +2743,7 @@ } if (!next) { let isApp = !!body.querySelector("main#app"); - let aTags = body.querySelectorAll("a,button,[type='button']"); + let aTags = body.querySelectorAll("a,button,[type='button'],.btn-action"); for (i = aTags.length - 1; i >= 0; i--) { if (next1) break; if (i % 100 === 0) { From d8e1657450967f34aea759e214c816458573404a Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 18 Jun 2024 21:25:13 +0800 Subject: [PATCH 0091/1065] Update T66y tool.user.js --- T66y tool/T66y tool.user.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/T66y tool/T66y tool.user.js b/T66y tool/T66y tool.user.js index 8b840c1f540..5e2b8ea6ec9 100644 --- a/T66y tool/T66y tool.user.js +++ b/T66y tool/T66y tool.user.js @@ -13,6 +13,7 @@ (function() { 'use strict'; + const enable1024sDelay = false; 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); From b1fd3b5ee00749bb6778cfb811b017271be78046 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 18 Jun 2024 21:25:24 +0800 Subject: [PATCH 0092/1065] Update T66y tool.user.js --- T66y tool/T66y tool.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/T66y tool/T66y tool.user.js b/T66y tool/T66y tool.user.js index 5e2b8ea6ec9..ccffc060607 100644 --- a/T66y tool/T66y tool.user.js +++ b/T66y tool/T66y tool.user.js @@ -13,7 +13,7 @@ (function() { 'use strict'; - const enable1024sDelay = false; + const enable1024sDelay = true; const defaultReply = "1024 感謝分享"; var helper = { addCss: function(css) { From 7bd3fd935fa00b5f0a1a0c6b272ec2fa1fb5cf59 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 19 Jun 2024 10:08:31 +0800 Subject: [PATCH 0093/1065] Update AppinnComment.user.js --- Appinn Comment/AppinnComment.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Appinn Comment/AppinnComment.user.js b/Appinn Comment/AppinnComment.user.js index 6914dd4cd91..21dc0cebf44 100644 --- a/Appinn Comment/AppinnComment.user.js +++ b/Appinn Comment/AppinnComment.user.js @@ -1,5 +1,5 @@ // ==UserScript== -// @name Appinn comment +// @name 小众软件评论显示 // @namespace hoothin // @version 2024-06-08 // @description 将小众软件论坛的评论内容显示在主站对应页面下部 From 12c6e9d5665310481c5bbb6e9bb38fe0d7739fdf Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 19 Jun 2024 10:12:12 +0800 Subject: [PATCH 0094/1065] Update AppinnComment.user.js --- Appinn Comment/AppinnComment.user.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Appinn Comment/AppinnComment.user.js b/Appinn Comment/AppinnComment.user.js index 21dc0cebf44..46076e191bc 100644 --- a/Appinn Comment/AppinnComment.user.js +++ b/Appinn Comment/AppinnComment.user.js @@ -1,8 +1,10 @@ // ==UserScript== -// @name 小众软件评论显示 +// @name Appinn comment +// @name:zh-CN 小众软件评论显示 // @namespace hoothin // @version 2024-06-08 -// @description 将小众软件论坛的评论内容显示在主站对应页面下部 +// @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== From 28df862a7b8501da74a9008d3a274bea9ad01790 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 19 Jun 2024 13:58:46 +0800 Subject: [PATCH 0095/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index fb4368249a2..336050cdbd9 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -238,7 +238,7 @@ switch (lang) { }, { "name": "发送到手机", - "url": "https://s.hoothin.com/#p{wait(x-peer)&call(document.querySelector('x-peer').dispatchEvent(new Event('contextmenu')))&#textInput=%s&click(#textInput+div>button)}", + "url": "https://s.hoothin.com/#p{wait(x-peer)&rclick(x-peer)&#textInput=%s&click(#textInput+div>button)}", "icon": "https://s.hoothin.com/images/favicon-96x96.png", "description": "自动发送选中文字到第一个匹配的设备" }, @@ -281,7 +281,7 @@ switch (lang) { { "name": "🔗 打开文字链接", "url": "%sr.replace(/(点|。)/g,\".\").replace(/[^ \\w\\-_\\.~!\\*';:@&=\\+\\$,\\/\\?#\\[\\]%]/g,\"\").replace(/.*([ ::]|^)(1[a-z0-9]{22,}).*?\\b([a-z0-9]{4}\\b|$).*/i,\"https://pan.baidu.com/s/$1?pwd=$2\").replace(/ /g,\"\").replace(/^/,\"http://\").replace(/^http:\\/\\/(https?:)/,\"$1\")", - "kwFilter": "\\w.*[\\.点。].*\\w|1[a-zA-Z0-9]{22,}", + "kwFilter": "\\w\\S*\\.\\S*\\w|\\w.*[点。].*\\w|1[a-zA-Z0-9]{22,}", "description": "支持类似“pan点baidu。com😄河蟹”以及“1bP23pzUpIV4CMuoMjOfxFA提取码:prt4”的分享链接", "nobatch": true }, @@ -467,12 +467,6 @@ switch (lang) { "selectPage": true, "openInNewTab": true, "sites": [ - { - "name": "小众软件评论", - "url": "showTips:%t \n\n{noscript[data-path]|innerHTML}", - "icon": "https://www.appinn.com/favicon.ico", - "kwFilter": "https://meta\\.appinn\\.net/t/topic/" - }, { "name": "⏬ BBDown", "url": "SearchJumper-BBDown://%u", @@ -1125,7 +1119,7 @@ switch (lang) { { "name": "🔗 Open text link", "url": "%sr.replace(/。/g,\".\").replace(/[^ \\w\\-_\\.~!\\*'\\(\\);:@&=\\+\\$,\\/\\?#\\[\\]%]/g,\"\").replace(/ /g,\"\").replace(/^/,\"http://\").replace(/^http:\\/\\/(https?:)/,\"$1\")", - "kwFilter": "\\w.*[\\.。].*\\w|1[a-zA-Z0-9]{22,}", + "kwFilter": "\\w\\S*\\.\\S*\\w|\\w.*[点。].*\\w|1[a-zA-Z0-9]{22,}", "nobatch": true }, { @@ -1475,7 +1469,7 @@ switch (lang) { }, { "name": "📱 Send to phone", - "url": "https://s.hoothin.com/#p{wait(x-peer)&call(document.querySelector('x-peer').dispatchEvent(new Event('contextmenu')))&#textInput=%s&click(#textInput+div>button)}", + "url": "https://s.hoothin.com/#p{wait(x-peer)&rclick(x-peer)&#textInput=%s&click(#textInput+div>button)}", "icon": "https://s.hoothin.com/images/favicon-96x96.png" }, { From d96b2d452ce6157f78a9aab6f9a41f621a87c662 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 19 Jun 2024 15:50:40 +0800 Subject: [PATCH 0096/1065] Update gallery.html --- Picviewer CE+/gallery.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/gallery.html b/Picviewer CE+/gallery.html index bd44b634b8d..fcb7221b322 100644 --- a/Picviewer CE+/gallery.html +++ b/Picviewer CE+/gallery.html @@ -2,6 +2,7 @@ Picviewer CE+ + - \ No newline at end of file + From 68ddd2eacd9e8215c3b24c4ee2975b38c2412cac Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 19 Jun 2024 15:52:55 +0800 Subject: [PATCH 0097/1065] Update gallery.html --- Picviewer CE+/gallery.html | 1 + 1 file changed, 1 insertion(+) diff --git a/Picviewer CE+/gallery.html b/Picviewer CE+/gallery.html index fcb7221b322..cf0b00f952d 100644 --- a/Picviewer CE+/gallery.html +++ b/Picviewer CE+/gallery.html @@ -3,6 +3,7 @@ Picviewer CE+ + From 63354dde6f8727afeaff4d02bad6b667737ebced Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 09:23:35 +0800 Subject: [PATCH 0098/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index f0d23536987..45c0d8834a9 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1620,5 +1620,11 @@ var siteInfo = [ lazyAttr: "data-a-hires", r: [/(_AC_|_CR0).*\./, /._SY\d+\_?/], s: ["", ""] + }, + { + name: "hentaigifz", + url: /^https:\/\/hentaigifz\.com/, + r: /-thumbnail.*/, + s: ".gif" } ]; From 534d9872946b3dd66c839fd7ce1ff6a04e31d1f2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 09:24:48 +0800 Subject: [PATCH 0099/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index ea03e60afc0..23265864f8d 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.18.2 +// @version 2024.6.20.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 @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1391020/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1397271/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1391048/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 From 4c34a368b0bafa360fb95844ee01ed679ec6cfa3 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 09:28:27 +0800 Subject: [PATCH 0100/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 23265864f8d..9c22dd6c823 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -18212,6 +18212,7 @@ ImgOps | https://imgops.com/#b#`; resize:both;\ width:auto;\ height:auto;\ + background: white;\ }\ .pv-gallery-head-command-drop-list-item_disabled{\ color:#757575;\ From b840660a9842ec980977ad666e391ee337c5ab9d Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 11:33:56 +0800 Subject: [PATCH 0101/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 364 ---------------------- 1 file changed, 364 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 336050cdbd9..63f13d262ea 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -44,149 +44,6 @@ switch (lang) { } ] }, - { - "type": "百科", - "icon": "book-open-reader", - "sites": [ - { - "name": "维基", - "url": "https://zh.wikipedia.org/wiki/%s", - "description": "The largest and most-read reference work in history.#wiki" - }, - { - "name": "百度百科", - "url": "https://baike.baidu.com/search/word?pic=1&sug=1&word=%s", - "description": "A semi-regulated Chinese-language collaborative online encyclopedia owned by the Chinese technology company Baidu.#wiki", - "match": "baike\\.baidu\\.com/search/" - }, - { - "name": "果壳", - "url": "https://www.guokr.com/search/all/?wd=%s" - }, - { - "name": "豆瓣", - "url": "https://www.douban.com/search?source=suggest&q=%s.replace(/\\./g,\" \")" - }, - { - "name": "Bangumi 番组计划", - "url": "https://bgm.tv/subject_search%p{cat=all&search_text=%s}", - "icon": "https://bgm.tv/img/favicon.ico" - } - ] - }, - { - "type": "社交", - "icon": "users", - "sites": [ - { - "name": "知乎", - "url": "https://www.zhihu.com/search?q=%s&type=content" - }, - { - "name": "V2ex", - "url": "https://www.sov2ex.com/?q=%s", - "icon": "https://sov2ex.oss-cn-shanghai.aliyuncs.com/assets/favicon/apple-icon-57x57.png" - }, - { - "name": "百度贴吧", - "url": "https://tieba.baidu.com/f/search/res?ie=utf-8&qw=%s", - "keywords": "kw|qw", - "match": "^https?://tieba\\.baidu\\.com/f" - }, - { - "name": "新浪微博", - "url": "https://s.weibo.com/weibo?q=%s" - }, - { - "name": "微信搜索", - "url": "https://weixin.sogou.com/weixin?ie=utf8&type=2&query=%s" - } - ] - }, - { - "type": "图片", - "icon": "image", - "sites": [ - { - "name": "百度图片", - "url": "https://image.baidu.com/search/index?tn=baiduimage&ie=utf-8&word=%s" - }, - { - "name": "谷歌图片", - "url": "https://www.google.com/search?q=%s&udm=2", - "match": "www\\.google\\..*udm=2" - }, - { - "name": "图片聚合搜索", - "url": "https://www.google.com/search?tbm=isch&as_q=%s%20(site:www.pexels.com%20OR%20site:pixabay.com%20OR%20site:unsplash.com%20OR%20site:stocksnap.io%20OR%20site:pxhere.com%20OR%20site:www.hippopx.com%20OR%20site:foter.com%20OR%20site:freepik.com%20OR%20site:colorhub.me)" - }, - { - "name": "Pinterest", - "url": "https://www.pinterest.com/search/pins/?q=%s&rs=typed&term_meta" - }, - { - "name": "Deviantart", - "url": "https://www.deviantart.com/browse/all/?q=%s" - }, - { - "name": "ChatGPT搜索GIF", - "url": "https://poe.com/ChatGPT#p{sleep(1000)&[class*\\='ChatMessageInputContainer'] textarea=hey ChatGPT. hope you're having a great day. From now on you will respond to anything I say with the perfect gif response. Once you know what gif you want to use, compile the most accurate and perfect search phrase that will result in the specific gif you want to send. respond with url: \" Sure, I'm happy to help you!\\n http://scythe-spot-carpenter.glitch.me/search?search_term\\=.gif \n%s&click(button[class*\\='ChatMessageSendButton_sendButton'])}", - "openInNewTab": true - } - ] - }, - { - "type": "词典", - "icon": "language", - "sites": [ - { - "name": "百度翻译", - "url": "https://fanyi.baidu.com/#auto/zh/%s" - }, - { - "name": "DeepL", - "url": "https://www.deepl.com/translator#zh/en/%s", - "icon": "https://www.deepl.com/img/favicon/favicon_96.png" - }, - { - "name": "谷歌翻译", - "url": "https://translate.google.com/?text=%s", - "match": "translate\\.google\\.com.*\\btext=" - }, - { - "name": "有道词典", - "url": "https://dict.youdao.com/search?q=%s", - "icon": "https://shared.ydstatic.com/images/favicon.ico" - }, - { - "name": "POE", - "url": "https://poe.com/ChatGPT#p{sleep(1000)&[class*\\='ChatMessageInputContainer']>textarea=Please help me to translate \\`%s\\` to English, please return only translated content not include the origin text&click(button[class*\\='ChatMessageSendButton_sendButton'])}" - } - ] - }, - { - "type": "影视", - "icon": "video", - "sites": [ - { - "name": "bilibili", - "url": "https://search.bilibili.com/all?keyword=%s" - }, - { - "name": "腾讯视频", - "url": "https://v.qq.com/x/search/?q=%s" - }, - { - "name": "樱花动漫", - "url": "https://www.yhdmz.org/list/?ex=1&kw=%s" - }, - { - "name": "在线之家", - "url": "https://www.zxzj.org/vodsearch/-------------.html?wd=%s", - "icon": "https://zxzj.vip/statics/img/favicon.ico" - } - ] - }, { "type": "划词搜索", "icon": "sitemap", @@ -381,85 +238,6 @@ switch (lang) { } ] }, - { - "type": "Etc", - "icon": "suitcase", - "sites": [ - { - "name": "邮编库", - "url": "http://www.youbianku.com/%s" - }, - { - "name": "AMO", - "url": "https://addons.mozilla.org/zh-CN/firefox/search/?q=%s" - }, - { - "name": "企查查", - "url": "https://www.qcc.com/search?key=%s", - "match": "^https?:\\/\\/www\\.qcc\\.com\\/(?:web|firm|search)" - }, - { - "name": "天眼查", - "url": "https://www.tianyancha.com/search?key=%s", - "match": "^https?:\\/\\/www\\.tianyancha\\.com\\/(?:search|company)" - } - ] - }, - { - "type": "Github", - "icon": "fa-brands fa-github ", - "match": "github\\.com", - "selectLink": true, - "selectPage": true, - "openInNewTab": true, - "sites": [ - { - "name": "页面镜像 - Fastgit", - "url": "%u.replace(/https:\\/\\/github\\.com/,\"https://hub.fastgit.xyz\")", - "kwFilter": "https:\\/\\/github\\.com" - }, - { - "name": "Raw镜像 - Fastgit", - "url": "%t.replace(/raw\\.githubusercontent\\.com/,\"raw.fastgit.org\").replace(/github.com(.*)\\/blob\\/(.*)/,\"raw.fastgit.org$1/$2\")", - "kwFilter": "github.com.*\\/blob\\/" - }, - { - "name": "Assets镜像 - Fastgit", - "url": "%t.replace(/github\\.githubassets\\.com/,\"assets.fastgit.orgz\")", - "kwFilter": "github\\.githubassets\\.com" - }, - { - "name": "Download镜像- Fastgit", - "url": "%t.replace(/github\\.com(.*\\/download\\/)/,\"download.fastgit.org$1\")", - "kwFilter": "github\\.com.*\\/download\\/" - }, - { - "name": "Archive镜像- Fastgit", - "url": "%t.replace(/github\\.com(.*\\/archive\\/)/,\"download.fastgit.org$1\")", - "kwFilter": "github\\.com.*\\/archive\\/" - }, - { - "name": "Ghproxy镜像加速", - "url": "https://ghproxy.com/%t" - } - ] - }, - { - "type": "VIP", - "icon": "data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgc3R5bGU9ImhlaWdodDogMWVtO2ZpbGw6IHdoaXRlO292ZXJmbG93OiBoaWRkZW47IiB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgcC1pZD0iODI3Ij48cGF0aCBkPSJNNjgzLjE5NTM2MyA1NjcuNjE1NDY5djM0OS4xNDQzOTloNzMuMzY5NDQyVjc4OS45NzUwMTdjMTE3LjI2ODMxMiAxLjczOTU4MiAxNzYuNzIxMDk1LTMuNDc5MTY1IDE5My4xOTU5NjItMTAzLjU1NjMxIDUuMjE4NzQ3LTI5LjI2NTkxNC01LjIxODc0Ny02Mi4xMTMzMjEtMTguMjE0NDQ5LTgwLjEyMzExNC0zOC42ODAxMjQtNTIuMzkyMTI2LTE1NS4wMjc0ODEtMzkuMzk2NDIzLTI0OC4zNTA5NTUtMzguNjgwMTI0ek03NTYuNTY0ODA1IDczMC42MjQ1NjN2LTEwMS44MTY3MjhjNTQuNDM4NjkzLTEuNzM5NTgyIDExMi4wNDk1NjUtNy43NzY5NTYgMTIxLjU2NjEwMyAzNi4yMjQyNDMgMTUuNjU2MjQxIDczLjU3NDA5OC02MC4zNzM3MzggNjcuMzMyMDY4LTEyMS41NjYxMDMgNjUuNTkyNDg1ek01NDEuODc5ODg0IDU2OS4zNTUwNTFjMC44MTg2MjcgMTE1LjUyODczIDAuODE4NjI3IDIzMS44NzYwODcgMS43Mzk1ODIgMzQ3LjQwNDgxN2g3MS42Mjk4NTlWNTY3LjYxNTQ2OWMtMjQuMTQ5NDk1IDEuMDIzMjg0LTQ4LjQwMTMxOSAxLjAyMzI4NC03My4zNjk0NDEgMS43Mzk1ODJ6TTY4MC43Mzk0ODIgMTAyLjEyMzcxM2MtMTEzLjA3Mjg0OSAxMTIuODY4MTkyLTIyNS44Mzg3MTMgMjI0LjkxNzc1OC0zMzkuNzMwMTg5IDMzNy45OTA2MDdWMTAyLjEyMzcxM0g2Ny42OTAyMTdjMC44MTg2MjcgMjIuNDA5OTEzIDAuODE4NjI3IDQ1LjYzODQ1MyAxLjczOTU4MiA2OC4xNTA2OTVoNjYuNDExMTEydjc0NS45NzM4MThjMjcxLjU3OTQ5NC0yNzEuNzg0MTUxIDU0Mi4zNDAzNjItNTQyLjU0NTAxOCA4MTMuOTE5ODU2LTgxNC4xMjQ1MTNINjgwLjczOTQ4MnoiIHAtaWQ9IjgyOCIvPjwvc3ZnPg==", - "match": "v\\.qq\\.com/x/|\\.mgtv\\.com/.*b/|v\\.youku\\.com/(v_show|video)/|\\.iqiyi\\.com/(v_|dianying)", - "sites": [ - { - "name": "无名小站", - "url": "https://www.administratorw.com/video.php?url=%u" - }, - { - "name": "小小解析", - "url": "http://tv.hzwdd.cn/#p{#url=%u&click(.btn-play)}", - "icon": "http://tv.hzwdd.cn/img/favicon.ico" - } - ] - }, { "type": "当前网页", "icon": "list", @@ -584,144 +362,6 @@ switch (lang) { } ] }, - { - "type": "网页快照", - "icon": "clock-rotate-left", - "selectLink": true, - "selectPage": true, - "openInNewTab": true, - "sites": [ - { - "name": "Wayback Machine all", - "url": "https://web.archive.org/web/*/%u", - "icon": "https://web.archive.org/_static/images/archive.ico" - }, - { - "name": "Wayback Machine", - "url": "https://web.archive.org/web/%u", - "icon": "https://web.archive.org/_static/images/archive.ico" - }, - { - "name": "Google 快照", - "url": "https://webcache.googleusercontent.com/search?q=cache:%u" - }, - { - "name": "Google 文本快照", - "url": "https://webcache.googleusercontent.com/search?strip=1&q=cache:%u" - }, - { - "name": "Bing 快照", - "url": "https://www.bing.com/search?q=url:%u&go=Search&qs=bs&form=QBRE#p{click(ol#b_results li.b_algo:first-of-type div.b_attribution a.trgr_icon)&open(ol#b_results li.b_algo:first-of-type div.b_attribution a[href*\\=\"cc.bingj.com/cache\"])}" - }, - { - "name": "Archive.is", - "url": "https://archive.is/newest/%u" - }, - { - "name": "Archive.is all", - "url": "https://archive.is/%u" - }, - { - "name": "Yahoo 快照", - "url": "https://search.yahoo.com/search?p=url:%u#p{open(#results li:first-of-type a[href*\\=\"cc.bingj.com/cache\"], #results li:first-of-type a[href*\\=\"cc.bingj.com%2fcache\"])}" - }, - { - "name": "Ghostarchive", - "url": "https://ghostarchive.org/search?term=%u" - }, - { - "name": "WebCite", - "url": "https://webcitation.org/query?url=%u" - } - ] - }, - { - "type": "辅助工具", - "icon": "list-alt", - "selectTxt": true, - "selectImg": true, - "selectAudio": true, - "selectVideo": true, - "selectLink": true, - "selectPage": true, - "openInNewTab": true, - "sites": [ - { - "name": "手机号码聚合搜索", - "url": "[\"360\",\"搜狗\"]", - "icon": "data:image/jpg;base64,/9j/4AAQSkZJRgABAQEBLAEsAAD/2wBDAAcFBQYFBAcGBQYIBwcIChELCgkJChUPEAwRGBUaGRgVGBcbHichGx0lHRcYIi4iJSgpKywrGiAvMy8qMicqKyr/2wBDAQcICAoJChQLCxQqHBgcKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKir/wAARCABAAEADASIAAhEBAxEB/8QAHAABAAICAwEAAAAAAAAAAAAAAAMIAgcBBQYE/8QAMxAAAQMDAgIIBAYDAAAAAAAAAQIDBAAFEQYSByEIEzFBUWFxgRQyUmIVIzNCkbFyoeH/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AsPSlKBSlKBSo2X2pDfWR3UPI+ptYUP5FSUClKUCo33kRo7j7ytrbSCtZxnAAyf8AQqSsHWkPtLacGUOJKFehGD/dBU2+9JPV0nVZmWFbUK0tL/Kgusoc61Hi4rGcn7SMd3jVotPXpjUel7deY6drU+KiQEZzt3JyU+xyPaqFXSzvWvUsuzyilp6NKVGWpw4CSle3JPh31efQ2mjo/QtrsJkiUuExtU8OxaiSo4+3KiB5YoNbWXTvC3VE5Y4cXuTp2+N5KfgH3WHQR4su8lp8QO6vWaT1beIepTozXoZ/GOrL0C4sJ2s3NodpA/a4O9Pr79XJjwuLFsukOdZ3dPaxsTiercKwXojpG5paHU43IVjs/wCGun1FepWqeAto10W+rvtifbmBSU7T1rboaeH+Khzx2dlBuqlRsPIkR232vkdQFp9CMj+6koFKUoKxdJPh29DvA1pbGSqJL2t3AJH6ToGErPkoADP1D7hXp+CfGy33GzxdNatmIiXGKgMxpT6tqJKBySkqPILA5c/m5d9bvmQ41whPRJzDciM+gtutOp3JWk8iCO8VWriJ0bJ8OS7cNAH4yIolRtzqwHmvJCjyWPI4V60G/NSa40zo8sDUl4jQFyRlpC8qUseOEgnHn2V9tl1BZdRRS/YbnDuLKcbjGdSvbnxA5j3FUKvFrvNrkiPfYc2I80OrCJba0FIHcN3d6VtLo22K+yuIyLzBS41aYbbiJrx5Id3IIS0PqO7ary258MhbalKUClKUClKUGDrTb7ex9CXUH9riQofwa4ZYajtBqO0hptPYhtISB7CpKUClKUH/2Q==" - }, - { - "name": "🧮 计算器", - "url": "calculator://" - }, - { - "name": "🔎 Everything搜索", - "url": "ES://%s" - }, - { - "name": "🦊 打开火狐", - "url": "FirefoxURL-308046B0AF4A39CB://%u" - }, - { - "name": "⏰ 时钟", - "url": "ms-clock://" - }, - { - "name": "✂️ 屏幕截图", - "url": "ms-screenclip://" - }, - { - "name": "☑️ ToDo", - "url": "ms-todo://", - "description": "微软To-Do" - }, - { - "name": "📓 Onenote", - "url": "onenote://" - }, - { - "name": "⌨️ VSCode", - "url": "vscode://%u" - }, - { - "name": "提取文本中链接并打开", - "url": "%sr.replace(/(点|。)/g,\".\").replace(/[^\\w\\-_\\.~!\\*'\\(\\);:@&=\\+\\$,\\/\\?#\\[\\]%]/g,\"\")" - }, - { - "name": "⭐ 查找当前Favicon", - "url": "javascript:let ico=document.querySelector(\"link[rel='shortcut icon'],link[rel='icon']\");if(ico)window.open(ico.href, \"_blank\");else window.open(location.origin + \"/favicon.ico\", \"_blank\")" - }, - { - "name": "🛠️ 扩展", - "url": "chrome://extensions/" - }, - { - "name": "🐞 远程调试", - "url": "chrome://inspect/#devices" - }, - { - "name": "🔖 书签管理器", - "url": "chrome://bookmarks/" - } - ] - }, - { - "type": "视频", - "icon": "circle-play", - "selectVideo": true, - "openInNewTab": true, - "sites": [ - { - "name": "M3u8播放器", - "url": "https://players.akamai.com/players/hlsjs?streamUrl=%t" - }, - { - "name": "去视频水印", - "url": "https://parse.bqrdh.com/smart/#p{.ant-input=%u&click(.ant-input-search-button)}" - } - ] - }, { "type": "AI", "icon": "robot", @@ -765,10 +405,6 @@ switch (lang) { "name": "复制知乎回答 ", "url": "c:%element{.AuthorInfo>[itemprop='name']}.prop(content)\n%element{.CopyrightRichText-richText}\n%element{.ContentItem-time}" }, - { - "name": "🔆 高亮关键词", - "url": "javascript:(function()%7Bvar%20count=0,text,dv;text=prompt(%22%E6%90%9C%E7%B4%A2%E9%85%B1%EF%BC%9A%E8%AF%B7%E8%BE%93%E5%85%A5%E9%AB%98%E4%BA%AE%E5%85%B3%E9%94%AE%E8%AF%8D%EF%BC%8Calt%E5%B7%A6%E9%94%AE%E5%8D%95%E5%87%BB%E4%B8%8B%E4%B8%80%E4%B8%AA%EF%BC%8Calt%E5%8F%B3%E9%94%AE%E4%B8%8A%E4%B8%80%E4%B8%AA%EF%BC%8Cr%E8%BF%98%E5%8E%9F%EF%BC%8Cc%7C%E8%87%AA%E5%AE%9A%E4%B9%89%E5%88%86%E9%9A%94(%E7%AB%96%E6%9D%A0)%EF%BC%8Co%E5%8E%9F%E5%A7%8B%E6%96%87%E6%9C%AC:%22,%20%22%S%22);if%20(text==null%7C%7Ctext.length==0)return;if(text===%22r%22)%7B%5B%5D.forEach.call(document.querySelectorAll(%22mark.searchJumper%22),mark=%3E%7Blet%20newNode=document.createTextNode(mark.innerText);mark.parentNode.replaceChild(newNode,mark);%7D);return;%7Dif(text.indexOf(%22o%22)===0)%7Btext=%5Btext.substr(1)%5D;%7Delse%20if(text.indexOf(%22c%22)===0)%7Btext=text.substr(1);text=text.substr(1).split(text.substr(0,1));%7Delse%20text=%5Btext%5D;dv=document.defaultView;let%20marks=%7B%7D;let%20focusMark;function%20setFocus(ele)%7BfocusMark.style.border=%22%22;focusMark=ele;focusMark.scrollIntoView(%7Bbehavior:%22smooth%22,block:%22center%22,inline:%22nearest%22%7D);focusMark.style.border=%222px%20dashed%20red%22;%7Dfunction%20searchWithinNode(node,te,len)%20%7Bvar%20pos,skip,spannode,middlebit,middleclone;skip=0;if(node.nodeType==3)%7Bpos=node.data.toUpperCase().indexOf(te);if%20(pos%3E=0)%20%7Blet%20index=marks%5Bte%5D.length;spannode=document.createElement(%22mark%22);spannode.className=%22searchJumper%22;spannode.addEventListener(%22mousedown%22,e=%3E%7Bif%20(!e.altKey)return;if(e.which===1)%7Bif(index!=marks%5Bte%5D.length-1)%7BsetFocus(marks%5Bte%5D%5Bindex+1%5D);%7D%7Delse%20if(e.which===3)%7Bif(index!=0)%7BsetFocus(marks%5Bte%5D%5Bindex-1%5D);%7D%7D%7D);spannode.addEventListener(%22click%22,e=%3E%7Be.stopPropagation();e.preventDefault();return%20false;%7D);middlebit=node.splitText(pos);middlebit.splitText(len);middleclone=middlebit.cloneNode(true);spannode.appendChild(middleclone);middlebit.parentNode.replaceChild(spannode,middlebit);marks%5Bte%5D.push(spannode);focusMark=spannode;++count;skip%20=%201;%7D%7D%20else%20if%20(node.nodeType==1&&node.childNodes&&node.tagName.toUpperCase()!=%22SCRIPT%22&&node.tagName.toUpperCase()!=%22STYLE%22&&node.tagName.toUpperCase()!=%22MARK%22)%7Bfor%20(var%20child=0;child%3Cnode.childNodes.length;++child)%7Bchild=child+searchWithinNode(node.childNodes%5Bchild%5D,te,len);%7D%7Dreturn%20skip;%7Dtext.forEach(t=%3E%7Bt=t.toUpperCase();marks%5Bt%5D=%5B%5D;searchWithinNode(document.body,t,t.length);%7D)%0A%7D)();" - }, { "name": "将svg图片复制为base64", "url": "javascript:(()=>{let svg=window.targetElement&&window.targetElement.querySelector('svg');if(svg){navigator.clipboard.writeText('data:image/svg+xml;base64,'+btoa(unescape(encodeURIComponent(new XMLSerializer().serializeToString(svg)))));alert(\"copy over!\")}})()" From b53d7eabf66d28de317dba366d9287473a9e7c9c Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 11:37:15 +0800 Subject: [PATCH 0102/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 250 ---------------------- 1 file changed, 250 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 63f13d262ea..5019cdc8d89 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -552,105 +552,6 @@ switch (lang) { } ] }, - { - "type": "News", - "icon": "newspaper", - "sites": [ - { - "name": "Google News", - "url": "https://news.google.com/search?q=%s&hl=zh-CN&gl=CN&ceid=CN:zh-Hans", - "icon": "https://www.google.com/favicon.ico" - }, - { - "name": "CNN", - "url": "https://edition.cnn.com/search/?q=%s" - }, - { - "name": "BBC", - "url": "https://www.bbc.co.uk/search?q=%s" - } - ] - }, - { - "type": "Translate", - "icon": "language", - "sites": [ - { - "name": "DeepL", - "url": "https://www.deepl.com/translator#*/en/%s", - "icon": "https://www.deepl.com/img/favicon/favicon_96.png" - }, - { - "name": "Google translate", - "url": "https://translate.google.com/?text=%s", - "match": "translate\\.google\\.com.*\\btext=" - }, - { - "name": "Bing translate", - "url": "http://www.bing.com/dict/search?q=%s" - }, - { - "name": "Forvo", - "url": "https://www.forvo.com/search/%s" - }, - { - "name": "Translate with ChatGPT", - "url": "https://poe.com/ChatGPT#p{sleep(1000)&[class*\\='ChatMessageInputContainer'] textarea=Please help me to translate \\`%s\\` to English, please return only translated content not include the origin text&click(button[class*\\='ChatMessageSendButton_sendButton'])}" - } - ] - }, - { - "type": "Develop", - "icon": "code", - "sites": [ - { - "name": "MDN", - "url": "https://developer.mozilla.org/zh-CN/search?q=%s" - }, - { - "name": "Stackoverflow", - "url": "https://stackoverflow.com/search?q=%s" - }, - { - "name": "Can I Use", - "url": "http://caniuse.com/#search=%s", - "icon": "https://caniuse.com/img/favicon-128.png" - }, - { - "name": "GitHub", - "url": "https://github.com/search?utf8=✓&q=%s", - "match": "https://github\\.com/search\\?.*&q=" - }, - { - "name": "W3c", - "url": "http://www.runoob.com/?s=%s" - }, - { - "name": "GreasyFork", - "url": "https://greasyfork.org/zh-CN/scripts?q=%s&utf8=✓" - }, - { - "name": "Gen RegExp by AI", - "url": "https://poe.com/ChatGPT#p{sleep(1000)&textarea[class^\\='ChatMessageInput']=Can you help me to write a RegExp which can detect %input{Target,Email address/Phone number} on `%s`&click([class^\\='ChatMessageInputView_sendButton']>button)}", - "openInNewTab": true - } - ] - }, - { - "type": "Wiki", - "icon": "book-open-reader", - "sites": [ - { - "name": "Wikipedia", - "url": "http://en.wikipedia.org/wiki/%s", - "description": "The largest and most-read reference work in history.#wiki" - }, - { - "name": "Quora", - "url": "https://www.quora.com/search?q=%s" - } - ] - }, { "type": "Social", "icon": "users", @@ -665,62 +566,6 @@ switch (lang) { } ] }, - { - "type": "APP", - "icon": "archive", - "sites": [ - { - "name": "Play", - "url": "https://play.google.com/store/search?q=%s" - }, - { - "name": "Coolapk", - "url": "https://www.coolapk.com/search?q=%s" - }, - { - "name": "Apkpure", - "url": "https://apkpure.com/cn/search?q=%s" - }, - { - "name": "APKMirror", - "url": "https://www.apkmirror.com/?s=%s" - }, - { - "name": "Chrome Store", - "url": "https://chrome.google.com/webstore/search/%s", - "icon": "https://www.google.com/images/icons/product/chrome_web_store-32.png" - } - ] - }, - { - "type": "Music", - "icon": "music", - "sites": [ - { - "name": "Jango", - "url": "https://www.jango.com/music/%s" - }, - { - "name": "QQ Music", - "url": "https://y.qq.com/portal/search.html#page=1&searchid=1&remoteplace=txt.yqq.top&t=song&w=%s" - } - ] - }, - { - "type": "Shopping", - "icon": "shopping-cart", - "sites": [ - { - "name": "Amazon", - "url": "http://www.amazon.cn/s/ref=nb_sb_noss?field-keywords=%s", - "icon": "https://www.amazon.cn/favicon.ico" - }, - { - "name": "1688", - "url": "https://s.1688.com/selloffer/offer_search.htm?keywords=%s" - } - ] - }, { "type": "Search in page", "icon": "sitemap", @@ -861,65 +706,6 @@ switch (lang) { } ] }, - { - "type": "Web cache", - "icon": "clock-rotate-left", - "selectPage": true, - "openInNewTab": true, - "sites": [ - { - "name": "Wayback Machine all", - "url": "https://web.archive.org/web/*/%u", - "icon": "https://web.archive.org/_static/images/archive.ico" - }, - { - "name": "Wayback Machine", - "url": "https://web.archive.org/web/%u", - "icon": "https://web.archive.org/_static/images/archive.ico" - }, - { - "name": "Google cache", - "url": "https://webcache.googleusercontent.com/search?q=cache:%u" - }, - { - "name": "Google cache text", - "url": "https://webcache.googleusercontent.com/search?strip=1&q=cache:%u" - }, - { - "name": "Bing cache", - "url": "https://www.bing.com/search?q=url:%u&go=Search&qs=bs&form=QBRE#p{click(ol#b_results li.b_algo:first-of-type div.b_attribution a.trgr_icon)&open(ol#b_results li.b_algo:first-of-type div.b_attribution a[href*\\=\"cc.bingj.com/cache\"])}" - }, - { - "name": "Archive.is", - "url": "https://archive.is/newest/%u" - }, - { - "name": "Archive.is all", - "url": "https://archive.is/%u" - }, - { - "name": "Memento", - "url": "http://timetravel.mementoweb.org/memento/0/%u", - "icon": "http://mementoweb.org/static/css/images/timetravel_logo_20x20.png" - }, - { - "name": "Megalodon", - "url": "https://megalodon.jp/?url=%u" - }, - { - "name": "Yahoo cache", - "url": "https://search.yahoo.com/search?p=url:%u#p{open(#results li:first-of-type a[href*\\=\"cc.bingj.com/cache\"], #results li:first-of-type a[href*\\=\"cc.bingj.com%2fcache\"])}" - }, - { - "name": "Ghostarchive", - "url": "https://ghostarchive.org/search?term=%u" - }, - { - "name": "WebCite", - "url": "https://webcitation.org/query?url=%u" - } - ] - }, { "type": "Search by image", "icon": "eye", @@ -964,42 +750,6 @@ switch (lang) { } ] }, - { - "type": "Scholar", - "icon": "graduation-cap", - "sites": [ - { - "name": "Google scholar", - "url": "https://scholar.google.com/scholar?hl=zh-CN&q=%s", - "icon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACqklEQVQ4jYWT2UtUURzHL/QH1LMP9hKVNUKFWpP7TDrjU9uEo4WPWlERUbSoueSMaTWjTBCRGV3HiCsSWrTQApVSZBtZWEZSUWZkC3PPne3OzKeHK1NKy4Hfyzl8P+d3vt/fkSRJmpWSVbU9vbxbMZXJSnqZrMx3yErqmrN/r7V+Zf76jjNz5mYXSilZldtKfGBrA5sXcg7Dpg5wX/lzNV+FlmuwsRNy6r9HJFO5v9feBlaXILNWxenT+Pgtzr/W2Oc4azwalqMgLXZ29di9JMXj/xH3P4pybjDKhvYg1qMgpZfKyko3lPk0xr9PF7/4EOfTjwQAiQRcfqpjrlMZeBVjc2eI/FaQ5jlkZWs3qKHENPH7yTg5DYKKExp6DGJxcLRprHILAJr7w5hdIC1wyMquHmNj3/kQN57rALz9Eie/SZBRo/JwLAZAtRLC4jIA7r4pQHqprBS0QkaNysLdAXbKIQAiOjh9Gml7VOS7kaSooGkGwFQqKzYvWFyCgiZBbqPg3mvjRv9ABNPeANeHdSbVBOu8GvYWA9ByMcyKmQCLS5DToFLSKlDuR/kmEox+Moyt6w2TtidAUbPgyKUwZceDWI7MAFhdRgdL9quk7ghw8bGeNPXdZJzKjiCZNSpZtSp5jQKb9zeA1SUw16ms9WqcvBlhcDTG4KsYoxO/ohXhBFWng5jrVCwuQbHnN0B2vaDiRJCJqdzvvtRZfUyQ3SA4dSuCbtjC0JsY5npBYRLg9PfaPEYK14f15NA4fRpLD6jkHxKY9ga4PWKcvRyPk9toGF7sBWmR45S/pN0Y5a6BaLLdroEoGTUqy6oNc99NGk85dCHM8oMCqzuIvQ2k2XPzLAWNX9UiD9i90D0EE8Yo8GQc/A/g2QSMfIHaPsg9DMUe4/dmbrnz8CdxKwtDTtdexQAAAABJRU5ErkJggg==" - }, - { - "name": "Wikipedia", - "url": "https://en.wikipedia.org/w/index.php?search=%s&button=&title=Special%3ASearch" - }, - { - "name": "Internet Archive", - "url": "https://archive.org/search.php?query=%s" - }, - { - "name": "Scholar", - "url": "http://scholar.google.com/scholar?hl=zh-CN&q=%s&btnG=&lr=" - }, - { - "name": "Google Book", - "url": "https://www.google.com/search?q=%s&tbm=bks&tbo=1&hl=en&gws_rd=ssl" - }, - { - "name": "krugle", - "url": "http://opensearch.krugle.org/document/search/#query=%s", - "icon": "https://opensearch.krugle.org/media/images/favicon.ico" - }, - { - "name": "npm", - "url": "https://www.npmjs.org/search?q=%s" - } - ] - }, { "type": "AI", "icon": "robot", From 1e98f1a251969fe12af7379ce4263696eb765bdd Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 11:47:30 +0800 Subject: [PATCH 0103/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 28 ----------------------- 1 file changed, 28 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 5019cdc8d89..11747206593 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -538,34 +538,6 @@ switch (lang) { } ] }, - { - "type": "Video", - "icon": "video", - "sites": [ - { - "name": "Youtube", - "url": "https://www.youtube.com/results?search_query=%s" - }, - { - "name": "Niconico", - "url": "http://www.nicovideo.jp/search/%s" - } - ] - }, - { - "type": "Social", - "icon": "users", - "sites": [ - { - "name": "Twitter", - "url": "https://twitter.com/search?q=%s" - }, - { - "name": "Facebook", - "url": "https://www.facebook.com/search/results.php?q=%s" - } - ] - }, { "type": "Search in page", "icon": "sitemap", From e68efe0b68870033770bb6d31dde078613557801 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 12:47:56 +0800 Subject: [PATCH 0104/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 45c0d8834a9..cdf94eced9b 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1626,5 +1626,13 @@ var siteInfo = [ url: /^https:\/\/hentaigifz\.com/, r: /-thumbnail.*/, s: ".gif" + }, + { + name: "porngifmag", + url: /^https:\/\/porngifmag\.com/, + xhr: { + url: ".thumb-image>a", + query: ".single-image>img" + } } ]; From 8bd1c0b657e0cb71ac358361a525e57147688224 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 13:10:31 +0800 Subject: [PATCH 0105/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 47 ++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 9c22dd6c823..a9252282ae2 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.20.1 +// @version 2024.6.20.2 // @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 @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1397271/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1397366/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1391048/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 @@ -16183,12 +16183,31 @@ ImgOps | https://imgops.com/#b#`; xhrLoad.load({ url: src, xhr: xhr, - cb: function(imgSrc, imgSrcs, caption) { + cb: function(imgSrc, imgSrcs, caption, captions) { if (imgSrc) { dataset(ele, 'src', imgSrc); dataset(ele, 'xhr', 'stop'); if (caption) dataset(ele, 'description', caption); self.getImg(ele); + if (imgSrcs && imgSrcs.length) { + let i = 0; + imgSrcs.forEach(src => { + if (src == imgSrc) return; + let img = document.createElement('img'); + img.src = src; + let cap = captions && captions[i] ? captions[i] : caption; + imgReady(img,{ + ready:function(){ + let result = findPic(img); + if (cap) result.description = cap; + self.data.push(result); + self._appendThumbSpans([result]); + self.loadThumb(); + } + }); + i++; + }) + } } else { xhrError(); } @@ -16682,6 +16701,7 @@ ImgOps | https://imgops.com/#b#`; }catch(e){}; self._spanMarkPool[item.src] = spanMark; } + spanMark.dataset.xhr=''; if(spanMark.dataset.naturalSize){ let naturalSize=JSON.parse(spanMark.dataset.naturalSize); item.sizeW=naturalSize.w; @@ -19195,12 +19215,31 @@ ImgOps | https://imgops.com/#b#`; xhrLoad.load({ url: dataset(ele,'src'), xhr: xhr, - cb: function(imgSrc, imgSrcs, caption) { + cb: function(imgSrc, imgSrcs, caption, captions) { if (imgSrc) { dataset(ele, 'src', imgSrc); dataset(ele, 'xhr', 'stop'); if (caption) dataset(ele, 'description', caption); beginLoadImg(); + if (imgSrcs && imgSrcs.length) { + let i = 0; + imgSrcs.forEach(src => { + if (src == imgSrc) return; + let img = document.createElement('img'); + img.src = src; + let cap = captions && captions[i] ? captions[i] : caption; + imgReady(img,{ + ready:function(){ + let result = findPic(img); + if (cap) result.description = cap; + self.oriThis.data.push(result); + self.oriThis._appendThumbSpans([result]); + self.oriThis.loadThumb(); + } + }); + i++; + }) + } } else { xhrError(); } From 617e4ba5bfa1c54ed5a9c335c4a4b50ce5059239 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 15:45:29 +0800 Subject: [PATCH 0106/1065] 1.9.37.61 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 3eaa588749a..ff1850813f9 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.60](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.61](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 0fd7766b6a8..ce82fe31f51 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.60 +// @version 1.9.37.61 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -1282,7 +1282,7 @@ let classList = ele.classList; for (let i = 0; i < classList.length; i++) { let c = classList[i]; - if (/^[\w\-_]+$/.test(c) && !/\d{4,}/.test(c)) { + if (c !== 'scrolling' && /^[a-z_][\w\-_]*$/.test(c) && !/\d{4,}/.test(c)) { className += '.' + c; } } @@ -1310,7 +1310,7 @@ let classList = prevE.classList; for (let i = 0; i < classList.length; i++) { let c = classList[i]; - if (/^[\w\-_]+$/.test(c) && !/\d{4,}/.test(c)) { + if (c !== 'scrolling' && /^[a-z_][\w\-_]*$/.test(c) && !/\d{4,}/.test(c)) { className += '.' + c; } } From be1eadef697f5dc3c4784775dec6ece22b872272 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 20:00:03 +0800 Subject: [PATCH 0107/1065] save as pdf --- Picviewer CE+/Picviewer CE+.user.js | 55 ++++++++++++++++++------ Picviewer CE+/pvcep_pdf_addon.user.js | 61 +++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 12 deletions(-) create mode 100644 Picviewer CE+/pvcep_pdf_addon.user.js diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index a9252282ae2..9767fac7154 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.20.2 +// @version 2024.6.20.3 // @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 @@ -14412,7 +14412,7 @@ ImgOps | https://imgops.com/#b#`; eleMaps['head-command-drop-list-others'].querySelector('input[data-command="scrollToEndAndReload"]').checked = prefs.gallery.scrollEndAndLoad; let srcSplit, downloading=false, saveParams; function getSaveParams() { - let nodes = self.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]'); + let nodes = self.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]:not(.ignore)'); let saveParams = [],saveIndex=0; [].forEach.call(nodes, function(node){ if(unsafeWindow.getComputedStyle(node).display!="none"){ @@ -15439,8 +15439,13 @@ ImgOps | https://imgops.com/#b#`; var self=this; if(prefs.gallery.downloadWithZip){ self.showTips(i18n("galleryDownloadWithZipAlert"), 100000); - var zip = new JSZip(),downloaded=0; - var fileName = document.title + ".zip"; + var zip,downloaded=0, pdf=!!unsafeWindow.pvcepimg2pdf; + var fileName = document.title + (pdf ? ".pdf" : ".zip"); + if (pdf) { + zip = new unsafeWindow.pvcepimg2pdf(fileName); + } else { + zip = new JSZip(); + } var len = saveParams.length; function downloadOne(imgSrc, imgName){ let crosHandler = imgSrc => { @@ -15455,9 +15460,11 @@ ImgOps | https://imgops.com/#b#`; downloaded++; self.showTips("Downloading "+downloaded+"/"+len, 1000000); if(downloaded == len){ - self.showTips("Begin compress to ZIP...", 100000); + self.showTips(`Begin compress to ${pdf ? 'PDF' : 'ZIP'}...`, 100000); zip.generateAsync({type:"blob"}, meta=>{self.showCompressProgress(meta)}).then(function(content){ - saveAs(content, fileName); + if (content) { + saveAs(content, fileName); + } callback(); }) } @@ -15474,9 +15481,11 @@ ImgOps | https://imgops.com/#b#`; zip.file(imgName.replace(/^data:.*/, "img").replace(/\//g,""), blob); downloaded++; if(downloaded == len){ - self.showTips("Begin compress to ZIP...", 100000); + self.showTips(`Begin compress to ${pdf ? 'PDF' : 'ZIP'}...`, 100000); zip.generateAsync({type:"blob"}, meta=>{self.showCompressProgress(meta)}).then(function(content){ - saveAs(content, fileName); + if (content) { + saveAs(content, fileName); + } callback(); }) } @@ -15730,6 +15739,7 @@ ImgOps | https://imgops.com/#b#`; var topP=document.createElement('p'); topP.className="pv-top-banner"; topP.innerHTML=createHTML(img.naturalWidth+' x '+img.naturalHeight); + topP.title=dlSpan.title; var checkBox=document.createElement('input'); checkBox.type="checkbox"; let self=this; @@ -15751,7 +15761,7 @@ ImgOps | https://imgops.com/#b#`; checkBox.click(); }; imgSpan.appendChild(topP); - imgSpan.appendChild(checkBox); + imgSpan.insertBefore(checkBox, imgSpan.firstChild); imgSpan.appendChild(dlSpan); }, addViewmoreItem: function(nodes) { @@ -16698,6 +16708,11 @@ ImgOps | https://imgops.com/#b#`; spanMark.title = title + (itemSrc.length > 150 ? itemSrc.slice(0, 110) + " ... " + itemSrc.slice(-30) : itemSrc); spanMark.innerHTML=createHTML('' + ''); + spanMark.addEventListener('contextmenu', function(e) { + spanMark.classList.toggle("ignore"); + e.preventDefault(); + e.stopPropagation(); + }); }catch(e){}; self._spanMarkPool[item.src] = spanMark; } @@ -17758,7 +17773,7 @@ ImgOps | https://imgops.com/#b#`; }, 300); }, exportImages: function () {// 导出所有图片到新窗口 - var nodes = this.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]'),i; + var nodes = this.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]:not(.ignore)'),i; var arr=[]; for (i = 0; i < nodes.length; ++i) { @@ -17828,7 +17843,7 @@ ImgOps | https://imgops.com/#b#`; } }, copyImages: function(isAlert) { - var nodes = this.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]'); + var nodes = this.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]:not(.ignore)'); var urls = []; [].forEach.call(nodes, function(node){ if(unsafeWindow.getComputedStyle(node).display!="none"){ @@ -18716,6 +18731,7 @@ ImgOps | https://imgops.com/#b#`; .pv-gallery-maximize-container>.maximizeChild:hover img {\ transform: scale3d(1.1, 1.1, 1.1);\ filter: brightness(1.1) !important;\ + opacity: 1;\ }\ .pv-gallery-maximize-container.pv-gallery-flex-maximize>.maximizeChild:hover img {\ transform: translateY(-50%) scale3d(1.1, 1.1, 1.1);\ @@ -18733,6 +18749,7 @@ ImgOps | https://imgops.com/#b#`; word-break: break-all;\ display: inline;\ margin: 0 auto;\ + transition:all 0.2s;\ }\ .pv-gallery-maximize-container span>p.pv-bottom-banner{\ bottom: 0;\ @@ -18753,7 +18770,10 @@ ImgOps | https://imgops.com/#b#`; cursor: pointer;\ }\ .pv-gallery-maximize-container span:hover>p{\ - opacity: 1;\ + opacity: 1!important;\ + }\ + .pv-gallery-maximize-container span>p:hover{\ + background: #000000cc;\ }\ .pv-gallery-maximize-container span>p.pv-bottom-banner:hover{\ color:red;\ @@ -18762,6 +18782,7 @@ ImgOps | https://imgops.com/#b#`; .pv-gallery-maximize-container span>input{\ position: absolute;\ top: 2px;\ + z-index:1;\ width: 20px;\ height: 20px;\ opacity: 0;\ @@ -18769,6 +18790,13 @@ ImgOps | https://imgops.com/#b#`; display: inline;\ cursor: pointer;\ }\ + .pv-gallery-maximize-container.checked img,\ + .pv-gallery-maximize-container.checked p{\ + opacity: 0.3;\ + }\ + .pv-gallery-maximize-container.checked input:checked+img {\ + opacity: 1;\ + }\ .pv-gallery-maximize-container.checked span>input{\ opacity: 1;\ }\ @@ -19019,6 +19047,9 @@ ImgOps | https://imgops.com/#b#`; -webkit-transition:all 0.2s ease-in-out;\ transition:all 0.2s ease-in-out;\ }\ + span.pv-gallery-sidebar-thumb-container.ignore {\ + opacity: 0.5;\ + }\ .pv-gallery-sidebar-thumbnails-container-h .pv-gallery-sidebar-thumb-container {\ margin:0 2px;\ height:100%;\ diff --git a/Picviewer CE+/pvcep_pdf_addon.user.js b/Picviewer CE+/pvcep_pdf_addon.user.js new file mode 100644 index 00000000000..3475e2de312 --- /dev/null +++ b/Picviewer CE+/pvcep_pdf_addon.user.js @@ -0,0 +1,61 @@ +// ==UserScript== +// @name Picviewer CE+ PDF addon +// @name:zh-CN Picviewer CE+ PDF 扩展 +// @name:zh-TW Picviewer CE+ PDF 擴充 +// @namespace https://github.com/hoothin/UserScripts +// @version 2024-06-20 +// @description Batch Download as PDF instead of ZIP +// @description:zh-CN 取代 ZIP, 打包下载时下载为 PDF +// @description:zh-TW 取代 ZIP, 打包下載時下載為 PDF +// @author hoothin +// @match *://*/* +// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== +// @grant unsafeWindow +// @require https://unpkg.com/jspdf@latest/dist/jspdf.umd.min.js +// ==/UserScript== + +(function() { + 'use strict'; + async function blobToDataURL(blob) { + return new Promise((resolve) => { + var a = new FileReader(); + a.readAsDataURL(blob); + a.onload = function (e) { + resolve(e.target.result); + }; + a.onerror = function (e) { + resolve(null); + }; + }); + } + + function img2pdf(pdfName) { + if (!(this instanceof img2pdf)) { + return new img2pdf(); + } + this.fileList = []; + this.file = async (fileName, blob) => { + this.fileList.push([fileName, blob]); + }; + this.generateAsync = async (config, progress) => { + const pdf = new window.jspdf.jsPDF(); + const fileLength = this.fileList.length; + for (const [key, param] of this.fileList.entries()) { + const fileName = param[0]; + let blob = param[1]; + let dataUrl = await blobToDataURL(blob); + const imgProps = pdf.getImageProperties(dataUrl); + const pdfWidth = pdf.internal.pageSize.getWidth(); + const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width; + pdf.addImage(dataUrl, blob.type, 0, 0, pdfWidth, pdfHeight); + progress({percent: (key + 1) / fileLength * 100, currentFile: fileName}); + if (key + 1 < fileLength) { + pdf.addPage(); + } + } + pdf.save(pdfName); + }; + } + const _unsafeWindow = typeof unsafeWindow === 'undefined' ? window : unsafeWindow; + _unsafeWindow.pvcepimg2pdf = img2pdf; +})(); \ No newline at end of file From 7eadc14ce47e24832562744a45715083fbd214d4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 20:08:38 +0800 Subject: [PATCH 0108/1065] Update README.md --- Picviewer CE+/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index ee3c9d4b92a..6a428d80db4 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -23,6 +23,7 @@ If you are glad to assist with the translation, please [🌐edit this file](http Need more rules for peculiar sites? feel free to pull requests or open issues. +[Picviewer CE+ PDF Addon](https://greasyfork.org/scripts/498445-picviewer-ce-pdf-addon) After installing this addon, when the `Compress to ZIP` feature is enabled, a PDF file will be generated instead of a ZIP file during the packaging process. ## 🔧 Custom [Rules Example](pvcep_rules.js): **💝 Buy me a coffee with [Ko-fi](https://ko-fi.com/hoothin) or [愛發電](https://afdian.net/a/hoothin) to keep my scripts always up to date.** From 4707559200f3ecc08f38eaf4612902c7390fc448 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 20:30:41 +0800 Subject: [PATCH 0109/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 9767fac7154..29a7d83373c 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.20.3 +// @version 2024.6.20.4 // @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 @@ -16685,6 +16685,7 @@ ImgOps | https://imgops.com/#b#`; this._dataCache = {}; this.eleMaps['maximize-container'].innerHTML = createHTML(""); } + var self = this; var urlReg=new RegExp(this.urlFilter); var createSpanMark = item => { var spanMark=self._spanMarkPool[item.src]; @@ -16709,9 +16710,23 @@ ImgOps | https://imgops.com/#b#`; spanMark.innerHTML=createHTML('' + ''); spanMark.addEventListener('contextmenu', function(e) { - spanMark.classList.toggle("ignore"); e.preventDefault(); e.stopPropagation(); + spanMark.classList.toggle("ignore"); + if ((e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) && self.lastMark && self.lastMark !== spanMark && self.lastMark.parentNode === spanMark.parentNode) { + const children = Array.from(thumbnails.children); + let current; + if (children.indexOf(self.lastMark) < children.indexOf(spanMark)) { + current = self.lastMark.nextElementSibling; + } else { + current = spanMark.nextElementSibling; + } + while (current !== null && current !== self.lastMark && current !== spanMark) { + current.classList.toggle("ignore"); + current = current.nextElementSibling; + } + } + self.lastMark = spanMark; }); }catch(e){}; self._spanMarkPool[item.src] = spanMark; @@ -19935,7 +19950,11 @@ ImgOps | https://imgops.com/#b#`; debug(self); return; } - downloadImg(self.img.src, (self.data.img.title || self.data.img.alt), prefs.saveName); + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { + _GM_openInTab(self.img.src, {active:false}); + } else { + downloadImg(self.img.src, (self.data.img.title || self.data.img.alt), prefs.saveName); + } }); //关闭 From 48db09f789eb376f61c44594669497864d0d3aa2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Jun 2024 21:20:46 +0800 Subject: [PATCH 0110/1065] wait --- Picviewer CE+/Picviewer CE+.user.js | 15 ++------------- Picviewer CE+/pvcep_pdf_addon.user.js | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 29a7d83373c..0c61fb67a72 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.20.4 +// @version 2024.6.20.5 // @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 @@ -15802,17 +15802,6 @@ ImgOps | https://imgops.com/#b#`; targetImgSpan.scrollIntoView({behavior: "smooth", block: "center", inline: "nearest"}); setTimeout(() => {targetImgSpan.scrollIntoView({block: "center", inline: "nearest"})}, 300); self.canScroll=true; - /*imgReady(targetImgSpan.querySelector("img").src,{ - ready:function(){ - self.curImgWin.remove(true); - let imgwin=new ImgWindowC(this); - imgwin.blur(true); - self.curImgWin.imgWindow.style.opacity=0; - self.curImgWin=imgwin; - self.curImgSpan=targetImgSpan; - self.canScroll=true; - } - });*/ }else{ self.canScroll=true; } @@ -15977,7 +15966,7 @@ ImgOps | https://imgops.com/#b#`; viewmoreBar.innerHTML = createHTML('✖'); viewmoreBar.parentNode.classList.add("showmore");//.backgroundColor = "#2a2a2a"; - var nodes = this.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]'); + var nodes = this.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]:not(.ignore)'); this.addViewmoreItem(nodes); this.bricksInstance.pack(); this.bricksInstance.resize(true); diff --git a/Picviewer CE+/pvcep_pdf_addon.user.js b/Picviewer CE+/pvcep_pdf_addon.user.js index 3475e2de312..0d0f51c7987 100644 --- a/Picviewer CE+/pvcep_pdf_addon.user.js +++ b/Picviewer CE+/pvcep_pdf_addon.user.js @@ -18,14 +18,16 @@ 'use strict'; async function blobToDataURL(blob) { return new Promise((resolve) => { - var a = new FileReader(); - a.readAsDataURL(blob); - a.onload = function (e) { - resolve(e.target.result); - }; - a.onerror = function (e) { - resolve(null); - }; + setTimeout(() => { + var a = new FileReader(); + a.readAsDataURL(blob); + a.onload = function (e) { + resolve(e.target.result); + }; + a.onerror = function (e) { + resolve(null); + }; + }, 0); }); } From 1d4d804dd58fa32b4a5d14eaa8ace5762505a4a1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 09:19:40 +0800 Subject: [PATCH 0111/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 0c61fb67a72..684ea5d977e 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -18621,7 +18621,7 @@ ImgOps | https://imgops.com/#b#`; color:#a1a1a1;\ white-space:nowrap;\ cursor:pointer;\ - z-index:1;\ + z-index: 2;\ display:none;\ height: 30px;\ width:30px;\ @@ -18637,6 +18637,7 @@ ImgOps | https://imgops.com/#b#`; .pv-gallery-maximize-container+p{\ position: fixed;\ width: 100%;\ + z-index: 2;\ text-align: center;\ pointer-events: none;\ margin-bottom: 45px;\ From eda93a01076aae7c40fe16f1a4b589ebc0801e9b Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 09:34:53 +0800 Subject: [PATCH 0112/1065] Update README.md --- Picviewer CE+/README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 6a428d80db4..4b660456f2a 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -24,6 +24,17 @@ If you are glad to assist with the translation, please [🌐edit this file](http Need more rules for peculiar sites? feel free to pull requests or open issues. [Picviewer CE+ PDF Addon](https://greasyfork.org/scripts/498445-picviewer-ce-pdf-addon) After installing this addon, when the `Compress to ZIP` feature is enabled, a PDF file will be generated instead of a ZIP file during the packaging process. +
    +Make a PDF e-book with this addon + + For example, if there is a website with images from `xxx.com/1.jpg` to `xxx.com/99.jpg`, you can use this addon to generate a beautiful PDF e-book as follows: +1. Open the gallery by pressing Ctrl + g +2. In the `Command` menu, find and click "Add image" +3. Input `xxx.com/[1-99].jpg` +4. Right-click in the thumbnail frame below to ignore any unwanted images +5. Click `Download all shown` in the `Command` menu +This way, you'll get a beautifully created PDF e-book. +
    ## 🔧 Custom [Rules Example](pvcep_rules.js): **💝 Buy me a coffee with [Ko-fi](https://ko-fi.com/hoothin) or [愛發電](https://afdian.net/a/hoothin) to keep my scripts always up to date.** From 9e386d189c29644bd00fd834ea8f8ebfd4246498 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 09:38:23 +0800 Subject: [PATCH 0113/1065] Update README.md --- Picviewer CE+/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 4b660456f2a..3a091307ff8 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -29,10 +29,11 @@ Need more rules for peculiar sites? feel free to pull requests or open issues. For example, if there is a website with images from `xxx.com/1.jpg` to `xxx.com/99.jpg`, you can use this addon to generate a beautiful PDF e-book as follows: 1. Open the gallery by pressing Ctrl + g -2. In the `Command` menu, find and click "Add image" +2. In the `Command` menu, find and click `Add image` 3. Input `xxx.com/[1-99].jpg` 4. Right-click in the thumbnail frame below to ignore any unwanted images 5. Click `Download all shown` in the `Command` menu + This way, you'll get a beautifully created PDF e-book.
    From fb72853376591d4dab8ee0b99869edadab1c25fb Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 09:41:28 +0800 Subject: [PATCH 0114/1065] Update README.md --- Picviewer CE+/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 3a091307ff8..af09ed25b12 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -15,6 +15,10 @@ + View long image by scroll +## Usage + +Hover your mouse over any image and click the icons on the float bar. + Press `CTRL + G` to quickly enter the gallery. Hold `CTRL` to view a larger picture when hovering over images or links. There are additional settings available in the "Picviewer CE+ config" for further customization. Currently, reviewing these settings is the best way to learn about the script's capabilities. Try exploring more functions on your own! From e044594b61cc83314b1cb75e141562bd0fa17dd6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 10:06:54 +0800 Subject: [PATCH 0115/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index cdf94eced9b..8a4651bfdc2 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1634,5 +1634,21 @@ var siteInfo = [ url: ".thumb-image>a", query: ".single-image>img" } + }, + { + name: "postimg host", + src: /^https:\/\/i\.postimg\.cc/, + xhr: { + url: "a[href^='https://postimg.cc/']", + query: "#main-image" + } + }, + { + name: "postimg", + url: /^https:\/\/postimg\.cc/, + xhr: { + url: ".thumb>a", + query: "#main-image" + } } ]; From 62e42f176cbc5198d9c92233fa924a6dcc5645a1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 10:10:11 +0800 Subject: [PATCH 0116/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 684ea5d977e..8763f0f5b26 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.20.5 +// @version 2024.6.21.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 @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1397366/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1397893/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1391048/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 @@ -23235,6 +23235,7 @@ ImgOps | https://imgops.com/#b#`; },100); }, open:async function(e,buttonType){ + if (!this.data || !this.data.imgSrc) return; if (this.data.imgSrc.indexOf("blob:") === 0) { let blobUrl = await getBase64FromBlobUrl(this.data.imgSrc); if (blobUrl) { @@ -24326,14 +24327,14 @@ ImgOps | https://imgops.com/#b#`; throwErrorInfo(ex); } if (nsrc) { - let src = nsrc, imgSrc = nsrc; + let src = nsrc, imgSrc = prefs.floatBar.listenBg && hasBg(target) ? targetBg : nsrc; if (Array.isArray(nsrc) && nsrc.length == 2) { imgSrc = nsrc[0]; src = nsrc[1]; } result = { src: src, - type: matchedRule.xhrLink ? "link" : "rule", + type: matchedRule.xhrLink && !targetBg ? "link" : "rule", imgSrc: imgSrc, noActual: src === imgSrc, img: target, From ab402e3fbd3b73df37699d052093112b13c98d7d Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 11:02:37 +0800 Subject: [PATCH 0117/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 8763f0f5b26..ad260b315bb 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.21.1 +// @version 2024.6.21.2 // @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 @@ -16951,7 +16951,7 @@ ImgOps | https://imgops.com/#b#`; } }, keyUpListener:function(e){ - if (e.ctrlKey || e.metaKey) return; + if (e.ctrlKey || e.metaKey || e.altKey) return; const key = e.key || String.fromCharCode(e.keyCode); if (e.target != this.gallery) return; switch(key.toLowerCase()){ @@ -16969,6 +16969,7 @@ ImgOps | https://imgops.com/#b#`; break; case prefs.floatBar.keys.actual: case prefs.floatBar.keys.current: + if (e.shiftKey) return; imgReady(this.src,{ ready:function(){ new ImgWindowC(this); @@ -16976,6 +16977,7 @@ ImgOps | https://imgops.com/#b#`; }); break; case prefs.floatBar.keys.download: + if (e.shiftKey) return; downloadImg(this.img.src, this.selected.title, prefs.saveName); break; } @@ -23235,7 +23237,7 @@ ImgOps | https://imgops.com/#b#`; },100); }, open:async function(e,buttonType){ - if (!this.data || !this.data.imgSrc) return; + if (!this.shown || !this.data || !this.data.imgSrc) return; if (this.data.imgSrc.indexOf("blob:") === 0) { let blobUrl = await getBase64FromBlobUrl(this.data.imgSrc); if (blobUrl) { From 7d45fa62a40bb17c3e0bc503990c0612aeddb9cc Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 11:12:35 +0800 Subject: [PATCH 0118/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index ad260b315bb..1882df6b0c7 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.21.2 +// @version 2024.6.21.3 // @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 @@ -22889,8 +22889,8 @@ ImgOps | https://imgops.com/#b#`; }; if(!buttonType)return; - self.hide(); self.open(e,buttonType); + self.hide(); },true); From fe121053948e83dfa602850e62d9fb5123df89d6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 11:20:04 +0800 Subject: [PATCH 0119/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 1882df6b0c7..ca485b47b80 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -23250,6 +23250,7 @@ ImgOps | https://imgops.com/#b#`; } } if (buttonType === 'download' && !this.data.xhr) { + if (e.ctrlKey || e.metaKey || e.altKey || e.shiftKey) return; downloadImg(this.data.src || this.data.imgSrc, (this.data.img.title || this.data.img.alt), prefs.saveName); return; } else { From 9ec6559671b5b8a6d011aac1b6a8f2c99909f693 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 15:51:15 +0800 Subject: [PATCH 0120/1065] 1.9.37.62 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 61 +++++++++++++++++++++++++++---------- Pagetual/pagetualRules.json | 13 ++++++++ 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index ff1850813f9..12a677488b8 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.61](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.62](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index ce82fe31f51..ae5542a10b9 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.61 +// @version 1.9.37.62 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -5750,7 +5750,7 @@ margin-bottom: 0px; } #configCon #saveBtn { - margin-bottom: -40px; + margin-bottom: -30px; } #configCon.showSave #saveBtn { margin-bottom: 0px; @@ -6940,28 +6940,35 @@ onload: async function(res) { if (isPause) return callback(false); var doc = null, response = res.response; - let preCode = ruleParser.curSiteRule.pageElementPre || ruleParser.curSiteRule.pagePre; + try { + doc = document.implementation.createHTMLDocument(''); + doc.documentElement.innerHTML = response; + } catch (e) { + debug('parse error:' + e.toString()); + } + let pageElement = null; + let preCode = ruleParser.curSiteRule.pagePre; if (preCode) { try { + let preResult; if (typeof preCode == 'function') { - response = preCode(response); + preResult = await preCode(response, doc); } else if (preCode.length == 2) { - response = response.replace(new RegExp(preCode[0], "gi"), preCode[1]); + preResult = response.replace(new RegExp(preCode[0], "gi"), preCode[1]); } else { - response = Function("response",'"use strict";' + preCode)(response); + preResult = await new AsyncFunction("response", "doc", '"use strict";' + preCode)(response, doc); + } + if (preResult) { + if (typeof preResult === "string") { + doc.documentElement.innerHTML = preResult; + } else pageElement = preResult; } } catch(e) { debug(e); } } - try { - doc = document.implementation.createHTMLDocument(''); - doc.documentElement.innerHTML = response; - let base = doc.querySelector("base"); - ruleParser.basePath = base ? base.href : url; - } catch (e) { - debug('parse error:' + e.toString()); - } + let base = doc.querySelector("base"); + ruleParser.basePath = base ? base.href : url; if (charsetValid && !ruleHeaders) { let equiv = doc.querySelector('[http-equiv="Content-Type"]'); if (equiv && equiv.content) { @@ -6972,7 +6979,9 @@ } } } - let pageElement = ruleParser.getPageElement(doc); + if (pageElement === null) { + pageElement = ruleParser.getPageElement(doc); + } if ((!pageElement || pageElement.length == 0) && res.status >= 400) { debug(res.status + " " + url, "Error status"); return callback(false); @@ -8394,9 +8403,29 @@ }, waitTime); return; } else { + let preCode = ruleParser.curSiteRule.pagePre, eles = null; + if (preCode) { + try { + let preResult; + if (typeof preCode == 'function') { + preResult = await preCode(doc.documentElement.innerHTML, doc); + } else if (preCode.length == 2) { + preResult = doc.documentElement.innerHTML.replace(new RegExp(preCode[0], "gi"), preCode[1]); + } else { + preResult = await new AsyncFunction("response", "doc", '"use strict";' + preCode)(doc.documentElement.innerHTML, doc); + } + if (preResult) { + if (typeof preResult === "string") { + doc.documentElement.innerHTML = preResult; + } else eles = preResult; + } + } catch(e) { + debug(e); + } + } let base = doc.querySelector("base"); ruleParser.basePath = base ? base.href : url; - let eles = ruleParser.getPageElement(doc, iframe.contentWindow, pageEleTryTimes < 25); + if (eles === null) eles = ruleParser.getPageElement(doc, iframe.contentWindow, pageEleTryTimes < 25); if (eles && eles.length > 0) { await ruleParser.hookUrl(doc); await callback(doc, eles); diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 1ef9e45b0f1..077308e3c85 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -7432,5 +7432,18 @@ "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}


  • `;eles.push(ele);});return eles;" } ] From 7db0d59d45c257c18f61c5d4015d3ad2f564b720 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Fri, 21 Jun 2024 07:51:33 +0000 Subject: [PATCH 0121/1065] Update version of Pagetual rules to 31 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 64bb6b746dc..e85087affde 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -30 +31 From 4cb4e8a46e0c6912d22d09b99328959a3c665d89 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 16:01:34 +0800 Subject: [PATCH 0122/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index ae5542a10b9..8d54742fab2 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -4277,7 +4277,7 @@ bottom.addEventListener("click", e => { if (!e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey) { - changeStop(true); + changeStop(true, true); } let scrollH = Math.max(document.documentElement.scrollHeight, getBody(document).scrollHeight); getBody(document).scrollTop = scrollH || 9999999; @@ -4290,14 +4290,14 @@ let removeTimer; move.addEventListener("click", e => { if (!moving) { - changeStop(!isPause); + changeStop(!isPause, true); } }, true); move.addEventListener("dblclick", e => { clearTimeout(removeTimer); document.removeEventListener("mousemove", mouseMoveHandler, true); document.removeEventListener("mouseup", mouseUpHandler, true); - changeStop(!isPause); + changeStop(!isPause, true); if (isPause) { ruleParser.hideAddedElements(); } else { @@ -6856,11 +6856,11 @@ if (forceState == 1) { forceState = 0; showTips(i18n("enableSiteTips")); - changeStop(false); + changeStop(false, true); } else { forceState = 1; showTips(i18n("disableSiteTips")); - changeStop(true); + changeStop(true, true); sideController.remove(); } setListData("forceState", location.host, forceState); @@ -7318,7 +7318,7 @@ var tipsWords = document.createElement("div"); tipsWords.className = "pagetual_tipsWords"; - function changeStop(stop) { + function changeStop(stop, save) { isPause = stop; [].forEach.call(getBody(document).querySelectorAll(".pagetual_pageBar,#pagetual-sideController"), bar => { if (isPause) { @@ -7329,7 +7329,7 @@ }); if (!isPause) ruleParser.showAddedElements(); manualPause = isPause; - if (sideController.inited) setListData("pauseState", location.host, isPause ? true : ""); + if (save && sideController.inited) setListData("pauseState", location.host, isPause ? true : ""); } function changeHideBar(hide) { @@ -7679,7 +7679,7 @@ changeHideBar(!isHideBar); } if (!rulesData.hideBarButNoStop) { - changeStop(!isPause); + changeStop(!isPause, true); showTips(i18n(isPause ? "disable" : "enable")); } if (!isPause) { @@ -7711,11 +7711,11 @@ if (forceState == 1) { forceState = 0; showTips(i18n("enableSiteTips")); - changeStop(false); + changeStop(false, true); } else { forceState = 1; showTips(i18n("disableSiteTips")); - changeStop(true); + changeStop(true, true); sideController.remove(); } if (!ruleParser.curSiteRule.url) { @@ -8145,7 +8145,7 @@ }); downSpan.addEventListener("click", e => { if (!e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey) { - changeStop(true); + changeStop(true, true); } pageBar.title = i18n(isPause ? "enable" : "disable"); scrollH = Math.max(document.documentElement.scrollHeight, getBody(document).scrollHeight); @@ -8155,7 +8155,7 @@ e.stopPropagation(); }); pageBar.addEventListener("click", e => { - changeStop(!isPause); + changeStop(!isPause, true); pageBar.title = i18n(isPause ? "enable" : "disable"); }); ruleParser.insertElement(pageBar); From be1198abd9c2f81f8bd82a39bcc047d33a51d43f Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 18:37:40 +0800 Subject: [PATCH 0123/1065] Update pvcep_pdf_addon.user.js --- Picviewer CE+/pvcep_pdf_addon.user.js | 29 +++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/pvcep_pdf_addon.user.js b/Picviewer CE+/pvcep_pdf_addon.user.js index 0d0f51c7987..f886aac0a41 100644 --- a/Picviewer CE+/pvcep_pdf_addon.user.js +++ b/Picviewer CE+/pvcep_pdf_addon.user.js @@ -3,14 +3,18 @@ // @name:zh-CN Picviewer CE+ PDF 扩展 // @name:zh-TW Picviewer CE+ PDF 擴充 // @namespace https://github.com/hoothin/UserScripts -// @version 2024-06-20 +// @version 2024-06-21 // @description Batch Download as PDF instead of ZIP // @description:zh-CN 取代 ZIP, 打包下载时下载为 PDF // @description:zh-TW 取代 ZIP, 打包下載時下載為 PDF // @author hoothin // @match *://*/* -// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== +// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @grant unsafeWindow +// @grant GM_registerMenuCommand +// @grant GM_unregisterMenuCommand +// @grant GM_getValue +// @grant GM_setValue // @require https://unpkg.com/jspdf@latest/dist/jspdf.umd.min.js // ==/UserScript== @@ -43,8 +47,12 @@ const pdf = new window.jspdf.jsPDF(); const fileLength = this.fileList.length; for (const [key, param] of this.fileList.entries()) { - const fileName = param[0]; + let fileName = param[0]; let blob = param[1]; + if (!blob && this.fileList.length === 1) { + fileName = this.fileList[0][0]; + blob = this.fileList[0][1]; + } let dataUrl = await blobToDataURL(blob); const imgProps = pdf.getImageProperties(dataUrl); const pdfWidth = pdf.internal.pageSize.getWidth(); @@ -58,6 +66,19 @@ pdf.save(pdfName); }; } + const _unsafeWindow = typeof unsafeWindow === 'undefined' ? window : unsafeWindow; - _unsafeWindow.pvcepimg2pdf = img2pdf; + let disabled = !!GM_getValue("pvcep_pdf_disabled"), registerId; + function registerMenuCommand() { + if (disabled) { + _unsafeWindow.pvcepimg2pdf = null; + } else _unsafeWindow.pvcepimg2pdf = img2pdf; + registerId = GM_registerMenuCommand(disabled ? "Enable addon" : "Disable addon", () => { + GM_unregisterMenuCommand(registerId); + disabled = !disabled; + GM_setValue("pvcep_pdf_disabled", disabled); + registerMenuCommand(); + }); + } + registerMenuCommand(); })(); \ No newline at end of file From 1437dc8e667374c307eece9b6376b7cca0cf6ede Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 18:44:27 +0800 Subject: [PATCH 0124/1065] Update pvcep_pdf_addon.user.js --- Picviewer CE+/pvcep_pdf_addon.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_pdf_addon.user.js b/Picviewer CE+/pvcep_pdf_addon.user.js index f886aac0a41..bdee07cec8c 100644 --- a/Picviewer CE+/pvcep_pdf_addon.user.js +++ b/Picviewer CE+/pvcep_pdf_addon.user.js @@ -73,7 +73,7 @@ if (disabled) { _unsafeWindow.pvcepimg2pdf = null; } else _unsafeWindow.pvcepimg2pdf = img2pdf; - registerId = GM_registerMenuCommand(disabled ? "Enable addon" : "Disable addon", () => { + registerId = GM_registerMenuCommand(disabled ? "❌ Disabled" : "✅ Enabled", () => { GM_unregisterMenuCommand(registerId); disabled = !disabled; GM_setValue("pvcep_pdf_disabled", disabled); From d01396ec935d3647c9b87a81cbfce44efa5f683b Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 18:45:14 +0800 Subject: [PATCH 0125/1065] Update pvcep_pdf_addon.user.js --- Picviewer CE+/pvcep_pdf_addon.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_pdf_addon.user.js b/Picviewer CE+/pvcep_pdf_addon.user.js index bdee07cec8c..3e6a8bbcfbe 100644 --- a/Picviewer CE+/pvcep_pdf_addon.user.js +++ b/Picviewer CE+/pvcep_pdf_addon.user.js @@ -3,7 +3,7 @@ // @name:zh-CN Picviewer CE+ PDF 扩展 // @name:zh-TW Picviewer CE+ PDF 擴充 // @namespace https://github.com/hoothin/UserScripts -// @version 2024-06-21 +// @version 2024-06-22 // @description Batch Download as PDF instead of ZIP // @description:zh-CN 取代 ZIP, 打包下载时下载为 PDF // @description:zh-TW 取代 ZIP, 打包下載時下載為 PDF From bfc4f0bdf64abfcfc13a15923fe64ac69925b905 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 19:24:03 +0800 Subject: [PATCH 0126/1065] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index db813579f47..34c34ce7056 100644 --- a/README.md +++ b/README.md @@ -38,5 +38,9 @@ +## Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=hoothin/UserScripts&type=Date)](https://star-history.com/#hoothin/UserScripts&Date) + ## Sponsors From 1103f4cb38f4af38b89ae57d6fdadb60be52278a Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 21:25:26 +0800 Subject: [PATCH 0127/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 077308e3c85..ae259faf883 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -6798,6 +6798,13 @@ "url": "^https?://forum\\.ru-board\\.com/", "nextLink": "table .small>b+a" }, +{ + "name": "Ru.Board", + "url": "^https?://forum\\.ru-board\\.com/", + "nextLink": "table .small>b+a", + "pageElement": "table.tb", + "include": "table.tb" +}, { "name": "淘宝已买到的宝贝", "url": "^https://buyertrade\\.taobao\\.com/", From 3748f4d0ab16d82d9452e2449671d8e402324d8b Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Fri, 21 Jun 2024 13:25:45 +0000 Subject: [PATCH 0128/1065] Update version of Pagetual rules to 32 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index e85087affde..f5c89552bd3 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -31 +32 From 08a0c1676d394203335e4a6d905d5b8241f87937 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Jun 2024 21:28:06 +0800 Subject: [PATCH 0129/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index ae259faf883..dd1282bd6df 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -6796,7 +6796,8 @@ { "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", From dc59ff8e5dbc2ff2f53c2e718e7a104a58e4894e Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Fri, 21 Jun 2024 13:28:48 +0000 Subject: [PATCH 0130/1065] Update version of Pagetual rules to 33 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index f5c89552bd3..bb95160cb6e 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -32 +33 From 32cea86daf6a57c1e5dd100a2fd57ffa3ac67be4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 09:14:02 +0800 Subject: [PATCH 0131/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 11747206593..64a61301d52 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -430,7 +430,7 @@ switch (lang) { }, { "name": "Google advanced", - "url": "https://www.google.com/search?q=%s%input{Filetype, filetype:doc/ filetype:ppt/ filetype:xls/ filetype:pdf}%input{Limit lang/zh-CN/zh-TW/zh-ALL/JA/EN,&lr=lang_zh-CN/&lr=lang_zh-TW/&lr=lang_zh-CN|lang_zh-TW/&lr=lang_ja/&lr=lang_en}%input{Limit date/Last hour/Last day/Last week/Last month/Last year,&as_qdr=h1/&as_qdr=d1/&as_qdr=w1/&as_qdr=m1/&as_qdr=y1}&ie=utf-8&oe=utf-8", + "url": "https://www.google.com/search?q=%sr.replace(/ \\w+:.*/,\"\")%input{In site/Reddit/Engadget, site:reddit.com/ site:engadget.com}%input{Filetype, filetype:doc/ filetype:ppt/ filetype:xls/ filetype:pdf/ filetype:txt}%input{Limit lang/Japanese/zh-CN/zh-TW/ZH/EN,&lr=lang_ja/&lr=lang_zh-CN/&lr=lang_zh-TW/&lr=lang_zh-CN|lang_zh-TW/&lr=lang_en}%input{Limit date/Last hour/Last day/Last week/Last month/Last year,&as_qdr=h1/&as_qdr=d1/&as_qdr=w1/&as_qdr=m1/&as_qdr=y1}&ie=utf-8&oe=utf-8", "match": "https://www\\.google\\..*/search((?!udm=2).)*$", "hideNotMatch": true }, From 902f6973b756ca5e86c5921c0de983e560bcb7d9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 09:33:00 +0800 Subject: [PATCH 0132/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 8a4651bfdc2..901aed8ac46 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1650,5 +1650,17 @@ var siteInfo = [ url: ".thumb>a", query: "#main-image" } + }, + { + name: "imagebam", + src: /^https:\/\/thumbs\d*\.imagebam\.com\//, + xhr: { + url: function(a, p) { + let imageId = this.src.match(/\/(\w+)\_\w\./); + if (!imageId) return null; + return `https://www.imagebam.com/view/${imageId[1]}`; + }, + query: ".main-image" + } } ]; From a7ee5ad00d614787e96d3524585003f7f24e9229 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 09:33:46 +0800 Subject: [PATCH 0133/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 66 ++++++++++++++++------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index ca485b47b80..e983f290539 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.21.3 +// @version 2024.6.22.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 @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1397893/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1398555/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1391048/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 @@ -15435,15 +15435,19 @@ ImgOps | https://imgops.com/#b#`; //console.debug(meta); this.showTips(parseInt(meta.percent)+"% Compress "+(meta.currentFile||""), 100000); }, - batchDownload:function(saveParams, callback){ - var self=this; - if(prefs.gallery.downloadWithZip){ + batchDownload: function(saveParams, callback) { + var self = this; + if (prefs.gallery.downloadWithZip) { self.showTips(i18n("galleryDownloadWithZipAlert"), 100000); - var zip,downloaded=0, pdf=!!unsafeWindow.pvcepimg2pdf; - var fileName = document.title + (pdf ? ".pdf" : ".zip"); - if (pdf) { - zip = new unsafeWindow.pvcepimg2pdf(fileName); + var zip, downloaded = 0, ext, packName = document.title; + if (unsafeWindow.pvcepPackAddon) { + packName += "." + unsafeWindow.pvcepPackAddon.ext; + zip = new unsafeWindow.pvcepPackAddon.pack(packName); + } else if (!!unsafeWindow.pvcepimg2pdf) { + packName += ".pdf"; + zip = new unsafeWindow.pvcepimg2pdf(packName); } else { + packName += ".zip"; zip = new JSZip(); } var len = saveParams.length; @@ -15460,10 +15464,10 @@ ImgOps | https://imgops.com/#b#`; downloaded++; self.showTips("Downloading "+downloaded+"/"+len, 1000000); if(downloaded == len){ - self.showTips(`Begin compress to ${pdf ? 'PDF' : 'ZIP'}...`, 100000); + self.showTips(`Begin compress to ${packName}...`, 100000); zip.generateAsync({type:"blob"}, meta=>{self.showCompressProgress(meta)}).then(function(content){ if (content) { - saveAs(content, fileName); + saveAs(content, packName); } callback(); }) @@ -15481,10 +15485,10 @@ ImgOps | https://imgops.com/#b#`; zip.file(imgName.replace(/^data:.*/, "img").replace(/\//g,""), blob); downloaded++; if(downloaded == len){ - self.showTips(`Begin compress to ${pdf ? 'PDF' : 'ZIP'}...`, 100000); + self.showTips(`Begin compress to ${packName}...`, 100000); zip.generateAsync({type:"blob"}, meta=>{self.showCompressProgress(meta)}).then(function(content){ if (content) { - saveAs(content, fileName); + saveAs(content, packName); } callback(); }) @@ -23722,22 +23726,6 @@ ImgOps | https://imgops.com/#b#`; console.log(e); } } - if (unsafeWindow.pvcepRules && Array.isArray(unsafeWindow.pvcepRules)) { - unsafeWindow.pvcepRules.forEach(rule => { - rule.custom = true; - let hasRule = false; - for (let s = 0; s < siteInfo.length; s++) { - if (siteInfo[s].name == rule.name) { - hasRule = true; - for (let si in rule) { - siteInfo[s][si] = rule[si]; - } - break; - } - } - if (!hasRule) siteInfo.unshift(rule); - }) - } var self = this, r = 0, urlChecked = false; self.rules=[]; @@ -23855,7 +23843,25 @@ ImgOps | https://imgops.com/#b#`; } },1); } - searchByTime(); + setTimeout(() => { + if (unsafeWindow.pvcepRules && Array.isArray(unsafeWindow.pvcepRules)) { + unsafeWindow.pvcepRules.forEach(rule => { + rule.custom = true; + let hasRule = false; + for (let s = 0; s < siteInfo.length; s++) { + if (siteInfo[s].name == rule.name) { + hasRule = true; + for (let si in rule) { + siteInfo[s][si] = rule[si]; + } + break; + } + } + if (!hasRule) siteInfo.unshift(rule); + }) + } + searchByTime(); + }, 1); }, replace:function(str, r, s){ var results=[],rt; From d84dd51d3eb7e8b3338654dd5517586f6e5be1b5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 09:47:12 +0800 Subject: [PATCH 0134/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index e983f290539..2de1523669b 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.22.1 +// @version 2024.6.22.2 // @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 @@ -23926,6 +23926,8 @@ ImgOps | https://imgops.com/#b#`; var base64Img = /^data:/i.test(img.src); for (var i = 0; i < this.rules.length; i++) { rule = this.rules[i]; + if (rule.src && !toRE(rule.src).test(img.src)) continue; + if (rule.exclude && toRE(rule.exclude).test(img.src)) continue; if (rule.xhr) { if (rule.xhr.url) { if (rule.xhr.url.test) { @@ -23954,8 +23956,6 @@ ImgOps | https://imgops.com/#b#`; } } if (base64Img && (!rule.url || !rule.getImage)) continue; - if (rule.src && !toRE(rule.src).test(img.src)) continue; - if (rule.exclude && toRE(rule.exclude).test(img.src)) continue; if (newSrc) { this.xhr = rule.xhr; return newSrc; From b244c5fd98f351f330c190ebc5fb3abfa83944fa Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 22 Jun 2024 01:56:21 +0000 Subject: [PATCH 0135/1065] Update items_all.json from http://wedata.net/databases/AutoPagerize/items_all.json --- Pagetual/items_all.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pagetual/items_all.json b/Pagetual/items_all.json index c7696b00892..df65f78aa80 100644 --- a/Pagetual/items_all.json +++ b/Pagetual/items_all.json @@ -19327,7 +19327,7 @@ "resource_url": "http://wedata.net/items/77750", "data": { "pageElement": "//ul[contains(concat(' ',@class,' '),' c-up-panel__list ')]/li", - "nextLink": "//div[@class='c-pager']/span[contains(concat(' ',@class,' '),' is-current ')]/following-sibling::a", + "nextLink": "//div[contains(concat(' ',@class,' '),' c-up-pager ')]//span[contains(concat(' ',@class,' '),' is-current ')]/following-sibling::a", "url": "^https?://syosetu\\.com/", "exampleUrl": "https://syosetu.com/favnovelmain/list/?nowcategory=1&order=newlist\r\nhttps://syosetu.com/favnovelmain/isnoticelist/\r\nhttps://syosetu.com/usernovelimpression/list/\r\nhttps://syosetu.com/favuser/list/\r\nhttps://syosetu.com/messagebox/top/" }, @@ -19335,7 +19335,7 @@ "created_by": "phodra", "name": "小説家になろう ユーザーページ", "created_at": "2016-01-04T01:43:02+09:00", - "updated_at": "2024-04-08T19:51:00+09:00" + "updated_at": "2024-06-22T07:58:54+09:00" }, { "resource_url": "http://wedata.net/items/77749", From a2c0265e95eda5d52b0d69c522f39e0fb7b90f15 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 22 Jun 2024 01:56:40 +0000 Subject: [PATCH 0136/1065] Update version of Pagetual rules to 34 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index bb95160cb6e..a7873645902 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -33 +34 From 7b26a518ab72317d08d0231f97faf4bfdab92a57 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 13:52:57 +0800 Subject: [PATCH 0137/1065] Update Switch Traditional Chinese and Simplified Chinese.user.js --- ...nal Chinese and Simplified Chinese.user.js | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js index 104f5f603e0..2c02c846ea6 100644 --- a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js +++ b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js @@ -6,7 +6,7 @@ // @namespace hoothin // @supportURL https://github.com/hoothin/UserScripts // @homepageURL https://github.com/hoothin/UserScripts -// @version 1.2.7.7 +// @version 1.2.7.8 // @description 任意轉換網頁中的簡體中文與正體中文(默認簡體→正體),顯示漢字對應漢語拼音,自訂任意替換文本 // @description:zh-CN 任意转换网页中的简体中文与繁体中文(默认繁体→简体),显示汉字对应汉语拼音,自定义任意替换文本 // @description:ja ウェブページ上の簡体字中国語と繁体字中国語を自由に変換し、中国語の文字にひらがなを表示し、任意の文字を置き換えることができます。 @@ -599,7 +599,6 @@ '凉水':'冰水', '打包':'外帶', '外卖':'外送', - '地道':'道地', '很火':'很紅', '宾馆':'飯店', '旅馆':'賓館', @@ -692,7 +691,6 @@ var lang = navigator.appName == "Netscape"?navigator.language:navigator.userLanguage; lang = lang.toLowerCase(); - //此處為補丁,因爲考慮到港澳臺繁體可能各有不同 switch(lang){ case "zh-tw": /*sc2tc["只"]=[ @@ -1353,7 +1351,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 +1379,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 +1408,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 +1482,7 @@ let customTermTitle = document.createElement('h3'); customTermTitle.style.margin = '5px 0'; - customTermTitle.innerText = '自定義簡繁用語轉換(可透過通配符設置生效網址範圍):'; + customTermTitle.innerText = '自訂簡繁用語轉換(可透過通配符設定生效網址範圍):'; let addNewGlob1 = document.createElement('button'); addNewGlob1.innerText = '添加生效網站'; @@ -1556,7 +1554,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 +1646,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'; @@ -1721,7 +1719,7 @@ storage.setItem('sc2tcCombTree', ""); storage.setItem('tc2scCombTree', ""); storage.setItem('fuckIlliteracyTree', ""); - alert('保存設置成功!'); + alert('保存設定成功!'); location.reload(); }); buttonCon.appendChild(saveBtn); @@ -1754,7 +1752,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,8 +1881,7 @@ 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); } From e22b68e358e459922a5d73b22d019db2d449577e Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 13:53:58 +0800 Subject: [PATCH 0138/1065] =?UTF-8?q?Create=20=E7=B0=A1=E7=B9=81=E8=BD=89?= =?UTF-8?q?=E6=8F=9B=20by=20Ch'=C3=BC=20Ts=C3=AA-t'ien.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...\233 by Ch'\303\274 Ts\303\252-t'ien.json" | 1665 +++++++++++++++++ 1 file changed, 1665 insertions(+) create mode 100644 "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" 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 From 0b569486020b7fa63ec08e28014371a9234a0ec5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 14:07:06 +0800 Subject: [PATCH 0139/1065] Update README.md --- Switch Traditional Chinese and Simplified Chinese/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Switch Traditional Chinese and Simplified Chinese/README.md b/Switch Traditional Chinese and Simplified Chinese/README.md index bcaabbe6278..c55260ffaee 100644 --- a/Switch Traditional Chinese and Simplified Chinese/README.md +++ b/Switch Traditional Chinese and Simplified Chinese/README.md @@ -8,6 +8,8 @@ + 可自定義用語轉換詞典 + 可透過通配符自定義生效網址,達成在不同網域套用不同用語詞典的效果 +[**Ch'ü Tsê-t'ien 的簡繁用語轉換配置文件**](https://hoothin.github.io/UserScripts/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese/%E7%B0%A1%E7%B9%81%E8%BD%89%E6%8F%9B%20by%20Ch'%C3%BC%20Ts%C3%AA-t'ien.json) 下載此檔案后在`自訂簡繁用語轉換`旁點擊按鈕匯入即可 + 我創建了一個sc2tc數組,裡面是一簡多繁的對照,有興趣的朋友可以修改並分享至[GITHUB](https://github.com/hoothin/UserScripts/blob/master/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese.user.js)。 如果你只是有更好的繁簡對照表,也歡迎提交給我。 From 6ed18277a52692d8e1b880067a09f3c09e2b25c9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 14:10:32 +0800 Subject: [PATCH 0140/1065] Update README.md --- .../README.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/README.md b/Switch Traditional Chinese and Simplified Chinese/README.md index c55260ffaee..c5fce6e05bb 100644 --- a/Switch Traditional Chinese and Simplified Chinese/README.md +++ b/Switch Traditional Chinese and Simplified Chinese/README.md @@ -1,16 +1,16 @@ -+ 默認自動切換至用戶所使用的默認語言 -+ `Ctrl + F8` 切換 **簡體中文** 與 **正體中文**(若輸入框為活動控件則只轉換輸入框内文字,框選文字時僅轉換對應文字且不會記憶) -+ 使用命令菜單中的 「繁簡切換【Ctrl + F8】」 可於當前網域禁用轉換 -+ 切換后會保存當前網站語言選擇 -+ 轉換頁面中所有的文字內容、描述字符、提示文字、標題等 -+ 支援在漢字上方顯示對應的漢語拼音字母 -+ 支援彈幕,以及動態插入的元素。 -+ 可自定義用語轉換詞典 -+ 可透過通配符自定義生效網址,達成在不同網域套用不同用語詞典的效果 ++ 預設會自動切換至使用者所使用的預設語言。 ++ 按下 `Ctrl + F8` 可在簡體中文與繁體中文之間切換(如果輸入框為活動控制項,則只有輸入框內的文字會被轉換;選取文字時,只有對應的文字會被轉換,且不會被記憶)。 ++ 使用命令選單中的「繁簡切換【Ctrl + F8】」功能可在當前網域禁用轉換。 ++ 切換語言後,會儲存目前網站的語言選擇。 ++ 可轉換頁面中所有的文字內容、描述字元、提示文字、標題等。 ++ 支援在漢字上方顯示對應的漢語拼音字母。 ++ 支援彈幕,以及動態插入的元素。 ++ 可自訂用語轉換詞典。 ++ 可透過通配符自訂生效網址,以在不同網域套用不同的用語詞典。 [**Ch'ü Tsê-t'ien 的簡繁用語轉換配置文件**](https://hoothin.github.io/UserScripts/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese/%E7%B0%A1%E7%B9%81%E8%BD%89%E6%8F%9B%20by%20Ch'%C3%BC%20Ts%C3%AA-t'ien.json) 下載此檔案后在`自訂簡繁用語轉換`旁點擊按鈕匯入即可 -我創建了一個sc2tc數組,裡面是一簡多繁的對照,有興趣的朋友可以修改並分享至[GITHUB](https://github.com/hoothin/UserScripts/blob/master/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese.user.js)。 +我建立了一個 sc2tc 陣列,其中包含了簡體中文到繁體中文的對照表。有興趣的朋友可以修改並分享至[GITHUB](https://github.com/hoothin/UserScripts/blob/master/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese.user.js)。 如果你只是有更好的繁簡對照表,也歡迎提交給我。 From c3f5cc43bbaf72ef0924b2cb3eb77a98b33ec12f Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 14:44:49 +0800 Subject: [PATCH 0141/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 63 +++++++++++++++++------------ 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 2de1523669b..29714aca98c 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.22.2 +// @version 2024.6.22.3 // @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 @@ -14594,14 +14594,13 @@ ImgOps | https://imgops.com/#b#`; media = document.createElement('video'); src = "video:" + src; } + media.title = file.name; var result = { src: src, type: 'force', imgSrc: src, - noActual:true, - description: '', - + description: file.name, img: media }; self.data.push(result); @@ -15319,31 +15318,45 @@ ImgOps | https://imgops.com/#b#`; container.style.display='none'; - container.addEventListener("drop", e => { + let allData = new Map(); + container.addEventListener("drop", async e => { e.preventDefault(); self.eleMaps['img-parent'].style.pointerEvents = ""; container.style.filter = ""; - var files = e.dataTransfer.files; + var files = [...e.dataTransfer.items].map( + item => item.getAsFileSystemHandle() + ); if (files.length) { - for (var i = 0; i < files.length; i++) { - let file = files.item(i); - file = files[i]; - let src = URL.createObjectURL(file); - let img=document.createElement('img'); - img.src=src; - var result = { - src: src, - type: 'force', - imgSrc: src, - - noActual:true, - description: '', - - img: img - }; - self.data.push(result); - self._appendThumbSpans([result]); + async function handle(items, dir = "") { + for await (let item of items) { + let name = item.name; + let path = dir + "/" + name; + if (allData.has(path)) continue; + if (item.kind === "directory") { + allData.set(path, true); + await handle(item.values(), path); + } else if (item.kind === "file") { + let file = await item.getFile(); + if (!file.type.match(/image.*/)) continue; + allData.set(path, true); + let src = URL.createObjectURL(file); + let img=document.createElement('img'); + img.src=src; + img.title=path; + var result = { + src: src, + type: 'force', + imgSrc: src, + noActual:true, + description: path, + img: img + }; + self.data.push(result); + self._appendThumbSpans([result]); + } + } } + await handle(files); self.loadThumb(); } }); @@ -16698,7 +16711,7 @@ ImgOps | https://imgops.com/#b#`; if (title.indexOf('http') === 0 || title.indexOf('data') === 0) title = ''; else title += '\n'; } - let itemSrc = item.src.replace(/^(data[^;]+).*/, "$1..."); + let itemSrc = item.src.replace(/^blob:.*/, "").replace(/^(data[^;]+).*/, "$1..."); spanMark.title = title + (itemSrc.length > 150 ? itemSrc.slice(0, 110) + " ... " + itemSrc.slice(-30) : itemSrc); spanMark.innerHTML=createHTML('' + ''); From b3ea1fd0c325ffd2519b54db1892875af7a9a53d Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 14:47:48 +0800 Subject: [PATCH 0142/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 29714aca98c..cd31064a858 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -18751,6 +18751,7 @@ ImgOps | https://imgops.com/#b#`; transform: scale3d(1, 1, 1);\ cursor: zoom-in;\ min-height: 88px;\ + border-radius: 10px;\ }\ .pv-gallery-maximize-container>.maximizeChild:hover img {\ transform: scale3d(1.1, 1.1, 1.1);\ From bee7be38871b9b524e728e65c162501051fad8ff Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 14:52:30 +0800 Subject: [PATCH 0143/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index cd31064a858..62165defe65 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.22.3 +// @version 2024.6.22.4 // @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 @@ -15337,19 +15337,27 @@ ImgOps | https://imgops.com/#b#`; await handle(item.values(), path); } else if (item.kind === "file") { let file = await item.getFile(); - if (!file.type.match(/image.*/)) continue; allData.set(path, true); let src = URL.createObjectURL(file); - let img=document.createElement('img'); - img.src=src; - img.title=path; + let media; + if (file.type.indexOf("image") === 0) { + media = document.createElement('img'); + } else if (file.type.indexOf("audio") === 0) { + media = document.createElement('audio'); + src = "audio:" + src; + } else if (file.type.indexOf("video") === 0) { + media = document.createElement('video'); + src = "video:" + src; + } else continue; + media.src = src; + media.title = path; var result = { src: src, type: 'force', imgSrc: src, noActual:true, description: path, - img: img + img: media }; self.data.push(result); self._appendThumbSpans([result]); From e85ad41b6b8e7e3c21be2ca24399fce92af83848 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 14:55:11 +0800 Subject: [PATCH 0144/1065] Update README.md --- Picviewer CE+/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index af09ed25b12..c22e6c12026 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -180,13 +180,14 @@ You have the option to use a standalone userscript, which allows you to manage a *A blank gallery page designed for viewing local or online pictures, showcasing every image you have imported.* +You can drag and drop folders or videos/audios/images into this gallery to get an electronic slideshow to view them. + Include `mode=`*`1`* to open gallery in view-more mode.
    Add `imgs=`*`http://xxx/xxx.jpg`* to import images. ` ` to split multi-image, `[01-09]` to generate nine urls form 01 to 09
    For example: ```url https://hoothin.github.io/UserScripts/Picviewer%20CE+/gallery.html?mode=0&imgs=http://xxx/xxx[01-99].jpg ``` -Just easily drag and drop your local images into the gallery to view them. From dcb25a869816df54981ae88212abaad63a21b475 Mon Sep 17 00:00:00 2001 From: Lemonade <61580921+lemonadeforlife@users.noreply.github.com> Date: Sat, 22 Jun 2024 14:09:03 +0600 Subject: [PATCH 0145/1065] Added rules for myanimelist search list --- Picviewer CE+/pvcep_rules.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 901aed8ac46..f6778782041 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1662,5 +1662,12 @@ var siteInfo = [ }, query: ".main-image" } + }, + { + name: "MAL Anime/Manga Search", + url: /^https:\/\/myanimelist\.net\/(anime|manga)\.php\?cat=(anime|manga).+/, + src: /^https:\/\/cdn\.myanimelist\.net/, + r: /\/r\/(\d+x\d+)(\/images\/(anime|manga)\/\d+\/\d+)\.webp.+/, + s: "$2l.jpg" } ]; From 4f6fdaccc9cf7b13bdc73a76f51f8506fb1c419f Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 16:59:14 +0800 Subject: [PATCH 0146/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 62165defe65..e36d50cef7a 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1398555/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1398739/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1391048/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 From 5c3a68ddaeb16959affb1c9c457632364c60f5e4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 17:03:51 +0800 Subject: [PATCH 0147/1065] Update README.md --- Picviewer CE+/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index c22e6c12026..7424aa3f1b8 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -142,9 +142,9 @@ You have the option to use a standalone userscript, which allows you to manage a Regular expression used to match the image src - r - `"r": "/(.*)\\d+/i"` + `"r": "/(.*)\\d+/i"` or `"r": "thumb"` - Regular expression used to replace the image src from + Simple string or regular expression used to replace the image src from - s `"s": "$1"` From 36f072c99e0d805102c5595329289810d5516ed7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 17:05:12 +0800 Subject: [PATCH 0148/1065] Update README.md --- Picviewer CE+/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 7424aa3f1b8..8af3b8c3006 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -1,4 +1,4 @@ -# 🏞️ Picviewer CE+ ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) +# 🏞️ Picviewer CE+ ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) 🗨️[Reddit](https://www.reddit.com/r/PicviewerCE) > Zoom images across all your favorite websites. Pop up, scale, edit, rotate, batch save images, or automatically load pictures from subsequent pages. Simply hover your mouse over any image and click the icons on the float bar. @@ -122,7 +122,7 @@ You have the option to use a standalone userscript, which allows you to manage a There are two types of rules available: + JSON (simple mode) - These rules are written in JSON format and can be imported online through [discussions](https://github.com/hoothin/UserScripts/discussions). + These rules are written in JSON format and can be imported online through [Discussions](https://github.com/hoothin/UserScripts/discussions) or [Reddit](https://www.reddit.com/r/PicviewerCE). They won't limited by websites that have a strict Content Security Policy that disallows unsafe-eval. + JSON params - name From 2cdeb9cbbd0e0028e3aad2f84351d3c7c0f12607 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 17:23:15 +0800 Subject: [PATCH 0149/1065] Update README.md --- Picviewer CE+/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 8af3b8c3006..64b91469cd8 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -187,6 +187,8 @@ Add `imgs=`*`http://xxx/xxx.jpg`* to import images. ` ` to split multi-image, `[ For example: ```url https://hoothin.github.io/UserScripts/Picviewer%20CE+/gallery.html?mode=0&imgs=http://xxx/xxx[01-99].jpg +or +https://hoothin.github.io/UserScripts/Picviewer%20CE+/gallery.html?mode=0&imgs=${encodeURIComponent(IMG1 + ' ' + IMG2)} ``` From b8a7095e885b1883363bf816c34e8f320ce89609 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 17:30:35 +0800 Subject: [PATCH 0150/1065] Update README.md --- Picviewer CE+/README.md | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 64b91469cd8..75ec316f914 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -94,25 +94,21 @@ You have the option to use a standalone userscript, which allows you to manage a (function() { 'use strict'; - window.pvcepRules = window.pvcepRules || []; - window.pvcepRules.push( - ... - [ - //Delete these two example rules and add your own. - { - name: "rule1", - src: /pics\.dmm\.co\.jp/i, - r: "ps.jpg", - s: "pl.jpg" - }, - { - name: "rule2", - url: /^https:\/\/xxx\.com\//, - r: /us\.xxx\.com\/\d+wm\//i, - s: "previews.xxx.com/images/" - } - ] - ); + window.pvcepRules = (window.pvcepRules || []).concat([ + //Delete these two example rules and add your own. + { + name: "rule1", + src: /pics\.dmm\.co\.jp/i, + r: "ps.jpg", + s: "pl.jpg" + }, + { + name: "rule2", + url: /^https:\/\/xxx\.com\//, + r: /us\.xxx\.com\/\d+wm\//i, + s: "previews.xxx.com/images/" + } + ]); })(); ``` From 5855e49e43bcb4e9b25388798ff6acb0ac675973 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 17:40:56 +0800 Subject: [PATCH 0151/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index e36d50cef7a..c891b0c8d39 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.22.4 +// @version 2024.6.22.5 // @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 @@ -20634,7 +20634,7 @@ ImgOps | https://imgops.com/#b#`; opacity: 0.5;\ border:none;\ padding:0;\ - padding-top:2px;\ + padding-top:2px!important;\ background-color:#1771FF;\ display: none;\ z-index: 2;\ @@ -20669,7 +20669,7 @@ ImgOps | https://imgops.com/#b#`; border:none;\ border-right: 1px solid #868686;\ padding:0;\ - padding-top:2px;\ + padding-top:2px!important;\ background-color:#1771FF;\ display: none;\ z-index: 2;\ @@ -20694,8 +20694,8 @@ ImgOps | https://imgops.com/#b#`; .pv-pic-window-description {\ display: none;\ background: yellow;\ - margin: 0 -5px 0 15px;\ - padding: 3px;\ + margin: 0 -5px 0 15px!important;\ + padding: 3px!important;\ color: black;\ text-shadow: 0 0 0px black;\ }\ @@ -20784,7 +20784,7 @@ ImgOps | https://imgops.com/#b#`; }\ .pv-pic-search-state>span {\ pointer-events: none;\ - padding: 1px 5px;\ + padding: 1px 5px!important;\ white-space: nowrap;\ overflow: hidden;\ }\ @@ -20899,7 +20899,7 @@ ImgOps | https://imgops.com/#b#`; -webkit-box-sizing:content-box;\ height: 24px;\ width: 24px;\ - padding: 12px 8px 6px 6px;\ + padding: 12px 8px 6px 6px!important;\ margin:0;\ display: block;\ background: transparent no-repeat center;\ @@ -20974,7 +20974,7 @@ ImgOps | https://imgops.com/#b#`; display:block;\ line-height:1.5;\ text-align:center;\ - padding:10px;\ + padding:10px!important;\ cursor:pointer;\ border: none;\ border-right: 2px solid transparent;\ From f7940b0ee3f5f40ade2c33c32d1cadc9dbbbeb5c Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 17:52:36 +0800 Subject: [PATCH 0152/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index c891b0c8d39..1e30aff2f4a 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.22.5 +// @version 2024.6.22.6 // @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 @@ -26062,7 +26062,7 @@ ImgOps | https://imgops.com/#b#`; if (/"name":/.test(content) && /"(r|xhr)":/.test(content)) { try { localStorage.setItem('picviewerCE.config.curTab', 4); - let webRule = JSON.parse(content); + let webRule = JSON.parse(content.replace(/^\/\/.*/g, "")); let customRules; let fieldsCustomRules = GM_config.fields.customRules; if (prefs.customRules.indexOf('"name":') !== -1) { From c5e8518f1aa7476fcdfe9a495391c0acaf0a5567 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 18:23:06 +0800 Subject: [PATCH 0153/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 1e30aff2f4a..3471116b643 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -13767,7 +13767,7 @@ ImgOps | https://imgops.com/#b#`; ''+ ''+prefs.icons.downloadSvgBtn+''+ ''); - getBody(document).appendChild(container); + document.documentElement.appendChild(container); let bricksInstance = Bricks({ container: ".pv-gallery-maximize-container", From e518eecbce862d015a64174b885e685b49ec75db Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 18:26:52 +0800 Subject: [PATCH 0154/1065] Update README.md --- Switch Traditional Chinese and Simplified Chinese/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/README.md b/Switch Traditional Chinese and Simplified Chinese/README.md index c5fce6e05bb..ead050330ec 100644 --- a/Switch Traditional Chinese and Simplified Chinese/README.md +++ b/Switch Traditional Chinese and Simplified Chinese/README.md @@ -1,4 +1,4 @@ -+ 預設會自動切換至使用者所使用的預設語言。 ++ 預設會自動切換至使用者所使用的語言。 + 按下 `Ctrl + F8` 可在簡體中文與繁體中文之間切換(如果輸入框為活動控制項,則只有輸入框內的文字會被轉換;選取文字時,只有對應的文字會被轉換,且不會被記憶)。 + 使用命令選單中的「繁簡切換【Ctrl + F8】」功能可在當前網域禁用轉換。 + 切換語言後,會儲存目前網站的語言選擇。 From ac7c727695debddd02942f4a8c1ee9ca7abc6420 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 18:30:11 +0800 Subject: [PATCH 0155/1065] Update README.md --- Picviewer CE+/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 75ec316f914..6356d03bd0d 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -1,4 +1,4 @@ -# 🏞️ Picviewer CE+ ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) 🗨️[Reddit](https://www.reddit.com/r/PicviewerCE) +# 🏞️ Picviewer CE+ ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) 🌐[Reddit](https://www.reddit.com/r/PicviewerCE) 🗨️[Discord](https://discord.com/invite/keqypXC6wD) > Zoom images across all your favorite websites. Pop up, scale, edit, rotate, batch save images, or automatically load pictures from subsequent pages. Simply hover your mouse over any image and click the icons on the float bar. From 612584f4a23cc6b6e0cf257cc010d91da004c352 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 18:33:15 +0800 Subject: [PATCH 0156/1065] Update README.md --- Picviewer CE+/README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 6356d03bd0d..64fb8444c5d 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -21,12 +21,13 @@ Hover your mouse over any image and click the icons on the float bar. Press `CTRL + G` to quickly enter the gallery. Hold `CTRL` to view a larger picture when hovering over images or links. -There are additional settings available in the "Picviewer CE+ config" for further customization. Currently, reviewing these settings is the best way to learn about the script's capabilities. Try exploring more functions on your own! - -If you are glad to assist with the translation, please [🌐edit this file](https://github.com/hoothin/UserScripts/edit/master/Picviewer%20CE%2B/pvcep_lang.js#L1). It will be beneficial for individuals who speak the same language as you do. Thank you for your help. - -Need more rules for peculiar sites? feel free to pull requests or open issues. +> There are additional settings available in the "Picviewer CE+ config" for further customization. Currently, reviewing these settings is the best way to learn about the script's capabilities. Try exploring more functions on your own! +> +> If you are glad to assist with the translation, please [🌐edit this file](https://github.com/hoothin/UserScripts/edit/master/Picviewer%20CE%2B/pvcep_lang.js#L1). It will be beneficial for individuals who speak the same language as you do. Thank you for your help. +> +> Need more rules for peculiar sites? feel free to pull requests or open issues. +## PDF Addon [Picviewer CE+ PDF Addon](https://greasyfork.org/scripts/498445-picviewer-ce-pdf-addon) After installing this addon, when the `Compress to ZIP` feature is enabled, a PDF file will be generated instead of a ZIP file during the packaging process.
    Make a PDF e-book with this addon @@ -174,7 +175,7 @@ You have the option to use a standalone userscript, which allows you to manage a ## Blank Gallery Page [https://hoothin.github.io/UserScripts/Picviewer%20CE+/gallery.html](https://hoothin.github.io/UserScripts/Picviewer%20CE+/gallery.html) -*A blank gallery page designed for viewing local or online pictures, showcasing every image you have imported.* +> *A blank gallery page designed for viewing local or online pictures, showcasing every image you have imported.* You can drag and drop folders or videos/audios/images into this gallery to get an electronic slideshow to view them. From 740600744926ba479eb2d196a800c0f3e79a0994 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Jun 2024 22:31:55 +0800 Subject: [PATCH 0157/1065] Update README.md --- Pagetual/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Pagetual/README.md b/Pagetual/README.md index 12a677488b8..e223aeaa3f9 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -57,6 +57,7 @@ https://raw.githubusercontent.com/hoothin/UserScripts/master/Pagetual/pagetualRu + [TerenceCK pagetualRules](https://github.com/TerenceCK/pagetualRules/blob/main/happymh.json) + [Liu's-Pagetual-Rule](https://github.com/JPLiu/TestFiles/blob/main/UserScripts/Pagetual/Liu's-Pagetual-Rule.json) + [skofkyo pagetualRules_EX](https://github.com/skofkyo/AutoPager/blob/main/pagetualRules_EX.json) ++ [MovByte eToolsPagetual](https://gist.github.com/MovByte/a585456490d2e1c8ca815871db0887f7)
    From 7c9acbb9944017a073d26d41eb2cc9673dac9e81 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 23 Jun 2024 09:08:02 +0800 Subject: [PATCH 0158/1065] Update README.md --- Picviewer CE+/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 64fb8444c5d..a8ad83966bd 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -52,7 +52,7 @@ This way, you'll get a beautifully created PDF e-book. ``` json { "name": "Dmm", - "src": "/pics\\.dmm\\.co\\.jp/i", + "src": "pics\\.dmm\\.co\\.jp", "r": "ps.jpg", "s": "pl.jpg" } From 3858bbb8380e3017ebaa7496f113dd0b13eb6a8d Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 23 Jun 2024 09:34:31 +0800 Subject: [PATCH 0159/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 3471116b643..b6f71a9ab3f 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.22.6 +// @version 2024.6.23.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 @@ -13443,11 +13443,11 @@ ImgOps | https://imgops.com/#b#`; function getSupportEventName(){ var ret='DOMMouseScroll'; - if(eventSupported('wheel')){//w3c FF>=17 ie>=9 - ret='wheel'; - }else if(eventSupported('mousewheel')){//opera,chrome + if(eventSupported('mousewheel')){//opera,chrome ret='mousewheel'; - }; + }else if(eventSupported('wheel')){//w3c FF>=17 ie>=9 + ret='wheel'; + } return ret; }; @@ -20731,6 +20731,9 @@ ImgOps | https://imgops.com/#b#`; .compare>.pv-pic-search-state{\ display: none;\ }\ + .pv-pic-window-container_focus:not(.preview)>.pv-pic-search-state {\ + opacity:0.8;\ + }\ .pv-pic-window-container_focus:not(.preview) .pv-pic-window-imgbox:hover~.pv-pic-window-pre,\ .pv-pic-window-container_focus:not(.preview) .pv-pic-window-imgbox:hover~.pv-pic-window-next{\ opacity:0.3;\ @@ -20809,6 +20812,7 @@ ImgOps | https://imgops.com/#b#`; color: white;\ cursor: pointer;\ display: none;\ + box-sizing: content-box;\ transition: all 0.3s ease;\ }\ .pv-pic-search-state>.pv-icon:hover {\ @@ -20817,9 +20821,6 @@ ImgOps | https://imgops.com/#b#`; .pv-pic-search-state>.pv-icon * {\ pointer-events: none;\ }\ - .pv-pic-window-container_focus:not(.preview)>.pv-pic-search-state {\ - opacity:0.8;\ - }\ .pv-pic-window-scrollSign {\ display: none;\ width: 100px;\ From 9e0ef4a522f24fbe8f326951b58cbc61b5b84ced Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 23 Jun 2024 10:45:12 +0800 Subject: [PATCH 0160/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index b6f71a9ab3f..abcbe8e615d 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -19828,7 +19828,7 @@ ImgOps | https://imgops.com/#b#`; this.img = img; this.actual = !!actual; this.src = data?data.src:img.src; - this.data = data; + this.data = data || findPic(img); this.initPos = initPos || false; this.preview = !!preview; this.isImg = this.img.nodeName.toUpperCase() == 'IMG'; @@ -20757,6 +20757,8 @@ ImgOps | https://imgops.com/#b#`; overflow:visible;\ background:none;\ box-shadow:none;\ + opacity: 1;\ + height: 30px;\ }\ .pv-pic-window-container>span.pv-pic-search-state:hover>span{\ opacity: 0;\ From ed26394a0e6d6ac8455afce9982c4537e822f3b3 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 23 Jun 2024 11:14:50 +0800 Subject: [PATCH 0161/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index abcbe8e615d..500fb9ae19f 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.23.1 +// @version 2024.6.23.2 // @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 @@ -12242,7 +12242,7 @@ ImgOps | https://imgops.com/#b#`; }, onload: function(d) { let blob = d.response; - let ext = blob.type.replace(/.*image\/(\w+).*/, "$1"); + let ext = blob.type.replace(/.*image\/([\w\-]+).*/, "$1"); let conversion = formatDict.get(ext); if (canvas && (conversion || forcePng)) { var self = this; @@ -25527,6 +25527,7 @@ ImgOps | https://imgops.com/#b#`; 'gallery.formatConversion': { label: i18n("formatConversion"), type: 'textarea', + title: 'webp>png\nx-icon>png', "default": prefs.gallery.formatConversion || '' }, 'gallery.aria2Host': { From c554d53559748d65016d2a53508a535df87114be Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 23 Jun 2024 12:57:14 +0800 Subject: [PATCH 0162/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 167 ++++++++++++++++++++-------- 1 file changed, 123 insertions(+), 44 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 500fb9ae19f..04e53dd9054 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.23.2 +// @version 2024.6.23.3 // @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 @@ -12414,7 +12414,7 @@ ImgOps | https://imgops.com/#b#`; searchData:defaultSearchData, downloadWithZip:true, autoOpenViewmore:false, - downloadGap:0 + downloadGap:1 }, imgWindow:{// 图片窗相关设置 @@ -14411,15 +14411,46 @@ ImgOps | https://imgops.com/#b#`; prefs.gallery.scrollEndAndLoad = !!storage.getListItem("scrollEndAndLoad", location.hostname); eleMaps['head-command-drop-list-others'].querySelector('input[data-command="scrollToEndAndReload"]').checked = prefs.gallery.scrollEndAndLoad; let srcSplit, downloading=false, saveParams; - function getSaveParams() { + async function getSaveParams() { let nodes = self.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]:not(.ignore)'); let saveParams = [],saveIndex=0; - [].forEach.call(nodes, function(node){ - if(unsafeWindow.getComputedStyle(node).display!="none"){ + for (const node of nodes) { + if (unsafeWindow.getComputedStyle(node).display !== "none") { saveIndex++; + + let xhr = dataset(node, 'xhr') !== 'stop' && self.getPropBySpanMark(node, "xhr"); + if (xhr) { + self.showTips("Sending request..."); + await new Promise(resolve => { + setTimeout(() => { + let xhrError = function() { + dataset(node, 'xhr', 'stop'); + dataset(node, 'src', dataset(node, 'thumbSrc')); + resolve(); + }; + xhrLoad.load({ + url: node.dataset.src, + xhr: xhr, + cb: function(imgSrc, imgSrcs, caption) { + if (imgSrc) { + dataset(node, 'src', imgSrc); + dataset(node, 'xhr', 'stop'); + if (caption) dataset(node, 'description', caption); + resolve(); + } else { + xhrError(); + } + }, + onerror: xhrError + }); + }, prefs.gallery.downloadGap || 0); + }); + } + + if (node.dataset.src.indexOf('data') === 0) srcSplit = ""; else { - srcSplit=node.dataset.src || ''; + srcSplit = node.dataset.src || ''; } let title = node.title.indexOf('\n') !== -1 ? node.title.split('\n')[0] : node.title; title = title.indexOf('http') === 0 || title.indexOf('data') === 0 ? '' : title; @@ -14434,11 +14465,11 @@ ImgOps | https://imgops.com/#b#`; } //saveAs(node.dataset.src, location.host+"-"+srcSplit[srcSplit.length-1]); } - }); + } return saveParams; } //命令下拉列表的点击处理 - eleMaps['head-command-drop-list-others'].addEventListener('click',function(e){ + eleMaps['head-command-drop-list-others'].addEventListener('click',async function(e){ if(e.button!=0)return;//左键 let target=e.target; let command=dataset(target,'command'); @@ -14504,7 +14535,7 @@ ImgOps | https://imgops.com/#b#`; self.showTips("Configure aria2 first!", 1000); return; } - saveParams = getSaveParams(); + saveParams = await getSaveParams(); [].forEach.call(saveParams, function(param){ _GM_xmlhttpRequest({ method: 'POST', @@ -14531,7 +14562,7 @@ ImgOps | https://imgops.com/#b#`; case 'downloadImage': if(downloading)break; downloading=true; - saveParams = getSaveParams(); + saveParams = await getSaveParams(); self.batchDownload(saveParams, ()=>{ downloading=false; self.showTips("Completed!", 1000); @@ -15197,17 +15228,28 @@ ImgOps | https://imgops.com/#b#`; let mainImgWin=new ImgWindowC(mainImg); mainImgWin.compare(imgSrcs); }; - batchDlBtn.onclick=function(e){ + batchDlBtn.onclick=async function(e){ checkBoxs=maximizeContainer.querySelectorAll(".maximizeChild>input:checked"); if(checkBoxs.length<1)checkBoxs=maximizeContainer.querySelectorAll(".maximizeChild>input"); var saveParams = [],saveIndex=0; - [].forEach.call(checkBoxs, function(node){ + for (const node of checkBoxs) { let conItem=node.parentNode; if(conItem.style.display=="none")return; saveIndex++; - let imgSrc=conItem.querySelector("img").src; + if (conItem.dataset.xhr) { + await new Promise((resolve) => { + let getxhroverHandler = e => { + conItem.removeEventListener('getxhrover', getxhroverHandler); + resolve(); + }; + conItem.addEventListener('getxhrover', getxhroverHandler); + conItem.dispatchEvent(new Event('getxhr')); + }); + } + + let imgSrc=conItem.querySelector("img").dataset.src || conItem.querySelector("img").src; let title=node.nextElementSibling.title; title = title.indexOf('\n') !== -1 ? title.split('\n')[0] : title; title = title.indexOf('http') === 0 || title.indexOf('data') === 0 ? '' : title; @@ -15219,7 +15261,7 @@ ImgOps | https://imgops.com/#b#`; title = getRightSaveName(srcSplit, title, prefs.saveName); var picName = (saveIndex < 10 ? "00" + saveIndex : (saveIndex < 100 ? "0" + saveIndex : saveIndex)) + (!title || title == document.title ? "" : "-" + title); saveParams.push([imgSrc, picName]); - }); + } self.batchDownload(saveParams, ()=>{ self.showTips("Completed!", 1000); }); @@ -15472,7 +15514,7 @@ ImgOps | https://imgops.com/#b#`; zip = new JSZip(); } var len = saveParams.length; - function downloadOne(imgSrc, imgName){ + function downloadOne(imgSrc, imgName, over){ let crosHandler = imgSrc => { urlToBlob(imgSrc, blob=>{ if (blob && blob.size>58) { @@ -15483,6 +15525,7 @@ ImgOps | https://imgops.com/#b#`; zip.file(fileName, blob); } else console.debug("error: "+imgSrc); downloaded++; + over && over(); self.showTips("Downloading "+downloaded+"/"+len, 1000000); if(downloaded == len){ self.showTips(`Begin compress to ${packName}...`, 100000); @@ -15505,6 +15548,7 @@ ImgOps | https://imgops.com/#b#`; canvas.toBlob(blob=>{ zip.file(imgName.replace(/^data:.*/, "img").replace(/\//g,""), blob); downloaded++; + over && over(); if(downloaded == len){ self.showTips(`Begin compress to ${packName}...`, 100000); zip.generateAsync({type:"blob"}, meta=>{self.showCompressProgress(meta)}).then(function(content){ @@ -15521,11 +15565,23 @@ ImgOps | https://imgops.com/#b#`; } } if(prefs.gallery.downloadGap > 0){ - let downIntv=setInterval(()=>{ - let saveParam=saveParams.shift(); - if(!saveParam)clearInterval(downIntv); - else downloadOne(saveParam[0], saveParam[1]); - },prefs.gallery.downloadGap); + let waitToDownloadOne = () => { + setTimeout(() => { + let saveParam = saveParams && saveParams.shift(); + if (!saveParam) clearInterval(downIntv); + else downloadOne(saveParam[0], saveParam[1], waitToDownloadOne); + }, prefs.gallery.downloadGap); + }; + let threadNum = 10; + let downIntv = setInterval(() => { + if (threadNum-- === 0) { + clearInterval(downIntv); + return; + } + let saveParam = saveParams && saveParams.shift(); + if (!saveParam) clearInterval(downIntv); + else downloadOne(saveParam[0], saveParam[1], waitToDownloadOne); + }, prefs.gallery.downloadGap); }else{ for(let i=0; i'); let img=imgSpan.querySelector("img"); - imgSpan.addEventListener("click", function(e) { + let xhr = dataset(node, 'xhr') !== 'stop' && self.getPropBySpanMark(node, "xhr"); + let getXhr = async () => { + let result = await new Promise((resolve) => { + let xhrError = function() { + dataset(node, 'xhr', 'stop'); + dataset(node, 'src', dataset(node, 'thumbSrc')); + resolve(null); + }; + xhrLoad.load({ + url: curNode.dataset.src, + xhr: xhr, + cb: function(imgSrc, imgSrcs, caption) { + if (imgSrc) { + dataset(node, 'src', imgSrc); + dataset(node, 'xhr', 'stop'); + if (caption) dataset(node, 'description', caption); + img.dataset.src = imgSrc; + resolve(imgSrc); + } else { + xhrError(); + } + }, + onerror: xhrError + }); + }); + imgSpan.removeEventListener('getxhr', getXhrHandler); + delete imgSpan.dataset.xhr; + imgSpan.dispatchEvent(new Event('getxhrover')); + return result; + }; + let getXhrHandler = e => { + getXhr(); + }; + if (xhr) { + imgSpan.dataset.xhr = true; + imgSpan.addEventListener('getxhr', getXhrHandler); + } + imgSpan.addEventListener("click", async function(e) { self.selectViewmore(imgSpan, curNode.dataset.src); let loadError = e => { let i = document.createElement("img"); @@ -15850,7 +15942,7 @@ ImgOps | https://imgops.com/#b#`; let loadImg = () => { self.showTips("Loading image..."); - let imgSrc = img.dataset.src; + let imgSrc = dataset(node, 'src'); let mode = matchedRule.getMode(imgSrc); let media; switch (mode) { @@ -15902,28 +15994,16 @@ ImgOps | https://imgops.com/#b#`; let xhr = dataset(node, 'xhr') !== 'stop' && self.getPropBySpanMark(node, "xhr"); if (xhr) { self.showTips("Sending request..."); - let xhrError = function() { - dataset(node, 'xhr', 'stop'); - dataset(node, 'src', dataset(node, 'thumbSrc')); + let imgSrc = await getXhr(); + if (imgSrc) { + loadImg(); + } else { loadError(); - }; - xhrLoad.load({ - url: curNode.dataset.src, - xhr: xhr, - cb: function(imgSrc, imgSrcs, caption) { - if (imgSrc) { - dataset(node, 'src', imgSrc); - dataset(node, 'xhr', 'stop'); - if (caption) dataset(node, 'description', caption); - img.dataset.src = imgSrc; - loadImg(); - } else { - xhrError(); - } - }, - onerror: xhrError - }); + } return; + } else { + imgSpan.removeEventListener('getxhr', getXhrHandler); + delete imgSpan.dataset.xhr; } loadImg(); }); @@ -16700,7 +16780,6 @@ ImgOps | https://imgops.com/#b#`; this.eleMaps['maximize-container'].innerHTML = createHTML(""); } var self = this; - var urlReg=new RegExp(this.urlFilter); var createSpanMark = item => { var spanMark=self._spanMarkPool[item.src]; if(!spanMark){ From 60a14963db445e03882a74c752435a1792d98add Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 23 Jun 2024 12:59:22 +0800 Subject: [PATCH 0163/1065] Update pvcep_pdf_addon.user.js --- Picviewer CE+/pvcep_pdf_addon.user.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Picviewer CE+/pvcep_pdf_addon.user.js b/Picviewer CE+/pvcep_pdf_addon.user.js index 3e6a8bbcfbe..155e8e3be7e 100644 --- a/Picviewer CE+/pvcep_pdf_addon.user.js +++ b/Picviewer CE+/pvcep_pdf_addon.user.js @@ -3,7 +3,7 @@ // @name:zh-CN Picviewer CE+ PDF 扩展 // @name:zh-TW Picviewer CE+ PDF 擴充 // @namespace https://github.com/hoothin/UserScripts -// @version 2024-06-22 +// @version 2024-06-23 // @description Batch Download as PDF instead of ZIP // @description:zh-CN 取代 ZIP, 打包下载时下载为 PDF // @description:zh-TW 取代 ZIP, 打包下載時下載為 PDF @@ -53,12 +53,16 @@ fileName = this.fileList[0][0]; blob = this.fileList[0][1]; } - let dataUrl = await blobToDataURL(blob); - const imgProps = pdf.getImageProperties(dataUrl); - const pdfWidth = pdf.internal.pageSize.getWidth(); - const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width; - pdf.addImage(dataUrl, blob.type, 0, 0, pdfWidth, pdfHeight); - progress({percent: (key + 1) / fileLength * 100, currentFile: fileName}); + try { + let dataUrl = await blobToDataURL(blob); + const imgProps = pdf.getImageProperties(dataUrl); + const pdfWidth = pdf.internal.pageSize.getWidth(); + const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width; + pdf.addImage(dataUrl, blob.type, 0, 0, pdfWidth, pdfHeight); + progress({percent: (key + 1) / fileLength * 100, currentFile: fileName}); + } catch(e) { + console.log(e); + } if (key + 1 < fileLength) { pdf.addPage(); } From 8a7c50ce29b3ca6428d3653f11af28e8161f8d64 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 23 Jun 2024 13:19:55 +0800 Subject: [PATCH 0164/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 04e53dd9054..1dad2708441 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -16824,7 +16824,7 @@ ImgOps | https://imgops.com/#b#`; }catch(e){}; self._spanMarkPool[item.src] = spanMark; } - spanMark.dataset.xhr=''; + //spanMark.dataset.xhr=''; if(spanMark.dataset.naturalSize){ let naturalSize=JSON.parse(spanMark.dataset.naturalSize); item.sizeW=naturalSize.w; From e4261925a286e42d3c3d6115a88dd14b63897bda Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 23 Jun 2024 21:17:50 +0800 Subject: [PATCH 0165/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 36 ++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 95031c3b776..ba04b1a7709 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -3,10 +3,10 @@ // @name:en Kill Baidu AD // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @namespace hoothin -// @version 1.22 -// @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,并防止反复 +// @version 1.23 +// @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,刪除百家号 // @description:en Just Kill Baidu AD -// @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,並防止反復 +// @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 // @author hoothin // @include http*://www.baidu.com/* // @include http*://m.baidu.com/* @@ -75,10 +75,25 @@ var list=document.querySelectorAll("#content_left>div,#content_left>table"); for(i=0;ispan"); if(span && span.innerHTML=="广告"){ item.remove(); @@ -127,10 +142,25 @@ return; } if(ele.parentNode && ele.parentNode.id=="content_left" && (ele.nodeName=="DIV" || ele.nodeName=="TABLE")){ + let mu = ele.getAttribute("mu"); + if (mu) { + if (/^https:\/\/baijiahao\.baidu\.com/.test(mu)) { + ele.remove(); + return; + } else { + let link = ele.querySelector("a[href*='www.baidu.com/link']"); + if (link) link.href = mu; + } + } let s = ele.getAttribute("style"); if (s && /display:(table|block)\s!important/.test(s)) { ele.remove(); }else{ + let baozhang = ele.querySelector("[data-baodata]"); + if (baozhang) { + ele.remove(); + return; + } var span=ele.querySelector("div>span"); if(span && span.innerHTML=="广告"){ ele.remove(); From d0b63d60a593d24ec08fdd74c0f14ac9759e299d Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 23 Jun 2024 21:42:02 +0800 Subject: [PATCH 0166/1065] Update pvcep_lang.js --- Picviewer CE+/pvcep_lang.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Picviewer CE+/pvcep_lang.js b/Picviewer CE+/pvcep_lang.js index d6ae5e36581..51a3c7dce87 100644 --- a/Picviewer CE+/pvcep_lang.js +++ b/Picviewer CE+/pvcep_lang.js @@ -61,6 +61,7 @@ const langData = [ slideGapTip: "Interval, unit (seconds)", slideBack: "Back", slideBackTip: "Play from back to front", + slideRandom: "Random", slideWait: "Wait for image reading", slideWaitTip: "The countdown starts after each image is completely read.", slideSkipError: "Skip error pictures", @@ -321,6 +322,7 @@ const langData = [ slideGapTip: "الفاصل، وحدة (ثواني)", slideBack: "رجوع", slideBackTip: "التشغيل من الخلف إلى الأمام", + slideRandom: "Random", slideWait: "انتظر قراءة الصورة", slideWaitTip: "يبدأ العد التنازلي بعد قراءة كل صورة بالكامل.", slideSkipError: "تخطي الصور الخاطئة", @@ -580,6 +582,7 @@ const langData = [ slideGapTip: "间隔时间,单位(秒)", slideBack: "后退", slideBackTip: "从后往前播放", + slideRandom: "随机播放", slideWait: "等待图片读取", slideWaitTip: "从每张图片完全读取完成后才开始倒计时", slideSkipError: "跳过错误图片", @@ -839,6 +842,7 @@ const langData = [ slideGapTip: "間隔時間,單位(秒)", slideBack: "後退", slideBackTip: "從後往前播放", + slideRandom: "隨機播放", slideWait: "等待圖片讀取", slideWaitTip: "從每張圖片完全讀取完成後才開始倒計時", slideSkipError: "跳過錯誤圖片", @@ -1099,6 +1103,7 @@ const langData = [ slideGapTip: "Intervalo de tempo, em segundos", slideBack: "De trás para frente", slideBackTip: "Reproduz a apresentação de Slides de trás para frente", + slideRandom: "Random", slideWait: "Aguardar a leitura da imagem", slideWaitTip: "A contagem regressiva só começa depois que a imagem é totalmente carregada", slideSkipError: "Ignorar imagens com erro", @@ -1359,6 +1364,7 @@ const langData = [ slideGapTip: "Время интервала, в секундах", slideBack: "От конца", slideBackTip: "Воспроизведение от конца к началу", + slideRandom: "Random", slideWait: "Ожидание считывания изображения", slideWaitTip: "Обратный отсчёт начинаётся только после того, как все изображения будут полностью считаны", slideSkipError: "Пропускать изображения с ошибкой", @@ -1619,6 +1625,7 @@ const langData = [ slideGapTip: "Aralık, birim (saniye)", slideBack: "Geri", slideBackTip: "Geriden ileriye doğru oynat", + slideRandom: "Random", slideWait: "Resimlerin okunması için bekleyin", slideWaitTip: "Gerisayım her resim okunduktan sonra başlar.", slideSkipError: "Hatalı resimleri atla", @@ -1878,6 +1885,7 @@ const langData = [ slideGapTip: "間隔 (単位: 秒)", slideBack: "戻る", slideBackTip: "前から後ろに再生", + slideRandom: "シャッフル", slideWait: "画像読み込みを待つ", slideWaitTip: "各画像が完全に読み込まれると、カウントダウンが始まります", slideSkipError: "エラー画像をスキップ", @@ -2138,6 +2146,7 @@ const langData = [ slideGapTip: "Час інтервалу, у секундах", slideBack: "З кінця", slideBackTip: "Відтворення від кінця до початку", + slideRandom: "Random", slideWait: "Очікування зчитування зображення", slideWaitTip: "Зворотній відлік почнеться тільки коли усі зображення будуть повністю зчитані", slideSkipError: "Пропускати зображення з помилками", From 2027bcaaf55acb2905a235f793c6b3207ad077af Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 23 Jun 2024 21:43:33 +0800 Subject: [PATCH 0167/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 46 +++++++++++++++++++---------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 1dad2708441..cd66d9a3c14 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.23.3 +// @version 2024.6.23.4 // @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 @@ -47,7 +47,7 @@ // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js // @require https://update.greasyfork.org/scripts/438080/1398739/pvcep_rules.js -// @require https://update.greasyfork.org/scripts/440698/1391048/pvcep_lang.js +// @require https://update.greasyfork.org/scripts/440698/1399329/pvcep_lang.js // @downloadURL https://greasyfork.org/scripts/24204-picviewer-ce/code/Picviewer%20CE+.user.js // @updateURL https://greasyfork.org/scripts/24204-picviewer-ce/code/Picviewer%20CE+.meta.js // @match *://*/* @@ -13622,6 +13622,10 @@ ImgOps | https://imgops.com/#b#`; ''+ ''+ ''+ + ''+ + ''+ + ''+ + ''+ ''+ ''+ ''+ @@ -14260,6 +14264,7 @@ ImgOps | https://imgops.com/#b#`; backward:false, skipErrorImg:true, run:false, + random:false }, //timing: //select(选中下一个图片后(缩略图栏选中了),还没开始读取大图(一般选中后,延时200ms开始读取大图)), @@ -14300,7 +14305,7 @@ ImgOps | https://imgops.com/#b#`; }, getEle:function(){ - return self.getThumSpan(this.opts.backward, null, true); + return self.getThumSpan(this.opts.backward, null, true, this.opts.random); }, go:function(){ this.stop();//停止上次的。 @@ -16138,25 +16143,36 @@ ImgOps | https://imgops.com/#b#`; } }, - getThumSpan:function(previous, relatedTarget, loop){ + getThumSpan:function(previous, relatedTarget, loop, random){ var ret; var rt = relatedTarget || this.selected; if(!rt)return; - while((rt=previous ? rt.previousElementSibling : rt.nextElementSibling)){ - if(rt.clientWidth!=0){ - ret=rt; - break; - } - } - if (loop && !ret) { - rt = (relatedTarget || this.selected).parentNode; - rt = previous ? rt.lastElementChild : rt.firstElementChild; - while ((rt = previous ? rt.previousElementSibling : rt.nextElementSibling)) { - if (rt.clientWidth != 0) { + if (random) { + if (rt.clientWidth === 0) return; + let sibling = rt.parentNode.children; + while (rt = sibling[Math.floor(Math.random() * sibling.length)]) { + if (rt.clientWidth !== 0) { ret = rt; break; } } + } else { + while((rt=previous ? rt.previousElementSibling : rt.nextElementSibling)){ + if(rt.clientWidth!=0){ + ret=rt; + break; + } + } + if (loop && !ret) { + rt = (relatedTarget || this.selected).parentNode; + rt = previous ? rt.lastElementChild : rt.firstElementChild; + while ((rt = previous ? rt.previousElementSibling : rt.nextElementSibling)) { + if (rt.clientWidth != 0) { + ret = rt; + break; + } + } + } } return ret; }, From 0a6c49f6276b49291945f19c0f957f5efa6d713b Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 23 Jun 2024 21:50:12 +0800 Subject: [PATCH 0168/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index cd66d9a3c14..4cfe0a9c2dd 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -18022,7 +18022,7 @@ ImgOps | https://imgops.com/#b#`; padding: 0;\ margin: 0;\ border: none;\ - z-index:'+prefs.imgWindow.zIndex+';\ + z-index:'+(prefs.imgWindow.zIndex - 1)+';\ background-color: transparent;\ display: initial;\ }\ From 49aa8e2d02b57d3881ada1279441cc8a22c85ac4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 24 Jun 2024 08:31:46 +0800 Subject: [PATCH 0169/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 237 ++++++++++++---------------- 1 file changed, 104 insertions(+), 133 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index ba04b1a7709..de50a68b225 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -3,13 +3,13 @@ // @name:en Kill Baidu AD // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @namespace hoothin -// @version 1.23 +// @version 1.23.1 // @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,刪除百家号 // @description:en Just Kill Baidu AD // @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 // @author hoothin -// @include http*://www.baidu.com/* -// @include http*://m.baidu.com/* +// @match *://www.baidu.com/* +// @match *://m.baidu.com/* // @grant GM_xmlhttpRequest // @run-at document-start // @license MIT License @@ -23,13 +23,12 @@ (function() { 'use strict'; - var killBaijiaType=2; - var MO = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; - if(MO){ - var observer = new MO(function(records){ + var MO = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, killBaijiaType = 1; + if (MO) { + var observer = new MO(function(records) { records.map(function(record) { - if(record.addedNodes.length){ - [].forEach.call(record.addedNodes,function(addedNode) { + if (record.addedNodes.length) { + [].forEach.call(record.addedNodes, function(addedNode) { clearOneAD(addedNode); }); } @@ -42,22 +41,22 @@ observer.observe(document, option); } - function checkBaijia(item){ - var itemHref=item.querySelector("a").href; - item.style.display="none"; - if(itemHref.indexOf("baidu.com")==-1)return; - var gmxhr=GM_xmlhttpRequest({ + function checkBaijia(item) { + var itemHref = item.querySelector("a").href; + item.style.display = "none"; + if (itemHref.indexOf("baidu.com") == -1) return; + var gmxhr = GM_xmlhttpRequest({ url: itemHref, headers: { "Accept": "text/html" }, method: "head", - onreadystatechange:function(response) { - if(response.readyState==4){ - if(response.finalUrl.indexOf("baijiahao.baidu.com")!=-1){ + onreadystatechange: function(response) { + if (response.readyState == 4) { + if (response.finalUrl.indexOf("baijiahao.baidu.com") != -1) { item.remove(); - }else{ - item.style.display=""; + } else { + item.style.display = ""; } gmxhr.abort(); } @@ -65,147 +64,119 @@ }); } - function clearAD(){ - if(!document.querySelectorAll)return; - var mAds=document.querySelectorAll(".ec_wise_ad,.ec_youxuan_card,.page-banner"),i; - for(i=0;idiv,#content_left>table"); - for(i=0;ispan"); + if (span && span.innerHTML == "广告") { item.remove(); - }else{ - let baozhang = item.querySelector("[data-baodata]"); - if (baozhang) { - item.remove(); - continue; - } - var span=item.querySelector("div>span"); - if(span && span.innerHTML=="广告"){ + } + [].forEach.call(item.querySelectorAll("span,a"), function(span) { + if (span && (span.innerHTML == "广告" || span.getAttribute("data-tuiguang"))) { item.remove(); } - [].forEach.call(item.querySelectorAll("span,a"),function(span){ - if(span && (span.innerHTML=="广告" || span.getAttribute("data-tuiguang"))){ + }); + if (killBaijiaType == 2) { + [].forEach.call(item.querySelectorAll("a>div>span+img"), function(img) { + if (img && /^https?:\/\/pic\.rmb\.bdstatic\.com/.test(img.src)) { + //checkBaijia(item); item.remove(); } }); - if(killBaijiaType==2){ - [].forEach.call(item.querySelectorAll("a>div>span+img"),function(img){ - if(img && /^https?:\/\/pic\.rmb\.bdstatic\.com/.test(img.src)){ - //checkBaijia(item); - item.remove(); - } - }); - } } } + } - var eb = document.querySelectorAll("#content_right>table>tbody>tr>td>div"); - for(i=0;idiv>div>div"); - if(nr){ - var nra=nr.querySelectorAll("a"); - for(i=0;idiv,#content_left>table"); + for (i = 0; i < list.length; i++) { + let item = list[i]; + checkLeftItem(item); + } + + var eb = document.querySelectorAll("#content_right>table>tbody>tr>td>div"); + checkRightTable(eb); + + var nr = document.querySelector("#content_right>div>div>div"); + if (nr) { + checkRightAd(nr); + } + } + + function clearOneAD(ele) { + if (ele.nodeType != 1) return; + if (ele.classList.contains("ec-tuiguang") || ele.classList.contains("ec_wise_ad") || ele.classList.contains("ec_youxuan_card") || ele.classList.contains("page-banner")) { ele.remove(); return; } - if(ele.parentNode && ele.parentNode.id=="content_left" && (ele.nodeName=="DIV" || ele.nodeName=="TABLE")){ - let mu = ele.getAttribute("mu"); - if (mu) { - if (/^https:\/\/baijiahao\.baidu\.com/.test(mu)) { - ele.remove(); - return; - } else { - let link = ele.querySelector("a[href*='www.baidu.com/link']"); - if (link) link.href = mu; - } - } - let s = ele.getAttribute("style"); - if (s && /display:(table|block)\s!important/.test(s)) { - ele.remove(); - }else{ - let baozhang = ele.querySelector("[data-baodata]"); - if (baozhang) { - ele.remove(); - return; - } - var span=ele.querySelector("div>span"); - if(span && span.innerHTML=="广告"){ - ele.remove(); - } - [].forEach.call(ele.querySelectorAll("span,a"),function(span){ - if(span && (span.innerHTML=="广告" || span.getAttribute("data-tuiguang"))){ - ele.remove(); - } - }); - if(killBaijiaType==2){ - [].forEach.call(ele.querySelectorAll("a>div>span+img"),function(img){ - if(img && /^https?:\/\/pic\.rmb\.bdstatic\.com/.test(img.src)){ - //checkBaijia(ele); - ele.remove(); - } - }); - } - } - }else if(ele.parentNode && ele.parentNode.id=="content_right"){ - if(ele.nodeName=="TABLE"){ + if (ele.parentNode && ele.parentNode.id == "content_left" && (ele.nodeName == "DIV" || ele.nodeName == "TABLE")) { + checkLeftItem(ele); + } else if (ele.parentNode && ele.parentNode.id == "content_right") { + if (ele.nodeName == "TABLE") { var eb = ele.querySelectorAll("tbody>tr>td>div"); - for(var i=0;idiv"); - if(nr){ - var nra=nr.querySelectorAll("a"); - for(i=0;idiv,#content_left>table"); - [].forEach.call(eles, e=>{clearOneAD(e)}); + } else { + let eles = ele.querySelectorAll("#content_left>div,#content_left>table"); + [].forEach.call(eles, e => {clearOneAD(e)}); } } - setTimeout(()=>{clearAD();},2000); + if (document.readyState == "complete" || document.readyState == "interactive") { + clearAD(); + } else { + document.addEventListener("readystatechange", e => { + if (document.readyState == "complete" || document.readyState == "interactive") { + clearAD(); + } + }); + } })(); \ No newline at end of file From 3459282efc51ff4aae71194b9f5b542224bb96c6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 24 Jun 2024 08:55:40 +0800 Subject: [PATCH 0170/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 33 +++++++++++++++++------------ 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index de50a68b225..4189ac9a3e7 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -1,11 +1,11 @@ // ==UserScript== -// @name 百度广告(首尾推广及右侧广告)清理 -// @name:en Kill Baidu AD +// @name Kill Baidu AD +// @name:zh-CN 百度广告(首尾推广及右侧广告)清理 // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @namespace hoothin -// @version 1.23.1 -// @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,刪除百家号 -// @description:en Just Kill Baidu AD +// @version 1.23.2 +// @description Kill Baidu AD +// @description:zh-CN 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,刪除百家号 // @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 // @author hoothin // @match *://www.baidu.com/* @@ -17,8 +17,6 @@ // @compatible firefox 测试通过 // @compatible opera 未测试 // @compatible safari 未测试 -// @contributionURL https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=rixixi@sina.com&item_name=Greasy+Fork+donation -// @contributionAmount 1 // ==/UserScript== (function() { @@ -124,15 +122,23 @@ } } - function clearAD() { - if (!document.querySelectorAll) return; - var mAds = document.querySelectorAll(".ec_wise_ad,.ec_youxuan_card,.page-banner"), i; - for (i = 0; i < mAds.length; i++) { - var mAd = mAds[i]; + function removeEcAd(ele) { + var mAds = ele.querySelectorAll(".ec_wise_ad,.ec_youxuan_card,.page-banner"); + for (let i = 0; i < mAds.length; i++) { + let mAd = mAds[i]; mAd.remove(); } + var baiduapp = ele.querySelector("#copyright+div"); + if (baiduapp && baiduapp.querySelector("[ref='open']")) { + baiduapp.remove(); + } + } + + function clearAD() { + if (!document.querySelectorAll) return; + removeEcAd(document); var list = document.querySelectorAll("#content_left>div,#content_left>table"); - for (i = 0; i < list.length; i++) { + for (let i = 0; i < list.length; i++) { let item = list[i]; checkLeftItem(item); } @@ -166,6 +172,7 @@ } } } else { + removeEcAd(ele); let eles = ele.querySelectorAll("#content_left>div,#content_left>table"); [].forEach.call(eles, e => {clearOneAD(e)}); } From 65ba6be763a9a724db2bfee9b2be65db5a36ddf8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 24 Jun 2024 09:00:03 +0800 Subject: [PATCH 0171/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 4189ac9a3e7..0af67c0bacb 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -4,7 +4,7 @@ // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @namespace hoothin // @version 1.23.2 -// @description Kill Baidu AD +// @description Just Kill Baidu AD // @description:zh-CN 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,刪除百家号 // @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 // @author hoothin From df7ec62a0c0df30d30e45233f148f9600c2529d4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 24 Jun 2024 09:01:42 +0800 Subject: [PATCH 0172/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 0af67c0bacb..fa20d03d6fa 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -1,10 +1,10 @@ // ==UserScript== -// @name Kill Baidu AD +// @name 百度广告(首尾推广及右侧广告)清理 // @name:zh-CN 百度广告(首尾推广及右侧广告)清理 // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @namespace hoothin // @version 1.23.2 -// @description Just Kill Baidu AD +// @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,刪除百家号 // @description:zh-CN 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,刪除百家号 // @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 // @author hoothin From 65982b8d8e5d028aed13421b395ea677040253ed Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 24 Jun 2024 09:11:37 +0800 Subject: [PATCH 0173/1065] 1.9.37.63 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index e223aeaa3f9..ed27f069e8f 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.62](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.63](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 8d54742fab2..29d555072ba 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.62 +// @version 1.9.37.63 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -7818,7 +7818,7 @@ }, 1); } - const loadmoreReg = /^\s*((点击)?加载更多|(點擊)?加載更多|load\s*more|もっと読み込む)[.…]*\s*$/i; + const loadmoreReg = /^\s*((点击)?加载更多|(點擊)?加載更多|(load|view)\s*more|もっと読み込む)[.…▼\s]*$/i; const defaultLoadmoreSel = ".loadMore,.LoadMore,[class*='load-more'],button.show_more,.button-show-more,button[data-testid='more-results-button'],#btn_preview_remain,.view-more-btn"; function getLoadMore(doc, loadmoreBtn) { if (!loadmoreBtn || !getBody(doc).contains(loadmoreBtn) || /less/.test(loadmoreBtn.innerText)) loadmoreBtn = null; From 1ed42a6588007ef3f420a3f8294881baa190b83f Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 24 Jun 2024 11:26:21 +0800 Subject: [PATCH 0174/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index fa20d03d6fa..274ba22d1dc 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -4,8 +4,8 @@ // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @namespace hoothin // @version 1.23.2 -// @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,刪除百家号 -// @description:zh-CN 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,刪除百家号 +// @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,删除百家号 +// @description:zh-CN 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,移除百家号 // @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 // @author hoothin // @match *://www.baidu.com/* From 713ad514eb251359c72a33b1e7bcf6820ffdb485 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 25 Jun 2024 01:59:13 +0000 Subject: [PATCH 0175/1065] Update items_all.json from http://wedata.net/databases/AutoPagerize/items_all.json --- Pagetual/items_all.json | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Pagetual/items_all.json b/Pagetual/items_all.json index df65f78aa80..15ff6e41a41 100644 --- a/Pagetual/items_all.json +++ b/Pagetual/items_all.json @@ -1,4 +1,19 @@ [ +{ + "resource_url": "http://wedata.net/items/86234", + "data": { + "insertBefore": "", + "pageElement": "//div[contains(concat(' ',@class,' '),' layout-book-section ')]", + "nextLink": "//li[contains(concat(' ',@class,' '),' to-next ')]/a", + "url": "^https://comic-boost\\.com/", + "exampleUrl": "https://comic-boost.com/genre/\r\nhttps://comic-boost.com/tag/%E7%95%B0%E4%B8%96%E7%95%8C" + }, + "database_resource_url": "http://wedata.net/databases/AutoPagerize", + "created_by": "t_f_m'", + "name": "comic boost 検索・一覧系", + "created_at": "2024-06-24T22:04:17+09:00", + "updated_at": "2024-06-24T22:04:17+09:00" +}, { "resource_url": "http://wedata.net/items/86233", "data": { @@ -76,8 +91,8 @@ { "resource_url": "http://wedata.net/items/86223", "data": { - "insertBefore": "//div[@class='width-container']/node()[last()]", "pageElement": "//div[@class='book-product-wrapper']", + "insertBefore": "//div[@class='width-container']/node()[last()]", "nextLink": "//li[contains(concat(' ',@class,' '),' to-next ')]/a", "url": "^https://comic-boost\\.com/content/", "exampleUrl": "https://comic-boost.com/content/00050001" @@ -86,7 +101,7 @@ "created_by": "t_f_m'", "name": "comic boost", "created_at": "2024-04-23T03:06:24+09:00", - "updated_at": "2024-04-23T03:06:24+09:00" + "updated_at": "2024-06-24T22:05:45+09:00" }, { "resource_url": "http://wedata.net/items/86219", From 42d2d0fea3f4f02d20ce78712f1174641d20d1f0 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 25 Jun 2024 01:59:31 +0000 Subject: [PATCH 0176/1065] Update version of Pagetual rules to 35 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index a7873645902..8f92bfdd497 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -34 +35 From 9c3e8e8490f2a42cf1ce48e9cf776b1be48faaa1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 25 Jun 2024 18:24:47 +0800 Subject: [PATCH 0177/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 4cfe0a9c2dd..2503e24e3f3 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.23.4 +// @version 2024.6.25.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 @@ -20381,7 +20381,8 @@ ImgOps | https://imgops.com/#b#`; if(prefs.imgWindow.backgroundColor){ this.imgWindow.style.backgroundColor=prefs.imgWindow.backgroundColor; } - getBody(document).appendChild(container); + + document.documentElement.appendChild(container); this.rotatedRadians=0;//已经旋转的角度 this.zoomLevel=0; @@ -25410,6 +25411,11 @@ ImgOps | https://imgops.com/#b#`; }, "default": prefs.floatBar.globalkeys.type }, + 'floatBar.globalkeys.invertInitShow': { + label: i18n("initShow"), + type: 'checkbox', + "default": prefs.floatBar.globalkeys.invertInitShow + }, 'floatBar.globalkeys.closeAfterPreview': { label: i18n("closeAfterPreview"), type: 'checkbox', @@ -25431,11 +25437,6 @@ ImgOps | https://imgops.com/#b#`; "default": prefs.previewMaxSizeH || 0, line: 'end', }, - 'floatBar.globalkeys.invertInitShow': { - label: i18n("initShow"), - type: 'checkbox', - "default": prefs.floatBar.globalkeys.invertInitShow - }, 'floatBar.globalkeys.previewFollowMouse': { label: i18n("previewFollowMouse"), type: 'checkbox', @@ -26191,6 +26192,7 @@ ImgOps | https://imgops.com/#b#`; } document.head.appendChild(configStyle); GM_config.open(); + document.documentElement.appendChild(GM_config.frame); setTimeout(()=>{ if (GM_config.frame && GM_config.frame.contentDocument.body.innerHTML === "") { From c5f0b8a746e53d98b2f2f7bfcd942e79cf06e0a0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 25 Jun 2024 21:15:36 +0800 Subject: [PATCH 0178/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 2503e24e3f3..6e03e24d671 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -24538,7 +24538,7 @@ ImgOps | https://imgops.com/#b#`; }; found = true; } - } else if (target.children.length == 1 && target.children[0].nodeName == "IMG") { + } else if (target.children.length == 1 && !target.innerText.trim() && target.children[0].nodeName == "IMG") { target = target.children[0]; found = true; } else if (prefs.floatBar.listenBg && broEle && hasBg(broEle)) { @@ -24577,7 +24577,7 @@ ImgOps | https://imgops.com/#b#`; } if (!found) { let checkEle = target; - while(checkEle && checkEle.children.length === 1) { + while(checkEle && !checkEle.innerText.trim() && checkEle.children.length === 1) { checkEle = checkEle.children[0]; if (checkEle.nodeName === "IMG") { target = checkEle; From aa879c9e5e0a5cd2841d8e244ec4ded64d4cb83b Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 25 Jun 2024 21:40:01 +0800 Subject: [PATCH 0179/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 6e03e24d671..ef66dbb7096 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.25.1 +// @version 2024.6.25.2 // @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 @@ -20382,7 +20382,11 @@ ImgOps | https://imgops.com/#b#`; this.imgWindow.style.backgroundColor=prefs.imgWindow.backgroundColor; } - document.documentElement.appendChild(container); + if (gallery && gallery.shown) { + document.documentElement.appendChild(container); + } else { + getBody(document).appendChild(container); + } this.rotatedRadians=0;//已经旋转的角度 this.zoomLevel=0; @@ -21336,7 +21340,8 @@ ImgOps | https://imgops.com/#b#`; let wSize = getWindowSize(); let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2), padding2 = 50, left, top;//内外侧间距 - let scrolled = prefs.imgWindow.fixed ? {x: 0, y: 0} : getScrolled(); + imgWindow.style.position = "fixed"; + let scrolled = {x: 0, y: 0}; if (imme) { imgWindow.classList.remove("pv-pic-window-transition-all"); From a78f7caa92bc0b4281f2502fa6edf7b639b5d291 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 26 Jun 2024 09:21:08 +0800 Subject: [PATCH 0180/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index f6778782041..ae66511424f 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1635,6 +1635,20 @@ var siteInfo = [ query: ".single-image>img" } }, + { + name: "behance", + url: /^https:\/\/www\.behance\.net/, + xhr: { + url: "a[href^='/gallery/']", + query: "img[class^='ImageElement-image']" + }, + getExtSrc: function() { + if (this.className && this.className.indexOf && this.className.indexOf("ProjectCoverNeue-link") !== -1) { + let img = this.parentNode.parentNode.querySelector("picture>img"); + if (img) return img.src; + } + } + }, { name: "postimg host", src: /^https:\/\/i\.postimg\.cc/, From da7f6f00608775f573090fb9854b4df947482915 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 26 Jun 2024 09:23:41 +0800 Subject: [PATCH 0181/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 44 +++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index ef66dbb7096..8ab02aefcc0 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.25.2 +// @version 2024.6.26.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 @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1398739/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1400550/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1399329/pvcep_lang.js // @downloadURL https://greasyfork.org/scripts/24204-picviewer-ce/code/Picviewer%20CE+.user.js // @updateURL https://greasyfork.org/scripts/24204-picviewer-ce/code/Picviewer%20CE+.meta.js @@ -18846,7 +18846,7 @@ ImgOps | https://imgops.com/#b#`; background-position: 0 0, 10px 10px;\ }\ .pv-gallery-maximize-container>.maximizeChild.selected{\ - border: 5px solid #ff0000;\ + border: 5px solid #ff000050;\ }\ .pv-gallery-maximize-container img{\ max-width: 100%;\ @@ -18854,7 +18854,7 @@ ImgOps | https://imgops.com/#b#`; transform: scale3d(1, 1, 1);\ cursor: zoom-in;\ min-height: 88px;\ - border-radius: 10px;\ + border-radius: 20px;\ }\ .pv-gallery-maximize-container>.maximizeChild:hover img {\ transform: scale3d(1.1, 1.1, 1.1);\ @@ -24089,7 +24089,7 @@ ImgOps | https://imgops.com/#b#`; if (rule.getImage) { newSrc = rule.getImage.call(target || img, a, p, rule); } else newSrc = null; - if (!base64Img && rule.r) { + if (!base64Img && rule.r && img.src) { if (!newSrc) newSrc = img.src; newSrc = this.replaceByRule(newSrc, rule); } @@ -24467,11 +24467,31 @@ ImgOps | https://imgops.com/#b#`; imgSrc = nsrc[0]; src = nsrc[1]; } + if (!matchedRule.xhrLink) { + let imgPN = target; + let imgPA, imgPE = []; + do { + if (imgPN.nodeName.toUpperCase() == 'A') { + imgPA = imgPN; + break; + } + } while (imgPN = imgPN.parentElement); + imgPN = target; + while (imgPN = imgPN.parentElement) { + if (imgPN.nodeName.toUpperCase() == 'BODY') { + break; + } else { + imgPE.push(imgPN); + } + } + src = matchedRule.getImage(target, imgPA, imgPE) || src; + } + let noActual = src === imgSrc; result = { src: src, - type: matchedRule.xhrLink && !targetBg ? "link" : "rule", + type: matchedRule.xhrLink && noActual ? "link" : "rule", imgSrc: imgSrc, - noActual: src === imgSrc, + noActual: noActual, img: target, xhr: matchedRule.xhr }; @@ -24543,7 +24563,7 @@ ImgOps | https://imgops.com/#b#`; }; found = true; } - } else if (target.children.length == 1 && !target.innerText.trim() && target.children[0].nodeName == "IMG") { + } else if (target.children.length == 1 && !(target.textContent && target.textContent.trim()) && target.children[0].nodeName == "IMG") { target = target.children[0]; found = true; } else if (prefs.floatBar.listenBg && broEle && hasBg(broEle)) { @@ -24582,7 +24602,7 @@ ImgOps | https://imgops.com/#b#`; } if (!found) { let checkEle = target; - while(checkEle && !checkEle.innerText.trim() && checkEle.children.length === 1) { + while(checkEle && !(checkEle.textContent && checkEle.textContent.trim()) && checkEle.children.length === 1) { checkEle = checkEle.children[0]; if (checkEle.nodeName === "IMG") { target = checkEle; @@ -24648,8 +24668,8 @@ ImgOps | https://imgops.com/#b#`; if (matchedRule.rules.length > 0 && target.nodeName.toUpperCase() != 'IMG') { let src = result.src, img = {src: src}, type, imgSrc = src; try { - var imgPN=target; - var imgPA,imgPE=[]; + let imgPN=target; + let imgPA,imgPE=[]; while(imgPN=imgPN.parentElement){ if(imgPN.nodeName.toUpperCase()=='A'){ imgPA=imgPN; @@ -24664,7 +24684,7 @@ ImgOps | https://imgops.com/#b#`; imgPE.push(imgPN); } } - var newSrc = matchedRule.getImage(img, imgPA, imgPE, target); + let newSrc = matchedRule.getImage(img, imgPA, imgPE, target); if (newSrc && imgSrc != newSrc) { let srcs, description; src = newSrc; From ea0092ba4f11d00804f9efbac1695d592a2344bc Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 26 Jun 2024 13:12:44 +0800 Subject: [PATCH 0182/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 82 +++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 21 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 8ab02aefcc0..33f5f0a2d76 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます // @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente // @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения -// @version 2024.6.26.1 +// @version 2024.6.26.2 // @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 @@ -15156,7 +15156,7 @@ ImgOps | https://imgops.com/#b#`; var targetP; if(!dataset(target,'src') && (targetP=target.parentNode) && !dataset(targetP,'src'))return; - self.select(targetP? targetP : target); + self.select(targetP || target, false, true); },false); //点击读取错误的图片占位符重新读取 @@ -16182,9 +16182,9 @@ ImgOps | https://imgops.com/#b#`; this.select(this.getThumSpan(true)); }, selectNext:function(){ - this.select(this.getThumSpan()); + this.select(this.getThumSpan(), false, true); }, - select:function(ele,noTransition){ + select:function(ele, noTransition, checkEnd){ if(!ele || this.selected==ele)return; if(this.selected){ this.selected.classList.remove(this.selectedClassName); @@ -16194,7 +16194,7 @@ ImgOps | https://imgops.com/#b#`; ele.classList.add('pv-gallery-sidebar-thumb_selected'); this.selected=ele; - this.arrowVisib(); + this.arrowVisib(checkEnd); var self=this; clearTimeout(this.loadImgTimer); @@ -17587,7 +17587,7 @@ ImgOps | https://imgops.com/#b#`; } } }, - arrowVisib:function(){//当当前选择元素的前面或者后面没有元素的时候隐藏控制箭头 + arrowVisib:function(checkEnd){//当当前选择元素的前面或者后面没有元素的时候隐藏控制箭头 var icps=this.eleMaps['img-controler-pre'].style; var icns=this.eleMaps['img-controler-next'].style; @@ -17605,7 +17605,7 @@ ImgOps | https://imgops.com/#b#`; }; // 最后几张图片,滚到底部添加新的图片 - if (nextSpan && prefs.gallery.scrollEndAndLoad && this._isLastSpan(nextSpan)) { + if (prefs.gallery.scrollEndAndLoad && checkEnd && (!nextSpan || this._isLastSpan(nextSpan))) { this.scrollToEndAndReload(); } @@ -17878,24 +17878,49 @@ ImgOps | https://imgops.com/#b#`; scrollToEndAndReload: function() {// 滚动主窗口到最底部,然后自动重载库的图片 if (this.isScrollToEndAndReloading) return; this.isScrollToEndAndReloading = true; + var scrollTarget; + if (document.documentElement.scrollTop) { + scrollTarget = document.documentElement; + } else if (getBody(document).scrollTop) { + scrollTarget = getBody(document); + } else if (this.data && this.data.length) { + let tempEle; + for (let i = 0; i < this.data.length; i++) { + tempEle = this.data[i].img; + if (tempEle && tempEle.parentNode) { + break; + } + } + if (tempEle) { + while (tempEle && (tempEle.scrollHeight === tempEle.clientHeight || unsafeWindow.getComputedStyle(tempEle).overflowY === "hidden")) { + tempEle = tempEle.parentNode; + } + } + if (tempEle) scrollTarget = tempEle; + } + scrollTarget = scrollTarget || document.documentElement; var self = this; setTimeout(() => { self.isScrollToEndAndReloading = false; - var des=document.documentElement.style; - des.overflow=''; + var des = document.documentElement.style; + des.overflow = ''; document.head.appendChild(self.hideScrollStyle); - window.scrollTo(0, 9999999); - setTimeout(() => { - des.overflow='hidden'; - document.head.removeChild(self.hideScrollStyle); - }, 0); - - clearTimeout(self.reloadTimeout); - self.reloadTimeout = setTimeout(function(){ - // self.reload(); - self.reloadNew(); - self.loadThumb(); - }, 1000); + let scrollIntv = setInterval(function() { + let scrollTop = scrollTarget.scrollTop; + scrollTarget.scrollTop += 500; + if (scrollTop === scrollTarget.scrollTop) { + clearInterval(scrollIntv); + setTimeout(() => { + des.overflow = 'hidden'; + document.head.removeChild(self.hideScrollStyle); + }, 0); + clearTimeout(self.reloadTimeout); + self.reloadTimeout = setTimeout(function() { + self.reloadNew(); + self.loadThumb(); + }, 1000); + } + }, 1); }, 300); }, exportImages: function () {// 导出所有图片到新窗口 @@ -24657,6 +24682,21 @@ ImgOps | https://imgops.com/#b#`; }; found = true; break; + } else if (ele.nodeName.toUpperCase() == 'CANVAS') { + let src = ele.src || ele.dataset.src; + if (src) { + target = ele; + let nsrc = src, noActual = true, type = "scale"; + result = { + src: nsrc, + type: type, + imgSrc: src, + noActual:noActual, + img: target + }; + found = true; + break; + } } } } From 59d20ff24c4d9fb099580d02ddd754d24803e48e Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 26 Jun 2024 13:29:23 +0800 Subject: [PATCH 0183/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 81 +++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 28 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 29d555072ba..b44aae49db3 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.63 +// @version 1.9.37.64 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -2139,7 +2139,7 @@ if (!body) return null; let bodyHeight = parseInt(body.offsetHeight || body.scrollHeight); let curHeight = bodyHeight, curWidth = 0; - let windowHeight = window.innerHeight || document.documentElement.clientHeight; + let windowHeight = window.innerHeight || document.documentElement.clientHeight; let windowWidth = window.innerWidth || document.documentElement.clientWidth; let needCheckNext = (doc == document && this.initNext), nextLeftPos = 0; if (needCheckNext && this.initNext.getBoundingClientRect) { @@ -3150,8 +3150,8 @@ let scrollHeight = video.scrollHeight || video.offsetHeight; if (compareNodeName(video, ["iframe"])) { } else if (scrollWidth > 100 && scrollHeight > 100) { - let winWidth = window.innerWidth || document.documentElement.clientWidth; - let winHeight = window.innerHeight || document.documentElement.clientHeight; + let winWidth = window.innerWidth || document.documentElement.clientWidth; + let winHeight = window.innerHeight || document.documentElement.clientHeight; if (scrollWidth > winWidth>>1 && scrollHeight > winHeight>>1) { debug("Disable when large media found"); } else { @@ -5474,13 +5474,38 @@ } let devicePixelRatio = window.devicePixelRatio; let scrollRange = Math.ceil(scrollRange_o / devicePixelRatio); + + let scrollTarget, body = getBody(document); + if (document.documentElement.scrollTop) { + scrollTarget = document.documentElement; + } else if (body.scrollTop) { + scrollTarget = body; + } else { + let tempEle; + let img = body.querySelector('img'); + if (img) { + tempEle = img; + while (tempEle && (tempEle.scrollHeight === tempEle.clientHeight || getComputedStyle(tempEle).overflowY === "hidden")) { + tempEle = tempEle.parentNode; + } + } + if (!tempEle && document.activeElement) { + let tempEle = document.activeElement; + while (tempEle && (tempEle.scrollHeight === tempEle.clientHeight || getComputedStyle(tempEle).overflowY === "hidden")) { + tempEle = tempEle.parentNode; + } + } + if (tempEle) scrollTarget = tempEle; + } + scrollTarget = scrollTarget || document.documentElement; + autoScrollInterval = setInterval(() => { if (isPause) return; if (devicePixelRatio !== window.devicePixelRatio) { devicePixelRatio = window.devicePixelRatio; scrollRange = Math.ceil(scrollRange_o / devicePixelRatio); } - window.scroll(window.scrollX, window.scrollY + scrollRange); + scrollTarget.scrollTop += scrollRange; }, parseInt(1000 / autoScroll)); } @@ -7343,22 +7368,22 @@ }); } - function isInViewPort(element) { + function isInViewPort(element) { if (!getBody(document).contains(element)) return false; - const viewWidth = window.innerWidth || document.documentElement.clientWidth; - const viewHeight = window.innerHeight || document.documentElement.clientHeight; - const { + const viewWidth = window.innerWidth || document.documentElement.clientWidth; + const viewHeight = window.innerHeight || document.documentElement.clientHeight; + const { top, right, bottom, left, - } = element.getBoundingClientRect(); + } = element.getBoundingClientRect(); - return ( - top >= 0 && - left >= 0 && - right <= viewWidth + 1 && - top <= viewHeight * rate && + return ( + top >= 0 && + left >= 0 && + right <= viewWidth + 1 && + top <= viewHeight * rate && isVisible(element, _unsafeWindow) ); } @@ -7369,22 +7394,22 @@ for (let i = 0; i < pageBars.length; i++) { let pageBar = pageBars[i]; if (!pageBar || !getBody(document).contains(pageBar)) continue; - let { + let { top, right, bottom, left, - } = pageBar.getBoundingClientRect(); + } = pageBar.getBoundingClientRect(); if (top > 500) { nextBar = pageBar; preBar = (i - 1 >= 0 ? pageBars[i - 1] : null); if (pageBar && getBody(document).contains(pageBar)) { - let { + let { top, right, bottom, left, - } = pageBar.getBoundingClientRect(); + } = pageBar.getBoundingClientRect(); if (top < -500) { preBar = pageBar; } else preBar = (i - 2 >= 0 ? pageBars[i - 2] : null); @@ -8816,20 +8841,20 @@ var scrollingToResize = false; function isTouchViewPort(element) { - const viewWidth = window.innerWidth || document.documentElement.clientWidth; - const viewHeight = window.innerHeight || document.documentElement.clientHeight; - const { + const viewWidth = window.innerWidth || document.documentElement.clientWidth; + const viewHeight = window.innerHeight || document.documentElement.clientHeight; + const { top, right, bottom, left, - } = element.getBoundingClientRect(); + } = element.getBoundingClientRect(); - return ( - top < viewHeight && - left < viewWidth && - right > 0 && - bottom > 0 + return ( + top < viewHeight && + left < viewWidth && + right > 0 && + bottom > 0 ); } From d24692776297eabdc7d364e09e843b20d16e4b8c Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 26 Jun 2024 13:30:02 +0800 Subject: [PATCH 0184/1065] Update README.md --- Pagetual/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index ed27f069e8f..55fa9308c9c 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.63](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.64](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* From 7f37b873cba7de7e0244b65134ce813e9455dad9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 26 Jun 2024 13:35:38 +0800 Subject: [PATCH 0185/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index b44aae49db3..e7a857481eb 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -5476,22 +5476,25 @@ let scrollRange = Math.ceil(scrollRange_o / devicePixelRatio); let scrollTarget, body = getBody(document); - if (document.documentElement.scrollTop) { + let checkOverflow = ele => { + return ele.scrollHeight !== ele.clientHeight && getComputedStyle(ele).overflowY !== "hidden"; + }; + if (document.documentElement.scrollTop || checkOverflow(document.documentElement)) { scrollTarget = document.documentElement; - } else if (body.scrollTop) { + } else if (body.scrollTop || checkOverflow(body)) { scrollTarget = body; } else { let tempEle; let img = body.querySelector('img'); if (img) { tempEle = img; - while (tempEle && (tempEle.scrollHeight === tempEle.clientHeight || getComputedStyle(tempEle).overflowY === "hidden")) { + while (tempEle && !checkOverflow(tempEle)) { tempEle = tempEle.parentNode; } } if (!tempEle && document.activeElement) { let tempEle = document.activeElement; - while (tempEle && (tempEle.scrollHeight === tempEle.clientHeight || getComputedStyle(tempEle).overflowY === "hidden")) { + while (tempEle && !checkOverflow(tempEle)) { tempEle = tempEle.parentNode; } } From c0610d15b7c90d182344f94e4e893dde548043d6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 26 Jun 2024 16:26:05 +0800 Subject: [PATCH 0186/1065] 1.9.37.65 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 55fa9308c9c..6b01f48fdae 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.64](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.65](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index e7a857481eb..0bf529224ee 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,7 +10,7 @@ // @name:fr Pagetual // @name:it Pagetual // @namespace hoothin -// @version 1.9.37.64 +// @version 1.9.37.65 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -2655,6 +2655,7 @@ "body [class*=Pages]>.curr+a", "body [class*=pagination] .next-btn", ".page>em+a", + "[name*=nextPage]", '//button[contains(@class, "Page")][text()="Next"]', '//button[contains(@class, "page")][text()="next"]' ]; From 478f6761fd51de99115ee906e24ac297a5563022 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Jun 2024 09:14:43 +0800 Subject: [PATCH 0187/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index dd1282bd6df..4ea18e39686 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5841,7 +5841,23 @@ "url": "^https?://www\\.baidu\\.com/(s|baidu)\\b.", "pageBarTop": 75, "replaceElement": "#page", + "exclude": ".AC-style-logo,.killRight", + "wait": 500 +}, +{ + "name": "Baidu", + "insertPos": 1, + "nextLink": [ + "//*[@id=\"page\"]/div/a[contains(text(),'下')]", + "//*[@id=\"page\"]/div/a[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", + "include": ".killRight", "wait": 500 }, { From 90d5c420fa60563830067b44251cf26ae57b641d Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Fri, 28 Jun 2024 01:15:03 +0000 Subject: [PATCH 0188/1065] Update version of Pagetual rules to 36 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 8f92bfdd497..7facc89938b 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -35 +36 From 8775b7b96888ca999b32bc371a0381d2bc66809f Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Jun 2024 09:32:15 +0800 Subject: [PATCH 0189/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 76 ++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 274ba22d1dc..a551473a953 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -3,7 +3,7 @@ // @name:zh-CN 百度广告(首尾推广及右侧广告)清理 // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @namespace hoothin -// @version 1.23.2 +// @version 1.23.3 // @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,删除百家号 // @description:zh-CN 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,移除百家号 // @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 @@ -11,6 +11,11 @@ // @match *://www.baidu.com/* // @match *://m.baidu.com/* // @grant GM_xmlhttpRequest +// @grant GM_addStyle +// @grant GM_getValue +// @grant GM_setValue +// @grant GM_registerMenuCommand +// @grant GM_unregisterMenuCommand // @run-at document-start // @license MIT License // @compatible chrome 测试通过 @@ -21,7 +26,7 @@ (function() { 'use strict'; - var MO = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, killBaijiaType = 1; + var MO = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, killBaijiaType = 1, killRight, killRightStyle, killRightRegister, hidePicture, hidePictureStyle, hidePictureRegister; if (MO) { var observer = new MO(function(records) { records.map(function(record) { @@ -136,6 +141,9 @@ function clearAD() { if (!document.querySelectorAll) return; + if (killRight) { + document.body.classList.add("killRight"); + } else document.body.classList.remove("killRight"); removeEcAd(document); var list = document.querySelectorAll("#content_left>div,#content_left>table"); for (let i = 0; i < list.length; i++) { @@ -177,6 +185,70 @@ [].forEach.call(eles, e => {clearOneAD(e)}); } } + function initCss() { + killRightStyle && killRightStyle.parentNode && killRightStyle.parentNode.removeChild(killRightStyle); + if (killRight) { + killRightStyle = GM_addStyle(` + #content_right,[tpl="recommend_list"],#rs_new { + display: none; + } + #container.sam_newgrid { + width: calc(100% - 150px); + } + #container.sam_newgrid #content_left { + column-width: 560px; + width: 100%; + } + #content_left .result-op, #content_left .result { + page-break-inside: avoid; + } + `); + } + hidePictureStyle && hidePictureStyle.parentNode && hidePictureStyle.parentNode.removeChild(hidePictureStyle); + if (hidePicture) { + hidePictureStyle = GM_addStyle(` + #wrapper_wrapper { + background: rgba(228, 228, 228, 0.29); + } + .c-span3,.c-span6>.c-img,[tpl="short_video"],[data-module="gp-peopleintro-img-click"],div[class^="img-container"] { + display: none; + } + a,a:active,#content_right a { + color: rgb(51,51,51); + } + em { + color: #4E6EF2!important; + } + .c-container.result[tpl], .result-op.c-container[tpl], .result-op.xpath-log.new-pmd[tpl] { + padding-top: 0px; + padding-bottom: 25px; + border-bottom: 1px solid rgba(211, 211, 211, 0.63); + } + `); + } + } + function registerMenuCommand() { + initCss(); + hidePictureRegister = GM_registerMenuCommand(hidePicture ? "❌ 恢复图片" : "✅ 隐藏图片", () => { + GM_unregisterMenuCommand(killRightRegister); + GM_unregisterMenuCommand(hidePictureRegister); + hidePicture = !hidePicture; + GM_setValue("hidePicture", hidePicture); + registerMenuCommand(); + }); + killRightRegister = GM_registerMenuCommand(killRight ? "❌ 恢复右边栏与布局" : "✅ 隐藏右边栏并多列显示", () => { + GM_unregisterMenuCommand(killRightRegister); + GM_unregisterMenuCommand(hidePictureRegister); + killRight = !killRight; + GM_setValue("killRight", killRight); + registerMenuCommand(); + }); + } + try { + killRight = !!GM_getValue("killRight"); + hidePicture = !!GM_getValue("hidePicture"); + registerMenuCommand(); + } catch(e) {} if (document.readyState == "complete" || document.readyState == "interactive") { clearAD(); } else { From 8d4b4d7e0d3f645489299d166cc2820952fc9da3 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Jun 2024 15:31:10 +0800 Subject: [PATCH 0190/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index a551473a953..44d3f1d23cc 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -210,9 +210,12 @@ #wrapper_wrapper { background: rgba(228, 228, 228, 0.29); } - .c-span3,.c-span6>.c-img,[tpl="short_video"],[data-module="gp-peopleintro-img-click"],div[class^="img-container"] { + .cos-col[style*="width:33"],.cos-col[style*="width:25"],.c-span3,.c-span4,.c-span6>.c-img,[tpl="short_video"],[data-module="gp-peopleintro-img-click"],div[class^="img-container"],[data-module="normal-img"],[role="img"],.c-gap-inner-y-img,div[class*="only-multi-image"] { display: none; } + .new-pmd .c-span9 { + width: 100%; + } a,a:active,#content_right a { color: rgb(51,51,51); } From b609bb9eee848acdc533e412fb40b82c92693c40 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Jun 2024 15:34:35 +0800 Subject: [PATCH 0191/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 44d3f1d23cc..15c9b639a9b 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -232,14 +232,14 @@ } function registerMenuCommand() { initCss(); - hidePictureRegister = GM_registerMenuCommand(hidePicture ? "❌ 恢复图片" : "✅ 隐藏图片", () => { + hidePictureRegister = GM_registerMenuCommand(hidePicture ? "✅ 恢复图片" : "❌ 隐藏图片", () => { GM_unregisterMenuCommand(killRightRegister); GM_unregisterMenuCommand(hidePictureRegister); hidePicture = !hidePicture; GM_setValue("hidePicture", hidePicture); registerMenuCommand(); }); - killRightRegister = GM_registerMenuCommand(killRight ? "❌ 恢复右边栏与布局" : "✅ 隐藏右边栏并多列显示", () => { + killRightRegister = GM_registerMenuCommand(killRight ? "✅ 恢复右边栏与布局" : "❌ 隐藏右边栏并多列显示", () => { GM_unregisterMenuCommand(killRightRegister); GM_unregisterMenuCommand(hidePictureRegister); killRight = !killRight; From 5f6a2379cfeae9c0b5d6b9076f79852a712ce411 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Jun 2024 15:48:10 +0800 Subject: [PATCH 0192/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 15c9b639a9b..5d65b5a544e 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -213,8 +213,8 @@ .cos-col[style*="width:33"],.cos-col[style*="width:25"],.c-span3,.c-span4,.c-span6>.c-img,[tpl="short_video"],[data-module="gp-peopleintro-img-click"],div[class^="img-container"],[data-module="normal-img"],[role="img"],.c-gap-inner-y-img,div[class*="only-multi-image"] { display: none; } - .new-pmd .c-span9 { - width: 100%; + .new-pmd .c-span9,.cos-col[style*="width:33"]+div,.cos-col[style*="width:25"]+div { + width: 100%!important; } a,a:active,#content_right a { color: rgb(51,51,51); From 43767a4dcf59c01e1235f4547509e3eb5de7d635 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Jun 2024 18:04:29 +0800 Subject: [PATCH 0193/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 179 +++++++++++++++++++++++++++- 1 file changed, 177 insertions(+), 2 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 5d65b5a544e..71cee164e68 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -3,19 +3,22 @@ // @name:zh-CN 百度广告(首尾推广及右侧广告)清理 // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @namespace hoothin -// @version 1.23.3 +// @version 1.23.4 // @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,删除百家号 // @description:zh-CN 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,移除百家号 // @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 // @author hoothin // @match *://www.baidu.com/* // @match *://m.baidu.com/* +// @match *://greasyfork.org/*/scripts/24192-* // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue +// @grant GM_openInTab // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand +// @connect * // @run-at document-start // @license MIT License // @compatible chrome 测试通过 @@ -26,7 +29,7 @@ (function() { 'use strict'; - var MO = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, killBaijiaType = 1, killRight, killRightStyle, killRightRegister, hidePicture, hidePictureStyle, hidePictureRegister; + var MO = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, killBaijiaType = 1, killRight, killRightStyle, killRightRegister, hidePicture, hidePictureStyle, hidePictureRegister, blackList; if (MO) { var observer = new MO(function(records) { records.map(function(record) { @@ -74,6 +77,12 @@ item.remove(); return; } else { + let title = item.querySelector("h3"); + let isBlack = checkBlackList(mu, title && title.innerText); + if (isBlack) { + item.remove(); + return; + } let link = item.querySelector("a[href*='www.baidu.com/link']"); if (link) link.href = mu; } @@ -230,6 +239,91 @@ `); } } + + function checkBlackList(url, title) { + if (!blackList || !blackList.forEach) return false; + for (let i = 0; i < blackList.length; i++) { + try { + let isBlack = checkBlack(url, title, blackList[i]); + if (isBlack) return true; + } catch (e) { + console.log(e); + } + } + return false; + } + + function checkBlack(url, title, pattern) { + if (!pattern || !pattern.trim() || pattern.indexOf("#") === 0 || pattern.indexOf("!") === 0 || pattern.indexOf(" ") === 0 || pattern.indexOf("Update") === 0) return false; + if (pattern.indexOf("/") === 0) { + let match = pattern.match(/^\/(.*)\/(\w*)$/); + if (match) { + return new RegExp(match[1], match[2]).test(url); + } + } + if (pattern.indexOf("title") === 0) { + let match = pattern.replace("title", "").trim(); + if (match.indexOf("/") === 0) { + match = match.match(/^\/(.*)\/(\w*)$/); + if (match) { + return new RegExp(match[1], match[2]).test(title); + } + } else if (match.indexOf("=~") === 0) { + match = match.match(/^=~\s*\/(.*)\/(\w*)$/); + if (match) { + return new RegExp(match[1], match[2]).test(title); + } + } else if (match.indexOf("=") === 0) { + match = match.match(/^=\s*"(.*)"$/); + if (match) { + return title === match[1]; + } + } else if (match.indexOf("^=") === 0) { + match = match.match(/^\^=\s*"(.*)"$/); + if (match) { + return title.indexOf(match[1]) === 0; + } + } else if (match.indexOf("$=") === 0) { + match = match.match(/^\$=\s*"(.*)"$/); + if (match) { + return title.endsWith(match[1]); + } + } else if (match.indexOf("*=") === 0) { + match = match.match(/^\*=\s*"(.*)"$/); + if (match) { + return title.indexOf(match[1]) !== -1; + } + } + } + return matchPattern(url, pattern); + } + + function matchPattern(url, pattern) { + if (pattern === '') { + return true; + } + let match = pattern.match(/^(\*|[\w-]+):\/{2,3}(?:(\*|\*\.[^/*]+|[^/*]+)\/)?(.*)$/); + if (!match) return false; + const [, scheme, host, path] = match + const urlScheme = url.split(':')[0]; + const urlParam = new URL(url); + if (scheme === '*' || urlScheme === scheme) { + if (host !== '*') { + const urlHost = urlParam.hostname; + if (host.startsWith('*')) { + const hostPattern = host.slice(2); + if (!urlHost.endsWith(hostPattern)) return false; + } else { + if (urlHost !== host) return false; + } + } + const urlPath = urlParam.pathname + urlParam.search; + const pathRegex = new RegExp(`^${path.replace(/([\.\?])/g, '\\$1').replace(/\*/g, '.*')}$`); + return pathRegex.test(urlPath); + } + return false; + } + function registerMenuCommand() { initCss(); hidePictureRegister = GM_registerMenuCommand(hidePicture ? "✅ 恢复图片" : "❌ 隐藏图片", () => { @@ -250,7 +344,88 @@ try { killRight = !!GM_getValue("killRight"); hidePicture = !!GM_getValue("hidePicture"); + blackList = GM_getValue("blackList") || []; + if (location.host === "greasyfork.org") { + let parent = document.querySelector('#additional-info'); + let baseCon = document.createElement('div'); + baseCon.style.margin = '20px'; + parent.insertBefore(baseCon, parent.children[0]); + let checkIndex = 0; + let createCheckbox = (name, defaultValue) => { + let box = document.createElement('div'); + let checkbox = document.createElement('input'); + checkbox.type = 'checkbox'; + checkbox.checked = defaultValue; + let id = 'stcnsc-checkbox' + checkIndex++; + checkbox.id = id; + let label = document.createElement('label'); + label.setAttribute('for', id); + label.innerText = name; + box.appendChild(checkbox); + box.appendChild(label); + baseCon.appendChild(box); + return checkbox; + }; + let hidePictureInput = createCheckbox('隐藏图片', hidePicture); + let killRightInput = createCheckbox('隐藏右边栏并多列显示', killRight); + let importInput = document.createElement('textarea'); + importInput.placeholder = '订阅 uBlacklist 规则:如 https://git.io/ublacklist'; + importInput.style.width = '100%'; + importInput.style.marginBottom = '10px'; + baseCon.appendChild(importInput); + let blackListInput = document.createElement('textarea'); + blackListInput.placeholder = '*://*.12345.cn/*\n*://*.54321.com/*\n一行一条'; + blackListInput.style.width = '100%'; + blackListInput.style.minHeight = "60px"; + blackListInput.value = blackList.join("\n"); + baseCon.appendChild(blackListInput); + function saveBlackList() { + GM_setValue("blackList", blackList); + } + let saveBtn = document.createElement('button'); + saveBtn.innerText = '保存'; + saveBtn.style.display = 'block'; + saveBtn.style.fontSize = 'x-large'; + saveBtn.style.fontWeight = 'bold'; + saveBtn.style.pointerEvents = 'all'; + saveBtn.style.cursor = 'pointer'; + saveBtn.addEventListener("click", function(e) { + hidePicture = hidePictureInput.checked; + killRight = killRightInput.checked; + GM_setValue("hidePicture", hidePicture); + GM_setValue("killRight", killRight); + if (importInput.value) { + alert("读取规则中……"); + let importUrls = importInput.value.trim().split("\n"); + importUrls.forEach(url => { + url = url && url.trim(); + if (!url) return; + GM_xmlhttpRequest({ + url: url, + onload: function(res) { + let result = res.response || res.responseText; + if (!result) return; + blackList = blackList.concat(result.split("\n")); + blackList = blackList.filter((value, index) => blackList.indexOf(value) === index); + saveBlackList(); + blackListInput.value = blackList.join("\n"); + } + }); + }); + } else if (blackListInput.value) { + blackList = blackListInput.value.split("\n"); + saveBlackList(); + } + alert("设置完毕"); + }); + baseCon.appendChild(saveBtn); + baseCon.appendChild(document.createElement("hr")); + return; + } registerMenuCommand(); + GM_registerMenuCommand("🔧 打开设置页", () => { + GM_openInTab("https://greasyfork.org/scripts/24192", {active: true}); + }); } catch(e) {} if (document.readyState == "complete" || document.readyState == "interactive") { clearAD(); From e2818e703a0d3df20a344beb796b19bf4bf3862e Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Jun 2024 18:12:52 +0800 Subject: [PATCH 0194/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 71cee164e68..bb0d1f48a91 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -3,7 +3,7 @@ // @name:zh-CN 百度广告(首尾推广及右侧广告)清理 // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @namespace hoothin -// @version 1.23.4 +// @version 1.23.5 // @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,删除百家号 // @description:zh-CN 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,移除百家号 // @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 @@ -303,8 +303,8 @@ return true; } let match = pattern.match(/^(\*|[\w-]+):\/{2,3}(?:(\*|\*\.[^/*]+|[^/*]+)\/)?(.*)$/); - if (!match) return false; - const [, scheme, host, path] = match + if (!match) return url.indexOf(pattern) !== -1; + const [, scheme, host, path] = match; const urlScheme = url.split(':')[0]; const urlParam = new URL(url); if (scheme === '*' || urlScheme === scheme) { From b25471bba6200dccca06a4cb7386eef8a9751be1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Jun 2024 18:18:58 +0800 Subject: [PATCH 0195/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index bb0d1f48a91..ba7c01d0436 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -254,6 +254,7 @@ } function checkBlack(url, title, pattern) { + pattern = pattern && pattern.replace(/\s*#.*/, ""); if (!pattern || !pattern.trim() || pattern.indexOf("#") === 0 || pattern.indexOf("!") === 0 || pattern.indexOf(" ") === 0 || pattern.indexOf("Update") === 0) return false; if (pattern.indexOf("/") === 0) { let match = pattern.match(/^\/(.*)\/(\w*)$/); From 8b5b9d4441caf21602970a0e73c79e4655636627 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Jun 2024 18:20:28 +0800 Subject: [PATCH 0196/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index ba7c01d0436..dd5fe6060c6 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -3,7 +3,7 @@ // @name:zh-CN 百度广告(首尾推广及右侧广告)清理 // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @namespace hoothin -// @version 1.23.5 +// @version 1.23.6 // @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,删除百家号 // @description:zh-CN 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,移除百家号 // @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 @@ -413,7 +413,7 @@ } }); }); - } else if (blackListInput.value) { + } else { blackList = blackListInput.value.split("\n"); saveBlackList(); } From aa87357b4910267a70bbb2ec12189572114ec83d Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Jun 2024 18:28:14 +0800 Subject: [PATCH 0197/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 4ea18e39686..e6dec797c34 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5841,7 +5841,7 @@ "url": "^https?://www\\.baidu\\.com/(s|baidu)\\b.", "pageBarTop": 75, "replaceElement": "#page", - "exclude": ".AC-style-logo,.killRight", + "exclude": ".AC-style-logo,.killRight,a.new-nextpage-only,a.new-nextpage", "wait": 500 }, { @@ -5856,7 +5856,7 @@ "url": "^https?://www\\.baidu\\.com/(s|baidu)\\b.", "pageBar": 0, "replaceElement": "#page", - "exclude": ".AC-style-logo", + "exclude": ".AC-style-logo,a.new-nextpage-only,a.new-nextpage", "include": ".killRight", "wait": 500 }, From 1e4e402b9c996f5bba33d586c43c6b14eb473b60 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Fri, 28 Jun 2024 10:28:33 +0000 Subject: [PATCH 0198/1065] Update version of Pagetual rules to 37 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 7facc89938b..81b5c5d06cc 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -36 +37 From 012f6d9e2951536cdf0c08b3f4ef30aac6fba6b6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Jun 2024 18:43:49 +0800 Subject: [PATCH 0199/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 32 +++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index dd5fe6060c6..10d3deaefcf 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -3,7 +3,7 @@ // @name:zh-CN 百度广告(首尾推广及右侧广告)清理 // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @namespace hoothin -// @version 1.23.6 +// @version 1.23.7 // @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,删除百家号 // @description:zh-CN 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,移除百家号 // @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 @@ -70,6 +70,29 @@ }); } + function checkMobileItem(item) { + let mu = item.dataset.log; + if (mu) { + try { + mu = JSON.parse(mu).mu; + } catch (e) { + return; + } + } + if (!mu) return; + if (/^https:\/\/baijiahao\.baidu\.com/.test(mu)) { + item.remove(); + return; + } else { + let title = item.querySelector('[data-module="title"]'); + let isBlack = checkBlackList(mu, title && title.innerText); + if (isBlack) { + item.remove(); + return; + } + } + } + function checkLeftItem(item) { let mu = item.getAttribute("mu"); if (mu) { @@ -77,7 +100,7 @@ item.remove(); return; } else { - let title = item.querySelector("h3"); + let title = item.querySelector('h3'); let isBlack = checkBlackList(mu, title && title.innerText); if (isBlack) { item.remove(); @@ -146,6 +169,11 @@ if (baiduapp && baiduapp.querySelector("[ref='open']")) { baiduapp.remove(); } + var list = ele.querySelectorAll(ele.id === "results" ? ".result" : "#results>.result"); + for (let i = 0; i < list.length; i++) { + let item = list[i]; + checkMobileItem(item); + } } function clearAD() { From 218ddf803611b40df8822756a7f6671f9e78e41c Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Jun 2024 18:55:26 +0800 Subject: [PATCH 0200/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 10d3deaefcf..25a8c72b7ac 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -11,6 +11,10 @@ // @match *://www.baidu.com/* // @match *://m.baidu.com/* // @match *://greasyfork.org/*/scripts/24192-* +// @exclude *://m.baidu.com +// @exclude *://m.baidu.com/ +// @exclude *://www.baidu.com +// @exclude *://www.baidu.com/ // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_getValue From d7a0dee2cd8f6e442d43d5a7ef682855b748b3da Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 29 Jun 2024 08:25:33 +0800 Subject: [PATCH 0201/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 0bf529224ee..6c601400d67 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -6987,7 +6987,7 @@ } else { preResult = await new AsyncFunction("response", "doc", '"use strict";' + preCode)(response, doc); } - if (preResult) { + if (typeof preResult !== "undefined") { if (typeof preResult === "string") { doc.documentElement.innerHTML = preResult; } else pageElement = preResult; @@ -8443,7 +8443,7 @@ } else { preResult = await new AsyncFunction("response", "doc", '"use strict";' + preCode)(doc.documentElement.innerHTML, doc); } - if (preResult) { + if (typeof preResult !== "undefined") { if (typeof preResult === "string") { doc.documentElement.innerHTML = preResult; } else eles = preResult; From 3fe226494ce3d31514efc42ce3f1bd544ba23e08 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 29 Jun 2024 09:20:49 +0800 Subject: [PATCH 0202/1065] ImgCodeCheck --- DownloadAllContent/DownloadAllContent.user.js | 77 ++++++++++--------- DownloadAllContent/README.md | 2 + 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index 5b2314a1959..f9a0c8d870a 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -4,7 +4,7 @@ // @name:zh-TW 怠惰小説下載器 // @name:ja 怠惰者小説ダウンロードツール // @namespace hoothin -// @version 2.8.3.6 +// @version 2.8.3.7 // @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,9 @@ if (window.top != window.self) { abort:"跳过此章", save:"保存当前", saveAsMd:"存为 Markdown", - downThreadNum:"设置同时下载的线程数", + downThreadNum:"设置同时下载的线程数,负数为单线程下载间隔", customTitle:"自定义章节标题,输入内页文字对应选择器", + maxDlPerMin:"每分钟最大下载数", reSortDefault:"默认按页面中位置排序章节", reverseOrder:"反转章节排序", saveBtn:"保存设置", @@ -291,8 +292,9 @@ if (window.top != window.self) { abort:"跳過此章", save:"保存當前", saveAsMd:"存爲 Markdown", - downThreadNum:"設置同時下載的綫程數", + downThreadNum:"設置同時下載的綫程數,負數為單線程下載間隔", customTitle:"自訂章節標題,輸入內頁文字對應選擇器", + maxDlPerMin:"每分鐘最大下載數", reSortDefault:"預設依頁面中位置排序章節", reverseOrder:"反轉章節排序", saveBtn:"儲存設定", @@ -353,6 +355,7 @@ if (window.top != window.self) { saveAsMd: "Markdown حفظ كـ", downThreadNum: "تعيين عدد الخيوط للتحميل", customTitle: "تخصيص عنوان الفصل، إدخال المحدد في الصفحة الداخلية", + maxDlPerMin:"الحد الأقصى لعدد التنزيلات في الدقيقة", reSortDefault: "الترتيب الافتراضي حسب الموقع في الصفحة", reverseOrder: "عكس ترتيب الفصول", saveBtn: "حفظ الإعدادات", @@ -395,8 +398,9 @@ if (window.top != window.self) { abort:"Abort", save:"Save", saveAsMd:"Save as Markdown", - downThreadNum:"Set threadNum for download", + downThreadNum:"Set threadNum for download, negative means interval of single thread", customTitle: "Customize the chapter title, enter the selector on inner page", + maxDlPerMin:"Maximum number of downloads per minute", reSortDefault: "Default sort by position in the page", reverseOrder:"Reverse chapter ordering", saveBtn:"Save Setting", @@ -519,14 +523,14 @@ if (window.top != window.self) {
    -
    +
    -
    +

    @@ -534,7 +538,7 @@ if (window.top != window.self) { -
    + `); let dacSortByPos = filterListContainer.querySelector("#dacSortByPos"); let dacSortByUrl = filterListContainer.querySelector("#dacSortByUrl"); @@ -809,7 +813,7 @@ if (window.top != window.self) { document.body.appendChild(shadowContainer); let shadow = shadowContainer.attachShadow({ mode: "open" }); shadow.appendChild(txtDownContent); - txtDownContent.innerHTML=createHTML(` + txtDownContent.innerHTML = createHTML(` \n" }, + { + "name": "Cheap VPS", + "url": "https://my.racknerd.com/aff.php?aff=12390", + "description": "Most cost-effective server, $2 per month" + }, { "name": "Copy target svg to base64", "url": "javascript:(()=>{let svg=window.targetElement&&window.targetElement.querySelector('svg');if(svg){navigator.clipboard.writeText('data:image/svg+xml;base64,'+btoa(unescape(encodeURIComponent(new XMLSerializer().serializeToString(svg)))));alert(\"copy over!\")}})()" From 224c660d18cdfaaeb155f5a96d9d0e7c1fa4b7cd Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 23 Sep 2024 21:42:25 +0800 Subject: [PATCH 0492/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 596acc0b3b9..3c99367846b 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -289,6 +289,11 @@ switch (lang) { "url": "https://my.racknerd.com/aff.php?aff=12390", "description": "性价比最高的服务器,2刀一个月" }, + { + "name": "稳定服务器vultr", + "url": "https://www.vultr.com/?ref=7427668", + "description": "老牌 VPS 服务商,5刀一个月。胜在稳定" + }, { "name": "二维码生成", "url": "https://hoothin.com/qrcode#%U", @@ -669,6 +674,11 @@ switch (lang) { "url": "https://my.racknerd.com/aff.php?aff=12390", "description": "Most cost-effective server, $2 per month" }, + { + "name": "Stable VPS", + "url": "https://www.vultr.com/?ref=7427668", + "description": "Veteran VPS provider, $5 per month, wins in stability" + }, { "name": "Copy target svg to base64", "url": "javascript:(()=>{let svg=window.targetElement&&window.targetElement.querySelector('svg');if(svg){navigator.clipboard.writeText('data:image/svg+xml;base64,'+btoa(unescape(encodeURIComponent(new XMLSerializer().serializeToString(svg)))));alert(\"copy over!\")}})()" From 906826193128bb4a5b1c254547818fec708fca05 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 24 Sep 2024 20:58:37 +0800 Subject: [PATCH 0493/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 53fb70715df..cfd410bdaf7 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -10,6 +10,29 @@ // @name:es Pagetual // @name:fr Pagetual // @name:it Pagetual +// @name:id Pagetual +// @name:ug Pagetual +// @name:ar Pagetual +// @name:he Pagetual +// @name:th Pagetual +// @name:nb Pagetual +// @name:sv Pagetual +// @name:sr Pagetual +// @name:sk Pagetual +// @name:hu Pagetual +// @name:ro Pagetual +// @name:fi Pagetual +// @name:el Pagetual +// @name:eo Pagetual +// @name:bg Pagetual +// @name:cs Pagetual +// @name:vi Pagetual +// @name:pl Pagetual +// @name:uk Pagetual +// @name:tr Pagetual +// @name:nl Pagetual +// @name:da Pagetual +// @name:fr-CA Pagetual // @namespace hoothin // @version 1.9.37.101 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. @@ -23,6 +46,29 @@ // @description:es Carga automática de las siguientes páginas web paginadas e inserción en la página actual. Admite miles de sitios web sin ninguna regla. // @description:fr Chargement automatique des pages Web paginées suivantes et insertion dans la page en cours. Prend en charge des milliers de sites Web sans aucune règle. // @description:it Caricamento automatico delle pagine Web impaginate successive e inserimento nella pagina corrente. Supporta migliaia di siti web senza alcuna regola. +// @description:id Pengambilan otomatis halaman web yang dipaginasi berikutnya dan penyisipan ke halaman saat ini untuk pengguliran tak terbatas. Mendukung ribuan situs web tanpa aturan apa pun. +// @description:ug Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. +// @description:ar Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. +// @description:he Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. +// @description:th ดึงหน้าเว็บแบบแบ่งหน้าถัดไปโดยอัตโนมัติและแทรกลงในหน้าปัจจุบันเพื่อเลื่อนแบบไม่มีที่สิ้นสุด รองรับเว็บไซต์หลายพันแห่งโดยไม่มีกฎเกณฑ์ใดๆ +// @description:nb Henter automatisk neste paginerte nettsider og setter inn på gjeldende side for uendelig rulling. Støtt tusenvis av nettsider uten noen regel. +// @description:sv Hämtar automatiskt nästa paginerade webbsidor och infogar på aktuell sida för oändlig rullning. Stöd tusentals webbplatser utan några regler. +// @description:sr Аутоматско преузимање следећих пагинираних веб страница и уметање у тренутну страницу за бесконачно померање. Подржите хиљаде веб локација без икаквог правила. +// @description:sk Samodejno pridobivanje naslednjih paginiranih spletnih strani in vstavljanje v trenutno stran za neskončno drsenje. Podprite na tisoče spletnih mest brez pravil. +// @description:hu A következő oldalszámozott weboldalak automatikus lekérése és beszúrása az aktuális oldalra a végtelen görgetés érdekében. Több ezer webhely támogatása szabály nélkül. +// @description:ro Preluare automată a următoarelor pagini web paginate și inserare în pagina curentă pentru defilare infinită. Suportă mii de site-uri web fără nicio regulă. +// @description:fi Hakee automaattisesti seuraavat sivutetut verkkosivut ja lisäämällä nykyiselle sivulle loputonta vieritystä. Tukee tuhansia web-sivustoja ilman sääntöjä. +// @description:el Αυτόματη ανάκτηση επόμενων σελιδοποιημένων ιστοσελίδων και εισαγωγή στην τρέχουσα σελίδα για άπειρη κύλιση. Υποστηρίξτε χιλιάδες ιστοσελίδες χωρίς κανένα κανόνα. +// @description:eo Aŭtomate alportado de sekvaj paĝigitaj retpaĝoj kaj enmetado en nunan paĝon por senfina movo. Subtenu milojn da retejoj sen ajna regulo. +// @description:bg Автоматично извличане на следващите уеб страници с пагиниране и вмъкване в текущата страница за безкрайно превъртане. Поддържайте хиляди уеб сайтове без никакви правила. +// @description:cs Automatické načítání dalších stránkovaných webových stránek a vkládání do aktuální stránky pro nekonečné posouvání. Podporujte tisíce webových stránek bez jakýchkoli pravidel. +// @description:vi Tự động tìm các trang web được phân trang tiếp theo và chèn vào trang hiện tại để cuộn vô hạn. Hỗ trợ hàng ngàn trang web mà không cần bất kỳ quy tắc nào. +// @description:pl Automatyczne pobieranie kolejnych stron internetowych z podziałem na strony i wstawianie ich do bieżącej strony w celu nieskończonego przewijania. Obsługa tysięcy stron internetowych bez żadnej reguły. +// @description:uk Автоматичне отримання наступних веб-сторінок із розбивкою на сторінки та вставка на поточну сторінку для нескінченного прокручування. Підтримка тисяч веб-сайтів без будь-яких правил. +// @description:tr Sonraki sayfalı web sayfalarını otomatik olarak getirme ve sonsuz kaydırma için geçerli sayfaya ekleme. Hiçbir kural olmadan binlerce web sitesini destekleyin. +// @description:nl Automatisch ophalen van volgende gepagineerde webpagina's en invoegen in huidige pagina voor oneindig scrollen. Ondersteun duizenden websites zonder enige regel. +// @description:da Automatisk hentning af næste paginerede websider og indsættelse på nuværende side for uendelig rulning. Støt tusindvis af websteder uden nogen regler. +// @description:fr-CA Récupération automatique des pages Web paginées suivantes et insertion dans la page actuelle pour un défilement infini. Prise en charge de milliers de sites Web sans aucune règle. // @author hoothin // @license MPL-2.0 // @match *://*/* @@ -52,6 +98,7 @@ // @connect wedata.net // @connect githubusercontent.com // @connect ghproxy.com +// @connect ghp.ci // @connect hoothin.github.io // @run-at document-end // @connect * From 0c336f5600bfa02b1a5bdee272a1e205f110da4b Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 25 Sep 2024 08:57:24 +0800 Subject: [PATCH 0494/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 7df1828bb36..27e1a5c296e 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -6251,6 +6251,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, From 4409f66aab46087e8d4f94064c773748d95a3145 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Wed, 25 Sep 2024 00:57:45 +0000 Subject: [PATCH 0495/1065] Update version of Pagetual rules to 69 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 38b10c1b2ba..b5489e5e51a 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -68 +69 From 6ed035ca251bc8942fdcc19e65af343b41a5c6c4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 25 Sep 2024 12:33:22 +0800 Subject: [PATCH 0496/1065] 1.9.37.102 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 5bc30b1f863..18d57f2d64a 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.101](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.102](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index cfd410bdaf7..09c4c4e3607 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -34,7 +34,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.101 +// @version 1.9.37.102 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -2557,7 +2557,7 @@ let articleNum = 0; for (i = 0; i < ele.children.length; i++) { let curNode = ele.children[i]; - if (ele !== body && /^H\d$/i.test(curNode.nodeName) && curNode.offsetParent) { + if (ele !== body && /^H\d$/i.test(curNode.nodeName) && curNode.offsetParent && curNode.offsetHeight) { curMaxEle = null; break; } From d5608f51fd303fd780cf1f41475b57f171f22e71 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 26 Sep 2024 08:05:54 +0800 Subject: [PATCH 0497/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 27e1a5c296e..088866f9b82 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5817,7 +5817,7 @@ "a.prev" ], "pageNum": "\\-\\d+\\-{$p}\\.html", - "pageElement": "div#threadlist form", + "pageElement": "div#threadlist>div>form", "replaceElement": "#pgt div.pg" }, { From 800fbe0db891381cc84ef09b2580f25e179e93b5 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 26 Sep 2024 00:06:16 +0000 Subject: [PATCH 0498/1065] Update version of Pagetual rules to 70 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index b5489e5e51a..2bbd69c2e54 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -69 +70 From be0c1382240c5c2b913d338d6409bb47cba10d2a Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 26 Sep 2024 21:22:44 +0800 Subject: [PATCH 0499/1065] 1.9.37.103 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 23 ++++++++++++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 18d57f2d64a..1af4136127a 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.102](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.103](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 09c4c4e3607..a05111af4ed 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -11,9 +11,6 @@ // @name:fr Pagetual // @name:it Pagetual // @name:id Pagetual -// @name:ug Pagetual -// @name:ar Pagetual -// @name:he Pagetual // @name:th Pagetual // @name:nb Pagetual // @name:sv Pagetual @@ -34,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.102 +// @version 1.9.37.103 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -47,9 +44,6 @@ // @description:fr Chargement automatique des pages Web paginées suivantes et insertion dans la page en cours. Prend en charge des milliers de sites Web sans aucune règle. // @description:it Caricamento automatico delle pagine Web impaginate successive e inserimento nella pagina corrente. Supporta migliaia di siti web senza alcuna regola. // @description:id Pengambilan otomatis halaman web yang dipaginasi berikutnya dan penyisipan ke halaman saat ini untuk pengguliran tak terbatas. Mendukung ribuan situs web tanpa aturan apa pun. -// @description:ug Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. -// @description:ar Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. -// @description:he Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:th ดึงหน้าเว็บแบบแบ่งหน้าถัดไปโดยอัตโนมัติและแทรกลงในหน้าปัจจุบันเพื่อเลื่อนแบบไม่มีที่สิ้นสุด รองรับเว็บไซต์หลายพันแห่งโดยไม่มีกฎเกณฑ์ใดๆ // @description:nb Henter automatisk neste paginerte nettsider og setter inn på gjeldende side for uendelig rulling. Støtt tusenvis av nettsider uten noen regel. // @description:sv Hämtar automatiskt nästa paginerade webbsidor och infogar på aktuell sida för oändlig rullning. Stöd tusentals webbplatser utan några regler. @@ -2410,6 +2404,7 @@ if (doc === document && this.docElementValid()) { return this.docPageElement; } + if (!curWin) curWin = doc.defaultView; let pageElement = null; let self = this; let body = getBody(doc); @@ -2452,8 +2447,8 @@ pageElement = null; } else if (curWin && curWin !== _unsafeWindow) { let parent = pageElement[0].parentNode; - let loading = parent.querySelector('[class*=loading]'); - if (loading && loading.offsetParent && loading.offsetHeight > parent.offsetHeight>>2) { + let loading = parent.querySelector('[class*=loading],[class*=Loader]'); + if (loading && loading.offsetParent && loading.offsetHeight > (parent.childElementCount === 1 ? parent.firstElementChild.offsetHeight : parent.offsetHeight)>>2) { pageElement = null; } else { loading = parent.querySelector('[class*=skeleton-item]'); @@ -2562,8 +2557,12 @@ break; } if (compareNodeName(curNode, ["canvas", "nav"])) continue; + if (curNode.getAttribute("aria-hidden") == "true") continue; let curStyle = curWin.getComputedStyle(curNode); - if (!curNode.offsetParent && curStyle.display !== "contents" && (curStyle.position !== "fixed" || curStyle.opacity === 0)) { + if (curStyle.opacity === "0") { + continue; + } + if (!curNode.offsetParent && curStyle.display !== "contents" && curStyle.position !== "fixed") { continue; } if (!compareNodeName(curNode, ["img"]) && curNode.querySelector('img') === null && /^\s*$/.test(curNode.innerText)) continue; @@ -3919,7 +3918,9 @@ } this.insert = getElement(insertSel, document, null, true); } else { - this.docPageElement = null; + if (this.docPageElement && this.docPageElement.length && !document.documentElement.contains(this.docPageElement[0])) { + this.docPageElement = null; + } let pageElement = this.getPageElement(document, _unsafeWindow); if (this.curSiteRule.smart && this.nextLinkHref == "#" && this.curSiteRule.pageElement === 'body') { debug("Stop as jsNext & whole body"); From 8368d0e2c5ca52429b3c1aa0e10cfbc77bb931a9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 27 Sep 2024 09:55:44 +0800 Subject: [PATCH 0500/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index a05111af4ed..c62f12ef8d1 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -7287,16 +7287,10 @@ if (rulesData.lang) { setLang(rulesData.lang); } - if (rulesData.firstRun) { + if (rulesData.firstRun && storage.supportCrossSave()) { rulesData.firstRun = false; storage.setItem("rulesData", rulesData); - setTimeout(() => { - storage.getItem("rulesData", data => { - if (data.firstRun === false) { - _GM_openInTab(firstRunPage, {active: true}); - } - }); - }, 100); + _GM_openInTab(firstRunPage, {active: true}); } _GM_registerMenuCommand(i18n("configure"), () => { _GM_openInTab(rulesData.configPage || configPage[0], {active: true}); From 28d23af2e952744b18a72e71aa4e5837e3c5c8ad Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 28 Sep 2024 09:08:38 +0800 Subject: [PATCH 0501/1065] 1.9.37.104 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 1af4136127a..44b27ecc18d 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.103](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.104](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index c62f12ef8d1..cc8b209780e 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.103 +// @version 1.9.37.104 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -2557,7 +2557,7 @@ break; } if (compareNodeName(curNode, ["canvas", "nav"])) continue; - if (curNode.getAttribute("aria-hidden") == "true") continue; + if (curNode.role === "menu") continue; let curStyle = curWin.getComputedStyle(curNode); if (curStyle.opacity === "0") { continue; From 972adce425c97b35f64b0df7b9694ad01fb108ff Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 28 Sep 2024 09:37:06 +0800 Subject: [PATCH 0502/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index cc8b209780e..17c105fa797 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2987,6 +2987,7 @@ "[aria-label$='next page']", ".pagination-nav__item--next>a", "a.pageright", + ".pager_on+a.pager", ".pager__next>a", ".page-numbers.current+a", "a.page-numbers.next", From 114c1e394c26a87605edbe6bb6d3eb4cea243914 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 28 Sep 2024 09:56:19 +0800 Subject: [PATCH 0503/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 17c105fa797..35f11d810fb 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2473,9 +2473,12 @@ if (pageElement && pageElement.length === 1 && pageElement[0].style.display === 'none') { pageElement = [body]; } - if (this.curSiteRule.smart && pageElement && pageElement.length > 0 && compareNodeName(pageElement[0], ["tr"])) { - let mainTr = this.insert.parentNode.querySelectorAll('tr'), mainTdNum = 0, newTdNum = 0; - mainTr = mainTr[mainTr.length - 1]; + if (this.insert && this.curSiteRule.smart && pageElement && pageElement.length > 0 && compareNodeName(pageElement[0], ["tr"])) { + let mainTr = this.insert.parentNode.lastElementChild, mainTdNum = 0, newTdNum = 0; + while (mainTr && !compareNodeName(mainTr, ["tr"])) { + if (!mainTr.previousElementSibling) break; + mainTr = mainTr.previousElementSibling; + } [].forEach.call(mainTr.children, el => { if (compareNodeName(el, ["td", "th"])) { mainTdNum += el.colSpan || 1; @@ -3907,6 +3910,7 @@ getInsert(refresh) { if (refresh) { + this.docPageElement = null; this.insert = null; } if (this.insert && this.insert.parentNode && document.documentElement.contains(this.insert)) { From 2f8fd73eab8c586b53d6a8ed63721da2ffdef119 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 28 Sep 2024 12:08:25 +0800 Subject: [PATCH 0504/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 3c99367846b..04a58cf4928 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -400,7 +400,7 @@ switch (lang) { }, { "name": "Futurepedia - Find The Best AI Tools & Software", - "url": "https://www.futurepedia.io/#p{input[name\\=q]=%s&click(button[type\\=submit]:not([disabled]))}" + "url": "https://www.futurepedia.io/search?search=%s" } ] }, @@ -779,7 +779,7 @@ switch (lang) { }, { "name": "Futurepedia - Find The Best AI Tools & Software", - "url": "https://www.futurepedia.io/#p{input[name\\=q]=%s&click(button[type\\=submit]:not([disabled]))}" + "url": "https://www.futurepedia.io/search?search=%s" } ] }, From b6ec788efb14ec2d4d071f7d55fcfe382927fdfc Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 28 Sep 2024 16:27:35 +0800 Subject: [PATCH 0505/1065] Update readme.md --- .../lib/readme.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md index 1f9ed4f33d0..0384226f00b 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md +++ b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md @@ -26,13 +26,15 @@ import Stcasc from 'switch-chinese'; + 轉正體中文 ``` js -stcasc.traditionalized("中文"); +stcasc.traditionalized("简体中文"); +//簡體中文 ``` + 轉簡體中文 ``` js -stcasc.simplized("中文"); +stcasc.simplized("正體中文"); +//正体中文 ``` + 添加快取 From 22e7a2e3bf717bb4d0d1ff24918913823ce7a879 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 29 Sep 2024 12:41:21 +0800 Subject: [PATCH 0506/1065] 1.9.37.105 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 44b27ecc18d..4e4eda28d74 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.104](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.105](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 35f11d810fb..47437a9671f 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.104 +// @version 1.9.37.105 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -4116,7 +4116,7 @@ } checkClickHref() { - if (this.curSiteRule.smart && this.nextLinkEle && !this.linkHasHref(this.nextLinkEle)) { + if (this.curSiteRule.smart && this.nextLinkEle && (!this.linkHasHref(this.nextLinkEle) || this.nextLinkEle.target !== "_blank")) { this.urlChanged(); isPause = true; if (!this.nextLinkHref) isLoading = false; @@ -8146,7 +8146,7 @@ clearTimeout(checkUrlTimer); checkUrlTimer = setTimeout(checkFunc, checkUrlTime); } - }); + }, true); } let scrollContainer; From 3662ff4273d281db18875df1514ca8ed74d30534 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 30 Sep 2024 18:34:09 +0800 Subject: [PATCH 0507/1065] 1.9.37.106 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 4e4eda28d74..b12f1eeaa67 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.105](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.106](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 47437a9671f..10a909d3e65 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.105 +// @version 1.9.37.106 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -4116,7 +4116,7 @@ } checkClickHref() { - if (this.curSiteRule.smart && this.nextLinkEle && (!this.linkHasHref(this.nextLinkEle) || this.nextLinkEle.target !== "_blank")) { + if (this.curSiteRule.smart && this.nextLinkEle && !this.linkHasHref(this.nextLinkEle)) { this.urlChanged(); isPause = true; if (!this.nextLinkHref) isLoading = false; @@ -8126,7 +8126,7 @@ } else if (!ruleParser.canListenUrlChange()) { return; } - if ((prevPathname !== window.location.pathname || prevSearch !== window.location.search) && window.location.href != ruleParser.historyUrl) { + if ((prevPathname !== window.location.pathname || prevSearch !== window.location.search || window.location.hash.indexOf("#!") === 0) && window.location.href != ruleParser.historyUrl) { checkUrlTime = 2000; urlWillChange = true; var e = new Event('pagetual_pushState'); From 00c22f7202486e7f435651b210172bfd4270da6f Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 4 Oct 2024 17:22:46 +0800 Subject: [PATCH 0508/1065] 1.9.37.107 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index b12f1eeaa67..a387173e02c 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.106](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.107](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 10a909d3e65..074a734a587 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.106 +// @version 1.9.37.107 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -2555,7 +2555,7 @@ let articleNum = 0; for (i = 0; i < ele.children.length; i++) { let curNode = ele.children[i]; - if (ele !== body && /^H\d$/i.test(curNode.nodeName) && curNode.offsetParent && curNode.offsetHeight) { + if (ele !== body && ele.parentNode !== body && /^H\d$/i.test(curNode.nodeName) && curNode.offsetParent && curNode.offsetHeight) { curMaxEle = null; break; } @@ -7295,7 +7295,13 @@ if (rulesData.firstRun && storage.supportCrossSave()) { rulesData.firstRun = false; storage.setItem("rulesData", rulesData); - _GM_openInTab(firstRunPage, {active: true}); + setTimeout(() => { + storage.getItem("rulesData", data => { + if (data.firstRun === false) { + _GM_openInTab(firstRunPage, {active: true}); + } + }); + }, 100); } _GM_registerMenuCommand(i18n("configure"), () => { _GM_openInTab(rulesData.configPage || configPage[0], {active: true}); From bf59b6ea773a7de456c1115866ebd158b5c671d2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 6 Oct 2024 10:53:24 +0800 Subject: [PATCH 0509/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 088866f9b82..d83950c082f 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -40,7 +40,8 @@ "author": "1nker", "url": "^https?://pubmed\\.ncbi\\.nlm\\.nih\\.gov/", "example": "https://pubmed.ncbi.nlm.nih.gov/?term=", - "loadMore": "button.load-button.next-page" + "loadMore": "button.load-button.next-page", + "nextLink": 0 }, { "name": "V2EX POST", From 298786dcb0d182dd4b6e5fc407b0678a331f7805 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 6 Oct 2024 02:53:40 +0000 Subject: [PATCH 0510/1065] Update version of Pagetual rules to 71 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 2bbd69c2e54..39f5b69311d 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -70 +71 From db02907d46a7648196036e25dad2a834d197df52 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 6 Oct 2024 13:18:30 +0800 Subject: [PATCH 0511/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 074a734a587..a8a7831c62a 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3271,6 +3271,7 @@ } if (next && next.classList && (next.classList.contains("results-more") || next.classList.contains("no"))) next = null; if (next && next.hasAttribute && next.hasAttribute("disabled")) next = null; + if (next && next.offsetHeight && next.offsetHeight > 200) next = null; if (next && next.parentNode.href && compareNodeName(next.parentNode, ["a"])) next = next.parentNode; return {next:next, canSave:canSave}; } From 3d81ed86da3e67ba13b1686674cfcdc64eb26b41 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 6 Oct 2024 17:39:46 +0800 Subject: [PATCH 0512/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index a8a7831c62a..7b9d7e85157 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -9784,6 +9784,9 @@ iframeDoc.addEventListener('wheel', e => { document.dispatchEvent(new Event('wheel')); }, true); + window.addEventListener("scroll", e => { + curIframe.contentWindow.dispatchEvent(new Event('scroll')); + }); }); let checkTimes = 0, findPageEle = false; let forceRefresh = e => { From a80937e650bb8f57bb8cdf758370ffb3218b80b2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 7 Oct 2024 12:24:45 +0800 Subject: [PATCH 0513/1065] 1.9.37.108 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 90 +++++++++++++++++++++++++++++++++------ 2 files changed, 77 insertions(+), 15 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index a387173e02c..178f882ffc9 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.107](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.108](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 7b9d7e85157..c5fe14abaa0 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.107 +// @version 1.9.37.108 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -4117,13 +4117,17 @@ } checkClickHref() { - if (this.curSiteRule.smart && this.nextLinkEle && !this.linkHasHref(this.nextLinkEle)) { + if (this.nextLinkHref === '#') { this.urlChanged(); isPause = true; if (!this.nextLinkHref) isLoading = false; } } + needCheckClick(ele) { + return !picker.contains(ele) && this.nextLinkHref === '#'; + } + docElementValid() { if (!this.docPageElement || this.docPageElement.length == 0) return false; if (!this.checkPageEle) { @@ -5138,6 +5142,7 @@ } #pagetual-picker { position: fixed; + max-width: 80vw; top: 10px; left: calc(50% - 178px); background: aliceblue; @@ -5639,11 +5644,11 @@ let initX = 0, initY = 0, initPos = {x: 0, y: 0}; let moveHanlder = e => { if (moving) { - frame.style.left = e.clientX - initX + "px"; - frame.style.top = e.clientY - initY + "px"; + frame.style.left = clientX(e) - initX + "px"; + frame.style.top = clientY(e) - initY + "px"; e.stopPropagation(); e.preventDefault(); - } else if(Math.abs(e.clientX - initPos.x) + Math.abs(e.clientY - initPos.y) > 20) { + } else if(Math.abs(clientX(e) - initPos.x) + Math.abs(clientY(e) - initPos.y) > 20) { moving = true; } }; @@ -5659,12 +5664,25 @@ e.preventDefault(); }; title.addEventListener("mousedown", e => { + e.preventDefault(); + e.stopPropagation(); initPos = {x: e.clientX, y: e.clientY}; initX = e.clientX - parseInt(getComputedStyle(frame).left); initY = e.clientY - parseInt(getComputedStyle(frame).top); document.addEventListener("mousemove", moveHanlder, true); title.addEventListener("mouseup", upHanlder, true); - }); + }, { passive: false, capture: false }); + + title.addEventListener('touchstart', e => { + e.preventDefault(); + e.stopPropagation(); + initPos = {x: clientX(e), y: clientY(e)}; + initX = initPos.x - parseInt(getComputedStyle(frame).left); + initY = initPos.y - parseInt(getComputedStyle(frame).top); + document.addEventListener("touchmove", moveHanlder, true); + title.addEventListener('touchend', upHanlder, false); + }, { passive: false, capture: false }); + frame.addEventListener("mouseenter", e => { if (!self.showSign || moving) return; if (self.mainSignDiv.parentNode) self.mainSignDiv.parentNode.removeChild(self.mainSignDiv); @@ -5746,6 +5764,10 @@ }; } + contains(ele) { + return this.frame && this.frame.contains(ele); + } + getTempRule(detail, noFill) { if (this.tempRule.value) { try { @@ -8112,11 +8134,8 @@ if (checkClickedEle) { if (typeof ruleParser.curSiteRule.refreshByClick !== "undefined") { } else if (!clickedSth && checkClickedEle && checkClickedEle.nodeName) { - if (compareNodeName(checkClickedEle, ["a", "button"])) { + if (compareNodeName(checkClickedEle, ["a", "button"]) && ruleParser.needCheckClick(checkClickedEle)) { clickedSth = true; - } else { - let targetStyle = _unsafeWindow.getComputedStyle(checkClickedEle); - if (targetStyle.cursor == "pointer") clickedSth = true; } } checkClickedEle = null; @@ -8147,7 +8166,7 @@ checkUrlTimer = setTimeout(checkFunc, checkUrlTime); document.addEventListener("click", e => { - if (!checkClickedEle) { + if (e.isTrusted && !checkClickedEle) { checkClickedEle = e.target; checkUrlTime = 300; clearTimeout(checkUrlTimer); @@ -8875,6 +8894,26 @@ }); } + async function waitForElements(sel, doc, maxTime) { + if (!sel) return null; + return new Promise((resolve) => { + let passedTime = 0; + let checkInv = setInterval(() => { + let result = getAllElements(sel, doc, null, true); + if (result && result.length) { + clearInterval(checkInv); + resolve(result); + } else if (maxTime) { + passedTime += 100; + if (passedTime >= maxTime) { + clearInterval(checkInv); + resolve(result); + } + } + }, 100); + }); + } + async function clickAction(sel, doc) { let btn = await waitForElement(sel, doc); emuClick(btn, doc); @@ -9050,6 +9089,22 @@ return result; } + function clientX(e) { + if (e.type.indexOf('touch') === 0) { + return e.changedTouches ? e.changedTouches[0].clientX : 0; + } else { + return e.clientX; + } + } + + function clientY(e) { + if (e.type.indexOf('touch') === 0) { + return e.changedTouches ? e.changedTouches[0].clientY : 0; + } else { + return e.clientY; + } + } + var failFromIframe = 0; var inCors = false; var checkRemoveIntv; @@ -9501,10 +9556,12 @@ } else { let refreshByClickSel = ruleParser.curSiteRule.refreshByClick; if (iframeDoc && refreshByClickSel) { - let clickBtn = await waitForElement(refreshByClickSel, iframeDoc); + let clickBtn = await waitForElements(refreshByClickSel, iframeDoc); await sleep(500); await cloneStatus(); - emuClick(clickBtn, iframeDoc); + if (clickBtn.length === 1) { + emuClick(clickBtn[0], iframeDoc); + } await sleep(500); } else { await cloneStatus(); @@ -9923,7 +9980,12 @@ }*/ let isJs = ruleParser.curSiteRule.action == 3 || ruleParser.hrefIsJs(nextLink); if (!isJs) { - emuIframe = null; + if (emuIframe) { + if (emuIframe.parentNode) { + emuIframe.parentNode.removeChild(emuIframe); + } + emuIframe = null; + } lastActiveUrl = nextLink; if (location.protocol === "https:" && /^http:/.test(nextLink)) { nextLink = nextLink.replace(/^http/, "https"); From b46b2dfed4aef98cd723d83648b31f636cac8b14 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 7 Oct 2024 12:32:34 +0800 Subject: [PATCH 0514/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index c5fe14abaa0..6c31161620c 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -4125,7 +4125,7 @@ } needCheckClick(ele) { - return !picker.contains(ele) && this.nextLinkHref === '#'; + return this.nextLinkHref === '#' && !picker.contains(ele) && ele.parentNode && ele.parentNode.className !== 'pagetual_pageBar'; } docElementValid() { @@ -8134,7 +8134,7 @@ if (checkClickedEle) { if (typeof ruleParser.curSiteRule.refreshByClick !== "undefined") { } else if (!clickedSth && checkClickedEle && checkClickedEle.nodeName) { - if (compareNodeName(checkClickedEle, ["a", "button"]) && ruleParser.needCheckClick(checkClickedEle)) { + if (compareNodeName(checkClickedEle, ["a", "button"]) && checkClickedEle.target !== "_blank" && ruleParser.needCheckClick(checkClickedEle)) { clickedSth = true; } } @@ -8743,14 +8743,14 @@ } nextEle.src = nextEle.src; } - }); + }, true); } else if (rulesData.pageBarMenu) { pageText.addEventListener("click", e => { e.stopPropagation(); if (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) return; e.preventDefault(); picker.start(); - }); + }, true); } pageBar.appendChild(downSpan); if (forceState == 2) { From b9378d736a8f4c1923dcda859273d9eccf992097 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 7 Oct 2024 12:38:01 +0800 Subject: [PATCH 0515/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 6c31161620c..b1c10a9e832 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -227,7 +227,7 @@ pageElementCss: "Custom style for main page elements", customCss: "Custom complete css", firstAlert: "You have not imported the base rule, please select the appropriate rule to import", - picker: "Pagetual page element picker", + picker: "Pagetual element picker", closePicker: "Close Pagetual picker", pickerPlaceholder: "Element selector, (Advanced users only, leave blank otherwise)", pickerCheck: "Check selector and copy", @@ -5167,6 +5167,7 @@ min-height: unset; } #pagetual-picker>.title { + max-width: 100%; margin: -5px 45px 10px 45px; font-size: 20px; font-weight: bold; @@ -8649,6 +8650,8 @@ setTimeout(() => { pageText.style.pointerEvents = 'all'; }, 250); + e.preventDefault(); + e.stopPropagation(); getBody(document).addEventListener("touchstart", touchBodyHandler, { passive: false, capture: false }); }, { passive: false, capture: false }); if (ruleParser.nextTitle) { From 6c1897f86eabe6e1b983c374d06c11c815697c47 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 7 Oct 2024 12:41:47 +0800 Subject: [PATCH 0516/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index b1c10a9e832..9c9a5470fbe 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -8650,8 +8650,6 @@ setTimeout(() => { pageText.style.pointerEvents = 'all'; }, 250); - e.preventDefault(); - e.stopPropagation(); getBody(document).addEventListener("touchstart", touchBodyHandler, { passive: false, capture: false }); }, { passive: false, capture: false }); if (ruleParser.nextTitle) { From 1f679049be9a7562ca645de0078b53586963e6de Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 7 Oct 2024 15:20:46 +0800 Subject: [PATCH 0517/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 9c9a5470fbe..5e53924b91e 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -8643,15 +8643,6 @@ touched = false; getBody(document).removeEventListener('touchstart', touchBodyHandler, { passive: false, capture: false }); }; - pageText.addEventListener("touchstart", e => { - if (touched) return; - touched = true; - pageText.style.pointerEvents = 'none'; - setTimeout(() => { - pageText.style.pointerEvents = 'all'; - }, 250); - getBody(document).addEventListener("touchstart", touchBodyHandler, { passive: false, capture: false }); - }, { passive: false, capture: false }); if (ruleParser.nextTitle) { pageText.innerHTML = createHTML(ruleParser.nextTitle + " "); pageText.title = ruleParser.nextTitle; @@ -8752,6 +8743,16 @@ e.preventDefault(); picker.start(); }, true); + } else { + pageText.addEventListener("touchstart", e => { + if (touched) return; + touched = true; + pageText.style.pointerEvents = 'none'; + setTimeout(() => { + pageText.style.pointerEvents = 'all'; + }, 250); + getBody(document).addEventListener("touchstart", touchBodyHandler, { passive: false, capture: false }); + }, { passive: false, capture: false }); } pageBar.appendChild(downSpan); if (forceState == 2) { From 468a8f74953b5efeb8aed26838e66c588ee10a90 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 10 Oct 2024 08:11:04 +0800 Subject: [PATCH 0518/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 5e53924b91e..2d708873975 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3026,6 +3026,7 @@ "body [class*=Pages]>.curr+a", "body [class*=page]>.cur+a", "body [class*=pagination] [class*=next]", + "body [class*=pagination] [class*=arrow-right]", ".page>em+a", "[name*=nextPage]", '//button[contains(@class, "Page")][text()="Next"]', From 3fd3b144ddf6ee8319720cc01c276f4d9a843c0a Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 10 Oct 2024 12:05:15 +0800 Subject: [PATCH 0519/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 2d708873975..60fe280cba7 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3026,7 +3026,7 @@ "body [class*=Pages]>.curr+a", "body [class*=page]>.cur+a", "body [class*=pagination] [class*=next]", - "body [class*=pagination] [class*=arrow-right]", + "body [class*=pagination] [class*=right]", ".page>em+a", "[name*=nextPage]", '//button[contains(@class, "Page")][text()="Next"]', From b549b6215b0392cf161aa634d95a7896cf0050da Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 10 Oct 2024 16:22:00 +0800 Subject: [PATCH 0520/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index d83950c082f..79987c793e9 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -7110,7 +7110,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 From fafdb744182cc534ab284272c487d73224743dd3 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 10 Oct 2024 08:22:18 +0000 Subject: [PATCH 0521/1065] Update version of Pagetual rules to 72 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 39f5b69311d..ea70ce01343 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -71 +72 From 313d655581e5a22131797667c0e23bb0984d0eb3 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Oct 2024 10:48:39 +0800 Subject: [PATCH 0522/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index b2d6d1bf537..899c6093175 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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.9.22.1 +// @version 2024.10.11.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -12493,7 +12493,7 @@ ImgOps | https://imgops.com/#b#`; }); } - return oldsrc != newsrc ? newsrc : null; + return oldsrc != canonicalUri(newsrc) ? newsrc : null; } ]; @@ -22781,6 +22781,7 @@ ImgOps | https://imgops.com/#b#`; } }, true); + var lastPopupLoading; // 载入动画 function LoadingAnimC(data, buttonType, waitImgLoad, openInTopWindow, initPos) { if (LoadingAnimC.all.find(function(item, index, array) { @@ -22788,6 +22789,12 @@ ImgOps | https://imgops.com/#b#`; return true; } })) return false; + if (buttonType === "popup") { + if (lastPopupLoading) { + lastPopupLoading.cancel(); + } + lastPopupLoading = this; + } this.args = arrayFn.slice.call(arguments, 0); if (data.src != data.imgSrc && !data.srcs) { data.srcs = [data.imgSrc]; @@ -22833,8 +22840,7 @@ ImgOps | https://imgops.com/#b#`; container.addEventListener('click',function(e){ var tcl=e.target.classList; if(tcl.contains('pv-loading-cancle')){ - self.imgReady && self.imgReady.abort(); - self.remove(); + self.cancel(); }else if(tcl.contains('pv-loading-retry')){ self.remove(); new LoadingAnimC(self.args[0],self.args[1],self.args[2],self.args[3]); @@ -22969,6 +22975,10 @@ ImgOps | https://imgops.com/#b#`; LoadingAnimC.all.splice(LoadingAnimC.all.indexOf(this),1); }; }, + cancel:function(){ + this.imgReady && this.imgReady.abort(); + this.remove(); + }, error:function(msg,img,e){ if(msg)debug(msg); this.loadingAnim.style.pointerEvents=""; From 57c65e0b9e2e006eca50d58281c52d2d3c3df54c Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Oct 2024 11:45:02 +0800 Subject: [PATCH 0523/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 899c6093175..5571c319822 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -24934,7 +24934,7 @@ ImgOps | https://imgops.com/#b#`; } if (!found && document.elementsFromPoint) { let elements = document.elementsFromPoint(clientX, clientY); - let checkLen = Math.min(elements.length, 5); + let checkLen = Math.min(elements.length, 10); for (let i = 0; i < checkLen; i++) { let ele = elements[i]; if (!ele) continue; From a0cc805fab5bdcb210efd9347caf8afd425e06c6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Oct 2024 16:20:11 +0800 Subject: [PATCH 0524/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 04a58cf4928..94f2887bd93 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -294,6 +294,11 @@ switch (lang) { "url": "https://www.vultr.com/?ref=7427668", "description": "老牌 VPS 服务商,5刀一个月。胜在稳定" }, + { + "name": "便宜域名", + "url": "https://www.namesilo.com/domain/search-domains?rid=44fb284bf", + "description": "比阿里云便宜,可以用支付宝支付" + }, { "name": "二维码生成", "url": "https://hoothin.com/qrcode#%U", @@ -679,6 +684,11 @@ switch (lang) { "url": "https://www.vultr.com/?ref=7427668", "description": "Veteran VPS provider, $5 per month, wins in stability" }, + { + "name": "Cheap Domain", + "url": "https://www.namesilo.com/domain/search-domains?rid=44fb284bf", + "description": "Buy Website Domain Name" + }, { "name": "Copy target svg to base64", "url": "javascript:(()=>{let svg=window.targetElement&&window.targetElement.querySelector('svg');if(svg){navigator.clipboard.writeText('data:image/svg+xml;base64,'+btoa(unescape(encodeURIComponent(new XMLSerializer().serializeToString(svg)))));alert(\"copy over!\")}})()" From 1854fbdc2f16bd738159c10893cb10d54d3c938d Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Oct 2024 19:06:21 +0800 Subject: [PATCH 0525/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 5571c319822..28031437a35 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -24631,7 +24631,7 @@ ImgOps | https://imgops.com/#b#`; if (isConfigOpen) return false; let selStr; try { - selStr = !selectionClientRect && document.getSelection().toString(); + selStr = !selectionClientRect && selectionStr; }catch(e){} if (selStr) return false; let keyActive=(prefs.floatBar.globalkeys.type == "hold" && checkGlobalKeydown(e)) || @@ -25206,10 +25206,10 @@ ImgOps | https://imgops.com/#b#`; } else { if (!canPreview) return; let target = e.target; - if (target.nodeName.toUpperCase() == "PICTURE"){ + if (target.nodeName == "PICTURE"){ target = target.querySelector("img") || target; } - if (target.nodeName.toUpperCase() != 'IMG') return; + if (target.nodeName != 'IMG') return; } } if (!initMouse) return; From cb425f79b7cbb999ccdf6845883accd1131af7c4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Oct 2024 19:14:17 +0800 Subject: [PATCH 0526/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 28031437a35..faae4adb673 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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.10.11.1 +// @version 2024.10.11.2 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -25172,7 +25172,7 @@ ImgOps | https://imgops.com/#b#`; canclePreCTO = clickToOpen(result); } - let hide = sizeHide || (prefs.floatBar.position == "hide" ? !altKey : altKey); + let hide = sizeHide || (prefs.floatBar.position == "hide" ? true : altKey); result.hide = hide; let canShow = floatBar.start(result); if (!checkUniqueImgWin() && canShow) { From 45036100e30bd2798fcf7c9a0de9c66a889eaf0d Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Oct 2024 20:28:48 +0800 Subject: [PATCH 0527/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index faae4adb673..b055deb3596 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -20856,7 +20856,7 @@ ImgOps | https://imgops.com/#b#`; -webkit-transition: opacity 0.2s ease-out;\ transition: opacity 0.1s ease-out;\ overscroll-behavior: none;\ - box-shadow: 0 0 10px 5px rgba(0,0,0,0.35);\ + box-shadow: 0 0 6px 2px rgba(0,0,0,0.35);\ box-sizing: content-box;\ display: initial;\ background: #00000080;\ @@ -21048,6 +21048,7 @@ ImgOps | https://imgops.com/#b#`; position: absolute;\ border: 10px solid transparent;\ margin-left: -22px;\ + top: -1px;\ border-right-color: yellow;\ }\ span.pv-pic-window-pre,\ @@ -21110,7 +21111,7 @@ ImgOps | https://imgops.com/#b#`; display: block;\ }\ span.pv-pic-search-state {\ - top: -21px;\ + top: -18px;\ left: 0px;\ display: block;\ position: absolute;\ @@ -21128,7 +21129,6 @@ ImgOps | https://imgops.com/#b#`; max-width: 100%;\ overflow: hidden;\ font: 13px / 1.4em "Trebuchet MS", sans-serif;\ - box-shadow: rgb(221, 221, 221) 0px 0px 1px inset;\ }\ .pv-pic-search-state>span {\ pointer-events: none;\ @@ -25107,7 +25107,7 @@ ImgOps | https://imgops.com/#b#`; imgSrc: src, noActual:true, img: target, - description: target.title + description: target.title || target.innerText }; checkUniqueImgWin(); } @@ -25198,7 +25198,7 @@ ImgOps | https://imgops.com/#b#`; if (canPreview) { uniqueImgWinInitX = e.clientX; uniqueImgWinInitY = e.clientY; - uniqueImgWin.followPos(uniqueImgWinInitX, uniqueImgWinInitY); + uniqueImgWin.followPos(uniqueImgWinInitX, uniqueImgWinInitY, true); } else { uniqueImgWin.remove(); } From 5470c98b06c972b281d08bb4c97433ea6bf568c8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Oct 2024 20:37:43 +0800 Subject: [PATCH 0528/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index b055deb3596..8ae9cd6d4c6 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -25048,7 +25048,7 @@ ImgOps | https://imgops.com/#b#`; var checkUniqueImgWin = function() { if (canPreview) { if (result.type != "link" && result.type != "rule" && result.src == result.imgSrc) { - if (result.imgAS.w <= result.imgCS.w && result.imgAS.h <= result.imgCS.h) { + if (result.imgAS.w < result.imgCS.w * 1.2 && result.imgAS.h < result.imgCS.h * 1.2) { if (result.img && result.img.childElementCount) return false; var wSize = getWindowSize(); if (result.imgAS.w <= wSize.w && result.imgAS.h <= wSize.h) return false; From 607c5368a89c0eeadb18b06310130a02bb9d6c55 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Oct 2024 20:53:54 +0800 Subject: [PATCH 0529/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 8ae9cd6d4c6..3adddb8d115 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -21111,7 +21111,7 @@ ImgOps | https://imgops.com/#b#`; display: block;\ }\ span.pv-pic-search-state {\ - top: -18px;\ + top: -21px;\ left: 0px;\ display: block;\ position: absolute;\ @@ -24033,6 +24033,9 @@ ImgOps | https://imgops.com/#b#`; }else{ src=imgSrc; type='force'; + if (img.nodeName == "A") { + description = img.title || img.alt || img.innerText; + } } } From 49c1538fc81fe180f4ba83c5219d00dda144f43c Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Oct 2024 21:08:46 +0800 Subject: [PATCH 0530/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 3adddb8d115..94abc5cac79 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -23401,7 +23401,9 @@ ImgOps | https://imgops.com/#b#`; }, start:function(data){ - if (data && data.type == "link") return; + if (data && data.type == "link") { + data.hide = true; + } //读取中的图片,不显示浮动栏,调整读取图标的位置. if(LoadingAnimC.all.find(function(item,index,array){ if (data.src == item.data.src || data.img == item.data.img) { @@ -25086,6 +25088,12 @@ ImgOps | https://imgops.com/#b#`; img: target }; checkUniqueImgWin(); + + if (!floatBar) { + floatBar = new FloatBarC(); + } + floatBar.start(result); + return; } @@ -25113,6 +25121,11 @@ ImgOps | https://imgops.com/#b#`; description: target.title || target.innerText }; checkUniqueImgWin(); + + if (!floatBar) { + floatBar = new FloatBarC(); + } + floatBar.start(result); } return; } From 991a10a131ec7254213d9c3595dc574f97d0ef12 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Oct 2024 21:22:47 +0800 Subject: [PATCH 0531/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 49923f046ee..05800544306 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -224,11 +224,6 @@ var siteInfo = [ name:"bilibili", enabled:true, url:/^https?:\/\/[^.]+\.bilibili.com/i, - ext: function(target) { - if(target && target.parentNode){ - return target.parentNode.querySelector("img"); - } - }, r: /\d+_\d+\/|\d+_x\d+\.jpg$|@\d+w_\d+h.*\.webp$|_\d+x\d+\.jpg$/i, s: "" }, From 20324f7a1881ac5f5780fbb6bad0ed46444d5530 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Oct 2024 21:27:53 +0800 Subject: [PATCH 0532/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 94abc5cac79..e434d4601b5 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1452374/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1463018/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -12403,7 +12403,7 @@ ImgOps | https://imgops.com/#b#`; searchData:defaultSearchData, downloadWithZip:true, autoOpenViewmore:false, - downloadGap:1 + downloadGap:100 }, imgWindow:{// 图片窗相关设置 From bf9e2750d108dc10efaf9fe28b12303627932e7e Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Oct 2024 21:39:43 +0800 Subject: [PATCH 0533/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index e434d4601b5..9ca4273c3b3 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12104,7 +12104,7 @@ ImgOps | https://imgops.com/#b#`; if (name) name = name.split("\n")[0].replace(/.*?\/\/[^\/]+\//, "").replace(/\?.*/, "").replace(/^data:.*/, ""); if (!url.replace || url.indexOf("data:") === 0) url = ""; url = url.replace(/.*?\/\/[^\/]+\//, ""); - let nameFromUrl = url.match(/.*([^\/\?\=\&]+)\.\w{2,5}(\?|@|$).*/, "$1"); + let nameFromUrl = url.match(/.*?([^\/\?\=\&]+)\.\w{2,5}(\?|@|$).*/, "$1"); nameFromUrl = nameFromUrl ? nameFromUrl[1] : ""; if (/\=&/.test(nameFromUrl)) { nameFromUrl = ""; @@ -12142,7 +12142,7 @@ ImgOps | https://imgops.com/#b#`; name = (nameFromUrl || name || "image").substr(-80); 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) { From 61d84114f2270f1e94998dd94f72dba7a4439641 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 12 Oct 2024 08:15:59 +0800 Subject: [PATCH 0534/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 60fe280cba7..8f6b5c62de0 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3193,7 +3193,7 @@ } } if (!isApp && !next3 && !isJs) { - if (/^(next\s*(»|>>|>|›|→|❯)?|>|▶|>|›|→|❯)$/i.test(aTag.textContent) && aTag.parentNode.hasAttribute && !aTag.parentNode.hasAttribute("jsaction")) { + if (/^(next\s*(»|>>|>|›|→|❯|\d+)?|>|▶|>|›|→|❯)\s*$/i.test(aTag.textContent) && aTag.parentNode.hasAttribute && !aTag.parentNode.hasAttribute("jsaction")) { next3 = aTag; } } @@ -3292,7 +3292,7 @@ } if (eles.length >= 2 && eles[0].href !== eles[1].href) { next = null; - } else if (doc === document) { + } else if (doc === document && next.offsetParent) { let left = getElementLeft(next); if (left < 20 || (document.documentElement.scrollWidth > 500 && left < 250)) { next = null; From 4273ae58ba186289b60d24fb4a1a40de5fbf0d37 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 12 Oct 2024 17:32:53 +0800 Subject: [PATCH 0535/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 47 +++++++++++++++-------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 9ca4273c3b3..873d2589aa8 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -20347,7 +20347,6 @@ ImgOps | https://imgops.com/#b#`; }; self.setToolBadge('zoom',self.zoomLevel); if (self==uniqueImgWin && prefs.floatBar.globalkeys.previewFollowMouse) { - self.following=true; self.followPos(uniqueImgWinInitX, uniqueImgWinInitY); } else { if (!self.zoomed) { @@ -21576,26 +21575,14 @@ ImgOps | https://imgops.com/#b#`; if (!imgWindow) return; this.followPosX = posX; this.followPosY = posY; - if (!this.following && !imme) { - clearTimeout(this.followPosTimer); - this.followPosTimer = setTimeout(() => { - if (this.previewed) return; - this.following = true; - imgWindow.classList.add("pv-pic-window-transition-all"); - this.followPos(this.followPosX, this.followPosY); - }, 50); - return; - } - this.following = false; + if (!imme && this.following) return; let wSize = getWindowSize(); let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2), padding2 = 50, left, top;//内外侧间距 imgWindow.style.position = "fixed"; let scrolled = {x: 0, y: 0}; - if (imme) { - imgWindow.classList.remove("pv-pic-window-transition-all"); - } else this.initMaxSize(); + this.initMaxSize(); if (imgWindow.offsetWidth / imgWindow.offsetHeight > wSize.w / wSize.h) { //宽条,上下半屏 @@ -21603,12 +21590,10 @@ ImgOps | https://imgops.com/#b#`; //上 top = posY - imgWindow.offsetHeight - padding1 + scrolled.y; if (top < padding2>>1) top = padding2>>1; - imgWindow.style.top = top + 'px'; } else { //下 top = posY + padding1 + scrolled.y; if (top > wSize.h - imgWindow.offsetHeight - 1) top = wSize.h - imgWindow.offsetHeight - 1; - imgWindow.style.top = top + 'px'; } left = (wSize.w - imgWindow.offsetWidth) / 2; let maxLeft = posX + padding1; @@ -21617,19 +21602,17 @@ ImgOps | https://imgops.com/#b#`; let minLeft = posX - imgWindow.offsetWidth - padding1; if (left < minLeft) left = minLeft; } - imgWindow.style.left = left + scrolled.x + 'px'; + left = left + scrolled.x; } else { //窄条,左右半屏 if (posX > wSize.w / 2) { //左 left = posX - imgWindow.offsetWidth - padding1 + scrolled.x; if (left < 1) left = 1; - imgWindow.style.left = left + 'px'; } else { //右 left = posX + padding1 + scrolled.x; if (left > wSize.w - imgWindow.offsetWidth - 1) left = wSize.w - imgWindow.offsetWidth - 1; - imgWindow.style.left = left + 'px'; } top = (wSize.h - imgWindow.offsetHeight) / 2; let maxTop = posY + padding1; @@ -21638,8 +21621,27 @@ ImgOps | https://imgops.com/#b#`; let minTop = posY - imgWindow.offsetHeight - padding1; if (top < minTop) top = minTop; } - imgWindow.style.top = top + scrolled.y + 'px'; + top = top + scrolled.y; + } + + clearTimeout(this.followPosTimer); + if (imme || !this.loaded) { + imgWindow.classList.remove("pv-pic-window-transition-all"); + this.following = false; + } else { + if (Math.abs(left - parseInt(imgWindow.style.left)) + Math.abs(top - parseInt(imgWindow.style.top)) > 200) { + this.following = true; + imgWindow.classList.add("pv-pic-window-transition-all"); + this.followPosTimer = setTimeout(() => { + this.following = false; + this.followPos(this.followPosX, this.followPosY); + }, 250); + } else { + imgWindow.classList.remove("pv-pic-window-transition-all"); + } } + imgWindow.style.left = left + 'px'; + imgWindow.style.top = top + 'px'; }, fitToScreen:function(){ let imgWindow = this.imgWindow; @@ -23160,7 +23162,6 @@ ImgOps | https://imgops.com/#b#`; uniqueImgWin.imgWindow.style.opacity = 0; }else{ if (prefs.floatBar.globalkeys.previewFollowMouse) { - uniqueImgWin.following=true; uniqueImgWin.followPos(uniqueImgWinInitX, uniqueImgWinInitY); } else { uniqueImgWin.initMaxSize(); @@ -25214,7 +25215,7 @@ ImgOps | https://imgops.com/#b#`; if (canPreview) { uniqueImgWinInitX = e.clientX; uniqueImgWinInitY = e.clientY; - uniqueImgWin.followPos(uniqueImgWinInitX, uniqueImgWinInitY, true); + uniqueImgWin.followPos(uniqueImgWinInitX, uniqueImgWinInitY); } else { uniqueImgWin.remove(); } From e84e0c1bc1638eadbf3c1afe57465d14c327fdbd Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 12 Oct 2024 18:06:41 +0800 Subject: [PATCH 0536/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 48 +++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 8f6b5c62de0..a696fef3613 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2473,28 +2473,6 @@ if (pageElement && pageElement.length === 1 && pageElement[0].style.display === 'none') { pageElement = [body]; } - if (this.insert && this.curSiteRule.smart && pageElement && pageElement.length > 0 && compareNodeName(pageElement[0], ["tr"])) { - let mainTr = this.insert.parentNode.lastElementChild, mainTdNum = 0, newTdNum = 0; - while (mainTr && !compareNodeName(mainTr, ["tr"])) { - if (!mainTr.previousElementSibling) break; - mainTr = mainTr.previousElementSibling; - } - [].forEach.call(mainTr.children, el => { - if (compareNodeName(el, ["td", "th"])) { - mainTdNum += el.colSpan || 1; - } - }); - [].forEach.call(pageElement[0].children, el => { - if (compareNodeName(el, ["td", "th"])) { - newTdNum += el.colSpan || 1; - } - }); - if (mainTdNum !== newTdNum) { - this.curSiteRule.pageElement = this.curSiteRule.pageElement.replace(/> *table.*/, ">table"); - this.getInsert(true); - return this.getPageElement(doc, curWin, dontFind); - } - } if ((this.curSiteRule.smart || !this.curSiteRule.pageElement) && (!pageElement || pageElement.length == 0) && curWin && !dontFind) { if (!body) return null; let bodyHeight = parseInt(body.offsetHeight || body.scrollHeight); @@ -2731,6 +2709,32 @@ } //if(pageElement)this.saveCurSiteRule(); } + if (this.insert && this.curSiteRule.smart && pageElement && pageElement.length > 0 && compareNodeName(this.insert.parentNode, ["tbody", "table"])) { + let mainTr = this.insert.parentNode.lastElementChild, mainTdNum = 0, newTdNum = 0; + while (mainTr && !compareNodeName(mainTr, ["tr"])) { + if (!mainTr.previousElementSibling) break; + mainTr = mainTr.previousElementSibling; + } + if (mainTr) { + [].forEach.call(mainTr.children, el => { + if (compareNodeName(el, ["td", "th"])) { + mainTdNum += el.colSpan || 1; + } + }); + if (compareNodeName(pageElement[0], ["tr"])) { + [].forEach.call(pageElement[0].children, el => { + if (compareNodeName(el, ["td", "th"])) { + newTdNum += el.colSpan || 1; + } + }); + } + if (mainTdNum !== newTdNum) { + this.curSiteRule.pageElement = this.curSiteRule.pageElement.replace(/> *table.*/, ">table"); + this.getInsert(true); + return this.getPageElement(doc, curWin, dontFind); + } + } + } if (doc !== document) { this.setPageElementCss(pageElement); From 39bd9d146b8cc1b38ea129fc3b2302d13c97b876 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 12 Oct 2024 18:10:35 +0800 Subject: [PATCH 0537/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 873d2589aa8..b3e5c561d94 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -21635,6 +21635,7 @@ ImgOps | https://imgops.com/#b#`; this.followPosTimer = setTimeout(() => { this.following = false; this.followPos(this.followPosX, this.followPosY); + imgWindow.classList.add("pv-pic-window-transition-all"); }, 250); } else { imgWindow.classList.remove("pv-pic-window-transition-all"); From 413b727c7fd3a9bcdd743259fe91266fb24f0ddf Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 12 Oct 2024 21:02:46 +0800 Subject: [PATCH 0538/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index b3e5c561d94..d225a506cc8 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -20522,6 +20522,10 @@ ImgOps | https://imgops.com/#b#`; if(prefs.imgWindow.zoom.mouseWheelZoom){//是否使用鼠标缩放 addWheelEvent(container,function(e){//滚轮缩放 + if (e.target && (e.target.className == "pv-pic-window-next" || e.target.className == "pv-pic-window-pre")) { + e.preventDefault && e.preventDefault(); + return; + } self.imgWindowEventHandler(e); },false); }; From cce4f21406825d57662cd4d773b190c382c59100 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 13 Oct 2024 08:33:13 +0800 Subject: [PATCH 0539/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index a696fef3613..cff1f94fff6 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -1308,7 +1308,7 @@ if (enableDebug) { console.log( `%c【Pagetual v.${_GM_info.script.version}】 ${title ? title : 'debug'}:`, - 'color: yellow;font-size: large;font-weight: bold;background-color: darkblue;', + 'color: yellow;font-size: large;font-weight: bold;background-color: darkblue;border-radius: 10px;text-shadow: 1px 1px 3px black;padding: 5px;', str ); } From e16857c02598647ae730e8e0fdb0ce34392a798a Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 13 Oct 2024 08:57:46 +0800 Subject: [PATCH 0540/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 05800544306..f7b83640cbe 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1346,9 +1346,15 @@ var siteInfo = [ try { const o = JSON.parse(html); const items0 = o.items[0]; + const videos = items0.video_versions; const images = items0.image_versions2; const carousel = items0.carousel_media; - if (carousel) { + if (videos) { + const videoUrl = videos[0].url + '.video'; + let videoAudioSubtitlesUrl = videoUrl; + const caption = (items0.caption ? items0.caption.text : (items0.accessibility_caption ? items0.accessibility_caption : items0.user.full_name)); + return {url: [videoUrl], cap: caption}; + } else if (carousel) { let gallery = []; const caption = (items0.caption ? items0.caption.text : (items0.accessibility_caption ? items0.accessibility_caption : items0.user.full_name)); carousel.map(c => { gallery.push(c.video_versions ? c.video_versions[0].url : c.image_versions2.candidates[0].url); }); From 528ea68dd1f5bf35e70a93035e5740706889ebd1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 13 Oct 2024 08:58:26 +0800 Subject: [PATCH 0541/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index d225a506cc8..526fcda48ff 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1463018/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1463813/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From 7c8e7b35e89db6928e12af9432e9495c5eca9764 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 13 Oct 2024 09:34:08 +0800 Subject: [PATCH 0542/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 526fcda48ff..367ce4a9948 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -15056,6 +15056,8 @@ ImgOps | https://imgops.com/#b#`; var moveFiredCount=0; var moveHandler=function(e){ + e.preventDefault(); + e.stopPropagation(); moveFiredCount++; if(moveFiredCount<2){//给个缓冲。。 return; @@ -21715,6 +21717,8 @@ ImgOps | https://imgops.com/#b#`; imgWStyle.top=oriOffset.top + (e.pageY || e.touches[0].pageY)-mouseCoor.y +'px'; self.keepScreenInside(); self.moving=true; + e.preventDefault(); + e.stopPropagation(); }; var mouseupHandler=function(){ e.preventDefault(); @@ -23490,14 +23494,17 @@ ImgOps | https://imgops.com/#b#`; var targetPosi = getContentClientRect(this.data.img); var pa = this.data.img.parentNode; if (pa && pa.scrollHeight > 30 && pa.scrollWidth > 30) { - var paPosi=getContentClientRect(pa); + var paPosi=pa.getBoundingClientRect(); if (paPosi.width > 30 && paPosi.height > 30) { - if (this.data.img.offsetTop != 0) { + const style = unsafeWindow.getComputedStyle(this.data.img); + const matrix = new DOMMatrixReadOnly(style.transform); + let translateX = matrix.m41, translateY = matrix.m42; + if (translateY || this.data.img.offsetTop != 0) { if (paPosi.height < targetPosi.height - 3) { targetPosi.top = paPosi.top; } } - if (this.data.img.offsetLeft != 0) { + if (translateX || this.data.img.offsetLeft != 0) { if (paPosi.width < targetPosi.width - 3) { targetPosi.left = paPosi.left; } From 5f003facc3d5ac7cc1670aeb8b45021959d19a45 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 13 Oct 2024 16:59:02 +0800 Subject: [PATCH 0543/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index f7b83640cbe..5c6affd3705 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1615,7 +1615,7 @@ var siteInfo = [ }, { name: "amazon", - url: /^https?:\/\/www\.amazon\.com\//, + url: /^https?:\/\/www\.amazon\./, lazyAttr: "data-a-hires", r: [/_?(_AC_|_CR0).*\./, /\._S.\d+\_?/], s: ["", ""] From 55c6992fd57e94ca9603e1228772ef7819cd371c Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 13 Oct 2024 17:13:45 +0800 Subject: [PATCH 0544/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 367ce4a9948..f2869c514bc 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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.10.11.2 +// @version 2024.10.13.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1463813/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1463960/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -24342,7 +24342,7 @@ ImgOps | https://imgops.com/#b#`; } else { newSrc = this.replace(src, rule.r, rule.s); } - return newSrc; + return newSrc && newSrc.length ? newSrc : src; }, getMode: function(src) { if (!src || !src.length) return ""; @@ -25066,7 +25066,7 @@ ImgOps | https://imgops.com/#b#`; var checkUniqueImgWin = function() { if (canPreview) { if (result.type != "link" && result.type != "rule" && result.src == result.imgSrc) { - if (result.imgAS.w < result.imgCS.w * 1.2 && result.imgAS.h < result.imgCS.h * 1.2) { + if (result.imgAS.w < result.imgCS.w * 1.5 && result.imgAS.h < result.imgCS.h * 1.5) { if (result.img && result.img.childElementCount) return false; var wSize = getWindowSize(); if (result.imgAS.w <= wSize.w && result.imgAS.h <= wSize.h) return false; From 9234a2e9243ddca52d4a6908c4be9e909c484629 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 14 Oct 2024 15:33:28 +0800 Subject: [PATCH 0545/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index cff1f94fff6..98348e4bad2 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2920,8 +2920,9 @@ if (e.style.display === "none" || e.getAttribute("aria-disabled") === "true") { return false; } + if (/banner|slick|slide|carousel|gallery/i.test(e.id)) return false; if (e.className) { - if (!/page/i.test(e.className) && /slick|slide|carousel|gallery|disabled\s*$/i.test(e.className)) { + if (!/page/i.test(e.className) && /banner|slick|slide|carousel|gallery|disabled\s*$/i.test(e.className)) { return false; } else if (e.classList) { if (e.classList.contains('disabled') || e.classList.contains('active')) { @@ -2930,7 +2931,7 @@ } } let ariaLabel = e.getAttribute("aria-label"); - if (ariaLabel && /slick|slide|carousel|gallery/i.test(ariaLabel)) return false; + if (ariaLabel && /banner|slick|slide|carousel|gallery/i.test(ariaLabel)) return false; return true; }; if (!ele) return false; From 83d53538e51ccff08aa2ef44e7b0b482f2711279 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 14 Oct 2024 16:17:54 +0800 Subject: [PATCH 0546/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index f2869c514bc..c0cce45d8b6 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -21097,6 +21097,7 @@ ImgOps | https://imgops.com/#b#`; border-radius: 0 0 8px 0;\ top: 0px;\ opacity:0.5;\ + pointer-events: all;\ }\ .pv-pic-window-container>.pv-pic-window-pre:hover~span.pv-pic-search-state,\ .pv-pic-window-container>.pv-pic-window-next:hover~span.pv-pic-search-state{\ @@ -21134,6 +21135,7 @@ ImgOps | https://imgops.com/#b#`; max-width: 100%;\ overflow: hidden;\ font: 13px / 1.4em "Trebuchet MS", sans-serif;\ + pointer-events: none;\ }\ .pv-pic-search-state>span {\ pointer-events: none;\ @@ -24069,7 +24071,7 @@ ImgOps | https://imgops.com/#b#`; noActual:noActual, xhr: xhr, - description: description || img.title || img.alt || '', + description: description || img.title || img.alt || (img.parentNode && img.parentNode.title) || '', img: img, // 处理的图片 imgPA: imgPA, // 图片的第一个父a元素 From ce53bb13ab1d36788c3b5136f6222b523f590170 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 14 Oct 2024 17:31:41 +0800 Subject: [PATCH 0547/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 43 ++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index c0cce45d8b6..fd30012fd75 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -20220,7 +20220,8 @@ ImgOps | https://imgops.com/#b#`; ''+prefs.icons.downloadSvgBtn+ '
    '); - container.firstChild.appendChild(img); + let imgbox=container.firstChild; + imgbox.appendChild(img); this.imgWindow=container; @@ -20509,6 +20510,20 @@ ImgOps | https://imgops.com/#b#`; e.preventDefault(); },false); + let hideToolbarTimer; + imgbox.addEventListener('mousemove',function(e){ + e.preventDefault(); + clearTimeout(hideToolbarTimer); + container.classList.remove("hideToolbar"); + hideToolbarTimer = setTimeout(() => { + container.classList.add("hideToolbar"); + }, 800); + },false); + imgbox.addEventListener('mouseleave',function(e){ + e.preventDefault(); + clearTimeout(hideToolbarTimer); + container.classList.remove("hideToolbar"); + },false); container.addEventListener('mousedown',function(e){//当按下的时,执行平移,缩放,旋转操作 self.imgWindowEventHandler(e); @@ -20529,6 +20544,11 @@ ImgOps | https://imgops.com/#b#`; return; } self.imgWindowEventHandler(e); + clearTimeout(hideToolbarTimer); + container.classList.remove("hideToolbar"); + hideToolbarTimer = setTimeout(() => { + container.classList.add("hideToolbar"); + }, 800); },false); }; @@ -20960,13 +20980,6 @@ ImgOps | https://imgops.com/#b#`; .pv-pic-window-container_focus:not(.preview)>.pv-pic-window-toolbar {\ display: block;\ }\ - .pv-pic-window-container:hover>.pv-pic-window-max.insert,\ - .pv-pic-window-container:hover>.pv-pic-window-close.insert{\ - opacity: 0.1!important;\ - }\ - .pv-pic-window-container:hover>.pv-pic-window-toolbar.insert{\ - opacity: 0.1;\ - }\ .pv-pic-window-toolbar:hover,\ .pv-pic-window-container>.pv-pic-window-toolbar.insert:hover{\ opacity: 1;\ @@ -21083,6 +21096,17 @@ ImgOps | https://imgops.com/#b#`; .pv-pic-window-container_focus:not(.preview)>.pv-pic-search-state {\ opacity:0.8;\ }\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-imgbox{\ + cursor: none;\ + }\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-search-state,\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-toolbar,\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-max,\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-close,\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-pre,\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-next{\ + opacity:0!important;\ + }\ .pv-pic-window-container_focus:not(.preview) .pv-pic-window-imgbox:hover~.pv-pic-window-pre,\ .pv-pic-window-container_focus:not(.preview) .pv-pic-window-imgbox:hover~.pv-pic-window-next{\ opacity:0.3;\ @@ -21093,10 +21117,9 @@ ImgOps | https://imgops.com/#b#`; opacity:1;\ pointer-events: all;\ }\ - .pv-pic-window-container:hover>.pv-pic-search-state{\ + .pv-pic-window-container_focus:hover>.pv-pic-search-state{\ border-radius: 0 0 8px 0;\ top: 0px;\ - opacity:0.5;\ pointer-events: all;\ }\ .pv-pic-window-container>.pv-pic-window-pre:hover~span.pv-pic-search-state,\ From a5a64bde0c69b6f9e2b56f3e68f8ff33591a2eff Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 14 Oct 2024 19:58:00 +0800 Subject: [PATCH 0548/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 5c6affd3705..b709a82528a 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1626,6 +1626,12 @@ var siteInfo = [ r: /-thumbnail.*/, s: ".gif" }, + { + name: "Bangumi", + url: /^https:\/\/bgm\.tv\//, + r: "/c/", + s: "/l/" + }, { name: "porngifmag", url: /^https:\/\/porngifmag\.com/, From 3d93e5a704ce9b52b631f7426a82771a08d023ec Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 15 Oct 2024 12:24:01 +0800 Subject: [PATCH 0549/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index fd30012fd75..2c6e72c7c31 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -20510,7 +20510,9 @@ ImgOps | https://imgops.com/#b#`; e.preventDefault(); },false); - let hideToolbarTimer; + let hideToolbarTimer = setTimeout(() => { + container.classList.add("hideToolbar"); + }, 800); imgbox.addEventListener('mousemove',function(e){ e.preventDefault(); clearTimeout(hideToolbarTimer); From 9f521f6ae63c6e22b14926e3054c24c50922155e Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 15 Oct 2024 15:47:00 +0800 Subject: [PATCH 0550/1065] 1.9.37.109 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 50 +++++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 178f882ffc9..19e5f377f7b 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.108](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.109](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 98348e4bad2..ab3341feca9 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.108 +// @version 1.9.37.109 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -3553,38 +3553,36 @@ parent = parent.parentNode; } if (doc === document) { - if (!this.linkHasHref(nextLink)) { - if (!isVisible(nextLink, _unsafeWindow)) { - this.nextLinkHref = false; - return null; - } - let video = document.querySelector("video,iframe[id*=play],[id*=play]>iframe,iframe[src*=player],iframe[src*=m3u8]"); - if (video) { - if (video.offsetParent && video.name !== 'pagetual-iframe') { - let scrollWidth = video.scrollWidth || video.offsetWidth; - let scrollHeight = video.scrollHeight || video.offsetHeight; - if (compareNodeName(video, ["iframe"])) { - } else if (scrollWidth > 100 && scrollHeight > 100) { - let winWidth = window.innerWidth || document.documentElement.clientWidth; - let winHeight = window.innerHeight || document.documentElement.clientHeight; - if (scrollWidth > winWidth>>1 && scrollHeight > winHeight>>1) { - debug("Disable when large media found"); - } else { - video = null; - } + if (!this.linkHasHref(nextLink) && !isVisible(nextLink, _unsafeWindow)) { + this.nextLinkHref = false; + return null; + } + let video = document.querySelector("video,iframe[id*=play],[id*=play]>iframe,iframe[src*=player],iframe[src*=m3u8]"); + if (video) { + if (video.offsetParent && video.name !== 'pagetual-iframe') { + let scrollWidth = video.scrollWidth || video.offsetWidth; + let scrollHeight = video.scrollHeight || video.offsetHeight; + if (compareNodeName(video, ["iframe"])) { + } else if (scrollWidth > 100 && scrollHeight > 100) { + let winWidth = window.innerWidth || document.documentElement.clientWidth; + let winHeight = window.innerHeight || document.documentElement.clientHeight; + if (scrollWidth > winWidth>>1 && scrollHeight > winHeight>>1) { + debug("Disable when large media found"); } else { video = null; } } else { video = null; } + } else { + video = null; } - if (video) { - isPause = true; - this.clearAddedElements(); - this.nextLinkHref = false; - return null; - } + } + if (video) { + isPause = true; + this.clearAddedElements(); + this.nextLinkHref = false; + return null; } let nextLinkCs = _unsafeWindow.getComputedStyle(nextLink); From 03e1ae38135081676b5c44fd35e97b875cc6a95f Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 15 Oct 2024 16:21:35 +0800 Subject: [PATCH 0551/1065] Update flashViewer.user.js --- FlashViewer-HTML5 Video/flashViewer.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FlashViewer-HTML5 Video/flashViewer.user.js b/FlashViewer-HTML5 Video/flashViewer.user.js index 794174d8cb5..f6d953c7643 100644 --- a/FlashViewer-HTML5 Video/flashViewer.user.js +++ b/FlashViewer-HTML5 Video/flashViewer.user.js @@ -3620,7 +3620,7 @@ mouseDown = true; lastRate = target.playbackRate; speedUpTimer = setTimeout(() => { - target.playbackRate = 3; + target.playbackRate = 5; target.play(); }, 500); lastPos = e.clientX; @@ -3637,7 +3637,6 @@ mouseDown = false; }, true); target.addEventListener('mousemove', function (e) { - clearTimeout(speedUpTimer); if (!mouseDown) return; if (!mouseMoving) { if (Math.abs(e.clientX - lastPos) > 10) { @@ -3645,6 +3644,7 @@ } return; } + clearTimeout(speedUpTimer); target.playbackRate = lastRate; target.pause(); target.currentTime += (e.clientX - lastPos) / 5; From becdd9d28113350b74c80f70a621a1b0def266ba Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 15 Oct 2024 18:54:24 +0800 Subject: [PATCH 0552/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index ab3341feca9..92405dbe69d 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2920,9 +2920,9 @@ if (e.style.display === "none" || e.getAttribute("aria-disabled") === "true") { return false; } - if (/banner|slick|slide|carousel|gallery/i.test(e.id)) return false; + if (/\bbanner|slick|slide|carousel|gallery/i.test(e.id)) return false; if (e.className) { - if (!/page/i.test(e.className) && /banner|slick|slide|carousel|gallery|disabled\s*$/i.test(e.className)) { + if (!/page/i.test(e.className) && /\bbanner|slick|slide|carousel|gallery|disabled\s*$/i.test(e.className)) { return false; } else if (e.classList) { if (e.classList.contains('disabled') || e.classList.contains('active')) { @@ -2931,7 +2931,7 @@ } } let ariaLabel = e.getAttribute("aria-label"); - if (ariaLabel && /banner|slick|slide|carousel|gallery/i.test(ariaLabel)) return false; + if (ariaLabel && /\bbanner|slick|slide|carousel|gallery/i.test(ariaLabel)) return false; return true; }; if (!ele) return false; From cee38bba7e089dfe5416d697f8d3b071a802ad26 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 16 Oct 2024 09:45:57 +0800 Subject: [PATCH 0553/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 92405dbe69d..bd8e7579254 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -8523,7 +8523,7 @@ }, 1); } - const loadmoreReg = /^\s*((点击)?(加载更多|继续加载)|(點擊)?(加載更多|繼續加載)|load\s*more|もっと読み込む)[\.…▼\s]*$/i; + const loadmoreReg = /^\s*((点击)?((加载|展开)(更多|剩余)|继续加载)|(點擊)?((加載|展開)(更多|剩餘)|繼續加載)|load\s*more|もっと読み込む)[\.…▼\s\d%]*$/i; const defaultLoadmoreSel = ".loadMore,.LoadMore,[class*='load-more'],button.show_more,.button-show-more,button[data-testid='more-results-button'],#btn_preview_remain,.view-more-btn"; function getLoadMore(doc, loadmoreBtn) { if (!loadmoreBtn || !getBody(doc).contains(loadmoreBtn) || /less/.test(loadmoreBtn.innerText)) loadmoreBtn = null; From c9f8f400f77ed231d5551cbb7e8d9b9a8ef2bf16 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 16 Oct 2024 14:25:18 +0800 Subject: [PATCH 0554/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index b709a82528a..eea2d077d70 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -425,7 +425,7 @@ var siteInfo = [ { name: '知乎', url: /(zhihu|zhimg)\.com/, - r: /_(b|xs|s|l|\d+x\d+)\./i, + r: /_(b|xs|s|l|\d+(x\d+|w))\./i, s: "." }, { From d37da6aaa34acc54c258678f712c9bf7d9a721bd Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 16 Oct 2024 14:26:35 +0800 Subject: [PATCH 0555/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 2c6e72c7c31..4426f4dc487 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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.10.13.1 +// @version 2024.10.16.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1463960/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1465639/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From 898bfaaea504270b446f0d698a4b220c6dc9a1a1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 16 Oct 2024 16:00:47 +0800 Subject: [PATCH 0556/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 4426f4dc487..1758c21874f 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -13382,10 +13382,12 @@ ImgOps | https://imgops.com/#b#`; function loadHandler(e){ + if(aborted)return; go('load',e); }; function errorHandler(e){ + if(aborted)return; go('error',e); }; @@ -22770,9 +22772,11 @@ ImgOps | https://imgops.com/#b#`; this.blur(true); if(!opacity)this.imgWindow.style.opacity=0; let self = this; - setTimeout(function(){ - if (self.isImg) self.img.src= prefs.icons.brokenImg_small;//如果在加载中取消,图片也取消读取。 - self.imgWindow.parentNode.removeChild(self.imgWindow); + setTimeout(() => { + if (this.removed) { + if (self.isImg) self.img.src= prefs.icons.brokenImg_small;//如果在加载中取消,图片也取消读取。 + self.imgWindow.parentNode.removeChild(self.imgWindow); + } },300); if (!this.preview) { From e02a87c3ac083a0b955d9b8cf539486ea0eac7da Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 17 Oct 2024 08:31:46 +0800 Subject: [PATCH 0557/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 1758c21874f..d62d3da4312 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -20513,7 +20513,9 @@ ImgOps | https://imgops.com/#b#`; },false); let hideToolbarTimer = setTimeout(() => { - container.classList.add("hideToolbar"); + if (this !== uniqueImgWin) { + container.classList.add("hideToolbar"); + } }, 800); imgbox.addEventListener('mousemove',function(e){ e.preventDefault(); From ac8ea572f5a4cf69d1eb04b99eed32cb83b0b172 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 17 Oct 2024 21:22:20 +0800 Subject: [PATCH 0558/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index eea2d077d70..92e5be81e74 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1629,7 +1629,7 @@ var siteInfo = [ { name: "Bangumi", url: /^https:\/\/bgm\.tv\//, - r: "/c/", + r: ["/c/","/m/"], s: "/l/" }, { From df6fe0f0427f499c34eb347f58548a73e7a632c1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 17 Oct 2024 21:26:27 +0800 Subject: [PATCH 0559/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index d62d3da4312..82bdfb265d5 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1465639/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1466550/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From 8b8109baabcd045981ec4974fc537ede11ef338e Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 18 Oct 2024 18:08:26 +0800 Subject: [PATCH 0560/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 82bdfb265d5..3d4fdb9d209 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12729,7 +12729,7 @@ ImgOps | https://imgops.com/#b#`; } const blobUrlMap = new Map(); - if (!envir.firefox) { + try { const drawImageProxy = new Proxy(unsafeWindow.CanvasRenderingContext2D.prototype.drawImage, { apply: function (target, thisArg, argumentsList) { let image = argumentsList[0]; @@ -12751,7 +12751,7 @@ ImgOps | https://imgops.com/#b#`; } }); unsafeWindow.URL.createObjectURL = createObjectURLProxy; - } + } catch(e) {} function downloadImg(url, name, type, errCb) { urlToBlob(url, (blob, ext) => { @@ -23531,13 +23531,13 @@ ImgOps | https://imgops.com/#b#`; if (paPosi.width > 30 && paPosi.height > 30) { const style = unsafeWindow.getComputedStyle(this.data.img); const matrix = new DOMMatrixReadOnly(style.transform); - let translateX = matrix.m41, translateY = matrix.m42; - if (translateY || this.data.img.offsetTop != 0) { + let translateX = matrix.m41, translateY = matrix.m42, scaleX = matrix.m11, scaleY = matrix.m22; + if (translateY || this.data.img.offsetTop != 0 || (scaleY && scaleY !== 1)) { if (paPosi.height < targetPosi.height - 3) { targetPosi.top = paPosi.top; } } - if (translateX || this.data.img.offsetLeft != 0) { + if (translateX || this.data.img.offsetLeft != 0 || (scaleX && scaleX !== 1)) { if (paPosi.width < targetPosi.width - 3) { targetPosi.left = paPosi.left; } From 37b12fe676cd2cd34198f15b8e2c11daecb0518f Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 18 Oct 2024 18:26:01 +0800 Subject: [PATCH 0561/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 3d4fdb9d209..eff5eb39472 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -24053,7 +24053,7 @@ ImgOps | https://imgops.com/#b#`; } catch (e) {} } } - if(src)type='scale'; + if(src)type='tpRule'; } if(!src && !base64Img){//遍历通配规则 @@ -25192,7 +25192,7 @@ ImgOps | https://imgops.com/#b#`; result.imgAS = sizeInfo; result.imgCS = sizeInfo; } - if (prefs.floatBar.showWithRules && result.type == "rule") { + if (prefs.floatBar.showWithRules && (result.type == "rule" || result.type == "tpRule")) { } else if (!(result.imgAS.w == result.imgCS.w && result.imgAS.h == result.imgCS.h)) {//如果不是两者完全相等,那么被缩放了. if (prefs.floatBar.sizeLimitOr) { if (result.imgCS.h <= prefs.floatBar.minSizeLimit.h && result.imgCS.w <= prefs.floatBar.minSizeLimit.w) {//最小限定判断. From a11e9eb5eefe54e20f4033a009ff22014cab3589 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 19 Oct 2024 19:15:59 +0800 Subject: [PATCH 0562/1065] Update Easy offline.user.js --- Easy offline/Easy offline.user.js | 370 +++++++++++++++--------------- 1 file changed, 185 insertions(+), 185 deletions(-) diff --git a/Easy offline/Easy offline.user.js b/Easy offline/Easy offline.user.js index 4fe80a22fc9..cbbc935b5d1 100644 --- a/Easy offline/Easy offline.user.js +++ b/Easy offline/Easy offline.user.js @@ -7,7 +7,7 @@ // @description:zh-TW 一鍵離綫下載 - 一鍵自動將磁鏈、bt種子或其他下載資源離綫下載至網盤 // @namespace https://github.com/hoothin/UserScripts/tree/master/Easy%20offline // @require http://code.jquery.com/jquery-1.7.2.min.js -// @version 1.9.40 +// @version 1.9.41 // @author Hoothin // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAQlBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////8IX9KGAAAAFXRSTlMAwT7hFahN0LZWJgqIavB7YJuRdDPJsaCPAAAA6ElEQVQ4y8WRW5aEIAxEDUGgAQUftf+tjgYOjcPMb3d96Im5pkIxfVgmOuY5mX/afkYVqb/6EXDGh+CNA7axvwOvZrUiDfalX6UY5y+AkZ687Ut9WNgw9SLYQ3cDYfNz4kIAq2Z/wYN0AiSRQN16iroMXnD3K2F+f1oBLK2ckeWpmjFEsc2Tfxn6ndUBLGgjNVgAX8oNa56AO8dKeAEccnW89ruB6bQVWGTL2IcmQJOTdXSdOAIRrMtxsekR8AQ5XyHARLTrAhi6xH0iYWfcOguQpeAtPJJXSvlqEdSl4XaGHb4HEE0f1w+Jcw2XCZjSwgAAAABJRU5ErkJggg== // @match *://*/* @@ -428,190 +428,190 @@ var disableUrl=[".torrentkitty.","bt.box.n0808.com"]; var manageLinksLang={}; var lang = navigator.appName=="Netscape"?navigator.language:navigator.userLanguage; + var config={}; + switch (lang){ + case "zh-CN": + case "zh-SG": + config={ + configure:"全载设置", + yyw:"115网盘", + baidu:"百度网盘", + furk:"Furk网盘", + seedr:"Seedr网盘", + pcloud:"Pcloud网盘", + xunlei:"迅雷离线", + xunleipan:"迅雷网盘", + xiaomi:"小米路由器", + weiyun:"腾讯微云", + bitqiu:"比特球", + apiv:"九秒云播", + torrent:"Itorrents种子下载", + btcache:"Btcache.me种子下载", + enable:"启用", + disable:"禁用", + addIcon:"添加站点", + settingTitle:"全载", + urlRegexpTips:"自定义需要启用一键下载的链接正则,一行一条", + disableOnSite:"已于此站点禁用,点击启用", + bdPathTips:"不需要加'我的网盘/全部文件'", + bdPathTitle:"度盘存储路径:", + settingMouseOver:"仅当鼠标经过时显示图标", + settingBtn:"设置", + allDisableError:"不能全部禁用!", + siteRuleSetOK:"设置成功,刷新生效", + setOK:"设置成功", + regExpError:"含有无效正则,请重新输入", + addSiteRuleTitle:"自定义新增图标规则,一行一条", + siteRulePlaceholder:"站点 @@ 站名 @@ 下载链接正则 @@ 图标base64 @@ 图标背景颜色 @@ 是否隐藏图标\n\n@@ 分隔,目标站点中用 $url 代替目标链接,$hash 代表目标磁链的 hash 值,${reg}用正则提取,$text代表链接文本,$title代表链接title\n\n可用//注释规则\n\n例如:http://192.168.2.1/d2r?u=$url@@路由器下载\nhttp://xxx.com/magnet/$hash@@磁链下载@@^magnet@@data:image/png;base64,AAA@@ffffff", + inputLink:"输入需要离线下载的链接:", + importOrNot:"是否导入规则?", + importCustomAlert:"点击确定追加规则,点击取消覆盖规则", + importOver:"规则导入完毕!", + postOver:"发送成功,返回消息:", + copyOver:"复制成功!", + postError:"发送失败,错误内容:", + importCustomSame:"存在同名规则,是否覆盖?", + copyLinks:"嗅探下载资源", + noLinks:"当前页面没有资源!", + userName:"请输入用户账号", + userPass:"请输入用户密码", + seekKey:"嗅探快捷键:" + }; + manageLinksLang={ + copyAll:"全部复制", + copySel:"复制选中", + addTips:"%i代表递增 %n代表文件名", + sortByName:"按文件名排序", + sortByUrl:"按网址排序", + sortByType:"按扩展名排序", + preHolder:"批量前缀", + nextHolder:"批量后缀", + closeBtn:"关闭", + typeHead:"类型:" + }; + break; + case "zh-TW": + case "zh-HK": + case "zh-MO": + config={ + configure:"全載設置", + yyw:"115網盤", + baidu:"百度網盤", + furk:"Furk網盤", + seedr:"Seedr網盤", + pcloud:"Pcloud網盤", + xunlei:"迅雷離線", + xunleipan:"迅雷網盤", + xiaomi:"小米路由器", + weiyun:"騰訊微雲", + bitqiu:"比特球", + apiv:"九秒雲播", + torrent:"Itorrents種子下載", + btcache:"Btcache.me種子下載", + enable:"啟用", + disable:"禁用", + addIcon:"添加站點", + settingTitle:"全載", + urlRegexpTips:"自定義需要啟用一鍵下載的連結正則,一行一條", + disableOnSite:"已於此站點禁用,點擊啟用", + bdPathTips:"不需要加'我的網盤/全部文件'", + bdPathTitle:"度盤存儲路徑:", + settingMouseOver:"僅當滑鼠經過時顯示圖標", + settingBtn:"設置", + allDisableError:"不能全部禁用!", + siteRuleSetOK:"設置成功,刷新生效", + setOK:"設置成功", + regExpError:"含有無效正則,請重新輸入", + addSiteRuleTitle:"自定義新增圖標規則,一行一條", + siteRulePlaceholder:"站點 @@ 站名 @@ 下載鏈接正則 @@ 圖標base64 @@ 圖標背景顏色 @@ 是否隱藏圖標\n\n@@ 分隔,目標站點中用 $url 代替目標連結,$hash 代表目標磁鏈的 hash 值,${reg}用正则提取,$text代表連結文本,$title代表連結title\n\n可用//注釋規則\n\n例如:http://192.168.2.1/d2r?u=$url@@路由器下載\nhttp://xxx.com/magnet/$hash@@磁鏈下載@@^magnet@@data:image/png;base64,AAA@@ffffff", + inputLink:"輸入需要離線下載的連結:", + importOrNot:"是否導入規則?", + importCustomAlert:"點擊確定追加規則,點擊取消覆蓋規則", + importOver:"規則導入完畢!", + postOver:"發送成功,返回消息:", + copyOver:"複製成功!", + postError:"發送失敗,錯誤内容:", + importCustomSame:"存在同名規則,是否覆蓋?", + copyLinks:"嗅探下載資源", + noLinks:"當前頁面沒有資源!", + userName:"請輸入用戶賬號", + userPass:"請輸入用戶密碼", + seekKey:"嗅探快捷鍵:" + }; + manageLinksLang={ + copyAll:"全部複製", + copySel:"複製選中", + addTips:"%i代表遞增 %n代表文件名", + sortByName:"按文件名排序", + sortByUrl:"按網址排序", + sortByType:"按擴展名排序", + preHolder:"批量前綴", + nextHolder:"批量後綴", + closeBtn:"關閉", + typeHead:"類型:" + }; + break; + default: + config={ + configure:"Easy-Offline Configure", + yyw:"115", + baidu:"BaiduPan", + furk:"Furk", + seedr:"Seedr", + pcloud:"Pcloud", + xunlei:"Xunlei", + xunleipan:"XunleiPan", + xiaomi:"MiWifi", + weiyun:"Weiyun", + bitqiu:"bitqiu", + apiv:"Apiv Online play", + torrent:"Torrent download in itorrent.org", + btcache:"Torrent download in btcache.me", + enable:"Enable ", + disable:"Disable ", + addIcon:"Add new site", + settingTitle: "Easy Offline", + urlRegexpTips: "Customize the Link Regexp, one per line", + disableOnSite: "Disabled currently, click to enable", + bdPathTips: "No need to add'/all files'", + bdPathTitle: "Path of BDpan:", + settingMouseOver: "Display the icon only when the mouse passes over", + settingBtn: "Save", + allDisableError: "Cannot disable all!", + siteRuleSetOK: "Set successfully, refresh takes effect", + setOK: "Set successfully", + regExpError: "Contains invalid regularity, please re-enter", + addSiteRuleTitle: "Customize new icon rules, one per line", + siteRulePlaceholder: "site @@ sitename @@ link regexp @@ icon base64 @@ icon background color @@ hide icon\n\nUse @@ to separated, use $url for the target Link, $hash for the hash of the target magnet link, ${reg} for regexp result on link, $text for link text, $title for link title\n\nUse // to comment rule\n\nFor example: http://192.168.2.1/d2r?u=$url@@MyRouter\nhttp://xxx.com/magnet/$hash@@MyMagnetLinkDownload@@^magnet@@data:image/png;base64,AAA@@ffffff", + inputLink: "Enter the link that needs to be downloaded with this:", + importOrNot:"Do you want to import rules?", + importCustomAlert:"Ok to add rule,Cancel to cover rule", + importOver:"Rules import over!", + postOver:"Post over, return: ", + copyOver:"Copy over!", + postError:"Fail in post, error: ", + importCustomSame:"Rule exists, overwritten?", + copyLinks:"Seek downloadable links", + noLinks:"No links!", + userName:"Input user name", + userPass:"Input user pass", + seekKey:"Seek key: " + }; + manageLinksLang={ + copyAll: "Copy all", + copySel: "Copy selected", + addTips: "%i means increment, %n means file name", + sortByName: "Sort by name", + sortByUrl: "Sort by URL", + sortByType: "Sort by type", + preHolder: "Batch Prefix", + nextHolder: "Batch Suffix", + closeBtn: "Close", + typeHead: "Type:" + }; + break; + } var i18n=(name)=>{ - var config={}; - switch (lang){ - case "zh-CN": - case "zh-SG": - config={ - configure:"全载设置", - yyw:"115网盘", - baidu:"百度网盘", - furk:"Furk网盘", - seedr:"Seedr网盘", - pcloud:"Pcloud网盘", - xunlei:"迅雷离线", - xunleipan:"迅雷网盘", - xiaomi:"小米路由器", - weiyun:"腾讯微云", - bitqiu:"比特球", - apiv:"九秒云播", - torrent:"Itorrents种子下载", - btcache:"Btcache.me种子下载", - enable:"启用", - disable:"禁用", - addIcon:"添加站点", - settingTitle:"全载", - urlRegexpTips:"自定义需要启用一键下载的链接正则,一行一条", - disableOnSite:"已于此站点禁用,点击启用", - bdPathTips:"不需要加'我的网盘/全部文件'", - bdPathTitle:"度盘存储路径:", - settingMouseOver:"仅当鼠标经过时显示图标", - settingBtn:"设置", - allDisableError:"不能全部禁用!", - siteRuleSetOK:"设置成功,刷新生效", - setOK:"设置成功", - regExpError:"含有无效正则,请重新输入", - addSiteRuleTitle:"自定义新增图标规则,一行一条", - siteRulePlaceholder:"站点 @@ 站名 @@ 下载链接正则 @@ 图标base64 @@ 图标背景颜色 @@ 是否隐藏图标\n\n@@ 分隔,目标站点中用 $url 代替目标链接,$hash 代表目标磁链的 hash 值,${reg}用正则提取,$text代表链接文本,$title代表链接title\n\n可用//注释规则\n\n例如:http://192.168.2.1/d2r?u=$url@@路由器下载\nhttp://xxx.com/magnet/$hash@@磁链下载@@^magnet@@data:image/png;base64,AAA@@ffffff", - inputLink:"输入需要离线下载的链接:", - importOrNot:"是否导入规则?", - importCustomAlert:"点击确定追加规则,点击取消覆盖规则", - importOver:"规则导入完毕!", - postOver:"发送成功,返回消息:", - copyOver:"复制成功!", - postError:"发送失败,错误内容:", - importCustomSame:"存在同名规则,是否覆盖?", - copyLinks:"嗅探下载资源", - noLinks:"当前页面没有资源!", - userName:"请输入用户账号", - userPass:"请输入用户密码", - seekKey:"嗅探快捷键:" - }; - manageLinksLang={ - copyAll:"全部复制", - copySel:"复制选中", - addTips:"%i代表递增 %n代表文件名", - sortByName:"按文件名排序", - sortByUrl:"按网址排序", - sortByType:"按扩展名排序", - preHolder:"批量前缀", - nextHolder:"批量后缀", - closeBtn:"关闭", - typeHead:"类型:" - }; - break; - case "zh-TW": - case "zh-HK": - case "zh-MO": - config={ - configure:"全載設置", - yyw:"115網盤", - baidu:"百度網盤", - furk:"Furk網盤", - seedr:"Seedr網盤", - pcloud:"Pcloud網盤", - xunlei:"迅雷離線", - xunleipan:"迅雷網盤", - xiaomi:"小米路由器", - weiyun:"騰訊微雲", - bitqiu:"比特球", - apiv:"九秒雲播", - torrent:"Itorrents種子下載", - btcache:"Btcache.me種子下載", - enable:"啟用", - disable:"禁用", - addIcon:"添加站點", - settingTitle:"全載", - urlRegexpTips:"自定義需要啟用一鍵下載的連結正則,一行一條", - disableOnSite:"已於此站點禁用,點擊啟用", - bdPathTips:"不需要加'我的網盤/全部文件'", - bdPathTitle:"度盤存儲路徑:", - settingMouseOver:"僅當滑鼠經過時顯示圖標", - settingBtn:"設置", - allDisableError:"不能全部禁用!", - siteRuleSetOK:"設置成功,刷新生效", - setOK:"設置成功", - regExpError:"含有無效正則,請重新輸入", - addSiteRuleTitle:"自定義新增圖標規則,一行一條", - siteRulePlaceholder:"站點 @@ 站名 @@ 下載鏈接正則 @@ 圖標base64 @@ 圖標背景顏色 @@ 是否隱藏圖標\n\n@@ 分隔,目標站點中用 $url 代替目標連結,$hash 代表目標磁鏈的 hash 值,${reg}用正则提取,$text代表連結文本,$title代表連結title\n\n可用//注釋規則\n\n例如:http://192.168.2.1/d2r?u=$url@@路由器下載\nhttp://xxx.com/magnet/$hash@@磁鏈下載@@^magnet@@data:image/png;base64,AAA@@ffffff", - inputLink:"輸入需要離線下載的連結:", - importOrNot:"是否導入規則?", - importCustomAlert:"點擊確定追加規則,點擊取消覆蓋規則", - importOver:"規則導入完畢!", - postOver:"發送成功,返回消息:", - copyOver:"複製成功!", - postError:"發送失敗,錯誤内容:", - importCustomSame:"存在同名規則,是否覆蓋?", - copyLinks:"嗅探下載資源", - noLinks:"當前頁面沒有資源!", - userName:"請輸入用戶賬號", - userPass:"請輸入用戶密碼", - seekKey:"嗅探快捷鍵:" - }; - manageLinksLang={ - copyAll:"全部複製", - copySel:"複製選中", - addTips:"%i代表遞增 %n代表文件名", - sortByName:"按文件名排序", - sortByUrl:"按網址排序", - sortByType:"按擴展名排序", - preHolder:"批量前綴", - nextHolder:"批量後綴", - closeBtn:"關閉", - typeHead:"類型:" - }; - break; - default: - config={ - configure:"Easy-Offline Configure", - yyw:"115", - baidu:"BaiduPan", - furk:"Furk", - seedr:"Seedr", - pcloud:"Pcloud", - xunlei:"Xunlei", - xunleipan:"XunleiPan", - xiaomi:"MiWifi", - weiyun:"Weiyun", - bitqiu:"bitqiu", - apiv:"Apiv Online play", - torrent:"Torrent download in itorrent.org", - btcache:"Torrent download in btcache.me", - enable:"Enable ", - disable:"Disable ", - addIcon:"Add new site", - settingTitle: "Easy Offline", - urlRegexpTips: "Customize the Link Regexp, one per line", - disableOnSite: "Disabled currently, click to enable", - bdPathTips: "No need to add'/all files'", - bdPathTitle: "Path of BDpan:", - settingMouseOver: "Display the icon only when the mouse passes over", - settingBtn: "Save", - allDisableError: "Cannot disable all!", - siteRuleSetOK: "Set successfully, refresh takes effect", - setOK: "Set successfully", - regExpError: "Contains invalid regularity, please re-enter", - addSiteRuleTitle: "Customize new icon rules, one per line", - siteRulePlaceholder: "site @@ sitename @@ link regexp @@ icon base64 @@ icon background color @@ hide icon\n\nUse @@ to separated, use $url for the target Link, $hash for the hash of the target magnet link, ${reg} for regexp result on link, $text for link text, $title for link title\n\nUse // to comment rule\n\nFor example: http://192.168.2.1/d2r?u=$url@@MyRouter\nhttp://xxx.com/magnet/$hash@@MyMagnetLinkDownload@@^magnet@@data:image/png;base64,AAA@@ffffff", - inputLink: "Enter the link that needs to be downloaded with this:", - importOrNot:"Do you want to import rules?", - importCustomAlert:"Ok to add rule,Cancel to cover rule", - importOver:"Rules import over!", - postOver:"Post over, return: ", - copyOver:"Copy over!", - postError:"Fail in post, error: ", - importCustomSame:"Rule exists, overwritten?", - copyLinks:"Seek downloadable links", - noLinks:"No links!", - userName:"Input user name", - userPass:"Input user pass", - seekKey:"Seek key: " - }; - manageLinksLang={ - copyAll: "Copy all", - copySel: "Copy selected", - addTips: "%i means increment, %n means file name", - sortByName: "Sort by name", - sortByUrl: "Sort by URL", - sortByType: "Sort by type", - preHolder: "Batch Prefix", - nextHolder: "Batch Suffix", - closeBtn: "Close", - typeHead: "Type:" - }; - break; - } return config[name]?config[name]:name; }; @@ -1420,7 +1420,7 @@ document.body.appendChild(configContent); configContent.innerHTML=`
    - ${i18n("settingTitle")} +

    ${i18n("settingTitle")}

    ${i18n("urlRegexpTips")}
    From 77fcf4a9550aafcdae41cde06d15b9ee72cbbe45 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 22 Oct 2024 11:00:54 +0800 Subject: [PATCH 0563/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index bd8e7579254..4d22b3440c1 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -8527,11 +8527,18 @@ const defaultLoadmoreSel = ".loadMore,.LoadMore,[class*='load-more'],button.show_more,.button-show-more,button[data-testid='more-results-button'],#btn_preview_remain,.view-more-btn"; function getLoadMore(doc, loadmoreBtn) { if (!loadmoreBtn || !getBody(doc).contains(loadmoreBtn) || /less/.test(loadmoreBtn.innerText)) loadmoreBtn = null; - if (!ruleParser.curSiteRule.smart && !ruleParser.curSiteRule.loadMore) return null; + let loadMoreSel = ruleParser.curSiteRule.loadMore; + if (!ruleParser.curSiteRule.smart && !loadMoreSel) return null; if (loadmoreBtn) return loadmoreBtn; - let btnSel = ruleParser.curSiteRule.loadMore || defaultLoadmoreSel; + let btnSel = loadMoreSel || defaultLoadmoreSel; if (btnSel) { loadmoreBtn = getElement(btnSel, doc, null, true); + if (loadmoreBtn && !loadMoreSel) { + let childBtns = loadmoreBtn.querySelectorAll("button,.btn"); + if (childBtns.length === 1) { + loadmoreBtn = childBtns[0]; + } + } } if (!loadmoreBtn) { let buttons = getBody(doc).querySelectorAll("input,button,a,div[onclick]"); From cc995494c5b7eeeb5beef51c18eddc40585285a2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 23 Oct 2024 21:47:54 +0800 Subject: [PATCH 0564/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index eff5eb39472..7448528cc18 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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.10.16.1 +// @version 2024.10.23.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -18907,7 +18907,7 @@ ImgOps | https://imgops.com/#b#`; }\ .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-body>.pv-gallery-img-container>span.pv-gallery-sidebar-toggle{\ opacity: 0.6;\ - padding: 15px;\ + padding: 35px;\ background-color:#00000000;\ }\ .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-body>.pv-gallery-img-container>span.pv-gallery-sidebar-toggle:hover{\ @@ -19156,6 +19156,7 @@ ImgOps | https://imgops.com/#b#`; .pv-gallery-sidebar-viewmore-v{\ height:30px;\ top:6%;\ + top: calc(50% - 25px);\ }\ .pv-gallery-sidebar-toggle-top{\ top:-3px;\ @@ -19163,9 +19164,12 @@ ImgOps | https://imgops.com/#b#`; .pv-gallery-sidebar-viewmore-top{\ top:15px;\ }\ - .pv-gallery-sidebar-toggle-right,.pv-gallery-sidebar-viewmore-right{\ + .pv-gallery-sidebar-toggle-right{\ right:-3px;\ }\ + .pv-gallery-sidebar-viewmore-right{\ + right:18px;\ + }\ .pv-gallery-sidebar-toggle-bottom{\ bottom:-3px;\ }\ @@ -19177,16 +19181,19 @@ ImgOps | https://imgops.com/#b#`; background-color: rgb(42, 42, 42);\ opacity: 1;\ }\ - .pv-gallery-sidebar-toggle-left,.pv-gallery-sidebar-viewmore-left{\ + .pv-gallery-sidebar-toggle-left{\ left:-3px;\ }\ + .pv-gallery-sidebar-viewmore-left{\ + left:18px;\ + }\ span.pv-gallery-sidebar-toggle-content{\ display:inline-block;\ vertical-align:middle;\ white-space:normal;\ word-wrap:break-word;\ overflow-wrap:break-word;\ - line-height:1.1;\ + line-height:16px;\ font-size:18px;\ text-align:center;\ margin-bottom:8px;\ @@ -19204,6 +19211,9 @@ ImgOps | https://imgops.com/#b#`; .pv-gallery-sidebar-toggle-content-v,.pv-gallery-sidebar-viewmore-content-v{\ width:1.1em;\ }\ + span.pv-gallery-sidebar-toggle-content-v{\ + line-height: 60px !important;\ + }\ /*侧边栏开始*/\ .pv-gallery-sidebar-container {\ position: absolute;\ From ed5180fe42b4f6ee6ea528397e440689d9415b73 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 24 Oct 2024 09:12:13 +0800 Subject: [PATCH 0565/1065] 1.9.37.110 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 19e5f377f7b..e31c6ceddea 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.109](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.110](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 4d22b3440c1..9405f35244c 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.109 +// @version 1.9.37.110 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -4129,7 +4129,7 @@ } needCheckClick(ele) { - return this.nextLinkHref === '#' && !picker.contains(ele) && ele.parentNode && ele.parentNode.className !== 'pagetual_pageBar'; + return this.nextLinkHref === '#' && !picker.contains(ele) && ele.parentNode && !ele.parentNode.classList.contains('pagetual_pageBar'); } docElementValid() { @@ -8603,7 +8603,7 @@ if (hidePageBar) return null; url = url.replace(/#p{.*/, ""); let example = (ruleParser.curSiteRule.insertPos == 2 || ruleParser.curSiteRule.insertPos == "in") ? insert.children[0] : (insert.parentNode.children[0] || insert); - while (example && (compareNodeName(example, ["script", "style"]) || example.className == "pagetual_pageBar")) { + while (example && (compareNodeName(example, ["script", "style"]) || example.classList.contains("pagetual_pageBar"))) { example = example.nextElementSibling; } if (!example || !example.parentNode) example = insert; @@ -8627,7 +8627,7 @@ let downSpan = document.createElement("span"); let pageText = document.createElement("a"); let pageNum; - pageBar.className = isHideBar ? "pagetual_pageBar hide" : "pagetual_pageBar"; + pageBar.className = isHideBar ? "pagetual_pageBar autopagerize_page_info hide" : "pagetual_pageBar autopagerize_page_info"; pageBar.id = "pagetual_pageBar" + curPage; pageBar.setAttribute("translate", "no"); if (isPause) { From 6201929f5d231fa834eebfb66c2a01aba6019847 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 24 Oct 2024 09:13:45 +0800 Subject: [PATCH 0566/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 79987c793e9..f13f8d6b0e9 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5545,8 +5545,7 @@ "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;}inIframe:#searchform,[data-l],[data-is-desktop]{display:none;}", - "surround": "shadowDom" + "css": "ol>li{display: inline-flex;}inIframe:#searchform,[data-l],[data-is-desktop]{display:none;}" }, { "name": "Google Trends", From 088d2d3632ad3a7163e37c10c30868e0616294ea Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 24 Oct 2024 01:14:01 +0000 Subject: [PATCH 0567/1065] Update version of Pagetual rules to 73 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index ea70ce01343..d69c74c8b95 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -72 +73 From 62fa800ae8384c4bfc54d421885a5fead75e5448 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 25 Oct 2024 15:57:07 +0800 Subject: [PATCH 0568/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 9405f35244c..f29990b1468 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -8325,14 +8325,20 @@ } if (scrolling) return; scrolling = true; + let curScroll = getBody(document).scrollTop || document.documentElement.scrollTop; setTimeout(() => { scrolling = false; + curScroll = getBody(document).scrollTop || document.documentElement.scrollTop; + if (curScroll <= 20) { + if (sideController.inited) { + sideController.pagenum.innerHTML = createHTML("1"); + } + } }, 100); if (!isLoading && !stopScroll) { checkScrollReach(); } ruleParser.changeVisibility(); - let curScroll = getBody(document).scrollTop || document.documentElement.scrollTop; if (ruleParser.curSiteRule.lockScroll) { if (isLoading && Math.abs(lastScroll - curScroll) > 350) { getBody(document).scrollTop = lastScroll; @@ -8346,11 +8352,6 @@ targetY = -1; } } - if (curScroll <= 20 && curScroll > 0) { - if (sideController.inited) { - sideController.pagenum.innerHTML = createHTML("1"); - } - } }; dblclickHandler = e => { if (forceState == 1 || compareNodeName(e.target, ["input", "textarea", "select", "a", "button", "svg", "use", "img", "path"])) return; From b7a96cd186280e9ebd8147af54272f42a19efbb9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 25 Oct 2024 16:14:55 +0800 Subject: [PATCH 0569/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index f29990b1468..a8d9f43c204 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -7820,14 +7820,14 @@ color: red; } .pagetual_pageBar a:hover>span { - opacity: 1!important; + opacity: 1 !important; } .pagetual_pageBar span.prevScreen, .pagetual_pageBar span.nextScreen { - display: block!important; + display: block !important; top: unset !important; padding: unset !important; - opacity: 0!important; + opacity: 0 !important; } .pagetual_pageBar a:hover>span.prevScreen { margin-top: -${rulesData.opacity == 1 ? 31 : 30}px!important; @@ -8712,7 +8712,7 @@ targetY = scrollTop - (window.innerHeight || document.documentElement.clientHeight); window.scrollTo({ top: targetY, behavior: 'smooth'}); } - }); + }, true); nextBtn.addEventListener("click", e => { e.stopPropagation(); e.preventDefault(); @@ -8724,7 +8724,7 @@ targetY = scrollH || 9999999; window.scrollTo({ top: targetY, behavior: 'smooth'}); } - }); + }, true); if (!rulesData.hideBarArrow) { pageText.insertBefore(preBtn, pageText.firstChild); pageText.insertBefore(nextBtn, pageText.firstChild); @@ -8737,7 +8737,7 @@ pageText.title = "Refresh"; pageText.appendChild(bgRing); pageText.addEventListener("click", e => { - e.stopPropagation(); + if (e.target !== pageText) return; if (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) return; e.preventDefault(); let nextEle = pageBar && pageBar.nextElementSibling; @@ -8750,6 +8750,7 @@ }, true); } else if (rulesData.pageBarMenu) { pageText.addEventListener("click", e => { + if (e.target !== pageText) return; e.stopPropagation(); if (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) return; e.preventDefault(); From 26adbd024e94d370100cc4b39f63e51f0f88b60a Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 25 Oct 2024 21:13:17 +0800 Subject: [PATCH 0570/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 7448528cc18..4b369f6fcba 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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.10.23.1 +// @version 2024.10.25.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -12729,7 +12729,7 @@ ImgOps | https://imgops.com/#b#`; } const blobUrlMap = new Map(); - try { + if (!envir.firefox) { const drawImageProxy = new Proxy(unsafeWindow.CanvasRenderingContext2D.prototype.drawImage, { apply: function (target, thisArg, argumentsList) { let image = argumentsList[0]; @@ -12751,7 +12751,7 @@ ImgOps | https://imgops.com/#b#`; } }); unsafeWindow.URL.createObjectURL = createObjectURLProxy; - } catch(e) {} + } function downloadImg(url, name, type, errCb) { urlToBlob(url, (blob, ext) => { From 6ec5d798b50cbb7ea849236e3c98d239e7cff276 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 26 Oct 2024 13:36:21 +0800 Subject: [PATCH 0571/1065] Update DownloadAllContent.user.js --- DownloadAllContent/DownloadAllContent.user.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index 6dfc2ae440a..a3935d8c601 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -4,7 +4,7 @@ // @name:zh-TW 怠惰小説下載器 // @name:ja 怠惰者小説ダウンロードツール // @namespace hoothin -// @version 2.8.3.13 +// @version 2.8.3.14 // @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文檔 @@ -1830,6 +1830,17 @@ if (window.top != window.self) { if(evalCode.indexOf("return ")==-1){ if(evalCode.indexOf("@")==0){ let content=""; + var selectors=GM_getValue("selectors"); + if(selectors){ + [].forEach.call(data.querySelectorAll(selectors),function(item){ + item.innerHTML=""; + }); + } + [].forEach.call(data.querySelectorAll("script,style,link,noscript,iframe"),function(item){ + if (item && item.parentNode) { + item.parentNode.removeChild(item); + } + }); if(retainImage){ [].forEach.call(data.querySelectorAll("img[src]"), img => { let imgTxt=`![img](${canonicalUri(img.getAttribute("src"), location.href)})`; From 3b066bfeaeae0b2de65e6defa553a66587ce2120 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 26 Oct 2024 16:29:19 +0800 Subject: [PATCH 0572/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 34 ++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 4b369f6fcba..95eed5e65ea 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -21487,6 +21487,9 @@ ImgOps | https://imgops.com/#b#`; }; this.isLongImg=rectSize.h > wSize.h && rectSize.h/rectSize.w > 2.5; if(prefs.imgWindow.suitLongImg && this.isLongImg){ + if(prefs.imgWindow.fitToScreen){ + this.fitToScreenWidth(); + } this.center(rectSize.w <= wSize.w,false); this.imgWindow.classList.add("pv-pic-window-scroll"); }else if(prefs.imgWindow.fitToScreen){ @@ -21705,7 +21708,7 @@ ImgOps | https://imgops.com/#b#`; w: parseFloat(imgWindowCS.width), }; - let size, containsScroll = imgWindow.classList.contains("pv-pic-window-scroll"); + let size = rectSize, containsScroll = imgWindow.classList.contains("pv-pic-window-scroll"); if (prefs.imgWindow.fitToScreenSmall || rectSize.w - wSize.w > 0 || rectSize.h - wSize.h > 0) {//超出屏幕,那么缩小。 if (rectSize.w / rectSize.h > wSize.w / wSize.h) { size = { @@ -21726,6 +21729,35 @@ ImgOps | https://imgops.com/#b#`; } }; }, + fitToScreenWidth:function(){ + let imgWindow = this.imgWindow; + if (!prefs.imgWindow.fitToScreen) return; + let wSize=getWindowSize(); + wSize.h -= 6; + wSize.w -= 6; + + let imgWindowCS = unsafeWindow.getComputedStyle(imgWindow); + let rectSize = { + h: parseFloat(imgWindowCS.height), + w: parseFloat(imgWindowCS.width), + }; + + let size = rectSize, containsScroll = imgWindow.classList.contains("pv-pic-window-scroll"); + if (rectSize.w > wSize.w) { + if (rectSize.w / rectSize.h > wSize.w / wSize.h) { + size = { + w: wSize.w, + h: wSize.w / (rectSize.w / rectSize.h), + }; + } + + let cs = this.getRotatedImgCliSize(size); + let ns = this.imgNaturalSize; + if (cs && ns && cs.w && ns.w) { + this.zoom(cs.w / ns.w); + } + }; + }, center:function(horizontal,vertical){ if(!horizontal && !vertical)return; var imgWindow=this.imgWindow; From 45c2dac25e2f0a79a11c174172f42d20fd0187f5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 27 Oct 2024 10:20:27 +0800 Subject: [PATCH 0573/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 95eed5e65ea..abea2ebbb78 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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.10.25.1 +// @version 2024.10.27.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -25549,6 +25549,7 @@ ImgOps | https://imgops.com/#b#`; if (action == 'enable' || action == 'search') return; if (key == prefs.floatBar.keys[action]) { floatBar.open(event, action); + event.stopPropagation(); event.preventDefault(); return true; } From 5e080a3a2c67bca852101a684bcf19d9b70b2085 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 27 Oct 2024 12:55:55 +0800 Subject: [PATCH 0574/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index abea2ebbb78..c4dc13187d7 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -21467,6 +21467,7 @@ ImgOps | https://imgops.com/#b#`; firstOpen:function(){ ImgWindowC.selectedTool='hand'; + this.removed = false; this.imgWindow.classList.remove("pv-pic-window-scroll"); this.focus(); var imgWindow=this.imgWindow; @@ -21679,7 +21680,7 @@ ImgOps | https://imgops.com/#b#`; imgWindow.classList.remove("pv-pic-window-transition-all"); this.following = false; } else { - if (Math.abs(left - parseInt(imgWindow.style.left)) + Math.abs(top - parseInt(imgWindow.style.top)) > 200) { + if (Math.abs(left - parseInt(imgWindow.style.left)) + Math.abs(top - parseInt(imgWindow.style.top)) > 50) { this.following = true; imgWindow.classList.add("pv-pic-window-transition-all"); this.followPosTimer = setTimeout(() => { From b8b7f8b301a426e2903fbb149a2ed26d96c29d83 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 28 Oct 2024 11:47:41 +0800 Subject: [PATCH 0575/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index f13f8d6b0e9..69b425d55b5 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5851,8 +5851,9 @@ "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", From 73312c586723776de51f3c6e451ae0fbb9a00539 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Mon, 28 Oct 2024 03:47:58 +0000 Subject: [PATCH 0576/1065] Update version of Pagetual rules to 74 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index d69c74c8b95..fff0a2476aa 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -73 +74 From 9c9d977d2be459d30be7eb7833475672aa908416 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 28 Oct 2024 12:06:36 +0800 Subject: [PATCH 0577/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 69b425d55b5..09018747109 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5674,7 +5674,16 @@ "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" + "nextLink": "#main > div.pagination-container > div.pagination > form[aria-label='page Next'] > button", + "action": 0 +}, +{ + "name": "Startpage Search Results", + "url": "^https?://www\\.startpage\\.com/sp/", + "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": "图书书目检索", From cd15ea7677537efd2ed0eef528c0b798335c405e Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 28 Oct 2024 12:07:24 +0800 Subject: [PATCH 0578/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 09018747109..f054a965671 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5675,13 +5675,6 @@ "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", - "action": 0 -}, -{ - "name": "Startpage Search Results", - "url": "^https?://www\\.startpage\\.com/sp/", - "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 }, From e5eebf86a0ffdb60fcc6f100b4eb95f656c8cd60 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Mon, 28 Oct 2024 04:08:07 +0000 Subject: [PATCH 0579/1065] Update version of Pagetual rules to 75 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index fff0a2476aa..78eb67cee1a 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -74 +75 From 6ffc2cff15e7c62e80c8012507c0bf8e3d788fdd Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 28 Oct 2024 20:14:08 +0800 Subject: [PATCH 0580/1065] 1.9.37.111 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index e31c6ceddea..e806ff20a68 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.110](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.111](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index a8d9f43c204..b8ef88a8442 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.110 +// @version 1.9.37.111 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -2219,7 +2219,7 @@ return -1; } else if ((b.nextLink || b.pageElement) && (!a.nextLink && !a.pageElement)) { return 1; - } else { + } else if (a.from === b.from) { if (a.url.length > b.url.length) { return -1; } else if (a.url.length < b.url.length) { From b80f0013ecc06a224f07098773ee7b93d89452b1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 28 Oct 2024 20:14:58 +0800 Subject: [PATCH 0581/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index b8ef88a8442..425f1c154a0 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2227,6 +2227,8 @@ } else { return 0; } + } else { + return 0; } } }); From d2305c95c16c670bc18e5122a3093acd57dabcf7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 28 Oct 2024 22:02:02 +0800 Subject: [PATCH 0582/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index f054a965671..f3a936bdaff 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -3463,7 +3463,7 @@ "example": "http://e-hentai.org/,https://exhentai.org/", "url": "^https?://(e-hentai|exhentai)\\.org/", "nextLink": "//table[@class='ptt']//a[string()='>'] | id('next') | id('unext')", - "pageElement": ".itg>div,.itg>tbody>tr:not(:first-of-type),.gl1t, #gdt>div:not(.c), #img", + "pageElement": ".itg>div,.itg>tbody>tr:not(:first-of-type),.gl1t, #gdt>div:not(.c),#gdt>a:not(.c), #img", "replaceElement": ".ptt,.ptb,.sn,.searchnav", "css": "#img {max-width: 100% !important;height: auto !important;min-height: 400px;}", "pageInit": "let img=doc.getElementById('img');img&&img.setAttribute('onerror','setTimeout(()=>{this.src=this.src},3000)');" From 435c9620aa07a59dcaf6624c2dc4dd5d7a658666 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Mon, 28 Oct 2024 14:02:18 +0000 Subject: [PATCH 0583/1065] Update version of Pagetual rules to 76 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 78eb67cee1a..dd475631bae 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -75 +76 From 612742d029bbe17d2f0881474d71dec95b014b16 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 29 Oct 2024 19:02:07 +0800 Subject: [PATCH 0584/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index f3a936bdaff..6ba6e0a4399 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -3466,7 +3466,8 @@ "pageElement": ".itg>div,.itg>tbody>tr:not(:first-of-type),.gl1t, #gdt>div:not(.c),#gdt>a:not(.c), #img", "replaceElement": ".ptt,.ptb,.sn,.searchnav", "css": "#img {max-width: 100% !important;height: auto !important;min-height: 400px;}", - "pageInit": "let img=doc.getElementById('img');img&&img.setAttribute('onerror','setTimeout(()=>{this.src=this.src},3000)');" + "pageInit": "let img=doc.getElementById('img');img&&img.setAttribute('onerror','setTimeout(()=>{this.src=this.src.replace(/(\\\\?time=.*)?$/,`?time=${Date.now()}`)},3000)');", + "action": 1 }, { "name": "177 漫画/xxiav - 圖片", From 282ee5f5b28afe725db0fcefb1f9ca6e6844afe7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 29 Oct 2024 19:02:59 +0800 Subject: [PATCH 0585/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 6ba6e0a4399..7e2a500e49c 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -3466,8 +3466,7 @@ "pageElement": ".itg>div,.itg>tbody>tr:not(:first-of-type),.gl1t, #gdt>div:not(.c),#gdt>a:not(.c), #img", "replaceElement": ".ptt,.ptb,.sn,.searchnav", "css": "#img {max-width: 100% !important;height: auto !important;min-height: 400px;}", - "pageInit": "let img=doc.getElementById('img');img&&img.setAttribute('onerror','setTimeout(()=>{this.src=this.src.replace(/(\\\\?time=.*)?$/,`?time=${Date.now()}`)},3000)');", - "action": 1 + "pageInit": "let img=doc.getElementById('img');img&&img.setAttribute('onerror','setTimeout(()=>{this.src=this.src.replace(/(\\\\?time=.*)?$/,`?time=${Date.now()}`)},3000)');" }, { "name": "177 漫画/xxiav - 圖片", From 4ab5e03fd660841f3ad27f7388b5593cd72e713d Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 29 Oct 2024 11:04:49 +0000 Subject: [PATCH 0586/1065] Update version of Pagetual rules to 77 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index dd475631bae..987e7ca9a76 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -76 +77 From 7c6c06323ee9954862cdca38b1779bf77f9a7b23 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 29 Oct 2024 21:09:36 +0800 Subject: [PATCH 0587/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 92e5be81e74..3b17795bd54 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -913,9 +913,9 @@ var siteInfo = [ url: /donmai\.us/, src: /(thumbnails|sample)\/(.*)\/(thumbnail|sample)_|\/\d+x\d+\//i, r: [/\/(thumbnails|sample)\/(.*)\/(thumbnail|sample)_(.*)/i, - /\/\d+x\d+\//i + /\/\d+x\d+\/(.*)\..*/i ], - s: ["/original/$2/$4","/original/"] + s: ["/original/$2/$4",["/original/$1.jpg", "/original/$1.png"]] }, { name: "erosberry", From fb235dd498a6739e70eb48ed1010bccf191260da Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 29 Oct 2024 21:11:08 +0800 Subject: [PATCH 0588/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index c4dc13187d7..ee89ae7a5bf 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1466550/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1473715/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From 71c8af0f61442f7bbda2fabe3294a0081cd7d153 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 30 Oct 2024 20:13:27 +0800 Subject: [PATCH 0589/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 425f1c154a0..cfbb36b8d47 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -1471,8 +1471,8 @@ const ruleImportUrlReg = /greasyfork\.org\/.*scripts\/438684(\-[^\/]*)?(\/discussions|\/?$|\/feedback)|github\.com\/hoothin\/UserScripts\/(tree\/master\/Pagetual|issues)|^https:\/\/pagetual\.hoothin\.com\/.*firstRun\.html/i; const allOfBody = "body>*"; const mainSel = ["article,.article","[role=main],main,.main,#main","#results"]; - const nextTextReg1 = new RegExp("\u005e\u7ffb\u003f\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u0031\u005d\u003f\u005b\u9875\u9801\u5f20\u5f35\u005d\u007c\u005e\u006e\u0065\u0078\u0074\u005b\u005c\u005c\u0073\u005f\u002d\u005d\u003f\u0070\u0061\u0067\u0065\u005c\u005c\u0073\u002a\u005b\u203a\u003e\u2192\u00bb\u005d\u003f\u0024\u007c\u6b21\u306e\u30da\u30fc\u30b8\u007c\u005e\u6b21\u3078\u003f\u0024\u007c\u0412\u043f\u0435\u0440\u0435\u0434\u007c\u005e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435", "i"); - const nextTextReg2 = new RegExp("\u005e\u0028\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u0031\u005d\u003f\u005b\u7ae0\u8bdd\u8a71\u8282\u7bc0\u5e45\u005d\u007c\u006e\u0065\u0078\u0074\u002e\u003f\u0063\u0068\u0061\u0070\u0074\u0065\u0072\u0029\u0028\u005b\u003a\uff1a\u005c\u002d\u005f\u2014\u005c\u0073\u005c\u002e\u3002\u003e\u0023\u00b7\u005c\u005b\u3010\u3001\uff08\u005c\u0028\u002f\u002c\uff0c\uff1b\u003b\u2192\u005d\u007c\u0024\u0029", "i"); + const nextTextReg1 = new RegExp("\u005e\u7ffb\u003f\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u2500\u0031\u005d\u003f\u005b\u9875\u9801\u5f20\u5f35\u005d\u007c\u005e\u006e\u0065\u0078\u0074\u005b\u005c\u005c\u0073\u005f\u002d\u005d\u003f\u0070\u0061\u0067\u0065\u005c\u005c\u0073\u002a\u005b\u203a\u003e\u2192\u00bb\u005d\u003f\u0024\u007c\u6b21\u306e\u30da\u30fc\u30b8\u007c\u005e\u6b21\u3078\u003f\u0024\u007c\u0412\u043f\u0435\u0440\u0435\u0434\u007c\u005e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435", "i"); + const nextTextReg2 = new RegExp("\u005e\u0028\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u2500\u0031\u005d\u003f\u005b\u7ae0\u8bdd\u8a71\u8282\u7bc0\u5e45\u005d\u007c\u006e\u0065\u0078\u0074\u002e\u003f\u0063\u0068\u0061\u0070\u0074\u0065\u0072\u0029\u0028\u005b\u003a\uff1a\u005c\u002d\u005f\u2014\u005c\u0073\u005c\u002e\u3002\u003e\u0023\u00b7\u005c\u005b\u3010\u3001\uff08\u005c\u0028\u002f\u002c\uff0c\uff1b\u003b\u2192\u005d\u007c\u0024\u0029", "i"); const prevReg = new RegExp("\u005e\u005c\u0073\u002a\u0028\u005b\u4e0a\u524d\u9996\u5c3e\u005d\u007c\u0070\u0072\u0065\u0076\u0069\u006f\u0075\u0073\u007c\u0065\u006e\u0064\u0029", "i"); const lazyImgAttr = ["data-lazy-src", "data-s", "data-lazy", "data-isrc", "data-url", "data-orig-file", "zoomfile", "file", "original", "load-src", "imgsrc", "real_src", "src2", "origin-src", "data-lazyload", "data-lazyload-src", "data-lazy-load-src", "data-ks-lazyload", "data-ks-lazyload-custom", "data-src", "data-defer-src", "data-actualsrc", "data-cover", "data-original", "data-thumb", "data-imageurl", "data-placeholder", "lazysrc"]; var rulesData = {uninited: true, firstRun: true, sideController: !isMobile}, ruleUrls, updateDate, loadNowNum = 5, autoScrollRate = 50; From bc613dee8606b00de36f9e54a8f1555508971ed6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 31 Oct 2024 12:47:31 +0800 Subject: [PATCH 0590/1065] 1.9.37.112 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index e806ff20a68..f5f80719a3a 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.111](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.112](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index cfbb36b8d47..cf4b9d4aedc 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.111 +// @version 1.9.37.112 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -9160,13 +9160,18 @@ clearInterval(checkRemoveIntv); window.removeEventListener('message', loadedHandler, false); iframe.removeEventListener('load', loadedHandler, false); + let doc; + try { + doc = iframe.contentDocument || iframe.contentWindow.document; + doc.hasFocus = () => true; + } catch(e) {} let pageEleTryTimes = 0; async function checkIframe() { if (urlChanged || isPause) { return callback(false, false); } try { - let doc = iframe.contentDocument || iframe.contentWindow.document; + doc = doc || iframe.contentDocument || iframe.contentWindow.document; if (checkEval && !await checkEval(doc)) { setTimeout(() => { checkIframe(); @@ -9544,6 +9549,7 @@ emuIframe.addEventListener("load", e => { try { iframeDoc = emuIframe.contentDocument || emuIframe.contentWindow.document; + iframeDoc.hasFocus = () => true; } catch(e) { if (e.message && e.message.indexOf("cross-origin") != -1 && notSetSandbox && emuIframe.hasAttribute("sandbox")) { emuIframe.removeAttribute("sandbox"); From 150504fc1b32202ad8315e1bd9724bc43e665892 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Nov 2024 16:02:07 +0800 Subject: [PATCH 0591/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index cf4b9d4aedc..3b50794605d 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3001,8 +3001,8 @@ ".pager__next>a", ".page-numbers.current+a", "a.page-numbers.next", - "body [class*=pagination] li.active+span+li>a", - "body [class*=pagination] li.active+li>a", + "body [class*=paginat] li.active+span+li>a", + "body [class*=paginat] li.active+li>a", "body [class^=pag] .current+a", ".page_current+a", "input[value='next']", @@ -3032,8 +3032,9 @@ "body [class*=page--current]+li>a", "body [class*=Pages]>.curr+a", "body [class*=page]>.cur+a", - "body [class*=pagination] [class*=next]", - "body [class*=pagination] [class*=right]", + "body [class*=paginat] [class*=current]+li>a", + "body [class*=paginat] [class*=next]", + "body [class*=paginat] [class*=right]", ".page>em+a", "[name*=nextPage]", '//button[contains(@class, "Page")][text()="Next"]', From 61494dcc3394194e46a88da0ede3220a0fa12c3c Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 4 Nov 2024 17:28:45 +0800 Subject: [PATCH 0592/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 7e2a500e49c..4a6b9882e6b 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5618,7 +5618,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" From e14b0da3aef206cf8bb3698d165639b7411c1572 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Mon, 4 Nov 2024 09:28:52 +0000 Subject: [PATCH 0593/1065] Update version of Pagetual rules to 78 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 987e7ca9a76..8e14edce9cc 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -77 +78 From ca2e58e3d95c91a2b8fdc9973d1f7ed1f22315cb Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 6 Nov 2024 20:43:34 +0800 Subject: [PATCH 0594/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 3b50794605d..57265bc4251 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2557,7 +2557,8 @@ let h = validSize.h; let w = validSize.w; if (isNaN(h) || isNaN(w) || !h || !w) continue; - isHori = Math.abs(preOffsetTop - curNode.offsetTop) <= 20 ? true : (preOffsetTop === -1 && curNode.nextElementSibling && curNode.nextElementSibling.offsetTop === curNode.offsetTop); + let elementSibling = curNode.nextElementSibling || curNode.previousElementSibling; + isHori = Math.abs(preOffsetTop - curNode.offsetTop) <= 20 ? true : (preOffsetTop === -1 && elementSibling && elementSibling.offsetTop === curNode.offsetTop); if (isHori && h <= 50) continue; /*if (isHori && nextLeftPos && curMaxEle && curWidth > 500 && curHeight > 500) { let curRect = curNode.getBoundingClientRect(); From 1183a9db38354bf91dc68e9aa47e1713fc3a9efc Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 10 Nov 2024 09:19:44 +0800 Subject: [PATCH 0595/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 4a6b9882e6b..f88593e79fe 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -6300,7 +6300,7 @@ }, { "name": "什么值得买社区", - "action": 0, + "action": 1, "url": "^https://post\\.smzdm\\.com/p", "pageElement": "#comment", "nextLink": ".pagedown>a" From 45012ecbbaaf8f4ebed0b182f970cdb5d8751738 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 10 Nov 2024 01:19:51 +0000 Subject: [PATCH 0596/1065] Update version of Pagetual rules to 79 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 8e14edce9cc..85322d0b541 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -78 +79 From adda7c74aa64c15502e93eb6bd4d2c7e26a9271a Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 12 Nov 2024 20:50:25 +0800 Subject: [PATCH 0597/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index f88593e79fe..a73a6423c35 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -7256,6 +7256,12 @@ "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/", From 5fdcb946d09bc7efeb636cbd79217c97e5ce9b6b Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 12 Nov 2024 13:13:40 +0000 Subject: [PATCH 0598/1065] Update version of Pagetual rules to 80 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 85322d0b541..d15a2cc44e3 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -79 +80 From 545dda853976c916a292367c1657a7578126067f Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 17 Nov 2024 19:27:55 +0800 Subject: [PATCH 0599/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 4751f08b422..58f40b123eb 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -107,7 +107,7 @@ function checkLeftItem(item) { let mu = item.getAttribute("mu"); - if (mu && mu !== 'null' && mu.indexOf("nourl") == -1) { + if (mu && mu !== 'null' && mu.indexOf("nourl") == -1 && mu.indexOf("lightapp") == -1) { if (/^https:\/\/baijiahao\.baidu\.com/.test(mu)) { item.remove(); return; @@ -422,7 +422,7 @@ function registerMenuCommand() { initCss(); if (window.top !== window.self) return; - hidePictureRegister = GM_registerMenuCommand(hidePicture ? "✅ 恢复图片与样式" : "❌ 隐藏图片并简化样式", () => { + hidePictureRegister = GM_registerMenuCommand(hidePicture ? "✅ 恢复图片视频与样式" : "❌ 隐藏图片视频并简化样式", () => { GM_unregisterMenuCommand(killRightRegister); GM_unregisterMenuCommand(hidePictureRegister); hidePicture = !hidePicture; From ac67e4f26d124d1d34f525f64eecbb9c686cf2fd Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 17 Nov 2024 19:31:15 +0800 Subject: [PATCH 0600/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 58f40b123eb..8d6543bde46 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -107,7 +107,7 @@ function checkLeftItem(item) { let mu = item.getAttribute("mu"); - if (mu && mu !== 'null' && mu.indexOf("nourl") == -1 && mu.indexOf("lightapp") == -1) { + if (mu && mu !== 'null' && mu.indexOf("nourl") == -1 && item.getAttribute("tpl") != "short_video") { if (/^https:\/\/baijiahao\.baidu\.com/.test(mu)) { item.remove(); return; From bfb456f96d25a91450aef5376b51780a1bad05af Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 18 Nov 2024 15:38:26 +0800 Subject: [PATCH 0601/1065] 1.9.37.113 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index f5f80719a3a..aff58592cd5 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.112](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.113](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 57265bc4251..c688ba5c0c8 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.112 +// @version 1.9.37.113 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -4460,7 +4460,11 @@ for (let i = 0; i < oldCanvass.length; i++) { let oldCanvas = oldCanvass[i]; let newCanvas = newCanvass[i]; - newCanvas.getContext('2d').drawImage(oldCanvas, 0, 0); + if (oldCanvas.width && oldCanvas.height) { + try { + newCanvas.getContext('2d').drawImage(oldCanvas, 0, 0); + } catch(e) {} + } } if (!compareNodeName(newEle, ["style", "script"])) self.visibilityItems.push(newEle); collection.appendChild(newEle); From 1743003464bdb02d0597d51513dc0be374af49fb Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 25 Nov 2024 18:30:47 +0800 Subject: [PATCH 0602/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index c688ba5c0c8..b9898ffcda6 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3005,6 +3005,7 @@ "body [class*=paginat] li.active+span+li>a", "body [class*=paginat] li.active+li>a", "body [class^=pag] .current+a", + "body [class*=-pag] .current+a", ".page_current+a", "input[value='next']", "input[value='Next page']", From 539542c9aa6fa298acd23826352d21bbb4c75121 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 26 Nov 2024 19:11:05 +0800 Subject: [PATCH 0603/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 54 ++++++++++++++++++----------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 8d6543bde46..569b6ebdb39 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -4,7 +4,7 @@ // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @name:en Kill Baidu AD // @namespace hoothin -// @version 1.23.10 +// @version 1.23.11 // @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,删除百家号 // @description:zh-CN 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,移除百家号 // @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 @@ -99,7 +99,7 @@ let title = item.querySelector('[data-module="title"]'); let isBlack = checkBlackList(mu, title && title.innerText); if (isBlack) { - item.remove(); + item.classList.add("blocked"); return; } } @@ -115,7 +115,7 @@ let title = item.querySelector('h3'); let isBlack = checkBlackList(mu, title && title.innerText); if (isBlack) { - item.remove(); + item.classList.add("blocked"); return; } let link = item.querySelector("a[href*='www.baidu.com/link']"); @@ -236,6 +236,14 @@ } function initCss() { killRightStyle && killRightStyle.parentNode && killRightStyle.parentNode.removeChild(killRightStyle); + GM_addStyle(` + body:not(.showBlocked) .blocked { + display: none!important; + } + body.showBlocked .blocked { + background: linen; + } + `); if (killRight) { killRightStyle = GM_addStyle(` #content_right,[tpl="recommend_list"],#rs_new { @@ -397,25 +405,27 @@ if (pattern === '') { return true; } - let match = pattern.match(/^(\*|[\w-]+):\/{2,3}(?:(\*|\*\.[^/*]+|[^/*]+)\/)?(.*)$/); - if (!match) return url.indexOf(pattern) !== -1; - const [, scheme, host, path] = match; - const urlScheme = url.split(':')[0]; - const urlParam = new URL(url); - if (scheme === '*' || urlScheme === scheme) { - if (host !== '*') { - const urlHost = urlParam.hostname; - if (host.startsWith('*')) { - const hostPattern = host.slice(2); - if (!urlHost.endsWith(hostPattern)) return false; - } else { - if (urlHost !== host) return false; + try { + let match = pattern.match(/^(\*|[\w-]+):\/{2,3}(?:(\*|\*\.[^/*]+|[^/*]+)\/)?(.*)$/); + if (!match) return url.indexOf(pattern) !== -1; + const [, scheme, host, path] = match; + const urlScheme = url.split(':')[0]; + const urlParam = new URL(url); + if (scheme === '*' || urlScheme === scheme) { + if (host !== '*') { + const urlHost = urlParam.hostname; + if (host.startsWith('*')) { + const hostPattern = host.slice(2); + if (!urlHost.endsWith(hostPattern)) return false; + } else { + if (urlHost !== host) return false; + } } + const urlPath = urlParam.pathname + urlParam.search; + const pathRegex = new RegExp(`^${path.replace(/([\.\?])/g, '\\$1').replace(/\*/g, '.*')}$`); + return pathRegex.test(urlPath); } - const urlPath = urlParam.pathname + urlParam.search; - const pathRegex = new RegExp(`^${path.replace(/([\.\?])/g, '\\$1').replace(/\*/g, '.*')}$`); - return pathRegex.test(urlPath); - } + } catch(e) {} return false; } @@ -536,6 +546,10 @@ return; } registerMenuCommand(); + GM_registerMenuCommand("👁️ 检查屏蔽元素", () => { + alert(`屏蔽元素数量:${document.body.querySelectorAll(".blocked").length}`) + document.body.classList.toggle("showBlocked"); + }); GM_registerMenuCommand("🔧 打开设置页", () => { GM_openInTab("https://greasyfork.org/scripts/24192", {active: true}); }); From f6b144e285f0813c3742b5c829657d158050bfef Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 27 Nov 2024 08:43:17 +0800 Subject: [PATCH 0604/1065] 1.9.37.114 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index aff58592cd5..ea3c673858c 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.113](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.114](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index b9898ffcda6..bd169bf10de 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.113 +// @version 1.9.37.114 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -1776,7 +1776,7 @@ timeout: 1000000, headers: { 'accept': 'application/json,text/html', - 'Referer': url, + 'Referer': url }, onload: function(res) { let json = null; @@ -3867,7 +3867,7 @@ headers: { 'Referer': location.href, 'User-Agent': navigator.userAgent, - "Content-Type": (postParams ? "application/x-www-form-urlencoded" : "text/html") + ";charset=" + charset, + "Content-Type": (postParams ? "application/x-www-form-urlencoded" : "text/html") + ";charset=" + charset }, timeout: 10000, onload: function(res) { @@ -7308,7 +7308,7 @@ ruleUrls = [{ id: 1, url: data && data.wedata2github ? 'https://hoothin.github.io/UserScripts/Pagetual/items_all.json' : 'http://wedata.net/databases/AutoPagerize/items_all.json', - type: 0, + type: 0 }]; if (data) { rulesData = data; @@ -7598,7 +7598,7 @@ 'Referer': location.href, 'User-Agent': navigator.userAgent, 'accept': 'text/html,application/xhtml+xml,application/xml', - "Content-Type": (postParams ? "application/x-www-form-urlencoded" : "text/html") + ";charset=" + charset, + "Content-Type": (postParams ? "application/x-www-form-urlencoded" : "text/html") + ";charset=" + charset }; if (ruleHeaders) { if (ruleHeaders.referer) { @@ -8044,7 +8044,7 @@ top, right, bottom, - left, + left } = element.getBoundingClientRect(); return ( @@ -8066,7 +8066,7 @@ top, right, bottom, - left, + left } = pageBar.getBoundingClientRect(); if (top > 500) { nextBar = pageBar; @@ -8076,7 +8076,7 @@ top, right, bottom, - left, + left } = pageBar.getBoundingClientRect(); if (top < -500) { preBar = pageBar; @@ -9645,7 +9645,7 @@ top, right, bottom, - left, + left } = element.getBoundingClientRect(); return ( From f38cc5ea283b93c6df7759b48b8259ebd9bae846 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 27 Nov 2024 10:24:56 +0800 Subject: [PATCH 0605/1065] Update README.md --- Pagetual/README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index ea3c673858c..8ccf6aec10d 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -16,17 +16,15 @@ https://raw.githubusercontent.com/hoothin/UserScripts/master/Pagetual/pagetualRu Buy me a coffee if you get help💞 -
    PayPal
    -
    Ko-fi
    -
    愛發電
    - donate - reward +
    PayPal
    +
    Ko-fi
    +
    愛發電
    - 💬Join our Discord + Join our 💬Discord - 📧Send me an email + Send me an 📧email Made with ❤️ by Hoothin From 7dd198a88a90775c2ba2a576b4fd09e5c7206ba1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 28 Nov 2024 08:30:04 +0800 Subject: [PATCH 0606/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index bd169bf10de..575aea2206c 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -1473,6 +1473,7 @@ const mainSel = ["article,.article","[role=main],main,.main,#main","#results"]; const nextTextReg1 = new RegExp("\u005e\u7ffb\u003f\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u2500\u0031\u005d\u003f\u005b\u9875\u9801\u5f20\u5f35\u005d\u007c\u005e\u006e\u0065\u0078\u0074\u005b\u005c\u005c\u0073\u005f\u002d\u005d\u003f\u0070\u0061\u0067\u0065\u005c\u005c\u0073\u002a\u005b\u203a\u003e\u2192\u00bb\u005d\u003f\u0024\u007c\u6b21\u306e\u30da\u30fc\u30b8\u007c\u005e\u6b21\u3078\u003f\u0024\u007c\u0412\u043f\u0435\u0440\u0435\u0434\u007c\u005e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435", "i"); const nextTextReg2 = new RegExp("\u005e\u0028\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u2500\u0031\u005d\u003f\u005b\u7ae0\u8bdd\u8a71\u8282\u7bc0\u5e45\u005d\u007c\u006e\u0065\u0078\u0074\u002e\u003f\u0063\u0068\u0061\u0070\u0074\u0065\u0072\u0029\u0028\u005b\u003a\uff1a\u005c\u002d\u005f\u2014\u005c\u0073\u005c\u002e\u3002\u003e\u0023\u00b7\u005c\u005b\u3010\u3001\uff08\u005c\u0028\u002f\u002c\uff0c\uff1b\u003b\u2192\u005d\u007c\u0024\u0029", "i"); + const nextTextReg3 = /^(next\s*(»|>>|>|›|→|❯|\d+)?|>|▶|>|›|→|❯)\s*$/i; const prevReg = new RegExp("\u005e\u005c\u0073\u002a\u0028\u005b\u4e0a\u524d\u9996\u5c3e\u005d\u007c\u0070\u0072\u0065\u0076\u0069\u006f\u0075\u0073\u007c\u0065\u006e\u0064\u0029", "i"); const lazyImgAttr = ["data-lazy-src", "data-s", "data-lazy", "data-isrc", "data-url", "data-orig-file", "zoomfile", "file", "original", "load-src", "imgsrc", "real_src", "src2", "origin-src", "data-lazyload", "data-lazyload-src", "data-lazy-load-src", "data-ks-lazyload", "data-ks-lazyload-custom", "data-src", "data-defer-src", "data-actualsrc", "data-cover", "data-original", "data-thumb", "data-imageurl", "data-placeholder", "lazysrc"]; var rulesData = {uninited: true, firstRun: true, sideController: !isMobile}, ruleUrls, updateDate, loadNowNum = 5, autoScrollRate = 50; @@ -3133,10 +3134,10 @@ if (pageDivs && pageDivs.length) { for (let i = pageDivs.length - 1; i >= 0; i--) { let p = pageDivs[i]; - if (/(next\s*(»|>>|>|›|→|❯)?|>|▶|>|›|→|❯)/i.test(p.title || p.value || '')) { + if (/next/i.test(p.title || p.value || '')) { next = p.querySelector("a,button,[type='button']") || p; break; - } else if (/^(next\s*(»|>>|>|›|→|❯)?|>|▶|>|›|→|❯)$/i.test((p.innerText || '').trim())) { + } else if (nextTextReg3.test((p.innerText || '').trim())) { next = p.querySelector("a,button,[type='button']") || p; break; } @@ -3202,8 +3203,20 @@ } } } - if (!isApp && !next3 && !isJs) { - if (/^(next\s*(»|>>|>|›|→|❯|\d+)?|>|▶|>|›|→|❯)\s*$/i.test(aTag.textContent) && aTag.parentNode.hasAttribute && !aTag.parentNode.hasAttribute("jsaction")) { + if (!isApp && !next3) { + if (isJs) { + if (!jsNext) { + let pa = aTag.parentNode; + if (pa && /pag[ei]/i.test(pa.className)) { + jsNext = aTag; + } else { + pa = pa.parentNode; + if (pa && /pag[ei]/i.test(pa.className)) { + jsNext = aTag; + } + } + } + } else if (nextTextReg3.test(aTag.textContent) && aTag.parentNode.hasAttribute && !aTag.parentNode.hasAttribute("jsaction")) { next3 = aTag; } } From 2cd665399f0770a45d6c659ce99a418ac3529c2f Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 28 Nov 2024 09:00:10 +0800 Subject: [PATCH 0607/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 575aea2206c..b0b9d63a5b3 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3203,10 +3203,10 @@ } } } - if (!isApp && !next3) { + if (!isApp && !next3 && nextTextReg3.test(aTag.textContent)) { + let pa = aTag.parentNode; if (isJs) { if (!jsNext) { - let pa = aTag.parentNode; if (pa && /pag[ei]/i.test(pa.className)) { jsNext = aTag; } else { @@ -3216,7 +3216,7 @@ } } } - } else if (nextTextReg3.test(aTag.textContent) && aTag.parentNode.hasAttribute && !aTag.parentNode.hasAttribute("jsaction")) { + } else if (pa.hasAttribute && !pa.hasAttribute("jsaction")) { next3 = aTag; } } From 3a9f8dedaa9535414503326f0e74e169e7998372 Mon Sep 17 00:00:00 2001 From: Lemonade <61580921+lemonadeforlife@users.noreply.github.com> Date: Thu, 28 Nov 2024 08:45:23 +0000 Subject: [PATCH 0608/1065] fixed mal search image big picture not getting big some of image link either webp or jpg. But my rules only accepted webp only. So I extended it to jpg. --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 3b17795bd54..cb3b58aed54 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1686,7 +1686,7 @@ var siteInfo = [ name: "MAL Anime/Manga Search", url: /^https:\/\/myanimelist\.net\/(anime|manga)\.php\?cat=(anime|manga).+/, src: /^https:\/\/cdn\.myanimelist\.net/, - r: /\/r\/(\d+x\d+)(\/images\/(anime|manga)\/\d+\/\d+)\.webp.+/, + r: /\/r\/(\d+x\d+)(\/images\/(anime|manga)\/\d+\/\d+)\.(webp|jpg).+/, s: "$2l.jpg" }, { From dd70e06dc6cfdc4603d72432de4fd6fc77ae4e41 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 28 Nov 2024 17:57:51 +0800 Subject: [PATCH 0609/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index ee89ae7a5bf..c26ced2a8be 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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.10.27.1 +// @version 2024.11.28.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1473715/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1492792/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From bbcc44c2d5f10da6d53e4ee5c47a5188bbedbbcf Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 2 Dec 2024 14:25:11 +0800 Subject: [PATCH 0610/1065] 1.9.37.115 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 8ccf6aec10d..6355ec0f6e4 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.114](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.115](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index b0b9d63a5b3..23430a76f25 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.114 +// @version 1.9.37.115 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -4657,6 +4657,9 @@ background: white; opacity: 0; } + #pagetual-sideController.minSize.uninited #pagetual-sideController-move > svg { + opacity: 1; + } #pagetual-sideController #pagetual-sideController-move > img, #pagetual-sideController #pagetual-sideController-move > span { width: 35px; @@ -4689,6 +4692,9 @@ #pagetual-sideController.minSize #pagetual-sideController-pagenum { opacity: 1; } + #pagetual-sideController.minSize.uninited #pagetual-sideController-pagenum { + opacity: 0; + } #pagetual-sideController:hover { opacity: 1; } @@ -4978,6 +4984,14 @@ } this.pagenum.innerHTML = createHTML(curPage); this.frame.title = i18n("page") + curPage; + if (!this.validPage) { + if (curPage === 1) { + this.frame.classList.add("uninited"); + } else { + this.frame.classList.remove("uninited"); + this.validPage = true; + } + } if (this.frame.parentNode) return; getBody(document).appendChild(this.frame); clearTimeout(this.hideTimer); From 1ae8d3f2bf50da2ed53be889811a6421403cc4ba Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 3 Dec 2024 15:26:54 +0800 Subject: [PATCH 0611/1065] prefix --- DownloadAllContent/DownloadAllContent.user.js | 70 +++++++++++-------- .../DownloadAllContentSavaAsZIP.user.js | 4 +- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index a3935d8c601..3b15e4dc686 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -4,7 +4,7 @@ // @name:zh-TW 怠惰小説下載器 // @name:ja 怠惰者小説ダウンロードツール // @namespace hoothin -// @version 2.8.3.14 +// @version 2.8.3.15 // @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文檔 @@ -268,10 +268,11 @@ if (window.top != window.self) { dacSaveAsZip:"下载为 zip", dacSetCustomRule:"修改规则", dacAddUrl:"添加章节", + prefix:"给章节名称添加前缀", dacStartDownload:"下载选中", - downloadShortcut:"下载章节", - downloadSingleShortcut:"下载单页", - downloadCustomShortcut:"自定义下载" + downloadShortcut:"下载章节快捷键", + downloadSingleShortcut:"下载单页快捷键", + downloadCustomShortcut:"自定义下载快捷键" }; break; case "zh": @@ -316,10 +317,11 @@ if (window.top != window.self) { dacSaveAsZip:"下載為 zip", dacSetCustomRule:"修改規則", dacAddUrl:"新增章節", + prefix:"為章節名稱加上前綴", dacStartDownload:"下載選取", - downloadShortcut:"下載章節", - downloadSingleShortcut:"下載單頁", - downloadCustomShortcut:"自設下載" + downloadShortcut:"下載章節快速鍵", + downloadSingleShortcut:"下載單頁快速鍵", + downloadCustomShortcut:"自設下載快速鍵" }; break; case "ar": @@ -379,6 +381,7 @@ if (window.top != window.self) { 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", @@ -425,10 +428,11 @@ 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; } @@ -966,6 +970,7 @@ if (window.top != window.self) { const minute=60000; var minTxtLength=GM_getValue("minTxtLength") || 100; var customTitle=GM_getValue("customTitle"); + var prefix=GM_getValue("prefix"); var disableNextPage=!!GM_getValue("disableNextPage"); var customNextPageReg=GM_getValue("nextPageReg"); var maxDlPerMin=GM_getValue("maxDlPerMin") || 0; @@ -977,6 +982,23 @@ if (window.top != window.self) { console.warn(e); } } + var linkIndex = 1; + function packLink(doc, item) { + if (customTitle) { + try { + let title = doc.querySelector(customTitle); + if (title && title.innerText) { + item.innerText = title.innerText; + } + } catch(e) { + console.warn(e); + } + } + if (prefix) { + item.innerText = prefix.replace(/\$i/g, linkIndex) + item.innerText; + linkIndex++; + } + } var insertSigns=[]; // var j=0,rCats=[]; var downIndex=0,downNum=0,downOnce=function(wait){ @@ -999,6 +1021,9 @@ if (window.top != window.self) { let curIndex=downIndex; let aTag=aEles[curIndex]; let request=(aTag, curIndex)=>{ + if (aTag && aTag.cloneNode) { + aTag = aTag.cloneNode(true); + } let tryTimes=0; let validTimes=0; function requestDoc(_charset) { @@ -1075,16 +1100,7 @@ if (window.top != window.self) { } else { console.log(result.status); } - if (customTitle) { - try { - let title = doc.querySelector(customTitle); - if (title && title.innerText) { - aTag.innerText = title.innerText; - } - } catch(e) { - console.warn(e); - } - } + packLink(doc, aTag); let validData = processDoc(curIndex, aTag, doc, (result.status>=400?` status: ${result.status} from: ${aTag.href} `:""), validTimes < 5); if (!validData && validTimes++ < 5) { downIndex--; @@ -1211,16 +1227,7 @@ if (window.top != window.self) { } }); } - if (customTitle) { - try { - let title = doc.querySelector(customTitle); - if (title && title.innerText) { - aTag.innerText = title.innerText; - } - } catch(e) { - console.warn(e); - } - } + packLink(doc, aTag); downIndex++; downNum++; let validData = processDoc(curIndex, aTag, doc, "", failedTimes < 2); @@ -2122,10 +2129,12 @@ if (window.top != window.self) { reSortUrl.name = "sort"; contentSort.name = "sort"; let reverse = createOption(i18n.reverseOrder, !!GM_getValue("reverse"), "checkbox"); + let prefix = createOption(i18n.prefix, GM_getValue("prefix") || ""); let disableNextPage = !!GM_getValue("disableNextPage"); let nextPage = createOption(i18n.nextPage, !disableNextPage, "checkbox"); let nextPageReg = createOption(i18n.nextPageReg, GM_getValue("nextPageReg") || ""); let retainImage = createOption(i18n.retainImage, !!GM_getValue("retainImage"), "checkbox"); + prefix.setAttribute("placeHolder", "第 $i 章:"); nextPageReg.setAttribute("placeHolder", "^\\s*(下一[页頁张張]|next\\s*page|次のページ)"); if (disableNextPage) { nextPageReg.parentNode.style.display = "none"; @@ -2159,6 +2168,7 @@ if (window.top != window.self) { GM_setValue("showFilterList", showFilterList.checked); GM_setValue("disableNextPage", !nextPage.checked); GM_setValue("nextPageReg", nextPageReg.value || ""); + GM_setValue("prefix", prefix.value || ""); GM_setValue("downloadShortcut", geneShortcutData(downloadShortcutInput.value) || ""); GM_setValue("downloadSingleShortcut", geneShortcutData(downloadSingleShortcutInput.value) || ""); GM_setValue("downloadCustomShortcut", geneShortcutData(downloadCustomShortcutInput.value) || ""); diff --git a/DownloadAllContent/DownloadAllContentSavaAsZIP.user.js b/DownloadAllContent/DownloadAllContentSavaAsZIP.user.js index ceb8dcc0a09..73c8e6a5ad6 100644 --- a/DownloadAllContent/DownloadAllContentSavaAsZIP.user.js +++ b/DownloadAllContent/DownloadAllContentSavaAsZIP.user.js @@ -3,7 +3,7 @@ // @name:zh-CN 怠惰小说下载器 ZIP 扩展 // @name:zh-TW 怠惰小説下載器 ZIP 擴充 // @namespace hoothin -// @version 0.6 +// @version 0.6.1 // @description Save content as ZIP for DownloadAllContent // @description:zh-CN 下载时分章节保存 TXT 并打包为 ZIP // @description:zh-TW 下載時分章節儲存 TXT 並打包為 ZIP @@ -198,7 +198,7 @@ imgMatch = cat.match(mdImgReg); hasImg = true; } - zipTemp.push({title: (i + 1) + " - " + catTitle.replace(/[\*\/:<>\?\\\|\r\n]/g, "_").slice(0, 50), hasImg: hasImg, content: cat}); + zipTemp.push({title: catTitle.replace(/[\*\/:<>\?\\\|\r\n]/g, "_").slice(0, 50), hasImg: hasImg, content: cat}); } downloadImages(() => { zipTemp.forEach(d => { From c03f153d7f859aa2043e4b37235d4a832a3bec9e Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 4 Dec 2024 17:50:12 +0800 Subject: [PATCH 0612/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index c26ced2a8be..22f96ee38d8 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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.11.28.1 +// @version 2024.12.4.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -12456,7 +12456,7 @@ ImgOps | https://imgops.com/#b#`; var matchedRule, _URL=location.href.slice(0, 500); - const lazyImgAttr = ["data-lazy-src", "org_src", "data-lazy", "data-url", "data-orig-file", "zoomfile", "file", "original", "load-src", "imgsrc", "real_src", "src2", "origin-src", "data-lazyload", "data-lazyload-src", "data-lazy-load-src", "data-ks-lazyload", "data-ks-lazyload-custom", "data-src", "data-defer-src", "data-actualsrc", "data-cover", "data-original", "data-thumb", "data-imageurl", "data-placeholder", "lazysrc", "data-preview"]; + const lazyImgAttr = ["data-lazy-src", "org_src", "data-lazy", "data-url", "data-orig-file", "zoomfile", "file", "original", "load-src", "imgsrc", "real_src", "src2", "origin-src", "data-lazyload", "data-lazyload-src", "data-lazy-load-src", "data-ks-lazyload", "data-ks-lazyload-custom", "data-src", "data-defer-src", "data-actualsrc", "data-cover", "data-original", "data-thumb", "data-imageurl", "data-placeholder", "lazysrc", "data-preview", "data-page-image-url"]; var tprules = [ function(a) { if (this.currentSrc && !this.src) this.src = this.currentSrc; @@ -13898,11 +13898,12 @@ ImgOps | https://imgops.com/#b#`; } if (self.lockMaxSize) { storage.setListItem("maxSize", location.hostname, self.lockMaxSize); - storage.setListItem("minSize", location.hostname, {h: sizeInputH.value, w: sizeInputW.value}); + self.curDefaultSize = {h: sizeInputH.value, w: sizeInputW.value}; } else { storage.setListItem("maxSize", location.hostname, ""); - storage.setListItem("minSize", location.hostname, ""); + self.curDefaultSize = ""; } + storage.setListItem("minSize", location.hostname, self.curDefaultSize); }; var maximizeTrigger=document.createElement('span'); @@ -15690,11 +15691,12 @@ ImgOps | https://imgops.com/#b#`; sizeInputW.title="min width: "+sizeInputW.value+"px"; sizeInputWSpan.innerHTML=createHTML("W: "+Math.floor(sizeInputW.value)+"px"); clearTimeout(this.saveDefaultSize); + var self=this; this.saveDefaultSize = setTimeout(() => { - storage.setListItem("minSize", location.hostname, {h: sizeInputH.value, w: sizeInputW.value}); + self.curDefaultSize = {h: sizeInputH.value, w: sizeInputW.value}; + storage.setListItem("minSize", location.hostname, self.curDefaultSize); }, 1000); - var self=this; var viewmoreShow = this.eleMaps['sidebar-toggle'].style.visibility == 'hidden'; if(viewmoreShow){ var maxSizeH=0,minSizeH=0,maxSizeW=0,minSizeW=0; @@ -17974,7 +17976,15 @@ ImgOps | https://imgops.com/#b#`; linkMedias.push(node); } }); - imgs = imgs.reverse().concat(linkMedias.reverse()); + imgs = imgs.reverse().sort((a, b) => { + if (a.offsetParent && !b.offsetParent) { + return -1; + } + if (!a.offsetParent && b.offsetParent) { + return 1; + } + return 0; + }).concat(linkMedias.reverse()); // 排除库里面的图片 imgs = imgs.filter(function(img){ if (img.parentNode) { From e86055c9768d2e210a0545a8cafd996a2eebd4b7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 6 Dec 2024 21:35:13 +0800 Subject: [PATCH 0613/1065] Update README.md --- DownloadAllContent/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DownloadAllContent/README.md b/DownloadAllContent/README.md index c8b5c03d8b7..4d45efd984d 100644 --- a/DownloadAllContent/README.md +++ b/DownloadAllContent/README.md @@ -18,7 +18,7 @@ 若是遇到下載出錯的站點,可隨意提交 issue 至 [Github](https://github.com/hoothin/UserScripts/)。請幫我點亮 Star ! -*對你有幫助的話,可透過 [![i](https://static.afdiancdn.com/favicon.ico) 愛發電](https://afdian.net/a/hoothin) 或者 [![i](https://ko-fi.com/favicon-32x32.png) Ko-fi](https://ko-fi.com/hoothin) 請我喝一杯奶茶。歡迎加入 [💬Discord 群組](https://discord.com/invite/keqypXC6wD)。* +*對你有幫助的話,可透過 [![i](https://static.afdiancdn.com/favicon.ico) 愛發電](https://afdian.com/a/hoothin) 或者 [![i](https://ko-fi.com/favicon-32x32.png) Ko-fi](https://ko-fi.com/hoothin) 請我喝一杯奶茶。歡迎加入 [💬Discord 群組](https://discord.com/invite/keqypXC6wD)。* ![donate](https://s2.loli.net/2023/02/06/afTMxeASm48z5vE.jpg) From cab78aaf3d6cffc1a0ce6997ba108c245aff55a5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 7 Dec 2024 13:47:37 +0800 Subject: [PATCH 0614/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 93 +++++++++++++++++------------ 1 file changed, 56 insertions(+), 37 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 22f96ee38d8..be6ebbc55f2 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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.12.4.1 +// @version 2024.12.7.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -17961,43 +17961,48 @@ ImgOps | https://imgops.com/#b#`; } return total; } - var imgs = Array.from(body.querySelectorAll('*')).concat([body]).reduceRight((total, node) => { - return anylizeEle(total, node); - }, []); - [].forEach.call(document.head.querySelectorAll("link[rel*='icon']"), node => { - if (imageReg.test(node.href)) { - node.src = node.href; - linkMedias.push(node); - } - }); - [].forEach.call(document.head.querySelectorAll('meta[itemprop="image"]'), node => { - if (imageReg.test(node.content)) { - node.src = node.content; - linkMedias.push(node); - } - }); - imgs = imgs.reverse().sort((a, b) => { - if (a.offsetParent && !b.offsetParent) { - return -1; - } - if (!a.offsetParent && b.offsetParent) { - return 1; - } - return 0; - }).concat(linkMedias.reverse()); - // 排除库里面的图片 - imgs = imgs.filter(function(img){ - if (img.parentNode) { - if (img.parentNode.id=="icons" || img.parentNode.id=="pagetual-preload") { - return false; - } else if (img.parentNode.classList && img.parentNode.classList.contains("search-jumper-btn")) { - return false; - } else if (img.classList && img.classList.contains("pagetual")) { - return false; + var imgs; + if (matchedRule.gallery) { + imgs = matchedRule.gallery(); + } else { + imgs = Array.from(body.querySelectorAll('*')).concat([body]).reduceRight((total, node) => { + return anylizeEle(total, node); + }, []); + [].forEach.call(document.head.querySelectorAll("link[rel*='icon']"), node => { + if (imageReg.test(node.href)) { + node.src = node.href; + linkMedias.push(node); } - } - return !(container.contains(img) || (preloadContainer&&preloadContainer.contains(img))); - }); + }); + [].forEach.call(document.head.querySelectorAll('meta[itemprop="image"]'), node => { + if (imageReg.test(node.content)) { + node.src = node.content; + linkMedias.push(node); + } + }); + imgs = imgs.reverse().sort((a, b) => { + if (a.offsetParent && !b.offsetParent) { + return -1; + } + if (!a.offsetParent && b.offsetParent) { + return 1; + } + return 0; + }).concat(linkMedias.reverse()); + // 排除库里面的图片 + imgs = imgs.filter(function(img){ + if (img.parentNode) { + if (img.parentNode.id=="icons" || img.parentNode.id=="pagetual-preload") { + return false; + } else if (img.parentNode.classList && img.parentNode.classList.contains("search-jumper-btn")) { + return false; + } else if (img.classList && img.classList.contains("pagetual")) { + return false; + } + } + return !(container.contains(img) || (preloadContainer&&preloadContainer.contains(img))); + }); + } await sleep(0); // 已经在图库里面的 @@ -21198,6 +21203,10 @@ ImgOps | https://imgops.com/#b#`; margin-right: -5px;\ padding: 3px;\ }\ + .pv-pic-search-state>span>strong {\ + background: inherit;\ + color: inherit;\ + }\ span.pv-pic-search-state>.pv-icon {\ width: 20px;\ height: 20px;\ @@ -24290,6 +24299,16 @@ ImgOps | https://imgops.com/#b#`; if (site.ext) { self.ext = site.ext; } + if (site.gallery) { + let gallery = site.gallery; + self.gallery = () => { + if (typeof gallery === "string") { + return document.querySelectorAll(gallery); + } else { + return gallery(); + } + }; + } if (site.video) { let reMatch = typeof site.video === "string" && site.video.match(/^\/(.*)\/(\w*)$/); if (reMatch) { From ac6e9c9d092684f44e509cd0d18b16c65a007d67 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 10 Dec 2024 21:04:56 +0800 Subject: [PATCH 0615/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 92 +++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 27 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 23430a76f25..10d8c992281 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -4383,14 +4383,13 @@ parent.parentNode.appendChild(loadingDiv); } } - getBody(document).scrollTop = lastScrollTop; - document.documentElement.scrollTop = lastScrollTop; + this.setPageTop(lastScrollTop); if (sideController.inited) { sideController.frame.classList.add("pagetual-sideController-loading"); } } - insertElement(ele) { + async insertElement(ele) { if (!this.insert || !this.insert.parentNode) { this.getInsert(); } @@ -4404,17 +4403,54 @@ this.addedElePool.push(ele); } if (this.curSiteRule.insertPos == 2 || this.curSiteRule.insertPos == "in") { - this.insert.appendChild(ele); + await this.addElementsInBatches(ele, child => { + self.insert.appendChild(child); + }); } else { - this.insert.parentNode.insertBefore(ele, this.insert); + await this.addElementsInBatches(ele, child => { + self.insert.parentNode.insertBefore(child, self.insert); + }); } } } + async addElementsInBatches(ele, appendCall) { + if (ele.nodeName !== "#document-fragment") { + return appendCall(ele); + } + let elements = ele.children; + return new Promise(resolve => { + function addBatch() { + const fragment = document.createDocumentFragment(); + const batchSize = 5; + for (let i = 0; i < batchSize && elements.length; i++) { + fragment.appendChild(elements[0]); + } + appendCall(fragment); + if (elements.length) { + requestAnimationFrame(addBatch); + } else resolve(); + } + addBatch(); + }); + } + noValidContent(url) { if (!this.curSiteRule.nextLinkByUrl) showTips(i18n("noValidContent"), url); } + setPageTop(top) { + if (getBody(document).scrollTop) { + if (getBody(document).scrollTop != top) { + getBody(document).scrollTop = top; + } + } else { + if (document.documentElement.scrollTop != top) { + document.documentElement.scrollTop = top; + } + } + } + async insertPage(doc, eles, url, callback, tried) { this.oldUrl = this.curUrl; let oldTitle = document.title; @@ -4516,14 +4552,15 @@ let ele = document.createElement("div"); self.insertElement(ele); let shadowRoot = ele.attachShadow({ mode: "open" }); - shadowRoot.appendChild(collection); + await self.addElementsInBatches(collection, child => { + shadowRoot.appendChild(child); + }); addCss(shadowRoot); } else { - self.insertElement(collection); + await self.insertElement(collection); } } - getBody(document).scrollTop = lastScrollTop; - document.documentElement.scrollTop = lastScrollTop; + this.setPageTop(lastScrollTop); this.pageAction(doc, newEles); let enableHistory = this.curSiteRule.history; let enableHistoryAfterInsert = false; @@ -8361,33 +8398,34 @@ } if (scrolling) return; scrolling = true; - let curScroll = getBody(document).scrollTop || document.documentElement.scrollTop; setTimeout(() => { scrolling = false; - curScroll = getBody(document).scrollTop || document.documentElement.scrollTop; + }, 100); + requestAnimationFrame(() => { + let curScroll = document.documentElement.scrollTop || document.body.scrollTop; if (curScroll <= 20) { - if (sideController.inited) { + if (sideController.inited && sideController.pagenum.innerHTML !== "1") { sideController.pagenum.innerHTML = createHTML("1"); } } - }, 100); + if (ruleParser.curSiteRule.lockScroll) { + if (isLoading && Math.abs(lastScroll - curScroll) > 350) { + getBody(document).scrollTop = lastScroll; + document.documentElement.scrollTop = lastScroll; + } else { + lastScroll = curScroll; + } + } + if (targetY >= 0) { + if (Math.abs(targetY - curScroll) < 100) { + targetY = -1; + } + } + }); if (!isLoading && !stopScroll) { checkScrollReach(); } ruleParser.changeVisibility(); - if (ruleParser.curSiteRule.lockScroll) { - if (isLoading && Math.abs(lastScroll - curScroll) > 350) { - getBody(document).scrollTop = lastScroll; - document.documentElement.scrollTop = lastScroll; - } else { - lastScroll = curScroll; - } - } - if (targetY >= 0) { - if (Math.abs(targetY - curScroll) < 100) { - targetY = -1; - } - } }; dblclickHandler = e => { if (forceState == 1 || compareNodeName(e.target, ["input", "textarea", "select", "a", "button", "svg", "use", "img", "path"])) return; @@ -8915,7 +8953,7 @@ if (sideController.inited) { try { let observer = new IntersectionObserver(entries => { - if (entries[0].intersectionRatio > 0) { + if (entries[0].intersectionRatio > 0 && sideController.pagenum.innerHTML != localPage) { sideController.pagenum.innerHTML = createHTML(localPage); } }); From 939b89a38b68d12e2b460db7a1995076b2bb0372 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 11 Dec 2024 12:14:03 +0800 Subject: [PATCH 0616/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 10d8c992281..0a8cdb60ec3 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -4428,7 +4428,7 @@ } appendCall(fragment); if (elements.length) { - requestAnimationFrame(addBatch); + setTimeout(addBatch, 0); } else resolve(); } addBatch(); @@ -4440,12 +4440,13 @@ } setPageTop(top) { - if (getBody(document).scrollTop) { - if (getBody(document).scrollTop != top) { + let bodyScroll = getBody(document).scrollTop; + if (bodyScroll) { + if (Math.abs(bodyScroll - top) > 50) { getBody(document).scrollTop = top; } } else { - if (document.documentElement.scrollTop != top) { + if (Math.abs(document.documentElement.scrollTop - top) > 50) { document.documentElement.scrollTop = top; } } @@ -4484,7 +4485,6 @@ window.scrollTo({ top: targetY, behavior: 'instant'}); targetY = -1; } - let lastScrollTop = getBody(document).scrollTop || document.documentElement.scrollTop; this.getInsert(); await this.pageInit(doc, eles); var self = this, newEles = []; @@ -4560,7 +4560,6 @@ await self.insertElement(collection); } } - this.setPageTop(lastScrollTop); this.pageAction(doc, newEles); let enableHistory = this.curSiteRule.history; let enableHistoryAfterInsert = false; From 6a3e74feabf23dc439fef2814572fb8a34f5720f Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 14 Dec 2024 15:57:43 +0800 Subject: [PATCH 0617/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index a73a6423c35..83557752534 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -7446,6 +7446,14 @@ "url": "^https?://www\\.pexels\\.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/", From 16131b345e4b9f6df6917547afd894c2fe8016d2 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 14 Dec 2024 07:58:05 +0000 Subject: [PATCH 0618/1065] Update version of Pagetual rules to 81 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index d15a2cc44e3..d88e3136998 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -80 +81 From 512b2b763292a93c4771ee9a42bc4ad25ec22fa8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 19 Dec 2024 20:03:01 +0800 Subject: [PATCH 0619/1065] update --- Kill Baidu AD/Kill Baidu AD.user.js | 2 +- Pagetual/pagetual.user.js | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index 569b6ebdb39..f0d233a5336 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -107,7 +107,7 @@ function checkLeftItem(item) { let mu = item.getAttribute("mu"); - if (mu && mu !== 'null' && mu.indexOf("nourl") == -1 && item.getAttribute("tpl") != "short_video") { + if (mu && mu !== 'null' && mu.indexOf("http") == 0 && mu.indexOf("nourl") == -1 && item.getAttribute("tpl") != "short_video") { if (/^https:\/\/baijiahao\.baidu\.com/.test(mu)) { item.remove(); return; diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 0a8cdb60ec3..c3238e83149 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2442,6 +2442,15 @@ pageElement = pageElement.children; } this.curSiteRule.pageElement = pageElementSel + (targetChild ? ">*" : ""); + } else if (!pageElement || pageElement.length === 0) { + pageElementSel = pageElementSel.replace(/[^\s\>]+\+/g, ""); + pageElement = getAllElements(pageElementSel, doc); + if (pageElement && pageElement.length === 1) { + if (targetChild) { + pageElement = pageElement.children; + } + this.curSiteRule.pageElement = pageElementSel + (targetChild ? ">*" : ""); + } } } } From cf03bc4401534d2c9c41e509d1fef52e13fb9b45 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 20 Dec 2024 08:20:27 +0800 Subject: [PATCH 0620/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index c3238e83149..f2c2eb13275 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -4392,7 +4392,7 @@ parent.parentNode.appendChild(loadingDiv); } } - this.setPageTop(lastScrollTop); + //this.setPageTop(lastScrollTop); if (sideController.inited) { sideController.frame.classList.add("pagetual-sideController-loading"); } From cfb00b8c0beba50884d3119ac26b4e314589e4a8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 25 Dec 2024 17:46:29 +0800 Subject: [PATCH 0621/1065] 1.9.37.116 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 6355ec0f6e4..53c49120d56 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.115](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.116](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index f2c2eb13275..f03b486d75a 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.115 +// @version 1.9.37.116 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -3045,6 +3045,7 @@ "body [class*=Pages]>.curr+a", "body [class*=page]>.cur+a", "body [class*=paginat] [class*=current]+li>a", + "body [class*=paginat] [class*=next-next]", "body [class*=paginat] [class*=next]", "body [class*=paginat] [class*=right]", ".page>em+a", @@ -8607,7 +8608,7 @@ } const loadmoreReg = /^\s*((点击)?((加载|展开)(更多|剩余)|继续加载)|(點擊)?((加載|展開)(更多|剩餘)|繼續加載)|load\s*more|もっと読み込む)[\.…▼\s\d%]*$/i; - const defaultLoadmoreSel = ".loadMore,.LoadMore,[class*='load-more'],button.show_more,.button-show-more,button[data-testid='more-results-button'],#btn_preview_remain,.view-more-btn"; + const defaultLoadmoreSel = ".loadMore,.LoadMore,[class^='load-more'],[class*=' load-more'],button.show_more,.button-show-more,button[data-testid='more-results-button'],#btn_preview_remain,.view-more-btn"; function getLoadMore(doc, loadmoreBtn) { if (!loadmoreBtn || !getBody(doc).contains(loadmoreBtn) || /less/.test(loadmoreBtn.innerText)) loadmoreBtn = null; let loadMoreSel = ruleParser.curSiteRule.loadMore; @@ -9384,7 +9385,7 @@ [...inputs].forEach(input => { let sel = geneSelector(input, true, true); let mirrorEle = iframeDoc.querySelector(sel); - if (!mirrorEle) return; + if (!mirrorEle || !mirrorEle.offsetParent) return; if (mirrorEle.type === "checkbox" || mirrorEle.type === "radio") { mirrorEle.checked = !!input.checked; } else { @@ -9394,8 +9395,9 @@ [...selectOptions].forEach(option => { let sel = geneSelector(option, true, true); let mirrorEle = iframeDoc.querySelector(sel); - if (!mirrorEle) return; + if (!mirrorEle || !mirrorEle.parentNode.offsetParent) return; let selected = option.selected; + if (mirrorEle.selected === selected) return; mirrorEle.selected = !!selected; if (selected) { mirrorEle.parentNode.dispatchEvent(new Event('change')); From 8275f591edd1354e00c52bfd1b1cf9ffa6fb06e4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 30 Dec 2024 15:44:29 +0800 Subject: [PATCH 0622/1065] Update Switch Traditional Chinese and Simplified Chinese.user.js --- ...nal Chinese and Simplified Chinese.user.js | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js index b023f3c445a..e379235e701 100644 --- a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js +++ b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js @@ -1275,19 +1275,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){ From 9b27408dfe75e5cfc121330a2198eaf71da695cd Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 1 Jan 2025 20:29:12 +0800 Subject: [PATCH 0623/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 94f2887bd93..43151b709b2 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -397,7 +397,7 @@ switch (lang) { }, { "name": "Poe - Sage AI Chat", - "url": "https://poe.com/#p{sleep(2000)&[class*\\=ChatMessageInputContainer]>textarea=%s&click([class*\\=ChatMessageSendButton])}" + "url": "https://poe.com/#p{sleep(2000)&[class*\\=ChatMessageInputContainer]>textarea=%s&click([data-button-send])}" }, { "name": "ChatGPT", @@ -547,7 +547,7 @@ switch (lang) { }, { "name": "Search GIF by ChatGPT", - "url": "https://poe.com/ChatGPT#p{sleep(1000)&[class*\\='ChatMessageInputContainer'] textarea=hey ChatGPT. hope you're having a great day. From now on you will respond to anything I say with the perfect gif response. Once you know what gif you want to use, compile the most accurate and perfect search phrase that will result in the specific gif you want to send. respond with url: \" Sure, I'm happy to help you!\\n http://scythe-spot-carpenter.glitch.me/search?search_term\\=.gif \n%s&click(button[class*\\='ChatMessageSendButton_sendButton'])}" + "url": "https://poe.com/ChatGPT#p{sleep(1000)&[class*\\='ChatMessageInputContainer'] textarea=hey ChatGPT. hope you're having a great day. From now on you will respond to anything I say with the perfect gif response. Once you know what gif you want to use, compile the most accurate and perfect search phrase that will result in the specific gif you want to send. respond with url: \" Sure, I'm happy to help you!\\n http://scythe-spot-carpenter.glitch.me/search?search_term\\=.gif \n%s&click([data-button-send])}" } ] }, @@ -781,7 +781,7 @@ switch (lang) { }, { "name": "Poe - Sage AI Chat", - "url": "https://poe.com/#p{sleep(2000)&[class*\\=ChatMessageInputContainer]>textarea=%s&click([class*\\=ChatMessageSendButton])}" + "url": "https://poe.com/#p{sleep(2000)&[class*\\=ChatMessageInputContainer]>textarea=%s&click([data-button-send])}" }, { "name": "ChatGPT", From ae6902d301b0c5b8c549ea57d980f84adcdc3c1d Mon Sep 17 00:00:00 2001 From: shandianchengzi <1252402849@qq.com> Date: Wed, 1 Jan 2025 23:51:26 +0800 Subject: [PATCH 0624/1065] feat(DownloadAllContent): add saveAs JSON buton, saveURL checkbox and disableAutoStartSave checkbox. --- DownloadAllContent/DownloadAllContent.user.js | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index 3b15e4dc686..d9af96e37e9 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -245,9 +245,12 @@ if (window.top != window.self) { abort:"跳过此章", save:"保存当前", saveAsMd:"存为 Markdown", + saveAsJSON: "存为 JSON", downThreadNum:"设置同时下载的线程数,负数为单线程下载间隔", enableTouch:"在移动端按→↓←↑的方向滑动屏幕画正方形立即开始下载", customTitle:"自定义章节标题,输入内页文字对应选择器", + saveUrl: "储存 URL", + disableAutoStartSave: "禁用自动保存", maxDlPerMin:"每分钟最大下载数", reSortDefault:"默认按页面中位置排序章节", reverseOrder:"反转章节排序", @@ -294,9 +297,12 @@ if (window.top != window.self) { abort:"跳過此章", save:"保存當前", saveAsMd:"存爲 Markdown", + saveAsJSON: "存爲 JSON", downThreadNum:"設置同時下載的綫程數,負數為單線程下載間隔", enableTouch:"在行動端按→↓←↑的方向滑動螢幕畫方立即開始下載", customTitle:"自訂章節標題,輸入內頁文字對應選擇器", + saveUrl: "儲存 URL", + disableAutoStartSave: "禁用自動保存", maxDlPerMin:"每分鐘最大下載數", reSortDefault:"預設依頁面中位置排序章節", reverseOrder:"反轉章節排序", @@ -358,9 +364,12 @@ if (window.top != window.self) { 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", @@ -405,9 +414,12 @@ if (window.top != window.self) { abort:"Abort", save:"Save", saveAsMd:"Save as Markdown", + 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", @@ -885,6 +897,7 @@ if (window.top != window.self) { +
    `); txtDownWords=txtDownContent.querySelector("#txtDownWords"); @@ -911,6 +924,8 @@ if (window.top != window.self) { var tempSavebtn = txtDownContent.querySelector('#tempSaveTxt'); var abortbtn = txtDownContent.querySelector('#abortRequest'); var saveAsMd = txtDownContent.querySelector('#saveAsMd'); + var saveAsJSON = txtDownContent.querySelector('#saveAsJSON'); + tempSavebtn.onclick = function(){ saveContent(); console.log(curRequests); @@ -928,6 +943,28 @@ if (window.top != window.self) { var blob = new Blob([txt], {type: "text/plain;charset=utf-8"}); saveAs(blob, document.title.replace(/[\*\/:<>\?\\\|\r\n,]/g, "_") + ".md"); } + saveAsJSON.onclick = function(){ + let txt = []; + rCats.forEach(cat => { + let catArr = cat.split("\r\n", 3); + let saveUrl = GM_getValue("saveUrl"); + let catJson = { + title: catArr[0].trim(), + content: catArr[1].trim() + }; + if (saveUrl){ + catJson = { + title: catArr[0].trim(), + url: catArr[1].trim(), + content: catArr[2].trim() + }; + } + txt.push(catJson); + }); + txt = JSON.stringify(txt, null, 2); + var blob = new Blob([txt], {type: "text/plain;charset=utf-8"}); + saveAs(blob, document.title.replace(/[\*\/:<>\?\\\|\r\n,]/g, "_") + ".json"); + } } let charset = (document.characterSet || document.charset || document.inputEncoding); @@ -1330,7 +1367,12 @@ if (window.top != window.self) { var waitForComplete; function processDoc(i, aTag, doc, cause, check){ let cbFunc=content=>{ - rCats[i]=(aTag.innerText.replace(/[\r\n\t]/g, "") + "\r\n" + (cause || '') + content.replace(/\s*$/, "")); + let isHref = ""; + let saveUrl = GM_getValue("saveUrl"); + if (saveUrl){ + isHref = aTag.href + '\r\n'; + } + rCats[i]=(aTag.innerText.replace(/[\r\n\t]/g, "") + "\r\n" + isHref + (cause || '') + content.replace(/\s*$/, "")); curRequests = curRequests.filter(function(e){return e[0]!=i}); txtDownContent.style.display="block"; txtDownWords.innerHTML=getI18n("downloading",[downNum,(aEles.length-downNum),aTag.innerText]); @@ -1340,7 +1382,10 @@ if (window.top != window.self) { if(downNum==aEles.length){ txtDownWords.innerHTML=getI18n("complete",[downNum]); sortInnerPage(); - saveContent(); + var disableAutoStartSave = GM_getValue("disableAutoStartSave"); + if(!disableAutoStartSave){ + saveContent(); + } } },3000); } @@ -2118,6 +2163,8 @@ if (window.top != window.self) { let downThreadNum = createOption(i18n.downThreadNum, GM_getValue("downThreadNum") || "20", "number"); let maxDlPerMin = createOption(i18n.maxDlPerMin, GM_getValue("maxDlPerMin") || "0", "number"); let customTitle = createOption(i18n.customTitle, GM_getValue("customTitle") || ""); + let saveUrl = createOption(i18n.saveUrl, !!GM_getValue("saveUrl"), "checkbox"); + let disableAutoStartSave = createOption(i18n.disableAutoStartSave, !!GM_getValue("disableAutoStartSave"), "checkbox"); customTitle.setAttribute("placeHolder", "title"); let minTxtLength = createOption(i18n.minTxtLength, GM_getValue("minTxtLength") || "100", "number"); let contentSortUrlValue = GM_getValue("contentSortUrl") || false; @@ -2152,6 +2199,8 @@ if (window.top != window.self) { GM_setValue("maxDlPerMin", parseInt(maxDlPerMin.value || 20)); GM_setValue("minTxtLength", parseInt(minTxtLength.value || 100)); GM_setValue("customTitle", customTitle.value || ""); + GM_setValue("disableAutoStartSave", disableAutoStartSave.checked); + GM_setValue("saveUrl", saveUrl.checked); if (reSortUrl.checked) { GM_setValue("contentSortUrl", true); GM_setValue("contentSort", false); From f485cc1cee54f2fe8ac52f12a4ebc811ac45f850 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 2 Jan 2025 20:04:56 +0800 Subject: [PATCH 0625/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index be6ebbc55f2..af18cb39c6a 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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.12.7.1 +// @version 2025.1.2.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -12247,6 +12247,7 @@ ImgOps | https://imgops.com/#b#`; let blob = d.response; if (!blob.type) return urlToBlob(url, cb, forcePng, tryTimes); let ext = blob.type.replace(/.*image\/([\w\-]+).*/, "$1"); + if (ext === "text/html" && (blob.size || 0) < 1000) return cb(null, ''); let conversion = formatDict.get(ext); if (canvas && (conversion || forcePng)) { var self = this; @@ -16620,6 +16621,7 @@ ImgOps | https://imgops.com/#b#`; }; self.imgNaturalSize=imgNaturalSize; + self.eleMaps['head-left-img-info-resolution'].textContent=imgNaturalSize.w + ' x ' + imgNaturalSize.h; dataset(relatedThumb,'naturalSize',JSON.stringify(imgNaturalSize)); let key = imgNaturalSize.w + "x" + imgNaturalSize.h; self.sizeMap[key] = (self.sizeMap[key] || 0) + 1; @@ -18453,6 +18455,7 @@ ImgOps | https://imgops.com/#b#`; }\ .pv-gallery-range-box>#pinSize{\ margin: 0 5px;\ + padding: 0px;\ }\ .pv-gallery-range-box>span{\ padding: 0 5px 0 5px;\ From 99e5f08b3eb3eb5cba6df1e6a7a9abc268ebb1fb Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 5 Jan 2025 07:59:42 +0000 Subject: [PATCH 0626/1065] Update version of Pagetual rules to 82 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index d88e3136998..dde92ddc1a5 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -81 +82 From eefd6fcb2d44ba7c189e65f48e1ece6e03cb52e0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 5 Jan 2025 15:59:46 +0800 Subject: [PATCH 0627/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 83557752534..f324c31e4d6 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5539,7 +5539,7 @@ "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('main')//style|//head//style", + "pageElement": "id('rso')|id('center_col')/style[contains(.,'relative')][id('rso')]", "action": 1, "pageNum": "&start={10*($p-1)}", "pageBarTop": 55, From bee53607532bfe9f778ab1e6fd6d5cbf1fa73f45 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 5 Jan 2025 16:05:11 +0800 Subject: [PATCH 0628/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index f324c31e4d6..9726fff6d13 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5539,7 +5539,7 @@ "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')]", + "pageElement": "id('rso')|id('center_col')/style[contains(.,'relative')]", "action": 1, "pageNum": "&start={10*($p-1)}", "pageBarTop": 55, From 046e31eed77e7132736f6c6c2e7c671141822dea Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 5 Jan 2025 08:08:36 +0000 Subject: [PATCH 0629/1065] Update version of Pagetual rules to 83 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index dde92ddc1a5..76a8b2b7030 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -82 +83 From 33819ea5e9e22fbc968d6795809e411124ad5fa9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 5 Jan 2025 17:08:20 +0800 Subject: [PATCH 0630/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index f03b486d75a..971596841ab 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -1477,7 +1477,7 @@ const prevReg = new RegExp("\u005e\u005c\u0073\u002a\u0028\u005b\u4e0a\u524d\u9996\u5c3e\u005d\u007c\u0070\u0072\u0065\u0076\u0069\u006f\u0075\u0073\u007c\u0065\u006e\u0064\u0029", "i"); const lazyImgAttr = ["data-lazy-src", "data-s", "data-lazy", "data-isrc", "data-url", "data-orig-file", "zoomfile", "file", "original", "load-src", "imgsrc", "real_src", "src2", "origin-src", "data-lazyload", "data-lazyload-src", "data-lazy-load-src", "data-ks-lazyload", "data-ks-lazyload-custom", "data-src", "data-defer-src", "data-actualsrc", "data-cover", "data-original", "data-thumb", "data-imageurl", "data-placeholder", "lazysrc"]; var rulesData = {uninited: true, firstRun: true, sideController: !isMobile}, ruleUrls, updateDate, loadNowNum = 5, autoScrollRate = 50; - var isPause = false, manualPause = false, isHideBar = false, isLoading = false, curPage = 1, forceState = 0, autoScroll = 0, autoScrollInterval, bottomGap = 1000, autoLoadNum = -1, nextIndex = 0, stopScroll = false, clickMode = false, openInNewTab = 0, charset = "UTF-8", charsetValid = true, urlWillChange = false, hidePageBar = false; + var isPause = false, manualPause = false, isHideBar = false, isLoading = false, curPage = 1, forceState = 0, autoScroll = 0, autoScrollInterval, bottomGap = 1000, autoLoadNum = -1, initAutoLoadNum = 0, nextIndex = 0, stopScroll = false, clickMode = false, openInNewTab = 0, charset = "UTF-8", charsetValid = true, urlWillChange = false, hidePageBar = false; var tryTimes = 0, showedLastPageTips = false, rate = 1, author = ''; function getBody(doc) { @@ -4847,6 +4847,7 @@ }, true); loadNow.addEventListener("click", e => { + initAutoLoadNum = 0; if (autoLoadNum != -1) { autoLoadNum = -1; return; @@ -5174,6 +5175,7 @@ ruleParser.curUrl += "#pagetual"; ruleParser.oldUrl = ruleParser.curUrl; autoLoadNum = -1; + initAutoLoadNum = 0; if (!ruleParser.nextLinkHref) { isLoading = false; } @@ -5716,6 +5718,7 @@ let loadNum = window.prompt(i18n("loadConfirm"), "1"); if (loadNum === "" || loadNum === null) return; autoLoadNum = Math.abs(parseInt(loadNum)); + initAutoLoadNum = 0; nextPage(); }, true); closeBtn.addEventListener("click", e => { @@ -7527,6 +7530,7 @@ rate = rulesData.rate; if (rulesData.autoLoadNum && rulesData.initRun) { autoLoadNum = parseInt(rulesData.autoLoadNum); + initAutoLoadNum = autoLoadNum; } openInNewTab = rulesData.openInNewTab ? 1 : 0; enableDebug = rulesData.enableDebug; @@ -7807,6 +7811,7 @@ ruleParser.initPage(() => { if (ruleParser.curSiteRule.autoLoadNum) { autoLoadNum = ruleParser.curSiteRule.autoLoadNum; + initAutoLoadNum = autoLoadNum; } if (ruleParser.curSiteRule.nextLink && Array && Array.isArray && Array.isArray(ruleParser.curSiteRule.nextLink)) { _GM_registerMenuCommand(i18n("nextSwitch"), () => { @@ -7831,6 +7836,7 @@ }); } _GM_registerMenuCommand(i18n("loadNow"), () => { + initAutoLoadNum = 0; if (autoLoadNum != -1) { autoLoadNum = -1; return; @@ -8356,6 +8362,7 @@ loadNowNum = detail; } autoLoadNum = detail; + initAutoLoadNum = 0; nextPage(); break; case "loadMore": @@ -10029,7 +10036,7 @@ function checkAutoLoadNum() { if (autoLoadNum >= 0) { if (autoLoadNum !== 0 && --autoLoadNum === 0) { - autoLoadNum = -1; + autoLoadNum = initAutoLoadNum || -1; } else { setTimeout(() => nextPage(), 1); } From 662af3199eb8f6d6478348383849ef3f4cd01b70 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 7 Jan 2025 15:18:37 +0800 Subject: [PATCH 0631/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 9726fff6d13..c549f0c479b 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5879,7 +5879,7 @@ "//*[@id=\"page\"]/div/a[contains(text(),'下')]", "//*[@id=\"page\"]/div/a[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, From a33c3761f962f7e628b1de4c0c39f1fdbe5cec8f Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 7 Jan 2025 07:19:21 +0000 Subject: [PATCH 0632/1065] Update version of Pagetual rules to 84 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 76a8b2b7030..871727de1fd 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -83 +84 From 68c2a682f3256a4abe1d622b9e0a1b4c2e7deb4c Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 18 Jan 2025 09:03:47 +0800 Subject: [PATCH 0633/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 971596841ab..433f16c1ec4 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2366,7 +2366,7 @@ let paStyle = curWin.getComputedStyle(ele.parentNode); let paDisplay = paStyle.display; let paOverflow = paStyle.overflow; - pf = (paDisplay.indexOf('flex') !== -1 && paStyle.flexDirection.indexOf("row") === 0 && paStyle.flexWrap !== "wrap") || compareNodeName(ele.parentNode, ["ul"]) || paDisplay.indexOf('grid') !== -1 || paOverflow === "hidden"; + pf = (paDisplay.indexOf('flex') !== -1 && paStyle.flexDirection.indexOf("row") === 0 && paStyle.flexWrap !== "wrap") || compareNodeName(ele.parentNode, ["ul", "td"]) || paDisplay.indexOf('grid') !== -1 || paOverflow === "hidden"; } let curStyle = curWin.getComputedStyle(ele); if (ele.children.length > 1) { From cdbf822c2280fce65e8ebb8c62aeec34a78898aa Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 24 Jan 2025 19:02:22 +0800 Subject: [PATCH 0634/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index af18cb39c6a..0793134d7b1 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.1.2.1 +// @version 2025.1.24.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -21127,7 +21127,7 @@ ImgOps | https://imgops.com/#b#`; .compare>.pv-pic-search-state{\ display: none;\ }\ - .pv-pic-window-container_focus:not(.preview)>.pv-pic-search-state {\ + .pv-pic-window-container_focus>.pv-pic-search-state,.preview>.pv-pic-search-state {\ opacity:0.8;\ }\ .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-imgbox{\ @@ -21182,7 +21182,7 @@ ImgOps | https://imgops.com/#b#`; color: #ffff00;\ height: 18px;\ line-height: 18px;\ - opacity:0.8;\ + opacity:0;\ transition: all 0.3s ease;\ user-select: none;\ -webkit-box-sizing: content-box;\ From 714335856c22a3e3ce71e1bdde99b10c0ec62d0b Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 4 Feb 2025 11:36:19 +0800 Subject: [PATCH 0635/1065] 1.9.37.117 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 53c49120d56..f3c38c02389 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.116](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.117](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 433f16c1ec4..424a24d45ad 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.116 +// @version 1.9.37.117 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -2208,7 +2208,7 @@ if (!this.hpRules) this.hpRules = []; let url = this.curSiteRule && this.curSiteRule.url, self = this; let href = location.href.slice(0, 500); - let matchedRules = this.hpRules.filter(rule => rule != self.curSiteRule && new RegExp(rule.url, "i").test(href) && self.ruleMatch(rule)); + let matchedRules = this.hpRules.filter(rule => JSON.stringify(rule) != JSON.stringify(self.curSiteRule) && new RegExp(rule.url, "i").test(href) && self.ruleMatch(rule)); if (url) matchedRules.unshift(this.curSiteRule); matchedRules.sort((a, b) => { if ((a.include || a.exclude) && (!b.include && !b.exclude)) { @@ -4295,18 +4295,20 @@ self.curSiteRule.pageNum = null; } } - if (self.curSiteRule.smart && self.nextLinkHref == false && self.possibleRule) { + if (self.curSiteRule.smart && self.possibleRule) { let urlReg = new RegExp(self.possibleRule.url, "i"); + let href = location.href.slice(0, 500); function checkPossible () { if (self.possibleCheck++ < 3) { - setTimeout(() => { - if (self.curSiteRule.smart) { - var href = location.href.slice(0, 500); - if (urlReg.test(href) && self.ruleMatch(self.possibleRule)) { - self.initPage(() => {}); - } else checkPossible(); + if (self.curSiteRule.smart) { + if (urlReg.test(href) && self.ruleMatch(self.possibleRule)) { + self.initPage(() => {}); + } else { + setTimeout(() => { + checkPossible(); + }, 3000); } - }, 3000); + } } } checkPossible(); From 0398e3bff235b870b2371a68318ba9616711e1ab Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 5 Feb 2025 16:45:03 +0800 Subject: [PATCH 0636/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 424a24d45ad..911f9198fec 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -4666,6 +4666,7 @@ .pagetual-sideController-btn { padding: 5px 0; cursor: pointer; + height: 35px; transition: transform .15s ease-in-out, opacity .3s ease; } #pagetual-sideController .pagetual-sideController-btn:hover { @@ -5255,6 +5256,8 @@ line-height: unset; min-width: unset; min-height: unset; + height: auto; + width: auto; } #pagetual-picker>.title { max-width: 100%; @@ -8067,7 +8070,7 @@ 100% { opacity: 1 } } `; - pageBarStyle = `overflow: visible;text-indent: initial;vertical-align: super;line-height:1;opacity:${rulesData.opacity};display:${rulesData.opacity == 0 ? "none" : "inline-flex"};padding:0;font-size: 30px;visibility: visible; position: relative; width: auto; max-width: 100vw; height: 30px; float: none; clear: both; margin: 5px auto; text-align: center;justify-content: center;box-sizing: content-box;${rulesData.opacity == 1 ? "border-top: 1px solid rgb(80, 80, 80);" : "box-shadow: 0px 0px 10px 0px #000000aa;border-radius: 20px;background-color: rgb(240 240 240 / 80%);"}`; + pageBarStyle = `z-index: 9;overflow: visible;text-indent: initial;vertical-align: super;line-height:1;opacity:${rulesData.opacity};display:${rulesData.opacity == 0 ? "none" : "inline-flex"};padding:0;font-size: 30px;visibility: visible; position: relative; width: auto; max-width: 100vw; height: 30px; float: none; clear: both; margin: 5px auto; text-align: center;justify-content: center;box-sizing: content-box;${rulesData.opacity == 1 ? "border-top: 1px solid rgb(80, 80, 80);" : "box-shadow: 0px 0px 10px 0px #000000aa;border-radius: 20px;background-color: rgb(240 240 240 / 80%);"}`; } if (!mainStyleEle || !mainStyleEle.parentNode) { mainStyleEle = _GM_addStyle(mainStyleStyle); From 307f7039ac138608bb3ecf79bd537e0bffc23456 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 5 Feb 2025 21:39:59 +0800 Subject: [PATCH 0637/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 911f9198fec..4b4770cb008 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -4667,6 +4667,7 @@ padding: 5px 0; cursor: pointer; height: 35px; + box-sizing: border-box; transition: transform .15s ease-in-out, opacity .3s ease; } #pagetual-sideController .pagetual-sideController-btn:hover { From ba81c4d5c7291400dc2dfc0729c56982a07a8746 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 20 Feb 2025 08:34:15 +0800 Subject: [PATCH 0638/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index c549f0c479b..0bdce1c2539 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -1916,7 +1916,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", @@ -5847,7 +5847,7 @@ "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全部商品页", From 74f5eef4f76797c692911d0a4f6ecac314f504c9 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 20 Feb 2025 00:34:20 +0000 Subject: [PATCH 0639/1065] Update version of Pagetual rules to 85 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 871727de1fd..a862eb8444d 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -84 +85 From c0ada4b336516343bcd440556d2100cd7b355fe7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Feb 2025 10:43:00 +0800 Subject: [PATCH 0640/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index cb3b58aed54..b45eeea0453 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -751,7 +751,7 @@ var siteInfo = [ if (a && a.href && /\/\/v.redd\.it\/\w+\/?$/.test(a.href)) { return a.href + '/DASHPlaylist.mpd'; } else if (a && a.href && /^https:\/\/www\.reddit\.com\/gallery\//.test(a.href)) { - return a.href; + return a.href.replace(/.*(reddit\.com\/)gallery\/([\da-z]+).*/, "https://www.$1by_id/t3_$2.json"); } else if (a && a.href && /redgifs\.com\//.test(a.href)) { const apiUrl = 'https://api.redgifs.com/v2'; if (!self.redgifsToken) { @@ -791,10 +791,20 @@ var siteInfo = [ if (data && data.gif) { return data.gif.urls.gif || data.gif.urls.hd; } - } else if (/^https:\/\/www\.reddit\.com\/gallery\//.test(url)) { - return [].reduce.call(doc.querySelectorAll("figure>a"), (total, cur) => { - return total.concat(cur.href); - }, []); + } else if (/\/by_id\//.test(url)) { + let data; + try { + data = JSON.parse(html).data.children[0].data; + } catch (e) { + return; + } + return (data.gallery_data && data.gallery_data.items || []).map(function(c, i) { + var u=data.media_metadata[c.media_id].s + return [ + (u.u ? u.u.replace(/preview(\.redd.it\/[^?]+).*/, 'i$1') : (u.mp4 ? u.mp4 + '#mp4' : u.gif)), + (!i ? '[' + new Date(data.created_utc*1e3).toLocaleString() + ' | ' + data.title + '] ' : '') + (c.caption || '') + ] + }) } var xmlDoc = (new DOMParser()).parseFromString(html, 'application/xml'); var highestRes = [].slice.call(xmlDoc.querySelectorAll('Representation[frameRate]')) From 0bc497cae43e001021df1891c90a3da30bba3e4d Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 21 Feb 2025 10:44:09 +0800 Subject: [PATCH 0641/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 0793134d7b1..5d3f2e656d6 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.1.24.1 +// @version 2025.2.21.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1492792/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1540697/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From 1380d1fffcb4df2c44a1fc45e874b7ae1ead8bd9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 23 Feb 2025 08:43:51 +0800 Subject: [PATCH 0642/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 5d3f2e656d6..9808974fc57 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.2.21.1 +// @version 2025.2.23.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -22997,6 +22997,8 @@ ImgOps | https://imgops.com/#b#`; self.data.all = imgSrcs; if (caption) self.data.description = caption; self.loadImg(imgSrc, imgSrcs); + } else if (self.data.imgSrc) { + self.loadImg(self.data.imgSrc, imgSrcs); } else { self.error(); } From 33b981a689d06575de05f87539e5c3a5e133fb84 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 24 Feb 2025 11:03:00 +0800 Subject: [PATCH 0643/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 4b4770cb008..61e70f40fcf 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2996,6 +2996,7 @@ ".nextPage", ".pagination-next>a", ".pagination>.active+a", + ".pagination>[class*=link_sel]+a", "a[data-pagination=next]", ".pageButtonsCurrent+a", "a[class*=nextpage]", From fa4e6769c84afe5b1ed182434fd27022687c923c Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 24 Feb 2025 12:43:15 +0800 Subject: [PATCH 0644/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 61e70f40fcf..fdc0a9e1e1a 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2996,7 +2996,7 @@ ".nextPage", ".pagination-next>a", ".pagination>.active+a", - ".pagination>[class*=link_sel]+a", + ".pagination>[class*=sel]+a", "a[data-pagination=next]", ".pageButtonsCurrent+a", "a[class*=nextpage]", From b3b3157aabc58b7f64ad14d15a688b3469aeac14 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 24 Feb 2025 16:34:01 +0800 Subject: [PATCH 0645/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index f0d233a5336..c047b000902 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -119,7 +119,10 @@ return; } let link = item.querySelector("a[href*='www.baidu.com/link']"); - if (link) link.href = mu; + if (link) { + link.href = mu; + item.setAttribute("mu", ""); + } } } let s = item.getAttribute("style"); From 9ef50eec147c963e071ec611083a0b6662bc0fab Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 25 Feb 2025 15:13:27 +0800 Subject: [PATCH 0646/1065] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fe1ef233350..884aa2ccfef 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ ## Contributors - + ## Star History From c26e1c59ed729771dc0407e75c35ffaeec35c34e Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 26 Feb 2025 18:16:43 +0800 Subject: [PATCH 0647/1065] Update DownloadAllContent.user.js --- DownloadAllContent/DownloadAllContent.user.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index d9af96e37e9..7c4c412991a 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -4,7 +4,7 @@ // @name:zh-TW 怠惰小説下載器 // @name:ja 怠惰者小説ダウンロードツール // @namespace hoothin -// @version 2.8.3.15 +// @version 2.8.3.16 // @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文檔 @@ -1019,8 +1019,7 @@ if (window.top != window.self) { console.warn(e); } } - var linkIndex = 1; - function packLink(doc, item) { + function packLink(doc, item, curIndex) { if (customTitle) { try { let title = doc.querySelector(customTitle); @@ -1032,8 +1031,7 @@ if (window.top != window.self) { } } if (prefix) { - item.innerText = prefix.replace(/\$i/g, linkIndex) + item.innerText; - linkIndex++; + item.innerText = prefix.replace(/\$i/g, ++curIndex) + item.innerText; } } var insertSigns=[]; @@ -1137,7 +1135,7 @@ if (window.top != window.self) { } else { console.log(result.status); } - packLink(doc, aTag); + packLink(doc, aTag, curIndex); let validData = processDoc(curIndex, aTag, doc, (result.status>=400?` status: ${result.status} from: ${aTag.href} `:""), validTimes < 5); if (!validData && validTimes++ < 5) { downIndex--; @@ -1264,7 +1262,7 @@ if (window.top != window.self) { } }); } - packLink(doc, aTag); + packLink(doc, aTag, curIndex); downIndex++; downNum++; let validData = processDoc(curIndex, aTag, doc, "", failedTimes < 2); @@ -1612,7 +1610,7 @@ if (window.top != window.self) { } getContentByLargest(); if (rStr.length < 100) { - let articles = pageData.querySelectorAll("article"); + let articles = pageData.querySelectorAll("article,.content,#content"); if (articles && articles.length == 1) { largestContent = articles[0]; largestNum = largestContent.innerText.length; From f9f4633a7c6f6d2c842e05071b5cd4540af5a8be Mon Sep 17 00:00:00 2001 From: Lemonade <61580921+lemonadeforlife@users.noreply.github.com> Date: Wed, 12 Mar 2025 10:46:45 +0000 Subject: [PATCH 0648/1065] Enhance rule to support entire MAL site Previously it only support search only anime or manga pics. Now it will support whole site. --- Picviewer CE+/pvcep_rules.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index b45eeea0453..46ae8b27fdc 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1693,10 +1693,9 @@ var siteInfo = [ } }, { - name: "MAL Anime/Manga Search", - url: /^https:\/\/myanimelist\.net\/(anime|manga)\.php\?cat=(anime|manga).+/, + name: "MAL Anime/Manga", src: /^https:\/\/cdn\.myanimelist\.net/, - r: /\/r\/(\d+x\d+)(\/images\/(anime|manga)\/\d+\/\d+)\.(webp|jpg).+/, + r: /(\/r\/\d+x\d+)?(\/images\/(anime|manga)\/\d+\/\d+)\.(webp|jpg).+/, s: "$2l.jpg" }, { From 9c913ba4d494089a4da92f0b737f72e283bd8c94 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 16 Mar 2025 09:30:28 +0800 Subject: [PATCH 0649/1065] Update DownloadAllContent.user.js --- DownloadAllContent/DownloadAllContent.user.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index 7c4c412991a..3024f4af863 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -4,7 +4,7 @@ // @name:zh-TW 怠惰小説下載器 // @name:ja 怠惰者小説ダウンロードツール // @namespace hoothin -// @version 2.8.3.16 +// @version 2.8.3.17 // @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文檔 @@ -1135,7 +1135,6 @@ if (window.top != window.self) { } else { console.log(result.status); } - packLink(doc, aTag, curIndex); let validData = processDoc(curIndex, aTag, doc, (result.status>=400?` status: ${result.status} from: ${aTag.href} `:""), validTimes < 5); if (!validData && validTimes++ < 5) { downIndex--; @@ -1262,7 +1261,6 @@ if (window.top != window.self) { } }); } - packLink(doc, aTag, curIndex); downIndex++; downNum++; let validData = processDoc(curIndex, aTag, doc, "", failedTimes < 2); @@ -1365,6 +1363,7 @@ if (window.top != window.self) { var waitForComplete; function processDoc(i, aTag, doc, cause, check){ let cbFunc=content=>{ + packLink(doc, aTag, i); let isHref = ""; let saveUrl = GM_getValue("saveUrl"); if (saveUrl){ From 69ce0dcf6762b750079b9e5a8caa65e6b43936b9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 16 Mar 2025 09:36:35 +0800 Subject: [PATCH 0650/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 9808974fc57..8ea15d20ea0 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.2.23.1 +// @version 2025.3.16.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1540697/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1552062/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From aedd5b1a0974f2fbbd48911fb8b0c61ea80c5431 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 16 Mar 2025 18:21:27 +0800 Subject: [PATCH 0651/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index fdc0a9e1e1a..a2c36c59a12 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.117 +// @version 1.9.37.118 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -4659,6 +4659,7 @@ line-height: normal; float: none; text-align: center; + font-feature-settings: normal; } #pagetual-sideController.stop { -webkit-filter: invert(100%); @@ -5345,6 +5346,7 @@ appearance: auto; display: inline-block; position: initial; + box-shadow: none; } #pagetual-picker [type=checkbox]:after, #pagetual-picker [type=radio]:after, @@ -5908,7 +5910,7 @@ } } else if (this.foundEle.length <= 3) { let foundEleRect = this.foundEle[0].getBoundingClientRect(); - if (foundEleRect.height < 30) { + if (foundEleRect.height < 50) { showTips("Next Link", "", 500); this.editTemp.nextLink = this.selectorInput.value; return this.editTemp; From e98da7aac1e7639ebb3da98898b72aab1bb7d291 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 17 Mar 2025 08:11:20 +0800 Subject: [PATCH 0652/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index a2c36c59a12..4ecebec232b 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3112,11 +3112,17 @@ await sleep(1); let pageDiv = body.querySelector(".pagination,.pagination-list"); if (pageDiv) { - cur = pageDiv.querySelector("[class*=current],.page-selected"); + cur = pageDiv.querySelector("[class*=current],.page-selected,[aria-current]"); if (cur) { - next = cur.parentNode.nextElementSibling; - if (next && next.nodeName === cur.parentNode.nodeName) next = next.querySelector("a"); - else next = null; + if (cur.parentNode == pageDiv) { + next = cur.nextElementSibling; + if (next && next.nodeName === cur.nodeName) next = next.nodeName == "A" ? next : next.querySelector("a"); + else next = null; + } else { + next = cur.parentNode.nextElementSibling; + if (next && next.nodeName === cur.parentNode.nodeName) next = next.querySelector("a"); + else next = null; + } } else { if (!pageDiv.querySelector("a")) { cur = pageDiv.querySelector("[class*=current],[class*=active]"); From c3e703c5e3ec89a715cb86c4a555a782380cc6cb Mon Sep 17 00:00:00 2001 From: skofkyo Date: Sat, 22 Mar 2025 00:01:06 +0800 Subject: [PATCH 0653/1065] Update pagetualRules.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新部分失效規則 刪除失效規則 --- Pagetual/pagetualRules.json | 1292 +++-------------------------------- 1 file changed, 80 insertions(+), 1212 deletions(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 0bdce1c2539..14101498c04 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -135,53 +135,6 @@ "pinUrl": true, "enable": 0 }, -{ - "name": "仙漫网 - 手機版閱讀", - "author": "skofkyo", - "example": "https://m.gaonaojin.com/kaijujiuwudi/0.html", - "url": "^https?://m\\.gaonaojin\\.com/\\w+/\\d+\\.html", - "init": "let hasTouchEvents=()=>{if(('ontouchstart'in window)||(navigator.maxTouchPoints>0)||(navigator.msMaxTouchPoints>0)){return true}return false};if(hasTouchEvents()===false){let style=document.createElement('style');style.id='PagetualStyle';style.innerHTML='#cp_img>img{width:auto!important;height:auto!important;max-width:100%!important;display:block!important;margin:0 auto !important}';document.head.appendChild(style)}let code=Array.from(document.scripts).find(s=>s.innerHTML.search(/eval/)>-1).innerHTML.match(/eval.+\\)\\)/)[0].slice(4);let imgData=eval(eval(code).match(/picdata[^;]+/)[0]);let F=new DocumentFragment();imgData.forEach(e=>{let img=new Image();img.src='https://res.xiaoqinre.com/'+e;F.appendChild(img)});let E=document.querySelector('#cp_img');E.innerHTML='';E.appendChild(F);", - "nextLink": "a.next[href$=html]", - "pageElement": "#cp_img", - "replaceElement": "head>title,#title[style*='30'],.btn.prev,.btn.next", - "pageInit": "let code=Array.from(doc.scripts).find(s=>s.innerHTML.search(/eval/)>-1).innerHTML.match(/eval.+\\)\\)/)[0].slice(4);let imgData=eval(eval(code).match(/picdata[^;]+/)[0]);let F=new DocumentFragment();imgData.forEach(e=>{let img=new Image();img.src='https://res.xiaoqinre.com/'+e;F.appendChild(img)});let E=doc.querySelector('#cp_img');E.innerHTML='';E.appendChild(F);", - "pageAction": "let gae=e=>document.querySelectorAll(e);let c=gae('#cp_img');if(c.length>10){c[0].remove()}let p=gae('.pagetual_pageBar');if(p.length>10){p[0].remove()}", - "preloadImages": "document.querySelector('#pagetual-preload').innerHTML='';let code=Array.from(doc.scripts).find(s=>s.innerHTML.search(/eval/)>-1).innerHTML.match(/eval.+\\)\\)/)[0].slice(4);let imgData=eval(eval(code).match(/picdata[^;]+/)[0]);let imgSrcArr=[];imgData.forEach(e=>{let imgSrc='https://res.xiaoqinre.com/'+e;imgSrcArr.push(imgSrc)});return imgSrcArr", - "pageBarText": "let t=doc.querySelector(\"#title[style*='30']\");if(t)return t.innerText", - "rate": 2, - "css": "img[style*='18vh'],.dropload-down{display:none!important}.recommendList{display:block!important}" -}, -{ - "name": "仙漫网 - 閱讀", - "author": "skofkyo", - "example": "https://www.gaonaojin.com/kaijujiuwudi/0.html", - "url": "^https?://www\\.gaonaojin\\.com/\\w+/\\d+\\.html", - "init": "let ge=e=>document.querySelector(e);if(ge('img[src*=banquan]')){location.replace(location.href.replace('www','m'))}else{let code=Array.from(document.scripts).find(s=>s.innerHTML.search(/eval/)>-1).innerHTML.trim().slice(4);let imgData=eval(eval(code).match(/picdata[^;]+/)[0]);let F=new DocumentFragment();imgData.forEach(e=>{let img=new Image();img.src=imgDomain+e;F.appendChild(img)});let E=ge('.comiclist');E.innerHTML='';E.appendChild(F)}", - "nextLink": "//li[a[@class='active']]/preceding-sibling::li[1]/a", - "pageElement": ".comiclist", - "replaceElement": "head>title,h1.title", - "pageInit": "let code=Array.from(doc.scripts).find(s=>s.innerHTML.search(/eval/)>-1).innerHTML.trim().slice(4);let imgData=eval(eval(code).match(/picdata[^;]+/)[0]);let F=new DocumentFragment();imgData.forEach(e=>{let img=new Image();img.src=imgDomain+e;F.appendChild(img)});let E=doc.querySelector('.comiclist');E.innerHTML='';E.appendChild(F);", - "pageAction": "let gae=e=>document.querySelectorAll(e);let c=gae('.comiclist');if(c.length>10){c[0].remove()}let p=gae('.pagetual_pageBar');if(p.length>10){p[0].remove()}", - "preloadImages": "document.querySelector('#pagetual-preload').innerHTML='';let code=Array.from(doc.scripts).find(s=>s.innerHTML.search(/eval/)>-1).innerHTML.trim().slice(4);let imgData=eval(eval(code).match(/picdata[^;]+/)[0]);let imgSrcArr=[];imgData.forEach(e=>{let imgSrc=imgDomain+e;imgSrcArr.push(imgSrc)});return imgSrcArr", - "pageBarText": "let t=doc.querySelector('a.active');if(t)return t.innerText.match(/[^(]+/)[0].trim();", - "css": "h1.title>span{display:none!important}.comiclist>img{width:auto!important;height:auto!important;max-width:100%!important;display:block!important;margin:0 auto !important}" -}, -{ - "name": "漫画台 - 閱讀", - "author": "skofkyo", - "example": "http://manhuat.cc/manhua/3394/660348.html", - "url": "(www\\.)?manhuat\\.cc/manhua/\\d+/\\d+\\.html", - "include": "//script[contains(text(),'imgs')]", - "init": "let ge=e=>document.querySelector(e);let E=ge('#contents');E.innerHTML=imgs.join('');", - "nextLink": "a[rel=next][href$=html],#next_url", - "pageElement": "#contents", - "replaceElement": "head>title,.con_top,.bottem1,.bottem2", - "pageInit": "let code=Array.from(doc.scripts).find(s=>s.innerHTML.search(/imgs/)>-1).innerHTML;let imgData=eval(code.match(/imgs[^;]+/)[0]);let E=doc.querySelector('#contents');E.innerHTML=imgData.join('');", - "pageAction": "let gae=e=>document.querySelectorAll(e);let c=gae('#contents');if(c.length>10){c[0].remove()}let p=gae('.pagetual_pageBar');if(p.length>10){p[0].remove()}", - "preloadImages": "document.querySelector('#pagetual-preload').innerHTML='';let code=Array.from(doc.scripts).find(s=>s.innerHTML.search(/imgs/)>-1).innerHTML;let imgData=eval(code.match(/imgs[^;]+/)[0]);let imgSrcArr=[];imgData.forEach(e=>{let imgSrc=e.match(/http[^\"]+/)[0];imgSrcArr.push(imgSrc)});return imgSrcArr", - "pageBarText": "let t=doc.querySelector('.bookname,.reader-main>h1');if(t)return t.innerText.match(/[^(]+/)[0].trim();", - "css": ".box_con #content{font-size:0!important}.bookname,.imgpage,.imgpage2,h3,.readtj{display:none!important}" -}, { "name": "開車漫画 - 閱讀", "author": "skofkyo", @@ -233,13 +186,6 @@ "pageElement": "//dt[div[@class='img']/a/img[@alt]]", "replaceElement": ".mypage" }, -{ - "name": "嗨皮漫畫 - 更新頁", - "author": "skofkyo", - "example": "https://m.happymh.com/latest", - "url": "^https?://m\\.happymh\\.com/latest$", - "loadMore": ".more-div-btn" -}, { "name": "嗨皮漫畫 - 閱讀 - 禁用", "author": "skofkyo", @@ -555,104 +501,57 @@ "pageElement": ".box-body", "replaceElement": ".page-pagination" }, -{ - "name": "無限動漫手機版 - 漫畫閱讀", - "author": "skofkyo", - "example": "https://8.twobili.com/comic/insurance_15059.html?ch=1", - "url": "^https?://8\\.twobili\\.com/comic/insurance", - "action": 1, - "wait": "if(!!doc.querySelector('#TheImg')){let frameCode=`let imgs=[];for(let i=1;i<=ps;i++){let src='https://img'+ss(c,4,2)+'.8comic.com/'+ss(c,6,1)+'/'+ti+'/'+ss(c,0,4)+'/'+nn([i])+'_'+ss(c,mm([i])+10,3,f)+'.jpg';let img=new Image();img.id='TheImg';img.src=src;imgs.push(img)}window.newImgs=imgs;`;let s=doc.createElement('script');s.textContent=frameCode;doc.body.appendChild(s);return true}else{return false}", - "init": "let _ge=e=>document.querySelector(e);let textNode=_ge('.book_inc_title')?.nextSibling;if(textNode?.nodeName=='#text'&&textNode?.textContent?.indexOf('alert')>-1){textNode.remove()}_ge('#pageindex').parentNode.appendChild(_ge('#prevvol').cloneNode(true));_ge('#pageindex').parentNode.appendChild(_ge('#nextvol').cloneNode(true));let ul=_ge('#TheTable>ul');let v1=_ge('.view_tmenu').cloneNode(true);let v2=[...document.querySelectorAll('.view_menut')][1];ul.appendChild(v2);ul.appendChild(v1);let b1=_ge('.book_inc_title');let b2=_ge('.book_link_item');ul.appendChild(b1);if(b2)ul.appendChild(b2);let E=_ge('#TheImg').parentNode;E.innerHTML='';E.append(...newImgs);", - "nextLinkByJs": "let next=doc.querySelector('#nextvol:not([style])');if(!!next){let{replaceurl,ni}=doc.defaultView;return replaceurl('ch',ni)}else{return null}", - "pageElement": "//script[contains(text(),'userAgent')]", - "insert": "//li[img[@id='TheImg']]", - "insertPos": "in", - "pageAction": "let E=document.querySelector('#TheImg').parentNode;E.append(...doc.defaultView.newImgs);ch=doc.defaultView.ch;", - "css": ".pinch-zoom-container{height:auto !important;display:contents !important}.view_tmenu+div[style],#pagenum,[onclick^='j'],#pageindex,ico+a+.material-icons.right-logo,.cd-popup,.ls-link-div{display:none !important}.view_menut a{width:33.3% !important;max-width:33.3% !important}" -}, -{ - "name": "無限動漫手機版 - 分類", - "author": "skofkyo", - "example": "https://m.comicbus.com/category/update_comic-1.html", - "url": "^https?://m\\.comicbus\\.com/category/", - "nextLink": "//a[span/@class='mdi mdi-skip-next mdi-next-btn']", - "pageElement": "#list_dl", - "replaceElement": ".pager", - "css": ".pagetual_pageBar{margin-top:-1px!important;margin-bottom:5px!important}" -}, -{ - "name": "無限動漫 - 漫畫閱讀", - "author": "skofkyo", - "example": "https://www.comicabc.com/online/new-18722.html?ch=26", - "url": "^https?://(a|www)\\.(comicabc|twobili)\\.com/(ReadComic|online)", - "pinUrl": true, - "action": 1, - "wait": "if(!![...doc.scripts].find(s=>s.textContent.includes('ge(e)'))){let frameCode=`let code=[...document.scripts].find(s=>s.innerHTML.includes('ge(e)')).innerHTML;let[,keyCode]=code.match(/ge\\\\([^.]+\\\\.src\\\\s?=\\\\s?([^;]+)/);let imgs=[];for(let i=1;i<=ps;i++){let code=keyCode.replace(/\\\\(pp?\\\\)/g,'('+i+')');let src=eval(code);let img=new Image();img.id='TheImg';img.src=src;imgs.push(img)}window.newImgs=imgs;`;let s=doc.createElement('script');s.textContent=frameCode;doc.body.appendChild(s);return true}else{return false}", - "init": "let E=document.querySelector('#TheImg').parentNode;E.innerHTML='';E.append(...newImgs);", - "nextLinkByJs": "let{rp,ni,fz,reurl}=doc.defaultView;let next=doc.querySelector('#nextvol:not([style])');if(next&&/ReadComic/.test(location.pathname)){return rp+ni+'/'+ni+(fz+fz).substr((3*ni)%fz.length,10)+'.html'}else if(next){return reurl('ch',ni)}else{return null}", - "pageElement": "//script[contains(text(),'ge(e)')]", - "insert": "//td[img[@id='TheImg']]", - "insertPos": "in", - "pageAction": "let E=document.querySelector('#TheImg').parentNode;E.append(...doc.defaultView.newImgs);", - "css": "#TheImg{max-width: 100% !important;display: block !important;margin: 0 auto !important;}#TheTable td:nth-child(1),#TheTable td:nth-child(3),.comment_block,#prevnext2,#prev,#next{display:none!important}" -}, { "name": "無限動漫 - 動漫大全", "author": "skofkyo", - "example": "https://www.comicabc.com/list/all_all_all/", - "url": "^https?://www\\.comicabc\\.com/list/", + "example": "https://www.8comic.com/list/all_all_all/", + "url": "^https?://www\\.8comic\\.com/list/", "nextLink": "//a[span/@class='mdi mdi-skip-next']", - "pageElement": ".default_row_width .row>.p-0", - "replaceElement": ".pager", - "css": ".pagetual_pageBar{margin-top:-14px!important}" + "pageElement": "a.comicpic_col6", + "replaceElement": ".pager" }, { "name": "無限動漫 - 分類", "author": "skofkyo", - "example": "https://www.comicabc.com/comic/6-1.html", - "url": "^https?://www\\.comicabc\\.com/comic/[a-z0-9-]+\\.html", + "example": "https://www.8comic.com/comic/u-1.html", + "url": "^https?://www\\.8comic\\.com/comic/[a-z0-9-]+\\.html", "nextLink": "//a[span/@class='mdi mdi-skip-next']", - "pageElement": ".default_row_width>.p-0", + "pageElement": ".row>div:has(>div.cat2_list)", "replaceElement": ".pager", "css": ".pagetual_pageBar{margin-top:-14px!important}" }, { "name": "無限動漫 - 圖庫原圖瀏覽", "author": "skofkyo", - "example": "https://www.comicabc.com/photo/p6038.html?n=1", - "url": "^https?://www\\.comicabc\\.com/photo/p\\d+\\.html\\?n=\\d+$", - "nextLinkByUrl": [ - "(\\?n=(\\d+))$", - "?n={$2+1}", - "#next:not([style])" - ], - "pageElement": "img[name='TheImg']", - "replaceElement": ".photo_main_div > div:nth-child(1)", - "pageBar": 0, - "css": "img[name='TheImg'] {max-width: 98% !important;display: block !important;margin: 0 auto !important;}" + "example": "https://www.8comic.com/photo/p6041.html?n=1", + "url": "^https?://www\\.8comic\\.com/photo/p[0-9-]+\\.html\\?n=\\d+$", + "init": "let total=document.querySelectorAll('#pageindex option').length;let imgSrc=new URL(document.querySelector('#TheImg').src).pathname;let html='';for(let i=1;i<=total;i++){let num=String(i).padStart(3,'0');let src=imgSrc.replace(/(\\d+)(\\.\\w)$/,`${num}$2`);html+=``}document.querySelector('.photo_main_div').innerHTML=html;", + "css": "#TheImg{margin:2px auto;display:block}", + "pinUrl": true }, { "name": "無限動漫 - 圖庫清單載入大圖", "author": "skofkyo", - "example": "https://www.comicabc.com/photo/6041.html", - "url": "^https?://www\\.comicabc\\.com/photo/\\d+\\.html$", + "example": "https://www.8comic.com/photo/6041.html", + "url": "^https?://www\\.8comic\\.com/photo/\\d+\\.html$", "init": "document.querySelectorAll('#dl img').forEach(img=>{let f=img.src.replace('.jpe','.jpg');img.src=f})", "pinUrl": true }, { - "name": "無限動漫 - 圖庫", + "name": "無限動漫 - 圖庫分類", "author": "skofkyo", - "example": "https://www.comicabc.com/photo/1-1.html", - "url": "^https?://www\\.comicabc\\.com/photo/[0-9-]+\\.html$", - "nextLink": "//a[span/@class='mdi mdi-skip-next']", - "pageElement": ".photo_main_div .row", + "example": "https://www.8comic.com/photo/3-1.html", + "url": "^https?://www\\.8comic\\.com/photo/[0-9-]+\\.html$", + "nextLink": "a:has(>.mdi-skip-next)", + "pageElement": ".row:has(>div>.cat2_list)", "replaceElement": ".pager" }, { "name": "無限動漫 - 類別停止自動匹配", "author": "skofkyo", - "example": "https://www.comicabc.com/html/1/", - "url": "^https?://www\\.comicabc\\.com/html/\\d+/$" + "example": "https://www.8comic.com/html/1/", + "url": "^https?://www\\.8comic\\.com/html/\\d+/$", + "enable": 0 }, { "name": "砂之船动漫家 - 手機版閱讀", @@ -698,8 +597,8 @@ { "name": "来漫画 - 手機版閱讀", "author": "skofkyo", - "example": "https://m.laimanhua8.com/kanmanhua/kaijujiangliyiyitiaoming/1684241122.html", - "url": "^https?://m\\.laimanhua8\\.com/kanmanhua/\\w+/\\d+\\.html", + "example": "https://m.laimanhua88.com/kanmanhua/kaijujiangliyiyitiaoming/1684241122.html", + "url": "^https?://m\\.laimanhua88\\.com/kanmanhua/\\w+/\\d+\\.html", "pinUrl": true, "history": 2, "init": "let ge=e=>document.querySelector(e);let code=Array.from(document.scripts).find(s=>s.innerHTML.search(/mhInfo/)>-1).innerHTML;let json=eval(code.match(/mhInfo[^;]+/)[0]);let E=ge('#manga');let F=new DocumentFragment();json.images.forEach(e=>{let img=new Image();img.src=realurl+json.path+e;F.appendChild(img)});E.innerHTML='';E.appendChild(F);", @@ -715,8 +614,8 @@ { "name": "来漫画 - 閱讀", "author": "skofkyo", - "example": "https://www.laimanhua8.com/kanmanhua/kaijujiangliyiyitiaoming/1684241122.html", - "url": "^https?://www\\.laimanhua8\\.com/kanmanhua/\\w+/\\d+\\.html", + "example": "https://www.laimanhua88.com/kanmanhua/kaijujiangliyiyitiaoming/1684241122.html", + "url": "^https?://www\\.laimanhua88\\.com/kanmanhua/\\w+/\\d+\\.html", "pinUrl": true, "history": 2, "init": "let ge=e=>document.querySelector(e);let code=Array.from(document.scripts).find(s=>s.innerHTML.search(/picTree/)>-1).innerHTML;let base64=eval(code.match(/picTree[^;]+/)[0]);let imgData=base64_decode(base64).split('$qingtiandy$');let host=getpicdamin();let E=ge('#pic-list');let F=new DocumentFragment();imgData.forEach(e=>{let img=new Image();img.src=encodeURI(host+e);F.appendChild(img)});E.innerHTML='';E.appendChild(F);$('head').append('')", @@ -776,8 +675,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);", @@ -793,8 +692,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);", @@ -840,52 +739,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", @@ -951,8 +804,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);", @@ -968,8 +821,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);", @@ -985,8 +838,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", @@ -1124,8 +977,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动漫 - 分類", @@ -1209,7 +1061,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))", @@ -1378,20 +1230,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" @@ -1459,25 +1302,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", @@ -1498,25 +1322,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", @@ -1584,28 +1389,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", @@ -1631,16 +1414,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", @@ -1696,27 +1469,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", @@ -1746,20 +1498,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", @@ -1806,16 +1544,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", @@ -1899,10 +1627,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", @@ -1945,16 +1673,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", @@ -2042,205 +1760,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", @@ -2300,28 +1819,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", @@ -2374,49 +1871,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": "美女目录网 - 圖片", @@ -2473,44 +1935,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", @@ -2695,10 +2119,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", @@ -2707,8 +2130,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 - 看圖禁用", @@ -2951,41 +2373,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", @@ -3020,25 +2407,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", @@ -3068,8 +2436,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", @@ -3100,8 +2467,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']", @@ -3122,7 +2489,7 @@ "name": "PPP.Porn - 首頁(載入更多 …)", "author": "skofkyo", "example": "https://ppp.porn/", - "url": "^https?://ppp\\.porn/$", + "url": "^https?://ppp\\.porn/", "loadMore": ".btn.btn--sm" }, { @@ -3136,15 +2503,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", @@ -3320,6 +2678,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;", @@ -3369,7 +2728,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']]", @@ -3525,30 +2884,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", @@ -3763,16 +3098,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", @@ -3822,16 +3147,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", @@ -3850,21 +3165,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", @@ -3899,7 +3199,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" }, @@ -3951,16 +3251,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", @@ -3970,16 +3260,6 @@ "pageElement": ".items", "replaceElement": ".pagination" }, -{ - "name": "ACG RW", - "author": "skofkyo", - "example": "https://www.acgrw.net/category/lifan/", - "url": "^https?://www\\.acgrw\\.net/", - "nextLink": "a.next", - "pageElement": ".uk-animation-slide-bottom-small", - "replaceElement": ".nav-links", - "pageInit": "doc.querySelectorAll('.media-content.scrollLoading:not(.ojbk)').forEach(div=>{div.style.backgroundImage=`url('${div.dataset.xurl}')`;div.classList.add('ojbk');div.removeAttribute('data-xurl')})" -}, { "name": "ACG - 🏠 西普拉斯驿站|小西驿站 - 数码,音乐,ACG论坛", "url": "^https?://post\\.cplus8\\.com/", @@ -4035,98 +3315,6 @@ "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 -}, -{ - "name": "xHamster pornstars", - "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 -}, -{ - "name": "xHamster", - "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;}" -}, { "name": "色色啦", "author": "skofkyo", @@ -4142,6 +3330,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", @@ -4239,29 +3428,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", @@ -4271,30 +3443,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", @@ -4332,14 +3480,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", @@ -4422,15 +3562,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", @@ -4448,8 +3579,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", @@ -4481,15 +3611,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", @@ -4512,24 +3633,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", @@ -4553,20 +3656,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>*", @@ -4582,58 +3676,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", @@ -4697,34 +3739,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", @@ -4744,18 +3764,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", @@ -4815,7 +3823,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": "丽图·污漫画 - 分類", @@ -4825,7 +3833,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": "海棠小说网 - 手机阅读", @@ -4874,7 +3882,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 }, { @@ -4901,7 +3909,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 }, { @@ -4918,17 +3926,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": "國模網", @@ -4940,59 +3938,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", @@ -5018,12 +3963,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 }, { @@ -5072,32 +4017,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", @@ -5300,33 +4219,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", @@ -5342,31 +4234,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", @@ -5381,7 +4248,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, @@ -5418,15 +4285,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,'')", @@ -5474,8 +4342,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", @@ -5486,8 +4354,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" From fb9cc2da209ad3ecfd04e9d10349db17855c294a Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Fri, 21 Mar 2025 16:01:19 +0000 Subject: [PATCH 0654/1065] Update version of Pagetual rules to 86 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index a862eb8444d..8cf5c1a22a2 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -85 +86 From e8a8623b459e40a387e51ed7d12cf2a554d092b2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 22 Mar 2025 10:51:06 +0800 Subject: [PATCH 0655/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 0bdce1c2539..a31c8beeccb 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5876,8 +5876,8 @@ "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\"]/style/following-sibling::*|//*[@id=\"content_left\"]/*", "pageNum": "&pn={10*($p-1)}", @@ -5891,8 +5891,8 @@ "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\"]", "pageNum": "&pn={10*($p-1)}", From 2e917b9c2910c0393f573453eb7646427d424870 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 22 Mar 2025 02:51:23 +0000 Subject: [PATCH 0656/1065] Update version of Pagetual rules to 86 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index a862eb8444d..8cf5c1a22a2 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -85 +86 From 578a99b1b500f8d25b3c86ecc9ce79016d8b2e1c Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 22 Mar 2025 05:51:26 +0000 Subject: [PATCH 0657/1065] Update version of Pagetual rules to 87 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 8cf5c1a22a2..84df3526d80 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -86 +87 From 60ee2cdd0758af525b71c00d4272d71d7b0cc3f2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 31 Mar 2025 20:51:14 +0800 Subject: [PATCH 0658/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 8ea15d20ea0..c43e92a2759 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -15593,9 +15593,6 @@ ImgOps | https://imgops.com/#b#`; urlToBlob(imgSrc, blob=>{ if (blob && blob.size>58) { let fileName = imgName.replace(/\//g, ""); - formatDict.forEach((value, key) => { - fileName.replace(new RegExp(`\\.${key}$`), value); - }); zip.file(fileName, blob); } else console.debug("error: "+imgSrc); downloaded++; From 8a20422e46c11cd925ce64d84d219d292934bf3f Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 7 Apr 2025 17:31:59 +0800 Subject: [PATCH 0659/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index c43e92a2759..ca73b819ead 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.3.16.1 +// @version 2025.4.7.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -23768,8 +23768,12 @@ ImgOps | https://imgops.com/#b#`; if (buttonType === 'download' && !this.data.xhr) { if (e.ctrlKey || e.metaKey || e.altKey || e.shiftKey) return; downloadImg(this.data.src || this.data.imgSrc, (this.data.img.title || this.data.img.alt), prefs.saveName); + e.stopPropagation(); + e.preventDefault(); return; } else { + e.stopPropagation(); + e.preventDefault(); let altKey = e.altKey; if (e.type != "click" && prefs.floatBar.globalkeys.invertInitShow && prefs.floatBar.globalkeys.alt) { altKey = false; @@ -25581,8 +25585,6 @@ ImgOps | https://imgops.com/#b#`; if (action == 'enable' || action == 'search') return; if (key == prefs.floatBar.keys[action]) { floatBar.open(event, action); - event.stopPropagation(); - event.preventDefault(); return true; } }); From a09cc55d7bd3302d051c821a57bda56715cce07c Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 9 Apr 2025 18:21:24 +0800 Subject: [PATCH 0660/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index b3ea04100d0..ecd81f87649 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -4413,7 +4413,7 @@ "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;}inIframe:#searchform,[data-l],[data-is-desktop]{display:none;}" + "css": "inIframe:#searchform,[data-l],[data-is-desktop]{display:none;}" }, { "name": "Google Trends", From e815376d2abf61f8f2d67be614a01141de97824a Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Wed, 9 Apr 2025 10:21:49 +0000 Subject: [PATCH 0661/1065] Update version of Pagetual rules to 88 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 84df3526d80..d22307c427b 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -87 +88 From e0f8cb065df60b30134decc303b373d8fc952f24 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 11 Apr 2025 16:31:19 +0800 Subject: [PATCH 0662/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index ca73b819ead..805a6567f0a 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -9,10 +9,10 @@ // @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 2025.4.7.1 +// @version 2025.4.11.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -23589,7 +23589,7 @@ ImgOps | https://imgops.com/#b#`; return true; } var targetPosi = getContentClientRect(this.data.img); - var pa = this.data.img.parentNode; + var pa = this.data.img.offsetParent || this.data.img.parentNode; if (pa && pa.scrollHeight > 30 && pa.scrollWidth > 30) { var paPosi=pa.getBoundingClientRect(); if (paPosi.width > 30 && paPosi.height > 30) { From e5bd74605690578fc11c04afdf3c4dc1633f6f19 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 14 Apr 2025 08:38:49 +0800 Subject: [PATCH 0663/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 46ae8b27fdc..38dd608f176 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1709,5 +1709,11 @@ var siteInfo = [ url: /^https:\/\/(www\.|m\.)?ctrip\.com/, r: /_(C|D)_\d[^\.]*/i, s: "" + }, + { + name: "nozomi", + url: "^https://nozomi\\.la", + r: "///qtn(\\..*)\\.\\w+\\.webp/i", + s: "//w$1.webp" } ]; From ce41626bf1094722dfd0c023329df7bbe342d4a7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 14 Apr 2025 08:42:14 +0800 Subject: [PATCH 0664/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 194 ++++++++++++++-------------- 1 file changed, 98 insertions(+), 96 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 805a6567f0a..fb4fc8a5bd9 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.4.11.1 +// @version 2025.4.14.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1552062/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1570604/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -12333,7 +12333,7 @@ ImgOps | https://imgops.com/#b#`; sizeLimitOr:false, keys: { - enable: true, + enable: false, actual: 'a', // 当出现悬浮条时按下 `a` 打开原图 search: 's', current: 'c', @@ -22434,25 +22434,14 @@ ImgOps | https://imgops.com/#b#`; }, focusedKeydown:async function(e){ var keyCode=e.keyCode; + if (!prefs.floatBar.keys.enable) return; if (this.data && this.data.img && e.key.toLowerCase() == prefs.floatBar.keys.download) { downloadImg(this.img.src, (this.data.img.title || this.data.img.alt), prefs.saveName); e.preventDefault(); e.stopPropagation(); return; } - var valid=[32,82,72,90,18,16,17,27,67,71];//有效的按键 - if(valid.indexOf(keyCode)==-1) return; - - e.preventDefault(); - - if(this.working){//working的时候也可以接受按下shift键,以便旋转的时候可以任何时候按下 - if(keyCode==16){//shift键 - this.shiftKeyUp=false; - }; - return; - }; - - if (e.key == prefs.floatBar.keys.gallery) { + if (e.key.toLowerCase() == prefs.floatBar.keys.gallery) { if (!gallery) { gallery = new GalleryC(); gallery.data = []; @@ -22463,89 +22452,102 @@ ImgOps | https://imgops.com/#b#`; gallery.data = allData; gallery.load(gallery.data); this.remove(); - } else { - switch(keyCode){ - case 82:{//r键,切换到旋转工具 - if(this.rKeyUp){ - this.rKeyUp=false; - this.beforeTool=this.selectedTool; - if (this.beforeTool != 'rotate') { - this.selectTool('rotate'); - } - var PI = Math.PI; - var value = this.rotatedRadians + (e.shiftKey ? -90 : 90) * PI / 180; - if (value >= 2 * PI) { - value -= 2 * PI; - } else if (value < 0) { - value += 2 * PI; - } - this.rotate(value,true); - }; - }break; - case 72:{//h键,切换到抓手工具 - if(this.hKeyUp){ - this.hKeyUp=false; - this.beforeTool=this.selectedTool; - this.selectTool('hand'); - }; - }break; - case 90:{//z键,切换到缩放工具 - if(this.zKeyUp){ - this.zKeyUp=false; - this.beforeTool=this.selectedTool; - this.selectTool('zoom'); - let level = e.shiftKey ? (this.zoomLevel - 0.5) : (this.zoomLevel + 0.5); - if (typeof level != 'undefined') { - this.zoom(level, { x: 0, y: 0}); - } - if (uniqueImgWin && uniqueImgWin == this) { - if (prefs.floatBar.globalkeys.previewFollowMouse) { - this.followPos(uniqueImgWinInitX, uniqueImgWinInitY, true); - } else { - this.center(true, true); - } + e.preventDefault(); + e.stopPropagation(); + return; + } + var valid=[32,82,72,90,18,16,17,27,67];//有效的按键 + if(valid.indexOf(keyCode)==-1) return; + + e.preventDefault(); + + if(this.working){//working的时候也可以接受按下shift键,以便旋转的时候可以任何时候按下 + if(keyCode==16){//shift键 + this.shiftKeyUp=false; + }; + return; + }; + switch(keyCode){ + case 82:{//r键,切换到旋转工具 + if(this.rKeyUp){ + this.rKeyUp=false; + this.beforeTool=this.selectedTool; + if (this.beforeTool != 'rotate') { + this.selectTool('rotate'); + } + var PI = Math.PI; + var value = this.rotatedRadians + (e.shiftKey ? -90 : 90) * PI / 180; + if (value >= 2 * PI) { + value -= 2 * PI; + } else if (value < 0) { + value += 2 * PI; + } + this.rotate(value,true); + }; + }break; + case 72:{//h键,切换到抓手工具 + if(this.hKeyUp){ + this.hKeyUp=false; + this.beforeTool=this.selectedTool; + this.selectTool('hand'); + }; + }break; + case 90:{//z键,切换到缩放工具 + if(this.zKeyUp){ + this.zKeyUp=false; + this.beforeTool=this.selectedTool; + this.selectTool('zoom'); + let level = e.shiftKey ? (this.zoomLevel - 0.5) : (this.zoomLevel + 0.5); + if (typeof level != 'undefined') { + this.zoom(level, { x: 0, y: 0}); + } + if (uniqueImgWin && uniqueImgWin == this) { + if (prefs.floatBar.globalkeys.previewFollowMouse) { + this.followPos(uniqueImgWinInitX, uniqueImgWinInitY, true); + } else { + this.center(true, true); } + } + }; + }break; + case 32:{//空格键阻止,临时切换到抓手功能 + if(this.spaceKeyUp){ + this.spaceKeyUp=false; + if(this.selectedTool!='hand'){ + this.tempHand=true; + this.changeCursor('hand'); }; - }break; - case 32:{//空格键阻止,临时切换到抓手功能 - if(this.spaceKeyUp){ - this.spaceKeyUp=false; - if(this.selectedTool!='hand'){ - this.tempHand=true; - this.changeCursor('hand'); + }; + }break; + case 18:{//alt键,在当前选择是缩放工具的时候,按下的时候切换到缩小功能 + if(this.altKeyUp){ + if((this.selectedTool!='zoom' && !this.tempZoom) || this.zoomOut)return; + this.zoomOut=true; + this.altKeyUp=false; + this.changeCursor('zoom',true); + }; + }break; + case 17:{//ctrl键临时切换到缩放工具 + if(this.ctrlKeyUp){ + var self=this; + this.ctrlkeyDownTimer=setTimeout(function(){//规避词典软件的ctrl+c,一瞬间切换到缩放的问题 + self.ctrlKeyUp=false; + if(self.selectedTool!='zoom'){ + self.tempZoom=true; + self.changeCursor('zoom'); }; - }; - }break; - case 18:{//alt键,在当前选择是缩放工具的时候,按下的时候切换到缩小功能 - if(this.altKeyUp){ - if((this.selectedTool!='zoom' && !this.tempZoom) || this.zoomOut)return; - this.zoomOut=true; - this.altKeyUp=false; - this.changeCursor('zoom',true); - }; - }break; - case 17:{//ctrl键临时切换到缩放工具 - if(this.ctrlKeyUp){ - var self=this; - this.ctrlkeyDownTimer=setTimeout(function(){//规避词典软件的ctrl+c,一瞬间切换到缩放的问题 - self.ctrlKeyUp=false; - if(self.selectedTool!='zoom'){ - self.tempZoom=true; - self.changeCursor('zoom'); - }; - },100); - }; - }break; - case 67:{//c键 - clearTimeout(this.ctrlkeyDownTimer); - }break; - case 27:{//ese关闭窗口 - if(prefs.imgWindow.close.escKey){ - this.remove(); - }; - }break; - default:break; - } + },100); + }; + }break; + case 67:{//c键 + clearTimeout(this.ctrlkeyDownTimer); + }break; + case 27:{//ese关闭窗口 + if(prefs.imgWindow.close.escKey){ + this.remove(); + }; + }break; + default:break; } e.stopPropagation(); return false; From 6545f6cdedc3103820dfae9585ed7b0825e759a4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 14 Apr 2025 15:21:40 +0800 Subject: [PATCH 0665/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index fb4fc8a5bd9..663ac0544ac 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -20314,8 +20314,7 @@ ImgOps | https://imgops.com/#b#`; gallery.data=[]; } var allData=await gallery.getAllValidImgs(); - if(allData.length<1)return; - allData.target={src:img.src}; + allData.target = self.data; gallery.data=allData; gallery.load(gallery.data); self.remove(); @@ -22447,8 +22446,7 @@ ImgOps | https://imgops.com/#b#`; gallery.data = []; } var allData = await gallery.getAllValidImgs(); - if (allData.length < 1) return; - allData.target = {src: this.img.src}; + allData.target = this.data; gallery.data = allData; gallery.load(gallery.data); this.remove(); From 3777657729a2b2e1156287a52b21d4e1d96c8c9b Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 16 Apr 2025 21:53:18 +0800 Subject: [PATCH 0666/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 4ecebec232b..16461b00c6c 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3586,6 +3586,9 @@ return null; } parent = parent.parentNode; + if (compareNodeName(parent, ["a"])) { + nextLink = parent; + } } if (doc === document) { if (!this.linkHasHref(nextLink) && !isVisible(nextLink, _unsafeWindow)) { @@ -8459,7 +8462,7 @@ ruleParser.changeVisibility(); }; dblclickHandler = e => { - if (forceState == 1 || compareNodeName(e.target, ["input", "textarea", "select", "a", "button", "svg", "use", "img", "path"])) return; + if (forceState == 1 || compareNodeName(e.target, ["input", "textarea", "select", "a", "button", "svg", "canvas", "use", "img", "path"])) return; if (!rulesData.dbClick2StopKey) { if ((rulesData.dbClick2StopCtrl && !e.ctrlKey) || (rulesData.dbClick2StopAlt && !e.altKey) || From 6e0d058a3d03c49463ba7ca8c25b4f60906246e9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 19 Apr 2025 08:27:39 +0800 Subject: [PATCH 0667/1065] update --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index f3c38c02389..8bacc927e33 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.117](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.119](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 16461b00c6c..4af851e5f37 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.118 +// @version 1.9.37.119 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -3034,10 +3034,9 @@ ".next>button", "a[alt=next]", ".pg_area>em+a", - "button.next:not([disabled])", - ".btn_next:not([disabled])", - ".btn-next:not([disabled])", "a#linkNext", + ".page>em+a", + "a.page_next", "body a[class*=page__next]", "body [class*=pager]>a.next", "body [class*=pagination-next]>a", @@ -3049,8 +3048,10 @@ "body [class*=paginat] [class*=next-next]", "body [class*=paginat] [class*=next]", "body [class*=paginat] [class*=right]", - ".page>em+a", "[name*=nextPage]", + "button.next:not([disabled])", + ".btn_next:not([disabled])", + ".btn-next:not([disabled])", '//button[contains(@class, "Page")][text()="Next"]', '//button[contains(@class, "page")][text()="next"]' ]; @@ -8480,7 +8481,7 @@ selObj = selection && selection.cloneContents().children[0]; if (selObj && !compareNodeName(selObj, ["img"])) selObj = false; } - if (selObj) { + if (selObj && selObj.trim()) { return; } } catch (e) {} @@ -8895,7 +8896,9 @@ let tdNum = 0; if (exampleStyle.display == "table-row") { [].forEach.call(example.children, el => { - tdNum += el.colSpan || 1; + if (el.offsetParent) { + tdNum += el.colSpan || 1; + } }); } else { [].forEach.call(example.children, el => { From 8643817e24dd7a2892403d819f5f153b4d629819 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 20 Apr 2025 09:40:34 +0800 Subject: [PATCH 0668/1065] Update README.md --- DownloadAllContent/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DownloadAllContent/README.md b/DownloadAllContent/README.md index 4d45efd984d..ea4e93b7e11 100644 --- a/DownloadAllContent/README.md +++ b/DownloadAllContent/README.md @@ -24,7 +24,7 @@ [怠惰小説下載器 ZIP 擴充](https://greasyfork.org/scripts/476943) 下載時分章節保存 TXT 並打包為 ZIP -[圖片驗證碼辨識](https://github.com/hoothin/ImgCodeCheck) 開啟`保留內文圖片的網址`後配合 ZIP 擴充可自動轉換圖片文字,詳閱[愛發電](https://afdian.net/p/c7fc3abc8e8411ee9b1852540025c377) +[圖片驗證碼辨識](https://github.com/hoothin/ImgCodeCheck) 開啟`保留內文圖片的網址`後配合 ZIP 擴充可自動轉換圖片文字,詳閱[愛發電](https://afdian.com/p/c7fc3abc8e8411ee9b1852540025c377) ## 怠惰心法 名喚怠惰,實為勤勉 From 368bc425b3636d4fbd35f1b39588df466c982972 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 21 Apr 2025 09:06:05 +0800 Subject: [PATCH 0669/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 663ac0544ac..ad4e834ee86 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.4.14.1 +// @version 2025.4.21.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -22360,6 +22360,7 @@ ImgOps | https://imgops.com/#b#`; var valid=[32,18,16,72,17,72,82,90,67,37,39]; if(valid.indexOf(keyCode)==-1)return; + if (window.getSelection().toString()) return; e.preventDefault(); switch(keyCode){ @@ -22434,6 +22435,7 @@ ImgOps | https://imgops.com/#b#`; focusedKeydown:async function(e){ var keyCode=e.keyCode; if (!prefs.floatBar.keys.enable) return; + if (window.getSelection().toString()) return; if (this.data && this.data.img && e.key.toLowerCase() == prefs.floatBar.keys.download) { downloadImg(this.img.src, (this.data.img.title || this.data.img.alt), prefs.saveName); e.preventDefault(); @@ -23754,6 +23756,7 @@ ImgOps | https://imgops.com/#b#`; }, open:async function(e,buttonType){ if (!this.shown || !this.data || !this.data.imgSrc) return; + if (window.getSelection().toString()) return; if (this.data.imgSrc.indexOf("blob:") === 0) { let blobUrl = await getBase64FromBlobUrl(this.data.imgSrc); if (blobUrl) { @@ -25578,7 +25581,7 @@ ImgOps | https://imgops.com/#b#`; if (event) { if (event.ctrlKey || event.metaKey) return false; - if ((event.altKey || event.shiftKey) && window.getSelection().toString()) return false; + if (window.getSelection().toString()) return false; } if (floatBar && isKeyDownEffectiveTarget(event.target)) { Object.keys(prefs.floatBar.keys).some(function(action) { From 2a76a33232e915924b1f2aabb03547717c37378e Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 22 Apr 2025 16:17:19 +0800 Subject: [PATCH 0670/1065] Update Kill Baidu AD.user.js --- Kill Baidu AD/Kill Baidu AD.user.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Kill Baidu AD/Kill Baidu AD.user.js b/Kill Baidu AD/Kill Baidu AD.user.js index c047b000902..565821eb870 100644 --- a/Kill Baidu AD/Kill Baidu AD.user.js +++ b/Kill Baidu AD/Kill Baidu AD.user.js @@ -4,7 +4,7 @@ // @name:zh-TW 百度廣告(首尾推廣及右側廣告)清理 // @name:en Kill Baidu AD // @namespace hoothin -// @version 1.23.11 +// @version 1.23.12 // @description 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,删除百家号 // @description:zh-CN 彻底清理百度搜索(www.baidu.com)结果首尾的推广广告、二次顽固广告、右侧广告,去除重定向,移除百家号 // @description:zh-TW 徹底清理百度搜索(www.baidu.com)結果首尾的推廣廣告、二次頑固廣告、右側廣告,去除重定向,刪除百家號 @@ -31,7 +31,11 @@ (function() { 'use strict'; - var MO = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, killBaijiaType = 1, killRight, killRightStyle, killRightRegister, hidePicture, hidePictureStyle, hidePictureRegister, blackList; + var MO = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, killBaijiaType = 1, killRight, killRightStyle, killRightRegister, hidePicture, keepBaijia, hidePictureStyle, hidePictureRegister, blackList; + killRight = !!GM_getValue("killRight"); + hidePicture = !!GM_getValue("hidePicture"); + keepBaijia = !!GM_getValue("keepBaijia"); + blackList = GM_getValue("blackList") || []; if (MO) { var observer = new MO(function(records) { records.map(function(record) { @@ -93,7 +97,7 @@ } if (!mu || mu === 'null') return; if (/^https:\/\/baijiahao\.baidu\.com/.test(mu)) { - item.remove(); + !keepBaijia && item.remove(); return; } else { let title = item.querySelector('[data-module="title"]'); @@ -109,7 +113,7 @@ let mu = item.getAttribute("mu"); if (mu && mu !== 'null' && mu.indexOf("http") == 0 && mu.indexOf("nourl") == -1 && item.getAttribute("tpl") != "short_video") { if (/^https:\/\/baijiahao\.baidu\.com/.test(mu)) { - item.remove(); + !keepBaijia && item.remove(); return; } else { let title = item.querySelector('h3'); @@ -147,7 +151,7 @@ [].forEach.call(item.querySelectorAll("a>div>span+img"), function(img) { if (img && /^https?:\/\/pic\.rmb\.bdstatic\.com/.test(img.src)) { //checkBaijia(item); - item.remove(); + !keepBaijia && item.remove(); } }); } @@ -453,9 +457,6 @@ function run() { try { - killRight = !!GM_getValue("killRight"); - hidePicture = !!GM_getValue("hidePicture"); - blackList = GM_getValue("blackList") || []; if (location.host === "greasyfork.org") { function initConfig() { let parent = document.querySelector('#additional-info'); @@ -480,6 +481,7 @@ }; let hidePictureInput = createCheckbox('隐藏图片并简化样式', hidePicture); let killRightInput = createCheckbox('隐藏右边栏并多列显示', killRight); + let keepBaijiaInput = createCheckbox('保留百家号', keepBaijia); let importInput = document.createElement('textarea'); importInput.placeholder = '订阅 uBlacklist 规则:如 https://git.io/ublacklist'; importInput.style.width = '100%'; @@ -504,8 +506,10 @@ saveBtn.addEventListener("click", function(e) { hidePicture = hidePictureInput.checked; killRight = killRightInput.checked; + keepBaijia = keepBaijiaInput.checked; GM_setValue("hidePicture", hidePicture); GM_setValue("killRight", killRight); + GM_setValue("keepBaijia", keepBaijia); if (importInput.value) { alert("读取规则中……"); let importUrls = importInput.value.trim().split("\n"); From f7ca1276e60647fb369d5e5491d8ccf63c3b2bb5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 22 Apr 2025 16:39:39 +0800 Subject: [PATCH 0671/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 31 ++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index ad4e834ee86..d4a5c62c87c 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -23591,9 +23591,30 @@ ImgOps | https://imgops.com/#b#`; return true; } var targetPosi = getContentClientRect(this.data.img); - var pa = this.data.img.offsetParent || this.data.img.parentNode; + var pa = this.data.img.parentNode, limited = false; if (pa && pa.scrollHeight > 30 && pa.scrollWidth > 30) { var paPosi=pa.getBoundingClientRect(); + if (paPosi.width > 30 && paPosi.height > 30) { + const style = unsafeWindow.getComputedStyle(this.data.img); + const matrix = new DOMMatrixReadOnly(style.transform); + let translateX = matrix.m41, translateY = matrix.m42, scaleX = matrix.m11, scaleY = matrix.m22; + if (translateY || this.data.img.offsetTop != 0 || (scaleY && scaleY !== 1)) { + if (paPosi.height < targetPosi.height - 3) { + limited = true; + targetPosi.top = paPosi.top; + } + } + if (translateX || this.data.img.offsetLeft != 0 || (scaleX && scaleX !== 1)) { + if (paPosi.width < targetPosi.width - 3) { + limited = true; + targetPosi.left = paPosi.left; + } + } + } + } + if (!limited) { + pa = this.data.img.offsetParent; + paPosi=pa.getBoundingClientRect(); if (paPosi.width > 30 && paPosi.height > 30) { const style = unsafeWindow.getComputedStyle(this.data.img); const matrix = new DOMMatrixReadOnly(style.transform); @@ -24967,7 +24988,10 @@ ImgOps | https://imgops.com/#b#`; if (broEle == target) broEle = null; } } - if (prefs.floatBar.listenBg && hasBg(target)) { + if (target.children.length == 1 && !(target.textContent && target.textContent.trim()) && target.children[0].nodeName == "IMG") { + target = target.children[0]; + found = true; + } else if (prefs.floatBar.listenBg && hasBg(target)) { let src = targetBg, nsrc = src, noActual = true, type = "scale"; result = { src: nsrc, @@ -24993,9 +25017,6 @@ ImgOps | https://imgops.com/#b#`; }; found = true; } - } else if (target.children.length == 1 && !(target.textContent && target.textContent.trim()) && target.children[0].nodeName == "IMG") { - target = target.children[0]; - found = true; } else if (prefs.floatBar.listenBg && broEle && hasBg(broEle)) { let src = targetBg, nsrc = src, noActual = true, type = "scale"; result = { From d7a171fe15e55afda3c144e660afde90d784e582 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 26 Apr 2025 08:39:27 +0800 Subject: [PATCH 0672/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 4af851e5f37..e245ad86c61 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -1474,7 +1474,7 @@ const nextTextReg1 = new RegExp("\u005e\u7ffb\u003f\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u2500\u0031\u005d\u003f\u005b\u9875\u9801\u5f20\u5f35\u005d\u007c\u005e\u006e\u0065\u0078\u0074\u005b\u005c\u005c\u0073\u005f\u002d\u005d\u003f\u0070\u0061\u0067\u0065\u005c\u005c\u0073\u002a\u005b\u203a\u003e\u2192\u00bb\u005d\u003f\u0024\u007c\u6b21\u306e\u30da\u30fc\u30b8\u007c\u005e\u6b21\u3078\u003f\u0024\u007c\u0412\u043f\u0435\u0440\u0435\u0434\u007c\u005e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435", "i"); const nextTextReg2 = new RegExp("\u005e\u0028\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u2500\u0031\u005d\u003f\u005b\u7ae0\u8bdd\u8a71\u8282\u7bc0\u5e45\u005d\u007c\u006e\u0065\u0078\u0074\u002e\u003f\u0063\u0068\u0061\u0070\u0074\u0065\u0072\u0029\u0028\u005b\u003a\uff1a\u005c\u002d\u005f\u2014\u005c\u0073\u005c\u002e\u3002\u003e\u0023\u00b7\u005c\u005b\u3010\u3001\uff08\u005c\u0028\u002f\u002c\uff0c\uff1b\u003b\u2192\u005d\u007c\u0024\u0029", "i"); const nextTextReg3 = /^(next\s*(»|>>|>|›|→|❯|\d+)?|>|▶|>|›|→|❯)\s*$/i; - const prevReg = new RegExp("\u005e\u005c\u0073\u002a\u0028\u005b\u4e0a\u524d\u9996\u5c3e\u005d\u007c\u0070\u0072\u0065\u0076\u0069\u006f\u0075\u0073\u007c\u0065\u006e\u0064\u0029", "i"); + const prevReg = new RegExp("\u005e\u005c\u0073\u002a\u0028\u005b\u4e0a\u524d\u9996\u5c3e\u005d\u007c\u0070\u0072\u0065\u0076\u007c\u0065\u006e\u0064\u0029", "i"); const lazyImgAttr = ["data-lazy-src", "data-s", "data-lazy", "data-isrc", "data-url", "data-orig-file", "zoomfile", "file", "original", "load-src", "imgsrc", "real_src", "src2", "origin-src", "data-lazyload", "data-lazyload-src", "data-lazy-load-src", "data-ks-lazyload", "data-ks-lazyload-custom", "data-src", "data-defer-src", "data-actualsrc", "data-cover", "data-original", "data-thumb", "data-imageurl", "data-placeholder", "lazysrc"]; var rulesData = {uninited: true, firstRun: true, sideController: !isMobile}, ruleUrls, updateDate, loadNowNum = 5, autoScrollRate = 50; var isPause = false, manualPause = false, isHideBar = false, isLoading = false, curPage = 1, forceState = 0, autoScroll = 0, autoScrollInterval, bottomGap = 1000, autoLoadNum = -1, initAutoLoadNum = 0, nextIndex = 0, stopScroll = false, clickMode = false, openInNewTab = 0, charset = "UTF-8", charsetValid = true, urlWillChange = false, hidePageBar = false; @@ -3015,8 +3015,8 @@ "a.page-numbers.next", "body [class*=paginat] li.active+span+li>a", "body [class*=paginat] li.active+li>a", - "body [class^=pag] .current+a", - "body [class*=-pag] .current+a", + "body [class^=pag] [class*=current]+a", + "body [class*=-pag] [class*=current]+a", ".page_current+a", "input[value='next']", "input[value='Next page']", From ba549f1ebc21babcefccb9a2cbe0ccca09152556 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 26 Apr 2025 21:34:03 +0800 Subject: [PATCH 0673/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index e245ad86c61..95397a2feef 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3192,7 +3192,7 @@ if (!this.verifyElement(aTag)) continue; if (aTag.dataset && aTag.dataset.preview) continue; let availableHref = aTag.href && aTag.href.length < 250 && !/^(javascript:|#)/.test(aTag.href); - if (availableHref && /next\-?(page)?$|\/video\/|\/vod\/play\//i.test(aTag.href)) continue; + if (availableHref && /next\-?(page)?$|\/vod\/play\//i.test(aTag.href)) continue; if (compareNodeName(aTag.parentNode, ["blockquote"])) continue; if (aTag.previousElementSibling && /\b(play|volume)\b/.test(aTag.previousElementSibling.className)) continue; if (aTag.nextElementSibling && /\b(play|volume)\b/.test(aTag.nextElementSibling.className)) continue; From 26b43aa0638edb62e989d07aa35d74ca82c7b5ee Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 2 May 2025 08:52:57 +0800 Subject: [PATCH 0674/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 43151b709b2..c45395818f7 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -132,7 +132,7 @@ switch (lang) { }, { "name": "🔗 打开文字链接", - "url": "%sr.replace(/(点|。)/g,\".\").replace(/[^ \\w\\-_\\.~!\\*';:@&=\\+\\$,\\/\\?#\\[\\]%]/g,\"\").replace(/.*([ ::]|^)(1[a-z0-9]{22,}).*?\\b([a-z0-9]{4}\\b|$).*/i,\"https://pan.baidu.com/s/$1?pwd=$2\").replace(/ /g,\"\").replace(/^/,\"http://\").replace(/^http:\\/\\/(https?:)/,\"$1\")", + "url": "%sr.replace(/(点|。)/g,\".\").replace(/[^\\s\\w\\-_\\.~!\\*';:@&=\\+\\$,\\/\\?#\\[\\]%]/g,\"\").replace(/https:\\/\\/pan\\.baidu\\.com\\/s\\//,\"\").replace(/.*([\\s::]|^)(1[a-z_0-9\\-]{22,})[\\s\\S]*?\\b([a-z0-9]{4}\\b|$).*/i,\"https://pan.baidu.com/s/$2?pwd=$3\").replace(/ /g,\"\").replace(/^/,\"http://\").replace(/^http:\\/\\/(https?:)/,\"$1\")", "kwFilter": "\\w\\S*\\.\\S*\\w|\\w.*[点。].*\\w|1[a-zA-Z0-9]{22,}", "description": "支持类似“pan点baidu。com😄河蟹”以及“1bP23pzUpIV4CMuoMjOfxFA提取码:prt4”的分享链接", "nobatch": true @@ -285,14 +285,9 @@ switch (lang) { "openInNewTab": true }, { - "name": "便宜服务器", - "url": "https://my.racknerd.com/aff.php?aff=12390", - "description": "性价比最高的服务器,2刀一个月" - }, - { - "name": "稳定服务器vultr", - "url": "https://www.vultr.com/?ref=7427668", - "description": "老牌 VPS 服务商,5刀一个月。胜在稳定" + "name": "☁️便宜服务器", + "url": "https://my.racknerd.com/aff.php?aff=12390&pid=903", + "description": "👍性价比最高的服务器,一年仅需11美元\n可以用支付宝付款\n已经稳定运行6年" }, { "name": "便宜域名", @@ -676,13 +671,8 @@ switch (lang) { }, { "name": "Cheap VPS", - "url": "https://my.racknerd.com/aff.php?aff=12390", - "description": "Most cost-effective server, $2 per month" - }, - { - "name": "Stable VPS", - "url": "https://www.vultr.com/?ref=7427668", - "description": "Veteran VPS provider, $5 per month, wins in stability" + "url": "https://my.racknerd.com/aff.php?aff=12390&pid=903", + "description": "Most cost-effective server, $11 per year" }, { "name": "Cheap Domain", From 3a1199b737162b52a77b5cb5ed65e05c91b4fe6d Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 4 May 2025 12:14:37 +0800 Subject: [PATCH 0675/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 38dd608f176..c81157a777f 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -534,8 +534,22 @@ var siteInfo = [ name: "Pixiv", url: /pixiv\.net|pximg\.net/, src: /pximg\.net\/c\/\d+x\d+/i, - r: /pximg\.net\/c\/\d+x\d+.*\/img\/(.*)_.*$/i, - s: ["pximg.net/img-original/img/$1.jpg","pximg.net/img-original/img/$1.png"] + r: [/pximg\.net\/c\/\d+x\d+.*\/img\/(.*)_.*$/i, /(pixiv.net\/img\d+\/img\/.+\/\d+)_[ms]\.(\w{2,5})$/i], + s: [["pximg.net/img-original/img/$1.jpg","pximg.net/img-original/img/$1.png"], + "$1.$2"], + getImage: function(a, p) { + if (this.src && a && /(\/artworks\/|member_illust\.php\?mode="|\/group\/)/.test(a.href)) { + let dateMatch = this.src.match(/\/img\/(\d+\/(\d\d\/?(?!\d{3})){5})\/(\d+)_/); + let countMatch = a.outerHTML.match(/(\d+)<\/span>/); + if (dateMatch && countMatch) { + return {all:Array(parseInt(countMatch[1])).keys().reduce( + (acc, cur) => acc.concat(`https://i.pximg.net/img-master/img/${dateMatch[1]}/${dateMatch[3]}_p${cur}_master1200.jpg`), + [] + )} + } + } + return null; + } }, { name: "Wallhaven", @@ -545,7 +559,7 @@ var siteInfo = [ /th\.wallhaven\.cc\/(small|lg)\/(.*)?\/(.*)\..*/i], s: [["wallpapers/full/wallhaven$1.jpg","wallpapers/full/wallhaven$1.png"], ["w.wallhaven.cc/full/$2/wallhaven-$3.jpg","w.wallhaven.cc/full/$2/wallhaven-$3.png"]], - getImage() { + getImage: function() { let srcReg1 = /wallpapers\/thumb\/small\/th(.*)\./i; let srcReg2 = /th\.wallhaven\.cc\/(small|lg)\/(.*)?\/(.*)\..*/i; let res1 = "wallpapers/full/wallhaven$1."; @@ -1139,12 +1153,6 @@ var siteInfo = [ if(newsrc!=this.src)return newsrc; } }, - { - name: "pixiv", - src: /pixiv\.net/i, - r: /(pixiv.net\/img\d+\/img\/.+\/\d+)_[ms]\.(\w{2,5})$/i, - s: "$1.$2" - }, { name: "douban", url: /douban\.com/i, From 83db3e7e4e99d6128145b8458fd602d4298cdd0c Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 4 May 2025 12:17:08 +0800 Subject: [PATCH 0676/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index d4a5c62c87c..72538f6245d 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.4.21.1 +// @version 2025.5.4.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1570604/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1582659/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -24182,6 +24182,7 @@ ImgOps | https://imgops.com/#b#`; if(!src)return; var ret = { + all: matchedRule.all, src: src, // 得到的src srcs: srcs, // 多个 src,失败了会尝试下一个 type: type, // 通过哪种方式得到的 @@ -24498,6 +24499,7 @@ ImgOps | https://imgops.com/#b#`; getImage: function(img, a, p, target) { var newSrc, rule; var base64Img = /^data:/i.test(img.src); + this.all = null; for (var i = 0; i < this.rules.length; i++) { rule = this.rules[i]; if (rule.src && !toRE(rule.src).test(img.src)) continue; @@ -24536,8 +24538,12 @@ ImgOps | https://imgops.com/#b#`; } if (rule.getImage) { newSrc = rule.getImage.call(target || img, a, p, rule); + if (newSrc && newSrc.all) { + this.all = newSrc.all; + newSrc = this.all[0]; + } } else newSrc = null; - if (!base64Img && rule.r && img.src) { + if (!base64Img && rule.r && img.src && !Array.isArray(newSrc)) { if (!newSrc) newSrc = img.currentSrc || img.src; newSrc = this.replaceByRule(newSrc, rule); } @@ -24913,6 +24919,11 @@ ImgOps | https://imgops.com/#b#`; throwErrorInfo(ex); } if (nsrc) { + let all; + if (nsrc && nsrc.all) { + all = nsrc.all; + nsrc = all[0]; + } let src = nsrc, imgSrc = prefs.floatBar.listenBg && hasBg(target) ? targetBg : nsrc; if (Array.isArray(nsrc) && nsrc.length == 2) { imgSrc = nsrc[0]; @@ -24939,6 +24950,7 @@ ImgOps | https://imgops.com/#b#`; } let noActual = src === imgSrc; result = { + all: all || matchedRule.all, src: src, type: matchedRule.xhrLink && noActual ? "link" : "rule", imgSrc: imgSrc, @@ -25171,6 +25183,7 @@ ImgOps | https://imgops.com/#b#`; description = attr ? node.getAttribute(attr) : (node.getAttribute('title') || node.textContent); } } + result.all = matchedRule.all; result.src = src; result.type = type; result.noActual = false; From 770f97f51221aeafe1ab3c529673dc841dffc09a Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 4 May 2025 16:07:22 +0800 Subject: [PATCH 0677/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 72538f6245d..fed456a07ea 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -23612,8 +23612,8 @@ ImgOps | https://imgops.com/#b#`; } } } - if (!limited) { - pa = this.data.img.offsetParent; + pa = this.data.img.offsetParent; + if (pa && !limited) { paPosi=pa.getBoundingClientRect(); if (paPosi.width > 30 && paPosi.height > 30) { const style = unsafeWindow.getComputedStyle(this.data.img); From da6de427f78eaa3b75adb5448b691d4fce4e7755 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 4 May 2025 19:35:32 +0800 Subject: [PATCH 0678/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 95397a2feef..4cfe385b566 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -8633,7 +8633,7 @@ }, 1); } - const loadmoreReg = /^\s*((点击)?((加载|展开)(更多|剩余)|继续加载)|(點擊)?((加載|展開)(更多|剩餘)|繼續加載)|load\s*more|もっと読み込む)[\.…▼\s\d%]*$/i; + const loadmoreReg = /^\s*((点击?)?(这里)?((看|加载|展开)(更多|剩余)|继续加载)|(點擊?)?(這裡)?((看|加載|展開)(更多|剩餘)|繼續加載)|load\s*more|もっと読み込む)[\.…▼\s\d%]*$/i; const defaultLoadmoreSel = ".loadMore,.LoadMore,[class^='load-more'],[class*=' load-more'],button.show_more,.button-show-more,button[data-testid='more-results-button'],#btn_preview_remain,.view-more-btn"; function getLoadMore(doc, loadmoreBtn) { if (!loadmoreBtn || !getBody(doc).contains(loadmoreBtn) || /less/.test(loadmoreBtn.innerText)) loadmoreBtn = null; From 828edb36835fb5a35318bbf2a0f0e2d912bbd99b Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 5 May 2025 08:48:03 +0800 Subject: [PATCH 0679/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index ecd81f87649..7e1ea1fa490 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5337,7 +5337,7 @@ "nextLink": "a[title='下一页']", "action": 2, "pageElement": "div#m_posts", - "pageAction": "doc&&doc.addEventListener('mouseover',e=>{e.preventDefault();e.stopPropagation()},true)" + "iframeInit": "win.self=win.top;" }, { "name": "NGA列表页", From b2ef3c2c4da88a8699f60b126183da542cf6092a Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Mon, 5 May 2025 00:48:20 +0000 Subject: [PATCH 0680/1065] Update version of Pagetual rules to 89 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index d22307c427b..8643cf6deba 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -88 +89 From 437b15367041d837741b0733ea63aba42039a526 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 8 May 2025 11:41:42 +0800 Subject: [PATCH 0681/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 1 + 1 file changed, 1 insertion(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 7e1ea1fa490..c88620ed120 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5337,6 +5337,7 @@ "nextLink": "a[title='下一页']", "action": 2, "pageElement": "div#m_posts", + "pageAction": "doc&&doc.addEventListener('mouseover',e=>{e.preventDefault();e.stopPropagation()},true)", "iframeInit": "win.self=win.top;" }, { From d8315656b679732ebff67eb19186b00acceb31ec Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 8 May 2025 03:51:02 +0000 Subject: [PATCH 0682/1065] Update version of Pagetual rules to 90 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 8643cf6deba..d61f00d8cad 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -89 +90 From 329cb36d4b447ba167d5388d1cea0610f7ae08b1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 7 Jun 2025 16:23:17 +0800 Subject: [PATCH 0683/1065] update --- Pagetual/pagetual.user.js | 3 ++- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 4cfe385b566..33829242e57 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3276,7 +3276,8 @@ let curHref = next4.getAttribute("href"); let curPageReg = new RegExp("(.*)" + (pageNum + 1) + afterStr.replace(/([\.\?])/g, '\\$1')); let otherPageHref = curHref.replace(curPageReg, `$1${pageNum}${afterStr}`); - let otherPageEle = body.querySelector(`a[href='${otherPageHref}']`); + let otherPageEles = body.querySelectorAll(`a[href='${otherPageHref}']`); + let otherPageEle = otherPageEles.length && otherPageEles[otherPageEles.length - 1]; if (!otherPageEle) { otherPageHref = curHref.replace(curPageReg, `$1${pageNum + 2}${afterStr}`); otherPageEle = body.querySelector(`a[href='${otherPageHref}']`); diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index fed456a07ea..41b999d6ba1 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.5.4.1 +// @version 2025.6.7.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -25217,7 +25217,7 @@ ImgOps | https://imgops.com/#b#`; if (result.imgAS.w < result.imgCS.w * 1.5 && result.imgAS.h < result.imgCS.h * 1.5) { if (result.img && result.img.childElementCount) return false; var wSize = getWindowSize(); - if (result.imgAS.w <= wSize.w && result.imgAS.h <= wSize.h) return false; + if (prefs.floatBar.globalkeys.invertInitShow && result.imgAS.w <= wSize.w && result.imgAS.h <= wSize.h) return false; } } uniqueImgWinInitX = clientX; From 2fab5d1baa47831d924a1cc7c1b251d08bd349b6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 9 Jun 2025 12:24:44 +0900 Subject: [PATCH 0684/1065] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 884aa2ccfef..909b0086f6f 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ ## Contributors - + ## Star History From 62d2877766bf7f23bce60324aaf86927c418050b Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 10 Jun 2025 09:29:37 +0900 Subject: [PATCH 0685/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index c88620ed120..21b4e912397 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5051,7 +5051,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", From f6cb6fa36e1d39db18bfee5fb81f90bb5e070168 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 10 Jun 2025 00:31:07 +0000 Subject: [PATCH 0686/1065] Update version of Pagetual rules to 91 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index d61f00d8cad..7fe4e495fed 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -90 +91 From 2fd8495eac3f956eb671cb9ad457afb55c20be92 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 10 Jun 2025 20:59:39 +0900 Subject: [PATCH 0687/1065] Update DownloadAllContent.user.js --- DownloadAllContent/DownloadAllContent.user.js | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index 3024f4af863..2f8502287a1 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -4,7 +4,7 @@ // @name:zh-TW 怠惰小説下載器 // @name:ja 怠惰者小説ダウンロードツール // @namespace hoothin -// @version 2.8.3.17 +// @version 2.8.3.18 // @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文檔 @@ -977,6 +977,7 @@ if (window.top != window.self) { charsetValid = false; } } else charsetValid = false; + var iframePool = []; function indexDownload(aEles, noSort){ if(aEles.length<1)return; initTxtDownDiv(); @@ -1034,6 +1035,16 @@ if (window.top != window.self) { item.innerText = prefix.replace(/\$i/g, ++curIndex) + item.innerText; } } + function getIframe() { + if (iframePool && iframePool.length) return iframePool.shift(); + let iframe = document.createElement('iframe'); + iframe.name = 'pagetual-iframe'; + iframe.width = '100%'; + iframe.height = '1000'; + iframe.frameBorder = '0'; + iframe.style.cssText = 'margin:0!important;padding:0!important;visibility:hidden!important;flex:0;opacity:0!important;pointer-events:none!important;position:fixed;top:0px;left:0px;z-index:-2147483647;'; + return iframe; + } var insertSigns=[]; // var j=0,rCats=[]; var downIndex=0,downNum=0,downOnce=function(wait){ @@ -1188,7 +1199,7 @@ if (window.top != window.self) { }); }; if (useIframe) { - let iframe = document.createElement('iframe'), inited = false, failedTimes = 0; + let iframe = getIframe(), inited = false, failedTimes = 0; let loadtimeout; let loadIframe = src => { iframe.src = src; @@ -1197,12 +1208,7 @@ if (window.top != window.self) { iframe.src = src; }, 20000); }; - iframe.name = 'pagetual-iframe'; - iframe.width = '100%'; - iframe.height = '1000'; - iframe.frameBorder = '0'; iframe.sandbox = iframeSandbox || "allow-same-origin allow-scripts allow-popups allow-forms"; - iframe.style.cssText = 'margin:0!important;padding:0!important;visibility:hidden!important;flex:0;opacity:0!important;pointer-events:none!important;position:fixed;top:0px;left:0px;z-index:-2147483647;'; iframe.addEventListener('load', e => { if (e.data != 'pagetual-iframe:DOMLoaded' && e.type != 'load') return; if (inited) return; @@ -1280,7 +1286,15 @@ if (window.top != window.self) { } catch(e) { console.debug("Stop as cors"); } - if (iframe && iframe.parentNode) iframe.parentNode.removeChild(iframe); + if (iframe && iframe.parentNode) { + try { + iframe.src = 'about:blank'; + } catch (e) { + console.error("Error clearing iframe src:", e); + } + iframe.parentNode.removeChild(iframe); + iframePool.push(iframe); + } } setTimeout(() => { checkIframe(); From e4b94a0c60aee41cf9de6f1f06dcb04ef9bf9575 Mon Sep 17 00:00:00 2001 From: Loss-lx <125890045+Loss-lx@users.noreply.github.com> Date: Wed, 11 Jun 2025 13:19:23 +0300 Subject: [PATCH 0688/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 21b4e912397..76157bf52fd 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -6424,5 +6424,15 @@ "action": 0, "pageElement":".web-result>li", "pagePre": "let evalData=response.match(/\\*{let ele=document.createElement('li');ele.innerHTML=`
  • ${item.title}


  • `;eles.push(ele);});return eles;" +}, + { + "name": "EpicentrK - Герметики та мастики", + "author": "epicentrkScraper", + "url": "^https?://epicentrk\\.ua/ua/shop/germetiki-i-silikony/.*$", + "example": "https://epicentrk.ua/ua/shop/germetiki-i-silikony/", + "nextlink": "div.pagination a.pagination__btn--next", + "replaceElement": "div.product-card", + "pageElement": "div.products-catalog__list", + "action": 2 } ] From 74e8016f039cf40248d1cf6af9cb0d53808e6f12 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 11 Jun 2025 20:00:56 +0900 Subject: [PATCH 0689/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 76157bf52fd..b33acd1698f 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -6425,14 +6425,14 @@ "pageElement":".web-result>li", "pagePre": "let evalData=response.match(/\\*{let ele=document.createElement('li');ele.innerHTML=`
  • ${item.title}


  • `;eles.push(ele);});return eles;" }, - { - "name": "EpicentrK - Герметики та мастики", - "author": "epicentrkScraper", - "url": "^https?://epicentrk\\.ua/ua/shop/germetiki-i-silikony/.*$", - "example": "https://epicentrk.ua/ua/shop/germetiki-i-silikony/", - "nextlink": "div.pagination a.pagination__btn--next", - "replaceElement": "div.product-card", - "pageElement": "div.products-catalog__list", - "action": 2 +{ + "name": "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 } ] From a64352956f9adf460554875fde06070a3d4e3de8 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Wed, 11 Jun 2025 11:01:42 +0000 Subject: [PATCH 0690/1065] Update version of Pagetual rules to 92 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 7fe4e495fed..cd5b0252729 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -91 +92 From f9de0350c2ed7bbe28cfd3009da66981b78a1c6f Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 14 Jun 2025 14:41:23 +0900 Subject: [PATCH 0691/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 33829242e57..f48936ed079 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -109,6 +109,7 @@ [].forEach.call(document.querySelectorAll("video"), video => { video.removeAttribute && video.removeAttribute("autoplay"); video.pause && video.pause(); + video.muted = true; }); }, 1000); }; @@ -3597,7 +3598,7 @@ this.nextLinkHref = false; return null; } - let video = document.querySelector("video,iframe[id*=play],[id*=play]>iframe,iframe[src*=player],iframe[src*=m3u8]"); + let video = document.querySelector("video,#videoContainer,iframe[id*=play],[id*=play]>iframe,iframe[src*=player],iframe[src*=m3u8]"); if (video) { if (video.offsetParent && video.name !== 'pagetual-iframe') { let scrollWidth = video.scrollWidth || video.offsetWidth; @@ -8439,7 +8440,7 @@ }, 100); requestAnimationFrame(() => { let curScroll = document.documentElement.scrollTop || document.body.scrollTop; - if (curScroll <= 20) { + if (curScroll && curScroll <= 50) { if (sideController.inited && sideController.pagenum.innerHTML !== "1") { sideController.pagenum.innerHTML = createHTML("1"); } From e490cc76175b26754ceb7c49864eb2fa2b7cfa1c Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 17 Jun 2025 13:34:47 +0900 Subject: [PATCH 0692/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index f48936ed079..fad04b9beb9 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -8439,8 +8439,9 @@ scrolling = false; }, 100); requestAnimationFrame(() => { - let curScroll = document.documentElement.scrollTop || document.body.scrollTop; - if (curScroll && curScroll <= 50) { + let curScroll = document.documentElement.scrollTop || getBody(document).scrollTop; + let scrollH = Math.max(document.documentElement.scrollHeight, getBody(document).scrollHeight); + if (scrollH && curScroll <= 60) { if (sideController.inited && sideController.pagenum.innerHTML !== "1") { sideController.pagenum.innerHTML = createHTML("1"); } From 40b141997dd6c066cbfcfddaa9160ec508b89cf5 Mon Sep 17 00:00:00 2001 From: Miyuki <50022810+Boxkun@users.noreply.github.com> Date: Fri, 20 Jun 2025 02:41:14 +0800 Subject: [PATCH 0693/1065] Update pvcep_rules.js Updated rules for Gelbooru --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index c81157a777f..43df6aade64 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -930,7 +930,7 @@ var siteInfo = [ url: /gelbooru\.com/, src: /(thumbnails|samples)\/(.*)\/(thumbnail|sample)_/i, r: /.*\/(thumbnails|samples)\/(.*)\/(thumbnail|sample)_(.*)\..*/i, - s: ["https://img3.gelbooru.com/images/$2/$4.png","https://img3.gelbooru.com/images/$2/$4.jpg"] + s: ["https://img4.gelbooru.com/images/$2/$4.png","https://img4.gelbooru.com/images/$2/$4.jpg"] }, { name: "donmai", From 039c38048587fa2c5e9c35836d8b111d00ee5e47 Mon Sep 17 00:00:00 2001 From: Miyuki <50022810+Boxkun@users.noreply.github.com> Date: Sun, 22 Jun 2025 02:57:21 +0800 Subject: [PATCH 0694/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 43df6aade64..52c203ea199 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -930,7 +930,7 @@ var siteInfo = [ url: /gelbooru\.com/, src: /(thumbnails|samples)\/(.*)\/(thumbnail|sample)_/i, r: /.*\/(thumbnails|samples)\/(.*)\/(thumbnail|sample)_(.*)\..*/i, - s: ["https://img4.gelbooru.com/images/$2/$4.png","https://img4.gelbooru.com/images/$2/$4.jpg"] + s: ["https://img4.gelbooru.com/images/$2/$4.png","https://img4.gelbooru.com/images/$2/$4.jpg","https://img4.gelbooru.com/images/$2/$4.jpeg"] }, { name: "donmai", From f095ca579a683dfb81b025824ff794d16c2caf8f Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 24 Jun 2025 18:29:33 +0900 Subject: [PATCH 0695/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 41b999d6ba1..01c37fe5b7d 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.6.7.1 +// @version 2025.6.24.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1582659/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1613188/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -22357,7 +22357,7 @@ ImgOps | https://imgops.com/#b#`; }, focusedKeyup:function(e){ var keyCode=e.keyCode; - var valid=[32,18,16,72,17,72,82,90,67,37,39]; + var valid=[27,32,18,16,72,17,72,82,90,67,37,39]; if(valid.indexOf(keyCode)==-1)return; if (window.getSelection().toString()) return; @@ -22422,6 +22422,12 @@ ImgOps | https://imgops.com/#b#`; case 37: this.switchImage(false); break; + case 27: + if (prefs.imgWindow.close.escKey) { + this.remove(); + e.stopPropagation(); + } + break; default:break; }; @@ -22543,9 +22549,6 @@ ImgOps | https://imgops.com/#b#`; clearTimeout(this.ctrlkeyDownTimer); }break; case 27:{//ese关闭窗口 - if(prefs.imgWindow.close.escKey){ - this.remove(); - }; }break; default:break; } From e8787824cbbc62933e4be2b857d58b6268a18ae0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 24 Jun 2025 19:08:06 +0900 Subject: [PATCH 0696/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 52c203ea199..93d326e4838 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1646,7 +1646,7 @@ var siteInfo = [ }, { name: "Bangumi", - url: /^https:\/\/bgm\.tv\//, + url: /^https:\/\/(bgm|bangumi)\.tv\//, r: ["/c/","/m/"], s: "/l/" }, From 345e20d7e76c4fcb8e63ca2471eca59600166ef5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 24 Jun 2025 19:10:44 +0900 Subject: [PATCH 0697/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 01c37fe5b7d..db0c6e5d5d2 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1613188/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1613206/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From 0ee0b5fa36850e9d9c595189025c05754589a8b3 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 28 Jun 2025 11:31:12 +0900 Subject: [PATCH 0698/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index b33acd1698f..fa567243728 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -4783,7 +4783,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 " }, { @@ -4792,7 +4792,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 From 5d6128e968cadf8f11d955a0f24cc1de37616541 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 28 Jun 2025 02:31:28 +0000 Subject: [PATCH 0699/1065] Update version of Pagetual rules to 93 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index cd5b0252729..c67f579c9a8 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -92 +93 From 1a130033d52228752124d0624813aa78832cd04f Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 29 Jun 2025 17:35:57 +0900 Subject: [PATCH 0700/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index db0c6e5d5d2..234a39dc5ea 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.6.24.1 +// @version 2025.6.29.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -24795,7 +24795,7 @@ ImgOps | https://imgops.com/#b#`; try { selStr = !selectionClientRect && selectionStr; }catch(e){} - if (selStr) return false; + if (selStr && selStr != "\n") return false; let keyActive=(prefs.floatBar.globalkeys.type == "hold" && checkGlobalKeydown(e)) || (prefs.floatBar.globalkeys.type == "press" && globalFuncEnabled); return prefs.floatBar.globalkeys.invertInitShow?!keyActive:keyActive; From 6656343299ca1552663fdc7909ad3da8c40937bf Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 29 Jun 2025 17:50:17 +0900 Subject: [PATCH 0701/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 234a39dc5ea..77dad430db5 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.6.29.1 +// @version 2025.6.29.2 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -25123,7 +25123,7 @@ ImgOps | https://imgops.com/#b#`; }; found = true; break; - } else if (ele.nodeName.toUpperCase() == 'CANVAS') { + } else if (target.nodeName.toUpperCase() != 'A' && ele.nodeName.toUpperCase() == 'CANVAS') { let src = ele.src || ele.dataset.src; if (src) { target = ele; From ee08e802bef79be0ceb56d92852c940c6a1707c3 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 29 Jun 2025 19:05:44 +0900 Subject: [PATCH 0702/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 93d326e4838..cd40402fd3c 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -425,7 +425,7 @@ var siteInfo = [ { name: '知乎', url: /(zhihu|zhimg)\.com/, - r: /_(b|xs|s|l|\d+(x\d+|w))\./i, + r: /_(b|qhd|xs|s|l|\d+(x\d+|w))\./i, s: "." }, { From 759e0ae415232250f9f7f9a8bcee181d5ee25c74 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 29 Jun 2025 19:06:33 +0900 Subject: [PATCH 0703/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 77dad430db5..d2aa1074583 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1613206/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1615955/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -25217,7 +25217,7 @@ ImgOps | https://imgops.com/#b#`; var checkUniqueImgWin = function() { if (canPreview) { if (result.type != "link" && result.type != "rule" && result.src == result.imgSrc) { - if (result.imgAS.w < result.imgCS.w * 1.5 && result.imgAS.h < result.imgCS.h * 1.5) { + if (result.imgAS.w < result.imgCS.w * 1.6 && result.imgAS.h < result.imgCS.h * 1.6) { if (result.img && result.img.childElementCount) return false; var wSize = getWindowSize(); if (prefs.floatBar.globalkeys.invertInitShow && result.imgAS.w <= wSize.w && result.imgAS.h <= wSize.h) return false; From 4a16a5467352e1de75254d73636cbb40c43c07b5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 30 Jun 2025 17:39:07 +0900 Subject: [PATCH 0704/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index d2aa1074583..4bd5fb1cfcc 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -13325,6 +13325,12 @@ ImgOps | https://imgops.com/#b#`; loadEnd.call(img,e); }; }; + iRReadyFn = iRReadyFn.filter(function(item) { + return item !== readyHandler + }); + isrcs = isrcs.filter(function(item) { + return item !== src + }); }break; case 'ready':{ if(!ready || readyHandler.done)return; @@ -13354,6 +13360,12 @@ ImgOps | https://imgops.com/#b#`; img:img, abort:function(){ if(!loadEndDone){ + iRReadyFn = iRReadyFn.filter(function(item) { + return item !== readyHandler + }); + isrcs = isrcs.filter(function(item) { + return item !== src + }); aborted=true; removeListener(); img.src= prefs.icons.brokenImg_small; @@ -25387,7 +25399,7 @@ ImgOps | https://imgops.com/#b#`; if (!canPreview) return; let target = e.target; if (target.nodeName == "PICTURE"){ - target = target.querySelector("img") || target; + target = target.lastElementChild || target; } if (target.nodeName != 'IMG') return; } From 220eb1ea63d9919de970cb15eb5557c02d1c846f Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 2 Jul 2025 20:58:28 +0900 Subject: [PATCH 0705/1065] Update DownloadAllContent.user.js --- DownloadAllContent/DownloadAllContent.user.js | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index 2f8502287a1..cf621899843 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -2,7 +2,7 @@ // @name DownloadAllContent // @name:zh-CN 怠惰小说下载器 // @name:zh-TW 怠惰小説下載器 -// @name:ja 怠惰者小説ダウンロードツール +// @name:ja 怠惰小説ダウンローダー // @namespace hoothin // @version 2.8.3.18 // @description Lightweight web scraping script. Fetch and download main textual content from the current page, provide special support for novels @@ -397,6 +397,57 @@ if (window.top != window.self) { 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: i18n={ fetch:"Download", From 0529d84deded25099ea39dd69b92fa369d5bd560 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 5 Jul 2025 09:18:12 +0900 Subject: [PATCH 0706/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index fad04b9beb9..88dd0f6bc93 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -7049,7 +7049,8 @@ blacklistInput.style.height = "500px"; blacklistInput.style.display = "none"; blacklistInput.spellcheck = false; - blacklistInput.placeholder = "http://*.xxx.com/*/y\n/^https?://.*\\.xxx\\.com/i \t\t<= Regexp\n//http://*.aaa.com/ \t\t<= Disable\n/*http://*.bbb.com\nhttp://*.ccc.com*/ \t\t<= Block comment"; + blacklistInput.placeholder = "http://*.xxx.com/*/y\n\n/^https?://.*\\.xxx\\.com/i \t\t<= Regexp\n\n// http://*.aaa.com/ \t\t<= Disable\n\n/* http://*.bbb.com\nhttp://*.ccc.com\nhttp://*.ddd.com */ \t\t<= Block comment"; + blacklistInput.title = blacklistInput.placeholder; blacklistInput.value = rulesData.blacklist ? rulesData.blacklist.join("\n") : ""; let blacklistBtn = document.createElement("button"); blacklistBtn.innerText = i18n("editBlacklist"); @@ -7463,6 +7464,11 @@ forceState == 1; return; } + } else if (curGlob.indexOf("^") == 0) { + if (new RegExp(curGlob).test(href)) { + forceState == 1; + return; + } } else if (globMatch(curGlob, href)) { forceState == 1; return; From 898a2b2689444d5b10e9b4576c2a5f3bd463f0a3 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 5 Jul 2025 13:51:31 +0900 Subject: [PATCH 0707/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 4bd5fb1cfcc..d035eb56258 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.6.29.2 +// @version 2025.7.5.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -17870,6 +17870,11 @@ ImgOps | https://imgops.com/#b#`; try { src = decodeURIComponent(src); } catch (e) {} + } else if (/[&\?]https?:/.test(src)) { + src = src.replace(/.*[&\?](https?:)/, "$1"); + try { + src = decodeURIComponent(src); + } catch (e) {} } node.src = src; linkMedias.push(node); @@ -24158,6 +24163,11 @@ ImgOps | https://imgops.com/#b#`; try { src = decodeURIComponent(src); } catch (e) {} + } else if (/[&\?]https?:/.test(src)) { + src = src.replace(/.*[&\?](https?:)/, "$1"); + try { + src = decodeURIComponent(src); + } catch (e) {} } } if(src)type='tpRule'; @@ -25287,6 +25297,11 @@ ImgOps | https://imgops.com/#b#`; try { src = decodeURIComponent(src); } catch (e) {} + } else if (/[&\?]https?:/.test(src)) { + src = src.replace(/.*[&\?](https?:)/, "$1"); + try { + src = decodeURIComponent(src); + } catch (e) {} } result = { src: src, From 2d640312b2639cf9aef4fd98132ac345fcca208c Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 6 Jul 2025 08:49:23 +0900 Subject: [PATCH 0708/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 88dd0f6bc93..c4587f7a30a 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -8858,6 +8858,7 @@ if (e.target !== pageText) return; if (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) return; e.preventDefault(); + e.stopPropagation(); let nextEle = pageBar && pageBar.nextElementSibling; if (nextEle && nextEle.name == 'pagetual-iframe') { if (curForceIframe == nextEle) { From 2bdd6bfb1c95399e8ab71470103defecff958f6c Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 7 Jul 2025 16:38:56 +0900 Subject: [PATCH 0709/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index c4587f7a30a..d62c465c476 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -7036,7 +7036,9 @@ ruleParser.customRules.unshift(rulesData.editTemp); rulesData.editTemp = null; storage.setItem("rulesData", rulesData); - customRulesInput.previousElementSibling.scrollIntoView(); + setTimeout(() => { + customRulesInput.previousElementSibling.scrollIntoView(); + }, 300); } customRulesInput.style.width = "100%"; customRulesInput.style.height = "800px"; From da7e6bf6dec98b58911bd57c4ebbcc99c6fb2a5b Mon Sep 17 00:00:00 2001 From: Miyuki <50022810+Boxkun@users.noreply.github.com> Date: Tue, 8 Jul 2025 02:29:08 +0800 Subject: [PATCH 0710/1065] Update pvcep_rules.js Add GIF rules for Gelbooru --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index cd40402fd3c..ad9b6e3b70e 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -930,7 +930,7 @@ var siteInfo = [ url: /gelbooru\.com/, src: /(thumbnails|samples)\/(.*)\/(thumbnail|sample)_/i, r: /.*\/(thumbnails|samples)\/(.*)\/(thumbnail|sample)_(.*)\..*/i, - s: ["https://img4.gelbooru.com/images/$2/$4.png","https://img4.gelbooru.com/images/$2/$4.jpg","https://img4.gelbooru.com/images/$2/$4.jpeg"] + s: ["https://img4.gelbooru.com/images/$2/$4.png","https://img4.gelbooru.com/images/$2/$4.jpg","https://img4.gelbooru.com/images/$2/$4.jpeg","https://img4.gelbooru.com/images/$2/$4.gif"] }, { name: "donmai", From 370ddb63932eeb51a7ced49c09d1fb4f349c4bed Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 8 Jul 2025 16:06:07 +0900 Subject: [PATCH 0711/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index d62c465c476..b7f74793822 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -1472,7 +1472,7 @@ const ruleImportUrlReg = /greasyfork\.org\/.*scripts\/438684(\-[^\/]*)?(\/discussions|\/?$|\/feedback)|github\.com\/hoothin\/UserScripts\/(tree\/master\/Pagetual|issues)|^https:\/\/pagetual\.hoothin\.com\/.*firstRun\.html/i; const allOfBody = "body>*"; const mainSel = ["article,.article","[role=main],main,.main,#main","#results"]; - const nextTextReg1 = new RegExp("\u005e\u7ffb\u003f\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u2500\u0031\u005d\u003f\u005b\u9875\u9801\u5f20\u5f35\u005d\u007c\u005e\u006e\u0065\u0078\u0074\u005b\u005c\u005c\u0073\u005f\u002d\u005d\u003f\u0070\u0061\u0067\u0065\u005c\u005c\u0073\u002a\u005b\u203a\u003e\u2192\u00bb\u005d\u003f\u0024\u007c\u6b21\u306e\u30da\u30fc\u30b8\u007c\u005e\u6b21\u3078\u003f\u0024\u007c\u0412\u043f\u0435\u0440\u0435\u0434\u007c\u005e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435", "i"); + const nextTextReg1 = new RegExp("\u005e\u7ffb\u003f\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u2500\u0031\u005d\u003f\u005b\u9875\u9801\u5f20\u5f35\u005d\u007c\u005e\u006e\u0065\u0078\u0074\u005b\u005c\u0073\u005f\u002d\u005d\u003f\u0070\u0061\u0067\u0065\u005c\u0073\u002a\u005b\u203a\u003e\u2192\u00bb\u005d\u003f\u0024\u007c\u6b21\u306e\u30da\u30fc\u30b8\u007c\u005e\u6b21\u3078\u003f\u0024\u007c\u0412\u043f\u0435\u0440\u0435\u0434\u007c\u005e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435", "i"); const nextTextReg2 = new RegExp("\u005e\u0028\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u2500\u0031\u005d\u003f\u005b\u7ae0\u8bdd\u8a71\u8282\u7bc0\u5e45\u005d\u007c\u006e\u0065\u0078\u0074\u002e\u003f\u0063\u0068\u0061\u0070\u0074\u0065\u0072\u0029\u0028\u005b\u003a\uff1a\u005c\u002d\u005f\u2014\u005c\u0073\u005c\u002e\u3002\u003e\u0023\u00b7\u005c\u005b\u3010\u3001\uff08\u005c\u0028\u002f\u002c\uff0c\uff1b\u003b\u2192\u005d\u007c\u0024\u0029", "i"); const nextTextReg3 = /^(next\s*(»|>>|>|›|→|❯|\d+)?|>|▶|>|›|→|❯)\s*$/i; const prevReg = new RegExp("\u005e\u005c\u0073\u002a\u0028\u005b\u4e0a\u524d\u9996\u5c3e\u005d\u007c\u0070\u0072\u0065\u0076\u007c\u0065\u006e\u0064\u0029", "i"); From 07071a41064639187388da8680be2a114307e4b4 Mon Sep 17 00:00:00 2001 From: Xinjie Shen Date: Tue, 8 Jul 2025 15:38:44 +0800 Subject: [PATCH 0712/1065] fix: nhentai rules --- Pagetual/pagetualRules.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index fa567243728..61e2ca77c0c 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -2746,10 +2746,10 @@ }, { "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 + "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", From 1d7f98cffc77fbf2404dd7320cd278be0e80a534 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 8 Jul 2025 17:32:53 +0900 Subject: [PATCH 0713/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index b7f74793822..6d881e425c4 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2436,21 +2436,30 @@ } } if (!pageElement || pageElement.length === 0) { - pageElementSel = pageElementSel.replace(/:nth-of-type\(\d+\)/g, ""); - pageElement = getAllElements(pageElementSel, doc); + let pageElementSelTrim = pageElementSel.replace(/:nth-of-type\(\d+\)/g, ""); + pageElement = getAllElements(pageElementSelTrim, doc); if (pageElement && pageElement.length === 1) { if (targetChild) { pageElement = pageElement.children; } - this.curSiteRule.pageElement = pageElementSel + (targetChild ? ">*" : ""); + this.curSiteRule.pageElement = pageElementSelTrim + (targetChild ? ">*" : ""); } else if (!pageElement || pageElement.length === 0) { - pageElementSel = pageElementSel.replace(/[^\s\>]+\+/g, ""); - pageElement = getAllElements(pageElementSel, doc); + pageElementSelTrim = pageElementSel.replace(/[^\s\>]+\+/g, ""); + pageElement = getAllElements(pageElementSelTrim, doc); if (pageElement && pageElement.length === 1) { if (targetChild) { pageElement = pageElement.children; } - this.curSiteRule.pageElement = pageElementSel + (targetChild ? ">*" : ""); + this.curSiteRule.pageElement = pageElementSelTrim + (targetChild ? ">*" : ""); + } else if (!pageElement || pageElement.length === 0) { + pageElementSelTrim = pageElementSel.replace(/\.[\w\-_]+/g, ""); + pageElement = getAllElements(pageElementSelTrim, doc); + if (pageElement && pageElement.length === 1) { + if (targetChild) { + pageElement = pageElement.children; + } + this.curSiteRule.pageElement = pageElementSelTrim + (targetChild ? ">*" : ""); + } } } } From 3ff79fa4f7973d7f1da4b45d4bfa1c83d99adb65 Mon Sep 17 00:00:00 2001 From: Xinjie Shen Date: Tue, 8 Jul 2025 18:05:20 +0800 Subject: [PATCH 0714/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 61e2ca77c0c..81474810a9b 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -2746,6 +2746,13 @@ }, { "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", From 34b4158013c5807aa0bc90d3bf8236cb271cfb85 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 8 Jul 2025 11:42:39 +0000 Subject: [PATCH 0715/1065] Update version of Pagetual rules to 94 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index c67f579c9a8..49541f72104 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -93 +94 From 8aeb7068648ef646f5712aaef5bd50b34d71e9d9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 9 Jul 2025 08:45:53 +0900 Subject: [PATCH 0716/1065] Update README.md --- DownloadAllContent/README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/DownloadAllContent/README.md b/DownloadAllContent/README.md index ea4e93b7e11..20a8e698800 100644 --- a/DownloadAllContent/README.md +++ b/DownloadAllContent/README.md @@ -15,6 +15,7 @@ + 打開小說目錄頁、論壇或貼吧內容頁 + 按下 `CTRL+F9` 或點擊命令菜單 + 按下 `SHIFT+CTRL+F9` 忽略目錄,僅下載當前頁 ++ 建議打開`下載前顯示章節篩選排序視窗` 若是遇到下載出錯的站點,可隨意提交 issue 至 [Github](https://github.com/hoothin/UserScripts/)。請幫我點亮 Star ! @@ -34,10 +35,10 @@ **CTRL+F9** 就完事了唄。 ### 第二層心法(超易) - 倘若章節連結沒有xx章、xx節、xx話之類的特徵字樣,可點擊**自定義下載**,輸入隨便一個章節名,例如 「眾神的風車」,即可標記所有同級連結為目錄章節並下載。假如頁面有兩套章節格式,也可標記多個,例如「眾神的風車,風車的眾神」。亦可標記排除項,例如「眾神的風車01!02!03,風車的眾神!鐵幕」,代表標記「眾神的風車01」同級連結並排除含有 02 的項和含有 03 的項,同時標記「風車的眾神」同級連結並排除含有「鐵幕」的項。 + 倘若章節連結沒有xx章、xx節、xx話之類的特徵字樣,可點擊**自定義下載**,輸入隨便一個章節名,例如 「`眾神的風車`」,即可標記所有同級連結為目錄章節並下載。假如頁面有兩套章節格式,也可標記多個,例如「`眾神的風車,風車的眾神`」。亦可標記排除項,例如「`眾神的風車01!02!03,風車的眾神!鐵幕`」,代表標記「眾神的風車01」同級連結並排除含有 02 的項和含有 03 的項,同時標記「風車的眾神」同級連結並排除含有「鐵幕」的項。 ### 第三層心法(略易) - 如果內頁沒有正文,但章節連結與真實內容連結有關聯,可通過**自定義下載**,替換連結內容獲取真實內容。例如 【`眾神的風車@@articles@@articlescontent`】,即可替換章節 URL 中的 articles 為 articlescontent 並自動獲取內容。 + 如果內頁沒有正文,但章節連結與真實內容連結有關聯,可通過**自定義下載**,替換連結內容獲取真實內容。例如 「`眾神的風車@@articles@@articlescontent`」,即可替換章節 URL 中的 articles 為 articlescontent 並自動獲取內容。 ### 第四層心法(略難) 如果連結無法由直接替換得到最終地址,可用正則替換,例如【`眾神的風車@@articles(\d+)@@articlescontent_$1b`】,即可替換章節 URL 中的 articles1、articles2 為 @@ -45,6 +46,8 @@ ### 第五層心法(難) 輸入章節的 css 選擇器可以更精確地標記章節連結。例如`.l_chaptname>a`,代表 class 為 l_chaptname 的元素下的 a 連結。 + 如果有内分頁,且無法用正則提取下一頁連結,可直接用選擇器來獲取,例如`.l_chaptname>a@@@@@@next:{.curr+a}`。 + 如果正文提取錯誤,亦可使用選擇器來獲取,例如`.l_chaptname>a@@@@@@@div#content`。 下載內容可能含有幹擾碼,此時只需點擊**懶人小說下載設置**,輸入幹擾碼的 css 選擇器即可排除幹擾碼。例如 `.mask,.ksam,font.jammer`,代表刪除 class 為 mask 或者 ksam 的元素或者 class 為 jammer 的 font 元素。 ### 第六層心法(超難) @@ -52,7 +55,7 @@ 如果返回 false,代表異步回調,可自行抓取內容並等待抓取成功後用 cb(content) 返回抓取到的 content。 - 倘若章節沒有連結,點擊後方纔生成連結跳轉,可通過 `>>` 管道處理抓取到的元素生成章節連結,詳情見下方例子。 + 倘若章節沒有連結,點擊後方纔生成連結跳轉,可通過 `>>` 管道處理抓取到的元素生成章節連結,例如`a.link >> item.href = xxx; return item;`。詳情見下方例子。 ### 第七層心法(極難) 倘若正文已經經過加密,需要解密才能獲取正確內容,可打開瀏覽器的控製臺,自定義 dacProcess 函數,調取頁面中網站自身的解密代碼處理抓取的加密數據。例如控製臺輸入`dacProcess=data=>{return decrypt(xxx);}` 代表調用網站的 decrypt 解密章節頁面返回的數據。然後再點擊**自定義下載**,需要注意自定義下載時標記章節是必需的。 From e0f3b53d6d03b7cd79ab010859bee2c68c0a1887 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 9 Jul 2025 08:47:56 +0900 Subject: [PATCH 0717/1065] Update DownloadAllContent.user.js --- DownloadAllContent/DownloadAllContent.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index cf621899843..e33a2ae3275 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -1157,7 +1157,7 @@ if (window.top != window.self) { } } let base = doc.querySelector("base"); - let nextPages = !disableNextPage && !processFunc && await checkNextPage(doc, base ? base.href : aTag.href); + let nextPages = !disableNextPage && (!processFunc || nextPageFunc) && await checkNextPage(doc, base ? base.href : aTag.href); if (nextPages) { if (!nextPages.length) nextPages = [nextPages]; nextPages.forEach(nextPage => { From 398b3797fa99147b6b12d9c7546390495c15678f Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 9 Jul 2025 08:48:14 +0900 Subject: [PATCH 0718/1065] Update README.md --- DownloadAllContent/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DownloadAllContent/README.md b/DownloadAllContent/README.md index 20a8e698800..6905113b430 100644 --- a/DownloadAllContent/README.md +++ b/DownloadAllContent/README.md @@ -47,7 +47,7 @@ 輸入章節的 css 選擇器可以更精確地標記章節連結。例如`.l_chaptname>a`,代表 class 為 l_chaptname 的元素下的 a 連結。 如果有内分頁,且無法用正則提取下一頁連結,可直接用選擇器來獲取,例如`.l_chaptname>a@@@@@@next:{.curr+a}`。 - 如果正文提取錯誤,亦可使用選擇器來獲取,例如`.l_chaptname>a@@@@@@@div#content`。 + 如果正文提取錯誤,亦可使用選擇器來獲取,例如`.l_chaptname>a@@@@@@@div#content`或者`.l_chaptname>a@@@@@@next:{.curr+a}@div#content`。 下載內容可能含有幹擾碼,此時只需點擊**懶人小說下載設置**,輸入幹擾碼的 css 選擇器即可排除幹擾碼。例如 `.mask,.ksam,font.jammer`,代表刪除 class 為 mask 或者 ksam 的元素或者 class 為 jammer 的 font 元素。 ### 第六層心法(超難) From dcd46200588e41a306962fe7773791d9d2fae4a8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 9 Jul 2025 09:08:40 +0900 Subject: [PATCH 0719/1065] Update README.md --- DownloadAllContent/README.md | 64 ++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/DownloadAllContent/README.md b/DownloadAllContent/README.md index 6905113b430..df53d45a953 100644 --- a/DownloadAllContent/README.md +++ b/DownloadAllContent/README.md @@ -1,29 +1,29 @@ -起點等都推薦用這個腳本[【小說】下載腳本](https://github.com/dodying/UserJs/tree/master/novel/novelDownloader),遇到沒人願意適配的小站再考慮我的腳本。 +起點等主流網站建議優先使用這個腳本[【小說】下載腳本](https://github.com/dodying/UserJs/tree/master/novel/novelDownloader),如果遇到沒有人願意支援的小網站,再考慮我的腳本。。 -勿用于版權站,如造成侵權或對象站點損失,後果自負。 +請勿用於有版權的網站,如造成侵權或對目標網站造成損失,後果請自行負責。 -輕量級抓取腳本,用於下載網頁小説或其他文字內容,理論上通用於任何靜態寫入正文的小說網站、論壇、貼吧等而無需規則。 +輕量級抓取腳本,用於下載網路小說或其他文字內容。理論上,它通用於任何將內文靜態寫入網頁的小說網站、論壇、貼吧等,且無須另外設定規則。 -腳本會自動檢索頁面中的主要內容並下載(省得複製完gal攻略還要手動逐條刪除「某某某13級頭銜水龍王發表於X年X月X日來自XX客戶端」)。 -如果位於小說目錄頁會遍歷所有章節並排序拼接後存為TXT文檔。 +腳本會自動偵測並下載頁面中的主要內容(省得複製完gal攻略還要手動逐條刪除「某某某13級頭銜水龍王發表於X年X月X日來自XX客戶端」)。 +如果當前在小說目錄頁,腳本會遍歷所有章節,排序後串接成一個 TXT 文字檔。 [![img](https://img.shields.io/github/stars/hoothin/UserScripts?style=social)](https://github.com/hoothin/UserScripts#StarMe) ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) --- # 操作說明 -+ 打開小說目錄頁、論壇或貼吧內容頁 -+ 按下 `CTRL+F9` 或點擊命令菜單 -+ 按下 `SHIFT+CTRL+F9` 忽略目錄,僅下載當前頁 -+ 建議打開`下載前顯示章節篩選排序視窗` ++ 開啟小說目錄頁、論壇或貼吧的內容頁面 ++ 按下 `CTRL+F9` 或點擊使用者腳本管理器中的指令選單 ++ 按下 `SHIFT+CTRL+F9` 可忽略目錄,僅下載當前頁面 ++ 建議開啟`下載前顯示章節篩選排序視窗`的選項 -若是遇到下載出錯的站點,可隨意提交 issue 至 [Github](https://github.com/hoothin/UserScripts/)。請幫我點亮 Star ! +如果遇到下載出錯的網站,歡迎到 [Github](https://github.com/hoothin/UserScripts/) 提交 issue。也請順手幫我點亮 Star! -*對你有幫助的話,可透過 [![i](https://static.afdiancdn.com/favicon.ico) 愛發電](https://afdian.com/a/hoothin) 或者 [![i](https://ko-fi.com/favicon-32x32.png) Ko-fi](https://ko-fi.com/hoothin) 請我喝一杯奶茶。歡迎加入 [💬Discord 群組](https://discord.com/invite/keqypXC6wD)。* +*對你有幫助的話,可透過 [![i](https://static.afdiancdn.com/favicon.ico) 愛發電](https://afdian.com/a/hoothin) 或者 [![i](https://ko-fi.com/favicon-32x32.png) Ko-fi](https://ko-fi.com/hoothin) 請我喝一杯奶茶。也歡迎加入 [💬Discord 群組](https://discord.com/invite/keqypXC6wD)。* ![donate](https://s2.loli.net/2023/02/06/afTMxeASm48z5vE.jpg) -[怠惰小説下載器 ZIP 擴充](https://greasyfork.org/scripts/476943) 下載時分章節保存 TXT 並打包為 ZIP +[怠惰小説下載器 ZIP 擴充](https://greasyfork.org/scripts/476943) 下載時將各章節分別存為 TXT,並打包成 ZIP 檔 [圖片驗證碼辨識](https://github.com/hoothin/ImgCodeCheck) 開啟`保留內文圖片的網址`後配合 ZIP 擴充可自動轉換圖片文字,詳閱[愛發電](https://afdian.com/p/c7fc3abc8e8411ee9b1852540025c377) @@ -35,43 +35,43 @@ **CTRL+F9** 就完事了唄。 ### 第二層心法(超易) - 倘若章節連結沒有xx章、xx節、xx話之類的特徵字樣,可點擊**自定義下載**,輸入隨便一個章節名,例如 「`眾神的風車`」,即可標記所有同級連結為目錄章節並下載。假如頁面有兩套章節格式,也可標記多個,例如「`眾神的風車,風車的眾神`」。亦可標記排除項,例如「`眾神的風車01!02!03,風車的眾神!鐵幕`」,代表標記「眾神的風車01」同級連結並排除含有 02 的項和含有 03 的項,同時標記「風車的眾神」同級連結並排除含有「鐵幕」的項。 + 倘若章節連結沒有xx章、xx節、xx話之類的特徵字樣,可點擊**自訂下載**,輸入任意一個章節名稱,例如 「`眾神的風車`」,即可標記所有同級的連結為目錄章節並下載。假如頁面有兩種章節格式,也可以標記多個,例如「`眾神的風車,風車的眾神`」。亦可標記排除項,例如「`眾神的風車01!02!03,風車的眾神!鐵幕`」,這代表:標記「眾神的風車01」的同級連結,但排除其中含有「02」和「03」的項目;同時標記「風車的眾神」的同級連結,並排除含有「鐵幕」的項目。 ### 第三層心法(略易) - 如果內頁沒有正文,但章節連結與真實內容連結有關聯,可通過**自定義下載**,替換連結內容獲取真實內容。例如 「`眾神的風車@@articles@@articlescontent`」,即可替換章節 URL 中的 articles 為 articlescontent 並自動獲取內容。 + 如果內頁沒有正文,但章節連結與真實內容連結有關聯,可透過**自訂下載**,替換連結內容來獲取真實內容。例如輸入 「`眾神的風車@@articles@@articlescontent`」,即可替換章節 URL 中的 articles 為 articlescontent 並自動獲取內容。 ### 第四層心法(略難) - 如果連結無法由直接替換得到最終地址,可用正則替換,例如【`眾神的風車@@articles(\d+)@@articlescontent_$1b`】,即可替換章節 URL 中的 articles1、articles2 為 + 如果連結無法由直接替換得到最終網址,可用正規表示式替換,例如【`眾神的風車@@articles(\d+)@@articlescontent_$1b`】,即可替換章節 URL 中的 articles1、articles2 為 `articlescontent_1b、articlescontent_2b` ### 第五層心法(難) 輸入章節的 css 選擇器可以更精確地標記章節連結。例如`.l_chaptname>a`,代表 class 為 l_chaptname 的元素下的 a 連結。 - 如果有内分頁,且無法用正則提取下一頁連結,可直接用選擇器來獲取,例如`.l_chaptname>a@@@@@@next:{.curr+a}`。 - 如果正文提取錯誤,亦可使用選擇器來獲取,例如`.l_chaptname>a@@@@@@@div#content`或者`.l_chaptname>a@@@@@@next:{.curr+a}@div#content`。 - 下載內容可能含有幹擾碼,此時只需點擊**懶人小說下載設置**,輸入幹擾碼的 css 選擇器即可排除幹擾碼。例如 `.mask,.ksam,font.jammer`,代表刪除 class 為 mask 或者 ksam 的元素或者 class 為 jammer 的 font 元素。 + 如果有内分頁,且無法用正規表示式提取下一頁連結,可直接用選擇器來獲取,例如`.l_chaptname>a@@@@@@next:{.curr+a}`。 + 如果內文擷取錯誤,也可以使用選擇器來獲取,例如`.l_chaptname>a@@@@@@@div#content`或者`.l_chaptname>a@@@@@@next:{.curr+a}@div#content`。 + 下載內容可能含有幹擾碼,此時只需點擊**懶人小說下載設置**,輸入幹擾碼的 CSS 選擇器即可排除幹擾碼。例如 `.mask,.ksam,font.jammer`,代表刪除 class 為 mask 或者 ksam 的元素,或者 class 為 jammer 的 font 元素。 ### 第六層心法(超難) - 倘若正文不在內頁正文,是頁面加載後處理得到的,可點擊**自定義下載**,輸入自定義代碼對內頁進行分析獲取正確結果。例如 【`眾神的風車@@@@@@var noval=JSON.parse(doc.querySelector("#meta-preload-data").content).novel;noval[Object.keys(noval)[0]].content;`】,即可通過自定義代碼處理返回頁面獲取內容。代碼中使用 doc 可以獲得返回頁面的 document,最後一個表達式的值為最終寫入的內容。 + 倘若內文並非直接存在於頁面原始碼,而是在頁面載入後才處理生成的,可以點擊**自訂下載**,輸入自訂程式碼對內頁進行分析以獲取正確結果。例如 【`眾神的風車@@@@@@var noval=JSON.parse(doc.querySelector("#meta-preload-data").content).novel;noval[Object.keys(noval)[0]].content;`】,即可透過自訂程式碼處理返回的頁面來獲取內容。程式碼中的 `doc` 代表返回頁面的 document 物件,最後一個表達式的值就是最終寫入的內容。 - 如果返回 false,代表異步回調,可自行抓取內容並等待抓取成功後用 cb(content) 返回抓取到的 content。 + 如果返回 `false`,代表這是一個非同步回呼(asynchronous callback),可自行抓取內容並等待抓取成功後用 `cb(content)`` 回傳抓取到的 content。 - 倘若章節沒有連結,點擊後方纔生成連結跳轉,可通過 `>>` 管道處理抓取到的元素生成章節連結,例如`a.link >> item.href = xxx; return item;`。詳情見下方例子。 + 倘若章節沒有連結,而是點擊後才生成連結並跳轉,可透過 `>>` 管道處理抓取到的元素生成章節連結,例如`a.link >> item.href = xxx; return item;`。詳情見下方範例。 ### 第七層心法(極難) - 倘若正文已經經過加密,需要解密才能獲取正確內容,可打開瀏覽器的控製臺,自定義 dacProcess 函數,調取頁面中網站自身的解密代碼處理抓取的加密數據。例如控製臺輸入`dacProcess=data=>{return decrypt(xxx);}` 代表調用網站的 decrypt 解密章節頁面返回的數據。然後再點擊**自定義下載**,需要注意自定義下載時標記章節是必需的。 + 倘若正文已經經過加密,需要解密才能獲取正確內容,可開啟瀏覽器的開發人員工具主控台,自訂 dacProcess 函數,調取頁面中網站自身的解密程式碼處理抓取的加密數據。例如主控台輸入`dacProcess=data=>{return decrypt(xxx);}` 代表調用網站的 decrypt 函數來解密章節頁面返回的資料。然後再點擊**自訂下載**,需要注意自訂下載時,標記章節是必要步驟。 -### 關於配置項 - **【以下功能需要通過 Tampermonkey 等管理器的命令菜單進入】** +### 關於設定選項 + **【以下功能需要透過 Tampermonkey 等腳本管理器的指令選單進入】** ![img](https://greasyfork.s3.us-east-2.amazonaws.com/grg0pe1t13eth8t012bd1absp9id) - - 自定義目錄:如`https://xxx.xxx/book-**[20-99]**.html,https://xxx.xxx/book-**[01-10]**.html`,意思為下載book-20.html到book-99.html,以及book-01.html到book-10.html,使用**[1-10]**則不補0。 - - 章節選擇器自定義:輸入章節連結的 css 選擇器即可,後面可以接上 url 替換碼、以及自定義處理代碼。 + - 自訂目錄:如`https://xxx.xxx/book-**[20-99]**.html,https://xxx.xxx/book-**[01-10]**.html`,意思為下載book-20.html到book-99.html,以及book-01.html到book-10.html,使用**[1-10]**則不補0。 + - 章節選擇器自訂:輸入章節連結的 css 選擇器即可,後面可以接上 url 替換碼、以及自定義處理代碼。 - 幹擾碼:填入幹擾碼的 css 選擇器,如`.mask,.ksam`,意為刪除 class 為 mask 或者 ksam 的元素。 - 按標題名重新排序:是則把目錄頁所有連結按標題名排序後存入txt,否則按頁面位置順序排列。 - - 下載線程數:同時下載的線程數,默認為20,遇到存在限製的站點(例如下載時總有章節獲取失敗)可調低。 + - 下載線程數:同時下載的執行緒數量,默認為20,遇到存在限製的站點(例如下載時總有章節獲取失敗)可調低。 ### 完整格式說明 -某個章節名 / CSS 選擇器【選擇器後可跟 >> 傳入 item 處理】 **@@** 抓取到 URL 的正則匹配 **@@** 正則替換 URL **@@** 根據爬取返回內容 data 處理並返回最終文本 +某個章節名 / CSS 選擇器【選擇器後可跟 >> 傳入 item 處理】 **@@** 抓取到 URL 的正規表示式匹配 **@@** 正規表示式替換 URL **@@** 根據爬取返回內容 data 進行處理並回傳最終文本 #### 内頁處理範例 假設章節元素為 `a.links` + 使用 iframe 處理内頁内容 @@ -80,16 +80,16 @@ `a.links@@@@@@iframe:sandbox:{allow-same-origin}` - iframe 添加初始化程式碼 `a.links@@@@@@iframe:init:{win.top=win.self}` -+ 自定義内頁中分頁抓取方式 ++ 自訂内頁中分頁抓取方式 - 透過選擇器抓取 `a.links@@@@@@next:{a.next}` - 透過程式碼生成 `a.links@@@@@@next:{return await getNextElement()}` 可以用多層 `{}` 來避免程式碼中出現大括號產生的問題 -### 自定義下載範例,打開目錄頁點擊【自定義下載】粘貼後使用,僅爲規則實例引導,有出入請自行修改 +### 自訂下載範例,打開目錄頁點擊【自訂下載】粘貼後使用,僅爲規則實例引導,有出入請自行修改 + [📕po18](https://www.po18.tw/books/755779/articles) -> 章節的選擇器為 `.l_chaptname>a` ,輸入並下載後發現通過 url 無法下載正文內容,正文是 ajax 通過 articlescontent 下載的。此時可後接 `@@articles@@articlescontent` (@@ 分隔) 將章節 url 中的 articles 替換為 articlescontent 。 `.l_chaptname>a@@articles@@articlescontent` 粘貼進命令菜單即可下載。其中第一個 articles 可使用正則,例如 `@@articles(\d+)@@$1content` 代表將連結中的「articles1」「articles2」等替換為「1content」「2content」。 +> 章節的選擇器為 `.l_chaptname>a` ,輸入並下載後發現通過 url 無法下載正文內容,正文是 ajax 通過 articlescontent 下載的。此時可後接 `@@articles@@articlescontent` (@@ 分隔) 將章節 url 中的 articles 替換為 articlescontent 。 `.l_chaptname>a@@articles@@articlescontent` 粘貼進命令菜單即可下載。其中第一個 articles 可使用正規表示式,例如 `@@articles(\d+)@@$1content` 代表將連結中的「articles1」「articles2」等替換為「1content」「2content」。 ``` css .l_chaptname>a@@articles@@articlescontent ``` @@ -210,7 +210,7 @@ function decode(t) { + [📕愛發電](https://愛發電/album/afee5ce2462d11ee897e52540025c377) > 我也是愛發電用戶,拿人手短,就不欺負它了。只給個思路,用第四層心法取 album_id 與 章節 id 去 /api/post 請求數據即可。 + [📕頭文字小説](https://m.touwz.net/dushi/yinhezhuiluo/) -> 簡單的分頁,沒啥難點。惟一需要注意的是,分頁連結藏在 js 代碼裏,用正則取出完事。 +> 簡單的分頁,沒啥難點。惟一需要注意的是,分頁連結藏在 js 代碼裏,用正規表示式取出完事。 ``` javascript .chapter>li>a@@@@@@let content="\n";let checkContent=(doc,over)=>{word=doc.querySelector('.content-div');if(!word)content+='\n'+doc.body.innerText;else {let ps=[];[].forEach.call(word.children, p=>{if(p.className!='moreinfo')ps.push(p.innerText)});content+=ps.join('\n');}let next=doc.querySelector("#pt_next");if(next){fetch(location.href+ doc.body.innerHTML.match(/'([^\|']+)\|[^']+'\.split/)[1]+".html").then(r => r.text()).then(d => {let _doc = document.implementation.createHTMLDocument('');_doc.documentElement.innerHTML = d;checkContent(_doc,over);});}else over();};checkContent(data,()=>{cb(content.replace(/\s*「如章节缺失请退#出#阅#读#模#式」\s*|\s*本章未完,点下一页继续阅读。>>>\s*/g,''))});return false; ``` From f560a8ef6e7621f201017bcc4ae5829f53374bf8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 13 Jul 2025 10:16:58 +0900 Subject: [PATCH 0720/1065] Update README.md --- DownloadAllContent/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DownloadAllContent/README.md b/DownloadAllContent/README.md index df53d45a953..5ac83b0837a 100644 --- a/DownloadAllContent/README.md +++ b/DownloadAllContent/README.md @@ -1,4 +1,4 @@ -起點等主流網站建議優先使用這個腳本[【小說】下載腳本](https://github.com/dodying/UserJs/tree/master/novel/novelDownloader),如果遇到沒有人願意支援的小網站,再考慮我的腳本。。 +起點等主流網站建議優先使用這個腳本[【小說】下載腳本](https://github.com/dodying/UserJs/tree/master/novel/novelDownloader),如果遇到沒有人願意支援的小網站,再考慮我的腳本。 請勿用於有版權的網站,如造成侵權或對目標網站造成損失,後果請自行負責。 @@ -19,7 +19,7 @@ 如果遇到下載出錯的網站,歡迎到 [Github](https://github.com/hoothin/UserScripts/) 提交 issue。也請順手幫我點亮 Star! -*對你有幫助的話,可透過 [![i](https://static.afdiancdn.com/favicon.ico) 愛發電](https://afdian.com/a/hoothin) 或者 [![i](https://ko-fi.com/favicon-32x32.png) Ko-fi](https://ko-fi.com/hoothin) 請我喝一杯奶茶。也歡迎加入 [💬Discord 群組](https://discord.com/invite/keqypXC6wD)。* +*對你有幫助的話,可透過 [![i](https://static.afdiancdn.com/favicon.ico) 愛發電](https://afdian.com/a/hoothin) 或者 [![i](https://ko-fi.com/favicon-32x32.png) Ko-fi](https://ko-fi.com/hoothin) 請我喝一杯奶茶。也歡迎加入 [💬Discord 群組](https://discord.com/invite/keqypXC6wD) 或者關注我的 [Twitter](https://twitter.com/intent/follow?screen_name=HoothinDev)。* ![donate](https://s2.loli.net/2023/02/06/afTMxeASm48z5vE.jpg) From 85d4122bc04cb17d73258a4701fb2aa58876e5f5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 13 Jul 2025 10:17:58 +0900 Subject: [PATCH 0721/1065] Update README.md --- Picviewer CE+/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index ae2f2722b85..967f4c2c423 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -1,4 +1,4 @@ -# 🏞️ Picviewer CE+ ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) 🌐[Reddit](https://www.reddit.com/r/PicviewerCE) 🗨️[Discord](https://discord.com/invite/keqypXC6wD) +# 🏞️ Picviewer CE+ ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) 🌐[Reddit](https://www.reddit.com/r/PicviewerCE) 🗨️[Discord](https://discord.com/invite/keqypXC6wD) 🕊️[Twitter](https://twitter.com/intent/follow?screen_name=HoothinDev) > Zoom images across all your favorite websites. Pop up, scale, edit, rotate, batch save images, or automatically load pictures from subsequent pages. Simply hover your mouse over any image and click the icons on the float bar. From fc6a13571120a2008c22a041659b6d0d26d96ae0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 13 Jul 2025 10:21:09 +0900 Subject: [PATCH 0722/1065] Update README.md --- Pagetual/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 8bacc927e33..1890be62940 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -21,10 +21,13 @@ https://raw.githubusercontent.com/hoothin/UserScripts/master/Pagetual/pagetualRu
    愛發電
    - Join our 💬Discord + Join 💬Discord - Send me an 📧email + Follow 🕊️twitter + + + Send 📧email Made with ❤️ by Hoothin From 2838a803ae509b787c4b773346f140d93f990378 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 14 Jul 2025 18:59:18 +0900 Subject: [PATCH 0723/1065] Update README.md --- Picviewer CE+/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 967f4c2c423..1c23c4d997d 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -1,4 +1,4 @@ -# 🏞️ Picviewer CE+ ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) 🌐[Reddit](https://www.reddit.com/r/PicviewerCE) 🗨️[Discord](https://discord.com/invite/keqypXC6wD) 🕊️[Twitter](https://twitter.com/intent/follow?screen_name=HoothinDev) +# 🏞️ Picviewer CE+ ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) 🌐[Reddit](https://www.reddit.com/r/PicviewerCE) 🗨️[Discord](https://discord.com/invite/keqypXC6wD) 🕊️[Twitter](https://twitter.com/intent/follow?screen_name=HoothinDev) [⏬](https://greasyfork.org/scripts/24204-picviewer-ce/code/Picviewer%20CE+.user.js) > Zoom images across all your favorite websites. Pop up, scale, edit, rotate, batch save images, or automatically load pictures from subsequent pages. Simply hover your mouse over any image and click the icons on the float bar. From 29bc9ccaf4425f830ac4be01735ef3d023a06978 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 17 Jul 2025 10:00:11 +0900 Subject: [PATCH 0724/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index d035eb56258..cafc4e2954b 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -26198,7 +26198,8 @@ ImgOps | https://imgops.com/#b#`; label: i18n("aria2Host"), type: 'text', className: 'order', - "default": prefs.gallery.aria2Host || 'http://localhost:6800' + "default": prefs.gallery.aria2Host || 'http://localhost:6800', + after: '/jsonrpc' }, 'gallery.aria2Token': { label: i18n("aria2Token"), From dc8f727fe6b144c8a47f403dbeee11518739cf25 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 17 Jul 2025 18:04:28 +0900 Subject: [PATCH 0725/1065] 1.9.37.120 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 90 +++++++++++++++++++-------------------- 2 files changed, 44 insertions(+), 48 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 1890be62940..5b6c3c2dfe1 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.119](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.120](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 6d881e425c4..af3d9d23ca5 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.119 +// @version 1.9.37.120 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -3904,61 +3904,57 @@ postParams = postParams[1]; url = url.replace(/#p{.*/, ""); } - _GM_xmlhttpRequest({ - url: url, + fetch(url, { method: postParams ? 'POST' : 'GET', - data: postParams, - overrideMimeType: 'text/html;charset=' + charset, + body: postParams, headers: { 'Referer': location.href, 'User-Agent': navigator.userAgent, "Content-Type": (postParams ? "application/x-www-form-urlencoded" : "text/html") + ";charset=" + charset - }, - timeout: 10000, - onload: function(res) { - var doc = null; - try { - doc = document.implementation.createHTMLDocument(''); - doc.documentElement.innerHTML = createHTML(res.response); - var body = getBody(doc); - if (!self.preloadDiv) { - self.preloadDiv = document.createElement('div'); - self.preloadDiv.id = "pagetual-preload"; - self.preloadDiv.style.cssText = 'display:none!important;'; - getBody(document).appendChild(self.preloadDiv); - self.checkedImgs = {}; - self.unCheckedImgs = []; - } - let code = self.curSiteRule.preloadImages; - if (code) { - let imgSrcArr = new Function("doc", '"use strict";' + code)(doc); - if (imgSrcArr && imgSrcArr.length) { - imgSrcArr.forEach(imgSrc => { - if (imgSrc && !self.checkedImgs[imgSrc]) { - self.checkedImgs[imgSrc] = true; - self.unCheckedImgs.push(imgSrc); - } - }); - } - self.preloadImageHandler(); - } else if (code !== 0 && code !== false) { - if (body && body.firstChild) { - self.lazyImgAction(body.children, doc); - } - [].forEach.call(doc.images, i => { - let iSrc = i.src; - if (iSrc && !self.checkedImgs[iSrc]) { - self.checkedImgs[iSrc] = true; - self.unCheckedImgs.push(iSrc); + } + }).then(response => response.text()).then(data => { + var doc = null; + try { + doc = document.implementation.createHTMLDocument(''); + doc.documentElement.innerHTML = createHTML(data); + var body = getBody(doc); + if (!self.preloadDiv) { + self.preloadDiv = document.createElement('div'); + self.preloadDiv.id = "pagetual-preload"; + self.preloadDiv.style.cssText = 'display:none!important;'; + getBody(document).appendChild(self.preloadDiv); + self.checkedImgs = {}; + self.unCheckedImgs = []; + } + let code = self.curSiteRule.preloadImages; + if (code) { + let imgSrcArr = new Function("doc", '"use strict";' + code)(doc); + if (imgSrcArr && imgSrcArr.length) { + imgSrcArr.forEach(imgSrc => { + if (imgSrc && !self.checkedImgs[imgSrc]) { + self.checkedImgs[imgSrc] = true; + self.unCheckedImgs.push(imgSrc); } }); - self.preloadImageHandler(); } + self.preloadImageHandler(); + } else if (code !== 0 && code !== false) { + if (body && body.firstChild) { + self.lazyImgAction(body.children, doc); + } + [].forEach.call(doc.images, i => { + let iSrc = i.src; + if (iSrc && !self.checkedImgs[iSrc]) { + self.checkedImgs[iSrc] = true; + self.unCheckedImgs.push(iSrc); + } + }); + self.preloadImageHandler(); } - catch(e) { - debug(e); - return; - } + } + catch(e) { + debug(e); + return; } }); } From 4a393c190fbf9a42a5fae2dd8a0147450b0a6929 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 18 Jul 2025 09:39:55 +0900 Subject: [PATCH 0726/1065] Update README.md --- Pagetual/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 5b6c3c2dfe1..53144f23965 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,8 +1,8 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.120](https://greasyfork.org/scripts/438684-pagetual/code/Pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.120](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* -🔧CONFIGURATION PAGE🔧 +🔧CONFIGURATION PAGE🔧

    
    From 267233e2e1f546f8a3e07a5d3b438847ebb0ce85 Mon Sep 17 00:00:00 2001
    From: hoothin 
    Date: Fri, 18 Jul 2025 09:40:36 +0900
    Subject: [PATCH 0727/1065] Update README.md
    
    ---
     Pagetual/README.md | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Pagetual/README.md b/Pagetual/README.md
    index 53144f23965..95107f5b47b 100644
    --- a/Pagetual/README.md
    +++ b/Pagetual/README.md
    @@ -2,7 +2,7 @@
     ==
     *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !*
     
    -🔧CONFIGURATION PAGE🔧
    +🔧CONFIGURATION PAGE
     
     

    
    From 5506613a76c489b2cc53f3dce04756f5f9ac674e Mon Sep 17 00:00:00 2001
    From: hoothin 
    Date: Fri, 18 Jul 2025 12:11:45 +0900
    Subject: [PATCH 0728/1065] Create CODE_OF_CONDUCT.md
    
    ---
     CODE_OF_CONDUCT.md | 128 +++++++++++++++++++++++++++++++++++++++++++++
     1 file changed, 128 insertions(+)
     create mode 100644 CODE_OF_CONDUCT.md
    
    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.
    
    From 1a88debb1744bd82a620d0878445ac3d626a2f90 Mon Sep 17 00:00:00 2001
    From: hoothin 
    Date: Fri, 18 Jul 2025 20:12:02 +0900
    Subject: [PATCH 0729/1065] nextLinkByUrl
    
    ---
     Pagetual/README.md          |  2 +-
     Pagetual/pagetual.user.js   | 27 ++++++++++++++++++++++-----
     Pagetual/pagetualRules.json | 18 +++++++++++++-----
     3 files changed, 36 insertions(+), 11 deletions(-)
    
    diff --git a/Pagetual/README.md b/Pagetual/README.md
    index 95107f5b47b..f5fec67cd21 100644
    --- a/Pagetual/README.md
    +++ b/Pagetual/README.md
    @@ -1,4 +1,4 @@
    -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.120](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version")
    +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.121](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version")
     ==
     *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !*
     
    diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js
    index af3d9d23ca5..a4dccfc95a6 100644
    --- a/Pagetual/pagetual.user.js
    +++ b/Pagetual/pagetual.user.js
    @@ -31,7 +31,7 @@
     // @name:da      Pagetual
     // @name:fr-CA   Pagetual
     // @namespace    hoothin
    -// @version      1.9.37.120
    +// @version      1.9.37.121
     // @description  Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule.
     // @description:zh-CN  终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页
     // @description:zh-TW  終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁
    @@ -3497,7 +3497,20 @@
                         debug(e);
                     }
                 } else if (this.curSiteRule.nextLinkByUrl) {
    -                let targetUrl = this.curUrl.replace(new RegExp(this.curSiteRule.nextLinkByUrl[0], "i"), this.curSiteRule.nextLinkByUrl[1]);
    +                let urlReg = new RegExp(this.curSiteRule.nextLinkByUrl[0], "i");
    +                let targetUrl;
    +                if (urlReg.test(this.curUrl)) {
    +                    targetUrl = this.curUrl.replace(urlReg, this.curSiteRule.nextLinkByUrl[1])
    +                } else {
    +                    if (this.curSiteRule.nextLinkByUrl[0].indexOf("&") != -1) {
    +                        urlReg = new RegExp(this.curSiteRule.nextLinkByUrl[0].replace("&", "\\?"), "i");
    +                    }
    +                    if (urlReg.test(this.curUrl)) {
    +                        targetUrl = this.curUrl.replace(urlReg, this.curSiteRule.nextLinkByUrl[1]);
    +                    } else {
    +                        targetUrl = this.curUrl + this.curSiteRule.nextLinkByUrl[1].replace(/\$\d+/g, "");
    +                    }
    +                }
                     if (targetUrl !== this.curUrl) {
                         let includeSel = this.curSiteRule.nextLinkByUrl[2];
                         let excludeSel = this.curSiteRule.nextLinkByUrl[3];
    @@ -3529,8 +3542,11 @@
                                         debug(e);
                                     }
                                 }
    -                            targetUrl = targetUrl.replace(rep, result);
    +                            targetUrl = targetUrl.replace(rep, result || "");
                             });
    +                        if (targetUrl.indexOf("&") != -1 && targetUrl.indexOf("?") == -1) {
    +                            targetUrl = targetUrl.replace("&", "?");
    +                        }
                         }
                     }
                     nextLink = {href: targetUrl};
    @@ -8754,7 +8770,6 @@
             let pageText = document.createElement("a");
             let pageNum;
             pageBar.className = isHideBar ? "pagetual_pageBar autopagerize_page_info hide" : "pagetual_pageBar autopagerize_page_info";
    -        pageBar.id = "pagetual_pageBar" + curPage;
             pageBar.setAttribute("translate", "no");
             if (isPause) {
                 pageBar.classList.add("stop");
    @@ -8775,6 +8790,7 @@
             if (openInNewTab == 1) pageText.target = "_blank";
             pageBar.appendChild(upSpan);
             pageBar.appendChild(pageText);
    +        let localPage = curPage;
             let touched = false;
             let touchBodyHandler = e => {
                 touched = false;
    @@ -8788,6 +8804,7 @@
                 pageText.innerHTML = createHTML(pageText.innerHTML + i18n("page"));
                 pageNum = document.createElement("span");
                 let num = ruleParser.getPageNumFromUrl(url, curPage);
    +            localPage = num;
                 pageNum.innerHTML = createHTML(num + " ");
                 pageNum.className = "pagetual_pageNum";
                 pageNum.title = i18n("inputPageNum");
    @@ -8815,6 +8832,7 @@
             } else {
                 pageText.innerHTML = createHTML(pageText.innerHTML + i18n("page") + curPage + " ");
             }
    +        pageBar.id = "pagetual_pageBar" + localPage;
             let preBtn = document.createElement("span");
             preBtn.innerHTML = createHTML("∧");
             preBtn.title = i18n("prevPage");
    @@ -8825,7 +8843,6 @@
             nextBtn.title = i18n("nextPage");
             nextBtn.className = "nextScreen";
             nextBtn.style.cssText = "display: none;text-align: center;right: unset; float: left; width: 40px; background: rgba(240, 240, 240, 0.8); position: absolute; z-index: 9999999; box-shadow: rgb(0 0 0 / 50%) 0px 5px 5px; border-radius: 0 0 20px 20px; margin-top: 30px; ";
    -        let localPage = curPage;
             preBtn.addEventListener("click", e => {
                 e.stopPropagation();
                 e.preventDefault();
    diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json
    index 81474810a9b..1c9d90df0ea 100644
    --- a/Pagetual/pagetualRules.json
    +++ b/Pagetual/pagetualRules.json
    @@ -5476,13 +5476,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",
    
    From 39c9413dde6adb33919f9bfda7a6f546cd5072d4 Mon Sep 17 00:00:00 2001
    From: hoothin-update 
    Date: Fri, 18 Jul 2025 11:12:17 +0000
    Subject: [PATCH 0730/1065] Update version of Pagetual rules to 95
    
    ---
     Pagetual/version | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Pagetual/version b/Pagetual/version
    index 49541f72104..5595fa46c06 100644
    --- a/Pagetual/version
    +++ b/Pagetual/version
    @@ -1 +1 @@
    -94
    +95
    
    From 0cdfc815c0cf6d8463240feaaea870b165703b20 Mon Sep 17 00:00:00 2001
    From: hoothin 
    Date: Sun, 20 Jul 2025 15:50:33 +0900
    Subject: [PATCH 0731/1065] Update pagetualRules.json
    
    ---
     Pagetual/pagetualRules.json | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json
    index 1c9d90df0ea..b8b41e113f3 100644
    --- a/Pagetual/pagetualRules.json
    +++ b/Pagetual/pagetualRules.json
    @@ -2784,7 +2784,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",
    
    From 2223860e7b7c683d4c9d3bf97d378a52c623d339 Mon Sep 17 00:00:00 2001
    From: hoothin-update 
    Date: Sun, 20 Jul 2025 06:50:48 +0000
    Subject: [PATCH 0732/1065] Update version of Pagetual rules to 96
    
    ---
     Pagetual/version | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Pagetual/version b/Pagetual/version
    index 5595fa46c06..f906e1845dc 100644
    --- a/Pagetual/version
    +++ b/Pagetual/version
    @@ -1 +1 @@
    -95
    +96
    
    From c0375d01c63775f468e24aa3e7f3f9fb40965463 Mon Sep 17 00:00:00 2001
    From: hoothin 
    Date: Tue, 22 Jul 2025 12:03:58 +0900
    Subject: [PATCH 0733/1065] Update Picviewer CE+.user.js
    
    ---
     Picviewer CE+/Picviewer CE+.user.js | 83 ++++++++++++++---------------
     1 file changed, 39 insertions(+), 44 deletions(-)
    
    diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js
    index cafc4e2954b..57d8e1607f7 100644
    --- a/Picviewer CE+/Picviewer CE+.user.js	
    +++ b/Picviewer CE+/Picviewer CE+.user.js	
    @@ -12,7 +12,7 @@
     // @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              2025.7.5.1
    +// @version              2025.7.22.1
     // @icon                 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg==
     // @namespace            https://github.com/hoothin/UserScripts
     // @homepage             https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B
    @@ -12226,6 +12226,22 @@ ImgOps | https://imgops.com/#b#`;
             };
             img.src = dataurl;
         }
    +    function urlToBlobWithFetch(urlString, cb){
    +        fetch(urlString).then(response => response.blob()).then(blob => cb(blob)).catch(error => {
    +            cb(null);
    +        });
    +    }
    +    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 urlToBlob(url, cb, forcePng, tryTimes = 0) {
             tryTimes++;
    @@ -12255,8 +12271,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"));
                             });
                         };
    @@ -14533,7 +14553,7 @@ ImgOps | https://imgops.com/#b#`;
                                 let picName = (saveIndex < 10 ? "00" + saveIndex : (saveIndex < 100 ? "0" + saveIndex : saveIndex)) + (title ? "-" + title : ""), hostArr = location.host.split(".");
                                 let host = hostArr[hostArr.length-2];
                                 saveParams.push([node.dataset.src, picName]);
    -                            if (node.dataset.srcs) {
    +                            if (node.dataset.srcs && node.dataset.srcs != node.dataset.src) {
                                     node.dataset.srcs.split(",").forEach(src => {
                                         saveParams.push([src, picName]);
                                     });
    @@ -15622,26 +15642,24 @@ ImgOps | https://imgops.com/#b#`;
                                 });
                             }
                             if(canvas && (/^data:/.test(imgSrc) || imgSrc.split("/")[2] == document.domain)){
    -                            self.dataURLToCanvas(imgSrc, canvas=>{
    -                                self.showTips("Downloading "+(downloaded+1)+"/"+len, 1000000);
    -                                if(!canvas){
    +                            urlToBlobWithFetch(imgSrc, blob=>{
    +                                if(!blob){
                                         crosHandler(imgSrc);
                                         return;
                                     }
    -                                canvas.toBlob(blob=>{
    -                                    zip.file(imgName.replace(/^data:.*/, "img").replace(/\//g,""), blob);
    -                                    downloaded++;
    -                                    over && over();
    -                                    if(downloaded == len){
    -                                        self.showTips(`Begin compress to ${packName}...`, 100000);
    -                                        zip.generateAsync({type:"blob"}, meta=>{self.showCompressProgress(meta)}).then(function(content){
    -                                            if (content) {
    -                                                saveAs(content, packName);
    -                                            }
    -                                            callback();
    -                                        })
    -                                    }
    -                                }, "image/png");
    +                                self.showTips("Downloading "+(downloaded+1)+"/"+len, 1000000);
    +                                zip.file(imgName.replace(/^data:.*/, "img").replace(/\//g,""), blob);
    +                                downloaded++;
    +                                over && over();
    +                                if(downloaded == len){
    +                                    self.showTips(`Begin compress to ${packName}...`, 100000);
    +                                    zip.generateAsync({type:"blob"}, meta=>{self.showCompressProgress(meta)}).then(function(content){
    +                                        if (content) {
    +                                            saveAs(content, packName);
    +                                        }
    +                                        callback();
    +                                    })
    +                                }
                                 });
                             }else{
                                 crosHandler(imgSrc);
    @@ -16190,29 +16208,6 @@ ImgOps | https://imgops.com/#b#`;
                         this.bricksInstance.resize(true);
                     }
                 },
    -            dataURLToCanvas:function (dataurl, cb){
    -                if(!dataurl)return cb(null);
    -                var ctx = canvas.getContext('2d');
    -                var img = new Image();
    -                img.setAttribute("crossOrigin","anonymous");
    -                img.onload = function(){
    -                    canvas.width = img.width;
    -                    canvas.height = img.height;
    -                    ctx.clearRect(0, 0, canvas.width, canvas.height);
    -                    ctx.drawImage(img, 0, 0);
    -                    cb(canvas);
    -                };
    -                img.onerror = function(){
    -                    cb(null);
    -                };
    -                img.src = dataurl;
    -            },
    -            blobToCanvas: function (blob, cb){
    -                var self=this;
    -                blobToDataURL(blob, function (dataurl){
    -                    self.dataURLToCanvas(dataurl, cb);
    -                });
    -            },
                 showHideBottom: function() {  // 显示隐藏 sidebar-container
                     var sidebarContainer = this.eleMaps['sidebar-container'],
                         isHidden = sidebarContainer.style.visibility == 'hidden';
    
    From e0864015f621255932128ae60643117674aaea7b Mon Sep 17 00:00:00 2001
    From: hoothin 
    Date: Thu, 24 Jul 2025 20:17:29 +0900
    Subject: [PATCH 0734/1065] Update pvcep_rules.js
    
    ---
     Picviewer CE+/pvcep_rules.js | 54 +++++++++++++++++++++++++++++++++++-
     1 file changed, 53 insertions(+), 1 deletion(-)
    
    diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js
    index cd40402fd3c..812a3e2eacd 100644
    --- a/Picviewer CE+/pvcep_rules.js	
    +++ b/Picviewer CE+/pvcep_rules.js	
    @@ -838,6 +838,58 @@ var siteInfo = [
                 }
             }
         },
    +    {
    +        name: "Twitch",
    +        url: /^https:\/\/(www\.twitch\.tv\/|www\.reddit\.com\/r\/TwitchClips\/)/,
    +        xhr: {
    +            url: function(a, p, xhr) {
    +                if (!a) return;
    +                if (!/twitch\.tv/.test(a.href)) return;
    +                let m = a.href.match(/(\/clip\/|clips\.twitch\.tv\/)([^?]{1,})/);
    +                if (m) {
    +                    var slug = m[2];
    +                    var operationNameClip = "VideoAccessToken_Clip";
    +                    var operationNameLiveOrVOD = "PlaybackAccessToken";
    +                    var sha256HashClip = "36b89d2507fce29e5ca551df756d27c1cfe079e2609642b4390aa4c35796eb11";
    +                    var sha256HashLiveOrVOD = "0828119ded1c13477966434e15800ff57ddacf13ba1911c129dc2200705b0712";
    +                    return `https://gql.twitch.tv/gql#p{{"operationName":"${operationNameClip}","variables":{"slug":"${slug}"},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"${sha256HashClip}"}}}}`;
    +                } else {
    +                    m = a.href.match(/(?:m\.|www\.)?twitch\.tv\/(?:(?!directory|downloads|jobs|store|twitchartists|turbo|privacy)(\w+)$|(?:\w+\/)?videos\/(\d+))/);
    +                    if (m) {
    +                        xhr.m = m;
    +                        return `https://gql.twitch.tv/gql#p{{"operationName":"PlaybackAccessToken_Template","query":"query PlaybackAccessToken_Template($login: String!, $isLive: Boolean!, $vodID: ID!, $isVod: Boolean!, $playerType: String!, $platform: String!) {  streamPlaybackAccessToken(channelName: $login, params: {platform: $platform, playerBackend: \\"mediaplayer\\", playerType: $playerType}) @include(if: $isLive) {    value    signature   authorization { isForbidden forbiddenReasonCode }   __typename  }  videoPlaybackAccessToken(id: $vodID, params: {platform: $platform, playerBackend: \\"mediaplayer\\", playerType: $playerType}) @include(if: $isVod) {    value    signature   __typename  }}","variables":{"isLive":${m[1]?'true':'false'},"login":"${m[1]||''}","isVod":true,"vodID":"${m[2]||''}","playerType":"site","platform":"web"}}}`;
    +                    }
    +                }
    +            },
    +            headers: function(url, xhr, getCookie) {
    +                return {"Client-ID":"kimne78kx3ncx6brgo4mv6wki5h1ko", "X-Device-Id": getCookie('unique_id') || getCookie('unique_id_durable') || 'd56e8463c57c7cd7'}
    +            },
    +            cacheNum: 20,
    +            query: function(html, doc, u, xhr) {
    +                try {
    +                    let r = JSON.parse(html);
    +                    if (r.data.clip) {
    +                        let signature = r.data.clip.playbackAccessToken.signature;
    +                        let token = r.data.clip.playbackAccessToken.value;
    +                        let t = JSON.parse(token);
    +                        let clip_uri = r.data.clip.videoQualities[0].sourceURL;
    +                        let fullsizeUrl = clip_uri + '?sig=' + signature + '&token=' + encodeURIComponent(token);
    +
    +                        return {url: ["video:" + fullsizeUrl], cap: ""};
    +                    } else {
    +                        let tokens = r.data.streamPlaybackAccessToken || r.data.videoPlaybackAccessToken;
    +                        if (!tokens) return;
    +                        let hex = ['A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    +                        let url = xhr.m[1] ? 'api/channel/hls': 'vod';
    +                        let p = Math.floor(999999 * Math.random());
    +                        let id = '';
    +                        for (let i = 0; i < 32; i++) id += hex[Math.floor(Math.random() * 16)];
    +                        return `video:https://usher.ttvnw.net/${url}/${xhr.m[1]||xhr.m[2]}.m3u8?acmb=eyJBcHBWZXJzaW9uIjoiYjlhNjU4ZWMtMTcyMS00Y2FjLThkMjgtZjk0NmJmY2E3YzUwIn0%3D&allow_source=true&p=${p}&platform=web&play_session_id=${id}&sig=${tokens.signature}&supported_codecs=av1,h264&token=${encodeURIComponent(tokens.value)}&transcode_mode=cbr_v1`;
    +                    }
    +                } catch { }
    +            }
    +        }
    +    },
         {
             name: "Rule34hentai",
             url: /rule34hentai\.net/,
    @@ -1368,7 +1420,7 @@ var siteInfo = [
                         const images = items0.image_versions2;
                         const carousel = items0.carousel_media;
                         if (videos) {
    -                        const videoUrl = videos[0].url + '.video';
    +                        const videoUrl = "video:" + videos[0].url;
                             let videoAudioSubtitlesUrl = videoUrl;
                             const caption = (items0.caption ? items0.caption.text : (items0.accessibility_caption ? items0.accessibility_caption : items0.user.full_name));
                             return {url: [videoUrl], cap: caption};
    
    From 7b6bec97224eb9d5addb13cdf411df0ae6b1c968 Mon Sep 17 00:00:00 2001
    From: hoothin 
    Date: Thu, 24 Jul 2025 23:48:16 +0900
    Subject: [PATCH 0735/1065] Update pvcep_rules.js
    
    ---
     Picviewer CE+/pvcep_rules.js | 104 +++++++++++++++++------------------
     1 file changed, 52 insertions(+), 52 deletions(-)
    
    diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js
    index 812a3e2eacd..4fd9481a669 100644
    --- a/Picviewer CE+/pvcep_rules.js	
    +++ b/Picviewer CE+/pvcep_rules.js	
    @@ -740,6 +740,58 @@ var siteInfo = [
             r: /thumbs(\d\.imgbox.*)_t\./i,
             s: "images$1_o."
         },
    +    {
    +        name: "Twitch",
    +        url: /^https:\/\/(www\.twitch\.tv\/|www\.reddit\.com\/r\/TwitchClips\/)/,
    +        xhr: {
    +            url: function(a, p, xhr) {
    +                if (!a) return;
    +                if (!/twitch\.tv/.test(a.href)) return;
    +                let m = a.href.match(/(\/clip\/|clips\.twitch\.tv\/)([^?]{1,})/);
    +                if (m) {
    +                    var slug = m[2];
    +                    var operationNameClip = "VideoAccessToken_Clip";
    +                    var operationNameLiveOrVOD = "PlaybackAccessToken";
    +                    var sha256HashClip = "36b89d2507fce29e5ca551df756d27c1cfe079e2609642b4390aa4c35796eb11";
    +                    var sha256HashLiveOrVOD = "0828119ded1c13477966434e15800ff57ddacf13ba1911c129dc2200705b0712";
    +                    return `https://gql.twitch.tv/gql#p{{"operationName":"${operationNameClip}","variables":{"slug":"${slug}"},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"${sha256HashClip}"}}}}`;
    +                } else {
    +                    m = a.href.match(/(?:m\.|www\.)?twitch\.tv\/(?:(?!directory|downloads|jobs|store|twitchartists|turbo|privacy)(\w+)$|(?:\w+\/)?videos\/(\d+))/);
    +                    if (m) {
    +                        return `https://gql.twitch.tv/gql#p{{"operationName":"PlaybackAccessToken_Template","query":"query PlaybackAccessToken_Template($login: String!, $isLive: Boolean!, $vodID: ID!, $isVod: Boolean!, $playerType: String!, $platform: String!) {  streamPlaybackAccessToken(channelName: $login, params: {platform: $platform, playerBackend: \\"mediaplayer\\", playerType: $playerType}) @include(if: $isLive) {    value    signature   authorization { isForbidden forbiddenReasonCode }   __typename  }  videoPlaybackAccessToken(id: $vodID, params: {platform: $platform, playerBackend: \\"mediaplayer\\", playerType: $playerType}) @include(if: $isVod) {    value    signature   __typename  }}","variables":{"isLive":${m[1]?'true':'false'},"login":"${m[1]||''}","isVod":true,"vodID":"${m[2]||''}","playerType":"site","platform":"web"}}}`;
    +                    }
    +                }
    +            },
    +            headers: function(url, xhr, getCookie) {
    +                return {"Client-ID":"kimne78kx3ncx6brgo4mv6wki5h1ko", "X-Device-Id": getCookie('unique_id') || getCookie('unique_id_durable') || 'd56e8463c57c7cd7'}
    +            },
    +            cacheNum: 20,
    +            query: function(html, doc, u, xhr) {
    +                try {
    +                    let r = JSON.parse(html);
    +                    if (r.data.clip) {
    +                        let signature = r.data.clip.playbackAccessToken.signature;
    +                        let token = r.data.clip.playbackAccessToken.value;
    +                        let t = JSON.parse(token);
    +                        let clip_uri = r.data.clip.videoQualities[0].sourceURL;
    +                        let fullsizeUrl = clip_uri + '?sig=' + signature + '&token=' + encodeURIComponent(token);
    +
    +                        return {url: ["video:" + fullsizeUrl], cap: ""};
    +                    } else {
    +                        let m = u.match(/"login":"(.*?)".*"vodID":"(.*?)"/);
    +                        let tokens = r.data.streamPlaybackAccessToken || r.data.videoPlaybackAccessToken;
    +                        if (!tokens) return;
    +                        let hex = ['A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    +                        let url = m[1] ? 'api/channel/hls': 'vod';
    +                        let p = Math.floor(999999 * Math.random());
    +                        let id = '';
    +                        for (let i = 0; i < 32; i++) id += hex[Math.floor(Math.random() * 16)];
    +                        return `video:https://usher.ttvnw.net/${url}/${m[1]||m[2]}.m3u8?acmb=eyJBcHBWZXJzaW9uIjoiYjlhNjU4ZWMtMTcyMS00Y2FjLThkMjgtZjk0NmJmY2E3YzUwIn0%3D&allow_source=true&p=${p}&platform=web&play_session_id=${id}&sig=${tokens.signature}&supported_codecs=av1,h264&token=${encodeURIComponent(tokens.value)}&transcode_mode=cbr_v1`;
    +                    }
    +                } catch { }
    +            }
    +        }
    +    },
         {
             name: "Reddit",
             url: /reddit\.com|redd\.it/,
    @@ -838,58 +890,6 @@ var siteInfo = [
                 }
             }
         },
    -    {
    -        name: "Twitch",
    -        url: /^https:\/\/(www\.twitch\.tv\/|www\.reddit\.com\/r\/TwitchClips\/)/,
    -        xhr: {
    -            url: function(a, p, xhr) {
    -                if (!a) return;
    -                if (!/twitch\.tv/.test(a.href)) return;
    -                let m = a.href.match(/(\/clip\/|clips\.twitch\.tv\/)([^?]{1,})/);
    -                if (m) {
    -                    var slug = m[2];
    -                    var operationNameClip = "VideoAccessToken_Clip";
    -                    var operationNameLiveOrVOD = "PlaybackAccessToken";
    -                    var sha256HashClip = "36b89d2507fce29e5ca551df756d27c1cfe079e2609642b4390aa4c35796eb11";
    -                    var sha256HashLiveOrVOD = "0828119ded1c13477966434e15800ff57ddacf13ba1911c129dc2200705b0712";
    -                    return `https://gql.twitch.tv/gql#p{{"operationName":"${operationNameClip}","variables":{"slug":"${slug}"},"extensions":{"persistedQuery":{"version":1,"sha256Hash":"${sha256HashClip}"}}}}`;
    -                } else {
    -                    m = a.href.match(/(?:m\.|www\.)?twitch\.tv\/(?:(?!directory|downloads|jobs|store|twitchartists|turbo|privacy)(\w+)$|(?:\w+\/)?videos\/(\d+))/);
    -                    if (m) {
    -                        xhr.m = m;
    -                        return `https://gql.twitch.tv/gql#p{{"operationName":"PlaybackAccessToken_Template","query":"query PlaybackAccessToken_Template($login: String!, $isLive: Boolean!, $vodID: ID!, $isVod: Boolean!, $playerType: String!, $platform: String!) {  streamPlaybackAccessToken(channelName: $login, params: {platform: $platform, playerBackend: \\"mediaplayer\\", playerType: $playerType}) @include(if: $isLive) {    value    signature   authorization { isForbidden forbiddenReasonCode }   __typename  }  videoPlaybackAccessToken(id: $vodID, params: {platform: $platform, playerBackend: \\"mediaplayer\\", playerType: $playerType}) @include(if: $isVod) {    value    signature   __typename  }}","variables":{"isLive":${m[1]?'true':'false'},"login":"${m[1]||''}","isVod":true,"vodID":"${m[2]||''}","playerType":"site","platform":"web"}}}`;
    -                    }
    -                }
    -            },
    -            headers: function(url, xhr, getCookie) {
    -                return {"Client-ID":"kimne78kx3ncx6brgo4mv6wki5h1ko", "X-Device-Id": getCookie('unique_id') || getCookie('unique_id_durable') || 'd56e8463c57c7cd7'}
    -            },
    -            cacheNum: 20,
    -            query: function(html, doc, u, xhr) {
    -                try {
    -                    let r = JSON.parse(html);
    -                    if (r.data.clip) {
    -                        let signature = r.data.clip.playbackAccessToken.signature;
    -                        let token = r.data.clip.playbackAccessToken.value;
    -                        let t = JSON.parse(token);
    -                        let clip_uri = r.data.clip.videoQualities[0].sourceURL;
    -                        let fullsizeUrl = clip_uri + '?sig=' + signature + '&token=' + encodeURIComponent(token);
    -
    -                        return {url: ["video:" + fullsizeUrl], cap: ""};
    -                    } else {
    -                        let tokens = r.data.streamPlaybackAccessToken || r.data.videoPlaybackAccessToken;
    -                        if (!tokens) return;
    -                        let hex = ['A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    -                        let url = xhr.m[1] ? 'api/channel/hls': 'vod';
    -                        let p = Math.floor(999999 * Math.random());
    -                        let id = '';
    -                        for (let i = 0; i < 32; i++) id += hex[Math.floor(Math.random() * 16)];
    -                        return `video:https://usher.ttvnw.net/${url}/${xhr.m[1]||xhr.m[2]}.m3u8?acmb=eyJBcHBWZXJzaW9uIjoiYjlhNjU4ZWMtMTcyMS00Y2FjLThkMjgtZjk0NmJmY2E3YzUwIn0%3D&allow_source=true&p=${p}&platform=web&play_session_id=${id}&sig=${tokens.signature}&supported_codecs=av1,h264&token=${encodeURIComponent(tokens.value)}&transcode_mode=cbr_v1`;
    -                    }
    -                } catch { }
    -            }
    -        }
    -    },
         {
             name: "Rule34hentai",
             url: /rule34hentai\.net/,
    
    From 66a3743f299d4e5e24eaecd1b5d3faae06c6c620 Mon Sep 17 00:00:00 2001
    From: hoothin 
    Date: Thu, 24 Jul 2025 23:52:44 +0900
    Subject: [PATCH 0736/1065] Update Picviewer CE+.user.js
    
    ---
     Picviewer CE+/Picviewer CE+.user.js | 322 +++++++++++++++++++++++-----
     1 file changed, 268 insertions(+), 54 deletions(-)
    
    diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js
    index 57d8e1607f7..8bd80cec569 100644
    --- a/Picviewer CE+/Picviewer CE+.user.js	
    +++ b/Picviewer CE+/Picviewer CE+.user.js	
    @@ -12,7 +12,7 @@
     // @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              2025.7.22.1
    +// @version              2025.7.24.1
     // @icon                 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg==
     // @namespace            https://github.com/hoothin/UserScripts
     // @homepage             https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B
    @@ -46,7 +46,7 @@
     // @grant                GM.notification
     // @grant                unsafeWindow
     // @require              https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js
    -// @require              https://update.greasyfork.org/scripts/438080/1615955/pvcep_rules.js
    +// @require              https://update.greasyfork.org/scripts/438080/1629578/pvcep_rules.js
     // @require              https://update.greasyfork.org/scripts/440698/1427239/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
    @@ -12231,6 +12231,141 @@ ImgOps | https://imgops.com/#b#`;
                 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();
    +            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(';');
    @@ -16067,12 +16202,18 @@ ImgOps | https://imgops.com/#b#`;
                                 curNode.dataset.src = curNode.dataset.thumbSrc;
                                 popupImgWin(i);
                             };
    -                        let loadImg = () => {
    +                        let loadImg = async() => {
                                 self.showTips("Loading image...");
     
                                 let imgSrc = dataset(node, 'src');
                                 let mode = matchedRule.getMode(imgSrc);
                                 let media;
    +                            let loaded = function() {
    +                                media.play();
    +                                self.showTips("");
    +                                popupImgWin(this || media);
    +                                media.removeEventListener('loadeddata', loaded);
    +                            }
                                 switch (mode) {
                                     case "video":
                                         media = document.createElement('video');
    @@ -16084,7 +16225,15 @@ ImgOps | https://imgops.com/#b#`;
                                         media.volume = matchedRule.mute ? 0 : 1;
                                         imgSrc = imgSrc.replace(/^video:/, "");
                                         if (imgSrc.indexOf('.mkv') !== -1) media.type = 'video/mp4';
    -                                    else if (imgSrc.indexOf('.m3u8') !== -1) media.type = 'application/vnd.apple.mpegurl';
    +                                    else if (imgSrc.indexOf('.m3u8') !== -1) {
    +                                        try {
    +                                            loaded();
    +                                            await initVideojs(media, imgSrc);
    +                                            imgSrc = "";
    +                                        } catch (error) {
    +                                            console.error('Failed to load or initialize Video.js player:', error);
    +                                        }
    +                                    }
                                         break;
                                     case "audio":
                                         media = document.createElement('audio');
    @@ -16097,15 +16246,11 @@ ImgOps | https://imgops.com/#b#`;
                                         break;
                                 }
                                 if (media) {
    -                                media.src = imgSrc;
    -                                let loaded = function() {
    -                                    media.play();
    -                                    self.showTips("");
    -                                    popupImgWin(this);
    -                                    media.removeEventListener('loadeddata', loaded);
    +                                if (imgSrc) {
    +                                    media.src = imgSrc;
    +                                    media.addEventListener('loadeddata', loaded);
    +                                    media.load();
                                     }
    -                                media.addEventListener('loadeddata', loaded);
    -                                media.load();
                                 } else {
                                     imgReady(imgSrc, {
                                         ready: function() {
    @@ -16382,7 +16527,7 @@ ImgOps | https://imgops.com/#b#`;
                         thumbScrollbar.scroll(needScrollDis - scrollCenter,false,!noTransition);
                     }, 0);
                 },
    -            getImg:function(ele){
    +            getImg:async function(ele){
                     var self = this;
     
                     var src = dataset(ele,'src');
    @@ -16460,6 +16605,19 @@ ImgOps | https://imgops.com/#b#`;
     
                     if (!src) return;
                     let media, mediaSrc = src;
    +                let loaded = function() {
    +                    var index = allLoading.indexOf(src);
    +                    if (index != -1) {
    +                        allLoading.splice(index,1);
    +                    }
    +
    +                    if (src != self.lastLoading) return;
    +
    +                    if (loadingIndicator && loadingIndicator.style) loadingIndicator.style.display = '';
    +                    if (preImgR) preImgR.abort();
    +                    self.loadImg(media, ele);
    +                    media.removeEventListener('loadeddata', loaded);
    +                }
                     if (isVideoLink(src)) {
                         media = document.createElement('video');
                         media.style.width = 0;
    @@ -16470,7 +16628,25 @@ ImgOps | https://imgops.com/#b#`;
                         media.volume = matchedRule.mute ? 0 : 1;
                         mediaSrc = mediaSrc.replace(/^video:/, "");
                         if (src.indexOf('.mkv') !== -1) media.type = 'video/mp4';
    -                    else if (src.indexOf('.m3u8') !== -1) media.type = 'application/vnd.apple.mpegurl';
    +                    else if (src.indexOf('.m3u8') !== -1) {
    +                        try {
    +                            loaded();
    +                            await initVideojs(media, mediaSrc);
    +                            media.onload = e => {
    +                                self.imgNaturalSize = {
    +                                    h:media.naturalHeight || 100,
    +                                    w:media.naturalWidth || 100,
    +                                };
    +                                self.fitToScreen({
    +                                    x:0,
    +                                    y:0,
    +                                });
    +                            };
    +                            mediaSrc = "";
    +                        } catch (error) {
    +                            console.error('Failed to load or initialize Video.js player:', error);
    +                        }
    +                    }
                     } else if (isAudioLink(src)) {
                         media = document.createElement('audio');
                         media.controls = true;
    @@ -16482,22 +16658,12 @@ ImgOps | https://imgops.com/#b#`;
                         if (this.eleMaps['sidebar-toggle'].style.visibility == 'hidden') {
                             media.autoplay = false;
                         }
    -                    media.src = mediaSrc;
    -                    let loaded = function() {
    -                        var index = allLoading.indexOf(src);
    -                        if (index != -1) {
    -                            allLoading.splice(index,1);
    -                        }
    -
    -                        if (src != self.lastLoading) return;
    -
    -                        if (loadingIndicator && loadingIndicator.style) loadingIndicator.style.display = '';
    -                        if (preImgR) preImgR.abort();
    -                        self.loadImg(media, ele);
    -                        media.removeEventListener('loadeddata', loaded);
    +                    if (mediaSrc) {
    +                        media.src = mediaSrc;
    +                        curLoadingMedia = media;
    +                        media.addEventListener('loadeddata', loaded);
    +                        media.load();
                         }
    -                    media.addEventListener('loadeddata', loaded);
    -                    media.load();
                         return;
                     }
                     this.imgReady=imgReady(src, {
    @@ -16548,6 +16714,9 @@ ImgOps | https://imgops.com/#b#`;
     
                 },
                 loadImg:function(img,relatedThumb,error){
    +                [].forEach.call(this.eleMaps['img-parent'].querySelectorAll("[id^=vjs_video]"), video => {
    +                    video.parentNode.removeChild(video);
    +                });
                     if(!/^(img|video|audio)$/i.test(img.nodeName)){//先读取。
                         this.getImg(img);
                         return;
    @@ -16560,8 +16729,8 @@ ImgOps | https://imgops.com/#b#`;
                     var imgNaturalSize;
                     if (/^video$/i.test(img.nodeName)) {
                         imgNaturalSize = {
    -                        h:img.videoHeight || 200,
    -                        w:img.videoWidth || 200,
    +                        h:img.videoHeight || 1080,
    +                        w:img.videoWidth || 1920,
                         };
                     } else if (/^audio$/i.test(img.nodeName)) {
                         imgNaturalSize = {
    @@ -16710,6 +16879,7 @@ ImgOps | https://imgops.com/#b#`;
                     var imgPaSty=img.parentNode.style;
                     imgPaSty.width='';
                     imgPaSty.height='';
    +                imgPaSty=this.eleMaps['img-parent'].style;
     
                     let rotate90 = this.galleryRotate == 90 || this.galleryRotate == 270;
                     let imgNaturalSize = rotate90 ? {w: this.imgNaturalSize.h, h: this.imgNaturalSize.w} : this.imgNaturalSize;
    @@ -18846,6 +19016,9 @@ ImgOps | https://imgops.com/#b#`;
                         justify-content: center;\
                         line-height:0;\
                         }\
    +                    .pv-gallery-img-parent video, .pv-gallery-img-parent>div{\
    +                    background-size: cover;\
    +                    }\
                         .pv-gallery-img_broken{\
                         display:none;\
                         cursor:pointer;\
    @@ -20261,6 +20434,7 @@ ImgOps | https://imgops.com/#b#`;
     
                     let imgbox=container.firstChild;
                     imgbox.appendChild(img);
    +                this.imgbox = imgbox;
     
                     this.imgWindow=container;
     
    @@ -20420,8 +20594,8 @@ ImgOps | https://imgops.com/#b#`;
                         setSearchState(`${img.naturalWidth} x ${img.naturalHeight}`, self.imgState);
                     }
                     if (!this.isImg) {
    -                    img.naturalHeight = img.videoHeight || 80;
    -                    img.naturalWidth = img.videoWidth || 300;
    +                    img.naturalHeight = img.videoHeight || 1080;
    +                    img.naturalWidth = img.videoWidth || 1920;
                         setTimeout(() => {
                             img.onload();
                         }, 0);
    @@ -22034,8 +22208,8 @@ ImgOps | https://imgops.com/#b#`;
                         };
                         img.width=afterImgSize.w;
                         img.height=afterImgSize.h;
    -                    img.parentNode.style.width=afterImgSize.w + 'px';
    -                    img.parentNode.style.height=afterImgSize.h + 'px';
    +                    self.imgbox.style.width=afterImgSize.w + 'px';
    +                    self.imgbox.style.height=afterImgSize.h + 'px';
                         if (afterImgSize.w < 60) {
                             self.imgState.style.display = "none";
                         } else {
    @@ -23125,11 +23299,16 @@ ImgOps | https://imgops.com/#b#`;
                 },
     
                 // 根据 imgSrc 载入图片,imgSrcs 为备用图片地址,imgSrc 加载失败备用
    -            loadImg: function(imgSrc, imgSrcs, nextFun) {
    +            loadImg: async function(imgSrc, imgSrcs, nextFun) {
                     var self = this;
     
                     var mode = matchedRule.getMode(imgSrc);
                     var media;
    +                let loaded = function() {
    +                    media.play();
    +                    self.load(this || media);
    +                    media.removeEventListener('loadeddata', loaded);
    +                }
                     if (this.buttonType === 'magnifier') {
                         media = document.createElement('img');
                         media.src = (mode === "video" || mode === "audio") ? this.data.imgSrc : imgSrc;
    @@ -23146,7 +23325,15 @@ ImgOps | https://imgops.com/#b#`;
                                 media.volume = matchedRule.mute ? 0 : 1;
                                 imgSrc = imgSrc.replace(/^video:/, "");
                                 if (imgSrc.indexOf('.mkv') !== -1) media.type = 'video/mp4';
    -                            else if (imgSrc.indexOf('.m3u8') !== -1) media.type = 'application/vnd.apple.mpegurl';
    +                            else if (imgSrc.indexOf('.m3u8') !== -1) {
    +                                try {
    +                                    loaded();
    +                                    await initVideojs(media, imgSrc);
    +                                    imgSrc = "";
    +                                } catch (error) {
    +                                    console.error('Failed to load or initialize Video.js player:', error);
    +                                }
    +                            }
                                 break;
                             case "audio":
                                 media = document.createElement('audio');
    @@ -23159,7 +23346,8 @@ ImgOps | https://imgops.com/#b#`;
                                 media = document.createElement('img');
                                 break;
                         }
    -                    media.src = imgSrc;
    +                    if (imgSrc) media.src = imgSrc;
    +                    curLoadingMedia = media;
                     }
     
                     var opts = {
    @@ -23182,13 +23370,10 @@ ImgOps | https://imgops.com/#b#`;
                     };
     
                     if (mode === 'video' || mode === 'audio') {
    -                    let loaded = function() {
    -                        media.play();
    -                        self.load(this);
    -                        media.removeEventListener('loadeddata', loaded);
    +                    if (imgSrc) {
    +                        media.addEventListener('loadeddata', loaded);
    +                        media.load();
                         }
    -                    media.addEventListener('loadeddata', loaded);
    -                    media.load();
                     } else {
                         self.imgReady = imgReady(media, opts);
                     }
    @@ -23887,7 +24072,7 @@ ImgOps | https://imgops.com/#b#`;
                         var iurl, iurls = [], cap, caps, doc = createDoc(html);
     
                         if(typeof q == 'function') {
    -                        iurl = await q(html, doc, url, xhr);
    +                        iurl = await q(html, doc, url + (post ? `#p{${post}}` : ""), xhr);
                             if (iurl) {
                                 if(iurl.url) {
                                     cap = iurl.cap;
    @@ -23928,9 +24113,9 @@ ImgOps | https://imgops.com/#b#`;
                                 cap: cap,
                                 caps: caps
                             };
    -                        caches[url] = cacheData;
    +                        caches[url + (post || "")] = cacheData;
                             if (cacheNum) {
    -                            storage.setListItem("xhrCache", url, cacheData, cacheNum);
    +                            storage.setListItem("xhrCache", url + (post || ""), cacheData, cacheNum);
                             }
                         }
     
    @@ -23959,7 +24144,7 @@ ImgOps | https://imgops.com/#b#`;
                     }
                     if (headers) {
                         if (typeof headers == 'function') {
    -                        headers = await headers(url, xhr);
    +                        headers = await headers(url, xhr, getCookie);
                         }
                         opts.headers = headers;
                     }
    @@ -24023,7 +24208,7 @@ ImgOps | https://imgops.com/#b#`;
                         opt.url = opt.url.replace(/#p{.*/, "");
                     }
     
    -                parsePage(opt.url, xhr.query || xhr.q, xhr.caption || xhr.c, xhr.post, opt.cb, xhr.headers, xhr.after);
    +                parsePage(opt.url, xhr.query || xhr.q, xhr.caption || xhr.c, opt.post, opt.cb, xhr.headers, xhr.after);
                 };
     
                 return _;
    @@ -25278,12 +25463,16 @@ ImgOps | https://imgops.com/#b#`;
                         return;
                     }
     
    -
    -                if (target.nodeName.toUpperCase() == 'A' && imageReg.test(target.href)) {
    -                } else if (target.parentNode && target.parentNode.nodeName.toUpperCase() == 'A' && imageReg.test(target.parentNode.href)) {
    +                let i = 0;
    +                while(target) {
    +                    if (i++ > 5) {
    +                        target = null;
    +                        break;
    +                    }
    +                    if ((target.nodeName == 'A' || target.nodeName == 'a') && imageReg.test(target.href)) {
    +                        break;
    +                    }
                         target = target.parentNode;
    -                } else {
    -                    target = null;
                     }
                     if (target) {
                         let src = target.href;
    @@ -25444,6 +25633,31 @@ ImgOps | https://imgops.com/#b#`;
                 initMouse = false;
             });
     
    +        var curLoadingMedia;
    +        document.addEventListener('securitypolicyviolation', (e) => {
    +            if (!e.violatedDirective.includes('media-src')) {
    +                return;
    +            }
    +            if (curLoadingMedia && curLoadingMedia.src == e.blockedURI) {
    +                GM_xmlhttpRequest({
    +                    method: 'GET',
    +                    url: curLoadingMedia.src,
    +                    responseType: 'blob',
    +                    onload: function(response) {
    +                        const blobUrl = URL.createObjectURL(response.response);
    +
    +                        curLoadingMedia.src = blobUrl;
    +                        curLoadingMedia.load();
    +                        videoElement.play().catch(err => console.warn('[CSP Fixer] Autoplay after fix was blocked.', err));
    +
    +                        const releaseBlob = () => URL.revokeObjectURL(blobUrl);
    +                        videoElement.addEventListener('ended', releaseBlob);
    +                        window.addEventListener('beforeunload', releaseBlob);
    +                    }
    +                });
    +            }
    +        });
    +
             async function input(sel, v) {
                 await new Promise((resolve) => {
                     let checkInv = setInterval(() => {
    
    From 7113af8f27347ada5462cc1d5c677f8ba7c2ee95 Mon Sep 17 00:00:00 2001
    From: hoothin 
    Date: Fri, 25 Jul 2025 11:05:49 +0900
    Subject: [PATCH 0737/1065] Update Picviewer CE+.user.js
    
    ---
     Picviewer CE+/Picviewer CE+.user.js | 3 ++-
     1 file changed, 2 insertions(+), 1 deletion(-)
    
    diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js
    index 8bd80cec569..f46b47c9272 100644
    --- a/Picviewer CE+/Picviewer CE+.user.js	
    +++ b/Picviewer CE+/Picviewer CE+.user.js	
    @@ -12356,6 +12356,7 @@ ImgOps | https://imgops.com/#b#`;
                 }
                 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();
    @@ -24144,7 +24145,7 @@ ImgOps | https://imgops.com/#b#`;
                     }
                     if (headers) {
                         if (typeof headers == 'function') {
    -                        headers = await headers(url, xhr, getCookie);
    +                        headers = await headers(url + (post ? `#p{${post}}` : ""), xhr, getCookie);
                         }
                         opts.headers = headers;
                     }
    
    From db8aeea5ac84dad7adc39069b1b436e68f03a157 Mon Sep 17 00:00:00 2001
    From: hoothin 
    Date: Fri, 25 Jul 2025 15:12:20 +0900
    Subject: [PATCH 0738/1065] Update README.md
    
    ---
     Picviewer CE+/README.md | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md
    index 1c23c4d997d..30cb4699344 100644
    --- a/Picviewer CE+/README.md	
    +++ b/Picviewer CE+/README.md	
    @@ -1,4 +1,4 @@
    -# 🏞️ Picviewer CE+ ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) 🌐[Reddit](https://www.reddit.com/r/PicviewerCE) 🗨️[Discord](https://discord.com/invite/keqypXC6wD) 🕊️[Twitter](https://twitter.com/intent/follow?screen_name=HoothinDev) [⏬](https://greasyfork.org/scripts/24204-picviewer-ce/code/Picviewer%20CE+.user.js)
    +# 🏞️ Picviewer CE+ ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) 🌐[Reddit](https://www.reddit.com/r/PicviewerCE) 🗨️[Discord](https://discord.com/invite/keqypXC6wD) 🕊️[Twitter](https://twitter.com/intent/follow?screen_name=HoothinDev) [⏬](https://hoothin.github.io/UserScripts/Picviewer%20CE+/Picviewer%20CE+.user.js)
     
     > Zoom images across all your favorite websites. Pop up, scale, edit, rotate, batch save images, or automatically load pictures from subsequent pages. Simply hover your mouse over any image and click the icons on the float bar.
     
    
    From fd8a8388dfc1ce8112dbc844e8438a064c8f9f05 Mon Sep 17 00:00:00 2001
    From: hoothin 
    Date: Sat, 26 Jul 2025 15:28:30 +0900
    Subject: [PATCH 0739/1065] Update Easy offline.user.js
    
    ---
     Easy offline/Easy offline.user.js | 10 ++++++----
     1 file changed, 6 insertions(+), 4 deletions(-)
    
    diff --git a/Easy offline/Easy offline.user.js b/Easy offline/Easy offline.user.js
    index cbbc935b5d1..a95eadbffb3 100644
    --- a/Easy offline/Easy offline.user.js	
    +++ b/Easy offline/Easy offline.user.js	
    @@ -1209,12 +1209,13 @@
                                     if(/^c:/.test(url)){
                                         urlArr.push(url.replace(/^c:/i,""));
                                     }else if(/^p:/.test(url)){
    -                                    url=url.match(/p:(.*?)\?(.*)/);
    +                                    url=url.match(/p:(.*?)\?(.*?)(\$headers({.*}))?$/);
                                         if(!url)return;
                                         let postData=JSON.stringify(urlArgs(url[2]));
    +                                    let headers = url[4] ? JSON.parse(url[4]) : null;
                                         url=url[1];
                                         _GM_xmlhttpRequest({
    -                                        method: "POST", url: url, data: postData,
    +                                        method: "POST", url: url, data: postData, headers: headers,
                                             onload: (d) => {
                                                 _GM_notification(i18n("postOver")+d.statusText);
                                             },
    @@ -1243,12 +1244,13 @@
                                 _GM_setClipboard(url.replace(/^c:/i,""));
                                 _GM_notification(i18n("copyOver"));
                             }else if(/^p:/.test(url)){
    -                            url=url.match(/p:(.*?)\?(.*)/);
    +                            url=url.match(/p:(.*?)\?(.*?)(\$headers({.*}))?$/);
                                 if(!url)return;
                                 let postData=JSON.stringify(urlArgs(url[2]));
    +                            let headers = url[4] ? JSON.parse(url[4]) : null;
                                 url=url[1];
                                 _GM_xmlhttpRequest({
    -                                method: "POST", url: url, data: postData,
    +                                method: "POST", url: url, data: postData, headers: headers,
                                     onload: (d) => {
                                         _GM_notification(i18n("postOver")+d.statusText);
                                     },
    
    From 087963871adbc8fb82d44a8b29ceffcea661acfe Mon Sep 17 00:00:00 2001
    From: hoothin 
    Date: Sat, 26 Jul 2025 15:36:59 +0900
    Subject: [PATCH 0740/1065] Update README.MD
    
    ---
     Easy offline/README.MD | 9 +++++++--
     1 file changed, 7 insertions(+), 2 deletions(-)
    
    diff --git a/Easy offline/README.MD b/Easy offline/README.MD
    index 6a26351630d..a0e3ba53343 100644
    --- a/Easy offline/README.MD	
    +++ b/Easy offline/README.MD	
    @@ -37,14 +37,14 @@ https://github.rc1844.workers.dev${https?://[^/]+(.*)}@@RC1844@@github\.com.*(re
     https://ghproxy.fsou.cc/$url@@Fsou@@github\.com.*(releases\/download|archive\/refs\/)@@@@ffff0f
     
    -### 自定義例子2 - Aria2下載 +### 自定義例子2 - Aria2 下載 同樣是點擊下方導入
     http://aria.hoothin.com/#!/new/$base64@@Aria2@@@@data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAABOFBMVEUAAADSVF7SVF7SVF7LVWDSVF7QVF/SVF7SVF7SVF7SVF7SVF7SVF7RVF7SVF7SVF7SVF7SVF7SVF7SVF7SVF7SVF7SVF5ma4Di4uLSVF7v7+9DQ0NvaX1+ZniUYXGtXGppan+cYG+TYXLs7OyyW2h4tsiVlJWxs7ylpaWgoKBwaX2JZHVRVFxNT1VNTU1KSkxGRkd0uMzKysp5tceHipjDV2JYWFrr5ufa2tvT09Pjycu9v8a5u8PCwsK+vr6rrbego6+Tp62pqamZnKmloaGjj5l5fY+MfY60gozDfIa3foJkaHzTX2hYW2i6UVluSEuK2/Pd3d7X0NLExcm1tbWRlKKbm5uohJCOjo6GhoqOeInPgIh0coV8fHx7e3vRbXbObXaNY3SgX25hYmRhYWHJVmGOTFGNTFENIl9FAAAAF3RSTlMAJNEM+vr1iQjpyFfr6pybmjLusJhyIzaw7jcAAAHlSURBVDjLfZNnU+NADIbXduyQBBLq2fK6JcQmF0gvtOOOztGv90Ln//8Ddm3txkNmeD54vNI7klYrkRFaYT6f0/Vcfr6gkXGUklH13HoQ1F2vapSUZ+6JbKbsmIzvR/zrlDPZibT/lerXTc4fuDJj6r6aCjKTq5gJZwDH+FvJzcj0U8to/A+M93hYnlIwv+qh6RhijkQMNakj66PhF8BBr3cAZwEa/GxcYMbB8284CT90whOZxMnwJKUyHvurG/thpxPub3wykXKR9c8QATZtu7YT9nZqlvVVhDA0Uqji4XDVtrdeM95a1uYhGqsFMi2usGfb9uJWrcb81toeGr1pknfxf8nmLFox79Do5smkKOFNWrAkipgkevCSINBRMJ5CCmSK7ZTg47ZMMSqyHwt+fOOCbl8WObrm0OKC4R0X7A5PxTVlo87pFy5oNrngLz0XjZKtXqH/uIBSLmjRhmw1KSaP1WIuIdiltCUfiyjJc7cp/bm2vt5qd7ufbylt43OPBoayqFEUNZtRZJ42KE0GBkeuwgUr7FIAl5cArHWNdjxyWmpomd+8AXh8ALjmNcuhTY/9AODiAsCXYy9RVN/hGRLuXVafWJz06nmAeLh6z5d3AMjAKCpkHG1hTp3V9Vl1biG1/k8fR16xKi9r1wAAAABJRU5ErkJggg==@@ff2a00
     
    *之所以把Aria2做成自定義是因為每個人的Aria2UI網址都不一樣,用我的伺服器管理本地的Aria2服務需要允許Chrome訪問本地資源,訪問 chrome://flags/#block-insecure-private-network-requests 並關閉即可。不想關閉的話直接打開設置把上面的網址換成自己本地的即可,例如 127.0.0.1 -### 自定義例子3 - Post請求RPC遠程下載 +### 自定義例子3 - Post 請求 RPC 遠程下載
     p:http://192.168.32.1:6800/jsonrpc?id=$random&jsonrpc=2.0&method=aria2.addUri&params=["token:123456",["$url"]]@@Aria2RPC@@@@@@df2a00
     
    @@ -68,6 +68,11 @@ https://translate.google.com/?client=gtx&dj=1&q=$text&sl=auto&tl=zh-CN&hl=zh-CN& $text{[^\w\-_\.~!\*'();:@&=\+\$,\/\?#\[\]%]}@@GetLink@@@@@@f9ff9f
    +### 自定義例子7 - Post 請求 OpenList(原AList)遠程下載 +
    +p:https://alist.domain.com/api/fs/add_offline_download?path=/115网盘/OpList离线下载&tool=115%20Cloud&delete_policy=delete_on_upload_succeed&urls=["$url"]$headers{"Content-Type": "application/json","Authorization": "alist-50a563b4-and-more-token-chars", "Accept": "*/*", "Host": "alist.domain.com", "Connection": "keep-alive"}@@OpenList@@@@@@df2a11
    +
    + ### Update - **`Alt + F9`** 自定義下載,選中文本超鏈則下載文本超鏈,鼠標指向鏈接則下載鏈接,沒有選中則彈框輸入鏈接下載 From 824502ef026c391a8c6068f61936609b491fd1c3 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 26 Jul 2025 21:57:48 +0900 Subject: [PATCH 0741/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 73 ++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 4fd9481a669..f1e20c558e4 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -807,18 +807,15 @@ var siteInfo = [ } return this.src; }, - getExtSrc: function() { - if (/^https?:\/\/imgur\.com(\/a)?\/\w{5,}/.test(this.href)) { - return this.href.replace(/^https?:\/\/imgur\.com(\/a)?\/(\w+)/, "https://i.imgur.com/$2.webp"); - } - }, xhr: { url: function(a, p, self) { - if (a && a.href && /\/\/v.redd\.it\/\w+\/?$/.test(a.href)) { - return a.href + '/DASHPlaylist.mpd'; - } else if (a && a.href && /^https:\/\/www\.reddit\.com\/gallery\//.test(a.href)) { - return a.href.replace(/.*(reddit\.com\/)gallery\/([\da-z]+).*/, "https://www.$1by_id/t3_$2.json"); - } else if (a && a.href && /redgifs\.com\//.test(a.href)) { + let aHref = a && a.href; + const imgurReg = /^https?:\/\/(?:(?:[im].)?(?:imgur.(?:com|io)|filmot.(?:com|org))\/+(?:(?:(a|gallery(?!\/random|\/custom)|t(?:opic)?\/[^/]+)|r\/[^/]+)\/(?:[^-/]+-)*([^W_]{5}(?:[^_W]{2})?)|(?:[^W_]{5}(?:[^W_]{2})?[,&])+[^_W]{5}(?:[^W_]{2})?)).*/; + if (/\/\/v.redd\.it\/\w+\/?$/.test(aHref)) { + return aHref + '/DASHPlaylist.mpd'; + } else if (/^https:\/\/www\.reddit\.com\/gallery\//.test(aHref)) { + return aHref.replace(/.*(reddit\.com\/)gallery\/([\da-z]+).*/, "https://www.$1by_id/t3_$2.json"); + } else if (/redgifs\.com\//.test(aHref)) { const apiUrl = 'https://api.redgifs.com/v2'; if (!self.redgifsToken) { self.redgifsToken = "1"; @@ -828,7 +825,10 @@ var siteInfo = [ } }); } - return apiUrl + "/gifs/" + a.href.replace(/.*redgifs.com\/(..\/)?(\w+\/)?(\w+)(?:\.\w+)?/, '$3');; + return apiUrl + "/gifs/" + aHref.replace(/.*redgifs.com\/(..\/)?(\w+\/)?(\w+)(?:\.\w+)?/, '$3');; + } else if (imgurReg.test(aHref)) { + const m = aHref.match(imgurReg); + return m[1] ? 'https://imgur.com/' + (m[1] == 'a' ? 'a/' + m[2] + '/embed' : m[1] + '/' + m[2] + '/hit.json') : m[0]; } else if (p[1] && p[1].classList.contains("search-result")) { let link = p[1].querySelector("a.search-link"); if (link && link.href) { @@ -847,6 +847,54 @@ var siteInfo = [ }, query: function(html, doc, url) { try { + if (/^https:\/\/imgur\.com\//.test(url)) { + var cap = [], urls = [], im, g, c, x, i, t, u, l = '//i.imgur.com/', p404='404 page'; + try { + if (typeof html == 'string' && html[0]!='{') { + if(html.lastIndexOf(p404, 300) > -1) throw true; + x = html.match(/(?:album|image)\s*[:=] +([^\n\r]+),/); + x = JSON.parse(x[1]) + t = window.t; if (window.t) delete window.t; + if (!t&&'title' in x)t = x; + x.album_images&&(x=x.album_images); + x.images&&(x=x.images)||x.items&&(x=x.items); + } else { + html=JSON.parse(html); + if(html.album){ + x=html.album + t={title:x.title, description: x.description} + x=x.images + } else { + x=html.data.image + if (x.is_album) { + t={title:x.title, description: x.description} + if (x.album_images.count != x.album_images.images.length) { + window.t=t + return; + } + x=x.album_images.images + } + } + if (window.t) delete window.t; + } + + if (!x)throw html.lastIndexOf(p404, 300) > -1; + + t = t && [t.title, t.description].filter(Boolean).join(' - ') || !1 + x = Array.isArray(x)?x:[x] + for (i = 0; i < x.length; ++i) { + im = x[i].image||x[i]; + c = [im.title, im.caption, im.description].filter(Boolean).join(' - '); + if (!i && t && t!=c) c='['+t+'] ' + c; + im.ext = im.ext || x[i].links.original.match(/\.[^.]+$/)[0]; + g = (''+im.animated)=='true' + u = l + im.hash; + urls.push(!g && im.width <= 1200 && im.height <= 1200 ? u + im.ext : (g ? [u + '.mp4', u + '.gif'] : ['#' + u + im.ext, u + 'h' + im.ext])); + cap.push(c); + } + } catch (ex) {} + return urls.length ? {url: urls, cap: cap} : null + } if (/redgifs\.com\//.test(url)) { let data; try { @@ -860,10 +908,11 @@ var siteInfo = [ } else if (/\/by_id\//.test(url)) { let data; try { - data = JSON.parse(html).data.children[0].data; + data = JSON.parse(html); } catch (e) { return; } + data = data.data.children[0].data; return (data.gallery_data && data.gallery_data.items || []).map(function(c, i) { var u=data.media_metadata[c.media_id].s return [ From a3395ff9d72b69a00dd069985cdd797f0f887724 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 26 Jul 2025 21:59:30 +0900 Subject: [PATCH 0742/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index f46b47c9272..00452e5654c 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.7.24.1 +// @version 2025.7.26.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1629578/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1630518/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -20542,7 +20542,7 @@ ImgOps | https://imgops.com/#b#`; this.curIndex = -1; if (this.data && this.data.all && this.data.all.length > 1) { for (let i = 0; i < this.data.all.length; i++) { - if (this.data.all[i].replace(/^(video|audio):/, "") == this.data.src) { + if (this.data.src.indexOf(this.data.all[i].replace(/^(video|audio):/, "")) !== -1) { this.curIndex = i; break; } @@ -20617,8 +20617,15 @@ ImgOps | https://imgops.com/#b#`; */ if (this.data) { var descriptionSpan = container.querySelector('.pv-pic-window-description'); - let desc = (this.data.description || '').trim(); - descriptionSpan.textContent = desc; + let desc = (this.data.description || ''); + if (Array.isArray(this.data.description) && Array.isArray(this.data.all)) { + let curIndex; + for (curIndex = 0; curIndex < this.data.all.length; curIndex++) { + if (this.data.src.indexOf(this.data.all[curIndex].replace(/^(video|audio):/, "")) !== -1) break; + } + desc = desc[curIndex] || desc[0] || ""; + } + descriptionSpan.textContent = desc.trim(); this.imgStateBox.title = desc; descriptionSpan.style.display = desc ? "inline" : "none"; this.descriptionSpan = descriptionSpan; @@ -20956,7 +20963,7 @@ ImgOps | https://imgops.com/#b#`; let imgData = this.data; let curIndex; for (curIndex = 0; curIndex < this.data.all.length; curIndex++) { - if (this.data.all[curIndex].replace(/^(video|audio):/, "") == this.data.src) break; + if (this.data.src.indexOf(this.data.all[curIndex].replace(/^(video|audio):/, "")) !== -1) break; } if (fw) { curIndex++; From a25c5b11d7aa339afb9e651fa069056dfbaa8983 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 27 Jul 2025 15:01:37 +0900 Subject: [PATCH 0743/1065] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 909b0086f6f..05ba8eee4e2 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ ## Contributors - + ## Star History From caa1cbcc6c47193c25f36a3fad3282552ac09c40 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 27 Jul 2025 16:10:21 +0900 Subject: [PATCH 0744/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 114 +++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index f1e20c558e4..a96ee806851 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -810,7 +810,6 @@ var siteInfo = [ xhr: { url: function(a, p, self) { let aHref = a && a.href; - const imgurReg = /^https?:\/\/(?:(?:[im].)?(?:imgur.(?:com|io)|filmot.(?:com|org))\/+(?:(?:(a|gallery(?!\/random|\/custom)|t(?:opic)?\/[^/]+)|r\/[^/]+)\/(?:[^-/]+-)*([^W_]{5}(?:[^_W]{2})?)|(?:[^W_]{5}(?:[^W_]{2})?[,&])+[^_W]{5}(?:[^W_]{2})?)).*/; if (/\/\/v.redd\.it\/\w+\/?$/.test(aHref)) { return aHref + '/DASHPlaylist.mpd'; } else if (/^https:\/\/www\.reddit\.com\/gallery\//.test(aHref)) { @@ -826,9 +825,6 @@ var siteInfo = [ }); } return apiUrl + "/gifs/" + aHref.replace(/.*redgifs.com\/(..\/)?(\w+\/)?(\w+)(?:\.\w+)?/, '$3');; - } else if (imgurReg.test(aHref)) { - const m = aHref.match(imgurReg); - return m[1] ? 'https://imgur.com/' + (m[1] == 'a' ? 'a/' + m[2] + '/embed' : m[1] + '/' + m[2] + '/hit.json') : m[0]; } else if (p[1] && p[1].classList.contains("search-result")) { let link = p[1].querySelector("a.search-link"); if (link && link.href) { @@ -847,54 +843,6 @@ var siteInfo = [ }, query: function(html, doc, url) { try { - if (/^https:\/\/imgur\.com\//.test(url)) { - var cap = [], urls = [], im, g, c, x, i, t, u, l = '//i.imgur.com/', p404='404 page'; - try { - if (typeof html == 'string' && html[0]!='{') { - if(html.lastIndexOf(p404, 300) > -1) throw true; - x = html.match(/(?:album|image)\s*[:=] +([^\n\r]+),/); - x = JSON.parse(x[1]) - t = window.t; if (window.t) delete window.t; - if (!t&&'title' in x)t = x; - x.album_images&&(x=x.album_images); - x.images&&(x=x.images)||x.items&&(x=x.items); - } else { - html=JSON.parse(html); - if(html.album){ - x=html.album - t={title:x.title, description: x.description} - x=x.images - } else { - x=html.data.image - if (x.is_album) { - t={title:x.title, description: x.description} - if (x.album_images.count != x.album_images.images.length) { - window.t=t - return; - } - x=x.album_images.images - } - } - if (window.t) delete window.t; - } - - if (!x)throw html.lastIndexOf(p404, 300) > -1; - - t = t && [t.title, t.description].filter(Boolean).join(' - ') || !1 - x = Array.isArray(x)?x:[x] - for (i = 0; i < x.length; ++i) { - im = x[i].image||x[i]; - c = [im.title, im.caption, im.description].filter(Boolean).join(' - '); - if (!i && t && t!=c) c='['+t+'] ' + c; - im.ext = im.ext || x[i].links.original.match(/\.[^.]+$/)[0]; - g = (''+im.animated)=='true' - u = l + im.hash; - urls.push(!g && im.width <= 1200 && im.height <= 1200 ? u + im.ext : (g ? [u + '.mp4', u + '.gif'] : ['#' + u + im.ext, u + 'h' + im.ext])); - cap.push(c); - } - } catch (ex) {} - return urls.length ? {url: urls, cap: cap} : null - } if (/redgifs\.com\//.test(url)) { let data; try { @@ -939,6 +887,68 @@ var siteInfo = [ } } }, + { + name: "imgurLink", + xhr: { + url: function(a, p) { + const imgurReg = /^https?:\/\/(?:(?:[im].)?(?:imgur.(?:com|io)|filmot.(?:com|org))\/+(?:(?:(a|gallery(?!\/random|\/custom)|t(?:opic)?\/[^/]+)|r\/[^/]+)\/(?:[^-/]+-)*([^W_]{5}(?:[^_W]{2})?)|(?:[^W_]{5}(?:[^W_]{2})?[,&])+[^_W]{5}(?:[^W_]{2})?)).*/; + if (a.href.match && imgurReg.test(a.href)) { + const m = a.href.match(imgurReg); + return m[1] ? 'https://imgur.com/' + (m[1] == 'a' ? 'a/' + m[2] + '/embed' : m[1] + '/' + m[2] + '/hit.json') : m[0]; + } + }, + query: function(html, doc, url) { + if (/^https:\/\/imgur\.com\//.test(url)) { + var cap = [], urls = [], im, g, c, x, i, t, u, l = '//i.imgur.com/', p404='404 page'; + try { + if (typeof html == 'string' && html[0]!='{') { + if(html.lastIndexOf(p404, 300) > -1) throw true; + x = html.match(/(?:album|image)\s*[:=] +([^\n\r]+),/); + x = JSON.parse(x[1]) + t = window.t; if (window.t) delete window.t; + if (!t&&'title' in x)t = x; + x.album_images&&(x=x.album_images); + x.images&&(x=x.images)||x.items&&(x=x.items); + } else { + html=JSON.parse(html); + if(html.album){ + x=html.album + t={title:x.title, description: x.description} + x=x.images + } else { + x=html.data.image + if (x.is_album) { + t={title:x.title, description: x.description} + if (x.album_images.count != x.album_images.images.length) { + window.t=t + return; + } + x=x.album_images.images + } + } + if (window.t) delete window.t; + } + + if (!x)throw html.lastIndexOf(p404, 300) > -1; + + t = t && [t.title, t.description].filter(Boolean).join(' - ') || !1 + x = Array.isArray(x)?x:[x] + for (i = 0; i < x.length; ++i) { + im = x[i].image||x[i]; + c = [im.title, im.caption, im.description].filter(Boolean).join(' - '); + if (!i && t && t!=c) c='['+t+'] ' + c; + im.ext = im.ext || x[i].links.original.match(/\.[^.]+$/)[0]; + g = (''+im.animated)=='true' + u = l + im.hash; + urls.push(!g && im.width <= 1200 && im.height <= 1200 ? u + im.ext : (g ? [u + '.mp4', u + '.gif'] : ['#' + u + im.ext, u + 'h' + im.ext])); + cap.push(c); + } + } catch (ex) {} + return urls.length ? {url: urls, cap: cap} : null + } + } + } + }, { name: "Rule34hentai", url: /rule34hentai\.net/, From 61b2b5e7b6978cd2a70061bb81cef75922043182 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 27 Jul 2025 16:16:53 +0900 Subject: [PATCH 0745/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 113 ++++++++++++++++------------ 1 file changed, 63 insertions(+), 50 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 00452e5654c..14b532a4d58 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.7.26.1 +// @version 2025.7.27.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1630518/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1630838/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -12554,8 +12554,8 @@ ImgOps | https://imgops.com/#b#`; descriptionLength: 32, // 注释的最大宽度 editSite: "", defaultSizeLimit:{ - w:160, - h:160 + w:80, + h:80 }, searchData:defaultSearchData, downloadWithZip:true, @@ -24573,47 +24573,6 @@ ImgOps | https://imgops.com/#b#`; if (site.mute) { self.mute = true; } - if (site.xhr) { - let siteXhr = site.xhr; - if (siteXhr.url && !self.getExtSrc) { - self.xhrLink = true; - self.getExtSrc = function (ele) { - ele = ele || this; - let newSrc; - let a; - if (ele && ele.href) { - a = ele; - } else { - a = ele.parentNode; - if (!a || !a.href) { - a = null; - } - } - if (siteXhr.url.test) { - if (a && siteXhr.url.test(a.href)) { - newSrc = a.href; - } - } else if (typeof siteXhr.url === 'string') { - try { - if (a && ele.matches(siteXhr.url)) { - newSrc = a.href; - } - } catch(e) { - debug(e); - } - } else { - newSrc = siteXhr.url.call(ele, a, [], siteXhr); - } - if (newSrc) { - self.xhr = siteXhr; - return newSrc; - } else { - self.xhr = null; - } - return newSrc; - } - } - } } self.rules.push(site); } @@ -24709,10 +24668,50 @@ ImgOps | https://imgops.com/#b#`; } return ""; }, + getXhrLink: function(a, p) { + var newSrc, rule; + this.xhr = null; + this.xhrLink = false; + for (var i = 0; i < this.rules.length; i++) { + rule = this.rules[i]; + if (rule.xhr) { + if (rule.xhr.url) { + if (rule.xhr.url.test) { + if (a && rule.xhr.url.test(a.href)) { + newSrc = a.href; + } + } else if (typeof rule.xhr.url === 'string') { + try { + if (a && a.matches(rule.xhr.url)) { + newSrc = a.href; + } + } catch(e) { + debug(e); + } + } else { + newSrc = rule.xhr.url.call(a, a, p, rule.xhr); + } + if (newSrc) { + this.xhrLink = true; + this.xhr = rule.xhr; + return newSrc; + } + } else if (a) { + newSrc = a.href; + if (newSrc) { + this.xhrLink = true; + this.xhr = rule.xhr; + return newSrc; + } + } + } + } + }, getImage: function(img, a, p, target) { var newSrc, rule; var base64Img = /^data:/i.test(img.src); this.all = null; + this.xhr = null; for (var i = 0; i < this.rules.length; i++) { rule = this.rules[i]; if (rule.src && !toRE(rule.src).test(img.src)) continue; @@ -25124,10 +25123,24 @@ ImgOps | https://imgops.com/#b#`; } return targetBg; }; - if (target.nodeName.toUpperCase() != 'IMG' && matchedRule.getExtSrc) { - let nsrc; + if (target.nodeName.toUpperCase() != 'IMG') { + let nsrc, imgPN, imgPA, imgPE = []; try { - nsrc = matchedRule.getExtSrc.call(target); + if (matchedRule.getExtSrc) { + nsrc = matchedRule.getExtSrc(target); + } + if (!nsrc && target.href) { + imgPN = target; + let i = 0; + while (imgPN = imgPN.parentElement) { + if (i++ > 5 || imgPN.nodeName.toUpperCase() == 'BODY') { + break; + } else { + imgPE.push(imgPN); + } + } + nsrc = matchedRule.getXhrLink(target, imgPE); + } } catch(ex) { throwErrorInfo(ex); } @@ -25143,8 +25156,8 @@ ImgOps | https://imgops.com/#b#`; src = nsrc[1]; } if (!matchedRule.xhrLink) { - let imgPN = target; - let imgPA, imgPE = []; + imgPN = target; + imgPE = []; do { if (imgPN.nodeName.toUpperCase() == 'A') { imgPA = imgPN; From ab058ef57724e8b146c00478bc76a706ee2c91f9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 27 Jul 2025 16:20:40 +0900 Subject: [PATCH 0746/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 14b532a4d58..bf939e77e10 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -24674,6 +24674,7 @@ ImgOps | https://imgops.com/#b#`; this.xhrLink = false; for (var i = 0; i < this.rules.length; i++) { rule = this.rules[i]; + if (rule.src) continue; if (rule.xhr) { if (rule.xhr.url) { if (rule.xhr.url.test) { @@ -25127,7 +25128,7 @@ ImgOps | https://imgops.com/#b#`; let nsrc, imgPN, imgPA, imgPE = []; try { if (matchedRule.getExtSrc) { - nsrc = matchedRule.getExtSrc(target); + nsrc = matchedRule.getExtSrc.call(target); } if (!nsrc && target.href) { imgPN = target; From e95a6aca0846d38ba69f0fb8257e29a0f4d91b2d Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 27 Jul 2025 18:28:13 +0900 Subject: [PATCH 0747/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index bf939e77e10..900ff060b93 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -21841,7 +21841,7 @@ ImgOps | https://imgops.com/#b#`; if (!imme && this.following) return; let wSize = getWindowSize(); - let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2), padding2 = 50, left, top;//内外侧间距 + let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2, (this.img.naturalWidth || 500)>>1, (this.img.naturalHeight || 500)>>1), padding2 = 50, left, top;//内外侧间距 imgWindow.style.position = "fixed"; let scrolled = {x: 0, y: 0}; From 57c28f0c58987276758337ed4fcc1ad1273bb977 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 27 Jul 2025 19:18:06 +0900 Subject: [PATCH 0748/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index a96ee806851..84248c1428e 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -18,7 +18,7 @@ or } Other parameter items can be added as needed. Note that css/ext/xhr/lazyAttr (lazy loaded original image URL attribute name)/description (description when collecting images, support selector or xpath)/clickToOpen should only be used after specifying the url. -xhr is used to obtain the attributes of the pictures on the inner pages. +xhr is used to obtain the attributes of the pictures on the inner pages. 1. First, use xhr.url() to filter and return the url of the parent a tag, and then the script will automatically grab the webpage pointed to by the url. 2. And get pictures through xhr. 2.1 xhr.query is the picture (you can For multiple, multiple will be added to the gallery) selector or function From be8fb375e7ee93850e79cc1df43d83fb883751f5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 28 Jul 2025 21:20:38 +0900 Subject: [PATCH 0749/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 84248c1428e..ffbe822e81e 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -277,16 +277,20 @@ var siteInfo = [ name:"deviantart", url:/^https?:\/\/[^.]*\.deviantart\.com/i, getImage: function(a, p) { - if (!a) return; - let media =Object.keys(a).filter(prop => prop.indexOf("__reactProps") === 0); - if (!media || !a[media] || !a[media].children || !a[media].children.props || !a[media].children.props.deviation) return; - media = a[media].children.props.deviation.media; - let fullview = media.types.filter(d => d.t === "fullview"); - let ext = media.baseUri.match(/\.\w+$/); - if (!fullview || !ext) return; - fullview = fullview[0]; - ext = ext[0]; - return media.baseUri + `/v1/fill/w_${fullview.w},h_${fullview.h}/${media.prettyName}-fullview${ext}?token=` + media.token[0]; + if (a) { + let media =Object.keys(a).filter(prop => prop.indexOf("__reactProps") === 0); + if (media && a[media] && a[media].children && a[media].children.props && a[media].children.props.deviation) { + media = a[media].children.props.deviation.media; + let fullview = media.types.filter(d => d.t === "fullview"); + let ext = media.baseUri.match(/\.\w+$/); + if (fullview && ext) { + fullview = fullview[0]; + ext = ext[0]; + return media.baseUri + `/v1/fill/w_${fullview.w},h_${fullview.h}/${media.prettyName}-fullview${ext}?token=` + media.token[0]; + } + } + } + return this.src && this.src.replace(/,q_\d+,/, ",q_100,").replace(/\/v1\/fill\/[^?]+\-pre\.\w+\?/, "?"); } }, { @@ -891,6 +895,7 @@ var siteInfo = [ name: "imgurLink", xhr: { url: function(a, p) { + if (!a) return; const imgurReg = /^https?:\/\/(?:(?:[im].)?(?:imgur.(?:com|io)|filmot.(?:com|org))\/+(?:(?:(a|gallery(?!\/random|\/custom)|t(?:opic)?\/[^/]+)|r\/[^/]+)\/(?:[^-/]+-)*([^W_]{5}(?:[^_W]{2})?)|(?:[^W_]{5}(?:[^W_]{2})?[,&])+[^_W]{5}(?:[^W_]{2})?)).*/; if (a.href.match && imgurReg.test(a.href)) { const m = a.href.match(imgurReg); From b71c44f95d394c5b72c8b6e2d2d0d4f01149a0ba Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 28 Jul 2025 21:21:13 +0900 Subject: [PATCH 0750/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 900ff060b93..c23226d32c9 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1630838/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1631523/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From ae602660a4f9644f3483a644e39fd618ef07753b Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 29 Jul 2025 10:03:13 +0900 Subject: [PATCH 0751/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 42 ++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index c23226d32c9..fb28e146335 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.7.27.1 +// @version 2025.7.29.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -14722,7 +14722,7 @@ ImgOps | https://imgops.com/#b#`; media = document.createElement('audio'); src = "audio:" + src; } else if (file.type.indexOf("video") === 0) { - media = document.createElement('video'); + media = createVideo(); src = "video:" + src; } else continue; media.title = file.name; @@ -15630,7 +15630,7 @@ ImgOps | https://imgops.com/#b#`; media = document.createElement('audio'); src = "audio:" + src; } else if (file.type.indexOf("video") === 0) { - media = document.createElement('video'); + media = createVideo(); src = "video:" + src; } else continue; media.src = src; @@ -16217,7 +16217,7 @@ ImgOps | https://imgops.com/#b#`; } switch (mode) { case "video": - media = document.createElement('video'); + media = createVideo(); media.style.width = 0; media.style.height = 0; media.controls = true; @@ -16620,7 +16620,7 @@ ImgOps | https://imgops.com/#b#`; media.removeEventListener('loadeddata', loaded); } if (isVideoLink(src)) { - media = document.createElement('video'); + media = createVideo(); media.style.width = 0; media.style.height = 0; media.controls = true; @@ -23324,7 +23324,7 @@ ImgOps | https://imgops.com/#b#`; } else { switch (mode) { case "video": - media = document.createElement('video'); + media = createVideo(); media.style.width = 0; media.style.height = 0; media.controls = true; @@ -25661,7 +25661,7 @@ ImgOps | https://imgops.com/#b#`; return; } if (curLoadingMedia && curLoadingMedia.src == e.blockedURI) { - GM_xmlhttpRequest({ + _GM_xmlhttpRequest({ method: 'GET', url: curLoadingMedia.src, responseType: 'blob', @@ -25670,15 +25670,39 @@ ImgOps | https://imgops.com/#b#`; curLoadingMedia.src = blobUrl; curLoadingMedia.load(); - videoElement.play().catch(err => console.warn('[CSP Fixer] Autoplay after fix was blocked.', err)); + curLoadingMedia.play().catch(err => console.warn('[CSP Fixer] Autoplay after fix was blocked.', err)); const releaseBlob = () => URL.revokeObjectURL(blobUrl); - videoElement.addEventListener('ended', releaseBlob); + curLoadingMedia.addEventListener('ended', releaseBlob); window.addEventListener('beforeunload', releaseBlob); } }); } }); + function createVideo() { + let media = document.createElement('video'); + media.addEventListener('error', e => { + if (/^blob:/.test(media.src)) return; + _GM_xmlhttpRequest({ + method: 'GET', + url: media.src, + responseType: 'blob', + onload: function(response) { + const blobUrl = URL.createObjectURL(response.response); + + media.src = blobUrl; + media.load(); + media.play().catch(err => console.warn('[CSP Fixer] Autoplay after fix was blocked.', err)); + + const releaseBlob = () => URL.revokeObjectURL(blobUrl); + media.addEventListener('ended', releaseBlob); + window.addEventListener('beforeunload', releaseBlob); + curLoadingMedia = null; + } + }); + }); + return media; + } async function input(sel, v) { await new Promise((resolve) => { From ff412abcb4f9b761d0534375124f03efe8494801 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 29 Jul 2025 18:43:47 +0900 Subject: [PATCH 0752/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 129 +++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 14 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index fb28e146335..2954bd39992 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -16198,10 +16198,33 @@ ImgOps | https://imgops.com/#b#`; e.preventDefault(); self.selectViewmore(imgSpan, curNode.dataset.src); let loadError = e => { - let i = document.createElement("img"); - i.src = curNode.dataset.thumbSrc; - curNode.dataset.src = curNode.dataset.thumbSrc; - popupImgWin(i); + if (/^blob:/.test(media.src)) { + let i = document.createElement("img"); + i.src = curNode.dataset.thumbSrc; + curNode.dataset.src = curNode.dataset.thumbSrc; + popupImgWin(i); + } else { + _GM_xmlhttpRequest({ + method: 'GET', + url: dataset(node, 'src'), + responseType: 'blob', + onload: function(response) { + const blobUrl = URL.createObjectURL(response.response); + let i = document.createElement("img"); + i.src = blobUrl; + curNode.dataset.src = curNode.dataset.thumbSrc; + popupImgWin(i); + const releaseBlob = () => URL.revokeObjectURL(blobUrl); + window.addEventListener('beforeunload', releaseBlob); + }, + onerror: function() { + let i = document.createElement("img"); + i.src = curNode.dataset.thumbSrc; + curNode.dataset.src = curNode.dataset.thumbSrc; + popupImgWin(i); + } + }); + } }; let loadImg = async() => { self.showTips("Loading image..."); @@ -16259,8 +16282,31 @@ ImgOps | https://imgops.com/#b#`; popupImgWin(this); }, error:function(e){ - self.showTips(""); - loadError(); + if (/^blob:/.test(imgSrc)) { + self.showTips(""); + loadError(); + } else if (mode == "image" || mode == "") { + _GM_xmlhttpRequest({ + method: 'GET', + url: imgSrc, + responseType: 'blob', + onload: function(response) { + const blobUrl = URL.createObjectURL(response.response); + self.showTips(""); + let img = document.createElement("img"); + popupImgWin(img); + const releaseBlob = () => URL.revokeObjectURL(blobUrl); + window.addEventListener('beforeunload', releaseBlob); + }, + onerror: function() { + self.showTips(""); + loadError(); + } + }); + } else { + self.showTips(""); + loadError(); + } } }); } @@ -16692,9 +16738,36 @@ ImgOps | https://imgops.com/#b#`; if(e.type=='error'){ if (loadingIndicator && loadingIndicator.style) loadingIndicator.style.display=''; - self.errorSpan=ele; - if(preImgR)preImgR.abort(); - self.loadImg(this, ele,true); + if (/^blob:/.test(src)) { + self.errorSpan=ele; + if(preImgR)preImgR.abort(); + self.loadImg(this, ele,true); + } else { + _GM_xmlhttpRequest({ + method: 'GET', + url: src, + responseType: 'blob', + onload: function(response) { + const blobUrl = URL.createObjectURL(response.response); + self.slideShow.run('loadEnd'); + let img = document.createElement("img"); + img.src = blobUrl; + imgReady(blobUrl, { + ready:function(){ + self.loadImg(img, ele, false); + self.slideShow.run('loadEnd'); + } + }); + const releaseBlob = () => URL.revokeObjectURL(blobUrl); + window.addEventListener('beforeunload', releaseBlob); + }, + onerror: function() { + self.errorSpan=ele; + if(preImgR)preImgR.abort(); + self.loadImg(this, ele, true); + } + }); + } }; self.slideShow.run('loadEnd'); @@ -23360,12 +23433,40 @@ ImgOps | https://imgops.com/#b#`; var opts = { error: function(e) { - if (Array.isArray(imgSrcs)) { - var src = imgSrcs.shift(); - if (src) { - self.loadImg(src, imgSrcs, nextFun); - return; + if (/^blob:/.test(imgSrc)) { + if (Array.isArray(imgSrcs)) { + var src = imgSrcs.shift(); + if (src) { + self.loadImg(src, imgSrcs, nextFun); + return; + } } + } else if (mode == "image" || mode == "") { + _GM_xmlhttpRequest({ + method: 'GET', + url: media.src, + responseType: 'blob', + onload: function(response) { + const blobUrl = URL.createObjectURL(response.response); + self.loadImg(blobUrl, imgSrcs, nextFun); + const releaseBlob = () => URL.revokeObjectURL(blobUrl); + window.addEventListener('beforeunload', releaseBlob); + }, + onerror: function() { + if (Array.isArray(imgSrcs)) { + var src = imgSrcs.shift(); + if (src) { + self.loadImg(src, imgSrcs, nextFun); + return; + } + } else { + self.error('', this, e); + } + } + }); + return; + } else { + self.error('', this, e); } if(nextFun) nextFun(); From 1b2ed9d263a344c7c6a7343fc78114c3335f0249 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 29 Jul 2025 19:52:01 +0900 Subject: [PATCH 0753/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index ffbe822e81e..df9d1f743b7 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1558,10 +1558,32 @@ var siteInfo = [ { name: "Sankaku Complex", url:/sankakucomplex\.com/, - src:/\/data\/preview\//, xhr:{ - url: "a", - query: "img#image" + url: function(a, p) { + const re = /^https?:\/\/(?:www\.)?((?:idol|chan)\.)?(sankaku)complex(\.com\/)(?:\w{2}\/)?(post)s?\/(?:show\/)?([a-zA-Z0-9]+).*/; + const $ = a && a.href.match(re); + if ($) { + return !$[1] ? `https://${$[2]}api${$[3]+$[4]}s/${$[5]}/fu` : $[0]; + } + }, + query: function(html, doc, url) { + const re = /^https?:\/\/((?:idol|chan|www)\.)?(sankaku)complex(\.com\/)(?:\w{2}\/)?(post)s?\/(?:show\/)?([a-zA-Z0-9]+).*/; + const $ = url.match(re); + if(html[0]!=='{') return; + let meta = document.querySelector('head > meta[name="referrer"]'); + if (!meta) { + meta = document.createElement('meta'); + meta.name = 'referrer'; + meta.content = 'same-origin'; + document.getElementsByTagName('head')[0].appendChild(meta); + } else if (meta.attributes.content.value !== 'same-origin') { + meta.attributes.content.value = 'same-origin'; + } + let lowres_url, highres_url; + lowres_url = html.match(/(?:(?:Resized: ]+?) href=|sample_url": ?)"([^"]+)/)?.[1]; + highres_url = html.match(/(?:(?:Original: ]+?) href="|file_url":"?)([^(,")]+)/)?.[1]; + return highres_url; + } } }, { From 2a00606873f5de383a6d58a0a2f846328079baa8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 29 Jul 2025 19:52:37 +0900 Subject: [PATCH 0754/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 2954bd39992..3dd31f726f5 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1631523/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1632035/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From 7221088d98a11a9250b59266a86fc4387c8d6662 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 29 Jul 2025 21:17:39 +0900 Subject: [PATCH 0755/1065] Update README.md --- Picviewer CE+/README.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 30cb4699344..2f9c19aa670 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -21,11 +21,23 @@ Hover your mouse over any image and click the icons on the float bar. Press `CTRL + G` to quickly enter the gallery. Hold `CTRL` to view a larger picture when hovering over images or links. -> There are additional settings available in the "Picviewer CE+ config" for further customization. Currently, reviewing these settings is the best way to learn about the script's capabilities. Try exploring more functions on your own! -> -> If you are glad to assist with the translation, please [🌐edit this file](https://github.com/hoothin/UserScripts/edit/master/Picviewer%20CE%2B/pvcep_lang.js#L1). It will be beneficial for individuals who speak the same language as you do. Thank you for your help. -> -> Need more rules for peculiar sites? feel free to pull requests or open issues. +English by [RX-3200](https://greasyfork.org/users/43-rx-3200). + +Português by [AstroCoelestis](https://greasyfork.org/users/881248). + +Русский by RX-3200 & vanja-san. + +Turkish by [PUFF1N](https://github.com/PUFF1N-000). + +Ukrainian by [MaSHiNiK](https://github.com/MaSHiNiK). + +Arabic by [Prankster 199](https://github.com/vfggf95565). + +There are additional settings available in the "Picviewer CE+ config" for further customization. Currently, reviewing these settings is the best way to learn about the script's capabilities. Try exploring more functions on your own! + +If you are glad to assist with the translation, please [🌐edit this file](https://github.com/hoothin/UserScripts/edit/master/Picviewer%20CE%2B/pvcep_lang.js#L1). It will be beneficial for individuals who speak the same language as you do. Thank you for your help. + +*Need more rules for peculiar sites? feel free to pull requests or open issues.* ## PDF Addon [Picviewer CE+ PDF Addon](https://greasyfork.org/scripts/498445-picviewer-ce-pdf-addon) After installing this addon, when the `Compress to ZIP` feature is enabled, a PDF file will be generated instead of a ZIP file during the packaging process. From cb5af827d2bd1efb4bac79b4e40d6abcc08dbd3f Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 29 Jul 2025 21:19:48 +0900 Subject: [PATCH 0756/1065] Update README.md --- Picviewer CE+/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 2f9c19aa670..0e989306c4e 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -21,19 +21,19 @@ Hover your mouse over any image and click the icons on the float bar. Press `CTRL + G` to quickly enter the gallery. Hold `CTRL` to view a larger picture when hovering over images or links. -English by [RX-3200](https://greasyfork.org/users/43-rx-3200). +There are additional settings available in the "Picviewer CE+ config" for further customization. Currently, reviewing these settings is the best way to learn about the script's capabilities. Try exploring more functions on your own! -Português by [AstroCoelestis](https://greasyfork.org/users/881248). ++ English by [RX-3200](https://greasyfork.org/users/43-rx-3200). -Русский by RX-3200 & vanja-san. ++ Português by [AstroCoelestis](https://greasyfork.org/users/881248). -Turkish by [PUFF1N](https://github.com/PUFF1N-000). ++ Русский by RX-3200 & vanja-san. -Ukrainian by [MaSHiNiK](https://github.com/MaSHiNiK). ++ Turkish by [PUFF1N](https://github.com/PUFF1N-000). -Arabic by [Prankster 199](https://github.com/vfggf95565). ++ Ukrainian by [MaSHiNiK](https://github.com/MaSHiNiK). -There are additional settings available in the "Picviewer CE+ config" for further customization. Currently, reviewing these settings is the best way to learn about the script's capabilities. Try exploring more functions on your own! ++ Arabic by [Prankster 199](https://github.com/vfggf95565). If you are glad to assist with the translation, please [🌐edit this file](https://github.com/hoothin/UserScripts/edit/master/Picviewer%20CE%2B/pvcep_lang.js#L1). It will be beneficial for individuals who speak the same language as you do. Thank you for your help. From 58ac68c41b1dee1a57bdebab21660c22f5cecd16 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 30 Jul 2025 12:38:01 +0900 Subject: [PATCH 0757/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index df9d1f743b7..05aaf4a29e1 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1004,7 +1004,7 @@ var siteInfo = [ if (!img) return; newsrc = img.src; } - return newsrc.replace(/\?.*$/i,""); + return newsrc.replace(/\?.*$/i,"").replace(/\/an_webp\/([^\/]+)\/mqdefault_6s\.webp/, "/vi/$1/hqdefault.jpg"); }, getImage: function(a, p) { var newsrc=this.src; @@ -1012,7 +1012,7 @@ var siteInfo = [ newsrc = p[2].querySelector("img").src; } if(!newsrc || newsrc.indexOf("i.ytimg.com") == -1) return; - return newsrc.replace(/\?.*$/i,""); + return newsrc.replace(/\?.*$/i,"").replace(/\/an_webp\/([^\/]+)\/mqdefault_6s\.webp/, "/vi/$1/hqdefault.jpg"); } }, { @@ -1559,13 +1559,7 @@ var siteInfo = [ name: "Sankaku Complex", url:/sankakucomplex\.com/, xhr:{ - url: function(a, p) { - const re = /^https?:\/\/(?:www\.)?((?:idol|chan)\.)?(sankaku)complex(\.com\/)(?:\w{2}\/)?(post)s?\/(?:show\/)?([a-zA-Z0-9]+).*/; - const $ = a && a.href.match(re); - if ($) { - return !$[1] ? `https://${$[2]}api${$[3]+$[4]}s/${$[5]}/fu` : $[0]; - } - }, + url: ["^https?://(?:www\\.)?(sankaku)complex(\\.com/)(?:\\w{2}/)?(post)s?/(?:show/)?([a-zA-Z0-9]+).*", "https://$1api$2$3s/$4/fu"], query: function(html, doc, url) { const re = /^https?:\/\/((?:idol|chan|www)\.)?(sankaku)complex(\.com\/)(?:\w{2}\/)?(post)s?\/(?:show\/)?([a-zA-Z0-9]+).*/; const $ = url.match(re); From f0f36bdd2ac91bd4e650ff0e71ca76390ed5034e Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 30 Jul 2025 12:39:39 +0900 Subject: [PATCH 0758/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 3dd31f726f5..aede2a65066 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.7.29.1 +// @version 2025.7.30.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1632035/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1632464/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -24624,6 +24624,15 @@ ImgOps | https://imgops.com/#b#`; let reMatch = typeof site.xhr.url === "string" && site.xhr.url.match(/^\/(.*)\/(\w*)$/); if (reMatch) { site.xhr.url = toRE(reMatch[1], reMatch[2]); + } else if (Array.isArray(site.xhr.url)) { + let urlRe = toRE(site.xhr.url[0], "i"); + let urlParam = site.xhr.url[1]; + site.xhr.url = (a, p) => { + if (!a || !a.href) return; + if (urlRe.test(a.href)) { + return a.href.replace(urlRe, urlParam);; + } + }; } } if (site.url && !urlChecked) { From 7650ed8636299d398c4be1d51b4069508d5b2e7d Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 31 Jul 2025 13:23:15 +0900 Subject: [PATCH 0759/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 05aaf4a29e1..96bcc248f08 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -625,8 +625,8 @@ var siteInfo = [ { name: "discordapp", url: /(discordapp\.|discord\.)(com|net)/, - r: [/\?width=\d+&height=\d+$/i, /.*\/external\/.*\/(https?)\/(.*)\?format.*/], - s: ["", "$1://$2"] + r: [/\?width=\d+&height=\d+$/i, /.*\/external\/.*\/(https?)\/(.*)\?format.*/, /media\.discordapp\.net/], + s: ["", "$1://$2", "cdn.discordapp.com"] }, { name: "推特", From 3d617033245a37d7b76958581e14a57c7fe0ee8d Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 31 Jul 2025 14:49:31 +0900 Subject: [PATCH 0760/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index aede2a65066..06baa669530 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.7.30.1 +// @version 2025.7.31.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1632464/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1633033/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -18301,7 +18301,7 @@ ImgOps | https://imgops.com/#b#`; if (this.isScrollToEndAndReloading) return; this.isScrollToEndAndReloading = true; var scrollTarget; - if (document.documentElement.scrollTop) { + if (document.documentElement.scrollTop || document.documentElement.scrollHeight - document.documentElement.clientHeight > 100) { scrollTarget = document.documentElement; } else if (getBody(document).scrollTop) { scrollTarget = getBody(document); @@ -18314,7 +18314,7 @@ ImgOps | https://imgops.com/#b#`; } } if (tempEle) { - while (tempEle && (tempEle.scrollHeight === tempEle.clientHeight || unsafeWindow.getComputedStyle(tempEle).overflowY === "hidden")) { + while (tempEle && (tempEle.scrollHeight - tempEle.clientHeight < 10 || unsafeWindow.getComputedStyle(tempEle).overflowY === "hidden")) { tempEle = tempEle.parentNode; } } @@ -18341,6 +18341,8 @@ ImgOps | https://imgops.com/#b#`; self.reloadNew(); self.loadThumb(); }, 1000); + } else { + self.reloadNew(); } }, 1); }, 300); From 703039fc0f2563a3a5a1783726a6fb5c5a42d094 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 31 Jul 2025 15:02:11 +0900 Subject: [PATCH 0761/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 06baa669530..fa6aeb105f8 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -16808,8 +16808,8 @@ ImgOps | https://imgops.com/#b#`; }; } else if (/^audio$/i.test(img.nodeName)) { imgNaturalSize = { - h:80, - w:300, + h:50, + w:350, }; } else { imgNaturalSize={ @@ -20670,8 +20670,13 @@ ImgOps | https://imgops.com/#b#`; setSearchState(`${img.naturalWidth} x ${img.naturalHeight}`, self.imgState); } if (!this.isImg) { - img.naturalHeight = img.videoHeight || 1080; - img.naturalWidth = img.videoWidth || 1920; + if (/^video$/i.test(img.nodeName)) { + img.naturalHeight = img.videoHeight || 1080; + img.naturalWidth = img.videoWidth || 1920; + } else if (/^audio$/i.test(img.nodeName)) { + img.naturalHeight = 50; + img.naturalWidth = 350; + } setTimeout(() => { img.onload(); }, 0); From 1e33194ac2968120e810c88ed82e33caf90d50d7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 31 Jul 2025 19:18:54 +0900 Subject: [PATCH 0762/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 96bcc248f08..1ac1ee71289 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1812,6 +1812,28 @@ var siteInfo = [ query: "#main-image" } }, + { + name: "postimg Link", + xhr: { + url: "a[href^='https://postimg.cc/']", + query: function(html, doc, url) { + if (url.indexOf("gallery") != -1) { + let urls = []; + [].forEach.call(doc.querySelectorAll("#thumb-list>.thumb-container"), ele => { + let hotlink = ele.dataset.hotlink; + let name = ele.dataset.name; + let ext = ele.dataset.ext; + if (hotlink && name && ext) { + urls.push(`https://i.postimg.cc/${hotlink}/${name}.${ext}`); + } + }); + if (urls.length) return urls; + } + let img = doc.querySelector("#main-image"); + return img && img.src; + } + } + }, { name: "postimg", url: /^https:\/\/postimg\.cc/, From 7eb9f5222a7a13b39e94f0875399e2ba5d4618cf Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 31 Jul 2025 19:19:40 +0900 Subject: [PATCH 0763/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index fa6aeb105f8..00ebf513013 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.7.31.1 +// @version 2025.7.31.2 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1633033/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1633157/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From a9492e8d08e6c077159650fbae0258c8629a91b0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 31 Jul 2025 19:30:03 +0900 Subject: [PATCH 0764/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 1ac1ee71289..c0e66679993 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1829,7 +1829,10 @@ var siteInfo = [ }); if (urls.length) return urls; } - let img = doc.querySelector("#main-image"); + let img = doc.querySelector("#download"); + if (img) { + return img.href; + } else img = doc.querySelector("#main-image"); return img && img.src; } } From 9434e8a5ce4013367268edf9ee44ad896e570418 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 31 Jul 2025 19:30:37 +0900 Subject: [PATCH 0765/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 00ebf513013..df94d8dfef3 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1633157/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1633161/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From 7a090acb5eb56017a50264646e2feb3ab57ab95c Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 31 Jul 2025 20:18:04 +0900 Subject: [PATCH 0766/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index df94d8dfef3..8e901066ad2 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -24188,7 +24188,7 @@ ImgOps | https://imgops.com/#b#`; var iurl, iurls = [], cap, caps, doc = createDoc(html); if(typeof q == 'function') { - iurl = await q(html, doc, url + (post ? `#p{${post}}` : ""), xhr); + iurl = await q(html, doc, url + (post ? `#p{${post}}` : ""), xhr, GM_fetch); if (iurl) { if(iurl.url) { cap = iurl.cap; From a995541827bb1b3fdea9bb1c584fc8f3ebff91d8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 1 Aug 2025 10:16:06 +0900 Subject: [PATCH 0767/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index c0e66679993..fd98dedb7e6 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1857,6 +1857,14 @@ var siteInfo = [ query: ".main-image" } }, + { + name: "Yupoo main", + url: /\byupoo\.com\//, + xhr: { + url: "a[href^='/albums/']", + query: "[data-type=photo]>img[data-src]", + } + }, { name: "MAL Anime/Manga", src: /^https:\/\/cdn\.myanimelist\.net/, From 73d5bf70c6f27a87da8de7a1f14f6c2c00f62888 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 1 Aug 2025 10:17:46 +0900 Subject: [PATCH 0768/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 8e901066ad2..db282841c45 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.7.31.2 +// @version 2025.8.1.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -12613,7 +12613,7 @@ ImgOps | https://imgops.com/#b#`; var matchedRule, _URL=location.href.slice(0, 500); - const lazyImgAttr = ["data-lazy-src", "org_src", "data-lazy", "data-url", "data-orig-file", "zoomfile", "file", "original", "load-src", "imgsrc", "real_src", "src2", "origin-src", "data-lazyload", "data-lazyload-src", "data-lazy-load-src", "data-ks-lazyload", "data-ks-lazyload-custom", "data-src", "data-defer-src", "data-actualsrc", "data-cover", "data-original", "data-thumb", "data-imageurl", "data-placeholder", "lazysrc", "data-preview", "data-page-image-url"]; + const lazyImgAttr = ["data-lazy-src", "org_src", "data-lazy", "data-url", "data-orig-file", "zoomfile", "file", "original", "load-src", "imgsrc", "real_src", "src2", "origin-src", "data-lazyload", "data-lazyload-src", "data-lazy-load-src", "data-ks-lazyload", "data-ks-lazyload-custom", "data-defer-src", "data-actualsrc", "data-original", "data-origin-src", "data-imageurl", "lazysrc", "data-src", "data-preview", "data-cover", "data-page-image-url", "data-thumb", "data-placeholder"]; var tprules = [ function(a) { if (this.currentSrc && !this.src) this.src = this.currentSrc; @@ -18047,7 +18047,7 @@ ImgOps | https://imgops.com/#b#`; var container = document.querySelector('.pv-gallery-container'), preloadContainer = document.querySelector('.pv-gallery-preloaded-img-container'); - var bgReg = /.*?url\(\s*["']?(.+?)["']?\s*\)([^'"]|$)/i; + var bgReg = /.*?url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; var body = getBody(document); var linkMedias = []; function anylizeEle(total, node) { @@ -23960,11 +23960,7 @@ ImgOps | https://imgops.com/#b#`; let offsetParent, bodyPosi; if (bodyStyle.position === "static") { - if (document.documentElement.scrollLeft || document.documentElement.scrollTop) { - offsetParent = document.documentElement; - } else { - offsetParent = body; - } + offsetParent = document.documentElement; bodyPosi = { top: 0, bottom: windowSize.h, @@ -25206,8 +25202,8 @@ ImgOps | https://imgops.com/#b#`; if (!target) return; } } - let bgReg = /.*url\(\s*["']?([^ad\s'"].+?)["']?\s*\)([^'"]|$)/i; - let bgRegLong = /^\s*url\(\s*["']?([^ad\s'"].+?)["']?\s*\)([^'"]|$)/i; + let bgReg = /.*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; + let bgRegLong = /^\s*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; let result, targetBg, hasBg = node => { if(node.nodeName.toUpperCase() == "HTML" || node.nodeName == "#document"){ return false; From b0dce13c6655e7cfc5faf1c0d41d4be3dda4a823 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 1 Aug 2025 10:18:13 +0900 Subject: [PATCH 0769/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index db282841c45..812d9416b5a 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1633161/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1633507/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From 601a60c1ddb9d24cce6598f090a4c014c2c6dc09 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 1 Aug 2025 18:04:16 +0900 Subject: [PATCH 0770/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 62 ++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index fd98dedb7e6..f7c2b359edf 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -660,7 +660,7 @@ var siteInfo = [ }, { name: "Fandom", - url: /fandom\.com/, + url: /\bfandom\.com/, r: [/scale\-to\-width\-down\/\d+/i, /smart\/width\/\d+\/height\/\d+/i], s: ["",""] @@ -706,7 +706,7 @@ var siteInfo = [ }, { name: "E621", - url: /e621\.net/, + url: /\be621\.net/, getImage: function(a, p) { if(p[2] && p[2].dataset.fileUrl){ return p[2].dataset.fileUrl; @@ -716,7 +716,7 @@ var siteInfo = [ }, { name: "Pinterest", - url: /pinterest\.com/, + url: /\bpinterest\.com/, getImage: function(a, p) { if(this.srcset){ var srcs=this.srcset.split(","),minSize=0,newSrc; @@ -734,13 +734,13 @@ var siteInfo = [ }, { name: "Zhisheji", - url: /zhisheji\.com/, + url: /\bzhisheji\.com/, r: /thumbnail\/.*/i, s: "" }, { name: "imgbox", - src: /imgbox\.com/, + src: /\bimgbox\.com/, r: /thumbs(\d\.imgbox.*)_t\./i, s: "images$1_o." }, @@ -798,7 +798,7 @@ var siteInfo = [ }, { name: "Reddit", - url: /reddit\.com|redd\.it/, + url: /\breddit\.com|redd\.it/, getImage: function() { if (this.srcset) { var srcs = this.srcset.split(/[xw],/i); @@ -956,26 +956,26 @@ var siteInfo = [ }, { name: "Rule34hentai", - url: /rule34hentai\.net/, + url: /\brule34hentai\.net/, r: "/_thumbs/", s: "/_images/" }, { name: "Rule34", - url: /rule34\.xxx/, + url: /\brule34\.xxx/, src: /\/(thumbnails|samples)\/(.*)\/(thumbnail|sample)_/i, r: /\/(thumbnails|samples)\/(.*)\/(thumbnail|sample)_(.*)\..*/i, s: ["/images/$2/$4.jpeg","/images/$2/$4.png","/images/$2/$4.jpg"] }, { name: "Photosight", - url: /photosight\.ru/, + url: /\bphotosight\.ru/, r: /(cdny\.de.*\/)t\//i, s: "$1x/" }, { name: "Xiaohongshu", - url: /xiaohongshu\.com/, + url: /\bxiaohongshu\.com/, ext: function(target) { if (target.className == 'change-pic') { var imgs=target.previousElementSibling.querySelectorAll('li'),i=0; @@ -991,7 +991,7 @@ var siteInfo = [ }, { name: "Youtube", - url: /youtube\.com/, + url: /\byoutube\.com/, ext: function(target) { if (target.tagName == "ytd-thumbnail" || target.id == "thumbnail-container") { return target.querySelector("img"); @@ -1183,13 +1183,13 @@ var siteInfo = [ }, { name: "gravatar", - src: /gravatar\.com\/avatar\/|\/gravatar\//i, + src: /\bgravatar\.com\/avatar\/|\/gravatar\//i, r: /(avatar\/.*[\?&]s=).*/, s: '$11920' }, { name: "ucServerAvatar", - src: /uc_server\/avatar\.php/i, + src: /\buc_server\/avatar\.php/i, r: /(uc_server\/avatar\.php\?uid=\d+&size=).*/, s: '$1big' }, @@ -1271,7 +1271,7 @@ var siteInfo = [ }, { name: "douban", - url: /douban\.com/i, + url: /\bdouban\.com/i, getImage:function(){ var $ = /(img\d+\.douban\.com\/)(?:(view\/)(?:photo|movie_poster_cover)\/(?!large)[^\/]+|(icon\/u(?=\d))|[sm](?=pic\/))(.*)/i.exec(this.src); var newsrc= $ ? ('http://' + $[1] + ($[2] ? $[2] + 'photo/photo' : (($[3]||'') + 'l')) + $[4]) : ''; @@ -1290,7 +1290,7 @@ var siteInfo = [ }, { name: "taobao", - url: /item\.taobao\.com/i, + url: /\bitem\.taobao\.com/i, r: [/.*((?:img\d\d\.taobaocdn|img(?:[^.]*\.?){1,2}?\.alicdn)\.com\/)(?:img\/|tps\/http:\/\/img\d\d+\.taobaocdn\.com\/)?((?:imgextra|bao\/uploaded)\/.+\.(?:jpe?g|png|gif|bmp))_.+\.jpg$/i, /(.*\.alicdn\.com\/.*?)((.jpg|.png)(\.|_)\d+x\d+.*)\.jpg(_\.webp)?$/i, /(.*\.alicdn\.com\/.*?)((\.|_)\d+x\d+.*|\.search|\.summ)\.jpg(_\.webp)?$/i], @@ -1305,14 +1305,14 @@ var siteInfo = [ }, { name: "yihaodianimg", - url: /yhd\.com/i, + url: /\byhd\.com/i, src: /yihaodianimg\.com/i, r: /(.*\.yihaodianimg\.com\/.*)_\d+x\d+\.jpg$/i, s: "$1.jpg" }, { name: "jd", - url: /jd\.com/i, + url: /\bjd\.com/i, src: /360buyimg\.com/i, r: [/(.*360buyimg\.com\/)n\d\/.+?\_(.*)/i, /(.*360buyimg\.com\/)n\d\/(.*)/i, @@ -1321,20 +1321,20 @@ var siteInfo = [ }, { name: "dangdang", - url: /dangdang\.com/i, - src: /ddimg\.cn/i, + url: /\bdangdang\.com/i, + src: /\bddimg\.cn/i, r: /(.*ddimg.cn\/.*?)_[bw]_(\d+\.jpg$)/i, s: "$1_e_$2" }, { name: "duokan", - url: /duokan\.com/i, + url: /\bduokan\.com/i, r: /(cover.read.duokan.com.*?\.jpg)!\w+$/i, s: "$1" }, { name: "yyets", - url: /yyets\.com/i, + url: /\byyets\.com/i, r: /^(res\.yyets\.com.*?\/ftp\/(?:attachment\/)?\d+\/\d+)\/[ms]_(.*)/i, s: "http://$1/$2" }, @@ -1387,35 +1387,35 @@ var siteInfo = [ }, { name: "nhentai", - url: /nhentai\./i, + url: /\bnhentai\./i, r: [/(cdn\..*\d+)t(\.[a-z]+)$/, /\/\/\w+(\..*\/)(\d+)t(\.[a-z]+)$/i], s: ["$1$2","//i$1$2$3"], example: "http://nhentai.net/g/113475/" }, { name: "GithubAvatars", - url: /github\.com/i, + url: /\bgithub\.com/i, r: /(avatars\d*\.githubusercontent\.com.*)\?.*$/i, s: "$1", example: "https://avatars2.githubusercontent.com/u/3233275/" }, { name: "ggpht", - src: /ggpht\.com/i, + src: /\bggpht\.com/i, r: /=s\d+.*/i, s: "=s9999" }, { name: "kodansha", - url: /kodansha\.co\.jp/i, - src: /kodansha\.co\.jp/i, + url: /\bkodansha\.co\.jp/i, + src: /\bkodansha\.co\.jp/i, r: 't_og_image_center', s: 'c_limit' }, { name: "fanseven", - url: /fanseven\.com/i, - src: /fanseven\.com/i, + url: /\bfanseven\.com/i, + src: /\bfanseven\.com/i, r: /w=\d+&h=\d+/i, s: 'w=9999&h=9999' }, @@ -1865,6 +1865,12 @@ var siteInfo = [ query: "[data-type=photo]>img[data-src]", } }, + { + name: "Google review", + url: /\bgoogle\.com\//, + r: /=w\d+\-h\d+\-\w/, + s: "=s3072-v1" + }, { name: "MAL Anime/Manga", src: /^https:\/\/cdn\.myanimelist\.net/, From cb36c5a3b59be079b1ba2da51fcfbffe22d3a706 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 1 Aug 2025 18:05:01 +0900 Subject: [PATCH 0771/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 812d9416b5a..f1502861f2e 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1633507/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1633680/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -13074,10 +13074,10 @@ ImgOps | https://imgops.com/#b#`; var rect=target.getBoundingClientRect(); var compStyle=unsafeWindow.getComputedStyle(target); var pFloat=parseFloat; - var top=rect.top + pFloat(compStyle.paddingTop) + pFloat(compStyle.borderTopWidth); - var right=rect.right - pFloat(compStyle.paddingRight) - pFloat(compStyle.borderRightWidth); - var bottom=rect.bottom - pFloat(compStyle.paddingBottom) - pFloat(compStyle.borderBottomWidth); - var left=rect.left + pFloat(compStyle.paddingLeft) + pFloat(compStyle.borderLeftWidth); + var top=rect.top + pFloat(compStyle.borderTopWidth); + var right=rect.right - pFloat(compStyle.borderRightWidth); + var bottom=rect.bottom - pFloat(compStyle.borderBottomWidth); + var left=rect.left + pFloat(compStyle.borderLeftWidth); return { top:top, right:right, From c6f2beaff2a4850a2285c6ce556605cc48bab66b Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 1 Aug 2025 18:49:57 +0900 Subject: [PATCH 0772/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index f7c2b359edf..0a341e091c6 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -829,7 +829,7 @@ var siteInfo = [ }); } return apiUrl + "/gifs/" + aHref.replace(/.*redgifs.com\/(..\/)?(\w+\/)?(\w+)(?:\.\w+)?/, '$3');; - } else if (p[1] && p[1].classList.contains("search-result")) { + } else if (p[1] && p[1].classList && p[1].classList.contains("search-result")) { let link = p[1].querySelector("a.search-link"); if (link && link.href) { if (/\/\/v.redd\.it\/\w+\/?$/.test(link.href)) { @@ -838,6 +838,8 @@ var siteInfo = [ return link.href; } } + } else if (a && this.src && p[2] && p[2].nodeName == "FACEPLATE-IMG") { + return a.href; } }, headers: (url, self) => { @@ -872,6 +874,17 @@ var siteInfo = [ (!i ? '[' + new Date(data.created_utc*1e3).toLocaleString() + ' | ' + data.title + '] ' : '') + (c.caption || '') ] }) + } else if (/\/r\//.test(url)) { + let img = doc.querySelector("img[src^='https://preview.redd.it/']"); + if (img) return img.src; + img = doc.querySelector("[packaged-media-json]"); + if (img) { + let mediaJson = img.getAttribute("packaged-media-json"); + if (mediaJson) { + return JSON.parse(mediaJson).playbackMp4s.permutations.pop().source.url; + } + } + return; } var xmlDoc = (new DOMParser()).parseFromString(html, 'application/xml'); var highestRes = [].slice.call(xmlDoc.querySelectorAll('Representation[frameRate]')) From 42c364e5b4f056351bfb51a4589f88efe3747a81 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 1 Aug 2025 18:51:24 +0900 Subject: [PATCH 0773/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index f1502861f2e..284bb1f78c6 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.8.1.1 +// @version 2025.8.1.2 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1633680/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1633712/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -24351,14 +24351,14 @@ ImgOps | https://imgops.com/#b#`; function findPic(img){ var imgPN=img; var imgPA,imgPE=[]; - while(imgPN=imgPN.parentElement){ + while(imgPN=imgPN.parentNode || imgPN.host){ if(imgPN.nodeName.toUpperCase()=='A'){ imgPA=imgPN; break; } } imgPN=img; - while(imgPN=imgPN.parentElement){ + while(imgPN=imgPN.parentNode || imgPN.host){ if(imgPN.nodeName.toUpperCase()=='BODY'){ break; }else{ @@ -25246,7 +25246,7 @@ ImgOps | https://imgops.com/#b#`; if (!nsrc && target.href) { imgPN = target; let i = 0; - while (imgPN = imgPN.parentElement) { + while (imgPN = imgPN.parentNode || imgPN.host) { if (i++ > 5 || imgPN.nodeName.toUpperCase() == 'BODY') { break; } else { @@ -25277,9 +25277,9 @@ ImgOps | https://imgops.com/#b#`; imgPA = imgPN; break; } - } while (imgPN = imgPN.parentElement); + } while (imgPN = imgPN.parentNode || imgPN.host); imgPN = target; - while (imgPN = imgPN.parentElement) { + while (imgPN = imgPN.parentNode || imgPN.host) { if (imgPN.nodeName.toUpperCase() == 'BODY') { break; } else { @@ -25488,14 +25488,14 @@ ImgOps | https://imgops.com/#b#`; try { let imgPN=target; let imgPA,imgPE=[]; - while(imgPN=imgPN.parentElement){ + while(imgPN=imgPN.parentNode || imgPN.host){ if(imgPN.nodeName.toUpperCase()=='A'){ imgPA=imgPN; break; } } imgPN=target; - while(imgPN=imgPN.parentElement){ + while(imgPN=imgPN.parentNode || imgPN.host){ if(imgPN.nodeName.toUpperCase()=='BODY'){ break; }else{ From b6bd65f3a275e5424b3b647a560350e3ea365c9e Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 10:06:16 +0900 Subject: [PATCH 0774/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 37 ++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 0a341e091c6..1b115386b11 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -801,11 +801,19 @@ var siteInfo = [ url: /\breddit\.com|redd\.it/, getImage: function() { if (this.srcset) { - var srcs = this.srcset.split(/[xw],/i); - for (let i = 0; i < srcs.length; i++) { - let srcInfo = srcs[i].trim().split(" ")[0]; - if (srcInfo.indexOf("?width") == -1) return srcInfo; - } + let srcs = this.srcset.split(/[xw],\s*/i); + let maxSize = 0; + let result = ""; + srcs.forEach(srcset => { + let srcArr = srcset.split(" "); + let curSize = parseInt(srcArr[1]); + if (srcArr[0].indexOf("?width") == -1) return srcArr[0]; + if (curSize > maxSize) { + maxSize = curSize; + result = srcArr[0]; + } + }); + if (this.src.indexOf("?width") !== -1) return result; } else if (/^https?:\/\/preview\./.test(this.src)){ return this.src.replace("preview", "i").replace(/\?.*/, ""); } @@ -876,7 +884,24 @@ var siteInfo = [ }) } else if (/\/r\//.test(url)) { let img = doc.querySelector("img[src^='https://preview.redd.it/']"); - if (img) return img.src; + if (img) { + if (img.srcset) { + let srcs = img.srcset.split(/[xw],\s*/i); + let maxSize = 0; + let result = ""; + srcs.forEach(srcset => { + let srcArr = srcset.split(" "); + let curSize = parseInt(srcArr[1]); + if (srcArr[0].indexOf("?width") == -1) return srcArr[0]; + if (curSize > maxSize) { + maxSize = curSize; + result = srcArr[0]; + } + }); + if (img.src.indexOf("?width") !== -1) return result; + } + return img.src; + } img = doc.querySelector("[packaged-media-json]"); if (img) { let mediaJson = img.getAttribute("packaged-media-json"); From 27b3ee1719fc2be8912967fd695a0de310905dd2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 10:10:43 +0900 Subject: [PATCH 0775/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 284bb1f78c6..15768511a87 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1633712/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1634053/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -12640,7 +12640,7 @@ ImgOps | https://imgops.com/#b#`; } if (newsrc) { } else if (this.srcset) { - var srcs = this.srcset.split(/[xw],/i), largeSize = -1; + var srcs = this.srcset.split(/[xw],\s*/i), largeSize = -1; srcs.forEach(srci => { let srcInfo = srci.trim().split(/\s+/), curSize = parseInt(srcInfo[1] || 0); if ((srcInfo[1] || !oldsrc) && curSize > largeSize) { @@ -24331,7 +24331,7 @@ ImgOps | https://imgops.com/#b#`; function pretreatment(img, fetchImg) { if (img.removeAttribute) img.removeAttribute("loading"); - if (img.nodeName.toUpperCase() != "IMG" || (!fetchImg && img.src && !/^data/.test(img.src))) return; + if (img.nodeName.toUpperCase() != "IMG" || (!fetchImg && img.src && !img.srcset && !/^data/.test(img.src))) return; let src; tprules.find(function(rule, index, array) { try { From dfa40a66d9d1221cf0742b2a71e9d4b3551e3d5c Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 13:45:08 +0900 Subject: [PATCH 0776/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 15768511a87..f1368cfd8b1 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -21362,7 +21362,7 @@ ImgOps | https://imgops.com/#b#`; margin: 0 -5px 0 15px!important;\ padding: 3px!important;\ color: black;\ - text-shadow: 0 0 0px black;\ + text-shadow: 0 0 1px #00000099;\ }\ .pv-pic-window-description::before {\ display: inline-block;\ @@ -21458,10 +21458,11 @@ ImgOps | https://imgops.com/#b#`; -webkit-box-sizing: content-box;\ box-sizing: content-box;\ border-radius: 1px;\ - background: rgb(0 0 0 / 80%);\ + background: rgb(0 0 0 / 75%);\ + box-shadow: rgb(221, 221, 221) 0px 0px 1px inset;\ max-width: 100%;\ overflow: hidden;\ - font: 13px / 1.4em "Trebuchet MS", sans-serif;\ + font: 13px / 1.4em Roboto,arial,sans-serif,微软雅黑,"Noto Sans SC";\ pointer-events: none;\ }\ .pv-pic-search-state>span {\ @@ -21478,7 +21479,7 @@ ImgOps | https://imgops.com/#b#`; }\ .pv-pic-search-state>span>strong {\ background: inherit;\ - color: inherit;\ + color: #ffffff;\ }\ span.pv-pic-search-state>.pv-icon {\ width: 20px;\ From 8daec662d4cf6cf16b0fa772c059fb369f0314fc Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 14:39:05 +0900 Subject: [PATCH 0777/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 1b115386b11..c3a7680000f 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -819,6 +819,14 @@ var siteInfo = [ } return this.src; }, + getExtSrc: function() { + if (this.getAttribute("reason") == "nsfw") { + if (!this.firstElementChild) return; + let img = this.firstElementChild.querySelector("img"); + if (!img) return; + return img.src.replace(/^https:\/\/preview\.redd\.it\/(.*)\?.*/, "https://i.redd.it/$1"); + } + }, xhr: { url: function(a, p, self) { let aHref = a && a.href; From eff623120c0dd679711c13fa39b26163ac935b31 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 14:39:33 +0900 Subject: [PATCH 0778/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index f1368cfd8b1..4ed54e1c80b 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1634053/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1634114/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From fecdf851ccf0441949d5bf532193ffd3541c62d7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 14:49:06 +0900 Subject: [PATCH 0779/1065] Update README.md --- Picviewer CE+/README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 0e989306c4e..1e7552d8244 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -1,6 +1,6 @@ -# 🏞️ Picviewer CE+ ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) 🌐[Reddit](https://www.reddit.com/r/PicviewerCE) 🗨️[Discord](https://discord.com/invite/keqypXC6wD) 🕊️[Twitter](https://twitter.com/intent/follow?screen_name=HoothinDev) [⏬](https://hoothin.github.io/UserScripts/Picviewer%20CE+/Picviewer%20CE+.user.js) +# 🏞️ Picviewer CE+ ⭐[Star](https://github.com/hoothin/UserScripts#StarMe) 🌐[Reddit](https://www.reddit.com/r/PicviewerCE) 🗨️[Discord](https://discord.com/invite/keqypXC6wD) 🕊️[Twitter](https://twitter.com/intent/follow?screen_name=HoothinDev) -> Zoom images across all your favorite websites. Pop up, scale, edit, rotate, batch save images, or automatically load pictures from subsequent pages. Simply hover your mouse over any image and click the icons on the float bar. +### Zoom images across all your favorite websites. Pop up, scale, edit, rotate, batch save images, or automatically load pictures from subsequent pages. Simply hover your mouse over any image and click the icons on the float bar. + **Adjust:** Scale/rotate/batch save every picture @@ -15,7 +15,9 @@ + View long image by scroll -## Usage +## 🚀 Quick Start + +Install from [Github](https://hoothin.github.io/UserScripts/Picviewer%20CE+/Picviewer%20CE+.user.js) or [Greasefork](https://greasyfork.org/scripts/24204-picviewer-ce). Hover your mouse over any image and click the icons on the float bar. @@ -23,6 +25,10 @@ Press `CTRL + G` to quickly enter the gallery. Hold `CTRL` to view a larger pict There are additional settings available in the "Picviewer CE+ config" for further customization. Currently, reviewing these settings is the best way to learn about the script's capabilities. Try exploring more functions on your own! +## 🤝 Contribution & Support + +If you are glad to assist with the translation, please [🌐edit this file](https://github.com/hoothin/UserScripts/edit/master/Picviewer%20CE%2B/pvcep_lang.js#L1). It will be beneficial for individuals who speak the same language as you do. Thank you for your help. + + English by [RX-3200](https://greasyfork.org/users/43-rx-3200). + Português by [AstroCoelestis](https://greasyfork.org/users/881248). @@ -35,11 +41,9 @@ There are additional settings available in the "Picviewer CE+ config" for furthe + Arabic by [Prankster 199](https://github.com/vfggf95565). -If you are glad to assist with the translation, please [🌐edit this file](https://github.com/hoothin/UserScripts/edit/master/Picviewer%20CE%2B/pvcep_lang.js#L1). It will be beneficial for individuals who speak the same language as you do. Thank you for your help. - *Need more rules for peculiar sites? feel free to pull requests or open issues.* -## PDF Addon +## ✨ PDF Addon [Picviewer CE+ PDF Addon](https://greasyfork.org/scripts/498445-picviewer-ce-pdf-addon) After installing this addon, when the `Compress to ZIP` feature is enabled, a PDF file will be generated instead of a ZIP file during the packaging process.
    Make a PDF e-book with this addon From e20c2668908b98460b03cc1c7779a5ddb9066cbb Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 16:56:02 +0900 Subject: [PATCH 0780/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index b8b41e113f3..4aea75096cf 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -6191,6 +6191,11 @@ "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/", From 689b37d137b52e441e46025b12d775fefab79a35 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 17:39:33 +0900 Subject: [PATCH 0781/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index c3a7680000f..41832c8bdae 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -799,8 +799,10 @@ var siteInfo = [ { name: "Reddit", url: /\breddit\.com|redd\.it/, - getImage: function() { - if (this.srcset) { + getImage: function(a, p) { + if (a && /review\.redd\.it/.test(a.href)) { + return a.href; + } else if (this.srcset) { let srcs = this.srcset.split(/[xw],\s*/i); let maxSize = 0; let result = ""; From 3d4de9f3c1f3c247134c4e054dea4fd727754b66 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 2 Aug 2025 08:40:04 +0000 Subject: [PATCH 0782/1065] Update version of Pagetual rules to 97 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index f906e1845dc..c17e934b51c 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -96 +97 From 2464cab4b8535b060876e48d7aea70841a6e60f0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 17:48:34 +0900 Subject: [PATCH 0783/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index a4dccfc95a6..7f1bdd100e3 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -4711,6 +4711,7 @@ } #pagetual-sideController #pagetual-sideController-move > svg { transition: transform .3s ease; + border-radius: 15px !important; } #pagetual-sideController #pagetual-sideController-move > svg:hover { transform: scale(1.2); @@ -8136,6 +8137,7 @@ const initStyle = `text-indent: initial;display: contents;right: unset;left: unset;top: unset;bottom: unset;inset: unset;clear: both;cy: initial;d: initial;dominant-baseline: initial;empty-cells: initial;fill: initial;fill-opacity: initial;fill-rule: initial;filter: initial;flex: initial;flex-flow: initial;float: initial;flood-color: initial;flood-opacity: initial;grid: initial;grid-area: initial;height: initial;hyphens: initial;image-orientation: initial;image-rendering: initial;inline-size: initial;inset-block: initial;inset-inline: initial;isolation: initial;letter-spacing: initial;lighting-color: initial;line-break: initial;list-style: initial;margin-block: initial;margin: 0px 5px;margin-inline: initial;marker: initial;mask: initial;mask-type: initial;max-block-size: initial;max-height: initial;max-inline-size: initial;max-width: initial;min-block-size: initial;min-height: initial;min-inline-size: initial;min-width: initial;mix-blend-mode: initial;object-fit: initial;object-position: initial;offset: initial;opacity: initial;order: initial;orphans: initial;outline: initial;outline-offset: initial;overflow-anchor: initial;overflow-clip-margin: initial;overflow-wrap: initial;overflow: initial;overscroll-behavior-block: initial;overscroll-behavior-inline: initial;overscroll-behavior: initial;padding-block: initial;padding: initial;padding-inline: initial;page: initial;page-orientation: initial;paint-order: initial;perspective: initial;perspective-origin: initial;pointer-events: initial;position: relative;quotes: initial;r: initial;resize: initial;ruby-position: initial;rx: initial;ry: initial;scroll-behavior: initial;scroll-margin-block: initial;scroll-margin: initial;scroll-margin-inline: initial;scroll-padding-block: initial;scroll-padding: initial;scroll-padding-inline: initial;scroll-snap-align: initial;scroll-snap-stop: initial;scroll-snap-type: initial;scrollbar-gutter: initial;shape-image-threshold: initial;shape-margin: initial;shape-outside: initial;shape-rendering: initial;size: initial;speak: initial;stop-color: initial;stop-opacity: initial;stroke: initial;stroke-dasharray: initial;stroke-dashoffset: initial;stroke-linecap: initial;stroke-linejoin: initial;stroke-miterlimit: initial;stroke-opacity: initial;stroke-width: initial;tab-size: initial;table-layout: initial;text-align: initial;text-align-last: initial;text-anchor: initial;text-combine-upright: initial;text-decoration: initial;text-decoration-skip-ink: initial;text-indent: initial;text-overflow: initial;text-shadow: initial;text-size-adjust: initial;text-transform: initial;text-underline-offset: initial;text-underline-position: initial;touch-action: initial;transform: initial;transform-box: initial;transform-origin: initial;transform-style: initial;transition: initial;user-select: initial;vector-effect: initial;vertical-align: initial;visibility: initial;border-spacing: initial;-webkit-border-image: initial;-webkit-box-align: initial;-webkit-box-decoration-break: initial;-webkit-box-direction: initial;-webkit-box-flex: initial;-webkit-box-ordinal-group: initial;-webkit-box-orient: initial;-webkit-box-pack: initial;-webkit-box-reflect: initial;-webkit-highlight: initial;-webkit-hyphenate-character: initial;-webkit-line-break: initial;-webkit-line-clamp: initial;-webkit-mask-box-image: initial;-webkit-mask: initial;-webkit-mask-composite: initial;-webkit-perspective-origin-x: initial;-webkit-perspective-origin-y: initial;-webkit-print-color-adjust: initial;-webkit-rtl-ordering: initial;-webkit-ruby-position: initial;-webkit-tap-highlight-color: initial;-webkit-text-combine: initial;-webkit-text-decorations-in-effect: initial;-webkit-text-emphasis: initial;-webkit-text-emphasis-position: initial;-webkit-text-fill-color: initial;-webkit-text-security: initial;-webkit-text-stroke: initial;-webkit-transform-origin-x: initial;-webkit-transform-origin-y: initial;-webkit-transform-origin-z: initial;-webkit-user-drag: initial;-webkit-user-modify: initial;white-space: initial;widows: initial;width: initial;will-change: initial;word-break: initial;word-spacing: initial;x: initial;y: initial;`; const pageTextStyle = `opacity: 1!important;text-indent: initial;padding: unset;border: none;background: unset!important;line-height: 30px;text-decoration: none;user-select: none;visibility: visible;position: initial;width: auto;max-width: 80%; white-space: nowrap; text-overflow: ellipsis;overflow: hidden;height: auto;float: none;clear: both;margin: 0px;text-align: center;display: inline-block;font-weight: bold;font-style: normal;font-size: 16px;letter-spacing: initial;vertical-align: top;color: rgb(85, 85, 95)!important;`; + const corsTips = "Blocked by CORS, try to install an extension like 'Ignore X-Frame headers'."; var sideControllerIcon = ''; var tipsWords = document.createElement("div"); @@ -9371,7 +9373,7 @@ } catch(e) { inCors = true; if (forceState === 3) { - debug("Stop as cors"); + debug(corsTips); isPause = true; } if (!ruleParser.curSiteRule.pageElement) { @@ -9483,7 +9485,7 @@ try { iframeDoc = emuIframe.contentDocument || emuIframe.contentWindow.document; } catch(e) { - returnFalse("Stop as cors"); + returnFalse(corsTips); return; } getBody(iframeDoc).scrollTop = 9999999; @@ -9703,7 +9705,7 @@ ruleParser.findNoNext(); } } else { - returnFalse("Stop as cors"); + returnFalse(corsTips); } return; } @@ -9981,7 +9983,7 @@ try { iframeDoc = curIframe.contentDocument || curIframe.contentWindow.document; } catch(e) { - debug("Stop as cors"); + debug(corsTips); isPause = true; callback(false); return; From 5115ece3b346f8829a0bd327e60da814dce1861c Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 18:49:22 +0900 Subject: [PATCH 0784/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 41832c8bdae..6fbe2286047 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1247,6 +1247,12 @@ var siteInfo = [ r: /\.md(\.[^\.]+)$/i, s: '$1' }, + { + name: "thumbnail", + src: /\.thumbnail\./i, + r: /\.thumbnail(\.[^\.]+)$/i, + s: '$1' + }, { name: "ytimg", src: /i\.ytimg\.com/i, @@ -1942,5 +1948,25 @@ var siteInfo = [ url: "^https://nozomi\\.la", r: "///qtn(\\..*)\\.\\w+\\.webp/i", s: "//w$1.webp" + }, + { + name: "Wjcodes", + url: /^https:\/\/[^\.]+\.wjcodes\.com\//, + getImage: function(a, p) { + if (!p[0]) return; + let dtEle; + if (dtEle = p[0].querySelector("[d=t]")) { + let onclick = dtEle.getAttribute("onclick"); + if (onclick) return onclick.replace(/.*download_file\('([^']+).*/, "$1"); + } + } + }, + { + name: "anime-pictures", + url: /^https:\/\/anime\-pictures\.net\//, + xhr: { + url: "a[href^='/posts/']", + query: "a.icon-download" + } } ]; From 3109124ecd079903aa29b52962c77a0d2125209a Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 18:50:38 +0900 Subject: [PATCH 0785/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 4ed54e1c80b..d59a0485d72 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1634114/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1634207/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -24871,10 +24871,10 @@ ImgOps | https://imgops.com/#b#`; } } else newSrc = null; if (!base64Img && rule.r && img.src && !Array.isArray(newSrc)) { - if (!newSrc) newSrc = img.currentSrc || img.src; + if (!newSrc) newSrc = img.src || img.currentSrc; newSrc = this.replaceByRule(newSrc, rule); } - if (newSrc && newSrc.length > 0 && newSrc != (img.currentSrc || img.src)) { + if (newSrc && newSrc.length > 0 && newSrc != (img.src || img.currentSrc)) { debug(rule); break; } else newSrc = null; From ff5622771b515891ec578b82c4d2ebced0f15a38 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 20:37:05 +0900 Subject: [PATCH 0786/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 6fbe2286047..22b47e96f45 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -295,14 +295,12 @@ var siteInfo = [ }, { name: '花瓣网', - enabled: true, url: /^https?:\/\/huaban\.com\//i, ext: 'previous-2', - r: /(.*img.hb.aicdn.com\/.*)_fw(?:236|320)$/i, - s: '$1_fw658', + r: [/(.*img.hb.aicdn.com\/.*)_fw(?:236|320)$/i, /_fw\d+\w+/i], + s: ['$1_fw658', ''], description: './../following-sibling::p[@class="description"]', - // css: '.pin a.img .cover { display: none; }', - exclude: /weixin_code\.png$/i, + exclude: /weixin_code\.png$/i }, { name: "wikipedia", From 09a9431948a820327336d9ffb4cfd2bd95c0bf06 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 20:38:22 +0900 Subject: [PATCH 0787/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index d59a0485d72..524520c9e52 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.8.1.2 +// @version 2025.8.1.3 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1634207/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1634247/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -12540,7 +12540,7 @@ ImgOps | https://imgops.com/#b#`; sidebarToggle: true, // 是否显示隐藏按钮 transition:true,//大图片区的动画。 preload:true,//对附近的图片进行预读。 - max:5,//最多预读多少张(前后各多少张) + max:3,//最多预读多少张(前后各多少张) zoomresized: 25, // 图片尺寸最少相差比例,单位:% scaleSmallSize: 250, // 图库的新类别,缩放的图片,尺寸的高或宽都小于该值 @@ -17005,12 +17005,28 @@ ImgOps | https://imgops.com/#b#`; if(imgNaturalSize.h/imgNaturalSize.w >= containerSize.h/containerSize.w){ let height=contentSSize.h-10; height=height<0?contentSSize.h:height; - imgSty.height=height + 'px'; + if (rotate90) { + imgSty.width=height + 'px'; + imgSty.setProperty('width', height+'px', 'important'); + } else { + imgSty.height=height + 'px'; + imgSty.setProperty('height', height+'px', 'important'); + } + imgPaSty.height=height + 'px'; + imgPaSty.setProperty('height', height+'px', 'important'); scaled=height/imgNaturalSize.h; }else{ let width=contentSSize.w-10; width=width<0?contentSSize.w:width; + if (rotate90) { + imgSty.height=width + 'px'; + imgSty.setProperty('height', width+'px', 'important'); + } else { + imgSty.width=width + 'px'; + imgSty.setProperty('width', width+'px', 'important'); + } imgSty.width=width + 'px'; + imgSty.setProperty('width', width+'px', 'important'); scaled=width/imgNaturalSize.w; }; scaled=(scaled*100).toFixed(2) + '%'; From 5b2c9eadb3a19ba39e511ca8889f1ed8b6700cae Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 20:39:36 +0900 Subject: [PATCH 0788/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 524520c9e52..0c996fc52e6 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -16996,8 +16996,8 @@ ImgOps | https://imgops.com/#b#`; imgSty.width=width + 'px'; imgSty.setProperty('width', width+'px', 'important'); } - imgSty.width=width + 'px'; - imgSty.setProperty('width', width+'px', 'important'); + imgPaSty.width=width + 'px'; + imgPaSty.setProperty('width', width+'px', 'important'); scaled=width/imgNaturalSize.w; }; scaled=(scaled*100).toFixed(2) + '%'; @@ -17025,8 +17025,8 @@ ImgOps | https://imgops.com/#b#`; imgSty.width=width + 'px'; imgSty.setProperty('width', width+'px', 'important'); } - imgSty.width=width + 'px'; - imgSty.setProperty('width', width+'px', 'important'); + imgPaSty.width=width + 'px'; + imgPaSty.setProperty('width', width+'px', 'important'); scaled=width/imgNaturalSize.w; }; scaled=(scaled*100).toFixed(2) + '%'; From 4b63289850fee42af53e1af3219cbb45d24dc6c0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 21:16:14 +0900 Subject: [PATCH 0789/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 22b47e96f45..8002943d107 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -856,6 +856,9 @@ var siteInfo = [ } } else if (a && this.src && p[2] && p[2].nodeName == "FACEPLATE-IMG") { return a.href; + } else if (p[3]) { + let a = p[3].querySelector("a.group"); + if (a) return a.href; } }, headers: (url, self) => { @@ -891,8 +894,15 @@ var siteInfo = [ ] }) } else if (/\/r\//.test(url)) { - let img = doc.querySelector("img[src^='https://preview.redd.it/']"); - if (img) { + let imgs = doc.querySelectorAll("img[src^='https://preview.redd.it/'],img[data-lazy-src^='https://preview.redd.it/']"); + let urls = []; + [].forEach.call(imgs, img => { + if (!img.src && img.getAttribute("data-lazy-src")) { + img.src = img.getAttribute("data-lazy-src"); + } + if (!img.srcset && img.getAttribute("data-lazy-srcset")) { + img.srcset = img.getAttribute("data-lazy-srcset"); + } if (img.srcset) { let srcs = img.srcset.split(/[xw],\s*/i); let maxSize = 0; @@ -900,19 +910,20 @@ var siteInfo = [ srcs.forEach(srcset => { let srcArr = srcset.split(" "); let curSize = parseInt(srcArr[1]); - if (srcArr[0].indexOf("?width") == -1) return srcArr[0]; + if (srcArr[0].indexOf("?width") == -1) return urls.push(srcArr[0]); if (curSize > maxSize) { maxSize = curSize; result = srcArr[0]; } }); - if (img.src.indexOf("?width") !== -1) return result; + if (img.src.indexOf("?width") !== -1) return urls.push(result); } - return img.src; - } - img = doc.querySelector("[packaged-media-json]"); - if (img) { - let mediaJson = img.getAttribute("packaged-media-json"); + urls.push(img.src); + }); + if (urls.length) return urls; + let json = doc.querySelector("[packaged-media-json]"); + if (json) { + let mediaJson = json.getAttribute("packaged-media-json"); if (mediaJson) { return JSON.parse(mediaJson).playbackMp4s.permutations.pop().source.url; } From 84f0f263fd2395e8fe3389773307ae1b0a5b6419 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 21:16:46 +0900 Subject: [PATCH 0790/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 0c996fc52e6..182fbe0a302 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1634247/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1634289/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From 813238ec0ba0f3519c555e4a156d8c979fb1a69e Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 21:52:45 +0900 Subject: [PATCH 0791/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 8002943d107..fc5275c1fd9 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -794,6 +794,14 @@ var siteInfo = [ } } }, + { + name: "streamain", + url: /^https:\/\/(streamain\.com\/|www\.reddit\.com\/)/, + xhr: { + url: "a[href^='https://streamain.com/'][href$='/watch']", + query: '#playbob-video' + } + }, { name: "Reddit", url: /\breddit\.com|redd\.it/, From cbf73ee3f85f1840136f853b8d6349d1121148e3 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 21:53:16 +0900 Subject: [PATCH 0792/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 182fbe0a302..09e5a3e57a8 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1634289/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1634302/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From a97a0108fe452cbcb52928fd4c2d0005f1eda3d1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 22:00:55 +0900 Subject: [PATCH 0793/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index fc5275c1fd9..21f2b91cc85 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -798,7 +798,7 @@ var siteInfo = [ name: "streamain", url: /^https:\/\/(streamain\.com\/|www\.reddit\.com\/)/, xhr: { - url: "a[href^='https://streamain.com/'][href$='/watch']", + url: /^https:\/\/streamain\.com\/.*\/watch$/, query: '#playbob-video' } }, @@ -1865,7 +1865,7 @@ var siteInfo = [ name: "behance", url: /^https:\/\/www\.behance\.net/, xhr: { - url: "a[href^='/gallery/']", + url: /^\/gallery\//, query: "img[class^='ImageElement-image']" }, getExtSrc: function() { @@ -1879,14 +1879,14 @@ var siteInfo = [ name: "postimg host", src: /^https:\/\/i\.postimg\.cc/, xhr: { - url: "a[href^='https://postimg.cc/']", + url: /^https:\/\/postimg\.cc\//, query: "#main-image" } }, { name: "postimg Link", xhr: { - url: "a[href^='https://postimg.cc/']", + url: /^https:\/\/postimg\.cc\//, query: function(html, doc, url) { if (url.indexOf("gallery") != -1) { let urls = []; @@ -1932,7 +1932,7 @@ var siteInfo = [ name: "Yupoo main", url: /\byupoo\.com\//, xhr: { - url: "a[href^='/albums/']", + url: /^\/albums\//, query: "[data-type=photo]>img[data-src]", } }, @@ -1982,7 +1982,7 @@ var siteInfo = [ name: "anime-pictures", url: /^https:\/\/anime\-pictures\.net\//, xhr: { - url: "a[href^='/posts/']", + url: /^\/posts\//, query: "a.icon-download" } } From 1fcb979dba7e55889f8fda432d293556fb204246 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 22:01:26 +0900 Subject: [PATCH 0794/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 09e5a3e57a8..f584288ddda 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1634302/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1634312/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From ae5f1b27e29feaeb6da3ca7fd0ca1d78c83748f7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 22:10:35 +0900 Subject: [PATCH 0795/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 21f2b91cc85..f56c3ae5424 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -902,7 +902,7 @@ var siteInfo = [ ] }) } else if (/\/r\//.test(url)) { - let imgs = doc.querySelectorAll("img[src^='https://preview.redd.it/'],img[data-lazy-src^='https://preview.redd.it/']"); + let imgs = doc.querySelectorAll("img[src*='preview.redd.it/'],img[data-lazy-src^='https://preview.redd.it/']"); let urls = []; [].forEach.call(imgs, img => { if (!img.src && img.getAttribute("data-lazy-src")) { From b8674c499c033b6b29d3ffccba7a0c1f053823ac Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 22:11:04 +0900 Subject: [PATCH 0796/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index f584288ddda..50bf9fca026 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1634312/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1634319/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From f57a8aca50c3f52034de49cbee249e058aeabd44 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 2 Aug 2025 22:35:33 +0900 Subject: [PATCH 0797/1065] Update README.md --- Picviewer CE+/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 1e7552d8244..79f94364c77 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -102,6 +102,8 @@ This way, you'll get a beautifully created PDF e-book. ``` You have the option to use a standalone userscript, which allows you to manage all of your custom rules effectively. +Feel free to share your own custom rules on Greasy Fork! + ``` js // ==UserScript== // @name Picviewer CE+ custom rules From 3eb8f06153a5cde0ace7802df5bd07cd09231cec Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 3 Aug 2025 16:08:16 +0900 Subject: [PATCH 0798/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 50bf9fca026..8459e2da3c4 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.8.1.3 +// @version 2025.8.2.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -12124,22 +12124,22 @@ ImgOps | https://imgops.com/#b#`; } 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"); @@ -12612,7 +12612,7 @@ ImgOps | https://imgops.com/#b#`; }; var matchedRule, - _URL=location.href.slice(0, 500); + _URL=location.href.length > 510 ? location.href.slice(0, 500) + location.href.slice(-10) : location.href.slice(0, 500); const lazyImgAttr = ["data-lazy-src", "org_src", "data-lazy", "data-url", "data-orig-file", "zoomfile", "file", "original", "load-src", "imgsrc", "real_src", "src2", "origin-src", "data-lazyload", "data-lazyload-src", "data-lazy-load-src", "data-ks-lazyload", "data-ks-lazyload-custom", "data-defer-src", "data-actualsrc", "data-original", "data-origin-src", "data-imageurl", "lazysrc", "data-src", "data-preview", "data-cover", "data-page-image-url", "data-thumb", "data-placeholder"]; var tprules = [ function(a) { @@ -17208,7 +17208,7 @@ ImgOps | https://imgops.com/#b#`; //if(item.xhr)spanMark.dataset.xhr=encodeURIComponent(JSON.stringify(item.xhr)); spanMark.dataset.description=encodeURIComponent(item.description || (item.img ? (item.img.title || item.img.alt || "") : "")); spanMark.dataset.thumbSrc=(item.img && (item.img.currentSrc || item.img.src)) || item.imgSrc; - let title = item.img ? (item.img.title || item.img.alt || "").slice(-80) : ""; + let title = item.img ? (item.img.title || item.img.alt || "").slice(-200) : ""; if (title) { if (title.indexOf('http') === 0 || title.indexOf('data') === 0) title = ''; else title += '\n'; @@ -25428,6 +25428,10 @@ ImgOps | https://imgops.com/#b#`; target = checkEle; found = true; break; + } else if (checkEle.nodeName === "PICTURE") { + target = checkEle.querySelector("img"); + found = true; + break; } else if (prefs.floatBar.listenBg && hasBg(checkEle)) { let src = targetBg, nsrc = src, noActual = true, type = "scale"; result = { @@ -25572,7 +25576,10 @@ ImgOps | https://imgops.com/#b#`; if (canPreview) { if (result.type != "link" && result.type != "rule" && result.src == result.imgSrc) { if (result.imgAS.w < result.imgCS.w * 1.6 && result.imgAS.h < result.imgCS.h * 1.6) { - if (result.img && result.img.childElementCount) return false; + if (result.img && result.img.childElementCount) { + if (result.type == "force") return false; + if (prefs.floatBar.globalkeys.invertInitShow) return false; + } var wSize = getWindowSize(); if (prefs.floatBar.globalkeys.invertInitShow && result.imgAS.w <= wSize.w && result.imgAS.h <= wSize.h) return false; } From 2c342d340e66eedf4913e11723a6bf77290627dd Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 3 Aug 2025 16:26:07 +0900 Subject: [PATCH 0799/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 4aea75096cf..fec987433dc 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -3428,7 +3428,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" }, { From fd99635fc551247738cf81aadb3a5ebad618daed Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 3 Aug 2025 07:26:23 +0000 Subject: [PATCH 0800/1065] Update version of Pagetual rules to 98 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index c17e934b51c..6529ff889b0 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -97 +98 From 89ebe06dfd27879a6e596f86d3fd9fe464bd8480 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 3 Aug 2025 16:38:35 +0900 Subject: [PATCH 0801/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 7f1bdd100e3..3585298929c 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -8668,7 +8668,7 @@ } const loadmoreReg = /^\s*((点击?)?(这里)?((看|加载|展开)(更多|剩余)|继续加载)|(點擊?)?(這裡)?((看|加載|展開)(更多|剩餘)|繼續加載)|load\s*more|もっと読み込む)[\.…▼\s\d%]*$/i; - const defaultLoadmoreSel = ".loadMore,.LoadMore,[class^='load-more'],[class*=' load-more'],button.show_more,.button-show-more,button[data-testid='more-results-button'],#btn_preview_remain,.view-more-btn"; + const defaultLoadmoreSel = ".loadMore,.LoadMore,[class^='load-more'],[class*=' load-more'],[class^='show-more'],[class*=' show-more'],[class*='_show-more'],[class*='-show-more'],button.show_more,button[data-testid='more-results-button'],#btn_preview_remain,.view-more-btn"; function getLoadMore(doc, loadmoreBtn) { if (!loadmoreBtn || !getBody(doc).contains(loadmoreBtn) || /less/.test(loadmoreBtn.innerText)) loadmoreBtn = null; let loadMoreSel = ruleParser.curSiteRule.loadMore; From a20fa6a2708c64fd7ebbd1dbb0f68c7c2a239ef2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 3 Aug 2025 16:45:44 +0900 Subject: [PATCH 0802/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 3585298929c..7ad5890f421 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -3046,15 +3046,16 @@ ".pg_area>em+a", "a#linkNext", ".page>em+a", + "body [class*=page--current]+li>a", + "body [class*=Pages]>.curr+a", + "body [class*=page]>.cur+a", + "body [class*=paging]>em+a", + "body [class*=paginat] [class*=current]+li>a", "a.page_next", "body a[class*=page__next]", "body [class*=pager]>a.next", "body [class*=pagination-next]>a", "body [class*=pagination-next]>button", - "body [class*=page--current]+li>a", - "body [class*=Pages]>.curr+a", - "body [class*=page]>.cur+a", - "body [class*=paginat] [class*=current]+li>a", "body [class*=paginat] [class*=next-next]", "body [class*=paginat] [class*=next]", "body [class*=paginat] [class*=right]", From 9b95e05fa6073d65fcbebfb4c17c12cf6f000ba3 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 3 Aug 2025 17:13:14 +0900 Subject: [PATCH 0803/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 7ad5890f421..7feea3333a8 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -5742,6 +5742,12 @@ ruleParser.customRules.unshift(editTemp); ruleParser.curSiteRule = editTemp; } else { + if (ruleParser.hpRules) { + let href = location.href.slice(0, 500); + ruleParser.hpRules = ruleParser.hpRules.filter(item => { + return item && !(new RegExp(item.url, "i").test(href) && ruleParser.ruleMatch(item)); + }); + } ruleParser.curSiteRule = {}; isPause = true; } @@ -6804,7 +6810,7 @@ let sideControllerIconInput = document.createElement("input"); sideControllerIconInput.style.width = "100%"; sideControllerIconInput.style.position = "relative"; - sideControllerIconInput.placeholder = "📄"; + sideControllerIconInput.placeholder = "☯️"; sideControllerIconInput.value = rulesData.sideControllerIcon || ''; sideControllerIconInput.spellcheck = false; sideControllerIconDiv.appendChild(sideControllerIconInput); From 0353ef02c8b8c1dcf99214962af48992830fac26 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 3 Aug 2025 17:19:05 +0900 Subject: [PATCH 0804/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 7feea3333a8..d9373e8aec6 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -2209,6 +2209,11 @@ if (!this.hpRules) this.hpRules = []; let url = this.curSiteRule && this.curSiteRule.url, self = this; let href = location.href.slice(0, 500); + if (instead) { + this.hpRules = this.hpRules.filter(item => { + return item && !(new RegExp(item.url, "i").test(href) && self.ruleMatch(item)); + }); + } let matchedRules = this.hpRules.filter(rule => JSON.stringify(rule) != JSON.stringify(self.curSiteRule) && new RegExp(rule.url, "i").test(href) && self.ruleMatch(rule)); if (url) matchedRules.unshift(this.curSiteRule); matchedRules.sort((a, b) => { @@ -5742,12 +5747,6 @@ ruleParser.customRules.unshift(editTemp); ruleParser.curSiteRule = editTemp; } else { - if (ruleParser.hpRules) { - let href = location.href.slice(0, 500); - ruleParser.hpRules = ruleParser.hpRules.filter(item => { - return item && !(new RegExp(item.url, "i").test(href) && ruleParser.ruleMatch(item)); - }); - } ruleParser.curSiteRule = {}; isPause = true; } From 1ae5fff17efde59410b4f2f0737e1b3edbe95e20 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 3 Aug 2025 21:25:23 +0900 Subject: [PATCH 0805/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index f56c3ae5424..3e30b757c5d 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1985,5 +1985,15 @@ var siteInfo = [ url: /^\/posts\//, query: "a.icon-download" } + }, + { + name: "hentai-sharing", + url: /^https:\/\/hentai\-sharing\.net\//, + getImage: function(a, p) { + if (a && a.href.indexOf("https://hentai-sharing.net/nyaa/") == 0) { + let link = atob(a.href.replace("https://hentai-sharing.net/nyaa/", "")); + return /\.(?:jpe?|pn)g/.test(link) ? link : ''; + } + } } ]; From 888c9001b228aae78bf55fd4578d330e58065992 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 3 Aug 2025 21:25:57 +0900 Subject: [PATCH 0806/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 8459e2da3c4..666e1896332 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1634319/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1634900/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From 74b6147281b22db3357d64d058d64d0f58fd5eb0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 4 Aug 2025 13:50:52 +0900 Subject: [PATCH 0807/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 666e1896332..bb532a120fa 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -25340,8 +25340,10 @@ ImgOps | https://imgops.com/#b#`; if (target.nodeName.toUpperCase() != 'A' && target.parentNode && target.parentNode.style && !/flex|grid|table/.test(getComputedStyle(target.parentNode).display)) { broEle = target.previousElementSibling; while (broEle) { - if (broEle.nodeName == "IMG") broImg = broEle; - else if (broEle.nodeName == "PICTURE") broImg = broEle.querySelector("img"); + if (broEle.offsetWidth) { + if (broEle.nodeName == "IMG") broImg = broEle; + else if (broEle.nodeName == "PICTURE") broImg = broEle.querySelector("img"); + } if (getComputedStyle(broEle).position !== "absolute") break; broEle = broEle.previousElementSibling; } @@ -25349,8 +25351,10 @@ ImgOps | https://imgops.com/#b#`; else if (!broEle) { broEle = target.nextElementSibling; while (broEle) { - if (broEle.nodeName == "IMG") broImg = broEle; - else if (broEle.nodeName == "PICTURE") broImg = broEle.querySelector("img"); + if (broEle.offsetWidth) { + if (broEle.nodeName == "IMG") broImg = broEle; + else if (broEle.nodeName == "PICTURE") broImg = broEle.querySelector("img"); + } if (getComputedStyle(broEle).position == "absolute") break; broEle = broEle.nextElementSibling; } From 97125081ecdea7f90ec1c86c7f27238f20e0e712 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 6 Aug 2025 09:09:02 +0900 Subject: [PATCH 0808/1065] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 05ba8eee4e2..b4a12fb47c4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@

    ⚙️Greasemonkey scripts

    - twitter license Support Contact From 7387e9002b5161d2dbdd6e3c802914a6214a0acc Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 6 Aug 2025 09:31:46 +0900 Subject: [PATCH 0809/1065] Update README.md --- Picviewer CE+/README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 79f94364c77..93fbf3fb5d6 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -1,4 +1,6 @@ -# 🏞️ Picviewer CE+ ⭐[Star](https://github.com/hoothin/UserScripts#StarMe) 🌐[Reddit](https://www.reddit.com/r/PicviewerCE) 🗨️[Discord](https://discord.com/invite/keqypXC6wD) 🕊️[Twitter](https://twitter.com/intent/follow?screen_name=HoothinDev) +# 🏞️ Picviewer CE+ + +![twitter](https://img.shields.io/twitter/follow/HoothinDev) [![Discord](https://img.shields.io/badge/Discord-Join-blue.svg?logo=discord&style=social)](https://discord.com/invite/keqypXC6wD) ![reddit](https://img.shields.io/reddit/subreddit-subscribers/PicviewerCE) ![stars](https://img.shields.io/github/stars/Hoothin/UserScripts) ### Zoom images across all your favorite websites. Pop up, scale, edit, rotate, batch save images, or automatically load pictures from subsequent pages. Simply hover your mouse over any image and click the icons on the float bar. @@ -15,6 +17,8 @@ + View long image by scroll +Recommended similar plugins: [Imagus](https://chromewebstore.google.com/detail/imagus/immpkjjlgappgfkkfieppnmlhakdmaab) - [Hover-zoom+](https://chromewebstore.google.com/detail/hover-zoom+/pccckmaobkjjboncdfnnofkonhgpceea) - [Mouseover Popup Image Viewer](https://greasyfork.org/scripts/394820) + ## 🚀 Quick Start Install from [Github](https://hoothin.github.io/UserScripts/Picviewer%20CE+/Picviewer%20CE+.user.js) or [Greasefork](https://greasyfork.org/scripts/24204-picviewer-ce). @@ -27,7 +31,7 @@ There are additional settings available in the "Picviewer CE+ config" for furthe ## 🤝 Contribution & Support -If you are glad to assist with the translation, please [🌐edit this file](https://github.com/hoothin/UserScripts/edit/master/Picviewer%20CE%2B/pvcep_lang.js#L1). It will be beneficial for individuals who speak the same language as you do. Thank you for your help. +If you are glad to assist with the translation, please ✍️[edit this file](https://github.com/hoothin/UserScripts/edit/master/Picviewer%20CE%2B/pvcep_lang.js#L1). It will be beneficial for individuals who speak the same language as you do. Thank you for your help. + English by [RX-3200](https://greasyfork.org/users/43-rx-3200). @@ -44,7 +48,7 @@ If you are glad to assist with the translation, please [🌐edit this file](http *Need more rules for peculiar sites? feel free to pull requests or open issues.* ## ✨ PDF Addon -[Picviewer CE+ PDF Addon](https://greasyfork.org/scripts/498445-picviewer-ce-pdf-addon) After installing this addon, when the `Compress to ZIP` feature is enabled, a PDF file will be generated instead of a ZIP file during the packaging process. +Picviewer CE+ [PDF Addon](https://greasyfork.org/scripts/498445-picviewer-ce-pdf-addon). After installing this addon, when the `Compress to ZIP` feature is enabled, a PDF file will be generated instead of a ZIP file during the packaging process.

    Make a PDF e-book with this addon From f6cd1a13cdf0b2dc887c55dd0c0bef8d7df49bdf Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 6 Aug 2025 09:34:01 +0900 Subject: [PATCH 0810/1065] Update README.md --- Picviewer CE+/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 93fbf3fb5d6..89d22cddfd0 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -1,6 +1,6 @@ # 🏞️ Picviewer CE+ -![twitter](https://img.shields.io/twitter/follow/HoothinDev) [![Discord](https://img.shields.io/badge/Discord-Join-blue.svg?logo=discord&style=social)](https://discord.com/invite/keqypXC6wD) ![reddit](https://img.shields.io/reddit/subreddit-subscribers/PicviewerCE) ![stars](https://img.shields.io/github/stars/Hoothin/UserScripts) +[![twitter](https://img.shields.io/twitter/follow/HoothinDev)](https://twitter.com/intent/follow?screen_name=HoothinDev) [![Discord](https://img.shields.io/badge/Discord-Join-blue.svg?logo=discord&style=social)](https://discord.com/invite/keqypXC6wD) [![reddit](https://img.shields.io/reddit/subreddit-subscribers/PicviewerCE)](https://www.reddit.com/r/PicviewerCE) [![stars](https://img.shields.io/github/stars/Hoothin/UserScripts)](https://github.com/hoothin/UserScripts#StarMe) ### Zoom images across all your favorite websites. Pop up, scale, edit, rotate, batch save images, or automatically load pictures from subsequent pages. Simply hover your mouse over any image and click the icons on the float bar. From 339f53ebe0fa946d04e493cd9302713e77b1755e Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 6 Aug 2025 22:29:15 +0900 Subject: [PATCH 0811/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index d9373e8aec6..dbe73d0134b 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -8674,7 +8674,7 @@ } const loadmoreReg = /^\s*((点击?)?(这里)?((看|加载|展开)(更多|剩余)|继续加载)|(點擊?)?(這裡)?((看|加載|展開)(更多|剩餘)|繼續加載)|load\s*more|もっと読み込む)[\.…▼\s\d%]*$/i; - const defaultLoadmoreSel = ".loadMore,.LoadMore,[class^='load-more'],[class*=' load-more'],[class^='show-more'],[class*=' show-more'],[class*='_show-more'],[class*='-show-more'],button.show_more,button[data-testid='more-results-button'],#btn_preview_remain,.view-more-btn"; + const defaultLoadmoreSel = ".loadMore,.LoadMore,[class^='load-more'],[class*=' load-more'],.show-more,[class*='_show-more'],[class*='-show-more'],button.show_more,button[data-testid='more-results-button'],#btn_preview_remain,.view-more-btn"; function getLoadMore(doc, loadmoreBtn) { if (!loadmoreBtn || !getBody(doc).contains(loadmoreBtn) || /less/.test(loadmoreBtn.innerText)) loadmoreBtn = null; let loadMoreSel = ruleParser.curSiteRule.loadMore; From fc3e474de534f915c8b64493aa5dfcabe6ac3a66 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 7 Aug 2025 10:35:39 +0900 Subject: [PATCH 0812/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 3e30b757c5d..28a323f93ef 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1995,5 +1995,13 @@ var siteInfo = [ return /\.(?:jpe?|pn)g/.test(link) ? link : ''; } } + }, + { + name: "streamain", + url: "^https://(www\\.)?img(?:inn|sed)\\.com/", + xhr: { + url: "/^https://(www\\.)?img(?:inn|sed)\\.com/p/[\\w-]/", + query: '.swiper-slide,.downloads a' + } } ]; From 2d2bd535789140e4091750fb0432a7648de7b9dc Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 7 Aug 2025 10:39:29 +0900 Subject: [PATCH 0813/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 30 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index bb532a120fa..af306e5ee6c 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1634900/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1636990/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -11978,13 +11978,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 +11999,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(f.onerror())}; } if (typeof GM_addStyle != 'undefined') { _GM_addStyle = GM_addStyle; @@ -24191,6 +24184,7 @@ ImgOps | https://imgops.com/#b#`; var handleError; var cacheNum = 0; var xhr; + var useFetch = false; /** * @param q 图片的选择器或函数 @@ -24259,8 +24253,12 @@ ImgOps | https://imgops.com/#b#`; onload: function(req) { try { if(req.status > 399) throw 'Server error: ' + req.status; - cb(req.responseText, req.finalUrl || url); + else cb(req.responseText, req.finalUrl || url); } catch(ex) { + if (!useFetch && req.responseHeaders.indexOf("cloudflare") != -1) { + useFetch = true; + return downloadPage(url, post, headers, cb); + } handleError(ex); } }, @@ -24278,7 +24276,15 @@ ImgOps | https://imgops.com/#b#`; opts.headers = headers; } - _GM_xmlhttpRequest(opts); + if (useFetch) { + let fetchOption = {method: opts.method || 'GET', headers: opts.headers}; + if (opts.method && opts.method != 'GET') { + fetchOption.body = opts.data || ''; + } + fetch(opts.url, fetchOption).then(response => response.text()).then(data => {opts.onload({responseText: data})}).catch(e => opts.onerror(e)); + } else { + _GM_xmlhttpRequest(opts); + } } function createDoc(text) { @@ -24304,7 +24310,7 @@ ImgOps | https://imgops.com/#b#`; function findFile(n, url) { pretreatment(n, true); - var path = n.src || n.href || (n.children && n.children[0] && n.children[0].src); + var path = (n.dataset && n.dataset.src) || n.src || n.href || (n.children && n.children[0] && n.children[0].src); if (/^video$/i.test(n.nodeName)) { path = "video:" + path; } else if (/^audio$/i.test(n.nodeName)) { From affe424f326dddc10b93c611f981af4f5308bc0b Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 7 Aug 2025 10:58:31 +0900 Subject: [PATCH 0814/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index af306e5ee6c..bd6f8ec5d61 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -11999,7 +11999,7 @@ ImgOps | https://imgops.com/#b#`; _GM_xmlhttpRequest = GM.xmlHttpRequest; GM_fetch = true; } else { - _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(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; From c25a273ffd6d151e02794b822e1379c97487ec4b Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 9 Aug 2025 23:53:24 +0900 Subject: [PATCH 0815/1065] Create X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 68 +++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 X-Downloader/X-Downloader.user.js diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js new file mode 100644 index 00000000000..57e111f7f39 --- /dev/null +++ b/X-Downloader/X-Downloader.user.js @@ -0,0 +1,68 @@ +// ==UserScript== +// @name X-Downloader +// @name:zh-CN X-Downloader +// @name:zh-TW X-Downloader +// @name:ja X-Downloader +// @namespace hoothin +// @version 2025-08-09 +// @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 优化你的 Twitter (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 +// ==/UserScript== + +(function() { + 'use strict'; + let downloadBtn = document.createElement("div"); + downloadBtn.style.cssText = "background: #000000aa; border-radius: 50%; transition: opacity ease 0.3s; position: absolute; top: 0; right: 0px; cursor: pointer; opacity: 0.5; padding: 5px;"; + downloadBtn.innerHTML = ``; + downloadBtn.addEventListener("click", e => { + e.preventDefault(); + e.stopPropagation(); + let parent = downloadBtn.parentNode; + if (!parent) return; + let img = parent.querySelector('[data-testid="tweetPhoto"]>img'); + if (img) { + let newsrc = img.src.replace("_normal.",".").replace("_200x200.",".").replace("_mini.",".").replace("_bigger.",".").replace(/_x\d+\./,"."); + 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"; + } + } + window.open(newsrc, "_blank"); + } else { + while(parent) { + if (parent.nodeName == "ARTICLE" && parent.dataset && parent.dataset.testid == "tweet") { + break; + } + parent = parent.parentNode; + } + if (parent) { + let link = parent.querySelector('a[role="link"][aria-label]'); + window.open(`https://twitter.hoothin.com/?url=${encodeURIComponent(link ? link.href : document.location.href)}`, "_blank"); + } + } + }); + downloadBtn.addEventListener("mouseenter", () => { + downloadBtn.style.opacity = 1; + }); + downloadBtn.addEventListener("mouseleave", () => { + downloadBtn.style.opacity = 0.5; + }); + document.addEventListener("mouseenter", e => { + if (e.target.dataset && e.target.dataset.testid == "tweetPhoto") { + e.target.parentNode.appendChild(downloadBtn); + } else if (e.target.firstElementChild) { + if (e.target.firstElementChild.getAttribute("role") == "progressbar") { + e.target.parentNode.parentNode.appendChild(downloadBtn); + } + } + }, true); +})(); \ No newline at end of file From 2e54cf9bb193294e71b6aceda7537ec27db8db15 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 10 Aug 2025 08:33:19 +0900 Subject: [PATCH 0816/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index dbe73d0134b..bccf054ae16 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -8143,7 +8143,7 @@ const initStyle = `text-indent: initial;display: contents;right: unset;left: unset;top: unset;bottom: unset;inset: unset;clear: both;cy: initial;d: initial;dominant-baseline: initial;empty-cells: initial;fill: initial;fill-opacity: initial;fill-rule: initial;filter: initial;flex: initial;flex-flow: initial;float: initial;flood-color: initial;flood-opacity: initial;grid: initial;grid-area: initial;height: initial;hyphens: initial;image-orientation: initial;image-rendering: initial;inline-size: initial;inset-block: initial;inset-inline: initial;isolation: initial;letter-spacing: initial;lighting-color: initial;line-break: initial;list-style: initial;margin-block: initial;margin: 0px 5px;margin-inline: initial;marker: initial;mask: initial;mask-type: initial;max-block-size: initial;max-height: initial;max-inline-size: initial;max-width: initial;min-block-size: initial;min-height: initial;min-inline-size: initial;min-width: initial;mix-blend-mode: initial;object-fit: initial;object-position: initial;offset: initial;opacity: initial;order: initial;orphans: initial;outline: initial;outline-offset: initial;overflow-anchor: initial;overflow-clip-margin: initial;overflow-wrap: initial;overflow: initial;overscroll-behavior-block: initial;overscroll-behavior-inline: initial;overscroll-behavior: initial;padding-block: initial;padding: initial;padding-inline: initial;page: initial;page-orientation: initial;paint-order: initial;perspective: initial;perspective-origin: initial;pointer-events: initial;position: relative;quotes: initial;r: initial;resize: initial;ruby-position: initial;rx: initial;ry: initial;scroll-behavior: initial;scroll-margin-block: initial;scroll-margin: initial;scroll-margin-inline: initial;scroll-padding-block: initial;scroll-padding: initial;scroll-padding-inline: initial;scroll-snap-align: initial;scroll-snap-stop: initial;scroll-snap-type: initial;scrollbar-gutter: initial;shape-image-threshold: initial;shape-margin: initial;shape-outside: initial;shape-rendering: initial;size: initial;speak: initial;stop-color: initial;stop-opacity: initial;stroke: initial;stroke-dasharray: initial;stroke-dashoffset: initial;stroke-linecap: initial;stroke-linejoin: initial;stroke-miterlimit: initial;stroke-opacity: initial;stroke-width: initial;tab-size: initial;table-layout: initial;text-align: initial;text-align-last: initial;text-anchor: initial;text-combine-upright: initial;text-decoration: initial;text-decoration-skip-ink: initial;text-indent: initial;text-overflow: initial;text-shadow: initial;text-size-adjust: initial;text-transform: initial;text-underline-offset: initial;text-underline-position: initial;touch-action: initial;transform: initial;transform-box: initial;transform-origin: initial;transform-style: initial;transition: initial;user-select: initial;vector-effect: initial;vertical-align: initial;visibility: initial;border-spacing: initial;-webkit-border-image: initial;-webkit-box-align: initial;-webkit-box-decoration-break: initial;-webkit-box-direction: initial;-webkit-box-flex: initial;-webkit-box-ordinal-group: initial;-webkit-box-orient: initial;-webkit-box-pack: initial;-webkit-box-reflect: initial;-webkit-highlight: initial;-webkit-hyphenate-character: initial;-webkit-line-break: initial;-webkit-line-clamp: initial;-webkit-mask-box-image: initial;-webkit-mask: initial;-webkit-mask-composite: initial;-webkit-perspective-origin-x: initial;-webkit-perspective-origin-y: initial;-webkit-print-color-adjust: initial;-webkit-rtl-ordering: initial;-webkit-ruby-position: initial;-webkit-tap-highlight-color: initial;-webkit-text-combine: initial;-webkit-text-decorations-in-effect: initial;-webkit-text-emphasis: initial;-webkit-text-emphasis-position: initial;-webkit-text-fill-color: initial;-webkit-text-security: initial;-webkit-text-stroke: initial;-webkit-transform-origin-x: initial;-webkit-transform-origin-y: initial;-webkit-transform-origin-z: initial;-webkit-user-drag: initial;-webkit-user-modify: initial;white-space: initial;widows: initial;width: initial;will-change: initial;word-break: initial;word-spacing: initial;x: initial;y: initial;`; const pageTextStyle = `opacity: 1!important;text-indent: initial;padding: unset;border: none;background: unset!important;line-height: 30px;text-decoration: none;user-select: none;visibility: visible;position: initial;width: auto;max-width: 80%; white-space: nowrap; text-overflow: ellipsis;overflow: hidden;height: auto;float: none;clear: both;margin: 0px;text-align: center;display: inline-block;font-weight: bold;font-style: normal;font-size: 16px;letter-spacing: initial;vertical-align: top;color: rgb(85, 85, 95)!important;`; - const corsTips = "Blocked by CORS, try to install an extension like 'Ignore X-Frame headers'."; + const corsTips = "Blocked by CORS, try to install an extension like 'Ignore X-Frame options'."; var sideControllerIcon = ''; var tipsWords = document.createElement("div"); From 5f57be14f57b4b2146e8961f58b80596a20bca6e Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 10 Aug 2025 09:58:03 +0900 Subject: [PATCH 0817/1065] Update X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 71 +++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index 57e111f7f39..1f516513296 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -4,9 +4,10 @@ // @name:zh-TW X-Downloader // @name:ja X-Downloader // @namespace hoothin -// @version 2025-08-09 +// @version 2025-08-10 +// @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 优化你的 Twitter (X) 浏览体验,直接在图片和视频(GIF)上添加一个便捷的下载按钮,一键轻松保存喜欢的媒体内容。 +// @description:zh-CN 优化你的推特 (X) 浏览体验,直接在图片和视频(GIF)上添加一个便捷的下载按钮,一键轻松保存喜欢的媒体内容。 // @description:zh-TW 優化您的 Twitter (X) 瀏覽體驗,直接在圖片及影片(GIF)上新增一個便捷的下載按鈕,一鍵輕鬆儲存喜愛的媒體內容。 // @description:ja Twitter (X) の画像や動画(GIF)に便利なダウンロードボタンを追加し、ワンクリックでお気に入りのメディアを簡単に保存できるようにします。 // @author hoothin @@ -14,21 +15,22 @@ // @match https://twitter.com/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant none +// @downloadURL https://update.greasyfork.org/scripts/545186/X-Downloader.user.js +// @updateURL https://update.greasyfork.org/scripts/545186/X-Downloader.meta.js // ==/UserScript== (function() { 'use strict'; - let downloadBtn = document.createElement("div"); + let downloadBtn = document.createElement("a"); + 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.5; padding: 5px;"; downloadBtn.innerHTML = ``; - downloadBtn.addEventListener("click", e => { - e.preventDefault(); - e.stopPropagation(); + downloadBtn.addEventListener("mousedown", e => { let parent = downloadBtn.parentNode; if (!parent) return; let img = parent.querySelector('[data-testid="tweetPhoto"]>img'); if (img) { - let newsrc = img.src.replace("_normal.",".").replace("_200x200.",".").replace("_mini.",".").replace("_bigger.",".").replace(/_x\d+\./,"."); + 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, ""); @@ -36,7 +38,30 @@ newsrc = newsrc + "&name=orig"; } } - window.open(newsrc, "_blank"); + 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.altKey) { + downloadByFetch(newsrc, imgname); + } } else { while(parent) { if (parent.nodeName == "ARTICLE" && parent.dataset && parent.dataset.testid == "tweet") { @@ -45,17 +70,45 @@ parent = parent.parentNode; } if (parent) { + downloadBtn.removeAttribute('download'); let link = parent.querySelector('a[role="link"][aria-label]'); - window.open(`https://twitter.hoothin.com/?url=${encodeURIComponent(link ? link.href : document.location.href)}`, "_blank"); + downloadBtn.href = `https://twitter.hoothin.com/?url=${encodeURIComponent(link ? link.href : document.location.href)}`; + if (e.altKey) { + window.open(downloadBtn.href, "_blank"); + } } } }); + downloadBtn.addEventListener("click", e => { + if (e.altKey) { + e.preventDefault(); + e.stopPropagation(); + } + }); downloadBtn.addEventListener("mouseenter", () => { downloadBtn.style.opacity = 1; }); downloadBtn.addEventListener("mouseleave", () => { downloadBtn.style.opacity = 0.5; }); + 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'); + } + } document.addEventListener("mouseenter", e => { if (e.target.dataset && e.target.dataset.testid == "tweetPhoto") { e.target.parentNode.appendChild(downloadBtn); From 27233b6a855e91668acabd657989dbc0633581b9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 10 Aug 2025 10:49:43 +0900 Subject: [PATCH 0818/1065] Update X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index 1f516513296..d62db8e4e63 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -109,13 +109,19 @@ window.open(imageUrl, '_blank'); } } - document.addEventListener("mouseenter", e => { + const addBtn = e => { if (e.target.dataset && e.target.dataset.testid == "tweetPhoto") { e.target.parentNode.appendChild(downloadBtn); + } else if (e.target.dataset && /^video\-player/.test(e.target.dataset.testid)) { + e.target.parentNode.appendChild(downloadBtn); } else if (e.target.firstElementChild) { if (e.target.firstElementChild.getAttribute("role") == "progressbar") { e.target.parentNode.parentNode.appendChild(downloadBtn); } + } else if (e.target.parentNode && e.target.parentNode.dataset && e.target.parentNode.dataset.testid == "tweetPhoto") { + e.target.parentNode.parentNode.appendChild(downloadBtn); } - }, true); + }; + document.addEventListener("mouseenter", addBtn, true); + document.addEventListener("touchstart", addBtn, true); })(); \ No newline at end of file From 63f0131bfb98f642f75bf6cb60191e9a08caeb3f Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 10 Aug 2025 13:51:53 +0900 Subject: [PATCH 0819/1065] Update X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index d62db8e4e63..1f1fac960e7 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -28,7 +28,7 @@ downloadBtn.addEventListener("mousedown", e => { let parent = downloadBtn.parentNode; if (!parent) return; - let img = parent.querySelector('[data-testid="tweetPhoto"]>img'); + 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; @@ -110,7 +110,9 @@ } } const addBtn = e => { - if (e.target.dataset && e.target.dataset.testid == "tweetPhoto") { + if (e.target.dataset && e.target.dataset.testid == "card.layoutLarge.media") { + e.target.parentNode.appendChild(downloadBtn); + } else if (e.target.dataset && e.target.dataset.testid == "tweetPhoto") { e.target.parentNode.appendChild(downloadBtn); } else if (e.target.dataset && /^video\-player/.test(e.target.dataset.testid)) { e.target.parentNode.appendChild(downloadBtn); From 077a058325d1c4ec8f2dd65aead04d44e81f3b73 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 10 Aug 2025 21:29:00 +0900 Subject: [PATCH 0820/1065] Update X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index 1f1fac960e7..f05bea2b7df 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -116,10 +116,6 @@ e.target.parentNode.appendChild(downloadBtn); } else if (e.target.dataset && /^video\-player/.test(e.target.dataset.testid)) { e.target.parentNode.appendChild(downloadBtn); - } else if (e.target.firstElementChild) { - if (e.target.firstElementChild.getAttribute("role") == "progressbar") { - e.target.parentNode.parentNode.appendChild(downloadBtn); - } } else if (e.target.parentNode && e.target.parentNode.dataset && e.target.parentNode.dataset.testid == "tweetPhoto") { e.target.parentNode.parentNode.appendChild(downloadBtn); } From 2d7d813e5d57909df763bd41e153cd69de42a409 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 12 Aug 2025 12:49:34 +0900 Subject: [PATCH 0821/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index bccf054ae16..e8d06b0fbcc 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -1472,7 +1472,7 @@ const ruleImportUrlReg = /greasyfork\.org\/.*scripts\/438684(\-[^\/]*)?(\/discussions|\/?$|\/feedback)|github\.com\/hoothin\/UserScripts\/(tree\/master\/Pagetual|issues)|^https:\/\/pagetual\.hoothin\.com\/.*firstRun\.html/i; const allOfBody = "body>*"; const mainSel = ["article,.article","[role=main],main,.main,#main","#results"]; - const nextTextReg1 = new RegExp("\u005e\u7ffb\u003f\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u2500\u0031\u005d\u003f\u005b\u9875\u9801\u5f20\u5f35\u005d\u007c\u005e\u006e\u0065\u0078\u0074\u005b\u005c\u0073\u005f\u002d\u005d\u003f\u0070\u0061\u0067\u0065\u005c\u0073\u002a\u005b\u203a\u003e\u2192\u00bb\u005d\u003f\u0024\u007c\u6b21\u306e\u30da\u30fc\u30b8\u007c\u005e\u6b21\u3078\u003f\u0024\u007c\u0412\u043f\u0435\u0440\u0435\u0434\u007c\u005e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435", "i"); + const nextTextReg1 = new RegExp("\u005e\u7ffb\u003f\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u2500\u0031\u005d\u003f\u005b\u9875\u9801\u5f20\u5f35\u005d\u007c\u005e\u006e\u0065\u0078\u0074\u005b\u005c\u0073\u005f\u002d\u005d\u003f\u0070\u0061\u0067\u0065\u005c\u0073\u002a\u005b\u203a\u003e\u2192\u00bb\u005d\u003f\u0024\u007c\u6b21\u306e\u30da\u30fc\u30b8\u007c\u005e\u6b21\u3078\u0024\u007c\u0412\u043f\u0435\u0440\u0435\u0434\u007c\u005e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435", "i"); const nextTextReg2 = new RegExp("\u005e\u0028\u005b\u4e0b\u540e\u5f8c\u6b21\u005d\u005b\u4e00\u30fc\u2500\u0031\u005d\u003f\u005b\u7ae0\u8bdd\u8a71\u8282\u7bc0\u5e45\u005d\u007c\u006e\u0065\u0078\u0074\u002e\u003f\u0063\u0068\u0061\u0070\u0074\u0065\u0072\u0029\u0028\u005b\u003a\uff1a\u005c\u002d\u005f\u2014\u005c\u0073\u005c\u002e\u3002\u003e\u0023\u00b7\u005c\u005b\u3010\u3001\uff08\u005c\u0028\u002f\u002c\uff0c\uff1b\u003b\u2192\u005d\u007c\u0024\u0029", "i"); const nextTextReg3 = /^(next\s*(»|>>|>|›|→|❯|\d+)?|>|▶|>|›|→|❯)\s*$/i; const prevReg = new RegExp("\u005e\u005c\u0073\u002a\u0028\u005b\u4e0a\u524d\u9996\u5c3e\u005d\u007c\u0070\u0072\u0065\u0076\u007c\u0065\u006e\u0064\u0029", "i"); From ca3e256c8295f08840260fa229f80d8784f9edd0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 13 Aug 2025 19:01:51 +0900 Subject: [PATCH 0822/1065] Update X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index f05bea2b7df..b121fd83e1a 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -1,10 +1,10 @@ // ==UserScript== -// @name X-Downloader -// @name:zh-CN X-Downloader -// @name:zh-TW X-Downloader -// @name:ja X-Downloader +// @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-10 +// @version 2025-08-13 // @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)上添加一个便捷的下载按钮,一键轻松保存喜欢的媒体内容。 @@ -89,7 +89,7 @@ downloadBtn.style.opacity = 1; }); downloadBtn.addEventListener("mouseleave", () => { - downloadBtn.style.opacity = 0.5; + downloadBtn.style.opacity = 0.1; }); async function downloadByFetch(imageUrl, filename) { try { From d64b63843bd7e75f29e56c2c9910a3141c5d5389 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 13 Aug 2025 19:07:23 +0900 Subject: [PATCH 0823/1065] Update X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index b121fd83e1a..456b6534c7a 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -23,7 +23,7 @@ 'use strict'; let downloadBtn = document.createElement("a"); 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.5; padding: 5px;"; + 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; @@ -109,15 +109,21 @@ window.open(imageUrl, '_blank'); } } + const show = (ele) => { + ele.appendChild(downloadBtn); + setTimeout(() => { + downloadBtn.style.opacity = 0.6; + }, 0); + }; const addBtn = e => { if (e.target.dataset && e.target.dataset.testid == "card.layoutLarge.media") { - e.target.parentNode.appendChild(downloadBtn); + show(e.target.parentNode); } else if (e.target.dataset && e.target.dataset.testid == "tweetPhoto") { - e.target.parentNode.appendChild(downloadBtn); + show(e.target.parentNode); } else if (e.target.dataset && /^video\-player/.test(e.target.dataset.testid)) { - e.target.parentNode.appendChild(downloadBtn); + show(e.target.parentNode); } else if (e.target.parentNode && e.target.parentNode.dataset && e.target.parentNode.dataset.testid == "tweetPhoto") { - e.target.parentNode.parentNode.appendChild(downloadBtn); + show(e.target.parentNode.parentNode); } }; document.addEventListener("mouseenter", addBtn, true); From 43b3c9aab2edf1917ec18c8e78cb5fab3ca12711 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 13 Aug 2025 19:09:24 +0900 Subject: [PATCH 0824/1065] Update X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index 456b6534c7a..9120b855507 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -89,7 +89,9 @@ downloadBtn.style.opacity = 1; }); downloadBtn.addEventListener("mouseleave", () => { - downloadBtn.style.opacity = 0.1; + setTimeout(() => { + downloadBtn.style.opacity = 0.1; + }, 100); }); async function downloadByFetch(imageUrl, filename) { try { From 7258a7119f02a0a6c8a4e4f544e82efe69e4a1a9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 13 Aug 2025 19:43:52 +0900 Subject: [PATCH 0825/1065] Update readme.md --- .../lib/readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md index 0384226f00b..81554448ece 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md +++ b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md @@ -1,6 +1,6 @@ 簡繁自由切換 === -> 切換簡體中文與正體中文 +> 切換正體/簡體中文,超輕量級,支援自訂詞彙與「一簡多繁」轉換,無任何相依性 [![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) @@ -10,9 +10,9 @@ + 基礎用法 ``` js -import Stcasc from './stcasc.lib.js'; -let stcasc = Stcasc(); -console.log(stcasc.traditionalized("香烟 香烟袅袅 烟雾里 里长面子 吃干面 干 把考卷发回来 卷发")); +const stcasc = Stcasc(); +const sc = "香烟 香烟袅袅 烟雾里 里长面子 吃干面 干 把考卷发回来 卷发"; +console.log(stcasc.traditionalized(sc)); //香菸 香煙裊裊 煙霧裡 里長面子 吃乾麵 幹 把考卷發回來 捲髮 ``` From 8a4f32764cd17f3422e199e6586f93a3502a398d Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 13 Aug 2025 20:05:43 +0900 Subject: [PATCH 0826/1065] sc2tcComb --- .../lib/package.json | 2 +- .../lib/readme.md | 18 ++++++++++++++++-- .../lib/stcasc.lib.js | 5 +++-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/package.json b/Switch Traditional Chinese and Simplified Chinese/lib/package.json index bb07bc51b0b..69c75edbaac 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/package.json +++ b/Switch Traditional Chinese and Simplified Chinese/lib/package.json @@ -1,6 +1,6 @@ { "name": "switch-chinese", - "version": "1.0.2", + "version": "1.0.3", "description": "Convert between simplified and traditional Chinese characters", "main": "stcasc.lib.js", "type": "module", diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md index 81554448ece..b330d713d23 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md +++ b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md @@ -10,10 +10,18 @@ + 基礎用法 ``` js +import Stcasc from './stcasc.lib.js'; const stcasc = Stcasc(); -const sc = "香烟 香烟袅袅 烟雾里 里长面子 吃干面 干 把考卷发回来 卷发"; +const sc = "香烟 香烟袅袅 烟雾里 里长面子 吃干面 干 把考卷发回来 卷发 知识产权"; console.log(stcasc.traditionalized(sc)); -//香菸 香煙裊裊 煙霧裡 里長面子 吃乾麵 幹 把考卷發回來 捲髮 +//香菸 香煙裊裊 煙霧裡 里長面子 吃乾麵 幹 把考卷發回來 捲髮 智慧財產權 +``` + +``` js +const stcasc = Stcasc({}, {}, true); +const sc = "知识产权"; +console.log(stcasc.traditionalized(sc)); +//知識産權 ``` + 透過 npm 安裝 @@ -56,3 +64,9 @@ const custom = { }; let stcasc = Stcasc(cache, custom); ``` + ++ 禁用用語轉換 + +``` js +let stcasc = Stcasc({}, {}, true); +``` diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js index f1fdb131004..5ec6942ab14 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js +++ b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js @@ -473,7 +473,7 @@ const tc2sc = { ['了','瞭望','瞭然','瞭解','瞭若指掌','瞭如指掌'] ] }; -const sc2tcComb = { +let sc2tcComb = { '香烟袅袅':'香煙裊裊', '袅袅香烟':'裊裊香煙', '补丁':'補靪', @@ -756,12 +756,13 @@ function simplized(orgStr) { return str; } -function Stcasc(cache, custom) { +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]; From 4cc82475f7d5691487a2f52952e184d60997915f Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 14 Aug 2025 14:47:24 +0900 Subject: [PATCH 0827/1065] 1.9.37.122 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 40 +++++++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index f5fec67cd21..f9ac544ca9e 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.121](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.122](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index e8d06b0fbcc..7074a186f1a 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.121 +// @version 1.9.37.122 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -8014,32 +8014,32 @@ margin-top: 30px!important; pointer-events: all; } - .pagetual_pageBar span>svg { + .pagetual_pageBar a>svg { -moz-transition:transform 0.5s ease, opacity 0.3s ease; -webkit-transition:transform 0.5s ease, opacity 0.3s ease; transition:transform 0.5 ease, opacity 0.3s ease; opacity: 0; } - .pagetual_pageBar.stop span>svg{ + .pagetual_pageBar.stop a>svg{ opacity: 1; } - .pagetual_pageBar.stop span>svg>path{ + .pagetual_pageBar.stop a>svg>path{ transform: scale(.8); transform-origin: center; -moz-transition:transform 0.3s ease; -webkit-transition:transform 0.3s ease; transition:transform 0.3 ease; } - .pagetual_pageBar.stop:hover span>svg>path{ + .pagetual_pageBar.stop:hover a>svg>path{ transform: unset; } - .pagetual_pageBar:hover span>svg { + .pagetual_pageBar:hover a>svg { opacity: 1; } - .pagetual_pageBar span>svg.upSvg:hover { + .pagetual_pageBar a>svg.upSvg:hover { transform: rotate(360deg) scale3d(1.2, 1.2, 1.2); } - .pagetual_pageBar span>svg.downSvg:hover { + .pagetual_pageBar a>svg.downSvg:hover { transform: rotate(540deg) scale3d(1.2, 1.2, 1.2)!important; } .pagetual_pageBar .pagetual_pageNum{ @@ -8773,8 +8773,8 @@ inLi = compareNodeName(example, ["li"]) || (example.nextElementSibling && compareNodeName(example.nextElementSibling, ["li"])); } let pageBar = document.createElement(inTable ? "tr" : (inLi ? "li" : "div")); - let upSpan = document.createElement("span"); - let downSpan = document.createElement("span"); + let upSpan = document.createElement("a"); + let downSpan = document.createElement("a"); let pageText = document.createElement("a"); let pageNum; pageBar.className = isHideBar ? "pagetual_pageBar autopagerize_page_info hide" : "pagetual_pageBar autopagerize_page_info"; @@ -8787,6 +8787,7 @@ upSpan.innerHTML = createHTML(upSvg); upSpan.children[0].style.cssText = upSvgCSS; upSpan.title = i18n("toTop"); + upSpan.href = ruleParser.initUrl || ''; downSpan.innerHTML = createHTML(downSvg); downSpan.children[0].style.cssText = downSvgCSS; downSpan.title = i18n("toBottom"); @@ -9006,21 +9007,32 @@ } upSpan.addEventListener("click", e => { + e.stopPropagation(); + if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) { + if (e.altKey) location.href = upSpan.href; + return; + } getBody(document).scrollTop = 0; document.documentElement.scrollTop = 0; e.preventDefault(); - e.stopPropagation(); + }); + downSpan.addEventListener("mousedown", e => { + if (ruleParser.nextLinkHref && ruleParser.nextLinkHref != '#') { + downSpan.href = ruleParser.nextLinkHref; + } else downSpan.href = ''; }); downSpan.addEventListener("click", e => { - if (!e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey) { - changeStop(true); + e.stopPropagation(); + if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) { + if (e.altKey && downSpan.getAttribute('href')) location.href = upSpan.href; + return; } + changeStop(true); pageBar.title = i18n(isPause ? "enable" : "disable"); scrollH = Math.max(document.documentElement.scrollHeight, getBody(document).scrollHeight); getBody(document).scrollTop = scrollH || 9999999; document.documentElement.scrollTop = scrollH || 9999999; e.preventDefault(); - e.stopPropagation(); }); pageBar.addEventListener("click", e => { changeStop(!isPause); From c80bb58a9360085dff46c673bfc6719ea58590fb Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 15 Aug 2025 19:54:02 +0900 Subject: [PATCH 0828/1065] update --- Picviewer CE+/pvcep_rules.js | 4 ++-- .../lib/package.json | 10 +++++++--- .../lib/readme.md | 17 +++++++---------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 28a323f93ef..d19952f0a12 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1939,8 +1939,8 @@ var siteInfo = [ { name: "Google review", url: /\bgoogle\.com\//, - r: /=w\d+\-h\d+\-\w/, - s: "=s3072-v1" + r: [/=w\d+\-h\d+\-\w/, /=s\d+/], + s: ["=s0-v1", "=s0"] }, { name: "MAL Anime/Manga", diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/package.json b/Switch Traditional Chinese and Simplified Chinese/lib/package.json index 69c75edbaac..37afff9f862 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/package.json +++ b/Switch Traditional Chinese and Simplified Chinese/lib/package.json @@ -1,7 +1,7 @@ { "name": "switch-chinese", - "version": "1.0.3", - "description": "Convert between simplified and traditional Chinese characters", + "version": "1.0.4", + "description": "Convert between simplified and traditional Chinese characters. 切換正體/簡體中文,超輕量級,支援自訂詞彙與「一簡多繁」轉換,無任何相依性。", "main": "stcasc.lib.js", "type": "module", "repository": { @@ -17,7 +17,11 @@ "繁体中文", "簡體中文", "繁體中文", - "正體中文" + "正體中文", + "简繁切换", + "簡繁切換", + "繁简转换", + "繁簡轉換" ], "author": "Hoothin", "license": "MIT", diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md index b330d713d23..eba1b85e44f 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md +++ b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md @@ -17,16 +17,10 @@ console.log(stcasc.traditionalized(sc)); //香菸 香煙裊裊 煙霧裡 里長面子 吃乾麵 幹 把考卷發回來 捲髮 智慧財產權 ``` -``` js -const stcasc = Stcasc({}, {}, true); -const sc = "知识产权"; -console.log(stcasc.traditionalized(sc)); -//知識産權 -``` + 透過 npm 安裝 -``` +``` shell npm install switch-chinese import Stcasc from 'switch-chinese'; ``` @@ -45,7 +39,7 @@ stcasc.simplized("正體中文"); //正体中文 ``` -+ 添加快取 ++ 添加快取,避免重複生成字典 ``` js let cache = loadCacheAtYourWay(); @@ -62,11 +56,14 @@ const custom = { "转换": "轉檔", "软件": "軟體" }; -let stcasc = Stcasc(cache, custom); +const stcasc = Stcasc(cache, custom); ``` + 禁用用語轉換 ``` js -let stcasc = Stcasc({}, {}, true); +const stcasc = Stcasc({}, {}, true); +const sc = "知识产权"; +console.log(stcasc.traditionalized(sc)); +//知識産權 ``` From b759fdf3518507999940ffc7f48a6a2735447a49 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 15 Aug 2025 19:55:59 +0900 Subject: [PATCH 0829/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index bd6f8ec5d61..76c454c3d42 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1636990/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1642363/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From 3c476228f79fbea7f5fa33f4779d259ffc496250 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 17 Aug 2025 09:28:16 +0900 Subject: [PATCH 0830/1065] Update X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index 9120b855507..a5d69582c7d 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -4,7 +4,7 @@ // @name:zh-TW X-Downloader-Script // @name:ja X-Downloader-Script // @namespace hoothin -// @version 2025-08-13 +// @version 2025-08-17 // @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)上添加一个便捷的下载按钮,一键轻松保存喜欢的媒体内容。 @@ -71,7 +71,7 @@ } if (parent) { downloadBtn.removeAttribute('download'); - let link = parent.querySelector('a[role="link"][aria-label]'); + let link = parent.querySelector('a[role="link"][aria-label][href^="/"]'); downloadBtn.href = `https://twitter.hoothin.com/?url=${encodeURIComponent(link ? link.href : document.location.href)}`; if (e.altKey) { window.open(downloadBtn.href, "_blank"); From 395a4b62261fab68311405554dcab39d0e23a92e Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 17 Aug 2025 10:20:46 +0900 Subject: [PATCH 0831/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index d19952f0a12..f6782e7b598 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1027,10 +1027,25 @@ var siteInfo = [ }, { name: "Rule34", - url: /\brule34\.xxx/, + url: /\b(rule34\.xxx|realbooru\.com)/, src: /\/(thumbnails|samples)\/(.*)\/(thumbnail|sample)_/i, - r: /\/(thumbnails|samples)\/(.*)\/(thumbnail|sample)_(.*)\..*/i, - s: ["/images/$2/$4.jpeg","/images/$2/$4.png","/images/$2/$4.jpg"] + xhr: { + url: function(a, p) { + if (!a) return; + const re = /^https?:\/\/(?:www\.)?(?:(realbooru\.com|rule34\.xxx))\/index\.php\?page=post&s=view&id=(\d+).*/; + const m = a.href.match(re); + if (m) { + return m[1] == "rule34.xxx" ? `https://api.${m[1]}/index.php?page=dapi&s=post&q=index&id=${m[2]}&json=1` : `https://${m[1]}/index.php?page=dapi&s=post&q=index&id=${m[2]}&json=1`; + } + }, + query: function(html, doc, url) { + try { + const o = JSON.parse(html); + let url = o[0]; + return url.file_url || `https://${location.hostname}/images/${url.directory}/${url.image}`; + } catch { } + } + } }, { name: "Photosight", From 1782dd939d5c2efd37ecadd44aaa77abbc5b5b87 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 17 Aug 2025 10:21:32 +0900 Subject: [PATCH 0832/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 76c454c3d42..19f0b3fe339 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.8.2.1 +// @version 2025.8.17.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1642363/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1643244/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 From bbf451f4c4f8d81e3749d5902ea8c1e855d41f4c Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 18 Aug 2025 22:26:47 +0900 Subject: [PATCH 0833/1065] Update X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 38 +++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index a5d69582c7d..15905cb48dd 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -4,7 +4,7 @@ // @name:zh-TW X-Downloader-Script // @name:ja X-Downloader-Script // @namespace hoothin -// @version 2025-08-17 +// @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)上添加一个便捷的下载按钮,一键轻松保存喜欢的媒体内容。 @@ -21,7 +21,7 @@ (function() { 'use strict'; - let downloadBtn = document.createElement("a"); + let downloadBtn = document.createElement("a"), touch = 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 = ``; @@ -59,7 +59,7 @@ imgname = `${user.innerText} ${time.innerText.replace(/(.*) · (.*)/, "$2 $1")}.${ext}`; } downloadBtn.href = newsrc; - if (e.altKey) { + if (e.altKey || touch) { downloadByFetch(newsrc, imgname); } } else { @@ -114,7 +114,7 @@ const show = (ele) => { ele.appendChild(downloadBtn); setTimeout(() => { - downloadBtn.style.opacity = 0.6; + downloadBtn.style.opacity = touch ? 0.8 : 0.6; }, 0); }; const addBtn = e => { @@ -128,6 +128,34 @@ show(e.target.parentNode.parentNode); } }; + function findFirstVisibleElement(selector) { + const elements = document.querySelectorAll(selector); + const firstVisibleElement = Array.from(elements).find(el => { + const rect = el.getBoundingClientRect(); + return rect.top < window.innerHeight && rect.top > 0 && rect.bottom >= 0; + }); + return firstVisibleElement; + } + let checkTimer; + const touchCheck = e => { + clearTimeout(checkTimer); + if (e.target == downloadBtn) return; + checkTimer = setTimeout(() => { + 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", addBtn, true); + document.addEventListener("touchstart", e => {touch = true; addBtn(e);}, true); + document.addEventListener("touchend", touchCheck, true); })(); \ No newline at end of file From 04e946a3ab617b8bd9335b70fd9130e3da0a32ab Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 19 Aug 2025 09:38:50 +0900 Subject: [PATCH 0834/1065] 1.9.37.123 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index f9ac544ca9e..d10465d01b4 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.122](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.123](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 7074a186f1a..b4381a9b27c 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.122 +// @version 1.9.37.123 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -2438,7 +2438,7 @@ } this.curSiteRule.pageElement = tempSel + (targetChild ? ">*" : ""); break; - } + } else pageElement = null; } if (!pageElement || pageElement.length === 0) { let pageElementSelTrim = pageElementSel.replace(/:nth-of-type\(\d+\)/g, ""); @@ -2464,8 +2464,8 @@ pageElement = pageElement.children; } this.curSiteRule.pageElement = pageElementSelTrim + (targetChild ? ">*" : ""); - } - } + } else pageElement = null; + } else pageElement = null; } } } @@ -8702,7 +8702,11 @@ } } if (loadmoreBtn && !ruleParser.curSiteRule.loadMore && loadmoreBtn.dataset.ajax !== "true") { - let href = loadmoreBtn.getAttribute("href"); + let href = loadmoreBtn.getAttribute("href"), i = 0, pa = loadmoreBtn.parentNode; + while (!href && i++ < 5 && pa) { + href = pa.getAttribute && pa.getAttribute("href"); + pa = pa.parentNode; + } if (href && href != "/" && !ruleParser.hrefIsJs(href)) { loadmoreBtn = null; } From 50faed9af511e2c76d3a13c5262378852bc20350 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 19 Aug 2025 18:21:18 +0900 Subject: [PATCH 0835/1065] Update X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index 15905cb48dd..02291b35eef 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -128,11 +128,14 @@ 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 => { - const rect = el.getBoundingClientRect(); - return rect.top < window.innerHeight && rect.top > 0 && rect.bottom >= 0; + return isElementVisible(el); }); return firstVisibleElement; } @@ -141,6 +144,7 @@ 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); From 72bb0a237b467a21a883de15c7ce999ea81dc310 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 19 Aug 2025 18:25:54 +0900 Subject: [PATCH 0836/1065] Update X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index 02291b35eef..163600fb25b 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -80,7 +80,7 @@ } }); downloadBtn.addEventListener("click", e => { - if (e.altKey) { + if (e.altKey || touch) { e.preventDefault(); e.stopPropagation(); } From f9aa7ac563e26b559f88ae185c6dbf95ee4f16e3 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 19 Aug 2025 18:27:41 +0900 Subject: [PATCH 0837/1065] Update X-Downloader.user.js --- X-Downloader/X-Downloader.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index 163600fb25b..c488f1f1ef4 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -73,7 +73,7 @@ downloadBtn.removeAttribute('download'); let link = parent.querySelector('a[role="link"][aria-label][href^="/"]'); downloadBtn.href = `https://twitter.hoothin.com/?url=${encodeURIComponent(link ? link.href : document.location.href)}`; - if (e.altKey) { + if (e.altKey || touch) { window.open(downloadBtn.href, "_blank"); } } From b9190596919c285d3f051f8710e2eb7a57f97fe8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 21 Aug 2025 12:08:16 +0900 Subject: [PATCH 0838/1065] Update README.md --- Picviewer CE+/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 89d22cddfd0..9a99e07cd7a 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -197,6 +197,8 @@ Feel free to share your own custom rules on Greasy Fork! - getImage - getExtSrc + Learn from https://github.com/hoothin/UserScripts/blob/master/Picviewer%20CE%2B/pvcep_rules.js +
    ## Blank Gallery Page From 8ce1d22b9bcf36ff223e4a04b7f570fc7503c375 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 22 Aug 2025 16:23:48 +0900 Subject: [PATCH 0839/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 19f0b3fe339..d088c6e3f83 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.8.17.1 +// @version 2025.8.22.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -25789,7 +25789,9 @@ ImgOps | https://imgops.com/#b#`; selectionChanging = false; const selection = window.getSelection(); selectionStr = selection.toString(); - if (selectionStr && selectionStr.length < 500 && imageReg.test(selectionStr)) { + if (selectionStr && selectionStr.length < 500) selectionStr = selectionStr.trim().replace(/^t?t?p?s?:/, "https:"); + else selectionStr = ''; + if (selectionStr && imageReg.test(selectionStr)) { const range = selection.getRangeAt(0); selectionClientRect = range.getBoundingClientRect(); } else { From 2c7aeae3ce3dade28a118785ae3eaa6e267539d4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 27 Aug 2025 21:35:54 +0900 Subject: [PATCH 0840/1065] update --- Pagetual/pagetual.user.js | 2 +- .../lib/package.json | 22 +++++++++++-------- .../lib/readme.md | 20 ++++++++++------- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index b4381a9b27c..518decd7fbb 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -8674,7 +8674,7 @@ } const loadmoreReg = /^\s*((点击?)?(这里)?((看|加载|展开)(更多|剩余)|继续加载)|(點擊?)?(這裡)?((看|加載|展開)(更多|剩餘)|繼續加載)|load\s*more|もっと読み込む)[\.…▼\s\d%]*$/i; - const defaultLoadmoreSel = ".loadMore,.LoadMore,[class^='load-more'],[class*=' load-more'],.show-more,[class*='_show-more'],[class*='-show-more'],button.show_more,button[data-testid='more-results-button'],#btn_preview_remain,.view-more-btn"; + const defaultLoadmoreSel = ".loadMore,.LoadMore,[class^='load-more'],[class*=' load-more'],.show-more,button.show_more,button[data-testid='more-results-button'],#btn_preview_remain,.view-more-btn"; function getLoadMore(doc, loadmoreBtn) { if (!loadmoreBtn || !getBody(doc).contains(loadmoreBtn) || /less/.test(loadmoreBtn.innerText)) loadmoreBtn = null; let loadMoreSel = ruleParser.curSiteRule.loadMore; diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/package.json b/Switch Traditional Chinese and Simplified Chinese/lib/package.json index 37afff9f862..2b4c2b72a33 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/package.json +++ b/Switch Traditional Chinese and Simplified Chinese/lib/package.json @@ -1,6 +1,6 @@ { "name": "switch-chinese", - "version": "1.0.4", + "version": "1.0.6", "description": "Convert between simplified and traditional Chinese characters. 切換正體/簡體中文,超輕量級,支援自訂詞彙與「一簡多繁」轉換,無任何相依性。", "main": "stcasc.lib.js", "type": "module", @@ -9,19 +9,23 @@ "url": "git+https://github.com/hoothin/UserScripts.git#master" }, "keywords": [ - "Switch", - "Traditional", - "Chinese", - "Simplified", + "简繁转换", + "簡繁轉換", + "简繁切换", + "簡繁切換", + "繁简转换", + "繁簡轉換", + "繁简切换", + "繁簡切換", "简体中文", "繁体中文", "簡體中文", "繁體中文", "正體中文", - "简繁切换", - "簡繁切換", - "繁简转换", - "繁簡轉換" + "Switch", + "Traditional", + "Chinese", + "Simplified" ], "author": "Hoothin", "license": "MIT", diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md index eba1b85e44f..cfe0e6f52e7 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md +++ b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md @@ -4,24 +4,28 @@ [![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) +Install +--- +``` shell +npm install switch-chinese +``` 演示 --- + 基礎用法 ``` js -import Stcasc from './stcasc.lib.js'; const stcasc = Stcasc(); -const sc = "香烟 香烟袅袅 烟雾里 里长面子 吃干面 干 把考卷发回来 卷发 知识产权"; -console.log(stcasc.traditionalized(sc)); -//香菸 香煙裊裊 煙霧裡 里長面子 吃乾麵 幹 把考卷發回來 捲髮 智慧財產權 +const sc = "简繁转换 繁简切换 香烟 香烟袅袅 烟雾里 里长面子 吃干面 干 把考卷发回来 卷发 知识产权"; +const tc = stcasc.traditionalized(sc); +console.log(tc); +//簡繁轉換 繁簡切換 香菸 香煙裊裊 煙霧裡 里長面子 吃乾麵 幹 把考卷發回來 捲髮 智慧財產權 ``` -+ 透過 npm 安裝 ++ Import ``` shell -npm install switch-chinese import Stcasc from 'switch-chinese'; ``` @@ -35,8 +39,8 @@ stcasc.traditionalized("简体中文"); + 轉簡體中文 ``` js -stcasc.simplized("正體中文"); -//正体中文 +stcasc.simplized("繁體中文"); +//繁体中文 ``` + 添加快取,避免重複生成字典 From a25ae67125715dd36e9b28a513a0835c114c71b8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 28 Aug 2025 17:20:04 +0900 Subject: [PATCH 0841/1065] Update BingBgForBaidu.user.js --- BingBgForBaidu/BingBgForBaidu.user.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/BingBgForBaidu/BingBgForBaidu.user.js b/BingBgForBaidu/BingBgForBaidu.user.js index 1e10922d55b..c33755d652d 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.41 +// @version 2.3.42 // @description 给百度首页换上Bing的背景图,并添加背景图链接与日历组件 // @description:en Just change the background image of baidu.com to bing.com // @author hoothin @@ -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(134); - iframe.width=592; - iframe.height=665; + $(iframe).show(200); + iframeDoc.scrollTop(125); + iframeDoc.scrollLeft(145); + iframe.width=618; + iframe.height=615; }; riliLink.onmouseleave=function(){ clearTimeout(t); From e767acee94d67ab5516ff85f22bb9fa48657124c Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 28 Aug 2025 18:54:57 +0900 Subject: [PATCH 0842/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2852 +++++++++++++++++++++++++++++++++++++ 1 file changed, 2852 insertions(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 518decd7fbb..7838725e7f5 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -282,6 +282,130 @@ lastPageTips: "Show tips when reaching the last page" } }, + { + name: "한국어", + match: ["ko"], + lang: { + enableDebug: "콘솔에 디버그 출력 활성화", + updateNotification: "규칙 업데이트 후 알림", + disable: "일시적으로 비활성화", + disableSite: "비활성화 상태 전환", + disableSiteTips: "이 사이트에서 비활성화됨.", + enableSiteTips: "이 사이트에서 활성화됨.", + enable: "✅자동 페이지 넘김 활성화", + tempActive: "일시적으로 활성", + toTop: "맨 위로 이동.", + toBottom: "맨 아래로 이동.", + current: "현재 페이지.", + forceIframe: "다음 페이지 강제 결합", + cancelForceIframe: "강제 결합 취소", + configure: "Pagetual 설정", + firstUpdate: "기본 규칙 목록을 초기화하려면 여기를 클릭하세요", + update: "온라인 규칙 업데이트", + click2update: "URL에서 규칙을 지금 업데이트하려면 클릭하세요", + loadNow: "다음 페이지 자동 로드", + loadConfirm: "몇 페이지를 로드하시겠습니까? (0은 무한을 의미)", + noNext: "다음 링크를 찾을 수 없습니다. 새 규칙을 만들어 주세요", + passSec: "#t#초 전에 업데이트됨", + passMin: "#t#분 전에 업데이트됨", + passHour: "#t#시간 전에 업데이트됨", + passDay: "#t#일 전에 업데이트됨", + cantDel: "내장된 규칙은 삭제할 수 없습니다", + confirmDel: "이 규칙을 정말로 삭제하시겠습니까?", + updateSucc: "업데이트 성공", + beginUpdate: "업데이트를 시작합니다. 잠시만 기다려 주세요", + customUrls: "Pagetual 또는 AutoPagerize 규칙 URL 가져오기, 한 줄에 하나의 URL.", + customRules: "사용자 정의 규칙을 입력하세요. ✍️규칙 기여하기", + save: "저장", + loadingText: "로딩 중...", + opacity: "불투명도", + opacityPlaceholder: "0: 구분선 숨기기", + hideBar: "페이지 구분선 숨기기", + hideBarButNoStop: "숨기지만 중지하지 않음", + dbClick2Stop: "일시 중지하려면 빈 공간을 두 번 클릭하세요", + sortTitle: "정렬은 다음 규칙 업데이트 후에 적용됩니다", + autoRun: "자동 활성화 (블랙리스트 모드)", + autoLoadNum: "미리 로드할 페이지 수", + turnRate: "바닥글로부터 페이지 높이의 【X】배 미만일 때 다음 페이지로 넘기기", + inputPageNum: "이동할 페이지 번호를 입력하세요", + enableHistory: "페이지 넘김 후 방문 기록 저장", + enableHistoryAfterInsert: "페이지 결합 직후 방문 기록 저장, 그렇지 않으면 탐색 후 저장", + contentVisibility: "렌더링 성능 향상을 위해 content-visibility 자동 전환", + initRun: "페이지 열람 직후 자동 넘김 시작", + preload: "속도 향상을 위해 다음 페이지 미리 로드", + click2ImportRule: "기본 규칙 링크를 가져오려면 클릭하고 업데이트가 완료될 때까지 기다리세요: ", + forceAllBody: "페이지의 전체 본문을 결합하시겠습니까?", + openInNewTab: "추가된 URL을 새 탭에서 열기", + importSucc: "가져오기 완료", + import: "가져오기", + editCurrent: "현재 웹사이트 규칙 편집", + editBlacklist: "URL 블랙리스트 편집, 한 줄에 하나씩 입력, [?,*] 와일드카드 지원.", + upBtnImg: "맨 위로 가기 아이콘", + downBtnImg: "맨 아래로 가기 아이콘", + sideControllerIcon: "사이드바 아이콘", + loadingTextTitle: "로딩", + dbClick2StopCtrl: "Ctrl 키", + dbClick2StopAlt: "Alt 키", + dbClick2StopShift: "Shift 키", + dbClick2StopMeta: "Meta 키", + dbClick2StopKey: "단축키", + pageElementCss: "주요 페이지 요소에 대한 사용자 정의 스타일", + customCss: "사용자 정의 전체 CSS", + firstAlert: "기본 규칙을 가져오지 않았습니다. 가져올 적절한 규칙을 선택해주세요", + picker: "Pagetual 요소 선택기", + closePicker: "Pagetual 선택기 닫기", + pickerPlaceholder: "요소 선택기 (고급 사용자 전용, 그렇지 않으면 비워두세요)", + pickerCheck: "선택기 확인 및 복사", + switchSelector: "클릭하여 요소 전환", + gotoEdit: "현재 선택기로 규칙 편집하러 가기", + manualMode: "결합 비활성화, 오른쪽 화살표 키를 사용하여 수동으로 다음 페이지로 이동 (또는 'pagetual.next' 이벤트 전달)", + clickMode: "결합 비활성화, 페이지 끝까지 스크롤하면 다음 페이지 자동 클릭", + pageBarMenu: "페이지 바 중앙을 클릭하여 선택기 메뉴 열기", + nextSwitch: "다음 링크 전환", + arrowToScroll: "왼쪽 화살표를 눌러 뒤로 스크롤하고 오른쪽 화살표를 눌러 페이지 이동", + sideController: "사이드바에 페이징 제어 바 표시", + sideControllerScroll: "스크롤 시 표시/숨김", + sideControllerAlways: "항상 표시", + hideLoadingIcon: "로딩 애니메이션 숨기기", + hideBarArrow: "페이지 바 화살표 숨기기", + duplicate: "중복된 Pagetual이 설치되었습니다. 스크립트 관리자를 확인하세요!", + forceStateIframe: "전체 페이지를 iframe으로 삽입", + forceStateDynamic: "iframe을 통해 동적 콘텐츠 로드", + forceStateDisable: "이 사이트에서 페이지 넘김 비활성화", + autoScrollRate: "스크롤 속도 (1~1000)", + disableAutoScroll: "자동 스크롤 중지", + enableAutoScroll: "자동 스크롤 활성화", + toggleAutoScroll: "자동 스크롤 전환", + ruleRequest: "규칙 요청", + page: "페이지 ", + prevPage: "이전 페이지", + nextPage: "다음 페이지", + errorRulesMustBeArray: "규칙은 배열이어야 합니다!", + errorJson: "JSON 오류, 다시 확인해주세요!", + editSuccess: "성공적으로 편집되었습니다", + errorWrongUrl: "잘못된 URL, 다시 확인해주세요!", + errorAlreadyExists: "규칙이 이미 존재합니다!", + settingsSaved: "설정이 저장되었습니다. 확인하려면 새로고침하세요", + iframe: "iframe으로 강제 분할", + dynamic: "동적 로딩", + reloadPage: "편집 완료, 지금 새로고침하시겠습니까?", + copied: "복사됨", + noValidContent: "유효한 콘텐츠를 찾을 수 없습니다. 보안 문자(Captcha)가 있을 수 있습니다", + outOfDate: "스크립트가 오래되었습니다. 최신 버전으로 업데이트해주세요.", + hideBarTips: "페이지네이션 바 숨기기, 몰입형 경험 전환", + setConfigPage: "현재 페이지를 기본 설정 페이지로 지정", + wedata2github: "wedata 주소를 github 저장소의 미러 주소로 변경", + addOtherProp: "규칙 속성 추가", + addNextSelector: "선택기 콘텐츠를 nextLink로 추가", + addPageSelector: "선택기 콘텐츠를 pageElement로 추가", + propName: "규칙 속성 이름 입력", + propValue: "규칙 속성 값 입력", + customFirst: "로컬 사용자 정의 규칙 캐시 무시", + rulesExample: "규칙 예시", + lastPage: "마지막 페이지에 도달했습니다", + lastPageTips: "마지막 페이지 도달 시 팁 표시" + } + }, { name: "Deutsch", match: ["de", "de-AT", "de-CH", "de-DE", "de-LI", "de-LU"], @@ -406,6 +530,2486 @@ lastPageTips: "Tipps anzeigen, wenn die letzte Seite erreicht ist" } }, + { + name: "ไทย", + match: ["th"], + lang: { + enableDebug: "เปิดใช้งานเอาต์พุตการดีบักไปยังคอนโซล", + updateNotification: "การแจ้งเตือนหลังจากอัปเดตกฎ", + disable: "ปิดใช้งานชั่วคราว", + disableSite: "สลับสถานะการปิดใช้งาน", + disableSiteTips: "ปิดใช้งานบนไซต์นี้", + enableSiteTips: "เปิดใช้งานบนไซต์นี้", + enable: "✅เปิดใช้งานการเปลี่ยนหน้าอัตโนมัติ", + tempActive: "ใช้งานชั่วคราว", + toTop: "กลับไปด้านบน", + toBottom: "ไปที่ด้านล่าง", + current: "หน้าปัจจุบัน", + forceIframe: "บังคับให้เข้าร่วมหน้าถัดไป", + cancelForceIframe: "ยกเลิกการเข้าร่วมบังคับ", + configure: "กำหนดค่า Pagetual", + firstUpdate: "คลิกที่นี่เพื่อเริ่มต้นรายการกฎเริ่มต้น", + update: "อัปเดตกฎออนไลน์", + click2update: "คลิกเพื่ออัปเดตกฎจาก url ทันที", + loadNow: "โหลดหน้าถัดไปโดยอัตโนมัติ", + loadConfirm: "คุณต้องการโหลดกี่หน้า (0 หมายถึงไม่สิ้นสุด)", + noNext: "ไม่พบลิงก์ถัดไป โปรดสร้างกฎใหม่", + passSec: "อัปเดตเมื่อ #t# วินาทีที่แล้ว", + passMin: "อัปเดตเมื่อ #t# นาทีที่แล้ว", + passHour: "อัปเดตเมื่อ #t# ชั่วโมงที่แล้ว", + passDay: "อัปเดตเมื่อ #t# วันที่แล้ว", + cantDel: "ไม่สามารถลบกฎในตัวได้", + confirmDel: "คุณแน่ใจหรือไม่ว่าต้องการลบกฎนี้", + updateSucc: "อัปเดตสำเร็จ", + beginUpdate: "เริ่มอัปเดต โปรดรอสักครู่", + customUrls: "นำเข้า URL กฎ Pagetual หรือ AutoPagerize หนึ่ง URL ต่อบรรทัด", + customRules: "ป้อนกฎที่กำหนดเอง ✍️มีส่วนร่วมในกฎ", + save: "บันทึก", + loadingText: "กำลังโหลด...", + opacity: "ความทึบ", + opacityPlaceholder: "0: ซ่อนตัวเว้นวรรค", + hideBar: "ซ่อนตัวเว้นวรรคของหน้า", + hideBarButNoStop: "ซ่อนแต่ไม่หยุด", + dbClick2Stop: "ดับเบิลคลิกที่พื้นที่ว่างเพื่อหยุดชั่วคราว", + sortTitle: "การเรียงลำดับจะมีผลหลังจากการอัปเดตกฎครั้งถัดไป", + autoRun: "เปิดใช้งานอัตโนมัติ (โหมดบัญชีดำ)", + autoLoadNum: "จำนวนหน้าที่โหลดล่วงหน้า", + turnRate: "เปลี่ยนหน้าถัดไปเมื่ออยู่ห่างจากส่วนท้ายน้อยกว่า【X】เท่าของความสูงของหน้า", + inputPageNum: "ป้อนหมายเลขหน้าเพื่อข้ามไป", + enableHistory: "เขียนประวัติการเข้าชมหลังจากการเปลี่ยนหน้า", + enableHistoryAfterInsert: "เขียนประวัติการเข้าชมทันทีหลังจากต่อเข้าด้วยกัน มิฉะนั้นจะเขียนหลังจากการเข้าชม", + contentVisibility: "สลับ content-visibility โดยอัตโนมัติเพื่อปรับปรุงประสิทธิภาพการเรนเดอร์", + initRun: "เปลี่ยนหน้าทันทีหลังจากเปิด", + preload: "โหลดหน้าถัดไปล่วงหน้าเพื่อเพิ่มความเร็ว", + click2ImportRule: "คลิกเพื่อนำเข้าลิงก์กฎพื้นฐาน แล้วรอจนกว่าการอัปเดตจะเสร็จสมบูรณ์: ", + forceAllBody: "เข้าร่วมเนื้อหาทั้งหมดของหน้าหรือไม่", + openInNewTab: "เปิด URL ของส่วนเพิ่มเติมในแท็บใหม่", + importSucc: "นำเข้าสำเร็จ", + import: "นำเข้า", + editCurrent: "แก้ไขกฎสำหรับเว็บไซต์ปัจจุบัน", + editBlacklist: "แก้ไขบัญชีดำของ URL หนึ่งรายการต่อบรรทัด รองรับ [?,*] wildcards", + upBtnImg: "ไอคอนกลับไปด้านบน", + downBtnImg: "ไอคอนไปที่ส่วนท้าย", + sideControllerIcon: "ไอคอนของแถบด้านข้าง", + loadingTextTitle: "กำลังโหลด", + dbClick2StopCtrl: "ปุ่ม Ctrl", + dbClick2StopAlt: "ปุ่ม Alt", + dbClick2StopShift: "ปุ่ม Shift", + dbClick2StopMeta: "ปุ่ม Meta", + dbClick2StopKey: "ปุ่มลัด", + pageElementCss: "สไตล์ที่กำหนดเองสำหรับองค์ประกอบหน้าหลัก", + customCss: "CSS ที่กำหนดเองทั้งหมด", + firstAlert: "คุณยังไม่ได้นำเข้ากฎพื้นฐาน โปรดเลือกกฎที่เหมาะสมเพื่อนำเข้า", + picker: "ตัวเลือกองค์ประกอบ Pagetual", + closePicker: "ปิดตัวเลือก Pagetual", + pickerPlaceholder: "ตัวเลือกองค์ประกอบ (สำหรับผู้ใช้ขั้นสูงเท่านั้น เว้นว่างไว้)", + pickerCheck: "ตรวจสอบตัวเลือกและคัดลอก", + switchSelector: "คลิกเพื่อสลับองค์ประกอบ", + gotoEdit: "ไปที่การแก้ไขกฎด้วยตัวเลือกปัจจุบัน", + manualMode: "ปิดใช้งานการต่อเข้าด้วยกัน เลื่อนหน้าถัดไปด้วยตนเองโดยใช้ปุ่มลูกศรขวา (หรือส่งเหตุการณ์ 'pagetual.next')", + clickMode: "ปิดใช้งานการต่อเข้าด้วยกัน คลิกหน้าถัดไปโดยอัตโนมัติเมื่อเลื่อนไปที่ท้ายหน้า", + pageBarMenu: "คลิกที่กึ่งกลางของแถบหน้าเพื่อเปิดเมนูตัวเลือก", + nextSwitch: "สลับลิงก์ถัดไป", + arrowToScroll: "กดลูกศรซ้ายเพื่อเลื่อนกลับและลูกศรขวาเพื่อเลื่อนหน้า", + sideController: "แสดงแถบควบคุมการแบ่งหน้าในแถบด้านข้าง", + sideControllerScroll: "สลับการเลื่อน", + sideControllerAlways: "แสดงเสมอ", + hideLoadingIcon: "ซ่อนภาพเคลื่อนไหวการโหลด", + hideBarArrow: "ซ่อนลูกศรสำหรับแถบหน้า", + duplicate: "มีการติดตั้ง Pagetual ที่ซ้ำกัน ตรวจสอบผู้จัดการสคริปต์ของคุณ!", + forceStateIframe: "ฝังหน้าเต็มเป็น iframe", + forceStateDynamic: "โหลดเนื้อหาแบบไดนามิกผ่าน iframe", + forceStateDisable: "ปิดใช้งานการเปลี่ยนหน้าบนไซต์นี้", + autoScrollRate: "ความเร็วในการเลื่อน (1~1000)", + disableAutoScroll: "หยุดการเลื่อนอัตโนมัติ", + enableAutoScroll: "เปิดใช้งานการเลื่อนอัตโนมัติ", + toggleAutoScroll: "สลับการเลื่อนอัตโนมัติ", + ruleRequest: "ขอกฎ", + page: "หน้า ", + prevPage: "หน้าก่อนหน้า", + nextPage: "หน้าถัดไป", + errorRulesMustBeArray: "กฎต้องเป็นอาร์เรย์!", + errorJson: "ข้อผิดพลาด JSON ตรวจสอบอีกครั้ง!", + editSuccess: "แก้ไขสำเร็จ", + errorWrongUrl: "URL ไม่ถูกต้อง ตรวจสอบอีกครั้ง!", + errorAlreadyExists: "มีกฎอยู่แล้ว!", + settingsSaved: "บันทึกการตั้งค่าแล้ว รีเฟรชเพื่อดู", + iframe: "บังคับแยกโดย iframe", + dynamic: "การโหลดแบบไดนามิก", + reloadPage: "แก้ไขเสร็จแล้ว โหลดใหม่ตอนนี้หรือไม่", + copied: "คัดลอกแล้ว", + noValidContent: "ไม่พบเนื้อหาที่ถูกต้อง อาจมี Captcha", + outOfDate: "สคริปต์ล้าสมัย โปรดอัปเดตเป็นเวอร์ชันล่าสุด", + hideBarTips: "ซ่อนแถบเลขหน้า สลับประสบการณ์ที่สมจริง", + setConfigPage: "ตั้งค่าหน้าปัจจุบันเป็นหน้าการกำหนดค่าเริ่มต้น", + wedata2github: "เปลี่ยนที่อยู่ wedata เป็นที่อยู่มิเรอร์ในที่เก็บ github", + addOtherProp: "เพิ่มคุณสมบัติของกฎ", + addNextSelector: "เพิ่มเนื้อหาตัวเลือกเป็น nextLink", + addPageSelector: "เพิ่มเนื้อหาตัวเลือกเป็น pageElement", + propName: "ป้อนชื่อคุณสมบัติของกฎ", + propValue: "ป้อนค่าคุณสมบัติของกฎ", + customFirst: "ไม่สนใจแคชสำหรับกฎที่กำหนดเองในเครื่อง", + rulesExample: "ตัวอย่างกฎ", + lastPage: "ถึงหน้าสุดท้ายแล้ว", + lastPageTips: "แสดงเคล็ดลับเมื่อถึงหน้าสุดท้าย" + } + }, + { + name: "Norsk (Bokmål)", + match: ["nb", "nb-NO"], + lang: { + enableDebug: "Aktiver feilsøkingsutdata til konsollen", + updateNotification: "Varsling etter at regler er oppdatert", + disable: "Deaktiver midlertidig", + disableSite: "Veksle deaktivert tilstand", + disableSiteTips: "Deaktivert på dette nettstedet.", + enableSiteTips: "Aktivert på dette nettstedet.", + enable: "✅Aktiver automatisk sidevending", + tempActive: "Midlertidig aktiv", + toTop: "Tilbake til toppen.", + toBottom: "Gå til bunnen.", + current: "Gjeldende side.", + forceIframe: "Tving til å koble til neste side", + cancelForceIframe: "Avbryt tvungen tilkobling", + configure: "Konfigurer Pagetual", + firstUpdate: "Klikk her for å initialisere standard regelliste", + update: "Oppdater nettbaserte regler", + click2update: "Klikk for å oppdatere regler fra url nå", + loadNow: "Last neste automatisk", + loadConfirm: "Hvor mange sider vil du laste? (0 betyr uendelig)", + noNext: "Ingen neste lenke funnet, vennligst opprett en ny regel", + passSec: "Oppdatert for #t# sekunder siden", + passMin: "Oppdatert for #t# minutter siden", + passHour: "Oppdatert for #t# timer siden", + passDay: "Oppdatert for #t# dager siden", + cantDel: "Kan ikke slette innebygde regler", + confirmDel: "Er du sikker på at du vil slette denne regelen?", + updateSucc: "Oppdatering vellykket", + beginUpdate: "Starter oppdatering, vent et øyeblikk", + customUrls: "Importer Pagetual eller AutoPagerize regel-url, én url per linje.", + customRules: "Skriv inn egendefinerte regler. ✍️Bidra med regler", + save: "Lagre", + loadingText: "Laster nå...", + opacity: "Opasitet", + opacityPlaceholder: "0: skjul avstandsstykke", + hideBar: "Skjul pagineringsavstandsstykket", + hideBarButNoStop: "Skjul, men ikke stopp", + dbClick2Stop: "Dobbeltklikk på det tomme området for å pause", + sortTitle: "Sortering trer i kraft etter neste regeloppdatering", + autoRun: "Auto-aktiver (svartelistemodus)", + autoLoadNum: "Antall for forhåndslastede sider", + turnRate: "Snu til neste side når det er mindre enn 【X】 ganger sidehøyden fra bunnteksten", + inputPageNum: "Skriv inn sidetall for å hoppe", + enableHistory: "Skriv nettleserlogg etter sidevending", + enableHistoryAfterInsert: "Skriv nettleserlogg umiddelbart etter spleising, ellers skriv etter surfing", + contentVisibility: "Bytt automatisk innholdssynlighet for å forbedre gjengivelsesytelsen", + initRun: "Snu sider umiddelbart etter åpning", + preload: "Forhåndslast neste side for å øke hastigheten", + click2ImportRule: "Klikk for å importere grunnregellenke, og vent deretter til oppdateringen er fullført: ", + forceAllBody: "Koble til hele sidens kropp?", + openInNewTab: "Åpne url-er for tillegg i ny fane", + importSucc: "Import fullført", + import: "Importer", + editCurrent: "Rediger regel for gjeldende nettsted", + editBlacklist: "Rediger url-svartelisten, én oppføring per linje, støtter [?,*] jokertegn.", + upBtnImg: "Ikon for tilbake til toppen", + downBtnImg: "Ikon for å gå til bunntekst", + sideControllerIcon: "Ikon for sidefelt", + loadingTextTitle: "Laster", + dbClick2StopCtrl: "Ctrl-tast", + dbClick2StopAlt: "Alt-tast", + dbClick2StopShift: "Shift-tast", + dbClick2StopMeta: "Meta-tast", + dbClick2StopKey: "Hurtigtast", + pageElementCss: "Egendefinert stil for hovedsideelementer", + customCss: "Egendefinert komplett css", + firstAlert: "Du har ikke importert grunnregelen, vennligst velg riktig regel å importere", + picker: "Pagetual elementvelger", + closePicker: "Lukk Pagetual-velger", + pickerPlaceholder: "Elementvelger, (Kun avanserte brukere, la stå tomt ellers)", + pickerCheck: "Sjekk velger og kopier", + switchSelector: "Klikk for å bytte element", + gotoEdit: "Gå til redigeringsregel med gjeldende velger", + manualMode: "Deaktiver spleising, gå manuelt frem til neste side med høyre piltast (eller send hendelsen 'pagetual.next')", + clickMode: "Deaktiver spleising, klikk automatisk på neste side når du ruller til slutten av siden", + pageBarMenu: "Klikk på midten av sidelinjen for å åpne velgermenyen", + nextSwitch: "Bytt neste lenke", + arrowToScroll: "Trykk venstre piltast for å rulle tilbake og høyre piltast for å gå frem en side", + sideController: "Vis pagineringskontrollinjen i sidefeltet", + sideControllerScroll: "Rulleveksling", + sideControllerAlways: "Vis alltid", + hideLoadingIcon: "Skjul lasteanimasjon", + hideBarArrow: "Skjul pil for sidelinje", + duplicate: "Duplikat Pagetual har blitt installert, sjekk skriptbehandleren din!", + forceStateIframe: "Bygg inn hele siden som iframe", + forceStateDynamic: "Last dynamisk innhold via iframe", + forceStateDisable: "Deaktiver sidevending på dette nettstedet", + autoScrollRate: "Rullehastighet (1~1000)", + disableAutoScroll: "Stopp automatisk rulling", + enableAutoScroll: "Aktiver automatisk rulling", + toggleAutoScroll: "Veksle automatisk rulling", + ruleRequest: "Regelforespørsel", + page: "Side ", + prevPage: "Forrige side", + nextPage: "Neste side", + errorRulesMustBeArray: "Regler må være en matrise!", + errorJson: "JSON-feil, sjekk igjen!", + editSuccess: "Redigering vellykket", + errorWrongUrl: "Feil url, sjekk igjen!", + errorAlreadyExists: "En regel eksisterer allerede!", + settingsSaved: "Innstillingene er lagret, oppdater for å se", + iframe: "Tvunget delt av iframe", + dynamic: "Dynamisk lasting", + reloadPage: "Redigering fullført, last på nytt nå?", + copied: "Kopiert", + noValidContent: "Ingen gyldig innhold funnet, en Captcha kan være til stede", + outOfDate: "Skriptet er utdatert, vennligst oppdater til den nyeste versjonen.", + hideBarTips: "Skjul pagineringslinjen, veksle mellom oppslukende opplevelse", + setConfigPage: "Angi gjeldende side som standard konfigurasjonsside", + wedata2github: "Endre wedata-adressen til speiladressen i github-depotet", + addOtherProp: "Legg til regelegenskaper", + addNextSelector: "Legg til velgerinnhold som nextLink", + addPageSelector: "Legg til velgerinnhold som pageElement", + propName: "Skriv inn regelegenskapsnavn", + propValue: "Skriv inn regelegenskapsverdi", + customFirst: "Ignorer hurtigbuffer for lokale egendefinerte regler", + rulesExample: "Regeleksempel", + lastPage: "Nådde den siste siden", + lastPageTips: "Vis tips når du når den siste siden" + } + }, + { + name: "Svenska", + match: ["sv"], + lang: { + enableDebug: "Aktivera felsökningsutdata till konsolen", + updateNotification: "Meddelande efter att regler har uppdaterats", + disable: "Inaktivera tillfälligt", + disableSite: "Växla inaktiverat läge", + disableSiteTips: "Inaktiverad på denna webbplats.", + enableSiteTips: "Aktiverad på denna webbplats.", + enable: "✅Aktivera automatisk sidvändning", + tempActive: "Tillfälligt aktiv", + toTop: "Tillbaka till toppen.", + toBottom: "Gå till botten.", + current: "Nuvarande sida.", + forceIframe: "Tvinga att ansluta till nästa sida", + cancelForceIframe: "Avbryt tvångsanslutning", + configure: "Konfigurera Pagetual", + firstUpdate: "Klicka här för att initiera standardregellistan", + update: "Uppdatera onlineregler", + click2update: "Klicka för att uppdatera regler från url nu", + loadNow: "Ladda nästa automatiskt", + loadConfirm: "Hur många sidor vill du ladda? (0 betyder oändligt)", + noNext: "Ingen nästa länk hittades, skapa en ny regel", + passSec: "Uppdaterad för #t# sekunder sedan", + passMin: "Uppdaterad för #t# minuter sedan", + passHour: "Uppdaterad för #t# timmar sedan", + passDay: "Uppdaterad för #t# dagar sedan", + cantDel: "Kan inte ta bort inbyggda regler", + confirmDel: "Är du säker på att du vill ta bort denna regel?", + updateSucc: "Uppdatering lyckades", + beginUpdate: "Påbörjar uppdatering, vänta ett ögonblick", + customUrls: "Importera Pagetual eller AutoPagerize regel-url, en url per rad.", + customRules: "Ange anpassade regler. ✍️Bidra med regler", + save: "Spara", + loadingText: "Laddar nu...", + opacity: "Opacitet", + opacityPlaceholder: "0: dölj mellanrum", + hideBar: "Dölj pagineringsmellanrummet", + hideBarButNoStop: "Dölj men stoppa inte", + dbClick2Stop: "Dubbelklicka på det tomma utrymmet för att pausa", + sortTitle: "Sortering träder i kraft efter nästa regeluppdatering", + autoRun: "Auto-aktivera (svartlistningsläge)", + autoLoadNum: "Antal för förinläsning av sidor", + turnRate: "Vänd till nästa sida när det är mindre än 【X】 gånger sidhöjden från sidfoten", + inputPageNum: "Ange sidnummer för att hoppa", + enableHistory: "Skriv webbhistorik efter sidvändning", + enableHistoryAfterInsert: "Skriv webbhistorik omedelbart efter sammanfogning, annars skriv efter surfning", + contentVisibility: "Växla automatiskt innehållssynlighet för att förbättra renderingsprestanda", + initRun: "Vänd sidor omedelbart efter öppning", + preload: "Förinläs nästa sida för att påskynda", + click2ImportRule: "Klicka för att importera grundregellänk, och vänta sedan tills uppdateringen är klar: ", + forceAllBody: "Anslut hela sidans kropp?", + openInNewTab: "Öppna webbadresser för tillägg i ny flik", + importSucc: "Importen är klar", + import: "Importera", + editCurrent: "Redigera regel för aktuell webbplats", + editBlacklist: "Redigera webbadress-svartlistan, en post per rad, stöder [?,*] jokertecken.", + upBtnImg: "Ikon för tillbaka till toppen", + downBtnImg: "Ikon för att gå till sidfot", + sideControllerIcon: "Ikon för sidofältet", + loadingTextTitle: "Laddar", + dbClick2StopCtrl: "Ctrl-tangent", + dbClick2StopAlt: "Alt-tangent", + dbClick2StopShift: "Shift-tangent", + dbClick2StopMeta: "Meta-tangent", + dbClick2StopKey: "Snabbtangent", + pageElementCss: "Anpassad stil för huvudsidaelement", + customCss: "Anpassad komplett css", + firstAlert: "Du har inte importerat grundregeln, välj lämplig regel att importera", + picker: "Pagetual elementväljare", + closePicker: "Stäng Pagetual-väljare", + pickerPlaceholder: "Elementväljare, (Endast avancerade användare, lämna tomt annars)", + pickerCheck: "Kontrollera väljare och kopiera", + switchSelector: "Klicka för att byta element", + gotoEdit: "Gå till redigera regel med aktuell väljare", + manualMode: "Inaktivera sammanfogning, gå manuellt framåt till nästa sida med höger piltangent (eller skicka händelsen 'pagetual.next')", + clickMode: "Inaktivera sammanfogning, klicka automatiskt på nästa sida när du rullar till slutet av sidan", + pageBarMenu: "Klicka på mitten av sidfältet för att öppna väljarmenyn", + nextSwitch: "Byt nästa länk", + arrowToScroll: "Tryck på vänster piltangent för att rulla tillbaka och höger piltangent för att gå fram en sida", + sideController: "Visa pagineringskontrollfältet i sidofältet", + sideControllerScroll: "Rullningsväxling", + sideControllerAlways: "Visa alltid", + hideLoadingIcon: "Dölj laddningsanimation", + hideBarArrow: "Dölj pil för sidfält", + duplicate: "Duplicerad Pagetual har installerats, kontrollera din skripthanterare!", + forceStateIframe: "Bädda in hela sidan som iframe", + forceStateDynamic: "Ladda dynamiskt innehåll via iframe", + forceStateDisable: "Inaktivera sidvändning på denna webbplats", + autoScrollRate: "Rullningshastighet (1~1000)", + disableAutoScroll: "Stoppa automatisk rullning", + enableAutoScroll: "Aktivera automatisk rullning", + toggleAutoScroll: "Växla automatisk rullning", + ruleRequest: "Regelförfrågan", + page: "Sida ", + prevPage: "Föregående sida", + nextPage: "Nästa sida", + errorRulesMustBeArray: "Regler måste vara en array!", + errorJson: "JSON-fel, kontrollera igen!", + editSuccess: "Redigering lyckades", + errorWrongUrl: "Fel webbadress, kontrollera igen!", + errorAlreadyExists: "En regel finns redan!", + settingsSaved: "Inställningarna har sparats, uppdatera för att se", + iframe: "Tvingad delning av iframe", + dynamic: "Dynamisk laddning", + reloadPage: "Redigering slutförd, ladda om nu?", + copied: "Kopierad", + noValidContent: "Inget giltigt innehåll hittades, en Captcha kan finnas", + outOfDate: "Skriptet är föråldrat, uppdatera till den senaste versionen.", + hideBarTips: "Dölj pagineringsfältet, växla till en uppslukande upplevelse", + setConfigPage: "Ange aktuell sida som standardkonfigurationssida", + wedata2github: "Ändra wedata-adressen till spegeladressen i github-förvaret", + addOtherProp: "Lägg till regelegenskaper", + addNextSelector: "Lägg till väljarinnehåll som nextLink", + addPageSelector: "Lägg till väljarinnehåll som pageElement", + propName: "Ange regelegenskapsnamn", + propValue: "Ange regelegenskapsvärde", + customFirst: "Ignorera cache för lokala anpassade regler", + rulesExample: "Regelexempel", + lastPage: "Nådde sista sidan", + lastPageTips: "Visa tips när du når sista sidan" + } + }, + { + name: "Српски", + match: ["sr"], + lang: { + enableDebug: "Омогући отклањање грешака на конзоли", + updateNotification: "Обавештење након ажурирања правила", + disable: "Привремено онемогући", + disableSite: "Промени стање онемогућености", + disableSiteTips: "Онемогућено на овом сајту.", + enableSiteTips: "Омогућено на овом сајту.", + enable: "✅Омогући аутоматско окретање страница", + tempActive: "Привремено активно", + toTop: "Назад на врх.", + toBottom: "Иди на дно.", + current: "Тренутна страница.", + forceIframe: "Присили спајање следеће странице", + cancelForceIframe: "Откажи присилно спајање", + configure: "Конфигуриши Pagetual", + firstUpdate: "Кликните овде да бисте покренули подразумевану листу правила", + update: "Ажурирај правила на мрежи", + click2update: "Кликните да бисте одмах ажурирали правила са УРЛ-а", + loadNow: "Учитај следеће аутоматски", + loadConfirm: "Колико страница желите да учитате? (0 значи бесконачно)", + noNext: "Није пронађена следећа веза, креирајте ново правило", + passSec: "Ажурирано пре #t# секунди", + passMin: "Ажурирано пре #t# минута", + passHour: "Ажурирано пре #t# сати", + passDay: "Ажурирано пре #t# дана", + cantDel: "Не могу се избрисати уграђена правила", + confirmDel: "Да ли сте сигурни да желите да избришете ово правило?", + updateSucc: "Ажурирање је успело", + beginUpdate: "Започни ажурирање, сачекајте тренутак", + customUrls: "Увезите Pagetual или AutoPagerize УРЛ правила, један УРЛ по линији.", + customRules: "Унесите прилагођена правила. ✍️Допринесите правилима", + save: "Сачувај", + loadingText: "Учитавање у току...", + opacity: "Провидност", + opacityPlaceholder: "0: сакриј размак", + hideBar: "Сакриј размак за пагинацију", + hideBarButNoStop: "Сакриј, али не заустављај", + dbClick2Stop: "Двапут кликните на празан простор да бисте паузирали", + sortTitle: "Сортирање ступа на снагу након следећег ажурирања правила", + autoRun: "Аутоматско омогућавање (режим црне листе)", + autoLoadNum: "Количина за унапред учитане странице", + turnRate: "Окрените следећу страницу када је мање од 【X】 пута висине странице од подножја", + inputPageNum: "Унесите број странице за скок", + enableHistory: "Упиши историју прегледања након окретања странице", + enableHistoryAfterInsert: "Упиши историју прегледања одмах након спајања, у супротном упиши након прегледања", + contentVisibility: "Аутоматски промени видљивост садржаја да би се побољшале перформансе приказивања", + initRun: "Окрени странице одмах након отварања", + preload: "Унапред учитај следећу страницу ради убрзања", + click2ImportRule: "Кликните да бисте увезли везу основних правила, а затим сачекајте док се ажурирање не заврши: ", + forceAllBody: "Спојити цело тело странице?", + openInNewTab: "Отвори УРЛ-ове додатака у новој картици", + importSucc: "Увоз је завршен", + import: "Увези", + editCurrent: "Уреди правило за тренутни веб-сајт", + editBlacklist: "Уредите УРЛ црну листу, један унос по линији, подржава џокере [?,*].", + upBtnImg: "Икона за повратак на врх", + downBtnImg: "Икона за одлазак на подножје", + sideControllerIcon: "Икона бочне траке", + loadingTextTitle: "Учитавање", + dbClick2StopCtrl: "Тастер Ctrl", + dbClick2StopAlt: "Тастер Alt", + dbClick2StopShift: "Тастер Shift", + dbClick2StopMeta: "Тастер Meta", + dbClick2StopKey: "Тастер пречице", + pageElementCss: "Прилагођени стил за главне елементе странице", + customCss: "Прилагођени комплетан ЦСС", + firstAlert: "Нисте увезли основно правило, изаберите одговарајуће правило за увоз", + picker: "Pagetual бирач елемената", + closePicker: "Затвори Pagetual бирач", + pickerPlaceholder: "Бирач елемената, (Само напредни корисници, иначе оставите празно)", + pickerCheck: "Провери бирач и копирај", + switchSelector: "Кликните да бисте променили елемент", + gotoEdit: "Иди на уређивање правила са тренутним бирачем", + manualMode: "Онемогући спајање, ручно пређи на следећу страницу помоћу десног тастера са стрелицом (или пошаљи догађај 'pagetual.next')", + clickMode: "Онемогући спајање, аутоматски кликни на следећу страницу приликом померања до краја странице", + pageBarMenu: "Кликните на центар траке странице да бисте отворили мени бирача", + nextSwitch: "Промени следећу везу", + arrowToScroll: "Притисните леви тастер са стрелицом за померање уназад и десни тастер са стрелицом за прелазак на страницу", + sideController: "Прикажи контролну траку за пагинацију у бочној траци", + sideControllerScroll: "Промена померања", + sideControllerAlways: "Увек прикажи", + hideLoadingIcon: "Сакриј анимацију учитавања", + hideBarArrow: "Сакриј стрелицу за траку странице", + duplicate: "Дупликат Pagetual је инсталиран, проверите свој менаџер скрипти!", + forceStateIframe: "Угради целу страницу као iframe", + forceStateDynamic: "Учитај динамички садржај путем iframe-a", + forceStateDisable: "Онемогући окретање страница на овом сајту", + autoScrollRate: "Брзина померања (1~1000)", + disableAutoScroll: "Заустави аутоматско померање", + enableAutoScroll: "Омогући аутоматско померање", + toggleAutoScroll: "Промени аутоматско померање", + ruleRequest: "Захтев за правило", + page: "Страница ", + prevPage: "Претходна страница", + nextPage: "Следећа страница", + errorRulesMustBeArray: "Правила морају бити низ!", + errorJson: "ЈСОН грешка, проверите поново!", + editSuccess: "Успешно уређено", + errorWrongUrl: "Погрешан УРЛ, проверите поново!", + errorAlreadyExists: "Правило већ постоји!", + settingsSaved: "Подешавања су сачувана, освежите да бисте видели", + iframe: "Присилно подељено iframe-ом", + dynamic: "Динамичко учитавање", + reloadPage: "Уређивање је завршено, поново учитати сада?", + copied: "Копирано", + noValidContent: "Није детектован важећи садржај, можда је присутан Цаптцха", + outOfDate: "Скрипта је застарела, ажурирајте на најновију верзију.", + hideBarTips: "Сакријте траку за пагинацију, промените имерзивно искуство", + setConfigPage: "Постави тренутну страницу као подразумевану страницу за конфигурацију", + wedata2github: "Промените wedata адресу на адресу огледала у гитхуб спремишту", + addOtherProp: "Додај својства правила", + addNextSelector: "Додај садржај бирача као nextLink", + addPageSelector: "Додај садржај бирача као pageElement", + propName: "Унесите назив својства правила", + propValue: "Унесите вредност својства правила", + customFirst: "Игнориши кеш за локална прилагођена правила", + rulesExample: "Пример правила", + lastPage: "Достигнута је последња страница", + lastPageTips: "Прикажи савете приликом достизања последње странице" + } + }, + { + name: "Slovenčina", + match: ["sk"], + lang: { + enableDebug: "Povoliť výstup ladenia do konzoly", + updateNotification: "Oznámenie po aktualizácii pravidiel", + disable: "Dočasne zakázať", + disableSite: "Prepnúť stav zakázania", + disableSiteTips: "Na tejto stránke zakázané.", + enableSiteTips: "Na tejto stránke povolené.", + enable: "✅Povoliť automatické otáčanie stránok", + tempActive: "Dočasne aktívne", + toTop: "Späť na začiatok.", + toBottom: "Ísť na koniec.", + current: "Aktuálna stránka.", + forceIframe: "Vynútiť pripojenie k ďalšej stránke", + cancelForceIframe: "Zrušiť vynútené pripojenie", + configure: "Konfigurovať Pagetual", + firstUpdate: "Kliknite sem pre inicializáciu predvoleného zoznamu pravidiel", + update: "Aktualizovať online pravidlá", + click2update: "Kliknite pre aktualizáciu pravidiel z URL teraz", + loadNow: "Načítať ďalšie automaticky", + loadConfirm: "Koľko stránok chcete načítať? (0 znamená nekonečno)", + noNext: "Nenašiel sa žiadny ďalší odkaz, vytvorte nové pravidlo", + passSec: "Aktualizované pred #t# sekundami", + passMin: "Aktualizované pred #t# minútami", + passHour: "Aktualizované pred #t# hodinami", + passDay: "Aktualizované pred #t# dňami", + cantDel: "Nie je možné odstrániť vstavané pravidlá", + confirmDel: "Ste si istí, že chcete odstrániť toto pravidlo?", + updateSucc: "Aktualizácia úspešná", + beginUpdate: "Začína sa aktualizácia, chvíľu počkajte", + customUrls: "Importovať URL pravidla Pagetual alebo AutoPagerize, jedno URL na riadok.", + customRules: "Zadajte vlastné pravidlá. ✍️Prispieť pravidlami", + save: "Uložiť", + loadingText: "Načítava sa...", + opacity: "Nepriehľadnosť", + opacityPlaceholder: "0: skryť medzerník", + hideBar: "Skryť medzerník stránkovania", + hideBarButNoStop: "Skryť, ale nezastaviť", + dbClick2Stop: "Dvojitým kliknutím na prázdne miesto pozastavíte", + sortTitle: "Triedenie sa prejaví po ďalšej aktualizácii pravidiel", + autoRun: "Automatické povolenie (režim čiernej listiny)", + autoLoadNum: "Množstvo pre prednačítané stránky", + turnRate: "Otočte na ďalšiu stránku, keď je menej ako 【X】 násobok výšky stránky od pätičky", + inputPageNum: "Zadajte číslo stránky na preskočenie", + enableHistory: "Zapísať históriu prehliadania po otočení stránky", + enableHistoryAfterInsert: "Zapísať históriu prehliadania ihneď po spojení, inak zapísať po prehliadaní", + contentVisibility: "Automaticky prepínať viditeľnosť obsahu na zlepšenie výkonu vykresľovania", + initRun: "Otočiť stránky ihneď po otvorení", + preload: "Prednačítať ďalšiu stránku na zrýchlenie", + click2ImportRule: "Kliknite pre import odkazu na základné pravidlá a potom počkajte, kým sa aktualizácia nedokončí: ", + forceAllBody: "Pripojiť celé telo stránky?", + openInNewTab: "Otvoriť URL adries prídavkov v novej karte", + importSucc: "Import dokončený", + import: "Importovať", + editCurrent: "Upraviť pravidlo pre aktuálnu webovú stránku", + editBlacklist: "Upraviť čiernu listinu URL, jeden záznam na riadok, podporuje zástupné znaky [?,*].", + upBtnImg: "Ikona späť na začiatok", + downBtnImg: "Ikona ísť na pätičku", + sideControllerIcon: "Ikona bočného panela", + loadingTextTitle: "Načítavanie", + dbClick2StopCtrl: "Kláves Ctrl", + dbClick2StopAlt: "Kláves Alt", + dbClick2StopShift: "Kláves Shift", + dbClick2StopMeta: "Kláves Meta", + dbClick2StopKey: "Klávesová skratka", + pageElementCss: "Vlastný štýl pre hlavné prvky stránky", + customCss: "Vlastné kompletné CSS", + firstAlert: "Neimportovali ste základné pravidlo, vyberte prosím vhodné pravidlo na import", + picker: "Výber prvkov Pagetual", + closePicker: "Zavrieť výber Pagetual", + pickerPlaceholder: "Výber prvkov, (Iba pre pokročilých používateľov, inak nechajte prázdne)", + pickerCheck: "Skontrolovať výber a kopírovať", + switchSelector: "Kliknutím prepnete prvok", + gotoEdit: "Prejsť na úpravu pravidla s aktuálnym výberom", + manualMode: "Zakázať spájanie, manuálne prejsť na ďalšiu stránku pomocou klávesu so šípkou doprava (alebo odoslať udalosť 'pagetual.next')", + clickMode: "Zakázať spájanie, automaticky kliknúť na ďalšiu stránku pri posunutí na koniec stránky", + pageBarMenu: "Kliknutím na stred lišty stránky otvoríte menu výberu", + nextSwitch: "Prepnúť ďalší odkaz", + arrowToScroll: "Stlačením ľavej šípky sa posuniete späť a pravou šípkou prejdete na stránku", + sideController: "Zobraziť ovládací panel stránkovania v bočnom paneli", + sideControllerScroll: "Prepnúť posúvanie", + sideControllerAlways: "Vždy zobraziť", + hideLoadingIcon: "Skryť animáciu načítavania", + hideBarArrow: "Skryť šípku pre lištu stránky", + duplicate: "Duplicitný Pagetual bol nainštalovaný, skontrolujte svoj správcu skriptov!", + forceStateIframe: "Vložiť celú stránku ako iframe", + forceStateDynamic: "Načítať dynamický obsah cez iframe", + forceStateDisable: "Zakázať otáčanie stránok na tejto stránke", + autoScrollRate: "Rýchlosť posúvania (1~1000)", + disableAutoScroll: "Zastaviť automatické posúvanie", + enableAutoScroll: "Povoliť automatické posúvanie", + toggleAutoScroll: "Prepnúť automatické posúvanie", + ruleRequest: "Žiadosť o pravidlo", + page: "Stránka ", + prevPage: "Predchádzajúca stránka", + nextPage: "Ďalšia stránka", + errorRulesMustBeArray: "Pravidlá musia byť pole!", + errorJson: "Chyba JSON, skontrolujte znova!", + editSuccess: "Úspešne upravené", + errorWrongUrl: "Nesprávne URL, skontrolujte znova!", + errorAlreadyExists: "Pravidlo už existuje!", + settingsSaved: "Nastavenia sú uložené, obnovte pre zobrazenie", + iframe: "Vynútené rozdelenie pomocou iframe", + dynamic: "Dynamické načítavanie", + reloadPage: "Úprava dokončená, načítať znova?", + copied: "Skopírované", + noValidContent: "Nebol zistený žiadny platný obsah, môže byť prítomná Captcha", + outOfDate: "Skript je zastaraný, aktualizujte prosím na najnovšiu verziu.", + hideBarTips: "Skryť lištu stránkovania, prepnúť pohlcujúci zážitok", + setConfigPage: "Nastaviť aktuálnu stránku ako predvolenú konfiguračnú stránku", + wedata2github: "Zmeniť adresu wedata na zrkadlovú adresu v repozitári github", + addOtherProp: "Pridať vlastnosti pravidla", + addNextSelector: "Pridať obsah výberu ako nextLink", + addPageSelector: "Pridať obsah výberu ako pageElement", + propName: "Zadajte názov vlastnosti pravidla", + propValue: "Zadajte hodnotu vlastnosti pravidla", + customFirst: "Ignorovať vyrovnávaciu pamäť pre lokálne vlastné pravidlá", + rulesExample: "Príklad pravidiel", + lastPage: "Dosiahli ste poslednú stránku", + lastPageTips: "Zobraziť tipy pri dosiahnutí poslednej stránky" + } + }, + { + name: "Magyar", + match: ["hu"], + lang: { + enableDebug: "Hibakeresési kimenet engedélyezése a konzolon", + updateNotification: "Értesítés a szabályok frissítése után", + disable: "Ideiglenes letiltás", + disableSite: "Letiltott állapot váltása", + disableSiteTips: "Letiltva ezen az oldalon.", + enableSiteTips: "Engedélyezve ezen az oldalon.", + enable: "✅Automatikus lapozás engedélyezése", + tempActive: "Ideiglenesen aktív", + toTop: "Vissza a tetejére.", + toBottom: "Ugrás az aljára.", + current: "Jelenlegi oldal.", + forceIframe: "Következő oldal csatlakozásának kényszerítése", + cancelForceIframe: "Kényszerített csatlakozás megszakítása", + configure: "Pagetual konfigurálása", + firstUpdate: "Kattintson ide az alapértelmezett szabálylista inicializálásához", + update: "Online szabályok frissítése", + click2update: "Kattintson a szabályok URL-ről történő frissítéséhez", + loadNow: "Következő automatikus betöltése", + loadConfirm: "Hány oldalt szeretne betölteni? (0 a végtelent jelenti)", + noNext: "Nincs következő link, hozzon létre új szabályt", + passSec: "#t# másodperce frissítve", + passMin: "#t# perce frissítve", + passHour: "#t# órája frissítve", + passDay: "#t# napja frissítve", + cantDel: "Beépített szabályok nem törölhetők", + confirmDel: "Biztosan törli ezt a szabályt?", + updateSucc: "Sikeres frissítés", + beginUpdate: "Frissítés megkezdése, kérem várjon egy pillanatot", + customUrls: "Pagetual vagy AutoPagerize szabály URL importálása, soronként egy URL.", + customRules: "Adjon meg egyéni szabályokat. ✍️Szabályok beküldése", + save: "Mentés", + loadingText: "Betöltés...", + opacity: "Átlátszóság", + opacityPlaceholder: "0: elválasztó elrejtése", + hideBar: "Lapozó elválasztó elrejtése", + hideBarButNoStop: "Elrejtés, de nem leállítás", + dbClick2Stop: "Dupla kattintás az üres területre a szüneteltetéshez", + sortTitle: "A rendezés a következő szabályfrissítés után lép érvénybe", + autoRun: "Automatikus engedélyezés (feketelista mód)", + autoLoadNum: "Előtöltendő oldalak száma", + turnRate: "Lapozzon a következő oldalra, ha a lábléctől mért távolság kevesebb, mint az oldal magasságának 【X】-szerese", + inputPageNum: "Adja meg az ugrani kívánt oldalszámot", + enableHistory: "Böngészési előzmények írása lapozás után", + enableHistoryAfterInsert: "Böngészési előzmények írása azonnal az illesztés után, egyébként a böngészés után", + contentVisibility: "A content-visibility automatikus váltása a renderelési teljesítmény javítása érdekében", + initRun: "Oldalak lapozása azonnal a megnyitás után", + preload: "Következő oldal előtöltése a gyorsítás érdekében", + click2ImportRule: "Kattintson az alapszabályok linkjének importálásához, majd várja meg a frissítés befejezését: ", + forceAllBody: "Csatlakoztatja az oldal teljes törzsét?", + openInNewTab: "A kiegészítések URL-jeinek megnyitása új lapon", + importSucc: "Importálás befejezve", + import: "Importálás", + editCurrent: "Szabály szerkesztése az aktuális webhelyhez", + editBlacklist: "URL feketelista szerkesztése, soronként egy bejegyzés, támogatja a [?,*] helyettesítő karaktereket.", + upBtnImg: "Vissza a tetejére ikon", + downBtnImg: "Ugrás a lábléchez ikon", + sideControllerIcon: "Oldalsáv ikonja", + loadingTextTitle: "Betöltés", + dbClick2StopCtrl: "Ctrl billentyű", + dbClick2StopAlt: "Alt billentyű", + dbClick2StopShift: "Shift billentyű", + dbClick2StopMeta: "Meta billentyű", + dbClick2StopKey: "Gyorsbillentyű", + pageElementCss: "Egyéni stílus a fő oldalelemekhez", + customCss: "Egyéni teljes CSS", + firstAlert: "Nem importálta az alapszabályt, kérjük, válassza ki a megfelelő szabályt az importáláshoz", + picker: "Pagetual elemkiválasztó", + closePicker: "Pagetual kiválasztó bezárása", + pickerPlaceholder: "Elemválasztó (Csak haladó felhasználóknak, egyébként hagyja üresen)", + pickerCheck: "Választó ellenőrzése és másolása", + switchSelector: "Kattintson az elem váltásához", + gotoEdit: "Ugrás a szabály szerkesztéséhez az aktuális választóval", + manualMode: "Illesztés letiltása, manuális lapozás a jobb nyílbillentyűvel (vagy a 'pagetual.next' esemény küldésével)", + clickMode: "Illesztés letiltása, automatikus kattintás a következő oldalra az oldal végére görgetve", + pageBarMenu: "Kattintson az oldalsáv közepére a kiválasztó menü megnyitásához", + nextSwitch: "Következő link váltása", + arrowToScroll: "Nyomja meg a bal nyilat a visszagörgetéshez és a jobb nyilat az oldallapozáshoz", + sideController: "A lapozásvezérlő sáv megjelenítése az oldalsávon", + sideControllerScroll: "Görgetés váltása", + sideControllerAlways: "Mindig mutassa", + hideLoadingIcon: "Betöltési animáció elrejtése", + hideBarArrow: "Oldalsáv nyilának elrejtése", + duplicate: "Duplikált Pagetual telepítve van, ellenőrizze a szkriptkezelőjét!", + forceStateIframe: "Teljes oldal beágyazása iframe-ként", + forceStateDynamic: "Dinamikus tartalom betöltése iframe-en keresztül", + forceStateDisable: "Lapozás letiltása ezen az oldalon", + autoScrollRate: "Görgetési sebesség (1-1000)", + disableAutoScroll: "Automatikus görgetés leállítása", + enableAutoScroll: "Automatikus görgetés engedélyezése", + toggleAutoScroll: "Automatikus görgetés váltása", + ruleRequest: "Szabálykérés", + page: "Oldal ", + prevPage: "Előző oldal", + nextPage: "Következő oldal", + errorRulesMustBeArray: "A szabályoknak tömbnek kell lenniük!", + errorJson: "JSON hiba, ellenőrizze újra!", + editSuccess: "Sikeres szerkesztés", + errorWrongUrl: "Hibás URL, ellenőrizze újra!", + errorAlreadyExists: "Már létezik egy szabály!", + settingsSaved: "A beállítások mentve, frissítsen a megtekintéshez", + iframe: "Iframe által kényszerített felosztás", + dynamic: "Dinamikus betöltés", + reloadPage: "Szerkesztés befejezve, újratölti most?", + copied: "Másolva", + noValidContent: "Nincs érvényes tartalom, lehet, hogy Captcha van jelen", + outOfDate: "A szkript elavult, kérjük, frissítsen a legújabb verzióra.", + hideBarTips: "A lapozósáv elrejtése, magával ragadó élmény váltása", + setConfigPage: "Az aktuális oldal beállítása alapértelmezett konfigurációs oldalként", + wedata2github: "A wedata cím megváltoztatása a tükör címre a github tárolóban", + addOtherProp: "Szabálytulajdonságok hozzáadása", + addNextSelector: "Választó tartalmának hozzáadása nextLink-ként", + addPageSelector: "Választó tartalmának hozzáadása pageElement-ként", + propName: "Adja meg a szabálytulajdonság nevét", + propValue: "Adja meg a szabálytulajdonság értékét", + customFirst: "Gyorsítótár figyelmen kívül hagyása a helyi egyéni szabályoknál", + rulesExample: "Szabályok példa", + lastPage: "Elérte az utolsó oldalt", + lastPageTips: "Tippek megjelenítése az utolsó oldal elérésekor" + } + }, + { + name: "Română", + match: ["ro"], + lang: { + enableDebug: "Activați ieșirea de depanare în consolă", + updateNotification: "Notificare după actualizarea regulilor", + disable: "Dezactivați temporar", + disableSite: "Comutați starea de dezactivare", + disableSiteTips: "Dezactivat pe acest site.", + enableSiteTips: "Activat pe acest site.", + enable: "✅Activați întoarcerea automată a paginii", + tempActive: "Activ temporar", + toTop: "Înapoi sus.", + toBottom: "Mergi jos.", + current: "Pagina curentă.", + forceIframe: "Forțați alăturarea la pagina următoare", + cancelForceIframe: "Anulați alăturarea forțată", + configure: "Configurați Pagetual", + firstUpdate: "Faceți clic aici pentru a inițializa lista de reguli implicită", + update: "Actualizați regulile online", + click2update: "Faceți clic pentru a actualiza regulile de la URL acum", + loadNow: "Încărcați următoarea automat", + loadConfirm: "Câte pagini doriți să încărcați? (0 înseamnă infinit)", + noNext: "Nu s-a găsit niciun link următor, vă rugăm să creați o nouă regulă", + passSec: "Actualizat acum #t# secunde", + passMin: "Actualizat acum #t# minute", + passHour: "Actualizat acum #t# ore", + passDay: "Actualizat acum #t# zile", + cantDel: "Nu se pot șterge regulile încorporate", + confirmDel: "Sunteți sigur că doriți să ștergeți această regulă?", + updateSucc: "Actualizare reușită", + beginUpdate: "Începe actualizarea, vă rugăm așteptați un moment", + customUrls: "Importați URL-ul regulii Pagetual sau AutoPagerize, un URL pe linie.", + customRules: "Introduceți reguli personalizate. ✍️Contribuiți cu reguli", + save: "Salvați", + loadingText: "Se încarcă...", + opacity: "Opacitate", + opacityPlaceholder: "0: ascundeți distanțierul", + hideBar: "Ascundeți distanțierul de paginare", + hideBarButNoStop: "Ascundeți, dar nu opriți", + dbClick2Stop: "Faceți dublu clic pe spațiul gol pentru a întrerupe", + sortTitle: "Sortarea intră în vigoare după următoarea actualizare a regulilor", + autoRun: "Activare automată (mod listă neagră)", + autoLoadNum: "Cantitatea de pagini de preîncărcat", + turnRate: "Întoarceți la pagina următoare când este mai puțin de 【X】 ori înălțimea paginii de la subsol", + inputPageNum: "Introduceți numărul paginii pentru a sări", + enableHistory: "Scrieți istoricul de navigare după întoarcerea paginii", + enableHistoryAfterInsert: "Scrieți istoricul de navigare imediat după îmbinare, altfel scrieți după navigare", + contentVisibility: "Comutați automat vizibilitatea conținutului pentru a îmbunătăți performanța de randare", + initRun: "Întoarceți paginile imediat după deschidere", + preload: "Preîncărcați pagina următoare pentru a accelera", + click2ImportRule: "Faceți clic pentru a importa linkul regulilor de bază, apoi așteptați până la finalizarea actualizării: ", + forceAllBody: "Alăturați corpul complet al paginii?", + openInNewTab: "Deschideți URL-urile adăugirilor într-o filă nouă", + importSucc: "Import finalizat", + import: "Importați", + editCurrent: "Editați regula pentru site-ul web curent", + editBlacklist: "Editați lista neagră de URL-uri, o intrare pe linie, suportă caracterele [?,*].", + upBtnImg: "Pictogramă înapoi sus", + downBtnImg: "Pictogramă mergi la subsol", + sideControllerIcon: "Pictogramă bară laterală", + loadingTextTitle: "Se încarcă", + dbClick2StopCtrl: "Tasta Ctrl", + dbClick2StopAlt: "Tasta Alt", + dbClick2StopShift: "Tasta Shift", + dbClick2StopMeta: "Tasta Meta", + dbClick2StopKey: "Tastă de comandă rapidă", + pageElementCss: "Stil personalizat pentru elementele principale ale paginii", + customCss: "CSS complet personalizat", + firstAlert: "Nu ați importat regula de bază, vă rugăm să selectați regula corespunzătoare pentru a o importa", + picker: "Selector de elemente Pagetual", + closePicker: "Închideți selectorul Pagetual", + pickerPlaceholder: "Selector de elemente (Doar utilizatori avansați, altfel lăsați necompletat)", + pickerCheck: "Verificați selectorul și copiați", + switchSelector: "Faceți clic pentru a comuta elementul", + gotoEdit: "Mergeți la editarea regulii cu selectorul curent", + manualMode: "Dezactivați îmbinarea, avansați manual la pagina următoare folosind tasta săgeată dreapta (sau trimiteți evenimentul 'pagetual.next')", + clickMode: "Dezactivați îmbinarea, faceți clic automat pe pagina următoare la derularea până la sfârșitul paginii", + pageBarMenu: "Faceți clic în centrul barei de pagină pentru a deschide meniul selectorului", + nextSwitch: "Comutați linkul următor", + arrowToScroll: "Apăsați săgeata stânga pentru a derula înapoi și săgeata dreapta pentru a avansa pagina", + sideController: "Afișați bara de control a paginării în bara laterală", + sideControllerScroll: "Comutare derulare", + sideControllerAlways: "Afișați întotdeauna", + hideLoadingIcon: "Ascundeți animația de încărcare", + hideBarArrow: "Ascundeți săgeata pentru bara de pagină", + duplicate: "Pagetual duplicat a fost instalat, verificați managerul de scripturi!", + forceStateIframe: "Încorporați pagina completă ca iframe", + forceStateDynamic: "Încărcați conținut dinamic prin iframe", + forceStateDisable: "Dezactivați întoarcerea paginii pe acest site", + autoScrollRate: "Viteza de derulare (1~1000)", + disableAutoScroll: "Opriți derularea automată", + enableAutoScroll: "Activați derularea automată", + toggleAutoScroll: "Comutați derularea automată", + ruleRequest: "Cerere de regulă", + page: "Pagina ", + prevPage: "Pagina anterioară", + nextPage: "Pagina următoare", + errorRulesMustBeArray: "Regulile trebuie să fie un tablou!", + errorJson: "Eroare JSON, verificați din nou!", + editSuccess: "Editat cu succes", + errorWrongUrl: "URL greșit, verificați din nou!", + errorAlreadyExists: "O regulă există deja!", + settingsSaved: "Setările sunt salvate, reîmprospătați pentru a vizualiza", + iframe: "Divizare forțată de iframe", + dynamic: "Încărcare dinamică", + reloadPage: "Editare finalizată, reîncărcați acum?", + copied: "Copiat", + noValidContent: "Nu s-a detectat niciun conținut valid, este posibil să existe un Captcha", + outOfDate: "Scriptul este învechit, vă rugăm să actualizați la cea mai recentă versiune.", + hideBarTips: "Ascundeți bara de paginare, comutați experiența imersivă", + setConfigPage: "Setați pagina curentă ca pagină de configurare implicită", + wedata2github: "Schimbați adresa wedata cu adresa oglindă din depozitul github", + addOtherProp: "Adăugați proprietăți de regulă", + addNextSelector: "Adăugați conținutul selectorului ca nextLink", + addPageSelector: "Adăugați conținutul selectorului ca pageElement", + propName: "Introduceți numele proprietății regulii", + propValue: "Introduceți valoarea proprietății regulii", + customFirst: "Ignorați memoria cache pentru regulile personalizate locale", + rulesExample: "Exemplu de reguli", + lastPage: "Ați ajuns la ultima pagină", + lastPageTips: "Afișați sfaturi la atingerea ultimei pagini" + } + }, + { + name: "Suomi", + match: ["fi"], + lang: { + enableDebug: "Ota virheenkorjaustuloste käyttöön konsolissa", + updateNotification: "Ilmoitus sääntöjen päivityksen jälkeen", + disable: "Poista väliaikaisesti käytöstä", + disableSite: "Vaihda käytöstä poistettu tila", + disableSiteTips: "Poistettu käytöstä tällä sivustolla.", + enableSiteTips: "Otettu käyttöön tällä sivustolla.", + enable: "✅Ota automaattinen sivunvaihto käyttöön", + tempActive: "Väliaikaisesti aktiivinen", + toTop: "Takaisin ylös.", + toBottom: "Mene alas.", + current: "Nykyinen sivu.", + forceIframe: "Pakota liittymään seuraavalle sivulle", + cancelForceIframe: "Peruuta pakotettu liittyminen", + configure: "Määritä Pagetual", + firstUpdate: "Napsauta tästä alustaaksesi oletussääntöluettelon", + update: "Päivitä verkkosäännöt", + click2update: "Napsauta päivittääksesi säännöt URL-osoitteesta nyt", + loadNow: "Lataa seuraava automaattisesti", + loadConfirm: "Kuinka monta sivua haluat ladata? (0 tarkoittaa ääretöntä)", + noNext: "Seuraavaa linkkiä ei löytynyt, luo uusi sääntö", + passSec: "Päivitetty #t# sekuntia sitten", + passMin: "Päivitetty #t# minuuttia sitten", + passHour: "Päivitetty #t# tuntia sitten", + passDay: "Päivitetty #t# päivää sitten", + cantDel: "Sisäänrakennettuja sääntöjä ei voi poistaa", + confirmDel: "Haluatko varmasti poistaa tämän säännön?", + updateSucc: "Päivitys onnistui", + beginUpdate: "Aloitetaan päivitys, odota hetki", + customUrls: "Tuo Pagetual- tai AutoPagerize-säännön URL-osoite, yksi URL-osoite riviä kohti.", + customRules: "Syötä mukautettuja sääntöjä. ✍️Osallistu sääntöihin", + save: "Tallenna", + loadingText: "Ladataan...", + opacity: "Läpinäkyvyys", + opacityPlaceholder: "0: piilota välilevy", + hideBar: "Piilota sivutuksen välilevy", + hideBarButNoStop: "Piilota, mutta älä pysäytä", + dbClick2Stop: "Kaksoisnapsauta tyhjää tilaa keskeyttääksesi", + sortTitle: "Lajittelu tulee voimaan seuraavan sääntöpäivityksen jälkeen", + autoRun: "Ota automaattisesti käyttöön (mustan listan tila)", + autoLoadNum: "Esiladattavien sivujen määrä", + turnRate: "Vaihda seuraavalle sivulle, kun se on alle 【X】 kertaa sivun korkeuden päässä alatunnisteesta", + inputPageNum: "Syötä sivunumero siirtyäksesi", + enableHistory: "Kirjoita selaushistoria sivunvaihdon jälkeen", + enableHistoryAfterInsert: "Kirjoita selaushistoria heti liittämisen jälkeen, muuten kirjoita selauksen jälkeen", + contentVisibility: "Vaihda automaattisesti sisällön näkyvyyttä parantaaksesi renderöintisuorituskykyä", + initRun: "Vaihda sivuja heti avaamisen jälkeen", + preload: "Esilataa seuraava sivu nopeuttaaksesi", + click2ImportRule: "Napsauta tuodaksesi perussääntöjen linkin ja odota sitten, kunnes päivitys on valmis: ", + forceAllBody: "Liitetäänkö sivun koko runko?", + openInNewTab: "Avaa lisäysten URL-osoitteet uudessa välilehdessä", + importSucc: "Tuonti onnistui", + import: "Tuo", + editCurrent: "Muokkaa nykyisen verkkosivuston sääntöä", + editBlacklist: "Muokkaa URL-mustaa listaa, yksi merkintä riviä kohti, tukee [?,*] -jokerimerkkejä.", + upBtnImg: "Takaisin ylös -kuvake", + downBtnImg: "Mene alatunnisteeseen -kuvake", + sideControllerIcon: "Sivupalkin kuvake", + loadingTextTitle: "Ladataan", + dbClick2StopCtrl: "Ctrl-näppäin", + dbClick2StopAlt: "Alt-näppäin", + dbClick2StopShift: "Shift-näppäin", + dbClick2StopMeta: "Meta-näppäin", + dbClick2StopKey: "Pikakuvake", + pageElementCss: "Mukautettu tyyli pääsivun elementeille", + customCss: "Mukautettu täydellinen CSS", + firstAlert: "Et ole tuonut perussääntöä, valitse sopiva sääntö tuotavaksi", + picker: "Pagetual-elementin valitsin", + closePicker: "Sulje Pagetual-valitsin", + pickerPlaceholder: "Elementin valitsin (Vain edistyneille käyttäjille, muuten jätä tyhjäksi)", + pickerCheck: "Tarkista valitsin ja kopioi", + switchSelector: "Napsauta vaihtaaksesi elementtiä", + gotoEdit: "Siirry muokkaamaan sääntöä nykyisellä valitsimella", + manualMode: "Poista liittäminen käytöstä, siirry manuaalisesti seuraavalle sivulle oikealla nuolinäppäimellä (tai lähetä tapahtuma 'pagetual.next')", + clickMode: "Poista liittäminen käytöstä, napsauta automaattisesti seuraavaa sivua, kun vierität sivun loppuun", + pageBarMenu: "Napsauta sivupalkin keskustaa avataksesi valitsinvalikon", + nextSwitch: "Vaihda seuraava linkki", + arrowToScroll: "Paina vasenta nuolta selataksesi taaksepäin ja oikeaa nuolta siirtyäksesi sivulle", + sideController: "Näytä sivutuksen ohjauspalkki sivupalkissa", + sideControllerScroll: "Vierityksen vaihto", + sideControllerAlways: "Näytä aina", + hideLoadingIcon: "Piilota latausanimaatio", + hideBarArrow: "Piilota nuoli sivupalkille", + duplicate: "Pagetualin kaksoiskappale on asennettu, tarkista komentosarjojen hallinta!", + forceStateIframe: "Upota koko sivu iframeksi", + forceStateDynamic: "Lataa dynaamista sisältöä iframen kautta", + forceStateDisable: "Poista sivunvaihto käytöstä tällä sivustolla", + autoScrollRate: "Vieritysnopeus (1-1000)", + disableAutoScroll: "Pysäytä automaattinen vieritys", + enableAutoScroll: "Ota automaattinen vieritys käyttöön", + toggleAutoScroll: "Vaihda automaattista vieritystä", + ruleRequest: "Sääntöpyyntö", + page: "Sivu ", + prevPage: "Edellinen sivu", + nextPage: "Seuraava sivu", + errorRulesMustBeArray: "Sääntöjen on oltava taulukko!", + errorJson: "JSON-virhe, tarkista uudelleen!", + editSuccess: "Muokkaus onnistui", + errorWrongUrl: "Väärä URL-osoite, tarkista uudelleen!", + errorAlreadyExists: "Sääntö on jo olemassa!", + settingsSaved: "Asetukset on tallennettu, päivitä nähdäksesi", + iframe: "Pakotettu jako iframella", + dynamic: "Dynaaminen lataus", + reloadPage: "Muokkaus valmis, ladataanko uudelleen nyt?", + copied: "Kopioitu", + noValidContent: "Kelvollista sisältöä ei havaittu, Captcha saattaa olla läsnä", + outOfDate: "Komentosarja on vanhentunut, päivitä uusimpaan versioon.", + hideBarTips: "Piilota sivutuspalkki, vaihda immersiiviseen kokemukseen", + setConfigPage: "Aseta nykyinen sivu oletusmäärityssivuksi", + wedata2github: "Vaihda wedata-osoite github-arkiston peiliosoitteeseen", + addOtherProp: "Lisää säännön ominaisuuksia", + addNextSelector: "Lisää valitsimen sisältö nimellä nextLink", + addPageSelector: "Lisää valitsimen sisältö nimellä pageElement", + propName: "Syötä säännön ominaisuuden nimi", + propValue: "Syötä säännön ominaisuuden arvo", + customFirst: "Ohita välimuisti paikallisille mukautetuille säännöille", + rulesExample: "Sääntöesimerkki", + lastPage: "Viimeinen sivu saavutettu", + lastPageTips: "Näytä vinkkejä, kun saavutaan viimeiselle sivulle" + } + }, + { + name: "Ελληνικά", + match: ["el"], + lang: { + enableDebug: "Ενεργοποίηση εξόδου εντοπισμού σφαλμάτων στην κονσόλα", + updateNotification: "Ειδοποίηση μετά την ενημέρωση των κανόνων", + disable: "Προσωρινή απενεργοποίηση", + disableSite: "Εναλλαγή κατάστασης απενεργοποίησης", + disableSiteTips: "Απενεργοποιημένο σε αυτόν τον ιστότοπο.", + enableSiteTips: "Ενεργοποιημένο σε αυτόν τον ιστότοπο.", + enable: "✅Ενεργοποίηση αυτόματης αλλαγής σελίδας", + tempActive: "Προσωρινά ενεργό", + toTop: "Επιστροφή στην κορυφή.", + toBottom: "Μετάβαση στο κάτω μέρος.", + current: "Τρέχουσα σελίδα.", + forceIframe: "Εξαναγκασμός συμμετοχής στην επόμενη σελίδα", + cancelForceIframe: "Ακύρωση εξαναγκασμένης συμμετοχής", + configure: "Διαμόρφωση Pagetual", + firstUpdate: "Κάντε κλικ εδώ για να αρχικοποιήσετε την προεπιλεγμένη λίστα κανόνων", + update: "Ενημέρωση διαδικτυακών κανόνων", + click2update: "Κάντε κλικ για να ενημερώσετε τους κανόνες από το URL τώρα", + loadNow: "Φόρτωση του επόμενου αυτόματα", + loadConfirm: "Πόσες σελίδες θέλετε να φορτώσετε; (0 σημαίνει άπειρο)", + noNext: "Δεν βρέθηκε επόμενος σύνδεσμος, δημιουργήστε έναν νέο κανόνα", + passSec: "Ενημερώθηκε πριν από #t# δευτερόλεπτα", + passMin: "Ενημερώθηκε πριν από #t# λεπτά", + passHour: "Ενημερώθηκε πριν από #t# ώρες", + passDay: "Ενημερώθηκε πριν από #t# ημέρες", + cantDel: "Δεν είναι δυνατή η διαγραφή ενσωματωμένων κανόνων", + confirmDel: "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτόν τον κανόνα;", + updateSucc: "Η ενημέρωση ολοκληρώθηκε με επιτυχία", + beginUpdate: "Έναρξη ενημέρωσης, περιμένετε μια στιγμή", + customUrls: "Εισαγωγή URL κανόνα Pagetual ή AutoPagerize, ένα URL ανά γραμμή.", + customRules: "Εισαγωγή προσαρμοσμένων κανόνων. ✍️Συνεισφέρετε κανόνες", + save: "Αποθήκευση", + loadingText: "Φόρτωση...", + opacity: "Αδιαφάνεια", + opacityPlaceholder: "0: απόκρυψη διαχωριστικού", + hideBar: "Απόκρυψη του διαχωριστικού σελιδοποίησης", + hideBarButNoStop: "Απόκρυψη αλλά όχι διακοπή", + dbClick2Stop: "Κάντε διπλό κλικ στον κενό χώρο για παύση", + sortTitle: "Η ταξινόμηση τίθεται σε ισχύ μετά την επόμενη ενημέρωση κανόνων", + autoRun: "Αυτόματη ενεργοποίηση (λειτουργία μαύρης λίστας)", + autoLoadNum: "Ποσότητα για προφόρτωση σελίδων", + turnRate: "Μετάβαση στην επόμενη σελίδα όταν απέχει λιγότερο από 【X】 φορές το ύψος της σελίδας από το υποσέλιδο", + inputPageNum: "Εισαγάγετε τον αριθμό σελίδας για μετάβαση", + enableHistory: "Εγγραφή ιστορικού περιήγησης μετά την αλλαγή σελίδας", + enableHistoryAfterInsert: "Εγγραφή ιστορικού περιήγησης αμέσως μετά τη συγκόλληση, διαφορετικά εγγραφή μετά την περιήγηση", + contentVisibility: "Αυτόματη εναλλαγή της ορατότητας περιεχομένου για βελτίωση της απόδοσης απόδοσης", + initRun: "Αλλαγή σελίδων αμέσως μετά το άνοιγμα", + preload: "Προφόρτωση της επόμενης σελίδας για επιτάχυνση", + click2ImportRule: "Κάντε κλικ για να εισαγάγετε τον σύνδεσμο των βασικών κανόνων και, στη συνέχεια, περιμένετε μέχρι να ολοκληρωθεί η ενημέρωση: ", + forceAllBody: "Συμμετοχή ολόκληρου του σώματος της σελίδας;", + openInNewTab: "Άνοιγμα των URL των προσθηκών σε νέα καρτέλα", + importSucc: "Η εισαγωγή ολοκληρώθηκε", + import: "Εισαγωγή", + editCurrent: "Επεξεργασία κανόνα για τον τρέχοντα ιστότοπο", + editBlacklist: "Επεξεργαστείτε τη μαύρη λίστα URL, μία καταχώριση ανά γραμμή, υποστηρίζει μπαλαντέρ [?,*].", + upBtnImg: "Εικονίδιο επιστροφής στην κορυφή", + downBtnImg: "Εικονίδιο μετάβασης στο υποσέλιδο", + sideControllerIcon: "Εικονίδιο πλευρικής γραμμής", + loadingTextTitle: "Φόρτωση", + dbClick2StopCtrl: "Πλήκτρο Ctrl", + dbClick2StopAlt: "Πλήκτρο Alt", + dbClick2StopShift: "Πλήκτρο Shift", + dbClick2StopMeta: "Πλήκτρο Meta", + dbClick2StopKey: "Πλήκτρο συντόμευσης", + pageElementCss: "Προσαρμοσμένο στυλ για τα κύρια στοιχεία της σελίδας", + customCss: "Προσαρμοσμένο πλήρες CSS", + firstAlert: "Δεν έχετε εισαγάγει τον βασικό κανόνα, επιλέξτε τον κατάλληλο κανόνα για εισαγωγή", + picker: "Επιλογέας στοιχείων Pagetual", + closePicker: "Κλείσιμο του επιλογέα Pagetual", + pickerPlaceholder: "Επιλογέας στοιχείων (Μόνο για προχωρημένους χρήστες, αλλιώς αφήστε κενό)", + pickerCheck: "Έλεγχος επιλογέα και αντιγραφή", + switchSelector: "Κάντε κλικ για εναλλαγή στοιχείου", + gotoEdit: "Μετάβαση στην επεξεργασία κανόνα με τον τρέχοντα επιλογέα", + manualMode: "Απενεργοποίηση συγκόλλησης, μη αυτόματη μετάβαση στην επόμενη σελίδα χρησιμοποιώντας το δεξί βέλος (ή αποστολή συμβάντος 'pagetual.next')", + clickMode: "Απενεργοποίηση συγκόλλησης, αυτόματο κλικ στην επόμενη σελίδα κατά την κύλιση στο τέλος της σελίδας", + pageBarMenu: "Κάντε κλικ στο κέντρο της γραμμής σελίδας για να ανοίξετε το μενού επιλογέα", + nextSwitch: "Εναλλαγή επόμενου συνδέσμου", + arrowToScroll: "Πατήστε το αριστερό βέλος για κύλιση προς τα πίσω και το δεξί βέλος για μετάβαση στη σελίδα", + sideController: "Εμφάνιση της γραμμής ελέγχου σελιδοποίησης στην πλευρική γραμμή", + sideControllerScroll: "Εναλλαγή κύλισης", + sideControllerAlways: "Πάντα εμφάνιση", + hideLoadingIcon: "Απόκρυψη κινούμενης εικόνας φόρτωσης", + hideBarArrow: "Απόκρυψη βέλους για τη γραμμή σελίδας", + duplicate: "Έχει εγκατασταθεί διπλότυπο Pagetual, ελέγξτε τον διαχειριστή σεναρίων σας!", + forceStateIframe: "Ενσωμάτωση ολόκληρης της σελίδας ως iframe", + forceStateDynamic: "Φόρτωση δυναμικού περιεχομένου μέσω iframe", + forceStateDisable: "Απενεργοποίηση αλλαγής σελίδας σε αυτόν τον ιστότοπο", + autoScrollRate: "Ταχύτητα κύλισης (1~1000)", + disableAutoScroll: "Διακοπή αυτόματης κύλισης", + enableAutoScroll: "Ενεργοποίηση αυτόματης κύλισης", + toggleAutoScroll: "Εναλλαγή αυτόματης κύλισης", + ruleRequest: "Αίτημα κανόνα", + page: "Σελίδα ", + prevPage: "Προηγούμενη σελίδα", + nextPage: "Επόμενη σελίδα", + errorRulesMustBeArray: "Οι κανόνες πρέπει να είναι πίνακας!", + errorJson: "Σφάλμα JSON, ελέγξτε ξανά!", + editSuccess: "Η επεξεργασία ολοκληρώθηκε με επιτυχία", + errorWrongUrl: "Λάθος URL, ελέγξτε ξανά!", + errorAlreadyExists: "Ένας κανόνας υπάρχει ήδη!", + settingsSaved: "Οι ρυθμίσεις αποθηκεύτηκαν, ανανεώστε για προβολή", + iframe: "Εξαναγκασμένος διαχωρισμός από iframe", + dynamic: "Δυναμική φόρτωση", + reloadPage: "Η επεξεργασία ολοκληρώθηκε, επαναφόρτωση τώρα;", + copied: "Αντιγράφηκε", + noValidContent: "Δεν εντοπίστηκε έγκυρο περιεχόμενο, ενδέχεται να υπάρχει Captcha", + outOfDate: "Το σενάριο είναι ξεπερασμένο, ενημερώστε στην πιο πρόσφατη έκδοση.", + hideBarTips: "Απόκρυψη της γραμμής σελιδοποίησης, εναλλαγή καθηλωτικής εμπειρίας", + setConfigPage: "Ορισμός της τρέχουσας σελίδας ως προεπιλεγμένης σελίδας διαμόρφωσης", + wedata2github: "Αλλάξτε τη διεύθυνση wedata στη διεύθυνση καθρέφτη στο αποθετήριο github", + addOtherProp: "Προσθήκη ιδιοτήτων κανόνα", + addNextSelector: "Προσθήκη περιεχομένου επιλογέα ως nextLink", + addPageSelector: "Προσθήκη περιεχομένου επιλογέα ως pageElement", + propName: "Εισαγάγετε το όνομα ιδιότητας κανόνα", + propValue: "Εισαγάγετε την τιμή ιδιότητας κανόνα", + customFirst: "Παράβλεψη κρυφής μνήμης για τοπικούς προσαρμοσμένους κανόνες", + rulesExample: "Παράδειγμα κανόνων", + lastPage: "Φτάσατε στην τελευταία σελίδα", + lastPageTips: "Εμφάνιση συμβουλών κατά την άφιξη στην τελευταία σελίδα" + } + }, + { + name: "Esperanto", + match: ["eo"], + lang: { + enableDebug: "Aktivigi sencimigan eligon al la konzolo", + updateNotification: "Sciigo post ĝisdatigo de reguloj", + disable: "Provizore malŝalti", + disableSite: "Baskuligi malŝaltitan staton", + disableSiteTips: "Malŝaltita en ĉi tiu retejo.", + enableSiteTips: "Ŝaltita en ĉi tiu retejo.", + enable: "✅Aktivigi aŭtomatan paĝo-turnadon", + tempActive: "Provizore aktiva", + toTop: "Reen al supro.", + toBottom: "Iri al malsupro.", + current: "Nuna paĝo.", + forceIframe: "Devigi kunigon de la sekva paĝo", + cancelForceIframe: "Nuligi devigitan kunigon", + configure: "Agordi Pagetual", + firstUpdate: "Klaku ĉi tie por pravalorizi la defaŭltan regul-liston", + update: "Ĝisdatigi retajn regulojn", + click2update: "Klaku por ĝisdatigi regulojn el URL nun", + loadNow: "Ŝargi la sekvan aŭtomate", + loadConfirm: "Kiom da paĝoj vi volas ŝargi? (0 signifas senfine)", + noNext: "Neniu sekva ligilo trovita, bonvolu krei novan regulon", + passSec: "Ĝisdatigita antaŭ #t# sekundoj", + passMin: "Ĝisdatigita antaŭ #t# minutoj", + passHour: "Ĝisdatigita antaŭ #t# horoj", + passDay: "Ĝisdatigita antaŭ #t# tagoj", + cantDel: "Ne eblas forigi enkonstruitajn regulojn", + confirmDel: "Ĉu vi certas, ke vi volas forigi ĉi tiun regulon?", + updateSucc: "Ĝisdatigo sukcesis", + beginUpdate: "Komencante ĝisdatigon, bonvolu atendi momenton", + customUrls: "Importi regulan URL de Pagetual aŭ AutoPagerize, unu URL po linio.", + customRules: "Enigu proprajn regulojn. ✍️Kontribui regulojn", + save: "Konservi", + loadingText: "Ŝargante...", + opacity: "Opakeco", + opacityPlaceholder: "0: kaŝi apartigilon", + hideBar: "Kaŝi la paĝrangan apartigilon", + hideBarButNoStop: "Kaŝi sed ne haltigi", + dbClick2Stop: "Duoble-klaku sur la malplena spaco por paŭzi", + sortTitle: "Ordigo efektiviĝas post la sekva ĝisdatigo de reguloj", + autoRun: "Aŭtomata aktivigo (nigra listo reĝimo)", + autoLoadNum: "Kvanto por antaŭŝargitaj paĝoj", + turnRate: "Turnu la sekvan paĝon kiam ĝi estas malpli ol 【X】 fojojn la paĝa alteco de la piedlinio", + inputPageNum: "Enigu paĝan numeron por salti", + enableHistory: "Skribi foliumhistorion post paĝo-turnado", + enableHistoryAfterInsert: "Skribi foliumhistorion tuj post kunigo, alie skribi post foliumado", + contentVisibility: "Aŭtomate baskuligi enhavan videblecon por plibonigi bildigan rendimenton", + initRun: "Turni paĝojn tuj post malfermo", + preload: "Antaŭŝargi la sekvan paĝon por rapidigi", + click2ImportRule: "Klaku por importi bazan regulan ligilon, kaj poste atendu ĝis la ĝisdatigo finiĝos: ", + forceAllBody: "Kunigi la plenan korpon de la paĝo?", + openInNewTab: "Malfermi URL-ojn de aldonoj en nova langeto", + importSucc: "Importado finiĝis", + import: "Importi", + editCurrent: "Redakti regulon por la nuna retejo", + editBlacklist: "Redakti la nigran liston de URL-oj, unu enigo po linio, subtenas [?,*] ĵokerojn.", + upBtnImg: "Ikono por reen al supro", + downBtnImg: "Ikono por iri al piedlinio", + sideControllerIcon: "Ikono de flanka stango", + loadingTextTitle: "Ŝargante", + dbClick2StopCtrl: "Klavo Ctrl", + dbClick2StopAlt: "Klavo Alt", + dbClick2StopShift: "Klavo Shift", + dbClick2StopMeta: "Klavo Meta", + dbClick2StopKey: "Fulmoklavo", + pageElementCss: "Propra stilo por ĉefaj paĝaj elementoj", + customCss: "Propra kompleta CSS", + firstAlert: "Vi ne importis la bazan regulon, bonvolu elekti la taŭgan regulon por importi", + picker: "Pagetual elementa elektilo", + closePicker: "Fermi la elektilon de Pagetual", + pickerPlaceholder: "Elementa elektilo (Nur por spertaj uzantoj, alie lasu malplena)", + pickerCheck: "Kontroli elektilon kaj kopii", + switchSelector: "Klaku por ŝanĝi elementon", + gotoEdit: "Iri al redakto de regulo kun la nuna elektilo", + manualMode: "Malŝalti kunigon, permane antaŭeniri al la sekva paĝo per la dekstra sagoklavo (aŭ sendi eventon 'pagetual.next')", + clickMode: "Malŝalti kunigon, aŭtomate alklaki la sekvan paĝon rulumante ĝis la fino de la paĝo", + pageBarMenu: "Klaku la centron de la paĝa stango por malfermi la elektilan menuon", + nextSwitch: "Ŝanĝi la sekvan ligilon", + arrowToScroll: "Premu la maldekstran sagon por rulumigi reen kaj la dekstran sagon por antaŭeniri paĝon", + sideController: "Montri la paĝrangan kontrolstangon en la flanka stango", + sideControllerScroll: "Rulumiga baskulo", + sideControllerAlways: "Ĉiam montri", + hideLoadingIcon: "Kaŝi ŝargan animacion", + hideBarArrow: "Kaŝi sagon por la paĝa stango", + duplicate: "Duplikata Pagetual estis instalita, kontrolu vian skript-administrilon!", + forceStateIframe: "Enigi plenan paĝon kiel iframe", + forceStateDynamic: "Ŝargi dinamikan enhavon per iframe", + forceStateDisable: "Malŝalti paĝo-turnadon en ĉi tiu retejo", + autoScrollRate: "Rulumrapido (1~1000)", + disableAutoScroll: "Haltigi Aŭtomatan Rulumadon", + enableAutoScroll: "Aktivigi Aŭtomatan Rulumadon", + toggleAutoScroll: "Baskuligi Aŭtomatan Rulumadon", + ruleRequest: "Regula Peto", + page: "Paĝo ", + prevPage: "Antaŭa paĝo", + nextPage: "Sekva paĝo", + errorRulesMustBeArray: "Reguloj devas esti tabelo!", + errorJson: "JSON-eraro, Rekontrolu!", + editSuccess: "Sukcese redaktita", + errorWrongUrl: "Malĝusta URL, Rekontrolu!", + errorAlreadyExists: "Regulo jam ekzistas!", + settingsSaved: "La agordoj estas konservitaj, refreŝigu por vidi", + iframe: "Devigita disigo per iframe", + dynamic: "Dinamika ŝargado", + reloadPage: "Redakto finiĝis, ĉu reŝargi nun?", + copied: "Kopiita", + noValidContent: "Neniu valida enhavo detektita, Captcha eble ĉeestas", + outOfDate: "La skripto estas malmoderna, bonvolu ĝisdatigi al la plej nova versio.", + hideBarTips: "Kaŝi la paĝrangan stangon, baskuligi imersivan sperton", + setConfigPage: "Agordi la nunan paĝon kiel la defaŭltan agordan paĝon", + wedata2github: "Ŝanĝi la wedata-adreson al la spegula adreso en la github-deponejo", + addOtherProp: "Aldoni regulajn ecojn", + addNextSelector: "Aldoni elektilan enhavon kiel nextLink", + addPageSelector: "Aldoni elektilan enhavon kiel pageElement", + propName: "Enigu regulan econan nomon", + propValue: "Enigu regulan econan valoron", + customFirst: "Ignori kaŝmemoron por lokaj propraj reguloj", + rulesExample: "Regula Ekzemplo", + lastPage: "Atingis la lastan paĝon", + lastPageTips: "Montri konsilojn atinginte la lastan paĝon" + } + }, + { + name: "Български", + match: ["bg"], + lang: { + enableDebug: "Активиране на изход за отстраняване на грешки в конзолата", + updateNotification: "Известие след актуализиране на правилата", + disable: "Временно деактивиране", + disableSite: "Превключване на деактивирано състояние", + disableSiteTips: "Деактивирано на този сайт.", + enableSiteTips: "Активирано на този сайт.", + enable: "✅Активиране на автоматично прелистване на страници", + tempActive: "Временно активно", + toTop: "Обратно горе.", + toBottom: "Към дъното.", + current: "Текуща страница.", + forceIframe: "Принудително присъединяване към следващата страница", + cancelForceIframe: "Отказ от принудително присъединяване", + configure: "Конфигуриране на Pagetual", + firstUpdate: "Щракнете тук, за да инициализирате списъка с правила по подразбиране", + update: "Актуализиране на онлайн правилата", + click2update: "Щракнете, за да актуализирате правилата от URL сега", + loadNow: "Зареждане на следващото автоматично", + loadConfirm: "Колко страници искате да заредите? (0 означава безкрайност)", + noNext: "Няма намерена следваща връзка, моля, създайте ново правило", + passSec: "Актуализирано преди #t# секунди", + passMin: "Актуализирано преди #t# минути", + passHour: "Актуализирано преди #t# часа", + passDay: "Актуализирано преди #t# дни", + cantDel: "Не могат да се изтриват вградени правила", + confirmDel: "Сигурни ли сте, че искате да изтриете това правило?", + updateSucc: "Актуализацията е успешна", + beginUpdate: "Започва актуализация, моля, изчакайте малко", + customUrls: "Импортиране на URL на правило Pagetual или AutoPagerize, един URL на ред.", + customRules: "Въведете персонализирани правила. ✍️Допринесете с правила", + save: "Запазване", + loadingText: "Зареждане...", + opacity: "Непрозрачност", + opacityPlaceholder: "0: скриване на разделителя", + hideBar: "Скриване на разделителя за пагинация", + hideBarButNoStop: "Скриване, но не спиране", + dbClick2Stop: "Двоен клик върху празното пространство за пауза", + sortTitle: "Сортирането влиза в сила след следващата актуализация на правилата", + autoRun: "Автоматично активиране (режим на черен списък)", + autoLoadNum: "Количество за предварително заредени страници", + turnRate: "Превъртете на следващата страница, когато е на по-малко от 【X】 пъти височината на страницата от долния колонтитул", + inputPageNum: "Въведете номер на страница за прескачане", + enableHistory: "Записване на историята на сърфиране след прелистване на страница", + enableHistoryAfterInsert: "Записване на историята на сърфиране веднага след снаждане, в противен случай записване след сърфиране", + contentVisibility: "Автоматично превключване на видимостта на съдържанието за подобряване на производителността на изобразяване", + initRun: "Превъртане на страници веднага след отваряне", + preload: "Предварително зареждане на следващата страница за ускоряване", + click2ImportRule: "Щракнете, за да импортирате връзката към основните правила, и след това изчакайте, докато актуализацията приключи: ", + forceAllBody: "Присъединяване на цялото тяло на страницата?", + openInNewTab: "Отваряне на URL адресите на допълненията в нов раздел", + importSucc: "Импортирането е завършено", + import: "Импортиране", + editCurrent: "Редактиране на правило за текущия уебсайт", + editBlacklist: "Редактирайте черния списък с URL адреси, един запис на ред, поддържа заместващи символи [?,*].", + upBtnImg: "Икона за връщане горе", + downBtnImg: "Икона за преминаване към долния колонтитул", + sideControllerIcon: "Икона на страничната лента", + loadingTextTitle: "Зареждане", + dbClick2StopCtrl: "Клавиш Ctrl", + dbClick2StopAlt: "Клавиш Alt", + dbClick2StopShift: "Клавиш Shift", + dbClick2StopMeta: "Клавиш Meta", + dbClick2StopKey: "Клавишна комбинация", + pageElementCss: "Персонализиран стил за основните елементи на страницата", + customCss: "Персонализиран пълен CSS", + firstAlert: "Не сте импортирали основното правило, моля, изберете подходящото правило за импортиране", + picker: "Избор на елементи на Pagetual", + closePicker: "Затваряне на избора на Pagetual", + pickerPlaceholder: "Избор на елементи (Само за напреднали потребители, в противен случай оставете празно)", + pickerCheck: "Проверка на селектора и копиране", + switchSelector: "Щракнете, за да превключите елемент", + gotoEdit: "Отидете на редактиране на правило с текущия селектор", + manualMode: "Деактивиране на снаждането, ръчно преминаване към следващата страница с помощта на десния клавиш със стрелка (или изпращане на събитие 'pagetual.next')", + clickMode: "Деактивиране на снаждането, автоматично щракване върху следващата страница при превъртане до края на страницата", + pageBarMenu: "Щракнете в центъра на лентата на страницата, за да отворите менюто за избор", + nextSwitch: "Превключване на следваща връзка", + arrowToScroll: "Натиснете лявата стрелка, за да превъртите назад, и дясната стрелка, за да преминете напред", + sideController: "Показване на контролната лента за пагинация в страничната лента", + sideControllerScroll: "Превключване на превъртането", + sideControllerAlways: "Винаги показване", + hideLoadingIcon: "Скриване на анимацията за зареждане", + hideBarArrow: "Скриване на стрелката за лентата на страницата", + duplicate: "Инсталиран е дубликат на Pagetual, проверете вашия мениджър на скриптове!", + forceStateIframe: "Вграждане на цялата страница като iframe", + forceStateDynamic: "Зареждане на динамично съдържание чрез iframe", + forceStateDisable: "Деактивиране на прелистването на страници на този сайт", + autoScrollRate: "Скорост на превъртане (1-1000)", + disableAutoScroll: "Спиране на автоматичното превъртане", + enableAutoScroll: "Активиране на автоматичното превъртане", + toggleAutoScroll: "Превключване на автоматичното превъртане", + ruleRequest: "Искане за правило", + page: "Страница ", + prevPage: "Предишна страница", + nextPage: "Следваща страница", + errorRulesMustBeArray: "Правилата трябва да са масив!", + errorJson: "Грешка в JSON, проверете отново!", + editSuccess: "Редактирането е успешно", + errorWrongUrl: "Грешен URL, проверете отново!", + errorAlreadyExists: "Правило вече съществува!", + settingsSaved: "Настройките са запазени, опреснете, за да видите", + iframe: "Принудително разделяне от iframe", + dynamic: "Динамично зареждане", + reloadPage: "Редактирането е завършено, презареждане сега?", + copied: "Копирано", + noValidContent: "Не е открито валидно съдържание, може да има Captcha", + outOfDate: "Скриптът е остарял, моля, актуализирайте до най-новата версия.", + hideBarTips: "Скрийте лентата за пагинация, превключете поглъщащото изживяване", + setConfigPage: "Задайте текущата страница като страница за конфигурация по подразбиране", + wedata2github: "Променете адреса на wedata на огледалния адрес в хранилището на github", + addOtherProp: "Добавяне на свойства на правилото", + addNextSelector: "Добавяне на съдържание на селектора като nextLink", + addPageSelector: "Добавяне на съдържание на селектора като pageElement", + propName: "Въведете име на свойството на правилото", + propValue: "Въведете стойност на свойството на правилото", + customFirst: "Игнориране на кеша за локални персонализирани правила", + rulesExample: "Пример за правила", + lastPage: "Достигната е последната страница", + lastPageTips: "Показване на съвети при достигане на последната страница" + } + }, + { + name: "Čeština", + match: ["cs"], + lang: { + enableDebug: "Povolit výstup ladění do konzole", + updateNotification: "Oznámení po aktualizaci pravidel", + disable: "Dočasně zakázat", + disableSite: "Přepnout stav zakázání", + disableSiteTips: "Na této stránce zakázáno.", + enableSiteTips: "Na této stránce povoleno.", + enable: "✅Povolit automatické otáčení stránek", + tempActive: "Dočasně aktivní", + toTop: "Zpět nahoru.", + toBottom: "Jít dolů.", + current: "Aktuální stránka.", + forceIframe: "Vynutit připojení k další stránce", + cancelForceIframe: "Zrušit vynucené připojení", + configure: "Konfigurovat Pagetual", + firstUpdate: "Klikněte sem pro inicializaci výchozího seznamu pravidel", + update: "Aktualizovat online pravidla", + click2update: "Klikněte pro aktualizaci pravidel z URL nyní", + loadNow: "Načíst další automaticky", + loadConfirm: "Kolik stránek chcete načíst? (0 znamená nekonečno)", + noNext: "Nenalezen žádný další odkaz, vytvořte nové pravidlo", + passSec: "Aktualizováno před #t# sekundami", + passMin: "Aktualizováno před #t# minutami", + passHour: "Aktualizováno před #t# hodinami", + passDay: "Aktualizováno před #t# dny", + cantDel: "Nelze odstranit vestavěná pravidla", + confirmDel: "Jste si jisti, že chcete toto pravidlo odstranit?", + updateSucc: "Aktualizace úspěšná", + beginUpdate: "Zahajuje se aktualizace, chvíli prosím počkejte", + customUrls: "Importovat URL pravidla Pagetual nebo AutoPagerize, jedno URL na řádek.", + customRules: "Zadejte vlastní pravidla. ✍️Přispějte pravidly", + save: "Uložit", + loadingText: "Načítání...", + opacity: "Neprůhlednost", + opacityPlaceholder: "0: skrýt oddělovač", + hideBar: "Skrýt oddělovač stránkování", + hideBarButNoStop: "Skrýt, ale nezastavit", + dbClick2Stop: "Dvojitým kliknutím na prázdné místo pozastavíte", + sortTitle: "Třídění se projeví po další aktualizaci pravidel", + autoRun: "Automatické povolení (režim černé listiny)", + autoLoadNum: "Množství pro přednačtené stránky", + turnRate: "Otočte na další stránku, když je méně než 【X】 násobek výšky stránky od zápatí", + inputPageNum: "Zadejte číslo stránky pro skok", + enableHistory: "Zapsat historii procházení po otočení stránky", + enableHistoryAfterInsert: "Zapsat historii procházení ihned po spojení, jinak zapsat po procházení", + contentVisibility: "Automaticky přepínat viditelnost obsahu pro zlepšení výkonu vykreslování", + initRun: "Otočit stránky ihned po otevření", + preload: "Přednačíst další stránku pro zrychlení", + click2ImportRule: "Klikněte pro import odkazu na základní pravidla a poté počkejte, dokud se aktualizace nedokončí: ", + forceAllBody: "Připojit celé tělo stránky?", + openInNewTab: "Otevřít URL adres přídavků v nové kartě", + importSucc: "Import dokončen", + import: "Importovat", + editCurrent: "Upravit pravidlo pro aktuální webovou stránku", + editBlacklist: "Upravit černou listinu URL, jeden záznam na řádek, podporuje zástupné znaky [?,*].", + upBtnImg: "Ikona zpět nahoru", + downBtnImg: "Ikona jít do zápatí", + sideControllerIcon: "Ikona bočního panelu", + loadingTextTitle: "Načítání", + dbClick2StopCtrl: "Klávesa Ctrl", + dbClick2StopAlt: "Klávesa Alt", + dbClick2StopShift: "Klávesa Shift", + dbClick2StopMeta: "Klávesa Meta", + dbClick2StopKey: "Klávesová zkratka", + pageElementCss: "Vlastní styl pro hlavní prvky stránky", + customCss: "Vlastní kompletní CSS", + firstAlert: "Neimportovali jste základní pravidlo, vyberte prosím vhodné pravidlo k importu", + picker: "Výběr prvků Pagetual", + closePicker: "Zavřít výběr Pagetual", + pickerPlaceholder: "Výběr prvků (Pouze pro pokročilé uživatele, jinak nechte prázdné)", + pickerCheck: "Zkontrolovat výběr a kopírovat", + switchSelector: "Kliknutím přepnete prvek", + gotoEdit: "Přejít na úpravu pravidla s aktuálním výběrem", + manualMode: "Zakázat spojování, ručně přejít na další stránku pomocí klávesy se šipkou doprava (nebo odeslat událost 'pagetual.next')", + clickMode: "Zakázat spojování, automaticky kliknout na další stránku při posunutí na konec stránky", + pageBarMenu: "Kliknutím na střed lišty stránky otevřete menu výběru", + nextSwitch: "Přepnout další odkaz", + arrowToScroll: "Stisknutím levé šipky se posunete zpět a pravou šipkou přejdete na stránku", + sideController: "Zobrazit ovládací panel stránkování v bočním panelu", + sideControllerScroll: "Přepnout posouvání", + sideControllerAlways: "Vždy zobrazit", + hideLoadingIcon: "Skrýt animaci načítání", + hideBarArrow: "Skrýt šipku pro lištu stránky", + duplicate: "Duplicitní Pagetual byl nainstalován, zkontrolujte svůj správce skriptů!", + forceStateIframe: "Vložit celou stránku jako iframe", + forceStateDynamic: "Načíst dynamický obsah přes iframe", + forceStateDisable: "Zakázat otáčení stránek на této stránce", + autoScrollRate: "Rychlost posouvání (1-1000)", + disableAutoScroll: "Zastavit automatické posouvání", + enableAutoScroll: "Povolit automatické posouvání", + toggleAutoScroll: "Přepnout automatické posouvání", + ruleRequest: "Žádost o pravidlo", + page: "Stránka ", + prevPage: "Předchozí stránka", + nextPage: "Další stránka", + errorRulesMustBeArray: "Pravidla musí být pole!", + errorJson: "Chyba JSON, zkontrolujte znovu!", + editSuccess: "Úspěšně upraveno", + errorWrongUrl: "Nesprávné URL, zkontrolujte znovu!", + errorAlreadyExists: "Pravidlo již existuje!", + settingsSaved: "Nastavení jsou uložena, obnovte pro zobrazení", + iframe: "Vynucené rozdělení pomocí iframe", + dynamic: "Dynamické načítání", + reloadPage: "Úprava dokončena, načíst znovu?", + copied: "Zkopírováno", + noValidContent: "Nebyl zjištěn žádný platný obsah, může být přítomna Captcha", + outOfDate: "Skript je zastaralý, aktualizujte prosím na nejnovější verzi.", + hideBarTips: "Skrýt lištu stránkování, přepnout pohlcující zážitek", + setConfigPage: "Nastavit aktuální stránku jako výchozí konfigurační stránku", + wedata2github: "Změnit adresu wedata na zrcadlovou adresu v repozitáři github", + addOtherProp: "Přidat vlastnosti pravidla", + addNextSelector: "Přidat obsah výběru jako nextLink", + addPageSelector: "Přidat obsah výběru jako pageElement", + propName: "Zadejte název vlastnosti pravidla", + propValue: "Zadejte hodnotu vlastnosti pravidla", + customFirst: "Ignorovat mezipaměť pro místní vlastní pravidla", + rulesExample: "Příklad pravidel", + lastPage: "Dosáhli jste poslední stránky", + lastPageTips: "Zobrazit tipy při dosažení poslední stránky" + } + }, + { + name: "Tiếng Việt", + match: ["vi"], + lang: { + enableDebug: "Bật đầu ra gỡ lỗi vào bảng điều khiển", + updateNotification: "Thông báo sau khi cập nhật quy tắc", + disable: "Tạm thời vô hiệu hóa", + disableSite: "Chuyển đổi trạng thái vô hiệu hóa", + disableSiteTips: "Đã vô hiệu hóa trên trang này.", + enableSiteTips: "Đã bật trên trang này.", + enable: "✅Bật tự động chuyển trang", + tempActive: "Tạm thời hoạt động", + toTop: "Quay lại đầu trang.", + toBottom: "Đi đến cuối trang.", + current: "Trang hiện tại.", + forceIframe: "Buộc tham gia trang tiếp theo", + cancelForceIframe: "Hủy bỏ buộc tham gia", + configure: "Cấu hình Pagetual", + firstUpdate: "Nhấp vào đây để khởi tạo danh sách quy tắc mặc định", + update: "Cập nhật quy tắc trực tuyến", + click2update: "Nhấp để cập nhật quy tắc từ url ngay bây giờ", + loadNow: "Tải trang tiếp theo tự động", + loadConfirm: "Bạn muốn tải bao nhiêu trang? (0 có nghĩa là vô hạn)", + noNext: "Không tìm thấy liên kết tiếp theo, vui lòng tạo quy tắc mới", + passSec: "Đã cập nhật #t# giây trước", + passMin: "Đã cập nhật #t# phút trước", + passHour: "Đã cập nhật #t# giờ trước", + passDay: "Đã cập nhật #t# ngày trước", + cantDel: "Không thể xóa các quy tắc cài sẵn", + confirmDel: "Bạn có chắc chắn muốn xóa quy tắc này không?", + updateSucc: "Cập nhật thành công", + beginUpdate: "Bắt đầu cập nhật, vui lòng đợi một lát", + customUrls: "Nhập URL quy tắc Pagetual hoặc AutoPagerize, mỗi URL một dòng.", + customRules: "Nhập các quy tắc tùy chỉnh. ✍️Đóng góp quy tắc", + save: "Lưu", + loadingText: "Đang tải...", + opacity: "Độ mờ", + opacityPlaceholder: "0: ẩn dấu phân cách", + hideBar: "Ẩn dấu phân cách phân trang", + hideBarButNoStop: "Ẩn nhưng không dừng", + dbClick2Stop: "Nhấp đúp vào khoảng trống để tạm dừng", + sortTitle: "Việc sắp xếp có hiệu lực sau khi cập nhật quy tắc tiếp theo", + autoRun: "Tự động bật (chế độ danh sách đen)", + autoLoadNum: "Số lượng trang tải trước", + turnRate: "Chuyển sang trang tiếp theo khi còn cách chân trang chưa đến 【X】 lần chiều cao trang", + inputPageNum: "Nhập số trang để chuyển đến", + enableHistory: "Ghi lại lịch sử duyệt web sau khi chuyển trang", + enableHistoryAfterInsert: "Ghi lại lịch sử duyệt web ngay sau khi ghép nối, nếu không thì ghi lại sau khi duyệt", + contentVisibility: "Tự động chuyển đổi khả năng hiển thị nội dung để cải thiện hiệu suất hiển thị", + initRun: "Chuyển trang ngay sau khi mở", + preload: "Tải trước trang tiếp theo để tăng tốc", + click2ImportRule: "Nhấp để nhập liên kết quy tắc cơ sở, sau đó đợi cho đến khi cập nhật hoàn tất: ", + forceAllBody: "Tham gia toàn bộ nội dung của trang?", + openInNewTab: "Mở các url bổ sung trong tab mới", + importSucc: "Nhập hoàn tất", + import: "Nhập", + editCurrent: "Chỉnh sửa quy tắc cho trang web hiện tại", + editBlacklist: "Chỉnh sửa danh sách đen url, mỗi mục một dòng, hỗ trợ ký tự đại diện [?,*].", + upBtnImg: "Biểu tượng quay lại đầu trang", + downBtnImg: "Biểu tượng đi đến chân trang", + sideControllerIcon: "Biểu tượng của thanh bên", + loadingTextTitle: "Đang tải", + dbClick2StopCtrl: "Phím Ctrl", + dbClick2StopAlt: "Phím Alt", + dbClick2StopShift: "Phím Shift", + dbClick2StopMeta: "Phím Meta", + dbClick2StopKey: "Phím tắt", + pageElementCss: "Kiểu tùy chỉnh cho các phần tử trang chính", + customCss: "CSS hoàn chỉnh tùy chỉnh", + firstAlert: "Bạn chưa nhập quy tắc cơ sở, vui lòng chọn quy tắc thích hợp để nhập", + picker: "Bộ chọn phần tử Pagetual", + closePicker: "Đóng bộ chọn Pagetual", + pickerPlaceholder: "Bộ chọn phần tử (Chỉ dành cho người dùng nâng cao, nếu không thì để trống)", + pickerCheck: "Kiểm tra bộ chọn và sao chép", + switchSelector: "Nhấp để chuyển đổi phần tử", + gotoEdit: "Chuyển đến chỉnh sửa quy tắc với bộ chọn hiện tại", + manualMode: "Vô hiệu hóa việc ghép nối, chuyển đến trang tiếp theo theo cách thủ công bằng phím mũi tên phải (hoặc gửi sự kiện 'pagetual.next')", + clickMode: "Vô hiệu hóa việc ghép nối, tự động nhấp vào trang tiếp theo khi cuộn đến cuối trang", + pageBarMenu: "Nhấp vào giữa thanh trang để mở menu bộ chọn", + nextSwitch: "Chuyển đổi liên kết tiếp theo", + arrowToScroll: "Nhấn mũi tên trái để cuộn lại và mũi tên phải để chuyển trang", + sideController: "Hiển thị thanh điều khiển phân trang trong thanh bên", + sideControllerScroll: "Chuyển đổi cuộn", + sideControllerAlways: "Luôn hiển thị", + hideLoadingIcon: "Ẩn hoạt ảnh tải", + hideBarArrow: "Ẩn mũi tên cho thanh trang", + duplicate: "Pagetual trùng lặp đã được cài đặt, hãy kiểm tra trình quản lý tập lệnh của bạn!", + forceStateIframe: "Nhúng toàn bộ trang dưới dạng iframe", + forceStateDynamic: "Tải nội dung động qua iframe", + forceStateDisable: "Vô hiệu hóa việc chuyển trang trên trang này", + autoScrollRate: "Tốc độ cuộn (1~1000)", + disableAutoScroll: "Dừng cuộn tự động", + enableAutoScroll: "Bật cuộn tự động", + toggleAutoScroll: "Chuyển đổi cuộn tự động", + ruleRequest: "Yêu cầu quy tắc", + page: "Trang ", + prevPage: "Trang trước", + nextPage: "Trang tiếp theo", + errorRulesMustBeArray: "Quy tắc phải là một mảng!", + errorJson: "Lỗi JSON, hãy kiểm tra lại!", + editSuccess: "Chỉnh sửa thành công", + errorWrongUrl: "URL sai, hãy kiểm tra lại!", + errorAlreadyExists: "Một quy tắc đã tồn tại!", + settingsSaved: "Cài đặt đã được lưu, hãy làm mới để xem", + iframe: "Tách bắt buộc bằng iframe", + dynamic: "Tải động", + reloadPage: "Chỉnh sửa hoàn tất, tải lại ngay bây giờ?", + copied: "Đã sao chép", + noValidContent: "Không phát hiện thấy nội dung hợp lệ, có thể có Captcha", + outOfDate: "Tập lệnh đã lỗi thời, vui lòng cập nhật lên phiên bản mới nhất.", + hideBarTips: "Ẩn thanh phân trang, chuyển đổi trải nghiệm đắm chìm", + setConfigPage: "Đặt trang hiện tại làm trang cấu hình mặc định", + wedata2github: "Thay đổi địa chỉ wedata thành địa chỉ nhân bản trong kho lưu trữ github", + addOtherProp: "Thêm thuộc tính quy tắc", + addNextSelector: "Thêm nội dung bộ chọn làm nextLink", + addPageSelector: "Thêm nội dung bộ chọn làm pageElement", + propName: "Nhập tên thuộc tính quy tắc", + propValue: "Nhập giá trị thuộc tính quy tắc", + customFirst: "Bỏ qua bộ nhớ cache cho các quy tắc tùy chỉnh cục bộ", + rulesExample: "Ví dụ về quy tắc", + lastPage: "Đã đến trang cuối cùng", + lastPageTips: "Hiển thị mẹo khi đến trang cuối cùng" + } + }, + { + name: "Polski", + match: ["pl"], + lang: { + enableDebug: "Włącz wyjście debugowania do konsoli", + updateNotification: "Powiadomienie po aktualizacji reguł", + disable: "Tymczasowo wyłącz", + disableSite: "Przełącz stan wyłączenia", + disableSiteTips: "Wyłączone na tej stronie.", + enableSiteTips: "Włączone na tej stronie.", + enable: "✅Włącz automatyczne przewracanie stron", + tempActive: "Tymczasowo aktywne", + toTop: "Powrót na górę.", + toBottom: "Przejdź na dół.", + current: "Bieżąca strona.", + forceIframe: "Wymuś dołączenie do następnej strony", + cancelForceIframe: "Anuluj wymuszone dołączenie", + configure: "Skonfiguruj Pagetual", + firstUpdate: "Kliknij tutaj, aby zainicjować domyślną listę reguł", + update: "Aktualizuj reguły online", + click2update: "Kliknij, aby zaktualizować reguły z adresu URL teraz", + loadNow: "Załaduj następną automatycznie", + loadConfirm: "Ile stron chcesz załadować? (0 oznacza nieskończoność)", + noNext: "Nie znaleziono następnego linku, utwórz nową regułę", + passSec: "Zaktualizowano #t# sekund temu", + passMin: "Zaktualizowano #t# minut temu", + passHour: "Zaktualizowano #t# godzin temu", + passDay: "Zaktualizowano #t# dni temu", + cantDel: "Nie można usunąć wbudowanych reguł", + confirmDel: "Czy na pewno chcesz usunąć tę regułę?", + updateSucc: "Aktualizacja zakończona powodzeniem", + beginUpdate: "Rozpoczynam aktualizację, proszę czekać", + customUrls: "Importuj adres URL reguły Pagetual lub AutoPagerize, jeden adres URL na linię.", + customRules: "Wprowadź niestandardowe reguły. ✍️Współtwórz reguły", + save: "Zapisz", + loadingText: "Ładowanie...", + opacity: "Przezroczystość", + opacityPlaceholder: "0: ukryj separator", + hideBar: "Ukryj separator paginacji", + hideBarButNoStop: "Ukryj, ale nie zatrzymuj", + dbClick2Stop: "Kliknij dwukrotnie w puste miejsce, aby wstrzymać", + sortTitle: "Sortowanie zacznie obowiązywać po następnej aktualizacji reguł", + autoRun: "Automatyczne włączanie (tryb czarnej listy)", + autoLoadNum: "Ilość stron do wstępnego załadowania", + turnRate: "Przewróć na następną stronę, gdy odległość od stopki jest mniejsza niż 【X】-krotność wysokości strony", + inputPageNum: "Wprowadź numer strony, aby przejść", + enableHistory: "Zapisuj historię przeglądania po przewróceniu strony", + enableHistoryAfterInsert: "Zapisuj historię przeglądania natychmiast po połączeniu, w przeciwnym razie zapisuj po przeglądaniu", + contentVisibility: "Automatycznie przełączaj widoczność zawartości, aby poprawić wydajność renderowania", + initRun: "Przewracaj strony natychmiast po otwarciu", + preload: "Wstępnie załaduj następną stronę, aby przyspieszyć", + click2ImportRule: "Kliknij, aby zaimportować link do podstawowych reguł, a następnie poczekaj na zakończenie aktualizacji: ", + forceAllBody: "Dołączyć całą treść strony?", + openInNewTab: "Otwórz adresy URL dodatków w nowej karcie", + importSucc: "Import zakończony", + import: "Importuj", + editCurrent: "Edytuj regułę dla bieżącej witryny", + editBlacklist: "Edytuj czarną listę adresów URL, jeden wpis na linię, obsługuje symbole wieloznaczne [?,*].", + upBtnImg: "Ikona powrotu na górę", + downBtnImg: "Ikona przejścia do stopki", + sideControllerIcon: "Ikona paska bocznego", + loadingTextTitle: "Ładowanie", + dbClick2StopCtrl: "Klawisz Ctrl", + dbClick2StopAlt: "Klawisz Alt", + dbClick2StopShift: "Klawisz Shift", + dbClick2StopMeta: "Klawisz Meta", + dbClick2StopKey: "Klawisz skrótu", + pageElementCss: "Niestandardowy styl dla głównych elementów strony", + customCss: "Niestandardowy kompletny CSS", + firstAlert: "Nie zaimportowałeś podstawowej reguły, wybierz odpowiednią regułę do zaimportowania", + picker: "Selektor elementów Pagetual", + closePicker: "Zamknij selektor Pagetual", + pickerPlaceholder: "Selektor elementów (Tylko dla zaawansowanych użytkowników, w przeciwnym razie pozostaw puste)", + pickerCheck: "Sprawdź selektor i skopiuj", + switchSelector: "Kliknij, aby przełączyć element", + gotoEdit: "Przejdź do edycji reguły z bieżącym selektorem", + manualMode: "Wyłącz łączenie, ręcznie przejdź do następnej strony za pomocą klawisza strzałki w prawo (lub wyślij zdarzenie 'pagetual.next')", + clickMode: "Wyłącz łączenie, automatycznie kliknij następną stronę po przewinięciu do końca strony", + pageBarMenu: "Kliknij środek paska strony, aby otworzyć menu selektora", + nextSwitch: "Przełącz następny link", + arrowToScroll: "Naciśnij lewą strzałkę, aby przewinąć do tyłu, a prawą strzałkę, aby przejść do przodu", + sideController: "Wyświetl pasek sterowania paginacją na pasku bocznym", + sideControllerScroll: "Przełączanie przewijania", + sideControllerAlways: "Zawsze pokazuj", + hideLoadingIcon: "Ukryj animację ładowania", + hideBarArrow: "Ukryj strzałkę paska strony", + duplicate: "Zainstalowano zduplikowany Pagetual, sprawdź menedżera skryptów!", + forceStateIframe: "Osadź całą stronę jako iframe", + forceStateDynamic: "Załaduj dynamiczną zawartość przez iframe", + forceStateDisable: "Wyłącz przewracanie stron na tej stronie", + autoScrollRate: "Prędkość przewijania (1-1000)", + disableAutoScroll: "Zatrzymaj automatyczne przewijanie", + enableAutoScroll: "Włącz automatyczne przewijanie", + toggleAutoScroll: "Przełącz automatyczne przewijanie", + ruleRequest: "Żądanie reguły", + page: "Strona ", + prevPage: "Poprzednia strona", + nextPage: "Następna strona", + errorRulesMustBeArray: "Reguły muszą być tablicą!", + errorJson: "Błąd JSON, sprawdź ponownie!", + editSuccess: "Edycja zakończona pomyślnie", + errorWrongUrl: "Błędny adres URL, sprawdź ponownie!", + errorAlreadyExists: "Reguła już istnieje!", + settingsSaved: "Ustawienia zostały zapisane, odśwież, aby zobaczyć", + iframe: "Wymuszony podział przez iframe", + dynamic: "Dynamiczne ładowanie", + reloadPage: "Edycja zakończona, przeładować teraz?", + copied: "Skopiowano", + noValidContent: "Nie wykryto prawidłowej zawartości, może być obecna Captcha", + outOfDate: "Skrypt jest przestarzały, zaktualizuj do najnowszej wersji.", + hideBarTips: "Ukryj pasek paginacji, przełącz na tryb immersyjny", + setConfigPage: "Ustaw bieżącą stronę jako domyślną stronę konfiguracji", + wedata2github: "Zmień adres wedata na adres lustrzany w repozytorium github", + addOtherProp: "Dodaj właściwości reguły", + addNextSelector: "Dodaj zawartość selektora jako nextLink", + addPageSelector: "Dodaj zawartość selektora jako pageElement", + propName: "Wprowadź nazwę właściwości reguły", + propValue: "Wprowadź wartość właściwości reguły", + customFirst: "Ignoruj pamięć podręczną dla lokalnych niestandardowych reguł", + rulesExample: "Przykład reguł", + lastPage: "Osiągnięto ostatnią stronę", + lastPageTips: "Pokaż wskazówki po osiągnięciu ostatniej strony" + } + }, + { + name: "Українська", + match: ["uk"], + lang: { + enableDebug: "Увімкнути вивід налагодження в консоль", + updateNotification: "Сповіщення після оновлення правил", + disable: "Тимчасово вимкнути", + disableSite: "Перемкнути стан вимкнення", + disableSiteTips: "Вимкнено на цьому сайті.", + enableSiteTips: "Увімкнено на цьому сайті.", + enable: "✅Увімкнути автоматичне перегортання сторінок", + tempActive: "Тимчасово активний", + toTop: "Повернутися нагору.", + toBottom: "Перейти вниз.", + current: "Поточна сторінка.", + forceIframe: "Примусово приєднати наступну сторінку", + cancelForceIframe: "Скасувати примусове приєднання", + configure: "Налаштувати Pagetual", + firstUpdate: "Натисніть тут, щоб ініціалізувати стандартний список правил", + update: "Оновити онлайн-правила", + click2update: "Натисніть, щоб оновити правила з URL зараз", + loadNow: "Завантажити наступну автоматично", + loadConfirm: "Скільки сторінок ви хочете завантажити? (0 означає нескінченно)", + noNext: "Не знайдено наступного посилання, створіть нове правило", + passSec: "Оновлено #t# секунд тому", + passMin: "Оновлено #t# хвилин тому", + passHour: "Оновлено #t# годин тому", + passDay: "Оновлено #t# днів тому", + cantDel: "Неможливо видалити вбудовані правила", + confirmDel: "Ви впевнені, що хочете видалити це правило?", + updateSucc: "Оновлення успішне", + beginUpdate: "Починається оновлення, зачекайте хвилинку", + customUrls: "Імпортувати URL правила Pagetual або AutoPagerize, один URL на рядок.", + customRules: "Введіть власні правила. ✍️Додайте правила", + save: "Зберегти", + loadingText: "Завантаження...", + opacity: "Непрозорість", + opacityPlaceholder: "0: приховати роздільник", + hideBar: "Приховати роздільник пагінації", + hideBarButNoStop: "Приховати, але не зупиняти", + dbClick2Stop: "Двічі клацніть на порожньому місці, щоб призупинити", + sortTitle: "Сортування набуде чинності після наступного оновлення правил", + autoRun: "Автоматичне ввімкнення (режим чорного списку)", + autoLoadNum: "Кількість для попередньо завантажених сторінок", + turnRate: "Перегорніть на наступну сторінку, коли до нижнього колонтитула залишиться менше 【X】 висот сторінки", + inputPageNum: "Введіть номер сторінки для переходу", + enableHistory: "Записувати історію переглядів після перегортання сторінки", + enableHistoryAfterInsert: "Записувати історію переглядів одразу після з'єднання, інакше записувати після перегляду", + contentVisibility: "Автоматично перемикати видимість вмісту для покращення продуктивності рендерингу", + initRun: "Перегортати сторінки одразу після відкриття", + preload: "Попередньо завантажити наступну сторінку для прискорення", + click2ImportRule: "Натисніть, щоб імпортувати посилання на базові правила, а потім зачекайте, доки оновлення не завершиться: ", + forceAllBody: "Приєднати все тіло сторінки?", + openInNewTab: "Відкрити URL-адреси доповнень у новій вкладці", + importSucc: "Імпорт завершено", + import: "Імпортувати", + editCurrent: "Редагувати правило для поточного веб-сайту", + editBlacklist: "Редагувати чорний список URL-адрес, один запис на рядок, підтримує символи підстановки [?,*].", + upBtnImg: "Іконка повернення нагору", + downBtnImg: "Іконка переходу до нижнього колонтитула", + sideControllerIcon: "Іконка бічної панелі", + loadingTextTitle: "Завантаження", + dbClick2StopCtrl: "Клавіша Ctrl", + dbClick2StopAlt: "Клавіша Alt", + dbClick2StopShift: "Клавіша Shift", + dbClick2StopMeta: "Клавіша Meta", + dbClick2StopKey: "Клавіша швидкого доступу", + pageElementCss: "Власний стиль для основних елементів сторінки", + customCss: "Власний повний CSS", + firstAlert: "Ви не імпортували базове правило, будь ласка, виберіть відповідне правило для імпорту", + picker: "Вибір елементів Pagetual", + closePicker: "Закрити вибір Pagetual", + pickerPlaceholder: "Вибір елементів (Лише для досвідчених користувачів, інакше залиште порожнім)", + pickerCheck: "Перевірити селектор і скопіювати", + switchSelector: "Натисніть, щоб перемкнути елемент", + gotoEdit: "Перейти до редагування правила з поточним селектором", + manualMode: "Вимкнути з'єднання, вручну переходити на наступну сторінку за допомогою клавіші зі стрілкою вправо (або надіслати подію 'pagetual.next')", + clickMode: "Вимкнути з'єднання, автоматично клацати на наступну сторінку при прокручуванні до кінця сторінки", + pageBarMenu: "Натисніть на центр панелі сторінки, щоб відкрити меню вибору", + nextSwitch: "Перемкнути наступне посилання", + arrowToScroll: "Натисніть ліву стрілку, щоб прокрутити назад, і праву стрілку, щоб перейти на сторінку вперед", + sideController: "Відображати панель керування пагінацією в бічній панелі", + sideControllerScroll: "Перемикання прокрутки", + sideControllerAlways: "Завжди показувати", + hideLoadingIcon: "Приховати анімацію завантаження", + hideBarArrow: "Приховати стрілку для панелі сторінки", + duplicate: "Встановлено дублікат Pagetual, перевірте свій менеджер скриптів!", + forceStateIframe: "Вбудувати повну сторінку як iframe", + forceStateDynamic: "Завантажувати динамічний вміст через iframe", + forceStateDisable: "Вимкнути перегортання сторінок на цьому сайті", + autoScrollRate: "Швидкість прокрутки (1-1000)", + disableAutoScroll: "Зупинити автоматичну прокрутку", + enableAutoScroll: "Увімкнути автоматичну прокрутку", + toggleAutoScroll: "Перемкнути автоматичну прокрутку", + ruleRequest: "Запит на правило", + page: "Сторінка ", + prevPage: "Попередня сторінка", + nextPage: "Наступна сторінка", + errorRulesMustBeArray: "Правила повинні бути масивом!", + errorJson: "Помилка JSON, перевірте ще раз!", + editSuccess: "Відредаговано успішно", + errorWrongUrl: "Неправильна URL-адреса, перевірте ще раз!", + errorAlreadyExists: "Правило вже існує!", + settingsSaved: "Налаштування збережено, оновіть, щоб переглянути", + iframe: "Примусове розділення за допомогою iframe", + dynamic: "Динамічне завантаження", + reloadPage: "Редагування завершено, перезавантажити зараз?", + copied: "Скопійовано", + noValidContent: "Не виявлено дійсного вмісту, можливо, є Captcha", + outOfDate: "Скрипт застарів, оновіть до останньої версії.", + hideBarTips: "Приховати панель пагінації, перемкнути на захоплюючий досвід", + setConfigPage: "Встановити поточну сторінку як сторінку конфігурації за замовчуванням", + wedata2github: "Змінити адресу wedata на дзеркальну адресу в репозиторії github", + addOtherProp: "Додати властивості правила", + addNextSelector: "Додати вміст селектора як nextLink", + addPageSelector: "Додати вміст селектора як pageElement", + propName: "Введіть назву властивості правила", + propValue: "Введіть значення властивості правила", + customFirst: "Ігнорувати кеш для локальних власних правил", + rulesExample: "Приклад правил", + lastPage: "Досягнуто останньої сторінки", + lastPageTips: "Показувати поради при досягненні останньої сторінки" + } + }, + { + name: "Türkçe", + match: ["tr"], + lang: { + enableDebug: "Konsola hata ayıklama çıktısını etkinleştir", + updateNotification: "Kurallar güncellendikten sonra bildirim", + disable: "Geçici olarak devre dışı bırak", + disableSite: "Devre dışı bırakma durumunu değiştir", + disableSiteTips: "Bu sitede devre dışı bırakıldı.", + enableSiteTips: "Bu sitede etkinleştirildi.", + enable: "✅Otomatik sayfa çevirmeyi etkinleştir", + tempActive: "Geçici olarak aktif", + toTop: "Başa dön.", + toBottom: "Sona git.", + current: "Mevcut sayfa.", + forceIframe: "Sonraki sayfaya katılmaya zorla", + cancelForceIframe: "Zorla katılmayı iptal et", + configure: "Pagetual'ı yapılandır", + firstUpdate: "Varsayılan kural listesini başlatmak için buraya tıklayın", + update: "Çevrimiçi kuralları güncelle", + click2update: "Kuralları şimdi URL'den güncellemek için tıkla", + loadNow: "Sonrakini otomatik olarak yükle", + loadConfirm: "Kaç sayfa yüklemek istiyorsunuz? (0 sonsuz demektir)", + noNext: "Sonraki bağlantı bulunamadı, lütfen yeni bir kural oluşturun", + passSec: "#t# saniye önce güncellendi", + passMin: "#t# dakika önce güncellendi", + passHour: "#t# saat önce güncellendi", + passDay: "#t# gün önce güncellendi", + cantDel: "Yerleşik kurallar silinemez", + confirmDel: "Bu kuralı silmek istediğinizden emin misiniz?", + updateSucc: "Güncelleme başarılı", + beginUpdate: "Güncelleme başlıyor, lütfen bir dakika bekleyin", + customUrls: "Pagetual veya AutoPagerize kural URL'sini içe aktarın, her satıra bir URL.", + customRules: "Özel kuralları girin. ✍️Kurallara katkıda bulunun", + save: "Kaydet", + loadingText: "Yükleniyor...", + opacity: "Opaklık", + opacityPlaceholder: "0: ayırıcıyı gizle", + hideBar: "Sayfalandırma ayırıcısını gizle", + hideBarButNoStop: "Gizle ama durdurma", + dbClick2Stop: "Duraklatmak için boş alana çift tıklayın", + sortTitle: "Sıralama bir sonraki kural güncellemesinden sonra etkili olur", + autoRun: "Otomatik etkinleştir (kara liste modu)", + autoLoadNum: "Önceden yüklenecek sayfa miktarı", + turnRate: "Altbilgiden sayfa yüksekliğinin 【X】 katından daha az olduğunda sonraki sayfaya geçin", + inputPageNum: "Atlamak için sayfa numarasını girin", + enableHistory: "Sayfa çevirdikten sonra tarama geçmişini yaz", + enableHistoryAfterInsert: "Birleştirmeden hemen sonra tarama geçmişini yaz, aksi takdirde taramadan sonra yaz", + contentVisibility: "Oluşturma performansını iyileştirmek için içerik görünürlüğünü otomatik olarak değiştir", + initRun: "Açtıktan hemen sonra sayfaları çevir", + preload: "Hızlandırmak için sonraki sayfayı önceden yükle", + click2ImportRule: "Temel kurallar bağlantısını içe aktarmak için tıklayın ve ardından güncelleme tamamlanana kadar bekleyin: ", + forceAllBody: "Sayfanın tam gövdesine katılsın mı?", + openInNewTab: "Eklerin URL'lerini yeni sekmede aç", + importSucc: "İçe aktarma tamamlandı", + import: "İçe aktar", + editCurrent: "Mevcut web sitesi için kuralı düzenle", + editBlacklist: "URL kara listesini düzenleyin, her satıra bir giriş, [?,*] joker karakterlerini destekler.", + upBtnImg: "Başa dön simgesi", + downBtnImg: "Altbilgiye git simgesi", + sideControllerIcon: "Kenar çubuğu simgesi", + loadingTextTitle: "Yükleniyor", + dbClick2StopCtrl: "Ctrl tuşu", + dbClick2StopAlt: "Alt tuşu", + dbClick2StopShift: "Shift tuşu", + dbClick2StopMeta: "Meta tuşu", + dbClick2StopKey: "Kısayol tuşu", + pageElementCss: "Ana sayfa öğeleri için özel stil", + customCss: "Özel tam CSS", + firstAlert: "Temel kuralı içe aktarmadınız, lütfen içe aktarmak için uygun kuralı seçin", + picker: "Pagetual öğe seçici", + closePicker: "Pagetual seçiciyi kapat", + pickerPlaceholder: "Öğe seçici (Yalnızca ileri düzey kullanıcılar, aksi takdirde boş bırakın)", + pickerCheck: "Seçiciyi kontrol et ve kopyala", + switchSelector: "Öğeyi değiştirmek için tıkla", + gotoEdit: "Mevcut seçiciyle kuralı düzenlemeye git", + manualMode: "Birleştirmeyi devre dışı bırak, sağ ok tuşunu kullanarak sonraki sayfaya manuel olarak ilerle (veya 'pagetual.next' olayını gönder)", + clickMode: "Birleştirmeyi devre dışı bırak, sayfanın sonuna kaydırıldığında sonraki sayfayı otomatik olarak tıkla", + pageBarMenu: "Seçici menüsünü açmak için sayfa çubuğunun ortasına tıklayın", + nextSwitch: "Sonraki bağlantıyı değiştir", + arrowToScroll: "Geri kaydırmak için sol oka, sayfayı ilerletmek için sağ oka basın", + sideController: "Sayfalandırma kontrol çubuğunu kenar çubuğunda göster", + sideControllerScroll: "Kaydırmayı değiştir", + sideControllerAlways: "Her zaman göster", + hideLoadingIcon: "Yükleme animasyonunu gizle", + hideBarArrow: "Sayfa çubuğu için oku gizle", + duplicate: "Yinelenen Pagetual yüklendi, komut dosyası yöneticinizi kontrol edin!", + forceStateIframe: "Tam sayfayı iframe olarak göm", + forceStateDynamic: "Dinamik içeriği iframe aracılığıyla yükle", + forceStateDisable: "Bu sitede sayfa çevirmeyi devre dışı bırak", + autoScrollRate: "Kaydırma hızı (1-1000)", + disableAutoScroll: "Otomatik Kaydırmayı Durdur", + enableAutoScroll: "Otomatik Kaydırmayı Etkinleştir", + toggleAutoScroll: "Otomatik Kaydırmayı Değiştir", + ruleRequest: "Kural İsteği", + page: "Sayfa ", + prevPage: "Önceki sayfa", + nextPage: "Sonraki sayfa", + errorRulesMustBeArray: "Kurallar bir Dizi olmalıdır!", + errorJson: "JSON hatası, Tekrar kontrol edin!", + editSuccess: "Başarıyla düzenlendi", + errorWrongUrl: "Yanlış URL, Tekrar kontrol edin!", + errorAlreadyExists: "Bir kural zaten var!", + settingsSaved: "Ayarlar kaydedildi, görüntülemek için yenileyin", + iframe: "Iframe tarafından zorla bölündü", + dynamic: "Dinamik yükleme", + reloadPage: "Düzenleme tamamlandı, şimdi yeniden yüklensin mi?", + copied: "Kopyalandı", + noValidContent: "Geçerli içerik algılanmadı, bir Captcha olabilir", + outOfDate: "Komut dosyası güncel değil, lütfen en son sürüme güncelleyin.", + hideBarTips: "Sayfalandırma çubuğunu gizle, sürükleyici deneyime geç", + setConfigPage: "Mevcut sayfayı varsayılan yapılandırma sayfası olarak ayarla", + wedata2github: "Wedata adresini github deposundaki ayna adresine değiştirin", + addOtherProp: "Kural özellikleri ekle", + addNextSelector: "Seçici içeriğini nextLink olarak ekle", + addPageSelector: "Seçici içeriğini pageElement olarak ekle", + propName: "Kural özelliği adını girin", + propValue: "Kural özelliği değerini girin", + customFirst: "Yerel özel kurallar için önbelleği yoksay", + rulesExample: "Kurallar Örneği", + lastPage: "Son sayfaya ulaşıldı", + lastPageTips: "Son sayfaya ulaşıldığında ipuçları göster" + } + }, + { + name: "Nederlands", + match: ["nl"], + lang: { + enableDebug: "Foutopsporingsuitvoer naar console inschakelen", + updateNotification: "Melding nadat regels zijn bijgewerkt", + disable: "Tijdelijk uitschakelen", + disableSite: "Uitgeschakelde status omschakelen", + disableSiteTips: "Uitgeschakeld op deze site.", + enableSiteTips: "Ingeschakeld op deze site.", + enable: "✅Automatisch pagina's omslaan inschakelen", + tempActive: "Tijdelijk actief", + toTop: "Terug naar boven.", + toBottom: "Ga naar beneden.", + current: "Huidige pagina.", + forceIframe: "Dwingen om volgende pagina te koppelen", + cancelForceIframe: "Gedwongen koppeling annuleren", + configure: "Pagetual configureren", + firstUpdate: "Klik hier om de standaardregellijst te initialiseren", + update: "Online regels bijwerken", + click2update: "Klik om regels nu vanaf URL bij te werken", + loadNow: "Laad volgende automatisch", + loadConfirm: "Hoeveel pagina's wilt u laden? (0 betekent oneindig)", + noNext: "Geen volgende link gevonden, maak een nieuwe regel", + passSec: "#t# seconden geleden bijgewerkt", + passMin: "#t# minuten geleden bijgewerkt", + passHour: "#t# uur geleden bijgewerkt", + passDay: "#t# dagen geleden bijgewerkt", + cantDel: "Ingebouwde regels kunnen niet worden verwijderd", + confirmDel: "Weet u zeker dat u deze regel wilt verwijderen?", + updateSucc: "Update geslaagd", + beginUpdate: "Start update, een ogenblik geduld", + customUrls: "Importeer Pagetual of AutoPagerize regel-URL, één URL per regel.", + customRules: "Voer aangepaste regels in. ✍️Draag regels bij", + save: "Opslaan", + loadingText: "Laden...", + opacity: "Dekking", + opacityPlaceholder: "0: verberg scheidingsteken", + hideBar: "Verberg het pagineringsscheidingsteken", + hideBarButNoStop: "Verbergen maar niet stoppen", + dbClick2Stop: "Dubbelklik op de lege ruimte om te pauzeren", + sortTitle: "Sorteren wordt van kracht na de volgende regelupdate", + autoRun: "Automatisch inschakelen (zwarte lijst-modus)", + autoLoadNum: "Aantal voor vooraf geladen pagina's", + turnRate: "Sla de volgende pagina om wanneer deze minder dan 【X】 keer de paginahoogte van de voettekst is", + inputPageNum: "Voer paginanummer in om te springen", + enableHistory: "Schrijf browsegeschiedenis na het omslaan van de pagina", + enableHistoryAfterInsert: "Schrijf browsegeschiedenis onmiddellijk na het splitsen, anders schrijven na het browsen", + contentVisibility: "Schakel automatisch de zichtbaarheid van inhoud om de renderprestaties te verbeteren", + initRun: "Sla pagina's onmiddellijk na het openen om", + preload: "Laad de volgende pagina vooraf om te versnellen", + click2ImportRule: "Klik om de link met basisregels te importeren en wacht vervolgens tot de update is voltooid: ", + forceAllBody: "Volledige body van de pagina koppelen?", + openInNewTab: "Open URL's van toevoegingen in een nieuw tabblad", + importSucc: "Importeren voltooid", + import: "Importeren", + editCurrent: "Regel voor huidige website bewerken", + editBlacklist: "Bewerk de URL-zwarte lijst, één item per regel, ondersteunt [?,*] jokertekens.", + upBtnImg: "Pictogram terug naar boven", + downBtnImg: "Pictogram ga naar voettekst", + sideControllerIcon: "Pictogram zijbalk", + loadingTextTitle: "Laden", + dbClick2StopCtrl: "Ctrl-toets", + dbClick2StopAlt: "Alt-toets", + dbClick2StopShift: "Shift-toets", + dbClick2StopMeta: "Meta-toets", + dbClick2StopKey: "Sneltoets", + pageElementCss: "Aangepaste stijl voor hoofdpagina-elementen", + customCss: "Aangepaste volledige CSS", + firstAlert: "U heeft de basisregel niet geïmporteerd, selecteer de juiste regel om te importeren", + picker: "Pagetual-elementenkiezer", + closePicker: "Pagetual-kiezer sluiten", + pickerPlaceholder: "Elementenkiezer (Alleen voor gevorderde gebruikers, laat anders leeg)", + pickerCheck: "Controleer kiezer en kopieer", + switchSelector: "Klik om van element te wisselen", + gotoEdit: "Ga naar regel bewerken met huidige kiezer", + manualMode: "Schakel splitsen uit, ga handmatig naar de volgende pagina met de rechterpijltoets (of verstuur gebeurtenis 'pagetual.next')", + clickMode: "Schakel splitsen uit, klik automatisch op de volgende pagina bij het scrollen naar het einde van de pagina", + pageBarMenu: "Klik op het midden van de paginabalk om het kiezermenu te openen", + nextSwitch: "Wissel volgende link", + arrowToScroll: "Druk op de linkerpijl om terug te scrollen en op de rechterpijl om naar de volgende pagina te gaan", + sideController: "Toon de pagineringsbalk in de zijbalk", + sideControllerScroll: "Scroll-schakelaar", + sideControllerAlways: "Altijd tonen", + hideLoadingIcon: "Verberg laadanimatie", + hideBarArrow: "Verberg pijl voor paginabalk", + duplicate: "Dubbele Pagetual is geïnstalleerd, controleer uw scriptmanager!", + forceStateIframe: "Volledige pagina insluiten als iframe", + forceStateDynamic: "Laad dynamische inhoud via iframe", + forceStateDisable: "Schakel het omslaan van pagina's op deze site uit", + autoScrollRate: "Scrollsnelheid (1-1000)", + disableAutoScroll: "Stop automatisch scrollen", + enableAutoScroll: "Schakel automatisch scrollen in", + toggleAutoScroll: "Schakel automatisch scrollen om", + ruleRequest: "Regelverzoek", + page: "Pagina ", + prevPage: "Vorige pagina", + nextPage: "Volgende pagina", + errorRulesMustBeArray: "Regels moeten een array zijn!", + errorJson: "JSON-fout, controleer opnieuw!", + editSuccess: "Succesvol bewerkt", + errorWrongUrl: "Verkeerde URL, controleer opnieuw!", + errorAlreadyExists: "Er bestaat al een regel!", + settingsSaved: "De instellingen zijn opgeslagen, ververs om te bekijken", + iframe: "Gedwongen gesplitst door iframe", + dynamic: "Dynamisch laden", + reloadPage: "Bewerking voltooid, nu opnieuw laden?", + copied: "Gekopieerd", + noValidContent: "Geen geldige inhoud gedetecteerd, er is mogelijk een Captcha aanwezig", + outOfDate: "Het script is verouderd, update naar de nieuwste versie.", + hideBarTips: "Verberg de pagineringsbalk, schakel de meeslepende ervaring om", + setConfigPage: "Stel de huidige pagina in als de standaardconfiguratiepagina", + wedata2github: "Wijzig het wedata-adres in het spiegeladres in de github-repository", + addOtherProp: "Voeg regeleigenschappen toe", + addNextSelector: "Voeg kiezerinhoud toe als nextLink", + addPageSelector: "Voeg kiezerinhoud toe als pageElement", + propName: "Voer de naam van de regeleigenschap in", + propValue: "Voer de waarde van de regeleigenschap in", + customFirst: "Cache negeren voor lokale aangepaste regels", + rulesExample: "Voorbeeld van regels", + lastPage: "Laatste pagina bereikt", + lastPageTips: "Toon tips bij het bereiken van de laatste pagina" + } + }, + { + name: "Dansk", + match: ["da"], + lang: { + enableDebug: "Aktivér fejlfindingsoutput til konsollen", + updateNotification: "Meddelelse efter opdatering af regler", + disable: "Deaktiver midlertidigt", + disableSite: "Skift deaktiveret tilstand", + disableSiteTips: "Deaktiveret på dette websted.", + enableSiteTips: "Aktiveret på dette websted.", + enable: "✅Aktivér automatisk sidevending", + tempActive: "Midlertidigt aktiv", + toTop: "Tilbage til toppen.", + toBottom: "Gå til bunden.", + current: "Nuværende side.", + forceIframe: "Tving tilslutning til næste side", + cancelForceIframe: "Annuller tvungen tilslutning", + configure: "Konfigurer Pagetual", + firstUpdate: "Klik her for at initialisere standardregellisten", + update: "Opdater onlineregler", + click2update: "Klik for at opdatere regler fra URL nu", + loadNow: "Indlæs næste automatisk", + loadConfirm: "Hvor mange sider vil du indlæse? (0 betyder uendelig)", + noNext: "Intet næste link fundet, opret en ny regel", + passSec: "Opdateret for #t# sekunder siden", + passMin: "Opdateret for #t# minutter siden", + passHour: "Opdateret for #t# timer siden", + passDay: "Opdateret for #t# dage siden", + cantDel: "Kan ikke slette indbyggede regler", + confirmDel: "Er du sikker på, at du vil slette denne regel?", + updateSucc: "Opdatering lykkedes", + beginUpdate: "Starter opdatering, vent venligst et øjeblik", + customUrls: "Importer Pagetual- eller AutoPagerize-regel-URL, én URL pr. linje.", + customRules: "Indtast brugerdefinerede regler. ✍️Bidrag med regler", + save: "Gem", + loadingText: "Indlæser...", + opacity: "Opacitet", + opacityPlaceholder: "0: skjul afstandsstykke", + hideBar: "Skjul pagineringsafstandsstykket", + hideBarButNoStop: "Skjul, men stop ikke", + dbClick2Stop: "Dobbeltklik på det tomme rum for at sætte på pause", + sortTitle: "Sortering træder i kraft efter næste regelopdatering", + autoRun: "Automatisk aktivering (sortlistetilstand)", + autoLoadNum: "Antal for forudindlæste sider", + turnRate: "Vend til næste side, når den er mindre end 【X】 gange sidehøjden fra sidefoden", + inputPageNum: "Indtast sidetal for at hoppe", + enableHistory: "Skriv browserhistorik efter sidevending", + enableHistoryAfterInsert: "Skriv browserhistorik umiddelbart efter splejsning, ellers skriv efter browsing", + contentVisibility: "Skift automatisk indholdssynlighed for at forbedre gengivelsesydelsen", + initRun: "Vend sider umiddelbart efter åbning", + preload: "Forudindlæs næste side for at fremskynde", + click2ImportRule: "Klik for at importere link til grundregler, og vent derefter, indtil opdateringen er fuldført: ", + forceAllBody: "Tilslut hele sidens krop?", + openInNewTab: "Åbn URL'er for tilføjelser i ny fane", + importSucc: "Import fuldført", + import: "Importer", + editCurrent: "Rediger regel for nuværende websted", + editBlacklist: "Rediger URL-sortlisten, én post pr. linje, understøtter [?,*] jokertegn.", + upBtnImg: "Ikon for tilbage til toppen", + downBtnImg: "Ikon for at gå til sidefod", + sideControllerIcon: "Sidebjælkeikon", + loadingTextTitle: "Indlæser", + dbClick2StopCtrl: "Ctrl-tast", + dbClick2StopAlt: "Alt-tast", + dbClick2StopShift: "Shift-tast", + dbClick2StopMeta: "Meta-tast", + dbClick2StopKey: "Genvejstast", + pageElementCss: "Brugerdefineret stil for hovedsideelementer", + customCss: "Brugerdefineret komplet CSS", + firstAlert: "Du har ikke importeret grundreglen, vælg den relevante regel at importere", + picker: "Pagetual-elementvælger", + closePicker: "Luk Pagetual-vælger", + pickerPlaceholder: "Elementvælger (Kun avancerede brugere, ellers lad være tomt)", + pickerCheck: "Kontroller vælger og kopier", + switchSelector: "Klik for at skifte element", + gotoEdit: "Gå til redigeringsregel med nuværende vælger", + manualMode: "Deaktiver splejsning, gå manuelt frem til næste side ved hjælp af højre piletast (eller send hændelsen 'pagetual.next')", + clickMode: "Deaktiver splejsning, klik automatisk på næste side, når du ruller til slutningen af siden", + pageBarMenu: "Klik på midten af sidebjælken for at åbne vælgermenuen", + nextSwitch: "Skift næste link", + arrowToScroll: "Tryk på venstre pil for at rulle tilbage og højre pil for at gå frem en side", + sideController: "Vis pagineringskontrolbjælken i sidebjælken", + sideControllerScroll: "Rul-skift", + sideControllerAlways: "Vis altid", + hideLoadingIcon: "Skjul indlæsningsanimation", + hideBarArrow: "Skjul pil for sidebjælke", + duplicate: "Duplikat Pagetual er blevet installeret, tjek din scriptmanager!", + forceStateIframe: "Integrer hele siden som en iframe", + forceStateDynamic: "Indlæs dynamisk indhold via iframe", + forceStateDisable: "Deaktiver sidevending på dette websted", + autoScrollRate: "Rullehastighed (1-1000)", + disableAutoScroll: "Stop automatisk rulning", + enableAutoScroll: "Aktivér automatisk rulning", + toggleAutoScroll: "Skift automatisk rulning", + ruleRequest: "Regelanmodning", + page: "Side ", + prevPage: "Forrige side", + nextPage: "Næste side", + errorRulesMustBeArray: "Regler skal være en matrix!", + errorJson: "JSON-fejl, tjek igen!", + editSuccess: "Redigering lykkedes", + errorWrongUrl: "Forkert URL, tjek igen!", + errorAlreadyExists: "En regel eksisterer allerede!", + settingsSaved: "Indstillingerne er gemt, opdater for at se", + iframe: "Tvunget opdelt af iframe", + dynamic: "Dynamisk indlæsning", + reloadPage: "Redigering fuldført, genindlæs nu?", + copied: "Kopieret", + noValidContent: "Intet gyldigt indhold fundet, en Captcha kan være til stede", + outOfDate: "Scriptet er forældet, opdater venligst til den nyeste version.", + hideBarTips: "Skjul pagineringsbjælken, skift til en fordybende oplevelse", + setConfigPage: "Indstil den aktuelle side som standardkonfigurationsside", + wedata2github: "Skift wedata-adressen til spejladressen i github-depotet", + addOtherProp: "Tilføj regelegenskaber", + addNextSelector: "Tilføj vælgerindhold som nextLink", + addPageSelector: "Tilføj vælgerindhold som pageElement", + propName: "Indtast regelegenskabsnavn", + propValue: "Indtast regelegenskabsværdi", + customFirst: "Ignorer cache for lokale brugerdefinerede regler", + rulesExample: "Regeleksempel", + lastPage: "Nåede den sidste side", + lastPageTips: "Vis tips, når du når den sidste side" + } + }, + { + name: "Français (Canada)", + match: ["fr-CA"], + lang: { + enableDebug: "Activer la sortie de débogage dans la console", + updateNotification: "Notification après la mise à jour des règles", + disable: "Désactiver temporairement", + disableSite: "Basculer l'état de désactivation", + disableSiteTips: "Désactivé sur ce site.", + enableSiteTips: "Activé sur ce site.", + enable: "✅Activer le changement de page automatique", + tempActive: "Temporairement actif", + toTop: "Retour en haut.", + toBottom: "Aller en bas.", + current: "Page actuelle.", + forceIframe: "Forcer la jonction de la page suivante", + cancelForceIframe: "Annuler la jonction forcée", + configure: "Configurer Pagetual", + firstUpdate: "Cliquez ici pour initialiser la liste de règles par défaut", + update: "Mettre à jour les règles en ligne", + click2update: "Cliquez pour mettre à jour les règles depuis l'URL maintenant", + loadNow: "Charger la suite automatiquement", + loadConfirm: "Combien de pages voulez-vous charger ? (0 pour infini)", + noNext: "Aucun lien suivant trouvé, veuillez créer une nouvelle règle", + passSec: "Mis à jour il y a #t# secondes", + passMin: "Mis à jour il y a #t# minutes", + passHour: "Mis à jour il y a #t# heures", + passDay: "Mis à jour il y a #t# jours", + cantDel: "Impossible de supprimer les règles intégrées", + confirmDel: "Êtes-vous sûr de vouloir supprimer cette règle ?", + updateSucc: "Mise à jour réussie", + beginUpdate: "Début de la mise à jour, veuillez patienter", + customUrls: "Importer l'URL des règles Pagetual ou AutoPagerize, une URL par ligne.", + customRules: "Saisir des règles personnalisées. ✍️Contribuer aux règles", + save: "Enregistrer", + loadingText: "Chargement en cours...", + opacity: "Opacité", + opacityPlaceholder: "0 : masquer le séparateur", + hideBar: "Masquer le séparateur de pagination", + hideBarButNoStop: "Masquer mais ne pas arrêter", + dbClick2Stop: "Double-cliquez sur l'espace vide pour mettre en pause", + sortTitle: "Le tri prendra effet après la prochaine mise à jour des règles", + autoRun: "Activation automatique (mode liste noire)", + autoLoadNum: "Nombre de pages à précharger", + turnRate: "Passer à la page suivante lorsqu'elle est à moins de 【X】 fois la hauteur de la page du pied de page", + inputPageNum: "Entrez le numéro de page pour y accéder", + enableHistory: "Inscrire l'historique de navigation après le changement de page", + enableHistoryAfterInsert: "Inscrire l'historique de navigation immédiatement après la jonction, sinon après la navigation", + contentVisibility: "Basculer automatiquement content-visibility pour améliorer les performances de rendu", + initRun: "Changer de page immédiatement après l'ouverture", + preload: "Précharger la page suivante pour accélérer", + click2ImportRule: "Cliquez pour importer le lien des règles de base, puis attendez la fin de la mise à jour : ", + forceAllBody: "Joindre le corps complet de la page ?", + openInNewTab: "Ouvrir les URL ajoutées dans un nouvel onglet", + importSucc: "Importation terminée", + import: "Importer", + editCurrent: "Modifier la règle pour le site actuel", + editBlacklist: "Modifier la liste noire d'URL, une entrée par ligne, supporte les jokers [?,*].", + upBtnImg: "Icône de retour en haut", + downBtnImg: "Icône d'aller en bas de page", + sideControllerIcon: "Icône de la barre latérale", + loadingTextTitle: "Chargement", + dbClick2StopCtrl: "Touche Ctrl", + dbClick2StopAlt: "Touche Alt", + dbClick2StopShift: "Touche Maj", + dbClick2StopMeta: "Touche Méta", + dbClick2StopKey: "Touche de raccourci", + pageElementCss: "Style personnalisé pour les éléments principaux de la page", + customCss: "CSS complet personnalisé", + firstAlert: "Vous n'avez pas importé la règle de base, veuillez sélectionner la règle appropriée à importer", + picker: "Sélecteur d'éléments Pagetual", + closePicker: "Fermer le sélecteur Pagetual", + pickerPlaceholder: "Sélecteur d'élément (Utilisateurs avancés seulement, laissez vide sinon)", + pickerCheck: "Vérifier le sélecteur et copier", + switchSelector: "Cliquez pour changer d'élément", + gotoEdit: "Aller à l'édition de la règle avec le sélecteur actuel", + manualMode: "Désactiver la jonction, avancer manuellement à la page suivante avec la flèche droite (ou envoyer l'événement 'pagetual.next')", + clickMode: "Désactiver la jonction, cliquer automatiquement sur la page suivante en faisant défiler jusqu'à la fin de la page", + pageBarMenu: "Cliquez au centre de la barre de page pour ouvrir le menu du sélecteur", + nextSwitch: "Changer de lien suivant", + arrowToScroll: "Appuyez sur la flèche gauche pour revenir en arrière et la flèche droite pour avancer", + sideController: "Afficher la barre de contrôle de pagination dans la barre latérale", + sideControllerScroll: "Afficher au défilement", + sideControllerAlways: "Toujours afficher", + hideLoadingIcon: "Masquer l'animation de chargement", + hideBarArrow: "Masquer les flèches de la barre de page", + duplicate: "Un doublon de Pagetual a été installé, vérifiez votre gestionnaire de scripts !", + forceStateIframe: "Intégrer la page complète en tant qu'iframe", + forceStateDynamic: "Charger le contenu dynamique via iframe", + forceStateDisable: "Désactiver le changement de page sur ce site", + autoScrollRate: "Vitesse de défilement (1~1000)", + disableAutoScroll: "Arrêter le défilement auto", + enableAutoScroll: "Activer le défilement auto", + toggleAutoScroll: "Basculer le défilement auto", + ruleRequest: "Demande de règle", + page: "Page ", + prevPage: "Page préc.", + nextPage: "Page suiv.", + errorRulesMustBeArray: "Les règles doivent être un tableau (Array) !", + errorJson: "Erreur JSON, veuillez vérifier !", + editSuccess: "Modification réussie", + errorWrongUrl: "URL incorrecte, veuillez vérifier !", + errorAlreadyExists: "Une règle existe déjà !", + settingsSaved: "Les paramètres sont enregistrés, actualisez pour voir les changements", + iframe: "Division forcée par iframe", + dynamic: "Chargement dynamique", + reloadPage: "Modification terminée, recharger maintenant ?", + copied: "Copié", + noValidContent: "Aucun contenu valide détecté, un Captcha peut être présent", + outOfDate: "Le script est obsolète, veuillez mettre à jour vers la dernière version.", + hideBarTips: "Masquer la barre de pagination, basculer l'expérience immersive", + setConfigPage: "Définir la page actuelle comme page de configuration par défaut", + wedata2github: "Changer l'adresse wedata pour l'adresse miroir dans le dépôt github", + addOtherProp: "Ajouter des propriétés à la règle", + addNextSelector: "Ajouter le contenu du sélecteur comme nextLink", + addPageSelector: "Ajouter le contenu du sélecteur comme pageElement", + propName: "Entrez le nom de la propriété de la règle", + propValue: "Entrez la valeur de la propriété de la règle", + customFirst: "Ignorer le cache pour les règles personnalisées locales", + rulesExample: "Exemple de règles", + lastPage: "Dernière page atteinte", + lastPageTips: "Afficher une notification en atteignant la dernière page" + } + }, + { + name: "Bahasa Indonesia", + match: ["id"], + lang: { + enableDebug: "Aktifkan output debug ke konsol", + updateNotification: "Notifikasi setelah aturan diperbarui", + disable: "Nonaktifkan sementara", + disableSite: "Ubah status nonaktif", + disableSiteTips: "Dinonaktifkan di situs ini.", + enableSiteTips: "Diaktifkan di situs ini.", + enable: "✅Aktifkan pembalik halaman otomatis", + tempActive: "Aktif sementara", + toTop: "Kembali ke Atas.", + toBottom: "Pergi ke Bawah.", + current: "Halaman Saat Ini.", + forceIframe: "Paksa untuk menggabungkan halaman berikutnya", + cancelForceIframe: "Batalkan penggabungan paksa", + configure: "Konfigurasi Pagetual", + firstUpdate: "Klik di sini untuk menginisialisasi daftar aturan default", + update: "Perbarui aturan online", + click2update: "Klik untuk memperbarui aturan dari URL sekarang", + loadNow: "Muat berikutnya secara otomatis", + loadConfirm: "Berapa halaman yang ingin Anda muat? (0 berarti tak terbatas)", + noNext: "Tautan berikutnya tidak ditemukan, harap buat aturan baru", + passSec: "Diperbarui #t# detik yang lalu", + passMin: "Diperbarui #t# menit yang lalu", + passHour: "Diperbarui #t# jam yang lalu", + passDay: "Diperbarui #t# hari yang lalu", + cantDel: "Tidak dapat menghapus aturan bawaan", + confirmDel: "Apakah Anda yakin ingin menghapus aturan ini?", + updateSucc: "Pembaruan berhasil", + beginUpdate: "Memulai pembaruan, harap tunggu sebentar", + customUrls: "Impor URL aturan Pagetual atau AutoPagerize, satu URL per baris.", + customRules: "Masukkan aturan khusus. ✍️Kontribusi aturan", + save: "Simpan", + loadingText: "Sedang Memuat...", + opacity: "Opasitas", + opacityPlaceholder: "0: sembunyikan pemisah", + hideBar: "Sembunyikan pemisah paginasi", + hideBarButNoStop: "Sembunyikan tapi jangan hentikan", + dbClick2Stop: "Klik dua kali pada ruang kosong untuk menjeda", + sortTitle: "Pengurutan berlaku setelah pembaruan aturan berikutnya", + autoRun: "Aktifkan otomatis (mode daftar hitam)", + autoLoadNum: "Jumlah halaman pramuat", + turnRate: "Buka halaman berikutnya saat jarak dari footer kurang dari 【X】 kali tinggi halaman", + inputPageNum: "Masukkan nomor halaman untuk melompat", + enableHistory: "Tulis riwayat penjelajahan setelah membalik halaman", + enableHistoryAfterInsert: "Tulis riwayat penjelajahan segera setelah penyambungan, jika tidak, tulis setelah menjelajah", + contentVisibility: "Secara otomatis mengganti content-visibility untuk meningkatkan kinerja rendering", + initRun: "Balik halaman segera setelah dibuka", + preload: "Pramuat halaman berikutnya untuk mempercepat", + click2ImportRule: "Klik untuk mengimpor tautan aturan dasar, lalu tunggu hingga pembaruan selesai: ", + forceAllBody: "Gabungkan seluruh badan halaman?", + openInNewTab: "Buka URL tambahan di tab baru", + importSucc: "Impor selesai", + import: "Impor", + editCurrent: "Edit aturan untuk situs web saat ini", + editBlacklist: "Edit daftar hitam URL, satu entri per baris, Mendukung wildcard [?,*].", + upBtnImg: "Ikon kembali ke atas", + downBtnImg: "Ikon pergi ke footer", + sideControllerIcon: "Ikon bilah sisi", + loadingTextTitle: "Memuat", + dbClick2StopCtrl: "Tombol Ctrl", + dbClick2StopAlt: "Tombol Alt", + dbClick2StopShift: "Tombol Shift", + dbClick2StopMeta: "Tombol Meta", + dbClick2StopKey: "Tombol pintas", + pageElementCss: "Gaya kustom untuk elemen halaman utama", + customCss: "CSS kustom lengkap", + firstAlert: "Anda belum mengimpor aturan dasar, silakan pilih aturan yang sesuai untuk diimpor", + picker: "Pemilih elemen Pagetual", + closePicker: "Tutup pemilih Pagetual", + pickerPlaceholder: "Selektor elemen, (Hanya pengguna tingkat lanjut, biarkan kosong jika tidak)", + pickerCheck: "Periksa selektor dan salin", + switchSelector: "Klik untuk mengganti elemen", + gotoEdit: "Pergi ke edit aturan dengan selektor saat ini", + manualMode: "Nonaktifkan penyambungan, maju ke halaman berikutnya secara manual menggunakan tombol panah kanan (atau kirim acara 'pagetual.next')", + clickMode: "Nonaktifkan penyambungan, klik halaman berikutnya secara otomatis saat menggulir ke akhir halaman", + pageBarMenu: "Klik tengah bilah halaman untuk membuka menu pemilih", + nextSwitch: "Ganti tautan berikutnya", + arrowToScroll: "Tekan panah kiri untuk menggulir ke belakang dan panah kanan untuk maju halaman", + sideController: "Tampilkan bilah kontrol paging di bilah sisi", + sideControllerScroll: "Tampilkan saat bergulir", + sideControllerAlways: "Selalu tampilkan", + hideLoadingIcon: "Sembunyikan animasi memuat", + hideBarArrow: "Sembunyikan panah untuk bilah halaman", + duplicate: "Pagetual duplikat telah diinstal, periksa manajer skrip Anda!", + forceStateIframe: "Sematkan halaman penuh sebagai iframe", + forceStateDynamic: "Muat konten dinamis melalui iframe", + forceStateDisable: "Nonaktifkan pembalik halaman di situs ini", + autoScrollRate: "Kecepatan gulir (1~1000)", + disableAutoScroll: "Hentikan Gulir Otomatis", + enableAutoScroll: "Aktifkan Gulir Otomatis", + toggleAutoScroll: "Ubah Gulir Otomatis", + ruleRequest: "Permintaan Aturan", + page: "Halaman ", + prevPage: "Halaman seb.", + nextPage: "Halaman ber.", + errorRulesMustBeArray: "Aturan harus berupa Array!", + errorJson: "Kesalahan JSON, Periksa lagi!", + editSuccess: "Berhasil diedit", + errorWrongUrl: "URL salah, Periksa lagi!", + errorAlreadyExists: "Aturan sudah ada!", + settingsSaved: "Pengaturan disimpan, segarkan untuk melihat", + iframe: "Pemisahan paksa oleh iframe", + dynamic: "Pemuatan dinamis", + reloadPage: "Pengeditan selesai, muat ulang sekarang?", + copied: "Disalin", + noValidContent: "Tidak ada konten valid yang terdeteksi, mungkin ada Captcha", + outOfDate: "Skrip sudah usang, harap perbarui ke versi terbaru.", + hideBarTips: "Sembunyikan bilah paginasi, alihkan pengalaman imersif", + setConfigPage: "Atur halaman saat ini sebagai halaman konfigurasi default", + wedata2github: "Ubah alamat wedata ke alamat cermin di repositori github", + addOtherProp: "Tambahkan properti aturan", + addNextSelector: "Tambahkan konten selektor sebagai nextLink", + addPageSelector: "Tambahkan konten selektor sebagai pageElement", + propName: "Masukkan nama properti aturan", + propValue: "Masukkan nilai properti aturan", + customFirst: "Abaikan cache untuk aturan kustom lokal", + rulesExample: "Contoh Aturan", + lastPage: "Telah mencapai halaman terakhir", + lastPageTips: "Tampilkan tip saat mencapai halaman terakhir" + } + }, { // Traduzido por Thiago Ramos (thiagojramos@outlook.com). name: "Português (Brasil)", @@ -531,6 +3135,254 @@ lastPageTips: "Mostrar dicas ao atingir a última página" } }, + { + name: "Français", + match: ["fr"], + lang: { + enableDebug: "Activer la sortie de débogage dans la console", + updateNotification: "Notification après la mise à jour des règles", + disable: "Désactiver temporairement", + disableSite: "Basculer l'état de désactivation", + disableSiteTips: "Désactivé sur ce site.", + enableSiteTips: "Activé sur ce site.", + enable: "✅Activer le changement de page automatique", + tempActive: "Temporairement actif", + toTop: "Retour en haut.", + toBottom: "Aller en bas.", + current: "Page actuelle.", + forceIframe: "Forcer la jonction de la page suivante", + cancelForceIframe: "Annuler la jonction forcée", + configure: "Configurer Pagetual", + firstUpdate: "Cliquez ici pour initialiser la liste de règles par défaut", + update: "Mettre à jour les règles en ligne", + click2update: "Cliquez pour mettre à jour les règles depuis l'URL maintenant", + loadNow: "Charger la suite automatiquement", + loadConfirm: "Combien de pages voulez-vous charger ? (0 pour infini)", + noNext: "Aucun lien suivant trouvé, veuillez créer une nouvelle règle", + passSec: "Mis à jour il y a #t# secondes", + passMin: "Mis à jour il y a #t# minutes", + passHour: "Mis à jour il y a #t# heures", + passDay: "Mis à jour il y a #t# jours", + cantDel: "Impossible de supprimer les règles intégrées", + confirmDel: "Êtes-vous sûr de vouloir supprimer cette règle ?", + updateSucc: "Mise à jour réussie", + beginUpdate: "Début de la mise à jour, veuillez patienter", + customUrls: "Importer l'URL des règles Pagetual ou AutoPagerize, une URL par ligne.", + customRules: "Saisir des règles personnalisées. ✍️Contribuer aux règles", + save: "Enregistrer", + loadingText: "Chargement en cours...", + opacity: "Opacité", + opacityPlaceholder: "0 : masquer le séparateur", + hideBar: "Masquer le séparateur de pagination", + hideBarButNoStop: "Masquer mais ne pas arrêter", + dbClick2Stop: "Double-cliquez sur l'espace vide pour mettre en pause", + sortTitle: "Le tri prendra effet après la prochaine mise à jour des règles", + autoRun: "Activation automatique (mode liste noire)", + autoLoadNum: "Nombre de pages à précharger", + turnRate: "Passer à la page suivante lorsqu'elle est à moins de 【X】 fois la hauteur de la page du pied de page", + inputPageNum: "Entrez le numéro de page pour y accéder", + enableHistory: "Inscrire l'historique de navigation après le changement de page", + enableHistoryAfterInsert: "Inscrire l'historique de navigation immédiatement après la jonction, sinon après la navigation", + contentVisibility: "Basculer automatiquement content-visibility pour améliorer les performances de rendu", + initRun: "Changer de page immédiatement après l'ouverture", + preload: "Précharger la page suivante pour accélérer", + click2ImportRule: "Cliquez pour importer le lien des règles de base, puis attendez la fin de la mise à jour : ", + forceAllBody: "Joindre le corps complet de la page ?", + openInNewTab: "Ouvrir les URL ajoutées dans un nouvel onglet", + importSucc: "Importation terminée", + import: "Importer", + editCurrent: "Modifier la règle pour le site actuel", + editBlacklist: "Modifier la liste noire d'URL, une entrée par ligne, supporte les jokers [?,*].", + upBtnImg: "Icône de retour en haut", + downBtnImg: "Icône d'aller en bas de page", + sideControllerIcon: "Icône de la barre latérale", + loadingTextTitle: "Chargement", + dbClick2StopCtrl: "Touche Ctrl", + dbClick2StopAlt: "Touche Alt", + dbClick2StopShift: "Touche Maj", + dbClick2StopMeta: "Touche Méta", + dbClick2StopKey: "Touche de raccourci", + pageElementCss: "Style personnalisé pour les éléments principaux de la page", + customCss: "CSS complet personnalisé", + firstAlert: "Vous n'avez pas importé la règle de base, veuillez sélectionner la règle appropriée à importer", + picker: "Sélecteur d'éléments Pagetual", + closePicker: "Fermer le sélecteur Pagetual", + pickerPlaceholder: "Sélecteur d'élément (Utilisateurs avancés seulement, laissez vide sinon)", + pickerCheck: "Vérifier le sélecteur et copier", + switchSelector: "Cliquez pour changer d'élément", + gotoEdit: "Aller à l'édition de la règle avec le sélecteur actuel", + manualMode: "Désactiver la jonction, avancer manuellement à la page suivante avec la flèche droite (ou envoyer l'événement 'pagetual.next')", + clickMode: "Désactiver la jonction, cliquer automatiquement sur la page suivante en faisant défiler jusqu'à la fin de la page", + pageBarMenu: "Cliquez au centre de la barre de page pour ouvrir le menu du sélecteur", + nextSwitch: "Changer de lien suivant", + arrowToScroll: "Appuyez sur la flèche gauche pour revenir en arrière et la flèche droite pour avancer", + sideController: "Afficher la barre de contrôle de pagination dans la barre latérale", + sideControllerScroll: "Afficher au défilement", + sideControllerAlways: "Toujours afficher", + hideLoadingIcon: "Masquer l'animation de chargement", + hideBarArrow: "Masquer les flèches de la barre de page", + duplicate: "Un doublon de Pagetual a été installé, vérifiez votre gestionnaire de scripts !", + forceStateIframe: "Intégrer la page complète en tant qu'iframe", + forceStateDynamic: "Charger le contenu dynamique via iframe", + forceStateDisable: "Désactiver le changement de page sur ce site", + autoScrollRate: "Vitesse de défilement (1~1000)", + disableAutoScroll: "Arrêter le défilement auto", + enableAutoScroll: "Activer le défilement auto", + toggleAutoScroll: "Basculer le défilement auto", + ruleRequest: "Demande de règle", + page: "Page ", + prevPage: "Page préc.", + nextPage: "Page suiv.", + errorRulesMustBeArray: "Les règles doivent être un tableau (Array) !", + errorJson: "Erreur JSON, veuillez vérifier !", + editSuccess: "Modification réussie", + errorWrongUrl: "URL incorrecte, veuillez vérifier !", + errorAlreadyExists: "Une règle existe déjà !", + settingsSaved: "Les paramètres sont enregistrés, actualisez pour voir les changements", + iframe: "Division forcée par iframe", + dynamic: "Chargement dynamique", + reloadPage: "Modification terminée, recharger maintenant ?", + copied: "Copié", + noValidContent: "Aucun contenu valide détecté, un Captcha peut être présent", + outOfDate: "Le script est obsolète, veuillez mettre à jour vers la dernière version.", + hideBarTips: "Masquer la barre de pagination, basculer l'expérience immersive", + setConfigPage: "Définir la page actuelle comme page de configuration par défaut", + wedata2github: "Changer l'adresse wedata pour l'adresse miroir dans le dépôt github", + addOtherProp: "Ajouter des propriétés à la règle", + addNextSelector: "Ajouter le contenu du sélecteur comme nextLink", + addPageSelector: "Ajouter le contenu du sélecteur comme pageElement", + propName: "Entrez le nom de la propriété de la règle", + propValue: "Entrez la valeur de la propriété de la règle", + customFirst: "Ignorer le cache pour les règles personnalisées locales", + rulesExample: "Exemple de règles", + lastPage: "Dernière page atteinte", + lastPageTips: "Afficher une notification en atteignant la dernière page" + } + }, + { + name: "Italiano", + match: ["it"], + lang: { + enableDebug: "Abilita output di debug nella console", + updateNotification: "Notifica dopo l'aggiornamento delle regole", + disable: "Disabilita temporaneamente", + disableSite: "Attiva/disattiva lo stato di disabilitazione", + disableSiteTips: "Disabilitato su questo sito.", + enableSiteTips: "Abilitato su questo sito.", + enable: "✅Abilita il cambio pagina automatico", + tempActive: "Temporaneamente attivo", + toTop: "Torna in cima.", + toBottom: "Vai in fondo.", + current: "Pagina corrente.", + forceIframe: "Forza l'unione della pagina successiva", + cancelForceIframe: "Annulla unione forzata", + configure: "Configura Pagetual", + firstUpdate: "Clicca qui per inizializzare l'elenco delle regole predefinite", + update: "Aggiorna regole online", + click2update: "Clicca per aggiornare le regole dall'URL ora", + loadNow: "Carica la prossima automaticamente", + loadConfirm: "Quante pagine vuoi caricare? (0 significa infinite)", + noNext: "Nessun link 'successivo' trovato, crea una nuova regola", + passSec: "Aggiornato #t# secondi fa", + passMin: "Aggiornato #t# minuti fa", + passHour: "Aggiornato #t# ore fa", + passDay: "Aggiornato #t# giorni fa", + cantDel: "Impossibile eliminare le regole predefinite", + confirmDel: "Sei sicuro di voler eliminare questa regola?", + updateSucc: "Aggiornamento riuscito", + beginUpdate: "Inizio aggiornamento, attendere un momento prego", + customUrls: "Importa URL di regole Pagetual o AutoPagerize, un URL per riga.", + customRules: "Inserisci regole personalizzate. ✍️Contribuisci alle regole", + save: "Salva", + loadingText: "Caricamento in corso...", + opacity: "Opacità", + opacityPlaceholder: "0: nascondi separatore", + hideBar: "Nascondi il separatore di pagina", + hideBarButNoStop: "Nascondi ma non fermare", + dbClick2Stop: "Fai doppio clic sullo spazio vuoto per mettere in pausa", + sortTitle: "L'ordinamento avrà effetto dopo il prossimo aggiornamento delle regole", + autoRun: "Abilitazione automatica (modalità lista nera)", + autoLoadNum: "Numero di pagine da precaricare", + turnRate: "Gira alla pagina successiva quando la distanza dal fondo è inferiore a 【X】 volte l'altezza della pagina", + inputPageNum: "Inserisci il numero di pagina a cui saltare", + enableHistory: "Scrivi la cronologia di navigazione dopo aver girato pagina", + enableHistoryAfterInsert: "Scrivi la cronologia subito dopo l'unione, altrimenti dopo la navigazione", + contentVisibility: "Cambia automaticamente content-visibility per migliorare le prestazioni di rendering", + initRun: "Inizia a girare le pagine subito dopo l'apertura", + preload: "Precarica la pagina successiva per velocizzare", + click2ImportRule: "Clicca per importare il link delle regole di base, poi attendi il completamento dell'aggiornamento: ", + forceAllBody: "Unire l'intero corpo della pagina?", + openInNewTab: "Apri gli URL aggiunti in una nuova scheda", + importSucc: "Importazione completata", + import: "Importa", + editCurrent: "Modifica regola per il sito corrente", + editBlacklist: "Modifica la lista nera di URL, una voce per riga, supporta i caratteri jolly [?,*].", + upBtnImg: "Icona per tornare in cima", + downBtnImg: "Icona per andare in fondo", + sideControllerIcon: "Icona della barra laterale", + loadingTextTitle: "Caricamento", + dbClick2StopCtrl: "Tasto Ctrl", + dbClick2StopAlt: "Tasto Alt", + dbClick2StopShift: "Tasto Maiusc", + dbClick2StopMeta: "Tasto Meta", + dbClick2StopKey: "Tasto di scelta rapida", + pageElementCss: "Stile personalizzato per gli elementi principali della pagina", + customCss: "CSS completo personalizzato", + firstAlert: "Non hai importato la regola di base, seleziona la regola appropriata da importare", + picker: "Selettore di elementi Pagetual", + closePicker: "Chiudi selettore Pagetual", + pickerPlaceholder: "Selettore di elementi (Solo utenti esperti, altrimenti lasciare vuoto)", + pickerCheck: "Controlla selettore e copia", + switchSelector: "Clicca per cambiare elemento", + gotoEdit: "Vai alla modifica della regola con il selettore corrente", + manualMode: "Disabilita unione, avanza manualmente alla pagina successiva con la freccia destra (o invia l'evento 'pagetual.next')", + clickMode: "Disabilita unione, clicca automaticamente la pagina successiva scorrendo fino alla fine", + pageBarMenu: "Clicca al centro della barra di pagina per aprire il menu del selettore", + nextSwitch: "Cambia link successivo", + arrowToScroll: "Premi freccia sinistra per scorrere indietro e freccia destra per avanzare di pagina", + sideController: "Mostra la barra di controllo della paginazione nella barra laterale", + sideControllerScroll: "Mostra durante lo scorrimento", + sideControllerAlways: "Mostra sempre", + hideLoadingIcon: "Nascondi animazione di caricamento", + hideBarArrow: "Nascondi frecce della barra di pagina", + duplicate: "È stato installato un duplicato di Pagetual, controlla il tuo gestore di script!", + forceStateIframe: "Incorpora la pagina intera come iframe", + forceStateDynamic: "Carica contenuto dinamico tramite iframe", + forceStateDisable: "Disabilita il cambio pagina su questo sito", + autoScrollRate: "Velocità di scorrimento (1~1000)", + disableAutoScroll: "Ferma scorrimento automatico", + enableAutoScroll: "Abilita scorrimento automatico", + toggleAutoScroll: "Attiva/disattiva scorrimento automatico", + ruleRequest: "Richiesta regola", + page: "Pagina ", + prevPage: "Pagina prec.", + nextPage: "Pagina succ.", + errorRulesMustBeArray: "Le regole devono essere un Array!", + errorJson: "Errore JSON, controlla di nuovo!", + editSuccess: "Modificato con successo", + errorWrongUrl: "URL errato, controlla di nuovo!", + errorAlreadyExists: "Una regola esiste già!", + settingsSaved: "Le impostazioni sono state salvate, aggiorna per visualizzare", + iframe: "Divisione forzata tramite iframe", + dynamic: "Caricamento dinamico", + reloadPage: "Modifica completata, ricaricare ora?", + copied: "Copiato", + noValidContent: "Nessun contenuto valido rilevato, potrebbe esserci un Captcha", + outOfDate: "Lo script non è aggiornato, si prega di aggiornare all'ultima versione.", + hideBarTips: "Nascondi la barra di paginazione, attiva/disattiva l'esperienza immersiva", + setConfigPage: "Imposta la pagina corrente come pagina di configurazione predefinita", + wedata2github: "Cambia l'indirizzo wedata con l'indirizzo mirror nel repository github", + addOtherProp: "Aggiungi proprietà alla regola", + addNextSelector: "Aggiungi contenuto del selettore come nextLink", + addPageSelector: "Aggiungi contenuto del selettore come pageElement", + propName: "Inserisci il nome della proprietà della regola", + propValue: "Inserisci il valore della proprietà della regola", + customFirst: "Ignora la cache per le regole personalizzate locali", + rulesExample: "Esempio di regole", + lastPage: "Raggiunta l'ultima pagina", + lastPageTips: "Mostra un avviso quando si raggiunge l'ultima pagina" + } + }, { // Translated by SrKalopsia (srkalopsia@gmail.com). name: "Español", From 7d3f26d8a7b8a9e05607894c8526fb4ecfcd6d04 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 28 Aug 2025 19:18:21 +0900 Subject: [PATCH 0843/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 7838725e7f5..ced954d0c55 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -9157,10 +9157,15 @@ if (ruleImportUrlReg.test(href) || inConfig) { let importing = false; if (!inUpdate && rulesData.uninited) { - setTimeout(() => { - if (!inUpdate && !importing) showTips(i18n("firstAlert")); - }, 3000); - showTips(i18n("firstAlert")); + let showTimes = 0; + let showFirstAlert = () => { + if (inUpdate || importing || ++showTimes > 5) return; + showTips(i18n("firstAlert"), configPage[0], 2000); + setTimeout(() => { + showFirstAlert(); + }, 3000); + }; + showFirstAlert(); } let defaultOption = document.querySelector('#discussion_rating_4'); if (defaultOption) defaultOption.checked = true; From 6bc4e318669cfa8f992963e1668d6a1f42f8c548 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 29 Aug 2025 08:46:05 +0900 Subject: [PATCH 0844/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 101 ++++++++++++++-------------- 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index d088c6e3f83..9896ffa84e6 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.8.22.1 +// @version 2025.8.29.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -25323,6 +25323,32 @@ ImgOps | https://imgops.com/#b#`; }; } } + var checkUniqueImgWin = function() { + if (canPreview) { + if (result.type != "link" && result.type != "rule" && result.src == result.imgSrc) { + if (result.imgAS.w < result.imgCS.w * 1.6 && result.imgAS.h < result.imgCS.h * 1.6) { + if (result.img && result.img.childElementCount) { + if (result.type == "force") return false; + if (prefs.floatBar.globalkeys.invertInitShow) return false; + } + var wSize = getWindowSize(); + if (prefs.floatBar.globalkeys.invertInitShow && result.imgAS.w <= wSize.w && result.imgAS.h <= wSize.h) return false; + } + } + uniqueImgWinInitX = clientX; + uniqueImgWinInitY = clientY; + if (uniqueImgWin && !uniqueImgWin.removed) { + if (uniqueImgWin.src == result.src) return true; + uniqueImgWin.remove(); + } + waitUntilMove(_target, () => { + new LoadingAnimC(result, 'popup', prefs.waitImgLoad, prefs.framesPicOpenInTopWindow); + }); + return true; + } else { + return false; + } + }; if (!result) { if (target.nodeName.toUpperCase() != 'IMG' && target.dataset.role == "img") { let img = target.parentNode.querySelector('img'); @@ -25340,13 +25366,34 @@ ImgOps | https://imgops.com/#b#`; }; } } else if (target.nodeName.toUpperCase() != 'IMG') { + if (selectionClientRect && + clientX > selectionClientRect.left && + clientX < selectionClientRect.left + selectionClientRect.width && + clientY > selectionClientRect.top && + clientY < selectionClientRect.top + selectionClientRect.height) { + result = { + src: selectionStr, + type: "link", + imgSrc: selectionStr, + noActual:true, + img: target + }; + checkUniqueImgWin(); + + if (!floatBar) { + floatBar = new FloatBarC(); + } + floatBar.start(result); + + return; + } let found = false; if (target.nodeName.toUpperCase() == "AREA") target = target.parentNode; var broEle, broImg; if (target.nodeName.toUpperCase() != 'A' && target.parentNode && target.parentNode.style && !/flex|grid|table/.test(getComputedStyle(target.parentNode).display)) { broEle = target.previousElementSibling; while (broEle) { - if (broEle.offsetWidth) { + if (broEle.offsetWidth && broEle.offsetWidth > target.offsetWidth>>1) { if (broEle.nodeName == "IMG") broImg = broEle; else if (broEle.nodeName == "PICTURE") broImg = broEle.querySelector("img"); } @@ -25357,7 +25404,7 @@ ImgOps | https://imgops.com/#b#`; else if (!broEle) { broEle = target.nextElementSibling; while (broEle) { - if (broEle.offsetWidth) { + if (broEle.offsetWidth && broEle.offsetWidth > target.offsetWidth>>1) { if (broEle.nodeName == "IMG") broImg = broEle; else if (broEle.nodeName == "PICTURE") broImg = broEle.querySelector("img"); } @@ -25582,56 +25629,8 @@ ImgOps | https://imgops.com/#b#`; } } } - var checkUniqueImgWin = function() { - if (canPreview) { - if (result.type != "link" && result.type != "rule" && result.src == result.imgSrc) { - if (result.imgAS.w < result.imgCS.w * 1.6 && result.imgAS.h < result.imgCS.h * 1.6) { - if (result.img && result.img.childElementCount) { - if (result.type == "force") return false; - if (prefs.floatBar.globalkeys.invertInitShow) return false; - } - var wSize = getWindowSize(); - if (prefs.floatBar.globalkeys.invertInitShow && result.imgAS.w <= wSize.w && result.imgAS.h <= wSize.h) return false; - } - } - uniqueImgWinInitX = clientX; - uniqueImgWinInitY = clientY; - if (uniqueImgWin && !uniqueImgWin.removed) { - if (uniqueImgWin.src == result.src) return true; - uniqueImgWin.remove(); - } - waitUntilMove(_target, () => { - new LoadingAnimC(result, 'popup', prefs.waitImgLoad, prefs.framesPicOpenInTopWindow); - }); - return true; - } else { - return false; - } - }; if (!result && target.nodeName.toUpperCase() != 'IMG') { - if (selectionClientRect && - clientX > selectionClientRect.left && - clientX < selectionClientRect.left + selectionClientRect.width && - clientY > selectionClientRect.top && - clientY < selectionClientRect.top + selectionClientRect.height) { - result = { - src: selectionStr, - type: "link", - imgSrc: selectionStr, - noActual:true, - img: target - }; - checkUniqueImgWin(); - - if (!floatBar) { - floatBar = new FloatBarC(); - } - floatBar.start(result); - - return; - } - let i = 0; while(target) { if (i++ > 5) { From 752e72345214c66be0114389672b4e95ef83df0a Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 1 Sep 2025 10:54:08 +0900 Subject: [PATCH 0845/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 9896ffa84e6..5a6bd37936c 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.8.29.1 +// @version 2025.9.1.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -25324,16 +25324,25 @@ ImgOps | https://imgops.com/#b#`; } } var checkUniqueImgWin = function() { - if (canPreview) { - if (result.type != "link" && result.type != "rule" && result.src == result.imgSrc) { - if (result.imgAS.w < result.imgCS.w * 1.6 && result.imgAS.h < result.imgCS.h * 1.6) { - if (result.img && result.img.childElementCount) { - if (result.type == "force") return false; - if (prefs.floatBar.globalkeys.invertInitShow) return false; + let invert = !canPreview && prefs.floatBar.globalkeys.invertInitShow && prefs.floatBar.globalkeys.type == "hold"; + if (canPreview || invert) { + let forceShow = (() => { + if (result.type != "link" && result.type != "rule" && result.src == result.imgSrc) { + if (result.imgAS.w < result.imgCS.w * 1.3 && result.imgAS.h < result.imgCS.h * 1.3) { + if (result.img && result.img.childElementCount) { + if (result.type == "force") return false; + if (prefs.floatBar.globalkeys.invertInitShow) return false; + } + var wSize = getWindowSize(); + if (prefs.floatBar.globalkeys.invertInitShow && result.imgAS.w <= wSize.w && result.imgAS.h <= wSize.h) return false; } - var wSize = getWindowSize(); - if (prefs.floatBar.globalkeys.invertInitShow && result.imgAS.w <= wSize.w && result.imgAS.h <= wSize.h) return false; } + return true; + })(); + if (forceShow) { + if (invert) return false; + } else { + if (!invert) return false; } uniqueImgWinInitX = clientX; uniqueImgWinInitY = clientY; From b6146bfe083c9c4053ab97fbed4959ed6135cfb5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 1 Sep 2025 20:34:04 +0900 Subject: [PATCH 0846/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index f6782e7b598..d7e487e9cbf 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1981,6 +1981,12 @@ var siteInfo = [ r: "///qtn(\\..*)\\.\\w+\\.webp/i", s: "//w$1.webp" }, + { + name: "hentaizap", + url: /\bhentaizap\.com\//, + r: /t\.jpg$/, + s: ".webp" + }, { name: "Wjcodes", url: /^https:\/\/[^\.]+\.wjcodes\.com\//, From 9e82848ee490d4f17e01e4b1096fcbd4e60f66e4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 1 Sep 2025 20:35:11 +0900 Subject: [PATCH 0847/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 5a6bd37936c..2ae75355fea 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1643244/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1652811/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1427239/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 @@ -25473,17 +25473,6 @@ ImgOps | https://imgops.com/#b#`; } else if (target.parentNode.nodeName.toUpperCase() == 'IMG') { target = target.parentNode; found = true; - } else if (prefs.floatBar.listenBg && hasBg(target.parentNode)) { - target = target.parentNode; - let src = targetBg, nsrc = src, noActual = true, type = "scale"; - result = { - src: nsrc, - type: type, - imgSrc: src, - noActual:noActual, - img: target - }; - found = true; } } if (!found) { @@ -25569,6 +25558,18 @@ ImgOps | https://imgops.com/#b#`; let imgs = target.shadowRoot.querySelectorAll('img'); if (imgs.length === 1) target = imgs[0]; } + if (!found && prefs.floatBar.listenBg && hasBg(target.parentNode)) { + target = target.parentNode; + let src = targetBg, nsrc = src, noActual = true, type = "scale"; + result = { + src: nsrc, + type: type, + imgSrc: src, + noActual:noActual, + img: target + }; + found = true; + } if (result && !/^data:/i.test(result.src)) { if (matchedRule.rules.length > 0 && target.nodeName.toUpperCase() != 'IMG') { let src = result.src, img = {src: src}, type, imgSrc = src; From df442daf5ccae8eb62bc5e61ac19cf1d029e9ace Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 2 Sep 2025 08:38:26 +0900 Subject: [PATCH 0848/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 2ae75355fea..01c4a52e376 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.1.1 +// @version 2025.9.2.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -24355,6 +24355,7 @@ ImgOps | https://imgops.com/#b#`; function pretreatment(img, fetchImg) { if (img.removeAttribute) img.removeAttribute("loading"); if (img.nodeName.toUpperCase() != "IMG" || (!fetchImg && img.src && !img.srcset && !/^data/.test(img.src))) return; + if (img.src && !/(^data|loading|lazy)/.test(img.src)) return; let src; tprules.find(function(rule, index, array) { try { From d63bafeb7bec5655b6979ebb6896c010ad75cff5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 2 Sep 2025 09:20:22 +0900 Subject: [PATCH 0849/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index ced954d0c55..2fdb892ec35 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -7286,6 +7286,10 @@ if (compareNodeName(parent, ["table"])) { parent.parentNode.appendChild(loadingDiv); } + if (loadingDiv.previousElementSibling) { + let preStyle = _unsafeWindow.getComputedStyle(loadingDiv.previousElementSibling); + loadingDiv.style.order = preStyle.order; + } } //this.setPageTop(lastScrollTop); if (sideController.inited) { @@ -11644,6 +11648,9 @@ pageBar.classList.add("stop"); } pageBar.style.cssText = pageBarStyle; + if (exampleStyle.order) { + pageBar.style.order = exampleStyle.order; + } pageBar.title = i18n(isPause ? "enable" : "disable"); upSpan.innerHTML = createHTML(upSvg); upSpan.children[0].style.cssText = upSvgCSS; From e32c7c761691bc99b1c9c928b49a001f3a322f3e Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 2 Sep 2025 22:23:19 +0900 Subject: [PATCH 0850/1065] update --- Pagetual/pagetual.user.js | 2 +- Picviewer CE+/pvcep_lang.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 2fdb892ec35..2479f1e6e5e 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -5384,7 +5384,7 @@ curWidth = validSize.w; } } - if (compareNodeName(ele, ["picture"]) || !ele.innerText || ele.innerText.trim() === '') { + if (compareNodeName(ele, ["picture", "img"])) { self.curSiteRule.pageElement = geneSelector(ele.parentNode) + ">" + ele.nodeName.toLowerCase(); debug(self.curSiteRule.pageElement, 'Page element'); let eles = []; diff --git a/Picviewer CE+/pvcep_lang.js b/Picviewer CE+/pvcep_lang.js index 8243fdb7bf2..adf87fa2c25 100644 --- a/Picviewer CE+/pvcep_lang.js +++ b/Picviewer CE+/pvcep_lang.js @@ -257,7 +257,7 @@ const langData = [ customLang: "Custom language", defaultLang: "Auto detect", hideIcon: "Hide icon", - initShow: "Invert Shortcut to show preview by default", + initShow: "Show preview by default", stayOut: "Let float bar stay out of the image", galleryDownloadGap: "Download interval", formatConversion: "Convert the image format when downloading. One rule per line", @@ -791,7 +791,7 @@ const langData = [ customLang: "设定语言", defaultLang: "自动选择", hideIcon: "隐藏图标", - initShow: "反转快捷键,默认显示预览", + initShow: "默认显示预览", stayOut: "使浮动工具栏显示在图片外部", galleryDownloadGap: "下载间隔时间", formatConversion: "下载时转换图片格式,一行一条", @@ -1057,7 +1057,7 @@ const langData = [ customLang: "設定語言", defaultLang: "自動選擇", hideIcon: "隱藏圖標", - initShow: "反轉快捷鍵,默認顯示預覽", + initShow: "默認顯示預覽", stayOut: "使浮動工具欄顯示在圖片外部", galleryDownloadGap: "下載間隔時間", formatConversion: "下載時轉換圖片格式,一行一條", @@ -2391,7 +2391,7 @@ const langData = [ customLang: "カスタム言語", defaultLang: "自動検出", hideIcon: "アイコンを隠す", - initShow: "ショートカットを反転して、デフォルトでプレビューを表示", + initShow: "デフォルトでプレビューを表示", stayOut: "フロートバーを画像外に留める", galleryDownloadGap: "ダウンロード間隔", formatConversion: "ダウンロード時に画像形式を変換します。1 行に 1 行", From 4e3e7cb3d8b063b79ba3a03fab0e9e9db3585b73 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 2 Sep 2025 22:37:24 +0900 Subject: [PATCH 0851/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 01c4a52e376..2703c1dd221 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.2.1 +// @version 2025.9.2.2 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -47,7 +47,7 @@ // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js // @require https://update.greasyfork.org/scripts/438080/1652811/pvcep_rules.js -// @require https://update.greasyfork.org/scripts/440698/1427239/pvcep_lang.js +// @require https://update.greasyfork.org/scripts/440698/1653424/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 // @match *://*/* @@ -25765,7 +25765,7 @@ ImgOps | https://imgops.com/#b#`; return; } if ((uniqueImgWin && !uniqueImgWin.removed && !uniqueImgWin.previewed)) { - if (canPreview) { + if (canPreview || prefs.floatBar.globalkeys.invertInitShow) { uniqueImgWinInitX = e.clientX; uniqueImgWinInitY = e.clientY; uniqueImgWin.followPos(uniqueImgWinInitX, uniqueImgWinInitY); From 6e7688f32b12e94c7d093587e026fdc7445efb9b Mon Sep 17 00:00:00 2001 From: Bug-Cache <98657967+Bug-Cache@users.noreply.github.com> Date: Thu, 4 Sep 2025 14:29:13 +0700 Subject: [PATCH 0852/1065] Update pagetualRules.json https://github.com/hoothin/UserScripts/issues/998#issuecomment-3245325962 --- Pagetual/pagetualRules.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index fec987433dc..9d7a7207672 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -1,4 +1,10 @@ [ +{ + "name": "Fapello", + "url": "^https?://fapello\\.com/", + "example": "https://fapello.com/noemy-love/38/", + "pageElement": "a.uk-align-center > img" +}, { "name": "精易论坛 - 手机版 - Powered by Discuz!", "url": "^https?://bbs\\.125\\.la/", From ad0358f0c8859b8570ee2b85a479bca5711f59ef Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 4 Sep 2025 07:32:29 +0000 Subject: [PATCH 0853/1065] Update version of Pagetual rules to 99 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 6529ff889b0..3ad5abd03ae 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -98 +99 From 13a5535a593b83bea7f7228a775a1e272696531b Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 4 Sep 2025 20:59:31 +0900 Subject: [PATCH 0854/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 2703c1dd221..2f534ed1311 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.2.2 +// @version 2025.9.4.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -20652,7 +20652,12 @@ ImgOps | https://imgops.com/#b#`; if (!self.zoomed) { if (!self.imgWindow.classList.contains("pv-pic-window-scroll")) { self.zoomLevel=0; - self.zoom(1); + if (img.naturalHeight && img.naturalHeight < 100) { + let zoomLevel = 100 / img.naturalHeight; + self.zoom(zoomLevel); + } else { + self.zoom(1); + } } if (self == uniqueImgWin) { self.initMaxSize(); @@ -23971,16 +23976,10 @@ ImgOps | https://imgops.com/#b#`; if (bodyStyle.position === "static") { offsetParent = document.documentElement; - bodyPosi = { - top: 0, - bottom: windowSize.h, - left: 0, - right: windowSize.w - }; } else { offsetParent = body; - bodyPosi = offsetParent.getBoundingClientRect(); } + bodyPosi = offsetParent.getBoundingClientRect(); var scrolled=getScrolled(offsetParent); From 03e04a1735ba8e387d9d72d233597b7e559d00ee Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 4 Sep 2025 21:37:00 +0900 Subject: [PATCH 0855/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 2f534ed1311..312067a3373 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -23983,10 +23983,10 @@ ImgOps | https://imgops.com/#b#`; var scrolled=getScrolled(offsetParent); - targetPosi.top = targetPosi.top - bodyPosi.top + scrolled.y; - targetPosi.left = targetPosi.left - bodyPosi.left + scrolled.x; - targetPosi.bottom = bodyPosi.bottom - targetPosi.bottom - scrolled.y; - targetPosi.right = bodyPosi.right - targetPosi.right - scrolled.x; + targetPosi.top = targetPosi.top - bodyPosi.top; + targetPosi.left = targetPosi.left - bodyPosi.left; + targetPosi.bottom = bodyPosi.bottom - targetPosi.bottom; + targetPosi.right = bodyPosi.right - targetPosi.right; var fbs = this.floatBar.style; var setPosition = { From 5a9edda1417046b8d91802aca4c1fa5356ea4433 Mon Sep 17 00:00:00 2001 From: Bug-Cache <98657967+Bug-Cache@users.noreply.github.com> Date: Fri, 5 Sep 2025 05:08:46 +0700 Subject: [PATCH 0856/1065] Update pagetualRules.json: woot https://github.com/hoothin/UserScripts/issues/971 --- Pagetual/pagetualRules.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 9d7a7207672..0bef18b9b67 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -1,4 +1,12 @@ [ +{ + "name": "Woot", + "url": "^https?://www\\.woot\\.com/", + "example": "https://www.woot.com/alldeals?ref=w_ngh_et_1", + "author": "Hoothin", + "nextLink": "//div[text()='Next >']", + "pinUrl": true +}, { "name": "Fapello", "url": "^https?://fapello\\.com/", From 596ff8c94bfe8d533377c4190260bd3e72e7908f Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 4 Sep 2025 23:37:55 +0000 Subject: [PATCH 0857/1065] Update version of Pagetual rules to 100 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 3ad5abd03ae..29d6383b52c 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -99 +100 From 3ad8308d640bd5e6575c6b4892913d8e149a1541 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 5 Sep 2025 18:33:26 +0900 Subject: [PATCH 0858/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index d7e487e9cbf..8a7a30ffffa 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -188,7 +188,12 @@ var siteInfo = [ if (!a) return; var reg = /&objurl=(http.*?\.(?:jpg|jpeg|png|gif|bmp))/i; if (a.href.match(reg)) { - return decodeURIComponent(RegExp.$1); + let url = RegExp.$1; + try { + url = decodeURIComponent(url); + url = decodeURIComponent(url); + }catch(e){} + return url; } } }, From 3c6d4397d718e6ae7cba2302fba29cdabf515b02 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 5 Sep 2025 18:46:05 +0900 Subject: [PATCH 0859/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 8a7a30ffffa..a6bf401d6b4 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -186,7 +186,7 @@ var siteInfo = [ url: /^https?:\/\/image\.baidu\.com\/.*&word=/i, getImage: function(a) { if (!a) return; - var reg = /&objurl=(http.*?\.(?:jpg|jpeg|png|gif|bmp))/i; + var reg = /&objurl=(http.*?\.(?:jpg|jpeg|png|gif|bmp|webp))/i; if (a.href.match(reg)) { let url = RegExp.$1; try { From 1288ce74aa5ede60305c9184784e1be741bdd6d1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 5 Sep 2025 18:47:23 +0900 Subject: [PATCH 0860/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 39 +++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 312067a3373..770f1fdd59e 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.4.1 +// @version 2025.9.5.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1652811/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1655189/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1653424/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 @@ -12540,8 +12540,8 @@ ImgOps | https://imgops.com/#b#`; showSmallSize:true,//是否默认显示小尺寸图片 disableArrow:false, - scrollEndAndLoad: false, // 滚动主窗口到最底部,然后自动重载库的图片。还有bug,有待进一步测试 - scrollEndAndLoad_num: 3, // 最后几张图片执行 + scrollEndAndLoad: true, // 滚动主窗口到最底部,然后自动重载库的图片。 + scrollEndAndLoad_num: 6, // 最后几张图片执行 autoZoom: false, // 如果有放大,则把图片及 sidebar 部分的缩放改回 100%,增大可视面积(仅在 chrome 下有效) descriptionLength: 32, // 注释的最大宽度 @@ -14632,7 +14632,13 @@ ImgOps | https://imgops.com/#b#`; self.switchThumbVisible();//切换图片类别显隐; },true); - prefs.gallery.scrollEndAndLoad = !!storage.getListItem("scrollEndAndLoad", location.hostname); + let scrollEndAndLoad = storage.getListItem("scrollEndAndLoad", location.hostname); + if (scrollEndAndLoad === true) { + prefs.gallery.scrollEndAndLoad = true; + } else if (scrollEndAndLoad === false) { + prefs.gallery.scrollEndAndLoad = false; + } + eleMaps['head-command-drop-list-others'].querySelector('input[data-command="scrollToEndAndReload"]').checked = prefs.gallery.scrollEndAndLoad; let srcSplit, downloading=false, saveParams; async function getSaveParams() { @@ -16284,6 +16290,11 @@ ImgOps | https://imgops.com/#b#`; url: imgSrc, responseType: 'blob', onload: function(response) { + if (response.response && response.response.type == "text/html") { + self.showTips(""); + loadError(); + return; + } const blobUrl = URL.createObjectURL(response.response); self.showTips(""); let img = document.createElement("img"); @@ -16741,6 +16752,12 @@ ImgOps | https://imgops.com/#b#`; url: src, responseType: 'blob', onload: function(response) { + if (response.response && response.response.type == "text/html") { + self.errorSpan=ele; + if(preImgR)preImgR.abort(); + self.loadImg(this, ele, true); + return; + } const blobUrl = URL.createObjectURL(response.response); self.slideShow.run('loadEnd'); let img = document.createElement("img"); @@ -18052,13 +18069,13 @@ ImgOps | https://imgops.com/#b#`; } }, getAllValidImgs:async function(newer, checkListenBg){ - var validImgs = []; - var container = document.querySelector('.pv-gallery-container'), + let validImgs = []; + let container = document.querySelector('.pv-gallery-container'), preloadContainer = document.querySelector('.pv-gallery-preloaded-img-container'); - var bgReg = /.*?url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; - var body = getBody(document); - var linkMedias = []; + let bgReg = /^\s*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; + let body = getBody(document); + let linkMedias = []; function anylizeEle(total, node) { if (/^iframe$/i.test(node.nodeName)) { if (node.name == "pagetual-iframe") return total; @@ -19203,7 +19220,7 @@ ImgOps | https://imgops.com/#b#`; border-top: 0px solid transparent;\ }\ .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-head{\ - opacity: 0.1;\ + opacity: 0;\ transition: opacity .3s ease;\ }\ .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-body>.pv-gallery-img-container{\ From cc56ed2b645a2ecb526ac2583509a15421fe405d Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 5 Sep 2025 19:55:02 +0900 Subject: [PATCH 0861/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 770f1fdd59e..3230e421116 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.5.1 +// @version 2025.9.5.2 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -12541,7 +12541,7 @@ ImgOps | https://imgops.com/#b#`; disableArrow:false, scrollEndAndLoad: true, // 滚动主窗口到最底部,然后自动重载库的图片。 - scrollEndAndLoad_num: 6, // 最后几张图片执行 + scrollEndAndLoad_num: 5, // 最后几张图片执行 autoZoom: false, // 如果有放大,则把图片及 sidebar 部分的缩放改回 100%,增大可视面积(仅在 chrome 下有效) descriptionLength: 32, // 注释的最大宽度 @@ -12647,7 +12647,7 @@ ImgOps | https://imgops.com/#b#`; } ]; - const imageReg = /^\s*(http|ftp).*\.(avi|avif|avifs|bmp|gif|gifv|ico|jfif|jpe|jpeg|jpg|jif|jfi|a?png|svgz?|webp|xbm|dib|divx|3gpp|m3u|m4v|mkv|mp4|mpe?g|ogv|webm|flv|flac|m4a|m4b|mpa|mp3|aac|cda|oga|ogg|opus|wma|wav)(&|\?|#|\/?$|\s)/i; + const imageReg = /^\s*(https?|ftp):\/\/.*?\/[^\.]*\.(avi|avif|avifs|bmp|gif|gifv|ico|jfif|jpe|jpeg|jpg|jif|jfi|a?png|svgz?|webp|xbm|dib|divx|3gpp|m3u|m4v|mkv|mp4|mpe?g|ogv|webm|flv|flac|m4a|m4b|mpa|mp3|aac|cda|oga|ogg|opus|wma|wav)(&|\?|#|\/?$|\s)/i; const ruleImportHost = ["greasyfork.org", "github.com", "reddit.com"]; const ruleImportUrlReg = /greasyfork\.org\/.*scripts\/24204(\-[^\/]*)?(\/discussions|\/?$|\/feedback)|github\.com\/hoothin\/UserScripts\/(tree\/master\/Picviewer%20CE%2B|issues|discussions)|\.reddit\.com\/r\/PicviewerCE/i; @@ -16739,13 +16739,14 @@ ImgOps | https://imgops.com/#b#`; }; if(src!=self.lastLoading)return; + let img = this; if(e.type=='error'){ if (loadingIndicator && loadingIndicator.style) loadingIndicator.style.display=''; if (/^blob:/.test(src)) { self.errorSpan=ele; if(preImgR)preImgR.abort(); - self.loadImg(this, ele,true); + self.loadImg(img, ele,true); } else { _GM_xmlhttpRequest({ method: 'GET', @@ -16755,7 +16756,7 @@ ImgOps | https://imgops.com/#b#`; if (response.response && response.response.type == "text/html") { self.errorSpan=ele; if(preImgR)preImgR.abort(); - self.loadImg(this, ele, true); + self.loadImg(img, ele, true); return; } const blobUrl = URL.createObjectURL(response.response); @@ -16774,7 +16775,7 @@ ImgOps | https://imgops.com/#b#`; onerror: function() { self.errorSpan=ele; if(preImgR)preImgR.abort(); - self.loadImg(this, ele, true); + self.loadImg(img, ele, true); } }); } From 32aaea49bb04a8da81e6fba38e68eaa80ffa03e6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 5 Sep 2025 20:07:26 +0900 Subject: [PATCH 0862/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 3230e421116..3cdd8c0b8c1 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12393,6 +12393,7 @@ ImgOps | https://imgops.com/#b#`; if (!blob.type) return urlToBlob(url, cb, forcePng, tryTimes); let ext = blob.type.replace(/.*image\/([\w\-]+).*/, "$1"); if (ext === "text/html" && (blob.size || 0) < 1000) return cb(null, ''); + if (ext === "none") ext = "webp"; let conversion = formatDict.get(ext); if (canvas && (conversion || forcePng)) { var self = this; From 36a07a00a7e8df34a8dd1a1e2a90f86c626f10a5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 6 Sep 2025 10:14:40 +0900 Subject: [PATCH 0863/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index a6bf401d6b4..1681c198b16 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -872,6 +872,9 @@ var siteInfo = [ } else if (p[3]) { let a = p[3].querySelector("a.group"); if (a) return a.href; + else if(p[3].previousElementSibling && p[3].previousElementSibling.getAttribute('slot') == 'full-post-link') { + return p[3].previousElementSibling.href; + } } }, headers: (url, self) => { From a02177731bf9d511d8bc2d24161478b9259ffe40 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 6 Sep 2025 10:15:20 +0900 Subject: [PATCH 0864/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 3cdd8c0b8c1..dd09ef9073c 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1655189/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1653424/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 From 621deff92a1b6b36101c4e173af59851ff106047 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 6 Sep 2025 15:48:09 +0900 Subject: [PATCH 0865/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 2479f1e6e5e..f9c24858c4f 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -98,8 +98,6 @@ // @connect * // @contributionURL https://ko-fi.com/hoothin // @contributionAmount 1 -// @downloadURL https://update.greasyfork.org/scripts/438684/Pagetual.user.js -// @updateURL https://update.greasyfork.org/scripts/438684/Pagetual.meta.js // ==/UserScript== (function() { From 268e475cf6246d56df2d9a91c58a2f82ff10489b Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:04:30 +0900 Subject: [PATCH 0866/1065] Create build-dist.yml --- .github/workflows/build-dist.yml | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/build-dist.yml diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml new file mode 100644 index 00000000000..9da77dcadc5 --- /dev/null +++ b/.github/workflows/build-dist.yml @@ -0,0 +1,34 @@ +name: Build Picviewer CE+ Dist + +on: + push: + branches: + - master + paths: + - 'Picviewer CE*/Picviewer CE*.user.js' + +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: | + TIMESTAMP=$(date +%s) + + sed -e "s#// @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js#// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=$TIMESTAMP#" \ + -e "s#// @require https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js#// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=$TIMESTAMP#" \ + -e "s#// @require https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js#// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=$TIMESTAMP#" \ + "Picviewer CE+/Picviewer CE+.user.js" > "Picviewer CE+/dist.user.js" + + - name: Commit and push dist.user.js + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: "chore(Picviewer CE+): Auto-generate dist.user.js with timestamp" + file_pattern: 'Picviewer CE+/dist.user.js' + commit_user_name: GitHub Actions + commit_user_email: rixixi@gmail.com + commit_author: GitHub Actions \ No newline at end of file From 2051bd69250ab1a8dc305a56e001b6468dd0670d Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:05:04 +0900 Subject: [PATCH 0867/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index dd09ef9073c..77b2308bb08 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -48,8 +48,6 @@ // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js // @require https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1653424/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 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* From 404af3ef40a29d304b08b05c4a2c9bf6b767da1b Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:10:07 +0900 Subject: [PATCH 0868/1065] Update build-dist.yml --- .github/workflows/build-dist.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index 9da77dcadc5..3d96b507613 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -25,10 +25,9 @@ jobs: "Picviewer CE+/Picviewer CE+.user.js" > "Picviewer CE+/dist.user.js" - name: Commit and push dist.user.js - uses: stefanzweifel/git-auto-commit-action@v5 - with: - commit_message: "chore(Picviewer CE+): Auto-generate dist.user.js with timestamp" - file_pattern: 'Picviewer CE+/dist.user.js' - commit_user_name: GitHub Actions - commit_user_email: rixixi@gmail.com - commit_author: GitHub Actions \ No newline at end of file + 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 with timestamp" + git push https://${{ secrets.ACTION_SECRET }}@github.com/${{ github.repository }} \ No newline at end of file From 361e9f97b9b9ac7456d848511eb550294f4cff5d Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:11:51 +0900 Subject: [PATCH 0869/1065] Update build-dist.yml --- .github/workflows/build-dist.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index 3d96b507613..fb33500caf8 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -6,6 +6,7 @@ on: - master paths: - 'Picviewer CE*/Picviewer CE*.user.js' + workflow_dispatch: jobs: build: From 8f1fcf0775339dceee30477253197821eb2b893e Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:17:15 +0900 Subject: [PATCH 0870/1065] Update build-dist.yml --- .github/workflows/build-dist.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index fb33500caf8..88c92b44c76 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -29,6 +29,6 @@ jobs: run: | git config --local user.email "rixixi@gmail.com" git config --local user.name "hoothin-update" - git add Picviewer CE+/dist.user.js + git add "Picviewer CE+/dist.user.js" git commit -m "chore(Picviewer CE+): Auto-generate dist.user.js with timestamp" git push https://${{ secrets.ACTION_SECRET }}@github.com/${{ github.repository }} \ No newline at end of file From 79975ab221933a93562745f90df0d80e3ccd2194 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 7 Sep 2025 01:17:56 +0000 Subject: [PATCH 0871/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 27547 +++++++++++++++++++++++++++++++++++ 1 file changed, 27547 insertions(+) create mode 100644 Picviewer CE+/dist.user.js diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js new file mode 100644 index 00000000000..77b2308bb08 --- /dev/null +++ b/Picviewer CE+/dist.user.js @@ -0,0 +1,27547 @@ +// ==UserScript== +// @name Picviewer CE+ +// @name:zh-CN Picviewer CE+ +// @name:zh-TW Picviewer CE+ +// @name:ja Picviewer CE+ +// @name:pt-BR Picviewer CE+ +// @name:ru Picviewer CE+ +// @author NLF && ywzhaiqi && hoothin +// @description Powerful picture viewing tool online, which can popup/scale/rotate/batch save pictures automatically +// @description:zh-CN 在线看图工具,支持图片翻转、旋转、缩放、弹出大图、批量保存 +// @description:zh-TW 線上看圖工具,支援圖片翻轉、旋轉、縮放、彈出大圖、批量儲存 +// @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 2025.9.5.2 +// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== +// @namespace https://github.com/hoothin/UserScripts +// @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B +// @supportURL https://github.com/hoothin/UserScripts/issues +// @connect www.google.com +// @connect www.google.com.hk +// @connect www.google.co.jp +// @connect ipv4.google.com +// @connect image.baidu.com +// @connect www.tineye.com +// @connect hoothin.com +// @connect * +// @grant GM_getValue +// @grant GM_setValue +// @grant GM_deleteValue +// @grant GM_addStyle +// @grant GM_openInTab +// @grant GM_setClipboard +// @grant GM_xmlhttpRequest +// @grant GM_registerMenuCommand +// @grant GM_notification +// @grant GM_download +// @grant GM.getValue +// @grant GM.setValue +// @grant GM.deleteValue +// @grant GM.addStyle +// @grant GM.openInTab +// @grant GM.setClipboard +// @grant GM.xmlHttpRequest +// @grant GM.registerMenuCommand +// @grant GM.notification +// @grant unsafeWindow +// @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js +// @require https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js +// @match *://*/* +// @exclude http://www.toodledo.com/tasks/* +// @exclude http*://maps.google.com*/* +// @exclude *://www.google.*/_/chrome/newtab* +// @exclude *://mega.*/* +// @exclude *://*.mega.*/* +// @exclude *://onedrive.live.com/* +// @run-at document-end +// @created 2011-6-15 +// @contributionURL https://ko-fi.com/hoothin +// @contributionAmount 1 +// ==/UserScript== + +if (window.top != window.self) { + try { + if ((window.self.innerWidth && window.self.innerWidth < 250) || (window.self.innerHeight && window.self.innerHeight < 250)) { + return; + } + } catch(e) { + return; + } +} + +(function (global, factory) { + if (typeof define === "function" && define.amd) { + define([], factory); + } else if (typeof exports !== "undefined") { + factory(); + } else { + var mod = { + exports: {} + }; + factory(); + global.FileSaver = mod.exports; + } +})(this, function () { + "use strict"; + + /* + * FileSaver.js + * A saveAs() FileSaver implementation. + * + * By Eli Grey, http://eligrey.com + * + * License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT) + * source : http://purl.eligrey.com/github/FileSaver.js + */ + // The one and only way of getting global scope in all environments + // https://stackoverflow.com/q/3277182/1008999 + var _global = typeof window === 'object' && window.window === window ? window : typeof self === 'object' && self.self === self ? self : typeof global === 'object' && global.global === global ? global : void 0; + + function bom(blob, opts) { + if (typeof opts === 'undefined') opts = { + autoBom: false + };else if (typeof opts !== 'object') { + console.warn('Deprecated: Expected third argument to be a object'); + opts = { + autoBom: !opts + }; + } // prepend BOM for UTF-8 XML and text/* types (including HTML) + // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF + + if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { + return new Blob([String.fromCharCode(0xFEFF), blob], { + type: blob.type + }); + } + + return blob; + } + + function download(url, name, opts) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'blob'; + + xhr.onload = function () { + saveAs(xhr.response, name, opts); + }; + + xhr.onerror = function () { + console.error('could not download file'); + }; + + xhr.send(); + } + + function corsEnabled(url) { + var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker + + xhr.open('HEAD', url, false); + + try { + xhr.send(); + } catch (e) {} + + return xhr.status >= 200 && xhr.status <= 299; + } // `a.click()` doesn't work for all browsers (#465) + + + function click(node) { + try { + node.dispatchEvent(new MouseEvent('click')); + } catch (e) { + var evt = document.createEvent('MouseEvents'); + evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null); + node.dispatchEvent(evt); + } + } // Detect WebView inside a native macOS app by ruling out all browsers + // We just need to check for 'Safari' because all other browsers (besides Firefox) include that too + // https://www.whatismybrowser.com/guides/the-latest-user-agent/macos + + + var isMacOSWebView = _global.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent); + var URL = _global.URL || _global.webkitURL; + var revokeObjectURL = URL.revokeObjectURL; + var createObjectURL = URL.createObjectURL; + var saveAs = _global.saveAs || ( // probably in some web worker + typeof window !== 'object' || window !== _global ? function saveAs() {} + /* noop */ + // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView + : 'download' in HTMLAnchorElement.prototype && !isMacOSWebView ? function saveAs(blob, name, opts) { + var URL = _global.URL || _global.webkitURL; + var a = document.createElement('a'); + name = name || blob.name || 'download'; + a.download = name; + a.rel = 'noopener'; // tabnabbing + // TODO: detect chrome extensions & packaged apps + // a.target = '_blank' + + if (typeof blob === 'string') { + // Support regular links + a.href = blob; + + if (a.origin !== location.origin) { + corsEnabled(a.href) ? download(blob, name, opts) : click(a, a.target = '_blank'); + } else { + click(a); + } + } else { + // Support blobs + a.href = createObjectURL(blob); + setTimeout(function () { + revokeObjectURL(a.href); + }, 4E4); // 40s + + setTimeout(function () { + click(a); + }, 0); + } + } // Use msSaveOrOpenBlob as a second approach + : 'msSaveOrOpenBlob' in navigator ? function saveAs(blob, name, opts) { + name = name || blob.name || 'download'; + + if (typeof blob === 'string') { + if (corsEnabled(blob)) { + download(blob, name, opts); + } else { + var a = document.createElement('a'); + a.href = blob; + a.target = '_blank'; + setTimeout(function () { + click(a); + }); + } + } else { + navigator.msSaveOrOpenBlob(bom(blob, opts), name); + } + } // Fallback to using FileReader and a popup + : function saveAs(blob, name, opts, popup) { + // Open a popup immediately do go around popup blocker + // Mostly only available on user interaction and the fileReader is async so... + popup = popup || open('', '_blank'); + + if (popup) { + popup.document.title = popup.document.body.innerText = 'downloading...'; + } + + if (typeof blob === 'string') return download(blob, name, opts); + var force = blob.type === 'application/octet-stream'; + + var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari; + + var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent); + + if ((isChromeIOS || force && isSafari || isMacOSWebView) && typeof FileReader !== 'undefined') { + // Safari doesn't allow downloading of blob URLs + var reader = new FileReader(); + + reader.onloadend = function () { + var url = reader.result; + url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;'); + if (popup) popup.location.href = url;else location = url; + popup = null; // reverse-tabnabbing #460 + }; + + reader.readAsDataURL(blob); + } else { + var url = createObjectURL(blob); + if (popup) popup.location = url;else location.href = url; + popup = null; // reverse-tabnabbing #460 + + setTimeout(function () { + revokeObjectURL(url); + }, 4E4); // 40s + } + }); + _global.saveAs = saveAs.saveAs = saveAs; + + if (typeof module !== 'undefined') { + module.exports = saveAs; + } +}); + +/*! + +JSZip v3.7.1 - A JavaScript class for generating and reading zip files + + +(c) 2009-2016 Stuart Knightley +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown. + +JSZip uses the library pako released under the MIT license : +https://github.com/nodeca/pako/blob/master/LICENSE +*/ + +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.JSZip = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = remainingBytes > 1 ? (((chr2 & 15) << 2) | (chr3 >> 6)) : 64; + enc4 = remainingBytes > 2 ? (chr3 & 63) : 64; + + output.push(_keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4)); + + } + + return output.join(""); +}; + +// public method for decoding +exports.decode = function(input) { + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0, resultIndex = 0; + + var dataUrlPrefix = "data:"; + + if (input.substr(0, dataUrlPrefix.length) === dataUrlPrefix) { + // This is a common error: people give a data url + // (data:image/png;base64,iVBOR...) with a {base64: true} and + // wonders why things don't work. + // We can detect that the string input looks like a data url but we + // *can't* be sure it is one: removing everything up to the comma would + // be too dangerous. + throw new Error("Invalid base64 input, it looks like a data url."); + } + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + var totalLength = input.length * 3 / 4; + if(input.charAt(input.length - 1) === _keyStr.charAt(64)) { + totalLength--; + } + if(input.charAt(input.length - 2) === _keyStr.charAt(64)) { + totalLength--; + } + if (totalLength % 1 !== 0) { + // totalLength is not an integer, the length does not match a valid + // base64 content. That can happen if: + // - the input is not a base64 content + // - the input is *almost* a base64 content, with a extra chars at the + // beginning or at the end + // - the input uses a base64 variant (base64url for example) + throw new Error("Invalid base64 input, bad content length."); + } + var output; + if (support.uint8array) { + output = new Uint8Array(totalLength|0); + } else { + output = new Array(totalLength|0); + } + + while (i < input.length) { + + enc1 = _keyStr.indexOf(input.charAt(i++)); + enc2 = _keyStr.indexOf(input.charAt(i++)); + enc3 = _keyStr.indexOf(input.charAt(i++)); + enc4 = _keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output[resultIndex++] = chr1; + + if (enc3 !== 64) { + output[resultIndex++] = chr2; + } + if (enc4 !== 64) { + output[resultIndex++] = chr3; + } + + } + + return output; +}; + +},{"./support":30,"./utils":32}],2:[function(require,module,exports){ +'use strict'; + +var external = require("./external"); +var DataWorker = require('./stream/DataWorker'); +var Crc32Probe = require('./stream/Crc32Probe'); +var DataLengthProbe = require('./stream/DataLengthProbe'); + +/** + * Represent a compressed object, with everything needed to decompress it. + * @constructor + * @param {number} compressedSize the size of the data compressed. + * @param {number} uncompressedSize the size of the data after decompression. + * @param {number} crc32 the crc32 of the decompressed file. + * @param {object} compression the type of compression, see lib/compressions.js. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the compressed data. + */ +function CompressedObject(compressedSize, uncompressedSize, crc32, compression, data) { + this.compressedSize = compressedSize; + this.uncompressedSize = uncompressedSize; + this.crc32 = crc32; + this.compression = compression; + this.compressedContent = data; +} + +CompressedObject.prototype = { + /** + * Create a worker to get the uncompressed content. + * @return {GenericWorker} the worker. + */ + getContentWorker: function () { + var worker = new DataWorker(external.Promise.resolve(this.compressedContent)) + .pipe(this.compression.uncompressWorker()) + .pipe(new DataLengthProbe("data_length")); + + var that = this; + worker.on("end", function () { + if (this.streamInfo['data_length'] !== that.uncompressedSize) { + throw new Error("Bug : uncompressed data size mismatch"); + } + }); + return worker; + }, + /** + * Create a worker to get the compressed content. + * @return {GenericWorker} the worker. + */ + getCompressedWorker: function () { + return new DataWorker(external.Promise.resolve(this.compressedContent)) + .withStreamInfo("compressedSize", this.compressedSize) + .withStreamInfo("uncompressedSize", this.uncompressedSize) + .withStreamInfo("crc32", this.crc32) + .withStreamInfo("compression", this.compression) + ; + } +}; + +/** + * Chain the given worker with other workers to compress the content with the + * given compression. + * @param {GenericWorker} uncompressedWorker the worker to pipe. + * @param {Object} compression the compression object. + * @param {Object} compressionOptions the options to use when compressing. + * @return {GenericWorker} the new worker compressing the content. + */ +CompressedObject.createWorkerFrom = function (uncompressedWorker, compression, compressionOptions) { + return uncompressedWorker + .pipe(new Crc32Probe()) + .pipe(new DataLengthProbe("uncompressedSize")) + .pipe(compression.compressWorker(compressionOptions)) + .pipe(new DataLengthProbe("compressedSize")) + .withStreamInfo("compression", compression); +}; + +module.exports = CompressedObject; + +},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(require,module,exports){ +'use strict'; + +var GenericWorker = require("./stream/GenericWorker"); + +exports.STORE = { + magic: "\x00\x00", + compressWorker : function (compressionOptions) { + return new GenericWorker("STORE compression"); + }, + uncompressWorker : function () { + return new GenericWorker("STORE decompression"); + } +}; +exports.DEFLATE = require('./flate'); + +},{"./flate":7,"./stream/GenericWorker":28}],4:[function(require,module,exports){ +'use strict'; + +var utils = require('./utils'); + +/** + * The following functions come from pako, from pako/lib/zlib/crc32.js + * released under the MIT license, see pako https://github.com/nodeca/pako/ + */ + +// Use ordinary array, since untyped makes no boost here +function makeTable() { + var c, table = []; + + for(var n =0; n < 256; n++){ + c = n; + for(var k =0; k < 8; k++){ + c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); + } + table[n] = c; + } + + return table; +} + +// Create table on load. Just 255 signed longs. Not a problem. +var crcTable = makeTable(); + + +function crc32(crc, buf, len, pos) { + var t = crcTable, end = pos + len; + + crc = crc ^ (-1); + + for (var i = pos; i < end; i++ ) { + crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +} + +// That's all for the pako functions. + +/** + * Compute the crc32 of a string. + * This is almost the same as the function crc32, but for strings. Using the + * same function for the two use cases leads to horrible performances. + * @param {Number} crc the starting value of the crc. + * @param {String} str the string to use. + * @param {Number} len the length of the string. + * @param {Number} pos the starting position for the crc32 computation. + * @return {Number} the computed crc32. + */ +function crc32str(crc, str, len, pos) { + var t = crcTable, end = pos + len; + + crc = crc ^ (-1); + + for (var i = pos; i < end; i++ ) { + crc = (crc >>> 8) ^ t[(crc ^ str.charCodeAt(i)) & 0xFF]; + } + + return (crc ^ (-1)); // >>> 0; +} + +module.exports = function crc32wrapper(input, crc) { + if (typeof input === "undefined" || !input.length) { + return 0; + } + + var isArray = utils.getTypeOf(input) !== "string"; + + if(isArray) { + return crc32(crc|0, input, input.length, 0); + } else { + return crc32str(crc|0, input, input.length, 0); + } +}; + +},{"./utils":32}],5:[function(require,module,exports){ +'use strict'; +exports.base64 = false; +exports.binary = false; +exports.dir = false; +exports.createFolders = true; +exports.date = null; +exports.compression = null; +exports.compressionOptions = null; +exports.comment = null; +exports.unixPermissions = null; +exports.dosPermissions = null; + +},{}],6:[function(require,module,exports){ +/* global Promise */ +'use strict'; + +// load the global object first: +// - it should be better integrated in the system (unhandledRejection in node) +// - the environment may have a custom Promise implementation (see zone.js) +var ES6Promise = null; +if (typeof Promise !== "undefined") { + ES6Promise = Promise; +} else { + ES6Promise = require("lie"); +} + +/** + * Let the user use/change some implementations. + */ +module.exports = { + Promise: ES6Promise +}; + +},{"lie":37}],7:[function(require,module,exports){ +'use strict'; +var USE_TYPEDARRAY = (typeof Uint8Array !== 'undefined') && (typeof Uint16Array !== 'undefined') && (typeof Uint32Array !== 'undefined'); + +var pako = require("pako"); +var utils = require("./utils"); +var GenericWorker = require("./stream/GenericWorker"); + +var ARRAY_TYPE = USE_TYPEDARRAY ? "uint8array" : "array"; + +exports.magic = "\x08\x00"; + +/** + * Create a worker that uses pako to inflate/deflate. + * @constructor + * @param {String} action the name of the pako function to call : either "Deflate" or "Inflate". + * @param {Object} options the options to use when (de)compressing. + */ +function FlateWorker(action, options) { + GenericWorker.call(this, "FlateWorker/" + action); + + this._pako = null; + this._pakoAction = action; + this._pakoOptions = options; + // the `meta` object from the last chunk received + // this allow this worker to pass around metadata + this.meta = {}; +} + +utils.inherits(FlateWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +FlateWorker.prototype.processChunk = function (chunk) { + this.meta = chunk.meta; + if (this._pako === null) { + this._createPako(); + } + this._pako.push(utils.transformTo(ARRAY_TYPE, chunk.data), false); +}; + +/** + * @see GenericWorker.flush + */ +FlateWorker.prototype.flush = function () { + GenericWorker.prototype.flush.call(this); + if (this._pako === null) { + this._createPako(); + } + this._pako.push([], true); +}; +/** + * @see GenericWorker.cleanUp + */ +FlateWorker.prototype.cleanUp = function () { + GenericWorker.prototype.cleanUp.call(this); + this._pako = null; +}; + +/** + * Create the _pako object. + * TODO: lazy-loading this object isn't the best solution but it's the + * quickest. The best solution is to lazy-load the worker list. See also the + * issue #446. + */ +FlateWorker.prototype._createPako = function () { + this._pako = new pako[this._pakoAction]({ + raw: true, + level: this._pakoOptions.level || -1 // default compression + }); + var self = this; + this._pako.onData = function(data) { + self.push({ + data : data, + meta : self.meta + }); + }; +}; + +exports.compressWorker = function (compressionOptions) { + return new FlateWorker("Deflate", compressionOptions); +}; +exports.uncompressWorker = function () { + return new FlateWorker("Inflate", {}); +}; + +},{"./stream/GenericWorker":28,"./utils":32,"pako":38}],8:[function(require,module,exports){ +'use strict'; + +var utils = require('../utils'); +var GenericWorker = require('../stream/GenericWorker'); +var utf8 = require('../utf8'); +var crc32 = require('../crc32'); +var signature = require('../signature'); + +/** + * Transform an integer into a string in hexadecimal. + * @private + * @param {number} dec the number to convert. + * @param {number} bytes the number of bytes to generate. + * @returns {string} the result. + */ +var decToHex = function(dec, bytes) { + var hex = "", i; + for (i = 0; i < bytes; i++) { + hex += String.fromCharCode(dec & 0xff); + dec = dec >>> 8; + } + return hex; +}; + +/** + * Generate the UNIX part of the external file attributes. + * @param {Object} unixPermissions the unix permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * adapted from http://unix.stackexchange.com/questions/14705/the-zip-formats-external-file-attribute : + * + * TTTTsstrwxrwxrwx0000000000ADVSHR + * ^^^^____________________________ file type, see zipinfo.c (UNX_*) + * ^^^_________________________ setuid, setgid, sticky + * ^^^^^^^^^________________ permissions + * ^^^^^^^^^^______ not used ? + * ^^^^^^ DOS attribute bits : Archive, Directory, Volume label, System file, Hidden, Read only + */ +var generateUnixExternalFileAttr = function (unixPermissions, isDir) { + + var result = unixPermissions; + if (!unixPermissions) { + // I can't use octal values in strict mode, hence the hexa. + // 040775 => 0x41fd + // 0100664 => 0x81b4 + result = isDir ? 0x41fd : 0x81b4; + } + return (result & 0xFFFF) << 16; +}; + +/** + * Generate the DOS part of the external file attributes. + * @param {Object} dosPermissions the dos permissions or null. + * @param {Boolean} isDir true if the entry is a directory, false otherwise. + * @return {Number} a 32 bit integer. + * + * Bit 0 Read-Only + * Bit 1 Hidden + * Bit 2 System + * Bit 3 Volume Label + * Bit 4 Directory + * Bit 5 Archive + */ +var generateDosExternalFileAttr = function (dosPermissions, isDir) { + + // the dir flag is already set for compatibility + return (dosPermissions || 0) & 0x3F; +}; + +/** + * Generate the various parts used in the construction of the final zip file. + * @param {Object} streamInfo the hash with information about the compressed file. + * @param {Boolean} streamedContent is the content streamed ? + * @param {Boolean} streamingEnded is the stream finished ? + * @param {number} offset the current offset from the start of the zip file. + * @param {String} platform let's pretend we are this platform (change platform dependents fields) + * @param {Function} encodeFileName the function to encode the file name / comment. + * @return {Object} the zip parts. + */ +var generateZipParts = function(streamInfo, streamedContent, streamingEnded, offset, platform, encodeFileName) { + var file = streamInfo['file'], + compression = streamInfo['compression'], + useCustomEncoding = encodeFileName !== utf8.utf8encode, + encodedFileName = utils.transformTo("string", encodeFileName(file.name)), + utfEncodedFileName = utils.transformTo("string", utf8.utf8encode(file.name)), + comment = file.comment, + encodedComment = utils.transformTo("string", encodeFileName(comment)), + utfEncodedComment = utils.transformTo("string", utf8.utf8encode(comment)), + useUTF8ForFileName = utfEncodedFileName.length !== file.name.length, + useUTF8ForComment = utfEncodedComment.length !== comment.length, + dosTime, + dosDate, + extraFields = "", + unicodePathExtraField = "", + unicodeCommentExtraField = "", + dir = file.dir, + date = file.date; + + + var dataInfo = { + crc32 : 0, + compressedSize : 0, + uncompressedSize : 0 + }; + + // if the content is streamed, the sizes/crc32 are only available AFTER + // the end of the stream. + if (!streamedContent || streamingEnded) { + dataInfo.crc32 = streamInfo['crc32']; + dataInfo.compressedSize = streamInfo['compressedSize']; + dataInfo.uncompressedSize = streamInfo['uncompressedSize']; + } + + var bitflag = 0; + if (streamedContent) { + // Bit 3: the sizes/crc32 are set to zero in the local header. + // The correct values are put in the data descriptor immediately + // following the compressed data. + bitflag |= 0x0008; + } + if (!useCustomEncoding && (useUTF8ForFileName || useUTF8ForComment)) { + // Bit 11: Language encoding flag (EFS). + bitflag |= 0x0800; + } + + + var extFileAttr = 0; + var versionMadeBy = 0; + if (dir) { + // dos or unix, we set the dos dir flag + extFileAttr |= 0x00010; + } + if(platform === "UNIX") { + versionMadeBy = 0x031E; // UNIX, version 3.0 + extFileAttr |= generateUnixExternalFileAttr(file.unixPermissions, dir); + } else { // DOS or other, fallback to DOS + versionMadeBy = 0x0014; // DOS, version 2.0 + extFileAttr |= generateDosExternalFileAttr(file.dosPermissions, dir); + } + + // date + // @see http://www.delorie.com/djgpp/doc/rbinter/it/52/13.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/65/16.html + // @see http://www.delorie.com/djgpp/doc/rbinter/it/66/16.html + + dosTime = date.getUTCHours(); + dosTime = dosTime << 6; + dosTime = dosTime | date.getUTCMinutes(); + dosTime = dosTime << 5; + dosTime = dosTime | date.getUTCSeconds() / 2; + + dosDate = date.getUTCFullYear() - 1980; + dosDate = dosDate << 4; + dosDate = dosDate | (date.getUTCMonth() + 1); + dosDate = dosDate << 5; + dosDate = dosDate | date.getUTCDate(); + + if (useUTF8ForFileName) { + // set the unicode path extra field. unzip needs at least one extra + // field to correctly handle unicode path, so using the path is as good + // as any other information. This could improve the situation with + // other archive managers too. + // This field is usually used without the utf8 flag, with a non + // unicode path in the header (winrar, winzip). This helps (a bit) + // with the messy Windows' default compressed folders feature but + // breaks on p7zip which doesn't seek the unicode path extra field. + // So for now, UTF-8 everywhere ! + unicodePathExtraField = + // Version + decToHex(1, 1) + + // NameCRC32 + decToHex(crc32(encodedFileName), 4) + + // UnicodeName + utfEncodedFileName; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x70" + + // size + decToHex(unicodePathExtraField.length, 2) + + // content + unicodePathExtraField; + } + + if(useUTF8ForComment) { + + unicodeCommentExtraField = + // Version + decToHex(1, 1) + + // CommentCRC32 + decToHex(crc32(encodedComment), 4) + + // UnicodeName + utfEncodedComment; + + extraFields += + // Info-ZIP Unicode Path Extra Field + "\x75\x63" + + // size + decToHex(unicodeCommentExtraField.length, 2) + + // content + unicodeCommentExtraField; + } + + var header = ""; + + // version needed to extract + header += "\x0A\x00"; + // general purpose bit flag + header += decToHex(bitflag, 2); + // compression method + header += compression.magic; + // last mod file time + header += decToHex(dosTime, 2); + // last mod file date + header += decToHex(dosDate, 2); + // crc-32 + header += decToHex(dataInfo.crc32, 4); + // compressed size + header += decToHex(dataInfo.compressedSize, 4); + // uncompressed size + header += decToHex(dataInfo.uncompressedSize, 4); + // file name length + header += decToHex(encodedFileName.length, 2); + // extra field length + header += decToHex(extraFields.length, 2); + + + var fileRecord = signature.LOCAL_FILE_HEADER + header + encodedFileName + extraFields; + + var dirRecord = signature.CENTRAL_FILE_HEADER + + // version made by (00: DOS) + decToHex(versionMadeBy, 2) + + // file header (common to file and central directory) + header + + // file comment length + decToHex(encodedComment.length, 2) + + // disk number start + "\x00\x00" + + // internal file attributes TODO + "\x00\x00" + + // external file attributes + decToHex(extFileAttr, 4) + + // relative offset of local header + decToHex(offset, 4) + + // file name + encodedFileName + + // extra field + extraFields + + // file comment + encodedComment; + + return { + fileRecord: fileRecord, + dirRecord: dirRecord + }; +}; + +/** + * Generate the EOCD record. + * @param {Number} entriesCount the number of entries in the zip file. + * @param {Number} centralDirLength the length (in bytes) of the central dir. + * @param {Number} localDirLength the length (in bytes) of the local dir. + * @param {String} comment the zip file comment as a binary string. + * @param {Function} encodeFileName the function to encode the comment. + * @return {String} the EOCD record. + */ +var generateCentralDirectoryEnd = function (entriesCount, centralDirLength, localDirLength, comment, encodeFileName) { + var dirEnd = ""; + var encodedComment = utils.transformTo("string", encodeFileName(comment)); + + // end of central dir signature + dirEnd = signature.CENTRAL_DIRECTORY_END + + // number of this disk + "\x00\x00" + + // number of the disk with the start of the central directory + "\x00\x00" + + // total number of entries in the central directory on this disk + decToHex(entriesCount, 2) + + // total number of entries in the central directory + decToHex(entriesCount, 2) + + // size of the central directory 4 bytes + decToHex(centralDirLength, 4) + + // offset of start of central directory with respect to the starting disk number + decToHex(localDirLength, 4) + + // .ZIP file comment length + decToHex(encodedComment.length, 2) + + // .ZIP file comment + encodedComment; + + return dirEnd; +}; + +/** + * Generate data descriptors for a file entry. + * @param {Object} streamInfo the hash generated by a worker, containing information + * on the file entry. + * @return {String} the data descriptors. + */ +var generateDataDescriptors = function (streamInfo) { + var descriptor = ""; + descriptor = signature.DATA_DESCRIPTOR + + // crc-32 4 bytes + decToHex(streamInfo['crc32'], 4) + + // compressed size 4 bytes + decToHex(streamInfo['compressedSize'], 4) + + // uncompressed size 4 bytes + decToHex(streamInfo['uncompressedSize'], 4); + + return descriptor; +}; + + +/** + * A worker to concatenate other workers to create a zip file. + * @param {Boolean} streamFiles `true` to stream the content of the files, + * `false` to accumulate it. + * @param {String} comment the comment to use. + * @param {String} platform the platform to use, "UNIX" or "DOS". + * @param {Function} encodeFileName the function to encode file names and comments. + */ +function ZipFileWorker(streamFiles, comment, platform, encodeFileName) { + GenericWorker.call(this, "ZipFileWorker"); + // The number of bytes written so far. This doesn't count accumulated chunks. + this.bytesWritten = 0; + // The comment of the zip file + this.zipComment = comment; + // The platform "generating" the zip file. + this.zipPlatform = platform; + // the function to encode file names and comments. + this.encodeFileName = encodeFileName; + // Should we stream the content of the files ? + this.streamFiles = streamFiles; + // If `streamFiles` is false, we will need to accumulate the content of the + // files to calculate sizes / crc32 (and write them *before* the content). + // This boolean indicates if we are accumulating chunks (it will change a lot + // during the lifetime of this worker). + this.accumulate = false; + // The buffer receiving chunks when accumulating content. + this.contentBuffer = []; + // The list of generated directory records. + this.dirRecords = []; + // The offset (in bytes) from the beginning of the zip file for the current source. + this.currentSourceOffset = 0; + // The total number of entries in this zip file. + this.entriesCount = 0; + // the name of the file currently being added, null when handling the end of the zip file. + // Used for the emitted metadata. + this.currentFile = null; + + + + this._sources = []; +} +utils.inherits(ZipFileWorker, GenericWorker); + +/** + * @see GenericWorker.push + */ +ZipFileWorker.prototype.push = function (chunk) { + + var currentFilePercent = chunk.meta.percent || 0; + var entriesCount = this.entriesCount; + var remainingFiles = this._sources.length; + + if(this.accumulate) { + this.contentBuffer.push(chunk); + } else { + this.bytesWritten += chunk.data.length; + + GenericWorker.prototype.push.call(this, { + data : chunk.data, + meta : { + currentFile : this.currentFile, + percent : entriesCount ? (currentFilePercent + 100 * (entriesCount - remainingFiles - 1)) / entriesCount : 100 + } + }); + } +}; + +/** + * The worker started a new source (an other worker). + * @param {Object} streamInfo the streamInfo object from the new source. + */ +ZipFileWorker.prototype.openedSource = function (streamInfo) { + this.currentSourceOffset = this.bytesWritten; + this.currentFile = streamInfo['file'].name; + + var streamedContent = this.streamFiles && !streamInfo['file'].dir; + + // don't stream folders (because they don't have any content) + if(streamedContent) { + var record = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName); + this.push({ + data : record.fileRecord, + meta : {percent:0} + }); + } else { + // we need to wait for the whole file before pushing anything + this.accumulate = true; + } +}; + +/** + * The worker finished a source (an other worker). + * @param {Object} streamInfo the streamInfo object from the finished source. + */ +ZipFileWorker.prototype.closedSource = function (streamInfo) { + this.accumulate = false; + var streamedContent = this.streamFiles && !streamInfo['file'].dir; + var record = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName); + + this.dirRecords.push(record.dirRecord); + if(streamedContent) { + // after the streamed file, we put data descriptors + this.push({ + data : generateDataDescriptors(streamInfo), + meta : {percent:100} + }); + } else { + // the content wasn't streamed, we need to push everything now + // first the file record, then the content + this.push({ + data : record.fileRecord, + meta : {percent:0} + }); + while(this.contentBuffer.length) { + this.push(this.contentBuffer.shift()); + } + } + this.currentFile = null; +}; + +/** + * @see GenericWorker.flush + */ +ZipFileWorker.prototype.flush = function () { + + var localDirLength = this.bytesWritten; + for(var i = 0; i < this.dirRecords.length; i++) { + this.push({ + data : this.dirRecords[i], + meta : {percent:100} + }); + } + var centralDirLength = this.bytesWritten - localDirLength; + + var dirEnd = generateCentralDirectoryEnd(this.dirRecords.length, centralDirLength, localDirLength, this.zipComment, this.encodeFileName); + + this.push({ + data : dirEnd, + meta : {percent:100} + }); +}; + +/** + * Prepare the next source to be read. + */ +ZipFileWorker.prototype.prepareNextSource = function () { + this.previous = this._sources.shift(); + this.openedSource(this.previous.streamInfo); + if (this.isPaused) { + this.previous.pause(); + } else { + this.previous.resume(); + } +}; + +/** + * @see GenericWorker.registerPrevious + */ +ZipFileWorker.prototype.registerPrevious = function (previous) { + this._sources.push(previous); + var self = this; + + previous.on('data', function (chunk) { + self.processChunk(chunk); + }); + previous.on('end', function () { + self.closedSource(self.previous.streamInfo); + if(self._sources.length) { + self.prepareNextSource(); + } else { + self.end(); + } + }); + previous.on('error', function (e) { + self.error(e); + }); + return this; +}; + +/** + * @see GenericWorker.resume + */ +ZipFileWorker.prototype.resume = function () { + if(!GenericWorker.prototype.resume.call(this)) { + return false; + } + + if (!this.previous && this._sources.length) { + this.prepareNextSource(); + return true; + } + if (!this.previous && !this._sources.length && !this.generatedError) { + this.end(); + return true; + } +}; + +/** + * @see GenericWorker.error + */ +ZipFileWorker.prototype.error = function (e) { + var sources = this._sources; + if(!GenericWorker.prototype.error.call(this, e)) { + return false; + } + for(var i = 0; i < sources.length; i++) { + try { + sources[i].error(e); + } catch(e) { + // the `error` exploded, nothing to do + } + } + return true; +}; + +/** + * @see GenericWorker.lock + */ +ZipFileWorker.prototype.lock = function () { + GenericWorker.prototype.lock.call(this); + var sources = this._sources; + for(var i = 0; i < sources.length; i++) { + sources[i].lock(); + } +}; + +module.exports = ZipFileWorker; + +},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(require,module,exports){ +'use strict'; + +var compressions = require('../compressions'); +var ZipFileWorker = require('./ZipFileWorker'); + +/** + * Find the compression to use. + * @param {String} fileCompression the compression defined at the file level, if any. + * @param {String} zipCompression the compression defined at the load() level. + * @return {Object} the compression object to use. + */ +var getCompression = function (fileCompression, zipCompression) { + + var compressionName = fileCompression || zipCompression; + var compression = compressions[compressionName]; + if (!compression) { + throw new Error(compressionName + " is not a valid compression method !"); + } + return compression; +}; + +/** + * Create a worker to generate a zip file. + * @param {JSZip} zip the JSZip instance at the right root level. + * @param {Object} options to generate the zip file. + * @param {String} comment the comment to use. + */ +exports.generateWorker = function (zip, options, comment) { + + var zipFileWorker = new ZipFileWorker(options.streamFiles, comment, options.platform, options.encodeFileName); + var entriesCount = 0; + try { + + zip.forEach(function (relativePath, file) { + entriesCount++; + var compression = getCompression(file.options.compression, options.compression); + var compressionOptions = file.options.compressionOptions || options.compressionOptions || {}; + var dir = file.dir, date = file.date; + + file._compressWorker(compression, compressionOptions) + .withStreamInfo("file", { + name : relativePath, + dir : dir, + date : date, + comment : file.comment || "", + unixPermissions : file.unixPermissions, + dosPermissions : file.dosPermissions + }) + .pipe(zipFileWorker); + }); + zipFileWorker.entriesCount = entriesCount; + } catch (e) { + zipFileWorker.error(e); + } + + return zipFileWorker; +}; + +},{"../compressions":3,"./ZipFileWorker":8}],10:[function(require,module,exports){ +'use strict'; + +/** + * Representation a of zip file in js + * @constructor + */ +function JSZip() { + // if this constructor is used without `new`, it adds `new` before itself: + if(!(this instanceof JSZip)) { + return new JSZip(); + } + + if(arguments.length) { + throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide."); + } + + // object containing the files : + // { + // "folder/" : {...}, + // "folder/data.txt" : {...} + // } + // NOTE: we use a null prototype because we do not + // want filenames like "toString" coming from a zip file + // to overwrite methods and attributes in a normal Object. + this.files = Object.create(null); + + this.comment = null; + + // Where we are in the hierarchy + this.root = ""; + this.clone = function() { + var newObj = new JSZip(); + for (var i in this) { + if (typeof this[i] !== "function") { + newObj[i] = this[i]; + } + } + return newObj; + }; +} +JSZip.prototype = require('./object'); +JSZip.prototype.loadAsync = require('./load'); +JSZip.support = require('./support'); +JSZip.defaults = require('./defaults'); + +// TODO find a better way to handle this version, +// a require('package.json').version doesn't work with webpack, see #327 +JSZip.version = "3.7.1"; + +JSZip.loadAsync = function (content, options) { + return new JSZip().loadAsync(content, options); +}; + +JSZip.external = require("./external"); +module.exports = JSZip; + +},{"./defaults":5,"./external":6,"./load":11,"./object":15,"./support":30}],11:[function(require,module,exports){ +'use strict'; +var utils = require('./utils'); +var external = require("./external"); +var utf8 = require('./utf8'); +var ZipEntries = require('./zipEntries'); +var Crc32Probe = require('./stream/Crc32Probe'); +var nodejsUtils = require("./nodejsUtils"); + +/** + * Check the CRC32 of an entry. + * @param {ZipEntry} zipEntry the zip entry to check. + * @return {Promise} the result. + */ +function checkEntryCRC32(zipEntry) { + return new external.Promise(function (resolve, reject) { + var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe()); + worker.on("error", function (e) { + reject(e); + }) + .on("end", function () { + if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) { + reject(new Error("Corrupted zip : CRC32 mismatch")); + } else { + resolve(); + } + }) + .resume(); + }); +} + +module.exports = function (data, options) { + var zip = this; + options = utils.extend(options || {}, { + base64: false, + checkCRC32: false, + optimizedBinaryString: false, + createFolders: false, + decodeFileName: utf8.utf8decode + }); + + if (nodejsUtils.isNode && nodejsUtils.isStream(data)) { + return external.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")); + } + + return utils.prepareContent("the loaded zip file", data, true, options.optimizedBinaryString, options.base64) + .then(function (data) { + var zipEntries = new ZipEntries(options); + zipEntries.load(data); + return zipEntries; + }).then(function checkCRC32(zipEntries) { + var promises = [external.Promise.resolve(zipEntries)]; + var files = zipEntries.files; + if (options.checkCRC32) { + for (var i = 0; i < files.length; i++) { + promises.push(checkEntryCRC32(files[i])); + } + } + return external.Promise.all(promises); + }).then(function addFiles(results) { + var zipEntries = results.shift(); + var files = zipEntries.files; + for (var i = 0; i < files.length; i++) { + var input = files[i]; + zip.file(input.fileNameStr, input.decompressed, { + binary: true, + optimizedBinaryString: true, + date: input.date, + dir: input.dir, + comment: input.fileCommentStr.length ? input.fileCommentStr : null, + unixPermissions: input.unixPermissions, + dosPermissions: input.dosPermissions, + createFolders: options.createFolders + }); + } + if (zipEntries.zipComment.length) { + zip.comment = zipEntries.zipComment; + } + + return zip; + }); +}; + +},{"./external":6,"./nodejsUtils":14,"./stream/Crc32Probe":25,"./utf8":31,"./utils":32,"./zipEntries":33}],12:[function(require,module,exports){ +"use strict"; + +var utils = require('../utils'); +var GenericWorker = require('../stream/GenericWorker'); + +/** + * A worker that use a nodejs stream as source. + * @constructor + * @param {String} filename the name of the file entry for this stream. + * @param {Readable} stream the nodejs stream. + */ +function NodejsStreamInputAdapter(filename, stream) { + GenericWorker.call(this, "Nodejs stream input adapter for " + filename); + this._upstreamEnded = false; + this._bindStream(stream); +} + +utils.inherits(NodejsStreamInputAdapter, GenericWorker); + +/** + * Prepare the stream and bind the callbacks on it. + * Do this ASAP on node 0.10 ! A lazy binding doesn't always work. + * @param {Stream} stream the nodejs stream to use. + */ +NodejsStreamInputAdapter.prototype._bindStream = function (stream) { + var self = this; + this._stream = stream; + stream.pause(); + stream + .on("data", function (chunk) { + self.push({ + data: chunk, + meta : { + percent : 0 + } + }); + }) + .on("error", function (e) { + if(self.isPaused) { + this.generatedError = e; + } else { + self.error(e); + } + }) + .on("end", function () { + if(self.isPaused) { + self._upstreamEnded = true; + } else { + self.end(); + } + }); +}; +NodejsStreamInputAdapter.prototype.pause = function () { + if(!GenericWorker.prototype.pause.call(this)) { + return false; + } + this._stream.pause(); + return true; +}; +NodejsStreamInputAdapter.prototype.resume = function () { + if(!GenericWorker.prototype.resume.call(this)) { + return false; + } + + if(this._upstreamEnded) { + this.end(); + } else { + this._stream.resume(); + } + + return true; +}; + +module.exports = NodejsStreamInputAdapter; + +},{"../stream/GenericWorker":28,"../utils":32}],13:[function(require,module,exports){ +'use strict'; + +var Readable = require('readable-stream').Readable; + +var utils = require('../utils'); +utils.inherits(NodejsStreamOutputAdapter, Readable); + +/** +* A nodejs stream using a worker as source. +* @see the SourceWrapper in http://nodejs.org/api/stream.html +* @constructor +* @param {StreamHelper} helper the helper wrapping the worker +* @param {Object} options the nodejs stream options +* @param {Function} updateCb the update callback. +*/ +function NodejsStreamOutputAdapter(helper, options, updateCb) { + Readable.call(this, options); + this._helper = helper; + + var self = this; + helper.on("data", function (data, meta) { + if (!self.push(data)) { + self._helper.pause(); + } + if(updateCb) { + updateCb(meta); + } + }) + .on("error", function(e) { + self.emit('error', e); + }) + .on("end", function () { + self.push(null); + }); +} + + +NodejsStreamOutputAdapter.prototype._read = function() { + this._helper.resume(); +}; + +module.exports = NodejsStreamOutputAdapter; + +},{"../utils":32,"readable-stream":16}],14:[function(require,module,exports){ +'use strict'; + +module.exports = { + /** + * True if this is running in Nodejs, will be undefined in a browser. + * In a browser, browserify won't include this file and the whole module + * will be resolved an empty object. + */ + isNode : typeof Buffer !== "undefined", + /** + * Create a new nodejs Buffer from an existing content. + * @param {Object} data the data to pass to the constructor. + * @param {String} encoding the encoding to use. + * @return {Buffer} a new Buffer. + */ + newBufferFrom: function(data, encoding) { + if (Buffer.from && Buffer.from !== Uint8Array.from) { + return Buffer.from(data, encoding); + } else { + if (typeof data === "number") { + // Safeguard for old Node.js versions. On newer versions, + // Buffer.from(number) / Buffer(number, encoding) already throw. + throw new Error("The \"data\" argument must not be a number"); + } + return new Buffer(data, encoding); + } + }, + /** + * Create a new nodejs Buffer with the specified size. + * @param {Integer} size the size of the buffer. + * @return {Buffer} a new Buffer. + */ + allocBuffer: function (size) { + if (Buffer.alloc) { + return Buffer.alloc(size); + } else { + var buf = new Buffer(size); + buf.fill(0); + return buf; + } + }, + /** + * Find out if an object is a Buffer. + * @param {Object} b the object to test. + * @return {Boolean} true if the object is a Buffer, false otherwise. + */ + isBuffer : function(b){ + return Buffer.isBuffer(b); + }, + + isStream : function (obj) { + return obj && + typeof obj.on === "function" && + typeof obj.pause === "function" && + typeof obj.resume === "function"; + } +}; + +},{}],15:[function(require,module,exports){ +'use strict'; +var utf8 = require('./utf8'); +var utils = require('./utils'); +var GenericWorker = require('./stream/GenericWorker'); +var StreamHelper = require('./stream/StreamHelper'); +var defaults = require('./defaults'); +var CompressedObject = require('./compressedObject'); +var ZipObject = require('./zipObject'); +var generate = require("./generate"); +var nodejsUtils = require("./nodejsUtils"); +var NodejsStreamInputAdapter = require("./nodejs/NodejsStreamInputAdapter"); + + +/** + * Add a file in the current folder. + * @private + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data of the file + * @param {Object} originalOptions the options of the file + * @return {Object} the new file. + */ +var fileAdd = function(name, data, originalOptions) { + // be sure sub folders exist + var dataType = utils.getTypeOf(data), + parent; + + + /* + * Correct options. + */ + + var o = utils.extend(originalOptions || {}, defaults); + o.date = o.date || new Date(); + if (o.compression !== null) { + o.compression = o.compression.toUpperCase(); + } + + if (typeof o.unixPermissions === "string") { + o.unixPermissions = parseInt(o.unixPermissions, 8); + } + + // UNX_IFDIR 0040000 see zipinfo.c + if (o.unixPermissions && (o.unixPermissions & 0x4000)) { + o.dir = true; + } + // Bit 4 Directory + if (o.dosPermissions && (o.dosPermissions & 0x0010)) { + o.dir = true; + } + + if (o.dir) { + name = forceTrailingSlash(name); + } + if (o.createFolders && (parent = parentFolder(name))) { + folderAdd.call(this, parent, true); + } + + var isUnicodeString = dataType === "string" && o.binary === false && o.base64 === false; + if (!originalOptions || typeof originalOptions.binary === "undefined") { + o.binary = !isUnicodeString; + } + + + var isCompressedEmpty = (data instanceof CompressedObject) && data.uncompressedSize === 0; + + if (isCompressedEmpty || o.dir || !data || data.length === 0) { + o.base64 = false; + o.binary = true; + data = ""; + o.compression = "STORE"; + dataType = "string"; + } + + /* + * Convert content to fit. + */ + + var zipObjectContent = null; + if (data instanceof CompressedObject || data instanceof GenericWorker) { + zipObjectContent = data; + } else if (nodejsUtils.isNode && nodejsUtils.isStream(data)) { + zipObjectContent = new NodejsStreamInputAdapter(name, data); + } else { + zipObjectContent = utils.prepareContent(name, data, o.binary, o.optimizedBinaryString, o.base64); + } + + var object = new ZipObject(name, zipObjectContent, o); + this.files[name] = object; + /* + TODO: we can't throw an exception because we have async promises + (we can have a promise of a Date() for example) but returning a + promise is useless because file(name, data) returns the JSZip + object for chaining. Should we break that to allow the user + to catch the error ? + + return external.Promise.resolve(zipObjectContent) + .then(function () { + return object; + }); + */ +}; + +/** + * Find the parent folder of the path. + * @private + * @param {string} path the path to use + * @return {string} the parent folder, or "" + */ +var parentFolder = function (path) { + if (path.slice(-1) === '/') { + path = path.substring(0, path.length - 1); + } + var lastSlash = path.lastIndexOf('/'); + return (lastSlash > 0) ? path.substring(0, lastSlash) : ""; +}; + +/** + * Returns the path with a slash at the end. + * @private + * @param {String} path the path to check. + * @return {String} the path with a trailing slash. + */ +var forceTrailingSlash = function(path) { + // Check the name ends with a / + if (path.slice(-1) !== "/") { + path += "/"; // IE doesn't like substr(-1) + } + return path; +}; + +/** + * Add a (sub) folder in the current folder. + * @private + * @param {string} name the folder's name + * @param {boolean=} [createFolders] If true, automatically create sub + * folders. Defaults to false. + * @return {Object} the new folder. + */ +var folderAdd = function(name, createFolders) { + createFolders = (typeof createFolders !== 'undefined') ? createFolders : defaults.createFolders; + + name = forceTrailingSlash(name); + + // Does this folder already exist? + if (!this.files[name]) { + fileAdd.call(this, name, null, { + dir: true, + createFolders: createFolders + }); + } + return this.files[name]; +}; + +/** +* Cross-window, cross-Node-context regular expression detection +* @param {Object} object Anything +* @return {Boolean} true if the object is a regular expression, +* false otherwise +*/ +function isRegExp(object) { + return Object.prototype.toString.call(object) === "[object RegExp]"; +} + +// return the actual prototype of JSZip +var out = { + /** + * @see loadAsync + */ + load: function() { + throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); + }, + + + /** + * Call a callback function for each entry at this folder level. + * @param {Function} cb the callback function: + * function (relativePath, file) {...} + * It takes 2 arguments : the relative path and the file. + */ + forEach: function(cb) { + var filename, relativePath, file; + /* jshint ignore:start */ + // ignore warning about unwanted properties because this.files is a null prototype object + for (filename in this.files) { + file = this.files[filename]; + relativePath = filename.slice(this.root.length, filename.length); + if (relativePath && filename.slice(0, this.root.length) === this.root) { // the file is in the current root + cb(relativePath, file); // TODO reverse the parameters ? need to be clean AND consistent with the filter search fn... + } + } + /* jshint ignore:end */ + }, + + /** + * Filter nested files/folders with the specified function. + * @param {Function} search the predicate to use : + * function (relativePath, file) {...} + * It takes 2 arguments : the relative path and the file. + * @return {Array} An array of matching elements. + */ + filter: function(search) { + var result = []; + this.forEach(function (relativePath, entry) { + if (search(relativePath, entry)) { // the file matches the function + result.push(entry); + } + + }); + return result; + }, + + /** + * Add a file to the zip file, or search a file. + * @param {string|RegExp} name The name of the file to add (if data is defined), + * the name of the file to find (if no data) or a regex to match files. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data The file data, either raw or base64 encoded + * @param {Object} o File options + * @return {JSZip|Object|Array} this JSZip object (when adding a file), + * a file (when searching by string) or an array of files (when searching by regex). + */ + file: function(name, data, o) { + if (arguments.length === 1) { + if (isRegExp(name)) { + var regexp = name; + return this.filter(function(relativePath, file) { + return !file.dir && regexp.test(relativePath); + }); + } + else { // text + var obj = this.files[this.root + name]; + if (obj && !obj.dir) { + return obj; + } else { + return null; + } + } + } + else { // more than one argument : we have data ! + name = this.root + name; + fileAdd.call(this, name, data, o); + } + return this; + }, + + /** + * Add a directory to the zip file, or search. + * @param {String|RegExp} arg The name of the directory to add, or a regex to search folders. + * @return {JSZip} an object with the new directory as the root, or an array containing matching folders. + */ + folder: function(arg) { + if (!arg) { + return this; + } + + if (isRegExp(arg)) { + return this.filter(function(relativePath, file) { + return file.dir && arg.test(relativePath); + }); + } + + // else, name is a new folder + var name = this.root + arg; + var newFolder = folderAdd.call(this, name); + + // Allow chaining by returning a new object with this folder as the root + var ret = this.clone(); + ret.root = newFolder.name; + return ret; + }, + + /** + * Delete a file, or a directory and all sub-files, from the zip + * @param {string} name the name of the file to delete + * @return {JSZip} this JSZip object + */ + remove: function(name) { + name = this.root + name; + var file = this.files[name]; + if (!file) { + // Look for any folders + if (name.slice(-1) !== "/") { + name += "/"; + } + file = this.files[name]; + } + + if (file && !file.dir) { + // file + delete this.files[name]; + } else { + // maybe a folder, delete recursively + var kids = this.filter(function(relativePath, file) { + return file.name.slice(0, name.length) === name; + }); + for (var i = 0; i < kids.length; i++) { + delete this.files[kids[i].name]; + } + } + + return this; + }, + + /** + * Generate the complete zip file + * @param {Object} options the options to generate the zip file : + * - compression, "STORE" by default. + * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. + * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the zip file + */ + generate: function(options) { + throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); + }, + + /** + * Generate the complete zip file as an internal stream. + * @param {Object} options the options to generate the zip file : + * - compression, "STORE" by default. + * - type, "base64" by default. Values are : string, base64, uint8array, arraybuffer, blob. + * @return {StreamHelper} the streamed zip file. + */ + generateInternalStream: function(options) { + var worker, opts = {}; + try { + opts = utils.extend(options || {}, { + streamFiles: false, + compression: "STORE", + compressionOptions : null, + type: "", + platform: "DOS", + comment: null, + mimeType: 'application/zip', + encodeFileName: utf8.utf8encode + }); + + opts.type = opts.type.toLowerCase(); + opts.compression = opts.compression.toUpperCase(); + + // "binarystring" is preferred but the internals use "string". + if(opts.type === "binarystring") { + opts.type = "string"; + } + + if (!opts.type) { + throw new Error("No output type specified."); + } + + utils.checkSupport(opts.type); + + // accept nodejs `process.platform` + if( + opts.platform === 'darwin' || + opts.platform === 'freebsd' || + opts.platform === 'linux' || + opts.platform === 'sunos' + ) { + opts.platform = "UNIX"; + } + if (opts.platform === 'win32') { + opts.platform = "DOS"; + } + + var comment = opts.comment || this.comment || ""; + worker = generate.generateWorker(this, opts, comment); + } catch (e) { + worker = new GenericWorker("error"); + worker.error(e); + } + return new StreamHelper(worker, opts.type || "string", opts.mimeType); + }, + /** + * Generate the complete zip file asynchronously. + * @see generateInternalStream + */ + generateAsync: function(options, onUpdate) { + return this.generateInternalStream(options).accumulate(onUpdate); + }, + /** + * Generate the complete zip file asynchronously. + * @see generateInternalStream + */ + generateNodeStream: function(options, onUpdate) { + options = options || {}; + if (!options.type) { + options.type = "nodebuffer"; + } + return this.generateInternalStream(options).toNodejsStream(onUpdate); + } +}; +module.exports = out; + +},{"./compressedObject":2,"./defaults":5,"./generate":9,"./nodejs/NodejsStreamInputAdapter":12,"./nodejsUtils":14,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31,"./utils":32,"./zipObject":35}],16:[function(require,module,exports){ +/* + * This file is used by module bundlers (browserify/webpack/etc) when + * including a stream implementation. We use "readable-stream" to get a + * consistent behavior between nodejs versions but bundlers often have a shim + * for "stream". Using this shim greatly improve the compatibility and greatly + * reduce the final size of the bundle (only one stream implementation, not + * two). + */ +module.exports = require("stream"); + +},{"stream":undefined}],17:[function(require,module,exports){ +'use strict'; +var DataReader = require('./DataReader'); +var utils = require('../utils'); + +function ArrayReader(data) { + DataReader.call(this, data); + for(var i = 0; i < this.data.length; i++) { + data[i] = data[i] & 0xFF; + } +} +utils.inherits(ArrayReader, DataReader); +/** + * @see DataReader.byteAt + */ +ArrayReader.prototype.byteAt = function(i) { + return this.data[this.zero + i]; +}; +/** + * @see DataReader.lastIndexOfSignature + */ +ArrayReader.prototype.lastIndexOfSignature = function(sig) { + var sig0 = sig.charCodeAt(0), + sig1 = sig.charCodeAt(1), + sig2 = sig.charCodeAt(2), + sig3 = sig.charCodeAt(3); + for (var i = this.length - 4; i >= 0; --i) { + if (this.data[i] === sig0 && this.data[i + 1] === sig1 && this.data[i + 2] === sig2 && this.data[i + 3] === sig3) { + return i - this.zero; + } + } + + return -1; +}; +/** + * @see DataReader.readAndCheckSignature + */ +ArrayReader.prototype.readAndCheckSignature = function (sig) { + var sig0 = sig.charCodeAt(0), + sig1 = sig.charCodeAt(1), + sig2 = sig.charCodeAt(2), + sig3 = sig.charCodeAt(3), + data = this.readData(4); + return sig0 === data[0] && sig1 === data[1] && sig2 === data[2] && sig3 === data[3]; +}; +/** + * @see DataReader.readData + */ +ArrayReader.prototype.readData = function(size) { + this.checkOffset(size); + if(size === 0) { + return []; + } + var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = ArrayReader; + +},{"../utils":32,"./DataReader":18}],18:[function(require,module,exports){ +'use strict'; +var utils = require('../utils'); + +function DataReader(data) { + this.data = data; // type : see implementation + this.length = data.length; + this.index = 0; + this.zero = 0; +} +DataReader.prototype = { + /** + * Check that the offset will not go too far. + * @param {string} offset the additional offset to check. + * @throws {Error} an Error if the offset is out of bounds. + */ + checkOffset: function(offset) { + this.checkIndex(this.index + offset); + }, + /** + * Check that the specified index will not be too far. + * @param {string} newIndex the index to check. + * @throws {Error} an Error if the index is out of bounds. + */ + checkIndex: function(newIndex) { + if (this.length < this.zero + newIndex || newIndex < 0) { + throw new Error("End of data reached (data length = " + this.length + ", asked index = " + (newIndex) + "). Corrupted zip ?"); + } + }, + /** + * Change the index. + * @param {number} newIndex The new index. + * @throws {Error} if the new index is out of the data. + */ + setIndex: function(newIndex) { + this.checkIndex(newIndex); + this.index = newIndex; + }, + /** + * Skip the next n bytes. + * @param {number} n the number of bytes to skip. + * @throws {Error} if the new index is out of the data. + */ + skip: function(n) { + this.setIndex(this.index + n); + }, + /** + * Get the byte at the specified index. + * @param {number} i the index to use. + * @return {number} a byte. + */ + byteAt: function(i) { + // see implementations + }, + /** + * Get the next number with a given byte size. + * @param {number} size the number of bytes to read. + * @return {number} the corresponding number. + */ + readInt: function(size) { + var result = 0, + i; + this.checkOffset(size); + for (i = this.index + size - 1; i >= this.index; i--) { + result = (result << 8) + this.byteAt(i); + } + this.index += size; + return result; + }, + /** + * Get the next string with a given byte size. + * @param {number} size the number of bytes to read. + * @return {string} the corresponding string. + */ + readString: function(size) { + return utils.transformTo("string", this.readData(size)); + }, + /** + * Get raw data without conversion, bytes. + * @param {number} size the number of bytes to read. + * @return {Object} the raw data, implementation specific. + */ + readData: function(size) { + // see implementations + }, + /** + * Find the last occurrence of a zip signature (4 bytes). + * @param {string} sig the signature to find. + * @return {number} the index of the last occurrence, -1 if not found. + */ + lastIndexOfSignature: function(sig) { + // see implementations + }, + /** + * Read the signature (4 bytes) at the current position and compare it with sig. + * @param {string} sig the expected signature + * @return {boolean} true if the signature matches, false otherwise. + */ + readAndCheckSignature: function(sig) { + // see implementations + }, + /** + * Get the next date. + * @return {Date} the date. + */ + readDate: function() { + var dostime = this.readInt(4); + return new Date(Date.UTC( + ((dostime >> 25) & 0x7f) + 1980, // year + ((dostime >> 21) & 0x0f) - 1, // month + (dostime >> 16) & 0x1f, // day + (dostime >> 11) & 0x1f, // hour + (dostime >> 5) & 0x3f, // minute + (dostime & 0x1f) << 1)); // second + } +}; +module.exports = DataReader; + +},{"../utils":32}],19:[function(require,module,exports){ +'use strict'; +var Uint8ArrayReader = require('./Uint8ArrayReader'); +var utils = require('../utils'); + +function NodeBufferReader(data) { + Uint8ArrayReader.call(this, data); +} +utils.inherits(NodeBufferReader, Uint8ArrayReader); + +/** + * @see DataReader.readData + */ +NodeBufferReader.prototype.readData = function(size) { + this.checkOffset(size); + var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = NodeBufferReader; + +},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(require,module,exports){ +'use strict'; +var DataReader = require('./DataReader'); +var utils = require('../utils'); + +function StringReader(data) { + DataReader.call(this, data); +} +utils.inherits(StringReader, DataReader); +/** + * @see DataReader.byteAt + */ +StringReader.prototype.byteAt = function(i) { + return this.data.charCodeAt(this.zero + i); +}; +/** + * @see DataReader.lastIndexOfSignature + */ +StringReader.prototype.lastIndexOfSignature = function(sig) { + return this.data.lastIndexOf(sig) - this.zero; +}; +/** + * @see DataReader.readAndCheckSignature + */ +StringReader.prototype.readAndCheckSignature = function (sig) { + var data = this.readData(4); + return sig === data; +}; +/** + * @see DataReader.readData + */ +StringReader.prototype.readData = function(size) { + this.checkOffset(size); + // this will work because the constructor applied the "& 0xff" mask. + var result = this.data.slice(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = StringReader; + +},{"../utils":32,"./DataReader":18}],21:[function(require,module,exports){ +'use strict'; +var ArrayReader = require('./ArrayReader'); +var utils = require('../utils'); + +function Uint8ArrayReader(data) { + ArrayReader.call(this, data); +} +utils.inherits(Uint8ArrayReader, ArrayReader); +/** + * @see DataReader.readData + */ +Uint8ArrayReader.prototype.readData = function(size) { + this.checkOffset(size); + if(size === 0) { + // in IE10, when using subarray(idx, idx), we get the array [0x00] instead of []. + return new Uint8Array(0); + } + var result = this.data.subarray(this.zero + this.index, this.zero + this.index + size); + this.index += size; + return result; +}; +module.exports = Uint8ArrayReader; + +},{"../utils":32,"./ArrayReader":17}],22:[function(require,module,exports){ +'use strict'; + +var utils = require('../utils'); +var support = require('../support'); +var ArrayReader = require('./ArrayReader'); +var StringReader = require('./StringReader'); +var NodeBufferReader = require('./NodeBufferReader'); +var Uint8ArrayReader = require('./Uint8ArrayReader'); + +/** + * Create a reader adapted to the data. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data to read. + * @return {DataReader} the data reader. + */ +module.exports = function (data) { + var type = utils.getTypeOf(data); + utils.checkSupport(type); + if (type === "string" && !support.uint8array) { + return new StringReader(data); + } + if (type === "nodebuffer") { + return new NodeBufferReader(data); + } + if (support.uint8array) { + return new Uint8ArrayReader(utils.transformTo("uint8array", data)); + } + return new ArrayReader(utils.transformTo("array", data)); +}; + +},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(require,module,exports){ +'use strict'; +exports.LOCAL_FILE_HEADER = "PK\x03\x04"; +exports.CENTRAL_FILE_HEADER = "PK\x01\x02"; +exports.CENTRAL_DIRECTORY_END = "PK\x05\x06"; +exports.ZIP64_CENTRAL_DIRECTORY_LOCATOR = "PK\x06\x07"; +exports.ZIP64_CENTRAL_DIRECTORY_END = "PK\x06\x06"; +exports.DATA_DESCRIPTOR = "PK\x07\x08"; + +},{}],24:[function(require,module,exports){ +'use strict'; + +var GenericWorker = require('./GenericWorker'); +var utils = require('../utils'); + +/** + * A worker which convert chunks to a specified type. + * @constructor + * @param {String} destType the destination type. + */ +function ConvertWorker(destType) { + GenericWorker.call(this, "ConvertWorker to " + destType); + this.destType = destType; +} +utils.inherits(ConvertWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +ConvertWorker.prototype.processChunk = function (chunk) { + this.push({ + data : utils.transformTo(this.destType, chunk.data), + meta : chunk.meta + }); +}; +module.exports = ConvertWorker; + +},{"../utils":32,"./GenericWorker":28}],25:[function(require,module,exports){ +'use strict'; + +var GenericWorker = require('./GenericWorker'); +var crc32 = require('../crc32'); +var utils = require('../utils'); + +/** + * A worker which calculate the crc32 of the data flowing through. + * @constructor + */ +function Crc32Probe() { + GenericWorker.call(this, "Crc32Probe"); + this.withStreamInfo("crc32", 0); +} +utils.inherits(Crc32Probe, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +Crc32Probe.prototype.processChunk = function (chunk) { + this.streamInfo.crc32 = crc32(chunk.data, this.streamInfo.crc32 || 0); + this.push(chunk); +}; +module.exports = Crc32Probe; + +},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(require,module,exports){ +'use strict'; + +var utils = require('../utils'); +var GenericWorker = require('./GenericWorker'); + +/** + * A worker which calculate the total length of the data flowing through. + * @constructor + * @param {String} propName the name used to expose the length + */ +function DataLengthProbe(propName) { + GenericWorker.call(this, "DataLengthProbe for " + propName); + this.propName = propName; + this.withStreamInfo(propName, 0); +} +utils.inherits(DataLengthProbe, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +DataLengthProbe.prototype.processChunk = function (chunk) { + if(chunk) { + var length = this.streamInfo[this.propName] || 0; + this.streamInfo[this.propName] = length + chunk.data.length; + } + GenericWorker.prototype.processChunk.call(this, chunk); +}; +module.exports = DataLengthProbe; + + +},{"../utils":32,"./GenericWorker":28}],27:[function(require,module,exports){ +'use strict'; + +var utils = require('../utils'); +var GenericWorker = require('./GenericWorker'); + +// the size of the generated chunks +// TODO expose this as a public variable +var DEFAULT_BLOCK_SIZE = 16 * 1024; + +/** + * A worker that reads a content and emits chunks. + * @constructor + * @param {Promise} dataP the promise of the data to split + */ +function DataWorker(dataP) { + GenericWorker.call(this, "DataWorker"); + var self = this; + this.dataIsReady = false; + this.index = 0; + this.max = 0; + this.data = null; + this.type = ""; + + this._tickScheduled = false; + + dataP.then(function (data) { + self.dataIsReady = true; + self.data = data; + self.max = data && data.length || 0; + self.type = utils.getTypeOf(data); + if(!self.isPaused) { + self._tickAndRepeat(); + } + }, function (e) { + self.error(e); + }); +} + +utils.inherits(DataWorker, GenericWorker); + +/** + * @see GenericWorker.cleanUp + */ +DataWorker.prototype.cleanUp = function () { + GenericWorker.prototype.cleanUp.call(this); + this.data = null; +}; + +/** + * @see GenericWorker.resume + */ +DataWorker.prototype.resume = function () { + if(!GenericWorker.prototype.resume.call(this)) { + return false; + } + + if (!this._tickScheduled && this.dataIsReady) { + this._tickScheduled = true; + utils.delay(this._tickAndRepeat, [], this); + } + return true; +}; + +/** + * Trigger a tick a schedule an other call to this function. + */ +DataWorker.prototype._tickAndRepeat = function() { + this._tickScheduled = false; + if(this.isPaused || this.isFinished) { + return; + } + this._tick(); + if(!this.isFinished) { + utils.delay(this._tickAndRepeat, [], this); + this._tickScheduled = true; + } +}; + +/** + * Read and push a chunk. + */ +DataWorker.prototype._tick = function() { + + if(this.isPaused || this.isFinished) { + return false; + } + + var size = DEFAULT_BLOCK_SIZE; + var data = null, nextIndex = Math.min(this.max, this.index + size); + if (this.index >= this.max) { + // EOF + return this.end(); + } else { + switch(this.type) { + case "string": + data = this.data.substring(this.index, nextIndex); + break; + case "uint8array": + data = this.data.subarray(this.index, nextIndex); + break; + case "array": + case "nodebuffer": + data = this.data.slice(this.index, nextIndex); + break; + } + this.index = nextIndex; + return this.push({ + data : data, + meta : { + percent : this.max ? this.index / this.max * 100 : 0 + } + }); + } +}; + +module.exports = DataWorker; + +},{"../utils":32,"./GenericWorker":28}],28:[function(require,module,exports){ +'use strict'; + +/** + * A worker that does nothing but passing chunks to the next one. This is like + * a nodejs stream but with some differences. On the good side : + * - it works on IE 6-9 without any issue / polyfill + * - it weights less than the full dependencies bundled with browserify + * - it forwards errors (no need to declare an error handler EVERYWHERE) + * + * A chunk is an object with 2 attributes : `meta` and `data`. The former is an + * object containing anything (`percent` for example), see each worker for more + * details. The latter is the real data (String, Uint8Array, etc). + * + * @constructor + * @param {String} name the name of the stream (mainly used for debugging purposes) + */ +function GenericWorker(name) { + // the name of the worker + this.name = name || "default"; + // an object containing metadata about the workers chain + this.streamInfo = {}; + // an error which happened when the worker was paused + this.generatedError = null; + // an object containing metadata to be merged by this worker into the general metadata + this.extraStreamInfo = {}; + // true if the stream is paused (and should not do anything), false otherwise + this.isPaused = true; + // true if the stream is finished (and should not do anything), false otherwise + this.isFinished = false; + // true if the stream is locked to prevent further structure updates (pipe), false otherwise + this.isLocked = false; + // the event listeners + this._listeners = { + 'data':[], + 'end':[], + 'error':[] + }; + // the previous worker, if any + this.previous = null; +} + +GenericWorker.prototype = { + /** + * Push a chunk to the next workers. + * @param {Object} chunk the chunk to push + */ + push : function (chunk) { + this.emit("data", chunk); + }, + /** + * End the stream. + * @return {Boolean} true if this call ended the worker, false otherwise. + */ + end : function () { + if (this.isFinished) { + return false; + } + + this.flush(); + try { + this.emit("end"); + this.cleanUp(); + this.isFinished = true; + } catch (e) { + this.emit("error", e); + } + return true; + }, + /** + * End the stream with an error. + * @param {Error} e the error which caused the premature end. + * @return {Boolean} true if this call ended the worker with an error, false otherwise. + */ + error : function (e) { + if (this.isFinished) { + return false; + } + + if(this.isPaused) { + this.generatedError = e; + } else { + this.isFinished = true; + + this.emit("error", e); + + // in the workers chain exploded in the middle of the chain, + // the error event will go downward but we also need to notify + // workers upward that there has been an error. + if(this.previous) { + this.previous.error(e); + } + + this.cleanUp(); + } + return true; + }, + /** + * Add a callback on an event. + * @param {String} name the name of the event (data, end, error) + * @param {Function} listener the function to call when the event is triggered + * @return {GenericWorker} the current object for chainability + */ + on : function (name, listener) { + this._listeners[name].push(listener); + return this; + }, + /** + * Clean any references when a worker is ending. + */ + cleanUp : function () { + this.streamInfo = this.generatedError = this.extraStreamInfo = null; + this._listeners = []; + }, + /** + * Trigger an event. This will call registered callback with the provided arg. + * @param {String} name the name of the event (data, end, error) + * @param {Object} arg the argument to call the callback with. + */ + emit : function (name, arg) { + if (this._listeners[name]) { + for(var i = 0; i < this._listeners[name].length; i++) { + this._listeners[name][i].call(this, arg); + } + } + }, + /** + * Chain a worker with an other. + * @param {Worker} next the worker receiving events from the current one. + * @return {worker} the next worker for chainability + */ + pipe : function (next) { + return next.registerPrevious(this); + }, + /** + * Same as `pipe` in the other direction. + * Using an API with `pipe(next)` is very easy. + * Implementing the API with the point of view of the next one registering + * a source is easier, see the ZipFileWorker. + * @param {Worker} previous the previous worker, sending events to this one + * @return {Worker} the current worker for chainability + */ + registerPrevious : function (previous) { + if (this.isLocked) { + throw new Error("The stream '" + this + "' has already been used."); + } + + // sharing the streamInfo... + this.streamInfo = previous.streamInfo; + // ... and adding our own bits + this.mergeStreamInfo(); + this.previous = previous; + var self = this; + previous.on('data', function (chunk) { + self.processChunk(chunk); + }); + previous.on('end', function () { + self.end(); + }); + previous.on('error', function (e) { + self.error(e); + }); + return this; + }, + /** + * Pause the stream so it doesn't send events anymore. + * @return {Boolean} true if this call paused the worker, false otherwise. + */ + pause : function () { + if(this.isPaused || this.isFinished) { + return false; + } + this.isPaused = true; + + if(this.previous) { + this.previous.pause(); + } + return true; + }, + /** + * Resume a paused stream. + * @return {Boolean} true if this call resumed the worker, false otherwise. + */ + resume : function () { + if(!this.isPaused || this.isFinished) { + return false; + } + this.isPaused = false; + + // if true, the worker tried to resume but failed + var withError = false; + if(this.generatedError) { + this.error(this.generatedError); + withError = true; + } + if(this.previous) { + this.previous.resume(); + } + + return !withError; + }, + /** + * Flush any remaining bytes as the stream is ending. + */ + flush : function () {}, + /** + * Process a chunk. This is usually the method overridden. + * @param {Object} chunk the chunk to process. + */ + processChunk : function(chunk) { + this.push(chunk); + }, + /** + * Add a key/value to be added in the workers chain streamInfo once activated. + * @param {String} key the key to use + * @param {Object} value the associated value + * @return {Worker} the current worker for chainability + */ + withStreamInfo : function (key, value) { + this.extraStreamInfo[key] = value; + this.mergeStreamInfo(); + return this; + }, + /** + * Merge this worker's streamInfo into the chain's streamInfo. + */ + mergeStreamInfo : function () { + for(var key in this.extraStreamInfo) { + if (!this.extraStreamInfo.hasOwnProperty(key)) { + continue; + } + this.streamInfo[key] = this.extraStreamInfo[key]; + } + }, + + /** + * Lock the stream to prevent further updates on the workers chain. + * After calling this method, all calls to pipe will fail. + */ + lock: function () { + if (this.isLocked) { + throw new Error("The stream '" + this + "' has already been used."); + } + this.isLocked = true; + if (this.previous) { + this.previous.lock(); + } + }, + + /** + * + * Pretty print the workers chain. + */ + toString : function () { + var me = "Worker " + this.name; + if (this.previous) { + return this.previous + " -> " + me; + } else { + return me; + } + } +}; + +module.exports = GenericWorker; + +},{}],29:[function(require,module,exports){ +'use strict'; + +var utils = require('../utils'); +var ConvertWorker = require('./ConvertWorker'); +var GenericWorker = require('./GenericWorker'); +var base64 = require('../base64'); +var support = require("../support"); +var external = require("../external"); + +var NodejsStreamOutputAdapter = null; +if (support.nodestream) { + try { + NodejsStreamOutputAdapter = require('../nodejs/NodejsStreamOutputAdapter'); + } catch(e) {} +} + +/** + * Apply the final transformation of the data. If the user wants a Blob for + * example, it's easier to work with an U8intArray and finally do the + * ArrayBuffer/Blob conversion. + * @param {String} type the name of the final type + * @param {String|Uint8Array|Buffer} content the content to transform + * @param {String} mimeType the mime type of the content, if applicable. + * @return {String|Uint8Array|ArrayBuffer|Buffer|Blob} the content in the right format. + */ +function transformZipOutput(type, content, mimeType) { + switch(type) { + case "blob" : + return utils.newBlob(utils.transformTo("arraybuffer", content), mimeType); + case "base64" : + return base64.encode(content); + default : + return utils.transformTo(type, content); + } +} + +/** + * Concatenate an array of data of the given type. + * @param {String} type the type of the data in the given array. + * @param {Array} dataArray the array containing the data chunks to concatenate + * @return {String|Uint8Array|Buffer} the concatenated data + * @throws Error if the asked type is unsupported + */ +function concat (type, dataArray) { + var i, index = 0, res = null, totalLength = 0; + for(i = 0; i < dataArray.length; i++) { + totalLength += dataArray[i].length; + } + switch(type) { + case "string": + return dataArray.join(""); + case "array": + return Array.prototype.concat.apply([], dataArray); + case "uint8array": + res = new Uint8Array(totalLength); + for(i = 0; i < dataArray.length; i++) { + res.set(dataArray[i], index); + index += dataArray[i].length; + } + return res; + case "nodebuffer": + return Buffer.concat(dataArray); + default: + throw new Error("concat : unsupported type '" + type + "'"); + } +} + +/** + * Listen a StreamHelper, accumulate its content and concatenate it into a + * complete block. + * @param {StreamHelper} helper the helper to use. + * @param {Function} updateCallback a callback called on each update. Called + * with one arg : + * - the metadata linked to the update received. + * @return Promise the promise for the accumulation. + */ +function accumulate(helper, updateCallback) { + return new external.Promise(function (resolve, reject){ + var dataArray = []; + var chunkType = helper._internalType, + resultType = helper._outputType, + mimeType = helper._mimeType; + helper + .on('data', function (data, meta) { + dataArray.push(data); + if(updateCallback) { + updateCallback(meta); + } + }) + .on('error', function(err) { + dataArray = []; + reject(err); + }) + .on('end', function (){ + try { + var result = transformZipOutput(resultType, concat(chunkType, dataArray), mimeType); + resolve(result); + } catch (e) { + reject(e); + } + dataArray = []; + }) + .resume(); + }); +} + +/** + * An helper to easily use workers outside of JSZip. + * @constructor + * @param {Worker} worker the worker to wrap + * @param {String} outputType the type of data expected by the use + * @param {String} mimeType the mime type of the content, if applicable. + */ +function StreamHelper(worker, outputType, mimeType) { + var internalType = outputType; + switch(outputType) { + case "blob": + case "arraybuffer": + internalType = "uint8array"; + break; + case "base64": + internalType = "string"; + break; + } + + try { + // the type used internally + this._internalType = internalType; + // the type used to output results + this._outputType = outputType; + // the mime type + this._mimeType = mimeType; + utils.checkSupport(internalType); + this._worker = worker.pipe(new ConvertWorker(internalType)); + // the last workers can be rewired without issues but we need to + // prevent any updates on previous workers. + worker.lock(); + } catch(e) { + this._worker = new GenericWorker("error"); + this._worker.error(e); + } +} + +StreamHelper.prototype = { + /** + * Listen a StreamHelper, accumulate its content and concatenate it into a + * complete block. + * @param {Function} updateCb the update callback. + * @return Promise the promise for the accumulation. + */ + accumulate : function (updateCb) { + return accumulate(this, updateCb); + }, + /** + * Add a listener on an event triggered on a stream. + * @param {String} evt the name of the event + * @param {Function} fn the listener + * @return {StreamHelper} the current helper. + */ + on : function (evt, fn) { + var self = this; + + if(evt === "data") { + this._worker.on(evt, function (chunk) { + fn.call(self, chunk.data, chunk.meta); + }); + } else { + this._worker.on(evt, function () { + utils.delay(fn, arguments, self); + }); + } + return this; + }, + /** + * Resume the flow of chunks. + * @return {StreamHelper} the current helper. + */ + resume : function () { + utils.delay(this._worker.resume, [], this._worker); + return this; + }, + /** + * Pause the flow of chunks. + * @return {StreamHelper} the current helper. + */ + pause : function () { + this._worker.pause(); + return this; + }, + /** + * Return a nodejs stream for this helper. + * @param {Function} updateCb the update callback. + * @return {NodejsStreamOutputAdapter} the nodejs stream. + */ + toNodejsStream : function (updateCb) { + utils.checkSupport("nodestream"); + if (this._outputType !== "nodebuffer") { + // an object stream containing blob/arraybuffer/uint8array/string + // is strange and I don't know if it would be useful. + // I you find this comment and have a good usecase, please open a + // bug report ! + throw new Error(this._outputType + " is not supported by this method"); + } + + return new NodejsStreamOutputAdapter(this, { + objectMode : this._outputType !== "nodebuffer" + }, updateCb); + } +}; + + +module.exports = StreamHelper; + +},{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(require,module,exports){ +'use strict'; + +exports.base64 = true; +exports.array = true; +exports.string = true; +exports.arraybuffer = typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined"; +exports.nodebuffer = typeof Buffer !== "undefined"; +// contains true if JSZip can read/generate Uint8Array, false otherwise. +exports.uint8array = typeof Uint8Array !== "undefined"; + +if (typeof ArrayBuffer === "undefined") { + exports.blob = false; +} +else { + var buffer = new ArrayBuffer(0); + try { + exports.blob = new Blob([buffer], { + type: "application/zip" + }).size === 0; + } + catch (e) { + try { + var Builder = self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder; + var builder = new Builder(); + builder.append(buffer); + exports.blob = builder.getBlob('application/zip').size === 0; + } + catch (e) { + exports.blob = false; + } + } +} + +try { + exports.nodestream = !!require('readable-stream').Readable; +} catch(e) { + exports.nodestream = false; +} + +},{"readable-stream":16}],31:[function(require,module,exports){ +'use strict'; + +var utils = require('./utils'); +var support = require('./support'); +var nodejsUtils = require('./nodejsUtils'); +var GenericWorker = require('./stream/GenericWorker'); + +/** + * The following functions come from pako, from pako/lib/utils/strings + * released under the MIT license, see pako https://github.com/nodeca/pako/ + */ + +// Table with utf8 lengths (calculated by first byte of sequence) +// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS, +// because max possible codepoint is 0x10ffff +var _utf8len = new Array(256); +for (var i=0; i<256; i++) { + _utf8len[i] = (i >= 252 ? 6 : i >= 248 ? 5 : i >= 240 ? 4 : i >= 224 ? 3 : i >= 192 ? 2 : 1); +} +_utf8len[254]=_utf8len[254]=1; // Invalid sequence start + +// convert string to array (typed, when possible) +var string2buf = function (str) { + var buf, c, c2, m_pos, i, str_len = str.length, buf_len = 0; + + // count binary size + for (m_pos = 0; m_pos < str_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4; + } + + // allocate buffer + if (support.uint8array) { + buf = new Uint8Array(buf_len); + } else { + buf = new Array(buf_len); + } + + // convert + for (i=0, m_pos = 0; i < buf_len; m_pos++) { + c = str.charCodeAt(m_pos); + if ((c & 0xfc00) === 0xd800 && (m_pos+1 < str_len)) { + c2 = str.charCodeAt(m_pos+1); + if ((c2 & 0xfc00) === 0xdc00) { + c = 0x10000 + ((c - 0xd800) << 10) + (c2 - 0xdc00); + m_pos++; + } + } + if (c < 0x80) { + /* one byte */ + buf[i++] = c; + } else if (c < 0x800) { + /* two bytes */ + buf[i++] = 0xC0 | (c >>> 6); + buf[i++] = 0x80 | (c & 0x3f); + } else if (c < 0x10000) { + /* three bytes */ + buf[i++] = 0xE0 | (c >>> 12); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } else { + /* four bytes */ + buf[i++] = 0xf0 | (c >>> 18); + buf[i++] = 0x80 | (c >>> 12 & 0x3f); + buf[i++] = 0x80 | (c >>> 6 & 0x3f); + buf[i++] = 0x80 | (c & 0x3f); + } + } + + return buf; +}; + +// Calculate max possible position in utf8 buffer, +// that will not break sequence. If that's not possible +// - (very small limits) return max size as is. +// +// buf[] - utf8 bytes array +// max - length limit (mandatory); +var utf8border = function(buf, max) { + var pos; + + max = max || buf.length; + if (max > buf.length) { max = buf.length; } + + // go back from last position, until start of sequence found + pos = max-1; + while (pos >= 0 && (buf[pos] & 0xC0) === 0x80) { pos--; } + + // Fuckup - very small and broken sequence, + // return max, because we should return something anyway. + if (pos < 0) { return max; } + + // If we came to start of buffer - that means vuffer is too small, + // return max too. + if (pos === 0) { return max; } + + return (pos + _utf8len[buf[pos]] > max) ? pos : max; +}; + +// convert array to string +var buf2string = function (buf) { + var str, i, out, c, c_len; + var len = buf.length; + + // Reserve max possible length (2 words per char) + // NB: by unknown reasons, Array is significantly faster for + // String.fromCharCode.apply than Uint16Array. + var utf16buf = new Array(len*2); + + for (out=0, i=0; i 4) { utf16buf[out++] = 0xfffd; i += c_len-1; continue; } + + // apply mask on first byte + c &= c_len === 2 ? 0x1f : c_len === 3 ? 0x0f : 0x07; + // join the rest + while (c_len > 1 && i < len) { + c = (c << 6) | (buf[i++] & 0x3f); + c_len--; + } + + // terminated by end of string? + if (c_len > 1) { utf16buf[out++] = 0xfffd; continue; } + + if (c < 0x10000) { + utf16buf[out++] = c; + } else { + c -= 0x10000; + utf16buf[out++] = 0xd800 | ((c >> 10) & 0x3ff); + utf16buf[out++] = 0xdc00 | (c & 0x3ff); + } + } + + // shrinkBuf(utf16buf, out) + if (utf16buf.length !== out) { + if(utf16buf.subarray) { + utf16buf = utf16buf.subarray(0, out); + } else { + utf16buf.length = out; + } + } + + // return String.fromCharCode.apply(null, utf16buf); + return utils.applyFromCharCode(utf16buf); +}; + + +// That's all for the pako functions. + + +/** + * Transform a javascript string into an array (typed if possible) of bytes, + * UTF-8 encoded. + * @param {String} str the string to encode + * @return {Array|Uint8Array|Buffer} the UTF-8 encoded string. + */ +exports.utf8encode = function utf8encode(str) { + if (support.nodebuffer) { + return nodejsUtils.newBufferFrom(str, "utf-8"); + } + + return string2buf(str); +}; + + +/** + * Transform a bytes array (or a representation) representing an UTF-8 encoded + * string into a javascript string. + * @param {Array|Uint8Array|Buffer} buf the data de decode + * @return {String} the decoded string. + */ +exports.utf8decode = function utf8decode(buf) { + if (support.nodebuffer) { + return utils.transformTo("nodebuffer", buf).toString("utf-8"); + } + + buf = utils.transformTo(support.uint8array ? "uint8array" : "array", buf); + + return buf2string(buf); +}; + +/** + * A worker to decode utf8 encoded binary chunks into string chunks. + * @constructor + */ +function Utf8DecodeWorker() { + GenericWorker.call(this, "utf-8 decode"); + // the last bytes if a chunk didn't end with a complete codepoint. + this.leftOver = null; +} +utils.inherits(Utf8DecodeWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +Utf8DecodeWorker.prototype.processChunk = function (chunk) { + + var data = utils.transformTo(support.uint8array ? "uint8array" : "array", chunk.data); + + // 1st step, re-use what's left of the previous chunk + if (this.leftOver && this.leftOver.length) { + if(support.uint8array) { + var previousData = data; + data = new Uint8Array(previousData.length + this.leftOver.length); + data.set(this.leftOver, 0); + data.set(previousData, this.leftOver.length); + } else { + data = this.leftOver.concat(data); + } + this.leftOver = null; + } + + var nextBoundary = utf8border(data); + var usableData = data; + if (nextBoundary !== data.length) { + if (support.uint8array) { + usableData = data.subarray(0, nextBoundary); + this.leftOver = data.subarray(nextBoundary, data.length); + } else { + usableData = data.slice(0, nextBoundary); + this.leftOver = data.slice(nextBoundary, data.length); + } + } + + this.push({ + data : exports.utf8decode(usableData), + meta : chunk.meta + }); +}; + +/** + * @see GenericWorker.flush + */ +Utf8DecodeWorker.prototype.flush = function () { + if(this.leftOver && this.leftOver.length) { + this.push({ + data : exports.utf8decode(this.leftOver), + meta : {} + }); + this.leftOver = null; + } +}; +exports.Utf8DecodeWorker = Utf8DecodeWorker; + +/** + * A worker to endcode string chunks into utf8 encoded binary chunks. + * @constructor + */ +function Utf8EncodeWorker() { + GenericWorker.call(this, "utf-8 encode"); +} +utils.inherits(Utf8EncodeWorker, GenericWorker); + +/** + * @see GenericWorker.processChunk + */ +Utf8EncodeWorker.prototype.processChunk = function (chunk) { + this.push({ + data : exports.utf8encode(chunk.data), + meta : chunk.meta + }); +}; +exports.Utf8EncodeWorker = Utf8EncodeWorker; + +},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(require,module,exports){ +'use strict'; + +var support = require('./support'); +var base64 = require('./base64'); +var nodejsUtils = require('./nodejsUtils'); +var setImmediate = require('set-immediate-shim'); +var external = require("./external"); + + +/** + * Convert a string that pass as a "binary string": it should represent a byte + * array but may have > 255 char codes. Be sure to take only the first byte + * and returns the byte array. + * @param {String} str the string to transform. + * @return {Array|Uint8Array} the string in a binary format. + */ +function string2binary(str) { + var result = null; + if (support.uint8array) { + result = new Uint8Array(str.length); + } else { + result = new Array(str.length); + } + return stringToArrayLike(str, result); +} + +/** + * Create a new blob with the given content and the given type. + * @param {String|ArrayBuffer} part the content to put in the blob. DO NOT use + * an Uint8Array because the stock browser of android 4 won't accept it (it + * will be silently converted to a string, "[object Uint8Array]"). + * + * Use only ONE part to build the blob to avoid a memory leak in IE11 / Edge: + * when a large amount of Array is used to create the Blob, the amount of + * memory consumed is nearly 100 times the original data amount. + * + * @param {String} type the mime type of the blob. + * @return {Blob} the created blob. + */ +exports.newBlob = function(part, type) { + exports.checkSupport("blob"); + + try { + // Blob constructor + return new Blob([part], { + type: type + }); + } + catch (e) { + + try { + // deprecated, browser only, old way + var Builder = self.BlobBuilder || self.WebKitBlobBuilder || self.MozBlobBuilder || self.MSBlobBuilder; + var builder = new Builder(); + builder.append(part); + return builder.getBlob(type); + } + catch (e) { + + // well, fuck ?! + throw new Error("Bug : can't construct the Blob."); + } + } + + +}; +/** + * The identity function. + * @param {Object} input the input. + * @return {Object} the same input. + */ +function identity(input) { + return input; +} + +/** + * Fill in an array with a string. + * @param {String} str the string to use. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to fill in (will be mutated). + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated array. + */ +function stringToArrayLike(str, array) { + for (var i = 0; i < str.length; ++i) { + array[i] = str.charCodeAt(i) & 0xFF; + } + return array; +} + +/** + * An helper for the function arrayLikeToString. + * This contains static information and functions that + * can be optimized by the browser JIT compiler. + */ +var arrayToStringHelper = { + /** + * Transform an array of int into a string, chunk by chunk. + * See the performances notes on arrayLikeToString. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @param {String} type the type of the array. + * @param {Integer} chunk the chunk size. + * @return {String} the resulting string. + * @throws Error if the chunk is too big for the stack. + */ + stringifyByChunk: function(array, type, chunk) { + var result = [], k = 0, len = array.length; + // shortcut + if (len <= chunk) { + return String.fromCharCode.apply(null, array); + } + while (k < len) { + if (type === "array" || type === "nodebuffer") { + result.push(String.fromCharCode.apply(null, array.slice(k, Math.min(k + chunk, len)))); + } + else { + result.push(String.fromCharCode.apply(null, array.subarray(k, Math.min(k + chunk, len)))); + } + k += chunk; + } + return result.join(""); + }, + /** + * Call String.fromCharCode on every item in the array. + * This is the naive implementation, which generate A LOT of intermediate string. + * This should be used when everything else fail. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @return {String} the result. + */ + stringifyByChar: function(array){ + var resultStr = ""; + for(var i = 0; i < array.length; i++) { + resultStr += String.fromCharCode(array[i]); + } + return resultStr; + }, + applyCanBeUsed : { + /** + * true if the browser accepts to use String.fromCharCode on Uint8Array + */ + uint8array : (function () { + try { + return support.uint8array && String.fromCharCode.apply(null, new Uint8Array(1)).length === 1; + } catch (e) { + return false; + } + })(), + /** + * true if the browser accepts to use String.fromCharCode on nodejs Buffer. + */ + nodebuffer : (function () { + try { + return support.nodebuffer && String.fromCharCode.apply(null, nodejsUtils.allocBuffer(1)).length === 1; + } catch (e) { + return false; + } + })() + } +}; + +/** + * Transform an array-like object to a string. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} array the array to transform. + * @return {String} the result. + */ +function arrayLikeToString(array) { + // Performances notes : + // -------------------- + // String.fromCharCode.apply(null, array) is the fastest, see + // see http://jsperf.com/converting-a-uint8array-to-a-string/2 + // but the stack is limited (and we can get huge arrays !). + // + // result += String.fromCharCode(array[i]); generate too many strings ! + // + // This code is inspired by http://jsperf.com/arraybuffer-to-string-apply-performance/2 + // TODO : we now have workers that split the work. Do we still need that ? + var chunk = 65536, + type = exports.getTypeOf(array), + canUseApply = true; + if (type === "uint8array") { + canUseApply = arrayToStringHelper.applyCanBeUsed.uint8array; + } else if (type === "nodebuffer") { + canUseApply = arrayToStringHelper.applyCanBeUsed.nodebuffer; + } + + if (canUseApply) { + while (chunk > 1) { + try { + return arrayToStringHelper.stringifyByChunk(array, type, chunk); + } catch (e) { + chunk = Math.floor(chunk / 2); + } + } + } + + // no apply or chunk error : slow and painful algorithm + // default browser on android 4.* + return arrayToStringHelper.stringifyByChar(array); +} + +exports.applyFromCharCode = arrayLikeToString; + + +/** + * Copy the data from an array-like to an other array-like. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayFrom the origin array. + * @param {Array|ArrayBuffer|Uint8Array|Buffer} arrayTo the destination array which will be mutated. + * @return {Array|ArrayBuffer|Uint8Array|Buffer} the updated destination array. + */ +function arrayLikeToArrayLike(arrayFrom, arrayTo) { + for (var i = 0; i < arrayFrom.length; i++) { + arrayTo[i] = arrayFrom[i]; + } + return arrayTo; +} + +// a matrix containing functions to transform everything into everything. +var transform = {}; + +// string to ? +transform["string"] = { + "string": identity, + "array": function(input) { + return stringToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return transform["string"]["uint8array"](input).buffer; + }, + "uint8array": function(input) { + return stringToArrayLike(input, new Uint8Array(input.length)); + }, + "nodebuffer": function(input) { + return stringToArrayLike(input, nodejsUtils.allocBuffer(input.length)); + } +}; + +// array to ? +transform["array"] = { + "string": arrayLikeToString, + "array": identity, + "arraybuffer": function(input) { + return (new Uint8Array(input)).buffer; + }, + "uint8array": function(input) { + return new Uint8Array(input); + }, + "nodebuffer": function(input) { + return nodejsUtils.newBufferFrom(input); + } +}; + +// arraybuffer to ? +transform["arraybuffer"] = { + "string": function(input) { + return arrayLikeToString(new Uint8Array(input)); + }, + "array": function(input) { + return arrayLikeToArrayLike(new Uint8Array(input), new Array(input.byteLength)); + }, + "arraybuffer": identity, + "uint8array": function(input) { + return new Uint8Array(input); + }, + "nodebuffer": function(input) { + return nodejsUtils.newBufferFrom(new Uint8Array(input)); + } +}; + +// uint8array to ? +transform["uint8array"] = { + "string": arrayLikeToString, + "array": function(input) { + return arrayLikeToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return input.buffer; + }, + "uint8array": identity, + "nodebuffer": function(input) { + return nodejsUtils.newBufferFrom(input); + } +}; + +// nodebuffer to ? +transform["nodebuffer"] = { + "string": arrayLikeToString, + "array": function(input) { + return arrayLikeToArrayLike(input, new Array(input.length)); + }, + "arraybuffer": function(input) { + return transform["nodebuffer"]["uint8array"](input).buffer; + }, + "uint8array": function(input) { + return arrayLikeToArrayLike(input, new Uint8Array(input.length)); + }, + "nodebuffer": identity +}; + +/** + * Transform an input into any type. + * The supported output type are : string, array, uint8array, arraybuffer, nodebuffer. + * If no output type is specified, the unmodified input will be returned. + * @param {String} outputType the output type. + * @param {String|Array|ArrayBuffer|Uint8Array|Buffer} input the input to convert. + * @throws {Error} an Error if the browser doesn't support the requested output type. + */ +exports.transformTo = function(outputType, input) { + if (!input) { + // undefined, null, etc + // an empty string won't harm. + input = ""; + } + if (!outputType) { + return input; + } + exports.checkSupport(outputType); + var inputType = exports.getTypeOf(input); + var result = transform[inputType][outputType](input); + return result; +}; + +/** + * Return the type of the input. + * The type will be in a format valid for JSZip.utils.transformTo : string, array, uint8array, arraybuffer. + * @param {Object} input the input to identify. + * @return {String} the (lowercase) type of the input. + */ +exports.getTypeOf = function(input) { + if (typeof input === "string") { + return "string"; + } + if (Object.prototype.toString.call(input) === "[object Array]") { + return "array"; + } + if (support.nodebuffer && nodejsUtils.isBuffer(input)) { + return "nodebuffer"; + } + if (support.uint8array && input instanceof Uint8Array) { + return "uint8array"; + } + if (support.arraybuffer && input instanceof ArrayBuffer) { + return "arraybuffer"; + } +}; + +/** + * Throw an exception if the type is not supported. + * @param {String} type the type to check. + * @throws {Error} an Error if the browser doesn't support the requested type. + */ +exports.checkSupport = function(type) { + var supported = support[type.toLowerCase()]; + if (!supported) { + throw new Error(type + " is not supported by this platform"); + } +}; + +exports.MAX_VALUE_16BITS = 65535; +exports.MAX_VALUE_32BITS = -1; // well, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" is parsed as -1 + +/** + * Prettify a string read as binary. + * @param {string} str the string to prettify. + * @return {string} a pretty string. + */ +exports.pretty = function(str) { + var res = '', + code, i; + for (i = 0; i < (str || "").length; i++) { + code = str.charCodeAt(i); + res += '\\x' + (code < 16 ? "0" : "") + code.toString(16).toUpperCase(); + } + return res; +}; + +/** + * Defer the call of a function. + * @param {Function} callback the function to call asynchronously. + * @param {Array} args the arguments to give to the callback. + */ +exports.delay = function(callback, args, self) { + setImmediate(function () { + callback.apply(self || null, args || []); + }); +}; + +/** + * Extends a prototype with an other, without calling a constructor with + * side effects. Inspired by nodejs' `utils.inherits` + * @param {Function} ctor the constructor to augment + * @param {Function} superCtor the parent constructor to use + */ +exports.inherits = function (ctor, superCtor) { + var Obj = function() {}; + Obj.prototype = superCtor.prototype; + ctor.prototype = new Obj(); +}; + +/** + * Merge the objects passed as parameters into a new one. + * @private + * @param {...Object} var_args All objects to merge. + * @return {Object} a new object with the data of the others. + */ +exports.extend = function() { + var result = {}, i, attr; + for (i = 0; i < arguments.length; i++) { // arguments is not enumerable in some browsers + for (attr in arguments[i]) { + if (arguments[i].hasOwnProperty(attr) && typeof result[attr] === "undefined") { + result[attr] = arguments[i][attr]; + } + } + } + return result; +}; + +/** + * Transform arbitrary content into a Promise. + * @param {String} name a name for the content being processed. + * @param {Object} inputData the content to process. + * @param {Boolean} isBinary true if the content is not an unicode string + * @param {Boolean} isOptimizedBinaryString true if the string content only has one byte per character. + * @param {Boolean} isBase64 true if the string content is encoded with base64. + * @return {Promise} a promise in a format usable by JSZip. + */ +exports.prepareContent = function(name, inputData, isBinary, isOptimizedBinaryString, isBase64) { + + // if inputData is already a promise, this flatten it. + var promise = external.Promise.resolve(inputData).then(function(data) { + + + var isBlob = support.blob && (data instanceof Blob || ['[object File]', '[object Blob]'].indexOf(Object.prototype.toString.call(data)) !== -1); + + if (isBlob && typeof FileReader !== "undefined") { + return new external.Promise(function (resolve, reject) { + var reader = new FileReader(); + + reader.onload = function(e) { + resolve(e.target.result); + }; + reader.onerror = function(e) { + reject(e.target.error); + }; + reader.readAsArrayBuffer(data); + }); + } else { + return data; + } + }); + + return promise.then(function(data) { + var dataType = exports.getTypeOf(data); + + if (!dataType) { + return external.Promise.reject( + new Error("Can't read the data of '" + name + "'. Is it " + + "in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?") + ); + } + // special case : it's way easier to work with Uint8Array than with ArrayBuffer + if (dataType === "arraybuffer") { + data = exports.transformTo("uint8array", data); + } else if (dataType === "string") { + if (isBase64) { + data = base64.decode(data); + } + else if (isBinary) { + // optimizedBinaryString === true means that the file has already been filtered with a 0xFF mask + if (isOptimizedBinaryString !== true) { + // this is a string, not in a base64 format. + // Be sure that this is a correct "binary string" + data = string2binary(data); + } + } + } + return data; + }); +}; + +},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,"set-immediate-shim":54}],33:[function(require,module,exports){ +'use strict'; +var readerFor = require('./reader/readerFor'); +var utils = require('./utils'); +var sig = require('./signature'); +var ZipEntry = require('./zipEntry'); +var utf8 = require('./utf8'); +var support = require('./support'); +// class ZipEntries {{{ +/** + * All the entries in the zip file. + * @constructor + * @param {Object} loadOptions Options for loading the stream. + */ +function ZipEntries(loadOptions) { + this.files = []; + this.loadOptions = loadOptions; +} +ZipEntries.prototype = { + /** + * Check that the reader is on the specified signature. + * @param {string} expectedSignature the expected signature. + * @throws {Error} if it is an other signature. + */ + checkSignature: function(expectedSignature) { + if (!this.reader.readAndCheckSignature(expectedSignature)) { + this.reader.index -= 4; + var signature = this.reader.readString(4); + throw new Error("Corrupted zip or bug: unexpected signature " + "(" + utils.pretty(signature) + ", expected " + utils.pretty(expectedSignature) + ")"); + } + }, + /** + * Check if the given signature is at the given index. + * @param {number} askedIndex the index to check. + * @param {string} expectedSignature the signature to expect. + * @return {boolean} true if the signature is here, false otherwise. + */ + isSignature: function(askedIndex, expectedSignature) { + var currentIndex = this.reader.index; + this.reader.setIndex(askedIndex); + var signature = this.reader.readString(4); + var result = signature === expectedSignature; + this.reader.setIndex(currentIndex); + return result; + }, + /** + * Read the end of the central directory. + */ + readBlockEndOfCentral: function() { + this.diskNumber = this.reader.readInt(2); + this.diskWithCentralDirStart = this.reader.readInt(2); + this.centralDirRecordsOnThisDisk = this.reader.readInt(2); + this.centralDirRecords = this.reader.readInt(2); + this.centralDirSize = this.reader.readInt(4); + this.centralDirOffset = this.reader.readInt(4); + + this.zipCommentLength = this.reader.readInt(2); + // warning : the encoding depends of the system locale + // On a linux machine with LANG=en_US.utf8, this field is utf8 encoded. + // On a windows machine, this field is encoded with the localized windows code page. + var zipComment = this.reader.readData(this.zipCommentLength); + var decodeParamType = support.uint8array ? "uint8array" : "array"; + // To get consistent behavior with the generation part, we will assume that + // this is utf8 encoded unless specified otherwise. + var decodeContent = utils.transformTo(decodeParamType, zipComment); + this.zipComment = this.loadOptions.decodeFileName(decodeContent); + }, + /** + * Read the end of the Zip 64 central directory. + * Not merged with the method readEndOfCentral : + * The end of central can coexist with its Zip64 brother, + * I don't want to read the wrong number of bytes ! + */ + readBlockZip64EndOfCentral: function() { + this.zip64EndOfCentralSize = this.reader.readInt(8); + this.reader.skip(4); + // this.versionMadeBy = this.reader.readString(2); + // this.versionNeeded = this.reader.readInt(2); + this.diskNumber = this.reader.readInt(4); + this.diskWithCentralDirStart = this.reader.readInt(4); + this.centralDirRecordsOnThisDisk = this.reader.readInt(8); + this.centralDirRecords = this.reader.readInt(8); + this.centralDirSize = this.reader.readInt(8); + this.centralDirOffset = this.reader.readInt(8); + + this.zip64ExtensibleData = {}; + var extraDataSize = this.zip64EndOfCentralSize - 44, + index = 0, + extraFieldId, + extraFieldLength, + extraFieldValue; + while (index < extraDataSize) { + extraFieldId = this.reader.readInt(2); + extraFieldLength = this.reader.readInt(4); + extraFieldValue = this.reader.readData(extraFieldLength); + this.zip64ExtensibleData[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue + }; + } + }, + /** + * Read the end of the Zip 64 central directory locator. + */ + readBlockZip64EndOfCentralLocator: function() { + this.diskWithZip64CentralDirStart = this.reader.readInt(4); + this.relativeOffsetEndOfZip64CentralDir = this.reader.readInt(8); + this.disksCount = this.reader.readInt(4); + if (this.disksCount > 1) { + throw new Error("Multi-volumes zip are not supported"); + } + }, + /** + * Read the local files, based on the offset read in the central part. + */ + readLocalFiles: function() { + var i, file; + for (i = 0; i < this.files.length; i++) { + file = this.files[i]; + this.reader.setIndex(file.localHeaderOffset); + this.checkSignature(sig.LOCAL_FILE_HEADER); + file.readLocalPart(this.reader); + file.handleUTF8(); + file.processAttributes(); + } + }, + /** + * Read the central directory. + */ + readCentralDir: function() { + var file; + + this.reader.setIndex(this.centralDirOffset); + while (this.reader.readAndCheckSignature(sig.CENTRAL_FILE_HEADER)) { + file = new ZipEntry({ + zip64: this.zip64 + }, this.loadOptions); + file.readCentralPart(this.reader); + this.files.push(file); + } + + if (this.centralDirRecords !== this.files.length) { + if (this.centralDirRecords !== 0 && this.files.length === 0) { + // We expected some records but couldn't find ANY. + // This is really suspicious, as if something went wrong. + throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length); + } else { + // We found some records but not all. + // Something is wrong but we got something for the user: no error here. + // console.warn("expected", this.centralDirRecords, "records in central dir, got", this.files.length); + } + } + }, + /** + * Read the end of central directory. + */ + readEndOfCentral: function() { + var offset = this.reader.lastIndexOfSignature(sig.CENTRAL_DIRECTORY_END); + if (offset < 0) { + // Check if the content is a truncated zip or complete garbage. + // A "LOCAL_FILE_HEADER" is not required at the beginning (auto + // extractible zip for example) but it can give a good hint. + // If an ajax request was used without responseType, we will also + // get unreadable data. + var isGarbage = !this.isSignature(0, sig.LOCAL_FILE_HEADER); + + if (isGarbage) { + throw new Error("Can't find end of central directory : is this a zip file ? " + + "If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html"); + } else { + throw new Error("Corrupted zip: can't find end of central directory"); + } + + } + this.reader.setIndex(offset); + var endOfCentralDirOffset = offset; + this.checkSignature(sig.CENTRAL_DIRECTORY_END); + this.readBlockEndOfCentral(); + + + /* extract from the zip spec : + 4) If one of the fields in the end of central directory + record is too small to hold required data, the field + should be set to -1 (0xFFFF or 0xFFFFFFFF) and the + ZIP64 format record should be created. + 5) The end of central directory record and the + Zip64 end of central directory locator record must + reside on the same disk when splitting or spanning + an archive. + */ + if (this.diskNumber === utils.MAX_VALUE_16BITS || this.diskWithCentralDirStart === utils.MAX_VALUE_16BITS || this.centralDirRecordsOnThisDisk === utils.MAX_VALUE_16BITS || this.centralDirRecords === utils.MAX_VALUE_16BITS || this.centralDirSize === utils.MAX_VALUE_32BITS || this.centralDirOffset === utils.MAX_VALUE_32BITS) { + this.zip64 = true; + + /* + Warning : the zip64 extension is supported, but ONLY if the 64bits integer read from + the zip file can fit into a 32bits integer. This cannot be solved : JavaScript represents + all numbers as 64-bit double precision IEEE 754 floating point numbers. + So, we have 53bits for integers and bitwise operations treat everything as 32bits. + see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Bitwise_Operators + and http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf section 8.5 + */ + + // should look for a zip64 EOCD locator + offset = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); + if (offset < 0) { + throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator"); + } + this.reader.setIndex(offset); + this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_LOCATOR); + this.readBlockZip64EndOfCentralLocator(); + + // now the zip64 EOCD record + if (!this.isSignature(this.relativeOffsetEndOfZip64CentralDir, sig.ZIP64_CENTRAL_DIRECTORY_END)) { + // console.warn("ZIP64 end of central directory not where expected."); + this.relativeOffsetEndOfZip64CentralDir = this.reader.lastIndexOfSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); + if (this.relativeOffsetEndOfZip64CentralDir < 0) { + throw new Error("Corrupted zip: can't find the ZIP64 end of central directory"); + } + } + this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir); + this.checkSignature(sig.ZIP64_CENTRAL_DIRECTORY_END); + this.readBlockZip64EndOfCentral(); + } + + var expectedEndOfCentralDirOffset = this.centralDirOffset + this.centralDirSize; + if (this.zip64) { + expectedEndOfCentralDirOffset += 20; // end of central dir 64 locator + expectedEndOfCentralDirOffset += 12 /* should not include the leading 12 bytes */ + this.zip64EndOfCentralSize; + } + + var extraBytes = endOfCentralDirOffset - expectedEndOfCentralDirOffset; + + if (extraBytes > 0) { + // console.warn(extraBytes, "extra bytes at beginning or within zipfile"); + if (this.isSignature(endOfCentralDirOffset, sig.CENTRAL_FILE_HEADER)) { + // The offsets seem wrong, but we have something at the specified offset. + // So… we keep it. + } else { + // the offset is wrong, update the "zero" of the reader + // this happens if data has been prepended (crx files for example) + this.reader.zero = extraBytes; + } + } else if (extraBytes < 0) { + throw new Error("Corrupted zip: missing " + Math.abs(extraBytes) + " bytes."); + } + }, + prepareReader: function(data) { + this.reader = readerFor(data); + }, + /** + * Read a zip file and create ZipEntries. + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the binary string representing a zip file. + */ + load: function(data) { + this.prepareReader(data); + this.readEndOfCentral(); + this.readCentralDir(); + this.readLocalFiles(); + } +}; +// }}} end of ZipEntries +module.exports = ZipEntries; + +},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utf8":31,"./utils":32,"./zipEntry":34}],34:[function(require,module,exports){ +'use strict'; +var readerFor = require('./reader/readerFor'); +var utils = require('./utils'); +var CompressedObject = require('./compressedObject'); +var crc32fn = require('./crc32'); +var utf8 = require('./utf8'); +var compressions = require('./compressions'); +var support = require('./support'); + +var MADE_BY_DOS = 0x00; +var MADE_BY_UNIX = 0x03; + +/** + * Find a compression registered in JSZip. + * @param {string} compressionMethod the method magic to find. + * @return {Object|null} the JSZip compression object, null if none found. + */ +var findCompression = function(compressionMethod) { + for (var method in compressions) { + if (!compressions.hasOwnProperty(method)) { + continue; + } + if (compressions[method].magic === compressionMethod) { + return compressions[method]; + } + } + return null; +}; + +// class ZipEntry {{{ +/** + * An entry in the zip file. + * @constructor + * @param {Object} options Options of the current file. + * @param {Object} loadOptions Options for loading the stream. + */ +function ZipEntry(options, loadOptions) { + this.options = options; + this.loadOptions = loadOptions; +} +ZipEntry.prototype = { + /** + * say if the file is encrypted. + * @return {boolean} true if the file is encrypted, false otherwise. + */ + isEncrypted: function() { + // bit 1 is set + return (this.bitFlag & 0x0001) === 0x0001; + }, + /** + * say if the file has utf-8 filename/comment. + * @return {boolean} true if the filename/comment is in utf-8, false otherwise. + */ + useUTF8: function() { + // bit 11 is set + return (this.bitFlag & 0x0800) === 0x0800; + }, + /** + * Read the local part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readLocalPart: function(reader) { + var compression, localExtraFieldsLength; + + // we already know everything from the central dir ! + // If the central dir data are false, we are doomed. + // On the bright side, the local part is scary : zip64, data descriptors, both, etc. + // The less data we get here, the more reliable this should be. + // Let's skip the whole header and dash to the data ! + reader.skip(22); + // in some zip created on windows, the filename stored in the central dir contains \ instead of /. + // Strangely, the filename here is OK. + // I would love to treat these zip files as corrupted (see http://www.info-zip.org/FAQ.html#backslashes + // or APPNOTE#4.4.17.1, "All slashes MUST be forward slashes '/'") but there are a lot of bad zip generators... + // Search "unzip mismatching "local" filename continuing with "central" filename version" on + // the internet. + // + // I think I see the logic here : the central directory is used to display + // content and the local directory is used to extract the files. Mixing / and \ + // may be used to display \ to windows users and use / when extracting the files. + // Unfortunately, this lead also to some issues : http://seclists.org/fulldisclosure/2009/Sep/394 + this.fileNameLength = reader.readInt(2); + localExtraFieldsLength = reader.readInt(2); // can't be sure this will be the same as the central dir + // the fileName is stored as binary data, the handleUTF8 method will take care of the encoding. + this.fileName = reader.readData(this.fileNameLength); + reader.skip(localExtraFieldsLength); + + if (this.compressedSize === -1 || this.uncompressedSize === -1) { + throw new Error("Bug or corrupted zip : didn't get enough information from the central directory " + "(compressedSize === -1 || uncompressedSize === -1)"); + } + + compression = findCompression(this.compressionMethod); + if (compression === null) { // no compression found + throw new Error("Corrupted zip : compression " + utils.pretty(this.compressionMethod) + " unknown (inner file : " + utils.transformTo("string", this.fileName) + ")"); + } + this.decompressed = new CompressedObject(this.compressedSize, this.uncompressedSize, this.crc32, compression, reader.readData(this.compressedSize)); + }, + + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readCentralPart: function(reader) { + this.versionMadeBy = reader.readInt(2); + reader.skip(2); + // this.versionNeeded = reader.readInt(2); + this.bitFlag = reader.readInt(2); + this.compressionMethod = reader.readString(2); + this.date = reader.readDate(); + this.crc32 = reader.readInt(4); + this.compressedSize = reader.readInt(4); + this.uncompressedSize = reader.readInt(4); + var fileNameLength = reader.readInt(2); + this.extraFieldsLength = reader.readInt(2); + this.fileCommentLength = reader.readInt(2); + this.diskNumberStart = reader.readInt(2); + this.internalFileAttributes = reader.readInt(2); + this.externalFileAttributes = reader.readInt(4); + this.localHeaderOffset = reader.readInt(4); + + if (this.isEncrypted()) { + throw new Error("Encrypted zip are not supported"); + } + + // will be read in the local part, see the comments there + reader.skip(fileNameLength); + this.readExtraFields(reader); + this.parseZIP64ExtraField(reader); + this.fileComment = reader.readData(this.fileCommentLength); + }, + + /** + * Parse the external file attributes and get the unix/dos permissions. + */ + processAttributes: function () { + this.unixPermissions = null; + this.dosPermissions = null; + var madeBy = this.versionMadeBy >> 8; + + // Check if we have the DOS directory flag set. + // We look for it in the DOS and UNIX permissions + // but some unknown platform could set it as a compatibility flag. + this.dir = this.externalFileAttributes & 0x0010 ? true : false; + + if(madeBy === MADE_BY_DOS) { + // first 6 bits (0 to 5) + this.dosPermissions = this.externalFileAttributes & 0x3F; + } + + if(madeBy === MADE_BY_UNIX) { + this.unixPermissions = (this.externalFileAttributes >> 16) & 0xFFFF; + // the octal permissions are in (this.unixPermissions & 0x01FF).toString(8); + } + + // fail safe : if the name ends with a / it probably means a folder + if (!this.dir && this.fileNameStr.slice(-1) === '/') { + this.dir = true; + } + }, + + /** + * Parse the ZIP64 extra field and merge the info in the current ZipEntry. + * @param {DataReader} reader the reader to use. + */ + parseZIP64ExtraField: function(reader) { + + if (!this.extraFields[0x0001]) { + return; + } + + // should be something, preparing the extra reader + var extraReader = readerFor(this.extraFields[0x0001].value); + + // I really hope that these 64bits integer can fit in 32 bits integer, because js + // won't let us have more. + if (this.uncompressedSize === utils.MAX_VALUE_32BITS) { + this.uncompressedSize = extraReader.readInt(8); + } + if (this.compressedSize === utils.MAX_VALUE_32BITS) { + this.compressedSize = extraReader.readInt(8); + } + if (this.localHeaderOffset === utils.MAX_VALUE_32BITS) { + this.localHeaderOffset = extraReader.readInt(8); + } + if (this.diskNumberStart === utils.MAX_VALUE_32BITS) { + this.diskNumberStart = extraReader.readInt(4); + } + }, + /** + * Read the central part of a zip file and add the info in this object. + * @param {DataReader} reader the reader to use. + */ + readExtraFields: function(reader) { + var end = reader.index + this.extraFieldsLength, + extraFieldId, + extraFieldLength, + extraFieldValue; + + if (!this.extraFields) { + this.extraFields = {}; + } + + while (reader.index + 4 < end) { + extraFieldId = reader.readInt(2); + extraFieldLength = reader.readInt(2); + extraFieldValue = reader.readData(extraFieldLength); + + this.extraFields[extraFieldId] = { + id: extraFieldId, + length: extraFieldLength, + value: extraFieldValue + }; + } + + reader.setIndex(end); + }, + /** + * Apply an UTF8 transformation if needed. + */ + handleUTF8: function() { + var decodeParamType = support.uint8array ? "uint8array" : "array"; + if (this.useUTF8()) { + this.fileNameStr = utf8.utf8decode(this.fileName); + this.fileCommentStr = utf8.utf8decode(this.fileComment); + } else { + var upath = this.findExtraFieldUnicodePath(); + if (upath !== null) { + this.fileNameStr = upath; + } else { + // ASCII text or unsupported code page + var fileNameByteArray = utils.transformTo(decodeParamType, this.fileName); + this.fileNameStr = this.loadOptions.decodeFileName(fileNameByteArray); + } + + var ucomment = this.findExtraFieldUnicodeComment(); + if (ucomment !== null) { + this.fileCommentStr = ucomment; + } else { + // ASCII text or unsupported code page + var commentByteArray = utils.transformTo(decodeParamType, this.fileComment); + this.fileCommentStr = this.loadOptions.decodeFileName(commentByteArray); + } + } + }, + + /** + * Find the unicode path declared in the extra field, if any. + * @return {String} the unicode path, null otherwise. + */ + findExtraFieldUnicodePath: function() { + var upathField = this.extraFields[0x7075]; + if (upathField) { + var extraReader = readerFor(upathField.value); + + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } + + // the crc of the filename changed, this field is out of date. + if (crc32fn(this.fileName) !== extraReader.readInt(4)) { + return null; + } + + return utf8.utf8decode(extraReader.readData(upathField.length - 5)); + } + return null; + }, + + /** + * Find the unicode comment declared in the extra field, if any. + * @return {String} the unicode comment, null otherwise. + */ + findExtraFieldUnicodeComment: function() { + var ucommentField = this.extraFields[0x6375]; + if (ucommentField) { + var extraReader = readerFor(ucommentField.value); + + // wrong version + if (extraReader.readInt(1) !== 1) { + return null; + } + + // the crc of the comment changed, this field is out of date. + if (crc32fn(this.fileComment) !== extraReader.readInt(4)) { + return null; + } + + return utf8.utf8decode(extraReader.readData(ucommentField.length - 5)); + } + return null; + } +}; +module.exports = ZipEntry; + +},{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(require,module,exports){ +'use strict'; + +var StreamHelper = require('./stream/StreamHelper'); +var DataWorker = require('./stream/DataWorker'); +var utf8 = require('./utf8'); +var CompressedObject = require('./compressedObject'); +var GenericWorker = require('./stream/GenericWorker'); + +/** + * A simple object representing a file in the zip file. + * @constructor + * @param {string} name the name of the file + * @param {String|ArrayBuffer|Uint8Array|Buffer} data the data + * @param {Object} options the options of the file + */ +var ZipObject = function(name, data, options) { + this.name = name; + this.dir = options.dir; + this.date = options.date; + this.comment = options.comment; + this.unixPermissions = options.unixPermissions; + this.dosPermissions = options.dosPermissions; + + this._data = data; + this._dataBinary = options.binary; + // keep only the compression + this.options = { + compression : options.compression, + compressionOptions : options.compressionOptions + }; +}; + +ZipObject.prototype = { + /** + * Create an internal stream for the content of this object. + * @param {String} type the type of each chunk. + * @return StreamHelper the stream. + */ + internalStream: function (type) { + var result = null, outputType = "string"; + try { + if (!type) { + throw new Error("No output type specified."); + } + outputType = type.toLowerCase(); + var askUnicodeString = outputType === "string" || outputType === "text"; + if (outputType === "binarystring" || outputType === "text") { + outputType = "string"; + } + result = this._decompressWorker(); + + var isUnicodeString = !this._dataBinary; + + if (isUnicodeString && !askUnicodeString) { + result = result.pipe(new utf8.Utf8EncodeWorker()); + } + if (!isUnicodeString && askUnicodeString) { + result = result.pipe(new utf8.Utf8DecodeWorker()); + } + } catch (e) { + result = new GenericWorker("error"); + result.error(e); + } + + return new StreamHelper(result, outputType, ""); + }, + + /** + * Prepare the content in the asked type. + * @param {String} type the type of the result. + * @param {Function} onUpdate a function to call on each internal update. + * @return Promise the promise of the result. + */ + async: function (type, onUpdate) { + return this.internalStream(type).accumulate(onUpdate); + }, + + /** + * Prepare the content as a nodejs stream. + * @param {String} type the type of each chunk. + * @param {Function} onUpdate a function to call on each internal update. + * @return Stream the stream. + */ + nodeStream: function (type, onUpdate) { + return this.internalStream(type || "nodebuffer").toNodejsStream(onUpdate); + }, + + /** + * Return a worker for the compressed content. + * @private + * @param {Object} compression the compression object to use. + * @param {Object} compressionOptions the options to use when compressing. + * @return Worker the worker. + */ + _compressWorker: function (compression, compressionOptions) { + if ( + this._data instanceof CompressedObject && + this._data.compression.magic === compression.magic + ) { + return this._data.getCompressedWorker(); + } else { + var result = this._decompressWorker(); + if(!this._dataBinary) { + result = result.pipe(new utf8.Utf8EncodeWorker()); + } + return CompressedObject.createWorkerFrom(result, compression, compressionOptions); + } + }, + /** + * Return a worker for the decompressed content. + * @private + * @return Worker the worker. + */ + _decompressWorker : function () { + if (this._data instanceof CompressedObject) { + return this._data.getContentWorker(); + } else if (this._data instanceof GenericWorker) { + return this._data; + } else { + return new DataWorker(this._data); + } + } +}; + +var removedMethods = ["asText", "asBinary", "asNodeBuffer", "asUint8Array", "asArrayBuffer"]; +var removedFn = function () { + throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide."); +}; + +for(var i = 0; i < removedMethods.length; i++) { + ZipObject.prototype[removedMethods[i]] = removedFn; +} +module.exports = ZipObject; + +},{"./compressedObject":2,"./stream/DataWorker":27,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31}],36:[function(require,module,exports){ +(function (global){ +'use strict'; +var Mutation = global.MutationObserver || global.WebKitMutationObserver; + +var scheduleDrain; + +{ + if (Mutation) { + var called = 0; + var observer = new Mutation(nextTick); + var element = global.document.createTextNode(''); + observer.observe(element, { + characterData: true + }); + scheduleDrain = function () { + element.data = (called = ++called % 2); + }; + } else if (!global.setImmediate && typeof global.MessageChannel !== 'undefined') { + var channel = new global.MessageChannel(); + channel.port1.onmessage = nextTick; + scheduleDrain = function () { + channel.port2.postMessage(0); + }; + } else if ('document' in global && 'onreadystatechange' in global.document.createElement('script')) { + scheduleDrain = function () { + + // Create a '; + if (navigator.userAgent.indexOf("Firefox") != -1) { + let c = unsafeWindow.open("", "_blank"); + c.document.write(html); + c.document.close(); + } else { + _GM_openInTab('data:text/html;charset=utf-8,' + encodeURIComponent(html),{active:true}); + } + }, + copyImages: function(isAlert) { + var nodes = this.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]:not(.ignore)'); + var urls = []; + [].forEach.call(nodes, function(node){ + if(unsafeWindow.getComputedStyle(node).display!="none"){ + urls.push(node.dataset.src); + } + }); + + let copyData = urls.join("\n"); + + _GM_setClipboard(copyData); + + this.urlsTextarea.value = copyData; + this.urlsTextareaCon.style.display = "block"; + + if (isAlert) { + this.showTips(i18n("copySuccess",urls.length)); + } + }, + + Preload:function(ele,oriThis){ + this.ele=ele; + this.oriThis=oriThis;//主this + this.init(); + }, + Scrollbar:function(scrollbar,container,isHorizontal){ + this.scrollbar=scrollbar; + this.container=container; + this.isHorizontal=isHorizontal + this.init(); + }, + + addStyle:function(){ + if (GalleryC.style) { + if (!GalleryC.style.parentNode) { + GalleryC.style = _GM_addStyle(GalleryC.style.innerText); + this.globalSSheet = GalleryC.style.sheet; + } + return; + } + GalleryC.style=_GM_addStyle('\ + /*最外层容器*/\ + .pv-gallery-container {\ + position: fixed;\ + top: 0;\ + left: 0;\ + width: 100%;\ + height: 100%;\ + min-width:unset;\ + min-height:unset;\ + padding: 0;\ + margin: 0;\ + border: none;\ + z-index:'+(prefs.imgWindow.zIndex - 1)+';\ + background-color: transparent;\ + display: initial;\ + }\ + /*全局border-box*/\ + .pv-gallery-container span{\ + -moz-box-sizing: border-box;\ + box-sizing: border-box;\ + line-height: 1.6;\ + text-overflow: unset;\ + background-image: initial;\ + float: initial;\ + }\ + .pv-gallery-container * {\ + font-size: 14px;\ + display: initial;\ + flex-direction: row;\ + user-select: none;\ + }\ + /*点击还原的工具条*/\ + span.pv-gallery-maximize-trigger{\ + position:fixed;\ + bottom:15px;\ + left:15px;\ + display:none;\ + background:#000;\ + opacity:0.6;\ + padding-left:10px;\ + font-size:16px;\ + line-height:0;\ + color:white;\ + cursor:pointer;\ + box-shadow:3px 3px 0 0 #333;\ + z-index:899999998;\ + }\ + .pv-gallery-maximize-trigger:hover{\ + opacity:0.9;\ + }\ + span.pv-gallery-maximize-trigger-close{\ + display:inline-block;\ + padding-left:10px;\ + vertical-align:middle;\ + height:30px;\ + padding:10px 0;\ + width:24px;\ + background:url("'+prefs.icons.loadingCancle+'") center no-repeat;\ + }\ + .pv-gallery-maximize-trigger-close:hover{\ + background-color:#333;\ + }\ + span.pv-gallery-head-command-close{\ + position:absolute;\ + top:0;\ + width:40px;\ + border-left: 1px solid #333333;\ + background:transparent no-repeat center;\ + background-image:url("'+prefs.icons.loadingCancle+'");\ + }\ + .pv-gallery-maximize-container+p{\ + position: fixed;\ + width: 100%;\ + z-index: 2;\ + text-align: center;\ + pointer-events: none;\ + margin-bottom: 45px;\ + left: 0;\ + bottom: 0;\ + opacity: 0;\ + transition: all .3s ease;\ + }\ + @media only screen and (max-width: 600px) {\ + .pv-gallery-maximize-container>.maximizeChild{\ + width:calc(50vw - 5px);\ + }\ + }\ + @media only screen and (min-width: 600px) {\ + .pv-gallery-maximize-container>.maximizeChild{\ + width:calc(33vw - 5px);\ + }\ + }\ + @media only screen and (min-width: 800px) {\ + .pv-gallery-maximize-container>.maximizeChild{\ + width:calc(25vw - 5px);\ + }\ + }\ + @media only screen and (min-width: 1000px) {\ + .pv-gallery-maximize-container>.maximizeChild{\ + width:calc(20vw - 5px);\ + }\ + }\ + @media only screen and (min-width: 1130px) {\ + .pv-gallery-maximize-container>.maximizeChild{\ + width:calc(16.6vw - 6px);\ + }\ + }\ + @media only screen and (max-width: 799px) {\ + .pv-gallery-range-box>input {\ + display: none;\ + }\ + .pv-gallery-head-command-drop-list {\ + right: 10px;\ + }\ + span.pv-gallery-head {\ + white-space: nowrap;\ + }\ + span.pv-gallery-sidebar-toggle-content {\ + font-size: 25px!important;\ + }\ + span.pv-gallery-sidebar-toggle {\ + height: 25px!important;\ + opacity: 0.6;\ + border-radius: 0!important;\ + }\ + .pv-gallery-sidebar-viewmore:not(.showmore) {\ + opacity: 0!important;\ + }\ + .pv-gallery-maximize-container{\ + margin-top: 30px;\ + }\ + .pv-gallery-sidebar-viewmore.showmore{\ + transform: scale(1.5);\ + bottom: 10px;\ + }\ + .pv-gallery-maximize-container span>p{\ + opacity: 0.3;\ + }\ + .pv-gallery-maximize-container+p{\ + opacity: 0.2;\ + }\ + span.pv-gallery-head-command-close {\ + position: fixed!important;\ + right: 0!important;\ + height: 29px!important;\ + background-color: black;\ + }\ + }\ + @media only screen and (min-width: 799px) {\ + .pv-gallery-maximize-container{\ + margin-top: 30px;\ + }\ + .pv-gallery-maximize-container span>p{\ + opacity: 0;\ + }\ + }\ + span.pv-gallery-tipsWords{\ + font-size: 50px;\ + font-weight: bold;\ + font-family: "黑体", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",\ + "Oxygen", "Ubuntu", "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji",\ + "Segoe UI Emoji", "Segoe UI Symbol";\ + color: #ffffff;\ + height: 70px;\ + line-height: 70px;\ + position: fixed;\ + left: 50%;\ + top: 10%;\ + margin-left: -150px;\ + padding: 0 10px;\ + z-index: 999999999;\ + background-color: #000;\ + border: 1px solid black;\ + border-radius: 10px;\ + opacity: 0;\ + filter: alpha(opacity=65);\ + box-shadow: 5px 5px 20px 0px #000;\ + -moz-transition:opacity 0.3s ease-in-out 0s;\ + -webkit-transition:opacity 0.3s ease-in-out 0s;\ + transition:opacity 0.3s ease-in-out 0s;\ + pointer-events: none;\ + overflow: hidden;\ + text-overflow: ellipsis;\ + white-space: nowrap;\ + max-width: 65%;\ + }\ + /*顶栏*/\ + span.pv-gallery-head {\ + position: absolute;\ + top: 0;\ + left: 0;\ + width: 100%;\ + min-height: 30px;\ + height: auto;\ + z-index:1;\ + background-color:rgb(0,0,0);\ + border:none;\ + border-bottom:1px solid #333333;\ + text-align:right;\ + line-height:0;\ + font-size: 14px;\ + color:#757575;\ + padding-right:42px;\ + display: block;\ + overflow-x: visible;\ + overflow-y: auto;\ + scrollbar-width: none;\ + -ms-overflow-style: none;\ + }\ + span.pv-gallery-head::-webkit-scrollbar {\ + width: 0 !important;\ + height: 0 !important;\ + }\ + .pv-gallery-head > span{\ + vertical-align:middle;\ + }\ + /*顶栏左边*/\ + span.pv-gallery-head-float-left{\ + float:left;\ + height:100%;\ + text-align:left;\ + padding-left:5px;\ + display: table;\ + }\ + .pv-gallery-head-float-left > span{\ + display:inline-block;\ + height:100%;\ + vertical-align:middle;\ + }\ + .pv-gallery-head-float-left > span > *{\ + vertical-align:middle;\ + }\ + .pv-gallery-head-left-img-info{\ + cursor:help;\ + }\ + .pv-gallery-head-left-img-info-description {\ + margin-left: 10px;\ + margin-right: 10px;\ + overflow: hidden;\ + text-overflow: ellipsis;\ + white-space: nowrap;\ + max-width: 6em;\ + display: inherit;\ + }\ + .pv-gallery-range-box{\ + display: inline-flex;\ + justify-content: center;\ + align-items: center;\ + }\ + .pv-gallery-range-box>#pinSize{\ + margin: 0 5px;\ + padding: 0px;\ + }\ + .pv-gallery-range-box>span{\ + padding: 0 5px 0 5px;\ + white-space: nowrap;\ + }\ + .pv-gallery-range-box>input{\ + background: white;\ + min-height: auto;\ + padding: 0;\ + -webkit-appearance: auto;\ + }\ + /*顶栏里面的按钮样式-开始*/\ + .pv-gallery-head-command{\ + display:inline-block;\ + cursor:pointer;\ + height:100%;\ + padding:0 8px;\ + text-align:center;\ + position:relative;\ + z-index:1;\ + vertical-align:middle;\ + -o-user-select: none;\ + -ms-user-select: none;\ + -webkit-user-select: none;\ + -moz-user-select: -moz-none;\ + user-select: none;\ + }\ + /*辅助点击事件的生成,countdown*/\ + .pv-gallery-head-command_overlayer{\ + top:0;\ + left:0;\ + right:0;\ + bottom:0;\ + position:absolute;\ + opacity:0;\ + }\ + .pv-gallery-head-command > *{\ + vertical-align:middle;\ + }\ + .pv-gallery-head-command-slide-show-countdown{\ + font-size:0.8em;\ + }\ + span.pv-gallery-head-command-slide-show-button{\ + border-radius:36px;\ + display:inline-block;\ + width:18px;\ + height:18px;\ + border:2px solid #757575;\ + margin-right:3px;\ + line-height:0;\ + }\ + .pv-gallery-head-command-slide-show-button-inner{\ + display:inline-block;\ + border:none;\ + border-top:4px solid transparent;\ + border-bottom:4px solid transparent;\ + border-left:8px solid #757575;\ + vertical-align:middle;\ + margin-left: 1px;\ + }\ + .pv-gallery-head-command-slide-show-button-inner_stop{\ + border-color:#757575;\ + margin-left: 0px;\ + }\ + span.pv-gallery-head-command-collect-icon{\ + display:inline-block;\ + height:20px;\ + width:20px;\ + background:transparent url("' + prefs.icons.fivePointedStar + '") 0 0 no-repeat;\ + }\ + span.pv-gallery-head-left-lock-icon{\ + display:inline-block;\ + height:20px;\ + width:20px;\ + cursor:pointer;\ + background:transparent url("' + prefs.icons.lock + '") 0 0 no-repeat;\ + }\ + span.pv-gallery-head-left-filter-icon{\ + display:inline-block;\ + height:20px;\ + width:20px;\ + cursor:pointer;\ + background:transparent url("' + prefs.icons.filter + '") 0 0 no-repeat;\ + }\ + .pv-gallery-head-command-collect-icon ~ .pv-gallery-head-command-collect-text::after{\ + content:"'+i18n("collect")+'";\ + }\ + .pv-gallery-head-command-collect-favorite > .pv-gallery-head-command-collect-icon{\ + background-position:-40px 0 !important;\ + }\ + .pv-gallery-head-command-collect-favorite > .pv-gallery-head-command-collect-text::after{\ + content:"'+i18n("collected")+'";\ + }\ + .pv-gallery-head-command-exit-collection{\ + color:#939300 !important;\ + display:none;\ + }\ + .pv-gallery-head-command-urlFilter{\ + color:#e9cccc !important;\ + display:none;\ + }\ + .pv-gallery-head-command:hover{\ + background-color:#272727;\ + color:#ccc;\ + }\ + /*droplist*/\ + .pv-gallery-head-command-drop-list{\ + position:fixed;\ + display:none;\ + box-shadow:0 0 3px #808080;\ + background-color:#272727;\ + line-height: 1.6;\ + text-align:left;\ + padding:10px;\ + color:#ccc;\ + margin-top:-1px;\ + z-index:9;\ + }\ + .pv-gallery-head-command-drop-list-item{\ + display:block;\ + padding:2px 5px;\ + cursor:pointer;\ + white-space:nowrap;\ + }\ + .pv-gallery-head-command-drop-list-item-collect-description{\ + cursor:default;\ + }\ + .pv-gallery-head-command-drop-list-item-collect-description > textarea{\ + resize:both;\ + width:auto;\ + height:auto;\ + background: white;\ + }\ + .pv-gallery-head-command-drop-list-item_disabled{\ + color:#757575;\ + }\ + .pv-gallery-head-command-drop-list-item input + *{\ + padding-left:3px;\ + }\ + .pv-gallery-head-command-drop-list-item input[type=number]{\ + text-align:left;\ + max-width:50px;\ + height:20px;\ + background: white;\ + color: black;\ + box-sizing: border-box;\ + display: initial;\ + margin: 0 5px;\ + padding: 0 5px;\ + }\ + .pv-gallery-head-command-drop-list-item input[type=checkbox]{\ + width:20px;\ + box-sizing: border-box;\ + display: initial;\ + margin: 0 5px;\ + opacity: 1;\ + position: initial;\ + }\ + .pv-gallery-head-command-drop-list-item > * {\ + vertical-align:middle;\ + width: auto;\ + opacity: 1;\ + height: auto;\ + padding: 0;\ + margin: 0;\ + }\ + .pv-gallery-head-command-drop-list-item label {\ + font-weight: normal;\ + display:inline;\ + font-size:unset;\ + line-height: initial;\ + color: inherit;\ + }\ + .pv-gallery-head-command-drop-list-item label:after {\ + display:none;\ + }\ + .pv-gallery-head-command-drop-list-item:hover{\ + background-color:#404040;\ + }\ + /*container*/\ + .pv-gallery-head-command-container{\ + display:inline-block;\ + height:100%;\ + position:relative;\ + }\ + /* after伪类生成标识下拉菜单的三角图标*/\ + .pv-gallery-head-command-container > .pv-gallery-head-command::after{\ + content:"";\ + display:inline-block;\ + vertical-align:middle;\ + border:none;\ + border-top:7px solid #757575;\ + border-left:5px solid transparent;\ + border-right:5px solid transparent;\ + margin-left:5px;\ + -moz-transition:all 0.3s ease-in-out 0s;\ + -webkit-transition:all 0.3s ease-in-out 0s;\ + transition:all 0.3s ease-in-out 0s;\ + }\ + .pv-gallery-head-command-container:hover{\ + box-shadow:0 0 3px #808080;\ + }\ + .pv-gallery-head-command-container:hover > .pv-gallery-head-command{\ + background-color:#272727;\ + color:#ccc;\ + }\ + .pv-gallery-head-command-container:hover > .pv-gallery-head-command::after{\ + -webkit-transform:rotate(180deg);\ + -moz-transform:rotate(180deg);\ + transform:rotate(180deg);\ + border-top:7px solid #ccc;\ + }\ + .pv-gallery-head-command-container:hover .pv-gallery-head-command-collect-icon{\ + background-position:-20px 0;\ + }\ + .pv-gallery-head-command-container:hover .pv-gallery-head-command-slide-show-button{\ + border-color:#ccc;\ + }\ + .pv-gallery-head-command-container:hover .pv-gallery-head-command-slide-show-button-inner{\ + border-left-color:#ccc;\ + }\ + .pv-gallery-head-command-container:hover .pv-gallery-head-command-slide-show-button-inner_stop{\ + border-color:#ccc;\ + }\ + .pv-gallery-head-command-container:hover > .pv-gallery-head-command-drop-list,.pv-gallery-head-command-container > .pv-gallery-head-command-drop-list.focus{\ + display:block;\ + }\ + /*顶栏里面的按钮样式-结束*/\ + .pv-gallery-body {\ + display: block;\ + height: 100%;\ + width: 100%;\ + margin: 0;\ + padding: 0;\ + border: none;\ + border-top: 30px solid transparent;\ + position: relative;\ + background-clip: padding-box;\ + z-index:0;\ + }\ + .pv-gallery-img-container {\ + display: block;\ + padding: 0;\ + margin: 0;\ + border: none;\ + height: 100%;\ + width: 100%;\ + background-clip: padding-box;\ + background-color: ' + (prefs.gallery.backgroundColor || 'rgba(20,20,20,0.75)') + ';\ + position:relative;\ + transition: background-color .3s ease;\ + }\ + .pv-gallery-img-container-top {\ + border-top: '+ prefs.gallery.sidebarSize +'px solid transparent;\ + }\ + .pv-gallery-img-container-right {\ + border-right: '+ prefs.gallery.sidebarSize +'px solid transparent;\ + }\ + .pv-gallery-img-container-bottom {\ + border-bottom: '+ prefs.gallery.sidebarSize +'px solid transparent;\ + }\ + .pv-gallery-img-container-left {\ + border-left: '+ prefs.gallery.sidebarSize +'px solid transparent;\ + }\ + /*大图区域的切换控制按钮*/\ + .pv-gallery-img-controler{\ + position:absolute;\ + top:50%;\ + height:60px;\ + width:50px;\ + margin-top:-30px;\ + cursor:pointer;\ + opacity:0.3;\ + z-index:1;\ + transition: opacity .5s ease;\ + }\ + .pv-gallery-sidebar-toggle-hide .pv-gallery-img-controler{\ + opacity:0;\ + }\ + span.pv-gallery-img-controler-pre{\ + background:rgba(70,70,70,0.8) url("'+prefs.icons.arrowLeft+'") no-repeat center;\ + left:10px;\ + }\ + span.pv-gallery-img-controler-next{\ + background:rgba(70,70,70,0.8) url("'+prefs.icons.arrowRight+'") no-repeat center;\ + right:10px;\ + }\ + .pv-gallery-img-controler:hover{\ + background-color:rgba(140,140,140,0.8);\ + opacity:0.9;\ + z-index:2;\ + }\ + /*滚动条样式--开始*/\ + .pv-gallery-scrollbar-h,\ + .pv-gallery-scrollbar-v{\ + display:none;\ + z-index:1;\ + position:absolute;\ + margin:0;\ + padding:0;\ + border:none;\ + }\ + .pv-gallery-scrollbar-h{\ + bottom:10px;\ + left:0;\ + right:0;\ + height:10px;\ + margin:0 2px;\ + }\ + .pv-gallery-scrollbar-v{\ + top:0;\ + bottom:0;\ + right:10px;\ + width:10px;\ + margin:2px 0;\ + }\ + .pv-gallery-scrollbar-h:hover{\ + height:25px;\ + bottom:0;\ + }\ + .pv-gallery-scrollbar-v:hover{\ + width:25px;\ + }\ + .pv-gallery-scrollbar-h:hover,\ + .pv-gallery-scrollbar-v:hover{\ + background-color:rgba(100,100,100,0.9);\ + z-index:2;\ + }\ + .pv-gallery-scrollbar-h-track,\ + .pv-gallery-scrollbar-v-track{\ + position:absolute;\ + top:0;\ + left:0;\ + right:0;\ + bottom:0;\ + background-color:rgba(100,100,100,0.3);\ + border:2px solid transparent;\ + }\ + .pv-gallery-scrollbar-h-handle,\ + .pv-gallery-scrollbar-v-handle{\ + position:absolute;\ + background-color:rgba(0,0,0,0.5);\ + }\ + .pv-gallery-scrollbar-h-handle{\ + height:100%;\ + }\ + .pv-gallery-scrollbar-v-handle{\ + width:100%;\ + right: 0;\ + }\ + .pv-gallery-scrollbar-h-handle:hover,\ + .pv-gallery-scrollbar-v-handle:hover{\ + background-color:rgba(80,33,33,1);\ + border: 2px solid #585757;\ + }\ + .pv-gallery-scrollbar-h-handle:active,\ + .pv-gallery-scrollbar-v-handle:active{\ + background-color:rgba(57,26,26,1);\ + border: 2px solid #878484;\ + }\ + /*滚动条样式--结束*/\ + .pv-gallery-img-content{\ + display:block;\ + width:100%;\ + height:100%;\ + overflow:hidden;\ + text-align:center;\ + padding:0;\ + border:none;\ + margin:0;\ + line-height:0;\ + font-size:0;\ + white-space:nowrap;\ + }\ + .pv-gallery-img-parent{\ + display:inline-flex;\ + align-items: center;\ + vertical-align: middle;\ + justify-content: center;\ + line-height:0;\ + }\ + .pv-gallery-img-parent video, .pv-gallery-img-parent>div{\ + background-size: cover;\ + }\ + .pv-gallery-img_broken{\ + display:none;\ + cursor:pointer;\ + }\ + .pv-gallery-img{\ + position:relative;\/*辅助e.layerX,layerY*/\ + display:inline-block;\ + vertical-align:middle;\ + width:auto;\ + height:auto;\ + padding:0;\ + border:5px solid #313131;\ + margin:1px;\ + opacity:0.3;\ + box-sizing: content-box;\ + background-color: #282828cc;\ + background-position: center 0;\ + background-repeat: no-repeat;\ + background-size: cover;\ + -webkit-background-size: cover;\ + -o-background-size: cover;\ + '+ + (prefs.gallery.transition ? ('\ + -webkit-transition: opacity 0.5s ease;\ + -moz-transition: opacity 0.5s ease;\ + transition: opacity 0.5s ease;\ + ') : '') + '\ + }\ + .pv-gallery-img_zoom-out{\ + cursor:'+support.cssCursorValue.zoomOut+';\ + }\ + .pv-gallery-img_zoom-in{\ + cursor:'+support.cssCursorValue.zoomIn+';\ + }\ + .pv-gallery-container.pv-gallery-sidebar-toggle-hide .pv-gallery-img{\ + border:0px;\ + }\ + span.pv-gallery-sidebar-toggle{\ + position:absolute;\ + line-height:12px;\ + text-align:center;\ + background-color:rgb(0,0,0);\ + color:#757575;\ + white-space:nowrap;\ + cursor:pointer;\ + z-index:2;\ + transition: background-color .3s ease, opacity .3s ease;\ + justify-content: center;\ + display:none;\ + }\ + :fullscreen .pv-gallery-container.pv-gallery-sidebar-toggle-hide span.pv-gallery-sidebar-toggle {\ + opacity: 0!important;\ + }\ + :-webkit-full-screen .pv-gallery-container.pv-gallery-sidebar-toggle-hide span.pv-gallery-sidebar-toggle {\ + opacity: 0!important;\ + }\ + :-ms-fullscreen .pv-gallery-container.pv-gallery-sidebar-toggle-hide span.pv-gallery-sidebar-toggle {\ + opacity: 0!important;\ + }\ + :fullscreen .pv-gallery-container.pv-gallery-sidebar-toggle-hide span.pv-gallery-sidebar-toggle:hover {\ + opacity: 1!important;\ + }\ + :-webkit-full-screen .pv-gallery-container.pv-gallery-sidebar-toggle-hide span.pv-gallery-sidebar-toggle:hover {\ + opacity: 1!important;\ + }\ + :-ms-fullscreen .pv-gallery-container.pv-gallery-sidebar-toggle-hide span.pv-gallery-sidebar-toggle:hover {\ + opacity: 1!important;\ + }\ + :fullscreen .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-head {\ + opacity: 0!important;\ + }\ + :-webkit-full-screen .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-head {\ + opacity: 0!important;\ + }\ + :-ms-fullscreen .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-head {\ + opacity: 0!important;\ + }\ + :fullscreen .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-head:hover {\ + opacity: 1!important;\ + }\ + :-webkit-full-screen .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-head:hover {\ + opacity: 1!important;\ + }\ + :-ms-fullscreen .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-head:hover {\ + opacity: 1!important;\ + }\ + .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-body>.pv-gallery-img-container>span.pv-gallery-sidebar-toggle{\ + opacity: 0.6;\ + padding: 35px;\ + background-color:#00000000;\ + }\ + .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-body>.pv-gallery-img-container>span.pv-gallery-sidebar-toggle:hover{\ + opacity: 1;\ + background-color:rgb(0 0 0 / 50%);\ + }\ + .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-body{\ + border-top: 0px solid transparent;\ + }\ + .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-head{\ + opacity: 0;\ + transition: opacity .3s ease;\ + }\ + .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-body>.pv-gallery-img-container{\ + background-color: black;\ + }\ + .pv-gallery-container.pv-gallery-sidebar-toggle-hide>.pv-gallery-head:hover{\ + opacity: 1;\ + }\ + .pv-gallery-container.pv-gallery-sidebar-toggle-hide .pv-gallery-img-parent,\ + .pv-gallery-container.pv-gallery-sidebar-toggle-hide .pv-gallery-img{\ + cursor: none;\ + }\ + .pv-gallery-sidebar-viewmore{\ + position:absolute;\ + line-height:0;\ + text-align:center;\ + background-color:#00000030;\ + color:#a1a1a1;\ + white-space:nowrap;\ + cursor:pointer;\ + z-index: 2;\ + display:none;\ + height: 30px;\ + width:30px;\ + border-radius: 15px;\ + line-height: 2 !important;\ + font-family: auto;\ + transition: background-color .3s ease;\ + }\ + .pv-gallery-sidebar-viewmore:hover{\ + opacity: 1;\ + background-color:#000000;\ + }\ + .pv-gallery-maximize-container+p:hover,.pv-gallery-maximize-container.checked+p:hover{\ + opacity: 1;\ + }\ + .pv-gallery-maximize-container.checked+p{\ + opacity: 0.8;\ + }\ + .pv-gallery-maximize-container+p>.need-checked{\ + display: none;\ + }\ + .pv-gallery-maximize-container.checked+p>.need-checked{\ + display: inline-block;\ + }\ + .pv-gallery-maximize-container+p>input{\ + pointer-events: all;\ + color: white;\ + background-color: black;\ + border: 0;\ + opacity: 0.8;\ + padding: 5px 10px;\ + cursor: pointer;\ + margin: 1px;\ + font-size: 20px;\ + }\ + .pv-gallery-maximize-container+p>input:hover{\ + color: red;\ + }\ + .pv-gallery-maximize-container{\ + min-width: 100%;\ + display: block;\ + background: black;\ + margin-left: 3px;\ + }\ + .pv-gallery-maximize-container.pv-gallery-flex-maximize{\ + column-count: unset;\ + -moz-column-count: unset;\ + -webkit-column-count: unset;\ + display: flex;\ + flex-flow: wrap;\ + justify-content: center;\ + }\ + .pv-gallery-maximize-container.pv-gallery-flex-maximize span{\ + width: 18.5%;\ + height: 30vh;\ + }\ + .pv-gallery-maximize-container.pv-gallery-flex-maximize img{\ + position: relative;\ + width: unset;\ + max-height: 100%;\ + max-width: 100%;\ + top: 50%;\ + transform: translateY(-50%) scale3d(1, 1, 1);\ + }\ + .pv-gallery-maximize-container.pv-gallery-flex-maximize img:hover {\ + transform: translateY(-50%) scale3d(1.1, 1.1, 1.1);\ + }\ + .pv-gallery-maximize-container span{\ + -moz-page-break-inside: avoid;\ + -webkit-column-break-inside: avoid;\ + break-inside: avoid;\ + float: left;\ + margin-bottom: 15px;\ + margin-right: 15px;\ + overflow: hidden;\ + position: relative;\ + }\ + .pv-gallery-maximize-container>.maximizeChild{\ + display: inline-block;\ + vertical-align: middle;\ + text-align: center;\ + background-color: rgba(40, 40, 40, 0.5);\ + border: 5px solid #000000;\ + font-size: 0px;\ + }\ + .pv-gallery-maximize-container>.maximizeChild:hover{\ + background: linear-gradient( 45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 75%, rgba(255, 255, 255, 0.4) 75%, rgba(255, 255, 255, 0.4) 100% ), linear-gradient( 45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 75%, rgba(255, 255, 255, 0.4) 75%, rgba(255, 255, 255, 0.4) 100% );\ + background-size: 20px 20px;\ + background-position: 0 0, 10px 10px;\ + }\ + .pv-gallery-maximize-container>.maximizeChild.selected{\ + border: 5px solid #ff000050;\ + }\ + .pv-gallery-maximize-container img{\ + max-width: 100%;\ + transition: transform .3s ease 0s;\ + transform: scale3d(1, 1, 1);\ + cursor: zoom-in;\ + min-height: 88px;\ + border-radius: 20px;\ + }\ + .pv-gallery-maximize-container>.maximizeChild:hover img {\ + transform: scale3d(1.1, 1.1, 1.1);\ + filter: brightness(1.1) !important;\ + opacity: 1;\ + }\ + .pv-gallery-maximize-container.pv-gallery-flex-maximize>.maximizeChild:hover img {\ + transform: translateY(-50%) scale3d(1.1, 1.1, 1.1);\ + }\ + .pv-gallery-maximize-container span>p{\ + position: absolute;\ + width: 100%;\ + max-height: 40%;\ + font-size: 18px;\ + text-align: center;\ + background: #00000080;\ + color: #fff;\ + left: 0;\ + user-select: none;\ + word-break: break-all;\ + display: inline;\ + margin: 0 auto;\ + transition:all 0.2s;\ + }\ + .pv-gallery-maximize-container span>p.pv-bottom-banner{\ + bottom: 0;\ + height: 35px;\ + cursor: pointer;\ + line-height: 40px;\ + }\ + .pv-gallery-maximize-container span>p.pv-bottom-banner>svg{\ + width: 20px;\ + height: 20px;\ + vertical-align: middle;\ + fill: currentColor;\ + overflow: hidden;\ + }\ + .pv-gallery-maximize-container span>p.pv-top-banner{\ + top: 0;\ + height: 25px;\ + cursor: pointer;\ + }\ + .pv-gallery-maximize-container span:hover>p{\ + opacity: 1!important;\ + }\ + .pv-gallery-maximize-container span>p:hover{\ + background: #000000cc;\ + }\ + .pv-gallery-maximize-container span>p.pv-bottom-banner:hover{\ + color:red;\ + font-weight:bold;\ + }\ + .pv-gallery-maximize-container span>input{\ + position: absolute;\ + top: 2px;\ + z-index:1;\ + width: 20px;\ + height: 20px;\ + opacity: 0;\ + left: 0;\ + display: inline;\ + cursor: pointer;\ + }\ + .pv-gallery-maximize-container.checked img,\ + .pv-gallery-maximize-container.checked p{\ + opacity: 0.3;\ + }\ + .pv-gallery-maximize-container.checked input:checked+img {\ + opacity: 1;\ + }\ + .pv-gallery-maximize-container.checked span>input{\ + opacity: 1;\ + }\ + .pv-gallery-maximize-container.checked span>.pv-top-banner{\ + opacity: 0.6;\ + }\ + .pv-gallery-maximize-container+p>input.compareBtn{\ + display: none;\ + }\ + .pv-gallery-maximize-container.canCompare+p>input.compareBtn{\ + display: inline;\ + }\ + .pv-gallery-maximize-container span:hover>input{\ + opacity: 1;\ + }\ + .pv-gallery-maximize-scroll{\ + overflow-y: scroll;\ + overflow-x: hidden;\ + height: 100%;\ + width: 100%;\ + position: absolute;\ + display: none;\ + top: 0;\ + left: 0;\ + background: black;\ + }\ + .pv-gallery-sidebar-toggle:hover,.pv-gallery-sidebar-viewmore:hover{\ + color:#ccc;\ + }\ + .pv-gallery-sidebar-toggle-h{\ + width:80px;\ + margin-left:-40px;\ + left:50%;\ + }\ + .pv-gallery-sidebar-viewmore-h{\ + margin-left:-15px;\ + left:50%;\ + }\ + .pv-gallery-sidebar-toggle-v{\ + height:80px;\ + margin-top:-40px;\ + top:50%;\ + }\ + .pv-gallery-sidebar-viewmore-v{\ + height:30px;\ + top:6%;\ + top: calc(50% - 25px);\ + }\ + .pv-gallery-sidebar-toggle-top{\ + top:-3px;\ + }\ + .pv-gallery-sidebar-viewmore-top{\ + top:15px;\ + }\ + .pv-gallery-sidebar-toggle-right{\ + right:-3px;\ + }\ + .pv-gallery-sidebar-viewmore-right{\ + right:18px;\ + }\ + .pv-gallery-sidebar-toggle-bottom{\ + bottom:-3px;\ + }\ + .pv-gallery-sidebar-viewmore-bottom{\ + display: block;\ + bottom:15px;\ + }\ + .pv-gallery-sidebar-viewmore-bottom.showmore{\ + background-color: rgb(42, 42, 42);\ + opacity: 1;\ + }\ + .pv-gallery-sidebar-toggle-left{\ + left:-3px;\ + }\ + .pv-gallery-sidebar-viewmore-left{\ + left:18px;\ + }\ + span.pv-gallery-sidebar-toggle-content{\ + display:inline-block;\ + vertical-align:middle;\ + white-space:normal;\ + word-wrap:break-word;\ + overflow-wrap:break-word;\ + line-height:16px;\ + font-size:18px;\ + text-align:center;\ + margin-bottom:8px;\ + }\ + span.pv-gallery-sidebar-viewmore-content{\ + display:inline-block;\ + vertical-align:middle;\ + white-space:normal;\ + word-wrap:break-word;\ + overflow-wrap:break-word;\ + line-height:1;\ + font-size:16px;\ + text-align:center;\ + }\ + .pv-gallery-sidebar-toggle-content-v,.pv-gallery-sidebar-viewmore-content-v{\ + width:1.1em;\ + }\ + span.pv-gallery-sidebar-toggle-content-v{\ + line-height: 60px !important;\ + }\ + /*侧边栏开始*/\ + .pv-gallery-sidebar-container {\ + position: absolute;\ + background-color:rgb(0,0,0);\ + padding:5px;\ + border:none;\ + margin:0;\ + text-align:center;\ + line-height:0;\ + white-space:nowrap;\ + -o-user-select: none;\ + -webkit-user-select: none;\ + -moz-user-select: -moz-none;\ + user-select: none;\ + }\ + .pv-gallery-sidebar-container-h {\ + height: '+ prefs.gallery.sidebarSize +'px;\ + width: 100%;\ + }\ + .pv-gallery-sidebar-container-v {\ + width: '+ prefs.gallery.sidebarSize +'px;\ + height: 100%;\ + }\ + .pv-gallery-sidebar-container-top {\ + top: 0;\ + left: 0;\ + border-bottom:1px solid #333333;\ + }\ + .pv-gallery-sidebar-container-right {\ + top: 0;\ + right: 0;\ + border-left:1px solid #333333;\ + }\ + .pv-gallery-sidebar-container-bottom {\ + bottom: 0;\ + left: 0;\ + border-top:1px solid #333333;\ + }\ + .pv-gallery-sidebar-container-left {\ + top: 0;\ + left: 0;\ + border-right:1px solid #333333;\ + }\ + .pv-gallery-sidebar-content {\ + display: inline-block;\ + margin: 0;\ + padding: 0;\ + border: none;\ + background-clip: padding-box;\ + vertical-align:middle;\ + position:relative;\ + text-align:left;\ + }\ + .pv-gallery-sidebar-content-h {\ + height: 100%;\ + width: 90%;\ + border-left: 40px solid transparent;\ + border-right: 40px solid transparent;\ + }\ + .pv-gallery-sidebar-content-v {\ + height: 90%;\ + width: 100%;\ + border-top: 40px solid transparent;\ + border-bottom: 40px solid transparent;\ + }\ + span.pv-gallery-sidebar-controler{\ + cursor:pointer;\ + position:absolute;\ + background:rgba(255,255,255,0.1) no-repeat center;\ + }\ + .pv-gallery-sidebar-controler:hover{\ + background-color:rgba(255,255,255,0.3);\ + }\ + .pv-gallery-sidebar-controler-pre-h,\ + .pv-gallery-sidebar-controler-next-h{\ + top:0;\ + width:36px;\ + height:100%;\ + }\ + .pv-gallery-sidebar-controler-pre-v,\ + .pv-gallery-sidebar-controler-next-v{\ + left:0;\ + width:100%;\ + height:36px;\ + }\ + span.pv-gallery-sidebar-controler-pre-h {\ + left: -40px;\ + background-image: url("'+prefs.icons.arrowLeft+'");\ + }\ + span.pv-gallery-sidebar-controler-next-h {\ + right: -40px;\ + background-image: url("'+prefs.icons.arrowRight+'");\ + }\ + span.pv-gallery-sidebar-controler-pre-v {\ + top: -40px;\ + background-image: url("'+prefs.icons.arrowTop+'");\ + }\ + span.pv-gallery-sidebar-controler-next-v {\ + bottom: -40px;\ + background-image: url("'+prefs.icons.arrowBottom+'");\ + }\ + .pv-gallery-sidebar-thumbnails-container {\ + display: block;\ + overflow: hidden;\ + height: 100%;\ + width: 100%;\ + margin:0;\ + border:none;\ + padding:0;\ + line-height:0;\ + position:relative;\ + }\ + .pv-gallery-sidebar-thumbnails-container span{\ + vertical-align:middle;\ + }\ + .pv-gallery-sidebar-thumbnails-container-h{\ + border-left:1px solid #464646;\ + border-right:1px solid #464646;\ + white-space:nowrap;\ + }\ + .pv-gallery-sidebar-thumbnails-container-v{\ + border-top:1px solid #464646;\ + border-bottom:1px solid #464646;\ + white-space:normal;\ + }\ + .pv-gallery-sidebar-thumbnails-container-top {\ + padding-bottom:5px;\ + }\ + .pv-gallery-sidebar-thumbnails-container-right {\ + padding-left:5px;\ + }\ + .pv-gallery-sidebar-thumbnails-container-bottom {\ + padding-top:5px;\ + }\ + .pv-gallery-sidebar-thumbnails-container-left {\ + padding-right:5px;\ + }\ + span.pv-gallery-sidebar-thumb-container {\ + display:inline-block;\ + text-align: center;\ + border:2px solid rgb(52,52,52);\ + background: linear-gradient( 45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 75%, rgba(255, 255, 255, 0.4) 75%, rgba(255, 255, 255, 0.4) 100% ), linear-gradient( 45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 75%, rgba(255, 255, 255, 0.4) 75%, rgba(255, 255, 255, 0.4) 100% );\ + background-size: 20px 20px;\ + background-position: 0 0, 10px 10px;\ + cursor:pointer;\ + position:relative;\ + padding:2px;\ + font-size:0;\ + line-height:0;\ + white-space:nowrap;\ + vertical-align: middle;\ + top:0;\ + left:0;\ + -webkit-transition:all 0.2s ease-in-out;\ + transition:all 0.2s ease-in-out;\ + }\ + span.pv-gallery-sidebar-thumb-container.ignore {\ + opacity: 0.5;\ + }\ + .pv-gallery-sidebar-thumbnails-container-h .pv-gallery-sidebar-thumb-container {\ + margin:0 2px;\ + height:100%;\ + }\ + .pv-gallery-sidebar-thumbnails-container-v .pv-gallery-sidebar-thumb-container {\ + margin:2px 0;\ + width:100%;\ + }\ + .pv-gallery-sidebar-thumbnails_hide-span > .pv-gallery-sidebar-thumb-container {\ + display:none;\ + }\ + .pv-gallery-sidebar-thumb-container:hover {\ + border:2px solid rgb(57,149,211);\ + }\ + span.pv-gallery-sidebar-thumb_selected {\ + border:2px solid rgb(229,59,62);\ + }\ + .pv-gallery-sidebar-thumb_selected-top {\ + top:5px;\ + }\ + .pv-gallery-sidebar-thumb_selected-right {\ + left:-5px;\ + }\ + .pv-gallery-sidebar-thumb_selected-bottom {\ + top:-5px;\ + }\ + .pv-gallery-sidebar-thumb_selected-left {\ + left:5px;\ + }\ + span.pv-gallery-sidebar-thumb-loading{\ + position:absolute;\ + top:0;\ + left:0;\ + text-align:center;\ + width:100%;\ + height:100%;\ + display:none;\ + opacity:0.6;\ + background:black url("' + prefs.icons.loading + '") no-repeat center ;\ + }\ + .pv-gallery-sidebar-thumb-loading:hover{\ + opacity:0.8;\ + }\ + .pv-gallery-sidebar-thumb {\ + display: inline-block;\ + vertical-align: middle;\ + max-width: 100% !important;\ + max-height: 100% !important;\ + height: auto !important;\ + width: auto !important;\ + min-width: 10%;\ + min-height: 10%;\ + }\ + .pv-gallery-urls-textarea {\ + display: none;\ + position: fixed;\ + top: 10vh;\ + left: 10vw;\ + z-index: 100;\ + }\ + .pv-gallery-urls-textarea>textarea {\ + width: 80vw;\ + height: 80vh;\ + border: 10px solid #272727;\ + background: #ffffffee;\ + color: black;\ + text-wrap: nowrap;\ + }\ + span.pv-gallery-urls-textarea-close,\ + span.pv-gallery-urls-textarea-download{\ + height: 40px;\ + top: -25px;\ + background: #272727 no-repeat center;\ + color: white;\ + border-radius: 50%;\ + cursor: pointer;\ + }\ + span.pv-gallery-urls-textarea-close:hover,\ + span.pv-gallery-urls-textarea-download:hover {\ + background-color: black;\ + }\ + span.pv-gallery-urls-textarea-close {\ + position:absolute;\ + right: -25px;\ + width:40px;\ + background-image:url("'+prefs.icons.loadingCancle+'");\ + }\ + span.pv-gallery-urls-textarea-download {\ + position: absolute;\ + left: -25px;\ + width: 40px;\ + display: flex;\ + align-items: center;\ + justify-content: center;\ + }\ + span.pv-gallery-urls-textarea-download>svg {\ + height: 15px;\ + width: 15px;\ + fill: white;\ + }\ + .pv-gallery-vertical-align-helper{\ + display:inline-block;\ + vertical-align:middle;\ + width:0;\ + height:100%;\ + margin:0;\ + border:0;\ + padding:0;\ + visibility:hidden;\ + white-space:nowrap;\ + background-color:red;\ + }\ + '); + this.globalSSheet=GalleryC.style.sheet; + + var head=document.head; + var style2=document.createElement('style'); + this.thumbVisibleStyle=style2; + style2.type='text/css'; + head.appendChild(style2); + + // 让 description 的文字内容溢出用点点点(...)省略号表示 + // .pv-gallery-head-left-img-info-description { + // overflow: hidden; + // text-overflow: ellipsis; + // white-space: nowrap; + // width: 27em; + // } + }, + + }; + + + GalleryC.prototype.Preload.prototype={//预读对象 + init:function(){ + if(!this.container){//预读的图片都仍里面 + var div=document.createElement('div'); + div.className='pv-gallery-preloaded-img-container'; + div.style.display='none'; + getBody(document).appendChild(div); + GalleryC.prototype.Preload.prototype.container=div; + }; + this.max=prefs.gallery.max; + this.nextNumber=0; + this.nextEle=this.ele; + this.preNumber=0; + this.preEle=this.ele; + this.direction='pre'; + }, + preload:function(){ + var ele=this.getPreloadEle(); + if(!ele){ + return; + }; + this.waitForReady(ele); + }, + waitForReady: function(ele) { + var self = this; + var beginLoadImg = () => { + self.imgReady = imgReady(dataset(ele,'src'), { + loadEnd: function(e) { + if (self.aborted) { + return; + } + + if (e.type == 'error') { + var srcs = dataset(ele, 'srcs'); + if (srcs) srcs = srcs.split(","); + if (srcs && srcs.length > 0) { + var src = srcs.shift(); + dataset(ele, 'srcs', srcs.join(",")); + if (src) { + dataset(ele, 'src', src); + self.waitForReady(ele); + return; + } + } + } + + dataset(ele,'preloaded','true'); + if (!dataset(ele,'naturalSize') && this.naturalHeight && this.naturalWidth) { + dataset(ele,'naturalSize', JSON.stringify({ + h: this.naturalHeight, + w: this.naturalWidth, + })); + let key = this.naturalWidth + "x" + this.naturalHeight; + self.oriThis.sizeMap[key] = (self.oriThis.sizeMap[key] || 0) + 1; + if (self.oriThis.sizeMap[key] === 2) { + let option = document.createElement("option"); + option.innerText = key; + option.value = this.naturalWidth + "-" + this.naturalWidth + "x" + this.naturalHeight + "-" + this.naturalHeight; + self.oriThis.pinSize.appendChild(option); + } + } + self.container.appendChild(this); + self.preload(); + }, + time:60 * 1000,//限时一分钟,否则强制结束并开始预读下一张。 + }); + }; + var xhr = dataset(ele, 'xhr') !== 'stop' && this.oriThis.getPropBySpanMark(ele, 'xhr'); + if (xhr) { + var xhrError = function() { + dataset(ele, 'xhr', 'stop'); + dataset(ele, 'src', dataset(ele, 'thumbSrc')); + beginLoadImg(); + }; + xhrLoad.load({ + url: dataset(ele,'src'), + xhr: xhr, + cb: function(imgSrc, imgSrcs, caption, captions) { + if (imgSrc) { + dataset(ele, 'src', imgSrc); + dataset(ele, 'xhr', 'stop'); + if (caption) dataset(ele, 'description', caption); + beginLoadImg(); + if (imgSrcs && imgSrcs.length) { + let i = 0; + imgSrcs.forEach(src => { + if (src == imgSrc) return; + let img = document.createElement('img'); + img.src = src; + let cap = captions && captions[i] ? captions[i] : caption; + imgReady(img,{ + ready:function(){ + let result = findPic(img); + if (cap) result.description = cap; + self.oriThis.data.push(result); + self.oriThis._appendThumbSpans([result]); + self.oriThis.loadThumb(); + } + }); + i++; + }) + } + } else { + xhrError(); + } + }, + onerror: xhrError + }); + } else { + beginLoadImg(); + } + }, + getPreloadEle:function(){ + if((this.max<=this.nextNumber && this.max<=this.preNumber) || (!this.nextEle && !this.preEle)){ + return; + }; + var ele=this.direction=='pre'? this.getNext() : this.getPrevious(); + if(ele && !dataset(ele,'preloaded')){ + return ele; + }else{ + return this.getPreloadEle(); + }; + }, + getNext:function(){ + this.nextNumber++; + this.direction='next'; + if(!this.nextEle)return; + return (this.nextEle = this.oriThis.getThumSpan(false,this.nextEle)); + }, + getPrevious:function(){ + this.preNumber++; + this.direction='pre'; + if(!this.preEle)return; + return (this.preEle = this.oriThis.getThumSpan(true,this.preEle)); + }, + abort:function(){ + this.aborted=true; + if(this.imgReady){ + this.imgReady.abort(); + }; + }, + }; + + + GalleryC.prototype.Scrollbar.prototype={//滚动条对象 + init:function(){ + var bar=this.scrollbar.bar; + this.shown=bar.offsetWidth!=0; + var self=this; + bar.addEventListener('mousedown',function(e){//点击滚动条区域,该干点什么! + e.preventDefault(); + var target=e.target; + var handle=self.scrollbar.handle; + var track=self.scrollbar.track; + switch(target){ + case handle:{//手柄;功能,拖动手柄来滚动窗口 + let pro=self.isHorizontal ? ['left','clientX'] : ['top','clientY']; + var oHOffset=parseFloat(handle.style[pro[0]]); + var oClient=e[pro[1]]; + + var moveHandler=function(e){ + self.scroll(oHOffset + e[pro[1]] - oClient,true); + }; + let upHandler=function(){ + document.removeEventListener('mousemove',moveHandler,true); + document.removeEventListener('mouseup',upHandler,true); + }; + document.addEventListener('mousemove',moveHandler,true); + document.addEventListener('mouseup',upHandler,true); + }break; + case track:{//轨道;功能,按住不放来连续滚动一个页面的距离 + let pro=self.isHorizontal ? ['left','offsetX','layerX','clientWidth','offsetWidth'] : ['top' , 'offsetY' ,'layerY','clientHeight','offsetHeight']; + var clickOffset=typeof e[pro[1]]=='undefined' ? e[pro[2]] : e[pro[1]]; + var handleOffset=parseFloat(handle.style[pro[0]]); + var handleSize=handle[pro[4]]; + var under= clickOffset > handleOffset ;//点击在滚动手柄的下方 + var containerSize=self.container[pro[3]]; + + var scroll=function(){ + self.scrollBy(under? (containerSize - 10) : (-containerSize + 10));//滚动一个页面距离少一点 + }; + scroll(); + + var checkStop=function(){//当手柄到达点击位置时停止 + var handleOffset=parseFloat(handle.style[pro[0]]); + if(clickOffset >= handleOffset && clickOffset <= (handleOffset + handleSize)){ + clearTimeout(scrollTimeout); + clearInterval(scrollInterval); + }; + }; + + + var scrollInterval; + var scrollTimeout=setTimeout(function(){ + scroll(); + scrollInterval=setInterval(function(){ + scroll(); + checkStop(); + },120); + checkStop(); + },300); + + + checkStop(); + + let upHandler=function(){ + clearTimeout(scrollTimeout); + clearInterval(scrollInterval); + document.removeEventListener('mouseup',upHandler,true); + }; + document.addEventListener('mouseup',upHandler,true); + }break; + }; + + },true); + }, + reset:function(){//判断滚动条该显示还是隐藏 + + var pro=this.isHorizontal ? ['scrollWidth','clientWidth','width'] : ['scrollHeight','clientHeight','height']; + + //如果内容大于容器的content区域 + + var scrollSize=this.container[pro[0]]; + var clientSize=this.container[pro[1]]; + var scrollMax=scrollSize - clientSize; + this.scrollMax=scrollMax; + if(scrollMax>0){ + this.show(); + var trackSize=this.scrollbar.track[pro[1]]; + this.trackSize=trackSize; + var handleSize=Math.floor((clientSize/scrollSize) * trackSize); + handleSize=Math.max(20,handleSize);//限制手柄的最小大小; + this.handleSize=handleSize; + this.one=(trackSize-handleSize) / scrollMax;//一个像素对应的滚动条长度 + this.scrollbar.handle.style[pro[2]]= handleSize + 'px'; + this.scroll(this.getScrolled()); + }else{ + this.hide(); + }; + }, + show:function(){ + if(this.shown)return; + this.shown=true; + this.scrollbar.bar.style.display='block'; + }, + hide:function(){ + if(!this.shown)return; + this.shown=false; + this.scrollbar.bar.style.display='none'; + }, + scrollBy:function(distance,handleDistance){ + return this.scroll(this.getScrolled() + (handleDistance? distance / this.one : distance)); + }, + scrollByPages:function(num){ + this.scroll(this.getScrolled() + (this.container[(this.isHorizontal ? 'clientWidth' : 'clientHeight')] - 10) * num); + }, + scroll:function(distance,handleDistance,transition){ + if(!this.shown)return; + + //滚动实际滚动条 + var _distance=distance; + _distance=handleDistance? distance / this.one : distance; + _distance=Math.max(0,_distance); + _distance=Math.min(_distance,this.scrollMax); + + + var pro=this.isHorizontal? ['left','scrollLeft'] : ['top','scrollTop']; + + + //滚动虚拟滚动条 + //根据比例转换为滚动条上应该滚动的距离。 + distance=handleDistance? distance : this.one * distance; + //处理非法值 + distance=Math.max(0,distance);//如果值小于0那么取0 + distance=Math.min(distance,this.trackSize - this.handleSize);//大于极限值,取极限值 + + var shs=this.scrollbar.handle.style; + var container=this.container; + if(transition){ + clearInterval(this.transitionInterval); + + var start=0; + var duration=10; + + var cStart=this.getScrolled(); + var cChange=_distance-cStart; + var sStart=parseFloat(shs[pro[0]]); + var sChange=distance-sStart; + + var transitionInterval=setInterval(function(){ + var cEnd=Tween.Cubic.easeInOut(start,cStart,cChange,duration); + var sEnd=Tween.Cubic.easeInOut(start,sStart,sChange,duration); + + container[pro[1]]=cEnd; + shs[pro[0]]=sEnd + 'px'; + + start++; + if(start>=duration){ + clearInterval(transitionInterval); + }; + },35); + + this.transitionInterval=transitionInterval; + + return; + }; + + var noScroll=shs[pro[0]].replace(/(\.\d*)?\s*px/,"")==Math.floor(distance); + shs[pro[0]]=distance + 'px'; + container[pro[1]]=_distance; + return noScroll; + }, + getScrolled:function(){ + return this.container[(this.isHorizontal ? 'scrollLeft' : 'scrollTop')]; + }, + }; + + + //放大镜 + function MagnifierC(img,data){ + this.img=img; + this.data=data; + this.init(); + }; + + MagnifierC.all=[]; + MagnifierC.styleZIndex=900000000;//全局z-index; + + MagnifierC.prototype={ + init:function(){ + MagnifierC.zoomRange=prefs.magnifier.wheelZoom.range.slice(0).sort((a, b)=>{return a - b}); + MagnifierC.zoomRangeR=MagnifierC.zoomRange.slice(0).reverse();//降序 + this.addStyle(); + MagnifierC.all.push(this); + var container=document.createElement('span'); + + container.className='pv-magnifier-container'; + getBody(document).appendChild(container); + + this.magnifier=container; + + var imgNaturalSize={ + h:this.img.naturalHeight, + w:this.img.naturalWidth, + }; + + this.imgNaturalSize=imgNaturalSize; + + var cs=container.style; + cs.zIndex=MagnifierC.styleZIndex++; + + + + var maxDia=Math.ceil(Math.sqrt(Math.pow(1/2*imgNaturalSize.w,2) + Math.pow(1/2*imgNaturalSize.h,2)) * 2); + this.maxDia=maxDia; + + var radius=prefs.magnifier.radius; + radius=Math.min(maxDia/2,radius); + this.radius=radius; + var diameter=radius * 2; + this.diameter=diameter; + + cs.width=diameter + 'px'; + cs.height=diameter + 'px'; + cs.borderRadius=radius+1 + 'px'; + cs.backgroundImage='url("'+ this.img.src +'")'; + cs.marginLeft= -radius +'px'; + cs.marginTop= -radius +'px'; + + var imgPos=getContentClientRect(this.data.img); + var wScrolled=getScrolled(); + var imgRange={//图片所在范围 + x:[imgPos.left + wScrolled.x , imgPos.right + wScrolled.x], + y:[imgPos.top + wScrolled.y, imgPos.bottom + wScrolled.y], + }; + var imgW=imgRange.x[1] - imgRange.x[0]; + var imgH=imgRange.y[1] - imgRange.y[0]; + //如果图片太小的话,进行范围扩大。 + var minSize=60; + if(imgW < minSize){ + imgRange.x[1] +=(minSize - imgW)/2; + imgRange.x[0] -=(minSize - imgW)/2; + imgW=minSize; + }; + if(imgH < minSize){ + imgRange.y[1] +=(minSize - imgH)/2; + imgRange.y[0] -=(minSize - imgH)/2; + imgH=minSize; + }; + this.imgSize={ + w:imgW, + h:imgH, + }; + this.imgRange=imgRange; + + this.setMouseRange(); + + + this.move({ + pageX:imgRange.x[0], + pageY:imgRange.y[0], + }); + + this._focus=this.focus.bind(this); + this._blur=this.blur.bind(this); + this._move=this.move.bind(this); + this._remove=this.remove.bind(this); + this._pause=this.pause.bind(this); + this._zoom=this.zoom.bind(this); + this._clickOut=this.clickOut.bind(this); + this._keydown=this.keydown.bind(this); + + if (prefs.magnifier.wheelZoom.enabled || prefs.magnifier.wheelZoom.scaleImage !== false) { + this.zoomLevel=1; + this.defaultDia=diameter; + addWheelEvent(container,this._zoom,false); + } + + container.addEventListener('mouseover',this._focus,false); + container.addEventListener('mouseout',this._blur,false); + container.addEventListener('dblclick',this._remove,false); + container.addEventListener('click',this._pause,false); + + + document.addEventListener('keydown',this._keydown, true); + document.addEventListener('mousemove',this._move,true); + document.addEventListener('mouseup',this._clickOut,true); + }, + addStyle:function(){ + if (MagnifierC.style) { + if (!MagnifierC.style.parentNode) { + MagnifierC.style = _GM_addStyle(MagnifierC.style.innerText); + } + return; + } + MagnifierC.style=_GM_addStyle('\ + .pv-magnifier-container{\ + position:absolute;\ + padding:0;\ + margin:0;\ + background-origin:border-box;\ + -moz-box-sizing:border-box;\ + box-sizing:border-box;\ + border:3px solid #CCCCCC;\ + background:rgba(40, 40, 40, 0.9) no-repeat;\ + }\ + .pv-magnifier-container_focus{\ + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.7);\ + }\ + .pv-magnifier-container_pause{\ + border-color:red;\ + }\ + '); + }, + clickOut:function(e){ + if(!this.magnifier.classList.contains("pv-magnifier-container_focus")){ + this.remove(e); + } + }, + focus:function(){ + this.magnifier.classList.add('pv-magnifier-container_focus'); + this.magnifier.style.zIndex=MagnifierC.styleZIndex++; + }, + blur:function(){ + this.magnifier.classList.remove('pv-magnifier-container_focus'); + }, + move:function(e){ + var mouseCoor={ + x:e.pageX, + y:e.pageY, + }; + var mouseRange=this.mouseRange; + var imgRange=this.imgRange; + + if( !(mouseCoor.x >= mouseRange.x[0] && mouseCoor.x <= mouseRange.x[1] && mouseCoor.y >= mouseRange.y[0] && mouseCoor.y <= mouseRange.y[1]))return;//如果不再鼠标范围 + if(mouseCoor.x > imgRange.x[1]){ + mouseCoor.x = imgRange.x[1]; + }else if(mouseCoor.x < imgRange.x[0]){ + mouseCoor.x = imgRange.x[0]; + }; + if(mouseCoor.y > imgRange.y[1]){ + mouseCoor.y = imgRange.y[1]; + }else if(mouseCoor.y < imgRange.y[0]){ + mouseCoor.y = imgRange.y[0]; + }; + + var ms=this.magnifier.style; + ms.top= mouseCoor.y + 'px'; + ms.left= mouseCoor.x + 'px'; + + var radius=this.radius; + var imgSize=this.imgSize; + var imgNaturalSize=this.imgNaturalSize; + var px=-((mouseCoor.x-imgRange.x[0])/imgSize.w * imgNaturalSize.w) + radius +'px'; + var py=-((mouseCoor.y-imgRange.y[0])/imgSize.h * imgNaturalSize.h) + radius +'px'; + ms.backgroundPosition=px + ' ' + py; + }, + getNextZoomLevel:function(){ + var level; + var self=this; + if(this.zoomOut){//缩小 + let found = MagnifierC.zoomRangeR.find(function(value){ + if(value < self.zoomLevel){ + level=value; + return true; + } + }) + if (!found) { + level = self.zoomLevel * 0.9; + } + }else{ + let found = MagnifierC.zoomRange.find(function(value){ + if(value > self.zoomLevel){ + level=value; + return true; + }; + }); + if (!found) { + level = self.zoomLevel * 1.1; + } + } + return level; + }, + zoom:function(e){ + if ((e.metaKey != !!prefs.magnifier.wheelZoom.meta) || + (e.altKey != !!prefs.magnifier.wheelZoom.alt) || + (e.ctrlKey != !!prefs.magnifier.wheelZoom.ctrl) || + (e.shiftKey != !!prefs.magnifier.wheelZoom.shift)) { + return; + } + if(e.deltaY===0)return;//非Y轴的滚动 + var ms=this.magnifier.style; + if(prefs.magnifier.wheelZoom.pauseFirst && !this.paused){ + if (prefs.magnifier.wheelZoom.scaleImage !== false) { + let curScale = ms.transform.match(/[\d\.]+/); + if (curScale) { + curScale = parseFloat(curScale[0]); + } else curScale = 1; + if (e.deltaY < 0) { + curScale += 0.1; + } else { + curScale -= 0.1; + } + if (curScale < 0.5) curScale = 0.5; + ms.transform = `scale(${curScale})`; + e.preventDefault(); + } + return; + } + if(!prefs.magnifier.wheelZoom.enabled)return; + e.preventDefault(); + if(e.deltaY < 0){//向上滚,放大; + if(this.diameter >= this.maxDia)return; + this.zoomOut=false; + }else{ + this.zoomOut=true; + }; + var level=this.getNextZoomLevel(); + if(!level)return; + + this.zoomLevel=level; + var diameter=this.defaultDia * level; + if(diameter > this.maxDia){ + diameter = this.maxDia; + }; + + var radius=diameter/2 + this.diameter=diameter; + var bRadius=this.radius; + this.radius=radius; + this.setMouseRange(); + ms.width=diameter+'px'; + ms.height=diameter+'px'; + ms.borderRadius=radius+1 + 'px'; + ms.marginLeft=-radius+'px'; + ms.marginTop=-radius+'px'; + var bBP=ms.backgroundPosition.split(' '); + ms.backgroundPosition=parseFloat(bBP[0]) + (radius - bRadius) + 'px' + ' ' + (parseFloat(bBP[1]) + ( radius - bRadius) + 'px'); + + }, + pause:function(){ + if(this.paused){ + this.magnifier.classList.remove('pv-magnifier-container_pause'); + document.addEventListener('mousemove',this._move,true); + }else{ + this.magnifier.classList.add('pv-magnifier-container_pause'); + document.removeEventListener('mousemove',this._move,true); + }; + this.paused=!this.paused; + }, + setMouseRange:function(){ + var imgRange=this.imgRange; + var radius=this.radius; + this.mouseRange={//鼠标活动范围 + x:[imgRange.x[0]-radius , imgRange.x[1] + radius], + y:[imgRange.y[0]-radius , imgRange.y[1] + radius], + }; + }, + keydown:function(e){ + if (e) { + e.preventDefault(); + e.stopPropagation(); + if (e.keyCode == 27) this.remove(); + } + }, + remove:function(e){ + if (e) { + e.preventDefault(); + e.stopPropagation(); + } + if (this.magnifier.parentNode) { + this.magnifier.parentNode.removeChild(this.magnifier); + MagnifierC.all.splice(MagnifierC.all.indexOf(this),1); + } + document.removeEventListener('mousemove',this._move,true); + document.removeEventListener('mouseup',this._clickOut,true); + document.removeEventListener('keydown',this._keydown, true); + }, + }; + + //图片窗口 + function ImgWindowC(img, data, actual, initPos, preview){ + this.loaded = false; + this.img = img; + this.actual = !!actual; + this.src = data?data.src:img.src; + this.data = data || findPic(img); + this.initPos = initPos || false; + this.preview = !!preview; + this.isImg = this.img.nodeName.toUpperCase() == 'IMG'; + this.init(); + if (data && this.isImg) { + this.img.src = location.protocol == "https" ? data.src.replace(/^http:/,"https:") : data.src; + } + }; + + ImgWindowC.all=[];//所有的窗口对象 + ImgWindowC.overlayer=null; + + + ImgWindowC.prototype={ + init:function(){ + ImgWindowC.showing = true; + ImgWindowC.zoomRange=prefs.imgWindow.zoom.range.slice(0).sort((a, b)=>{return a - b}); + ImgWindowC.zoomRangeR=ImgWindowC.zoomRange.slice(0).reverse();//降序 + var self=this; + if(uniqueImgWin && !uniqueImgWin.removed){ + uniqueImgWin.remove(); + } + if (!this.preview) { + //图片是否已经被打开 + if(ImgWindowC.all.find(function(iwin){ + if(iwin.src==self.src){ + iwin.firstOpen(); + return true; + }; + }))return; + } + + this.addStyle(); + + var img=this.img; + img.className='pv-pic-window-pic pv-pic-ignored'; + img.style.cssText='\ + top:0px;\ + left:0px;\ + '; + + var imgNaturalSize={ + h:img.naturalHeight, + w:img.naturalWidth, + }; + this.imgNaturalSize=imgNaturalSize; + this.following=false; + + var container=document.createElement('span'); + container.style.cssText='\ + cursor:pointer;\ + top:0px;\ + left:0px;\ + opacity:0;\ + background:black url("'+prefs.icons.loading+'") center no-repeat;\ + '; + container.className='pv-pic-window-container'; + container.innerHTML=createHTML( + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + '0'+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + '0'+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + '' + + '' + + '' + + //'' + + '' + + ''+ + ''+ + ''+ + ''+ + ''+prefs.icons.downloadSvgBtn+ + ''); + + let imgbox=container.firstChild; + imgbox.appendChild(img); + this.imgbox = imgbox; + + this.imgWindow=container; + + var toolMap={ + 'hand':container.querySelector('.pv-pic-window-tb-hand'), + 'rotate':container.querySelector('.pv-pic-window-tb-rotate'), + 'zoom':container.querySelector('.pv-pic-window-tb-zoom'), + 'fh':container.querySelector('.pv-pic-window-tb-flip-horizontal'), + 'fv':container.querySelector('.pv-pic-window-tb-flip-vertical'), + 'compare':container.querySelector('.pv-pic-window-tb-compare') + }; + this.toolMap=toolMap; + + var preButton=container.querySelector('.pv-pic-window-pre'); + preButton.addEventListener('click',function(e){ + e.preventDefault(); + e.stopPropagation(); + self.switchImage(false); + },false); + var nextButton=container.querySelector('.pv-pic-window-next'); + nextButton.addEventListener('click',function(e){ + e.preventDefault(); + e.stopPropagation(); + self.switchImage(true); + },false); + if (gallery && (gallery.shown || gallery.minimized)) { + preButton.style.display = "none"; + nextButton.style.display = "none"; + } + this.imgStateBox = container.querySelector('.pv-pic-search-state'); + this.imgState = container.querySelector('.pv-pic-search-state>span'); + this.preButton = container.querySelector('.pv-pic-window-pre'); + this.nextButton = container.querySelector('.pv-pic-window-next'); + let downloadIcon = container.querySelector('.pv-pic-search-state>svg'); + downloadIcon && downloadIcon.addEventListener('click', function(e) { + if (!self.data || !self.img) { + debug(self); + return; + } + e.preventDefault(); + e.stopPropagation(); + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { + _GM_openInTab(self.img.src, {active:false}); + } else { + downloadImg(self.img.src, (self.data.img.title || self.data.img.alt), prefs.saveName); + } + }, true); + + //关闭 + var closeButton=container.querySelector('.pv-pic-window-close'); + closeButton.style.cssText='top: -22px;right: 0px;'; + this.closeButton=closeButton; + closeButton.addEventListener('click',function(e){ + self.remove(); + },false); + + var maxButton=container.querySelector('.pv-pic-window-max'); + maxButton.style.cssText='top: -22px;right: 46px;'; + this.maxButton=maxButton; + maxButton.addEventListener('click',async function(e){ + if(!gallery){ + gallery=new GalleryC(); + gallery.data=[]; + } + var allData=await gallery.getAllValidImgs(); + allData.target = self.data; + gallery.data=allData; + gallery.load(gallery.data); + self.remove(); + },false); + + //var searchButton=container.querySelector('.pv-pic-window-search'); + //searchButton.style.cssText='top: -22px;right: 50px;'; + //this.searchButton=searchButton; + var srcs, from; + img.onerror=function(e){ + //setSearchState(i18n("loadNextSimilar"),img.parentNode); + if(self.removed || !self.isImg)return; + console.info(img.src+" "+i18n("loadError")); + if(!self.data)return; + var src; + if(self.data.srcs) + src=self.data.srcs.shift(); + if(src)img.src=src; + else{ + if(img.src!=self.data.imgSrc) + img.src=self.data.imgSrc; + return; + if(from 1) { + for (let i = 0; i < this.data.all.length; i++) { + if (this.data.src.indexOf(this.data.all[i].replace(/^(video|audio):/, "")) !== -1) { + this.curIndex = i; + break; + } + } + } + img.onload = function(e) { + if (self.removed) return; + self.loaded = true; + container.style.background=''; + if (self.preview && img.naturalHeight == 1 && img.naturalWidth == 1) { + self.remove(); + return; + } + self.imgWindow.style.display = ""; + self.imgNaturalSize = { + h:img.naturalHeight, + w:img.naturalWidth, + }; + self.setToolBadge('zoom',self.zoomLevel); + if (self==uniqueImgWin && prefs.floatBar.globalkeys.previewFollowMouse) { + self.followPos(uniqueImgWinInitX, uniqueImgWinInitY); + } else { + if (!self.zoomed) { + if (!self.imgWindow.classList.contains("pv-pic-window-scroll")) { + self.zoomLevel=0; + if (img.naturalHeight && img.naturalHeight < 100) { + let zoomLevel = 100 / img.naturalHeight; + self.zoom(zoomLevel); + } else { + self.zoom(1); + } + } + if (self == uniqueImgWin) { + self.initMaxSize(); + } + if (prefs.imgWindow.fitToScreen) { + self.fitToScreen(); + } + if (self.initPos) { + self.imgWindow.style.left = self.initPos.left; + self.imgWindow.style.top = self.initPos.top; + } else self.center(true, true); + } + } + self.imgWindow.style.opacity = 1; + self.keepScreenInside(); + + var wSize = getWindowSize(); + wSize.h -= 16; + wSize.w -= 16; + self.isLongImg = self.imgNaturalSize.h >= wSize.h && self.imgNaturalSize.h / self.imgNaturalSize.w > 2.5; + } + if (imgNaturalSize.h && imgNaturalSize.w) { + container.style.background=''; + setSearchState(`${img.naturalWidth} x ${img.naturalHeight}`, self.imgState); + } + if (!this.isImg) { + if (/^video$/i.test(img.nodeName)) { + img.naturalHeight = img.videoHeight || 1080; + img.naturalWidth = img.videoWidth || 1920; + } else if (/^audio$/i.test(img.nodeName)) { + img.naturalHeight = 50; + img.naturalWidth = 350; + } + setTimeout(() => { + img.onload(); + }, 0); + } + /*searchButton.addEventListener('click',function(e){ + sortSearch(); + searchImgByImg(self.img.src, self.img.parentNode, function(srcs, index){ + from=index; + self.srcs=srcs; + self.img.src=srcs.shift(); + }); + },false);*/ + + /** + * 说明 + * 1、对原来的适应屏幕等功能会有影响,暂时禁用。 + * 2、分为 absolute 和默认的2种情况 + */ + if (this.data) { + var descriptionSpan = container.querySelector('.pv-pic-window-description'); + let desc = (this.data.description || ''); + if (Array.isArray(this.data.description) && Array.isArray(this.data.all)) { + let curIndex; + for (curIndex = 0; curIndex < this.data.all.length; curIndex++) { + if (this.data.src.indexOf(this.data.all[curIndex].replace(/^(video|audio):/, "")) !== -1) break; + } + desc = desc[curIndex] || desc[0] || ""; + } + descriptionSpan.textContent = desc.trim(); + this.imgStateBox.title = desc; + descriptionSpan.style.display = desc ? "inline" : "none"; + this.descriptionSpan = descriptionSpan; + } + + var toolbar=container.querySelector('.pv-pic-window-toolbar'); + toolbar.style.cssText='\ + top: 0px;\ + left: -42px;\ + '; + this.toolbar=toolbar; + + this.selectedToolClass='pv-pic-window-tb-tool-selected'; + + this.viewRange=container.querySelector('.pv-pic-window-range'); + + this.rotateIndicator=container.querySelector('.pv-pic-window-rotate-indicator'); + this.rotateIPointer=container.querySelector('.pv-pic-window-rotate-indicator-pointer'); + this.rotateOverlayer=container.querySelector('.pv-pic-window-rotate-overlayer'); + + + this.hKeyUp=true; + this.rKeyUp=true; + this.zKeyUp=true; + + this.spaceKeyUp=true; + this.ctrlKeyUp=true; + this.altKeyUp=true; + this.shiftKeyUp=true; + this.moving=false; + + //缩放工具的扩展菜单 + container.querySelector('.pv-pic-window-tb-tool-extend-menu-zoom').addEventListener('click',function(e){ + var target=e.target; + var text=target.title; + var value; + switch(text){ + case '1':{ + value=1; + }break; + case '+0.1':{ + value=self.zoomLevel + 0.1; + }break; + case '-0.1':{ + value=self.zoomLevel - 0.1; + }break; + }; + if(typeof value!='undefined'){ + self.zoom(value,{x:0,y:0}); + }; + },true); + + //旋转工具的扩展菜单 + container.querySelector('.pv-pic-window-tb-tool-extend-menu-rotate').addEventListener('click',function(e){ + var target=e.target; + var text=target.title; + var value; + function convert(deg){ + return deg * Math.PI/180; + }; + + switch(text){ + case '0':{ + value=0; + }break; + case '+90':{ + value=self.rotatedRadians + convert(90); + }break; + case '-90':{ + value=self.rotatedRadians - convert(90); + }break; + }; + + var PI=Math.PI; + if(typeof value!='undefined'){ + if(value>=2*PI){ + value-=2*PI; + }else if(value<0){ + value+=2*PI; + }; + self.rotate(value,true); + }; + },true); + + toolbar.addEventListener('mousedown',function(e){//鼠标按下选择工具 + self.toolbarEventHandler(e); + },false); + + toolbar.addEventListener('click',function(e){ + e.preventDefault(); + e.stopPropagation(); + },false); + + + toolbar.addEventListener('dblclick',function(e){//鼠标双击工具 + self.toolbarEventHandler(e); + },false); + + + //阻止浏览器对图片的默认控制行为 + img.addEventListener('mousedown',function(e){ + e.preventDefault(); + },false); + + let hideToolbarTimer = setTimeout(() => { + if (this !== uniqueImgWin) { + container.classList.add("hideToolbar"); + } + }, 800); + imgbox.addEventListener('mousemove',function(e){ + e.preventDefault(); + clearTimeout(hideToolbarTimer); + container.classList.remove("hideToolbar"); + hideToolbarTimer = setTimeout(() => { + container.classList.add("hideToolbar"); + }, 800); + },false); + imgbox.addEventListener('mouseleave',function(e){ + e.preventDefault(); + clearTimeout(hideToolbarTimer); + container.classList.remove("hideToolbar"); + },false); + + container.addEventListener('mousedown',function(e){//当按下的时,执行平移,缩放,旋转操作 + self.imgWindowEventHandler(e); + },false); + + container.addEventListener('touchstart',function(e){//当按下的时,执行平移,缩放,旋转操作 + self.imgWindowEventHandler(e); + },{ passive: true, capture: false }); + + container.addEventListener('click',function(e){//阻止opera ctrl+点击保存图片 + self.imgWindowEventHandler(e); + },false); + + if(prefs.imgWindow.zoom.mouseWheelZoom){//是否使用鼠标缩放 + addWheelEvent(container,function(e){//滚轮缩放 + if (e.target && (e.target.className == "pv-pic-window-next" || e.target.className == "pv-pic-window-pre")) { + e.preventDefault && e.preventDefault(); + return; + } + self.imgWindowEventHandler(e); + clearTimeout(hideToolbarTimer); + container.classList.remove("hideToolbar"); + hideToolbarTimer = setTimeout(() => { + container.classList.add("hideToolbar"); + }, 800); + },false); + }; + + + + //是否点击图片外部关闭 + if(prefs.imgWindow.overlayer.shown && prefs.imgWindow.close.clickOutside){ + var clickOutside=function(e){ + var target=e.target; + if(!container.contains(target)){ + self.remove(); + document.removeEventListener(prefs.imgWindow.close.clickOutside,clickOutside,true); + }; + }; + this.clickOutside=clickOutside; + document.addEventListener(prefs.imgWindow.close.clickOutside,clickOutside,true); + }; + + //是否双击图片本身关闭 + if(prefs.imgWindow.close.dblClickImgWindow){ + var dblClickImgWindow=function(e){ + var target=e.target; + if(target==container || target==img || target==self.imgState || target==self.rotateOverlayer){ + self.remove(); + e.stopPropagation(); + }; + e.preventDefault(); + }; + container.addEventListener('dblclick',dblClickImgWindow,true); + }; + + + if (!this.preview) { + ImgWindowC.all.push(this); + } + + this._blur=this.blur.bind(this); + this._focusedKeydown=this.focusedKeydown.bind(this); + this._focusedKeyup=this.focusedKeyup.bind(this); + + if(prefs.imgWindow.overlayer.shown){//是否显示覆盖层 + var overlayer=ImgWindowC.overlayer; + if(!overlayer){ + overlayer=document.createElement('span'); + ImgWindowC.overlayer=overlayer; + overlayer.className='pv-pic-window-overlayer'; + }; + overlayer.style.backgroundColor=prefs.imgWindow.overlayer.color; + getBody(document).appendChild(overlayer); + overlayer.style.display='block'; + }; + if(prefs.imgWindow.backgroundColor){ + this.imgWindow.style.backgroundColor=prefs.imgWindow.backgroundColor; + } + + if (gallery && gallery.shown) { + document.documentElement.appendChild(container); + } else { + getBody(document).appendChild(container); + } + + this.rotatedRadians=0;//已经旋转的角度 + this.zoomLevel=0; + this.zoom(1); + this.setToolBadge('zoom',1); + + this.firstOpen(); + this.imgWindow.style.opacity=1; + + //选中默认工具 + this.selectTool(prefs.imgWindow.defaultTool); + }, + geneCompareImg: function(src, percent) { + let parent = document.createElement("div"); + let compareImgCon = document.createElement("div"); + compareImgCon.className = "compareImgCon"; + let compareImg = document.createElement("img"); + let compareSlider = document.createElement("div"); + compareSlider.className = "compareSlider"; + compareSlider.title = "Right mouse to bottom, hold to top"; + compareImgCon.style.width = percent + "%"; + compareSlider.style.left = percent + "%"; + let compareSliderButton = document.createElement("button"); + let self = this; + let upTimer, initLeft; + let mouseMoveHandler = e => { + if (upTimer && Math.abs(initLeft - e.pageX) > 10) { + clearTimeout(upTimer); + upTimer = null; + } + if (compareSliderButton.style.display == "") { + document.removeEventListener("mousemove", mouseMoveHandler); + document.removeEventListener("touchmove", mouseMoveHandler); + return; + } + e = (e.changedTouches) ? e.changedTouches[0] : e; + let a = self.img.getBoundingClientRect(); + let x = e.pageX - a.left; + x = x - window.pageXOffset; + if (x < 0) x = 0; + if (x > a.width) x = a.width; + compareImgCon.style.width = x / a.width * 100 + "%"; + compareSlider.style.left = x / a.width * 100 + "%"; + }; + let beginSlide = e => { + compareSliderButton.style.display = "none"; + initLeft = e.pageX; + clearTimeout(upTimer); + upTimer = setTimeout(() => { + self.compareBox.appendChild(parent); + }, 1000); + document.addEventListener("mousemove", mouseMoveHandler); + document.addEventListener("touchmove", mouseMoveHandler); + e.preventDefault(); + e.stopPropagation(); + let mouseUpHandler = e => { + clearTimeout(upTimer); + compareSliderButton.style.display = ""; + document.removeEventListener("mousemove", mouseMoveHandler); + }; + document.addEventListener("mouseup", mouseUpHandler); + document.addEventListener("touchend", mouseUpHandler); + }; + compareSlider.addEventListener("mousedown", beginSlide); + compareSlider.addEventListener("contextmenu", e => { + self.compareBox.insertBefore(parent, self.compareBox.firstChild); + e.preventDefault(); + e.stopPropagation(); + }); + compareSlider.addEventListener("touchstart", beginSlide); + compareSlider.appendChild(compareSliderButton); + compareImg.src = src; + compareImgCon.appendChild(compareImg); + parent.appendChild(compareImgCon); + parent.appendChild(compareSlider); + return parent; + }, + compare: function(otherSrcs) { + if (!otherSrcs || otherSrcs.length === 0) return; + if (!this.compareBox) { + let compareBox = document.createElement("div"); + compareBox.className = "compareBox"; + this.compareBox = compareBox; + this.img.parentNode.appendChild(compareBox); + this.imgWindow.classList.add("compare"); + } + this.compareBox.innerHTML = createHTML(""); + let self = this, count = 0, compareImgConList = [], targetCompareImg; + otherSrcs.forEach(src => { + count++; + let percent = 100 - count * (100 / (otherSrcs.length + 1)); + let compareImg = self.geneCompareImg(src, percent); + self.compareBox.appendChild(compareImg); + compareImgConList.unshift(compareImg.children[0]); + }); + this.img.addEventListener("mousedown", e => { + targetCompareImg = null; + let percentX = e.offsetX / self.img.clientWidth * 100; + for (let i = 0; i < compareImgConList.length; i++) { + let compareImgCon = compareImgConList[i]; + let compareWidth = parseInt(compareImgCon.style.width); + if (percentX < compareWidth) { + targetCompareImg = compareImgCon; + targetCompareImg.style.opacity = 0; + break; + } + } + if (targetCompareImg == null) { + self.img.style.opacity = 0; + compareImgConList[compareImgConList.length - 1].style.overflow = "visible"; + } + }); + this.img.addEventListener("mouseup", e => { + if (targetCompareImg) { + targetCompareImg.style.opacity = ""; + } else { + self.img.style.opacity = ""; + compareImgConList[compareImgConList.length - 1].style.overflow = ""; + } + }); + this.preButton.style.display = "none"; + this.nextButton.style.display = "none"; + }, + switchImage:async function(fw){ + if (this.data && this.data.all && this.data.all.length > 1) { + let initPos = prefs.imgWindow.switchStoreLoc ? {left: this.imgWindow.style.left, top: this.imgWindow.style.top} : false; + this.remove(); + let imgData = this.data; + let curIndex; + for (curIndex = 0; curIndex < this.data.all.length; curIndex++) { + if (this.data.src.indexOf(this.data.all[curIndex].replace(/^(video|audio):/, "")) !== -1) break; + } + if (fw) { + curIndex++; + if (curIndex == this.data.all.length) curIndex = 0; + } else { + curIndex--; + if (curIndex == -1) curIndex = this.data.all.length - 1; + } + imgData.xhr = null; + imgData.src = this.data.all[curIndex]; + let openType = "actual"; + if (uniqueImgWin && uniqueImgWin == this) { + uniqueImgWin = null; + openType = "popup"; + } + new LoadingAnimC(imgData, openType, false, true, initPos); + return; + } + if (!gallery) { + gallery = new GalleryC(); + gallery.data = []; + } + if (gallery.shown || gallery.minimized) { + return; + } + var allData = await gallery.getAllValidImgs(false, true); + if (allData.length <= 1) return; + const validData = (data, src) => { + if (!data || !data.img || !data.img.parentNode) return false; + if (data.img.parentNode.classList.contains("pv-pic-window-container")) return false; + if (data.src == src) return false; + if (data.src && /^data:/.test(data.src) && data.src.length < 250) return false; + return true; + }; + if (this.data.img) { + for (let i = 0; i < allData.length; i++) { + let imgData = allData[i]; + if (imgData.img == this.data.img) { + if (fw) { + if (i != allData.length - 1) { + i++; + imgData = allData[i]; + while (!validData(imgData, this.data.src)) { + i++; + if (i == allData.length) return; + imgData = allData[i]; + } + if (imgData && imgData.img) { + let initPos = prefs.imgWindow.switchStoreLoc ? {left: this.imgWindow.style.left, top: this.imgWindow.style.top} : false; + this.remove(); + new LoadingAnimC(imgData, (this.actual ? "actual" : "current"), false, true, initPos); + } + } + } else { + if (i != 0) { + i--; + imgData = allData[i]; + while (!validData(imgData, this.data.src)) { + i--; + if (i == -1) return; + imgData = allData[i]; + } + if (imgData) { + let initPos = prefs.imgWindow.switchStoreLoc ? {left: this.imgWindow.style.left, top: this.imgWindow.style.top} : false; + this.remove(); + new LoadingAnimC(imgData, (this.actual ? "actual" : "current"), false, true, initPos); + } + } + } + return; + } + } + if (this.data.img.src) { + for (let i = 0; i < allData.length; i++) { + let imgData = allData[i]; + if (imgData.img && imgData.img.src == this.data.img.src) { + if (fw) { + if (i != allData.length - 1) { + i++; + imgData = allData[i]; + while (!validData(imgData, this.data.src)) { + i++; + if (i == allData.length) return; + imgData = allData[i]; + } + if (imgData && imgData.img) { + let initPos = prefs.imgWindow.switchStoreLoc ? {left: this.imgWindow.style.left, top: this.imgWindow.style.top} : false; + this.remove(); + new LoadingAnimC(imgData, (this.actual ? "actual" : "current"), false, true, initPos); + } + } + } else { + if (i != 0) { + i--; + imgData = allData[i]; + while (!validData(imgData, this.data.src)) { + i--; + if (i == -1) return; + imgData = allData[i]; + } + if (imgData) { + let initPos = prefs.imgWindow.switchStoreLoc ? {left: this.imgWindow.style.left, top: this.imgWindow.style.top} : false; + this.remove(); + new LoadingAnimC(imgData, (this.actual ? "actual" : "current"), false, true, initPos); + } + } + } + return; + } + } + } + } + }, + changeData:function(result){ + if(this.src != result.src){ + this.loaded = false; + this.data = result; + this.src = result.src; + this.img.src = location.protocol == "https"?result.src.replace(/^https?:/,""):result.src; + } + }, + addStyle:function(){ + if (ImgWindowC.style) { + if (!ImgWindowC.style.parentNode) { + ImgWindowC.style = _GM_addStyle(ImgWindowC.style.innerText); + } + return; + } + ImgWindowC.style=_GM_addStyle('\ + .pv-pic-window-container {\ + ' + (prefs.imgWindow.fixed ? 'position: fixed;' : 'position: absolute;') + '\ + background-image: initial;\ + padding: 0;\ + border: 3px solid rgb(255 255 255 / 50%);\ + border-radius: 1px;\ + line-height: 0;\ + text-align: left;\ + box-sizing: content-box;\ + -webkit-transition: opacity 0.2s ease-out;\ + transition: opacity 0.1s ease-out;\ + overscroll-behavior: none;\ + box-shadow: 0 0 6px 2px rgba(0,0,0,0.35);\ + box-sizing: content-box;\ + display: initial;\ + background: #00000080;\ + }\ + .pv-pic-window-container span {\ + background-image: initial;\ + float: initial;\ + }\ + .pv-pic-window-transition-all{\ + -webkit-transition: top 0.2s ease, left 0.2s ease;\ + transition: top 0.2s ease, left 0.2s ease;\ + }\ + .pv-pic-window-imgbox {\ + position: relative;\ + display: block;\ + overflow: hidden;\ + background-color: rgba(40, 40, 40, 0.65);\ + }\ + .pv-pic-window-container .compareBox {\ + position: absolute;\ + top: 0;\ + left: 0;\ + width: 100%;\ + height: 100%;\ + pointer-events: none;\ + }\ + .pv-pic-window-container .compareBox>div {\ + width: 100%;\ + height: 100%;\ + position: absolute;\ + }\ + .pv-pic-window-container .compareBox>div>.compareImgCon {\ + width: 100%;\ + max-width: 100%;\ + height: 100%;\ + overflow: hidden;\ + }\ + .pv-pic-window-container .compareBox>div>.compareImgCon>img {\ + width: auto;\ + height: 100%;\ + max-width: unset;\ + }\ + .pv-pic-window-container .compareBox>div>.compareSlider {\ + position: absolute;\ + top: 0;\ + bottom: 0;\ + width: 2px;\ + background-color: rgba(255,255,255,.5);\ + border-top: 0;\ + border-bottom: 0;\ + box-shadow: 0 0 2px rgba(0,0,0,.5);\ + overflow: visible;\ + z-index: 9;\ + }\ + .pv-pic-window-container .compareBox>div>.compareSlider>button {\ + position: absolute;\ + top: calc(50% - 40px);\ + left: -4px;\ + width: 10px;\ + background-color: #ddd;\ + border: 4px solid #fff;\ + height: 80px;\ + text-align: center;\ + padding: 0;\ + outline: 0;\ + cursor: ew-resize;\ + box-shadow: 0 0 2px rgba(0,0,0,.5);\ + pointer-events: all;\ + box-sizing: border-box;\ + background-image: none;\ + }\ + .pv-pic-window-container .compareBox>div>.compareSlider>button:hover {\ + background-color: #777;\ + }\ + .pv-pic-window-close,\ + .pv-pic-window-max,\ + .pv-pic-window-search,\ + .pv-pic-window-toolbar,\ + .pv-pic-window-tb-tool-extend-menu{\ + -webkit-transition: opacity 0.2s ease-in-out;\ + transition: opacity 0.2s ease-in-out;\ + box-sizing: content-box;\ + }\ + .pv-pic-window-toolbar {\ + position: absolute;\ + background-color: #535353;\ + padding: 0;\ + opacity: 0.5;\ + display: none;\ + cursor: default;\ + -o-user-select: none;\ + -webkit-user-select: none;\ + -moz-user-select: -moz-none;\ + user-select: none;\ + }\ + .pv-pic-window-container_focus:not(.preview)>.pv-pic-window-toolbar {\ + display: block;\ + }\ + .pv-pic-window-toolbar:hover,\ + .pv-pic-window-container>.pv-pic-window-toolbar.insert:hover{\ + opacity: 1;\ + }\ + span.pv-pic-window-close {\ + cursor: pointer;\ + position: absolute;\ + right: 0px;\ + top: -22px;\ + background: url("'+prefs.icons.close+'") no-repeat center bottom;\ + height: 17px;\ + width: 46px;\ + opacity: 0.5;\ + border:none;\ + padding:0;\ + padding-top:2px!important;\ + background-color:#1771FF;\ + display: none;\ + z-index: 2;\ + }\ + .pv-pic-window-container_focus:not(.preview)>.pv-pic-window-close {\ + display: block;\ + }\ + span.pv-pic-window-search {\ + cursor: pointer;\ + position: absolute;\ + right: 50px;\ + top: -22px;\ + background: url("'+prefs.icons.searchBtn+'") no-repeat center bottom;\ + height: 17px;\ + width: 46px;\ + opacity: 0.9;\ + border:none;\ + padding:0;\ + padding-top:2px;\ + background-color:#1771FF;\ + display: none;\ + }\ + span.pv-pic-window-max {\ + cursor: pointer;\ + position: absolute;\ + right: 46px;\ + top: -22px;\ + background: url("'+prefs.icons.maxBtn+'") no-repeat center bottom;\ + height: 17px;\ + width: 46px;\ + opacity: 0.5;\ + border:none;\ + border-right: 1px solid #868686;\ + padding:0;\ + padding-top:2px!important;\ + background-color:#1771FF;\ + display: none;\ + z-index: 2;\ + }\ + .pv-pic-window-container>.pv-pic-window-max:hover,\ + .pv-pic-window-container>.pv-pic-window-close:hover,\ + .pv-pic-window-container>.pv-pic-window-max.insert:hover,\ + .pv-pic-window-container>.pv-pic-window-close.insert:hover {\ + background-color:red;\ + opacity: 1!important;\ + }\ + .pv-pic-window-container_focus:not(.preview)>.pv-pic-window-max {\ + display: block;\ + }\ + .pv-pic-window-search:hover {\ + background-color:red;\ + opacity: 1;\ + }\ + .pv-pic-window-container_focus:not(.preview)>.pv-pic-window-search {\ + display: block;\ + }\ + .pv-pic-window-description {\ + display: none;\ + background: yellow;\ + margin: 0 -5px 0 15px!important;\ + padding: 3px!important;\ + color: black;\ + text-shadow: 0 0 1px #00000099;\ + }\ + .pv-pic-window-description::before {\ + display: inline-block;\ + content:"";\ + position: absolute;\ + border: 10px solid transparent;\ + margin-left: -22px;\ + top: -1px;\ + border-right-color: yellow;\ + }\ + span.pv-pic-window-pre,\ + span.pv-pic-window-next{\ + -webkit-transition: opacity 0.3s ease;\ + transition: opacity 0.3s ease;\ + position: absolute;\ + height: 100px;\ + top: calc(50% - 50px);\ + width: 36px;\ + background: #ffffff60 no-repeat center;\ + opacity: 0;\ + cursor: pointer;\ + pointer-events: none;\ + }\ + span.pv-pic-window-pre {\ + left: 0;\ + background-image: url("'+prefs.icons.arrowLeft+'");\ + }\ + span.pv-pic-window-next {\ + right: 0;\ + background-image: url("'+prefs.icons.arrowRight+'");\ + }\ + .compare>.pv-pic-search-state{\ + display: none;\ + }\ + .pv-pic-window-container_focus>.pv-pic-search-state,.preview>.pv-pic-search-state {\ + opacity:0.8;\ + }\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-imgbox{\ + cursor: none;\ + }\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-search-state,\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-toolbar,\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-max,\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-close,\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-pre,\ + .pv-pic-window-container_focus.hideToolbar>.pv-pic-window-next{\ + opacity:0!important;\ + }\ + .pv-pic-window-container_focus:not(.preview) .pv-pic-window-imgbox:hover~.pv-pic-window-pre,\ + .pv-pic-window-container_focus:not(.preview) .pv-pic-window-imgbox:hover~.pv-pic-window-next{\ + opacity:0.3;\ + pointer-events: all;\ + }\ + .pv-pic-window-container>.pv-pic-window-pre:hover,\ + .pv-pic-window-container>.pv-pic-window-next:hover{\ + opacity:1;\ + pointer-events: all;\ + }\ + .pv-pic-window-container_focus:hover>.pv-pic-search-state{\ + border-radius: 0 0 8px 0;\ + top: 0px;\ + pointer-events: all;\ + }\ + .pv-pic-window-container>.pv-pic-window-pre:hover~span.pv-pic-search-state,\ + .pv-pic-window-container>.pv-pic-window-next:hover~span.pv-pic-search-state{\ + opacity:0;\ + }\ + .pv-pic-window-container>span.pv-pic-search-state:hover{\ + overflow:visible;\ + background:none;\ + box-shadow:none;\ + opacity: 1;\ + height: 30px;\ + }\ + .pv-pic-window-container>span.pv-pic-search-state:hover>span{\ + opacity: 0;\ + }\ + .pv-pic-window-container>span.pv-pic-search-state:hover>svg{\ + display: block;\ + }\ + span.pv-pic-search-state {\ + top: -21px;\ + left: 0px;\ + display: block;\ + position: absolute;\ + z-index: 1;\ + color: #ffff00;\ + height: 18px;\ + line-height: 18px;\ + opacity:0;\ + transition: all 0.3s ease;\ + user-select: none;\ + -webkit-box-sizing: content-box;\ + box-sizing: content-box;\ + border-radius: 1px;\ + background: rgb(0 0 0 / 75%);\ + box-shadow: rgb(221, 221, 221) 0px 0px 1px inset;\ + max-width: 100%;\ + overflow: hidden;\ + font: 13px / 1.4em Roboto,arial,sans-serif,微软雅黑,"Noto Sans SC";\ + pointer-events: none;\ + }\ + .pv-pic-search-state>span {\ + pointer-events: none;\ + padding: 1px 5px!important;\ + white-space: nowrap;\ + overflow: hidden;\ + }\ + .pv-pic-search-state>span>b {\ + background: yellow;\ + color: black;\ + margin-right: -5px;\ + padding: 3px;\ + }\ + .pv-pic-search-state>span>strong {\ + background: inherit;\ + color: #ffffff;\ + }\ + span.pv-pic-search-state>.pv-icon {\ + width: 20px;\ + height: 20px;\ + vertical-align: middle;\ + fill: currentColor;\ + overflow: hidden;\ + position: absolute;\ + left: 1px;\ + top: 1px;\ + background: black;\ + border-radius: 15px;\ + padding: 5px;\ + color: white;\ + cursor: pointer;\ + display: none;\ + box-sizing: content-box;\ + transition: all 0.3s ease;\ + }\ + .pv-pic-search-state>.pv-icon:hover {\ + color: #ffff00;\ + }\ + .pv-pic-search-state>.pv-icon * {\ + pointer-events: none;\ + }\ + .pv-pic-window-scrollSign {\ + display: none;\ + width: 100px;\ + height: auto;\ + fill: black;\ + top: 10px;\ + right: 0px;\ + position: absolute;\ + opacity: 0;\ + -webkit-animation: scroll_sign_opacity 2s 3 ease-in-out;\ + animation: scroll_sign_opacity 2s 3 ease-in-out;\ + }\ + @-webkit-keyframes scroll_sign_opacity {\ + 0% { opacity: 0 }\ + 50% { opacity: 1 }\ + 100% { opacity: 0 }\ + }\ + @keyframes scroll_sign_opacity {\ + 0% { opacity: 0 }\ + 50% { opacity: 1 }\ + 100% { opacity: 0 }\ + }\ + .pv-pic-window-scroll {\ + max-height: calc(100vh - 2px);\ + max-width: 100vw;\ + }\ + .pv-pic-window-scroll>.pv-pic-window-imgbox {\ + max-height: calc(100vh - 2px);\ + max-width: 100vw;\ + overflow-y: scroll;\ + overflow-x: hidden;\ + overscroll-behavior: contain;\ + -ms-scroll-chaining: contain;\ + scrollbar-color: initial;\ + }\ + .pv-pic-window-scroll>.pv-pic-window-scrollSign {\ + display: block;\ + }\ + .pv-pic-window-scroll>.pv-pic-window-close,\ + .pv-pic-window-scroll>.pv-pic-window-max {\ + display: none;\ + }\ + .pv-pic-window-black>.pv-pic-window-imgbox>img {\ + background: black!important;\ + }\ + .pv-pic-window-white>.pv-pic-window-imgbox>img {\ + background: white!important;\ + }\ + .transition-transform{\ + transition: transform 0.3s ease;\ + }\ + .transition-all{\ + transition: all 0.3s ease;\ + }\ + .pv-pic-window-pic {\ + position: relative;\ + display:inline-block;\/*opera把图片设置display:block会出现渲染问题,会有残影,还会引发其他各种问题,吓尿*/\ + max-width:unset;\ + min-width:unset;\ + max-height:unset;\ + min-height:unset;\ + width:inherit;\ + height:inherit;\ + padding:0;\ + margin:0;\ + border:none;\ + vertical-align:middle;\ + }\ + .pv-pic-window-container.preview {\ + pointer-events: none;\ + }\ + .pv-pic-window-container_focus:not(.preview) .pv-pic-window-imgbox {\ + box-shadow: 0 0 6px black;\ + }\ + span.pv-pic-window-container_focus:not(.preview) .pv-pic-window-pic {\ + background: linear-gradient( 45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 75%, rgba(255, 255, 255, 0.4) 75%, rgba(255, 255, 255, 0.4) 100% ), linear-gradient( 45deg, rgba(255, 255, 255, 0.4) 25%, transparent 25%, transparent 75%, rgba(255, 255, 255, 0.4) 75%, rgba(255, 255, 255, 0.4) 100% );\ + background-size: 20px 20px;\ + background-position: 0 0, 10px 10px;\ + }\ + span.pv-pic-window-tb-tool,\ + span.pv-pic-window-tb-command{\ + box-sizing:content-box;\ + -moz-box-sizing:content-box;\ + -webkit-box-sizing:content-box;\ + height: 24px;\ + width: 24px;\ + padding: 12px 8px 6px 6px!important;\ + margin:0;\ + display: block;\ + background: transparent no-repeat center;\ + cursor: pointer;\ + position: relative;\ + border: none;\ + border-left: 2px solid transparent;\ + border-bottom: 1px solid #868686;\ + background-origin: content-box;\ + }\ + .pv-pic-window-toolbar > span:last-child {\ + border-bottom: none;\ + }\ + .pv-pic-window-tb-tool:hover,\ + .pv-pic-window-tb-command:hover{\ + border-left: 2px solid red;\ + }\ + .pv-pic-window-tb-tool-selected{\ + box-shadow: inset 0 21px 0 rgba(255,255,255,0.3) ,inset 0 -21px 0 rgba(0,0,0,0.3);\ + border-left:2px solid #1771FF;\ + }\ + .pv-pic-window-toolbar span.pv-pic-window-tb-hand {\ + background-image: url("'+prefs.icons.hand+'")!important;\ + }\ + .pv-pic-window-toolbar span.pv-pic-window-tb-rotate {\ + background-image: url("'+prefs.icons.rotate+'")!important;\ + }\ + .pv-pic-window-toolbar span.pv-pic-window-tb-zoom {\ + background-image: url("'+prefs.icons.zoom+'")!important;\ + }\ + .pv-pic-window-toolbar span.pv-pic-window-tb-flip-horizontal {\ + background-image: url("'+prefs.icons.flipHorizontal+'")!important;\ + }\ + .pv-pic-window-toolbar span.pv-pic-window-tb-flip-vertical {\ + background-image: url("'+prefs.icons.flipVertical+'")!important;\ + }\ + .pv-pic-window-toolbar span.pv-pic-window-tb-compare {\ + background-image: url("'+prefs.icons.compare+'")!important;\ + }\ + .pv-pic-window-tb-tool-badge-container {\ + display: block;\ + position: relative;\ + }\ + span.pv-pic-window-tb-tool-badge {\ + position: absolute;\ + top: -3px;\ + right: 1px;\ + font-size: 10px;\ + line-height: 1.5;\ + padding: 0 3px;\ + background-color: #F93;\ + border-radius: 50px;\ + opacity: 0.5;\ + color: black;\ + }\ + span.pv-pic-window-tb-tool-extend-menu{\ + position:absolute;\ + top:0;\ + margin-left:-1px;\ + background-color:#535353;\ + display:none;\ + left:40px;\ + color:#C3C3C3;\ + font-size:12px;\ + text-shadow:0px -1px 0px black;\ + opacity:0.7;\ + }\ + .pv-pic-window-tb-tool-extend-menu:hover{\ + opacity:0.9;\ + }\ + .pv-pic-window-tb-tool-extend-menu-item{\ + display:block;\ + line-height:1.5;\ + text-align:center;\ + padding:10px!important;\ + cursor:pointer;\ + border: none;\ + border-right: 2px solid transparent;\ + border-bottom: 1px solid #868686;\ + font-size: 20px;\ + }\ + .pv-pic-window-tb-tool-extend-menu-item>svg{\ + pointer-events: none;\ + }\ + .pv-pic-window-tb-tool-extend-menu-item:last-child{\ + border-bottom: none;\ + }\ + .pv-pic-window-tb-tool-extend-menu-item:hover{\ + border-right:2px solid red;\ + }\ + .pv-pic-window-tb-tool-extend-menu-item:active{\ + padding:11px 9px 9px 11px;\ + }\ + .pv-pic-window-tb-tool-extend-menu-container:hover .pv-pic-window-tb-tool{\ + border-left:2px solid red;\ + }\ + .pv-pic-window-tb-tool-extend-menu-container:hover .pv-pic-window-tb-tool-extend-menu{\ + display:block;\ + }\ + .pv-pic-window-tb-tool-extend-menu-container::after{\ + content:"";\ + position:absolute;\ + right:1px;\ + bottom:2px;\ + width:0;\ + height:0;\ + padding:0;\ + margin:0;\ + border:3px solid #C3C3C3;\ + border-top-color:transparent;\ + border-left-color:transparent;\ + opacity:0.5;\ + }\ + .pv-pic-window-overlayer{\ + height:100%;\ + width:100%;\ + position:fixed;\ + top:0;\ + left:0;\ + z-index: '+prefs.imgWindow.zIndex+';\ + }\ + span.pv-pic-window-rotate-indicator{\ + display:none;\ + position:fixed;\ + width:250px;\ + height:250px;\ + padding:10px;\ + margin-top:-135px;\ + margin-left:-135px;\ + background:transparent url("'+ prefs.icons.rotateIndicatorBG +'") no-repeat center;\ + }\ + span.pv-pic-window-rotate-indicator-pointer{\ + display:block;\ + margin-left:auto;\ + margin-right:auto;\ + background:transparent url("'+ prefs.icons.rotateIndicatorPointer +'") no-repeat center;\ + width:60px;\ + height:240px;\ + position:relative;\ + top:5px;\ + transform:rotate(0.1deg);\ + }\ + .pv-pic-window-rotate-overlayer{/*当切换到旋转工具的时候显示这个覆盖层,然后旋转指示器显示在这个覆盖层的下面*/\ + position:absolute;\ + top:0;\ + bottom:0;\ + left:0;\ + right:0;\ + display:none;\ + background-color:transparent;\ + }\ + .pv-pic-window-range{\ + position:absolute;\ + border:none;\ + width:100px;\ + height:100px;\ + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.8);\ + display:none;\ + padding:0;\ + background-color:rgba(255, 0, 0, 0.150);\ + }\ + .pv-pic-window-container::-webkit-scrollbar, .pv-pic-window-container>.pv-pic-window-imgbox::-webkit-scrollbar { width: 0 !important }\ + .pv-pic-window-container, .pv-pic-window-container>.pv-pic-window-imgbox { -ms-overflow-style: none;overflow: -moz-scrollbars-none; }\ + '); + }, + + firstOpen:function(){ + ImgWindowC.selectedTool='hand'; + this.removed = false; + this.imgWindow.classList.remove("pv-pic-window-scroll"); + this.focus(); + var imgWindow=this.imgWindow; + var scrolled=prefs.imgWindow.fixed ? {x:0, y:0} : getScrolled(); + imgWindow.style.left=-5 + scrolled.x + 'px'; + imgWindow.style.top=-5 + scrolled.y + 'px'; + + //window的尺寸 + var wSize=getWindowSize(); + //空隙 + wSize.h -= 16; + wSize.w -= 16; + + var imgWindowCS=unsafeWindow.getComputedStyle(imgWindow); + var rectSize={ + h:parseFloat(imgWindowCS.height), + w:parseFloat(imgWindowCS.width), + }; + this.isLongImg=rectSize.h > wSize.h && rectSize.h/rectSize.w > 2.5; + if(prefs.imgWindow.suitLongImg && this.isLongImg){ + if(prefs.imgWindow.fitToScreen){ + this.fitToScreenWidth(); + } + this.center(rectSize.w <= wSize.w,false); + this.imgWindow.classList.add("pv-pic-window-scroll"); + }else if(prefs.imgWindow.fitToScreen){ + this.fitToScreen(); + this.center(true,true); + }else{ + this.center(rectSize.w <= wSize.w , rectSize.h <= wSize.h); + } + if (this.initPos) { + this.imgWindow.style.left = this.initPos.left; + this.imgWindow.style.top = this.initPos.top; + } + + this.keepScreenInside(); + }, + keepScreenInside:function(){//保持按钮在屏幕里面. + var imgWindow=this.imgWindow; + var imgWindowFullSize={ + h:imgWindow.offsetHeight, + w:imgWindow.offsetWidth, + }; + + var windowSize=getWindowSize(); + + function keepSI(obj,offsetDirection,defaultValue, out){ + var objRect=obj.getBoundingClientRect(); + var objStyle=obj.style; + var insert=false; + + while(offsetDirection.length){ + var oD=offsetDirection[0]; + var oDV=defaultValue[0]; + var outV=0; + if(out)outV=out.shift(); + offsetDirection.shift(); + defaultValue.shift(); + var oValue=parseFloat(objStyle[oD]); + var newValue; + switch(oD){ + case 'top': + newValue=oValue - objRect.top - outV; + if(objRect.top-outV<=0){ + newValue=Math.min(newValue,imgWindowFullSize.h); + }else{ + newValue=Math.max(newValue,oDV); + }; + break; + case 'right': + newValue=oValue + (objRect.right - windowSize.w) + outV; + if(objRect.right+outV >= windowSize.w){//屏幕外 + newValue=Math.min(newValue,imgWindowFullSize.w); + }else{ + newValue=Math.max(newValue,oDV); + }; + break; + case 'bottom': + newValue=oValue + (objRect.bottom - windowSize.h) + outV; + if(objRect.bottom+outV >= windowSize.h){//屏幕外 + newValue=Math.min(newValue,imgWindowFullSize.h); + }else{ + newValue=Math.max(newValue,oDV); + }; + break; + case 'left': + newValue=oValue - objRect.left - outV; + if(objRect.left-outV<=0){ + newValue=Math.min(newValue,imgWindowFullSize.w); + }else{ + newValue=Math.max(newValue,oDV); + } + break; + } + insert=insert||newValue!==oDV; + objStyle[oD]=newValue + 'px'; + } + insert ? obj.classList.add("insert") : obj.classList.remove("insert"); + } + + keepSI(this.closeButton,['top','right'],[-22,0]); + keepSI(this.maxButton,['top','right'],[-22,46],[0,46]); + //keepSI(this.searchButton,['top','right'],[-22,50]); + keepSI(this.toolbar,['top','left'],[0,-42]); + + // 保持注释在图片里面 + //keepSI(this.descriptionSpan,['bottom', 'left'],[-40, 10]); + }, + initMaxSize: function() { + let wSize = getWindowSize(); + let maxWidth = wSize.w - 50, maxHeight = wSize.h - 50, left, top; + if (prefs.floatBar.previewMaxSizeW && maxWidth > prefs.floatBar.previewMaxSizeW) { + maxWidth = prefs.floatBar.previewMaxSizeW; + } + if (prefs.floatBar.previewMaxSizeW && maxHeight > prefs.floatBar.previewMaxSizeH) { + maxHeight = prefs.floatBar.previewMaxSizeH; + } + if (this.zoomLevel === 1) { + this.zoomLevel = 0; + this.zoom(1); + } + + let imgWindowCS = unsafeWindow.getComputedStyle(this.imgWindow); + let rectSize = { + h: parseFloat(imgWindowCS.height), + w: parseFloat(imgWindowCS.width), + }; + + let size, containsScroll = this.imgWindow.classList.contains("pv-pic-window-scroll"); + + if (prefs.imgWindow.fitToScreenSmall || rectSize.w > maxWidth || rectSize.h > maxHeight) { + if (rectSize.w / rectSize.h > maxWidth / maxHeight) { + size = { + w: maxWidth, + h: maxWidth / (rectSize.w / rectSize.h), + }; + } else if (!containsScroll) { + size = { + h: maxHeight, + w: maxHeight * (rectSize.w / rectSize.h), + } + }; + + let cs = this.getRotatedImgCliSize(size); + let ns = this.imgNaturalSize; + if (cs && ns && cs.w && ns.w) { + this.zoom(cs.w / ns.w); + } + } + }, + followPos: function(posX, posY, imme) { + if (this.removed) return; + if (!prefs.floatBar.globalkeys.previewFollowMouse) return; + let imgWindow = this.imgWindow; + if (!imgWindow) return; + this.followPosX = posX; + this.followPosY = posY; + if (!imme && this.following) return; + let wSize = getWindowSize(); + + let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2, (this.img.naturalWidth || 500)>>1, (this.img.naturalHeight || 500)>>1), padding2 = 50, left, top;//内外侧间距 + imgWindow.style.position = "fixed"; + let scrolled = {x: 0, y: 0}; + + this.initMaxSize(); + + if (imgWindow.offsetWidth / imgWindow.offsetHeight > wSize.w / wSize.h) { + //宽条,上下半屏 + if (posY > wSize.h / 2) { + //上 + top = posY - imgWindow.offsetHeight - padding1 + scrolled.y; + if (top < padding2>>1) top = padding2>>1; + } else { + //下 + top = posY + padding1 + scrolled.y; + if (top > wSize.h - imgWindow.offsetHeight - 1) top = wSize.h - imgWindow.offsetHeight - 1; + } + left = (wSize.w - imgWindow.offsetWidth) / 2; + let maxLeft = posX + padding1; + if (left > maxLeft) left = maxLeft; + else { + let minLeft = posX - imgWindow.offsetWidth - padding1; + if (left < minLeft) left = minLeft; + } + left = left + scrolled.x; + } else { + //窄条,左右半屏 + if (posX > wSize.w / 2) { + //左 + left = posX - imgWindow.offsetWidth - padding1 + scrolled.x; + if (left < 1) left = 1; + } else { + //右 + left = posX + padding1 + scrolled.x; + if (left > wSize.w - imgWindow.offsetWidth - 1) left = wSize.w - imgWindow.offsetWidth - 1; + } + top = (wSize.h - imgWindow.offsetHeight) / 2; + let maxTop = posY + padding1; + if (top > maxTop) top = maxTop; + else { + let minTop = posY - imgWindow.offsetHeight - padding1; + if (top < minTop) top = minTop; + } + top = top + scrolled.y; + } + + clearTimeout(this.followPosTimer); + if (imme || !this.loaded) { + imgWindow.classList.remove("pv-pic-window-transition-all"); + this.following = false; + } else { + if (Math.abs(left - parseInt(imgWindow.style.left)) + Math.abs(top - parseInt(imgWindow.style.top)) > 50) { + this.following = true; + imgWindow.classList.add("pv-pic-window-transition-all"); + this.followPosTimer = setTimeout(() => { + this.following = false; + this.followPos(this.followPosX, this.followPosY); + imgWindow.classList.add("pv-pic-window-transition-all"); + }, 250); + } else { + imgWindow.classList.remove("pv-pic-window-transition-all"); + } + } + imgWindow.style.left = left + 'px'; + imgWindow.style.top = top + 'px'; + }, + fitToScreen:function(){ + let imgWindow = this.imgWindow; + if (!prefs.imgWindow.fitToScreen) return; + let wSize=getWindowSize(); + //空隙 + wSize.h -= 6; + wSize.w -= 6; + + let imgWindowCS = unsafeWindow.getComputedStyle(imgWindow); + let rectSize = { + h: parseFloat(imgWindowCS.height), + w: parseFloat(imgWindowCS.width), + }; + + let size = rectSize, containsScroll = imgWindow.classList.contains("pv-pic-window-scroll"); + if (prefs.imgWindow.fitToScreenSmall || rectSize.w - wSize.w > 0 || rectSize.h - wSize.h > 0) {//超出屏幕,那么缩小。 + if (rectSize.w / rectSize.h > wSize.w / wSize.h) { + size = { + w: wSize.w, + h: wSize.w / (rectSize.w / rectSize.h), + }; + } else if (!containsScroll) { + size = { + h: wSize.h, + w: wSize.h * (rectSize.w / rectSize.h), + } + }; + + let cs = this.getRotatedImgCliSize(size); + let ns = this.imgNaturalSize; + if (cs && ns && cs.w && ns.w) { + this.zoom(cs.w / ns.w); + } + }; + }, + fitToScreenWidth:function(){ + let imgWindow = this.imgWindow; + if (!prefs.imgWindow.fitToScreen) return; + let wSize=getWindowSize(); + wSize.h -= 6; + wSize.w -= 6; + + let imgWindowCS = unsafeWindow.getComputedStyle(imgWindow); + let rectSize = { + h: parseFloat(imgWindowCS.height), + w: parseFloat(imgWindowCS.width), + }; + + let size = rectSize, containsScroll = imgWindow.classList.contains("pv-pic-window-scroll"); + if (rectSize.w > wSize.w) { + if (rectSize.w / rectSize.h > wSize.w / wSize.h) { + size = { + w: wSize.w, + h: wSize.w / (rectSize.w / rectSize.h), + }; + } + + let cs = this.getRotatedImgCliSize(size); + let ns = this.imgNaturalSize; + if (cs && ns && cs.w && ns.w) { + this.zoom(cs.w / ns.w); + } + }; + }, + center:function(horizontal,vertical){ + if(!horizontal && !vertical)return; + var imgWindow=this.imgWindow; + if(!imgWindow)return; + var wSize=getWindowSize(); + var scrolled=prefs.imgWindow.fixed ? {x:0, y:0} : getScrolled(); + if(horizontal)imgWindow.style.left = (wSize.w - imgWindow.offsetWidth)/2 + scrolled.x +'px'; + if(vertical)imgWindow.style.top = (wSize.h - imgWindow.offsetHeight)/2 + scrolled.y +'px'; + }, + + + move:function(e){ + this.working=true; + var cursor=this.cursor; + this.changeCursor('handing'); + + var mouseCoor={ + x:e.pageX || e.touches[0].pageX, + y:e.pageY || e.touches[0].pageY, + }; + var imgWindow=this.imgWindow; + var imgWStyle=imgWindow.style; + var oriOffset={ + left:parseFloat(imgWStyle.left), + top:parseFloat(imgWStyle.top), + }; + var self=this; + var moveHandler=function(e){ + imgWStyle.left=oriOffset.left+ (e.pageX || e.touches[0].pageX)-mouseCoor.x +'px'; + imgWStyle.top=oriOffset.top + (e.pageY || e.touches[0].pageY)-mouseCoor.y +'px'; + self.keepScreenInside(); + self.moving=true; + e.preventDefault(); + e.stopPropagation(); + }; + var mouseupHandler=function(){ + e.preventDefault(); + self.changeCursor(cursor); + self.working=false; + if(self.tempHand && self.spaceKeyUp){//如果是临时切换到抓手工具,平移完成后返回上个工具 + self.tempHand=false; + self.changeCursor(self.selectedTool); + }; + document.removeEventListener('mousemove',moveHandler,true); + document.removeEventListener('mouseup',mouseupHandler,true); + document.removeEventListener('touchmove',moveHandler,true); + document.removeEventListener('touchend',mouseupHandler,true); + }; + document.addEventListener('mousemove',moveHandler,true); + document.addEventListener('mouseup',mouseupHandler,true); + document.addEventListener('touchmove',moveHandler,true); + document.addEventListener('touchend',mouseupHandler,true); + }, + rotate:function(origin,topLeft){ + + var img=this.img; + var imgWindow=this.imgWindow; + imgWindow.classList.remove("pv-pic-window-scroll"); + + var iTransform=img.style[support.cssTransform].replace(/rotate\([^)]*\)/i,''); + + var imgWindowCS=unsafeWindow.getComputedStyle(imgWindow); + var imgRectSize={ + h:parseFloat(imgWindowCS.height), + w:parseFloat(imgWindowCS.width), + }; + + var rectOffset={ + top:parseFloat(imgWindow.style.top), + left:parseFloat(imgWindow.style.left), + }; + + var imgSize={ + h:img.clientHeight, + w:img.clientWidth, + }; + + var imgOffset={ + top:parseFloat(img.parentNode.style.top), + left:parseFloat(img.parentNode.style.left), + }; + + var self=this; + var PI=Math.PI; + + var rotate = function (radians) { + if (self.rotatedRadians == radians) return; + if (self.working) { + img.parentNode.style[support.cssTransform] = ' rotate(' + radians + 'rad) ' + iTransform; + } else { + img.parentNode.classList.remove("transition-transform"); + img.parentNode.style[support.cssTransform] = ' rotate('+ radians +'rad) ' + iTransform; + setTimeout(()=>{ + img.parentNode.classList.add("transition-transform"); + },0); + } + self.rotateIPointer.style[support.cssTransform]='rotate('+ radians +'rad)';//旋转指示器 + + self.rotatedRadians=radians; + self.setToolBadge('rotate',radians/(PI/180)); + + var afterimgRectSize=self.getRotatedImgRectSize( radians, imgSize ); + imgWindow.style.width=afterimgRectSize.w +'px'; + imgWindow.style.height=afterimgRectSize.h + 'px'; + + if(!topLeft){ + self.setImgWindowOffset(rectOffset,imgRectSize,afterimgRectSize); + }; + + self.setImgOffset(imgOffset,imgRectSize,afterimgRectSize); + self.keepScreenInside(); + }; + + + if(typeof origin=='number'){ + rotate(origin); + return; + }; + + + this.working=true; + + var lastRotatedRadians=this.rotatedRadians; + this.shiftKeyUp=true; + var shiftRotateStep=prefs.imgWindow.shiftRotateStep / (180/Math.PI);//转成弧度 + + var moveHandler=function(e){ + self.rotateIndicator.style.display='block'; + var radians=lastRotatedRadians + Math.atan2( e.clientY - origin.y, e.clientX - origin.x ); + if(radians>=2*PI){ + radians-=2*PI; + }else if(radians<0){ + radians+=2*PI; + }; + + if(!self.shiftKeyUp){//如果按下了shift键,那么步进缩放 + radians -= radians % shiftRotateStep; + radians += shiftRotateStep; + }; + rotate(radians); + }; + + var mouseupHandler=function(){ + self.working=false; + self.rotateIndicator.style.display='none'; + document.removeEventListener('mousemove',moveHandler,true); + document.removeEventListener('mouseup',mouseupHandler,true); + self.img.parentNode.classList.add("transition-transform"); + }; + + self.img.parentNode.classList.remove("transition-transform"); + document.addEventListener('mousemove',moveHandler,true); + document.addEventListener('mouseup',mouseupHandler,true); + }, + convertToValidRadians:function(radians){ + //转成0-90的等价角度。 + var PI=Math.PI; + if(radians > PI){ + radians = 2*PI - radians; + }; + if(radians > 1/2*PI){ + radians = PI - radians; + }; + return radians; + }, + getRotatedImgRectSize:function( radians, imgSize ){//通过旋转后的角度和图片的大小,求虚拟矩形的大小 + imgSize= imgSize ? imgSize :{ + h:this.img.clientHeight, + w:this.img.clentWidth, + }; + + if(typeof radians==='undefined'){ + radians = this.rotatedRadians; + }; + + radians=this.convertToValidRadians(radians); + + return { + h:this.notExponential(imgSize.h* Math.cos(radians) + imgSize.w * Math.sin(radians)), + w:this.notExponential(imgSize.h* Math.sin(radians) + imgSize.w * Math.cos(radians)), + }; + }, + getRotatedImgCliSize:function(rectSize,radians){//通过虚拟矩形的大小和图片的旋转角度,求图片的大小 + + if(typeof radians==='undefined'){ + radians = this.rotatedRadians; + }; + + radians=this.convertToValidRadians(radians); + + if(radians==0){ + //radians=Math.PI/180 * 1/100; + return rectSize; + }; + + var h=(rectSize.h-rectSize.w * Math.tan(radians))/(Math.cos(radians)-Math.sin(radians)*Math.tan(radians)); + var w=(rectSize.h - h*Math.cos(radians))/Math.sin(radians); + return { + h:h, + w:w, + }; + + }, + setImgOffset:function(oriOffset,bImgSize,aImgSize){ + var imgStyle=this.img.parentNode.style; + + //避免出现指数形式的数字和单位相加,导致变成无效值 + var top=this.notExponential(oriOffset.top + (aImgSize.h-bImgSize.h)*1/2) + 'px'; + var left=this.notExponential(oriOffset.left + (aImgSize.w-bImgSize.w)*1/2) + 'px'; + imgStyle.top= top; + imgStyle.left= left; + }, + setImgWindowOffset:function(oriOffset,bImgWindowSize,aImgWidnowSize,ratio){ + ratio= ratio? ratio : {x:1/2,y:1/2}; + var imgWindowStyle=this.imgWindow.style; + var top=oriOffset.top - (aImgWidnowSize.h-bImgWindowSize.h)*ratio.y + 'px'; + var left=oriOffset.left - (aImgWidnowSize.w-bImgWindowSize.w)*ratio.x + 'px'; + imgWindowStyle.top= top; + imgWindowStyle.left= left; + }, + zoom:function(e,ratio){//e可能是undefined,可能是事件对象,可能是直接的缩放级别数字 + var imgWindow=this.imgWindow; + var imgWindowCS=unsafeWindow.getComputedStyle(imgWindow); + var imgRectSize={ + h:parseFloat(imgWindowCS.height), + w:parseFloat(imgWindowCS.width), + }; + + var rectOffset={ + top:parseFloat(imgWindow.style.top), + left:parseFloat(imgWindow.style.left), + }; + + var img=this.img; + var self=this; + + var zoom=function(level){//缩放到指定级别 + if(typeof level=='undefined' || level<0 || level==self.zoomLevel)return; + + var afterImgSize={ + h:self.imgNaturalSize.h * level || 10, + w:self.imgNaturalSize.w * level || 10, + }; + img.width=afterImgSize.w; + img.height=afterImgSize.h; + self.imgbox.style.width=afterImgSize.w + 'px'; + self.imgbox.style.height=afterImgSize.h + 'px'; + if (afterImgSize.w < 60) { + self.imgState.style.display = "none"; + } else { + self.imgState.style.display = ""; + } + if (afterImgSize.w < 220) { + self.maxButton.style.opacity = "0"; + self.closeButton.style.opacity = "0"; + } else { + self.maxButton.style.opacity = ""; + self.closeButton.style.opacity = ""; + } + if (afterImgSize.w < 100 || afterImgSize.h < 100) { + self.preButton.style.left = "-36px"; + self.nextButton.style.right = "-36px"; + } else { + self.preButton.style.left = "0px"; + self.nextButton.style.right = "0px"; + } + + var afterimgRectSize=self.getRotatedImgRectSize( self.rotatedRadians, afterImgSize ); + imgWindow.style.width=afterimgRectSize.w +'px'; + imgWindow.style.height=afterimgRectSize.h + 'px'; + self.setImgWindowOffset(rectOffset,imgRectSize,afterimgRectSize,ratio); + self.setImgOffset({top:0,left:0},afterImgSize,afterimgRectSize);//如果旋转了,调整偏移 + self.zoomLevel=level; + self.setToolBadge('zoom',level); + self.keepScreenInside(); + }; + + if(typeof e!='object'){ + ratio=ratio? ratio : { + x:1/2, + y:1/2, + }; + zoom(e); + return; + }; + + this.working=true; + + ratio=this.getZoomRatio({ + x:e.clientX, + y:e.clientY, + }); + + + var moved; + var lastPageX=e.pageX; + var currentLevel=this.zoomLevel; + var moveFired=0; + var moveHandler=function(e){ + moveFired++ + if(moveFired < 2){//有时候点击的时候不小心会触发一发move + return; + }; + moved=true; + var pageX=e.pageX; + var level; + if(pageX > lastPageX){//向右移,zoomin扩大 + self.changeCursor('zoom',false); + level=0.05; + }else{//向左移,zoomout缩小 + self.changeCursor('zoom',true); + level=-0.05; + }; + lastPageX=pageX; + currentLevel += level; + zoom(currentLevel); + }; + + var mouseupHandler=function(e){ + self.working=false; + document.removeEventListener('mousemove',moveHandler,true); + document.removeEventListener('mouseup',mouseupHandler,true); + + var level=self.getNextZoomLevel(); + + if(self.zoomOut && self.altKeyUp){ + self.zoomOut=false; + }; + + if(!moved){//如果没有平移缩放。 + zoom(level); + }; + + self.changeCursor('zoom',self.zoomOut); + + if(self.tempZoom && self.ctrlKeyUp && self.altKeyUp){ + self.tempZoom=false; + self.changeCursor(self.selectedTool); + }; + + }; + + document.addEventListener('mousemove',moveHandler,true); + document.addEventListener('mouseup',mouseupHandler,true); + }, + getNextZoomLevel:function(){ + var level; + var self=this; + if(this.zoomOut){//缩小 + let found = ImgWindowC.zoomRangeR.find(function(value){ + if(value < self.zoomLevel){ + level=value; + return true; + } + }); + if (!found) { + level = self.zoomLevel * 0.9; + } + }else{ + let found = ImgWindowC.zoomRange.find(function(value){ + if(value > self.zoomLevel){ + level=value; + return true; + }; + }); + if (!found) { + level = self.zoomLevel * 1.1; + } + } + return level; + }, + getZoomRatio:function(mouseCoor){ + var ibcRect=this.img.getBoundingClientRect(); + var ratio={ + x:(mouseCoor.x-ibcRect.left)/ibcRect.width, + y:(mouseCoor.y-ibcRect.top)/ibcRect.height, + }; + if(ratio.x<0){ + ratio.x=0 + }else if(ratio.x>1){ + ratio.x=1 + }; + if(ratio.y<0){ + ratio.y=0 + }else if(ratio.y>1){ + ratio.y=1 + }; + return ratio; + }, + aerialView:function(e){ + this.working=true; + //记住现在的缩放比例 + var cLevel=this.zoomLevel; + + var wSize=getWindowSize(); + wSize.h -= 16; + wSize.w -= 16; + + var imgWindow=this.imgWindow; + var imgWindowCS=unsafeWindow.getComputedStyle(imgWindow); + var rectSize={ + h:parseFloat(imgWindowCS.height), + w:parseFloat(imgWindowCS.width), + }; + var rectRatio=rectSize.h/rectSize.w; + var windowRatio=wSize.h/wSize.w; + + var size; + var rangeSize={}; + if(rectRatio > windowRatio){ + size={ + h:wSize.h, + w:wSize.h / rectRatio, + }; + rangeSize.h=Math.min(wSize.h * (size.h / rectSize.h), size.h); + rangeSize.w=Math.min(rangeSize.h / windowRatio , size.w); + }else{ + size={ + w:wSize.w, + h:wSize.w * rectRatio, + }; + rangeSize.w=Math.min(wSize.w * (size.w / rectSize.w), size.w); + rangeSize.h=Math.min(rangeSize.w * windowRatio , size.h); + }; + + + this.zoom(this.getRotatedImgCliSize(size).w/this.imgNaturalSize.w); + + this.center(true,true); + + this.keepScreenInside(); + + var viewRange=this.viewRange; + var vRS=viewRange.style; + vRS.display='block'; + vRS.height=rangeSize.h + 'px'; + vRS.width=rangeSize.w + 'px'; + vRS.top=0 + 'px'; + vRS.left=0 + 'px'; + + + + var viewRangeRect=viewRange.getBoundingClientRect(); + var scrolled=prefs.imgWindow.fixed ? {x:0, y:0} : getScrolled(); + var viewRangeCenterCoor={ + x:viewRangeRect.left + scrolled.x + 1/2 * rangeSize.w, + y:viewRangeRect.top + scrolled.y + 1/2 * rangeSize.h, + }; + + var self=this; + + var moveRange={ + x:[8,8+size.w-rangeSize.w], + y:[8,8+size.h-rangeSize.h] + }; + + + function setViewRangePosition(pageXY){ + var top=pageXY.y - viewRangeCenterCoor.y; + var left=pageXY.x - viewRangeCenterCoor.x; + if(top<=moveRange.y[0]){ + top=moveRange.y[0]; + }else if(top>=moveRange.y[1]){ + top=moveRange.y[1]; + }; + vRS.top= top + 'px'; + if(left<=moveRange.x[0]){ + left=moveRange.x[0]; + }else if(left>=moveRange.x[1]){ + left=moveRange.x[1]; + }; + vRS.left= left + 'px'; + }; + + setViewRangePosition({ + x:e.pageX, + y:e.pageY, + }); + + var moveHandler=function(e){ + setViewRangePosition({ + x:e.pageX, + y:e.pageY, + }); + }; + + var mouseupHandler=function(){ + self.working=false; + viewRange.style.display='none'; + self.zoom(cLevel); + var scrolled=prefs.imgWindow.fixed ? {x:0, y:0} : getScrolled(); + imgWindow.style.top= -13 - rectSize.h * ((parseFloat(vRS.top) - moveRange.y[0])/size.h) + scrolled.y +'px'; + imgWindow.style.left= -13 - rectSize.w * ((parseFloat(vRS.left) - moveRange.x[0])/size.w) + scrolled.x +'px'; + + //说明图片的高度没有屏幕高,居中 + //说明图片的宽度没有屏幕宽,居中 + self.center(rangeSize.w == size.w , rangeSize.h == size.h); + + self.keepScreenInside(); + + document.removeEventListener('mousemove',moveHandler,true); + document.removeEventListener('mouseup',mouseupHandler,true); + }; + document.addEventListener('mousemove',moveHandler,true); + document.addEventListener('mouseup',mouseupHandler,true); + }, + setToolBadge:function(tool,content){ + var scale=0; + switch(tool){ + case 'zoom':{ + scale=2; + if (this.img.naturalWidth) { + setSearchState(`${this.img.naturalWidth} x ${this.img.naturalHeight}` + (content !== 1 ? ` (${parseInt(content * 100)}%)` : "") + (this.curIndex >=0 ? ` [${this.curIndex + 1}/${this.data.all.length}]` : ""), this.imgState); + this.descriptionSpan && this.imgState.appendChild(this.descriptionSpan); + } + }break; + case 'rotate':{ + scale=1; + }break; + default:break; + } + content=typeof content=='string'? content : content.toFixed(scale); + this.toolMap[tool].nextElementSibling.textContent=content; + }, + notExponential:function(num){//不要转为指数形势 + if(num>0){ + if(num >= 999999999999999934463){ + return 999999999999999934463; + }else if(num <= 0.000001){ + return 0.000001; + }; + }else if(num < 0){ + if(num >= -0.000001){ + return -0.000001; + }else if(num <= -999999999999999934463){ + return -999999999999999934463 + }; + }; + + return num; + }, + + blur:function(e){ + if(!this.focused)return; + ImgWindowC.showing = false; + var imgWindow =this.imgWindow; + //点击imgWinodw的外部的时候失去焦点 + if(e!==true && imgWindow.contains(e.target))return; + imgWindow.classList.remove('pv-pic-window-container_focus'); + document.removeEventListener('mousedown',this._blur,true); + document.removeEventListener('keydown',this._focusedKeydown,false); + document.removeEventListener('keyup',this._focusedKeyup,true); + this.changeCursor('default'); + ImgWindowC.selectedTool=this.selectedTool; + this.imgWindow.style.zIndex= prefs.imgWindow.zIndex; + this.zIndex=prefs.imgWindow.zIndex; + this.focused=false; + }, + focus:function(){ + if(this.focused)return; + this.toolMap.compare.style.display = ImgWindowC.all.length > 1 ? "" : "none"; + ImgWindowC.showing = true; + this.imgWindow.classList.add('pv-pic-window-container_focus'); + this.imgWindow.style.zIndex=prefs.imgWindow.zIndex+1; + this.zIndex=prefs.imgWindow.zIndex+1; + document.addEventListener('keydown',this._focusedKeydown,false); + document.addEventListener('keyup',this._focusedKeyup,true); + document.addEventListener('mousedown',this._blur,true); + + //还原鼠标样式。 + this.changeCursor(this.selectedTool); + + if(prefs.imgWindow.syncSelectedTool && ImgWindowC.selectedTool){ + this.selectTool(ImgWindowC.selectedTool); + }; + + this.focused=true; + }, + focusedKeyup:function(e){ + var keyCode=e.keyCode; + var valid=[27,32,18,16,72,17,72,82,90,67,37,39]; + if(valid.indexOf(keyCode)==-1)return; + + if (window.getSelection().toString()) return; + e.preventDefault(); + + switch(keyCode){ + case 32:{//空格键,临时切换到移动 + this.spaceKeyUp=true; + if(!this.tempHand)return;//如果之前没有临时切换到抓手工具(当已经在工作的时候,按下空格不会临时切换到抓手工具) + if(!this.working){//松开按键的时候,没有在继续平移了。 + this.tempHand=false; + this.changeCursor(this.selectedTool); + }; + }break; + case 18:{//alt键盘切换缩小放大。 + this.altKeyUp=true; + if(!this.zoomOut)return; + if(!this.working){ + this.zoomOut=false; + this.changeCursor('zoom'); + if(this.tempZoom && this.ctrlKeyUp){ + this.tempZoom=false; + this.changeCursor(this.selectedTool); + }; + }; + }break; + case 16://shift键,旋转的时候按住shift键,步进缩放。 + this.shiftKeyUp=true; + break; + case 17:{//ctrl键 + clearTimeout(this.ctrlkeyDownTimer); + if(!this.justCKeyUp){//如果刚才没有松开c,规避划词软件的ctrl+c松开 + this.ctrlKeyUp=true; + if(!this.tempZoom)return;//如果没有切换到了缩放 + if(!this.working && this.altKeyUp){ + this.tempZoom=false; + this.changeCursor(this.selectedTool); + }; + }; + }break; + case 67:{//c键 + this.justCKeyUp=true; + var self=this; + clearTimeout(this.justCKeyUpTimer); + this.justCKeyUpTimer=setTimeout(function(){ + self.justCKeyUp=false; + _GM_setClipboard(self.src); + },100) + }break; + case 72://h键 + this.hKeyUp=true; + break; + case 82://r键 + this.rKeyUp=true; + break; + case 90://z键 + this.zKeyUp=true; + break; + case 39: + this.switchImage(true); + break; + case 37: + this.switchImage(false); + break; + case 27: + if (prefs.imgWindow.close.escKey) { + this.remove(); + e.stopPropagation(); + } + break; + default:break; + }; + + if([72,82,90].indexOf(keyCode)!=-1){ + if(!this.working && this.restoreBeforeTool){ + this.restoreBeforeTool=false; + this.selectTool(this.beforeTool); + }; + }; + }, + focusedKeydown:async function(e){ + var keyCode=e.keyCode; + if (!prefs.floatBar.keys.enable) return; + if (window.getSelection().toString()) return; + if (this.data && this.data.img && e.key.toLowerCase() == prefs.floatBar.keys.download) { + downloadImg(this.img.src, (this.data.img.title || this.data.img.alt), prefs.saveName); + e.preventDefault(); + e.stopPropagation(); + return; + } + if (e.key.toLowerCase() == prefs.floatBar.keys.gallery) { + if (!gallery) { + gallery = new GalleryC(); + gallery.data = []; + } + var allData = await gallery.getAllValidImgs(); + allData.target = this.data; + gallery.data = allData; + gallery.load(gallery.data); + this.remove(); + e.preventDefault(); + e.stopPropagation(); + return; + } + var valid=[32,82,72,90,18,16,17,27,67];//有效的按键 + if(valid.indexOf(keyCode)==-1) return; + + e.preventDefault(); + + if(this.working){//working的时候也可以接受按下shift键,以便旋转的时候可以任何时候按下 + if(keyCode==16){//shift键 + this.shiftKeyUp=false; + }; + return; + }; + switch(keyCode){ + case 82:{//r键,切换到旋转工具 + if(this.rKeyUp){ + this.rKeyUp=false; + this.beforeTool=this.selectedTool; + if (this.beforeTool != 'rotate') { + this.selectTool('rotate'); + } + var PI = Math.PI; + var value = this.rotatedRadians + (e.shiftKey ? -90 : 90) * PI / 180; + if (value >= 2 * PI) { + value -= 2 * PI; + } else if (value < 0) { + value += 2 * PI; + } + this.rotate(value,true); + }; + }break; + case 72:{//h键,切换到抓手工具 + if(this.hKeyUp){ + this.hKeyUp=false; + this.beforeTool=this.selectedTool; + this.selectTool('hand'); + }; + }break; + case 90:{//z键,切换到缩放工具 + if(this.zKeyUp){ + this.zKeyUp=false; + this.beforeTool=this.selectedTool; + this.selectTool('zoom'); + let level = e.shiftKey ? (this.zoomLevel - 0.5) : (this.zoomLevel + 0.5); + if (typeof level != 'undefined') { + this.zoom(level, { x: 0, y: 0}); + } + if (uniqueImgWin && uniqueImgWin == this) { + if (prefs.floatBar.globalkeys.previewFollowMouse) { + this.followPos(uniqueImgWinInitX, uniqueImgWinInitY, true); + } else { + this.center(true, true); + } + } + }; + }break; + case 32:{//空格键阻止,临时切换到抓手功能 + if(this.spaceKeyUp){ + this.spaceKeyUp=false; + if(this.selectedTool!='hand'){ + this.tempHand=true; + this.changeCursor('hand'); + }; + }; + }break; + case 18:{//alt键,在当前选择是缩放工具的时候,按下的时候切换到缩小功能 + if(this.altKeyUp){ + if((this.selectedTool!='zoom' && !this.tempZoom) || this.zoomOut)return; + this.zoomOut=true; + this.altKeyUp=false; + this.changeCursor('zoom',true); + }; + }break; + case 17:{//ctrl键临时切换到缩放工具 + if(this.ctrlKeyUp){ + var self=this; + this.ctrlkeyDownTimer=setTimeout(function(){//规避词典软件的ctrl+c,一瞬间切换到缩放的问题 + self.ctrlKeyUp=false; + if(self.selectedTool!='zoom'){ + self.tempZoom=true; + self.changeCursor('zoom'); + }; + },100); + }; + }break; + case 67:{//c键 + clearTimeout(this.ctrlkeyDownTimer); + }break; + case 27:{//ese关闭窗口 + }break; + default:break; + } + e.stopPropagation(); + return false; + }, + + toolbarEventHandler:function(e){ + e.preventDefault(); + e.stopPropagation(); + var target=e.target; + var toolMap=this.toolMap; + for(var i in toolMap){ + if(toolMap.hasOwnProperty(i) && toolMap[i]==target){ + switch(e.type){ + case 'mousedown':{ + this.selectTool(i); + }break; + case 'dblclick':{ + this.dblclickCommand(i); + }break; + default:break; + }; + break; + }; + }; + }, + imgWindowEventHandler:function(e){ + if (e.button == 0) { + e.stopPropagation(); + } + var selectedTool=this.selectedTool; + if(selectedTool == "hand" && prefs.imgWindow.suitLongImg && this.isLongImg){ + var inScroll=this.imgWindow.classList.contains("pv-pic-window-scroll"); + if(e.type == "wheel" && inScroll) + return; + if(e.type == "click" && !this.moving){ + var wSize=getWindowSize(); + var imgWindow=this.imgWindow; + var scrolled=prefs.imgWindow.fixed ? {x:0, y:0} : getScrolled(); + var origTop=parseFloat(imgWindow.style.top); + if(inScroll){ + imgWindow.style.top = parseFloat(imgWindow.style.top) - getScrolled(imgWindow.children[0]).y +'px'; + this.imgWindow.classList.remove("pv-pic-window-scroll"); + } else { + this.rotate(0,true); + this.imgWindow.classList.add("pv-pic-window-scroll"); + imgWindow.children[0].scrollTop = -parseInt(imgWindow.style.top); + } + //this.center(true , true); + if(!inScroll){ + imgWindow.style.top= (wSize.h - imgWindow.offsetHeight)/2 + scrolled.y +'px'; + var scrollTop=parseFloat(imgWindow.style.top)-origTop; + if(this.imgWindow.scrollTop)this.imgWindow.scrollTop = scrollTop; + else if(this.imgWindow.pageYOffset)this.imgWindow.pageYOffset = scrollTop; + else if(this.imgWindow.scrollY)this.imgWindow.scrollY = scrollTop; + } + this.keepScreenInside(); + } + } + switch(e.type){ + case 'click':{//阻止opera的图片保存 + if (selectedTool === "hand" && !this.moving) { + if (this.imgWindow.classList.contains("pv-pic-window-black")) { + this.imgWindow.classList.remove("pv-pic-window-black"); + this.imgWindow.classList.add("pv-pic-window-white"); + } else if (this.imgWindow.classList.contains("pv-pic-window-white")) { + this.imgWindow.classList.remove("pv-pic-window-white"); + } else { + this.imgWindow.classList.add("pv-pic-window-black"); + } + } + this.moving=false; + if(e.ctrlKey && e.target.nodeName.toUpperCase()=='IMG'){ + e.preventDefault(); + } + }break; + case 'mousedown': + case 'touchstart':{ + if(!this.focused){//如果没有focus,先focus + this.focus(); + this.moving=true; + this.keepScreenInside(); + }; + + var target=e.target; + if(e.button==2){//由于rotate时候的覆盖层问题,修复右键的图片菜单弹出 + if(target!=this.rotateOverlayer)return; + var self=this; + this.rotateOverlayer.style.display='none'; + var upHandler=function(){ + document.removeEventListener('mouseup',upHandler,true); + setTimeout(function(){ + self.rotateOverlayer.style.display='block'; + },10); + }; + document.addEventListener('mouseup',upHandler,true); + return; + }; + + if((e.button!=0 && e.type!="touchstart") || (target!=this.imgWindow && target!=this.img && target!=this.rotateOverlayer && target!=this.imgState))return; + e.preventDefault(); + if(this.tempHand){ + this.move(e); + }else if(this.tempZoom){ + this.zoom(e); + }else if(selectedTool=='hand'){ + this.restoreBeforeTool=!this.hKeyUp; + if(this.hKeyUp){ + this.move(e); + }else{//鸟瞰视图 + this.aerialView(e); + }; + }else if(selectedTool=='rotate'){ + var origin={//旋转原点 + x:e.clientX - 30,//稍微偏左一点。 + y:e.clientY , + }; + + var rIS=this.rotateIndicator.style; + //rIS.display='block'; + rIS.top=origin.y + 'px'; + rIS.left=origin.x + 'px'; + + this.restoreBeforeTool=!this.rKeyUp; + this.rotate(origin); + }else if(selectedTool=='zoom'){ + this.restoreBeforeTool=!this.zKeyUp; + this.zoom(e); + }; + }break; + case 'wheel':{ + if(!this.focused)return;//如果没有focus + if(e.deltaY===0)return;//非Y轴的滚动 + e.preventDefault(); + if(this.working)return; + var oriZoomOut=this.zoomOut; + this.zoomOut = !!(e.deltaY > 0); + + var ratio=this.getZoomRatio({ + x:e.clientX, + y:e.clientY, + }); + + var level=this.getNextZoomLevel(); + this.zoomed=true; + + this.zoom(level,ratio); + this.zoomOut=oriZoomOut; + }break; + default:break; + }; + }, + + dblclickCommand:function(tool){ + var done; + switch(tool){ + case 'hand':{//双击居中,并且适应屏幕 + this.zoom(1); + this.fitToScreen(); + this.center(true,true); + this.keepScreenInside(); + }break; + case 'rotate':{//双击还原旋转 + if(this.rotatedRadians==0)return; + done=true; + this.rotate(0,true); + }break; + case 'zoom':{//双击还原缩放 + if(this.zoomLevel==1)return; + done=true; + this.zoom(1,{x:0,y:0}); + }break; + default:break; + }; + + if((tool=='rotate' || tool=='zoom') && done){ + var scrolled=prefs.imgWindow.fixed ? {x:0, y:0} : getScrolled(); + var imgWindow=this.imgWindow; + var imgWinodowRect=imgWindow.getBoundingClientRect(); + var imgWindowStyle=imgWindow.style; + if(imgWinodowRect.left<40){ + imgWindowStyle.left=40 + scrolled.x + 'px'; + }; + if(imgWinodowRect.top<-5){ + imgWindowStyle.top=-5 + scrolled.y +'px'; + }; + this.keepScreenInside(); + }; + + }, + doFlipCommand:function(command){ + var map={ + fv:[/scaleY\([^)]*\)/i,' scaleY(-1) '], + fh:[/scaleX\([^)]*\)/i,' scaleX(-1) '], + }; + + var iTransform=this.img.parentNode.style[support.cssTransform]; + + var toolClassList=this.toolMap[command].classList; + + if(map[command][0].test(iTransform)){ + iTransform=iTransform.replace(map[command][0],''); + toolClassList.remove(this.selectedToolClass); + }else{ + iTransform += map[command][1]; + toolClassList.add(this.selectedToolClass); + }; + this.img.parentNode.style[support.cssTransform]=iTransform; + + }, + selectTool:function(tool){ + var command=['fv','fh']; + if(command.indexOf(tool)==-1){//工具选择 + if(this.selectedTool==tool){ + return; + } + let self=this; + if(tool=="compare"){ + var topmost=0, topmostWin; + ImgWindowC.all.forEach(function(iwin){ + if(iwin.zIndex >= topmost && iwin!=self){ + topmost=iwin.zIndex; + topmostWin=iwin; + }; + }); + if(topmostWin){ + this.toolMap.compare.style.display="none"; + this.compare([topmostWin.img.src]); + }; + return; + } + var selectedTool=this.selectedTool; + this.selectedTool=tool; + if(this.tempHand || this.tempZoom){//临时工具中。不变鼠标 + return; + }; + + this.rotateOverlayer.style.display=(tool=='rotate'? 'block' : 'none');//这个覆盖层是为了捕捉双击或者单击事件。 + + if(selectedTool){ + this.toolMap[selectedTool].classList.remove(this.selectedToolClass); + }; + this.toolMap[tool].classList.add(this.selectedToolClass); + this.changeCursor(tool); + }else{//命令 + this.doFlipCommand(tool); + }; + }, + changeCursor:function(tool,zoomOut){ + if(tool=='zoom'){ + tool+=zoomOut? '-out' : '-in'; + }; + if(this.cursor==tool)return; + this.cursor=tool; + + var cursor; + + switch(tool){ + case 'hand':{ + cursor=support.cssCursorValue.grab || 'pointer'; + }break; + case 'handing':{ + cursor=support.cssCursorValue.grabbing || 'pointer'; + }break; + case 'zoom-in':{ + cursor=support.cssCursorValue.zoomIn; + }break; + case 'zoom-out':{ + cursor=support.cssCursorValue.zoomOut; + }break; + case 'rotate':{ + cursor='progress'; + }break; + case 'default':{ + cursor=''; + }break; + }; + + if(typeof cursor!='undefined'){ + this.imgWindow.style.cursor=cursor; + }; + + }, + + remove:function(opacity){ + if(this.removed)return; + this.removed=true; + //this.imgWindow.classList.remove("pv-pic-window-transition-all"); + this.blur(true); + if(!opacity)this.imgWindow.style.opacity=0; + let self = this; + setTimeout(() => { + if (this.removed) { + if (self.isImg) self.img.src= prefs.icons.brokenImg_small;//如果在加载中取消,图片也取消读取。 + self.imgWindow.parentNode.removeChild(self.imgWindow); + } + },300); + + if (!this.preview) { + var index=ImgWindowC.all.indexOf(this); + ImgWindowC.all.splice(index,1); + } + var removeEvent=document.createEvent('CustomEvent'); + removeEvent.initCustomEvent('pv-removeImgWindow',false,false); + this.imgWindow.dispatchEvent(removeEvent); + + //focus next + if(ImgWindowC.all.length==0){ + if(ImgWindowC.overlayer){ + ImgWindowC.overlayer.style.display='none'; + }; + }else{ + var topmost=0, topmostWin; + ImgWindowC.all.forEach(function(iwin){ + if(iwin.zIndex >= topmost){ + topmost=iwin.zIndex; + topmostWin=iwin; + } + }); + if(topmostWin){ + topmostWin.focus(); + } + } + + }, + + }; + + addWheelEvent(getBody(document), e => { + if (uniqueImgWin && !uniqueImgWin.removed) { + if (uniqueImgWin.isLongImg) { + e.preventDefault(); + e.stopPropagation(); + uniqueImgWin.img.parentNode.scrollTop += e.deltaY; + } else if (uniqueImgWin.curIndex >= 0) { + e.preventDefault(); + e.stopPropagation(); + uniqueImgWin.switchImage(e.deltaY > 0); + } + } + }, true); + + var lastPopupLoading; + // 载入动画 + function LoadingAnimC(data, buttonType, waitImgLoad, openInTopWindow, initPos) { + if (LoadingAnimC.all.find(function(item, index, array) { + if (data.src == item.data.src || data.img == item.data.img) { + return true; + } + })) return false; + if (buttonType === "popup") { + if (lastPopupLoading) { + lastPopupLoading.cancel(); + } + lastPopupLoading = this; + } + this.args = arrayFn.slice.call(arguments, 0); + if (data.src != data.imgSrc && !data.srcs) { + data.srcs = [data.imgSrc]; + } + this.data = data;//data + this.buttonType = buttonType;//点击的按钮类型 + this.openInTopWindow = openInTopWindow;//是否在顶层窗口打开,如果在frame里面的话 + this.waitImgLoad = waitImgLoad;//是否等待完全读取后打开 + this.initPos = initPos || false; + this.init(); + } + + LoadingAnimC.all=[]; + + LoadingAnimC.prototype={ + init:function(){ + LoadingAnimC.all.push(this); + this.addStyle(); + var container=document.createElement('span'); + + container.className='pv-loading-container'; + this.loadingAnim=container; + + container.title=i18n("loading")+':' + this.data.src; + let retrySpan=document.createElement('span'); + retrySpan.className='pv-loading-button pv-loading-retry'; + retrySpan.title='Retry'; + container.appendChild(retrySpan); + let cancelSpan=document.createElement('span'); + cancelSpan.className='pv-loading-button pv-loading-cancle'; + cancelSpan.title='Cancel'; + container.appendChild(cancelSpan); + /*container.innerHTML= + ''+ + '';*/ + + if (this.buttonType == 'popup'){ + container.style.pointerEvents="none"; + } + getBody(document).appendChild(container); + + var self = this; + container.addEventListener('click',function(e){ + var tcl=e.target.classList; + if(tcl.contains('pv-loading-cancle')){ + self.cancel(); + }else if(tcl.contains('pv-loading-retry')){ + self.remove(); + new LoadingAnimC(self.args[0],self.args[1],self.args[2],self.args[3]); + }; + },true); + + this.setPosition(); + + if (!this.data.noActual && (this.buttonType == 'current' || this.buttonType == 'gallery')) { + this.loadImg(this.data.imgSrc); + } else { + if (!this.data.xhr) { + if(this.buttonType == 'search'){ + sortSearch(); + let from=0; + let searchFun=function(){ + searchImgByImg(self.data.imgSrc, null, function(srcs, index){ + let src=srcs.shift(); + if(index==3){ + self.loadImg(src, srcs); + }else{ + from=index+1; + self.loadImg(src, srcs, searchFun); + } + },function(e) { + self.error("网络错误"); + },function(e) { + self.error("没有找到原图"); + }, from); + }; + searchFun(); + }else{ + this.loadImg(this.data.src||this.data.imgSrc, this.data.srcs); + } + } else { + xhrLoad.load({ + url: this.data.src, + xhr: this.data.xhr, + cb: function(imgSrc, imgSrcs, caption) { + if (imgSrc) { + self.data.src = imgSrc; + if (imgSrcs && imgSrcs.length) { + imgSrcs = Array.from(new Set(imgSrcs)); + } + self.data.all = imgSrcs; + if (caption) self.data.description = caption; + self.loadImg(imgSrc, imgSrcs); + } else if (self.data.imgSrc) { + self.loadImg(self.data.imgSrc, imgSrcs); + } else { + self.error(); + } + }, + onerror: function() { + self.error(); + } + }); + } + } + }, + addStyle:function(){ + if (LoadingAnimC.style) { + if (!LoadingAnimC.style.parentNode) { + LoadingAnimC.style = _GM_addStyle(LoadingAnimC.style.innerText); + } + return; + } + LoadingAnimC.style=_GM_addStyle('\ + .pv-loading-container {\ + position: absolute;\ + z-index:999999997;\ + background: black url("'+prefs.icons.loading+'") center no-repeat;\ + background-origin: content-box;\ + border: none;\ + padding: 1px 30px 1px 2px;\ + margin: 0;\ + opacity: 0.5;\ + height: 24px;\ + min-width: 24px;\ + box-shadow: 2px 2px 0px #666;\ + -webkit-transition: opacity 0.15s ease-in-out;\ + transition: opacity 0.15s ease-in-out;\ + width: initial;\ + }\ + .pv-loading-container:hover {\ + opacity: 0.9;\ + }\ + .pv-loading-button {\ + cursor: pointer;\ + height: 24px;\ + width: 24px;\ + position: absolute;\ + right: 0;\ + top: 0;\ + opacity: 0.4;\ + background:transparent center no-repeat;\ + -webkit-transition: opacity 0.15s ease-in-out;\ + transition: opacity 0.15s ease-in-out;\ + }\ + .pv-loading-button:hover {\ + opacity: 1;\ + }\ + .pv-loading-cancle{\ + pointer-events: all;\ + background-image: url("'+prefs.icons.loadingCancle+'");\ + }\ + .pv-loading-retry{\ + display:none;\ + pointer-events: all;\ + background-image: url("'+prefs.icons.retry+'");\ + }\ + .pv-loading-container_error{\ + background-image:none;\ + }\ + .pv-loading-container_error::after{\ + content:"'+i18n("loadError")+'";\ + line-height: 24px;\ + color: red;\ + font-size: 14px;\ + display:inline;\ + }\ + .pv-loading-container_error .pv-loading-cancle{\ + display:none;\ + }\ + .pv-loading-container_error .pv-loading-retry{\ + display:block;\ + }\ + '); + }, + remove:function(){ + if(!this.removed){ + this.removed=true; + this.loadingAnim.parentNode.removeChild(this.loadingAnim); + LoadingAnimC.all.splice(LoadingAnimC.all.indexOf(this),1); + }; + }, + cancel:function(){ + this.imgReady && this.imgReady.abort(); + this.remove(); + }, + error:function(msg,img,e){ + if(msg)debug(msg); + this.loadingAnim.style.pointerEvents=""; + this.loadingAnim.classList.add('pv-loading-container_error'); + debug('Picviewer CE+ 载入大图错误:%o', this.data); + + var self=this; + setTimeout(function(){ + self.remove(); + },3000); + }, + setPosition:function(){ + var position=getContentClientRect(this.data.img); + var cs=this.loadingAnim.style; + var scrolled=getScrolled(); + cs.top=position.top + scrolled.y +1 + 'px'; + cs.left=position.left + scrolled.x +1 + 'px'; + cs.removeProperty('display'); + }, + + // 根据 imgSrc 载入图片,imgSrcs 为备用图片地址,imgSrc 加载失败备用 + loadImg: async function(imgSrc, imgSrcs, nextFun) { + var self = this; + + var mode = matchedRule.getMode(imgSrc); + var media; + let loaded = function() { + media.play(); + self.load(this || media); + media.removeEventListener('loadeddata', loaded); + } + if (this.buttonType === 'magnifier') { + media = document.createElement('img'); + media.src = (mode === "video" || mode === "audio") ? this.data.imgSrc : imgSrc; + mode = ""; + } else { + switch (mode) { + case "video": + media = createVideo(); + media.style.width = 0; + media.style.height = 0; + media.controls = true; + media.loop = true; + media.autoplay = true; + media.volume = matchedRule.mute ? 0 : 1; + imgSrc = imgSrc.replace(/^video:/, ""); + if (imgSrc.indexOf('.mkv') !== -1) media.type = 'video/mp4'; + else if (imgSrc.indexOf('.m3u8') !== -1) { + try { + loaded(); + await initVideojs(media, imgSrc); + imgSrc = ""; + } catch (error) { + console.error('Failed to load or initialize Video.js player:', error); + } + } + break; + case "audio": + media = document.createElement('audio'); + media.controls = true; + media.autoplay = true; + media.volume = matchedRule.mute ? 0 : 1; + imgSrc = imgSrc.replace(/^audio:/, ""); + break; + default: + media = document.createElement('img'); + break; + } + if (imgSrc) media.src = imgSrc; + curLoadingMedia = media; + } + + var opts = { + error: function(e) { + if (/^blob:/.test(imgSrc)) { + if (Array.isArray(imgSrcs)) { + var src = imgSrcs.shift(); + if (src) { + self.loadImg(src, imgSrcs, nextFun); + return; + } + } + } else if (mode == "image" || mode == "") { + _GM_xmlhttpRequest({ + method: 'GET', + url: media.src, + responseType: 'blob', + onload: function(response) { + const blobUrl = URL.createObjectURL(response.response); + self.loadImg(blobUrl, imgSrcs, nextFun); + const releaseBlob = () => URL.revokeObjectURL(blobUrl); + window.addEventListener('beforeunload', releaseBlob); + }, + onerror: function() { + if (Array.isArray(imgSrcs)) { + var src = imgSrcs.shift(); + if (src) { + self.loadImg(src, imgSrcs, nextFun); + return; + } + } else { + self.error('', this, e); + } + } + }); + return; + } else { + self.error('', this, e); + } + + if(nextFun) nextFun(); + else self.error('', this, e); + }, + }; + + opts[self.waitImgLoad ? 'load' : 'ready'] = function(e) { + self.load(this, e); + }; + + if (mode === 'video' || mode === 'audio') { + if (imgSrc) { + media.addEventListener('loadeddata', loaded); + media.load(); + } + } else { + self.imgReady = imgReady(media, opts); + } + }, + + load:async function(img,e){ + this.remove(); + this.img=img; + var buttonType=this.buttonType; + + if(buttonType=='gallery'){ + if(!gallery){ + gallery=new GalleryC(); + gallery.data=[]; + } + var allData=await gallery.getAllValidImgs(); + allData.target=this.data; + this.data=allData; + }; + + var self=this; + function openInTop(){ + var data=self.data; + + //删除不能发送的项。 + var delCantClone=function(obj){ + if(!obj)return; + delete obj.img; + delete obj.imgPA; + }; + + if(Array.isArray(data)){ + frameSentSuccessData=frameSentData; + frameSentData=cloneObject(data,true); + delCantClone(data.target); + data.forEach(function(obj){ + delCantClone(obj); + }); + }else{ + delCantClone(data); + }; + + window.postMessage({ + messageID:messageID, + src:img.src, + data:data, + command:'open', + buttonType:buttonType, + to:'top', + },'*'); + }; + + if(this.openInTopWindow && isFrame && topWindowValid!==false && buttonType!='magnifier'){ + if(topWindowValid){ + openInTop(); + }else{//先发消息问问顶层窗口是不是非frameset窗口 + window.postMessage({ + messageID:messageID, + command:'topWindowValid', + to:'top', + },'*'); + + document.addEventListener('pv-topWindowValid',function(e){ + topWindowValid=e.detail; + if(topWindowValid){//如果顶层窗口有效 + openInTop(); + }else{ + self.open(); + }; + },true); + }; + + }else{ + this.open(); + }; + + + }, + open:function(){ + switch(this.buttonType){ + case 'popup': + if(uniqueImgWin && uniqueImgWin.src != this.data.src && (!this.data.srcs || !this.data.srcs.includes(uniqueImgWin.src))){ + uniqueImgWin.remove(); + } + if(!uniqueImgWin || uniqueImgWin.removed){ + this.data.src=this.img.src; + uniqueImgWin = new ImgWindowC(this.img, this.data, null, null, true); + //uniqueImgWin.imgWindow.classList.add("pv-pic-window-transition-all"); + } + //uniqueImgWin.blur({target:this.data.img}); + if(!uniqueImgWin.loaded){ + if(prefs.waitImgLoad){ + uniqueImgWin.imgWindow.style.display = "none"; + uniqueImgWin.imgWindow.style.opacity = 0; + }else{ + if (prefs.floatBar.globalkeys.previewFollowMouse) { + uniqueImgWin.followPos(uniqueImgWinInitX, uniqueImgWinInitY); + } else { + uniqueImgWin.initMaxSize(); + uniqueImgWin.center(true,true); + if(centerInterval)clearInterval(centerInterval); + centerInterval=setInterval(function(){ + if(!uniqueImgWin || uniqueImgWin.removed || uniqueImgWin.loaded){ + clearInterval(centerInterval); + }else{ + uniqueImgWin.center(true,true); + } + },300); + } + } + } + uniqueImgWin.imgWindow.classList.add("preview"); + break; + case 'gallery': + if(!gallery){ + gallery=new GalleryC(); + }; + gallery.load(this.data,this.from); + gallery.changeMinView(); + break; + case 'magnifier': + new MagnifierC(this.img,this.data); + break; + case 'download': + downloadImg(this.data.src || this.data.imgSrc, (this.data.img.title || this.data.img.alt), prefs.saveName); + break; + case "copy": + _GM_setClipboard(this.data.src || this.data.imgSrc); + break; + case "open": + _GM_openInTab(this.data.src || this.data.imgSrc, {active:false}); + break; + case "copyImg": + copyData(this.data.src || this.data.imgSrc); + break; + case 'actual': + case 'search': + case 'current': + case 'original'://original 是为了兼容以前的规则 + if(this.data.src!=this.img.src)this.data.src=this.img.src; + new ImgWindowC(this.img, this.data, this.buttonType == 'actual', this.initPos || false); + break; + }; + }, + }; + + function copyData(url) { + if (typeof ClipboardItem != 'undefined') { + urlToBlob(url, (blob, ext) => { + if (blob) { + try { + navigator.clipboard.write([ + new ClipboardItem({ + [blob.type]: blob + }) + ]); + } catch (error) { + console.error(error); + } + } + }, true); + } else _GM_setClipboard(url); + } + + //工具栏 + function FloatBarC(){ + this.init(); + }; + + FloatBarC.prototype={ + init:function(){ + this.addStyle(); + var container=document.createElement('span'); + container.id='pv-float-bar-container'; + getBody(document).appendChild(container); + for(let i=0;i<5;i++){ + let spanChild=document.createElement('span'); + spanChild.className='pv-float-bar-button'; + container.appendChild(spanChild); + } + /*container.innerHTML= + ''+ + ''+ + ''+ + ''+ + '';*/ + + var buttons={ + }; + this.buttons=buttons; + this.children=container.children; + + arrayFn.forEach.call(this.children,function(child,index){ + var titleMap={ + actual:i18n("actualBtn").replace(/ ?\(A\)/,` (${prefs.floatBar.keys.actual.toUpperCase()})`), + search:i18n("searchBtn").replace(/ ?\(S\)/,` (${prefs.floatBar.keys.search.toUpperCase()})`), + gallery:i18n("galleryBtn").replace(/ ?\(G\)/,` (${prefs.floatBar.keys.gallery.toUpperCase()})`), + current:i18n("currentBtn").replace(/ ?\(C\)/,` (${prefs.floatBar.keys.current.toUpperCase()})`), + magnifier:i18n("magnifierBtn").replace(/ ?\(M\)/,` (${prefs.floatBar.keys.magnifier.toUpperCase()})`), + download:i18n("download")+` (${prefs.floatBar.keys.download.toUpperCase()})`, + }; + var buttonName=prefs.floatBar.butonOrder[index]; + if(!buttonName){ + child.style.display="none"; + return; + } + buttons[buttonName]=child; + child.title=titleMap[buttonName]; + child.classList.add('pv-float-bar-button-' + buttonName); + }); + + + this.floatBar=container; + + + var self=this; + container.addEventListener('click',function(e){ + var buttonType; + var target=e.target; + for(var type in buttons){ + if(!buttons.hasOwnProperty(type))return; + if(target==buttons[type]){ + buttonType=type; + break; + }; + }; + if(!buttonType)return; + + self.open(e,buttonType); + self.hide(); + + },true); + + + addCusMouseEvent('mouseleave',container,function(e){ + clearTimeout(self.hideTimer); + self.hideTimer=setTimeout(function(){ + self.hide(); + },prefs.floatBar.hideDelay); + }); + + addCusMouseEvent('mouseenter',container,function(e){ + clearTimeout(self.hideTimer); + clearTimeout(self.showTimer); + clearTimeout(self.globarOutTimer); + }); + + this._scrollHandler=this.scrollHandler.bind(this); + }, + addStyle:function(){ + if (FloatBarC.style) { + if (!FloatBarC.style.parentNode) { + FloatBarC.style = _GM_addStyle(FloatBarC.style.innerText); + } + return; + } + FloatBarC.style=_GM_addStyle('\ + #pv-float-bar-container {\ + position: absolute;\ + background-image: initial;\ + top: 0px;\ + left: 0px;\ + z-index:2147483640;\ + padding: 5px;\ + margin: 0;\ + border: none;\ + opacity: 0.35;\ + line-height: 0;\ + -webkit-transition: opacity 0.2s ease-in-out;\ + transition: opacity 0.2s ease-in-out;\ + display:none;\ + }\ + #pv-float-bar-container:hover {\ + opacity: 1;\ + }\ + #pv-float-bar-container .pv-float-bar-button {\ + vertical-align:middle;\ + cursor: pointer;\ + width: 18px;\ + height: 18px;\ + padding: 0;\ + margin:0;\ + border: none;\ + display: inline-block;\ + position: relative;\ + box-shadow: 1px 0 3px 0px rgba(0,0,0,0.9);\ + background: transparent center no-repeat;\ + background-size:100% 100%;\ + background-origin: content-box;\ + -webkit-transition: margin-right 0.15s ease-in-out , width 0.15s ease-in-out , height 0.15s ease-in-out ;\ + transition: margin-right 0.15s ease-in-out , width 0.15s ease-in-out , height 0.15s ease-in-out ;\ + }\ + #pv-float-bar-container .pv-float-bar-button:not(:last-child){\ + margin-right: -14px;\ + }\ + #pv-float-bar-container .pv-float-bar-button:first-child {\ + z-index: 4;\ + }\ + #pv-float-bar-container .pv-float-bar-button:nth-child(2) {\ + z-index: 3;\ + }\ + #pv-float-bar-container .pv-float-bar-button:nth-child(3) {\ + z-index: 2;\ + }\ + #pv-float-bar-container .pv-float-bar-button:last-child {\ + z-index: 1;\ + }\ + #pv-float-bar-container:hover > .pv-float-bar-button {\ + width: 24px;\ + height: 24px;\ + }\ + #pv-float-bar-container:hover > .pv-float-bar-button:not(:last-child) {\ + margin-right: 4px;\ + }\ + #pv-float-bar-container .pv-float-bar-button-actual {\ + background-image:url("'+ prefs.icons.actual +'")!important;\ + }\ + #pv-float-bar-container .pv-float-bar-button-search {\ + background-image:url("'+ prefs.icons.search +'")!important;\ + }\ + #pv-float-bar-container .pv-float-bar-button-gallery {\ + background-image:url("'+ prefs.icons.gallery +'")!important;\ + }\ + #pv-float-bar-container .pv-float-bar-button-current {\ + background-image:url("'+ prefs.icons.current +'")!important;\ + }\ + #pv-float-bar-container .pv-float-bar-button-magnifier {\ + background-image:url("'+ prefs.icons.magnifier +'")!important;\ + }\ + #pv-float-bar-container .pv-float-bar-button-download {\ + background-image:url("'+ prefs.icons.download +'")!important;\ + }\ + '); + }, + start:function(data){ + + if (data && data.type == "link") { + data.hide = true; + } + //读取中的图片,不显示浮动栏,调整读取图标的位置. + if(LoadingAnimC.all.find(function(item,index,array){ + if (data.src == item.data.src || data.img == item.data.img) { + return true; + } + })) return false; + + + //被放大镜盯上的图片,不要显示浮动栏. + if(MagnifierC.all.find(function(item,index,array){ + if(data.src==item.data.src){ + return true; + }; + }))return false; + + var self=this; + clearTimeout(this.hideTimer); + + var imgOutHandler=function(e){ + document.removeEventListener('mouseout',imgOutHandler,true); + clearTimeout(self.showTimer); + clearTimeout(self.hideTimer); + self.hideTimer=setTimeout(function(){ + self.hide(); + },prefs.floatBar.hideDelay); + }; + + clearTimeout(this.globarOutTimer); + this.globarOutTimer=setTimeout(function(){//稍微延时。错开由于css hover样式发生的out; + document.addEventListener('mouseout',imgOutHandler,true); + },150); + + clearTimeout(this.showTimer); + self.data=data; + if (data.hide) { + this.show(); + this.floatBar.style.display = 'none'; + this.floatBar.style.opacity = 0; + return false; + } + if(!this.shown || self.data.img!=data.img){ + this.floatBar.style.transition="unset"; + this.floatBar.style.opacity=0.01; + } + this.showTimer=setTimeout(function(){ + self.show(); + },prefs.floatBar.showDelay); + return true; + }, + setButton:function(){ + if(this.buttons['actual']){ + if(this.data.noActual){ + this.buttons['actual'].style.display='none'; + }else{ + this.buttons['actual'].style.removeProperty('display'); + } + } + if(this.buttons['magnifier']){ + if(this.data.type != "force" && this.data.img.nodeName.toUpperCase() == 'IMG'){ + this.buttons['magnifier'].style.removeProperty('display'); + }else{ + this.buttons['magnifier'].style.display='none'; + } + } + if (this.data.img.nodeName.toUpperCase() != 'IMG') { + //this.buttons['gallery'].style.display = 'none'; + //this.buttons['current'].style.display = 'none'; + } else { + //this.buttons['gallery'].style.removeProperty('display'); + //this.buttons['current'].style.removeProperty('display'); + } + }, + setPosition: function() { + //如果图片被删除了,或者隐藏了。 + if (this.data.img.offsetWidth == 0) { + return true; + } + var targetPosi = getContentClientRect(this.data.img); + var pa = this.data.img.parentNode, limited = false; + if (pa && pa.scrollHeight > 30 && pa.scrollWidth > 30) { + var paPosi=pa.getBoundingClientRect(); + if (paPosi.width > 30 && paPosi.height > 30) { + const style = unsafeWindow.getComputedStyle(this.data.img); + const matrix = new DOMMatrixReadOnly(style.transform); + let translateX = matrix.m41, translateY = matrix.m42, scaleX = matrix.m11, scaleY = matrix.m22; + if (translateY || this.data.img.offsetTop != 0 || (scaleY && scaleY !== 1)) { + if (paPosi.height < targetPosi.height - 3) { + limited = true; + targetPosi.top = paPosi.top; + } + } + if (translateX || this.data.img.offsetLeft != 0 || (scaleX && scaleX !== 1)) { + if (paPosi.width < targetPosi.width - 3) { + limited = true; + targetPosi.left = paPosi.left; + } + } + } + } + pa = this.data.img.offsetParent; + if (pa && !limited) { + paPosi=pa.getBoundingClientRect(); + if (paPosi.width > 30 && paPosi.height > 30) { + const style = unsafeWindow.getComputedStyle(this.data.img); + const matrix = new DOMMatrixReadOnly(style.transform); + let translateX = matrix.m41, translateY = matrix.m42, scaleX = matrix.m11, scaleY = matrix.m22; + if (translateY || this.data.img.offsetTop != 0 || (scaleY && scaleY !== 1)) { + if (paPosi.height < targetPosi.height - 3) { + targetPosi.top = paPosi.top; + } + } + if (translateX || this.data.img.offsetLeft != 0 || (scaleX && scaleX !== 1)) { + if (paPosi.width < targetPosi.width - 3) { + targetPosi.left = paPosi.left; + } + } + } + } + var windowSize=getWindowSize(); + var img=this.data.img; + + var floatBarPosi=prefs.floatBar.position.toLowerCase().split(/\s+/); + + var offsetX=prefs.floatBar.offset.x; + var offsetY=prefs.floatBar.offset.y; + + let body = getBody(document); + let bodyStyle = unsafeWindow.getComputedStyle(body); + let offsetParent, bodyPosi; + + if (bodyStyle.position === "static") { + offsetParent = document.documentElement; + } else { + offsetParent = body; + } + bodyPosi = offsetParent.getBoundingClientRect(); + + + var scrolled=getScrolled(offsetParent); + targetPosi.top = targetPosi.top - bodyPosi.top; + targetPosi.left = targetPosi.left - bodyPosi.left; + targetPosi.bottom = bodyPosi.bottom - targetPosi.bottom; + targetPosi.right = bodyPosi.right - targetPosi.right; + + var fbs = this.floatBar.style; + var setPosition = { + top:function() { + var top = targetPosi.top; + if (top + offsetY - scrolled.y < 10) { + top = scrolled.y; + offsetY = 0; + } else { + if (prefs.floatBar.stayOut) { + top = top + offsetY - 10 - prefs.floatBar.stayOutOffsetY; + } else { + top = top + offsetY; + } + if (targetPosi.height <= 50) top -= 10; + } + fbs.bottom = 'unset'; + fbs.top = top + 'px'; + }, + right:function() { + var right = targetPosi.right; + if (prefs.floatBar.stayOut) { + right = right - offsetX - prefs.floatBar.stayOutOffsetX; + } else { + right = right - offsetX; + } + if (targetPosi.width <= 50) right += 10; + fbs.left = 'unset'; + fbs.right = right + 'px'; + }, + bottom:function() { + var bottom = targetPosi.bottom; + if (prefs.floatBar.stayOut) { + bottom = bottom - offsetY - 40 - prefs.floatBar.stayOutOffsetY; + } else { + bottom = bottom - offsetY - 30; + } + if (targetPosi.height <= 50) bottom += 10; + fbs.top = 'unset'; + fbs.bottom = bottom + 'px'; + }, + left:function() { + var left = targetPosi.left; + if (left + offsetX - scrolled.x < 0) { + left = scrolled.x; + offsetX = 0; + } else { + if (prefs.floatBar.stayOut) { + left = left + offsetX - prefs.floatBar.stayOutOffsetX; + } else { + left = left + offsetX; + } + if (targetPosi.width <= 50) left -= 10; + } + fbs.right = 'unset'; + fbs.left = left + 'px'; + }, + center:function() { + var left = targetPosi.left + offsetX; + fbs.left = left + targetPosi.width / 2 + 'px'; + }, + hide:function(){ + var top=targetPosi.top; + var left=targetPosi.left; + if(prefs.floatBar.stayOut){ + top=top + offsetY - 10 - prefs.floatBar.stayOutOffsetY; + left=left + offsetX - prefs.floatBar.stayOutOffsetX; + }else{ + top=top + offsetY; + left=left + offsetX; + } + if(targetPosi.height<=50)top-=10; + fbs.top=top + 'px'; + if(targetPosi.width<=50)left-=10; + fbs.left=left + 'px'; + }, + }; + + setPosition[floatBarPosi[0]](); + if(floatBarPosi.length>1){ + setPosition[floatBarPosi[1]](); + } + }, + show:function(){ + if(this.setPosition())return; + this.shown=true; + this.addStyle(); + this.setButton(); + this.floatBar.style.transition=""; + this.floatBar.style.display='block'; + this.floatBar.style.opacity=""; + clearTimeout(this.hideTimer); + window.removeEventListener('scroll',this._scrollHandler,true); + window.addEventListener('scroll',this._scrollHandler,true); + }, + hide:function(){ + clearTimeout(this.showTimer); + this.floatBar.style.opacity=0.01; + this.shown=false; + this.floatBar.style.display='none'; + window.removeEventListener('scroll',this._scrollHandler,true); + }, + scrollHandler:function(){//更新坐标 + clearTimeout(this.scrollUpdateTimer); + var self=this; + this.scrollUpdateTimer=setTimeout(function(){ + self.setPosition(); + },100); + }, + open:async function(e,buttonType){ + if (!this.shown || !this.data || !this.data.imgSrc) return; + if (window.getSelection().toString()) return; + if (this.data.imgSrc.indexOf("blob:") === 0) { + let blobUrl = await getBase64FromBlobUrl(this.data.imgSrc); + if (blobUrl) { + let sameSrc = (this.data.src === this.data.imgSrc); + this.data.imgSrc = blobUrl; + this.data.srcs = [this.data.imgSrc]; + if (sameSrc) { + this.data.src = blobUrl; + } + } + } + if (buttonType === 'download' && !this.data.xhr) { + if (e.ctrlKey || e.metaKey || e.altKey || e.shiftKey) return; + downloadImg(this.data.src || this.data.imgSrc, (this.data.img.title || this.data.img.alt), prefs.saveName); + e.stopPropagation(); + e.preventDefault(); + return; + } else { + e.stopPropagation(); + e.preventDefault(); + let altKey = e.altKey; + if (e.type != "click" && prefs.floatBar.globalkeys.invertInitShow && prefs.floatBar.globalkeys.alt) { + altKey = false; + } + let additionEnable = prefs.floatBar.invertAdditionalFeature ? !altKey : altKey; + if (additionEnable) { + let src, feature = prefs.floatBar.additionalFeature; + if (buttonType == 'actual') { + if (this.data.xhr) { + buttonType = feature || "open"; + } else { + src = this.data.src || this.data.imgSrc; + } + } else if (buttonType == 'current') { + src = this.data.imgSrc; + } + if (src) { + switch(feature) { + case "copy": + _GM_setClipboard(src); + break; + case "open": + _GM_openInTab(src, {active:false}); + break; + case "copyImg": + copyData(src); + break; + } + return; + } + } + } + var waitImgLoad = e && e.ctrlKey ? !prefs.waitImgLoad : prefs.waitImgLoad; //按住ctrl取反向值 + var openInTopWindow = e && e.shiftKey ? !prefs.framesPicOpenInTopWindow : prefs.framesPicOpenInTopWindow; //按住shift取反向值 + if (!waitImgLoad && buttonType == 'magnifier' && !envir.chrome) { //非chrome的background-image需要全部载入后才能显示出来 + waitImgLoad = true; + }; + new LoadingAnimC(this.data, buttonType, waitImgLoad, openInTopWindow); + if (e.type == "click") { + floatBar.hide(); + } + }, + update:function(img,src){ + if(this.data.img==img && this.data.imgSrc!=src){ + this.data.src=src; + this.data.noActual=false; + this.data.type="rule"; + if(this.shown){ + this.setButton(); + } + } + } + }; + + /** + * 提取自 Mouseover Popup Image Viewer 脚本,用于 xhr 方式的获取 + */ + var xhrLoad = function() { + var _ = {}; + + var caches = {}; + var handleError; + var cacheNum = 0; + var xhr; + var useFetch = false; + + /** + * @param q 图片的选择器或函数 + * @param c 图片说明的选择器或函数 + */ + function parsePage(url, q, c, post, cb, headers, after) { + downloadPage(url, post, headers, async function(html) { + var iurl, iurls = [], cap, caps, doc = createDoc(html); + + if(typeof q == 'function') { + iurl = await q(html, doc, url + (post ? `#p{${post}}` : ""), xhr, GM_fetch); + if (iurl) { + if(iurl.url) { + cap = iurl.cap; + iurl = iurl.url; + } + if (Array.isArray(iurl)) { + iurl = iurl.map(u => after(u)); + iurls = iurl; + iurl = iurls[0]; + } else iurl = after(iurl); + } + } else { + var inodes = findNodes(q, doc); + inodes.forEach(function(node) { + iurls.push(after(findFile(node, url))); + }); + iurl = iurls[0]; + } + + if (c) { + if(typeof c == 'function') { + cap = await c(html, doc, url, xhr); + } else { + var cnodes = findNodes(c, doc); + cap = cnodes.length ? findCaption(cnodes[0]) : false; + } + if (Array.isArray(cap)) { + caps = cap; + cap = caps[0]; + } + } + + // 缓存 + if (iurl) { + let cacheData = { + iurl: iurl, + iurls: iurls, + cap: cap, + caps: caps + }; + caches[url + (post || "")] = cacheData; + if (cacheNum) { + storage.setListItem("xhrCache", url + (post || ""), cacheData, cacheNum); + } + } + + cb(iurl, iurls, cap, caps); + }); + } + + async function downloadPage(url, post, headers, cb) { + var opts = { + method: 'GET', + url: url, + onload: function(req) { + try { + if(req.status > 399) throw 'Server error: ' + req.status; + else cb(req.responseText, req.finalUrl || url); + } catch(ex) { + if (!useFetch && req.responseHeaders.indexOf("cloudflare") != -1) { + useFetch = true; + return downloadPage(url, post, headers, cb); + } + handleError(ex); + } + }, + onerror: handleError + }; + if (post) { + opts.method = 'POST'; + opts.data = post; + opts.headers = {'Content-Type':'application/x-www-form-urlencoded','Referer':url}; + } + if (headers) { + if (typeof headers == 'function') { + headers = await headers(url + (post ? `#p{${post}}` : ""), xhr, getCookie); + } + opts.headers = headers; + } + + if (useFetch) { + let fetchOption = {method: opts.method || 'GET', headers: opts.headers}; + if (opts.method && opts.method != 'GET') { + fetchOption.body = opts.data || ''; + } + fetch(opts.url, fetchOption).then(response => response.text()).then(data => {opts.onload({responseText: data})}).catch(e => opts.onerror(e)); + } else { + _GM_xmlhttpRequest(opts); + } + } + + function createDoc(text) { + var doc = document.implementation.createHTMLDocument('PicViewerCE'); + doc.documentElement.innerHTML = text; + return doc; + } + + function findNodes(q, doc) { + var nodes = [], + node; + if (!Array.isArray(q)) q = [q]; + for (var i = 0, len = q.length; i < len; i++) { + node = qs(q[i], doc); + if (node && node.length) { + [].forEach.call(node, n => { + nodes.push(n); + }); + } + } + return nodes; + } + + function findFile(n, url) { + pretreatment(n, true); + var path = (n.dataset && n.dataset.src) || n.src || n.href || (n.children && n.children[0] && n.children[0].src); + if (/^video$/i.test(n.nodeName)) { + path = "video:" + path; + } else if (/^audio$/i.test(n.nodeName)) { + path = "audio:" + path; + } else if (path.baseVal) path = path.baseVal; + return path ? path.trim() : false; + } + + function findCaption(n) { + return n.getAttribute('content') || n.getAttribute('title') || n.textContent; + } + + function qs(s, n) { + return n.querySelectorAll(s); + } + + _.load = function(opt) { + xhr = opt.xhr; + var info = caches[opt.url] || storage.getListItem("xhrCache", opt.url); + cacheNum = xhr.cacheNum || 0; + if (info) { + opt.cb(info.iurl, info.iurls, info.cap, info.caps); + return; + } + + handleError = opt.onerror || function() {}; + let postParams = opt.url.match(/#p{(.*)}$/); + if (!opt.post && postParams) { + opt.post = postParams[1]; + opt.url = opt.url.replace(/#p{.*/, ""); + } + + parsePage(opt.url, xhr.query || xhr.q, xhr.caption || xhr.c, opt.post, opt.cb, xhr.headers, xhr.after); + }; + + return _; + }(); + + + // ------------------- run ------------------------- + + function pretreatment(img, fetchImg) { + if (img.removeAttribute) img.removeAttribute("loading"); + if (img.nodeName.toUpperCase() != "IMG" || (!fetchImg && img.src && !img.srcset && !/^data/.test(img.src))) return; + if (img.src && !/(^data|loading|lazy)/.test(img.src)) return; + let src; + tprules.find(function(rule, index, array) { + try { + src = rule.call(img); + if (src) { + return true; + } + } catch(err) { + debug(err); + } + }); + if (src) { + img.src = src; + } + } + + function findPic(img){ + var imgPN=img; + var imgPA,imgPE=[]; + while(imgPN=imgPN.parentNode || imgPN.host){ + if(imgPN.nodeName.toUpperCase()=='A'){ + imgPA=imgPN; + break; + } + } + imgPN=img; + while(imgPN=imgPN.parentNode || imgPN.host){ + if(imgPN.nodeName.toUpperCase()=='BODY'){ + break; + }else{ + imgPE.push(imgPN); + } + } + + var iPASrc=imgPA? imgPA.href : ''; + //base64字符串过长导致正则匹配卡死浏览器 + var base64Img=/^data:/i.test(img.src); + var src, // 大图地址 + srcs, // 备用的大图地址 + type, // 类别 + noActual = false, //没有原图 + imgSrc = img.currentSrc||img.src||img.dataset.lazySrc, // img 节点的 src + xhr, + description; // 图片的注释 + var imgCStyle = unsafeWindow.getComputedStyle(img); + if (/^link$/i.test(img.nodeName)) { + imgCStyle = {height:64, width:64}; + } + if (!/IMG/i.test(img.nodeName) && imgCStyle && imgCStyle.backgroundImage && imgCStyle.backgroundImage != "none") { + let sh = imgCStyle.height, sw = imgCStyle.width; + if (!img.offsetWidth) sw = 10; + if (!img.offsetHeight) sh = 10; + if (imgCStyle.backgroundRepeatX == "repeat") { + sw = 10; + } + if (imgCStyle.backgroundRepeatY == "repeat") { + sh = 10; + } + imgCStyle = {height:sh, width:sw}; + } + var imgCS = { + h: parseFloat(imgCStyle.height) || img.height || img.offsetHeight, + w: parseFloat(imgCStyle.width) || img.width || img.offsetWidth, + }; + if (imgCS.h === 0 && imgCS.w === 0) { + for (let i = 0; i < imgPE.length; i++) { + if (imgPE[i].offsetHeight) { + imgCS = { + h: imgPE[i].offsetHeight, + w: imgPE[i].offsetWidth + }; + break; + } + } + } + var imgAS={//实际尺寸。 + h:img.naturalHeight > 1 ? img.naturalHeight : imgCS.h, + w:img.naturalWidth > 1 ? img.naturalWidth : imgCS.w, + }; + if(!src && matchedRule.rules.length>0){// 通过高级规则获取. + // 排除 + try{ + let newSrc=matchedRule.getImage(img,imgPA,imgPE); + if(newSrc && imgSrc!=newSrc) src=newSrc; + }catch(err){ + throwErrorInfo(err); + } + + if(src) { + if (Array.isArray(src)) { + srcs = src; + src = srcs.shift(); + } + + type = 'rule'; + xhr = matchedRule.xhr; + + if (matchedRule.lazyAttr) { // 由于采用了延迟加载技术,所以图片可能为 loading.gif + imgSrc = img.getAttribute(matchedRule.lazyAttr) || img.src; + } + + if (matchedRule.description) { + let desc = matchedRule.description, attr; + if (Array.isArray(desc) && desc.length === 2) { + attr = desc[1]; + desc = desc[0]; + } + var node = getElementMix(desc, img); + if (node) { + description = attr ? node.getAttribute(attr) : (node.getAttribute('title') || node.textContent); + } + } + } + } + + if(/^IMG$/i.test(img.nodeName) && !src && iPASrc){//链接可能是一张图片... + if(iPASrc!=img.src && imageReg.test(iPASrc)){ + src=iPASrc; + if (/[&\?]url\=/.test(src)) { + src = src.replace(/.*[&\?]url\=(.*?)(&.*|$)/, "$1"); + try { + src = decodeURIComponent(src); + } catch (e) {} + } else if (/[&\?]https?:/.test(src)) { + src = src.replace(/.*[&\?](https?:)/, "$1"); + try { + src = decodeURIComponent(src); + } catch (e) {} + } + } + if(src)type='tpRule'; + } + + if(!src && !base64Img){//遍历通配规则 + tprules.find(function(rule,index,array){ + try{ + src=rule.call(img,imgPA); + if(src){ + return true; + }; + }catch(err){ + throwErrorInfo(err); + }; + }); + if(src)type='tpRule'; + } + + if(!src || src==imgSrc){//本图片是否被缩放. + noActual=true; + if(!(imgAS.w==imgCS.w && imgAS.h==imgCS.h)){//如果不是两者完全相等,那么被缩放了. + src=imgSrc; + type='scale'; + if (imgAS.h < prefs.gallery.scaleSmallSize && imgAS.w < prefs.gallery.scaleSmallSize) { + type='scaleSmall'; + } + }else{ + src=imgSrc; + type='force'; + if (img.nodeName == "A") { + description = img.title || img.alt || img.innerText; + } + } + } + + if(!src)return; + + var ret = { + all: matchedRule.all, + src: src, // 得到的src + srcs: srcs, // 多个 src,失败了会尝试下一个 + type: type, // 通过哪种方式得到的 + imgSrc: imgSrc, // 处理的图片的src + iPASrc: iPASrc, // 图片的第一个父a元素的链接地址 + sizeH:imgAS.h, + sizeW:imgAS.w, + imgCS:imgCS, + imgAS:imgAS, + + noActual:noActual, + xhr: xhr, + description: description || img.title || img.alt || (img.parentNode && img.parentNode.title) || '', + + img: img, // 处理的图片 + imgPA: imgPA, // 图片的第一个父a元素 + }; + return ret; + } + + function getMatchedRule() { + return new MatchedRuleC(); + /*var rule = siteInfo.find(function(site, index, array) { + if (site.enabled != false && site.url && toRE(site.url).test(_URL)) { + return true; + } + }); + + return rule;*/ + } + + function MatchedRuleC(){ + this.init(); + } + + const videoExtensions = new Set(['3gpp', 'm4v', 'mkv', 'mp4', 'ogv', 'webm', 'm3u8']); + const audioExtensions = new Set(['flac', 'm4a', 'mp3', 'oga', 'ogg', 'opus', 'wav']); + + function isVideoLink(url) { + if (url.indexOf('.video') !== -1 || url.indexOf('video:') === 0) + return true; + + url = url.replace(/.gif(\?width=\d*&|\?)format=mp4/, '.mp4?').replace(/\/$/, ""); + if (url.lastIndexOf('?') > 0) + url = url.substring(0, url.lastIndexOf('?')); + const ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase(); + + return videoExtensions.has(ext) + || url.indexOf('googlevideo.com/videoplayback') > 0 + || url.indexOf('v.redd.it') > 0; + } + + function isAudioLink(url) { + if (url.indexOf('.audio') !== -1 || url.indexOf('audio:') === 0) + return true; + url = url.replace(/\/$/, ""); + if (url.lastIndexOf('?') > 0) + url = url.substring(0, url.lastIndexOf('?')); + const ext = url.substring(url.lastIndexOf('.') + 1).toLowerCase(); + return audioExtensions.has(ext); + } + + MatchedRuleC.prototype={ + init:function(){ + if (prefs.customRules) { + if (prefs.customRules == `[ +/* + { + name: "Example, can be deleted safely", + url: /^https?:\\/\\/www\\.google\\.com\\/search\\?/, + getImage: function(a) {}, + src: /avatar/i, + r: /\\?.*$/i, + s: '' + } +*/]`) { + prefs.customRules = "[]"; + } + try { + var customRules; + if (prefs.customRules.indexOf("name:") !== -1) { + if (!isunsafe()) { + customRules = unsafeWindow.eval(createScript(prefs.customRules)); + } + } else { + customRules = JSON.parse(prefs.customRules); + } + if (Array.isArray(customRules)) { + customRules.forEach(rule => { + rule.custom = true; + let hasRule = false; + for (let s = 0; s < siteInfo.length; s++) { + if (siteInfo[s].name == rule.name) { + hasRule = true; + for (let si in rule) { + siteInfo[s][si] = rule[si]; + } + break; + } + } + if (!hasRule) siteInfo.unshift(rule); + }) + } + } catch(e) { + console.log("Wrong rule for Picviewer CE+"); + console.log(e); + } + } + + var self = this, r = 0, urlChecked = false; + self.rules=[]; + function searchByTime(){ + setTimeout(()=>{ + let end=r+20; + end=end>siteInfo.length?siteInfo.length:end; + for(;r { + let newSrc = self.replaceByRule(src, site, true); + if (Array.isArray(newSrc)) newSrc = newSrc[0]; + return newSrc && newSrc.length ? newSrc : src; + }; + let reMatch = typeof site.xhr.url === "string" && site.xhr.url.match(/^\/(.*)\/(\w*)$/); + if (reMatch) { + site.xhr.url = toRE(reMatch[1], reMatch[2]); + } else if (Array.isArray(site.xhr.url)) { + let urlRe = toRE(site.xhr.url[0], "i"); + let urlParam = site.xhr.url[1]; + site.xhr.url = (a, p) => { + if (!a || !a.href) return; + if (urlRe.test(a.href)) { + return a.href.replace(urlRe, urlParam);; + } + }; + } + } + if (site.url && !urlChecked) { + urlChecked = true; + if (site.css) { + var style = _GM_addStyle(site.css); + style.id = 'gm-picviewer-site-style'; + } + if (site.lazyAttr) { + self.lazyAttr = site.lazyAttr; + } + if (site.description) { + self.description = site.description; + } + if (site.clickToOpen) { + self.clickToOpen = site.clickToOpen; + } + if (site.ext) { + self.ext = site.ext; + } + if (site.gallery) { + let gallery = site.gallery; + self.gallery = () => { + if (typeof gallery === "string") { + return document.querySelectorAll(gallery); + } else { + return gallery(); + } + }; + } + if (site.video) { + let reMatch = typeof site.video === "string" && site.video.match(/^\/(.*)\/(\w*)$/); + if (reMatch) { + site.video = toRE(reMatch[1], reMatch[2]); + } + self.video = site.video; + } + if (site.audio) { + let reMatch = typeof site.audio === "string" && site.audio.match(/^\/(.*)\/(\w*)$/); + if (reMatch) { + site.audio = toRE(reMatch[1], reMatch[2]); + } + self.audio = site.audio; + } + if (site.getExtSrc) { + self.getExtSrc = site.getExtSrc; + } + if (site.mute) { + self.mute = true; + } + } + self.rules.push(site); + } + } + if(end { + if (a.custom && !b.custom) return -1; + if (!a.custom && b.custom) return 1; + if (a.url && !b.url) return -1; + if (!a.url && b.url) return 1; + return 0; + }); + } + },1); + } + setTimeout(() => { + if (unsafeWindow.pvcepRules && Array.isArray(unsafeWindow.pvcepRules)) { + unsafeWindow.pvcepRules.forEach(rule => { + rule.custom = true; + let hasRule = false; + for (let s = 0; s < siteInfo.length; s++) { + if (siteInfo[s].name == rule.name) { + hasRule = true; + for (let si in rule) { + siteInfo[s][si] = rule[si]; + } + break; + } + } + if (!hasRule) siteInfo.unshift(rule); + }) + } + searchByTime(); + }, 1); + }, + replace:function(str, r, s){ + var results=[],rt; + let reMatch = typeof r === "string" && r.match(/^\/(.*)\/(\w+)$/); + if (reMatch) { + r = toRE(reMatch[1], reMatch[2]); + } + if(Array.isArray(s)){ + s.forEach(_s=>{ + rt=str.replace(r, _s); + if(rt && rt!=str)results.push(rt); + }); + }else{ + rt=str.replace(r, s); + if(rt && rt!=str)return rt; + } + return results; + }, + replaceByRule: function(src, rule, check) { + if (check) { + if (!rule.r || /^data:/i.test(src)) return src; + } + let newSrc; + if (Array.isArray(rule.r)) {//r最多一层 + for (var j = 0; j < rule.r.length; j++) { + var _r = rule.r[j]; + if (_r) { + if (Array.isArray(rule.s)) {//s对上r最多两层 + var _s = rule.s[j]; + newSrc = this.replace(src, _r, _s); + } else { + newSrc = this.replace(src, _r, rule.s); + } + if (newSrc && newSrc.length && newSrc !== src) { + break; + } + } + } + } else { + newSrc = this.replace(src, rule.r, rule.s); + } + return newSrc && newSrc.length ? newSrc : src; + }, + getMode: function(src) { + if (!src || !src.length) return ""; + if (this.video && this.video.test(src)) { + return "video"; + } + if (this.audio && this.audio.test(src)) { + return "audio"; + } + if (isVideoLink(src)) { + return "video"; + } + if (isAudioLink(src)) { + return "audio"; + } + return ""; + }, + getXhrLink: function(a, p) { + var newSrc, rule; + this.xhr = null; + this.xhrLink = false; + for (var i = 0; i < this.rules.length; i++) { + rule = this.rules[i]; + if (rule.src) continue; + if (rule.xhr) { + if (rule.xhr.url) { + if (rule.xhr.url.test) { + if (a && rule.xhr.url.test(a.href)) { + newSrc = a.href; + } + } else if (typeof rule.xhr.url === 'string') { + try { + if (a && a.matches(rule.xhr.url)) { + newSrc = a.href; + } + } catch(e) { + debug(e); + } + } else { + newSrc = rule.xhr.url.call(a, a, p, rule.xhr); + } + if (newSrc) { + this.xhrLink = true; + this.xhr = rule.xhr; + return newSrc; + } + } else if (a) { + newSrc = a.href; + if (newSrc) { + this.xhrLink = true; + this.xhr = rule.xhr; + return newSrc; + } + } + } + } + }, + getImage: function(img, a, p, target) { + var newSrc, rule; + var base64Img = /^data:/i.test(img.src); + this.all = null; + this.xhr = null; + for (var i = 0; i < this.rules.length; i++) { + rule = this.rules[i]; + if (rule.src && !toRE(rule.src).test(img.src)) continue; + if (rule.exclude && toRE(rule.exclude).test(img.src)) continue; + if (rule.xhr) { + if (rule.xhr.url) { + if (rule.xhr.url.test) { + if (a && rule.xhr.url.test(a.href)) { + newSrc = a.href; + } + } else if (typeof rule.xhr.url === 'string') { + try { + if (a && a.matches(rule.xhr.url)) { + newSrc = a.href; + } + } catch(e) { + debug(e); + } + } else { + newSrc = rule.xhr.url.call(target || img, a, p, rule.xhr); + } + if (newSrc) { + this.xhr = rule.xhr; + return newSrc; + } else { + this.xhr = null; + } + } else if (a) { + newSrc = a.href; + } + } + if (base64Img && (!rule.url || !rule.getImage)) continue; + if (newSrc) { + this.xhr = rule.xhr; + return newSrc; + } + if (rule.getImage) { + newSrc = rule.getImage.call(target || img, a, p, rule); + if (newSrc && newSrc.all) { + this.all = newSrc.all; + newSrc = this.all[0]; + } + } else newSrc = null; + if (!base64Img && rule.r && img.src && !Array.isArray(newSrc)) { + if (!newSrc) newSrc = img.src || img.currentSrc; + newSrc = this.replaceByRule(newSrc, rule); + } + if (newSrc && newSrc.length > 0 && newSrc != (img.src || img.currentSrc)) { + debug(rule); + break; + } else newSrc = null; + } + if (newSrc && newSrc.length == 0) newSrc = null; + return newSrc; + } + }; + + var isFrame=window!=window.parent; + var topWindowValid; + var frameSentData; + var frameSentSuccessData; + function handleMessage(e){ + var data=e.data; + if( !data || !data.messageID || data.messageID != messageID )return; + var source=e.source,command,cusEvent; + if(typeof source=='undefined' || source!==window){ + if(!isFrame){ + command=data.command; + switch(command){ + case 'open':{ + if (data.buttonType === 'download') { + downloadImg(data.src, document.title, prefs.saveName); + return; + } + var img=document.createElement('img'); + img.src=data.src; + + imgReady(img,{ + ready:function(){ + LoadingAnimC.prototype.open.call({ + img:img, + data:data.data, + buttonType:data.buttonType, + from:data.from, + }); + }, + }); + }break; + case 'navigateToImg':{ + cusEvent=document.createEvent('CustomEvent'); + cusEvent.initCustomEvent('pv-navigateToImg',false,false,data.exist); + document.dispatchEvent(cusEvent); + }break; + case 'topWindowValid':{ + if(data.from) + window.postMessage({ + messageID:messageID, + command:'topWindowValid_frame', + valid:getBody(document).nodeName.toUpperCase()!='FRAMESET', + to:data.from, + },'*'); + }break; + }; + + }else{ + command=data.command; + switch(command){ + case 'navigateToImg':{ + + if(!frameSentData.unique){ + var unique=GalleryC.prototype.unique(frameSentData); + frameSentData=unique.data; + frameSentData.unique=true; + }; + var targetImg=frameSentData[data.index].img; + var exist=(document.documentElement.contains(targetImg) && unsafeWindow.getComputedStyle(targetImg).display!='none'); + + if(exist){ + if(gallery && gallery.shown){ + gallery.minimize(); + }; + setTimeout(function(){ + GalleryC.prototype.navigateToImg(targetImg); + flashEle(targetImg); + },0); + }; + if (data.from) { + window.postMessage({ + messageID:messageID, + command:'navigateToImg', + exist:exist, + to:data.from, + index:data.index + },'*'); + } + }break; + case 'sendFail':{ + frameSentData=frameSentSuccessData; + }break; + case 'topWindowValid_frame':{ + cusEvent=document.createEvent('CustomEvent'); + cusEvent.initCustomEvent('pv-topWindowValid',false,false,data.valid); + document.dispatchEvent(cusEvent); + }break; + }; + }; + + }; + } + + //页面脚本用来转发消息 + //原因chrome的contentscript无法访问非自己外的别的窗口。都会返回undefined,自然也无法向其他的窗口发送信息,这里用pagescript做个中间代理 + //通讯逻辑..A页面的contentscript发送到A页面的pagescript,pagescript转交给B页面的contentscript + var messageID='pv-0.5106795670312598'; + + var _isunsafe = null; + function isunsafe(){ + if (_isunsafe === null) { + try { + _isunsafe = unsafeWindow.eval(createScript("false")); + } catch (e) { + console.debug("unsafe"); + _isunsafe = true; + } + } + return _isunsafe; + } + function addPageScript() { + + if(isunsafe())return; + var pageScript=document.createElement('script'); + pageScript.id = 'picviewer-page-script'; + + var pageScriptText=function(messageID){ + var frameID=Math.random(); + var frames={ + top:window.top, + }; + + window.addEventListener('message',function(e){ + var data=e.data; + if( !data || !data.messageID || data.messageID != messageID )return;//通信ID认证 + var source=e.source; + if(source===window){//来自contentscript,发送出去,或者干嘛。 + if(data.to){ + data.from=frameID; + frames[data.to].postMessage(data,'*'); + }else{ + switch(data.command){ + case 'getIframeObject':{ + var frameWindow=frames[data.windowId]; + var iframes=document.getElementsByTagName('iframe'); + var iframe; + var targetIframe; + for(var i=iframes.length-1 ; i>=0 ; i--){ + iframe=iframes[i]; + if(iframe.contentWindow===frameWindow){ + targetIframe=iframe; + break; + }; + }; + var cusEvent=document.createEvent('CustomEvent'); + cusEvent.initCustomEvent('pv-getIframeObject',false,false,targetIframe); + document.dispatchEvent(cusEvent); + }break; + }; + }; + + }else{//来自别的窗口的,contentscript可以直接接收,这里保存下来自的窗口的引用 + frames[data.from]=source; + }; + },true) + }; + + pageScript.textContent=createScript('(' + pageScriptText.toString() + ')('+ JSON.stringify(messageID) +')'); + if(document.head)document.head.appendChild(pageScript); + } + + function clickToOpen(data){ + var preventDefault = matchedRule.clickToOpen.preventDefault; + var button = matchedRule.clickToOpen.button || 0; + var alt = !!matchedRule.clickToOpen.alt; + var ctrl = !!matchedRule.clickToOpen.ctrl; + var shift = !!matchedRule.clickToOpen.shift; + var meta = !!matchedRule.clickToOpen.meta; + + function mouseout(){ + document.removeEventListener('mouseout', mouseout, true); + document.removeEventListener(button == 2 ? 'contextmenu' : 'mousedown', click, true); + if(data.imgPA && preventDefault){ + data.imgPA.removeEventListener('click', clickA, true); + }; + }; + + function checkLimit(e){ + if(e.button!=button || + e.altKey!=alt || + e.ctrlKey!=ctrl || + e.shiftKey!=shift || + e.metaKey!=meta){ + return false; + } + return true; + } + + function click(e){ + if(!checkLimit(e))return; + FloatBarC.prototype.open.call({ + data:data, + },e,matchedRule.clickToOpen.type); + if(preventDefault){ + e.preventDefault(); + e.stopPropagation(); + return false; + } + }; + + function clickA(e){//阻止a的默认行为 + if(!checkLimit(e))return; + e.preventDefault(); + }; + + document.addEventListener(button == 2 ? 'contextmenu' : 'mousedown', click, true); + + if(data.imgPA && preventDefault){ + data.imgPA.addEventListener('click', clickA, true); + }; + + setTimeout(function(){//稍微延时。错开由于css hover样式发生的out; + document.addEventListener('mouseout', mouseout, true); + },100); + + return function(){ + mouseout(); + }; + } + + var canclePreCTO,uniqueImgWin,centerInterval,globalFuncEnabled=false,isConfigOpen=false; + function checkGlobalKeydown(e){ + return(!((!e.ctrlKey && e.key !== 'Control' && prefs.floatBar.globalkeys.ctrl)|| + (!e.altKey && e.key !== 'Alt' && prefs.floatBar.globalkeys.alt)|| + (!e.shiftKey && e.key !== 'Shift' && prefs.floatBar.globalkeys.shift)|| + (!e.metaKey && e.key !== 'Meta' && prefs.floatBar.globalkeys.command)|| + (!prefs.floatBar.globalkeys.ctrl && !prefs.floatBar.globalkeys.alt && !prefs.floatBar.globalkeys.shift && !prefs.floatBar.globalkeys.command))); + } + + function checkPreview(e){ + if (isConfigOpen) return false; + let selStr; + try { + selStr = !selectionClientRect && selectionStr; + }catch(e){} + if (selStr && selStr != "\n") return false; + let keyActive=(prefs.floatBar.globalkeys.type == "hold" && checkGlobalKeydown(e)) || + (prefs.floatBar.globalkeys.type == "press" && globalFuncEnabled); + return prefs.floatBar.globalkeys.invertInitShow?!keyActive:keyActive; + } + + var untilMoveTimer, moveHandler, uniqueImgWinInitX, uniqueImgWinInitY; + function waitUntilMove(target, callback) { + if (moveHandler) document.removeEventListener('mousemove', moveHandler, true); + if (untilMoveTimer) clearTimeout(untilMoveTimer); + + moveHandler = e => { + uniqueImgWinInitX = e.clientX; + uniqueImgWinInitY = e.clientY; + if (target != e.target) { + let preRect = target.getBoundingClientRect(); + let nextRect = e.target.getBoundingClientRect(); + if (preRect && nextRect && (preRect.left > nextRect.left || preRect.right < nextRect.right || preRect.top > nextRect.top || preRect.bottom < nextRect.bottom)) { + document.removeEventListener('mousemove', moveHandler, true); + clearTimeout(untilMoveTimer); + } + } + } + document.addEventListener('mousemove', moveHandler, true); + untilMoveTimer = setTimeout(() => { + document.removeEventListener('mousemove', moveHandler, true); + callback(); + }, prefs.floatBar.showDelay || 0) + } + + function checkFloatBar(_target, type, canPreview, clientX, clientY, altKey) { + let target = _target; + if (!target || target.id == "pv-float-bar-container" || + (target.parentNode && (target.parentNode.id == "icons" || target.parentNode.className == "search-jumper-btn")) || + (target.className && + (/^pv\-/.test(target.className) || + target.className == "whx-a" || + target.className == "whx-a-node" || + target.className == "search-jumper-btn" || + target.classList.contains("pv-icon") || + target.classList.contains("ks-imagezoom-lens")))) { + return; + } + if (target.nodeName.toUpperCase() == "PICTURE"){ + target = target.querySelector("img"); + } + if (type == "mousemove") { + if ((uniqueImgWin && !uniqueImgWin.removed && !uniqueImgWin.previewed)) { + uniqueImgWin.followPos(clientX, clientY); + if (!canPreview) { + uniqueImgWin.remove(); + } + return; + } else if (target.nodeName.toUpperCase() != 'IMG' || !canPreview) { + return; + } + } + + // 扩展模式,检查前面一个是否为 img + if (target.nodeName.toUpperCase() != 'IMG' && matchedRule.rules.length > 0 && matchedRule.ext) { + var _type = typeof matchedRule.ext; + if (_type == 'string') { + switch (matchedRule.ext) { + case 'previous': + target = target.previousElementSibling || target; + break; + case 'next': + target = target.nextElementSibling || target; + break; + case 'previous-2': + target = (target.previousElementSibling && + target.previousElementSibling.previousElementSibling) || target; + break; + } + } else if (_type == 'function') { + try { + target = matchedRule.ext(target) || target; + } catch(ex) { + throwErrorInfo(ex); + } + + if (!target) return; + } + } + let bgReg = /.*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; + let bgRegLong = /^\s*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; + let result, targetBg, hasBg = node => { + if(node.nodeName.toUpperCase() == "HTML" || node.nodeName == "#document"){ + return false; + } + if (node.clientWidth <= prefs.floatBar.minSizeLimit.w || node.clientHeight <= prefs.floatBar.minSizeLimit.h) { + return false; + } + targetBg = ""; + let nodeStyle = unsafeWindow.getComputedStyle(node); + + let bg = nodeStyle.backgroundRepeatX != "repeat" && nodeStyle.backgroundRepeatY != "repeat" && nodeStyle.backgroundImage; + if (bg && bg !== "none") { + targetBg = nodeStyle.backgroundImage.match(bg.length > 500 ? bgRegLong : bgReg); + } + if (!targetBg) { + nodeStyle = unsafeWindow.getComputedStyle(node, "::before"); + bg = nodeStyle.backgroundRepeatX != "repeat" && nodeStyle.backgroundRepeatY != "repeat" && nodeStyle.backgroundImage; + if (bg && bg !== "none") { + targetBg = nodeStyle.backgroundImage.match(bg.length > 500 ? bgRegLong : bgReg); + } + } + if (!targetBg) { + nodeStyle = unsafeWindow.getComputedStyle(node, "::after"); + bg = nodeStyle.backgroundRepeatX != "repeat" && nodeStyle.backgroundRepeatY != "repeat" && nodeStyle.backgroundImage; + if (bg && bg !== "none") { + targetBg = nodeStyle.backgroundImage.match(bg.length > 500 ? bgRegLong : bgReg); + } + } + if (targetBg) { + targetBg = targetBg[1].replace(/\\"/g, '"'); + } + return targetBg; + }; + if (target.nodeName.toUpperCase() != 'IMG') { + let nsrc, imgPN, imgPA, imgPE = []; + try { + if (matchedRule.getExtSrc) { + nsrc = matchedRule.getExtSrc.call(target); + } + if (!nsrc && target.href) { + imgPN = target; + let i = 0; + while (imgPN = imgPN.parentNode || imgPN.host) { + if (i++ > 5 || imgPN.nodeName.toUpperCase() == 'BODY') { + break; + } else { + imgPE.push(imgPN); + } + } + nsrc = matchedRule.getXhrLink(target, imgPE); + } + } catch(ex) { + throwErrorInfo(ex); + } + if (nsrc) { + let all; + if (nsrc && nsrc.all) { + all = nsrc.all; + nsrc = all[0]; + } + let src = nsrc, imgSrc = prefs.floatBar.listenBg && hasBg(target) ? targetBg : nsrc; + if (Array.isArray(nsrc) && nsrc.length == 2) { + imgSrc = nsrc[0]; + src = nsrc[1]; + } + if (!matchedRule.xhrLink) { + imgPN = target; + imgPE = []; + do { + if (imgPN.nodeName.toUpperCase() == 'A') { + imgPA = imgPN; + break; + } + } while (imgPN = imgPN.parentNode || imgPN.host); + imgPN = target; + while (imgPN = imgPN.parentNode || imgPN.host) { + if (imgPN.nodeName.toUpperCase() == 'BODY') { + break; + } else { + imgPE.push(imgPN); + } + } + src = matchedRule.getImage(target, imgPA, imgPE) || src; + } + let noActual = src === imgSrc; + result = { + all: all || matchedRule.all, + src: src, + type: matchedRule.xhrLink && noActual ? "link" : "rule", + imgSrc: imgSrc, + noActual: noActual, + img: target, + xhr: matchedRule.xhr + }; + } + } + var checkUniqueImgWin = function() { + let invert = !canPreview && prefs.floatBar.globalkeys.invertInitShow && prefs.floatBar.globalkeys.type == "hold"; + if (canPreview || invert) { + let forceShow = (() => { + if (result.type != "link" && result.type != "rule" && result.src == result.imgSrc) { + if (result.imgAS.w < result.imgCS.w * 1.3 && result.imgAS.h < result.imgCS.h * 1.3) { + if (result.img && result.img.childElementCount) { + if (result.type == "force") return false; + if (prefs.floatBar.globalkeys.invertInitShow) return false; + } + var wSize = getWindowSize(); + if (prefs.floatBar.globalkeys.invertInitShow && result.imgAS.w <= wSize.w && result.imgAS.h <= wSize.h) return false; + } + } + return true; + })(); + if (forceShow) { + if (invert) return false; + } else { + if (!invert) return false; + } + uniqueImgWinInitX = clientX; + uniqueImgWinInitY = clientY; + if (uniqueImgWin && !uniqueImgWin.removed) { + if (uniqueImgWin.src == result.src) return true; + uniqueImgWin.remove(); + } + waitUntilMove(_target, () => { + new LoadingAnimC(result, 'popup', prefs.waitImgLoad, prefs.framesPicOpenInTopWindow); + }); + return true; + } else { + return false; + } + }; + if (!result) { + if (target.nodeName.toUpperCase() != 'IMG' && target.dataset.role == "img") { + let img = target.parentNode.querySelector('img'); + if (img) target = img; + } + if (target.nodeName.toUpperCase() == 'IMAGE') { + let src = target.href && target.href.baseVal; + if (src) { + result = { + src: src, + type: "rule", + imgSrc: src, + noActual: true, + img: target.parentNode + }; + } + } else if (target.nodeName.toUpperCase() != 'IMG') { + if (selectionClientRect && + clientX > selectionClientRect.left && + clientX < selectionClientRect.left + selectionClientRect.width && + clientY > selectionClientRect.top && + clientY < selectionClientRect.top + selectionClientRect.height) { + result = { + src: selectionStr, + type: "link", + imgSrc: selectionStr, + noActual:true, + img: target + }; + checkUniqueImgWin(); + + if (!floatBar) { + floatBar = new FloatBarC(); + } + floatBar.start(result); + + return; + } + let found = false; + if (target.nodeName.toUpperCase() == "AREA") target = target.parentNode; + var broEle, broImg; + if (target.nodeName.toUpperCase() != 'A' && target.parentNode && target.parentNode.style && !/flex|grid|table/.test(getComputedStyle(target.parentNode).display)) { + broEle = target.previousElementSibling; + while (broEle) { + if (broEle.offsetWidth && broEle.offsetWidth > target.offsetWidth>>1) { + if (broEle.nodeName == "IMG") broImg = broEle; + else if (broEle.nodeName == "PICTURE") broImg = broEle.querySelector("img"); + } + if (getComputedStyle(broEle).position !== "absolute") break; + broEle = broEle.previousElementSibling; + } + if (broEle == target) broEle = null; + else if (!broEle) { + broEle = target.nextElementSibling; + while (broEle) { + if (broEle.offsetWidth && broEle.offsetWidth > target.offsetWidth>>1) { + if (broEle.nodeName == "IMG") broImg = broEle; + else if (broEle.nodeName == "PICTURE") broImg = broEle.querySelector("img"); + } + if (getComputedStyle(broEle).position == "absolute") break; + broEle = broEle.nextElementSibling; + } + if (broEle == target) broEle = null; + } + } + if (target.children.length == 1 && !(target.textContent && target.textContent.trim()) && target.children[0].nodeName == "IMG") { + target = target.children[0]; + found = true; + } else if (prefs.floatBar.listenBg && hasBg(target)) { + let src = targetBg, nsrc = src, noActual = true, type = "scale"; + result = { + src: nsrc, + type: type, + imgSrc: src, + noActual:noActual, + img: target + }; + found = true; + } else if (broImg) { + target = broImg; + found = true; + } else if (target.nodeName.toUpperCase() == 'CANVAS') { + let src = target.src || target.dataset.src; + if (src) { + let nsrc = src, noActual = true, type = "scale"; + result = { + src: nsrc, + type: type, + imgSrc: src, + noActual:noActual, + img: target + }; + found = true; + } + } else if (prefs.floatBar.listenBg && broEle && hasBg(broEle)) { + let src = targetBg, nsrc = src, noActual = true, type = "scale"; + result = { + src: nsrc, + type: type, + imgSrc: src, + noActual:noActual, + img: target + }; + found = true; + } else if (target.parentNode) { + let imgs; + if (target.nodeName == 'A') { + imgs = target.querySelectorAll('img'); + } + if (imgs && imgs.length == 1) { + target = imgs[0]; + found = true; + } else if (target.parentNode.nodeName.toUpperCase() == 'IMG') { + target = target.parentNode; + found = true; + } + } + if (!found) { + let checkEle = target; + while(checkEle && !(checkEle.textContent && checkEle.textContent.trim()) && checkEle.children.length === 1) { + checkEle = checkEle.children[0]; + if (checkEle.nodeName === "IMG") { + target = checkEle; + found = true; + break; + } else if (checkEle.nodeName === "PICTURE") { + target = checkEle.querySelector("img"); + found = true; + break; + } else if (prefs.floatBar.listenBg && hasBg(checkEle)) { + let src = targetBg, nsrc = src, noActual = true, type = "scale"; + result = { + src: nsrc, + type: type, + imgSrc: src, + noActual:noActual, + img: checkEle + }; + found = true; + break; + } + } + } + if (!found && target.children && target.children[0] && target.children[0].nodeName.toUpperCase() == 'IMG') { + let img = target.children[0]; + while (img.nextElementSibling && img.nextElementSibling.nodeName.toUpperCase() == 'IMG') { + img = img.nextElementSibling; + } + let rect = img.getBoundingClientRect(); + + if (clientY >= rect.top && clientY <= rect.bottom && clientX >= rect.left && clientX <= rect.right) { + target = img; + found = true; + } + } + if (!found && document.elementsFromPoint) { + let elements = document.elementsFromPoint(clientX, clientY); + let checkLen = Math.min(elements.length, 10); + for (let i = 0; i < checkLen; i++) { + let ele = elements[i]; + if (!ele) continue; + if (/^img$/i.test(ele.nodeName)) { + target = ele; + result = null; + found = true; + break; + } else if (prefs.floatBar.listenBg && hasBg(ele)) { + target = ele; + let src = targetBg, nsrc = src, noActual = true, type = "scale"; + result = { + src: nsrc, + type: type, + imgSrc: src, + noActual:noActual, + img: target + }; + found = true; + break; + } else if (target.nodeName.toUpperCase() != 'A' && ele.nodeName.toUpperCase() == 'CANVAS') { + let src = ele.src || ele.dataset.src; + if (src) { + target = ele; + let nsrc = src, noActual = true, type = "scale"; + result = { + src: nsrc, + type: type, + imgSrc: src, + noActual:noActual, + img: target + }; + found = true; + break; + } + } + } + } + if (!found && target.shadowRoot) { + let imgs = target.shadowRoot.querySelectorAll('img'); + if (imgs.length === 1) target = imgs[0]; + } + if (!found && prefs.floatBar.listenBg && hasBg(target.parentNode)) { + target = target.parentNode; + let src = targetBg, nsrc = src, noActual = true, type = "scale"; + result = { + src: nsrc, + type: type, + imgSrc: src, + noActual:noActual, + img: target + }; + found = true; + } + if (result && !/^data:/i.test(result.src)) { + if (matchedRule.rules.length > 0 && target.nodeName.toUpperCase() != 'IMG') { + let src = result.src, img = {src: src}, type, imgSrc = src; + try { + let imgPN=target; + let imgPA,imgPE=[]; + while(imgPN=imgPN.parentNode || imgPN.host){ + if(imgPN.nodeName.toUpperCase()=='A'){ + imgPA=imgPN; + break; + } + } + imgPN=target; + while(imgPN=imgPN.parentNode || imgPN.host){ + if(imgPN.nodeName.toUpperCase()=='BODY'){ + break; + }else{ + imgPE.push(imgPN); + } + } + let newSrc = matchedRule.getImage(img, imgPA, imgPE, target); + if (newSrc && imgSrc != newSrc) { + let srcs, description; + src = newSrc; + if (Array.isArray(src)) { + srcs = src; + src = srcs.shift(); + } + type = 'rule'; + + if (matchedRule.description) { + let desc = matchedRule.description, attr; + if (Array.isArray(desc) && desc.length === 2) { + attr = desc[1]; + desc = desc[0]; + } + var node = getElementMix(desc, img); + if (node) { + description = attr ? node.getAttribute(attr) : (node.getAttribute('title') || node.textContent); + } + } + result.all = matchedRule.all; + result.src = src; + result.type = type; + result.noActual = false; + result.xhr = matchedRule.xhr; + result.description = description || ''; + } + } catch(err) {} + if (result.type != "rule") { + tprules.find(function(rule, index, array) { + try { + src = rule.call(img); + if (src) { + return true; + }; + } catch(err) { + } + }); + if (src && src != imgSrc) { + result.src = src; + result.type = "tpRule"; + result.noActual = false; + } + } + } + } + } + } + + if (!result && target.nodeName.toUpperCase() != 'IMG') { + let i = 0; + while(target) { + if (i++ > 5) { + target = null; + break; + } + if ((target.nodeName == 'A' || target.nodeName == 'a') && imageReg.test(target.href)) { + break; + } + target = target.parentNode; + } + if (target) { + let src = target.href; + if (/[&\?]url\=/.test(src)) { + src = src.replace(/.*[&\?]url\=(.*?)(&.*|$)/, "$1"); + try { + src = decodeURIComponent(src); + } catch (e) {} + } else if (/[&\?]https?:/.test(src)) { + src = src.replace(/.*[&\?](https?:)/, "$1"); + try { + src = decodeURIComponent(src); + } catch (e) {} + } + result = { + src: src, + type: "link", + imgSrc: src, + noActual:true, + img: target, + description: target.title || target.innerText + }; + checkUniqueImgWin(); + + if (!floatBar) { + floatBar = new FloatBarC(); + } + floatBar.start(result); + } + return; + } + + let sizeHide = false; + if (!result) { + pretreatment(target) + result = findPic(target); + if (!result) return; + } + + if (result) { + if (!result.imgAS && !result.imgCS) { + let sizeInfo = { + w: result.img.offsetWidth || result.img.scrollWidth || target.offsetWidth || target.scrollWidth, + h: result.img.offsetHeight || result.img.scrollHeight || target.offsetHeight || target.scrollHeight + } + result.imgAS = sizeInfo; + result.imgCS = sizeInfo; + } + if (prefs.floatBar.showWithRules && (result.type == "rule" || result.type == "tpRule")) { + } else if (!(result.imgAS.w == result.imgCS.w && result.imgAS.h == result.imgCS.h)) {//如果不是两者完全相等,那么被缩放了. + if (prefs.floatBar.sizeLimitOr) { + if (result.imgCS.h <= prefs.floatBar.minSizeLimit.h && result.imgCS.w <= prefs.floatBar.minSizeLimit.w) {//最小限定判断. + sizeHide = true; + } + }else{ + if (result.imgCS.h <= prefs.floatBar.minSizeLimit.h || result.imgCS.w <= prefs.floatBar.minSizeLimit.w) {//最小限定判断. + sizeHide = true; + } + } + } else { + if (prefs.floatBar.sizeLimitOr) { + if (result.imgCS.w <= prefs.floatBar.forceShow.size.w && result.imgCS.h <= prefs.floatBar.forceShow.size.h) { + sizeHide = true; + } + } else { + if (result.imgCS.w <= prefs.floatBar.forceShow.size.w || result.imgCS.h <= prefs.floatBar.forceShow.size.h) { + sizeHide = true; + } + } + } + debug(result); + if (!result.noActual) { + if (!result.srcs) { + result.srcs = [result.imgSrc]; + } else { + if (result.imgSrc && result.srcs.join(" ").indexOf(result.imgSrc) == -1) { + result.srcs.push(result.imgSrc); + } + } + } + if (!floatBar) { + floatBar = new FloatBarC(); + } + if (result.type == 'rule' && matchedRule.clickToOpen && matchedRule.clickToOpen.enabled) { + if (canclePreCTO) {//取消上次的,防止一次点击打开多张图片 + canclePreCTO(); + } + canclePreCTO = clickToOpen(result); + } + + let hide = sizeHide || (prefs.floatBar.position == "hide" ? true : altKey); + result.hide = hide; + let canShow = floatBar.start(result); + if (!checkUniqueImgWin() && canShow) { + if (floatBar.floatBar.style.opacity == 0) { + floatBar.floatBar.style.opacity = ""; + } + floatBar.floatBar.style.display = "initial"; + } + } + } + + var checkFloatBarTimer, initMouse = false; + function globalMouseoverHandler(e) { + if (galleryMode) return;//库模式全屏中...... + if (e.target == ImgWindowC.overlayer) return; + let canPreview = checkPreview(e); + if (e.type == "mousemove") { + if (!initMouse) { + initMouse = true; + return; + } + if ((uniqueImgWin && !uniqueImgWin.removed && !uniqueImgWin.previewed)) { + if (canPreview || prefs.floatBar.globalkeys.invertInitShow) { + uniqueImgWinInitX = e.clientX; + uniqueImgWinInitY = e.clientY; + uniqueImgWin.followPos(uniqueImgWinInitX, uniqueImgWinInitY); + } else { + uniqueImgWin.remove(); + } + return; + } else { + if (!canPreview) return; + let target = e.target; + if (target.nodeName == "PICTURE"){ + target = target.lastElementChild || target; + } + if (target.nodeName != 'IMG') return; + } + } + if (!initMouse) return; + clearTimeout(checkFloatBarTimer); + checkFloatBarTimer = setTimeout(function() { + if (!e || !e.target || !e.target.parentNode) return; + if (gallery && gallery.shown) return; + checkFloatBar(e.target, e.type, canPreview, e.clientX, e.clientY, e.altKey); + }, 50); + } + + var selectionClientRect, selectionStr, selectionChanging = false; + document.addEventListener('selectionchange', e => { + if (selectionChanging) return; + selectionChanging = true; + setTimeout(() => { + selectionChanging = false; + const selection = window.getSelection(); + selectionStr = selection.toString(); + if (selectionStr && selectionStr.length < 500) selectionStr = selectionStr.trim().replace(/^t?t?p?s?:/, "https:"); + else selectionStr = ''; + if (selectionStr && imageReg.test(selectionStr)) { + const range = selection.getRangeAt(0); + selectionClientRect = range.getBoundingClientRect(); + } else { + selectionClientRect = null; + } + }, 300); + }); + + document.addEventListener('visibilitychange', e => { + initMouse = false; + }); + + var curLoadingMedia; + document.addEventListener('securitypolicyviolation', (e) => { + if (!e.violatedDirective.includes('media-src')) { + return; + } + if (curLoadingMedia && curLoadingMedia.src == e.blockedURI) { + _GM_xmlhttpRequest({ + method: 'GET', + url: curLoadingMedia.src, + responseType: 'blob', + onload: function(response) { + const blobUrl = URL.createObjectURL(response.response); + + curLoadingMedia.src = blobUrl; + curLoadingMedia.load(); + curLoadingMedia.play().catch(err => console.warn('[CSP Fixer] Autoplay after fix was blocked.', err)); + + const releaseBlob = () => URL.revokeObjectURL(blobUrl); + curLoadingMedia.addEventListener('ended', releaseBlob); + window.addEventListener('beforeunload', releaseBlob); + } + }); + } + }); + function createVideo() { + let media = document.createElement('video'); + media.addEventListener('error', e => { + if (/^blob:/.test(media.src)) return; + _GM_xmlhttpRequest({ + method: 'GET', + url: media.src, + responseType: 'blob', + onload: function(response) { + const blobUrl = URL.createObjectURL(response.response); + + media.src = blobUrl; + media.load(); + media.play().catch(err => console.warn('[CSP Fixer] Autoplay after fix was blocked.', err)); + + const releaseBlob = () => URL.revokeObjectURL(blobUrl); + media.addEventListener('ended', releaseBlob); + window.addEventListener('beforeunload', releaseBlob); + curLoadingMedia = null; + } + }); + }); + return media; + } + + async function input(sel, v) { + await new Promise((resolve) => { + let checkInv = setInterval(() => { + let input = document.querySelector(sel); + if (input) { + input.focus(); + input.scrollIntoView(); + let lastValue = input.value; + if (input.nodeName == "INPUT") { + var nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set; + nativeInputValueSetter.call(input, v); + } else { + var nativeTextareaValueSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value").set; + nativeTextareaValueSetter.call(input, v); + } + let event = new Event('focus', { bubbles: true }); + input.dispatchEvent(event); + event = new Event('input', { bubbles: true }); + let tracker = input._valueTracker; + if (tracker) { + tracker.setValue(lastValue); + } + input.dispatchEvent(event); + event = new Event('change', { bubbles: true }); + input.dispatchEvent(event); + clearInterval(checkInv); + resolve(); + } + }, 100); + }); + } + + function emuClick(btn){ + if(!PointerEvent)return btn.click(); + let eventParam={ + isTrusted: true, + altKey: false, + azimuthAngle: 0, + bubbles: true, + button: 0, + buttons: 0, + clientX: 1, + clientY: 1, + cancelBubble: false, + cancelable: true, + composed: true, + ctrlKey: false, + defaultPrevented: false, + detail: 1, + eventPhase: 2, + fromElement: null, + height: 1, + isPrimary: false, + metaKey: false, + pointerId: 1, + pointerType: "mouse", + pressure: 0, + relatedTarget: null, + returnValue: true, + shiftKey: false, + toElement: null, + twist: 0, + which: 1 + }; + btn.focus(); + var mouseclick = new PointerEvent("mouseover",eventParam); + btn.dispatchEvent(mouseclick); + mouseclick = new PointerEvent("pointerover",eventParam); + btn.dispatchEvent(mouseclick); + mouseclick = new PointerEvent("mousedown",eventParam); + btn.dispatchEvent(mouseclick); + mouseclick = new PointerEvent("pointerdown",eventParam); + btn.dispatchEvent(mouseclick); + mouseclick = new PointerEvent("mouseup",eventParam); + btn.dispatchEvent(mouseclick); + mouseclick = new PointerEvent("pointerup",eventParam); + btn.dispatchEvent(mouseclick); + btn.click(); + } + + async function clickEle(sel, failAction) { + await new Promise((resolve) => { + let checkInv = setInterval(() => { + let ele = document.querySelector(sel); + if (ele) { + clearInterval(checkInv); + emuClick(ele); + resolve(); + }else if(failAction) { + failAction(); + } + }, 100); + }); + } + + async function sleep(time) { + await new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, time); + }) + } + + function isKeyDownEffectiveTarget(target) { + var localName = (target.shadowRoot ? (target.shadowRoot.activeElement || target) : target).localName; + + // 确保光标不是定位在文字输入框或选择框 + if (localName == 'textarea' || localName == 'input' || localName == 'select'){ + return false; + } + + // 视频播放器 + if (localName == 'object' || localName == 'embed'){ + return false; + } + + // 百度贴吧回复输入的问题 + if (target.getAttribute('contenteditable') == 'true'){ + return false; + } + + return true; + } + + async function openGallery(){ + if(!gallery){ + gallery=new GalleryC(); + gallery.data=[]; + } + var allData=await gallery.getAllValidImgs(); + if(allData.length<1)return; + gallery.data=allData; + gallery.load(gallery.data); + return gallery; + } + + function getActiveElement(root) { + const activeEl = root.activeElement; + if (!activeEl) { + return null; + } + if (activeEl.shadowRoot) { + return getActiveElement(activeEl.shadowRoot); + } else { + return activeEl; + } + } + + function inputActive(doc) { + let activeEl = getActiveElement(doc); + if (activeEl && + ((/INPUT|TEXTAREA/i.test(activeEl.nodeName) && + activeEl.getAttribute("aria-readonly") != "true" + ) || + activeEl.contentEditable == 'true' + ) + ) { + return true; + } else { + while (activeEl && activeEl.nodeName) { + if (activeEl.contentEditable == 'true') return true; + if (activeEl.nodeName.toUpperCase() == 'BODY') { + break; + } + activeEl = activeEl.parentNode; + } + } + return false; + } + + function keydown(event) { + + //if (ImgWindowC.showing) return; + if (gallery && gallery.shown) return; + if (inputActive(document)) { + return; + } + var key = event.key; + if(checkGlobalKeydown(event)){ + if(prefs.floatBar.keys.enable && key==prefs.floatBar.keys.gallery){ + openGallery(); + event.stopPropagation(); + event.preventDefault(); + globalFuncEnabled = !globalFuncEnabled; + return true; + }else if((!gallery || (!gallery.shown && !gallery.minimized)) && prefs.floatBar.globalkeys.type == "press"){ + globalFuncEnabled = !globalFuncEnabled; + return true; + } + } + if (!prefs.floatBar.keys.enable){ + return false; + } + + if (event) { + if (event.ctrlKey || event.metaKey) return false; + if (window.getSelection().toString()) return false; + } + if (floatBar && isKeyDownEffectiveTarget(event.target)) { + Object.keys(prefs.floatBar.keys).some(function(action) { + if (action == 'enable' || action == 'search') return; + if (key == prefs.floatBar.keys[action]) { + floatBar.open(event, action); + return true; + } + }); + } + } + + function keyup(event) { + let isFuncKey = !event.isTrusted || event.key == 'Alt' || event.key == 'Control' || event.key == 'Meta'; + if(isFuncKey && (prefs.floatBar.globalkeys.type == "hold" || !checkPreview(event)) && (uniqueImgWin && !uniqueImgWin.removed)){ + clearTimeout(checkFloatBarTimer); + if(prefs.floatBar.globalkeys.closeAfterPreview){ + if (uniqueImgWin) { + uniqueImgWin.remove(); + } + }else{ + uniqueImgWin.focus(); + uniqueImgWin.imgWindow.classList.remove("pv-pic-window-transition-all"); + uniqueImgWin.imgWindow.classList.remove("preview"); + uniqueImgWin.previewed=true; + uniqueImgWin = null; + } + } + } + + function createEleFromJson(json) { + let collection = document.createDocumentFragment(); + json.forEach(data => { + if (/^script/i.test(data.node)) return; + let ele = document.createElement(data.node); + if (data.text) { + ele.innerText = data.text; + } + if (data.attr) { + Object.keys(data.attr).forEach(key => { + if (/^on/i.test(key)) return; + ele.setAttribute(key, data.attr[key]); + }); + } + if (data.children) { + let children = createEleFromJson(data.children); + ele.appendChild(children); + } + collection.appendChild(ele); + }); + return collection; + } + + window.addEventListener('message', handleMessage, true); + + addPageScript(); + + document.addEventListener('keyup', keyup, false); + document.addEventListener('mouseenter', globalMouseoverHandler, true); + document.addEventListener('mousemove', globalMouseoverHandler, true); + + document.addEventListener('mouseout',e=>{ + if (e.relatedTarget == ImgWindowC.overlayer) return; + if(uniqueImgWin && !uniqueImgWin.removed){ + if(checkPreview(e)){ + let showArea=uniqueImgWin.data.img.getBoundingClientRect(); + if(e.clientX < showArea.left + 20 || + e.clientX > showArea.right - 20 || + e.clientY < showArea.top + 20 || + e.clientY > showArea.bottom - 20){ + uniqueImgWin && uniqueImgWin.remove(); + } + } + } + }, true); + var editSitesFunc={ + "Lunapic": (src, initOpen) => { + _GM_openInTab('https://www.lunapic.com/editor/index.php?action=url&url=' + src, {active:true}); + }, + "Pixlr easy": async (src, initOpen) => { + if(initOpen){ + storage.setItem("editUrl", src); + _GM_openInTab('https://pixlr.com/x/', {active:true}); + }else{ + storage.setItem("editUrl", ""); + if(/^https:\/\/pixlr\.com\//.test(location.href)){ + await sleep(1000); + await clickEle('#splash-file-menu'); + await clickEle('#splash-file-url'); + await input('#image-url', src); + await clickEle('.dialog>.buttons>a.button.positive'); + } + } + }, + "Pixlr advanced": async (src, initOpen) => { + if(initOpen){ + storage.setItem("editUrl", src); + _GM_openInTab('https://pixlr.com/e/', {active:true}); + }else{ + storage.setItem("editUrl", ""); + if(/^https:\/\/pixlr\.com\//.test(location.href)){ + await sleep(1000); + await clickEle('#splash-file-menu'); + await clickEle('#splash-file-url'); + await input('#image-url', src); + await clickEle('.dialog>.buttons>a.button.positive'); + } + } + }, + "Photopea": async (src, initOpen) => { + if(initOpen){ + storage.setItem("editUrl", src); + _GM_openInTab('https://www.photopea.com/', {active:true}); + }else{ + storage.setItem("editUrl", ""); + if(/^https:\/\/www\.photopea\.com\//.test(location.href)){ + await sleep(1000); + await clickEle('.topbar>span>button'); + await clickEle('.cmanager>.contextpanel>div:nth-child(4)'); + await clickEle('.cmanager>div:last-child>div:nth-child(3)'); + await input('span.fitem.tinput>input', src); + await clickEle('.form>button'); + } + } + } + }; + var editSitesName={}; + for(let key in editSitesFunc){ + editSitesName[key]=key; + } + var newsInited = false, newsNode = null; + + initLang(); + var customLangOption={ + 'auto': i18n("defaultLang") + }; + for(let key in langList){ + customLangOption[key]=langList[key]; + } + GM_config.init({ + id: 'pv-prefs', + title: GM_config.create('a', { + href: 'https://greasyfork.org/scripts/24204-picviewer-ce', + target: '_blank', + textContent: 'Picviewer CE+ '+i18n("config"), + title: i18n("openHomePage") + }), + isTabs: true, + skin: 'tab', + frameStyle: { + minWidth: "350px", + width: ((visualLength((i18n("floatBar") + i18n("magnifier") + i18n("gallery") + i18n("imgWindow") + i18n("others")),"14px","arial,tahoma,myriad pro,sans-serif") + 250) || 480) + 'px', + zIndex:'2147483648', + margin: '1px', + border: '2px solid rgb(0, 0, 0)' + }, + css: [ + "#pv-prefs input[type='text'] { width: 50px; } ", + "#pv-prefs input[type='number'] { width: 50px; } ", + "#pv-prefs .inline .config_var { margin-left: 6px; }", + "#pv-prefs label.size { width: 205px; }", + "#pv-prefs span.sep-x { margin-left: 0px !important; }", + "#pv-prefs label.sep-x { margin-right: 5px; }", + "#pv-prefs label.floatBar-key { margin-left: 20px; width: 100px; }", + "#pv-prefs input.color { width: 120px; }", + "#pv-prefs input.order { width: 250px; }", + "#pv-prefs .config_header>a { border-bottom: solid 2px; }", + "#pv-prefs a:hover { color: #9f9f9f; }", + "#pv-prefs a { color: black; }", + "#pv-prefs .section_header_holder { padding-right: 10px; }", + "#pv-prefs textarea { width: 100%; }", + "#pv-prefs .nav-tabs { white-space: nowrap; width: fit-content; max-width: 100%; margin: 20 auto; display: flex; overflow-x: auto; overflow-y: visible; }", + ].join('\n'), + fields: { + // 浮动工具栏 + 'floatBar.position': { + label: i18n("position"), + title: i18n("positionTips"), + type: 'select', + options: { + 'top left': i18n("topLeft"), + 'top right': i18n("topRight"), + 'bottom right': i18n("bottomRight"), + 'bottom left': i18n("bottomLeft"), + 'top center': i18n("topCenter"), + 'bottom center': i18n("bottomCenter"), + 'hide': i18n("hide") + }, + "default": prefs.floatBar.position, + section: [i18n("floatBar")], + }, + 'floatBar.stayOut': { + label: i18n("stayOut"), + type: 'checkbox', + "default": prefs.floatBar.stayOut, + line: 'start' + }, + 'floatBar.stayOutOffsetX': { + label: 'X:', + type: 'int', + "default": prefs.floatBar.stayOutOffsetX + }, + 'floatBar.stayOutOffsetY': { + label: 'Y:', + type: 'int', + "default": prefs.floatBar.stayOutOffsetY, + after: ' '+i18n("px"), + line: 'end' + }, + 'floatBar.showDelay': { + label: i18n("showDelay"), + type: 'int', + "default": prefs.floatBar.showDelay, + after: ' '+i18n("ms"), + }, + 'floatBar.hideDelay': { + label: i18n("hideDelay"), + type: 'int', + className: 'hideDelay', + "default": prefs.floatBar.hideDelay, + after: ' '+i18n("ms") + }, + 'floatBar.forceShow.size.w': { + label: i18n("forceShow"), + type: 'int', + className: 'size', + "default": prefs.floatBar.forceShow.size.w, + title: i18n("forceShowTip"), + line: 'start', + }, + 'floatBar.forceShow.size.h': { + label: ' x ', + type: 'int', + className: 'sep-x', + after: ' '+i18n("px"), + "default": prefs.floatBar.forceShow.size.h, + line: 'end', + }, + 'floatBar.minSizeLimit.w': { + label: i18n("minSizeLimit"), + type: 'int', + className: 'size', + "default": prefs.floatBar.minSizeLimit.w, + title: i18n("minSizeLimitTip"), + line: 'start', + }, + 'floatBar.minSizeLimit.h': { + label: ' x ', + type: 'int', + className: 'sep-x', + after: ' '+i18n("px"), + "default": prefs.floatBar.minSizeLimit.h, + line: 'end', + }, + 'floatBar.sizeLimitOr': { + label: i18n("sizeLimitOr"), + type: "checkbox", + "default": false + }, + 'floatBar.showWithRules': { + label: i18n("showWithRules"), + type: "checkbox", + "default": prefs.floatBar.showWithRules, + title: i18n("showWithRulesTip"), + }, + 'floatBar.butonOrder': { + label: i18n("butonOrder"), + type: 'text', + className: 'order', + title: 'actual,current,gallery,magnifier,download', + "default": prefs.floatBar.butonOrder.join(', '), + }, + 'floatBar.additionalFeature': { + label: i18n("additionalFeature"), + type: 'select', + options: { + 'copy': i18n("copy"), + 'copyImg': i18n("copyImg"), + 'open': i18n("openInNewTab") + }, + "default": prefs.floatBar.additionalFeature || 'open' + }, + 'floatBar.invertAdditionalFeature': { + label: i18n("invertAdditionalFeature"), + type: 'checkbox', + "default": prefs.floatBar.invertAdditionalFeature + }, + 'floatBar.listenBg': { + label: i18n("listenBg"), + type: 'checkbox', + "default": prefs.floatBar.listenBg, + title: i18n("listenBgTip") + }, + 'floatBar.globalkeys.ctrl': { + label: i18n("globalkeys"), + type: 'checkbox', + after: "CTRL +", + "default": true, + line: 'start' + }, + 'floatBar.globalkeys.alt': { + after: "ALT +", + type: 'checkbox', + className: 'sep-x', + "default": false, + }, + 'floatBar.globalkeys.shift': { + after: "SHIFT +", + type: 'checkbox', + className: 'sep-x', + "default": false, + }, + 'floatBar.globalkeys.command': { + after: "META", + type: 'checkbox', + className: 'sep-x', + "default": false, + line: 'end', + }, + 'floatBar.globalkeys.type': { + label: i18n("globalkeysType"), + type: 'select', + options: { + 'press': i18n("globalkeysPress"), + 'hold': i18n("globalkeysHold") + }, + "default": prefs.floatBar.globalkeys.type + }, + 'floatBar.globalkeys.invertInitShow': { + label: i18n("initShow"), + type: 'checkbox', + "default": prefs.floatBar.globalkeys.invertInitShow + }, + 'floatBar.globalkeys.closeAfterPreview': { + label: i18n("closeAfterPreview"), + type: 'checkbox', + "default": prefs.floatBar.globalkeys.closeAfterPreview + }, + 'floatBar.previewMaxSizeW': { + label: i18n("previewMaxSize"), + type: 'int', + className: 'size', + "default": prefs.previewMaxSizeW || 0, + title: i18n("previewMaxSizeTip"), + line: 'start', + }, + 'floatBar.previewMaxSizeH': { + label: ' x ', + type: 'int', + className: 'sep-x', + after: ' '+i18n("px"), + "default": prefs.previewMaxSizeH || 0, + line: 'end', + }, + 'floatBar.globalkeys.previewFollowMouse': { + label: i18n("previewFollowMouse"), + type: 'checkbox', + "default": prefs.floatBar.globalkeys.previewFollowMouse + }, + // 按键 + 'floatBar.keys.enable': { + label: i18n("keysEnable"), + type: 'checkbox', + "default": prefs.floatBar.keys.enable + }, + 'floatBar.keys.actual': { + label: i18n("keysActual"), + type: 'text', + className: 'floatBar-key', + "default": prefs.floatBar.keys.actual, + title: i18n("keysActualTip") + }, + /*'floatBar.keys.search': { + label: i18n("keysSearch"), + type: 'text', + className: 'floatBar-key', + "default": prefs.floatBar.keys.search, + title: i18n("keysSearchTip") + },*/ + 'floatBar.keys.current': { + label: i18n("keysCurrent"), + type: 'text', + className: 'floatBar-key', + "default": prefs.floatBar.keys.current, + title: i18n("keysCurrentTip") + }, + 'floatBar.keys.magnifier': { + label: i18n("keysMagnifier"), + type: 'text', + className: 'floatBar-key', + "default": prefs.floatBar.keys.magnifier, + title: i18n("keysMagnifierTip") + }, + 'floatBar.keys.gallery': { + label: i18n("keysGallery"), + type: 'text', + className: 'floatBar-key', + "default": prefs.floatBar.keys.gallery, + title: i18n("keysGalleryTip") + }, + 'floatBar.keys.download': { + label: i18n("download"), + type: 'text', + className: 'floatBar-key', + "default": prefs.floatBar.keys.download + }, + 'floatBar.disableKeySites': { + label: i18n("disableKeySites"), + type: 'textarea', + "default": prefs.floatBar.disableKeySites + }, + + // 放大镜 + 'magnifier.radius': { + label: i18n("magnifierRadius"), + type: 'int', + "default": prefs.magnifier.radius, + section: [i18n("magnifier")], + after: ' '+i18n("px") + }, + 'magnifier.wheelZoom.enabled': { + label: i18n("magnifierWheelZoomEnabled"), + type: 'checkbox', + "default": prefs.magnifier.wheelZoom.enabled, + }, + 'magnifier.wheelZoom.scaleImage': { + label: i18n("magnifierScaleImage"), + type: 'checkbox', + "default": prefs.magnifier.wheelZoom.scaleImage !== false, + }, + 'magnifier.wheelZoom.ctrl': { + label: '', + type: 'checkbox', + after: "CTRL +", + "default": false, + line: 'start' + }, + 'magnifier.wheelZoom.alt': { + after: "ALT +", + type: 'checkbox', + className: 'sep-x', + "default": false, + }, + 'magnifier.wheelZoom.shift': { + after: "SHIFT +", + type: 'checkbox', + className: 'sep-x', + "default": false, + }, + 'magnifier.wheelZoom.meta': { + after: "META", + type: 'checkbox', + className: 'sep-x', + "default": false, + line: 'end', + }, + 'magnifier.wheelZoom.range': { + label: i18n("magnifierWheelZoomRange"), + type: 'textarea', + "default": prefs.magnifier.wheelZoom.range.join(', '), + }, + + // 图库 + 'gallery.defaultSizeLimit.w': { + label: i18n("defaultSizeLimit"), + type: 'int', + className: 'size', + section: [i18n("gallery")], + "default": prefs.gallery.defaultSizeLimit.w, + line: 'start', + }, + 'gallery.defaultSizeLimit.h': { + label: ' x ', + type: 'int', + className: 'sep-x', + after: ' '+i18n("px"), + "default": prefs.gallery.defaultSizeLimit.h, + line: 'end', + }, + 'gallery.fitToScreen': { + label: i18n("galleryFitToScreen"), + type: 'checkbox', + "default": prefs.gallery.fitToScreen, + title: i18n("galleryFitToScreenTip"), + line: 'start', + }, + 'gallery.fitToScreenSmall': { + label: i18n("galleryFitToScreenSmall"), + type: 'checkbox', + "default": prefs.gallery.fitToScreenSmall, + line: 'end', + }, + 'gallery.scrollEndToChange': { + label: i18n("galleryScrollEndToChange"), + type: 'checkbox', + "default": prefs.gallery.scrollEndToChange, + title: i18n("galleryScrollEndToChangeTip") + }, + 'gallery.backgroundColor': { + label: i18n("backgroundColor"), + type: 'text', + className: 'color', + "default": prefs.gallery.backgroundColor || 'rgba(20,20,20,0.75)', + line: 'end' + }, + 'gallery.exportType': { + label: i18n("galleryExportType"), + type: 'select', + options: { + 'grid': i18n("grid"), + 'gridBig': i18n("gridBig"), + 'list': i18n("list") + }, + "default": prefs.gallery.exportType, + }, + 'gallery.loadMore': { + label: i18n("galleryAutoLoad"), + type: 'checkbox', + "default": prefs.gallery.loadMore + }, + 'gallery.loadAll': { + label: i18n("galleryLoadAll"), + type: 'checkbox', + "default": prefs.gallery.loadAll, + title: i18n("galleryLoadAllTip") + }, + 'gallery.viewmoreEndless': { + label: i18n("viewmoreEndless"), + type: 'checkbox', + "default": prefs.gallery.viewmoreEndless + }, + 'gallery.downloadWithZip': { + label: i18n("galleryDownloadWithZip"), + type: 'checkbox', + "default": prefs.gallery.downloadWithZip + }, + 'gallery.downloadGap': { + label: i18n("galleryDownloadGap"), + type: 'int', + "default": prefs.gallery.downloadGap, + after: ' ms', + }, + 'gallery.formatConversion': { + label: i18n("formatConversion"), + type: 'textarea', + title: 'webp>png\nx-icon>png', + "default": prefs.gallery.formatConversion || '' + }, + 'gallery.aria2Host': { + label: i18n("aria2Host"), + type: 'text', + className: 'order', + "default": prefs.gallery.aria2Host || 'http://localhost:6800', + after: '/jsonrpc' + }, + 'gallery.aria2Token': { + label: i18n("aria2Token"), + type: 'text', + "default": prefs.gallery.aria2Token || '' + }, + 'gallery.scaleSmallSize': { + label: i18n("galleryScaleSmallSize1"), + type: 'int', + "default": prefs.gallery.scaleSmallSize, + after: i18n("galleryScaleSmallSize2") + }, + 'gallery.showSmallSize':{ + label: i18n("galleryShowSmallSize"), + type: 'checkbox', + "default": prefs.gallery.showSmallSize + }, + 'gallery.transition': { + label: i18n("galleryTransition"), + type: 'checkbox', + "default": prefs.gallery.transition + }, + 'gallery.disableArrow': { + label: i18n("galleryDisableArrow"), + type: 'checkbox', + "default": prefs.gallery.disableArrow + }, + 'gallery.sidebarPosition': { + label: i18n("gallerySidebarPosition"), + type: 'select', + options: { + 'bottom': i18n("bottom"), + 'right': i18n("right"), + 'left': i18n("left"), + 'top': i18n("top") + }, + "default": prefs.gallery.sidebarPosition, + line: 'start', + }, + 'gallery.sidebarSize': { + label: i18n("gallerySidebarSize"), + type: 'int', + "default": prefs.gallery.sidebarSize, + title: i18n("gallerySidebarSizeTip"), + after: ' '+i18n("px"), + line: 'end', + }, + 'gallery.max': { + label: i18n("galleryMax1"), + type: 'number', + "default": prefs.gallery.max, + after: i18n("galleryMax2") + }, + 'gallery.autoZoom': { + label: i18n("galleryAutoZoom"), + type: 'checkbox', + "default": prefs.gallery.autoZoom, + title: i18n("galleryAutoZoomTip") + }, + 'gallery.descriptionLength': { + label: i18n("galleryDescriptionLength1"), + type: 'int', + "default": prefs.gallery.descriptionLength, + after: i18n("galleryDescriptionLength2") + }, + 'gallery.autoOpenViewmore': { + label: i18n("autoOpenViewmore"), + type: 'checkbox', + "default": prefs.gallery.autoOpenViewmore + }, + 'gallery.autoOpenSites': { + label: i18n("galleryAutoOpenSites"), + type: 'textarea', + "default": prefs.gallery.autoOpenSites + }, + 'gallery.searchData': { + label: i18n("gallerySearchData"), + type: 'textarea', + "default": prefs.gallery.searchData + }, + 'gallery.editSite': { + label: i18n("galleryEditSite"), + type: 'select', + options: editSitesName, + "default": prefs.gallery.editSite, + }, + + // 图片窗口 + 'imgWindow.fitToScreen': { + label: i18n("imgWindowFitToScreen"), + type: 'checkbox', + "default": prefs.imgWindow.fitToScreen, + section: [i18n("imgWindow")], + title: i18n("imgWindowFitToScreenTip"), + }, + 'imgWindow.fitToScreenSmall': { + label: i18n("imgWindowFitToScreenWhenSmall"), + type: 'checkbox', + "default": prefs.imgWindow.fitToScreenSmall + }, + 'imgWindow.suitLongImg': { + label: i18n("suitLongImg"), + type: 'checkbox', + "default": prefs.imgWindow.suitLongImg + }, + 'imgWindow.switchStoreLoc': { + label: i18n("switchStoreLoc"), + type: 'checkbox', + "default": prefs.imgWindow.switchStoreLoc + }, + 'imgWindow.defaultTool': { + label: i18n("imgWindowDefaultTool"), + type: 'select', + options: { + 'hand': i18n("hand"), + 'rotate': i18n("rotate"), + 'zoom': i18n("zoom"), + }, + "default": prefs.imgWindow.defaultTool, + }, + 'imgWindow.close.escKey': { + label: i18n("imgWindowEscKey"), + type: 'checkbox', + "default": prefs.imgWindow.close.escKey, + line: 'start', + }, + 'imgWindow.close.dblClickImgWindow': { + label: i18n("imgWindowDblClickImgWindow"), + type: 'checkbox', + "default": prefs.imgWindow.close.dblClickImgWindow, + }, + 'imgWindow.close.clickOutside': { + label: i18n("imgWindowClickOutside"), + type: 'select', + options: { + '': i18n("none"), + 'click': i18n("click"), + 'dblclick': i18n("dblclick"), + }, + "default": prefs.imgWindow.close.clickOutside, + title: i18n("imgWindowClickOutsideTip"), + line: 'end', + }, + 'imgWindow.backgroundColor': { + label: i18n("backgroundColor"), + type: 'text', + className: 'color', + "default": prefs.imgWindow.backgroundColor, + line: 'end' + }, + 'imgWindow.overlayer.shown': { + label: i18n("imgWindowOverlayerShown"), + type: 'checkbox', + "default": prefs.imgWindow.overlayer.shown, + line: 'start', + }, + 'imgWindow.overlayer.color': { + label: i18n("imgWindowOverlayerColor"), + type: 'text', + className: 'color', + "default": prefs.imgWindow.overlayer.color, + line: 'end' + }, + 'imgWindow.shiftRotateStep': { + label: i18n("imgWindowShiftRotateStep1"), + type: 'int', + "default": prefs.imgWindow.shiftRotateStep, + after: i18n("imgWindowShiftRotateStep2") + }, + 'imgWindow.zoom.mouseWheelZoom': { + label: i18n("imgWindowMouseWheelZoom"), + type: 'checkbox', + "default": prefs.imgWindow.zoom.mouseWheelZoom, + }, + 'imgWindow.zoom.range': { + label: i18n("imgWindowZoomRange"), + type: 'textarea', + "default": prefs.imgWindow.zoom.range.join(', '), + title: i18n("imgWindowZoomRangeTip"), + attr: { + "spellcheck": "false" + } + }, + 'imgWindow.fixed': { + label: i18n("positionFixed"), + "default": prefs.imgWindow.fixed, + type: 'checkbox', + }, + 'imgWindow.zIndex': { + label: "z-Index", + "default": prefs.imgWindow.zIndex, + type: 'int', + }, + + // 其它 + 'waitImgLoad': { + label: i18n("waitImgLoad"), + type: 'checkbox', + "default": prefs.waitImgLoad, + section: [i18n("others")], + title: i18n("waitImgLoadTip") + }, + 'customLang': { + label: i18n("customLang"), + type: 'select', + options: customLangOption, + "default": prefs.customLang, + line: 'end', + }, + 'saveName': { + label: i18n("saveName"), + type: 'select', + options: { + 0: i18n("default"), + 1: i18n("textFirst"), + 2: i18n("onlyUrl"), + 3: i18n("urlAndText") + }, + "default": (prefs.saveName || 0), + title: i18n("saveNameTip"), + }, + 'saveNameAddTitle': { + label: i18n("saveNameAddTitle"), + type: 'checkbox', + "default": !!prefs.saveNameAddTitle + }, + 'debug': { + label: i18n("debug"), + type: 'checkbox', + "default": prefs.debug + }, + 'customRules': { + label: GM_config.create('a', { + href: 'https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B#-custom-rules-example', + target: '_blank', + textContent: i18n("customRules") + }), + type: 'textarea', + "default": prefs.customRules + } + /*'firstEngine': { + label: i18n("firstEngine"), + type: 'select', + options: { + "Tineye":"Tineye", + "Google":"Google", + "Baidu":"Baidu" + }, + "default": prefs.firstEngine, + },*/ + }, + events: { + open: async function(doc, win, frame) { + isConfigOpen = true; + let saveBtn = doc.querySelector("#"+this.id+"_saveBtn"); + let closeBtn = doc.querySelector("#"+this.id+"_closeBtn"); + let resetLink = doc.querySelector("#"+this.id+"_resetLink"); + let customInput = doc.querySelector("#"+this.id+"_field_customRules"); + customInput.style.height = "188px"; + customInput.setAttribute("spellcheck", "false"); + saveBtn.textContent = i18n("saveBtn"); + saveBtn.title = i18n("saveBtnTips"); + saveBtn.addEventListener('click', e => { + if (customInput.value) { + if (customInput.value.trim().indexOf("[") != 0) { + e.stopPropagation(); + e.preventDefault(); + alert("The rules must be enclosed in square brackets ([])."); + return; + } + try { + var customRules; + if (customInput.value.indexOf("name:") !== -1) { + if (!isunsafe()) { + unsafeWindow.eval(createScript(customInput.value)); + } + } else { + customInput.value = JSON.stringify(JSON.parse(customInput.value), null, 4); + } + } catch(err) { + e.stopPropagation(); + e.preventDefault(); + alert("Wrong rule:" + err.toString()); + } + } + }, true); + closeBtn.textContent=i18n("closeBtn"); + closeBtn.title=i18n("closeBtnTips"); + resetLink.textContent=i18n("resetLink"); + resetLink.title=i18n("resetLinkTips"); + let searchData=doc.getElementById(this.id+"_field_gallery.searchData"); + if(searchData && searchData.value==""){ + searchData.value=defaultSearchData; + } + let about = doc.getElementById(this.id + "_section_4"); + if (about) { + if (!newsNode) { + newsNode = document.createElement("div"); + let newsEles = createEleFromJson([ + { + node: "div", + text: "Made with ❤️ by @", + attr: { + style: "width: calc(100% - 8px); text-align: center;" + }, + children: [ + { + node: "a", + text: "Hoothin", + attr: { + "href": "mailto:rixixi@gmail.com" + } + }, + { + node: "br" + }, + { + node: "a", + text: "Star Me on 🐱Github", + attr: { + href: "https://github.com/hoothin/UserScripts", + target: "_blank" + } + }, + { + node: "br" + }, + { + node: "span", + text: "Join our " + }, + { + node: "a", + text: "Discord", + attr: { + href: "https://discord.com/invite/keqypXC6wD", + target: "_blank" + } + } + ] + }, + { + node: "img", + attr: { + src: "https://s2.loli.net/2023/02/06/afTMxeASm48z5vE.jpg", + style: "width: 100%; margin-top: 5px; max-height: 180px; display: none;", + onload: "this.style.display=''" + } + }, + { + node: "div", + attr: { + style: "width: 100%; display: flex; align-items: center; justify-content: center; margin-top: 5px; font-size: 14px;" + }, + children: [ + { + node: "img", + attr: { + src: "https://ko-fi.com/favicon-32x32.png", + style: "margin-right: 5px; height: 25px; display: none;", + onload: "this.style.display=''" + } + }, + { + node: "a", + text: "Ko-fi", + attr: { + href: "https://ko-fi.com/hoothin", + style: "margin-right: 10px;", + target: "_blank" + } + }, + { + node: "img", + attr: { + src: "https://static.afdiancdn.com/favicon.ico", + style: "margin-right: 5px; height: 20px; display: none;", + onload: "this.style.display=''" + } + }, + { + node: "a", + text: "爱发电", + attr: { + href: "https://afdian.com/@hoothin", + target: "_blank" + } + } + ] + } + ]); + newsNode.style.padding = "5px"; + newsNode.appendChild(newsEles); + about.appendChild(newsNode); + } + if (!newsInited) { + let news = await GM_fetch(`https://hoothin.com/scripts/pvcep/${lang}`).then(response => response.json()).catch(e => {}); + newsInited = true; + if (!news) return; + let newsEles = createEleFromJson(news); + if (newsEles && newsEles.childElementCount) { + if (newsNode) about.removeChild(newsNode); + newsNode = document.createElement("div"); + newsNode.appendChild(newsEles); + } + } + about.appendChild(newsNode); + } + }, + save: function() { + loadPrefs(); + storage.setItem("customLang", prefs.customLang); + }, + close: function() { + isConfigOpen = false; + } + } + }); + + + + loadPrefs(); + + var hideIcon=storage.getListItem("hideIcon", location.hostname) || false; + var hideIconStyle=document.createElement('style'); + hideIconStyle.textContent=`#pv-float-bar-container{display:none!important}`; + if(hideIcon){ + document.head.appendChild(hideIconStyle); + } + _GM_registerMenuCommand(i18n("openConfig"), openPrefs); + _GM_registerMenuCommand(i18n("openGallery"), openGallery); + _GM_registerMenuCommand(i18n("hideIcon") + (hideIcon ? "☑️" : ""), () => { + hideIcon=!hideIcon; + storage.setListItem("hideIcon", location.hostname, hideIcon); + if(hideIcon){ + document.head.appendChild(hideIconStyle); + }else{ + document.head.removeChild(hideIconStyle); + } + }); + _GM_registerMenuCommand(i18n("ruleRequest"), () => { + _GM_openInTab("https://github.com/hoothin/UserScripts/issues/new?labels=Picviewer%20CE%2B&template=custom-rule-request.md&title=Request%20Picviewer%20CE%2B%20support%20for%20" + location.hostname, {active:true}); + }); + + function initKeyInputs() { + if (!GM_config.frame || !GM_config.frame.contentDocument) return; + let keyInputs = GM_config.frame.contentDocument.querySelectorAll('input.floatBar-key'); + [].forEach.call(keyInputs, input => { + input.setAttribute('readOnly', 'readonly'); + input.addEventListener("keydown", e => { + if (e.key === 'Escape' || e.key === 'Backspace') input.value = ''; + else input.value = e.key; + e.stopPropagation(); + e.preventDefault(); + }); + }); + } + + matchedRule = getMatchedRule(); + let editUrl=storage.getItem("editUrl"); + if(editUrl){ + let editFunc=editSitesFunc[prefs.gallery.editSite]; + if(!editFunc)editFunc=editSitesFunc[Object.keys(editSitesFunc)[0]]; + if(editFunc){ + if (document.readyState == 'complete'){ + editFunc(editUrl); + }else{ + let readystatechangeHandler = e => { + if (document.readyState == 'complete') { + editFunc(editUrl); + document.removeEventListener('readystatechange', readystatechangeHandler); + } + }; + document.addEventListener('readystatechange', readystatechangeHandler); + } + } + } + + var configStyle = document.createElement("style"); + configStyle.textContent = "#pv-prefs { display: initial; }"; + configStyle.type = 'text/css'; + if (location.hostname == "hoothin.github.io" && location.pathname == "/UserScripts/Picviewer%20CE+/") { + openPrefs(); + } else if (location.hostname == "hoothin.github.io" && location.pathname == "/UserScripts/Picviewer%20CE+/gallery.html") { + let gallery = new GalleryC(); + gallery.data = []; + gallery.lockGallery = true; + var allData = await gallery.getAllValidImgs(); + gallery.data = allData; + gallery.load(gallery.data); + let searchParams = new URLSearchParams(location.search); + let viewMore = searchParams.get("mode"); + let imgs = searchParams.get("imgs"); + if (imgs) { + gallery.addImageUrls(imgs); + } + if (viewMore == "1") { + gallery.maximizeSidebar(); + } + let imgCon = gallery.eleMaps['img-content'], waitingDouble = false, openImageTimer; + imgCon.addEventListener('click', e => { + if (e.target == imgCon) { + clearTimeout(openImageTimer); + if (waitingDouble) { + waitingDouble = false; + gallery.openImages({altKey: true}); + return; + } + waitingDouble = true; + openImageTimer = setTimeout(() => { + waitingDouble = false; + gallery.openImages(e); + }, 300); + } + }, true); + } else if (prefs.gallery.autoOpenSites) { + let sitesArr=prefs.gallery.autoOpenSites.split("\n"); + for(let s=0;s { + if (!ruleImportUrlReg.test(location.href)) return; + if (/pre|code/i.test(e.target.nodeName)) { + let content = e.target.innerText.trim(); + if (/"name":/.test(content) && /"(r|xhr)":/.test(content)) { + try { + localStorage.setItem('picviewerCE.config.curTab', 4); + let webRule = JSON.parse(content.replace(/^\/\/.*/g, "")); + let customRules; + let fieldsCustomRules = GM_config.fields.customRules; + if (prefs.customRules.indexOf('"name":') !== -1) { + customRules = JSON.parse(prefs.customRules); + } else { + customRules = []; + } + customRules.push(webRule); + fieldsCustomRules.value = JSON.stringify(customRules, null, 4); + openPrefs(); + } catch (e) { + alert(e.toString()); + } + } + } + }, true); + } + + function openPrefs() { + let fieldsSearchData = GM_config.fields["gallery.searchData"]; + if (fieldsSearchData && fieldsSearchData.value) { + fieldsSearchData.value = fieldsSearchData.value.replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/&/g, "&").replace(/>/g, ">").replace(/").replace(/</g, "<").replace(/&/g, "&").replace(/>/g, ">").replace(/{ + if (GM_config.frame && GM_config.frame.contentDocument.body.innerHTML === "") { + _GM_openInTab("https://hoothin.github.io/UserScripts/Picviewer%20CE+/", {active:true}); + return; + } + if (GM_config.frame && GM_config.frame.style && GM_config.frame.style.display == "none") { + GM_config.frame.src=""; + } + initKeyInputs(); + }, 1000); + } + + function loadPrefs() { + // 根据 GM_config 的 key 载入设置到 prefs + Object.keys(GM_config.fields).forEach(function(keyStr) { + var keys = keyStr.split('.'); + var lastKey = keys.pop(); + + var lastPref = prefs; + var curKey = keys.shift(); + while(curKey){ + lastPref = lastPref[curKey]; + curKey = keys.shift(); + } + + var value = GM_config.get(keyStr); + if (typeof value != 'undefined') { + // 特殊的 + if (keyStr == 'magnifier.wheelZoom.range' || keyStr == 'imgWindow.zoom.range') { + lastPref[lastKey] = value.split(/[,,]\s*/).map(function(s) { return parseFloat(s)}); + } else if(keyStr == 'floatBar.butonOrder') { + lastPref[lastKey] = value.trim().split(/\s*[,,]\s*/); + } else { + lastPref[lastKey] = value; + } + } + }); + try { + if (localStorage && localStorage.setItem) { + if (!storage.getItem('inited')) { + localStorage.setItem('picviewerCE.config.curTab', 4); + storage.setItem('inited', true); + } + } + } catch(e) {} + if (typeof prefs.gallery.formatConversion == 'undefined') { + prefs.gallery.formatConversion = "webp>png"; + } + prefs.gallery.formatConversion.split("\n").forEach(str => { + let pair = str.split(">"); + if (pair.length !== 2) return; + formatDict.set(pair[0].trim(), pair[1].trim()); + }); + + debug = prefs.debug ? console.log.bind(console) : function() {}; + } + + }; + + function drawTobase64(img){ + canvas.width = img.naturalWidth || img.width; + canvas.height = img.naturalHeight || img.height; + let ctx = canvas.getContext('2d'); + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.drawImage(img, 0, 0); + return canvas.toDataURL("image/png"); + } + + function init2(){ + init(topObject,window,document,arrayFn,envir,storage,unsafeWindow); + }; + + + //大致检测运行环境 + var envir={ + ie:typeof document.documentMode == 'number', + firefox:typeof XPCNativeWrapper == 'function', + opera:!!window.opera, + chrome:!!window.chrome, + }; + + //ie的话,不支持 < ie9的版本 + if(envir.ie && document.documentMode < 9){ + return; + }; + + + var arrayFn=(function(){ + var arrayProto=Array.prototype; + return { + find:arrayProto.find, + slice:arrayProto.slice, + forEach:arrayProto.forEach, + some:arrayProto.some, + every:arrayProto.every, + map:arrayProto.map, + filter:arrayProto.filter, + indexOf:arrayProto.indexOf, + lastIndexOf:arrayProto.lastIndexOf, + }; + + })(); + + var storage={ + supportGM: typeof GM_getValue=='function' && typeof GM_getValue('a','b')!='undefined',//chrome的gm函数式空函数 + mxAppStorage:(function(){//傲游扩展储存接口 + try{ + return window.external.mxGetRuntime().storage; + }catch(e){ + }; + })(), + operaUJSStorage:(function(){//opera userjs全局存储接口 + try{ + return window.opera.scriptStorage; + }catch(e){ + }; + })(), + setItem:function(key,value){ + if (this.supportGM) { + GM_setValue(key, value); + if (value === "" && typeof GM_deleteValue != 'undefined') { + GM_deleteValue(key); + } + } else if (this.operaUJSStorage) { + this.operaUJSStorage.setItem(key, value); + } else if (this.mxAppStorage) { + this.mxAppStorage.setConfig(key, value); + } else if (window.localStorage) { + window.localStorage.setItem(key, value); + } + }, + getItem:function(key){ + var value; + if(this.supportGM){ + value=GM_getValue(key); + }else if(this.operaUJSStorage){ + value=this.operaUJSStorage.getItem(key); + }else if(this.mxAppStorage){ + value=this.mxAppStorage.getConfig(key); + }else if(window.localStorage){ + value=window.localStorage.getItem(key); + }; + return value; + }, + getListItem: function(list, key) { + var value; + var listData = this.getItem(list); + if (listData) { + for(var i = 0; i < listData.length; i++) { + var data = listData[i]; + if (data.k == key) { + value = data.v; + break; + } + } + } + return value; + }, + setListItem: function(list, key, value, limitNum = 50) { + var listData = this.getItem(list); + if (!listData || !listData.filter) listData = []; + listData = listData.filter(data => data && data.k != key); + if (value) { + listData.unshift({k: key, v: value}); + if (listData.length > limitNum) listData.pop(); + } + this.setItem(list, listData); + } + }; + + function getUrl(url, callback, onError){ + _GM_xmlhttpRequest({ + method: 'GET', + url: url.trim(), + onload: callback, + onerror: onError + }); + } + + function setSearchState(words, imgState){ + if (imgState) imgState.innerHTML=createHTML(words); + } + + var searchSort=["Tineye","Google","Baidu"]; + function sortSearch(){ + for(var i=0;i2)break; + srcs.push(imgData.objURL); + } + setSearchState(i18n("findOverBeginLoad",["百度",srcs.length]),imgCon); + callBackFun(srcs); + }else{ + searchNext(); + return; + } + }, onError); + }; + var searchGoogle=function(){ + setSearchState(i18n("beginSearchImg","Google"),imgCon); + getUrl("https://www.google.com/searchbyimage?safe=off&image_url="+encodeURIComponent(imgSrc), function(d){ + let googleHtml=document.implementation.createHTMLDocument(''); + googleHtml.documentElement.innerHTML = d.responseText; + let sizeUrl=googleHtml.querySelector("div.card-section>div>div>span.gl>a"); + if(sizeUrl){ + getUrl("https://www.google.com"+sizeUrl.getAttribute("href"), function(d){ + googleHtml.documentElement.innerHTML = d.responseText; + let imgs=googleHtml.querySelectorAll("div.rg_meta"); + if(imgs.length==0){searchNext();return;} + srcs=[]; + for(var i=0;i2)break; + let jsonData=JSON.parse(imgs[i].innerHTML); + srcs.push(jsonData.ou); + } + setSearchState(i18n("findOverBeginLoad",["Google",srcs.length]),imgCon); + callBackFun(srcs); + }, onError); + }else{ + searchNext(); + } + }, onError); + }; + var searchTineye=function(){ + setSearchState(i18n("beginSearchImg","Tineye"),imgCon); + getUrl("https://www.tineye.com/search?url="+encodeURIComponent(imgSrc)+"&sort=size", function(d){ + let tineyeHtml=document.implementation.createHTMLDocument(''); + tineyeHtml.documentElement.innerHTML = d.responseText; + let searchImg=tineyeHtml.querySelectorAll(".match-details>div.match:first-of-type>p.image-link:first-of-type>a"); + if(searchImg.length>0){ + srcs=[]; + for(var i=0;i2)break; + srcs.push(searchImg[i].href); + } + setSearchState(i18n("findOverBeginLoad",["Tineye",srcs.length]),imgCon); + callBackFun(srcs); + }else{ + searchNext(); + } + }, onError); + }; + var searchNext=function(){ + searchFrom++; + if(searchFrom<=searchSort.length)switchSearch(); + else{ + if(noneResult)noneResult(); + setSearchState(i18n("findNoPic"),imgCon); + setTimeout(function(){ + setSearchState("",imgCon); + },2000); + } + }; + var callBackFun=function(srcs){ + callBack(srcs, searchFrom); + }; + if(!searchFrom)searchFrom=1; + var switchSearch=function(){ + switch(searchSort[searchFrom-1]){ + case "Baidu": + searchBaidu(); + break; + case "Google": + searchGoogle(); + break; + case "Tineye": + searchTineye(); + break; + default: + searchTineye(); + break; + } + }; + switchSearch(); + } + + if (window.top != window.self) { + if (window.self.innerWidth === 0 && window.self.innerHeight === 0) { + if (document.readyState !== "complete") { + window.addEventListener('load', e => { + setTimeout(() => { + if (window.self.innerWidth > 250 && window.self.innerHeight > 250) { + init2(); + } + }, 500); + }); + } + } else { + init2(); + } + } else { + init2(); + } + +})(this,window,document,(typeof unsafeWindow=='undefined'? window : unsafeWindow)); \ No newline at end of file From 016b93b6decfaf20e60e6d119375d76a35b7dca8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:19:54 +0900 Subject: [PATCH 0872/1065] Update jekyll-gh-pages.yml --- .github/workflows/jekyll-gh-pages.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/jekyll-gh-pages.yml b/.github/workflows/jekyll-gh-pages.yml index 00b864d6d2c..5ed5cada8c8 100644 --- a/.github/workflows/jekyll-gh-pages.yml +++ b/.github/workflows/jekyll-gh-pages.yml @@ -8,6 +8,7 @@ on: paths-ignore: - 'Pagetual/items_all.json' - 'Pagetual/pagetualRules.json' + - '.github/*' workflow_run: workflows: ["Update Version on File Change"] types: From feb52f2a007fa8abd6253e679efceab51e860d4d Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:21:06 +0900 Subject: [PATCH 0873/1065] Update jekyll-gh-pages.yml --- .github/workflows/jekyll-gh-pages.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/jekyll-gh-pages.yml b/.github/workflows/jekyll-gh-pages.yml index 5ed5cada8c8..9bdd4e3eec5 100644 --- a/.github/workflows/jekyll-gh-pages.yml +++ b/.github/workflows/jekyll-gh-pages.yml @@ -9,6 +9,7 @@ on: - 'Pagetual/items_all.json' - 'Pagetual/pagetualRules.json' - '.github/*' + - '.github/*/*' workflow_run: workflows: ["Update Version on File Change"] types: From 30d7d930ec73fc1562f010d8ecfecdab45ffa9fd Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:23:02 +0900 Subject: [PATCH 0874/1065] Update build-dist.yml --- .github/workflows/build-dist.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index 88c92b44c76..5d4053480f2 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -20,9 +20,9 @@ jobs: run: | TIMESTAMP=$(date +%s) - sed -e "s#// @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js#// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=$TIMESTAMP#" \ - -e "s#// @require https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js#// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=$TIMESTAMP#" \ - -e "s#// @require https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js#// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=$TIMESTAMP#" \ + sed -e "s#https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=$TIMESTAMP#" \ + -e "s#https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=$TIMESTAMP#" \ + -e "s#https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=$TIMESTAMP#" \ "Picviewer CE+/Picviewer CE+.user.js" > "Picviewer CE+/dist.user.js" - name: Commit and push dist.user.js From 25d4a9eb2bdfd03bfe73fcea5396597c0706d50e Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 7 Sep 2025 01:23:38 +0000 Subject: [PATCH 0875/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 77b2308bb08..259a54a3d0d 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -45,9 +45,9 @@ // @grant GM.registerMenuCommand // @grant GM.notification // @grant unsafeWindow -// @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js -// @require https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1757208217 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1757208217 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1757208217 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* From f1ed00d9436aa6fb3add1c385f98a551425c262c Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:29:38 +0900 Subject: [PATCH 0876/1065] Update README.md --- Picviewer CE+/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 9a99e07cd7a..3c60cc5ac91 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -19,9 +19,9 @@ Recommended similar plugins: [Imagus](https://chromewebstore.google.com/detail/imagus/immpkjjlgappgfkkfieppnmlhakdmaab) - [Hover-zoom+](https://chromewebstore.google.com/detail/hover-zoom+/pccckmaobkjjboncdfnnofkonhgpceea) - [Mouseover Popup Image Viewer](https://greasyfork.org/scripts/394820) -## 🚀 Quick Start +## Quick Start -Install from [Github](https://hoothin.github.io/UserScripts/Picviewer%20CE+/Picviewer%20CE+.user.js) or [Greasefork](https://greasyfork.org/scripts/24204-picviewer-ce). +Install from [Github📥](https://hoothin.github.io/UserScripts/Picviewer%20CE+/Picviewer%20CE+.user.js) or [Greasefork📥](https://greasyfork.org/scripts/24204-picviewer-ce). Hover your mouse over any image and click the icons on the float bar. @@ -29,7 +29,7 @@ Press `CTRL + G` to quickly enter the gallery. Hold `CTRL` to view a larger pict There are additional settings available in the "Picviewer CE+ config" for further customization. Currently, reviewing these settings is the best way to learn about the script's capabilities. Try exploring more functions on your own! -## 🤝 Contribution & Support +## Contribution & Support If you are glad to assist with the translation, please ✍️[edit this file](https://github.com/hoothin/UserScripts/edit/master/Picviewer%20CE%2B/pvcep_lang.js#L1). It will be beneficial for individuals who speak the same language as you do. Thank you for your help. @@ -47,7 +47,7 @@ If you are glad to assist with the translation, please ✍️[edit this file](ht *Need more rules for peculiar sites? feel free to pull requests or open issues.* -## ✨ PDF Addon +## PDF Addon Picviewer CE+ [PDF Addon](https://greasyfork.org/scripts/498445-picviewer-ce-pdf-addon). After installing this addon, when the `Compress to ZIP` feature is enabled, a PDF file will be generated instead of a ZIP file during the packaging process.
    Make a PDF e-book with this addon @@ -62,7 +62,7 @@ Picviewer CE+ [PDF Addon](https://greasyfork.org/scripts/498445-picviewer-ce-pdf This way, you'll get a beautifully created PDF e-book.
    -## 🔧 Custom [Rules Example](pvcep_rules.js): +## Custom [Rules Example](pvcep_rules.js): **💝 Buy me a coffee with [Ko-fi](https://ko-fi.com/hoothin) or [愛發電](https://afdian.com/a/hoothin) to keep my scripts always up to date.** From a4a6a8d276da7792557a332827784e58c968ba98 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:30:45 +0900 Subject: [PATCH 0877/1065] Update README.md --- Picviewer CE+/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 3c60cc5ac91..2ff6f1da30d 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -21,7 +21,7 @@ Recommended similar plugins: [Imagus](https://chromewebstore.google.com/detail/i ## Quick Start -Install from [Github📥](https://hoothin.github.io/UserScripts/Picviewer%20CE+/Picviewer%20CE+.user.js) or [Greasefork📥](https://greasyfork.org/scripts/24204-picviewer-ce). +Install from [Github📥](https://hoothin.github.io/UserScripts/Picviewer%20CE+/dist.user.js) or [Greasefork📥](https://greasyfork.org/scripts/24204-picviewer-ce). Hover your mouse over any image and click the icons on the float bar. From 23014da270a40e1b170a3240b27a3b4c1cf7bc73 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:36:35 +0900 Subject: [PATCH 0878/1065] clean --- 91wii/91wii.user.js | 50 --------------------------------------------- 91wii/README.md | 1 - 2 files changed, 51 deletions(-) delete mode 100644 91wii/91wii.user.js delete mode 100644 91wii/README.md 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 自动作答数学题,自动签到 From 4cdec0726ce7eef7c4bbccbb1189dc98c362bf7c Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:47:44 +0900 Subject: [PATCH 0879/1065] Update README.md --- Picviewer CE+/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 2ff6f1da30d..113d217db68 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -206,7 +206,9 @@ Feel free to share your own custom rules on Greasy Fork! > *A blank gallery page designed for viewing local or online pictures, showcasing every image you have imported.* -You can drag and drop folders or videos/audios/images into this gallery to get an electronic slideshow to view them. +You can drag and drop **folders** or videos/audios/images into this gallery to get an electronic slideshow to view them. + +Click with `Ctrl key` can import folder too. Include `mode=`*`1`* to open gallery in view-more mode.
    Add `imgs=`*`http://xxx/xxx.jpg`* to import images. ` ` to split multi-image, `[01-09]` to generate nine urls form 01 to 09
    From ca65ddca001cdb23b03213fbf6aa8b2432311ad4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 10:49:12 +0900 Subject: [PATCH 0880/1065] Update README.md --- RandomSexyPic/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RandomSexyPic/README.md b/RandomSexyPic/README.md index da0cf674153..74032e9065c 100644 --- a/RandomSexyPic/README.md +++ b/RandomSexyPic/README.md @@ -3,7 +3,7 @@ Random sexy pictures Browsing assistance for [Lolicon sexy pictures Api](https://api.lolicon.app/setu/v2?r18=1&num=5) --- -Can be used to preview pictures with any other JSON api.
    Just open the api and click the "Parse current api" under command menu, and click again & cancel to disable.
    +Can be used to preview pictures with **any other JSON api**.
    Just open the api and click the "Parse current api" under command menu, and click again & cancel to disable.
    For example: https://wall.alphacoders.com/api2.0/get.php?method=highest_rated&page=1&info_level=2&page=2 ![case1](case1.jpg)![case2](case2.jpg)![case3](case3.jpg)![case4](case4.jpg)![case5](case5.jpg) From 2c55c3737db786f3fe628e82590467bd7ca23983 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 18:16:51 +0900 Subject: [PATCH 0881/1065] Update README.md --- DownloadAllContent/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DownloadAllContent/README.md b/DownloadAllContent/README.md index 5ac83b0837a..74e08fc3948 100644 --- a/DownloadAllContent/README.md +++ b/DownloadAllContent/README.md @@ -9,6 +9,8 @@ [![img](https://img.shields.io/github/stars/hoothin/UserScripts?style=social)](https://github.com/hoothin/UserScripts#StarMe) ⭐[Star Me](https://github.com/hoothin/UserScripts#StarMe) +安裝: [Github📥](https://hoothin.github.io/UserScripts/DownloadAllContent/DownloadAllContent.user.js) / [Greasefork📥](https://greasyfork.org/scripts/25068). + --- # 操作說明 From 8a674a203192910678c5c38248375baa58d308b1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 18:42:55 +0900 Subject: [PATCH 0882/1065] Update README.md --- Picviewer CE+/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 113d217db68..bcf279a3eb4 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -144,10 +144,12 @@ Feel free to share your own custom rules on Greasy Fork!

    Advance rule wizard

    There are two types of rules available: + + JSON (simple mode) These rules are written in JSON format and can be imported online through [Discussions](https://github.com/hoothin/UserScripts/discussions) or [Reddit](https://www.reddit.com/r/PicviewerCE). They won't limited by websites that have a strict Content Security Policy that disallows unsafe-eval. + + JSON params - name @@ -189,9 +191,11 @@ Feel free to share your own custom rules on Greasy Fork! `"xhr": { "url": ".showcase__link", "query": "img[fetchpriority]" }` Fetch the link above the image that matches ".showcase__link" and query the "img[fetchpriority]" on the inner page from the link. + + JS (full mode) These rules are written in JavaScript object format. If you are not using a standalone userscript, they may be limited by websites that have a strict Content Security Policy that disallows unsafe-eval. + + JS params - all mentioned above and the function type instead of string type - getImage From 6dba7997e4d8725780e618aac834a233e2de16f1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 18:48:09 +0900 Subject: [PATCH 0883/1065] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b4a12fb47c4..cd32fd58fbb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

    ⚙️Greasemonkey scripts

    +

    ⚙️Greasemonkey scripts

    license From 90b0937b198d59010e2e0ed843a68d7ead5e694a Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 18:54:00 +0900 Subject: [PATCH 0884/1065] Update README.md --- Picviewer CE+/README.md | 132 +++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 62 deletions(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index bcf279a3eb4..313e4896d75 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -140,69 +140,77 @@ Feel free to share your own custom rules on Greasy Fork! })(); ``` -

    -

    Advance rule wizard

    - - There are two types of rules available: - - + JSON (simple mode) - - These rules are written in JSON format and can be imported online through [Discussions](https://github.com/hoothin/UserScripts/discussions) or [Reddit](https://www.reddit.com/r/PicviewerCE). - They won't limited by websites that have a strict Content Security Policy that disallows unsafe-eval. - - + JSON params - - name - - `"name": "rule name"` - - Name of the rule - - url - - `"url": "^https://google\\.com"` - - Regular expression used to match the site URL. - - src - - `"src": "^https://image\\.xx\\.com"` - - Regular expression used to match the image src - - r - - `"r": "/(.*)\\d+/i"` or `"r": "thumb"` - - Simple string or regular expression used to replace the image src from - - s - - `"s": "$1"` - - Replace the image src to - - ext - - `"ext": "previous"` - - Capture nearby image element when the mouse hovers over a non-image element. - - lazyAttr - - `"lazyAttr": "data-lazy"` - - Lazy loaded original image URL attribute name - - xhr - - `"xhr": { "url": ".showcase__link", "query": "img[fetchpriority]" }` - - Fetch the link above the image that matches ".showcase__link" and query the "img[fetchpriority]" on the inner page from the link. - - + JS (full mode) - - These rules are written in JavaScript object format. If you are not using a standalone userscript, they may be limited by websites that have a strict Content Security Policy that disallows unsafe-eval. - - + JS params - - all mentioned above and the function type instead of string type - - getImage - - getExtSrc - - Learn from https://github.com/hoothin/UserScripts/blob/master/Picviewer%20CE%2B/pvcep_rules.js +
    +

    Advance rule wizard

    +

    There are two types of rules available:

    +
      +
    • +

      JSON (simple mode)

      +

      These rules are written in JSON format and can be imported online through Discussions or Reddit. +They won't limited by websites that have a strict Content Security Policy that disallows unsafe-eval.

      +
        +
      • JSON params +
          +
        • +

          name

          +

          "name": "rule name"

          +

          Name of the rule

          +
        • +
        • +

          url

          +

          "url": "^https://google\\.com"

          +

          Regular expression used to match the site URL.

          +
        • +
        • +

          src

          +

          "src": "^https://image\\.xx\\.com"

          +

          Regular expression used to match the image src

          +
        • +
        • +

          r

          +

          "r": "/(.*)\\d+/i" or "r": "thumb"

          +

          Simple string or regular expression used to replace the image src from

          +
        • +
        • +

          s

          +

          "s": "$1"

          +

          Replace the image src to

          +
        • +
        • +

          ext

          +

          "ext": "previous"

          +

          Capture nearby image element when the mouse hovers over a non-image element.

          +
        • +
        • +

          lazyAttr

          +

          "lazyAttr": "data-lazy"

          +

          Lazy loaded original image URL attribute name

          +
        • +
        • +

          xhr

          +

          "xhr": { "url": ".showcase__link", "query": "img[fetchpriority]" }

          +

          Fetch the link above the image that matches ".showcase__link" and query the "img[fetchpriority]" on the inner page from the link.

          +
        • +
        +
      • +
      +
    • +
    • +

      JS (full mode)

      +

      These rules are written in JavaScript object format. If you are not using a standalone userscript, they may be limited by websites that have a strict Content Security Policy that disallows unsafe-eval.

      +
        +
      • JS params +
          +
        • all mentioned above and the function type instead of string type
        • +
        • getImage
        • +
        • getExtSrc
        • +
        +
      • +
      +

      Learn from https://github.com/hoothin/UserScripts/blob/master/Picviewer%20CE%2B/pvcep_rules.js

      +
    • +
    ## Blank Gallery Page From d54398c1e53ec865267e2fe9e3a5be6d723c19af Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 18:57:16 +0900 Subject: [PATCH 0885/1065] Update README.md --- Picviewer CE+/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index 313e4896d75..c15333f29cc 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -142,7 +142,7 @@ Feel free to share your own custom rules on Greasy Fork!
    -

    Advance rule wizard

    +Advance rule wizard

    There are two types of rules available:

    • From 87beff8bf775654b03f799553e9933e53e886470 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 18:59:56 +0900 Subject: [PATCH 0886/1065] Update README.md --- Picviewer CE+/README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index c15333f29cc..b3dd17cd2dd 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -49,17 +49,18 @@ If you are glad to assist with the translation, please ✍️[edit this file](ht ## PDF Addon Picviewer CE+ [PDF Addon](https://greasyfork.org/scripts/498445-picviewer-ce-pdf-addon). After installing this addon, when the `Compress to ZIP` feature is enabled, a PDF file will be generated instead of a ZIP file during the packaging process. -
      + +
      Make a PDF e-book with this addon - - For example, if there is a website with images from `xxx.com/1.jpg` to `xxx.com/99.jpg`, you can use this addon to generate a beautiful PDF e-book as follows: -1. Open the gallery by pressing Ctrl + g -2. In the `Command` menu, find and click `Add image` -3. Input `xxx.com/[1-99].jpg` -4. Right-click in the thumbnail frame below to ignore any unwanted images -5. Click `Download all shown` in the `Command` menu - -This way, you'll get a beautifully created PDF e-book. +

      For example, if there is a website with images from xxx.com/1.jpg to xxx.com/99.jpg, you can use this addon to generate a beautiful PDF e-book as follows:

      +
        +
      1. Open the gallery by pressing Ctrl + g
      2. +
      3. In the Command menu, find and click Add image
      4. +
      5. Input xxx.com/[1-99].jpg
      6. +
      7. Right-click in the thumbnail frame below to ignore any unwanted images
      8. +
      9. Click Download all shown in the Command menu
      10. +
      +

      This way, you'll get a beautifully created PDF e-book.

      ## Custom [Rules Example](pvcep_rules.js): From b4c7d82d0d2c7b512cb495c7cfb609d5bdaeefb8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 19:02:51 +0900 Subject: [PATCH 0887/1065] Update README.md --- Picviewer CE+/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/README.md b/Picviewer CE+/README.md index b3dd17cd2dd..392a5418786 100644 --- a/Picviewer CE+/README.md +++ b/Picviewer CE+/README.md @@ -48,7 +48,7 @@ If you are glad to assist with the translation, please ✍️[edit this file](ht *Need more rules for peculiar sites? feel free to pull requests or open issues.* ## PDF Addon -Picviewer CE+ [PDF Addon](https://greasyfork.org/scripts/498445-picviewer-ce-pdf-addon). After installing this addon, when the `Compress to ZIP` feature is enabled, a PDF file will be generated instead of a ZIP file during the packaging process. +Picviewer CE+ [PDF Addon](https://hoothin.github.io/UserScripts/Picviewer%20CE+/pvcep_pdf_addon.user.js). After installing this addon, when the `Compress to ZIP` feature is enabled, a PDF file will be generated instead of a ZIP file during the packaging process.
      Make a PDF e-book with this addon From b42eb23d7dc775b1a073c4972f35eb870368902a Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 19:04:24 +0900 Subject: [PATCH 0888/1065] Update README.md --- DownloadAllContent/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DownloadAllContent/README.md b/DownloadAllContent/README.md index 74e08fc3948..46df4e75dbd 100644 --- a/DownloadAllContent/README.md +++ b/DownloadAllContent/README.md @@ -25,7 +25,7 @@ ![donate](https://s2.loli.net/2023/02/06/afTMxeASm48z5vE.jpg) -[怠惰小説下載器 ZIP 擴充](https://greasyfork.org/scripts/476943) 下載時將各章節分別存為 TXT,並打包成 ZIP 檔 +[怠惰小説下載器 ZIP 擴充](https://hoothin.github.io/UserScripts/DownloadAllContent/DownloadAllContentSavaAsZIP.user.js) 下載時將各章節分別存為 TXT,並打包成 ZIP 檔 [圖片驗證碼辨識](https://github.com/hoothin/ImgCodeCheck) 開啟`保留內文圖片的網址`後配合 ZIP 擴充可自動轉換圖片文字,詳閱[愛發電](https://afdian.com/p/c7fc3abc8e8411ee9b1852540025c377) From 56d4b8909dae7eefb0a4f8d6b583cceb57473e58 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 7 Sep 2025 20:26:16 +0900 Subject: [PATCH 0889/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 77b2308bb08..5d2e3b12a01 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -26218,7 +26218,7 @@ ImgOps | https://imgops.com/#b#`; GM_config.init({ id: 'pv-prefs', title: GM_config.create('a', { - href: 'https://greasyfork.org/scripts/24204-picviewer-ce', + href: 'https://hoothin.github.io/UserScripts/Picviewer%20CE%2B', target: '_blank', textContent: 'Picviewer CE+ '+i18n("config"), title: i18n("openHomePage") @@ -26940,7 +26940,8 @@ ImgOps | https://imgops.com/#b#`; node: "a", text: "Hoothin", attr: { - "href": "mailto:rixixi@gmail.com" + href: "https://www.hoothin.com/", + target: "_blank" } }, { From 8ef58be22c03cf351153194e9ce1c19e096bbd45 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 7 Sep 2025 11:26:31 +0000 Subject: [PATCH 0890/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 259a54a3d0d..be91b33a8f1 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -45,9 +45,9 @@ // @grant GM.registerMenuCommand // @grant GM.notification // @grant unsafeWindow -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1757208217 -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1757208217 -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1757208217 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1757244391 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1757244391 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1757244391 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* @@ -26218,7 +26218,7 @@ ImgOps | https://imgops.com/#b#`; GM_config.init({ id: 'pv-prefs', title: GM_config.create('a', { - href: 'https://greasyfork.org/scripts/24204-picviewer-ce', + href: 'https://hoothin.github.io/UserScripts/Picviewer%20CE%2B', target: '_blank', textContent: 'Picviewer CE+ '+i18n("config"), title: i18n("openHomePage") @@ -26940,7 +26940,8 @@ ImgOps | https://imgops.com/#b#`; node: "a", text: "Hoothin", attr: { - "href": "mailto:rixixi@gmail.com" + href: "https://www.hoothin.com/", + target: "_blank" } }, { From 08f740e9c21c08b36c46fc61bfe58e364ad2f4ce Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 10 Sep 2025 21:04:41 +0900 Subject: [PATCH 0891/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 39 +++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 5d2e3b12a01..462415137cd 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.5.2 +// @version 2025.9.10.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -12218,7 +12218,33 @@ ImgOps | https://imgops.com/#b#`; img.src = dataurl; } function urlToBlobWithFetch(urlString, cb){ - fetch(urlString).then(response => response.blob()).then(blob => cb(blob)).catch(error => { + fetch(urlString).then(response => response.blob()).then(blob => { + let ext = blob.type.replace(/.*image\/([\w\-]+).*/, "$1"); + if (ext === "text/html" && (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); + } + }).catch(error => { cb(null); }); } @@ -15756,9 +15782,10 @@ ImgOps | https://imgops.com/#b#`; var len = saveParams.length; function downloadOne(imgSrc, imgName, over){ let crosHandler = imgSrc => { - urlToBlob(imgSrc, blob=>{ + urlToBlob(imgSrc, (blob, ext)=>{ if (blob && blob.size>58) { let fileName = imgName.replace(/\//g, ""); + if (ext) fileName = fileName.replace(/\.\w+$/, "") + "." + ext; zip.file(fileName, blob); } else console.debug("error: "+imgSrc); downloaded++; @@ -15776,13 +15803,15 @@ ImgOps | https://imgops.com/#b#`; }); } if(canvas && (/^data:/.test(imgSrc) || imgSrc.split("/")[2] == document.domain)){ - urlToBlobWithFetch(imgSrc, blob=>{ + urlToBlobWithFetch(imgSrc, (blob, ext)=>{ if(!blob){ crosHandler(imgSrc); return; } self.showTips("Downloading "+(downloaded+1)+"/"+len, 1000000); - zip.file(imgName.replace(/^data:.*/, "img").replace(/\//g,""), blob); + let fileName = imgName.replace(/^data:.*/, "img").replace(/\//g,""); + if (ext) fileName = fileName.replace(/\.\w+$/, "") + "." + ext; + zip.file(fileName, blob); downloaded++; over && over(); if(downloaded == len){ From 1d601ee9601a8310912c9f07a21f84a331bf1192 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Wed, 10 Sep 2025 12:04:57 +0000 Subject: [PATCH 0892/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 45 +++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index be91b33a8f1..62aa1bb71e6 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.9.5.2 +// @version 2025.9.10.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -45,9 +45,9 @@ // @grant GM.registerMenuCommand // @grant GM.notification // @grant unsafeWindow -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1757244391 -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1757244391 -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1757244391 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1757505897 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1757505897 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1757505897 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* @@ -12218,7 +12218,33 @@ ImgOps | https://imgops.com/#b#`; img.src = dataurl; } function urlToBlobWithFetch(urlString, cb){ - fetch(urlString).then(response => response.blob()).then(blob => cb(blob)).catch(error => { + fetch(urlString).then(response => response.blob()).then(blob => { + let ext = blob.type.replace(/.*image\/([\w\-]+).*/, "$1"); + if (ext === "text/html" && (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); + } + }).catch(error => { cb(null); }); } @@ -15756,9 +15782,10 @@ ImgOps | https://imgops.com/#b#`; var len = saveParams.length; function downloadOne(imgSrc, imgName, over){ let crosHandler = imgSrc => { - urlToBlob(imgSrc, blob=>{ + urlToBlob(imgSrc, (blob, ext)=>{ if (blob && blob.size>58) { let fileName = imgName.replace(/\//g, ""); + if (ext) fileName = fileName.replace(/\.\w+$/, "") + "." + ext; zip.file(fileName, blob); } else console.debug("error: "+imgSrc); downloaded++; @@ -15776,13 +15803,15 @@ ImgOps | https://imgops.com/#b#`; }); } if(canvas && (/^data:/.test(imgSrc) || imgSrc.split("/")[2] == document.domain)){ - urlToBlobWithFetch(imgSrc, blob=>{ + urlToBlobWithFetch(imgSrc, (blob, ext)=>{ if(!blob){ crosHandler(imgSrc); return; } self.showTips("Downloading "+(downloaded+1)+"/"+len, 1000000); - zip.file(imgName.replace(/^data:.*/, "img").replace(/\//g,""), blob); + let fileName = imgName.replace(/^data:.*/, "img").replace(/\//g,""); + if (ext) fileName = fileName.replace(/\.\w+$/, "") + "." + ext; + zip.file(fileName, blob); downloaded++; over && over(); if(downloaded == len){ From 3056f84814c03717b769d6f4c9cc1b52d674258d Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 11 Sep 2025 22:35:14 +0900 Subject: [PATCH 0893/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 462415137cd..7b6ae024385 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.10.1 +// @version 2025.9.11.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -23439,6 +23439,7 @@ ImgOps | https://imgops.com/#b#`; },3000); }, setPosition:function(){ + if (!this.data.img) return; var position=getContentClientRect(this.data.img); var cs=this.loadingAnim.style; var scrolled=getScrolled(); @@ -23572,7 +23573,7 @@ ImgOps | https://imgops.com/#b#`; }; var self=this; - function openInTop(){ + async function openInTop(){ var data=self.data; //删除不能发送的项。 @@ -23593,6 +23594,15 @@ ImgOps | https://imgops.com/#b#`; delCantClone(data); }; + if(!gallery){ + gallery=new GalleryC(); + gallery.data=[]; + } + let allData=(await gallery.getAllValidImgs()).map(item => item.src); + allData = allData.filter((item, index) => { + return allData.indexOf(item) === index; + }); + data.all = allData; window.postMessage({ messageID:messageID, src:img.src, From cbc827dbc624403417fc954e5631abfb74fdb2c0 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 11 Sep 2025 13:35:25 +0000 Subject: [PATCH 0894/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 62aa1bb71e6..d664e6cbef1 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.9.10.1 +// @version 2025.9.11.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -45,9 +45,9 @@ // @grant GM.registerMenuCommand // @grant GM.notification // @grant unsafeWindow -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1757505897 -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1757505897 -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1757505897 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1757597725 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1757597725 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1757597725 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* @@ -23439,6 +23439,7 @@ ImgOps | https://imgops.com/#b#`; },3000); }, setPosition:function(){ + if (!this.data.img) return; var position=getContentClientRect(this.data.img); var cs=this.loadingAnim.style; var scrolled=getScrolled(); @@ -23572,7 +23573,7 @@ ImgOps | https://imgops.com/#b#`; }; var self=this; - function openInTop(){ + async function openInTop(){ var data=self.data; //删除不能发送的项。 @@ -23593,6 +23594,15 @@ ImgOps | https://imgops.com/#b#`; delCantClone(data); }; + if(!gallery){ + gallery=new GalleryC(); + gallery.data=[]; + } + let allData=(await gallery.getAllValidImgs()).map(item => item.src); + allData = allData.filter((item, index) => { + return allData.indexOf(item) === index; + }); + data.all = allData; window.postMessage({ messageID:messageID, src:img.src, From b3eda9bc4438228b9937f0b23eea958035d2df2e Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 14 Sep 2025 22:57:03 +0900 Subject: [PATCH 0895/1065] Update build-dist.yml --- .github/workflows/build-dist.yml | 54 +++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index 5d4053480f2..db9b72a7711 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -16,19 +16,59 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Replace require paths, add timestamp, and create dist file + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install Terser + run: npm install terser -g + + - name: Build and Minify User Script run: | + set -e + TIMESTAMP=$(date +%s) + SOURCE_FILE="Picviewer CE+/Picviewer CE+.user.js" + DIST_FILE="Picviewer CE+/dist.user.js" + + TEMP_DIR=$(mktemp -d) + TEMP_PROCESSED_FILE="$TEMP_DIR/processed.user.js" + HEADER_FILE="$TEMP_DIR/header.txt" + BODY_FILE="$TEMP_DIR/body.js" + MINIFIED_BODY_FILE="$TEMP_DIR/body.min.js" + + echo "Step 1: Replacing paths and adding timestamp..." + sed -e "s#https://update.greasyfork.org/scripts/6158/[0-9]\+/GM_config%20CN.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=$TIMESTAMP#" \ + -e "s#https://update.greasyfork.org/scripts/438080/[0-9]\+/pvcep_rules.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=$TIMESTAMP#" \ + -e "s#https://update.greasyfork.org/scripts/440698/[0-9]\+/pvcep_lang.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=$TIMESTAMP#" \ + "$SOURCE_FILE" > "$TEMP_PROCESSED_FILE" + echo "Path replacement complete." - sed -e "s#https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=$TIMESTAMP#" \ - -e "s#https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=$TIMESTAMP#" \ - -e "s#https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=$TIMESTAMP#" \ - "Picviewer CE+/Picviewer CE+.user.js" > "Picviewer CE+/dist.user.js" + echo "Step 2: Separating UserScript header and body..." + sed -n '/\/\/ ==UserScript==/,/\/\/ ==\/UserScript==/p' "$TEMP_PROCESSED_FILE" > "$HEADER_FILE" + sed '1,/\/\/ ==\/UserScript==/d' "$TEMP_PROCESSED_FILE" > "$BODY_FILE" + echo "Header and body separated." + + echo "Step 3: Minifying the script body with Terser..." + terser "$BODY_FILE" --compress --mangle -o "$MINIFIED_BODY_FILE" + echo "Minification complete." + + echo "Step 4: Combining header and minified body..." + cat "$HEADER_FILE" > "$DIST_FILE" + echo "" >> "$DIST_FILE" + cat "$MINIFIED_BODY_FILE" >> "$DIST_FILE" + echo "Final dist file created at $DIST_FILE." - 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 with timestamp" - git push https://${{ secrets.ACTION_SECRET }}@github.com/${{ github.repository }} \ No newline at end of file + if git diff --staged --quiet; then + echo "No changes to commit." + else + git commit -m "chore(Picviewer CE+): Auto-generate and minify dist.user.js" + git push https://${{ secrets.ACTION_SECRET }}@github.com/${{ github.repository }} + fi + From 113d601eefac095ebfab0b6718b7660ac1d4e879 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 17 Sep 2025 20:14:06 +0900 Subject: [PATCH 0896/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 7b6ae024385..c62ff2313ee 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -21626,8 +21626,8 @@ ImgOps | https://imgops.com/#b#`; min-width:unset;\ max-height:unset;\ min-height:unset;\ - width:inherit;\ - height:inherit;\ + width:inherit!important;\ + height:inherit!important;\ padding:0;\ margin:0;\ border:none;\ From b76ffcb7072ddf65602db09b8566dffe9c3223bc Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 17 Sep 2025 20:19:34 +0900 Subject: [PATCH 0897/1065] Revert "Update build-dist.yml" This reverts commit b3eda9bc4438228b9937f0b23eea958035d2df2e. --- .github/workflows/build-dist.yml | 54 +++++--------------------------- 1 file changed, 7 insertions(+), 47 deletions(-) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index db9b72a7711..5d4053480f2 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -16,59 +16,19 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Set up Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - - - name: Install Terser - run: npm install terser -g - - - name: Build and Minify User Script + - name: Replace require paths, add timestamp, and create dist file run: | - set -e - TIMESTAMP=$(date +%s) - SOURCE_FILE="Picviewer CE+/Picviewer CE+.user.js" - DIST_FILE="Picviewer CE+/dist.user.js" - - TEMP_DIR=$(mktemp -d) - TEMP_PROCESSED_FILE="$TEMP_DIR/processed.user.js" - HEADER_FILE="$TEMP_DIR/header.txt" - BODY_FILE="$TEMP_DIR/body.js" - MINIFIED_BODY_FILE="$TEMP_DIR/body.min.js" - - echo "Step 1: Replacing paths and adding timestamp..." - sed -e "s#https://update.greasyfork.org/scripts/6158/[0-9]\+/GM_config%20CN.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=$TIMESTAMP#" \ - -e "s#https://update.greasyfork.org/scripts/438080/[0-9]\+/pvcep_rules.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=$TIMESTAMP#" \ - -e "s#https://update.greasyfork.org/scripts/440698/[0-9]\+/pvcep_lang.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=$TIMESTAMP#" \ - "$SOURCE_FILE" > "$TEMP_PROCESSED_FILE" - echo "Path replacement complete." - echo "Step 2: Separating UserScript header and body..." - sed -n '/\/\/ ==UserScript==/,/\/\/ ==\/UserScript==/p' "$TEMP_PROCESSED_FILE" > "$HEADER_FILE" - sed '1,/\/\/ ==\/UserScript==/d' "$TEMP_PROCESSED_FILE" > "$BODY_FILE" - echo "Header and body separated." - - echo "Step 3: Minifying the script body with Terser..." - terser "$BODY_FILE" --compress --mangle -o "$MINIFIED_BODY_FILE" - echo "Minification complete." - - echo "Step 4: Combining header and minified body..." - cat "$HEADER_FILE" > "$DIST_FILE" - echo "" >> "$DIST_FILE" - cat "$MINIFIED_BODY_FILE" >> "$DIST_FILE" - echo "Final dist file created at $DIST_FILE." + sed -e "s#https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=$TIMESTAMP#" \ + -e "s#https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=$TIMESTAMP#" \ + -e "s#https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=$TIMESTAMP#" \ + "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" - if git diff --staged --quiet; then - echo "No changes to commit." - else - git commit -m "chore(Picviewer CE+): Auto-generate and minify dist.user.js" - git push https://${{ secrets.ACTION_SECRET }}@github.com/${{ github.repository }} - fi - + git commit -m "chore(Picviewer CE+): Auto-generate dist.user.js with timestamp" + git push https://${{ secrets.ACTION_SECRET }}@github.com/${{ github.repository }} \ No newline at end of file From 2b9d4708ac79073702856ca7e8393558da4c855a Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 21 Sep 2025 18:15:47 +0900 Subject: [PATCH 0898/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 1681c198b16..61a294a9005 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1043,14 +1043,13 @@ var siteInfo = [ const re = /^https?:\/\/(?:www\.)?(?:(realbooru\.com|rule34\.xxx))\/index\.php\?page=post&s=view&id=(\d+).*/; const m = a.href.match(re); if (m) { - return m[1] == "rule34.xxx" ? `https://api.${m[1]}/index.php?page=dapi&s=post&q=index&id=${m[2]}&json=1` : `https://${m[1]}/index.php?page=dapi&s=post&q=index&id=${m[2]}&json=1`; + return a.href; } }, query: function(html, doc, url) { try { - const o = JSON.parse(html); - let url = o[0]; - return url.file_url || `https://${location.hostname}/images/${url.directory}/${url.image}`; + const o = doc.querySelector(".link-list>ul>li>a[href^=http]"); + return o && o.href; } catch { } } } From 14dbc3bce91adcc434ac40d2b51e3b14a4bb5b98 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 21 Sep 2025 18:16:43 +0900 Subject: [PATCH 0899/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index c62ff2313ee..2f7610ddf7b 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.11.1 +// @version 2025.9.21.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1664500/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js // @match *://*/* // @exclude http://www.toodledo.com/tasks/* From 7b7b1611367661c9b198e09b0a8c39245c3143fc Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 21 Sep 2025 09:16:54 +0000 Subject: [PATCH 0900/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index d664e6cbef1..5bf9939bc48 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.9.11.1 +// @version 2025.9.21.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -45,9 +45,9 @@ // @grant GM.registerMenuCommand // @grant GM.notification // @grant unsafeWindow -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1757597725 -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1757597725 -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1757597725 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1758446213 +// @require https://update.greasyfork.org/scripts/438080/1664500/pvcep_rules.js +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1758446213 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* @@ -21626,8 +21626,8 @@ ImgOps | https://imgops.com/#b#`; min-width:unset;\ max-height:unset;\ min-height:unset;\ - width:inherit;\ - height:inherit;\ + width:inherit!important;\ + height:inherit!important;\ padding:0;\ margin:0;\ border:none;\ From 00e21d9cc7496a2902c0d55a76b3f53cbc1a408f Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 21 Sep 2025 19:32:04 +0900 Subject: [PATCH 0901/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 2f7610ddf7b..2a4470fb7cb 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.21.1 +// @version 2025.9.21.2 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -15837,10 +15837,14 @@ ImgOps | https://imgops.com/#b#`; }, prefs.gallery.downloadGap); }; let threadNum = 10; + if (prefs.gallery.downloadGap > 500) { + threadNum = 1; + } else if (prefs.gallery.downloadGap > 100) { + threadNum = 5; + } let downIntv = setInterval(() => { - if (threadNum-- === 0) { + if (--threadNum === 0) { clearInterval(downIntv); - return; } let saveParam = saveParams && saveParams.shift(); if (!saveParam) clearInterval(downIntv); @@ -19847,6 +19851,9 @@ ImgOps | https://imgops.com/#b#`; GalleryC.prototype.Preload.prototype.container=div; }; this.max=prefs.gallery.max; + if (prefs.gallery.downloadGap > 500) { + this.max = 0; + } this.nextNumber=0; this.nextEle=this.ele; this.preNumber=0; From ae6c200cded606160611f51d668f3e2437c8710c Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 21 Sep 2025 10:32:16 +0000 Subject: [PATCH 0902/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 5bf9939bc48..7924c3b8bb0 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.9.21.1 +// @version 2025.9.21.2 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -45,9 +45,9 @@ // @grant GM.registerMenuCommand // @grant GM.notification // @grant unsafeWindow -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1758446213 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1758450736 // @require https://update.greasyfork.org/scripts/438080/1664500/pvcep_rules.js -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1758446213 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1758450736 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* @@ -15837,10 +15837,14 @@ ImgOps | https://imgops.com/#b#`; }, prefs.gallery.downloadGap); }; let threadNum = 10; + if (prefs.gallery.downloadGap > 500) { + threadNum = 1; + } else if (prefs.gallery.downloadGap > 100) { + threadNum = 5; + } let downIntv = setInterval(() => { - if (threadNum-- === 0) { + if (--threadNum === 0) { clearInterval(downIntv); - return; } let saveParam = saveParams && saveParams.shift(); if (!saveParam) clearInterval(downIntv); @@ -19847,6 +19851,9 @@ ImgOps | https://imgops.com/#b#`; GalleryC.prototype.Preload.prototype.container=div; }; this.max=prefs.gallery.max; + if (prefs.gallery.downloadGap > 500) { + this.max = 0; + } this.nextNumber=0; this.nextEle=this.ele; this.preNumber=0; From 3607242c9b7e8093c8b4ec526a01ad706ccb0b7d Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 21 Sep 2025 19:40:48 +0900 Subject: [PATCH 0903/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 2a4470fb7cb..88248a374cc 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12928,18 +12928,19 @@ ImgOps | https://imgops.com/#b#`; unsafeWindow.URL.createObjectURL = createObjectURLProxy; } - function downloadImg(url, name, type, errCb) { + function downloadImg(url, name, type, over) { urlToBlob(url, (blob, ext) => { if(blob){ try { saveAs(blob, (prefs.saveNameAddTitle ? document.title.replace(/[\*\/:<>\?\\\|]/g, "") + " - " : "") + getRightSaveName(url, name, type, ext)); + over && over(); } catch(e) { _GM_download(url, name, type); - if (errCb) errCb(); + over && over(); } }else{ _GM_download(url, name, type); - if (errCb) errCb(); + over && over(); } }); } @@ -15857,9 +15858,14 @@ ImgOps | https://imgops.com/#b#`; } return; } - - let download5Times=function(){ - for(let i=0;i<5;i++){ + let threadNum = 10; + if (prefs.gallery.downloadGap > 500) { + threadNum = 1; + } else if (prefs.gallery.downloadGap > 100) { + threadNum = 5; + } + let downloadMulTimes=function(){ + for(let i=0;i0){ setTimeout(()=>{ - download5Times(); - },1000); + downloadMulTimes(); + },prefs.gallery.downloadGap); } }; - download5Times(); + downloadMulTimes(); }, changeMinView:function(){ var sizeInputH=this.sizeInputH; From 935bf368d1f3f474f1cde518abdd0e6fa046c693 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 21 Sep 2025 20:18:05 +0900 Subject: [PATCH 0904/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 44 +++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 88248a374cc..7b111a6a560 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12220,7 +12220,7 @@ ImgOps | https://imgops.com/#b#`; function urlToBlobWithFetch(urlString, cb){ fetch(urlString).then(response => response.blob()).then(blob => { let ext = blob.type.replace(/.*image\/([\w\-]+).*/, "$1"); - if (ext === "text/html" && (blob.size || 0) < 1000) return cb(null, ''); + if (ext && ext.indexOf("text/html") === 0 && (blob.size || 0) < 1000) return cb(null, ''); if (ext === "none") ext = "webp"; let conversion = formatDict.get(ext); if (canvas && conversion) { @@ -12416,7 +12416,10 @@ ImgOps | https://imgops.com/#b#`; let blob = d.response; if (!blob.type) return urlToBlob(url, cb, forcePng, tryTimes); let ext = blob.type.replace(/.*image\/([\w\-]+).*/, "$1"); - if (ext === "text/html" && (blob.size || 0) < 1000) return cb(null, ''); + if (ext && ext.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)) { @@ -12929,8 +12932,13 @@ ImgOps | https://imgops.com/#b#`; } function downloadImg(url, name, type, over) { - urlToBlob(url, (blob, ext) => { - if(blob){ + if(canvas && (/^data:/.test(url) || url.split("/")[2] == document.domain)){ + urlToBlobWithFetch(url, (blob, ext)=>{ + if(!blob){ + _GM_download(url, name, type); + over && over(); + return; + } try { saveAs(blob, (prefs.saveNameAddTitle ? document.title.replace(/[\*\/:<>\?\\\|]/g, "") + " - " : "") + getRightSaveName(url, name, type, ext)); over && over(); @@ -12938,11 +12946,23 @@ ImgOps | https://imgops.com/#b#`; _GM_download(url, name, type); over && over(); } - }else{ - _GM_download(url, name, type); - over && over(); - } - }); + }); + } else { + urlToBlob(url, (blob, ext) => { + if(blob){ + try { + saveAs(blob, (prefs.saveNameAddTitle ? document.title.replace(/[\*\/:<>\?\\\|]/g, "") + " - " : "") + getRightSaveName(url, name, type, ext)); + over && over(); + } catch(e) { + _GM_download(url, name, type); + over && over(); + } + }else{ + _GM_download(url, name, type); + over && over(); + } + }); + } } function getBlob(url) { @@ -14676,7 +14696,7 @@ ImgOps | https://imgops.com/#b#`; let xhr = dataset(node, 'xhr') !== 'stop' && self.getPropBySpanMark(node, "xhr"); if (xhr) { - self.showTips("Sending request..."); + self.showTips("Sending request...", 3000); await new Promise(resolve => { setTimeout(() => { let xhrError = function() { @@ -15506,6 +15526,7 @@ ImgOps | https://imgops.com/#b#`; saveIndex++; if (conItem.dataset.xhr) { + self.showTips("Sending request...", 3000); await new Promise((resolve) => { let getxhroverHandler = e => { conItem.removeEventListener('getxhrover', getxhroverHandler); @@ -15865,6 +15886,7 @@ ImgOps | https://imgops.com/#b#`; threadNum = 5; } let downloadMulTimes=function(){ + self.showTips("Downloading...", 3000); for(let i=0;i Date: Sun, 21 Sep 2025 11:18:20 +0000 Subject: [PATCH 0905/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 70 ++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 7924c3b8bb0..85fb6dad1b1 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -45,9 +45,9 @@ // @grant GM.registerMenuCommand // @grant GM.notification // @grant unsafeWindow -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1758450736 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1758453500 // @require https://update.greasyfork.org/scripts/438080/1664500/pvcep_rules.js -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1758450736 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1758453500 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* @@ -12220,7 +12220,7 @@ ImgOps | https://imgops.com/#b#`; function urlToBlobWithFetch(urlString, cb){ fetch(urlString).then(response => response.blob()).then(blob => { let ext = blob.type.replace(/.*image\/([\w\-]+).*/, "$1"); - if (ext === "text/html" && (blob.size || 0) < 1000) return cb(null, ''); + if (ext && ext.indexOf("text/html") === 0 && (blob.size || 0) < 1000) return cb(null, ''); if (ext === "none") ext = "webp"; let conversion = formatDict.get(ext); if (canvas && conversion) { @@ -12416,7 +12416,10 @@ ImgOps | https://imgops.com/#b#`; let blob = d.response; if (!blob.type) return urlToBlob(url, cb, forcePng, tryTimes); let ext = blob.type.replace(/.*image\/([\w\-]+).*/, "$1"); - if (ext === "text/html" && (blob.size || 0) < 1000) return cb(null, ''); + if (ext && ext.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)) { @@ -12928,20 +12931,38 @@ ImgOps | https://imgops.com/#b#`; unsafeWindow.URL.createObjectURL = createObjectURLProxy; } - function downloadImg(url, name, type, errCb) { - urlToBlob(url, (blob, ext) => { - if(blob){ + function downloadImg(url, name, type, over) { + if(canvas && (/^data:/.test(url) || url.split("/")[2] == document.domain)){ + urlToBlobWithFetch(url, (blob, ext)=>{ + if(!blob){ + _GM_download(url, name, type); + over && over(); + return; + } try { saveAs(blob, (prefs.saveNameAddTitle ? document.title.replace(/[\*\/:<>\?\\\|]/g, "") + " - " : "") + getRightSaveName(url, name, type, ext)); + over && over(); } catch(e) { _GM_download(url, name, type); - if (errCb) errCb(); + over && over(); } - }else{ - _GM_download(url, name, type); - if (errCb) errCb(); - } - }); + }); + } else { + urlToBlob(url, (blob, ext) => { + if(blob){ + try { + saveAs(blob, (prefs.saveNameAddTitle ? document.title.replace(/[\*\/:<>\?\\\|]/g, "") + " - " : "") + getRightSaveName(url, name, type, ext)); + over && over(); + } catch(e) { + _GM_download(url, name, type); + over && over(); + } + }else{ + _GM_download(url, name, type); + over && over(); + } + }); + } } function getBlob(url) { @@ -14675,7 +14696,7 @@ ImgOps | https://imgops.com/#b#`; let xhr = dataset(node, 'xhr') !== 'stop' && self.getPropBySpanMark(node, "xhr"); if (xhr) { - self.showTips("Sending request..."); + self.showTips("Sending request...", 3000); await new Promise(resolve => { setTimeout(() => { let xhrError = function() { @@ -15505,6 +15526,7 @@ ImgOps | https://imgops.com/#b#`; saveIndex++; if (conItem.dataset.xhr) { + self.showTips("Sending request...", 3000); await new Promise((resolve) => { let getxhroverHandler = e => { conItem.removeEventListener('getxhrover', getxhroverHandler); @@ -15857,9 +15879,15 @@ ImgOps | https://imgops.com/#b#`; } return; } - - let download5Times=function(){ - for(let i=0;i<5;i++){ + let threadNum = 10; + if (prefs.gallery.downloadGap > 500) { + threadNum = 1; + } else if (prefs.gallery.downloadGap > 100) { + threadNum = 5; + } + let downloadMulTimes=function(){ + self.showTips("Downloading...", 3000); + for(let i=0;i0){ setTimeout(()=>{ - download5Times(); - },1000); + downloadMulTimes(); + },prefs.gallery.downloadGap); } }; - download5Times(); + downloadMulTimes(); }, changeMinView:function(){ var sizeInputH=this.sizeInputH; @@ -16349,7 +16377,7 @@ ImgOps | https://imgops.com/#b#`; }; let xhr = dataset(node, 'xhr') !== 'stop' && self.getPropBySpanMark(node, "xhr"); if (xhr) { - self.showTips("Sending request..."); + self.showTips("Sending request...", 3000); let imgSrc = await getXhr(); if (imgSrc) { loadImg(); From 58f321512dcc4d31aff752e91ffda5754487257b Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 21 Sep 2025 20:27:17 +0900 Subject: [PATCH 0906/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 7b111a6a560..3237d1e04e5 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -16254,6 +16254,10 @@ ImgOps | https://imgops.com/#b#`; imgSpan.addEventListener('getxhr', getXhrHandler); } imgSpan.addEventListener("click", async function(e) { + if (maximizeContainer.classList.contains("checked")) { + imgSpan.querySelector("input").click(); + return; + } e.preventDefault(); self.selectViewmore(imgSpan, curNode.dataset.src); let loadError = e => { From a6775bab3c0001af3d3bd59ac1007389a33f8c88 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 21 Sep 2025 11:27:28 +0000 Subject: [PATCH 0907/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 85fb6dad1b1..1608d33bb9c 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -45,9 +45,9 @@ // @grant GM.registerMenuCommand // @grant GM.notification // @grant unsafeWindow -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1758453500 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1758454047 // @require https://update.greasyfork.org/scripts/438080/1664500/pvcep_rules.js -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1758453500 +// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1758454047 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* @@ -16254,6 +16254,10 @@ ImgOps | https://imgops.com/#b#`; imgSpan.addEventListener('getxhr', getXhrHandler); } imgSpan.addEventListener("click", async function(e) { + if (maximizeContainer.classList.contains("checked")) { + imgSpan.querySelector("input").click(); + return; + } e.preventDefault(); self.selectViewmore(imgSpan, curNode.dataset.src); let loadError = e => { From d384b18d6c6ed482c22ef5ccec2fc07c2cd12988 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 21 Sep 2025 21:05:22 +0900 Subject: [PATCH 0908/1065] Update build-dist.yml --- .github/workflows/build-dist.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index 5d4053480f2..c2c383a628e 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -20,9 +20,9 @@ jobs: run: | TIMESTAMP=$(date +%s) - sed -e "s#https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=$TIMESTAMP#" \ - -e "s#https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=$TIMESTAMP#" \ - -e "s#https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js#http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=$TIMESTAMP#" \ + sed -e "s#https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js#https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=$TIMESTAMP#" \ + -e "s#https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js#https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=$TIMESTAMP#" \ + -e "s#https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js#https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=$TIMESTAMP#" \ "Picviewer CE+/Picviewer CE+.user.js" > "Picviewer CE+/dist.user.js" - name: Commit and push dist.user.js @@ -31,4 +31,4 @@ jobs: 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 with timestamp" - git push https://${{ secrets.ACTION_SECRET }}@github.com/${{ github.repository }} \ No newline at end of file + git push https://${{ secrets.ACTION_SECRET }}@github.com/${{ github.repository }} From b1614d46c21709eb3e6bad691f923ff4e1758330 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 21 Sep 2025 12:07:12 +0000 Subject: [PATCH 0909/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 1608d33bb9c..264424cb9ce 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -45,9 +45,9 @@ // @grant GM.registerMenuCommand // @grant GM.notification // @grant unsafeWindow -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1758454047 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1758456432 // @require https://update.greasyfork.org/scripts/438080/1664500/pvcep_rules.js -// @require http://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1758454047 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1758456432 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* From bdad502664683a8ae26bdcb73bd181a13e602e85 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 21 Sep 2025 21:11:47 +0900 Subject: [PATCH 0910/1065] Update build-dist.yml --- .github/workflows/build-dist.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index c2c383a628e..f91248a171e 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -18,11 +18,9 @@ jobs: - name: Replace require paths, add timestamp, and create dist file run: | - TIMESTAMP=$(date +%s) - - sed -e "s#https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js#https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=$TIMESTAMP#" \ - -e "s#https://update.greasyfork.org/scripts/438080/1655629/pvcep_rules.js#https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=$TIMESTAMP#" \ - -e "s#https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js#https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=$TIMESTAMP#" \ + sed -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#" \ + -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#" \ + -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#" \ "Picviewer CE+/Picviewer CE+.user.js" > "Picviewer CE+/dist.user.js" - name: Commit and push dist.user.js From adb12606ab1b4c5726d978fc5e465882a5704198 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 21 Sep 2025 21:16:34 +0900 Subject: [PATCH 0911/1065] Update build-dist.yml --- .github/workflows/build-dist.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index f91248a171e..4ad8cabf542 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -18,10 +18,11 @@ jobs: - name: Replace require paths, add timestamp, and create dist file run: | - sed -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#" \ - -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#" \ - -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#" \ - "Picviewer CE+/Picviewer CE+.user.js" > "Picviewer CE+/dist.user.js" + 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: | From e5914d4019de15cf0d31ed73ecff8398bf0645aa Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 21 Sep 2025 12:17:05 +0000 Subject: [PATCH 0912/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 264424cb9ce..fdcab2bebcb 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -45,9 +45,9 @@ // @grant GM.registerMenuCommand // @grant GM.notification // @grant unsafeWindow -// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=1758456432 -// @require https://update.greasyfork.org/scripts/438080/1664500/pvcep_rules.js -// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1758456432 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=23710 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1664500 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1653424 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* From 724c844ef0e4eec007a57b2a73ecebfea5599fbd Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 21 Sep 2025 23:47:32 +0900 Subject: [PATCH 0913/1065] 1.9.37.124 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index d10465d01b4..c4fcad3d2c6 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.123](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.124](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index f9c24858c4f..2b03ef4a593 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.123 +// @version 1.9.37.124 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -5568,7 +5568,7 @@ posEle = posEle.previousElementSibling || posEle.parentNode; } if (posEle && posEle.lastElementChild) { - if (posEle.scrollHeight === 0) posEle = posEle.lastElementChild; + if (posEle.scrollHeight === 0 && posEle.lastElementChild.offsetParent) posEle = posEle.lastElementChild; else if (posEle.lastElementChild.offsetTop > 500) { posEle = posEle.lastElementChild; } @@ -7618,7 +7618,7 @@ text-shadow: rgb(255 255 255) 0px 0px 10px; } #pagetual-sideController #pagetual-sideController-pagenum { - font-size: 15px!important; + font-size: 12px!important; line-height: 30px; text-align: center; position: absolute; @@ -9950,6 +9950,12 @@ configCon.appendChild(blacklistBtn); configCon.appendChild(blacklistInput); let saveBtn = document.createElement("button"); + langSelect.onchange = e => { + saveBtn.click(); + setTimeout(() => { + location.reload(); + }, 500); + }; saveBtn.innerHTML = i18n("save"); saveBtn.id = "saveBtn"; configCon.appendChild(saveBtn); @@ -10328,7 +10334,9 @@ }, 100); } _GM_registerMenuCommand(i18n("configure"), () => { - _GM_openInTab(rulesData.configPage || configPage[0], {active: true}); + if (window.top == window.self) { + _GM_openInTab(rulesData.configPage || configPage[0], {active: true}); + } }); if (rulesData.blacklist && rulesData.blacklist.length > 0) { let href = location.href.slice(0, 500); @@ -10411,7 +10419,7 @@ rulesData.updateNotification = true; } if (typeof(rulesData.initRun) == "undefined") { - rulesData.initRun = true; + rulesData.initRun = false; } if (typeof(rulesData.preload) == "undefined") { rulesData.preload = false; @@ -10669,6 +10677,11 @@ if (!ruleParser.curSiteRule.smart || !xhrFailed) { xhrFailed = true; return callback(false); + } else { + if (!ruleParser.curSiteRule.sleep) { + ruleParser.curSiteRule.sleep = 1000; + return callback(false); + } } } if (inCors && (!pageElement || pageElement.length == 0) && ruleParser.curSiteRule.smart) { @@ -11800,7 +11813,7 @@ example = compareNodeName(example, ["tr", "tbody"]) ? example : example.nextElementSibling || example; if (compareNodeName(example, ["tbody"])) example = example.querySelector("tr"); let nextTr = example; - while (nextTr && nextTr.children.length == 0) nextTr = nextTr.nextElementSibling; + while (nextTr && (nextTr.children.length == 0 || (nextTr.children.length == 1 && !nextTr.children[0].offsetParent))) nextTr = nextTr.nextElementSibling; if (nextTr) example = nextTr; let tdNum = 0; if (exampleStyle.display == "table-row") { From 05b982fb608976fd4edd95a4c0d2ff3352ec84df Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 22 Sep 2025 17:27:23 +0900 Subject: [PATCH 0914/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 60 +++++++++++++++++------------ 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 3237d1e04e5..43ee1eda989 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.21.2 +// @version 2025.9.22.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -18193,7 +18193,7 @@ ImgOps | https://imgops.com/#b#`; total.push(node); } } else if (/^a$/i.test(node.nodeName)) { - if (imageReg.test(node.href)) { + if (node.href && node.href.length < 300 && imageReg.test(node.href)) { let src = node.href; if (/[&\?]url\=/.test(src)) { src = src.replace(/.*[&\?]url\=(.*?)(&.*|$)/, "$1"); @@ -18413,30 +18413,30 @@ ImgOps | https://imgops.com/#b#`; } scrollTarget = scrollTarget || document.documentElement; var self = this; - setTimeout(() => { - self.isScrollToEndAndReloading = false; - var des = document.documentElement.style; - des.overflow = ''; - document.head.appendChild(self.hideScrollStyle); - let scrollIntv = setInterval(function() { - let scrollTop = scrollTarget.scrollTop; - scrollTarget.scrollTop += 500; - if (scrollTop === scrollTarget.scrollTop) { - clearInterval(scrollIntv); - setTimeout(() => { - des.overflow = 'hidden'; - document.head.removeChild(self.hideScrollStyle); - }, 0); - clearTimeout(self.reloadTimeout); - self.reloadTimeout = setTimeout(function() { - self.reloadNew(); - self.loadThumb(); - }, 1000); - } else { + var des = document.documentElement.style; + des.overflow = ''; + document.head.appendChild(self.hideScrollStyle); + let scrollIntv = setInterval(function() { + let scrollTop = scrollTarget.scrollTop; + scrollTarget.scrollTop += 800; + if (scrollTop === scrollTarget.scrollTop) { + clearInterval(scrollIntv); + self.isScrollToEndAndReloading = false; + setTimeout(() => { + des.overflow = 'hidden'; + document.head.removeChild(self.hideScrollStyle); + }, 0); + if (self.lastScrollTop == scrollTop) return; + clearTimeout(self.reloadTimeout); + self.reloadTimeout = setTimeout(function() { self.reloadNew(); - } - }, 1); - }, 300); + self.loadThumb(); + self.lastScrollTop = scrollTop; + }, 300); + } else { + self.reloadNew(); + } + }, 150); }, exportImages: function () {// 导出所有图片到新窗口 var nodes = this.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]:not(.ignore)'),i; @@ -19483,6 +19483,16 @@ ImgOps | https://imgops.com/#b#`; .pv-gallery-maximize-container.checked span>.pv-top-banner{\ opacity: 0.6;\ }\ + .pv-gallery-maximize-container+p>input{\ + width:min-content;\ + border: 1px solid transparent;\ + border-bottom-color: #a3a3a3;\ + }\ + .pv-gallery-maximize-container+p>input:hover{\ + border-color: white;\ + background: #333;\ + color: white;\ + }\ .pv-gallery-maximize-container+p>input.compareBtn{\ display: none;\ }\ From a60962cde0d8372bfcc92ff73364e39f159f007d Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Mon, 22 Sep 2025 08:27:34 +0000 Subject: [PATCH 0915/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 60 ++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index fdcab2bebcb..6575a5bbcaf 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.9.21.2 +// @version 2025.9.22.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -18193,7 +18193,7 @@ ImgOps | https://imgops.com/#b#`; total.push(node); } } else if (/^a$/i.test(node.nodeName)) { - if (imageReg.test(node.href)) { + if (node.href && node.href.length < 300 && imageReg.test(node.href)) { let src = node.href; if (/[&\?]url\=/.test(src)) { src = src.replace(/.*[&\?]url\=(.*?)(&.*|$)/, "$1"); @@ -18413,30 +18413,30 @@ ImgOps | https://imgops.com/#b#`; } scrollTarget = scrollTarget || document.documentElement; var self = this; - setTimeout(() => { - self.isScrollToEndAndReloading = false; - var des = document.documentElement.style; - des.overflow = ''; - document.head.appendChild(self.hideScrollStyle); - let scrollIntv = setInterval(function() { - let scrollTop = scrollTarget.scrollTop; - scrollTarget.scrollTop += 500; - if (scrollTop === scrollTarget.scrollTop) { - clearInterval(scrollIntv); - setTimeout(() => { - des.overflow = 'hidden'; - document.head.removeChild(self.hideScrollStyle); - }, 0); - clearTimeout(self.reloadTimeout); - self.reloadTimeout = setTimeout(function() { - self.reloadNew(); - self.loadThumb(); - }, 1000); - } else { + var des = document.documentElement.style; + des.overflow = ''; + document.head.appendChild(self.hideScrollStyle); + let scrollIntv = setInterval(function() { + let scrollTop = scrollTarget.scrollTop; + scrollTarget.scrollTop += 800; + if (scrollTop === scrollTarget.scrollTop) { + clearInterval(scrollIntv); + self.isScrollToEndAndReloading = false; + setTimeout(() => { + des.overflow = 'hidden'; + document.head.removeChild(self.hideScrollStyle); + }, 0); + if (self.lastScrollTop == scrollTop) return; + clearTimeout(self.reloadTimeout); + self.reloadTimeout = setTimeout(function() { self.reloadNew(); - } - }, 1); - }, 300); + self.loadThumb(); + self.lastScrollTop = scrollTop; + }, 300); + } else { + self.reloadNew(); + } + }, 150); }, exportImages: function () {// 导出所有图片到新窗口 var nodes = this.eleMaps['sidebar-thumbnails-container'].querySelectorAll('.pv-gallery-sidebar-thumb-container[data-src]:not(.ignore)'),i; @@ -19483,6 +19483,16 @@ ImgOps | https://imgops.com/#b#`; .pv-gallery-maximize-container.checked span>.pv-top-banner{\ opacity: 0.6;\ }\ + .pv-gallery-maximize-container+p>input{\ + width:min-content;\ + border: 1px solid transparent;\ + border-bottom-color: #a3a3a3;\ + }\ + .pv-gallery-maximize-container+p>input:hover{\ + border-color: white;\ + background: #333;\ + color: white;\ + }\ .pv-gallery-maximize-container+p>input.compareBtn{\ display: none;\ }\ From bb90de1412c61738ef876e3eb0ba5a19437ea0c8 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 24 Sep 2025 16:55:13 +0900 Subject: [PATCH 0916/1065] Update flashViewer.user.js --- FlashViewer-HTML5 Video/flashViewer.user.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/FlashViewer-HTML5 Video/flashViewer.user.js b/FlashViewer-HTML5 Video/flashViewer.user.js index f6d953c7643..86a8f8e6620 100644 --- a/FlashViewer-HTML5 Video/flashViewer.user.js +++ b/FlashViewer-HTML5 Video/flashViewer.user.js @@ -2,9 +2,9 @@ // @name flashViewer // @author NLF & Hoothin // @description 围观Flash,增加 HTML5 视频速度与亮度调整 -// @version 1.2.1.8 +// @version 1.2.1.9 // @created 2013-12-27 -// @lastUpdated 2024-8-10 +// @lastUpdated 2025-9-24 // @grant none // @run-at document-start // @namespace http://userscripts.org/users/NLF @@ -1555,6 +1555,7 @@ minHeight: 150, scale: function (e) { + if (this.pinned || this.maximized) return; if (e.deltaY > 0) { this.zoomLevel += -0.1; if (this.zoomLevel > 3) this.zoomLevel = 1; @@ -1635,7 +1636,7 @@ var vNodeName = video.nodeName; // 如果是这些元素,那么pin的时候直接用fixed方式(这些元素随便调整position不会引发重载) - var fixedPin = /^(?:IFRAME|VIDEO|AUDIO)$/.test(vNodeName); + var fixedPin = /^(?:IFRAME|VIDEO|AUDIO|CANVAS)$/.test(vNodeName); this.fixedPin = fixedPin; video.fvPopVideo = true;// 标记弹出中。 @@ -3843,7 +3844,7 @@ } // 可弹出元素 - const availableNode = /^(?:OBJECT|EMBED|VIDEO|AUDIO|IFRAME)$/i; + const availableNode = /^(?:OBJECT|EMBED|VIDEO|AUDIO|IFRAME|CANVAS)$/i; if (!availableNode.test(tNName)) { target = null; if (document.elementsFromPoint) { From 464b3876a353a536ed0b048f0fe0064dd4af45a9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 24 Sep 2025 17:01:20 +0900 Subject: [PATCH 0917/1065] Update flashViewer.user.js --- FlashViewer-HTML5 Video/flashViewer.user.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/FlashViewer-HTML5 Video/flashViewer.user.js b/FlashViewer-HTML5 Video/flashViewer.user.js index 86a8f8e6620..e3f508f5e90 100644 --- a/FlashViewer-HTML5 Video/flashViewer.user.js +++ b/FlashViewer-HTML5 Video/flashViewer.user.js @@ -1642,7 +1642,9 @@ video.fvPopVideo = true;// 标记弹出中。 this.zoomLevel = 1; video.addEventListener("wheel", this.scale.bind(this)); - video.addEventListener("mousedown", this.videoMouseDown.bind(this), true); + if (vNodeName === "VIDEO") { + video.addEventListener("mousedown", this.videoMouseDown.bind(this), true); + } // 很多网站加载flash为了兼容现代浏览器和ie,经常使用 object classid嵌套object或者embed的格式 var vPEIsObject; From 5e390a40d74e87d594b7da67d0c0f5550bbea25d Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 24 Sep 2025 17:04:32 +0900 Subject: [PATCH 0918/1065] Update README.md --- FlashViewer-HTML5 Video/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FlashViewer-HTML5 Video/README.md b/FlashViewer-HTML5 Video/README.md index f066f20599a..75131a452b8 100644 --- a/FlashViewer-HTML5 Video/README.md +++ b/FlashViewer-HTML5 Video/README.md @@ -1,4 +1,4 @@ -# [FlashViewer](https://github.com/hoothin/UserScripts/raw/master/FlashViewer-HTML5%20Video/flashViewer.user.js) +# [FlashViewer](https://hoothin.github.io/UserScripts/FlashViewer-HTML5%20Video/flashViewer.user.js) HTML5 視頻增強腳本 原作者 NLF From 77499da0414709254b705b89cb46908a9871ee2e Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 24 Sep 2025 21:18:04 +0900 Subject: [PATCH 0919/1065] Update README.md --- FlashViewer-HTML5 Video/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FlashViewer-HTML5 Video/README.md b/FlashViewer-HTML5 Video/README.md index 75131a452b8..94771d645c5 100644 --- a/FlashViewer-HTML5 Video/README.md +++ b/FlashViewer-HTML5 Video/README.md @@ -1,4 +1,4 @@ -# [FlashViewer](https://hoothin.github.io/UserScripts/FlashViewer-HTML5%20Video/flashViewer.user.js) +# [FlashViewer⬇️](https://hoothin.github.io/UserScripts/FlashViewer-HTML5%20Video/flashViewer.user.js) HTML5 視頻增強腳本 原作者 NLF From 4735f1b09aa0fe59846df49d3642e600342d623c Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 25 Sep 2025 22:50:00 +0900 Subject: [PATCH 0920/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 61a294a9005..fa5d76083e6 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1073,7 +1073,7 @@ var siteInfo = [ } return target; }, - r: [/\/w\/\d+\/(h\/\d+\/)?(q\/\d+\/)?/i, /.*\.xhscdn\.com.*\/(\w+)(!.*|$)/i], + r: [/\/w\/\d+\/(h\/\d+\/)?(q\/\d+\/)?/i, /.*\.xhscdn\.com.*\d\/(\w+)(!.*|$)/i], s: ["/w/1080/", "https://sns-img-bd.xhscdn.com/$1"] }, { From bd4e0606f90960514e96caa72c7df1e578f5d94f Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 25 Sep 2025 22:50:59 +0900 Subject: [PATCH 0921/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 43ee1eda989..fec4f2ded3d 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.22.1 +// @version 2025.9.25.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1664500/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1666736/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js // @match *://*/* // @exclude http://www.toodledo.com/tasks/* From 5e4a9c1982b1f7777f76a61ba6406e614c64666f Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 25 Sep 2025 13:51:12 +0000 Subject: [PATCH 0922/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 6575a5bbcaf..b32f1490479 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.9.22.1 +// @version 2025.9.25.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=23710 -// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1664500 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1666736 // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1653424 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* From 5da90838ebc61fd327ee7b06835cd7cec1e3cfbe Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 26 Sep 2025 15:45:35 +0900 Subject: [PATCH 0923/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index fec4f2ded3d..b2144a1a6c9 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.25.1 +// @version 2025.9.26.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -22031,7 +22031,7 @@ ImgOps | https://imgops.com/#b#`; if (!imme && this.following) return; let wSize = getWindowSize(); - let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2, (this.img.naturalWidth || 500)>>1, (this.img.naturalHeight || 500)>>1), padding2 = 50, left, top;//内外侧间距 + let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2, Math.max(this.data.img && this.data.img.clientWidth, this.data.img && this.data.img.clientHeight, 100)>>2), padding2 = 50, left, top;//内外侧间距 imgWindow.style.position = "fixed"; let scrolled = {x: 0, y: 0}; From 1ca7e08fb05054e6689171927daeae25bb236834 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Fri, 26 Sep 2025 06:45:57 +0000 Subject: [PATCH 0924/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index b32f1490479..314ff647062 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.9.25.1 +// @version 2025.9.26.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -22031,7 +22031,7 @@ ImgOps | https://imgops.com/#b#`; if (!imme && this.following) return; let wSize = getWindowSize(); - let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2, (this.img.naturalWidth || 500)>>1, (this.img.naturalHeight || 500)>>1), padding2 = 50, left, top;//内外侧间距 + let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2, Math.max(this.data.img && this.data.img.clientWidth, this.data.img && this.data.img.clientHeight, 100)>>2), padding2 = 50, left, top;//内外侧间距 imgWindow.style.position = "fixed"; let scrolled = {x: 0, y: 0}; From 98e9e98aec23832e3735119dab33f24b8740fb24 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 27 Sep 2025 09:24:34 +0900 Subject: [PATCH 0925/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index b2144a1a6c9..2807b7e71f9 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.26.1 +// @version 2025.9.27.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -22031,7 +22031,7 @@ ImgOps | https://imgops.com/#b#`; if (!imme && this.following) return; let wSize = getWindowSize(); - let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2, Math.max(this.data.img && this.data.img.clientWidth, this.data.img && this.data.img.clientHeight, 100)>>2), padding2 = 50, left, top;//内外侧间距 + let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2, Math.max(this.data.img && this.data.img.clientWidth, this.data.img && this.data.img.clientHeight, 50)>>1), padding2 = 50, left, top;//内外侧间距 imgWindow.style.position = "fixed"; let scrolled = {x: 0, y: 0}; @@ -25584,6 +25584,7 @@ ImgOps | https://imgops.com/#b#`; let checkEle = target; while(checkEle && !(checkEle.textContent && checkEle.textContent.trim()) && checkEle.children.length === 1) { checkEle = checkEle.children[0]; + if (target.clientWidth && target.clientWidth > checkEle.clientWidth * 1.2) break; if (checkEle.nodeName === "IMG") { target = checkEle; found = true; @@ -26229,6 +26230,7 @@ ImgOps | https://imgops.com/#b#`; if (e.relatedTarget == ImgWindowC.overlayer) return; if(uniqueImgWin && !uniqueImgWin.removed){ if(checkPreview(e)){ + if (!uniqueImgWin.data.img) return uniqueImgWin && uniqueImgWin.remove(); let showArea=uniqueImgWin.data.img.getBoundingClientRect(); if(e.clientX < showArea.left + 20 || e.clientX > showArea.right - 20 || From 8d46a9eb565e53652c0a62f1b966019d49985f5d Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 27 Sep 2025 00:24:45 +0000 Subject: [PATCH 0926/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 314ff647062..29cef4f8836 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.9.26.1 +// @version 2025.9.27.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -22031,7 +22031,7 @@ ImgOps | https://imgops.com/#b#`; if (!imme && this.following) return; let wSize = getWindowSize(); - let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2, Math.max(this.data.img && this.data.img.clientWidth, this.data.img && this.data.img.clientHeight, 100)>>2), padding2 = 50, left, top;//内外侧间距 + let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2, Math.max(this.data.img && this.data.img.clientWidth, this.data.img && this.data.img.clientHeight, 50)>>1), padding2 = 50, left, top;//内外侧间距 imgWindow.style.position = "fixed"; let scrolled = {x: 0, y: 0}; @@ -25584,6 +25584,7 @@ ImgOps | https://imgops.com/#b#`; let checkEle = target; while(checkEle && !(checkEle.textContent && checkEle.textContent.trim()) && checkEle.children.length === 1) { checkEle = checkEle.children[0]; + if (target.clientWidth && target.clientWidth > checkEle.clientWidth * 1.2) break; if (checkEle.nodeName === "IMG") { target = checkEle; found = true; @@ -26229,6 +26230,7 @@ ImgOps | https://imgops.com/#b#`; if (e.relatedTarget == ImgWindowC.overlayer) return; if(uniqueImgWin && !uniqueImgWin.removed){ if(checkPreview(e)){ + if (!uniqueImgWin.data.img) return uniqueImgWin && uniqueImgWin.remove(); let showArea=uniqueImgWin.data.img.getBoundingClientRect(); if(e.clientX < showArea.left + 20 || e.clientX > showArea.right - 20 || From 604b7b76b954c63d7c24dceeba0276e4590a90d4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 27 Sep 2025 10:01:46 +0900 Subject: [PATCH 0927/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 2807b7e71f9..7d55dbb9832 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -27303,6 +27303,7 @@ ImgOps | https://imgops.com/#b#`; } function openPrefs() { + if (window.top != window.self) return; let fieldsSearchData = GM_config.fields["gallery.searchData"]; if (fieldsSearchData && fieldsSearchData.value) { fieldsSearchData.value = fieldsSearchData.value.replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/&/g, "&").replace(/>/g, ">").replace(/ Date: Sat, 27 Sep 2025 01:01:58 +0000 Subject: [PATCH 0928/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 29cef4f8836..fddce2949fe 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -27303,6 +27303,7 @@ ImgOps | https://imgops.com/#b#`; } function openPrefs() { + if (window.top != window.self) return; let fieldsSearchData = GM_config.fields["gallery.searchData"]; if (fieldsSearchData && fieldsSearchData.value) { fieldsSearchData.value = fieldsSearchData.value.replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/&/g, "&").replace(/>/g, ">").replace(/ Date: Sat, 27 Sep 2025 21:01:43 +0900 Subject: [PATCH 0929/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 7d55dbb9832..e806eaf5b7b 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -22031,7 +22031,9 @@ ImgOps | https://imgops.com/#b#`; if (!imme && this.following) return; let wSize = getWindowSize(); - let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2, Math.max(this.data.img && this.data.img.clientWidth, this.data.img && this.data.img.clientHeight, 50)>>1), padding2 = 50, left, top;//内外侧间距 + let paddingW = Math.min(250, wSize.w>>2, Math.max(this.data.img && this.data.img.clientWidth, 50)>>1); + let paddingH = Math.min(250, wSize.h>>2, Math.max(this.data.img && this.data.img.clientHeight, 50)>>1); + let padding2 = 50, left, top;//内外侧间距 imgWindow.style.position = "fixed"; let scrolled = {x: 0, y: 0}; @@ -22041,18 +22043,18 @@ ImgOps | https://imgops.com/#b#`; //宽条,上下半屏 if (posY > wSize.h / 2) { //上 - top = posY - imgWindow.offsetHeight - padding1 + scrolled.y; + top = posY - imgWindow.offsetHeight - paddingH + scrolled.y; if (top < padding2>>1) top = padding2>>1; } else { //下 - top = posY + padding1 + scrolled.y; + top = posY + paddingH + scrolled.y; if (top > wSize.h - imgWindow.offsetHeight - 1) top = wSize.h - imgWindow.offsetHeight - 1; } left = (wSize.w - imgWindow.offsetWidth) / 2; - let maxLeft = posX + padding1; + let maxLeft = posX + paddingW; if (left > maxLeft) left = maxLeft; else { - let minLeft = posX - imgWindow.offsetWidth - padding1; + let minLeft = posX - imgWindow.offsetWidth - paddingW; if (left < minLeft) left = minLeft; } left = left + scrolled.x; @@ -22060,18 +22062,18 @@ ImgOps | https://imgops.com/#b#`; //窄条,左右半屏 if (posX > wSize.w / 2) { //左 - left = posX - imgWindow.offsetWidth - padding1 + scrolled.x; + left = posX - imgWindow.offsetWidth - paddingW + scrolled.x; if (left < 1) left = 1; } else { //右 - left = posX + padding1 + scrolled.x; + left = posX + paddingW + scrolled.x; if (left > wSize.w - imgWindow.offsetWidth - 1) left = wSize.w - imgWindow.offsetWidth - 1; } top = (wSize.h - imgWindow.offsetHeight) / 2; - let maxTop = posY + padding1; + let maxTop = posY + paddingH; if (top > maxTop) top = maxTop; else { - let minTop = posY - imgWindow.offsetHeight - padding1; + let minTop = posY - imgWindow.offsetHeight - paddingH; if (top < minTop) top = minTop; } top = top + scrolled.y; From 0f0ca61da0b98f04070f04a8103a83a87927460e Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 27 Sep 2025 12:25:15 +0000 Subject: [PATCH 0930/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index fddce2949fe..c31d2231f6e 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -22031,7 +22031,9 @@ ImgOps | https://imgops.com/#b#`; if (!imme && this.following) return; let wSize = getWindowSize(); - let padding1 = Math.min(250, wSize.h>>2, wSize.w>>2, Math.max(this.data.img && this.data.img.clientWidth, this.data.img && this.data.img.clientHeight, 50)>>1), padding2 = 50, left, top;//内外侧间距 + let paddingW = Math.min(250, wSize.w>>2, Math.max(this.data.img && this.data.img.clientWidth, 50)>>1); + let paddingH = Math.min(250, wSize.h>>2, Math.max(this.data.img && this.data.img.clientHeight, 50)>>1); + let padding2 = 50, left, top;//内外侧间距 imgWindow.style.position = "fixed"; let scrolled = {x: 0, y: 0}; @@ -22041,18 +22043,18 @@ ImgOps | https://imgops.com/#b#`; //宽条,上下半屏 if (posY > wSize.h / 2) { //上 - top = posY - imgWindow.offsetHeight - padding1 + scrolled.y; + top = posY - imgWindow.offsetHeight - paddingH + scrolled.y; if (top < padding2>>1) top = padding2>>1; } else { //下 - top = posY + padding1 + scrolled.y; + top = posY + paddingH + scrolled.y; if (top > wSize.h - imgWindow.offsetHeight - 1) top = wSize.h - imgWindow.offsetHeight - 1; } left = (wSize.w - imgWindow.offsetWidth) / 2; - let maxLeft = posX + padding1; + let maxLeft = posX + paddingW; if (left > maxLeft) left = maxLeft; else { - let minLeft = posX - imgWindow.offsetWidth - padding1; + let minLeft = posX - imgWindow.offsetWidth - paddingW; if (left < minLeft) left = minLeft; } left = left + scrolled.x; @@ -22060,18 +22062,18 @@ ImgOps | https://imgops.com/#b#`; //窄条,左右半屏 if (posX > wSize.w / 2) { //左 - left = posX - imgWindow.offsetWidth - padding1 + scrolled.x; + left = posX - imgWindow.offsetWidth - paddingW + scrolled.x; if (left < 1) left = 1; } else { //右 - left = posX + padding1 + scrolled.x; + left = posX + paddingW + scrolled.x; if (left > wSize.w - imgWindow.offsetWidth - 1) left = wSize.w - imgWindow.offsetWidth - 1; } top = (wSize.h - imgWindow.offsetHeight) / 2; - let maxTop = posY + padding1; + let maxTop = posY + paddingH; if (top > maxTop) top = maxTop; else { - let minTop = posY - imgWindow.offsetHeight - padding1; + let minTop = posY - imgWindow.offsetHeight - paddingH; if (top < minTop) top = minTop; } top = top + scrolled.y; From ebc155ffbca3dd67399947ab05bea21bee95b3f5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 28 Sep 2025 12:53:33 +0900 Subject: [PATCH 0931/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index e806eaf5b7b..2e3f1b24cb7 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.27.1 +// @version 2025.9.27.2 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -25861,11 +25861,17 @@ ImgOps | https://imgops.com/#b#`; } } - var checkFloatBarTimer, initMouse = false; + var checkFloatBarTimer, initMouse = false, lastEvent; function globalMouseoverHandler(e) { if (galleryMode) return;//库模式全屏中...... if (e.target == ImgWindowC.overlayer) return; let canPreview = checkPreview(e); + if (e.type == "keydown") { + if (!lastEvent) return; + e = lastEvent; + } else { + lastEvent = e; + } if (e.type == "mousemove") { if (!initMouse) { initMouse = true; @@ -26140,6 +26146,7 @@ ImgOps | https://imgops.com/#b#`; return false; } + let keypressing = false; function keydown(event) { //if (ImgWindowC.showing) return; @@ -26149,6 +26156,10 @@ ImgOps | https://imgops.com/#b#`; } var key = event.key; if(checkGlobalKeydown(event)){ + if (!keypressing) { + globalMouseoverHandler(event); + keypressing = true; + } if(prefs.floatBar.keys.enable && key==prefs.floatBar.keys.gallery){ openGallery(); event.stopPropagation(); @@ -26165,7 +26176,9 @@ ImgOps | https://imgops.com/#b#`; } if (event) { - if (event.ctrlKey || event.metaKey) return false; + if (event.ctrlKey || event.metaKey) { + return false; + } if (window.getSelection().toString()) return false; } if (floatBar && isKeyDownEffectiveTarget(event.target)) { @@ -26180,6 +26193,7 @@ ImgOps | https://imgops.com/#b#`; } function keyup(event) { + keypressing = false; let isFuncKey = !event.isTrusted || event.key == 'Alt' || event.key == 'Control' || event.key == 'Meta'; if(isFuncKey && (prefs.floatBar.globalkeys.type == "hold" || !checkPreview(event)) && (uniqueImgWin && !uniqueImgWin.removed)){ clearTimeout(checkFloatBarTimer); From b577523d8e4f5c1b9db137f360719e95a220b61f Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 28 Sep 2025 03:53:54 +0000 Subject: [PATCH 0932/1065] chore(Picviewer CE+): Auto-generate dist.user.js with timestamp --- Picviewer CE+/dist.user.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index c31d2231f6e..1a58b0f785d 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.9.27.1 +// @version 2025.9.27.2 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -25861,11 +25861,17 @@ ImgOps | https://imgops.com/#b#`; } } - var checkFloatBarTimer, initMouse = false; + var checkFloatBarTimer, initMouse = false, lastEvent; function globalMouseoverHandler(e) { if (galleryMode) return;//库模式全屏中...... if (e.target == ImgWindowC.overlayer) return; let canPreview = checkPreview(e); + if (e.type == "keydown") { + if (!lastEvent) return; + e = lastEvent; + } else { + lastEvent = e; + } if (e.type == "mousemove") { if (!initMouse) { initMouse = true; @@ -26140,6 +26146,7 @@ ImgOps | https://imgops.com/#b#`; return false; } + let keypressing = false; function keydown(event) { //if (ImgWindowC.showing) return; @@ -26149,6 +26156,10 @@ ImgOps | https://imgops.com/#b#`; } var key = event.key; if(checkGlobalKeydown(event)){ + if (!keypressing) { + globalMouseoverHandler(event); + keypressing = true; + } if(prefs.floatBar.keys.enable && key==prefs.floatBar.keys.gallery){ openGallery(); event.stopPropagation(); @@ -26165,7 +26176,9 @@ ImgOps | https://imgops.com/#b#`; } if (event) { - if (event.ctrlKey || event.metaKey) return false; + if (event.ctrlKey || event.metaKey) { + return false; + } if (window.getSelection().toString()) return false; } if (floatBar && isKeyDownEffectiveTarget(event.target)) { @@ -26180,6 +26193,7 @@ ImgOps | https://imgops.com/#b#`; } function keyup(event) { + keypressing = false; let isFuncKey = !event.isTrusted || event.key == 'Alt' || event.key == 'Control' || event.key == 'Meta'; if(isFuncKey && (prefs.floatBar.globalkeys.type == "hold" || !checkPreview(event)) && (uniqueImgWin && !uniqueImgWin.removed)){ clearTimeout(checkFloatBarTimer); From e11141b969e2253941ff7dad007ce34ee87ce862 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 29 Sep 2025 11:43:34 +0900 Subject: [PATCH 0933/1065] Update build-dist.yml --- .github/workflows/build-dist.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml index 4ad8cabf542..ef4f9880fb6 100644 --- a/.github/workflows/build-dist.yml +++ b/.github/workflows/build-dist.yml @@ -29,5 +29,5 @@ jobs: 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 with timestamp" + git commit -m "chore(Picviewer CE+): Auto-generate dist.user.js" git push https://${{ secrets.ACTION_SECRET }}@github.com/${{ github.repository }} From 2904f7df6b3c248e19dbecb6ed0517410a9ff520 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 30 Sep 2025 16:39:52 +0900 Subject: [PATCH 0934/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 2b03ef4a593..cde5111054d 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -6823,11 +6823,15 @@ }); self.preloadImageHandler(); } + self.fetchFailed = 0; } catch(e) { debug(e); return; } + }).catch(error => { + self.fetchFailed = (self.fetchFailed || 0) + 1; + if (self.fetchFailed > 1) self.curSiteRule.preload = 0; }); } @@ -7286,7 +7290,7 @@ } if (loadingDiv.previousElementSibling) { let preStyle = _unsafeWindow.getComputedStyle(loadingDiv.previousElementSibling); - loadingDiv.style.order = preStyle.order; + if (preStyle.order && preStyle.order !== '0') loadingDiv.style.order = preStyle.order; } } //this.setPageTop(lastScrollTop); From 245a405972b6151a62a37cf7ee6c0f2e981e9ac6 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 30 Sep 2025 18:56:56 +0900 Subject: [PATCH 0935/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index fa5d76083e6..34f9148c807 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -2031,5 +2031,11 @@ var siteInfo = [ url: "/^https://(www\\.)?img(?:inn|sed)\\.com/p/[\\w-]/", query: '.swiper-slide,.downloads a' } + }, + { + name: "zlib", + src: /^https:\/\/[^\/]+\.cdn\-zlib\./i, + r: /covers\d+/i, + s: 'covers4096' } ]; From 456bb139b9896691bb4dea53a5e5cf2974340b42 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 30 Sep 2025 19:01:15 +0900 Subject: [PATCH 0936/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 180 +++++++++++----------------- 1 file changed, 69 insertions(+), 111 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 2e3f1b24cb7..890624b1b63 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.27.2 +// @version 2025.9.30.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1666736/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1669339/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js // @match *://*/* // @exclude http://www.toodledo.com/tasks/* @@ -12675,7 +12675,7 @@ ImgOps | https://imgops.com/#b#`; } ]; - const imageReg = /^\s*(https?|ftp):\/\/.*?\/[^\.]*\.(avi|avif|avifs|bmp|gif|gifv|ico|jfif|jpe|jpeg|jpg|jif|jfi|a?png|svgz?|webp|xbm|dib|divx|3gpp|m3u|m4v|mkv|mp4|mpe?g|ogv|webm|flv|flac|m4a|m4b|mpa|mp3|aac|cda|oga|ogg|opus|wma|wav)(&|\?|#|\/?$|\s)/i; + const imageReg = /^\s*(https?|ftp):\/\/.*?\/[^\.::]*\.(avi|avif|avifs|bmp|gif|gifv|ico|jfif|jpe|jpeg|jpg|jif|jfi|a?png|svgz?|webp|xbm|dib|divx|3gpp|m3u|m4v|mkv|mp4|mpe?g|ogv|webm|flv|flac|m4a|m4b|mpa|mp3|aac|cda|oga|ogg|opus|wma|wav)(&|\?|#|\/?$|\s)/i; const ruleImportHost = ["greasyfork.org", "github.com", "reddit.com"]; const ruleImportUrlReg = /greasyfork\.org\/.*scripts\/24204(\-[^\/]*)?(\/discussions|\/?$|\/feedback)|github\.com\/hoothin\/UserScripts\/(tree\/master\/Picviewer%20CE%2B|issues|discussions)|\.reddit\.com\/r\/PicviewerCE/i; @@ -13451,6 +13451,7 @@ ImgOps | https://imgops.com/#b#`; + var errorList = {}, errorBlobList = {}; var imgReady=function(img,opts){ if(/NodeList|HTMLCollection/.test(Object.prototype.toString.call(img)) || Array.isArray(img)){ @@ -13596,6 +13597,42 @@ ImgOps | https://imgops.com/#b#`; function errorHandler(e){ if(aborted)return; + + if (!errorBlobList[img.src] && !/^blob:/.test(img.src)) { + errorList[img.src]=true; + _GM_xmlhttpRequest({ + method: 'GET', + url: img.src, + responseType: 'blob', + onload: function(response) { + const blobUrl = URL.createObjectURL(response.response); + const releaseBlob = () => URL.revokeObjectURL(blobUrl); + window.addEventListener('beforeunload', releaseBlob); + + let orgSrc = img.src; + img.src = blobUrl; + setTimeout(() => { + if (aborted) return; + if (typeof img.width == 'number' && img.width && img.height) { + go('load', { + type:'load', + target: img, + }); + } else { + errorBlobList[orgSrc] = true; + go('error',e); + } + }, 0); + }, + onerror: function() { + if (aborted) return; + errorBlobList[orgSrc] = true; + go('error',e); + } + }); + return; + } + go('error',e); }; @@ -13616,6 +13653,7 @@ ImgOps | https://imgops.com/#b#`; }); },0); }else{//这不是图片.opera会识别错误. + errorList[img.src]=true; setTimeout(function(){ if(aborted)return; go('error',{ @@ -13646,6 +13684,12 @@ ImgOps | https://imgops.com/#b#`; iRInterval=setInterval(checkReady,66); }; }; + if (errorList[img.src]) { + go('error',{ + type:'error', + target:img, + }); + } return ret; }; @@ -14947,7 +14991,7 @@ ImgOps | https://imgops.com/#b#`; self.img.style.display = ""; } }); - }, + } }); } else { let target = self.img; @@ -16345,36 +16389,8 @@ ImgOps | https://imgops.com/#b#`; popupImgWin(this); }, error:function(e){ - if (/^blob:/.test(imgSrc)) { - self.showTips(""); - loadError(); - } else if (mode == "image" || mode == "") { - _GM_xmlhttpRequest({ - method: 'GET', - url: imgSrc, - responseType: 'blob', - onload: function(response) { - if (response.response && response.response.type == "text/html") { - self.showTips(""); - loadError(); - return; - } - const blobUrl = URL.createObjectURL(response.response); - self.showTips(""); - let img = document.createElement("img"); - popupImgWin(img); - const releaseBlob = () => URL.revokeObjectURL(blobUrl); - window.addEventListener('beforeunload', releaseBlob); - }, - onerror: function() { - self.showTips(""); - loadError(); - } - }); - } else { - self.showTips(""); - loadError(); - } + self.showTips(""); + loadError(); } }); } @@ -16807,42 +16823,9 @@ ImgOps | https://imgops.com/#b#`; if(e.type=='error'){ if (loadingIndicator && loadingIndicator.style) loadingIndicator.style.display=''; - if (/^blob:/.test(src)) { - self.errorSpan=ele; - if(preImgR)preImgR.abort(); - self.loadImg(img, ele,true); - } else { - _GM_xmlhttpRequest({ - method: 'GET', - url: src, - responseType: 'blob', - onload: function(response) { - if (response.response && response.response.type == "text/html") { - self.errorSpan=ele; - if(preImgR)preImgR.abort(); - self.loadImg(img, ele, true); - return; - } - const blobUrl = URL.createObjectURL(response.response); - self.slideShow.run('loadEnd'); - let img = document.createElement("img"); - img.src = blobUrl; - imgReady(blobUrl, { - ready:function(){ - self.loadImg(img, ele, false); - self.slideShow.run('loadEnd'); - } - }); - const releaseBlob = () => URL.revokeObjectURL(blobUrl); - window.addEventListener('beforeunload', releaseBlob); - }, - onerror: function() { - self.errorSpan=ele; - if(preImgR)preImgR.abort(); - self.loadImg(img, ele, true); - } - }); - } + self.errorSpan=ele; + if(preImgR)preImgR.abort(); + self.loadImg(img, ele,true); }; self.slideShow.run('loadEnd'); @@ -23553,44 +23536,16 @@ ImgOps | https://imgops.com/#b#`; var opts = { error: function(e) { - if (/^blob:/.test(imgSrc)) { - if (Array.isArray(imgSrcs)) { - var src = imgSrcs.shift(); - if (src) { - self.loadImg(src, imgSrcs, nextFun); - return; - } + if (Array.isArray(imgSrcs)) { + var src = imgSrcs.shift(); + if (src) { + self.loadImg(src, imgSrcs, nextFun); + return; } - } else if (mode == "image" || mode == "") { - _GM_xmlhttpRequest({ - method: 'GET', - url: media.src, - responseType: 'blob', - onload: function(response) { - const blobUrl = URL.createObjectURL(response.response); - self.loadImg(blobUrl, imgSrcs, nextFun); - const releaseBlob = () => URL.revokeObjectURL(blobUrl); - window.addEventListener('beforeunload', releaseBlob); - }, - onerror: function() { - if (Array.isArray(imgSrcs)) { - var src = imgSrcs.shift(); - if (src) { - self.loadImg(src, imgSrcs, nextFun); - return; - } - } else { - self.error('', this, e); - } - } - }); - return; } else { - self.error('', this, e); + if(nextFun) nextFun(); + else self.error('', this, e); } - - if(nextFun) nextFun(); - else self.error('', this, e); }, }; @@ -25278,7 +25233,7 @@ ImgOps | https://imgops.com/#b#`; }, prefs.floatBar.showDelay || 0) } - function checkFloatBar(_target, type, canPreview, clientX, clientY, altKey) { + function checkFloatBar(_target, type, canPreview, clientX, clientY, altKey, composedTarget) { let target = _target; if (!target || target.id == "pv-float-bar-container" || (target.parentNode && (target.parentNode.id == "icons" || target.parentNode.className == "search-jumper-btn")) || @@ -25335,7 +25290,7 @@ ImgOps | https://imgops.com/#b#`; let bgReg = /.*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; let bgRegLong = /^\s*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; let result, targetBg, hasBg = node => { - if(node.nodeName.toUpperCase() == "HTML" || node.nodeName == "#document"){ + if(node.nodeName.toUpperCase() == "HTML" || node.nodeName == "#document" || node.nodeType != 1){ return false; } if (node.clientWidth <= prefs.floatBar.minSizeLimit.w || node.clientHeight <= prefs.floatBar.minSizeLimit.h) { @@ -25503,17 +25458,18 @@ ImgOps | https://imgops.com/#b#`; return; } + if (composedTarget) target = composedTarget; let found = false; if (target.nodeName.toUpperCase() == "AREA") target = target.parentNode; var broEle, broImg; - if (target.nodeName.toUpperCase() != 'A' && target.parentNode && target.parentNode.style && !/flex|grid|table/.test(getComputedStyle(target.parentNode).display)) { + if (target.parentNode && target.parentNode.style && !/flex|grid|table/.test(getComputedStyle(target.parentNode).display)) { broEle = target.previousElementSibling; while (broEle) { if (broEle.offsetWidth && broEle.offsetWidth > target.offsetWidth>>1) { if (broEle.nodeName == "IMG") broImg = broEle; else if (broEle.nodeName == "PICTURE") broImg = broEle.querySelector("img"); } - if (getComputedStyle(broEle).position !== "absolute") break; + if (broEle.offsetWidth && broEle.offsetHeight && getComputedStyle(broEle).position !== "absolute") break; broEle = broEle.previousElementSibling; } if (broEle == target) broEle = null; @@ -25861,7 +25817,7 @@ ImgOps | https://imgops.com/#b#`; } } - var checkFloatBarTimer, initMouse = false, lastEvent; + var checkFloatBarTimer, initMouse = false, lastEvent, composedTarget; function globalMouseoverHandler(e) { if (galleryMode) return;//库模式全屏中...... if (e.target == ImgWindowC.overlayer) return; @@ -25871,6 +25827,8 @@ ImgOps | https://imgops.com/#b#`; e = lastEvent; } else { lastEvent = e; + let path = e && e.composedPath && e.composedPath(); + composedTarget = path && path[0]; } if (e.type == "mousemove") { if (!initMouse) { @@ -25900,7 +25858,7 @@ ImgOps | https://imgops.com/#b#`; checkFloatBarTimer = setTimeout(function() { if (!e || !e.target || !e.target.parentNode) return; if (gallery && gallery.shown) return; - checkFloatBar(e.target, e.type, canPreview, e.clientX, e.clientY, e.altKey); + checkFloatBar(e.target, e.type, canPreview, e.clientX, e.clientY, e.altKey, composedTarget); }, 50); } From c84e38f7034fc20862fd7e35940c181d72c7250c Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 30 Sep 2025 10:01:26 +0000 Subject: [PATCH 0937/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 180 ++++++++++++++----------------------- 1 file changed, 69 insertions(+), 111 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 1a58b0f785d..a4262be7589 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.9.27.2 +// @version 2025.9.30.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=23710 -// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1666736 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1669339 // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1653424 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* @@ -12675,7 +12675,7 @@ ImgOps | https://imgops.com/#b#`; } ]; - const imageReg = /^\s*(https?|ftp):\/\/.*?\/[^\.]*\.(avi|avif|avifs|bmp|gif|gifv|ico|jfif|jpe|jpeg|jpg|jif|jfi|a?png|svgz?|webp|xbm|dib|divx|3gpp|m3u|m4v|mkv|mp4|mpe?g|ogv|webm|flv|flac|m4a|m4b|mpa|mp3|aac|cda|oga|ogg|opus|wma|wav)(&|\?|#|\/?$|\s)/i; + const imageReg = /^\s*(https?|ftp):\/\/.*?\/[^\.::]*\.(avi|avif|avifs|bmp|gif|gifv|ico|jfif|jpe|jpeg|jpg|jif|jfi|a?png|svgz?|webp|xbm|dib|divx|3gpp|m3u|m4v|mkv|mp4|mpe?g|ogv|webm|flv|flac|m4a|m4b|mpa|mp3|aac|cda|oga|ogg|opus|wma|wav)(&|\?|#|\/?$|\s)/i; const ruleImportHost = ["greasyfork.org", "github.com", "reddit.com"]; const ruleImportUrlReg = /greasyfork\.org\/.*scripts\/24204(\-[^\/]*)?(\/discussions|\/?$|\/feedback)|github\.com\/hoothin\/UserScripts\/(tree\/master\/Picviewer%20CE%2B|issues|discussions)|\.reddit\.com\/r\/PicviewerCE/i; @@ -13451,6 +13451,7 @@ ImgOps | https://imgops.com/#b#`; + var errorList = {}, errorBlobList = {}; var imgReady=function(img,opts){ if(/NodeList|HTMLCollection/.test(Object.prototype.toString.call(img)) || Array.isArray(img)){ @@ -13596,6 +13597,42 @@ ImgOps | https://imgops.com/#b#`; function errorHandler(e){ if(aborted)return; + + if (!errorBlobList[img.src] && !/^blob:/.test(img.src)) { + errorList[img.src]=true; + _GM_xmlhttpRequest({ + method: 'GET', + url: img.src, + responseType: 'blob', + onload: function(response) { + const blobUrl = URL.createObjectURL(response.response); + const releaseBlob = () => URL.revokeObjectURL(blobUrl); + window.addEventListener('beforeunload', releaseBlob); + + let orgSrc = img.src; + img.src = blobUrl; + setTimeout(() => { + if (aborted) return; + if (typeof img.width == 'number' && img.width && img.height) { + go('load', { + type:'load', + target: img, + }); + } else { + errorBlobList[orgSrc] = true; + go('error',e); + } + }, 0); + }, + onerror: function() { + if (aborted) return; + errorBlobList[orgSrc] = true; + go('error',e); + } + }); + return; + } + go('error',e); }; @@ -13616,6 +13653,7 @@ ImgOps | https://imgops.com/#b#`; }); },0); }else{//这不是图片.opera会识别错误. + errorList[img.src]=true; setTimeout(function(){ if(aborted)return; go('error',{ @@ -13646,6 +13684,12 @@ ImgOps | https://imgops.com/#b#`; iRInterval=setInterval(checkReady,66); }; }; + if (errorList[img.src]) { + go('error',{ + type:'error', + target:img, + }); + } return ret; }; @@ -14947,7 +14991,7 @@ ImgOps | https://imgops.com/#b#`; self.img.style.display = ""; } }); - }, + } }); } else { let target = self.img; @@ -16345,36 +16389,8 @@ ImgOps | https://imgops.com/#b#`; popupImgWin(this); }, error:function(e){ - if (/^blob:/.test(imgSrc)) { - self.showTips(""); - loadError(); - } else if (mode == "image" || mode == "") { - _GM_xmlhttpRequest({ - method: 'GET', - url: imgSrc, - responseType: 'blob', - onload: function(response) { - if (response.response && response.response.type == "text/html") { - self.showTips(""); - loadError(); - return; - } - const blobUrl = URL.createObjectURL(response.response); - self.showTips(""); - let img = document.createElement("img"); - popupImgWin(img); - const releaseBlob = () => URL.revokeObjectURL(blobUrl); - window.addEventListener('beforeunload', releaseBlob); - }, - onerror: function() { - self.showTips(""); - loadError(); - } - }); - } else { - self.showTips(""); - loadError(); - } + self.showTips(""); + loadError(); } }); } @@ -16807,42 +16823,9 @@ ImgOps | https://imgops.com/#b#`; if(e.type=='error'){ if (loadingIndicator && loadingIndicator.style) loadingIndicator.style.display=''; - if (/^blob:/.test(src)) { - self.errorSpan=ele; - if(preImgR)preImgR.abort(); - self.loadImg(img, ele,true); - } else { - _GM_xmlhttpRequest({ - method: 'GET', - url: src, - responseType: 'blob', - onload: function(response) { - if (response.response && response.response.type == "text/html") { - self.errorSpan=ele; - if(preImgR)preImgR.abort(); - self.loadImg(img, ele, true); - return; - } - const blobUrl = URL.createObjectURL(response.response); - self.slideShow.run('loadEnd'); - let img = document.createElement("img"); - img.src = blobUrl; - imgReady(blobUrl, { - ready:function(){ - self.loadImg(img, ele, false); - self.slideShow.run('loadEnd'); - } - }); - const releaseBlob = () => URL.revokeObjectURL(blobUrl); - window.addEventListener('beforeunload', releaseBlob); - }, - onerror: function() { - self.errorSpan=ele; - if(preImgR)preImgR.abort(); - self.loadImg(img, ele, true); - } - }); - } + self.errorSpan=ele; + if(preImgR)preImgR.abort(); + self.loadImg(img, ele,true); }; self.slideShow.run('loadEnd'); @@ -23553,44 +23536,16 @@ ImgOps | https://imgops.com/#b#`; var opts = { error: function(e) { - if (/^blob:/.test(imgSrc)) { - if (Array.isArray(imgSrcs)) { - var src = imgSrcs.shift(); - if (src) { - self.loadImg(src, imgSrcs, nextFun); - return; - } + if (Array.isArray(imgSrcs)) { + var src = imgSrcs.shift(); + if (src) { + self.loadImg(src, imgSrcs, nextFun); + return; } - } else if (mode == "image" || mode == "") { - _GM_xmlhttpRequest({ - method: 'GET', - url: media.src, - responseType: 'blob', - onload: function(response) { - const blobUrl = URL.createObjectURL(response.response); - self.loadImg(blobUrl, imgSrcs, nextFun); - const releaseBlob = () => URL.revokeObjectURL(blobUrl); - window.addEventListener('beforeunload', releaseBlob); - }, - onerror: function() { - if (Array.isArray(imgSrcs)) { - var src = imgSrcs.shift(); - if (src) { - self.loadImg(src, imgSrcs, nextFun); - return; - } - } else { - self.error('', this, e); - } - } - }); - return; } else { - self.error('', this, e); + if(nextFun) nextFun(); + else self.error('', this, e); } - - if(nextFun) nextFun(); - else self.error('', this, e); }, }; @@ -25278,7 +25233,7 @@ ImgOps | https://imgops.com/#b#`; }, prefs.floatBar.showDelay || 0) } - function checkFloatBar(_target, type, canPreview, clientX, clientY, altKey) { + function checkFloatBar(_target, type, canPreview, clientX, clientY, altKey, composedTarget) { let target = _target; if (!target || target.id == "pv-float-bar-container" || (target.parentNode && (target.parentNode.id == "icons" || target.parentNode.className == "search-jumper-btn")) || @@ -25335,7 +25290,7 @@ ImgOps | https://imgops.com/#b#`; let bgReg = /.*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; let bgRegLong = /^\s*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; let result, targetBg, hasBg = node => { - if(node.nodeName.toUpperCase() == "HTML" || node.nodeName == "#document"){ + if(node.nodeName.toUpperCase() == "HTML" || node.nodeName == "#document" || node.nodeType != 1){ return false; } if (node.clientWidth <= prefs.floatBar.minSizeLimit.w || node.clientHeight <= prefs.floatBar.minSizeLimit.h) { @@ -25503,17 +25458,18 @@ ImgOps | https://imgops.com/#b#`; return; } + if (composedTarget) target = composedTarget; let found = false; if (target.nodeName.toUpperCase() == "AREA") target = target.parentNode; var broEle, broImg; - if (target.nodeName.toUpperCase() != 'A' && target.parentNode && target.parentNode.style && !/flex|grid|table/.test(getComputedStyle(target.parentNode).display)) { + if (target.parentNode && target.parentNode.style && !/flex|grid|table/.test(getComputedStyle(target.parentNode).display)) { broEle = target.previousElementSibling; while (broEle) { if (broEle.offsetWidth && broEle.offsetWidth > target.offsetWidth>>1) { if (broEle.nodeName == "IMG") broImg = broEle; else if (broEle.nodeName == "PICTURE") broImg = broEle.querySelector("img"); } - if (getComputedStyle(broEle).position !== "absolute") break; + if (broEle.offsetWidth && broEle.offsetHeight && getComputedStyle(broEle).position !== "absolute") break; broEle = broEle.previousElementSibling; } if (broEle == target) broEle = null; @@ -25861,7 +25817,7 @@ ImgOps | https://imgops.com/#b#`; } } - var checkFloatBarTimer, initMouse = false, lastEvent; + var checkFloatBarTimer, initMouse = false, lastEvent, composedTarget; function globalMouseoverHandler(e) { if (galleryMode) return;//库模式全屏中...... if (e.target == ImgWindowC.overlayer) return; @@ -25871,6 +25827,8 @@ ImgOps | https://imgops.com/#b#`; e = lastEvent; } else { lastEvent = e; + let path = e && e.composedPath && e.composedPath(); + composedTarget = path && path[0]; } if (e.type == "mousemove") { if (!initMouse) { @@ -25900,7 +25858,7 @@ ImgOps | https://imgops.com/#b#`; checkFloatBarTimer = setTimeout(function() { if (!e || !e.target || !e.target.parentNode) return; if (gallery && gallery.shown) return; - checkFloatBar(e.target, e.type, canPreview, e.clientX, e.clientY, e.altKey); + checkFloatBar(e.target, e.type, canPreview, e.clientX, e.clientY, e.altKey, composedTarget); }, 50); } From e383523626d9c3c161b27504bb82aca0adbd2916 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 30 Sep 2025 19:06:30 +0900 Subject: [PATCH 0938/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 890624b1b63..24f25ceb7e3 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -25822,14 +25822,6 @@ ImgOps | https://imgops.com/#b#`; if (galleryMode) return;//库模式全屏中...... if (e.target == ImgWindowC.overlayer) return; let canPreview = checkPreview(e); - if (e.type == "keydown") { - if (!lastEvent) return; - e = lastEvent; - } else { - lastEvent = e; - let path = e && e.composedPath && e.composedPath(); - composedTarget = path && path[0]; - } if (e.type == "mousemove") { if (!initMouse) { initMouse = true; @@ -25854,6 +25846,14 @@ ImgOps | https://imgops.com/#b#`; } } if (!initMouse) return; + if (e.type == "keydown") { + if (!lastEvent) return; + e = lastEvent; + } else { + lastEvent = e; + let path = e && e.composedPath && e.composedPath(); + composedTarget = path && path[0]; + } clearTimeout(checkFloatBarTimer); checkFloatBarTimer = setTimeout(function() { if (!e || !e.target || !e.target.parentNode) return; From f897d2afa68b53b77e73429cdccaa5c4b15c21f1 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 30 Sep 2025 10:08:09 +0000 Subject: [PATCH 0939/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index a4262be7589..2a544b5075e 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -25822,14 +25822,6 @@ ImgOps | https://imgops.com/#b#`; if (galleryMode) return;//库模式全屏中...... if (e.target == ImgWindowC.overlayer) return; let canPreview = checkPreview(e); - if (e.type == "keydown") { - if (!lastEvent) return; - e = lastEvent; - } else { - lastEvent = e; - let path = e && e.composedPath && e.composedPath(); - composedTarget = path && path[0]; - } if (e.type == "mousemove") { if (!initMouse) { initMouse = true; @@ -25854,6 +25846,14 @@ ImgOps | https://imgops.com/#b#`; } } if (!initMouse) return; + if (e.type == "keydown") { + if (!lastEvent) return; + e = lastEvent; + } else { + lastEvent = e; + let path = e && e.composedPath && e.composedPath(); + composedTarget = path && path[0]; + } clearTimeout(checkFloatBarTimer); checkFloatBarTimer = setTimeout(function() { if (!e || !e.target || !e.target.parentNode) return; From e25b2aff7d9a5c1e7b0d0966134e41f9ad7ab166 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 2 Oct 2025 20:19:35 +0900 Subject: [PATCH 0940/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 24f25ceb7e3..afbc0130109 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -25290,7 +25290,7 @@ ImgOps | https://imgops.com/#b#`; let bgReg = /.*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; let bgRegLong = /^\s*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; let result, targetBg, hasBg = node => { - if(node.nodeName.toUpperCase() == "HTML" || node.nodeName == "#document" || node.nodeType != 1){ + if(/^(html|body|#document)$/i.test(node.nodeName) || node.nodeType != 1){ return false; } if (node.clientWidth <= prefs.floatBar.minSizeLimit.w || node.clientHeight <= prefs.floatBar.minSizeLimit.h) { From 9758a22b7ea072d4ede79f6f5a58da7b0f142380 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 2 Oct 2025 11:19:48 +0000 Subject: [PATCH 0941/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 2a544b5075e..7117fbffb8a 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -25290,7 +25290,7 @@ ImgOps | https://imgops.com/#b#`; let bgReg = /.*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; let bgRegLong = /^\s*url\(\s*["']?([^ad\s'"#].+?)["']?\s*\)([^'"]|$)/i; let result, targetBg, hasBg = node => { - if(node.nodeName.toUpperCase() == "HTML" || node.nodeName == "#document" || node.nodeType != 1){ + if(/^(html|body|#document)$/i.test(node.nodeName) || node.nodeType != 1){ return false; } if (node.clientWidth <= prefs.floatBar.minSizeLimit.w || node.clientHeight <= prefs.floatBar.minSizeLimit.h) { From 33311300077ee7a938906ab2c8d935e8a53fd38c Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 5 Oct 2025 18:52:29 +0900 Subject: [PATCH 0942/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index afbc0130109..d1d432dea14 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.9.30.1 +// @version 2025.10.5.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -24038,10 +24038,20 @@ ImgOps | https://imgops.com/#b#`; if (bodyStyle.position === "static") { offsetParent = document.documentElement; + bodyPosi = body.getBoundingClientRect(); + let docPosy = offsetParent.getBoundingClientRect(); + if (bodyPosi.top == docPosy.top && bodyPosi.left == docPosy.left && bodyPosi.bottom == docPosy.bottom && bodyPosi.right == docPosy.right) { + bodyPosi = { + top: -offsetParent.scrollTop, + left: -offsetParent.scrollLeft, + bottom: offsetParent.scrollHeight - offsetParent.scrollTop, + right: offsetParent.scrollWidth - offsetParent.scrollLeft + }; + } } else { offsetParent = body; + bodyPosi = offsetParent.getBoundingClientRect(); } - bodyPosi = offsetParent.getBoundingClientRect(); var scrolled=getScrolled(offsetParent); @@ -24145,6 +24155,7 @@ ImgOps | https://imgops.com/#b#`; window.addEventListener('scroll',this._scrollHandler,true); }, hide:function(){ + lastEvent = null; clearTimeout(this.showTimer); this.floatBar.style.opacity=0.01; this.shown=false; @@ -26204,7 +26215,7 @@ ImgOps | https://imgops.com/#b#`; if (e.relatedTarget == ImgWindowC.overlayer) return; if(uniqueImgWin && !uniqueImgWin.removed){ if(checkPreview(e)){ - if (!uniqueImgWin.data.img) return uniqueImgWin && uniqueImgWin.remove(); + if (!uniqueImgWin.data.img || !uniqueImgWin.data.img.parentNode) return uniqueImgWin && uniqueImgWin.remove(); let showArea=uniqueImgWin.data.img.getBoundingClientRect(); if(e.clientX < showArea.left + 20 || e.clientX > showArea.right - 20 || From d506c2a3771b68e806ba2b35a527f3f386725aa1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 5 Oct 2025 19:29:05 +0900 Subject: [PATCH 0943/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index cde5111054d..55d0456001a 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -5798,9 +5798,9 @@ if (e.style.display === "none" || e.getAttribute("aria-disabled") === "true") { return false; } - if (/\bbanner|slick|slide|carousel|gallery/i.test(e.id)) return false; + if (/\bbanner|slick|slide|carousel/i.test(e.id)) return false; if (e.className) { - if (!/page/i.test(e.className) && /\bbanner|slick|slide|carousel|gallery|disabled\s*$/i.test(e.className)) { + if (!/page/i.test(e.className) && /\bbanner|slick|slide|carousel|disabled\s*$/i.test(e.className)) { return false; } else if (e.classList) { if (e.classList.contains('disabled') || e.classList.contains('active')) { @@ -5809,7 +5809,7 @@ } } let ariaLabel = e.getAttribute("aria-label"); - if (ariaLabel && /\bbanner|slick|slide|carousel|gallery/i.test(ariaLabel)) return false; + if (ariaLabel && /\bbanner|slick|slide|carousel/i.test(ariaLabel)) return false; return true; }; if (!ele) return false; @@ -5919,7 +5919,8 @@ ".btn_next:not([disabled])", ".btn-next:not([disabled])", '//button[contains(@class, "Page")][text()="Next"]', - '//button[contains(@class, "page")][text()="next"]' + '//button[contains(@class, "page")][text()="next"]', + '//form/button[@type="submit"][text()="Next"]' ]; let next = await this.querySelectorList(body, selectorList, doc.defaultView); if (!next) { From 8216506dceff5242b871819e37f791df4fc5f35c Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 5 Oct 2025 10:29:28 +0000 Subject: [PATCH 0944/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 7117fbffb8a..f55c6b1d18f 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.9.30.1 +// @version 2025.10.5.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -24038,10 +24038,20 @@ ImgOps | https://imgops.com/#b#`; if (bodyStyle.position === "static") { offsetParent = document.documentElement; + bodyPosi = body.getBoundingClientRect(); + let docPosy = offsetParent.getBoundingClientRect(); + if (bodyPosi.top == docPosy.top && bodyPosi.left == docPosy.left && bodyPosi.bottom == docPosy.bottom && bodyPosi.right == docPosy.right) { + bodyPosi = { + top: -offsetParent.scrollTop, + left: -offsetParent.scrollLeft, + bottom: offsetParent.scrollHeight - offsetParent.scrollTop, + right: offsetParent.scrollWidth - offsetParent.scrollLeft + }; + } } else { offsetParent = body; + bodyPosi = offsetParent.getBoundingClientRect(); } - bodyPosi = offsetParent.getBoundingClientRect(); var scrolled=getScrolled(offsetParent); @@ -24145,6 +24155,7 @@ ImgOps | https://imgops.com/#b#`; window.addEventListener('scroll',this._scrollHandler,true); }, hide:function(){ + lastEvent = null; clearTimeout(this.showTimer); this.floatBar.style.opacity=0.01; this.shown=false; @@ -26204,7 +26215,7 @@ ImgOps | https://imgops.com/#b#`; if (e.relatedTarget == ImgWindowC.overlayer) return; if(uniqueImgWin && !uniqueImgWin.removed){ if(checkPreview(e)){ - if (!uniqueImgWin.data.img) return uniqueImgWin && uniqueImgWin.remove(); + if (!uniqueImgWin.data.img || !uniqueImgWin.data.img.parentNode) return uniqueImgWin && uniqueImgWin.remove(); let showArea=uniqueImgWin.data.img.getBoundingClientRect(); if(e.clientX < showArea.left + 20 || e.clientX > showArea.right - 20 || From 3932b4bf214267899e0e15f207d17c8fc4c62091 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 5 Oct 2025 19:30:16 +0900 Subject: [PATCH 0945/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 0bef18b9b67..9a03e0b6e17 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -3061,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" From 4605fdb88e262c09c490ef1f540bbc133b20b425 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 5 Oct 2025 10:30:47 +0000 Subject: [PATCH 0946/1065] Update version of Pagetual rules to 101 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 29d6383b52c..398050c62c8 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -100 +101 From 7ca84de4be5035185354781e8b540906cb9a9a8c Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 7 Oct 2025 15:12:28 +0900 Subject: [PATCH 0947/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index d1d432dea14..19d52d686a2 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.10.5.1 +// @version 2025.10.7.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -25272,6 +25272,9 @@ ImgOps | https://imgops.com/#b#`; } } + if (target.nodeName.toUpperCase() == 'IMG' && !target.naturalHeight) { + target = target.parentNode; + } // 扩展模式,检查前面一个是否为 img if (target.nodeName.toUpperCase() != 'IMG' && matchedRule.rules.length > 0 && matchedRule.ext) { var _type = typeof matchedRule.ext; @@ -25469,7 +25472,7 @@ ImgOps | https://imgops.com/#b#`; return; } - if (composedTarget) target = composedTarget; + if (composedTarget && composedTarget.naturalHeight) target = composedTarget; let found = false; if (target.nodeName.toUpperCase() == "AREA") target = target.parentNode; var broEle, broImg; @@ -25497,7 +25500,7 @@ ImgOps | https://imgops.com/#b#`; if (broEle == target) broEle = null; } } - if (target.children.length == 1 && !(target.textContent && target.textContent.trim()) && target.children[0].nodeName == "IMG") { + if (target.children.length == 1 && !(target.textContent && target.textContent.trim()) && target.children[0].naturalHeight) { target = target.children[0]; found = true; } else if (prefs.floatBar.listenBg && hasBg(target)) { From c71d961ffc1210c9b749db4dba916c857e7584c7 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 7 Oct 2025 06:12:38 +0000 Subject: [PATCH 0948/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index f55c6b1d18f..451246496d7 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.10.5.1 +// @version 2025.10.7.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -25272,6 +25272,9 @@ ImgOps | https://imgops.com/#b#`; } } + if (target.nodeName.toUpperCase() == 'IMG' && !target.naturalHeight) { + target = target.parentNode; + } // 扩展模式,检查前面一个是否为 img if (target.nodeName.toUpperCase() != 'IMG' && matchedRule.rules.length > 0 && matchedRule.ext) { var _type = typeof matchedRule.ext; @@ -25469,7 +25472,7 @@ ImgOps | https://imgops.com/#b#`; return; } - if (composedTarget) target = composedTarget; + if (composedTarget && composedTarget.naturalHeight) target = composedTarget; let found = false; if (target.nodeName.toUpperCase() == "AREA") target = target.parentNode; var broEle, broImg; @@ -25497,7 +25500,7 @@ ImgOps | https://imgops.com/#b#`; if (broEle == target) broEle = null; } } - if (target.children.length == 1 && !(target.textContent && target.textContent.trim()) && target.children[0].nodeName == "IMG") { + if (target.children.length == 1 && !(target.textContent && target.textContent.trim()) && target.children[0].naturalHeight) { target = target.children[0]; found = true; } else if (prefs.floatBar.listenBg && hasBg(target)) { From 0f60c6bc6d1676aef7a0c4ead34318997b148e1b Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 9 Oct 2025 17:55:17 +0900 Subject: [PATCH 0949/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 19d52d686a2..df509f9e9cf 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -25831,7 +25831,7 @@ ImgOps | https://imgops.com/#b#`; } } - var checkFloatBarTimer, initMouse = false, lastEvent, composedTarget; + var checkFloatBarTimer, initMouse = false, lastEvent, composedTarget, checking = false; function globalMouseoverHandler(e) { if (galleryMode) return;//库模式全屏中...... if (e.target == ImgWindowC.overlayer) return; @@ -25851,6 +25851,13 @@ ImgOps | https://imgops.com/#b#`; } return; } else { + if (checking) { + setTimeout(() => { + checking = false; + }, 50); + return; + } + checking = true; if (!canPreview) return; let target = e.target; if (target.nodeName == "PICTURE"){ @@ -25865,8 +25872,15 @@ ImgOps | https://imgops.com/#b#`; e = lastEvent; } else { lastEvent = e; - let path = e && e.composedPath && e.composedPath(); - composedTarget = path && path[0]; + if (checking) { + setTimeout(() => { + checking = false; + }, 50); + } else { + checking = true; + let path = e && e.composedPath && e.composedPath(); + composedTarget = path && path[0]; + } } clearTimeout(checkFloatBarTimer); checkFloatBarTimer = setTimeout(function() { From fee0f1f85139fd60374c55fa5e16f0108f3760f8 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Fri, 10 Oct 2025 05:31:56 +0000 Subject: [PATCH 0950/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 451246496d7..8664664b8ef 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -25831,7 +25831,7 @@ ImgOps | https://imgops.com/#b#`; } } - var checkFloatBarTimer, initMouse = false, lastEvent, composedTarget; + var checkFloatBarTimer, initMouse = false, lastEvent, composedTarget, checking = false; function globalMouseoverHandler(e) { if (galleryMode) return;//库模式全屏中...... if (e.target == ImgWindowC.overlayer) return; @@ -25851,6 +25851,13 @@ ImgOps | https://imgops.com/#b#`; } return; } else { + if (checking) { + setTimeout(() => { + checking = false; + }, 50); + return; + } + checking = true; if (!canPreview) return; let target = e.target; if (target.nodeName == "PICTURE"){ @@ -25865,8 +25872,15 @@ ImgOps | https://imgops.com/#b#`; e = lastEvent; } else { lastEvent = e; - let path = e && e.composedPath && e.composedPath(); - composedTarget = path && path[0]; + if (checking) { + setTimeout(() => { + checking = false; + }, 50); + } else { + checking = true; + let path = e && e.composedPath && e.composedPath(); + composedTarget = path && path[0]; + } } clearTimeout(checkFloatBarTimer); checkFloatBarTimer = setTimeout(function() { From 2af014b3c874e4179a4a2b717a807a3c139561a0 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 10 Oct 2025 20:10:02 +0900 Subject: [PATCH 0951/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 105 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 5 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 55d0456001a..19a800cae18 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.124 +// @version 1.9.37.125 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -4560,9 +4560,103 @@ return segs.length ? '/' + segs.join('/') : null; } - const escapeHTMLPolicy = (_unsafeWindow.trustedTypes && _unsafeWindow.trustedTypes.createPolicy) ? _unsafeWindow.trustedTypes.createPolicy('pagetual_default', { - createHTML: (string, sink) => string - }) : null; + function parseTrustedTypes(cspString) { + const policies = new Set(); + const ttRegex = /trusted-types\s+([^;]+)/gi; + let match; + while ((match = ttRegex.exec(cspString)) !== null) { + match[1].trim().split(/\s+/) + .forEach(name => { + if (name !== "'allow-duplicates'" && name !== "'none'") { + policies.add(name.replace(/'/g, '')); + } + }); + } + return Array.from(policies); + } + + async function getAvailablePolicyNamesOptimized() { + if (_unsafeWindow.trustedTypes && _unsafeWindow.trustedTypes.getPolicyNames) { + const existingNames = _unsafeWindow.trustedTypes.getPolicyNames(); + if (existingNames.length > 0) { + return new Set(existingNames); + } + } + + const meta = document.querySelector('meta[http-equiv="Content-Security-Policy"]'); + if (meta) { + const metaNames = parseTrustedTypes(meta.content); + if (metaNames.length > 0) { + return new Set(metaNames); + } + } + + 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 headerNames = parseTrustedTypes(cspHeader); + if (headerNames.length > 0) { + resolve(new Set(headerNames)); + } else { + resolve(new Set()); + } + }, + onerror: function(error) { + resolve(new Set()); + } + }); + }); + } + + function isTrustedTypesEnforced() { + try { + document.createElement('div').innerHTML = ''; + return false; + } catch (e) { + return true; + } + } + + async function createPolicy() { + if (_unsafeWindow.trustedTypes && _unsafeWindow.trustedTypes.createPolicy && isTrustedTypesEnforced()) { + const allowedNames = await getAvailablePolicyNamesOptimized(); + + if (allowedNames.size === 0) { + escapeHTMLPolicy = _unsafeWindow.trustedTypes.createPolicy('pagetual_default', { + createHTML: (string, sink) => string + }); + return; + } + + for (const name of allowedNames) { + if (name === '*') continue; + try { + escapeHTMLPolicy = _unsafeWindow.trustedTypes.createPolicy(name, { + createHTML: (string, sink) => string + }); + break; + } catch (e) { + try { + escapeHTMLPolicy = _unsafeWindow.trustedTypes.policies.get(name); + if (escapeHTMLPolicy) { + break; + } + } catch (e2) { + console.warn(`create '${name}' failed`); + } + } + } + } + } + + let escapeHTMLPolicy = null; function createHTML(html) { return escapeHTMLPolicy ? escapeHTMLPolicy.createHTML(html) : html; @@ -10290,7 +10384,8 @@ } let pageReady = false; - function initRules(callback) { + async function initRules(callback) { + await createPolicy(); charset = (document.characterSet || document.charset || document.inputEncoding); let equiv = document.querySelector('[http-equiv="Content-Type"]'); if (equiv && equiv.content) { From a33bdb63ea341236a294bca4f5e7ab7cfc9fd725 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 10 Oct 2025 20:17:48 +0900 Subject: [PATCH 0952/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 109 ++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 7 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index df509f9e9cf..4015b405bae 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.10.7.1 +// @version 2025.10.10.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -12455,15 +12455,109 @@ ImgOps | https://imgops.com/#b#`; }); } 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 parseTrustedTypes(cspString) { + const policies = new Set(); + const ttRegex = /trusted-types\s+([^;]+)/gi; + let match; + while ((match = ttRegex.exec(cspString)) !== null) { + match[1].trim().split(/\s+/) + .forEach(name => { + if (name !== "'allow-duplicates'" && name !== "'none'") { + policies.add(name.replace(/'/g, '')); + } + }); + } + return Array.from(policies); + } + + async function getAvailablePolicyNamesOptimized() { + if (unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.getPolicyNames) { + const existingNames = unsafeWindow.trustedTypes.getPolicyNames(); + if (existingNames.length > 0) { + return new Set(existingNames); + } + } + + const meta = document.querySelector('meta[http-equiv="Content-Security-Policy"]'); + if (meta) { + const metaNames = parseTrustedTypes(meta.content); + if (metaNames.length > 0) { + return new Set(metaNames); + } + } + + 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 headerNames = parseTrustedTypes(cspHeader); + if (headerNames.length > 0) { + resolve(new Set(headerNames)); + } else { + resolve(new Set()); + } + }, + onerror: function(error) { + resolve(new Set()); + } + }); }); } + function isTrustedTypesEnforced() { + try { + document.createElement('div').innerHTML = ''; + return false; + } catch (e) { + return true; + } + } + + async function createPolicy() { + if (unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.createPolicy && isTrustedTypesEnforced()) { + const allowedNames = await getAvailablePolicyNamesOptimized(); + + if (allowedNames.size === 0) { + escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy('pvcep_default', { + createHTML: (string, sink) => string, + createScriptURL: string => string, + createScript: string => string + }); + return; + } + + for (const name of allowedNames) { + if (name === '*') continue; + try { + escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy(name, { + createHTML: (string, sink) => string, + createScriptURL: string => string, + createScript: string => string + }); + break; + } catch (e) { + try { + escapeHTMLPolicy = unsafeWindow.trustedTypes.policies.get(name); + if (escapeHTMLPolicy) { + break; + } + } catch (e2) { + console.warn(`create '${name}' failed`); + } + } + } + } + } + + let escapeHTMLPolicy = null; + function getBody(doc){ return doc.body || doc.querySelector('body') || doc; } @@ -12477,6 +12571,7 @@ ImgOps | https://imgops.com/#b#`; return escapeHTMLPolicy?escapeHTMLPolicy.createScript(html):html; } async function init(topObject,window,document,arrayFn,envir,storage,unsafeWindow){ + await createPolicy(); // 默认设置,请到设置界面修改 prefs={ floatBar:{//浮动工具栏相关设置. From e1a9c1ab0d1811aafec7ce0e53cfcbd1801ffcad Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 10 Oct 2025 20:18:29 +0900 Subject: [PATCH 0953/1065] Update README.md --- Pagetual/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index c4fcad3d2c6..b41b3d04643 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.124](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.125](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* From f061593a6b38640426f591921426305c6024f389 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Fri, 10 Oct 2025 11:18:53 +0000 Subject: [PATCH 0954/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 109 ++++++++++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 7 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 8664664b8ef..c4ce7f0cda0 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.10.7.1 +// @version 2025.10.10.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -12455,15 +12455,109 @@ ImgOps | https://imgops.com/#b#`; }); } 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 parseTrustedTypes(cspString) { + const policies = new Set(); + const ttRegex = /trusted-types\s+([^;]+)/gi; + let match; + while ((match = ttRegex.exec(cspString)) !== null) { + match[1].trim().split(/\s+/) + .forEach(name => { + if (name !== "'allow-duplicates'" && name !== "'none'") { + policies.add(name.replace(/'/g, '')); + } + }); + } + return Array.from(policies); + } + + async function getAvailablePolicyNamesOptimized() { + if (unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.getPolicyNames) { + const existingNames = unsafeWindow.trustedTypes.getPolicyNames(); + if (existingNames.length > 0) { + return new Set(existingNames); + } + } + + const meta = document.querySelector('meta[http-equiv="Content-Security-Policy"]'); + if (meta) { + const metaNames = parseTrustedTypes(meta.content); + if (metaNames.length > 0) { + return new Set(metaNames); + } + } + + 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 headerNames = parseTrustedTypes(cspHeader); + if (headerNames.length > 0) { + resolve(new Set(headerNames)); + } else { + resolve(new Set()); + } + }, + onerror: function(error) { + resolve(new Set()); + } + }); }); } + function isTrustedTypesEnforced() { + try { + document.createElement('div').innerHTML = ''; + return false; + } catch (e) { + return true; + } + } + + async function createPolicy() { + if (unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.createPolicy && isTrustedTypesEnforced()) { + const allowedNames = await getAvailablePolicyNamesOptimized(); + + if (allowedNames.size === 0) { + escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy('pvcep_default', { + createHTML: (string, sink) => string, + createScriptURL: string => string, + createScript: string => string + }); + return; + } + + for (const name of allowedNames) { + if (name === '*') continue; + try { + escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy(name, { + createHTML: (string, sink) => string, + createScriptURL: string => string, + createScript: string => string + }); + break; + } catch (e) { + try { + escapeHTMLPolicy = unsafeWindow.trustedTypes.policies.get(name); + if (escapeHTMLPolicy) { + break; + } + } catch (e2) { + console.warn(`create '${name}' failed`); + } + } + } + } + } + + let escapeHTMLPolicy = null; + function getBody(doc){ return doc.body || doc.querySelector('body') || doc; } @@ -12477,6 +12571,7 @@ ImgOps | https://imgops.com/#b#`; return escapeHTMLPolicy?escapeHTMLPolicy.createScript(html):html; } async function init(topObject,window,document,arrayFn,envir,storage,unsafeWindow){ + await createPolicy(); // 默认设置,请到设置界面修改 prefs={ floatBar:{//浮动工具栏相关设置. From 4143b2f34eab9448dde54f4283489c41a639499b Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 12 Oct 2025 21:24:31 +0900 Subject: [PATCH 0955/1065] Update pagetualRules.json --- Pagetual/pagetualRules.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Pagetual/pagetualRules.json b/Pagetual/pagetualRules.json index 9a03e0b6e17..c8332cd09d8 100644 --- a/Pagetual/pagetualRules.json +++ b/Pagetual/pagetualRules.json @@ -5519,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, From 9c7dca8e32418161177a842ec8d005a0c8e7eeb0 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sun, 12 Oct 2025 12:24:46 +0000 Subject: [PATCH 0956/1065] Update version of Pagetual rules to 102 --- Pagetual/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pagetual/version b/Pagetual/version index 398050c62c8..257e563266b 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -101 +102 From edba8c1b5f4e8a7f85a745640c8484ccabe390dc Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 16 Oct 2025 13:25:23 +0900 Subject: [PATCH 0957/1065] Update Switch Traditional Chinese and Simplified Chinese.user.js --- ...nal Chinese and Simplified Chinese.user.js | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js index e379235e701..c4009b12925 100644 --- a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js +++ b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js @@ -6,7 +6,7 @@ // @namespace hoothin // @supportURL https://github.com/hoothin/UserScripts // @homepageURL https://github.com/hoothin/UserScripts -// @version 1.2.7.9 +// @version 1.2.7.10 // @description 任意轉換網頁中的簡體中文與正體中文(默認簡體→正體),顯示漢字對應漢語拼音,自訂任意替換文本 // @description:zh-CN 任意转换网页中的简体中文与繁体中文(默认繁体→简体),显示汉字对应汉语拼音,自定义任意替换文本 // @description:ja ウェブページ上の簡体字中国語と繁体字中国語を自由に変換し、中国語の文字にひらがなを表示し、任意の文字を置き換えることができます。 @@ -1713,12 +1713,16 @@ storage.setItem('sc2tcCombConfig', sc2tcCombConfig); } catch (e) { console.log(e); + alert("自訂簡繁用語轉換格式錯誤:" + e); + return; } try { illiteracyConfig = customIlliteracyInput.value ? JSON.parse(customIlliteracyInput.value) : ""; storage.setItem('illiteracyConfig', illiteracyConfig); } catch (e) { console.log(e); + alert("通用字詞轉換格式錯誤:" + e); + return; } storage.setItem('sc2tcCombTree', ""); storage.setItem('tc2scCombTree', ""); @@ -1888,32 +1892,38 @@ function makeCombTree(key, value) { let curTree=sc2tcCombTree; for(let i=0;i Date: Thu, 16 Oct 2025 20:28:19 +0900 Subject: [PATCH 0958/1065] update --- Pagetual/pagetual.user.js | 10 +--- Picviewer CE+/Picviewer CE+.user.js | 75 +++++++++++++++-------------- 2 files changed, 40 insertions(+), 45 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 19a800cae18..c644b963b10 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -4643,14 +4643,8 @@ }); break; } catch (e) { - try { - escapeHTMLPolicy = _unsafeWindow.trustedTypes.policies.get(name); - if (escapeHTMLPolicy) { - break; - } - } catch (e2) { - console.warn(`create '${name}' failed`); - } + console.warn(`create '${name}' failed`); + return; } } } diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 4015b405bae..92a3f8522cc 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.10.10.1 +// @version 2025.10.16.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -12543,14 +12543,8 @@ ImgOps | https://imgops.com/#b#`; }); break; } catch (e) { - try { - escapeHTMLPolicy = unsafeWindow.trustedTypes.policies.get(name); - if (escapeHTMLPolicy) { - break; - } - } catch (e2) { - console.warn(`create '${name}' failed`); - } + console.warn(`create '${name}' failed`); + return; } } } @@ -22227,12 +22221,10 @@ ImgOps | https://imgops.com/#b#`; let size = rectSize, containsScroll = imgWindow.classList.contains("pv-pic-window-scroll"); if (rectSize.w > wSize.w) { - if (rectSize.w / rectSize.h > wSize.w / wSize.h) { - size = { - w: wSize.w, - h: wSize.w / (rectSize.w / rectSize.h), - }; - } + size = { + w: wSize.w, + h: wSize.w / (rectSize.w / rectSize.h), + }; let cs = this.getRotatedImgCliSize(size); let ns = this.imgNaturalSize; @@ -24250,7 +24242,7 @@ ImgOps | https://imgops.com/#b#`; window.addEventListener('scroll',this._scrollHandler,true); }, hide:function(){ - lastEvent = null; + target = null; clearTimeout(this.showTimer); this.floatBar.style.opacity=0.01; this.shown=false; @@ -25674,16 +25666,18 @@ ImgOps | https://imgops.com/#b#`; } } } - if (!found && target.children && target.children[0] && target.children[0].nodeName.toUpperCase() == 'IMG') { - let img = target.children[0]; - while (img.nextElementSibling && img.nextElementSibling.nodeName.toUpperCase() == 'IMG') { - img = img.nextElementSibling; - } - let rect = img.getBoundingClientRect(); + if (!found && target.children && target.children.length) { + let img = target.querySelector("img"); + if (img) { + while (img.nextElementSibling && img.nextElementSibling.nodeName.toUpperCase() == 'IMG') { + img = img.nextElementSibling; + } + let rect = img.getBoundingClientRect(); - if (clientY >= rect.top && clientY <= rect.bottom && clientX >= rect.left && clientX <= rect.right) { - target = img; - found = true; + if (clientY >= rect.top && clientY <= rect.bottom && clientX >= rect.left && clientX <= rect.right) { + target = img; + found = true; + } } } if (!found && document.elementsFromPoint) { @@ -25926,7 +25920,7 @@ ImgOps | https://imgops.com/#b#`; } } - var checkFloatBarTimer, initMouse = false, lastEvent, composedTarget, checking = false; + var checkFloatBarTimer, initMouse = false, composedTarget, checking = false, target, type, clientX, clientY, altKey; function globalMouseoverHandler(e) { if (galleryMode) return;//库模式全屏中...... if (e.target == ImgWindowC.overlayer) return; @@ -25963,26 +25957,33 @@ ImgOps | https://imgops.com/#b#`; } if (!initMouse) return; if (e.type == "keydown") { - if (!lastEvent) return; - e = lastEvent; + if (!target) return; } else { - lastEvent = e; - if (checking) { - setTimeout(() => { - checking = false; - }, 50); - } else { - checking = true; + target = e.target; + type = e.type; + clientX = e.clientX; + clientY = e.clientY; + altKey = e.altKey; + if (e.type !== "mousemove") { let path = e && e.composedPath && e.composedPath(); composedTarget = path && path[0]; } } clearTimeout(checkFloatBarTimer); checkFloatBarTimer = setTimeout(function() { - if (!e || !e.target || !e.target.parentNode) return; + if (!target || !target.parentNode) return; if (gallery && gallery.shown) return; - checkFloatBar(e.target, e.type, canPreview, e.clientX, e.clientY, e.altKey, composedTarget); + checkFloatBar(target, type, canPreview, clientX, clientY, altKey, composedTarget); }, 50); + if (e.target.shadowRoot) { + if (!e.target.shadowRoot.initListener) { + e.target.shadowRoot.initListener = true; + e.target.shadowRoot.addEventListener('mouseenter', (e) => { + globalMouseoverHandler(e); + }, true); + e.target.shadowRoot.addEventListener('mousemove', globalMouseoverHandler, true); + } + } } var selectionClientRect, selectionStr, selectionChanging = false; From 68710e448a1771eb0d9ef0788eaf2d94a0784d06 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 16 Oct 2025 11:28:30 +0000 Subject: [PATCH 0959/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 75 +++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index c4ce7f0cda0..6a142a772c1 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.10.10.1 +// @version 2025.10.16.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -12543,14 +12543,8 @@ ImgOps | https://imgops.com/#b#`; }); break; } catch (e) { - try { - escapeHTMLPolicy = unsafeWindow.trustedTypes.policies.get(name); - if (escapeHTMLPolicy) { - break; - } - } catch (e2) { - console.warn(`create '${name}' failed`); - } + console.warn(`create '${name}' failed`); + return; } } } @@ -22227,12 +22221,10 @@ ImgOps | https://imgops.com/#b#`; let size = rectSize, containsScroll = imgWindow.classList.contains("pv-pic-window-scroll"); if (rectSize.w > wSize.w) { - if (rectSize.w / rectSize.h > wSize.w / wSize.h) { - size = { - w: wSize.w, - h: wSize.w / (rectSize.w / rectSize.h), - }; - } + size = { + w: wSize.w, + h: wSize.w / (rectSize.w / rectSize.h), + }; let cs = this.getRotatedImgCliSize(size); let ns = this.imgNaturalSize; @@ -24250,7 +24242,7 @@ ImgOps | https://imgops.com/#b#`; window.addEventListener('scroll',this._scrollHandler,true); }, hide:function(){ - lastEvent = null; + target = null; clearTimeout(this.showTimer); this.floatBar.style.opacity=0.01; this.shown=false; @@ -25674,16 +25666,18 @@ ImgOps | https://imgops.com/#b#`; } } } - if (!found && target.children && target.children[0] && target.children[0].nodeName.toUpperCase() == 'IMG') { - let img = target.children[0]; - while (img.nextElementSibling && img.nextElementSibling.nodeName.toUpperCase() == 'IMG') { - img = img.nextElementSibling; - } - let rect = img.getBoundingClientRect(); + if (!found && target.children && target.children.length) { + let img = target.querySelector("img"); + if (img) { + while (img.nextElementSibling && img.nextElementSibling.nodeName.toUpperCase() == 'IMG') { + img = img.nextElementSibling; + } + let rect = img.getBoundingClientRect(); - if (clientY >= rect.top && clientY <= rect.bottom && clientX >= rect.left && clientX <= rect.right) { - target = img; - found = true; + if (clientY >= rect.top && clientY <= rect.bottom && clientX >= rect.left && clientX <= rect.right) { + target = img; + found = true; + } } } if (!found && document.elementsFromPoint) { @@ -25926,7 +25920,7 @@ ImgOps | https://imgops.com/#b#`; } } - var checkFloatBarTimer, initMouse = false, lastEvent, composedTarget, checking = false; + var checkFloatBarTimer, initMouse = false, composedTarget, checking = false, target, type, clientX, clientY, altKey; function globalMouseoverHandler(e) { if (galleryMode) return;//库模式全屏中...... if (e.target == ImgWindowC.overlayer) return; @@ -25963,26 +25957,33 @@ ImgOps | https://imgops.com/#b#`; } if (!initMouse) return; if (e.type == "keydown") { - if (!lastEvent) return; - e = lastEvent; + if (!target) return; } else { - lastEvent = e; - if (checking) { - setTimeout(() => { - checking = false; - }, 50); - } else { - checking = true; + target = e.target; + type = e.type; + clientX = e.clientX; + clientY = e.clientY; + altKey = e.altKey; + if (e.type !== "mousemove") { let path = e && e.composedPath && e.composedPath(); composedTarget = path && path[0]; } } clearTimeout(checkFloatBarTimer); checkFloatBarTimer = setTimeout(function() { - if (!e || !e.target || !e.target.parentNode) return; + if (!target || !target.parentNode) return; if (gallery && gallery.shown) return; - checkFloatBar(e.target, e.type, canPreview, e.clientX, e.clientY, e.altKey, composedTarget); + checkFloatBar(target, type, canPreview, clientX, clientY, altKey, composedTarget); }, 50); + if (e.target.shadowRoot) { + if (!e.target.shadowRoot.initListener) { + e.target.shadowRoot.initListener = true; + e.target.shadowRoot.addEventListener('mouseenter', (e) => { + globalMouseoverHandler(e); + }, true); + e.target.shadowRoot.addEventListener('mousemove', globalMouseoverHandler, true); + } + } } var selectionClientRect, selectionStr, selectionChanging = false; From 179a45dcdd92afc215a98334b08ab7323379c08b Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 16 Oct 2025 21:58:55 +0900 Subject: [PATCH 0960/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 92a3f8522cc..d5d71a9dc12 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -23539,6 +23539,7 @@ ImgOps | https://imgops.com/#b#`; }, remove:function(){ if(!this.removed){ + lastPopupLoading = null; this.removed=true; this.loadingAnim.parentNode.removeChild(this.loadingAnim); LoadingAnimC.all.splice(LoadingAnimC.all.indexOf(this),1); @@ -23651,6 +23652,7 @@ ImgOps | https://imgops.com/#b#`; }, load:async function(img,e){ + lastPopupLoading = null; this.remove(); this.img=img; var buttonType=this.buttonType; From 85c80405624b4a68dae6b4e157a7435306b6ff3f Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Thu, 16 Oct 2025 13:34:17 +0000 Subject: [PATCH 0961/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 6a142a772c1..2a12f799800 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -23539,6 +23539,7 @@ ImgOps | https://imgops.com/#b#`; }, remove:function(){ if(!this.removed){ + lastPopupLoading = null; this.removed=true; this.loadingAnim.parentNode.removeChild(this.loadingAnim); LoadingAnimC.all.splice(LoadingAnimC.all.indexOf(this),1); @@ -23651,6 +23652,7 @@ ImgOps | https://imgops.com/#b#`; }, load:async function(img,e){ + lastPopupLoading = null; this.remove(); this.img=img; var buttonType=this.buttonType; From e74c019e77c44b0702b830b8bcbc8904014f8f5b Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 18 Oct 2025 18:55:42 +0900 Subject: [PATCH 0962/1065] sbbd --- BingBgForBaidu/BingBgForBaidu.user.js | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/BingBgForBaidu/BingBgForBaidu.user.js b/BingBgForBaidu/BingBgForBaidu.user.js index c33755d652d..663d6b4c93a 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.42 +// @version 2.3.43 // @description 给百度首页换上Bing的背景图,并添加背景图链接与日历组件 // @description:en Just change the background image of baidu.com to bing.com // @author hoothin @@ -99,7 +99,7 @@ iframeDoc.scrollTop(125); iframeDoc.scrollLeft(145); iframe.width=618; - iframe.height=615; + iframe.height=630; }; riliLink.onmouseleave=function(){ clearTimeout(t); @@ -123,17 +123,14 @@ riliLink.title=title; } }; - var skinContainer=document.querySelector(".s-skin-container"); - if(!skinContainer){ - skinContainer=document.getElementsByTagName("body")[0]; - 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-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]; + 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;}.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+"\")"; From f112393bf1b4e99b97b3d031c477a864e2815529 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 19 Oct 2025 21:12:57 +0900 Subject: [PATCH 0963/1065] fkbd --- BingBgForBaidu/BingBgForBaidu.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BingBgForBaidu/BingBgForBaidu.user.js b/BingBgForBaidu/BingBgForBaidu.user.js index 663d6b4c93a..6d53105a5c0 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.43 +// @version 2.3.44 // @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;}.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图"; From 19be024fa622e158a7a5e4cd75d670ac26a5a34e Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 19 Oct 2025 21:17:44 +0900 Subject: [PATCH 0964/1065] Update BingBgForBaidu.user.js --- BingBgForBaidu/BingBgForBaidu.user.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/BingBgForBaidu/BingBgForBaidu.user.js b/BingBgForBaidu/BingBgForBaidu.user.js index 6d53105a5c0..43bb7714ff9 100644 --- a/BingBgForBaidu/BingBgForBaidu.user.js +++ b/BingBgForBaidu/BingBgForBaidu.user.js @@ -153,7 +153,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(() => { @@ -165,6 +165,11 @@ }, 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: "https://global.bing.com/HPImageArchive.aspx?format=js&idx=0&pid=hp&video=1&n=1", From f9701f9c17603a4186a8f05b407430bc058fe1d2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 20 Oct 2025 09:16:23 +0900 Subject: [PATCH 0965/1065] Update BingBgForBaidu.user.js --- BingBgForBaidu/BingBgForBaidu.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BingBgForBaidu/BingBgForBaidu.user.js b/BingBgForBaidu/BingBgForBaidu.user.js index 43bb7714ff9..6c86b1050dd 100644 --- a/BingBgForBaidu/BingBgForBaidu.user.js +++ b/BingBgForBaidu/BingBgForBaidu.user.js @@ -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("[tpl='ai-tools-panel'],.fixed-skin-wrapper{display: none!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;}"); + 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图"; From d613c68876c0a5d7384fd18b8d3dac9683671013 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 22 Oct 2025 09:42:05 +0900 Subject: [PATCH 0966/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index d5d71a9dc12..3b841f72517 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.10.16.1 +// @version 2025.10.22.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -22813,7 +22813,7 @@ ImgOps | https://imgops.com/#b#`; }, focusedKeyup:function(e){ var keyCode=e.keyCode; - var valid=[27,32,18,16,72,17,72,82,90,67,37,39]; + var valid=[27,32,18,16,72,17,72,82,90,67,37,38,39,40]; if(valid.indexOf(keyCode)==-1)return; if (window.getSelection().toString()) return; @@ -22872,12 +22872,12 @@ ImgOps | https://imgops.com/#b#`; case 90://z键 this.zKeyUp=true; break; - case 39: - this.switchImage(true); - break; case 37: this.switchImage(false); break; + case 39: + this.switchImage(true); + break; case 27: if (prefs.imgWindow.close.escKey) { this.remove(); @@ -22918,7 +22918,7 @@ ImgOps | https://imgops.com/#b#`; e.stopPropagation(); return; } - var valid=[32,82,72,90,18,16,17,27,67];//有效的按键 + var valid=[32,82,72,90,18,16,17,27,67,38,40];//有效的按键 if(valid.indexOf(keyCode)==-1) return; e.preventDefault(); @@ -23006,6 +23006,12 @@ ImgOps | https://imgops.com/#b#`; }break; case 27:{//ese关闭窗口 }break; + case 38:{//上 + this.imgbox.scrollTop -= 200; + }break; + case 40:{//下 + this.imgbox.scrollTop += 200; + }break; default:break; } e.stopPropagation(); From 78dfe1a5f9b62c0d19b48ca924dcb038f33469d6 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Wed, 22 Oct 2025 00:42:24 +0000 Subject: [PATCH 0967/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 2a12f799800..e25371e7230 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.10.16.1 +// @version 2025.10.22.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -22813,7 +22813,7 @@ ImgOps | https://imgops.com/#b#`; }, focusedKeyup:function(e){ var keyCode=e.keyCode; - var valid=[27,32,18,16,72,17,72,82,90,67,37,39]; + var valid=[27,32,18,16,72,17,72,82,90,67,37,38,39,40]; if(valid.indexOf(keyCode)==-1)return; if (window.getSelection().toString()) return; @@ -22872,12 +22872,12 @@ ImgOps | https://imgops.com/#b#`; case 90://z键 this.zKeyUp=true; break; - case 39: - this.switchImage(true); - break; case 37: this.switchImage(false); break; + case 39: + this.switchImage(true); + break; case 27: if (prefs.imgWindow.close.escKey) { this.remove(); @@ -22918,7 +22918,7 @@ ImgOps | https://imgops.com/#b#`; e.stopPropagation(); return; } - var valid=[32,82,72,90,18,16,17,27,67];//有效的按键 + var valid=[32,82,72,90,18,16,17,27,67,38,40];//有效的按键 if(valid.indexOf(keyCode)==-1) return; e.preventDefault(); @@ -23006,6 +23006,12 @@ ImgOps | https://imgops.com/#b#`; }break; case 27:{//ese关闭窗口 }break; + case 38:{//上 + this.imgbox.scrollTop -= 200; + }break; + case 40:{//下 + this.imgbox.scrollTop += 200; + }break; default:break; } e.stopPropagation(); From c55d0703088768187a3c859e14dcbf32d47f55c9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 27 Oct 2025 21:53:59 +0900 Subject: [PATCH 0968/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 3b841f72517..4ede058bfda 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.10.22.1 +// @version 2025.10.27.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -13627,6 +13627,9 @@ ImgOps | https://imgops.com/#b#`; }break; case 'error':{ removeListener(); + iRReadyFn = iRReadyFn.filter(function(item) { + return item !== readyHandler + }); if(error){ error.call(img,e); }; @@ -13703,13 +13706,8 @@ ImgOps | https://imgops.com/#b#`; setTimeout(() => { if (aborted) return; if (typeof img.width == 'number' && img.width && img.height) { - go('load', { - type:'load', - target: img, - }); } else { errorBlobList[orgSrc] = true; - go('error',e); } }, 0); }, From 6fb19d626a91e8511dc110c781c11b6c8b7de143 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Mon, 27 Oct 2025 12:54:15 +0000 Subject: [PATCH 0969/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index e25371e7230..68e33c7db3d 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.10.22.1 +// @version 2025.10.27.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -13627,6 +13627,9 @@ ImgOps | https://imgops.com/#b#`; }break; case 'error':{ removeListener(); + iRReadyFn = iRReadyFn.filter(function(item) { + return item !== readyHandler + }); if(error){ error.call(img,e); }; @@ -13703,13 +13706,8 @@ ImgOps | https://imgops.com/#b#`; setTimeout(() => { if (aborted) return; if (typeof img.width == 'number' && img.width && img.height) { - go('load', { - type:'load', - target: img, - }); } else { errorBlobList[orgSrc] = true; - go('error',e); } }, 0); }, From 64a3ec226ac5dbeabee0e1e05a82ece3b064ccc4 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 27 Oct 2025 22:16:14 +0900 Subject: [PATCH 0970/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 122 ++++++++++++++++++---------- 1 file changed, 78 insertions(+), 44 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 4ede058bfda..445482c9340 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12458,32 +12458,39 @@ ImgOps | https://imgops.com/#b#`; 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'" && name !== "'none'") { - policies.add(name.replace(/'/g, '')); - } - }); + if (name === "'allow-duplicates'") { + allowDuplicates = true; + } else if (name !== "'none'") { + policies.add(name.replace(/'/g, '')); + } + }); } - return Array.from(policies); + return { names: policies, allowDuplicates: allowDuplicates, ttDirectiveFound: ttDirectiveFound }; } - async function getAvailablePolicyNamesOptimized() { - if (unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.getPolicyNames) { - const existingNames = unsafeWindow.trustedTypes.getPolicyNames(); - if (existingNames.length > 0) { - return new Set(existingNames); - } - } + 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 metaNames = parseTrustedTypes(meta.content); - if (metaNames.length > 0) { - return new Set(metaNames); + const metaResult = parseTrustedTypes(meta.content); + metaResult.names.forEach(name => combinedPolicies.add(name)); + if (metaResult.allowDuplicates) { + combinedAllowDuplicates = true; + } + if (metaResult.ttDirectiveFound) { + combinedTtDirectiveFound = true; } } @@ -12493,19 +12500,31 @@ ImgOps | https://imgops.com/#b#`; 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 headerNames = parseTrustedTypes(cspHeader); - if (headerNames.length > 0) { - resolve(new Set(headerNames)); - } else { - resolve(new Set()); + .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(new Set()); + resolve({ + names: combinedPolicies, + allowDuplicates: combinedAllowDuplicates, + ttDirectiveFound: combinedTtDirectiveFound + }); } }); }); @@ -12521,33 +12540,48 @@ ImgOps | https://imgops.com/#b#`; } async function createPolicy() { - if (unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.createPolicy && isTrustedTypesEnforced()) { - const allowedNames = await getAvailablePolicyNamesOptimized(); + 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; + } - if (allowedNames.size === 0) { - escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy('pvcep_default', { + const MY_POLICY_NAME = 'pvcep_default'; + + try { + escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy(MY_POLICY_NAME, { + createHTML: (string, sink) => string, + createScriptURL: string => string, + createScript: string => string + }); + return; + } catch (e) { + } + + const existingPolicies = new Set(unsafeWindow.trustedTypes.getPolicyNames()); + for (const name of allowedNames) { + if (name === '*' || existingPolicies.has(name)) { + continue; + } + + try { + escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy(name, { createHTML: (string, sink) => string, createScriptURL: string => string, createScript: string => string }); return; - } - - for (const name of allowedNames) { - if (name === '*') continue; - try { - escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy(name, { - createHTML: (string, sink) => string, - createScriptURL: string => string, - createScript: string => string - }); - break; - } catch (e) { - console.warn(`create '${name}' failed`); - return; - } + } catch (e) { + debug(`create '${name}' failed, trying next...`); } } + debug("Could not create any trusted types policy."); } let escapeHTMLPolicy = null; From b26cbb3d63939d1009ca004e098cfc35448ca25e Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 27 Oct 2025 22:23:52 +0900 Subject: [PATCH 0971/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 127 +++++++++++++++++++++++++------------- 1 file changed, 83 insertions(+), 44 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index c644b963b10..ec17e5b593c 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -4562,32 +4562,40 @@ 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) { - match[1].trim().split(/\s+/) - .forEach(name => { - if (name !== "'allow-duplicates'" && name !== "'none'") { - policies.add(name.replace(/'/g, '')); - } - }); - } - return Array.from(policies); - } + ttDirectiveFound = true; - async function getAvailablePolicyNamesOptimized() { - if (_unsafeWindow.trustedTypes && _unsafeWindow.trustedTypes.getPolicyNames) { - const existingNames = _unsafeWindow.trustedTypes.getPolicyNames(); - if (existingNames.length > 0) { - return new Set(existingNames); + const policyNames = match[1].trim().split(/\s+/); + for (const name of policyNames) { + if (name === "'allow-duplicates'") { + allowDuplicates = true; + } else if (name !== "'none'") { + policies.add(name.replace(/'/g, '')); + } } } + 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 metaNames = parseTrustedTypes(meta.content); - if (metaNames.length > 0) { - return new Set(metaNames); + const metaResult = parseTrustedTypes(meta.content); + metaResult.names.forEach(name => combinedPolicies.add(name)); + if (metaResult.allowDuplicates) { + combinedAllowDuplicates = true; + } + if (metaResult.ttDirectiveFound) { + combinedTtDirectiveFound = true; } } @@ -4597,19 +4605,31 @@ 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('; '); + .filter(h => h.toLowerCase().startsWith('content-security-policy:')) + .map(h => h.substring(26).trim()) + .join('; '); - const headerNames = parseTrustedTypes(cspHeader); - if (headerNames.length > 0) { - resolve(new Set(headerNames)); - } else { - resolve(new Set()); + 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(new Set()); + resolve({ + names: combinedPolicies, + allowDuplicates: combinedAllowDuplicates, + ttDirectiveFound: combinedTtDirectiveFound + }); } }); }); @@ -4625,29 +4645,48 @@ } async function createPolicy() { - if (_unsafeWindow.trustedTypes && _unsafeWindow.trustedTypes.createPolicy && isTrustedTypesEnforced()) { - const allowedNames = await getAvailablePolicyNamesOptimized(); + if (!(_unsafeWindow.trustedTypes && _unsafeWindow.trustedTypes.createPolicy && isTrustedTypesEnforced())) { + return; + } - if (allowedNames.size === 0) { - escapeHTMLPolicy = _unsafeWindow.trustedTypes.createPolicy('pagetual_default', { - createHTML: (string, sink) => string - }); - 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 + }); + return; + } catch (e) { + } + + const existingPolicies = new Set(_unsafeWindow.trustedTypes.getPolicyNames()); + for (const name of allowedNames) { + if (name === '*' || existingPolicies.has(name)) { + continue; } - for (const name of allowedNames) { - if (name === '*') continue; - try { - escapeHTMLPolicy = _unsafeWindow.trustedTypes.createPolicy(name, { - createHTML: (string, sink) => string - }); - break; - } catch (e) { - console.warn(`create '${name}' failed`); - return; - } + try { + escapeHTMLPolicy = _unsafeWindow.trustedTypes.createPolicy(name, { + createHTML: (string, sink) => string, + createScriptURL: string => string, + createScript: string => string + }); + return; + } catch (e) { + debug(`create '${name}' failed, trying next...`); } } + debug("Could not create any trusted types policy."); } let escapeHTMLPolicy = null; From bc2b255c97e11fbe6e98de20b0cd872320a7216b Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Mon, 27 Oct 2025 13:24:16 +0000 Subject: [PATCH 0972/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 122 ++++++++++++++++++++++++------------- 1 file changed, 78 insertions(+), 44 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 68e33c7db3d..7dbfcbdc63a 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12458,32 +12458,39 @@ ImgOps | https://imgops.com/#b#`; 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'" && name !== "'none'") { - policies.add(name.replace(/'/g, '')); - } - }); + if (name === "'allow-duplicates'") { + allowDuplicates = true; + } else if (name !== "'none'") { + policies.add(name.replace(/'/g, '')); + } + }); } - return Array.from(policies); + return { names: policies, allowDuplicates: allowDuplicates, ttDirectiveFound: ttDirectiveFound }; } - async function getAvailablePolicyNamesOptimized() { - if (unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.getPolicyNames) { - const existingNames = unsafeWindow.trustedTypes.getPolicyNames(); - if (existingNames.length > 0) { - return new Set(existingNames); - } - } + 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 metaNames = parseTrustedTypes(meta.content); - if (metaNames.length > 0) { - return new Set(metaNames); + const metaResult = parseTrustedTypes(meta.content); + metaResult.names.forEach(name => combinedPolicies.add(name)); + if (metaResult.allowDuplicates) { + combinedAllowDuplicates = true; + } + if (metaResult.ttDirectiveFound) { + combinedTtDirectiveFound = true; } } @@ -12493,19 +12500,31 @@ ImgOps | https://imgops.com/#b#`; 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 headerNames = parseTrustedTypes(cspHeader); - if (headerNames.length > 0) { - resolve(new Set(headerNames)); - } else { - resolve(new Set()); + .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(new Set()); + resolve({ + names: combinedPolicies, + allowDuplicates: combinedAllowDuplicates, + ttDirectiveFound: combinedTtDirectiveFound + }); } }); }); @@ -12521,33 +12540,48 @@ ImgOps | https://imgops.com/#b#`; } async function createPolicy() { - if (unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.createPolicy && isTrustedTypesEnforced()) { - const allowedNames = await getAvailablePolicyNamesOptimized(); + 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; + } - if (allowedNames.size === 0) { - escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy('pvcep_default', { + const MY_POLICY_NAME = 'pvcep_default'; + + try { + escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy(MY_POLICY_NAME, { + createHTML: (string, sink) => string, + createScriptURL: string => string, + createScript: string => string + }); + return; + } catch (e) { + } + + const existingPolicies = new Set(unsafeWindow.trustedTypes.getPolicyNames()); + for (const name of allowedNames) { + if (name === '*' || existingPolicies.has(name)) { + continue; + } + + try { + escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy(name, { createHTML: (string, sink) => string, createScriptURL: string => string, createScript: string => string }); return; - } - - for (const name of allowedNames) { - if (name === '*') continue; - try { - escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy(name, { - createHTML: (string, sink) => string, - createScriptURL: string => string, - createScript: string => string - }); - break; - } catch (e) { - console.warn(`create '${name}' failed`); - return; - } + } catch (e) { + debug(`create '${name}' failed, trying next...`); } } + debug("Could not create any trusted types policy."); } let escapeHTMLPolicy = null; From 5943163ee64646b532110c19b40d8a13cb08ab79 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 28 Oct 2025 17:13:06 +0900 Subject: [PATCH 0973/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index ec17e5b593c..58cca3fb32b 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -6361,6 +6361,7 @@ root_domain = /^\w+\:\/\/\/?[^\/]+/.exec(root_page)[0], absolute_regex = /^\w+\:\/\//; this.updateUrl = false; + src = src.replace(/^\/(\.\.\/)+/, "/"); while (src.indexOf("../") === 0) { src = src.substr(3); root_page = root_page.replace(/\/[^\/]+\/$/, "/"); From 15e5418c4f45eff54610ed8f439e69b0f1edf44a Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 28 Oct 2025 17:14:41 +0900 Subject: [PATCH 0974/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 445482c9340..cbae4e915b1 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12155,6 +12155,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(/\/[^\/]+\/$/, "/"); From 0e020afc9e5bd71019aa539f5c5dda98290d0ff4 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 28 Oct 2025 08:15:08 +0000 Subject: [PATCH 0975/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 7dbfcbdc63a..1395cd9b877 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12155,6 +12155,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(/\/[^\/]+\/$/, "/"); From fa88630f8df16716d43257cd1593fbb5c0041772 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 1 Nov 2025 22:16:09 +0900 Subject: [PATCH 0976/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 34f9148c807..76038f2c4bd 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1481,7 +1481,7 @@ var siteInfo = [ { name: "nhentai", url: /\bnhentai\./i, - r: [/(cdn\..*\d+)t(\.[a-z]+)$/, /\/\/\w+(\..*\/)(\d+)t(\.[a-z]+)$/i], + r: [/(cdn\..*\d+)t(\.[a-z]+)$/, /\/\/\w+(\..*\/)(\d+)t(\.[a-z]+)(\.[a-z]+)?$/i], s: ["$1$2","//i$1$2$3"], example: "http://nhentai.net/g/113475/" }, From f12ebf9f5cde43256dc2d0e143a9924163494777 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 1 Nov 2025 22:17:19 +0900 Subject: [PATCH 0977/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index cbae4e915b1..6b4ffe5ed28 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.10.27.1 +// @version 2025.11.1.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1669339/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1687504/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js // @match *://*/* // @exclude http://www.toodledo.com/tasks/* From 0591ec63869128ac18b59f2bd9322c409a6bf690 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 1 Nov 2025 13:17:31 +0000 Subject: [PATCH 0978/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 1395cd9b877..272140f784a 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.10.27.1 +// @version 2025.11.1.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=23710 -// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1669339 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1687504 // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1653424 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* From 5045d524c40bdc6bcf02056383322285b8abea51 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 3 Nov 2025 21:23:13 +0900 Subject: [PATCH 0979/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 467 ++++++++++++++++++++++ 1 file changed, 467 insertions(+) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index c45395818f7..12f00de2c20 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -421,6 +421,473 @@ switch (lang) { } ]; break; + case "ja": + sitesConfig = [ + { + "description": "検索エンジンの主分類", + "icon": "search", + "sites": [ + { + "keywords": "textarea[name='q']", + "match": "https://www\\.google\\..*/search((?!udm=2).)*$", + "name": "Google", + "url": "https://www.google.co.jp/search?q=%s&ie=utf-8&oe=utf-8" + }, + { + "match": "https://search\\.yahoo\\.co\\.jp/search", + "name": "Yahoo! JAPAN", + "url": "https://search.yahoo.co.jp/search?p=%s" + }, + { + "match": "^https://(www|cn|global)\\.bing\\.com/search", + "name": "Bing", + "url": "https://www.bing.com/search?q=%s" + }, + { + "name": "Goo", + "url": "https://service.smt.docomo.ne.jp/portal/search/web/result.html?q=%s" + }, + { + "match": "https://duckduckgo\\.com", + "name": "DuckDuckGo", + "url": "https://duckduckgo.com/?q=%s" + }, + { + "match": "https://www\\.ecosia\\.org/search", + "name": "Ecosia", + "url": "https://www.ecosia.org/search?q=%s" + }, + { + "match": "https://www\\.perplexity\\.ai/search", + "name": "Perplexity", + "url": "https://www.perplexity.ai/search?q=%s" + }, + { + "icon": "https://www.amazon.co.jp/favicon.ico", + "name": "Amazon.co.jpで検索", + "url": "https://www.amazon.co.jp/s?k=%s" + }, + { + "icon": "https://www.rakuten.co.jp/favicon.ico", + "name": "楽天市場で検索", + "url": "https://search.rakuten.co.jp/search/mall/%s/" + } + ], + "type": "検索" + }, + { + "icon": "sitemap", + "openInNewTab": true, + "selectTxt": true, + "sites": [ + { + "name": "Googleで検索", + "url": "[\"Google\"]" + }, + { + "name": "📄 コピー", + "nobatch": true, + "url": "c:%sr" + }, + { + "name": "📝 貼り付け", + "url": "paste:" + }, + { + "name": "🔆 ページ内検索", + "url": "find:%sr" + }, + { + "name": "Googleサイト内検索", + "url": "https://www.google.co.jp/search?q=%s%20site%3A%h" + }, + { + "name": "AIに質問", + "url": "[\"この内容を解説 (Gemini)\"]" + }, + { + "name": "Yahoo! サイト内検索", + "url": "https://search.yahoo.co.jp/search?p=%s%20site%3A%h" + }, + { + "icon": "https://hoothin.com/qrcode/favicon.svg", + "name": "テキストをQRコードに変換", + "url": "https://hoothin.com/qrcode#%s" + }, + { + "name": "ウィキペディアプレビュー", + "url": "showTips:https://ja.wikipedia.org/wiki/%s\n
      \na>img|src}\"/>\n{.mw-parser-output>p}\n
      " + }, + { + "name": "Metacriticスコア", + "url": "showTips:https://www.metacritic.com/search/%s/\n
      \n\n
      \n

      {.c-pageSiteSearch-results-item>div>p}

      \n
      \n{.u-text-uppercase}\n{.c-pageSiteSearch-results-item strong}\n{.c-siteReviewScore}\n
      \n
      \n
      " + }, + { + "name": "IMDbスコア", + "url": "showTips:https://www.imdb.com/find/?q=%s&exact=true.then{.find-title-result .ipc-metadata-list-summary-item__t}\n

      \n{.hero__primary-text}\n{.ipc-btn__text>div>div>div}\n

      \n
      \n\n
      \n
      {a.ipc-chip|()}
      \n
      Year: {h1+ul>li>.ipc-link}
      \n
      Director: {section>div>div>.title-pc-list>li:nth-child(1) li}
      \n
      Writer: {section>div>div>.title-pc-list>li:nth-child(2) li}
      \n
      Stars: {section>div>div>.title-pc-list>li:nth-child(3) li|()}
      \n
      {section>p>span}
      \n
      \n
      " + }, + { + "name": "すべてのエンジンを展開", + "url": "https://search.hoothin.com/all#%s" + }, + { + "kwFilter": "\\d\\$|\\$\\d", + "name": "💴ドルを円に変換", + "nobatch": true, + "url": "showTips:http://apilayer.net/api/convert?from=USD&to=JPY&amount=1&access_key=%template{apilayer key} \n{name}
      %sr USD = {json.result|*%sr.replace(/\\D/g,'')} JPY" + }, + { + "kwFilter": "^https?:", + "name": "📦 リンクを一括オープン", + "url": "%s[all]" + }, + { + "description": "「example.com」などのテキストリンクをサポート", + "kwFilter": "\\w\\S*\\.\\S*\\w|\\w.*[点。].*\\w", + "name": "🔗 テキストリンクを開く", + "nobatch": true, + "url": "%sr.replace(/(点|。)/g,\".\").replace(/[^\\s\\w\\-_\\.~!\\*';:@&=\\+\\$,\\/\\?#\\[\\]%]/g,\"\").replace(/ /g,\"\").replace(/^/,\"http://\").replace(/^http:\\/\\/(https?:)/,\"$1\")" + }, + { + "icon": "https://ejje.weblio.jp/favicon.ico", + "kwFilter": "^[a-zA-Z\\s]+$", + "name": "Weblio英和・和英辞典", + "url": "showTips:https://ejje.weblio.jp/content/%s\n
      \n{.summaryM.midashigo}
      \n{.summaryM.level_v15}
      \n{.summaryM.wordclass} {.summaryM.Jtnhj}\n
      " + }, + { + "kwFilter": "^[a-zA-Z]+$", + "name": "DeepL英語から日本語", + "url": "https://www.deepl.com/translator#en/ja/%s" + }, + { + "kwFilter": "^https?://.", + "name": "↩️ 短縮URLを復元", + "url": "showTips:%s\n{url}" + }, + { + "kwFilter": "^\\s*[0-9a-zA-z\\+\\/\\=]{4,}\\s*$", + "name": "🔓 base64デコード", + "url": "showTips:\n📋 %bd" + }, + { + "name": "🔒 base64エンコード", + "url": "paste:%be" + }, + { + "name": "📎 選択テキストを一括置換", + "url": "paste:%sr.replace(/%input{マッチング正規表現を入力}/g,\"%input{置換文字列を入力}\")" + }, + { + "kwFilter": "^http.*\\.(3gpp|m4v|mkv|mp4|ogv|webm)\\b", + "name": "📺 ビデオプレビュー", + "url": "showTips:\n" + }, + { + "kwFilter": "^http.*\\.(flac|m4a|mp3|oga|ogg|opus|wav)\\b", + "name": "🎵 オーディオプレビュー", + "url": "showTips:\n" + }, + { + "kwFilter": "^http.*\\.(avif|bmp|gif|gifv|ico|jfif|jpe|jpeg|jpg|png|svg|webp|xbm)\\b", + "name": "🏞️ 画像プレビュー", + "url": "showTips:\n" + } + ], + "type": "選択テキスト検索" + }, + { + "icon": "eye", + "openInNewTab": true, + "selectImg": true, + "sites": [ + { + "name": "Google画像検索", + "url": "https://www.google.com/searchbyimage?sbisrc=cr_1_0_0&image_url=%T" + }, + { + "name": "Google Lens", + "url": "https://www.google.com/imghp#p{sleep(500)&click([data-propagated-experiment-ids])&[name\\=\"encoded_image\"]=%i}" + }, + { + "icon": "https://hoothin.com/qrcode/favicon.svg", + "name": "QRコードデコード", + "url": "https://hoothin.com/qrdecode#p{#fileInput=%i}" + }, + { + "name": "Google翻訳画像", + "url": "https://translate.google.com/?op=images#p{input[accept^\\=\"image\"]=%i}" + }, + { + "name": "一键抠图", + "url": "https://www.remove.bg/ja/upload#p{wait()&body=%i}" + }, + { + "icon": "https://trace.moe/favicon.png", + "name": "アニメシーン検索", + "url": "https://trace.moe/?url=%T" + }, + { + "description": "Lunapicで画像を編集", + "name": "Lunapic", + "nobatch": true, + "url": "https://www.lunapic.com/editor/index.php?action=url&url=%t" + }, + { + "name": "Bing画像検索", + "url": "https://www.bing.com/images/search?view=detailv2&iss=sbi&form=SBIVSP&sbisrc=UrlPaste&q=imgurl:%T" + }, + { + "name": "TinEye", + "url": "https://www.tineye.com/search?url=%T" + }, + { + "name": "QRコード生成", + "url": "[\"QRコード生成\"]" + } + ], + "type": "画像検索" + }, + { + "icon": "list", + "openInNewTab": true, + "selectLink": true, + "selectPage": true, + "sites": [ + { + "icon": "data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik05NjAgOTYwSDY0di02NGg4OTZ2NjR6IG0tNzMuNi02ODYuNGwtODQgODQtNDUuNiA0NS42TDM4NCA3NzZsLTE5MiA1NiA1Ni0xOTIgNTAyLjQtNTAyLjRjNC00IDkuNi02LjQgMTQuNC02LjQgNCAwIDggMS42IDEwLjQgNEw4ODggMjQ4YzcuMiA3LjIgNS42IDE3LjYtMS42IDI1LjZ6TTcxMiAzNTcuNkw2NjYuNCAzMTIgMzA0LjggNjczLjZsLTE4LjQgNjQgNjQtMTguNEw3MTIgMzU3LjZ6IG05Ny42LTk3LjZsLTQ1LjYtNDUuNi01MiA1MiA0NS42IDQ1LjYgNTItNTJ6Ij48L3BhdGg+PC9zdmc+", + "name": "現在のページを編集", + "nobatch": true, + "url": "javascript:(function(){document.body.setAttribute('contenteditable', 'true');alert('ウェブページ編集を有効にしました。ESCキーでキャンセル');document.onkeydown = function (e) {e = e || window.event;if(e.keyCode==27){document.body.setAttribute('contenteditable', 'false');}}})();" + }, + { + "description": "ウェブページの右クリックおよびコピー制限を解除", + "icon": "data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik04MDAgNDQ4SDcwNFYzMjBjMC0xMDYuNC04NS42LTE5Mi0xOTItMTkyUzMyMCAyMTMuNiAzMjAgMzIwaDY0YzAtNzAuNCA1Ny42LTEyOCAxMjgtMTI4czEyOCA1Ny42IDEyOCAxMjh2MTI4SDIyNGMtMTcuNiAwLTMyIDE0LjQtMzIgMzJ2Mzg0YzAgMTcuNiAxNC40IDMyIDMyIDMyaDU3NmMxNy42IDAgMzItMTQuNCAzMi0zMlY0ODBjMC0xNy42LTE0LjQtMzItMzItMzJ6TTUxMiA3MzZgLTM1LjIgMC02NC0yOC44LTY0LTY0czI4LjgtNjQgNjQtNjQgNjQgMjguOCA2NCA2NC0yOC44IDY0LTY0IDY0eiI+PC9wYXRoPjwvc3ZnPg==", + "name": "制限解除", + "nobatch": true, + "url": "javascript:var d=document,b=d.body;with(b.onselectstart=b.oncopy=b.onpaste=b.onkeydown=b.oncontextmenu=b.onmousemove=b.ondragstart=d.oncopy=d.onpaste=null,d.onselectstart=d.oncontextmenu=d.onmousedown=d.onkeydown=function(){return!0},d.wrappedJSObject||d)onmouseup=null,onmousedown=null,oncontextmenu=null;for(var a=d.getElementsByTagName(\"*\"),i=a.length-1;i>=0;i--){var o=a[i];with(o.wrappedJSObject||o)onmouseup=null,onmousedown=null}var h=d.getElementsByTagName(\"head\")[0];if(h){var s=d.createElement(\"style\");s.innerHTML=\"html,*{user-select:text!important;-moz-user-select:text!important;-webkit-user-select:text!important;-webkit-user-drag:text!important;-khtml-user-select:text!important;-khtml-user-drag:text!important;pointer-events:auto!important;}\",h.appendChild(s)}Event.prototype.preventDefault=function(){};" + }, + { + "description": "拡張機能“Ignore X-Frame headers”と併用する必要があります", + "name": "🔗 リンクプレビュー", + "url": "showTips:\n\n" + }, + { + "description": "ctrl バックグラウンドタブ alt 小窓 ctrl+shift シークレットウィンドウ", + "icon": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiPjxwYXRoIGQ9Ik03MjIuOCA0NTlsLTE4LjkgMTguOS0yLjcgMi43LTQuNyA0LjgtNTIuNyA1Mi43IDI2LjMgMjYuMyA1Mi43LTUyLjcgMTg0LjQgMTg0LjQtMjEwLjcgMjEwLjgtMTg0LjQtMTg0LjQgNTIuNi01Mi43LTI2LjMtMjYuNC01Mi43IDUyLjctMjYuMyAyNi40IDIzNy4xIDIzNy4xIDI2My40LTI2My41eiIgZmlsbD0iIzA2MDAwMSIvPjxwYXRoIGQ9Ik0zMjcuNyAzNTMuNmwzNDIuNSAzNDIuNSAyNi4zLTI2LjNMMzU0IDMyNy4zeiIgZmlsbD0iIzA2MDAwMSIvPjxwYXRoIGQ9Ik0zMDEuMyA1MTEuN0wxMTYuOSAzMjcuM2wyMTAuOC0yMTAuN0w1MTIuMSAzMDFsLTUyLjcgNTIuNiAyNi4zIDI2LjQgNTIuNy01Mi43IDI2LjMtMjYuNC0yMzctMjM3TDY0LjIgMzI3LjNsMjM3LjEgMjM3LjEgMjYuMy0yNi4zIDUyLjgtNTIuN0wzNTQgNDU5eiIgZmlsbD0iIzA2MDAwMSIvPjwvc3ZnPg==", + "name": "リンクを開く", + "openInNewTab": true, + "url": "%t" + }, + { + "icon": "https://hoothin.com/qrcode/favicon.svg", + "name": "QRコード生成", + "url": "https://hoothin.com/qrcode#%U" + }, + { + "icon": "https://web.archive.org/_static/images/archive.ico", + "name": "現在のページをアーカイブ", + "nobatch": true, + "url": "https://web.archive.org/save/%u" + }, + { + "name": "万能コマンド", + "nobatch": true, + "url": "https://wn.run/%u" + }, + { + "icon": "https://is.gd/isgd_favicon.ico", + "name": "is.gd", + "url": "https://is.gd/create.php%p{url=%u&opt=0}" + }, + { + "icon": "https://docrdsfx76ssb.cloudfront.net/static/1678306332/pages/wp-content/uploads/2019/02/favicon.ico", + "name": "URL Shortener", + "url": "https://bitly.com/%p{url=%u}" + }, + { + "description": "クリップボードの内容を行ごとに分割して、現在のフォーカス入力ボックスに順次貼り付け", + "name": "⌨️ 行ごとに入力", + "url": "#p{@=%s[]}" + }, + { + "description": "クリップボード画像を検索", + "name": "Google Lens - クリップボード画像検索", + "url": "[\"Google Lens\"]" + }, + { + "name": "Mainonly by jerrylus", + "url": "javascript:(function(){var e=document.body;let n=document.head.appendChild(document.createElement(\"style\"));n.textContent=\".mainonly { outline: 2px solid red; }\";let t=CSS.supports(\"selector(:has(*))\");function o(n){n instanceof HTMLElement&&(e.classList.remove(\"mainonly\"),(e=n).classList.add(\"mainonly\"))}function i(e){o(e.target)}function l(o){if(o.preventDefault(),t)n.textContent=\":not(:has(.mainonly), .mainonly, .mainonly *) { visibility: hidden; }\";else{n.textContent=\":not(.mainonly *, .mainonly-ancestor) { visibility: hidden; }\";var i=e;do i.classList.add(\"mainonly-ancestor\");while(i=i.parentElement)}r()}function s(o){if(\"Escape\"===o.key){o.preventDefault();var i=window.scrollY||document.documentElement.scrollTop;if(n.remove(),document.removeEventListener(\"keydown\",s),r(),e?.classList.remove(\"mainonly\"),!t)for(let l of document.getElementsByClassName(\"mainonly-ancestor\"))l.classList.remove(\"mainonly-ancestor\");window.scrollTo(0,i)}}function a(n){n.preventDefault(),n.deltaY<0?o(e.parentElement):o(e.firstElementChild)}function r(){document.removeEventListener(\"mouseover\",i),document.removeEventListener(\"click\",l),document.removeEventListener(\"wheel\",a)}document.addEventListener(\"mouseover\",i),document.addEventListener(\"click\",l),document.addEventListener(\"wheel\",a,{passive:!1}),document.addEventListener(\"keydown\",s)}())" + }, + { + "kwFilter": "^http.*\\.(3gpp|m4v|mkv|mp4|ogv|webm)(\\?|#|$)", + "name": "📺 ビデオプレビュー - 現在のページ", + "url": "[\"📺 ビデオプレビュー\"]" + }, + { + "kwFilter": "^http.*\\.(flac|m4a|mp3|oga|ogg|opus|wav)(\\?|#|$)", + "name": "🎵 オーディオプレビュー - 現在のページ", + "url": "[\"🎵 オーディオプレビュー\"]" + }, + { + "kwFilter": "^http.*\\.(avif|bmp|gif|gifv|ico|jfif|jpe|jpeg|jpg|png|svg|webp|xbm)(\\?|#|$)", + "name": "🏞️ 画像プレビュー - 現在のページ", + "url": "[\"🏞️ 画像プレビュー\"]" + } + ], + "type": "現在のページ" + }, + { + "icon": "robot", + "openInNewTab": 1, + "selectTxt": true, + "sites": [ + { + "icon": "https://www.gstatic.com/lamda/images/favicon_v1_150160cddff7f294ce30.svg", + "name": "この内容を解説 (Gemini)", + "url": "https://gemini.google.com/app#p{.ql-editor.textarea=以下の内容を説明してください\n`%s`} " + }, + { + "icon": "https://www.gstatic.com/lamda/images/favicon_v1_150160cddff7f294ce30.svg", + "name": "Gemini", + "url": "https://gemini.google.com/app#p{.ql-editor.textarea=%s}" + }, + { + "name": "Poe - AIチャット", + "url": "https://poe.com/#p{sleep(2000)&[class*\\=ChatMessageInputContainer]>textarea=%s&click([data-button-send])}" + }, + { + "name": "ChatGPT", + "url": "https://chat.openai.com/#p{#prompt-textarea=%s&click(#prompt-textarea+button)}" + }, + { + "name": "Futurepedia - AIツールを検索", + "url": "https://www.futurepedia.io/search?search=%s" + } + ], + "type": "AI" + }, + { + "type": "Assit", + "icon": "list-alt", + "selectTxt": true, + "selectImg": true, + "selectAudio": true, + "selectVideo": true, + "selectLink": true, + "selectPage": true, + "openInNewTab": true, + "sites": [ + { + "name": "Twitterで共有", + "url": "https://twitter.com/intent/tweet?url=%T" + }, + { + "icon": "data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTE3LjQ5NCAyMS40ODhjLTIuMTQgMC00LjEzOS0uNzYtNS44MDgtMi4xM0w0LjM5MiAxOS4zOXYtMi41ODNjLS41NzktMS40NDgtLjkxMi0zLjA0OC0uOTEyLTQuNzY0IDAtNS4xNiA0Ljc4OC05LjM0OCA5LjAxMi05LjM0OCA0LjIyNCAwIDkuMDEyIDQuMTg4IDkuMDEyIDkuMzQ4IDAgNS4xNi00Ljc4OCA5LjM0OC05LjAxMiA5LjM0OHptLjAwOC0xNy4zMDVjLTMuNTUyIDAtNi40MyA3LjU4My02LjQzIDcuNTgzczIuODc4IDcuNTgzIDYuNDMgNy41ODNjMy41NTIgMCA2LjQzLTcuNTgzIDYuNDMtNy41ODNzLTIuODc4LTcuNTgzLTYuNDMtNy41ODN6bS0uNjYgMTAuMTE0Yy0uMzk2IDAtLjcxNC0uMzE4LS43MTQtLjcxNHMuMzE4LS43MTQuNzE0LS43MTRjLjM5NiAwIC43MTQuMzE4LjcxNC43MTRzLS4zMTguNzE0LS43MTQuNzE0em0yLjY0IDBjLS4zOTYgMC0uNzE0LS4zMTgtLjcxNC0uNzE0cy4zMTgtLjcxNC43MTQtLjcxNGMuMzk2IDAgLjcxNC4zMTguNzE0LjcxNHMtLjMxOC43MTQtLjcxNC43MTR6bS01LjI4IDBjLS4zOTYgMC0uNzE0LS4zMTgtLjcxNC0uNzE0cy4zMTgtLjcxNC43MTQtLjcxNGMuMzk2IDAgLjcxNC4zMTguNzE0LjcxNHMtLjMxOC43MTQtLjcxNC43MTR6IiBmaWxsPSIjMDZDMzAwIj48L3BhdGg+PC9zdmc+", + "name": "LINEで共有", + "nobatch": true, + "url": "https://line.me/R/share?text=%n%20%u" + }, + { + "name": "Send by Gmail", + "url": "https://mail.google.com/mail/u/0/?tf=cm&source=mailto&body=%n %T" + }, + { + "name": "Share to Facebook", + "url": "https://www.facebook.com/sharer/sharer.php?u=%T&t=%n" + }, + { + "name": "🧮 Calculator", + "url": "calculator://" + }, + { + "name": "🔎 Everything", + "url": "ES://%s" + }, + { + "name": "🦊 Firefox", + "url": "FirefoxURL-308046B0AF4A39CB://%u" + }, + { + "name": "⏰ Clock", + "url": "ms-clock://" + }, + { + "name": "✂️ Screenclip", + "url": "ms-screenclip://" + }, + { + "name": "☑️ ToDo", + "url": "ms-todo://", + "description": "Microsoft To-Do" + }, + { + "name": "📓 Onenote", + "url": "onenote://" + }, + { + "name": "⌨️ VSCode", + "url": "vscode://%u" + }, + { + "name": "Open the link inside words", + "url": "%sr.replace(/[^\\w\\-_\\.~!\\*'\\(\\);:@&=\\+\\$,\\/\\?#\\[\\]%]/g,\"\")" + }, + { + "name": "リンクをMarkdownでコピー", + "url": "c:[%sr](%t)" + }, + { + "name": "📱 Send to phone", + "url": "https://s.hoothin.com/#p{wait(x-peer)&rclick(x-peer)&#textInput=%s&click(#textInput+div>button)}", + "icon": "https://s.hoothin.com/images/favicon-96x96.png" + }, + { + "name": "Bing Search in site", + "url": "https://www.bing.com/search?q=%s%20site%3A%h" + }, + { + "name": "Duckduckgo Search in site", + "url": "https://duckduckgo.com/?q=%s%20site%3A%h" + }, + { + "name": "Yahoo Search in site", + "url": "https://search.yahoo.com/search;?p=%s%20site%3A%h" + }, + { + "name": "Yandex Search in site", + "url": "https://yandex.com/search/?text=%s%20site%3A%h" + }, + { + "name": "Startpage Search in site", + "url": "https://www.startpage.com/sp/search?query=%s%20site%3A%h", + "icon": "https://www.startpage.com/sp/cdn/favicons/favicon-16x16--default.png" + }, + { + "name": "Preview wikipedia", + "url": "showTips:https://en.wikipedia.org/wiki/%s\n
      \nimg|src}\"/>\n{.mw-parser-output>p}\n
      " + }, + { + "name": "🛠️ Copy selected(pic&link)", + "url": "c:%element{}" + }, + { + "name": "🛠️ Copy selected(txt(link))", + "url": "c:%element{}.replace(/!\\[.*?\\]\\(.*?\\)/g,\"\").replace(/\\[ *\\]\\(.*?\\)\\s*/g,\"\").replace(/\\[((.|\\n)*?)\\](\\(.*?\\))/g,\"$1$3\")" + }, + { + "name": "🛠️ Copy selected({ txt | link })", + "url": "c:%element{}.replace(/!\\[.*?\\]\\(.*?\\)/g,\"\").replace(/\\[\\s*\\]\\(.*?\\)\\s*/g,\"\").replace(/\\[((.|\\n)*?)\\]\\((.*?)\\)/g,\"{ $1 | $3 }\")" + } + ] + }, + { + "icon": "recycle", + "match": "0", + "sites": [], + "type": "ごみ箱" + } + ] + break; default: sitesConfig = [ { From c34709d6bcac5cdd7e032285a63b982c3696501e Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 9 Nov 2025 18:03:17 +0900 Subject: [PATCH 0980/1065] Optimize switch-chinese --- .../lib/package.json | 48 +- .../lib/readme.md | 926 +++++++++++++++++- .../lib/stcasc.d.ts | 127 +++ .../lib/stcasc.lib.js | 102 +- .../lib/test.js | 114 +++ 5 files changed, 1257 insertions(+), 60 deletions(-) create mode 100644 Switch Traditional Chinese and Simplified Chinese/lib/stcasc.d.ts create mode 100644 Switch Traditional Chinese and Simplified Chinese/lib/test.js diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/package.json b/Switch Traditional Chinese and Simplified Chinese/lib/package.json index 2b4c2b72a33..6b5b53c909e 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/package.json +++ b/Switch Traditional Chinese and Simplified Chinese/lib/package.json @@ -1,14 +1,41 @@ { "name": "switch-chinese", - "version": "1.0.6", - "description": "Convert between simplified and traditional Chinese characters. 切換正體/簡體中文,超輕量級,支援自訂詞彙與「一簡多繁」轉換,無任何相依性。", + "version": "1.0.7", + "description": "Lightweight Chinese converter library for bidirectional conversion between Simplified and Traditional Chinese with intelligent word segmentation, custom dictionary support, character detection, and multiple output formats. Zero dependencies. 轻量级简繁体中文智能转换库,支持简繁双向转换、智能分词、自定义词库、文本检测及多种输出格式,零依赖。", "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", "简繁转换", "簡繁轉換", "简繁切换", @@ -22,15 +49,22 @@ "簡體中文", "繁體中文", "正體中文", - "Switch", - "Traditional", - "Chinese", - "Simplified" + "中文转换", + "中文检测", + "一简多繁", + "智能分词", + "自定义词库", + "零依赖", + "轻量级" ], "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" + "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 index cfe0e6f52e7..5e61732887f 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md +++ b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md @@ -1,73 +1,915 @@ -簡繁自由切換 -=== -> 切換正體/簡體中文,超輕量級,支援自訂詞彙與「一簡多繁」轉換,無任何相依性 +# switch-chinese + +[简体中文](#简体中文) | [繁體中文](#繁體中文) | [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) -Install +### 特性 + +- **轻量级**:零依赖,体积小,性能优异 +- **智能转换**:支持基于词组的智能分词和「一简多繁」精准转换 +- **自定义词库**:允许用户自定义简繁转换词汇 +- **缓存机制**:支持字典缓存,避免重复初始化 +- **简繁检测**:自动检测文本是简体中文、繁体中文还是未知类型 +- **术语转换**:内置大陆简体与台湾正体的常用术语转换 +- **无依赖**:纯 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'; + +// 第一次调用,生成字典 +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(text, options?)`: 将简体中文转换为繁体中文 +- `simplized(text, options?)`: 将繁体中文转换为简体中文 +- `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) + +### 关键词 + +简繁转换, 繁简转换, 简体中文, 繁体中文, 正体中文, 中文转换, 一简多繁, 简繁切换, 繁简切换, 中文检测, 智能分词, 自定义词库, 零依赖, 轻量级 + --- -``` shell + +## 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 +- **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 + +### 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(text, options?)`: Convert Simplified Chinese to Traditional Chinese +- `simplized(text, options?)`: Convert Traditional Chinese to Simplified Chinese +- `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 + --- -+ 基礎用法 -``` js -const stcasc = Stcasc(); -const sc = "简繁转换 繁简切换 香烟 香烟袅袅 烟雾里 里长面子 吃干面 干 把考卷发回来 卷发 知识产权"; -const tc = stcasc.traditionalized(sc); +## 繁體中文 + +簡繁體中文智能轉換庫 - 支援簡體中文與正體中文雙向轉換,基於詞組的智能分詞處理「一簡多繁」問題 + +[![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'; + +// 第一次呼叫,生成字典 +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('简体中文'); ``` +#### 自訂簡繁轉換詞庫 + +可以根據業務需求自訂簡繁轉換規則: -+ Import +```javascript +import stcasc from 'switch-chinese'; -``` shell -import Stcasc from 'switch-chinese'; +const customDict = { + '身份': '身分', + '转义': '跳脫', + '转换': '轉檔', + '软件': '軟體', + '硬件': '硬體', + '网络': '網路', + '服务器': '伺服器' +}; + +const { traditionalized, simplized } = stcasc({}, customDict); + +console.log(traditionalized('软件转换')); +// 輸出: 軟體轉檔(使用自訂詞庫) ``` -+ 轉正體中文 +#### 停用術語轉換 + +預設情況下,函式庫會轉換一些特定術語(如「知识产权」→「智慧財產權」)。如需停用此功能: + +```javascript +import stcasc from 'switch-chinese'; -``` js -stcasc.traditionalized("简体中文"); -//簡體中文 +// 第三個參數設定為 true 以停用術語轉換 +const { traditionalized } = stcasc({}, {}, true); + +console.log(traditionalized('知识产权')); +// 輸出: 知識産權(僅做字元轉換,不轉換術語) ``` -+ 轉簡體中文 +#### 輸出格式選項 + +函式庫支援多種輸出格式: + +```javascript +import stcasc, { OutputFormat } from 'switch-chinese'; + +const { traditionalized } = stcasc(); + +// 普通格式(預設) +const normal = traditionalized('简体中文'); +// 輸出: 簡體中文 -``` js -stcasc.simplized("繁體中文"); -//繁体中文 +// 括號格式:同時顯示原文和轉換後的文字 +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?) + +主函式,用於建立轉換器實例。 + +**參數:** -``` js -let cache = loadCacheAtYourWay(); -let stcasc = Stcasc(cache); -saveCacheAtYourWay(stcasc.cache); +- `cache` (Object, 可選): 快取物件,用於避免重複生成字典 +- `custom` (Object, 可選): 自訂簡繁轉換詞庫 +- `disableTerms` (Boolean, 可選): 是否停用術語轉換,預設 `false` + +**回傳值:** + +回傳包含以下方法的物件: + +- `traditionalized(text, options?)`: 將簡體中文轉換為繁體中文 +- `simplized(text, options?)`: 將繁體中文轉換為簡體中文 +- `detect(text)`: 檢測文字的中文類型,回傳 ChineseType 列舉值 +- `cache`: 字典快取物件 + +**Options 參數:** + +- `format` (Number, 可選): 輸出格式,使用 `OutputFormat` 常數 + +#### ChineseType + +匯出的常數物件,用於表示中文類型檢測結果: + +```javascript +export const ChineseType = { + SIMPLIFIED: 0, // 簡體中文 + TRADITIONAL: 1, // 繁體中文 + UNKNOWN: 2 // 未知類型 +}; ``` -+ 自訂簡繁切換 +#### OutputFormat + +匯出的常數物件,用於表示輸出格式選項: -``` js -const custom = { - "身份": "身分", - "转义": "跳脫", - "转换": "轉檔", - "软件": "軟體" +```javascript +export const OutputFormat = { + NORMAL: 0, // 只輸出轉換後的結果 + BRACKET: 1, // 輸出「轉換(原文)」格式 + RUBY: 2 // 輸出 HTML 標籤格式 }; -const stcasc = Stcasc(cache, custom); ``` -+ 禁用用語轉換 +### 轉換範例 + +#### 智能詞組轉換 + +本函式庫支援基於上下文的智能詞組轉換,能夠正確處理「一簡多繁」的情況: + +```javascript +const { traditionalized } = stcasc(); + +// 智能識別詞組邊界 +console.log(traditionalized('香烟袅袅')); +// 輸出: 香煙裊裊 + +console.log(traditionalized('里长面子')); +// 輸出: 里長面子(「里長」是職務名稱) + +console.log(traditionalized('吃干面')); +// 輸出: 吃乾麵(「乾麵」是食物) + +console.log(traditionalized('把考卷发回来')); +// 輸出: 把考卷發回來(「發」是動詞) + +console.log(traditionalized('卷发')); +// 輸出: 捲髮(「捲髮」是髮型) +``` + +#### 術語轉換 -``` js -const stcasc = Stcasc({}, {}, true); -const sc = "知识产权"; -console.log(stcasc.traditionalized(sc)); -//知識産權 +內建常用的大陸簡體與台灣正體術語轉換: + +```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..a1826ffbc2b --- /dev/null +++ b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.d.ts @@ -0,0 +1,127 @@ +/** + * 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; +} + +/** + * 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 - Text to convert + * @param options - Conversion options + * @returns Converted simplified Chinese text + */ + simplized(text: string, options?: ConversionOptions): string; + + /** + * Convert simplified Chinese to traditional Chinese + * @param text - Text to convert + * @param options - Conversion options + * @returns Converted traditional Chinese text + */ + traditionalized(text: string, options?: ConversionOptions): string; + + /** + * 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 index 5ec6942ab14..fd68babb100 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js +++ b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js @@ -1,4 +1,16 @@ '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 = { @@ -610,12 +622,15 @@ let sc2tcComb = { var stDict = {}, tsDict = {}; var sc2tcCombTree = {}, tc2scCombTree = {}; -function traditionalized(orgStr) { +function traditionalized(orgStr, options) { + options = options || {}; + const format = options.format !== undefined ? options.format : OutputFormat.NORMAL; + 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; + let search = sc2tcCombTree[char], searchIndex = i, hasMatch = false, startIndex = i; while (search && searchIndex < orgStr.length) { let downTree = null; if (searchIndex < orgStr.length - 1) { @@ -625,7 +640,19 @@ function traditionalized(orgStr) { if (search.end) { hasMatch = true; i = searchIndex; - str += search.end; + 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; } @@ -675,7 +702,13 @@ function traditionalized(orgStr) { } else { newChar = tChar; } - str += newChar; + 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; @@ -683,12 +716,15 @@ function traditionalized(orgStr) { return str; } -function simplized(orgStr) { +function simplized(orgStr, options) { + options = options || {}; + const format = options.format !== undefined ? options.format : OutputFormat.NORMAL; + 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; + let search = tc2scCombTree[char], searchIndex = i, hasMatch = false, startIndex = i; while (search && searchIndex < orgStr.length) { let downTree = null; if (searchIndex < orgStr.length - 1) { @@ -698,7 +734,19 @@ function simplized(orgStr) { if (search.end) { hasMatch = true; i = searchIndex; - str += search.end; + 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; } @@ -748,7 +796,13 @@ function simplized(orgStr) { } else { newChar = sChar; } - str += newChar; + 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; @@ -756,7 +810,33 @@ function simplized(orgStr) { return str; } -function Stcasc(cache, custom, disableTerms) { +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; @@ -834,7 +914,7 @@ function Stcasc(cache, custom, disableTerms) { cache.stDict = stDict; cache.tsDict = tsDict; } - return {simplized, traditionalized, cache}; + return {simplized, traditionalized, detect, cache}; } -export default Stcasc; \ No newline at end of file +export default stcasc; \ No newline at end of file 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..e62bdfd428d --- /dev/null +++ b/Switch Traditional Chinese and Simplified Chinese/lib/test.js @@ -0,0 +1,114 @@ +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(''); + +console.log('========== 测试完成 =========='); From 565a2a83711a316a9a44ca0f5718ad9a3760b582 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sun, 9 Nov 2025 21:41:22 +0900 Subject: [PATCH 0981/1065] Update README.md --- .../README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Switch Traditional Chinese and Simplified Chinese/README.md b/Switch Traditional Chinese and Simplified Chinese/README.md index 5b4a8effcb0..1466c414d28 100644 --- a/Switch Traditional Chinese and Simplified Chinese/README.md +++ b/Switch Traditional Chinese and Simplified Chinese/README.md @@ -34,6 +34,22 @@
      '鼠标':'滑鼠'
       
      +漢語拼音標注 +--- + +目前有個問題,除了配對到詞組的多音字之外,多音單字還需要一個預設拼音。 + +例如“了”應該預設是“le”而不是“liao”。 + +我改了一些,常用的幾個多音單字都改了。但我數了一下,這類多音單字總共有800多個,需要有人來幫忙整理一下。 + +如果有對幫忙有興趣的朋友,以下是整理步驟: + ++ 下載dict.txt ++ 正規搜尋`^(\S \S) \[.*\n(\1.*\n)+` ++ 刪除多餘的行,只保留一個預設讀音 ++ 將修改後的字典提交給我,也可以直接執行專案中的 run.py 來轉換檔案後查看效果 + npm 前端庫 --- From da468b4632cbe676bfaf206536855cba93ac740b Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 10 Nov 2025 20:42:22 +0900 Subject: [PATCH 0982/1065] update --- .../lib/package.json | 4 +- .../lib/stcasc.lib.js | 152 +++++++++--------- X-Downloader/X-Downloader.user.js | 14 +- 3 files changed, 89 insertions(+), 81 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/package.json b/Switch Traditional Chinese and Simplified Chinese/lib/package.json index 6b5b53c909e..623ba02340f 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/package.json +++ b/Switch Traditional Chinese and Simplified Chinese/lib/package.json @@ -1,7 +1,7 @@ { "name": "switch-chinese", - "version": "1.0.7", - "description": "Lightweight Chinese converter library for bidirectional conversion between Simplified and Traditional Chinese with intelligent word segmentation, custom dictionary support, character detection, and multiple output formats. Zero dependencies. 轻量级简繁体中文智能转换库,支持简繁双向转换、智能分词、自定义词库、文本检测及多种输出格式,零依赖。", + "version": "1.0.10", + "description": "簡繁轉換,支援簡繁雙向轉換、智慧分詞、自訂詞庫、文字偵測及多種輸出格式,零依賴。 Lightweight Chinese converter library for conversion between Simplified and Traditional Chinese. 轻量级简繁体中文智能转换库,支持简繁双向转换、智能分词、自定义词库、文本检测及多种输出格式,零依赖。", "main": "stcasc.lib.js", "types": "stcasc.d.ts", "type": "module", diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js index fd68babb100..f45a1c0867e 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js +++ b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js @@ -837,84 +837,90 @@ function detect(text) { } function stcasc(cache, custom, disableTerms) { - if (!cache) cache = {}; - if (cache.sc2tcCombTree && cache.tc2scCombTree) { - sc2tcCombTree = cache.sc2tcCombTree; + if (!cache) cache = {}; + if (cache.sc2tcCombTree && cache.tc2scCombTree) { + sc2tcCombTree = cache.sc2tcCombTree; tc2scCombTree = cache.tc2scCombTree; - } else { + } 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 newTree = {}; - if (i == key.length - 1) { - newTree = {"end": value}; - } - let curKey = key.charAt(i); - let branch = curTree[curKey]; - if (!branch) { - curTree[curKey] = newTree; - curTree = newTree; - } else { - curTree = branch; - } - } - curTree = tc2scCombTree; - for (let i = 0; i < value.length; i++) { - let newTree = {}; - if (i == value.length - 1) { - newTree = {"end": key}; - } - let curKey = value.charAt(i); - let branch = curTree[curKey]; - if (!branch) { - curTree[curKey] = newTree; - curTree = newTree; - } else { - curTree = branch; - } - } - } - 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; + 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 = value; + } + } + 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; + } + 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; + } 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}; + } + return {simplized, traditionalized, detect, cache}; } export default stcasc; \ No newline at end of file diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js index c488f1f1ef4..72531dfbd90 100644 --- a/X-Downloader/X-Downloader.user.js +++ b/X-Downloader/X-Downloader.user.js @@ -15,19 +15,20 @@ // @match https://twitter.com/* // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== // @grant none -// @downloadURL https://update.greasyfork.org/scripts/545186/X-Downloader.user.js -// @updateURL https://update.greasyfork.org/scripts/545186/X-Downloader.meta.js +// @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; + 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; @@ -59,7 +60,8 @@ imgname = `${user.innerText} ${time.innerText.replace(/(.*) · (.*)/, "$2 $1")}.${ext}`; } downloadBtn.href = newsrc; - if (e.altKey || touch) { + if ((e.button === 0 && !e.ctrlKey) || touch) { + simpleClick = true; downloadByFetch(newsrc, imgname); } } else { @@ -72,7 +74,7 @@ if (parent) { downloadBtn.removeAttribute('download'); let link = parent.querySelector('a[role="link"][aria-label][href^="/"]'); - downloadBtn.href = `https://twitter.hoothin.com/?url=${encodeURIComponent(link ? link.href : document.location.href)}`; + downloadBtn.href = `https://twitter.luopo.org/?url=${encodeURIComponent(link ? link.href : document.location.href)}`; if (e.altKey || touch) { window.open(downloadBtn.href, "_blank"); } @@ -80,7 +82,7 @@ } }); downloadBtn.addEventListener("click", e => { - if (e.altKey || touch) { + if (simpleClick || e.altKey || touch) { e.preventDefault(); e.stopPropagation(); } From 56d3efea043510a3372a60bdc3f85fc353cf072b Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 10 Nov 2025 22:03:09 +0900 Subject: [PATCH 0983/1065] Update DownloadAllContent.user.js --- DownloadAllContent/DownloadAllContent.user.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index e33a2ae3275..4df64b84efc 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -931,7 +931,7 @@ if (window.top != window.self) { height: 30px;line-height: 30px;display:block;color:#FFF;text-align:center;font-size: 12px;font-weight: bold;font-family: arial;background: initial; float: initial; } #txtDownQuit+div{ - position:absolute;right:0px;bottom:2px;cursor: pointer;max-width:85px; + position:absolute;right:0px;bottom:2px;cursor: pointer;display: flex; } #txtDownQuit+div>button{ background: #008aff;border: 0;padding: 5px;border-radius: 6px;color: white;float: right;margin: 1px;height: 25px;line-height: 16px;cursor: pointer;overflow: hidden; @@ -1071,7 +1071,7 @@ if (window.top != window.self) { console.warn(e); } } - function packLink(doc, item, curIndex) { + function packLink(doc, item) { if (customTitle) { try { let title = doc.querySelector(customTitle); @@ -1082,9 +1082,6 @@ if (window.top != window.self) { console.warn(e); } } - if (prefix) { - item.innerText = prefix.replace(/\$i/g, ++curIndex) + item.innerText; - } } function getIframe() { if (iframePool && iframePool.length) return iframePool.shift(); @@ -1424,11 +1421,16 @@ if (window.top != window.self) { } } rCats = rCats.filter(function(e){return e!=null}); + if (prefix) { + for(i=0;i{ - packLink(doc, aTag, i); + packLink(doc, aTag); let isHref = ""; let saveUrl = GM_getValue("saveUrl"); if (saveUrl){ From c9181342c87cc2b5871acb79f135a8c7da7b2600 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 11 Nov 2025 09:57:44 +0900 Subject: [PATCH 0984/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 58cca3fb32b..32c0e0c844c 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -4908,10 +4908,12 @@ getBody(doc).scrollTop = actualTop - 10; doc.documentElement.scrollTop = actualTop - 10; setTimeout(() => { - while (actualTop < maxHeight) { + if (actualTop < maxHeight) { actualTop += 200; getBody(doc).scrollTop = actualTop; doc.documentElement.scrollTop = actualTop; + getBody(doc).scrollTop = maxHeight; + doc.documentElement.scrollTop = maxHeight; } }, 0); return false; @@ -4958,7 +4960,13 @@ runPageBar(pageBar) { if (this.curSiteRule.pageBar && this.curSiteRule.pageBar !== 0) { try { - ((typeof this.curSiteRule.pageBar === 'function') ? this.curSiteRule.pageBar : Function("pageBar",'"use strict";' + this.curSiteRule.pageBar))(pageBar); + if (typeof this.curSiteRule.pageBar === 'function') { + this.curSiteRule.pageBar(pageBar); + } else if (/^pageBar\.className=['"][^'"]*['"];?$/.test(this.curSiteRule.pageBar)) { + pageBar.className = this.curSiteRule.pageBar.match(/^pageBar\.className=['"]([^'"]*)['"];?$/)[1]; + } else { + Function("pageBar",'"use strict";' + this.curSiteRule.pageBar)(pageBar); + } } catch(e) { debug(e); } From 842e9f68e7059f229197740d1314afe5edfdc2d2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 26 Nov 2025 19:00:52 +0900 Subject: [PATCH 0985/1065] update --- .../lib/package.json | 4 +- .../lib/readme.md | 177 +++++++++++++++++- .../lib/stcasc.d.ts | 52 ++++- .../lib/stcasc.lib.js | 70 ++++++- .../lib/test.js | 101 ++++++++++ 5 files changed, 384 insertions(+), 20 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/package.json b/Switch Traditional Chinese and Simplified Chinese/lib/package.json index 623ba02340f..d179f7ced29 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/package.json +++ b/Switch Traditional Chinese and Simplified Chinese/lib/package.json @@ -1,7 +1,7 @@ { "name": "switch-chinese", - "version": "1.0.10", - "description": "簡繁轉換,支援簡繁雙向轉換、智慧分詞、自訂詞庫、文字偵測及多種輸出格式,零依賴。 Lightweight Chinese converter library for conversion between Simplified and Traditional Chinese. 轻量级简繁体中文智能转换库,支持简繁双向转换、智能分词、自定义词库、文本检测及多种输出格式,零依赖。", + "version": "1.0.12", + "description": "繁簡轉換,支援簡繁雙向轉換、智慧分詞、自訂詞庫、文字偵測及多種輸出格式,零依賴。 Lightweight Chinese converter library for conversion between Simplified and Traditional Chinese. 轻量级简繁体中文智能转换库,支持简繁双向转换、智能分词、自定义词库、文本检测及多种输出格式,零依赖。", "main": "stcasc.lib.js", "types": "stcasc.d.ts", "type": "module", diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md index 5e61732887f..895ac2dc06a 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md +++ b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md @@ -14,6 +14,7 @@ - **轻量级**:零依赖,体积小,性能优异 - **智能转换**:支持基于词组的智能分词和「一简多繁」精准转换 +- **多种数据类型**:支持字符串、数组、对象的转换,自动递归处理嵌套结构 - **自定义词库**:允许用户自定义简繁转换词汇 - **缓存机制**:支持字典缓存,避免重复初始化 - **简繁检测**:自动检测文本是简体中文、繁体中文还是未知类型 @@ -82,6 +83,54 @@ ChineseType 枚举值: - `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); +// 所有字符串属性值都会被转换,数字等其他类型保持不变 +``` + ### 高级用法 #### 使用缓存优化性能 @@ -186,8 +235,14 @@ OutputFormat 枚举值: 返回包含以下方法的对象: -- `traditionalized(text, options?)`: 将简体中文转换为繁体中文 -- `simplized(text, options?)`: 将繁体中文转换为简体中文 +- `traditionalized(input, options?)`: 将简体中文转换为繁体中文 + - `input`: 可以是字符串、数组或对象 + - 字符串:直接转换返回新字符串 + - 数组:转换所有字符串元素,其他类型保持不变 + - 对象:递归转换所有字符串属性值,其他类型保持不变 +- `simplized(input, options?)`: 将繁体中文转换为简体中文 + - `input`: 可以是字符串、数组或对象 + - 支持的数据类型同 `traditionalized` - `detect(text)`: 检测文本的中文类型,返回 ChineseType 枚举值 - `cache`: 字典缓存对象 @@ -318,6 +373,7 @@ Lightweight Chinese converter library for bidirectional conversion between Simpl - **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 @@ -386,6 +442,54 @@ ChineseType enumeration values: - `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 @@ -490,8 +594,14 @@ Main function to create a converter instance. An object containing the following methods: -- `traditionalized(text, options?)`: Convert Simplified Chinese to Traditional Chinese -- `simplized(text, options?)`: Convert Traditional Chinese to Simplified Chinese +- `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 @@ -622,6 +732,7 @@ Chinese Converter, Simplified Chinese, Traditional Chinese, Chinese Translation, - **輕量級**:零依賴,體積小,效能優異 - **智能轉換**:支援基於詞組的智能分詞和「一簡多繁」精準轉換 +- **多種資料類型**:支援字串、陣列、物件的轉換,自動遞迴處理巢狀結構 - **自訂詞庫**:允許使用者自訂簡繁轉換詞彙 - **快取機制**:支援字典快取,避免重複初始化 - **簡繁檢測**:自動檢測文字是簡體中文、繁體中文還是未知類型 @@ -690,6 +801,54 @@ ChineseType 列舉值: - `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); +// 所有字串屬性值都會被轉換,數字等其他類型保持不變 +``` + ### 進階用法 #### 使用快取最佳化效能 @@ -794,8 +953,14 @@ OutputFormat 列舉值: 回傳包含以下方法的物件: -- `traditionalized(text, options?)`: 將簡體中文轉換為繁體中文 -- `simplized(text, options?)`: 將繁體中文轉換為簡體中文 +- `traditionalized(input, options?)`: 將簡體中文轉換為繁體中文 + - `input`: 可以是字串、陣列或物件 + - 字串:直接轉換並回傳新字串 + - 陣列:轉換所有字串元素,其他類型保持不變 + - 物件:遞迴轉換所有字串屬性值,其他類型保持不變 +- `simplized(input, options?)`: 將繁體中文轉換為簡體中文 + - `input`: 可以是字串、陣列或物件 + - 支援的資料類型同 `traditionalized` - `detect(text)`: 檢測文字的中文類型,回傳 ChineseType 列舉值 - `cache`: 字典快取物件 diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.d.ts b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.d.ts index a1826ffbc2b..350324519b8 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.d.ts +++ b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.d.ts @@ -33,12 +33,20 @@ export interface ConversionOptions { 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; + sc2tcCombTree?: Record; + tc2scCombTree?: Record; stDict?: Record; tsDict?: Record; } @@ -56,20 +64,52 @@ export type CustomDictionary = Record; export interface StcascConverter { /** * Convert traditional Chinese to simplified Chinese - * @param text - Text to convert + * @param text - String to convert * @param options - Conversion options - * @returns Converted simplified Chinese text + * @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 - Text to convert + * @param text - String to convert * @param options - Conversion options - * @returns Converted traditional Chinese text + * @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 diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js index f45a1c0867e..3124b14018f 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js +++ b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js @@ -622,10 +622,7 @@ let sc2tcComb = { var stDict = {}, tsDict = {}; var sc2tcCombTree = {}, tc2scCombTree = {}; -function traditionalized(orgStr, options) { - options = options || {}; - const format = options.format !== undefined ? options.format : OutputFormat.NORMAL; - +function traditionalizedString(orgStr, format) { if (!orgStr) return ""; var str = '', char; for (var i = 0; i < orgStr.length; i++) { @@ -716,10 +713,39 @@ function traditionalized(orgStr, options) { return str; } -function simplized(orgStr, options) { +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++) { @@ -810,6 +836,38 @@ function simplized(orgStr, options) { 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; @@ -875,7 +933,7 @@ function stcasc(cache, custom, disableTerms) { if (i == value.length - 1) { newTree = {"end": key}; if (branch) { - branch.end = value; + branch.end = key; } } if (branch) { diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/test.js b/Switch Traditional Chinese and Simplified Chinese/lib/test.js index e62bdfd428d..55337889052 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/test.js +++ b/Switch Traditional Chinese and Simplified Chinese/lib/test.js @@ -111,4 +111,105 @@ 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('========== 测试完成 =========='); From 2c467c8f9ebaedeaeb83250f10200535bb6327b9 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 26 Nov 2025 19:09:42 +0900 Subject: [PATCH 0986/1065] Update Switch Traditional Chinese and Simplified Chinese.user.js --- ... Traditional Chinese and Simplified Chinese.user.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js index c4009b12925..9bae3c6027a 100644 --- a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js +++ b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js @@ -6,7 +6,7 @@ // @namespace hoothin // @supportURL https://github.com/hoothin/UserScripts // @homepageURL https://github.com/hoothin/UserScripts -// @version 1.2.7.10 +// @version 1.2.7.11 // @description 任意轉換網頁中的簡體中文與正體中文(默認簡體→正體),顯示漢字對應漢語拼音,自訂任意替換文本 // @description:zh-CN 任意转换网页中的简体中文与繁体中文(默认繁体→简体),显示汉字对应汉语拼音,自定义任意替换文本 // @description:ja ウェブページ上の簡体字中国語と繁体字中国語を自由に変換し、中国語の文字にひらがなを表示し、任意の文字を置き換えることができます。 @@ -1217,14 +1217,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()){ @@ -1916,7 +1916,7 @@ if(i==value.length-1){ newTree={"end":key}; if(branch){ - branch.end=value; + branch.end=key; } } if(branch){ From c6161ea41f6370c12de99304357d6794b046e275 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 28 Nov 2025 09:45:39 +0900 Subject: [PATCH 0987/1065] Update searchJumperDefaultConfig.js --- SearchJumper/searchJumperDefaultConfig.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SearchJumper/searchJumperDefaultConfig.js b/SearchJumper/searchJumperDefaultConfig.js index 12f00de2c20..bb3efb0264d 100644 --- a/SearchJumper/searchJumperDefaultConfig.js +++ b/SearchJumper/searchJumperDefaultConfig.js @@ -1025,7 +1025,7 @@ switch (lang) { }, { "name": "💲USD to RMB", - "url": "showTips:http://apilayer.net/api/convert?from=USD&to=CNY&amount=1&access_key=%template{apilayer key} \n{name}
      %sr USD = {json.result|*%sr.replace(/\\D/,'')} RMB", + "url": "showTips:http://apilayer.net/api/convert?from=USD&to=CNY&amount=1&access_key=%template{apilayer key} \n{name}
      %sr USD = {json.result|*%sr.replace(/\\D/g,'')} RMB", "kwFilter": "\\d\\$|\\$\\d" }, { From 777f3688bb2f9b2a54d29b8605a81d8d261cf2cb Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 1 Dec 2025 22:50:34 +0900 Subject: [PATCH 0988/1065] pixiv --- DownloadAllContent/DownloadAllContent.user.js | 4 ++-- DownloadAllContent/README.md | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js index 4df64b84efc..de600e6dc11 100644 --- a/DownloadAllContent/DownloadAllContent.user.js +++ b/DownloadAllContent/DownloadAllContent.user.js @@ -4,7 +4,7 @@ // @name:zh-TW 怠惰小説下載器 // @name:ja 怠惰小説ダウンローダー // @namespace hoothin -// @version 2.8.3.18 +// @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文檔 @@ -1536,10 +1536,10 @@ if (window.top != window.self) { function getPageContent(doc, cb, url){ if(!doc)return i18n.error; - if(doc.body && !doc.body.children.length)return doc.body.innerText; if(processFunc){ return processFunc(doc, cb, url); } + if(doc.body && !doc.body.children.length)return doc.body.innerText; [].forEach.call(doc.querySelectorAll("span,div,ul"),function(item){ var thisStyle=doc.defaultView?doc.defaultView.getComputedStyle(item):item.style; if(thisStyle && (thisStyle.display=="none" || (item.nodeName=="SPAN" && thisStyle.fontSize=="0px"))){ diff --git a/DownloadAllContent/README.md b/DownloadAllContent/README.md index 46df4e75dbd..f5de4823ebd 100644 --- a/DownloadAllContent/README.md +++ b/DownloadAllContent/README.md @@ -104,6 +104,10 @@ ``` javascript main>section ul>li div>a@@@@@@var noval=JSON.parse(doc.querySelector("#meta-preload-data").content).novel;noval[Object.keys(noval)[0]].content; ``` + 新規則 + ``` javascript +main>section ul>li div>a@@novel/show\.php\?id=@@ajax/novel/@@data.json().body.content; + ``` + [📕紅薯中文網](https://g.hongshu.com/chapterlist/91735.do) > 這個站沒有目錄連結,此時可以遍歷標籤自己創建目錄連結下載 ``` javascript From 111cb84a235554e76a3aa64ed609fec10d332892 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 2 Dec 2025 15:43:55 +0900 Subject: [PATCH 0989/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index 76038f2c4bd..dd8a8f3b675 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1091,7 +1091,7 @@ var siteInfo = [ if (!img) return; newsrc = img.src; } - return newsrc.replace(/\?.*$/i,"").replace(/\/an_webp\/([^\/]+)\/mqdefault_6s\.webp/, "/vi/$1/hqdefault.jpg"); + return newsrc.replace(/\?.*$/i,"").replace(/\/an_webp\/([^\/]+)\/mqdefault_6s\.webp/, "/vi/$1/maxresdefault.jpg").replace(/hq\w+\.jpg/, "maxresdefault.jpg"); }, getImage: function(a, p) { var newsrc=this.src; @@ -1099,7 +1099,7 @@ var siteInfo = [ newsrc = p[2].querySelector("img").src; } if(!newsrc || newsrc.indexOf("i.ytimg.com") == -1) return; - return newsrc.replace(/\?.*$/i,"").replace(/\/an_webp\/([^\/]+)\/mqdefault_6s\.webp/, "/vi/$1/hqdefault.jpg"); + return newsrc.replace(/\?.*$/i,"").replace(/\/an_webp\/([^\/]+)\/mqdefault_6s\.webp/, "/vi/$1/maxresdefault.jpg").replace(/hq\w+\.jpg/, "maxresdefault.jpg"); } }, { From 147fde5fb86d1a0b0e2ba3a0cbe3219fcad6d957 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 2 Dec 2025 15:45:30 +0900 Subject: [PATCH 0990/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 6b4ffe5ed28..5f5d2a9ac56 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.11.1.1 +// @version 2025.12.2.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1687504/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1705900/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js // @match *://*/* // @exclude http://www.toodledo.com/tasks/* @@ -19510,7 +19510,7 @@ ImgOps | https://imgops.com/#b#`; transition: transform .3s ease 0s;\ transform: scale3d(1, 1, 1);\ cursor: zoom-in;\ - min-height: 88px;\ + min-height: 150px;\ border-radius: 20px;\ }\ .pv-gallery-maximize-container>.maximizeChild:hover img {\ @@ -19588,6 +19588,9 @@ ImgOps | https://imgops.com/#b#`; .pv-gallery-maximize-container.checked span>.pv-top-banner{\ opacity: 0.6;\ }\ + .pv-gallery-maximize-container.checked span>img{\ + cursor: pointer;\ + }\ .pv-gallery-maximize-container+p>input{\ width:min-content;\ border: 1px solid transparent;\ From 5d2533285915060a22334a55f0ea7ddd1ffbdb7e Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 2 Dec 2025 06:45:42 +0000 Subject: [PATCH 0991/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 272140f784a..975811cdb79 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.11.1.1 +// @version 2025.12.2.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=23710 -// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1687504 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1705900 // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1653424 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* @@ -19510,7 +19510,7 @@ ImgOps | https://imgops.com/#b#`; transition: transform .3s ease 0s;\ transform: scale3d(1, 1, 1);\ cursor: zoom-in;\ - min-height: 88px;\ + min-height: 150px;\ border-radius: 20px;\ }\ .pv-gallery-maximize-container>.maximizeChild:hover img {\ @@ -19588,6 +19588,9 @@ ImgOps | https://imgops.com/#b#`; .pv-gallery-maximize-container.checked span>.pv-top-banner{\ opacity: 0.6;\ }\ + .pv-gallery-maximize-container.checked span>img{\ + cursor: pointer;\ + }\ .pv-gallery-maximize-container+p>input{\ width:min-content;\ border: 1px solid transparent;\ From 486f78c9b36a954fa01593bd5c2f6d5a238fd586 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 4 Dec 2025 18:44:52 +0900 Subject: [PATCH 0992/1065] Update Switch Traditional Chinese and Simplified Chinese.user.js --- ...aditional Chinese and Simplified Chinese.user.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js index 9bae3c6027a..233c1ebb303 100644 --- a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js +++ b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js @@ -6,7 +6,7 @@ // @namespace hoothin // @supportURL https://github.com/hoothin/UserScripts // @homepageURL https://github.com/hoothin/UserScripts -// @version 1.2.7.11 +// @version 1.2.7.12 // @description 任意轉換網頁中的簡體中文與正體中文(默認簡體→正體),顯示漢字對應漢語拼音,自訂任意替換文本 // @description:zh-CN 任意转换网页中的简体中文与繁体中文(默认繁体→简体),显示汉字对应汉语拼音,自定义任意替换文本 // @description:ja ウェブページ上の簡体字中国語と繁体字中国語を自由に変換し、中国語の文字にひらがなを表示し、任意の文字を置き換えることができます。 @@ -1122,6 +1122,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', From 0143b6cfcf38ef6696887a7f345175139e9c9ee7 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 10 Dec 2025 13:38:45 +0900 Subject: [PATCH 0993/1065] update --- .../Switch Traditional Chinese and Simplified Chinese.user.js | 4 ---- .../lib/stcasc.lib.js | 4 ---- 2 files changed, 8 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js index 233c1ebb303..e2228c3ba3d 100644 --- a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js +++ b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js @@ -152,10 +152,6 @@ '栗', ['慄','战栗','颤栗','不寒而栗'] ], - '凄':[ - '淒', - ['悽','凄厉','凄惨','悲凄','凄苦'] - ], '沈':[ '沈', ['瀋','沈阳'] diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js index 3124b14018f..cfe8e268376 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js +++ b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js @@ -96,10 +96,6 @@ const sc2tc = { '栗', ['慄','战栗','颤栗','不寒而栗'] ], - '凄':[ - '淒', - ['悽','凄厉','凄惨','悲凄','凄苦'] - ], '沈':[ '沈', ['瀋','沈阳'] From d6655998c4c541493251af510fed657d9b1b0b37 Mon Sep 17 00:00:00 2001 From: hoothin Date: Wed, 10 Dec 2025 13:41:31 +0900 Subject: [PATCH 0994/1065] Update package.json --- .../lib/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/package.json b/Switch Traditional Chinese and Simplified Chinese/lib/package.json index d179f7ced29..415ffcc676a 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/package.json +++ b/Switch Traditional Chinese and Simplified Chinese/lib/package.json @@ -1,6 +1,6 @@ { "name": "switch-chinese", - "version": "1.0.12", + "version": "1.0.13", "description": "繁簡轉換,支援簡繁雙向轉換、智慧分詞、自訂詞庫、文字偵測及多種輸出格式,零依賴。 Lightweight Chinese converter library for conversion between Simplified and Traditional Chinese. 轻量级简繁体中文智能转换库,支持简繁双向转换、智能分词、自定义词库、文本检测及多种输出格式,零依赖。", "main": "stcasc.lib.js", "types": "stcasc.d.ts", From c35558f57dac607c5a121301852b2930e77e923c Mon Sep 17 00:00:00 2001 From: Miyuki <50022810+Boxkun@users.noreply.github.com> Date: Mon, 15 Dec 2025 05:26:45 +0800 Subject: [PATCH 0995/1065] Update rule for gelbooru --- Picviewer CE+/pvcep_rules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index b993719ca50..d1a878995eb 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -1133,7 +1133,7 @@ var siteInfo = [ url: /gelbooru\.com/, src: /(thumbnails|samples)\/(.*)\/(thumbnail|sample)_/i, r: /.*\/(thumbnails|samples)\/(.*)\/(thumbnail|sample)_(.*)\..*/i, - s: ["https://img4.gelbooru.com/images/$2/$4.png","https://img4.gelbooru.com/images/$2/$4.jpg","https://img4.gelbooru.com/images/$2/$4.jpeg","https://img4.gelbooru.com/images/$2/$4.gif"] + s: ["https://img2.gelbooru.com/images/$2/$4.png","https://img2.gelbooru.com/images/$2/$4.jpg","https://img2.gelbooru.com/images/$2/$4.jpeg","https://img2.gelbooru.com/images/$2/$4.gif"] }, { name: "donmai", From 0e8b891a327a644d2c7a16dcb3448a5e94118275 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 19 Dec 2025 17:26:13 +0900 Subject: [PATCH 0996/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 5f5d2a9ac56..56f4021ccb6 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.12.2.1 +// @version 2025.12.19.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1705900/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1714183/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js // @match *://*/* // @exclude http://www.toodledo.com/tasks/* @@ -13727,6 +13727,7 @@ ImgOps | https://imgops.com/#b#`; if (!errorBlobList[img.src] && !/^blob:/.test(img.src)) { errorList[img.src]=true; + let orgSrc = img.src; _GM_xmlhttpRequest({ method: 'GET', url: img.src, @@ -13736,7 +13737,6 @@ ImgOps | https://imgops.com/#b#`; const releaseBlob = () => URL.revokeObjectURL(blobUrl); window.addEventListener('beforeunload', releaseBlob); - let orgSrc = img.src; img.src = blobUrl; setTimeout(() => { if (aborted) return; From e66b368c232a9e04f6fac7fb707772ecd04a482a Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Fri, 19 Dec 2025 08:26:27 +0000 Subject: [PATCH 0997/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 975811cdb79..8ae3445d5de 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.12.2.1 +// @version 2025.12.19.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=23710 -// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1705900 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1714183 // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1653424 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* @@ -13727,6 +13727,7 @@ ImgOps | https://imgops.com/#b#`; if (!errorBlobList[img.src] && !/^blob:/.test(img.src)) { errorList[img.src]=true; + let orgSrc = img.src; _GM_xmlhttpRequest({ method: 'GET', url: img.src, @@ -13736,7 +13737,6 @@ ImgOps | https://imgops.com/#b#`; const releaseBlob = () => URL.revokeObjectURL(blobUrl); window.addEventListener('beforeunload', releaseBlob); - let orgSrc = img.src; img.src = blobUrl; setTimeout(() => { if (aborted) return; From c80ed60d65d9bcb743dbf61abeb696a025564146 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 26 Dec 2025 10:20:46 +0900 Subject: [PATCH 0998/1065] Update pagetual.user.js --- Pagetual/pagetual.user.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index 32c0e0c844c..d406513e3b3 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.125 +// @version 1.9.37.126 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -11419,14 +11419,6 @@ let action = e.data.action; let detail = e.data.detail; switch (action) { - case "config": - if (!detail || typeof detail !== 'object') return; - rulesData = { - ...rulesData, - ...detail - } - storage.setItem("rulesData", rulesData); - break; case "nextPage": if (detail === "" || detail === null) return; detail = parseInt(detail) || 0; From bfaf086c77d77203714460445373a8d6b827e460 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 29 Dec 2025 20:52:10 +0900 Subject: [PATCH 0999/1065] sideControllerPos --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 31 ++++++++++++++++++------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index b41b3d04643..c58d65bd3fc 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.125](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.127](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index d406513e3b3..ddc0c1d1acf 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.126 +// @version 1.9.37.127 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -153,7 +153,7 @@ } const noRuleTest = false; - const lang = navigator.appName === "Netscape" ? navigator.language : navigator.userLanguage; + var langName = navigator.appName === "Netscape" ? navigator.language : navigator.userLanguage; const langData = [ { // English translation update by github.com/https433, admin@abby0666.xyz. @@ -4135,6 +4135,7 @@ }); var i18nData = langData[0].lang; function setLang(la) { + langName = la; for (let i = 0; i < langData.length; i++) { let lang = langData[i]; if (lang && lang.match.indexOf(la) !== -1) { @@ -4148,7 +4149,7 @@ } } } - setLang(lang); + setLang(langName); var enableDebug = true; var _GM_xmlhttpRequest, _GM_registerMenuCommand, _GM_notification, _GM_addStyle, _GM_openInTab, _GM_info, _GM_setClipboard; function i18n(name, param) { @@ -4314,7 +4315,8 @@ }); } const isMobile = ('ontouchstart' in document.documentElement && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)); - const configPage = [`https://pagetual.hoothin.com/${lang === 'zh-CN' ? 'cn/' : ''}rule.html`, + const cnConfigPage = "https://pagetual.hoothin.com/cn/rule.html"; + const configPage = ["https://pagetual.hoothin.com/rule.html", "https://github.com/hoothin/UserScripts/tree/master/Pagetual", "https://hoothin.github.io/UserScripts/Pagetual/"]; const firstRunPage = "https://pagetual.hoothin.com/firstRun"; @@ -7969,7 +7971,7 @@ e.stopPropagation(); }, true); - let initX, initY, moving = false; + let initX, initY, perX, perY, moving = false; let removeTimer; move.addEventListener("click", e => { if (!moving) { @@ -8013,10 +8015,10 @@ if (moving) { let windowHeight = window.innerHeight || document.documentElement.clientHeight; let windowWidth = window.innerWidth || document.documentElement.clientWidth; - initX = (clientX(e) - 10 + 40) / windowWidth * 100; - initY = (clientY(e) - 83 + 83) / windowHeight * 100; - this.frame.style.top = `calc(${initY}% - 83px)`; - this.frame.style.left = `calc(${initX}% - 40px)`; + perX = (clientX(e) - 10 + 40) / windowWidth * 100; + perY = (clientY(e) - 83 + 83) / windowHeight * 100; + this.frame.style.top = `calc(${perY}% - 83px)`; + this.frame.style.left = `calc(${perX}% - 40px)`; } else if (Math.abs(clientX(e) - initX) + Math.abs(clientY(e) - initY) > 5) { moving = true; clearTimeout(removeTimer); @@ -8028,8 +8030,8 @@ document.removeEventListener("mouseup", mouseUpHandler, true); document.removeEventListener("touchmove", mouseMoveHandler, true); document.removeEventListener("touchend", mouseUpHandler, true); - if (moving) { - rulesData.sideControllerPos = {x: parseInt(initX), y: parseInt(initY)}; + if (moving && perX && perY && perX > 0 && perX < 100 && perY > 0 && perY < 100) { + rulesData.sideControllerPos = {x: parseInt(perX), y: parseInt(perY)}; storage.setItem("rulesData", rulesData); } }; @@ -9565,9 +9567,9 @@ let rulesExample = document.querySelector("#user-content-rules-example+a,#rules-example>a"); if (rulesExample) { rulesExample.innerText = i18n("rulesExample"); - if (lang == "zh-CN") { + if (langName == "zh-CN") { rulesExample.href = rulesExample.href.replace("en", "cn"); - } else if (lang == "zh-TW" || lang == "zh-HK") { + } else if (langName == "zh-TW" || langName == "zh-HK") { rulesExample.href = rulesExample.href.replace("/en", ""); } } @@ -10463,6 +10465,9 @@ } if (rulesData.lang) { setLang(rulesData.lang); + if (langName === 'zh-CN') { + configPage.unshift(cnConfigPage); + } } if (rulesData.firstRun && storage.supportCrossSave()) { rulesData.firstRun = false; From 0f2a15d7f58ebae861091894d32226f41b7a7127 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 1 Jan 2026 10:36:34 +0900 Subject: [PATCH 1000/1065] =?UTF-8?q?=E5=B9=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Switch Traditional Chinese and Simplified Chinese.user.js | 2 +- .../lib/package.json | 2 +- .../lib/stcasc.lib.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js index e2228c3ba3d..086c092c202 100644 --- a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js +++ b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js @@ -385,7 +385,7 @@ '干':[ '幹', ['乾','口干','吃干','吐干','吮干','吸干','吹干','呷干','喉干','喝干','嘴干','太干','干井','干似','干冰','干冷','干化','干咳','干咽','干品','干哥','干嚎','干土','干坤','干妹','干姊','干姐','干姜','干娘','干爹','干爸','干妈','干季','干巴','干布','干干','干式','干弟','干性','干料','干旱','干杯','干果','干枝','干枯','干柴','干梅','干沙','干泥','干洗','干涸','干渴','干焦','干熬','干燥','干爽','干球','干疤','干瘦','干眼','干瞪','干硬','干窘','干笑','干等','干粉','干耗','干肉','干股','干脆','干花','干草','干菜','干薪','干衣','干裂','干透','干酪','干醋','干隆','干面','弄干','很干','抹干','抽干','揩干','擦干','晾干','朝干','未干','杯干','果干','桑干','榨干','水干','流干','海干','滴干','炒干','烘干','烤干','焙干','焦干','煨干','熨干','略干','碗干','粉干','耗干','肉干','舔干','菜干','蒸干','速干','干儿','干哑','干呕','干坛','干孙','干尸','干搁','干晒','干净','干涩','干涧','干湿','干热','干烧','干瘪','干瘾','干发','干粮','干结','干丝','干声','干叶','干号','干货','干阳','干饭','拧干','晒干','极干','泪干','沥干','烧干','烩干','发干','笋干','绞干','阴干','难干','风干','饮干','饼干','鱼干','唇干'], - ['干','干系','天干','干涉','干扰','干戈','相干'] + ['干','干系','天干','干涉','干扰','干戈','相干','不干','干你什么','干你事','干你的事','干他什么','干他事','干他的事','干她什么','干她事','干她的事'] ], '了':[ '了', diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/package.json b/Switch Traditional Chinese and Simplified Chinese/lib/package.json index 415ffcc676a..94f23191a74 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/package.json +++ b/Switch Traditional Chinese and Simplified Chinese/lib/package.json @@ -1,6 +1,6 @@ { "name": "switch-chinese", - "version": "1.0.13", + "version": "1.0.14", "description": "繁簡轉換,支援簡繁雙向轉換、智慧分詞、自訂詞庫、文字偵測及多種輸出格式,零依賴。 Lightweight Chinese converter library for conversion between Simplified and Traditional Chinese. 轻量级简繁体中文智能转换库,支持简繁双向转换、智能分词、自定义词库、文本检测及多种输出格式,零依赖。", "main": "stcasc.lib.js", "types": "stcasc.d.ts", diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js index cfe8e268376..135cc540db3 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js +++ b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js @@ -329,7 +329,7 @@ const sc2tc = { '干':[ '幹', ['乾','口干','吃干','吐干','吮干','吸干','吹干','呷干','喉干','喝干','嘴干','太干','干井','干似','干冰','干冷','干化','干咳','干咽','干品','干哥','干嚎','干土','干坤','干妹','干姊','干姐','干姜','干娘','干爹','干爸','干妈','干季','干巴','干布','干干','干式','干弟','干性','干料','干旱','干杯','干果','干枝','干枯','干柴','干梅','干沙','干泥','干洗','干涸','干渴','干焦','干熬','干燥','干爽','干球','干疤','干瘦','干眼','干瞪','干硬','干窘','干笑','干等','干粉','干耗','干肉','干股','干脆','干花','干草','干菜','干薪','干衣','干裂','干透','干酪','干醋','干隆','干面','弄干','很干','抹干','抽干','揩干','擦干','晾干','朝干','未干','杯干','果干','桑干','榨干','水干','流干','海干','滴干','炒干','烘干','烤干','焙干','焦干','煨干','熨干','略干','碗干','粉干','耗干','肉干','舔干','菜干','蒸干','速干','干儿','干哑','干呕','干坛','干孙','干尸','干搁','干晒','干净','干涩','干涧','干湿','干热','干烧','干瘪','干瘾','干发','干粮','干结','干丝','干声','干叶','干号','干货','干阳','干饭','拧干','晒干','极干','泪干','沥干','烧干','烩干','发干','笋干','绞干','阴干','难干','风干','饮干','饼干','鱼干','唇干'], - ['干','干系','天干','干涉','干扰','干戈','相干'] + ['干','干系','天干','干涉','干扰','干戈','相干','干你什么','干你事','干你的事','干他什么','干他事','干他的事','干她什么','干她事','干她的事'] ], '了':[ '了', From 9ba001343e1f6bf7e7e28465456225bfdb26001d Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 1 Jan 2026 10:43:23 +0900 Subject: [PATCH 1001/1065] fix --- .../Switch Traditional Chinese and Simplified Chinese.user.js | 2 +- .../lib/package.json | 2 +- Switch Traditional Chinese and Simplified Chinese/lib/readme.md | 2 ++ .../lib/stcasc.lib.js | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js index 086c092c202..6ee429ba0f1 100644 --- a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js +++ b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js @@ -385,7 +385,7 @@ '干':[ '幹', ['乾','口干','吃干','吐干','吮干','吸干','吹干','呷干','喉干','喝干','嘴干','太干','干井','干似','干冰','干冷','干化','干咳','干咽','干品','干哥','干嚎','干土','干坤','干妹','干姊','干姐','干姜','干娘','干爹','干爸','干妈','干季','干巴','干布','干干','干式','干弟','干性','干料','干旱','干杯','干果','干枝','干枯','干柴','干梅','干沙','干泥','干洗','干涸','干渴','干焦','干熬','干燥','干爽','干球','干疤','干瘦','干眼','干瞪','干硬','干窘','干笑','干等','干粉','干耗','干肉','干股','干脆','干花','干草','干菜','干薪','干衣','干裂','干透','干酪','干醋','干隆','干面','弄干','很干','抹干','抽干','揩干','擦干','晾干','朝干','未干','杯干','果干','桑干','榨干','水干','流干','海干','滴干','炒干','烘干','烤干','焙干','焦干','煨干','熨干','略干','碗干','粉干','耗干','肉干','舔干','菜干','蒸干','速干','干儿','干哑','干呕','干坛','干孙','干尸','干搁','干晒','干净','干涩','干涧','干湿','干热','干烧','干瘪','干瘾','干发','干粮','干结','干丝','干声','干叶','干号','干货','干阳','干饭','拧干','晒干','极干','泪干','沥干','烧干','烩干','发干','笋干','绞干','阴干','难干','风干','饮干','饼干','鱼干','唇干'], - ['干','干系','天干','干涉','干扰','干戈','相干','不干','干你什么','干你事','干你的事','干他什么','干他事','干他的事','干她什么','干她事','干她的事'] + ['干','干系','天干','干涉','干扰','干戈','相干','不干','干我什麽','干我事','干我的事','干你什麽','干你事','干你的事','干他什麽','干他事','干他的事','干她什麽','干她事','干她的事'] ], '了':[ '了', diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/package.json b/Switch Traditional Chinese and Simplified Chinese/lib/package.json index 94f23191a74..18fda07895d 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/package.json +++ b/Switch Traditional Chinese and Simplified Chinese/lib/package.json @@ -1,6 +1,6 @@ { "name": "switch-chinese", - "version": "1.0.14", + "version": "1.0.15", "description": "繁簡轉換,支援簡繁雙向轉換、智慧分詞、自訂詞庫、文字偵測及多種輸出格式,零依賴。 Lightweight Chinese converter library for conversion between Simplified and Traditional Chinese. 轻量级简繁体中文智能转换库,支持简繁双向转换、智能分词、自定义词库、文本检测及多种输出格式,零依赖。", "main": "stcasc.lib.js", "types": "stcasc.d.ts", diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md index 895ac2dc06a..39d5ed194ec 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md +++ b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md @@ -1,5 +1,7 @@ # switch-chinese +[Demo](https://tool.hoothin.com/chinese-converter) + [简体中文](#简体中文) | [繁體中文](#繁體中文) | [English](#english) --- diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js index 135cc540db3..fc76ef6c8b1 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js +++ b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js @@ -329,7 +329,7 @@ const sc2tc = { '干':[ '幹', ['乾','口干','吃干','吐干','吮干','吸干','吹干','呷干','喉干','喝干','嘴干','太干','干井','干似','干冰','干冷','干化','干咳','干咽','干品','干哥','干嚎','干土','干坤','干妹','干姊','干姐','干姜','干娘','干爹','干爸','干妈','干季','干巴','干布','干干','干式','干弟','干性','干料','干旱','干杯','干果','干枝','干枯','干柴','干梅','干沙','干泥','干洗','干涸','干渴','干焦','干熬','干燥','干爽','干球','干疤','干瘦','干眼','干瞪','干硬','干窘','干笑','干等','干粉','干耗','干肉','干股','干脆','干花','干草','干菜','干薪','干衣','干裂','干透','干酪','干醋','干隆','干面','弄干','很干','抹干','抽干','揩干','擦干','晾干','朝干','未干','杯干','果干','桑干','榨干','水干','流干','海干','滴干','炒干','烘干','烤干','焙干','焦干','煨干','熨干','略干','碗干','粉干','耗干','肉干','舔干','菜干','蒸干','速干','干儿','干哑','干呕','干坛','干孙','干尸','干搁','干晒','干净','干涩','干涧','干湿','干热','干烧','干瘪','干瘾','干发','干粮','干结','干丝','干声','干叶','干号','干货','干阳','干饭','拧干','晒干','极干','泪干','沥干','烧干','烩干','发干','笋干','绞干','阴干','难干','风干','饮干','饼干','鱼干','唇干'], - ['干','干系','天干','干涉','干扰','干戈','相干','干你什么','干你事','干你的事','干他什么','干他事','干他的事','干她什么','干她事','干她的事'] + ['干','干系','天干','干涉','干扰','干戈','相干','干我什麽','干我事','干我的事','干你什麽','干你事','干你的事','干他什麽','干他事','干他的事','干她什麽','干她事','干她的事'] ], '了':[ '了', From 2b928ed6978db6ccbe3e2707e69da75b5ec66c25 Mon Sep 17 00:00:00 2001 From: hoothin Date: Thu, 1 Jan 2026 12:41:21 +0900 Subject: [PATCH 1002/1065] fix --- ...nal Chinese and Simplified Chinese.user.js | 18 ++++++++++++----- .../lib/package.json | 2 +- .../lib/readme.md | 2 +- .../lib/stcasc.lib.js | 20 +++++++++++++------ 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js index 6ee429ba0f1..38bafb561f1 100644 --- a/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js +++ b/Switch Traditional Chinese and Simplified Chinese/Switch Traditional Chinese and Simplified Chinese.user.js @@ -385,7 +385,7 @@ '干':[ '幹', ['乾','口干','吃干','吐干','吮干','吸干','吹干','呷干','喉干','喝干','嘴干','太干','干井','干似','干冰','干冷','干化','干咳','干咽','干品','干哥','干嚎','干土','干坤','干妹','干姊','干姐','干姜','干娘','干爹','干爸','干妈','干季','干巴','干布','干干','干式','干弟','干性','干料','干旱','干杯','干果','干枝','干枯','干柴','干梅','干沙','干泥','干洗','干涸','干渴','干焦','干熬','干燥','干爽','干球','干疤','干瘦','干眼','干瞪','干硬','干窘','干笑','干等','干粉','干耗','干肉','干股','干脆','干花','干草','干菜','干薪','干衣','干裂','干透','干酪','干醋','干隆','干面','弄干','很干','抹干','抽干','揩干','擦干','晾干','朝干','未干','杯干','果干','桑干','榨干','水干','流干','海干','滴干','炒干','烘干','烤干','焙干','焦干','煨干','熨干','略干','碗干','粉干','耗干','肉干','舔干','菜干','蒸干','速干','干儿','干哑','干呕','干坛','干孙','干尸','干搁','干晒','干净','干涩','干涧','干湿','干热','干烧','干瘪','干瘾','干发','干粮','干结','干丝','干声','干叶','干号','干货','干阳','干饭','拧干','晒干','极干','泪干','沥干','烧干','烩干','发干','笋干','绞干','阴干','难干','风干','饮干','饼干','鱼干','唇干'], - ['干','干系','天干','干涉','干扰','干戈','相干','不干','干我什麽','干我事','干我的事','干你什麽','干你事','干你的事','干他什麽','干他事','干他的事','干她什麽','干她事','干她的事'] + ['干','干系','天干','干涉','干扰','干戈','相干','不干','干我什','干我事','干我的事','干你什','干你事','干你的事','干他什','干他事','干他的事','干她什','干她事','干她的事'] ], '了':[ '了', @@ -867,11 +867,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; @@ -940,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; diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/package.json b/Switch Traditional Chinese and Simplified Chinese/lib/package.json index 18fda07895d..489310114ed 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/package.json +++ b/Switch Traditional Chinese and Simplified Chinese/lib/package.json @@ -1,6 +1,6 @@ { "name": "switch-chinese", - "version": "1.0.15", + "version": "1.0.16", "description": "繁簡轉換,支援簡繁雙向轉換、智慧分詞、自訂詞庫、文字偵測及多種輸出格式,零依賴。 Lightweight Chinese converter library for conversion between Simplified and Traditional Chinese. 轻量级简繁体中文智能转换库,支持简繁双向转换、智能分词、自定义词库、文本检测及多种输出格式,零依赖。", "main": "stcasc.lib.js", "types": "stcasc.d.ts", diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md index 39d5ed194ec..670521a96db 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md +++ b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md @@ -1,6 +1,6 @@ # switch-chinese -[Demo](https://tool.hoothin.com/chinese-converter) +[Online Demo](https://tool.hoothin.com/chinese-converter) [简体中文](#简体中文) | [繁體中文](#繁體中文) | [English](#english) diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js index fc76ef6c8b1..2256dc7222a 100644 --- a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js +++ b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js @@ -329,7 +329,7 @@ const sc2tc = { '干':[ '幹', ['乾','口干','吃干','吐干','吮干','吸干','吹干','呷干','喉干','喝干','嘴干','太干','干井','干似','干冰','干冷','干化','干咳','干咽','干品','干哥','干嚎','干土','干坤','干妹','干姊','干姐','干姜','干娘','干爹','干爸','干妈','干季','干巴','干布','干干','干式','干弟','干性','干料','干旱','干杯','干果','干枝','干枯','干柴','干梅','干沙','干泥','干洗','干涸','干渴','干焦','干熬','干燥','干爽','干球','干疤','干瘦','干眼','干瞪','干硬','干窘','干笑','干等','干粉','干耗','干肉','干股','干脆','干花','干草','干菜','干薪','干衣','干裂','干透','干酪','干醋','干隆','干面','弄干','很干','抹干','抽干','揩干','擦干','晾干','朝干','未干','杯干','果干','桑干','榨干','水干','流干','海干','滴干','炒干','烘干','烤干','焙干','焦干','煨干','熨干','略干','碗干','粉干','耗干','肉干','舔干','菜干','蒸干','速干','干儿','干哑','干呕','干坛','干孙','干尸','干搁','干晒','干净','干涩','干涧','干湿','干热','干烧','干瘪','干瘾','干发','干粮','干结','干丝','干声','干叶','干号','干货','干阳','干饭','拧干','晒干','极干','泪干','沥干','烧干','烩干','发干','笋干','绞干','阴干','难干','风干','饮干','饼干','鱼干','唇干'], - ['干','干系','天干','干涉','干扰','干戈','相干','干我什麽','干我事','干我的事','干你什麽','干你事','干你的事','干他什麽','干他事','干他的事','干她什麽','干她事','干她的事'] + ['干','干系','天干','干涉','干扰','干戈','相干','干我什','干我事','干我的事','干你什','干你事','干你的事','干他什','干他事','干他的事','干她什','干她事','干她的事'] ], '了':[ '了', @@ -677,11 +677,15 @@ function traditionalizedString(orgStr, format) { 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; @@ -800,11 +804,15 @@ function simplizedString(orgStr, format) { 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; @@ -977,4 +985,4 @@ function stcasc(cache, custom, disableTerms) { return {simplized, traditionalized, detect, cache}; } -export default stcasc; \ No newline at end of file +export default stcasc; From 5fb569f412a06949bf31f1fea80ba8f42b920f01 Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 5 Jan 2026 13:22:41 +0900 Subject: [PATCH 1003/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 56f4021ccb6..e1eb2944b58 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -15,7 +15,7 @@ // @version 2025.12.19.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts -// @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B +// @homepage https://pv.hoothin.com/ // @supportURL https://github.com/hoothin/UserScripts/issues // @connect www.google.com // @connect www.google.com.hk @@ -26450,7 +26450,7 @@ ImgOps | https://imgops.com/#b#`; GM_config.init({ id: 'pv-prefs', title: GM_config.create('a', { - href: 'https://hoothin.github.io/UserScripts/Picviewer%20CE%2B', + href: 'https://pv.hoothin.com/', target: '_blank', textContent: 'Picviewer CE+ '+i18n("config"), title: i18n("openHomePage") From ad6e08ca418246df5843a7663c0ae20dc2463f66 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Mon, 5 Jan 2026 04:22:57 +0000 Subject: [PATCH 1004/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 8ae3445d5de..28cb754cfda 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -15,7 +15,7 @@ // @version 2025.12.19.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts -// @homepage https://github.com/hoothin/UserScripts/tree/master/Picviewer%20CE%2B +// @homepage https://pv.hoothin.com/ // @supportURL https://github.com/hoothin/UserScripts/issues // @connect www.google.com // @connect www.google.com.hk @@ -26450,7 +26450,7 @@ ImgOps | https://imgops.com/#b#`; GM_config.init({ id: 'pv-prefs', title: GM_config.create('a', { - href: 'https://hoothin.github.io/UserScripts/Picviewer%20CE%2B', + href: 'https://pv.hoothin.com/', target: '_blank', textContent: 'Picviewer CE+ '+i18n("config"), title: i18n("openHomePage") From 4f7c6820bfa49a75504a2628038d3e27f2369b6a Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 5 Jan 2026 21:42:07 +0900 Subject: [PATCH 1005/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 248 +++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index e1eb2944b58..a72abbdb16c 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2025.12.19.1 +// @version 2026.1.5.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://pv.hoothin.com/ @@ -12055,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"; @@ -13939,6 +14119,7 @@ ImgOps | https://imgops.com/#b#`; ''+ ''+ '0 x 0'+ + ''+ '(1 / 1)'+ '(100%)'+ ''+ @@ -14325,6 +14506,7 @@ ImgOps | https://imgops.com/#b#`; 'head-left-img-info', 'head-left-img-info-description', 'head-left-img-info-resolution', + 'head-left-img-info-size', 'head-left-img-info-count', 'head-left-img-info-scaling', @@ -16289,8 +16471,28 @@ ImgOps | https://imgops.com/#b#`; dlSpan.onclick=clickCb; var topP=document.createElement('p'); topP.className="pv-top-banner"; - topP.innerHTML=createHTML(img.naturalWidth+' x '+img.naturalHeight); + var baseTextGetter = () => (img.naturalWidth + ' x ' + img.naturalHeight); + var baseText = baseTextGetter(); + topP.textContent = baseText; + updateViewmoreSizeLabel(topP, baseText, curNode.dataset.src, 'local-only', baseTextGetter); topP.title=dlSpan.title; + let hoverTimer = null; + let autoFetched = false; + let onEnter = () => { + if (autoFetched || topP.textContent.indexOf("|") !== -1) return; + hoverTimer = setTimeout(() => { + autoFetched = true; + scheduleViewmoreAutoSize(topP, baseText, curNode.dataset.src, baseTextGetter); + }, 1000); + }; + let onLeave = () => { + if (hoverTimer) { + clearTimeout(hoverTimer); + hoverTimer = null; + } + }; + imgSpan.addEventListener("mouseenter", onEnter, true); + imgSpan.addEventListener("mouseleave", onLeave, true); var checkBox=document.createElement('input'); checkBox.type="checkbox"; let self=this; @@ -17000,6 +17202,7 @@ ImgOps | https://imgops.com/#b#`; this.imgNaturalSize=imgNaturalSize; this.eleMaps['head-left-img-info-resolution'].textContent=imgNaturalSize.w + ' x ' + imgNaturalSize.h; + updateGalleryHeaderSize(this, img, 'auto'); var thumbnails=this.eleMaps['sidebar-thumbnails-container'].childNodes,i=0; thumbnails=Array.prototype.slice.call(thumbnails).filter(function(thumbnail){ if(thumbnail.style.display=="none"){ @@ -17037,6 +17240,7 @@ ImgOps | https://imgops.com/#b#`; this.imgError=true; this.img.style.display='none'; this.eleMaps['img_broken'].style.display='inline-block'; + this.eleMaps['head-left-img-info-size'].textContent=''; dataset(relatedThumb,'naturalSize',JSON.stringify({w: 0, h: 0})); }else{ var srcs=dataset(relatedThumb, 'srcs'); @@ -17049,6 +17253,7 @@ ImgOps | https://imgops.com/#b#`; self.imgNaturalSize=imgNaturalSize; self.eleMaps['head-left-img-info-resolution'].textContent=imgNaturalSize.w + ' x ' + imgNaturalSize.h; + updateGalleryHeaderSize(self, this, 'auto'); dataset(relatedThumb,'naturalSize',JSON.stringify(imgNaturalSize)); let key = imgNaturalSize.w + "x" + imgNaturalSize.h; self.sizeMap[key] = (self.sizeMap[key] || 0) + 1; @@ -17584,6 +17789,7 @@ ImgOps | https://imgops.com/#b#`; //清空dom this.eleMaps['sidebar-thumbnails-container'].innerHTML=createHTML(''); this.eleMaps['head-left-img-info-resolution'].textContent='0 x 0'; + this.eleMaps['head-left-img-info-size'].textContent=''; this.eleMaps['head-left-img-info-count'].textContent='(1 / 1)'; this.eleMaps['head-left-img-info-scaling'].textContent='(100%)'; //隐藏滚动条 @@ -18890,6 +19096,10 @@ ImgOps | https://imgops.com/#b#`; .pv-gallery-head-left-img-info{\ cursor:help;\ }\ + .pv-gallery-head-left-img-info-size {\ + margin-left: 6px;\ + margin-right: 6px;\ + }\ .pv-gallery-head-left-img-info-description {\ margin-left: 10px;\ margin-right: 10px;\ @@ -20624,6 +20834,8 @@ ImgOps | https://imgops.com/#b#`; this.initPos = initPos || false; this.preview = !!preview; this.isImg = this.img.nodeName.toUpperCase() == 'IMG'; + this.imgSizeBytes = null; + this.imgSizeText = ""; this.init(); if (data && this.isImg) { this.img.src = location.protocol == "https" ? data.src.replace(/^http:/,"https:") : data.src; @@ -20838,6 +21050,8 @@ ImgOps | https://imgops.com/#b#`; img.onload = function(e) { if (self.removed) return; self.loaded = true; + self.imgSizeBytes = null; + self.imgSizeText = ""; container.style.background=''; if (self.preview && img.naturalHeight == 1 && img.naturalWidth == 1) { self.remove(); @@ -20849,6 +21063,7 @@ ImgOps | https://imgops.com/#b#`; w:img.naturalWidth, }; self.setToolBadge('zoom',self.zoomLevel); + self.fetchImgSize(self.img.src, 'auto'); if (self==uniqueImgWin && prefs.floatBar.globalkeys.previewFollowMouse) { self.followPos(uniqueImgWinInitX, uniqueImgWinInitY); } else { @@ -20884,7 +21099,8 @@ ImgOps | https://imgops.com/#b#`; } if (imgNaturalSize.h && imgNaturalSize.w) { container.style.background=''; - setSearchState(`${img.naturalWidth} x ${img.naturalHeight}`, self.imgState); + self.updateImgState(1); + self.fetchImgSize(self.img.src, 'auto'); } if (!this.isImg) { if (/^video$/i.test(img.nodeName)) { @@ -22775,14 +22991,34 @@ ImgOps | https://imgops.com/#b#`; document.addEventListener('mousemove',moveHandler,true); document.addEventListener('mouseup',mouseupHandler,true); }, + updateImgState:function(zoomValue){ + if (!this.imgState || !this.img || !this.img.naturalWidth) return; + var sizeText = this.imgSizeText ? " (" + this.imgSizeText + ")" : ""; + var zoomText = (typeof zoomValue === "number" && zoomValue !== 1) ? " (" + parseInt(zoomValue * 100) + "%)" : ""; + var indexText = (this.curIndex >= 0 && this.data && this.data.all) ? " [" + (this.curIndex + 1) + "/" + this.data.all.length + "]" : ""; + setSearchState("" + this.img.naturalWidth + " x " + this.img.naturalHeight + "" + sizeText + zoomText + indexText, this.imgState); + this.descriptionSpan && this.imgState.appendChild(this.descriptionSpan); + }, + fetchImgSize:function(url, strategy){ + if (!this.isImg) return; + var sizeUrl = url || (this.img ? this.img.src : ""); + if (!sizeUrl) return; + var self = this; + imageSizeFetcher.getSize(sizeUrl, { strategy: strategy || 'auto' }).then(size => { + if (size === null) return; + if (!self.img || self.img.src !== sizeUrl) return; + self.imgSizeBytes = size; + self.imgSizeText = formatBytes(size); + self.updateImgState(self.zoomLevel || 1); + }); + }, setToolBadge:function(tool,content){ var scale=0; switch(tool){ case 'zoom':{ scale=2; if (this.img.naturalWidth) { - setSearchState(`${this.img.naturalWidth} x ${this.img.naturalHeight}` + (content !== 1 ? ` (${parseInt(content * 100)}%)` : "") + (this.curIndex >=0 ? ` [${this.curIndex + 1}/${this.data.all.length}]` : ""), this.imgState); - this.descriptionSpan && this.imgState.appendChild(this.descriptionSpan); + this.updateImgState(content); } }break; case 'rotate':{ @@ -27778,4 +28014,4 @@ ImgOps | https://imgops.com/#b#`; init2(); } -})(this,window,document,(typeof unsafeWindow=='undefined'? window : unsafeWindow)); \ No newline at end of file +})(this,window,document,(typeof unsafeWindow=='undefined'? window : unsafeWindow)); From 296751100dc26af05a6c016942f252d64989c1f3 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Mon, 5 Jan 2026 12:42:28 +0000 Subject: [PATCH 1006/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 248 ++++++++++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 28cb754cfda..207a6a3ddf1 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2025.12.19.1 +// @version 2026.1.5.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://pv.hoothin.com/ @@ -12055,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"; @@ -13939,6 +14119,7 @@ ImgOps | https://imgops.com/#b#`; ''+ ''+ '0 x 0'+ + ''+ '(1 / 1)'+ '(100%)'+ ''+ @@ -14325,6 +14506,7 @@ ImgOps | https://imgops.com/#b#`; 'head-left-img-info', 'head-left-img-info-description', 'head-left-img-info-resolution', + 'head-left-img-info-size', 'head-left-img-info-count', 'head-left-img-info-scaling', @@ -16289,8 +16471,28 @@ ImgOps | https://imgops.com/#b#`; dlSpan.onclick=clickCb; var topP=document.createElement('p'); topP.className="pv-top-banner"; - topP.innerHTML=createHTML(img.naturalWidth+' x '+img.naturalHeight); + var baseTextGetter = () => (img.naturalWidth + ' x ' + img.naturalHeight); + var baseText = baseTextGetter(); + topP.textContent = baseText; + updateViewmoreSizeLabel(topP, baseText, curNode.dataset.src, 'local-only', baseTextGetter); topP.title=dlSpan.title; + let hoverTimer = null; + let autoFetched = false; + let onEnter = () => { + if (autoFetched || topP.textContent.indexOf("|") !== -1) return; + hoverTimer = setTimeout(() => { + autoFetched = true; + scheduleViewmoreAutoSize(topP, baseText, curNode.dataset.src, baseTextGetter); + }, 1000); + }; + let onLeave = () => { + if (hoverTimer) { + clearTimeout(hoverTimer); + hoverTimer = null; + } + }; + imgSpan.addEventListener("mouseenter", onEnter, true); + imgSpan.addEventListener("mouseleave", onLeave, true); var checkBox=document.createElement('input'); checkBox.type="checkbox"; let self=this; @@ -17000,6 +17202,7 @@ ImgOps | https://imgops.com/#b#`; this.imgNaturalSize=imgNaturalSize; this.eleMaps['head-left-img-info-resolution'].textContent=imgNaturalSize.w + ' x ' + imgNaturalSize.h; + updateGalleryHeaderSize(this, img, 'auto'); var thumbnails=this.eleMaps['sidebar-thumbnails-container'].childNodes,i=0; thumbnails=Array.prototype.slice.call(thumbnails).filter(function(thumbnail){ if(thumbnail.style.display=="none"){ @@ -17037,6 +17240,7 @@ ImgOps | https://imgops.com/#b#`; this.imgError=true; this.img.style.display='none'; this.eleMaps['img_broken'].style.display='inline-block'; + this.eleMaps['head-left-img-info-size'].textContent=''; dataset(relatedThumb,'naturalSize',JSON.stringify({w: 0, h: 0})); }else{ var srcs=dataset(relatedThumb, 'srcs'); @@ -17049,6 +17253,7 @@ ImgOps | https://imgops.com/#b#`; self.imgNaturalSize=imgNaturalSize; self.eleMaps['head-left-img-info-resolution'].textContent=imgNaturalSize.w + ' x ' + imgNaturalSize.h; + updateGalleryHeaderSize(self, this, 'auto'); dataset(relatedThumb,'naturalSize',JSON.stringify(imgNaturalSize)); let key = imgNaturalSize.w + "x" + imgNaturalSize.h; self.sizeMap[key] = (self.sizeMap[key] || 0) + 1; @@ -17584,6 +17789,7 @@ ImgOps | https://imgops.com/#b#`; //清空dom this.eleMaps['sidebar-thumbnails-container'].innerHTML=createHTML(''); this.eleMaps['head-left-img-info-resolution'].textContent='0 x 0'; + this.eleMaps['head-left-img-info-size'].textContent=''; this.eleMaps['head-left-img-info-count'].textContent='(1 / 1)'; this.eleMaps['head-left-img-info-scaling'].textContent='(100%)'; //隐藏滚动条 @@ -18890,6 +19096,10 @@ ImgOps | https://imgops.com/#b#`; .pv-gallery-head-left-img-info{\ cursor:help;\ }\ + .pv-gallery-head-left-img-info-size {\ + margin-left: 6px;\ + margin-right: 6px;\ + }\ .pv-gallery-head-left-img-info-description {\ margin-left: 10px;\ margin-right: 10px;\ @@ -20624,6 +20834,8 @@ ImgOps | https://imgops.com/#b#`; this.initPos = initPos || false; this.preview = !!preview; this.isImg = this.img.nodeName.toUpperCase() == 'IMG'; + this.imgSizeBytes = null; + this.imgSizeText = ""; this.init(); if (data && this.isImg) { this.img.src = location.protocol == "https" ? data.src.replace(/^http:/,"https:") : data.src; @@ -20838,6 +21050,8 @@ ImgOps | https://imgops.com/#b#`; img.onload = function(e) { if (self.removed) return; self.loaded = true; + self.imgSizeBytes = null; + self.imgSizeText = ""; container.style.background=''; if (self.preview && img.naturalHeight == 1 && img.naturalWidth == 1) { self.remove(); @@ -20849,6 +21063,7 @@ ImgOps | https://imgops.com/#b#`; w:img.naturalWidth, }; self.setToolBadge('zoom',self.zoomLevel); + self.fetchImgSize(self.img.src, 'auto'); if (self==uniqueImgWin && prefs.floatBar.globalkeys.previewFollowMouse) { self.followPos(uniqueImgWinInitX, uniqueImgWinInitY); } else { @@ -20884,7 +21099,8 @@ ImgOps | https://imgops.com/#b#`; } if (imgNaturalSize.h && imgNaturalSize.w) { container.style.background=''; - setSearchState(`${img.naturalWidth} x ${img.naturalHeight}`, self.imgState); + self.updateImgState(1); + self.fetchImgSize(self.img.src, 'auto'); } if (!this.isImg) { if (/^video$/i.test(img.nodeName)) { @@ -22775,14 +22991,34 @@ ImgOps | https://imgops.com/#b#`; document.addEventListener('mousemove',moveHandler,true); document.addEventListener('mouseup',mouseupHandler,true); }, + updateImgState:function(zoomValue){ + if (!this.imgState || !this.img || !this.img.naturalWidth) return; + var sizeText = this.imgSizeText ? " (" + this.imgSizeText + ")" : ""; + var zoomText = (typeof zoomValue === "number" && zoomValue !== 1) ? " (" + parseInt(zoomValue * 100) + "%)" : ""; + var indexText = (this.curIndex >= 0 && this.data && this.data.all) ? " [" + (this.curIndex + 1) + "/" + this.data.all.length + "]" : ""; + setSearchState("" + this.img.naturalWidth + " x " + this.img.naturalHeight + "" + sizeText + zoomText + indexText, this.imgState); + this.descriptionSpan && this.imgState.appendChild(this.descriptionSpan); + }, + fetchImgSize:function(url, strategy){ + if (!this.isImg) return; + var sizeUrl = url || (this.img ? this.img.src : ""); + if (!sizeUrl) return; + var self = this; + imageSizeFetcher.getSize(sizeUrl, { strategy: strategy || 'auto' }).then(size => { + if (size === null) return; + if (!self.img || self.img.src !== sizeUrl) return; + self.imgSizeBytes = size; + self.imgSizeText = formatBytes(size); + self.updateImgState(self.zoomLevel || 1); + }); + }, setToolBadge:function(tool,content){ var scale=0; switch(tool){ case 'zoom':{ scale=2; if (this.img.naturalWidth) { - setSearchState(`${this.img.naturalWidth} x ${this.img.naturalHeight}` + (content !== 1 ? ` (${parseInt(content * 100)}%)` : "") + (this.curIndex >=0 ? ` [${this.curIndex + 1}/${this.data.all.length}]` : ""), this.imgState); - this.descriptionSpan && this.imgState.appendChild(this.descriptionSpan); + this.updateImgState(content); } }break; case 'rotate':{ @@ -27778,4 +28014,4 @@ ImgOps | https://imgops.com/#b#`; init2(); } -})(this,window,document,(typeof unsafeWindow=='undefined'? window : unsafeWindow)); \ No newline at end of file +})(this,window,document,(typeof unsafeWindow=='undefined'? window : unsafeWindow)); From a9cbde28aa16e7983c91dbe8e82bd8042f22cad1 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 10 Jan 2026 11:25:32 +0900 Subject: [PATCH 1007/1065] 1.9.37.128 --- Pagetual/README.md | 2 +- Pagetual/pagetual.user.js | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index c58d65bd3fc..6077f2266b0 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -1,4 +1,4 @@ -[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.127](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") +[☯️](https://greasyfork.org/scripts/438684 "Install from greasyfork")東方永頁機 [v.1.9.37.128](https://hoothin.github.io/UserScripts/Pagetual/pagetual.user.js "Latest version") == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js index ddc0c1d1acf..c84d06d613c 100644 --- a/Pagetual/pagetual.user.js +++ b/Pagetual/pagetual.user.js @@ -31,7 +31,7 @@ // @name:da Pagetual // @name:fr-CA Pagetual // @namespace hoothin -// @version 1.9.37.127 +// @version 1.9.37.128 // @description Perpetual pages - powerful auto-pager script. Auto fetching next paginated web pages and inserting into current page for infinite scroll. Support thousands of web sites without any rule. // @description:zh-CN 终极自动翻页 - 加载并拼接下一分页内容至当前页尾,智能适配任意网页 // @description:zh-TW 終極自動翻頁 - 加載並拼接下一分頁內容至當前頁尾,智能適配任意網頁 @@ -137,6 +137,9 @@ if (document.body && getComputedStyle(document.body).display === 'none') { document.body.style.display = 'block'; } + Element.prototype.scrollIntoView = function() { + console.log('ScrollIntoView blocked.'); + }; return; } @@ -12648,12 +12651,12 @@ } let eles = ruleParser.getPageElement(iframeDoc, emuIframe.contentWindow, true), checkItem; if (eles && eles.length > 0) { - eles = [].filter.call(eles, ele => {return ele && !compareNodeName(ele, ["style", "script", "meta"])}); - if (compareNodeName(eles[0], ["ul"]) || eles.length == 1) checkItem = eles[0]; - else if (eles[0].parentNode == eles[1].parentNode) { - checkItem = eles[0].parentNode; + const filterEles = [].filter.call(eles, ele => {return ele && !compareNodeName(ele, ["style", "script", "meta"])}); + if (compareNodeName(filterEles[0], ["ul"]) || filterEles.length == 1) checkItem = filterEles[0]; + else if (filterEles[0].parentNode == filterEles[1].parentNode) { + checkItem = filterEles[0].parentNode; } else { - checkItem = eles[0]; + checkItem = filterEles[0]; } } if (!checkItem) { From a86577325dc95639a0c77e3dc956fa8782b562ce Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 13 Jan 2026 12:51:06 +0900 Subject: [PATCH 1008/1065] stitch --- Picviewer CE+/pvcep_lang.js | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/Picviewer CE+/pvcep_lang.js b/Picviewer CE+/pvcep_lang.js index adf87fa2c25..113b1cfa052 100644 --- a/Picviewer CE+/pvcep_lang.js +++ b/Picviewer CE+/pvcep_lang.js @@ -29,6 +29,11 @@ const langData = [ closeBtn: "Cancel", invertBtn: "Invert", compareBtn: "Compare", + stitch: "Stitch", + stitchDone: "Done", + stitchCancel: "Cancel", + stitchHorizontal: "Horizontal", + stitchVertical: "Vertical", selectAllBtn: "Select All", closeBtnTips: "cancel this setting and restore all options", resetLink: "Restore default settings", @@ -297,6 +302,11 @@ const langData = [ closeBtn: "%D8%A5%D9%84%D8%BA%D8%A7%D8%A1", invertBtn: "%D8%B9%D9%83%D8%B3", compareBtn: "%D9%85%D9%82%D8%A7%D8%B1%D9%86%D8%A9", + stitch: "%D8%AF%D9%85%D8%AC", + stitchDone: "%D8%AA%D9%85", + stitchCancel: "%D8%A5%D9%84%D8%BA%D8%A7%D8%A1", + stitchHorizontal: "%D8%A3%D9%81%D9%82%D9%8A", + stitchVertical: "%D8%B9%D9%85%D9%88%D8%AF%D9%8A", selectAllBtn: "%D8%AA%D8%AD%D8%AF%D9%8A%D8%AF%20%D8%A7%D9%84%D9%83%D9%84", closeBtnTips: "%D8%A5%D9%84%D8%BA%D8%A7%D8%A1%20%D9%87%D8%B0%D8%A7%20%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF%20%D9%88%D8%A7%D8%B3%D8%AA%D8%B9%D8%A7%D8%AF%D8%A9%20%D8%AC%D9%85%D9%8A%D8%B9%20%D8%A7%D9%84%D8%AE%D9%8A%D8%A7%D8%B1%D8%A7%D8%AA", resetLink: "%D8%A7%D8%B3%D8%AA%D8%B9%D8%A7%D8%AF%D8%A9%20%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF%D8%A7%D8%AA%20%D8%A7%D9%84%D8%A7%D9%81%D8%AA%D8%B1%D8%A7%D8%B6%D9%8A%D8%A9", @@ -563,6 +573,11 @@ const langData = [ closeBtn: "取消", invertBtn: "反选", compareBtn: "对比", + stitch: "拼接", + stitchDone: "完成", + stitchCancel: "取消", + stitchHorizontal: "横排", + stitchVertical: "竖排", selectAllBtn: "全选", closeBtnTips: "取消本次设置,所有选项还原", resetLink: "恢复默认设置", @@ -829,6 +844,11 @@ const langData = [ closeBtn: "取消", invertBtn: "反選", compareBtn: "對比", + stitch: "拼接", + stitchDone: "完成", + stitchCancel: "取消", + stitchHorizontal: "橫排", + stitchVertical: "豎排", selectAllBtn: "全選", closeBtnTips: "取消本次設置,所有選項還原", resetLink: "恢復默認設置", @@ -1096,6 +1116,11 @@ const langData = [ closeBtn: "Sair", invertBtn: "Inverter", compareBtn: "Comparar", + stitch: "Montar", + stitchDone: "Concluir", + stitchCancel: "Cancelar", + stitchHorizontal: "Horizontal", + stitchVertical: "Vertical", selectAllBtn: "Selecionar tudo", closeBtnTips: "Sair sem aplicar as mudanças", resetLink: "Restaurar Padrões", @@ -1363,6 +1388,11 @@ const langData = [ closeBtn: "Cancelar", invertBtn: "Inverter", compareBtn: "Comparar", + stitch: "Montar", + stitchDone: "Concluir", + stitchCancel: "Cancelar", + stitchHorizontal: "Horizontal", + stitchVertical: "Vertical", selectAllBtn: "Selecione tudo", closeBtnTips: "Descarta as alterações e restaura as configurações anteriores", resetLink: "Restaurar definições originais", @@ -1630,6 +1660,11 @@ const langData = [ closeBtn: "Закрыть", invertBtn: "Откатить", compareBtn: "Сравнивать", + stitch: "Склеить", + stitchDone: "Готово", + stitchCancel: "Отмена", + stitchHorizontal: "Горизонтально", + stitchVertical: "Вертикально", selectAllBtn: "Выбрать все", closeBtnTips: "Отменяет эту настройку и восстанавливает все параметры", resetLink: "Восстановить по умолчанию", @@ -1897,6 +1932,11 @@ const langData = [ closeBtn: "İptal Et", invertBtn: "Tersine Çevir", compareBtn: "Kıyaslamak", + stitch: "Birleştir", + stitchDone: "Tamam", + stitchCancel: "İptal", + stitchHorizontal: "Yatay", + stitchVertical: "Dikey", selectAllBtn: "Hepsini seç", closeBtnTips: "bu ayarı iptal et ve tüm ayarları varsayılan haline döndür", resetLink: "Ayarları varsayılana döndür", @@ -2163,6 +2203,11 @@ const langData = [ closeBtn: "キャンセル", invertBtn: "反転", compareBtn: "比較", + stitch: "結合", + stitchDone: "完了", + stitchCancel: "キャンセル", + stitchHorizontal: "横", + stitchVertical: "縦", selectAllBtn: "全て選択", closeBtnTips: "設定をキャンセルし、すべてのオプションを復元します", resetLink: "初期設定に戻す", @@ -2430,6 +2475,11 @@ const langData = [ closeBtn: "Закрити", invertBtn: "Відновити", compareBtn: "Порівняти", + stitch: "З'єднати", + stitchDone: "Готово", + stitchCancel: "Скасувати", + stitchHorizontal: "Горизонтально", + stitchVertical: "Вертикально", selectAllBtn: "Вибрати все", closeBtnTips: "Скасовує ці налаштування та відновлює усі параметри", resetLink: "Скинути налаштування", From 960e78fa8c7e22fbe2fd73bd24d660b9c33e89fb Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 13 Jan 2026 13:28:55 +0900 Subject: [PATCH 1009/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 659 +++++++++++++++++++++++++++- 1 file changed, 657 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index a72abbdb16c..f2e12a8cf84 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12784,7 +12784,7 @@ ImgOps | https://imgops.com/#b#`; // 默认设置,请到设置界面修改 prefs={ floatBar:{//浮动工具栏相关设置. - butonOrder:['actual','current','gallery','magnifier','download'],//按钮排列顺序'actual'(实际的图片),'current'(当前显示的图片),'magnifier'(放大镜观察),'gallery'(图集),'search'(搜索原图) + butonOrder:['actual','current','gallery','magnifier','download','stitch'],//按钮排列顺序'actual'(实际的图片),'current'(当前显示的图片),'magnifier'(放大镜观察),'gallery'(图集),'search'(搜索原图) additionalFeature: 'open', invertAdditionalFeature: false, listenBg:true,//监听背景图 @@ -12992,6 +12992,7 @@ ImgOps | https://imgops.com/#b#`; gallery:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAP1BMVEUAAAD///94eHgZGRn39/fz8/POzs6xsbGSkpJ9fX1UVFQpKSnb29vJycmmpqafn5+UlJSNjY0/Pz8hISENDQ2fWpEMAAAAcUlEQVQoz43SWQrEIBRE0Xe7M8/T/tcaNSKCKUh95nCDiIaYYa9zUDQRiiaCalANqkE0n6BuBLArWBTUAsa2/3yqfwYdzAl+GeCWAN9YM7nvo4chgoXmgjP8CdoEvqmA/oCQRHgat2p7YM2gvHb9GMRu7acCGLmlyNoAAAAASUVORK5CYII=', search:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAXVBMVEUAAAD///+MjIwmJibNzc2UlJTd3d2lpaUKCgrT09O/v78YGBjj4+MvLy8PDw/IyMh5eXn5+fn29vby8vLo6OjDw8O7u7u3t7ewsLCcnJx1dXVubm4+Pj43NzdkZGStc/JSAAAA4ElEQVQoz52RWW7DMAxE9bR635fYcXr/Y5aW7TYIGqDI/EjUAzRDUvFGCvWn/gHMOnmfNeYFJLonqnPVM8hrIA3B7of5BXkK47bXWwbe/ACp3OWqwSYnaI73+zStSST6AKYjE/sbQCZkpi0j0HSlUl/gPdwleM8SgSfIRzd8laRkcl0oIihYIkiVqhnl6hgicPRGrMHW0Ej4gXCYt8xiPoIw6TtANL8CVtpanSu1xvARJHYnpxpIq6tzU8D8UKIywHCNZCcpUDuXteDL57HngVMhf1nUQ9uisG47y492/kbfyJQHZ5yu1AMAAAAASUVORK5CYII=', download:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAASFBMVEUAAAD///86Ojq8vLxXV1ciIiKcnJympqZjY2MxMTHc3NywsLBDQ0NPT08VFRV5eXn39/fw8PDZ2dnV1dXKysqUlJTl5eUNDQ1EnTQhAAAAtUlEQVQoz33QWRKDIBAE0Gl2AXFP7n/TDKIEk5j+wKp+ZQ0D4SYE+pkDkrMe3rr0ATEYpUkrE+IFouyppJexgRR6IQQAPodlAqeAMyRoByIyjo8DrGpA2Td43YD2FfJHokR2hOsf8uy1v87oZOnrjHorFu7rreoexKLzhiFlqJsPxJL7dcZagWU532oG0ABNzj7y6wpwVAOgJ8AztgyhhTRyM0TsUQ0MuRi3AqaBayp85T/c5AVMKwUv6mnXTQAAAABJRU5ErkJggg==', + stitch:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYAgMAAACdGdVrAAAACVBMVEUAAAD///9XV1cawLSAAAAAKUlEQVQI12MIBQMGBwYgYMRBqQawRgAp0QDWEOwUHu349EGNxqsd6kAArN4RJ/MiMK0AAAAASUVORK5CYII=', downloadSvgBtn:'Download', video:'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiIHZlcnNpb249IjEuMSI+PHBhdGggZD0iTTUxMiA2NEMyNjUuNiA2NCA2NCAyNjUuNiA2NCA1MTJzMjAxLjYgNDQ4IDQ0OCA0NDggNDQ4LTIwMS42IDQ0OC00NDhTNzU4LjQgNjQgNTEyIDY0ek02OTEuMiA1NDRsLTI1NiAxNTYuOEM0MjguOCA3MDQgNDIyLjQgNzA0IDQxNiA3MDRjLTYuNCAwLTkuNiAwLTE2LTMuMkMzOTAuNCA2OTQuNCAzODQgNjg0LjggMzg0IDY3MkwzODQgMzUyYzAtMTIuOCA2LjQtMjIuNCAxNi0yOC44IDkuNi02LjQgMjIuNC02LjQgMzIgMGwyNTYgMTY2LjRjOS42IDYuNCAxNiAxNiAxNiAyOC44QzcwNCA1MjggNzAwLjggNTQwLjggNjkxLjIgNTQ0eiIgZmlsbD0id2hpdGUiLz48L3N2Zz4=', audio:'data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTc2OCA5MzguNjY2NjY3SDI1NmE4NS4zMzMzMzMgODUuMzMzMzMzIDAgMCAxLTg1LjMzMzMzMy04NS4zMzMzMzRWMTcwLjY2NjY2N2E4NS4zMzMzMzMgODUuMzMzMzMzIDAgMCAxIDg1LjMzMzMzMy04NS4zMzMzMzRoNDIuNjY2NjY3djI5OC42NjY2NjdsMTA2LjY2NjY2Ni02NEw1MTIgMzg0Vjg1LjMzMzMzM2gyNTZhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMSA4NS4zMzMzMzMgODUuMzMzMzM0djY4Mi42NjY2NjZhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMS04NS4zMzMzMzMgODUuMzMzMzM0bS0yMTMuMzMzMzMzLTI5OC42NjY2NjdhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMC04NS4zMzMzMzQgODUuMzMzMzMzIDg1LjMzMzMzMyA4NS4zMzMzMzMgMCAwIDAgODUuMzMzMzM0IDg1LjMzMzMzNCA4NS4zMzMzMzMgODUuMzMzMzMzIDAgMCAwIDg1LjMzMzMzMy04NS4zMzMzMzR2LTIxMy4zMzMzMzNoMTI4di04NS4zMzMzMzNoLTE3MC42NjY2Njd2MjI0Ljg1MzMzM2MtMTIuMzczMzMzLTcuMjUzMzMzLTI3LjMwNjY2Ny0xMS41Mi00Mi42NjY2NjYtMTEuNTJ6IiBmaWxsPSJ3aGl0ZSIvPjwvc3ZnPg==', @@ -13236,6 +13237,22 @@ ImgOps | https://imgops.com/#b#`; } function downloadImg(url, name, type, over) { + if (/^blob:/.test(url)) { + const blob = getBlob(url); + if (blob) { + let ext = blob.type.replace(/.*image\/([\w\-]+).*/, "$1"); + if (ext === "none") ext = "png"; + try { + saveAs(blob, (prefs.saveNameAddTitle ? document.title.replace(/[\*\/:<>\?\\\|]/g, "") + " - " : "") + getRightSaveName(url, name, type, ext)); + over && over(); + return; + } catch (e) { + _GM_download(url, name, type); + over && over(); + return; + } + } + } if(canvas && (/^data:/.test(url) || url.split("/")[2] == document.domain)){ urlToBlobWithFetch(url, (blob, ext)=>{ if(!blob){ @@ -20991,6 +21008,7 @@ ImgOps | https://imgops.com/#b#`; self.remove(); },false); + var maxButton=container.querySelector('.pv-pic-window-max'); maxButton.style.cssText='top: -22px;right: 46px;'; this.maxButton=maxButton; @@ -23626,6 +23644,621 @@ ImgOps | https://imgops.com/#b#`; } }, true); + function StitcherC() { + this.selecting = false; + this.previewing = false; + this.selected = new Set(); + this.overlay = null; + this.preview = null; + this.layout = 'column'; + this.dragging = false; + this.startX = 0; + this.startY = 0; + } + + StitcherC.prototype = { + addStyle: function() { + if (StitcherC.style) { + if (!StitcherC.style.parentNode) { + StitcherC.style = _GM_addStyle(StitcherC.style.innerText); + } + return; + } + StitcherC.style = _GM_addStyle('\ + .pv-stitch-overlay {\ + position: fixed;\ + top: 0;\ + left: 0;\ + width: 100%;\ + height: 100%;\ + z-index:'+(prefs.imgWindow.zIndex + 5)+';\ + pointer-events: none;\ + }\ + .pv-stitch-overlay * {\ + box-sizing: border-box;\ + }\ + .pv-stitch-panel {\ + position: fixed;\ + top: 12px;\ + left: 12px;\ + display: flex;\ + gap: 8px;\ + padding: 6px;\ + background: rgba(0,0,0,0.65);\ + border: 1px solid rgba(255,255,255,0.2);\ + border-radius: 6px;\ + pointer-events: auto;\ + }\ + .pv-stitch-panel-inline {\ + position: absolute;\ + top: 8px;\ + right: 8px;\ + left: auto;\ + }\ + .pv-stitch-action {\ + width: 28px;\ + height: 28px;\ + display: flex;\ + align-items: center;\ + justify-content: center;\ + color: #fff;\ + background: rgba(255,255,255,0.12);\ + border-radius: 4px;\ + cursor: pointer;\ + }\ + .pv-stitch-action:hover {\ + background: rgba(255,255,255,0.25);\ + }\ + .pv-stitch-action.active {\ + background: rgba(255,255,255,0.4);\ + }\ + .pv-stitch-action>svg {\ + width: 18px;\ + height: 18px;\ + fill: none;\ + stroke: currentColor;\ + stroke-width: 3;\ + stroke-linecap: round;\ + stroke-linejoin: round;\ + }\ + .pv-stitch-box {\ + position: fixed;\ + border: 1px dashed rgba(255,255,255,0.9);\ + background: rgba(79,179,255,0.18);\ + pointer-events: none;\ + display: none;\ + }\ + .pv-stitch-selected {\ + outline: 3px solid rgba(79,179,255,0.95);\ + outline-offset: -3px;\ + box-shadow: 0 0 0 3px rgba(79,179,255,0.9), 0 0 12px rgba(79,179,255,0.85);\ + filter: brightness(0.78) saturate(1.15);\ + }\ + .pv-stitch-selected-parent {\ + outline: 3px solid rgba(79,179,255,0.95);\ + outline-offset: -3px;\ + box-shadow: 0 0 0 3px rgba(79,179,255,0.9), 0 0 12px rgba(79,179,255,0.85);\ + }\ + .pv-stitch-preview {\ + pointer-events: auto;\ + background: rgba(0,0,0,0.6);\ + }\ + .pv-stitch-stage {\ + position: fixed;\ + top: 50%;\ + left: 50%;\ + transform: translate(-50%, -50%);\ + max-width: 90vw;\ + max-height: 80vh;\ + overflow: auto;\ + padding: 12px;\ + background: rgba(0,0,0,0.75);\ + border: 1px solid rgba(255,255,255,0.2);\ + border-radius: 8px;\ + pointer-events: auto;\ + }\ + .pv-stitch-items {\ + display: flex;\ + gap: 10px;\ + }\ + .pv-stitch-items-horizontal {\ + flex-direction: row;\ + }\ + .pv-stitch-items-vertical {\ + flex-direction: column;\ + }\ + .pv-stitch-item {\ + padding: 6px;\ + background: rgba(0,0,0,0.55);\ + border: 1px solid rgba(255,255,255,0.2);\ + border-radius: 6px;\ + cursor: move;\ + }\ + .pv-stitch-item.dragging {\ + opacity: 0.4;\ + }\ + .pv-stitch-item img {\ + display: block;\ + max-width: 220px;\ + max-height: 220px;\ + }\ + .pv-stitch-selecting, .pv-stitch-selecting * {\ + user-select: none;\ + }\ + '); + }, + openSelect: function() { + if (this.selecting || this.previewing) return; + this.addStyle(); + this.selecting = true; + if (floatBar) floatBar.hide(); + document.documentElement.classList.add('pv-stitch-selecting'); + const overlay = document.createElement('div'); + overlay.className = 'pv-stitch-overlay pv-stitch-select'; + overlay.innerHTML = createHTML( + '
      '+ + '
      '+ + ''+ + '
      '+ + '
      '+ + ''+ + '
      '+ + '
      '+ + '
      ' + ); + document.body.appendChild(overlay); + this.overlay = overlay; + this.box = overlay.querySelector('.pv-stitch-box'); + const panel = overlay.querySelector('.pv-stitch-panel'); + this.placePanel(panel); + overlay.querySelector('.pv-stitch-action-done').addEventListener('click', () => { + if (!this.selected.size) { + this.closeSelect(); + return; + } + const selected = Array.from(this.selected); + this.closeSelect(false); + this.openPreview(selected); + }); + overlay.querySelector('.pv-stitch-action-cancel').addEventListener('click', () => { + this.closeSelect(); + }); + + this.onSelectMouseDown = (e) => { + if (!this.selecting) return; + if (panel.contains(e.target)) return; + if (e.button !== 0 && e.button !== 2) return; + e.preventDefault(); + e.stopPropagation(); + this.dragging = true; + panel.style.display = 'none'; + this.dragMode = (e.button === 2 || e.altKey || e.shiftKey) ? 'remove' : 'add'; + this.startX = e.clientX; + this.startY = e.clientY; + this.updateBox(e.clientX, e.clientY); + this.box.style.display = 'block'; + }; + this.onSelectMouseMove = (e) => { + if (!this.dragging) return; + e.preventDefault(); + e.stopPropagation(); + this.updateBox(e.clientX, e.clientY); + }; + this.onSelectMouseUp = (e) => { + if (!this.dragging) return; + e.preventDefault(); + e.stopPropagation(); + this.dragging = false; + const rect = this.getBoxRect(e.clientX, e.clientY); + this.box.style.display = 'none'; + if (rect.width < 4 && rect.height < 4) { + const img = this.findImageAt(e.clientX, e.clientY); + if (img) this.toggleSelection(img, this.dragMode); + panel.style.display = ''; + this.placePanelNear(panel, e.clientX, e.clientY); + return; + } + this.applySelection(rect, this.dragMode); + panel.style.display = ''; + this.placePanelNear(panel, e.clientX, e.clientY); + }; + this.onSelectClick = (e) => { + if (!this.selecting) return; + if (panel.contains(e.target)) return; + e.preventDefault(); + e.stopPropagation(); + }; + this.onSelectContext = (e) => { + if (!this.selecting) return; + if (panel.contains(e.target)) return; + e.preventDefault(); + e.stopPropagation(); + }; + this.onKeyDown = (e) => { + if (e.key !== 'Escape') return; + if (this.selecting) this.closeSelect(); + if (this.previewing) this.closePreview(); + }; + document.addEventListener('mousedown', this.onSelectMouseDown, true); + document.addEventListener('mousemove', this.onSelectMouseMove, true); + document.addEventListener('mouseup', this.onSelectMouseUp, true); + document.addEventListener('click', this.onSelectClick, true); + document.addEventListener('contextmenu', this.onSelectContext, true); + document.addEventListener('keydown', this.onKeyDown, true); + }, + closeSelect: function(clear = true) { + if (!this.selecting) return; + this.selecting = false; + document.documentElement.classList.remove('pv-stitch-selecting'); + if (this.overlay && this.overlay.parentNode) { + this.overlay.parentNode.removeChild(this.overlay); + } + this.overlay = null; + this.box = null; + if (clear) this.clearSelection(); + document.removeEventListener('mousedown', this.onSelectMouseDown, true); + document.removeEventListener('mousemove', this.onSelectMouseMove, true); + document.removeEventListener('mouseup', this.onSelectMouseUp, true); + document.removeEventListener('click', this.onSelectClick, true); + document.removeEventListener('contextmenu', this.onSelectContext, true); + if (!this.previewing) document.removeEventListener('keydown', this.onKeyDown, true); + }, + clearSelection: function() { + this.selected.forEach((img) => { + img.classList.remove('pv-stitch-selected'); + this.toggleParentClass(img, false); + }); + this.selected.clear(); + }, + updateBox: function(x, y) { + const rect = this.getBoxRect(x, y); + this.box.style.left = rect.left + 'px'; + this.box.style.top = rect.top + 'px'; + this.box.style.width = rect.width + 'px'; + this.box.style.height = rect.height + 'px'; + }, + getBoxRect: function(x, y) { + const left = Math.min(this.startX, x); + const top = Math.min(this.startY, y); + const width = Math.abs(this.startX - x); + const height = Math.abs(this.startY - y); + return {left, top, width, height, right: left + width, bottom: top + height}; + }, + applySelection: function(rect, mode) { + const imgs = this.getSelectableImages(); + imgs.forEach((img) => { + const r = img.getBoundingClientRect(); + if (rect.right < r.left || rect.left > r.right || rect.bottom < r.top || rect.top > r.bottom) return; + if (mode === 'remove') this.removeSelection(img); + else this.addSelection(img); + }); + }, + addSelection: function(img) { + if (this.selected.has(img)) return; + this.selected.add(img); + img.classList.add('pv-stitch-selected'); + this.toggleParentClass(img, true); + }, + removeSelection: function(img) { + if (!this.selected.has(img)) return; + this.selected.delete(img); + img.classList.remove('pv-stitch-selected'); + this.toggleParentClass(img, false); + }, + toggleSelection: function(img, mode) { + if (mode === 'remove') { + this.removeSelection(img); + return; + } + if (this.selected.has(img)) this.removeSelection(img); + else this.addSelection(img); + }, + toggleParentClass: function(img, isAdd) { + const parent = img && img.parentNode; + if (!parent || parent.nodeType !== 1) return; + const tag = parent.tagName; + if (tag === 'BODY' || tag === 'HTML') return; + parent.classList.toggle('pv-stitch-selected-parent', isAdd); + }, + findImageAt: function(x, y) { + const els = document.elementsFromPoint(x, y); + for (let i = 0; i < els.length; i++) { + const el = els[i]; + if (this.overlay && this.overlay.contains(el)) continue; + if (el.tagName === 'IMG') return el; + } + return null; + }, + getSelectableImages: function() { + const imgs = document.querySelectorAll('img'); + const list = []; + for (let i = 0; i < imgs.length; i++) { + const img = imgs[i]; + if (!img.src && !img.currentSrc) continue; + const style = unsafeWindow.getComputedStyle(img); + if (style.display === 'none' || style.visibility === 'hidden') continue; + const rect = img.getBoundingClientRect(); + if (rect.width < 4 || rect.height < 4) continue; + list.push(img); + } + return list; + }, + getImgSrc: function(img) { + const original = this.getOriginalImgSrc(img); + if (original) return original; + return img.currentSrc || img.src || img.getAttribute('data-src') || img.getAttribute('data-original') || img.getAttribute('data-lazy-src') || img.getAttribute('data-zoom-image') || img.getAttribute('data-large'); + }, + getOriginalImgSrc: function(img) { + if (!img) return ""; + let imgPA, imgPE = []; + let imgPN = img.parentNode; + while (imgPN && imgPN.nodeType === 1 && imgPN.nodeName !== "BODY") { + if (!imgPA && imgPN.nodeName === "A") imgPA = imgPN; + imgPE.push(imgPN); + imgPN = imgPN.parentNode; + } + try { + if (matchedRule && matchedRule.rules && matchedRule.rules.length > 0 && matchedRule.getImage) { + let src = matchedRule.getImage(img, imgPA, imgPE); + if (Array.isArray(src)) src = src[0]; + if (src && src !== img.src) return src; + } + } catch (e) {} + try { + if (tprules && tprules[0]) { + const src = tprules[0].call(img); + if (src) return src; + } + } catch (e) {} + if (imgPA && imgPA.href && imageReg.test(imgPA.href) && imgPA.href !== img.src) { + return imgPA.href; + } + return ""; + }, + openPreview: function(selected) { + const srcs = []; + selected.forEach((img) => { + const src = this.getImgSrc(img); + if (src) srcs.push(src); + img.classList.remove('pv-stitch-selected'); + this.toggleParentClass(img, false); + }); + this.selected.clear(); + if (!srcs.length) return; + if (this.previewing) return; + this.previewing = true; + this.addStyle(); + const overlay = document.createElement('div'); + overlay.className = 'pv-stitch-overlay pv-stitch-preview'; + const isVertical = this.layout === 'column'; + overlay.innerHTML = createHTML( + '
      '+ + '
      '+ + '
      '+ + ''+ + '
      '+ + '
      '+ + ''+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + ''+ + '
      '+ + '
      '+ + ''+ + '
      '+ + '
      ' + ); + document.body.appendChild(overlay); + this.preview = overlay; + const itemsCon = overlay.querySelector('.pv-stitch-items'); + const stage = overlay.querySelector('.pv-stitch-stage'); + const actionPanel = overlay.querySelector('.pv-stitch-panel-action'); + this.placeActionPanel(stage, actionPanel); + srcs.forEach((src) => { + const item = document.createElement('div'); + item.className = 'pv-stitch-item'; + item.setAttribute('draggable', 'true'); + item.dataset.src = src; + const img = document.createElement('img'); + img.src = src; + img.addEventListener('load', () => this.placeActionPanel(stage, actionPanel)); + item.appendChild(img); + itemsCon.appendChild(item); + }); + setTimeout(() => this.placeActionPanel(stage, actionPanel), 0); + let dragItem = null; + itemsCon.addEventListener('dragstart', (e) => { + const item = e.target.closest('.pv-stitch-item'); + if (!item) return; + dragItem = item; + dragItem.classList.add('dragging'); + e.dataTransfer.effectAllowed = 'move'; + }); + itemsCon.addEventListener('dragend', () => { + if (dragItem) dragItem.classList.remove('dragging'); + dragItem = null; + }); + itemsCon.addEventListener('dragover', (e) => { + if (!dragItem) return; + const target = e.target.closest('.pv-stitch-item'); + if (!target || target === dragItem) return; + e.preventDefault(); + const rect = target.getBoundingClientRect(); + const before = this.layout === 'row' ? e.clientX < rect.left + rect.width / 2 : e.clientY < rect.top + rect.height / 2; + itemsCon.insertBefore(dragItem, before ? target : target.nextSibling); + }); + + const btnHorizontal = overlay.querySelector('.pv-stitch-action-horizontal'); + const btnVertical = overlay.querySelector('.pv-stitch-action-vertical'); + btnHorizontal.addEventListener('click', () => { + this.setLayout('row', itemsCon, btnHorizontal, btnVertical); + this.placeActionPanel(stage, actionPanel); + }); + btnVertical.addEventListener('click', () => { + this.setLayout('column', itemsCon, btnHorizontal, btnVertical); + this.placeActionPanel(stage, actionPanel); + }); + overlay.querySelector('.pv-stitch-action-done').addEventListener('click', async () => { + const ordered = Array.from(itemsCon.querySelectorAll('.pv-stitch-item')).map(item => item.dataset.src); + this.closePreview(); + await this.renderStitch(ordered, this.layout); + }); + overlay.querySelector('.pv-stitch-action-cancel').addEventListener('click', () => { + this.closePreview(); + }); + document.addEventListener('keydown', this.onKeyDown, true); + }, + closePreview: function() { + if (!this.previewing) return; + this.previewing = false; + if (this.preview && this.preview.parentNode) { + this.preview.parentNode.removeChild(this.preview); + } + this.preview = null; + if (!this.selecting) document.removeEventListener('keydown', this.onKeyDown, true); + }, + placePanel: function(panel) { + if (!panel) return; + requestAnimationFrame(() => { + const rect = panel.getBoundingClientRect(); + const pad = 8; + const left = Math.min(Math.max(pad, (window.innerWidth - rect.width) / 2), window.innerWidth - rect.width - pad); + let top = Math.round(window.innerHeight * 0.72); + if (top + rect.height > window.innerHeight - pad) { + top = window.innerHeight - rect.height - pad; + } + if (top < pad) top = pad; + panel.style.left = left + 'px'; + panel.style.top = top + 'px'; + }); + }, + placePanelNear: function(panel, x, y) { + if (!panel) return; + requestAnimationFrame(() => { + const rect = panel.getBoundingClientRect(); + const pad = 8; + const maxX = Math.max(pad, window.innerWidth - rect.width - pad); + const maxY = Math.max(pad, window.innerHeight - rect.height - pad); + let left = x + 12; + let top = y + 12; + if (left > maxX) left = x - rect.width - 12; + if (top > maxY) top = y - rect.height - 12; + left = Math.min(Math.max(pad, left), maxX); + top = Math.min(Math.max(pad, top), maxY); + panel.style.left = left + 'px'; + panel.style.top = top + 'px'; + }); + }, + placeActionPanel: function(stage, panel) { + if (!stage || !panel) return; + requestAnimationFrame(() => { + const stageRect = stage.getBoundingClientRect(); + const panelRect = panel.getBoundingClientRect(); + const pad = 8; + const centerX = stageRect.left + stageRect.width / 2 - panelRect.width / 2; + let top = stageRect.bottom + 12; + let left = centerX; + if (top + panelRect.height > window.innerHeight - pad) { + top = stageRect.top - panelRect.height - 12; + } + left = Math.min(Math.max(pad, left), window.innerWidth - panelRect.width - pad); + top = Math.min(Math.max(pad, top), window.innerHeight - panelRect.height - pad); + panel.style.left = left + 'px'; + panel.style.top = top + 'px'; + }); + }, + setLayout: function(layout, itemsCon, btnHorizontal, btnVertical) { + this.layout = layout === 'column' ? 'column' : 'row'; + itemsCon.classList.toggle('pv-stitch-items-horizontal', this.layout === 'row'); + itemsCon.classList.toggle('pv-stitch-items-vertical', this.layout === 'column'); + btnHorizontal.classList.toggle('active', this.layout === 'row'); + btnVertical.classList.toggle('active', this.layout === 'column'); + }, + loadImageForStitch: function(src) { + return new Promise((resolve, reject) => { + const img = new Image(); + img.crossOrigin = 'anonymous'; + let revoke = null; + const onLoad = () => resolve({img, revoke}); + const onError = () => reject(new Error('load failed')); + img.onload = onLoad; + img.onerror = onError; + if (/^data:|^blob:/i.test(src)) { + img.src = src; + return; + } + _GM_xmlhttpRequest({ + method: 'GET', + url: src, + responseType: 'blob', + onload: (response) => { + if (response.response instanceof Blob) { + const blobUrl = URL.createObjectURL(response.response); + revoke = () => URL.revokeObjectURL(blobUrl); + img.src = blobUrl; + return; + } + img.src = src; + }, + onerror: onError + }); + }); + }, + renderStitch: async function(srcs, layout) { + if (!srcs || !srcs.length) return; + try { + const loaded = await Promise.all(srcs.map(src => this.loadImageForStitch(src))); + let totalW = 0; + let totalH = 0; + if (layout === 'column') { + loaded.forEach(({img}) => { + totalW = Math.max(totalW, img.naturalWidth || img.width); + totalH += img.naturalHeight || img.height; + }); + } else { + loaded.forEach(({img}) => { + totalW += img.naturalWidth || img.width; + totalH = Math.max(totalH, img.naturalHeight || img.height); + }); + } + const canvas = document.createElement('canvas'); + canvas.width = Math.max(1, totalW); + canvas.height = Math.max(1, totalH); + const ctx = canvas.getContext('2d'); + let offset = 0; + loaded.forEach(({img}) => { + const w = img.naturalWidth || img.width; + const h = img.naturalHeight || img.height; + if (layout === 'column') { + ctx.drawImage(img, 0, offset, w, h); + offset += h; + } else { + ctx.drawImage(img, offset, 0, w, h); + offset += w; + } + }); + const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png')); + loaded.forEach(({revoke}) => revoke && revoke()); + if (!blob) return; + const blobUrl = unsafeWindow.URL.createObjectURL(blob); + const outImg = new Image(); + outImg.src = blobUrl; + outImg.title = document.title || ''; + outImg.alt = outImg.title; + const data = {img: outImg, imgSrc: blobUrl, src: blobUrl, srcs: [blobUrl]}; + new ImgWindowC(outImg, data, true); + } catch (e) { + console.warn('[Picviewer CE+] stitch failed', e); + } + } + }; + + var stitcher = new StitcherC(); + var lastPopupLoading; // 载入动画 function LoadingAnimC(data, buttonType, waitImgLoad, openInTopWindow, initPos) { @@ -24109,7 +24742,7 @@ ImgOps | https://imgops.com/#b#`; var container=document.createElement('span'); container.id='pv-float-bar-container'; getBody(document).appendChild(container); - for(let i=0;i<5;i++){ + for(let i=0;i win.remove(true)); + } + if (stitcher) stitcher.openSelect(); + return; + } if (this.data.imgSrc.indexOf("blob:") === 0) { let blobUrl = await getBase64FromBlobUrl(this.data.imgSrc); if (blobUrl) { @@ -27530,6 +28179,12 @@ ImgOps | https://imgops.com/#b#`; } _GM_registerMenuCommand(i18n("openConfig"), openPrefs); _GM_registerMenuCommand(i18n("openGallery"), openGallery); + _GM_registerMenuCommand(i18n("stitch"), () => { + if (ImgWindowC.all && ImgWindowC.all.length) { + ImgWindowC.all.slice(0).forEach(win => win.remove(true)); + } + if (stitcher) stitcher.openSelect(); + }); _GM_registerMenuCommand(i18n("hideIcon") + (hideIcon ? "☑️" : ""), () => { hideIcon=!hideIcon; storage.setListItem("hideIcon", location.hostname, hideIcon); From 29b5494cc727007e8319a0792839e7f2e8dafa0e Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 13 Jan 2026 13:30:22 +0900 Subject: [PATCH 1010/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index f2e12a8cf84..b49a6c450e5 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2026.1.5.1 +// @version 2026.1.13.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://pv.hoothin.com/ @@ -47,7 +47,7 @@ // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js // @require https://update.greasyfork.org/scripts/438080/1714183/pvcep_rules.js -// @require https://update.greasyfork.org/scripts/440698/1653424/pvcep_lang.js +// @require https://update.greasyfork.org/scripts/440698/1733533/pvcep_lang.js // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* From 9a4929966013ac1468b94b66115ed63fdb6084ee Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 13 Jan 2026 04:30:34 +0000 Subject: [PATCH 1011/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 663 ++++++++++++++++++++++++++++++++++++- 1 file changed, 659 insertions(+), 4 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 207a6a3ddf1..5ca8e4bcf44 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2026.1.5.1 +// @version 2026.1.13.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://pv.hoothin.com/ @@ -47,7 +47,7 @@ // @grant unsafeWindow // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=23710 // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1714183 -// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1653424 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1733533 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* @@ -12784,7 +12784,7 @@ ImgOps | https://imgops.com/#b#`; // 默认设置,请到设置界面修改 prefs={ floatBar:{//浮动工具栏相关设置. - butonOrder:['actual','current','gallery','magnifier','download'],//按钮排列顺序'actual'(实际的图片),'current'(当前显示的图片),'magnifier'(放大镜观察),'gallery'(图集),'search'(搜索原图) + butonOrder:['actual','current','gallery','magnifier','download','stitch'],//按钮排列顺序'actual'(实际的图片),'current'(当前显示的图片),'magnifier'(放大镜观察),'gallery'(图集),'search'(搜索原图) additionalFeature: 'open', invertAdditionalFeature: false, listenBg:true,//监听背景图 @@ -12992,6 +12992,7 @@ ImgOps | https://imgops.com/#b#`; gallery:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAP1BMVEUAAAD///94eHgZGRn39/fz8/POzs6xsbGSkpJ9fX1UVFQpKSnb29vJycmmpqafn5+UlJSNjY0/Pz8hISENDQ2fWpEMAAAAcUlEQVQoz43SWQrEIBRE0Xe7M8/T/tcaNSKCKUh95nCDiIaYYa9zUDQRiiaCalANqkE0n6BuBLArWBTUAsa2/3yqfwYdzAl+GeCWAN9YM7nvo4chgoXmgjP8CdoEvqmA/oCQRHgat2p7YM2gvHb9GMRu7acCGLmlyNoAAAAASUVORK5CYII=', search:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAXVBMVEUAAAD///+MjIwmJibNzc2UlJTd3d2lpaUKCgrT09O/v78YGBjj4+MvLy8PDw/IyMh5eXn5+fn29vby8vLo6OjDw8O7u7u3t7ewsLCcnJx1dXVubm4+Pj43NzdkZGStc/JSAAAA4ElEQVQoz52RWW7DMAxE9bR635fYcXr/Y5aW7TYIGqDI/EjUAzRDUvFGCvWn/gHMOnmfNeYFJLonqnPVM8hrIA3B7of5BXkK47bXWwbe/ACp3OWqwSYnaI73+zStSST6AKYjE/sbQCZkpi0j0HSlUl/gPdwleM8SgSfIRzd8laRkcl0oIihYIkiVqhnl6hgicPRGrMHW0Ej4gXCYt8xiPoIw6TtANL8CVtpanSu1xvARJHYnpxpIq6tzU8D8UKIywHCNZCcpUDuXteDL57HngVMhf1nUQ9uisG47y492/kbfyJQHZ5yu1AMAAAAASUVORK5CYII=', download:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAASFBMVEUAAAD///86Ojq8vLxXV1ciIiKcnJympqZjY2MxMTHc3NywsLBDQ0NPT08VFRV5eXn39/fw8PDZ2dnV1dXKysqUlJTl5eUNDQ1EnTQhAAAAtUlEQVQoz33QWRKDIBAE0Gl2AXFP7n/TDKIEk5j+wKp+ZQ0D4SYE+pkDkrMe3rr0ATEYpUkrE+IFouyppJexgRR6IQQAPodlAqeAMyRoByIyjo8DrGpA2Td43YD2FfJHokR2hOsf8uy1v87oZOnrjHorFu7rreoexKLzhiFlqJsPxJL7dcZagWU532oG0ABNzj7y6wpwVAOgJ8AztgyhhTRyM0TsUQ0MuRi3AqaBayp85T/c5AVMKwUv6mnXTQAAAABJRU5ErkJggg==', + stitch:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYAgMAAACdGdVrAAAACVBMVEUAAAD///9XV1cawLSAAAAAKUlEQVQI12MIBQMGBwYgYMRBqQawRgAp0QDWEOwUHu349EGNxqsd6kAArN4RJ/MiMK0AAAAASUVORK5CYII=', downloadSvgBtn:'Download', video:'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDI0IDEwMjQiIHZlcnNpb249IjEuMSI+PHBhdGggZD0iTTUxMiA2NEMyNjUuNiA2NCA2NCAyNjUuNiA2NCA1MTJzMjAxLjYgNDQ4IDQ0OCA0NDggNDQ4LTIwMS42IDQ0OC00NDhTNzU4LjQgNjQgNTEyIDY0ek02OTEuMiA1NDRsLTI1NiAxNTYuOEM0MjguOCA3MDQgNDIyLjQgNzA0IDQxNiA3MDRjLTYuNCAwLTkuNiAwLTE2LTMuMkMzOTAuNCA2OTQuNCAzODQgNjg0LjggMzg0IDY3MkwzODQgMzUyYzAtMTIuOCA2LjQtMjIuNCAxNi0yOC44IDkuNi02LjQgMjIuNC02LjQgMzIgMGwyNTYgMTY2LjRjOS42IDYuNCAxNiAxNiAxNiAyOC44QzcwNCA1MjggNzAwLjggNTQwLjggNjkxLjIgNTQ0eiIgZmlsbD0id2hpdGUiLz48L3N2Zz4=', audio:'data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTc2OCA5MzguNjY2NjY3SDI1NmE4NS4zMzMzMzMgODUuMzMzMzMzIDAgMCAxLTg1LjMzMzMzMy04NS4zMzMzMzRWMTcwLjY2NjY2N2E4NS4zMzMzMzMgODUuMzMzMzMzIDAgMCAxIDg1LjMzMzMzMy04NS4zMzMzMzRoNDIuNjY2NjY3djI5OC42NjY2NjdsMTA2LjY2NjY2Ni02NEw1MTIgMzg0Vjg1LjMzMzMzM2gyNTZhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMSA4NS4zMzMzMzMgODUuMzMzMzM0djY4Mi42NjY2NjZhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMS04NS4zMzMzMzMgODUuMzMzMzM0bS0yMTMuMzMzMzMzLTI5OC42NjY2NjdhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMC04NS4zMzMzMzQgODUuMzMzMzMzIDg1LjMzMzMzMyA4NS4zMzMzMzMgMCAwIDAgODUuMzMzMzM0IDg1LjMzMzMzNCA4NS4zMzMzMzMgODUuMzMzMzMzIDAgMCAwIDg1LjMzMzMzMy04NS4zMzMzMzR2LTIxMy4zMzMzMzNoMTI4di04NS4zMzMzMzNoLTE3MC42NjY2Njd2MjI0Ljg1MzMzM2MtMTIuMzczMzMzLTcuMjUzMzMzLTI3LjMwNjY2Ny0xMS41Mi00Mi42NjY2NjYtMTEuNTJ6IiBmaWxsPSJ3aGl0ZSIvPjwvc3ZnPg==', @@ -13236,6 +13237,22 @@ ImgOps | https://imgops.com/#b#`; } function downloadImg(url, name, type, over) { + if (/^blob:/.test(url)) { + const blob = getBlob(url); + if (blob) { + let ext = blob.type.replace(/.*image\/([\w\-]+).*/, "$1"); + if (ext === "none") ext = "png"; + try { + saveAs(blob, (prefs.saveNameAddTitle ? document.title.replace(/[\*\/:<>\?\\\|]/g, "") + " - " : "") + getRightSaveName(url, name, type, ext)); + over && over(); + return; + } catch (e) { + _GM_download(url, name, type); + over && over(); + return; + } + } + } if(canvas && (/^data:/.test(url) || url.split("/")[2] == document.domain)){ urlToBlobWithFetch(url, (blob, ext)=>{ if(!blob){ @@ -20991,6 +21008,7 @@ ImgOps | https://imgops.com/#b#`; self.remove(); },false); + var maxButton=container.querySelector('.pv-pic-window-max'); maxButton.style.cssText='top: -22px;right: 46px;'; this.maxButton=maxButton; @@ -23626,6 +23644,621 @@ ImgOps | https://imgops.com/#b#`; } }, true); + function StitcherC() { + this.selecting = false; + this.previewing = false; + this.selected = new Set(); + this.overlay = null; + this.preview = null; + this.layout = 'column'; + this.dragging = false; + this.startX = 0; + this.startY = 0; + } + + StitcherC.prototype = { + addStyle: function() { + if (StitcherC.style) { + if (!StitcherC.style.parentNode) { + StitcherC.style = _GM_addStyle(StitcherC.style.innerText); + } + return; + } + StitcherC.style = _GM_addStyle('\ + .pv-stitch-overlay {\ + position: fixed;\ + top: 0;\ + left: 0;\ + width: 100%;\ + height: 100%;\ + z-index:'+(prefs.imgWindow.zIndex + 5)+';\ + pointer-events: none;\ + }\ + .pv-stitch-overlay * {\ + box-sizing: border-box;\ + }\ + .pv-stitch-panel {\ + position: fixed;\ + top: 12px;\ + left: 12px;\ + display: flex;\ + gap: 8px;\ + padding: 6px;\ + background: rgba(0,0,0,0.65);\ + border: 1px solid rgba(255,255,255,0.2);\ + border-radius: 6px;\ + pointer-events: auto;\ + }\ + .pv-stitch-panel-inline {\ + position: absolute;\ + top: 8px;\ + right: 8px;\ + left: auto;\ + }\ + .pv-stitch-action {\ + width: 28px;\ + height: 28px;\ + display: flex;\ + align-items: center;\ + justify-content: center;\ + color: #fff;\ + background: rgba(255,255,255,0.12);\ + border-radius: 4px;\ + cursor: pointer;\ + }\ + .pv-stitch-action:hover {\ + background: rgba(255,255,255,0.25);\ + }\ + .pv-stitch-action.active {\ + background: rgba(255,255,255,0.4);\ + }\ + .pv-stitch-action>svg {\ + width: 18px;\ + height: 18px;\ + fill: none;\ + stroke: currentColor;\ + stroke-width: 3;\ + stroke-linecap: round;\ + stroke-linejoin: round;\ + }\ + .pv-stitch-box {\ + position: fixed;\ + border: 1px dashed rgba(255,255,255,0.9);\ + background: rgba(79,179,255,0.18);\ + pointer-events: none;\ + display: none;\ + }\ + .pv-stitch-selected {\ + outline: 3px solid rgba(79,179,255,0.95);\ + outline-offset: -3px;\ + box-shadow: 0 0 0 3px rgba(79,179,255,0.9), 0 0 12px rgba(79,179,255,0.85);\ + filter: brightness(0.78) saturate(1.15);\ + }\ + .pv-stitch-selected-parent {\ + outline: 3px solid rgba(79,179,255,0.95);\ + outline-offset: -3px;\ + box-shadow: 0 0 0 3px rgba(79,179,255,0.9), 0 0 12px rgba(79,179,255,0.85);\ + }\ + .pv-stitch-preview {\ + pointer-events: auto;\ + background: rgba(0,0,0,0.6);\ + }\ + .pv-stitch-stage {\ + position: fixed;\ + top: 50%;\ + left: 50%;\ + transform: translate(-50%, -50%);\ + max-width: 90vw;\ + max-height: 80vh;\ + overflow: auto;\ + padding: 12px;\ + background: rgba(0,0,0,0.75);\ + border: 1px solid rgba(255,255,255,0.2);\ + border-radius: 8px;\ + pointer-events: auto;\ + }\ + .pv-stitch-items {\ + display: flex;\ + gap: 10px;\ + }\ + .pv-stitch-items-horizontal {\ + flex-direction: row;\ + }\ + .pv-stitch-items-vertical {\ + flex-direction: column;\ + }\ + .pv-stitch-item {\ + padding: 6px;\ + background: rgba(0,0,0,0.55);\ + border: 1px solid rgba(255,255,255,0.2);\ + border-radius: 6px;\ + cursor: move;\ + }\ + .pv-stitch-item.dragging {\ + opacity: 0.4;\ + }\ + .pv-stitch-item img {\ + display: block;\ + max-width: 220px;\ + max-height: 220px;\ + }\ + .pv-stitch-selecting, .pv-stitch-selecting * {\ + user-select: none;\ + }\ + '); + }, + openSelect: function() { + if (this.selecting || this.previewing) return; + this.addStyle(); + this.selecting = true; + if (floatBar) floatBar.hide(); + document.documentElement.classList.add('pv-stitch-selecting'); + const overlay = document.createElement('div'); + overlay.className = 'pv-stitch-overlay pv-stitch-select'; + overlay.innerHTML = createHTML( + '
      '+ + '
      '+ + ''+ + '
      '+ + '
      '+ + ''+ + '
      '+ + '
      '+ + '
      ' + ); + document.body.appendChild(overlay); + this.overlay = overlay; + this.box = overlay.querySelector('.pv-stitch-box'); + const panel = overlay.querySelector('.pv-stitch-panel'); + this.placePanel(panel); + overlay.querySelector('.pv-stitch-action-done').addEventListener('click', () => { + if (!this.selected.size) { + this.closeSelect(); + return; + } + const selected = Array.from(this.selected); + this.closeSelect(false); + this.openPreview(selected); + }); + overlay.querySelector('.pv-stitch-action-cancel').addEventListener('click', () => { + this.closeSelect(); + }); + + this.onSelectMouseDown = (e) => { + if (!this.selecting) return; + if (panel.contains(e.target)) return; + if (e.button !== 0 && e.button !== 2) return; + e.preventDefault(); + e.stopPropagation(); + this.dragging = true; + panel.style.display = 'none'; + this.dragMode = (e.button === 2 || e.altKey || e.shiftKey) ? 'remove' : 'add'; + this.startX = e.clientX; + this.startY = e.clientY; + this.updateBox(e.clientX, e.clientY); + this.box.style.display = 'block'; + }; + this.onSelectMouseMove = (e) => { + if (!this.dragging) return; + e.preventDefault(); + e.stopPropagation(); + this.updateBox(e.clientX, e.clientY); + }; + this.onSelectMouseUp = (e) => { + if (!this.dragging) return; + e.preventDefault(); + e.stopPropagation(); + this.dragging = false; + const rect = this.getBoxRect(e.clientX, e.clientY); + this.box.style.display = 'none'; + if (rect.width < 4 && rect.height < 4) { + const img = this.findImageAt(e.clientX, e.clientY); + if (img) this.toggleSelection(img, this.dragMode); + panel.style.display = ''; + this.placePanelNear(panel, e.clientX, e.clientY); + return; + } + this.applySelection(rect, this.dragMode); + panel.style.display = ''; + this.placePanelNear(panel, e.clientX, e.clientY); + }; + this.onSelectClick = (e) => { + if (!this.selecting) return; + if (panel.contains(e.target)) return; + e.preventDefault(); + e.stopPropagation(); + }; + this.onSelectContext = (e) => { + if (!this.selecting) return; + if (panel.contains(e.target)) return; + e.preventDefault(); + e.stopPropagation(); + }; + this.onKeyDown = (e) => { + if (e.key !== 'Escape') return; + if (this.selecting) this.closeSelect(); + if (this.previewing) this.closePreview(); + }; + document.addEventListener('mousedown', this.onSelectMouseDown, true); + document.addEventListener('mousemove', this.onSelectMouseMove, true); + document.addEventListener('mouseup', this.onSelectMouseUp, true); + document.addEventListener('click', this.onSelectClick, true); + document.addEventListener('contextmenu', this.onSelectContext, true); + document.addEventListener('keydown', this.onKeyDown, true); + }, + closeSelect: function(clear = true) { + if (!this.selecting) return; + this.selecting = false; + document.documentElement.classList.remove('pv-stitch-selecting'); + if (this.overlay && this.overlay.parentNode) { + this.overlay.parentNode.removeChild(this.overlay); + } + this.overlay = null; + this.box = null; + if (clear) this.clearSelection(); + document.removeEventListener('mousedown', this.onSelectMouseDown, true); + document.removeEventListener('mousemove', this.onSelectMouseMove, true); + document.removeEventListener('mouseup', this.onSelectMouseUp, true); + document.removeEventListener('click', this.onSelectClick, true); + document.removeEventListener('contextmenu', this.onSelectContext, true); + if (!this.previewing) document.removeEventListener('keydown', this.onKeyDown, true); + }, + clearSelection: function() { + this.selected.forEach((img) => { + img.classList.remove('pv-stitch-selected'); + this.toggleParentClass(img, false); + }); + this.selected.clear(); + }, + updateBox: function(x, y) { + const rect = this.getBoxRect(x, y); + this.box.style.left = rect.left + 'px'; + this.box.style.top = rect.top + 'px'; + this.box.style.width = rect.width + 'px'; + this.box.style.height = rect.height + 'px'; + }, + getBoxRect: function(x, y) { + const left = Math.min(this.startX, x); + const top = Math.min(this.startY, y); + const width = Math.abs(this.startX - x); + const height = Math.abs(this.startY - y); + return {left, top, width, height, right: left + width, bottom: top + height}; + }, + applySelection: function(rect, mode) { + const imgs = this.getSelectableImages(); + imgs.forEach((img) => { + const r = img.getBoundingClientRect(); + if (rect.right < r.left || rect.left > r.right || rect.bottom < r.top || rect.top > r.bottom) return; + if (mode === 'remove') this.removeSelection(img); + else this.addSelection(img); + }); + }, + addSelection: function(img) { + if (this.selected.has(img)) return; + this.selected.add(img); + img.classList.add('pv-stitch-selected'); + this.toggleParentClass(img, true); + }, + removeSelection: function(img) { + if (!this.selected.has(img)) return; + this.selected.delete(img); + img.classList.remove('pv-stitch-selected'); + this.toggleParentClass(img, false); + }, + toggleSelection: function(img, mode) { + if (mode === 'remove') { + this.removeSelection(img); + return; + } + if (this.selected.has(img)) this.removeSelection(img); + else this.addSelection(img); + }, + toggleParentClass: function(img, isAdd) { + const parent = img && img.parentNode; + if (!parent || parent.nodeType !== 1) return; + const tag = parent.tagName; + if (tag === 'BODY' || tag === 'HTML') return; + parent.classList.toggle('pv-stitch-selected-parent', isAdd); + }, + findImageAt: function(x, y) { + const els = document.elementsFromPoint(x, y); + for (let i = 0; i < els.length; i++) { + const el = els[i]; + if (this.overlay && this.overlay.contains(el)) continue; + if (el.tagName === 'IMG') return el; + } + return null; + }, + getSelectableImages: function() { + const imgs = document.querySelectorAll('img'); + const list = []; + for (let i = 0; i < imgs.length; i++) { + const img = imgs[i]; + if (!img.src && !img.currentSrc) continue; + const style = unsafeWindow.getComputedStyle(img); + if (style.display === 'none' || style.visibility === 'hidden') continue; + const rect = img.getBoundingClientRect(); + if (rect.width < 4 || rect.height < 4) continue; + list.push(img); + } + return list; + }, + getImgSrc: function(img) { + const original = this.getOriginalImgSrc(img); + if (original) return original; + return img.currentSrc || img.src || img.getAttribute('data-src') || img.getAttribute('data-original') || img.getAttribute('data-lazy-src') || img.getAttribute('data-zoom-image') || img.getAttribute('data-large'); + }, + getOriginalImgSrc: function(img) { + if (!img) return ""; + let imgPA, imgPE = []; + let imgPN = img.parentNode; + while (imgPN && imgPN.nodeType === 1 && imgPN.nodeName !== "BODY") { + if (!imgPA && imgPN.nodeName === "A") imgPA = imgPN; + imgPE.push(imgPN); + imgPN = imgPN.parentNode; + } + try { + if (matchedRule && matchedRule.rules && matchedRule.rules.length > 0 && matchedRule.getImage) { + let src = matchedRule.getImage(img, imgPA, imgPE); + if (Array.isArray(src)) src = src[0]; + if (src && src !== img.src) return src; + } + } catch (e) {} + try { + if (tprules && tprules[0]) { + const src = tprules[0].call(img); + if (src) return src; + } + } catch (e) {} + if (imgPA && imgPA.href && imageReg.test(imgPA.href) && imgPA.href !== img.src) { + return imgPA.href; + } + return ""; + }, + openPreview: function(selected) { + const srcs = []; + selected.forEach((img) => { + const src = this.getImgSrc(img); + if (src) srcs.push(src); + img.classList.remove('pv-stitch-selected'); + this.toggleParentClass(img, false); + }); + this.selected.clear(); + if (!srcs.length) return; + if (this.previewing) return; + this.previewing = true; + this.addStyle(); + const overlay = document.createElement('div'); + overlay.className = 'pv-stitch-overlay pv-stitch-preview'; + const isVertical = this.layout === 'column'; + overlay.innerHTML = createHTML( + '
      '+ + '
      '+ + '
      '+ + ''+ + '
      '+ + '
      '+ + ''+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + '
      '+ + ''+ + '
      '+ + '
      '+ + ''+ + '
      '+ + '
      ' + ); + document.body.appendChild(overlay); + this.preview = overlay; + const itemsCon = overlay.querySelector('.pv-stitch-items'); + const stage = overlay.querySelector('.pv-stitch-stage'); + const actionPanel = overlay.querySelector('.pv-stitch-panel-action'); + this.placeActionPanel(stage, actionPanel); + srcs.forEach((src) => { + const item = document.createElement('div'); + item.className = 'pv-stitch-item'; + item.setAttribute('draggable', 'true'); + item.dataset.src = src; + const img = document.createElement('img'); + img.src = src; + img.addEventListener('load', () => this.placeActionPanel(stage, actionPanel)); + item.appendChild(img); + itemsCon.appendChild(item); + }); + setTimeout(() => this.placeActionPanel(stage, actionPanel), 0); + let dragItem = null; + itemsCon.addEventListener('dragstart', (e) => { + const item = e.target.closest('.pv-stitch-item'); + if (!item) return; + dragItem = item; + dragItem.classList.add('dragging'); + e.dataTransfer.effectAllowed = 'move'; + }); + itemsCon.addEventListener('dragend', () => { + if (dragItem) dragItem.classList.remove('dragging'); + dragItem = null; + }); + itemsCon.addEventListener('dragover', (e) => { + if (!dragItem) return; + const target = e.target.closest('.pv-stitch-item'); + if (!target || target === dragItem) return; + e.preventDefault(); + const rect = target.getBoundingClientRect(); + const before = this.layout === 'row' ? e.clientX < rect.left + rect.width / 2 : e.clientY < rect.top + rect.height / 2; + itemsCon.insertBefore(dragItem, before ? target : target.nextSibling); + }); + + const btnHorizontal = overlay.querySelector('.pv-stitch-action-horizontal'); + const btnVertical = overlay.querySelector('.pv-stitch-action-vertical'); + btnHorizontal.addEventListener('click', () => { + this.setLayout('row', itemsCon, btnHorizontal, btnVertical); + this.placeActionPanel(stage, actionPanel); + }); + btnVertical.addEventListener('click', () => { + this.setLayout('column', itemsCon, btnHorizontal, btnVertical); + this.placeActionPanel(stage, actionPanel); + }); + overlay.querySelector('.pv-stitch-action-done').addEventListener('click', async () => { + const ordered = Array.from(itemsCon.querySelectorAll('.pv-stitch-item')).map(item => item.dataset.src); + this.closePreview(); + await this.renderStitch(ordered, this.layout); + }); + overlay.querySelector('.pv-stitch-action-cancel').addEventListener('click', () => { + this.closePreview(); + }); + document.addEventListener('keydown', this.onKeyDown, true); + }, + closePreview: function() { + if (!this.previewing) return; + this.previewing = false; + if (this.preview && this.preview.parentNode) { + this.preview.parentNode.removeChild(this.preview); + } + this.preview = null; + if (!this.selecting) document.removeEventListener('keydown', this.onKeyDown, true); + }, + placePanel: function(panel) { + if (!panel) return; + requestAnimationFrame(() => { + const rect = panel.getBoundingClientRect(); + const pad = 8; + const left = Math.min(Math.max(pad, (window.innerWidth - rect.width) / 2), window.innerWidth - rect.width - pad); + let top = Math.round(window.innerHeight * 0.72); + if (top + rect.height > window.innerHeight - pad) { + top = window.innerHeight - rect.height - pad; + } + if (top < pad) top = pad; + panel.style.left = left + 'px'; + panel.style.top = top + 'px'; + }); + }, + placePanelNear: function(panel, x, y) { + if (!panel) return; + requestAnimationFrame(() => { + const rect = panel.getBoundingClientRect(); + const pad = 8; + const maxX = Math.max(pad, window.innerWidth - rect.width - pad); + const maxY = Math.max(pad, window.innerHeight - rect.height - pad); + let left = x + 12; + let top = y + 12; + if (left > maxX) left = x - rect.width - 12; + if (top > maxY) top = y - rect.height - 12; + left = Math.min(Math.max(pad, left), maxX); + top = Math.min(Math.max(pad, top), maxY); + panel.style.left = left + 'px'; + panel.style.top = top + 'px'; + }); + }, + placeActionPanel: function(stage, panel) { + if (!stage || !panel) return; + requestAnimationFrame(() => { + const stageRect = stage.getBoundingClientRect(); + const panelRect = panel.getBoundingClientRect(); + const pad = 8; + const centerX = stageRect.left + stageRect.width / 2 - panelRect.width / 2; + let top = stageRect.bottom + 12; + let left = centerX; + if (top + panelRect.height > window.innerHeight - pad) { + top = stageRect.top - panelRect.height - 12; + } + left = Math.min(Math.max(pad, left), window.innerWidth - panelRect.width - pad); + top = Math.min(Math.max(pad, top), window.innerHeight - panelRect.height - pad); + panel.style.left = left + 'px'; + panel.style.top = top + 'px'; + }); + }, + setLayout: function(layout, itemsCon, btnHorizontal, btnVertical) { + this.layout = layout === 'column' ? 'column' : 'row'; + itemsCon.classList.toggle('pv-stitch-items-horizontal', this.layout === 'row'); + itemsCon.classList.toggle('pv-stitch-items-vertical', this.layout === 'column'); + btnHorizontal.classList.toggle('active', this.layout === 'row'); + btnVertical.classList.toggle('active', this.layout === 'column'); + }, + loadImageForStitch: function(src) { + return new Promise((resolve, reject) => { + const img = new Image(); + img.crossOrigin = 'anonymous'; + let revoke = null; + const onLoad = () => resolve({img, revoke}); + const onError = () => reject(new Error('load failed')); + img.onload = onLoad; + img.onerror = onError; + if (/^data:|^blob:/i.test(src)) { + img.src = src; + return; + } + _GM_xmlhttpRequest({ + method: 'GET', + url: src, + responseType: 'blob', + onload: (response) => { + if (response.response instanceof Blob) { + const blobUrl = URL.createObjectURL(response.response); + revoke = () => URL.revokeObjectURL(blobUrl); + img.src = blobUrl; + return; + } + img.src = src; + }, + onerror: onError + }); + }); + }, + renderStitch: async function(srcs, layout) { + if (!srcs || !srcs.length) return; + try { + const loaded = await Promise.all(srcs.map(src => this.loadImageForStitch(src))); + let totalW = 0; + let totalH = 0; + if (layout === 'column') { + loaded.forEach(({img}) => { + totalW = Math.max(totalW, img.naturalWidth || img.width); + totalH += img.naturalHeight || img.height; + }); + } else { + loaded.forEach(({img}) => { + totalW += img.naturalWidth || img.width; + totalH = Math.max(totalH, img.naturalHeight || img.height); + }); + } + const canvas = document.createElement('canvas'); + canvas.width = Math.max(1, totalW); + canvas.height = Math.max(1, totalH); + const ctx = canvas.getContext('2d'); + let offset = 0; + loaded.forEach(({img}) => { + const w = img.naturalWidth || img.width; + const h = img.naturalHeight || img.height; + if (layout === 'column') { + ctx.drawImage(img, 0, offset, w, h); + offset += h; + } else { + ctx.drawImage(img, offset, 0, w, h); + offset += w; + } + }); + const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png')); + loaded.forEach(({revoke}) => revoke && revoke()); + if (!blob) return; + const blobUrl = unsafeWindow.URL.createObjectURL(blob); + const outImg = new Image(); + outImg.src = blobUrl; + outImg.title = document.title || ''; + outImg.alt = outImg.title; + const data = {img: outImg, imgSrc: blobUrl, src: blobUrl, srcs: [blobUrl]}; + new ImgWindowC(outImg, data, true); + } catch (e) { + console.warn('[Picviewer CE+] stitch failed', e); + } + } + }; + + var stitcher = new StitcherC(); + var lastPopupLoading; // 载入动画 function LoadingAnimC(data, buttonType, waitImgLoad, openInTopWindow, initPos) { @@ -24109,7 +24742,7 @@ ImgOps | https://imgops.com/#b#`; var container=document.createElement('span'); container.id='pv-float-bar-container'; getBody(document).appendChild(container); - for(let i=0;i<5;i++){ + for(let i=0;i win.remove(true)); + } + if (stitcher) stitcher.openSelect(); + return; + } if (this.data.imgSrc.indexOf("blob:") === 0) { let blobUrl = await getBase64FromBlobUrl(this.data.imgSrc); if (blobUrl) { @@ -27530,6 +28179,12 @@ ImgOps | https://imgops.com/#b#`; } _GM_registerMenuCommand(i18n("openConfig"), openPrefs); _GM_registerMenuCommand(i18n("openGallery"), openGallery); + _GM_registerMenuCommand(i18n("stitch"), () => { + if (ImgWindowC.all && ImgWindowC.all.length) { + ImgWindowC.all.slice(0).forEach(win => win.remove(true)); + } + if (stitcher) stitcher.openSelect(); + }); _GM_registerMenuCommand(i18n("hideIcon") + (hideIcon ? "☑️" : ""), () => { hideIcon=!hideIcon; storage.setListItem("hideIcon", location.hostname, hideIcon); From 24d209fab8700ffa90905187533a8e02709250a5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 13 Jan 2026 13:40:24 +0900 Subject: [PATCH 1012/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index b49a6c450e5..e9ed452c7bb 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -24165,6 +24165,9 @@ ImgOps | https://imgops.com/#b#`; if (top + panelRect.height > window.innerHeight - pad) { top = stageRect.top - panelRect.height - 12; } + if (top + panelRect.height > window.innerHeight - pad || top < pad) { + top = window.innerHeight - panelRect.height - pad; + } left = Math.min(Math.max(pad, left), window.innerWidth - panelRect.width - pad); top = Math.min(Math.max(pad, top), window.innerHeight - panelRect.height - pad); panel.style.left = left + 'px'; From f35b1d7166aa90ffe66698e97e1cea9e8a878401 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 13 Jan 2026 05:01:31 +0000 Subject: [PATCH 1013/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 5ca8e4bcf44..f0ee22da405 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -24165,6 +24165,9 @@ ImgOps | https://imgops.com/#b#`; if (top + panelRect.height > window.innerHeight - pad) { top = stageRect.top - panelRect.height - 12; } + if (top + panelRect.height > window.innerHeight - pad || top < pad) { + top = window.innerHeight - panelRect.height - pad; + } left = Math.min(Math.max(pad, left), window.innerWidth - panelRect.width - pad); top = Math.min(Math.max(pad, top), window.innerHeight - panelRect.height - pad); panel.style.left = left + 'px'; From 8b008d9d1c7ccc8857d6cd712bb6477f50381e09 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 13 Jan 2026 16:09:41 +0900 Subject: [PATCH 1014/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 118 +++++++++++++++++----------- 1 file changed, 73 insertions(+), 45 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index e9ed452c7bb..69b14bfd5a8 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -23984,8 +23984,6 @@ ImgOps | https://imgops.com/#b#`; return list; }, getImgSrc: function(img) { - const original = this.getOriginalImgSrc(img); - if (original) return original; return img.currentSrc || img.src || img.getAttribute('data-src') || img.getAttribute('data-original') || img.getAttribute('data-lazy-src') || img.getAttribute('data-zoom-image') || img.getAttribute('data-large'); }, getOriginalImgSrc: function(img) { @@ -24016,15 +24014,22 @@ ImgOps | https://imgops.com/#b#`; return ""; }, openPreview: function(selected) { - const srcs = []; + const sources = []; selected.forEach((img) => { - const src = this.getImgSrc(img); - if (src) srcs.push(src); + const current = this.getImgSrc(img); + const original = this.getOriginalImgSrc(img); + const displaySrc = current || original; + if (displaySrc) { + sources.push({ + current: displaySrc, + original: original && original !== displaySrc ? original : '' + }); + } img.classList.remove('pv-stitch-selected'); this.toggleParentClass(img, false); }); this.selected.clear(); - if (!srcs.length) return; + if (!sources.length) return; if (this.previewing) return; this.previewing = true; this.addStyle(); @@ -24058,13 +24063,14 @@ ImgOps | https://imgops.com/#b#`; const stage = overlay.querySelector('.pv-stitch-stage'); const actionPanel = overlay.querySelector('.pv-stitch-panel-action'); this.placeActionPanel(stage, actionPanel); - srcs.forEach((src) => { + sources.forEach((source) => { const item = document.createElement('div'); item.className = 'pv-stitch-item'; item.setAttribute('draggable', 'true'); - item.dataset.src = src; + item.dataset.src = source.current; + if (source.original) item.dataset.original = source.original; const img = document.createElement('img'); - img.src = src; + img.src = source.current; img.addEventListener('load', () => this.placeActionPanel(stage, actionPanel)); item.appendChild(img); itemsCon.appendChild(item); @@ -24103,7 +24109,10 @@ ImgOps | https://imgops.com/#b#`; this.placeActionPanel(stage, actionPanel); }); overlay.querySelector('.pv-stitch-action-done').addEventListener('click', async () => { - const ordered = Array.from(itemsCon.querySelectorAll('.pv-stitch-item')).map(item => item.dataset.src); + const ordered = Array.from(itemsCon.querySelectorAll('.pv-stitch-item')).map(item => ({ + current: item.dataset.src, + original: item.dataset.original || '' + })); this.closePreview(); await this.renderStitch(ordered, this.layout); }); @@ -24211,49 +24220,68 @@ ImgOps | https://imgops.com/#b#`; }); }); }, - renderStitch: async function(srcs, layout) { - if (!srcs || !srcs.length) return; - try { - const loaded = await Promise.all(srcs.map(src => this.loadImageForStitch(src))); - let totalW = 0; - let totalH = 0; + createStitchBlobUrl: async function(srcs, layout) { + const loaded = await Promise.all(srcs.map(src => this.loadImageForStitch(src))); + let totalW = 0; + let totalH = 0; + if (layout === 'column') { + loaded.forEach(({img}) => { + totalW = Math.max(totalW, img.naturalWidth || img.width); + totalH += img.naturalHeight || img.height; + }); + } else { + loaded.forEach(({img}) => { + totalW += img.naturalWidth || img.width; + totalH = Math.max(totalH, img.naturalHeight || img.height); + }); + } + const canvas = document.createElement('canvas'); + canvas.width = Math.max(1, totalW); + canvas.height = Math.max(1, totalH); + const ctx = canvas.getContext('2d'); + let offset = 0; + loaded.forEach(({img}) => { + const w = img.naturalWidth || img.width; + const h = img.naturalHeight || img.height; if (layout === 'column') { - loaded.forEach(({img}) => { - totalW = Math.max(totalW, img.naturalWidth || img.width); - totalH += img.naturalHeight || img.height; - }); + ctx.drawImage(img, 0, offset, w, h); + offset += h; } else { - loaded.forEach(({img}) => { - totalW += img.naturalWidth || img.width; - totalH = Math.max(totalH, img.naturalHeight || img.height); - }); + ctx.drawImage(img, offset, 0, w, h); + offset += w; } - const canvas = document.createElement('canvas'); - canvas.width = Math.max(1, totalW); - canvas.height = Math.max(1, totalH); - const ctx = canvas.getContext('2d'); - let offset = 0; - loaded.forEach(({img}) => { - const w = img.naturalWidth || img.width; - const h = img.naturalHeight || img.height; - if (layout === 'column') { - ctx.drawImage(img, 0, offset, w, h); - offset += h; - } else { - ctx.drawImage(img, offset, 0, w, h); - offset += w; - } - }); - const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png')); - loaded.forEach(({revoke}) => revoke && revoke()); - if (!blob) return; - const blobUrl = unsafeWindow.URL.createObjectURL(blob); + }); + const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png')); + loaded.forEach(({revoke}) => revoke && revoke()); + if (!blob) return ''; + return unsafeWindow.URL.createObjectURL(blob); + }, + renderStitch: async function(items, layout) { + if (!items || !items.length) return; + try { + const currentSrcs = items.map(item => item.current || item.src || item); + if (currentSrcs.some(src => !src)) return; + const blobUrl = await this.createStitchBlobUrl(currentSrcs, layout); + if (!blobUrl) return; const outImg = new Image(); outImg.src = blobUrl; outImg.title = document.title || ''; outImg.alt = outImg.title; const data = {img: outImg, imgSrc: blobUrl, src: blobUrl, srcs: [blobUrl]}; - new ImgWindowC(outImg, data, true); + const imgWin = new ImgWindowC(outImg, data, true); + const finalSrcs = items.map((item, index) => item.original || currentSrcs[index]); + const needsReplace = finalSrcs.some((src, index) => src && src !== currentSrcs[index]); + if (!needsReplace) return; + this.createStitchBlobUrl(finalSrcs, layout).then((finalBlobUrl) => { + if (!finalBlobUrl) return; + if (!imgWin || imgWin.removed) { + unsafeWindow.URL.revokeObjectURL(finalBlobUrl); + return; + } + imgWin.changeData({img: imgWin.img, imgSrc: finalBlobUrl, src: finalBlobUrl, srcs: [finalBlobUrl]}); + }).catch((e) => { + console.warn('[Picviewer CE+] stitch replace failed', e); + }); } catch (e) { console.warn('[Picviewer CE+] stitch failed', e); } From c8320dd05cd0416c308486a00bf91f16fe7c47c7 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 13 Jan 2026 07:09:58 +0000 Subject: [PATCH 1015/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 118 +++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 45 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index f0ee22da405..427fe3c7eda 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -23984,8 +23984,6 @@ ImgOps | https://imgops.com/#b#`; return list; }, getImgSrc: function(img) { - const original = this.getOriginalImgSrc(img); - if (original) return original; return img.currentSrc || img.src || img.getAttribute('data-src') || img.getAttribute('data-original') || img.getAttribute('data-lazy-src') || img.getAttribute('data-zoom-image') || img.getAttribute('data-large'); }, getOriginalImgSrc: function(img) { @@ -24016,15 +24014,22 @@ ImgOps | https://imgops.com/#b#`; return ""; }, openPreview: function(selected) { - const srcs = []; + const sources = []; selected.forEach((img) => { - const src = this.getImgSrc(img); - if (src) srcs.push(src); + const current = this.getImgSrc(img); + const original = this.getOriginalImgSrc(img); + const displaySrc = current || original; + if (displaySrc) { + sources.push({ + current: displaySrc, + original: original && original !== displaySrc ? original : '' + }); + } img.classList.remove('pv-stitch-selected'); this.toggleParentClass(img, false); }); this.selected.clear(); - if (!srcs.length) return; + if (!sources.length) return; if (this.previewing) return; this.previewing = true; this.addStyle(); @@ -24058,13 +24063,14 @@ ImgOps | https://imgops.com/#b#`; const stage = overlay.querySelector('.pv-stitch-stage'); const actionPanel = overlay.querySelector('.pv-stitch-panel-action'); this.placeActionPanel(stage, actionPanel); - srcs.forEach((src) => { + sources.forEach((source) => { const item = document.createElement('div'); item.className = 'pv-stitch-item'; item.setAttribute('draggable', 'true'); - item.dataset.src = src; + item.dataset.src = source.current; + if (source.original) item.dataset.original = source.original; const img = document.createElement('img'); - img.src = src; + img.src = source.current; img.addEventListener('load', () => this.placeActionPanel(stage, actionPanel)); item.appendChild(img); itemsCon.appendChild(item); @@ -24103,7 +24109,10 @@ ImgOps | https://imgops.com/#b#`; this.placeActionPanel(stage, actionPanel); }); overlay.querySelector('.pv-stitch-action-done').addEventListener('click', async () => { - const ordered = Array.from(itemsCon.querySelectorAll('.pv-stitch-item')).map(item => item.dataset.src); + const ordered = Array.from(itemsCon.querySelectorAll('.pv-stitch-item')).map(item => ({ + current: item.dataset.src, + original: item.dataset.original || '' + })); this.closePreview(); await this.renderStitch(ordered, this.layout); }); @@ -24211,49 +24220,68 @@ ImgOps | https://imgops.com/#b#`; }); }); }, - renderStitch: async function(srcs, layout) { - if (!srcs || !srcs.length) return; - try { - const loaded = await Promise.all(srcs.map(src => this.loadImageForStitch(src))); - let totalW = 0; - let totalH = 0; + createStitchBlobUrl: async function(srcs, layout) { + const loaded = await Promise.all(srcs.map(src => this.loadImageForStitch(src))); + let totalW = 0; + let totalH = 0; + if (layout === 'column') { + loaded.forEach(({img}) => { + totalW = Math.max(totalW, img.naturalWidth || img.width); + totalH += img.naturalHeight || img.height; + }); + } else { + loaded.forEach(({img}) => { + totalW += img.naturalWidth || img.width; + totalH = Math.max(totalH, img.naturalHeight || img.height); + }); + } + const canvas = document.createElement('canvas'); + canvas.width = Math.max(1, totalW); + canvas.height = Math.max(1, totalH); + const ctx = canvas.getContext('2d'); + let offset = 0; + loaded.forEach(({img}) => { + const w = img.naturalWidth || img.width; + const h = img.naturalHeight || img.height; if (layout === 'column') { - loaded.forEach(({img}) => { - totalW = Math.max(totalW, img.naturalWidth || img.width); - totalH += img.naturalHeight || img.height; - }); + ctx.drawImage(img, 0, offset, w, h); + offset += h; } else { - loaded.forEach(({img}) => { - totalW += img.naturalWidth || img.width; - totalH = Math.max(totalH, img.naturalHeight || img.height); - }); + ctx.drawImage(img, offset, 0, w, h); + offset += w; } - const canvas = document.createElement('canvas'); - canvas.width = Math.max(1, totalW); - canvas.height = Math.max(1, totalH); - const ctx = canvas.getContext('2d'); - let offset = 0; - loaded.forEach(({img}) => { - const w = img.naturalWidth || img.width; - const h = img.naturalHeight || img.height; - if (layout === 'column') { - ctx.drawImage(img, 0, offset, w, h); - offset += h; - } else { - ctx.drawImage(img, offset, 0, w, h); - offset += w; - } - }); - const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png')); - loaded.forEach(({revoke}) => revoke && revoke()); - if (!blob) return; - const blobUrl = unsafeWindow.URL.createObjectURL(blob); + }); + const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png')); + loaded.forEach(({revoke}) => revoke && revoke()); + if (!blob) return ''; + return unsafeWindow.URL.createObjectURL(blob); + }, + renderStitch: async function(items, layout) { + if (!items || !items.length) return; + try { + const currentSrcs = items.map(item => item.current || item.src || item); + if (currentSrcs.some(src => !src)) return; + const blobUrl = await this.createStitchBlobUrl(currentSrcs, layout); + if (!blobUrl) return; const outImg = new Image(); outImg.src = blobUrl; outImg.title = document.title || ''; outImg.alt = outImg.title; const data = {img: outImg, imgSrc: blobUrl, src: blobUrl, srcs: [blobUrl]}; - new ImgWindowC(outImg, data, true); + const imgWin = new ImgWindowC(outImg, data, true); + const finalSrcs = items.map((item, index) => item.original || currentSrcs[index]); + const needsReplace = finalSrcs.some((src, index) => src && src !== currentSrcs[index]); + if (!needsReplace) return; + this.createStitchBlobUrl(finalSrcs, layout).then((finalBlobUrl) => { + if (!finalBlobUrl) return; + if (!imgWin || imgWin.removed) { + unsafeWindow.URL.revokeObjectURL(finalBlobUrl); + return; + } + imgWin.changeData({img: imgWin.img, imgSrc: finalBlobUrl, src: finalBlobUrl, srcs: [finalBlobUrl]}); + }).catch((e) => { + console.warn('[Picviewer CE+] stitch replace failed', e); + }); } catch (e) { console.warn('[Picviewer CE+] stitch failed', e); } From 4b73ec962e79cd8cb106d413364646577399bf82 Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 17 Jan 2026 18:26:04 +0900 Subject: [PATCH 1016/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 47 ++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 69b14bfd5a8..b11d15cc288 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2026.1.13.1 +// @version 2026.1.17.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://pv.hoothin.com/ @@ -24224,15 +24224,33 @@ ImgOps | https://imgops.com/#b#`; const loaded = await Promise.all(srcs.map(src => this.loadImageForStitch(src))); let totalW = 0; let totalH = 0; + let maxW = 0; + let maxH = 0; + loaded.forEach(({img}) => { + const w = img.naturalWidth || img.width; + const h = img.naturalHeight || img.height; + if (w > maxW) maxW = w; + if (h > maxH) maxH = h; + }); if (layout === 'column') { loaded.forEach(({img}) => { - totalW = Math.max(totalW, img.naturalWidth || img.width); - totalH += img.naturalHeight || img.height; + const w = img.naturalWidth || img.width; + const h = img.naturalHeight || img.height; + const ratio = w ? (maxW / w) : 1; + const drawW = maxW || w; + const drawH = h * ratio; + totalW = Math.max(totalW, drawW); + totalH += drawH; }); } else { loaded.forEach(({img}) => { - totalW += img.naturalWidth || img.width; - totalH = Math.max(totalH, img.naturalHeight || img.height); + const w = img.naturalWidth || img.width; + const h = img.naturalHeight || img.height; + const ratio = h ? (maxH / h) : 1; + const drawH = maxH || h; + const drawW = w * ratio; + totalW += drawW; + totalH = Math.max(totalH, drawH); }); } const canvas = document.createElement('canvas'); @@ -24244,11 +24262,17 @@ ImgOps | https://imgops.com/#b#`; const w = img.naturalWidth || img.width; const h = img.naturalHeight || img.height; if (layout === 'column') { - ctx.drawImage(img, 0, offset, w, h); - offset += h; + const ratio = w ? (maxW / w) : 1; + const drawW = maxW || w; + const drawH = h * ratio; + ctx.drawImage(img, 0, offset, drawW, drawH); + offset += drawH; } else { - ctx.drawImage(img, offset, 0, w, h); - offset += w; + const ratio = h ? (maxH / h) : 1; + const drawH = maxH || h; + const drawW = w * ratio; + ctx.drawImage(img, offset, 0, drawW, drawH); + offset += drawW; } }); const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png')); @@ -28266,7 +28290,7 @@ ImgOps | https://imgops.com/#b#`; var configStyle = document.createElement("style"); configStyle.textContent = "#pv-prefs { display: initial; }"; configStyle.type = 'text/css'; - if (location.hostname == "hoothin.github.io" && location.pathname == "/UserScripts/Picviewer%20CE+/") { + if ((location.hostname == "hoothin.github.io" && location.pathname == "/UserScripts/Picviewer%20CE+/") || (location.hostname == "pv.hoothin.com" && location.pathname.indexOf("open-settings") !== -1)) { openPrefs(); } else if (location.hostname == "hoothin.github.io" && location.pathname == "/UserScripts/Picviewer%20CE+/gallery.html") { let gallery = new GalleryC(); @@ -28382,7 +28406,7 @@ ImgOps | https://imgops.com/#b#`; setTimeout(()=>{ if (GM_config.frame && GM_config.frame.contentDocument.body.innerHTML === "") { - _GM_openInTab("https://hoothin.github.io/UserScripts/Picviewer%20CE+/", {active:true}); + _GM_openInTab("https://pv.hoothin.com/open-settings", {active:true}); return; } if (GM_config.frame && GM_config.frame.style && GM_config.frame.style.display == "none") { @@ -28420,6 +28444,7 @@ ImgOps | https://imgops.com/#b#`; try { if (localStorage && localStorage.setItem) { if (!storage.getItem('inited')) { + _GM_openInTab("https://pv.hoothin.com/first-run"); localStorage.setItem('picviewerCE.config.curTab', 4); storage.setItem('inited', true); } From c02f019c2cad42361ace182d397c17806b111823 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Sat, 17 Jan 2026 09:26:18 +0000 Subject: [PATCH 1017/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 47 +++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 427fe3c7eda..5ae597ad9f5 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2026.1.13.1 +// @version 2026.1.17.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://pv.hoothin.com/ @@ -24224,15 +24224,33 @@ ImgOps | https://imgops.com/#b#`; const loaded = await Promise.all(srcs.map(src => this.loadImageForStitch(src))); let totalW = 0; let totalH = 0; + let maxW = 0; + let maxH = 0; + loaded.forEach(({img}) => { + const w = img.naturalWidth || img.width; + const h = img.naturalHeight || img.height; + if (w > maxW) maxW = w; + if (h > maxH) maxH = h; + }); if (layout === 'column') { loaded.forEach(({img}) => { - totalW = Math.max(totalW, img.naturalWidth || img.width); - totalH += img.naturalHeight || img.height; + const w = img.naturalWidth || img.width; + const h = img.naturalHeight || img.height; + const ratio = w ? (maxW / w) : 1; + const drawW = maxW || w; + const drawH = h * ratio; + totalW = Math.max(totalW, drawW); + totalH += drawH; }); } else { loaded.forEach(({img}) => { - totalW += img.naturalWidth || img.width; - totalH = Math.max(totalH, img.naturalHeight || img.height); + const w = img.naturalWidth || img.width; + const h = img.naturalHeight || img.height; + const ratio = h ? (maxH / h) : 1; + const drawH = maxH || h; + const drawW = w * ratio; + totalW += drawW; + totalH = Math.max(totalH, drawH); }); } const canvas = document.createElement('canvas'); @@ -24244,11 +24262,17 @@ ImgOps | https://imgops.com/#b#`; const w = img.naturalWidth || img.width; const h = img.naturalHeight || img.height; if (layout === 'column') { - ctx.drawImage(img, 0, offset, w, h); - offset += h; + const ratio = w ? (maxW / w) : 1; + const drawW = maxW || w; + const drawH = h * ratio; + ctx.drawImage(img, 0, offset, drawW, drawH); + offset += drawH; } else { - ctx.drawImage(img, offset, 0, w, h); - offset += w; + const ratio = h ? (maxH / h) : 1; + const drawH = maxH || h; + const drawW = w * ratio; + ctx.drawImage(img, offset, 0, drawW, drawH); + offset += drawW; } }); const blob = await new Promise(resolve => canvas.toBlob(resolve, 'image/png')); @@ -28266,7 +28290,7 @@ ImgOps | https://imgops.com/#b#`; var configStyle = document.createElement("style"); configStyle.textContent = "#pv-prefs { display: initial; }"; configStyle.type = 'text/css'; - if (location.hostname == "hoothin.github.io" && location.pathname == "/UserScripts/Picviewer%20CE+/") { + if ((location.hostname == "hoothin.github.io" && location.pathname == "/UserScripts/Picviewer%20CE+/") || (location.hostname == "pv.hoothin.com" && location.pathname.indexOf("open-settings") !== -1)) { openPrefs(); } else if (location.hostname == "hoothin.github.io" && location.pathname == "/UserScripts/Picviewer%20CE+/gallery.html") { let gallery = new GalleryC(); @@ -28382,7 +28406,7 @@ ImgOps | https://imgops.com/#b#`; setTimeout(()=>{ if (GM_config.frame && GM_config.frame.contentDocument.body.innerHTML === "") { - _GM_openInTab("https://hoothin.github.io/UserScripts/Picviewer%20CE+/", {active:true}); + _GM_openInTab("https://pv.hoothin.com/open-settings", {active:true}); return; } if (GM_config.frame && GM_config.frame.style && GM_config.frame.style.display == "none") { @@ -28420,6 +28444,7 @@ ImgOps | https://imgops.com/#b#`; try { if (localStorage && localStorage.setItem) { if (!storage.getItem('inited')) { + _GM_openInTab("https://pv.hoothin.com/first-run"); localStorage.setItem('picviewerCE.config.curTab', 4); storage.setItem('inited', true); } From 3ef164265f2bff8373c9af59c1e30174bd12583a Mon Sep 17 00:00:00 2001 From: hoothin Date: Mon, 19 Jan 2026 09:43:22 +0900 Subject: [PATCH 1018/1065] Update README.md --- Pagetual/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Pagetual/README.md b/Pagetual/README.md index 6077f2266b0..b24092e63dc 100644 --- a/Pagetual/README.md +++ b/Pagetual/README.md @@ -2,7 +2,7 @@ == *Pagetual - Perpetual pages. Auto loading paginated web pages for 90% of all web sites !* -🔧CONFIGURATION PAGE +🔧CONFIGURATION PAGE

      @@ -33,7 +33,7 @@ https://raw.githubusercontent.com/hoothin/UserScripts/master/Pagetual/pagetualRu
               Made with ❤️ by Hoothin
           
           
      -        
      +        
           
       
       
      
      From cb0d902e7f7ad2c9355f98f895733799bc538700 Mon Sep 17 00:00:00 2001
      From: hoothin 
      Date: Mon, 19 Jan 2026 10:02:34 +0900
      Subject: [PATCH 1019/1065] Update pagetual.user.js
      
      ---
       Pagetual/pagetual.user.js | 28 +++++++++++++++++++++++++---
       1 file changed, 25 insertions(+), 3 deletions(-)
      
      diff --git a/Pagetual/pagetual.user.js b/Pagetual/pagetual.user.js
      index c84d06d613c..56682e7251e 100644
      --- a/Pagetual/pagetual.user.js
      +++ b/Pagetual/pagetual.user.js
      @@ -9328,7 +9328,7 @@
                       importBtn.style.fontSize = "20px";
                       importBtn.addEventListener("click", e => {
                           let parentNode = importBtn.parentNode;
      -                    if (!parentNode) return;
      +                    if (!parentNode || !e.isTrusted) return;
                           parentNode.removeChild(importBtn);
                           try {
                               let rules = parentNode.innerText.trim();
      @@ -9522,11 +9522,11 @@
                         padding: 0!important;
                        }
                        #saveBtn {
      -                  width: 60vw;
      +                  width: var(--config-width, 60vw);
                         position: fixed;
                         z-index: 999;
                         bottom: 0;
      -                  left: 20vw;
      +                  left: var(--config-left, 20vw);
                         font-size: xx-large;
                         opacity: 0.6;
                         cursor: pointer;
      @@ -10021,6 +10021,7 @@
               }
       
               updateP.onclick = e => {
      +            if (!e.isTrusted) return;
                   updateFail = false;
                   //ruleParser.rules = [];
                   showTips(i18n("beginUpdate"), "", 30000);
      @@ -10105,8 +10106,29 @@
               saveBtn.innerHTML = i18n("save");
               saveBtn.id = "saveBtn";
               configCon.appendChild(saveBtn);
      +        saveBtn.style.display = "none";
      +        const syncSaveBtnLayout = () => {
      +            if (!configCon || !saveBtn) return;
      +            const rect = configCon.getBoundingClientRect();
      +            if (rect.width > 0) {
      +                document.documentElement.style.setProperty("--config-left", `${rect.left}px`);
      +                document.documentElement.style.setProperty("--config-width", `${rect.width}px`);
      +                saveBtn.style.display = "";
      +            } else {
      +                saveBtn.style.display = "none";
      +            }
      +        };
      +        syncSaveBtnLayout();
      +        window.addEventListener("resize", syncSaveBtnLayout);
      +        if (window.ResizeObserver) {
      +            const saveBtnResizeObserver = new ResizeObserver(() => {
      +                syncSaveBtnLayout();
      +            });
      +            saveBtnResizeObserver.observe(configCon);
      +        }
               saveBtn.onclick = e => {
                   try {
      +                if (!e.isTrusted) return;
                       let customRules;
                       if (editor) {
                           if (editorChanged) {
      
      From 16cd85d93141722d41dc03e53da4262a31182343 Mon Sep 17 00:00:00 2001
      From: hoothin 
      Date: Tue, 20 Jan 2026 11:38:26 +0900
      Subject: [PATCH 1020/1065] Update README.md
      
      ---
       Pagetual/README.md | 5 +----
       1 file changed, 1 insertion(+), 4 deletions(-)
      
      diff --git a/Pagetual/README.md b/Pagetual/README.md
      index b24092e63dc..a0d35bb29cf 100644
      --- a/Pagetual/README.md
      +++ b/Pagetual/README.md
      @@ -30,10 +30,7 @@ https://raw.githubusercontent.com/hoothin/UserScripts/master/Pagetual/pagetualRu
               Send 📧email
           
           
      -        Made with ❤️ by Hoothin
      -    
      -    
      -        
      +        
      Made with ❤️ by Hoothin From aa81734ae9a05ee5fa5d91e798ccf12c3c74a36b Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 20 Jan 2026 17:11:16 +0900 Subject: [PATCH 1021/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index b11d15cc288..a9f1ad098dd 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -27420,6 +27420,8 @@ ImgOps | https://imgops.com/#b#`; "#pv-prefs .section_header_holder { padding-right: 10px; }", "#pv-prefs textarea { width: 100%; }", "#pv-prefs .nav-tabs { white-space: nowrap; width: fit-content; max-width: 100%; margin: 20 auto; display: flex; overflow-x: auto; overflow-y: visible; }", + "#pv-prefs_buttons_holder { position: fixed; bottom: 0; width: 100%; right: 10px; background: #EEE; }", + "#pv-prefs_wrapper { padding-bottom: 70px; }" ].join('\n'), fields: { // 浮动工具栏 @@ -28055,6 +28057,9 @@ ImgOps | https://imgops.com/#b#`; }, events: { open: async function(doc, win, frame) { + if (localStorage && localStorage.getItem && localStorage.getItem('picviewerCE.config.curTab') === null) { + localStorage.setItem('picviewerCE.config.curTab', 4); + } isConfigOpen = true; let saveBtn = doc.querySelector("#"+this.id+"_saveBtn"); let closeBtn = doc.querySelector("#"+this.id+"_closeBtn"); @@ -28442,12 +28447,9 @@ ImgOps | https://imgops.com/#b#`; } }); try { - if (localStorage && localStorage.setItem) { - if (!storage.getItem('inited')) { - _GM_openInTab("https://pv.hoothin.com/first-run"); - localStorage.setItem('picviewerCE.config.curTab', 4); - storage.setItem('inited', true); - } + if (!storage.getItem('inited')) { + _GM_openInTab("https://pv.hoothin.com/first-run", {active:true}); + storage.setItem('inited', true); } } catch(e) {} if (typeof prefs.gallery.formatConversion == 'undefined') { From 6f1c5ddcdf2ecbcb8e2e87633d9ea7599de72a83 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 20 Jan 2026 08:11:35 +0000 Subject: [PATCH 1022/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index 5ae597ad9f5..a5658d84035 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -27420,6 +27420,8 @@ ImgOps | https://imgops.com/#b#`; "#pv-prefs .section_header_holder { padding-right: 10px; }", "#pv-prefs textarea { width: 100%; }", "#pv-prefs .nav-tabs { white-space: nowrap; width: fit-content; max-width: 100%; margin: 20 auto; display: flex; overflow-x: auto; overflow-y: visible; }", + "#pv-prefs_buttons_holder { position: fixed; bottom: 0; width: 100%; right: 10px; background: #EEE; }", + "#pv-prefs_wrapper { padding-bottom: 70px; }" ].join('\n'), fields: { // 浮动工具栏 @@ -28055,6 +28057,9 @@ ImgOps | https://imgops.com/#b#`; }, events: { open: async function(doc, win, frame) { + if (localStorage && localStorage.getItem && localStorage.getItem('picviewerCE.config.curTab') === null) { + localStorage.setItem('picviewerCE.config.curTab', 4); + } isConfigOpen = true; let saveBtn = doc.querySelector("#"+this.id+"_saveBtn"); let closeBtn = doc.querySelector("#"+this.id+"_closeBtn"); @@ -28442,12 +28447,9 @@ ImgOps | https://imgops.com/#b#`; } }); try { - if (localStorage && localStorage.setItem) { - if (!storage.getItem('inited')) { - _GM_openInTab("https://pv.hoothin.com/first-run"); - localStorage.setItem('picviewerCE.config.curTab', 4); - storage.setItem('inited', true); - } + if (!storage.getItem('inited')) { + _GM_openInTab("https://pv.hoothin.com/first-run", {active:true}); + storage.setItem('inited', true); } } catch(e) {} if (typeof prefs.gallery.formatConversion == 'undefined') { From 6d9dcf44298e4abc38d139d025794204594edecd Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 20 Jan 2026 19:37:46 +0900 Subject: [PATCH 1023/1065] Update pvcep_rules.js --- Picviewer CE+/pvcep_rules.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Picviewer CE+/pvcep_rules.js b/Picviewer CE+/pvcep_rules.js index d1a878995eb..25a9bade564 100644 --- a/Picviewer CE+/pvcep_rules.js +++ b/Picviewer CE+/pvcep_rules.js @@ -302,8 +302,8 @@ var siteInfo = [ name: '花瓣网', url: /^https?:\/\/huaban\.com\//i, ext: 'previous-2', - r: [/(.*img.hb.aicdn.com\/.*)_fw(?:236|320)$/i, /_fw\d+\w+/i], - s: ['$1_fw658', ''], + r: [/(.*img.hb.aicdn.com\/.*)_fw(?:236|320)$/i, /(\/small)(\/.*)_fw\d+\w+/i, /_fw\d+\w+/i], + s: ['$1_fw658', '$2', ''], description: './../following-sibling::p[@class="description"]', exclude: /weixin_code\.png$/i }, From 649a918643b999f38796a074b4bb48aeecbc4083 Mon Sep 17 00:00:00 2001 From: hoothin Date: Tue, 20 Jan 2026 19:40:47 +0900 Subject: [PATCH 1024/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index a9f1ad098dd..d78cf8b0efd 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js -// @require https://update.greasyfork.org/scripts/438080/1714183/pvcep_rules.js +// @require https://update.greasyfork.org/scripts/438080/1738227/pvcep_rules.js // @require https://update.greasyfork.org/scripts/440698/1733533/pvcep_lang.js // @match *://*/* // @exclude http://www.toodledo.com/tasks/* From 7faf1e9246f26ba4369d26ab28454064dfa6713e Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Tue, 20 Jan 2026 10:40:58 +0000 Subject: [PATCH 1025/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index a5658d84035..e9ba3d4b72b 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -46,7 +46,7 @@ // @grant GM.notification // @grant unsafeWindow // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=23710 -// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1714183 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1738227 // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1733533 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* From 3a228321e99057fd147d02084735701c4031aef5 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 23 Jan 2026 10:15:14 +0900 Subject: [PATCH 1026/1065] Update pvcep_lang.js --- Picviewer CE+/pvcep_lang.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Picviewer CE+/pvcep_lang.js b/Picviewer CE+/pvcep_lang.js index 113b1cfa052..b65c8122ea3 100644 --- a/Picviewer CE+/pvcep_lang.js +++ b/Picviewer CE+/pvcep_lang.js @@ -117,6 +117,8 @@ const langData = [ config: "Settings", openConfig: "Open Settings", ruleRequest: "Rule Request", + disableKeyForHost: "Disable shortcuts", + restoreKeyForHost: "Restore shortcuts", closeGallery: "Close Gallery", returnToGallery: "Back to the Gallery", picInfo: "Click to change", @@ -390,6 +392,8 @@ const langData = [ config: "%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF%D8%A7%D8%AA", openConfig: "%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", ruleRequest: "%D8%B7%D9%84%D8%A8%20%D8%A7%D9%84%D9%82%D9%88%D8%A7%D8%B9%D8%AF", + disableKeyForHost: "Disable shortcuts", + restoreKeyForHost: "Restore shortcuts", closeGallery: "%D8%A5%D8%BA%D9%84%D8%A7%D9%82%20%D8%A7%D9%84%D9%85%D8%B9%D8%B1%D8%B6", returnToGallery: "%D8%A7%D9%84%D8%B9%D9%88%D8%AF%D8%A9%20%D8%A5%D9%84%D9%89%20%D8%A7%D9%84%D9%85%D8%B9%D8%B1%D8%B6", picInfo: "%D8%A7%D9%86%D9%82%D8%B1%20%D9%84%D8%AA%D8%BA%D9%8A%D9%8A%D8%B1", @@ -661,6 +665,8 @@ const langData = [ config: "设置", openConfig: "打开设置", ruleRequest: "适配请求", + disableKeyForHost: "Disable shortcuts", + restoreKeyForHost: "Restore shortcuts", closeGallery: "关闭库", returnToGallery: "回到库", picInfo: "点击修改", @@ -932,6 +938,8 @@ const langData = [ config: "設置", openConfig: "打開設置", ruleRequest: "適配請求", + disableKeyForHost: "Disable shortcuts", + restoreKeyForHost: "Restore shortcuts", closeGallery: "關閉庫", returnToGallery: "回到庫", picInfo: "點擊修改", @@ -1204,6 +1212,8 @@ const langData = [ config: "Configurações", openConfig: "Abrir configurações", ruleRequest: "Solicitar regra", + disableKeyForHost: "Disable shortcuts", + restoreKeyForHost: "Restore shortcuts", closeGallery: "Fechar galeria", returnToGallery: "Voltar para a Galeria", picInfo: "Clique para editar", @@ -1476,6 +1486,8 @@ const langData = [ config: "Configurações", openConfig: "Configurações", ruleRequest: "Pedido de regra", + disableKeyForHost: "Disable shortcuts", + restoreKeyForHost: "Restore shortcuts", closeGallery: "Sair da Galeria", returnToGallery: "Voltar para a Galeria", picInfo: "Clique para alterar", @@ -1748,6 +1760,8 @@ const langData = [ config: "Параметры", openConfig: "Открыть параметры", ruleRequest: "Запрос правил", + disableKeyForHost: "Disable shortcuts", + restoreKeyForHost: "Restore shortcuts", closeGallery: "Закрыть галерею", returnToGallery: "Вернуться в галерею", picInfo: "Нажмите, чтобы изменить", @@ -2020,6 +2034,8 @@ const langData = [ config: "Ayarlar", openConfig: "Ayarları Açın", ruleRequest: "Kural Talebi", + disableKeyForHost: "Disable shortcuts", + restoreKeyForHost: "Restore shortcuts", closeGallery: "Galeriyi kapatın", returnToGallery: "Galeriye geri dönün", picInfo: "Değiştirmek için tıklayın", @@ -2291,6 +2307,8 @@ const langData = [ config: "設定", openConfig: "設定を開く", ruleRequest: "ルール要求", + disableKeyForHost: "Disable shortcuts", + restoreKeyForHost: "Restore shortcuts", closeGallery: "ギャラリーを閉じる", returnToGallery: "ギャラリーに戻る", picInfo: "クリックして変更", @@ -2563,6 +2581,8 @@ const langData = [ config: "Налаштування", openConfig: "Відкрити налаштування", ruleRequest: "Правило Запит", + disableKeyForHost: "Disable shortcuts", + restoreKeyForHost: "Restore shortcuts", closeGallery: "Закрити галерею", returnToGallery: "Повернутись у галерею", picInfo: "Натисніть, щоб змінити", From 14c3308d019091a52aab926a61f9c9d26996d975 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 23 Jan 2026 10:28:18 +0900 Subject: [PATCH 1027/1065] Update pvcep_lang.js --- Picviewer CE+/pvcep_lang.js | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Picviewer CE+/pvcep_lang.js b/Picviewer CE+/pvcep_lang.js index b65c8122ea3..2bda9d64459 100644 --- a/Picviewer CE+/pvcep_lang.js +++ b/Picviewer CE+/pvcep_lang.js @@ -392,8 +392,8 @@ const langData = [ config: "%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF%D8%A7%D8%AA", openConfig: "%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", ruleRequest: "%D8%B7%D9%84%D8%A8%20%D8%A7%D9%84%D9%82%D9%88%D8%A7%D8%B9%D8%AF", - disableKeyForHost: "Disable shortcuts", - restoreKeyForHost: "Restore shortcuts", + disableKeyForHost: "%D8%AA%D8%B9%D8%B7%D9%8A%D9%84%20%D8%A7%D9%84%D8%A7%D8%AE%D8%AA%D8%B5%D8%A7%D8%B1%D8%A7%D8%AA", + restoreKeyForHost: "%D8%A7%D8%B3%D8%AA%D8%B9%D8%A7%D8%AF%D8%A9%20%D8%A7%D9%84%D8%A7%D8%AE%D8%AA%D8%B5%D8%A7%D8%B1%D8%A7%D8%AA", closeGallery: "%D8%A5%D8%BA%D9%84%D8%A7%D9%82%20%D8%A7%D9%84%D9%85%D8%B9%D8%B1%D8%B6", returnToGallery: "%D8%A7%D9%84%D8%B9%D9%88%D8%AF%D8%A9%20%D8%A5%D9%84%D9%89%20%D8%A7%D9%84%D9%85%D8%B9%D8%B1%D8%B6", picInfo: "%D8%A7%D9%86%D9%82%D8%B1%20%D9%84%D8%AA%D8%BA%D9%8A%D9%8A%D8%B1", @@ -665,8 +665,8 @@ const langData = [ config: "设置", openConfig: "打开设置", ruleRequest: "适配请求", - disableKeyForHost: "Disable shortcuts", - restoreKeyForHost: "Restore shortcuts", + disableKeyForHost: "禁用快捷键", + restoreKeyForHost: "恢复快捷键", closeGallery: "关闭库", returnToGallery: "回到库", picInfo: "点击修改", @@ -938,8 +938,8 @@ const langData = [ config: "設置", openConfig: "打開設置", ruleRequest: "適配請求", - disableKeyForHost: "Disable shortcuts", - restoreKeyForHost: "Restore shortcuts", + disableKeyForHost: "停用快速鍵", + restoreKeyForHost: "恢復快速鍵", closeGallery: "關閉庫", returnToGallery: "回到庫", picInfo: "點擊修改", @@ -1212,8 +1212,8 @@ const langData = [ config: "Configurações", openConfig: "Abrir configurações", ruleRequest: "Solicitar regra", - disableKeyForHost: "Disable shortcuts", - restoreKeyForHost: "Restore shortcuts", + disableKeyForHost: "Desativar atalhos", + restoreKeyForHost: "Restaurar atalhos", closeGallery: "Fechar galeria", returnToGallery: "Voltar para a Galeria", picInfo: "Clique para editar", @@ -1486,8 +1486,8 @@ const langData = [ config: "Configurações", openConfig: "Configurações", ruleRequest: "Pedido de regra", - disableKeyForHost: "Disable shortcuts", - restoreKeyForHost: "Restore shortcuts", + disableKeyForHost: "Desativar atalhos", + restoreKeyForHost: "Restaurar atalhos", closeGallery: "Sair da Galeria", returnToGallery: "Voltar para a Galeria", picInfo: "Clique para alterar", @@ -1760,8 +1760,8 @@ const langData = [ config: "Параметры", openConfig: "Открыть параметры", ruleRequest: "Запрос правил", - disableKeyForHost: "Disable shortcuts", - restoreKeyForHost: "Restore shortcuts", + disableKeyForHost: "Отключить сочетания клавиш", + restoreKeyForHost: "Восстановить сочетания клавиш", closeGallery: "Закрыть галерею", returnToGallery: "Вернуться в галерею", picInfo: "Нажмите, чтобы изменить", @@ -2034,8 +2034,8 @@ const langData = [ config: "Ayarlar", openConfig: "Ayarları Açın", ruleRequest: "Kural Talebi", - disableKeyForHost: "Disable shortcuts", - restoreKeyForHost: "Restore shortcuts", + disableKeyForHost: "Kısayolları devre dışı bırak", + restoreKeyForHost: "Kısayolları geri yükle", closeGallery: "Galeriyi kapatın", returnToGallery: "Galeriye geri dönün", picInfo: "Değiştirmek için tıklayın", @@ -2307,8 +2307,8 @@ const langData = [ config: "設定", openConfig: "設定を開く", ruleRequest: "ルール要求", - disableKeyForHost: "Disable shortcuts", - restoreKeyForHost: "Restore shortcuts", + disableKeyForHost: "ショートカットを無効にする", + restoreKeyForHost: "ショートカットを元に戻す", closeGallery: "ギャラリーを閉じる", returnToGallery: "ギャラリーに戻る", picInfo: "クリックして変更", @@ -2581,8 +2581,8 @@ const langData = [ config: "Налаштування", openConfig: "Відкрити налаштування", ruleRequest: "Правило Запит", - disableKeyForHost: "Disable shortcuts", - restoreKeyForHost: "Restore shortcuts", + disableKeyForHost: "Вимкнути комбінації клавіш", + restoreKeyForHost: "Відновити комбінації клавіш", closeGallery: "Закрити галерею", returnToGallery: "Повернутись у галерею", picInfo: "Натисніть, щоб змінити", From be1e07b35b945c23cba0c7b4b2827a64c081d9e2 Mon Sep 17 00:00:00 2001 From: hoothin Date: Fri, 23 Jan 2026 10:29:59 +0900 Subject: [PATCH 1028/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 76 ++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index d78cf8b0efd..dc08df12a53 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -12,7 +12,7 @@ // @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 2026.1.17.1 +// @version 2026.1.23.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://pv.hoothin.com/ @@ -47,7 +47,7 @@ // @grant unsafeWindow // @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js // @require https://update.greasyfork.org/scripts/438080/1738227/pvcep_rules.js -// @require https://update.greasyfork.org/scripts/440698/1733533/pvcep_lang.js +// @require https://update.greasyfork.org/scripts/440698/1740314/pvcep_lang.js // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* @@ -28254,6 +28254,30 @@ ImgOps | https://imgops.com/#b#`; document.head.removeChild(hideIconStyle); } }); + function buildDisableKeyPattern() { + let originPattern = location.origin.replace(/^https?/, "https?").replace(/\./g, "\\."); + let pathBase = location.pathname.replace(/[^\/]*$/, ""); + return "^" + originPattern + pathBase; + } + function isDisableKeyPatternMatched() { + let pattern = buildDisableKeyPattern(); + let list = normalizeDisableKeySites(prefs.floatBar.disableKeySites); + return list.indexOf(pattern) !== -1; + } + _GM_registerMenuCommand( + isDisableKeyPatternMatched() ? i18n("restoreKeyForHost") : i18n("disableKeyForHost"), + () => { + let pattern = buildDisableKeyPattern(); + let list = normalizeDisableKeySites(prefs.floatBar.disableKeySites); + if (list.indexOf(pattern) === -1) { + list.unshift(pattern); + saveDisableKeySites(list); + } else { + let nextList = list.filter(item => item !== pattern); + saveDisableKeySites(nextList); + } + } + ); _GM_registerMenuCommand(i18n("ruleRequest"), () => { _GM_openInTab("https://github.com/hoothin/UserScripts/issues/new?labels=Picviewer%20CE%2B&template=custom-rule-request.md&title=Request%20Picviewer%20CE%2B%20support%20for%20" + location.hostname, {active:true}); }); @@ -28346,19 +28370,47 @@ ImgOps | https://imgops.com/#b#`; } // 注册按键 - let disableKey = false; - if (prefs.floatBar.disableKeySites) { - let sitesArr = prefs.floatBar.disableKeySites.split("\n"); - for(let s = 0; s < sitesArr.length; s++) { - let siteReg = sitesArr[s].trim(); - if (new RegExp(siteReg).test(_URL)) { - disableKey = true; - break; + function normalizeDisableKeySites(value) { + if (!value) return []; + return value.split("\n").map(s => s.trim()).filter(Boolean); + } + + function isKeyDisabledForUrl(url, host, list) { + for (let i = 0; i < list.length; i++) { + let siteReg = list[i]; + try { + let reg = new RegExp(siteReg); + if (reg.test(url) || reg.test(host)) return true; + } catch (e) { } } + return false; } - if (!disableKey) { - document.addEventListener('keydown', keydown, true); + + let keydownBound = false; + function updateKeydownListener() { + let list = normalizeDisableKeySites(prefs.floatBar.disableKeySites); + let disableKey = isKeyDisabledForUrl(_URL, location.hostname, list); + if (!disableKey && !keydownBound) { + document.addEventListener('keydown', keydown, true); + keydownBound = true; + } else if (disableKey && keydownBound) { + document.removeEventListener('keydown', keydown, true); + keydownBound = false; + } + } + updateKeydownListener(); + + function saveDisableKeySites(list) { + let value = list.join("\n"); + prefs.floatBar.disableKeySites = value; + if (GM_config && GM_config.set) { + GM_config.set('floatBar.disableKeySites', value); + let field = GM_config.fields && GM_config.fields['floatBar.disableKeySites']; + if (field && field.node) field.node.value = value; + GM_config.save(); + } + updateKeydownListener(); } let canImport = false; From 95c543b6ccd8659d25c9c92bfdd66f6714b74186 Mon Sep 17 00:00:00 2001 From: hoothin-update Date: Fri, 23 Jan 2026 01:30:08 +0000 Subject: [PATCH 1029/1065] chore(Picviewer CE+): Auto-generate dist.user.js --- Picviewer CE+/dist.user.js | 76 ++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/Picviewer CE+/dist.user.js b/Picviewer CE+/dist.user.js index e9ba3d4b72b..856071eb35f 100644 --- a/Picviewer CE+/dist.user.js +++ b/Picviewer CE+/dist.user.js @@ -12,7 +12,7 @@ // @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 2026.1.17.1 +// @version 2026.1.23.1 // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg== // @namespace https://github.com/hoothin/UserScripts // @homepage https://pv.hoothin.com/ @@ -47,7 +47,7 @@ // @grant unsafeWindow // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=23710 // @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=1738227 -// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1733533 +// @require https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=1740314 // @match *://*/* // @exclude http://www.toodledo.com/tasks/* // @exclude http*://maps.google.com*/* @@ -28254,6 +28254,30 @@ ImgOps | https://imgops.com/#b#`; document.head.removeChild(hideIconStyle); } }); + function buildDisableKeyPattern() { + let originPattern = location.origin.replace(/^https?/, "https?").replace(/\./g, "\\."); + let pathBase = location.pathname.replace(/[^\/]*$/, ""); + return "^" + originPattern + pathBase; + } + function isDisableKeyPatternMatched() { + let pattern = buildDisableKeyPattern(); + let list = normalizeDisableKeySites(prefs.floatBar.disableKeySites); + return list.indexOf(pattern) !== -1; + } + _GM_registerMenuCommand( + isDisableKeyPatternMatched() ? i18n("restoreKeyForHost") : i18n("disableKeyForHost"), + () => { + let pattern = buildDisableKeyPattern(); + let list = normalizeDisableKeySites(prefs.floatBar.disableKeySites); + if (list.indexOf(pattern) === -1) { + list.unshift(pattern); + saveDisableKeySites(list); + } else { + let nextList = list.filter(item => item !== pattern); + saveDisableKeySites(nextList); + } + } + ); _GM_registerMenuCommand(i18n("ruleRequest"), () => { _GM_openInTab("https://github.com/hoothin/UserScripts/issues/new?labels=Picviewer%20CE%2B&template=custom-rule-request.md&title=Request%20Picviewer%20CE%2B%20support%20for%20" + location.hostname, {active:true}); }); @@ -28346,19 +28370,47 @@ ImgOps | https://imgops.com/#b#`; } // 注册按键 - let disableKey = false; - if (prefs.floatBar.disableKeySites) { - let sitesArr = prefs.floatBar.disableKeySites.split("\n"); - for(let s = 0; s < sitesArr.length; s++) { - let siteReg = sitesArr[s].trim(); - if (new RegExp(siteReg).test(_URL)) { - disableKey = true; - break; + function normalizeDisableKeySites(value) { + if (!value) return []; + return value.split("\n").map(s => s.trim()).filter(Boolean); + } + + function isKeyDisabledForUrl(url, host, list) { + for (let i = 0; i < list.length; i++) { + let siteReg = list[i]; + try { + let reg = new RegExp(siteReg); + if (reg.test(url) || reg.test(host)) return true; + } catch (e) { } } + return false; } - if (!disableKey) { - document.addEventListener('keydown', keydown, true); + + let keydownBound = false; + function updateKeydownListener() { + let list = normalizeDisableKeySites(prefs.floatBar.disableKeySites); + let disableKey = isKeyDisabledForUrl(_URL, location.hostname, list); + if (!disableKey && !keydownBound) { + document.addEventListener('keydown', keydown, true); + keydownBound = true; + } else if (disableKey && keydownBound) { + document.removeEventListener('keydown', keydown, true); + keydownBound = false; + } + } + updateKeydownListener(); + + function saveDisableKeySites(list) { + let value = list.join("\n"); + prefs.floatBar.disableKeySites = value; + if (GM_config && GM_config.set) { + GM_config.set('floatBar.disableKeySites', value); + let field = GM_config.fields && GM_config.fields['floatBar.disableKeySites']; + if (field && field.node) field.node.value = value; + GM_config.save(); + } + updateKeydownListener(); } let canImport = false; From 864431639548fd3f77a85a669e4eae0a5798a57c Mon Sep 17 00:00:00 2001 From: hoothin Date: Sat, 31 Jan 2026 18:24:23 +0900 Subject: [PATCH 1030/1065] Update Picviewer CE+.user.js --- Picviewer CE+/Picviewer CE+.user.js | 213 ++++++++++++++++++++-------- 1 file changed, 150 insertions(+), 63 deletions(-) diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index dc08df12a53..1cb566a73bd 100644 --- a/Picviewer CE+/Picviewer CE+.user.js +++ b/Picviewer CE+/Picviewer CE+.user.js @@ -11925,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'; @@ -12744,24 +12744,6 @@ ImgOps | https://imgops.com/#b#`; return; } catch (e) { } - - const existingPolicies = new Set(unsafeWindow.trustedTypes.getPolicyNames()); - for (const name of allowedNames) { - if (name === '*' || existingPolicies.has(name)) { - continue; - } - - try { - escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy(name, { - createHTML: (string, sink) => string, - createScriptURL: string => string, - createScript: string => string - }); - return; - } catch (e) { - debug(`create '${name}' failed, trying next...`); - } - } debug("Could not create any trusted types policy."); } @@ -12771,7 +12753,107 @@ ImgOps | https://imgops.com/#b#`; 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 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][^>]*>|[^<]+/g; + 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][^>]*>|[^<]+/g; + 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][^>]*>|[^<]+/g; + 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 (metaResult.ttDirectiveFound) { - combinedTtDirectiveFound = true; + if (token.indexOf('|<\/?[a-zA-Z][^>]*>|[^<]+/g; + const tokenRe = /|]*>|<\/?[a-zA-Z][^>]*>|[^<]+/gi; let match; while ((match = tokenRe.exec(html))) { const token = match[0]; @@ -4626,6 +4639,9 @@ if (token.indexOf('|<\/?[a-zA-Z][^>]*>|[^<]+/g; + const tokenRe = /|]*>|<\/?[a-zA-Z][^>]*>|[^<]+/gi; let match; while ((match = tokenRe.exec(html))) { const token = match[0]; @@ -12828,6 +12841,9 @@ ImgOps | https://imgops.com/#b#`; if (token.indexOf('|<\/?[a-zA-Z][^>]*>|[^<]+/g; + const tokenRe = /|]*>|<\/?[a-zA-Z][^>]*>|[^<]+/gi; let match; while ((match = tokenRe.exec(html))) { const token = match[0]; @@ -12828,6 +12841,9 @@ ImgOps | https://imgops.com/#b#`; if (token.indexOf('