666 lines
543 KiB
JavaScript
666 lines
543 KiB
JavaScript
// ==UserScript==
|
||
// @name 4chan XT
|
||
// @version XT 2.1.4
|
||
// @minGMVer 1.14
|
||
// @minFFVer 74
|
||
// @namespace 4chan-XT
|
||
// @description 4chan XT is a script that adds various features to anonymous imageboards.
|
||
// @license MIT; https://github.com/TuxedoTako/4chan-xt/blob/project-XT/LICENSE
|
||
// @include http://boards.4chan.org/*
|
||
// @include https://boards.4chan.org/*
|
||
// @include http://sys.4chan.org/*
|
||
// @include https://sys.4chan.org/*
|
||
// @include http://www.4chan.org/*
|
||
// @include https://www.4chan.org/*
|
||
// @include http://boards.4channel.org/*
|
||
// @include https://boards.4channel.org/*
|
||
// @include http://sys.4channel.org/*
|
||
// @include https://sys.4channel.org/*
|
||
// @include http://www.4channel.org/*
|
||
// @include https://www.4channel.org/*
|
||
// @include http://i.4cdn.org/*
|
||
// @include https://i.4cdn.org/*
|
||
// @include http://is.4chan.org/*
|
||
// @include https://is.4chan.org/*
|
||
// @include http://is2.4chan.org/*
|
||
// @include https://is2.4chan.org/*
|
||
// @include http://is.4channel.org/*
|
||
// @include https://is.4channel.org/*
|
||
// @include http://is2.4channel.org/*
|
||
// @include https://is2.4channel.org/*
|
||
// @include https://erischan.org/*
|
||
// @include https://www.erischan.org/*
|
||
// @include https://fufufu.moe/*
|
||
// @include https://gnfos.com/*
|
||
// @include https://himasugi.blog/*
|
||
// @include https://www.himasugi.blog/*
|
||
// @include https://kakashinenpo.com/*
|
||
// @include https://www.kakashinenpo.com/*
|
||
// @include https://kissu.moe/*
|
||
// @include https://www.kissu.moe/*
|
||
// @include https://lainchan.org/*
|
||
// @include https://www.lainchan.org/*
|
||
// @include https://merorin.com/*
|
||
// @include https://ota-ch.com/*
|
||
// @include https://www.ota-ch.com/*
|
||
// @include https://ponyville.us/*
|
||
// @include https://www.ponyville.us/*
|
||
// @include https://smuglo.li/*
|
||
// @include https://notso.smuglo.li/*
|
||
// @include https://smugloli.net/*
|
||
// @include https://smug.nepu.moe/*
|
||
// @include https://sportschan.org/*
|
||
// @include https://www.sportschan.org/*
|
||
// @include https://sushigirl.us/*
|
||
// @include https://www.sushigirl.us/*
|
||
// @include https://tvch.moe/*
|
||
// @exclude http://www.4chan.org/advertise
|
||
// @exclude https://www.4chan.org/advertise
|
||
// @exclude http://www.4chan.org/advertise?*
|
||
// @exclude https://www.4chan.org/advertise?*
|
||
// @exclude http://www.4chan.org/donate
|
||
// @exclude https://www.4chan.org/donate
|
||
// @exclude http://www.4chan.org/donate?*
|
||
// @exclude https://www.4chan.org/donate?*
|
||
// @exclude http://www.4channel.org/advertise
|
||
// @exclude https://www.4channel.org/advertise
|
||
// @exclude http://www.4channel.org/advertise?*
|
||
// @exclude https://www.4channel.org/advertise?*
|
||
// @exclude http://www.4channel.org/donate
|
||
// @exclude https://www.4channel.org/donate
|
||
// @exclude http://www.4channel.org/donate?*
|
||
// @exclude https://www.4channel.org/donate?*
|
||
// @connect 4chan.org
|
||
// @connect 4channel.org
|
||
// @connect 4cdn.org
|
||
// @connect 4chenz.github.io
|
||
// @connect archive.4plebs.org
|
||
// @connect warosu.org
|
||
// @connect desuarchive.org
|
||
// @connect boards.fireden.net
|
||
// @connect arch.b4k.co
|
||
// @connect archived.moe
|
||
// @connect thebarchive.com
|
||
// @connect archiveofsins.com
|
||
// @connect www.tokyochronos.net
|
||
// @connect archive.palanq.win
|
||
// @connect eientei.xyz
|
||
// @connect api.clyp.it
|
||
// @connect api.dailymotion.com
|
||
// @connect api.github.com
|
||
// @connect soundcloud.com
|
||
// @connect api.streamable.com
|
||
// @connect vimeo.com
|
||
// @connect www.youtube.com
|
||
// @connect *
|
||
// @grant GM_getValue
|
||
// @grant GM_setValue
|
||
// @grant GM_deleteValue
|
||
// @grant GM_listValues
|
||
// @grant GM_addValueChangeListener
|
||
// @grant GM_openInTab
|
||
// @grant GM_xmlhttpRequest
|
||
// @grant GM.getValue
|
||
// @grant GM.setValue
|
||
// @grant GM.deleteValue
|
||
// @grant GM.listValues
|
||
// @grant GM.openInTab
|
||
// @grant GM.xmlHttpRequest
|
||
// @run-at document-start
|
||
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAF5JREFUeNrtkTESABAQxPD/R6tsE2dUGYUtFJvLDKf93KevHJAjpBorAQWSBIKqFASC4G0pCAkm4GfaEvgYXl0T6HBaE97f0vmnfYHbZOMLZCx9ISdKWwjOWZSC8GYm4SUGwfYgqI4AAAAASUVORK5CYII=
|
||
// ==/UserScript==
|
||
/*
|
||
* 4chan X
|
||
*
|
||
* Licensed under the MIT license.
|
||
* https://github.com/ccd0/4chan-x/blob/master/LICENSE
|
||
*
|
||
* Appchan X Copyright © 2013-2016 Zixaphir <zixaphirmoxphar@gmail.com>
|
||
* http://zixaphir.github.io/appchan-x/
|
||
* 4chan x Copyright © 2009-2011 James Campos <james.r.campos@gmail.com>
|
||
* https://github.com/aeosynth/4chan-x
|
||
* 4chan x Copyright © 2012-2014 Nicolas Stepien <stepien.nicolas@gmail.com>
|
||
* https://4chan-x.just-believe.in/
|
||
* 4chan x Copyright © 2013-2014 Jordan Bates <saudrapsmann@gmail.com>
|
||
* http://seaweedchan.github.io/4chan-x/
|
||
* 4chan x Copyright © 2012-2013 ihavenoface
|
||
* http://ihavenoface.github.io/4chan-x/
|
||
* 4chan SS Copyright © 2011-2013 Ahodesuka
|
||
* https://github.com/ahodesuka/4chan-Style-Script/
|
||
*
|
||
* Permission is hereby granted, free of charge, to any person
|
||
* obtaining a copy of this software and associated documentation
|
||
* files (the "Software"), to deal in the Software without
|
||
* restriction, including without limitation the rights to use,
|
||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
* copies of the Software, and to permit persons to whom the
|
||
* Software is furnished to do so, subject to the following
|
||
* conditions:
|
||
*
|
||
* The above copyright notice and this permission notice shall be
|
||
* included in all copies or substantial portions of the Software.
|
||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||
* OTHER DEALINGS IN THE SOFTWARE.
|
||
*
|
||
* Contributors:
|
||
* aeosynth
|
||
* mayhemydg
|
||
* noface
|
||
* !K.WeEabo0o
|
||
* blaise
|
||
* that4chanwolf
|
||
* desuwa
|
||
* seaweed
|
||
* e000
|
||
* ahodesuka
|
||
* Shou
|
||
* ferongr
|
||
* xat
|
||
* Ongpot
|
||
* thisisanon
|
||
* Anonymous
|
||
* Seiba
|
||
* herpaderpderp
|
||
* WakiMiko
|
||
* btmcsweeney
|
||
* AppleBloom
|
||
* detharonil
|
||
*
|
||
* All the people who've taken the time to write bug reports.
|
||
*
|
||
* Thank you.
|
||
*/
|
||
/*
|
||
* Contains data from external sources:
|
||
*
|
||
* src/Monitoring/ThreadUpdater/beep.wav from http://freesound.org/people/pierrecartoons1979/sounds/90112/
|
||
* cc-by-nc-3.0
|
||
*
|
||
* Icons used to identify various websites are property of the respective websites.
|
||
*/
|
||
!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.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."],
|
||
"Remove Spoilers":[!1,"Remove all spoilers in text."],"Reveal Spoilers":[!1,"Indicate spoilers if Remove Spoilers is enabled, or make the text appear hovered if Remove Spoiler is disabled."],"Normalize URL":[!0,"Rewrite the URL of the current page, removing slugs and excess slashes, and changing /res/ to /thread/."],"Work around CORB Bug":[!0,"Leave this checked until your garbage browser is fixed."],"Disable Autoplaying Sounds":[!1,"Prevent sounds on the page from autoplaying."],"Disable Native Extension":[!0,`${e.name} is NOT designed to work with the native extension.`],"Enable Native Flash Embedding":[!0,"Activate the native extension's Flash embedding if the native extension is disabled."]},Linkification:{Linkify:[!0,"Convert text into links where applicable."],"Link Title":[!0,"Replace the link of a supported site with its actual title.",1],"Cover Preview":[!0,"Show preview of supported links on hover.",1],
|
||
Embedding:[!0,"Embed supported services. Note: Some services don't work on HTTPS.",1],"Auto-embed":[!1,"Auto-embed Linkify Embeds.",2],"Floating Embeds":[!1,"Embed content in a frame that remains in place when the page is scrolled.",2]},Filtering:{Anonymize:[!1,"Make everyone Anonymous."],Filter:[!0,"Self-moderation placebo."],"Filtered Backlinks":[!1,"When enabled, shows backlinks to filtered posts with a line-through decoration. Otherwise, hides the backlinks.",1],"Filter in Native Catalog":[!0,"Apply 4chan X filters in native catalog.",1],"MD5 Quick Filter Notifications":[!0,"Show notification when quick filtering MD5s using the button or keybind.",1],"Recursive Hiding":[!0,"Hide replies of hidden posts, recursively."],"Thread Hiding Buttons":[!0,"Add buttons to hide entire threads."],"Reply Hiding Buttons":[!0,"Add buttons to hide single replies."],Stubs:[!0,"Show stubs of hidden threads / replies."]},"Images and Videos":{"Image Expansion":[!0,"Expand images / videos."],
|
||
"Image Hover":[!0,"Show full image / video on mouseover."],"Image Hover in Catalog":[!0,`Show full image / video on mouseover in ${e.name} catalog.`],Gallery:[!0,"Adds a simple and cute image gallery. Has more options in the gallery menu."],"Fullscreen Gallery":[!1,"Open gallery in fullscreen mode.",1],"PDF in Gallery":[!1,"Show PDF files in gallery.",1],Sauce:[!0,"Add sauce links to images."],"WEBM Metadata":[!0,"Add link to fetch title metadata from webm videos."],"Reveal Spoiler Thumbnails":[!1,"Replace spoiler thumbnails with the original image."],"Replace GIF":[!1,"Replace gif thumbnails with the actual image."],"Replace JPG":[!1,"Replace jpg thumbnails with the actual image."],"Replace PNG":[!1,"Replace png thumbnails with the actual image."],"Replace WEBM":[!1,"Replace webm, mp4, and ogv thumbnails with the actual video. Probably will degrade browser performance ;)"],"Image Prefetching":[!0,"Add a shortcut icon to the header to turn on image preloading."],
|
||
"Fappe Tyme":[!0,"Hide posts without images when header menu item is checked. *hint* *hint*"],"Werk Tyme":[!0,"Hide all post images when header menu item is checked."],Autoplay:[!0,"Videos begin playing immediately when opened."],"Restart when Opened":[!1,"Restart GIFs and WebMs when you hover over or expand them."],"Show Controls":[!0,"Show controls on videos expanded inline."],"Click Passthrough":[!1,"Clicks on videos trigger your browser's default behavior. Videos can be contracted with button / dragging to the left.",1],"Allow Sound":[!0,"Open videos with the sound unmuted."],"Mouse Wheel Volume":[!0,"Adjust volume of videos with the mouse wheel over the thumbnail/filename/gallery."],"Loop in New Tab":[!0,"Loop videos opened in their own tabs."],"Volume in New Tab":[!0,`Apply ${e.name} mute and volume settings to videos opened in their own tabs.`],"Enable sound posts":[!0,"Enable loading audio from [sound=] file names. This audio is fetched from third parties."]},Menu:{
|
||
Menu:[!0,"Add a drop-down menu to posts."],"Report Link":[!0,"Add a report link to the menu.",1],"Copy Text Link":[!0,"Add a link to copy the post's text.",1],"Thread Hiding Link":[!0,"Add a link to hide entire threads.",1],"Reply Hiding Link":[!0,"Add a link to hide single replies.",1],"Delete Link":[!0,"Add post and image deletion links to the menu.",1],"Archive Link":[!0,"Add an archive link to the menu.",1],"Edit Link":[!0,"Add a link to edit the image in Tegaki, /i/'s painting program. Requires Quick Reply.",1],"Download Link":[!1,"Add a download with original filename link to the menu.",1]},Monitoring:{"Thread Updater":[!0,'Fetch and insert new replies. Has more options in the header menu and the "Advanced" tab.'],"Unread Count":[!0,"Show the unread posts count in the tab title."],"Quoted Title":[!1,"Change the page title to reflect you've been quoted.",1],"Hide Unread Count at (0)":[!1,"Hide the unread posts count in the tab title when it reaches 0.",1],
|
||
"Unread Favicon":[!0,"Show a different favicon when there are unread posts."],"Unread Line":[!0,"Show a line to distinguish read posts from unread ones."],"Remember Last Read Post":[!0,"Remember how far you've read after you close the thread."],"Scroll to Last Read Post":[!0,"Scroll back to the last read post when reopening a thread.",1],"Unread Line in Index":[!1,"Show a line between read and unread posts in threads in the index.",1],"Remove Thread Excerpt":[!1,"Replace the excerpt of the thread in the tab title with the board title."],"Thread Stats":[!0,"Display reply and image count."],"IP Count in Stats":[!0,"Display the unique IP count in the thread stats.",1],"Page Count in Stats":[!0,"Display the page count in the thread stats.",1],"Updater and Stats in Header":[!0,"Places the thread updater and thread stats in the header instead of floating them."],"Thread Watcher":[!0,"Bookmark threads. Has more options in the thread watcher menu."],
|
||
"Fixed Thread Watcher":[!0,"Makes the thread watcher scroll with the page.",1],"Persistent Thread Watcher":[!1,"The thread watcher will be visible when the page is loaded.",1],"Mark New IPs":[!1,"Label each post from a new IP with the thread's current IP count."],"Reply Pruning":[!0,"Add option in header menu to hide old replies in long threads. Activated by default in stickies."],"Prune All Threads":[!1,"Activate Reply Pruning by default in all threads.",1]},"Posting and Captchas":{"Quick Reply":[!0,"All-in-one form to reply, create threads, automate dumping and more."],"Persistent QR":[!1,"The Quick reply won't disappear after posting.",1],"Auto Hide QR":[!0,"Automatically hide the quick reply when posting.",2],"Open Post in New Tab":[!0,"Open new threads in a new tab, and open replies in a new tab if you're not already in the thread.",1],"Remember QR Size":[!1,"Remember the size of the Quick reply.",1],
|
||
"Remember Spoiler":[!1,"Remember the spoiler state, instead of resetting after posting.",1],"Randomize Filename":[!1,"Set the filename to a random timestamp within the past year. Disabled on /f/.",1],"Show New Thread Option in Threads":[!0,"Show the option to post a new / different thread from inside a thread.",1],"Show Upload Progress":[!0,"Track progress of file uploads as percentage in submit button.",1],Cooldown:[!0,"Indicate the remaining time before posting again.",1],"Posting Success Notifications":[!0,"Show notifications on successful post creation or file uploading.",1],"Auto-load captcha":[!1,"Automatically load the captcha in the QR even if your post is empty.",1],"Post on Captcha Completion":[!1,"Submit the post immediately when the captcha is completed.",1],"Force Noscript Captcha":[!1,"Use the non-Javascript fallback captcha even if Javascript is enabled."],"Pass Link":[!1,"Add a 4chan Pass login link to the bottom of the page."]},"Quote Links":{
|
||
"Quote Backlinks":[!0,"Add quote backlinks."],"OP Backlinks":[!0,"Add backlinks to the OP.",1],"Bottom Backlinks":[!1,"Place backlinks at the bottom of posts.",1],"Quote Inlining":[!0,"Inline quoted post on click."],"Inline Cross-thread Quotes Only":[!1,"Don't inline quote links when the posts are visible in the thread.",1],"Quote Hash Navigation":[!1,"Include an extra link after quotes for autoscrolling to quoted posts.",1],"Forward Hiding":[!0,"Hide original posts of inlined backlinks.",1],"Quote Previewing":[!0,"Show quoted post on hover."],"Quote Highlighting":[!0,"Highlight the previewed post.",1],"Resurrect Quotes":[!0,"Link dead quotes to the archives, and support inlining/previewing of archive links like quote links."],"Remember Your Posts":[!0,"Remember your posting history."],"Mark Quotes of You":[!0,"Add '(You)' to quotes linking to your posts.",1],"Highlight Posts Quoting You":[!0,"Highlights any posts that contain a quote to your post.",1],
|
||
"Highlight Own Posts":[!0,"Highlights own posts.",1],"Mark OP Quotes":[!0,"Add '(OP)' to OP quotes."],"Mark Cross-thread Quotes":[!0,"Add '(Cross-thread)' to cross-threads quotes."],"Quote Threading":[!0,"Add option in header menu to thread conversations."]}},imageExpansion:{"Fit width":[!0,""],"Fit height":[!1,""],"Scroll into view":[!0,"Scroll down when expanding images to bring the full image into view."],"Expand spoilers":[!0,"Expand all images along with spoilers."],"Expand videos":[!0,"Expand all images also expands videos."],"Expand from here":[!1,"Expand all images only from current position to thread end."],"Expand thread only":[!1,"In index, expand all images only within the current thread."],"Advance on contract":[!1,"Advance to next post when contracting an expanded image."]},gallery:{"Hide Thumbnails":[!1],"Fit Width":[!0],"Fit Height":[!0],"Stretch to Fit":[!1],"Scroll to Post":[!0],"Slide Delay":[6]},"Default Volume":1,threadWatcher:{
|
||
"Current Board":[!1,"Only show watched threads from the current board."],"Auto Update Thread Watcher":[!0,"Periodically check status of watched threads."],"Auto Watch":[!0,"Automatically watch threads you start."],"Auto Watch Reply":[!0,"Automatically watch threads you reply to."],"Auto Prune":[!1,"Automatically remove dead threads."],"Show Page":[!0,"Show what page watched threads are on."],"Show Unread Count":[!0,"Show number of unread posts in watched threads."],"Show Site Prefix":[!0,"When multiple sites are shown in the thread watcher, add a prefix to board names to distinguish them."],"Require OP Quote Link":[!1,"For purposes of thread watcher highlighting, only consider posts with a quote link to the OP as replies to the OP."]},filter:{general:"",postID:"# Highlight dubs on [s4s]:\n#/(\\d)\\1$/;highlight;top:no;boards:s4s",name:"# Filter any namefags:\n#/^(?!Anonymous$)/",uniqueID:"# Filter a specific ID:\n#/Txhvk1Tl/",tripcode:"# Filter any tripfag\n#/^!/",
|
||
capcode:"# Set a custom class for mods:\n#/Mod$/;highlight:mod;op:yes\n# Set a custom class for admins:\n#/Admin$/;highlight:admin;op:yes",pass:"# Filter anyone using since4pass:\n#/./",email:"",subject:"# Filter Generals on /v/:\n#/general/i;boards:v;op:only",comment:"# Filter Stallman copypasta on /g/:\n#/what you're refer+ing to as linux/i;boards:g\n# Filter posts with 20 or more quote links:\n#/(?:>>\\d(?:(?!>>\\d)[^])*){20}/\n# Filter posts like T H I S / H / I / S:\n#/^>?\\s?\\w\\s?(\\w)\\s?(\\w)\\s?(\\w).*$[\\s>]+\\1[\\s>]+\\2[\\s>]+\\3/im",flag:"",filename:"",dimensions:"# Highlight potential wallpapers:\n#/1920x1080/;op:yes;highlight;top:no;boards:w,wg",filesize:"",MD5:""},
|
||
sauces:'# Known filename formats:\nhttps://www.pixiv.net/member_illust.php?mode=medium&illust_id=%$1;regexp:/^(\\d+)_p\\d+/\njavascript:void(open("https://www.deviantart.com/"+%$1.replace(/_/g,"-")+"/art/"+parseInt(%$2,36)));regexp:/^\\w+_by_(\\w+)[_-]d([\\da-z]{6})\\b/\nhttps://imgur.com/%$1;regexp:/^(?![a-zA-Z][a-z]{6})(?![A-Z]{7})(?!\\d{7})([\\da-zA-Z]{7})(?: \\(\\d+\\))?\\.\\w+$/\nhttps://flickr.com/photo.gne?id=%$1;regexp:/^(\\d+)_[\\da-f]{10}(?:_\\w)*\\b/\nhttps://www.facebook.com/photo.php?fbid=%$1;regexp:/^\\d+_(\\d+)_\\d+_[no]\\b/\n\n# Reverse image search:\nhttps://www.google.com/searchbyimage?sbisrc=4chanx&image_url=%IMG&safe=off\nhttps://yandex.com/images/search?rpt=imageview&url=%IMG\n#//tineye.com/search?url=%IMG\n#//www.bing.com/images/search?q=imgurl:%IMG&view=detailv2&iss=sbi#enterInsights\n#https://lens.google.com/uploadbyurl?url=%IMG;text:lens\n\n# Specialized reverse image search:\n//iqdb.org/?url=%IMG\nhttps://trace.moe/?auto&url=%IMG;text:wait\n#//3d.iqdb.org/?url=%IMG\n#//saucenao.com/search.php?url=%IMG\n\n# "View Same" in archives:\nhttp://eye.swfchan.com/search/?q=%name;types:swf\n#https://desuarchive.org/_/search/image/%sMD5/\n#https://archive.4plebs.org/_/search/image/%sMD5/\n#https://boards.fireden.net/_/search/image/%sMD5/\n#https://foolz.fireden.net/_/search/image/%sMD5/\n\n# Other tools:\n#http://exif.regex.info/exif.cgi?imgurl=%URL\n#//imgops.com/start?url=%URL;types:gif,jpg,png\n#//www.gif-explode.com/%URL;types:gif',
|
||
FappeT:{werk:!1},"Custom CSS":!0,Index:{"Index Mode":"paged","Previous Index Mode":"paged","Index Size":"small","Show Replies":[!0,'Show replies in the index, and also in the catalog if "Catalog hover expand" is checked.'],"Catalog Hover Expand":[!1,"Expand the comment and show more details when you hover over a thread in the catalog."],"Catalog Hover Toggle":[!0,'Turn "Catalog hover expand" on and off by clicking in the catalog.'],"Pin Watched Threads":[!1,"Move watched threads to the start of the index."],"Anchor Hidden Threads":[!0,"Move hidden threads to the end of the index."],"Refreshed Navigation":[!1,"Refresh index when navigating through pages."]},Header:{"Fixed Header":!0,"Header auto-hide":!1,"Header auto-hide on scroll":!1,"Bottom Header":!1,"Centered links":!1,"Header catalog links":!1,"Bottom Board List":!0,"Shortcut Icons":!0,"Custom Board Navigation":!0},archives:{archiveLists:"https://4chenz.github.io/archives.json/archives.json",lastarchivecheck:0,archiveAutoUpdate:!0
|
||
},externalCatalogURLs:"//catalog.neet.tv/%board/;boards:4chan.org:3,a,adv,an,asp,biz,c,cgl,ck,cm,co,diy,f,fa,fit,g,gd,his,i,int,jp,k,lgbt,lit,m,mlp,mu,n,news,o,out,p,po,pol,s4s,sci,sp,tg,toy,trv,tv,v,vg,vip,vp,vr,w,wg,wsg,wsr,x",boardnav:`[ toggle-all ]\n[current-index-text:"Index"\ncurrent-catalog-text:"Catalog"\ncurrent-expired-text:"Expired"\ncurrent-archive-text:"Archive"]\n[external-text:"FAQ","${e.name}"]`,QR:{"QR.personas":'#options:"sage";boards:jp;always',sjisPreview:!1},jsWhitelist:"http://s.4cdn.org\nhttps://s.4cdn.org\nhttp://www.google.com\nhttps://www.google.com\nhttps://www.gstatic.com\nhttp://cdn.mathjax.org\nhttps://cdn.mathjax.org\nhttps://cdnjs.cloudflare.com\nhttps://hcaptcha.com\nhttps://*.hcaptcha.com\n'self'\n'unsafe-inline'\n'unsafe-eval'",captchaLanguage:"",time:"%m/%d/%y(%a)%H:%M:%S",timeLocale:"",backlink:">>%id",pastedname:"file",fileInfo:"%l %d (%p%s, %r%g)",favicon:"ferongr",
|
||
usercss:"/* Board title rice */\ndiv.boardTitle {\n font-weight: 400 !important;\n}\n:root.yotsuba div.boardTitle {\n font-family: sans-serif !important;\n text-shadow: 1px 1px 1px rgba(100,0,0,0.6);\n}\n:root.yotsuba-b div.boardTitle {\n font-family: sans-serif !important;\n text-shadow: 1px 1px 1px rgba(105,10,15,0.6);\n}\n:root.photon div.boardTitle {\n font-family: sans-serif !important;\n text-shadow: 1px 1px 1px rgba(0,74,153,0.6);\n}\n:root.tomorrow div.boardTitle {\n font-family: sans-serif !important;\n text-shadow: 1px 1px 1px rgba(167,170,168,0.6);\n}\n",hotkeys:{"Toggle board list":["Ctrl+b","Toggle the full board list."],"Toggle header":["Shift+h","Toggle the auto-hide option of the header."],"Open empty QR":["q","Open QR without post number inserted."],"Open QR":["Shift+q","Open QR with post number inserted."],"Open settings":["Alt+o","Open Settings."],Close:["Esc","Close dialogs or notifications."],"Spoiler tags":["Ctrl+s","Insert spoiler tags."],
|
||
"Code tags":["Alt+c","Insert code tags."],"Eqn tags":["Alt+e","Insert eqn tags."],"Math tags":["Alt+m","Insert math tags."],"SJIS tags":["Alt+a","Insert SJIS tags."],"Toggle sage":["Alt+s","Toggle sage in options field."],"Toggle Cooldown":["Alt+Comma","Toggle custom cooldown timer."],"Post from URL":["Alt+l","Post from URL."],"Add new post":["Alt+n","Add new post to the QR dump list."],"Submit QR":["Ctrl+Enter","Submit post."],Watch:["w","Watch thread."],Update:["r","Update the thread / refresh the index."],"Update thread watcher":["Shift+r","Manually refresh thread watcher."],"Toggle thread watcher":["t","Toggle visibility of thread watcher."],"Toggle threading":["Shift+t","Toggle threading."],"Mark thread read":["Ctrl+0",'Mark thread read from index (requires "Unread Line in Index").'],"Expand image":["Shift+e","Expand selected image."],"Expand images":["e","Expand all images."],"Open Gallery":["g","Opens the gallery."],
|
||
"Next Gallery Image":["Right","Go to the next image in gallery mode."],"Previous Gallery Image":["Left","Go to the previous image in gallery mode."],"Advance Gallery":["Enter","Go to next image or, if Autoplay is off, play video."],Pause:["p","Pause/play videos in the gallery."],Slideshow:["Ctrl+Right","Toggle the gallery slideshow mode."],"Rotate image clockwise":["Shift+Right","Rotate image clockwise in gallery."],"Rotate image anticlockwise":["Shift+Left","Rotate image anticlockwise in gallery."],"Download Gallery Image":["Shift+j","Download current image in gallery."],fappeTyme:["f","Toggle Fappe Tyme."],werkTyme:["Shift+w","Toggle Werk Tyme."],"Front page":["1","Jump to front page."],"Open front page":["Shift+1","Open front page in a new tab."],"Next page":["Ctrl+Right","Jump to the next page."],"Previous page":["Ctrl+Left","Jump to the previous page."],"Paged mode":["Alt+1","Open the index in paged mode."],
|
||
"Infinite scrolling mode":["Alt+2","Open the index in infinite scrolling mode."],"All pages mode":["Alt+3","Open the index in all threads mode."],"Open catalog":["Shift+c","Open the catalog of the current board."],"Search form":["Ctrl+Alt+s","Focus the search field on the board index."],"Cycle sort type":["Alt+x","Cycle through index sort types."],"Next thread":["Ctrl+Down","See next thread."],"Previous thread":["Ctrl+Up","See previous thread."],"Expand thread":["Ctrl+e","Expand thread."],"Open thread":["o","Open thread in current tab."],"Open thread tab":["Shift+o","Open thread in new tab."],"Next reply":["j","Select next reply."],"Previous reply":["k","Select previous reply."],"Deselect reply":["Shift+d","Deselect reply."],Hide:["x","Hide thread."],"Quick Filter MD5":["5","Add the MD5 of the selected image to the filter list."],"Previous Post Quoting You":["Alt+Up","Scroll to the previous post that quotes you."],
|
||
"Next Post Quoting You":["Alt+Down","Scroll to the next post that quotes you."]},updater:{checkbox:{Beep:[!1,"Beep on new post to completely read thread."],"Beep Quoting You":[!1,"Beep on new post quoting you."],"Auto Scroll":[!1,"Scroll updated posts into view. Only enabled at bottom of page."],"Bottom Scroll":[!1,"Always scroll to the bottom, not the first new post. Useful for event threads."],"Scroll BG":[!1,"Auto-scroll background tabs."],"Auto Update":[!0,"Automatically fetch new posts."],"Optional Increase":[!1,"Increase the intervals between updates on threads without new posts."]},Interval:5},customCooldown:0,customCooldownEnabled:!0,"Thread Quotes":!1,"Max Replies":1e3,"Autohiding Scrollbar":!1,position:{"embedding.position":"top: 50px; right: 0px;","thread-stats.position":"bottom: 0px; right: 0px;","updater.position":"bottom: 0px; left: 0px;","thread-watcher.position":"top: 50px; left: 0px;","qr.position":"top: 50px; right: 0px;"},fourchanImageHost:"i.4cdn.org",
|
||
hiddenPSAList:[{}],
|
||
knownBanners:["0.jpg","1.jpg","2.jpg","4.jpg","6.jpg","7.jpg","8.jpg","9.jpg","10.jpg","11.jpg","12.jpg","13.jpg","14.jpg","16.jpg","17.jpg","18.jpg","19.jpg","20.jpg","21.jpg","22.jpg","24.jpg","25.jpg","26.jpg","28.jpg","29.jpg","33.jpg","38.jpg","39.jpg","43.jpg","44.jpg","45.jpg","46.jpg","47.jpg","52.jpg","54.jpg","57.jpg","59.jpg","60.jpg","61.jpg","64.jpg","66.jpg","67.jpg","69.jpg","71.jpg","72.jpg","76.jpg","77.jpg","81.jpg","82.jpg","83.jpg","84.jpg","88.jpg","90.jpg","91.jpg","96.jpg","98.jpg","99.jpg","100.jpg","104.jpg","106.jpg","116.jpg","119.jpg","137.jpg","140.jpg","148.jpg","149.jpg","150.jpg","154.jpg","156.jpg","157.jpg","158.jpg","159.jpg","161.jpg","162.jpg","164.jpg","165.jpg","166.jpg","167.jpg","168.jpg","169.jpg","170.jpg","171.jpg","172.jpg","173.jpg","174.jpg","175.jpg","176.jpg","178.jpg","179.jpg","180.jpg","181.jpg","182.jpg","183.jpg","186.jpg","189.jpg","190.jpg","192.jpg","193.jpg","194.jpg","197.jpg","198.jpg","200.jpg","201.jpg","202.jpg","203.jpg","205.jpg","206.jpg","207.jpg","208.jpg","210.jpg","213.jpg","214.jpg","215.jpg","216.jpg","218.jpg","219.jpg","220.jpg","221.jpg","222.jpg","223.jpg","224.jpg","227.jpg","0.png","1.png","2.png","3.png","5.png","6.png","9.png","10.png","11.png","12.png","14.png","16.png","19.png","20.png","21.png","22.png","23.png","24.png","26.png","27.png","28.png","29.png","30.png","31.png","32.png","33.png","34.png","37.png","39.png","40.png","41.png","42.png","43.png","44.png","45.png","48.png","49.png","50.png","51.png","52.png","53.png","57.png","58.png","59.png","64.png","66.png","67.png","68.png","69.png","70.png","71.png","72.png","76.png","78.png","79.png","81.png","82.png","85.png","86.png","87.png","89.png","95.png","98.png","100.png","101.png","102.png","105.png","106.png","107.png","109.png","110.png","111.png","112.png","113.png","114.png","115.png","116.png","118.png","119.png","120.png","121.png","122.png","123.png","126.png","128.png","130.png","134.png","136.png","138.png","139.png","140.png","142.png","145.png","146.png","149.png","150.png","151.png","152.png","153.png","154.png","155.png","156.png","157.png","158.png","159.png","160.png","163.png","164.png","165.png","166.png","167.png","168.png","169.png","170.png","171.png","172.png","173.png","174.png","178.png","179.png","180.png","181.png","182.png","184.png","186.png","188.png","190.png","192.png","193.png","194.png","195.png","196.png","197.png","198.png","200.png","202.png","203.png","205.png","206.png","207.png","209.png","212.png","213.png","214.png","216.png","217.png","218.png","219.png","220.png","221.png","222.png","223.png","224.png","225.png","226.png","229.png","231.png","232.png","233.png","234.png","235.png","237.png","238.png","239.png","240.png","241.png","242.png","244.png","245.png","246.png","247.png","248.png","249.png","250.png","253.png","254.png","255.png","256.png","257.png","258.png","259.png","260.png","262.png","268.png","0.gif","1.gif","2.gif","3.gif","4.gif","5.gif","6.gif","7.gif","8.gif","9.gif","10.gif","12.gif","13.gif","14.gif","15.gif","16.gif","18.gif","19.gif","20.gif","21.gif","22.gif","23.gif","24.gif","28.gif","29.gif","30.gif","33.gif","34.gif","35.gif","36.gif","37.gif","39.gif","40.gif","42.gif","44.gif","45.gif","46.gif","48.gif","50.gif","52.gif","54.gif","55.gif","57.gif","58.gif","59.gif","60.gif","61.gif","63.gif","64.gif","66.gif","67.gif","68.gif","69.gif","70.gif","72.gif","73.gif","75.gif","76.gif","77.gif","78.gif","80.gif","81.gif","82.gif","83.gif","86.gif","87.gif","88.gif","92.gif","93.gif","94.gif","95.gif","96.gif","97.gif","98.gif","99.gif","100.gif","101.gif","102.gif","103.gif","104.gif","105.gif","106.gif","108.gif","109.gif","110.gif","111.gif","112.gif","113.gif","115.gif","116.gif","117.gif","118.gif","119.gif","120.gif","122.gif","123.gif","124.gif","127.gif","129.gif","130.gif","131.gif","134.gif","135.gif","136.gif","138.gif","139.gif","141.gif","144.gif","146.gif","148.gif","149.gif","153.gif","154.gif","155.gif","157.gif","158.gif","159.gif","160.gif","161.gif","162.gif","164.gif","166.gif","167.gif","168.gif","169.gif","170.gif","171.gif","172.gif","173.gif","174.gif","175.gif","176.gif","177.gif","178.gif","181.gif","182.gif","183.gif","185.gif","186.gif","187.gif","188.gif","189.gif","190.gif","191.gif","192.gif","193.gif","195.gif","196.gif","197.gif","200.gif","201.gif","202.gif","203.gif","204.gif","205.gif","206.gif","207.gif","208.gif","209.gif","210.gif","211.gif","212.gif","213.gif","214.gif","215.gif","216.gif","217.gif","219.gif","220.gif","221.gif","222.gif","224.gif","225.gif","226.gif","227.gif","228.gif","230.gif","232.gif","233.gif","234.gif","235.gif","238.gif","240.gif","241.gif","243.gif","244.gif","245.gif","246.gif","247.gif","249.gif","250.gif","251.gif","253.gif"].join(","),
|
||
passMessageClosed:!1,"Prerequest Captcha":!1,PSAseen:[[]]};var h={init:()=>Ve.asap((()=>a.head&&(h.el=Ve('link[rel="shortcut icon"]',a.head))),h.initAsap),set(e){if(h.status=e,h.el)return h.el.href=h[e],Ve.add(a.head,h.el)},initAsap(){h.el.type="image/x-icon";const{href:e}=h.el;if(h.isSFW=/ws\.ico$/.test(e),h.default=e,h.switch(),h.status)return h.set(h.status)},switch(){let e={
|
||
ferongr:["iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///9zBQC/AADpDAP/gID/q6voCwJJTwpOAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxUlEQVR42q1TOwrCQBB9s0FRtJI0WoqFtSLYegoP4gVSeJsUHsHSI3iFeIqRXXgwrhlXwYHHhLwPTB7B36abBCV+0pA4DUBQUNZYQptGtW3jtoKyxgoe0yrBCoyZfL/5ioQ3URZOXW9I341l3oo+NXEZiW4CEuIzvPECopED4OaZ3RNmeAm4u+a8Jr5f17VyVoL8fr8qcltzwlyyj2iqcgPOQ9ExkHAITgD75bYBe0A5S4H/P9htuWMF3QXoQpwaKeT+lnsC6JE5I6aq6fEAAAAASUVORK5CYII=","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///8AcH4AtswA2PJ55fKi6fIA1/FtpPADAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxElEQVQ4y2NgoBq4/vE/HJOsBiRQUIfA2AzBqQYqUfn00/9FLz+BaQxDCKqBmX7jExijKEDSDJPHrnnbGQhGV4RmOFwdVkNwhQMheYwQxhaIi7b9Z9A3gWAQm2BUoQOgRhgA8o7j1ozLC4LCyAZcx6kZI5qg4kLKqggDFFWxJySsUQVzlb4pwgAJaTRvokcVNgOqOv8zcHBCsL07DgNg8YsczzA5MxtUL+DMD8g0slxI/H8GQ/P/DJKyeKIRpglXZsIiBwBhP5O+VbI/JgAAAABJRU5ErkJggg==","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///8oeQBJ3ABV/wHM/7Lu/+ZU/gAqUP3dAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAx0lEQVQ4y2NgoBYI+cfwH4ZJVgMS0KhEYGyG4FQDkzjzf9P/d/+fgWl0QwiqgSkI/c8IxsgKkDXD5LFq9rwDweiK0A2HqcNqCK5wICSPEcLYAtH+AMN/IXMIBrEJRie6OEgjDAC5x3FqxuUFNiEUA67j1IweTTBxBQ1puAG86jgSEraogskJWSBcwCGF5k30qMJmgMFEhv/MXBAs5oLDAFj8IsczTE7UEeECbhU8+QGZRpaTi2b4L2zF8J9TGk80wjThykzY5AAW/2O1C2mIbgAAAABJRU5ErkJggg=="],
|
||
"xat-":["iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAG1BMVEX+AACLkZFub2yfaF3zZGIAAAD/AAD/iYr/zs8IPcF6AAAABXRSTlMAeprJ7xzg6IEAAABZSURBVAjXY2DABKGBSkqioQwMrGmpxsZhaQEMDGFpIa5pqSCRtPDSNJBIaGh5eShQDYOye0V7iREKAyQFYoiCFAcyILQDGcGmEEZYkGoqiMHKysAQEICwGwAAjBmBqhYlagAAAABJRU5ErkJggg==","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAPFBMVEUAAACEgoBva2ilamDxcG7IaWYgFBNOSEf//f0PDQwBAAA7LCwAAAD/AAD+hIX+m5z+zc5HAADPAAAGAADl032uAAAADHRSTlMAzNv0/vz+6v3+7ALrmfyXAAAAaUlEQVQY042PyxKAIAhFAc1eV7T6/3/N8VXOtAgWwBm4ANEPA8AswpySXHvvYZLlpBNrh9pDtcSqAQ1BUTVIjNUQY5icmwfglmXNgE0d6QBF9GigrU0A9LoM53U1kFzk6SBQuWfD/vHqDUCpBmVKTTM4AAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIVBMVEUAAACRjop4dXVpZ2tdcI9dfKdisfMAAAAumMN9xv+s2/+PADT2AAAAB3RSTlMAepGdv83v3HIc4QAAAFxJREFUCNdjYMAE5YXKRuLlDAzsHe2uIRUdBQwMFR1l6R3tIJGOyukdIJHy8lkry4FqGEwzV62aFozMUAFJOQEZ4iDFhQwI7UBGaTiEUVFs3g5isLMzMBQUIOwGAJRlIu9hk08QAAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEUAAACAgYVlc4ljsu4AAAAAAAAAAAAumMODyP6b1P6e1f/g8v89msgSIiwNFxwbPU3tQYj5AAAABnRSTlMAxej+9VTmD9ciAAAAZElEQVQI12NgwARpiUKKYmkMDGzlZUpK6eUJDAzp5clm5WUgkfKMtnKQSFpa54o0oBoGJYvZO88+gjJu7wMyhIBS2SCGGFDxaxADpP32NjAjSe0bSFd6epIaWISNjYEhJRVhNwAGlyJpYtcvcAAAAABJRU5ErkJggg==","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAHlBMVEUfJSCRi5Frbm9dn19082KR/30AAABmzDOq/5vZ/9Gt/vt2AAAABnRSTlMAe5rJ7/4vxEp4AAAAWUlEQVQI12NgwARpiUpKYmkMDGzlZcbG6eUJDAzp5Slu5WUgkfLUsHKQSFpaRGsaUA2DsmvnjBAjFAZICsQQAylOZEBoBzKSzSCM9CS1MhCDjY2BISEBYTcAtgAcKSK2vuIAAAAASUVORK5CYII=","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAM1BMVEUAAACBj39tfm1qj2RepFlu2VQAAQAAAAAAAABmyzOX/oSr/pus/pzk/98PGgtatC4CBAI1ENblAAAACHRSTlMA09/p9v77ig0SBcQAAABnSURBVBjTjY9LDsAgCEQRsR2xWu9/2hK/adJFYQG8wABEPwyAYzNnSatjjPAiviWLhPCqI1R7HBrQdCmGBrEETTmnUAq/QMm5dODHyAQOXXR1zLUGsIEI7lonMGfeHQTq9xw4P159AIxSBSC53km7AAAAAElFTkSuQmCC"],
|
||
Mayhem:["iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABFklEQVR4AZ2R4WqEMBCEFy1yiJQQ14gcIhIuFBFR+qPQ93+v66QMksrlTwMfkZ2ZZbMKTgVqYIDl3YAbeCM31lJP/Zul4MAEPJjBQGNDLGsz8PQ6aqLAP5PTdd1WlmU09mSKtdTDRgrkzspJPKq6RxMahfj9yhOzQEZwZAwfzrk1ox3MXibIN8hO4MAjeV72CemJGWblnRsOYOdoGw0jebB20BPAwKzUQPlrFhrXFw1Wagu9yuzZwINzVAZCURRL+gRr7Wd8Vtqg4Th/lsUmewyk9WQ/A7NiwJz5VV/GmO+MNjMrFvh/NPDMigHTaeJN09a27ZHRJmalBg54CgfvAGYSLpoHjlmpuAwFdzDy7oGS/qIpM9UPFGg1b1kUlssAAAAASUVORK5CYII=","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABR0lEQVR4AYWSQWq0QBCFCw0SRIK0PQ4hiIhEZBhEySLyewUPEMgqR/JIXiDhzz7kKKYePIZajEzDRxfV9dWU3SO6IiVWUsVxT5R75Y4gTmwNnUh4kCulUiuV8sjChDjmKtaUcHgmHsnNrMPh0IVhiMIjKZGzNXDoyhMzF7C89z2KtFGD+FoNXEUKZdgpaPM8P++cDXTtBDca7EyQK8+bXTufYBccuvLAG26UnqN1LCgI4g/lm7zTgSux4vk0J8rnKw3+m1//pBPbBrVyGZVNmiAITviEtm3t+D+2QcJx7GUxlN4594K4ZY75Xzh0JVWqnad6TdP0H+LRNBjHcYNDV5xS32qwaC4my7Lwn6guu5QoomgbdFmWDYhnM8E8zxscuhLzPWtKA/dGqUizrityX9M0YX+DQ1ciXobnP6vgfmTOM7Znnk70B58pPaEvx+epAAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/ElEQVR4AZ3RUWqEMBSF4ftQZAhSREQJIiIXpQwi+tSldkFdWPsLhyEE0ocKH2Fyzg1mNJ4KAQ1arTUeeJMH6qwTUJmCHjMcC6KKtbSIylzdXpl18J/k4fdTpUFmPLOOa9bGe+P4+n5RYYfLXuiMsAlXofBxK2QXpvwN/jqg+AY91vR+pStk+apZe0fEhhMXDhUmWXEoO9WNmrWAzvRPq7jnB2jvUGfWTEgPcJzZFTbZk/0Tnh5QI+af6lVGvq/Do2atwVL4VJ+3QrZo1lr4Pw5wzVqDWaV7SUvHrZDNmrWAHq7g0rphkS3LXDMBVqFGhxGT1gGdDFnWaab6BRmXRvbxDmYiAAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4AY2SQUrEQBBFS9CMNFEkhAQdYmiCIUgcZlYGc4VsBcGVF/AuWXme4F7RtXiVWF9+Y9MYtOHRTdX/NZWaEj2RYpQTJeEdK4fKPuA7DjSGXiQkU0qlUqxySmFMEsYsNSU8zEmK4OwdEbmkKCclYoGmolfWCGyenh1O0EJE2gXNWpFC2S0IGrCQ29EbdPCPAmEHmXIxByf8hDAPD71yzAnXypatbSgoAN8Pyju5h4deMUrqJk1z+0uBN+/XX+gxfoFK2QafUJO2aRq//Q+/QIx2wr+Kwq0rusrP/QKf9MTCtbQLf9U1wNvYnz3qug45S68kSvVXgbPbx3nvYPXNOI7cRPWySukK+DcGCvA+urqZ3RmGAbmSXjFK5rpwW8nhWVJP04TYa9/3uO/goVciDiPlZhW8c8ZAHuRSeqIv32FK/GYGL8YAAAAASUVORK5CYII=","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/ElEQVR4AZ3RUWqEMBSF4ftQZAihDCKKiAQJShERQx+6o662e2p/4TCEQF468BEm95yLovFr4PBEq9PjgTd5wBcZp6559AiIWDAq6KXV3aJMUMfDOsTf7Mf/XaFBAvYiE9W16b74/vl8UeBAlKOSmWAzUiXwcavMkrrFE9QXVJ+gx5q9XvUVivmqrr1jxIYLCacCs6y6S8psGNU1hw4Bu4JHuUB3pzJBHZcviLiKV9jkyO4vxHyBx1h+qlcY5b2Wj+raE0vlU33dKrNFXWsR/7EgqmtPBIXuIw+dt8osqGsOPaIGSeeGRbZiFtVxsAYeHSbMOgd0MhSzTp3mD4RaQX4aW3NMAAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABP0lEQVR4AYWS0UqFQBCGhziImNRBRImDmUgiIaF0kWSP4AMEXXXTE/QiPpL3UdR19Crb/PAvLEtyFj5mmfn/cdxd0RUokbJXEsZYCZUd4D72NBG8wkKmlEqtVMoFhTFJmKuoKelBTVIkjbNE5IainJTIeZqaXjkg8fp+Z7GCjiLQbWgOihTKsCFowUZtoNef4HgDf4JMuTbe8n/Br8NDr5zxhBul52i3FBQE+xflmzzTA69ESmpPmubunwZfztc/6IncBrXSe7/QkK5tW3f8H7dBjHH8q6Kwt033V6Hb4JeeWPgsq42rugfYZ92psWscRwMPvZIo9bEGD2+F2YUnBizLwpeoXnYpbQM34kAB9peP58aueZ4NPPRKxPusaRoYG6UizbquyH1O04T4RA+8EvAwUr6sgjFnDuReLaUn+ANygUa7+9SCWgAAAABJRU5ErkJggg=="],
|
||
"4chanJS":["iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAD/AABnZ2f///8nFk05AAAAAXRSTlMAQObYZgAAAEFJREFUeNqNjgEKACAMAjvX/98cAkkxgmSgO8Bt/Ai4ApJ6KKhzF3OiEMDASrGB/QWgPEHsUpN+Ng9xAETMYhDrWmeHAMcmvycWAAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAD1BMVEUAAAAAAAD/AABmZmYA/wBD99DBAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAE9JREFUCNdljcsRACEIQ5MOiNKAdGAJ9N/Uiu7nsMzABHgB4B8ygFoZA2hhVWavhhGeURPJU9q45+17hGbfGxa82Ndex3hEM44SJGD2/b4AzDgGlHbl388AAAAASUVORK5CYII=","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAAul8NnZ2f////82iC9AAAAAXRSTlMAQObYZgAAAEFJREFUeNqNjgEKACAMAjvX/98cAkkxgmSgO8Bt/Ai4ApJ6KKhzF3OiEMDASrGB/QWgPEHsUpN+Ng9xAETMYhDrWmeHAMcmvycWAAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAD1BMVEUAAAAAAAAul8NnZ2f/AAD7B+mqAAAAAXRSTlMAQObYZgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAE9JREFUCNdljcsRACEIQ5MOiNKAdGAJ9N/Uiu7nsMzABHgB4B8ygFoZA2hhVWavhhGeURPJU9q45+17hGbfGxa82Ndex3hEM44SJGD2/b4AzDgGlHbl388AAAAASUVORK5CYII=","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAElBMVEUBAAAAAABmzDNlyjJnZ2f///+6o7dfAAAAAXRSTlMAQObYZgAAAERJREFUeF6NjkEKADEIA51o///lJZfQxUsHITogWi8AvwZJuxmYa25xDooBLEwOWFTYAsYVhdorLZt9Ng9xCUTCUCQ2H3F4ANrZ2WNiAAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAD1BMVEUAAAAAAABmzDNmZmb/AAC8/wCMAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAE9JREFUCNdljcsRACEIQ5MOiNKAdGAJ9N/Uiu7nsMzABHgB4B8ygFoZA2hhVWavhhGeURPJU9q45+17hGbfGxa82Ndex3hEM44SJGD2/b4AzDgGlHbl388AAAAASUVORK5CYII="],
|
||
Original:["iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX/////AAD///8AAABBZmS3AAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII=","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhElEQVR42q1RwQnAMAjMu5M4guAKXa4j5dUROo5tipSDcrFChUONd0di2m/hEGVOHDyIPufgwAFASDkpoSzmBrkJ2UMyR9LsJ3rvrqo3Rt1YMIMhhNnOxLMnoMFBxHyJAr2IOBFzA8U+6pLBdmEJTA0aMVjpDd6Loks0s5HZNwYx8tfZCZ0kll7ORffZAAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX///8ul8P///8AAACaqgkzAAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII=","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAABBQcHFx4KISoNLToaVW4oKCgul8M4ODg7OzvBwcH///8uS/CdAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eILZO5/XI0UAgm7H9tOsu0yGWAQSOoFijHOxOANGqm/LczpOaXs4gISrPZ+gc2+hO5w2xdwgOjBFUIF+sEJrhUl9JFr+badFwR+BfqlmGUJAAAAAElFTkSuQmCC","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX///9mzDP///8AAACT0n1lAAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII=","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAAECAIQIAgWLAsePA8oKCg4ODg6dB07OztmzDPBwcH///+rsf3XAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eIDhbn/cTVSCCTsfmw7ybbLZIBBIKkXKKU0E4M3aKT+tjCn5xiziwuIsNr7BTb7ErrDZV/AAaIHdwgV6AcnuFaU0Eeu5dt2XiUyBjCQ2bIrAAAAAElFTkSuQmCC"],
|
||
Metro:["iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAC/AABrZQDiAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAC/AAD///8dAAApAABsAAAHAAA4AACQAAAsAABMCpCvAAAAA3RSTlMAPse+s4iwAAAAMklEQVQI12NggAFmY2MDECaNAQZCilAzVJyg5oS4GqAxUtygjIp2KGOKJ5SxepcB3BUAcdYRqxAtgFoAAAAASUVORK5CYII=","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAAA1/GhpCidAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAAA1/H///8AISUALzQAeokACAkAQEcAorYAMTcE9WFNAAAAA3RSTlMAPse+s4iwAAAAMklEQVQI12NggAFmY2MDECaNAQZCilAzVJyg5oS4GqAxUtygjIp2KGOKJ5SxepcB3BUAcdYRqxAtgFoAAAAASUVORK5CYII=","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAABV/wErM5hwAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==","iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAABV/wH///8NKAASOAAwkQADCgAZTABAwQATOwC5e3VGAAAAA3RSTlMAPse+s4iwAAAAMklEQVQI12NggAFmY2MDECaNAQZCilAzVJyg5oS4GqAxUtygjIp2KGOKJ5SxepcB3BUAcdYRqxAtgFoAAAAASUVORK5CYII="]
|
||
};e=Ve.getOwn(e,t.favicon);const n=h;let o=0;for(;e[o];)e[o]="data:image/png;base64,"+e[o++];return[n.unreadDead,n.unreadDeadY,n.unreadSFW,n.unreadSFWY,n.unreadNSFW,n.unreadNSFWY]=e,n.update()},update(){return this.isSFW?(this.unread=this.unreadSFW,this.unreadY=this.unreadSFWY):(this.unread=this.unreadNSFW,this.unreadY=this.unreadNSFWY)},SFW:"//s.4cdn.org/image/favicon-ws.ico",NSFW:"//s.4cdn.org/image/favicon.ico",dead:"data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==",logo:"data:image/png;base64,R0lGODlhEAAQAJEAAAAAAP///9vb2////yH5BAEAAAMALAAAAAAQABAAAAIvnI+pq+D9DBAUoFkPFnbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw=="};const u=(e,t=a.body)=>Array.from(t.querySelectorAll(e)),p={init(){if(!("yotsuba"!==n.SITE.software||a.cookie.indexOf("pass_enabled=1")>=0)){
|
||
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"]}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,
|
||
this.ipCount=void 0,this.json=null,this.OP=null,this.catalogView=null,this.nodes={root:null},this.board.threads.push(this.ID,this),n.threads.push(this.fullID,this)}setPage(e){let t;const{info:n,reply:o}=this.OP.nodes;if((t=Ve(".page-num",n))||(t=Ve.el("span",{className:"page-num"}),Ve.replace(o.parentNode.previousSibling,[Ve.tn(" "),t,Ve.tn(" ")])),t.title=`This thread is on page ${e} in the original index.`,t.textContent=`[${e}]`,this.catalogView)return this.catalogView.nodes.pageCount.textContent=e}setCount(e,t,n){if(!this.catalogView)return;const o=this.catalogView.nodes[`${e}Count`];return o.textContent=t,(n?Ve.addClass:Ve.rmClass)(o,"warning")}setStatus(e,t){const n=`is${e}`;if(this[n]!==t&&(this[n]=t,this.OP))return this.setIcon("Sticky",this.isSticky),this.setIcon("Closed",this.isClosed&&!this.isArchived),this.setIcon("Archived",this.isArchived)}setIcon(e,t){const o=e.toLowerCase();let a=Ve(`.${o}Icon`,this.OP.nodes.info);if(!!a===t)return;if(!t)return Ve.rm(a.previousSibling),
|
||
Ve.rm(a),void(this.catalogView&&Ve.rm(Ve(`.${o}Icon`,this.catalogView.nodes.icons)));a=Ve.el("img",{src:`${n.SITE.Build.staticPath}${o}${n.SITE.Build.gifIcon}`,alt:e,title:e,className:`${o}Icon retina`}),"f"===n.BOARD.ID&&(a.style.cssText="height: 18px; width: 18px;");const i="Sticky"!==e&&this.isSticky?Ve(".stickyIcon",this.OP.nodes.info):Ve(".page-num",this.OP.nodes.info)||this.OP.nodes.quote;return Ve.after(i,[Ve.tn(" "),a]),this.catalogView?("Sticky"===e&&this.isClosed?Ve.prepend:Ve.add)(this.catalogView.nodes.icons,a.cloneNode()):void 0}kill(){return this.isDead=!0}collect(){let e=0;if(this.posts.forEach((function(t){return t.clones.length?e++:t.collect()})),!e)return n.threads.rm(this.fullID),this.board.threads.rm(this)}}class C{toString(){return this.ID}constructor(e,t){this.thread=t,this.ID=this.thread.ID,this.board=this.thread.board;const{post:n}=this.thread.OP.nodes;this.nodes={root:e,thumb:Ve(".catalog-thumb",n),icons:Ve(".catalog-icons",n),postCount:Ve(".post-count",n),
|
||
fileCount:Ve(".file-count",n),pageCount:Ve(".page-count",n),replies:null},this.thread.catalogView=this}}var D=function(){let e,t;return D=class{static initClass(){e=null,t=null}constructor(e){this.setPosition=this.setPosition.bind(this),this.close=this.close.bind(this),this.keybinds=this.keybinds.bind(this),this.onFocus=this.onFocus.bind(this),this.addEntry=this.addEntry.bind(this),this.type=e,Ve.on(a,"AddMenuEntry",(({detail:e})=>{if(e.type===this.type)return delete e.open,this.addEntry(e)})),this.entries=[]}makeMenu(){const e=Ve.el("div",{className:"dialog",id:"menu",tabIndex:0});return e.dataset.type=this.type,Ve.on(e,"click",(e=>e.stopPropagation())),Ve.on(e,"keydown",this.keybinds),e}toggle(n,o,a){if(n.preventDefault(),n.stopPropagation(),e){const n=t;if(e.close(),n===o)return}if(this.entries.length)return this.open(o,a)}open(n,o){let i;const r=this.menu=this.makeMenu();for(i of(e=this,t=n,this.entries.sort(((e,t)=>e.order-t.order)),this.entries))this.insertEntry(i,r,o)
|
||
;return Ve.addClass(t,"active"),Ve.on(a,"click CloseMenu",this.close),Ve.on(a,"scroll",this.setPosition),Ve.on(window,"resize",this.setPosition),Ve.after(n,r),this.setPosition(),i=Ve(".entry",r),this.focus(i),r.focus()}setPosition(){const e=this.menu.getBoundingClientRect(),n=t.getBoundingClientRect();window.scrollY,n.top,window.scrollX,n.left;const o=i.clientHeight,a=i.clientWidth,[r,s]=n.top+n.height+e.height<o?[`${n.bottom}px`,""]:["",o-n.top+"px"],[l,d]=n.left+e.width<a?[`${n.left}px`,""]:["",a-n.right+"px"];return Ve.extend(this.menu.style,{top:r,right:d,bottom:s,left:l}),this.menu.classList.toggle("left",d)}insertEntry(e,t,n){let o;if("function"==typeof e.open)try{if(!e.open(n))return}catch(e){return void Ot.handleErrors({message:`Error in building the ${this.type} menu.`,error:e})}if(Ve.add(t,e.el),e.subEntries){for(var a of((o=Ve(".submenu",e.el))&&Ve.rm(o),o=Ve.el("div",{className:"dialog submenu"}),e.subEntries))this.insertEntry(a,o,n);Ve.add(e.el,o)}}close(){
|
||
return Ve.rm(this.menu),delete this.menu,Ve.rmClass(t,"active"),e=null,t=null,Ve.off(a,"click scroll CloseMenu",this.close),Ve.off(a,"scroll",this.setPosition),Ve.off(window,"resize",this.setPosition)}findNextEntry(e,t){const n=[...e.parentNode.children];return n.sort(((e,t)=>e.style.order-t.style.order)),n[n.indexOf(e)+t]}keybinds(e){let n,o,a,i=Ve(".focused",this.menu);for(;n=Ve(".focused",i);)i=n;switch(e.keyCode){case 27:t.focus(),this.close();break;case 13:case 32:i.click();break;case 38:(o=this.findNextEntry(i,-1))&&this.focus(o);break;case 40:(o=this.findNextEntry(i,1))&&this.focus(o);break;case 39:if((a=Ve(".submenu",i))&&(o=a.firstElementChild)){let e;for(;e=this.findNextEntry(o,-1);)o=e;this.focus(o)}break;case 37:(o=Ve.x('parent::*[contains(@class,"submenu")]/parent::*',i))&&this.focus(o);break;default:return}return e.preventDefault(),e.stopPropagation()}onFocus(e){return e.stopPropagation(),this.focus(e.target)}focus(e){let t,n
|
||
;for(;t=Ve.x('parent::*/child::*[contains(@class,"focused")]',e);)Ve.rmClass(t,"focused");for(t of u(".focused",e))Ve.rmClass(t,"focused");if(Ve.addClass(e,"focused"),!(n=Ve(".submenu",e)))return;const o=n.getBoundingClientRect(),a=e.getBoundingClientRect(),r=i.clientHeight,s=i.clientWidth,[l,d]=a.top+o.height<r?["0px","auto"]:["auto","0px"],[c,h]=a.right+o.width<s-150?["100%","auto"]:["auto","100%"],{style:p}=n;return p.top=l,p.bottom=d,p.left=c,p.right=h}addEntry(e){return this.parseEntry(e),this.entries.push(e)}parseEntry(e){const{el:t,subEntries:n}=e;if(Ve.addClass(t,"entry"),Ve.on(t,"focus mouseover",this.onFocus),t.style.order=e.order||100,n)for(var o of(Ve.addClass(t,"has-submenu"),n))this.parseEntry(o)}},D.initClass(),D}(),E=function(e){let n;if("mousedown"===e.type&&0!==e.button)return;e.preventDefault(),(n="touchstart"===e.type)&&(e=e.changedTouches[e.changedTouches.length-1])
|
||
;const o=Ve.x('ancestor::div[contains(@class,"dialog")][1]',this),r=o.getBoundingClientRect(),s=i.clientHeight,l=i.clientWidth,d={id:o.id,style:o.style,dx:e.clientX-r.left,dy:e.clientY-r.top,height:s-r.height,width:l-r.width,screenHeight:s,screenWidth:l,isTouching:n};return[d.topBorder,d.bottomBorder]=t["Header auto-hide"]||!t["Fixed Header"]?[0,0]:t["Bottom Header"]?[0,Ke.bar.getBoundingClientRect().height]:[Ke.bar.getBoundingClientRect().height,0],n?(d.identifier=e.identifier,d.move=S.bind(d),d.up=R.bind(d),Ve.on(a,"touchmove",d.move),Ve.on(a,"touchend touchcancel",d.up)):(d.move=T.bind(d),d.up=B.bind(d),Ve.on(a,"mousemove",d.move),Ve.on(a,"mouseup",d.up))},S=function(e){for(var t of e.changedTouches)if(t.identifier===this.identifier)return void T.call(this,t)},T=function(e){const{clientX:t,clientY:n}=e;let o=t-this.dx;o=o<10?0:this.width-o<10?"":o/this.screenWidth*100+"%";let a=n-this.dy
|
||
;a=a<10+this.topBorder?this.topBorder+"px":this.height-a<10+this.bottomBorder?"":a/this.screenHeight*100+"%";const i=""===o?0:"",r=""===a?this.bottomBorder+"px":"",{style:s}=this;return s.left=o,s.right=i,s.top=a,s.bottom=r},R=function(e){for(var t of e.changedTouches)if(t.identifier===this.identifier)return void B.call(this)},B=function(){return this.isTouching?(Ve.off(a,"touchmove",this.move),Ve.off(a,"touchend touchcancel",this.up)):(Ve.off(a,"mousemove",this.move),Ve.off(a,"mouseup",this.up)),Ve.set(`${this.id}.position`,this.style.cssText)};const P=function({root:e,el:t,latestEvent:n,endEvents:o,height:r,width:s,cb:l,noRemove:d}){const c=e.getBoundingClientRect(),h={root:e,el:t,style:t.style,isImage:["IMG","VIDEO"].includes(t.nodeName),cb:l,endEvents:o,latestEvent:n,clientHeight:i.clientHeight,clientWidth:i.clientWidth,height:r,width:s,noRemove:d,clientX:(c.left+c.right)/2,clientY:(c.top+c.bottom)/2};return h.hover=M.bind(h),h.hoverend=N.bind(h),h.hover(h.latestEvent),
|
||
new MutationObserver((function(){if(t.parentNode)return h.hover(h.latestEvent)})).observe(t,{childList:!0}),Ve.on(e,o,h.hoverend),Ve.x('ancestor::div[contains(@class,"inline")][1]',e)&&Ve.on(a,"keydown",h.hoverend),Ve.on(e,"mousemove",h.hover),h.workaround=function(t){if(!e.contains(t.target))return h.hoverend(t)},Ve.on(i,"mousemove",h.workaround)};P.padding=25;var M=function(e){this.latestEvent=e;const n=(this.height||this.el.offsetHeight)+P.padding,o=this.width||this.el.offsetWidth,{clientX:a,clientY:i}=t["Follow Cursor"]?e:this,r=this.isImage?Math.max(0,i*(this.clientHeight-n)/this.clientHeight):Math.max(0,Math.min(this.clientHeight-n,i-120));let s=this.clientWidth/2;this.isImage||(s=Math.max(s,this.clientWidth-400));let l=(a<=s?a:this.clientWidth-a)+45;this.isImage&&(l=Math.min(l,this.clientWidth-o)),l+="px";const[d,c]=a<=s?[l,""]:["",l],{style:h}=this;return h.top=r+"px",h.left=d,h.right=c},N=function(e){
|
||
if(("keydown"!==e.type||13===e.keyCode)&&"TEXTAREA"!==e.target.nodeName)return this.noRemove||Ve.rm(this.el),Ve.off(this.root,this.endEvents,this.hoverend),Ve.off(a,"keydown",this.hoverend),Ve.off(this.root,"mousemove",this.hover),Ve.off(i,"mousemove",this.workaround),this.cb?this.cb.call(this):void 0};const L={dialog:function(e,n){const o=Ve.el("div",{className:"dialog",id:e});Ve.extend(o,n),o.style.cssText=t[`${e}.position`];const a=Ve(".move",o);for(var i of(Ve.on(a,"touchstart mousedown",E),a.children))i.tagName&&Ve.on(i,"touchstart mousedown",(e=>e.stopPropagation()));return o},Menu:D,hover:P,checkbox:function(e,n,o){null==o&&(o=t[e]);const a=Ve.el("label"),i=Ve.el("input",{type:"checkbox",name:e,checked:o});return Ve.add(a,[i,Ve.tn(` ${n}`)]),a}};var F={init(){switch(n.VIEW){case"index":if(!t["Index Navigation"])return;break;case"thread":if(!t["Reply Navigation"])return;break;default:return}const e=Ve.el("span",{id:"navlinks"}),o=Ve.el("a",{textContent:"▲",href:"javascript:;"
|
||
}),i=Ve.el("a",{textContent:"▼",href:"javascript:;"});Ve.on(o,"click",this.prev),Ve.on(i,"click",this.next),Ve.add(e,[o,Ve.tn(" "),i]);var r=function(){return Ve.off(a,"4chanXInitFinished",r),Ve.add(a.body,e)};return Ve.on(a,"4chanXInitFinished",r)},prev:()=>"thread"===n.VIEW?window.scrollTo(0,0):F.scroll(-1),next:()=>"thread"===n.VIEW?window.scrollTo(0,a.body.scrollHeight):F.scroll(1),getThread(){if("thread"===n.VIEW)return n.threads.get(`${n.BOARD}.${n.THREADID}`).nodes.root;if(!Ve.hasClass(i,"catalog-mode"))for(var e of u(n.SITE.selectors.thread)){var t=ze.threadFromRoot(e);if((!t.isHidden||t.stub)&&Ke.getTopOf(e)>=-e.getBoundingClientRect().height)return e}},scroll(e){let t;a.activeElement?.blur();let o=F.getThread();if(!o)return;const r=1===e?"following":"preceding";if(t=Ve.x(`${r}-sibling::${n.SITE.xpath.thread}[not(@hidden)][1]`,o)){const n=Ke.getTopOf(o);(1===e&&n<5||-1===e&&n>-5)&&(o=t)}const s=Ke.getTopOf(o)+i.clientHeight-a.body.getBoundingClientRect().bottom
|
||
;return s>0&&(a.body.style.marginBottom=`${s}px`),Ke.scrollTo(o),s>0&&!F.haveExtra?(F.haveExtra=!0,Ve.on(a,"scroll",F.removeExtra)):void 0},removeExtra(){const e=i.clientHeight-a.body.getBoundingClientRect().bottom;return e>0?a.body.style.marginBottom=`${e}px`:(a.body.style.marginBottom="",delete F.haveExtra,Ve.off(a,"scroll",F.removeExtra))}},O={init(){if((this.useFaster=/\S/.test(t.fourchanImageHost))&&"yotsuba"===n.SITE.software&&["index","thread"].includes(n.VIEW))return l.Post.push({name:"Image Host Rewriting",cb:this.node})},suggestions:["i.4cdn.org","is2.4chan.org"],host:()=>t.fourchanImageHost.trim()||"i.4cdn.org",flashHost:()=>"i.4cdn.org",thumbHost:()=>"i.4cdn.org",test:e=>"i.4cdn.org"===e||O.regex.test(e),regex:/^is\d*\.4chan(?:nel)?\.org$/,node(){if(this.isClone)return;const e=O.host();return this.file&&O.test(this.file.url.split("/")[2])&&!/\.swf$/.test(this.file.url)&&(this.file.link.hostname=e,this.file.thumbLink&&(this.file.thumbLink.hostname=e),
|
||
this.file.url=this.file.link.href),O.fixLinks(u("a",this.nodes.comment))},fixLinks(e){for(var t of e)if(O.test(t.hostname)&&!/\.swf$/.test(t.pathname)){var n=O.host();t.hostname!==n&&(t.hostname=n)}}},$={init(){if(!["index","thread"].includes(n.VIEW)||!t["Image Expansion"]&&!t["Image Hover"]&&!t["Image Hover in Catalog"]&&!t.Gallery)return;if(Ve.sync("Allow Sound",(function(e){t["Allow Sound"]=e,$.inputs&&($.inputs.unmute.checked=e)})),Ve.sync("Default Volume",(function(e){t["Default Volume"]=e,$.inputs&&($.inputs.volume.value=e)})),t["Mouse Wheel Volume"]&&l.Post.push({name:"Mouse Wheel Volume",cb:this.node}),n.SITE.noAudio?.(n.BOARD))return;t["Mouse Wheel Volume"]&&l.CatalogThread.push({name:"Mouse Wheel Volume",cb:this.catalogNode});const e=L.checkbox("Allow Sound","Allow Sound");e.title=c.main["Images and Videos"]["Allow Sound"][1];const a=Ve.el("label",{title:"Default volume for videos."});return Ve.extend(a,{
|
||
innerHTML:'<input name="Default Volume" type="range" min="0" max="1" step="0.01" value="'+o(t["Default Volume"])+'"> Volume'}),this.inputs={unmute:e.firstElementChild,volume:a.firstElementChild},Ve.on(this.inputs.unmute,"change",Ve.cb.checked),Ve.on(this.inputs.volume,"change",Ve.cb.value),Ke.menu.addEntry({el:e,order:200}),Ke.menu.addEntry({el:a,order:201})},setup:e=>(e.muted=!t["Allow Sound"],e.volume=t["Default Volume"],Ve.on(e,"volumechange",$.change)),change(){const{muted:e,volume:n}=this,o={"Allow Sound":!e,"Default Volume":n};for(var a in o){var i=o[a];t[a]===i&&delete o[a]}if(Ve.set(o),Ve.extend(t,o),$.inputs)return $.inputs.unmute.checked=!e,$.inputs.volume.value=n},node(){if(!n.SITE.noAudio?.(this.board))for(var e of this.files)e.isVideo&&(e.thumb&&Ve.on(e.thumb,"wheel",$.wheel.bind(Ke.hover)),Ve.on(Ve(".file-info",e.text)||e.link,"wheel",$.wheel.bind(e.thumbLink)))},catalogNode(){const e=this.thread.OP.files[0]
|
||
;if(e?.isVideo)return Ve.on(this.nodes.thumb,"wheel",$.wheel.bind(Ke.hover))},wheel(e){let t;if(e.shiftKey||e.altKey||e.ctrlKey||e.metaKey)return;if(!(t=Ve("video:not([data-md5])",this)))return;if(t.muted||!Ve.hasAudio(t))return;let n=t.volume+.1;return e.deltaY<0&&(n*=1.1),e.deltaY>0&&(n/=1.1),t.volume=Ve.minmax(n-.1,0,1),e.preventDefault()}},j={pause(e){if("VIDEO"===e.nodeName)return e.pause(),Ve.off(e,"volumechange",$.change),e.muted=!0},rewind(e){if("VIDEO"===e.nodeName){if(e.readyState>=e.HAVE_METADATA)return e.currentTime=0}else if(/\.gif$/.test(e.src))return Ve.queueTask((()=>e.src=e.src))},pushCache:e=>(j.cache=e,Ve.on(e,"error",j.cacheError)),popCache(){const e=j.cache;return Ve.off(e,"error",j.cacheError),delete j.cache,e},cacheError(){if(j.cache===this)return delete j.cache},decodeError(e,t){let n;return e.error?.code===MediaError.MEDIA_ERR_DECODE&&((n=Ve(".warning",t.thumb.parentNode))||(n=Ve.el("div",{className:"warning"}),Ve.after(t.thumb,n)),
|
||
n.textContent="Error: Corrupt or unplayable video",!0)},isFromArchive:e=>"yotsuba"===n.SITE.software&&!O.test(e.src.split("/")[2]),error(e,o,a,i,r){let s;const l=a.url.split("/");let d=null;if("yotsuba"===n.SITE.software&&t["404 Redirect"]&&(d=Ze.to("file",{boardID:o.board.ID,filename:l[l.length-1]})),d&&Ze.securityCheck(d)||(d=null),(o.isDead||a.isDead)&&!j.isFromArchive(e))return r(d);if(null!=i&&(s=setTimeout((()=>r(d)),i)),o.isDead||a.isDead)return;const c=function(){if(!j.isFromArchive(e))return null!=i&&clearTimeout(s),r(d)},h=n.SITE.urls.threadJSON?.(o);if(h){var u=function(e){let t,i;if(404===this.status){let t;!e&&(t=n.SITE.urls.archivedThreadJSON?.(o))?Ve.ajax(t,{onloadend(){return u.call(this,!0)}}):o.kill(!o.isClone,a.index)}if(200!==this.status)return c();for(i of this.response.posts)if(i.no===o.ID)break;return i.no!==o.ID?(o.kill(),c()):(t=a.docIndex,n.SITE.Build.parseJSON(i,o.board).filesDeleted.includes(t)?(o.kill(!0),c()):d=a.url)};return Ve.ajax(h,{onloadend(){
|
||
return u.call(this)}})}},addControls(e){var t=function(){Ve.off(e,"mouseover",t);const n=(new Date).getTime();return Ve.asap((()=>"gecko"!==Ve.engine||e.readyState>=3&&e.currentTime<=Math.max(.1,e.duration-.5)||(new Date).getTime()>=n+1e3),(()=>e.controls=!0))};return Ve.on(e,"mouseover",t)},onControls:e=>t["Show Controls"]&&t["Click Passthrough"]&&"VIDEO"===e.target.nodeName||e.target.controls&&e.target.getBoundingClientRect().bottom-e.clientY<35,download(e){if("blob:"===this.protocol)return!0;e.preventDefault();const{href:t,download:n}=this;return Ue.file(t,(function(e){if(e){const t=Ve.el("a",{href:URL.createObjectURL(e),download:n,hidden:!0});return Ve.add(a.body,t),t.click(),Ve.rm(t)}return new Xe("warning",`Could not download ${t}`,20)}))}};const q={setupSync(e,t){e.addEventListener("playing",(()=>{t.currentTime=e.currentTime,t.play()})),e.addEventListener("pause",(()=>{t.pause()})),e.addEventListener("seeked",(()=>{t.currentTime=e.currentTime})),
|
||
e.addEventListener("ratechange",(()=>{t.currentTime=e.currentTime,t.playbackRate=e.playbackRate})),e.addEventListener("waiting",(()=>{t.currentTime=e.currentTime,t.pause()})),t.addEventListener("canplay",(()=>{t.currentTime<.1&&(e.currentTime=0)}),{once:!0})},setupAudioSlider(e,t){const n=document.createElement("span");n.appendChild(document.createTextNode("🔊︎ "));const o=document.createElement("input");o.type="range",o.max="1",o.step="0.01",o.valueAsNumber=t.volume,o.addEventListener("input",(()=>{t.volume=o.valueAsNumber})),n.appendChild(o);const a=document.createElement("a");return a.href=t.src,a.download="",a.target="_blank",a.textContent=" 📥︎",n.appendChild(a),n}};var U={init(){if(this.enabled=t["Image Expansion"]&&["index","thread"].includes(n.VIEW))return this.EAI=Ve.el("a",{className:"expand-all-shortcut",textContent:"➕︎",title:"Expand All Images",href:"javascript:;"}),Ve.on(this.EAI,"click",this.cb.toggleAll),Ke.addShortcut("expand-all",this.EAI,520),
|
||
Ve.on(a,"scroll visibilitychange",this.cb.playVideos),this.videoControls=Ve.el("span",{className:"video-controls"}),Ve.extend(this.videoControls,{innerHTML:' <a href="javascript:;" title="You can also contract the video by dragging it to the left.">contract</a>'}),l.Post.push({name:"Image Expansion",cb:this.node})},node(){if(this.file&&(this.file.isImage||this.file.isVideo))if(Ve.on(this.file.thumbLink,"click",U.cb.toggle),this.isClone){if(this.file.isExpanding)return U.contract(this),U.expand(this);if(this.file.isExpanded&&this.file.isVideo)return $.setup(this.file.fullImage),U.setupVideoCB(this),U.setupVideo(this,!this.origin.file.fullImage?.paused||this.origin.file.wasPlaying,this.file.fullImage.controls)}else if(U.on&&!this.isHidden&&!this.isFetchedQuote&&(t["Expand spoilers"]||!this.file.isSpoiler)&&(t["Expand videos"]||!this.file.isVideo))return U.expand(this)},cb:{toggle(e){if(Ve.modifiedClick(e))return;const n=ze.postFromNode(this),{file:o}=n
|
||
;return o.isExpanded&&j.onControls(e)?void 0:(e.preventDefault(),!t.Autoplay&&o.fullImage?.paused?o.fullImage.play():U.toggle(n))},toggleAll(){let e;Ve.event("CloseMenu");const o=F.getThread(),a=function(a){const{file:r}=a;if(r&&(r.isImage||r.isVideo)&&i.contains(a.nodes.root)&&(!U.on||!(!t["Expand spoilers"]&&r.isSpoiler||!t["Expand videos"]&&r.isVideo||t["Expand from here"]&&Ke.getTopOf(r.thumb)<0||t["Expand thread only"]&&"index"===n.VIEW&&!o?.contains(r.thumb))))return Ve.queueTask(e,a)};return(U.on=Ve.hasClass(U.EAI,"expand-all-shortcut"))?(U.EAI.className="contract-all-shortcut",U.EAI.title="Contract All Images",U.EAI.textContent="➖︎",e=U.expand):(U.EAI.className="expand-all-shortcut",U.EAI.title="Expand All Images",U.EAI.textContent="➕︎",e=U.contract),n.posts.forEach((function(e){for(e of[e,...e.clones])a(e)}))},playVideos:()=>n.posts.forEach((function(e){for(e of[e,...e.clones]){var{file:t}=e;if(t&&t.isVideo&&t.isExpanded){
|
||
var n=t.fullImage,o=Ve.hasAudio(n)&&!n.muted||Ke.isNodeVisible(n);o&&t.wasPlaying?(delete t.wasPlaying,n.play()):o||n.paused||(t.wasPlaying=!0,n.pause())}}})),setFitness(){return Ve[this.checked?"addClass":"rmClass"](i,this.name.toLowerCase().replace(/\s+/g,"-"))}},toggle(e){if(!e.file.isExpanding&&!e.file.isExpanded)return e.file.scrollIntoView=t["Scroll into view"],void U.expand(e);if(U.contract(e),t["Advance on contract"]){let t=e.nodes.root;for(;(t=Ve.x("following::div[contains(@class,'postContainer')][1]",t))&&(Ve(".stub",t)||0===t.offsetHeight););if(t)return Ke.scrollTo(t)}},contract(e){let n,o,r,s;const{file:l}=e;if(o=l.fullImage){n=Ke.getTopOf(o)+o.getBoundingClientRect().height,r=a.body.clientHeight,({scrollY:s}=window)}for(var d of(Ve.rmClass(e.nodes.root,"expanded-image"),Ve.rmClass(l.thumb,"expanding"),Ve.rm(l.videoControls),l.thumbLink.href=l.url,l.thumbLink.target="_blank",["isExpanding","isExpanded","videoControls","wasPlaying","scrollIntoView"]))delete l[d];if(o){
|
||
if(i.contains(o)&&(n<=0?window.scrollBy(0,s-window.scrollY+a.body.clientHeight-r):Ke.scrollToIfNeeded(e.nodes.root),window.scrollX>0&&window.scrollBy(-window.scrollX,0)),Ve.off(o,"error",U.error),j.pushCache(o),l.isVideo)for(var c in j.pause(o),U.videoCB){var h=U.videoCB[c];Ve.off(o,c,h)}t["Restart when Opened"]&&j.rewind(l.thumb),delete l.fullImage,Ve.queueTask((function(){if(!l.isExpanding&&!l.isExpanded&&(Ve.rmClass(o,"full-image"),!o.id))return Ve.rm(o)})),l.audio&&(l.audio.remove(),delete l.audio,l.audioSlider&&(l.audioSlider.remove(),delete l.audioSlider))}},expand(e,n){const{file:o}=e,{thumb:a,thumbLink:i,isVideo:r}=o;if(e.isHidden||o.isExpanding||o.isExpanded)return;let s;if(Ve.addClass(a,"expanding"),o.isExpanding=!0,o.fullImage?s=o.fullImage:j.cache?.dataset.fileID===`${e.fullID}.${o.index}`?(s=o.fullImage=j.popCache(),Ve.on(s,"error",U.error),t["Restart when Opened"]&&"ihover"!==s.id&&j.rewind(s),s.removeAttribute("id")):(s=o.fullImage=Ve.el(r?"video":"img"),
|
||
s.dataset.fileID=`${e.fullID}.${o.index}`,Ve.on(s,"error",U.error),s.src=n||o.url),s.className="full-image",Ve.after(a,s),r&&(o.videoControls||(o.videoControls=U.videoControls.cloneNode(!0),Ve.add(o.text,o.videoControls)),i.removeAttribute("href"),i.removeAttribute("target"),s.loop=!0,$.setup(s),U.setupVideoCB(e)),r?s.readyState>=s.HAVE_METADATA?U.completeExpand(e):Ve.on(s,"loadedmetadata",(()=>U.completeExpand(e))):Ve.asap((()=>s.naturalHeight),(()=>U.completeExpand(e))),t["Enable sound posts"]&&t["Allow Sound"]){const e=o.name.match(/\[sound=([^\]]+)]/);if(e){let n=decodeURIComponent(e[1]);n.startsWith("http")||(n=`https://${n}`);const a=Ve.el("audio",{src:n});$.setup(a),r?(q.setupSync(s,a),t["Show Controls"]&&(o.audioSlider=q.setupAudioSlider(s,a),Ve.after(s.parentElement,o.audioSlider))):(a.controls=t["Show Controls"],a.autoplay=t.Autoplay),Ve.after(s,a),o.audio=a}}},completeExpand(e){const{file:n}=e;if(!n.isExpanding)return
|
||
;const o=Ke.getTopOf(n.thumb)+n.thumb.getBoundingClientRect().height,r=a.body.clientHeight,{scrollY:s}=window;if(Ve.addClass(e.nodes.root,"expanded-image"),Ve.rmClass(n.thumb,"expanding"),n.isExpanded=!0,delete n.isExpanding,i.contains(e.nodes.root)&&o<=0&&window.scrollBy(0,s-window.scrollY+a.body.clientHeight-r),n.scrollIntoView){delete n.scrollIntoView;const e=Math.min(i.clientHeight-n.fullImage.getBoundingClientRect().bottom-25,Ke.getBottomOf(n.fullImage));e<0&&window.scrollBy(0,Math.min(-e,Ke.getTopOf(n.fullImage)))}return n.isVideo?U.setupVideo(e,t.Autoplay,t["Show Controls"]):void 0},setupVideo(e,t,n){const{fullImage:o}=e.file;if(t)return o.controls=!1,Ve.asap((()=>i.contains(o)),(function(){return!a.hidden&&Ke.isNodeVisible(o)?o.play():e.file.wasPlaying=!0})),n?j.addControls(o):void 0;o.controls=n},videoCB:function(){let e=!1;return{mouseover:()=>e=!1,mousedown(t){if(0===t.button)return e=!0},mouseup(t){if(0===t.button)return e=!1},mouseout(t){
|
||
if((1&t.buttons||e)&&t.clientX<=this.getBoundingClientRect().left)return U.toggle(ze.postFromNode(this))}}}(),setupVideoCB(e){for(var t in U.videoCB){var n=U.videoCB[t];Ve.on(e.file.fullImage,t,n)}if(e.file.videoControls)return Ve.on(e.file.videoControls.firstElementChild,"click",(()=>U.toggle(e)))},error(){const e=ze.postFromNode(this);if(Ve.rm(this),delete e.file.fullImage,e.file.isExpanding||e.file.isExpanded)return j.decodeError(this,e.file)||j.isFromArchive(this)?U.contract(e):j.error(this,e,e.file,1e4,(function(t){if((e.file.isExpanding||e.file.isExpanded)&&(U.contract(e),t))return U.expand(e,t)}))},menu:{init(){if(!U.enabled)return;const e=Ve.el("span",{textContent:"Image Expansion",className:"image-expansion-link"}),{createSubEntry:t}=U.menu,n=[];for(var o in c.imageExpansion){var a=c.imageExpansion[o];n.push(t(o,a[1]))}return Ke.menu.addEntry({el:e,order:105,subEntries:n})},createSubEntry(e,t){const n=L.checkbox(e,e);n.title=t;const o=n.firstElementChild
|
||
;return["Fit width","Fit height"].includes(e)&&Ve.on(o,"change",U.cb.setFitness),Ve.event("change",null,o),Ve.on(o,"change",Ve.cb.checked),{el:n}}}};class H{toString(){return this.ID}constructor(e,o,a,i={}){
|
||
// @normalizedOriginal = Test.normalize root
|
||
if(void 0===e&&void 0===o&&void 0===a)return;if(this.root=e,this.thread=o,this.board=a,Ve.extend(this,i),this.ID=+e.id.match(/\d*$/)[0],this.postID=this.ID,this.threadID=this.thread.ID,this.boardID=this.board.ID,this.siteID=n.SITE.ID,this.fullID=`${this.board}.${this.ID}`,this.context=this,this.isReply=this.ID!==this.threadID,e.dataset.fullID=this.fullID,this.nodes=this.parseNodes(e),!this.isReply){for(var r of(this.thread.OP=this,["isSticky","isClosed","isArchived"])){var s;(s=n.SITE.selectors.icons[r])&&(this.thread[r]=!!Ve(s,this.nodes.info))}this.thread.isArchived&&(this.thread.isClosed=!0,this.thread.kill())}const l=this.nodes.name?.textContent,d=this.nodes.tripcode?.textContent;if(this.info={subject:this.nodes.subject?.textContent||void 0,name:l,email:this.nodes.email?decodeURIComponent(this.nodes.email.href.replace(/^mailto:/,"")):void 0,tripcode:d,uniqueID:this.nodes.uniqueID?.textContent,capcode:this.nodes.capcode?.textContent.replace("## ",""),
|
||
pass:this.nodes.pass?.title.match(/\d*$/)[0],flagCode:this.nodes.flag?.className.match(/flag-(\w+)/)?.[1].toUpperCase(),flagCodeTroll:this.nodes.flag?.className.match(/bfl-(\w+)/)?.[1].toUpperCase(),flag:this.nodes.flag?.title,date:this.nodes.date?n.SITE.parseDate(this.nodes.date):void 0,nameBlock:t.Anonymize?"Anonymous":`${l||""} ${d||""}`.trim()},this.info.capcode&&(this.info.nameBlock+=` ## ${this.info.capcode}`),this.info.uniqueID&&(this.info.nameBlock+=` (ID: ${this.info.uniqueID})`),this.parseComment(),this.parseQuotes(),this.parseFiles(),this.isDead=!1,this.isHidden=!1,this.clones=[],n.posts.get(this.fullID))for(var c of(this.isRebuilt=!0,this.clones=n.posts.get(this.fullID).clones,this.clones))c.origin=this;!this.isFetchedQuote&&this.ID>this.thread.lastPost&&(this.thread.lastPost=this.ID),this.board.posts.push(this.ID,this),this.thread.posts.push(this.ID,this),n.posts.push(this.fullID,this),this.isFetchedQuote=!1,this.isClone=!1}parseNodes(e){
|
||
const t=n.SITE.selectors,o=Ve(t.post,e)||e,a=Ve(t.infoRoot,o),i={root:e,bottom:this.isReply||!n.SITE.isOPContainerThread?e:Ve(t.opBottom,e),post:o,info:a,comment:Ve(t.comment,o),quotelinks:[],archivelinks:[],embedlinks:[],backlinks:o.getElementsByClassName("backlink"),uniqueIDRoot:void 0,uniqueID:void 0};for(var r in t.info){var s=t.info[r];i[r]=Ve(s,a)}return n.SITE.parseNodes?.(this,i),i.uniqueIDRoot||(i.uniqueIDRoot=i.uniqueID),i}parseComment(){let e;return this.nodes.comment.normalize(),this.nodes.commentClean=e=this.nodes.comment.cloneNode(!0),n.SITE.cleanComment?.(e),this.info.comment=this.nodesToText(e)}commentDisplay(){const e=this.nodes.commentClean.cloneNode(!0);return t["Remove Spoilers"]||t["Reveal Spoilers"]||this.cleanSpoilers(e),n.SITE.cleanCommentDisplay?.(e),this.nodesToText(e).trim().replace(/\s+$/gm,"")}commentOrig(){const e=this.nodes.commentClean.cloneNode(!0);return n.SITE.insertTags?.(e),this.nodesToText(e)}nodesToText(e){let t,n=""
|
||
;const o=Ve.X(".//br|.//text()",e);let a=0;for(;t=o.snapshotItem(a++);)n+=t.data||"\n";return n}cleanSpoilers(e){const t=u(n.SITE.selectors.spoiler,e);for(var o of t)Ve.replace(o,Ve.tn("[spoiler]"))}parseQuotes(){for(var e of(this.quotes=[],u(n.SITE.selectors.quotelink,this.nodes.comment)))this.parseQuote(e)}parseQuote(e){const t=e.href.match(n.SITE.regexp.quotelink);if(!(t||this.isClone&&e.dataset.postID))return;if(this.nodes.quotelinks.push(e),this.isClone)return;const o=`${t[1]}.${t[3]}`;this.quotes.includes(o)||this.quotes.push(o)}parseFiles(){let e;this.files=[];const t=this.fileRoots();let n=0;for(let a=0;a<t.length;a++){var o=t[a];(e=this.parseFile(o))&&(e.index=n++,e.docIndex=a,this.files.push(e))}if(this.files.length)return this.file=this.files[0]}fileRoots(){if(n.SITE.selectors.multifile){const e=u(n.SITE.selectors.multifile,this.nodes.root);if(e.length)return e}return[this.nodes.root]}parseFile(e){const t={isDead:!1};for(var o in n.SITE.selectors.file){
|
||
var a=n.SITE.selectors.file[o];t[o]=Ve(a,e)}if(t.thumbLink=t.thumb?.parentNode,!t.text||!t.link)return;if(!n.SITE.parseFile(this,t))return;Ve.extend(t,{url:t.link.href,isImage:Ve.isImage(t.link.href),isVideo:Ve.isVideo(t.link.href)});let i=+t.size.match(/[\d.]+/)[0],r=["B","KB","MB","GB"].indexOf(t.size.match(/\w+$/)[0]);for(;r-- >0;)i*=1024;return t.sizeInBytes=i,t}kill(e,t=0){let n;if(e){if(this.isDead||this.files[t].isDead)return;this.files[t].isDead=!0,Ve.addClass(this.nodes.root,"deleted-file")}else{if(this.isDead)return;this.isDead=!0,Ve.rmClass(this.nodes.root,"deleted-file"),Ve.addClass(this.nodes.root,"deleted-post")}if((n=Ve("strong.warning",this.nodes.info))||(n=Ve.el("strong",{className:"warning"}),Ve.after(Ve("input",this.nodes.info),n)),n.textContent=e?"[File deleted]":"[Deleted]",!this.isClone){for(var o of this.clones)o.kill(e,t);if(!e)for(var a of ze.allQuotelinksLinkingTo(this))Ve.hasClass(a,"deadlink")||(Ve.add(a,H.deadMark.cloneNode(!0)),Ve.addClass(a,"deadlink"))}}
|
||
resurrect(){this.isDead=!1,Ve.rmClass(this.nodes.root,"deleted-post");const e=Ve("strong.warning",this.nodes.info);if(this.files.some((e=>e.isDead))?(Ve.addClass(this.nodes.root,"deleted-file"),e.textContent="[File deleted]"):Ve.rm(e),!this.isClone){for(var t of this.clones)t.resurrect();for(var n of ze.allQuotelinksLinkingTo(this))Ve.hasClass(n,"deadlink")&&(Ve.rm(Ve(".qmark-dead",n)),Ve.rmClass(n,"deadlink"))}}collect(){n.posts.rm(this.fullID),this.thread.posts.rm(this),this.board.posts.rm(this)}addClone(e,t){return l.Post.execute(this),new V(this,e,t)}rmClone(e){for(var t of(this.clones.splice(e,1),this.clones.slice(e)))t.nodes.root.dataset.clone=e++}setCatalogOP(e){this.nodes.root.classList.toggle("catalog-container",e),this.nodes.root.classList.toggle("opContainer",!e),this.nodes.post.classList.toggle("catalog-post",e),this.nodes.post.classList.toggle("op",!e),this.nodes.post.style.left=this.nodes.post.style.right=null}}H.deadMark=(()=>{const e=document.createElement("span")
|
||
;return e.textContent=" (Dead)",e.className="qmark-dead",e})();class V extends H{constructor(e,t,o){let a,i,r;for(r of(super(),this.isClone=!0,this.origin=e,this.context=t,["ID","postID","threadID","boardID","siteID","fullID","board","thread","info","quotes","isReply"]))this[r]=this.origin[r];const{nodes:s}=this.origin,l=o?this.cloneWithoutVideo(s.root):s.root.cloneNode(!0);for(var d of[l,...u("[id]",l)])d.id+=`_${V.suffix}`;for(var c of(V.suffix++,u(".inline",l)))Ve.rm(c);for(var h of u(".inlined",l))Ve.rmClass(h,"inlined");for(var p of(this.nodes=this.parseNodes(l),l.hidden=!1,Ve.rmClass(l,"forwarded"),Ve.rmClass(this.nodes.post,"highlight"),this.isReply||(this.setCatalogOP(!1),Ve.rm(Ve(".catalog-link",this.nodes.post)),Ve.rm(Ve(".catalog-stats",this.nodes.post)),Ve.rm(Ve(".catalog-replies",this.nodes.post))),this.parseQuotes(),this.quotes=[...this.origin.quotes],this.files=[],this.origin.files.length&&(i=this.fileRoots()),this.origin.files)){a={...p};var g=i[a.docIndex]
|
||
;for(r in n.SITE.selectors.file){var f=n.SITE.selectors.file[r];a[r]=Ve(f,g)}a.thumbLink=a.thumb?.parentNode,a.thumbLink&&(a.fullImage=Ve(".full-image",a.thumbLink)),a.videoControls=Ve(".video-controls",a.text),a.videoThumb&&(a.thumb.muted=!0),this.files.push(a)}return this.files.length&&(this.file=this.files[0],this.file.thumb&&o&&U.contract(this)),this.origin.isDead&&(this.isDead=!0),l.dataset.clone=this.origin.clones.push(this)-1,this}cloneWithoutVideo(e){if("VIDEO"!==e.tagName||e.dataset.md5){if(e.nodeType===Node.ELEMENT_NODE&&Ve("video",e)){const n=e.cloneNode(!1);for(var t of e.childNodes)Ve.add(n,this.cloneWithoutVideo(t));return n}return e.cloneNode(!0)}return[]}}V.suffix=0;var Q={init(){if(["index","thread"].includes(n.VIEW)&&t.Menu)return this.button=Ve.el("a",{className:"menu-button",href:"javascript:;"}),Ve.extend(this.button,{textContent:"🞃"}),this.menu=new L.Menu("post"),l.Post.push({name:"Menu",cb:this.node}),l.CatalogThread.push({name:"Menu",cb:this.catalogNode})},
|
||
node(){if(this.isClone){const e=Ve(".menu-button",this.nodes.info);return Ve.rmClass(e,"active"),Ve.rm(Ve(".dialog",this.nodes.info)),void Q.makeButton(this,e)}return Ve.add(this.nodes.info,Q.makeButton(this))},catalogNode(){return Ve.after(this.nodes.icons,Q.makeButton(this.thread.OP))},makeButton:(e,t)=>(t||(t=Q.button.cloneNode(!0)),Ve.on(t,"click",(function(t){return Q.menu.toggle(t,this,e)})),t)},z={recursives:m(),init(){if(["index","thread"].includes(n.VIEW))return l.Post.push({name:"Recursive",cb:this.node})},node(){if(!this.isClone&&!this.isFetchedQuote)for(var e of this.quotes){var t;if(t=z.recursives[e])for(var n=0;n<t.recursives.length;n++){(0,t.recursives[n])(this,...t.args[n])}}},add(e,t,...n){const o=z.recursives[t.fullID]||(z.recursives[t.fullID]={recursives:[],args:[]});return o.recursives.push(e),o.args.push(n)},rm(e,t){let n;if(n=z.recursives[t.fullID])for(let t=0;t<n.recursives.length;t++){n.recursives[t]===e&&(n.recursives.splice(t,1),n.args.splice(t,1))}},
|
||
apply(e,t,...o){const{fullID:a}=t;return n.posts.forEach((function(t){if(t.quotes.includes(a))return e(t,...o)}))}},W={init(){if(["index","thread"].includes(n.VIEW)&&(t["Reply Hiding Buttons"]||t.Menu&&t["Reply Hiding Link"]))return t["Reply Hiding Buttons"]&&Ve.addClass(i,"reply-hide"),this.db=new y("hiddenPosts"),l.Post.push({name:"Reply Hiding",cb:this.node})},isHidden:(e,t,n)=>!(!W.db||!W.db.get({boardID:e,threadID:t,postID:n})),node(){let e,o;if(!this.isReply||this.isClone||this.isFetchedQuote)return;if((e=W.db.get({boardID:this.board.ID,threadID:this.thread.ID,postID:this.ID}))&&(e.thisPost?W.hide(this,e.makeStub,e.hideRecursively):(z.apply(W.hide,this,e.makeStub,!0),z.add(W.hide,this,e.makeStub,!0))),!t["Reply Hiding Buttons"])return;const a=W.makeButton(this,"hide");if(o=n.SITE.selectors.sideArrows){const e=Ve(o,this.nodes.root);return Ve.replace(e.firstChild,a),e.className="replacedSideArrows"}return Ve.prepend(this.nodes.info,a)},menu:{init(){
|
||
if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Reply Hiding Link"])return;let e=Ve.el("div",{className:"hide-reply-link",textContent:"Hide"}),o=Ve.el("a",{textContent:"Apply",href:"javascript:;"});Ve.on(o,"click",W.menu.hide);let a=L.checkbox("thisPost","This post",!0),i=L.checkbox("replies","Hide replies",t["Recursive Hiding"]);const r=L.checkbox("makeStub","Make stub",t.Stubs);Q.menu.addEntry({el:e,order:20,open:e=>!(!e.isReply||e.isClone||e.isHidden)&&(W.menu.post=e,!0),subEntries:[{el:o},{el:a},{el:i},{el:r}]}),e=Ve.el("div",{className:"show-reply-link",textContent:"Show"}),o=Ve.el("a",{textContent:"Apply",href:"javascript:;"}),Ve.on(o,"click",W.menu.show),a=L.checkbox("thisPost","This post",!1),i=L.checkbox("replies","Show replies",!1);const s=Ve.el("a",{textContent:"Hide stub",href:"javascript:;"});return Ve.on(s,"click",W.menu.hideStub),Q.menu.addEntry({el:e,order:20,open(e){let n;return!(!e.isReply||e.isClone||!e.isHidden)&&(!!(n=W.db.get({boardID:e.board.ID,
|
||
threadID:e.thread.ID,postID:e.ID}))&&(W.menu.post=e,a.firstChild.checked=e.isHidden,i.firstChild.checked=null!=n?.hideRecursively?n.hideRecursively:t["Recursive Hiding"],!0))},subEntries:[{el:o},{el:a},{el:i}]}),Q.menu.addEntry({el:s,order:15,open:e=>!(!e.isReply||e.isClone||!e.isHidden)&&(!!W.db.get({boardID:e.board.ID,threadID:e.thread.ID,postID:e.ID})&&(W.menu.post=e))})},hide(){const e=this.parentNode,t=Ve("input[name=thisPost]",e).checked,n=Ve("input[name=replies]",e).checked,o=Ve("input[name=makeStub]",e).checked,{post:a}=W.menu;if(t)W.hide(a,o,n);else{if(!n)return;z.apply(W.hide,a,o,!0),z.add(W.hide,a,o,!0)}return W.saveHiddenState(a,!0,t,o,n),Ve.event("CloseMenu")},show(){let e;const t=this.parentNode,n=Ve("input[name=thisPost]",t).checked,o=Ve("input[name=replies]",t).checked,{post:a}=W.menu;if(n)W.show(a,o);else{if(!o)return;z.apply(W.show,a,!0),z.rm(W.hide,a,!0)}return(e=W.db.get({boardID:a.board.ID,threadID:a.thread.ID,postID:a.ID
|
||
}))&&W.saveHiddenState(a,!(n&&o),!n,e.makeStub,!o),Ve.event("CloseMenu")},hideStub(){let e;const{post:t}=W.menu;(e=W.db.get({boardID:t.board.ID,threadID:t.thread.ID,postID:t.ID}))&&(W.show(t,e.hideRecursively),W.hide(t,!1,e.hideRecursively),W.saveHiddenState(t,!0,!0,!1,e.hideRecursively)),Ve.event("CloseMenu")}},makeButton(e,t){const n=Ve.el("span",{textContent:"hide"===t?"➖︎":"➕︎"}),o=Ve.el("a",{className:`${t}-reply-button`,href:"javascript:;"});return Ve.add(o,n),Ve.on(o,"click",W.toggle),o},saveHiddenState(e,t,n,o,a){const i={boardID:e.board.ID,threadID:e.thread.ID,postID:e.ID};return t?(i.val={thisPost:!1!==n,makeStub:o,hideRecursively:a},W.db.set(i)):W.db.delete(i)},toggle(){const e=ze.postFromNode(this);return W[e.isHidden?"show":"hide"](e),W.saveHiddenState(e,e.isHidden)},hide(e,n=t.Stubs,o=t["Recursive Hiding"]){if(e.isHidden)return;for(var a of(e.isHidden=!0,o&&(z.apply(W.hide,e,n,!0),z.add(W.hide,e,n,!0)),ze.allQuotelinksLinkingTo(e)))Ve.addClass(a,"filtered")
|
||
;if(!n)return void(e.nodes.root.hidden=!0);const i=W.makeButton(e,"show");return Ve.add(i,Ve.tn(` ${e.info.nameBlock}`)),e.nodes.stub=Ve.el("div",{className:"stub"}),Ve.add(e.nodes.stub,i),t.Menu&&Ve.add(e.nodes.stub,Q.makeButton(e)),Ve.prepend(e.nodes.root,e.nodes.stub)},show(e,n=t["Recursive Hiding"]){for(var o of(e.nodes.stub?(Ve.rm(e.nodes.stub),delete e.nodes.stub):e.nodes.root.hidden=!1,e.isHidden=!1,n&&(z.apply(W.show,e,!0),z.rm(W.hide,e)),ze.allQuotelinksLinkingTo(e)))Ve.rmClass(o,"filtered")}},G={INTERVAL:3e4,init(){if((["index","thread","archive"].includes(n.VIEW)&&t["Relative Post Dates"]&&!t["Relative Date Title"]||ue.enabled)&&(this.flush(),Ve.on(a,"visibilitychange PostsInserted",this.flush)),t["Relative Post Dates"])return l.Post.push({name:"Relative Post Dates",cb:this.node})},node(){if(!this.info.date)return;const e=this.nodes.date;if(t["Relative Date Title"])Ve.on(e,"mouseover",(()=>G.hover(this)));else if(!this.isClone)return e.title=e.textContent,G.update(this)},
|
||
relative(e,t,n,o){let a,i=(()=>{if((a=e/w)>=1){const e=t.getFullYear()-n.getFullYear();let o=t.getMonth()-n.getMonth();const i=t.getDate()-n.getDate();return e>1?(a=e-(o<0||0===o&&i<0),"year"):1===e&&(o>0||0===o&&i>=0)?(a=e,"year"):(o+=12*e)>1?(a=o-(i<0),"month"):1===o&&i>=0?(a=o,"month"):"day"}return(a=e/v)>=1?"hour":(a=e/A)>=1?"minute":(a=Math.max(0,e)/b,"second")})();const r=Math.round(a);return o?i="month"===i?"mo":i[0]:1!==r&&(i+="s"),o?`${r}${i}`:`${r} ${i} ago`},stale:[],flush(){if(a.hidden)return;const e=new Date;for(var t of G.stale)G.update(t,e);return G.stale=[],clearTimeout(G.timeout),G.timeout=setTimeout(G.flush,G.INTERVAL)},hover(e){const{date:t}=e.info,n=new Date,o=n-t;return e.nodes.date.title=G.relative(o,n,t)},update(e,t){let n,o;const a=e instanceof H;a?(({date:o}=e.info),n=!1):(o=new Date(+e.dataset.utc),n=!!e.dataset.abbrev),t||(t=new Date);const i=t-o,r=G.relative(i,t,o,n)
|
||
;if(a)for(var s of[e].concat(e.clones))s.nodes.date.firstChild.textContent=r;else e.firstChild.textContent=r;return G.setOwnTimeout(i,e)},setOwnTimeout(e,t){const n=e<A?b-(e+500)%b:e<v?A-(e+3e4)%A:e<w?v-(e+v/2)%v:w-(e+w/2)%w;return setTimeout(G.markStale,n,t)},markStale(e){if(!G.stale.includes(e)&&(!(e instanceof H)||n.posts.get(e.fullID))&&(!(e instanceof Element)||i.contains(e)))return G.stale.push(e)}},Y={cbs:[],init(){let e;if("yotsuba"!==n.SITE.software)return;const o=Date.now();if(o-2*v>=(e=t.boardConfig.lastChecked||0)||e>o)return Ve.ajax(`${location.protocol}//a.4cdn.org/boards.json`,{onloadend:this.load});{const{boards:e}=t.boardConfig;return this.set(e)}},load(){let e;if(200===this.status&&this.response&&this.response.boards){for(var n of(e=m(),this.response.boards))e[n.board]=n;Ve.set("boardConfig",{boards:e,lastChecked:Date.now()})}else{({boards:e}=t.boardConfig);const n=(()=>{switch(this.status){case 0:return"Connection Error";case 200:return"Invalid Data";default:
|
||
return`Error ${this.statusText} (${this.status})`}})();new Xe("warning",`Failed to load board configuration. ${n}`,20)}return Y.set(e)},set(e){for(var t in this.boards=e,n.boards){n.boards[t].config=this.boards[t]||{}}for(var o of this.cbs)Ve.queueTask(o)},ready(e){return this.boards?e():this.cbs.push(e)},sfwBoards(e){return(()=>{const n=[],o=this.boards||t.boardConfig.boards;for(var a in o){!!o[a].ws_board===e&&n.push(a)}return n})()},isSFW(e){return!!(this.boards||t.boardConfig.boards)[e]?.ws_board},domain:e=>`boards.${Y.isSFW(e)?"4channel":"4chan"}.org`,isArchived(e){const n=(this.boards||t.boardConfig.boards)[e];return!n||n.is_archived},noAudio(e){if("yotsuba"!==n.SITE.software)return!1;const o=this.boards||t.boardConfig.boards;return o&&o[e]&&!o[e].webm_audio},title(e){return(this.boards||t.boardConfig.boards)?.[e]?.title||""}};class J{toString(){return this.ID}constructor(e){this.ID=e,this.boardID=this.ID,this.siteID=n.SITE.ID,this.threads=new k,this.posts=new k,
|
||
this.config=Y.boards?.[this.ID]||{},n.boards[this]=this}cooldowns(){const e=(this.config||{}).cooldowns||{},t={thread:e.threads||0,reply:e.replies||0,image:e.images||0,thread_global:300};if(a.cookie.indexOf("pass_enabled=1")>=0)for(var n of["reply","image"])t[n]=Math.ceil(t[n]/2);return t}}const K={init(){return Ve.on(a,"QRPostSuccessful",(e=>{if(e.detail.redirect)return this.event=e,this.delays=0,Ve.queueTask((()=>{if(e===this.event&&0===this.delays)return location.href=e.detail.redirect}))}))},delays:0,delay(){if(!this.event)return null;const e=this.event;return this.delays++,()=>{if(e===this.event)return this.delays--,0===this.delays?location.href=e.detail.redirect:void 0}}};var X={init(){if("index"===n.VIEW&&t["Comment Expansion"]&&!t["JSON Index"])return l.Post.push({name:"Comment Expansion",cb:this.node})},node(){let e;if(e=Ve(".abbr > a:not([onclick])",this.nodes.comment))return Ve.on(e,"click",X.cb)},callbacks:[],cb(e){return e.preventDefault(),X.expand(ze.postFromNode(this))},
|
||
expand(e){let t;return e.nodes.longComment&&!e.nodes.longComment.parentNode?(Ve.replace(e.nodes.shortComment,e.nodes.longComment),void(e.nodes.comment=e.nodes.longComment)):(t=Ve(".abbr > a",e.nodes.comment))?(t.textContent=`Post No.${e} Loading...`,Ve.cache(n.SITE.urls.threadJSON({boardID:e.boardID,threadID:e.threadID}),(function(){return X.parse(this,t,e)}))):void 0},contract(e){if(!e.nodes.shortComment)return;return Ve(".abbr > a",e.nodes.shortComment).textContent="here",Ve.replace(e.nodes.longComment,e.nodes.shortComment),e.nodes.comment=e.nodes.shortComment},parse(e,t,o){let a,i;const{status:r}=e;if(![200,304].includes(r))return void(t.textContent=r?`Error ${e.statusText} (${r})`:"Connection Error");const{posts:s}=e.response;for(a of((i=s[0].custom_spoiler)&&(n.SITE.Build.spoilerRange[n.BOARD]=i),s))if(a.no===o.ID)break;if(a.no!==o.ID)return void(t.textContent=`Post No.${o} not found.`);const{comment:l}=o.nodes,d=l.cloneNode(!1);for(var c of(d.innerHTML=a.com,u(".quotelink",d))){
|
||
var h=c.getAttribute("href");"/"!==h[0]&&("#"===h[0]?c.href=`${t.pathname.split(/\/+/).splice(0,4).join("/")}${h}`:c.href=`${t.pathname.split(/\/+/).splice(0,3).join("/")}/${h}`)}for(var p of(o.nodes.shortComment=l,Ve.replace(l,d),o.nodes.comment=o.nodes.longComment=d,o.parseComment(),o.parseQuotes(),X.callbacks))p.call(o)}},_={init(){if(t["Remember Your Posts"]&&(this.db=new y("yourPosts"),Ve.sync("Remember Your Posts",(e=>t["Remember Your Posts"]=e)),Ve.on(a,"QRPostSuccessful",(function(e){const n=K.delay();return Ve.get("Remember Your Posts",t["Remember Your Posts"],(function(t){if(!t["Remember Your Posts"])return;const{boardID:o,threadID:a,postID:i}=e.detail;return _.db.set({boardID:o,threadID:a,postID:i,val:!0},n)}))})),["index","thread","archive"].includes(n.VIEW)))return t["Highlight Own Posts"]&&Ve.addClass(i,"highlight-own"),t["Highlight Posts Quoting You"]&&Ve.addClass(i,"highlight-you"),t["Comment Expansion"]&&X.callbacks.push(this.node),this.mark=Ve.el("span",{
|
||
textContent:" (You)",className:"qmark-you"}),l.Post.push({name:"Mark Quotes of You",cb:this.node}),_.menu.init()},isYou:e=>!!_.db?.get({boardID:e.boardID,threadID:e.threadID,postID:e.ID}),node(){if(!this.isClone&&(_.isYou(this)&&Ve.addClass(this.nodes.root,"yourPost"),this.quotes.length))for(var e of this.nodes.quotelinks)_.db.get(ze.postDataFromLink(e))&&(t["Mark Quotes of You"]&&Ve.add(e,_.mark.cloneNode(!0)),Ve.addClass(e,"you"),Ve.addClass(this.nodes.root,"quotesYou"))},menu:{init(){const e=Ve.el("label",{className:"toggle-you"},{innerHTML:'<input type="checkbox"> You'}),t=Ve("input",e);return Ve.on(t,"change",_.menu.toggle),Q.menu?.addEntry({el:e,order:80,open:e=>(_.menu.post=e.origin||e,t.checked=_.isYou(e),!0)})},toggle(){const{post:e}=_.menu,n={boardID:e.board.ID,threadID:e.thread.ID,postID:e.ID,val:!0};for(var o of(this.checked?_.db.set(n):_.db.delete(n),[e].concat(e.clones)))o.nodes.root.classList.toggle("yourPost",this.checked)
|
||
;for(var a of ze.allQuotelinksLinkingTo(e))if(this.checked?t["Mark Quotes of You"]&&Ve.add(a,_.mark.cloneNode(!0)):Ve.rm(Ve(".qmark-you",a)),a.classList.toggle("you",this.checked),Ve.hasClass(a,"quotelink")){var i=ze.postFromNode(a).nodes.root;i.classList.toggle("quotesYou",!!Ve(".quotelink.you",i))}}},cb:{seek(e){let t,o,a;const{highlight:r}=n.SITE.classes;if((t=Ve(`.${r}`))&&Ve.rmClass(t,r),_.lastRead&&i.contains(_.lastRead)&&Ve.hasClass(_.lastRead,"quotesYou"))o=_.lastRead;else{if(!(o=_.lastRead=Ve(".quotesYou")))return void new Xe("warning","No posts are currently quoting you, loser.",20);if(_.cb.scroll(o))return}const s=`${e}::div[contains(@class,'quotesYou')]`;for(;o=(a=Ve.X(s,o)).snapshotItem("preceding"===e?a.snapshotLength-1:0);)if(_.cb.scroll(o))return;const l=u(".quotesYou");return _.cb.scroll(l["following"===e?0:l.length-1])},scroll(e){const t=ze.postFromRoot(e);if(t.nodes.post.getBoundingClientRect().height){if(_.lastRead=e,location.href=ze.url("post",t),
|
||
Ke.scrollTo(t.nodes.post),t.isReply){const e=`${n.SITE.selectors.postContainer}${n.SITE.selectors.highlightable.reply}`;let o=t.nodes.root;o.matches(e)||(o=Ve(e,o)),Ve.addClass(o,n.SITE.classes.highlight)}return!0}return!1}}};class Z{constructor(e){if(this.length=0,e)for(var t of e)this.push(t)}push(e){let t,{ID:n}=e;if(n||(n=e.id),this[n])return;const{last:o}=this;return this[n]=t={prev:o,next:null,data:e,ID:n},t.prev=o,this.last=o?o.next=t:this.first=t,this.length++}before(e,t){if(t.next===e||t===e)return;this.rmi(t);const{prev:n}=e;return e.prev=t,t.next=e,t.prev=n,n?n.next=t:this.first=t}after(e,t){if(t.prev===e||t===e)return;this.rmi(t);const{next:n}=e;return e.next=t,t.prev=e,t.next=n,n?n.prev=t:this.last=t}prepend(e){const{first:t}=this;if(e!==t&&this[e.ID])return this.rmi(e),e.next=t,t?t.prev=e:this.last=e,this.first=e,delete e.prev}shift(){return this.rm(this.first.ID)}order(){let e;const t=[e=this.first];for(;e=e.next;)t.push(e);return t}rm(e){const t=this[e]
|
||
;if(t)return delete this[e],this.length--,this.rmi(t),delete t.next,delete t.prev}rmi(e){const{prev:t,next:n}=e;return t?t.next=n:this.first=n,n?n.prev=t:this.last=t}}var ee={init(){if("thread"===n.VIEW&&(t["Unread Count"]||t["Unread Favicon"]||t["Unread Line"]||t["Remember Last Read Post"]||t["Desktop Notifications"]||t["Quote Threading"]))return t["Remember Last Read Post"]&&(Ve.sync("Remember Last Read Post",(e=>t["Remember Last Read Post"]=e)),this.db=new y("lastReadPosts",this.sync)),this.hr=Ve.el("hr",{id:"unread-line",className:"unread-line"}),this.posts=new Set,this.postsQuotingYou=new Set,this.order=new Z,this.position=null,l.Thread.push({name:"Unread",cb:this.node}),l.Post.push({name:"Unread",cb:this.addPost})},node(){for(var e of(ee.thread=this,ee.title=a.title,ee.lastReadPost=ee.db?.get({boardID:this.board.ID,threadID:this.ID})||0,ee.readCount=0,this.posts.keys))+e<=ee.lastReadPost&&ee.readCount++;Ve.one(a,"4chanXInitFinished",ee.ready),Ve.on(a,"PostsInserted",ee.onUpdate),
|
||
Ve.on(a,"ThreadUpdate",(function(e){if(e.detail[404])return ee.update()}));const t=Ve.el("a",{href:"javascript:;",className:"unread-reset",textContent:"Mark all unread"});return Ve.on(t,"click",ee.reset),Ke.menu.addEntry({el:t,order:70})},ready(){if(t["Remember Last Read Post"]&&t["Scroll to Last Read Post"]&&ee.scroll(),ee.setLine(!0),ee.read(),ee.update(),Ve.on(a,"scroll visibilitychange",ee.read),t["Unread Line"])return Ve.on(a,"visibilitychange",ee.setLine)},positionPrev:()=>ee.position?ee.position.prev:ee.order.last,scroll(){let e;if((e=location.hash.match(/\d+/))&&e[0]in ee.thread.posts)return;let t=ee.positionPrev();for(;t;){var{bottom:n}=t.data.nodes;if(n.getBoundingClientRect().height){Ke.scrollToIfNeeded(n,!0);break}t=t.prev}},reset(){if(null!=ee.lastReadPost)return ee.posts=new Set,ee.postsQuotingYou=new Set,ee.order=new Z,ee.position=null,ee.lastReadPost=0,ee.readCount=0,ee.thread.posts.forEach((e=>ee.addPost.call(e))),Ve.forceSync("Remember Last Read Post"),
|
||
!t["Remember Last Read Post"]||ee.thread.isDead&&!ee.thread.isArchived||ee.db.set({boardID:ee.thread.board.ID,threadID:ee.thread.ID,val:0}),ee.updatePosition(),ee.setLine(),ee.update()},sync(){if(null==ee.lastReadPost)return;const e=ee.db.get({boardID:ee.thread.board.ID,threadID:ee.thread.ID,defaultValue:0});if(ee.lastReadPost>=e)return;ee.lastReadPost=e;const t=ee.thread.posts.keys;for(let e=ee.readCount,o=t.length;e<o;e++){var n=+t[e];if(!ee.thread.posts.get(n).isFetchedQuote){if(n>ee.lastReadPost)break;ee.posts.delete(n),ee.postsQuotingYou.delete(n)}ee.readCount++}return ee.updatePosition(),ee.setLine(),ee.update()},addPost(){if(!(this.isFetchedQuote||this.isClone||(ee.order.push(this),this.ID<=ee.lastReadPost||this.isHidden||_.isYou(this))))return ee.posts.add(ee.posts.last=this.ID),ee.addPostQuotingYou(this),null!=ee.position?ee.position:ee.position=ee.order[this.ID]},addPostQuotingYou(e){
|
||
for(var t of e.nodes.quotelinks)if(_.db?.get(ze.postDataFromLink(t)))return ee.postsQuotingYou.add(ee.postsQuotingYou.last=e.ID),void ee.openNotification(e)},openNotification(e,t=" replied to you"){if(!Ke.areNotificationsEnabled)return;const n=new Notification(`${e.info.nameBlock}${t}`,{body:e.commentDisplay(),icon:h.logo});return n.onclick=function(){return Ke.scrollToIfNeeded(e.nodes.bottom,!0),window.focus()},n.onshow=()=>setTimeout((()=>n.close()),7e3)},onUpdate:()=>Ve.queueTask((function(){return ee.setLine(),ee.read(),ee.update()})),readSinglePost(e){const{ID:t}=e;if(ee.posts.has(t))return ee.posts.delete(t),ee.postsQuotingYou.delete(t),ee.updatePosition(),ee.saveLastReadPost(),ee.update()},read:f(100,(function(e){if(ee.posts.size||ee.readCount===ee.thread.posts.keys.length||ee.saveLastReadPost(),a.hidden||!ee.posts.size)return;let t=0;for(;ee.position;){var{ID:n,data:o}=ee.position,{bottom:i}=o.nodes;if(i.getBoundingClientRect().height&&Ke.getBottomOf(i)<=-1)break;t++,
|
||
ee.posts.delete(n),ee.postsQuotingYou.delete(n),ee.position=ee.position.next}return t?(ee.updatePosition(),ee.saveLastReadPost(),e?ee.update():void 0):void 0})),updatePosition(){for(;ee.position&&!ee.posts.has(ee.position.ID);)ee.position=ee.position.next},saveLastReadPost:f(2e3,(function(){let e;if(Ve.forceSync("Remember Last Read Post"),!t["Remember Last Read Post"]||!ee.db)return;const n=ee.thread.posts.keys;for(let t=ee.readCount,o=n.length;t<o;t++){if(e=+n[t],!ee.thread.posts.get(e).isFetchedQuote){if(ee.posts.has(e))break;ee.lastReadPost=e}ee.readCount++}return!ee.thread.isDead||ee.thread.isArchived?ee.db.set({boardID:ee.thread.board.ID,threadID:ee.thread.ID,val:ee.lastReadPost}):void 0})),setLine(e){if(t["Unread Line"]){if(ee.hr.hidden||a.hidden||!0===e){const e=ee.linePosition;if(ee.linePosition=ee.positionPrev()){if(ee.linePosition!==e){let e=ee.linePosition.data.nodes.bottom;"BR"===e.nextSibling?.tagName&&(e=e.nextSibling),Ve.after(e,ee.hr)}}else Ve.rm(ee.hr)}
|
||
return ee.hr.hidden=ee.linePosition===ee.order.last}},update(){const e=ee.posts.size,o=ee.postsQuotingYou.size;if(t["Unread Count"]){const n=t["Quoted Title"]&&o?"(!) ":"",i=e||!t["Hide Unread Count at (0)"]?`(${e}) `:"",r=ee.thread.isDead?ee.title.replace("-",ee.thread.isArchived?"- Archived -":"- 404 -"):ee.title;a.title=`${n}${i}${r}`}if(ee.saveThreadWatcherCount(),t["Unread Favicon"]&&"yotsuba"===n.SITE.software){const{isDead:t}=ee.thread;return h.set(o?t?"unreadDeadY":"unreadY":e?t?"unreadDead":"unread":t?"dead":"default")}},saveThreadWatcherCount:f(2e3,(function(){if(Ve.forceSync("Remember Last Read Post"),t["Remember Last Read Post"]&&(!ee.thread.isDead||ee.thread.isArchived)){let e;const o=!t["Require OP Quote Link"]&&_.isYou(ee.thread.OP)?ee.posts:ee.postsQuotingYou;if(o.size){if(!o.has(o.last)){o.last=0,e=ee.thread.posts.keys;for(let t=e.length-1;t>=0;t--)if(o.has(+e[t])){o.last=e[t];break}}}else o.last=0;return ae.update(n.SITE.ID,ee.thread.board.ID,ee.thread.ID,{
|
||
last:ee.thread.lastPost,isDead:ee.thread.isDead,isArchived:ee.thread.isArchived,unread:ee.posts.size,quotingYou:o.last||0})}}))},te={statuses:m(),init(){if("index"===n.VIEW&&t["Thread Expansion"])return t["JSON Index"]?Ve.on(a,"IndexRefreshInternal",this.onIndexRefresh):l.Thread.push({name:"Expand Thread",cb(){return te.setButton(this)}})},setButton(e){let t;if(e.nodes.root&&(t=Ve(".summary",e.nodes.root)))return t.textContent=n.SITE.Build.summaryText("+",...t.textContent.match(/\d+/g)),t.style.cursor="pointer",Ve.on(t,"click",te.cbToggle)},disconnect(e){if("thread"!==n.VIEW&&t["Thread Expansion"]){for(var o in te.statuses){var i,r=te.statuses[o];(i=r.req)&&(delete r.req,i.abort()),delete te.statuses[o]}return e?void 0:Ve.off(a,"IndexRefreshInternal",this.onIndexRefresh)}},onIndexRefresh:()=>(te.disconnect(!0),n.BOARD.threads.forEach((e=>te.setButton(e)))),cbToggle(e){if(!Ve.modifiedClick(e))return e.preventDefault(),te.toggle(ze.threadFromNode(this))},cbToggleBottom(e){
|
||
if(Ve.modifiedClick(e))return;e.preventDefault();const t=ze.threadFromNode(this);Ve.rm(this);const{bottom:n}=t.nodes.root.getBoundingClientRect();return te.toggle(t),window.scrollBy(0,t.nodes.root.getBoundingClientRect().bottom-n)},toggle(e){let t;if(e.nodes.root&&(t=Ve(".summary",e.nodes.root)))return e.ID in te.statuses?te.contract(e,t,e.nodes.root):te.expand(e,t)},expand(e,t){let o;return te.statuses[e]=o={},t.textContent=n.SITE.Build.summaryText("...",...t.textContent.match(/\d+/g)),o.req=Ve.cache(n.SITE.urls.threadJSON({boardID:e.board.ID,threadID:e.ID}),(function(){if(this===o.req)return delete o.req,te.parse(this,e,t)})),o.numReplies=u(n.SITE.selectors.replyOriginal,e.nodes.root).length},contract(e,o,a){let i;const r=te.statuses[e];if(delete te.statuses[e],i=r.req)return delete r.req,i.abort(),void(o&&(o.textContent=n.SITE.Build.summaryText("+",...o.textContent.match(/\d+/g))));let s=u(".thread > .replyContainer",a);r.numReplies&&(s=s.slice(0,-r.numReplies));let l=0,d=0
|
||
;for(var c of s){if(t["Quote Inlining"])for(var h;h=Ve(".inlined",c);)h.click();l++,"file"in ze.postFromRoot(c)&&d++,Ve.rm(c)}return ue.enabled&&Ve.event("PostsRemoved",null,o.parentNode),o.textContent=n.SITE.Build.summaryText("+",l,d),Ve.rm(Ve(".summary-bottom",a))},parse(e,t,o){let a;if(![200,304].includes(e.status))return void(o.textContent=e.status?`Error ${e.statusText} (${e.status})`:"Connection Error");n.SITE.Build.spoilerRange[t.board]=e.response.posts[0].custom_spoiler;const i=[],r=[];let s=0;for(var l of e.response.posts){var d;l.no!==t.ID&&(!(d=t.posts.get(l.no))||d.isFetchedQuote?(a=n.SITE.Build.postFromObject(l,t.board.ID),"file"in(d=new H(a,t,t.board))&&s++,i.push(d),r.push(a)):("file"in d&&s++,({root:a}=d.nodes),r.push(a)))}Ot.callbackNodes("Post",i),Ve.after(o,r),Ve.event("PostsInserted",null,o.parentNode);const c=r.length;if(o.textContent=n.SITE.Build.summaryText("-",c,s),a){const e=o.cloneNode(!0);return e.classList.add("summary-bottom"),
|
||
Ve.on(e,"click",te.cbToggleBottom),Ve.after(a,e)}}},ne={lastReadPost:m(),hr:m(),markReadLink:m(),init(){if("index"===n.VIEW&&t["Remember Last Read Post"]&&t["Unread Line in Index"])return this.enabled=!0,this.db=new y("lastReadPosts",this.sync),l.Thread.push({name:"Unread Line in Index",cb:this.node}),Ve.on(a,"IndexRefreshInternal",this.onIndexRefresh),Ve.on(a,"PostsInserted PostsRemoved",this.onPostsInserted)},node(){if(ne.lastReadPost[this.fullID]=ne.db.get({boardID:this.board.ID,threadID:this.ID})||0,!ue.enabled)return ne.update(this)},onIndexRefresh(e){if(!e.detail.isCatalog)return(()=>{const t=[];for(var o of e.detail.threadIDs){var a=n.threads.get(o);t.push(ne.update(a))}return t})()},onPostsInserted(e){if(e.target===ue.root)return;const n=ze.threadFromNode(e.target);if(!n||n.nodes.root!==e.target)return;const o=!!ne.hr[n.fullID]?.parentNode;return ne.update(n),
|
||
t["Scroll to Last Read Post"]&&"PostsInserted"===e.type&&!o&&ne.hr[n.fullID]?.parentNode?Ke.scrollToIfNeeded(ne.hr[n.fullID],!0):void 0},sync:()=>n.threads.forEach((function(e){const t=ne.db.get({boardID:e.board.ID,threadID:e.ID})||0;if(t!==ne.lastReadPost[e.fullID]&&(ne.lastReadPost[e.fullID]=t,e.nodes.root?.parentNode))return ne.update(e)})),update(e){let t;const o=ne.lastReadPost[e.fullID];let a=0,i=0,r=null;e.posts.forEach((function(t){if(t.isReply&&e.nodes.root.contains(t.nodes.root)){if(a++,t.ID<=o)return i++;if((!r||t.ID<r.ID)&&!t.isHidden&&!_.isYou(t))return r=t}}));let s=ne.hr[e.fullID];r&&(i||o===e.OP.ID&&(!Ve(n.SITE.selectors.summary,e.nodes.root)||e.ID in te.statuses))?(s||(s=ne.hr[e.fullID]=Ve.el("hr",{className:"unread-line"})),Ve.before(r.nodes.root,s)):Ve.rm(s);const l=a?r||!i:ue.enabled?e.lastPost>o:e.OP.ID>o;e.nodes.root.classList.toggle("unread-thread",l);let d=ne.markReadLink[e.fullID];return d||(d=ne.markReadLink[e.fullID]=Ve.el("a",{
|
||
className:"unread-mark-read brackets-wrap",href:"javascript:;",textContent:"Mark Read"}),Ve.on(d,"click",ne.markRead)),(t=Ve(n.SITE.selectors.threadDivider,e.nodes.root))?Ve.before(t,d):Ve.add(e.nodes.root,d)},markRead(){const e=ze.threadFromNode(this);return ne.lastReadPost[e.fullID]=e.lastPost,ne.db.set({boardID:e.board.ID,threadID:e.ID,val:e.lastPost}),Ve.rm(ne.hr[e.fullID]),e.nodes.root.classList.remove("unread-thread"),ae.update(n.SITE.ID,e.board.ID,e.ID,{last:e.lastPost,unread:0,quotingYou:0})}},oe={init(){let e;if(this.enabled=t["Thread Watcher"]){switch(this.shortcut=e=Ve.el("a",{id:"watcher-link",textContent:"👁︎",title:"Thread Watcher",href:"javascript:;"}),this.db=new y("watchedThreads",this.refresh,!0),this.dbLM=new y("watcherLastModified",null,!0),this.dialog=L.dialog("thread-watcher",{
|
||
innerHTML:'<div class="move">\n Thread Watcher <a class="refresh" title="Check threads" href="javascript:;">🗘</a>\n <span id="watcher-status"></span>\n <a class="menu-button" href="javascript:;">🞃</a>\n <a class="close" href="javascript:;">×</a>\n</div>\n<div id="watched-threads"></div>\n'}),this.status=Ve("#watcher-status",this.dialog),this.list=this.dialog.lastElementChild,this.refreshButton=Ve(".refresh",this.dialog),this.closeButton=Ve(".move > .close",this.dialog),this.unreaddb=ee.db||ne.db||new y("lastReadPosts"),this.unreadEnabled=t["Remember Last Read Post"],Ve.on(a,"QRPostSuccessful",this.cb.post),Ve.on(e,"click",this.toggleWatcher),Ve.on(this.refreshButton,"click",this.buttonFetchAll),Ve.on(this.closeButton,"click",this.toggleWatcher),this.menu.addHeaderMenuEntry(),Ve.onExists(i,"body",this.addDialog),n.VIEW){case"index":Ve.on(a,"IndexUpdate",this.cb.onIndexUpdate);break;case"thread":Ve.on(a,"ThreadUpdate",this.cb.onThreadRefresh)}
|
||
if(t["Fixed Thread Watcher"]&&Ve.addClass(i,"fixed-watcher"),t["Persistent Thread Watcher"]||(Ve.addClass(oe.shortcut,"disabled"),this.dialog.hidden=!0),Ke.addShortcut("watcher",e,510),oe.initLastModified(),oe.fetchAuto(),Ve.on(window,"visibilitychange focus",(()=>Ve.queueTask(oe.fetchAuto))),t.Menu&&ue.enabled&&Q.menu.addEntry({el:Ve.el("a",{href:"javascript:;",className:"has-shortcut-text"},{innerHTML:'<span></span><span class="shortcut-text">Alt+click</span>'}),order:6,open({thread:e}){return"catalog"===t["Index Mode"]&&(this.el.firstElementChild.textContent=oe.isWatched(e)?"Unwatch":"Watch",this.cb&&Ve.off(this.el,"click",this.cb),this.cb=function(){return Ve.event("CloseMenu"),oe.toggle(e)},Ve.on(this.el,"click",this.cb),!0)}}),["index","thread"].includes(n.VIEW))return l.Post.push({name:"Thread Watcher",cb:this.node}),l.CatalogThread.push({name:"Thread Watcher",cb:this.catalogNode})}},isWatched:e=>!!oe.db?.get({boardID:e.board.ID,threadID:e.ID}),isWatchedRaw:(e,t)=>!!oe.db?.get({
|
||
boardID:e,threadID:t}),setToggler:(e,t)=>(e.classList.toggle("watched",t),e.title=(t?"Unwatch":"Watch")+" Thread"),node(){let e;if(this.isReply)return;this.isClone?e=Ve(".watch-thread-link",this.nodes.info):(e=Ve.el("a",{href:"javascript:;",className:"watch-thread-link"}),Ve.before(Ve("input",this.nodes.info),e));const t=n.SITE.ID,o=this.board.ID,a=this.thread.ID,i=oe.db.get({siteID:t,boardID:o,threadID:a});return oe.setToggler(e,!!i),Ve.on(e,"click",oe.cb.toggle),i&&null==i.excerpt?Ve.queueTask((()=>oe.update(t,o,a,{excerpt:ze.threadExcerpt(this.thread)}))):void 0},catalogNode(){return oe.isWatched(this.thread)&&Ve.addClass(this.nodes.root,"watched"),Ve.on(this.nodes.root,"mousedown click",(e=>{if(0===e.button&&e.altKey)return"click"===e.type&&oe.toggle(this.thread),e.preventDefault()}))},addDialog(){if(Ot.isThisPageLegit())return oe.build(),Ve.prepend(a.body,oe.dialog)},toggleWatcher:()=>(Ve.toggleClass(oe.shortcut,"disabled"),oe.dialog.hidden=!oe.dialog.hidden),cb:{openAll(){
|
||
if(!Ve.hasClass(this,"disabled")){for(var e of u("a.watcher-link",oe.list))Ve.open(e.href);return Ve.event("CloseMenu")}},openUnread(){if(!Ve.hasClass(this,"disabled")){for(var e of u(".replies-unread > a.watcher-link",oe.list))Ve.open(e.href);return Ve.event("CloseMenu")}},openDeads(){if(!Ve.hasClass(this,"disabled")){for(var e of u(".dead-thread > a.watcher-link",oe.list))Ve.open(e.href);return Ve.event("CloseMenu")}},pruneDeads(){if(!Ve.hasClass(this,"disabled")){for(var{siteID:e,boardID:t,threadID:n,data:o}of oe.getAll())o.isDead&&oe.db.delete({siteID:e,boardID:t,threadID:n});return oe.refresh(),Ve.event("CloseMenu")}},dismiss(){for(var{siteID:e,boardID:t,threadID:n,data:o}of oe.getAll())o.quotingYou&&oe.update(e,t,n,{dismiss:o.quotingYou||0});return Ve.event("CloseMenu")},toggle(){const{thread:e}=ze.postFromNode(this);return oe.toggle(e)},rm(){const{siteID:e}=this.parentNode.dataset,[t,n]=this.parentNode.dataset.fullID.split(".");return oe.rm(e,t,+n)},post(e){
|
||
const{boardID:o,threadID:a,postID:i}=e.detail,r=K.delay();if(i===a){if(t["Auto Watch"])return oe.addRaw(o,a,{},r)}else if(t["Auto Watch Reply"])return oe.add(n.threads.get(o+"."+a)||new I(a,n.boards[o]||new J(o)),r)},onIndexUpdate(e){const{db:o}=oe,a=n.SITE.ID,i=n.BOARD.ID;let r=0;for(var s in o.data[a].boards[i]){var l=o.data[a].boards[i][s];if(!l?.isDead&&!e.detail.threads.includes(`${i}.${s}`)){if(!e.detail.threads.some((e=>+e.split(".")[1]>s)))continue;t["Auto Prune"]||!l||"object"!=typeof l?(o.delete({boardID:i,threadID:s}),r++):oe.fetchStatus({siteID:a,boardID:i,threadID:s,data:l})}}if(r)return oe.refresh()},onThreadRefresh(e){const t=n.threads.get(e.detail.threadID);if(e.detail[404]&&oe.isWatched(t))return oe.add(t)}},requests:[],fetched:0,fetch(e,{siteID:t,force:o},a,i){0===oe.requests.length&&(oe.status.textContent="...",Ve.addClass(oe.refreshButton,"spin"));const r=t===n.SITE.ID?Ve.ajax:Ue.ajax;o&&delete Ve.lastModified.ThreadWatcher?.[e]
|
||
;const s=Ve.whenModified(e,"ThreadWatcher",(function(){if(!this.finished)return this.finished=!0,oe.fetched++,oe.fetched===oe.requests.length?oe.clearRequests():oe.status.textContent=`${Math.round(oe.fetched/oe.requests.length*100)}%`,i.apply(this,a)}),{timeout:A,ajax:r});return oe.requests.push(s)},clearRequests:()=>(oe.requests=[],oe.fetched=0,oe.status.textContent="",Ve.rmClass(oe.refreshButton,"spin")),abort(){for(var e of(delete oe.syncing,oe.requests))e.finished||(e.finished=!0,e.abort());return oe.clearRequests()},initLastModified(){const e=Ve.lastModified.ThreadWatcher||(Ve.lastModified.ThreadWatcher=m());for(var t in oe.dbLM.data){var n=oe.dbLM.data[t];for(var o in n.boards){var a=n.boards[o];if(oe.db.get({siteID:t,boardID:o}))for(var i in a){var r=a[i];e[i]=r}else oe.dbLM.delete({siteID:t,boardID:o})}}},fetchAuto(){let e;if(clearTimeout(oe.timeout),!t["Auto Update Thread Watcher"])return
|
||
;const{db:n}=oe,o=t["Show Page"]||oe.unreadEnabled&&t["Show Unread Count"]?3e5:2*v,i=Date.now();return(i-o>=(e=n.data.lastChecked||0)||e>i)&&!a.hidden&&a.hasFocus()&&oe.fetchAllStatus(o),oe.timeout=setTimeout(oe.fetchAuto,o)},buttonFetchAll:()=>oe.syncing||oe.requests.length?oe.abort():oe.fetchAllStatus(),fetchAllStatus(e=0){oe.status.textContent="...",Ve.addClass(oe.refreshButton,"spin"),oe.syncing=!0;const t=[oe.db,oe.unreaddb,_.db].filter((e=>e));let n=0;return t.map((o=>o.forceSync((function(){if(++n===t.length){let t;if(!oe.syncing)return;if(delete oe.syncing,0>(t=Date.now()-(oe.db.data.lastChecked||0))||t>=e){let e;const{db:t}=oe,n=Date.now(),a=!(n-2*v<(e=t.data.lastChecked2||0)&&e<=n),i=oe.getAll(!0);for(var o of i)oe.fetchBoard(o,a);t.setLastChecked(),a&&t.setLastChecked("lastChecked2")}if(oe.fetched===oe.requests.length)return oe.clearRequests()}}))))},fetchBoard(e,o){if(!e.some((e=>!e.data.isDead)))return;let a=!1;for(var i of e){var{data:r}=i
|
||
;r.isDead||-1===r.last||(t["Show Page"]&&null==r.page&&(a=!0),null==r.modified&&(a=i.force=!0))}const{siteID:s,boardID:l}=e[0],d=n.sites[s];if(!d)return;const c=o&&d.threadModTimeIgnoresSage?"catalogJSON":"threadsListJSON",h=d.urls[c]?.({siteID:s,boardID:l});return h?oe.fetch(h,{siteID:s,force:a},[e,h],oe.parseBoard):void 0},parseBoard(e,o){let a,i;if(200!==this.status)return;const{siteID:r,boardID:s}=e[0],l=this.getResponseHeader("Last-Modified");oe.dbLM.extend({siteID:r,boardID:s,val:Ve.item(o,l)});const d=m();let c=0,h=0,u=null;try{c=this.response[0]?.threads.length||0;for(let e=0;e<this.response.length;e++)for(var p of(a=this.response[e],a.threads))d[p.no]={page:e+1,index:h,modified:p.last_modified,replies:p.replies},h++,(null==u||p.no<u)&&(u=p.no)}catch(t){for(i of e)oe.fetchStatus(i)}for(i of e){var{threadID:g,data:f}=i;if(d[g]){var b,A,v;if(({page:a,index:b,modified:A,replies:v}=d[g]),t["Show Page"]){var w=n.sites[r].isPrunedByAge?.({siteID:r,boardID:s})?g===u:b>=h-c
|
||
;oe.update(r,s,g,{page:a,lastPage:w})}oe.unreadEnabled&&t["Show Unread Count"]&&(A!==f.modified||null!=v&&v!==f.replies)&&((i.newData||(i.newData={})).modified=A,oe.fetchStatus(i))}else oe.fetchStatus(i)}},fetchStatus(e){const{siteID:t,boardID:o,threadID:a,data:i,force:r}=e,s=n.sites[t]?.urls.threadJSON?.({siteID:t,boardID:o,threadID:a});if(s&&(!i.isDead||r)&&-1!==i.last)return oe.fetch(s,{siteID:t,force:r},[e],oe.parseStatus)},parseStatus(e,o){let a,i,{siteID:r,boardID:s,threadID:l,data:d,newData:c,force:h}=e;const u=n.sites[r];if(200===this.status&&this.response){let e;i=this.response.posts[this.response.posts.length-1].no;const n=this.response.posts.length-1;if(a=e=!(!this.response.posts[0].archived&&!o),a&&t["Auto Prune"])return void oe.rm(r,s,l);if(i===d.last&&a===d.isDead&&e===d.isArchived)return;const h=oe.unreaddb.get({siteID:r,boardID:s,threadID:l,defaultValue:0});let b=d.unread||0,A=d.quotingYou||0;const v=!!_.db?.get({siteID:r,boardID:s,threadID:l,postID:l})
|
||
;for(var p of this.response.posts)if(!(p.no<=(d.last||0)||p.no<=h||_.db?.get({siteID:r,boardID:s,threadID:l,postID:p.no}))){var g=!1;if(!t["Require OP Quote Link"]&&v)g=!0;else if(_.db&&p.com){var f,m=u.regexp.quotelinkHTML;for(m.lastIndex=0;f=m.exec(p.com);)if(_.db.get({siteID:r,boardID:f[1]?encodeURIComponent(f[1]):s,threadID:f[2]||l,postID:f[3]||f[2]||l})){g=!0;break}}(!b||!A&&g)&&We.isHidden(u.Build.parseJSON(p,{siteID:r,boardID:s}))||(b++,g&&(A=p.no))}return c||(c={}),Ve.extend(c,{last:i,replies:n,isDead:a,isArchived:e,unread:b,quotingYou:A}),oe.update(r,s,l,c)}if(404===this.status){const t=n.sites[r]?.urls.archivedThreadJSON?.({siteID:r,boardID:s,threadID:l});return!o&&t?oe.fetch(t,{siteID:r,force:h},[e,!0],oe.parseStatus):u.mayLackJSON&&null==d.last?oe.update(r,s,l,{last:-1}):oe.update(r,s,l,{isDead:!0})}},getAll(e){const o=[];for(var a in oe.db.data){var i=oe.db.data[a];for(var r in i.boards){var s,l=i.boards[r]
|
||
;if(!t["Current Board"]||a===n.SITE.ID&&r===n.BOARD.ID)for(var d in e&&o.push(s=[]),l){var c=l[d];c&&"object"==typeof c&&(e?s:o).push({siteID:a,boardID:r,threadID:d,data:c})}}}return o},makeLine(e,o,a,i){let r;const s=Ve.el("a",{textContent:"✕",href:"javascript:;"});Ve.on(s,"click",oe.cb.rm);let{excerpt:l,isArchived:d}=i;l||(l=`/${o}/ - No.${a}`),t["Show Site Prefix"]&&(l=oe.prefixes[e]+l);const c=Ve.el("a",{href:n.sites[e]?.urls.thread({siteID:e,boardID:o,threadID:a},d)||"",title:l,className:"watcher-link"});if(t["Show Page"]&&null!=i.page&&(r=Ve.el("span",{textContent:`[${i.page}]`,className:"watcher-page"}),Ve.add(c,r)),oe.unreadEnabled&&t["Show Unread Count"]&&null!=i.unread){const e=Ve.el("span",{textContent:`(${i.unread})`,className:"watcher-unread"});Ve.add(c,e)}const h=Ve.el("span",{textContent:l,className:"watcher-title"});Ve.add(c,h);const u=Ve.el("div"),p=`${o}.${a}`;return u.dataset.fullID=p,u.dataset.siteID=e,
|
||
"thread"===n.VIEW&&p===`${n.BOARD}.${n.THREADID}`&&Ve.addClass(u,"current"),i.isDead&&Ve.addClass(u,"dead-thread"),t["Show Page"]&&(i.lastPage&&Ve.addClass(u,"last-page"),null!=i.page&&(u.dataset.page=i.page)),oe.unreadEnabled&&t["Show Unread Count"]&&(0===i.unread&&Ve.addClass(u,"replies-read"),i.unread&&Ve.addClass(u,"replies-unread"),(i.quotingYou||0)>(i.dismiss||0)&&Ve.addClass(u,"replies-quoting-you")),Ve.add(u,[s,Ve.tn(" "),c]),u},setPrefixes(e){const t=m();for(var{siteID:n}of e)if(!(n in t)){for(var o=0,a="",i=Object.keys(t);i.length>0;){o++,a=n.slice(0,o);var r=[];for(var s of i)s.slice(0,o)===a?r.push(s):t[s].length<o&&(t[s]=s.slice(0,o));i=r}t[n]=a}return oe.prefixes=t},build(){const e=[],t=oe.getAll();for(var{siteID:o,boardID:a,threadID:i,data:r}of(oe.setPrefixes(t),t)){var s;null==r.excerpt&&o===n.SITE.ID&&(s=n.threads.get(`${a}.${i}`))&&s.OP&&oe.db.extend({boardID:a,threadID:i,val:{excerpt:ze.threadExcerpt(s)}}),e.push(oe.makeLine(o,a,i,r))}const{list:l}=oe
|
||
;return Ve.rmAll(l),Ve.add(l,e),oe.refreshIcon()},refresh(){if(oe.build(),n.threads.forEach((function(e){const t=oe.isWatched(e);if(e.OP)for(var n of[e.OP,...e.OP.clones]){var o;(o=Ve(".watch-thread-link",n.nodes.info))&&oe.setToggler(o,t)}if(e.catalogView)return e.catalogView.nodes.root.classList.toggle("watched",t)})),t["Pin Watched Threads"])return Ve.event("SortIndex",{deferred:"catalog"!==t["Index Mode"]})},refreshIcon(){for(var e of["replies-unread","replies-quoting-you"])oe.shortcut.classList.toggle(e,!!Ve(`.${e}`,oe.dialog))},update(e,n,o,a){let i,r,s,l;if(!(i=oe.db?.get({siteID:e,boardID:n,threadID:o})))return;if(a.isDead&&t["Auto Prune"])return void oe.rm(e,n,o);if(a.isDead||-1===a.last)for(r of["isArchived","page","lastPage","unread","quotingyou"])r in a||(a[r]=void 0);null!=a.last&&a.last<i.last&&(a.modified=void 0);let d=0;for(r in a)l=a[r],i[r]!==l&&d++;if(d){if(oe.db.extend({siteID:e,boardID:n,threadID:o,val:a}),
|
||
s=Ve(`#watched-threads > [data-site-i-d='${e}'][data-full-i-d='${n}.${o}']`,oe.dialog)){const t=oe.makeLine(e,n,o,i);return Ve.replace(s,t),oe.refreshIcon()}return oe.refresh()}},set404(e,n,o){let a;return(a=oe.db?.get({boardID:e,threadID:n}))?t["Auto Prune"]?(oe.db.delete({boardID:e,threadID:n}),o()):a.isDead&&null==a.isArchived&&null==a.page&&null==a.lastPage&&null==a.unread&&null==a.quotingYou?o():oe.db.extend({boardID:e,threadID:n,val:{isDead:!0,isArchived:void 0,page:void 0,lastPage:void 0,unread:void 0,quotingYou:void 0}},o):o()},toggle(e){const t=n.SITE.ID,o=e.board.ID,a=e.ID;return oe.db.get({boardID:o,threadID:a})?oe.rm(t,o,a):oe.add(e)},add(e,o){const a={},i=n.SITE.ID,r=e.board.ID,s=e.ID;if(e.isDead){if(t["Auto Prune"]&&oe.db.get({boardID:r,threadID:s}))return void oe.rm(i,r,s,o);a.isDead=!0}return e.OP&&(a.excerpt=ze.threadExcerpt(e)),oe.addRaw(r,s,a,o)},addRaw(e,o,a,i){const r=oe.db.get({boardID:e,threadID:o,defaultValue:m()});delete r.last,delete r.modified,Ve.extend(r,a),
|
||
oe.db.set({boardID:e,threadID:o,val:r},i),oe.refresh();const s={siteID:n.SITE.ID,boardID:e,threadID:o,data:a,force:!0};return t["Show Page"]&&!a.isDead?oe.fetchBoard([s]):oe.unreadEnabled&&t["Show Unread Count"]?oe.fetchStatus(s):void 0},rm:(e,t,n,o)=>(oe.db.delete({siteID:e,boardID:t,threadID:n},o),oe.refresh()),menu:{init(){if(!t["Thread Watcher"])return;const e=this.menu=new L.Menu("thread watcher");return Ve.on(Ve(".menu-button",oe.dialog),"click",(function(t){return e.toggle(t,this,oe)})),this.addMenuEntries()},addHeaderMenuEntry(){if("thread"!==n.VIEW)return;const e=Ve.el("a",{href:"javascript:;"});return Ke.menu.addEntry({el:e,order:60,open(){const[t,o,a]=oe.db.get({boardID:n.BOARD.ID,threadID:n.THREADID})?["unwatch-thread","watch-thread","Unwatch thread"]:["watch-thread","unwatch-thread","Watch thread"];return Ve.addClass(e,t),Ve.rmClass(e,o),e.textContent=a,!0}}),Ve.on(e,"click",(()=>oe.toggle(n.threads.get(`${n.BOARD}.${n.THREADID}`))))},addMenuEntries(){const e=[]
|
||
;for(var{text:t,title:n,cb:o,open:a}of(e.push({text:"Open all threads",cb:oe.cb.openAll,open(){return this.el.classList.toggle("disabled",!oe.list.firstElementChild),!0}}),e.push({text:"Open unread threads",cb:oe.cb.openUnread,open(){return this.el.classList.toggle("disabled",!Ve(".replies-unread",oe.list)),!0}}),e.push({text:"Open dead threads",cb:oe.cb.openDeads,open(){return this.el.classList.toggle("disabled",!Ve(".dead-thread",oe.list)),!0}}),e.push({text:"Prune dead threads",cb:oe.cb.pruneDeads,open(){return this.el.classList.toggle("disabled",!Ve(".dead-thread",oe.list)),!0}}),e.push({text:"Dismiss posts quoting you",title:"Unhighlight the thread watcher icon and threads until there are new replies quoting you.",cb:oe.cb.dismiss,open(){return this.el.classList.toggle("disabled",!Ve.hasClass(oe.shortcut,"replies-quoting-you")),!0}}),e)){var i={el:Ve.el("a",{textContent:t,href:"javascript:;"})};n&&(i.el.title=n),Ve.on(i.el,"click",o),i.open=a.bind(i),this.menu.addEntry(i)}
|
||
for(var r in c.threadWatcher){var s=c.threadWatcher[r];this.addCheckbox(r,s[1])}},addCheckbox(e,t){const n={type:"thread watcher",el:L.checkbox(e,e.replace(" Thread Watcher",""))};n.el.title=t;const o=n.el.firstElementChild;return"Show Unread Count"!==e||oe.unreadEnabled||(o.disabled=!0,Ve.addClass(n.el,"disabled"),n.el.title+="\n[Remember Last Read Post is disabled.]"),Ve.on(o,"change",Ve.cb.checked),["Current Board","Show Page","Show Unread Count","Show Site Prefix"].includes(e)&&Ve.on(o,"change",oe.refresh),["Show Page","Show Unread Count","Auto Update Thread Watcher"].includes(e)&&Ve.on(o,"change",oe.fetchAuto),this.menu.addEntry(n)}}},ae=oe;const ie=Symbol("isEscaped"),re=new Set(["area","base","br","col","embed","hr","img","input","link","meta","source","track","wbr"]),se=Symbol("hFragment");function le(e,t,...n){let a=e===se?"":`<${e}`;if(t)for(const[e,n]of Object.entries(t))(n||0===n)&&(a+=` ${e}`,!0!==n&&(a+=`="${o(n.toString())}"`));e!==se&&(a+=">");const i=e!==se&&re.has(e)
|
||
;if(i){if(n.length)throw new TypeError(`${e} is a void html element and can't have child elements`)}else for(const e of n)null!=e&&""!==e&&(e instanceof Object&&"innerHTML"in e&&e[ie]?a+=e.innerHTML:a+=o(e.toString()));return i||e===se||(a+=`</${e}>`),{innerHTML:a,[ie]:!0}}class de{static archiveTags={"\n":{innerHTML:"<br>"},"[b]":{innerHTML:"<b>"},"[/b]":{innerHTML:"</b>"},"[spoiler]":{innerHTML:"<s>"},"[/spoiler]":{innerHTML:"</s>"},"[code]":{innerHTML:'<pre class="prettyprint">'},"[/code]":{innerHTML:"</pre>"},"[moot]":{innerHTML:'<div style="padding:5px;margin-left:.5em;border-color:#faa;border:2px dashed rgba(255,0,0,.1);border-radius:2px">'},"[/moot]":{innerHTML:"</div>"},"[banned]":{innerHTML:'<strong style="color: red;">'},"[/banned]":{innerHTML:"</strong>"},"[fortune]":e=>({innerHTML:'<span class="fortune" style="color:'+o(e.match(/#\w+|$/)[0])+'"><b>'}),"[/fortune]":{innerHTML:"</b></span>"},"[i]":{innerHTML:'<span class="mu-i">'},"[/i]":{innerHTML:"</span>"},"[red]":{
|
||
innerHTML:'<span class="mu-r">'},"[/red]":{innerHTML:"</span>"},"[green]":{innerHTML:'<span class="mu-g">'},"[/green]":{innerHTML:"</span>"},"[blue]":{innerHTML:'<span class="mu-b">'},"[/blue]":{innerHTML:"</span>"}};constructor(e,t,o,a,i){let r,s;if(this.boardID=e,this.threadID=t,this.postID=o,this.root=a,this.quoter=i,r=n.posts.get(`${this.boardID}.${this.postID}`))this.insert(r);else{if((r=ue.replyData?.[`${this.boardID}.${this.postID}`])&&(s=n.threads.get(`${this.boardID}.${this.threadID}`))){const e=n.boards[this.boardID];return r=new H(n.SITE.Build.postFromObject(r,this.boardID),s,e,{isFetchedQuote:!0}),Ot.callbackNodes("Post",[r]),void this.insert(r)}if(this.root.textContent=`Loading post No.${this.postID}...`,this.threadID){const e=this;Ve.cache(n.SITE.urls.threadJSON({boardID:this.boardID,threadID:this.threadID}),(function({isCached:t}){return e.fetchedPost(this,t)}))}else this.archivedPost()}}insert(e){if(!this.root.parentNode)return;this.quoter||(this.quoter=e)
|
||
;const t=e.addClone(this.quoter.context,Ve.hasClass(this.root,"dialog"));Ot.callbackNodes("Post",[t]);const{nodes:n}=t;Ve.rmAll(n.root),Ve.add(n.root,n.post);const o=[...t.nodes.quotelinks,...t.nodes.backlinks];for(var i of o){var{boardID:r,postID:s}=ze.postDataFromLink(i);s===this.quoter.ID&&r===this.quoter.board.ID&&Ve.addClass(i,"forwardlink")}if(t.nodes.flag&&!de.flagCSS&&!(de.flagCSS=Ve('link[href^="//s.4cdn.org/css/flags."]'))){const e=Ve('link[href^="//s.4cdn.org/css/"]')?.href.match(/\d+(?=\.css$)|$/)[0]||Date.now();de.flagCSS=Ve.el("link",{rel:"stylesheet",href:`//s.4cdn.org/css/flags.${e}.css`}),Ve.add(a.head,de.flagCSS)}return Ve.rmAll(this.root),Ve.add(this.root,n.root),Ve.event("PostsInserted",null,this.root)}fetchedPost(e,t){let o;if(o=n.posts.get(`${this.boardID}.${this.postID}`))return void this.insert(o);const{status:a}=e;if(200!==a){if(a&&this.archivedPost())return;return Ve.addClass(this.root,"warning"),
|
||
void(this.root.textContent=404===a?`Thread No.${this.threadID} 404'd.`:a?`Error ${e.statusText} (${e.status}).`:"Connection Error")}const{posts:i}=e.response;for(o of(n.SITE.Build.spoilerRange[this.boardID]=i[0].custom_spoiler,i))if(o.no===this.postID)break;if(o.no!==this.postID){if(t){const e=n.SITE.urls.threadJSON({boardID:this.boardID,threadID:this.threadID});Ve.cleanCache((t=>t===e));const t=this;return void Ve.cache(e,(function(){return t.fetchedPost(this,!1)}))}if(this.archivedPost())return;return Ve.addClass(this.root,"warning"),void(this.root.textContent=`Post No.${this.postID} was not found.`)}const r=n.boards[this.boardID]||new J(this.boardID),s=n.threads.get(`${this.boardID}.${this.threadID}`)||new I(this.threadID,r);return o=new H(n.SITE.Build.postFromObject(o,this.boardID),s,r,{isFetchedQuote:!0}),Ot.callbackNodes("Post",[o]),this.insert(o)}archivedPost(){let e;if(!t["Resurrect Quotes"])return!1;if(!(e=Ze.to("post",{boardID:this.boardID,postID:this.postID})))return!1
|
||
;const n=Ze.data.post[this.boardID],o=/^https:\/\//.test(e)||"http:"===location.protocol;if(o||t["Exempt Archives from Encryption"]){const t=this;return Ue.cache(e,(function(){if(!o&&this.response?.media){const{media:e}=this.response;for(var a in e)/_link$/.test(a)&&(Ve.getOwn(e,a)?.match(/^http:\/\//)||delete e[a])}return t.parseArchivedPost(this.response,e,n)})),!0}return!1}parseArchivedPost(e,t,a){let i;if(i=n.posts.get(`${this.boardID}.${this.postID}`))return void this.insert(i);if(null==e)return Ve.addClass(this.root,"warning"),void(this.root.textContent=`Error fetching Post No.${this.postID} from ${a.name}.`);if(e.error)return Ve.addClass(this.root,"warning"),void(this.root.textContent=e.error);let r=(e.comment||"").split(/(\n|\[\/?(?:b|spoiler|code|moot|banned|fortune(?: color="#\w+")?|i|red|green|blue)\])/);r=r.map(((e,t)=>{if(t%2==1){var n=de.archiveTags[e.replace(/\ .*\]/,"]")];return"function"==typeof n?n(e):n}var a=">"===e[0]
|
||
;return e=e.replace(/(\[\/?[a-z]+):lit(\])/g,"$1$2").split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g).map(((e,t)=>t%2?`<span class="deadlink">${o(e)}</span>`:o(e))).join(""),{innerHTML:a?`<span class="quote">${e}</span>`:e}})),r={innerHTML:o.cat(r),[ie]:!0},this.threadID=+e.thread_num;const s={ID:this.postID,threadID:this.threadID,boardID:this.boardID,isReply:this.postID!==this.threadID};if(s.info={subject:e.title,email:e.email,name:e.name||"",tripcode:e.trip,capcode:(()=>{switch(e.capcode){case"M":return"Mod";case"A":return"Admin";case"D":return"Developer";case"V":return"Verified";case"F":return"Founder";case"G":return"Manager"}})(),uniqueID:e.poster_hash,flagCode:e.poster_country,flagCodeTroll:e.troll_country_code,flag:e.poster_country_name||e.troll_country_name,dateUTC:e.timestamp,dateText:e.fourchan_date,commentHTML:r},s.info.capcode&&delete s.info.uniqueID,e.media&&+e.media.banned)s.fileDeleted=!0;else if(e.media?.media_filename){let{thumb_link:n}=e.media
|
||
;"/"===n?.[0]&&(n=t.split("/",3).join("/")+n),Ze.securityCheck(n)||(n="");let a=Ze.to("file",{boardID:this.boardID,filename:e.media.media_orig});Ze.securityCheck(a)||(a=""),s.file={name:e.media.media_filename,url:a||("f"===this.boardID?`${location.protocol}//${O.flashHost()}/${this.boardID}/${encodeURIComponent(o(e.media.media_filename))}`:`${location.protocol}//${O.host()}/${this.boardID}/${e.media.media_orig}`),height:e.media.media_h,width:e.media.media_w,MD5:e.media.media_hash,size:Ve.bytesToString(e.media.media_size),thumbURL:n||`${location.protocol}//${O.thumbHost()}/${this.boardID}/${e.media.preview_orig}`,theight:e.media.preview_h,twidth:e.media.preview_w,isSpoiler:"1"===e.media.spoiler},/\.pdf$/.test(s.file.url)||(s.file.dimensions=`${s.file.width}x${s.file.height}`),"f"===this.boardID&&e.media.exif&&(s.file.tag=JSON.parse(e.media.exif).Tag)}s.extra=m()
|
||
;const l=n.boards[this.boardID]||new J(this.boardID),d=n.threads.get(`${this.boardID}.${this.threadID}`)||new I(this.threadID,l);return i=new H(n.SITE.Build.post(s),d,l,{isFetchedQuote:!0}),i.kill(),i.file&&(i.file.thumbURL=s.file.thumbURL),Ot.callbackNodes("Post",[i]),this.insert(i)}}var ce={init(){if(t["Quote Previewing"]&&("archive"===n.VIEW&&Ve.on(a,"mouseover",(function(e){if("A"===e.target.nodeName&&Ve.hasClass(e.target,"quotelink"))return ce.mouseover.call(e.target,e)})),["index","thread"].includes(n.VIEW)))return t["Comment Expansion"]&&X.callbacks.push(this.node),l.Post.push({name:"Quote Previewing",cb:this.node})},node(){for(var e of this.nodes.quotelinks.concat([...this.nodes.backlinks],this.nodes.archivelinks))Ve.on(e,"mouseover",ce.mouseover)},mouseover(e){let o;if(Ve.hasClass(this,"inlined")&&!Ve.hasClass(i,"catalog-mode")||!a.contains(this))return;const{boardID:r,threadID:s,postID:l}=ze.postDataFromLink(this),d=Ve.el("div",{id:"qp",className:"dialog"})
|
||
;if(Ve.add(Ke.hover,d),new de(r,s,l,d,ze.postFromNode(this)),L.hover({root:this,el:d,latestEvent:e,endEvents:"mouseout click",cb:ce.mouseout}),t["Quote Highlighting"]&&(o=n.posts.get(`${r}.${l}`))){const e=[o].concat(o.clones);for(var c of(e.pop(),e))Ve.addClass(c.nodes.post,"qphl")}},mouseout(){let e;if(!(e=this.el.firstElementChild))return;Ve.event("PostsRemoved",null,Ke.hover);let n=ze.postFromRoot(e).origin;if(n.rmClone(e.dataset.clone),t["Quote Highlighting"])for(n of[n].concat(n.clones))Ve.rmClass(n.nodes.post,"qphl")}},he={showHiddenThreads:!1,changed:{},enabledOn:({siteID:e,boardID:o})=>t["JSON Index"]&&"yotsuba"===n.sites[e].software&&"f"!==o,init(){let e,o,r;if("index"!==n.VIEW)return;if(Ve.one(a,"4chanXInitFinished",this.cb.initFinished),Ve.on(a,"PostsInserted",this.cb.postsInserted),!this.enabledOn(n.BOARD))return;this.enabled=!0,l.Post.push({name:"Index Page Numbers",cb:this.node}),l.CatalogThread.push({name:"Catalog Features",cb:this.catalogNode}),
|
||
this.search=history.state?.searched||"",history.state?.mode&&(t["Index Mode"]=history.state?.mode),this.currentSort=history.state?.sort,this.currentSort||(this.currentSort="object"==typeof t["Index Sort"]?t["Index Sort"][n.BOARD.ID]||"bump":t["Index Sort"]),this.currentPage=this.getCurrentPage(),this.processHash(),Ve.addClass(i,"index-loading",`${t["Index Mode"].replace(/\ /g,"-")}-mode`),Ve.on(window,"popstate",this.cb.popstate),Ve.on(a,"scroll",this.scroll),Ve.on(a,"SortIndex",this.cb.resort),this.button=Ve.el("a",{title:"Refresh",href:"javascript:;",textContent:"🗘"}),Ve.on(this.button,"click",(()=>he.update())),Ke.addShortcut("index-refresh",this.button,590);const s=[];for(r in this.inputs=o=m(),c.Index){var d=c.Index[r];if(d instanceof Array){var h=L.checkbox(r,`${r[0]}${r.slice(1).toLowerCase()}`);h.title=d[1],s.push({el:h}),e=h.firstChild,Ve.on(e,"change",Ve.cb.checked),o[r]=e}}Ve.on(o["Show Replies"],"change",this.cb.replies),
|
||
Ve.on(o["Catalog Hover Expand"],"change",this.cb.hover),Ve.on(o["Pin Watched Threads"],"change",this.cb.resort),Ve.on(o["Anchor Hidden Threads"],"change",this.cb.resort);const p=function(t){if(e=Ve.getOwn(o,t.target.name))return e.checked=t.target.checked,Ve.event("change",null,e)};Ve.on(a,"OpenSettings",(()=>Ve.on(Ve.id("fourchanx-settings"),"change",p)));const g=L.checkbox("Per-Board Sort Type","Per-board sort type","object"==typeof t["Index Sort"]);for(var f of(g.title="Set the sorting order of each board independently.",Ve.on(g.firstChild,"change",this.cb.perBoardSort),s.splice(3,0,{el:g}),Ke.menu.addEntry({el:Ve.el("span",{textContent:"Index Navigation"}),order:100,subEntries:s}),this.navLinks=Ve.el("div",{className:"navLinks json-index"}),Ve.extend(this.navLinks,{
|
||
innerHTML:'<span class="brackets-wrap indexlink"><a href="#index">Index</a></span> \n<span class="brackets-wrap cataloglink"><a href="#catalog">Catalog</a></span> \n<span class="brackets-wrap archlistlink"><a href="./archive">Archive</a></span> \n<span class="brackets-wrap bottomlink"><a href="#bottom">Bottom</a></span> \n<span class="brackets-wrap" id="index-last-refresh"><a href="javascript:;"><time title="Last index refresh">...</time></a></span> \n<input type="search" id="index-search" class="field" placeholder="Search">\n<a id="index-search-clear" href="javascript:;" title="Clear search">×</a>\n<span id="hidden-label" hidden> — <span id="hidden-count"></span> <span id="hidden-toggle">[<a href="javascript:;">Show</a>]</span></span>\n<span id="index-options">\n <input type="checkbox" id="index-rev" name="Reverse Sort" title="Reverse sort order">\n <span id="lastlong-options" hidden>\n <input type="text" title="Minimum letter count (without image)">\n <input type="text" title="Minimum letter count (with image)">\n </span>\n <select id="index-sort" name="Index Sort">\n <option disabled>Index Sort</option>\n <option value="bump">Bump order</option>\n <option value="lastreply">Last reply</option>\n <option value="lastlong">Last long reply</option>\n <option value="birth">Creation date</option>\n <option value="replycount">Reply count</option>\n <option value="filecount">File count</option>\n <option value="activity">Posts per minute</option>\n </select>\n <select id="index-size" name="Index Size">\n <option disabled>Image Size</option>\n <option value="small">Small</option>\n <option value="large">Large</option>\n </select>\n <select id="index-mode" name="Index Mode">\n <option disabled>Index Mode</option>\n <option value="paged">Paged</option>\n <option value="infinite">Infinite scrolling</option>\n <option value="all pages">All threads</option>\n <option value="catalog">Catalog</option>\n </select>\n</span>\n'
|
||
}),Ve(".cataloglink a",this.navLinks).href=Ye.catalog(),Y.isArchived(n.BOARD.ID)||(Ve(".archlistlink",this.navLinks).hidden=!0),Ve.on(Ve("#index-last-refresh a",this.navLinks),"click",this.cb.refreshFront),this.searchInput=Ve("#index-search",this.navLinks),this.setupSearch(),Ve.on(this.searchInput,"input",this.onSearchInput),Ve.on(Ve("#index-search-clear",this.navLinks),"click",this.clearSearch),this.hideLabel=Ve("#hidden-label",this.navLinks),Ve.on(Ve("#hidden-toggle a",this.navLinks),"click",this.cb.toggleHiddenThreads),this.selectRev=Ve("#index-rev",this.navLinks),this.selectMode=Ve("#index-mode",this.navLinks),this.selectSort=Ve("#index-sort",this.navLinks),this.selectSize=Ve("#index-size",this.navLinks),Ve.on(this.selectRev,"change",this.cb.sort),Ve.on(this.selectMode,"change",this.cb.mode),Ve.on(this.selectSort,"change",this.cb.sort),Ve.on(this.selectSize,"change",Ve.cb.value),Ve.on(this.selectSize,"change",this.cb.size),[this.selectMode,this.selectSize]))f.value=t[f.name]
|
||
;this.selectRev.checked=/-rev$/.test(he.currentSort),this.selectSort.value=he.currentSort.replace(/-rev$/,""),this.lastLongOptions=Ve("#lastlong-options",this.navLinks),this.lastLongInputs=u("input",this.lastLongOptions),this.lastLongThresholds=[0,0],this.lastLongOptions.hidden="lastlong"!==this.selectSort.value;for(let o=0;o<this.lastLongInputs.length;o++){e=this.lastLongInputs[o],Ve.on(e,"change",this.cb.lastLongThresholds);var b=t[`Last Long Reply Thresholds ${o}`];e.value=this.lastLongThresholds[o]="object"==typeof b?b[n.BOARD.ID]??100:b}return this.root=Ve.el("div",{className:"board json-index"}),Ve.on(this.root,"click",this.cb.hoverToggle),this.cb.size(),this.cb.hover(),this.pagelist=Ve.el("div",{className:"pagelist json-index"}),Ve.extend(this.pagelist,{
|
||
innerHTML:'<div class="prev">\n <a>\n <button disabled>Previous</button>\n </a>\n</div>\n<div class="pages"></div>\n<div class="next">\n <a>\n <button disabled>Next</button>\n </a>\n</div>\n<div class="pages cataloglink">\n <a href="./catalog">Catalog</a>\n</div>\n'}),Ve(".cataloglink a",this.pagelist).href=Ye.catalog(),Ve.on(this.pagelist,"click",this.cb.pageNav),this.update(!0),Ve.onExists(i,"title + *",(()=>a.title=a.title.replace(/\ -\ Page\ \d+/,""))),Ve.onExists(i,".board > .thread > .postContainer, .board + *",(function(){let e;n.SITE.Build.hat=Ve(".board > .thread > img:first-child"),n.SITE.Build.hat&&(n.BOARD.threads.forEach((function(e){if(e.nodes.root)return Ve.prepend(e.nodes.root,n.SITE.Build.hat.cloneNode(!1))})),Ve.addClass(i,"hats-enabled"),Ve.addStyle(`.catalog-thread::after {background-image: url(${n.SITE.Build.hat.src});}`));const t=Ve(".board");Ve.replace(t,he.root),he.loaded&&Ve.event("PostsInserted",null,he.root);try{
|
||
a.implementation.createDocument(null,null,null).appendChild(t)}catch(e){}for(e of u(".navLinks"))Ve.rm(e);Ve.rm(Ve.id("ctrl-top"));const o=Ve.id("delform").previousElementSibling;Ve.before(o,Ve.el("hr")),Ve.before(o,he.navLinks);const r=Ve("#index-last-refresh time",he.navLinks);if(r.dataset.utc)return G.update(r)})),Ot.ready((function(){let e;return(e=Ve(".pagelist"))&&Ve.replace(e,he.pagelist),Ve.rmClass(i,"index-loading")}))},scroll(){if(he.req||!he.liveThreadData||"infinite"!==t["Index Mode"]||window.scrollY<=i.scrollHeight-(300+window.innerHeight))return;null==he.pageNum&&(he.pageNum=he.currentPage);const e=++he.pageNum;if(e>he.pagesNum)return he.endNotice();const n=he.threadsOnPage(e);return he.buildStructure(n)},endNotice:function(){let e=!1;const t=()=>e=!1;return function(){if(!e)return e=!0,new Xe("info","Last page reached.",2),setTimeout(t,3e3)}}(),menu:{init(){if("index"===n.VIEW&&t.Menu&&t["Thread Hiding Link"]&&he.enabledOn(n.BOARD))return Q.menu.addEntry({el:Ve.el("a",{
|
||
href:"javascript:;",className:"has-shortcut-text"},{innerHTML:'<span></span><span class="shortcut-text">Shift+click</span>'}),order:20,open({thread:e}){return"catalog"===t["Index Mode"]&&(this.el.firstElementChild.textContent=e.isHidden?"Unhide":"Hide",this.cb&&Ve.off(this.el,"click",this.cb),this.cb=function(){return Ve.event("CloseMenu"),he.toggleHide(e)},Ve.on(this.el,"click",this.cb),!0)}})}},node(){if(!this.isReply&&!this.isClone&&null!=he.threadPosition[this.ID])return this.thread.setPage(Math.floor(he.threadPosition[this.ID]/he.threadsNumPerPage)+1)},catalogNode(){return Ve.on(this.nodes.root,"mousedown click",(e=>{if(0===e.button&&e.shiftKey)return"click"===e.type&&he.toggleHide(this.thread),e.preventDefault()}))},toggleHide(e){if(he.showHiddenThreads){if(pe.show(e),!pe.db.get({boardID:e.board.ID,threadID:e.ID}))return}else pe.hide(e);return pe.saveHiddenState(e)},cycleSortType(){let e;const t=he.selectSort.options.filter((e=>!e.disabled));for(e=0;e<t.length;e++){
|
||
if(t[e].selected)break}return t[(e+1)%t.length].selected=!0,Ve.event("change",null,he.selectSort)},cb:{initFinished:()=>(he.initFinishedFired=!0,Ve.queueTask((()=>he.cb.postsInserted()))),postsInserted(){if(!he.initFinishedFired)return;let e=0;return n.posts.forEach((function(t){if(!t.isFetchedQuote&&!t.indexRefreshSeen&&i.contains(t.nodes.root))return t.indexRefreshSeen=!0,e++})),e?Ve.event("IndexRefresh"):void 0},toggleHiddenThreads:()=>(Ve("#hidden-toggle a",he.navLinks).textContent=(he.showHiddenThreads=!he.showHiddenThreads)?"Hide":"Show",he.sort(),he.buildIndex()),mode(){return he.pushState({mode:this.value}),he.pageLoad(!1)},sort(){const e=he.selectRev.checked?he.selectSort.value+"-rev":he.selectSort.value;return he.pushState({sort:e}),he.pageLoad(!1)},resort(e){if(he.changed.order=!0,!e?.detail?.deferred)return he.pageLoad(!1)},perBoardSort(){t["Index Sort"]=this.checked?m():"",he.saveSort();for(let e=0;e<2;e++)t[`Last Long Reply Thresholds ${e}`]=this.checked?m():"",
|
||
he.saveLastLongThresholds(e)},lastLongThresholds(){const e=[...this.parentNode.children].indexOf(this),t=+this.value;if(Number.isFinite(t))return he.lastLongThresholds[e]=t,he.saveLastLongThresholds(e),he.changed.order=!0,he.pageLoad(!1);this.value=he.lastLongThresholds[e]},size(e){if("catalog"!==t["Index Mode"]?(Ve.rmClass(he.root,"catalog-small"),Ve.rmClass(he.root,"catalog-large")):"small"===t["Index Size"]?(Ve.addClass(he.root,"catalog-small"),Ve.rmClass(he.root,"catalog-large")):(Ve.addClass(he.root,"catalog-large"),Ve.rmClass(he.root,"catalog-small")),e)return he.buildIndex()},replies:()=>he.buildIndex(),hover:()=>i.classList.toggle("catalog-hover-expand",t["Catalog Hover Expand"]),hoverToggle(e){if(t["Catalog Hover Toggle"]&&Ve.hasClass(i,"catalog-mode")&&!Ve.modifiedClick(e)&&!Ve.x("ancestor-or-self::a",e.target)){let t;const n=he.inputs["Catalog Hover Expand"];if(n.checked=!n.checked,Ve.event("change",null,n),t=ze.threadFromNode(e.target))return he.cb.catalogReplies.call(t),
|
||
he.cb.hoverAdjust.call(t.OP.nodes)}},popstate(e){if(e?.state){const{searched:t,mode:n,sort:o}=e.state,a=he.getCurrentPage();return he.setState({search:t,mode:n,sort:o,page:a}),he.pageLoad(!1)}{const e=he.processHash();return t["Refreshed Navigation"]&&e?he.update():he.pageLoad()}},pageNav(e){let t;if(!Ve.modifiedClick(e)){switch(e.target.nodeName){case"BUTTON":e.target.blur(),t=e.target.parentNode;break;case"A":t=e.target;break;default:return}if("Catalog"!==t.textContent)return e.preventDefault(),he.userPageNav(+t.pathname.split(/\/+/)[2]||1)}},refreshFront:()=>(he.pushState({page:1}),he.update()),catalogReplies(){if(t["Show Replies"]&&Ve.hasClass(i,"catalog-hover-expand")&&!this.catalogView.nodes.replies)return he.buildCatalogReplies(this)},hoverAdjust(){let e;if(!Ve.hasClass(i,"catalog-hover-expand"))return;const t=this.post.getBoundingClientRect();if(e=Ve.minmax(0,-t.left,i.clientWidth-t.right)){const{style:t}=this.post;return t.left=`${e}px`,t.right=-e+"px",
|
||
Ve.one(this.root,"mouseleave",(()=>t.left=t.right=null))}}},scrollToIndex:()=>Ke.scrollToIfNeeded(he.navLinks.getBoundingClientRect().height?he.navLinks:he.root),getCurrentPage:()=>+window.location.pathname.split(/\/+/)[2]||1,userPageNav:e=>(he.pushState({page:e}),t["Refreshed Navigation"]?he.update():he.pageLoad()),hashCommands:{mode:{paged:"paged","infinite-scrolling":"infinite",infinite:"infinite","all-threads":"all pages","all-pages":"all pages",catalog:"catalog"},sort:{"bump-order":"bump","last-reply":"lastreply","last-long-reply":"lastlong","creation-date":"birth","reply-count":"replycount","file-count":"filecount","posts-per-minute":"activity"}},processHash(){let e=location.href.match(/#.*/)?.[0]||"";const n={replace:!0},o=e.slice(1).split("/"),a=[];for(var i of o){var r,s;(r=Ve.getOwn(he.hashCommands.mode,i))?n.mode=r:"index"===i?(n.mode=t["Previous Index Mode"],n.page=1):(s=Ve.getOwn(he.hashCommands.sort,i.replace(/-rev$/,"")))?(n.sort=s,
|
||
/-rev$/.test(i)&&(n.sort+="-rev")):/^s=/.test(i)?n.search=decodeURIComponent(i.slice(2)).replace(/\+/g," ").trim():a.push(i)}return e=a.join("/"),e&&(n.hash=`#${e}`),he.pushState(n),o.length-a.length},pushState(e){let{search:o,hash:a,replace:i}=e,r=history.state?.oldpage;null!=o&&o!==he.search&&(e.page=o?1:r||1,o?he.search||(r=he.currentPage):r=void 0),he.setState(e);const s=1===he.currentPage?`/${n.BOARD}/`:`/${n.BOARD}/${he.currentPage}`;return a||(a=""),history[i?"replaceState":"pushState"]({mode:t["Index Mode"],sort:he.currentSort,searched:he.search,oldpage:r},"",`${location.protocol}//${location.host}${s}${a}`)},setState({search:e,mode:n,sort:o,page:a,hash:i}){if(null!=e&&e!==he.search&&(he.changed.search=!0,he.search=e),null!=n&&n!==t["Index Mode"]&&(he.changed.mode=!0,t["Index Mode"]=n,Ve.set("Index Mode",n),"catalog"!==n&&t["Previous Index Mode"]!==n&&(t["Previous Index Mode"]=n,Ve.set("Previous Index Mode",n))),null!=o&&o!==he.currentSort&&(he.changed.sort=!0,he.currentSort=o,
|
||
he.saveSort()),["all pages","catalog"].includes(t["Index Mode"])&&(a=1),null!=a&&a!==he.currentPage&&(he.changed.page=!0,he.currentPage=a),null!=i)return he.changed.hash=!0},savePerBoard:(e,o)=>("object"==typeof t[e]?t[e][n.BOARD.ID]=o:t[e]=o,Ve.set(e,t[e])),saveSort:()=>he.savePerBoard("Index Sort",he.currentSort),saveLastLongThresholds:e=>he.savePerBoard(`Last Long Reply Thresholds ${e}`,he.lastLongThresholds[e]),pageLoad(e=!0){if(!he.liveThreadData)return;let{threads:t,order:n,search:o,mode:a,sort:i,page:r,hash:s}=he.changed;return t||(t=o),n||(n=i),(t||n)&&he.sort(),t&&he.buildPagelist(),o&&he.setupSearch(),a&&he.setupMode(),i&&he.setupSort(),(t||a||r||n)&&he.buildIndex(),(t||r)&&he.setPage(),e&&!s&&he.scrollToIndex(),s&&Ke.hashScroll(),he.changed={}},setupMode(){for(var e of["paged","infinite","all pages","catalog"])Ve[e===t["Index Mode"]?"addClass":"rmClass"](i,`${e.replace(/\ /g,"-")}-mode`);return he.selectMode.value=t["Index Mode"],he.cb.size(),he.showHiddenThreads=!1,
|
||
Ve("#hidden-toggle a",he.navLinks).textContent="Show"},setupSort:()=>(he.selectRev.checked=/-rev$/.test(he.currentSort),he.selectSort.value=he.currentSort.replace(/-rev$/,""),he.lastLongOptions.hidden="lastlong"!==he.selectSort.value),getPagesNum:()=>he.search?Math.ceil(he.sortedThreadIDs.length/he.threadsNumPerPage):he.pagesNum,getMaxPageNum:()=>Math.max(1,he.getPagesNum()),buildPagelist(){const e=Ve(".pages",he.pagelist),t=he.getMaxPageNum();if(e.childElementCount!==t){const o=[];for(let e=1,a=t;e<=a;e++){var n=Ve.el("a",{textContent:e,href:1===e?"./":e});o.push(Ve.tn("["),n,Ve.tn("] "))}return Ve.rmAll(e),Ve.add(e,o)}},setPage(){let e,t;const n=he.currentPage,o=he.getMaxPageNum(),a=Ve(".pages",he.pagelist),i=a.previousElementSibling.firstElementChild,r=a.nextElementSibling.firstElementChild;let s=Math.max(n-1,1);if(i.href=1===s?"./":s,i.firstElementChild.disabled=s===n,s=Math.min(n+1,o),r.href=1===s?"./":s,r.firstElementChild.disabled=s===n,t=Ve("strong",a)){
|
||
if(+t.textContent===n)return;Ve.replace(t,t.firstChild)}else t=Ve.el("strong");if(e=a.children[n-1])return Ve.before(e,t),Ve.add(t,e)},updateHideLabel(){if(!he.hideLabel)return;let e=0;for(var t of he.liveThreadIDs)he.isHidden(t)&&e++;return e?(he.hideLabel.hidden=!1,Ve("#hidden-count",he.navLinks).textContent=1===e?"1 hidden thread":`${e} hidden threads`):(he.hideLabel.hidden=!0,void(he.showHiddenThreads&&he.cb.toggleHiddenThreads()))},update(e){let o;if((o=he.req)&&(delete he.req,o.abort()),t["Index Refresh Notifications"]?(he.notice||(he.notice=new Xe("info","Refreshing index...")),he.nTimeout||(he.nTimeout=setTimeout((()=>{he.notice&&(he.notice.el.lastElementChild.textContent+=" (disable JSON Index if this takes too long)")}),3e3))):he.nTimeout||(he.nTimeout=setTimeout((()=>he.notice||(he.notice=new Xe("info","Refreshing index... (disable JSON Index if this takes too long)"))),3e3)),
|
||
e||"loading"===a.readyState||Ve(".board + *"))return he.req=Ve.whenModified(n.SITE.urls.catalogJSON({boardID:n.BOARD.ID}),"Index",he.load),Ve.addClass(he.button,"spin");location.reload()},load(){let e;if(this!==he.req)return;Ve.rmClass(he.button,"spin");const{notice:n,nTimeout:o}=he;if(o&&clearTimeout(o),delete he.nTimeout,delete he.req,delete he.notice,![200,304].includes(this.status))return e="Index refresh failed. "+(this.status?`Error ${this.statusText} (${this.status})`:"Connection Error"),void(n?(n.setType("warning"),n.el.lastElementChild.textContent=e,setTimeout(n.close,b)):new Xe("warning",e,1));try{200===this.status?he.parse(this.response):304===this.status&&he.pageLoad()}catch(t){return e=t,r.error(`Index failure: ${e.message}`,e.stack),void(n?(n.setType("error"),n.el.lastElementChild.textContent="Index refresh failed.",setTimeout(n.close,b)):new Xe("error","Index refresh failed.",1))}n&&(t["Index Refresh Notifications"]?(n.setType("success"),
|
||
n.el.lastElementChild.textContent="Index refreshed!",setTimeout(n.close,b)):n.close());const a=Ve("#index-last-refresh time",he.navLinks);return a.dataset.utc=Date.parse(this.getResponseHeader("Last-Modified")),G.update(a)},parse:e=>(Ve.cleanCache((e=>/^https?:\/\/a\.4cdn\.org\//.test(e))),he.parseThreadList(e),he.changed.threads=!0,he.pageLoad()),parseThreadList(e){he.pagesNum=e.length,he.threadsNumPerPage=e[0]?.threads.length||1,he.liveThreadData=e.reduce(((e,t)=>e.concat(t.threads)),[]),he.liveThreadIDs=he.liveThreadData.map((e=>e.no)),he.liveThreadDict=m(),he.threadPosition=m(),he.parsedThreads=m(),he.replyData=m();for(let e=0;e<he.liveThreadData.length;e++){var t,o,a=he.liveThreadData[e];if(he.liveThreadDict[a.no]=a,he.threadPosition[a.no]=e,he.parsedThreads[a.no]=t=n.SITE.Build.parseJSON(a,n.BOARD),t.filterResults=o=We.test(t),t.isOnTop=o.top,t.isHidden=o.hide||pe.isHidden(t.boardID,t.threadID),a.last_replies)for(var i of a.last_replies)he.replyData[`${n.BOARD}.${i.no}`]=i}
|
||
he.liveThreadData[0]&&(n.SITE.Build.spoilerRange[n.BOARD.ID]=he.liveThreadData[0].custom_spoiler),n.BOARD.threads.forEach((function(e){if(!he.liveThreadIDs.includes(e.ID))return e.collect()})),Ve.event("IndexUpdate",{threads:he.liveThreadIDs.map((e=>`${n.BOARD}.${e}`))})},isHidden(e){let t;return(t=n.BOARD.threads.get(e))&&t.OP&&!t.OP.isFetchedQuote?t.isHidden:he.parsedThreads[e].isHidden},isHiddenReply:(e,t)=>W.isHidden(n.BOARD.ID,e,t.no)||We.isHidden(n.SITE.Build.parseJSON(t,n.BOARD)),buildThreads(e,t,o){let a;const i=[],r=[];let s=[];for(var l of e){var d,c;try{var h,u=he.liveThreadDict[l];if(c=n.BOARD.threads.get(l))c.json!==u&&JSON.stringify(c.json)!==JSON.stringify(u)&&(c.setCount("post",u.replies+1,u.bumplimit),c.setCount("file",u.images+!!u.ext,u.imagelimit),c.setStatus("Sticky",!!u.sticky),c.setStatus("Closed",!!u.closed)),c.catalogView&&(Ve.rm(c.catalogView.nodes.replies),c.catalogView.nodes.replies=null);else c=new I(l,n.BOARD),r.push(c)
|
||
;var p=u.last_replies&&u.last_replies.length?u.last_replies[u.last_replies.length-1].no:l;if(p>c.lastPost&&(c.lastPost=p),c.json=u,i.push(c),(h=c.OP)&&!h.isFetchedQuote)h.setCatalogOP(t),c.setPage(Math.floor(he.threadPosition[l]/he.threadsNumPerPage)+1);else{var g=he.parsedThreads[l];d=n.SITE.Build.post(g),(h=new H(d,c,n.BOARD)).filterResults=g.filterResults,s.push(h)}t&&c.nodes.root||n.SITE.Build.thread(c,u,o)}catch(e){a||(a=[]),a.push({message:`Parsing of Thread No.${c} failed. Thread will be skipped.`,error:e,html:d?.outerHTML})}}return a&&Ot.handleErrors(a),o&&(s=s.concat(he.buildReplies(i))),Ot.callbackNodes("Thread",r),Ot.callbackNodes("Post",s),he.updateHideLabel(),Ve.event("IndexRefreshInternal",{threadIDs:i.map((e=>e.fullID)),isCatalog:t}),i},buildReplies(e){let t;const o=[];for(var a of e){var i;if(i=he.liveThreadDict[a.ID].last_replies){var r=[];for(var s of i){var l,d;if(!(d=a.posts.get(s.no))||d.isFetchedQuote){r.push(l=n.SITE.Build.postFromObject(s,a.board.ID));try{
|
||
o.push(new H(l,a,a.board))}catch(e){t||(t=[]),t.push({message:`Parsing of Post No.${s.no} failed. Post will be skipped.`,error:e,html:l?.outerHTML})}}else r.push(d.nodes.root)}Ve.add(a.nodes.root,r)}}return t&&Ot.handleErrors(t),o},buildCatalogViews(e){const t=[];for(var o of e)if(!o.catalogView){var{ID:a}=o,i=Math.floor(he.threadPosition[a]/he.threadsNumPerPage)+1,r=n.SITE.Build.catalogThread(o,he.liveThreadDict[a],i);t.push(new C(r,o))}Ot.callbackNodes("CatalogThread",t)},sizeCatalogViews(e){const n="small"===t["Index Size"]?150:250;for(var o of e){var{thumb:a}=o.catalogView.nodes,{width:i,height:r}=a.dataset;if(i){var s=n/Math.max(i,r);a.style.width=i*s+"px",a.style.height=r*s+"px"}}},buildCatalogReplies(e){let t;const{nodes:o}=e.catalogView;if(!(t=he.liveThreadDict[e.ID].last_replies))return;const a=[];for(var i of t)if(!he.isHiddenReply(e.ID,i)){var r=n.SITE.Build.catalogReply(e,i);G.update(Ve("time",r)),Ve.on(Ve(".catalog-reply-preview",r),"mouseover",ce.mouseover),a.push(r)}
|
||
o.replies=Ve.el("div",{className:"catalog-replies"}),Ve.add(o.replies,a),Ve.add(e.OP.nodes.post,o.replies)},sort(){let e;const{liveThreadIDs:o,liveThreadData:a}=he;if(!a)return;const i=(new Date).getTime()/1e3,r=he.currentSort.replace(/-rev$/,"");return he.sortedThreadIDs=(()=>{switch(r){case"lastreply":case"lastlong":var e=a.some((e=>e.last_replies?.length)),t=function(t){if(!e)return t.last_modified;const o=t.last_replies||[];for(let e=o.length-1;e>=0;e--){var a=o[e];if(!he.isHiddenReply(t.no,a)){if("lastreply"===r)return a;if((a.com?n.SITE.Build.parseComment(a.com).replace(/[^a-z]/gi,"").length:0)>=he.lastLongThresholds[+!!a.ext])return a}}return t.omitted_posts&&t.last_replies?.length?t.last_replies[0]:t},s=m();for(var l of a)s[l.no]=t(l).no;return[...a].sort(((e,t)=>s[t.no]-s[e.no])).map((e=>e.no));case"bump":default:return o;case"birth":return[...o].sort(((e,t)=>t-e));case"replycount":return[...a].sort(((e,t)=>t.replies-e.replies)).map((e=>e.no));case"filecount":
|
||
return[...a].sort(((e,t)=>t.images-e.images)).map((e=>e.no));case"activity":return[...a].sort(((e,t)=>(i-e.time)/(e.replies+1)-(i-t.time)/(t.replies+1))).map((e=>e.no))}})(),/-rev$/.test(he.currentSort)&&he.sortedThreadIDs.reverse(),he.search&&(e=he.querySearch(he.search))&&(he.sortedThreadIDs=e),he.sortOnTop((e=>e.isSticky)),he.sortOnTop((e=>e.isOnTop||t["Pin Watched Threads"]&&ae.isWatchedRaw(e.boardID,e.threadID))),t["Anchor Hidden Threads"]?he.sortOnTop((e=>!he.isHidden(e.threadID))):void 0},sortOnTop(e){const t=[],n=[];for(var o of he.sortedThreadIDs)(e(he.parsedThreads[o])?t:n).push(o);return he.sortedThreadIDs=t.concat(n)},buildIndex(){let e;if(he.liveThreadData){switch(t["Index Mode"]){case"all pages":e=he.sortedThreadIDs;break;case"catalog":e=he.sortedThreadIDs.filter((e=>!he.isHidden(e)!==he.showHiddenThreads));break;default:e=he.threadsOnPage(he.currentPage)}delete he.pageNum,Ve.rmAll(he.root),Ve.rmAll(Ke.hover),
|
||
he.loaded&&he.root.parentNode&&Ve.event("PostsRemoved",null,he.root),"catalog"===t["Index Mode"]?he.buildCatalog(e):he.buildStructure(e)}},threadsOnPage(e){const t=he.threadsNumPerPage,n=t*(e-1);return he.sortedThreadIDs.slice(n,n+t)},buildStructure(e){const n=he.buildThreads(e,!1,t["Show Replies"]),o=[];for(var a of n)o.push(a.nodes.root,Ve.el("hr"));Ve.add(he.root,o),he.root.parentNode&&Ve.event("PostsInserted",null,he.root),he.loaded=!0},buildCatalog(e){let t=0;const n=e.length;let o=null;var a=function(){if(o&&!o.parentNode)return;const i=t>0&&he.root.parentNode?n:t+30;return o=he.buildCatalogPart(e.slice(t,i))[0],t=i,t<n?Ve.queueTask(a):(he.root.parentNode&&Ve.event("PostsInserted",null,he.root),he.loaded=!0)};a()},buildCatalogPart(e){const t=he.buildThreads(e,!0);he.buildCatalogViews(t),he.sizeCatalogViews(t);const n=[];for(var o of t)o.OP.setCatalogOP(!0),Ve.add(o.catalogView.nodes.root,o.OP.nodes.root),n.push(o.catalogView.nodes.root),
|
||
Ve.on(o.catalogView.nodes.root,"mouseenter",he.cb.catalogReplies.bind(o)),Ve.on(o.OP.nodes.root,"mouseenter",he.cb.hoverAdjust.bind(o.OP.nodes));return Ve.add(he.root,n),n},clearSearch:()=>(he.searchInput.value="",he.onSearchInput(),he.searchInput.focus()),setupSearch:()=>(he.searchInput.value=he.search,he.search?he.searchInput.dataset.searching=1:he.searchInput.removeAttribute("data-searching")),onSearchInput(){const e=he.searchInput.value.trim();if(e!==he.search)return he.pushState({search:e,replace:!!e==!!he.search}),he.pageLoad(!1)},querySearch(e){let t,n;if(n=e.match(/^([\w+]+):\/(.*)\/(\w*)$/)){let e;try{e=RegExp(n[2],n[3])}catch(e){return[]}return he.sortedThreadIDs.filter((t=>e.test(We.values(n[1],he.parsedThreads[t]).join("\n"))))}if(t=e.toLowerCase().match(/\S+/g))return he.sortedThreadIDs.filter((e=>he.searchMatch(he.parsedThreads[e],t)))},searchMatch(e,t){const{info:o,file:a}=e;null==o.comment&&(o.comment=n.SITE.Build.parseComment(o.commentHTML.innerHTML));let i=[]
|
||
;for(var r of["comment","subject","name","tripcode"])r in o&&i.push(o[r]);for(var s of(a&&i.push(a.name),i=i.join(" ").toLowerCase(),t))if(-1===i.indexOf(s))return!1;return!0}},ue=he,pe={init(){if(["index","catalog"].includes(n.VIEW)&&(t["Thread Hiding Buttons"]||t.Menu&&t["Thread Hiding Link"]||t["JSON Index"]))return this.db=new y("hiddenThreads"),"catalog"===n.VIEW?this.catalogWatch():(this.catalogSet(n.BOARD),Ve.on(a,"IndexRefreshInternal",this.onIndexRefresh),t["Thread Hiding Buttons"]&&Ve.addClass(i,"thread-hide"),l.Post.push({name:"Thread Hiding",cb:this.node}))},catalogSet(e){if(!Ve.hasStorage||"yotsuba"!==n.SITE.software)return;const t=pe.db.get({boardID:e.ID,defaultValue:m()});for(var o in t)t[o]=!0;return localStorage.setItem(`4chan-hide-t-${e}`,JSON.stringify(t))},catalogWatch(){if(Ve.hasStorage&&"yotsuba"===n.SITE.software)return this.hiddenThreads=JSON.parse(localStorage.getItem(`4chan-hide-t-${n.BOARD}`))||{},
|
||
Ot.ready((()=>new MutationObserver(pe.catalogSave).observe(Ve.id("threads"),{attributes:!0,subtree:!0,attributeFilter:["style"]})))},catalogSave(){let e;const o=JSON.parse(localStorage.getItem(`4chan-hide-t-${n.BOARD}`))||{};for(e in o)Ve.hasOwn(pe.hiddenThreads,e)||pe.db.set({boardID:n.BOARD.ID,threadID:e,val:{makeStub:t.Stubs}});for(e in pe.hiddenThreads)Ve.hasOwn(o,e)||pe.db.delete({boardID:n.BOARD.ID,threadID:e});return pe.hiddenThreads=o},isHidden:(e,t)=>!(!pe.db||!pe.db.get({boardID:e,threadID:t})),node(){let e;if(!(this.isReply||this.isClone||this.isFetchedQuote))return t["Thread Hiding Buttons"]&&Ve.prepend(this.nodes.root,pe.makeButton(this.thread,"hide")),(e=pe.db.get({boardID:this.board.ID,threadID:this.ID}))?pe.hide(this.thread,e.makeStub):void 0},onIndexRefresh:()=>n.BOARD.threads.forEach((function(e){const{root:t}=e.nodes;if(e.isHidden&&e.stub&&!t.contains(e.stub))return pe.makeStub(e,t)})),menu:{init(){if("index"!==n.VIEW||!t.Menu||!t["Thread Hiding Link"])return
|
||
;let e=Ve.el("div",{className:"hide-thread-link",textContent:"Hide"});const o=Ve.el("a",{textContent:"Apply",href:"javascript:;"});Ve.on(o,"click",pe.menu.hide);const a=L.checkbox("Stubs","Make stub");Q.menu.addEntry({el:e,order:20,open:({thread:e,isReply:n})=>!(n||e.isHidden||t["JSON Index"]&&"catalog"===t["Index Mode"])&&(pe.menu.thread=e,!0),subEntries:[{el:o},{el:a}]}),e=Ve.el("a",{className:"show-thread-link",textContent:"Show",href:"javascript:;"}),Ve.on(e,"click",pe.menu.show),Q.menu.addEntry({el:e,order:20,open:({thread:e,isReply:n})=>!(n||!e.isHidden||t["JSON Index"]&&"catalog"===t["Index Mode"])&&(pe.menu.thread=e,!0)});const i=Ve.el("a",{textContent:"Hide stub",href:"javascript:;"});return Ve.on(i,"click",pe.menu.hideStub),Q.menu.addEntry({el:i,order:15,open:({thread:e,isReply:n})=>!(n||!e.isHidden||t["JSON Index"]&&"catalog"===t["Index Mode"])&&(pe.menu.thread=e)})},hide(){const e=Ve("input",this.parentNode).checked,{thread:t}=pe.menu;return pe.hide(t,e),
|
||
pe.saveHiddenState(t,e),Ve.event("CloseMenu")},show(){const{thread:e}=pe.menu;return pe.show(e),pe.saveHiddenState(e),Ve.event("CloseMenu")},hideStub(){const{thread:e}=pe.menu;pe.show(e),pe.hide(e,!1),pe.saveHiddenState(e,!1),Ve.event("CloseMenu")}},makeButton(e,t){const n=Ve.el("a",{className:`${t}-thread-button`,href:"javascript:;"});return Ve.extend(n,{textContent:"hide"===t?"➖︎":"➕︎"}),n.dataset.fullID=e.fullID,Ve.on(n,"click",pe.toggle),n},makeStub(e,o){let a,i,r=u(n.SITE.selectors.replyOriginal,o).length;(a=Ve(n.SITE.selectors.summary,o))&&(r+=+a.textContent.match(/\d+/));const s=pe.makeButton(e,"show");if(Ve.add(s,Ve.tn(` ${e.OP.info.nameBlock} (${1===r?"1 reply":`${r} replies`})`)),e.stub=Ve.el("div",{className:"stub"}),t.Menu?Ve.add(e.stub,[s,Q.makeButton(e.OP)]):Ve.add(e.stub,s),Ve.prepend(o,e.stub),i=Ve(n.SITE.selectors.threadDivider,o))return Ve.addClass(i,"threadDivider")},saveHiddenState:(e,t)=>(e.isHidden?pe.db.set({boardID:e.board.ID,threadID:e.ID,val:{makeStub:t}
|
||
}):pe.db.delete({boardID:e.board.ID,threadID:e.ID}),pe.catalogSet(e.board)),toggle(e){return e instanceof I||(e=n.threads.get(this.dataset.fullID)),e.isHidden?pe.show(e):pe.hide(e),pe.saveHiddenState(e)},hide(e,n=t.Stubs){if(e.isHidden)return;const o=e.nodes.root;return e.isHidden=!0,ue.updateHideLabel(),e.catalogView&&!ue.showHiddenThreads&&(Ve.rm(e.catalogView.nodes.root),Ve.event("PostsRemoved",null,ue.root)),n?pe.makeStub(e,o):o.hidden=!0},show(e){e.stub&&(Ve.rm(e.stub),delete e.stub);if(e.nodes.root.hidden=e.isHidden=!1,ue.updateHideLabel(),e.catalogView&&ue.showHiddenThreads)return Ve.rm(e.catalogView.nodes.root),Ve.event("PostsRemoved",null,ue.root)}};const ge=" | ",fe=le("div",{id:"fourchanx-settings",class:"dialog"},le("nav",null,le("div",{class:"sections-list"}),le("p",{class:"imp-exp-result warning"}),le("div",{class:"credits"},le("a",{class:"export"},"Export"),ge,le("a",{class:"import"},"Import"),ge,le("a",{class:"reset"},"Reset Settings"),ge,le("input",{type:"file",
|
||
hidden:!0}),le("a",{href:e.page,target:"_blank"},e.name),ge,le("a",{href:e.changelog,target:"_blank"},n.VERSION),ge,le("a",{href:e.issues,target:"_blank"},"Issues"),ge,le("a",{href:"javascript:;",class:"close",title:"Close"},"✕"))),le("div",{class:"section-container"},le("section",null)));const me={
|
||
boards:'/* General */\n.dialog {\n border: 1px solid;\n display: block;\n background-color: inherit;\n}\n.dialog:not(#qr):not(#thread-watcher):not(#header-bar) {\n box-shadow: 0 1px 2px rgba(0, 0, 0, .15);\n}\n#qr,\n#thread-watcher {\n box-shadow: -1px 2px 2px rgba(0, 0, 0, 0.25);\n}\n.captcha-img,\n.field {\n background-color: #FFF;\n border: 1px solid #CCC;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n color: #333;\n font: 13px sans-serif;\n outline: none;\n transition: color .25s, border-color .25s;\n}\n.field::-moz-placeholder {\n color: #AAA;\n font-size: 13px;\n opacity: 1;\n}\n.captch-img:hover,\n.field:hover {\n border-color: #999;\n}\n.field:hover, .field:focus, .field.focus {\n color: #000;\n}\n.field[disabled] {\n background-color: #F2F2F2;\n color: #888;\n}\n.field::-webkit-search-decoration {\n display: none;\n}\n.move {\n cursor: move;\n overflow: hidden;\n}\nlabel {\n cursor: pointer;\n}\na[href="javascript:;"] {\n text-decoration: none;\n}\n.warning {\n color: red;\n}\n:root.sw-yotsuba #boardNavDesktop, :root.sw-yotsuba #boardNavMobile {\n display: none !important;\n}\n:root.hide-bottom-board-list $site$boardListBottom {\n display: none;\n}\nbody.hasDropDownNav{\n margin-top: 5px;\n}\n:root:not(.keyboard-focus) a {\n outline: none;\n}\n.painted {\n border-radius: 3px;\n padding: 0px 2px;\n}\n[hidden] {\n display: none !important;\n}\n\n/* 4chan style fixes */\n/* overrides 4chan CSS on div.opContainer, div.op */\n:root.sw-yotsuba .opContainer, :root.sw-yotsuba .op {\n display: block;\n overflow: visible;\n}\n:root.sw-yotsuba .reply > .file > .fileText {\n margin: 0 20px;\n}\n:root.sw-yotsuba #arc-list span.quote {\n color: #789922;\n}\n:root.sw-yotsuba .fileText a {\n unicode-bidi: -moz-isolate;\n unicode-bidi: -webkit-isolate;\n}\n:root.sw-yotsuba #g-recaptcha {\n min-height: 78px;\n height: auto;\n}\n:root.sw-yotsuba:not(.js-enabled) #postForm {\n display: table;\n}\n:root.sw-yotsuba #captchaContainerAlt td:nth-child(2) {\n display: table-cell !important;\n}\n:root.sw-yotsuba canvas#tegaki-canvas {\n background: none;\n}\n/* Disable obnoxious captcha fade-in. */\n:root.sw-yotsuba > body > div:last-of-type {\n transition: none !important;\n}\n/* Fix captcha scrolling to top of page. */\n:root.sw-yotsuba > body > div[style*=" top: -10000px;"] {\n visibility: hidden !important;\n}\n/* Make long filenames wrap properly: https://github.com/ccd0/4chan-x/issues/1082 */\n:root.sw-yotsuba .post > .file {\n /* currently nonstandard but may be added: https://lists.w3.org/Archives/Public/www-style/2016Mar/0352.html, https://bugzilla.mozilla.org/show_bug.cgi?id=1296042 */\n word-break: break-word;\n}\n:root.sw-yotsuba:not(.ua-webkit):not(.ua-blink) .fileText {\n word-wrap: break-word;\n max-width: calc(100vw - 90px);\n}\n:root.sw-yotsuba > body.is_catalog .thread > a > img {\n display: inline-block;\n}\n/* Links to NSFW boards */\n:root.sw-yotsuba .nwsb {\n display: inline;\n}\n:root.sw-yotsuba .fileText {\n max-width: auto;\n white-space: normal;\n}\n\n/* Ads */\n:root.sw-yotsuba .ad-cnt > *, :root.sw-yotsuba .adg-rects > *, :root.sw-yotsuba .bsa-cnt {\n height: auto !important;\n}\n:root.sw-yotsuba:not(.ads-loaded) hr.abovePostForm,\n:root.sw-yotsuba:not(.ads-loaded) .adg-rects > hr,\n:root.sw-yotsuba #adg-ol + hr,\n:root.sw-yotsuba .danbo-slot:empty {\n display: none;\n}\n:root.sw-yotsuba .adg-rects {\n margin: 0;\n font-size: 0;\n}\n:root.sw-yotsuba div.center[style] {\n display: none !important;\n}\n\n/* Tinyboard / vichan conflicts */\n#menu > .hide-thread-link {\n width: auto;\n height: auto;\n overflow: visible;\n background-image: none;\n}\n#menu label.entry {\n display: block;\n}\n#fourchanx-settings label {\n display: inline;\n}\n.intro a[href="javascript:;"],\n#menu a {\n margin: 0;\n}\n.gal-buttons.gal-buttons a {\n font-size: inherit;\n}\n:root.sw-tinyboard.fixed.top-header:not(.autohide) .boardlist,\n:root.sw-tinyboard.fixed.top-header:not(.autohide) .bar.top {\n position: static;\n}\n:root.sw-tinyboard.fixed.top-header:not(.autohide) div.pages.top {\n top: auto;\n bottom: 0;\n}\n:root.sw-tinyboard.fixed.top-header.autohide .boardlist,\n:root.sw-tinyboard.fixed.top-header.autohide .bar.top {\n z-index: 3;\n}\n\n/* Tinyboard site style conflicts */\n:root[data-host="fufufu.moe"].fixed.top-header:not(.autohide) div.pages.top {\n top: 26px;\n bottom: auto;\n}\n:root[data-host="merorin.com"].fixed.top-header:not(.autohide) span.settings {\n top: 26px;\n}\n:root[data-host="fufufu.moe"]:not(.fixed) #header-bar {\n margin-top: 38px;\n}\n:root[data-host="lainchan.org"]:not(.fixed) #header-bar {\n margin-top: 17px;\n}\n:root[data-host="smuglo.li"]:not(.fixed) #header-bar {\n margin-top: 8px;\n}\n\n/* Anti-autoplay */\naudio.controls-added {\n display: block;\n margin: auto;\n white-space: normal;\n}\n:root.anti-autoplay div.embed {\n position: static;\n width: auto;\n height: auto;\n text-align: center;\n}\n:root.anti-autoplay .autoplay-removed {\n visibility: visible !important;\n min-width: 640px;\n min-height: 360px;\n}\n\n/* fixed, z-index */\n#overlay,\n#qp, #ihover,\n#navlinks, .fixed #header-bar,\n:root.float #updater,\n:root.float #thread-stats,\n#qr {\n position: fixed;\n}\n#overlay {\n z-index: 999;\n}\n#qp, #ihover {\n z-index: 60;\n}\n#menu, .gal-buttons {\n z-index: 50;\n}\n#updater, #thread-stats {\n z-index: 40;\n}\n:root.fixed #header-bar, #notifications {\n z-index: 35;\n}\n#a-gallery {\n z-index: 30;\n}\n#navlinks {\n z-index: 25;\n}\n#qr {\n z-index: 20;\n}\n#embedding {\n z-index: 11;\n}\n:root.fixed-watcher #thread-watcher {\n z-index: 10;\n}\n:root.fixed:not(.gallery-open) #header-bar:not(:hover) {\n z-index: 8;\n}\n#thread-watcher {\n z-index: 5;\n}\n\n/* Header */\n.fixed.top-header body {\n padding-top: 2em;\n}\n.fixed.bottom-header body {\n padding-bottom: 2em;\n}\n.fixed #header-bar {\n right: 0;\n left: 0;\n padding: 3px 4px 4px;\n font-size: 12px;\n}\n.fixed.top-header #header-bar {\n top: 0;\n}\n.fixed.bottom-header #header-bar {\n bottom: 0;\n}\n#header-bar {\n border-width: 0;\n transition: all .1s .05s ease-in-out;\n}\n:root.fixed #header-bar {\n box-shadow: -5px 1px 10px rgba(0, 0, 0, 0.20);\n}\n:root.centered-links #shortcuts {\n width: 300px;\n text-align: right;\n}\n:root.centered-links #header-bar {\n text-align: center;\n}\n#custom-board-list {\n font-size: 13px;\n vertical-align: middle;\n}\n#full-board-list {\n vertical-align: middle;\n}\n:root.centered-links #custom-board-list {\n position: relative;\n left: 150px;\n}\n.fixed.top-header #header-bar {\n border-bottom-width: 1px;\n}\n.fixed.bottom-header #header-bar {\n box-shadow: 0 -1px 2px rgba(0, 0, 0, .15);\n border-top-width: 1px;\n}\n.fixed.bottom-header #header-bar .menu-button i {\n border-top: none;\n border-bottom: 6px solid;\n}\n.fixed #header-bar.autohide:not(:hover) {\n box-shadow: none;\n transition: all .8s .6s cubic-bezier(.55, .055, .675, .19);\n}\n.fixed.top-header #header-bar.autohide:not(:hover) {\n margin-bottom: -1em;\n -webkit-transform: translateY(-100%);\n transform: translateY(-100%);\n}\n.fixed.bottom-header #header-bar.autohide:not(:hover) {\n -webkit-transform: translateY(100%);\n transform: translateY(100%);\n}\n#scroll-marker {\n left: 0;\n right: 0;\n height: 10px;\n position: absolute;\n}\n#header-bar:not(.autohide) #scroll-marker {\n pointer-events: none;\n}\n#header-bar #scroll-marker {\n display: none;\n}\n.fixed #header-bar #scroll-marker {\n display: block;\n}\n.fixed.top-header #header-bar #scroll-marker {\n top: 100%;\n}\n.fixed.bottom-header #header-bar #scroll-marker {\n bottom: 100%;\n}\n#board-list a, #shortcuts a:not(.entry) {\n text-decoration: none;\n padding: 1px;\n}\n#shortcuts:empty {\n display: none;\n}\n.brackets-wrap::before {\n content: "\\00a0[";\n}\n.brackets-wrap::after {\n content: "]\\00a0";\n}\n.dead-thread,\n.disabled:not(.replies-quoting-you) {\n opacity: .45;\n}\n#shortcuts {\n float: right;\n}\n:root.autohiding-scrollbar #shortcuts {\n margin-right: 12px;\n}\n.shortcut {\n margin-left: 3px;\n vertical-align: middle;\n}\n:root.shortcut-icons .native-settings {\n font-size: 0;\n color: transparent;\n display: inline-block;\n vertical-align: top;\n height: 12px;\n width: 14px;\n background: url(\'//s.4cdn.org/image/favicon.ico\') 0px -1px no-repeat;\n}\n#navbotright,\n#navtopright {\n display: none;\n}\n#toggleMsgBtn {\n display: none !important;\n}\n.current,\n:root.sw-yotsuba div#boardNavDesktopFoot a.current {\n font-weight: bold;\n}\n@media (min-width: 1300px) {\n :root.sw-yotsuba.fixed:not(.centered-links) #header-bar {\n white-space: nowrap;\n display: -webkit-flex;\n display: flex;\n -webkit-align-items: center;\n align-items: center;\n }\n :root.sw-yotsuba.fixed:not(.centered-links) #board-list {\n -webkit-flex: auto;\n flex: auto;\n }\n :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list {\n display: -webkit-flex;\n display: flex;\n }\n :root.sw-yotsuba.fixed:not(.centered-links) .hide-board-list-container {\n -webkit-flex: none;\n flex: none;\n margin-right: 5px;\n }\n :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList {\n -webkit-flex: auto;\n flex: auto;\n display: -webkit-flex;\n display: flex;\n width: 0px; /* XXX Fixes Edge not shrinking the board list below default size when needed */\n }\n :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > a,\n :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > span:not(.space):not(.spacer) {\n -webkit-flex: none;\n flex: none;\n padding: .17em;\n margin: -.17em -.32em;\n }\n :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > span {\n pointer-events: none;\n }\n :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > span.space {\n -webkit-flex: 0 .63 .63em;\n flex: 0 .63 .63em;\n }\n :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > span.spacer {\n -webkit-flex: 0 .38 .38em;\n flex: 0 .38 .38em;\n }\n :root.sw-yotsuba.fixed:not(.centered-links) #shortcuts {\n float: initial;\n -webkit-flex: none;\n flex: none;\n display: -webkit-flex;\n display: flex;\n -webkit-align-items: center;\n align-items: center;\n }\n}\n/* 4chan X link brackets */\n.brackets-wrap::before {\n content: "[";\n}\n.brackets-wrap::after {\n content: "]";\n}\n/* Notifications */\n#notifications {\n position: fixed;\n top: 0;\n height: 0;\n text-align: center;\n right: 0;\n left: 0;\n visibility: visible;\n}\n#notifications:empty {\n display: none;\n}\n:root.fixed.top-header:not(.gallery-open) #header-bar #notifications,\n:root.fixed.top-header #header-bar.autohide #notifications {\n position: absolute;\n top: 100%;\n}\n.notification {\n color: #FFF;\n font-weight: 700;\n text-shadow: 0 1px 2px rgba(0, 0, 0, .5);\n box-shadow: 0 1px 2px rgba(0, 0, 0, .15);\n border-radius: 2px;\n margin: 1px auto;\n width: 550px;\n max-width: 100%;\n position: relative;\n transition: all .25s ease-in-out;\n}\n.notification.error {\n background-color: hsla(0, 100%, 38%, .9);\n}\n.notification.warning {\n background-color: hsla(36, 100%, 38%, .9);\n}\n.notification.info {\n background-color: hsla(200, 100%, 38%, .9);\n}\n.notification.success {\n background-color: hsla(104, 100%, 38%, .9);\n}\n.notification a {\n color: white;\n}\n.notification > .close {\n padding: 7px;\n top: 0px;\n right: 5px;\n position: absolute;\n}\n.notification > .fa-times::before {\n font-size: 11px !important;\n}\n.message {\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n padding: 6px 20px;\n max-height: 200px;\n width: 100%;\n overflow: auto;\n white-space: pre-line;\n}\n.message a {\n text-decoration: underline;\n}\n:root.tainted .report-error {\n display: none;\n}\n\n/* Settings */\n:root.fourchan-x body {\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n#overlay {\n background-color: rgba(0, 0, 0, .5);\n display: -webkit-flex;\n display: flex;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n}\n#fourchanx-settings {\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n box-shadow: 0 0 15px rgba(0, 0, 0, .15);\n height: 600px;\n max-height: 100%;\n width: 900px;\n max-width: 100%;\n margin: auto;\n padding: 5px;\n display: -webkit-flex;\n display: flex;\n -webkit-flex-direction: column;\n flex-direction: column;\n}\n#fourchanx-settings > nav {\n padding: 2px 2px 8px;\n display: -webkit-flex;\n display: flex;\n}\n#fourchanx-settings > nav a {\n text-decoration: underline;\n}\n#fourchanx-settings > nav a.close {\n text-decoration: none;\n padding: 0 2px;\n margin: 0;\n}\n.section-container {\n -webkit-flex: 1;\n flex: 1;\n position: relative;\n overflow: auto;\n padding-right: 5px;\n overscroll-behavior: contain;\n}\n.sections-list {\n -webkit-flex: 1;\n flex: 1;\n}\n.export, .import, .reset {\n cursor: pointer;\n text-decoration: none !important;\n}\n.tab-selected {\n font-weight: 700;\n}\n.section-sauce ul,\n.section-advanced ul {\n list-style: none;\n margin: 0;\n}\n.section-sauce ul {\n padding: 8px;\n}\n.section-advanced ul {\n padding: 0px;\n}\n.section-sauce li,\n.section-advanced li {\n padding-left: 4px;\n}\n.section-main ul {\n margin: 0;\n padding: 0 0 0 16px;\n}\n.section-main li {\n white-space: pre-line;\n list-style: disc;\n}\n.section-main li:not(:first-of-type) {\n margin-top: 4px;\n}\n.section-main label {\n text-decoration: underline;\n}\ndiv[data-checked="false"] > .suboption-list {\n display: none;\n}\n.suboption-list {\n position: relative;\n}\n.suboption-list::before {\n content: "";\n display: inline-block;\n position: absolute;\n left: .7em;\n width: 0;\n height: 100%;\n border-left: 1px solid;\n}\n.suboption-list > div {\n position: relative;\n padding-left: 1.4em;\n}\n.suboption-list > div::before {\n content: "";\n display: inline-block;\n position: absolute;\n left: .7em;\n width: .7em;\n height: .6em;\n border-left: 1px solid;\n border-bottom: 1px solid;\n}\n#fourchanx-settings .section-main p {\n margin: .5em 0 0;\n}\n.section-filter ul {\n padding: 0;\n}\n.section-filter li {\n margin: 10px 40px;\n list-style: disc;\n}\n.section-filter textarea {\n height: 500px;\n}\n.section-main a, .section-filter a, .section-advanced a {\n text-decoration: underline;\n}\n#sauce-doc-expand:not(:checked) ~ #sauce-doc {\n max-height: 130px;\n overflow: auto;\n}\n#sauce-doc > label {\n float: right;\n margin: 0 5px;\n}\n/* XXX for OneeChan */\n#sauce-doc-expand + .riceCheck {\n display: none;\n}\n.section-sauce textarea {\n height: 430px;\n}\n.section-advanced .field[name="boardnav"] {\n width: 100%;\n}\n.section-advanced textarea {\n height: 150px;\n}\n.section-advanced textarea[name="archiveLists"],\n.section-advanced textarea[name="externalCatalogURLs"],\n.section-advanced textarea[name="knownBanners"] {\n height: 75px;\n}\n.section-advanced .archive-cell {\n min-width: 160px;\n text-align: center;\n}\n.section-advanced #archive-board-select {\n position: absolute;\n}\n.section-advanced .note {\n font-size: 0.8em;\n font-style: italic;\n margin-left: 10px;\n}\n.section-advanced .note code {\n font-style: normal;\n font-size: 11px;\n}\n.favicon-preview > img {\n vertical-align: middle;\n}\n.favicon-preview > img:nth-of-type(3n+1) {\n margin-left: 4px;\n}\n.section-keybinds .field {\n font-family: monospace;\n}\n#fourchanx-settings fieldset {\n border: 1px solid;\n border-radius: 3px;\n padding: 0.35em 0.625em 0.75em;\n margin: 0px 2px;\n}\n#fourchanx-settings legend {\n font-weight: 700;\n color: inherit;\n}\n#fourchanx-settings textarea {\n font-family: monospace;\n width: 100%;\n resize: vertical;\n}\n#fourchanx-settings code {\n color: #000;\n background-color: #FFF;\n padding: 0 2px;\n}\n#fourchanx-settings th {\n text-align: center;\n font-weight: bold;\n}\n#fourchanx-settings p {\n margin: 1em 0px;\n}\n#fourchanx-settings table {\n margin: auto;\n}\n\n/* Index */\n:root.index-loading .navLinks:not(.json-index),\n:root.index-loading .board:not(.json-index),\n:root.index-loading .pagelist:not(.json-index),\n:root.infinite-mode .pagelist,\n:root.all-pages-mode .pagelist,\n:root.catalog-mode .pagelist,\n:root:not(.catalog-mode) .indexlink,\n:root.catalog-mode .cataloglink,\n:root:not(.catalog-mode) #hidden-label,\n:root:not(.catalog-mode) #index-size {\n display: none;\n}\n#index-search {\n padding-right: 1.5em;\n width: 100px;\n transition: color .25s, border-color .25s, width .25s;\n}\n#index-search:focus,\n#index-search[data-searching] {\n width: 200px;\n}\n#index-search-clear {\n color: gray;\n display: inline-block;\n position: relative;\n left: -1em;\n width: 0;\n}\n/* ``::-webkit-*\'\' selectors break selector lists on Firefox. */\n#index-search::-webkit-search-cancel-button {\n display: none;\n}\n#index-search:not([data-searching]) + #index-search-clear {\n display: none;\n}\n#index-options {\n float: right;\n}\n#lastlong-options {\n display: inline-block;\n vertical-align: middle;\n height: 28px;\n margin: -14px 0;\n}\n#lastlong-options > input {\n padding: 0;\n border: 0 !important;\n text-align: center;\n background: transparent;\n display: block;\n font-size: 12px;\n height: 12px;\n width: 30px;\n margin: 1px 0;\n}\n.summary {\n text-decoration: none;\n}\n\n/* Catalog */\n:root.catalog-mode .board {\n text-align: center;\n}\n.catalog-thread {\n display: inline-block;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n border: 1px solid transparent;\n word-wrap: break-word;\n vertical-align: top;\n position: relative;\n}\n/* overrides 4chan CSS on div.thread */\n.catalog-thread.catalog-thread {\n margin: 2px;\n}\n.catalog-small > .catalog-thread {\n width: 165px;\n height: 320px;\n}\n.catalog-large > .catalog-thread {\n width: 270px;\n height: 410px;\n}\n:root.catalog-hover-expand .catalog-thread:hover {\n z-index: 1;\n}\n.catalog-container {\n position: absolute;\n top: -4px;\n left: 0;\n right: 0;\n bottom: 0;\n}\n.catalog-container:not(:hover),\n:root:not(.catalog-hover-expand) .catalog-container {\n overflow: hidden;\n}\n.catalog-post {\n position: absolute;\n top: 4px;\n left: 0;\n right: 0;\n border: 1px solid transparent;\n padding-top: 20px;\n}\n/* overrides inline CSS from Index.cb.hoverAdjust */\n:root:not(.catalog-hover-expand) .catalog-post {\n left: 0 !important;\n right: 0 !important;\n}\n/* overrides 4chan CSS on div.post */\n.catalog-post.catalog-post {\n margin: -21px -1px -1px;\n overflow: visible;\n}\n.catalog-thread.noFile > * > .catalog-post {\n margin-top: -7px;\n padding-top: 6px;\n}\n:root.catalog-hover-expand .catalog-container:hover > .catalog-post {\n margin-left: -61px;\n margin-right: -61px;\n}\n:root.catalog-hover-expand .catalog-container:hover > * > :not(.catalog-replies) {\n padding-left: 2px;\n padding-right: 2px;\n}\n.catalog-link {\n display: block;\n position: relative;\n}\n.catalog-thumb {\n border-radius: 2px;\n box-shadow: 0 0 5px rgba(0, 0, 0, .25);\n vertical-align: top;\n}\n.catalog-thumb.spoiler-file {\n width: 100px;\n height: 100px;\n}\n.catalog-thumb.deleted-file {\n width: 127px;\n height: 13px;\n padding: 20px 11px;\n}\n.catalog-thumb.no-file {\n width: 77px;\n height: 13px;\n padding: 20px 36px;\n}\n.catalog-icons > img,\n.catalog-stats > .menu-button {\n width: 1em;\n height: 1em;\n margin: 0;\n vertical-align: text-top;\n padding-left: 2px;\n}\n.catalog-stats > .menu-button {\n font-weight: normal;\n}\n.catalog-stats > .menu-button > i::before {\n line-height: 11px;\n}\n.catalog-stats {\n font-size: 10px;\n font-weight: 700;\n padding-top: 2px;\n}\n.catalog-stats > [title] {\n cursor: help;\n}\n.catalog-post > .postMessage {\n margin: 0;\n padding-bottom: .3em;\n}\n.catalog-container:not(:hover) > * > .file,\n.catalog-container:not(:hover) > * > .postInfo > :not(.subject),\n.catalog-container:not(:hover) > * > .catalog-replies,\n.catalog-container:not(:hover) .extra-linebreak,\n.catalog-container:not(:hover) .abbr,\n:root:not(.catalog-hover-expand) .catalog-container > * > .file,\n:root:not(.catalog-hover-expand) .catalog-container > * > .postInfo > :not(.subject),\n:root:not(.catalog-hover-expand) .catalog-container > * > .catalog-replies,\n:root:not(.catalog-hover-expand) .catalog-container .extra-linebreak,\n:root:not(.catalog-hover-expand) .catalog-container .abbr,\n.catalog-thread > .catalog-container > :not(.catalog-post),\n.catalog-post > .file > :not(.fileText),\n.catalog-post > * > .fileText > :not(:first-child),\n.catalog-post > .postInfo > :not(.subject):not(.nameBlock):not(.dateTime),\n.catalog-post > .postInfo > .nameBlock > .contact-links,\n.catalog-post > * > * > .posteruid,\n.catalog-post > * > * > .postJumper,\n:root.bottom-backlinks .catalog-post > .container,\n.post:not(.catalog-post) > .catalog-link,\n.post:not(.catalog-post) > .catalog-stats,\n.post:not(.catalog-post) > .catalog-replies {\n display: none;\n}\n.catalog-post > .file {\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n min-height: 20px;\n background-color: inherit;\n}\n.catalog-post > * > .fileText {\n position: relative;\n padding: 2px;\n background-color: inherit;\n}\n.catalog-small .catalog-post > * .fileText {\n font-size: 10px;\n}\n.catalog-post > * > .fileText:not(:hover) {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.catalog-post > * > .fileText:hover {\n z-index: 1;\n}\n/* overrides 4chan CSS on div.post div.postInfo */\n.catalog-post > .postInfo.postInfo {\n width: auto;\n}\n.catalog-post > * > .subject {\n display: block;\n}\n.catalog-post > * > .dateTime {\n display: inline-block;\n font-style: italic;\n}\n:root.catalog-hover-expand .catalog-container:hover > * > * > .nameBlock,\n:root.catalog-hover-expand .catalog-container:hover > * > * > .dateTime,\n:root.catalog-hover-expand .catalog-container:hover > * > .postMessage:not(:empty) {\n padding-top: .3em;\n}\n.catalog-post .extra-linebreak {\n content: \'\'; /* makes this work in Blink/WebKit */\n display: block;\n margin-top: .3em;\n}\n.catalog-reply {\n text-align: left;\n white-space: nowrap;\n border-top: 1px solid transparent;\n display: -webkit-flex;\n display: flex;\n -webkit-flex-direction: row;\n flex-direction: row;\n -webkit-align-items: stretch;\n align-items: stretch;\n}\n.catalog-reply > * {\n padding: 3px;\n overflow: hidden;\n -webkit-flex: none;\n flex: none;\n}\n.catalog-reply > span {\n font-style: italic;\n font-weight: bold;\n}\n.catalog-reply-excerpt {\n -webkit-flex: 1 1 auto;\n flex: 1 1 auto;\n}\n.catalog-post .prettyprinted {\n max-width: 100%;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n.catalog-post .MathJax_Display {\n text-align: center !important;\n}\n.catalog-container:not(:hover) .exif,\n:root:not(.catalog-hover-expand) .catalog-container .exif {\n display: none !important;\n}\n.catalog-post > * > .exif {\n border-collapse: collapse;\n}\n:root.catalog-hover-expand .catalog-container:hover .exif[style*="display: block;"] {\n display: inline-block !important;\n}\n.catalog-post > * > .exif,\n.catalog-post > * > .exif > tbody {\n background-color: inherit;\n}\n.catalog-post > * > .exif,\n.catalog-post > * > .exif td {\n min-width: 0;\n}\n.catalog-post > * > .exif td {\n padding-top: 1px;\n}\n:root.hats-enabled .catalog-thread::after {\n content: \'\';\n pointer-events: none;\n position: absolute;\n background-size: contain;\n}\n:root.hats-enabled .catalog-small > .catalog-thread::after {\n left: -8px;\n top: -59px;\n width: 96px;\n height: 96px;\n}\n:root.hats-enabled:not(.werkTyme) .catalog-small > .catalog-thread:not(.noFile)::after {\n left: calc(67px - .3px * var(--tn-w));\n}\n:root.hats-enabled .catalog-large > .catalog-thread::after {\n left: -15px;\n top: -98px;\n width: 160px;\n height: 160px;\n}\n:root.hats-enabled:not(.werkTyme) .catalog-large > .catalog-thread:not(.noFile)::after {\n left: calc(110px - .5px * var(--tn-w));\n}\n\n/* Copy Text Link\'s textarea element */\ntextarea.copy-text-element {\n height: 0;\n width: 0;\n position: absolute;\n top: -10000px;\n}\n\n/* Announcement Hiding */\n:root.hide-announcement $site$psa {\n display: none;\n}\n.hide-announcement-button {\n opacity: 0.4;\n float: left;\n}\n\n/* Unread */\n.unread-line {\n margin: 0;\n border-color: rgb(255,0,0);\n}\n.unread-line + br {\n display: none;\n}\n.unread-mark-read {\n float: right;\n clear: both;\n width: 100%;\n text-align: right;\n}\n:not(.unread-thread) > .unread-mark-read {\n display: none;\n}\n\n/* Thread Updater */\n#updater {\n background: none;\n border: none;\n box-shadow: none;\n}\n#updater > .move {\n position: absolute;\n top: -5px;\n bottom: -5px;\n left: -5px;\n right: -5px;\n z-index: -1;\n}\n#updater > div:last-child {\n text-align: center;\n}\n#updater input[type="number"] {\n width: 4em;\n}\n:root.float #updater {\n padding: 0px 3px;\n}\n:root:not(.float).shortcut-icons #updater {\n display: inline-block;\n min-width: 12pt;\n text-align: right;\n}\n.new {\n color: limegreen;\n}\n#update-status:not(.empty) + #update-timer:not(.empty):not(.loading) {\n margin-left: 5px;\n}\n#update-timer {\n cursor: pointer;\n}\n\n/* Thread Watcher */\n#thread-watcher {\n position: absolute;\n}\n#thread-watcher {\n padding-bottom: 3px;\n padding-left: 3px;\n white-space: nowrap;\n min-width: 146px;\n}\n#watched-threads {\n overflow-x: hidden;\n overflow-y: auto;\n}\n#thread-watcher .refresh {\n padding: 0px 3px;\n}\n:root.fixed-watcher #thread-watcher {\n position: fixed;\n}\n:root.fixed-watcher #watched-threads {\n /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */\n max-height: 85vh;\n max-height: calc(100vh - 75px);\n}\n:root:not(.fixed-watcher) #watched-threads:not(:hover) {\n max-height: 210px;\n overflow-y: hidden;\n}\n#thread-watcher > .move {\n padding-top: 3px;\n}\n#watched-threads > div {\n padding-left: 3px;\n padding-right: 3px;\n}\n#watched-threads .watcher-link {\n max-width: 250px;\n display: -webkit-inline-flex;\n display: inline-flex;\n -webkit-flex-direction: row;\n flex-direction: row;\n}\n#watched-threads .watcher-page,\n#watched-threads .watcher-unread {\n -webkit-flex: 0 0 auto;\n flex: 0 0 auto;\n margin-right: 2px;\n}\n#watched-threads .watcher-title {\n overflow: hidden;\n text-overflow: ellipsis;\n -webkit-flex: 0 1 auto;\n flex: 0 1 auto;\n}\n#watched-threads .watcher-title:not(:first-child) {\n margin-left: 2px;\n}\n.replies-quoting-you > a, #watcher-link.replies-quoting-you, .last-page > a > .watcher-page {\n color: #F00;\n}\n#thread-watcher a {\n text-decoration: none;\n}\n#thread-watcher .move > .close {\n position: absolute;\n right: 0px;\n top: 0px;\n padding: 0px 4px;\n}\n.watch-thread-link {\n padding-top: 18px;\n width: 18px;\n height: 0px;\n display: inline-block;\n background-repeat: no-repeat;\n opacity: 0.2;\n position: relative;\n top: 1px;\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(0,0,0)\' 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}\n.watch-thread-link.watched {\n opacity: 1;\n}\n\n\n/* Thread Stats */\n#thread-stats {\n background: none;\n border: none;\n box-shadow: none;\n}\n:root.float #thread-stats > .move > :not(#page-count) {\n pointer-events: none;\n}\n:root.float #thread-stats {\n padding: 0px 3px;\n}\n#page-count {\n cursor: pointer;\n}\n\n/* Quote */\n.hashlink::before {\n content: \' \';\n visibility: hidden;\n}\n.inline + .hashlink {\n display: none !important;\n}\n:root.resurrect-quotes .deadlink {\n text-decoration: none !important;\n}\n.catalog-post .qmark-ct {\n display: none;\n}\n.backlink.deadlink:not(.forwardlink),\n.quotelink.deadlink:not(.forwardlink) {\n text-decoration: underline !important;\n}\n:root:not(.catalog-mode) .inlined {\n opacity: .5;\n}\n#qp input, .forwarded {\n display: none;\n}\n.quotelink.forwardlink,\n.backlink.forwardlink {\n text-decoration: none;\n border-bottom: 1px dashed;\n}\n.filtered {\n text-decoration: underline line-through;\n}\n:root.hide-backlinks .backlink.filtered,\n:root.hide-backlinks .backlink.filtered + .hashlink.filtered {\n display: none;\n}\n.postNum + .container::before {\n content: " ";\n}\n:root.bottom-backlinks .container {\n display: block;\n clear: both;\n margin: 0 4px;\n}\n:root.bottom-backlinks .backlink {\n font-size: 90%;\n}\n.inline {\n border: 1px solid;\n display: table;\n margin: 2px 0;\n}\n.container ~ .inline {\n margin-left: 20px;\n}\n:root.catalog-mode .inline {\n display: none;\n}\n.inline .post {\n border: 0 !important;\n background-color: transparent !important;\n display: table !important;\n margin: 0 !important;\n padding: 1px 2px !important;\n}\n#qp > .opContainer::after {\n content: \'\';\n clear: both;\n display: table;\n}\n#qp .post {\n border: none;\n margin: 0;\n padding: 2px 2px 5px;\n}\n#qp img {\n max-height: 80vh;\n max-width: 50vw;\n}\n\n/* Quote Threading */\n.threadContainer {\n margin-left: 20px;\n border-left: 1px solid rgba(128,128,128,.3);\n}\n.threadOP {\n clear: both;\n}\n\n/* File */\n.expanded-image > .post > .file > .fileThumb {\n display: flex;\n flex-direction: column;\n}\n.fileText-original,\n.fnswitch:hover > .fntrunc,\n.fnswitch:not(:hover) > .fnfull,\n.expanded-image > .post > .file > .fileThumb > video[data-md5],\n.expanded-image > .post > .file > .fileThumb > img[data-md5] {\n display: none;\n}\n.full-image[data-file-i-d] {\n display: none;\n cursor: pointer;\n}\n.expanded-image > .post > .file > .fileThumb > .full-image {\n display: inline;\n}\n.expanded-image > .post > .file > .fileThumb > audio {\n height: 30px;\n width: 100%;\n min-width: 300px;\n}\n.expanded-image {\n clear: left;\n}\n.expanding {\n opacity: .5;\n}\n:root.fit-height .full-image {\n max-height: 100vh;\n}\n:root.fit-height.fixed .full-image {\n /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */\n max-height: 93vh;\n max-height: calc(100vh - 35px);\n}\n:root.fit-width .full-image {\n max-width: 100%;\n}\n:root.ua-gecko.fit-width .full-image {\n width: 100%;\n}\n.fileThumb > .warning {\n clear: both;\n}\n#ihover {\n pointer-events: none;\n /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */\n max-height: 95vh;\n max-height: calc(100vh - 25px);\n max-width: 100vw;\n}\n/* WEBM Metadata */\n.webm-title > a::before {\n content: "title";\n text-decoration: underline;\n}\n.webm-title.loading > a::after {\n content: "...";\n}\n.webm-title.error > a:hover::before,\n.webm-title.error > a:focus::before {\n content: "error";\n text-decoration: none;\n}\n.webm-title > span {\n cursor: text;\n}\n.webm-title.not-found > span::before {\n content: "not found";\n}\n.webm-title:not(:hover):not(:focus) > span,\n.webm-title:hover > span + a,\n.webm-title:focus > span + a {\n display: none;\n}\n/* Volume control */\ninput[name="Default Volume"] {\n width: 4em;\n height: 1ex;\n vertical-align: middle;\n margin: 0px;\n}\n/* Fappe and Werk Tyme */\n:root.fappeTyme $site$replyOriginal.noFile,\n:root.fappeTyme $site$replyOriginal.noFile + br {\n display: none;\n}\n:root.werkTyme $site$thumbLink,\n:root.werkTyme $site$file$thumb,\n:root.werkTyme .catalog-thumb:not(.deleted-file):not(.no-file),\n:root:not(.werkTyme) .werkTyme-filename {\n display: none;\n}\n.werkTyme-filename {\n font-weight: bold;\n font-size: 110%;\n}\n:root.werkTyme .catalog-link {\n box-shadow: 0 0 5px rgba(0, 0, 0, .25);\n padding: 8px;\n text-align: center;\n}\n:root.werkTyme .catalog-thumb {\n box-shadow: none;\n padding: 0;\n vertical-align: middle;\n}\n.indicator {\n background: rgba(255,0,0,0.8);\n font-weight: bold;\n display: inline-block;\n min-width: 9px;\n padding: 0px 2px;\n margin: 0 1px;\n text-align: center;\n color: white;\n border-radius: 2px;\n cursor: pointer;\n}\n:root:not(.fappeTyme) #shortcut-fappe,\n:root:not(.werkTyme) #shortcut-werk {\n display: none;\n}\n\n/* Index/Reply Navigation */\n#navlinks {\n font-size: 16px;\n top: 25px;\n right: 10px;\n}\n:root.catalog-mode #navlinks {\n display: none;\n}\n\n/* Highlighting */\n.qphl {\n outline: 2px solid rgba(216, 94, 49, .8);\n}\n:root.highlight-you .quotesYou$site$highlightable$op,\n:root.highlight-you .quotesYou$site$highlightable$reply {\n border-left: 3px solid rgba(221, 0, 0, .8);\n}\n:root.highlight-own .yourPost$site$highlightable$op,\n:root.highlight-own .yourPost$site$highlightable$reply {\n border-left: 3px dashed rgba(221, 0, 0, .8);\n}\n.filter-highlight$site$highlightable$op,\n.filter-highlight$site$highlightable$reply {\n box-shadow: inset 5px 0 rgba(221, 0, 0, .5);\n}\n:root.highlight-own .yourPost > $site$sideArrows,\n:root.highlight-you .quotesYou > $site$sideArrows,\n.filter-highlight > $site$sideArrows {\n color: rgba(221, 0, 0, .8);\n}\n:root.highlight-own .yourPost$site$highlightable$op::after,\n:root.highlight-you .quotesYou$site$highlightable$op::after,\n.filter-highlight$site$highlightable$op::after {\n content: "";\n display: block;\n clear: both;\n}\n:root:not(.werkTyme) .catalog-thread.filter-highlight .catalog-thumb,\n:root.werkTyme .catalog-thread.filter-highlight:not(:hover),\n:root.werkTyme:not(.catalog-hover-expand) .catalog-thread.filter-highlight,\n:root.werkTyme.catalog-hover-expand .catalog-thread.filter-highlight > .catalog-container:hover > .catalog-post,\n:root.catalog $site$catalog$thread.filter-highlight$site$highlightable$catalog {\n box-shadow: 0 0 3px 3px rgba(255, 0, 0, .5);\n}\n:root:not(.werkTyme) .catalog-thread.watched .catalog-thumb,\n:root:root.werkTyme .catalog-thread.watched:not(:hover),\n:root:root.werkTyme:not(.catalog-hover-expand) .catalog-thread.watched,\n:root.werkTyme.catalog-hover-expand .catalog-thread.watched > .catalog-container:hover > .catalog-post {\n border: 2px solid rgba(255, 0, 0, .75);\n}\n\n/* Spoiler text */\n:root.reveal-spoilers $site$spoiler,\n:root.reveal-spoilers $site$spoiler > a {\n color: white !important;\n}\n:root.reveal-spoilers .removed-spoiler::before {\n content: "[spoiler]";\n}\n:root.reveal-spoilers .removed-spoiler::after {\n content: "[/spoiler]";\n}\n\n/* Thread & Reply Hiding */\n.hide-thread-button,\n.hide-reply-button {\n float: left;\n margin-right: 4px;\n padding: 2px;\n}\n$site$infoRoot a.hide-reply-button {\n margin-right: 6px;\n padding: 0;\n}\n.replacedSideArrows {\n float: left;\n}\n.hide-thread-button:not(:hover),\n.hide-reply-button:not(:hover) {\n opacity: 0.4;\n}\n.threadContainer .hide-reply-button {\n margin-left: 2px !important;\n position: relative;\n left: 1px;\n}\n.hide-thread-button {\n margin-top: -1px;\n width: 11px;\n}\n.stub ~ :not(.threadDivider) {\n display: none !important;\n}\n.stub input {\n display: inline-block;\n}\n$site$thread[hidden] + hr {\n display: none;\n}\n:root.reply-hide $site$sideArrows {\n display: none;\n}\n:root.sw-yotsuba.thread-hide .party-hat {\n left: 19px;\n}\n\n/* Anonymize */\n:root.anonymize $site$info$name,\n:root.sw-yotsuba.anonymize .post-author:not([class*=capcode]) {\n font-size: 0;\n}\n:root.anonymize $site$info$tripcode,\n:root.sw-yotsuba.anonymize .n-pu {\n display: none;\n}\n:root.anonymize $site$info$name::before,\n:root.sw-yotsuba.anonymize .post-author:not([class*=capcode])::before {\n content: "Anonymous";\n font-size: 10pt;\n}\n:root.sw-yotsuba.anonymize .flashListing .name::before,\n:root.sw-yotsuba.anonymize .post-last > .post-author:not([class*=capcode])::before {\n font-size: 9pt;\n}\n\n/* QR */\n:root.hide-original-post-form #togglePostFormLink,\n#qr.autohide:not(.focus):not(:hover):not(:active) > form,\n:root.thread-view #qr:not(.show-new-thread-option) select[data-name="thread"],\n#file-n-submit:not(.has-file) #qr-filerm {\n display: none;\n}\n:root.hide-original-post-form #postForm {\n display: none !important;\n}\n#qr select,\n#qr-filename-container > a,\n.remove,\n.captcha-img {\n cursor: pointer;\n}\n#qr {\n position: fixed;\n padding: 1px;\n border: 1px solid transparent;\n min-width: 300px;\n border-radius: 3px 3px 0 0;\n}\n#qr > form {\n /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */\n max-height: 85vh;\n max-height: calc(100vh - 75px);\n overflow-y: auto;\n overflow-x: hidden;\n}\n#qrtab {\n border-radius: 3px 3px 0 0;\n}\n#qrtab {\n margin-bottom: 1px;\n}\n#qr .close {\n float: right;\n padding: 0 3px;\n}\n.qr-link-container {\n text-align: center;\n margin: 16px 0;\n}\n.qr-link-container-bottom {\n width: 200px;\n position: absolute;\n left: -100px;\n margin-left: 50%;\n text-align: center;\n}\n.qr-link {\n border-radius: 3px;\n padding: 6px 10px 5px;\n font-weight: bold;\n vertical-align: middle;\n border-style: solid;\n border-width: 1px;\n font-size: 10pt;\n}\n.qr-link-container + #togglePostFormLink {\n font-size: 10pt;\n font-weight: normal;\n margin: -8px 0 3.5px;\n}\n.persona {\n width: 100%;\n display: -webkit-flex;\n display: flex;\n -webkit-flex-direction: row;\n flex-direction: row;\n}\n.persona .field {\n -webkit-flex: 1;\n flex: 1;\n width: 0;\n}\n#qr.forced-anon input[data-name="name"]:not(.force-show),\n#qr.forced-anon input[data-name="sub"]:not(.force-show),\n#qr.reply-to-thread input[data-name="sub"]:not(.force-show),\nbody:not(.board_f) #qr select[name="filetag"],\n#qr.reply-to-thread select[name="filetag"],\n#qr:not(.has-sjis) #sjis-toggle,\n#qr:not(.has-math) #tex-preview-button,\n#qr.tex-preview .textarea > :not(#tex-preview),\n#qr:not(.tex-preview) #tex-preview {\n display: none;\n}\n.persona button {\n -webkit-flex: 0 0 23px;\n flex: 0 0 23px;\n -webkit-align-self: stretch;\n align-self: stretch;\n border: 1px solid #BBB;\n padding: 0;\n background: linear-gradient(to bottom, #F8F8F8, #DCDCDC) no-repeat;\n color: #000;\n}\n#qr.sjis-preview #sjis-toggle, #qr.tex-preview #tex-preview-button {\n background: #DCDCDC;\n}\n#sjis-toggle, #qr.sjis-preview textarea.field {\n font-family: "IPAMonaPGothic","Mona","MS PGothic",monospace;\n font-size: 16px;\n line-height: 17px;\n}\n#tex-preview-button {\n font-size: 10px;\n}\n#tex-preview {\n white-space: pre-line;\n}\n#qr textarea.field {\n height: 14.8em;\n min-height: 9em;\n}\n#qr.has-captcha textarea.field {\n height: 9em;\n}\ninput.field.tripped:not(:hover):not(:focus) {\n color: transparent !important;\n text-shadow: none !important;\n}\n#qr textarea {\n min-width: 300px;\n resize: both;\n}\n.field {\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n margin: 0px;\n padding: 2px 4px 3px;\n}\n#qr label input[type="checkbox"] {\n position: relative;\n top: 2px;\n}\n\n/* Recaptcha v2 */\n#qr .captcha-root {\n position: relative;\n}\n#qr .captcha-container > div {\n margin: auto;\n width: 304px;\n}\n/* XXX scrollable with scroll bar hidden; prevents scroll on space press */\n:root.ua-blink #qr .captcha-container > div,\n:root.ua-edge #qr .captcha-container > div {\n overflow: hidden;\n}\n:root.ua-blink #qr .captcha-container > div > div:first-of-type,\n:root.ua-edge #qr .captcha-container > div > div:first-of-type {\n overflow-y: scroll;\n overflow-x: hidden;\n padding-right: 30px;\n height: 99%;\n width: 100%;\n}\n#qr .captcha-counter {\n display: block;\n width: 100%;\n text-align: center;\n pointer-events: none;\n}\n#qr.captcha-open .captcha-counter {\n position: absolute;\n bottom: 3px;\n}\n#qr .captcha-counter > a {\n pointer-events: auto;\n display: inline-block; /* XXX https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8851747/ */\n}\n#qr:not(.captcha-open) .captcha-counter > a {\n display: block;\n width: 100%;\n}\n#qr.captcha-v2 #qr-captcha-iframe {\n width: 302px;\n height: 423px;\n border: 0;\n display: block;\n margin: auto;\n}\n.goog-bubble-content {\n max-width: 100vw;\n max-height: 100vh;\n overflow: auto;\n}\n.goog-bubble-content iframe {\n position: static !important;\n}\n\n/* File Input, Submit Button, Oekaki */\n#file-n-submit, #qr .oekaki {\n display: -webkit-flex;\n display: flex;\n -webkit-align-items: stretch;\n align-items: stretch;\n height: 25px;\n margin-top: 1px;\n}\n#file-n-submit > input, #qr-draw-button {\n background: linear-gradient(to bottom, #F8F8F8, #DCDCDC) no-repeat;\n border: 1px solid #BBB;\n border-radius: 2px;\n height: 100%;\n}\n#qr-file-button, #qr-draw-button {\n width: 15%;\n}\n#file-n-submit input[type="submit"] {\n width: 25%;\n}\n#qr-filename-container {\n -webkit-flex: 1 1 auto;\n flex: 1 1 auto;\n width: 0;\n display: -webkit-flex;\n display: flex;\n -webkit-align-items: center;\n align-items: center;\n position: relative;\n padding: 1px;\n}\ninput#qr-filename {\n border: none !important;\n background: none !important;\n outline: none;\n}\n#qr-filename,\n.has-file #qr-no-file {\n display: none;\n}\n#qr-no-file,\n.has-file #qr-filename {\n -webkit-flex: 1 1 auto;\n flex: 1 1 auto;\n width: 0px; /* XXX Fixes filename not shrinking to allow space for buttons in Edge */\n display: inline-block;\n padding: 0;\n padding-left: 3px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n#qr-no-file {\n color: #AAA;\n}\n#qr .oekaki.has-file {\n display: none;\n}\n#qr .oekaki > label {\n -webkit-flex: 1 1 auto;\n flex: 1 1 auto;\n width: 0;\n display: -webkit-flex;\n display: flex;\n -webkit-align-items: center;\n align-items: center;\n height: 100%;\n}\n#qr .oekaki > label > span {\n margin: 0 3px;\n}\n#qr .oekaki > label > input {\n -webkit-flex: 1 1 auto;\n flex: 1 1 auto;\n width: 0;\n height: 100%;\n}\n#qr .oekaki-bg {\n position: relative;\n display: inline-block;\n height: 100%;\n width: 10%;\n margin-left: 3px;\n}\n#qr .oekaki-bg > * {\n position: absolute;\n top: 0;\n left: 0;\n margin: 0;\n}\n#qr .oekaki-bg > :not([name="oekaki-bgcolor"]) {\n z-index: 1;\n}\n#qr [name="oekaki-bgcolor"] {\n height: 100%;\n width: 100%;\n border: none;\n padding: 0;\n}\n#qr [name="oekaki-bg"]:not(:checked) ~ [name="oekaki-bgcolor"] {\n visibility: hidden;\n}\n#qr input[type="file"] {\n visibility: hidden;\n position: absolute;\n}\n\n/* Spoiler Checkbox, QR Icons */\n#qr-filename-container > label, #qr-filename-container > a {\n -webkit-flex: none;\n flex: none;\n margin: 0;\n margin-right: 3px;\n}\n#qr:not(.has-spoiler) #qr-spoiler-label,\n#file-n-submit:not(.has-file) #qr-spoiler-label,\n.has-file #paste-area,\n.has-file #url-button,\n#file-n-submit:not(.custom-cooldown) #custom-cooldown-button {\n display: none;\n}\n#qr-filename-container > label {\n position: relative;\n}\n#qr-filename-container input[type="checkbox"] {\n margin: 0;\n}\n.checkbox-letter {\n font-size: 13px;\n font-weight: bold;\n}\n#qr-filename-container label:not(:hover) > input[type="checkbox"]:not(:focus):not(:checked),\n#qr-filename-container label:not(:hover) > input[type="checkbox"]:not(:focus):not(:checked) ~ :not(.checkbox-letter),\n#qr-filename-container label:hover > .checkbox-letter,\ninput[type="checkbox"]:focus ~ .checkbox-letter,\ninput[type="checkbox"]:checked ~ .checkbox-letter {\n /* not displayed but still focusable */\n position: absolute;\n opacity: 0;\n pointer-events: none;\n}\n.checkbox-letter, #paste-area, #url-button, #custom-cooldown-button, #dump-button {\n opacity: 0.6;\n}\n#paste-area {\n font-size: 0;\n}\n#paste-area:focus {\n opacity: 1;\n}\n#custom-cooldown-button.disabled {\n opacity: 0.27;\n}\n\n/* Thread and Flash Tag Select */\n#qr select {\n background: white;\n border: 1px solid #CCC;\n}\n#qr select[data-name="thread"] {\n float: right;\n}\n#qr > form > select {\n margin-top: 1px;\n}\n\n/* Dumping UI */\n.dump #dump-list-container {\n display: block;\n}\n#dump-list-container {\n display: none;\n position: relative;\n overflow-y: hidden;\n margin-top: 1px;\n}\n#dump-list {\n overflow-x: auto;\n overflow-y: auto;\n white-space: nowrap;\n width: 248px;\n max-height: 248px;\n min-height: 90px;\n max-width: 100%;\n min-width: 100%;\n display: -webkit-flex;\n display: flex;\n -webkit-flex-wrap: wrap;\n flex-wrap: wrap;\n}\n#dump-list:hover {\n overflow-x: auto;\n}\n.qr-preview {\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n counter-increment: thumbnails;\n cursor: move;\n display: inline-block;\n height: 90px;\n width: 90px;\n padding: 2px;\n opacity: .5;\n overflow: hidden;\n position: relative;\n text-shadow: 0 0 2px #000;\n -webkit-transition: opacity .25s ease-in-out, -webkit-transform .25s ease-in-out;\n transition: opacity .25s ease-in-out, transform .25s ease-in-out, -webkit-transform .25s ease-in-out;\n vertical-align: top;\n background-size: cover;\n -webkit-flex: none;\n flex: none;\n}\n.qr-preview:hover,\n.qr-preview:focus {\n opacity: .9;\n}\n.qr-preview::before {\n content: counter(thumbnails);\n color: #fff;\n position: absolute;\n top: 3px;\n right: 3px;\n text-shadow: 0 0 3px #000, 0 0 8px #000;\n}\n.qr-preview#selected {\n opacity: 1;\n}\n.qr-preview.drag {\n box-shadow: 0 0 10px rgba(0,0,0,.5);\n -webkit-transform: scale(.8);\n transform: scale(.8);\n}\n.qr-preview.over {\n border-color: #fff;\n -webkit-transform: scale(1.1);\n transform: scale(1.1);\n opacity: 0.9;\n z-index: 10;\n}\n.qr-preview > span {\n color: #fff;\n}\n.remove {\n background: none;\n color: #e00;\n padding: 1px;\n}\na:only-of-type > .remove {\n display: none;\n}\n.remove:hover::after {\n content: " Remove";\n}\n.qr-preview:not(.has-file) label,\n#qr:not(.has-spoiler) .qr-preview-spoiler {\n display: none;\n}\n.qr-preview > label {\n background: rgba(0,0,0,.5);\n color: #fff;\n right: 0;\n bottom: 0;\n left: 0;\n position: absolute;\n text-align: center;\n}\n.qr-preview > label > input {\n margin: 0;\n}\n#add-post {\n cursor: pointer;\n font-size: 2em;\n position: absolute;\n bottom: 20px;\n right: 10px;\n -webkit-transform: translateY(-50%);\n transform: translateY(-50%);\n}\n.textarea {\n position: relative;\n display: -webkit-flex;\n display: flex;\n}\n#char-count {\n color: #000;\n background: hsla(0, 0%, 100%, .5);\n font-size: 8pt;\n position: absolute;\n bottom: 1px;\n right: 1px;\n pointer-events: none;\n}\n#char-count.warning {\n color: red;\n}\n\n/* Menu */\n.menu-button:not(.fa-bars) {\n display: inline-block;\n position: relative;\n cursor: pointer;\n}\n#header-bar .menu-button i {\n border-top: 6px solid;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n display: inline-block;\n margin: 2px;\n vertical-align: middle;\n}\n.postInfo > .menu-button,\n#thread-watcher .menu-button {\n width: 18px;\n height: 15px;\n text-align: center;\n}\n#menu {\n position: fixed;\n outline: none;\n font-weight: normal;\n}\n#menu, .submenu {\n border-radius: 3px;\n padding-top: 1px;\n padding-bottom: 3px;\n}\n.entry {\n cursor: pointer;\n display: block;\n outline: none;\n padding: 2px 10px;\n position: relative;\n text-decoration: none;\n white-space: nowrap;\n min-width: 70px;\n text-align: left;\n text-shadow: none;\n font-size: 10pt;\n}\n.left>.entry.has-submenu {\n padding-right: 17px !important;\n}\n.entry input[type="checkbox"],\n.entry input[type="radio"] {\n margin: 0px;\n position: relative;\n top: 2px;\n}\n.entry input[type="number"] {\n width: 4.5em;\n}\n.entry.has-shortcut-text {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n.entry .shortcut-text {\n opacity: 0.5;\n font-size: 70%;\n margin-left: 5px;\n}\n.has-submenu::after {\n content: "";\n border-left: .5em solid;\n border-top: .3em solid transparent;\n border-bottom: .3em solid transparent;\n display: inline-block;\n margin: .3em;\n position: absolute;\n right: 3px;\n}\n.left .has-submenu::after {\n border-left: 0;\n border-right: .5em solid;\n}\n.submenu {\n display: none;\n position: absolute;\n left: 100%;\n top: -1px;\n margin-left: 0px;\n margin-top: -2px;\n}\n.focused > .submenu {\n display: block;\n}\n.imp-exp-result {\n position: absolute;\n text-align: center;\n margin: auto;\n right: 0px;\n left: 0px;\n width: 200px;\n}\n\n/* Custom Board Titles */\n.boardTitle, .boardSubtitle {\n white-space: pre-line;\n}\n.boardTitle[contenteditable="true"],\n.boardSubtitle[contenteditable="true"] {\n cursor: text !important;\n}\n\n/* Embedding */\n.embedder:not(.embedded) > span {\n display: none;\n}\n#embedding {\n padding: 1px 4px 1px 4px;\n position: fixed;\n}\n#embedding.empty {\n display: none;\n}\n#embedding > div:first-child {\n display: -webkit-flex;\n display: flex;\n}\n#embedding .move {\n -webkit-flex: 1;\n flex: 1;\n}\n#embedding .jump {\n margin: -1px 4px;\n text-decoration: none;\n}\n\n/* Gallery */\n#a-gallery {\n position: fixed;\n top: 0;\n bottom: 0;\n left: 0;\n right: 0;\n display: -webkit-flex;\n display: flex;\n -webkit-flex-direction: row;\n flex-direction: row;\n background: rgba(0,0,0,0.7);\n}\n.gal-viewport {\n display: -webkit-flex;\n display: flex;\n -webkit-align-items: stretch;\n align-items: stretch;\n -webkit-flex-direction: row;\n flex-direction: row;\n -webkit-flex: 1 1 auto;\n flex: 1 1 auto;\n overflow: hidden;\n}\n.gal-thumbnails {\n -webkit-flex: 0 0 150px;\n flex: 0 0 150px;\n overflow-y: auto;\n display: -webkit-flex;\n display: flex;\n -webkit-flex-direction: column;\n flex-direction: column;\n -webkit-align-items: stretch;\n align-items: stretch;\n text-align: center;\n background: rgba(0,0,0,.5);\n border-left: 1px solid #222;\n}\n.gal-hide-thumbnails .gal-thumbnails {\n display: none;\n}\n.gal-thumb img,\n.gal-thumb video {\n max-width: 125px;\n max-height: 125px;\n height: auto;\n width: auto;\n}\n.gal-thumb {\n -webkit-flex: 0 0 auto;\n flex: 0 0 auto;\n padding: 3px;\n line-height: 0;\n transition: background .2s linear;\n}\n.gal-highlight {\n background: rgba(0, 190, 255,.8);\n}\n.gal-prev {\n border-right: 1px solid #222;\n}\n.gal-next {\n border-left: 1px solid #222;\n}\n.gal-prev,\n.gal-next {\n -webkit-flex: 0 0 20px;\n flex: 0 0 20px;\n position: relative;\n cursor: pointer;\n opacity: 0.7;\n background-color: rgba(0, 0, 0, 0.3);\n}\n.gal-prev:hover,\n.gal-next:hover {\n opacity: 1;\n}\n.gal-prev::after,\n.gal-next::after {\n position: absolute;\n top: 48.6%;\n -webkit-transform: translateY(-50%);\n transform: translateY(-50%);\n display: inline-block;\n border-top: 11px solid transparent;\n border-bottom: 11px solid transparent;\n content: "";\n}\n.gal-prev::after {\n border-right: 12px solid #fff;\n right: 5px;\n}\n.gal-next::after {\n border-left: 12px solid #fff;\n right: 3px;\n}\n.gal-image {\n -webkit-flex: 1 0 auto;\n flex: 1 0 auto;\n display: -webkit-flex;\n display: flex;\n -webkit-align-items: flex-start;\n align-items: flex-start;\n -webkit-justify-content: space-around;\n justify-content: space-around;\n overflow: hidden;\n /* Flex > Non-Flex child max-width and overflow fix (Firefox only?) */\n width: 1%;\n}\n:root:not(.gal-fit-height):not(.gal-pdf) .gal-image {\n overflow-y: scroll !important;\n}\n:root:not(.gal-fit-width):not(.gal-pdf) .gal-image {\n overflow-x: scroll !important;\n}\n.gal-image a {\n display: -webkit-flex;\n display: flex;\n -webkit-align-items: flex-start;\n align-items: flex-start;\n margin: auto;\n line-height: 0;\n max-width: 100%;\n}\n:root.gal-pdf .gal-image a {\n width: 100%;\n height: 100%;\n}\n.gal-image img,\n.gal-image video {\n -webkit-flex: none;\n flex: none;\n}\n.gal-fit-width .gal-image img,\n.gal-fit-width .gal-image video {\n max-width: 100%;\n}\n.gal-fit-height .gal-image img,\n.gal-fit-height .gal-image video {\n /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */\n max-height: 95vh;\n max-height: calc(100vh - 25px);\n}\n.gal-image iframe {\n width: 100%;\n height: 100%;\n}\n.gal-buttons {\n font-size: 2em;\n margin-right: 3px;\n padding-left: 7px;\n padding-right: 7px;\n top: 5px;\n}\n:root.gal-pdf .gal-buttons {\n top: 40px;\n background: rgba(0,0,0,0.6) !important;\n border-radius: 3px;\n}\n.gal-buttons a {\n color: #ffffff;\n text-shadow: 0px 0px 1px #000000;\n}\n.gal-buttons i {\n display: inline-block;\n margin: 2px;\n position: relative;\n}\n.gal-start i {\n border-left: 10px solid;\n border-top: 6px solid transparent;\n border-bottom: 6px solid transparent;\n bottom: 1px;\n}\n.gal-stop i {\n border: 5px solid;\n bottom: 2px;\n}\n.gal-buttons.gal-playing > .gal-start,\n.gal-buttons:not(.gal-playing) > .gal-stop {\n display: none;\n}\n.gal-buttons .menu-button i {\n border-top: 10px solid;\n border-right: 6px solid transparent;\n border-left: 6px solid transparent;\n bottom: 2px;\n vertical-align: baseline;\n}\n.gal-labels {\n position: fixed;\n bottom: 6px;\n display: -webkit-flex;\n display: flex;\n -webkit-flex-direction: column;\n flex-direction: column;\n -webkit-align-items: flex-end;\n align-items: flex-end;\n\n}\n:root:not(.show-sauce) .gal-sauce {\n display: none;\n}\n.gal-name,\n.gal-count,\n.gal-sauce {\n background: rgba(0,0,0,0.6) !important;\n border-radius: 3px;\n padding: 1px 5px 2px 5px;\n margin-top: 3px;\n color: #ffffff !important;\n text-decoration: none !important;\n}\n.gal-sauce a {\n color: #ffffff !important;\n}\n.gal-name:hover,\n.gal-buttons a:hover,\n.gal-sauce a:hover {\n color: rgb(95, 95, 101) !important;\n}\n:root.gal-pdf .gal-buttons a:hover {\n color: rgb(204, 204, 204) !important;\n}\n.gal-buttons,\n.gal-labels {\n position: fixed;\n right: 195px;\n}\n.gal-hide-thumbnails .gal-buttons,\n.gal-hide-thumbnails .gal-labels {\n right: 44px;\n}\n:root:not(.gal-fit-width):not(.gal-pdf) .gal-labels {\n bottom: 23px !important;\n}\n:root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-buttons,\n:root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-labels {\n right: 178px !important;\n}\n:root.gal-hide-thumbnails.gal-fit-height:not(.gal-pdf) .gal-buttons,\n:root.gal-hide-thumbnails.gal-fit-height:not(.gal-pdf) .gal-labels {\n right: 28px !important;\n}\n:root.gallery-open.fixed #header-bar:not(.autohide),\n:root.gallery-open.fixed #header-bar:not(.autohide) #shortcuts .fa::before {\n visibility: hidden;\n}\n\n/* Mod Contact Links */\n.contact-links {\n margin-left: 2px;\n}\n.move-note > a {\n text-decoration: underline;\n}\n.invisible {\n font-size: 0;\n}\n\n/* PostJumper */\n.postJumper > .prev,\n.postJumper > .next {\n font-size: 120%;\n}\n\n/* PSA */\n.fcx-announcement {\n text-align: center;\n}\n.fcx-announcement a {\n text-decoration: underline;\n}\n\n@keyframes spin {\n 0% {transform:rotate(0deg);}\n 100% {transform:rotate(359deg);}\n}\n\n.spin {\n animation:spin 2s infinite linear;\n}\n/* General */\n:root.yotsuba .dialog {\n background-color: #F0E0D6;\n border-color: #D9BFB7;\n}\n:root.yotsuba .field:focus,\n:root.yotsuba .field.focus {\n border-color: #EA8;\n}\n\n/* 4chan style fixes */\n:root.yotsuba.highlight-you .quotesYou$site$highlightable$reply {\n border-left: 3px solid rgba(221, 0, 0, .8) !important;\n}\n:root.yotsuba.highlight-own .yourPost$site$highlightable$reply {\n border-left: 3px dashed rgba(221, 0, 0, .8) !important;\n}\n\n/* Header */\n:root.yotsuba #header-bar.dialog {\n background-color: rgba(240,224,214,0.98);\n}\n:root.yotsuba:not(.fixed) #header-bar, :root.yotsuba #notifications {\n font-size: 9pt;\n}\n:root.yotsuba #header-bar, :root.yotsuba #notifications {\n color: #B86;\n}\n:root.yotsuba #board-list a, :root.yotsuba #shortcuts a {\n color: #800000;\n}\n\n/* Settings */\n:root.yotsuba #fourchanx-settings fieldset, :root.yotsuba .section-main div::before {\n border-color: #D9BFB7;\n}\n:root.yotsuba .suboption-list > div:last-of-type {\n background-color: #F0E0D6;\n}\n\n/* Catalog */\n:root.yotsuba.catalog-hover-expand .catalog-container:hover > .post {\n background-color: #F0E0D6;\n}\n:root.yotsuba.werkTyme .catalog-thread:not(:hover),\n:root.yotsuba.werkTyme:not(.catalog-hover-expand) .catalog-thread,\n:root.yotsuba.catalog-hover-expand .catalog-container:hover > .post,\n:root.yotsuba.catalog-hover-expand .catalog-container:hover .catalog-reply {\n border-color: #D9BFB7;\n}\n\n/* Quote */\n:root.yotsuba .backlink.deadlink {\n color: #00E !important;\n}\n:root.yotsuba .inline {\n border-color: #D9BFB7;\n background-color: rgba(255, 255, 255, .14);\n}\n\n/* Fappe and Werk Tyme */\n:root.yotsuba .indicator {\n color: #F0E0D6;\n}\n\n/* QR */\n.yotsuba #dump-list::-webkit-scrollbar-thumb {\n background-color: #F0E0D6;\n border-color: #D9BFB7;\n}\n:root.yotsuba .qr-preview {\n background-color: rgba(0, 0, 0, .15);\n}\n:root.yotsuba .qr-link {\n border-color: rgb(225, 209, 199) rgb(225, 209, 199) rgb(210, 194, 184);\n background: linear-gradient(#FFEFE5, #F0E0D6) repeat scroll 0% 0% transparent;\n}\n:root.yotsuba .qr-link:hover {\n background: #F0E0D6;\n}\n\n/* Menu */\n:root.yotsuba #menu {\n color: #800000;\n}\n:root.yotsuba .entry {\n font-size: 10pt;\n}\n:root.yotsuba .focused.entry {\n background: rgba(255, 255, 255, .33);\n}\n\n/* Unread */\n:root.yotsuba .unread-mark-read {\n background-color: rgba(240,224,214,0.5);\n}\n\n/* Thread Watcher */\n:root.yotsuba .replies-quoting-you > a, :root.yotsuba #watcher-link.replies-quoting-you, :root.yotsuba .last-page > a > .watcher-page {\n color: #F00;\n}\n\n/* Watcher Favicon */\n:root.yotsuba .watch-thread-link\n{\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(128,0,0)\' 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}\n/* General */\n:root.yotsuba-b .dialog {\n background-color: #D6DAF0;\n border-color: #B7C5D9;\n}\n:root.yotsuba-b .field:focus,\n:root.yotsuba-b .field.focus {\n border-color: #98E;\n}\n\n/* 4chan style fixes */\n:root.yotsuba-b.highlight-you .quotesYou$site$highlightable$reply {\n border-left: 3px solid rgba(221, 0, 0, .8) !important;\n}\n:root.yotsuba-b.highlight-own .yourPost$site$highlightable$reply {\n border-left: 3px dashed rgba(221, 0, 0, .8) !important;\n}\n\n/* Header */\n:root.yotsuba-b #header-bar.dialog {\n background-color: rgba(214,218,240,0.98);\n}\n:root.yotsuba-b:not(.fixed) #header-bar, :root.yotsuba-b #notifications {\n font-size: 9pt;\n}\n:root.yotsuba-b #header-bar, :root.yotsuba-b #notifications {\n color: #89A;\n}\n:root.yotsuba-b #board-list a, :root.yotsuba-b #shortcuts a {\n color: #34345C;\n}\n\n/* Settings */\n:root.yotsuba-b #fourchanx-settings fieldset, :root.yotsuba-b .section-main div::before {\n border-color: #B7C5D9;\n}\n:root.yotsuba-b .suboption-list > div:last-of-type {\n background-color: #D6DAF0;\n}\n\n/* Catalog */\n:root.yotsuba-b.catalog-hover-expand .catalog-container:hover > .post {\n background-color: #D6DAF0;\n}\n:root.yotsuba-b.werkTyme .catalog-thread:not(:hover),\n:root.yotsuba-b.werkTyme:not(.catalog-hover-expand) .catalog-thread,\n:root.yotsuba-b.catalog-hover-expand .catalog-container:hover > .post,\n:root.yotsuba-b.catalog-hover-expand .catalog-container:hover .catalog-reply {\n border-color: #B7C5D9;\n}\n\n/* Quote */\n:root.yotsuba-b .backlink.deadlink {\n color: #34345C !important;\n}\n:root.yotsuba-b .inline {\n border-color: #B7C5D9;\n background-color: rgba(255, 255, 255, .14);\n}\n\n/* Fappe and Werk Tyme */\n:root.yotsuba-b .indicator {\n color: #D6DAF0;\n}\n\n/* QR */\n.yotsuba-b #dump-list::-webkit-scrollbar-thumb {\n background-color: #D6DAF0;\n border-color: #B7C5D9;\n}\n:root.yotsuba-b .qr-preview {\n background-color: rgba(0, 0, 0, .15);\n}\n:root.yotsuba-b .qr-link {\n border-color: rgb(199, 203, 225) rgb(199, 203, 225) rgb(184, 188, 210);\n background: linear-gradient(#E5E9FF, #D6DAF0) repeat scroll 0% 0% transparent;\n}\n:root.yotsuba-b .qr-link:hover {\n background: #D9DDF3;\n}\n\n\n/* Menu */\n:root.yotsuba-b #menu {\n color: #000;\n}\n:root.yotsuba-b .entry {\n font-size: 10pt;\n}\n:root.yotsuba-b .focused.entry {\n background: rgba(255, 255, 255, .33);\n}\n\n/* Unread */\n:root.yotsuba-b .unread-mark-read {\n background-color: rgba(214,218,240,0.5);\n}\n\n/* Thread Watcher */\n:root.yotsuba-b .replies-quoting-you > a, :root.yotsuba-b #watcher-link.replies-quoting-you {\n color: #F00;\n}\n\n/* Watcher Favicon */\n:root.yotsuba-b .watch-thread-link\n{\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(0,0,0)\' 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}\n/* General */\n:root.futaba .dialog {\n background-color: #F0E0D6;\n border-color: #D9BFB7;\n}\n:root.futaba .field:focus,\n:root.futaba .field.focus {\n border-color: #EA8;\n}\n\n/* Header */\n:root.futaba #header-bar.dialog {\n background-color: rgba(240,224,214,0.98);\n}\n:root.futaba:not(.fixed) #header-bar, :root.futaba #notifications {\n font-size: 11pt;\n}\n:root.futaba #header-bar, :root.futaba #notifications {\n color: #B86;\n}\n:root.futaba #header-bar a, :root.futaba #notifications a {\n color: #800000;\n}\n\n/* Settings */\n:root.futaba #fourchanx-settings fieldset, :root.futaba .section-main div::before {\n border-color: #D9BFB7;\n}\n:root.futaba .suboption-list > div:last-of-type {\n background-color: #F0E0D6;\n}\n\n/* Catalog */\n:root.futaba.catalog-hover-expand .catalog-container:hover > .post {\n background-color: #F0E0D6;\n}\n:root.futaba.werkTyme .catalog-thread:not(:hover),\n:root.futaba.werkTyme:not(.catalog-hover-expand) .catalog-thread,\n:root.futaba.catalog-hover-expand .catalog-container:hover > .post,\n:root.futaba.catalog-hover-expand .catalog-container:hover .catalog-reply {\n border-color: #D9BFB7;\n}\n\n/* Quote */\n:root.futaba .backlink.deadlink {\n color: #00E !important;\n}\n:root.futaba .inline {\n border-color: #D9BFB7;\n background-color: rgba(255, 255, 255, .14);\n}\n\n/* Fappe and Werk Tyme */\n:root.futaba .indicator {\n color: #F0E0D6;\n}\n\n/* Anonymize */\n:root.futaba.anonymize $site$info$name::before {\n font-size: 12pt;\n}\n\n/* QR */\n.futaba #dump-list::-webkit-scrollbar-thumb {\n background-color: #F0E0D6;\n border-color: #D9BFB7;\n}\n:root.futaba .qr-preview {\n background-color: rgba(0, 0, 0, .15);\n}\n:root.futaba .qr-link {\n border-color: rgb(225, 209, 199) rgb(225, 209, 199) rgb(210, 194, 184);\n background: linear-gradient(#FFEFE5, #F0E0D6) repeat scroll 0% 0% transparent;\n}\n:root.futaba .qr-link:hover {\n background: #F0E0D6;\n}\n\n/* Menu */\n:root.futaba #menu {\n color: #800000;\n}\n:root.futaba .entry {\n font-size: 12pt;\n}\n:root.futaba .focused.entry {\n background: rgba(255, 255, 255, .33);\n}\n\n/* Unread */\n:root.futaba .unread-mark-read {\n background-color: rgba(240,224,214,0.5);\n}\n\n/* Thread Watcher */\n:root.futaba .replies-quoting-you > a, :root.futaba #watcher-link.replies-quoting-you, :root.futaba .last-page > a > .watcher-page {\n color: #F00;\n}\n\n/* Watcher Favicon */\n:root.futaba .watch-thread-link\n{\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(128,0,0)\' 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}\n/* General */\n:root.burichan .dialog {\n background-color: #D6DAF0;\n border-color: #B7C5D9;\n}\n:root.burichan .field:focus,\n:root.burichan .field.focus {\n border-color: #98E;\n}\n\n/* Header */\n:root.burichan #header-bar.dialog {\n background-color: rgba(214,218,240,0.98);\n}\n:root.burichan:not(.fixed) #header-bar, :root.burichan #header-bar #notifications {\n font-size: 11pt;\n}\n:root.burichan #header-bar, :root.burichan #header-bar #notifications {\n color: #89A;\n}\n:root.burichan #header-bar a, :root.burichan #header-bar #notifications a {\n color: #34345C;\n}\n\n/* Settings */\n:root.burichan #fourchanx-settings fieldset, :root.burichan .section-main div::before {\n border-color: #B7C5D9;\n}\n:root.burichan .suboption-list > div:last-of-type {\n background-color: #D6DAF0;\n}\n\n/* Catalog */\n:root.burichan.catalog-hover-expand .catalog-container:hover > .post {\n background-color: #D6DAF0;\n}\n:root.burichan.werkTyme .catalog-thread:not(:hover),\n:root.burichan.werkTyme:not(.catalog-hover-expand) .catalog-thread,\n:root.burichan.catalog-hover-expand .catalog-container:hover > .post,\n:root.burichan.catalog-hover-expand .catalog-container:hover .catalog-reply {\n border-color: #B7C5D9;\n}\n\n/* Quote */\n:root.burichan .backlink.deadlink {\n color: #34345C !important;\n}\n:root.burichan .inline {\n border-color: #B7C5D9;\n background-color: rgba(255, 255, 255, .14);\n}\n\n/* Fappe and Werk Tyme */\n:root.burichan .indicator {\n color: #D6DAF0;\n}\n\n/* Anonymize */\n:root.burichan.anonymize $site$info$name::before {\n font-size: 12pt;\n}\n\n/* QR */\n.burichan #dump-list::-webkit-scrollbar-thumb {\n background-color: #D6DAF0;\n border-color: #B7C5D9;\n}\n:root.burichan .qr-preview {\n background-color: rgba(0, 0, 0, .15);\n}\n:root.burichan .qr-link {\n border-color: rgb(199, 203, 225) rgb(199, 203, 225) rgb(184, 188, 210);\n background: linear-gradient(#E5E9FF, #D6DAF0) repeat scroll 0% 0% transparent;\n}\n:root.burichan .qr-link:hover {\n background: #D9DDF3;\n}\n\n/* Menu */\n:root.burichan #menu {\n color: #000000;\n}\n:root.burichan .entry {\n font-size: 12pt;\n}\n:root.burichan .focused.entry {\n background: rgba(255, 255, 255, .33);\n}\n\n/* Unread */\n:root.burichan .unread-mark-read {\n background-color: rgba(214,218,240,0.5);\n}\n\n/* Thread Watcher */\n:root.burichan .replies-quoting-you > a, :root.burichan #watcher-link.replies-quoting-you, :root.burichan .last-page > a > .watcher-page {\n color: #F00;\n}\n\n/* Watcher Favicon */\n:root.burichan .watch-thread-link\n{\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(0,0,0)\' 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}\n/* General */\n:root.tomorrow .dialog {\n background-color: #282A2E;\n border-color: #111;\n}\n\n/* 4chan style fixes */\n:root.tomorrow #arc-list span.quote {\n color: #B5BD68;\n}\n:root.tomorrow.highlight-you .quotesYou$site$highlightable$reply {\n border-left: 3px solid rgba(145, 182, 214, .8) !important;\n}\n:root.tomorrow.highlight-own .yourPost$site$highlightable$reply {\n border-left: 3px dashed rgba(145, 182, 214, .8) !important;\n}\n\n/* Header */\n:root.tomorrow #header-bar.dialog {\n background-color: rgba(40,42,46,0.9);\n}\n:root.tomorrow:not(.fixed) #header-bar, :root.tomorrow #notifications {\n font-size: 9pt;\n}\n:root.tomorrow #header-bar, :root.tomorrow #notifications {\n color: #C5C8C6;\n}\n:root.tomorrow #header-bar a, :root.tomorrow #notifications a {\n color: #81A2BE;\n}\n:root.tomorrow.shortcut-icons .native-settings {\n background-image: url(\'//s.4cdn.org/image/favicon-ws.ico\');\n}\n\n/* Settings */\n:root.tomorrow #fourchanx-settings fieldset, :root.tomorrow .section-main div::before {\n border-color: #111;\n}\n:root.tomorrow .suboption-list > div:last-of-type {\n background-color: #282A2E;\n}\n\n/* Catalog */\n:root.tomorrow.catalog-hover-expand .catalog-container:hover > .post {\n background-color: #282A2E;\n}\n:root.tomorrow.werkTyme .catalog-thread:not(:hover),\n:root.tomorrow.werkTyme:not(.catalog-hover-expand) .catalog-thread,\n:root.tomorrow.catalog-hover-expand .catalog-container:hover > .post,\n:root.tomorrow.catalog-hover-expand .catalog-container:hover .catalog-reply {\n border-color: #111;\n}\n\n/* Quote */\n:root.tomorrow .backlink.deadlink {\n color: #81A2BE !important;\n}\n:root.tomorrow .inline {\n border-color: #111;\n background-color: rgba(0, 0, 0, .14);\n}\n\n/* Fappe and Werk Tyme */\n:root.tomorrow .indicator {\n color: #282A2E;\n}\n\n/* Highlighting */\n:root.tomorrow .qphl {\n outline: 2px solid rgba(145, 182, 214, .8);\n}\n:root.tomorrow.highlight-you .quotesYou$site$highlightable$op,\n:root.tomorrow.highlight-you .quotesYou$site$highlightable$reply {\n border-left: 3px solid rgba(145, 182, 214, .8);\n}\n:root.tomorrow.highlight-own .yourPost$site$highlightable$op,\n:root.tomorrow.highlight-own .yourPost$site$highlightable$reply {\n border-left: 3px dashed rgba(145, 182, 214, .8);\n}\n:root.tomorrow .filter-highlight$site$highlightable$op,\n:root.tomorrow .filter-highlight$site$highlightable$reply {\n box-shadow: inset 5px 0 rgba(145, 182, 214, .5);\n}\n:root.tomorrow.highlight-own .yourPost > $site$sideArrows,\n:root.tomorrow.highlight-you .quotesYou > $site$sideArrows,\n:root.tomorrow .filter-highlight > $site$sideArrows {\n color: rgb(155, 185, 210);\n}\n:root.tomorrow .catalog-thread.filter-highlight .catalog-thumb,\n:root.tomorrow.werkTyme .catalog-thread.filter-highlight:not(:hover),\n:root.tomorrow.werkTyme:not(.catalog-hover-expand) .catalog-thread.filter-highlight,\n:root.tomorrow.werkTyme.catalog-hover-expand .catalog-thread.filter-highlight > .catalog-container:hover > .catalog-post {\n box-shadow: 0 0 3px 3px rgba(64, 192, 255, .7);\n}\n:root.tomorrow .catalog-thread.watched .catalog-thumb,\n:root.tomorrow.werkTyme .catalog-thread.watched:not(:hover),\n:root.tomorrow.werkTyme:not(.catalog-hover-expand) .catalog-thread.watched,\n:root.tomorrow.werkTyme.catalog-hover-expand .catalog-thread.watched > .catalog-container:hover > .catalog-post {\n border: 2px solid rgb(64, 192, 255);\n}\n\n\n/* QR */\n.tomorrow #dump-list::-webkit-scrollbar-thumb {\n background-color: #282A2E;\n border-color: #111;\n}\n:root.tomorrow .qr-preview {\n background-color: rgba(255, 255, 255, .15);\n}\n:root.tomorrow #qr .field {\n background-color: rgb(26, 27, 29);\n color: rgb(197,200,198);\n border-color: rgb(40, 41, 42);\n}\n:root.tomorrow #qr .field:focus,\n:root.tomorrow #qr .field.focus {\n border-color: rgb(129, 162, 190) !important;\n background-color: rgb(30,32,36);\n}\n:root.tomorrow .persona button {\n background: linear-gradient(to bottom, #2E3035, #222427) no-repeat;\n color: rgb(197,200,198);\n border-color: rgb(40, 41, 42);\n outline: none;\n}\n:root.tomorrow .persona button::-moz-focus-inner {\n border: none;\n}\n:root.tomorrow .persona button:focus {\n border-color: rgb(129, 162, 190);\n}\n:root.tomorrow #qr.sjis-preview #sjis-toggle,\n:root.tomorrow #qr.tex-preview #tex-preview-button {\n background: rgb(26, 27, 29);\n}\n:root.tomorrow #qr select,\n:root.tomorrow #file-n-submit > input,\n:root.tomorrow #qr-draw-button {\n border-color: rgb(40, 41, 42);\n}\n:root.tomorrow #qr-filename {\n color: rgb(197,200,198);\n}\n:root.tomorrow .qr-link {\n border-color: rgb(25, 27, 31) rgb(25, 27, 31) rgb(10, 12, 16);\n background: linear-gradient(#37393D, #282A2E) repeat scroll 0% 0% transparent;\n}\n:root.tomorrow .qr-link:hover {\n background: #282A2E;\n}\n\n/* Menu */\n:root.tomorrow #menu {\n color: #C5C8C6;\n}\n:root.tomorrow .entry {\n font-size: 10pt;\n}\n:root.tomorrow .focused.entry {\n background: rgba(0, 0, 0, .33);\n}\n\n/* Unread */\n:root.tomorrow .unread-line {\n border-color: rgb(197, 200, 198);\n}\n:root.tomorrow .unread-mark-read {\n background-color: rgba(40,42,46,0.5);\n}\n\n/* Thread Watcher */\n:root.tomorrow .replies-quoting-you > a, :root.tomorrow #watcher-link.replies-quoting-you, :root.tomorrow .last-page > a > .watcher-page {\n color: #F00 !important;\n}\n\n/* Watcher Favicon */\n:root.tomorrow .watch-thread-link\n{\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(197,200,198)\' 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}\n/* General */\n:root.photon .dialog {\n background-color: #DDD;\n border-color: #CCC;\n}\n:root.photon .field:focus,\n:root.photon .field.focus {\n border-color: #EA8;\n}\n\n/* 4chan style fixes */\n:root.photon #arc-list tr:nth-of-type(odd) span.quote {\n color: #C0E17A;\n}\n:root.photon.highlight-you .quotesYou$site$highlightable$reply {\n border-left: 3px solid rgba(221, 0, 0, .8) !important;\n}\n:root.photon.highlight-own .yourPost$site$highlightable$reply {\n border-left: 3px dashed rgba(221, 0, 0, .8) !important;\n}\n\n/* Header */\n:root.photon #header-bar.dialog {\n background-color: rgba(221,221,221,0.98);\n}\n:root.photon:not(.fixed) #header-bar, :root.photon #notifications {\n font-size: 9pt;\n}\n:root.photon #header-bar, :root.photon #notifications {\n color: #333;\n}\n:root.photon #header-bar a, :root.photon #notifications a {\n color: #FF6600;\n}\n\n/* Settings */\n:root.photon #fourchanx-settings fieldset, :root.photon .section-main div::before {\n border-color: #CCC;\n}\n:root.photon .suboption-list > div:last-of-type {\n background-color: #DDD;\n}\n\n/* Catalog */\n:root.photon.catalog-hover-expand .catalog-container:hover > .post {\n background-color: #DDD;\n}\n:root.photon.werkTyme .catalog-thread:not(:hover),\n:root.photon.werkTyme:not(.catalog-hover-expand) .catalog-thread,\n:root.photon.catalog-hover-expand .catalog-container:hover > .post,\n:root.photon.catalog-hover-expand .catalog-container:hover .catalog-reply {\n border-color: #CCC;\n}\n\n/* Quote */\n:root.photon .backlink.deadlink {\n color: #F60 !important;\n}\n:root.photon .inline {\n border-color: #CCC;\n background-color: rgba(255, 255, 255, .14);\n}\n\n/* Fappe and Werk Tyme */\n:root.photon .indicator {\n color: #DDD;\n}\n\n/* QR */\n.photon #dump-list::-webkit-scrollbar-thumb {\n background-color: #DDD;\n border-color: #CCC;\n}\n:root.photon .qr-preview {\n background-color: rgba(0, 0, 0, .15);\n}\n:root.photon .qr-link {\n border-color: rgb(206, 206, 206) rgb(206, 206, 206) rgb(191, 191, 191);\n background: linear-gradient(#ECECEC, #DDD) repeat scroll 0% 0% transparent;\n}\n:root.photon .qr-link:hover {\n background: #DDDDDD;\n}\n\n/* Menu */\n:root.photon #menu {\n color: #333;\n}\n:root.photon .entry {\n font-size: 10pt;\n}\n:root.photon .focused.entry {\n background: rgba(255, 255, 255, .33);\n}\n\n/* Unread */\n:root.photon .unread-mark-read {\n background-color: rgba(221,221,221,0.5);\n}\n\n/* Thread Watcher */\n:root.photon .replies-quoting-you > a, :root.photon #watcher-link.replies-quoting-you, :root.photon .last-page > a > .watcher-page {\n color: #00F !important;\n}\n\n/* Watcher Favicon */\n:root.photon .watch-thread-link\n{\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(51,51,51)\' 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}\n/* General */\n:root.spooky .dialog {\n background-color: #171526;\n border-color: #707070;\n}\n:root.spooky .field:focus,\n:root.spooky .field.focus {\n border-color: #98E;\n}\n\n/* 4chan style fixes */\n:root.spooky #arc-list span.quote {\n color: #634C2C;\n}\n:root.spooky.highlight-you .quotesYou$site$highlightable$reply {\n border-left: 3px solid rgba(145, 182, 214, .8) !important;\n}\n:root.spooky.highlight-own .yourPost$site$highlightable$reply {\n border-left: 3px dashed rgba(145, 182, 214, .8) !important;\n}\n\n/* Header */\n:root.spooky #header-bar.dialog {\n background-color: rgba(23,21,38,0.98);\n}\n:root.spooky:not(.fixed) #header-bar, :root.spooky #notifications {\n font-size: 9pt;\n}\n:root.spooky #header-bar, :root.spooky #notifications {\n color: #C49756;\n}\n:root.spooky #board-list a, :root.spooky #shortcuts a {\n color: #FE9600;\n}\n:root.spooky.shortcut-icons .native-settings {\n background-image: url(\'//s.4cdn.org/image/favicon-ws.ico\');\n}\n\n/* Settings */\n:root.spooky #fourchanx-settings fieldset, :root.spooky .section-main div::before {\n border-color: #707070;\n}\n:root.spooky .suboption-list > div:last-of-type {\n background-color: #171526;\n}\n\n/* Catalog */\n:root.spooky.catalog-hover-expand .catalog-container:hover > .post {\n background-color: #171526;\n}\n:root.spooky.werkTyme .catalog-thread:not(:hover),\n:root.spooky.werkTyme:not(.catalog-hover-expand) .catalog-thread,\n:root.spooky.catalog-hover-expand .catalog-container:hover > .post,\n:root.spooky.catalog-hover-expand .catalog-container:hover .catalog-reply {\n border-color: #707070;\n}\n\n/* Quote */\n:root.spooky .backlink.deadlink {\n color: #FE9600 !important;\n}\n:root.spooky .inline {\n border-color: #707070;\n background-color: rgba(255, 255, 255, .14);\n}\n\n/* Fappe and Werk Tyme */\n:root.spooky .indicator {\n color: #171526;\n}\n\n/* Highlighting */\n:root.spooky .qphl {\n outline: 2px solid rgba(145, 182, 214, .8);\n}\n:root.spooky.highlight-you .quotesYou$site$highlightable$op,\n:root.spooky.highlight-you .quotesYou$site$highlightable$reply {\n border-left: 3px solid rgba(145, 182, 214, .8);\n}\n:root.spooky.highlight-own .yourPost$site$highlightable$op,\n:root.spooky.highlight-own .yourPost$site$highlightable$reply {\n border-left: 3px dashed rgba(145, 182, 214, .8);\n}\n:root.spooky .filter-highlight$site$highlightable$op,\n:root.spooky .filter-highlight$site$highlightable$reply {\n box-shadow: inset 5px 0 rgba(145, 182, 214, .5);\n}\n:root.spooky.highlight-own .yourPost > $site$sideArrows,\n:root.spooky.highlight-you .quotesYou > $site$sideArrows,\n:root.spooky .filter-highlight > $site$sideArrows {\n color: rgb(155, 185, 210);\n}\n\n/* QR */\n.spooky #dump-list::-webkit-scrollbar-thumb {\n background-color: #171526;\n border-color: #707070;\n}\n:root.spooky .qr-preview {\n background-color: rgba(0, 0, 0, .15);\n}\n:root.spooky #qr .field {\n background-color: rgb(26, 27, 29);\n color: rgb(197,200,198);\n border-color: rgb(40, 41, 42);\n}\n:root.spooky #qr .field:focus,\n:root.spooky #qr .field.focus {\n border-color: rgb(254, 150, 0) !important;\n background-color: rgb(30,32,36);\n}\n:root.spooky .persona button {\n background: linear-gradient(to bottom, #2E3035, #222427) no-repeat;\n color: rgb(197,200,198);\n border-color: rgb(40, 41, 42);\n outline: none;\n}\n:root.spooky .persona button::-moz-focus-inner {\n border: none;\n}\n:root.spooky .persona button:focus {\n border-color: rgb(254, 150, 0);\n}\n:root.spooky #qr.sjis-preview #sjis-toggle,\n:root.spooky #qr.tex-preview #tex-preview-button {\n background: rgb(26, 27, 29);\n}\n:root.spooky #qr select,\n:root.spooky #file-n-submit > input,\n:root.spooky #qr-draw-button {\n border-color: rgb(40, 41, 42);\n}\n:root.spooky #qr-filename {\n color: rgb(197,200,198);\n}\n\n:root.spooky .qr-link {\n border-color: rgb(8, 6, 23) rgb(8, 6, 23) rgb(0, 0, 8);\n background: linear-gradient(#262435, #171526) repeat scroll 0% 0% transparent;\n}\n:root.spooky .qr-link:hover {\n background: #1A1829;\n}\n\n\n/* Menu */\n:root.spooky #menu {\n color: #FE9600;\n}\n:root.spooky .entry {\n font-size: 10pt;\n}\n:root.spooky .focused.entry {\n background: rgba(255, 255, 255, .33);\n}\n\n/* Unread */\n:root.spooky .unread-line {\n border-color: rgb(197, 200, 198);\n visibility: visible;\n opacity: 1;\n}\n:root.spooky .unread-mark-read {\n background-color: rgba(23,21,38,0.5);\n}\n\n/* Thread Watcher */\n:root.spooky .replies-quoting-you > a, :root.spooky #watcher-link.replies-quoting-you, :root.spooky .last-page > a > .watcher-page {\n color: #F00 !important;\n}\n\n/* Watcher Favicon */\n:root.spooky .watch-thread-link\n{\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(254,150,0)\' 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}\n'+(be=[{
|
||
name:"Audio",data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAitJREFUOE9jYCAWKJWwavr0KyXWb/FIbDtUFFyzJx6nVofE2Xo5nXsj0rqPNSR0nVkR2Hjmgmfd+U9Otdf+m5Vf/6+SfeU/R9ChVVgNYDRtlfJuuPA/rPfe/4QpD/6nznj0P27Kw/9unff/69Xf+69c/+C/SO7N/0z+OAxgMmmRCe++/r9i3ev/KWvf/vdY8PK/bt/9/wrNV3/IN5y/IVt1YqNg4pGTTP4HsbuA2bhZ2qvpyn+xjIObxAp3VwqlrgngLFyryVy5nhPmZJHANS2cwYexG8BmVC/pWn3hP4NZlzWuQDJI3dIiFnUUuwEsQAOcq87jNcC7fHeLUtJxHF4AGmBWeAavAWH1+1rUUk7giAWjOknllON4DXAs2NEiG4/DBQxAF/CFHfrPYI4jDFSLuJVjNrUJhB/B7gIGo1pJRt99GAZYJK7wLJ1z7Xzl4vu/7aqv/GRBj0bjqAX2qb0nJ7mXH17C4HcUxQA+hymWtSue/C5a9up/9Ozn/7Vr7v1nRY7GqMb91T3b3v6vWvPmf/S0p/9ZQk+DDLCBRSOz06Jqk+o7/21nvfqvsebDf7kZL/5zBaxphkezd+OFn7HzXvz3Wvjmv9a8N//5Ek//ZTBpVYUrMG2X5wjcdl68+uI/wa5Lr3hSNjczGFeywOVZ/bbcVGp//F9izfv/Ql03f3P4LC/HSEQquYwMFnUCDJ7dzBhyjGZNQpye89M5gpfnMvtNUyE2h4PUAQBovvT7lyNljwAAAABJRU5ErkJggg=="},{name:"Bitchute",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAadQTFRFAAAAwzw8xDs7cY6O0iws0ysrtF9f0Sws1CwsyzU1zTIy1igoyzQ01icnY7i4t0hI0S4u0ysr1Soq1ikp1ikp1Soq0ysr0S4uu0VFzjEx1Csr1ygo2Ccn2Ccn1ygo1CoqzjExzjAw1Skp2Ccn2Ccn1ikp0TAwxzY21Soq1SoqyzQ00iws1ygo1ygo0yws1Soq1Skp1igo1igo1igo1igo1igo1igo1Coq1Soq0C0t1ygo1ygo0S4unV5e1Csr1ygo1ygo1CsruUdHxzg41Skp1ygo1CsryTU10C4u1igo1ycn1ygo0i0txjo60S0t1ikp1ygo1ikp1Cws1Coq1Coq0yws0S0tyzQ00iws1Soq0ysr0i0txDs72Ccn2CUl2CYm2CQk3EFB2S8v2zw82jY24FZW3D0931FR3EBA3UND8LS04FVV7qys4V9f4WBg+erq766u9t7e7qqq2Ckp54KC9+Pj6pSU+Ojo5XNz9NHR6YqK8bu765ub5G5u9M3N6ImJ88vL5XV165eX3UVF6pWV3UhI2Soq2jU12Coq2jQ02Cgo2Sws////FaxLuAAAAF10Uk5TAAAAAAAAAAAAAAAAAAAAASJnoLy9oWolAhBz1vr72XgTGKf8/a4cCpuiDVvz9mS6xOvy9vzg6aGsPOToRAFv9fh2Awm07XgIMd765UEDOsfemVhhY00nBommbCkEI8horgAAAL5JREFUKBUFwbFKA0EUQNF7387sMq4EmzRpLSSdIBYKFv6Af2prnSYkRT4gWFgkCBJQ0EIFdcZzBCeqqh4qdk7VW2ChPusw02sAYKU7z7wEAAA2piQKFbrWSHazc1J0XWs5pdxPDykcVX+7Y9UxUsSo+s7PibqPFBRV/C5qi4i/UkrJrc7L47Bt4ZWnUaMCAE9GSrtKBQD2fR+bnAEAeOn7dUTOwApe35bDsPz0zsniQlV98IN0tJ3f6P0XAMA/kxou7OXCdnoAAAAASUVORK5CYII="
|
||
},{name:"Clyp",data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAwUExURTSY22ey5E2l4KbS75rM7Y3F64C/6f///8zl9nS45r/f9PL5/UGe3bPY8Vqr4v///wNjrzUAAAABYktHRA8YugDZAAAAB3RJTUUH4AINEi85AIH95AAAAE9JREFUCNdjYMAGGBWgDGYHCM2a3hkAZmi0dzSBaKaO9o5moCqmLiCjYzNQyw4QowIodQzI6E0AKcpo72gE6+Jyb1kAMehUA9RktgdYbQYAjGIVNGGXBJkAAAAASUVORK5CYII="},{name:"Dailymotion",data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAnUExURQBk3ff6/trp+kKO5wZt3xx54q7P9Ozz/IS17zOG5WKh653E8sbc9/GbbcoAAABZSURBVAjXY2BAASyhDhAGc9oECMOjyAAiESEEYrBYpLWBGcwHxcvBjDDxHelghpF0yDQwY3kVgweEUeEQDWbMEepqAjO8FMsLIeYsU8o+BrbCdWboTAe4AwALXxWGjW41FwAAAABJRU5ErkJggg=="},{name:"Gfycat",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAjVBMVEWn3gCo3gSr3w2t4BSu4Bav4Ri35C+45DK45DO55DXA50rA50vB50zC6E/D6FTF6VjG6VvL62vN7G/P7XbQ7XfW74vY8JDa8ZTe8qDe8qLf86Pi9Kzj9K7k9LHp9sDp98Lq98Ps+Mr0++L5/O75/fD6/fH6/fL6/fP7/fT7/fb8/ff8/vj8/vn+/v7///91X4cfAAAAcklEQVR42o3M2xKBUACF4aVQckrIuRJK6H//x2sme4/MuPDfre9i6c/Cc3U5Dj87BuAxsXvGu6JvIIXEHRWwNHCHQNrCzkAFkbSBg4EM8i+Yw7PXBa3zRfuxVyf/Bis7nKwGKAcWxgC8prI5Sc315OlnDfzpDar2S9/oAAAAAElFTkSuQmCC"},{name:"Gist",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABblBMVEXc3NykpKTW1tbb29ugoKCdnZ0AAAACAgIEDRcKCgoMDAwODg4QIzYRDAoTExMUDwwVAg0WICsaEw8aGhoiCBklGxUmERwwKCQ7LSU7Ozs8LSZFLyNINi1JNyxJNy1KSklMOi5VR1FXV1daQTRkZGRseYZwU0F4eHh7dnR8bWV/YE6IdGiKcGCKkJaNgYeNjY2RdGOScWCUcWCZmZmhoaGkpKSoqKirfmaurq6xsbG1tbW6urq+vr7AbmzBb23CwsLGxsbHx8fHyMjJycnJysrMzMzOiYbPi4fQ0NDRoYbT09PU1NTW1tbY2NjZqIzZ2dnb29vd3d3f39/i4uLktZrk5OTl5eXm5ubn5+fo6Ojq6urs7OzttKLu7u7wuqbw8PDx8fHz8/P4+Pj5+fn7uZj8vpz9ya79ybD/tZf/upr/wZ//w6H/xKH/xaL/xrH/yqj/y7T/zqv/z7D/07D/17n/2Lv/2Lz/3L//38n/4Mk3Q/ZuAAAABnRSTlMSFcbGzc5MNKFvAAAA1klEQVQoz2NgYPZHAswMDEwRSclwkBTBxOARn4gE4j0YXBOiJNUDg7y8Ar1UlOITXBkcY73Z2Li42dg42dn4wmIdGeyjQ7nZoEA4PNqewSZKlw0O9KJsGKwjBdl4ZeWkJGQUhNjEIq0ZrMI5+D0ri7Jz8itCRAXCrRgsQ3mUy+xicrPSbfO0REItGSyCVaVL3ONSU9LcCtQUgy0YzIJ85M1LizMzCsv9xF2CzBhMAwN99TV1DI0MtDWcAgNNGUycA5CAswkDi5kDwrMOZiwMjKzGSICVEQDhZj0UQV7PewAAAABJRU5ErkJggg=="},{name:"Image",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAs5JREFUOE+lk/tvi1EYx98/xT8gW4REIpGFMEQWl2FiM9ZMZhm2xRAyOsmujFFmdFRHu0tWm87UypxStr69zPauN5e5rHVp3IYhbOvHy+wHEQlxkm+ek+d8nm9OznkeSfrfldmgJC7QyUlTymsJTfuTZ25z4HdWYwyLreYhtpgekGPw0+kKvo1Eo+IXRSIiEhkWZuc9tqnsJD9EqTUopCxjSGTpB0iueczSo1HyW8cpsExQ1DbxI2pt45j9cXpexul4FEd79RnZphAa/SD7WvuFtO6UItbU9LC+YQxNI2w0wwYT5LRAdhOU3oBTIXC9gXP3oUSGgz2vST3gYHejR0jptT1C332f8yrUEYHrz8CgxDnpm6DKCUfc0KnmXa/AEVPPwnDcD0cvetA2uYRk67Ive/lpjO7YBO1PPuF8Df3vwf4cbNE4tqdw7YVq8HYyHx6FvhE1hkMEg8HDUqvFkjT4aIjMqkqyqkswDSrcfBfH+Q561YLAZ/B+BLda6FXlU/cPv0AoEPhuoP1h4Av7Wbh9E/Py15NWWUjeSR3nZDfeN+N0DY9hG/7K1eGP3P0S5/EYRFUF/IOTBrUXHPm9fT6mr1xEwupkZqxbzLyiDJYUZ5NSnkdqdSHpxyrYdFpPgdmAsdfJwPMI/Yr65bf7tZLGGBQ7DNdJWFtIYvoOZmbuZE7OXpIKKli86zAr9p9gTVktWTVnKTI2U95uRWe3U2IJUDbVB5p6hVm5x5m9Vc/cnedZUNzC8lILaQesZBy6hEZ3maKzgvJWFzVWD9XtXvVGQbSWASFtMATVRlJIKbOTWtlJXaeXepuPM1f6MNp9GLt8mLvvYLmp0OhQ2Fwvk6m7xaqDTvY0eYWUVtcnllXfYlGpnfklVuraHHg8HjxuN+6fktUHlWWZPaZeUo/ILK0UKttBcbNbSB9GP0yLxWJJUxoZGUn80zD9C/vXQ/4NHY10h3M1zmQAAAAASUVORK5CYII="
|
||
},{name:"Installgentoo",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABcVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB3dIYAAAAAAAAAAAAbGh4BBAcCBgoBBgoCBwsCCQ/QzucCCA7MyuXZ1eUBBQmTh8fo5/i9svIAAADh3vQAAAACCA0CCQ8CCQ4DDBQbGCUDChDr6vgAAAAAAAAREBIDCxK6tdfe2fTv7/cDCxIDDBQEDRUHDhgMJjXk4PZdXWdLUFoUNEYOKDgSMUMRLUBneI4eTGj08/QmW3onW3rTzvfOx/giU3IiVHMkWHdEaYJobHv3+PokWHpua6TNy9xZgZ+1quz8/foQKj0XPFInWn0nW38tZ4o6fqg8gq48grA9hrU/i7pAhrNAiLdBjLtEjr1FksNIjr5Il8pImMtKWnNqhL97odKFqti5q/q5rPq60+nCt/vLw/vPx/jV0vHY0/rc1/rg2/vh3fzn4fzu6/vx8vf19Pv19Pz49/v5+Pv8/Pv8/fr9/vv+/frziVtUAAAAT3RSTlMABQYHCAoNDhARGRobL0ZOV1xdXV5fYGBmZnB0eX2MjZSaoaGio6mqqqustLq7zubo6Ojo6evt7u/x8fLy9/f4+Pj5+vr6+vr6+/39/v7+XKgUSwAAAMhJREFUKM9jYGDg4OZmZgABKINT1dBAhBHIYFMxMBIDisjbhoZbCTExsCu5hoeY8DEwcOkEx8fY6MqpucTGB0izglVEplcU5/gmRYWBVQDNMK+s0hN3SvMyBpsBNJxXw0NfwTEjVQZqHQMHj5RfWW5mliSEC7TPzK6yJD/bXZQRzGdXcisqLy309okA2Q4Eis4peQWmstqBCdGW/CABraC45ERBBs3A6Fh/AbAKTwsHa34QZW8NVsGuLqwswQSjQICTmYMFQaEDAAF8JHLfKGswAAAAAElFTkSuQmCC"},{name:"Liveleak",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAlNJREFUGBkFwU2LVmUYAODrPu8Z5x1xSpRBXQyFoLsBE+wfiO5atJOgnf9DUPwFgtGinUgEaQsRhHYuMtpEiEWuG5iNjuOcj+c8z911xXcXL/68c3Dw1fzhg0QgEQAAEYGUKXFie9vxlSs/xk/rdavjGEkmkWSih65z4osv9GfOiK6LzEyZ2uGh4dUrmzs72ddlUUhkoiMr4PT167589Mh6c1N0nSRlqrX67dat+PDyZXRT19m5edPnt28rGFHxMcJ6d9fprS1/37tneP3aemPD1uamUydPOru3p5DdGOH0tWsu3LhhxIQJM2qEpRT/Pn3q/du3AhARSmvGTH0lplKMrVkiYpVpQaJlighzhDkzhmEA0fcWoqAfyaFW4zTlgCABxlrNmY4ylUzLsiREprFWc0T2M+ZSjKWY0AEaltZUjJixZJIpuk5pTWlNP2BYFvOyKJkCAKU1tTXHrZlqVWolUxdhxsfVSj9FmJfFMM9GdICGGa01HyMstYpMIFPJVNDPmYZSTOPoOEKHzNRlKpmWWh1j6TpLa2SKTKVWU6Z+Qolwdm/P9QcPZKa2LH69e9eIMs+WCL/cv2/98CGZPrt61am+V9APq1X89eyZ/968obVYaiXT4dGREgG+vnPHeHgYMsH2+fP+efEihtVKv7SWw/6+9/v7KYLMhIywTJPamvOXLomukyRsrNf+ePzYkpl9dJ3SWgSCSCQCfz5/7pMLF2yfO6eLiAQcHRz4/cmT+HR7O+Ob3d0fNt69+7a2BiICQCJbA0EgE5lpvbXl1OXL3/8Pfax4+6SjSukAAAAASUVORK5CYII="},{
|
||
name:"Pastebin",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB1FBMVEUAAAAAAAAAAABWYWwAAABbY3BbYm5dZnFdZXJeZnMEBAQHCAhYYGpdZnFdZnBgaHIlJyomKCooKi09QkdESU5eZGtdYmhdYmleY2lrcXdqb3Rqb3Rqb3SSmJ+SlJeWmJutr7GtrrCWm6ChpKhbW1tmZmZvb290dHR3d3d4eHh5eXl6enp8fHx+gIJ/f3+CgoKDg4OEhISFhYWHh4eKioqKjI2Li4uMjIyOjo6Pj4+QkJCRkZGSkpKUlJSVl5mWlpaYmZqZm52ampqbm5ucnJydnZ2enp6fn5+hoaGioqKkpKSkpaalpaWmp6mmp6qnqauoqKioqquoqq2qqqqrrK2srKysra6srrCsrrGurq6vr6+wsLCxsbGysrKztLa0tLS1t7m2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr7AwMDAwsTBwcHExcfFxcXFxsnGxsbHx8fIyMjJycnMzMzNzc3Ozs7O0NLPz8/Q0NDR0dHR09XT09PV1dXV1dbV1tfV19rW1tbX19fX19jY2tzZ2dnZ2tva2tra3N3a3N7c3Nze3t7f39/f4OHg4ODi4uLl5+jm5ubs7Ozs7e3u7u7v7+/v8PDw8PDx8fHy8vLz8/P29vYSoLMZAAAAJHRSTlMABAUGCwsNHCAiLzMzMzZEYGJwgIuOnJycnqmqq9bc3+/w8fkZ0N/uAAAA/klEQVQoU2NgYGDl5YMDdgYGBmZZ3964CYFtIR3e9Q7K/AwMHI55KfaFmcHWMy3K3MwlGRg4wz0zdYpcorRbNbL0LaWAAp3ts2umV8wo6MupTauQBgqUG03VL7W3sfZSb1erAgm02M+yzYrVCXUy6zapAQlUx/dEdyX3J3ZHVUYVywAF8o2rDNN1Go2jzGLMokAC2QbuSc42mXmaOXop9iAtCXrJ5qXWjT59Abl2ESJAAX/tSIMMiyrrqQ3T6uS5gQK6kSqpqkUermGTexQFmYACflqR+hlWZSamzQpCLEDPsSmVVDT1TJw0JUhOAMRnYOARFRMTE5cQF+ZiBPIAII5B3EVG0b4AAAAASUVORK5CYII="
|
||
},{name:"Peertube",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABIFBMVEUhHyAAAABzPBnxaA3CWBEnJSYbGRptbW16enpzc3PTayWhb04hHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyApIh+0UhMfHiBWMhvsZg7zaQ0hHyAhHyAXHCHzaQ3xaA3xaA3xaA3xaA0hHyAhHyDxaA3xaA3xaA3xaA3xaA3xaA0oJickIiMdGxwUEhPxaA3xaA3xaA1sbGxwcHB3d3eFhYXxaA3xaA3xaA1zc3Nzc3Nzc3Nzc3Nzc3PxaA3xaA3xaA1zc3Nzc3NtdHjxaA3xaA1yc3STcFnvaA/yaAxzc3N4c2/FbDFzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3MhHyDxaA1zc3MAAAAfljyVAAAAXHRSTlMAAAAAAAAAAAAAAAAZkjMBHOLXYArj8p0u2VsJ1XaGL/OhKyXc1WEN2gwk2/SjKgEYiS4B/tYFGosqAdleAxzj12ML9Z8s850rJWbYeYMs1F8Koiri1V0MGZY0AYbIBFIAAAABYktHRAH/Ai3eAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4wYXFBUVX81QWQAAAKxJREFUGNNVz9UWgkAQANDBtdbu7lZsxe7ubpH//wxBPKDzNvdMAmi0Oj0QQgAYjCazBX7BStvsDqHoAzTtdLklf+Dx+vwICRAIhsKRaCyOvpAwJ6Up8pXOZHOIAFm+UCzJEQuvMhWrIFBUa/WGkodmq40Ad7q9/kDFwnA05lpYYCbT2ZykFvxQDhhmuVpvcvxaHra7vfp72KflcMSYEOB0vlyx+By+3R9PMSfe+P0enM1454kAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDYtMjRUMDM6MjE6MjEtMDc6MDDse6MAAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTA2LTI0VDAzOjIxOjIxLTA3OjAwnSYbvAAAAABJRU5ErkJggg=="
|
||
},{name:"Soundcloud",data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABsklEQVQ4y5WTy2pUQRCGv2rbzDjJeAlIBmOyipGIIJqFEBDElwh4yULGeRFXPoEIBl/AvQ/gC2RnxCAoxijiwks852S6+3dxzslcHJCpTXVX11/Xv0097gLPgVNMJxnQNfX4zsqleWbnpoMf/oa9d988MM9MC/rp+E0a+A0dsVobMNMCOO8B6McRoABJI+A6gJmN3D2A8jgEBCEkSEMBrcrsDAzDWWn3AjgKFaDMmgRqniGFgsaDp1jrLOngDf1XT1D+A1dFc4MKAkkiCVKjjVu7g9+4Rzx4i1u6hjXbuMWr0O5QPNvCu7IaCZwEKQukLGDrm5x8uI0tr6MkiGlkiv7yLfzN+6S5i6QsIMABkEfcxhbWWYMkVAOjxvYAjc3HNHrbKI9VBQBFwF25XQKSBjqIf1YBuAurEMrczgDygD6/x2LCpFLXLUyQ+PoldphhBhYfIX09XU1+Flaukz7uYqs3SHs7cG4BmTsmkBUF9mmXEwa28BNLPaQPLepuNcbGSWQquQC2/Kdcox1FUGkcB0ykck1nA2+wTzMs8stGnP4rbWGw74EuS/GFQWfK7/wF6P4F7fzIAYkdmdEAAAAASUVORK5CYII="},{name:"Streamable",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABXFBMVEUPkPoNj/qExv0PkPoPkPoPkPoPkPoPkPoPkPoPkPoPkPoPkPoPkPoPkPoPkPoPkPoPkPoNj/oPkPoNj/oNj/qExv0PkPpruvwPkPornfoVk/opnPpnufwPkPqExv0Nj/oPkPoNj/oPkPoPkPoPkPoPkPoPkPoPkPoPkPoPkPoPkPoPkPoPkPoPkPoOj/opnPsVk/oMjvoOkPoTkfo6pPsblfo3ovva7v7////v9/5Sr/whmPry+f5htvze8P7W7P5itvyl1v0imPu84P3o9P50v/zN6P73+/8lmvs8pfs+pfsKjvr9/v9EqfsNj/oom/v8/v9nufxAp/tJq/sQkPrb7v6t2f0IjPoclvr6/f9luPwUkvrp9f7h8f5ruvy/4f4kmftpuvwxoPum1v32+/8jmfpMrPvu9/7z+f9UsPs7pPv8/f/4/P9oufwalfpDqPsMj/ounvtVsPsnm/qzfQQ9AAAALXRSTlMAAAAggMzw0IYkBPb4iAamsgZ+jPwogpDO1vTYlPoulL4KivyUCiqO1PL01i67tUAWAAAAAWJLR0Q4oAel1gAAAAd0SU1FB+MGFxMuDXVcMbIAAADdSURBVBjTY2AAAmYWVjY2dg5OBgZGJiCXi4VbFwx4ePlAAlz8unAgIAgUENJFAsJMDMw8unp6+gaGRsYmpoa6IqIMYrp6ZuYWllbW5hY2toZ64gwSurp29g6OTs4urm7uHrqSDGy6nhZeet5WPr5+/gGBelJAgSCLYL+Q0LBw3YjIKKAAu250TGxcvE1CYlJySqquNAOHrl9aukVGZla2RU6uoZ4MA6esrl9evnWBYWFRMdBaOQYGXmSHyQNdyieA4CsogjzHpyQL4SqrqIJ9y8Cgpq6hqaWtogPyPgDmvSxRxBWM9AAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOS0wNi0yNFQwMjo0NjoxMy0wNzowMCKUvXUAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTktMDYtMjRUMDI6NDY6MTMtMDc6MDBTyQXJAAAAAElFTkSuQmCC"
|
||
},{name:"Twitchtv",data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAYUExURf///2RBpWRBpWRBpWRBpWRBpWRBpf///+zQyUYAAAAGdFJOUwFdZX0lTzs4r5oAAAABYktHRAcWYYjrAAAAB3RJTUUH4AINEi42iSXRNAAAAD1JREFUCNdjYEiDAAZGGIMtjQEEUBlMCWoEGci6mGEMsxQgIy0BiB3AjLS0FAYQIw0kwABipoI1AhkBQBIAFCIXxiHgq80AAAAASUVORK5CYII="},{name:"Twitter",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAEsUExURf///1Cf21Gg3FGi31Gh3VKj4FGh3lKj4VKk4lKl41Ol5FOn51Sp6VSo6FOn5lCf21Gg3FGh3VGi31Gi31Gh3lGg3FGg3FGg3FGg3FGh3lGg3FGi31Kk4lKj4FGh3lGi31Kk4lGh3lGg3FGh3lOm5FOm5VGi31Kj4VSo6FGi31Gh3VGg3FKj4FOn51Gi31So6FWr7VOl5FGi31On51Sq6lKk4lOo51Sp6VOm5FSq61Ws7VOn51Oo51Sq61Ol5FOm5FSq61Wr7VOo51On51Sr7FWs7VSp6lGg3FGh3VOm5FWr7VSp6lKj4VOm5FSo6FSr7FWs7VWs7VWr7VSq6lOo51Om5FOo51So6FOm5VOl5FSq61Ws7VSr7FSp6lSp6VWs7lWr7VKk4lSq6v///6E3MNsAAABVdFJOUwAAAAAAAAAAAAAAAAAAAB0Ii+3xnBVTJhfsMKb+qTEp9GwBF/7lLAbo0m4pLkUTdvk2Ev3+EZnOBo/3Z8ffCRzH/D0OqPxiLnvx3UI8m9n1++GwXQZNS29BAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+ACDRIwBwy67tEAAADKSURBVBjTY2BAB4xogIGRH8IQEBQSFhEVE2eQkJQC8ZmkQ8PCI2Rk5RjkIxUUlRgZlVWioqNjYlXVGNQ14iI1tbR14qLj4+MTdJkZ9PQNosJCE0OjgPz4KEMWBiPjhPiEmKQokIJ4E1MmBmazhHg4MGdlYmCzsLSC8ROsmRkZmFht4Eps7ViADmOzd4DyHZ2YmYACTOzOLmATXd04mIBOd/eQ9owFCXh5c7KB/MLi4+vnHxAYFBzCwcYEEmBi5uLm4eHl42RmAnsSAMZBLgZiFUQ5AAAAAElFTkSuQmCC"
|
||
},{name:"Video",data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAxgDGAP8nNqN7AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gMZBjQQLEEqGwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAA5SURBVDjLY2AYaMDIwMDwn1JD/lPCZhpwL+B1wf///ykzgBhDiAoDfIYQZQAjIyP5BuDTPJqQqAQAvW0ZAMk8+EEAAAAASUVORK5CYII="},{name:"Vidlii",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACvlBMVEUCWv8HXf8AWv8AAAD///8AVP+bqP8AWv8AVO4AOqUAGkgAyf8APa0AL4QABAsASdEAVv8AUv8AUv8AVP8AWP8BWv8JXv8RYv8QYv8DW/8DXP8xdv9RiP9Af/8IXf8AKP8KXv8JXf8NYf8aaf8ATP0UZP0AVf8AT/8AT/8AVv8ATedvnPVAf/8AT/sYZvl0o/8PYf8udf8aa/8FXf8AVf8AOrRBe/Nvn/8AUv0aaPkXZ/8ATv8AKYQZYuwIXf8ca/wTZP8ASP8AED0HUNwZaf8xdPwDWv8AAAAAQMRcjvQAU/8AMZssb/Jmmf8AU/8AJXsRW+dSif8AUv8AAAAASdQtdP8ATv8AQ/8AQv8APbtKgfQud/8XZ/8TZP8FXP8AKIIcZO4wdP8AF08KU95tnv4gafhZi/Rnl/ZzofcocP8AAAAAQ8Q4efRwnvVmlvVcjvgrcfsAQsQAOK0APrwAQcUEStMLXPgDWv8AHE8APLEARdIAQ80ASeEAVf8AOJkAAAAAAAAAAAAABBMAJJIAY/9rmP+vxv90n/+buPv29/7C1P+zx/n///2Crv/7+fjs8f++z/f///3l6fX9/f/L2fj9/P5ilv9Nh/3h6f6vyf/D0vT///2lwP/Z5Pf3+P9OiP9klvr9/Puzyf+QsPX//fnW4v/k6vfv8/86ev94pfj///uRtf/y8vby9f9Fgv9EgPzt7/jj7f8mcf+eufj///x1pP/Z4fT///52pf9Uivv09fnV4v8ncf64yvj7+/6vxPX///yyyf9ynvr6+vvG1/8ocv3O2/fz9v53ofX8+/nb5v+YuPz//vy0yv8vdP3e5/fn7v/p7PX09//b5P7///6eu/9Df/zq7vjc5//I1vT//v3+/v////9+q/9Tivnn6fPy8/rW4fzI1/2qwv6YtPT8+fX39/jz9PqJrveTsvqfpuxrAAAAhXRSTlMAAAAAAAAAAAAAAAAAAAAABSlERA45nrSzP3TZ7e12Ao2LusMcrJYhFwaR/uhCwP/x5tZzBWHy+n3OvA8u17jmpwgPrOz5jAF2+3FA7PdYG8fuPQaX5jAGAV/39MCmdy/e/RGz/vj5/f/rAXj4//z13n52i5qmmFQ1lqOQaTgIBAYKEAYAKGjtAgAAAKNJREFUGBkFwT0uRGEYBtD3ZJ77uT8iGrXCAixCr7OCyRA2oCKqiUYkOgoJwhqUbMAKLEChVYhk4pxswvcWfFGVEbYtuJutqir9Ibc0uh0+V+mf5gY69yN2PzKJiTjCg8qa3uLRAJpKM9AMoL1VOi9zJ4CQ9z0jwHX+RAwAURUxAMSB/L7u35wCGlKaHrDkPGVmwhlc6FN6l1iHKxupn+djAPgHrEwa+qrzy0oAAAAASUVORK5CYII="
|
||
},{name:"Cimeo",data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAYFBMVEUAAAAIdZUKh6sLlLkLmr4LmsAMp88NrdYVW3MZj7Acstkrt9s1e5E7vN5EfI9JvdtKwuBijp5kpbl30eiDt8aG1uqRr7qTyNehxM+k4PCy3enB3OTg6Ovv9PXw+fz////L9U5WAAAAAXRSTlMAQObYZgAAAIFJREFUeNplz90OwiAMBWAQpAoyxclkP3je/y0H2AQXz0WT8100rRD6kNI9/cRroemQL3hXhoujZYj4OHoAmBvYGcBISwbWBvfXCrytnIDUQMkbsBpagMA7zhtQdyTFQAmIG7IkYniiZuh3XGsPqoOZkMOJOpAcLqUzNFGGu/57fwc1hgtp0mVSyQAAAABJRU5ErkJggg=="},{name:"Vine",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAHCUExURQAAAAC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+jwC+j////54tRLAAAACUdFJOUwAAAEK+9/e+QQIDAwEqzskfUZmUNHz2mrT++V1w+f5tCanNFUDwfEjtjAyyvg027Hki27QMBJzaHE/1+FkNsN0iZvv6bxyAlB589lQeyud0KB8PQO+ZBUrc+eXgcRG/3CoATe316Wxw/P6BAgBt+fp4IAwh0d4zM9q7Fm76qi605EMSrvfX/PRtAivF9IAJNMLxhA2KYlJ9AAAAAWJLR0SVCGB6gwAAAAd0SU1FB+ACDRI2MOJd7FgAAADrSURBVBjTLY9VWwJgGEPfiYWBha2YYHcHditgd3d3odjdivvBfgK727nYsyPiCrw03j6+fv6AaAMCgyAI1lElJBQSFh6hBxDJqOiY2Lh4SEKiIQlITmFqWrqRJkhGJrOA7Bzm5uUXsBBSVMySUpSVs6KyqrqmFmKuY30D0NjU3NLa1t6h9jvZ1Q30WGi19fb1KzAwyKFhYGSUY+MTkwpMTXNmFpibX+Di0rICWFldW9/A5tb2zu7ePtTrg0MeHePklPYzuDRw7uDF5RWvbwC32O0d7x8en55f4DHF6xv5/vHp6f/k6/vH+evuf1LAObptvSvrAAAAAElFTkSuQmCC"
|
||
},{name:"Vocaroo",
|
||
data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAw9JREFUOE9jYMABuMwYmCyTJKUCGlSnFSy02TTzeOyCiQcDViX26qVz2TAyYtWmEMwuoZ3M7V40LcB79pHkc0svpvzY8jD//87nxf+3Pyn8v/ZO8v+VNyP/2mZJumI1QCWSI8232Hjumitlfw5+qPp/9l8TCt76JP//xkdx/wsXWCzjtWFkwTCkbWFe9plPk/+ga4Txz/xt/D/hkN//gMXif21a+NbyWjIwoRiy6GDT5rP/mlFsPfyp5n/NpOj/22+0gMUXXIz/H7hC/L/bFKFbPDZMrHAD5H35OPt2J9zacDv/f3V7xv9FhwrBGubsT/1//Pjx/1GJ/mD+/nfl/1v3Ovy3KRJNQbHdOlXCvOO03/+pm1P/v3v37n90hhtYw9HPtf8Xb2v937cmHswHeWPRxYj/LvkK3igGKARwicTO07118H3V/5kbi/4vPZMJtK3s/6YH2f+Pfq1B8VbjWrdnMu5s4nAD9CNFhKwz5DTUvLl419zKvAcLtG1P84BRl/b/5M/6/6f/NPzf/qzo84yj0Uus0xUU4Zor54bm9+4OfZG02OCuoAMTb9ZkC9ull1Nvrr2Z+XvRpaRfc65H/68F+jl9svEhzyLFWoccWVc+eyTHq/twydjlKRln7jX9bNMkMJnbhoFRL1xCqmKx6/yi2fYXa/c5/e846PV/5fW0/7OPx/yfcjzop34ulxdGGvDuU8mMXaX507lBuiN6ueadmQeT/p/93vf/1O+G//sP5fw/eL3o/5JLif8zVxs+Tlir9S26UyeFQQvJGBE7FvaFZ9LfN+1y+WjbItSb3GmXvXd15v8zroH/HxgE/D+aGPx/18vi/z07PeZNPRKxe/Kh0Ae8toxscCO4zBkYXArk9C1SxJUYjBkYPPIVtbbuTftz3cz//2O9wP/75iSAXdO72/dt2HL5F6YlfBW4MiJYXMiBiW3t7azHBx+V/t89N+H/8a+1//e9K/9attDp5LQjYX8SuvVL8RoAkmxa65299Erq1FnHo0qrl7t4BddriIs4MrM3rfWcFd+pGwVSAwBZ0bKP8yrZPAAAAABJRU5ErkJggg=="
|
||
},{name:"Youtube",data:"iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAYAAABr5z2BAAABIklEQVQoz53LvUrDUBjG8bOoOammSf1IoBSvoCB4JeIqOHgBLt6AIMRBBQelWurQ2kERnMRBsBUcIp5FJSBI5oQsJVkkUHh8W0o5nhaFHvjBgef/Mq+Q46RJBMkI/vE+aOus956tnEswIZe1LV0QyJ5sE2GzgZfVMtRNIdiDpccEssdlB1mW4bvTwdvWJtRdErM7U+8S/FJykCRJX5qm+KpVce8UMNLRLbulz4iSjTAMh6Iowsd5BeNadp3nUF0VlxAEwZBotXC0Usa4ll3meZdA1iguwvf9vpvDA2wvmKgYGtSud8suDB4TyGr2PF49D/vra9jRZ1BVdknMzgwuCGSnZEObwu6sBnVTCHZiaC7BhFx2PKdxUidiAH/4lLo9Mv0DELVs9qsOHXwAAAAASUVORK5CYII="}],
|
||
"/* Link Title Favicons */\n"+be.map((({name:e,data:t})=>`.linkify.${e}::before {\n content: "";\n background: transparent url('data:image/png;base64,${t}') center left no-repeat!important;\n padding-left: 18px;\n}\n`)).join("")+"/* XXX Moved to end of stylesheet to avoid breaking whole stylesheet in Maxthon. */\n@supports (text-decoration-style: dashed) or (-moz-text-decoration-style: dashed) {\n .quotelink.forwardlink,\n .backlink.forwardlink {\n text-decoration: underline;\n -moz-text-decoration-style: dashed;\n text-decoration-style: dashed;\n border-bottom: none;\n }\n}\n"),
|
||
report:"#g-recaptcha,\n:root:not(.js-enabled) #captchaContainerAlt {\n height: auto;\n}\n#captchaContainerAlt td:nth-child(2) {\n display: table-cell !important;\n}\n\n/* Archive reports */\n#archive-report {\n padding: 3px;\n}\n#archive-report-enabled {\n vertical-align: middle;\n}\n#archive-report > label {\n display: block;\n}\n#archive-report-reason {\n display: block;\n width: 98%;\n}\n.archive-report-success {\n color: green;\n}\n.archive-report-error {\n color: red;\n}",www:"#captcha-cnt {\n height: auto;\n}\n:root:not(.js-enabled) #form {\n display: block;\n}\n#bd > div[style], #bd > div[style] > * {\n height: auto !important;\n margin: 0 !important;\n font-size: 0;\n}\n",sub:function(e){var t={site:n.SITE.selectors};return e.replace(/\$[\w\$]+/g,(function(e){for(var n=e.slice(1).split("$"),o=t,a=0;a<n.length;a++){if("object"!=typeof o)return":not(*)";o=Ve.getOwn(o,n[a])}return"string"!=typeof o?":not(*)":o}))}};var be;const Ae={init(){
|
||
if(t["Custom CSS"])return this.addStyle()},addStyle(){return this.style=Ve.addStyle(me.sub(t.usercss),"custom-css","#fourchanx-css")},rmStyle(){if(this.style)return Ve.rm(this.style),delete this.style},update(){return this.style?this.style.textContent=me.sub(t.usercss):this.addStyle()}},ve={isOPContainerThread:!0,mayLackJSON:!0,threadModTimeIgnoresSage:!0,disabledFeatures:["Resurrect Quotes","Quick Reply Personas","Quick Reply","Cooldown","Report Link","Delete Link","Edit Link","Quote Inlining","Quote Previewing","Quote Backlinks","File Info Formatting","Image Expansion","Image Expansion (Menu)","Comment Expansion","Thread Expansion","Favicon","Quote Threading","Thread Updater","Banner","Flash Features","Reply Pruning"],detect(){for(var e of u("script:not([src])",a.head)){var t;if(t=e.textContent.match(/\bvar configRoot=(".*?")/)){var n=m();try{var o=JSON.parse(t[1]);"/"===o[0]?n.root=location.origin+o:/^https?:/.test(o)&&(n.root=o)}catch(e){}return n}}return!1},awaitBoard(e){
|
||
if(Ve.id("react-ui")){const t=this.selectors=Object.create(this.selectors);return t.boardFor={index:".page-container"},t.thread='div[id^="thread_"]',Ot.mounted(e)}return e()},urls:{thread:({siteID:e,boardID:n,threadID:o},a)=>`${t.siteProperties[e]?.root||`http://${e}/`}${n}/${a?"archive/":""}res/${o}.html`,post:({postID:e})=>`#${e}`,index:({siteID:e,boardID:n})=>`${t.siteProperties[e]?.root||`http://${e}/`}${n}/`,catalog:({siteID:e,boardID:n})=>`${t.siteProperties[e]?.root||`http://${e}/`}${n}/catalog.html`,threadJSON({siteID:e,boardID:n,threadID:o},a){const i=t.siteProperties[e]?.root;return i?`${i}${n}/${a?"archive/":""}res/${o}.json`:""},archivedThreadJSON:e=>ve.urls.threadJSON(e,!0),threadsListJSON({siteID:e,boardID:n}){const o=t.siteProperties[e]?.root;return o?`${o}${n}/threads.json`:""},archiveListJSON({siteID:e,boardID:n}){const o=t.siteProperties[e]?.root;return o?`${o}${n}/archive/archive.json`:""},catalogJSON({siteID:e,boardID:n}){const o=t.siteProperties[e]?.root
|
||
;return o?`${o}${n}/catalog.json`:""},file:({siteID:e,boardID:n},o)=>`${t.siteProperties[e]?.root||`http://${e}/`}${n}/${o}`,thumb:(e,t)=>ve.urls.file(e,t)},selectors:{board:'form[name="postcontrols"]',thread:'input[name="board"] ~ div[id^="thread_"]',threadDivider:'div[id^="thread_"] > hr:last-child',summary:".omitted",postContainer:'div[id^="reply_"]:not(.hidden)',opBottom:".op",replyOriginal:'div[id^="reply_"]:not(.hidden)',infoRoot:".intro",info:{subject:".subject",name:".name",email:".email",tripcode:".trip",uniqueID:".poster_id",capcode:".capcode",flag:".flag",date:"time",nameBlock:"label",quote:'a[href*="#q"]',reply:'a[href*="/res/"]:not([href*="#"])'},icons:{isSticky:".fa-thumb-tack",isClosed:".fa-lock"},file:{text:".fileinfo",link:".fileinfo > a",thumb:"a > .post-image"},thumbLink:".file > a",multifile:".files > .file",highlightable:{op:" > .op",reply:".reply",catalog:" > .thread"},comment:".body",spoiler:".spoiler",quotelink:'a[onclick*="highlightReply("]',catalog:{
|
||
board:"#Grid",thread:".mix",thumb:".thread-image"},boardList:".boardlist",boardListBottom:".boardlist.bottom",styleSheet:"#stylesheet",psa:".blotter",nav:{prev:".pages > form > [value=Previous]",next:".pages > form > [value=Next]"}},classes:{highlight:"highlighted"},xpath:{thread:'div[starts-with(@id,"thread_")]',postContainer:'div[starts-with(@id,"reply_") or starts-with(@id,"thread_")]',replyContainer:'div[starts-with(@id,"reply_")]'},regexp:{quotelink:new RegExp("/([^/]+)/res/(\\d+)(?:\\.\\w+)?#(\\d+)$"),quotelinkHTML:/<a [^>]*\bhref="[^"]*\/([^\/]+)\/res\/(\d+)(?:\.\w+)?#(\d+)"/g},Build:{parseJSON(e,t){const n=this.parseJSON(e,t);if("deleted"===e.ext&&(delete n.file,Ve.extend(n,{files:[],fileDeleted:!0,filesDeleted:[0]})),e.extra_files){let o;for(let a=0;a<e.extra_files.length;a++){"deleted"===e.extra_files[a].ext?n.filesDeleted.push(a):(o=this.parseJSONFile(e,t),n.files.push(o))}n.files.length&&(n.file=n.files[0])}return n},
|
||
parseComment:e=>(e=e.replace(/<br\b[^<]*>/gi,"\n").replace(/<[^>]*>/g,""),Ve.unescape(e))},bgColoredEl:()=>Ve.el("div",{className:"post reply"}),isFileURL:e=>/\/src\/[^\/]+/.test(e.pathname),preParsingFixes(e){let t;if(t=Ve('a > input[name="board"]',e))return Ve.before(t.parentNode,t)},parseNodes(e,t){let n;if(t.uniqueID)return;let o="",a=t.nameBlock.nextSibling;for(;a&&3===a.nodeType;)o+=a.textContent,a=a.nextSibling;if(n=o.match(/(\s*ID:\s*)(\S+)/)){let e;t.info.normalize();let{nextSibling:o}=t.nameBlock;return o=o.splitText(n[1].length),o.splitText(n[2].length),t.uniqueID=e=Ve.el("span",{className:"poster_id"}),Ve.replace(o,e),Ve.add(e,o)}},parseDate(e){let t=Date.parse(e.getAttribute("datetime")?.trim());return isNaN(t)?(t=Date.parse(e.textContent.trim()+" UTC"),isNaN(t)?void 0:new Date(t)):new Date(t)},parseFile(e,t){let n,o;const{text:a,link:i,thumb:r}=t;if(Ve.x(`ancestor::${this.xpath.postContainer}[1]`,a)!==e.nodes.root)return!1
|
||
;if(!(o=i.nextSibling?.textContent.includes("(")?i.nextSibling:i.nextElementSibling))return!1;if(!(n=o.textContent.match(/\((.*,\s*)?([\d.]+ ?[KMG]?B).*\)/)))return!1;const s=Ve(".postfilename",a);return Ve.extend(t,{name:s?s.title||s.textContent:i.pathname.match(/[^/]*$/)[0],size:n[2],dimensions:n[0].match(/\d+x\d+/)?.[0]}),r&&Ve.extend(t,{thumbURL:/\/static\//.test(r.src)&&Ve.isImage(i.href)?i.href:r.src,isSpoiler:/^Spoiler/i.test(n[1]||"")||"Spoiler Image"===i.textContent}),!0},isThumbExpanded:e=>Ve.hasClass(e.thumb.parentNode,"expanded")||"true"===e.thumb.parentNode.dataset.expanded,isLinkified:e=>/\bnofollow\b/.test(e.rel),catalogPin:e=>e.dataset.sticky="true"},we=le("div",{class:"box-inner"},le("div",{class:"boxbar"},le("h2",null,"Trouble buying a 4chan Pass? (a message from 4chan X)",le("a",{href:"javascript:;",style:"text-decoration: none; float: right; margin-right: 4px;",title:"Close"},"×"))),le("div",{class:"boxcontent"},"Check the 4chan X wiki for ",le("a",{
|
||
href:`${e.captchaFAQ}#alternatives`,target:"_blank",rel:"noopener"},"alternative solutions"),".")),xe={init(){if(t.passMessageClosed)return;const e=Ve.el("div",{className:"box-outer top-box"},we);e.style.cssText="padding-bottom: 0;";const n=Ve("a",e);return Ve.on(n,"click",(function(){return Ve.rm(e),Ve.set("passMessageClosed",!0)})),Ve.ready((function(){let t;return(t=Ve.id("hd"))?Ve.after(t,e):Ve.prepend(a.body,e)}))}};var ye={init(){let e;if(e=location.search.match(/\bno=(\d+)/))return Oe.replace.init(),this.postID=+e[1],Ve.ready(this.ready)},ready:()=>(Ve.addStyle(me.report),t["Archive Report"]&&ye.archive(),new MutationObserver((function(){return ye.fit('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'),ye.fit("body")})).observe(a.body,{childList:!0,attributes:!0,subtree:!0}),ye.fit("body")),fit(e){let t;if(!(t=Ve(e,doc))||"hidden"===getComputedStyle(t).visibility)return;const n=t.getBoundingClientRect().bottom-doc.clientHeight+8;return n>0?window.resizeBy(0,n):void 0},
|
||
archive(){let e,t;if(!(t=Ze.report(n.BOARD.ID)).length)return;const o=Ve("form"),a=Ve.id("reportTypes"),i=Ve("h3"),r=Ve.el("fieldset",{id:"archive-report",hidden:!0},{innerHTML:'<legend><label><input id="archive-report-enabled" type="checkbox">Report illegal content to archives</label></legend>\n<label for="archive-report-reason">Details</label>\n<textarea id="archive-report-reason" disabled>Illegal content</textarea>\n<button id="archive-report-submit" hidden>Submit</button>\n'}),s=Ve("#archive-report-enabled",r),l=Ve("#archive-report-reason",r),d=Ve("#archive-report-submit",r);if(Ve.on(s,"change",(function(){return l.disabled=!this.checked})),o&&a?(r.hidden=!Ve('[value="31"]',a).checked,Ve.on(a,"change",(function(e){return r.hidden="31"!==e.target.value,ye.fit("body")})),Ve.after(a,r),ye.fit("body"),Ve.one(o,"submit",(function(e){if(!r.hidden&&s.checked)return e.preventDefault(),ye.archiveSubmit(t,l.value,(e=>(this.action="#archiveresults="+encodeURIComponent(JSON.stringify(e)),
|
||
this.submit())))}))):i&&(r.hidden=/Report submitted!/.test(i.textContent),Ve.on(s,"change",(function(){return d.hidden=!this.checked})),Ve.after(i,r),Ve.on(d,"click",(()=>ye.archiveSubmit(t,l.value,ye.archiveResults)))),e=location.hash.match(/^#archiveresults=(.*)$/))try{return ye.archiveResults(JSON.parse(decodeURIComponent(e[1])))}catch(e){}},archiveSubmit(e,t,o){const a=Ve.formData({board:n.BOARD.ID,num:ye.postID,reason:t}),i=[];for(var[r,s]of e)!function(t,n){Ve.ajax(n,{onloadend(){if(i.push([t,this.response||{error:""}]),i.length===e.length)return o(i)},form:a})}(r,s)},archiveResults(e){const t=Ve.id("archive-report");for(var[n,o]of e){var i=Ve.el("h3",{className:"archive-report-response"});"success"in o?(Ve.addClass(i,"archive-report-success"),i.textContent=`${n}: ${o.success}`):(Ve.addClass(i,"archive-report-error"),i.textContent=`${n}: ${o.error||"Error reporting post."}`),t?Ve.before(t,i):Ve.add(a.body,i)}}};const ke={init(){
|
||
if(t["Remember Your Posts"])return Ve.ready(this.ready)},ready(){if("Post successful!"!==a.title)return;let[e,t,o]=Ve("h1").nextSibling.textContent.match(/thread:(\d+),no:(\d+)/);o=+o,t=+t||o;return new y("yourPosts").set({boardID:n.BOARD.ID,threadID:t,postID:o,val:!0})}};const Ie={isOPContainerThread:!1,hasIPCount:!0,archivedBoardsKnown:!0,urls:{thread:({boardID:e,threadID:t})=>`${location.protocol}//${Y.domain(e)}/${e}/thread/${t}`,post:({postID:e})=>`#p${e}`,index:({boardID:e})=>`${location.protocol}//${Y.domain(e)}/${e}/`,catalog:({boardID:e})=>"f"===e?void 0:`${location.protocol}//${Y.domain(e)}/${e}/catalog`,archive:({boardID:e})=>Y.isArchived(e)?`${location.protocol}//${Y.domain(e)}/${e}/archive`:void 0,threadJSON:({boardID:e,threadID:t})=>`${location.protocol}//a.4cdn.org/${e}/thread/${t}.json`,threadsListJSON:({boardID:e})=>`${location.protocol}//a.4cdn.org/${e}/threads.json`,
|
||
archiveListJSON:({boardID:e})=>Y.isArchived(e)?`${location.protocol}//a.4cdn.org/${e}/archive.json`:"",catalogJSON:({boardID:e})=>`${location.protocol}//a.4cdn.org/${e}/catalog.json`,file({boardID:e},t){const n="f"===e?O.flashHost():O.host();return`${location.protocol}//${n}/${e}/${t}`},thumb:({boardID:e},t)=>`${location.protocol}//${O.thumbHost()}/${e}/${t}`},isPrunedByAge:({boardID:e})=>"f"===e,areMD5sDeferred:({boardID:e})=>"f"===e,isOnePage:({boardID:e})=>"f"===e,noAudio:({boardID:e})=>Y.noAudio(e),selectors:{board:".board",thread:".thread",threadDivider:".board > hr",summary:".summary",postContainer:".postContainer",replyOriginal:".replyContainer:not([data-clone])",sideArrows:"div.sideArrows",post:".post",infoRoot:".postInfo",info:{subject:".subject",name:".name",email:".useremail",tripcode:".postertrip",uniqueIDRoot:".posteruid",uniqueID:".posteruid > .hand",capcode:".capcode.hand",pass:".n-pu",flag:".flag, .bfl",date:".dateTime",nameBlock:".nameBlock",
|
||
quote:".postNum > a:nth-of-type(2)",reply:".replylink"},icons:{isSticky:".stickyIcon",isClosed:".closedIcon",isArchived:".archivedIcon"},file:{text:".file > :first-child",link:".fileText > a",thumb:"a.fileThumb > [data-md5]"},thumbLink:"a.fileThumb",highlightable:{op:".opContainer",reply:" > .reply",catalog:""},comment:".postMessage",spoiler:"s",quotelink:":not(pre) > .quotelink",catalog:{board:"#threads",thread:".thread",thumb:".thumb"},boardList:"#boardNavDesktop > .boardList",boardListBottom:"#boardNavDesktopFoot > .boardList",styleSheet:"link[title=switch]",psa:"#globalMessage",psaTop:"#globalToggle",searchBox:"#search-box",nav:{prev:".prev > form > [type=submit]",next:".next > form > [type=submit]"}},classes:{highlight:"highlight"},xpath:{thread:'div[contains(concat(" ",@class," ")," thread ")]',postContainer:'div[contains(@class,"postContainer")]',replyContainer:'div[contains(@class,"replyContainer")]'},regexp:{
|
||
quotelink:new RegExp("^https?://boards\\.4chan(?:nel)?\\.org/+([^/]+)/+thread/+(\\d+)(?:[/?][^#]*)?(?:#p(\\d+))?$"),quotelinkHTML:/<a [^>]*\bhref="(?:(?:\/\/boards\.4chan(?:nel)?\.org)?\/([^\/]+)\/thread\/)?(\d+)?(?:#p(\d+))?"/g,pass:/^https?:\/\/www\.4chan(?:nel)?\.org\/+pass(?:$|[?#])/,captcha:/^https?:\/\/sys\.4chan(?:nel)?\.org\/+captcha(?:$|[?#])/},bgColoredEl:()=>Ve.el("div",{className:"reply"}),isThisPageLegit:()=>["boards.4chan.org","boards.4channel.org"].includes(location.hostname)&&a.doctype&&!Ve('link[href*="favicon-status.ico"]',a.head)&&!["4chan - Temporarily Offline","4chan - Error","504 Gateway Time-out","MathJax Equation Source"].includes(a.title),is404:()=>["4chan - Temporarily Offline","4chan - 404 Not Found"].includes(a.title)||"thread"===n.VIEW&&Ve(".board")&&!Ve(".opContainer"),isIncomplete:()=>["index","thread"].includes(n.VIEW)&&!Ve(".board + *"),isBoardlessPage:e=>["www.4chan.org","www.4channel.org"].includes(e.hostname),
|
||
isAuxiliaryPage:e=>!["boards.4chan.org","boards.4channel.org"].includes(e.hostname),isFileURL:e=>O.test(e.hostname),initAuxiliary(){switch(location.hostname){case"www.4chan.org":case"www.4channel.org":return void(Ie.regexp.pass.test(location.href)?xe.init():(Ve.onExists(i,"body",(()=>Ve.addStyle(me.www))),Oe.replace.init()));case"sys.4chan.org":case"sys.4channel.org":var e=location.pathname.split(/\/+/);if("imgboard.php"===e[2]){let e;/\bmode=report\b/.test(location.search)?ye.init():(e=location.search.match(/\bres=(\d+)/))&&Ve.ready((function(){if(t["404 Redirect"]&&"Error: Specified thread does not exist."===Ve.id("errmsg")?.textContent)return Ze.navigate("thread",{boardID:n.BOARD.ID,postID:+e[1]})}))}else"post"===e[2]&&ke.init();return}},scriptData(){for(var e of u("script:not([src])",a.head))if(/\bcooldowns *=/.test(e.textContent))return e.textContent;return""},parseThreadMetadata(e){let t;const o=this.scriptData();if(e.postLimit=/\bbumplimit *= *1\b/.test(o),
|
||
e.fileLimit=/\bimagelimit *= *1\b/.test(o),e.ipCount=(t=o.match(/\bunique_ips *= *(\d+)\b/))?+t[1]:void 0,"f"===n.BOARD.ID&&e.OP.file){const{file:t}=e.OP;return Ve.ajax(this.urls.threadJSON({boardID:"f",threadID:e.ID}),{timeout:A,onloadend(){if(this.response)return t.text.dataset.md5=t.MD5=this.response.posts[0].md5}})}},parseNodes(e,t){if("f"===e.boardID)return(()=>{const e=[];for(var n of["Sticky","Closed"]){var o;(o=Ve(`img[alt=${n}]`,t.info))&&e.push(Ve.addClass(o,`${n.toLowerCase()}Icon`,"retina"))}return e})()},parseDate:e=>new Date(1e3*e.dataset.utc),parseFile(e,t){let n;const{text:o,link:a,thumb:i}=t;if(!(n=a.nextSibling?.textContent.match(/\(([\d.]+ [KMG]?B).*\)/)))return!1;if(Ve.extend(t,{name:o.title||a.title||a.textContent,size:n[1],dimensions:n[0].match(/\d+x\d+/)?.[0],tag:n[0].match(/,[^,]*, ([a-z]+)\)/i)?.[1],MD5:o.dataset.md5}),i&&(Ve.extend(t,{thumbURL:i.src,MD5:i.dataset.md5,isSpoiler:Ve.hasClass(i.parentNode,"imgspoiler")}),t.isSpoiler)){let n
|
||
;t.thumbURL=(n=a.href.match(/\d+(?=\.\w+$)/))?`${location.protocol}//${O.thumbHost()}/${e.board}/${n[0]}s.jpg`:void 0}return!0},cleanComment(e){let t;if(t=Ve(".abbr",e)){for(var n of u(".abbr + br, .exif",e))Ve.rm(n);for(let e=0;e<2;e++){var o;(o=t.previousSibling)&&"BR"===o.nodeName&&Ve.rm(o)}return Ve.rm(t)}},cleanCommentDisplay(e){let t;return(t=Ve("b",e))&&/^Rolled /.test(t.textContent)&&Ve.rm(t),Ve.rm(Ve(".fortune",e))},insertTags(e){let t;for(t of u("s, .removed-spoiler",e))Ve.replace(t,[Ve.tn("[spoiler]"),...t.childNodes,Ve.tn("[/spoiler]")]);for(t of u(".prettyprint",e))Ve.replace(t,[Ve.tn("[code]"),...t.childNodes,Ve.tn("[/code]")])},hasCORS:e=>e.split("/").slice(0,3).join("/")===location.protocol+"//a.4cdn.org",sfwBoards:e=>Y.sfwBoards(e),uidColor(e){let t=0,n=0;for(;n<8;)t=(t<<5)-t+e.charCodeAt(n++);return t>>8&16777215},isLinkified:e=>O.test(e.hostname),testNativeExtension:()=>Ve.global((function(){if(window.Parser?.postMenuIcon)return this.enabled="true"})),
|
||
transformBoardList(){let e;const t=[],n=()=>Ve.el("span",{className:"spacer"}),o=Ve.X(".//a|.//text()[not(ancestor::a)]",Ve(Ie.selectors.boardList));let a=0;for(;e=o.snapshotItem(a++);)switch(e.nodeName){case"#text":for(var i of e.nodeValue){var r=Ve.el("span",{textContent:i});" "===i&&(r.className="space"),"]"===i&&t.push(n()),t.push(r),"["===i&&t.push(n())}break;case"A":var s=e.cloneNode(!0);t.push(s)}return t},Build:{staticPath:"//s.4cdn.org/image/",gifIcon:window.devicePixelRatio>=2?"@2x.gif":".gif",spoilerRange:Object.create(null),shortFilename(e){const t=e.match(/\.?[^\.]*$/)[0];return e.length-t.length>30?`${e.match(/(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[^]){0,25}/)[0]}(...)${t}`:e},spoilerThumb(e){let t;return(t=this.spoilerRange[e])?`${this.staticPath}spoiler-${e}${Math.floor(1+t*Math.random())}.png`:`${this.staticPath}spoiler.png`},sameThread:(e,t)=>"thread"===n.VIEW&&n.BOARD.ID===e&&n.THREADID===+t,
|
||
threadURL:(e,t)=>e!==n.BOARD.ID?`//${Y.domain(e)}/${e}/thread/${t}`:"thread"!==n.VIEW||+t!==n.THREADID?`/${e}/thread/${t}`:"",postURL(e,t,n){return`${this.threadURL(e,t)}#p${n}`},parseJSON(e,{siteID:t,boardID:n}){const o={ID:e.no,postID:e.no,threadID:e.resto||e.no,boardID:n,siteID:t,isReply:!!e.resto,isSticky:!!e.sticky,isClosed:!!e.closed,isArchived:!!e.archived,fileDeleted:!!e.filedeleted,filesDeleted:e.filedeleted?[0]:[]};for(var a in o.info={subject:Ve.unescape(e.sub),email:Ve.unescape(e.email),name:Ve.unescape(e.name)||"",tripcode:e.trip,pass:null!=e.since4pass?`${e.since4pass}`:void 0,uniqueID:e.id,flagCode:e.country,flagCodeTroll:e.board_flag,flag:Ve.unescape(e.country_name||e.flag_name),dateUTC:e.time,dateText:e.now,commentHTML:{innerHTML:e.com||"",[ie]:!0}},e.capcode&&(o.info.capcode=e.capcode.replace(/_highlight$/,"").replace(/_/g," ").replace(/\b\w/g,(e=>e.toUpperCase())),o.capcodeHighlight=/_highlight$/.test(e.capcode),delete o.info.uniqueID),o.files=[],
|
||
e.ext&&(o.file=this.parseJSONFile(e,{siteID:t,boardID:n}),o.files.push(o.file)),o.extra=m(),e)"x"===a[0]&&(o.extra[a]=e[a]);return o},parseJSONFile(e,{siteID:t,boardID:o}){const a=n.sites[t],i="yotsuba"===a.software&&"f"===o?`${encodeURIComponent(e.filename)}${e.ext}`:`${e.tim}${e.ext}`,r={name:Ve.unescape(e.filename)+e.ext,url:a.urls.file({siteID:t,boardID:o},i),height:e.h,width:e.w,MD5:e.md5,size:Ve.bytesToString(e.fsize),thumbURL:a.urls.thumb({siteID:t,boardID:o},`${e.tim}s.jpg`),theight:e.tn_h,twidth:e.tn_w,isSpoiler:!!e.spoiler,tag:e.tag,hasDownscale:!!e.m_img};return null==e.h||/\.pdf$/.test(r.url)||(r.dimensions=`${r.width}x${r.height}`),r},parseComment:e=>(e=e.replace(/<br\b[^<]*>/gi,"\n").replace(/\n\n<span\b[^<]* class="abbr"[^]*$/i,"").replace(/<[^>]*>/g,""),Ve.unescape(e)),parseCommentDisplay(e){if(!t["Remove Spoilers"]&&!t["Reveal Spoilers"]){let t;for(;(t=e.replace(/<s>(?:(?!<\/?s>).)*<\/s>/g,"[spoiler]"))!==e;)e=t}
|
||
return e=e.replace(/^<b\b[^<]*>Rolled [^<]*<\/b>/i,"").replace(/<span\b[^<]* class="fortune"[^]*$/i,""),this.parseComment(e).trim().replace(/\s+$/gm,"")},postFromObject(e,t){const o=this.parseJSON(e,{boardID:t,siteID:n.SITE.ID});return this.post(o)},post(e){const{ID:t,threadID:o,boardID:a,file:i}=e,{subject:r,email:s,name:l,tripcode:d,capcode:c,pass:h,uniqueID:p,flagCode:g,flagCodeTroll:f,flag:m,dateUTC:b,dateText:A,commentHTML:v}=e.info,{staticPath:w,gifIcon:x}=this;let y,k,I;if(c)if(I=c.toLowerCase(),"Founder"===c)k="the Founder",y="4chan's Founder";else if("Verified"===c)k="Verified Users",y="";else{const e=Ve.getOwn({Admin:"Administrator",Mod:"Moderator"},c)||c;k=`${e}s`,y=`a 4chan ${e}`}const C=this.threadURL(a,o),D=function(e,t,o,a,i,r,s,l,d,c,h,u,p,g,f,m,b,A,v,w,x,y,k){const I=[le("span",{class:"name"+(a?" "+a:"")},r)];s&&I.push(" ",le("span",{class:"postertrip"},s)),l&&I.push(" ",le("span",{title:`Pass user since ${l}`,class:"n-pu"})),a&&I.push(" ",le("strong",{
|
||
class:`capcode hand id_${d}`,title:`Highlight posts by ${c}`},"## ",a));const C=i?[" ",le("a",{href:`mailto:${i}`,class:"useremail"},...I)]:I;"f"===y&&!t.isReply||p||C.push(" "),p&&(C.push(le("img",{src:`${h}${d}icon${u}`,alt:`${a} Icon}`,title:`This user is ${p}.`,class:"identityIcon retina"})),g&&!a&&C.push(le("span",{class:`posteruid id_${g}`},"(ID: ",le("span",{class:"hand",title:"Highlight posts by this ID"},"$",g),")"))),m&&C.push(" ",le("span",{title:f,class:`flag flag-${m.toLowerCase()}`})),b&&C.push(" ",le("span",{title:f,class:`bfl bfl-${b.toLowerCase()}`}));const D=[le("a",{href:w,title:"Link to this post"},"No."),le("a",{href:x,title:"Reply to this post"},e)];if(t.isSticky){const e=`${h}sticky${u}`;D.push(" "),"f"===y?D.push(le("img",{src:e,alt:"Sticky",title:"Sticky",style:"height: 18px; width: 18px;"})):D.push(le("img",{src:e,alt:"Sticky",title:"Sticky",class:"stickyIcon retina"}))}if(t.isClosed&&!t.isArchived){D.push(" ");const e=`${h}closed${u}`
|
||
;"f"===y?D.push(le("img",{src:e,alt:"Closed",title:"Closed",style:"height: 18px; width: 18px;"})):D.push(le("img",{src:e,alt:"Closed",title:"Closed",class:"closedIcon retina"}))}return t.isArchived&&D.push(" ",le("img",{src:`${h}archived${u}`,alt:"Archived",title:"Archived",class:"archivedIcon retina"})),t.isReply||"index"!==n.VIEW||(D.push(" "),D.push(le("span",null,"[",le("a",{href:`/${y}/thread/${k}`,class:"replylink"},"Reply"),"]"))),le("div",{class:"postInfo desktop",id:`pi${e}`},le("input",{type:"checkbox",name:e,value:"delete"})," ",...!t.isReply||"f"===y||o?[le("span",{class:"subject"},o)," "]:[],le("span",{class:`nameBlock${a||""}`},...C)," ",le("span",{class:"dateTime","data-utc":A},v)," ",le("span",{class:"postNum"+(" f"!==y||t.isReply?" desktop":"")},...D))}(t,e,r,c,s,l,d,h,I,k,w,x,y,p,m,g,f,b,A,`${C}#p${t}`,this.sameThread(a,o)?`javascript:quote('${+t}');`:`${C}#q${t}`,a,o);let E,S,T,R;i&&(E=/^https?:(?=\/\/i\.4cdn\.org\/)/,S=i.url.replace(E,""),
|
||
T=this.shortFilename(i.name),R=i.isSpoiler?this.spoilerThumb(a):i.thumbURL.replace(E,""));const B=function(e,t,n,o,a,i,r,s,l){if(e){const r=[];return"f"===n?r.push(le("div",{class:"fileInfo","data-md5":e.MD5},le("span",{class:"fileText",id:`fT${t}`},"File: ",le("a",{"data-width":e.width,"data-height":e.height,href:o,target:"_blank"},e.name),"-(",e.size,", ",e.dimensions,e.tag?", "+e.tag:"",")"))):r.push(le("div",{class:"fileText",id:`fT${t}`,title:e.isSpoiler?e.name:null},"File: ",le("a",{title:e.name===a||e.isSpoiler?null:e.name,href:o,target:"_blank"},e.isSpoiler?"Spoiler Image":a),` (${e.size}, ${e.dimensions||"PDF"})`),le("a",{class:"fileThumb"+(e.isSpoiler?" imgspoiler":""),href:o,target:"_blank","data-m":e.hasDownscale?"":null},le("img",{src:i,alt:e.size,"data-md5":e.MD5,style:`height: ${e.isSpoiler?"100":e.theight}px; width: ${e.isSpoiler?"100":e.twidth}px;`,loading:"lazy"}))),le("div",{class:"file",id:`f${t}`},...r)}return r.fileDeleted?le("div",{class:"file",id:`f${t}`
|
||
},le("span",{class:"fileThumb"},le("img",{src:`${s}filedeleted-res${l}`,alt:"File deleted.",class:"fileDeletedRes retina"}))):{innerHTML:"",[ie]:!0}}(i,t,a,S,T,R,e,w,x),P=e.isReply?"reply":"op",M=le(se,null,e.isReply?le("div",{class:"sideArrows",id:`sa${t}`},">>"):"",le("div",{id:`p${t}`,class:`post ${P}${e.capcodeHighlight?" highlightPost":""}`},e.isReply?le(se,null,D,B):le(se,null,B,D),le("blockquote",{class:"postMessage",id:`m${t}`},v))),N=Ve.el("div",{className:`postContainer ${P}Container`,id:`pc${t}`});for(var L of(Ve.extend(N,M),u(".quotelink",N))){var F,O=L.getAttribute("href");if("#"===O[0])this.sameThread(a,o)||(L.href=this.threadURL(a,o)+O);else(F=L.href.match(Ie.regexp.quotelink))&&this.sameThread(F[1],F[2])&&(L.href=O.match(/(#[^#]*)?$/)[0]||"#")}return N},summaryText(e,t,n){let o="";return e&&(o+=`${e} `),o+=`${t} post${t>1?"s":""}`,+n&&(o+=` and ${n} image repl${n>1?"ies":"y"}`),o+` ${"-"===e?"shown":"omitted"}.`},summary(e,t,n,o){return Ve.el("a",{className:"summary",
|
||
textContent:this.summaryText("",n,o),href:`/${e}/thread/${t}`})},thread(e,t,n){let o;if((o=e.nodes.root)?Ve.rmAll(o):e.nodes.root=o=Ve.el("div",{className:"thread",id:`t${t.no}`}),this.hat&&Ve.add(o,this.hat.cloneNode(!1)),Ve.add(o,e.OP.nodes.root),t.omitted_posts||!n&&t.replies){const[a,i]=n?[t.omitted_posts,t.images-t.last_replies.filter((e=>!!e.ext)).length]:[t.replies,t.images],r=this.summary(e.board.ID,t.no,a,i);Ve.add(o,r)}return o},catalogThread(e,n,o){let a,i,r;const{staticPath:s,gifIcon:l}=this,{tn_w:d,tn_h:c}=n;if(n.spoiler&&!t["Reveal Spoiler Thumbnails"]){let t;r=`${s}spoiler`,(t=this.spoilerRange[e.board])&&(r+=`-${e.board}`+Math.floor(1+t*Math.random())),r+=".png",i="spoiler-file",a="--tn-w: 100; --tn-h: 100;"}else if(n.filedeleted)r=`${s}filedeleted-res${l}`,i="deleted-file";else if(e.OP.file){r=e.OP.file.thumbURL;const t=250/Math.max(d,c);a=`--tn-w: ${d*t}; --tn-h: ${c*t};`}else r=`${s}nofile.png`,i="no-file"
|
||
;const h=n.replies+1,p=n.images+!!n.ext,g=Ve.el("div",function(e,t,n,o,a,i,r,s,l){return le(se,null,le("a",{class:"catalog-link",href:`/${e.board}/thread/${e.ID}`},le("img",n?{src:t,class:`catalog-thumb ${n}`}:{src:t,class:"catalog-thumb","data-width":o.tn_w,"data-height":o.tn_h})),le("div",{class:"catalog-stats"},le("span",{title:"Posts / Files / Page"},le("span",{class:"post-count"+(o.bumplimit?" warning":"")},a)," / ",le("span",{class:"file-count"+(o.imagelimit?" warning":"")},i)," / ",le("span",{class:"page-count"},r)),le("span",{class:"catalog-icons"},e.isSticky?le("img",{src:`${s}sticky${l}`,class:"stickyIcon",title:"Sticky"}):"",e.isClosed?le("img",{src:`${s}closed${l}`,class:"closedIcon",title:"Closed"}):"")))}(e,r,i,n,h,p,o,s,l));for(var f of(Ve.before(e.OP.nodes.info,[...g.childNodes]),u("br",e.OP.nodes.comment)))f.previousSibling&&"BR"===f.previousSibling.nodeName&&Ve.addClass(f,"extra-linebreak");const m=Ve.el("div",{className:"thread catalog-thread",id:`t${e}`})
|
||
;return e.OP.highlights&&Ve.addClass(m,...e.OP.highlights),e.OP.file||Ve.addClass(m,"noFile"),m.style.cssText=a||"",m},catalogReply(e,t){let n="";t.com&&(n=this.parseCommentDisplay(t.com).replace(/>>\d+/g,"").trim().replace(/\n+/g," // ")),t.ext&&(n||(n=`${Ve.unescape(t.filename)}${t.ext}`)),t.com&&(n||(n=Ve.unescape(t.com.replace(/<br\b[^<]*>/gi," // ")))),n||(n=" "),n.length>73&&(n=`${n.slice(0,70)}...`);const o=this.postURL(e.board.ID,e.ID,t.no);return Ve.el("div",{className:"catalog-reply"},le(se,null,le("span",null,le("time",{"data-utc":1e3*t.time,"data-abbrev":"1"},"..."),": "),le("a",{class:"catalog-reply-excerpt",href:o},n),le("a",{class:"catalog-reply-preview",href:o},"...")))}}},Ce={tinyboard:ve,yotsuba:Ie};var De={init(){if(["index","thread","archive"].includes(n.VIEW)&&t["File Info Formatting"])return l.Post.push({name:"File Info Formatting",cb:this.node})},node(){if(!this.file)return;if(this.isClone){let e
|
||
;for(e of u(".file-info .download-button",this.file.text))Ve.on(e,"click",j.download);for(e of u(".file-info .quick-filter-md5",this.file.text))Ve.on(e,"click",We.quickFilterMD5);return}const e=Ve.el("span",{className:"fileText-original"});Ve.prepend(this.file.link.parentNode,e),Ve.add(e,[this.file.link.previousSibling,this.file.link,this.file.link.nextSibling]);const n=Ve.el("span",{className:"file-info"});return De.format(t.fileInfo,this,n),Ve.prepend(this.file.text,n)},format(e,t,n){let a;const i=[];for(a of(e.replace(/%(.)|[^%]+/g,(function(e,n){return i.push(Ve.hasOwn(De.formatters,n)?De.formatters[n].call(t):{innerHTML:o(e)}),""})),Ve.extend(n,{innerHTML:o.cat(i)}),u(".download-button",n)))Ve.on(a,"click",j.download);for(a of u(".quick-filter-md5",n))Ve.on(a,"click",We.quickFilterMD5)},formatters:{t(){return{innerHTML:o(this.file.url.match(/[^/]*$/)[0]),[ie]:!0}},T(){return le("a",{href:this.file.url,target:"_blank"},De.formatters.t.call(this))},l(){return le("a",{
|
||
href:this.file.url,target:"_blank"},De.formatters.n.call(this))},L(){return le("a",{href:this.file.url,target:"_blank"},De.formatters.N.call(this))},n(){const e=this.file.name,t=Ce.yotsuba.Build.shortFilename(this.file.name,this.isReply);return e===t?{innerHTML:o(e),[ie]:!0}:le("span",{class:"fnswitch"},le("span",{class:"fntrunc"},t),le("span",{class:"fnfull"},e))},N(){return{innerHTML:o(this.file.name),[ie]:!0}},d(){return le("a",{href:this.file.url,download:this.file.name,class:"download-button"},"📥︎")},f:()=>({innerHTML:'<a href="javascript:;" class="quick-filter-md5">✕</a>',[ie]:!0}),p(){return{innerHTML:this.file.isSpoiler?"Spoiler, ":"",[ie]:!0}},s(){return{innerHTML:o(this.file.size),[ie]:!0}},B(){return{innerHTML:Math.round(this.file.sizeInBytes)+" Bytes",[ie]:!0}},K(){return{innerHTML:Math.round(this.file.sizeInBytes/1024)+" KB",[ie]:!0}},M(){return{innerHTML:Math.round(this.file.sizeInBytes/1048576*100)/100+" MB",[ie]:!0}},r(){return{innerHTML:o(this.file.dimensions||"PDF"),
|
||
[ie]:!0}},g(){return{innerHTML:this.file.tag?", "+o(this.file.tag):"",[ie]:!0}},"%":()=>({innerHTML:"%",[ie]:!0})}},Ee={init(){["index","thread","archive"].includes(n.VIEW)&&t["Time Formatting"]&&l.Post.push({name:"Time Formatting",cb:this.node})},node(){if(!this.info.date||this.isClone)return;const{textContent:e}=this.nodes.date;this.nodes.date.textContent=e.match(/^\s*/)[0]+Ee.format(t.time,this.info.date)+e.match(/\s*$/)[0]},format:(e,t)=>e.replace(/%(.)/g,(function(e,n){return Ve.hasOwn(Ee.formatters,n)?Ee.formatters[n].call(t):e})),zeroPad:e=>e<10?`0${e}`:e,formatterCache:new Map,formatters:{a(){let e=Ee.formatterCache.get("a");return e||(e=Intl.DateTimeFormat(t.timeLocale||void 0,{weekday:"short"}),Ee.formatterCache.set("a",e)),e.format(this)},A(){let e=Ee.formatterCache.get("A");return e||(e=Intl.DateTimeFormat(t.timeLocale||void 0,{weekday:"long"}),Ee.formatterCache.set("A",e)),e.format(this)},b(){let e=Ee.formatterCache.get("b")
|
||
;return e||(e=Intl.DateTimeFormat(t.timeLocale||void 0,{month:"short"}),Ee.formatterCache.set("b",e)),e.format(this)},B(){let e=Ee.formatterCache.get("B");return e||(e=Intl.DateTimeFormat(t.timeLocale||void 0,{month:"long"}),Ee.formatterCache.set("B",e)),e.format(this)},d(){return Ee.zeroPad(this.getDate())},e(){return this.getDate()},H(){return Ee.zeroPad(this.getHours())},I(){return Ee.zeroPad(this.getHours()%12||12)},k(){return this.getHours()},l(){return this.getHours()%12||12},m(){return Ee.zeroPad(this.getMonth()+1)},M(){return Ee.zeroPad(this.getMinutes())},p(){let e=Ee.formatterCache.get("p");e||(e=Intl.DateTimeFormat(t.timeLocale||void 0,{hour:"numeric",hour12:!0}),Ee.formatterCache.set("p",e));return e.formatToParts(this).find((e=>"dayPeriod"===e.type)).value},P(){return Ee.formatters.p.call(this).toLowerCase()},S(){return Ee.zeroPad(this.getSeconds())},y(){return this.getFullYear().toString().slice(2)},Y(){return this.getFullYear()},"%":()=>"%"}},Se={init(){
|
||
if("thread"!==n.VIEW||!t["Reply Pruning"])return;this.container=Ve.frag(),this.summary=Ve.el("span",{hidden:!0,className:"summary"}),this.summary.style.cursor="pointer",Ve.on(this.summary,"click",(()=>(this.inputs.enabled.checked=!this.inputs.enabled.checked,Ve.event("change",null,this.inputs.enabled))));const e=L.checkbox("Prune Replies","Show Last",t["Prune All Threads"]),a=Ve.el("span",{title:"Maximum number of replies to show."},{innerHTML:' <input type="number" name="Max Replies" min="0" step="1" value="'+o(t["Max Replies"])+'" class="field">'});return Ve.prepend(a,e),this.inputs={enabled:e.firstElementChild,replies:a.lastElementChild},this.setEnabled.call(this.inputs.enabled),Ve.on(this.inputs.enabled,"change",this.setEnabled),Ve.on(this.inputs.replies,"change",Ve.cb.value),Ke.menu.addEntry({el:a,order:190}),l.Thread.push({name:"Reply Pruning",cb:this.node})},position:0,hidden:0,hiddenFiles:0,total:0,totalFiles:0,setEnabled(){const e=Te.input
|
||
;return this.checked&&e?.checked&&(e.checked=!1,Ve.event("change",null,e)),Se.active=this.checked},showIfHidden(e){if(Se.container&&Ve(`#${e}`,Se.container))return Se.inputs.enabled.checked=!1,Ve.event("change",null,Se.inputs.enabled)},node(){let e;return Se.thread=this,this.isSticky&&(Se.active=Se.inputs.enabled.checked=!0,Te.input&&(t["Thread Quotes"]=Te.input.checked=!1)),this.posts.forEach((function(e){if(e.isReply&&(Se.total++,e.file))return Se.totalFiles++})),Se.active&&/^#p\d+$/.test(location.hash)&&1<=(e=this.posts.keys.indexOf(location.hash.slice(2)))&&e<1+Math.max(Se.total-+t["Max Replies"],0)&&(Se.active=Se.inputs.enabled.checked=!1),Ve.after(this.OP.nodes.root,Se.summary),Ve.on(Se.inputs.enabled,"change",Se.update),Ve.on(Se.inputs.replies,"change",Se.update),Ve.on(a,"ThreadUpdate",Se.updateCount),Ve.on(a,"ThreadUpdate",Se.update),Se.update()},updateCount(e){if(!e.detail[404])for(var t of e.detail.newPosts)Se.total++,n.posts.get(t).file&&Se.totalFiles++},update(){let e,o,i
|
||
;const r=Se.hidden,s=Se.active?Math.max(Se.total-+t["Max Replies"],0):0,l=a.body.clientHeight-window.scrollY,{posts:d}=Se.thread;if(Se.hidden<s){for(;Se.hidden<s&&Se.position<d.keys.length;)if(i=d.get(d.keys[Se.position++]),i.isReply&&!i.isFetchedQuote){for(;(o=Se.summary.nextSibling)&&o!==i.nodes.root;)Ve.add(Se.container,o);Ve.add(Se.container,i.nodes.root),Se.hidden++,i.file&&Se.hiddenFiles++}}else if(Se.hidden>s){const e=Ve.frag();for(;Se.hidden>s&&Se.position>0;)if(i=d.get(d.keys[--Se.position]),i.isReply&&!i.isFetchedQuote){for(;(o=Se.container.lastChild)&&o!==i.nodes.root;)Ve.prepend(e,o);Ve.prepend(e,i.nodes.root),Se.hidden--,i.file&&Se.hiddenFiles--}Ve.after(Se.summary,e),Ve.event("PostsInserted",null,Se.summary.parentNode)}if(Se.summary.textContent=Se.active?n.SITE.Build.summaryText("+",Se.hidden,Se.hiddenFiles):n.SITE.Build.summaryText("-",Se.total,Se.totalFiles),Se.summary.hidden=Se.total<=+t["Max Replies"],
|
||
r!==s&&(e=Ke.getTopOf(Ve(".board")))<0)return window.scrollBy(0,Math.max(a.body.clientHeight-l,window.scrollY+e)-window.scrollY)}},Te={init(){if(t["Quote Threading"]&&"thread"===n.VIEW)return this.controls=Ve.el("label",{innerHTML:'<input id="threadingControl" name="Thread Quotes" type="checkbox"> Threading'}),this.threadNewLink=Ve.el("span",{className:"brackets-wrap threadnewlink",hidden:!0}),Ve.extend(this.threadNewLink,{innerHTML:'<a href="javascript:;">Thread New Posts</a>'}),this.input=Ve("input",this.controls),this.input.checked=t["Thread Quotes"],Ve.on(this.input,"change",this.setEnabled),Ve.on(this.input,"change",this.rethread),Ve.on(this.threadNewLink.firstElementChild,"click",this.rethread),Ve.on(a,"4chanXInitFinished",(()=>this.ready=!0)),Ke.menu.addEntry(this.entry={el:this.controls,order:99}),l.Thread.push({name:"Quote Threading",cb:this.setThread}),l.Post.push({name:"Quote Threading",cb:this.node})},parent:m(),children:m(),inserted:m(),toggleThreading(){
|
||
return this.setThreadingState(!t["Thread Quotes"])},setThreadingState(e){return this.input.checked=e,this.setEnabled.call(this.input),this.rethread.call(this.input)},setEnabled(){if(this.checked){Ve.set("Prune All Threads",!1);const e=Se.inputs?.enabled;e?.checked&&(e.checked=!1,Ve.event("change",null,e))}return Ve.cb.checked.call(this)},setThread(){return Te.thread=this,Ve.asap((()=>!t["Thread Updater"]||Ve(".navLinksBot > .updatelink")),(function(){let e;if(e=Ve(".navLinksBot"))return Ve.add(e,[Ve.tn(" "),Te.threadNewLink])}))},node(){let e;if(this.isFetchedQuote||this.isClone||!this.isReply)return;const t=new Set;let o=null;for(var a of this.quotes)(e=n.posts.get(a))&&!e.isFetchedQuote&&e.isReply&&e.ID<this.ID&&(t.add(e.ID),(!o||e.ID>o.ID)&&(o=e));if(!o)return;let i=o;for(;i=Te.parent[i.fullID];)t.delete(i.ID);return 1===t.size?Te.parent[this.fullID]=o:void 0},descendants(e){let t,n=[e];if(t=Te.children[e.fullID])for(var o of t)n=n.concat(Te.descendants(o));return n},insert(e){
|
||
let n,o;if(!t["Thread Quotes"]||!(n=Te.parent[e.fullID])||Te.inserted[e.fullID])return!1;const a=Te.descendants(e);if(!ee.posts.has(n.ID)&&function(){for(var e of a)if(ee.posts.has(e.ID))return!0}())return Te.threadNewLink.hidden=!1,!1;const{order:i}=ee,r=Te.children[n.fullID]||(Te.children[n.fullID]=[]),s=n.nodes.threadContainer||Ve.el("div",{className:"threadContainer"}),l=[e.nodes.root];e.nodes.threadContainer&&l.push(e.nodes.threadContainer);let d=r.length;for(let t=r.length-1;t>=0;t--){r[t].ID>=e.ID&&d--}if(d!==r.length){const t=r[d];for(o of a)i.before(i[t.ID],i[o.ID]);r.splice(d,0,e),Ve.before(t.nodes.root,l)}else{let t,d=n;for(;(t=Te.children[d.fullID])&&t.length;)d=t[t.length-1];for(let e=a.length-1;e>=0;e--)o=a[e],i.after(i[d.ID],i[o.ID]);r.push(e),Ve.add(s,l)}return Te.inserted[e.fullID]=!0,n.nodes.threadContainer||(n.nodes.threadContainer=s,Ve.addClass(n.nodes.root,"threadOP"),Ve.after(n.nodes.root,s)),!0},rethread(){if(!Te.ready)return;const{thread:e}=Te,{posts:n}=e
|
||
;if(Te.threadNewLink.hidden=!0,t["Thread Quotes"])n.forEach(Te.insert);else{const t=[];ee.order=new Z,Te.inserted=m(),n.forEach((function(e){if(!e.isFetchedQuote)return ee.order.push(e),e.isReply&&t.push(e.nodes.root),Te.children[e.fullID]?(delete Te.children[e.fullID],Ve.rmClass(e.nodes.root,"threadOP"),Ve.rm(e.nodes.threadContainer),delete e.nodes.threadContainer):void 0})),Ve.add(e.nodes.root,t)}return ee.position=ee.order.first,ee.updatePosition(),ee.setLine(!0),ee.read(),ee.update()}},Re={init(){let e,o,r;if("thread"!==n.VIEW||!t["Thread Updater"])return;this.enabled=!0,this.audio=Ve.el("audio"),"gecko"!==Ve.engine&&(this.audio.src=this.beep),t["Updater and Stats in Header"]?(this.dialog=r=Ve.el("span",{id:"updater"}),Ve.extend(r,{innerHTML:'<span id="update-status" class="empty"></span><span id="update-timer" class="empty" title="Update now"></span>'}),Ke.addShortcut("updater",r,100)):(this.dialog=r=L.dialog("updater",{
|
||
innerHTML:'<div class="move"></div><span id="update-status" class="empty"></span><span id="update-timer" class="empty" title="Update now"></span>'}),Ve.addClass(i,"float"),Ve.ready((()=>Ve.add(a.body,r)))),this.checkPostCount=0,this.timer=Ve("#update-timer",r),this.status=Ve("#update-status",r),Ve.on(this.timer,"click",this.update),Ve.on(this.status,"click",this.update);const s=Ve.el("span",{className:"brackets-wrap updatelink"});Ve.extend(s,{innerHTML:'<a href="javascript:;">Update</a>'}),Ot.ready((function(){let e;if(e=Ve(".navLinksBot"))return Ve.add(e,[Ve.tn(" "),s])})),Ve.on(s.firstElementChild,"click",this.update);const d=[];for(o in c.updater.checkbox){var h=c.updater.checkbox[o];e=L.checkbox(o,o),e.title=h[1];var u=e.firstElementChild;Ve.on(u,"change",Ve.cb.checked),"Scroll BG"===u.name?(Ve.on(u,"change",this.cb.scrollBG),this.cb.scrollBG()):"Auto Update"===u.name&&Ve.on(u,"change",this.setInterval),d.push({el:e})}return this.settings=Ve.el("span",{
|
||
innerHTML:'<a href="javascript:;">Interval</a>'}),Ve.on(this.settings,"click",this.intervalShortcut),d.push({el:this.settings}),Ke.menu.addEntry(this.entry={el:Ve.el("span",{textContent:"Updater"}),order:110,subEntries:d}),l.Thread.push({name:"Thread Updater",cb:this.node})},node(){return Re.thread=this,Re.root=this.nodes.root,Re.outdateCount=0,Re.postIDs=[],Re.fileIDs=[],this.posts.forEach((function(e){if(Re.postIDs.push(e.ID),e.file)return Re.fileIDs.push(e.ID)})),Re.cb.interval.call(Ve.el("input",{value:t.Interval})),Ve.on(a,"QRPostSuccessful",Re.cb.checkpost),Ve.on(a,"visibilitychange",Re.cb.visibility),Re.setInterval()},
|
||
/*
|
||
http://freesound.org/people/pierrecartoons1979/sounds/90112/
|
||
cc-by-nc-3.0
|
||
*/
|
||
beep:"data:audio/wav;base64,UklGRjQDAABXQVZFZm10IBAAAAABAAEAgD4AAIA+AAABAAgAc21wbDwAAABBAAADAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkYXRhzAIAAGMms8em0tleMV4zIpLVo8nhfSlcPR102Ki+5JspVEkdVtKzs+K1NEhUIT7DwKrcy0g6WygsrM2k1NpiLl0zIY/WpMrjgCdbPhxw2Kq+5Z4qUkkdU9K1s+K5NkVTITzBwqnczko3WikrqM+l1NxlLF0zIIvXpsnjgydZPhxs2ay95aIrUEkdUdC3suK8N0NUIjq+xKrcz002WioppdGm091pK1w0IIjYp8jkhydXPxxq2K295aUrTkoeTs65suK+OUFUIzi7xqrb0VA0WSoootKm0t5tKlo1H4TYqMfkiydWQBxm16+85actTEseS8y7seHAPD9TIza5yKra01QyWSson9On0d5wKVk2H4DYqcfkjidUQB1j1rG75KsvSkseScu8seDCPz1TJDW2yara1FYxWSwnm9Sn0N9zKVg2H33ZqsXkkihSQR1g1bK65K0wSEsfR8i+seDEQTxUJTOzy6rY1VowWC0mmNWoz993KVc3H3rYq8TklSlRQh1d1LS647AyR0wgRMbAsN/GRDpTJTKwzKrX1l4vVy4lldWpzt97KVY4IXbUr8LZljVPRCxhw7W3z6ZISkw1VK+4sMWvXEhSPk6buay9sm5JVkZNiLWqtrJ+TldNTnquqbCwilZXU1BwpKirrpNgWFhTaZmnpquZbFlbVmWOpaOonHZcXlljhaGhpZ1+YWBdYn2cn6GdhmdhYGN3lp2enIttY2Jjco+bnJuOdGZlZXCImJqakHpoZ2Zug5WYmZJ/bGlobX6RlpeSg3BqaW16jZSVkoZ0bGtteImSk5KIeG5tbnaFkJKRinxxbm91gY2QkIt/c3BwdH6Kj4+LgnZxcXR8iI2OjIR5c3J0e4WLjYuFe3VzdHmCioyLhn52dHR5gIiKioeAeHV1eH+GiYqHgXp2dnh9hIiJh4J8eHd4fIKHiIeDfXl4eHyBhoeHhH96eHmA",
|
||
playBeep(){const{audio:e}=Re;return e.src||(e.src=Re.beep),e.paused?e.play():Ve.one(e,"ended",Re.playBeep)},cb:{checkpost(e){if(e.detail.threadID===Re.thread.ID)return Re.postID=e.detail.postID,Re.checkPostCount=0,Re.outdateCount=0,Re.setInterval()},visibility(){if(!a.hidden)return Re.outdateCount=0,Re.seconds>Re.interval?Re.setInterval():void 0},scrollBG:()=>Re.scrollBG=t["Scroll BG"]?()=>!0:()=>!a.hidden,interval(e){let t=parseInt(this.value,10);if(t<1&&(t=1),Re.interval=this.value=t,e)return Ve.cb.value.call(this)},load(){if(this===Re.req)switch(this.status){case 200:return Re.parse(this),Re.thread.isArchived?Re.kill():Re.setInterval();case 404:return Ve.ajax(n.SITE.urls.catalogJSON({boardID:Re.thread.board.ID}),{onloadend(){let e;if(200===this.status){for(var t of(e=!0,this.response))for(var n of t.threads)if(n.no===Re.thread.ID){e=!1;break}}else e=!1;return e?Re.kill():Re.error(this)}});default:return Re.error(this)}}},kill:()=>(Re.thread.kill(),Re.setInterval(),
|
||
Ve.event("ThreadUpdate",{404:!0,threadID:Re.thread.fullID})),error:e=>(304===e.status&&Re.set("status",""),Re.setInterval(),e.status?304!==e.status?Re.set("status",`${e.statusText} (${e.status})`,"warning"):void 0:Re.set("status","Connection Error","warning")),setInterval(){if(clearTimeout(Re.timeoutID),Re.thread.isDead)return Re.set("status",Re.thread.isArchived?"Archived":"404","warning"),void Re.set("timer","");if(Re.postID&&Re.checkPostCount<5)return Re.set("timer","...","loading"),void(Re.timeoutID=setTimeout(Re.update,++Re.checkPostCount*b));if(!t["Auto Update"])return void Re.set("timer","Update");const{interval:e}=Re;if(t["Optional Increase"]){const t=a.hidden?10:5,n=Math.min(Re.outdateCount,t),o=(Math.floor(.1*e)||1)*n*n;Re.seconds=Ve.minmax(o,e,300)}else Re.seconds=e;return Re.timeout()},intervalShortcut(){Be.open("Advanced");const e=Ve.id("fourchanx-settings");return Ve("input[name=Interval]",e).focus()},set(e,t,n){let o;const a=Re[e]
|
||
;return(o=a.firstChild)?o.data=t:a.textContent=t,a.className=n??(""===t?"empty":"")},timeout:()=>(Re.seconds?(Re.set("timer",Re.seconds),Re.timeoutID=setTimeout(Re.timeout,1e3)):(Re.outdateCount++,Re.update()),Re.seconds--),update(){let e;return clearTimeout(Re.timeoutID),Re.set("timer","...","loading"),(e=Re.req)&&(delete Re.req,e.abort()),Re.req=Ve.whenModified(n.SITE.urls.threadJSON({boardID:Re.thread.board.ID,threadID:Re.thread.ID}),"ThreadUpdater",Re.cb.load,{timeout:A})},updateThreadStatus(e,t){if(Re.thread[`is${e}`]===t)return;if(Re.thread.setStatus(e,t),"Closed"===e&&Re.thread.isArchived)return;return new Xe("info",`The thread is ${"Sticky"===e?t?"now a sticky":"not a sticky anymore":t?"now closed":"not closed anymore"}.`,30)},parse(e){let o,r,s;const l=e.response.posts,d=l[0],{thread:c}=Re,{board:h}=c,u=Re.postIDs[Re.postIDs.length-1];if(l[l.length-1].no<u&&new Date(e.getResponseHeader("Last-Modified"))-c.posts.get(u).info.date<3e4)return
|
||
;n.SITE.Build.spoilerRange[h]=d.custom_spoiler,c.setStatus("Archived",!!d.archived),Re.updateThreadStatus("Sticky",!!d.sticky),Re.updateThreadStatus("Closed",!!d.closed),c.postLimit=!!d.bumplimit,c.fileLimit=!!d.imagelimit,null!=d.unique_ips&&(c.ipCount=d.unique_ips);const p=[],g=[],f=[],m=[];for(var b of l)if(o=b.no,g.push(o),b.fsize&&f.push(o),!(o<=u))if(!(s=c.posts.get(o))||s.isFetchedQuote){m.push(`${h}.${o}`);var A=n.SITE.Build.postFromObject(b,h.ID);p.push(new H(A,c,h)),Re.postID===o&&delete Re.postID}else s.resurrect();const v=[];for(o of Re.postIDs)g.includes(o)||(c.posts.get(o).kill(),v.push(`${h}.${o}`));Re.postIDs=g;const w=[];for(o of Re.fileIDs)f.includes(o)||v.includes(`${h}.${o}`)||(c.posts.get(o).kill(!0),w.push(`${h}.${o}`));if(Re.fileIDs=f,p.length){Re.set("status",`+${p.length}`,"new"),Re.outdateCount=0;const e=ee.posts?.size,n=ee.postsQuotingYou?.size;Ot.callbackNodes("Post",p),
|
||
!a.hidden&&a.hasFocus()||(t["Beep Quoting You"]&&ee.postsQuotingYou?.size>n?(Re.playBeep(),t.Beep&&Re.playBeep()):t.Beep&&ee.posts?.size>0&&0===e&&Re.playBeep());const o=t["Auto Scroll"]&&Re.scrollBG()&&Re.root.getBoundingClientRect().bottom-i.clientHeight<25;let r=null;for(s of p)Te.insert(s)||(r||(r=s.nodes.root),Ve.add(Re.root,s.nodes.root));Ve.event("PostsInserted",null,Re.root),o&&(t["Bottom Scroll"]?window.scrollTo(0,a.body.clientHeight):r&&Ke.scrollTo(r))}else Re.set("status","");return null!=d.unique_ips&&(r=Ve.id("unique-ips"))&&(r.textContent=d.unique_ips,r.previousSibling.textContent=r.previousSibling.textContent.replace(/\b(?:is|are)\b/,1===d.unique_ips?"is":"are"),r.nextSibling.textContent=r.nextSibling.textContent.replace(/\bposters?\b/,1===d.unique_ips?"poster":"posters")),Ve.event("ThreadUpdate",{404:!1,threadID:c.fullID,newPosts:m,deletedPosts:v,deletedFiles:w,postCount:d.replies+1,fileCount:d.images+!!d.fsize,ipCount:d.unique_ips})}},Be={dialog:void 0,init(){
|
||
const o=Ve.el("a",{className:"settings-link",textContent:"🔧︎",title:`${e.name} Settings`,href:"javascript:;"});Ve.on(o,"click",Be.open),Ke.addShortcut("settings",o,820);const i=this.addSection;if(i("Main",this.main),i("Filter",this.filter),i("Sauce",this.sauce),i("Advanced",this.advanced),i("Keybinds",this.keybinds),Ve.on(a,"AddSettingsSection",Be.addSection),Ve.on(a,"OpenSettings",(e=>Be.open(e.detail))),"yotsuba"===n.SITE.software&&t["Disable Native Extension"])return Ve.hasStorage?Ve.global((function(){try{const e=JSON.parse(localStorage.getItem("4chan-settings"))||{};if(e.disableAll)return;return e.disableAll=!0,localStorage.setItem("4chan-settings",JSON.stringify(e))}catch(e){return Object.defineProperty(window,"Config",{value:{disableAll:!0}})}})):Ve.global((()=>Object.defineProperty(window,"Config",{value:{disableAll:!0}})))},open(e){let t,n;if(Be.dialog)return;Ve.event("CloseMenu"),Be.dialog=t=Ve.el("div",{id:"overlay"},fe),Ve.on(Ve(".export",t),"click",Be.export),
|
||
Ve.on(Ve(".import",t),"click",Be.import),Ve.on(Ve(".reset",t),"click",Be.reset),Ve.on(Ve("input",t),"change",Be.onImport);const o=[];for(var i of Be.sections){var r=Ve.el("a",{className:`tab-${i.hyphenatedTitle}`,textContent:i.title,href:"javascript:;"});Ve.on(r,"click",Be.openSection.bind(i)),o.push(r,Ve.tn(" | ")),i.title===e&&(n=r)}return o.pop(),Ve.add(Ve(".sections-list",t),o),"none"!==e&&(n||o[0]).click(),Ve.on(Ve(".close",t),"click",Be.close),Ve.on(window,"beforeunload",Be.close),Ve.on(t,"click",(()=>{"INPUT"!==a.activeElement?.tagName&&"TEXTAREA"!==a.activeElement?.tagName&&Be.close()})),Ve.on(t.firstElementChild,"click",(e=>e.stopPropagation())),Ve.add(a.body,t),Ve.event("OpenSettings",null,t)},close(){if(Be.dialog)return a.activeElement?.blur(),Ve.rm(Be.dialog),delete Be.dialog},sections:[],addSection(e,t){"string"!=typeof e&&({title:e,open:t}=e.detail);const n=e.toLowerCase().replace(/\s+/g,"-");return Be.sections.push({title:e,hyphenatedTitle:n,open:t})},openSection(){let e
|
||
;(e=Ve(".tab-selected",Be.dialog))&&Ve.rmClass(e,"tab-selected"),Ve.addClass(Ve(`.tab-${this.hyphenatedTitle}`,Be.dialog),"tab-selected");const t=Ve("section",Be.dialog);return Ve.rmAll(t),t.className=`section-${this.hyphenatedTitle}`,this.open(t,n),t.scrollTop=0,Ve.event("OpenSettings",null,t)},warnings:{localStorage(t){if(Ve.cantSync){const n=Ve.cantSet?"save your settings":"synchronize settings between tabs";return t(Ve.el("li",{textContent:`${e.name} needs local storage to ${n}.\nEnable it on boards.${location.hostname.split(".")[1]}.org in your browser's privacy settings (may be listed as part of "local data" or "cookies").`}))}},ads:e=>Ve.onExists(i,".adg-rects > .desktop",(t=>Ve.onExists(t,"iframe",(function(){const t=Ze.to("thread",{boardID:"qa",threadID:362590});return e(Ve.el("li",le(se,null,"To protect yourself from ",le("a",{href:t,target:"_blank"},"malicious ads"),", you should ",le("a",{href:"https://github.com/gorhill/uBlock#ublock-origin",target:"_blank"
|
||
},"block ads")," on 4chan.")))}))))},main(o){let a;const i=Ve.el("fieldset",{hidden:!0},{innerHTML:"<legend>Warnings</legend><ul></ul>"}),r=function(e){return Ve.add(Ve("ul",i),e),i.hidden=!1};for(a in Be.warnings){(0,Be.warnings[a])(r)}Ve.add(o,i);const s=m(),l=m(),d=function(e,n){const o=[e];return(()=>{const e=[];for(a in n){var i=n[a];if(i instanceof Array){var r=i[1],d=Ve.el("div",{innerHTML:`<label><input type="checkbox" name="${a}">${a}</label><span class="description">: ${r}</span>`});d.dataset.name=a;var c=Ve("input",d);Ve.on(c,"change",Ve.cb.checked),Ve.on(c,"change",(function(){return this.parentNode.parentNode.dataset.checked=this.checked})),s[a]=t[a],l[a]=c;var h=i[2]||0;if(o.length<=h){var u=Ve.el("div",{className:"suboption-list"});Ve.add(o[o.length-1].lastElementChild,u),o[h]=u}else o.length>h+1&&o.splice(h+1,o.length-(h+1));e.push(Ve.add(o[h],d))}}return e})()};for(var h in c.main){var u=c.main[h],p=Ve.el("fieldset",{innerHTML:`<legend>${h}</legend>`});d(p,u),
|
||
"Posting and Captchas"===h&&Ve.add(p,Ve.el("p",{innerHTML:'For more info on captcha options and issues, see the <a href="'+e.captchaFAQ+'" target="_blank">captcha FAQ</a>.'})),Ve.add(o,p)}d(Ve('div[data-name="JSON Index"] > .suboption-list',o),c.Index),"gecko"!==Ve.engine&&(Ve('div[data-name="Remember QR Size"]',o).hidden=!0),(Ve.perProtocolSettings||"https:"!==location.protocol)&&(Ve('div[data-name="Redirect to HTTPS"]',o).hidden=!0),"crx"!==x&&(Ve('div[data-name="Work around CORB Bug"]',o).hidden=!0),Ve.get(s,(function(e){for(a in e){var t=e[a];l[a].checked=t,l[a].parentNode.parentNode.dataset.checked=t}}));const g=Ve.el("div",{innerHTML:'<button></button><span class="description">: Clear manually-hidden threads and posts on all boards. Reload the page to apply.'}),f=Ve("button",g);return Ve.get({hiddenThreads:m(),hiddenPosts:m()},(function({hiddenThreads:e,hiddenPosts:t}){let n,o,a,i,r=0;for(o in e)if(a=e[o],"boards"!==o)for(o in a.boards)n=a.boards[o],r+=Object.keys(n).length
|
||
;for(o in e.boards)n=e.boards[o],r+=Object.keys(n).length;for(o in t)if(a=t[o],"boards"!==o)for(o in a.boards)for(o in n=a.boards[o],n)i=n[o],r+=Object.keys(i).length;for(o in t.boards)for(o in n=t.boards[o],n)i=n[o],r+=Object.keys(i).length;return f.textContent=`Hidden: ${r}`})),Ve.on(f,"click",(function(){return this.textContent="Hidden: 0",Ve.get("hiddenThreads",m(),(function({hiddenThreads:e}){if(Ve.hasStorage&&"yotsuba"===n.SITE.software){let t;for(t in e["4chan.org"]?.boards)localStorage.removeItem(`4chan-hide-t-${t}`);for(t in e.boards)localStorage.removeItem(`4chan-hide-t-${t}`)}return Ve.delete(["hiddenThreads","hiddenPosts"])}))})),Ve.after(Ve('input[name="Stubs"]',o).parentNode.parentNode,g)},export(){const e=m();return Ve.extend(e,t),Ve.get(e,(function(e){return delete e.boardConfig,Be.downloadExport({version:n.VERSION,date:Date.now(),Conf:e})}))},downloadExport(t){const o=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),a=URL.createObjectURL(o),i=Ve.el("a",{
|
||
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(/^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/")),
|
||
h(["#https://desustorage.org/_/search/image/%sMD5/","#https://boards.fireden.net/_/search/image/%sMD5/","#https://foolz.fireden.net/_/search/image/%sMD5/","#//www.gif-explode.com/%URL;types:gif"])),p<"00001.00011.00035.00000"&&h(["https://whatanime.ga/?auto&url=%IMG;text:wait"]),p<"00001.00012.00000.00000"&&(null==n["Exempt Archives from Encryption"]&&l("Exempt Archives from Encryption",!1),null==n["Show New Thread Option in Threads"]&&l("Show New Thread Option in Threads",!1),n["Show Name and Subject"]&&u("#qr .persona .field {display: block !important;}"),!1===n["QR Shortcut"]&&u("#shortcut-qr {display: none;}"),!1===n["Bottom QR Link"]&&u(".qr-link-container-bottom {display: none;}")),p<"00001.00012.00000.00006"&&null!=n.sauces&&l("sauces",n.sauces.replace(/^(#?\s*)https:\/\/(?:desustorage|cuckchan)\.org\//gm,"$1https://desuarchive.org/")),
|
||
p<"00001.00012.00001.00000"&&null==n["Persistent Thread Watcher"]&&null!=n["Toggleable Thread Watcher"]&&l("Persistent Thread Watcher",!n["Toggleable Thread Watcher"]),p<"00001.00012.00003.00000")for(i of["Image Hover in Catalog","Auto Watch","Auto Watch Reply"])d(i,!1);if(p<"00001.00013.00001.00002"&&h(["#//www.bing.com/images/search?q=imgurl:%IMG&view=detailv2&iss=sbi#enterInsights"]),p<"00001.00013.00005.00000"&&(null!=n.sauces&&l("sauces",n.sauces.replace(/^(#?\s*)http:\/\/regex\.info\/exif\.cgi/gm,"$1http://exif.regex.info/exif.cgi")),h(c.sauces.match(/# Known filename formats:(?:\n.+)*|$/)[0].split("\n"))),p<"00001.00013.00007.00002"&&d("Require OP Quote Link",!0),p<"00001.00013.00008.00000"&&d("Download Link",!0),p<"00001.00013.00009.00003"&&null!=n.jsWhitelist){const e=n.jsWhitelist.split("\n");!e.includes("https://cdnjs.cloudflare.com")&&e.includes("https://cdn.mathjax.org")&&l("jsWhitelist",n.jsWhitelist+"\n\nhttps://cdnjs.cloudflare.com")}
|
||
if(p<"00001.00014.00000.00006"&&null!=n.siteSoftware&&l("siteSoftware",n.siteSoftware+"\n4cdn.org yotsuba"),p<"00001.00014.00003.00002"&&null!=n.sauces&&l("sauces",n.sauces.replace(/^(#?\s*)https:\/\/whatanime\.ga\//gm,"$1https://trace.moe/")),p<"00001.00014.00004.00004"&&(null==n.siteSoftware||/^4channel\.org yotsuba$/m.test(n.siteSoftware)||l("siteSoftware",n.siteSoftware+"\n4channel.org yotsuba")),p<"00001.00014.00005.00000"){for(var x of y.keys)if(n[x]?.boards){var{boards:k,lastChecked:I}=n[x];n[x]["4chan.org"]={boards:k,lastChecked:I},delete n[x].boards,delete n[x].lastChecked,l(x,n[x])}if(null!=n.siteSoftware&&null==n.siteProperties){const e=m();for(var C of n.siteSoftware.split("\n")){var[D,E]=C.split(" ");e[D]={software:E}}l("siteProperties",e)}}
|
||
return p<"00001.00014.00006.00006"&&null!=n.sauces&&l("sauces",n.sauces.replace(/\/\/%\$1\.deviantart\.com\/gallery\/#\/d%\$2;regexp:\/\^\\w\+_by_\(\\w\+\)-d\(\[\\da-z\]\+\)\//g,"//www.deviantart.com/gallery/#/d%$1%$2;regexp:/^\\w+_by_\\w+[_-]d([\\da-z]{6})\\b|^d([\\da-z]{6})-[\\da-z]{8}-/")),p<"00001.00014.00008.00000"&&null!=n.sauces&&l("sauces",n.sauces.replace(/https:\/\/www\.yandex\.com\/images\/search/g,"https://yandex.com/images/search")),p<"00001.00014.00009.00000"&&null!=n.sauces&&(l("sauces",n.sauces.replace(/^(#?\s*)(?:http:)?\/\/(www\.pixiv\.net|www\.deviantart\.com|imgur\.com|flickr\.com)\//gm,"$1https://$2/")),l("sauces",n.sauces.replace(/https:\/\/yandex\.com\/images\/search\?rpt=imageview&img_url=%IMG/g,"https://yandex.com/images/search?rpt=imageview&url=%IMG"))),p<"00001.00014.00009.00001"&&null!=n["Use Faster Image Host"]&&null==n.fourchanImageHost&&l("fourchanImageHost",n["Use Faster Image Host"]?"i.4cdn.org":""),
|
||
p<"00001.00014.00010.00001"&&null==n["Filter in Native Catalog"]&&l("Filter in Native Catalog",!1),p<"00001.00014.00012.00008"&&null==n.boardnav&&l("boardnav",`[ toggle-all ]\na-replace\nc-replace\ng-replace\nk-replace\nv-replace\nvg-replace\nvr-replace\nck-replace\nco-replace\nfit-replace\njp-replace\nmu-replace\nsp-replace\ntv-replace\nvp-replace\n[external-text:"FAQ","${e.faq}"]`),p<"00001.00014.00016.00001"&&null!=n.archiveLists&&l("archiveLists",n.archiveLists.replace("https://mayhemydg.github.io/archives.json/archives.json","https://nstepien.github.io/archives.json/archives.json")),
|
||
p<"00001.00014.00016.00007"&&null!=n.sauces&&l("sauces",n.sauces.replace(/https:\/\/www\.deviantart\.com\/gallery\/#\/d%\$1%\$2;regexp:\/\^\\w\+_by_\\w\+\[_-\]d\(\[\\da-z\]\{6\}\)\\b\|\^d\(\[\\da-z\]\{6\}\)-\[\\da-z\]\{8\}-\//g,'javascript:void(open("https://www.deviantart.com/"+%$1.replace(/_/g,"-")+"/art/"+parseInt(%$2,36)));regexp:/^\\w+_by_(\\w+)[_-]d([\\da-z]{6})\\b/').replace(/\/\/imgops\.com\/%URL/g,"//imgops.com/start?url=%URL")),p<"00001.00014.00017.00002"&&null!=n.jsWhitelist&&l("jsWhitelist",n.jsWhitelist+"\n\nhttps://hcaptcha.com\nhttps://*.hcaptcha.com"),p<"00001.00014.00020.00004"&&null!=n.archiveLists&&l("archiveLists",n.archiveLists.replace("https://nstepien.github.io/archives.json/archives.json","https://4chenz.github.io/archives.json/archives.json")),
|
||
p<"00001.00014.00022.00003"&&n.sauces&&(l("sauces",n.sauces.replace(/^#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(IMG|T?URL)&safe=off(?=$|;)/gm,"https://www.google.com/searchbyimage?sbisrc=4chanx&image_url=%$1&safe=off")),"00001.00014.00022.00002"!==p||/\bsbisrc=/.test(n.sauces)||l("sauces",n.sauces.replace(/^#?\s*https:\/\/lens\.google\.com\/uploadbyurl\?url=%(IMG|T?URL)(?=$|;)/m,"https://www.google.com/searchbyimage?sbisrc=4chanx&image_url=%$1&safe=off"))),s},loadSettings:(e,t)=>("2"===e.version.split(".")[0]?e=Be.convertFrom.loadletter(e):e.version!==n.VERSION&&Be.upgrade(e.Conf,e.version),Ve.clear((function(n){return n?t(n):Ve.set(e.Conf,t)}))),reset(){if(confirm("Your current settings will be entirely wiped, are you sure?"))return Ve.clear((function(e){return e?Ve(".imp-exp-result").textContent="Import failed due to an error.":confirm("Reset successful. Reload now?")?window.location.reload():void 0}))},filter(e){Ve.extend(e,{
|
||
innerHTML:'<select name="filter">\n <option value="guide">Guide</option>\n <option value="general">General</option>\n <option value="postID">Post number</option>\n <option value="name">Name</option>\n <option value="uniqueID">Unique ID</option>\n <option value="tripcode">Tripcode</option>\n <option value="capcode">Capcode</option>\n <option value="pass">Pass Date</option>\n <option value="email">Email</option>\n <option value="subject">Subject</option>\n <option value="comment">Comment</option>\n <option value="flag">Flag</option>\n <option value="filename">Filename</option>\n <option value="dimensions">Image dimensions</option>\n <option value="filesize">Filesize</option>\n <option value="MD5">Image MD5</option>\n </select>\n<div></div>\n'});const t=Ve("select",e);return Ve.on(t,"change",Be.selectFilter),Be.selectFilter.call(t)},selectFilter(){let e;const n=this.nextElementSibling;if("guide"!==(e=this.value)){if(!Ve.hasOwn(c.filter,e))return;Ve.rmAll(n)
|
||
;const o=Ve.el("textarea",{name:e,className:"field",spellcheck:!1});return Ve.on(o,"change",Ve.cb.value),void Ve.get(e,t[e],(function(t){return o.value=t[e],Ve.add(n,o)}))}return Object.keys(c.filter).filter((e=>"general"!==e)).map(((e,t)=>({innerHTML:(t?",":"")+`<wbr>${o(e)}`}))),Ve.extend(n,{
|
||
innerHTML:'<div class="warning"><code>Filter</code> is disabled.</div>\n<p>\n Use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions" target="_blank">regular expressions</a>, one per line.<br>\n Lines starting with a <code>#</code> will be ignored.<br>\n For example, <code>/weeaboo/i</code> will filter posts containing the string `<code>weeaboo</code>`, case-insensitive.<br>\n MD5 and Unique ID filtering use exact string matching, not regular expressions.\n</p>\n<ul>You can use these settings with each regular expression, separate them with semicolons:\n <li>\n Per boards, separate them with commas. It is global if not specified. Use <code>sfw</code> and <code>nsfw</code> to reference all worksafe or not-worksafe boards.<br>\n For example: <code>boards:a,jp;</code>.<br>\n To specify boards on a particular site, put the beginning of the domain and a slash character before the list.<br>\n Any initial <code>www.</code> should not be included, and all 4chan domains are considered <code>4chan.org</code>.<br>\n For example: <code>boards:4:a,jp,sama:a,z;</code>.<br>\n An asterisk can be used to specify all boards on a site.<br>\n For example: <code>boards:4:*;</code>.<br>\n </li>\n <li>\n Select boards to be excluded from the filter. The syntax is the same as for the <code>boards:</code> option above.<br>\n For example: <code>exclude:vg,v;</code>.\n </li>\n <li>\n Filter OPs only along with their threads (`only`) or replies only (`no`).<br>\n For example: <code>op:only;</code> or <code>op:no;</code>.\n </li>\n <li>\n Filter only posts with files (`only`) or only posts without files (`no`).<br>\n For example: <code>file:only;</code> or <code>file:no;</code>.\n </li>\n <li>\n Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`).<br>\n For example: <code>stub:yes;</code> or <code>stub:no;</code>.\n </li>\n <li>\n Highlight instead of hiding. You can specify a class name to use with a userstyle.<br>\n For example: <code>highlight;</code> or <code>highlight:wallpaper;</code>.\n </li>\n <li>\n Highlighted OPs will have their threads put on top of the board index by default.<br>\n For example: <code>top:yes;</code> or <code>top:no;</code>.\n </li>\n <li>\n Show a desktop notification instead of hiding.<br>\n For example: <code>notify;</code>.\n </li>\n <li>\n Filters in the "General" section apply to multiple fields, by default <code>subject,name,filename,comment</code>.<br>\n The fields can be specified with the <code>type</code> option, separated by commas.<br>\n For example: <code>type:@{filterTypes};</code>.<br>\n Types can also be combined with a <code>+</code> sign; this indicates the filter applies to the given fields joined by newlines.<br>\n For example: <code>type:filename+filesize+dimensions;</code>.<br>\n </li>\n</ul>\n'
|
||
}),Ve(".warning",n).hidden=t.Filter},sauce(e){Ve.extend(e,{
|
||
innerHTML:'<div class="warning"><code>Sauce</code> is disabled.</div>\n<input id="sauce-doc-expand" type="checkbox" hidden>\n<div id="sauce-doc">\n <label for="sauce-doc-expand">[expand]</label>\n <div>These parameters will be replaced by their corresponding values in the URL and displayed text:</div>\n <ul>\n <li><code>%IMG</code>: Full image URL for GIF, JPG, and PNG; thumbnail URL for other types.</li>\n <li><code>%URL</code>: Full image URL.</li>\n <li><code>%TURL</code>: Thumbnail URL.</li>\n <li><code>%name</code>: Original file name.</li>\n <li><code>%board</code>: Current board.</li>\n <li><code>%MD5</code>: MD5 hash in base64.</li>\n <li><code>%sMD5</code>: MD5 hash in base64 using <code>-</code> and <code>_</code>.</li>\n <li><code>%hMD5</code>: MD5 hash in hexadecimal.</li>\n <li><code>%$0</code>: Matched regular expression within the filename.</li>\n <li><code>%$1</code>, <code>%$2</code>, <code>%$3</code>, ... : Subexpressions within the matched regular expression.</li>\n <li><code>%%</code>, <code>%semi</code>: Literal <code>%</code> and <code>;</code>.</li>\n </ul>\n <div>Lines starting with a <code>#</code> will be ignored.</div>\n <div>You can specify a display text by appending <code>;text:[text]</code> to the URL.</div>\n <div>You can specify the applicable boards/sites by appending <code>;boards:[board1],[board2]</code>. See the Filter guide for details.</div>\n <div>You can specify the applicable file types by appending <code>;types:[extension1],[extension2]</code>.</div>\n <div>You can specify a regular expression the filename must match by appending <code>;regexp:[regular expression]</code>.</div>\n</div>\n<textarea hidden name="sauces" class="field" spellcheck="false"></textarea>\n'
|
||
}),Ve(".warning",e).hidden=t.Sauce;const n=Ve("textarea",e);return Ve.get("sauces",t.sauces,(function(e){return n.value=e.sauces,n.hidden=!1})),Ve.on(n,"change",Ve.cb.value)},advanced(e){let n,o;for(var a of(Ve.extend(e,{
|
||
innerHTML:'<fieldset>\n <legend>Archives</legend>\n <div class="warning" data-feature="404 Redirect"><code>404 Redirect</code> is disabled.</div>\n <select id="archive-board-select"></select>\n <table id="archive-table">\n <thead>\n <th>Thread redirection</th>\n <th>Post fetching</th>\n <th>File redirection</th>\n </thead>\n <tbody></tbody>\n </table>\n <br>\n <div>\n <b>Archive Lists</b>: Each line below should be an archive list in <a href="https://github.com/MayhemYDG/archives.json/blob/gh-pages/CONTRIBUTING.md" target="_blank">this format</a> or a URL to load an archive list from.<br>\n Archive properties can be overriden by another item with the same <code>uid</code> (or if absent, its <code>name</code>).\n </div>\n <textarea hidden name="archiveLists" class="field" spellcheck="false"></textarea>\n <button id="update-archives">Update now</button> Last updated: <time id="lastarchivecheck"></time> <label><input type="checkbox" name="archiveAutoUpdate"> Auto-update</label>\n</fieldset>\n\n<fieldset>\n <legend>External Catalog</legend>\n <div class="warning" data-feature="External Catalog"><code>External Catalog</code> is disabled. This will be used only as a fallback.</div>\n <div>\n URLs of external catalog sites, where <code>%board</code> is to be replaced by the board name.<br>\n Each URL should be followed by <code>;boards:</code> and optionally <code>;exclude:</code> and a list of supported/excluded boards in the format explained in the Filter guide.\n </div>\n <textarea hidden name="externalCatalogURLs" class="field" spellcheck="false"></textarea>\n</fieldset>\n\n<fieldset>\n <legend>Override 4chan Image Host</legend>\n <div>Change 4chan image links to this domain. Leave blank for no change.</div>\n <div><input name="fourchanImageHost" class="field" spellcheck="false" list="list-fourchanImageHost"></div>\n <datalist id="list-fourchanImageHost"></datalist>\n</fieldset>\n\n<fieldset>\n <legend>Captcha Language</legend>\n <div>Choose from <a href="https://developers.google.com/recaptcha/docs/language" target="_blank">list of language codes</a>. Leave blank to autoselect.</div>\n <div><input name="captchaLanguage" class="field" spellcheck="false"></div>\n</fieldset>\n\n<fieldset>\n <legend>Custom Board Navigation</legend>\n <div><textarea hidden name="boardnav" class="field" spellcheck="false"></textarea></div>\n <span class="note">New lines will be converted into spaces.</span><br><br>\n <div class="note">In the following examples for /g/, <code>g</code> can be changed to a different board ID (<code>a</code>, <code>b</code>, etc...), the current board (<code>current</code>), or the Twitter link (<code>@</code>).</div>\n <div>Board link: <code>g</code></div>\n <div>Archive link: <code>g-archive</code></div>\n <div>Internal archive link: <code>g-expired</code></div>\n <div>Title link: <code>g-title</code></div>\n <div>Board link (Replace with title when on that board): <code>g-replace</code></div>\n <div>Full text link: <code>g-full</code></div>\n <div>Custom text link: <code>g-text:"Install Gentoo"</code></div>\n <div>Index-only link: <code>g-index</code></div>\n <div>Catalog-only link: <code>g-catalog</code></div>\n <div>Index mode: <code>g-mode:"infinite scrolling"</code></div>\n <div>Index sort: <code>g-sort:"creation date rev"</code></div>\n <div>External link: <code>external-text:"Google","http://www.google.com"</code></div>\n <div>Open in new tab: <code>g-nt</code></div>\n <div>Combinations are possible: <code>g-index-text:"Technology Index"</code></div>\n <div>Full board list toggle: <code>toggle-all</code></div>\n <br>\n <div class="note">\n <code>[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:"Piracy"]</code><br>\n will give you<br>\n <code>[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]</code><br>\n if you are on /g/.\n </div>\n</fieldset>\n\n<fieldset>\n <legend>Time Formatting <span class="warning" data-feature="Time Formatting">is disabled.</span></legend>\n <div><input name="time" class="field" spellcheck="false">: <span class="time-preview"></span></div>\n <div>Supported <a href="http://man7.org/linux/man-pages/man1/date.1.html" target="_blank">format specifiers</a>:</div>\n <div>Day: <code>%a</code>, <code>%A</code>, <code>%d</code>, <code>%e</code></div>\n <div>Month: <code>%m</code>, <code>%b</code>, <code>%B</code></div>\n <div>Year: <code>%y</code>, <code>%Y</code></div>\n <div>Hour: <code>%k</code>, <code>%H</code>, <code>%l</code>, <code>%I</code>, <code>%p</code>, <code>%P</code></div>\n <div>Minute: <code>%M</code></div>\n <div>Second: <code>%S</code></div>\n <div>Literal <code>%</code>: <code>%%</code></div>\n <div><a href="https://www.w3.org/International/articles/language-tags/" target="_blank">Language tag</a>: <input name="timeLocale" class="field" spellcheck="false"> (needs page reload)</div>\n</fieldset>\n\n<fieldset>\n <legend>Quote Backlinks formatting <span class="warning" data-feature="Quote Backlinks">is disabled.</span></legend>\n <div><input name="backlink" class="field" spellcheck="false">: <span class="backlink-preview"></span></div>\n</fieldset>\n\n<fieldset>\n <legend>Default pasted content filename</legend>\n <div><input name="pastedname" class="field" spellcheck="false">.png</div>\n</fieldset>\n\n<fieldset>\n <legend>File Info Formatting <span class="warning" data-feature="File Info Formatting">is disabled.</span></legend>\n <div><input name="fileInfo" class="field" spellcheck="false">: <span class="file-info file-info-preview"></span></div>\n <div>Link: <code>%l</code> (truncated), <code>%L</code> (untruncated), <code>%T</code> (4chan filename)</div>\n <div>Filename: <code>%n</code> (truncated), <code>%N</code> (untruncated), <code>%t</code> (4chan filename)</div>\n <div>Download button: <code>%d</code></div>\n <div>Quick filter MD5: <code>%f</code></div>\n <div>Spoiler indicator: <code>%p</code></div>\n <div>Size: <code>%B</code> (Bytes), <code>%K</code> (KB), <code>%M</code> (MB), <code>%s</code> (4chan default)</div>\n <div>Resolution: <code>%r</code> (Displays 'PDF' for PDF files)</div>\n <div>Tag: <code>%g</code>\n <div>Literal <code>%</code>: <code>%%</code></div>\n</fieldset>\n\n<fieldset>\n <legend>Quick Reply Personas</legend>\n <textarea hidden class="personafield field" name="QR.personas" spellcheck="false"></textarea>\n <p>\n One item per line.<br>\n Items will be added in the relevant input's auto-completion list.<br>\n Password items will always be used, since there is no password input.<br>\n Lines starting with a <code>#</code> will be ignored.\n </p>\n <ul>You can use these settings with each item, separate them with semicolons:\n <li>Possible items are: <code>name</code>, <code>options</code> (or equivalently <code>email</code>), <code>subject</code> and <code>password</code>.</li>\n <li>Wrap values of items with quotes, like this: <code>options:"sage"</code>.</li>\n <li>Force values as defaults with the <code>always</code> keyword, for example: <code>options:"sage";always</code>.</li>\n <li>Select specific boards for an item, separated with commas, for example: <code>options:"sage";boards:jp;always</code>.</li>\n </ul>\n</fieldset>\n\n<fieldset>\n <legend>Unread Favicon <span class="warning" data-feature="Unread Favicon">is disabled.</span></legend>\n <select name="favicon">\n <option value="ferongr">ferongr</option>\n <option value="xat-">xat-</option>\n <option value="4chanJS">4chanJS</option>\n <option value="Mayhem">Mayhem</option>\n <option value="Original">Original</option>\n <option value="Metro">Metro</option>\n </select>\n <span class="favicon-preview"></span>\n</fieldset>\n\n<fieldset>\n <legend>Thread Updater <span class="warning" data-feature="Thread Updater">is disabled.</span></legend>\n <div>\n Interval: <input type="number" name="Interval" class="field" min="1"> seconds\n </div>\n</fieldset>\n\n<fieldset>\n <legend>Custom Cooldown Time</legend>\n <div>\n Seconds: <input type="number" name="customCooldown" class="field" min="0">\n </div>\n</fieldset>\n\n<fieldset>\n <legend>\n <label><input type="checkbox" name="Custom CSS"> Custom CSS</label>\n </legend>\n <div>For more information about customizing 4chan X's CSS, see the <a href="https://github.com/ccd0/4chan-x/wiki/Styling-Guide" target="_blank">styling guide</a>.</div>\n <button id="apply-css">Apply CSS</button>\n <textarea hidden name="usercss" class="field" spellcheck="false"></textarea>\n</fieldset>\n\n<fieldset>\n <legend>Javascript Whitelist</legend>\n <div>\n Sources from which Javascript is allowed to be loaded by <a href="http://content-security-policy.com/#source_list" target="_blank">Content Security Policy</a>.<br>\n Lines starting with a <code>#</code> will be ignored.\n </div>\n <textarea hidden name="jsWhitelist" class="field" spellcheck="false"></textarea>\n</fieldset>\n\n<fieldset>\n <legend>Known Banners</legend>\n <div>List of known banners, used for click-to-change feature.</div>\n <textarea hidden name="knownBanners" class="field" spellcheck="false"></textarea>\n</fieldset>\n'
|
||
}),u(".warning",e)))a.hidden=t[a.dataset.feature];const i=m();for(n of u("[name]",e))i[n.name]=n;Ve.on(i.archiveLists,"change",(function(){return Ve.set("lastarchivecheck",0),t.lastarchivecheck=0,Ve.id("lastarchivecheck").textContent="never"}));const r=m();for(o in i)if(n=i[o],!["Interval","Custom CSS"].includes(o)){r[o]=t[o];var s="SELECT"===n.nodeName||["checkbox","radio"].includes(n.type)||"TEXTAREA"===n.nodeName&&!(o in Be)?"change":"input";Ve.on(n,s,Ve.cb["checkbox"===n.type?"checked":"value"]),o in Be&&Ve.on(n,s,Be[o])}Ve.get(r,(function(e){for(var t in e){var o=e[t];n=i[t],n["checkbox"===n.type?"checked":"value"]=o,n.hidden=!1,t in Be&&Be[t].call(n)}}));const l=Ve.id("list-fourchanImageHost");for(var d of O.suggestions)Ve.add(l,Ve.el("option",{textContent:d}));const c=i.Interval,h=i["Custom CSS"],p=Ve("#apply-css",e);c.value=t.Interval,h.checked=t["Custom CSS"],i.usercss.disabled=!t["Custom CSS"],p.disabled=!t["Custom CSS"],Ve.on(c,"change",Re.cb.interval),
|
||
Ve.on(h,"change",Be.togglecss),Ve.on(p,"click",(()=>Ae.update()));const g=m();for(o of["archives","selectedArchives","lastarchivecheck"])g[o]=t[o];Ve.get(g,(function(n){return Ve.extend(t,n),Ze.selectArchives(),Be.addArchiveTable(e)}));const f=Ve("#archive-board-select",e),b=Ve("#archive-table",e),A=Ve("#update-archives",e);return Ve.on(f,"change",(function(){return Ve("tbody > :not([hidden])",b).hidden=!0,Ve(`tbody > .${this.value}`,b).hidden=!1})),Ve.on(A,"click",(()=>Ze.update((()=>Be.addArchiveTable(e)))))},addArchiveTable(e){let o,a;Ve("#lastarchivecheck",e).textContent=0===t.lastarchivecheck?"never":new Date(t.lastarchivecheck).toLocaleString();const i=Ve("#archive-board-select",e),r=Ve("#archive-table",e),s=Ve("tbody",e);Ve.rmAll(i),Ve.rmAll(s);const l=m();for(var{uid:d,name:c,boards:h,files:u,software:p}of t.archives)if(["fuuka","foolfuuka"].includes(p))for(o of h){a=l[o]||(l[o]={thread:[],post:[],file:[]});var g=[d??c,c];a.thread.push(g),"foolfuuka"===p&&a.post.push(g),
|
||
u.includes(o)&&a.file.push(g)}const f=[],b=[];for(o of Object.keys(l).sort()){var A=Ve.el("tr",{className:`board-${o}`});for(var v of(A.hidden=o!==n.BOARD.ID,b.push(Ve.el("option",{textContent:`/${o}/`,value:`board-${o}`,selected:o===n.BOARD.ID})),a=l[o],["thread","post","file"]))Ve.add(A,Be.addArchiveCell(o,a,v));f.push(A)}if(0!==f.length)for(o in i.hidden=r.hidden=!1,n.BOARD.ID in l||(f[0].hidden=!1),Ve.add(i,b),Ve.add(s,f),t.selectedArchives){var w=t.selectedArchives[o];for(var x in w){var y,k=w[x];(y=Ve(`select[data-boardid='${o}'][data-type='${x}']`,s))&&(y.value=JSON.stringify(k),y.value||(y.value=y.firstChild.value))}}else i.hidden=r.hidden=!0},addArchiveCell(e,t,n){const{length:o}=t[n],a=Ve.el("td",{className:"archive-cell"});if(!o)return a.textContent="--",a;const i=[];let r=0;for(;r<o;){var s=t[n][r++];i.push(Ve.el("option",{value:JSON.stringify(s[0]),textContent:s[1]}))}Ve.extend(a,{innerHTML:"<select></select>"});const l=a.firstElementChild
|
||
;return(l.disabled=1===o)||(l.setAttribute("data-boardid",e),l.setAttribute("data-type",n),Ve.on(l,"change",Be.saveSelectedArchive)),Ve.add(l,i),a},saveSelectedArchive(){return Ve.get("selectedArchives",t.selectedArchives,(({selectedArchives:e})=>((e[this.dataset.boardid]||(e[this.dataset.boardid]=m()))[this.dataset.type]=JSON.parse(this.value),Ve.set("selectedArchives",e),t.selectedArchives=e,Ze.selectArchives())))},boardnav(){return Ke.generateBoardList(this.value)},time(){return this.nextElementSibling.textContent=Ee.format(this.value,new Date)},timeLocale:()=>Be.time.call(Ve("[name=time]",Be.dialog)),backlink(){return this.nextElementSibling.textContent=this.value.replace(/%(?:id|%)/g,(e=>({"%id":"123456789","%%":"%"}[e])))},fileInfo(){const e={isReply:!0,file:{url:`//${O.host()}/g/1334437723720.jpg`,name:"d9bb2efc98dd0df141a94399ff5880b7.jpg",size:"276 KB",sizeInBytes:282624,dimensions:"1280x720",isImage:!0,isVideo:!1,isSpoiler:!0,tag:"Loop"}}
|
||
;return De.format(this.value,e,this.nextElementSibling)},favicon(){h.switch(),"thread"===n.VIEW&&t["Unread Favicon"]&&ee.update();const e=this.nextElementSibling.children,o=h,a=[o.SFW,o.unreadSFW,o.unreadSFWY,o.NSFW,o.unreadNSFW,o.unreadNSFWY,o.dead,o.unreadDead,o.unreadDeadY];for(let t=0;t<a.length;t++){var i=a[t];e[t]||Ve.add(this.nextElementSibling,Ve.el("img")),e[t].src=i}},togglecss(){return(Ve("textarea[name=usercss]",Ve.x("ancestor::fieldset[1]",this)).disabled=Ve.id("apply-css").disabled=!this.checked)?Ae.rmStyle():Ae.addStyle(),Ve.cb.checked.call(this)},keybinds(e){let n;Ve.extend(e,{
|
||
innerHTML:'<div class="warning"><code>Keybinds</code> are disabled.</div>\n<div>Allowed keys: <kbd>a-z</kbd>, <kbd>0-9</kbd>, <kbd>Ctrl</kbd>, <kbd>Shift</kbd>, <kbd>Alt</kbd>, <kbd>Meta</kbd>, <kbd>Enter</kbd>, <kbd>Esc</kbd>, <kbd>Up</kbd>, <kbd>Down</kbd>, <kbd>Right</kbd>, <kbd>Left</kbd>.</div>\n<div>Press <kbd>Backspace</kbd> to disable a keybind.</div>\n<table><tbody>\n <tr><th>Actions</th><th>Keybinds</th></tr>\n</tbody></table>\n'}),Ve(".warning",e).hidden=t.Keybinds;const o=Ve("tbody",e),a=m(),i=m();for(n in c.hotkeys){var r=c.hotkeys[n],s=Ve.el("tr",{innerHTML:`<td>${r[1]}</td><td><input class="field"></td>`}),l=Ve("input",s);l.name=n,l.spellcheck=!1,a[n]=t[n],i[n]=l,Ve.on(l,"keydown",Be.keybind),Ve.add(o,s)}return Ve.get(a,(function(e){for(n in e){var t=e[n];i[n].value=t}}))},keybind(e){let t;if(9!==e.keyCode&&(e.preventDefault(),e.stopPropagation(),null!=(t=Fe.keyCode(e))))return this.value=t,Ve.cb.value.call(this)}},Pe={init(){
|
||
if((t["Fappe Tyme"]||t["Werk Tyme"])&&["index","thread","archive"].includes(n.VIEW)){for(var e of(this.nodes={},this.enabled={fappe:!1,werk:t.werk},["Fappe","Werk"]))if(t[`${e} Tyme`]){var o=e.toLowerCase(),a=L.checkbox(o,`${e} Tyme`,!1);a.title=`${e} Tyme`,this.nodes[o]=a.firstElementChild,t[o]&&this.set(o,!0),Ve.on(this.nodes[o],"change",this.toggle.bind(this,o)),Ke.menu.addEntry({el:a,order:97});var i=Ve.el("span",{className:"indicator",textContent:e[0],title:`${e} Tyme active`});Ve.on(i,"click",(function(){const e=Ve.getOwn(Pe.nodes,this.parentNode.id.replace("shortcut-",""));return e.checked=!e.checked,Ve.event("change",null,e)})),Ke.addShortcut(o,i,410)}return t["Werk Tyme"]&&Ve.sync("werk",this.set.bind(this,"werk")),l.Post.push({name:"Fappe Tyme",cb:this.node}),l.CatalogThread.push({name:"Werk Tyme",cb:this.catalogNode})}},node(){return this.nodes.root.classList.toggle("noFile",!this.files.length)},catalogNode(){const e=this.thread.OP.files[0];if(!e)return;const t=Ve.el("div",{
|
||
textContent:e.name,className:"werkTyme-filename"});return Ve.add(this.nodes.thumb.parentNode,t)},set(e,t){return this.enabled[e]=this.nodes[e].checked=t,Ve[(t?"add":"rm")+"Class"](i,`${e}Tyme`)},toggle(e){if(this.set(e,!this.enabled[e]),"werk"===e)return Ve.cb.checked.call(this.nodes[e])}},Me={init(){let e;if(!["index","thread"].includes(n.VIEW)||!t.Sauce)return;Ve.addClass(i,"show-sauce");const o=[];for(e of t.sauces.split("\n")){var a;"#"!==e[0]&&(a=this.parseLink(e))&&o.push(a)}return o.length?(this.links=o,this.link=Ve.el("a",{target:"_blank",className:"sauce"}),l.Post.push({name:"Sauce",cb:this.node})):void 0},parseLink(e){if(!(e=e.trim()))return null;const t=m(),n=e.split(/;(?=(?:text|boards|types|regexp|sandbox):?)/);for(let e=0;e<n.length;e++){var o=n[e];if(0===e)t.url=o;else{var a=o.match(/^(\w*):?(.*)$/);t[a[1]]=a[2]}}if(t.text||(t.text=t.url.match(/(\w+)\.\w+\//)?.[1]||"?"),"boards"in t&&(t.boards=We.parseBoards(t.boards)),"regexp"in t)try{let e
|
||
;(e=t.regexp.match(/^\/(.*)\/(\w*)$/))?t.regexp=RegExp(e[1],e[2]):t.regexp=RegExp(t.regexp)}catch(t){return new Xe("warning",[Ve.tn("Invalid regexp for Sauce link:"),Ve.el("br"),Ve.tn(e),Ve.el("br"),Ve.tn(t.message)],60),null}return t},createSauceLink(e,t,o){let a,i,r;const s=o.url.match(/[^.]*$/)[0],l=m();if(Ve.extend(l,e),l.boards&&!l.boards[`${t.siteID}/${t.boardID}`]&&!l.boards[`${t.siteID}/*`])return null;if(l.types&&(r=s,!l.types.split(",").includes(r)))return null;if(l.regexp&&!(i=o.name.match(l.regexp)))return null;const d=[];for(var c of["url","text"])l[c]=l[c].replace(/%(T?URL|IMG|[sh]?MD5|board|name|%|semi|\$\d+)/g,(function(e,n){let a;if("$"===n[0]){if(!i)return e;a=i[n.slice(1)]||""}else if(a=Me.formatters[n](t,o,s),null==a)return d.push(n),"";return"url"!==c||["%","semi"].includes(n)||(/^javascript:/i.test(l.url)&&(a=JSON.stringify(a)),a=encodeURIComponent(a)),a}))
|
||
;return n.SITE.areMD5sDeferred?.(t.board)&&d.length&&!d.filter((e=>!/^.?MD5$/.test(e))).length?(a=Me.link.cloneNode(!1),a.dataset.skip="1",a):d.length?null:(a=Me.link.cloneNode(!1),a.href=l.url,a.textContent=l.text,/^javascript:/i.test(l.url)&&a.removeAttribute("target"),a)},node(){if(!this.isClone)for(var e of this.files)Me.file(this,e)},file(e,t){let n,o;const a=[],i=[];for(n of Me.links)(o=Me.createSauceLink(n,e,t))&&(a.push(Ve.tn(" "),o),o.dataset.skip&&i.push([n,o]));if(Ve.add(t.text,a),i.length){var r=new MutationObserver((function(){if(t.text.dataset.md5){for([n,o]of i){var a;(a=Me.createSauceLink(n,e,t))&&Ve.replace(o,a)}return r.disconnect()}}));return r.observe(t.text,{attributes:!0})}},formatters:{TURL:(e,t)=>t.thumbURL,URL:(e,t)=>t.url,IMG:(e,t,n)=>["gif","jpg","jpeg","png"].includes(n)?t.url:t.thumbURL,MD5:(e,t)=>t.MD5,sMD5:(e,t)=>t.MD5?.replace(/[+/=]/g,(e=>({"+":"-","/":"_","=":""}[e]))),hMD5(e,t){
|
||
if(t.MD5)return atob(t.MD5).map((e=>`0${e.charCodeAt(0).toString(16)}`.slice(-2))).join("")},board:e=>e.board.ID,name:(e,t)=>t.name,"%":()=>"%",semi:()=>";"}},Ne={init(){if(!(this.enabled=t.Gallery&&["index","thread"].includes(n.VIEW)))return;this.delay=t["Slide Delay"];const e=Ve.el("a",{href:"javascript:;",title:"Gallery",textContent:"🖼︎"});return Ve.on(e,"click",this.cb.toggle),Ke.addShortcut("gallery",e,530),l.Post.push({name:"Gallery",cb:this.node})},node(){return(()=>{const e=[];for(var o of this.files)o.thumb&&(Ne.nodes&&(Ne.generateThumb(this,o),Ne.nodes.total.textContent=Ne.images.length),t["Image Expansion"]||"tinyboard"===n.SITE.software&&Ot.jsEnabled?e.push(void 0):e.push(Ve.on(o.thumbLink,"click",Ne.cb.image)));return e})()},build(e){let o,r;const{cb:s}=Ne;t["Fullscreen Gallery"]&&(Ve.one(a,"fullscreenchange mozfullscreenchange webkitfullscreenchange",(()=>Ve.on(a,"fullscreenchange mozfullscreenchange webkitfullscreenchange",s.close))),i.mozRequestFullScreen?.(),
|
||
i.webkitRequestFullScreen?.(Element.ALLOW_KEYBOARD_INPUT)),Ne.images=[];const l=Ne.nodes={};Ne.fileIDs=m(),Ne.slideshow=!1,l.el=o=Ve.el("div",{id:"a-gallery"}),Ve.extend(o,{innerHTML:'<div class="gal-viewport">\n <span class="gal-buttons">\n <a href="javascript:;" class="gal-start" title="Start slideshow"><i></i></a>\n <a href="javascript:;" class="gal-stop" title="Stop slideshow"><i></i></a>\n <a href="javascript:;" class="menu-button"><i></i></a>\n <a href="javascript:;" class="gal-close">×</a>\n </span>\n <div class="gal-labels">\n <span class="gal-count">\n <span class="count"></span> / <span class="total"></span>\n </span>\n <a class="gal-name" target="_blank"></a>\n <span class="gal-sauce"></span>\n </div>\n <div class="gal-prev"></div>\n <div class="gal-image">\n <a href="javascript:;"><img></a>\n </div>\n <div class="gal-next"></div>\n</div>\n<div class="gal-thumbnails"></div>\n'});const d={buttons:".gal-buttons",frame:".gal-image",
|
||
name:".gal-name",count:".count",total:".total",sauce:".gal-sauce",thumbs:".gal-thumbnails",next:".gal-image a",current:".gal-image img"};for(var c in d){var h=d[c];l[c]=Ve(h,o)}const p=Ve(".menu-button",o);for(var g of(l.menu=new L.Menu("gallery"),Ve.on(l.frame,"click",s.blank),t["Mouse Wheel Volume"]&&Ve.on(l.frame,"wheel",$.wheel),Ve.on(l.next,"click",s.click),Ve.on(l.name,"click",j.download),Ve.on(Ve(".gal-prev",o),"click",s.prev),Ve.on(Ve(".gal-next",o),"click",s.next),Ve.on(Ve(".gal-start",o),"click",s.start),Ve.on(Ve(".gal-stop",o),"click",s.stop),Ve.on(Ve(".gal-close",o),"click",s.close),Ve.on(p,"click",(function(e){return l.menu.toggle(e,this,n)})),Ne.menu.createSubEntries()))g.order=0,l.menu.addEntry(g);for(var f of(Ve.on(a,"keydown",s.keybinds),t.Keybinds&&Ve.off(a,"keydown",Fe.keydown),Ve.on(window,"resize",Ne.cb.setHeight),u(n.SITE.selectors.file.thumb))){var b;if(b=ze.postFromNode(f))for(var A of b.files)if(A.thumb&&(Ne.generateThumb(b,A),
|
||
!e&&Ne.fileIDs[`${b.fullID}.${A.index}`])){var v=A.thumbLink;Ke.getTopOf(v)+v.getBoundingClientRect().height>=0&&(e=v)}}return Ve.addClass(i,"gallery-open"),Ve.add(a.body,o),l.thumbs.scrollTop=0,l.current.parentElement.scrollTop=0,e&&(r=Ve(`[href='${e.href}']`,l.thumbs)),r||(r=Ne.images[Ne.images.length-1]),r&&Ne.open(r),i.style.overflow="hidden",l.total.textContent=Ne.images.length},generateThumb(e,n){if(e.isClone||e.isHidden)return;if(!n||!n.thumb||!n.isImage&&!n.isVideo&&!t["PDF in Gallery"])return;if(Ne.fileIDs[`${e.fullID}.${n.index}`])return;Ne.fileIDs[`${e.fullID}.${n.index}`]=!0;const o=Ve.el("a",{className:"gal-thumb",href:n.url,target:"_blank",title:n.name});o.dataset.id=Ne.images.length,o.dataset.post=e.fullID,o.dataset.file=n.index;const a=n.thumb.cloneNode(!1);return a.style.cssText="",Ve.add(o,a),Ve.on(o,"click",Ne.cb.open),Ne.images.push(o),Ve.add(Ne.nodes.thumbs,o)},load(e,t){const n=e.href.match(/\w*$/),o=Ve.getOwn({webm:"video",mp4:"video",ogv:"video",pdf:"iframe"
|
||
},n)||"img",a=Ve.el(o);return Ve.extend(a.dataset,e.dataset),Ve.on(a,"error",t),a.src=e.href,a},open(e){let o,a,r;const{nodes:s}=Ne,l=+s.current.dataset.id,d=+e.dataset.id;if((o=Ne.images[l])&&Ve.rmClass(o,"gal-highlight"),Ve.addClass(e,"gal-highlight"),s.thumbs.scrollTop=e.offsetTop+e.offsetHeight/2-s.thumbs.clientHeight/2,Ne.cache?.dataset.id===""+d?(a=Ne.cache,Ve.off(a,"error",Ne.cacheError),Ve.on(a,"error",Ne.error)):a=Ne.load(e,Ne.error),Ve.off(s.current,"error",Ne.error),j.pause(s.current),Ve.replace(s.current,a),s.current=a,"VIDEO"===a.nodeName&&(a.loop=!0,$.setup(a),t.Autoplay&&a.play(),t["Show Controls"]&&j.addControls(a)),i.classList.toggle("gal-pdf","IFRAME"===a.nodeName),Ne.cb.setHeight(),s.count.textContent=+e.dataset.id+1,s.name.download=s.name.textContent=e.title,s.name.href=e.href,s.frame.scrollTop=0,s.next.focus(),Ve.rmAll(s.sauce),t.Sauce&&Me.links&&(r=n.posts.get(a.dataset.post))){const e=[];for(var c of Me.links){var h
|
||
;(h=Me.createSauceLink(c,r,r.files[+a.dataset.file]))&&e.push(Ve.tn(" "),h)}Ve.add(s.sauce,e)}if(Ne.slideshow&&(d>l||l===Ne.images.length-1&&0===d)?Ne.setupTimer():Ne.cb.stop(),t["Scroll to Post"]&&(r=n.posts.get(a.dataset.post))&&Ke.scrollTo(r.nodes.root),isNaN(l)||d===(l+1)%Ne.images.length)return Ne.cache=Ne.load(Ne.images[(d+1)%Ne.images.length],Ne.cacheError)},error(){if(this.error?.code===MediaError.MEDIA_ERR_DECODE)return new Xe("error","Corrupt or unplayable video",30);if(j.isFromArchive(this))return;const e=n.posts.get(this.dataset.post),t=e.files[+this.dataset.file];return j.error(this,e,t,null,(e=>{if(e)return Ne.images[+this.dataset.id].href=e,Ne.nodes.current===this?this.src=e:void 0}))},cacheError:()=>delete Ne.cache,cleanupTimer(){clearTimeout(Ne.timeoutID);const{current:e}=Ne.nodes;return Ve.off(e,"canplaythrough load",Ne.startTimer),Ve.off(e,"ended",Ne.cb.next)},startTimer:()=>Ne.timeoutID=setTimeout(Ne.checkTimer,Ne.delay*b),setupTimer(){Ne.cleanupTimer()
|
||
;const{current:e}=Ne.nodes,t="VIDEO"===e.nodeName;return t&&e.play(),(t?e.readyState>=4:e.complete)||"IFRAME"===e.nodeName?Ne.startTimer():Ve.on(e,t?"canplaythrough":"load",Ne.startTimer)},checkTimer(){const{current:e}=Ne.nodes;return"VIDEO"!==e.nodeName||e.paused?Ne.cb.next():(Ve.on(e,"ended",Ne.cb.next),e.loop=!1)},cb:{keybinds(e){let n;if(!(n=Fe.keyCode(e)))return;const o=(()=>{switch(n){case t.Close:case t["Open Gallery"]:return Ne.cb.close;case t["Next Gallery Image"]:return Ne.cb.next;case t["Advance Gallery"]:return Ne.cb.advance;case t["Previous Gallery Image"]:return Ne.cb.prev;case t.Pause:return Ne.cb.pause;case t.Slideshow:return Ne.cb.toggleSlideshow;case t["Rotate image anticlockwise"]:return Ne.cb.rotateLeft;case t["Rotate image clockwise"]:return Ne.cb.rotateRight;case t["Download Gallery Image"]:return Ne.cb.download}})();return o?(e.stopPropagation(),e.preventDefault(),o()):void 0},open(e){if(e&&e.preventDefault(),this)return Ne.open(this)},image(e){
|
||
return e.preventDefault(),e.stopPropagation(),Ne.build(this)},prev:()=>Ne.cb.open.call(Ne.images[+Ne.nodes.current.dataset.id-1]||Ne.images[Ne.images.length-1]),next:()=>Ne.cb.open.call(Ne.images[+Ne.nodes.current.dataset.id+1]||Ne.images[0]),click(e){if(!j.onControls(e))return e.preventDefault(),Ne.cb.advance()},advance:()=>!t.Autoplay&&Ne.nodes.current.paused?Ne.nodes.current.play():Ne.cb.next(),toggle:()=>(Ne.nodes?Ne.cb.close:Ne.build)(),blank(e){if(e.target===this)return Ne.cb.close()},toggleSlideshow:()=>Ne.cb[Ne.slideshow?"stop":"start"](),download:()=>Ve(".gal-name").click(),pause(){Ne.cb.stop();const{current:e}=Ne.nodes;if("VIDEO"===e.nodeName)return e[e.paused?"play":"pause"]()},start:()=>(Ve.addClass(Ne.nodes.buttons,"gal-playing"),Ne.slideshow=!0,Ne.setupTimer()),stop(){if(!Ne.slideshow)return;Ne.cleanupTimer();const{current:e}=Ne.nodes;return"VIDEO"===e.nodeName&&(e.loop=!0),Ve.rmClass(Ne.nodes.buttons,"gal-playing"),Ne.slideshow=!1},rotateLeft:()=>Ne.cb.rotate(270),
|
||
rotateRight:()=>Ne.cb.rotate(90),rotate:f(100,(function(e){const{current:t}=Ne.nodes;if("IFRAME"!==t.nodeName)return t.dataRotate=((t.dataRotate||0)+e)%360,t.style.transform=`rotate(${t.dataRotate}deg)`,Ne.cb.setHeight()})),close:()=>(Ve.off(Ne.nodes.current,"error",Ne.error),j.pause(Ne.nodes.current),Ve.rm(Ne.nodes.el),Ve.rmClass(i,"gallery-open"),t["Fullscreen Gallery"]&&(Ve.off(a,"fullscreenchange mozfullscreenchange webkitfullscreenchange",Ne.cb.close),a.mozCancelFullScreen?.(),a.webkitExitFullscreen?.()),delete Ne.nodes,delete Ne.fileIDs,i.style.overflow="",Ve.off(a,"keydown",Ne.cb.keybinds),t.Keybinds&&Ve.on(a,"keydown",Fe.keydown),Ve.off(window,"resize",Ne.cb.setHeight),clearTimeout(Ne.timeoutID)),setFitness(){return(this.checked?Ve.addClass:Ve.rmClass)(i,`gal-${this.name.toLowerCase().replace(/\s+/g,"-")}`)},setHeight:f(100,(function(){let e,o,a;const{current:r,frame:s}=Ne.nodes,{style:l}=r
|
||
;if(t["Stretch to Fit"]&&(e=n.posts.get(r.dataset.post)?.files[+r.dataset.file].dimensions)){const[t,n]=e.split("x");let o=s.clientWidth,d=i.clientHeight-25;(r.dataRotate||0)%180==90&&([o,d]=[d,o]),a=Math.min(d,n/t*o),l.minHeight=a+"px",l.minWidth=t/n*a+"px"}else l.minHeight=l.minWidth="";return(r.dataRotate||0)%180==90?(l.maxWidth=t["Fit Height"]?i.clientHeight-25+"px":"none",l.maxHeight=t["Fit Width"]?`${s.clientWidth}px`:"none",o=(r.clientWidth-r.clientHeight)/2,l.margin=`${o}px ${-o}px`):l.maxWidth=l.maxHeight=l.margin=""})),setDelay(){return Ne.delay=+this.value}},menu:{init(){if(!Ne.enabled)return;const e=Ve.el("span",{textContent:"Gallery",className:"gallery-link"});return Ke.menu.addEntry({el:e,order:105,subEntries:Ne.menu.createSubEntries()})},createSubEntry(e){const t=L.checkbox(e,e),n=t.firstElementChild;return["Hide Thumbnails","Fit Width","Fit Height"].includes(e)&&Ve.on(n,"change",Ne.cb.setFitness),Ve.event("change",null,n),Ve.on(n,"change",Ve.cb.checked),
|
||
["Hide Thumbnails","Fit Width","Fit Height","Stretch to Fit"].includes(e)&&Ve.on(n,"change",Ne.cb.setHeight),{el:t}},createSubEntries(){const e=["Hide Thumbnails","Fit Width","Fit Height","Stretch to Fit","Scroll to Post"].map((e=>Ne.menu.createSubEntry(e))),t=Ve.el("label",{innerHTML:'Slide Delay: <input type="number" name="Slide Delay" min="0" step="any" class="field">'}),n=t.firstElementChild;return n.value=Ne.delay,Ve.on(n,"change",Ne.cb.setDelay),Ve.on(n,"change",Ve.cb.value),e.push({el:t}),e}}},Le={init(){if(["index","thread","archive"].includes(n.VIEW)&&t.Linkify&&(t.Embedding||t["Link Title"]||t["Cover Preview"])){for(var e of(this.types=m(),this.ordered_types))this.types[e.key]=e;return t.Embedding&&"archive"!==n.VIEW&&(this.dialog=L.dialog("embedding",{innerHTML:'<div>\n <div class="move"></div>\n <a href="javascript:;" class="jump" title="Jump to post">→</a>\n <a href="javascript:;" class="close" title="Close">×</a>\n</div>\n<div id="media-embed"><div></div></div>\n'}),
|
||
this.media=Ve("#media-embed",this.dialog),Ve.one(a,"4chanXInitFinished",this.ready),Ve.on(a,"IndexRefreshInternal",(()=>n.posts.forEach((function(e){for(e of[e,...e.clones])for(var t of e.nodes.embedlinks)Le.cb.catalogRemove.call(t)}))))),t["Link Title"]?Ve.on(a,"4chanXInitFinished PostsInserted",(function(){for(var e in Le.types){var t=Le.types[e];t.title?.batchSize&&Le.flushTitles(t.title)}})):void 0}},events(e){let o,a,i;if("archive"!==n.VIEW){if(t.Embedding)for(a=0,i=e.nodes.embedlinks=u(".embedder",e.nodes.comment);o=i[a++];)Ve.on(o,"click",Le.cb.click),Ve.hasClass(o,"embedded")&&Le.cb.toggle.call(o);if(t["Cover Preview"])for(a=0,i=u(".linkify",e.nodes.comment);o=i[a++];){var r;(r=Le.services(o))&&Le.preview(r)}else;}},process(e,o){let a;if((t.Embedding||t["Link Title"]||t["Cover Preview"])&&!Ve.x("ancestor::pre",e))return(a=Le.services(e))&&(a.post=o,t.Embedding&&"archive"!==n.VIEW&&Le.embed(a),t["Link Title"]&&Le.title(a),
|
||
t["Cover Preview"]&&"archive"!==n.VIEW)?Le.preview(a):void 0},services(e){const{href:t}=e;for(var n of Le.ordered_types){var o;if(o=n.regExp.exec(t))return{key:n.key,uid:o[1],options:o[2],link:e}}},embed(e){const{key:n,uid:o,options:a,link:r,post:s}=e,{href:l}=r;Ve.addClass(r,n.toLowerCase());const d=Ve.el("a",{className:"embedder",href:"javascript:;"},{innerHTML:"(<span>un</span>embed)"}),c={key:n,uid:o,options:a,href:l};for(var h in c){var u=c[h];d.dataset[h]=u}if(Ve.on(d,"click",Le.cb.click),Ve.after(r,[Ve.tn(" "),d]),s.nodes.embedlinks.push(d),t["Auto-embed"]&&!t["Floating Embeds"]&&!s.isFetchedQuote)return Ve.hasClass(i,"catalog-mode")?Ve.addClass(d,"embed-removed"):Le.cb.toggle.call(d)},ready(){if(Ot.isThisPageLegit())return Ve.addClass(Le.dialog,"empty"),Ve.on(Ve(".close",Le.dialog),"click",Le.closeFloat),Ve.on(Ve(".move",Le.dialog),"mousedown",Le.dragEmbed),Ve.on(Ve(".jump",Le.dialog),"click",(function(){if(i.contains(Le.lastEmbed))return Ke.scrollTo(Le.lastEmbed)})),
|
||
Ve.add(a.body,Le.dialog)},closeFloat:()=>(delete Le.lastEmbed,Ve.addClass(Le.dialog,"empty"),Ve.replace(Le.media.firstChild,Ve.el("div"))),dragEmbed(){const{style:e}=Le.media;return Le.dragEmbed.mouseup?(Ve.off(a,"mouseup",Le.dragEmbed),Le.dragEmbed.mouseup=!1,void(e.pointerEvents="")):(Ve.on(a,"mouseup",Le.dragEmbed),Le.dragEmbed.mouseup=!0,e.pointerEvents="none")},title(e){let t;const{key:n,uid:o,options:a,link:i,post:r}=e;if(t=Le.types[n].title)return Ve.addClass(i,n.toLowerCase()),t.batchSize?((t.queue||(t.queue=[])).push(e),t.queue.length>=t.batchSize?Le.flushTitles(t):void 0):Ue.cache(t.api(o),(function(){return Le.cb.title(this,e)}))},flushTitles(e){let t;const{queue:n}=e;if(!n?.length)return;e.queue=[];return Ue.cache(e.api((()=>{const e=[];for(t of n)e.push(t.uid);return e})()),(function(){for(t of n)Le.cb.title(this,t)}))},preview(e){let t;const{key:n,uid:o,link:a}=e;if(t=Le.types[n].preview)return Ve.on(a,"mouseover",(function(e){const n=t.url(o),{height:i}=t,r=Ve.el("img",{
|
||
src:n,id:"ihover"});return Ve.add(Ke.hover,r),L.hover({root:a,el:r,latestEvent:e,endEvents:"mouseout click",height:i})}))},cb:{click(e){if(e.preventDefault(),Ve.hasClass(this,"embedded")||!t["Floating Embeds"]&&!Ve.hasClass(i,"catalog-mode"))return Le.cb.toggle.call(this);{let e;if(!(e=Le.media.firstChild))return;return Ve.replace(e,Le.cb.embed(this)),Le.lastEmbed=ze.postFromNode(this).nodes.root,Ve.rmClass(Le.dialog,"empty")}},toggle(){return Ve.hasClass(this,"embedded")?Ve.rm(this.nextElementSibling):Ve.after(this,Le.cb.embed(this)),Ve.toggleClass(this,"embedded")},embed(e){let t,n;const o=Ve.el("div",{className:"media-embed"});return Ve.add(o,t=(n=Le.types[e.dataset.key]).el(e)),t.style.cssText=null!=n.style?n.style:"border: none; width: 640px; height: 360px;",o},catalogRemove(){const e=Ve.hasClass(i,"catalog-mode");if(e&&Ve.hasClass(this,"embedded")||!e&&Ve.hasClass(this,"embed-removed"))return Le.cb.toggle.call(this),Ve.toggleClass(this,"embed-removed")},title(e,t){let n
|
||
;const{key:o,uid:a,options:i,link:r,post:s}=t,l=Le.types[o].title;let{status:d}=e;if([200,304].includes(d)&&l.status&&(d=l.status(e.response)[0]),d)for(var c of(n=`[${o}] ${(()=>{switch(d){case 200:case 304:return n=l.text(e.response,a),"string"==typeof n?n:n=r.textContent;case 404:return"Not Found";case 403:case 401:return"Forbidden or Private";default:return`${d}'d`}})()}`,r.dataset.original=r.textContent,r.textContent=n,s.clones))for(var h of u("a.linkify",c.nodes.comment))h.href===r.href&&(null==h.dataset.original&&(h.dataset.original=h.textContent),h.textContent=n)}},ordered_types:[{key:"audio",regExp:/^[^?#]+\.(?:mp3|m4a|oga|wav|flac)(?:[?#]|$)/i,style:"",el:e=>Ve.el("audio",{controls:!0,preload:"auto",src:e.dataset.href})},{key:"image",regExp:/^[^?#]+\.(?:gif|png|jpg|jpeg|bmp|webp)(?::\w+)?(?:[?#]|$)/i,style:"",el(e){const t=o(e.dataset.href);return Ve.el("div",{innerHTML:`<a target="_blank" href="${t}"><img src="${t}" style="max-width: 80vw; max-height: 80vh;"></a>`})}},{
|
||
key:"video",regExp:/^[^?#]+\.(?:og[gv]|webm|mp4)(?:[?#]|$)/i,style:"max-width: 80vw; max-height: 80vh;",el(e){const t=Ve.el("video",{hidden:!0,controls:!0,preload:"auto",src:e.dataset.href,loop:O.test(e.dataset.href.split("/")[2])});return Ve.on(t,"loadedmetadata",(function(){return 0===t.videoHeight&&t.parentNode?Ve.replace(t,Le.types.audio.el(e)):t.hidden=!1})),t}},{key:"PeerTube",regExp:/^(\w+:\/\/[^\/]+\/videos\/watch\/\w{8}-\w{4}-\w{4}-\w{4}-\w{12})(.*)/,el(e){let t;const n=(t=e.dataset.options.match(/[?&](start=\w+)/))?`?${t[1]}`:"",o=Ve.el("iframe",{src:e.dataset.uid.replace("/videos/watch/","/videos/embed/")+n});return o.setAttribute("allowfullscreen","true"),o}},{key:"BitChute",regExp:/^\w+:\/\/(?:www\.)?bitchute\.com\/video\/([\w\-]+)/,el(e){const t=Ve.el("iframe",{src:`https://www.bitchute.com/embed/${e.dataset.uid}/`});return t.setAttribute("allowfullscreen","true"),t}},{key:"Clyp",regExp:/^\w+:\/\/(?:www\.)?clyp\.it\/(\w{8})/,
|
||
style:"border: 0; width: 640px; height: 160px;",el:e=>Ve.el("iframe",{src:`https://clyp.it/${e.dataset.uid}/widget`}),title:{api:e=>`https://api.clyp.it/oembed?url=https://clyp.it/${e}`,text:e=>e.title}},{key:"Dailymotion",regExp:/^\w+:\/\/(?:(?:www\.)?dailymotion\.com\/(?:embed\/)?video|dai\.ly)\/([A-Za-z0-9]+)[^?]*(.*)/,el(e){let t;const n=(t=e.dataset.options.match(/[?&](start=\d+)/))?`?${t[1]}`:"",o=Ve.el("iframe",{src:`//www.dailymotion.com/embed/video/${e.dataset.uid}${n}`});return o.setAttribute("allowfullscreen","true"),o},title:{api:e=>`https://api.dailymotion.com/video/${e}`,text:e=>e.title},preview:{url:e=>`https://www.dailymotion.com/thumbnail/video/${e}`,height:240}},{key:"Gfycat",regExp:/^\w+:\/\/(?:www\.)?gfycat\.com\/(?:iframe\/)?(\w+)/,el(e){const t=Ve.el("iframe",{src:`//gfycat.com/ifr/${e.dataset.uid}`});return t.setAttribute("allowfullscreen","true"),t}},{key:"Gist",regExp:/^\w+:\/\/gist\.github\.com\/[\w\-]+\/(\w+)/,style:"",el:function(){let e=0
|
||
;return function(t){const n=Ve.el("pre",{hidden:!0,id:"gist-embed-"+e++});return Ue.cache(`https://api.github.com/gists/${t.dataset.uid}`,(function(){return n.textContent=Object.values(this.response.files)[0].content,n.className="prettyprint",Ve.global((()=>window.prettyPrint?.((function(){}),document.getElementById(document.currentScript.dataset.id).parentNode)),{id:n.id}),n.hidden=!1})),n}}(),title:{api:e=>`https://api.github.com/gists/${e}`,text({files:e}){for(var t in e)if(e.hasOwnProperty(t))return t}}},{key:"InstallGentoo",regExp:/^\w+:\/\/paste\.installgentoo\.com\/view\/(?:raw\/|download\/|embed\/)?(\w+)/,el:e=>Ve.el("iframe",{src:`https://paste.installgentoo.com/view/embed/${e.dataset.uid}`})},{key:"LiveLeak",regExp:/^\w+:\/\/(?:\w+\.)?liveleak\.com\/.*\?.*[tif]=(\w+)/,el(e){const t=Ve.el("iframe",{src:`https://www.liveleak.com/e/${e.dataset.uid}`});return t.setAttribute("allowfullscreen","true"),t}},{key:"Loopvid",
|
||
regExp:/^\w+:\/\/(?:www\.)?loopvid.appspot.com\/#?((?:pf|kd|lv|gd|gh|db|dx|nn|cp|wu|ig|ky|mf|m2|pc|1c|pi|ni|wl|ko|mm|ic|gc)\/[\w\-\/]+(?:,[\w\-\/]+)*|fc\/\w+\/\d+|https?:\/\/.+)/,style:"max-width: 80vw; max-height: 80vh;",el(e){const t=Ve.el("video",{controls:!0,preload:"auto",loop:!0});if(/^http/.test(e.dataset.uid))return Ve.add(t,Ve.el("source",{src:e.dataset.uid})),t;const[n,o,a]=e.dataset.uid.match(/(\w+)\/(.*)/),i=(()=>{switch(o){case"gd":case"wu":case"fc":return[""];case"gc":return["giant","fat","zippy"];default:return[".webm",".mp4"]}})();for(var r of a.split(","))for(var s of i){var l=`${r}${s}`,d=(()=>{switch(o){case"pf":return[`https://kastden.org/_loopvid_media/pf/${l}`,`https://web.archive.org/web/2/http://a.pomf.se/${l}`];case"kd":return[`https://kastden.org/loopvid/${l}`];case"lv":return[`https://lv.kastden.org/${l}`];case"gd":return[`https://docs.google.com/uc?export=download&id=${l}`];case"gh":return[`https://googledrive.com/host/${l}`];case"db":
|
||
return[`https://dl.dropboxusercontent.com/u/${l}`];case"dx":return[`https://dl.dropboxusercontent.com/${l}`];case"nn":return[`https://kastden.org/_loopvid_media/nn/${l}`];case"cp":return[`https://copy.com/${l}`];case"wu":return[`http://webmup.com/${l}/vid.webm`];case"ig":return[`https://i.imgur.com/${l}`];case"ky":return[`https://kastden.org/_loopvid_media/ky/${l}`];case"mf":return[`https://kastden.org/_loopvid_media/mf/${l}`,`https://web.archive.org/web/2/https://d.maxfile.ro/${l}`];case"m2":return[`https://kastden.org/_loopvid_media/m2/${l}`];case"pc":return[`https://kastden.org/_loopvid_media/pc/${l}`,`https://web.archive.org/web/2/http://a.pomf.cat/${l}`];case"1c":return[`http://b.1339.cf/${l}`];case"pi":return[`https://kastden.org/_loopvid_media/pi/${l}`,`https://web.archive.org/web/2/https://u.pomf.is/${l}`];case"ni":return[`https://kastden.org/_loopvid_media/ni/${l}`,`https://web.archive.org/web/2/https://u.nya.is/${l}`];case"wl":return[`http://webm.land/media/${l}`];case"ko":
|
||
return[`https://kordy.kastden.org/loopvid/${l}`];case"mm":return[`https://kastden.org/_loopvid_media/mm/${l}`,`https://web.archive.org/web/2/https://my.mixtape.moe/${l}`];case"ic":return[`https://media.8ch.net/file_store/${l}`];case"fc":return[`//${O.host()}/${l}.webm`];case"gc":return[`https://${s}.gfycat.com/${r}.webm`]}})();for(var c of d)Ve.add(t,Ve.el("source",{src:c}))}return t}},{key:"Openings.moe",regExp:/^\w+:\/\/openings.moe\/\?video=([^.&=]+)/,style:"width: 1280px; height: 720px; max-width: 80vw; max-height: 80vh;",el(e){const t=Ve.el("iframe",{src:`https://openings.moe/?video=${e.dataset.uid}`});return t.setAttribute("allowfullscreen","true"),t}},{key:"Pastebin",regExp:/^\w+:\/\/(?:\w+\.)?pastebin\.com\/(?!u\/)(?:[\w.]+(?:\/|\?i\=))?(\w+)/,el:e=>Ve.el("iframe",{src:`//pastebin.com/embed_iframe.php?i=${e.dataset.uid}`})},{key:"SoundCloud",regExp:/^\w+:\/\/(?:www\.)?(?:soundcloud\.com\/|snd\.sc\/)([\w\-\/]+)/,style:"border: 0; width: 500px; height: 400px;",
|
||
el:e=>Ve.el("iframe",{src:`https://w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F${encodeURIComponent(e.dataset.uid)}`}),title:{api:e=>`${location.protocol}//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F${encodeURIComponent(e)}`,text:e=>e.title}},{key:"StrawPoll",regExp:/^\w+:\/\/(?:www\.)?strawpoll\.me\/(?:embed_\d+\/)?(\d+(?:\/r)?)/,style:"border: 0; width: 600px; height: 406px;",el:e=>Ve.el("iframe",{src:`https://www.strawpoll.me/embed_1/${e.dataset.uid}`})},{key:"Streamable",regExp:/^\w+:\/\/(?:www\.)?streamable\.com\/(\w+)/,el(e){const t=Ve.el("iframe",{src:`https://streamable.com/o/${e.dataset.uid}`});return t.setAttribute("allowfullscreen","true"),t},title:{api:e=>`https://api.streamable.com/oembed?url=https://streamable.com/${e}`,text:e=>e.title}},{key:"TwitchTV",regExp:/^\w+:\/\/(?:www\.|secure\.|clips\.|m\.)?twitch\.tv\/(\w[^#\&\?]*)/,el(e){
|
||
let t,n=e.dataset.href.match(/^\w+:\/\/(?:(clips\.)|\w+\.)?twitch\.tv\/(?:\w+\/)?(clip\/)?(\w[^#\&\?]*)/);if(n[1]||n[2])t=`//clips.twitch.tv/embed?clip=${n[3]}&parent=${location.hostname}`;else{let o;n=e.dataset.uid.match(/(\w+)(?:\/(?:v\/)?(\d+))?/),t=`//player.twitch.tv/?${n[2]?`video=v${n[2]}`:`channel=${n[1]}`}&autoplay=false&parent=${location.hostname}`,(o=e.dataset.href.match(/\bt=(\w+)/))&&(t+=`&time=${o[1]}`)}const o=Ve.el("iframe",{src:t});return o.setAttribute("allowfullscreen","true"),o}},{key:"Twitter",regExp:/^\w+:\/\/(?:www\.|mobile\.)?(?:twitter|x)\.com\/(\w+\/status\/\d+)/,style:"border: none; width: 550px; height: 250px; overflow: hidden; resize: both;",el(e){const t=Ve.el("iframe");Ve.on(t,"load",(function(){return this.contentWindow.postMessage({element:"t",query:"height"},"https://twitframe.com")}));var n=function(e){if(e.source===t.contentWindow&&"https://twitframe.com"===e.origin)return Ve.off(window,"message",n),
|
||
(o||t).style.height=+Ve.minmax(e.data.height,250,.8*i.clientHeight)+"px"};if(Ve.on(window,"message",n),t.src=`https://twitframe.com/show?url=https://twitter.com/${e.dataset.uid}`,"gecko"===Ve.engine){t.style.cssText="border: none; width: 100%; height: 100%;";var o=Ve.el("div");return Ve.add(o,t),o}return t}},{key:"VidLii",regExp:/^\w+:\/\/(?:www\.)?vidlii\.com\/watch\?v=(\w{11})/,style:"border: none; width: 640px; height: 392px;",el(e){const t=Ve.el("iframe",{src:`https://www.vidlii.com/embed?v=${e.dataset.uid}&a=0`});return t.setAttribute("allowfullscreen","true"),t}},{key:"Vimeo",regExp:/^\w+:\/\/(?:www\.)?vimeo\.com\/(\d+)/,el(e){const t=Ve.el("iframe",{src:`//player.vimeo.com/video/${e.dataset.uid}?wmode=opaque`});return t.setAttribute("allowfullscreen","true"),t},title:{api:e=>`https://vimeo.com/api/oembed.json?url=https://vimeo.com/${e}`,text:e=>e.title}},{key:"Vine",regExp:/^\w+:\/\/(?:www\.)?vine\.co\/v\/(\w+)/,style:"border: none; width: 500px; height: 500px;",
|
||
el:e=>Ve.el("iframe",{src:`https://vine.co/v/${e.dataset.uid}/card`})},{key:"Vocaroo",regExp:/^\w+:\/\/(?:(?:www\.|old\.)?vocaroo\.com|voca\.ro)\/((?:i\/)?\w+)/,style:"",el(e){const t=Ve.el("iframe");return t.width=300,t.height=60,t.setAttribute("frameborder",0),t.src=`https://vocaroo.com/embed/${e.dataset.uid.replace(/^i\//,"")}?autoplay=0`,t}},{key:"YouTube",regExp:/^\w+:\/\/(?:youtu.be\/|[\w.]*youtube[\w.]*\/.*(?:v=|\bembed\/|\bv\/|live\/))([\w\-]{11})(.*)/,el(e){let t=e.dataset.options.match(/\b(?:star)?t\=(\w+)/);t&&(t=t[1]),t&&!/^\d+$/.test(t)&&(t+=" 0h0m0s",t=3600*t.match(/(\d+)h/)[1]+60*t.match(/(\d+)m/)[1]+1*t.match(/(\d+)s/)[1]);const n=Ve.el("iframe",{src:`//www.youtube.com/embed/${e.dataset.uid}?rel=0&wmode=opaque${t?"&start="+t:""}`});return n.setAttribute("allowfullscreen","true"),n},title:{api:e=>`https://www.youtube.com/oembed?url=https%3A//www.youtube.com/watch%3Fv%3D${e}&format=json`,text:e=>e.title,status(e){if(e.error){const t=e.error.match(/^(\d*)\s*(.*)/)
|
||
;return[+t[1],t[2]]}return[200,"OK"]}},preview:{url:e=>`https://img.youtube.com/vi/${e}/0.jpg`,height:360}}]},Fe={init(){if(t.Keybinds){for(var e in c.hotkeys)Ve.sync(e,Fe.sync);var n=function(){for(var e of(Ve.off(a,"4chanXInitFinished",n),Ve.on(a,"keydown",Fe.keydown),u("[accesskey]")))e.removeAttribute("accesskey")};return Ve.on(a,"4chanXInitFinished",n)}},sync:(e,n)=>t[n]=e,keydown(e){let o,a,i,r,s;if(!(o=Fe.keyCode(e)))return;const{target:l}=e;if(!["INPUT","TEXTAREA"].includes(l.nodeName)||/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(o)&&!/^Alt\+(\d|Up|Down|Left|Right)$/.test(o)){switch(["index","thread"].includes(n.VIEW)&&(i=F.getThread(),a=ze.threadFromRoot(i)),o){case t["Toggle board list"]:if(!t["Custom Board Navigation"])return;Ke.toggleBoardList();break;case t["Toggle header"]:Ke.toggleBarVisibility();break;case t["Open empty QR"]:if(!$e.postingIsEnabled)return;Fe.qr();break;case t["Open QR"]:if(!$e.postingIsEnabled||!i)return;Fe.qr(i);break;case t["Open settings"]:Be.open()
|
||
;break;case t.Close:if(Be.dialog)Be.close();else if((s=u(".notification")).length)for(var d of s)Ve(".close",d).click();else if($e.nodes&&!$e.nodes.el.hidden&&"none"!==window.getComputedStyle($e.nodes.form).display)t["Persistent QR"]?$e.hide():$e.close();else{if(!Le.lastEmbed)return;Le.closeFloat()}break;case t["Spoiler tags"]:if("TEXTAREA"!==l.nodeName)return;Fe.tags("spoiler",l);break;case t["Code tags"]:if("TEXTAREA"!==l.nodeName)return;Fe.tags("code",l);break;case t["Eqn tags"]:if("TEXTAREA"!==l.nodeName)return;Fe.tags("eqn",l);break;case t["Math tags"]:if("TEXTAREA"!==l.nodeName)return;Fe.tags("math",l);break;case t["SJIS tags"]:if("TEXTAREA"!==l.nodeName)return;Fe.tags("sjis",l);break;case t["Toggle sage"]:if(!$e.nodes||$e.nodes.el.hidden)return;Fe.sage();break;case t["Toggle Cooldown"]:if(!$e.nodes||$e.nodes.el.hidden||!Ve.hasClass($e.nodes.fileSubmit,"custom-cooldown"))return;$e.toggleCustomCooldown();break;case t["Post from URL"]:if(!$e.postingIsEnabled)return;$e.handleUrl("")
|
||
;break;case t["Add new post"]:if(!$e.postingIsEnabled)return;$e.addPost();break;case t["Submit QR"]:if(!$e.nodes||$e.nodes.el.hidden)return;$e.status()||$e.submit();break;case t.Update:switch(n.VIEW){case"thread":if(!Re.enabled)return;Re.update();break;case"index":if(!ue.enabled)return;ue.update();break;default:return}break;case t.Watch:if(!ae.enabled||!a)return;ae.toggle(a);break;case t["Update thread watcher"]:if(!ae.enabled)return;ae.buttonFetchAll();break;case t["Toggle thread watcher"]:if(!ae.enabled)return;ae.toggleWatcher();break;case t["Toggle threading"]:if(!Te.ready)return;Te.toggleThreading();break;case t["Mark thread read"]:if("index"!==n.VIEW||!a||!ne.enabled)return;ne.markRead.call(i);break;case t["Expand image"]:if(!U.enabled||!i)return;var c=ze.postFromNode(Fe.post(i));c.file&&U.toggle(c);break;case t["Expand images"]:if(!U.enabled)return;U.cb.toggleAll();break;case t["Open Gallery"]:if(!Ne.enabled)return;Ne.cb.toggle();break;case t.fappeTyme:if(!Pe.nodes?.fappe)return
|
||
;Pe.toggle("fappe");break;case t.werkTyme:if(!Pe.nodes?.werk)return;Pe.toggle("werk");break;case t["Front page"]:ue.enabled?ue.userPageNav(1):location.href=`/${n.BOARD}/`;break;case t["Open front page"]:Ve.open(`${location.origin}/${n.BOARD}/`);break;case t["Next page"]:if("index"!==n.VIEW||n.SITE.isOnePage?.(n.BOARD))return;if(ue.enabled){if(!["paged","infinite"].includes(t["Index Mode"]))return;Ve(".next button",ue.pagelist).click()}else Ve(n.SITE.selectors.nav.next)?.click();break;case t["Previous page"]:if("index"!==n.VIEW||n.SITE.isOnePage?.(n.BOARD))return;if(ue.enabled){if(!["paged","infinite"].includes(t["Index Mode"]))return;Ve(".prev button",ue.pagelist).click()}else Ve(n.SITE.selectors.nav.prev)?.click();break;case t["Search form"]:if("index"!==n.VIEW)return;var h=ue.enabled?ue.searchInput:n.SITE.selectors.searchBox?Ve(n.SITE.selectors.searchBox):void 0;if(!h)return;Ke.scrollToIfNeeded(h),h.focus();break;case t["Paged mode"]:if(!ue.enabledOn(n.BOARD))return
|
||
;location.href="index"===n.VIEW?"#paged":`/${n.BOARD}/#paged`;break;case t["Infinite scrolling mode"]:if(!ue.enabledOn(n.BOARD))return;location.href="index"===n.VIEW?"#infinite":`/${n.BOARD}/#infinite`;break;case t["All pages mode"]:if(!ue.enabledOn(n.BOARD))return;location.href="index"===n.VIEW?"#all-pages":`/${n.BOARD}/#all-pages`;break;case t["Open catalog"]:if(!(r=Ye.catalog()))return;location.href=r;break;case t["Cycle sort type"]:if(!ue.enabled)return;ue.cycleSortType();break;case t["Next thread"]:if("index"!==n.VIEW||!i)return;F.scroll(1);break;case t["Previous thread"]:if("index"!==n.VIEW||!i)return;F.scroll(-1);break;case t["Expand thread"]:if("index"!==n.VIEW||!i)return;te.toggle(a),Ke.scrollTo(i);break;case t["Open thread"]:if("index"!==n.VIEW||!i)return;Fe.open(a);break;case t["Open thread tab"]:if("index"!==n.VIEW||!i)return;Fe.open(a,!0);break;case t["Next reply"]:if(!i)return;Fe.hl(1,i);break;case t["Previous reply"]:if(!i)return;Fe.hl(-1,i);break
|
||
;case t["Deselect reply"]:if(!i)return;Fe.hl(0,i);break;case t.Hide:if(!a||!pe.db)return;Ke.scrollTo(i),pe.toggle(a);break;case t["Quick Filter MD5"]:if(!i)return;c=Fe.post(i),Fe.hl(1,i),We.quickFilterMD5.call(c,e);break;case t["Previous Post Quoting You"]:if(!i||!_.db)return;_.cb.seek("preceding");break;case t["Next Post Quoting You"]:if(!i||!_.db)return;_.cb.seek("following");break;default:return}return e.preventDefault(),e.stopPropagation()}},keyCode(e){let t=(()=>{let t;switch(t=e.keyCode){case 8:return"";case 13:return"Enter";case 27:return"Esc";case 32:return"Space";case 37:return"Left";case 38:return"Up";case 39:return"Right";case 40:return"Down";case 188:return"Comma";case 190:return"Period";case 191:return"Slash";case 59:case 186:return"Semicolon";default:return 48<=t&&t<=57||65<=t&&t<=90?String.fromCharCode(t).toLowerCase():96<=t&&t<=105?String.fromCharCode(t-48).toLowerCase():null}})();return t&&(e.altKey&&(t="Alt+"+t),e.ctrlKey&&(t="Ctrl+"+t),e.metaKey&&(t="Meta+"+t),
|
||
e.shiftKey&&(t="Shift+"+t)),t},post(e){const t=n.SITE.selectors;return Ve(`${t.postContainer}${t.highlightable.reply}.${n.SITE.classes.highlight}`,e)||Ve(`${n.SITE.isOPContainerThread?t.thread:t.postContainer}${t.highlightable.op}`,e)},qr:e=>($e.open(),null!=e&&$e.quote.call(Fe.post(e)),$e.nodes.com.focus()),tags(e,t){Y.ready((function(){const{config:t}=n.BOARD;if(!(()=>{switch(e){case"spoiler":return!!t.spoilers;case"code":return!!t.code_tags;case"math":case"eqn":return!!t.math_tags;case"sjis":return!!t.sjis_tags}})())return new Xe("warning",`[${e}] tags are not supported on /${n.BOARD}/.`,20)}));const{value:o}=t,a=t.selectionStart,i=t.selectionEnd;t.value=o.slice(0,a)+`[${e}]`+o.slice(a,i)+`[/${e}]`+o.slice(i);const r=`[${e}]`.length+i;return t.setSelectionRange(r,r),Ve.event("input",null,t)},sage(){const e=/sage/i.test($e.nodes.email.value);return $e.nodes.email.value=e?"":"sage"},open(e,t){if("index"!==n.VIEW)return;const o=ze.url("thread",e);return t?Ve.open(o):location.href=o},
|
||
hl(e,t){const o=`${n.SITE.selectors.postContainer}${n.SITE.selectors.highlightable.reply}`,{highlight:a}=n.SITE.classes,i=Ve(`${o}.${a}`,t);if(!e)return void(i&&Ve.rmClass(i,a));if(i){const{height:t}=i.getBoundingClientRect();if(Ke.getTopOf(i)>=-t&&Ke.getBottomOf(i)>=-t){let t;const{root:r}=ze.postFromNode(i).nodes,s=1===e?"following":"preceding";if(!(t=Ve.x(`${s}-sibling::${n.SITE.xpath.replyContainer}[not(@hidden) and not(child::div[@class='stub'])][1]`,r)))return;return t.matches(o)||(t=Ve(o,t)),Ke.scrollToIfNeeded(t,1===e),Ve.addClass(t,a),void Ve.rmClass(i,a)}Ve.rmClass(i,a)}const r=u(o,t);for(var s of(-1===e&&r.reverse(),r))if(1===e&&Ke.getTopOf(s)>0||-1===e&&Ke.getBottomOf(s)>0)return void Ve.addClass(s,a)}};const Oe={Cache:{init(){return Ve.on(a,"SaveCaptcha",(e=>this.saveAPI(e.detail))),Ve.on(a,"NoCaptcha",(e=>this.noCaptcha(e.detail)))},captchas:[],getCount(){return this.captchas.length},neededRaw(){
|
||
return!(this.haveCookie()||this.captchas.length||$e.req||this.submitCB)&&($e.posts.length>1||t["Auto-load captcha"]||!$e.posts[0].isOnlyQuotes()||$e.posts[0].file)},needed(){return this.neededRaw()&&Ve.event("LoadCaptcha")},prerequest(){if(t["Prerequest Captcha"])return Ve.queueTask((()=>{if(!this.prerequested&&this.neededRaw()&&!Ve.event("LoadCaptcha")&&!$e.captcha.occupied()&&$e.cooldown.seconds<=60&&$e.selected===$e.posts[$e.posts.length-1]&&!$e.selected.isOnlyQuotes()){const e="new"!==$e.selected.thread;if(!Ve.event("RequestCaptcha",{isReply:e}))return this.prerequested=!0,this.submitCB=e=>{if(e)return this.save(e)},this.updateCount()}}))},haveCookie:()=>/\b_ct=/.test(a.cookie)&&"new"!==$e.posts[0].thread,getOne(){let e;return delete this.prerequested,this.clear(),(e=this.captchas.shift())?(this.count(),e):null},request(e){if(this.submitCB||!Ve.event("RequestCaptcha",{isReply:e}))return e=>(this.submitCB=e,this.updateCount())},abort(){if(this.submitCB)return delete this.submitCB,
|
||
Ve.event("AbortCaptcha"),this.updateCount()},saveAPI(e){let t;return(t=this.submitCB)?(delete this.submitCB,t(e),this.updateCount()):this.save(e)},noCaptcha(e){let t;if(t=this.submitCB)return this.haveCookie()&&!e?.error||($e.error(e?.error||"Failed to retrieve captcha."),$e.captcha.setup(a.activeElement===$e.nodes.status)),delete this.submitCB,t(),this.updateCount()},save(e){let t;return(t=this.submitCB)?(this.abort(),void t(e)):(this.captchas.push(e),this.captchas.sort(((e,t)=>e.timeout-t.timeout)),this.count())},clear(){if(this.captchas.length){let e;const t=Date.now();for(e=0;e<this.captchas.length;e++){if(this.captchas[e].timeout>t)break}if(e)return this.captchas=this.captchas.slice(e),this.count()}},count(){return clearTimeout(this.timer),this.captchas.length&&(this.timer=setTimeout(this.clear.bind(this),this.captchas[0].timeout-Date.now())),this.updateCount()},updateCount(){return Ve.event("CaptchaCount",this.captchas.length)}},Replace:p,t:g,v2:{lifetime:12e4,init(){
|
||
if(a.cookie.indexOf("pass_enabled=1")>=0)return;if(!(this.isEnabled=!!Ve("#g-recaptcha, #captcha-forced-noscript")||!Ve.id("postForm")))return;(this.noscript=t["Force Noscript Captcha"]||!Ot.jsEnabled)&&Ve.addClass($e.nodes.el,"noscript-captcha"),Oe.cache.init(),Ve.on(a,"CaptchaCount",this.count.bind(this));const e=Ve.el("div",{className:"captcha-root"});Ve.extend(e,{innerHTML:'<div class="captcha-counter"><a href="javascript:;"></a></div>'});const n=Ve(".captcha-counter > a",e);return this.nodes={root:e,counter:n},this.count(),Ve.addClass($e.nodes.el,"has-captcha","captcha-v2"),Ve.after($e.nodes.com.parentNode,e),Ve.on(n,"click",this.toggle.bind(this)),Ve.on(n,"keydown",(e=>{if("Space"===Fe.keyCode(e))return this.toggle(),e.preventDefault(),e.stopPropagation()})),Ve.on(window,"captcha:success",(()=>Ve.queueTask((()=>this.save(!1)))))},timeouts:{},prevNeeded:0,noscriptURL(){let n,o=`https://www.google.com/recaptcha/api/fallback?k=${e.recaptchaKey}`
|
||
;return(n=t.captchaLanguage.trim())&&(o+=`&hl=${encodeURIComponent(n)}`),o},moreNeeded(){return Ve.queueTask((()=>{const e=Oe.cache.needed();return e&&!this.prevNeeded&&this.setup($e.cooldown.auto&&a.activeElement===$e.nodes.status),this.prevNeeded=e}))},toggle(){return this.nodes.container&&!this.timeouts.destroy?this.destroy():this.setup(!0,!0)},setup(e,t){if(this.isEnabled&&(Oe.cache.needed()||t)){if(e&&(Ve.addClass($e.nodes.el,"focus"),this.nodes.counter.focus()),this.timeouts.destroy)return clearTimeout(this.timeouts.destroy),delete this.timeouts.destroy,this.reload();if(!this.nodes.container)return this.nodes.container=Ve.el("div",{className:"captcha-container"}),Ve.prepend(this.nodes.root,this.nodes.container),new MutationObserver(this.afterSetup.bind(this)).observe(this.nodes.container,{childList:!0,subtree:!0}),this.noscript?this.setupNoscript():this.setupJS();Ve.queueTask((()=>{let e
|
||
;if(this.nodes.container&&a.activeElement===this.nodes.counter&&(e=Ve('iframe[src^="https://www.google.com/recaptcha/"]',this.nodes.container)))return e.focus(),$e.focus()}))}},setupNoscript(){const e=Ve.el("iframe",{id:"qr-captcha-iframe",scrolling:"no",src:this.noscriptURL()}),t=Ve.el("div"),n=Ve.el("textarea");return Ve.add(t,n),Ve.add(this.nodes.container,[e,t])},setupJS:()=>Ve.global((function(){const t=function(){const{classList:t}=document.documentElement,n=document.querySelector("#qr .captcha-container");return n.dataset.widgetID=window.grecaptcha.render(n,{sitekey:e.recaptchaKey,theme:t.contains("tomorrow")||t.contains("spooky")||t.contains("dark-captcha")?"dark":"light",callback:e=>window.dispatchEvent(new CustomEvent("captcha:success",{detail:e}))})};if(window.grecaptcha)return t();{const e=window.onRecaptchaLoaded;if(window.onRecaptchaLoaded=function(){return t(),e()},!document.head.querySelector('script[src^="https://www.google.com/recaptcha/api.js"]')){
|
||
const e=document.createElement("script");return e.src="https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoaded&render=explicit",document.head.appendChild(e)}}})),afterSetup(e){for(var t of e)for(var n of t.addedNodes){var o,a;(o=Ve.x('./descendant-or-self::iframe[starts-with(@src, "https://www.google.com/recaptcha/")]',n))&&this.setupIFrame(o),(a=Ve.x("./descendant-or-self::textarea",n))&&this.setupTextArea(a)}},setupIFrame(e){let t;if(doc.contains(e))return Oe.replace.iframe(e),Ve.addClass($e.nodes.el,"captcha-open"),this.fixQRPosition(),Ve.on(e,"load",this.fixQRPosition),a.activeElement===this.nodes.counter&&e.focus(),["blink","edge"].includes(Ve.engine)&&(t=e.parentNode,u("#qr .captcha-container > div > div:first-of-type").includes(t))?Ve.on(e.parentNode,"scroll",(function(){return this.scrollTop=0})):void 0},fixQRPosition(){if($e.nodes.el.getBoundingClientRect().bottom>doc.clientHeight)return $e.nodes.el.style.top="",$e.nodes.el.style.bottom="0px"},setupTextArea(e){
|
||
return Ve.one(e,"input",(()=>this.save(!0)))},destroy(){if(this.isEnabled)return delete this.timeouts.destroy,Ve.rmClass($e.nodes.el,"captcha-open"),this.nodes.container?(Ve.global((function(){const e=document.querySelector("#qr .captcha-container");return window.grecaptcha.reset(e.dataset.widgetID)})),Ve.rm(this.nodes.container),delete this.nodes.container):void 0},getOne:e=>Oe.cache.getOne(e),save(e,n){Oe.cache.save({response:n||Ve("textarea",this.nodes.container).value,timeout:Date.now()+this.lifetime});const o="IFRAME"===a.activeElement?.nodeName&&/https?:\/\/www\.google\.com\/recaptcha\//.test(a.activeElement.src);if(Oe.cache.needed()?(o&&($e.cooldown.auto||t["Post on Captcha Completion"]?this.nodes.counter.focus():$e.nodes.status.focus()),this.reload()):(e?this.destroy():null==this.timeouts.destroy&&(this.timeouts.destroy=setTimeout(this.destroy.bind(this),3e3)),o&&$e.nodes.status.focus()),t["Post on Captcha Completion"]&&!$e.cooldown.auto)return $e.submit()},count(){
|
||
const e=Oe.cache.getCount(),t=Oe.cache.submitCB?"...":"";return this.nodes.counter.textContent=`Captchas: ${e}${t}`,this.moreNeeded()},reload(){return Ve('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]',this.nodes.container)?(this.destroy(),this.setup(!1,!0)):Ve.global((function(){const e=document.querySelector("#qr .captcha-container");return window.grecaptcha.reset(e.dataset.widgetID)}))},occupied(){return!!this.nodes.container&&!this.timeouts.destroy}}};var $e={mimeTypes:["image/jpeg","image/png","image/gif","application/pdf","application/vnd.adobe.flash.movie","application/x-shockwave-flash","video/webm"],validExtension:/\.(jpe?g|png|gif|pdf|swf|webm)$/i,typeFromExtension:{jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",pdf:"application/pdf",swf:"application/vnd.adobe.flash.movie",webm:"video/webm"},extensionFromType:{"image/jpeg":"jpg","image/png":"png","image/gif":"gif","application/pdf":"pdf","application/vnd.adobe.flash.movie":"swf",
|
||
"application/x-shockwave-flash":"swf","video/webm":"webm"},init(){let e;if(t["Quick Reply"])return this.posts=[],Ve.on(a,"4chanXInitFinished",(()=>Y.ready($e.initReady))),l.Post.push({name:"Quick Reply",cb:this.node}),this.shortcut=e=Ve.el("a",{className:"disabled",textContent:"↩",title:"Quick Reply",href:"javascript:;"}),Ve.on(e,"click",(function(){if($e.postingIsEnabled)return t["Persistent QR"]||!$e.nodes||$e.nodes.el.hidden?($e.open(),$e.nodes.com.focus()):$e.close()})),Ke.addShortcut("qr",e,540)},initReady(){let e;const o=Ve("#g-recaptcha, #captcha-forced-noscript")?"v2":"t";$e.captcha=Oe[o],$e.postingIsEnabled=!0;const{config:i}=n.BOARD,r=(e,t)=>+(i[e]??t);if($e.min_width=r("min_image_width",1),$e.min_height=r("min_image_height",1),$e.max_width=$e.max_height=1e4,$e.max_size=r("max_filesize",4194304),$e.max_size_video=r("max_webm_filesize",$e.max_size),$e.max_comment=r("max_comment_chars",2e3),$e.max_width_video=$e.max_height_video=2048,
|
||
$e.max_duration_video=r("max_webm_duration",120),$e.forcedAnon=!!i.forced_anon,$e.spoiler=!!i.spoilers,e=Ve.id("togglePostFormLink")){const t=Ve.el("h1",{className:"qr-link-container"});Ve.extend(t,{innerHTML:`<a href="javascript:;" class="qr-link">${"thread"===n.VIEW?"Reply to Thread":"Start a Thread"}</a>`}),$e.link=t.firstElementChild,Ve.on(t.firstChild,"click",(function(){return $e.open(),$e.nodes.com.focus()})),Ve.before(e,t),e.firstElementChild.textContent="Original Form"}if("thread"===n.VIEW){let e;const t=Ve.el("div",{className:"brackets-wrap qr-link-container-bottom"});Ve.extend(t,{innerHTML:'<a href="javascript:;" class="qr-link-bottom">Reply to Thread</a>'}),Ve.on(t.firstElementChild,"click",(function(){return $e.open(),$e.nodes.com.focus()})),(e=Ve(".navLinksBot"))&&Ve.prepend(e,t)}if(Ve.on(a,"QRGetFile",$e.getFile),Ve.on(a,"QRDrawFile",$e.drawFile),Ve.on(a,"QRSetFile",$e.setFile),Ve.on(a,"paste",$e.paste),Ve.on(a,"dragover",$e.dragOver),Ve.on(a,"drop",$e.dropFile),
|
||
Ve.on(a,"dragstart dragend",$e.drag),Ve.on(a,"IndexRefreshInternal",$e.generatePostableThreadsList),Ve.on(a,"ThreadUpdate",$e.statusCheck),t["Persistent QR"])return $e.open(),t["Auto Hide QR"]?$e.hide():void 0},statusCheck(){if(!$e.nodes)return;const{thread:e}=$e.posts[0];return"new"!==e&&n.threads.get(`${n.BOARD}.${e}`).isDead?$e.abort():$e.status()},node(){if(Ve.on(this.nodes.quote,"click",$e.quote),this.isFetchedQuote)return $e.generatePostableThreadsList()},open(){if($e.nodes)$e.nodes.el.hidden&&$e.captcha.setup(),$e.nodes.el.hidden=!1,$e.unhide();else try{$e.dialog()}catch(e){return delete $e.nodes,void Ot.handleErrors({message:"Quick Reply dialog creation crashed.",error:e})}return Ve.rmClass($e.shortcut,"disabled")},close(){if(!$e.req){for(var e of($e.nodes.el.hidden=!0,$e.cleanNotifications(),$e.blur(),Ve.rmClass($e.nodes.el,"dump"),Ve.addClass($e.shortcut,"disabled"),new $e.post(!0),$e.posts.splice(0,$e.posts.length-1)))e.delete();return $e.cooldown.auto=!1,$e.status(),
|
||
$e.captcha.destroy()}$e.abort()},focus:()=>Ve.queueTask((function(){if(!$e.inBubble())return $e.hasFocus=a.activeElement&&$e.nodes.el.contains(a.activeElement),$e.nodes.el.classList.toggle("focus",$e.hasFocus)})),inBubble(){const e=u('iframe[src^="https://www.google.com/recaptcha/api2/frame"]');return e.includes(a.activeElement)||e.some((e=>"hidden"!==getComputedStyle(e).visibility&&e.getBoundingClientRect().bottom>0))},hide:()=>($e.blur(),Ve.addClass($e.nodes.el,"autohide"),$e.nodes.autohide.checked=!0),unhide:()=>(Ve.rmClass($e.nodes.el,"autohide"),$e.nodes.autohide.checked=!1),toggleHide(){return this.checked?$e.hide():$e.unhide()},blur(){if($e.nodes.el.contains(a.activeElement))return a.activeElement.blur()},toggleSJIS:e=>(e.preventDefault(),t.sjisPreview=!t.sjisPreview,Ve.set("sjisPreview",t.sjisPreview),$e.nodes.el.classList.toggle("sjis-preview",t.sjisPreview)),texPreviewShow:()=>Ve.hasClass($e.nodes.el,"tex-preview")?$e.texPreviewHide():(Ve.addClass($e.nodes.el,"tex-preview"),
|
||
$e.nodes.texPreview.textContent=$e.nodes.com.value,Ve.event("mathjax",null,$e.nodes.texPreview)),texPreviewHide:()=>Ve.rmClass($e.nodes.el,"tex-preview"),addPost(){const e=$e.nodes&&!$e.nodes.el.hidden;return $e.open(),e&&(Ve.addClass($e.nodes.el,"dump"),new $e.post(!0)),$e.nodes.com.focus()},setCustomCooldown:e=>(t.customCooldownEnabled=e,$e.cooldown.customCooldown=e,$e.nodes.customCooldown.classList.toggle("disabled",!e)),toggleCustomCooldown(){const e=Ve.hasClass($e.nodes.customCooldown,"disabled");return $e.setCustomCooldown(e),Ve.set("customCooldownEnabled",e)},error(e,t){let n;$e.open(),"string"==typeof e?n=Ve.tn(e):(n=e,n.removeAttribute("style"));const o=new Xe("warning",n);if($e.notifications.push(o),Ke.areNotificationsEnabled){if(a.hidden||!t&&!a.hasFocus()){const e=new Notification(n.textContent,{body:n.textContent,icon:h.logo});if(e.onclick=()=>window.focus(),"gecko"!==Ve.engine)return e.onclose=()=>o.close(),e.onshow=()=>setTimeout((function(){return e.onclose=null,
|
||
e.close()}),7e3)}}else if(a.hidden&&!$e.cooldown.auto)return alert(n.textContent)},connectionError:()=>Ve.el("span",{innerHTML:'Connection error while posting. [<a href="'+e.faq+'#connection-errors" target="_blank">More info</a>]'}),notifications:[],cleanNotifications(){for(var e of $e.notifications)e.close();return $e.notifications=[]},status(){let e,t;if(!$e.nodes)return;const{thread:o}=$e.posts[0];"new"!==o&&n.threads.get(`${n.BOARD}.${o}`).isDead&&(t="Dead",e=!0,$e.cooldown.auto=!1),t=$e.req?$e.req.progress:$e.cooldown.seconds||t;const{status:a}=$e.nodes;return a.value=t?$e.cooldown.auto?`Auto ${t}`:t:"Submit",a.disabled=e||!1},openPost(){if($e.open(),$e.selected.isLocked){const e=$e.posts.indexOf($e.selected);return($e.posts[e+1]||new $e.post).select(),Ve.addClass($e.nodes.el,"dump"),$e.cooldown.auto=!0}},quote(e){let t;if(e?.preventDefault(),!$e.postingIsEnabled)return;const o=a.getSelection(),i=ze.postFromNode(this),{root:r}=i.nodes,s=new Range;s.selectNode(r)
|
||
;let l=i.board.ID===n.BOARD.ID?`>>${i}\n`:`>>>/${i.board}/${i}\n`;for(let e=0,a=o.rangeCount,i=0<=a;i?e<a:e>a;i?e++:e--)try{var d,c;if(t=o.getRangeAt(e),t.compareBoundaryPoints(Range.START_TO_START,s)<0&&t.setStartBefore(r),t.compareBoundaryPoints(Range.END_TO_END,s)>0&&t.setEndAfter(r),!t.toString().trim())continue;var h=t.cloneContents(),p=t.commonAncestorContainer;for(c of(Ve.x('ancestor-or-self::*[self::s or contains(@class,"removed-spoiler")]',p)&&(Ve.prepend(h,Ve.tn("[spoiler]")),Ve.add(h,Ve.tn("[/spoiler]"))),(d=Ve.x('ancestor-or-self::pre[contains(@class,"prettyprint")]',p))&&(Ve.prepend(h,Ve.tn("[code]")),Ve.add(h,Ve.tn("[/code]"))),u(d?"br":".prettyprint br",h)))Ve.replace(c,Ve.tn("\n"));for(c of u("br",h))c!==h.lastChild&&Ve.replace(c,Ve.tn("\n>"));for(c of(n.SITE.insertTags?.(h),u(".linkify[data-original]",h)))Ve.replace(c,Ve.tn(c.dataset.original));for(c of u(".embedder",h))" "===c.previousSibling?.nodeValue&&Ve.rm(c.previousSibling),Ve.rm(c)
|
||
;l+=`>${h.textContent.trim()}\n`}catch(e){}$e.openPost();const{com:g,thread:f}=$e.nodes;g.value||(f.value=ze.threadFromNode(this));const m=$e.selected.isOnlyQuotes(),b=g.selectionStart;return g.value=g.value.slice(0,b)+l+g.value.slice(g.selectionEnd),t=b+l.length,g.setSelectionRange(t,t),g.focus(),m&&($e.selected.quotedText=g.value),$e.selected.save(g),$e.selected.save(f)},characterCount(){const e=$e.nodes.charCount,t=$e.nodes.com.value.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"_").length;return e.textContent=t,e.hidden=t<$e.max_comment/2,(t>$e.max_comment?Ve.addClass:Ve.rmClass)(e,"warning")},getFile:()=>Ve.event("QRFile",$e.selected?.file),drawFile(e){const t=$e.selected?.file;if(!t||!/^(image|video)\//.test(t.type))return;const n=/^video\//.test(t),o=Ve.el(n?"video":"img");return Ve.on(o,"error",(()=>$e.openError())),Ve.on(o,n?"loadeddata":"load",(function(){return e.target.getContext("2d").drawImage(o,0,0),URL.revokeObjectURL(o.src),Ve.event("QRImageDrawn",null,e.target)})),
|
||
o.src=URL.createObjectURL(t)},openError(){const t=Ve.el("div");return Ve.extend(t,{innerHTML:'Could not open file. [<a href="'+o(e.faq)+'#error-reading-metadata" target="_blank">More info</a>]'}),$e.error(t)},setFile(e){const{file:t,name:n,source:o}=e.detail;return null!=n&&(t.name=n),null!=o&&(t.source=o),$e.open(),$e.handleFiles([t])},drag(e){const t="dragstart"===e.type?Ve.off:Ve.on;return t(a,"dragover",$e.dragOver),t(a,"drop",$e.dropFile)},dragOver:e=>(e.preventDefault(),e.dataTransfer.dropEffect="copy"),dropFile(e){if(e.dataTransfer.files.length)return e.preventDefault(),$e.open(),$e.handleFiles(e.dataTransfer.files)},paste(e){if(!e.clipboardData.items)return;let n=null,o=-1;for(var a of e.clipboardData.items){var i;if("file"===a.kind&&(i=a.getAsFile())){var r=2*(i.size<=$e.max_size)+("image/png"===i.type);r>o&&(n=i,o=r)}}if(n){const{type:e}=n,o=new Blob([n],{type:e});o.name=`${t.pastedname}.${Ve.getOwn($e.extensionFromType,e)||"jpg"}`,$e.open(),$e.handleFiles([o]),
|
||
Ve.addClass($e.nodes.el,"dump")}},pasteFF(){const{pasteArea:e}=$e.nodes;if(!e.childNodes.length)return;const n=u("img",e);for(var o of(Ve.rmAll(e),n)){var a,{src:i}=o;if(a=i.match(/data:(image\/(\w+));base64,(.+)/)){for(var r=atob(a[3]),s=new Uint8Array(r.length),l=0,d=r.length,c=0<=d;c?l<d:l>d;c?l++:l--)s[l]=r.charCodeAt(l);var h=new Blob([s],{type:a[1]});h.name=`${t.pastedname}.${a[2]}`,$e.handleFiles([h])}else/^https?:\/\//.test(i)&&$e.handleUrl(i)}},handleUrl:e=>($e.open(),$e.selected.preventAutoPost(),Ue.permission((function(){const t=prompt("Enter a URL:",e);if(null!==t)return $e.nodes.fileButton.focus(),Ue.file(t,(function(e){return e&&!/^text\//.test(e.type)?$e.handleFiles([e]):$e.error("Can't load file.")}))}))),handleFiles(e){if(this!==$e&&(e=[...this.files],this.value=null),e.length){for(var t of($e.cleanNotifications(),e))$e.handleFile(t,e.length);return 1!==e.length&&Ve.addClass($e.nodes.el,"dump"),
|
||
a.activeElement===$e.nodes.fileButton&&Ve.hasClass($e.nodes.fileSubmit,"has-file")?$e.nodes.filename.focus():void 0}},handleFile(e,t){let n;const o=/^text\//.test(e.type);return 1===t?n=$e.selected:(n=$e.posts[$e.posts.length-1],(o?n.com||n.pasting:n.file)&&(n=new $e.post)),n[o?"pasteText":"setFile"](e)},openFileInput(){if(!$e.nodes.fileButton.disabled)return $e.nodes.fileInput.click(),$e.nodes.fileButton.focus()},generatePostableThreadsList(){if(!$e.nodes)return;const e=$e.nodes.thread,t=[e.firstElementChild];for(var o of n.BOARD.threads.keys)t.push(Ve.el("option",{value:o,textContent:`Thread ${o}`}));const a=e.value;return Ve.rmAll(e),Ve.add(e,t),e.value=a,e.value!==a?(e.value="thread"===n.VIEW?n.THREADID:"new",("thread"===n.VIEW?Ve.addClass:Ve.rmClass)($e.nodes.el,"reply-to-thread")):void 0},dialog(){let e,o,i,r;$e.nodes=i={el:e=L.dialog("qr",{
|
||
innerHTML:'<div class="move">\n <label>\n <input type="checkbox" id="autohide" title="Auto-hide">\n Quick Reply\n </label>\n <a href="javascript:;" class="close" title="Close">×</a>\n <select data-name="thread" title="Create a new thread / Reply">\n <option value="new">New thread</option>\n </select>\n</div>\n<form>\n <div class="persona">\n <button type="button" id="sjis-toggle" title="Toggle Mona font">∀</button>\n <button type="button" id="tex-preview-button" title="Preview TeX">T<sub>E</sub>X</button>\n <input name="name" data-name="name" list="list-name" placeholder="Name" class="field" size="1">\n <input name="email" data-name="email" list="list-email" placeholder="Options" class="field" size="1">\n <input name="sub" data-name="sub" list="list-sub" placeholder="Subject" class="field" size="1">\n </div>\n <div class="textarea">\n <textarea data-name="com" placeholder="Comment" class="field"></textarea>\n <span id="char-count"></span>\n <div id="tex-preview"></div>\n </div>\n <div id="dump-list-container">\n <div id="dump-list"></div>\n <a id="add-post" href="javascript:;" title="Add a post">+</a>\n </div>\n <div class="oekaki" hidden>\n <input type="button" id="qr-draw-button" value="Draw">\n <label><span>Width:</span><input name="oekaki-width" value="400" type="number" class="field" size="1"></label>\n <label><span>Height:</span><input name="oekaki-height" value="400" type="number" class="field" size="1"></label>\n <span class="oekaki-bg" title="Background Color"><input name="oekaki-bg" type="checkbox" checked><input name="oekaki-bgcolor" type="color" value="#ffffff"></span>\n </div>\n <div id="file-n-submit">\n <input type="button" id="qr-file-button" value="Files">\n <span id="qr-filename-container" class="field">\n <span id="qr-no-file">No selected file</span>\n <input id="qr-filename" data-name="filename" spellcheck="false">\n <label id="qr-spoiler-label">\n <input type="checkbox" id="qr-file-spoiler" title="Spoiler image">\n <a class="checkbox-letter">S</a>\n </label>\n <a id="qr-oekaki-button" title="Edit in Tegaki">✎︎</a>\n <a href="javascript:;" id="qr-filerm" title="Remove file">✕</a>\n <a id="url-button" title="Post from URL">🔗︎</a>\n <a hidden id="paste-area" title="Select to paste images" tabindex="-1" contentEditable="true">📋︎</a>\n <a id="custom-cooldown-button" title="Toggle custom cooldown" class="disabled">🕒︎</a>\n <a id="dump-button" title="Dump list">+</a>\n </span>\n <input type="submit">\n </div>\n <select data-default="4" name="filetag">\n <option value="0">Hentai</option>\n <option value="6">Porn</option>\n <option value="1">Japanese</option>\n <option value="2">Anime</option>\n <option value="3">Game</option>\n <option value="5">Loop</option>\n <option value="4" selected>Other</option>\n </select>\n <input type="file" multiple>\n</form>\n<datalist id="list-name"></datalist>\n<datalist id="list-email"></datalist>\n<datalist id="list-sub"></datalist>\n'
|
||
})};const s=(t,n)=>i[t]=Ve(n,e);s("move",".move"),s("autohide","#autohide"),s("close",".close"),s("thread","select"),s("form","form"),s("sjisToggle","#sjis-toggle"),s("texButton","#tex-preview-button"),s("name","[data-name=name]"),s("email","[data-name=email]"),s("sub","[data-name=sub]"),s("com","[data-name=com]"),s("charCount","#char-count"),s("texPreview","#tex-preview"),s("dumpList","#dump-list"),s("addPost","#add-post"),s("oekaki",".oekaki"),s("drawButton","#qr-draw-button"),s("fileSubmit","#file-n-submit"),s("fileButton","#qr-file-button"),s("noFile","#qr-no-file"),s("filename","#qr-filename"),s("spoiler","#qr-file-spoiler"),s("oekakiButton","#qr-oekaki-button"),s("fileRM","#qr-filerm"),s("urlButton","#url-button"),s("pasteArea","#paste-area"),s("customCooldown","#custom-cooldown-button"),s("dumpButton","#dump-button"),s("status","[type=submit]"),s("flashTag","[name=filetag]"),s("fileInput","[type=file]");const{config:l}=n.BOARD,{classList:d}=$e.nodes.el
|
||
;d.toggle("forced-anon",$e.forcedAnon),d.toggle("has-spoiler",$e.spoiler),d.toggle("has-sjis",!!l.sjis_tags),d.toggle("has-math",!!l.math_tags),d.toggle("sjis-preview",!!l.sjis_tags&&t.sjisPreview),d.toggle("show-new-thread-option",t["Show New Thread Option in Threads"]),parseInt(t.customCooldown,10)>0&&(Ve.addClass($e.nodes.fileSubmit,"custom-cooldown"),Ve.get("customCooldownEnabled",t.customCooldownEnabled,(function({customCooldownEnabled:e}){return $e.setCustomCooldown(e),Ve.sync("customCooldownEnabled",$e.setCustomCooldown)}))),$e.flagsInput(),Ve.on(i.autohide,"change",$e.toggleHide),Ve.on(i.close,"click",$e.close),Ve.on(i.status,"click",$e.submit),Ve.on(i.form,"submit",$e.submit),Ve.on(i.sjisToggle,"click",$e.toggleSJIS),Ve.on(i.texButton,"mousedown",$e.texPreviewShow),Ve.on(i.texButton,"mouseup",$e.texPreviewHide),Ve.on(i.addPost,"click",(()=>new $e.post(!0))),Ve.on(i.drawButton,"click",$e.oekaki.draw),Ve.on(i.fileButton,"click",$e.openFileInput),
|
||
Ve.on(i.noFile,"click",$e.openFileInput),Ve.on(i.filename,"focus",(function(){return Ve.addClass(this.parentNode,"focus")})),Ve.on(i.filename,"blur",(function(){return Ve.rmClass(this.parentNode,"focus")})),Ve.on(i.spoiler,"change",(()=>$e.selected.nodes.spoiler.click())),Ve.on(i.oekakiButton,"click",$e.oekaki.button),Ve.on(i.fileRM,"click",(()=>$e.selected.rmFile())),Ve.on(i.urlButton,"click",(()=>$e.handleUrl(""))),Ve.on(i.customCooldown,"click",$e.toggleCustomCooldown),Ve.on(i.dumpButton,"click",(()=>i.el.classList.toggle("dump"))),Ve.on(i.fileInput,"change",$e.handleFiles),window.addEventListener("focus",$e.focus,!0),window.addEventListener("blur",$e.focus,!0),Ve.on(a,"click",$e.focus),"gecko"!==Ve.engine||window.DataTransferItemList||(i.pasteArea.hidden=!1),new MutationObserver($e.pasteFF).observe(i.pasteArea,{childList:!0});const c=["thread","name","email","sub","com","filename","flag"];let h=0;const u=function(){return $e.selected.save(this)};for(;r=c[h++];){var p
|
||
;(p=i[r])&&(o="SELECT"===p.nodeName?"change":"input",Ve.on(i[r],o,u))}return"gecko"===Ve.engine&&t["Remember QR Size"]&&(Ve.get("QR Size","",(e=>i.com.style.cssText=e["QR Size"])),Ve.on(i.com,"mouseup",(function(e){if(0===e.button)return Ve.set("QR Size",this.style.cssText)}))),$e.generatePostableThreadsList(),$e.persona.load(),new $e.post(!0),$e.status(),$e.cooldown.setup(),$e.captcha.init(),Ve.add(a.body,e),$e.captcha.setup(),$e.oekaki.setup(),Ve.event("QRDialogCreation",null,e)},flags(){const e=Ve.el("select",{name:"flag",className:"flagSelector"}),t=(t,n)=>Ve.add(e,Ve.el("option",{value:t,textContent:n}));for(var o in t("0",n.BOARD.config.country_flags?"Geographic Location":"None"),n.BOARD.config.board_flags){t(o,n.BOARD.config.board_flags[o])}return e},flagsInput(){const{nodes:e}=$e;if(e&&(e.flag&&(Ve.rm(e.flag),delete e.flag),n.BOARD.config.board_flags)){const t=$e.flags();return t.dataset.name="flag",t.dataset.default="0",e.flag=t,Ve.add(e.form,t)}},submit(e){let o,i,r
|
||
;e?.preventDefault();const s=e?.shiftKey;if($e.req)return void $e.abort();if(Ve.forceSync("cooldowns"),$e.cooldown.seconds){if(!s)return $e.cooldown.auto=!$e.cooldown.auto,void $e.status();$e.cooldown.clear()}const l=$e.posts[0];delete l.quotedText,l.forceSave();let d=l.thread;const c=n.BOARD.threads.get(d);if("f"===n.BOARD.ID&&"new"===d&&(r=$e.nodes.flashTag.value),"new"===d?(d=null,n.BOARD.config.require_subject&&!l.sub?i="New threads require a subject.":n.BOARD.config.text_only||l.file||(i="No file selected.")):n.BOARD.threads.get(d).isClosed?i="You can't reply to this thread anymore.":l.com||l.file?l.file&&c.fileLimit&&(i="Max limit of image replies has been reached."):i="No comment or file.","r9k"!==n.BOARD.ID||l.com?.match(/[a-z-]/i)||i||(i="Original comment required."),!$e.captcha.isEnabled||$e.captcha===Oe.v2&&/\b_ct=/.test(a.cookie)&&d||i&&!s||(o=$e.captcha.getOne(!!d),$e.captcha===Oe.v2&&(o||(o=Oe.cache.request(!!d))),o||(i="No valid captcha.",
|
||
$e.captcha.setup(!$e.cooldown.auto||a.activeElement===$e.nodes.status))),$e.cleanNotifications(),i&&!s)return $e.cooldown.auto=!1,$e.status(),void $e.error(i);$e.cooldown.auto=$e.posts.length>1,l.lock();const h={MAX_FILE_SIZE:$e.max_size,mode:"regist",pwd:$e.persona.getPassword(),resto:d,name:$e.forcedAnon?void 0:l.name,email:l.email,sub:$e.forcedAnon||d?void 0:l.sub,com:l.com,upfile:l.file,filetag:r,spoiler:l.spoiler,flag:l.flag},u={responseType:"document",withCredentials:!0,onloadend:$e.response,form:Ve.formData(h)};t["Show Upload Progress"]&&(u.onprogress=function(e){if(this===$e.req?.upload)return e.loaded<e.total?$e.req.progress=`${Math.round(e.loaded/e.total*100)}%`:($e.req.isUploadFinished=!0,$e.req.progress="..."),$e.status()});let p=function(e){if(null!=e)if($e.currentCaptcha=e,$e.captcha===Oe.v2)null!=e.challenge?(u.form.append("recaptcha_challenge_field",e.challenge),
|
||
u.form.append("recaptcha_response_field",e.response)):u.form.append("g-recaptcha-response",e.response);else for(var t in e){var o=e[t];u.form.append(t,o)}return $e.req=Ve.ajax(`https://sys.${location.hostname.split(".")[1]}.org/${n.BOARD}/post`,u),$e.req.progress="..."};return"function"==typeof o?($e.req={progress:"...",abort:()=>($e.captcha===Oe.v2&&Oe.cache.abort(),p=null)},o((function(e){return $e.captcha===Oe.v2&&Oe.cache.haveCookie()?(p?.(),e?Oe.cache.save(e):void 0):e?p?.(e):(delete $e.req,l.unlock(),$e.cooldown.auto=!!Oe.cache.getCount(),$e.status())}))):p(o),$e.status()},response(){let e,o;if(this!==$e.req)return;delete $e.req;const i=$e.posts[0];if(i.unlock(),o=this.response?.getElementById("errmsg")){const e=Ve("a",o);e&&(e.target="_blank")}else(e=!this.response||"Post successful!"!==this.response.title)?(o=$e.connectionError(),$e.captcha===Oe.v2&&$e.currentCaptcha&&Oe.cache.save($e.currentCaptcha)):200!==this.status&&(o=`Error ${this.statusText} (${this.status})`)
|
||
;if(e||$e.captcha.setUsed?.(),delete $e.currentCaptcha,o){let t;if($e.errorCount=($e.errorCount||0)+1,/captcha|verification/i.test(o.textContent)||e)/mistyped/i.test(o.textContent)?o="You mistyped the CAPTCHA, or the CAPTCHA malfunctioned.":/expired/i.test(o.textContent)&&(o="This CAPTCHA is no longer valid because it has expired."),$e.errorCount>=5?$e.cooldown.auto=!1:($e.cooldown.auto=$e.captcha.isEnabled||e,$e.cooldown.addDelay(i,2));else if(o.textContent&&(t=o.textContent.match(/\d+\s+(?:minute|second)/gi))&&!/duplicate|hour/i.test(o.textContent)){$e.cooldown.auto=!/have\s+been\s+muted/i.test(o.textContent);let e=0;for(var r of t)e+=(/minute/i.test(r)?60:1)*+r.match(/\d+/)[0];/muted/i.test(o.textContent)?$e.cooldown.addMute(e):$e.cooldown.addDelay(i,e)}else $e.cooldown.auto=!1;return $e.captcha.setup($e.cooldown.auto&&[$e.nodes.status,a.body].includes(a.activeElement)),$e.status(),void $e.error(o)}delete $e.errorCount;const s=Ve("h1",this.response)
|
||
;let[l,d,c]=s.nextSibling.textContent.match(/thread:(\d+),no:(\d+)/);c=+c,d=+d||c;const h=d!==c;Ve.event("QRPostSuccessful",{boardID:n.BOARD.ID,threadID:d,postID:c}),Ve.event("QRPostSuccessful_",{boardID:n.BOARD.ID,threadID:d,postID:c});const u=$e.posts.length-1;$e.cooldown.auto=u&&h;const p=!function(){for(var e of $e.posts.slice(1))if(e.thread===i.thread)return!0}();u?(i.rm(),$e.captcha.setup(a.activeElement===$e.nodes.status)):t["Persistent QR"]?(i.rm(),t["Auto Hide QR"]?$e.hide():$e.blur()):$e.close(),$e.cleanNotifications(),t["Posting Success Notifications"]&&$e.notifications.push(new Xe("success",s.textContent,5)),$e.cooldown.add(d,c);const g=d===c?`${window.location.origin}/${n.BOARD}/thread/${d}`:d!==n.THREADID&&p&&t["Open Post in New Tab"]?`${window.location.origin}/${n.BOARD}/thread/${d}#p${c}`:void 0;if(g){const e=t["Open Post in New Tab"]||u?()=>Ve.open(g):()=>location.href=g;d===c?$e.waitForThread(g,e):e()}return $e.status()},waitForThread(e,t){let n=0;var o=function(){
|
||
return Ve.ajax(e,{onloadend(){return n++,n>=6||200===this.status?t():setTimeout(o,n*b)},responseType:"text",type:"HEAD"})};return o()},abort(){let e;return(e=$e.req)&&!$e.req.isUploadFinished&&(delete $e.req,e.abort(),$e.captcha===Oe.v2&&$e.currentCaptcha&&Oe.cache.save($e.currentCaptcha),delete $e.currentCaptcha,$e.posts[0].unlock(),$e.cooldown.auto=!1,$e.notifications.push(new Xe("info","QR upload aborted.",5))),$e.status()},cooldown:{seconds:0,delays:{deletion:60},init(){if(t["Quick Reply"])return this.data=t.cooldowns,this.changes=m(),Ve.sync("cooldowns",this.sync)},setup(){for(var e in Ve.extend($e.cooldown.delays,n.BOARD.cooldowns()),$e.cooldown.maxDelay=0,$e.cooldown.delays){var t=$e.cooldown.delays[e];["thread","thread_global"].includes(e)||($e.cooldown.maxDelay=Math.max($e.cooldown.maxDelay,t))}return $e.cooldown.isSetup=!0,$e.cooldown.start()},start(){const{data:e}=$e.cooldown
|
||
;if(t.Cooldown&&$e.cooldown.isSetup&&!$e.cooldown.isCounting&&!(Object.keys(e[n.BOARD.ID]||{}).length+Object.keys(e.global||{}).length<=0))return $e.cooldown.isCounting=!0,$e.cooldown.count()},sync:e=>($e.cooldown.data=e||m(),$e.cooldown.start()),add(e,o){if(!t.Cooldown)return;const a=Date.now(),i=n.BOARD.ID;return $e.cooldown.set(i,a,{threadID:e,postID:o}),e===o&&$e.cooldown.set("global",a,{boardID:i,threadID:e,postID:o}),$e.cooldown.save(),$e.cooldown.start()},addDelay(e,o){if(!t.Cooldown)return;const a=$e.cooldown.categorize(e);return a.delay=o,$e.cooldown.set(n.BOARD.ID,Date.now(),a),$e.cooldown.save(),$e.cooldown.start()},addMute(e){if(t.Cooldown)return $e.cooldown.set(n.BOARD.ID,Date.now(),{type:"mute",delay:e}),$e.cooldown.save(),$e.cooldown.start()},delete(e){let t;if(!$e.cooldown.data)return;const n=$e.cooldown.data[e.board.ID]||($e.cooldown.data[e.board.ID]=m());for(var o in n)t=n[o],null==t.delay&&t.threadID===e.thread.ID&&t.postID===e.ID&&$e.cooldown.set(e.board.ID,o,null)
|
||
;return $e.cooldown.save()},secondsDeletion(e){if(!$e.cooldown.data||!t.Cooldown)return 0;const n=$e.cooldown.data[e.board.ID]||m();for(var o in n){var a=n[o];if(null==a.delay&&a.threadID===e.thread.ID&&a.postID===e.ID){var i=$e.cooldown.delays.deletion-Math.floor((Date.now()-o)/b);return Math.max(i,0)}}return 0},categorize:e=>"new"===e.thread?{type:"thread"}:{type:e.file?"image":"reply",threadID:+e.thread},mergeChange:(e,t,n,o)=>o?(e[t]||(e[t]=m()))[n]=o:t in e&&(delete e[t][n],0===Object.keys(e[t]).length)?delete e[t]:void 0,set:(e,t,n)=>($e.cooldown.mergeChange($e.cooldown.data,e,t,n),($e.cooldown.changes[e]||($e.cooldown.changes[e]=m()))[t]=n),save(){const{changes:e}=$e.cooldown;if(Object.keys(e).length)return Ve.get("cooldowns",m(),(function({cooldowns:e}){for(var t in $e.cooldown.changes){for(var n in $e.cooldown.changes[t]){var o=$e.cooldown.changes[t][n];$e.cooldown.mergeChange(e,t,n,o)}$e.cooldown.data=e}return Ve.set("cooldowns",e,(()=>$e.cooldown.changes=m()))}))},
|
||
clear:()=>($e.cooldown.data=m(),$e.cooldown.changes=m(),$e.cooldown.auto=!1,$e.cooldown.update(),Ve.queueTask(Ve.delete,"cooldowns")),update(){let e;if(!$e.cooldown.isCounting)return;let o=!1,a=0;const i=Date.now(),{type:r,threadID:s}=$e.cooldown.categorize($e.posts[0]);let l=0;if(t.Cooldown)for(var d of[n.BOARD.ID,"global"]){var c=$e.cooldown.data[d]||($e.cooldown.data[d]=m());for(var h in c){e=c[h],h=+h;var u=Math.floor((i-h)/b);if(u<0)$e.cooldown.set(d,h,null),o=!0;else if(null==e.delay){var p=e.threadID!==e.postID?$e.cooldown.maxDelay:$e.cooldown.delays["global"===d?"thread_global":"thread"];if($e.cooldown.customCooldown&&(p=Math.max(p,parseInt(t.customCooldown,10))),p<=u)$e.cooldown.set(d,h,null),o=!0;else if("thread"===r==(e.threadID===e.postID)&&e.boardID!==n.BOARD.ID){var g="global"===d?"_global":"";l=Math.max(l,$e.cooldown.delays[r+g]-u),$e.cooldown.customCooldown&&(l=Math.max(l,parseInt(t.customCooldown,10)-u))}}else e.delay<=u?($e.cooldown.set(d,h,null),
|
||
o=!0):(e.type===r&&e.threadID===s||"mute"===e.type)&&(l=Math.max(l,e.delay-u))}a+=Object.keys(c).length}o&&$e.cooldown.save,a?(clearTimeout($e.cooldown.timeout),$e.cooldown.timeout=setTimeout($e.cooldown.count,b)):delete $e.cooldown.isCounting;const f=l!==$e.cooldown.seconds;return $e.cooldown.seconds=l,f?$e.status():void 0},count(){if($e.cooldown.update(),0===$e.cooldown.seconds&&$e.cooldown.auto&&!$e.req)return $e.submit()}},oekaki:{menu:{init(){if(!(["index","thread"].includes(n.VIEW)&&t.Menu&&t["Edit Link"]&&t["Quick Reply"]))return;const e=Ve.el("a",{className:"edit-link",href:"javascript:;",textContent:"Edit image"});return Ve.on(e,"click",this.editFile),Q.menu.addEntry({el:e,order:90,open(e){$e.oekaki.menu.post=e;const{file:t}=e;return $e.postingIsEnabled&&!!t&&(t.isImage||t.isVideo)}})},editFile(){const{post:e}=$e.oekaki.menu;$e.quote.call(e.nodes.post);const{isVideo:t}=e.file,n=e.file.fullImage?.currentTime||0;return Ue.file(e.file.url,(function(o){if(o){if(t){
|
||
const t=Ve.el("video");return Ve.on(t,"loadedmetadata",(function(){return Ve.on(t,"seeked",(function(){const n=Ve.el("canvas",{width:t.videoWidth,height:t.videoHeight});return n.getContext("2d").drawImage(t,0,0),n.toBlob((function(t){return t.name=e.file.name.replace(/\.\w+$/,"")+".png",$e.handleFiles([t]),$e.oekaki.edit()}))})),t.currentTime=n})),Ve.on(t,"error",(()=>$e.openError())),t.src=URL.createObjectURL(o)}return o.name=e.file.name,$e.handleFiles([o]),$e.oekaki.edit()}return $e.error("Can't load file.")}))}},setup:()=>Ve.global((function(){const{FCX:e}=window;if(e.oekakiCB=()=>window.Tegaki.flatten().toBlob((function(t){const n=`oekaki-${Date.now()}`;return e.oekakiLatest=n,document.dispatchEvent(new CustomEvent("QRSetFile",{bubbles:!0,detail:{file:t,name:e.oekakiName,source:n}}))})),window.Tegaki)return document.querySelector("#qr .oekaki").hidden=!1})),load(e){if(Ve('script[src^="//s.4cdn.org/js/tegaki"]',a.head))return e();{const t=Ve.el("link",{rel:"stylesheet",
|
||
href:`//s.4cdn.org/css/tegaki.${Date.now()}.css`}),n=Ve.el("script",{src:`//s.4cdn.org/js/tegaki.min.${Date.now()}.js`});let o=0;const i=function(){if(2==++o)return e()};return Ve.on(t,"load",i),Ve.on(n,"load",i),Ve.add(a.head,[t,n])}},draw:()=>Ve.global((function(){const{Tegaki:e,FCX:t}=window;return e.bg&&e.destroy(),t.oekakiName="tegaki.png",e.open({onDone:t.oekakiCB,onCancel:()=>e.bgColor="#ffffff",width:+document.querySelector("#qr [name=oekaki-width]").value,height:+document.querySelector("#qr [name=oekaki-height]").value,bgColor:document.querySelector("#qr [name=oekaki-bg]").checked?document.querySelector("#qr [name=oekaki-bgcolor]").value:"transparent"})})),button:()=>$e.selected.file?$e.oekaki.edit():$e.oekaki.toggle(),edit:()=>$e.oekaki.load((()=>Ve.global((function(){
|
||
const{Tegaki:e,FCX:t}=window,n=document.getElementById("qr-filename").value.replace(/\.\w+$/,"")+".png",{source:o}=document.getElementById("file-n-submit").dataset,a=e=>document.dispatchEvent(new CustomEvent("CreateNotification",{bubbles:!0,detail:{type:"warning",content:e,lifetime:20}}));var i=function(o){o&&this.removeEventListener("QRMetadata",i,!1);const r=document.getElementById("selected");if(!r?.dataset.type)return a("No file to edit.");if(!/^(image|video)\//.test(r.dataset.type))return a("Not an image.");if(!r.dataset.height)return a("Metadata not available.");if("loading"===r.dataset.height)return void r.addEventListener("QRMetadata",i,!1);e.bg&&e.destroy(),t.oekakiName=n,e.open({onDone:t.oekakiCB,onCancel:()=>e.bgColor="#ffffff",width:+r.dataset.width,height:+r.dataset.height,bgColor:"transparent"});const s=document.createElement("canvas");return s.width=s.naturalWidth=+r.dataset.width,s.height=s.naturalHeight=+r.dataset.height,s.hidden=!0,document.body.appendChild(s),
|
||
s.addEventListener("QRImageDrawn",(function(){return this.remove(),e.onOpenImageLoaded.call(this)}),!1),s.dispatchEvent(new CustomEvent("QRDrawFile",{bubbles:!0}))};return e.bg&&e.onDoneCb===t.oekakiCB&&o===t.oekakiLatest?(t.oekakiName=n,e.resume()):i()})))),toggle:()=>$e.oekaki.load((()=>$e.nodes.oekaki.hidden=!$e.nodes.oekaki.hidden))},persona:{always:{},types:{name:[],email:[],sub:[]},init(){if(t["Quick Reply"]||t.Menu&&t["Delete Link"])for(var e of t["QR.personas"].split("\n"))$e.persona.parseItem(e.trim())},parseItem(e){let t,o,a,i;if("#"===e[0])return;if(!(t=e.match(/(name|options|email|subject|password):"(.*)"/i)))return;[t,a,i]=t,e=e.replace(t,"");const r=e.match(/boards:([^;]+)/i)?.[1].toLowerCase()||"global";if("global"===r||(o=n.BOARD.ID,r.split(",").includes(o))){if("password"!==a)return"options"===a&&(a="email"),"subject"===a&&(a="sub"),/always/i.test(e)&&($e.persona.always[a]=i),$e.persona.types[a].includes(i)?void 0:$e.persona.types[a].push(i);$e.persona.pwd=i}},load(){
|
||
for(var e in $e.persona.types){var t=$e.persona.types[e],n=Ve(`#list-${e}`,$e.nodes.el);for(var o of t)o&&Ve.add(n,Ve.el("option",{textContent:o}))}},getPassword(){let e;return null!=$e.persona.pwd?$e.persona.pwd:(e=a.cookie.match(/4chan_pass=([^;]+)/))?decodeURIComponent(e[1]):""},get:e=>Ve.get("QR.persona",{},(({"QR.persona":t})=>e(t))),set:e=>Ve.get("QR.persona",{},(function({"QR.persona":t}){return t={name:e.name,flag:e.flag},Ve.set("QR.persona",t)}))},post:class{constructor(e){this.select=this.select.bind(this);const o=Ve.el("a",{className:"qr-preview",draggable:!0,href:"javascript:;"});for(var a of(Ve.extend(o,{innerHTML:'<a class="remove" title="Remove">✕</a><label class="qr-preview-spoiler"><input type="checkbox"> Spoiler</label><span></span>'}),this.nodes={el:o,rm:o.firstChild,spoiler:Ve(".qr-preview-spoiler input",o),span:o.lastChild},Ve.on(o,"click",this.select),Ve.on(this.nodes.rm,"click",(e=>(e.stopPropagation(),this.rm()))),
|
||
Ve.on(this.nodes.spoiler,"change",(e=>(this.spoiler=e.target.checked,this===$e.selected&&($e.nodes.spoiler.checked=this.spoiler),this.preventAutoPost()))),u("label",o)))Ve.on(a,"click",(e=>e.stopPropagation()));for(var i of(Ve.add($e.nodes.dumpList,o),["dragStart","dragEnter","dragLeave","dragOver","dragEnd","drop"]))Ve.on(o,i.toLowerCase(),this[i]);this.thread="thread"===n.VIEW?n.THREADID:"new";const r=$e.posts[$e.posts.length-1];$e.posts.push(this),this.nodes.spoiler.checked=this.spoiler=!(!r||!t["Remember Spoiler"])&&r.spoiler,$e.persona.get((e=>{if(this.name="name"in $e.persona.always?$e.persona.always.name:r?r.name:e.name,this.email="email"in $e.persona.always?$e.persona.always.email:"",this.sub="sub"in $e.persona.always?$e.persona.always.sub:"",$e.nodes.flag&&(this.flag=r?r.flag:e.flag&&e.flag in n.BOARD.config.board_flags?e.flag:void 0),$e.selected===this)return this.load()})),e&&this.select(),this.unlock(),$e.captcha.moreNeeded()}rm(){this.delete()
|
||
;const e=$e.posts.indexOf(this);return 1===$e.posts.length?(new $e.post(!0),Ve.rmClass($e.nodes.el,"dump")):this===$e.selected&&($e.posts[e-1]||$e.posts[e+1]).select(),$e.posts.splice(e,1),$e.status(),$e.captcha.updateThread?.()}delete(){return Ve.rm(this.nodes.el),URL.revokeObjectURL(this.URL),this.dismissErrors()}lock(e=!0){if(this.isLocked=e,this===$e.selected){for(var t of["thread","name","email","sub","com","fileButton","filename","spoiler","flag"]){var n;(n=$e.nodes[t])&&(n.disabled=e)}return this.nodes.rm.style.visibility=e?"hidden":"",this.nodes.spoiler.disabled=e,this.nodes.el.draggable=!e}}unlock(){return this.lock(!1)}select(){$e.selected&&($e.selected.nodes.el.removeAttribute("id"),$e.selected.forceSave()),$e.selected=this,this.lock(this.isLocked),this.nodes.el.id="selected";const e=this.nodes.el.getBoundingClientRect(),t=this.nodes.el.parentNode.getBoundingClientRect();return this.nodes.el.parentNode.scrollLeft+=e.left+e.width/2-t.left-t.width/2,this.load()}load(){
|
||
for(var e of["thread","name","email","sub","com","filename","flag"]){var t;(t=$e.nodes[e])&&(t.value=this[e]||t.dataset.default||"")}return("new"!==this.thread?Ve.addClass:Ve.rmClass)($e.nodes.el,"reply-to-thread"),this.showFileData(),$e.characterCount()}save(e,t){if("checkbox"===e.type)return void(this.spoiler=e.checked);const{name:n}=e.dataset;if(!["thread","name","email","sub","com","filename","flag"].includes(n))return;const o=this[n]||e.dataset.default||null;switch(this[n]=e.value||e.dataset.default||null,n){case"thread":("new"!==this.thread?Ve.addClass:Ve.rmClass)($e.nodes.el,"reply-to-thread"),$e.status(),$e.captcha.updateThread?.();break;case"com":this.updateComment();break;case"filename":if(!this.file)return;this.saveFilename(),this.updateFilename();break;case"name":case"flag":this[n]!==o&&$e.persona.set(this)}return t?void 0:this.preventAutoPost()}forceSave(){if(this===$e.selected)for(var e of["thread","name","email","sub","com","filename","spoiler","flag"]){var t
|
||
;(t=$e.nodes[e])&&this.save(t,!0)}}preventAutoPost(){if($e.cooldown.auto&&this===$e.posts[0]&&($e.cooldown.update(),$e.cooldown.seconds<=5))return $e.cooldown.auto=!1}setComment(e){return this.com=e||null,this===$e.selected&&($e.nodes.com.value=this.com),this.updateComment()}updateComment(){if(this===$e.selected&&$e.characterCount(),this.nodes.span.textContent=this.com,$e.captcha.moreNeeded(),$e.captcha===Oe.v2)return Oe.cache.prerequest()}isOnlyQuotes(){return(this.com||"").trim()===(this.quotedText||"").trim()}static rmErrored(e){e.stopPropagation();for(let e=$e.posts.length-1;e>=0;e--){var t,n=$e.posts[e];if(t=n.errors)for(var o of t)if(i.contains(o)){n.rm();break}}}error(e,t,n){const a=Ve.el("div",{className:e});Ve.extend(a,{innerHTML:t+(n?` [<a href="${o(n)}" target="_blank">More info</a>]`:"")+'<br>[<a href="javascript:;">delete post</a>] [<a href="javascript:;">delete all</a>]'}),(this.errors||(this.errors=[])).push(a);const[i,r]=u("a",a);return Ve.on(a,"click",(()=>{
|
||
if($e.posts.includes(this))return this.select()})),Ve.on(i,"click",(e=>{if(e.stopPropagation(),$e.posts.includes(this))return this.rm()})),Ve.on(r,"click",$e.post.rmErrored),$e.error(a,!0)}fileError(e,t){return this.error("file-error",`${this.filename}: ${e}`,t)}dismissErrors(e=(()=>!0)){if(this.errors)for(var t of this.errors)i.contains(t)&&e(t)&&t.parentNode.previousElementSibling.click()}setFile(e){if(this.file=e,t["Randomize Filename"]&&"f"!==n.BOARD.ID){let e;this.filename=""+(1e3*Date.now()-Math.floor(365*Math.random()*w*1e3)),(e=this.file.name.match($e.validExtension))&&(this.filename+=e[0])}else this.filename=this.file.name;return this.filesize=Ve.bytesToString(this.file.size),this.checkSize(),Ve.addClass(this.nodes.el,"has-file"),$e.captcha.moreNeeded(),URL.revokeObjectURL(this.URL),this.saveFilename(),this===$e.selected?this.showFileData():this.updateFilename(),this.rmMetadata(),this.nodes.el.dataset.type=this.file.type,this.nodes.el.style.backgroundImage="",
|
||
$e.mimeTypes.includes(this.file.type)?/^(image|video)\//.test(this.file.type)&&this.readFile():this.fileError("Unsupported file type."),this.preventAutoPost()}checkSize(){let e=$e.max_size;if(/^video\//.test(this.file.type)&&(e=Math.min(e,$e.max_size_video)),this.file.size>e)return this.fileError(`File too large (file: ${this.filesize}, max: ${Ve.bytesToString(e)}).`)}readFile(){const t=/^video\//.test(this.file.type),n=Ve.el(t?"video":"img");if(t&&!n.canPlayType(this.file.type))return;const o=t?"loadeddata":"load";var a=()=>(Ve.off(n,o,a),Ve.off(n,"error",i),this.checkDimensions(n),this.setThumbnail(n),Ve.event("QRMetadata",null,this.nodes.el)),i=()=>(Ve.off(n,o,a),Ve.off(n,"error",i),this.fileError(`Corrupt ${t?"video":"image"} or error reading metadata.`,e.faq+"#error-reading-metadata"),URL.revokeObjectURL(n.src),this.nodes.el.removeAttribute("data-height"),Ve.event("QRMetadata",null,this.nodes.el));return this.nodes.el.dataset.height="loading",Ve.on(n,o,a),Ve.on(n,"error",i),
|
||
n.src=URL.createObjectURL(this.file)}checkDimensions(e){let t,o;if("IMG"===e.tagName){if(({height:t,width:o}=e),this.nodes.el.dataset.height=t,this.nodes.el.dataset.width=o,(t>$e.max_height||o>$e.max_width)&&this.fileError(`Image too large (image: ${t}x${o}px, max: ${$e.max_height}x${$e.max_width}px)`),t<$e.min_height||o<$e.min_width)return this.fileError(`Image too small (image: ${t}x${o}px, min: ${$e.min_height}x${$e.min_width}px)`)}else{const{videoHeight:t,videoWidth:o,duration:a}=e;this.nodes.el.dataset.height=t,this.nodes.el.dataset.width=o,this.nodes.el.dataset.duration=a;const i=Math.min($e.max_height,$e.max_height_video),r=Math.min($e.max_width,$e.max_width_video);if((t>i||o>r)&&this.fileError(`Video too large (video: ${t}x${o}px, max: ${i}x${r}px)`),(t<$e.min_height||o<$e.min_width)&&this.fileError(`Video too small (video: ${t}x${o}px, min: ${$e.min_height}x${$e.min_width}px)`),
|
||
isFinite(a)?a>$e.max_duration_video&&this.fileError(`Video too long (video: ${a}s, max: ${$e.max_duration_video}s)`):this.fileError("Video lacks duration metadata (try remuxing)"),Y.noAudio(n.BOARD.ID)&&Ve.hasAudio(e))return this.fileError("Audio not allowed")}}setThumbnail(e){let t,n;const o="VIDEO"===e.tagName;let a=180*window.devicePixelRatio;if("image/gif"===this.file.type&&(a*=3),o)t=e.videoHeight,n=e.videoWidth;else if(({height:t,width:n}=e),t<a||n<a)return this.URL=e.src,void(this.nodes.el.style.backgroundImage=`url(${this.URL})`);t<=n?(n*=a/t,t=a):(t*=a/n,n=a);const i=Ve.el("canvas");return i.height=t,i.width=n,i.getContext("2d").drawImage(e,0,0,n,t),URL.revokeObjectURL(e.src),i.toBlob((e=>(this.URL=URL.createObjectURL(e),this.nodes.el.style.backgroundImage=`url(${this.URL})`)))}rmFile(){if(!this.isLocked)return delete this.file,delete this.filename,delete this.filesize,this.nodes.el.removeAttribute("title"),$e.nodes.filename.removeAttribute("title"),this.rmMetadata(),
|
||
this.nodes.el.style.backgroundImage="",Ve.rmClass(this.nodes.el,"has-file"),this.showFileData(),URL.revokeObjectURL(this.URL),this.dismissErrors((e=>Ve.hasClass(e,"file-error"))),this.preventAutoPost()}rmMetadata(){for(var e of["type","height","width","duration"])this.nodes.el.removeAttribute(`data-${e}`)}saveFilename(){if(this.file.newName=(this.filename||"").replace(/[/\\]/g,"-"),!$e.validExtension.test(this.filename))return this.file.newName+=`.${Ve.getOwn($e.extensionFromType,this.file.type)||"jpg"}`}updateFilename(){const e=`${this.filename} (${this.filesize})`;if(this.nodes.el.title=e,this===$e.selected)return $e.nodes.filename.title=e}showFileData(){return this.file?(this.updateFilename(),$e.nodes.filename.value=this.filename,Ve.addClass($e.nodes.oekaki,"has-file"),Ve.addClass($e.nodes.fileSubmit,"has-file")):(Ve.rmClass($e.nodes.oekaki,"has-file"),Ve.rmClass($e.nodes.fileSubmit,"has-file")),
|
||
null!=this.file?.source?$e.nodes.fileSubmit.dataset.source=this.file.source:$e.nodes.fileSubmit.removeAttribute("data-source"),$e.nodes.spoiler.checked=this.spoiler}pasteText(e){this.pasting=!0,this.preventAutoPost();const t=new FileReader;return t.onload=e=>{const{result:t}=e.target;return this.setComment(this.com?`${this.com}\n${t}`:t),delete this.pasting},t.readAsText(e)}dragStart(e){const{left:t,top:n}=this.getBoundingClientRect();return e.dataTransfer.setDragImage(this,e.clientX-t,e.clientY-n),Ve.addClass(this,"drag")}dragEnd(){return Ve.rmClass(this,"drag")}dragEnter(){return Ve.addClass(this,"over")}dragLeave(){return Ve.rmClass(this,"over")}dragOver(e){return e.preventDefault(),e.dataTransfer.dropEffect="move"}drop(){if(Ve.rmClass(this,"over"),!this.draggable)return;const e=Ve(".drag",this.parentNode),t=e=>{for(let t=0;t<e.parentNode.children.length;t++)if(e.parentNode.children[t]===e)return t;return-1},n=t(e),o=t(this);if($e.posts[n].isLocked||$e.posts[o].isLocked)return
|
||
;(n<o?Ve.after:Ve.before)(this,e);const a=$e.posts.splice(n,1)[0];return $e.posts.splice(o,0,a),$e.status(),$e.captcha.updateThread?.()}}};let je;"crx"===x&&(je=function(){const e=[];return chrome.runtime.onMessage.addListener((function(t){return e[t.id](t.data),delete e[t.id]})),(t,n)=>chrome.runtime.sendMessage(t,(t=>e[t]=n))}());var qe={binary(e,t,n=m()){if(e=e.replace(/^((?:https?:)?\/\/(?:\w+\.)?(?:4chan|4channel|4cdn)\.org)\/adv\//,"$1//adv/"),"crx"===x)je({type:"ajax",url:e,headers:n,responseType:"arraybuffer"},(function({response:e,responseHeaderString:n}){return e&&(e=new Uint8Array(e)),t(e,n)}));else{const o=function(){return Ve.ajax(e,{headers:n,responseType:"arraybuffer",onloadend(){return this.status&&this.response?t(new Uint8Array(this.response),this.getAllResponseHeaders()):t(null)}})};if(void 0===window.GM_xmlhttpRequest||null===window.GM_xmlhttpRequest)return void o();const a={method:"GET",url:e,headers:n,responseType:"arraybuffer",
|
||
overrideMimeType:"text/plain; charset=x-user-defined",onload(e){let n;if(e.response instanceof ArrayBuffer)n=new Uint8Array(e.response);else{const t=e.responseText;n=new Uint8Array(t.length);let o=0;for(;o<t.length;)n[o]=t.charCodeAt(o),o++}return t(n,e.responseHeaders)},onerror:()=>t(null),onabort:()=>t(null)};try{return(GM?.xmlHttpRequest||GM_xmlhttpRequest)(a)}catch(e){return o()}}},file:(e,t)=>qe.binary(e,(function(n,o){if(null==n)return t(null);let a=e.match(/([^\/?#]+)\/*(?:$|[?#])/)?.[1];const i=o.match(/Content-Type:\s*(.*)/i)?.[1],r=o.match(/Content-Disposition:\s*(.*)/i)?.[1];let s=i?.match(/[^;]*/)[0]||"application/octet-stream";const l=r?.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)?.[1]||i?.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)?.[1];l&&(a=l.replace(/\\"/g,'"')),/^text\/plain;\s*charset=x-user-defined$/i.test(s)&&(s=Ve.getOwn($e.typeFromExtension,a.match(/[^.]*$/)[0].toLowerCase())||"application/octet-stream");const d=new Blob([n],{type:s});return d.name=a,t(d)})),
|
||
Request:function(){const e=class{static initClass(){this.prototype.status=0,this.prototype.statusText="",this.prototype.response=null,this.prototype.responseHeaderString=null}getResponseHeader(e){if(null==this.responseHeaders&&null!=this.responseHeaderString)for(var t of(this.responseHeaders=m(),this.responseHeaderString.split("\r\n"))){var n;if((n=t.indexOf(":"))>=0){var o=t.slice(0,n).trim().toLowerCase(),a=t.slice(n+1).trim();this.responseHeaders[o]=a}}return this.responseHeaders?.[e.toLowerCase()]??null}abort(){}onloadend(){}};return e.initClass(),e}(),ajax(e,t={}){let n,{onloadend:o,timeout:a,responseType:i,headers:r}=t;if(null==i&&(i="json"),null==window.GM?.xmlHttpRequest&&(void 0===window.GM_xmlhttpRequest||null===window.GM_xmlhttpRequest))return Ve.ajax(e,t);const s=new qe.Request;if(s.onloadend=o,"userscript"===x){const o={method:"GET",url:e,headers:r,timeout:a,onload(e){try{const t="json"===i?e.responseText?JSON.parse(e.responseText):null:e.responseText;Ve.extend(s,{
|
||
response:t,status:e.status,statusText:e.statusText,responseHeaderString:e.responseHeaders})}catch(e){}return s.onloadend()},onerror:()=>s.onloadend(),onabort:()=>s.onloadend(),ontimeout:()=>s.onloadend()};try{n=(GM?.xmlHttpRequest||GM_xmlhttpRequest)(o)}catch(n){return Ve.ajax(e,t)}n&&"function"==typeof n.abort&&(s.abort=function(){try{return n.abort()}catch(e){}})}else je({type:"ajax",url:e,responseType:i,headers:r,timeout:a},(function(e){return e.status&&Ve.extend(s,e),s.onloadend()}));return s},cache:(e,t)=>Ve.cache(e,t,{ajax:qe.ajax}),permission:(e,t,n)=>"crx"===x?je({type:"permission",origins:n},(function(n){return n?e():t()})):e()},Ue=qe;const He=(e,t=document.body)=>t.querySelector(e);He.id=e=>a.getElementById(e),He.ready=function(e){if("loading"===a.readyState){var t=function(){return He.off(a,"DOMContentLoaded",t),e()};return He.on(a,"DOMContentLoaded",t)}He.queueTask(e)},He.formData=function(e){if(e instanceof HTMLFormElement)return new FormData(e);const t=new FormData
|
||
;for(var n in e){var o=e[n];o&&("object"==typeof o&&"newName"in o?t.append(n,o,o.newName):t.append(n,o))}return t},He.extend=function(e,t){for(var n in t){var o=t[n];e[n]=o}},He.hasOwn=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),He.getOwn=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)?e[t]:void 0},He.ajax=function(){let e;e=window.wrappedJSObject&&!XMLHttpRequest.wrappedJSObject?XPCNativeWrapper(window.wrappedJSObject.XMLHttpRequest):XMLHttpRequest;if("userscript"===x)return function(o,a={}){if(null==a.responseType&&(a.responseType="json"),a.type||(a.type=a.form?"post":"get"),o=o.replace(/^((?:https?:)?\/\/(?:\w+\.)?(?:4chan|4channel|4cdn)\.org)\/adv\//,"$1//adv/"),"crx"===x&&t["Work around CORB Bug"]&&"yotsuba"===n.SITE.software&&!a.testCORB&&FormData.prototype.entries)return He.ajaxPage(o,a);const{onloadend:i,timeout:s,responseType:l,withCredentials:d,type:c,onprogress:h,form:u,headers:p}=a,g=new e;try{g.open(c,o,!0);const e=p||{};for(var f in e){var m=e[f]
|
||
;g.setRequestHeader(f,m)}He.extend(g,{onloadend:i,timeout:s,responseType:l,withCredentials:d}),He.extend(g.upload,{onprogress:h}),He.on(g,"error",(function(){if(!g.status)return r.warn(`4chan X failed to load: ${o}`)})),"crx"===x&&He.on(g,"load",(()=>{t["Work around CORB Bug"]||4!==g.readyState||200!==g.status||""!==g.statusText||null!==g.response||He.set("Work around CORB Bug",t["Work around CORB Bug"]=Date.now())})),g.send(u)}catch(e){if(2153644038!==e.result)throw e;g.onloadend=i,He.queueTask(He.event,"error",null,g),He.queueTask(He.event,"loadend",null,g)}return g};{let e=0;const t=m();return He.ajaxPageInit=function(){return He.global((function(){return window.FCX.requests=Object.create(null),document.addEventListener("4chanXAjax",(function(e){let t,n;const{url:o,timeout:a,responseType:i,withCredentials:r,type:s,onprogress:l,form:d,headers:c,id:h}=e.detail;window.FCX.requests[h]=n=new XMLHttpRequest,n.open(s,o,!0);const u=c||{};for(var p in u){var g=u[p];n.setRequestHeader(p,g)}
|
||
if(n.responseType="document"===i?"text":i,n.timeout=a,n.withCredentials=r,l&&(n.upload.onprogress=function(e){const{loaded:t,total:n}=e,o={loaded:t,total:n,id:h};return document.dispatchEvent(new CustomEvent("4chanXAjaxProgress",{bubbles:!0,detail:o}))}),n.onloadend=function(){delete window.FCX.requests[h];const{status:e,statusText:t,response:n}=this,o={status:e,statusText:t,response:n,responseHeaderString:this.getAllResponseHeaders(),id:h};return document.dispatchEvent(new CustomEvent("4chanXAjaxLoadend",{bubbles:!0,detail:o}))},n.onerror=function(){if(!n.status)return console.warn(`4chan X failed to load: ${o}`)},d)for(var f of(t=new FormData,d))t.append(f[0],f[1]);else t=null;return n.send(t)}),!1),document.addEventListener("4chanXAjaxAbort",(function(e){let t;if(t=window.FCX.requests[e.detail.id])return t.abort()}),!1)})),He.on(a,"4chanXAjaxProgress",(function(e){let n;if(n=t[e.detail.id])return n.upload.onprogress.call(n.upload,e.detail)})),
|
||
He.on(a,"4chanXAjaxLoadend",(function(e){let n;if(n=t[e.detail.id]){if(delete t[e.detail.id],e.detail.status){for(var o of["status","statusText","response","responseHeaderString"])n[o]=e.detail[o];"document"===n.responseType&&(n.response=(new DOMParser).parseFromString(e.detail.response,"text/html"))}return n.onloadend()}}))},He.ajaxPage=function(n,o={}){let a,{onloadend:i,timeout:r,responseType:s,withCredentials:l,type:d,onprogress:c,form:h,headers:u}=o;const p=e++;return t[p]=a=new Ue.Request,He.extend(a,{responseType:s,onloadend:i}),a.upload={onprogress:c},a.abort=()=>He.event("4chanXAjaxAbort",{id:p}),h&&(h=Array.from(h.entries())),He.event("4chanXAjax",{url:n,timeout:r,responseType:s,withCredentials:l,type:d,onprogress:!!c,form:h,headers:u,id:p}),a}}}(),He.lastModified=m(),He.whenModified=function(e,t,n,o={}){let a;const{timeout:i,ajax:r}=o,s=[];"blink"===He.engine&&s.push(`s=${t}`),"a.4cdn.org"===e.split("/")[2]&&s.push(`t=${Date.now()}`);const l=e;s.length&&(e+="?"+s.join("&"))
|
||
;const d=m();null!=(a=He.lastModified[t]?.[l])&&(d["If-Modified-Since"]=a);return(r||He.ajax)(e,{onloadend(){return(He.lastModified[t]||(He.lastModified[t]=m()))[l]=this.getResponseHeader("Last-Modified"),n.call(this)},timeout:i,headers:d})},function(){const e=m();He.cache=function(t,n,o={}){let a;const{ajax:i}=o;if(a=e[t])return a.callbacks?a.callbacks.push(n):He.queueTask((()=>n.call(a,{isCached:!0}))),a;return a=(i||He.ajax)(t,{onloadend:function(){for(n of(this.status||delete e[t],this.callbacks))(e=>{He.queueTask((()=>e.call(this,{isCached:!1})))})(n);return delete this.callbacks}}),a.callbacks=[n],e[t]=a},He.cleanCache=function(t){for(var n in e)t(n)&&delete e[n]}}(),He.cb={checked(){if(He.hasOwn(t,this.name))return He.set(this.name,this.checked),t[this.name]=this.checked},value(){if(He.hasOwn(t,this.name))return He.set(this.name,this.value.trim()),t[this.name]=this.value}},He.asap=function(e,t){return e()?t():setTimeout(He.asap,25,e,t)},He.onExists=function(e,t,n){let o
|
||
;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,...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
|