Fix Settings.upgrade to work with version numbers prepended with XT
This commit is contained in:
parent
5815070572
commit
1973f87414
@ -3,6 +3,11 @@
|
||||
4chan XT uses a different user script namespace, so to migrate you need to export settings from 4chan X, and import them
|
||||
in XT.
|
||||
|
||||
### XT v2.1.4 (2023-09-02)
|
||||
|
||||
- Fix DataBoard class, should solve [#7](https://github.com/TuxedoTako/4chan-xt/issues/7)
|
||||
- Fix Settings.upgrade to work with version numbers prepended with XT
|
||||
|
||||
### XT v2.1.3 (2023-08-21)
|
||||
|
||||
- Embed x.com links.
|
||||
|
||||
File diff suppressed because one or more lines are too long
217
builds/4chan-XT-noupdate.user.min.js
vendored
217
builds/4chan-XT-noupdate.user.min.js
vendored
@ -1,6 +1,6 @@
|
||||
// ==UserScript==
|
||||
// @name 4chan XT
|
||||
// @version XT 2.1.3
|
||||
// @version XT 2.1.4
|
||||
// @minGMVer 1.14
|
||||
// @minFFVer 74
|
||||
// @namespace 4chan-XT
|
||||
@ -187,7 +187,7 @@
|
||||
!function(){"use strict";var e={name:"4chan XT",path:"4chan-XT",fork:"TuxedoTako",page:"https://github.com/TuxedoTako/4chan-xt",downloads:"https://github.com/TuxedoTako/4chan-xt/releases",oldVersions:"https://raw.githubusercontent.com/ccd0/4chan-x/",faq:"https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions",captchaFAQ:"https://github.com/ccd0/4chan-x/wiki/Captcha-FAQ",cssGuide:"https://github.com/ccd0/4chan-x/wiki/Styling-Guide",license:"https://github.com/TuxedoTako/4chan-xt/blob/project-XT/LICENSE",changelog:"https://github.com/TuxedoTako/4chan-xt/blob/project-XT/CHANGELOG.md",issues:"https://github.com/TuxedoTako/4chan-xt/issues",newIssue:"https://github.com/TuxedoTako/4chan-xt/issues",newIssueMaxLength:8181,alternatives:"https://www.4chan-x.net/4chan_alternatives.html",appid:"lacclbnghgdicfifcamcmcnilckjamag",appidGecko:"4chan-x@4chan-x.net",chromeStoreID:"ohnjgmpcibpbafdlkimncjhflgedgpam",recaptchaKey:"6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc",distBranch:"gh-pages",
|
||||
includes_only:["*://boards.4chan.org/*","*://sys.4chan.org/*","*://www.4chan.org/*","*://boards.4channel.org/*","*://sys.4channel.org/*","*://www.4channel.org/*","*://i.4cdn.org/*","*://is.4chan.org/*","*://is2.4chan.org/*","*://is.4channel.org/*","*://is2.4channel.org/*"],matches_only:["*://*.4chan.org/*","*://*.4channel.org/*","*://*.4cdn.org/*"],
|
||||
matches:["https://erischan.org/*","https://www.erischan.org/*","https://fufufu.moe/*","https://gnfos.com/*","https://himasugi.blog/*","https://www.himasugi.blog/*","https://kakashinenpo.com/*","https://www.kakashinenpo.com/*","https://kissu.moe/*","https://www.kissu.moe/*","https://lainchan.org/*","https://www.lainchan.org/*","https://merorin.com/*","https://ota-ch.com/*","https://www.ota-ch.com/*","https://ponyville.us/*","https://www.ponyville.us/*","https://smuglo.li/*","https://notso.smuglo.li/*","https://smugloli.net/*","https://smug.nepu.moe/*","https://sportschan.org/*","https://www.sportschan.org/*","https://sushigirl.us/*","https://www.sushigirl.us/*","https://tvch.moe/*"],matches_extra:[],exclude_matches:["*://www.4chan.org/advertise","*://www.4chan.org/advertise?*","*://www.4chan.org/donate","*://www.4chan.org/donate?*","*://www.4channel.org/advertise","*://www.4channel.org/advertise?*","*://www.4channel.org/donate","*://www.4channel.org/donate?*"],
|
||||
grants:["GM_getValue","GM_setValue","GM_deleteValue","GM_listValues","GM_addValueChangeListener","GM_openInTab","GM_xmlhttpRequest","GM.getValue","GM.setValue","GM.deleteValue","GM.listValues","GM.openInTab","GM.xmlHttpRequest"],min:{chrome:"80",firefox:"74",greasemonkey:"1.14"}};const t=Object.create(null),n={VERSION:"XT 2.1.3",NAMESPACE:e.name,sites:Object.create(null),boards:Object.create(null)},o=function(){const e={"&":"&","'":"'",'"':""","<":"<",">":">"},t=/[&"'<>]/g,n=function(t){return e[t]},o=function(e){return e.toString().replace(t,n)};return o.cat=function(e){let t="";for(let n=0;n<e.length;n++)t+=e[n].innerHTML;return t},o}(),a=document,i=a.documentElement,r=console,s=function(){return i};class l{static initClass(){this.Post=new l("Post"),this.Thread=new l("Thread"),this.CatalogThread=new l("Catalog Thread"),this.CatalogThreadNative=new l("Catalog Thread")}constructor(e){this.type=e,this.keys=[]}push({name:e,cb:t}){return this[e]||this.keys.push(e),
|
||||
grants:["GM_getValue","GM_setValue","GM_deleteValue","GM_listValues","GM_addValueChangeListener","GM_openInTab","GM_xmlhttpRequest","GM.getValue","GM.setValue","GM.deleteValue","GM.listValues","GM.openInTab","GM.xmlHttpRequest"],min:{chrome:"80",firefox:"74",greasemonkey:"1.14"}};const t=Object.create(null),n={VERSION:"XT 2.1.4",NAMESPACE:e.name,sites:Object.create(null),boards:Object.create(null)},o=function(){const e={"&":"&","'":"'",'"':""","<":"<",">":">"},t=/[&"'<>]/g,n=function(t){return e[t]},o=function(e){return e.toString().replace(t,n)};return o.cat=function(e){let t="";for(let n=0;n<e.length;n++)t+=e[n].innerHTML;return t},o}(),a=document,i=a.documentElement,r=console,s=function(){return i};class l{static initClass(){this.Post=new l("Post"),this.Thread=new l("Thread"),this.CatalogThread=new l("Catalog Thread"),this.CatalogThreadNative=new l("Catalog Thread")}constructor(e){this.type=e,this.keys=[]}push({name:e,cb:t}){return this[e]||this.keys.push(e),
|
||||
this[e]=t}execute(e,t=this.keys,n=!1){let o;if(!e.callbacksExecuted||n){for(var a of(e.callbacksExecuted=!0,t))try{this[a]?.call(e)}catch(t){o||(o=[]),o.push({message:['"',a,'" crashed on node ',this.type," No.",e.ID," (",e.board,")."].join(""),error:t,html:e.nodes?.root?.outerHTML})}return o?Ot.handleErrors(o):void 0}}}l.initClass();const c={main:{Miscellaneous:{"Redirect to HTTPS":[!0,"Redirect to the HTTPS version of 4chan."],"JSON Index":[!0,"Replace the original board index with one supporting searching, sorting, infinite scrolling, and a catalog mode."],[`Use ${e.name} Catalog`]:[!0,`Link to ${e.name}'s catalog instead of the native 4chan one.`,1],"Index Refresh Notifications":[!1,"Show a notice at the top of the page when the index is refreshed.",1],"Follow Cursor":[!0,"Image Hover and Quote Preview move with the mouse cursor."],"Open Threads in New Tab":[!1,`Make links to threads in the index / ${e.name} catalog open in a new tab.`],
|
||||
"External Catalog":[!1,"Link to external catalog instead of the internal one."],"Catalog Links":[!1,"Add toggle link in header menu to turn Navigation links into links to each board's catalog."],"Announcement Hiding":[!0,"Add button to hide 4chan announcements."],"Desktop Notifications":[!0,`Enables desktop notifications across various ${e.name} features.`],"404 Redirect":[!0,"Redirect dead threads and images to the archives."],"Archive Report":[!0,"Enable reporting posts to supported archives."],"Exempt Archives from Encryption":[!0,"Permit loading content from, and warningless redirects to, HTTP-only archives from HTTPS pages."],Keybinds:[!0,"Bind actions to keyboard shortcuts."],"Time Formatting":[!0,"Localize and format timestamps."],"Relative Post Dates":[!0,'Display dates like "3 minutes ago". Tooltip shows the timestamp.'],"Relative Date Title":[!0,"Show Relative Post Date only when hovering over dates.",1],
|
||||
"Comment Expansion":[!0,"Expand comments that are too long to display on the index. Not applicable with JSON Index."],"File Info Formatting":[!0,"Reformat the file information."],"Thread Expansion":[!0,"Add buttons to expand threads."],"Index Navigation":[!1,"Add buttons to navigate between threads."],"Reply Navigation":[!1,"Add buttons to navigate to top / bottom of thread."],"Unique ID and Capcode Navigation":[!1,"Add buttons to navigate to posts having the same unique ID or capcode."],"Custom Board Titles":[!0,"Allow editing of the board title and subtitle by ctrl/⌘+clicking them."],"Persistent Custom Board Titles":[!1,"Force custom board titles to be persistent, even if the board titles are updated.",1],"Show Updated Notifications":[!0,`Show notifications when ${e.name} is successfully updated.`],"Color User IDs":[!0,"Assign unique colors to user IDs on boards that use them"],"Count Posts by ID":[!0,"Display number of posts in the thread when hovering over an ID."],
|
||||
@ -224,8 +224,8 @@ Metro:["iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAC/AABrZQDiAAAA
|
||||
if(!t["Force Noscript Captcha"]||!Ot.jsEnabled)return t.captchaLanguage.trim()?["boards.4chan.org","boards.4channel.org"].includes(location.hostname)?Ve.onExists(i,"#captchaFormPart",(e=>Ve.onExists(e,'iframe[src^="https://www.google.com/recaptcha/"]',Oe.replace.iframe))):Ve.onExists(i,'iframe[src^="https://www.google.com/recaptcha/"]',Oe.replace.iframe):void 0;Ve.ready(Oe.replace.noscript)}},noscript(){let e,t,n;if(!(t=Ve("#g-recaptcha"))||!(e=Ve("noscript",t.parentNode)))return;const o=Ve.el("span",{id:"captcha-forced-noscript"});Ve.replace(e,o),Ve.rm(t);const a=function(){return o.innerHTML=e.textContent,Oe.replace.iframe(Ve('iframe[src^="https://www.google.com/recaptcha/"]',o))};return(n=Ve("#togglePostFormLink a, #form-link"))?Ve.on(n,"click",a):a()},iframe(e){let n;if(n=t.captchaLanguage.trim()){const t=/[?&]hl=/.test(e.src)?e.src.replace(/([?&]hl=)[^&]*/,"$1"+encodeURIComponent(n)):e.src+`&hl=${encodeURIComponent(n)}`;e.src!==t&&(e.src=t)}}},g={init(){
|
||||
if(a.cookie.indexOf("pass_enabled=1")>=0)return;if(!(this.isEnabled=!!Ve("#t-root")||!Ve.id("postForm")))return;const e=Ve.el("div",{className:"captcha-root"});return this.nodes={root:e},Ve.addClass($e.nodes.el,"has-captcha","captcha-t"),Ve.after($e.nodes.com.parentNode,e)},moreNeeded(){},getThread(){let e;const t=n.BOARD.ID;return e="new"===$e.posts[0].thread?"0":""+$e.posts[0].thread,{boardID:t,threadID:e}},setup(e){if(this.isEnabled)return this.nodes.container||(this.nodes.container=Ve.el("div",{className:"captcha-container"}),Ve.prepend(this.nodes.root,this.nodes.container),g.currentThread=g.getThread(),Ve.global((function(){const e=document.querySelector("#qr .captcha-container");return window.TCaptcha.init(e,this.boardID,+this.threadID),window.TCaptcha.setErrorCb((e=>window.dispatchEvent(new CustomEvent("CreateNotification",{detail:{type:"warning",content:""+e}}))))}),g.currentThread)),e?Ve("#t-resp").focus():void 0},destroy(){
|
||||
if(this.isEnabled&&this.nodes.container)return Ve.global((()=>window.TCaptcha.destroy())),Ve.rm(this.nodes.container),delete this.nodes.container},updateThread(){if(!this.isEnabled)return;const{boardID:e,threadID:t}=g.currentThread||{},n=g.getThread();return n.boardID!==e||n.threadID!==t?(g.destroy(),g.setup()):void 0},getOne(){let e,t={};if(this.nodes.container)for(var n of["t-response","t-challenge"])t[n]=Ve(`[name='${n}']`,this.nodes.container).value;return t["t-response"]||(e=Ve("#t-msg"))&&/Verification not required/i.test(e.textContent)||(t=null),t},setUsed(){if(this.isEnabled)return this.nodes.container?Ve.global((()=>window.TCaptcha.clearChallenge())):void 0},occupied(){return!!this.nodes.container}},f=(e,t)=>{let n=0,o=null,a=null,i=null;const r=function(){return n=Date.now(),t.apply(a,i)};return function(){return i=arguments,a=this,n<Date.now()-e?r():(clearTimeout(o),o=setTimeout(r,e))}},m=()=>Object.create(null);m.clone=function(e){if("object"!=typeof e||null===e)return e
|
||||
;if(e instanceof Array){const t=[];for(let n=0,o=e.length;n<o;n++)t.push(m.clone(e[n]));return t}{const o=Object.create(null);for(var t in e){var n=e[t];o[t]=m.clone(n)}return o}},m.json=e=>m.clone(JSON.parse(e));const b=1e3,A=6e4,v=36e5,w=24*v,x=window.GM_xmlhttpRequest?"userscript":"crx";class y{static initClass(){this.keys=["hiddenThreads","hiddenPosts","lastReadPosts","yourPosts","watchedThreads","watcherLastModified","customTitles"],this.changes=[]}constructor(e,n,o){if(this.onSync=this.onSync.bind(this),this.key=e,this.initData(t[this.key]),Ve.sync(this.key,this.onSync),o||this.clean(),n){var i=()=>(Ve.off(a,"4chanXInitFinished",i),this.sync=n);Ve.on(a,"4chanXInitFinished",i)}}initData(e){let t;if(this.data=e,this.data.boards){let e;({boards:t,lastChecked:e}=this.data),this.data["4chan.org"]={boards:t,lastChecked:e},delete this.data.boards,delete this.data.lastChecked}return this.data[n.SITE.ID]||(this.data[n.SITE.ID]={boards:m()})}save(e,t){return e(),y.changes.push(e),
|
||||
Ve.get(this.key,{boards:m()},(n=>{if(!y.changes.length)return;const o=(n[this.key].version||0)>(this.data.version||0);if(o)for(e of(this.initData(n[this.key]),y.changes))e();return y.changes=[],this.data.version=(this.data.version||0)+1,Ve.set(this.key,this.data,(()=>(o&&this.sync?.(),t?.())))}))}forceSync(e){return Ve.get(this.key,{boards:m()},(t=>{if((t[this.key].version||0)>(this.data.version||0)){for(var n of(this.initData(t[this.key]),y.changes))n();this.sync?.()}return e?.()}))}delete({siteID:e,boardID:t,threadID:o,postID:a},i){if(e||(e=n.SITE.ID),this.data[e])return this.save((()=>{if(a){if(!this.data[e].boards[t]?.[o])return;return delete this.data[e].boards[t][o][a],this.deleteIfEmpty({siteID:e,boardID:t,threadID:o})}if(o){if(!this.data[e].boards[t])return;return delete this.data[e].boards[t][o],this.deleteIfEmpty({siteID:e,boardID:t})}return delete this.data[e].boards[t]}),i)}deleteIfEmpty({siteID:e,boardID:t,threadID:n}){if(this.data[e])if(n){
|
||||
;if(e instanceof Array){const t=[];for(let n=0,o=e.length;n<o;n++)t.push(m.clone(e[n]));return t}{const o=Object.create(null);for(var t in e){var n=e[t];o[t]=m.clone(n)}return o}},m.json=e=>m.clone(JSON.parse(e));const b=1e3,A=6e4,v=36e5,w=24*v,x=window.GM_xmlhttpRequest?"userscript":"crx";class y{static initClass(){this.keys=["hiddenThreads","hiddenPosts","lastReadPosts","yourPosts","watchedThreads","watcherLastModified","customTitles"]}constructor(e,n,o){if(this.changes=[],this.onSync=this.onSync.bind(this),this.key=e,this.initData(t[this.key]),Ve.sync(this.key,this.onSync),o||this.clean(),n){var i=()=>(Ve.off(a,"4chanXInitFinished",i),this.sync=n);Ve.on(a,"4chanXInitFinished",i)}}initData(e){let t;if(this.data=e,this.data.boards){let e;({boards:t,lastChecked:e}=this.data),this.data["4chan.org"]={boards:t,lastChecked:e},delete this.data.boards,delete this.data.lastChecked}return this.data[n.SITE.ID]||(this.data[n.SITE.ID]={boards:m()})}save(e,t){return e(),this.changes.push(e),
|
||||
Ve.get(this.key,{boards:m()},(n=>{if(!this.changes.length)return;const o=(n[this.key].version||0)>(this.data.version||0);if(o)for(e of(this.initData(n[this.key]),this.changes))e();return this.changes=[],this.data.version=(this.data.version||0)+1,Ve.set(this.key,this.data,(()=>(o&&this.sync?.(),t?.())))}))}forceSync(e){return Ve.get(this.key,{boards:m()},(t=>{if((t[this.key].version||0)>(this.data.version||0)){for(var n of(this.initData(t[this.key]),this.changes))n();this.sync?.()}return e?.()}))}delete({siteID:e,boardID:t,threadID:o,postID:a},i){if(e||(e=n.SITE.ID),this.data[e])return this.save((()=>{if(a){if(!this.data[e].boards[t]?.[o])return;return delete this.data[e].boards[t][o][a],this.deleteIfEmpty({siteID:e,boardID:t,threadID:o})}if(o){if(!this.data[e].boards[t])return;return delete this.data[e].boards[t][o],this.deleteIfEmpty({siteID:e,boardID:t})}return delete this.data[e].boards[t]}),i)}deleteIfEmpty({siteID:e,boardID:t,threadID:n}){if(this.data[e])if(n){
|
||||
if(!Object.keys(this.data[e].boards[t][n]).length)return delete this.data[e].boards[t][n],this.deleteIfEmpty({siteID:e,boardID:t})}else if(!Object.keys(this.data[e].boards[t]).length)return delete this.data[e].boards[t]}set(e,t){return this.save((()=>this.setUnsafe(e)),t)}setUnsafe({siteID:e,boardID:t,threadID:o,postID:a,val:i}){if(e||(e=n.SITE.ID),this.data[e]||(this.data[e]={boards:m()}),void 0!==a){let n;return((n=this.data[e].boards[t]||(this.data[e].boards[t]=m()))[o]||(n[o]=m()))[a]=i}return void 0!==o?(this.data[e].boards[t]||(this.data[e].boards[t]=m()))[o]=i:this.data[e].boards[t]=i}extend({siteID:e,boardID:t,threadID:n,postID:o,val:a},i){return this.save((()=>{const i=this.get({siteID:e,boardID:t,threadID:n,postID:o,defaultValue:m()});for(var r in a){var s=a[r];void 0===s?delete i[r]:i[r]=s}return this.setUnsafe({siteID:e,boardID:t,threadID:n,postID:o,val:i})}),i)}setLastChecked(e="lastChecked"){return this.save((()=>this.data[e]=Date.now()))}
|
||||
get({siteID:e,boardID:t,threadID:o,postID:a,defaultValue:i}){let r,s;if(e||(e=n.SITE.ID),r=this.data[e]?.boards[t]){let e;if(null==o)if(null!=a){for(e=0;e<r.length;e++)if(r[e],a in e){s=e[a];break}}else s=r;else(e=r[o])&&(s=null!=a?e[a]:e)}return s||i}clean(){let e,t;const o=n.SITE.ID;for(e in this.data[o].boards)this.data[o].boards[e],this.deleteIfEmpty({siteID:o,boardID:e});const a=Date.now();if(a-2*v>=(t=this.data[o].lastChecked||0)||t>a)for(e in this.data[o].lastChecked=a,this.data[o].boards)this.ajaxClean(e)}ajaxClean(e){const t=this,o=n.SITE.ID,a=n.SITE.urls.threadsListJSON?.({siteID:o,boardID:e});if(a)return Ve.cache(a,(function(){if(200!==this.status)return;const a=n.SITE.urls.archiveListJSON?.({siteID:o,boardID:e});if(!a)return t.ajaxCleanParse(e,this.response);const i=this.response;return Ve.cache(a,(function(){if(200===this.status||!n.SITE.archivedBoardsKnown&&404===this.status)return t.ajaxCleanParse(e,i,this.response)}))}))}ajaxCleanParse(e,t,o){let a,i;const r=n.SITE.ID
|
||||
;if(!(a=this.data[r].boards[e]))return;const s=m();if(t)for(var l of t)for(var d of l.threads)i=d.no,i in a&&(s[i]=a[i]);if(o)for(i of o)i in a&&(s[i]=a[i]);return this.data[r].boards[e]=s,this.deleteIfEmpty({siteID:r,boardID:e}),Ve.set(this.key,this.data)}onSync(e){if(!((e.version||0)<=(this.data.version||0)))return this.initData(e),this.sync?.()}}y.initClass();class k{constructor(){this.keys=[]}push(e,t){return this[e=`${e}`]||this.keys.push(e),this[e]=t}rm(e){let t;if(e=`${e}`,-1!==(t=this.keys.indexOf(e)))return this.keys.splice(t,1),delete this[e]}forEach(e){for(var t of this.keys)e(this[t])}get(e){return"keys"===e?void 0:Ve.getOwn(this,e)}}class I{toString(){return this.ID}constructor(e,t){this.board=t,this.ID=+e,this.threadID=this.ID,this.boardID=this.board.ID,this.siteID=n.SITE.ID,this.fullID=`${this.board}.${this.ID}`,this.posts=new k,this.isDead=!1,this.isHidden=!1,this.isSticky=!1,this.isClosed=!1,this.isArchived=!1,this.postLimit=!1,this.fileLimit=!1,this.lastPost=0,
|
||||
@ -434,7 +434,7 @@ Ve.on(Ve(".import",t),"click",Be.import),Ve.on(Ve(".reset",t),"click",Be.reset),
|
||||
download:`${e.name} v${n.VERSION}-${t.date}.json`,href:a}),r=Ve(".imp-exp-result",Be.dialog);return Ve.rmAll(r),Ve.add(r,i),i.click()},import(){return Ve("input[type=file]",this.parentNode).click()},onImport(){let e;if(!(e=this.files[0]))return;this.value=null;const t=Ve(".imp-exp-result");if(!confirm("Your current settings will be entirely overwritten, are you sure?"))return void(t.textContent="Import aborted.");const n=new FileReader;return n.onload=function(e){try{return Be.loadSettings(m.json(e.target.result),(function(e){return e?t.textContent="Import failed due to an error.":confirm("Import successful. Reload now?")?window.location.reload():void 0}))}catch(e){const n=e;return t.textContent="Import failed due to an error.",r.error(n.stack)}},n.readAsText(e)},convertFrom:{loadletter(e){for(var t in"Always CDN"in(e=function(e,t){for(var n in t){var o=t[n];o&&(e.Conf[o]=e.Conf[n]),delete e.Conf[n]}return e}(e,{"Disable 4chan's extension":"Disable Native Extension",
|
||||
"Comment Auto-Expansion":"","Remove Slug":"","Always HTTPS":"Redirect to HTTPS","Check for Updates":"","Recursive Filtering":"Recursive Hiding","Reply Hiding":"Reply Hiding Buttons","Thread Hiding":"Thread Hiding Buttons","Show Stubs":"Stubs","Image Auto-Gif":"Replace GIF","Expand All WebM":"Expand videos","Reveal Spoilers":"Reveal Spoiler Thumbnails","Expand From Current":"Expand from here","Current Page":"Page Count in Stats","Current Page Position":"","Alternative captcha":"Use Recaptcha v1","Alt index captcha":"Use Recaptcha v1 on Index","Auto Submit":"Post on Captcha Completion","Open Reply in New Tab":"Open Post in New Tab","Remember QR size":"Remember QR Size","Remember Subject":"","Quote Inline":"Quote Inlining","Quote Preview":"Quote Previewing","Indicate OP quote":"Mark OP Quotes","Indicate You quote":"Mark Quotes of You","Indicate Cross-thread Quotes":"Mark Cross-thread Quotes",uniqueid:"uniqueID",mod:"capcode",email:"",country:"flag",md5:"MD5",openEmptyQR:"Open empty QR",
|
||||
openQR:"Open QR",openOptions:"Open settings",close:"Close",spoiler:"Spoiler tags",sageru:"Toggle sage",code:"Code tags",sjis:"SJIS tags",submit:"Submit QR",watch:"Watch",update:"Update",unreadCountTo0:"",expandAllImages:"Expand images",expandImage:"Expand image",zero:"Front page",nextPage:"Next page",previousPage:"Previous page",nextThread:"Next thread",previousThread:"Previous thread",expandThread:"Expand thread",openThreadTab:"Open thread",openThread:"Open thread tab",nextReply:"Next reply",previousReply:"Previous reply",hide:"Hide",Scrolling:"Auto Scroll",Verbose:""})).Conf&&(e.Conf.fourchanImageHost=e.Conf["Always CDN"]?"i.4cdn.org":"",delete e.Conf["Always CDN"]),e.Conf.sauces=e.Conf.sauces.replace(/\$\d/g,(function(e){switch(e){case"$1":return"%TURL";case"$2":return"%URL";case"$3":return"%MD5";case"$4":return"%board";default:return e}})),c.hotkeys)c.hotkeys[t],
|
||||
t in e.Conf&&(e.Conf[t]=e.Conf[t].replace(/ctrl|alt|meta/g,(e=>`${e[0].toUpperCase()}${e.slice(1)}`)).replace(/(^|.+\+)[A-Z]$/g,(e=>`Shift+${e.slice(0,-1)}${e.slice(-1).toLowerCase()}`)));if(e.WatchedThreads)for(var n in e.Conf.watchedThreads=m.clone({"4chan.org":{boards:{}}}),e.WatchedThreads){var o=e.WatchedThreads[n];for(var a in o){var i=o[a];(e.Conf.watchedThreads["4chan.org"].boards[n]||(e.Conf.watchedThreads["4chan.org"].boards[n]=m()))[a]={excerpt:i.textContent}}}return e}},upgrade(n,o){let a,i,r;const s=m(),l=(e,t)=>n[e]=s[e]=t,d=function(e,t){if(null==n[e])return l(e,t)},h=function(e){if(null!=n.sauces&&(e=e.filter((e=>n.sauces.indexOf(e.match(/[^#;\s]+|$/)[0])<0))).length)return l("sauces",n.sauces+"\n\n"+e.join("\n"))},u=function(e){if(null==n.usercss&&l("usercss",c.usercss),n.usercss.indexOf(e)<0)return l("usercss",e+"\n\n"+n.usercss)};if(a='"'===o[0])try{o=JSON.parse(o)}catch(e){}const p=o.replace(/\d+/g,(e=>("0000"+e).slice(-5)))
|
||||
t in e.Conf&&(e.Conf[t]=e.Conf[t].replace(/ctrl|alt|meta/g,(e=>`${e[0].toUpperCase()}${e.slice(1)}`)).replace(/(^|.+\+)[A-Z]$/g,(e=>`Shift+${e.slice(0,-1)}${e.slice(-1).toLowerCase()}`)));if(e.WatchedThreads)for(var n in e.Conf.watchedThreads=m.clone({"4chan.org":{boards:{}}}),e.WatchedThreads){var o=e.WatchedThreads[n];for(var a in o){var i=o[a];(e.Conf.watchedThreads["4chan.org"].boards[n]||(e.Conf.watchedThreads["4chan.org"].boards[n]=m()))[a]={excerpt:i.textContent}}}return e}},upgrade(n,o){let a,i,r;const s=m(),l=(e,t)=>n[e]=s[e]=t,d=function(e,t){if(null==n[e])return l(e,t)},h=function(e){if(null!=n.sauces&&(e=e.filter((e=>n.sauces.indexOf(e.match(/[^#;\s]+|$/)[0])<0))).length)return l("sauces",n.sauces+"\n\n"+e.join("\n"))},u=function(e){if(null==n.usercss&&l("usercss",c.usercss),n.usercss.indexOf(e)<0)return l("usercss",e+"\n\n"+n.usercss)};if(a='"'===o[0])try{o=JSON.parse(o)}catch(e){}const p=o.replace(/^XT /i,"").replace(/\d+/g,(e=>e.padStart(5,"0")))
|
||||
;if(p<"00001.00013.00014.00008")for(i in n)if(r=n[i],"string"==typeof r&&"string"!=typeof t[i]&&!["Index Sort","Last Long Reply Thresholds 0","Last Long Reply Thresholds 1"].includes(i)){a=!0;break}if(a)for(i in n)if(r=n[i],"string"==typeof r)try{var g=JSON.parse(r);l(i,g)}catch(e){}if(p<"00001.00011.00008.00000"&&(null==n["Fixed Thread Watcher"]&&l("Fixed Thread Watcher",n["Toggleable Thread Watcher"]??!0),null==n["Exempt Archives from Encryption"]&&l("Exempt Archives from Encryption",n["Except Archives from Encryption"]??!1)),p<"00001.00011.00010.00001"&&null!=n.selectedArchives){const e={Moe:0,"4plebs Archive":3,"Nyafuu Archive":4,"Love is Over":5,"Rebecca Black Tech":8,warosu:10,fgts:15,not4plebs:22,DesuStorage:23,"fireden.net":24,disabled:null};for(var f in n.selectedArchives){var b=n.selectedArchives[f];for(var A in b){var v=b[A];Ve.hasOwn(e,v)&&(b[A]=e[v])}}l("selectedArchives",n.selectedArchives)}if(p<"00001.00011.00016.00000"){let e
|
||||
;(e=c.usercss.match(/\/\* Board title rice \*\/(?:\n.+)*/)[0])&&null!=n.usercss&&n.usercss.indexOf(e)<0&&l("usercss",e+"\n\n"+n.usercss)}if(p<"00001.00011.00017.00000")for(i of["Persistent QR","Color User IDs","Fappe Tyme","Werk Tyme","Highlight Posts Quoting You","Highlight Own Posts"])null==n[i]&&l(i,"Persistent QR"===i);if(p<"00001.00011.00017.00006"&&null!=n.sauces&&l("sauces",n.sauces.replace(/^(#?\s*)http:\/\/iqdb\.org\//gm,"$1//iqdb.org/")),p<"00001.00011.00019.00003"&&!Be.dialog&&Ve.queueTask((()=>Be.warnings.ads((e=>new Xe("warning",[...e.childNodes]))))),p<"00001.00011.00020.00003"){const e={"Inline Cross-thread Quotes Only":!1,"Pass Link":!0};for(i in e){var w=e[i];null==n[i]&&l(i,w)}}if(p<"00001.00011.00021.00003"&&null==n["Remember Your Posts"]&&l("Remember Your Posts",n["Mark Quotes of You"]??!0),p<"00001.00011.00022.00000"&&null!=n.sauces&&(l("sauces",n.sauces.replace(/^(#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(?:IMG|URL))%3Fs\.jpg/gm,"$1")),
|
||||
l("sauces",n.sauces.replace(/^#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(?:IMG|T?URL)(?=$|;)/gm,"$&&safe=off"))),p<"00001.00011.00022.00002"&&null==n["Use Recaptcha v1 in Reports"]&&n["Use Recaptcha v1"]&&!n["Use Recaptcha v2 in Reports"]&&l("Use Recaptcha v1 in Reports",!0),p<"00001.00011.00024.00000"&&null!=n["JSON Navigation"]&&null==n["JSON Index"]&&l("JSON Index",n["JSON Navigation"]),p<"00001.00011.00026.00000"&&(null!=n["Oekaki Links"]&&null==n["Edit Link"]&&l("Edit Link",n["Oekaki Links"]),null==n["Inline Cross-thread Quotes Only"]&&l("Inline Cross-thread Quotes Only",!0)),p<"00001.00011.00030.00000"&&n["Quote Threading"]&&null==n["Thread Quotes"]&&l("Thread Quotes",!0),p<"00001.00011.00032.00000"&&(null!=n.sauces&&l("sauces",n.sauces.replace(/^(#?\s*)http:\/\/3d\.iqdb\.org\//gm,"$1//3d.iqdb.org/")),
|
||||
@ -557,110 +557,109 @@ He.on(a,"4chanXAjaxLoadend",(function(e){let n;if(n=t[e.detail.id]){if(delete t[
|
||||
;if(o=He(t,e))return n(o);var a=new MutationObserver((function(){if(o=He(t,e))return a.disconnect(),n(o)}));return a.observe(e,{childList:!0,subtree:!0})},He.addStyle=function(e,t,n="head"){const o=He.el("style",{textContent:e});return null!=t&&(o.id=t),He.onExists(i,n,(()=>He.add(a.head,o))),o},He.addCSP=function(e){const t=He.el("meta",{httpEquiv:"Content-Security-Policy",content:e});if(a.head)return He.add(a.head,t),He.rm(t);{const e=He.add(i||a,He.el("head"));return He.add(e,t),He.rm(e)}},He.x=function(e,t){return t||(t=a.body),a.evaluate(e,t,null,8,null).singleNodeValue},He.X=function(e,t){return t||(t=a.body),a.evaluate(e,t,null,7,null)},He.addClass=function(e,...t){for(var n of t)e.classList.add(n)},He.rmClass=function(e,...t){for(var n of t)e.classList.remove(n)},He.toggleClass=(e,t)=>e.classList.toggle(t),He.hasClass=(e,t)=>e.classList.contains(t),He.rm=e=>e?.remove(),He.rmAll=e=>e.textContent=null,He.tn=e=>a.createTextNode(e),He.frag=()=>a.createDocumentFragment(),
|
||||
He.nodes=function(e){if(!(e instanceof Array))return e;const t=He.frag();for(var n of e)t.appendChild(n);return t},He.add=(e,t)=>e.appendChild(He.nodes(t)),He.prepend=(e,t)=>e.insertBefore(He.nodes(t),e.firstChild),He.after=(e,t)=>e.parentNode.insertBefore(He.nodes(t),e.nextSibling),He.before=(e,t)=>e.parentNode.insertBefore(He.nodes(t),e),He.replace=(e,t)=>e.parentNode.replaceChild(He.nodes(t),e),He.el=function(e,t,n){const o=a.createElement(e);return t&&He.extend(o,t),n&&He.extend(o,n),o},He.on=function(e,t,n){for(var o of t.split(" "))e.addEventListener(o,n,!1)},He.off=function(e,t,n){for(var o of t.split(" "))e.removeEventListener(o,n,!1)},He.one=function(e,t,n){var o=function(a){return He.off(e,t,o),n.call(this,a)};return He.on(e,t,o)},He.event=function(e,t,n=a){return globalThis.chrome?.extension||null!=t&&"function"==typeof cloneInto&&(t=cloneInto(t,a.defaultView)),n.dispatchEvent(new CustomEvent(e,{bubbles:!0,cancelable:!0,detail:t}))},"userscript"===x&&function(){
|
||||
if(/PaleMoon\//.test(navigator.userAgent)&&!(+GM_info?.version?.split(".")[0]<2)&&"undefined"==typeof cloneInto)try{return new CustomEvent("x",{detail:{}})}catch(t){const n={Object:unsafeWindow.Object,Array:unsafeWindow.Array};var e=function(t){let o;if(null!=t&&"object"==typeof t&&(o=n[t.constructor.name])){const n=new o;for(var a in t){var i=t[a];n[a]=e(i)}return n}return t};return He.event=(t,n,o=a)=>o.dispatchEvent(new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:e(n)}))}}(),He.modifiedClick=e=>e.shiftKey||e.altKey||e.ctrlKey||e.metaKey||0!==e.button,He.open=globalThis.chrome?.extension?e=>window.open(e,"_blank"):null!=GM?.openInTab?GM.openInTab:"undefined"!=typeof GM_openInTab&&null!==GM_openInTab?GM_openInTab:e=>window.open(e,"_blank"),He.debounce=function(e,t){let n=0,o=null,a=null,i=null;const r=function(){return n=Date.now(),t.apply(a,i)};return function(){return i=arguments,a=this,n<Date.now()-e?r():(clearTimeout(o),o=setTimeout(r,e))}},He.queueTask=function(){
|
||||
const e=[],t=function(){const t=e.shift(),n=t[0],o=Array.prototype.slice.call(t,1);return n.apply(n,o)};if(window.MessageChannel){const n=new MessageChannel;return n.port1.onmessage=t,function(){return e.push(arguments),n.port2.postMessage(null)}}return function(){return e.push(arguments),setTimeout(t,0)}}(),He.global=function(e,t){if(i){const n=He.el("script",{textContent:`(${e}).call(document.currentScript.dataset);`});return t&&He.extend(n.dataset,t),He.add(a.head||i,n),He.rm(n),n.dataset}try{e.call(t)}catch(e){}return t},He.bytesToString=function(e){let t=0;for(;e>=1024;)e/=1024,t++;return`${e=t>1?Math.round(100*e)/100:Math.round(e)} ${["B","KB","MB","GB"][t]}`},He.minmax=(e,t,n)=>e<t?t:e>n?n:e,He.hasAudio=e=>e.mozHasAudio||!!e.webkitAudioDecodedByteCount||"AUDIO"===e.nextElementSibling?.tagName,He.luma=e=>.299*e[0]+.587*e[1]+.114*e[2],He.unescape=function(e){return null==e?e:e.replace(/<[^>]*>/g,"").replace(/&(amp|#039|quot|lt|gt|#44);/g,(e=>({"&":"&","'":"'",
|
||||
""":'"',"<":"<",">":">",",":","}[e])))},He.isImage=e=>/\.(jpe?g|jfif|png|gif|bmp|webp|avif|jxl)$/i.test(e),He.isVideo=e=>/\.(webm|mp4|ogv)$/i.test(e),He.engine=/Edge\//.test(navigator.userAgent)?"edge":/Chrome\//.test(navigator.userAgent)?"blink":/WebKit\//.test(navigator.userAgent)?"webkit":/Gecko\/|Goanna/.test(navigator.userAgent)?"gecko":void 0,He.hasStorage=function(){try{return"true"===localStorage.getItem(n.NAMESPACE+"hasStorage")||(localStorage.setItem(n.NAMESPACE+"hasStorage","true"),"true"===localStorage.getItem(n.NAMESPACE+"hasStorage"))}catch(e){return!1}}(),He.item=function(e,t){const n=m();return n[e]=t,n},He.oneItemSugar=e=>function(t,n,o){return"string"==typeof t?e(He.item(t,n),o):e(t,n)},He.syncing=m(),He.securityCheck=function(e){if("https:"!==location.protocol)return delete e["Redirect to HTTPS"]},"crx"===x?(He.oldValue={local:m(),sync:m()},chrome.storage.onChanged.addListener((function(e,t){for(var n in e){
|
||||
var o=He.oldValue.local[n]??He.oldValue.sync[n];He.oldValue[t][n]=m.clone(e[n].newValue);var a=He.oldValue.local[n]??He.oldValue.sync[n],i=He.syncing[n];i&&JSON.stringify(a)!==JSON.stringify(o)&&i(a,n)}})),He.sync=(e,t)=>He.syncing[e]=t,He.forceSync=function(){},He.crxWorking=function(){try{if(chrome.runtime.getManifest())return!0}catch(e){}if(!He.crxWarningShown){const e=He.el("div",{innerHTML:'4chan X seems to have been updated. You will need to <a href="javascript:;">reload</a> the page.'});He.on(He("a",e),"click",(()=>location.reload())),new Xe("warning",e),He.crxWarningShown=!0}return!1},He.get=He.oneItemSugar((function(e,t){if(!He.crxWorking())return;const n={},o=function(o){let a=Object.keys(e);return"gecko"===He.engine&&"sync"===o&&a.length>3&&(a=null),chrome.storage[o].get(a,(function(i){let s;if(i=m.clone(i),chrome.runtime.lastError&&r.error(chrome.runtime.lastError.message),null===a){const t=m();for(s in i){var l=i[s];He.hasOwn(e,s)&&(t[s]=l)}i=t}
|
||||
for(s in e)He.oldValue[o][s]=i[s];if(n[o]=i,n.local&&n.sync)return He.extend(e,n.sync),He.extend(e,n.local),t(e)}))};return o("local"),o("sync")})),function(){const e={local:m(),sync:m()},t=(e,t)=>unescape(encodeURIComponent(JSON.stringify(e))).length+unescape(encodeURIComponent(JSON.stringify(t))).length>chrome.storage.sync.QUOTA_BYTES_PER_ITEM;He.delete=function(t){if(He.crxWorking()){for(var n of("string"==typeof t&&(t=[t]),t))delete e.local[n],delete e.sync[n];return chrome.storage.local.remove(t),chrome.storage.sync.remove(t)}};const n={};var o=function(i,s){const l=m();if(He.extend(l,e[i]),Object.keys(l).length&&!(n[i]>Date.now()))return chrome.storage[i].set(l,(function(){let d,c;if(d=chrome.runtime.lastError)return r.error(d.message),setTimeout(o,A,i),n[i]=Date.now()+A,s?.(d);for(c in delete n[i],l)e[i][c]===l[c]&&delete e[i][c];if("local"===i){for(c in l){var h=l[c];t(c,h)||(e.sync[c]=h)}a()}else chrome.storage.local.remove((()=>{const t=[];for(c in l)c in e.local||t.push(c)
|
||||
;return t})());return s?.()}))},a=f(b,(()=>o("sync")));He.set=He.oneItemSugar((function(t,n){if(He.crxWorking())return He.securityCheck(t),He.extend(e.local,t),o("local",n)})),He.clear=function(t){if(!He.crxWorking())return;e.local=m(),e.sync=m();let n=2,o=null;const a=function(){if(chrome.runtime.lastError&&r.error(chrome.runtime.lastError.message),null==o&&(o=chrome.runtime.lastError),!--n)return t?.(o)};return chrome.storage.local.clear(a),chrome.storage.sync.clear(a)}}()):null==GM?.deleteValue||!window.BroadcastChannel||"undefined"!=typeof GM_addValueChangeListener&&null!==GM_addValueChangeListener?("undefined"!=typeof GM_deleteValue&&null!==GM_deleteValue||(He.perProtocolSettings=!0),"undefined"!=typeof GM_deleteValue&&null!==GM_deleteValue?(He.getValue=GM_getValue,He.listValues=()=>GM_listValues()):He.hasStorage?(He.getValue=e=>localStorage.getItem(e),He.listValues=()=>(()=>{const e=[];for(var t in localStorage)t.slice(0,n.NAMESPACE.length)===n.NAMESPACE&&e.push(t);return e
|
||||
})()):(He.getValue=function(){},He.listValues=()=>[]),"undefined"!=typeof GM_addValueChangeListener&&null!==GM_addValueChangeListener?(He.setValue=GM_setValue,He.deleteValue=GM_deleteValue):"undefined"!=typeof GM_deleteValue&&null!==GM_deleteValue?(He.oldValue=m(),He.setValue=function(e,t){if(GM_setValue(e,t),e in He.syncing&&(He.oldValue[e]=t,He.hasStorage))return localStorage.setItem(e,t)},He.deleteValue=function(e){if(GM_deleteValue(e),e in He.syncing&&(delete He.oldValue[e],He.hasStorage))return localStorage.removeItem(e)},He.hasStorage||(He.cantSync=!0)):He.hasStorage?(He.oldValue=m(),He.setValue=function(e,t){return e in He.syncing&&(He.oldValue[e]=t),localStorage.setItem(e,t)},He.deleteValue=function(e){return e in He.syncing&&delete He.oldValue[e],localStorage.removeItem(e)}):(He.setValue=function(){},He.deleteValue=function(){},He.cantSync=He.cantSet=!0),
|
||||
"undefined"!=typeof GM_addValueChangeListener&&null!==GM_addValueChangeListener?(He.sync=(e,t)=>He.syncing[e]=GM_addValueChangeListener(n.NAMESPACE+e,(function(n,o,a,i){if(i)return void 0!==a&&(a=m.json(a)),t(a,e)})),He.forceSync=function(){}):"undefined"!=typeof GM_deleteValue&&null!==GM_deleteValue||He.hasStorage?(He.sync=function(e,t){return e=n.NAMESPACE+e,He.syncing[e]=t,He.oldValue[e]=He.getValue(e)},function(){const e=function({key:e,newValue:t}){let o;if(o=He.syncing[e]){if(null!=t){if(t===He.oldValue[e])return;return He.oldValue[e]=t,o(m.json(t),e.slice(n.NAMESPACE.length))}if(null!=He.oldValue[e])return delete He.oldValue[e],o(void 0,e.slice(n.NAMESPACE.length))}};He.on(window,"storage",e),He.forceSync=function(t){return t=n.NAMESPACE+t,e({key:t,newValue:He.getValue(t)})}}()):(He.sync=function(){},He.forceSync=function(){}),He.delete=function(e){for(var t of(e instanceof Array||(e=[e]),e))He.deleteValue(n.NAMESPACE+t)},
|
||||
He.get=He.oneItemSugar(((e,t)=>He.queueTask(He.getSync,e,t))),He.getSync=function(e,t){for(var o in e){var a;if(a=He.getValue(n.NAMESPACE+o))try{e[o]=m.json(a)}catch(e){if(!/^(?:undefined)*$/.test(a))throw e}}return t(e)},He.set=He.oneItemSugar((function(e,t){return He.securityCheck(e),He.queueTask((function(){for(var o in e){var a=e[o];He.setValue(n.NAMESPACE+o,JSON.stringify(a))}return t?.()}))})),He.clear=function(e){He.delete(Object.keys(t)),He.delete(["previousversion","QR Size","QR.persona"]);try{He.delete(He.listValues().map((e=>e.replace(n.NAMESPACE,""))))}catch(e){}return e?.()}):(He.syncChannel=new BroadcastChannel(n.NAMESPACE+"sync"),He.on(He.syncChannel,"message",(e=>(()=>{const t=[];for(var n in e.data){var o,a=e.data[n];(o=He.syncing[n])&&t.push(o(m.json(JSON.stringify(a)),n))}return t})())),He.sync=(e,t)=>He.syncing[e]=t,He.forceSync=function(){},He.delete=function(e,t){let o;return e instanceof Array||(e=[e]),Promise.all((()=>{const t=[]
|
||||
;for(o of e)t.push(GM.deleteValue(n.NAMESPACE+o));return t})()).then((function(){const n=m();for(o of e)n[o]=void 0;return He.syncChannel.postMessage(n),t?.()}))},He.get=He.oneItemSugar((function(e,t){const o=Object.keys(e);return Promise.all(o.map((e=>GM.getValue(n.NAMESPACE+e)))).then((function(n){for(let t=0;t<n.length;t++){var a=n[t];a&&(e[o[t]]=m.json(a))}return t(e)}))})),He.set=He.oneItemSugar((function(e,t){return He.securityCheck(e),Promise.all((()=>{const t=[];for(var o in e){var a=e[o];t.push(GM.setValue(n.NAMESPACE+o,JSON.stringify(a)))}return t})()).then((function(){return He.syncChannel.postMessage(e),t?.()}))})),He.clear=e=>GM.listValues().then((t=>He.delete(t.map((e=>e.replace(n.NAMESPACE,""))),e))).catch((()=>He.delete(Object.keys(t).concat(["previousversion","QR Size","QR.persona"]),e))));var Ve=He,Qe={url(e,t,...o){let a,i;return(i=n.sites[t.siteID])&&(a=Ve.getOwn(i.urls,e))?a(t,...o):void 0},threadExcerpt(e){
|
||||
const{OP:t}=e,n=`/${decodeURIComponent(e.board.ID)}/ - `+(t.info.subject?.trim()||t.commentDisplay().replace(/\n+/g," // ")||t.file?.name||`No.${t}`);return n.length>73?`${n.slice(0,70)}...`:n},threadFromRoot(e){if(null==e)return null;const{board:t}=e.dataset;return n.threads.get(`${t?encodeURIComponent(t):n.BOARD.ID}.${e.id.match(/\d*$/)[0]}`)},threadFromNode:e=>Qe.threadFromRoot(Ve.x(`ancestor-or-self::${n.SITE.xpath.thread}`,e)),postFromRoot(e){if(null==e)return null;const t=n.posts.get(e.dataset.fullID),o=e.dataset.clone;return o?t.clones[+o]:t},postFromNode:e=>Qe.postFromRoot(Ve.x(`ancestor-or-self::${n.SITE.xpath.postContainer}[1]`,e)),postDataFromLink(e){let t,o,a;if(e.dataset.postID)({boardID:t,threadID:a,postID:o}=e.dataset),a||(a=0);else{const i=e.href.match(n.SITE.regexp.quotelink);[t,a,o]=i.slice(1),o||(o=a)}return{boardID:t,threadID:+a,postID:+o}},allQuotelinksLinkingTo(e){const o=[],{posts:a}=n,{fullID:i}=e,r=function(e,t){for(var n of(o.push(...e.nodes[t]||[]),
|
||||
e.clones))o.push(...n.nodes[t]||[])};if(a.forEach((function(e){if(e.quotes.includes(i))return r(e,"quotelinks")})),t["Quote Backlinks"])for(var s of e.quotes){var l;(l=a.get(s))&&r(l,"backlinks")}return o.filter((function(t){const{boardID:n,postID:o}=Qe.postDataFromLink(t);return n===e.board.ID&&o===e.ID}))}},ze=Qe,We={filters:new Map,init(){if(["index","thread","catalog"].includes(n.VIEW)&&t.Filter&&("catalog"!==n.VIEW||t["Filter in Native Catalog"])){for(var e in t["Filtered Backlinks"]||Ve.addClass(i,"hide-backlinks"),c.filter)for(var o of t[e].split("\n")){let n,i,l,c,m;if("#"===o[0])continue;if(!(l=o.match(/\/(.*)\/(\w*)/)))continue;var a=o.replace(l[0],""),r=this.parseBoards(a.match(/(?:^|;)\s*boards:([^;]+)/)?.[1]),s=this.parseBoards(a.match(/(?:^|;)\s*exclude:([^;]+)/)?.[1]);if(i=["uniqueID","MD5"].includes(e))l=l[1];else try{l=RegExp(l[1],l[2])}catch(t){new Xe("warning",[Ve.tn(`Invalid ${e} filter:`),Ve.el("br"),Ve.tn(o),Ve.el("br"),Ve.tn(t.message)],60);continue}
|
||||
var d=a.match(/(?:^|;)\s*op:(no|only)/)?.[1]||"",h=Ve.getOwn({no:1,only:2},d)||0,u=a.match(/(?:^|;)\s*file:(no|only)/)?.[1]||"";h|=Ve.getOwn({no:4,only:8},u)||0;var p=(()=>{switch(a.match(/(?:^|;)\s*stub:(yes|no)/)?.[1]){case"yes":return!0;case"no":return!1;default:return t.Stubs}})(),g=/(?:^|;)\s*notify/.test(a);(n=/(?:^|;)\s*highlight/.test(a))&&(n=a.match(/(?:^|;)\s*highlight:([\w-]+)/)?.[1]||"filter-highlight",c=a.match(/(?:^|;)\s*top:(yes|no)/)?.[1]||"yes",c="yes"===c),"general"===e&&(m=(m=a.match(/(?:^|;)\s*type:([^;]*)/))?m[1].split(","):["subject","name","filename","comment"]);const b={isstring:i,regexp:l,boards:r,excludes:s,mask:h,hide:!(n||g),stub:p,hl:n,top:c,noti:g};if("general"===e)for(var f of m)this.filters.get(f)?.push(b)??this.filters.set(f,[b]);else this.filters.get(e)?.push(b)??this.filters.set(e,[b])}if(this.filters.size){for(const e of["MD5","uniqueID"]){const t=this.filters.get(e);if(!t)continue;const n=new Map
|
||||
;for(const e of t)n.get(e.regexp)?.push(e)??n.set(e.regexp,[e]);this.filters.set(e,n)}return"catalog"===n.VIEW?We.catalog():l.Post.push({name:"Filter",cb:this.node})}}},parseBoards(e){let t;if(!e)return!1;if(t=We.parseBoardsMemo[e])return t;t=m();let o="";for(var a of e.split(","))for(var i in a.includes(":")&&([o,a]=a.split(":").slice(-2)),n.sites){var r=n.sites[i];if(i.slice(0,o.length)===o)if(["nsfw","sfw"].includes(a))for(var s of r.sfwBoards?.("sfw"===a)||[])t[`${i}/${s}`]=!0;else t[`${i}/${encodeURIComponent(a)}`]=!0}return We.parseBoardsMemo[e]=t,t},parseBoardsMemo:m(),test(e,t=!0){if(e.filterResults)return e.filterResults;let n,o=!1,a=!0,i=!1,r=!1;_.isYou(e)&&(t=!1);let s=e.isReply?2:1;s|=e.file?4:8;const l=`${e.siteID}/${e.boardID}`,d=`${e.siteID}/*`;for(const c of We.filters.keys())for(const h of We.values(c,e)){const e=We.filters.get(c),u=Array.isArray(e)?e:e.get(h)
|
||||
;if(u)for(const e of u)e.boards&&!e.boards[l]&&!e.boards[d]||e.excludes&&(e.excludes[l]||e.excludes[d])||e.mask&s||!(e.isstring?e.regexp===h:e.regexp.test(h))||(e.hide?t&&(o=!0,a&&({stub:a}=e)):(n&&n.includes(e.hl)||(n||(n=[])).push(e.hl),i||({top:i}=e),e.noti&&(r=!0)))}return o?{hide:o,stub:a}:{hl:n,top:i,noti:r}},node(){if(this.isClone)return;const{hide:e,stub:t,hl:o,top:a,noti:i}=We.test(this,!this.isFetchedQuote&&(this.isReply||"index"===n.VIEW));return e?this.isReply?W.hide(this,t):pe.hide(this.thread,t):o&&(this.highlights=o,Ve.addClass(this.nodes.root,...o)),i&&ee.posts&&this.ID>ee.lastReadPost&&!_.isYou(this)?ee.openNotification(this," triggered a notification filter"):void 0},catalog(){let e;if(e=n.SITE.urls.catalogJSON?.(n.BOARD))return We.catalogData=m(),Ve.ajax(e,{onloadend:We.catalogParse}),l.CatalogThreadNative.push({name:"Filter",cb:this.catalogNode})},catalogParse(){if([200,404].includes(this.status)){
|
||||
for(var e of this.response)for(var t of e.threads)We.catalogData[t.no]=t;n.BOARD.threads.forEach((function(e){if(e.catalogViewNative)return We.catalogNode.call(e.catalogViewNative)}))}else new Xe("warning","Failed to fetch catalog JSON data. "+(this.status?`Error ${this.statusText} (${this.status})`:"Connection Error"),1)},catalogNode(){if(this.boardID!==n.BOARD.ID||!We.catalogData[this.ID])return;if(_.db?.get({siteID:n.SITE.ID,boardID:this.boardID,threadID:this.ID,postID:this.ID}))return;const{hide:e,hl:t,top:o}=We.test(n.SITE.Build.parseJSON(We.catalogData[this.ID],this));return e?this.nodes.root.hidden=!0:(t&&(this.highlights=t,Ve.addClass(this.nodes.root,...t)),o?(Ve.prepend(this.nodes.root.parentNode,this.nodes.root),n.SITE.catalogPin?.(this.nodes.root)):void 0)},isHidden:e=>!!We.test(e).hide,valueF:{postID:e=>[`${e.ID}`],name:e=>void 0===e.info.name?[]:[e.info.name],uniqueID:e=>[e.info.uniqueID||""],tripcode:e=>void 0===e.info.tripcode?[]:[e.info.tripcode],
|
||||
capcode:e=>void 0===e.info.capcode?[]:[e.info.capcode],pass:e=>[e.info.pass],email:e=>[e.info.email],subject:e=>[e.info.subject||(e.isReply?void 0:"")],comment:e=>(null==e.info.comment&&(e.info.comment=n.sites[e.siteID]?.Build?.parseComment?.(e.info.commentHTML.innerHTML)),[e.info.comment]),flag:e=>void 0===e.info.flag?[]:[e.info.flag],filename:e=>e.files.map((e=>e.name)),dimensions:e=>e.files.map((e=>e.dimensions)),filesize:e=>e.files.map((e=>e.size)),MD5:e=>e.files.map((e=>e.MD5))},values:(e,t)=>Ve.hasOwn(We.valueF,e)?We.valueF[e](t).filter((e=>null!=e)):[e.split("+").map((function(e){let n;return(n=Ve.getOwn(We.valueF,e))?n(t).map((e=>e||"")).join("\n"):""})).join("\n")],addFilter(e,n,o){if(Ve.hasOwn(c.filter,e))return Ve.get(e,t[e],(function(t){let a=t[e];return a=a?`${a}\n${n}`:n,Ve.set(e,a,o)}))},removeFilters:(e,n,o)=>Ve.get(e,t[e],(function(t){let a=t[e];const i=(Array.isArray(n)?n:[...n.values()].flat()).map(We.escape).join("|")
|
||||
;return a=a.replace(RegExp(`(?:$\n|^)(?:${i})$`,"mg"),""),Ve.set(e,a,o)})),showFilters(e){Be.open("Filter");const t=Ve(".section-container"),n=Ve("select[name=filter]",t);return n.value=e,Be.selectFilter.call(n),Ve.onExists(t,"textarea",(function(e){const t=e.textLength;return e.setSelectionRange(t,t),e.focus()}))},quickFilterMD5(){const e=ze.postFromNode(this),o=e.files.filter((e=>e.MD5));if(!o.length)return;const a=o.map((e=>`/${e.MD5}/`)).join("\n");We.addFilter("MD5",a);const i=e.origin||e;if(i.isReply?W.hide(i):"index"===n.VIEW&&pe.hide(i.thread),!t["MD5 Quick Filter Notifications"])return void(e.nodes.post.getBoundingClientRect().height&&new Xe("info","MD5 filtered.",2));let{notice:r}=We.quickFilterMD5;if(r)return r.filters.push(a),r.posts.push(i),Ve("span",r.el).textContent=`${r.filters.length} MD5s filtered.`;{const e=Ve.el("div",{innerHTML:'<span>MD5 filtered.</span> [<a href="javascript:;">show</a>] [<a href="javascript:;">undo</a>]'})
|
||||
;r=We.quickFilterMD5.notice=new Xe("info",e,void 0,(()=>delete We.quickFilterMD5.notice)),r.filters=[a],r.posts=[i];const t=u("a",e);return Ve.on(t[0],"click",We.quickFilterCB.show.bind(r)),Ve.on(t[1],"click",We.quickFilterCB.undo.bind(r))}},quickFilterCB:{show(){return We.showFilters("MD5"),this.close()},undo(){for(var e of(We.removeFilters("MD5",this.filters),this.posts))e.isReply?W.show(e):"index"===n.VIEW&&pe.show(e.thread);return this.close()}},escape:e=>e.replace(new RegExp("/|\\\\|\\^|\\$|\\n|\\.|\\(|\\)|\\{|\\}|\\[|\\]|\\?|\\*|\\+|\\|","g"),(function(e){return"\n"===e?"\\n":"\\"===e?"\\\\":`\\${e}`})),menu:{init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t.Filter)return;const e={el:Ve.el("div",{textContent:"Filter"}),order:50,open:e=>(We.menu.post=e,!0),subEntries:[]}
|
||||
;for(var o of[["Name","name"],["Unique ID","uniqueID"],["Tripcode","tripcode"],["Capcode","capcode"],["Pass Date","pass"],["Email","email"],["Subject","subject"],["Comment","comment"],["Flag","flag"],["Filename","filename"],["Image dimensions","dimensions"],["Filesize","filesize"],["Image MD5","MD5"]])e.subEntries.push(We.menu.createSubEntry(o[0],o[1]));return Q.menu.addEntry(e)},createSubEntry(e,t){const n=Ve.el("a",{href:"javascript:;",textContent:e});return n.dataset.type=t,Ve.on(n,"click",We.menu.makeFilter),{el:n,open:e=>We.values(t,e).length}},makeFilter(){const{type:e}=this.dataset,t=We.values(e,We.menu.post).map((function(t){const n=["uniqueID","MD5"].includes(e)?t:We.escape(t);return["uniqueID","MD5"].includes(e)?`/${n}/`:`/^${n}$/`})).join("\n");return We.addFilter(e,t,(()=>We.showFilters(e)))}}},Ge={defaultProperties:{"4chan.org":{software:"yotsuba"},"4channel.org":{canonical:"4chan.org"},"4cdn.org":{canonical:"4chan.org"},"notso.smuglo.li":{canonical:"smuglo.li"},
|
||||
"smugloli.net":{canonical:"smuglo.li"},"smug.nepu.moe":{canonical:"smuglo.li"}},init(e){Ve.extend(t.siteProperties,Ge.defaultProperties);let o=Ge.resolve();return o&&Ve.hasOwn(Ce,t.siteProperties[o].software)&&(this.set(o),e()),Ve.onExists(i,"body",(()=>{for(var a in Ce){var i;if(i=Ce[a].detect?.()){i.software=a,o=location.hostname.replace(/^www\./,"");var r=t.siteProperties[o]||(t.siteProperties[o]=m()),s=0;for(var l in i)r[l]!==i[l]&&(r[l]=i[l],s++);return s&&Ve.set("siteProperties",t.siteProperties),void(n.SITE||(this.set(o),e()))}}}))},resolve(e=location){let{hostname:n}=e;for(;n&&!Ve.hasOwn(t.siteProperties,n);)n=n.replace(/^[^.]*\.?/,"");if(n){let e;(e=t.siteProperties[n].canonical)&&(n=e)}return n},parseURL(e){const t=Ge.resolve(e);return Ot.parseURL(n.sites[t],e)},set(e){for(var o in t.siteProperties){var a,i=t.siteProperties[o];if(!i.canonical){var{software:r}=i;r&&Ve.hasOwn(Ce,r)&&(n.sites[o]=a=Object.create(Ce[r]),Ve.extend(a,{ID:o,siteID:o,properties:i,software:r}))}}
|
||||
return n.SITE=n.sites[e]}},Ye={init(){if("yotsuba"===n.SITE.software&&(t["External Catalog"]||t["JSON Index"])&&(!t["JSON Index"]||"index"!==n.VIEW)){const o=(()=>{switch(n.VIEW){case"thread":case"archive":return".navLinks.desktop > a";case"catalog":return".navLinks > :first-child > a";case"index":return"#ctrl-top > a, .cataloglink > a"}})();Ve.ready((function(){for(var a of u(o)){var i;switch(a.pathname.replace(/\/+/g,"/")){case`/${n.BOARD}/`:t["JSON Index"]&&(a.textContent="Index"),a.href=Ye.index();break;case`/${n.BOARD}/catalog`:a.href=Ye.catalog()}if("catalog"===n.VIEW&&(i=Ye.catalog())!==n.SITE.urls.catalog?.(n.BOARD)){var r=a.parentNode.cloneNode(!0),s=r.firstElementChild;s.href=i,s.textContent=s.hostname===location.hostname?`${e.name} Catalog`:"External Catalog",Ve.after(a.parentNode,[Ve.tn(" "),r])}}}))}if("yotsuba"===n.SITE.software&&t["JSON Index"]&&t[`Use ${e.name} Catalog`]&&l.Post.push({name:"Catalog Link Rewrite",cb:this.node}),this.enabled=t["Catalog Links"]){let e
|
||||
;Ye.el=e=L.checkbox("Header catalog links","Catalog Links"),e.id="toggleCatalog";const t=Ve("input",e);return Ve.on(t,"change",this.toggle),Ve.sync("Header catalog links",Ye.set),Ke.menu.addEntry({el:e,order:95})}},node(){for(var e of u("a",this.nodes.comment)){var t;(t=e.href.match(/^https?:\/\/(boards\.4chan(?:nel)?\.org\/[^\/]+)\/catalog(#s=.*)?/))&&(e.href=`//${t[1]}/${t[2]||"#catalog"}`)}},toggle(){return Ve.event("CloseMenu"),Ve.set("Header catalog links",this.checked),Ye.set(this.checked)},set:e=>(t["Header catalog links"]=e,Ye.setLinks(Ke.boardList),Ye.setLinks(Ke.bottomBoardList),Ye.el.title=`Turn catalog links ${e?"off":"on"}.`,Ve("input",Ye.el).checked=e),setLinks(e){if(!(Ye.enabled??t["Catalog Links"])||!e)return;const n=/(?:index)?(?:\.\w+)?$/;for(var o of u("a:not([data-only])",e)){var{siteID:a,boardID:i}=o.dataset;if(!a||!i){var r;if(({siteID:a,boardID:i,VIEW:r}=Ge.parseURL(o)),
|
||||
!a||!i||!["index","catalog"].includes(r)||!o.dataset.indexOptions&&o.href.replace(n,"")!==(ze.url(r,{siteID:a,boardID:i})||"").replace(n,""))continue;Ve.extend(o.dataset,{siteID:a,boardID:i})}var s={siteID:a,boardID:i},l=t["Header catalog links"]?Ye.catalog(s):ze.url("index",s);l&&(o.href=l,o.dataset.indexOptions&&l.split("#")[0]===ze.url("index",s)&&(o.href+=(o.hash?"/":"#")+o.dataset.indexOptions))}},externalParse(){for(var e of(Ye.externalList=m(),t.externalCatalogURLs.split("\n")))if("#"!==e[0]){var n=e.split(";")[0],o=We.parseBoards(e.match(/;boards:([^;]+)/)?.[1]||"*"),a=We.parseBoards(e.match(/;exclude:([^;]+)/)?.[1])||m();for(var i in o)a[i]||a[i.split("/")[0]+"/*"]||(Ye.externalList[i]=n)}},external({siteID:e,boardID:t}){Ye.externalList||Ye.externalParse();const n=Ye.externalList[`${e}/${t}`]||Ye.externalList[`${e}/*`];return n?n.replace(/%board/g,t):void 0},jsonIndex:(e,t)=>n.SITE.ID===e.siteID&&n.BOARD.ID===e.boardID&&"index"===n.VIEW?t:ze.url("index",e)+t,
|
||||
catalog(o=n.BOARD){let a,i;return t["External Catalog"]&&(a=Ye.external(o))?a:ue.enabledOn(o)&&t[`Use ${e.name} Catalog`]?Ye.jsonIndex(o,"#catalog"):(i=ze.url("catalog",o))?i:Ye.external(o)},index:(e=n.BOARD)=>ue.enabledOn(e)?Ye.jsonIndex(e,"#index"):ze.url("index",e)},Je={init(){Ve.onExists(i,"body",(()=>{if(Ot.isThisPageLegit())return Ve.add(this.bar,[this.noticesRoot,this.toggle]),Ve.prepend(a.body,this.bar),Ve.add(a.body,Je.hover),this.setBarPosition(t["Bottom Header"])})),this.menu=new L.Menu("header");const e=Ve.el("span",{className:"menu-button"});Ve.extend(e,{innerHTML:"<i></i>"});const o=L.checkbox,r=o("Fixed Header","Fixed Header"),s=o("Header auto-hide","Auto-hide header"),l=o("Header auto-hide on scroll","Auto-hide header on scroll"),d=o("Bottom Header","Bottom header"),c=o("Centered links","Centered links"),h=o("Custom Board Navigation","Custom board navigation"),p=o("Bottom Board List","Hide bottom board list"),g=o("Shortcut Icons","Shortcut Icons"),f=Ve.el("a",{
|
||||
textContent:"Edit custom board navigation",href:"javascript:;"});if(this.barFixedToggler=r.firstElementChild,this.scrollHeaderToggler=l.firstElementChild,this.barPositionToggler=d.firstElementChild,this.linkJustifyToggler=c.firstElementChild,this.headerToggler=s.firstElementChild,this.footerToggler=p.firstElementChild,this.shortcutToggler=g.firstElementChild,this.customNavToggler=h.firstElementChild,Ve.on(e,"click",this.menuToggle),Ve.on(this.headerToggler,"change",this.toggleBarVisibility),Ve.on(this.barFixedToggler,"change",this.toggleBarFixed),Ve.on(this.barPositionToggler,"change",this.toggleBarPosition),Ve.on(this.scrollHeaderToggler,"change",this.toggleHideBarOnScroll),Ve.on(this.linkJustifyToggler,"change",this.toggleLinkJustify),Ve.on(this.footerToggler,"change",this.toggleFooterVisibility),Ve.on(this.shortcutToggler,"change",this.toggleShortcutIcons),Ve.on(this.customNavToggler,"change",this.toggleCustomNav),Ve.on(f,"click",this.editCustomNav),
|
||||
this.setBarFixed(t["Fixed Header"]),this.setHideBarOnScroll(t["Header auto-hide on scroll"]),this.setBarVisibility(t["Header auto-hide"]),this.setLinkJustify(t["Centered links"]),this.setShortcutIcons(t["Shortcut Icons"]),this.setFooterVisibility(t["Bottom Board List"]),Ve.sync("Fixed Header",this.setBarFixed),Ve.sync("Header auto-hide on scroll",this.setHideBarOnScroll),Ve.sync("Bottom Header",this.setBarPosition),Ve.sync("Shortcut Icons",this.setShortcutIcons),Ve.sync("Header auto-hide",this.setBarVisibility),Ve.sync("Centered links",this.setLinkJustify),Ve.sync("Bottom Board List",this.setFooterVisibility),this.addShortcut("menu",e,900),this.menu.addEntry({el:Ve.el("span",{textContent:"Header"}),order:107,subEntries:[{el:r},{el:s},{el:l},{el:d},{el:c},{el:p},{el:g},{el:h},{el:f}]}),Ve.on(window,"load popstate",Je.hashScroll),Ve.on(a,"CreateNotification",this.createNotification),this.setBoardList(),Ve.onExists(i,`${n.SITE.selectors.boardList} + *`,Je.generateFullBoardList),
|
||||
Ot.ready((function(){let e;if("yotsuba"===n.SITE.software&&!(e=Ve.id("boardNavDesktopFoot"))){let t;if(!(t=Ve.id("absbot")))return;e=Ve.id("boardNavDesktop").cloneNode(!0),e.id="boardNavDesktopFoot",Ve("#navtopright",e).id="navbotright",Ve("#settingsWindowLink",e).id="settingsWindowLinkBot",Ve.before(t,e),Ve.global((()=>window.cloneTopNav=function(){}))}if(Je.bottomBoardList=Ve(n.SITE.selectors.boardListBottom)){for(var t of u("a",Je.bottomBoardList))t.hostname===location.hostname&&t.pathname.split("/")[1]===n.BOARD.ID&&(t.className="current");return Ye.setLinks(Je.bottomBoardList)}})),"yotsuba"===n.SITE.software&&("catalog"===n.VIEW||!t["Disable Native Extension"])){const e=Ve.el("a",{href:"javascript:;"});"catalog"===n.VIEW?(e.title=e.textContent="Catalog Settings",e.textContent="🕮︎"):(e.title=e.textContent="4chan Settings",e.className="native-settings"),Ve.on(e,"click",(()=>Ve.id("settingsWindowLink").click())),this.addShortcut("native",e,810)}
|
||||
return this.enableDesktopNotifications()},bar:Ve.el("div",{id:"header-bar"}),noticesRoot:Ve.el("div",{id:"notifications"}),shortcuts:Ve.el("span",{id:"shortcuts"}),hover:Ve.el("div",{id:"hoverUI"}),toggle:Ve.el("div",{id:"scroll-marker"}),setBoardList(){let e;Je.boardList=e=Ve.el("span",{id:"board-list"}),Ve.extend(e,{innerHTML:'<span id="custom-board-list"></span><span id="full-board-list" hidden><span class="hide-board-list-container brackets-wrap"><a href="javascript:;" class="hide-board-list-button"> - </a></span> <span class="boardList"></span></span>'});const n=Ve(".hide-board-list-button",e);return Ve.on(n,"click",Je.toggleBoardList),Ve.prepend(Je.bar,[Je.boardList,Je.shortcuts]),Je.setCustomNav(t["Custom Board Navigation"]),Je.generateBoardList(t.boardnav),Ve.sync("Custom Board Navigation",Je.setCustomNav),Ve.sync("boardnav",Je.generateBoardList)},generateFullBoardList(){let e
|
||||
;e=n.SITE.transformBoardList?n.SITE.transformBoardList():[...Ve(n.SITE.selectors.boardList).cloneNode(!0).childNodes];const t=Ve(".boardList",Je.boardList);for(var o of(Ve.add(t,e),u("a",t)))o.hostname===location.hostname&&o.pathname.split("/")[1]===n.BOARD.ID&&(o.className="current");return Ye.setLinks(t)},generateBoardList(e){const t=Ve("#custom-board-list",Je.boardList);if(Ve.rmAll(t),!e)return;const n=(e=e.replace(/(\r\n|\n|\r)/g," ")).match(/[\w@]+(-(all|title|replace|full|index|catalog|archive|expired|nt|(mode|sort|text):"[^"]+"(,"[^"]+")?))*|[^\w@]+/g).map((e=>Je.mapCustomNavigation(e)));return Ve.add(t,n),Ye.setLinks(t)},mapCustomNavigation(e){let o,a,i,r;if(/^[^\w@]/.test(e))return Ve.tn(e);let s=r=null;e=e.replace(/-text:"([^"]+)"(?:,"([^"]+)")?/g,(function(e,t,n){return s=t,r=n,""}));let l=[];if(e=e.replace(/-(?:mode|sort):"([^"]+)"/g,(function(e,t){return l.push(t.toLowerCase().replace(/\ /g,"-")),""})),l=l.join("/"),/^toggle-all/.test(e))return o=Ve.el("a",{
|
||||
className:"show-board-list-button",textContent:s||"+",href:"javascript:;"}),Ve.on(o,"click",Je.toggleBoardList),o;if(/^external/.test(e))return o=Ve.el("a",{href:r||"javascript:;",textContent:s||"+",className:"external"}),/-nt/.test(e)&&(o.target="_blank",o.rel="noopener"),o;let d=e.split("-")[0];if("current"===d){if(!["boards.4chan.org","boards.4channel.org"].includes(location.hostname))return o=Ve.el("a",{href:`/${n.BOARD.ID}/`,textContent:s||decodeURIComponent(n.BOARD.ID),className:"current"}),/-nt/.test(e)&&(o.target="_blank",o.rel="noopener"),/-index/.test(e)?o.dataset.only="index":/-catalog/.test(e)?(o.dataset.only="catalog",o.href+="catalog.html"):/-(archive|expired)/.test(e)&&(o=o.firstChild),o;d=n.BOARD.ID}if(o=function(){let e;return"@"===d?Ve.el("a",{href:"https://twitter.com/4chan",title:"4chan Twitter",textContent:"@"}):(o=Ve.el("a",{href:`//${Y.domain(d)}/${d}/`,textContent:d,title:Y.title(d)}),["catalog","archive"].includes(n.VIEW)&&(e=ze.url(n.VIEW,{siteID:"4chan.org",
|
||||
boardID:d}))&&(o.href=e),o.hostname===location.hostname&&d===n.BOARD.ID&&(o.className="current"),o)}(),o.textContent=/-title/.test(e)||/-replace/.test(e)&&o.hostname===location.hostname&&d===n.BOARD.ID?o.title||o.textContent:/-full/.test(e)?`/${d}/`+(o.title?` - ${o.title}`:""):s||d,i=e.match(/-(index|catalog)/)){const e=Ye[i[1]]({siteID:"4chan.org",boardID:d});if(!e)return o.firstChild;o.dataset.only=i[1],o.href=e,"catalog"===i[1]&&Ve.addClass(o,"catalog")}if(t["JSON Index"]&&l&&(o.dataset.indexOptions=l,["boards.4chan.org","boards.4channel.org"].includes(o.hostname)&&""===o.pathname.split("/")[2]&&(o.href+=(o.hash?"/":"#")+l)),/-archive/.test(e)){if(!(a=Ze.to("board",{boardID:d})))return o.firstChild;o.href=a}if(/-expired/.test(e)){if(!Y.isArchived(d))return o.firstChild;o.href=`//${Y.domain(d)}/${d}/archive`}return/-nt/.test(e)&&(o.target="_blank",o.rel="noopener"),"@"===d&&Ve.addClass(o,"navSmall"),o},toggleBoardList(){
|
||||
const{bar:e}=Je,t=Ve("#custom-board-list",e),n=Ve("#full-board-list",e),o=!n.hidden;return t.hidden=!o,n.hidden=o},setLinkJustify:e=>(Je.linkJustifyToggler.checked=e,e?Ve.addClass(i,"centered-links"):Ve.rmClass(i,"centered-links")),toggleLinkJustify(){Ve.event("CloseMenu");const e="INPUT"===this.nodeName?this.checked:void 0;return Je.setLinkJustify(e),Ve.set("Centered links",e)},setBarFixed:e=>(Je.barFixedToggler.checked=e,e?(Ve.addClass(i,"fixed"),Ve.addClass(Je.bar,"dialog")):(Ve.rmClass(i,"fixed"),Ve.rmClass(Je.bar,"dialog"))),toggleBarFixed(){return Ve.event("CloseMenu"),Je.setBarFixed(this.checked),t["Fixed Header"]=this.checked,Ve.set("Fixed Header",this.checked)},setShortcutIcons:e=>(Je.shortcutToggler.checked=e,e?Ve.addClass(i,"shortcut-icons"):Ve.rmClass(i,"shortcut-icons")),toggleShortcutIcons(){return Ve.event("CloseMenu"),Je.setShortcutIcons(this.checked),t["Shortcut Icons"]=this.checked,Ve.set("Shortcut Icons",this.checked)},setBarVisibility:e=>(Je.headerToggler.checked=e,
|
||||
Ve.event("CloseMenu"),(e?Ve.addClass:Ve.rmClass)(Je.bar,"autohide"),(e?Ve.addClass:Ve.rmClass)(i,"autohide")),toggleBarVisibility(){const e="INPUT"===this.nodeName?this.checked:!Ve.hasClass(Je.bar,"autohide");t["Header auto-hide"]=e,Ve.set("Header auto-hide",e),Je.setBarVisibility(e);return new Xe("info","The header bar will "+(e?"automatically hide itself.":"remain visible."),2)},setHideBarOnScroll(e){if(Je.scrollHeaderToggler.checked=e,!e)return Ve.off(window,"scroll",Je.hideBarOnScroll),Ve.rmClass(Je.bar,"scroll"),Je.bar.classList.toggle("autohide",t["Header auto-hide"]);Ve.on(window,"scroll",Je.hideBarOnScroll)},toggleHideBarOnScroll(){const e=this.checked;return Ve.cb.checked.call(this),Je.setHideBarOnScroll(e)},hideBarOnScroll(){const e=window.pageYOffset;return e>(Je.previousOffset||0)?Ve.addClass(Je.bar,"autohide","scroll"):Ve.rmClass(Je.bar,"autohide","scroll"),Je.previousOffset=e},setBarPosition(e){Je.barPositionToggler&&(Je.barPositionToggler.checked=e),Ve.event("CloseMenu")
|
||||
;const t=e?["bottom-header","top-header","after"]:["top-header","bottom-header","add"];return Ve.addClass(i,t[0]),Ve.rmClass(i,t[1]),Ve[t[2]](Je.bar,Je.noticesRoot)},toggleBarPosition(){return Ve.cb.checked.call(this),Je.setBarPosition(this.checked)},setFooterVisibility:e=>(Je.footerToggler.checked=e,i.classList.toggle("hide-bottom-board-list",e)),toggleFooterVisibility(){Ve.event("CloseMenu");const e="INPUT"===this.nodeName?this.checked:Ve.hasClass(i,"hide-bottom-board-list");Je.setFooterVisibility(e),Ve.set("Bottom Board List",e);return new Xe("info",e?"The bottom navigation will now be hidden.":"The bottom navigation will remain visible.",2)},setCustomNav(e){Je.customNavToggler.checked=e;const t=Ve("#custom-board-list",Je.bar),n=Ve("#full-board-list",Je.bar),o=Ve(".hide-board-list-container",n);return[t.hidden,n.hidden,o.hidden]=e?[!1,!0,!1]:[!0,!1,!0]},toggleCustomNav(){return Ve.cb.checked.call(this),Je.setCustomNav(this.checked)},editCustomNav(){Be.open("Advanced")
|
||||
;const e=Ve.id("fourchanx-settings");return Ve("[name=boardnav]",e).focus()},hashScroll(e){let t;if(e){if(e.state)return;history.state||history.replaceState({},"")}if(t=location.hash.slice(1)){let e;if(Se.showIfHidden(t),e=Ve.id(t))return Ve.queueTask((()=>Je.scrollTo(e)))}},scrollTo(e,n,o){let a,i;if(e.offsetParent)if(n){if(i=Je.getBottomOf(e),t["Fixed Header"]&&t["Header auto-hide on scroll"]&&t["Bottom header"]&&(({height:a}=Je.bar.getBoundingClientRect()),i<=0?Je.isHidden()||(i+=a):Je.isHidden()&&(i-=a)),!o||i<0)return window.scrollBy(0,-i)}else if(i=Je.getTopOf(e),t["Fixed Header"]&&t["Header auto-hide on scroll"]&&!t["Bottom header"]&&(({height:a}=Je.bar.getBoundingClientRect()),i>=0?Je.isHidden()||(i+=a):Je.isHidden()&&(i-=a)),!o||i<0)return window.scrollBy(0,i)},scrollToIfNeeded:(e,t)=>Je.scrollTo(e,t,!0),getTopOf(e){let{top:n}=e.getBoundingClientRect();if(t["Fixed Header"]&&!t["Bottom Header"]){const e=Je.toggle.getBoundingClientRect();n-=e.top+e.height}return n},
|
||||
getBottomOf(e){const{clientHeight:n}=i;let o=n-e.getBoundingClientRect().bottom;if(t["Fixed Header"]&&t["Bottom Header"]){const e=Je.toggle.getBoundingClientRect();o-=n-e.bottom+e.height}return o},isNodeVisible(e){if(a.hidden||!i.contains(e))return!1;const{height:t}=e.getBoundingClientRect();return Je.getTopOf(e)+t>=0&&Je.getBottomOf(e)+t>=0},isHidden(){const{top:e}=Je.bar.getBoundingClientRect();return t["Bottom header"]?e===i.clientHeight:e<0},addShortcut(e,t,n){const o=Ve.el("span",{id:`shortcut-${e}`,className:"shortcut brackets-wrap"});for(var a of(Ve.add(o,t),o.dataset.index=n,u("[data-index]",Je.shortcuts)))if(+a.dataset.index>+n)return void Ve.before(a,o);return Ve.add(Je.shortcuts,o)},rmShortcut:e=>Ve.rm(e.parentElement),menuToggle(e){return Je.menu.toggle(e,this,n)},createNotification(e){const{type:t,content:n,lifetime:o}=e.detail;return new Xe(t,n,o)},areNotificationsEnabled:!1,enableDesktopNotifications(){let n;if(!window.Notification||!t["Desktop Notifications"])return
|
||||
;switch(Notification.permission){case"granted":return void(Je.areNotificationsEnabled=!0);case"denied":return}const o=Ve.el("span",{innerHTML:`${e.name} needs your permission to show desktop notifications. [<a href="${e.faq}#why-is-4chan-x-asking-for-permission-to-show-desktop-notifications" target="_blank">FAQ</a>]<br><button>Authorize</button> or <button>Disable</button>`}),[a,i]=u("button",o);return Ve.on(a,"click",(()=>Notification.requestPermission((function(e){if(Je.areNotificationsEnabled="granted"===e,"default"!==e)return n.close()})))),Ve.on(i,"click",(function(){return Ve.set("Desktop Notifications",!1),n.close()})),n=new Xe("info",o)}},Ke=Je;class Xe{constructor(e,t,n,o){this.add=this.add.bind(this),this.close=this.close.bind(this),this.timeout=n,this.onclose=o,this.el=Ve.el("div",{innerHTML:'<a href="javascript:;" class="close" title="Close">✕</a><div class="message"></div>'}),this.el.style.opacity=0,this.setType(e),Ve.on(this.el.firstElementChild,"click",this.close),
|
||||
"string"==typeof t&&(t=Ve.tn(t)),Ve.add(this.el.lastElementChild,t),Ve.ready(this.add)}setType(e){return this.el.className=`notification ${e}`}add(){if(!this.closed){if(!a.hidden)return Ve.off(a,"visibilitychange",this.add),Ve.add(Ke.noticesRoot,this.el),this.el.clientHeight,this.el.style.opacity=1,this.timeout?setTimeout(this.close,this.timeout*b):void 0;Ve.on(a,"visibilitychange",this.add)}}close(){return this.closed=!0,Ve.off(a,"visibilitychange",this.add),Ve.rm(this.el),this.onclose?.()}}var _e={archives:[{uid:3,name:"4plebs",domain:"archive.4plebs.org",http:!0,https:!0,software:"foolfuuka",boards:["adv","f","hr","mlpol","mo","o","pol","s4s","sp","tg","trv","tv","x"],files:["adv","f","hr","mlpol","mo","o","pol","s4s","sp","tg","trv","tv","x"],reports:!0},{uid:10,name:"warosu",domain:"warosu.org",http:!1,https:!0,software:"fuuka",boards:["3","biz","cgl","ck","diy","fa","ic","jp","lit","sci","vr","vt"],files:["3","biz","cgl","ck","diy","fa","ic","jp","lit","sci","vr","vt"],
|
||||
search:["biz","cgl","ck","diy","fa","ic","jp","lit","sci","vr","vt"]},{uid:23,name:"Desuarchive",domain:"desuarchive.org",http:!0,https:!0,software:"foolfuuka",boards:["a","aco","an","c","cgl","co","d","fit","g","his","int","k","m","mlp","mu","q","qa","r9k","tg","trash","vr","wsg"],files:["a","aco","an","c","cgl","co","d","fit","g","his","int","k","m","mlp","mu","q","qa","r9k","tg","trash","vr"],reports:!0},{uid:24,name:"fireden.net",domain:"boards.fireden.net",http:!1,https:!0,software:"foolfuuka",boards:["cm","co","ic","sci","vip","y"],files:["cm","co","ic","sci","vip","y"],search:["cm","co","ic","sci","y"]},{uid:25,name:"arch.b4k.co",domain:"arch.b4k.co",http:!0,https:!0,software:"foolfuuka",boards:["g","mlp","qb","v","vg","vm","vmg","vp","vrpg","vst"],files:["qb","v","vg","vm","vmg","vp","vrpg","vst"],search:["qb","v","vg","vm","vmg","vp","vrpg","vst"]},{uid:29,name:"Archived.Moe",domain:"archived.moe",http:!0,https:!0,software:"foolfuuka",
|
||||
boards:["3","a","aco","adv","an","asp","b","bant","biz","c","can","cgl","ck","cm","co","cock","con","d","diy","e","f","fa","fap","fit","fitlit","g","gd","gif","h","hc","his","hm","hr","i","ic","int","jp","k","lgbt","lit","m","mlp","mlpol","mo","mtv","mu","n","news","o","out","outsoc","p","po","pol","pw","q","qa","qb","qst","r","r9k","s","s4s","sci","soc","sp","spa","t","tg","toy","trash","trv","tv","u","v","vg","vint","vip","vm","vmg","vp","vr","vrpg","vst","vt","w","wg","wsg","wsr","x","xs","y"],files:["can","cock","con","fap","fitlit","gd","mlpol","mo","mtv","outsoc","po","q","qb","qst","spa","vint","vip"],search:["aco","adv","an","asp","b","bant","biz","c","can","cgl","ck","cm","cock","con","d","diy","e","f","fap","fitlit","gd","gif","h","hc","his","hm","hr","i","ic","lgbt","lit","mlpol","mo","mtv","n","news","o","out","outsoc","p","po","pw","q","qa","qst","r","s","soc","spa","trv","u","vint","vip","vrpg","w","wg","wsg","wsr","x","y"],reports:!0},{uid:30,name:"TheBArchive.com",
|
||||
domain:"thebarchive.com",http:!0,https:!0,software:"foolfuuka",boards:["b","bant"],files:["b","bant"],reports:!0},{uid:31,name:"Archive Of Sins",domain:"archiveofsins.com",http:!0,https:!0,software:"foolfuuka",boards:["h","hc","hm","i","lgbt","r","s","soc","t","u"],files:["h","hc","hm","i","lgbt","r","s","soc","t","u"],reports:!0},{uid:34,name:"TokyoChronos",domain:"www.tokyochronos.net",http:!1,https:!0,software:"foolfuuka",boards:["c","g","jp","mu","vp","vrpg","vt"],files:[],reports:!0},{uid:36,name:"palanq.win",domain:"archive.palanq.win",http:!1,https:!0,software:"foolfuuka",boards:["bant","c","con","e","i","n","news","out","p","pw","qst","toy","vip","vp","vt","w","wg","wsr"],files:["bant","c","e","i","n","news","out","p","pw","qst","toy","vip","vp","vt","w","wg","wsr"],reports:!0},{uid:37,name:"Eientei",domain:"eientei.xyz",http:!1,https:!0,software:"Eientei",boards:["3","i","sci","xs"],files:["3","i","sci","xs"],reports:!0}],init(){if(this.selectArchives(),t.archiveAutoUpdate){
|
||||
const e=Date.now();if(e-2*w>=t.lastarchivecheck||t.lastarchivecheck>e)return this.update()}},selectArchives(){let e,n,o,a;const i={thread:m(),post:m(),file:m()},r=m();for(o of t.archives){var s,l,d;for(var c of["boards","files"])o[c]instanceof Array||(o[c]=[]);if(({uid:d,name:s,boards:n,files:a,software:l}=o),["fuuka","foolfuuka"].includes(l))for(e of(r[JSON.stringify(d??s)]=o,n))e in i.thread||(i.thread[e]=o),e in i.post||"foolfuuka"!==l||(i.post[e]=o),!(e in i.file)&&a.includes(e)&&(i.file[e]=o)}for(e in t.selectedArchives){var h=t.selectedArchives[e];for(var u in h){var p,g=h[u];(p=r[JSON.stringify(g)])&&Ve.hasOwn(i,u)&&(n="file"===u?p.files:p.boards,n.includes(e)&&(i[u][e]=p))}}return _e.data=i},update(e){let n;const o=[],a=[];let i=0;for(n of t.archiveLists.split("\n"))"#"!==n[0]&&(n=n.trim(),n&&o.push(n));const r=(e,t,n)=>new Xe("warning",`Error ${t} archive data from\n${e}\n${n}`,20),s=t=>function(){
|
||||
if(200!==this.status)return r(o[t],"fetching",this.status?`Error ${this.statusText} (${this.status})`:"Connection Error");let{response:n}=this;return n instanceof Array||(n=[n]),a[t]=n,i++,i===o.length?_e.parse(a,e):void 0};if(o.length)for(let e=0;e<o.length;e++)if(n=o[e],["[","{"].includes(n[0])){var l;try{l=JSON.parse(n)}catch(e){r(n,"parsing",e.message);continue}s(e).call({status:200,response:l})}else Ue.ajax(n,{onloadend:s(e)});else _e.parse([],e)},parse(e,n){const o=[],a=m();for(var i of e)for(var r of i){var s=JSON.stringify(r.uid??r.name);s in a?Ve.extend(a[s],r):(a[s]=m.clone(r),o.push(r))}const l={archives:o,lastarchivecheck:Date.now()};return Ve.set(l),Ve.extend(t,l),_e.selectArchives(),n?.()},to(e,t){const n=(["search","board"].includes(e)?_e.data.thread:_e.data[e])[t.boardID];return n?_e[e](n,t):""},protocol(e){let{protocol:t}=location;return Ve.getOwn(e,t.slice(0,-1))||(t="https:"===t?"http:":"https:"),`${t}//`},thread(e,{boardID:t,threadID:n,postID:o}){
|
||||
let a=n?`${t}/thread/${n}`:`${t}/post/${o}`;return"foolfuuka"===e.software&&(a+="/"),n&&o&&(a+="foolfuuka"===e.software?`#${o}`:`#p${o}`),`${_e.protocol(e)}${e.domain}/${a}`},post(e,{boardID:t,postID:n}){const o=`${_e.protocol(e)}${e.domain}/_/api/chan/post/?board=${t}&num=${n}`;return _e.securityCheck(o)?o:""},file(e,{boardID:t,filename:n}){if(!n)return"";if("f"===t)n=encodeURIComponent(Ve.unescape(decodeURIComponent(n)));else if(/[sm]\.jpg$/.test(n))return"";return`${_e.protocol(e)}${e.domain}/${t}/full_image/${n}`},board:(e,{boardID:t})=>`${_e.protocol(e)}${e.domain}/${t}/`,search(e,{boardID:t,type:n,value:o}){"capcode"===(n="name"===n?"username":"MD5"===n?"image":n)?o=Ve.getOwn({Developer:"dev",Verified:"ver"},o)||o.toLowerCase():"image"===n&&(o=o.replace(/[+/=]/g,(e=>({"+":"-","/":"_","=":""}[e])))),o=encodeURIComponent(o);const a="foolfuuka"===e.software?`${t}/search/${n}/${o}/`:"image"===n?`${t}/image/${o}`:`${t}/?task=search2&search_${n}=${o}`
|
||||
;return`${_e.protocol(e)}${e.domain}/${a}`},report(e){const n=[];for(var o of t.archives){var{software:a,https:i,reports:r,boards:s,name:l,domain:d}=o;"foolfuuka"===a&&i&&r&&s instanceof Array&&s.includes(e)&&n.push([l,`https://${d}/_/api/chan/offsite_report/`])}return n},securityCheck:e=>/^https:\/\//.test(e)||"http:"===location.protocol||t["Exempt Archives from Encryption"],navigate(e,t,n){_e.data||_e.init();const o=_e.to(e,t);return o&&(_e.securityCheck(o)||confirm(`Redirect to ${o}?\n\nYour connection will not be encrypted.`))?location.replace(o):n?location.replace(n):void 0}},Ze=_e;class et{toString(){return this.ID}constructor(e){this.nodes={root:e,thumb:Ve(n.SITE.selectors.catalog.thumb,e)},this.siteID=n.SITE.ID,this.boardID=this.nodes.thumb.parentNode.pathname.split(/\/+/)[1],this.board=n.boards[this.boardID]||new J(this.boardID),this.ID=this.threadID=+(e.dataset.id||e.id).match(/\d*$/)[0],this.thread=this.board.threads.get(this.ID)||new I(this.ID,this.board)}}const tt={init(){
|
||||
if(t.Anonymize)return Ve.addClass(i,"anonymize")}};var nt={init(){if(["index","thread"].includes(n.VIEW))return t["Image Hover"]&&l.Post.push({name:"Image Hover",cb:this.node}),t["Image Hover in Catalog"]?l.CatalogThread.push({name:"Image Hover",cb:this.catalogNode}):void 0},node(){return this.files.filter((e=>(e.isImage||e.isVideo)&&e.thumb)).map((e=>Ve.on(e.thumb,"mouseover",nt.mouseover(this,e))))},catalogNode(){const e=this.thread.OP.files[0];if(e&&(e.isImage||e.isVideo))return Ve.on(this.nodes.thumb,"mouseover",nt.mouseover(this.thread.OP,e))},mouseover:(e,o)=>function(a){let r,s,l;if(!i.contains(this))return;const{isVideo:d}=o;if(o.isExpanding||o.isExpanded||n.SITE.isThumbExpanded?.(o))return;const c=nt.error(e,o);if(j.cache?.dataset.fileID===`${e.fullID}.${o.index}`?(r=j.popCache(),Ve.on(r,"error",c)):(r=Ve.el(d?"video":"img"),r.dataset.fileID=`${e.fullID}.${o.index}`,Ve.on(r,"error",c),r.src=o.url),t["Restart when Opened"]&&(j.rewind(r),j.rewind(this)),r.id="ihover",
|
||||
Ve.add(Ke.hover,r),d&&(r.loop=!0,r.controls=!1,$.setup(r),t.Autoplay&&(r.play(),"VIDEO"===this.nodeName&&(this.currentTime=r.currentTime))),o.dimensions){[l,s]=o.dimensions.split("x").map((e=>+e));const e=i.clientWidth,t=i.clientHeight-L.hover.padding,n=Math.min(1,e/l,t/s);l*=n,s*=n,r.style.maxWidth=`${l}px`,r.style.maxHeight=`${s}px`}return L.hover({root:this,el:r,latestEvent:a,endEvents:"mouseout click",height:s,width:l,noRemove:!0,cb:()=>(Ve.off(r,"error",c),j.pushCache(r),j.pause(r),Ve.rm(r),r.removeAttribute("style"))})},error:(e,t)=>function(){if(!j.decodeError(this,t))return j.error(this,e,t,3e3,(e=>e?this.src=e+(this.src===e?"?"+Date.now():""):Ve.rm(this)))}},ot={init(){if(!["index","thread","archive"].includes(n.VIEW))return;const e=t["Replace JPG"]||t["Replace PNG"]||t["Replace GIF"]||t["Replace WEBM"];if(!t["Image Prefetching"]&&!e)return;if(l.Post.push({name:"Image Replace",cb:this.node}),Ve.on(a,"PostsInserted",(function(){
|
||||
if(ot.prefetchEnabled||e)return n.posts.forEach(ot.prefetchAll)})),t["Replace WEBM"]&&Ve.on(a,"scroll visibilitychange 4chanXInitFinished PostsInserted",this.playVideos),!t["Image Prefetching"]||!["index","thread"].includes(n.VIEW))return;const o=Ve.el("a",{href:"javascript:;",title:"Prefetch Images",innerHTML:"🗲︎"});return Ve.on(o,"click",this.toggle),Ke.addShortcut("prefetch",o,525)},node(){if(!this.isClone)for(var e of this.files)t["Replace WEBM"]&&e.isVideo&&ot.replaceVideo(this,e),ot.prefetch(this,e)},replaceVideo(e,t){const{thumb:n}=t,o=Ve.el("video",{preload:"none",loop:!0,muted:!0,poster:n.src||n.dataset.src,textContent:n.alt,className:n.className});for(var a of(o.setAttribute("muted","muted"),o.dataset.md5=n.dataset.md5,["height","width","maxHeight","maxWidth"]))o.style[a]=n.style[a];return o.src=t.url,Ve.replace(n,o),t.thumb=o,t.videoThumb=!0},prefetch(e,n){let o,a;const{isImage:r,isVideo:s,thumb:l,url:d}=n;if(n.isPrefetched||!r&&!s||e.isHidden||e.thread.isHidden)return
|
||||
;s?a="WEBM":(a=d.match(/\.([^.]+)$/)?.[1].toUpperCase(),"JPEG"===a&&(a="JPG"));const c=t[`Replace ${a}`]&&!/spoiler/.test(l.src||l.dataset.src);if(!c&&!ot.prefetchEnabled)return;if(Ve.hasClass(i,"catalog-mode"))return;if(![e,...e.clones].some((e=>i.contains(e.nodes.root))))return;if(n.isPrefetched=!0,n.videoThumb){for(o of e.clones)o.file.thumb.preload="auto";return l.preload="auto",void("gecko"===Ve.engine&&Ve.on(l,"loadeddata",(function(){return this.removeAttribute("poster")})))}const h=Ve.el(r?"img":"video");return s&&(h.preload="auto"),c&&r&&Ve.on(h,"load",(function(){for(o of e.clones)o.file.thumb.src=d;return l.src=d})),h.src=d},prefetchAll(e){for(var t of e.files)ot.prefetch(e,t)},toggle(){ot.prefetchEnabled=!ot.prefetchEnabled,this.classList.toggle("disabled",!ot.prefetchEnabled),ot.prefetchEnabled&&n.posts.forEach(ot.prefetchAll)},playVideos(){const e=Ve.id("qp")?.firstElementChild;return n.posts.forEach((function(t){
|
||||
for(t of[t,...t.clones])for(var n of t.files)if(n.videoThumb){var{thumb:o}=n;Ke.isNodeVisible(o)||t.nodes.root===e?o.play():o.pause()}}))}},at={init(){if(t["WEBM Metadata"]&&["index","thread"].includes(n.VIEW))return l.Post.push({name:"WEBM Metadata",cb:this.node})},node(){for(let n=0;n<this.files.length;n++){var e,t=this.files[n];if(/webm$/i.test(t.url))this.isClone?e=Ve(".webm-title",t.text):((e=Ve.el("span",{className:"webm-title"})).dataset.index=n,Ve.extend(e,{innerHTML:'<a href="javascript:;"></a>'}),Ve.add(t.text,[Ve.tn(" "),e])),1===e.children.length&&Ve.one(e.lastElementChild,"mouseover focus",at.load)}},load(){Ve.rmClass(this.parentNode,"error"),Ve.addClass(this.parentNode,"loading");const{index:e}=this.parentNode.dataset;return Ue.binary(ze.postFromNode(this).files[+e].url,(e=>{if(Ve.rmClass(this.parentNode,"loading"),null!=e){const t=at.parse(e),n=Ve.el("span",{textContent:t||""});return null==t&&Ve.addClass(this.parentNode,"not-found"),Ve.before(this,n),
|
||||
this.parentNode.tabIndex=0,a.activeElement===this&&this.parentNode.focus(),this.tabIndex=-1}return Ve.addClass(this.parentNode,"error"),Ve.one(this,"click",at.load)}),{Range:"bytes=0-9999"})},parse(e){const t=function(){let t=e[n++],o=0;for(;t<128>>o;)o++;for(t^=128>>o;o--&&n<e.length;)t=t<<8^e[n++];return t};for(var n=0;n<e.length;){var o=t(),a=t();if(15273===o){for(var i="";a--&&n<e.length;)i+=String.fromCharCode(e[n++]);return decodeURIComponent(escape(i))}[139690087,88713574].includes(o)||(n+=a)}return null}};const it={init(){if(["index","thread","archive"].includes(n.VIEW)&&t["Reveal Spoiler Thumbnails"])return l.Post.push({name:"Reveal Spoiler Thumbnails",cb:this.node})},node(){if(!this.isClone)for(var e of this.files)if(e.thumb&&e.isSpoiler){var{thumb:t}=e;t.removeAttribute("style"),t.style.maxHeight=t.style.maxWidth=this.isReply?"125px":"250px",t.src?t.src=e.thumbURL:t.dataset.src=e.thumbURL}}};var rt={init(){
|
||||
if(["index","thread","archive"].includes(n.VIEW)&&t.Linkify)return t["Comment Expansion"]&&X.callbacks.push(this.node),l.Post.push({name:"Linkify",cb:this.node}),Le.init()},node(){let e;if(this.isClone)return Le.events(this);if(!rt.regString.test(this.info.comment))return;for(e of u("a",this.nodes.comment))n.SITE.isLinkified?.(e)&&(Ve.addClass(e,"linkify"),O.useFaster&&O.fixLinks([e]),Le.process(e,this));const t=rt.process(this.nodes.comment);for(e of(O.useFaster&&O.fixLinks(t),t))Le.process(e,this)},process(e){let t;const n=/[^\s"]+/g,o=/[\s"]/,a=Ve.X(".//br|.//text()",e);let i=0;const r=[];for(;e=a.snapshotItem(i++);){var s,{data:l}=e;if(l&&"A"!==e.parentElement.nodeName)for(;s=n.exec(l);){var d,{index:c}=s,h=e,u=s[0];if((t=c+u.length)===l.length)for(n.lastIndex=0;d=a.snapshotItem(i++);){var p;if("BR"===d.nodeName||"P"===d.parentElement.nodeName&&!d.previousSibling){var g,f
|
||||
;if((g=u.match(/(https?:\/\/)?([a-z\d-]+\.)*[a-z\d-]+$/i))&&(f=a.snapshotItem(i)?.data?.match(/^(\.[a-z\d-]+)*\//i))&&0===(g[0]+f[0]).search(rt.regString))continue;break}if("A"===d.parentElement.nodeName&&!rt.regString.test(u))break;if(h=d,({data:l}=d),p=o.exec(l)){u+=l.slice(0,p.index),n.lastIndex=t=p.index,i--;break}({length:t}=l),u+=l}if(rt.regString.test(u)&&r.push(rt.makeRange(e,h,c,t)),!n.lastIndex||e!==h)break}}for(i=r.length;i--;)r[i]=rt.makeLink(r[i]);return r},regString:new RegExp('((https?|mailto|git|magnet|ftp|irc):([a-z\\d%/?])|([-a-z\\d]+[.])+(aero|asia|biz|cat|com|coop|dance|info|int|jobs|mobi|moe|museum|name|net|org|post|pro|tel|travel|xxx|xyz|edu|gov|mil|[a-z]{2})([:/]|(?![^\\s"]))|[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}|[-\\w\\d.@]+@[a-z\\d.-]+\\.[a-z\\d])',"i"),makeRange(e,t,n,o){const a=document.createRange();return a.setStart(e,n),a.setEnd(t,o),a},makeLink(e){let t,n,o=e.toString(),a=o.search(rt.regString);if(a>0){
|
||||
for(o=o.slice(a);e.startOffset+a>=e.startContainer.data.length;)a--;a&&e.setStart(e.startContainer,e.startOffset+a)}for(a=0;/[)\]}>.,]/.test(t=o.charAt(o.length-(1+a)))&&(/[.,]/.test(t)||o.match(/[()\[\]{}<>]/g).length%2);)a++;if(a){for(o=o.slice(0,-a);e.endOffset-a<0;)a--;a&&e.setEnd(e.endContainer,e.endOffset-a)}/((mailto|magnet):|.+:\/\/)/.test(o)||(o=(/@/.test(o)?"mailto:":"http://")+o),(n=o.match(/^(https?:\/\/[^/]*%[0-9a-f]{2})(.*)$/i))&&(o=n[1].replace(/%([0-9a-f]{2})/gi,(function(e,t){return"25"===t?e:String.fromCharCode(parseInt(t,16))}))+n[2]);const i=Ve.el("a",{className:"linkify",rel:"noreferrer noopener",target:"_blank",href:o});return Ve.add(i,e.extractContents()),e.insertNode(i),i}};const st={init(){if("yotsuba"!==n.SITE.software||!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Archive Link"])return;const e={el:Ve.el("div",{textContent:"Archive"}),order:60,open:({ID:e,thread:t,board:n})=>!!Ze.to("thread",{postID:e,threadID:t.ID,boardID:n.ID}),subEntries:[]}
|
||||
;for(var o of[["Post","post"],["Name","name"],["Tripcode","tripcode"],["Capcode","capcode"],["Subject","subject"],["Flag","country"],["Filename","filename"],["Image MD5","MD5"]])e.subEntries.push(this.createSubEntry(o[0],o[1]));return Q.menu.addEntry(e)},createSubEntry(e,t){const n=Ve.el("a",{textContent:e,target:"_blank"}),o="post"===t?function({ID:e,thread:t,board:o}){return n.href=Ze.to("thread",{postID:e,threadID:t.ID,boardID:o.ID}),!0}:function(e){const o="country"===t&&e.info.flagCodeTroll?"troll_country":t,a="country"===t?e.info.flagCode||e.info.flagCodeTroll?.toLowerCase():We.values(t,e)[0];return!!a&&(n.href=Ze.to("search",{boardID:e.board.ID,type:o,value:a,isSearch:!0}),!0)};return{el:n,open:o}}};var lt={init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Copy Text Link"])return;const e=Ve.el("a",{className:"copy-text-link",href:"javascript:;",textContent:"Copy Text"});return Ve.on(e,"click",lt.copy),Q.menu.addEntry({el:e,order:12,
|
||||
open:e=>(lt.text=(e.origin||e).commentOrig(),!0)})},copy(){const e=Ve.el("textarea",{className:"copy-text-element",value:lt.text});Ve.add(a.body,e),e.select();try{a.execCommand("copy")}catch(e){}return Ve.rm(e)}},dt={auto:[m(),m()],init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Delete Link"])return;const e=Ve.el("div",{className:"delete-link",textContent:"Delete"}),o=Ve.el("a",{className:"delete-post",href:"javascript:;"}),a=Ve.el("a",{className:"delete-file",href:"javascript:;"});this.nodes={menu:e.firstChild,links:[o,a]};const i={el:o,open:()=>(o.textContent=dt.linkText(!1),Ve.on(o,"click",dt.toggle),!0)},r={el:a,open:({file:e})=>!(!e||e.isDead)&&(a.textContent=dt.linkText(!0),Ve.on(a,"click",dt.toggle),!0)};return Q.menu.addEntry({el:e,order:40,open:e=>!e.isDead&&(dt.post=e,dt.nodes.menu.textContent=dt.menuText(),dt.cooldown.start(e),!0),subEntries:[i,r]})},menuText(){let e;return(e=dt.cooldown.seconds[dt.post.fullID])?`Delete (${e})`:"Delete"},linkText(e){
|
||||
let t=e?"File":"Post";return dt.auto[+e][dt.post.fullID]&&(t=`Deleting ${t.toLowerCase()}...`),t},toggle(){const{post:e}=dt,t=Ve.hasClass(this,"delete-file"),n=dt.auto[+t];if(n[e.fullID]?delete n[e.fullID]:n[e.fullID]=!0,this.textContent=dt.linkText(t),!dt.cooldown.seconds[e.fullID])return dt.delete(e,t)},delete(e,t){const o=dt.nodes.links[+t];delete dt.auto[+t][e.fullID],e.fullID===dt.post.fullID&&Ve.off(o,"click",dt.toggle);const a={mode:"usrdel",onlyimgdel:t,pwd:$e.persona.getPassword()};return a[+e.ID]="delete",Ve.ajax(Ve.id("delform").action.replace(`/${n.BOARD}/`,`/${e.board}/`),{responseType:"document",withCredentials:!0,onloadend(){return dt.load(o,e,t,this.response)},form:Ve.formData(a)})},load(e,n,o,a){let i;if(!a)return new Xe("warning","Connection error, please retry.",20),void(n.fullID===dt.post.fullID&&Ve.on(e,"click",dt.toggle));if(e.textContent=dt.linkText(o),"4chan - Banned"===a.title){const e=Ve.el("span",{
|
||||
innerHTML:'You can't delete posts because you are <a href="//www.4chan.org/banned" target="_blank">banned</a>.'});return new Xe("warning",e,20)}if(i=a.getElementById("errmsg")){if(new Xe("warning",i.textContent,20),n.fullID===dt.post.fullID&&Ve.on(e,"click",dt.toggle),$e.cooldown.data&&t.Cooldown&&/\bwait\b/i.test(i.textContent))return dt.cooldown.start(n,5),dt.auto[+o][n.fullID]=!0,dt.nodes.links[+o].textContent=dt.linkText(o)}else if(o||$e.cooldown.delete(n),"Updating index..."===a.title&&(n.origin||n).kill(o),n.fullID===dt.post.fullID)return e.textContent="Deleted"},cooldown:{seconds:m(),start(e,t){if(null==dt.cooldown.seconds[e.fullID])return null==t&&(t=$e.cooldown.secondsDeletion(e)),t>0?(dt.cooldown.seconds[e.fullID]=t,dt.cooldown.count(e)):void 0},count(e){if(e.fullID===dt.post.fullID&&(dt.nodes.menu.textContent=dt.menuText()),dt.cooldown.seconds[e.fullID]>0&&t.Cooldown)dt.cooldown.seconds[e.fullID]--,
|
||||
setTimeout(dt.cooldown.count,1e3,e);else for(var n of(delete dt.cooldown.seconds[e.fullID],[!1,!0]))dt.auto[+n][e.fullID]&&dt.delete(e,n)}}};const ct={init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Download Link"])return;const e=Ve.el("a",{className:"download-link",textContent:"Download file"});return Ve.on(e,"click",j.download),Q.menu.addEntry({el:e,order:100,open:({file:t})=>!!t&&(e.href=t.url,e.download=t.name,!0)})}};var ht={init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Report Link"])return;const e=Ve.el("a",{className:"report-link",href:"javascript:;",textContent:"Report"});return Ve.on(e,"click",ht.report),Q.menu.addEntry({el:e,order:10,open:e=>(ht.url=`//sys.${location.hostname.split(".")[1]}.org/${e.board}/imgboard.php?mode=report&no=${e}`,a.cookie.indexOf("pass_enabled=1")>=0?ht.dims="width=350,height=275":ht.dims="width=400,height=550",!0)})},report(){
|
||||
const{url:e,dims:t}=ht,n=Date.now(),o=`toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,${t}`;return window.open(e,n,o)}},ut={init(){if(t["Disable Autoplaying Sounds"]){for(var e of(Ve.addClass(i,"anti-autoplay"),u("audio[autoplay]",i)))this.stop(e);return window.addEventListener("loadstart",(e=>this.stop(e.target)),!0),l.Post.push({name:"Disable Autoplaying Sounds",cb:this.node}),Ve.ready((()=>this.process(d.body)))}},stop(e){if(e.autoplay&&(e.pause(),e.autoplay=!1,!e.controls))return e.controls=!0,Ve.addClass(e,"controls-added")},node(){return ut.process(this.nodes.comment)},process(e){for(var t of u('iframe[src*="youtube"][src*="autoplay=1"]',e))ut.processVideo(t,"src");for(var n of u('object[data*="youtube"][data*="autoplay=1"]',e))ut.processVideo(n,"data")},processVideo:(e,t)=>(e[t]=e[t].replace(/\?autoplay=1&?/,"?").replace("&autoplay=1",""),"none"===window.getComputedStyle(e).display&&(e.style.display="block"),Ve.addClass(e,"autoplay-removed"))},pt={init(){
|
||||
if(t["Custom Board Titles"]&&(this.db=new y("customTitles",null,!0)),Ve.asap((()=>a.body),(()=>Ve.asap((()=>Ve("hr")),pt.ready))),"f"!==n.BOARD.ID)return Ot.ready((()=>Ve.queueTask(pt.load)))},ready(){const e=Ve(".boardBanner"),{children:o}=e;if("thread"===n.VIEW&&t["Remove Thread Excerpt"]&&pt.setTitle(o[1].textContent),o[0].title="Click to change",Ve.on(o[0],"click",pt.cb.toggle),t["Custom Board Titles"]&&(pt.custom(o[1]),o[2]))return pt.custom(o[2])},load(){const e=Ve.id("bannerCnt");if(!e.firstChild){const t=Ve.el("img",{alt:"4chan",src:"//s.4cdn.org/image/title/"+e.dataset.src});return Ve.add(e,t)}},setTitle:e=>null!=ee.title?(ee.title=e,ee.update()):a.title=e,cb:{toggle(){pt.choices?.length||(pt.choices=t.knownBanners.split(",").slice());const e=Math.floor(pt.choices.length*Math.random()),n=pt.choices.splice(e,1);return Ve("img",this.parentNode).src=`//s.4cdn.org/image/title/${n}`},click(e){if(e.ctrlKey||e.metaKey){
|
||||
for(var t of(null==pt.original[this.className]&&(pt.original[this.className]=this.cloneNode(!0)),this.contentEditable=!0,u("br",this)))Ve.replace(t,Ve.tn("\n"));return this.focus()}},keydown(e){if(e.stopPropagation(),!e.shiftKey&&13===e.keyCode)return this.blur()},blur(){for(var e of u("br",this))Ve.replace(e,Ve.tn("\n"));return(this.textContent=this.textContent.replace(/\n*$/,""))?(this.contentEditable=!1,pt.db.set({boardID:n.BOARD.ID,threadID:this.className,val:{title:this.textContent,orig:pt.original[this.className].textContent}})):(Ve.rmAll(this),Ve.add(this,[...pt.original[this.className].cloneNode(!0).childNodes]),pt.db.delete({boardID:n.BOARD.ID,threadID:this.className}))}},original:m(),custom(e){let o;const{className:a}=e;for(var i of(e.title=`Ctrl/⌘+click to edit board ${a.slice(5).toLowerCase()}`,e.spellcheck=!1,["click","keydown","blur"]))Ve.on(e,i,pt.cb[i]);if(o=pt.db.get({boardID:n.BOARD.ID,threadID:a
|
||||
}))return t["Persistent Custom Board Titles"]||o.orig===e.textContent?(pt.original[a]=e.cloneNode(!0),e.textContent=o.title):pt.db.delete({boardID:n.BOARD.ID,threadID:a})}},gt={init(){if("f"===n.BOARD.ID&&t["Enable Native Flash Embedding"])return Ve.ready(gt.initReady)},initReady:()=>Ve.hasStorage?Ve.global((function(){if(JSON.parse(localStorage["4chan-settings"]||"{}").disableAll)return window.SWFEmbed.init()})):("thread"===n.VIEW&&Ve.global((()=>window.Main.tid=location.pathname.split(/\/+/)[3])),Ve.global((()=>window.SWFEmbed.init())))},ft={init(){if("yotsuba"===n.SITE.software&&["index","thread","archive"].includes(n.VIEW))return Y.ready(this.initBoard),Ot.ready(this.initReady)},initBoard(){if(n.BOARD.config.code_tags&&(Ve.on(window,"prettyprint:cb",(function(e){let t,o;if((t=n.posts.get(e.detail.ID))&&(o=u(".prettyprint",t.nodes.comment)[+e.detail.i]))return Ve.hasClass(o,"prettyprinted")?void 0:(o.innerHTML=e.detail.html,Ve.addClass(o,"prettyprinted"))})),
|
||||
Ve.global((()=>window.addEventListener("prettyprint",(e=>window.dispatchEvent(new CustomEvent("prettyprint:cb",{detail:{ID:e.detail.ID,i:e.detail.i,html:window.prettyPrintOne(e.detail.html)}}))),!1))),l.Post.push({name:"Parse [code] tags",cb:ft.code}),n.posts.forEach((function(e){if(e.callbacksExecuted)return l.Post.execute(e,["Parse [code] tags"],!0)})),X.callbacks.push(ft.code)),n.BOARD.config.math_tags)return Ve.global((()=>window.addEventListener("mathjax",(function(e){return window.MathJax?window.MathJax.Hub.Queue(["Typeset",window.MathJax.Hub,e.target]):(document.querySelector('script[src^="//cdn.mathjax.org/"]')||(window.loadMathJax(),window.loadMathJax=function(){}),e.target.classList.contains("postMessage")?void 0:document.querySelector('script[src^="//cdn.mathjax.org/"]').addEventListener("load",(()=>window.MathJax.Hub.Queue(["Typeset",window.MathJax.Hub,e.target])),!1))}),!1))),l.Post.push({name:"Parse [math] tags",cb:ft.math}),n.posts.forEach((function(e){
|
||||
if(e.callbacksExecuted)return l.Post.execute(e,["Parse [math] tags"],!0)})),X.callbacks.push(ft.math)},initReady:()=>Ve.global((function(){for(var e of(window.clickable_ids=!1,document.querySelectorAll(".posteruid, .capcode")))e.removeEventListener("click",window.idClick,!1)})),code(){if(!this.isClone)return Ve.ready((()=>{const e=u(".prettyprint",this.nodes.comment);for(let n=0;n<e.length;n++){var t=e[n];Ve.hasClass(t,"prettyprinted")||Ve.event("prettyprint",{ID:this.fullID,i:n,html:t.innerHTML},window)}}))},math(){let e;if(/\[(math|eqn)\]/.test(this.nodes.comment.textContent)){if((e=u("wbr",this.nodes.comment)).length){for(var t of e)Ve.rm(t);this.nodes.comment.normalize()}var n=()=>{if(i.contains(this.nodes.comment))return Ve.off(a,"PostsInserted",n),Ve.event("mathjax",null,this.nodes.comment)};return Ve.on(a,"PostsInserted",n),n()}}},mt={init(){if(["index","thread"].includes(n.VIEW)&&t["Color User IDs"])return this.ids=m(),this.ids.Heaven=[0,0,0,"#fff"],l.Post.push({
|
||||
name:"Color User IDs",cb:this.node})},node(){let e,t;if(this.isClone||!(t=this.info.uniqueID)||!(e=this.nodes.uniqueID))return;const n=mt.ids[t]||mt.compute(t),{style:o}=e;return o.color=n[3],o.backgroundColor=`rgb(${n[0]},${n[1]},${n[2]})`,Ve.addClass(e,"painted")},compute(e){const t=n.SITE.uidColor?n.SITE.uidColor(e):parseInt(e,16),o=[t>>16&255,t>>8&255,255&t];return o.push(Ve.luma(o)>125?"#000":"#fff"),this.ids[e]=o}},bt={init(){if(["index","thread"].includes(n.VIEW))return l.Post.push({name:"Highlight by User ID",cb:this.node})},uniqueID:null,node(){if(this.nodes.uniqueIDRoot&&Ve.on(this.nodes.uniqueIDRoot,"click",bt.click(this)),this.nodes.capcode&&Ve.on(this.nodes.capcode,"click",bt.click(this)),!this.isClone)return bt.set(this)},set(e){const t=(e.info.uniqueID||e.info.capcode)===bt.uniqueID;return Ve[t?"addClass":"rmClass"](e.nodes.post,"highlight")},click:e=>function(){const t=e.info.uniqueID||e.info.capcode;return bt.uniqueID=bt.uniqueID===t?null:t,n.posts.forEach(bt.set)}
|
||||
},At={init(){if("thread"===n.VIEW&&t["Count Posts by ID"])return l.Thread.push({name:"Count Posts by ID",cb(){return At.thread=this}}),l.Post.push({name:"Count Posts by ID",cb:this.node})},node(){if(this.nodes.uniqueID&&this.thread===At.thread)return Ve.on(this.nodes.uniqueID,"mouseover",At.count)},count(){const{uniqueID:e}=ze.postFromNode(this).info;let t=0;return At.thread.posts.forEach((function(n){if(n.info.uniqueID===e)return t++})),this.title=`${t} post${1===t?"":"s"} by this ID`}},vt={init(){if("yotsuba"===n.SITE.software&&["index","thread"].includes(n.VIEW))return l.Post.push({name:"Mod Contact Links",cb:this.node})},node(){let e;if(this.isClone||!Ve.hasOwn(vt.specific,this.info.capcode))return;const t=Ve.el("span",{className:"contact-links brackets-wrap"});if(Ve.extend(t,vt.template(this.info.capcode)),Ve.after(this.nodes.capcode,t),(e=this.info.comment.match(/This thread was moved to >>>\/(\w+)\//))&&Ve.hasOwn(vt.moveNote,e[1])){const t=Ve.el("div",{className:"move-note"})
|
||||
;return Ve.extend(t,vt.moveNote[e[1]]),Ve.add(this.nodes.post,t)}},template:e=>({innerHTML:'<a href="https://www.4chan.org/feedback" target="_blank">feedback</a>'+vt.specific[e]().innerHTML}),specific:{Mod:()=>({innerHTML:' <a href="https://www.4chan-x.net/4chan-irc.html" target="_blank">IRC</a>'}),Manager:()=>vt.specific.Mod(),Developer:()=>({innerHTML:' <a href="https://github.com/4chan" target="_blank">github</a>'}),Admin:()=>({innerHTML:' <a href="https://twitter.com/hiroyuki_ni" target="_blank">twitter</a>'})},moveNote:{qa:{innerHTML:'Moving a thread to /qa/ does not imply mods will read it. If you wish to contact mods, use <a href="https://www.4chan.org/feedback" target="_blank">feedback</a><span class="invisible"> (https://www.4chan.org/feedback)</span> or <a href="https://www.4chan-x.net/4chan-irc.html" target="_blank">IRC</a><span class="invisible"> (https://www.4chan-x.net/4chan-irc.html)</span>.'}}};const wt={init(){if(!t["Normalize URL"])return
|
||||
;let e=location.pathname.split(/\/+/);if("yotsuba"===n.SITE.software)switch(n.VIEW){case"thread":e[2]="thread",e=e.slice(0,4);break;case"index":e=e.slice(0,3)}return e=e.join("/"),location.pathname!==e?history.replaceState(history.state,"",`${location.protocol}//${location.host}${e}${location.hash}`):void 0}};var xt={init(){if(t["Unique ID and Capcode Navigation"]&&["index","thread"].includes(n.VIEW))return this.buttons=this.makeButtons(),l.Post.push({name:"Post Jumper",cb:this.node})},node(){if(this.isClone)for(var e of u(".postJumper",this.nodes.info))xt.addListeners(e);else if(this.nodes.uniqueIDRoot&&xt.addButtons(this,"uniqueID"),this.nodes.capcode)return xt.addButtons(this,"capcode")},addButtons(e,t){const n=e.info[t],o=xt.buttons.cloneNode(!0);return Ve.extend(o.dataset,{type:t,value:n}),Ve.after(e.nodes[t+("capcode"===t?"":"Root")],o),xt.addListeners(o)},addListeners:e=>(Ve.on(e.firstChild,"click",xt.buttonClick),Ve.on(e.lastChild,"click",xt.buttonClick)),buttonClick(){let e
|
||||
;const t=Ve.hasClass(this,"prev")?-1:1;if(e=xt.find(this.parentNode,t))return xt.scroll(this.parentNode,e)},find(e,t){const{type:n,value:o}=e.dataset,a=`span[contains(@class,"postJumper") and @data-value="${o}" and @data-type="${n}"]`,i=t<0?"preceding":"following";let r=e;for(;r=Ve.x(`${i}::${a}`,r);)if(r.getBoundingClientRect().height)return r;if((r=Ve.x(`(//${a})[${t<0?"last()":"1"}]`))&&r.getBoundingClientRect().height)return r;for(;(r=Ve.x(`${i}::${a}`,r))&&r!==e;)if(r.getBoundingClientRect().height)return r;return null},makeButtons(){const e=Ve.el("span",{className:"postJumper"});return Ve.extend(e,{innerHTML:'<a href="javascript:;" class="'+o("prev")+'">'+o("⏫")+'</a><a href="javascript:;" class="'+o("next")+'">'+o("⏬")+"</a>"}),e},scroll(e,t){const n=e.getBoundingClientRect().top,o=t.getBoundingClientRect().top;return window.scrollBy(0,o-n)}};const yt={init(){let e;if("yotsuba"===n.SITE.software&&"qa"===n.BOARD.ID){const t={
|
||||
innerHTML:'Stay in touch with your <a href="https://www.4chan-x.net/qa_friends.html" target="_blank" rel="noopener">/qa/ friends</a>!'};e=Ve.el("div",{className:"fcx-announcement"},t),Ve.onExists(i,".boardBanner",(t=>Ve.after(t,e)))}if("samachan.org"in t.siteProperties&&!t.PSAseen.includes("samachan"))return e=Ve.el("span",{innerHTML:'<a href="https://sushigirl.us/yakuza/res/776.html" target="_blank" rel="noopener">Looking for a new home?<br>Some former Samachan users are regrouping on SushiChan.</a><br>(a message from 4chan X)'}),Ot.ready((function(){return new Xe("info",e),t.PSAseen.push("samachan"),Ve.set("PSAseen",t.PSAseen)}))}};var kt={init(){if(t["Announcement Hiding"]&&n.SITE.selectors.psa)return Ve.addClass(i,"hide-announcement"),Ve.onExists(i,n.SITE.selectors.psa,this.setup),Ve.ready((function(){if(!Ve(n.SITE.selectors.psa))return Ve.rmClass(i,"hide-announcement")}))},setup(e){let o,a;kt.psa=e,kt.text=e.dataset.utc??e.innerHTML,
|
||||
n.SITE.selectors.psaTop&&(a=Ve(n.SITE.selectors.psaTop)?.previousElementSibling)&&"HR"===a.nodeName&&(kt.hr=a),kt.content=Ve.el("div");const r={el:Ve.el("a",{textContent:"Show announcement",className:"show-announcement",href:"javascript:;"}),order:50,open:()=>e.hidden};return Ke.menu.addEntry(r),Ve.on(r.el,"click",kt.toggle),kt.btn=o=Ve.el("a",{title:"Mark announcement as read and hide.",className:"hide-announcement-button",href:"javascript:;",textContent:"➖︎"}),Ve.on(o,"click",kt.toggle),"HR"===e.firstChild?.tagName?Ve.after(e.firstChild,o):Ve.prepend(e,o),kt.sync(t.hiddenPSAList),Ve.rmClass(i,"hide-announcement"),Ve.sync("hiddenPSAList",kt.sync)},toggle(){const e=Ve.hasClass(this,"hide-announcement-button"),o=function(t){return e?t[n.SITE.ID]=kt.text:delete t[n.SITE.ID]};return o(t.hiddenPSAList),kt.sync(t.hiddenPSAList),Ve.get("hiddenPSAList",t.hiddenPSAList,(function({hiddenPSAList:e}){return o(e),Ve.set("hiddenPSAList",e)}))},sync(e){const{psa:t,content:o}=kt
|
||||
;t.hidden=e[n.SITE.ID]===kt.text,t.hidden?Ve.add(o,[...t.childNodes]):Ve.add(t,[...o.childNodes]),kt.hr&&(kt.hr.hidden=t.hidden)}},It={init(){if(t["Reveal Spoilers"]&&Ve.addClass(i,"reveal-spoilers"),t["Remove Spoilers"])return l.Post.push({name:"Reveal Spoilers",cb:this.node}),"archive"===n.VIEW?Ve.ready((()=>It.unspoiler(Ve.id("arc-list")))):void 0},node(){return It.unspoiler(this.nodes.comment)},unspoiler(e){const t=u(n.SITE.selectors.spoiler,e);for(var o of t){var a=Ve.el("span",{className:"removed-spoiler"});Ve.replace(o,a),Ve.add(a,[...o.childNodes])}}},Ct={init(){if("index"===n.VIEW&&t["Open Threads in New Tab"])return l.Post.push({name:"Thread Links",cb:this.node}),l.CatalogThread.push({name:"Thread Links",cb:this.catalogNode})},node(){if(!this.isReply&&!this.isClone)return Ct.process(this.nodes.reply)},catalogNode(){return Ct.process(this.nodes.thumb.parentNode)},process:e=>e.target="_blank"};const Dt={init(){
|
||||
if("tinyboard"===n.SITE.software)return"thread"===n.VIEW?Ot.ready((()=>Ve.global((function(){let e,{boardID:t,threadID:n}=document.currentScript.dataset;n=+n;const o=document.querySelector('form[name="post"]');window.$(document).ajaxComplete((function(e,i,r){let s;if(r.url!==o.action)return;if(!(s=+i.responseJSON?.id))return;const l={boardID:t,threadID:n,postID:s};try{const{redirect:e,noko:t}=i.responseJSON;!e||null==a||a||t||(l.redirect=e)}catch(e){}return e=new CustomEvent("QRPostSuccessful",{bubbles:!0,detail:l}),document.dispatchEvent(e)}));var a=window.tb_settings?.ajax?.always_noko_replies;return((e=window.tb_settings||(window.tb_settings={})).ajax||(e.ajax={})).always_noko_replies=!0}),{boardID:n.BOARD.ID,threadID:n.THREADID}))):void 0}};var Et={init(){if("yotsuba"===n.SITE.software&&"thread"===n.VIEW&&t["Mark New IPs"])return l.Thread.push({name:"Mark New IPs",cb:this.node})},node(){return Et.ipCount=this.ipCount,Et.postCount=this.posts.keys.length,
|
||||
Ve.on(a,"ThreadUpdate",Et.onUpdate)},onUpdate(e){let t;const{ipCount:o,postCount:a,newPosts:i,deletedPosts:r}=e.detail;if(null!=o){switch(o-Et.ipCount){case a-Et.postCount+r.length:var s=Et.ipCount;for(t of i)Et.markNew(n.posts.get(t),++s);break;case-r.length:for(t of i)Et.markOld(n.posts.get(t))}return Et.ipCount=o,Et.postCount=a}},markNew(e,t){const n=Math.floor(t/10)%10==1?"th":["st","nd","rd"][t%10-1]||"th",o=Ve.el("span",{className:"ip-counter",textContent:`(${t})`});return e.nodes.nameBlock.title=`This is the ${t}${n} IP in the thread.`,Ve.add(e.nodes.nameBlock,[Ve.tn(" "),o]),Ve.addClass(e.nodes.root,"new-ip")},markOld:e=>(e.nodes.nameBlock.title="Not the first post from this IP.",Ve.addClass(e.nodes.root,"old-ip"))},St={postCount:0,fileCount:0,postIndex:0,init(){let e;if("thread"!==n.VIEW||!t["Thread Stats"])return;t["Page Count in Stats"]&&(this[n.SITE.isPrunedByAge?.(n.BOARD)?"showPurgePos":"showPage"]=!0);const r={
|
||||
innerHTML:'<span id="post-count">?</span> / <span id="file-count">?</span>'+(t["IP Count in Stats"]&&n.SITE.hasIPCount?' / <span id="ip-count">?</span>':"")+(t["Page Count in Stats"]?' / <span id="page-count">?</span>':"")};let s="Posts / Files";return t["IP Count in Stats"]&&n.SITE.hasIPCount&&(s+=" / IPs"),t["Page Count in Stats"]&&(s+=this.showPurgePos?" / Purge Position":" / Page"),t["Updater and Stats in Header"]?(this.dialog=e=Ve.el("span",{id:"thread-stats",title:s}),Ve.extend(e,r),Ke.addShortcut("stats",e,200)):(this.dialog=e=L.dialog("thread-stats",{innerHTML:'<div class="move" title="'+o(s)+'">'+r.innerHTML+"</div>"}),Ve.addClass(i,"float"),Ve.ready((()=>Ve.add(a.body,e)))),this.postCountEl=Ve("#post-count",e),this.fileCountEl=Ve("#file-count",e),this.ipCountEl=Ve("#ip-count",e),this.pageCountEl=Ve("#page-count",e),this.pageCountEl&&Ve.on(this.pageCountEl,"click",St.fetchPage),l.Thread.push({name:"Thread Stats",cb:this.node})},node(){return St.thread=this,St.count(),
|
||||
St.update(),St.fetchPage(),Ve.on(a,"PostsInserted",(()=>Ve.queueTask(St.onPostsInserted))),Ve.on(a,"ThreadUpdate",St.onUpdate)},count(){const{posts:e}=St.thread,t=e.keys.length;for(let o=St.postIndex,a=t;o<a;o++){var n=e.get(e.keys[o]);n.isFetchedQuote||(St.postCount++,St.fileCount+=n.files.length)}return St.postIndex=t},onUpdate(e){if(e.detail[404])return;const{postCount:t,fileCount:n}=e.detail;return Ve.extend(St,{postCount:t,fileCount:n}),St.postIndex=St.thread.posts.keys.length,St.update(),St.showPage&&"1"!==St.pageCountEl.textContent?St.fetchPage():void 0},onPostsInserted(){if(!(St.thread.posts.keys.length<=St.postIndex))return St.count(),St.update(),St.showPage&&"1"!==St.pageCountEl.textContent?St.fetchPage():void 0},update(){const{thread:e,postCountEl:t,fileCountEl:n,ipCountEl:o}=St;return t.textContent=St.postCount,n.textContent=St.fileCount,o.textContent=e.ipCount??"?",t.classList.toggle("warning",e.postLimit&&!e.isSticky),n.classList.toggle("warning",e.fileLimit&&!e.isSticky)
|
||||
},fetchPage(){if(St.pageCountEl)return clearTimeout(St.timeout),St.thread.isDead?(St.pageCountEl.textContent="Dead",void Ve.addClass(St.pageCountEl,"warning")):(St.timeout=setTimeout(St.fetchPage,12e4),Ve.whenModified(n.SITE.urls.threadsListJSON(St.thread),"ThreadStats",St.onThreadsLoad))},onThreadsLoad(){if(200===this.status){let e,t;if(St.showPurgePos){let n=1;for(e of this.response)for(t of e.threads)t.no<St.thread.ID&&n++;return St.pageCountEl.textContent=n,St.pageCountEl.classList.toggle("warning",1===n)}{let n,o=n=0;for(e of this.response)n+=e.threads.length;for(let a=0;a<this.response.length;a++)for(t of(e=this.response[a],e.threads)){if(t.no===St.thread.ID)return St.pageCountEl.textContent=a+1,St.pageCountEl.classList.toggle("warning",o>=n-this.response[0].threads.length),St.lastPageUpdate=new Date(t.last_modified*b),void St.retry();o++}}}else if(304===this.status)return St.retry()},retry(){
|
||||
if(!(!St.showPage||"1"===St.pageCountEl.textContent||n.SITE.threadModTimeIgnoresSage||St.thread.posts.get(St.thread.lastPost).info.date<=St.lastPageUpdate))return clearTimeout(St.timeout),St.timeout=setTimeout(St.fetchPage,5e3)}};const Tt={init(){if("yotsuba"===n.SITE.software&&t["Pass Link"])return Ot.ready(this.ready)},ready(){let e;if(!(e=Ve.id("styleSelector")))return;const t=Ve.el("span",{className:"brackets-wrap pass-link-container"});return Ve.extend(t,{innerHTML:'<a href="javascript:;">4chan Pass</a>'}),Ve.on(t.firstElementChild,"click",(()=>window.open(`//sys.${location.hostname.split(".")[1]}.org/auth`,Date.now(),"width=500,height=280,toolbar=0"))),Ve.before(e.previousSibling,[t,Ve.tn(" ")])}};var Rt={init(){if(["index","thread"].includes(n.VIEW)&&t["Quote Inlining"])return t["Comment Expansion"]&&X.callbacks.push(this.node),l.Post.push({name:"Quote Inlining",cb:this.node})},node(){const{process:e}=Rt,{isClone:t}=this
|
||||
;for(var n of this.nodes.quotelinks.concat([...this.nodes.backlinks],this.nodes.archivelinks))e(n,t)},process:(e,n)=>(t["Quote Hash Navigation"]&&(n||Ve.after(e,Rt.qiQuote(e,Ve.hasClass(e,"filtered")))),Ve.on(e,"click",Rt.toggle)),qiQuote(e,t){let n="hashlink";return t&&(n+=" filtered"),Ve.el("a",{className:n,textContent:"#",href:e.href})},toggle(e){if(Ve.modifiedClick(e))return;const{boardID:o,threadID:a,postID:r}=ze.postDataFromLink(this);if(t["Inline Cross-thread Quotes Only"]&&"thread"===n.VIEW&&n.posts.get(`${o}.${r}`)?.nodes.root.offsetParent)return;if(Ve.hasClass(i,"catalog-mode"))return;e.preventDefault();const s=ze.postFromNode(this),{context:l}=s;if(Ve.hasClass(this,"inlined"))Rt.rm(this,o,a,r,l);else{if(Ve.x(`ancestor::div[@data-full-i-d='${o}.${r}']`,this))return;Rt.add(this,o,a,r,l,s)}return this.classList.toggle("inlined")},findRoot:(e,t)=>t?Ve.x('ancestor::*[parent::*[contains(@class,"post")]][1]',e):Ve.x("ancestor-or-self::*[parent::blockquote][1]",e),add(e,o,a,i,r,s){
|
||||
let l;const d=Ve.hasClass(e,"backlink"),c=Ve.el("div",{className:"inline"});c.dataset.fullID=`${o}.${i}`;const h=Rt.findRoot(e,d);Ve.after(h,c);const u=Ve.x('ancestor::*[contains(@class,"postContainer")][1]',h);if(Ve.addClass(u,"hasInline"),new de(o,a,i,c,s),(l=n.posts.get(`${o}.${i}`))&&r.thread===l.thread&&(d&&t["Forward Hiding"]&&(Ve.addClass(l.nodes.root,"forwarded"),l.forwarded++||(l.forwarded=1)),ee.posts))return ee.readSinglePost(l)},rm(e,o,a,i,r){let s,l;const d=Ve.hasClass(e,"backlink");let c=Rt.findRoot(e,d);c=Ve.x(`following-sibling::div[@data-full-i-d='${o}.${i}'][1]`,c);const h=Ve.x('ancestor::*[contains(@class,"postContainer")][1]',c),{parentNode:u}=c;if(Ve.rm(c),Ve.event("PostsRemoved",null,u),Ve(".inline",h)||Ve.rmClass(h,"hasInline"),!(s=c.firstElementChild))return;const p=n.posts.get(`${o}.${i}`);for(p.rmClone(s.dataset.clone),t["Forward Hiding"]&&d&&r.thread===n.threads.get(`${o}.${a}`)&&!--p.forwarded&&(delete p.forwarded,
|
||||
Ve.rmClass(p.nodes.root,"forwarded"));l=Ve(".inlined",s);)({boardID:o,threadID:a,postID:i}=ze.postDataFromLink(l)),Rt.rm(l,o,a,i,r),Ve.rmClass(l,"inlined")}},Bt={containers:m(),init(){if(["index","thread"].includes(n.VIEW)&&t["Quote Backlinks"])return(this.bottomBacklinks=t["Bottom Backlinks"])&&Ve.addClass(i,"bottom-backlinks"),l.Post.push({name:"Quote Backlinking Part 1",cb:this.firstNode}),l.Post.push({name:"Quote Backlinking Part 2",cb:this.secondNode})},firstNode(){if(this.isClone||!this.quotes.length||this.isRebuilt)return;const e=t["Mark Quotes of You"]&&_.isYou(this),o=Ve.el("a",{href:n.SITE.Build.postURL(this.board.ID,this.thread.ID,this.ID),className:this.isHidden?"filtered backlink":"backlink",textContent:t.backlink.replace(/%(?:id|%)/g,(e=>({"%id":this.ID,"%%":"%"}[e])))});for(var a of(e&&Ve.add(o,_.mark.cloneNode(!0)),this.quotes)){var i,r=[Bt.getContainer(a)];if((i=n.posts.get(a))&&i.nodes.backlinkContainer)for(var s of i.clones)r.push(s.nodes.backlinkContainer)
|
||||
;for(var l of r){var d=o.cloneNode(!0),c=l.firstChild?[Ve.tn(" "),d]:[d];if(t["Quote Previewing"]&&Ve.on(d,"mouseover",ce.mouseover),t["Quote Inlining"]&&(Ve.on(d,"click",Rt.toggle),t["Quote Hash Navigation"])){var h=Rt.qiQuote(d,Ve.hasClass(d,"filtered"));c.push(h)}Ve.add(l,c)}}},secondNode(){if(this.isClone&&(this.origin.isReply||t["OP Backlinks"]))return void(this.nodes.backlinkContainer=Ve(".container",this.nodes.post));if(!this.isReply&&!t["OP Backlinks"])return;const e=Bt.getContainer(this.fullID);return this.nodes.backlinkContainer=e,Bt.bottomBacklinks?Ve.add(this.nodes.post,e):Ve.add(this.nodes.info,e)},getContainer(e){return this.containers[e]||(this.containers[e]=Ve.el("span",{className:"container"}))}},Pt={init(){if(["index","thread"].includes(n.VIEW)&&t["Mark Cross-thread Quotes"])return t["Comment Expansion"]&&X.callbacks.push(this.node),this.mark=Ve.el("span",{textContent:" (Cross-thread)",className:"qmark-ct"}),l.Post.push({name:"Mark Cross-thread Quotes",cb:this.node})
|
||||
},node(){if(this.isClone&&this.thread===this.context.thread)return;const{board:e,thread:t}=this.context;for(var n of this.nodes.quotelinks){var{boardID:o,threadID:a}=ze.postDataFromLink(n);a&&(this.isClone&&Ve.rm(Ve(".qmark-ct",n)),o===e.ID&&a!==t.ID&&Ve.add(n,Pt.mark.cloneNode(!0)))}}},Mt={init(){if(["index","thread"].includes(n.VIEW)&&t["Mark OP Quotes"])return t["Comment Expansion"]&&X.callbacks.push(this.node),this.mark=Ve.el("span",{textContent:" (OP)",className:"qmark-op"}),l.Post.push({name:"Mark OP Quotes",cb:this.node})},node(){let e,t,n;if(this.isClone&&this.thread===this.context.thread)return;if(!(n=this.quotes).length)return;const{quotelinks:o}=this.nodes;if(this.isClone&&n.includes(this.thread.fullID))for(e=0;t=o[e++];)Ve.rm(Ve(".qmark-op",t));const{fullID:a}=this.context.thread;if(n.includes(a))for(e=0;t=o[e++];){var{boardID:i,postID:r}=ze.postDataFromLink(t);`${i}.${r}`===a&&Ve.add(t,Mt.mark.cloneNode(!0))}}};var Nt={init(){
|
||||
if(["index","thread"].includes(n.VIEW)&&t["Resurrect Quotes"])return Ve.addClass(i,"resurrect-quotes"),t["Comment Expansion"]&&X.callbacks.push(this.node),l.Post.push({name:"Resurrect Quotes",cb:this.node})},node(){if(this.isClone)this.nodes.archivelinks=u("a.linkify.quotelink",this.nodes.comment);else{for(var e of u("a.linkify",this.nodes.comment))Nt.parseArchivelink.call(this,e);for(var t of u(".deadlink",this.nodes.comment))Nt.parseDeadlink.call(this,t)}},parseArchivelink(e){let t;if(!(t=e.pathname.match(/^\/([^/]+)\/thread\/S?(\d+)\/?$/)))return;if(["boards.4chan.org","boards.4channel.org"].includes(e.hostname))return;const n=t[1],o=t[2],a=e.hash.match(/^#[pq]?(\d+)$|$/)[1]||o;return Ze.to("post",{boardID:n,postID:a})?(Ve.addClass(e,"quotelink"),Ve.extend(e.dataset,{boardID:n,threadID:o,postID:a}),this.nodes.archivelinks.push(e)):void 0},parseDeadlink(e){let t,o,a,i;if(Ve.hasClass(e.parentNode,"prettyprint"))return void Nt.fixDeadlink(e);const r=e.textContent
|
||||
;if(!(i=r.match(/\d+$/)?.[0]))return;if("0"===i[0])return void Nt.fixDeadlink(e);const s=(o=r.match(/^>>>\/([a-z\d]+)/))?o[1]:this.board.ID,l=`${s}.${i}`;if(a=n.posts.get(l))a.isDead?(t=Ve.el("a",{href:n.SITE.Build.postURL(s,a.thread.ID,i),className:"quotelink deadlink",textContent:r}),Ve.add(t,H.deadMark.cloneNode(!0)),Ve.extend(t.dataset,{boardID:s,threadID:a.thread.ID,postID:i})):t=Ve.el("a",{href:n.SITE.Build.postURL(s,a.thread.ID,i),className:"quotelink",textContent:r});else{const e=Ze.to("thread",{boardID:s,threadID:0,postID:i}),n=Ze.to("post",{boardID:s,postID:i});(e||n)&&(t=Ve.el("a",{href:e||"javascript:;",className:"deadlink",textContent:r}),Ve.add(t,H.deadMark.cloneNode(!0)),n&&(Ve.addClass(t,"quotelink"),Ve.extend(t.dataset,{boardID:s,postID:i})))}if(this.quotes.includes(l)||this.quotes.push(l),t)return Ve.replace(e,t),Ve.hasClass(t,"quotelink")?this.nodes.quotelinks.push(t):void 0;Ve.add(e,H.deadMark.cloneNode(!0))},fixDeadlink(e){let t
|
||||
;if(!(t=e.previousSibling)||"BR"===t.nodeName){const t=Ve.el("span",{className:"quote"});Ve.before(e,t),Ve.add(t,e)}return Ve.replace(e,[...e.childNodes])}};const Lt={init(){this.toBlob(),Ve.global(this.toBlob),Element.prototype.matches||(Element.prototype.matches=Element.prototype.mozMatchesSelector||Element.prototype.webkitMatchesSelector)},toBlob:function(){HTMLCanvasElement.prototype.toBlob||(HTMLCanvasElement.prototype.toBlob=function(e,t,n){const o=this.toDataURL(t,n),a=atob(o.slice(o.indexOf(",")+1)),i=a.length,r=new Uint8Array(i);for(let e=0,t=i;e<t;e++)r[e]=a.charCodeAt(e);return e(new Blob([r],{type:t||"image/png"}))})}};var Ft={init(){let o;try{let t=window;if("crx"===x&&(t=t.wrappedJSObject||t),`${e.name} antidup`in t)return;t[`${e.name} antidup`]=!0}catch(e){}try{if(window.frameElement&&["","about:blank"].includes(window.frameElement.src))return}catch(e){}if(i&&Ve.hasClass(i,"fourchan-x"))return;Ve.asap(s,(function(){if(Ve.addClass(i,"fourchan-x","seaweedchan"),
|
||||
Ve.engine)return Ve.addClass(i,`ua-${Ve.engine}`)})),Ve.on(a,"4chanXInitFinished",(function(){return Ft.expectInitFinished?delete Ft.expectInitFinished:(new Xe("error","Error: Multiple copies of 4chan X are enabled."),Ve.addClass(i,"tainted"))}));var r=function(){return a.removeEventListener("mounted",r,!0),Ft.isMounted=!0,Ft.mountedCBs.map((e=>(()=>{try{return e()}catch(e){}})()))};a.addEventListener("mounted",r,!0);var l=function(e,n){if(n instanceof Array)t[e]=m.clone(n[0]);else if("object"==typeof n)for(var o in n){var a=n[o];l(o,a)}else t[e]=n};for(var d of(["boards.4chan.org","boards.4channel.org"].includes(location.hostname)&&(Ve.global((function(){const e=String.fromCharCode;return String.fromCharCode=function(){if(document.body)String.fromCharCode=e;else if(document.currentScript&&!document.currentScript.src)throw Error();return e.apply(this,arguments)}})),Ve.asap(s,(()=>Ve.onExists(i,"iframe[srcdoc]",Ve.rm)))),l(null,c),y.keys))t[d]=m();t.customTitles=m.clone({"4chan.org":{
|
||||
boards:{qa:{boardTitle:{orig:"/qa/ - Question & Answer",title:"/qa/ - 2D/Random"}}}}}),t.boardConfig={boards:m()},t.archives=Ze.archives,t.selectedArchives=m(),t.cooldowns=m(),t["Index Sort"]=m();for(let e=0;e<2;e++)t[`Last Long Reply Thresholds ${e}`]=m();t.siteProperties=m(),t["Except Archives from Encryption"]=!1,t["JSON Navigation"]=!0,t["Oekaki Links"]=!0,t["Show Name and Subject"]=!1,t["QR Shortcut"]=!0,t["Bottom QR Link"]=!0,t["Toggleable Thread Watcher"]=!0,t.siteSoftware="",t["Use Faster Image Host"]="true",t["Captcha Fixes"]=!0,t.captchaServiceDomain="",t.captchaServiceKey=m(),!/\.4chan(?:nel)?\.org$/.test(location.hostname)||Ce.yotsuba.regexp.pass.test(location.href)||Ce.yotsuba.regexp.captcha.test(location.href)||u("script:not([src])",a).filter((e=>/this\[/.test(e.textContent))).length||(Ve.getSync||Ve.get)({jsWhitelist:t.jsWhitelist},(({jsWhitelist:e})=>Ve.addCSP(`script-src ${e.replace(/^#.*$/gm,"").replace(/[\s;]+/g," ").trim()}`)));const h=m();for(o in t)h[o]=void 0
|
||||
;return h.previousversion=void 0,(Ve.getSync||Ve.get)(h,(function(e){if(Ve.perProtocolSettings||!/\.4chan(?:nel)?\.org$/.test(location.hostname)||!(e["Redirect to HTTPS"]??t["Redirect to HTTPS"])||"https:"===location.protocol)return Ve.asap(s,(function(){for(o in Ve.cantSet||(null==e.previousversion?(Ft.isFirstRun=!0,Ft.ready((function(){return Ve.set("previousversion",n.VERSION),Be.open()}))):e.previousversion!==n.VERSION&&Ft.upgrade(e)),t){var a=t[o];t[o]=e[o]??a}return Ge.init(Ft.initFeatures)}));location.replace("https://"+location.host+location.pathname+location.search+location.hash)}))},upgrade(t){const{previousversion:o}=t,a=Be.upgrade(t,o);return t.previousversion=a.previousversion=n.VERSION,Ve.set(a,(function(){if(t["Show Updated Notifications"]??1){const t=Ve.el("span",{innerHTML:`${e.name} has been updated to <a href="${e.changelog}" target="_blank">version ${n.VERSION}</a>.`});return new Xe("info",t,15)}}))},parseURL(e=n.SITE,t=location){const o={};if(!e)return o
|
||||
;if(o.siteID=e.ID,e.isBoardlessPage?.(t))return o;const a=t.pathname.split(/\/+/);return o.boardID=a[1],e.isFileURL(t)?o.VIEW="file":e.isAuxiliaryPage?.(t)||(["thread","res"].includes(a[2])?(o.VIEW="thread",o.threadID=o.THREADID=+a[3].replace(/\.\w+$/,"")):"archive"===a[2]&&"res"===a[3]?(o.VIEW="thread",o.threadID=o.THREADID=+a[4].replace(/\.\w+$/,""),o.threadArchived=!0):/^(?:catalog|archive)(?:\.\w+)?$/.test(a[2])?o.VIEW=a[2].replace(/\.\w+$/,""):/^(?:index|\d*)(?:\.\w+)?$/.test(a[2])&&(o.VIEW="index")),o},initFeatures(){if(Ve.global((function(){return document.documentElement.classList.add("js-enabled"),window.FCX={}})),Ft.jsEnabled=Ve.hasClass(i,"js-enabled"),Ve.ajaxPageInit?.(),Ve.extend(n,Ft.parseURL()),n.boardID&&(n.BOARD=new J(n.boardID)),n.VIEW){if("file"!==n.VIEW){for(var[e,o]of(n.threads=new k,n.posts=new k,Ve.onExists(i,"body",Ft.initStyle),Ft.features))if(!n.SITE.disabledFeatures||!n.SITE.disabledFeatures.includes(e))try{o.init()}catch(t){Ft.handleErrors({
|
||||
message:`"${e}" initialization crashed.`,error:t})}return Ve.ready(Ft.initReady)}Ve.asap((()=>"loading"!==a.readyState),(function(){let e;if("yotsuba"===n.SITE.software&&t["404 Redirect"]&&n.SITE.is404?.()){const e=location.pathname.split(/\/+/);return Ze.navigate("file",{boardID:n.BOARD.ID,filename:e[e.length-1]})}if((e=Ve("video"))&&(t["Volume in New Tab"]&&$.setup(e),t["Loop in New Tab"]))return e.loop=!0,e.controls=!1,e.play(),j.addControls(e)}))}else n.SITE.initAuxiliary?.()},initStyle(){if(!Ft.isThisPageLegit())return;const e=Ve("link[href*=mobile]",a.head);e&&(e.disabled=!0),i.dataset.host=location.host,Ve.addClass(i,`sw-${n.SITE.software}`),Ve.addClass(i,"thread"===n.VIEW?"thread-view":n.VIEW),Ve.onExists(i,".ad-cnt, .adg-rects > .desktop",(e=>Ve.onExists(e,"img, iframe",(()=>Ve.addClass(i,"ads-loaded"))))),t["Autohiding Scrollbar"]&&Ve.addClass(i,"autohiding-scrollbar"),Ve.ready((function(){
|
||||
if(a.body.clientHeight>i.clientHeight&&window.innerWidth===i.clientWidth!==t["Autohiding Scrollbar"])return t["Autohiding Scrollbar"]=!t["Autohiding Scrollbar"],Ve.set("Autohiding Scrollbar",t["Autohiding Scrollbar"]),Ve.toggleClass(i,"autohiding-scrollbar")})),Ve.addStyle(me.sub(me.boards),"fourchanx-css"),Ft.bgColorStyle=Ve.el("style",{id:"fourchanx-bgcolor-css"});let o=!1;return Ve.on(a,"mousedown",(()=>o=!1)),Ve.on(a,"keydown",(function(e){if(9===e.keyCode)return o=!0})),window.addEventListener("focus",(()=>i.classList.toggle("keyboard-focus",o)),!0),Ft.setClass()},setClass(){let e,t,o;const r=["yotsuba","yotsuba-b","futaba","burichan","photon","tomorrow","spooky"];if("yotsuba"===n.SITE.software&&"catalog"===n.VIEW&&(e=Ve.id("base-css"))&&(t=e.href.match(/catalog_(\w+)/)?.[1].replace("_new","").replace(/_+/g,"-"),r.includes(t)))return void Ve.addClass(i,t);t=e=o=null;const s=function(){if("yotsuba"===n.SITE.software){for(var s of(Ve.rmClass(i,t),t=null,o))if(s.href===e?.href){
|
||||
t=s.title.toLowerCase().replace("new","").trim().replace(/\s+/g,"-"),"_special"===t&&(t=s.href.match(/[a-z]*(?=[^/]*$)/)[0]),r.includes(t)||(t=null);break}if(t)return Ve.addClass(i,t),void Ve.rm(Ft.bgColorStyle)}const l=n.SITE.bgColoredEl();l.style.position="absolute",l.style.visibility="hidden",Ve.add(a.body,l);let d=window.getComputedStyle(l).backgroundColor;Ve.rm(l);const c=d.match(/[\d.]+/g);if(!/^rgb\(/.test(d)){const e=window.getComputedStyle(a.body);d=`${e.backgroundColor} ${e.backgroundImage} ${e.backgroundRepeat} ${e.backgroundPosition}`}let h=`.dialog, .suboption-list > div:last-of-type, :root.catalog-hover-expand .catalog-container:hover > .post {\n background: ${d};\n}\n.unread-mark-read {\n background-color: rgba(${c.slice(0,3).join(", ")}, ${.5*(c[3]||1)});\n}`
|
||||
;return Ve.luma(c)<100&&(h+=".watch-thread-link {\n background-image: url(\"data:image/svg+xml,<svg viewBox='0 0 26 26' preserveAspectRatio='true' xmlns='http://www.w3.org/2000/svg'><path fill='rgb(200,200,200)' d='M24.132,7.971c-2.203-2.205-5.916-2.098-8.25,0.235L15.5,8.588l-0.382-0.382c-2.334-2.333-6.047-2.44-8.25-0.235c-2.204,2.203-2.098,5.916,0.235,8.249l8.396,8.396l8.396-8.396C26.229,13.887,26.336,10.174,24.132,7.971z'/></svg>\");\n}"),Ft.bgColorStyle.textContent=h,Ve.after(Ve.id("fourchanx-css"),Ft.bgColorStyle)};if(Ve.onExists(a.head,n.SITE.selectors.styleSheet,(function(t){return e=t,"yotsuba"===n.SITE.software&&(o=u('link[rel="alternate stylesheet"]',a.head)),new MutationObserver(s).observe(e,{attributes:!0,attributeFilter:["href"]}),Ve.on(e,"load",s),s()})),!e){for(var l of u('link[rel="stylesheet"]',a.head))Ve.on(l,"load",s);return s()}},initReady(){if(!n.SITE.is404?.()){if(n.SITE.isIncomplete?.()){const e=Ve.el("div",{
|
||||
innerHTML:'The page didn't load completely.<br>Some features may not work unless you <a href="javascript:;">reload</a>.'});Ve.on(Ve("a",e),"click",(()=>location.reload())),new Xe("warning",e)}return"catalog"===n.VIEW?Ft.initCatalog():ue.enabled?(Ft.expectInitFinished=!0,Ve.event("4chanXInitFinished")):n.SITE.awaitBoard?n.SITE.awaitBoard(Ft.initThread):Ft.initThread()}"thread"===n.VIEW&&ae.set404(n.BOARD.ID,n.THREADID,(function(){if(t["404 Redirect"])return Ze.navigate("thread",{boardID:n.BOARD.ID,threadID:n.THREADID,postID:+location.hash.match(/\d+/)},`/${n.BOARD}/`)}))},initThread(){let e;const t=n.SITE.selectors;if(e=Ve(t.boardFor?.[n.VIEW]||t.board)){const o=[],a=[],i=[];try{n.SITE.preParsingFixes?.(e)}catch(e){}return Ft.addThreadsObserver=new MutationObserver(Ft.addThreads),Ft.addPostsObserver=new MutationObserver(Ft.addPosts),Ft.addThreadsObserver.observe(e,{childList:!0}),Ft.parseThreads(u(t.thread,e),o,a,i),i.length&&Ft.handleErrors(i),
|
||||
"thread"===n.VIEW&&(n.threadArchived&&(o[0].isArchived=!0,o[0].kill()),n.SITE.parseThreadMetadata?.(o[0])),Ft.callbackNodes("Thread",o),Ft.callbackNodesDB("Post",a,(function(){for(var e of a)Te.insert(e);return Ft.expectInitFinished=!0,Ve.event("4chanXInitFinished")}))}return Ft.expectInitFinished=!0,Ve.event("4chanXInitFinished")},parseThreads(e,t,o,a){for(var i of e){var r=(()=>{let e;return(e=i.dataset.board)?(e=encodeURIComponent(e),n.boards[e]||new J(e)):n.BOARD})(),s=+i.id.match(/\d*$/)[0];if(!s||r.threads.get(s)?.nodes.root)return;var l=new I(s,r);l.nodes.root=i,t.push(l);var d=u(n.SITE.selectors.postContainer,i);n.SITE.isOPContainerThread&&d.unshift(i),Ft.parsePosts(d,l,o,a),Ft.addPostsObserver.observe(i,{childList:!0})}},parsePosts(e,t,o,a){for(var i of e)if((!i.dataset.fullID||!n.posts.get(i.dataset.fullID))&&Ve(n.SITE.selectors.comment,i))try{o.push(new H(i,t,t.board))}catch(e){a.push({message:`Parsing of Post No.${i.id.match(/\d+/)} failed. Post will be skipped.`,error:e,
|
||||
html:i.outerHTML})}},addThreads(e){const t=[];for(var o of e)for(var a of o.addedNodes)a.nodeType===Node.ELEMENT_NODE&&a.matches(n.SITE.selectors.thread)&&t.push(a);if(!t.length)return;const i=[],r=[],s=[];return Ft.parseThreads(t,i,r,s),s.length&&Ft.handleErrors(s),Ft.callbackNodes("Thread",i),Ft.callbackNodesDB("Post",r,(()=>Ve.event("PostsInserted",null,e[0].target)))},addPosts(e){let t;const o=[],a=[],r=[],s=[];for(var l of e){t=ze.threadFromRoot(l.target);var d=[];for(var c of l.addedNodes)c.nodeType===Node.ELEMENT_NODE&&(c.matches(n.SITE.selectors.postContainer)||(c=Ve(n.SITE.selectors.postContainer,c)))&&d.push(c);var h=r.length;Ft.parsePosts(d,t,r,s),r.length>h&&!o.includes(t)&&o.push(t);var u=!1;for(var p of l.removedNodes)if(ze.postFromRoot(p)?.nodes.root===p&&!i.contains(p)){u=!0;break}u&&!a.includes(t)&&a.push(t)}return s.length&&Ft.handleErrors(s),Ft.callbackNodesDB("Post",r,(function(){for(t of o)Ve.event("PostsInserted",null,t.nodes.root)
|
||||
;for(t of a)Ve.event("PostsRemoved",null,t.nodes.root)}))},initCatalog(){let e;const t=n.SITE.selectors.catalog;if(t&&(e=Ve(t.board))){const n=[],o=[];Ft.addCatalogThreadsObserver=new MutationObserver(Ft.addCatalogThreads),Ft.addCatalogThreadsObserver.observe(e,{childList:!0}),Ft.parseCatalogThreads(u(t.thread,e),n,o),o.length&&Ft.handleErrors(o),Ft.callbackNodes("CatalogThreadNative",n)}return Ft.expectInitFinished=!0,Ve.event("4chanXInitFinished")},parseCatalogThreads(e,t,n){for(var o of e)try{var a=new et(o);a.thread.catalogViewNative?.nodes.root!==o&&(a.thread.catalogViewNative=a,t.push(a))}catch(e){n.push({message:`Parsing of Catalog Thread No.${(o.dataset.id||o.id).match(/\d+/)} failed. Thread will be skipped.`,error:e,html:o.outerHTML})}},addCatalogThreads(e){const t=[];for(var o of e)for(var a of o.addedNodes)a.nodeType===Node.ELEMENT_NODE&&a.matches(n.SITE.selectors.catalog.thread)&&t.push(a);if(!t.length)return;const i=[],r=[];return Ft.parseCatalogThreads(t,i,r),
|
||||
r.length&&Ft.handleErrors(r),Ft.callbackNodes("CatalogThreadNative",i)},callbackNodes(e,t){let n,o=0;const a=l[e];for(;n=t[o++];)a.execute(n)},callbackNodesDB(e,t,n){let o=0;const a=l[e],i=function(){let e;return!!(e=t[o])&&(a.execute(e),++o%250)};var r=function(){for(;i(););if(t[o])return setTimeout(r,0);n&&n()};return r()},handleErrors(r){let s;if(a.body&&Ve.hasClass(a.body,"fourchan_x")&&!Ve.hasClass(i,"tainted")&&(new Xe("error","Error: Multiple copies of 4chan X are enabled."),Ve.addClass(i,"tainted")),n.SITE.testNativeExtension&&!Ve.hasClass(i,"tainted")){const{enabled:a}=n.SITE.testNativeExtension();if(a&&(Ve.addClass(i,"tainted"),t["Disable Native Extension"]&&!Ft.isFirstRun)){const t=Ve.el("div",{innerHTML:'Failed to disable the native extension. You may need to <a href="'+o(e.faq)+'#blocking-native-extension" target="_blank">block it</a>.'});new Xe("error",t)}}if(r instanceof Array?1===r.length&&(s=r[0]):s=r,s)return void new Xe("error",Ft.parseError(s,Ft.reportLink([s])),15)
|
||||
;const l=Ve.el("div",{innerHTML:`${r.length} errors occurred.${Ft.reportLink(r).innerHTML} [<a href="javascript:;">show</a>]`});Ve.on(l.lastElementChild,"click",(function(){return[this.textContent,d.hidden]="show"===this.textContent?["hide",!1]:["show",!0]}));var d=Ve.el("div",{hidden:!0});for(s of r)Ve.add(d,Ft.parseError(s));return new Xe("error",[l,d],30)},parseError(t,a){r.error(t.message,t.error.stack);const i=Ve.el("div",{innerHTML:o(t.message)+(a?a.innerHTML:"")}),s=Ve.el("div",{textContent:`${t.error.name||"Error"}: ${t.error.message||"see console for details"}`}),l=t.error.stack?.match(/\d+(?=:\d+\)?$)/gm)?.join().replace(/^/," at ")||"";return[i,s,Ve.el("div",{textContent:`(${e.name} ${e.fork} v${n.VERSION} ${x} on ${Ve.engine}${l})`})]},reportLink(t){let o;const a=t[0];let i=a.message;t.length>1&&(i+=` (+${t.length-1} other errors)`);let r="";const s=function(t){
|
||||
if(encodeURIComponent(i+r+t+"\n").length<=e.newIssueMaxLength-e.newIssue.replace(/%(title|details)/,"").length)return r+=t+"\n"};s(`[Please describe the steps needed to reproduce this error.]\n\nScript: ${e.name} ${e.fork} v${n.VERSION} ${x}\nURL: ${location.href}\nUser agent: ${navigator.userAgent}`),"userscript"===x&&(o="undefined"!=typeof GM&&null!==GM?GM.info:"undefined"!=typeof GM_info&&null!==GM_info?GM_info:void 0)&&s(`Userscript manager: ${o.scriptHandler} ${o.version}`),s("\n"+a.error),a.error.stack&&s(a.error.stack.replace(a.error.toString(),"").trim()),a.html&&s("\n`"+a.html+"`"),r=r.replace(/file:\/{3}.+\//g,"");return{innerHTML:`<span class="report-error"> [<a href="${e.newIssue.replace("%title",encodeURIComponent(i)).replace("%details",encodeURIComponent(r))}" target="_blank">report</a>]</span>`}},
|
||||
isThisPageLegit:()=>("thisPageIsLegit"in Ft||(Ft.thisPageIsLegit=n.SITE.isThisPageLegit?n.SITE.isThisPageLegit():!/^[45]\d\d\b/.test(document.title)&&!/\.(?:json|rss)$/.test(location.pathname)),Ft.thisPageIsLegit),ready:e=>Ve.ready((function(){if(Ft.isThisPageLegit())return e()})),mounted:e=>Ft.isMounted?e():Ft.mountedCBs.push(e),mountedCBs:[],features:[["Polyfill",Lt],["Board Configuration",Y],["Normalize URL",wt],["Delay Redirect on Post",K],["Captcha Configuration",p],["Image Host Rewriting",O],["Redirect",Ze],["Header",Ke],["Catalog Links",Ye],["Settings",Be],["Index Generator",ue],["Disable Autoplay",ut],["Announcement Hiding",kt],["Fourchan thingies",ft],["Tinyboard Glue",Dt],["Color User IDs",mt],["Highlight by User ID",bt],["Count Posts by ID",At],["Custom CSS",Ae],["Thread Links",Ct],["Linkify",rt],["Reveal Spoilers",It],["Resurrect Quotes",Nt],["Filter",We],["Thread Hiding Buttons",pe],["Reply Hiding Buttons",W],["Recursive",z],["Strike-through Quotes",{init(){
|
||||
if(["index","thread"].includes(n.VIEW)&&(t["Reply Hiding Buttons"]||t.Menu&&t["Reply Hiding Link"]||t.Filter))return l.Post.push({name:"Strike-through Quotes",cb:this.node})},node(){if(!this.isClone)for(var e of this.nodes.quotelinks){var{boardID:t,postID:o}=ze.postDataFromLink(e);n.posts.get(`${t}.${o}`)?.isHidden&&Ve.addClass(e,"filtered")}}
|
||||
const e=[],t=function(){const[t,...n]=e.shift();t(...n)};return function(){e.push(arguments),Promise.resolve().then(t)}}(),He.global=function(e,t){if(i){const n=He.el("script",{textContent:`(${e}).call(document.currentScript.dataset);`});return t&&He.extend(n.dataset,t),He.add(a.head||i,n),He.rm(n),n.dataset}try{e.call(t)}catch(e){}return t},He.bytesToString=function(e){let t=0;for(;e>=1024;)e/=1024,t++;return`${e=t>1?Math.round(100*e)/100:Math.round(e)} ${["B","KB","MB","GB"][t]}`},He.minmax=(e,t,n)=>e<t?t:e>n?n:e,He.hasAudio=e=>e.mozHasAudio||!!e.webkitAudioDecodedByteCount||"AUDIO"===e.nextElementSibling?.tagName,He.luma=e=>.299*e[0]+.587*e[1]+.114*e[2],He.unescape=function(e){return null==e?e:e.replace(/<[^>]*>/g,"").replace(/&(amp|#039|quot|lt|gt|#44);/g,(e=>({"&":"&","'":"'",""":'"',"<":"<",">":">",",":","}[e])))},He.isImage=e=>/\.(jpe?g|jfif|png|gif|bmp|webp|avif|jxl)$/i.test(e),He.isVideo=e=>/\.(webm|mp4|ogv)$/i.test(e),
|
||||
He.engine=/Edge\//.test(navigator.userAgent)?"edge":/Chrome\//.test(navigator.userAgent)?"blink":/WebKit\//.test(navigator.userAgent)?"webkit":/Gecko\/|Goanna/.test(navigator.userAgent)?"gecko":void 0,He.hasStorage=function(){try{return"true"===localStorage.getItem(n.NAMESPACE+"hasStorage")||(localStorage.setItem(n.NAMESPACE+"hasStorage","true"),"true"===localStorage.getItem(n.NAMESPACE+"hasStorage"))}catch(e){return!1}}(),He.item=function(e,t){const n=m();return n[e]=t,n},He.oneItemSugar=e=>function(t,n,o){return"string"==typeof t?e(He.item(t,n),o):e(t,n)},He.syncing=m(),He.securityCheck=function(e){if("https:"!==location.protocol)return delete e["Redirect to HTTPS"]},"crx"===x?(He.oldValue={local:m(),sync:m()},chrome.storage.onChanged.addListener((function(e,t){for(var n in e){var o=He.oldValue.local[n]??He.oldValue.sync[n];He.oldValue[t][n]=m.clone(e[n].newValue);var a=He.oldValue.local[n]??He.oldValue.sync[n],i=He.syncing[n];i&&JSON.stringify(a)!==JSON.stringify(o)&&i(a,n)}})),
|
||||
He.sync=(e,t)=>He.syncing[e]=t,He.forceSync=function(){},He.crxWorking=function(){try{if(chrome.runtime.getManifest())return!0}catch(e){}if(!He.crxWarningShown){const e=He.el("div",{innerHTML:'4chan X seems to have been updated. You will need to <a href="javascript:;">reload</a> the page.'});He.on(He("a",e),"click",(()=>location.reload())),new Xe("warning",e),He.crxWarningShown=!0}return!1},He.get=He.oneItemSugar((function(e,t){if(!He.crxWorking())return;const n={},o=function(o){let a=Object.keys(e);return"gecko"===He.engine&&"sync"===o&&a.length>3&&(a=null),chrome.storage[o].get(a,(function(i){let s;if(i=m.clone(i),chrome.runtime.lastError&&r.error(chrome.runtime.lastError.message),null===a){const t=m();for(s in i){var l=i[s];He.hasOwn(e,s)&&(t[s]=l)}i=t}for(s in e)He.oldValue[o][s]=i[s];if(n[o]=i,n.local&&n.sync)return He.extend(e,n.sync),He.extend(e,n.local),t(e)}))};return o("local"),o("sync")})),function(){const e={local:m(),sync:m()
|
||||
},t=(e,t)=>unescape(encodeURIComponent(JSON.stringify(e))).length+unescape(encodeURIComponent(JSON.stringify(t))).length>chrome.storage.sync.QUOTA_BYTES_PER_ITEM;He.delete=function(t){if(He.crxWorking()){for(var n of("string"==typeof t&&(t=[t]),t))delete e.local[n],delete e.sync[n];return chrome.storage.local.remove(t),chrome.storage.sync.remove(t)}};const n={};var o=function(i,s){const l=m();if(He.extend(l,e[i]),Object.keys(l).length&&!(n[i]>Date.now()))return chrome.storage[i].set(l,(function(){let d,c;if(d=chrome.runtime.lastError)return r.error(d.message),setTimeout(o,A,i),n[i]=Date.now()+A,s?.(d);for(c in delete n[i],l)e[i][c]===l[c]&&delete e[i][c];if("local"===i){for(c in l){var h=l[c];t(c,h)||(e.sync[c]=h)}a()}else chrome.storage.local.remove((()=>{const t=[];for(c in l)c in e.local||t.push(c);return t})());return s?.()}))},a=f(b,(()=>o("sync")));He.set=He.oneItemSugar((function(t,n){if(He.crxWorking())return He.securityCheck(t),He.extend(e.local,t),o("local",n)})),
|
||||
He.clear=function(t){if(!He.crxWorking())return;e.local=m(),e.sync=m();let n=2,o=null;const a=function(){if(chrome.runtime.lastError&&r.error(chrome.runtime.lastError.message),null==o&&(o=chrome.runtime.lastError),!--n)return t?.(o)};return chrome.storage.local.clear(a),chrome.storage.sync.clear(a)}}()):null==GM?.deleteValue||!window.BroadcastChannel||"undefined"!=typeof GM_addValueChangeListener&&null!==GM_addValueChangeListener?("undefined"!=typeof GM_deleteValue&&null!==GM_deleteValue||(He.perProtocolSettings=!0),"undefined"!=typeof GM_deleteValue&&null!==GM_deleteValue?(He.getValue=GM_getValue,He.listValues=()=>GM_listValues()):He.hasStorage?(He.getValue=e=>localStorage.getItem(e),He.listValues=()=>(()=>{const e=[];for(var t in localStorage)t.slice(0,n.NAMESPACE.length)===n.NAMESPACE&&e.push(t);return e})()):(He.getValue=function(){},He.listValues=()=>[]),"undefined"!=typeof GM_addValueChangeListener&&null!==GM_addValueChangeListener?(He.setValue=GM_setValue,
|
||||
He.deleteValue=GM_deleteValue):"undefined"!=typeof GM_deleteValue&&null!==GM_deleteValue?(He.oldValue=m(),He.setValue=function(e,t){if(GM_setValue(e,t),e in He.syncing&&(He.oldValue[e]=t,He.hasStorage))return localStorage.setItem(e,t)},He.deleteValue=function(e){if(GM_deleteValue(e),e in He.syncing&&(delete He.oldValue[e],He.hasStorage))return localStorage.removeItem(e)},He.hasStorage||(He.cantSync=!0)):He.hasStorage?(He.oldValue=m(),He.setValue=function(e,t){return e in He.syncing&&(He.oldValue[e]=t),localStorage.setItem(e,t)},He.deleteValue=function(e){return e in He.syncing&&delete He.oldValue[e],localStorage.removeItem(e)}):(He.setValue=function(){},He.deleteValue=function(){},He.cantSync=He.cantSet=!0),"undefined"!=typeof GM_addValueChangeListener&&null!==GM_addValueChangeListener?(He.sync=(e,t)=>He.syncing[e]=GM_addValueChangeListener(n.NAMESPACE+e,(function(n,o,a,i){if(i)return void 0!==a&&(a=m.json(a)),t(a,e)})),
|
||||
He.forceSync=function(){}):"undefined"!=typeof GM_deleteValue&&null!==GM_deleteValue||He.hasStorage?(He.sync=function(e,t){return e=n.NAMESPACE+e,He.syncing[e]=t,He.oldValue[e]=He.getValue(e)},function(){const e=function({key:e,newValue:t}){let o;if(o=He.syncing[e]){if(null!=t){if(t===He.oldValue[e])return;return He.oldValue[e]=t,o(m.json(t),e.slice(n.NAMESPACE.length))}if(null!=He.oldValue[e])return delete He.oldValue[e],o(void 0,e.slice(n.NAMESPACE.length))}};He.on(window,"storage",e),He.forceSync=function(t){return t=n.NAMESPACE+t,e({key:t,newValue:He.getValue(t)})}}()):(He.sync=function(){},He.forceSync=function(){}),He.delete=function(e){for(var t of(e instanceof Array||(e=[e]),e))He.deleteValue(n.NAMESPACE+t)},He.get=He.oneItemSugar(((e,t)=>He.queueTask(He.getSync,e,t))),He.getSync=function(e,t){for(var o in e){var a;if(a=He.getValue(n.NAMESPACE+o))try{e[o]=m.json(a)}catch(e){if(!/^(?:undefined)*$/.test(a))throw e}}return t(e)},He.set=He.oneItemSugar((function(e,t){
|
||||
return He.securityCheck(e),He.queueTask((function(){for(var o in e){var a=e[o];He.setValue(n.NAMESPACE+o,JSON.stringify(a))}return t?.()}))})),He.clear=function(e){He.delete(Object.keys(t)),He.delete(["previousversion","QR Size","QR.persona"]);try{He.delete(He.listValues().map((e=>e.replace(n.NAMESPACE,""))))}catch(e){}return e?.()}):(He.syncChannel=new BroadcastChannel(n.NAMESPACE+"sync"),He.on(He.syncChannel,"message",(e=>(()=>{const t=[];for(var n in e.data){var o,a=e.data[n];(o=He.syncing[n])&&t.push(o(m.json(JSON.stringify(a)),n))}return t})())),He.sync=(e,t)=>He.syncing[e]=t,He.forceSync=function(){},He.delete=function(e,t){let o;return e instanceof Array||(e=[e]),Promise.all((()=>{const t=[];for(o of e)t.push(GM.deleteValue(n.NAMESPACE+o));return t})()).then((function(){const n=m();for(o of e)n[o]=void 0;return He.syncChannel.postMessage(n),t?.()}))},He.get=He.oneItemSugar((function(e,t){const o=Object.keys(e)
|
||||
;return Promise.all(o.map((e=>GM.getValue(n.NAMESPACE+e)))).then((function(n){for(let t=0;t<n.length;t++){var a=n[t];a&&(e[o[t]]=m.json(a))}return t(e)}))})),He.set=He.oneItemSugar((function(e,t){return He.securityCheck(e),Promise.all((()=>{const t=[];for(var o in e){var a=e[o];t.push(GM.setValue(n.NAMESPACE+o,JSON.stringify(a)))}return t})()).then((function(){return He.syncChannel.postMessage(e),t?.()}))})),He.clear=e=>GM.listValues().then((t=>He.delete(t.map((e=>e.replace(n.NAMESPACE,""))),e))).catch((()=>He.delete(Object.keys(t).concat(["previousversion","QR Size","QR.persona"]),e))));var Ve=He,Qe={url(e,t,...o){let a,i;return(i=n.sites[t.siteID])&&(a=Ve.getOwn(i.urls,e))?a(t,...o):void 0},threadExcerpt(e){const{OP:t}=e,n=`/${decodeURIComponent(e.board.ID)}/ - `+(t.info.subject?.trim()||t.commentDisplay().replace(/\n+/g," // ")||t.file?.name||`No.${t}`);return n.length>73?`${n.slice(0,70)}...`:n},threadFromRoot(e){if(null==e)return null;const{board:t}=e.dataset
|
||||
;return n.threads.get(`${t?encodeURIComponent(t):n.BOARD.ID}.${e.id.match(/\d*$/)[0]}`)},threadFromNode:e=>Qe.threadFromRoot(Ve.x(`ancestor-or-self::${n.SITE.xpath.thread}`,e)),postFromRoot(e){if(null==e)return null;const t=n.posts.get(e.dataset.fullID),o=e.dataset.clone;return o?t.clones[+o]:t},postFromNode:e=>Qe.postFromRoot(Ve.x(`ancestor-or-self::${n.SITE.xpath.postContainer}[1]`,e)),postDataFromLink(e){let t,o,a;if(e.dataset.postID)({boardID:t,threadID:a,postID:o}=e.dataset),a||(a=0);else{const i=e.href.match(n.SITE.regexp.quotelink);[t,a,o]=i.slice(1),o||(o=a)}return{boardID:t,threadID:+a,postID:+o}},allQuotelinksLinkingTo(e){const o=[],{posts:a}=n,{fullID:i}=e,r=function(e,t){for(var n of(o.push(...e.nodes[t]||[]),e.clones))o.push(...n.nodes[t]||[])};if(a.forEach((function(e){if(e.quotes.includes(i))return r(e,"quotelinks")})),t["Quote Backlinks"])for(var s of e.quotes){var l;(l=a.get(s))&&r(l,"backlinks")}return o.filter((function(t){
|
||||
const{boardID:n,postID:o}=Qe.postDataFromLink(t);return n===e.board.ID&&o===e.ID}))}},ze=Qe,We={filters:new Map,init(){if(["index","thread","catalog"].includes(n.VIEW)&&t.Filter&&("catalog"!==n.VIEW||t["Filter in Native Catalog"])){for(var e in t["Filtered Backlinks"]||Ve.addClass(i,"hide-backlinks"),c.filter)for(var o of t[e].split("\n")){let n,i,l,c,m;if("#"===o[0])continue;if(!(l=o.match(/\/(.*)\/(\w*)/)))continue;var a=o.replace(l[0],""),r=this.parseBoards(a.match(/(?:^|;)\s*boards:([^;]+)/)?.[1]),s=this.parseBoards(a.match(/(?:^|;)\s*exclude:([^;]+)/)?.[1]);if(i=["uniqueID","MD5"].includes(e))l=l[1];else try{l=RegExp(l[1],l[2])}catch(t){new Xe("warning",[Ve.tn(`Invalid ${e} filter:`),Ve.el("br"),Ve.tn(o),Ve.el("br"),Ve.tn(t.message)],60);continue}var d=a.match(/(?:^|;)\s*op:(no|only)/)?.[1]||"",h=Ve.getOwn({no:1,only:2},d)||0,u=a.match(/(?:^|;)\s*file:(no|only)/)?.[1]||"";h|=Ve.getOwn({no:4,only:8},u)||0;var p=(()=>{switch(a.match(/(?:^|;)\s*stub:(yes|no)/)?.[1]){case"yes":
|
||||
return!0;case"no":return!1;default:return t.Stubs}})(),g=/(?:^|;)\s*notify/.test(a);(n=/(?:^|;)\s*highlight/.test(a))&&(n=a.match(/(?:^|;)\s*highlight:([\w-]+)/)?.[1]||"filter-highlight",c=a.match(/(?:^|;)\s*top:(yes|no)/)?.[1]||"yes",c="yes"===c),"general"===e&&(m=(m=a.match(/(?:^|;)\s*type:([^;]*)/))?m[1].split(","):["subject","name","filename","comment"]);const b={isstring:i,regexp:l,boards:r,excludes:s,mask:h,hide:!(n||g),stub:p,hl:n,top:c,noti:g};if("general"===e)for(var f of m)this.filters.get(f)?.push(b)??this.filters.set(f,[b]);else this.filters.get(e)?.push(b)??this.filters.set(e,[b])}if(this.filters.size){for(const e of["MD5","uniqueID"]){const t=this.filters.get(e);if(!t)continue;const n=new Map;for(const e of t)n.get(e.regexp)?.push(e)??n.set(e.regexp,[e]);this.filters.set(e,n)}return"catalog"===n.VIEW?We.catalog():l.Post.push({name:"Filter",cb:this.node})}}},parseBoards(e){let t;if(!e)return!1;if(t=We.parseBoardsMemo[e])return t;t=m();let o=""
|
||||
;for(var a of e.split(","))for(var i in a.includes(":")&&([o,a]=a.split(":").slice(-2)),n.sites){var r=n.sites[i];if(i.slice(0,o.length)===o)if(["nsfw","sfw"].includes(a))for(var s of r.sfwBoards?.("sfw"===a)||[])t[`${i}/${s}`]=!0;else t[`${i}/${encodeURIComponent(a)}`]=!0}return We.parseBoardsMemo[e]=t,t},parseBoardsMemo:m(),test(e,t=!0){if(e.filterResults)return e.filterResults;let n,o=!1,a=!0,i=!1,r=!1;_.isYou(e)&&(t=!1);let s=e.isReply?2:1;s|=e.file?4:8;const l=`${e.siteID}/${e.boardID}`,d=`${e.siteID}/*`;for(const c of We.filters.keys())for(const h of We.values(c,e)){const e=We.filters.get(c),u=Array.isArray(e)?e:e.get(h);if(u)for(const e of u)e.boards&&!e.boards[l]&&!e.boards[d]||e.excludes&&(e.excludes[l]||e.excludes[d])||e.mask&s||!(e.isstring?e.regexp===h:e.regexp.test(h))||(e.hide?t&&(o=!0,a&&({stub:a}=e)):(n&&n.includes(e.hl)||(n||(n=[])).push(e.hl),i||({top:i}=e),e.noti&&(r=!0)))}return o?{hide:o,stub:a}:{hl:n,top:i,noti:r}},node(){if(this.isClone)return
|
||||
;const{hide:e,stub:t,hl:o,top:a,noti:i}=We.test(this,!this.isFetchedQuote&&(this.isReply||"index"===n.VIEW));return e?this.isReply?W.hide(this,t):pe.hide(this.thread,t):o&&(this.highlights=o,Ve.addClass(this.nodes.root,...o)),i&&ee.posts&&this.ID>ee.lastReadPost&&!_.isYou(this)?ee.openNotification(this," triggered a notification filter"):void 0},catalog(){let e;if(e=n.SITE.urls.catalogJSON?.(n.BOARD))return We.catalogData=m(),Ve.ajax(e,{onloadend:We.catalogParse}),l.CatalogThreadNative.push({name:"Filter",cb:this.catalogNode})},catalogParse(){if([200,404].includes(this.status)){for(var e of this.response)for(var t of e.threads)We.catalogData[t.no]=t;n.BOARD.threads.forEach((function(e){if(e.catalogViewNative)return We.catalogNode.call(e.catalogViewNative)}))}else new Xe("warning","Failed to fetch catalog JSON data. "+(this.status?`Error ${this.statusText} (${this.status})`:"Connection Error"),1)},catalogNode(){if(this.boardID!==n.BOARD.ID||!We.catalogData[this.ID])return;if(_.db?.get({
|
||||
siteID:n.SITE.ID,boardID:this.boardID,threadID:this.ID,postID:this.ID}))return;const{hide:e,hl:t,top:o}=We.test(n.SITE.Build.parseJSON(We.catalogData[this.ID],this));return e?this.nodes.root.hidden=!0:(t&&(this.highlights=t,Ve.addClass(this.nodes.root,...t)),o?(Ve.prepend(this.nodes.root.parentNode,this.nodes.root),n.SITE.catalogPin?.(this.nodes.root)):void 0)},isHidden:e=>!!We.test(e).hide,valueF:{postID:e=>[`${e.ID}`],name:e=>void 0===e.info.name?[]:[e.info.name],uniqueID:e=>[e.info.uniqueID||""],tripcode:e=>void 0===e.info.tripcode?[]:[e.info.tripcode],capcode:e=>void 0===e.info.capcode?[]:[e.info.capcode],pass:e=>[e.info.pass],email:e=>[e.info.email],subject:e=>[e.info.subject||(e.isReply?void 0:"")],comment:e=>(null==e.info.comment&&(e.info.comment=n.sites[e.siteID]?.Build?.parseComment?.(e.info.commentHTML.innerHTML)),[e.info.comment]),flag:e=>void 0===e.info.flag?[]:[e.info.flag],filename:e=>e.files.map((e=>e.name)),dimensions:e=>e.files.map((e=>e.dimensions)),
|
||||
filesize:e=>e.files.map((e=>e.size)),MD5:e=>e.files.map((e=>e.MD5))},values:(e,t)=>Ve.hasOwn(We.valueF,e)?We.valueF[e](t).filter((e=>null!=e)):[e.split("+").map((function(e){let n;return(n=Ve.getOwn(We.valueF,e))?n(t).map((e=>e||"")).join("\n"):""})).join("\n")],addFilter(e,n,o){if(Ve.hasOwn(c.filter,e))return Ve.get(e,t[e],(function(t){let a=t[e];return a=a?`${a}\n${n}`:n,Ve.set(e,a,o)}))},removeFilters:(e,n,o)=>Ve.get(e,t[e],(function(t){let a=t[e];const i=(Array.isArray(n)?n:[...n.values()].flat()).map(We.escape).join("|");return a=a.replace(RegExp(`(?:$\n|^)(?:${i})$`,"mg"),""),Ve.set(e,a,o)})),showFilters(e){Be.open("Filter");const t=Ve(".section-container"),n=Ve("select[name=filter]",t);return n.value=e,Be.selectFilter.call(n),Ve.onExists(t,"textarea",(function(e){const t=e.textLength;return e.setSelectionRange(t,t),e.focus()}))},quickFilterMD5(){const e=ze.postFromNode(this),o=e.files.filter((e=>e.MD5));if(!o.length)return;const a=o.map((e=>`/${e.MD5}/`)).join("\n")
|
||||
;We.addFilter("MD5",a);const i=e.origin||e;if(i.isReply?W.hide(i):"index"===n.VIEW&&pe.hide(i.thread),!t["MD5 Quick Filter Notifications"])return void(e.nodes.post.getBoundingClientRect().height&&new Xe("info","MD5 filtered.",2));let{notice:r}=We.quickFilterMD5;if(r)return r.filters.push(a),r.posts.push(i),Ve("span",r.el).textContent=`${r.filters.length} MD5s filtered.`;{const e=Ve.el("div",{innerHTML:'<span>MD5 filtered.</span> [<a href="javascript:;">show</a>] [<a href="javascript:;">undo</a>]'});r=We.quickFilterMD5.notice=new Xe("info",e,void 0,(()=>delete We.quickFilterMD5.notice)),r.filters=[a],r.posts=[i];const t=u("a",e);return Ve.on(t[0],"click",We.quickFilterCB.show.bind(r)),Ve.on(t[1],"click",We.quickFilterCB.undo.bind(r))}},quickFilterCB:{show(){return We.showFilters("MD5"),this.close()},undo(){for(var e of(We.removeFilters("MD5",this.filters),this.posts))e.isReply?W.show(e):"index"===n.VIEW&&pe.show(e.thread);return this.close()}},
|
||||
escape:e=>e.replace(new RegExp("/|\\\\|\\^|\\$|\\n|\\.|\\(|\\)|\\{|\\}|\\[|\\]|\\?|\\*|\\+|\\|","g"),(function(e){return"\n"===e?"\\n":"\\"===e?"\\\\":`\\${e}`})),menu:{init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t.Filter)return;const e={el:Ve.el("div",{textContent:"Filter"}),order:50,open:e=>(We.menu.post=e,!0),subEntries:[]};for(var o of[["Name","name"],["Unique ID","uniqueID"],["Tripcode","tripcode"],["Capcode","capcode"],["Pass Date","pass"],["Email","email"],["Subject","subject"],["Comment","comment"],["Flag","flag"],["Filename","filename"],["Image dimensions","dimensions"],["Filesize","filesize"],["Image MD5","MD5"]])e.subEntries.push(We.menu.createSubEntry(o[0],o[1]));return Q.menu.addEntry(e)},createSubEntry(e,t){const n=Ve.el("a",{href:"javascript:;",textContent:e});return n.dataset.type=t,Ve.on(n,"click",We.menu.makeFilter),{el:n,open:e=>We.values(t,e).length}},makeFilter(){const{type:e}=this.dataset,t=We.values(e,We.menu.post).map((function(t){
|
||||
const n=["uniqueID","MD5"].includes(e)?t:We.escape(t);return["uniqueID","MD5"].includes(e)?`/${n}/`:`/^${n}$/`})).join("\n");return We.addFilter(e,t,(()=>We.showFilters(e)))}}},Ge={defaultProperties:{"4chan.org":{software:"yotsuba"},"4channel.org":{canonical:"4chan.org"},"4cdn.org":{canonical:"4chan.org"},"notso.smuglo.li":{canonical:"smuglo.li"},"smugloli.net":{canonical:"smuglo.li"},"smug.nepu.moe":{canonical:"smuglo.li"}},init(e){Ve.extend(t.siteProperties,Ge.defaultProperties);let o=Ge.resolve();return o&&Ve.hasOwn(Ce,t.siteProperties[o].software)&&(this.set(o),e()),Ve.onExists(i,"body",(()=>{for(var a in Ce){var i;if(i=Ce[a].detect?.()){i.software=a,o=location.hostname.replace(/^www\./,"");var r=t.siteProperties[o]||(t.siteProperties[o]=m()),s=0;for(var l in i)r[l]!==i[l]&&(r[l]=i[l],s++);return s&&Ve.set("siteProperties",t.siteProperties),void(n.SITE||(this.set(o),e()))}}}))},resolve(e=location){let{hostname:n}=e;for(;n&&!Ve.hasOwn(t.siteProperties,n);)n=n.replace(/^[^.]*\.?/,"")
|
||||
;if(n){let e;(e=t.siteProperties[n].canonical)&&(n=e)}return n},parseURL(e){const t=Ge.resolve(e);return Ot.parseURL(n.sites[t],e)},set(e){for(var o in t.siteProperties){var a,i=t.siteProperties[o];if(!i.canonical){var{software:r}=i;r&&Ve.hasOwn(Ce,r)&&(n.sites[o]=a=Object.create(Ce[r]),Ve.extend(a,{ID:o,siteID:o,properties:i,software:r}))}}return n.SITE=n.sites[e]}},Ye={init(){if("yotsuba"===n.SITE.software&&(t["External Catalog"]||t["JSON Index"])&&(!t["JSON Index"]||"index"!==n.VIEW)){const o=(()=>{switch(n.VIEW){case"thread":case"archive":return".navLinks.desktop > a";case"catalog":return".navLinks > :first-child > a";case"index":return"#ctrl-top > a, .cataloglink > a"}})();Ve.ready((function(){for(var a of u(o)){var i;switch(a.pathname.replace(/\/+/g,"/")){case`/${n.BOARD}/`:t["JSON Index"]&&(a.textContent="Index"),a.href=Ye.index();break;case`/${n.BOARD}/catalog`:a.href=Ye.catalog()}if("catalog"===n.VIEW&&(i=Ye.catalog())!==n.SITE.urls.catalog?.(n.BOARD)){
|
||||
var r=a.parentNode.cloneNode(!0),s=r.firstElementChild;s.href=i,s.textContent=s.hostname===location.hostname?`${e.name} Catalog`:"External Catalog",Ve.after(a.parentNode,[Ve.tn(" "),r])}}}))}if("yotsuba"===n.SITE.software&&t["JSON Index"]&&t[`Use ${e.name} Catalog`]&&l.Post.push({name:"Catalog Link Rewrite",cb:this.node}),this.enabled=t["Catalog Links"]){let e;Ye.el=e=L.checkbox("Header catalog links","Catalog Links"),e.id="toggleCatalog";const t=Ve("input",e);return Ve.on(t,"change",this.toggle),Ve.sync("Header catalog links",Ye.set),Ke.menu.addEntry({el:e,order:95})}},node(){for(var e of u("a",this.nodes.comment)){var t;(t=e.href.match(/^https?:\/\/(boards\.4chan(?:nel)?\.org\/[^\/]+)\/catalog(#s=.*)?/))&&(e.href=`//${t[1]}/${t[2]||"#catalog"}`)}},toggle(){return Ve.event("CloseMenu"),Ve.set("Header catalog links",this.checked),Ye.set(this.checked)},set:e=>(t["Header catalog links"]=e,Ye.setLinks(Ke.boardList),Ye.setLinks(Ke.bottomBoardList),
|
||||
Ye.el.title=`Turn catalog links ${e?"off":"on"}.`,Ve("input",Ye.el).checked=e),setLinks(e){if(!(Ye.enabled??t["Catalog Links"])||!e)return;const n=/(?:index)?(?:\.\w+)?$/;for(var o of u("a:not([data-only])",e)){var{siteID:a,boardID:i}=o.dataset;if(!a||!i){var r;if(({siteID:a,boardID:i,VIEW:r}=Ge.parseURL(o)),!a||!i||!["index","catalog"].includes(r)||!o.dataset.indexOptions&&o.href.replace(n,"")!==(ze.url(r,{siteID:a,boardID:i})||"").replace(n,""))continue;Ve.extend(o.dataset,{siteID:a,boardID:i})}var s={siteID:a,boardID:i},l=t["Header catalog links"]?Ye.catalog(s):ze.url("index",s);l&&(o.href=l,o.dataset.indexOptions&&l.split("#")[0]===ze.url("index",s)&&(o.href+=(o.hash?"/":"#")+o.dataset.indexOptions))}},externalParse(){for(var e of(Ye.externalList=m(),t.externalCatalogURLs.split("\n")))if("#"!==e[0]){var n=e.split(";")[0],o=We.parseBoards(e.match(/;boards:([^;]+)/)?.[1]||"*"),a=We.parseBoards(e.match(/;exclude:([^;]+)/)?.[1])||m()
|
||||
;for(var i in o)a[i]||a[i.split("/")[0]+"/*"]||(Ye.externalList[i]=n)}},external({siteID:e,boardID:t}){Ye.externalList||Ye.externalParse();const n=Ye.externalList[`${e}/${t}`]||Ye.externalList[`${e}/*`];return n?n.replace(/%board/g,t):void 0},jsonIndex:(e,t)=>n.SITE.ID===e.siteID&&n.BOARD.ID===e.boardID&&"index"===n.VIEW?t:ze.url("index",e)+t,catalog(o=n.BOARD){let a,i;return t["External Catalog"]&&(a=Ye.external(o))?a:ue.enabledOn(o)&&t[`Use ${e.name} Catalog`]?Ye.jsonIndex(o,"#catalog"):(i=ze.url("catalog",o))?i:Ye.external(o)},index:(e=n.BOARD)=>ue.enabledOn(e)?Ye.jsonIndex(e,"#index"):ze.url("index",e)},Je={init(){Ve.onExists(i,"body",(()=>{if(Ot.isThisPageLegit())return Ve.add(this.bar,[this.noticesRoot,this.toggle]),Ve.prepend(a.body,this.bar),Ve.add(a.body,Je.hover),this.setBarPosition(t["Bottom Header"])})),this.menu=new L.Menu("header");const e=Ve.el("span",{className:"menu-button"});Ve.extend(e,{innerHTML:"<i></i>"})
|
||||
;const o=L.checkbox,r=o("Fixed Header","Fixed Header"),s=o("Header auto-hide","Auto-hide header"),l=o("Header auto-hide on scroll","Auto-hide header on scroll"),d=o("Bottom Header","Bottom header"),c=o("Centered links","Centered links"),h=o("Custom Board Navigation","Custom board navigation"),p=o("Bottom Board List","Hide bottom board list"),g=o("Shortcut Icons","Shortcut Icons"),f=Ve.el("a",{textContent:"Edit custom board navigation",href:"javascript:;"});if(this.barFixedToggler=r.firstElementChild,this.scrollHeaderToggler=l.firstElementChild,this.barPositionToggler=d.firstElementChild,this.linkJustifyToggler=c.firstElementChild,this.headerToggler=s.firstElementChild,this.footerToggler=p.firstElementChild,this.shortcutToggler=g.firstElementChild,this.customNavToggler=h.firstElementChild,Ve.on(e,"click",this.menuToggle),Ve.on(this.headerToggler,"change",this.toggleBarVisibility),Ve.on(this.barFixedToggler,"change",this.toggleBarFixed),
|
||||
Ve.on(this.barPositionToggler,"change",this.toggleBarPosition),Ve.on(this.scrollHeaderToggler,"change",this.toggleHideBarOnScroll),Ve.on(this.linkJustifyToggler,"change",this.toggleLinkJustify),Ve.on(this.footerToggler,"change",this.toggleFooterVisibility),Ve.on(this.shortcutToggler,"change",this.toggleShortcutIcons),Ve.on(this.customNavToggler,"change",this.toggleCustomNav),Ve.on(f,"click",this.editCustomNav),this.setBarFixed(t["Fixed Header"]),this.setHideBarOnScroll(t["Header auto-hide on scroll"]),this.setBarVisibility(t["Header auto-hide"]),this.setLinkJustify(t["Centered links"]),this.setShortcutIcons(t["Shortcut Icons"]),this.setFooterVisibility(t["Bottom Board List"]),Ve.sync("Fixed Header",this.setBarFixed),Ve.sync("Header auto-hide on scroll",this.setHideBarOnScroll),Ve.sync("Bottom Header",this.setBarPosition),Ve.sync("Shortcut Icons",this.setShortcutIcons),Ve.sync("Header auto-hide",this.setBarVisibility),Ve.sync("Centered links",this.setLinkJustify),
|
||||
Ve.sync("Bottom Board List",this.setFooterVisibility),this.addShortcut("menu",e,900),this.menu.addEntry({el:Ve.el("span",{textContent:"Header"}),order:107,subEntries:[{el:r},{el:s},{el:l},{el:d},{el:c},{el:p},{el:g},{el:h},{el:f}]}),Ve.on(window,"load popstate",Je.hashScroll),Ve.on(a,"CreateNotification",this.createNotification),this.setBoardList(),Ve.onExists(i,`${n.SITE.selectors.boardList} + *`,Je.generateFullBoardList),Ot.ready((function(){let e;if("yotsuba"===n.SITE.software&&!(e=Ve.id("boardNavDesktopFoot"))){let t;if(!(t=Ve.id("absbot")))return;e=Ve.id("boardNavDesktop").cloneNode(!0),e.id="boardNavDesktopFoot",Ve("#navtopright",e).id="navbotright",Ve("#settingsWindowLink",e).id="settingsWindowLinkBot",Ve.before(t,e),Ve.global((()=>window.cloneTopNav=function(){}))}if(Je.bottomBoardList=Ve(n.SITE.selectors.boardListBottom)){for(var t of u("a",Je.bottomBoardList))t.hostname===location.hostname&&t.pathname.split("/")[1]===n.BOARD.ID&&(t.className="current")
|
||||
;return Ye.setLinks(Je.bottomBoardList)}})),"yotsuba"===n.SITE.software&&("catalog"===n.VIEW||!t["Disable Native Extension"])){const e=Ve.el("a",{href:"javascript:;"});"catalog"===n.VIEW?(e.title=e.textContent="Catalog Settings",e.textContent="🕮︎"):(e.title=e.textContent="4chan Settings",e.className="native-settings"),Ve.on(e,"click",(()=>Ve.id("settingsWindowLink").click())),this.addShortcut("native",e,810)}return this.enableDesktopNotifications()},bar:Ve.el("div",{id:"header-bar"}),noticesRoot:Ve.el("div",{id:"notifications"}),shortcuts:Ve.el("span",{id:"shortcuts"}),hover:Ve.el("div",{id:"hoverUI"}),toggle:Ve.el("div",{id:"scroll-marker"}),setBoardList(){let e;Je.boardList=e=Ve.el("span",{id:"board-list"}),Ve.extend(e,{innerHTML:'<span id="custom-board-list"></span><span id="full-board-list" hidden><span class="hide-board-list-container brackets-wrap"><a href="javascript:;" class="hide-board-list-button"> - </a></span> <span class="boardList"></span></span>'})
|
||||
;const n=Ve(".hide-board-list-button",e);return Ve.on(n,"click",Je.toggleBoardList),Ve.prepend(Je.bar,[Je.boardList,Je.shortcuts]),Je.setCustomNav(t["Custom Board Navigation"]),Je.generateBoardList(t.boardnav),Ve.sync("Custom Board Navigation",Je.setCustomNav),Ve.sync("boardnav",Je.generateBoardList)},generateFullBoardList(){let e;e=n.SITE.transformBoardList?n.SITE.transformBoardList():[...Ve(n.SITE.selectors.boardList).cloneNode(!0).childNodes];const t=Ve(".boardList",Je.boardList);for(var o of(Ve.add(t,e),u("a",t)))o.hostname===location.hostname&&o.pathname.split("/")[1]===n.BOARD.ID&&(o.className="current");return Ye.setLinks(t)},generateBoardList(e){const t=Ve("#custom-board-list",Je.boardList);if(Ve.rmAll(t),!e)return;const n=(e=e.replace(/(\r\n|\n|\r)/g," ")).match(/[\w@]+(-(all|title|replace|full|index|catalog|archive|expired|nt|(mode|sort|text):"[^"]+"(,"[^"]+")?))*|[^\w@]+/g).map((e=>Je.mapCustomNavigation(e)));return Ve.add(t,n),Ye.setLinks(t)},mapCustomNavigation(e){
|
||||
let o,a,i,r;if(/^[^\w@]/.test(e))return Ve.tn(e);let s=r=null;e=e.replace(/-text:"([^"]+)"(?:,"([^"]+)")?/g,(function(e,t,n){return s=t,r=n,""}));let l=[];if(e=e.replace(/-(?:mode|sort):"([^"]+)"/g,(function(e,t){return l.push(t.toLowerCase().replace(/\ /g,"-")),""})),l=l.join("/"),/^toggle-all/.test(e))return o=Ve.el("a",{className:"show-board-list-button",textContent:s||"+",href:"javascript:;"}),Ve.on(o,"click",Je.toggleBoardList),o;if(/^external/.test(e))return o=Ve.el("a",{href:r||"javascript:;",textContent:s||"+",className:"external"}),/-nt/.test(e)&&(o.target="_blank",o.rel="noopener"),o;let d=e.split("-")[0];if("current"===d){if(!["boards.4chan.org","boards.4channel.org"].includes(location.hostname))return o=Ve.el("a",{href:`/${n.BOARD.ID}/`,textContent:s||decodeURIComponent(n.BOARD.ID),className:"current"}),/-nt/.test(e)&&(o.target="_blank",o.rel="noopener"),/-index/.test(e)?o.dataset.only="index":/-catalog/.test(e)?(o.dataset.only="catalog",
|
||||
o.href+="catalog.html"):/-(archive|expired)/.test(e)&&(o=o.firstChild),o;d=n.BOARD.ID}if(o=function(){let e;return"@"===d?Ve.el("a",{href:"https://twitter.com/4chan",title:"4chan Twitter",textContent:"@"}):(o=Ve.el("a",{href:`//${Y.domain(d)}/${d}/`,textContent:d,title:Y.title(d)}),["catalog","archive"].includes(n.VIEW)&&(e=ze.url(n.VIEW,{siteID:"4chan.org",boardID:d}))&&(o.href=e),o.hostname===location.hostname&&d===n.BOARD.ID&&(o.className="current"),o)}(),o.textContent=/-title/.test(e)||/-replace/.test(e)&&o.hostname===location.hostname&&d===n.BOARD.ID?o.title||o.textContent:/-full/.test(e)?`/${d}/`+(o.title?` - ${o.title}`:""):s||d,i=e.match(/-(index|catalog)/)){const e=Ye[i[1]]({siteID:"4chan.org",boardID:d});if(!e)return o.firstChild;o.dataset.only=i[1],o.href=e,"catalog"===i[1]&&Ve.addClass(o,"catalog")}if(t["JSON Index"]&&l&&(o.dataset.indexOptions=l,["boards.4chan.org","boards.4channel.org"].includes(o.hostname)&&""===o.pathname.split("/")[2]&&(o.href+=(o.hash?"/":"#")+l)),
|
||||
/-archive/.test(e)){if(!(a=Ze.to("board",{boardID:d})))return o.firstChild;o.href=a}if(/-expired/.test(e)){if(!Y.isArchived(d))return o.firstChild;o.href=`//${Y.domain(d)}/${d}/archive`}return/-nt/.test(e)&&(o.target="_blank",o.rel="noopener"),"@"===d&&Ve.addClass(o,"navSmall"),o},toggleBoardList(){const{bar:e}=Je,t=Ve("#custom-board-list",e),n=Ve("#full-board-list",e),o=!n.hidden;return t.hidden=!o,n.hidden=o},setLinkJustify:e=>(Je.linkJustifyToggler.checked=e,e?Ve.addClass(i,"centered-links"):Ve.rmClass(i,"centered-links")),toggleLinkJustify(){Ve.event("CloseMenu");const e="INPUT"===this.nodeName?this.checked:void 0;return Je.setLinkJustify(e),Ve.set("Centered links",e)},setBarFixed:e=>(Je.barFixedToggler.checked=e,e?(Ve.addClass(i,"fixed"),Ve.addClass(Je.bar,"dialog")):(Ve.rmClass(i,"fixed"),Ve.rmClass(Je.bar,"dialog"))),toggleBarFixed(){return Ve.event("CloseMenu"),Je.setBarFixed(this.checked),t["Fixed Header"]=this.checked,Ve.set("Fixed Header",this.checked)},
|
||||
setShortcutIcons:e=>(Je.shortcutToggler.checked=e,e?Ve.addClass(i,"shortcut-icons"):Ve.rmClass(i,"shortcut-icons")),toggleShortcutIcons(){return Ve.event("CloseMenu"),Je.setShortcutIcons(this.checked),t["Shortcut Icons"]=this.checked,Ve.set("Shortcut Icons",this.checked)},setBarVisibility:e=>(Je.headerToggler.checked=e,Ve.event("CloseMenu"),(e?Ve.addClass:Ve.rmClass)(Je.bar,"autohide"),(e?Ve.addClass:Ve.rmClass)(i,"autohide")),toggleBarVisibility(){const e="INPUT"===this.nodeName?this.checked:!Ve.hasClass(Je.bar,"autohide");t["Header auto-hide"]=e,Ve.set("Header auto-hide",e),Je.setBarVisibility(e);return new Xe("info","The header bar will "+(e?"automatically hide itself.":"remain visible."),2)},setHideBarOnScroll(e){if(Je.scrollHeaderToggler.checked=e,!e)return Ve.off(window,"scroll",Je.hideBarOnScroll),Ve.rmClass(Je.bar,"scroll"),Je.bar.classList.toggle("autohide",t["Header auto-hide"]);Ve.on(window,"scroll",Je.hideBarOnScroll)},toggleHideBarOnScroll(){const e=this.checked
|
||||
;return Ve.cb.checked.call(this),Je.setHideBarOnScroll(e)},hideBarOnScroll(){const e=window.pageYOffset;return e>(Je.previousOffset||0)?Ve.addClass(Je.bar,"autohide","scroll"):Ve.rmClass(Je.bar,"autohide","scroll"),Je.previousOffset=e},setBarPosition(e){Je.barPositionToggler&&(Je.barPositionToggler.checked=e),Ve.event("CloseMenu");const t=e?["bottom-header","top-header","after"]:["top-header","bottom-header","add"];return Ve.addClass(i,t[0]),Ve.rmClass(i,t[1]),Ve[t[2]](Je.bar,Je.noticesRoot)},toggleBarPosition(){return Ve.cb.checked.call(this),Je.setBarPosition(this.checked)},setFooterVisibility:e=>(Je.footerToggler.checked=e,i.classList.toggle("hide-bottom-board-list",e)),toggleFooterVisibility(){Ve.event("CloseMenu");const e="INPUT"===this.nodeName?this.checked:Ve.hasClass(i,"hide-bottom-board-list");Je.setFooterVisibility(e),Ve.set("Bottom Board List",e);return new Xe("info",e?"The bottom navigation will now be hidden.":"The bottom navigation will remain visible.",2)},
|
||||
setCustomNav(e){Je.customNavToggler.checked=e;const t=Ve("#custom-board-list",Je.bar),n=Ve("#full-board-list",Je.bar),o=Ve(".hide-board-list-container",n);return[t.hidden,n.hidden,o.hidden]=e?[!1,!0,!1]:[!0,!1,!0]},toggleCustomNav(){return Ve.cb.checked.call(this),Je.setCustomNav(this.checked)},editCustomNav(){Be.open("Advanced");const e=Ve.id("fourchanx-settings");return Ve("[name=boardnav]",e).focus()},hashScroll(e){let t;if(e){if(e.state)return;history.state||history.replaceState({},"")}if(t=location.hash.slice(1)){let e;if(Se.showIfHidden(t),e=Ve.id(t))return Ve.queueTask((()=>Je.scrollTo(e)))}},scrollTo(e,n,o){let a,i;if(e.offsetParent)if(n){if(i=Je.getBottomOf(e),t["Fixed Header"]&&t["Header auto-hide on scroll"]&&t["Bottom header"]&&(({height:a}=Je.bar.getBoundingClientRect()),i<=0?Je.isHidden()||(i+=a):Je.isHidden()&&(i-=a)),!o||i<0)return window.scrollBy(0,-i)}else if(i=Je.getTopOf(e),
|
||||
t["Fixed Header"]&&t["Header auto-hide on scroll"]&&!t["Bottom header"]&&(({height:a}=Je.bar.getBoundingClientRect()),i>=0?Je.isHidden()||(i+=a):Je.isHidden()&&(i-=a)),!o||i<0)return window.scrollBy(0,i)},scrollToIfNeeded:(e,t)=>Je.scrollTo(e,t,!0),getTopOf(e){let{top:n}=e.getBoundingClientRect();if(t["Fixed Header"]&&!t["Bottom Header"]){const e=Je.toggle.getBoundingClientRect();n-=e.top+e.height}return n},getBottomOf(e){const{clientHeight:n}=i;let o=n-e.getBoundingClientRect().bottom;if(t["Fixed Header"]&&t["Bottom Header"]){const e=Je.toggle.getBoundingClientRect();o-=n-e.bottom+e.height}return o},isNodeVisible(e){if(a.hidden||!i.contains(e))return!1;const{height:t}=e.getBoundingClientRect();return Je.getTopOf(e)+t>=0&&Je.getBottomOf(e)+t>=0},isHidden(){const{top:e}=Je.bar.getBoundingClientRect();return t["Bottom header"]?e===i.clientHeight:e<0},addShortcut(e,t,n){const o=Ve.el("span",{id:`shortcut-${e}`,className:"shortcut brackets-wrap"});for(var a of(Ve.add(o,t),
|
||||
o.dataset.index=n,u("[data-index]",Je.shortcuts)))if(+a.dataset.index>+n)return void Ve.before(a,o);return Ve.add(Je.shortcuts,o)},rmShortcut:e=>Ve.rm(e.parentElement),menuToggle(e){return Je.menu.toggle(e,this,n)},createNotification(e){const{type:t,content:n,lifetime:o}=e.detail;return new Xe(t,n,o)},areNotificationsEnabled:!1,enableDesktopNotifications(){let n;if(!window.Notification||!t["Desktop Notifications"])return;switch(Notification.permission){case"granted":return void(Je.areNotificationsEnabled=!0);case"denied":return}const o=Ve.el("span",{innerHTML:`${e.name} needs your permission to show desktop notifications. [<a href="${e.faq}#why-is-4chan-x-asking-for-permission-to-show-desktop-notifications" target="_blank">FAQ</a>]<br><button>Authorize</button> or <button>Disable</button>`}),[a,i]=u("button",o);return Ve.on(a,"click",(()=>Notification.requestPermission((function(e){if(Je.areNotificationsEnabled="granted"===e,"default"!==e)return n.close()})))),
|
||||
Ve.on(i,"click",(function(){return Ve.set("Desktop Notifications",!1),n.close()})),n=new Xe("info",o)}},Ke=Je;class Xe{constructor(e,t,n,o){this.add=this.add.bind(this),this.close=this.close.bind(this),this.timeout=n,this.onclose=o,this.el=Ve.el("div",{innerHTML:'<a href="javascript:;" class="close" title="Close">✕</a><div class="message"></div>'}),this.el.style.opacity=0,this.setType(e),Ve.on(this.el.firstElementChild,"click",this.close),"string"==typeof t&&(t=Ve.tn(t)),Ve.add(this.el.lastElementChild,t),Ve.ready(this.add)}setType(e){return this.el.className=`notification ${e}`}add(){if(!this.closed){if(!a.hidden)return Ve.off(a,"visibilitychange",this.add),Ve.add(Ke.noticesRoot,this.el),this.el.clientHeight,this.el.style.opacity=1,this.timeout?setTimeout(this.close,this.timeout*b):void 0;Ve.on(a,"visibilitychange",this.add)}}close(){return this.closed=!0,Ve.off(a,"visibilitychange",this.add),Ve.rm(this.el),this.onclose?.()}}var _e={archives:[{uid:3,name:"4plebs",
|
||||
domain:"archive.4plebs.org",http:!0,https:!0,software:"foolfuuka",boards:["adv","f","hr","mlpol","mo","o","pol","s4s","sp","tg","trv","tv","x"],files:["adv","f","hr","mlpol","mo","o","pol","s4s","sp","tg","trv","tv","x"],reports:!0},{uid:10,name:"warosu",domain:"warosu.org",http:!1,https:!0,software:"fuuka",boards:["3","biz","cgl","ck","diy","fa","ic","jp","lit","sci","vr","vt"],files:["3","biz","cgl","ck","diy","fa","ic","jp","lit","sci","vr","vt"],search:["biz","cgl","ck","diy","fa","ic","jp","lit","sci","vr","vt"]},{uid:23,name:"Desuarchive",domain:"desuarchive.org",http:!0,https:!0,software:"foolfuuka",boards:["a","aco","an","c","cgl","co","d","fit","g","his","int","k","m","mlp","mu","q","qa","r9k","tg","trash","vr","wsg"],files:["a","aco","an","c","cgl","co","d","fit","g","his","int","k","m","mlp","mu","q","qa","r9k","tg","trash","vr"],reports:!0},{uid:24,name:"fireden.net",domain:"boards.fireden.net",http:!1,https:!0,software:"foolfuuka",boards:["cm","co","ic","sci","vip","y"],
|
||||
files:["cm","co","ic","sci","vip","y"],search:["cm","co","ic","sci","y"]},{uid:25,name:"arch.b4k.co",domain:"arch.b4k.co",http:!0,https:!0,software:"foolfuuka",boards:["g","mlp","qb","v","vg","vm","vmg","vp","vrpg","vst"],files:["qb","v","vg","vm","vmg","vp","vrpg","vst"],search:["qb","v","vg","vm","vmg","vp","vrpg","vst"]},{uid:29,name:"Archived.Moe",domain:"archived.moe",http:!0,https:!0,software:"foolfuuka",boards:["3","a","aco","adv","an","asp","b","bant","biz","c","can","cgl","ck","cm","co","cock","con","d","diy","e","f","fa","fap","fit","fitlit","g","gd","gif","h","hc","his","hm","hr","i","ic","int","jp","k","lgbt","lit","m","mlp","mlpol","mo","mtv","mu","n","news","o","out","outsoc","p","po","pol","pw","q","qa","qb","qst","r","r9k","s","s4s","sci","soc","sp","spa","t","tg","toy","trash","trv","tv","u","v","vg","vint","vip","vm","vmg","vp","vr","vrpg","vst","vt","w","wg","wsg","wsr","x","xs","y"],
|
||||
files:["can","cock","con","fap","fitlit","gd","mlpol","mo","mtv","outsoc","po","q","qb","qst","spa","vint","vip"],search:["aco","adv","an","asp","b","bant","biz","c","can","cgl","ck","cm","cock","con","d","diy","e","f","fap","fitlit","gd","gif","h","hc","his","hm","hr","i","ic","lgbt","lit","mlpol","mo","mtv","n","news","o","out","outsoc","p","po","pw","q","qa","qst","r","s","soc","spa","trv","u","vint","vip","vrpg","w","wg","wsg","wsr","x","y"],reports:!0},{uid:30,name:"TheBArchive.com",domain:"thebarchive.com",http:!0,https:!0,software:"foolfuuka",boards:["b","bant"],files:["b","bant"],reports:!0},{uid:31,name:"Archive Of Sins",domain:"archiveofsins.com",http:!0,https:!0,software:"foolfuuka",boards:["h","hc","hm","i","lgbt","r","s","soc","t","u"],files:["h","hc","hm","i","lgbt","r","s","soc","t","u"],reports:!0},{uid:34,name:"TokyoChronos",domain:"www.tokyochronos.net",http:!1,https:!0,software:"foolfuuka",boards:["c","g","jp","mu","vp","vrpg","vt"],files:[],reports:!0},{uid:36,
|
||||
name:"palanq.win",domain:"archive.palanq.win",http:!1,https:!0,software:"foolfuuka",boards:["bant","c","con","e","i","n","news","out","p","pw","qst","toy","vip","vp","vt","w","wg","wsr"],files:["bant","c","e","i","n","news","out","p","pw","qst","toy","vip","vp","vt","w","wg","wsr"],reports:!0},{uid:37,name:"Eientei",domain:"eientei.xyz",http:!1,https:!0,software:"Eientei",boards:["3","i","sci","xs"],files:["3","i","sci","xs"],reports:!0}],init(){if(this.selectArchives(),t.archiveAutoUpdate){const e=Date.now();if(e-2*w>=t.lastarchivecheck||t.lastarchivecheck>e)return this.update()}},selectArchives(){let e,n,o,a;const i={thread:m(),post:m(),file:m()},r=m();for(o of t.archives){var s,l,d;for(var c of["boards","files"])o[c]instanceof Array||(o[c]=[]);if(({uid:d,name:s,boards:n,files:a,software:l}=o),["fuuka","foolfuuka"].includes(l))for(e of(r[JSON.stringify(d??s)]=o,n))e in i.thread||(i.thread[e]=o),e in i.post||"foolfuuka"!==l||(i.post[e]=o),!(e in i.file)&&a.includes(e)&&(i.file[e]=o)}
|
||||
for(e in t.selectedArchives){var h=t.selectedArchives[e];for(var u in h){var p,g=h[u];(p=r[JSON.stringify(g)])&&Ve.hasOwn(i,u)&&(n="file"===u?p.files:p.boards,n.includes(e)&&(i[u][e]=p))}}return _e.data=i},update(e){let n;const o=[],a=[];let i=0;for(n of t.archiveLists.split("\n"))"#"!==n[0]&&(n=n.trim(),n&&o.push(n));const r=(e,t,n)=>new Xe("warning",`Error ${t} archive data from\n${e}\n${n}`,20),s=t=>function(){if(200!==this.status)return r(o[t],"fetching",this.status?`Error ${this.statusText} (${this.status})`:"Connection Error");let{response:n}=this;return n instanceof Array||(n=[n]),a[t]=n,i++,i===o.length?_e.parse(a,e):void 0};if(o.length)for(let e=0;e<o.length;e++)if(n=o[e],["[","{"].includes(n[0])){var l;try{l=JSON.parse(n)}catch(e){r(n,"parsing",e.message);continue}s(e).call({status:200,response:l})}else Ue.ajax(n,{onloadend:s(e)});else _e.parse([],e)},parse(e,n){const o=[],a=m();for(var i of e)for(var r of i){var s=JSON.stringify(r.uid??r.name)
|
||||
;s in a?Ve.extend(a[s],r):(a[s]=m.clone(r),o.push(r))}const l={archives:o,lastarchivecheck:Date.now()};return Ve.set(l),Ve.extend(t,l),_e.selectArchives(),n?.()},to(e,t){const n=(["search","board"].includes(e)?_e.data.thread:_e.data[e])[t.boardID];return n?_e[e](n,t):""},protocol(e){let{protocol:t}=location;return Ve.getOwn(e,t.slice(0,-1))||(t="https:"===t?"http:":"https:"),`${t}//`},thread(e,{boardID:t,threadID:n,postID:o}){let a=n?`${t}/thread/${n}`:`${t}/post/${o}`;return"foolfuuka"===e.software&&(a+="/"),n&&o&&(a+="foolfuuka"===e.software?`#${o}`:`#p${o}`),`${_e.protocol(e)}${e.domain}/${a}`},post(e,{boardID:t,postID:n}){const o=`${_e.protocol(e)}${e.domain}/_/api/chan/post/?board=${t}&num=${n}`;return _e.securityCheck(o)?o:""},file(e,{boardID:t,filename:n}){if(!n)return"";if("f"===t)n=encodeURIComponent(Ve.unescape(decodeURIComponent(n)));else if(/[sm]\.jpg$/.test(n))return"";return`${_e.protocol(e)}${e.domain}/${t}/full_image/${n}`},
|
||||
board:(e,{boardID:t})=>`${_e.protocol(e)}${e.domain}/${t}/`,search(e,{boardID:t,type:n,value:o}){"capcode"===(n="name"===n?"username":"MD5"===n?"image":n)?o=Ve.getOwn({Developer:"dev",Verified:"ver"},o)||o.toLowerCase():"image"===n&&(o=o.replace(/[+/=]/g,(e=>({"+":"-","/":"_","=":""}[e])))),o=encodeURIComponent(o);const a="foolfuuka"===e.software?`${t}/search/${n}/${o}/`:"image"===n?`${t}/image/${o}`:`${t}/?task=search2&search_${n}=${o}`;return`${_e.protocol(e)}${e.domain}/${a}`},report(e){const n=[];for(var o of t.archives){var{software:a,https:i,reports:r,boards:s,name:l,domain:d}=o;"foolfuuka"===a&&i&&r&&s instanceof Array&&s.includes(e)&&n.push([l,`https://${d}/_/api/chan/offsite_report/`])}return n},securityCheck:e=>/^https:\/\//.test(e)||"http:"===location.protocol||t["Exempt Archives from Encryption"],navigate(e,t,n){_e.data||_e.init();const o=_e.to(e,t)
|
||||
;return o&&(_e.securityCheck(o)||confirm(`Redirect to ${o}?\n\nYour connection will not be encrypted.`))?location.replace(o):n?location.replace(n):void 0}},Ze=_e;class et{toString(){return this.ID}constructor(e){this.nodes={root:e,thumb:Ve(n.SITE.selectors.catalog.thumb,e)},this.siteID=n.SITE.ID,this.boardID=this.nodes.thumb.parentNode.pathname.split(/\/+/)[1],this.board=n.boards[this.boardID]||new J(this.boardID),this.ID=this.threadID=+(e.dataset.id||e.id).match(/\d*$/)[0],this.thread=this.board.threads.get(this.ID)||new I(this.ID,this.board)}}const tt={init(){if(t.Anonymize)return Ve.addClass(i,"anonymize")}};var nt={init(){if(["index","thread"].includes(n.VIEW))return t["Image Hover"]&&l.Post.push({name:"Image Hover",cb:this.node}),t["Image Hover in Catalog"]?l.CatalogThread.push({name:"Image Hover",cb:this.catalogNode}):void 0},node(){return this.files.filter((e=>(e.isImage||e.isVideo)&&e.thumb)).map((e=>Ve.on(e.thumb,"mouseover",nt.mouseover(this,e))))},catalogNode(){
|
||||
const e=this.thread.OP.files[0];if(e&&(e.isImage||e.isVideo))return Ve.on(this.nodes.thumb,"mouseover",nt.mouseover(this.thread.OP,e))},mouseover:(e,o)=>function(a){let r,s,l;if(!i.contains(this))return;const{isVideo:d}=o;if(o.isExpanding||o.isExpanded||n.SITE.isThumbExpanded?.(o))return;const c=nt.error(e,o);if(j.cache?.dataset.fileID===`${e.fullID}.${o.index}`?(r=j.popCache(),Ve.on(r,"error",c)):(r=Ve.el(d?"video":"img"),r.dataset.fileID=`${e.fullID}.${o.index}`,Ve.on(r,"error",c),r.src=o.url),t["Restart when Opened"]&&(j.rewind(r),j.rewind(this)),r.id="ihover",Ve.add(Ke.hover,r),d&&(r.loop=!0,r.controls=!1,$.setup(r),t.Autoplay&&(r.play(),"VIDEO"===this.nodeName&&(this.currentTime=r.currentTime))),o.dimensions){[l,s]=o.dimensions.split("x").map((e=>+e));const e=i.clientWidth,t=i.clientHeight-L.hover.padding,n=Math.min(1,e/l,t/s);l*=n,s*=n,r.style.maxWidth=`${l}px`,r.style.maxHeight=`${s}px`}return L.hover({root:this,el:r,latestEvent:a,endEvents:"mouseout click",height:s,width:l,
|
||||
noRemove:!0,cb:()=>(Ve.off(r,"error",c),j.pushCache(r),j.pause(r),Ve.rm(r),r.removeAttribute("style"))})},error:(e,t)=>function(){if(!j.decodeError(this,t))return j.error(this,e,t,3e3,(e=>e?this.src=e+(this.src===e?"?"+Date.now():""):Ve.rm(this)))}},ot={init(){if(!["index","thread","archive"].includes(n.VIEW))return;const e=t["Replace JPG"]||t["Replace PNG"]||t["Replace GIF"]||t["Replace WEBM"];if(!t["Image Prefetching"]&&!e)return;if(l.Post.push({name:"Image Replace",cb:this.node}),Ve.on(a,"PostsInserted",(function(){if(ot.prefetchEnabled||e)return n.posts.forEach(ot.prefetchAll)})),t["Replace WEBM"]&&Ve.on(a,"scroll visibilitychange 4chanXInitFinished PostsInserted",this.playVideos),!t["Image Prefetching"]||!["index","thread"].includes(n.VIEW))return;const o=Ve.el("a",{href:"javascript:;",title:"Prefetch Images",innerHTML:"🗲︎"});return Ve.on(o,"click",this.toggle),Ke.addShortcut("prefetch",o,525)},node(){
|
||||
if(!this.isClone)for(var e of this.files)t["Replace WEBM"]&&e.isVideo&&ot.replaceVideo(this,e),ot.prefetch(this,e)},replaceVideo(e,t){const{thumb:n}=t,o=Ve.el("video",{preload:"none",loop:!0,muted:!0,poster:n.src||n.dataset.src,textContent:n.alt,className:n.className});for(var a of(o.setAttribute("muted","muted"),o.dataset.md5=n.dataset.md5,["height","width","maxHeight","maxWidth"]))o.style[a]=n.style[a];return o.src=t.url,Ve.replace(n,o),t.thumb=o,t.videoThumb=!0},prefetch(e,n){let o,a;const{isImage:r,isVideo:s,thumb:l,url:d}=n;if(n.isPrefetched||!r&&!s||e.isHidden||e.thread.isHidden)return;s?a="WEBM":(a=d.match(/\.([^.]+)$/)?.[1].toUpperCase(),"JPEG"===a&&(a="JPG"));const c=t[`Replace ${a}`]&&!/spoiler/.test(l.src||l.dataset.src);if(!c&&!ot.prefetchEnabled)return;if(Ve.hasClass(i,"catalog-mode"))return;if(![e,...e.clones].some((e=>i.contains(e.nodes.root))))return;if(n.isPrefetched=!0,n.videoThumb){for(o of e.clones)o.file.thumb.preload="auto";return l.preload="auto",
|
||||
void("gecko"===Ve.engine&&Ve.on(l,"loadeddata",(function(){return this.removeAttribute("poster")})))}const h=Ve.el(r?"img":"video");return s&&(h.preload="auto"),c&&r&&Ve.on(h,"load",(function(){for(o of e.clones)o.file.thumb.src=d;return l.src=d})),h.src=d},prefetchAll(e){for(var t of e.files)ot.prefetch(e,t)},toggle(){ot.prefetchEnabled=!ot.prefetchEnabled,this.classList.toggle("disabled",!ot.prefetchEnabled),ot.prefetchEnabled&&n.posts.forEach(ot.prefetchAll)},playVideos(){const e=Ve.id("qp")?.firstElementChild;return n.posts.forEach((function(t){for(t of[t,...t.clones])for(var n of t.files)if(n.videoThumb){var{thumb:o}=n;Ke.isNodeVisible(o)||t.nodes.root===e?o.play():o.pause()}}))}},at={init(){if(t["WEBM Metadata"]&&["index","thread"].includes(n.VIEW))return l.Post.push({name:"WEBM Metadata",cb:this.node})},node(){for(let n=0;n<this.files.length;n++){var e,t=this.files[n];if(/webm$/i.test(t.url))this.isClone?e=Ve(".webm-title",t.text):((e=Ve.el("span",{className:"webm-title"
|
||||
})).dataset.index=n,Ve.extend(e,{innerHTML:'<a href="javascript:;"></a>'}),Ve.add(t.text,[Ve.tn(" "),e])),1===e.children.length&&Ve.one(e.lastElementChild,"mouseover focus",at.load)}},load(){Ve.rmClass(this.parentNode,"error"),Ve.addClass(this.parentNode,"loading");const{index:e}=this.parentNode.dataset;return Ue.binary(ze.postFromNode(this).files[+e].url,(e=>{if(Ve.rmClass(this.parentNode,"loading"),null!=e){const t=at.parse(e),n=Ve.el("span",{textContent:t||""});return null==t&&Ve.addClass(this.parentNode,"not-found"),Ve.before(this,n),this.parentNode.tabIndex=0,a.activeElement===this&&this.parentNode.focus(),this.tabIndex=-1}return Ve.addClass(this.parentNode,"error"),Ve.one(this,"click",at.load)}),{Range:"bytes=0-9999"})},parse(e){const t=function(){let t=e[n++],o=0;for(;t<128>>o;)o++;for(t^=128>>o;o--&&n<e.length;)t=t<<8^e[n++];return t};for(var n=0;n<e.length;){var o=t(),a=t();if(15273===o){for(var i="";a--&&n<e.length;)i+=String.fromCharCode(e[n++])
|
||||
;return decodeURIComponent(escape(i))}[139690087,88713574].includes(o)||(n+=a)}return null}};const it={init(){if(["index","thread","archive"].includes(n.VIEW)&&t["Reveal Spoiler Thumbnails"])return l.Post.push({name:"Reveal Spoiler Thumbnails",cb:this.node})},node(){if(!this.isClone)for(var e of this.files)if(e.thumb&&e.isSpoiler){var{thumb:t}=e;t.removeAttribute("style"),t.style.maxHeight=t.style.maxWidth=this.isReply?"125px":"250px",t.src?t.src=e.thumbURL:t.dataset.src=e.thumbURL}}};var rt={init(){if(["index","thread","archive"].includes(n.VIEW)&&t.Linkify)return t["Comment Expansion"]&&X.callbacks.push(this.node),l.Post.push({name:"Linkify",cb:this.node}),Le.init()},node(){let e;if(this.isClone)return Le.events(this);if(!rt.regString.test(this.info.comment))return;for(e of u("a",this.nodes.comment))n.SITE.isLinkified?.(e)&&(Ve.addClass(e,"linkify"),O.useFaster&&O.fixLinks([e]),Le.process(e,this));const t=rt.process(this.nodes.comment);for(e of(O.useFaster&&O.fixLinks(t),
|
||||
t))Le.process(e,this)},process(e){let t;const n=/[^\s"]+/g,o=/[\s"]/,a=Ve.X(".//br|.//text()",e);let i=0;const r=[];for(;e=a.snapshotItem(i++);){var s,{data:l}=e;if(l&&"A"!==e.parentElement.nodeName)for(;s=n.exec(l);){var d,{index:c}=s,h=e,u=s[0];if((t=c+u.length)===l.length)for(n.lastIndex=0;d=a.snapshotItem(i++);){var p;if("BR"===d.nodeName||"P"===d.parentElement.nodeName&&!d.previousSibling){var g,f;if((g=u.match(/(https?:\/\/)?([a-z\d-]+\.)*[a-z\d-]+$/i))&&(f=a.snapshotItem(i)?.data?.match(/^(\.[a-z\d-]+)*\//i))&&0===(g[0]+f[0]).search(rt.regString))continue;break}if("A"===d.parentElement.nodeName&&!rt.regString.test(u))break;if(h=d,({data:l}=d),p=o.exec(l)){u+=l.slice(0,p.index),n.lastIndex=t=p.index,i--;break}({length:t}=l),u+=l}if(rt.regString.test(u)&&r.push(rt.makeRange(e,h,c,t)),!n.lastIndex||e!==h)break}}for(i=r.length;i--;)r[i]=rt.makeLink(r[i]);return r},
|
||||
regString:new RegExp('((https?|mailto|git|magnet|ftp|irc):([a-z\\d%/?])|([-a-z\\d]+[.])+(aero|asia|biz|cat|com|coop|dance|info|int|jobs|mobi|moe|museum|name|net|org|post|pro|tel|travel|xxx|xyz|edu|gov|mil|[a-z]{2})([:/]|(?![^\\s"]))|[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}\\.[\\d]{1,3}|[-\\w\\d.@]+@[a-z\\d.-]+\\.[a-z\\d])',"i"),makeRange(e,t,n,o){const a=document.createRange();return a.setStart(e,n),a.setEnd(t,o),a},makeLink(e){let t,n,o=e.toString(),a=o.search(rt.regString);if(a>0){for(o=o.slice(a);e.startOffset+a>=e.startContainer.data.length;)a--;a&&e.setStart(e.startContainer,e.startOffset+a)}for(a=0;/[)\]}>.,]/.test(t=o.charAt(o.length-(1+a)))&&(/[.,]/.test(t)||o.match(/[()\[\]{}<>]/g).length%2);)a++;if(a){for(o=o.slice(0,-a);e.endOffset-a<0;)a--;a&&e.setEnd(e.endContainer,e.endOffset-a)}/((mailto|magnet):|.+:\/\/)/.test(o)||(o=(/@/.test(o)?"mailto:":"http://")+o),(n=o.match(/^(https?:\/\/[^/]*%[0-9a-f]{2})(.*)$/i))&&(o=n[1].replace(/%([0-9a-f]{2})/gi,(function(e,t){
|
||||
return"25"===t?e:String.fromCharCode(parseInt(t,16))}))+n[2]);const i=Ve.el("a",{className:"linkify",rel:"noreferrer noopener",target:"_blank",href:o});return Ve.add(i,e.extractContents()),e.insertNode(i),i}};const st={init(){if("yotsuba"!==n.SITE.software||!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Archive Link"])return;const e={el:Ve.el("div",{textContent:"Archive"}),order:60,open:({ID:e,thread:t,board:n})=>!!Ze.to("thread",{postID:e,threadID:t.ID,boardID:n.ID}),subEntries:[]};for(var o of[["Post","post"],["Name","name"],["Tripcode","tripcode"],["Capcode","capcode"],["Subject","subject"],["Flag","country"],["Filename","filename"],["Image MD5","MD5"]])e.subEntries.push(this.createSubEntry(o[0],o[1]));return Q.menu.addEntry(e)},createSubEntry(e,t){const n=Ve.el("a",{textContent:e,target:"_blank"}),o="post"===t?function({ID:e,thread:t,board:o}){return n.href=Ze.to("thread",{postID:e,threadID:t.ID,boardID:o.ID}),!0}:function(e){
|
||||
const o="country"===t&&e.info.flagCodeTroll?"troll_country":t,a="country"===t?e.info.flagCode||e.info.flagCodeTroll?.toLowerCase():We.values(t,e)[0];return!!a&&(n.href=Ze.to("search",{boardID:e.board.ID,type:o,value:a,isSearch:!0}),!0)};return{el:n,open:o}}};var lt={init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Copy Text Link"])return;const e=Ve.el("a",{className:"copy-text-link",href:"javascript:;",textContent:"Copy Text"});return Ve.on(e,"click",lt.copy),Q.menu.addEntry({el:e,order:12,open:e=>(lt.text=(e.origin||e).commentOrig(),!0)})},copy(){const e=Ve.el("textarea",{className:"copy-text-element",value:lt.text});Ve.add(a.body,e),e.select();try{a.execCommand("copy")}catch(e){}return Ve.rm(e)}},dt={auto:[m(),m()],init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Delete Link"])return;const e=Ve.el("div",{className:"delete-link",textContent:"Delete"}),o=Ve.el("a",{className:"delete-post",href:"javascript:;"}),a=Ve.el("a",{className:"delete-file",
|
||||
href:"javascript:;"});this.nodes={menu:e.firstChild,links:[o,a]};const i={el:o,open:()=>(o.textContent=dt.linkText(!1),Ve.on(o,"click",dt.toggle),!0)},r={el:a,open:({file:e})=>!(!e||e.isDead)&&(a.textContent=dt.linkText(!0),Ve.on(a,"click",dt.toggle),!0)};return Q.menu.addEntry({el:e,order:40,open:e=>!e.isDead&&(dt.post=e,dt.nodes.menu.textContent=dt.menuText(),dt.cooldown.start(e),!0),subEntries:[i,r]})},menuText(){let e;return(e=dt.cooldown.seconds[dt.post.fullID])?`Delete (${e})`:"Delete"},linkText(e){let t=e?"File":"Post";return dt.auto[+e][dt.post.fullID]&&(t=`Deleting ${t.toLowerCase()}...`),t},toggle(){const{post:e}=dt,t=Ve.hasClass(this,"delete-file"),n=dt.auto[+t];if(n[e.fullID]?delete n[e.fullID]:n[e.fullID]=!0,this.textContent=dt.linkText(t),!dt.cooldown.seconds[e.fullID])return dt.delete(e,t)},delete(e,t){const o=dt.nodes.links[+t];delete dt.auto[+t][e.fullID],e.fullID===dt.post.fullID&&Ve.off(o,"click",dt.toggle);const a={mode:"usrdel",onlyimgdel:t,
|
||||
pwd:$e.persona.getPassword()};return a[+e.ID]="delete",Ve.ajax(Ve.id("delform").action.replace(`/${n.BOARD}/`,`/${e.board}/`),{responseType:"document",withCredentials:!0,onloadend(){return dt.load(o,e,t,this.response)},form:Ve.formData(a)})},load(e,n,o,a){let i;if(!a)return new Xe("warning","Connection error, please retry.",20),void(n.fullID===dt.post.fullID&&Ve.on(e,"click",dt.toggle));if(e.textContent=dt.linkText(o),"4chan - Banned"===a.title){const e=Ve.el("span",{innerHTML:'You can't delete posts because you are <a href="//www.4chan.org/banned" target="_blank">banned</a>.'});return new Xe("warning",e,20)}if(i=a.getElementById("errmsg")){if(new Xe("warning",i.textContent,20),n.fullID===dt.post.fullID&&Ve.on(e,"click",dt.toggle),$e.cooldown.data&&t.Cooldown&&/\bwait\b/i.test(i.textContent))return dt.cooldown.start(n,5),dt.auto[+o][n.fullID]=!0,dt.nodes.links[+o].textContent=dt.linkText(o)}else if(o||$e.cooldown.delete(n),"Updating index..."===a.title&&(n.origin||n).kill(o),
|
||||
n.fullID===dt.post.fullID)return e.textContent="Deleted"},cooldown:{seconds:m(),start(e,t){if(null==dt.cooldown.seconds[e.fullID])return null==t&&(t=$e.cooldown.secondsDeletion(e)),t>0?(dt.cooldown.seconds[e.fullID]=t,dt.cooldown.count(e)):void 0},count(e){if(e.fullID===dt.post.fullID&&(dt.nodes.menu.textContent=dt.menuText()),dt.cooldown.seconds[e.fullID]>0&&t.Cooldown)dt.cooldown.seconds[e.fullID]--,setTimeout(dt.cooldown.count,1e3,e);else for(var n of(delete dt.cooldown.seconds[e.fullID],[!1,!0]))dt.auto[+n][e.fullID]&&dt.delete(e,n)}}};const ct={init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Download Link"])return;const e=Ve.el("a",{className:"download-link",textContent:"Download file"});return Ve.on(e,"click",j.download),Q.menu.addEntry({el:e,order:100,open:({file:t})=>!!t&&(e.href=t.url,e.download=t.name,!0)})}};var ht={init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Report Link"])return;const e=Ve.el("a",{className:"report-link",href:"javascript:;",
|
||||
textContent:"Report"});return Ve.on(e,"click",ht.report),Q.menu.addEntry({el:e,order:10,open:e=>(ht.url=`//sys.${location.hostname.split(".")[1]}.org/${e.board}/imgboard.php?mode=report&no=${e}`,a.cookie.indexOf("pass_enabled=1")>=0?ht.dims="width=350,height=275":ht.dims="width=400,height=550",!0)})},report(){const{url:e,dims:t}=ht,n=Date.now(),o=`toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,${t}`;return window.open(e,n,o)}},ut={init(){if(t["Disable Autoplaying Sounds"]){for(var e of(Ve.addClass(i,"anti-autoplay"),u("audio[autoplay]",i)))this.stop(e);return window.addEventListener("loadstart",(e=>this.stop(e.target)),!0),l.Post.push({name:"Disable Autoplaying Sounds",cb:this.node}),Ve.ready((()=>this.process(d.body)))}},stop(e){if(e.autoplay&&(e.pause(),e.autoplay=!1,!e.controls))return e.controls=!0,Ve.addClass(e,"controls-added")},node(){return ut.process(this.nodes.comment)},process(e){
|
||||
for(var t of u('iframe[src*="youtube"][src*="autoplay=1"]',e))ut.processVideo(t,"src");for(var n of u('object[data*="youtube"][data*="autoplay=1"]',e))ut.processVideo(n,"data")},processVideo:(e,t)=>(e[t]=e[t].replace(/\?autoplay=1&?/,"?").replace("&autoplay=1",""),"none"===window.getComputedStyle(e).display&&(e.style.display="block"),Ve.addClass(e,"autoplay-removed"))},pt={init(){if(t["Custom Board Titles"]&&(this.db=new y("customTitles",null,!0)),Ve.asap((()=>a.body),(()=>Ve.asap((()=>Ve("hr")),pt.ready))),"f"!==n.BOARD.ID)return Ot.ready((()=>Ve.queueTask(pt.load)))},ready(){const e=Ve(".boardBanner"),{children:o}=e;if("thread"===n.VIEW&&t["Remove Thread Excerpt"]&&pt.setTitle(o[1].textContent),o[0].title="Click to change",Ve.on(o[0],"click",pt.cb.toggle),t["Custom Board Titles"]&&(pt.custom(o[1]),o[2]))return pt.custom(o[2])},load(){const e=Ve.id("bannerCnt");if(!e.firstChild){const t=Ve.el("img",{alt:"4chan",src:"//s.4cdn.org/image/title/"+e.dataset.src});return Ve.add(e,t)}},
|
||||
setTitle:e=>null!=ee.title?(ee.title=e,ee.update()):a.title=e,cb:{toggle(){pt.choices?.length||(pt.choices=t.knownBanners.split(",").slice());const e=Math.floor(pt.choices.length*Math.random()),n=pt.choices.splice(e,1);return Ve("img",this.parentNode).src=`//s.4cdn.org/image/title/${n}`},click(e){if(e.ctrlKey||e.metaKey){for(var t of(null==pt.original[this.className]&&(pt.original[this.className]=this.cloneNode(!0)),this.contentEditable=!0,u("br",this)))Ve.replace(t,Ve.tn("\n"));return this.focus()}},keydown(e){if(e.stopPropagation(),!e.shiftKey&&13===e.keyCode)return this.blur()},blur(){for(var e of u("br",this))Ve.replace(e,Ve.tn("\n"));return(this.textContent=this.textContent.replace(/\n*$/,""))?(this.contentEditable=!1,pt.db.set({boardID:n.BOARD.ID,threadID:this.className,val:{title:this.textContent,orig:pt.original[this.className].textContent}})):(Ve.rmAll(this),Ve.add(this,[...pt.original[this.className].cloneNode(!0).childNodes]),pt.db.delete({boardID:n.BOARD.ID,
|
||||
threadID:this.className}))}},original:m(),custom(e){let o;const{className:a}=e;for(var i of(e.title=`Ctrl/⌘+click to edit board ${a.slice(5).toLowerCase()}`,e.spellcheck=!1,["click","keydown","blur"]))Ve.on(e,i,pt.cb[i]);if(o=pt.db.get({boardID:n.BOARD.ID,threadID:a}))return t["Persistent Custom Board Titles"]||o.orig===e.textContent?(pt.original[a]=e.cloneNode(!0),e.textContent=o.title):pt.db.delete({boardID:n.BOARD.ID,threadID:a})}},gt={init(){if("f"===n.BOARD.ID&&t["Enable Native Flash Embedding"])return Ve.ready(gt.initReady)},initReady:()=>Ve.hasStorage?Ve.global((function(){if(JSON.parse(localStorage["4chan-settings"]||"{}").disableAll)return window.SWFEmbed.init()})):("thread"===n.VIEW&&Ve.global((()=>window.Main.tid=location.pathname.split(/\/+/)[3])),Ve.global((()=>window.SWFEmbed.init())))},ft={init(){if("yotsuba"===n.SITE.software&&["index","thread","archive"].includes(n.VIEW))return Y.ready(this.initBoard),Ot.ready(this.initReady)},initBoard(){
|
||||
if(n.BOARD.config.code_tags&&(Ve.on(window,"prettyprint:cb",(function(e){let t,o;if((t=n.posts.get(e.detail.ID))&&(o=u(".prettyprint",t.nodes.comment)[+e.detail.i]))return Ve.hasClass(o,"prettyprinted")?void 0:(o.innerHTML=e.detail.html,Ve.addClass(o,"prettyprinted"))})),Ve.global((()=>window.addEventListener("prettyprint",(e=>window.dispatchEvent(new CustomEvent("prettyprint:cb",{detail:{ID:e.detail.ID,i:e.detail.i,html:window.prettyPrintOne(e.detail.html)}}))),!1))),l.Post.push({name:"Parse [code] tags",cb:ft.code}),n.posts.forEach((function(e){if(e.callbacksExecuted)return l.Post.execute(e,["Parse [code] tags"],!0)})),X.callbacks.push(ft.code)),n.BOARD.config.math_tags)return Ve.global((()=>window.addEventListener("mathjax",(function(e){return window.MathJax?window.MathJax.Hub.Queue(["Typeset",window.MathJax.Hub,e.target]):(document.querySelector('script[src^="//cdn.mathjax.org/"]')||(window.loadMathJax(),window.loadMathJax=function(){}),
|
||||
e.target.classList.contains("postMessage")?void 0:document.querySelector('script[src^="//cdn.mathjax.org/"]').addEventListener("load",(()=>window.MathJax.Hub.Queue(["Typeset",window.MathJax.Hub,e.target])),!1))}),!1))),l.Post.push({name:"Parse [math] tags",cb:ft.math}),n.posts.forEach((function(e){if(e.callbacksExecuted)return l.Post.execute(e,["Parse [math] tags"],!0)})),X.callbacks.push(ft.math)},initReady:()=>Ve.global((function(){for(var e of(window.clickable_ids=!1,document.querySelectorAll(".posteruid, .capcode")))e.removeEventListener("click",window.idClick,!1)})),code(){if(!this.isClone)return Ve.ready((()=>{const e=u(".prettyprint",this.nodes.comment);for(let n=0;n<e.length;n++){var t=e[n];Ve.hasClass(t,"prettyprinted")||Ve.event("prettyprint",{ID:this.fullID,i:n,html:t.innerHTML},window)}}))},math(){let e;if(/\[(math|eqn)\]/.test(this.nodes.comment.textContent)){if((e=u("wbr",this.nodes.comment)).length){for(var t of e)Ve.rm(t);this.nodes.comment.normalize()}var n=()=>{
|
||||
if(i.contains(this.nodes.comment))return Ve.off(a,"PostsInserted",n),Ve.event("mathjax",null,this.nodes.comment)};return Ve.on(a,"PostsInserted",n),n()}}},mt={init(){if(["index","thread"].includes(n.VIEW)&&t["Color User IDs"])return this.ids=m(),this.ids.Heaven=[0,0,0,"#fff"],l.Post.push({name:"Color User IDs",cb:this.node})},node(){let e,t;if(this.isClone||!(t=this.info.uniqueID)||!(e=this.nodes.uniqueID))return;const n=mt.ids[t]||mt.compute(t),{style:o}=e;return o.color=n[3],o.backgroundColor=`rgb(${n[0]},${n[1]},${n[2]})`,Ve.addClass(e,"painted")},compute(e){const t=n.SITE.uidColor?n.SITE.uidColor(e):parseInt(e,16),o=[t>>16&255,t>>8&255,255&t];return o.push(Ve.luma(o)>125?"#000":"#fff"),this.ids[e]=o}},bt={init(){if(["index","thread"].includes(n.VIEW))return l.Post.push({name:"Highlight by User ID",cb:this.node})},uniqueID:null,node(){if(this.nodes.uniqueIDRoot&&Ve.on(this.nodes.uniqueIDRoot,"click",bt.click(this)),
|
||||
this.nodes.capcode&&Ve.on(this.nodes.capcode,"click",bt.click(this)),!this.isClone)return bt.set(this)},set(e){const t=(e.info.uniqueID||e.info.capcode)===bt.uniqueID;return Ve[t?"addClass":"rmClass"](e.nodes.post,"highlight")},click:e=>function(){const t=e.info.uniqueID||e.info.capcode;return bt.uniqueID=bt.uniqueID===t?null:t,n.posts.forEach(bt.set)}},At={init(){if("thread"===n.VIEW&&t["Count Posts by ID"])return l.Thread.push({name:"Count Posts by ID",cb(){return At.thread=this}}),l.Post.push({name:"Count Posts by ID",cb:this.node})},node(){if(this.nodes.uniqueID&&this.thread===At.thread)return Ve.on(this.nodes.uniqueID,"mouseover",At.count)},count(){const{uniqueID:e}=ze.postFromNode(this).info;let t=0;return At.thread.posts.forEach((function(n){if(n.info.uniqueID===e)return t++})),this.title=`${t} post${1===t?"":"s"} by this ID`}},vt={init(){if("yotsuba"===n.SITE.software&&["index","thread"].includes(n.VIEW))return l.Post.push({name:"Mod Contact Links",cb:this.node})},node(){let e
|
||||
;if(this.isClone||!Ve.hasOwn(vt.specific,this.info.capcode))return;const t=Ve.el("span",{className:"contact-links brackets-wrap"});if(Ve.extend(t,vt.template(this.info.capcode)),Ve.after(this.nodes.capcode,t),(e=this.info.comment.match(/This thread was moved to >>>\/(\w+)\//))&&Ve.hasOwn(vt.moveNote,e[1])){const t=Ve.el("div",{className:"move-note"});return Ve.extend(t,vt.moveNote[e[1]]),Ve.add(this.nodes.post,t)}},template:e=>({innerHTML:'<a href="https://www.4chan.org/feedback" target="_blank">feedback</a>'+vt.specific[e]().innerHTML}),specific:{Mod:()=>({innerHTML:' <a href="https://www.4chan-x.net/4chan-irc.html" target="_blank">IRC</a>'}),Manager:()=>vt.specific.Mod(),Developer:()=>({innerHTML:' <a href="https://github.com/4chan" target="_blank">github</a>'}),Admin:()=>({innerHTML:' <a href="https://twitter.com/hiroyuki_ni" target="_blank">twitter</a>'})},moveNote:{qa:{
|
||||
innerHTML:'Moving a thread to /qa/ does not imply mods will read it. If you wish to contact mods, use <a href="https://www.4chan.org/feedback" target="_blank">feedback</a><span class="invisible"> (https://www.4chan.org/feedback)</span> or <a href="https://www.4chan-x.net/4chan-irc.html" target="_blank">IRC</a><span class="invisible"> (https://www.4chan-x.net/4chan-irc.html)</span>.'}}};const wt={init(){if(!t["Normalize URL"])return;let e=location.pathname.split(/\/+/);if("yotsuba"===n.SITE.software)switch(n.VIEW){case"thread":e[2]="thread",e=e.slice(0,4);break;case"index":e=e.slice(0,3)}return e=e.join("/"),location.pathname!==e?history.replaceState(history.state,"",`${location.protocol}//${location.host}${e}${location.hash}`):void 0}};var xt={init(){if(t["Unique ID and Capcode Navigation"]&&["index","thread"].includes(n.VIEW))return this.buttons=this.makeButtons(),l.Post.push({name:"Post Jumper",cb:this.node})},node(){
|
||||
if(this.isClone)for(var e of u(".postJumper",this.nodes.info))xt.addListeners(e);else if(this.nodes.uniqueIDRoot&&xt.addButtons(this,"uniqueID"),this.nodes.capcode)return xt.addButtons(this,"capcode")},addButtons(e,t){const n=e.info[t],o=xt.buttons.cloneNode(!0);return Ve.extend(o.dataset,{type:t,value:n}),Ve.after(e.nodes[t+("capcode"===t?"":"Root")],o),xt.addListeners(o)},addListeners:e=>(Ve.on(e.firstChild,"click",xt.buttonClick),Ve.on(e.lastChild,"click",xt.buttonClick)),buttonClick(){let e;const t=Ve.hasClass(this,"prev")?-1:1;if(e=xt.find(this.parentNode,t))return xt.scroll(this.parentNode,e)},find(e,t){const{type:n,value:o}=e.dataset,a=`span[contains(@class,"postJumper") and @data-value="${o}" and @data-type="${n}"]`,i=t<0?"preceding":"following";let r=e;for(;r=Ve.x(`${i}::${a}`,r);)if(r.getBoundingClientRect().height)return r;if((r=Ve.x(`(//${a})[${t<0?"last()":"1"}]`))&&r.getBoundingClientRect().height)return r
|
||||
;for(;(r=Ve.x(`${i}::${a}`,r))&&r!==e;)if(r.getBoundingClientRect().height)return r;return null},makeButtons(){const e=Ve.el("span",{className:"postJumper"});return Ve.extend(e,{innerHTML:'<a href="javascript:;" class="'+o("prev")+'">'+o("⏫")+'</a><a href="javascript:;" class="'+o("next")+'">'+o("⏬")+"</a>"}),e},scroll(e,t){const n=e.getBoundingClientRect().top,o=t.getBoundingClientRect().top;return window.scrollBy(0,o-n)}};const yt={init(){let e;if("yotsuba"===n.SITE.software&&"qa"===n.BOARD.ID){const t={innerHTML:'Stay in touch with your <a href="https://www.4chan-x.net/qa_friends.html" target="_blank" rel="noopener">/qa/ friends</a>!'};e=Ve.el("div",{className:"fcx-announcement"},t),Ve.onExists(i,".boardBanner",(t=>Ve.after(t,e)))}if("samachan.org"in t.siteProperties&&!t.PSAseen.includes("samachan"))return e=Ve.el("span",{
|
||||
innerHTML:'<a href="https://sushigirl.us/yakuza/res/776.html" target="_blank" rel="noopener">Looking for a new home?<br>Some former Samachan users are regrouping on SushiChan.</a><br>(a message from 4chan X)'}),Ot.ready((function(){return new Xe("info",e),t.PSAseen.push("samachan"),Ve.set("PSAseen",t.PSAseen)}))}};var kt={init(){if(t["Announcement Hiding"]&&n.SITE.selectors.psa)return Ve.addClass(i,"hide-announcement"),Ve.onExists(i,n.SITE.selectors.psa,this.setup),Ve.ready((function(){if(!Ve(n.SITE.selectors.psa))return Ve.rmClass(i,"hide-announcement")}))},setup(e){let o,a;kt.psa=e,kt.text=e.dataset.utc??e.innerHTML,n.SITE.selectors.psaTop&&(a=Ve(n.SITE.selectors.psaTop)?.previousElementSibling)&&"HR"===a.nodeName&&(kt.hr=a),kt.content=Ve.el("div");const r={el:Ve.el("a",{textContent:"Show announcement",className:"show-announcement",href:"javascript:;"}),order:50,open:()=>e.hidden};return Ke.menu.addEntry(r),Ve.on(r.el,"click",kt.toggle),kt.btn=o=Ve.el("a",{
|
||||
title:"Mark announcement as read and hide.",className:"hide-announcement-button",href:"javascript:;",textContent:"➖︎"}),Ve.on(o,"click",kt.toggle),"HR"===e.firstChild?.tagName?Ve.after(e.firstChild,o):Ve.prepend(e,o),kt.sync(t.hiddenPSAList),Ve.rmClass(i,"hide-announcement"),Ve.sync("hiddenPSAList",kt.sync)},toggle(){const e=Ve.hasClass(this,"hide-announcement-button"),o=function(t){return e?t[n.SITE.ID]=kt.text:delete t[n.SITE.ID]};return o(t.hiddenPSAList),kt.sync(t.hiddenPSAList),Ve.get("hiddenPSAList",t.hiddenPSAList,(function({hiddenPSAList:e}){return o(e),Ve.set("hiddenPSAList",e)}))},sync(e){const{psa:t,content:o}=kt;t.hidden=e[n.SITE.ID]===kt.text,t.hidden?Ve.add(o,[...t.childNodes]):Ve.add(t,[...o.childNodes]),kt.hr&&(kt.hr.hidden=t.hidden)}},It={init(){if(t["Reveal Spoilers"]&&Ve.addClass(i,"reveal-spoilers"),t["Remove Spoilers"])return l.Post.push({name:"Reveal Spoilers",cb:this.node}),"archive"===n.VIEW?Ve.ready((()=>It.unspoiler(Ve.id("arc-list")))):void 0},node(){
|
||||
return It.unspoiler(this.nodes.comment)},unspoiler(e){const t=u(n.SITE.selectors.spoiler,e);for(var o of t){var a=Ve.el("span",{className:"removed-spoiler"});Ve.replace(o,a),Ve.add(a,[...o.childNodes])}}},Ct={init(){if("index"===n.VIEW&&t["Open Threads in New Tab"])return l.Post.push({name:"Thread Links",cb:this.node}),l.CatalogThread.push({name:"Thread Links",cb:this.catalogNode})},node(){if(!this.isReply&&!this.isClone)return Ct.process(this.nodes.reply)},catalogNode(){return Ct.process(this.nodes.thumb.parentNode)},process:e=>e.target="_blank"};const Dt={init(){if("tinyboard"===n.SITE.software)return"thread"===n.VIEW?Ot.ready((()=>Ve.global((function(){let e,{boardID:t,threadID:n}=document.currentScript.dataset;n=+n;const o=document.querySelector('form[name="post"]');window.$(document).ajaxComplete((function(e,i,r){let s;if(r.url!==o.action)return;if(!(s=+i.responseJSON?.id))return;const l={boardID:t,threadID:n,postID:s};try{const{redirect:e,noko:t}=i.responseJSON
|
||||
;!e||null==a||a||t||(l.redirect=e)}catch(e){}return e=new CustomEvent("QRPostSuccessful",{bubbles:!0,detail:l}),document.dispatchEvent(e)}));var a=window.tb_settings?.ajax?.always_noko_replies;return((e=window.tb_settings||(window.tb_settings={})).ajax||(e.ajax={})).always_noko_replies=!0}),{boardID:n.BOARD.ID,threadID:n.THREADID}))):void 0}};var Et={init(){if("yotsuba"===n.SITE.software&&"thread"===n.VIEW&&t["Mark New IPs"])return l.Thread.push({name:"Mark New IPs",cb:this.node})},node(){return Et.ipCount=this.ipCount,Et.postCount=this.posts.keys.length,Ve.on(a,"ThreadUpdate",Et.onUpdate)},onUpdate(e){let t;const{ipCount:o,postCount:a,newPosts:i,deletedPosts:r}=e.detail;if(null!=o){switch(o-Et.ipCount){case a-Et.postCount+r.length:var s=Et.ipCount;for(t of i)Et.markNew(n.posts.get(t),++s);break;case-r.length:for(t of i)Et.markOld(n.posts.get(t))}return Et.ipCount=o,Et.postCount=a}},markNew(e,t){const n=Math.floor(t/10)%10==1?"th":["st","nd","rd"][t%10-1]||"th",o=Ve.el("span",{
|
||||
className:"ip-counter",textContent:`(${t})`});return e.nodes.nameBlock.title=`This is the ${t}${n} IP in the thread.`,Ve.add(e.nodes.nameBlock,[Ve.tn(" "),o]),Ve.addClass(e.nodes.root,"new-ip")},markOld:e=>(e.nodes.nameBlock.title="Not the first post from this IP.",Ve.addClass(e.nodes.root,"old-ip"))},St={postCount:0,fileCount:0,postIndex:0,init(){let e;if("thread"!==n.VIEW||!t["Thread Stats"])return;t["Page Count in Stats"]&&(this[n.SITE.isPrunedByAge?.(n.BOARD)?"showPurgePos":"showPage"]=!0);const r={innerHTML:'<span id="post-count">?</span> / <span id="file-count">?</span>'+(t["IP Count in Stats"]&&n.SITE.hasIPCount?' / <span id="ip-count">?</span>':"")+(t["Page Count in Stats"]?' / <span id="page-count">?</span>':"")};let s="Posts / Files";return t["IP Count in Stats"]&&n.SITE.hasIPCount&&(s+=" / IPs"),t["Page Count in Stats"]&&(s+=this.showPurgePos?" / Purge Position":" / Page"),t["Updater and Stats in Header"]?(this.dialog=e=Ve.el("span",{id:"thread-stats",title:s}),
|
||||
Ve.extend(e,r),Ke.addShortcut("stats",e,200)):(this.dialog=e=L.dialog("thread-stats",{innerHTML:'<div class="move" title="'+o(s)+'">'+r.innerHTML+"</div>"}),Ve.addClass(i,"float"),Ve.ready((()=>Ve.add(a.body,e)))),this.postCountEl=Ve("#post-count",e),this.fileCountEl=Ve("#file-count",e),this.ipCountEl=Ve("#ip-count",e),this.pageCountEl=Ve("#page-count",e),this.pageCountEl&&Ve.on(this.pageCountEl,"click",St.fetchPage),l.Thread.push({name:"Thread Stats",cb:this.node})},node(){return St.thread=this,St.count(),St.update(),St.fetchPage(),Ve.on(a,"PostsInserted",(()=>Ve.queueTask(St.onPostsInserted))),Ve.on(a,"ThreadUpdate",St.onUpdate)},count(){const{posts:e}=St.thread,t=e.keys.length;for(let o=St.postIndex,a=t;o<a;o++){var n=e.get(e.keys[o]);n.isFetchedQuote||(St.postCount++,St.fileCount+=n.files.length)}return St.postIndex=t},onUpdate(e){if(e.detail[404])return;const{postCount:t,fileCount:n}=e.detail;return Ve.extend(St,{postCount:t,fileCount:n}),St.postIndex=St.thread.posts.keys.length,
|
||||
St.update(),St.showPage&&"1"!==St.pageCountEl.textContent?St.fetchPage():void 0},onPostsInserted(){if(!(St.thread.posts.keys.length<=St.postIndex))return St.count(),St.update(),St.showPage&&"1"!==St.pageCountEl.textContent?St.fetchPage():void 0},update(){const{thread:e,postCountEl:t,fileCountEl:n,ipCountEl:o}=St;return t.textContent=St.postCount,n.textContent=St.fileCount,o.textContent=e.ipCount??"?",t.classList.toggle("warning",e.postLimit&&!e.isSticky),n.classList.toggle("warning",e.fileLimit&&!e.isSticky)},fetchPage(){if(St.pageCountEl)return clearTimeout(St.timeout),St.thread.isDead?(St.pageCountEl.textContent="Dead",void Ve.addClass(St.pageCountEl,"warning")):(St.timeout=setTimeout(St.fetchPage,12e4),Ve.whenModified(n.SITE.urls.threadsListJSON(St.thread),"ThreadStats",St.onThreadsLoad))},onThreadsLoad(){if(200===this.status){let e,t;if(St.showPurgePos){let n=1;for(e of this.response)for(t of e.threads)t.no<St.thread.ID&&n++;return St.pageCountEl.textContent=n,
|
||||
St.pageCountEl.classList.toggle("warning",1===n)}{let n,o=n=0;for(e of this.response)n+=e.threads.length;for(let a=0;a<this.response.length;a++)for(t of(e=this.response[a],e.threads)){if(t.no===St.thread.ID)return St.pageCountEl.textContent=a+1,St.pageCountEl.classList.toggle("warning",o>=n-this.response[0].threads.length),St.lastPageUpdate=new Date(t.last_modified*b),void St.retry();o++}}}else if(304===this.status)return St.retry()},retry(){if(!(!St.showPage||"1"===St.pageCountEl.textContent||n.SITE.threadModTimeIgnoresSage||St.thread.posts.get(St.thread.lastPost).info.date<=St.lastPageUpdate))return clearTimeout(St.timeout),St.timeout=setTimeout(St.fetchPage,5e3)}};const Tt={init(){if("yotsuba"===n.SITE.software&&t["Pass Link"])return Ot.ready(this.ready)},ready(){let e;if(!(e=Ve.id("styleSelector")))return;const t=Ve.el("span",{className:"brackets-wrap pass-link-container"});return Ve.extend(t,{innerHTML:'<a href="javascript:;">4chan Pass</a>'}),
|
||||
Ve.on(t.firstElementChild,"click",(()=>window.open(`//sys.${location.hostname.split(".")[1]}.org/auth`,Date.now(),"width=500,height=280,toolbar=0"))),Ve.before(e.previousSibling,[t,Ve.tn(" ")])}};var Rt={init(){if(["index","thread"].includes(n.VIEW)&&t["Quote Inlining"])return t["Comment Expansion"]&&X.callbacks.push(this.node),l.Post.push({name:"Quote Inlining",cb:this.node})},node(){const{process:e}=Rt,{isClone:t}=this;for(var n of this.nodes.quotelinks.concat([...this.nodes.backlinks],this.nodes.archivelinks))e(n,t)},process:(e,n)=>(t["Quote Hash Navigation"]&&(n||Ve.after(e,Rt.qiQuote(e,Ve.hasClass(e,"filtered")))),Ve.on(e,"click",Rt.toggle)),qiQuote(e,t){let n="hashlink";return t&&(n+=" filtered"),Ve.el("a",{className:n,textContent:"#",href:e.href})},toggle(e){if(Ve.modifiedClick(e))return;const{boardID:o,threadID:a,postID:r}=ze.postDataFromLink(this);if(t["Inline Cross-thread Quotes Only"]&&"thread"===n.VIEW&&n.posts.get(`${o}.${r}`)?.nodes.root.offsetParent)return
|
||||
;if(Ve.hasClass(i,"catalog-mode"))return;e.preventDefault();const s=ze.postFromNode(this),{context:l}=s;if(Ve.hasClass(this,"inlined"))Rt.rm(this,o,a,r,l);else{if(Ve.x(`ancestor::div[@data-full-i-d='${o}.${r}']`,this))return;Rt.add(this,o,a,r,l,s)}return this.classList.toggle("inlined")},findRoot:(e,t)=>t?Ve.x('ancestor::*[parent::*[contains(@class,"post")]][1]',e):Ve.x("ancestor-or-self::*[parent::blockquote][1]",e),add(e,o,a,i,r,s){let l;const d=Ve.hasClass(e,"backlink"),c=Ve.el("div",{className:"inline"});c.dataset.fullID=`${o}.${i}`;const h=Rt.findRoot(e,d);Ve.after(h,c);const u=Ve.x('ancestor::*[contains(@class,"postContainer")][1]',h);if(Ve.addClass(u,"hasInline"),new de(o,a,i,c,s),(l=n.posts.get(`${o}.${i}`))&&r.thread===l.thread&&(d&&t["Forward Hiding"]&&(Ve.addClass(l.nodes.root,"forwarded"),l.forwarded++||(l.forwarded=1)),ee.posts))return ee.readSinglePost(l)},rm(e,o,a,i,r){let s,l;const d=Ve.hasClass(e,"backlink");let c=Rt.findRoot(e,d)
|
||||
;c=Ve.x(`following-sibling::div[@data-full-i-d='${o}.${i}'][1]`,c);const h=Ve.x('ancestor::*[contains(@class,"postContainer")][1]',c),{parentNode:u}=c;if(Ve.rm(c),Ve.event("PostsRemoved",null,u),Ve(".inline",h)||Ve.rmClass(h,"hasInline"),!(s=c.firstElementChild))return;const p=n.posts.get(`${o}.${i}`);for(p.rmClone(s.dataset.clone),t["Forward Hiding"]&&d&&r.thread===n.threads.get(`${o}.${a}`)&&!--p.forwarded&&(delete p.forwarded,Ve.rmClass(p.nodes.root,"forwarded"));l=Ve(".inlined",s);)({boardID:o,threadID:a,postID:i}=ze.postDataFromLink(l)),Rt.rm(l,o,a,i,r),Ve.rmClass(l,"inlined")}},Bt={containers:m(),init(){if(["index","thread"].includes(n.VIEW)&&t["Quote Backlinks"])return(this.bottomBacklinks=t["Bottom Backlinks"])&&Ve.addClass(i,"bottom-backlinks"),l.Post.push({name:"Quote Backlinking Part 1",cb:this.firstNode}),l.Post.push({name:"Quote Backlinking Part 2",cb:this.secondNode})},firstNode(){if(this.isClone||!this.quotes.length||this.isRebuilt)return
|
||||
;const e=t["Mark Quotes of You"]&&_.isYou(this),o=Ve.el("a",{href:n.SITE.Build.postURL(this.board.ID,this.thread.ID,this.ID),className:this.isHidden?"filtered backlink":"backlink",textContent:t.backlink.replace(/%(?:id|%)/g,(e=>({"%id":this.ID,"%%":"%"}[e])))});for(var a of(e&&Ve.add(o,_.mark.cloneNode(!0)),this.quotes)){var i,r=[Bt.getContainer(a)];if((i=n.posts.get(a))&&i.nodes.backlinkContainer)for(var s of i.clones)r.push(s.nodes.backlinkContainer);for(var l of r){var d=o.cloneNode(!0),c=l.firstChild?[Ve.tn(" "),d]:[d];if(t["Quote Previewing"]&&Ve.on(d,"mouseover",ce.mouseover),t["Quote Inlining"]&&(Ve.on(d,"click",Rt.toggle),t["Quote Hash Navigation"])){var h=Rt.qiQuote(d,Ve.hasClass(d,"filtered"));c.push(h)}Ve.add(l,c)}}},secondNode(){if(this.isClone&&(this.origin.isReply||t["OP Backlinks"]))return void(this.nodes.backlinkContainer=Ve(".container",this.nodes.post));if(!this.isReply&&!t["OP Backlinks"])return;const e=Bt.getContainer(this.fullID)
|
||||
;return this.nodes.backlinkContainer=e,Bt.bottomBacklinks?Ve.add(this.nodes.post,e):Ve.add(this.nodes.info,e)},getContainer(e){return this.containers[e]||(this.containers[e]=Ve.el("span",{className:"container"}))}},Pt={init(){if(["index","thread"].includes(n.VIEW)&&t["Mark Cross-thread Quotes"])return t["Comment Expansion"]&&X.callbacks.push(this.node),this.mark=Ve.el("span",{textContent:" (Cross-thread)",className:"qmark-ct"}),l.Post.push({name:"Mark Cross-thread Quotes",cb:this.node})},node(){if(this.isClone&&this.thread===this.context.thread)return;const{board:e,thread:t}=this.context;for(var n of this.nodes.quotelinks){var{boardID:o,threadID:a}=ze.postDataFromLink(n);a&&(this.isClone&&Ve.rm(Ve(".qmark-ct",n)),o===e.ID&&a!==t.ID&&Ve.add(n,Pt.mark.cloneNode(!0)))}}},Mt={init(){if(["index","thread"].includes(n.VIEW)&&t["Mark OP Quotes"])return t["Comment Expansion"]&&X.callbacks.push(this.node),this.mark=Ve.el("span",{textContent:" (OP)",className:"qmark-op"}),l.Post.push({
|
||||
name:"Mark OP Quotes",cb:this.node})},node(){let e,t,n;if(this.isClone&&this.thread===this.context.thread)return;if(!(n=this.quotes).length)return;const{quotelinks:o}=this.nodes;if(this.isClone&&n.includes(this.thread.fullID))for(e=0;t=o[e++];)Ve.rm(Ve(".qmark-op",t));const{fullID:a}=this.context.thread;if(n.includes(a))for(e=0;t=o[e++];){var{boardID:i,postID:r}=ze.postDataFromLink(t);`${i}.${r}`===a&&Ve.add(t,Mt.mark.cloneNode(!0))}}};var Nt={init(){if(["index","thread"].includes(n.VIEW)&&t["Resurrect Quotes"])return Ve.addClass(i,"resurrect-quotes"),t["Comment Expansion"]&&X.callbacks.push(this.node),l.Post.push({name:"Resurrect Quotes",cb:this.node})},node(){if(this.isClone)this.nodes.archivelinks=u("a.linkify.quotelink",this.nodes.comment);else{for(var e of u("a.linkify",this.nodes.comment))Nt.parseArchivelink.call(this,e);for(var t of u(".deadlink",this.nodes.comment))Nt.parseDeadlink.call(this,t)}},parseArchivelink(e){let t
|
||||
;if(!(t=e.pathname.match(/^\/([^/]+)\/thread\/S?(\d+)\/?$/)))return;if(["boards.4chan.org","boards.4channel.org"].includes(e.hostname))return;const n=t[1],o=t[2],a=e.hash.match(/^#[pq]?(\d+)$|$/)[1]||o;return Ze.to("post",{boardID:n,postID:a})?(Ve.addClass(e,"quotelink"),Ve.extend(e.dataset,{boardID:n,threadID:o,postID:a}),this.nodes.archivelinks.push(e)):void 0},parseDeadlink(e){let t,o,a,i;if(Ve.hasClass(e.parentNode,"prettyprint"))return void Nt.fixDeadlink(e);const r=e.textContent;if(!(i=r.match(/\d+$/)?.[0]))return;if("0"===i[0])return void Nt.fixDeadlink(e);const s=(o=r.match(/^>>>\/([a-z\d]+)/))?o[1]:this.board.ID,l=`${s}.${i}`;if(a=n.posts.get(l))a.isDead?(t=Ve.el("a",{href:n.SITE.Build.postURL(s,a.thread.ID,i),className:"quotelink deadlink",textContent:r}),Ve.add(t,H.deadMark.cloneNode(!0)),Ve.extend(t.dataset,{boardID:s,threadID:a.thread.ID,postID:i})):t=Ve.el("a",{href:n.SITE.Build.postURL(s,a.thread.ID,i),className:"quotelink",textContent:r});else{const e=Ze.to("thread",{
|
||||
boardID:s,threadID:0,postID:i}),n=Ze.to("post",{boardID:s,postID:i});(e||n)&&(t=Ve.el("a",{href:e||"javascript:;",className:"deadlink",textContent:r}),Ve.add(t,H.deadMark.cloneNode(!0)),n&&(Ve.addClass(t,"quotelink"),Ve.extend(t.dataset,{boardID:s,postID:i})))}if(this.quotes.includes(l)||this.quotes.push(l),t)return Ve.replace(e,t),Ve.hasClass(t,"quotelink")?this.nodes.quotelinks.push(t):void 0;Ve.add(e,H.deadMark.cloneNode(!0))},fixDeadlink(e){let t;if(!(t=e.previousSibling)||"BR"===t.nodeName){const t=Ve.el("span",{className:"quote"});Ve.before(e,t),Ve.add(t,e)}return Ve.replace(e,[...e.childNodes])}};const Lt={init(){this.toBlob(),Ve.global(this.toBlob),Element.prototype.matches||(Element.prototype.matches=Element.prototype.mozMatchesSelector||Element.prototype.webkitMatchesSelector)},toBlob:function(){HTMLCanvasElement.prototype.toBlob||(HTMLCanvasElement.prototype.toBlob=function(e,t,n){const o=this.toDataURL(t,n),a=atob(o.slice(o.indexOf(",")+1)),i=a.length,r=new Uint8Array(i)
|
||||
;for(let e=0,t=i;e<t;e++)r[e]=a.charCodeAt(e);return e(new Blob([r],{type:t||"image/png"}))})}};var Ft={init(){let o;try{let t=window;if("crx"===x&&(t=t.wrappedJSObject||t),`${e.name} antidup`in t)return;t[`${e.name} antidup`]=!0}catch(e){}try{if(window.frameElement&&["","about:blank"].includes(window.frameElement.src))return}catch(e){}if(i&&Ve.hasClass(i,"fourchan-x"))return;Ve.asap(s,(function(){if(Ve.addClass(i,"fourchan-x","seaweedchan"),Ve.engine)return Ve.addClass(i,`ua-${Ve.engine}`)})),Ve.on(a,"4chanXInitFinished",(function(){return Ft.expectInitFinished?delete Ft.expectInitFinished:(new Xe("error","Error: Multiple copies of 4chan X are enabled."),Ve.addClass(i,"tainted"))}));var r=function(){return a.removeEventListener("mounted",r,!0),Ft.isMounted=!0,Ft.mountedCBs.map((e=>(()=>{try{return e()}catch(e){}})()))};a.addEventListener("mounted",r,!0);var l=function(e,n){if(n instanceof Array)t[e]=m.clone(n[0]);else if("object"==typeof n)for(var o in n){var a=n[o];l(o,a)}else t[e]=n
|
||||
};for(var d of(["boards.4chan.org","boards.4channel.org"].includes(location.hostname)&&(Ve.global((function(){const e=String.fromCharCode;return String.fromCharCode=function(){if(document.body)String.fromCharCode=e;else if(document.currentScript&&!document.currentScript.src)throw Error();return e.apply(this,arguments)}})),Ve.asap(s,(()=>Ve.onExists(i,"iframe[srcdoc]",Ve.rm)))),l(null,c),y.keys))t[d]=m();t.customTitles=m.clone({"4chan.org":{boards:{qa:{boardTitle:{orig:"/qa/ - Question & Answer",title:"/qa/ - 2D/Random"}}}}}),t.boardConfig={boards:m()},t.archives=Ze.archives,t.selectedArchives=m(),t.cooldowns=m(),t["Index Sort"]=m();for(let e=0;e<2;e++)t[`Last Long Reply Thresholds ${e}`]=m();t.siteProperties=m(),t["Except Archives from Encryption"]=!1,t["JSON Navigation"]=!0,t["Oekaki Links"]=!0,t["Show Name and Subject"]=!1,t["QR Shortcut"]=!0,t["Bottom QR Link"]=!0,t["Toggleable Thread Watcher"]=!0,t.siteSoftware="",t["Use Faster Image Host"]="true",t["Captcha Fixes"]=!0,
|
||||
t.captchaServiceDomain="",t.captchaServiceKey=m(),!/\.4chan(?:nel)?\.org$/.test(location.hostname)||Ce.yotsuba.regexp.pass.test(location.href)||Ce.yotsuba.regexp.captcha.test(location.href)||u("script:not([src])",a).filter((e=>/this\[/.test(e.textContent))).length||(Ve.getSync||Ve.get)({jsWhitelist:t.jsWhitelist},(({jsWhitelist:e})=>Ve.addCSP(`script-src ${e.replace(/^#.*$/gm,"").replace(/[\s;]+/g," ").trim()}`)));const h=m();for(o in t)h[o]=void 0;return h.previousversion=void 0,(Ve.getSync||Ve.get)(h,(function(e){if(Ve.perProtocolSettings||!/\.4chan(?:nel)?\.org$/.test(location.hostname)||!(e["Redirect to HTTPS"]??t["Redirect to HTTPS"])||"https:"===location.protocol)return Ve.asap(s,(function(){for(o in Ve.cantSet||(null==e.previousversion?(Ft.isFirstRun=!0,Ft.ready((function(){return Ve.set("previousversion",n.VERSION),Be.open()}))):e.previousversion!==n.VERSION&&Ft.upgrade(e)),t){var a=t[o];t[o]=e[o]??a}return Ge.init(Ft.initFeatures)}))
|
||||
;location.replace("https://"+location.host+location.pathname+location.search+location.hash)}))},upgrade(t){const{previousversion:o}=t,a=Be.upgrade(t,o);return t.previousversion=a.previousversion=n.VERSION,Ve.set(a,(function(){if(t["Show Updated Notifications"]??1){const t=Ve.el("span",{innerHTML:`${e.name} has been updated to <a href="${e.changelog}" target="_blank">version ${n.VERSION}</a>.`});return new Xe("info",t,15)}}))},parseURL(e=n.SITE,t=location){const o={};if(!e)return o;if(o.siteID=e.ID,e.isBoardlessPage?.(t))return o;const a=t.pathname.split(/\/+/);return o.boardID=a[1],e.isFileURL(t)?o.VIEW="file":e.isAuxiliaryPage?.(t)||(["thread","res"].includes(a[2])?(o.VIEW="thread",o.threadID=o.THREADID=+a[3].replace(/\.\w+$/,"")):"archive"===a[2]&&"res"===a[3]?(o.VIEW="thread",o.threadID=o.THREADID=+a[4].replace(/\.\w+$/,""),o.threadArchived=!0):/^(?:catalog|archive)(?:\.\w+)?$/.test(a[2])?o.VIEW=a[2].replace(/\.\w+$/,""):/^(?:index|\d*)(?:\.\w+)?$/.test(a[2])&&(o.VIEW="index")),o},
|
||||
initFeatures(){if(Ve.global((function(){return document.documentElement.classList.add("js-enabled"),window.FCX={}})),Ft.jsEnabled=Ve.hasClass(i,"js-enabled"),Ve.ajaxPageInit?.(),Ve.extend(n,Ft.parseURL()),n.boardID&&(n.BOARD=new J(n.boardID)),n.VIEW){if("file"!==n.VIEW){for(var[e,o]of(n.threads=new k,n.posts=new k,Ve.onExists(i,"body",Ft.initStyle),Ft.features))if(!n.SITE.disabledFeatures||!n.SITE.disabledFeatures.includes(e))try{o.init()}catch(t){Ft.handleErrors({message:`"${e}" initialization crashed.`,error:t})}return Ve.ready(Ft.initReady)}Ve.asap((()=>"loading"!==a.readyState),(function(){let e;if("yotsuba"===n.SITE.software&&t["404 Redirect"]&&n.SITE.is404?.()){const e=location.pathname.split(/\/+/);return Ze.navigate("file",{boardID:n.BOARD.ID,filename:e[e.length-1]})}if((e=Ve("video"))&&(t["Volume in New Tab"]&&$.setup(e),t["Loop in New Tab"]))return e.loop=!0,e.controls=!1,e.play(),j.addControls(e)}))}else n.SITE.initAuxiliary?.()},initStyle(){if(!Ft.isThisPageLegit())return
|
||||
;const e=Ve("link[href*=mobile]",a.head);e&&(e.disabled=!0),i.dataset.host=location.host,Ve.addClass(i,`sw-${n.SITE.software}`),Ve.addClass(i,"thread"===n.VIEW?"thread-view":n.VIEW),Ve.onExists(i,".ad-cnt, .adg-rects > .desktop",(e=>Ve.onExists(e,"img, iframe",(()=>Ve.addClass(i,"ads-loaded"))))),t["Autohiding Scrollbar"]&&Ve.addClass(i,"autohiding-scrollbar"),Ve.ready((function(){if(a.body.clientHeight>i.clientHeight&&window.innerWidth===i.clientWidth!==t["Autohiding Scrollbar"])return t["Autohiding Scrollbar"]=!t["Autohiding Scrollbar"],Ve.set("Autohiding Scrollbar",t["Autohiding Scrollbar"]),Ve.toggleClass(i,"autohiding-scrollbar")})),Ve.addStyle(me.sub(me.boards),"fourchanx-css"),Ft.bgColorStyle=Ve.el("style",{id:"fourchanx-bgcolor-css"});let o=!1;return Ve.on(a,"mousedown",(()=>o=!1)),Ve.on(a,"keydown",(function(e){if(9===e.keyCode)return o=!0})),window.addEventListener("focus",(()=>i.classList.toggle("keyboard-focus",o)),!0),Ft.setClass()},setClass(){let e,t,o
|
||||
;const r=["yotsuba","yotsuba-b","futaba","burichan","photon","tomorrow","spooky"];if("yotsuba"===n.SITE.software&&"catalog"===n.VIEW&&(e=Ve.id("base-css"))&&(t=e.href.match(/catalog_(\w+)/)?.[1].replace("_new","").replace(/_+/g,"-"),r.includes(t)))return void Ve.addClass(i,t);t=e=o=null;const s=function(){if("yotsuba"===n.SITE.software){for(var s of(Ve.rmClass(i,t),t=null,o))if(s.href===e?.href){t=s.title.toLowerCase().replace("new","").trim().replace(/\s+/g,"-"),"_special"===t&&(t=s.href.match(/[a-z]*(?=[^/]*$)/)[0]),r.includes(t)||(t=null);break}if(t)return Ve.addClass(i,t),void Ve.rm(Ft.bgColorStyle)}const l=n.SITE.bgColoredEl();l.style.position="absolute",l.style.visibility="hidden",Ve.add(a.body,l);let d=window.getComputedStyle(l).backgroundColor;Ve.rm(l);const c=d.match(/[\d.]+/g);if(!/^rgb\(/.test(d)){const e=window.getComputedStyle(a.body);d=`${e.backgroundColor} ${e.backgroundImage} ${e.backgroundRepeat} ${e.backgroundPosition}`}
|
||||
let h=`.dialog, .suboption-list > div:last-of-type, :root.catalog-hover-expand .catalog-container:hover > .post {\n background: ${d};\n}\n.unread-mark-read {\n background-color: rgba(${c.slice(0,3).join(", ")}, ${.5*(c[3]||1)});\n}`;return Ve.luma(c)<100&&(h+=".watch-thread-link {\n background-image: url(\"data:image/svg+xml,<svg viewBox='0 0 26 26' preserveAspectRatio='true' xmlns='http://www.w3.org/2000/svg'><path fill='rgb(200,200,200)' d='M24.132,7.971c-2.203-2.205-5.916-2.098-8.25,0.235L15.5,8.588l-0.382-0.382c-2.334-2.333-6.047-2.44-8.25-0.235c-2.204,2.203-2.098,5.916,0.235,8.249l8.396,8.396l8.396-8.396C26.229,13.887,26.336,10.174,24.132,7.971z'/></svg>\");\n}"),Ft.bgColorStyle.textContent=h,Ve.after(Ve.id("fourchanx-css"),Ft.bgColorStyle)};if(Ve.onExists(a.head,n.SITE.selectors.styleSheet,(function(t){return e=t,"yotsuba"===n.SITE.software&&(o=u('link[rel="alternate stylesheet"]',a.head)),new MutationObserver(s).observe(e,{attributes:!0,attributeFilter:["href"]}),
|
||||
Ve.on(e,"load",s),s()})),!e){for(var l of u('link[rel="stylesheet"]',a.head))Ve.on(l,"load",s);return s()}},initReady(){if(!n.SITE.is404?.()){if(n.SITE.isIncomplete?.()){const e=Ve.el("div",{innerHTML:'The page didn't load completely.<br>Some features may not work unless you <a href="javascript:;">reload</a>.'});Ve.on(Ve("a",e),"click",(()=>location.reload())),new Xe("warning",e)}return"catalog"===n.VIEW?Ft.initCatalog():ue.enabled?(Ft.expectInitFinished=!0,Ve.event("4chanXInitFinished")):n.SITE.awaitBoard?n.SITE.awaitBoard(Ft.initThread):Ft.initThread()}"thread"===n.VIEW&&ae.set404(n.BOARD.ID,n.THREADID,(function(){if(t["404 Redirect"])return Ze.navigate("thread",{boardID:n.BOARD.ID,threadID:n.THREADID,postID:+location.hash.match(/\d+/)},`/${n.BOARD}/`)}))},initThread(){let e;const t=n.SITE.selectors;if(e=Ve(t.boardFor?.[n.VIEW]||t.board)){const o=[],a=[],i=[];try{n.SITE.preParsingFixes?.(e)}catch(e){}return Ft.addThreadsObserver=new MutationObserver(Ft.addThreads),
|
||||
Ft.addPostsObserver=new MutationObserver(Ft.addPosts),Ft.addThreadsObserver.observe(e,{childList:!0}),Ft.parseThreads(u(t.thread,e),o,a,i),i.length&&Ft.handleErrors(i),"thread"===n.VIEW&&(n.threadArchived&&(o[0].isArchived=!0,o[0].kill()),n.SITE.parseThreadMetadata?.(o[0])),Ft.callbackNodes("Thread",o),Ft.callbackNodesDB("Post",a,(function(){for(var e of a)Te.insert(e);return Ft.expectInitFinished=!0,Ve.event("4chanXInitFinished")}))}return Ft.expectInitFinished=!0,Ve.event("4chanXInitFinished")},parseThreads(e,t,o,a){for(var i of e){var r=(()=>{let e;return(e=i.dataset.board)?(e=encodeURIComponent(e),n.boards[e]||new J(e)):n.BOARD})(),s=+i.id.match(/\d*$/)[0];if(!s||r.threads.get(s)?.nodes.root)return;var l=new I(s,r);l.nodes.root=i,t.push(l);var d=u(n.SITE.selectors.postContainer,i);n.SITE.isOPContainerThread&&d.unshift(i),Ft.parsePosts(d,l,o,a),Ft.addPostsObserver.observe(i,{childList:!0})}},parsePosts(e,t,o,a){
|
||||
for(var i of e)if((!i.dataset.fullID||!n.posts.get(i.dataset.fullID))&&Ve(n.SITE.selectors.comment,i))try{o.push(new H(i,t,t.board))}catch(e){a.push({message:`Parsing of Post No.${i.id.match(/\d+/)} failed. Post will be skipped.`,error:e,html:i.outerHTML})}},addThreads(e){const t=[];for(var o of e)for(var a of o.addedNodes)a.nodeType===Node.ELEMENT_NODE&&a.matches(n.SITE.selectors.thread)&&t.push(a);if(!t.length)return;const i=[],r=[],s=[];return Ft.parseThreads(t,i,r,s),s.length&&Ft.handleErrors(s),Ft.callbackNodes("Thread",i),Ft.callbackNodesDB("Post",r,(()=>Ve.event("PostsInserted",null,e[0].target)))},addPosts(e){let t;const o=[],a=[],r=[],s=[];for(var l of e){t=ze.threadFromRoot(l.target);var d=[];for(var c of l.addedNodes)c.nodeType===Node.ELEMENT_NODE&&(c.matches(n.SITE.selectors.postContainer)||(c=Ve(n.SITE.selectors.postContainer,c)))&&d.push(c);var h=r.length;Ft.parsePosts(d,t,r,s),r.length>h&&!o.includes(t)&&o.push(t);var u=!1
|
||||
;for(var p of l.removedNodes)if(ze.postFromRoot(p)?.nodes.root===p&&!i.contains(p)){u=!0;break}u&&!a.includes(t)&&a.push(t)}return s.length&&Ft.handleErrors(s),Ft.callbackNodesDB("Post",r,(function(){for(t of o)Ve.event("PostsInserted",null,t.nodes.root);for(t of a)Ve.event("PostsRemoved",null,t.nodes.root)}))},initCatalog(){let e;const t=n.SITE.selectors.catalog;if(t&&(e=Ve(t.board))){const n=[],o=[];Ft.addCatalogThreadsObserver=new MutationObserver(Ft.addCatalogThreads),Ft.addCatalogThreadsObserver.observe(e,{childList:!0}),Ft.parseCatalogThreads(u(t.thread,e),n,o),o.length&&Ft.handleErrors(o),Ft.callbackNodes("CatalogThreadNative",n)}return Ft.expectInitFinished=!0,Ve.event("4chanXInitFinished")},parseCatalogThreads(e,t,n){for(var o of e)try{var a=new et(o);a.thread.catalogViewNative?.nodes.root!==o&&(a.thread.catalogViewNative=a,t.push(a))}catch(e){n.push({message:`Parsing of Catalog Thread No.${(o.dataset.id||o.id).match(/\d+/)} failed. Thread will be skipped.`,error:e,
|
||||
html:o.outerHTML})}},addCatalogThreads(e){const t=[];for(var o of e)for(var a of o.addedNodes)a.nodeType===Node.ELEMENT_NODE&&a.matches(n.SITE.selectors.catalog.thread)&&t.push(a);if(!t.length)return;const i=[],r=[];return Ft.parseCatalogThreads(t,i,r),r.length&&Ft.handleErrors(r),Ft.callbackNodes("CatalogThreadNative",i)},callbackNodes(e,t){let n,o=0;const a=l[e];for(;n=t[o++];)a.execute(n)},callbackNodesDB(e,t,n){let o=0;const a=l[e],i=function(){let e;return!!(e=t[o])&&(a.execute(e),++o%250)};var r=function(){for(;i(););if(t[o])return setTimeout(r,0);n&&n()};return r()},handleErrors(r){let s;if(a.body&&Ve.hasClass(a.body,"fourchan_x")&&!Ve.hasClass(i,"tainted")&&(new Xe("error","Error: Multiple copies of 4chan X are enabled."),Ve.addClass(i,"tainted")),n.SITE.testNativeExtension&&!Ve.hasClass(i,"tainted")){const{enabled:a}=n.SITE.testNativeExtension();if(a&&(Ve.addClass(i,"tainted"),t["Disable Native Extension"]&&!Ft.isFirstRun)){const t=Ve.el("div",{
|
||||
innerHTML:'Failed to disable the native extension. You may need to <a href="'+o(e.faq)+'#blocking-native-extension" target="_blank">block it</a>.'});new Xe("error",t)}}if(r instanceof Array?1===r.length&&(s=r[0]):s=r,s)return void new Xe("error",Ft.parseError(s,Ft.reportLink([s])),15);const l=Ve.el("div",{innerHTML:`${r.length} errors occurred.${Ft.reportLink(r).innerHTML} [<a href="javascript:;">show</a>]`});Ve.on(l.lastElementChild,"click",(function(){return[this.textContent,d.hidden]="show"===this.textContent?["hide",!1]:["show",!0]}));var d=Ve.el("div",{hidden:!0});for(s of r)Ve.add(d,Ft.parseError(s));return new Xe("error",[l,d],30)},parseError(t,a){r.error(t.message,t.error.stack);const i=Ve.el("div",{innerHTML:o(t.message)+(a?a.innerHTML:"")}),s=Ve.el("div",{textContent:`${t.error.name||"Error"}: ${t.error.message||"see console for details"}`}),l=t.error.stack?.match(/\d+(?=:\d+\)?$)/gm)?.join().replace(/^/," at ")||"";return[i,s,Ve.el("div",{
|
||||
textContent:`(${e.name} ${e.fork} v${n.VERSION} ${x} on ${Ve.engine}${l})`})]},reportLink(t){let o;const a=t[0];let i=a.message;t.length>1&&(i+=` (+${t.length-1} other errors)`);let r="";const s=function(t){if(encodeURIComponent(i+r+t+"\n").length<=e.newIssueMaxLength-e.newIssue.replace(/%(title|details)/,"").length)return r+=t+"\n"};s(`[Please describe the steps needed to reproduce this error.]\n\nScript: ${e.name} ${e.fork} v${n.VERSION} ${x}\nURL: ${location.href}\nUser agent: ${navigator.userAgent}`),"userscript"===x&&(o="undefined"!=typeof GM&&null!==GM?GM.info:"undefined"!=typeof GM_info&&null!==GM_info?GM_info:void 0)&&s(`Userscript manager: ${o.scriptHandler} ${o.version}`),s("\n"+a.error),a.error.stack&&s(a.error.stack.replace(a.error.toString(),"").trim()),a.html&&s("\n`"+a.html+"`"),r=r.replace(/file:\/{3}.+\//g,"");return{
|
||||
innerHTML:`<span class="report-error"> [<a href="${e.newIssue.replace("%title",encodeURIComponent(i)).replace("%details",encodeURIComponent(r))}" target="_blank">report</a>]</span>`}},isThisPageLegit:()=>("thisPageIsLegit"in Ft||(Ft.thisPageIsLegit=n.SITE.isThisPageLegit?n.SITE.isThisPageLegit():!/^[45]\d\d\b/.test(document.title)&&!/\.(?:json|rss)$/.test(location.pathname)),Ft.thisPageIsLegit),ready:e=>Ve.ready((function(){if(Ft.isThisPageLegit())return e()})),mounted:e=>Ft.isMounted?e():Ft.mountedCBs.push(e),mountedCBs:[],
|
||||
features:[["Polyfill",Lt],["Board Configuration",Y],["Normalize URL",wt],["Delay Redirect on Post",K],["Captcha Configuration",p],["Image Host Rewriting",O],["Redirect",Ze],["Header",Ke],["Catalog Links",Ye],["Settings",Be],["Index Generator",ue],["Disable Autoplay",ut],["Announcement Hiding",kt],["Fourchan thingies",ft],["Tinyboard Glue",Dt],["Color User IDs",mt],["Highlight by User ID",bt],["Count Posts by ID",At],["Custom CSS",Ae],["Thread Links",Ct],["Linkify",rt],["Reveal Spoilers",It],["Resurrect Quotes",Nt],["Filter",We],["Thread Hiding Buttons",pe],["Reply Hiding Buttons",W],["Recursive",z],["Strike-through Quotes",{init(){if(["index","thread"].includes(n.VIEW)&&(t["Reply Hiding Buttons"]||t.Menu&&t["Reply Hiding Link"]||t.Filter))return l.Post.push({name:"Strike-through Quotes",cb:this.node})},node(){if(!this.isClone)for(var e of this.nodes.quotelinks){var{boardID:t,postID:o}=ze.postDataFromLink(e);n.posts.get(`${t}.${o}`)?.isHidden&&Ve.addClass(e,"filtered")}}
|
||||
}],["Quick Reply Personas",$e.persona],["Quick Reply",$e],["Cooldown",$e.cooldown],["Post Jumper",xt],["Pass Link",Tt],["Menu",Q],["Index Generator (Menu)",ue.menu],["Report Link",ht],["Copy Text Link",lt],["Thread Hiding (Menu)",pe.menu],["Reply Hiding (Menu)",W.menu],["Delete Link",dt],["Filter (Menu)",We.menu],["Edit Link",$e.oekaki.menu],["Download Link",ct],["Archive Link",st],["Quote Inlining",Rt],["Quote Previewing",ce],["Quote Backlinks",Bt],["Mark Quotes of You",_],["Mark OP Quotes",Mt],["Mark Cross-thread Quotes",Pt],["Anonymize",tt],["Time Formatting",Ee],["Relative Post Dates",G],["File Info Formatting",De],["Fappe Tyme",Pe],["Gallery",Ne],["Gallery (menu)",Ne.menu],["Sauce",Me],["Image Expansion",U],["Image Expansion (Menu)",U.menu],["Reveal Spoiler Thumbnails",it],["Image Loading",ot],["Image Hover",nt],["Volume Control",$],["WEBM Metadata",at],["Comment Expansion",X],["Thread Expansion",te],["Favicon",h],["Unread",ee],["Unread Line in Index",ne],["Quote Threading",Te],["Thread Stats",St],["Thread Updater",Re],["Thread Watcher",ae],["Thread Watcher (Menu)",ae.menu],["Mark New IPs",Et],["Index Navigation",F],["Keybinds",Fe],["Banner",pt],["Announcements",yt],["Flash Features",gt],["Reply Pruning",Se],["Mod Contact Links",vt]]
|
||||
},Ot=Ft;Ve.ready((()=>Ft.init()))}();
|
||||
//# sourceMappingURL=4chan-XT-noupdate.user.min.js.map
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "4chan XT",
|
||||
"version": "XT 2.1.3",
|
||||
"version": "XT 2.1.4",
|
||||
"manifest_version": 2,
|
||||
"description": "4chan XT is a script that adds various features to anonymous imageboards.",
|
||||
"icons": {
|
||||
|
||||
@ -79,8 +79,8 @@
|
||||
'use strict';
|
||||
|
||||
var version = {
|
||||
"version": "XT 2.1.3",
|
||||
"date": "2023-08-21T18:04:11.719Z"
|
||||
"version": "XT 2.1.4",
|
||||
"date": "2023-09-02T15:03:39.080Z"
|
||||
};
|
||||
|
||||
var meta = {
|
||||
@ -1967,11 +1967,10 @@ https://*.hcaptcha.com
|
||||
class DataBoard {
|
||||
static initClass() {
|
||||
this.keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads', 'watcherLastModified', 'customTitles'];
|
||||
|
||||
this.changes = [];
|
||||
}
|
||||
|
||||
constructor(key, sync, dontClean) {
|
||||
this.changes = [];
|
||||
this.onSync = this.onSync.bind(this);
|
||||
this.key = key;
|
||||
this.initData(Conf[this.key]);
|
||||
@ -2002,15 +2001,15 @@ https://*.hcaptcha.com
|
||||
|
||||
save(change, cb) {
|
||||
change();
|
||||
DataBoard.changes.push(change);
|
||||
this.changes.push(change);
|
||||
return $$1.get(this.key, { boards: dict() }, items => {
|
||||
if (!DataBoard.changes.length) { return; }
|
||||
if (!this.changes.length) { return; }
|
||||
const needSync = ((items[this.key].version || 0) > (this.data.version || 0));
|
||||
if (needSync) {
|
||||
this.initData(items[this.key]);
|
||||
for (change of DataBoard.changes) { change(); }
|
||||
for (change of this.changes) { change(); }
|
||||
}
|
||||
DataBoard.changes = [];
|
||||
this.changes = [];
|
||||
this.data.version = (this.data.version || 0) + 1;
|
||||
return $$1.set(this.key, this.data, () => {
|
||||
if (needSync) { this.sync?.(); }
|
||||
@ -2023,7 +2022,7 @@ https://*.hcaptcha.com
|
||||
return $$1.get(this.key, { boards: dict() }, items => {
|
||||
if ((items[this.key].version || 0) > (this.data.version || 0)) {
|
||||
this.initData(items[this.key]);
|
||||
for (var change of DataBoard.changes) { change(); }
|
||||
for (var change of this.changes) { change(); }
|
||||
this.sync?.();
|
||||
}
|
||||
return cb?.();
|
||||
@ -15521,7 +15520,7 @@ Enable it on boards.${location.hostname.split('.')[1]}.org in your browser's pri
|
||||
}
|
||||
catch (error) { }
|
||||
}
|
||||
const compareString = version.replace(/\d+/g, x => ('0000' + x).slice(-5));
|
||||
const compareString = version.replace(/^XT /i, '').replace(/\d+/g, x => x.padStart(5, '0'));
|
||||
if (compareString < '00001.00013.00014.00008') {
|
||||
for (key in data) {
|
||||
val = data[key];
|
||||
@ -21352,27 +21351,16 @@ vp-replace
|
||||
};
|
||||
|
||||
$.queueTask = (function() {
|
||||
// inspired by https://www.w3.org/Bugs/Public/show_bug.cgi?id=15007
|
||||
const taskQueue = [];
|
||||
const execTask = function() {
|
||||
const task = taskQueue.shift();
|
||||
const func = task[0];
|
||||
const args = Array.prototype.slice.call(task, 1);
|
||||
return func.apply(func, args);
|
||||
const [func, ...args] = taskQueue.shift();
|
||||
func(...args);
|
||||
};
|
||||
return function() {
|
||||
taskQueue.push(arguments);
|
||||
// setTimeout is throttled in background tabs on firefox
|
||||
Promise.resolve().then(execTask);
|
||||
};
|
||||
if (window.MessageChannel) {
|
||||
const taskChannel = new MessageChannel();
|
||||
taskChannel.port1.onmessage = execTask;
|
||||
return function() {
|
||||
taskQueue.push(arguments);
|
||||
return taskChannel.port2.postMessage(null);
|
||||
};
|
||||
} else { // XXX Firefox
|
||||
return function() {
|
||||
taskQueue.push(arguments);
|
||||
return setTimeout(execTask, 0);
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
$.global = function(fn, data) {
|
||||
|
||||
@ -519,7 +519,7 @@ Enable it on boards.${location.hostname.split('.')[1]}.org in your browser's pri
|
||||
version = JSON.parse(version);
|
||||
} catch (error) {}
|
||||
}
|
||||
const compareString = version.replace(/\d+/g, x => ('0000'+x).slice(-5));
|
||||
const compareString = version.replace(/^XT /i, '').replace(/\d+/g, x => x.padStart(5, '0'));
|
||||
if (compareString < '00001.00013.00014.00008') {
|
||||
for (key in data) {
|
||||
val = data[key];
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
{
|
||||
"version": "XT 2.1.3",
|
||||
"date": "2023-08-21T18:04:11.719Z"
|
||||
"version": "XT 2.1.4",
|
||||
"date": "2023-09-02T15:03:39.080Z"
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user