From 486b0df99088ce3c2acf8103cfca528c661be9f1 Mon Sep 17 00:00:00 2001 From: Tuxedo Takodachi Date: Sun, 30 Apr 2023 16:04:01 +0200 Subject: [PATCH] XT release --- CHANGELOG.md | 20 + Makefile | 336 - README.md | 7 +- builds/4chan-X-beta.crx | Bin 333539 -> 0 bytes builds/4chan-X-beta.meta.js | 113 - builds/4chan-X-beta.user.js | 27999 --------------------- builds/4chan-X-noupdate.crx | Bin 333478 -> 0 bytes builds/4chan-X-noupdate.user.js | 27999 --------------------- builds/4chan-X.crx | Bin 333535 -> 0 bytes builds/4chan-X.meta.js | 113 - builds/4chan-X.user.js | 27999 --------------------- builds/4chan-X.zip | Bin 330469 -> 0 bytes builds/4chan-XT-noupdate.user.js | 27297 ++++++++++++++++++++ builds/4chan-XT-noupdate.user.min.js | 664 + builds/4chan-XT-noupdate.user.min.js.map | 1 + builds/crx/eventPage.js | 60 + builds/crx/icon128.png | Bin 0 -> 196 bytes builds/crx/icon16.png | Bin 0 -> 154 bytes builds/crx/icon48.png | Bin 0 -> 185 bytes builds/crx/manifest.json | 109 + builds/crx/script.js | 27186 ++++++++++++++++++++ builds/updates-beta.json | 12 - builds/updates-beta.xml | 7 - builds/updates.json | 12 - builds/updates.xml | 7 - package.json | 8 +- src/meta/metadata.js | 4 +- tools/rollup.js | 2 +- version.json | 4 +- 29 files changed, 55349 insertions(+), 84610 deletions(-) delete mode 100644 Makefile delete mode 100644 builds/4chan-X-beta.crx delete mode 100644 builds/4chan-X-beta.meta.js delete mode 100644 builds/4chan-X-beta.user.js delete mode 100644 builds/4chan-X-noupdate.crx delete mode 100644 builds/4chan-X-noupdate.user.js delete mode 100644 builds/4chan-X.crx delete mode 100644 builds/4chan-X.meta.js delete mode 100644 builds/4chan-X.user.js delete mode 100644 builds/4chan-X.zip create mode 100644 builds/4chan-XT-noupdate.user.js create mode 100644 builds/4chan-XT-noupdate.user.min.js create mode 100644 builds/4chan-XT-noupdate.user.min.js.map create mode 100644 builds/crx/eventPage.js create mode 100644 builds/crx/icon128.png create mode 100644 builds/crx/icon16.png create mode 100644 builds/crx/icon48.png create mode 100644 builds/crx/manifest.json create mode 100644 builds/crx/script.js delete mode 100644 builds/updates-beta.json delete mode 100644 builds/updates-beta.xml delete mode 100644 builds/updates.json delete mode 100644 builds/updates.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index a6232b332..4db746208 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +## 4chan XT changelog + +4chan XT uses a different user script namespace, so to migrate you need to export settings from 4chan X, and import them +in XT. + +### XT v2.0.0 + +#### 2023-04-30 + +This is the first XT release, which means this is after the migration from coffeescript to typescript, but there are +some other changes as well. These changes aren't in the upstream PR. + +- Optimized image filters: filters are in a Map with the hash as key, instead of iterating over all image filters +- I removed font awesome to make the script smaller, and used unicode icons instead. This might break some user scripts + build in 4chan X that rely on them, and I only tested on windows. +- For even smaller user script size, there is a minified version available +- https://github.com/ccd0/4chan-x/pull/3352, fix for https://github.com/ccd0/4chan-x/issues/3349 was ported + +## Original 4chan X changelog + **Note**: Installing the script from one of the links below will disable automatic updates. If you want automatic updates, install the script from the links on the [main page](https://www.4chan-x.net/). -Sometimes the changelog has notes (not comprehensive) acknowledging people's work. This does not mean the changes are their fault, only that their code was used. All changes to the script are chosen by and the fault of the maintainer (ccd0). diff --git a/Makefile b/Makefile deleted file mode 100644 index 01f95ce95..000000000 --- a/Makefile +++ /dev/null @@ -1,336 +0,0 @@ -ifdef ComSpec - BIN := $(subst /,\,node_modules/.bin/) - RMDIR := -rmdir /s /q - RM := -del - CAT = type $(subst /,\,$1) > $(subst /,\,$2) 2>NUL - MKDIR = -mkdir $(subst /,\,$@) - QUOTE = $(patsubst %,"%",$1) -else - BIN := node_modules/.bin/ - RMDIR := rm -rf - RM := rm -rf - CAT = cat $1 > $2 - MKDIR = mkdir -p $@ - QUOTE = $(patsubst %,'%',$1) -endif -CP = $(call CAT,$<,$@) - -npgoals := clean cleanrel cleanweb cleanfull withtests archives $(foreach i,1 2 3 4,bump$(i)) tag tagcommit beta stable web update updatehard -ifneq "$(filter $(npgoals),$(MAKECMDGOALS))" "" -.NOTPARALLEL : -endif - -coffee := $(BIN)coffee -c --no-header -template := node tools/template.js -template_deps := package.json tools/template.js - -# read name meta_name meta_distBranch -$(eval $(shell node tools/pkgvars.js)) - -# must be read in when needed to prevent out-of-date version -version = $(shell node -p "JSON.parse(require('fs').readFileSync('version.json')).version") - -source_directories := \ - globals config css platform classes site \ - Archive Filtering General Images Linkification \ - Menu Miscellaneous Monitoring Posting Quotelinks \ - main - -# remove extension when sorting so X.coffee comes before X.Y.coffee -sort_directory = \ - $(subst !c,.coffee,$(subst !j,.js,$(sort $(subst .coffee,!c,$(subst .js,!j, \ - $(wildcard src/$1/*.coffee src/$1/*.js)))))) - -sources := $(foreach d,$(source_directories),$(call sort_directory,$(d))) - -uses_tests_enabled := \ - src/classes/Post.coffee \ - src/General/Test.coffee \ - src/Linkification/Linkify.coffee \ - src/main/Main.coffee - -imports_src/globals/globals.js := \ - version.json -imports_src/css/CSS.js := \ - node_modules/font-awesome/fonts/fontawesome-webfont.woff -imports_src/Monitoring/Favicon.coffee := \ - src/meta/icon128.png - -imports = \ - $(filter-out %.coffee %.js,$(wildcard $(dir $1)*.*)) \ - $(wildcard $(basename $1)/*.*) \ - $(if $(filter $(uses_tests_enabled),$1),.tests_enabled) \ - $(imports_$1) - -dests_platform = $(addprefix tmp/,$(subst /,-,$(patsubst src/%,%.js,$(subst platform,platform_$2,$1)))) - -dests_of = $(sort $(call dests_platform,$1,crx) $(call dests_platform,$1,userscript)) - -dests := $(foreach s,$(sources),$(call dests_of,$(s))) - -updates := $(subst tmp/,.events/,$(dests)) - -pieces = \ - tmp/LICENSE \ - tmp/meta-newline.js \ - tmp/meta-fbegin.js \ - tmp/meta-newline.js \ - tmp/declaration.js \ - tmp/meta-newline.js \ - $(foreach s,$(sources),$(call dests_platform,$(s),$1)) \ - tmp/meta-fend.js - -crx_contents := script.js eventPage.js icon16.png icon48.png icon128.png manifest.json - -release := \ - $(foreach f, \ - $(foreach c,. -beta.,$(name)$(c)crx updates$(c)xml updates$(c)json $(name)$(c)user.js $(name)$(c)meta.js) \ - $(name)-noupdate.crx \ - $(name)-noupdate.user.js \ - $(name).zip \ - ,builds/$(f)) - -script := $(foreach f,$(filter-out %.crx %.zip,$(release)),test$(f)) $(foreach t,crx crx-beta crx-noupdate,$(foreach f,$(crx_contents),testbuilds/$(t)/$(f))) - -crx := $(foreach f,$(filter %.crx %.zip,$(release)),test$(f)) - -default : script jshint install - -all : default release - -.events .events2 tmp testbuilds builds : - $(MKDIR) - -.tests_enabled : - echo false> .tests_enabled - -.events/declare : $(wildcard src/*/*.coffee) tools/declare.js | .events tmp - node tools/declare.js - echo -> $@ - -tmp/declaration.js : .events/declare - $(if $(wildcard $@),,node tools/declare.js && echo -> $<) - -define check_source -$$(subst tmp/,.events/,$(call dests_of,$1)) : $1 $$(call imports,$1) | .events - echo -> $$(call QUOTE,$$@) -endef - -$(foreach s,$(sources),$(eval $(call check_source,$(subst $$,$$$$,$(s))))) - -.events/compile : $(updates) $(template_deps) tools/chain.js - node tools/chain.js $(call QUOTE, \ - $(subst .events/,tmp/, \ - $(if $(filter-out $(updates),$?), \ - $(updates), \ - $(filter $(updates),$?) \ - ) \ - ) \ - ) - echo -> $@ - -$(dests) : .events/compile - $(if $(wildcard $@),, \ - node tools/chain.js $(call QUOTE, $(filter-out $(wildcard $(dests)),$(dests))) \ - && echo -> $< \ - ) - -tmp/eventPage.js : src/meta/eventPage.coffee | tmp - $(coffee) -o tmp src/meta/eventPage.coffee - -tmp/LICENSE : LICENSE tools/newlinefix.js | tmp - node tools/newlinefix.js $< $@ - -tmp/meta-%.js : src/meta/%.js tools/newlinefix.js | tmp - node tools/newlinefix.js $< $@ - -define rules_channel - -testbuilds/crx$1 : - $$(MKDIR) - -testbuilds/crx$1/script.js : $$(call pieces,crx) | testbuilds/crx$1 .events/compile - @echo Concatenating: $$@ - @$$(call CAT,$$(call QUOTE,$$(call pieces,crx)),$$@) - -testbuilds/crx$1/eventPage.js : tmp/eventPage.js | testbuilds/crx$1 - $$(CP) - -testbuilds/crx$1/icon%.png : src/meta/icon%.png | testbuilds/crx$1 - $$(CP) - -testbuilds/crx$1/manifest.json : src/meta/manifest.json version.json $(template_deps) | testbuilds/crx$1 - $(template) $$< $$@ type=crx channel=$1 - -testbuilds/updates$1.xml : src/meta/updates.xml version.json $(template_deps) | testbuilds/crx$1 - $(template) $$< $$@ type=crx channel=$1 - -testbuilds/updates$1.json : src/meta/updates.json version.json $(template_deps) | testbuilds/crx$1 - $(template) $$< $$@ type=crx channel=$1 - -testbuilds/$(name)$1.crx.zip : \ - $(foreach f,$(crx_contents),testbuilds/crx$1/$(f)) \ - package.json version.json tools/zip-crx.js - node tools/zip-crx.js $1 - -testbuilds/$(name)$1.crx : $(foreach f,$(crx_contents),testbuilds/crx$1/$(f)) version.json tools/sign.sh | tmp - tools/sign.sh $1 - -testbuilds/$(name)$1.meta.js : src/meta/metadata.js src/meta/icon48.png version.json src/Archive/archives.json $(template_deps) | testbuilds - $(template) $$< $$@ type=userscript channel=$1 - -testbuilds/$(name)$1.user.js : testbuilds/$(name)$1.meta.js tmp/meta-newline.js $$(call pieces,userscript) | .events/compile - @echo Concatenating: $$@ - @$$(call CAT,testbuilds/$(name)$1.meta.js tmp/meta-newline.js $$(call QUOTE,$$(call pieces,userscript)),$$@) - -endef - -$(eval $(call rules_channel,)) -$(eval $(call rules_channel,-beta)) -$(eval $(call rules_channel,-noupdate)) - -testbuilds/$(name).zip : testbuilds/$(name)-noupdate.crx.zip - $(CP) - -builds/% : testbuilds/% | builds - $(CP) - -test.html : README.md template.jst tools/markdown.js - node tools/markdown.js - -index.html : test.html - $(CP) - -tmp/.jshintrc : src/meta/jshint.json tmp/declaration.js src/globals/globals.js $(template_deps) | tmp - $(template) $< $@ - -.events/jshint : $(dests) tmp/.jshintrc - $(BIN)jshint $(call QUOTE, \ - $(if $(filter-out $(dests),$?), \ - $(dests), \ - $(filter $(dests),$?) \ - ) \ - ) - echo -> $@ - -install.json : - echo {}> $@ - -.events/install : $(script) install.json tools/install.js | .events - node tools/install.js - echo -> $@ - -.events/CHANGELOG : version.json | .events - node tools/updcl.js - echo -> $@ - -dist : - git worktree add $@ $(meta_distBranch) - -$(wildcard dist/* dist/*/*) : dist - @ - -distready : dist $(wildcard dist/* dist/*/*) - cd dist && git checkout $(meta_distBranch) - cd dist && git pull - -.events2/push-git : .git/refs/heads .git/refs/tags $(wildcard .git/refs/heads/* .git/refs/tags/*) | .events2 distready - git push origin --tags -f - git push origin --all - echo -> $@ - -.events2/push-web : .git/refs/heads/$(meta_distBranch) | .events2 distready - git push web --tags -f - git push web $(meta_distBranch) - echo -> $@ - -.events2/push-store : .git/refs/tags/stable | .events2 distready - node tools/webstore.js - echo -> $@ - -.SECONDARY : - -.PHONY: default all distready script crx release jshint install push $(npgoals) - -script : $(script) - -crx : $(crx) - -release : $(release) - -jshint : .events/jshint - -install : .events/install - -push : .events2/push-git .events2/push-web .events2/push-store - -clean : - $(RMDIR) tmp tmp-crx testbuilds .events - $(RM) .tests_enabled - -cleanrel : clean - $(RMDIR) builds - -cleanweb : - $(RM) test.html - -cleanfull : clean cleanweb - $(RMDIR) .events2 dist node_modules - git worktree prune - -withtests : - echo true> .tests_enabled - -$(MAKE) - echo false> .tests_enabled - -archives : - git fetch -n archives - git merge --no-commit -s ours archives/gh-pages - git show archives/gh-pages:archives.json > src/Archive/archives.json - -git commit -am 'Update archive list.' - -$(foreach i,1 2 3 4,bump$(i)) : - $(MAKE) archives - node tools/bump.js $(subst bump,,$@) - $(MAKE) .events/CHANGELOG - $(MAKE) all - -tag : - git add builds - $(MAKE) cleanrel - $(MAKE) all - git diff --quiet -- builds - $(MAKE) tagcommit - -tagcommit : - git commit -am "Release $(meta_name) v$(version)." - git tag -a $(version) -m "$(meta_name) v$(version)." - -beta : distready - git tag -af beta -m "$(meta_name) v$(version)." - cd dist && git merge --no-commit -s ours beta - cd dist && git checkout beta "builds/*-beta.*" img .gitignore .gitattributes - cd dist && git commit -am "Move $(meta_name) v$(version) to beta channel." - -stable : distready - git push . HEAD:bstable - git tag -af stable -m "$(meta_name) v$(version)." - cd dist && git merge --no-commit -s ours stable - cd dist && git checkout stable "builds/$(name).*" builds/updates.xml builds/updates.json - cd dist && git commit -am "Move $(meta_name) v$(version) to stable channel." - -web : index.html distready - -git commit -am "Build web page." - cd dist && git merge --no-commit -s ours master - cd dist && git checkout master README.md index.html web.css img .gitignore .gitattributes - cd dist && git commit -am "Update web page." - -update : - $(RM) package-lock.json - npm install --save-dev $(shell node tools/unpinned.js) - npm install - -updatehard : - $(RM) package-lock.json - npm install --save-dev $(shell node tools/unpinned.js latest) - npm install diff --git a/README.md b/README.md index dfbaf5806..9a4cd4c7c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # 4chan XT -**This repo is work in progress!** Use the build from the [repo this is forked from](https://github.com/ccd0/4chan-x) in the meantime. +I would prefer that this is merged into [the repo this is forked from](https://github.com/ccd0/4chan-x), but in the mean +time, you can try this fork as well. PR to upstream: https://github.com/ccd0/4chan-x/pull/3341. @@ -20,8 +21,7 @@ The 4chan XT project is a migration of 4chan X from coffeescript to TypeScript/J - [x] crx directory that can be loaded as an unpacked extension is created - [x] beta - [x] noupdate -- [ ] run and debug -- [ ] port updates made to 4chan-X made since this was forked +- [x] port updates made to 4chan-X made since this was forked ## Other notes @@ -61,6 +61,7 @@ The 4chan XT project is a migration of 4chan X from coffeescript to TypeScript/J - [x] 7295b21b73eb13ec53fdc61767ada341c2e13144 Avoid breaking sauce settings of people with links to original Google Images and Google Lens, provided they didn't already update to v1.14.22.3. - [x] 71873cd7b22a565c2a41fa24f63f7504152683eb Recognize JPEG files with .jfif extensions as images for purposes of Image Hover etc.; also recognize .avif and .jxl files as images. - [x] ea2462ecc47327c6f0c31348d95fd2b1b6447cb3 Release 4chan X v1.14.22.4. +- [x] e31438f9a9907078508912fd4c4d44bf21ac773c Fix youtube /live embeds diff --git a/builds/4chan-X-beta.crx b/builds/4chan-X-beta.crx deleted file mode 100644 index 1439282ab5b123f538e9810efc1ce918a1f3433b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 333539 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¼%VgLiMcKpk&DLpL_KZ60aS@PN7>xO`?x4ZLx`mc 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 C(9v-gQCy?2|AW3)cR<1;f?Hek=H^hnI>QO} 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

tT_T?Ki-SKpjcZwbBwVNml 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 V2qnDM2LM3V)AagYkdE+r_aBV6L013( diff --git a/builds/4chan-X-beta.meta.js b/builds/4chan-X-beta.meta.js deleted file mode 100644 index 15afd1f83..000000000 --- a/builds/4chan-X-beta.meta.js +++ /dev/null @@ -1,113 +0,0 @@ -// ==UserScript== -// @name 4chan X beta -// @version 1.14.22.4 -// @minGMVer 1.14 -// @minFFVer 26 -// @namespace 4chan-X -// @description 4chan X is a script that adds various features to anonymous imageboards. -// @license MIT; https://github.com/ccd0/4chan-x/blob/master/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 -// @updateURL https://www.4chan-x.net/builds/4chan-X-beta.meta.js -// @downloadURL https://www.4chan-x.net/builds/4chan-X-beta.user.js -// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAF5JREFUeNrtkTESABAQxPD/R6tsE2dUGYUtFJvLDKf93KevHJAjpBorAQWSBIKqFASC4G0pCAkm4GfaEvgYXl0T6HBaE97f0vmnfYHbZOMLZCx9ISdKWwjOWZSC8GYm4SUGwfYgqI4AAAAASUVORK5CYII= -// ==/UserScript== diff --git a/builds/4chan-X-beta.user.js b/builds/4chan-X-beta.user.js deleted file mode 100644 index 37d9c5c40..000000000 --- a/builds/4chan-X-beta.user.js +++ /dev/null @@ -1,27999 +0,0 @@ -// ==UserScript== -// @name 4chan X beta -// @version 1.14.22.4 -// @minGMVer 1.14 -// @minFFVer 26 -// @namespace 4chan-X -// @description 4chan X is a script that adds various features to anonymous imageboards. -// @license MIT; https://github.com/ccd0/4chan-x/blob/master/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 -// @updateURL https://www.4chan-x.net/builds/4chan-X-beta.meta.js -// @downloadURL https://www.4chan-x.net/builds/4chan-X-beta.user.js -// @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 -* http://zixaphir.github.io/appchan-x/ -* 4chan x Copyright © 2009-2011 James Campos -* https://github.com/aeosynth/4chan-x -* 4chan x Copyright © 2012-2014 Nicolas Stepien -* https://4chan-x.just-believe.in/ -* 4chan x Copyright © 2013-2014 Jordan Bates -* 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 -* -* Font Awesome by Dave Gandy (http://fontawesome.io) -* license: http://fontawesome.io/license/ -* -* Icons used to identify various websites are property of the respective websites. -*/ - -(function() { - -'use strict'; - -var $, $$, Anonymize, AntiAutoplay, ArchiveLink, Banner, Board, BoardConfig, CSS, Callbacks, Captcha, CatalogLinks, CatalogThread, CatalogThreadNative, Config, Connection, CopyTextLink, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, Embedding, ExpandComment, ExpandThread, FappeTyme, Favicon, Fetcher, FileInfo, Filter, Flash, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, IDPostCount, ImageCommon, ImageExpand, ImageHost, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Metadata, ModContact, Nav, NormalizeURL, Notice, PSA, PSAHiding, PassLink, PassMessage, Polyfill, Post, PostHiding, PostJumper, PostRedirect, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, ReplyPruning, Report, ReportLink, RevealSpoilers, SW, Sauce, Settings, ShimSet, SimpleDict, Site, Test, Thread, ThreadHiding, ThreadLinks, ThreadStats, ThreadUpdater, ThreadWatcher, Time, Tinyboard, UI, Unread, UnreadIndex, Volume; - -var Conf, E, c, d, doc, docSet, g; - -Conf = Object.create(null); -c = console; -d = document; -doc = d.documentElement; - -// Workaround for userscript managers that run script before document.documentElement is set -docSet = function() { - return (doc = d.documentElement); -}; - -g = { - VERSION: '1.14.22.4', - NAMESPACE: '4chan X.', - sites: Object.create(null), - boards: Object.create(null) -}; - -E = (function() { - var fn, r, regex, str; - str = { - '&': '&', - "'": ''', - '"': '"', - '<': '<', - '>': '>' - }; - r = String.prototype.replace; - regex = /[&"'<>]/g; - fn = function(x) { - return str[x]; - }; - return function(text) { - return r.call(text, regex, fn); - }; -})(); - -E.cat = function(templates) { - var html, i, len; - html = ''; - for (i = 0, len = templates.length; i < len; i++) { - html += templates[i].innerHTML; - } - return html; -}; - -Config = (function() { - var Config; - - Config = { - main: { - 'Miscellaneous': { - 'Redirect to HTTPS': [true, 'Redirect to the HTTPS version of 4chan.'], - 'JSON Index': [true, 'Replace the original board index with one supporting searching, sorting, infinite scrolling, and a catalog mode.'], - 'Use 4chan X Catalog': [true, 'Link to 4chan X\'s catalog instead of the native 4chan one.', 1], - 'Index Refresh Notifications': [false, 'Show a notice at the top of the page when the index is refreshed.', 1], - 'Follow Cursor': [true, 'Image Hover and Quote Preview move with the mouse cursor.'], - 'Open Threads in New Tab': [false, 'Make links to threads in the index / 4chan X catalog open in a new tab.'], - 'External Catalog': [false, 'Link to external catalog instead of the internal one.'], - 'Catalog Links': [false, 'Add toggle link in header menu to turn Navigation links into links to each board\'s catalog.'], - 'Announcement Hiding': [true, 'Add button to hide 4chan announcements.'], - 'Desktop Notifications': [true, 'Enables desktop notifications across various 4chan X features.'], - '404 Redirect': [true, 'Redirect dead threads and images to the archives.'], - 'Archive Report': [true, 'Enable reporting posts to supported archives.'], - 'Exempt Archives from Encryption': [true, 'Permit loading content from, and warningless redirects to, HTTP-only archives from HTTPS pages.'], - 'Keybinds': [true, 'Bind actions to keyboard shortcuts.'], - 'Time Formatting': [true, 'Localize and format timestamps.'], - 'Relative Post Dates': [true, 'Display dates like "3 minutes ago". Tooltip shows the timestamp.'], - 'Relative Date Title': [true, 'Show Relative Post Date only when hovering over dates.', 1], - 'Comment Expansion': [true, 'Expand comments that are too long to display on the index. Not applicable with JSON Index.'], - 'File Info Formatting': [true, 'Reformat the file information.'], - 'Thread Expansion': [true, 'Add buttons to expand threads.'], - 'Index Navigation': [false, 'Add buttons to navigate between threads.'], - 'Reply Navigation': [false, 'Add buttons to navigate to top / bottom of thread.'], - 'Unique ID and Capcode Navigation': [false, 'Add buttons to navigate to posts having the same unique ID or capcode.'], - 'Custom Board Titles': [true, 'Allow editing of the board title and subtitle by ctrl/\u2318+clicking them.'], - 'Persistent Custom Board Titles': [false, 'Force custom board titles to be persistent, even if the board titles are updated.', 1], - 'Show Updated Notifications': [true, 'Show notifications when 4chan X is successfully updated.'], - 'Color User IDs': [true, 'Assign unique colors to user IDs on boards that use them'], - 'Count Posts by ID': [true, 'Display number of posts in the thread when hovering over an ID.'], - 'Remove Spoilers': [false, 'Remove all spoilers in text.'], - 'Reveal Spoilers': [false, 'Indicate spoilers if Remove Spoilers is enabled, or make the text appear hovered if Remove Spoiler is disabled.'], - 'Normalize URL': [true, 'Rewrite the URL of the current page, removing slugs and excess slashes, and changing /res/ to /thread/.'], - 'Work around CORB Bug': [true, 'Leave this checked until your garbage browser is fixed.'], - 'Disable Autoplaying Sounds': [false, 'Prevent sounds on the page from autoplaying.'], - 'Disable Native Extension': [true, '4chan X is NOT designed to work with the native extension.'], - 'Enable Native Flash Embedding': [true, 'Activate the native extension\'s Flash embedding if the native extension is disabled.'] - }, - 'Linkification': { - 'Linkify': [true, 'Convert text into links where applicable.'], - 'Link Title': [true, 'Replace the link of a supported site with its actual title.', 1], - 'Cover Preview': [true, 'Show preview of supported links on hover.', 1], - 'Embedding': [true, 'Embed supported services. Note: Some services don\'t work on HTTPS.', 1], - 'Auto-embed': [false, 'Auto-embed Linkify Embeds.', 2], - 'Floating Embeds': [false, 'Embed content in a frame that remains in place when the page is scrolled.', 2] - }, - 'Filtering': { - 'Anonymize': [false, 'Make everyone Anonymous.'], - 'Filter': [true, 'Self-moderation placebo.'], - 'Filtered Backlinks': [false, 'When enabled, shows backlinks to filtered posts with a line-through decoration. Otherwise, hides the backlinks.', 1], - 'Filter in Native Catalog': [true, 'Apply 4chan X filters in native catalog.', 1], - 'MD5 Quick Filter Notifications': [true, 'Show notification when quick filtering MD5s using the button or keybind.', 1], - 'Recursive Hiding': [true, 'Hide replies of hidden posts, recursively.'], - 'Thread Hiding Buttons': [true, 'Add buttons to hide entire threads.'], - 'Reply Hiding Buttons': [true, 'Add buttons to hide single replies.'], - 'Stubs': [true, 'Show stubs of hidden threads / replies.'] - }, - 'Images and Videos': { - 'Image Expansion': [true, 'Expand images / videos.'], - 'Image Hover': [true, 'Show full image / video on mouseover.'], - 'Image Hover in Catalog': [true, 'Show full image / video on mouseover in 4chan X catalog.'], - 'Gallery': [true, 'Adds a simple and cute image gallery. Has more options in the gallery menu.'], - 'Fullscreen Gallery': [false, 'Open gallery in fullscreen mode.', 1], - 'PDF in Gallery': [false, 'Show PDF files in gallery.', 1], - 'Sauce': [true, 'Add sauce links to images.'], - 'WEBM Metadata': [true, 'Add link to fetch title metadata from webm videos.'], - 'Reveal Spoiler Thumbnails': [false, 'Replace spoiler thumbnails with the original image.'], - 'Replace GIF': [false, 'Replace gif thumbnails with the actual image.'], - 'Replace JPG': [false, 'Replace jpg thumbnails with the actual image.'], - 'Replace PNG': [false, 'Replace png thumbnails with the actual image.'], - 'Replace WEBM': [false, 'Replace webm, mp4, and ogv thumbnails with the actual video. Probably will degrade browser performance ;)'], - 'Image Prefetching': [true, 'Add a shortcut icon to the header to turn on image preloading.'], - 'Fappe Tyme': [true, 'Hide posts without images when header menu item is checked. *hint* *hint*'], - 'Werk Tyme': [true, 'Hide all post images when header menu item is checked.'], - 'Autoplay': [true, 'Videos begin playing immediately when opened.'], - 'Restart when Opened': [false, 'Restart GIFs and WebMs when you hover over or expand them.'], - 'Show Controls': [true, 'Show controls on videos expanded inline.'], - 'Click Passthrough': [false, 'Clicks on videos trigger your browser\'s default behavior. Videos can be contracted with button / dragging to the left.', 1], - 'Allow Sound': [true, 'Open videos with the sound unmuted.'], - 'Mouse Wheel Volume': [true, 'Adjust volume of videos with the mouse wheel over the thumbnail/filename/gallery.'], - 'Loop in New Tab': [true, 'Loop videos opened in their own tabs.'], - 'Volume in New Tab': [true, 'Apply 4chan X mute and volume settings to videos opened in their own tabs.'] - }, - 'Menu': { - 'Menu': [true, 'Add a drop-down menu to posts.'], - 'Report Link': [true, 'Add a report link to the menu.', 1], - 'Copy Text Link': [true, 'Add a link to copy the post\'s text.', 1], - 'Thread Hiding Link': [true, 'Add a link to hide entire threads.', 1], - 'Reply Hiding Link': [true, 'Add a link to hide single replies.', 1], - 'Delete Link': [true, 'Add post and image deletion links to the menu.', 1], - 'Archive Link': [true, 'Add an archive link to the menu.', 1], - 'Edit Link': [true, 'Add a link to edit the image in Tegaki, /i/\'s painting program. Requires Quick Reply.', 1], - 'Download Link': [false, 'Add a download with original filename link to the menu.', 1] - }, - 'Monitoring': { - 'Thread Updater': [true, 'Fetch and insert new replies. Has more options in the header menu and the "Advanced" tab.'], - 'Unread Count': [true, 'Show the unread posts count in the tab title.'], - 'Quoted Title': [false, 'Change the page title to reflect you\'ve been quoted.', 1], - 'Hide Unread Count at (0)': [false, 'Hide the unread posts count in the tab title when it reaches 0.', 1], - 'Unread Favicon': [true, 'Show a different favicon when there are unread posts.'], - 'Unread Line': [true, 'Show a line to distinguish read posts from unread ones.'], - 'Remember Last Read Post': [true, 'Remember how far you\'ve read after you close the thread.'], - 'Scroll to Last Read Post': [true, 'Scroll back to the last read post when reopening a thread.', 1], - 'Unread Line in Index': [false, 'Show a line between read and unread posts in threads in the index.', 1], - 'Remove Thread Excerpt': [false, 'Replace the excerpt of the thread in the tab title with the board title.'], - 'Thread Stats': [true, 'Display reply and image count.'], - 'IP Count in Stats': [true, 'Display the unique IP count in the thread stats.', 1], - 'Page Count in Stats': [true, 'Display the page count in the thread stats.', 1], - 'Updater and Stats in Header': [true, 'Places the thread updater and thread stats in the header instead of floating them.'], - 'Thread Watcher': [true, 'Bookmark threads. Has more options in the thread watcher menu.'], - 'Fixed Thread Watcher': [true, 'Makes the thread watcher scroll with the page.', 1], - 'Persistent Thread Watcher': [false, 'The thread watcher will be visible when the page is loaded.', 1], - 'Mark New IPs': [false, 'Label each post from a new IP with the thread\'s current IP count.'], - 'Reply Pruning': [true, 'Add option in header menu to hide old replies in long threads. Activated by default in stickies.'], - 'Prune All Threads': [false, 'Activate Reply Pruning by default in all threads.', 1] - }, - 'Posting and Captchas': { - 'Quick Reply': [true, 'All-in-one form to reply, create threads, automate dumping and more.'], - 'Persistent QR': [false, 'The Quick reply won\'t disappear after posting.', 1], - 'Auto Hide QR': [true, 'Automatically hide the quick reply when posting.', 2], - 'Open Post in New Tab': [true, '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': [false, 'Remember the size of the Quick reply.', 1], - 'Remember Spoiler': [false, 'Remember the spoiler state, instead of resetting after posting.', 1], - 'Randomize Filename': [false, 'Set the filename to a random timestamp within the past year. Disabled on /f/.', 1], - 'Show New Thread Option in Threads': [true, 'Show the option to post a new / different thread from inside a thread.', 1], - 'Show Upload Progress': [true, 'Track progress of file uploads as percentage in submit button.', 1], - 'Cooldown': [true, 'Indicate the remaining time before posting again.', 1], - 'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.', 1], - 'Auto-load captcha': [false, 'Automatically load the captcha in the QR even if your post is empty.', 1], - 'Post on Captcha Completion': [false, 'Submit the post immediately when the captcha is completed.', 1], - 'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha even if Javascript is enabled.'], - 'Pass Link': [false, 'Add a 4chan Pass login link to the bottom of the page.'] - }, - 'Quote Links': { - 'Quote Backlinks': [true, 'Add quote backlinks.'], - 'OP Backlinks': [true, 'Add backlinks to the OP.', 1], - 'Bottom Backlinks': [false, 'Place backlinks at the bottom of posts.', 1], - 'Quote Inlining': [true, 'Inline quoted post on click.'], - 'Inline Cross-thread Quotes Only': [false, 'Don\'t inline quote links when the posts are visible in the thread.', 1], - 'Quote Hash Navigation': [false, 'Include an extra link after quotes for autoscrolling to quoted posts.', 1], - 'Forward Hiding': [true, 'Hide original posts of inlined backlinks.', 1], - 'Quote Previewing': [true, 'Show quoted post on hover.'], - 'Quote Highlighting': [true, 'Highlight the previewed post.', 1], - 'Resurrect Quotes': [true, 'Link dead quotes to the archives, and support inlining/previewing of archive links like quote links.'], - 'Remember Your Posts': [true, 'Remember your posting history.'], - 'Mark Quotes of You': [true, 'Add \'(You)\' to quotes linking to your posts.', 1], - 'Highlight Posts Quoting You': [true, 'Highlights any posts that contain a quote to your post.', 1], - 'Highlight Own Posts': [true, 'Highlights own posts.', 1], - 'Mark OP Quotes': [true, 'Add \'(OP)\' to OP quotes.'], - 'Mark Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.'], - 'Quote Threading': [true, 'Add option in header menu to thread conversations.'] - } - }, - imageExpansion: { - 'Fit width': [true, ''], - 'Fit height': [false, ''], - 'Scroll into view': [true, 'Scroll down when expanding images to bring the full image into view.'], - 'Expand spoilers': [true, 'Expand all images along with spoilers.'], - 'Expand videos': [true, 'Expand all images also expands videos.'], - 'Expand from here': [false, 'Expand all images only from current position to thread end.'], - 'Expand thread only': [false, 'In index, expand all images only within the current thread.'], - 'Advance on contract': [false, 'Advance to next post when contracting an expanded image.'] - }, - gallery: { - 'Hide Thumbnails': [false], - 'Fit Width': [true], - 'Fit Height': [true], - 'Stretch to Fit': [false], - 'Scroll to Post': [true], - 'Slide Delay': [6.0] - }, - 'Default Volume': 1.0, - threadWatcher: { - 'Current Board': [false, 'Only show watched threads from the current board.'], - 'Auto Update Thread Watcher': [true, 'Periodically check status of watched threads.'], - 'Auto Watch': [true, 'Automatically watch threads you start.'], - 'Auto Watch Reply': [true, 'Automatically watch threads you reply to.'], - 'Auto Prune': [false, 'Automatically remove dead threads.'], - 'Show Page': [true, 'Show what page watched threads are on.'], - 'Show Unread Count': [true, 'Show number of unread posts in watched threads.'], - 'Show Site Prefix': [true, 'When multiple sites are shown in the thread watcher, add a prefix to board names to distinguish them.'], - 'Require OP Quote Link': [false, '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: false - }, - 'Custom CSS': true, - Index: { - 'Index Mode': 'paged', - 'Previous Index Mode': 'paged', - 'Index Size': 'small', - 'Show Replies': [true, 'Show replies in the index, and also in the catalog if "Catalog hover expand" is checked.'], - 'Catalog Hover Expand': [false, 'Expand the comment and show more details when you hover over a thread in the catalog.'], - 'Catalog Hover Toggle': [true, 'Turn "Catalog hover expand" on and off by clicking in the catalog.'], - 'Pin Watched Threads': [false, 'Move watched threads to the start of the index.'], - 'Anchor Hidden Threads': [true, 'Move hidden threads to the end of the index.'], - 'Refreshed Navigation': [false, 'Refresh index when navigating through pages.'] - }, - Header: { - 'Fixed Header': true, - 'Header auto-hide': false, - 'Header auto-hide on scroll': false, - 'Bottom Header': false, - 'Centered links': false, - 'Header catalog links': false, - 'Bottom Board List': true, - 'Shortcut Icons': true, - 'Custom Board Navigation': true - }, - archives: { - archiveLists: 'https://4chenz.github.io/archives.json/archives.json', - lastarchivecheck: 0, - archiveAutoUpdate: true - }, - 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\",\"https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions\"]", - QR: { - 'QR.personas': "#options:\"sage\";boards:jp;always", - sjisPreview: false - }, - 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': [false, 'Beep on new post to completely read thread.'], - 'Beep Quoting You': [false, 'Beep on new post quoting you.'], - 'Auto Scroll': [false, 'Scroll updated posts into view. Only enabled at bottom of page.'], - 'Bottom Scroll': [false, 'Always scroll to the bottom, not the first new post. Useful for event threads.'], - 'Scroll BG': [false, 'Auto-scroll background tabs.'], - 'Auto Update': [true, 'Automatically fetch new posts.'], - 'Optional Increase': [false, 'Increase the intervals between updates on threads without new posts.'] - }, - 'Interval': 5 - }, - customCooldown: 0, - customCooldownEnabled: true, - 'Thread Quotes': false, - 'Max Replies': 1000, - 'Autohiding Scrollbar': false, - 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', - passMessageClosed: false, - 'Prerequest Captcha': false, - 'PSAseen': [[]] - }; - - return Config; - -}).call(this); - -CSS = { - -boards: -"/*!\n\ - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome\n\ - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n\ - */\n\ -@font-face {\n\ - font-family: FontAwesome;\n\ - src: url('data:application/font-woff;base64,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') format('woff');\n\ - font-weight: 400;\n\ - font-style: normal;\n\ -}\n\ -.fa-glass:before {content: \"\\f000\";}\n\ -.fa-music:before {content: \"\\f001\";}\n\ -.fa-search:before {content: \"\\f002\";}\n\ -.fa-envelope-o:before {content: \"\\f003\";}\n\ -.fa-heart:before {content: \"\\f004\";}\n\ -.fa-star:before {content: \"\\f005\";}\n\ -.fa-star-o:before {content: \"\\f006\";}\n\ -.fa-user:before {content: \"\\f007\";}\n\ -.fa-film:before {content: \"\\f008\";}\n\ -.fa-th-large:before {content: \"\\f009\";}\n\ -.fa-th:before {content: \"\\f00a\";}\n\ -.fa-th-list:before {content: \"\\f00b\";}\n\ -.fa-check:before {content: \"\\f00c\";}\n\ -.fa-remove:before, .fa-close:before, .fa-times:before {content: \"\\f00d\";}\n\ -.fa-search-plus:before {content: \"\\f00e\";}\n\ -.fa-search-minus:before {content: \"\\f010\";}\n\ -.fa-power-off:before {content: \"\\f011\";}\n\ -.fa-signal:before {content: \"\\f012\";}\n\ -.fa-gear:before, .fa-cog:before {content: \"\\f013\";}\n\ -.fa-trash-o:before {content: \"\\f014\";}\n\ -.fa-home:before {content: \"\\f015\";}\n\ -.fa-file-o:before {content: \"\\f016\";}\n\ -.fa-clock-o:before {content: \"\\f017\";}\n\ -.fa-road:before {content: \"\\f018\";}\n\ -.fa-download:before {content: \"\\f019\";}\n\ -.fa-arrow-circle-o-down:before {content: \"\\f01a\";}\n\ -.fa-arrow-circle-o-up:before {content: \"\\f01b\";}\n\ -.fa-inbox:before {content: \"\\f01c\";}\n\ -.fa-play-circle-o:before {content: \"\\f01d\";}\n\ -.fa-rotate-right:before, .fa-repeat:before {content: \"\\f01e\";}\n\ -.fa-refresh:before {content: \"\\f021\";}\n\ -.fa-list-alt:before {content: \"\\f022\";}\n\ -.fa-lock:before {content: \"\\f023\";}\n\ -.fa-flag:before {content: \"\\f024\";}\n\ -.fa-headphones:before {content: \"\\f025\";}\n\ -.fa-volume-off:before {content: \"\\f026\";}\n\ -.fa-volume-down:before {content: \"\\f027\";}\n\ -.fa-volume-up:before {content: \"\\f028\";}\n\ -.fa-qrcode:before {content: \"\\f029\";}\n\ -.fa-barcode:before {content: \"\\f02a\";}\n\ -.fa-tag:before {content: \"\\f02b\";}\n\ -.fa-tags:before {content: \"\\f02c\";}\n\ -.fa-book:before {content: \"\\f02d\";}\n\ -.fa-bookmark:before {content: \"\\f02e\";}\n\ -.fa-print:before {content: \"\\f02f\";}\n\ -.fa-camera:before {content: \"\\f030\";}\n\ -.fa-font:before {content: \"\\f031\";}\n\ -.fa-bold:before {content: \"\\f032\";}\n\ -.fa-italic:before {content: \"\\f033\";}\n\ -.fa-text-height:before {content: \"\\f034\";}\n\ -.fa-text-width:before {content: \"\\f035\";}\n\ -.fa-align-left:before {content: \"\\f036\";}\n\ -.fa-align-center:before {content: \"\\f037\";}\n\ -.fa-align-right:before {content: \"\\f038\";}\n\ -.fa-align-justify:before {content: \"\\f039\";}\n\ -.fa-list:before {content: \"\\f03a\";}\n\ -.fa-dedent:before, .fa-outdent:before {content: \"\\f03b\";}\n\ -.fa-indent:before {content: \"\\f03c\";}\n\ -.fa-video-camera:before {content: \"\\f03d\";}\n\ -.fa-photo:before, .fa-image:before, .fa-picture-o:before {content: \"\\f03e\";}\n\ -.fa-pencil:before {content: \"\\f040\";}\n\ -.fa-map-marker:before {content: \"\\f041\";}\n\ -.fa-adjust:before {content: \"\\f042\";}\n\ -.fa-tint:before {content: \"\\f043\";}\n\ -.fa-edit:before, .fa-pencil-square-o:before {content: \"\\f044\";}\n\ -.fa-share-square-o:before {content: \"\\f045\";}\n\ -.fa-check-square-o:before {content: \"\\f046\";}\n\ -.fa-arrows:before {content: \"\\f047\";}\n\ -.fa-step-backward:before {content: \"\\f048\";}\n\ -.fa-fast-backward:before {content: \"\\f049\";}\n\ -.fa-backward:before {content: \"\\f04a\";}\n\ -.fa-play:before {content: \"\\f04b\";}\n\ -.fa-pause:before {content: \"\\f04c\";}\n\ -.fa-stop:before {content: \"\\f04d\";}\n\ -.fa-forward:before {content: \"\\f04e\";}\n\ -.fa-fast-forward:before {content: \"\\f050\";}\n\ -.fa-step-forward:before {content: \"\\f051\";}\n\ -.fa-eject:before {content: \"\\f052\";}\n\ -.fa-chevron-left:before {content: \"\\f053\";}\n\ -.fa-chevron-right:before {content: \"\\f054\";}\n\ -.fa-plus-circle:before {content: \"\\f055\";}\n\ -.fa-minus-circle:before {content: \"\\f056\";}\n\ -.fa-times-circle:before {content: \"\\f057\";}\n\ -.fa-check-circle:before {content: \"\\f058\";}\n\ -.fa-question-circle:before {content: \"\\f059\";}\n\ -.fa-info-circle:before {content: \"\\f05a\";}\n\ -.fa-crosshairs:before {content: \"\\f05b\";}\n\ -.fa-times-circle-o:before {content: \"\\f05c\";}\n\ -.fa-check-circle-o:before {content: \"\\f05d\";}\n\ -.fa-ban:before {content: \"\\f05e\";}\n\ -.fa-arrow-left:before {content: \"\\f060\";}\n\ -.fa-arrow-right:before {content: \"\\f061\";}\n\ -.fa-arrow-up:before {content: \"\\f062\";}\n\ -.fa-arrow-down:before {content: \"\\f063\";}\n\ -.fa-mail-forward:before, .fa-share:before {content: \"\\f064\";}\n\ -.fa-expand:before {content: \"\\f065\";}\n\ -.fa-compress:before {content: \"\\f066\";}\n\ -.fa-plus:before {content: \"\\f067\";}\n\ -.fa-minus:before {content: \"\\f068\";}\n\ -.fa-asterisk:before {content: \"\\f069\";}\n\ -.fa-exclamation-circle:before {content: \"\\f06a\";}\n\ -.fa-gift:before {content: \"\\f06b\";}\n\ -.fa-leaf:before {content: \"\\f06c\";}\n\ -.fa-fire:before {content: \"\\f06d\";}\n\ -.fa-eye:before {content: \"\\f06e\";}\n\ -.fa-eye-slash:before {content: \"\\f070\";}\n\ -.fa-warning:before, .fa-exclamation-triangle:before {content: \"\\f071\";}\n\ -.fa-plane:before {content: \"\\f072\";}\n\ -.fa-calendar:before {content: \"\\f073\";}\n\ -.fa-random:before {content: \"\\f074\";}\n\ -.fa-comment:before {content: \"\\f075\";}\n\ -.fa-magnet:before {content: \"\\f076\";}\n\ -.fa-chevron-up:before {content: \"\\f077\";}\n\ -.fa-chevron-down:before {content: \"\\f078\";}\n\ -.fa-retweet:before {content: \"\\f079\";}\n\ -.fa-shopping-cart:before {content: \"\\f07a\";}\n\ -.fa-folder:before {content: \"\\f07b\";}\n\ -.fa-folder-open:before {content: \"\\f07c\";}\n\ -.fa-arrows-v:before {content: \"\\f07d\";}\n\ -.fa-arrows-h:before {content: \"\\f07e\";}\n\ -.fa-bar-chart-o:before, .fa-bar-chart:before {content: \"\\f080\";}\n\ -.fa-twitter-square:before {content: \"\\f081\";}\n\ -.fa-facebook-square:before {content: \"\\f082\";}\n\ -.fa-camera-retro:before {content: \"\\f083\";}\n\ -.fa-key:before {content: \"\\f084\";}\n\ -.fa-gears:before, .fa-cogs:before {content: \"\\f085\";}\n\ -.fa-comments:before {content: \"\\f086\";}\n\ -.fa-thumbs-o-up:before {content: \"\\f087\";}\n\ -.fa-thumbs-o-down:before {content: \"\\f088\";}\n\ -.fa-star-half:before {content: \"\\f089\";}\n\ -.fa-heart-o:before {content: \"\\f08a\";}\n\ -.fa-sign-out:before {content: \"\\f08b\";}\n\ -.fa-linkedin-square:before {content: \"\\f08c\";}\n\ -.fa-thumb-tack:before {content: \"\\f08d\";}\n\ -.fa-external-link:before {content: \"\\f08e\";}\n\ -.fa-sign-in:before {content: \"\\f090\";}\n\ -.fa-trophy:before {content: \"\\f091\";}\n\ -.fa-github-square:before {content: \"\\f092\";}\n\ -.fa-upload:before {content: \"\\f093\";}\n\ -.fa-lemon-o:before {content: \"\\f094\";}\n\ -.fa-phone:before {content: \"\\f095\";}\n\ -.fa-square-o:before {content: \"\\f096\";}\n\ -.fa-bookmark-o:before {content: \"\\f097\";}\n\ -.fa-phone-square:before {content: \"\\f098\";}\n\ -.fa-twitter:before {content: \"\\f099\";}\n\ -.fa-facebook-f:before, .fa-facebook:before {content: \"\\f09a\";}\n\ -.fa-github:before {content: \"\\f09b\";}\n\ -.fa-unlock:before {content: \"\\f09c\";}\n\ -.fa-credit-card:before {content: \"\\f09d\";}\n\ -.fa-feed:before, .fa-rss:before {content: \"\\f09e\";}\n\ -.fa-hdd-o:before {content: \"\\f0a0\";}\n\ -.fa-bullhorn:before {content: \"\\f0a1\";}\n\ -.fa-bell:before {content: \"\\f0f3\";}\n\ -.fa-certificate:before {content: \"\\f0a3\";}\n\ -.fa-hand-o-right:before {content: \"\\f0a4\";}\n\ -.fa-hand-o-left:before {content: \"\\f0a5\";}\n\ -.fa-hand-o-up:before {content: \"\\f0a6\";}\n\ -.fa-hand-o-down:before {content: \"\\f0a7\";}\n\ -.fa-arrow-circle-left:before {content: \"\\f0a8\";}\n\ -.fa-arrow-circle-right:before {content: \"\\f0a9\";}\n\ -.fa-arrow-circle-up:before {content: \"\\f0aa\";}\n\ -.fa-arrow-circle-down:before {content: \"\\f0ab\";}\n\ -.fa-globe:before {content: \"\\f0ac\";}\n\ -.fa-wrench:before {content: \"\\f0ad\";}\n\ -.fa-tasks:before {content: \"\\f0ae\";}\n\ -.fa-filter:before {content: \"\\f0b0\";}\n\ -.fa-briefcase:before {content: \"\\f0b1\";}\n\ -.fa-arrows-alt:before {content: \"\\f0b2\";}\n\ -.fa-group:before, .fa-users:before {content: \"\\f0c0\";}\n\ -.fa-chain:before, .fa-link:before {content: \"\\f0c1\";}\n\ -.fa-cloud:before {content: \"\\f0c2\";}\n\ -.fa-flask:before {content: \"\\f0c3\";}\n\ -.fa-cut:before, .fa-scissors:before {content: \"\\f0c4\";}\n\ -.fa-copy:before, .fa-files-o:before {content: \"\\f0c5\";}\n\ -.fa-paperclip:before {content: \"\\f0c6\";}\n\ -.fa-save:before, .fa-floppy-o:before {content: \"\\f0c7\";}\n\ -.fa-square:before {content: \"\\f0c8\";}\n\ -.fa-navicon:before, .fa-reorder:before, .fa-bars:before {content: \"\\f0c9\";}\n\ -.fa-list-ul:before {content: \"\\f0ca\";}\n\ -.fa-list-ol:before {content: \"\\f0cb\";}\n\ -.fa-strikethrough:before {content: \"\\f0cc\";}\n\ -.fa-underline:before {content: \"\\f0cd\";}\n\ -.fa-table:before {content: \"\\f0ce\";}\n\ -.fa-magic:before {content: \"\\f0d0\";}\n\ -.fa-truck:before {content: \"\\f0d1\";}\n\ -.fa-pinterest:before {content: \"\\f0d2\";}\n\ -.fa-pinterest-square:before {content: \"\\f0d3\";}\n\ -.fa-google-plus-square:before {content: \"\\f0d4\";}\n\ -.fa-google-plus:before {content: \"\\f0d5\";}\n\ -.fa-money:before {content: \"\\f0d6\";}\n\ -.fa-caret-down:before {content: \"\\f0d7\";}\n\ -.fa-caret-up:before {content: \"\\f0d8\";}\n\ -.fa-caret-left:before {content: \"\\f0d9\";}\n\ -.fa-caret-right:before {content: \"\\f0da\";}\n\ -.fa-columns:before {content: \"\\f0db\";}\n\ -.fa-unsorted:before, .fa-sort:before {content: \"\\f0dc\";}\n\ -.fa-sort-down:before, .fa-sort-desc:before {content: \"\\f0dd\";}\n\ -.fa-sort-up:before, .fa-sort-asc:before {content: \"\\f0de\";}\n\ -.fa-envelope:before {content: \"\\f0e0\";}\n\ -.fa-linkedin:before {content: \"\\f0e1\";}\n\ -.fa-rotate-left:before, .fa-undo:before {content: \"\\f0e2\";}\n\ -.fa-legal:before, .fa-gavel:before {content: \"\\f0e3\";}\n\ -.fa-dashboard:before, .fa-tachometer:before {content: \"\\f0e4\";}\n\ -.fa-comment-o:before {content: \"\\f0e5\";}\n\ -.fa-comments-o:before {content: \"\\f0e6\";}\n\ -.fa-flash:before, .fa-bolt:before {content: \"\\f0e7\";}\n\ -.fa-sitemap:before {content: \"\\f0e8\";}\n\ -.fa-umbrella:before {content: \"\\f0e9\";}\n\ -.fa-paste:before, .fa-clipboard:before {content: \"\\f0ea\";}\n\ -.fa-lightbulb-o:before {content: \"\\f0eb\";}\n\ -.fa-exchange:before {content: \"\\f0ec\";}\n\ -.fa-cloud-download:before {content: \"\\f0ed\";}\n\ -.fa-cloud-upload:before {content: \"\\f0ee\";}\n\ -.fa-user-md:before {content: \"\\f0f0\";}\n\ -.fa-stethoscope:before {content: \"\\f0f1\";}\n\ -.fa-suitcase:before {content: \"\\f0f2\";}\n\ -.fa-bell-o:before {content: \"\\f0a2\";}\n\ -.fa-coffee:before {content: \"\\f0f4\";}\n\ -.fa-cutlery:before {content: \"\\f0f5\";}\n\ -.fa-file-text-o:before {content: \"\\f0f6\";}\n\ -.fa-building-o:before {content: \"\\f0f7\";}\n\ -.fa-hospital-o:before {content: \"\\f0f8\";}\n\ -.fa-ambulance:before {content: \"\\f0f9\";}\n\ -.fa-medkit:before {content: \"\\f0fa\";}\n\ -.fa-fighter-jet:before {content: \"\\f0fb\";}\n\ -.fa-beer:before {content: \"\\f0fc\";}\n\ -.fa-h-square:before {content: \"\\f0fd\";}\n\ -.fa-plus-square:before {content: \"\\f0fe\";}\n\ -.fa-angle-double-left:before {content: \"\\f100\";}\n\ -.fa-angle-double-right:before {content: \"\\f101\";}\n\ -.fa-angle-double-up:before {content: \"\\f102\";}\n\ -.fa-angle-double-down:before {content: \"\\f103\";}\n\ -.fa-angle-left:before {content: \"\\f104\";}\n\ -.fa-angle-right:before {content: \"\\f105\";}\n\ -.fa-angle-up:before {content: \"\\f106\";}\n\ -.fa-angle-down:before {content: \"\\f107\";}\n\ -.fa-desktop:before {content: \"\\f108\";}\n\ -.fa-laptop:before {content: \"\\f109\";}\n\ -.fa-tablet:before {content: \"\\f10a\";}\n\ -.fa-mobile-phone:before, .fa-mobile:before {content: \"\\f10b\";}\n\ -.fa-circle-o:before {content: \"\\f10c\";}\n\ -.fa-quote-left:before {content: \"\\f10d\";}\n\ -.fa-quote-right:before {content: \"\\f10e\";}\n\ -.fa-spinner:before {content: \"\\f110\";}\n\ -.fa-circle:before {content: \"\\f111\";}\n\ -.fa-mail-reply:before, .fa-reply:before {content: \"\\f112\";}\n\ -.fa-github-alt:before {content: \"\\f113\";}\n\ -.fa-folder-o:before {content: \"\\f114\";}\n\ -.fa-folder-open-o:before {content: \"\\f115\";}\n\ -.fa-smile-o:before {content: \"\\f118\";}\n\ -.fa-frown-o:before {content: \"\\f119\";}\n\ -.fa-meh-o:before {content: \"\\f11a\";}\n\ -.fa-gamepad:before {content: \"\\f11b\";}\n\ -.fa-keyboard-o:before {content: \"\\f11c\";}\n\ -.fa-flag-o:before {content: \"\\f11d\";}\n\ -.fa-flag-checkered:before {content: \"\\f11e\";}\n\ -.fa-terminal:before {content: \"\\f120\";}\n\ -.fa-code:before {content: \"\\f121\";}\n\ -.fa-mail-reply-all:before, .fa-reply-all:before {content: \"\\f122\";}\n\ -.fa-star-half-empty:before, .fa-star-half-full:before, .fa-star-half-o:before {content: \"\\f123\";}\n\ -.fa-location-arrow:before {content: \"\\f124\";}\n\ -.fa-crop:before {content: \"\\f125\";}\n\ -.fa-code-fork:before {content: \"\\f126\";}\n\ -.fa-unlink:before, .fa-chain-broken:before {content: \"\\f127\";}\n\ -.fa-question:before {content: \"\\f128\";}\n\ -.fa-info:before {content: \"\\f129\";}\n\ -.fa-exclamation:before {content: \"\\f12a\";}\n\ -.fa-superscript:before {content: \"\\f12b\";}\n\ -.fa-subscript:before {content: \"\\f12c\";}\n\ -.fa-eraser:before {content: \"\\f12d\";}\n\ -.fa-puzzle-piece:before {content: \"\\f12e\";}\n\ -.fa-microphone:before {content: \"\\f130\";}\n\ -.fa-microphone-slash:before {content: \"\\f131\";}\n\ -.fa-shield:before {content: \"\\f132\";}\n\ -.fa-calendar-o:before {content: \"\\f133\";}\n\ -.fa-fire-extinguisher:before {content: \"\\f134\";}\n\ -.fa-rocket:before {content: \"\\f135\";}\n\ -.fa-maxcdn:before {content: \"\\f136\";}\n\ -.fa-chevron-circle-left:before {content: \"\\f137\";}\n\ -.fa-chevron-circle-right:before {content: \"\\f138\";}\n\ -.fa-chevron-circle-up:before {content: \"\\f139\";}\n\ -.fa-chevron-circle-down:before {content: \"\\f13a\";}\n\ -.fa-html5:before {content: \"\\f13b\";}\n\ -.fa-css3:before {content: \"\\f13c\";}\n\ -.fa-anchor:before {content: \"\\f13d\";}\n\ -.fa-unlock-alt:before {content: \"\\f13e\";}\n\ -.fa-bullseye:before {content: \"\\f140\";}\n\ -.fa-ellipsis-h:before {content: \"\\f141\";}\n\ -.fa-ellipsis-v:before {content: \"\\f142\";}\n\ -.fa-rss-square:before {content: \"\\f143\";}\n\ -.fa-play-circle:before {content: \"\\f144\";}\n\ -.fa-ticket:before {content: \"\\f145\";}\n\ -.fa-minus-square:before {content: \"\\f146\";}\n\ -.fa-minus-square-o:before {content: \"\\f147\";}\n\ -.fa-level-up:before {content: \"\\f148\";}\n\ -.fa-level-down:before {content: \"\\f149\";}\n\ -.fa-check-square:before {content: \"\\f14a\";}\n\ -.fa-pencil-square:before {content: \"\\f14b\";}\n\ -.fa-external-link-square:before {content: \"\\f14c\";}\n\ -.fa-share-square:before {content: \"\\f14d\";}\n\ -.fa-compass:before {content: \"\\f14e\";}\n\ -.fa-toggle-down:before, .fa-caret-square-o-down:before {content: \"\\f150\";}\n\ -.fa-toggle-up:before, .fa-caret-square-o-up:before {content: \"\\f151\";}\n\ -.fa-toggle-right:before, .fa-caret-square-o-right:before {content: \"\\f152\";}\n\ -.fa-euro:before, .fa-eur:before {content: \"\\f153\";}\n\ -.fa-gbp:before {content: \"\\f154\";}\n\ -.fa-dollar:before, .fa-usd:before {content: \"\\f155\";}\n\ -.fa-rupee:before, .fa-inr:before {content: \"\\f156\";}\n\ -.fa-cny:before, .fa-rmb:before, .fa-yen:before, .fa-jpy:before {content: \"\\f157\";}\n\ -.fa-ruble:before, .fa-rouble:before, .fa-rub:before {content: \"\\f158\";}\n\ -.fa-won:before, .fa-krw:before {content: \"\\f159\";}\n\ -.fa-bitcoin:before, .fa-btc:before {content: \"\\f15a\";}\n\ -.fa-file:before {content: \"\\f15b\";}\n\ -.fa-file-text:before {content: \"\\f15c\";}\n\ -.fa-sort-alpha-asc:before {content: \"\\f15d\";}\n\ -.fa-sort-alpha-desc:before {content: \"\\f15e\";}\n\ -.fa-sort-amount-asc:before {content: \"\\f160\";}\n\ -.fa-sort-amount-desc:before {content: \"\\f161\";}\n\ -.fa-sort-numeric-asc:before {content: \"\\f162\";}\n\ -.fa-sort-numeric-desc:before {content: \"\\f163\";}\n\ -.fa-thumbs-up:before {content: \"\\f164\";}\n\ -.fa-thumbs-down:before {content: \"\\f165\";}\n\ -.fa-youtube-square:before {content: \"\\f166\";}\n\ -.fa-youtube:before {content: \"\\f167\";}\n\ -.fa-xing:before {content: \"\\f168\";}\n\ -.fa-xing-square:before {content: \"\\f169\";}\n\ -.fa-youtube-play:before {content: \"\\f16a\";}\n\ -.fa-dropbox:before {content: \"\\f16b\";}\n\ -.fa-stack-overflow:before {content: \"\\f16c\";}\n\ -.fa-instagram:before {content: \"\\f16d\";}\n\ -.fa-flickr:before {content: \"\\f16e\";}\n\ -.fa-adn:before {content: \"\\f170\";}\n\ -.fa-bitbucket:before {content: \"\\f171\";}\n\ -.fa-bitbucket-square:before {content: \"\\f172\";}\n\ -.fa-tumblr:before {content: \"\\f173\";}\n\ -.fa-tumblr-square:before {content: \"\\f174\";}\n\ -.fa-long-arrow-down:before {content: \"\\f175\";}\n\ -.fa-long-arrow-up:before {content: \"\\f176\";}\n\ -.fa-long-arrow-left:before {content: \"\\f177\";}\n\ -.fa-long-arrow-right:before {content: \"\\f178\";}\n\ -.fa-apple:before {content: \"\\f179\";}\n\ -.fa-windows:before {content: \"\\f17a\";}\n\ -.fa-android:before {content: \"\\f17b\";}\n\ -.fa-linux:before {content: \"\\f17c\";}\n\ -.fa-dribbble:before {content: \"\\f17d\";}\n\ -.fa-skype:before {content: \"\\f17e\";}\n\ -.fa-foursquare:before {content: \"\\f180\";}\n\ -.fa-trello:before {content: \"\\f181\";}\n\ -.fa-female:before {content: \"\\f182\";}\n\ -.fa-male:before {content: \"\\f183\";}\n\ -.fa-gittip:before, .fa-gratipay:before {content: \"\\f184\";}\n\ -.fa-sun-o:before {content: \"\\f185\";}\n\ -.fa-moon-o:before {content: \"\\f186\";}\n\ -.fa-archive:before {content: \"\\f187\";}\n\ -.fa-bug:before {content: \"\\f188\";}\n\ -.fa-vk:before {content: \"\\f189\";}\n\ -.fa-weibo:before {content: \"\\f18a\";}\n\ -.fa-renren:before {content: \"\\f18b\";}\n\ -.fa-pagelines:before {content: \"\\f18c\";}\n\ -.fa-stack-exchange:before {content: \"\\f18d\";}\n\ -.fa-arrow-circle-o-right:before {content: \"\\f18e\";}\n\ -.fa-arrow-circle-o-left:before {content: \"\\f190\";}\n\ -.fa-toggle-left:before, .fa-caret-square-o-left:before {content: \"\\f191\";}\n\ -.fa-dot-circle-o:before {content: \"\\f192\";}\n\ -.fa-wheelchair:before {content: \"\\f193\";}\n\ -.fa-vimeo-square:before {content: \"\\f194\";}\n\ -.fa-turkish-lira:before, .fa-try:before {content: \"\\f195\";}\n\ -.fa-plus-square-o:before {content: \"\\f196\";}\n\ -.fa-space-shuttle:before {content: \"\\f197\";}\n\ -.fa-slack:before {content: \"\\f198\";}\n\ -.fa-envelope-square:before {content: \"\\f199\";}\n\ -.fa-wordpress:before {content: \"\\f19a\";}\n\ -.fa-openid:before {content: \"\\f19b\";}\n\ -.fa-institution:before, .fa-bank:before, .fa-university:before {content: \"\\f19c\";}\n\ -.fa-mortar-board:before, .fa-graduation-cap:before {content: \"\\f19d\";}\n\ -.fa-yahoo:before {content: \"\\f19e\";}\n\ -.fa-google:before {content: \"\\f1a0\";}\n\ -.fa-reddit:before {content: \"\\f1a1\";}\n\ -.fa-reddit-square:before {content: \"\\f1a2\";}\n\ -.fa-stumbleupon-circle:before {content: \"\\f1a3\";}\n\ -.fa-stumbleupon:before {content: \"\\f1a4\";}\n\ -.fa-delicious:before {content: \"\\f1a5\";}\n\ -.fa-digg:before {content: \"\\f1a6\";}\n\ -.fa-pied-piper-pp:before {content: \"\\f1a7\";}\n\ -.fa-pied-piper-alt:before {content: \"\\f1a8\";}\n\ -.fa-drupal:before {content: \"\\f1a9\";}\n\ -.fa-joomla:before {content: \"\\f1aa\";}\n\ -.fa-language:before {content: \"\\f1ab\";}\n\ -.fa-fax:before {content: \"\\f1ac\";}\n\ -.fa-building:before {content: \"\\f1ad\";}\n\ -.fa-child:before {content: \"\\f1ae\";}\n\ -.fa-paw:before {content: \"\\f1b0\";}\n\ -.fa-spoon:before {content: \"\\f1b1\";}\n\ -.fa-cube:before {content: \"\\f1b2\";}\n\ -.fa-cubes:before {content: \"\\f1b3\";}\n\ -.fa-behance:before {content: \"\\f1b4\";}\n\ -.fa-behance-square:before {content: \"\\f1b5\";}\n\ -.fa-steam:before {content: \"\\f1b6\";}\n\ -.fa-steam-square:before {content: \"\\f1b7\";}\n\ -.fa-recycle:before {content: \"\\f1b8\";}\n\ -.fa-automobile:before, .fa-car:before {content: \"\\f1b9\";}\n\ -.fa-cab:before, .fa-taxi:before {content: \"\\f1ba\";}\n\ -.fa-tree:before {content: \"\\f1bb\";}\n\ -.fa-spotify:before {content: \"\\f1bc\";}\n\ -.fa-deviantart:before {content: \"\\f1bd\";}\n\ -.fa-soundcloud:before {content: \"\\f1be\";}\n\ -.fa-database:before {content: \"\\f1c0\";}\n\ -.fa-file-pdf-o:before {content: \"\\f1c1\";}\n\ -.fa-file-word-o:before {content: \"\\f1c2\";}\n\ -.fa-file-excel-o:before {content: \"\\f1c3\";}\n\ -.fa-file-powerpoint-o:before {content: \"\\f1c4\";}\n\ -.fa-file-photo-o:before, .fa-file-picture-o:before, .fa-file-image-o:before {content: \"\\f1c5\";}\n\ -.fa-file-zip-o:before, .fa-file-archive-o:before {content: \"\\f1c6\";}\n\ -.fa-file-sound-o:before, .fa-file-audio-o:before {content: \"\\f1c7\";}\n\ -.fa-file-movie-o:before, .fa-file-video-o:before {content: \"\\f1c8\";}\n\ -.fa-file-code-o:before {content: \"\\f1c9\";}\n\ -.fa-vine:before {content: \"\\f1ca\";}\n\ -.fa-codepen:before {content: \"\\f1cb\";}\n\ -.fa-jsfiddle:before {content: \"\\f1cc\";}\n\ -.fa-life-bouy:before, .fa-life-buoy:before, .fa-life-saver:before, .fa-support:before, .fa-life-ring:before {content: \"\\f1cd\";}\n\ -.fa-circle-o-notch:before {content: \"\\f1ce\";}\n\ -.fa-ra:before, .fa-resistance:before, .fa-rebel:before {content: \"\\f1d0\";}\n\ -.fa-ge:before, .fa-empire:before {content: \"\\f1d1\";}\n\ -.fa-git-square:before {content: \"\\f1d2\";}\n\ -.fa-git:before {content: \"\\f1d3\";}\n\ -.fa-y-combinator-square:before, .fa-yc-square:before, .fa-hacker-news:before {content: \"\\f1d4\";}\n\ -.fa-tencent-weibo:before {content: \"\\f1d5\";}\n\ -.fa-qq:before {content: \"\\f1d6\";}\n\ -.fa-wechat:before, .fa-weixin:before {content: \"\\f1d7\";}\n\ -.fa-send:before, .fa-paper-plane:before {content: \"\\f1d8\";}\n\ -.fa-send-o:before, .fa-paper-plane-o:before {content: \"\\f1d9\";}\n\ -.fa-history:before {content: \"\\f1da\";}\n\ -.fa-circle-thin:before {content: \"\\f1db\";}\n\ -.fa-header:before {content: \"\\f1dc\";}\n\ -.fa-paragraph:before {content: \"\\f1dd\";}\n\ -.fa-sliders:before {content: \"\\f1de\";}\n\ -.fa-share-alt:before {content: \"\\f1e0\";}\n\ -.fa-share-alt-square:before {content: \"\\f1e1\";}\n\ -.fa-bomb:before {content: \"\\f1e2\";}\n\ -.fa-soccer-ball-o:before, .fa-futbol-o:before {content: \"\\f1e3\";}\n\ -.fa-tty:before {content: \"\\f1e4\";}\n\ -.fa-binoculars:before {content: \"\\f1e5\";}\n\ -.fa-plug:before {content: \"\\f1e6\";}\n\ -.fa-slideshare:before {content: \"\\f1e7\";}\n\ -.fa-twitch:before {content: \"\\f1e8\";}\n\ -.fa-yelp:before {content: \"\\f1e9\";}\n\ -.fa-newspaper-o:before {content: \"\\f1ea\";}\n\ -.fa-wifi:before {content: \"\\f1eb\";}\n\ -.fa-calculator:before {content: \"\\f1ec\";}\n\ -.fa-paypal:before {content: \"\\f1ed\";}\n\ -.fa-google-wallet:before {content: \"\\f1ee\";}\n\ -.fa-cc-visa:before {content: \"\\f1f0\";}\n\ -.fa-cc-mastercard:before {content: \"\\f1f1\";}\n\ -.fa-cc-discover:before {content: \"\\f1f2\";}\n\ -.fa-cc-amex:before {content: \"\\f1f3\";}\n\ -.fa-cc-paypal:before {content: \"\\f1f4\";}\n\ -.fa-cc-stripe:before {content: \"\\f1f5\";}\n\ -.fa-bell-slash:before {content: \"\\f1f6\";}\n\ -.fa-bell-slash-o:before {content: \"\\f1f7\";}\n\ -.fa-trash:before {content: \"\\f1f8\";}\n\ -.fa-copyright:before {content: \"\\f1f9\";}\n\ -.fa-at:before {content: \"\\f1fa\";}\n\ -.fa-eyedropper:before {content: \"\\f1fb\";}\n\ -.fa-paint-brush:before {content: \"\\f1fc\";}\n\ -.fa-birthday-cake:before {content: \"\\f1fd\";}\n\ -.fa-area-chart:before {content: \"\\f1fe\";}\n\ -.fa-pie-chart:before {content: \"\\f200\";}\n\ -.fa-line-chart:before {content: \"\\f201\";}\n\ -.fa-lastfm:before {content: \"\\f202\";}\n\ -.fa-lastfm-square:before {content: \"\\f203\";}\n\ -.fa-toggle-off:before {content: \"\\f204\";}\n\ -.fa-toggle-on:before {content: \"\\f205\";}\n\ -.fa-bicycle:before {content: \"\\f206\";}\n\ -.fa-bus:before {content: \"\\f207\";}\n\ -.fa-ioxhost:before {content: \"\\f208\";}\n\ -.fa-angellist:before {content: \"\\f209\";}\n\ -.fa-cc:before {content: \"\\f20a\";}\n\ -.fa-shekel:before, .fa-sheqel:before, .fa-ils:before {content: \"\\f20b\";}\n\ -.fa-meanpath:before {content: \"\\f20c\";}\n\ -.fa-buysellads:before {content: \"\\f20d\";}\n\ -.fa-connectdevelop:before {content: \"\\f20e\";}\n\ -.fa-dashcube:before {content: \"\\f210\";}\n\ -.fa-forumbee:before {content: \"\\f211\";}\n\ -.fa-leanpub:before {content: \"\\f212\";}\n\ -.fa-sellsy:before {content: \"\\f213\";}\n\ -.fa-shirtsinbulk:before {content: \"\\f214\";}\n\ -.fa-simplybuilt:before {content: \"\\f215\";}\n\ -.fa-skyatlas:before {content: \"\\f216\";}\n\ -.fa-cart-plus:before {content: \"\\f217\";}\n\ -.fa-cart-arrow-down:before {content: \"\\f218\";}\n\ -.fa-diamond:before {content: \"\\f219\";}\n\ -.fa-ship:before {content: \"\\f21a\";}\n\ -.fa-user-secret:before {content: \"\\f21b\";}\n\ -.fa-motorcycle:before {content: \"\\f21c\";}\n\ -.fa-street-view:before {content: \"\\f21d\";}\n\ -.fa-heartbeat:before {content: \"\\f21e\";}\n\ -.fa-venus:before {content: \"\\f221\";}\n\ -.fa-mars:before {content: \"\\f222\";}\n\ -.fa-mercury:before {content: \"\\f223\";}\n\ -.fa-intersex:before, .fa-transgender:before {content: \"\\f224\";}\n\ -.fa-transgender-alt:before {content: \"\\f225\";}\n\ -.fa-venus-double:before {content: \"\\f226\";}\n\ -.fa-mars-double:before {content: \"\\f227\";}\n\ -.fa-venus-mars:before {content: \"\\f228\";}\n\ -.fa-mars-stroke:before {content: \"\\f229\";}\n\ -.fa-mars-stroke-v:before {content: \"\\f22a\";}\n\ -.fa-mars-stroke-h:before {content: \"\\f22b\";}\n\ -.fa-neuter:before {content: \"\\f22c\";}\n\ -.fa-genderless:before {content: \"\\f22d\";}\n\ -.fa-facebook-official:before {content: \"\\f230\";}\n\ -.fa-pinterest-p:before {content: \"\\f231\";}\n\ -.fa-whatsapp:before {content: \"\\f232\";}\n\ -.fa-server:before {content: \"\\f233\";}\n\ -.fa-user-plus:before {content: \"\\f234\";}\n\ -.fa-user-times:before {content: \"\\f235\";}\n\ -.fa-hotel:before, .fa-bed:before {content: \"\\f236\";}\n\ -.fa-viacoin:before {content: \"\\f237\";}\n\ -.fa-train:before {content: \"\\f238\";}\n\ -.fa-subway:before {content: \"\\f239\";}\n\ -.fa-medium:before {content: \"\\f23a\";}\n\ -.fa-yc:before, .fa-y-combinator:before {content: \"\\f23b\";}\n\ -.fa-optin-monster:before {content: \"\\f23c\";}\n\ -.fa-opencart:before {content: \"\\f23d\";}\n\ -.fa-expeditedssl:before {content: \"\\f23e\";}\n\ -.fa-battery-4:before, .fa-battery:before, .fa-battery-full:before {content: \"\\f240\";}\n\ -.fa-battery-3:before, .fa-battery-three-quarters:before {content: \"\\f241\";}\n\ -.fa-battery-2:before, .fa-battery-half:before {content: \"\\f242\";}\n\ -.fa-battery-1:before, .fa-battery-quarter:before {content: \"\\f243\";}\n\ -.fa-battery-0:before, .fa-battery-empty:before {content: \"\\f244\";}\n\ -.fa-mouse-pointer:before {content: \"\\f245\";}\n\ -.fa-i-cursor:before {content: \"\\f246\";}\n\ -.fa-object-group:before {content: \"\\f247\";}\n\ -.fa-object-ungroup:before {content: \"\\f248\";}\n\ -.fa-sticky-note:before {content: \"\\f249\";}\n\ -.fa-sticky-note-o:before {content: \"\\f24a\";}\n\ -.fa-cc-jcb:before {content: \"\\f24b\";}\n\ -.fa-cc-diners-club:before {content: \"\\f24c\";}\n\ -.fa-clone:before {content: \"\\f24d\";}\n\ -.fa-balance-scale:before {content: \"\\f24e\";}\n\ -.fa-hourglass-o:before {content: \"\\f250\";}\n\ -.fa-hourglass-1:before, .fa-hourglass-start:before {content: \"\\f251\";}\n\ -.fa-hourglass-2:before, .fa-hourglass-half:before {content: \"\\f252\";}\n\ -.fa-hourglass-3:before, .fa-hourglass-end:before {content: \"\\f253\";}\n\ -.fa-hourglass:before {content: \"\\f254\";}\n\ -.fa-hand-grab-o:before, .fa-hand-rock-o:before {content: \"\\f255\";}\n\ -.fa-hand-stop-o:before, .fa-hand-paper-o:before {content: \"\\f256\";}\n\ -.fa-hand-scissors-o:before {content: \"\\f257\";}\n\ -.fa-hand-lizard-o:before {content: \"\\f258\";}\n\ -.fa-hand-spock-o:before {content: \"\\f259\";}\n\ -.fa-hand-pointer-o:before {content: \"\\f25a\";}\n\ -.fa-hand-peace-o:before {content: \"\\f25b\";}\n\ -.fa-trademark:before {content: \"\\f25c\";}\n\ -.fa-registered:before {content: \"\\f25d\";}\n\ -.fa-creative-commons:before {content: \"\\f25e\";}\n\ -.fa-gg:before {content: \"\\f260\";}\n\ -.fa-gg-circle:before {content: \"\\f261\";}\n\ -.fa-tripadvisor:before {content: \"\\f262\";}\n\ -.fa-odnoklassniki:before {content: \"\\f263\";}\n\ -.fa-odnoklassniki-square:before {content: \"\\f264\";}\n\ -.fa-get-pocket:before {content: \"\\f265\";}\n\ -.fa-wikipedia-w:before {content: \"\\f266\";}\n\ -.fa-safari:before {content: \"\\f267\";}\n\ -.fa-chrome:before {content: \"\\f268\";}\n\ -.fa-firefox:before {content: \"\\f269\";}\n\ -.fa-opera:before {content: \"\\f26a\";}\n\ -.fa-internet-explorer:before {content: \"\\f26b\";}\n\ -.fa-tv:before, .fa-television:before {content: \"\\f26c\";}\n\ -.fa-contao:before {content: \"\\f26d\";}\n\ -.fa-500px:before {content: \"\\f26e\";}\n\ -.fa-amazon:before {content: \"\\f270\";}\n\ -.fa-calendar-plus-o:before {content: \"\\f271\";}\n\ -.fa-calendar-minus-o:before {content: \"\\f272\";}\n\ -.fa-calendar-times-o:before {content: \"\\f273\";}\n\ -.fa-calendar-check-o:before {content: \"\\f274\";}\n\ -.fa-industry:before {content: \"\\f275\";}\n\ -.fa-map-pin:before {content: \"\\f276\";}\n\ -.fa-map-signs:before {content: \"\\f277\";}\n\ -.fa-map-o:before {content: \"\\f278\";}\n\ -.fa-map:before {content: \"\\f279\";}\n\ -.fa-commenting:before {content: \"\\f27a\";}\n\ -.fa-commenting-o:before {content: \"\\f27b\";}\n\ -.fa-houzz:before {content: \"\\f27c\";}\n\ -.fa-vimeo:before {content: \"\\f27d\";}\n\ -.fa-black-tie:before {content: \"\\f27e\";}\n\ -.fa-fonticons:before {content: \"\\f280\";}\n\ -.fa-reddit-alien:before {content: \"\\f281\";}\n\ -.fa-edge:before {content: \"\\f282\";}\n\ -.fa-credit-card-alt:before {content: \"\\f283\";}\n\ -.fa-codiepie:before {content: \"\\f284\";}\n\ -.fa-modx:before {content: \"\\f285\";}\n\ -.fa-fort-awesome:before {content: \"\\f286\";}\n\ -.fa-usb:before {content: \"\\f287\";}\n\ -.fa-product-hunt:before {content: \"\\f288\";}\n\ -.fa-mixcloud:before {content: \"\\f289\";}\n\ -.fa-scribd:before {content: \"\\f28a\";}\n\ -.fa-pause-circle:before {content: \"\\f28b\";}\n\ -.fa-pause-circle-o:before {content: \"\\f28c\";}\n\ -.fa-stop-circle:before {content: \"\\f28d\";}\n\ -.fa-stop-circle-o:before {content: \"\\f28e\";}\n\ -.fa-shopping-bag:before {content: \"\\f290\";}\n\ -.fa-shopping-basket:before {content: \"\\f291\";}\n\ -.fa-hashtag:before {content: \"\\f292\";}\n\ -.fa-bluetooth:before {content: \"\\f293\";}\n\ -.fa-bluetooth-b:before {content: \"\\f294\";}\n\ -.fa-percent:before {content: \"\\f295\";}\n\ -.fa-gitlab:before {content: \"\\f296\";}\n\ -.fa-wpbeginner:before {content: \"\\f297\";}\n\ -.fa-wpforms:before {content: \"\\f298\";}\n\ -.fa-envira:before {content: \"\\f299\";}\n\ -.fa-universal-access:before {content: \"\\f29a\";}\n\ -.fa-wheelchair-alt:before {content: \"\\f29b\";}\n\ -.fa-question-circle-o:before {content: \"\\f29c\";}\n\ -.fa-blind:before {content: \"\\f29d\";}\n\ -.fa-audio-description:before {content: \"\\f29e\";}\n\ -.fa-volume-control-phone:before {content: \"\\f2a0\";}\n\ -.fa-braille:before {content: \"\\f2a1\";}\n\ -.fa-assistive-listening-systems:before {content: \"\\f2a2\";}\n\ -.fa-asl-interpreting:before, .fa-american-sign-language-interpreting:before {content: \"\\f2a3\";}\n\ -.fa-deafness:before, .fa-hard-of-hearing:before, .fa-deaf:before {content: \"\\f2a4\";}\n\ -.fa-glide:before {content: \"\\f2a5\";}\n\ -.fa-glide-g:before {content: \"\\f2a6\";}\n\ -.fa-signing:before, .fa-sign-language:before {content: \"\\f2a7\";}\n\ -.fa-low-vision:before {content: \"\\f2a8\";}\n\ -.fa-viadeo:before {content: \"\\f2a9\";}\n\ -.fa-viadeo-square:before {content: \"\\f2aa\";}\n\ -.fa-snapchat:before {content: \"\\f2ab\";}\n\ -.fa-snapchat-ghost:before {content: \"\\f2ac\";}\n\ -.fa-snapchat-square:before {content: \"\\f2ad\";}\n\ -.fa-pied-piper:before {content: \"\\f2ae\";}\n\ -.fa-first-order:before {content: \"\\f2b0\";}\n\ -.fa-yoast:before {content: \"\\f2b1\";}\n\ -.fa-themeisle:before {content: \"\\f2b2\";}\n\ -.fa-google-plus-circle:before, .fa-google-plus-official:before {content: \"\\f2b3\";}\n\ -.fa-fa:before, .fa-font-awesome:before {content: \"\\f2b4\";}\n\ -.fa-handshake-o:before {content: \"\\f2b5\";}\n\ -.fa-envelope-open:before {content: \"\\f2b6\";}\n\ -.fa-envelope-open-o:before {content: \"\\f2b7\";}\n\ -.fa-linode:before {content: \"\\f2b8\";}\n\ -.fa-address-book:before {content: \"\\f2b9\";}\n\ -.fa-address-book-o:before {content: \"\\f2ba\";}\n\ -.fa-vcard:before, .fa-address-card:before {content: \"\\f2bb\";}\n\ -.fa-vcard-o:before, .fa-address-card-o:before {content: \"\\f2bc\";}\n\ -.fa-user-circle:before {content: \"\\f2bd\";}\n\ -.fa-user-circle-o:before {content: \"\\f2be\";}\n\ -.fa-user-o:before {content: \"\\f2c0\";}\n\ -.fa-id-badge:before {content: \"\\f2c1\";}\n\ -.fa-drivers-license:before, .fa-id-card:before {content: \"\\f2c2\";}\n\ -.fa-drivers-license-o:before, .fa-id-card-o:before {content: \"\\f2c3\";}\n\ -.fa-quora:before {content: \"\\f2c4\";}\n\ -.fa-free-code-camp:before {content: \"\\f2c5\";}\n\ -.fa-telegram:before {content: \"\\f2c6\";}\n\ -.fa-thermometer-4:before, .fa-thermometer:before, .fa-thermometer-full:before {content: \"\\f2c7\";}\n\ -.fa-thermometer-3:before, .fa-thermometer-three-quarters:before {content: \"\\f2c8\";}\n\ -.fa-thermometer-2:before, .fa-thermometer-half:before {content: \"\\f2c9\";}\n\ -.fa-thermometer-1:before, .fa-thermometer-quarter:before {content: \"\\f2ca\";}\n\ -.fa-thermometer-0:before, .fa-thermometer-empty:before {content: \"\\f2cb\";}\n\ -.fa-shower:before {content: \"\\f2cc\";}\n\ -.fa-bathtub:before, .fa-s15:before, .fa-bath:before {content: \"\\f2cd\";}\n\ -.fa-podcast:before {content: \"\\f2ce\";}\n\ -.fa-window-maximize:before {content: \"\\f2d0\";}\n\ -.fa-window-minimize:before {content: \"\\f2d1\";}\n\ -.fa-window-restore:before {content: \"\\f2d2\";}\n\ -.fa-times-rectangle:before, .fa-window-close:before {content: \"\\f2d3\";}\n\ -.fa-times-rectangle-o:before, .fa-window-close-o:before {content: \"\\f2d4\";}\n\ -.fa-bandcamp:before {content: \"\\f2d5\";}\n\ -.fa-grav:before {content: \"\\f2d6\";}\n\ -.fa-etsy:before {content: \"\\f2d7\";}\n\ -.fa-imdb:before {content: \"\\f2d8\";}\n\ -.fa-ravelry:before {content: \"\\f2d9\";}\n\ -.fa-eercast:before {content: \"\\f2da\";}\n\ -.fa-microchip:before {content: \"\\f2db\";}\n\ -.fa-snowflake-o:before {content: \"\\f2dc\";}\n\ -.fa-superpowers:before {content: \"\\f2dd\";}\n\ -.fa-wpexplorer:before {content: \"\\f2de\";}\n\ -.fa-meetup:before {content: \"\\f2e0\";}\n\ -.fa::before {\n\ - font-family: FontAwesome;\n\ - font-weight: 400;\n\ - font-style: normal;\n\ - -webkit-font-smoothing: antialiased;\n\ - text-decoration: inherit;\n\ - speak: none;\n\ - display: inline-block;\n\ - font-size: 13px;\n\ - visibility: visible;\n\ -}\n\ -:root:not(.shortcut-icons) #shortcuts .fa::before {\n\ - display: none;\n\ -}\n\ -:root.shortcut-icons #shortcuts .fa::before {\n\ - font-size: 15px !important;\n\ - margin-top: -3px !important;\n\ - position: relative;\n\ - top: 1px;\n\ -}\n\ -:root.shortcut-icons #shortcuts .fa, .menu-button .fa {\n\ - font-size: 0;\n\ - visibility: hidden;\n\ -}\n\ -:root.shortcut-icons .shortcut.brackets-wrap::after,\n\ -:root.shortcut-icons .shortcut.brackets-wrap::before {\n\ - display: none;\n\ -}\n\ -:root.shortcut-icons #shortcuts a .fa,\n\ -.menu-button .fa,\n\ -.hide-reply-button .fa,\n\ -.hide-thread-button .fa {\n\ - display: inline;\n\ -}\n\ -.fa-spin::before {\n\ - -webkit-animation:spin 2s infinite linear;\n\ - -moz-animation:spin 2s infinite linear;\n\ - -o-animation:spin 2s infinite linear;\n\ - animation:spin 2s infinite linear;\n\ -}\n\ -@-moz-keyframes spin {\n\ - 0% {-moz-transform:rotate(0deg);}\n\ - 100% {-moz-transform:rotate(359deg);}\n\ -}\n\ -@-webkit-keyframes spin {\n\ - 0% {-webkit-transform:rotate(0deg);}\n\ - 100% {-webkit-transform:rotate(359deg);}\n\ -}\n\ -@keyframes spin {\n\ - 0% {transform:rotate(0deg);}\n\ - 100% {transform:rotate(359deg);}\n\ -}\n\ -/* 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\ -}\n\ -label {\n\ - cursor: pointer;\n\ -}\n\ -a[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\ -}\n\ -body.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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Anti-autoplay */\n\ -audio.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\ -/* 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\ -/* 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\ -/* 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\ -}\n\ -div[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\ -/* 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\ -/* 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\ -/* Copy Text Link's textarea element */\n\ -textarea.copy-text-element {\n\ - height: 0;\n\ - width: 0;\n\ - position: absolute;\n\ - top: -10000px;\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\ -/* 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\ -/* 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\ -/* 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,\");\n\ -}\n\ -.watch-thread-link.watched {\n\ - opacity: 1;\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\ -/* 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\ -/* 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\ -/* File */\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 {\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 */\n\ -input[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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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),\n\ -body: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\ -}\n\ -input.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\ -/* 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\ -/* 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\ -}\n\ -input#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\ -/* 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,\n\ -input[type=\"checkbox\"]:focus ~ .checkbox-letter,\n\ -input[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\ -/* 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\ -/* 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\ -}\n\ -a: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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -: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\ -/* 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\ -/* PostJumper */\n\ -.postJumper > .prev,\n\ -.postJumper > .next {\n\ - font-size: 120%;\n\ -}\n\ -/* PSA */\n\ -.fcx-announcement {\n\ - text-align: center;\n\ -}\n\ -.fcx-announcement a {\n\ - text-decoration: underline;\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.yotsuba .indicator {\n\ - color: #F0E0D6;\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\ -/* 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\ -/* Unread */\n\ -:root.yotsuba .unread-mark-read {\n\ - background-color: rgba(240,224,214,0.5);\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\ -/* Watcher Favicon */\n\ -:root.yotsuba .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.yotsuba-b .indicator {\n\ - color: #D6DAF0;\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\ -/* 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\ -/* Unread */\n\ -:root.yotsuba-b .unread-mark-read {\n\ - background-color: rgba(214,218,240,0.5);\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\ -/* Watcher Favicon */\n\ -:root.yotsuba-b .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.futaba .indicator {\n\ - color: #F0E0D6;\n\ -}\n\ -/* Anonymize */\n\ -:root.futaba.anonymize $site$info$name::before {\n\ - font-size: 12pt;\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\ -/* 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\ -/* Unread */\n\ -:root.futaba .unread-mark-read {\n\ - background-color: rgba(240,224,214,0.5);\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\ -/* Watcher Favicon */\n\ -:root.futaba .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.burichan .indicator {\n\ - color: #D6DAF0;\n\ -}\n\ -/* Anonymize */\n\ -:root.burichan.anonymize $site$info$name::before {\n\ - font-size: 12pt;\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\ -/* 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\ -/* Unread */\n\ -:root.burichan .unread-mark-read {\n\ - background-color: rgba(214,218,240,0.5);\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\ -/* Watcher Favicon */\n\ -:root.burichan .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\n\ -}\n\ -/* General */\n\ -:root.tomorrow .dialog {\n\ - background-color: #282A2E;\n\ - border-color: #111;\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.tomorrow .indicator {\n\ - color: #282A2E;\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Watcher Favicon */\n\ -:root.tomorrow .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.photon .indicator {\n\ - color: #DDD;\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\ -/* 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\ -/* Unread */\n\ -:root.photon .unread-mark-read {\n\ - background-color: rgba(221,221,221,0.5);\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\ -/* Watcher Favicon */\n\ -:root.photon .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.spooky .indicator {\n\ - color: #171526;\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\ -/* 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\ -: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\ -/* 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\ -/* 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\ -/* 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\ -/* Watcher Favicon */\n\ -:root.spooky .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\n\ -}\n\ -/* Link Title Favicons */\n\ -.linkify.audio::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.bitchute::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAadQTFRFAAAAwzw8xDs7cY6O0iws0ysrtF9f0Sws1CwsyzU1zTIy1igoyzQ01icnY7i4t0hI0S4u0ysr1Soq1ikp1ikp1Soq0ysr0S4uu0VFzjEx1Csr1ygo2Ccn2Ccn1ygo1CoqzjExzjAw1Skp2Ccn2Ccn1ikp0TAwxzY21Soq1SoqyzQ00iws1ygo1ygo0yws1Soq1Skp1igo1igo1igo1igo1igo1igo1Coq1Soq0C0t1ygo1ygo0S4unV5e1Csr1ygo1ygo1CsruUdHxzg41Skp1ygo1CsryTU10C4u1igo1ycn1ygo0i0txjo60S0t1ikp1ygo1ikp1Cws1Coq1Coq0yws0S0tyzQ00iws1Soq0ysr0i0txDs72Ccn2CUl2CYm2CQk3EFB2S8v2zw82jY24FZW3D0931FR3EBA3UND8LS04FVV7qys4V9f4WBg+erq766u9t7e7qqq2Ckp54KC9+Pj6pSU+Ojo5XNz9NHR6YqK8bu765ub5G5u9M3N6ImJ88vL5XV165eX3UVF6pWV3UhI2Soq2jU12Coq2jQ02Cgo2Sws////FaxLuAAAAF10Uk5TAAAAAAAAAAAAAAAAAAAAASJnoLy9oWolAhBz1vr72XgTGKf8/a4cCpuiDVvz9mS6xOvy9vzg6aGsPOToRAFv9fh2Awm07XgIMd765UEDOsfemVhhY00nBommbCkEI8horgAAAL5JREFUKBUFwbFKA0EUQNF7387sMq4EmzRpLSSdIBYKFv6Af2prnSYkRT4gWFgkCBJQ0EIFdcZzBCeqqh4qdk7VW2ChPusw02sAYKU7z7wEAAA2piQKFbrWSHazc1J0XWs5pdxPDykcVX+7Y9UxUsSo+s7PibqPFBRV/C5qi4i/UkrJrc7L47Bt4ZWnUaMCAE9GSrtKBQD2fR+bnAEAeOn7dUTOwApe35bDsPz0zsniQlV98IN0tJ3f6P0XAMA/kxou7OXCdnoAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.clyp::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAwUExURTSY22ey5E2l4KbS75rM7Y3F64C/6f///8zl9nS45r/f9PL5/UGe3bPY8Vqr4v///wNjrzUAAAABYktHRA8YugDZAAAAB3RJTUUH4AINEi85AIH95AAAAE9JREFUCNdjYMAGGBWgDGYHCM2a3hkAZmi0dzSBaKaO9o5moCqmLiCjYzNQyw4QowIodQzI6E0AKcpo72gE6+Jyb1kAMehUA9RktgdYbQYAjGIVNGGXBJkAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.dailymotion::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAnUExURQBk3ff6/trp+kKO5wZt3xx54q7P9Ozz/IS17zOG5WKh653E8sbc9/GbbcoAAABZSURBVAjXY2BAASyhDhAGc9oECMOjyAAiESEEYrBYpLWBGcwHxcvBjDDxHelghpF0yDQwY3kVgweEUeEQDWbMEepqAjO8FMsLIeYsU8o+BrbCdWboTAe4AwALXxWGjW41FwAAAABJRU5ErkJggg==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.gfycat::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAjVBMVEWn3gCo3gSr3w2t4BSu4Bav4Ri35C+45DK45DO55DXA50rA50vB50zC6E/D6FTF6VjG6VvL62vN7G/P7XbQ7XfW74vY8JDa8ZTe8qDe8qLf86Pi9Kzj9K7k9LHp9sDp98Lq98Ps+Mr0++L5/O75/fD6/fH6/fL6/fP7/fT7/fb8/ff8/vj8/vn+/v7///91X4cfAAAAcklEQVR42o3M2xKBUACF4aVQckrIuRJK6H//x2sme4/MuPDfre9i6c/Cc3U5Dj87BuAxsXvGu6JvIIXEHRWwNHCHQNrCzkAFkbSBg4EM8i+Yw7PXBa3zRfuxVyf/Bis7nKwGKAcWxgC8prI5Sc315OlnDfzpDar2S9/oAAAAAElFTkSuQmCC') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.gist::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.image::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.installgentoo::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.liveleak::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.pastebin::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB1FBMVEUAAAAAAAAAAABWYWwAAABbY3BbYm5dZnFdZXJeZnMEBAQHCAhYYGpdZnFdZnBgaHIlJyomKCooKi09QkdESU5eZGtdYmhdYmleY2lrcXdqb3Rqb3Rqb3SSmJ+SlJeWmJutr7GtrrCWm6ChpKhbW1tmZmZvb290dHR3d3d4eHh5eXl6enp8fHx+gIJ/f3+CgoKDg4OEhISFhYWHh4eKioqKjI2Li4uMjIyOjo6Pj4+QkJCRkZGSkpKUlJSVl5mWlpaYmZqZm52ampqbm5ucnJydnZ2enp6fn5+hoaGioqKkpKSkpaalpaWmp6mmp6qnqauoqKioqquoqq2qqqqrrK2srKysra6srrCsrrGurq6vr6+wsLCxsbGysrKztLa0tLS1t7m2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr7AwMDAwsTBwcHExcfFxcXFxsnGxsbHx8fIyMjJycnMzMzNzc3Ozs7O0NLPz8/Q0NDR0dHR09XT09PV1dXV1dbV1tfV19rW1tbX19fX19jY2tzZ2dnZ2tva2tra3N3a3N7c3Nze3t7f39/f4OHg4ODi4uLl5+jm5ubs7Ozs7e3u7u7v7+/v8PDw8PDx8fHy8vLz8/P29vYSoLMZAAAAJHRSTlMABAUGCwsNHCAiLzMzMzZEYGJwgIuOnJycnqmqq9bc3+/w8fkZ0N/uAAAA/klEQVQoU2NgYGDl5YMDdgYGBmZZ3964CYFtIR3e9Q7K/AwMHI55KfaFmcHWMy3K3MwlGRg4wz0zdYpcorRbNbL0LaWAAp3ts2umV8wo6MupTauQBgqUG03VL7W3sfZSb1erAgm02M+yzYrVCXUy6zapAQlUx/dEdyX3J3ZHVUYVywAF8o2rDNN1Go2jzGLMokAC2QbuSc42mXmaOXop9iAtCXrJ5qXWjT59Abl2ESJAAX/tSIMMiyrrqQ3T6uS5gQK6kSqpqkUermGTexQFmYACflqR+hlWZSamzQpCLEDPsSmVVDT1TJw0JUhOAMRnYOARFRMTE5cQF+ZiBPIAII5B3EVG0b4AAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.peertube::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABIFBMVEUhHyAAAABzPBnxaA3CWBEnJSYbGRptbW16enpzc3PTayWhb04hHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyApIh+0UhMfHiBWMhvsZg7zaQ0hHyAhHyAXHCHzaQ3xaA3xaA3xaA3xaA0hHyAhHyDxaA3xaA3xaA3xaA3xaA3xaA0oJickIiMdGxwUEhPxaA3xaA3xaA1sbGxwcHB3d3eFhYXxaA3xaA3xaA1zc3Nzc3Nzc3Nzc3Nzc3PxaA3xaA3xaA1zc3Nzc3NtdHjxaA3xaA1yc3STcFnvaA/yaAxzc3N4c2/FbDFzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3MhHyDxaA1zc3MAAAAfljyVAAAAXHRSTlMAAAAAAAAAAAAAAAAZkjMBHOLXYArj8p0u2VsJ1XaGL/OhKyXc1WEN2gwk2/SjKgEYiS4B/tYFGosqAdleAxzj12ML9Z8s850rJWbYeYMs1F8Koiri1V0MGZY0AYbIBFIAAAABYktHRAH/Ai3eAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4wYXFBUVX81QWQAAAKxJREFUGNNVz9UWgkAQANDBtdbu7lZsxe7ubpH//wxBPKDzNvdMAmi0Oj0QQgAYjCazBX7BStvsDqHoAzTtdLklf+Dx+vwICRAIhsKRaCyOvpAwJ6Up8pXOZHOIAFm+UCzJEQuvMhWrIFBUa/WGkodmq40Ad7q9/kDFwnA05lpYYCbT2ZykFvxQDhhmuVpvcvxaHra7vfp72KflcMSYEOB0vlyx+By+3R9PMSfe+P0enM1454kAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDYtMjRUMDM6MjE6MjEtMDc6MDDse6MAAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTA2LTI0VDAzOjIxOjIxLTA3OjAwnSYbvAAAAABJRU5ErkJggg==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.soundcloud::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABsklEQVQ4y5WTy2pUQRCGv2rbzDjJeAlIBmOyipGIIJqFEBDElwh4yULGeRFXPoEIBl/AvQ/gC2RnxCAoxijiwks852S6+3dxzslcHJCpTXVX11/Xv0097gLPgVNMJxnQNfX4zsqleWbnpoMf/oa9d988MM9MC/rp+E0a+A0dsVobMNMCOO8B6McRoABJI+A6gJmN3D2A8jgEBCEkSEMBrcrsDAzDWWn3AjgKFaDMmgRqniGFgsaDp1jrLOngDf1XT1D+A1dFc4MKAkkiCVKjjVu7g9+4Rzx4i1u6hjXbuMWr0O5QPNvCu7IaCZwEKQukLGDrm5x8uI0tr6MkiGlkiv7yLfzN+6S5i6QsIMABkEfcxhbWWYMkVAOjxvYAjc3HNHrbKI9VBQBFwF25XQKSBjqIf1YBuAurEMrczgDygD6/x2LCpFLXLUyQ+PoldphhBhYfIX09XU1+Flaukz7uYqs3SHs7cG4BmTsmkBUF9mmXEwa28BNLPaQPLepuNcbGSWQquQC2/Kdcox1FUGkcB0ykck1nA2+wTzMs8stGnP4rbWGw74EuS/GFQWfK7/wF6P4F7fzIAYkdmdEAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.streamable::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.twitchtv::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAYUExURf///2RBpWRBpWRBpWRBpWRBpWRBpf///+zQyUYAAAAGdFJOUwFdZX0lTzs4r5oAAAABYktHRAcWYYjrAAAAB3RJTUUH4AINEi42iSXRNAAAAD1JREFUCNdjYEiDAAZGGIMtjQEEUBlMCWoEGci6mGEMsxQgIy0BiB3AjLS0FAYQIw0kwABipoI1AhkBQBIAFCIXxiHgq80AAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.twitter::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAEsUExURf///1Cf21Gg3FGi31Gh3VKj4FGh3lKj4VKk4lKl41Ol5FOn51Sp6VSo6FOn5lCf21Gg3FGh3VGi31Gi31Gh3lGg3FGg3FGg3FGg3FGh3lGg3FGi31Kk4lKj4FGh3lGi31Kk4lGh3lGg3FGh3lOm5FOm5VGi31Kj4VSo6FGi31Gh3VGg3FKj4FOn51Gi31So6FWr7VOl5FGi31On51Sq6lKk4lOo51Sp6VOm5FSq61Ws7VOn51Oo51Sq61Ol5FOm5FSq61Wr7VOo51On51Sr7FWs7VSp6lGg3FGh3VOm5FWr7VSp6lKj4VOm5FSo6FSr7FWs7VWs7VWr7VSq6lOo51Om5FOo51So6FOm5VOl5FSq61Ws7VSr7FSp6lSp6VWs7lWr7VKk4lSq6v///6E3MNsAAABVdFJOUwAAAAAAAAAAAAAAAAAAAB0Ii+3xnBVTJhfsMKb+qTEp9GwBF/7lLAbo0m4pLkUTdvk2Ev3+EZnOBo/3Z8ffCRzH/D0OqPxiLnvx3UI8m9n1++GwXQZNS29BAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+ACDRIwBwy67tEAAADKSURBVBjTY2BAB4xogIGRH8IQEBQSFhEVE2eQkJQC8ZmkQ8PCI2Rk5RjkIxUUlRgZlVWioqNjYlXVGNQ14iI1tbR14qLj4+MTdJkZ9PQNosJCE0OjgPz4KEMWBiPjhPiEmKQokIJ4E1MmBmazhHg4MGdlYmCzsLSC8ROsmRkZmFht4Eps7ViADmOzd4DyHZ2YmYACTOzOLmATXd04mIBOd/eQ9owFCXh5c7KB/MLi4+vnHxAYFBzCwcYEEmBi5uLm4eHl42RmAnsSAMZBLgZiFUQ5AAAAAElFTkSuQmCC') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.video::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAxgDGAP8nNqN7AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gMZBjQQLEEqGwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAA5SURBVDjLY2AYaMDIwMDwn1JD/lPCZhpwL+B1wf///ykzgBhDiAoDfIYQZQAjIyP5BuDTPJqQqAQAvW0ZAMk8+EEAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.vidlii::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.vimeo::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAYFBMVEUAAAAIdZUKh6sLlLkLmr4LmsAMp88NrdYVW3MZj7Acstkrt9s1e5E7vN5EfI9JvdtKwuBijp5kpbl30eiDt8aG1uqRr7qTyNehxM+k4PCy3enB3OTg6Ovv9PXw+fz////L9U5WAAAAAXRSTlMAQObYZgAAAIFJREFUeNplz90OwiAMBWAQpAoyxclkP3je/y0H2AQXz0WT8100rRD6kNI9/cRroemQL3hXhoujZYj4OHoAmBvYGcBISwbWBvfXCrytnIDUQMkbsBpagMA7zhtQdyTFQAmIG7IkYniiZuh3XGsPqoOZkMOJOpAcLqUzNFGGu/57fwc1hgtp0mVSyQAAAABJRU5ErkJggg==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.vine::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.vocaroo::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.youtube::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAYAAABr5z2BAAABIklEQVQoz53LvUrDUBjG8bOoOammSf1IoBSvoCB4JeIqOHgBLt6AIMRBBQelWurQ2kERnMRBsBUcIp5FJSBI5oQsJVkkUHh8W0o5nhaFHvjBgef/Mq+Q46RJBMkI/vE+aOus956tnEswIZe1LV0QyJ5sE2GzgZfVMtRNIdiDpccEssdlB1mW4bvTwdvWJtRdErM7U+8S/FJykCRJX5qm+KpVce8UMNLRLbulz4iSjTAMh6Iowsd5BeNadp3nUF0VlxAEwZBotXC0Usa4ll3meZdA1iguwvf9vpvDA2wvmKgYGtSud8suDB4TyGr2PF49D/vra9jRZ1BVdknMzgwuCGSnZEObwu6sBnVTCHZiaC7BhFx2PKdxUidiAH/4lLo9Mv0DELVs9qsOHXwAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -/* 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\ -/* 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(css) { - var variables = { - site: g.SITE.selectors - }; - return css.replace(/\$[\w\$]+/g, function(name) { - var words = name.slice(1).split('$'); - var sel = variables; - for (var i = 0; i < words.length; i++) { - if (typeof sel !== 'object') return ':not(*)'; - sel = $.getOwn(sel, words[i]); - } - if (typeof sel !== 'string') return ':not(*)'; - return sel; - }); -} - -}; - -$ = (function() { - var $, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - $ = function(selector, root) { - if (root == null) { - root = d.body; - } - return root.querySelector(selector); - }; - - $.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000))); - - $.id = function(id) { - return d.getElementById(id); - }; - - $.ready = function(fc) { - var cb; - if (d.readyState !== 'loading') { - $.queueTask(fc); - return; - } - cb = function() { - $.off(d, 'DOMContentLoaded', cb); - return fc(); - }; - return $.on(d, 'DOMContentLoaded', cb); - }; - - $.formData = function(form) { - var fd, key, val; - if (form instanceof HTMLFormElement) { - return new FormData(form); - } - fd = new FormData(); - for (key in form) { - val = form[key]; - if (val) { - if (typeof val === 'object' && 'newName' in val) { - fd.append(key, val, val.newName); - } else { - fd.append(key, val); - } - } - } - return fd; - }; - - $.extend = function(object, properties) { - var key, val; - for (key in properties) { - val = properties[key]; - object[key] = val; - } - }; - - $.dict = function() { - return Object.create(null); - }; - - $.dict.clone = function(obj) { - var arr, i, j, key, map, ref, val; - if (typeof obj !== 'object' || obj === null) { - return obj; - } else if (obj instanceof Array) { - arr = []; - for (i = j = 0, ref = obj.length; j < ref; i = j += 1) { - arr.push($.dict.clone(obj[i])); - } - return arr; - } else { - map = Object.create(null); - for (key in obj) { - val = obj[key]; - map[key] = $.dict.clone(val); - } - return map; - } - }; - - $.dict.json = function(str) { - return $.dict.clone(JSON.parse(str)); - }; - - $.hasOwn = function(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); - }; - - $.getOwn = function(obj, key) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - return obj[key]; - } else { - return void 0; - } - }; - - $.ajax = (function() { - var pageXHR; - if (window.wrappedJSObject && !XMLHttpRequest.wrappedJSObject) { - pageXHR = XPCNativeWrapper(window.wrappedJSObject.XMLHttpRequest); - } else { - pageXHR = XMLHttpRequest; - } - return function(url, options) { - var err, form, headers, key, onloadend, onprogress, r, ref, responseType, timeout, type, value, withCredentials; - if (options == null) { - options = {}; - } - if (options.responseType == null) { - options.responseType = 'json'; - } - options.type || (options.type = options.form && 'post' || 'get'); - url = url.replace(/^((?:https?:)?\/\/(?:\w+\.)?(?:4chan|4channel|4cdn)\.org)\/adv\//, '$1//adv/'); - onloadend = options.onloadend, timeout = options.timeout, responseType = options.responseType, withCredentials = options.withCredentials, type = options.type, onprogress = options.onprogress, form = options.form, headers = options.headers; - r = new pageXHR(); - try { - r.open(type, url, true); - ref = headers || {}; - for (key in ref) { - value = ref[key]; - r.setRequestHeader(key, value); - } - $.extend(r, { - onloadend: onloadend, - timeout: timeout, - responseType: responseType, - withCredentials: withCredentials - }); - $.extend(r.upload, { - onprogress: onprogress - }); - $.on(r, 'error', function() { - if (!r.status) { - return c.warn("4chan X failed to load: " + url); - } - }); - r.send(form); - } catch (error) { - err = error; - if (err.result !== 0x805e0006) { - throw err; - } - r.onloadend = onloadend; - $.queueTask($.event, 'error', null, r); - $.queueTask($.event, 'loadend', null, r); - } - return r; - }; - })(); - - $.lastModified = $.dict(); - - $.whenModified = function(url, bucket, cb, options) { - var ajax, headers, params, r, ref, t, timeout, url0; - if (options == null) { - options = {}; - } - timeout = options.timeout, ajax = options.ajax; - params = []; - if ($.engine === 'blink') { - params.push("s=" + bucket); - } - if (url.split('/')[2] === 'a.4cdn.org') { - params.push("t=" + (Date.now())); - } - url0 = url; - if (params.length) { - url += '?' + params.join('&'); - } - headers = $.dict(); - if ((t = (ref = $.lastModified[bucket]) != null ? ref[url0] : void 0) != null) { - headers['If-Modified-Since'] = t; - } - r = (ajax || $.ajax)(url, { - onloadend: function() { - var base; - ((base = $.lastModified)[bucket] || (base[bucket] = $.dict()))[url0] = this.getResponseHeader('Last-Modified'); - return cb.call(this); - }, - timeout: timeout, - headers: headers - }); - return r; - }; - - (function() { - var reqs; - reqs = $.dict(); - $.cache = function(url, cb, options) { - var ajax, onloadend, req; - if (options == null) { - options = {}; - } - ajax = options.ajax; - if ((req = reqs[url])) { - if (req.callbacks) { - req.callbacks.push(cb); - } else { - $.queueTask(function() { - return cb.call(req, { - isCached: true - }); - }); - } - return req; - } - onloadend = function() { - var fn1, j, len, ref; - if (!this.status) { - delete reqs[url]; - } - ref = this.callbacks; - fn1 = (function(_this) { - return function(cb) { - return $.queueTask(function() { - return cb.call(_this, { - isCached: false - }); - }); - }; - })(this); - for (j = 0, len = ref.length; j < len; j++) { - cb = ref[j]; - fn1(cb); - } - return delete this.callbacks; - }; - req = (ajax || $.ajax)(url, { - onloadend: onloadend - }); - req.callbacks = [cb]; - return reqs[url] = req; - }; - return $.cleanCache = function(testf) { - var url; - for (url in reqs) { - if (testf(url)) { - delete reqs[url]; - } - } - }; - })(); - - $.cb = { - checked: function() { - if ($.hasOwn(Conf, this.name)) { - $.set(this.name, this.checked); - return Conf[this.name] = this.checked; - } - }, - value: function() { - if ($.hasOwn(Conf, this.name)) { - $.set(this.name, this.value.trim()); - return Conf[this.name] = this.value; - } - } - }; - - $.asap = function(test, cb) { - if (test()) { - return cb(); - } else { - return setTimeout($.asap, 25, test, cb); - } - }; - - $.onExists = function(root, selector, cb) { - var el, observer; - if (el = $(selector, root)) { - return cb(el); - } - observer = new MutationObserver(function() { - if (el = $(selector, root)) { - observer.disconnect(); - return cb(el); - } - }); - return observer.observe(root, { - childList: true, - subtree: true - }); - }; - - $.addStyle = function(css, id, test) { - var style; - if (test == null) { - test = 'head'; - } - style = $.el('style', { - textContent: css - }); - if (id != null) { - style.id = id; - } - $.onExists(doc, test, function() { - return $.add(d.head, style); - }); - return style; - }; - - $.addCSP = function(policy) { - var head, meta; - meta = $.el('meta', { - httpEquiv: 'Content-Security-Policy', - content: policy - }); - if (d.head) { - $.add(d.head, meta); - return $.rm(meta); - } else { - head = $.add(doc || d, $.el('head')); - $.add(head, meta); - return $.rm(head); - } - }; - - $.x = function(path, root) { - root || (root = d.body); - return d.evaluate(path, root, null, 8, null).singleNodeValue; - }; - - $.X = function(path, root) { - root || (root = d.body); - return d.evaluate(path, root, null, 7, null); - }; - - $.addClass = function() { - var className, classNames, el, j, len; - el = arguments[0], classNames = 2 <= arguments.length ? slice.call(arguments, 1) : []; - for (j = 0, len = classNames.length; j < len; j++) { - className = classNames[j]; - el.classList.add(className); - } - }; - - $.rmClass = function() { - var className, classNames, el, j, len; - el = arguments[0], classNames = 2 <= arguments.length ? slice.call(arguments, 1) : []; - for (j = 0, len = classNames.length; j < len; j++) { - className = classNames[j]; - el.classList.remove(className); - } - }; - - $.toggleClass = function(el, className) { - return el.classList.toggle(className); - }; - - $.hasClass = function(el, className) { - return indexOf.call(el.classList, className) >= 0; - }; - - $.rm = function(el) { - return el != null ? el.remove() : void 0; - }; - - $.rmAll = function(root) { - return root.textContent = null; - }; - - $.tn = function(s) { - return d.createTextNode(s); - }; - - $.frag = function() { - return d.createDocumentFragment(); - }; - - $.nodes = function(nodes) { - var frag, j, len, node; - if (!(nodes instanceof Array)) { - return nodes; - } - frag = $.frag(); - for (j = 0, len = nodes.length; j < len; j++) { - node = nodes[j]; - frag.appendChild(node); - } - return frag; - }; - - $.add = function(parent, el) { - return parent.appendChild($.nodes(el)); - }; - - $.prepend = function(parent, el) { - return parent.insertBefore($.nodes(el), parent.firstChild); - }; - - $.after = function(root, el) { - return root.parentNode.insertBefore($.nodes(el), root.nextSibling); - }; - - $.before = function(root, el) { - return root.parentNode.insertBefore($.nodes(el), root); - }; - - $.replace = function(root, el) { - return root.parentNode.replaceChild($.nodes(el), root); - }; - - $.el = function(tag, properties, properties2) { - var el; - el = d.createElement(tag); - if (properties) { - $.extend(el, properties); - } - if (properties2) { - $.extend(el, properties2); - } - return el; - }; - - $.on = function(el, events, handler) { - var event, j, len, ref; - ref = events.split(' '); - for (j = 0, len = ref.length; j < len; j++) { - event = ref[j]; - el.addEventListener(event, handler, false); - } - }; - - $.off = function(el, events, handler) { - var event, j, len, ref; - ref = events.split(' '); - for (j = 0, len = ref.length; j < len; j++) { - event = ref[j]; - el.removeEventListener(event, handler, false); - } - }; - - $.one = function(el, events, handler) { - var cb; - cb = function(e) { - $.off(el, events, cb); - return handler.call(this, e); - }; - return $.on(el, events, cb); - }; - - $.event = function(event, detail, root) { - if (root == null) { - root = d; - } - if ((detail != null) && typeof cloneInto === 'function') { - detail = cloneInto(detail, d.defaultView); - } - return root.dispatchEvent(new CustomEvent(event, { - bubbles: true, - cancelable: true, - detail: detail - })); - }; - - (function() { - var clone, err, ref, unsafeConstructors; - if (!(/PaleMoon\//.test(navigator.userAgent) && +(typeof GM_info !== "undefined" && GM_info !== null ? (ref = GM_info.version) != null ? ref.split('.')[0] : void 0 : void 0) >= 2 && typeof cloneInto === 'undefined')) { - return; - } - try { - return new CustomEvent('x', { - detail: {} - }); - } catch (error) { - err = error; - unsafeConstructors = { - Object: unsafeWindow.Object, - Array: unsafeWindow.Array - }; - clone = function(obj) { - var constructor, key, obj2, val; - if ((obj != null) && typeof obj === 'object' && (constructor = unsafeConstructors[obj.constructor.name])) { - obj2 = new constructor(); - for (key in obj) { - val = obj[key]; - obj2[key] = clone(val); - } - return obj2; - } else { - return obj; - } - }; - return $.event = function(event, detail, root) { - if (root == null) { - root = d; - } - return root.dispatchEvent(new CustomEvent(event, { - bubbles: true, - cancelable: true, - detail: clone(detail) - })); - }; - } - })(); - - $.modifiedClick = function(e) { - return e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0; - }; - - $.open = (typeof GM !== "undefined" && GM !== null ? GM.openInTab : void 0) != null ? GM.openInTab : typeof GM_openInTab !== "undefined" && GM_openInTab !== null ? GM_openInTab : function(url) { - return window.open(url, '_blank'); - }; - - $.debounce = function(wait, fn) { - var args, exec, lastCall, that, timeout; - lastCall = 0; - timeout = null; - that = null; - args = null; - exec = function() { - lastCall = Date.now(); - return fn.apply(that, args); - }; - return function() { - args = arguments; - that = this; - if (lastCall < Date.now() - wait) { - return exec(); - } - clearTimeout(timeout); - return timeout = setTimeout(exec, wait); - }; - }; - - $.queueTask = (function() { - var execTask, taskChannel, taskQueue; - taskQueue = []; - execTask = function() { - var args, func, task; - task = taskQueue.shift(); - func = task[0]; - args = Array.prototype.slice.call(task, 1); - return func.apply(func, args); - }; - if (window.MessageChannel) { - taskChannel = new MessageChannel(); - taskChannel.port1.onmessage = execTask; - return function() { - taskQueue.push(arguments); - return taskChannel.port2.postMessage(null); - }; - } else { - return function() { - taskQueue.push(arguments); - return setTimeout(execTask, 0); - }; - } - })(); - - $.global = function(fn, data) { - var script; - if (doc) { - script = $.el('script', { - textContent: "(" + fn + ").call(document.currentScript.dataset);" - }); - if (data) { - $.extend(script.dataset, data); - } - $.add(d.head || doc, script); - $.rm(script); - return script.dataset; - } else { - try { - fn.call(data); - } catch (error) {} - return data; - } - }; - - $.bytesToString = function(size) { - var unit; - unit = 0; - while (size >= 1024) { - size /= 1024; - unit++; - } - size = unit > 1 ? Math.round(size * 100) / 100 : Math.round(size); - return size + " " + ['B', 'KB', 'MB', 'GB'][unit]; - }; - - $.minmax = function(value, min, max) { - return (value < min ? min : value > max ? max : value); - }; - - $.hasAudio = function(video) { - return video.mozHasAudio || !!video.webkitAudioDecodedByteCount; - }; - - $.luma = function(rgb) { - return rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114; - }; - - $.unescape = function(text) { - if (text == null) { - return text; - } - return text.replace(/<[^>]*>/g, '').replace(/&(amp|#039|quot|lt|gt|#44);/g, function(c) { - return { - '&': '&', - ''': "'", - '"': '"', - '<': '<', - '>': '>', - ',': ',' - }[c]; - }); - }; - - $.isImage = function(url) { - return /\.(jpe?g|jfif|png|gif|bmp|webp|avif|jxl)$/i.test(url); - }; - - $.isVideo = function(url) { - return /\.(webm|mp4|ogv)$/i.test(url); - }; - - $.engine = (function() { - if (/Edge\//.test(navigator.userAgent)) { - return 'edge'; - } - if (/Chrome\//.test(navigator.userAgent)) { - return 'blink'; - } - if (/WebKit\//.test(navigator.userAgent)) { - return 'webkit'; - } - if (/Gecko\/|Goanna/.test(navigator.userAgent)) { - return 'gecko'; - } - })(); - - $.platform = 'userscript'; - - $.hasStorage = (function() { - try { - if (localStorage.getItem(g.NAMESPACE + 'hasStorage') === 'true') { - return true; - } - localStorage.setItem(g.NAMESPACE + 'hasStorage', 'true'); - return localStorage.getItem(g.NAMESPACE + 'hasStorage') === 'true'; - } catch (error) { - return false; - } - })(); - - $.item = function(key, val) { - var item; - item = $.dict(); - item[key] = val; - return item; - }; - - $.oneItemSugar = function(fn) { - return function(key, val, cb) { - if (typeof key === 'string') { - return fn($.item(key, val), cb); - } else { - return fn(key, val); - } - }; - }; - - $.syncing = $.dict(); - - $.securityCheck = function(data) { - if (location.protocol !== 'https:') { - return delete data['Redirect to HTTPS']; - } - }; - - if (((typeof GM !== "undefined" && GM !== null ? GM.deleteValue : void 0) != null) && window.BroadcastChannel && (typeof GM_addValueChangeListener === "undefined" || GM_addValueChangeListener === null)) { - $.syncChannel = new BroadcastChannel(g.NAMESPACE + 'sync'); - $.on($.syncChannel, 'message', function(e) { - var cb, key, ref, results, val; - ref = e.data; - results = []; - for (key in ref) { - val = ref[key]; - if ((cb = $.syncing[key])) { - results.push(cb($.dict.json(JSON.stringify(val)), key)); - } - } - return results; - }); - $.sync = function(key, cb) { - return $.syncing[key] = cb; - }; - $.forceSync = function() {}; - $["delete"] = function(keys, cb) { - var key; - if (!(keys instanceof Array)) { - keys = [keys]; - } - return Promise.all((function() { - var j, len, results; - results = []; - for (j = 0, len = keys.length; j < len; j++) { - key = keys[j]; - results.push(GM.deleteValue(g.NAMESPACE + key)); - } - return results; - })()).then(function() { - var items, j, key, len; - items = $.dict(); - for (j = 0, len = keys.length; j < len; j++) { - key = keys[j]; - items[key] = void 0; - } - $.syncChannel.postMessage(items); - return typeof cb === "function" ? cb() : void 0; - }); - }; - $.get = $.oneItemSugar(function(items, cb) { - var key, keys; - keys = Object.keys(items); - return Promise.all((function() { - var j, len, results; - results = []; - for (j = 0, len = keys.length; j < len; j++) { - key = keys[j]; - results.push(GM.getValue(g.NAMESPACE + key)); - } - return results; - })()).then(function(values) { - var i, j, len, val; - for (i = j = 0, len = values.length; j < len; i = ++j) { - val = values[i]; - if (val) { - items[keys[i]] = $.dict.json(val); - } - } - return cb(items); - }); - }); - $.set = $.oneItemSugar(function(items, cb) { - var key, val; - $.securityCheck(items); - return Promise.all((function() { - var results; - results = []; - for (key in items) { - val = items[key]; - results.push(GM.setValue(g.NAMESPACE + key, JSON.stringify(val))); - } - return results; - })()).then(function() { - $.syncChannel.postMessage(items); - return typeof cb === "function" ? cb() : void 0; - }); - }); - $.clear = function(cb) { - return GM.listValues().then(function(keys) { - return $["delete"](keys.map(function(key) { - return key.replace(g.NAMESPACE, ''); - }), cb); - })["catch"](function() { - return $["delete"](Object.keys(Conf).concat(['previousversion', 'QR Size', 'QR.persona']), cb); - }); - }; - } else { - if (typeof GM_deleteValue === "undefined" || GM_deleteValue === null) { - $.perProtocolSettings = true; - } - if (typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) { - $.getValue = GM_getValue; - $.listValues = function() { - return GM_listValues(); - }; - } else if ($.hasStorage) { - $.getValue = function(key) { - return localStorage.getItem(key); - }; - $.listValues = function() { - var key, results; - results = []; - for (key in localStorage) { - if (key.slice(0, g.NAMESPACE.length) === g.NAMESPACE) { - results.push(key); - } - } - return results; - }; - } else { - $.getValue = function() {}; - $.listValues = function() { - return []; - }; - } - if (typeof GM_addValueChangeListener !== "undefined" && GM_addValueChangeListener !== null) { - $.setValue = GM_setValue; - $.deleteValue = GM_deleteValue; - } else if (typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) { - $.oldValue = $.dict(); - $.setValue = function(key, val) { - GM_setValue(key, val); - if (key in $.syncing) { - $.oldValue[key] = val; - if ($.hasStorage) { - return localStorage.setItem(key, val); - } - } - }; - $.deleteValue = function(key) { - GM_deleteValue(key); - if (key in $.syncing) { - delete $.oldValue[key]; - if ($.hasStorage) { - return localStorage.removeItem(key); - } - } - }; - if (!$.hasStorage) { - $.cantSync = true; - } - } else if ($.hasStorage) { - $.oldValue = $.dict(); - $.setValue = function(key, val) { - if (key in $.syncing) { - $.oldValue[key] = val; - } - return localStorage.setItem(key, val); - }; - $.deleteValue = function(key) { - if (key in $.syncing) { - delete $.oldValue[key]; - } - return localStorage.removeItem(key); - }; - } else { - $.setValue = function() {}; - $.deleteValue = function() {}; - $.cantSync = $.cantSet = true; - } - if (typeof GM_addValueChangeListener !== "undefined" && GM_addValueChangeListener !== null) { - $.sync = function(key, cb) { - return $.syncing[key] = GM_addValueChangeListener(g.NAMESPACE + key, function(key2, oldValue, newValue, remote) { - if (remote) { - if (newValue !== void 0) { - newValue = $.dict.json(newValue); - } - return cb(newValue, key); - } - }); - }; - $.forceSync = function() {}; - } else if ((typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) || $.hasStorage) { - $.sync = function(key, cb) { - key = g.NAMESPACE + key; - $.syncing[key] = cb; - return $.oldValue[key] = $.getValue(key); - }; - (function() { - var onChange; - onChange = function(arg) { - var cb, key, newValue; - key = arg.key, newValue = arg.newValue; - if (!(cb = $.syncing[key])) { - return; - } - if (newValue != null) { - if (newValue === $.oldValue[key]) { - return; - } - $.oldValue[key] = newValue; - return cb($.dict.json(newValue), key.slice(g.NAMESPACE.length)); - } else { - if ($.oldValue[key] == null) { - return; - } - delete $.oldValue[key]; - return cb(void 0, key.slice(g.NAMESPACE.length)); - } - }; - $.on(window, 'storage', onChange); - return $.forceSync = function(key) { - key = g.NAMESPACE + key; - return onChange({ - key: key, - newValue: $.getValue(key) - }); - }; - })(); - } else { - $.sync = function() {}; - $.forceSync = function() {}; - } - $["delete"] = function(keys) { - var j, key, len; - if (!(keys instanceof Array)) { - keys = [keys]; - } - for (j = 0, len = keys.length; j < len; j++) { - key = keys[j]; - $.deleteValue(g.NAMESPACE + key); - } - }; - $.get = $.oneItemSugar(function(items, cb) { - return $.queueTask($.getSync, items, cb); - }); - $.getSync = function(items, cb) { - var err, key, val2; - for (key in items) { - if ((val2 = $.getValue(g.NAMESPACE + key))) { - try { - items[key] = $.dict.json(val2); - } catch (error) { - err = error; - if (!/^(?:undefined)*$/.test(val2)) { - throw err; - } - } - } - } - return cb(items); - }; - $.set = $.oneItemSugar(function(items, cb) { - $.securityCheck(items); - return $.queueTask(function() { - var key, value; - for (key in items) { - value = items[key]; - $.setValue(g.NAMESPACE + key, JSON.stringify(value)); - } - return typeof cb === "function" ? cb() : void 0; - }); - }); - $.clear = function(cb) { - $["delete"](Object.keys(Conf)); - $["delete"](['previousversion', 'QR Size', 'QR.persona']); - try { - $["delete"]($.listValues().map(function(key) { - return key.replace(g.NAMESPACE, ''); - })); - } catch (error) {} - return typeof cb === "function" ? cb() : void 0; - }; - } - - return $; - -}).call(this); - -$$ = (function() { - var $$, - slice = [].slice; - - $$ = function(selector, root) { - if (root == null) { - root = d.body; - } - return slice.call(root.querySelectorAll(selector)); - }; - - return $$; - -}).call(this); - -CrossOrigin = (function() { - var CrossOrigin, Request; - - CrossOrigin = { - binary: function(url, cb, headers) { - var fallback, gmOptions; - if (headers == null) { - headers = $.dict(); - } - url = url.replace(/^((?:https?:)?\/\/(?:\w+\.)?(?:4chan|4channel|4cdn)\.org)\/adv\//, '$1//adv/'); - fallback = function() { - return $.ajax(url, { - headers: headers, - responseType: 'arraybuffer', - onloadend: function() { - if (this.status && this.response) { - return cb(new Uint8Array(this.response), this.getAllResponseHeaders()); - } else { - return cb(null); - } - } - }); - }; - if (!(((typeof GM !== "undefined" && GM !== null ? GM.xmlHttpRequest : void 0) != null) || (typeof GM_xmlhttpRequest !== "undefined" && GM_xmlhttpRequest !== null))) { - fallback(); - return; - } - gmOptions = { - method: "GET", - url: url, - headers: headers, - responseType: 'arraybuffer', - overrideMimeType: 'text/plain; charset=x-user-defined', - onload: function(xhr) { - var data, i, r; - if (xhr.response instanceof ArrayBuffer) { - data = new Uint8Array(xhr.response); - } else { - r = xhr.responseText; - data = new Uint8Array(r.length); - i = 0; - while (i < r.length) { - data[i] = r.charCodeAt(i); - i++; - } - } - return cb(data, xhr.responseHeaders); - }, - onerror: function() { - return cb(null); - }, - onabort: function() { - return cb(null); - } - }; - try { - return ((typeof GM !== "undefined" && GM !== null ? GM.xmlHttpRequest : void 0) || GM_xmlhttpRequest)(gmOptions); - } catch (error) { - return fallback(); - } - }, - file: function(url, cb) { - return CrossOrigin.binary(url, function(data, headers) { - var blob, contentDisposition, contentType, match, mime, name, ref, ref1, ref2, ref3, ref4; - if (data == null) { - return cb(null); - } - name = (ref = url.match(/([^\/?#]+)\/*(?:$|[?#])/)) != null ? ref[1] : void 0; - contentType = (ref1 = headers.match(/Content-Type:\s*(.*)/i)) != null ? ref1[1] : void 0; - contentDisposition = (ref2 = headers.match(/Content-Disposition:\s*(.*)/i)) != null ? ref2[1] : void 0; - mime = (contentType != null ? contentType.match(/[^;]*/)[0] : void 0) || 'application/octet-stream'; - match = (contentDisposition != null ? (ref3 = contentDisposition.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)) != null ? ref3[1] : void 0 : void 0) || (contentType != null ? (ref4 = contentType.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)) != null ? ref4[1] : void 0 : void 0); - if (match) { - name = match.replace(/\\"/g, '"'); - } - if (/^text\/plain;\s*charset=x-user-defined$/i.test(mime)) { - mime = $.getOwn(QR.typeFromExtension, name.match(/[^.]*$/)[0].toLowerCase()) || 'application/octet-stream'; - } - blob = new Blob([data], { - type: mime - }); - blob.name = name; - return cb(blob); - }); - }, - Request: Request = (function() { - function Request() {} - - Request.prototype.status = 0; - - Request.prototype.statusText = ''; - - Request.prototype.response = null; - - Request.prototype.responseHeaderString = null; - - Request.prototype.getResponseHeader = function(headerName) { - var header, i, j, key, len, ref, ref1, ref2, val; - if ((this.responseHeaders == null) && (this.responseHeaderString != null)) { - this.responseHeaders = $.dict(); - ref = this.responseHeaderString.split('\r\n'); - for (j = 0, len = ref.length; j < len; j++) { - header = ref[j]; - if ((i = header.indexOf(':')) >= 0) { - key = header.slice(0, i).trim().toLowerCase(); - val = header.slice(i + 1).trim(); - this.responseHeaders[key] = val; - } - } - } - return (ref1 = (ref2 = this.responseHeaders) != null ? ref2[headerName.toLowerCase()] : void 0) != null ? ref1 : null; - }; - - Request.prototype.abort = function() {}; - - Request.prototype.onloadend = function() {}; - - return Request; - - })(), - ajax: function(url, options) { - var gmOptions, gmReq, headers, onloadend, req, responseType, timeout; - if (options == null) { - options = {}; - } - onloadend = options.onloadend, timeout = options.timeout, responseType = options.responseType, headers = options.headers; - if (responseType == null) { - responseType = 'json'; - } - if (!(((typeof GM !== "undefined" && GM !== null ? GM.xmlHttpRequest : void 0) != null) || (typeof GM_xmlhttpRequest !== "undefined" && GM_xmlhttpRequest !== null))) { - return $.ajax(url, options); - } - req = new CrossOrigin.Request(); - req.onloadend = onloadend; - gmOptions = { - method: 'GET', - url: url, - headers: headers, - timeout: timeout, - onload: function(xhr) { - var response; - try { - response = (function() { - switch (responseType) { - case 'json': - if (xhr.responseText) { - return JSON.parse(xhr.responseText); - } else { - return null; - } - break; - default: - return xhr.responseText; - } - })(); - $.extend(req, { - response: response, - status: xhr.status, - statusText: xhr.statusText, - responseHeaderString: xhr.responseHeaders - }); - } catch (error) {} - return req.onloadend(); - }, - onerror: function() { - return req.onloadend(); - }, - onabort: function() { - return req.onloadend(); - }, - ontimeout: function() { - return req.onloadend(); - } - }; - try { - gmReq = ((typeof GM !== "undefined" && GM !== null ? GM.xmlHttpRequest : void 0) || GM_xmlhttpRequest)(gmOptions); - } catch (error) { - return $.ajax(url, options); - } - if (gmReq && typeof gmReq.abort === 'function') { - req.abort = function() { - try { - return gmReq.abort(); - } catch (error) {} - }; - } - return req; - }, - cache: function(url, cb) { - return $.cache(url, cb, { - ajax: CrossOrigin.ajax - }); - }, - permission: function(cb) { - return cb(); - } - }; - - return CrossOrigin; - -}).call(this); - -Board = (function() { - var Board; - - Board = (function() { - Board.prototype.toString = function() { - return this.ID; - }; - - function Board(ID) { - var ref; - this.ID = ID; - this.boardID = this.ID; - this.siteID = g.SITE.ID; - this.threads = new SimpleDict(); - this.posts = new SimpleDict(); - this.config = ((ref = BoardConfig.boards) != null ? ref[this.ID] : void 0) || {}; - g.boards[this] = this; - } - - Board.prototype.cooldowns = function() { - var c, c2, i, key, len, ref; - c2 = (this.config || {}).cooldowns || {}; - c = { - thread: c2.threads || 0, - reply: c2.replies || 0, - image: c2.images || 0, - thread_global: 300 - }; - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - ref = ['reply', 'image']; - for (i = 0, len = ref.length; i < len; i++) { - key = ref[i]; - c[key] = Math.ceil(c[key] / 2); - } - } - return c; - }; - - return Board; - - })(); - - return Board; - -}).call(this); - -Callbacks = (function() { - var Callbacks; - - Callbacks = (function() { - Callbacks.Post = new Callbacks('Post'); - - Callbacks.Thread = new Callbacks('Thread'); - - Callbacks.CatalogThread = new Callbacks('Catalog Thread'); - - Callbacks.CatalogThreadNative = new Callbacks('Catalog Thread'); - - function Callbacks(type) { - this.type = type; - this.keys = []; - } - - Callbacks.prototype.push = function(arg) { - var cb, name; - name = arg.name, cb = arg.cb; - if (!this[name]) { - this.keys.push(name); - } - return this[name] = cb; - }; - - Callbacks.prototype.execute = function(node, keys, force) { - var err, errors, i, len, name, ref, ref1, ref2; - if (keys == null) { - keys = this.keys; - } - if (force == null) { - force = false; - } - if (node.callbacksExecuted && !force) { - return; - } - node.callbacksExecuted = true; - for (i = 0, len = keys.length; i < len; i++) { - name = keys[i]; - try { - if ((ref = this[name]) != null) { - ref.call(node); - } - } catch (error) { - err = error; - if (!errors) { - errors = []; - } - errors.push({ - message: ['"', name, '" crashed on node ', this.type, ' No.', node.ID, ' (', node.board, ').'].join(''), - error: err, - html: (ref1 = node.nodes) != null ? (ref2 = ref1.root) != null ? ref2.outerHTML : void 0 : void 0 - }); - } - } - if (errors) { - return Main.handleErrors(errors); - } - }; - - return Callbacks; - - })(); - - return Callbacks; - -}).call(this); - -CatalogThread = (function() { - var CatalogThread; - - CatalogThread = (function() { - CatalogThread.prototype.toString = function() { - return this.ID; - }; - - function CatalogThread(root, thread) { - var post; - this.thread = thread; - this.ID = this.thread.ID; - this.board = this.thread.board; - post = this.thread.OP.nodes.post; - this.nodes = { - root: root, - thumb: $('.catalog-thumb', post), - icons: $('.catalog-icons', post), - postCount: $('.post-count', post), - fileCount: $('.file-count', post), - pageCount: $('.page-count', post), - replies: null - }; - this.thread.catalogView = this; - } - - return CatalogThread; - - })(); - - return CatalogThread; - -}).call(this); - -CatalogThreadNative = (function() { - var CatalogThreadNative; - - CatalogThreadNative = (function() { - CatalogThreadNative.prototype.toString = function() { - return this.ID; - }; - - function CatalogThreadNative(root) { - this.nodes = { - root: root, - thumb: $(g.SITE.selectors.catalog.thumb, root) - }; - this.siteID = g.SITE.ID; - this.boardID = this.nodes.thumb.parentNode.pathname.split(/\/+/)[1]; - this.board = g.boards[this.boardID] || new Board(this.boardID); - this.ID = this.threadID = +(root.dataset.id || root.id).match(/\d*$/)[0]; - this.thread = this.board.threads.get(this.ID) || new Thread(this.ID, this.board); - } - - return CatalogThreadNative; - - })(); - - return CatalogThreadNative; - -}).call(this); - -Connection = (function() { - var Connection, - bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - - Connection = (function() { - function Connection(target, origin, cb) { - this.target = target; - this.origin = origin; - this.cb = cb != null ? cb : {}; - this.onMessage = bind(this.onMessage, this); - this.send = bind(this.send, this); - $.on(window, 'message', this.onMessage); - } - - Connection.prototype.targetWindow = function() { - if (this.target instanceof window.HTMLIFrameElement) { - return this.target.contentWindow; - } else { - return this.target; - } - }; - - Connection.prototype.send = function(data) { - return this.targetWindow().postMessage("" + g.NAMESPACE + (JSON.stringify(data)), this.origin); - }; - - Connection.prototype.onMessage = function(e) { - var data, type, value; - if (!(e.source === this.targetWindow() && e.origin === this.origin && typeof e.data === 'string' && e.data.slice(0, g.NAMESPACE.length) === g.NAMESPACE)) { - return; - } - data = JSON.parse(e.data.slice(g.NAMESPACE.length)); - for (type in data) { - value = data[type]; - if ($.hasOwn(this.cb, type)) { - this.cb[type](value); - } - } - }; - - return Connection; - - })(); - - return Connection; - -}).call(this); - -DataBoard = (function() { - var DataBoard, - bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - - DataBoard = (function() { - DataBoard.keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads', 'watcherLastModified', 'customTitles']; - - function DataBoard(key1, sync, dontClean) { - var init; - this.key = key1; - this.onSync = bind(this.onSync, this); - this.initData(Conf[this.key]); - $.sync(this.key, this.onSync); - if (!dontClean) { - this.clean(); - } - if (!sync) { - return; - } - init = (function(_this) { - return function() { - $.off(d, '4chanXInitFinished', init); - return _this.sync = sync; - }; - })(this); - $.on(d, '4chanXInitFinished', init); - } - - DataBoard.prototype.initData = function(data1) { - var base, boards, lastChecked, name, ref; - this.data = data1; - if (this.data.boards) { - ref = this.data, boards = ref.boards, lastChecked = ref.lastChecked; - this.data['4chan.org'] = { - boards: boards, - lastChecked: lastChecked - }; - delete this.data.boards; - delete this.data.lastChecked; - } - return (base = this.data)[name = g.SITE.ID] || (base[name] = { - boards: $.dict() - }); - }; - - DataBoard.prototype.changes = []; - - DataBoard.prototype.save = function(change, cb) { - change(); - this.changes.push(change); - return $.get(this.key, { - boards: $.dict() - }, (function(_this) { - return function(items) { - var i, len, needSync, ref; - if (!_this.changes.length) { - return; - } - needSync = (items[_this.key].version || 0) > (_this.data.version || 0); - if (needSync) { - _this.initData(items[_this.key]); - ref = _this.changes; - for (i = 0, len = ref.length; i < len; i++) { - change = ref[i]; - change(); - } - } - _this.changes = []; - _this.data.version = (_this.data.version || 0) + 1; - return $.set(_this.key, _this.data, function() { - if (needSync) { - if (typeof _this.sync === "function") { - _this.sync(); - } - } - return typeof cb === "function" ? cb() : void 0; - }); - }; - })(this)); - }; - - DataBoard.prototype.forceSync = function(cb) { - return $.get(this.key, { - boards: $.dict() - }, (function(_this) { - return function(items) { - var change, i, len, ref; - if ((items[_this.key].version || 0) > (_this.data.version || 0)) { - _this.initData(items[_this.key]); - ref = _this.changes; - for (i = 0, len = ref.length; i < len; i++) { - change = ref[i]; - change(); - } - if (typeof _this.sync === "function") { - _this.sync(); - } - } - return typeof cb === "function" ? cb() : void 0; - }; - })(this)); - }; - - DataBoard.prototype["delete"] = function(arg, cb) { - var boardID, postID, siteID, threadID; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID; - siteID || (siteID = g.SITE.ID); - if (!this.data[siteID]) { - return; - } - return this.save((function(_this) { - return function() { - var ref; - if (postID) { - if (!((ref = _this.data[siteID].boards[boardID]) != null ? ref[threadID] : void 0)) { - return; - } - delete _this.data[siteID].boards[boardID][threadID][postID]; - return _this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }); - } else if (threadID) { - if (!_this.data[siteID].boards[boardID]) { - return; - } - delete _this.data[siteID].boards[boardID][threadID]; - return _this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID - }); - } else { - return delete _this.data[siteID].boards[boardID]; - } - }; - })(this), cb); - }; - - DataBoard.prototype.deleteIfEmpty = function(arg) { - var boardID, siteID, threadID; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID; - if (!this.data[siteID]) { - return; - } - if (threadID) { - if (!Object.keys(this.data[siteID].boards[boardID][threadID]).length) { - delete this.data[siteID].boards[boardID][threadID]; - return this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID - }); - } - } else if (!Object.keys(this.data[siteID].boards[boardID]).length) { - return delete this.data[siteID].boards[boardID]; - } - }; - - DataBoard.prototype.set = function(data, cb) { - return this.save((function(_this) { - return function() { - return _this.setUnsafe(data); - }; - })(this), cb); - }; - - DataBoard.prototype.setUnsafe = function(arg) { - var base, base1, base2, base3, boardID, postID, siteID, threadID, val; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, val = arg.val; - siteID || (siteID = g.SITE.ID); - (base = this.data)[siteID] || (base[siteID] = { - boards: $.dict() - }); - if (postID !== void 0) { - return ((base1 = ((base2 = this.data[siteID].boards)[boardID] || (base2[boardID] = $.dict())))[threadID] || (base1[threadID] = $.dict()))[postID] = val; - } else if (threadID !== void 0) { - return ((base3 = this.data[siteID].boards)[boardID] || (base3[boardID] = $.dict()))[threadID] = val; - } else { - return this.data[siteID].boards[boardID] = val; - } - }; - - DataBoard.prototype.extend = function(arg, cb) { - var boardID, postID, siteID, threadID, val; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, val = arg.val; - return this.save((function(_this) { - return function() { - var key, oldVal, subVal; - oldVal = _this.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - postID: postID, - defaultValue: $.dict() - }); - for (key in val) { - subVal = val[key]; - if (typeof subVal === 'undefined') { - delete oldVal[key]; - } else { - oldVal[key] = subVal; - } - } - return _this.setUnsafe({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - postID: postID, - val: oldVal - }); - }; - })(this), cb); - }; - - DataBoard.prototype.setLastChecked = function(key) { - if (key == null) { - key = 'lastChecked'; - } - return this.save((function(_this) { - return function() { - return _this.data[key] = Date.now(); - }; - })(this)); - }; - - DataBoard.prototype.get = function(arg) { - var ID, board, boardID, defaultValue, i, len, postID, ref, siteID, thread, threadID, val; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, defaultValue = arg.defaultValue; - siteID || (siteID = g.SITE.ID); - if (board = (ref = this.data[siteID]) != null ? ref.boards[boardID] : void 0) { - if (threadID == null) { - if (postID != null) { - for (thread = i = 0, len = board.length; i < len; thread = ++i) { - ID = board[thread]; - if (postID in thread) { - val = thread[postID]; - break; - } - } - } else { - val = board; - } - } else if (thread = board[threadID]) { - val = postID != null ? thread[postID] : thread; - } - } - return val || defaultValue; - }; - - DataBoard.prototype.clean = function() { - var boardID, now, ref, ref1, siteID, val; - siteID = g.SITE.ID; - ref = this.data[siteID].boards; - for (boardID in ref) { - val = ref[boardID]; - this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID - }); - } - now = Date.now(); - if (!((now - 2 * $.HOUR < (ref1 = this.data[siteID].lastChecked || 0) && ref1 <= now))) { - this.data[siteID].lastChecked = now; - for (boardID in this.data[siteID].boards) { - this.ajaxClean(boardID); - } - } - }; - - DataBoard.prototype.ajaxClean = function(boardID) { - var base, siteID, that, threadsList; - that = this; - siteID = g.SITE.ID; - threadsList = typeof (base = g.SITE.urls).threadsListJSON === "function" ? base.threadsListJSON({ - siteID: siteID, - boardID: boardID - }) : void 0; - if (!threadsList) { - return; - } - return $.cache(threadsList, function() { - var archiveList, base1, response1; - if (this.status !== 200) { - return; - } - archiveList = typeof (base1 = g.SITE.urls).archiveListJSON === "function" ? base1.archiveListJSON({ - siteID: siteID, - boardID: boardID - }) : void 0; - if (!archiveList) { - return that.ajaxCleanParse(boardID, this.response); - } - response1 = this.response; - return $.cache(archiveList, function() { - if (!(this.status === 200 || (!g.SITE.archivedBoardsKnown && this.status === 404))) { - return; - } - return that.ajaxCleanParse(boardID, response1, this.response); - }); - }); - }; - - DataBoard.prototype.ajaxCleanParse = function(boardID, response1, response2) { - var ID, board, i, j, k, len, len1, len2, page, ref, siteID, thread, threads; - siteID = g.SITE.ID; - if (!(board = this.data[siteID].boards[boardID])) { - return; - } - threads = $.dict(); - if (response1) { - for (i = 0, len = response1.length; i < len; i++) { - page = response1[i]; - ref = page.threads; - for (j = 0, len1 = ref.length; j < len1; j++) { - thread = ref[j]; - ID = thread.no; - if (ID in board) { - threads[ID] = board[ID]; - } - } - } - } - if (response2) { - for (k = 0, len2 = response2.length; k < len2; k++) { - ID = response2[k]; - if (ID in board) { - threads[ID] = board[ID]; - } - } - } - this.data[siteID].boards[boardID] = threads; - this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID - }); - return $.set(this.key, this.data); - }; - - DataBoard.prototype.onSync = function(data) { - if (!((data.version || 0) > (this.data.version || 0))) { - return; - } - this.initData(data); - return typeof this.sync === "function" ? this.sync() : void 0; - }; - - return DataBoard; - - })(); - - return DataBoard; - -}).call(this); - -Fetcher = (function() { - var Fetcher, - slice = [].slice; - - Fetcher = (function() { - function Fetcher(boardID1, threadID, postID1, root, quoter) { - var board, post, ref, that, thread; - this.boardID = boardID1; - this.threadID = threadID; - this.postID = postID1; - this.root = root; - this.quoter = quoter; - if (post = g.posts.get(this.boardID + "." + this.postID)) { - this.insert(post); - return; - } - if ((post = (ref = Index.replyData) != null ? ref[this.boardID + "." + this.postID] : void 0) && (thread = g.threads.get(this.boardID + "." + this.threadID))) { - board = g.boards[this.boardID]; - post = new Post(g.SITE.Build.postFromObject(post, this.boardID), thread, board, { - isFetchedQuote: true - }); - Main.callbackNodes('Post', [post]); - this.insert(post); - return; - } - this.root.textContent = "Loading post No." + this.postID + "..."; - if (this.threadID) { - that = this; - $.cache(g.SITE.urls.threadJSON({ - boardID: this.boardID, - threadID: this.threadID - }), function(arg) { - var isCached; - isCached = arg.isCached; - return that.fetchedPost(this, isCached); - }); - } else { - this.archivedPost(); - } - } - - Fetcher.prototype.insert = function(post) { - var boardID, clone, cssVersion, k, len, nodes, postID, quote, ref, ref1, ref2; - if (!this.root.parentNode) { - return; - } - this.quoter || (this.quoter = post); - clone = post.addClone(this.quoter.context, $.hasClass(this.root, 'dialog')); - Main.callbackNodes('Post', [clone]); - nodes = clone.nodes; - $.rmAll(nodes.root); - $.add(nodes.root, nodes.post); - ref = clone.nodes.quotelinks.concat(slice.call(clone.nodes.backlinks)); - for (k = 0, len = ref.length; k < len; k++) { - quote = ref[k]; - ref1 = Get.postDataFromLink(quote), boardID = ref1.boardID, postID = ref1.postID; - if (postID === this.quoter.ID && boardID === this.quoter.board.ID) { - $.addClass(quote, 'forwardlink'); - } - } - if (clone.nodes.flag && !(Fetcher.flagCSS || (Fetcher.flagCSS = $('link[href^="//s.4cdn.org/css/flags."]')))) { - cssVersion = ((ref2 = $('link[href^="//s.4cdn.org/css/"]')) != null ? ref2.href.match(/\d+(?=\.css$)|$/)[0] : void 0) || Date.now(); - Fetcher.flagCSS = $.el('link', { - rel: 'stylesheet', - href: "//s.4cdn.org/css/flags." + cssVersion + ".css" - }); - $.add(d.head, Fetcher.flagCSS); - } - $.rmAll(this.root); - $.add(this.root, nodes.root); - return $.event('PostsInserted', null, this.root); - }; - - Fetcher.prototype.fetchedPost = function(req, isCached) { - var api, board, k, len, post, posts, status, that, thread; - if (post = g.posts.get(this.boardID + "." + this.postID)) { - this.insert(post); - return; - } - status = req.status; - if (status !== 200) { - if (status && this.archivedPost()) { - return; - } - $.addClass(this.root, 'warning'); - this.root.textContent = status === 404 ? "Thread No." + this.threadID + " 404'd." : !status ? 'Connection Error' : "Error " + req.statusText + " (" + req.status + ")."; - return; - } - posts = req.response.posts; - g.SITE.Build.spoilerRange[this.boardID] = posts[0].custom_spoiler; - for (k = 0, len = posts.length; k < len; k++) { - post = posts[k]; - if (post.no === this.postID) { - break; - } - } - if (post.no !== this.postID) { - if (isCached) { - api = g.SITE.urls.threadJSON({ - boardID: this.boardID, - threadID: this.threadID - }); - $.cleanCache(function(url) { - return url === api; - }); - that = this; - $.cache(api, function() { - return that.fetchedPost(this, false); - }); - return; - } - if (this.archivedPost()) { - return; - } - $.addClass(this.root, 'warning'); - this.root.textContent = "Post No." + this.postID + " was not found."; - return; - } - board = g.boards[this.boardID] || new Board(this.boardID); - thread = g.threads.get(this.boardID + "." + this.threadID) || new Thread(this.threadID, board); - post = new Post(g.SITE.Build.postFromObject(post, this.boardID), thread, board, { - isFetchedQuote: true - }); - Main.callbackNodes('Post', [post]); - return this.insert(post); - }; - - Fetcher.prototype.archivedPost = function() { - var archive, encryptionOK, that, url; - if (!Conf['Resurrect Quotes']) { - return false; - } - if (!(url = Redirect.to('post', { - boardID: this.boardID, - postID: this.postID - }))) { - return false; - } - archive = Redirect.data.post[this.boardID]; - encryptionOK = /^https:\/\//.test(url) || location.protocol === 'http:'; - if (encryptionOK || Conf['Exempt Archives from Encryption']) { - that = this; - CrossOrigin.cache(url, function() { - var key, media, ref, ref1; - if (!encryptionOK && ((ref = this.response) != null ? ref.media : void 0)) { - media = this.response.media; - for (key in media) { - if (/_link$/.test(key)) { - if (!((ref1 = $.getOwn(media, key)) != null ? ref1.match(/^http:\/\//) : void 0)) { - delete media[key]; - } - } - } - } - return that.parseArchivedPost(this.response, url, archive); - }); - return true; - } - return false; - }; - - Fetcher.prototype.parseArchivedPost = function(data, url, archive) { - var board, comment, greentext, i, j, media_link, o, post, ref, tag, text, text2, thread, thumb_link; - if (post = g.posts.get(this.boardID + "." + this.postID)) { - this.insert(post); - return; - } - if (data == null) { - $.addClass(this.root, 'warning'); - this.root.textContent = "Error fetching Post No." + this.postID + " from " + archive.name + "."; - return; - } - if (data.error) { - $.addClass(this.root, 'warning'); - this.root.textContent = data.error; - return; - } - comment = (data.comment || '').split(/(\n|\[\/?(?:b|spoiler|code|moot|banned|fortune(?: color="#\w+")?|i|red|green|blue)\])/); - comment = (function() { - var k, len, results; - results = []; - for (i = k = 0, len = comment.length; k < len; i = ++k) { - text = comment[i]; - if (i % 2 === 1) { - tag = this.archiveTags[text.replace(/\ .*\]/, ']')]; - if (typeof tag === 'function') { - results.push(tag(text)); - } else { - results.push(tag); - } - } else { - greentext = text[0] === '>'; - text = text.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2'); - text = (function() { - var l, len1, ref, results1; - ref = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g); - results1 = []; - for (j = l = 0, len1 = ref.length; l < len1; j = ++l) { - text2 = ref[j]; - results1.push({innerHTML: ((j % 2) ? "" + E(text2) + "" : E(text2))}); - } - return results1; - })(); - text = {innerHTML: ((greentext) ? "" + E.cat(text) + "" : E.cat(text))}; - results.push(text); - } - } - return results; - }).call(this); - comment = {innerHTML: E.cat(comment)}; - this.threadID = +data.thread_num; - o = { - ID: this.postID, - threadID: this.threadID, - boardID: this.boardID, - isReply: this.postID !== this.threadID - }; - o.info = { - subject: data.title, - email: data.email, - name: data.name || '', - tripcode: data.trip, - capcode: (function() { - switch (data.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: data.poster_hash, - flagCode: data.poster_country, - flagCodeTroll: data.troll_country_code, - flag: data.poster_country_name || data.troll_country_name, - dateUTC: data.timestamp, - dateText: data.fourchan_date, - commentHTML: comment - }; - if (o.info.capcode) { - delete o.info.uniqueID; - } - if (data.media && !!+data.media.banned) { - o.fileDeleted = true; - } else if ((ref = data.media) != null ? ref.media_filename : void 0) { - thumb_link = data.media.thumb_link; - if ((thumb_link != null ? thumb_link[0] : void 0) === '/') { - thumb_link = url.split('/', 3).join('/') + thumb_link; - } - if (!Redirect.securityCheck(thumb_link)) { - thumb_link = ''; - } - media_link = Redirect.to('file', { - boardID: this.boardID, - filename: data.media.media_orig - }); - if (!Redirect.securityCheck(media_link)) { - media_link = ''; - } - o.file = { - name: data.media.media_filename, - url: media_link || (this.boardID === 'f' ? location.protocol + "//" + (ImageHost.flashHost()) + "/" + this.boardID + "/" + (encodeURIComponent(E(data.media.media_filename))) : location.protocol + "//" + (ImageHost.host()) + "/" + this.boardID + "/" + data.media.media_orig), - height: data.media.media_h, - width: data.media.media_w, - MD5: data.media.media_hash, - size: $.bytesToString(data.media.media_size), - thumbURL: thumb_link || (location.protocol + "//" + (ImageHost.thumbHost()) + "/" + this.boardID + "/" + data.media.preview_orig), - theight: data.media.preview_h, - twidth: data.media.preview_w, - isSpoiler: data.media.spoiler === '1' - }; - if (!/\.pdf$/.test(o.file.url)) { - o.file.dimensions = o.file.width + "x" + o.file.height; - } - if (this.boardID === 'f' && data.media.exif) { - o.file.tag = JSON.parse(data.media.exif).Tag; - } - } - o.extra = $.dict(); - board = g.boards[this.boardID] || new Board(this.boardID); - thread = g.threads.get(this.boardID + "." + this.threadID) || new Thread(this.threadID, board); - post = new Post(g.SITE.Build.post(o), thread, board, { - isFetchedQuote: true - }); - post.kill(); - if (post.file) { - post.file.thumbURL = o.file.thumbURL; - } - Main.callbackNodes('Post', [post]); - return this.insert(post); - }; - - Fetcher.prototype.archiveTags = { - '\n': {innerHTML: "
"}, - '[b]': {innerHTML: ""}, - '[/b]': {innerHTML: ""}, - '[spoiler]': {innerHTML: ""}, - '[/spoiler]': {innerHTML: ""}, - '[code]': {innerHTML: "
"},
-      '[/code]': {innerHTML: "
"}, - '[moot]': {innerHTML: "
"}, - '[/moot]': {innerHTML: "
"}, - '[banned]': {innerHTML: ""}, - '[/banned]': {innerHTML: ""}, - '[fortune]': function(text) { - return {innerHTML: ""}; - }, - '[/fortune]': {innerHTML: ""}, - '[i]': {innerHTML: ""}, - '[/i]': {innerHTML: ""}, - '[red]': {innerHTML: ""}, - '[/red]': {innerHTML: ""}, - '[green]': {innerHTML: ""}, - '[/green]': {innerHTML: ""}, - '[blue]': {innerHTML: ""}, - '[/blue]': {innerHTML: ""} - }; - - return Fetcher; - - })(); - - return Fetcher; - -}).call(this); - -Notice = (function() { - var Notice, - bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - - Notice = (function() { - function Notice(type, content, timeout, onclose) { - this.timeout = timeout; - this.onclose = onclose; - this.close = bind(this.close, this); - this.add = bind(this.add, this); - this.el = $.el('div', {innerHTML: "
"}); - this.el.style.opacity = 0; - this.setType(type); - $.on(this.el.firstElementChild, 'click', this.close); - if (typeof content === 'string') { - content = $.tn(content); - } - $.add(this.el.lastElementChild, content); - $.ready(this.add); - } - - Notice.prototype.setType = function(type) { - return this.el.className = "notification " + type; - }; - - Notice.prototype.add = function() { - if (this.closed) { - return; - } - if (d.hidden) { - $.on(d, 'visibilitychange', this.add); - return; - } - $.off(d, 'visibilitychange', this.add); - $.add(Header.noticesRoot, this.el); - this.el.clientHeight; - this.el.style.opacity = 1; - if (this.timeout) { - return setTimeout(this.close, this.timeout * $.SECOND); - } - }; - - Notice.prototype.close = function() { - this.closed = true; - $.off(d, 'visibilitychange', this.add); - $.rm(this.el); - return typeof this.onclose === "function" ? this.onclose() : void 0; - }; - - return Notice; - - })(); - - return Notice; - -}).call(this); - -Post = (function() { - var Post, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Post = (function() { - Post.prototype.toString = function() { - return this.ID; - }; - - function Post(root, thread, board, flags) { - var clone, j, k, key, len, len1, ref, ref1, ref10, ref11, ref12, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, selector; - this.thread = thread; - this.board = board; - if (flags == null) { - flags = {}; - } - $.extend(this, flags); - this.ID = +root.id.match(/\d*$/)[0]; - this.postID = this.ID; - this.threadID = this.thread.ID; - this.boardID = this.board.ID; - this.siteID = g.SITE.ID; - this.fullID = this.board + "." + this.ID; - this.context = this; - this.isReply = this.ID !== this.threadID; - root.dataset.fullID = this.fullID; - this.nodes = this.parseNodes(root); - if (!this.isReply) { - this.thread.OP = this; - ref = ['isSticky', 'isClosed', 'isArchived']; - for (j = 0, len = ref.length; j < len; j++) { - key = ref[j]; - if ((selector = g.SITE.selectors.icons[key])) { - this.thread[key] = !!$(selector, this.nodes.info); - } - } - if (this.thread.isArchived) { - this.thread.isClosed = true; - this.thread.kill(); - } - } - this.info = { - subject: ((ref1 = this.nodes.subject) != null ? ref1.textContent : void 0) || void 0, - name: (ref2 = this.nodes.name) != null ? ref2.textContent : void 0, - email: this.nodes.email ? decodeURIComponent(this.nodes.email.href.replace(/^mailto:/, '')) : void 0, - tripcode: (ref3 = this.nodes.tripcode) != null ? ref3.textContent : void 0, - uniqueID: (ref4 = this.nodes.uniqueID) != null ? ref4.textContent : void 0, - capcode: (ref5 = this.nodes.capcode) != null ? ref5.textContent.replace('## ', '') : void 0, - pass: (ref6 = this.nodes.pass) != null ? ref6.title.match(/\d*$/)[0] : void 0, - flagCode: (ref7 = this.nodes.flag) != null ? (ref8 = ref7.className.match(/flag-(\w+)/)) != null ? ref8[1].toUpperCase() : void 0 : void 0, - flagCodeTroll: (ref9 = this.nodes.flag) != null ? (ref10 = ref9.className.match(/bfl-(\w+)/)) != null ? ref10[1].toUpperCase() : void 0 : void 0, - flag: (ref11 = this.nodes.flag) != null ? ref11.title : void 0, - date: this.nodes.date ? g.SITE.parseDate(this.nodes.date) : void 0 - }; - if (Conf['Anonymize']) { - this.info.nameBlock = 'Anonymous'; - } else { - this.info.nameBlock = ((this.info.name || '') + " " + (this.info.tripcode || '')).trim(); - } - if (this.info.capcode) { - this.info.nameBlock += " ## " + this.info.capcode; - } - if (this.info.uniqueID) { - this.info.nameBlock += " (ID: " + this.info.uniqueID + ")"; - } - this.parseComment(); - this.parseQuotes(); - this.parseFiles(); - this.isDead = false; - this.isHidden = false; - this.clones = []; - if (g.posts.get(this.fullID)) { - this.isRebuilt = true; - this.clones = g.posts.get(this.fullID).clones; - ref12 = this.clones; - for (k = 0, len1 = ref12.length; k < len1; k++) { - clone = ref12[k]; - clone.origin = this; - } - } - if (!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); - g.posts.push(this.fullID, this); - } - - Post.prototype.parseNodes = function(root) { - var base, info, key, nodes, post, ref, s, selector; - s = g.SITE.selectors; - post = $(s.post, root) || root; - info = $(s.infoRoot, post); - nodes = { - root: root, - bottom: this.isReply || !g.SITE.isOPContainerThread ? root : $(s.opBottom, root), - post: post, - info: info, - comment: $(s.comment, post), - quotelinks: [], - archivelinks: [], - embedlinks: [] - }; - ref = s.info; - for (key in ref) { - selector = ref[key]; - nodes[key] = $(selector, info); - } - if (typeof (base = g.SITE).parseNodes === "function") { - base.parseNodes(this, nodes); - } - nodes.uniqueIDRoot || (nodes.uniqueIDRoot = nodes.uniqueID); - if ($.engine === 'edge') { - Object.defineProperty(nodes, 'backlinks', { - configurable: true, - enumerable: true, - get: function() { - return post.getElementsByClassName('backlink'); - } - }); - } else { - nodes.backlinks = post.getElementsByClassName('backlink'); - } - return nodes; - }; - - Post.prototype.parseComment = function() { - var base, bq; - this.nodes.comment.normalize(); - this.nodes.commentClean = bq = this.nodes.comment.cloneNode(true); - if (typeof (base = g.SITE).cleanComment === "function") { - base.cleanComment(bq); - } - return this.info.comment = this.nodesToText(bq); - }; - - Post.prototype.commentDisplay = function() { - var base, bq; - bq = this.nodes.commentClean.cloneNode(true); - if (!(Conf['Remove Spoilers'] || Conf['Reveal Spoilers'])) { - this.cleanSpoilers(bq); - } - if (typeof (base = g.SITE).cleanCommentDisplay === "function") { - base.cleanCommentDisplay(bq); - } - return this.nodesToText(bq).trim().replace(/\s+$/gm, ''); - }; - - Post.prototype.commentOrig = function() { - var base, bq; - bq = this.nodes.commentClean.cloneNode(true); - if (typeof (base = g.SITE).insertTags === "function") { - base.insertTags(bq); - } - return this.nodesToText(bq); - }; - - Post.prototype.nodesToText = function(bq) { - var i, node, nodes, text; - text = ""; - nodes = $.X('.//br|.//text()', bq); - i = 0; - while (node = nodes.snapshotItem(i++)) { - text += node.data || '\n'; - } - return text; - }; - - Post.prototype.cleanSpoilers = function(bq) { - var j, len, node, spoilers; - spoilers = $$(g.SITE.selectors.spoiler, bq); - for (j = 0, len = spoilers.length; j < len; j++) { - node = spoilers[j]; - $.replace(node, $.tn('[spoiler]')); - } - }; - - Post.prototype.parseQuotes = function() { - var j, len, quotelink, ref; - this.quotes = []; - ref = $$(g.SITE.selectors.quotelink, this.nodes.comment); - for (j = 0, len = ref.length; j < len; j++) { - quotelink = ref[j]; - this.parseQuote(quotelink); - } - }; - - Post.prototype.parseQuote = function(quotelink) { - var fullID, match; - match = quotelink.href.match(g.SITE.regexp.quotelink); - if (!(match || (this.isClone && quotelink.dataset.postID))) { - return; - } - this.nodes.quotelinks.push(quotelink); - if (this.isClone) { - return; - } - fullID = match[1] + "." + match[3]; - if (indexOf.call(this.quotes, fullID) < 0) { - return this.quotes.push(fullID); - } - }; - - Post.prototype.parseFiles = function() { - var docIndex, file, fileRoot, fileRoots, index, j, len; - this.files = []; - fileRoots = this.fileRoots(); - index = 0; - for (docIndex = j = 0, len = fileRoots.length; j < len; docIndex = ++j) { - fileRoot = fileRoots[docIndex]; - if ((file = this.parseFile(fileRoot))) { - file.index = index++; - file.docIndex = docIndex; - this.files.push(file); - } - } - if (this.files.length) { - return this.file = this.files[0]; - } - }; - - Post.prototype.fileRoots = function() { - var roots; - if (g.SITE.selectors.multifile) { - roots = $$(g.SITE.selectors.multifile, this.nodes.root); - if (roots.length) { - return roots; - } - } - return [this.nodes.root]; - }; - - Post.prototype.parseFile = function(fileRoot) { - var file, key, ref, ref1, selector, size, unit; - file = {}; - ref = g.SITE.selectors.file; - for (key in ref) { - selector = ref[key]; - file[key] = $(selector, fileRoot); - } - file.thumbLink = (ref1 = file.thumb) != null ? ref1.parentNode : void 0; - if (!(file.text && file.link)) { - return; - } - if (!g.SITE.parseFile(this, file)) { - return; - } - $.extend(file, { - url: file.link.href, - isImage: $.isImage(file.link.href), - isVideo: $.isVideo(file.link.href) - }); - size = +file.size.match(/[\d.]+/)[0]; - unit = ['B', 'KB', 'MB', 'GB'].indexOf(file.size.match(/\w+$/)[0]); - while (unit-- > 0) { - size *= 1024; - } - file.sizeInBytes = size; - return file; - }; - - Post.deadMark = $.el('span', { - textContent: '\u00A0(Dead)', - className: 'qmark-dead' - }); - - Post.prototype.kill = function(file, index) { - var clone, j, k, len, len1, quotelink, ref, ref1, strong; - if (index == null) { - index = 0; - } - if (file) { - if (this.isDead || this.files[index].isDead) { - return; - } - this.files[index].isDead = true; - $.addClass(this.nodes.root, 'deleted-file'); - } else { - if (this.isDead) { - return; - } - this.isDead = true; - $.rmClass(this.nodes.root, 'deleted-file'); - $.addClass(this.nodes.root, 'deleted-post'); - } - if (!(strong = $('strong.warning', this.nodes.info))) { - strong = $.el('strong', { - className: 'warning' - }); - $.after($('input', this.nodes.info), strong); - } - strong.textContent = file ? '[File deleted]' : '[Deleted]'; - if (this.isClone) { - return; - } - ref = this.clones; - for (j = 0, len = ref.length; j < len; j++) { - clone = ref[j]; - clone.kill(file, index); - } - if (file) { - return; - } - ref1 = Get.allQuotelinksLinkingTo(this); - for (k = 0, len1 = ref1.length; k < len1; k++) { - quotelink = ref1[k]; - if (!(!$.hasClass(quotelink, 'deadlink'))) { - continue; - } - $.add(quotelink, Post.deadMark.cloneNode(true)); - $.addClass(quotelink, 'deadlink'); - } - }; - - Post.prototype.resurrect = function() { - var clone, j, k, len, len1, quotelink, ref, ref1, strong; - this.isDead = false; - $.rmClass(this.nodes.root, 'deleted-post'); - strong = $('strong.warning', this.nodes.info); - if (this.files.some(function(file) { - return file.isDead; - })) { - $.addClass(this.nodes.root, 'deleted-file'); - strong.textContent = '[File deleted]'; - } else { - $.rm(strong); - } - if (this.isClone) { - return; - } - ref = this.clones; - for (j = 0, len = ref.length; j < len; j++) { - clone = ref[j]; - clone.resurrect(); - } - ref1 = Get.allQuotelinksLinkingTo(this); - for (k = 0, len1 = ref1.length; k < len1; k++) { - quotelink = ref1[k]; - if (!($.hasClass(quotelink, 'deadlink'))) { - continue; - } - $.rm($('.qmark-dead', quotelink)); - $.rmClass(quotelink, 'deadlink'); - } - }; - - Post.prototype.collect = function() { - g.posts.rm(this.fullID); - this.thread.posts.rm(this); - return this.board.posts.rm(this); - }; - - Post.prototype.addClone = function(context, contractThumb) { - Callbacks.Post.execute(this); - return new Post.Clone(this, context, contractThumb); - }; - - Post.prototype.rmClone = function(index) { - var clone, j, len, ref; - this.clones.splice(index, 1); - ref = this.clones.slice(index); - for (j = 0, len = ref.length; j < len; j++) { - clone = ref[j]; - clone.nodes.root.dataset.clone = index++; - } - }; - - Post.prototype.setCatalogOP = function(isCatalogOP) { - this.nodes.root.classList.toggle('catalog-container', isCatalogOP); - this.nodes.root.classList.toggle('opContainer', !isCatalogOP); - this.nodes.post.classList.toggle('catalog-post', isCatalogOP); - this.nodes.post.classList.toggle('op', !isCatalogOP); - return this.nodes.post.style.left = this.nodes.post.style.right = null; - }; - - return Post; - - })(); - - return Post; - -}).call(this); - -(function() { - var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, - hasProp = {}.hasOwnProperty, - slice = [].slice; - - Post.Clone = (function(superClass) { - extend(_Class, superClass); - - _Class.prototype.isClone = true; - - function _Class() { - var that; - that = Object.create(Post.Clone.prototype); - that.construct.apply(that, arguments); - return that; - } - - _Class.prototype.construct = function(origin, context, contractThumb) { - var base, file, fileRoot, fileRoots, i, inline, inlined, j, k, key, l, len, len1, len2, len3, len4, m, node, nodes, originFile, ref, ref1, ref2, ref3, ref4, ref5, ref6, root, selector, val; - this.origin = origin; - this.context = context; - ref = ['ID', 'postID', 'threadID', 'boardID', 'siteID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']; - for (i = 0, len = ref.length; i < len; i++) { - key = ref[i]; - this[key] = this.origin[key]; - } - nodes = this.origin.nodes; - root = contractThumb ? this.cloneWithoutVideo(nodes.root) : nodes.root.cloneNode(true); - (base = Post.Clone).suffix || (base.suffix = 0); - ref1 = [root].concat(slice.call($$('[id]', root))); - for (j = 0, len1 = ref1.length; j < len1; j++) { - node = ref1[j]; - node.id += "_" + Post.Clone.suffix; - } - Post.Clone.suffix++; - ref2 = $$('.inline', root); - for (k = 0, len2 = ref2.length; k < len2; k++) { - inline = ref2[k]; - $.rm(inline); - } - ref3 = $$('.inlined', root); - for (l = 0, len3 = ref3.length; l < len3; l++) { - inlined = ref3[l]; - $.rmClass(inlined, 'inlined'); - } - this.nodes = this.parseNodes(root); - root.hidden = false; - $.rmClass(root, 'forwarded'); - $.rmClass(this.nodes.post, 'highlight'); - if (!this.isReply) { - this.setCatalogOP(false); - $.rm($('.catalog-link', this.nodes.post)); - $.rm($('.catalog-stats', this.nodes.post)); - $.rm($('.catalog-replies', this.nodes.post)); - } - this.parseQuotes(); - this.quotes = slice.call(this.origin.quotes); - this.files = []; - if (this.origin.files.length) { - fileRoots = this.fileRoots(); - } - ref4 = this.origin.files; - for (m = 0, len4 = ref4.length; m < len4; m++) { - originFile = ref4[m]; - file = {}; - for (key in originFile) { - val = originFile[key]; - file[key] = val; - } - fileRoot = fileRoots[file.docIndex]; - ref5 = g.SITE.selectors.file; - for (key in ref5) { - selector = ref5[key]; - file[key] = $(selector, fileRoot); - } - file.thumbLink = (ref6 = file.thumb) != null ? ref6.parentNode : void 0; - if (file.thumbLink) { - file.fullImage = $('.full-image', file.thumbLink); - } - file.videoControls = $('.video-controls', file.text); - if (file.videoThumb) { - file.thumb.muted = true; - } - this.files.push(file); - } - if (this.files.length) { - this.file = this.files[0]; - if (this.file.thumb && contractThumb) { - ImageExpand.contract(this); - } - } - if (this.origin.isDead) { - this.isDead = true; - } - return root.dataset.clone = this.origin.clones.push(this) - 1; - }; - - _Class.prototype.cloneWithoutVideo = function(node) { - var child, clone, i, len, ref; - if (node.tagName === 'VIDEO' && !node.dataset.md5) { - return []; - } else if (node.nodeType === Node.ELEMENT_NODE && $('video', node)) { - clone = node.cloneNode(false); - ref = node.childNodes; - for (i = 0, len = ref.length; i < len; i++) { - child = ref[i]; - $.add(clone, this.cloneWithoutVideo(child)); - } - return clone; - } else { - return node.cloneNode(true); - } - }; - - return _Class; - - })(Post); - -}).call(this); - -RandomAccessList = (function() { - var RandomAccessList; - - RandomAccessList = (function() { - function RandomAccessList(items) { - var i, item, len; - this.length = 0; - if (items) { - for (i = 0, len = items.length; i < len; i++) { - item = items[i]; - this.push(item); - } - } - } - - RandomAccessList.prototype.push = function(data) { - var ID, item, last; - ID = data.ID; - ID || (ID = data.id); - if (this[ID]) { - return; - } - last = this.last; - this[ID] = item = { - prev: last, - next: null, - data: data, - ID: ID - }; - item.prev = last; - this.last = last ? last.next = item : this.first = item; - return this.length++; - }; - - RandomAccessList.prototype.before = function(root, item) { - var prev; - if (item.next === root || item === root) { - return; - } - this.rmi(item); - prev = root.prev; - root.prev = item; - item.next = root; - item.prev = prev; - if (prev) { - return prev.next = item; - } else { - return this.first = item; - } - }; - - RandomAccessList.prototype.after = function(root, item) { - var next; - if (item.prev === root || item === root) { - return; - } - this.rmi(item); - next = root.next; - root.next = item; - item.prev = root; - item.next = next; - if (next) { - return next.prev = item; - } else { - return this.last = item; - } - }; - - RandomAccessList.prototype.prepend = function(item) { - var first; - first = this.first; - if (item === first || !this[item.ID]) { - return; - } - this.rmi(item); - item.next = first; - if (first) { - first.prev = item; - } else { - this.last = item; - } - this.first = item; - return delete item.prev; - }; - - RandomAccessList.prototype.shift = function() { - return this.rm(this.first.ID); - }; - - RandomAccessList.prototype.order = function() { - var item, order; - order = [item = this.first]; - while (item = item.next) { - order.push(item); - } - return order; - }; - - RandomAccessList.prototype.rm = function(ID) { - var item; - item = this[ID]; - if (!item) { - return; - } - delete this[ID]; - this.length--; - this.rmi(item); - delete item.next; - return delete item.prev; - }; - - RandomAccessList.prototype.rmi = function(item) { - var next, prev; - prev = item.prev, next = item.next; - if (prev) { - prev.next = next; - } else { - this.first = next; - } - if (next) { - return next.prev = prev; - } else { - return this.last = prev; - } - }; - - return RandomAccessList; - - })(); - - return RandomAccessList; - -}).call(this); - -ShimSet = (function() { - var ShimSet; - - ShimSet = (function() { - function ShimSet() { - this.elements = $.dict(); - this.size = 0; - } - - ShimSet.prototype.has = function(value) { - return value in this.elements; - }; - - ShimSet.prototype.add = function(value) { - if (this.elements[value]) { - return; - } - this.elements[value] = true; - return this.size++; - }; - - ShimSet.prototype["delete"] = function(value) { - if (!this.elements[value]) { - return; - } - delete this.elements[value]; - return this.size--; - }; - - return ShimSet; - - })(); - - if (!('Set' in window)) { - window.Set = ShimSet; - } - - return ShimSet; - -}).call(this); - -SimpleDict = (function() { - var SimpleDict, - slice = [].slice; - - SimpleDict = (function() { - function SimpleDict() { - this.keys = []; - } - - SimpleDict.prototype.push = function(key, data) { - key = "" + key; - if (!this[key]) { - this.keys.push(key); - } - return this[key] = data; - }; - - SimpleDict.prototype.rm = function(key) { - var i; - key = "" + key; - if ((i = this.keys.indexOf(key)) !== -1) { - this.keys.splice(i, 1); - return delete this[key]; - } - }; - - SimpleDict.prototype.forEach = function(fn) { - var j, key, len, ref; - ref = slice.call(this.keys); - for (j = 0, len = ref.length; j < len; j++) { - key = ref[j]; - fn(this[key]); - } - }; - - SimpleDict.prototype.get = function(key) { - if (key === 'keys') { - return void 0; - } else { - return $.getOwn(this, key); - } - }; - - return SimpleDict; - - })(); - - return SimpleDict; - -}).call(this); - -Thread = (function() { - var Thread; - - Thread = (function() { - Thread.prototype.toString = function() { - return this.ID; - }; - - function Thread(ID, board) { - this.board = board; - this.ID = +ID; - this.threadID = this.ID; - this.boardID = this.board.ID; - this.siteID = g.SITE.ID; - this.fullID = this.board + "." + this.ID; - this.posts = new SimpleDict(); - this.isDead = false; - this.isHidden = false; - this.isSticky = false; - this.isClosed = false; - this.isArchived = false; - this.postLimit = false; - this.fileLimit = false; - 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); - g.threads.push(this.fullID, this); - } - - Thread.prototype.setPage = function(pageNum) { - var icon, info, ref, reply; - ref = this.OP.nodes, info = ref.info, reply = ref.reply; - if (!(icon = $('.page-num', info))) { - icon = $.el('span', { - className: 'page-num' - }); - $.replace(reply.parentNode.previousSibling, [$.tn(' '), icon, $.tn(' ')]); - } - icon.title = "This thread is on page " + pageNum + " in the original index."; - icon.textContent = "[" + pageNum + "]"; - if (this.catalogView) { - return this.catalogView.nodes.pageCount.textContent = pageNum; - } - }; - - Thread.prototype.setCount = function(type, count, reachedLimit) { - var el; - if (!this.catalogView) { - return; - } - el = this.catalogView.nodes[type + "Count"]; - el.textContent = count; - return (reachedLimit ? $.addClass : $.rmClass)(el, 'warning'); - }; - - Thread.prototype.setStatus = function(type, status) { - var name; - name = "is" + type; - if (this[name] === status) { - return; - } - this[name] = status; - if (!this.OP) { - return; - } - this.setIcon('Sticky', this.isSticky); - this.setIcon('Closed', this.isClosed && !this.isArchived); - return this.setIcon('Archived', this.isArchived); - }; - - Thread.prototype.setIcon = function(type, status) { - var icon, root, typeLC; - typeLC = type.toLowerCase(); - icon = $("." + typeLC + "Icon", this.OP.nodes.info); - if (!!icon === status) { - return; - } - if (!status) { - $.rm(icon.previousSibling); - $.rm(icon); - if (this.catalogView) { - $.rm($("." + typeLC + "Icon", this.catalogView.nodes.icons)); - } - return; - } - icon = $.el('img', { - src: "" + g.SITE.Build.staticPath + typeLC + g.SITE.Build.gifIcon, - alt: type, - title: type, - className: typeLC + "Icon retina" - }); - if (g.BOARD.ID === 'f') { - icon.style.cssText = 'height: 18px; width: 18px;'; - } - root = type !== 'Sticky' && this.isSticky ? $('.stickyIcon', this.OP.nodes.info) : $('.page-num', this.OP.nodes.info) || this.OP.nodes.quote; - $.after(root, [$.tn(' '), icon]); - if (!this.catalogView) { - return; - } - return (type === 'Sticky' && this.isClosed ? $.prepend : $.add)(this.catalogView.nodes.icons, icon.cloneNode()); - }; - - Thread.prototype.kill = function() { - return this.isDead = true; - }; - - Thread.prototype.collect = function() { - var n; - n = 0; - this.posts.forEach(function(post) { - if (post.clones.length) { - return n++; - } else { - return post.collect(); - } - }); - if (!n) { - g.threads.rm(this.fullID); - return this.board.threads.rm(this); - } - }; - - return Thread; - - })(); - - return Thread; - -}).call(this); - -SW = {}; - -(function() { - var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - SW.tinyboard = { - isOPContainerThread: true, - mayLackJSON: true, - threadModTimeIgnoresSage: true, - 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: function() { - var j, len, m, properties, ref, root, script; - ref = $$('script:not([src])', d.head); - for (j = 0, len = ref.length; j < len; j++) { - script = ref[j]; - if ((m = script.textContent.match(/\bvar configRoot=(".*?")/))) { - properties = $.dict(); - try { - root = JSON.parse(m[1]); - if (root[0] === '/') { - properties.root = location.origin + root; - } else if (/^https?:/.test(root)) { - properties.root = root; - } - } catch (error) {} - return properties; - } - } - return false; - }, - awaitBoard: function(cb) { - var reactUI, s; - if ((reactUI = $.id('react-ui'))) { - s = this.selectors = Object.create(this.selectors); - s.boardFor = { - index: '.page-container' - }; - s.thread = 'div[id^="thread_"]'; - return Main.mounted(cb); - } else { - return cb(); - } - }, - urls: { - thread: function(arg, isArchived) { - var boardID, ref, siteID, threadID; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID; - return "" + (((ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0) || ("http://" + siteID + "/")) + boardID + "/" + (isArchived ? 'archive/' : '') + "res/" + threadID + ".html"; - }, - post: function(arg) { - var postID; - postID = arg.postID; - return "#" + postID; - }, - index: function(arg) { - var boardID, ref, siteID; - siteID = arg.siteID, boardID = arg.boardID; - return "" + (((ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0) || ("http://" + siteID + "/")) + boardID + "/"; - }, - catalog: function(arg) { - var boardID, ref, siteID; - siteID = arg.siteID, boardID = arg.boardID; - return "" + (((ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0) || ("http://" + siteID + "/")) + boardID + "/catalog.html"; - }, - threadJSON: function(arg, isArchived) { - var boardID, ref, root, siteID, threadID; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID; - root = (ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0; - if (root) { - return "" + root + boardID + "/" + (isArchived ? 'archive/' : '') + "res/" + threadID + ".json"; - } else { - return ''; - } - }, - archivedThreadJSON: function(thread) { - return SW.tinyboard.urls.threadJSON(thread, true); - }, - threadsListJSON: function(arg) { - var boardID, ref, root, siteID; - siteID = arg.siteID, boardID = arg.boardID; - root = (ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0; - if (root) { - return "" + root + boardID + "/threads.json"; - } else { - return ''; - } - }, - archiveListJSON: function(arg) { - var boardID, ref, root, siteID; - siteID = arg.siteID, boardID = arg.boardID; - root = (ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0; - if (root) { - return "" + root + boardID + "/archive/archive.json"; - } else { - return ''; - } - }, - catalogJSON: function(arg) { - var boardID, ref, root, siteID; - siteID = arg.siteID, boardID = arg.boardID; - root = (ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0; - if (root) { - return "" + root + boardID + "/catalog.json"; - } else { - return ''; - } - }, - file: function(arg, filename) { - var boardID, ref, siteID; - siteID = arg.siteID, boardID = arg.boardID; - return "" + (((ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0) || ("http://" + siteID + "/")) + boardID + "/" + filename; - }, - thumb: function(board, filename) { - return SW.tinyboard.urls.file(board, filename); - } - }, - 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: /\/([^\/]+)\/res\/(\d+)(?:\.\w+)?#(\d+)$/, - quotelinkHTML: /]*\bhref="[^"]*\/([^\/]+)\/res\/(\d+)(?:\.\w+)?#(\d+)"/g - }, - Build: { - parseJSON: function(data, board) { - var extra_file, file, i, j, len, o, ref; - o = SW.yotsuba.Build.parseJSON(data, board); - if (data.ext === 'deleted') { - delete o.file; - $.extend(o, { - files: [], - fileDeleted: true, - filesDeleted: [0] - }); - } - if (data.extra_files) { - ref = data.extra_files; - for (i = j = 0, len = ref.length; j < len; i = ++j) { - extra_file = ref[i]; - if (extra_file.ext === 'deleted') { - o.filesDeleted.push(i); - } else { - file = SW.yotsuba.Build.parseJSONFile(data, board); - o.files.push(file); - } - } - if (o.files.length) { - o.file = o.files[0]; - } - } - return o; - }, - parseComment: function(html) { - html = html.replace(//gi, '\n').replace(/<[^>]*>/g, ''); - return $.unescape(html); - } - }, - bgColoredEl: function() { - return $.el('div', { - className: 'post reply' - }); - }, - isFileURL: function(url) { - return /\/src\/[^\/]+/.test(url.pathname); - }, - preParsingFixes: function(board) { - var broken; - if ((broken = $('a > input[name="board"]', board))) { - return $.before(broken.parentNode, broken); - } - }, - parseNodes: function(post, nodes) { - var m, nextSibling, node, text, uniqueID; - if (nodes.uniqueID) { - return; - } - text = ''; - node = nodes.nameBlock.nextSibling; - while (node && node.nodeType === 3) { - text += node.textContent; - node = node.nextSibling; - } - if ((m = text.match(/(\s*ID:\s*)(\S+)/))) { - nodes.info.normalize(); - nextSibling = nodes.nameBlock.nextSibling; - nextSibling = nextSibling.splitText(m[1].length); - nextSibling.splitText(m[2].length); - nodes.uniqueID = uniqueID = $.el('span', { - className: 'poster_id' - }); - $.replace(nextSibling, uniqueID); - return $.add(uniqueID, nextSibling); - } - }, - parseDate: function(node) { - var date, ref; - date = Date.parse((ref = node.getAttribute('datetime')) != null ? ref.trim() : void 0); - if (!isNaN(date)) { - return new Date(date); - } - date = Date.parse(node.textContent.trim() + ' UTC'); - if (!isNaN(date)) { - return new Date(date); - } - return void 0; - }, - parseFile: function(post, file) { - var info, infoNode, link, nameNode, ref, ref1, text, thumb; - text = file.text, link = file.link, thumb = file.thumb; - if ($.x("ancestor::" + this.xpath.postContainer + "[1]", text) !== post.nodes.root) { - return false; - } - if (!(infoNode = indexOf.call((ref = link.nextSibling) != null ? ref.textContent : void 0, '(') >= 0 ? link.nextSibling : link.nextElementSibling)) { - return false; - } - if (!(info = infoNode.textContent.match(/\((.*,\s*)?([\d.]+ ?[KMG]?B).*\)/))) { - return false; - } - nameNode = $('.postfilename', text); - $.extend(file, { - name: nameNode ? nameNode.title || nameNode.textContent : link.pathname.match(/[^\/]*$/)[0], - size: info[2], - dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0 - }); - if (thumb) { - $.extend(file, { - thumbURL: /\/static\//.test(thumb.src) && $.isImage(link.href) ? link.href : thumb.src, - isSpoiler: /^Spoiler/i.test(info[1] || '') || link.textContent === 'Spoiler Image' - }); - } - return true; - }, - isThumbExpanded: function(file) { - return $.hasClass(file.thumb.parentNode, 'expanded') || file.thumb.parentNode.dataset.expanded === 'true'; - }, - isLinkified: function(link) { - return /\bnofollow\b/.test(link.rel); - }, - catalogPin: function(threadRoot) { - return threadRoot.dataset.sticky = 'true'; - } - }; - -}).call(this); - -(function() { - var slice = [].slice; - - SW.yotsuba = { - isOPContainerThread: false, - hasIPCount: true, - archivedBoardsKnown: true, - urls: { - thread: function(arg) { - var boardID, threadID; - boardID = arg.boardID, threadID = arg.threadID; - return location.protocol + "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/thread/" + threadID; - }, - post: function(arg) { - var postID; - postID = arg.postID; - return "#p" + postID; - }, - index: function(arg) { - var boardID; - boardID = arg.boardID; - return location.protocol + "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/"; - }, - catalog: function(arg) { - var boardID; - boardID = arg.boardID; - if (boardID === 'f') { - return void 0; - } else { - return location.protocol + "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/catalog"; - } - }, - archive: function(arg) { - var boardID; - boardID = arg.boardID; - if (BoardConfig.isArchived(boardID)) { - return location.protocol + "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/archive"; - } else { - return void 0; - } - }, - threadJSON: function(arg) { - var boardID, threadID; - boardID = arg.boardID, threadID = arg.threadID; - return location.protocol + "//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json"; - }, - threadsListJSON: function(arg) { - var boardID; - boardID = arg.boardID; - return location.protocol + "//a.4cdn.org/" + boardID + "/threads.json"; - }, - archiveListJSON: function(arg) { - var boardID; - boardID = arg.boardID; - if (BoardConfig.isArchived(boardID)) { - return location.protocol + "//a.4cdn.org/" + boardID + "/archive.json"; - } else { - return ''; - } - }, - catalogJSON: function(arg) { - var boardID; - boardID = arg.boardID; - return location.protocol + "//a.4cdn.org/" + boardID + "/catalog.json"; - }, - file: function(arg, filename) { - var boardID, hostname; - boardID = arg.boardID; - hostname = boardID === 'f' ? ImageHost.flashHost() : ImageHost.host(); - return location.protocol + "//" + hostname + "/" + boardID + "/" + filename; - }, - thumb: function(arg, filename) { - var boardID; - boardID = arg.boardID; - return location.protocol + "//" + (ImageHost.thumbHost()) + "/" + boardID + "/" + filename; - } - }, - isPrunedByAge: function(arg) { - var boardID; - boardID = arg.boardID; - return boardID === 'f'; - }, - areMD5sDeferred: function(arg) { - var boardID; - boardID = arg.boardID; - return boardID === 'f'; - }, - isOnePage: function(arg) { - var boardID; - boardID = arg.boardID; - return boardID === 'f'; - }, - noAudio: function(arg) { - var boardID; - boardID = arg.boardID; - return BoardConfig.noAudio(boardID); - }, - 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: /^https?:\/\/boards\.4chan(?:nel)?\.org\/+([^\/]+)\/+thread\/+(\d+)(?:[\/?][^#]*)?(?:#p(\d+))?$/, - quotelinkHTML: /]*\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: function() { - return $.el('div', { - className: 'reply' - }); - }, - isThisPageLegit: function() { - var ref, ref1; - return ((ref = location.hostname) === 'boards.4chan.org' || ref === 'boards.4channel.org') && d.doctype && !$('link[href*="favicon-status.ico"]', d.head) && ((ref1 = d.title) !== '4chan - Temporarily Offline' && ref1 !== '4chan - Error' && ref1 !== '504 Gateway Time-out' && ref1 !== 'MathJax Equation Source'); - }, - is404: function() { - var ref; - return ((ref = d.title) === '4chan - Temporarily Offline' || ref === '4chan - 404 Not Found') || (g.VIEW === 'thread' && $('.board') && !$('.opContainer')); - }, - isIncomplete: function() { - var ref; - return ((ref = g.VIEW) === 'index' || ref === 'thread') && !$('.board + *'); - }, - isBoardlessPage: function(url) { - var ref; - return (ref = url.hostname) === 'www.4chan.org' || ref === 'www.4channel.org'; - }, - isAuxiliaryPage: function(url) { - var ref; - return (ref = url.hostname) !== 'boards.4chan.org' && ref !== 'boards.4channel.org'; - }, - isFileURL: function(url) { - return ImageHost.test(url.hostname); - }, - initAuxiliary: function() { - var match, pathname; - switch (location.hostname) { - case 'www.4chan.org': - case 'www.4channel.org': - if (SW.yotsuba.regexp.pass.test(location.href)) { - PassMessage.init(); - } else { - $.onExists(doc, 'body', function() { - return $.addStyle(CSS.www); - }); - Captcha.replace.init(); - } - break; - case 'sys.4chan.org': - case 'sys.4channel.org': - pathname = location.pathname.split(/\/+/); - if (pathname[2] === 'imgboard.php') { - if (/\bmode=report\b/.test(location.search)) { - Report.init(); - } else if ((match = location.search.match(/\bres=(\d+)/))) { - $.ready(function() { - var ref; - if (Conf['404 Redirect'] && ((ref = $.id('errmsg')) != null ? ref.textContent : void 0) === 'Error: Specified thread does not exist.') { - return Redirect.navigate('thread', { - boardID: g.BOARD.ID, - postID: +match[1] - }); - } - }); - } - } else if (pathname[2] === 'post') { - PostSuccessful.init(); - } - } - }, - scriptData: function() { - var j, len, ref, script; - ref = $$('script:not([src])', d.head); - for (j = 0, len = ref.length; j < len; j++) { - script = ref[j]; - if (/\bcooldowns *=/.test(script.textContent)) { - return script.textContent; - } - } - return ''; - }, - parseThreadMetadata: function(thread) { - var file, m, scriptData; - scriptData = this.scriptData(); - thread.postLimit = /\bbumplimit *= *1\b/.test(scriptData); - thread.fileLimit = /\bimagelimit *= *1\b/.test(scriptData); - thread.ipCount = (m = scriptData.match(/\bunique_ips *= *(\d+)\b/)) ? +m[1] : void 0; - if (g.BOARD.ID === 'f' && thread.OP.file) { - file = thread.OP.file; - return $.ajax(this.urls.threadJSON({ - boardID: 'f', - threadID: thread.ID - }), { - timeout: $.MINUTE, - onloadend: function() { - if (this.response) { - return file.text.dataset.md5 = file.MD5 = this.response.posts[0].md5; - } - } - }); - } - }, - parseNodes: function(post, nodes) { - var icon, j, len, ref, results, type; - if (post.boardID === 'f') { - ref = ['Sticky', 'Closed']; - results = []; - for (j = 0, len = ref.length; j < len; j++) { - type = ref[j]; - if ((icon = $("img[alt=" + type + "]", nodes.info))) { - results.push($.addClass(icon, (type.toLowerCase()) + "Icon", 'retina')); - } - } - return results; - } - }, - parseDate: function(node) { - return new Date(node.dataset.utc * 1000); - }, - parseFile: function(post, file) { - var info, link, m, ref, ref1, ref2, text, thumb; - text = file.text, link = file.link, thumb = file.thumb; - if (!(info = (ref = link.nextSibling) != null ? ref.textContent.match(/\(([\d.]+ [KMG]?B).*\)/) : void 0)) { - return false; - } - $.extend(file, { - name: text.title || link.title || link.textContent, - size: info[1], - dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0, - tag: (ref2 = info[0].match(/,[^,]*, ([a-z]+)\)/i)) != null ? ref2[1] : void 0, - MD5: text.dataset.md5 - }); - if (thumb) { - $.extend(file, { - thumbURL: thumb.src, - MD5: thumb.dataset.md5, - isSpoiler: $.hasClass(thumb.parentNode, 'imgspoiler') - }); - if (file.isSpoiler) { - file.thumbURL = (m = link.href.match(/\d+(?=\.\w+$)/)) ? location.protocol + "//" + (ImageHost.thumbHost()) + "/" + post.board + "/" + m[0] + "s.jpg" : void 0; - } - } - return true; - }, - cleanComment: function(bq) { - var abbr, br, i, j, k, len, node, ref; - if ((abbr = $('.abbr', bq))) { - ref = $$('.abbr + br, .exif', bq); - for (j = 0, len = ref.length; j < len; j++) { - node = ref[j]; - $.rm(node); - } - for (i = k = 0; k < 2; i = ++k) { - if ((br = abbr.previousSibling) && br.nodeName === 'BR') { - $.rm(br); - } - } - return $.rm(abbr); - } - }, - cleanCommentDisplay: function(bq) { - var b; - if ((b = $('b', bq)) && /^Rolled /.test(b.textContent)) { - $.rm(b); - } - return $.rm($('.fortune', bq)); - }, - insertTags: function(bq) { - var j, k, len, len1, node, ref, ref1; - ref = $$('s, .removed-spoiler', bq); - for (j = 0, len = ref.length; j < len; j++) { - node = ref[j]; - $.replace(node, [$.tn('[spoiler]')].concat(slice.call(node.childNodes), [$.tn('[/spoiler]')])); - } - ref1 = $$('.prettyprint', bq); - for (k = 0, len1 = ref1.length; k < len1; k++) { - node = ref1[k]; - $.replace(node, [$.tn('[code]')].concat(slice.call(node.childNodes), [$.tn('[/code]')])); - } - }, - hasCORS: function(url) { - return url.split('/').slice(0, 3).join('/') === location.protocol + '//a.4cdn.org'; - }, - sfwBoards: function(sfw) { - return BoardConfig.sfwBoards(sfw); - }, - uidColor: function(uid) { - var i, msg; - msg = 0; - i = 0; - while (i < 8) { - msg = (msg << 5) - msg + uid.charCodeAt(i++); - } - return (msg >> 8) & 0xFFFFFF; - }, - isLinkified: function(link) { - return ImageHost.test(link.hostname); - }, - testNativeExtension: function() { - return $.global(function() { - if (window.Parser.postMenuIcon) { - return this.enabled = 'true'; - } - }); - }, - transformBoardList: function() { - var a, chr, i, items, j, len, node, nodes, ref, spacer, span; - nodes = []; - spacer = function() { - return $.el('span', { - className: 'spacer' - }); - }; - items = $.X('.//a|.//text()[not(ancestor::a)]', $(SW.yotsuba.selectors.boardList)); - i = 0; - while (node = items.snapshotItem(i++)) { - switch (node.nodeName) { - case '#text': - ref = node.nodeValue; - for (j = 0, len = ref.length; j < len; j++) { - chr = ref[j]; - span = $.el('span', { - textContent: chr - }); - if (chr === ' ') { - span.className = 'space'; - } - if (chr === ']') { - nodes.push(spacer()); - } - nodes.push(span); - if (chr === '[') { - nodes.push(spacer()); - } - } - break; - case 'A': - a = node.cloneNode(true); - nodes.push(a); - } - } - return nodes; - } - }; - -}).call(this); - -(function() { - var Build, - slice = [].slice; - - Build = { - staticPath: '//s.4cdn.org/image/', - gifIcon: window.devicePixelRatio >= 2 ? '@2x.gif' : '.gif', - spoilerRange: $.dict(), - shortFilename: function(filename) { - var ext; - ext = filename.match(/\.?[^\.]*$/)[0]; - if (filename.length - ext.length > 30) { - return (filename.match(/(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[^]){0,25}/)[0]) + "(...)" + ext; - } else { - return filename; - } - }, - spoilerThumb: function(boardID) { - var spoilerRange; - if (spoilerRange = Build.spoilerRange[boardID]) { - return Build.staticPath + "spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png"; - } else { - return Build.staticPath + "spoiler.png"; - } - }, - sameThread: function(boardID, threadID) { - return g.VIEW === 'thread' && g.BOARD.ID === boardID && g.THREADID === +threadID; - }, - threadURL: function(boardID, threadID) { - if (boardID !== g.BOARD.ID) { - return "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/thread/" + threadID; - } else if (g.VIEW !== 'thread' || +threadID !== g.THREADID) { - return "/" + boardID + "/thread/" + threadID; - } else { - return ''; - } - }, - postURL: function(boardID, threadID, postID) { - return (Build.threadURL(boardID, threadID)) + "#p" + postID; - }, - parseJSON: function(data, arg) { - var boardID, key, o, siteID; - siteID = arg.siteID, boardID = arg.boardID; - o = { - ID: data.no, - postID: data.no, - threadID: data.resto || data.no, - boardID: boardID, - siteID: siteID, - isReply: !!data.resto, - isSticky: !!data.sticky, - isClosed: !!data.closed, - isArchived: !!data.archived, - fileDeleted: !!data.filedeleted, - filesDeleted: data.filedeleted ? [0] : [] - }; - o.info = { - subject: $.unescape(data.sub), - email: $.unescape(data.email), - name: $.unescape(data.name) || '', - tripcode: data.trip, - pass: data.since4pass != null ? "" + data.since4pass : void 0, - uniqueID: data.id, - flagCode: data.country, - flagCodeTroll: data.board_flag, - flag: $.unescape(data.country_name || data.flag_name), - dateUTC: data.time, - dateText: data.now, - commentHTML: { - innerHTML: data.com || '' - } - }; - if (data.capcode) { - o.info.capcode = data.capcode.replace(/_highlight$/, '').replace(/_/g, ' ').replace(/\b\w/g, function(c) { - return c.toUpperCase(); - }); - o.capcodeHighlight = /_highlight$/.test(data.capcode); - delete o.info.uniqueID; - } - o.files = []; - if (data.ext) { - o.file = SW.yotsuba.Build.parseJSONFile(data, { - siteID: siteID, - boardID: boardID - }); - o.files.push(o.file); - } - o.extra = $.dict(); - for (key in data) { - if (key[0] === 'x') { - o.extra[key] = data[key]; - } - } - return o; - }, - parseJSONFile: function(data, arg) { - var boardID, filename, o, site, siteID; - siteID = arg.siteID, boardID = arg.boardID; - site = g.sites[siteID]; - filename = site.software === 'yotsuba' && boardID === 'f' ? "" + (encodeURIComponent(data.filename)) + data.ext : "" + data.tim + data.ext; - o = { - name: ($.unescape(data.filename)) + data.ext, - url: site.urls.file({ - siteID: siteID, - boardID: boardID - }, filename), - height: data.h, - width: data.w, - MD5: data.md5, - size: $.bytesToString(data.fsize), - thumbURL: site.urls.thumb({ - siteID: siteID, - boardID: boardID - }, data.tim + "s.jpg"), - theight: data.tn_h, - twidth: data.tn_w, - isSpoiler: !!data.spoiler, - tag: data.tag, - hasDownscale: !!data.m_img - }; - if ((data.h != null) && !/\.pdf$/.test(o.url)) { - o.dimensions = o.width + "x" + o.height; - } - return o; - }, - parseComment: function(html) { - html = html.replace(//gi, '\n').replace(/\n\n]*>/g, ''); - return $.unescape(html); - }, - parseCommentDisplay: function(html) { - var html2; - if (!(Conf['Remove Spoilers'] || Conf['Reveal Spoilers'])) { - while ((html2 = html.replace(/(?:(?!<\/?s>).)*<\/s>/g, '[spoiler]')) !== html) { - html = html2; - } - } - html = html.replace(/^Rolled [^<]*<\/b>/i, '').replace(/ " + ((!o.isReply || boardID === "f" || subject) ? "" + E(subject || "") + " " : "") + "" + ((email) ? "" : "") + "" + E(name) + "" + ((tripcode) ? " " + E(tripcode) + "" : "") + ((pass) ? " " : "") + ((capcode) ? " ## " + E(capcode) + "" : "") + ((email) ? "" : "") + ((boardID === "f" && !o.isReply || capcodeDescription) ? "" : " ") + ((capcodeDescription) ? " \""" : "") + ((uniqueID && !capcode) ? " (ID: " + E(uniqueID) + ")" : "") + ((flagCode) ? " " : "") + ((flagCodeTroll) ? " " : "") + " " + E(dateText) + " No." + E(ID) + "" + ((o.isSticky) ? " \"Sticky\"" : "") + ((o.isClosed && !o.isArchived) ? " \"Closed\"" : "") + ((o.isArchived) ? " \"Archived\"" : "") + ((!o.isReply && g.VIEW === "index") ? "   [Reply]" : "") + ""}; - - /* File Info */ - if (file) { - protocol = /^https?:(?=\/\/i\.4cdn\.org\/)/; - fileURL = file.url.replace(protocol, ''); - shortFilename = Build.shortFilename(file.name); - fileThumb = file.isSpoiler ? Build.spoilerThumb(boardID) : file.thumbURL.replace(protocol, ''); - } - fileBlock = {innerHTML: ((file) ? "
" + ((boardID === "f") ? "
File: " + E(file.name) + "-(" + E(file.size) + ", " + E(file.dimensions) + ((file.tag) ? ", " + E(file.tag) : "") + ")
" : "
File: " + ((file.isSpoiler) ? "Spoiler Image" : E(shortFilename)) + " (" + E(file.size) + ", " + E(file.dimensions || "PDF") + ")
\""") + "
" : ((o.fileDeleted) ? "
\"File
" : ""))}; - - /* Whole Post */ - postClass = o.isReply ? 'reply' : 'op'; - wholePost = {innerHTML: ((o.isReply) ? "
>>
" : "") + "
" + ((o.isReply) ? (postInfo).innerHTML + (fileBlock).innerHTML : (fileBlock).innerHTML + (postInfo).innerHTML) + "
" + (commentHTML).innerHTML + "
"}; - container = $.el('div', { - className: "postContainer " + postClass + "Container", - id: "pc" + ID - }); - $.extend(container, wholePost); - ref1 = $$('.quotelink', container); - for (i = 0, len = ref1.length; i < len; i++) { - quote = ref1[i]; - href = quote.getAttribute('href'); - if (href[0] === '#') { - if (!Build.sameThread(boardID, threadID)) { - quote.href = Build.threadURL(boardID, threadID) + href; - } - } else { - if ((match = quote.href.match(SW.yotsuba.regexp.quotelink)) && (Build.sameThread(match[1], match[2]))) { - quote.href = href.match(/(#[^#]*)?$/)[0] || '#'; - } - } - } - return container; - }, - summaryText: function(status, posts, files) { - var text; - text = ''; - if (status) { - text += status + " "; - } - text += posts + " post" + (posts > 1 ? 's' : ''); - if (+files) { - text += " and " + files + " image repl" + (files > 1 ? 'ies' : 'y'); - } - return text += " " + (status === '-' ? 'shown' : 'omitted') + "."; - }, - summary: function(boardID, threadID, posts, files) { - return $.el('a', { - className: 'summary', - textContent: Build.summaryText('', posts, files), - href: "/" + boardID + "/thread/" + threadID - }); - }, - thread: function(thread, data, withReplies) { - var files, posts, ref, root, summary; - if ((root = thread.nodes.root)) { - $.rmAll(root); - } else { - thread.nodes.root = root = $.el('div', { - className: 'thread', - id: "t" + data.no - }); - } - if (Build.hat) { - $.add(root, Build.hat.cloneNode(false)); - } - $.add(root, thread.OP.nodes.root); - if (data.omitted_posts || !withReplies && data.replies) { - ref = withReplies ? [ - data.omitted_posts, data.images - data.last_replies.filter(function(data) { - return !!data.ext; - }).length - ] : [data.replies, data.images], posts = ref[0], files = ref[1]; - summary = Build.summary(thread.board.ID, data.no, posts, files); - $.add(root, summary); - } - return root; - }, - catalogThread: function(thread, data, pageCount) { - var br, container, cssText, fileCount, gifIcon, i, imgClass, len, postCount, ratio, ref, root, spoilerRange, src, staticPath, tn_h, tn_w; - staticPath = Build.staticPath, gifIcon = Build.gifIcon; - tn_w = data.tn_w, tn_h = data.tn_h; - if (data.spoiler && !Conf['Reveal Spoiler Thumbnails']) { - src = staticPath + "spoiler"; - if (spoilerRange = Build.spoilerRange[thread.board]) { - src += ("-" + thread.board) + Math.floor(1 + spoilerRange * Math.random()); - } - src += '.png'; - imgClass = 'spoiler-file'; - cssText = "--tn-w: 100; --tn-h: 100;"; - } else if (data.filedeleted) { - src = staticPath + "filedeleted-res" + gifIcon; - imgClass = 'deleted-file'; - } else if (thread.OP.file) { - src = thread.OP.file.thumbURL; - ratio = 250 / Math.max(tn_w, tn_h); - cssText = "--tn-w: " + (tn_w * ratio) + "; --tn-h: " + (tn_h * ratio) + ";"; - } else { - src = staticPath + "nofile.png"; - imgClass = 'no-file'; - } - postCount = data.replies + 1; - fileCount = data.images + !!data.ext; - container = $.el('div', {innerHTML: "
" + E(postCount) + " / " + E(fileCount) + " / " + E(pageCount) + "" + ((thread.isSticky) ? "" : "") + ((thread.isClosed) ? "" : "") + "
"}); - $.before(thread.OP.nodes.info, slice.call(container.childNodes)); - ref = $$('br', thread.OP.nodes.comment); - for (i = 0, len = ref.length; i < len; i++) { - br = ref[i]; - if (br.previousSibling && br.previousSibling.nodeName === 'BR') { - $.addClass(br, 'extra-linebreak'); - } - } - root = $.el('div', { - className: 'thread catalog-thread', - id: "t" + thread - }); - if (thread.OP.highlights) { - $.addClass.apply($, [root].concat(slice.call(thread.OP.highlights))); - } - if (!thread.OP.file) { - $.addClass(root, 'noFile'); - } - root.style.cssText = cssText || ''; - return root; - }, - catalogReply: function(thread, data) { - var excerpt, link; - excerpt = ''; - if (data.com) { - excerpt = Build.parseCommentDisplay(data.com).replace(/>>\d+/g, '').trim().replace(/\n+/g, ' // '); - } - if (data.ext) { - excerpt || (excerpt = "" + ($.unescape(data.filename)) + data.ext); - } - if (data.com) { - excerpt || (excerpt = $.unescape(data.com.replace(//gi, ' // '))); - } - excerpt || (excerpt = '\xA0'); - if (excerpt.length > 73) { - excerpt = excerpt.slice(0, 70) + "..."; - } - link = Build.postURL(thread.board.ID, thread.ID, data.no); - return $.el('div', { - className: 'catalog-reply' - }, {innerHTML: ": " + E(excerpt) + "..."}); - } - }; - - SW.yotsuba.Build = Build; - -}).call(this); - -Site = (function() { - var Site; - - Site = { - 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: function(cb) { - var hostname; - $.extend(Conf['siteProperties'], Site.defaultProperties); - hostname = Site.resolve(); - if (hostname && $.hasOwn(SW, Conf['siteProperties'][hostname].software)) { - this.set(hostname); - cb(); - } - return $.onExists(doc, 'body', (function(_this) { - return function() { - var base, base1, changed, changes, key, properties, software; - for (software in SW) { - if (!((changes = typeof (base = SW[software]).detect === "function" ? base.detect() : void 0))) { - continue; - } - changes.software = software; - hostname = location.hostname.replace(/^www\./, ''); - properties = ((base1 = Conf['siteProperties'])[hostname] || (base1[hostname] = $.dict())); - changed = 0; - for (key in changes) { - if (!(properties[key] !== changes[key])) { - continue; - } - properties[key] = changes[key]; - changed++; - } - if (changed) { - $.set('siteProperties', Conf['siteProperties']); - } - if (!g.SITE) { - _this.set(hostname); - cb(); - } - return; - } - }; - })(this)); - }, - resolve: function(url) { - var canonical, hostname; - if (url == null) { - url = location; - } - hostname = url.hostname; - while (hostname && !$.hasOwn(Conf['siteProperties'], hostname)) { - hostname = hostname.replace(/^[^.]*\.?/, ''); - } - if (hostname) { - if ((canonical = Conf['siteProperties'][hostname].canonical)) { - hostname = canonical; - } - } - return hostname; - }, - parseURL: function(url) { - var siteID; - siteID = Site.resolve(url); - return Main.parseURL(g.sites[siteID], url); - }, - set: function(hostname) { - var ID, properties, ref, site, software; - ref = Conf['siteProperties']; - for (ID in ref) { - properties = ref[ID]; - if (properties.canonical) { - continue; - } - software = properties.software; - if (!(software && $.hasOwn(SW, software))) { - continue; - } - g.sites[ID] = site = Object.create(SW[software]); - $.extend(site, { - ID: ID, - siteID: ID, - properties: properties, - software: software - }); - } - return g.SITE = g.sites[hostname]; - } - }; - - return Site; - -}).call(this); - -Redirect = (function() { - var Redirect, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Redirect = { - archives: [ - { "uid": 3, "name": "4plebs", "domain": "archive.4plebs.org", "http": true, "https": true, "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": true }, - { "uid": 10, "name": "warosu", "domain": "warosu.org", "http": false, "https": true, "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": true, "https": true, "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": true }, - { "uid": 24, "name": "fireden.net", "domain": "boards.fireden.net", "http": false, "https": true, "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": true, "https": true, "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": true, "https": true, "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": true }, - { "uid": 30, "name": "TheBArchive.com", "domain": "thebarchive.com", "http": true, "https": true, "software": "foolfuuka", "boards": [ "b", "bant" ], "files": [ "b", "bant" ], "reports": true }, - { "uid": 31, "name": "Archive Of Sins", "domain": "archiveofsins.com", "http": true, "https": true, "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": true }, - { "uid": 34, "name": "TokyoChronos", "domain": "www.tokyochronos.net", "http": false, "https": true, "software": "foolfuuka", "boards": [ "c", "g", "jp", "mu", "vp", "vrpg", "vt" ], "files": [], "reports": true }, - { "uid": 36, "name": "palanq.win", "domain": "archive.palanq.win", "http": false, "https": true, "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": true }, - { "uid": 37, "name": "Eientei", "domain": "eientei.xyz", "http": false, "https": true, "software": "Eientei", "boards": [ "3", "i", "sci", "xs" ], "files": [ "3", "i", "sci", "xs" ], "reports": true } - ], - init: function() { - var now, ref; - this.selectArchives(); - if (Conf['archiveAutoUpdate']) { - now = Date.now(); - if (!((now - 2 * $.DAY < (ref = Conf['lastarchivecheck']) && ref <= now))) { - return this.update(); - } - } - }, - selectArchives: function() { - var archive, archives, boardID, boards, data, files, id, j, k, key, l, len, len1, len2, name, o, record, ref, ref1, ref2, software, type, uid; - o = { - thread: $.dict(), - post: $.dict(), - file: $.dict() - }; - archives = $.dict(); - ref = Conf['archives']; - for (j = 0, len = ref.length; j < len; j++) { - data = ref[j]; - ref1 = ['boards', 'files']; - for (k = 0, len1 = ref1.length; k < len1; k++) { - key = ref1[k]; - if (!(data[key] instanceof Array)) { - data[key] = []; - } - } - uid = data.uid, name = data.name, boards = data.boards, files = data.files, software = data.software; - if (software !== 'fuuka' && software !== 'foolfuuka') { - continue; - } - archives[JSON.stringify(uid != null ? uid : name)] = data; - for (l = 0, len2 = boards.length; l < len2; l++) { - boardID = boards[l]; - if (!(boardID in o.thread)) { - o.thread[boardID] = data; - } - if (!(boardID in o.post || software !== 'foolfuuka')) { - o.post[boardID] = data; - } - if (!(boardID in o.file || indexOf.call(files, boardID) < 0)) { - o.file[boardID] = data; - } - } - } - ref2 = Conf['selectedArchives']; - for (boardID in ref2) { - record = ref2[boardID]; - for (type in record) { - id = record[type]; - if (!((archive = archives[JSON.stringify(id)]) && $.hasOwn(o, type))) { - continue; - } - boards = type === 'file' ? archive.files : archive.boards; - if (indexOf.call(boards, boardID) >= 0) { - o[type][boardID] = archive; - } - } - } - return Redirect.data = o; - }, - update: function(cb) { - var err, fail, i, j, k, len, len1, load, nloaded, ref, ref1, response, responses, url, urls; - urls = []; - responses = []; - nloaded = 0; - ref = Conf['archiveLists'].split('\n'); - for (j = 0, len = ref.length; j < len; j++) { - url = ref[j]; - if (!(url[0] !== '#')) { - continue; - } - url = url.trim(); - if (url) { - urls.push(url); - } - } - fail = function(url, action, msg) { - return new Notice('warning', "Error " + action + " archive data from\n" + url + "\n" + msg, 20); - }; - load = function(i) { - return function() { - var response; - if (this.status !== 200) { - return fail(urls[i], 'fetching', (this.status ? "Error " + this.statusText + " (" + this.status + ")" : 'Connection Error')); - } - response = this.response; - if (!(response instanceof Array)) { - response = [response]; - } - responses[i] = response; - nloaded++; - if (nloaded === urls.length) { - return Redirect.parse(responses, cb); - } - }; - }; - if (urls.length) { - for (i = k = 0, len1 = urls.length; k < len1; i = ++k) { - url = urls[i]; - if ((ref1 = url[0]) === '[' || ref1 === '{') { - try { - response = JSON.parse(url); - } catch (error) { - err = error; - fail(url, 'parsing', err.message); - continue; - } - load(i).call({ - status: 200, - response: response - }); - } else { - CrossOrigin.ajax(url, { - onloadend: load(i) - }); - } - } - } else { - Redirect.parse([], cb); - } - }, - parse: function(responses, cb) { - var archiveUIDs, archives, data, items, j, k, len, len1, ref, response, uid; - archives = []; - archiveUIDs = $.dict(); - for (j = 0, len = responses.length; j < len; j++) { - response = responses[j]; - for (k = 0, len1 = response.length; k < len1; k++) { - data = response[k]; - uid = JSON.stringify((ref = data.uid) != null ? ref : data.name); - if (uid in archiveUIDs) { - $.extend(archiveUIDs[uid], data); - } else { - archiveUIDs[uid] = $.dict.clone(data); - archives.push(data); - } - } - } - items = { - archives: archives, - lastarchivecheck: Date.now() - }; - $.set(items); - $.extend(Conf, items); - Redirect.selectArchives(); - return typeof cb === "function" ? cb() : void 0; - }, - to: function(dest, data) { - var archive; - archive = (dest === 'search' || dest === 'board' ? Redirect.data.thread : Redirect.data[dest])[data.boardID]; - if (!archive) { - return ''; - } - return Redirect[dest](archive, data); - }, - protocol: function(archive) { - var protocol; - protocol = location.protocol; - if (!$.getOwn(archive, protocol.slice(0, -1))) { - protocol = protocol === 'https:' ? 'http:' : 'https:'; - } - return protocol + "//"; - }, - thread: function(archive, arg) { - var boardID, path, postID, threadID; - boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID; - path = threadID ? boardID + "/thread/" + threadID : boardID + "/post/" + postID; - if (archive.software === 'foolfuuka') { - path += '/'; - } - if (threadID && postID) { - path += archive.software === 'foolfuuka' ? "#" + postID : "#p" + postID; - } - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; - }, - post: function(archive, arg) { - var boardID, postID, protocol, url; - boardID = arg.boardID, postID = arg.postID; - protocol = Redirect.protocol(archive); - url = "" + protocol + archive.domain + "/_/api/chan/post/?board=" + boardID + "&num=" + postID; - if (!Redirect.securityCheck(url)) { - return ''; - } - return url; - }, - file: function(archive, arg) { - var boardID, filename; - boardID = arg.boardID, filename = arg.filename; - if (!filename) { - return ''; - } - if (boardID === 'f') { - filename = encodeURIComponent($.unescape(decodeURIComponent(filename))); - } else { - if (/[sm]\.jpg$/.test(filename)) { - return ''; - } - } - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/full_image/" + filename; - }, - board: function(archive, arg) { - var boardID; - boardID = arg.boardID; - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/"; - }, - search: function(archive, arg) { - var boardID, path, type, value; - boardID = arg.boardID, type = arg.type, value = arg.value; - type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; - if (type === 'capcode') { - value = $.getOwn({ - 'Developer': 'dev', - 'Verified': 'ver' - }, value) || value.toLowerCase(); - } else if (type === 'image') { - value = value.replace(/[+\/=]/g, function(c) { - return { - '+': '-', - '/': '_', - '=': '' - }[c]; - }); - } - value = encodeURIComponent(value); - path = archive.software === 'foolfuuka' ? boardID + "/search/" + type + "/" + value + "/" : type === 'image' ? boardID + "/image/" + value : boardID + "/?task=search2&search_" + type + "=" + value; - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; - }, - report: function(boardID) { - var archive, boards, domain, https, j, len, name, ref, reports, software, urls; - urls = []; - ref = Conf['archives']; - for (j = 0, len = ref.length; j < len; j++) { - archive = ref[j]; - software = archive.software, https = archive.https, reports = archive.reports, boards = archive.boards, name = archive.name, domain = archive.domain; - if (software === 'foolfuuka' && https && reports && boards instanceof Array && indexOf.call(boards, boardID) >= 0) { - urls.push([name, "https://" + domain + "/_/api/chan/offsite_report/"]); - } - } - return urls; - }, - securityCheck: function(url) { - return /^https:\/\//.test(url) || location.protocol === 'http:' || Conf['Exempt Archives from Encryption']; - }, - navigate: function(dest, data, alternative) { - var url; - if (!Redirect.data) { - Redirect.init(); - } - url = Redirect.to(dest, data); - if (url && (Redirect.securityCheck(url) || confirm("Redirect to " + url + "?\n\nYour connection will not be encrypted."))) { - return location.replace(url); - } else if (alternative) { - return location.replace(alternative); - } - } - }; - - return Redirect; - -}).call(this); - -Anonymize = (function() { - var Anonymize; - - Anonymize = { - init: function() { - if (!Conf['Anonymize']) { - return; - } - return $.addClass(doc, 'anonymize'); - } - }; - - return Anonymize; - -}).call(this); - -Filter = (function() { - var Filter, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - Filter = { - filters: $.dict(), - init: function() { - var base, base1, boards, err, excludes, file, filter, hide, hl, i, isstring, j, key, len, len1, line, mask, noti, op, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, regexp, stub, top, type, types; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'catalog') && Conf['Filter'])) { - return; - } - if (g.VIEW === 'catalog' && !Conf['Filter in Native Catalog']) { - return; - } - if (!Conf['Filtered Backlinks']) { - $.addClass(doc, 'hide-backlinks'); - } - for (key in Config.filter) { - ref1 = Conf[key].split('\n'); - for (i = 0, len = ref1.length; i < len; i++) { - line = ref1[i]; - if (line[0] === '#') { - continue; - } - if (!(regexp = line.match(/\/(.*)\/(\w*)/))) { - continue; - } - filter = line.replace(regexp[0], ''); - boards = this.parseBoards((ref2 = filter.match(/(?:^|;)\s*boards:([^;]+)/)) != null ? ref2[1] : void 0); - excludes = this.parseBoards((ref3 = filter.match(/(?:^|;)\s*exclude:([^;]+)/)) != null ? ref3[1] : void 0); - if ((isstring = (key === 'uniqueID' || key === 'MD5'))) { - regexp = regexp[1]; - } else { - try { - regexp = RegExp(regexp[1], regexp[2]); - } catch (error) { - err = error; - new Notice('warning', [$.tn("Invalid " + key + " filter:"), $.el('br'), $.tn(line), $.el('br'), $.tn(err.message)], 60); - continue; - } - } - op = ((ref4 = filter.match(/(?:^|;)\s*op:(no|only)/)) != null ? ref4[1] : void 0) || ''; - mask = $.getOwn({ - 'no': 1, - 'only': 2 - }, op) || 0; - file = ((ref5 = filter.match(/(?:^|;)\s*file:(no|only)/)) != null ? ref5[1] : void 0) || ''; - mask = mask | ($.getOwn({ - 'no': 4, - 'only': 8 - }, file) || 0); - stub = (function() { - var ref6; - switch ((ref6 = filter.match(/(?:^|;)\s*stub:(yes|no)/)) != null ? ref6[1] : void 0) { - case 'yes': - return true; - case 'no': - return false; - default: - return Conf['Stubs']; - } - })(); - noti = /(?:^|;)\s*notify/.test(filter); - if ((hl = /(?:^|;)\s*highlight/.test(filter))) { - hl = ((ref6 = filter.match(/(?:^|;)\s*highlight:([\w-]+)/)) != null ? ref6[1] : void 0) || 'filter-highlight'; - top = ((ref7 = filter.match(/(?:^|;)\s*top:(yes|no)/)) != null ? ref7[1] : void 0) || 'yes'; - top = top === 'yes'; - } - if (key === 'general') { - if ((types = filter.match(/(?:^|;)\s*type:([^;]*)/))) { - types = types[1].split(','); - } else { - types = ['subject', 'name', 'filename', 'comment']; - } - } - hide = !(hl || noti); - filter = { - isstring: isstring, - regexp: regexp, - boards: boards, - excludes: excludes, - mask: mask, - hide: hide, - stub: stub, - hl: hl, - top: top, - noti: noti - }; - if (key === 'general') { - for (j = 0, len1 = types.length; j < len1; j++) { - type = types[j]; - ((base = this.filters)[type] || (base[type] = [])).push(filter); - } - } else { - ((base1 = this.filters)[key] || (base1[key] = [])).push(filter); - } - } - } - if (!Object.keys(this.filters).length) { - return; - } - if (g.VIEW === 'catalog') { - return Filter.catalog(); - } else { - return Callbacks.Post.push({ - name: 'Filter', - cb: this.node - }); - } - }, - parseBoards: function(boardsRaw) { - var boardID, boardID2, boards, i, j, len, len1, ref, ref1, ref2, ref3, site, siteFilter, siteID; - if (!boardsRaw) { - return false; - } - if ((boards = Filter.parseBoardsMemo[boardsRaw])) { - return boards; - } - boards = $.dict(); - siteFilter = ''; - ref = boardsRaw.split(','); - for (i = 0, len = ref.length; i < len; i++) { - boardID = ref[i]; - if (indexOf.call(boardID, ':') >= 0) { - ref1 = boardID.split(':').slice(-2), siteFilter = ref1[0], boardID = ref1[1]; - } - ref2 = g.sites; - for (siteID in ref2) { - site = ref2[siteID]; - if (siteID.slice(0, siteFilter.length) === siteFilter) { - if (boardID === 'nsfw' || boardID === 'sfw') { - ref3 = (typeof site.sfwBoards === "function" ? site.sfwBoards(boardID === 'sfw') : void 0) || []; - for (j = 0, len1 = ref3.length; j < len1; j++) { - boardID2 = ref3[j]; - boards[siteID + "/" + boardID2] = true; - } - } else { - boards[siteID + "/" + (encodeURIComponent(boardID))] = true; - } - } - } - } - Filter.parseBoardsMemo[boardsRaw] = boards; - return boards; - }, - parseBoardsMemo: $.dict(), - test: function(post, hideable) { - var board, filter, hide, hl, i, j, key, len, len1, mask, noti, ref, ref1, ref2, site, stub, top, value; - if (hideable == null) { - hideable = true; - } - if (post.filterResults) { - return post.filterResults; - } - hide = false; - stub = true; - hl = void 0; - top = false; - noti = false; - if (QuoteYou.isYou(post)) { - hideable = false; - } - mask = (post.isReply ? 2 : 1); - mask = mask | (post.file ? 4 : 8); - board = post.siteID + "/" + post.boardID; - site = post.siteID + "/*"; - for (key in Filter.filters) { - ref = Filter.values(key, post); - for (i = 0, len = ref.length; i < len; i++) { - value = ref[i]; - ref1 = Filter.filters[key]; - for (j = 0, len1 = ref1.length; j < len1; j++) { - filter = ref1[j]; - if ((filter.boards && !(filter.boards[board] || filter.boards[site])) || (filter.excludes && (filter.excludes[board] || filter.excludes[site])) || (filter.mask & mask) || (filter.isstring ? filter.regexp !== value : !filter.regexp.test(value))) { - continue; - } - if (filter.hide) { - if (hideable) { - hide = true; - stub && (stub = filter.stub); - } - } else { - if (!(hl && (ref2 = filter.hl, indexOf.call(hl, ref2) >= 0))) { - (hl || (hl = [])).push(filter.hl); - } - top || (top = filter.top); - if (filter.noti) { - noti = true; - } - } - } - } - } - if (hide) { - return { - hide: hide, - stub: stub - }; - } else { - return { - hl: hl, - top: top, - noti: noti - }; - } - }, - node: function() { - var hide, hl, noti, ref, stub, top; - if (this.isClone) { - return; - } - ref = Filter.test(this, !this.isFetchedQuote && (this.isReply || g.VIEW === 'index')), hide = ref.hide, stub = ref.stub, hl = ref.hl, top = ref.top, noti = ref.noti; - if (hide) { - if (this.isReply) { - PostHiding.hide(this, stub); - } else { - ThreadHiding.hide(this.thread, stub); - } - } else { - if (hl) { - this.highlights = hl; - $.addClass.apply($, [this.nodes.root].concat(slice.call(hl))); - } - } - if (noti && Unread.posts && (this.ID > Unread.lastReadPost) && !QuoteYou.isYou(this)) { - return Unread.openNotification(this, ' triggered a notification filter'); - } - }, - catalog: function() { - var base, url; - if (!(url = typeof (base = g.SITE.urls).catalogJSON === "function" ? base.catalogJSON(g.BOARD) : void 0)) { - return; - } - Filter.catalogData = $.dict(); - $.ajax(url, { - onloadend: Filter.catalogParse - }); - return Callbacks.CatalogThreadNative.push({ - name: 'Filter', - cb: this.catalogNode - }); - }, - catalogParse: function() { - var i, item, j, len, len1, page, ref, ref1, ref2; - if ((ref = this.status) !== 200 && ref !== 404) { - new Notice('warning', "Failed to fetch catalog JSON data. " + (this.status ? "Error " + this.statusText + " (" + this.status + ")" : 'Connection Error'), 1); - return; - } - ref1 = this.response; - for (i = 0, len = ref1.length; i < len; i++) { - page = ref1[i]; - ref2 = page.threads; - for (j = 0, len1 = ref2.length; j < len1; j++) { - item = ref2[j]; - Filter.catalogData[item.no] = item; - } - } - g.BOARD.threads.forEach(function(thread) { - if (thread.catalogViewNative) { - return Filter.catalogNode.call(thread.catalogViewNative); - } - }); - }, - catalogNode: function() { - var base, hide, hl, ref, ref1, top; - if (!(this.boardID === g.BOARD.ID && Filter.catalogData[this.ID])) { - return; - } - if ((ref = QuoteYou.db) != null ? ref.get({ - siteID: g.SITE.ID, - boardID: this.boardID, - threadID: this.ID, - postID: this.ID - }) : void 0) { - return; - } - ref1 = Filter.test(g.SITE.Build.parseJSON(Filter.catalogData[this.ID], this)), hide = ref1.hide, hl = ref1.hl, top = ref1.top; - if (hide) { - return this.nodes.root.hidden = true; - } else { - if (hl) { - this.highlights = hl; - $.addClass.apply($, [this.nodes.root].concat(slice.call(hl))); - } - if (top) { - $.prepend(this.nodes.root.parentNode, this.nodes.root); - return typeof (base = g.SITE).catalogPin === "function" ? base.catalogPin(this.nodes.root) : void 0; - } - } - }, - isHidden: function(post) { - return !!Filter.test(post).hide; - }, - valueF: { - postID: function(post) { - return ["" + post.ID]; - }, - name: function(post) { - return [post.info.name]; - }, - uniqueID: function(post) { - return [post.info.uniqueID || '']; - }, - tripcode: function(post) { - return [post.info.tripcode]; - }, - capcode: function(post) { - return [post.info.capcode]; - }, - pass: function(post) { - return [post.info.pass]; - }, - email: function(post) { - return [post.info.email]; - }, - subject: function(post) { - return [post.info.subject || (post.isReply ? void 0 : '')]; - }, - comment: function(post) { - var base, ref, ref1; - return [((base = post.info).comment != null ? base.comment : base.comment = (ref = g.sites[post.siteID]) != null ? (ref1 = ref.Build) != null ? typeof ref1.parseComment === "function" ? ref1.parseComment(post.info.commentHTML.innerHTML) : void 0 : void 0 : void 0)]; - }, - flag: function(post) { - return [post.info.flag]; - }, - filename: function(post) { - return post.files.map(function(f) { - return f.name; - }); - }, - dimensions: function(post) { - return post.files.map(function(f) { - return f.dimensions; - }); - }, - filesize: function(post) { - return post.files.map(function(f) { - return f.size; - }); - }, - MD5: function(post) { - return post.files.map(function(f) { - return f.MD5; - }); - } - }, - values: function(key, post) { - if ($.hasOwn(Filter.valueF, key)) { - return Filter.valueF[key](post).filter(function(v) { - return v != null; - }); - } else { - return [ - key.split('+').map(function(k) { - var f; - if ((f = $.getOwn(Filter.valueF, k))) { - return f(post).map(function(v) { - return v || ''; - }).join('\n'); - } else { - return ''; - } - }).join('\n') - ]; - } - }, - addFilter: function(type, re, cb) { - if (!$.hasOwn(Config.filter, type)) { - return; - } - return $.get(type, Conf[type], function(item) { - var save; - save = item[type]; - save = save ? save + "\n" + re : re; - return $.set(type, save, cb); - }); - }, - removeFilters: function(type, res, cb) { - return $.get(type, Conf[type], function(item) { - var save; - save = item[type]; - res = res.map(Filter.escape).join('|'); - save = save.replace(RegExp("(?:$\n|^)(?:" + res + ")$", 'mg'), ''); - return $.set(type, save, cb); - }); - }, - showFilters: function(type) { - var section, select; - Settings.open('Filter'); - section = $('.section-container'); - select = $('select[name=filter]', section); - select.value = type; - Settings.selectFilter.call(select); - return $.onExists(section, 'textarea', function(ta) { - var tl; - tl = ta.textLength; - ta.setSelectionRange(tl, tl); - return ta.focus(); - }); - }, - quickFilterMD5: function() { - var files, filter, links, msg, notice, origin, post; - post = Get.postFromNode(this); - files = post.files.filter(function(f) { - return f.MD5; - }); - if (!files.length) { - return; - } - filter = files.map(function(f) { - return "/" + f.MD5 + "/"; - }).join('\n'); - Filter.addFilter('MD5', filter); - origin = post.origin || post; - if (origin.isReply) { - PostHiding.hide(origin); - } else if (g.VIEW === 'index') { - ThreadHiding.hide(origin.thread); - } - if (!Conf['MD5 Quick Filter Notifications']) { - if (post.nodes.post.getBoundingClientRect().height) { - new Notice('info', 'MD5 filtered.', 2); - } - return; - } - notice = Filter.quickFilterMD5.notice; - if (notice) { - notice.filters.push(filter); - notice.posts.push(origin); - return $('span', notice.el).textContent = notice.filters.length + " MD5s filtered."; - } else { - msg = $.el('div', {innerHTML: "MD5 filtered. [show] [undo]"}); - notice = Filter.quickFilterMD5.notice = new Notice('info', msg, void 0, function() { - return delete Filter.quickFilterMD5.notice; - }); - notice.filters = [filter]; - notice.posts = [origin]; - links = $$('a', msg); - $.on(links[0], 'click', Filter.quickFilterCB.show.bind(notice)); - return $.on(links[1], 'click', Filter.quickFilterCB.undo.bind(notice)); - } - }, - quickFilterCB: { - show: function() { - Filter.showFilters('MD5'); - return this.close(); - }, - undo: function() { - var i, len, post, ref; - Filter.removeFilters('MD5', this.filters); - ref = this.posts; - for (i = 0, len = ref.length; i < len; i++) { - post = ref[i]; - if (post.isReply) { - PostHiding.show(post); - } else if (g.VIEW === 'index') { - ThreadHiding.show(post.thread); - } - } - return this.close(); - } - }, - escape: function(value) { - return value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) { - if (c === '\n') { - return '\\n'; - } else if (c === '\\') { - return '\\\\'; - } else { - return "\\" + c; - } - }); - }, - menu: { - init: function() { - var div, entry, i, len, ref, ref1, type; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Filter'])) { - return; - } - div = $.el('div', { - textContent: 'Filter' - }); - entry = { - el: div, - order: 50, - open: function(post) { - Filter.menu.post = post; - return true; - }, - subEntries: [] - }; - ref1 = [['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']]; - for (i = 0, len = ref1.length; i < len; i++) { - type = ref1[i]; - entry.subEntries.push(Filter.menu.createSubEntry(type[0], type[1])); - } - return Menu.menu.addEntry(entry); - }, - createSubEntry: function(text, type) { - var el; - el = $.el('a', { - href: 'javascript:;', - textContent: text - }); - el.dataset.type = type; - $.on(el, 'click', Filter.menu.makeFilter); - return { - el: el, - open: function(post) { - return Filter.values(type, post).length; - } - }; - }, - makeFilter: function() { - var res, type, values; - type = this.dataset.type; - values = Filter.values(type, Filter.menu.post); - res = values.map(function(value) { - var re; - re = type === 'uniqueID' || type === 'MD5' ? value : Filter.escape(value); - if (type === 'uniqueID' || type === 'MD5') { - return "/" + re + "/"; - } else { - return "/^" + re + "$/"; - } - }).join('\n'); - return Filter.addFilter(type, res, function() { - return Filter.showFilters(type); - }); - } - } - }; - - return Filter; - -}).call(this); - -PostHiding = (function() { - var PostHiding; - - PostHiding = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Reply Hiding Buttons'] && !(Conf['Menu'] && Conf['Reply Hiding Link'])) { - return; - } - if (Conf['Reply Hiding Buttons']) { - $.addClass(doc, "reply-hide"); - } - this.db = new DataBoard('hiddenPosts'); - return Callbacks.Post.push({ - name: 'Reply Hiding', - cb: this.node - }); - }, - isHidden: function(boardID, threadID, postID) { - return !!(PostHiding.db && PostHiding.db.get({ - boardID: boardID, - threadID: threadID, - postID: postID - })); - }, - node: function() { - var button, data, sa, sideArrows; - if (!this.isReply || this.isClone || this.isFetchedQuote) { - return; - } - if (data = PostHiding.db.get({ - boardID: this.board.ID, - threadID: this.thread.ID, - postID: this.ID - })) { - if (data.thisPost) { - PostHiding.hide(this, data.makeStub, data.hideRecursively); - } else { - Recursive.apply(PostHiding.hide, this, data.makeStub, true); - Recursive.add(PostHiding.hide, this, data.makeStub, true); - } - } - if (!Conf['Reply Hiding Buttons']) { - return; - } - button = PostHiding.makeButton(this, 'hide'); - if ((sa = g.SITE.selectors.sideArrows)) { - sideArrows = $(sa, this.nodes.root); - $.replace(sideArrows.firstChild, button); - return sideArrows.className = 'replacedSideArrows'; - } else { - return $.prepend(this.nodes.info, button); - } - }, - menu: { - init: function() { - var apply, div, hideStubLink, makeStub, ref, replies, thisPost; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Menu'] || !Conf['Reply Hiding Link']) { - return; - } - div = $.el('div', { - className: 'hide-reply-link', - textContent: 'Hide' - }); - apply = $.el('a', { - textContent: 'Apply', - href: 'javascript:;' - }); - $.on(apply, 'click', PostHiding.menu.hide); - thisPost = UI.checkbox('thisPost', 'This post', true); - replies = UI.checkbox('replies', 'Hide replies', Conf['Recursive Hiding']); - makeStub = UI.checkbox('makeStub', 'Make stub', Conf['Stubs']); - Menu.menu.addEntry({ - el: div, - order: 20, - open: function(post) { - if (!post.isReply || post.isClone || post.isHidden) { - return false; - } - PostHiding.menu.post = post; - return true; - }, - subEntries: [ - { - el: apply - }, { - el: thisPost - }, { - el: replies - }, { - el: makeStub - } - ] - }); - div = $.el('div', { - className: 'show-reply-link', - textContent: 'Show' - }); - apply = $.el('a', { - textContent: 'Apply', - href: 'javascript:;' - }); - $.on(apply, 'click', PostHiding.menu.show); - thisPost = UI.checkbox('thisPost', 'This post', false); - replies = UI.checkbox('replies', 'Show replies', false); - hideStubLink = $.el('a', { - textContent: 'Hide stub', - href: 'javascript:;' - }); - $.on(hideStubLink, 'click', PostHiding.menu.hideStub); - Menu.menu.addEntry({ - el: div, - order: 20, - open: function(post) { - var data; - if (!post.isReply || post.isClone || !post.isHidden) { - return false; - } - if (!(data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }))) { - return false; - } - PostHiding.menu.post = post; - thisPost.firstChild.checked = post.isHidden; - replies.firstChild.checked = (data != null ? data.hideRecursively : void 0) != null ? data.hideRecursively : Conf['Recursive Hiding']; - return true; - }, - subEntries: [ - { - el: apply - }, { - el: thisPost - }, { - el: replies - } - ] - }); - return Menu.menu.addEntry({ - el: hideStubLink, - order: 15, - open: function(post) { - var data; - if (!post.isReply || post.isClone || !post.isHidden) { - return false; - } - if (!(data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }))) { - return false; - } - return PostHiding.menu.post = post; - } - }); - }, - hide: function() { - var makeStub, parent, post, replies, thisPost; - parent = this.parentNode; - thisPost = $('input[name=thisPost]', parent).checked; - replies = $('input[name=replies]', parent).checked; - makeStub = $('input[name=makeStub]', parent).checked; - post = PostHiding.menu.post; - if (thisPost) { - PostHiding.hide(post, makeStub, replies); - } else if (replies) { - Recursive.apply(PostHiding.hide, post, makeStub, true); - Recursive.add(PostHiding.hide, post, makeStub, true); - } else { - return; - } - PostHiding.saveHiddenState(post, true, thisPost, makeStub, replies); - return $.event('CloseMenu'); - }, - show: function() { - var data, parent, post, replies, thisPost; - parent = this.parentNode; - thisPost = $('input[name=thisPost]', parent).checked; - replies = $('input[name=replies]', parent).checked; - post = PostHiding.menu.post; - if (thisPost) { - PostHiding.show(post, replies); - } else if (replies) { - Recursive.apply(PostHiding.show, post, true); - Recursive.rm(PostHiding.hide, post, true); - } else { - return; - } - if (data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - })) { - PostHiding.saveHiddenState(post, !(thisPost && replies), !thisPost, data.makeStub, !replies); - } - return $.event('CloseMenu'); - }, - hideStub: function() { - var data, post; - post = PostHiding.menu.post; - if (data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - })) { - PostHiding.show(post, data.hideRecursively); - PostHiding.hide(post, false, data.hideRecursively); - PostHiding.saveHiddenState(post, true, true, false, data.hideRecursively); - } - $.event('CloseMenu'); - } - }, - makeButton: function(post, type) { - var a, span; - span = $.el('span', { - className: "fa fa-" + (type === 'hide' ? 'minus' : 'plus') + "-square-o", - textContent: "" - }); - a = $.el('a', { - className: type + "-reply-button", - href: 'javascript:;' - }); - $.add(a, span); - $.on(a, 'click', PostHiding.toggle); - return a; - }, - saveHiddenState: function(post, isHiding, thisPost, makeStub, hideRecursively) { - var data; - data = { - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }; - if (isHiding) { - data.val = { - thisPost: thisPost !== false, - makeStub: makeStub, - hideRecursively: hideRecursively - }; - return PostHiding.db.set(data); - } else { - return PostHiding.db["delete"](data); - } - }, - toggle: function() { - var post; - post = Get.postFromNode(this); - PostHiding[(post.isHidden ? 'show' : 'hide')](post); - return PostHiding.saveHiddenState(post, post.isHidden); - }, - hide: function(post, makeStub, hideRecursively) { - var a, i, len, quotelink, ref; - if (makeStub == null) { - makeStub = Conf['Stubs']; - } - if (hideRecursively == null) { - hideRecursively = Conf['Recursive Hiding']; - } - if (post.isHidden) { - return; - } - post.isHidden = true; - if (hideRecursively) { - Recursive.apply(PostHiding.hide, post, makeStub, true); - Recursive.add(PostHiding.hide, post, makeStub, true); - } - ref = Get.allQuotelinksLinkingTo(post); - for (i = 0, len = ref.length; i < len; i++) { - quotelink = ref[i]; - $.addClass(quotelink, 'filtered'); - } - if (!makeStub) { - post.nodes.root.hidden = true; - return; - } - a = PostHiding.makeButton(post, 'show'); - $.add(a, $.tn(" " + post.info.nameBlock)); - post.nodes.stub = $.el('div', { - className: 'stub' - }); - $.add(post.nodes.stub, a); - if (Conf['Menu']) { - $.add(post.nodes.stub, Menu.makeButton(post)); - } - return $.prepend(post.nodes.root, post.nodes.stub); - }, - show: function(post, showRecursively) { - var i, len, quotelink, ref; - if (showRecursively == null) { - showRecursively = Conf['Recursive Hiding']; - } - if (post.nodes.stub) { - $.rm(post.nodes.stub); - delete post.nodes.stub; - } else { - post.nodes.root.hidden = false; - } - post.isHidden = false; - if (showRecursively) { - Recursive.apply(PostHiding.show, post, true); - Recursive.rm(PostHiding.hide, post); - } - ref = Get.allQuotelinksLinkingTo(post); - for (i = 0, len = ref.length; i < len; i++) { - quotelink = ref[i]; - $.rmClass(quotelink, 'filtered'); - } - } - }; - - return PostHiding; - -}).call(this); - -Recursive = (function() { - var Recursive, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Recursive = { - recursives: $.dict(), - init: function() { - var ref; - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - return Callbacks.Post.push({ - name: 'Recursive', - cb: this.node - }); - }, - node: function() { - var i, j, k, len, len1, obj, quote, recursive, ref, ref1; - if (this.isClone || this.isFetchedQuote) { - return; - } - ref = this.quotes; - for (j = 0, len = ref.length; j < len; j++) { - quote = ref[j]; - if (obj = Recursive.recursives[quote]) { - ref1 = obj.recursives; - for (i = k = 0, len1 = ref1.length; k < len1; i = ++k) { - recursive = ref1[i]; - recursive.apply(null, [this].concat(slice.call(obj.args[i]))); - } - } - } - }, - add: function() { - var args, base, name, obj, post, recursive; - recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; - obj = (base = Recursive.recursives)[name = post.fullID] || (base[name] = { - recursives: [], - args: [] - }); - obj.recursives.push(recursive); - return obj.args.push(args); - }, - rm: function(recursive, post) { - var i, j, len, obj, rec, ref; - if (!(obj = Recursive.recursives[post.fullID])) { - return; - } - ref = obj.recursives; - for (i = j = 0, len = ref.length; j < len; i = ++j) { - rec = ref[i]; - if (!(rec === recursive)) { - continue; - } - obj.recursives.splice(i, 1); - obj.args.splice(i, 1); - } - }, - apply: function() { - var args, fullID, post, recursive; - recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; - fullID = post.fullID; - return g.posts.forEach(function(post) { - if (indexOf.call(post.quotes, fullID) >= 0) { - return recursive.apply(null, [post].concat(slice.call(args))); - } - }); - } - }; - - return Recursive; - -}).call(this); - -ThreadHiding = (function() { - var ThreadHiding; - - ThreadHiding = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'catalog') || !Conf['Thread Hiding Buttons'] && !(Conf['Menu'] && Conf['Thread Hiding Link']) && !Conf['JSON Index']) { - return; - } - this.db = new DataBoard('hiddenThreads'); - if (g.VIEW === 'catalog') { - return this.catalogWatch(); - } - this.catalogSet(g.BOARD); - $.on(d, 'IndexRefreshInternal', this.onIndexRefresh); - if (Conf['Thread Hiding Buttons']) { - $.addClass(doc, 'thread-hide'); - } - return Callbacks.Post.push({ - name: 'Thread Hiding', - cb: this.node - }); - }, - catalogSet: function(board) { - var hiddenThreads, threadID; - if (!($.hasStorage && g.SITE.software === 'yotsuba')) { - return; - } - hiddenThreads = ThreadHiding.db.get({ - boardID: board.ID, - defaultValue: $.dict() - }); - for (threadID in hiddenThreads) { - hiddenThreads[threadID] = true; - } - return localStorage.setItem("4chan-hide-t-" + board, JSON.stringify(hiddenThreads)); - }, - catalogWatch: function() { - if (!($.hasStorage && g.SITE.software === 'yotsuba')) { - return; - } - this.hiddenThreads = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; - return Main.ready(function() { - return new MutationObserver(ThreadHiding.catalogSave).observe($.id('threads'), { - attributes: true, - subtree: true, - attributeFilter: ['style'] - }); - }); - }, - catalogSave: function() { - var hiddenThreads2, threadID; - hiddenThreads2 = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; - for (threadID in hiddenThreads2) { - if (!$.hasOwn(ThreadHiding.hiddenThreads, threadID)) { - ThreadHiding.db.set({ - boardID: g.BOARD.ID, - threadID: threadID, - val: { - makeStub: Conf['Stubs'] - } - }); - } - } - for (threadID in ThreadHiding.hiddenThreads) { - if (!$.hasOwn(hiddenThreads2, threadID)) { - ThreadHiding.db["delete"]({ - boardID: g.BOARD.ID, - threadID: threadID - }); - } - } - return ThreadHiding.hiddenThreads = hiddenThreads2; - }, - isHidden: function(boardID, threadID) { - return !!(ThreadHiding.db && ThreadHiding.db.get({ - boardID: boardID, - threadID: threadID - })); - }, - node: function() { - var data; - if (this.isReply || this.isClone || this.isFetchedQuote) { - return; - } - if (Conf['Thread Hiding Buttons']) { - $.prepend(this.nodes.root, ThreadHiding.makeButton(this.thread, 'hide')); - } - if (data = ThreadHiding.db.get({ - boardID: this.board.ID, - threadID: this.ID - })) { - return ThreadHiding.hide(this.thread, data.makeStub); - } - }, - onIndexRefresh: function() { - return g.BOARD.threads.forEach(function(thread) { - var root; - root = thread.nodes.root; - if (thread.isHidden && thread.stub && !root.contains(thread.stub)) { - return ThreadHiding.makeStub(thread, root); - } - }); - }, - menu: { - init: function() { - var apply, div, hideStubLink, makeStub; - if (g.VIEW !== 'index' || !Conf['Menu'] || !Conf['Thread Hiding Link']) { - return; - } - div = $.el('div', { - className: 'hide-thread-link', - textContent: 'Hide' - }); - apply = $.el('a', { - textContent: 'Apply', - href: 'javascript:;' - }); - $.on(apply, 'click', ThreadHiding.menu.hide); - makeStub = UI.checkbox('Stubs', 'Make stub'); - Menu.menu.addEntry({ - el: div, - order: 20, - open: function(arg) { - var isReply, thread; - thread = arg.thread, isReply = arg.isReply; - if (isReply || thread.isHidden || Conf['JSON Index'] && Conf['Index Mode'] === 'catalog') { - return false; - } - ThreadHiding.menu.thread = thread; - return true; - }, - subEntries: [ - { - el: apply - }, { - el: makeStub - } - ] - }); - div = $.el('a', { - className: 'show-thread-link', - textContent: 'Show', - href: 'javascript:;' - }); - $.on(div, 'click', ThreadHiding.menu.show); - Menu.menu.addEntry({ - el: div, - order: 20, - open: function(arg) { - var isReply, thread; - thread = arg.thread, isReply = arg.isReply; - if (isReply || !thread.isHidden || Conf['JSON Index'] && Conf['Index Mode'] === 'catalog') { - return false; - } - ThreadHiding.menu.thread = thread; - return true; - } - }); - hideStubLink = $.el('a', { - textContent: 'Hide stub', - href: 'javascript:;' - }); - $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); - return Menu.menu.addEntry({ - el: hideStubLink, - order: 15, - open: function(arg) { - var isReply, thread; - thread = arg.thread, isReply = arg.isReply; - if (isReply || !thread.isHidden || Conf['JSON Index'] && Conf['Index Mode'] === 'catalog') { - return false; - } - return ThreadHiding.menu.thread = thread; - } - }); - }, - hide: function() { - var makeStub, thread; - makeStub = $('input', this.parentNode).checked; - thread = ThreadHiding.menu.thread; - ThreadHiding.hide(thread, makeStub); - ThreadHiding.saveHiddenState(thread, makeStub); - return $.event('CloseMenu'); - }, - show: function() { - var thread; - thread = ThreadHiding.menu.thread; - ThreadHiding.show(thread); - ThreadHiding.saveHiddenState(thread); - return $.event('CloseMenu'); - }, - hideStub: function() { - var thread; - thread = ThreadHiding.menu.thread; - ThreadHiding.show(thread); - ThreadHiding.hide(thread, false); - ThreadHiding.saveHiddenState(thread, false); - $.event('CloseMenu'); - } - }, - makeButton: function(thread, type) { - var a; - a = $.el('a', { - className: type + "-thread-button", - href: 'javascript:;' - }); - $.extend(a, {innerHTML: ""}); - a.dataset.fullID = thread.fullID; - $.on(a, 'click', ThreadHiding.toggle); - return a; - }, - makeStub: function(thread, root) { - var a, numReplies, summary, threadDivider; - numReplies = $$(g.SITE.selectors.replyOriginal, root).length; - if (summary = $(g.SITE.selectors.summary, root)) { - numReplies += +summary.textContent.match(/\d+/); - } - a = ThreadHiding.makeButton(thread, 'show'); - $.add(a, $.tn(" " + thread.OP.info.nameBlock + " (" + (numReplies === 1 ? '1 reply' : numReplies + " replies") + ")")); - thread.stub = $.el('div', { - className: 'stub' - }); - if (Conf['Menu']) { - $.add(thread.stub, [a, Menu.makeButton(thread.OP)]); - } else { - $.add(thread.stub, a); - } - $.prepend(root, thread.stub); - if ((threadDivider = $(g.SITE.selectors.threadDivider, root))) { - return $.addClass(threadDivider, 'threadDivider'); - } - }, - saveHiddenState: function(thread, makeStub) { - if (thread.isHidden) { - ThreadHiding.db.set({ - boardID: thread.board.ID, - threadID: thread.ID, - val: { - makeStub: makeStub - } - }); - } else { - ThreadHiding.db["delete"]({ - boardID: thread.board.ID, - threadID: thread.ID - }); - } - return ThreadHiding.catalogSet(thread.board); - }, - toggle: function(thread) { - if (!(thread instanceof Thread)) { - thread = g.threads.get(this.dataset.fullID); - } - if (thread.isHidden) { - ThreadHiding.show(thread); - } else { - ThreadHiding.hide(thread); - } - return ThreadHiding.saveHiddenState(thread); - }, - hide: function(thread, makeStub) { - var threadRoot; - if (makeStub == null) { - makeStub = Conf['Stubs']; - } - if (thread.isHidden) { - return; - } - threadRoot = thread.nodes.root; - thread.isHidden = true; - Index.updateHideLabel(); - if (thread.catalogView && !Index.showHiddenThreads) { - $.rm(thread.catalogView.nodes.root); - $.event('PostsRemoved', null, Index.root); - } - if (!makeStub) { - return threadRoot.hidden = true; - } - return ThreadHiding.makeStub(thread, threadRoot); - }, - show: function(thread) { - var threadRoot; - if (thread.stub) { - $.rm(thread.stub); - delete thread.stub; - } - threadRoot = thread.nodes.root; - threadRoot.hidden = thread.isHidden = false; - Index.updateHideLabel(); - if (thread.catalogView && Index.showHiddenThreads) { - $.rm(thread.catalogView.nodes.root); - return $.event('PostsRemoved', null, Index.root); - } - } - }; - - return ThreadHiding; - -}).call(this); - -BoardConfig = (function() { - var BoardConfig; - - BoardConfig = { - cbs: [], - init: function() { - var boards, now, ref; - if (g.SITE.software !== 'yotsuba') { - return; - } - now = Date.now(); - if (!((now - 2 * $.HOUR < (ref = Conf['boardConfig'].lastChecked || 0) && ref <= now))) { - return $.ajax(location.protocol + "//a.4cdn.org/boards.json", { - onloadend: this.load - }); - } else { - boards = Conf['boardConfig'].boards; - return this.set(boards); - } - }, - load: function() { - var board, boards, err, i, len, ref; - if (this.status === 200 && this.response && this.response.boards) { - boards = $.dict(); - ref = this.response.boards; - for (i = 0, len = ref.length; i < len; i++) { - board = ref[i]; - boards[board.board] = board; - } - $.set('boardConfig', { - boards: boards, - lastChecked: Date.now() - }); - } else { - boards = Conf['boardConfig'].boards; - err = (function() { - switch (this.status) { - case 0: - return 'Connection Error'; - case 200: - return 'Invalid Data'; - default: - return "Error " + this.statusText + " (" + this.status + ")"; - } - }).call(this); - new Notice('warning', "Failed to load board configuration. " + err, 20); - } - return BoardConfig.set(boards); - }, - set: function(boards1) { - var ID, board, cb, i, len, ref, ref1; - this.boards = boards1; - ref = g.boards; - for (ID in ref) { - board = ref[ID]; - board.config = this.boards[ID] || {}; - } - ref1 = this.cbs; - for (i = 0, len = ref1.length; i < len; i++) { - cb = ref1[i]; - $.queueTask(cb); - } - }, - ready: function(cb) { - if (this.boards) { - return cb(); - } else { - return this.cbs.push(cb); - } - }, - sfwBoards: function(sfw) { - var board, data, ref, results; - ref = this.boards || Conf['boardConfig'].boards; - results = []; - for (board in ref) { - data = ref[board]; - if (!!data.ws_board === sfw) { - results.push(board); - } - } - return results; - }, - isSFW: function(board) { - var ref; - return !!((ref = (this.boards || Conf['boardConfig'].boards)[board]) != null ? ref.ws_board : void 0); - }, - domain: function(board) { - return "boards." + (BoardConfig.isSFW(board) ? '4channel' : '4chan') + ".org"; - }, - isArchived: function(board) { - var data; - data = (this.boards || Conf['boardConfig'].boards)[board]; - return !data || data.is_archived; - }, - noAudio: function(boardID) { - var boards; - if (g.SITE.software !== 'yotsuba') { - return false; - } - boards = this.boards || Conf['boardConfig'].boards; - return boards && boards[boardID] && !boards[boardID].webm_audio; - }, - title: function(boardID) { - var ref, ref1; - return ((ref = this.boards || Conf['boardConfig'].boards) != null ? (ref1 = ref[boardID]) != null ? ref1.title : void 0 : void 0) || ''; - } - }; - - return BoardConfig; - -}).call(this); - -Get = (function() { - var Get, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Get = { - url: function() { - var IDs, args, f, site, type; - type = arguments[0], IDs = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; - if ((site = g.sites[IDs.siteID]) && (f = $.getOwn(site.urls, type))) { - return f.apply(null, [IDs].concat(slice.call(args))); - } else { - return void 0; - } - }, - threadExcerpt: function(thread) { - var OP, excerpt, ref, ref1; - OP = thread.OP; - excerpt = ("/" + (decodeURIComponent(thread.board.ID)) + "/ - ") + (((ref = OP.info.subject) != null ? ref.trim() : void 0) || OP.commentDisplay().replace(/\n+/g, ' // ') || ((ref1 = OP.file) != null ? ref1.name : void 0) || ("No." + OP)); - if (excerpt.length > 73) { - return excerpt.slice(0, 70) + "..."; - } - return excerpt; - }, - threadFromRoot: function(root) { - var board; - if (root == null) { - return null; - } - board = root.dataset.board; - return g.threads.get((board ? encodeURIComponent(board) : g.BOARD.ID) + "." + (root.id.match(/\d*$/)[0])); - }, - threadFromNode: function(node) { - return Get.threadFromRoot($.x("ancestor-or-self::" + g.SITE.xpath.thread, node)); - }, - postFromRoot: function(root) { - var index, post; - if (root == null) { - return null; - } - post = g.posts.get(root.dataset.fullID); - index = root.dataset.clone; - if (index) { - return post.clones[+index]; - } else { - return post; - } - }, - postFromNode: function(root) { - return Get.postFromRoot($.x("ancestor-or-self::" + g.SITE.xpath.postContainer + "[1]", root)); - }, - postDataFromLink: function(link) { - var boardID, match, postID, ref, ref1, threadID; - if (link.dataset.postID) { - ref = link.dataset, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - threadID || (threadID = 0); - } else { - match = link.href.match(g.SITE.regexp.quotelink); - ref1 = match.slice(1), boardID = ref1[0], threadID = ref1[1], postID = ref1[2]; - postID || (postID = threadID); - } - return { - boardID: boardID, - threadID: +threadID, - postID: +postID - }; - }, - allQuotelinksLinkingTo: function(post) { - var fullID, handleQuotes, i, len, posts, qPost, quote, quotelinks, ref; - quotelinks = []; - posts = g.posts; - fullID = post.fullID; - handleQuotes = function(qPost, type) { - var clone, i, len, ref; - quotelinks.push.apply(quotelinks, qPost.nodes[type]); - ref = qPost.clones; - for (i = 0, len = ref.length; i < len; i++) { - clone = ref[i]; - quotelinks.push.apply(quotelinks, clone.nodes[type]); - } - }; - posts.forEach(function(qPost) { - if (indexOf.call(qPost.quotes, fullID) >= 0) { - return handleQuotes(qPost, 'quotelinks'); - } - }); - if (Conf['Quote Backlinks']) { - ref = post.quotes; - for (i = 0, len = ref.length; i < len; i++) { - quote = ref[i]; - if (qPost = posts.get(quote)) { - handleQuotes(qPost, 'backlinks'); - } - } - } - return quotelinks.filter(function(quotelink) { - var boardID, postID, ref1; - ref1 = Get.postDataFromLink(quotelink), boardID = ref1.boardID, postID = ref1.postID; - return boardID === post.board.ID && postID === post.ID; - }); - } - }; - - return Get; - -}).call(this); - -Header = (function() { - var Header, - slice = [].slice; - - Header = { - init: function() { - var barFixedToggler, barPositionToggler, box, cs, customNavToggler, editCustomNav, footerToggler, headerToggler, linkJustifyToggler, menuButton, scrollHeaderToggler, shortcutToggler; - $.onExists(doc, 'body', (function(_this) { - return function() { - if (!Main.isThisPageLegit()) { - return; - } - $.add(_this.bar, [_this.noticesRoot, _this.toggle]); - $.prepend(d.body, _this.bar); - $.add(d.body, Header.hover); - return _this.setBarPosition(Conf['Bottom Header']); - }; - })(this)); - this.menu = new UI.Menu('header'); - menuButton = $.el('span', { - className: 'menu-button' - }); - $.extend(menuButton, {innerHTML: ""}); - box = UI.checkbox; - barFixedToggler = box('Fixed Header', 'Fixed Header'); - headerToggler = box('Header auto-hide', 'Auto-hide header'); - scrollHeaderToggler = box('Header auto-hide on scroll', 'Auto-hide header on scroll'); - barPositionToggler = box('Bottom Header', 'Bottom header'); - linkJustifyToggler = box('Centered links', 'Centered links'); - customNavToggler = box('Custom Board Navigation', 'Custom board navigation'); - footerToggler = box('Bottom Board List', 'Hide bottom board list'); - shortcutToggler = box('Shortcut Icons', 'Shortcut Icons'); - editCustomNav = $.el('a', { - textContent: 'Edit custom board navigation', - href: 'javascript:;' - }); - this.barFixedToggler = barFixedToggler.firstElementChild; - this.scrollHeaderToggler = scrollHeaderToggler.firstElementChild; - this.barPositionToggler = barPositionToggler.firstElementChild; - this.linkJustifyToggler = linkJustifyToggler.firstElementChild; - this.headerToggler = headerToggler.firstElementChild; - this.footerToggler = footerToggler.firstElementChild; - this.shortcutToggler = shortcutToggler.firstElementChild; - this.customNavToggler = customNavToggler.firstElementChild; - $.on(menuButton, 'click', this.menuToggle); - $.on(this.headerToggler, 'change', this.toggleBarVisibility); - $.on(this.barFixedToggler, 'change', this.toggleBarFixed); - $.on(this.barPositionToggler, 'change', this.toggleBarPosition); - $.on(this.scrollHeaderToggler, 'change', this.toggleHideBarOnScroll); - $.on(this.linkJustifyToggler, 'change', this.toggleLinkJustify); - $.on(this.footerToggler, 'change', this.toggleFooterVisibility); - $.on(this.shortcutToggler, 'change', this.toggleShortcutIcons); - $.on(this.customNavToggler, 'change', this.toggleCustomNav); - $.on(editCustomNav, 'click', this.editCustomNav); - this.setBarFixed(Conf['Fixed Header']); - this.setHideBarOnScroll(Conf['Header auto-hide on scroll']); - this.setBarVisibility(Conf['Header auto-hide']); - this.setLinkJustify(Conf['Centered links']); - this.setShortcutIcons(Conf['Shortcut Icons']); - this.setFooterVisibility(Conf['Bottom Board List']); - $.sync('Fixed Header', this.setBarFixed); - $.sync('Header auto-hide on scroll', this.setHideBarOnScroll); - $.sync('Bottom Header', this.setBarPosition); - $.sync('Shortcut Icons', this.setShortcutIcons); - $.sync('Header auto-hide', this.setBarVisibility); - $.sync('Centered links', this.setLinkJustify); - $.sync('Bottom Board List', this.setFooterVisibility); - this.addShortcut('menu', menuButton, 900); - this.menu.addEntry({ - el: $.el('span', { - textContent: 'Header' - }), - order: 107, - subEntries: [ - { - el: barFixedToggler - }, { - el: headerToggler - }, { - el: scrollHeaderToggler - }, { - el: barPositionToggler - }, { - el: linkJustifyToggler - }, { - el: footerToggler - }, { - el: shortcutToggler - }, { - el: customNavToggler - }, { - el: editCustomNav - } - ] - }); - $.on(window, 'load popstate', Header.hashScroll); - $.on(d, 'CreateNotification', this.createNotification); - this.setBoardList(); - $.onExists(doc, g.SITE.selectors.boardList + " + *", Header.generateFullBoardList); - Main.ready(function() { - var a, absbot, footer, i, len, ref; - if (g.SITE.software === 'yotsuba' && !(footer = $.id('boardNavDesktopFoot'))) { - if (!(absbot = $.id('absbot'))) { - return; - } - footer = $.id('boardNavDesktop').cloneNode(true); - footer.id = 'boardNavDesktopFoot'; - $('#navtopright', footer).id = 'navbotright'; - $('#settingsWindowLink', footer).id = 'settingsWindowLinkBot'; - $.before(absbot, footer); - $.global(function() { - return window.cloneTopNav = function() {}; - }); - } - if ((Header.bottomBoardList = $(g.SITE.selectors.boardListBottom))) { - ref = $$('a', Header.bottomBoardList); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - if (a.hostname === location.hostname && a.pathname.split('/')[1] === g.BOARD.ID) { - a.className = 'current'; - } - } - return CatalogLinks.setLinks(Header.bottomBoardList); - } - }); - if (g.SITE.software === 'yotsuba' && (g.VIEW === 'catalog' || !Conf['Disable Native Extension'])) { - cs = $.el('a', { - href: 'javascript:;' - }); - if (g.VIEW === 'catalog') { - cs.title = cs.textContent = 'Catalog Settings'; - cs.className = 'fa fa-book'; - } else { - cs.title = cs.textContent = '4chan Settings'; - cs.className = 'native-settings'; - } - $.on(cs, 'click', function() { - return $.id('settingsWindowLink').click(); - }); - this.addShortcut('native', cs, 810); - } - return this.enableDesktopNotifications(); - }, - bar: $.el('div', { - id: 'header-bar' - }), - noticesRoot: $.el('div', { - id: 'notifications' - }), - shortcuts: $.el('span', { - id: 'shortcuts' - }), - hover: $.el('div', { - id: 'hoverUI' - }), - toggle: $.el('div', { - id: 'scroll-marker' - }), - setBoardList: function() { - var boardList, btn; - Header.boardList = boardList = $.el('span', { - id: 'board-list' - }); - $.extend(boardList, {innerHTML: ""}); - btn = $('.hide-board-list-button', boardList); - $.on(btn, 'click', Header.toggleBoardList); - $.prepend(Header.bar, [Header.boardList, Header.shortcuts]); - Header.setCustomNav(Conf['Custom Board Navigation']); - Header.generateBoardList(Conf['boardnav']); - $.sync('Custom Board Navigation', Header.setCustomNav); - return $.sync('boardnav', Header.generateBoardList); - }, - generateFullBoardList: function() { - var a, fullBoardList, i, len, nodes, ref; - if (g.SITE.transformBoardList) { - nodes = g.SITE.transformBoardList(); - } else { - nodes = slice.call($(g.SITE.selectors.boardList).cloneNode(true).childNodes); - } - fullBoardList = $('.boardList', Header.boardList); - $.add(fullBoardList, nodes); - ref = $$('a', fullBoardList); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - if (a.hostname === location.hostname && a.pathname.split('/')[1] === g.BOARD.ID) { - a.className = 'current'; - } - } - return CatalogLinks.setLinks(fullBoardList); - }, - generateBoardList: function(boardnav) { - var list, nodes, re, t; - list = $('#custom-board-list', Header.boardList); - $.rmAll(list); - if (!boardnav) { - return; - } - boardnav = boardnav.replace(/(\r\n|\n|\r)/g, ' '); - re = /[\w@]+(-(all|title|replace|full|index|catalog|archive|expired|nt|(mode|sort|text):"[^"]+"(,"[^"]+")?))*|[^\w@]+/g; - nodes = (function() { - var i, len, ref, results; - ref = boardnav.match(re); - results = []; - for (i = 0, len = ref.length; i < len; i++) { - t = ref[i]; - results.push(Header.mapCustomNavigation(t)); - } - return results; - })(); - $.add(list, nodes); - return CatalogLinks.setLinks(list); - }, - mapCustomNavigation: function(t) { - var a, boardID, href, indexOptions, m, ref, ref1, text, url, urlIC; - if (/^[^\w@]/.test(t)) { - return $.tn(t); - } - text = url = null; - t = t.replace(/-text:"([^"]+)"(?:,"([^"]+)")?/g, function(m0, m1, m2) { - text = m1; - url = m2; - return ''; - }); - indexOptions = []; - t = t.replace(/-(?:mode|sort):"([^"]+)"/g, function(m0, m1) { - indexOptions.push(m1.toLowerCase().replace(/\ /g, '-')); - return ''; - }); - indexOptions = indexOptions.join('/'); - if (/^toggle-all/.test(t)) { - a = $.el('a', { - className: 'show-board-list-button', - textContent: text || '+', - href: 'javascript:;' - }); - $.on(a, 'click', Header.toggleBoardList); - return a; - } - if (/^external/.test(t)) { - a = $.el('a', { - href: url || 'javascript:;', - textContent: text || '+', - className: 'external' - }); - if (/-nt/.test(t)) { - a.target = '_blank'; - a.rel = 'noopener'; - } - return a; - } - boardID = t.split('-')[0]; - if (boardID === 'current') { - if ((ref = location.hostname) === 'boards.4chan.org' || ref === 'boards.4channel.org') { - boardID = g.BOARD.ID; - } else { - a = $.el('a', { - href: "/" + g.BOARD.ID + "/", - textContent: text || decodeURIComponent(g.BOARD.ID), - className: 'current' - }); - if (/-nt/.test(t)) { - a.target = '_blank'; - a.rel = 'noopener'; - } - if (/-index/.test(t)) { - a.dataset.only = 'index'; - } else if (/-catalog/.test(t)) { - a.dataset.only = 'catalog'; - a.href += 'catalog.html'; - } else if (/-(archive|expired)/.test(t)) { - a = a.firstChild; - } - return a; - } - } - a = (function() { - var ref1, urlV; - if (boardID === '@') { - return $.el('a', { - href: 'https://twitter.com/4chan', - title: '4chan Twitter', - textContent: '@' - }); - } - a = $.el('a', { - href: "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/", - textContent: boardID, - title: BoardConfig.title(boardID) - }); - if (((ref1 = g.VIEW) === 'catalog' || ref1 === 'archive') && (urlV = Get.url(g.VIEW, { - siteID: '4chan.org', - boardID: boardID - }))) { - a.href = urlV; - } - if (a.hostname === location.hostname && boardID === g.BOARD.ID) { - a.className = 'current'; - } - return a; - })(); - a.textContent = /-title/.test(t) || /-replace/.test(t) && a.hostname === location.hostname && boardID === g.BOARD.ID ? a.title || a.textContent : /-full/.test(t) ? ("/" + boardID + "/") + (a.title ? " - " + a.title : '') : text || boardID; - if (m = t.match(/-(index|catalog)/)) { - urlIC = CatalogLinks[m[1]]({ - siteID: '4chan.org', - boardID: boardID - }); - if (urlIC) { - a.dataset.only = m[1]; - a.href = urlIC; - if (m[1] === 'catalog') { - $.addClass(a, 'catalog'); - } - } else { - return a.firstChild; - } - } - if (Conf['JSON Index'] && indexOptions) { - a.dataset.indexOptions = indexOptions; - if (((ref1 = a.hostname) === 'boards.4chan.org' || ref1 === 'boards.4channel.org') && a.pathname.split('/')[2] === '') { - a.href += (a.hash ? '/' : '#') + indexOptions; - } - } - if (/-archive/.test(t)) { - if (href = Redirect.to('board', { - boardID: boardID - })) { - a.href = href; - } else { - return a.firstChild; - } - } - if (/-expired/.test(t)) { - if (BoardConfig.isArchived(boardID)) { - a.href = "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/archive"; - } else { - return a.firstChild; - } - } - if (/-nt/.test(t)) { - a.target = '_blank'; - a.rel = 'noopener'; - } - if (boardID === '@') { - $.addClass(a, 'navSmall'); - } - return a; - }, - toggleBoardList: function() { - var bar, custom, full, showBoardList; - bar = Header.bar; - custom = $('#custom-board-list', bar); - full = $('#full-board-list', bar); - showBoardList = !full.hidden; - custom.hidden = !showBoardList; - return full.hidden = showBoardList; - }, - setLinkJustify: function(centered) { - Header.linkJustifyToggler.checked = centered; - if (centered) { - return $.addClass(doc, 'centered-links'); - } else { - return $.rmClass(doc, 'centered-links'); - } - }, - toggleLinkJustify: function() { - var centered; - $.event('CloseMenu'); - centered = this.nodeName === 'INPUT' ? this.checked : void 0; - Header.setLinkJustify(centered); - return $.set('Centered links', centered); - }, - setBarFixed: function(fixed) { - Header.barFixedToggler.checked = fixed; - if (fixed) { - $.addClass(doc, 'fixed'); - return $.addClass(Header.bar, 'dialog'); - } else { - $.rmClass(doc, 'fixed'); - return $.rmClass(Header.bar, 'dialog'); - } - }, - toggleBarFixed: function() { - $.event('CloseMenu'); - Header.setBarFixed(this.checked); - Conf['Fixed Header'] = this.checked; - return $.set('Fixed Header', this.checked); - }, - setShortcutIcons: function(show) { - Header.shortcutToggler.checked = show; - if (show) { - return $.addClass(doc, 'shortcut-icons'); - } else { - return $.rmClass(doc, 'shortcut-icons'); - } - }, - toggleShortcutIcons: function() { - $.event('CloseMenu'); - Header.setShortcutIcons(this.checked); - Conf['Shortcut Icons'] = this.checked; - return $.set('Shortcut Icons', this.checked); - }, - setBarVisibility: function(hide) { - Header.headerToggler.checked = hide; - $.event('CloseMenu'); - (hide ? $.addClass : $.rmClass)(Header.bar, 'autohide'); - return (hide ? $.addClass : $.rmClass)(doc, 'autohide'); - }, - toggleBarVisibility: function() { - var hide, message; - hide = this.nodeName === 'INPUT' ? this.checked : !$.hasClass(Header.bar, 'autohide'); - Conf['Header auto-hide'] = hide; - $.set('Header auto-hide', hide); - Header.setBarVisibility(hide); - message = "The header bar will " + (hide ? 'automatically hide itself.' : 'remain visible.'); - return new Notice('info', message, 2); - }, - setHideBarOnScroll: function(hide) { - Header.scrollHeaderToggler.checked = hide; - if (hide) { - $.on(window, 'scroll', Header.hideBarOnScroll); - return; - } - $.off(window, 'scroll', Header.hideBarOnScroll); - $.rmClass(Header.bar, 'scroll'); - return Header.bar.classList.toggle('autohide', Conf['Header auto-hide']); - }, - toggleHideBarOnScroll: function() { - var hide; - hide = this.checked; - $.cb.checked.call(this); - return Header.setHideBarOnScroll(hide); - }, - hideBarOnScroll: function() { - var offsetY; - offsetY = window.pageYOffset; - if (offsetY > (Header.previousOffset || 0)) { - $.addClass(Header.bar, 'autohide', 'scroll'); - } else { - $.rmClass(Header.bar, 'autohide', 'scroll'); - } - return Header.previousOffset = offsetY; - }, - setBarPosition: function(bottom) { - var args, ref; - if ((ref = Header.barPositionToggler) != null) { - ref.checked = bottom; - } - $.event('CloseMenu'); - args = bottom ? ['bottom-header', 'top-header', 'after'] : ['top-header', 'bottom-header', 'add']; - $.addClass(doc, args[0]); - $.rmClass(doc, args[1]); - return $[args[2]](Header.bar, Header.noticesRoot); - }, - toggleBarPosition: function() { - $.cb.checked.call(this); - return Header.setBarPosition(this.checked); - }, - setFooterVisibility: function(hide) { - Header.footerToggler.checked = hide; - return doc.classList.toggle('hide-bottom-board-list', hide); - }, - toggleFooterVisibility: function() { - var hide, message; - $.event('CloseMenu'); - hide = this.nodeName === 'INPUT' ? this.checked : $.hasClass(doc, 'hide-bottom-board-list'); - Header.setFooterVisibility(hide); - $.set('Bottom Board List', hide); - message = hide ? 'The bottom navigation will now be hidden.' : 'The bottom navigation will remain visible.'; - return new Notice('info', message, 2); - }, - setCustomNav: function(show) { - var btn, cust, full, ref; - Header.customNavToggler.checked = show; - cust = $('#custom-board-list', Header.bar); - full = $('#full-board-list', Header.bar); - btn = $('.hide-board-list-container', full); - return ref = show ? [false, true, false] : [true, false, true], cust.hidden = ref[0], full.hidden = ref[1], btn.hidden = ref[2], ref; - }, - toggleCustomNav: function() { - $.cb.checked.call(this); - return Header.setCustomNav(this.checked); - }, - editCustomNav: function() { - var settings; - Settings.open('Advanced'); - settings = $.id('fourchanx-settings'); - return $('[name=boardnav]', settings).focus(); - }, - hashScroll: function(e) { - var el, hash; - if (e) { - if (e.state) { - return; - } - if (!history.state) { - history.replaceState({}, ''); - } - } - if ((hash = location.hash.slice(1))) { - ReplyPruning.showIfHidden(hash); - if ((el = $.id(hash))) { - return $.queueTask(function() { - return Header.scrollTo(el); - }); - } - } - }, - scrollTo: function(root, down, needed) { - var height, x; - if (!root.offsetParent) { - return; - } - if (down) { - x = Header.getBottomOf(root); - if (Conf['Fixed Header'] && Conf['Header auto-hide on scroll'] && Conf['Bottom header']) { - height = Header.bar.getBoundingClientRect().height; - if (x <= 0) { - if (!Header.isHidden()) { - x += height; - } - } else { - if (Header.isHidden()) { - x -= height; - } - } - } - if (!(needed && x >= 0)) { - return window.scrollBy(0, -x); - } - } else { - x = Header.getTopOf(root); - if (Conf['Fixed Header'] && Conf['Header auto-hide on scroll'] && !Conf['Bottom header']) { - height = Header.bar.getBoundingClientRect().height; - if (x >= 0) { - if (!Header.isHidden()) { - x += height; - } - } else { - if (Header.isHidden()) { - x -= height; - } - } - } - if (!(needed && x >= 0)) { - return window.scrollBy(0, x); - } - } - }, - scrollToIfNeeded: function(root, down) { - return Header.scrollTo(root, down, true); - }, - getTopOf: function(root) { - var headRect, top; - top = root.getBoundingClientRect().top; - if (Conf['Fixed Header'] && !Conf['Bottom Header']) { - headRect = Header.toggle.getBoundingClientRect(); - top -= headRect.top + headRect.height; - } - return top; - }, - getBottomOf: function(root) { - var bottom, clientHeight, headRect; - clientHeight = doc.clientHeight; - bottom = clientHeight - root.getBoundingClientRect().bottom; - if (Conf['Fixed Header'] && Conf['Bottom Header']) { - headRect = Header.toggle.getBoundingClientRect(); - bottom -= clientHeight - headRect.bottom + headRect.height; - } - return bottom; - }, - isNodeVisible: function(node) { - var height; - if (d.hidden || !doc.contains(node)) { - return false; - } - height = node.getBoundingClientRect().height; - return Header.getTopOf(node) + height >= 0 && Header.getBottomOf(node) + height >= 0; - }, - isHidden: function() { - var top; - top = Header.bar.getBoundingClientRect().top; - if (Conf['Bottom header']) { - return top === doc.clientHeight; - } else { - return top < 0; - } - }, - addShortcut: function(id, el, index) { - var i, item, len, ref, shortcut; - shortcut = $.el('span', { - id: "shortcut-" + id, - className: 'shortcut brackets-wrap' - }); - $.add(shortcut, el); - shortcut.dataset.index = index; - ref = $$('[data-index]', Header.shortcuts); - for (i = 0, len = ref.length; i < len; i++) { - item = ref[i]; - if (!(+item.dataset.index > +index)) { - continue; - } - $.before(item, shortcut); - return; - } - return $.add(Header.shortcuts, shortcut); - }, - rmShortcut: function(el) { - return $.rm(el.parentElement); - }, - menuToggle: function(e) { - return Header.menu.toggle(e, this, g); - }, - createNotification: function(e) { - var content, lifetime, notice, ref, type; - ref = e.detail, type = ref.type, content = ref.content, lifetime = ref.lifetime; - return notice = new Notice(type, content, lifetime); - }, - areNotificationsEnabled: false, - enableDesktopNotifications: function() { - var authorize, disable, el, notice, ref; - if (!(window.Notification && Conf['Desktop Notifications'])) { - return; - } - switch (Notification.permission) { - case 'granted': - Header.areNotificationsEnabled = true; - return; - case 'denied': - return; - } - el = $.el('span', {innerHTML: "4chan X needs your permission to show desktop notifications. [FAQ]
or "}); - ref = $$('button', el), authorize = ref[0], disable = ref[1]; - $.on(authorize, 'click', function() { - return Notification.requestPermission(function(status) { - Header.areNotificationsEnabled = status === 'granted'; - if (status === 'default') { - return; - } - return notice.close(); - }); - }); - $.on(disable, 'click', function() { - $.set('Desktop Notifications', false); - return notice.close(); - }); - return notice = new Notice('info', el); - } - }; - - return Header; - -}).call(this); - -Index = (function() { - var Index, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Index = { - showHiddenThreads: false, - changed: {}, - enabledOn: function(arg) { - var boardID, siteID; - siteID = arg.siteID, boardID = arg.boardID; - return Conf['JSON Index'] && g.sites[siteID].software === 'yotsuba' && boardID !== 'f'; - }, - init: function() { - var arr, entries, i, input, inputs, k, l, label, len1, len2, name, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, select, sortEntry, tRaw, watchSettings; - if (g.VIEW !== 'index') { - return; - } - $.one(d, '4chanXInitFinished', this.cb.initFinished); - $.on(d, 'PostsInserted', this.cb.postsInserted); - if (!this.enabledOn(g.BOARD)) { - return; - } - this.enabled = true; - Callbacks.Post.push({ - name: 'Index Page Numbers', - cb: this.node - }); - Callbacks.CatalogThread.push({ - name: 'Catalog Features', - cb: this.catalogNode - }); - this.search = ((ref = history.state) != null ? ref.searched : void 0) || ''; - if ((ref1 = history.state) != null ? ref1.mode : void 0) { - Conf['Index Mode'] = (ref2 = history.state) != null ? ref2.mode : void 0; - } - this.currentSort = (ref3 = history.state) != null ? ref3.sort : void 0; - this.currentSort || (this.currentSort = typeof Conf['Index Sort'] === 'object' ? Conf['Index Sort'][g.BOARD.ID] || 'bump' : Conf['Index Sort']); - this.currentPage = this.getCurrentPage(); - this.processHash(); - $.addClass(doc, 'index-loading', (Conf['Index Mode'].replace(/\ /g, '-')) + "-mode"); - $.on(window, 'popstate', this.cb.popstate); - $.on(d, 'scroll', this.scroll); - $.on(d, 'SortIndex', this.cb.resort); - this.button = $.el('a', { - className: 'fa fa-refresh', - title: 'Refresh', - href: 'javascript:;', - textContent: 'Refresh Index' - }); - $.on(this.button, 'click', function() { - return Index.update(); - }); - Header.addShortcut('index-refresh', this.button, 590); - entries = []; - this.inputs = inputs = $.dict(); - ref4 = Config.Index; - for (name in ref4) { - arr = ref4[name]; - if (!(arr instanceof Array)) { - continue; - } - label = UI.checkbox(name, "" + name[0] + (name.slice(1).toLowerCase())); - label.title = arr[1]; - entries.push({ - el: label - }); - input = label.firstChild; - $.on(input, 'change', $.cb.checked); - inputs[name] = input; - } - $.on(inputs['Show Replies'], 'change', this.cb.replies); - $.on(inputs['Catalog Hover Expand'], 'change', this.cb.hover); - $.on(inputs['Pin Watched Threads'], 'change', this.cb.resort); - $.on(inputs['Anchor Hidden Threads'], 'change', this.cb.resort); - watchSettings = function(e) { - if ((input = $.getOwn(inputs, e.target.name))) { - input.checked = e.target.checked; - return $.event('change', null, input); - } - }; - $.on(d, 'OpenSettings', function() { - return $.on($.id('fourchanx-settings'), 'change', watchSettings); - }); - sortEntry = UI.checkbox('Per-Board Sort Type', 'Per-board sort type', typeof Conf['Index Sort'] === 'object'); - sortEntry.title = 'Set the sorting order of each board independently.'; - $.on(sortEntry.firstChild, 'change', this.cb.perBoardSort); - entries.splice(3, 0, { - el: sortEntry - }); - Header.menu.addEntry({ - el: $.el('span', { - textContent: 'Index Navigation' - }), - order: 100, - subEntries: entries - }); - this.navLinks = $.el('div', { - className: 'navLinks json-index' - }); - $.extend(this.navLinks, {innerHTML: "Index Catalog Archive Bottom ×"}); - $('.cataloglink a', this.navLinks).href = CatalogLinks.catalog(); - if (!BoardConfig.isArchived(g.BOARD.ID)) { - $('.archlistlink', this.navLinks).hidden = true; - } - $.on($('#index-last-refresh a', this.navLinks), 'click', this.cb.refreshFront); - this.searchInput = $('#index-search', this.navLinks); - this.setupSearch(); - $.on(this.searchInput, 'input', this.onSearchInput); - $.on($('#index-search-clear', this.navLinks), 'click', this.clearSearch); - this.hideLabel = $('#hidden-label', this.navLinks); - $.on($('#hidden-toggle a', this.navLinks), 'click', this.cb.toggleHiddenThreads); - this.selectRev = $('#index-rev', this.navLinks); - this.selectMode = $('#index-mode', this.navLinks); - this.selectSort = $('#index-sort', this.navLinks); - this.selectSize = $('#index-size', this.navLinks); - $.on(this.selectRev, 'change', this.cb.sort); - $.on(this.selectMode, 'change', this.cb.mode); - $.on(this.selectSort, 'change', this.cb.sort); - $.on(this.selectSize, 'change', $.cb.value); - $.on(this.selectSize, 'change', this.cb.size); - ref5 = [this.selectMode, this.selectSize]; - for (k = 0, len1 = ref5.length; k < len1; k++) { - select = ref5[k]; - select.value = Conf[select.name]; - } - this.selectRev.checked = /-rev$/.test(Index.currentSort); - this.selectSort.value = Index.currentSort.replace(/-rev$/, ''); - this.lastLongOptions = $('#lastlong-options', this.navLinks); - this.lastLongInputs = $$('input', this.lastLongOptions); - this.lastLongThresholds = [0, 0]; - this.lastLongOptions.hidden = this.selectSort.value !== 'lastlong'; - ref6 = this.lastLongInputs; - for (i = l = 0, len2 = ref6.length; l < len2; i = ++l) { - input = ref6[i]; - $.on(input, 'change', this.cb.lastLongThresholds); - tRaw = Conf["Last Long Reply Thresholds " + i]; - input.value = this.lastLongThresholds[i] = typeof tRaw === 'object' ? (ref7 = tRaw[g.BOARD.ID]) != null ? ref7 : 100 : tRaw; - } - this.root = $.el('div', { - className: 'board json-index' - }); - $.on(this.root, 'click', this.cb.hoverToggle); - this.cb.size(); - this.cb.hover(); - this.pagelist = $.el('div', { - className: 'pagelist json-index' - }); - $.extend(this.pagelist, {innerHTML: "
"}); - $('.cataloglink a', this.pagelist).href = CatalogLinks.catalog(); - $.on(this.pagelist, 'click', this.cb.pageNav); - this.update(true); - $.onExists(doc, 'title + *', function() { - return d.title = d.title.replace(/\ -\ Page\ \d+/, ''); - }); - $.onExists(doc, '.board > .thread > .postContainer, .board + *', function() { - var board, el, len3, m, ref8, timeEl, topNavPos; - g.SITE.Build.hat = $('.board > .thread > img:first-child'); - if (g.SITE.Build.hat) { - g.BOARD.threads.forEach(function(thread) { - if (thread.nodes.root) { - return $.prepend(thread.nodes.root, g.SITE.Build.hat.cloneNode(false)); - } - }); - $.addClass(doc, 'hats-enabled'); - $.addStyle(".catalog-thread::after {background-image: url(" + g.SITE.Build.hat.src + ");}"); - } - board = $('.board'); - $.replace(board, Index.root); - if (Index.loaded) { - $.event('PostsInserted', null, Index.root); - } - try { - d.implementation.createDocument(null, null, null).appendChild(board); - } catch (error) {} - ref8 = $$('.navLinks'); - for (m = 0, len3 = ref8.length; m < len3; m++) { - el = ref8[m]; - $.rm(el); - } - $.rm($.id('ctrl-top')); - topNavPos = $.id('delform').previousElementSibling; - $.before(topNavPos, $.el('hr')); - $.before(topNavPos, Index.navLinks); - timeEl = $('#index-last-refresh time', Index.navLinks); - if (timeEl.dataset.utc) { - return RelativeDates.update(timeEl); - } - }); - return Main.ready(function() { - var pagelist; - if ((pagelist = $('.pagelist'))) { - $.replace(pagelist, Index.pagelist); - } - return $.rmClass(doc, 'index-loading'); - }); - }, - scroll: function() { - var pageNum, threadIDs; - if (Index.req || !Index.liveThreadData || Conf['Index Mode'] !== 'infinite' || (window.scrollY <= doc.scrollHeight - (300 + window.innerHeight))) { - return; - } - if (Index.pageNum == null) { - Index.pageNum = Index.currentPage; - } - pageNum = ++Index.pageNum; - if (pageNum > Index.pagesNum) { - return Index.endNotice(); - } - threadIDs = Index.threadsOnPage(pageNum); - return Index.buildStructure(threadIDs); - }, - endNotice: (function() { - var notify, reset; - notify = false; - reset = function() { - return notify = false; - }; - return function() { - if (notify) { - return; - } - notify = true; - new Notice('info', "Last page reached.", 2); - return setTimeout(reset, 3 * $.SECOND); - }; - })(), - menu: { - init: function() { - if (!(g.VIEW === 'index' && Conf['Menu'] && Conf['Thread Hiding Link'] && Index.enabledOn(g.BOARD))) { - return; - } - return Menu.menu.addEntry({ - el: $.el('a', { - href: 'javascript:;', - className: 'has-shortcut-text' - }, {innerHTML: "Shift+click"}), - order: 20, - open: function(arg) { - var thread; - thread = arg.thread; - if (Conf['Index Mode'] !== 'catalog') { - return false; - } - this.el.firstElementChild.textContent = thread.isHidden ? 'Unhide' : 'Hide'; - if (this.cb) { - $.off(this.el, 'click', this.cb); - } - this.cb = function() { - $.event('CloseMenu'); - return Index.toggleHide(thread); - }; - $.on(this.el, 'click', this.cb); - return true; - } - }); - } - }, - node: function() { - if (this.isReply || this.isClone || !(Index.threadPosition[this.ID] != null)) { - return; - } - return this.thread.setPage(Math.floor(Index.threadPosition[this.ID] / Index.threadsNumPerPage) + 1); - }, - catalogNode: function() { - return $.on(this.nodes.root, 'mousedown click', (function(_this) { - return function(e) { - if (!(e.button === 0 && e.shiftKey)) { - return; - } - if (e.type === 'click') { - Index.toggleHide(_this.thread); - } - return e.preventDefault(); - }; - })(this)); - }, - toggleHide: function(thread) { - if (Index.showHiddenThreads) { - ThreadHiding.show(thread); - if (!ThreadHiding.db.get({ - boardID: thread.board.ID, - threadID: thread.ID - })) { - return; - } - } else { - ThreadHiding.hide(thread); - } - return ThreadHiding.saveHiddenState(thread); - }, - cycleSortType: function() { - var i, k, len1, type, types; - types = slice.call(Index.selectSort.options).filter(function(option) { - return !option.disabled; - }); - for (i = k = 0, len1 = types.length; k < len1; i = ++k) { - type = types[i]; - if (type.selected) { - break; - } - } - types[(i + 1) % types.length].selected = true; - return $.event('change', null, Index.selectSort); - }, - cb: { - initFinished: function() { - Index.initFinishedFired = true; - return $.queueTask(function() { - return Index.cb.postsInserted(); - }); - }, - postsInserted: function() { - var n; - if (!Index.initFinishedFired) { - return; - } - n = 0; - g.posts.forEach(function(post) { - if (!post.isFetchedQuote && !post.indexRefreshSeen && doc.contains(post.nodes.root)) { - post.indexRefreshSeen = true; - return n++; - } - }); - if (n) { - return $.event('IndexRefresh'); - } - }, - toggleHiddenThreads: function() { - $('#hidden-toggle a', Index.navLinks).textContent = (Index.showHiddenThreads = !Index.showHiddenThreads) ? 'Hide' : 'Show'; - Index.sort(); - return Index.buildIndex(); - }, - mode: function() { - Index.pushState({ - mode: this.value - }); - return Index.pageLoad(false); - }, - sort: function() { - var value; - value = Index.selectRev.checked ? Index.selectSort.value + "-rev" : Index.selectSort.value; - Index.pushState({ - sort: value - }); - return Index.pageLoad(false); - }, - resort: function(e) { - var ref; - Index.changed.order = true; - if (!(e != null ? (ref = e.detail) != null ? ref.deferred : void 0 : void 0)) { - return Index.pageLoad(false); - } - }, - perBoardSort: function() { - var i, k; - Conf['Index Sort'] = this.checked ? $.dict() : ''; - Index.saveSort(); - for (i = k = 0; k < 2; i = ++k) { - Conf["Last Long Reply Thresholds " + i] = this.checked ? $.dict() : ''; - Index.saveLastLongThresholds(i); - } - }, - lastLongThresholds: function() { - var i, value; - i = slice.call(this.parentNode.children).indexOf(this); - value = +this.value; - if (!Number.isFinite(value)) { - this.value = Index.lastLongThresholds[i]; - return; - } - Index.lastLongThresholds[i] = value; - Index.saveLastLongThresholds(i); - Index.changed.order = true; - return Index.pageLoad(false); - }, - size: function(e) { - if (Conf['Index Mode'] !== 'catalog') { - $.rmClass(Index.root, 'catalog-small'); - $.rmClass(Index.root, 'catalog-large'); - } else if (Conf['Index Size'] === 'small') { - $.addClass(Index.root, 'catalog-small'); - $.rmClass(Index.root, 'catalog-large'); - } else { - $.addClass(Index.root, 'catalog-large'); - $.rmClass(Index.root, 'catalog-small'); - } - if (e) { - return Index.buildIndex(); - } - }, - replies: function() { - return Index.buildIndex(); - }, - hover: function() { - return doc.classList.toggle('catalog-hover-expand', Conf['Catalog Hover Expand']); - }, - hoverToggle: function(e) { - var input, thread; - if (Conf['Catalog Hover Toggle'] && $.hasClass(doc, 'catalog-mode') && !$.modifiedClick(e) && !$.x('ancestor-or-self::a', e.target)) { - input = Index.inputs['Catalog Hover Expand']; - input.checked = !input.checked; - $.event('change', null, input); - if ((thread = Get.threadFromNode(e.target))) { - Index.cb.catalogReplies.call(thread); - return Index.cb.hoverAdjust.call(thread.OP.nodes); - } - } - }, - popstate: function(e) { - var mode, nCommands, page, ref, searched, sort; - if (e != null ? e.state : void 0) { - ref = e.state, searched = ref.searched, mode = ref.mode, sort = ref.sort; - page = Index.getCurrentPage(); - Index.setState({ - search: searched, - mode: mode, - sort: sort, - page: page - }); - return Index.pageLoad(false); - } else { - nCommands = Index.processHash(); - if (Conf['Refreshed Navigation'] && nCommands) { - return Index.update(); - } else { - return Index.pageLoad(); - } - } - }, - pageNav: function(e) { - var a; - if ($.modifiedClick(e)) { - return; - } - switch (e.target.nodeName) { - case 'BUTTON': - e.target.blur(); - a = e.target.parentNode; - break; - case 'A': - a = e.target; - break; - default: - return; - } - if (a.textContent === 'Catalog') { - return; - } - e.preventDefault(); - return Index.userPageNav(+a.pathname.split(/\/+/)[2] || 1); - }, - refreshFront: function() { - Index.pushState({ - page: 1 - }); - return Index.update(); - }, - catalogReplies: function() { - if (Conf['Show Replies'] && $.hasClass(doc, 'catalog-hover-expand') && !this.catalogView.nodes.replies) { - return Index.buildCatalogReplies(this); - } - }, - hoverAdjust: function() { - var rect, style, x; - if (!$.hasClass(doc, 'catalog-hover-expand')) { - return; - } - rect = this.post.getBoundingClientRect(); - if ((x = $.minmax(0, -rect.left, doc.clientWidth - rect.right))) { - style = this.post.style; - style.left = x + "px"; - style.right = (-x) + "px"; - return $.one(this.root, 'mouseleave', function() { - return style.left = style.right = null; - }); - } - } - }, - scrollToIndex: function() { - return Header.scrollToIfNeeded((Index.navLinks.getBoundingClientRect().height ? Index.navLinks : Index.root)); - }, - getCurrentPage: function() { - return +window.location.pathname.split(/\/+/)[2] || 1; - }, - userPageNav: function(page) { - Index.pushState({ - page: page - }); - if (Conf['Refreshed Navigation']) { - return Index.update(); - } else { - return Index.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: function() { - var command, commands, hash, k, leftover, len1, mode, ref, sort, state; - hash = ((ref = location.href.match(/#.*/)) != null ? ref[0] : void 0) || ''; - state = { - replace: true - }; - commands = hash.slice(1).split('/'); - leftover = []; - for (k = 0, len1 = commands.length; k < len1; k++) { - command = commands[k]; - if ((mode = $.getOwn(Index.hashCommands.mode, command))) { - state.mode = mode; - } else if (command === 'index') { - state.mode = Conf['Previous Index Mode']; - state.page = 1; - } else if ((sort = $.getOwn(Index.hashCommands.sort, command.replace(/-rev$/, '')))) { - state.sort = sort; - if (/-rev$/.test(command)) { - state.sort += '-rev'; - } - } else if (/^s=/.test(command)) { - state.search = decodeURIComponent(command.slice(2)).replace(/\+/g, ' ').trim(); - } else { - leftover.push(command); - } - } - hash = leftover.join('/'); - if (hash) { - state.hash = "#" + hash; - } - Index.pushState(state); - return commands.length - leftover.length; - }, - pushState: function(state) { - var hash, pageBeforeSearch, pathname, ref, replace, search; - search = state.search, hash = state.hash, replace = state.replace; - pageBeforeSearch = (ref = history.state) != null ? ref.oldpage : void 0; - if ((search != null) && search !== Index.search) { - state.page = search ? 1 : pageBeforeSearch || 1; - if (!search) { - pageBeforeSearch = void 0; - } else if (!Index.search) { - pageBeforeSearch = Index.currentPage; - } - } - Index.setState(state); - pathname = Index.currentPage === 1 ? "/" + g.BOARD + "/" : "/" + g.BOARD + "/" + Index.currentPage; - hash || (hash = ''); - return history[replace ? 'replaceState' : 'pushState']({ - mode: Conf['Index Mode'], - sort: Index.currentSort, - searched: Index.search, - oldpage: pageBeforeSearch - }, '', location.protocol + "//" + location.host + pathname + hash); - }, - setState: function(arg) { - var hash, mode, page, ref, search, sort; - search = arg.search, mode = arg.mode, sort = arg.sort, page = arg.page, hash = arg.hash; - if ((search != null) && search !== Index.search) { - Index.changed.search = true; - Index.search = search; - } - if ((mode != null) && mode !== Conf['Index Mode']) { - Index.changed.mode = true; - Conf['Index Mode'] = mode; - $.set('Index Mode', mode); - if (!(mode === 'catalog' || Conf['Previous Index Mode'] === mode)) { - Conf['Previous Index Mode'] = mode; - $.set('Previous Index Mode', mode); - } - } - if ((sort != null) && sort !== Index.currentSort) { - Index.changed.sort = true; - Index.currentSort = sort; - Index.saveSort(); - } - if ((ref = Conf['Index Mode']) === 'all pages' || ref === 'catalog') { - page = 1; - } - if ((page != null) && page !== Index.currentPage) { - Index.changed.page = true; - Index.currentPage = page; - } - if (hash != null) { - return Index.changed.hash = true; - } - }, - savePerBoard: function(key, value) { - if (typeof Conf[key] === 'object') { - Conf[key][g.BOARD.ID] = value; - } else { - Conf[key] = value; - } - return $.set(key, Conf[key]); - }, - saveSort: function() { - return Index.savePerBoard('Index Sort', Index.currentSort); - }, - saveLastLongThresholds: function(i) { - return Index.savePerBoard("Last Long Reply Thresholds " + i, Index.lastLongThresholds[i]); - }, - pageLoad: function(scroll) { - var hash, mode, order, page, ref, search, sort, threads; - if (scroll == null) { - scroll = true; - } - if (!Index.liveThreadData) { - return; - } - ref = Index.changed, threads = ref.threads, order = ref.order, search = ref.search, mode = ref.mode, sort = ref.sort, page = ref.page, hash = ref.hash; - threads || (threads = search); - order || (order = sort); - if (threads || order) { - Index.sort(); - } - if (threads) { - Index.buildPagelist(); - } - if (search) { - Index.setupSearch(); - } - if (mode) { - Index.setupMode(); - } - if (sort) { - Index.setupSort(); - } - if (threads || mode || page || order) { - Index.buildIndex(); - } - if (threads || page) { - Index.setPage(); - } - if (scroll && !hash) { - Index.scrollToIndex(); - } - if (hash) { - Header.hashScroll(); - } - return Index.changed = {}; - }, - setupMode: function() { - var k, len1, mode, ref; - ref = ['paged', 'infinite', 'all pages', 'catalog']; - for (k = 0, len1 = ref.length; k < len1; k++) { - mode = ref[k]; - $[mode === Conf['Index Mode'] ? 'addClass' : 'rmClass'](doc, (mode.replace(/\ /g, '-')) + "-mode"); - } - Index.selectMode.value = Conf['Index Mode']; - Index.cb.size(); - Index.showHiddenThreads = false; - return $('#hidden-toggle a', Index.navLinks).textContent = 'Show'; - }, - setupSort: function() { - Index.selectRev.checked = /-rev$/.test(Index.currentSort); - Index.selectSort.value = Index.currentSort.replace(/-rev$/, ''); - return Index.lastLongOptions.hidden = Index.selectSort.value !== 'lastlong'; - }, - getPagesNum: function() { - if (Index.search) { - return Math.ceil(Index.sortedThreadIDs.length / Index.threadsNumPerPage); - } else { - return Index.pagesNum; - } - }, - getMaxPageNum: function() { - return Math.max(1, Index.getPagesNum()); - }, - buildPagelist: function() { - var a, i, k, maxPageNum, nodes, pagesRoot, ref; - pagesRoot = $('.pages', Index.pagelist); - maxPageNum = Index.getMaxPageNum(); - if (pagesRoot.childElementCount !== maxPageNum) { - nodes = []; - for (i = k = 1, ref = maxPageNum; k <= ref; i = k += 1) { - a = $.el('a', { - textContent: i, - href: i === 1 ? './' : i - }); - nodes.push($.tn('['), a, $.tn('] ')); - } - $.rmAll(pagesRoot); - return $.add(pagesRoot, nodes); - } - }, - setPage: function() { - var a, href, maxPageNum, next, pageNum, pagesRoot, prev, strong; - pageNum = Index.currentPage; - maxPageNum = Index.getMaxPageNum(); - pagesRoot = $('.pages', Index.pagelist); - prev = pagesRoot.previousSibling.firstChild; - next = pagesRoot.nextSibling.firstChild; - href = Math.max(pageNum - 1, 1); - prev.href = href === 1 ? './' : href; - prev.firstChild.disabled = href === pageNum; - href = Math.min(pageNum + 1, maxPageNum); - next.href = href === 1 ? './' : href; - next.firstChild.disabled = href === pageNum; - if (strong = $('strong', pagesRoot)) { - if (+strong.textContent === pageNum) { - return; - } - $.replace(strong, strong.firstChild); - } else { - strong = $.el('strong'); - } - if ((a = pagesRoot.children[pageNum - 1])) { - $.before(a, strong); - return $.add(strong, a); - } - }, - updateHideLabel: function() { - var hiddenCount, k, len1, ref, threadID; - if (!Index.hideLabel) { - return; - } - hiddenCount = 0; - ref = Index.liveThreadIDs; - for (k = 0, len1 = ref.length; k < len1; k++) { - threadID = ref[k]; - if (Index.isHidden(threadID)) { - hiddenCount++; - } - } - if (!hiddenCount) { - Index.hideLabel.hidden = true; - if (Index.showHiddenThreads) { - Index.cb.toggleHiddenThreads(); - } - return; - } - Index.hideLabel.hidden = false; - return $('#hidden-count', Index.navLinks).textContent = hiddenCount === 1 ? '1 hidden thread' : hiddenCount + " hidden threads"; - }, - update: function(firstTime) { - var oldReq; - if ((oldReq = Index.req)) { - delete Index.req; - oldReq.abort(); - } - if (Conf['Index Refresh Notifications']) { - Index.notice || (Index.notice = new Notice('info', 'Refreshing index...')); - Index.nTimeout || (Index.nTimeout = setTimeout(function() { - var ref; - return (ref = Index.notice) != null ? ref.el.lastElementChild.textContent += ' (disable JSON Index if this takes too long)' : void 0; - }, 3 * $.SECOND)); - } else { - Index.nTimeout || (Index.nTimeout = setTimeout(function() { - return Index.notice || (Index.notice = new Notice('info', 'Refreshing index... (disable JSON Index if this takes too long)')); - }, 3 * $.SECOND)); - } - if (!firstTime && d.readyState !== 'loading' && !$('.board + *')) { - location.reload(); - return; - } - Index.req = $.whenModified(g.SITE.urls.catalogJSON({ - boardID: g.BOARD.ID - }), 'Index', Index.load); - return $.addClass(Index.button, 'fa-spin'); - }, - load: function() { - var err, nTimeout, notice, ref, timeEl; - if (this !== Index.req) { - return; - } - $.rmClass(Index.button, 'fa-spin'); - notice = Index.notice, nTimeout = Index.nTimeout; - if (nTimeout) { - clearTimeout(nTimeout); - } - delete Index.nTimeout; - delete Index.req; - delete Index.notice; - if ((ref = this.status) !== 200 && ref !== 304) { - err = "Index refresh failed. " + (this.status ? "Error " + this.statusText + " (" + this.status + ")" : 'Connection Error'); - if (notice) { - notice.setType('warning'); - notice.el.lastElementChild.textContent = err; - setTimeout(notice.close, $.SECOND); - } else { - new Notice('warning', err, 1); - } - return; - } - try { - if (this.status === 200) { - Index.parse(this.response); - } else if (this.status === 304) { - Index.pageLoad(); - } - } catch (error) { - err = error; - c.error("Index failure: " + err.message, err.stack); - if (notice) { - notice.setType('error'); - notice.el.lastElementChild.textContent = 'Index refresh failed.'; - setTimeout(notice.close, $.SECOND); - } else { - new Notice('error', 'Index refresh failed.', 1); - } - return; - } - if (notice) { - if (Conf['Index Refresh Notifications']) { - notice.setType('success'); - notice.el.lastElementChild.textContent = 'Index refreshed!'; - setTimeout(notice.close, $.SECOND); - } else { - notice.close(); - } - } - timeEl = $('#index-last-refresh time', Index.navLinks); - timeEl.dataset.utc = Date.parse(this.getResponseHeader('Last-Modified')); - return RelativeDates.update(timeEl); - }, - parse: function(pages) { - $.cleanCache(function(url) { - return /^https?:\/\/a\.4cdn\.org\//.test(url); - }); - Index.parseThreadList(pages); - Index.changed.threads = true; - return Index.pageLoad(); - }, - parseThreadList: function(pages) { - var ID, data, i, k, l, len1, len2, obj, ref, ref1, ref2, reply, results; - Index.pagesNum = pages.length; - Index.threadsNumPerPage = ((ref = pages[0]) != null ? ref.threads.length : void 0) || 1; - Index.liveThreadData = pages.reduce((function(arr, next) { - return arr.concat(next.threads); - }), []); - Index.liveThreadIDs = Index.liveThreadData.map(function(data) { - return data.no; - }); - Index.liveThreadDict = $.dict(); - Index.threadPosition = $.dict(); - Index.parsedThreads = $.dict(); - Index.replyData = $.dict(); - ref1 = Index.liveThreadData; - for (i = k = 0, len1 = ref1.length; k < len1; i = ++k) { - data = ref1[i]; - Index.liveThreadDict[data.no] = data; - Index.threadPosition[data.no] = i; - Index.parsedThreads[data.no] = obj = g.SITE.Build.parseJSON(data, g.BOARD); - obj.filterResults = results = Filter.test(obj); - obj.isOnTop = results.top; - obj.isHidden = results.hide || ThreadHiding.isHidden(obj.boardID, obj.threadID); - if (data.last_replies) { - ref2 = data.last_replies; - for (l = 0, len2 = ref2.length; l < len2; l++) { - reply = ref2[l]; - Index.replyData[g.BOARD + "." + reply.no] = reply; - } - } - } - if (Index.liveThreadData[0]) { - g.SITE.Build.spoilerRange[g.BOARD.ID] = Index.liveThreadData[0].custom_spoiler; - } - g.BOARD.threads.forEach(function(thread) { - var ref3; - if (ref3 = thread.ID, indexOf.call(Index.liveThreadIDs, ref3) < 0) { - return thread.collect(); - } - }); - $.event('IndexUpdate', { - threads: (function() { - var len3, m, ref3, results1; - ref3 = Index.liveThreadIDs; - results1 = []; - for (m = 0, len3 = ref3.length; m < len3; m++) { - ID = ref3[m]; - results1.push(g.BOARD + "." + ID); - } - return results1; - })() - }); - }, - isHidden: function(threadID) { - var thread; - if ((thread = g.BOARD.threads.get(threadID)) && thread.OP && !thread.OP.isFetchedQuote) { - return thread.isHidden; - } else { - return Index.parsedThreads[threadID].isHidden; - } - }, - isHiddenReply: function(threadID, replyData) { - return PostHiding.isHidden(g.BOARD.ID, threadID, replyData.no) || Filter.isHidden(g.SITE.Build.parseJSON(replyData, g.BOARD)); - }, - buildThreads: function(threadIDs, isCatalog, withReplies) { - var ID, OP, err, errors, isStale, k, lastPost, len1, newPosts, newThreads, obj, opRoot, t, thread, threadData, threads; - threads = []; - newThreads = []; - newPosts = []; - for (k = 0, len1 = threadIDs.length; k < len1; k++) { - ID = threadIDs[k]; - try { - threadData = Index.liveThreadDict[ID]; - if ((thread = g.BOARD.threads.get(ID))) { - isStale = (thread.json !== threadData) && (JSON.stringify(thread.json) !== JSON.stringify(threadData)); - if (isStale) { - thread.setCount('post', threadData.replies + 1, threadData.bumplimit); - thread.setCount('file', threadData.images + !!threadData.ext, threadData.imagelimit); - thread.setStatus('Sticky', !!threadData.sticky); - thread.setStatus('Closed', !!threadData.closed); - } - if (thread.catalogView) { - $.rm(thread.catalogView.nodes.replies); - thread.catalogView.nodes.replies = null; - } - } else { - thread = new Thread(ID, g.BOARD); - newThreads.push(thread); - } - lastPost = threadData.last_replies && threadData.last_replies.length ? threadData.last_replies[threadData.last_replies.length - 1].no : ID; - if (lastPost > thread.lastPost) { - thread.lastPost = lastPost; - } - thread.json = threadData; - threads.push(thread); - if ((OP = thread.OP) && !OP.isFetchedQuote) { - OP.setCatalogOP(isCatalog); - thread.setPage(Math.floor(Index.threadPosition[ID] / Index.threadsNumPerPage) + 1); - } else { - obj = Index.parsedThreads[ID]; - opRoot = g.SITE.Build.post(obj); - OP = new Post(opRoot, thread, g.BOARD); - OP.filterResults = obj.filterResults; - newPosts.push(OP); - } - if (!(isCatalog && thread.nodes.root)) { - g.SITE.Build.thread(thread, threadData, withReplies); - } - } catch (error) { - err = error; - if (!errors) { - errors = []; - } - errors.push({ - message: "Parsing of Thread No." + thread + " failed. Thread will be skipped.", - error: err, - html: opRoot != null ? opRoot.outerHTML : void 0 - }); - } - } - if (errors) { - Main.handleErrors(errors); - } - if (withReplies) { - newPosts = newPosts.concat(Index.buildReplies(threads)); - } - Main.callbackNodes('Thread', newThreads); - Main.callbackNodes('Post', newPosts); - Index.updateHideLabel(); - $.event('IndexRefreshInternal', { - threadIDs: (function() { - var l, len2, results1; - results1 = []; - for (l = 0, len2 = threads.length; l < len2; l++) { - t = threads[l]; - results1.push(t.fullID); - } - return results1; - })(), - isCatalog: isCatalog - }); - return threads; - }, - buildReplies: function(threads) { - var data, err, errors, k, l, lastReplies, len1, len2, node, nodes, post, posts, thread; - posts = []; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - if (!(lastReplies = Index.liveThreadDict[thread.ID].last_replies)) { - continue; - } - nodes = []; - for (l = 0, len2 = lastReplies.length; l < len2; l++) { - data = lastReplies[l]; - if ((post = thread.posts.get(data.no)) && !post.isFetchedQuote) { - nodes.push(post.nodes.root); - continue; - } - nodes.push(node = g.SITE.Build.postFromObject(data, thread.board.ID)); - try { - posts.push(new Post(node, thread, thread.board)); - } catch (error) { - err = error; - if (!errors) { - errors = []; - } - errors.push({ - message: "Parsing of Post No." + data.no + " failed. Post will be skipped.", - error: err, - html: node != null ? node.outerHTML : void 0 - }); - } - } - $.add(thread.nodes.root, nodes); - } - if (errors) { - Main.handleErrors(errors); - } - return posts; - }, - buildCatalogViews: function(threads) { - var ID, catalogThreads, k, len1, page, root, thread; - catalogThreads = []; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - if (!(!thread.catalogView)) { - continue; - } - ID = thread.ID; - page = Math.floor(Index.threadPosition[ID] / Index.threadsNumPerPage) + 1; - root = g.SITE.Build.catalogThread(thread, Index.liveThreadDict[ID], page); - catalogThreads.push(new CatalogThread(root, thread)); - } - Main.callbackNodes('CatalogThread', catalogThreads); - }, - sizeCatalogViews: function(threads) { - var height, k, len1, ratio, ref, size, thread, thumb, width; - size = Conf['Index Size'] === 'small' ? 150 : 250; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - thumb = thread.catalogView.nodes.thumb; - ref = thumb.dataset, width = ref.width, height = ref.height; - if (!width) { - continue; - } - ratio = size / Math.max(width, height); - thumb.style.width = width * ratio + 'px'; - thumb.style.height = height * ratio + 'px'; - } - }, - buildCatalogReplies: function(thread) { - var data, k, lastReplies, len1, nodes, replies, reply; - nodes = thread.catalogView.nodes; - if (!(lastReplies = Index.liveThreadDict[thread.ID].last_replies)) { - return; - } - replies = []; - for (k = 0, len1 = lastReplies.length; k < len1; k++) { - data = lastReplies[k]; - if (Index.isHiddenReply(thread.ID, data)) { - continue; - } - reply = g.SITE.Build.catalogReply(thread, data); - RelativeDates.update($('time', reply)); - $.on($('.catalog-reply-preview', reply), 'mouseover', QuotePreview.mouseover); - replies.push(reply); - } - nodes.replies = $.el('div', { - className: 'catalog-replies' - }); - $.add(nodes.replies, replies); - $.add(thread.OP.nodes.post, nodes.replies); - }, - sort: function() { - var lastlong, lastlongD, liveThreadData, liveThreadIDs, repliesAvailable, sortType, thread, threadIDs, tmp_time; - liveThreadIDs = Index.liveThreadIDs, liveThreadData = Index.liveThreadData; - if (!liveThreadData) { - return; - } - tmp_time = new Date().getTime() / 1000; - sortType = Index.currentSort.replace(/-rev$/, ''); - Index.sortedThreadIDs = (function() { - var k, len1; - switch (sortType) { - case 'lastreply': - case 'lastlong': - repliesAvailable = liveThreadData.some(function(thread) { - var ref; - return (ref = thread.last_replies) != null ? ref.length : void 0; - }); - lastlong = function(thread) { - var i, k, len, r, ref, ref1; - if (!repliesAvailable) { - return thread.last_modified; - } - ref = thread.last_replies || []; - for (i = k = ref.length - 1; k >= 0; i = k += -1) { - r = ref[i]; - if (Index.isHiddenReply(thread.no, r)) { - continue; - } - if (sortType === 'lastreply') { - return r; - } - len = r.com ? g.SITE.Build.parseComment(r.com).replace(/[^a-z]/ig, '').length : 0; - if (len >= Index.lastLongThresholds[+(!!r.ext)]) { - return r; - } - } - if (thread.omitted_posts && ((ref1 = thread.last_replies) != null ? ref1.length : void 0)) { - return thread.last_replies[0]; - } else { - return thread; - } - }; - lastlongD = $.dict(); - for (k = 0, len1 = liveThreadData.length; k < len1; k++) { - thread = liveThreadData[k]; - lastlongD[thread.no] = lastlong(thread).no; - } - return slice.call(liveThreadData).sort(function(a, b) { - return lastlongD[b.no] - lastlongD[a.no]; - }).map(function(post) { - return post.no; - }); - case 'bump': - return liveThreadIDs; - case 'birth': - return slice.call(liveThreadIDs).sort(function(a, b) { - return b - a; - }); - case 'replycount': - return slice.call(liveThreadData).sort(function(a, b) { - return b.replies - a.replies; - }).map(function(post) { - return post.no; - }); - case 'filecount': - return slice.call(liveThreadData).sort(function(a, b) { - return b.images - a.images; - }).map(function(post) { - return post.no; - }); - case 'activity': - return slice.call(liveThreadData).sort(function(a, b) { - return (tmp_time - a.time) / (a.replies + 1) - (tmp_time - b.time) / (b.replies + 1); - }).map(function(post) { - return post.no; - }); - default: - return liveThreadIDs; - } - })(); - if (/-rev$/.test(Index.currentSort)) { - Index.sortedThreadIDs = slice.call(Index.sortedThreadIDs).reverse(); - } - if (Index.search && (threadIDs = Index.querySearch(Index.search))) { - Index.sortedThreadIDs = threadIDs; - } - Index.sortOnTop(function(obj) { - return obj.isSticky; - }); - Index.sortOnTop(function(obj) { - return obj.isOnTop || Conf['Pin Watched Threads'] && ThreadWatcher.isWatchedRaw(obj.boardID, obj.threadID); - }); - if (Conf['Anchor Hidden Threads']) { - return Index.sortOnTop(function(obj) { - return !Index.isHidden(obj.threadID); - }); - } - }, - sortOnTop: function(match) { - var ID, bottomThreads, k, len1, ref, topThreads; - topThreads = []; - bottomThreads = []; - ref = Index.sortedThreadIDs; - for (k = 0, len1 = ref.length; k < len1; k++) { - ID = ref[k]; - (match(Index.parsedThreads[ID]) ? topThreads : bottomThreads).push(ID); - } - return Index.sortedThreadIDs = topThreads.concat(bottomThreads); - }, - buildIndex: function() { - var threadIDs; - if (!Index.liveThreadData) { - return; - } - switch (Conf['Index Mode']) { - case 'all pages': - threadIDs = Index.sortedThreadIDs; - break; - case 'catalog': - threadIDs = Index.sortedThreadIDs.filter(function(ID) { - return !Index.isHidden(ID) !== Index.showHiddenThreads; - }); - break; - default: - threadIDs = Index.threadsOnPage(Index.currentPage); - } - delete Index.pageNum; - $.rmAll(Index.root); - $.rmAll(Header.hover); - if (Index.loaded && Index.root.parentNode) { - $.event('PostsRemoved', null, Index.root); - } - if (Conf['Index Mode'] === 'catalog') { - Index.buildCatalog(threadIDs); - } else { - Index.buildStructure(threadIDs); - } - }, - threadsOnPage: function(pageNum) { - var nodesPerPage, offset; - nodesPerPage = Index.threadsNumPerPage; - offset = nodesPerPage * (pageNum - 1); - return Index.sortedThreadIDs.slice(offset, offset + nodesPerPage); - }, - buildStructure: function(threadIDs) { - var k, len1, nodes, thread, threads; - threads = Index.buildThreads(threadIDs, false, Conf['Show Replies']); - nodes = []; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - nodes.push(thread.nodes.root, $.el('hr')); - } - $.add(Index.root, nodes); - if (Index.root.parentNode) { - $.event('PostsInserted', null, Index.root); - } - Index.loaded = true; - }, - buildCatalog: function(threadIDs) { - var fn, i, n, node0; - i = 0; - n = threadIDs.length; - node0 = null; - fn = function() { - var j; - if (node0 && !node0.parentNode) { - return; - } - j = i > 0 && Index.root.parentNode ? n : i + 30; - node0 = Index.buildCatalogPart(threadIDs.slice(i, j))[0]; - i = j; - if (i < n) { - return $.queueTask(fn); - } else { - if (Index.root.parentNode) { - $.event('PostsInserted', null, Index.root); - } - return Index.loaded = true; - } - }; - fn(); - }, - buildCatalogPart: function(threadIDs) { - var k, len1, nodes, thread, threads; - threads = Index.buildThreads(threadIDs, true); - Index.buildCatalogViews(threads); - Index.sizeCatalogViews(threads); - nodes = []; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - thread.OP.setCatalogOP(true); - $.add(thread.catalogView.nodes.root, thread.OP.nodes.root); - nodes.push(thread.catalogView.nodes.root); - $.on(thread.catalogView.nodes.root, 'mouseenter', Index.cb.catalogReplies.bind(thread)); - $.on(thread.OP.nodes.root, 'mouseenter', Index.cb.hoverAdjust.bind(thread.OP.nodes)); - } - $.add(Index.root, nodes); - return nodes; - }, - clearSearch: function() { - Index.searchInput.value = ''; - Index.onSearchInput(); - return Index.searchInput.focus(); - }, - setupSearch: function() { - Index.searchInput.value = Index.search; - if (Index.search) { - return Index.searchInput.dataset.searching = 1; - } else { - return Index.searchInput.removeAttribute('data-searching'); - } - }, - onSearchInput: function() { - var search; - search = Index.searchInput.value.trim(); - if (search === Index.search) { - return; - } - Index.pushState({ - search: search, - replace: !!search === !!Index.search - }); - return Index.pageLoad(false); - }, - querySearch: function(query) { - var keywords, match, regexp; - if ((match = query.match(/^([\w+]+):\/(.*)\/(\w*)$/))) { - try { - regexp = RegExp(match[2], match[3]); - } catch (error) { - return []; - } - return Index.sortedThreadIDs.filter(function(ID) { - return regexp.test(Filter.values(match[1], Index.parsedThreads[ID]).join('\n')); - }); - } - if (!(keywords = query.toLowerCase().match(/\S+/g))) { - return; - } - return Index.sortedThreadIDs.filter(function(ID) { - return Index.searchMatch(Index.parsedThreads[ID], keywords); - }); - }, - searchMatch: function(obj, keywords) { - var file, info, k, key, keyword, l, len1, len2, ref, text; - info = obj.info, file = obj.file; - if (info.comment == null) { - info.comment = g.SITE.Build.parseComment(info.commentHTML.innerHTML); - } - text = []; - ref = ['comment', 'subject', 'name', 'tripcode']; - for (k = 0, len1 = ref.length; k < len1; k++) { - key = ref[k]; - if (key in info) { - text.push(info[key]); - } - } - if (file) { - text.push(file.name); - } - text = text.join(' ').toLowerCase(); - for (l = 0, len2 = keywords.length; l < len2; l++) { - keyword = keywords[l]; - if (-1 === text.indexOf(keyword)) { - return false; - } - } - return true; - } - }; - - return Index; - -}).call(this); - -Polyfill = (function() { - var Polyfill; - - Polyfill = { - init: function() { - var base; - this.toBlob(); - $.global(this.toBlob); - (base = Element.prototype).matches || (base.matches = Element.prototype.mozMatchesSelector || Element.prototype.webkitMatchesSelector); - }, - toBlob: function() { - if (HTMLCanvasElement.prototype.toBlob) { - return; - } - HTMLCanvasElement.prototype.toBlob = function(cb, type, encoderOptions) { - var data, i, j, l, ref, ui8a, url; - url = this.toDataURL(type, encoderOptions); - data = atob(url.slice(url.indexOf(',') + 1)); - l = data.length; - ui8a = new Uint8Array(l); - for (i = j = 0, ref = l; j < ref; i = j += 1) { - ui8a[i] = data.charCodeAt(i); - } - return cb(new Blob([ui8a], { - type: type || 'image/png' - })); - }; - } - }; - - return Polyfill; - -}).call(this); - -Settings = (function() { - var Settings, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Settings = { - init: function() { - var add, link; - link = $.el('a', { - className: 'settings-link fa fa-wrench', - textContent: 'Settings', - title: '4chan X Settings', - href: 'javascript:;' - }); - $.on(link, 'click', Settings.open); - Header.addShortcut('settings', link, 820); - add = this.addSection; - add('Main', this.main); - add('Filter', this.filter); - add('Sauce', this.sauce); - add('Advanced', this.advanced); - add('Keybinds', this.keybinds); - $.on(d, 'AddSettingsSection', Settings.addSection); - $.on(d, 'OpenSettings', function(e) { - return Settings.open(e.detail); - }); - if (g.SITE.software === 'yotsuba' && Conf['Disable Native Extension']) { - if ($.hasStorage) { - return $.global(function() { - var settings; - try { - settings = JSON.parse(localStorage.getItem('4chan-settings')) || {}; - if (settings.disableAll) { - return; - } - settings.disableAll = true; - return localStorage.setItem('4chan-settings', JSON.stringify(settings)); - } catch (error) { - return Object.defineProperty(window, 'Config', { - value: { - disableAll: true - } - }); - } - }); - } else { - return $.global(function() { - return Object.defineProperty(window, 'Config', { - value: { - disableAll: true - } - }); - }); - } - } - }, - open: function(openSection) { - var dialog, j, len, link, links, ref, section, sectionToOpen; - if (Settings.dialog) { - return; - } - $.event('CloseMenu'); - Settings.dialog = dialog = $.el('div', { - id: 'overlay' - }, {innerHTML: ""}); - $.on($('.export', dialog), 'click', Settings["export"]); - $.on($('.import', dialog), 'click', Settings["import"]); - $.on($('.reset', dialog), 'click', Settings.reset); - $.on($('input', dialog), 'change', Settings.onImport); - links = []; - ref = Settings.sections; - for (j = 0, len = ref.length; j < len; j++) { - section = ref[j]; - link = $.el('a', { - className: "tab-" + section.hyphenatedTitle, - textContent: section.title, - href: 'javascript:;' - }); - $.on(link, 'click', Settings.openSection.bind(section)); - links.push(link, $.tn(' | ')); - if (section.title === openSection) { - sectionToOpen = link; - } - } - links.pop(); - $.add($('.sections-list', dialog), links); - if (openSection !== 'none') { - (sectionToOpen ? sectionToOpen : links[0]).click(); - } - $.on($('.close', dialog), 'click', Settings.close); - $.on(window, 'beforeunload', Settings.close); - $.on(dialog, 'click', Settings.close); - $.on(dialog.firstElementChild, 'click', function(e) { - return e.stopPropagation(); - }); - $.add(d.body, dialog); - return $.event('OpenSettings', null, dialog); - }, - close: function() { - var ref; - if (!Settings.dialog) { - return; - } - if ((ref = d.activeElement) != null) { - ref.blur(); - } - $.rm(Settings.dialog); - return delete Settings.dialog; - }, - sections: [], - addSection: function(title, open) { - var hyphenatedTitle, ref; - if (typeof title !== 'string') { - ref = title.detail, title = ref.title, open = ref.open; - } - hyphenatedTitle = title.toLowerCase().replace(/\s+/g, '-'); - return Settings.sections.push({ - title: title, - hyphenatedTitle: hyphenatedTitle, - open: open - }); - }, - openSection: function() { - var section, selected; - if (selected = $('.tab-selected', Settings.dialog)) { - $.rmClass(selected, 'tab-selected'); - } - $.addClass($(".tab-" + this.hyphenatedTitle, Settings.dialog), 'tab-selected'); - section = $('section', Settings.dialog); - $.rmAll(section); - section.className = "section-" + this.hyphenatedTitle; - this.open(section, g); - section.scrollTop = 0; - return $.event('OpenSettings', null, section); - }, - warnings: { - localStorage: function(cb) { - var why; - if ($.cantSync) { - why = $.cantSet ? 'save your settings' : 'synchronize settings between tabs'; - return cb($.el('li', { - textContent: "4chan X needs local storage to " + why + ".\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: function(cb) { - return $.onExists(doc, '.adg-rects > .desktop', function(ad) { - return $.onExists(ad, 'iframe', function() { - var url; - url = Redirect.to('thread', { - boardID: 'qa', - threadID: 362590 - }); - return cb($.el('li', {innerHTML: "To protect yourself from malicious ads, you should block ads on 4chan."})); - }); - }); - } - }, - main: function(section) { - var addCheckboxes, addWarning, button, div, fs, inputs, items, key, keyFS, obj, ref, ref1, warning, warnings; - warnings = $.el('fieldset', { - hidden: true - }, {innerHTML: "Warnings
    "}); - addWarning = function(item) { - $.add($('ul', warnings), item); - return warnings.hidden = false; - }; - ref = Settings.warnings; - for (key in ref) { - warning = ref[key]; - warning(addWarning); - } - $.add(section, warnings); - items = $.dict(); - inputs = $.dict(); - addCheckboxes = function(root, obj) { - var arr, container, containers, description, div, input, level, results; - containers = [root]; - results = []; - for (key in obj) { - arr = obj[key]; - if (!(arr instanceof Array)) { - continue; - } - description = arr[1]; - div = $.el('div', {innerHTML: ": " + E(description) + ""}); - div.dataset.name = key; - input = $('input', div); - $.on(input, 'change', $.cb.checked); - $.on(input, 'change', function() { - return this.parentNode.parentNode.dataset.checked = this.checked; - }); - items[key] = Conf[key]; - inputs[key] = input; - level = arr[2] || 0; - if (containers.length <= level) { - container = $.el('div', { - className: 'suboption-list' - }); - $.add(containers[containers.length - 1].lastElementChild, container); - containers[level] = container; - } else if (containers.length > level + 1) { - containers.splice(level + 1, containers.length - (level + 1)); - } - results.push($.add(containers[level], div)); - } - return results; - }; - ref1 = Config.main; - for (keyFS in ref1) { - obj = ref1[keyFS]; - fs = $.el('fieldset', {innerHTML: "" + E(keyFS) + ""}); - addCheckboxes(fs, obj); - if (keyFS === 'Posting and Captchas') { - $.add(fs, $.el('p', {innerHTML: "For more info on captcha options and issues, see the captcha FAQ."})); - } - $.add(section, fs); - } - addCheckboxes($('div[data-name="JSON Index"] > .suboption-list', section), Config.Index); - if ($.engine !== 'gecko') { - $('div[data-name="Remember QR Size"]', section).hidden = true; - } - if ($.perProtocolSettings || location.protocol !== 'https:') { - $('div[data-name="Redirect to HTTPS"]', section).hidden = true; - } - if ($.platform !== 'crx') { - $('div[data-name="Work around CORB Bug"]', section).hidden = true; - } - $.get(items, function(items) { - var val; - for (key in items) { - val = items[key]; - inputs[key].checked = val; - inputs[key].parentNode.parentNode.dataset.checked = val; - } - }); - div = $.el('div', {innerHTML: ": Clear manually-hidden threads and posts on all boards. Reload the page to apply."}); - button = $('button', div); - $.get({ - hiddenThreads: $.dict(), - hiddenPosts: $.dict() - }, function(arg) { - var ID, board, hiddenNum, hiddenPosts, hiddenThreads, ref2, ref3, ref4, ref5, site, thread; - hiddenThreads = arg.hiddenThreads, hiddenPosts = arg.hiddenPosts; - hiddenNum = 0; - for (ID in hiddenThreads) { - site = hiddenThreads[ID]; - if (ID !== 'boards') { - ref2 = site.boards; - for (ID in ref2) { - board = ref2[ID]; - hiddenNum += Object.keys(board).length; - } - } - } - ref3 = hiddenThreads.boards; - for (ID in ref3) { - board = ref3[ID]; - hiddenNum += Object.keys(board).length; - } - for (ID in hiddenPosts) { - site = hiddenPosts[ID]; - if (ID !== 'boards') { - ref4 = site.boards; - for (ID in ref4) { - board = ref4[ID]; - for (ID in board) { - thread = board[ID]; - hiddenNum += Object.keys(thread).length; - } - } - } - } - ref5 = hiddenPosts.boards; - for (ID in ref5) { - board = ref5[ID]; - for (ID in board) { - thread = board[ID]; - hiddenNum += Object.keys(thread).length; - } - } - return button.textContent = "Hidden: " + hiddenNum; - }); - $.on(button, 'click', function() { - this.textContent = 'Hidden: 0'; - return $.get('hiddenThreads', $.dict(), function(arg) { - var boardID, hiddenThreads, ref2; - hiddenThreads = arg.hiddenThreads; - if ($.hasStorage && g.SITE.software === 'yotsuba') { - for (boardID in (ref2 = hiddenThreads['4chan.org']) != null ? ref2.boards : void 0) { - localStorage.removeItem("4chan-hide-t-" + boardID); - } - for (boardID in hiddenThreads.boards) { - localStorage.removeItem("4chan-hide-t-" + boardID); - } - } - return $["delete"](['hiddenThreads', 'hiddenPosts']); - }); - }); - return $.after($('input[name="Stubs"]', section).parentNode.parentNode, div); - }, - "export": function() { - var Conf2; - Conf2 = $.dict(); - $.extend(Conf2, Conf); - return $.get(Conf2, function(Conf2) { - delete Conf2['boardConfig']; - return Settings.downloadExport({ - version: g.VERSION, - date: Date.now(), - Conf: Conf2 - }); - }); - }, - downloadExport: function(data) { - var a, blob, p, url; - blob = new Blob([JSON.stringify(data, null, 2)], { - type: 'application/json' - }); - url = URL.createObjectURL(blob); - a = $.el('a', { - download: "4chan X v" + g.VERSION + "-" + data.date + ".json", - href: url - }); - p = $('.imp-exp-result', Settings.dialog); - $.rmAll(p); - $.add(p, a); - return a.click(); - }, - "import": function() { - return $('input[type=file]', this.parentNode).click(); - }, - onImport: function() { - var file, output, reader; - if (!(file = this.files[0])) { - return; - } - this.value = null; - output = $('.imp-exp-result'); - if (!confirm('Your current settings will be entirely overwritten, are you sure?')) { - output.textContent = 'Import aborted.'; - return; - } - reader = new FileReader(); - reader.onload = function(e) { - var err; - try { - return Settings.loadSettings($.dict.json(e.target.result), function(err) { - if (err) { - return output.textContent = 'Import failed due to an error.'; - } else if (confirm('Import successful. Reload now?')) { - return window.location.reload(); - } - }); - } catch (error) { - err = error; - output.textContent = 'Import failed due to an error.'; - return c.error(err.stack); - } - }; - return reader.readAsText(file); - }, - convertFrom: { - loadletter: function(data) { - var base, boardID, convertSettings, key, ref, ref1, threadData, threadID, threads, val; - convertSettings = function(data, map) { - var newKey, prevKey; - for (prevKey in map) { - newKey = map[prevKey]; - if (newKey) { - data.Conf[newKey] = data.Conf[prevKey]; - } - delete data.Conf[prevKey]; - } - return data; - }; - data = convertSettings(data, { - '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': '' - }); - if ('Always CDN' in data.Conf) { - data.Conf['fourchanImageHost'] = data.Conf['Always CDN'] ? 'i.4cdn.org' : ''; - delete data.Conf['Always CDN']; - } - data.Conf.sauces = data.Conf.sauces.replace(/\$\d/g, function(c) { - switch (c) { - case '$1': - return '%TURL'; - case '$2': - return '%URL'; - case '$3': - return '%MD5'; - case '$4': - return '%board'; - default: - return c; - } - }); - ref = Config.hotkeys; - for (key in ref) { - val = ref[key]; - if (key in data.Conf) { - data.Conf[key] = data.Conf[key].replace(/ctrl|alt|meta/g, function(s) { - return "" + (s[0].toUpperCase()) + s.slice(1); - }).replace(/(^|.+\+)[A-Z]$/g, function(s) { - return "Shift+" + s.slice(0, -1) + (s.slice(-1).toLowerCase()); - }); - } - } - if (data.WatchedThreads) { - data.Conf['watchedThreads'] = $.dict.clone({ - '4chan.org': { - boards: {} - } - }); - ref1 = data.WatchedThreads; - for (boardID in ref1) { - threads = ref1[boardID]; - for (threadID in threads) { - threadData = threads[threadID]; - ((base = data.Conf['watchedThreads']['4chan.org'].boards)[boardID] || (base[boardID] = $.dict()))[threadID] = { - excerpt: threadData.textContent - }; - } - } - } - return data; - } - }, - upgrade: function(data, version) { - var addCSS, addSauces, boardID, boards, changes, compareString, corrupted, db, hostname, j, k, key, l, lastChecked, len, len1, len2, len3, line, list, m, name, record, ref, ref1, ref10, ref11, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, rice, set, setD, siteProperties, software, type, uids, val, val2, value; - changes = $.dict(); - set = function(key, value) { - return data[key] = changes[key] = value; - }; - setD = function(key, value) { - if (data[key] == null) { - return set(key, value); - } - }; - addSauces = function(sauces) { - if (data['sauces'] != null) { - sauces = sauces.filter(function(s) { - return data['sauces'].indexOf(s.match(/[^#;\s]+|$/)[0]) < 0; - }); - if (sauces.length) { - return set('sauces', data['sauces'] + '\n\n' + sauces.join('\n')); - } - } - }; - addCSS = function(css) { - if (data['usercss'] == null) { - set('usercss', Config['usercss']); - } - if (data['usercss'].indexOf(css) < 0) { - return set('usercss', css + '\n\n' + data['usercss']); - } - }; - if ((corrupted = version[0] === '"')) { - try { - version = JSON.parse(version); - } catch (error) {} - } - compareString = version.replace(/\d+/g, function(x) { - return ('0000' + x).slice(-5); - }); - if (compareString < '00001.00013.00014.00008') { - for (key in data) { - val = data[key]; - if (!(typeof val === 'string' && typeof Conf[key] !== 'string' && (key !== 'Index Sort' && key !== 'Last Long Reply Thresholds 0' && key !== 'Last Long Reply Thresholds 1'))) { - continue; - } - corrupted = true; - break; - } - } - if (corrupted) { - for (key in data) { - val = data[key]; - if (typeof val === 'string') { - try { - val2 = JSON.parse(val); - set(key, val2); - } catch (error) {} - } - } - } - if (compareString < '00001.00011.00008.00000') { - if (data['Fixed Thread Watcher'] == null) { - set('Fixed Thread Watcher', (ref = data['Toggleable Thread Watcher']) != null ? ref : true); - } - if (data['Exempt Archives from Encryption'] == null) { - set('Exempt Archives from Encryption', (ref1 = data['Except Archives from Encryption']) != null ? ref1 : false); - } - } - if (compareString < '00001.00011.00010.00001') { - if (data['selectedArchives'] != null) { - uids = { - "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 - }; - ref2 = data['selectedArchives']; - for (boardID in ref2) { - record = ref2[boardID]; - for (type in record) { - name = record[type]; - if ($.hasOwn(uids, name)) { - record[type] = uids[name]; - } - } - } - set('selectedArchives', data['selectedArchives']); - } - } - if (compareString < '00001.00011.00016.00000') { - if ((rice = Config['usercss'].match(/\/\* Board title rice \*\/(?:\n.+)*/)[0])) { - if ((data['usercss'] != null) && data['usercss'].indexOf(rice) < 0) { - set('usercss', rice + '\n\n' + data['usercss']); - } - } - } - if (compareString < '00001.00011.00017.00000') { - ref3 = ['Persistent QR', 'Color User IDs', 'Fappe Tyme', 'Werk Tyme', 'Highlight Posts Quoting You', 'Highlight Own Posts']; - for (j = 0, len = ref3.length; j < len; j++) { - key = ref3[j]; - if (data[key] == null) { - set(key, key === 'Persistent QR'); - } - } - } - if (compareString < '00001.00011.00017.00006') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/iqdb\.org\//mg, '$1//iqdb.org/')); - } - } - if (compareString < '00001.00011.00019.00003' && !Settings.dialog) { - $.queueTask(function() { - return Settings.warnings.ads(function(item) { - return new Notice('warning', slice.call(item.childNodes)); - }); - }); - } - if (compareString < '00001.00011.00020.00003') { - ref4 = { - 'Inline Cross-thread Quotes Only': false, - 'Pass Link': true - }; - for (key in ref4) { - value = ref4[key]; - if (data[key] == null) { - set(key, value); - } - } - } - if (compareString < '00001.00011.00021.00003') { - if (data['Remember Your Posts'] == null) { - set('Remember Your Posts', (ref5 = data['Mark Quotes of You']) != null ? ref5 : true); - } - } - if (compareString < '00001.00011.00022.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(?:IMG|URL))%3Fs\.jpg/mg, '$1')); - set('sauces', data['sauces'].replace(/^#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(?:IMG|T?URL)(?=$|;)/mg, '$&&safe=off')); - } - } - if (compareString < '00001.00011.00022.00002') { - if ((data['Use Recaptcha v1 in Reports'] == null) && data['Use Recaptcha v1'] && !data['Use Recaptcha v2 in Reports']) { - set('Use Recaptcha v1 in Reports', true); - } - } - if (compareString < '00001.00011.00024.00000') { - if ((data['JSON Navigation'] != null) && (data['JSON Index'] == null)) { - set('JSON Index', data['JSON Navigation']); - } - } - if (compareString < '00001.00011.00026.00000') { - if ((data['Oekaki Links'] != null) && (data['Edit Link'] == null)) { - set('Edit Link', data['Oekaki Links']); - } - if (data['Inline Cross-thread Quotes Only'] == null) { - set('Inline Cross-thread Quotes Only', true); - } - } - if (compareString < '00001.00011.00030.00000') { - if (data['Quote Threading'] && (data['Thread Quotes'] == null)) { - set('Thread Quotes', true); - } - } - if (compareString < '00001.00011.00032.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/3d\.iqdb\.org\//mg, '$1//3d.iqdb.org/')); - } - addSauces(['#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']); - } - if (compareString < '00001.00011.00035.00000') { - addSauces(['https://whatanime.ga/?auto&url=%IMG;text:wait']); - } - if (compareString < '00001.00012.00000.00000') { - if (data['Exempt Archives from Encryption'] == null) { - set('Exempt Archives from Encryption', false); - } - if (data['Show New Thread Option in Threads'] == null) { - set('Show New Thread Option in Threads', false); - } - if (data['Show Name and Subject']) { - addCSS('#qr .persona .field {display: block !important;}'); - } - if (data['QR Shortcut'] === false) { - addCSS('#shortcut-qr {display: none;}'); - } - if (data['Bottom QR Link'] === false) { - addCSS('.qr-link-container-bottom {display: none;}'); - } - } - if (compareString < '00001.00012.00000.00006') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)https:\/\/(?:desustorage|cuckchan)\.org\//mg, '$1https://desuarchive.org/')); - } - } - if (compareString < '00001.00012.00001.00000') { - if ((data['Persistent Thread Watcher'] == null) && (data['Toggleable Thread Watcher'] != null)) { - set('Persistent Thread Watcher', !data['Toggleable Thread Watcher']); - } - } - if (compareString < '00001.00012.00003.00000') { - ref6 = ['Image Hover in Catalog', 'Auto Watch', 'Auto Watch Reply']; - for (k = 0, len1 = ref6.length; k < len1; k++) { - key = ref6[k]; - setD(key, false); - } - } - if (compareString < '00001.00013.00001.00002') { - addSauces(['#//www.bing.com/images/search?q=imgurl:%IMG&view=detailv2&iss=sbi#enterInsights']); - } - if (compareString < '00001.00013.00005.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/regex\.info\/exif\.cgi/mg, '$1http://exif.regex.info/exif.cgi')); - } - addSauces(Config['sauces'].match(/# Known filename formats:(?:\n.+)*|$/)[0].split('\n')); - } - if (compareString < '00001.00013.00007.00002') { - setD('Require OP Quote Link', true); - } - if (compareString < '00001.00013.00008.00000') { - setD('Download Link', true); - } - if (compareString < '00001.00013.00009.00003') { - if (data['jsWhitelist'] != null) { - list = data['jsWhitelist'].split('\n'); - if (indexOf.call(list, 'https://cdnjs.cloudflare.com') < 0 && indexOf.call(list, 'https://cdn.mathjax.org') >= 0) { - set('jsWhitelist', data['jsWhitelist'] + '\n\nhttps://cdnjs.cloudflare.com'); - } - } - } - if (compareString < '00001.00014.00000.00006') { - if (data['siteSoftware'] != null) { - set('siteSoftware', data['siteSoftware'] + '\n4cdn.org yotsuba'); - } - } - if (compareString < '00001.00014.00003.00002') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)https:\/\/whatanime\.ga\//mg, '$1https://trace.moe/')); - } - } - if (compareString < '00001.00014.00004.00004') { - if ((data['siteSoftware'] != null) && !/^4channel\.org yotsuba$/m.test(data['siteSoftware'])) { - set('siteSoftware', data['siteSoftware'] + '\n4channel.org yotsuba'); - } - } - if (compareString < '00001.00014.00005.00000') { - ref7 = DataBoard.keys; - for (l = 0, len2 = ref7.length; l < len2; l++) { - db = ref7[l]; - if ((ref8 = data[db]) != null ? ref8.boards : void 0) { - ref9 = data[db], boards = ref9.boards, lastChecked = ref9.lastChecked; - data[db]['4chan.org'] = { - boards: boards, - lastChecked: lastChecked - }; - delete data[db].boards; - delete data[db].lastChecked; - set(db, data[db]); - } - } - if ((data['siteSoftware'] != null) && (data['siteProperties'] == null)) { - siteProperties = $.dict(); - ref10 = data['siteSoftware'].split('\n'); - for (m = 0, len3 = ref10.length; m < len3; m++) { - line = ref10[m]; - ref11 = line.split(' '), hostname = ref11[0], software = ref11[1]; - siteProperties[hostname] = { - software: software - }; - } - set('siteProperties', siteProperties); - } - } - if (compareString < '00001.00014.00006.00006') { - if (data['sauces'] != null) { - set('sauces', data['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}-/')); - } - } - if (compareString < '00001.00014.00008.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/https:\/\/www\.yandex\.com\/images\/search/g, 'https://yandex.com/images/search')); - } - } - if (compareString < '00001.00014.00009.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)(?:http:)?\/\/(www\.pixiv\.net|www\.deviantart\.com|imgur\.com|flickr\.com)\//mg, '$1https://$2/')); - set('sauces', data['sauces'].replace(/https:\/\/yandex\.com\/images\/search\?rpt=imageview&img_url=%IMG/g, 'https://yandex.com/images/search?rpt=imageview&url=%IMG')); - } - } - if (compareString < '00001.00014.00009.00001') { - if ((data['Use Faster Image Host'] != null) && (data['fourchanImageHost'] == null)) { - set('fourchanImageHost', (data['Use Faster Image Host'] ? 'i.4cdn.org' : '')); - } - } - if (compareString < '00001.00014.00010.00001') { - if (data['Filter in Native Catalog'] == null) { - set('Filter in Native Catalog', false); - } - } - if (compareString < '00001.00014.00012.00008') { - if (data['boardnav'] == null) { - set('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\",\"https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions\"]"); - } - } - if (compareString < '00001.00014.00016.00001') { - if (data['archiveLists'] != null) { - set('archiveLists', data['archiveLists'].replace('https://mayhemydg.github.io/archives.json/archives.json', 'https://nstepien.github.io/archives.json/archives.json')); - } - } - if (compareString < '00001.00014.00016.00007') { - if (data['sauces'] != null) { - set('sauces', data['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')); - } - } - if (compareString < '00001.00014.00017.00002') { - if (data['jsWhitelist'] != null) { - set('jsWhitelist', data['jsWhitelist'] + '\n\nhttps://hcaptcha.com\nhttps://*.hcaptcha.com'); - } - } - if (compareString < '00001.00014.00020.00004') { - if (data['archiveLists'] != null) { - set('archiveLists', data['archiveLists'].replace('https://nstepien.github.io/archives.json/archives.json', 'https://4chenz.github.io/archives.json/archives.json')); - } - } - if (compareString < '00001.00014.00022.00003') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(IMG|T?URL)&safe=off(?=$|;)/mg, 'https://www.google.com/searchbyimage?sbisrc=4chanx&image_url=%$1&safe=off')); - if (compareString === '00001.00014.00022.00002' && !/\bsbisrc=/.test(data['sauces'])) { - set('sauces', data['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')); - } - } - addSauces(['#https://lens.google.com/uploadbyurl?url=%IMG;text:lens']); - } - return changes; - }, - loadSettings: function(data, cb) { - if (data.version.split('.')[0] === '2') { - data = Settings.convertFrom.loadletter(data); - } else if (data.version !== g.VERSION) { - Settings.upgrade(data.Conf, data.version); - } - return $.clear(function(err) { - if (err) { - return cb(err); - } - return $.set(data.Conf, cb); - }); - }, - reset: function() { - if (confirm('Your current settings will be entirely wiped, are you sure?')) { - return $.clear(function(err) { - if (err) { - return $('.imp-exp-result').textContent = 'Import failed due to an error.'; - } else if (confirm('Reset successful. Reload now?')) { - return window.location.reload(); - } - }); - } - }, - filter: function(section) { - var select; - $.extend(section, {innerHTML: "
    "}); - select = $('select', section); - $.on(select, 'change', Settings.selectFilter); - return Settings.selectFilter.call(select); - }, - selectFilter: function() { - var div, filterTypes, name, ta; - div = this.nextElementSibling; - if ((name = this.value) !== 'guide') { - if (!$.hasOwn(Config.filter, name)) { - return; - } - $.rmAll(div); - ta = $.el('textarea', { - name: name, - className: 'field', - spellcheck: false - }); - $.on(ta, 'change', $.cb.value); - $.get(name, Conf[name], function(item) { - ta.value = item[name]; - return $.add(div, ta); - }); - return; - } - filterTypes = Object.keys(Config.filter).filter(function(x) { - return x !== 'general'; - }).map(function(x, i) { - return {innerHTML: ((i) ? "," : "") + "" + E(x)}; - }); - $.extend(div, {innerHTML: "
    Filter is disabled.

    Use regular expressions, one per line.
    Lines starting with a # will be ignored.
    For example, /weeaboo/i will filter posts containing the string `weeaboo`, case-insensitive.
    MD5 and Unique ID filtering use exact string matching, not regular expressions.

      You can use these settings with each regular expression, separate them with semicolons:
    • Per boards, separate them with commas. It is global if not specified. Use sfw and nsfw to reference all worksafe or not-worksafe boards.
      For example: boards:a,jp;.
      To specify boards on a particular site, put the beginning of the domain and a slash character before the list.
      Any initial www. should not be included, and all 4chan domains are considered 4chan.org.
      For example: boards:4:a,jp,sama:a,z;.
      An asterisk can be used to specify all boards on a site.
      For example: boards:4:*;.
    • Select boards to be excluded from the filter. The syntax is the same as for the boards: option above.
      For example: exclude:vg,v;.
    • Filter OPs only along with their threads (`only`) or replies only (`no`).
      For example: op:only; or op:no;.
    • Filter only posts with files (`only`) or only posts without files (`no`).
      For example: file:only; or file:no;.
    • Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`).
      For example: stub:yes; or stub:no;.
    • Highlight instead of hiding. You can specify a class name to use with a userstyle.
      For example: highlight; or highlight:wallpaper;.
    • Highlighted OPs will have their threads put on top of the board index by default.
      For example: top:yes; or top:no;.
    • Show a desktop notification instead of hiding.
      For example: notify;.
    • Filters in the \"General\" section apply to multiple fields, by default subject,name,filename,comment.
      The fields can be specified with the type option, separated by commas.
      For example: type:" + E.cat(filterTypes) + ";.
      Types can also be combined with a + sign; this indicates the filter applies to the given fields joined by newlines.
      For example: type:filename+filesize+dimensions;.
    "}); - return $('.warning', div).hidden = Conf['Filter']; - }, - sauce: function(section) { - var ta; - $.extend(section, {innerHTML: "
    Sauce is disabled.
    These parameters will be replaced by their corresponding values in the URL and displayed text:
    • %IMG: Full image URL for GIF, JPG, and PNG; thumbnail URL for other types.
    • %URL: Full image URL.
    • %TURL: Thumbnail URL.
    • %name: Original file name.
    • %board: Current board.
    • %MD5: MD5 hash in base64.
    • %sMD5: MD5 hash in base64 using - and _.
    • %hMD5: MD5 hash in hexadecimal.
    • %$0: Matched regular expression within the filename.
    • %$1, %$2, %$3, ... : Subexpressions within the matched regular expression.
    • %%, %semi: Literal % and ;.
    Lines starting with a # will be ignored.
    You can specify a display text by appending ;text:[text] to the URL.
    You can specify the applicable boards/sites by appending ;boards:[board1],[board2]. See the Filter guide for details.
    You can specify the applicable file types by appending ;types:[extension1],[extension2].
    You can specify a regular expression the filename must match by appending ;regexp:[regular expression].
    "}); - $('.warning', section).hidden = Conf['Sauce']; - ta = $('textarea', section); - $.get('sauces', Conf['sauces'], function(item) { - ta.value = item['sauces']; - return ta.hidden = false; - }); - return $.on(ta, 'change', $.cb.value); - }, - advanced: function(section) { - var applyCSS, boardSelect, customCSS, event, input, inputs, interval, items, itemsArchive, j, k, l, len, len1, len2, len3, listImageHost, m, name, ref, ref1, ref2, ref3, ref4, table, textContent, updateArchives, warning; - $.extend(section, {innerHTML: "
    Archives
    404 Redirect is disabled.
    Thread redirectionPost fetchingFile redirection

    Archive Lists: Each line below should be an archive list in this format or a URL to load an archive list from.
    Archive properties can be overriden by another item with the same uid (or if absent, its name).
    Last updated:
    External Catalog
    External Catalog is disabled. This will be used only as a fallback.
    URLs of external catalog sites, where %board is to be replaced by the board name.
    Each URL should be followed by ;boards: and optionally ;exclude: and a list of supported/excluded boards in the format explained in the Filter guide.
    Override 4chan Image Host
    Change 4chan image links to this domain. Leave blank for no change.
    Captcha Language
    Choose from list of language codes. Leave blank to autoselect.
    Custom Board Navigation
    New lines will be converted into spaces.

    In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
    Board link: g
    Archive link: g-archive
    Internal archive link: g-expired
    Title link: g-title
    Board link (Replace with title when on that board): g-replace
    Full text link: g-full
    Custom text link: g-text:"Install Gentoo"
    Index-only link: g-index
    Catalog-only link: g-catalog
    Index mode: g-mode:"infinite scrolling"
    Index sort: g-sort:"creation date rev"
    External link: external-text:"Google","http://www.google.com"
    Open in new tab: g-nt
    Combinations are possible: g-index-text:"Technology Index"
    Full board list toggle: toggle-all

    [ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:"Piracy"]
    will give you
    [ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
    if you are on /g/.
    Time Formatting is disabled.
    :
    Day: %a, %A, %d, %e
    Month: %m, %b, %B
    Year: %y, %Y
    Hour: %k, %H, %l, %I, %p, %P
    Minute: %M
    Second: %S
    Literal %: %%
    Quote Backlinks formatting is disabled.
    :
    Default pasted content filename
    .png
    File Info Formatting is disabled.
    :
    Link: %l (truncated), %L (untruncated), %T (4chan filename)
    Filename: %n (truncated), %N (untruncated), %t (4chan filename)
    Download button: %d
    Quick filter MD5: %f
    Spoiler indicator: %p
    Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
    Resolution: %r (Displays 'PDF' for PDF files)
    Tag: %g
    Literal %: %%
    Quick Reply Personas

    One item per line.
    Items will be added in the relevant input's auto-completion list.
    Password items will always be used, since there is no password input.
    Lines starting with a # will be ignored.

      You can use these settings with each item, separate them with semicolons:
    • Possible items are: name, options (or equivalently email), subject and password.
    • Wrap values of items with quotes, like this: options:"sage".
    • Force values as defaults with the always keyword, for example: options:"sage";always.
    • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
    Unread Favicon is disabled.
    Thread Updater is disabled.
    Interval: seconds
    Custom Cooldown Time
    Seconds:
    For more information about customizing 4chan X's CSS, see the styling guide.
    Javascript Whitelist
    Sources from which Javascript is allowed to be loaded by Content Security Policy.
    Lines starting with a # will be ignored.
    Known Banners
    List of known banners, used for click-to-change feature.
    "}); - ref = $$('.warning', section); - for (j = 0, len = ref.length; j < len; j++) { - warning = ref[j]; - warning.hidden = Conf[warning.dataset.feature]; - } - inputs = $.dict(); - ref1 = $$('[name]', section); - for (k = 0, len1 = ref1.length; k < len1; k++) { - input = ref1[k]; - inputs[input.name] = input; - } - $.on(inputs['archiveLists'], 'change', function() { - $.set('lastarchivecheck', 0); - Conf['lastarchivecheck'] = 0; - return $.id('lastarchivecheck').textContent = 'never'; - }); - items = $.dict(); - for (name in inputs) { - input = inputs[name]; - if (!(name !== 'Interval' && name !== 'Custom CSS')) { - continue; - } - items[name] = Conf[name]; - event = (input.nodeName === 'SELECT' || ((ref2 = input.type) === 'checkbox' || ref2 === 'radio') || (input.nodeName === 'TEXTAREA' && !(name in Settings))) ? 'change' : 'input'; - $.on(input, event, $.cb[input.type === 'checkbox' ? 'checked' : 'value']); - if (name in Settings) { - $.on(input, event, Settings[name]); - } - } - $.get(items, function(items) { - var key, val; - for (key in items) { - val = items[key]; - input = inputs[key]; - input[input.type === 'checkbox' ? 'checked' : 'value'] = val; - input.hidden = false; - if (key in Settings) { - Settings[key].call(input); - } - } - }); - listImageHost = $.id('list-fourchanImageHost'); - ref3 = ImageHost.suggestions; - for (l = 0, len2 = ref3.length; l < len2; l++) { - textContent = ref3[l]; - $.add(listImageHost, $.el('option', { - textContent: textContent - })); - } - interval = inputs['Interval']; - customCSS = inputs['Custom CSS']; - applyCSS = $('#apply-css', section); - interval.value = Conf['Interval']; - customCSS.checked = Conf['Custom CSS']; - inputs['usercss'].disabled = !Conf['Custom CSS']; - applyCSS.disabled = !Conf['Custom CSS']; - $.on(interval, 'change', ThreadUpdater.cb.interval); - $.on(customCSS, 'change', Settings.togglecss); - $.on(applyCSS, 'click', function() { - return CustomCSS.update(); - }); - itemsArchive = $.dict(); - ref4 = ['archives', 'selectedArchives', 'lastarchivecheck']; - for (m = 0, len3 = ref4.length; m < len3; m++) { - name = ref4[m]; - itemsArchive[name] = Conf[name]; - } - $.get(itemsArchive, function(itemsArchive) { - $.extend(Conf, itemsArchive); - Redirect.selectArchives(); - return Settings.addArchiveTable(section); - }); - boardSelect = $('#archive-board-select', section); - table = $('#archive-table', section); - updateArchives = $('#update-archives', section); - $.on(boardSelect, 'change', function() { - $('tbody > :not([hidden])', table).hidden = true; - return $("tbody > ." + this.value, table).hidden = false; - }); - return $.on(updateArchives, 'click', function() { - return Redirect.update(function() { - return Settings.addArchiveTable(section); - }); - }); - }, - addArchiveTable: function(section) { - var archBoards, archive, boardID, boardOptions, boardSelect, boards, data, files, id, item, j, k, l, len, len1, len2, len3, m, name, o, ref, ref1, ref2, ref3, ref4, row, rows, select, software, table, tbody, type, uid; - $('#lastarchivecheck', section).textContent = Conf['lastarchivecheck'] === 0 ? 'never' : new Date(Conf['lastarchivecheck']).toLocaleString(); - boardSelect = $('#archive-board-select', section); - table = $('#archive-table', section); - tbody = $('tbody', section); - $.rmAll(boardSelect); - $.rmAll(tbody); - archBoards = $.dict(); - ref = Conf['archives']; - for (j = 0, len = ref.length; j < len; j++) { - ref1 = ref[j], uid = ref1.uid, name = ref1.name, boards = ref1.boards, files = ref1.files, software = ref1.software; - if (software !== 'fuuka' && software !== 'foolfuuka') { - continue; - } - for (k = 0, len1 = boards.length; k < len1; k++) { - boardID = boards[k]; - o = archBoards[boardID] || (archBoards[boardID] = { - thread: [], - post: [], - file: [] - }); - archive = [uid != null ? uid : name, name]; - o.thread.push(archive); - if (software === 'foolfuuka') { - o.post.push(archive); - } - if (indexOf.call(files, boardID) >= 0) { - o.file.push(archive); - } - } - } - rows = []; - boardOptions = []; - ref2 = Object.keys(archBoards).sort(); - for (l = 0, len2 = ref2.length; l < len2; l++) { - boardID = ref2[l]; - row = $.el('tr', { - className: "board-" + boardID - }); - row.hidden = boardID !== g.BOARD.ID; - boardOptions.push($.el('option', { - textContent: "/" + boardID + "/", - value: "board-" + boardID, - selected: boardID === g.BOARD.ID - })); - o = archBoards[boardID]; - ref3 = ['thread', 'post', 'file']; - for (m = 0, len3 = ref3.length; m < len3; m++) { - item = ref3[m]; - $.add(row, Settings.addArchiveCell(boardID, o, item)); - } - rows.push(row); - } - if (rows.length === 0) { - boardSelect.hidden = table.hidden = true; - return; - } - boardSelect.hidden = table.hidden = false; - if (!(g.BOARD.ID in archBoards)) { - rows[0].hidden = false; - } - $.add(boardSelect, boardOptions); - $.add(tbody, rows); - ref4 = Conf['selectedArchives']; - for (boardID in ref4) { - data = ref4[boardID]; - for (type in data) { - id = data[type]; - if ((select = $("select[data-boardid='" + boardID + "'][data-type='" + type + "']", tbody))) { - select.value = JSON.stringify(id); - if (!select.value) { - select.value = select.firstChild.value; - } - } - } - } - }, - addArchiveCell: function(boardID, data, type) { - var archive, i, length, options, select, td; - length = data[type].length; - td = $.el('td', { - className: 'archive-cell' - }); - if (!length) { - td.textContent = '--'; - return td; - } - options = []; - i = 0; - while (i < length) { - archive = data[type][i++]; - options.push($.el('option', { - value: JSON.stringify(archive[0]), - textContent: archive[1] - })); - } - $.extend(td, {innerHTML: ""}); - select = td.firstElementChild; - if (!(select.disabled = length === 1)) { - select.setAttribute('data-boardid', boardID); - select.setAttribute('data-type', type); - $.on(select, 'change', Settings.saveSelectedArchive); - } - $.add(select, options); - return td; - }, - saveSelectedArchive: function() { - return $.get('selectedArchives', Conf['selectedArchives'], (function(_this) { - return function(arg) { - var name1, selectedArchives; - selectedArchives = arg.selectedArchives; - (selectedArchives[name1 = _this.dataset.boardid] || (selectedArchives[name1] = $.dict()))[_this.dataset.type] = JSON.parse(_this.value); - $.set('selectedArchives', selectedArchives); - Conf['selectedArchives'] = selectedArchives; - return Redirect.selectArchives(); - }; - })(this)); - }, - boardnav: function() { - return Header.generateBoardList(this.value); - }, - time: function() { - return this.nextElementSibling.textContent = Time.format(this.value, new Date()); - }, - timeLocale: function() { - return Settings.time.call($('[name=time]', Settings.dialog)); - }, - backlink: function() { - return this.nextElementSibling.textContent = this.value.replace(/%(?:id|%)/g, function(x) { - return { - '%id': '123456789', - '%%': '%' - }[x]; - }); - }, - fileInfo: function() { - var data; - data = { - isReply: true, - file: { - url: "//" + (ImageHost.host()) + "/g/1334437723720.jpg", - name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg', - size: '276 KB', - sizeInBytes: 276 * 1024, - dimensions: '1280x720', - isImage: true, - isVideo: false, - isSpoiler: true, - tag: 'Loop' - } - }; - return FileInfo.format(this.value, data, this.nextElementSibling); - }, - favicon: function() { - var f, i, icon, img, j, len, ref; - Favicon["switch"](); - if (g.VIEW === 'thread' && Conf['Unread Favicon']) { - Unread.update(); - } - img = this.nextElementSibling.children; - f = Favicon; - ref = [f.SFW, f.unreadSFW, f.unreadSFWY, f.NSFW, f.unreadNSFW, f.unreadNSFWY, f.dead, f.unreadDead, f.unreadDeadY]; - for (i = j = 0, len = ref.length; j < len; i = ++j) { - icon = ref[i]; - if (!img[i]) { - $.add(this.nextElementSibling, $.el('img')); - } - img[i].src = icon; - } - }, - togglecss: function() { - if ($('textarea[name=usercss]', $.x('ancestor::fieldset[1]', this)).disabled = $.id('apply-css').disabled = !this.checked) { - CustomCSS.rmStyle(); - } else { - CustomCSS.addStyle(); - } - return $.cb.checked.call(this); - }, - keybinds: function(section) { - var arr, input, inputs, items, key, ref, tbody, tr; - $.extend(section, {innerHTML: "
    Keybinds are disabled.
    Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
    Press Backspace to disable a keybind.
    ActionsKeybinds
    "}); - $('.warning', section).hidden = Conf['Keybinds']; - tbody = $('tbody', section); - items = $.dict(); - inputs = $.dict(); - ref = Config.hotkeys; - for (key in ref) { - arr = ref[key]; - tr = $.el('tr', {innerHTML: "" + E(arr[1]) + ""}); - input = $('input', tr); - input.name = key; - input.spellcheck = false; - items[key] = Conf[key]; - inputs[key] = input; - $.on(input, 'keydown', Settings.keybind); - $.add(tbody, tr); - } - return $.get(items, function(items) { - var val; - for (key in items) { - val = items[key]; - inputs[key].value = val; - } - }); - }, - keybind: function(e) { - var key; - if (e.keyCode === 9) { - return; - } - e.preventDefault(); - e.stopPropagation(); - if ((key = Keybinds.keyCode(e)) == null) { - return; - } - this.value = key; - return $.cb.value.call(this); - } - }; - - return Settings; - -}).call(this); - -Test = (function() { - return Test; - -}).call(this); - -UI = (function() { - var Menu, UI, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove, - bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - slice = [].slice; - - dialog = function(id, properties) { - var child, el, i, len, move, ref; - el = $.el('div', { - className: 'dialog', - id: id - }); - $.extend(el, properties); - el.style.cssText = Conf[id + ".position"]; - move = $('.move', el); - $.on(move, 'touchstart mousedown', dragstart); - ref = move.children; - for (i = 0, len = ref.length; i < len; i++) { - child = ref[i]; - if (!child.tagName) { - continue; - } - $.on(child, 'touchstart mousedown', function(e) { - return e.stopPropagation(); - }); - } - return el; - }; - - Menu = (function() { - var currentMenu, lastToggledButton; - - currentMenu = null; - - lastToggledButton = null; - - function Menu(type) { - this.type = type; - this.addEntry = bind(this.addEntry, this); - this.onFocus = bind(this.onFocus, this); - this.keybinds = bind(this.keybinds, this); - this.close = bind(this.close, this); - this.setPosition = bind(this.setPosition, this); - $.on(d, 'AddMenuEntry', (function(_this) { - return function(arg) { - var detail; - detail = arg.detail; - if (detail.type !== _this.type) { - return; - } - delete detail.open; - return _this.addEntry(detail); - }; - })(this)); - this.entries = []; - } - - Menu.prototype.makeMenu = function() { - var menu; - menu = $.el('div', { - className: 'dialog', - id: 'menu', - tabIndex: 0 - }); - menu.dataset.type = this.type; - $.on(menu, 'click', function(e) { - return e.stopPropagation(); - }); - $.on(menu, 'keydown', this.keybinds); - return menu; - }; - - Menu.prototype.toggle = function(e, button, data) { - var previousButton; - e.preventDefault(); - e.stopPropagation(); - if (currentMenu) { - previousButton = lastToggledButton; - currentMenu.close(); - if (previousButton === button) { - return; - } - } - if (!this.entries.length) { - return; - } - return this.open(button, data); - }; - - Menu.prototype.open = function(button, data) { - var entry, i, len, menu, ref; - menu = this.menu = this.makeMenu(); - currentMenu = this; - lastToggledButton = button; - this.entries.sort(function(first, second) { - return first.order - second.order; - }); - ref = this.entries; - for (i = 0, len = ref.length; i < len; i++) { - entry = ref[i]; - this.insertEntry(entry, menu, data); - } - $.addClass(lastToggledButton, 'active'); - $.on(d, 'click CloseMenu', this.close); - $.on(d, 'scroll', this.setPosition); - $.on(window, 'resize', this.setPosition); - $.after(button, menu); - this.setPosition(); - entry = $('.entry', menu); - this.focus(entry); - return menu.focus(); - }; - - Menu.prototype.setPosition = function() { - var bLeft, bRect, bTop, bottom, cHeight, cWidth, left, mRect, ref, ref1, right, top; - mRect = this.menu.getBoundingClientRect(); - bRect = lastToggledButton.getBoundingClientRect(); - bTop = window.scrollY + bRect.top; - bLeft = window.scrollX + bRect.left; - cHeight = doc.clientHeight; - cWidth = doc.clientWidth; - ref = bRect.top + bRect.height + mRect.height < cHeight ? [bRect.bottom + "px", ''] : ['', (cHeight - bRect.top) + "px"], top = ref[0], bottom = ref[1]; - ref1 = bRect.left + mRect.width < cWidth ? [bRect.left + "px", ''] : ['', (cWidth - bRect.right) + "px"], left = ref1[0], right = ref1[1]; - $.extend(this.menu.style, { - top: top, - right: right, - bottom: bottom, - left: left - }); - return this.menu.classList.toggle('left', right); - }; - - Menu.prototype.insertEntry = function(entry, parent, data) { - var err, i, len, ref, subEntry, submenu; - if (typeof entry.open === 'function') { - try { - if (!entry.open(data)) { - return; - } - } catch (error) { - err = error; - Main.handleErrors({ - message: "Error in building the " + this.type + " menu.", - error: err - }); - return; - } - } - $.add(parent, entry.el); - if (!entry.subEntries) { - return; - } - if (submenu = $('.submenu', entry.el)) { - $.rm(submenu); - } - submenu = $.el('div', { - className: 'dialog submenu' - }); - ref = entry.subEntries; - for (i = 0, len = ref.length; i < len; i++) { - subEntry = ref[i]; - this.insertEntry(subEntry, submenu, data); - } - $.add(entry.el, submenu); - }; - - Menu.prototype.close = function() { - $.rm(this.menu); - delete this.menu; - $.rmClass(lastToggledButton, 'active'); - currentMenu = null; - lastToggledButton = null; - $.off(d, 'click scroll CloseMenu', this.close); - $.off(d, 'scroll', this.setPosition); - return $.off(window, 'resize', this.setPosition); - }; - - Menu.prototype.findNextEntry = function(entry, direction) { - var entries; - entries = slice.call(entry.parentNode.children); - entries.sort(function(first, second) { - return first.style.order - second.style.order; - }); - return entries[entries.indexOf(entry) + direction]; - }; - - Menu.prototype.keybinds = function(e) { - var entry, next, nextPrev, subEntry, submenu; - entry = $('.focused', this.menu); - while (subEntry = $('.focused', entry)) { - entry = subEntry; - } - switch (e.keyCode) { - case 27: - lastToggledButton.focus(); - this.close(); - break; - case 13: - case 32: - entry.click(); - break; - case 38: - if (next = this.findNextEntry(entry, -1)) { - this.focus(next); - } - break; - case 40: - if (next = this.findNextEntry(entry, +1)) { - this.focus(next); - } - break; - case 39: - if ((submenu = $('.submenu', entry)) && (next = submenu.firstElementChild)) { - while (nextPrev = this.findNextEntry(next, -1)) { - next = nextPrev; - } - this.focus(next); - } - break; - case 37: - if (next = $.x('parent::*[contains(@class,"submenu")]/parent::*', entry)) { - this.focus(next); - } - break; - default: - return; - } - e.preventDefault(); - return e.stopPropagation(); - }; - - Menu.prototype.onFocus = function(e) { - e.stopPropagation(); - return this.focus(e.target); - }; - - Menu.prototype.focus = function(entry) { - var bottom, cHeight, cWidth, eRect, focused, i, left, len, ref, ref1, ref2, right, sRect, style, submenu, top; - while (focused = $.x('parent::*/child::*[contains(@class,"focused")]', entry)) { - $.rmClass(focused, 'focused'); - } - ref = $$('.focused', entry); - for (i = 0, len = ref.length; i < len; i++) { - focused = ref[i]; - $.rmClass(focused, 'focused'); - } - $.addClass(entry, 'focused'); - if (!(submenu = $('.submenu', entry))) { - return; - } - sRect = submenu.getBoundingClientRect(); - eRect = entry.getBoundingClientRect(); - cHeight = doc.clientHeight; - cWidth = doc.clientWidth; - ref1 = eRect.top + sRect.height < cHeight ? ['0px', 'auto'] : ['auto', '0px'], top = ref1[0], bottom = ref1[1]; - ref2 = eRect.right + sRect.width < cWidth - 150 ? ['100%', 'auto'] : ['auto', '100%'], left = ref2[0], right = ref2[1]; - style = submenu.style; - style.top = top; - style.bottom = bottom; - style.left = left; - return style.right = right; - }; - - Menu.prototype.addEntry = function(entry) { - this.parseEntry(entry); - return this.entries.push(entry); - }; - - Menu.prototype.parseEntry = function(entry) { - var el, i, len, subEntries, subEntry; - el = entry.el, subEntries = entry.subEntries; - $.addClass(el, 'entry'); - $.on(el, 'focus mouseover', this.onFocus); - el.style.order = entry.order || 100; - if (!subEntries) { - return; - } - $.addClass(el, 'has-submenu'); - for (i = 0, len = subEntries.length; i < len; i++) { - subEntry = subEntries[i]; - this.parseEntry(subEntry); - } - }; - - return Menu; - - })(); - - dragstart = function(e) { - var el, isTouching, o, rect, ref, screenHeight, screenWidth; - if (e.type === 'mousedown' && e.button !== 0) { - return; - } - e.preventDefault(); - if (isTouching = e.type === 'touchstart') { - e = e.changedTouches[e.changedTouches.length - 1]; - } - el = $.x('ancestor::div[contains(@class,"dialog")][1]', this); - rect = el.getBoundingClientRect(); - screenHeight = doc.clientHeight; - screenWidth = doc.clientWidth; - o = { - id: el.id, - style: el.style, - dx: e.clientX - rect.left, - dy: e.clientY - rect.top, - height: screenHeight - rect.height, - width: screenWidth - rect.width, - screenHeight: screenHeight, - screenWidth: screenWidth, - isTouching: isTouching - }; - ref = Conf['Header auto-hide'] || !Conf['Fixed Header'] ? [0, 0] : Conf['Bottom Header'] ? [0, Header.bar.getBoundingClientRect().height] : [Header.bar.getBoundingClientRect().height, 0], o.topBorder = ref[0], o.bottomBorder = ref[1]; - if (isTouching) { - o.identifier = e.identifier; - o.move = touchmove.bind(o); - o.up = touchend.bind(o); - $.on(d, 'touchmove', o.move); - return $.on(d, 'touchend touchcancel', o.up); - } else { - o.move = drag.bind(o); - o.up = dragend.bind(o); - $.on(d, 'mousemove', o.move); - return $.on(d, 'mouseup', o.up); - } - }; - - touchmove = function(e) { - var i, len, ref, touch; - ref = e.changedTouches; - for (i = 0, len = ref.length; i < len; i++) { - touch = ref[i]; - if (touch.identifier === this.identifier) { - drag.call(this, touch); - return; - } - } - }; - - drag = function(e) { - var bottom, clientX, clientY, left, right, style, top; - clientX = e.clientX, clientY = e.clientY; - left = clientX - this.dx; - left = left < 10 ? 0 : this.width - left < 10 ? '' : left / this.screenWidth * 100 + '%'; - top = clientY - this.dy; - top = top < (10 + this.topBorder) ? this.topBorder + 'px' : this.height - top < (10 + this.bottomBorder) ? '' : top / this.screenHeight * 100 + '%'; - right = left === '' ? 0 : ''; - bottom = top === '' ? this.bottomBorder + 'px' : ''; - style = this.style; - style.left = left; - style.right = right; - style.top = top; - return style.bottom = bottom; - }; - - touchend = function(e) { - var i, len, ref, touch; - ref = e.changedTouches; - for (i = 0, len = ref.length; i < len; i++) { - touch = ref[i]; - if (touch.identifier === this.identifier) { - dragend.call(this); - return; - } - } - }; - - dragend = function() { - if (this.isTouching) { - $.off(d, 'touchmove', this.move); - $.off(d, 'touchend touchcancel', this.up); - } else { - $.off(d, 'mousemove', this.move); - $.off(d, 'mouseup', this.up); - } - return $.set(this.id + ".position", this.style.cssText); - }; - - hoverstart = function(arg) { - var cb, el, endEvents, height, latestEvent, noRemove, o, rect, ref, root, width; - root = arg.root, el = arg.el, latestEvent = arg.latestEvent, endEvents = arg.endEvents, height = arg.height, width = arg.width, cb = arg.cb, noRemove = arg.noRemove; - rect = root.getBoundingClientRect(); - o = { - root: root, - el: el, - style: el.style, - isImage: (ref = el.nodeName) === 'IMG' || ref === 'VIDEO', - cb: cb, - endEvents: endEvents, - latestEvent: latestEvent, - clientHeight: doc.clientHeight, - clientWidth: doc.clientWidth, - height: height, - width: width, - noRemove: noRemove, - clientX: (rect.left + rect.right) / 2, - clientY: (rect.top + rect.bottom) / 2 - }; - o.hover = hover.bind(o); - o.hoverend = hoverend.bind(o); - o.hover(o.latestEvent); - new MutationObserver(function() { - if (el.parentNode) { - return o.hover(o.latestEvent); - } - }).observe(el, { - childList: true - }); - $.on(root, endEvents, o.hoverend); - if ($.x('ancestor::div[contains(@class,"inline")][1]', root)) { - $.on(d, 'keydown', o.hoverend); - } - $.on(root, 'mousemove', o.hover); - o.workaround = function(e) { - if (!root.contains(e.target)) { - return o.hoverend(e); - } - }; - return $.on(doc, 'mousemove', o.workaround); - }; - - hoverstart.padding = 25; - - hover = function(e) { - var clientX, clientY, height, left, marginX, ref, ref1, right, style, threshold, top, width; - this.latestEvent = e; - height = (this.height || this.el.offsetHeight) + hoverstart.padding; - width = this.width || this.el.offsetWidth; - ref = Conf['Follow Cursor'] ? e : this, clientX = ref.clientX, clientY = ref.clientY; - top = this.isImage ? Math.max(0, clientY * (this.clientHeight - height) / this.clientHeight) : Math.max(0, Math.min(this.clientHeight - height, clientY - 120)); - threshold = this.clientWidth / 2; - if (!this.isImage) { - threshold = Math.max(threshold, this.clientWidth - 400); - } - marginX = (clientX <= threshold ? clientX : this.clientWidth - clientX) + 45; - if (this.isImage) { - marginX = Math.min(marginX, this.clientWidth - width); - } - marginX += 'px'; - ref1 = clientX <= threshold ? [marginX, ''] : ['', marginX], left = ref1[0], right = ref1[1]; - style = this.style; - style.top = top + 'px'; - style.left = left; - return style.right = right; - }; - - hoverend = function(e) { - if (e.type === 'keydown' && e.keyCode !== 13 || e.target.nodeName === "TEXTAREA") { - return; - } - if (!this.noRemove) { - $.rm(this.el); - } - $.off(this.root, this.endEvents, this.hoverend); - $.off(d, 'keydown', this.hoverend); - $.off(this.root, 'mousemove', this.hover); - $.off(doc, 'mousemove', this.workaround); - if (this.cb) { - return this.cb.call(this); - } - }; - - checkbox = function(name, text, checked) { - var input, label; - if (checked == null) { - checked = Conf[name]; - } - label = $.el('label'); - input = $.el('input', { - type: 'checkbox', - name: name, - checked: checked - }); - $.add(label, [input, $.tn(" " + text)]); - return label; - }; - - UI = { - dialog: dialog, - Menu: Menu, - hover: hoverstart, - checkbox: checkbox - }; - - return UI; - -}).call(this); - -FappeTyme = (function() { - var FappeTyme; - - FappeTyme = { - init: function() { - var el, i, indicator, lc, len, ref, ref1, type; - if (!((Conf['Fappe Tyme'] || Conf['Werk Tyme']) && ((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive'))) { - return; - } - this.nodes = {}; - this.enabled = { - fappe: false, - werk: Conf['werk'] - }; - ref1 = ["Fappe", "Werk"]; - for (i = 0, len = ref1.length; i < len; i++) { - type = ref1[i]; - if (!Conf[type + " Tyme"]) { - continue; - } - lc = type.toLowerCase(); - el = UI.checkbox(lc, type + " Tyme", false); - el.title = type + " Tyme"; - this.nodes[lc] = el.firstElementChild; - if (Conf[lc]) { - this.set(lc, true); - } - $.on(this.nodes[lc], 'change', this.toggle.bind(this, lc)); - Header.menu.addEntry({ - el: el, - order: 97 - }); - indicator = $.el('span', { - className: 'indicator', - textContent: type[0], - title: type + " Tyme active" - }); - $.on(indicator, 'click', function() { - var check; - check = $.getOwn(FappeTyme.nodes, this.parentNode.id.replace('shortcut-', '')); - check.checked = !check.checked; - return $.event('change', null, check); - }); - Header.addShortcut(lc, indicator, 410); - } - if (Conf['Werk Tyme']) { - $.sync('werk', this.set.bind(this, 'werk')); - } - Callbacks.Post.push({ - name: 'Fappe Tyme', - cb: this.node - }); - return Callbacks.CatalogThread.push({ - name: 'Werk Tyme', - cb: this.catalogNode - }); - }, - node: function() { - return this.nodes.root.classList.toggle('noFile', !this.files.length); - }, - catalogNode: function() { - var file, filename; - file = this.thread.OP.files[0]; - if (!file) { - return; - } - filename = $.el('div', { - textContent: file.name, - className: 'werkTyme-filename' - }); - return $.add(this.nodes.thumb.parentNode, filename); - }, - set: function(type, enabled) { - this.enabled[type] = this.nodes[type].checked = enabled; - return $[(enabled ? 'add' : 'rm') + "Class"](doc, type + "Tyme"); - }, - toggle: function(type) { - this.set(type, !this.enabled[type]); - if (type === 'werk') { - return $.cb.checked.call(this.nodes[type]); - } - } - }; - - return FappeTyme; - -}).call(this); - -Gallery = (function() { - var Gallery; - - Gallery = { - init: function() { - var el, ref; - if (!(this.enabled = Conf['Gallery'] && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - this.delay = Conf['Slide Delay']; - el = $.el('a', { - href: 'javascript:;', - title: 'Gallery', - className: 'fa fa-picture-o', - textContent: 'Gallery' - }); - $.on(el, 'click', this.cb.toggle); - Header.addShortcut('gallery', el, 530); - return Callbacks.Post.push({ - name: 'Gallery', - cb: this.node - }); - }, - node: function() { - var file, i, len, ref, results; - ref = this.files; - results = []; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if (!file.thumb) { - continue; - } - if (Gallery.nodes) { - Gallery.generateThumb(this, file); - Gallery.nodes.total.textContent = Gallery.images.length; - } - if (!(Conf['Image Expansion'] || (g.SITE.software === 'tinyboard' && Main.jsEnabled))) { - results.push($.on(file.thumbLink, 'click', Gallery.cb.image)); - } else { - results.push(void 0); - } - } - return results; - }, - build: function(image) { - var candidate, cb, dialog, entry, file, i, j, k, key, len, len1, len2, menuButton, nodes, post, postThumb, ref, ref1, ref2, ref3, thumb, value; - cb = Gallery.cb; - if (Conf['Fullscreen Gallery']) { - $.one(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', function() { - return $.on(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', cb.close); - }); - if (typeof doc.mozRequestFullScreen === "function") { - doc.mozRequestFullScreen(); - } - if (typeof doc.webkitRequestFullScreen === "function") { - doc.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT); - } - } - Gallery.images = []; - nodes = Gallery.nodes = {}; - Gallery.fileIDs = $.dict(); - Gallery.slideshow = false; - nodes.el = dialog = $.el('div', { - id: 'a-gallery' - }); - $.extend(dialog, {innerHTML: "
    ×
    /
    "}); - ref = { - 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 (key in ref) { - value = ref[key]; - nodes[key] = $(value, dialog); - } - menuButton = $('.menu-button', dialog); - nodes.menu = new UI.Menu('gallery'); - $.on(nodes.frame, 'click', cb.blank); - if (Conf['Mouse Wheel Volume']) { - $.on(nodes.frame, 'wheel', Volume.wheel); - } - $.on(nodes.next, 'click', cb.click); - $.on(nodes.name, 'click', ImageCommon.download); - $.on($('.gal-prev', dialog), 'click', cb.prev); - $.on($('.gal-next', dialog), 'click', cb.next); - $.on($('.gal-start', dialog), 'click', cb.start); - $.on($('.gal-stop', dialog), 'click', cb.stop); - $.on($('.gal-close', dialog), 'click', cb.close); - $.on(menuButton, 'click', function(e) { - return nodes.menu.toggle(e, this, g); - }); - ref1 = Gallery.menu.createSubEntries(); - for (i = 0, len = ref1.length; i < len; i++) { - entry = ref1[i]; - entry.order = 0; - nodes.menu.addEntry(entry); - } - $.on(d, 'keydown', cb.keybinds); - if (Conf['Keybinds']) { - $.off(d, 'keydown', Keybinds.keydown); - } - $.on(window, 'resize', Gallery.cb.setHeight); - ref2 = $$(g.SITE.selectors.file.thumb); - for (j = 0, len1 = ref2.length; j < len1; j++) { - postThumb = ref2[j]; - if (!(post = Get.postFromNode(postThumb))) { - continue; - } - ref3 = post.files; - for (k = 0, len2 = ref3.length; k < len2; k++) { - file = ref3[k]; - if (!file.thumb) { - continue; - } - Gallery.generateThumb(post, file); - if (!image && Gallery.fileIDs[post.fullID + "." + file.index]) { - candidate = file.thumbLink; - if (Header.getTopOf(candidate) + candidate.getBoundingClientRect().height >= 0) { - image = candidate; - } - } - } - } - $.addClass(doc, 'gallery-open'); - $.add(d.body, dialog); - nodes.thumbs.scrollTop = 0; - nodes.current.parentElement.scrollTop = 0; - if (image) { - thumb = $("[href='" + image.href + "']", nodes.thumbs); - } - thumb || (thumb = Gallery.images[Gallery.images.length - 1]); - if (thumb) { - Gallery.open(thumb); - } - doc.style.overflow = 'hidden'; - return nodes.total.textContent = Gallery.images.length; - }, - generateThumb: function(post, file) { - var thumb, thumbImg; - if (post.isClone || post.isHidden) { - return; - } - if (!(file && file.thumb && (file.isImage || file.isVideo || Conf['PDF in Gallery']))) { - return; - } - if (Gallery.fileIDs[post.fullID + "." + file.index]) { - return; - } - Gallery.fileIDs[post.fullID + "." + file.index] = true; - thumb = $.el('a', { - className: 'gal-thumb', - href: file.url, - target: '_blank', - title: file.name - }); - thumb.dataset.id = Gallery.images.length; - thumb.dataset.post = post.fullID; - thumb.dataset.file = file.index; - thumbImg = file.thumb.cloneNode(false); - thumbImg.style.cssText = ''; - $.add(thumb, thumbImg); - $.on(thumb, 'click', Gallery.cb.open); - Gallery.images.push(thumb); - return $.add(Gallery.nodes.thumbs, thumb); - }, - load: function(thumb, errorCB) { - var elType, ext, file; - ext = thumb.href.match(/\w*$/); - elType = $.getOwn({ - 'webm': 'video', - 'mp4': 'video', - 'ogv': 'video', - 'pdf': 'iframe' - }, ext) || 'img'; - file = $.el(elType); - $.extend(file.dataset, thumb.dataset); - $.on(file, 'error', errorCB); - file.src = thumb.href; - return file; - }, - open: function(thumb) { - var el, file, i, len, link, newID, node, nodes, oldID, post, ref, ref1, sauces; - nodes = Gallery.nodes; - oldID = +nodes.current.dataset.id; - newID = +thumb.dataset.id; - if (el = Gallery.images[oldID]) { - $.rmClass(el, 'gal-highlight'); - } - $.addClass(thumb, 'gal-highlight'); - nodes.thumbs.scrollTop = thumb.offsetTop + thumb.offsetHeight / 2 - nodes.thumbs.clientHeight / 2; - if (((ref = Gallery.cache) != null ? ref.dataset.id : void 0) === '' + newID) { - file = Gallery.cache; - $.off(file, 'error', Gallery.cacheError); - $.on(file, 'error', Gallery.error); - } else { - file = Gallery.load(thumb, Gallery.error); - } - $.off(nodes.current, 'error', Gallery.error); - ImageCommon.pause(nodes.current); - $.replace(nodes.current, file); - nodes.current = file; - if (file.nodeName === 'VIDEO') { - file.loop = true; - Volume.setup(file); - if (Conf['Autoplay']) { - file.play(); - } - if (Conf['Show Controls']) { - ImageCommon.addControls(file); - } - } - doc.classList.toggle('gal-pdf', file.nodeName === 'IFRAME'); - Gallery.cb.setHeight(); - nodes.count.textContent = +thumb.dataset.id + 1; - nodes.name.download = nodes.name.textContent = thumb.title; - nodes.name.href = thumb.href; - nodes.frame.scrollTop = 0; - nodes.next.focus(); - $.rmAll(nodes.sauce); - if (Conf['Sauce'] && Sauce.links && (post = g.posts.get(file.dataset.post))) { - sauces = []; - ref1 = Sauce.links; - for (i = 0, len = ref1.length; i < len; i++) { - link = ref1[i]; - if ((node = Sauce.createSauceLink(link, post, post.files[+file.dataset.file]))) { - sauces.push($.tn(' '), node); - } - } - $.add(nodes.sauce, sauces); - } - if (Gallery.slideshow && (newID > oldID || (oldID === Gallery.images.length - 1 && newID === 0))) { - Gallery.setupTimer(); - } else { - Gallery.cb.stop(); - } - if (Conf['Scroll to Post'] && (post = g.posts.get(file.dataset.post))) { - Header.scrollTo(post.nodes.root); - } - if (isNaN(oldID) || newID === (oldID + 1) % Gallery.images.length) { - return Gallery.cache = Gallery.load(Gallery.images[(newID + 1) % Gallery.images.length], Gallery.cacheError); - } - }, - error: function() { - var file, post, ref; - if (((ref = this.error) != null ? ref.code : void 0) === MediaError.MEDIA_ERR_DECODE) { - return new Notice('error', 'Corrupt or unplayable video', 30); - } - if (ImageCommon.isFromArchive(this)) { - return; - } - post = g.posts.get(this.dataset.post); - file = post.files[+this.dataset.file]; - return ImageCommon.error(this, post, file, null, (function(_this) { - return function(url) { - if (!url) { - return; - } - Gallery.images[+_this.dataset.id].href = url; - if (Gallery.nodes.current === _this) { - return _this.src = url; - } - }; - })(this)); - }, - cacheError: function() { - return delete Gallery.cache; - }, - cleanupTimer: function() { - var current; - clearTimeout(Gallery.timeoutID); - current = Gallery.nodes.current; - $.off(current, 'canplaythrough load', Gallery.startTimer); - return $.off(current, 'ended', Gallery.cb.next); - }, - startTimer: function() { - return Gallery.timeoutID = setTimeout(Gallery.checkTimer, Gallery.delay * $.SECOND); - }, - setupTimer: function() { - var current, isVideo; - Gallery.cleanupTimer(); - current = Gallery.nodes.current; - isVideo = current.nodeName === 'VIDEO'; - if (isVideo) { - current.play(); - } - if ((isVideo ? current.readyState >= 4 : current.complete) || current.nodeName === 'IFRAME') { - return Gallery.startTimer(); - } else { - return $.on(current, (isVideo ? 'canplaythrough' : 'load'), Gallery.startTimer); - } - }, - checkTimer: function() { - var current; - current = Gallery.nodes.current; - if (current.nodeName === 'VIDEO' && !current.paused) { - $.on(current, 'ended', Gallery.cb.next); - return current.loop = false; - } else { - return Gallery.cb.next(); - } - }, - cb: { - keybinds: function(e) { - var cb, key; - if (!(key = Keybinds.keyCode(e))) { - return; - } - cb = (function() { - switch (key) { - case Conf['Close']: - case Conf['Open Gallery']: - return Gallery.cb.close; - case Conf['Next Gallery Image']: - return Gallery.cb.next; - case Conf['Advance Gallery']: - return Gallery.cb.advance; - case Conf['Previous Gallery Image']: - return Gallery.cb.prev; - case Conf['Pause']: - return Gallery.cb.pause; - case Conf['Slideshow']: - return Gallery.cb.toggleSlideshow; - case Conf['Rotate image anticlockwise']: - return Gallery.cb.rotateLeft; - case Conf['Rotate image clockwise']: - return Gallery.cb.rotateRight; - case Conf['Download Gallery Image']: - return Gallery.cb.download; - } - })(); - if (!cb) { - return; - } - e.stopPropagation(); - e.preventDefault(); - return cb(); - }, - open: function(e) { - if (e) { - e.preventDefault(); - } - if (this) { - return Gallery.open(this); - } - }, - image: function(e) { - e.preventDefault(); - e.stopPropagation(); - return Gallery.build(this); - }, - prev: function() { - return Gallery.cb.open.call(Gallery.images[+Gallery.nodes.current.dataset.id - 1] || Gallery.images[Gallery.images.length - 1]); - }, - next: function() { - return Gallery.cb.open.call(Gallery.images[+Gallery.nodes.current.dataset.id + 1] || Gallery.images[0]); - }, - click: function(e) { - if (ImageCommon.onControls(e)) { - return; - } - e.preventDefault(); - return Gallery.cb.advance(); - }, - advance: function() { - if (!Conf['Autoplay'] && Gallery.nodes.current.paused) { - return Gallery.nodes.current.play(); - } else { - return Gallery.cb.next(); - } - }, - toggle: function() { - return (Gallery.nodes ? Gallery.cb.close : Gallery.build)(); - }, - blank: function(e) { - if (e.target === this) { - return Gallery.cb.close(); - } - }, - toggleSlideshow: function() { - return Gallery.cb[Gallery.slideshow ? 'stop' : 'start'](); - }, - download: function() { - var name; - name = $('.gal-name'); - return name.click(); - }, - pause: function() { - var current; - Gallery.cb.stop(); - current = Gallery.nodes.current; - if (current.nodeName === 'VIDEO') { - return current[current.paused ? 'play' : 'pause'](); - } - }, - start: function() { - $.addClass(Gallery.nodes.buttons, 'gal-playing'); - Gallery.slideshow = true; - return Gallery.setupTimer(); - }, - stop: function() { - var current; - if (!Gallery.slideshow) { - return; - } - Gallery.cleanupTimer(); - current = Gallery.nodes.current; - if (current.nodeName === 'VIDEO') { - current.loop = true; - } - $.rmClass(Gallery.nodes.buttons, 'gal-playing'); - return Gallery.slideshow = false; - }, - rotateLeft: function() { - return Gallery.cb.rotate(270); - }, - rotateRight: function() { - return Gallery.cb.rotate(90); - }, - rotate: $.debounce(100, function(delta) { - var current; - current = Gallery.nodes.current; - if (current.nodeName === 'IFRAME') { - return; - } - current.dataRotate = ((current.dataRotate || 0) + delta) % 360; - current.style.transform = "rotate(" + current.dataRotate + "deg)"; - return Gallery.cb.setHeight(); - }), - close: function() { - $.off(Gallery.nodes.current, 'error', Gallery.error); - ImageCommon.pause(Gallery.nodes.current); - $.rm(Gallery.nodes.el); - $.rmClass(doc, 'gallery-open'); - if (Conf['Fullscreen Gallery']) { - $.off(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', Gallery.cb.close); - if (typeof d.mozCancelFullScreen === "function") { - d.mozCancelFullScreen(); - } - if (typeof d.webkitExitFullscreen === "function") { - d.webkitExitFullscreen(); - } - } - delete Gallery.nodes; - delete Gallery.fileIDs; - doc.style.overflow = ''; - $.off(d, 'keydown', Gallery.cb.keybinds); - if (Conf['Keybinds']) { - $.on(d, 'keydown', Keybinds.keydown); - } - $.off(window, 'resize', Gallery.cb.setHeight); - return clearTimeout(Gallery.timeoutID); - }, - setFitness: function() { - return (this.checked ? $.addClass : $.rmClass)(doc, "gal-" + (this.name.toLowerCase().replace(/\s+/g, '-'))); - }, - setHeight: $.debounce(100, function() { - var containerHeight, containerWidth, current, dim, frame, height, margin, minHeight, ref, ref1, ref2, ref3, style, width; - ref = Gallery.nodes, current = ref.current, frame = ref.frame; - style = current.style; - if (Conf['Stretch to Fit'] && (dim = (ref1 = g.posts.get(current.dataset.post)) != null ? ref1.files[+current.dataset.file].dimensions : void 0)) { - ref2 = dim.split('x'), width = ref2[0], height = ref2[1]; - containerWidth = frame.clientWidth; - containerHeight = doc.clientHeight - 25; - if ((current.dataRotate || 0) % 180 === 90) { - ref3 = [containerHeight, containerWidth], containerWidth = ref3[0], containerHeight = ref3[1]; - } - minHeight = Math.min(containerHeight, height / width * containerWidth); - style.minHeight = minHeight + 'px'; - style.minWidth = (width / height * minHeight) + 'px'; - } else { - style.minHeight = style.minWidth = ''; - } - if ((current.dataRotate || 0) % 180 === 90) { - style.maxWidth = Conf['Fit Height'] ? (doc.clientHeight - 25) + "px" : 'none'; - style.maxHeight = Conf['Fit Width'] ? frame.clientWidth + "px" : 'none'; - margin = (current.clientWidth - current.clientHeight) / 2; - return style.margin = margin + "px " + (-margin) + "px"; - } else { - return style.maxWidth = style.maxHeight = style.margin = ''; - } - }), - setDelay: function() { - return Gallery.delay = +this.value; - } - }, - menu: { - init: function() { - var el; - if (!Gallery.enabled) { - return; - } - el = $.el('span', { - textContent: 'Gallery', - className: 'gallery-link' - }); - return Header.menu.addEntry({ - el: el, - order: 105, - subEntries: Gallery.menu.createSubEntries() - }); - }, - createSubEntry: function(name) { - var input, label; - label = UI.checkbox(name, name); - input = label.firstElementChild; - if (name === 'Hide Thumbnails' || name === 'Fit Width' || name === 'Fit Height') { - $.on(input, 'change', Gallery.cb.setFitness); - } - $.event('change', null, input); - $.on(input, 'change', $.cb.checked); - if (name === 'Hide Thumbnails' || name === 'Fit Width' || name === 'Fit Height' || name === 'Stretch to Fit') { - $.on(input, 'change', Gallery.cb.setHeight); - } - return { - el: label - }; - }, - createSubEntries: function() { - var delayInput, delayLabel, item, subEntries; - subEntries = (function() { - var i, len, ref, results; - ref = ['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Stretch to Fit', 'Scroll to Post']; - results = []; - for (i = 0, len = ref.length; i < len; i++) { - item = ref[i]; - results.push(Gallery.menu.createSubEntry(item)); - } - return results; - })(); - delayLabel = $.el('label', {innerHTML: "Slide Delay: "}); - delayInput = delayLabel.firstElementChild; - delayInput.value = Gallery.delay; - $.on(delayInput, 'change', Gallery.cb.setDelay); - $.on(delayInput, 'change', $.cb.value); - subEntries.push({ - el: delayLabel - }); - return subEntries; - } - } - }; - - return Gallery; - -}).call(this); - -ImageCommon = (function() { - var ImageCommon, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - ImageCommon = { - pause: function(video) { - if (video.nodeName !== 'VIDEO') { - return; - } - video.pause(); - $.off(video, 'volumechange', Volume.change); - return video.muted = true; - }, - rewind: function(el) { - if (el.nodeName === 'VIDEO') { - if (el.readyState >= el.HAVE_METADATA) { - return el.currentTime = 0; - } - } else if (/\.gif$/.test(el.src)) { - return $.queueTask(function() { - return el.src = el.src; - }); - } - }, - pushCache: function(el) { - ImageCommon.cache = el; - return $.on(el, 'error', ImageCommon.cacheError); - }, - popCache: function() { - var el; - el = ImageCommon.cache; - $.off(el, 'error', ImageCommon.cacheError); - delete ImageCommon.cache; - return el; - }, - cacheError: function() { - if (ImageCommon.cache === this) { - return delete ImageCommon.cache; - } - }, - decodeError: function(file, fileObj) { - var message, ref; - if (((ref = file.error) != null ? ref.code : void 0) !== MediaError.MEDIA_ERR_DECODE) { - return false; - } - if (!(message = $('.warning', fileObj.thumb.parentNode))) { - message = $.el('div', { - className: 'warning' - }); - $.after(fileObj.thumb, message); - } - message.textContent = 'Error: Corrupt or unplayable video'; - return true; - }, - isFromArchive: function(file) { - return g.SITE.software === 'yotsuba' && !ImageHost.test(file.src.split('/')[2]); - }, - error: function(file, post, fileObj, delay, cb) { - var base, parseJSON, redirect, src, threadJSON, timeoutID, url; - src = fileObj.url.split('/'); - url = null; - if (g.SITE.software === 'yotsuba' && Conf['404 Redirect']) { - url = Redirect.to('file', { - boardID: post.board.ID, - filename: src[src.length - 1] - }); - } - if (!(url && Redirect.securityCheck(url))) { - url = null; - } - if ((post.isDead || fileObj.isDead) && !ImageCommon.isFromArchive(file)) { - return cb(url); - } - if (delay != null) { - timeoutID = setTimeout((function() { - return cb(url); - }), delay); - } - if (post.isDead || fileObj.isDead) { - return; - } - redirect = function() { - if (!ImageCommon.isFromArchive(file)) { - if (delay != null) { - clearTimeout(timeoutID); - } - return cb(url); - } - }; - threadJSON = typeof (base = g.SITE.urls).threadJSON === "function" ? base.threadJSON(post) : void 0; - if (!threadJSON) { - return; - } - parseJSON = function(isArchiveURL) { - var archivedThreadJSON, base1, i, len, postObj, ref, ref1; - if (this.status === 404) { - if (!isArchiveURL && (archivedThreadJSON = typeof (base1 = g.SITE.urls).archivedThreadJSON === "function" ? base1.archivedThreadJSON(post) : void 0)) { - $.ajax(archivedThreadJSON, { - onloadend: function() { - return parseJSON.call(this, true); - } - }); - } else { - post.kill(!post.isClone, fileObj.index); - } - } - if (this.status !== 200) { - return redirect(); - } - ref = this.response.posts; - for (i = 0, len = ref.length; i < len; i++) { - postObj = ref[i]; - if (postObj.no === post.ID) { - break; - } - } - if (postObj.no !== post.ID) { - post.kill(); - return redirect(); - } else if (ref1 = fileObj.docIndex, indexOf.call(g.SITE.Build.parseJSON(postObj, post.board).filesDeleted, ref1) >= 0) { - post.kill(true); - return redirect(); - } else { - return url = fileObj.url; - } - }; - return $.ajax(threadJSON, { - onloadend: function() { - return parseJSON.call(this); - } - }); - }, - addControls: function(video) { - var handler; - handler = function() { - var t; - $.off(video, 'mouseover', handler); - t = new Date().getTime(); - return $.asap((function() { - return $.engine !== 'gecko' || (video.readyState >= 3 && video.currentTime <= Math.max(0.1, video.duration - 0.5)) || new Date().getTime() >= t + 1000; - }), function() { - return video.controls = true; - }); - }; - return $.on(video, 'mouseover', handler); - }, - onControls: function(e) { - return (Conf['Show Controls'] && Conf['Click Passthrough'] && e.target.nodeName === 'VIDEO') || (e.target.controls && e.target.getBoundingClientRect().bottom - e.clientY < 35); - }, - download: function(e) { - var download, href, ref; - if (this.protocol === 'blob:') { - return true; - } - e.preventDefault(); - ref = this, href = ref.href, download = ref.download; - return CrossOrigin.file(href, function(blob) { - var a; - if (blob) { - a = $.el('a', { - href: URL.createObjectURL(blob), - download: download, - hidden: true - }); - $.add(d.body, a); - a.click(); - return $.rm(a); - } else { - return new Notice('warning', "Could not download " + href, 20); - } - }); - } - }; - - return ImageCommon; - -}).call(this); - -ImageExpand = (function() { - var ImageExpand, - slice = [].slice; - - ImageExpand = { - init: function() { - var ref; - if (!(this.enabled = Conf['Image Expansion'] && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - this.EAI = $.el('a', { - className: 'expand-all-shortcut fa fa-expand', - textContent: 'EAI', - title: 'Expand All Images', - href: 'javascript:;' - }); - $.on(this.EAI, 'click', this.cb.toggleAll); - Header.addShortcut('expand-all', this.EAI, 520); - $.on(d, 'scroll visibilitychange', this.cb.playVideos); - this.videoControls = $.el('span', { - className: 'video-controls' - }); - $.extend(this.videoControls, {innerHTML: " contract"}); - return Callbacks.Post.push({ - name: 'Image Expansion', - cb: this.node - }); - }, - node: function() { - var ref; - if (!(this.file && (this.file.isImage || this.file.isVideo))) { - return; - } - $.on(this.file.thumbLink, 'click', ImageExpand.cb.toggle); - if (this.isClone) { - if (this.file.isExpanding) { - ImageExpand.contract(this); - return ImageExpand.expand(this); - } else if (this.file.isExpanded && this.file.isVideo) { - Volume.setup(this.file.fullImage); - ImageExpand.setupVideoCB(this); - return ImageExpand.setupVideo(this, !((ref = this.origin.file.fullImage) != null ? ref.paused : void 0) || this.origin.file.wasPlaying, this.file.fullImage.controls); - } - } else if (ImageExpand.on && !this.isHidden && !this.isFetchedQuote && (Conf['Expand spoilers'] || !this.file.isSpoiler) && (Conf['Expand videos'] || !this.file.isVideo)) { - return ImageExpand.expand(this); - } - }, - cb: { - toggle: function(e) { - var file, post, ref; - if ($.modifiedClick(e)) { - return; - } - post = Get.postFromNode(this); - file = post.file; - if (file.isExpanded && ImageCommon.onControls(e)) { - return; - } - e.preventDefault(); - if (!Conf['Autoplay'] && ((ref = file.fullImage) != null ? ref.paused : void 0)) { - return file.fullImage.play(); - } else { - return ImageExpand.toggle(post); - } - }, - toggleAll: function() { - var func, threadRoot, toggle; - $.event('CloseMenu'); - threadRoot = Nav.getThread(); - toggle = function(post) { - var file; - file = post.file; - if (!(file && (file.isImage || file.isVideo) && doc.contains(post.nodes.root))) { - return; - } - if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || !Conf['Expand videos'] && file.isVideo || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0 || Conf['Expand thread only'] && g.VIEW === 'index' && !(threadRoot != null ? threadRoot.contains(file.thumb) : void 0))) { - return; - } - return $.queueTask(func, post); - }; - if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) { - ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress'; - ImageExpand.EAI.title = 'Contract All Images'; - func = ImageExpand.expand; - } else { - ImageExpand.EAI.className = 'expand-all-shortcut fa fa-expand'; - ImageExpand.EAI.title = 'Expand All Images'; - func = ImageExpand.contract; - } - return g.posts.forEach(function(post) { - var i, len, ref; - ref = [post].concat(slice.call(post.clones)); - for (i = 0, len = ref.length; i < len; i++) { - post = ref[i]; - toggle(post); - } - }); - }, - playVideos: function() { - return g.posts.forEach(function(post) { - var file, i, len, ref, video, visible; - ref = [post].concat(slice.call(post.clones)); - for (i = 0, len = ref.length; i < len; i++) { - post = ref[i]; - file = post.file; - if (!(file && file.isVideo && file.isExpanded)) { - continue; - } - video = file.fullImage; - visible = ($.hasAudio(video) && !video.muted) || Header.isNodeVisible(video); - if (visible && file.wasPlaying) { - delete file.wasPlaying; - video.play(); - } else if (!visible && !video.paused) { - file.wasPlaying = true; - video.pause(); - } - } - }); - }, - setFitness: function() { - return $[this.checked ? 'addClass' : 'rmClass'](doc, this.name.toLowerCase().replace(/\s+/g, '-')); - } - }, - toggle: function(post) { - var next; - if (!(post.file.isExpanding || post.file.isExpanded)) { - post.file.scrollIntoView = Conf['Scroll into view']; - ImageExpand.expand(post); - return; - } - ImageExpand.contract(post); - if (Conf['Advance on contract']) { - next = post.nodes.root; - while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) { - if (!($('.stub', next) || next.offsetHeight === 0)) { - break; - } - } - if (next) { - return Header.scrollTo(next); - } - } - }, - contract: function(post) { - var bottom, cb, el, eventName, file, i, len, oldHeight, ref, ref1, scrollY, top, x; - file = post.file; - if (el = file.fullImage) { - top = Header.getTopOf(el); - bottom = top + el.getBoundingClientRect().height; - oldHeight = d.body.clientHeight; - scrollY = window.scrollY; - } - $.rmClass(post.nodes.root, 'expanded-image'); - $.rmClass(file.thumb, 'expanding'); - $.rm(file.videoControls); - file.thumbLink.href = file.url; - file.thumbLink.target = '_blank'; - ref = ['isExpanding', 'isExpanded', 'videoControls', 'wasPlaying', 'scrollIntoView']; - for (i = 0, len = ref.length; i < len; i++) { - x = ref[i]; - delete file[x]; - } - if (!el) { - return; - } - if (doc.contains(el)) { - if (bottom <= 0) { - window.scrollBy(0, scrollY - window.scrollY + d.body.clientHeight - oldHeight); - } else { - Header.scrollToIfNeeded(post.nodes.root); - } - if (window.scrollX > 0) { - window.scrollBy(-window.scrollX, 0); - } - } - $.off(el, 'error', ImageExpand.error); - ImageCommon.pushCache(el); - if (file.isVideo) { - ImageCommon.pause(el); - ref1 = ImageExpand.videoCB; - for (eventName in ref1) { - cb = ref1[eventName]; - $.off(el, eventName, cb); - } - } - if (Conf['Restart when Opened']) { - ImageCommon.rewind(file.thumb); - } - delete file.fullImage; - return $.queueTask(function() { - if (file.isExpanding || file.isExpanded) { - return; - } - $.rmClass(el, 'full-image'); - if (el.id) { - return; - } - return $.rm(el); - }); - }, - expand: function(post, src) { - var el, file, isVideo, ref, thumb, thumbLink; - file = post.file; - thumb = file.thumb, thumbLink = file.thumbLink, isVideo = file.isVideo; - if (post.isHidden || file.isExpanding || file.isExpanded) { - return; - } - $.addClass(thumb, 'expanding'); - file.isExpanding = true; - if (file.fullImage) { - el = file.fullImage; - } else if (((ref = ImageCommon.cache) != null ? ref.dataset.fileID : void 0) === (post.fullID + "." + file.index)) { - el = file.fullImage = ImageCommon.popCache(); - $.on(el, 'error', ImageExpand.error); - if (Conf['Restart when Opened'] && el.id !== 'ihover') { - ImageCommon.rewind(el); - } - el.removeAttribute('id'); - } else { - el = file.fullImage = $.el((isVideo ? 'video' : 'img')); - el.dataset.fileID = post.fullID + "." + file.index; - $.on(el, 'error', ImageExpand.error); - el.src = src || file.url; - } - el.className = 'full-image'; - $.after(thumb, el); - if (isVideo) { - if (!file.videoControls) { - file.videoControls = ImageExpand.videoControls.cloneNode(true); - $.add(file.text, file.videoControls); - } - thumbLink.removeAttribute('href'); - thumbLink.removeAttribute('target'); - el.loop = true; - Volume.setup(el); - ImageExpand.setupVideoCB(post); - } - if (!isVideo) { - return $.asap((function() { - return el.naturalHeight; - }), function() { - return ImageExpand.completeExpand(post); - }); - } else if (el.readyState >= el.HAVE_METADATA) { - return ImageExpand.completeExpand(post); - } else { - return $.on(el, 'loadedmetadata', function() { - return ImageExpand.completeExpand(post); - }); - } - }, - completeExpand: function(post) { - var bottom, file, imageBottom, oldHeight, scrollY; - file = post.file; - if (!file.isExpanding) { - return; - } - bottom = Header.getTopOf(file.thumb) + file.thumb.getBoundingClientRect().height; - oldHeight = d.body.clientHeight; - scrollY = window.scrollY; - $.addClass(post.nodes.root, 'expanded-image'); - $.rmClass(file.thumb, 'expanding'); - file.isExpanded = true; - delete file.isExpanding; - if (doc.contains(post.nodes.root) && bottom <= 0) { - window.scrollBy(0, scrollY - window.scrollY + d.body.clientHeight - oldHeight); - } - if (file.scrollIntoView) { - delete file.scrollIntoView; - imageBottom = Math.min(doc.clientHeight - file.fullImage.getBoundingClientRect().bottom - 25, Header.getBottomOf(file.fullImage)); - if (imageBottom < 0) { - window.scrollBy(0, Math.min(-imageBottom, Header.getTopOf(file.fullImage))); - } - } - if (file.isVideo) { - return ImageExpand.setupVideo(post, Conf['Autoplay'], Conf['Show Controls']); - } - }, - setupVideo: function(post, playing, controls) { - var fullImage; - fullImage = post.file.fullImage; - if (!playing) { - fullImage.controls = controls; - return; - } - fullImage.controls = false; - $.asap((function() { - return doc.contains(fullImage); - }), function() { - if (!d.hidden && Header.isNodeVisible(fullImage)) { - return fullImage.play(); - } else { - return post.file.wasPlaying = true; - } - }); - if (controls) { - return ImageCommon.addControls(fullImage); - } - }, - videoCB: (function() { - var mousedown; - mousedown = false; - return { - mouseover: function() { - return mousedown = false; - }, - mousedown: function(e) { - if (e.button === 0) { - return mousedown = true; - } - }, - mouseup: function(e) { - if (e.button === 0) { - return mousedown = false; - } - }, - mouseout: function(e) { - if (((e.buttons & 1) || mousedown) && e.clientX <= this.getBoundingClientRect().left) { - return ImageExpand.toggle(Get.postFromNode(this)); - } - } - }; - })(), - setupVideoCB: function(post) { - var cb, eventName, ref; - ref = ImageExpand.videoCB; - for (eventName in ref) { - cb = ref[eventName]; - $.on(post.file.fullImage, eventName, cb); - } - if (post.file.videoControls) { - return $.on(post.file.videoControls.firstElementChild, 'click', function() { - return ImageExpand.toggle(post); - }); - } - }, - error: function() { - var post; - post = Get.postFromNode(this); - $.rm(this); - delete post.file.fullImage; - if (!(post.file.isExpanding || post.file.isExpanded)) { - return; - } - if (ImageCommon.decodeError(this, post.file)) { - return ImageExpand.contract(post); - } - if (ImageCommon.isFromArchive(this)) { - return ImageExpand.contract(post); - } - return ImageCommon.error(this, post, post.file, 10 * $.SECOND, function(URL) { - if (post.file.isExpanding || post.file.isExpanded) { - ImageExpand.contract(post); - if (URL) { - return ImageExpand.expand(post, URL); - } - } - }); - }, - menu: { - init: function() { - var conf, createSubEntry, el, name, ref, subEntries; - if (!ImageExpand.enabled) { - return; - } - el = $.el('span', { - textContent: 'Image Expansion', - className: 'image-expansion-link' - }); - createSubEntry = ImageExpand.menu.createSubEntry; - subEntries = []; - ref = Config.imageExpansion; - for (name in ref) { - conf = ref[name]; - subEntries.push(createSubEntry(name, conf[1])); - } - return Header.menu.addEntry({ - el: el, - order: 105, - subEntries: subEntries - }); - }, - createSubEntry: function(name, desc) { - var input, label; - label = UI.checkbox(name, name); - label.title = desc; - input = label.firstElementChild; - if (name === 'Fit width' || name === 'Fit height') { - $.on(input, 'change', ImageExpand.cb.setFitness); - } - $.event('change', null, input); - $.on(input, 'change', $.cb.checked); - return { - el: label - }; - } - } - }; - - return ImageExpand; - -}).call(this); - -ImageHost = (function() { - var ImageHost; - - ImageHost = { - init: function() { - var ref; - if (!((this.useFaster = /\S/.test(Conf['fourchanImageHost'])) && g.SITE.software === 'yotsuba' && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - return Callbacks.Post.push({ - name: 'Image Host Rewriting', - cb: this.node - }); - }, - suggestions: ['i.4cdn.org', 'is2.4chan.org'], - host: function() { - return Conf['fourchanImageHost'].trim() || 'i.4cdn.org'; - }, - flashHost: function() { - return 'i.4cdn.org'; - }, - thumbHost: function() { - return 'i.4cdn.org'; - }, - test: function(hostname) { - return hostname === 'i.4cdn.org' || ImageHost.regex.test(hostname); - }, - regex: /^is\d*\.4chan(?:nel)?\.org$/, - node: function() { - var host; - if (this.isClone) { - return; - } - host = ImageHost.host(); - if (this.file && ImageHost.test(this.file.url.split('/')[2]) && !/\.swf$/.test(this.file.url)) { - this.file.link.hostname = host; - if (this.file.thumbLink) { - this.file.thumbLink.hostname = host; - } - this.file.url = this.file.link.href; - } - return ImageHost.fixLinks($$('a', this.nodes.comment)); - }, - fixLinks: function(links) { - var host, i, len, link; - for (i = 0, len = links.length; i < len; i++) { - link = links[i]; - if (!(ImageHost.test(link.hostname) && !/\.swf$/.test(link.pathname))) { - continue; - } - host = ImageHost.host(); - if (link.hostname !== host) { - link.hostname = host; - } - } - } - }; - - return ImageHost; - -}).call(this); - -ImageHover = (function() { - var ImageHover; - - ImageHover = { - init: function() { - var ref; - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - if (Conf['Image Hover']) { - Callbacks.Post.push({ - name: 'Image Hover', - cb: this.node - }); - } - if (Conf['Image Hover in Catalog']) { - return Callbacks.CatalogThread.push({ - name: 'Image Hover', - cb: this.catalogNode - }); - } - }, - node: function() { - var file, i, len, ref, results; - ref = this.files; - results = []; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if ((file.isImage || file.isVideo) && file.thumb) { - results.push($.on(file.thumb, 'mouseover', ImageHover.mouseover(this, file))); - } - } - return results; - }, - catalogNode: function() { - var file; - file = this.thread.OP.files[0]; - if (!(file && (file.isImage || file.isVideo))) { - return; - } - return $.on(this.nodes.thumb, 'mouseover', ImageHover.mouseover(this.thread.OP, file)); - }, - mouseover: function(post, file) { - return function(e) { - var base, el, error, height, isVideo, maxHeight, maxWidth, ref, ref1, scale, width, x; - if (!doc.contains(this)) { - return; - } - isVideo = file.isVideo; - if (file.isExpanding || file.isExpanded || (typeof (base = g.SITE).isThumbExpanded === "function" ? base.isThumbExpanded(file) : void 0)) { - return; - } - error = ImageHover.error(post, file); - if (((ref = ImageCommon.cache) != null ? ref.dataset.fileID : void 0) === (post.fullID + "." + file.index)) { - el = ImageCommon.popCache(); - $.on(el, 'error', error); - } else { - el = $.el((isVideo ? 'video' : 'img')); - el.dataset.fileID = post.fullID + "." + file.index; - $.on(el, 'error', error); - el.src = file.url; - } - if (Conf['Restart when Opened']) { - ImageCommon.rewind(el); - ImageCommon.rewind(this); - } - el.id = 'ihover'; - $.add(Header.hover, el); - if (isVideo) { - el.loop = true; - el.controls = false; - Volume.setup(el); - if (Conf['Autoplay']) { - el.play(); - if (this.nodeName === 'VIDEO') { - this.currentTime = el.currentTime; - } - } - } - if (file.dimensions) { - ref1 = (function() { - var i, len, ref1, results; - ref1 = file.dimensions.split('x'); - results = []; - for (i = 0, len = ref1.length; i < len; i++) { - x = ref1[i]; - results.push(+x); - } - return results; - })(), width = ref1[0], height = ref1[1]; - maxWidth = doc.clientWidth; - maxHeight = doc.clientHeight - UI.hover.padding; - scale = Math.min(1, maxWidth / width, maxHeight / height); - width *= scale; - height *= scale; - el.style.maxWidth = width + "px"; - el.style.maxHeight = height + "px"; - } - return UI.hover({ - root: this, - el: el, - latestEvent: e, - endEvents: 'mouseout click', - height: height, - width: width, - noRemove: true, - cb: function() { - $.off(el, 'error', error); - ImageCommon.pushCache(el); - ImageCommon.pause(el); - $.rm(el); - return el.removeAttribute('style'); - } - }); - }; - }, - error: function(post, file) { - return function() { - if (ImageCommon.decodeError(this, file)) { - return; - } - return ImageCommon.error(this, post, file, 3 * $.SECOND, (function(_this) { - return function(URL) { - if (URL) { - return _this.src = URL + (_this.src === URL ? '?' + Date.now() : ''); - } else { - return $.rm(_this); - } - }; - })(this)); - }; - } - }; - - return ImageHover; - -}).call(this); - -ImageLoader = (function() { - var ImageLoader, - slice = [].slice; - - ImageLoader = { - init: function() { - var el, ref, ref1, replace; - if ((ref = g.VIEW) !== 'index' && ref !== 'thread' && ref !== 'archive') { - return; - } - replace = Conf['Replace JPG'] || Conf['Replace PNG'] || Conf['Replace GIF'] || Conf['Replace WEBM']; - if (!(Conf['Image Prefetching'] || replace)) { - return; - } - Callbacks.Post.push({ - name: 'Image Replace', - cb: this.node - }); - $.on(d, 'PostsInserted', function() { - if (ImageLoader.prefetchEnabled || replace) { - return g.posts.forEach(ImageLoader.prefetchAll); - } - }); - if (Conf['Replace WEBM']) { - $.on(d, 'scroll visibilitychange 4chanXInitFinished PostsInserted', this.playVideos); - } - if (!(Conf['Image Prefetching'] && ((ref1 = g.VIEW) === 'index' || ref1 === 'thread'))) { - return; - } - el = $.el('a', { - href: 'javascript:;', - title: 'Prefetch Images', - className: 'fa fa-bolt disabled', - textContent: 'Prefetch' - }); - $.on(el, 'click', this.toggle); - return Header.addShortcut('prefetch', el, 525); - }, - node: function() { - var file, i, len, ref; - if (this.isClone) { - return; - } - ref = this.files; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if (Conf['Replace WEBM'] && file.isVideo) { - ImageLoader.replaceVideo(this, file); - } - ImageLoader.prefetch(this, file); - } - }, - replaceVideo: function(post, file) { - var attr, i, len, ref, thumb, video; - thumb = file.thumb; - video = $.el('video', { - preload: 'none', - loop: true, - muted: true, - poster: thumb.src || thumb.dataset.src, - textContent: thumb.alt, - className: thumb.className - }); - video.setAttribute('muted', 'muted'); - video.dataset.md5 = thumb.dataset.md5; - ref = ['height', 'width', 'maxHeight', 'maxWidth']; - for (i = 0, len = ref.length; i < len; i++) { - attr = ref[i]; - video.style[attr] = thumb.style[attr]; - } - video.src = file.url; - $.replace(thumb, video); - file.thumb = video; - return file.videoThumb = true; - }, - prefetch: function(post, file) { - var clone, el, i, isImage, isVideo, len, ref, ref1, replace, thumb, type, url; - isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, url = file.url; - if (file.isPrefetched || !(isImage || isVideo) || post.isHidden || post.thread.isHidden) { - return; - } - if (isVideo) { - type = 'WEBM'; - } else { - type = (ref = url.match(/\.([^.]+)$/)) != null ? ref[1].toUpperCase() : void 0; - if (type === 'JPEG') { - type = 'JPG'; - } - } - replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src || thumb.dataset.src); - if (!(replace || ImageLoader.prefetchEnabled)) { - return; - } - if ($.hasClass(doc, 'catalog-mode')) { - return; - } - if (![post].concat(slice.call(post.clones)).some(function(clone) { - return doc.contains(clone.nodes.root); - })) { - return; - } - file.isPrefetched = true; - if (file.videoThumb) { - ref1 = post.clones; - for (i = 0, len = ref1.length; i < len; i++) { - clone = ref1[i]; - clone.file.thumb.preload = 'auto'; - } - thumb.preload = 'auto'; - if ($.engine === 'gecko') { - $.on(thumb, 'loadeddata', function() { - return this.removeAttribute('poster'); - }); - } - return; - } - el = $.el(isImage ? 'img' : 'video'); - if (isVideo) { - el.preload = 'auto'; - } - if (replace && isImage) { - $.on(el, 'load', function() { - var j, len1, ref2; - ref2 = post.clones; - for (j = 0, len1 = ref2.length; j < len1; j++) { - clone = ref2[j]; - clone.file.thumb.src = url; - } - return thumb.src = url; - }); - } - return el.src = url; - }, - prefetchAll: function(post) { - var file, i, len, ref; - ref = post.files; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - ImageLoader.prefetch(post, file); - } - }, - toggle: function() { - ImageLoader.prefetchEnabled = !ImageLoader.prefetchEnabled; - this.classList.toggle('disabled', !ImageLoader.prefetchEnabled); - if (ImageLoader.prefetchEnabled) { - g.posts.forEach(ImageLoader.prefetchAll); - } - }, - playVideos: function() { - var qpClone, ref; - qpClone = (ref = $.id('qp')) != null ? ref.firstElementChild : void 0; - return g.posts.forEach(function(post) { - var file, i, j, len, len1, ref1, ref2, thumb; - ref1 = [post].concat(slice.call(post.clones)); - for (i = 0, len = ref1.length; i < len; i++) { - post = ref1[i]; - ref2 = post.files; - for (j = 0, len1 = ref2.length; j < len1; j++) { - file = ref2[j]; - if (!file.videoThumb) { - continue; - } - thumb = file.thumb; - if (Header.isNodeVisible(thumb) || post.nodes.root === qpClone) { - thumb.play(); - } else { - thumb.pause(); - } - } - } - }); - } - }; - - return ImageLoader; - -}).call(this); - -Metadata = (function() { - var Metadata; - - Metadata = { - init: function() { - var ref; - if (!(Conf['WEBM Metadata'] && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - return Callbacks.Post.push({ - name: 'WEBM Metadata', - cb: this.node - }); - }, - node: function() { - var el, file, i, j, len1, ref; - ref = this.files; - for (i = j = 0, len1 = ref.length; j < len1; i = ++j) { - file = ref[i]; - if (!(/webm$/i.test(file.url))) { - continue; - } - if (this.isClone) { - el = $('.webm-title', file.text); - } else { - el = $.el('span', { - className: 'webm-title' - }); - el.dataset.index = i; - $.extend(el, {innerHTML: ""}); - $.add(file.text, [$.tn(' '), el]); - } - if (el.children.length === 1) { - $.one(el.lastElementChild, 'mouseover focus', Metadata.load); - } - } - }, - load: function() { - var index; - $.rmClass(this.parentNode, 'error'); - $.addClass(this.parentNode, 'loading'); - index = this.parentNode.dataset.index; - return CrossOrigin.binary(Get.postFromNode(this).files[+index].url, (function(_this) { - return function(data) { - var output, title; - $.rmClass(_this.parentNode, 'loading'); - if (data != null) { - title = Metadata.parse(data); - output = $.el('span', { - textContent: title || '' - }); - if (title == null) { - $.addClass(_this.parentNode, 'not-found'); - } - $.before(_this, output); - _this.parentNode.tabIndex = 0; - if (d.activeElement === _this) { - _this.parentNode.focus(); - } - return _this.tabIndex = -1; - } else { - $.addClass(_this.parentNode, 'error'); - return $.one(_this, 'click', Metadata.load); - } - }; - })(this), { - Range: 'bytes=0-9999' - }); - }, - parse: function(data) { - var element, i, readInt, size, title; - readInt = function() { - var len, n; - n = data[i++]; - len = 0; - while (n < (0x80 >> len)) { - len++; - } - n ^= 0x80 >> len; - while (len-- && i < data.length) { - n = (n << 8) ^ data[i++]; - } - return n; - }; - i = 0; - while (i < data.length) { - element = readInt(); - size = readInt(); - if (element === 0x3BA9) { - title = ''; - while (size-- && i < data.length) { - title += String.fromCharCode(data[i++]); - } - return decodeURIComponent(escape(title)); - } else if (element !== 0x8538067 && element !== 0x549A966) { - i += size; - } - } - return null; - } - }; - - return Metadata; - -}).call(this); - -RevealSpoilers = (function() { - var RevealSpoilers; - - RevealSpoilers = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Reveal Spoiler Thumbnails'])) { - return; - } - return Callbacks.Post.push({ - name: 'Reveal Spoiler Thumbnails', - cb: this.node - }); - }, - node: function() { - var file, i, len, ref, thumb; - if (this.isClone) { - return; - } - ref = this.files; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if (!(file.thumb && file.isSpoiler)) { - continue; - } - thumb = file.thumb; - thumb.removeAttribute('style'); - thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; - if (thumb.src) { - thumb.src = file.thumbURL; - } else { - thumb.dataset.src = file.thumbURL; - } - } - } - }; - - return RevealSpoilers; - -}).call(this); - -Sauce = (function() { - var Sauce, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Sauce = { - init: function() { - var j, len, link, linkData, links, ref, ref1; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Sauce'])) { - return; - } - $.addClass(doc, 'show-sauce'); - links = []; - ref1 = Conf['sauces'].split('\n'); - for (j = 0, len = ref1.length; j < len; j++) { - link = ref1[j]; - if (link[0] !== '#' && (linkData = this.parseLink(link))) { - links.push(linkData); - } - } - if (!links.length) { - return; - } - this.links = links; - this.link = $.el('a', { - target: '_blank', - className: 'sauce' - }); - return Callbacks.Post.push({ - name: 'Sauce', - cb: this.node - }); - }, - parseLink: function(link) { - var err, i, j, len, m, part, parts, ref, ref1, regexp; - if (!(link = link.trim())) { - return null; - } - parts = $.dict(); - ref = link.split(/;(?=(?:text|boards|types|regexp|sandbox):?)/); - for (i = j = 0, len = ref.length; j < len; i = ++j) { - part = ref[i]; - if (i === 0) { - parts['url'] = part; - } else { - m = part.match(/^(\w*):?(.*)$/); - parts[m[1]] = m[2]; - } - } - parts['text'] || (parts['text'] = ((ref1 = parts['url'].match(/(\w+)\.\w+\//)) != null ? ref1[1] : void 0) || '?'); - if ('boards' in parts) { - parts['boards'] = Filter.parseBoards(parts['boards']); - } - if ('regexp' in parts) { - try { - if ((regexp = parts['regexp'].match(/^\/(.*)\/(\w*)$/))) { - parts['regexp'] = RegExp(regexp[1], regexp[2]); - } else { - parts['regexp'] = RegExp(parts['regexp']); - } - } catch (error) { - err = error; - new Notice('warning', [$.tn("Invalid regexp for Sauce link:"), $.el('br'), $.tn(link), $.el('br'), $.tn(err.message)], 60); - return null; - } - } - return parts; - }, - createSauceLink: function(link, post, file) { - var a, base, ext, j, key, len, matches, missing, parts, ref; - ext = file.url.match(/[^.]*$/)[0]; - parts = $.dict(); - $.extend(parts, link); - if (!(!parts['boards'] || parts['boards'][post.siteID + "/" + post.boardID] || parts['boards'][post.siteID + "/*"])) { - return null; - } - if (!(!parts['types'] || indexOf.call(parts['types'].split(','), ext) >= 0)) { - return null; - } - if (!(!parts['regexp'] || (matches = file.name.match(parts['regexp'])))) { - return null; - } - missing = []; - ref = ['url', 'text']; - for (j = 0, len = ref.length; j < len; j++) { - key = ref[j]; - parts[key] = parts[key].replace(/%(T?URL|IMG|[sh]?MD5|board|name|%|semi|\$\d+)/g, function(orig, parameter) { - var type; - if (parameter[0] === '$') { - if (!matches) { - return orig; - } - type = matches[parameter.slice(1)] || ''; - } else { - type = Sauce.formatters[parameter](post, file, ext); - if (type == null) { - missing.push(parameter); - return ''; - } - } - if (key === 'url' && (parameter !== '%' && parameter !== 'semi')) { - if (/^javascript:/i.test(parts['url'])) { - type = JSON.stringify(type); - } - type = encodeURIComponent(type); - } - return type; - }); - } - if ((typeof (base = g.SITE).areMD5sDeferred === "function" ? base.areMD5sDeferred(post.board) : void 0) && missing.length && !missing.filter(function(x) { - return !/^.?MD5$/.test(x); - }).length) { - a = Sauce.link.cloneNode(false); - a.dataset.skip = '1'; - return a; - } - if (missing.length) { - return null; - } - a = Sauce.link.cloneNode(false); - a.href = parts['url']; - a.textContent = parts['text']; - if (/^javascript:/i.test(parts['url'])) { - a.removeAttribute('target'); - } - return a; - }, - node: function() { - var file, j, len, ref; - if (this.isClone) { - return; - } - ref = this.files; - for (j = 0, len = ref.length; j < len; j++) { - file = ref[j]; - Sauce.file(this, file); - } - }, - file: function(post, file) { - var j, len, link, node, nodes, observer, ref, skipped; - nodes = []; - skipped = []; - ref = Sauce.links; - for (j = 0, len = ref.length; j < len; j++) { - link = ref[j]; - if ((node = Sauce.createSauceLink(link, post, file))) { - nodes.push($.tn(' '), node); - if (node.dataset.skip) { - skipped.push([link, node]); - } - } - } - $.add(file.text, nodes); - if (skipped.length) { - observer = new MutationObserver(function() { - var k, len1, node2, ref1; - if (file.text.dataset.md5) { - for (k = 0, len1 = skipped.length; k < len1; k++) { - ref1 = skipped[k], link = ref1[0], node = ref1[1]; - if ((node2 = Sauce.createSauceLink(link, post, file))) { - $.replace(node, node2); - } - } - return observer.disconnect(); - } - }); - return observer.observe(file.text, { - attributes: true - }); - } - }, - formatters: { - TURL: function(post, file) { - return file.thumbURL; - }, - URL: function(post, file) { - return file.url; - }, - IMG: function(post, file, ext) { - if (ext === 'gif' || ext === 'jpg' || ext === 'jpeg' || ext === 'png') { - return file.url; - } else { - return file.thumbURL; - } - }, - MD5: function(post, file) { - return file.MD5; - }, - sMD5: function(post, file) { - var ref; - return (ref = file.MD5) != null ? ref.replace(/[+\/=]/g, function(c) { - return { - '+': '-', - '/': '_', - '=': '' - }[c]; - }) : void 0; - }, - hMD5: function(post, file) { - var c; - if (file.MD5) { - return ((function() { - var j, len, ref, results; - ref = atob(file.MD5); - results = []; - for (j = 0, len = ref.length; j < len; j++) { - c = ref[j]; - results.push(("0" + (c.charCodeAt(0).toString(16))).slice(-2)); - } - return results; - })()).join(''); - } - }, - board: function(post) { - return post.board.ID; - }, - name: function(post, file) { - return file.name; - }, - '%': function() { - return '%'; - }, - semi: function() { - return ';'; - } - } - }; - - return Sauce; - -}).call(this); - -Volume = (function() { - var Volume; - - Volume = { - init: function() { - var base, ref, unmuteEntry, volumeEntry; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && (Conf['Image Expansion'] || Conf['Image Hover'] || Conf['Image Hover in Catalog'] || Conf['Gallery']))) { - return; - } - $.sync('Allow Sound', function(x) { - var ref1; - Conf['Allow Sound'] = x; - return (ref1 = Volume.inputs) != null ? ref1.unmute.checked = x : void 0; - }); - $.sync('Default Volume', function(x) { - var ref1; - Conf['Default Volume'] = x; - return (ref1 = Volume.inputs) != null ? ref1.volume.value = x : void 0; - }); - if (Conf['Mouse Wheel Volume']) { - Callbacks.Post.push({ - name: 'Mouse Wheel Volume', - cb: this.node - }); - } - if (typeof (base = g.SITE).noAudio === "function" ? base.noAudio(g.BOARD) : void 0) { - return; - } - if (Conf['Mouse Wheel Volume']) { - Callbacks.CatalogThread.push({ - name: 'Mouse Wheel Volume', - cb: this.catalogNode - }); - } - unmuteEntry = UI.checkbox('Allow Sound', 'Allow Sound'); - unmuteEntry.title = Config.main['Images and Videos']['Allow Sound'][1]; - volumeEntry = $.el('label', { - title: 'Default volume for videos.' - }); - $.extend(volumeEntry, {innerHTML: " Volume"}); - this.inputs = { - unmute: unmuteEntry.firstElementChild, - volume: volumeEntry.firstElementChild - }; - $.on(this.inputs.unmute, 'change', $.cb.checked); - $.on(this.inputs.volume, 'change', $.cb.value); - Header.menu.addEntry({ - el: unmuteEntry, - order: 200 - }); - return Header.menu.addEntry({ - el: volumeEntry, - order: 201 - }); - }, - setup: function(video) { - video.muted = !Conf['Allow Sound']; - video.volume = Conf['Default Volume']; - return $.on(video, 'volumechange', Volume.change); - }, - change: function() { - var items, key, muted, ref, val, volume; - ref = this, muted = ref.muted, volume = ref.volume; - items = { - 'Allow Sound': !muted, - 'Default Volume': volume - }; - for (key in items) { - val = items[key]; - if (Conf[key] === val) { - delete items[key]; - } - } - $.set(items); - $.extend(Conf, items); - if (Volume.inputs) { - Volume.inputs.unmute.checked = !muted; - return Volume.inputs.volume.value = volume; - } - }, - node: function() { - var base, file, i, len, ref; - if (typeof (base = g.SITE).noAudio === "function" ? base.noAudio(this.board) : void 0) { - return; - } - ref = this.files; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if (!file.isVideo) { - continue; - } - if (file.thumb) { - $.on(file.thumb, 'wheel', Volume.wheel.bind(Header.hover)); - } - $.on($('.file-info', file.text) || file.link, 'wheel', Volume.wheel.bind(file.thumbLink)); - } - }, - catalogNode: function() { - var file; - file = this.thread.OP.files[0]; - if (!(file != null ? file.isVideo : void 0)) { - return; - } - return $.on(this.nodes.thumb, 'wheel', Volume.wheel.bind(Header.hover)); - }, - wheel: function(e) { - var el, volume; - if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { - return; - } - if (!(el = $('video:not([data-md5])', this))) { - return; - } - if (el.muted || !$.hasAudio(el)) { - return; - } - volume = el.volume + 0.1; - if (e.deltaY < 0) { - volume *= 1.1; - } - if (e.deltaY > 0) { - volume /= 1.1; - } - el.volume = $.minmax(volume - 0.1, 0, 1); - return e.preventDefault(); - } - }; - - return Volume; - -}).call(this); - -Embedding = (function() { - var Embedding, - slice = [].slice; - - Embedding = { - init: function() { - var j, len, ref, ref1, type; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Linkify'] && (Conf['Embedding'] || Conf['Link Title'] || Conf['Cover Preview']))) { - return; - } - this.types = $.dict(); - ref1 = this.ordered_types; - for (j = 0, len = ref1.length; j < len; j++) { - type = ref1[j]; - this.types[type.key] = type; - } - if (Conf['Embedding'] && g.VIEW !== 'archive') { - this.dialog = UI.dialog('embedding', {innerHTML: "
    "}); - this.media = $('#media-embed', this.dialog); - $.one(d, '4chanXInitFinished', this.ready); - $.on(d, 'IndexRefreshInternal', function() { - return g.posts.forEach(function(post) { - var embed, k, l, len1, len2, ref2, ref3; - ref2 = [post].concat(slice.call(post.clones)); - for (k = 0, len1 = ref2.length; k < len1; k++) { - post = ref2[k]; - ref3 = post.nodes.embedlinks; - for (l = 0, len2 = ref3.length; l < len2; l++) { - embed = ref3[l]; - Embedding.cb.catalogRemove.call(embed); - } - } - }); - }); - } - if (Conf['Link Title']) { - return $.on(d, '4chanXInitFinished PostsInserted', function() { - var key, ref2, ref3, service; - ref2 = Embedding.types; - for (key in ref2) { - service = ref2[key]; - if ((ref3 = service.title) != null ? ref3.batchSize : void 0) { - Embedding.flushTitles(service.title); - } - } - }); - } - }, - events: function(post) { - var data, el, i, items; - if (g.VIEW === 'archive') { - return; - } - if (Conf['Embedding']) { - i = 0; - items = post.nodes.embedlinks = $$('.embedder', post.nodes.comment); - while (el = items[i++]) { - $.on(el, 'click', Embedding.cb.click); - if ($.hasClass(el, 'embedded')) { - Embedding.cb.toggle.call(el); - } - } - } - if (Conf['Cover Preview']) { - i = 0; - items = $$('.linkify', post.nodes.comment); - while (el = items[i++]) { - if ((data = Embedding.services(el))) { - Embedding.preview(data); - } - } - } - }, - process: function(link, post) { - var data; - if (!(Conf['Embedding'] || Conf['Link Title'] || Conf['Cover Preview'])) { - return; - } - if ($.x('ancestor::pre', link)) { - return; - } - if (data = Embedding.services(link)) { - data.post = post; - if (Conf['Embedding'] && g.VIEW !== 'archive') { - Embedding.embed(data); - } - if (Conf['Link Title']) { - Embedding.title(data); - } - if (Conf['Cover Preview'] && g.VIEW !== 'archive') { - return Embedding.preview(data); - } - } - }, - services: function(link) { - var href, j, len, match, ref, type; - href = link.href; - ref = Embedding.ordered_types; - for (j = 0, len = ref.length; j < len; j++) { - type = ref[j]; - if ((match = type.regExp.exec(href))) { - return { - key: type.key, - uid: match[1], - options: match[2], - link: link - }; - } - } - }, - embed: function(data) { - var embed, href, key, link, name, options, post, ref, uid, value; - key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; - href = link.href; - $.addClass(link, key.toLowerCase()); - embed = $.el('a', { - className: 'embedder', - href: 'javascript:;' - }, {innerHTML: "(unembed)"}); - ref = { - key: key, - uid: uid, - options: options, - href: href - }; - for (name in ref) { - value = ref[name]; - embed.dataset[name] = value; - } - $.on(embed, 'click', Embedding.cb.click); - $.after(link, [$.tn(' '), embed]); - post.nodes.embedlinks.push(embed); - if (Conf['Auto-embed'] && !Conf['Floating Embeds'] && !post.isFetchedQuote) { - if ($.hasClass(doc, 'catalog-mode')) { - return $.addClass(embed, 'embed-removed'); - } else { - return Embedding.cb.toggle.call(embed); - } - } - }, - ready: function() { - if (!Main.isThisPageLegit()) { - return; - } - $.addClass(Embedding.dialog, 'empty'); - $.on($('.close', Embedding.dialog), 'click', Embedding.closeFloat); - $.on($('.move', Embedding.dialog), 'mousedown', Embedding.dragEmbed); - $.on($('.jump', Embedding.dialog), 'click', function() { - if (doc.contains(Embedding.lastEmbed)) { - return Header.scrollTo(Embedding.lastEmbed); - } - }); - return $.add(d.body, Embedding.dialog); - }, - closeFloat: function() { - delete Embedding.lastEmbed; - $.addClass(Embedding.dialog, 'empty'); - return $.replace(Embedding.media.firstChild, $.el('div')); - }, - dragEmbed: function() { - var style; - style = Embedding.media.style; - if (Embedding.dragEmbed.mouseup) { - $.off(d, 'mouseup', Embedding.dragEmbed); - Embedding.dragEmbed.mouseup = false; - style.pointerEvents = ''; - return; - } - $.on(d, 'mouseup', Embedding.dragEmbed); - Embedding.dragEmbed.mouseup = true; - return style.pointerEvents = 'none'; - }, - title: function(data) { - var key, link, options, post, service, uid; - key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; - if (!(service = Embedding.types[key].title)) { - return; - } - $.addClass(link, key.toLowerCase()); - if (service.batchSize) { - (service.queue || (service.queue = [])).push(data); - if (service.queue.length >= service.batchSize) { - return Embedding.flushTitles(service); - } - } else { - return CrossOrigin.cache(service.api(uid), (function() { - return Embedding.cb.title(this, data); - })); - } - }, - flushTitles: function(service) { - var cb, data, queue; - queue = service.queue; - if (!(queue != null ? queue.length : void 0)) { - return; - } - service.queue = []; - cb = function() { - var data, j, len; - for (j = 0, len = queue.length; j < len; j++) { - data = queue[j]; - Embedding.cb.title(this, data); - } - }; - return CrossOrigin.cache(service.api((function() { - var j, len, results; - results = []; - for (j = 0, len = queue.length; j < len; j++) { - data = queue[j]; - results.push(data.uid); - } - return results; - })()), cb); - }, - preview: function(data) { - var key, link, service, uid; - key = data.key, uid = data.uid, link = data.link; - if (!(service = Embedding.types[key].preview)) { - return; - } - return $.on(link, 'mouseover', function(e) { - var el, height, src; - src = service.url(uid); - height = service.height; - el = $.el('img', { - src: src, - id: 'ihover' - }); - $.add(Header.hover, el); - return UI.hover({ - root: link, - el: el, - latestEvent: e, - endEvents: 'mouseout click', - height: height - }); - }); - }, - cb: { - click: function(e) { - var div; - e.preventDefault(); - if (!$.hasClass(this, 'embedded') && (Conf['Floating Embeds'] || $.hasClass(doc, 'catalog-mode'))) { - if (!(div = Embedding.media.firstChild)) { - return; - } - $.replace(div, Embedding.cb.embed(this)); - Embedding.lastEmbed = Get.postFromNode(this).nodes.root; - return $.rmClass(Embedding.dialog, 'empty'); - } else { - return Embedding.cb.toggle.call(this); - } - }, - toggle: function() { - if ($.hasClass(this, "embedded")) { - $.rm(this.nextElementSibling); - } else { - $.after(this, Embedding.cb.embed(this)); - } - return $.toggleClass(this, 'embedded'); - }, - embed: function(a) { - var container, el, type; - container = $.el('div', { - className: 'media-embed' - }); - $.add(container, el = (type = Embedding.types[a.dataset.key]).el(a)); - el.style.cssText = type.style != null ? type.style : 'border: none; width: 640px; height: 360px;'; - return container; - }, - catalogRemove: function() { - var isCatalog; - isCatalog = $.hasClass(doc, 'catalog-mode'); - if ((isCatalog && $.hasClass(this, 'embedded')) || (!isCatalog && $.hasClass(this, 'embed-removed'))) { - Embedding.cb.toggle.call(this); - return $.toggleClass(this, 'embed-removed'); - } - }, - title: function(req, data) { - var base1, j, k, key, len, len1, link, link2, options, post, post2, ref, ref1, service, status, text, uid; - key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; - service = Embedding.types[key].title; - status = req.status; - if ((status === 200 || status === 304) && service.status) { - status = service.status(req.response)[0]; - } - if (!status) { - return; - } - text = "[" + key + "] " + ((function() { - switch (status) { - case 200: - case 304: - text = service.text(req.response, uid); - if (typeof text === 'string') { - return text; - } else { - return text = link.textContent; - } - break; - case 404: - return "Not Found"; - case 403: - case 401: - return "Forbidden or Private"; - default: - return status + "'d"; - } - })()); - link.dataset.original = link.textContent; - link.textContent = text; - ref = post.clones; - for (j = 0, len = ref.length; j < len; j++) { - post2 = ref[j]; - ref1 = $$('a.linkify', post2.nodes.comment); - for (k = 0, len1 = ref1.length; k < len1; k++) { - link2 = ref1[k]; - if (!(link2.href === link.href)) { - continue; - } - if ((base1 = link2.dataset).original == null) { - base1.original = link2.textContent; - } - link2.textContent = text; - } - } - } - }, - ordered_types: [ - { - key: 'audio', - regExp: /^[^?#]+\.(?:mp3|m4a|oga|wav|flac)(?:[?#]|$)/i, - style: '', - el: function(a) { - return $.el('audio', { - controls: true, - preload: 'auto', - src: a.dataset.href - }); - } - }, { - key: 'image', - regExp: /^[^?#]+\.(?:gif|png|jpg|jpeg|bmp|webp)(?::\w+)?(?:[?#]|$)/i, - style: '', - el: function(a) { - return $.el('div', {innerHTML: ""}); - } - }, { - key: 'video', - regExp: /^[^?#]+\.(?:og[gv]|webm|mp4)(?:[?#]|$)/i, - style: 'max-width: 80vw; max-height: 80vh;', - el: function(a) { - var el; - el = $.el('video', { - hidden: true, - controls: true, - preload: 'auto', - src: a.dataset.href, - loop: ImageHost.test(a.dataset.href.split('/')[2]) - }); - $.on(el, 'loadedmetadata', function() { - if (el.videoHeight === 0 && el.parentNode) { - return $.replace(el, Embedding.types.audio.el(a)); - } else { - return el.hidden = false; - } - }); - return el; - } - }, { - key: 'PeerTube', - regExp: /^(\w+:\/\/[^\/]+\/videos\/watch\/\w{8}-\w{4}-\w{4}-\w{4}-\w{12})(.*)/, - el: function(a) { - var el, options, start; - options = (start = a.dataset.options.match(/[?&](start=\w+)/)) ? "?" + start[1] : ''; - el = $.el('iframe', { - src: a.dataset.uid.replace('/videos/watch/', '/videos/embed/') + options - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'BitChute', - regExp: /^\w+:\/\/(?:www\.)?bitchute\.com\/video\/([\w\-]+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://www.bitchute.com/embed/" + a.dataset.uid + "/" - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Clyp', - regExp: /^\w+:\/\/(?:www\.)?clyp\.it\/(\w{8})/, - style: 'border: 0; width: 640px; height: 160px;', - el: function(a) { - return $.el('iframe', { - src: "https://clyp.it/" + a.dataset.uid + "/widget" - }); - }, - title: { - api: function(uid) { - return "https://api.clyp.it/oembed?url=https://clyp.it/" + uid; - }, - text: function(_) { - return _.title; - } - } - }, { - key: 'Dailymotion', - regExp: /^\w+:\/\/(?:(?:www\.)?dailymotion\.com\/(?:embed\/)?video|dai\.ly)\/([A-Za-z0-9]+)[^?]*(.*)/, - el: function(a) { - var el, options, start; - options = (start = a.dataset.options.match(/[?&](start=\d+)/)) ? "?" + start[1] : ''; - el = $.el('iframe', { - src: "//www.dailymotion.com/embed/video/" + a.dataset.uid + options - }); - el.setAttribute("allowfullscreen", "true"); - return el; - }, - title: { - api: function(uid) { - return "https://api.dailymotion.com/video/" + uid; - }, - text: function(_) { - return _.title; - } - }, - preview: { - url: function(uid) { - return "https://www.dailymotion.com/thumbnail/video/" + uid; - }, - height: 240 - } - }, { - key: 'Gfycat', - regExp: /^\w+:\/\/(?:www\.)?gfycat\.com\/(?:iframe\/)?(\w+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "//gfycat.com/ifr/" + a.dataset.uid - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Gist', - regExp: /^\w+:\/\/gist\.github\.com\/[\w\-]+\/(\w+)/, - style: '', - el: (function() { - var counter; - counter = 0; - return function(a) { - var el; - el = $.el('pre', { - hidden: true, - id: "gist-embed-" + (counter++) - }); - CrossOrigin.cache("https://api.github.com/gists/" + a.dataset.uid, function() { - el.textContent = Object.values(this.response.files)[0].content; - el.className = 'prettyprint'; - $.global(function() { - return typeof window.prettyPrint === "function" ? window.prettyPrint((function() {}), document.getElementById(document.currentScript.dataset.id).parentNode) : void 0; - }, { - id: el.id - }); - return el.hidden = false; - }); - return el; - }; - })(), - title: { - api: function(uid) { - return "https://api.github.com/gists/" + uid; - }, - text: function(arg) { - var file, files; - files = arg.files; - for (file in files) { - if (files.hasOwnProperty(file)) { - return file; - } - } - } - } - }, { - key: 'InstallGentoo', - regExp: /^\w+:\/\/paste\.installgentoo\.com\/view\/(?:raw\/|download\/|embed\/)?(\w+)/, - el: function(a) { - return $.el('iframe', { - src: "https://paste.installgentoo.com/view/embed/" + a.dataset.uid - }); - } - }, { - key: 'LiveLeak', - regExp: /^\w+:\/\/(?:\w+\.)?liveleak\.com\/.*\?.*[tif]=(\w+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://www.liveleak.com/e/" + a.dataset.uid - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - 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: function(a) { - var _, base, el, host, j, k, l, len, len1, len2, name, names, ref, ref1, type, types, url, urls; - el = $.el('video', { - controls: true, - preload: 'auto', - loop: true - }); - if (/^http/.test(a.dataset.uid)) { - $.add(el, $.el('source', { - src: a.dataset.uid - })); - return el; - } - ref = a.dataset.uid.match(/(\w+)\/(.*)/), _ = ref[0], host = ref[1], names = ref[2]; - types = (function() { - switch (host) { - case 'gd': - case 'wu': - case 'fc': - return ['']; - case 'gc': - return ['giant', 'fat', 'zippy']; - default: - return ['.webm', '.mp4']; - } - })(); - ref1 = names.split(','); - for (j = 0, len = ref1.length; j < len; j++) { - name = ref1[j]; - for (k = 0, len1 = types.length; k < len1; k++) { - type = types[k]; - base = "" + name + type; - urls = (function() { - switch (host) { - case 'pf': - return ["https://kastden.org/_loopvid_media/pf/" + base, "https://web.archive.org/web/2/http://a.pomf.se/" + base]; - case 'kd': - return ["https://kastden.org/loopvid/" + base]; - case 'lv': - return ["https://lv.kastden.org/" + base]; - case 'gd': - return ["https://docs.google.com/uc?export=download&id=" + base]; - case 'gh': - return ["https://googledrive.com/host/" + base]; - case 'db': - return ["https://dl.dropboxusercontent.com/u/" + base]; - case 'dx': - return ["https://dl.dropboxusercontent.com/" + base]; - case 'nn': - return ["https://kastden.org/_loopvid_media/nn/" + base]; - case 'cp': - return ["https://copy.com/" + base]; - case 'wu': - return ["http://webmup.com/" + base + "/vid.webm"]; - case 'ig': - return ["https://i.imgur.com/" + base]; - case 'ky': - return ["https://kastden.org/_loopvid_media/ky/" + base]; - case 'mf': - return ["https://kastden.org/_loopvid_media/mf/" + base, "https://web.archive.org/web/2/https://d.maxfile.ro/" + base]; - case 'm2': - return ["https://kastden.org/_loopvid_media/m2/" + base]; - case 'pc': - return ["https://kastden.org/_loopvid_media/pc/" + base, "https://web.archive.org/web/2/http://a.pomf.cat/" + base]; - case '1c': - return ["http://b.1339.cf/" + base]; - case 'pi': - return ["https://kastden.org/_loopvid_media/pi/" + base, "https://web.archive.org/web/2/https://u.pomf.is/" + base]; - case 'ni': - return ["https://kastden.org/_loopvid_media/ni/" + base, "https://web.archive.org/web/2/https://u.nya.is/" + base]; - case 'wl': - return ["http://webm.land/media/" + base]; - case 'ko': - return ["https://kordy.kastden.org/loopvid/" + base]; - case 'mm': - return ["https://kastden.org/_loopvid_media/mm/" + base, "https://web.archive.org/web/2/https://my.mixtape.moe/" + base]; - case 'ic': - return ["https://media.8ch.net/file_store/" + base]; - case 'fc': - return ["//" + (ImageHost.host()) + "/" + base + ".webm"]; - case 'gc': - return ["https://" + type + ".gfycat.com/" + name + ".webm"]; - } - })(); - for (l = 0, len2 = urls.length; l < len2; l++) { - url = urls[l]; - $.add(el, $.el('source', { - src: url - })); - } - } - } - return el; - } - }, { - key: 'Openings.moe', - regExp: /^\w+:\/\/openings.moe\/\?video=([^.&=]+)/, - style: 'width: 1280px; height: 720px; max-width: 80vw; max-height: 80vh;', - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://openings.moe/?video=" + a.dataset.uid - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Pastebin', - regExp: /^\w+:\/\/(?:\w+\.)?pastebin\.com\/(?!u\/)(?:[\w.]+(?:\/|\?i\=))?(\w+)/, - el: function(a) { - var div; - return div = $.el('iframe', { - src: "//pastebin.com/embed_iframe.php?i=" + a.dataset.uid - }); - } - }, { - key: 'SoundCloud', - regExp: /^\w+:\/\/(?:www\.)?(?:soundcloud\.com\/|snd\.sc\/)([\w\-\/]+)/, - style: 'border: 0; width: 500px; height: 400px;', - el: function(a) { - return $.el('iframe', { - src: "https://w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F" + (encodeURIComponent(a.dataset.uid)) - }); - }, - title: { - api: function(uid) { - return location.protocol + "//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F" + (encodeURIComponent(uid)); - }, - text: function(_) { - return _.title; - } - } - }, { - key: 'StrawPoll', - regExp: /^\w+:\/\/(?:www\.)?strawpoll\.me\/(?:embed_\d+\/)?(\d+(?:\/r)?)/, - style: 'border: 0; width: 600px; height: 406px;', - el: function(a) { - return $.el('iframe', { - src: "https://www.strawpoll.me/embed_1/" + a.dataset.uid - }); - } - }, { - key: 'Streamable', - regExp: /^\w+:\/\/(?:www\.)?streamable\.com\/(\w+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://streamable.com/o/" + a.dataset.uid - }); - el.setAttribute("allowfullscreen", "true"); - return el; - }, - title: { - api: function(uid) { - return "https://api.streamable.com/oembed?url=https://streamable.com/" + uid; - }, - text: function(_) { - return _.title; - } - } - }, { - key: 'TwitchTV', - regExp: /^\w+:\/\/(?:www\.|secure\.|clips\.|m\.)?twitch\.tv\/(\w[^#\&\?]*)/, - el: function(a) { - var el, m, time, url; - m = a.dataset.href.match(/^\w+:\/\/(?:(clips\.)|\w+\.)?twitch\.tv\/(?:\w+\/)?(clip\/)?(\w[^#\&\?]*)/); - if (m[1] || m[2]) { - url = "//clips.twitch.tv/embed?clip=" + m[3] + "&parent=" + location.hostname; - } else { - m = a.dataset.uid.match(/(\w+)(?:\/(?:v\/)?(\d+))?/); - url = "//player.twitch.tv/?" + (m[2] ? "video=v" + m[2] : "channel=" + m[1]) + "&autoplay=false&parent=" + location.hostname; - if ((time = a.dataset.href.match(/\bt=(\w+)/))) { - url += "&time=" + time[1]; - } - } - el = $.el('iframe', { - src: url - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Twitter', - regExp: /^\w+:\/\/(?:www\.|mobile\.)?twitter\.com\/(\w+\/status\/\d+)/, - style: 'border: none; width: 550px; height: 250px; overflow: hidden; resize: both;', - el: function(a) { - var cont, el, onMessage; - el = $.el('iframe'); - $.on(el, 'load', function() { - return this.contentWindow.postMessage({ - element: 't', - query: 'height' - }, 'https://twitframe.com'); - }); - onMessage = function(e) { - if (e.source === el.contentWindow && e.origin === 'https://twitframe.com') { - $.off(window, 'message', onMessage); - return (cont || el).style.height = (+$.minmax(e.data.height, 250, 0.8 * doc.clientHeight)) + "px"; - } - }; - $.on(window, 'message', onMessage); - el.src = "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid; - if ($.engine === 'gecko') { - el.style.cssText = 'border: none; width: 100%; height: 100%;'; - cont = $.el('div'); - $.add(cont, el); - return cont; - } else { - return el; - } - } - }, { - key: 'VidLii', - regExp: /^\w+:\/\/(?:www\.)?vidlii\.com\/watch\?v=(\w{11})/, - style: 'border: none; width: 640px; height: 392px;', - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://www.vidlii.com/embed?v=" + a.dataset.uid + "&a=0" - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Vimeo', - regExp: /^\w+:\/\/(?:www\.)?vimeo\.com\/(\d+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "//player.vimeo.com/video/" + a.dataset.uid + "?wmode=opaque" - }); - el.setAttribute("allowfullscreen", "true"); - return el; - }, - title: { - api: function(uid) { - return "https://vimeo.com/api/oembed.json?url=https://vimeo.com/" + uid; - }, - text: function(_) { - return _.title; - } - } - }, { - key: 'Vine', - regExp: /^\w+:\/\/(?:www\.)?vine\.co\/v\/(\w+)/, - style: 'border: none; width: 500px; height: 500px;', - el: function(a) { - return $.el('iframe', { - src: "https://vine.co/v/" + a.dataset.uid + "/card" - }); - } - }, { - key: 'Vocaroo', - regExp: /^\w+:\/\/(?:(?:www\.|old\.)?vocaroo\.com|voca\.ro)\/((?:i\/)?\w+)/, - style: '', - el: function(a) { - var el; - el = $.el('iframe'); - el.width = 300; - el.height = 60; - el.setAttribute('frameborder', 0); - el.src = "https://vocaroo.com/embed/" + (a.dataset.uid.replace(/^i\//, '')) + "?autoplay=0"; - return el; - } - }, { - key: 'YouTube', - regExp: /^\w+:\/\/(?:youtu.be\/|[\w.]*youtube[\w.]*\/.*(?:v=|\bembed\/|\bv\/))([\w\-]{11})(.*)/, - el: function(a) { - var el, start; - start = a.dataset.options.match(/\b(?:star)?t\=(\w+)/); - if (start) { - start = start[1]; - } - if (start && !/^\d+$/.test(start)) { - start += ' 0h0m0s'; - start = 3600 * start.match(/(\d+)h/)[1] + 60 * start.match(/(\d+)m/)[1] + 1 * start.match(/(\d+)s/)[1]; - } - el = $.el('iframe', { - src: "//www.youtube.com/embed/" + a.dataset.uid + "?rel=0&wmode=opaque" + (start ? '&start=' + start : '') - }); - el.setAttribute("allowfullscreen", "true"); - return el; - }, - title: { - api: function(uid) { - return "https://www.youtube.com/oembed?url=https%3A//www.youtube.com/watch%3Fv%3D" + uid + "&format=json"; - }, - text: function(_) { - return _.title; - }, - status: function(_) { - var m; - if (_.error) { - m = _.error.match(/^(\d*)\s*(.*)/); - return [+m[1], m[2]]; - } else { - return [200, 'OK']; - } - } - }, - preview: { - url: function(uid) { - return "https://img.youtube.com/vi/" + uid + "/0.jpg"; - }, - height: 360 - } - } - ] - }; - - return Embedding; - -}).call(this); - -Linkify = (function() { - var Linkify; - - Linkify = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread' && ref !== 'archive') || !Conf['Linkify']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - Callbacks.Post.push({ - name: 'Linkify', - cb: this.node - }); - return Embedding.init(); - }, - node: function() { - var base, j, k, len, len1, link, links, ref; - if (this.isClone) { - return Embedding.events(this); - } - if (!Linkify.regString.test(this.info.comment)) { - return; - } - ref = $$('a', this.nodes.comment); - for (j = 0, len = ref.length; j < len; j++) { - link = ref[j]; - if (!(typeof (base = g.SITE).isLinkified === "function" ? base.isLinkified(link) : void 0)) { - continue; - } - $.addClass(link, 'linkify'); - if (ImageHost.useFaster) { - ImageHost.fixLinks([link]); - } - Embedding.process(link, this); - } - links = Linkify.process(this.nodes.comment); - if (ImageHost.useFaster) { - ImageHost.fixLinks(links); - } - for (k = 0, len1 = links.length; k < len1; k++) { - link = links[k]; - Embedding.process(link, this); - } - }, - process: function(node) { - var data, end, endNode, i, index, length, links, part1, part2, ref, ref1, result, saved, snapshot, space, test, word; - test = /[^\s"]+/g; - space = /[\s"]/; - snapshot = $.X('.//br|.//text()', node); - i = 0; - links = []; - while (node = snapshot.snapshotItem(i++)) { - data = node.data; - if (!data || node.parentElement.nodeName === "A") { - continue; - } - while (result = test.exec(data)) { - index = result.index; - endNode = node; - word = result[0]; - if ((length = index + word.length) === data.length) { - test.lastIndex = 0; - while ((saved = snapshot.snapshotItem(i++))) { - if (saved.nodeName === 'BR' || (saved.parentElement.nodeName === 'P' && !saved.previousSibling)) { - if ((part1 = word.match(/(https?:\/\/)?([a-z\d-]+\.)*[a-z\d-]+$/i)) && (part2 = (ref = snapshot.snapshotItem(i)) != null ? (ref1 = ref.data) != null ? ref1.match(/^(\.[a-z\d-]+)*\//i) : void 0 : void 0) && (part1[0] + part2[0]).search(Linkify.regString) === 0) { - continue; - } else { - break; - } - } - if (saved.parentElement.nodeName === "A" && !Linkify.regString.test(word)) { - break; - } - endNode = saved; - data = saved.data; - if (end = space.exec(data)) { - word += data.slice(0, end.index); - test.lastIndex = length = end.index; - i--; - break; - } else { - length = data.length; - word += data; - } - } - } - if (Linkify.regString.test(word)) { - links.push(Linkify.makeRange(node, endNode, index, length)); - } - if (!(test.lastIndex && node === endNode)) { - break; - } - } - } - i = links.length; - while (i--) { - links[i] = Linkify.makeLink(links[i]); - } - return links; - }, - regString: /((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: function(startNode, endNode, startOffset, endOffset) { - var range; - range = document.createRange(); - range.setStart(startNode, startOffset); - range.setEnd(endNode, endOffset); - return range; - }, - makeLink: function(range) { - var a, encodedDomain, i, t, text; - text = range.toString(); - i = text.search(Linkify.regString); - if (i > 0) { - text = text.slice(i); - while (range.startOffset + i >= range.startContainer.data.length) { - i--; - } - if (i) { - range.setStart(range.startContainer, range.startOffset + i); - } - } - i = 0; - while (/[)\]}>.,]/.test(t = text.charAt(text.length - (1 + i)))) { - if (!(/[.,]/.test(t) || (text.match(/[()\[\]{}<>]/g)).length % 2)) { - break; - } - i++; - } - if (i) { - text = text.slice(0, -i); - while (range.endOffset - i < 0) { - i--; - } - if (i) { - range.setEnd(range.endContainer, range.endOffset - i); - } - } - if (!/((mailto|magnet):|.+:\/\/)/.test(text)) { - text = (/@/.test(text) ? 'mailto:' : 'http://') + text; - } - if (encodedDomain = text.match(/^(https?:\/\/[^\/]*%[0-9a-f]{2})(.*)$/i)) { - text = encodedDomain[1].replace(/%([0-9a-f]{2})/ig, function(x, y) { - if (y === '25') { - return x; - } else { - return String.fromCharCode(parseInt(y, 16)); - } - }) + encodedDomain[2]; - } - a = $.el('a', { - className: 'linkify', - rel: 'noreferrer noopener', - target: '_blank', - href: text - }); - $.add(a, range.extractContents()); - range.insertNode(a); - return a; - } - }; - - return Linkify; - -}).call(this); - -ArchiveLink = (function() { - var ArchiveLink; - - ArchiveLink = { - init: function() { - var div, entry, i, len, ref, ref1, type; - if (!(g.SITE.software === 'yotsuba' && ((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Archive Link'])) { - return; - } - div = $.el('div', { - textContent: 'Archive' - }); - entry = { - el: div, - order: 60, - open: function(arg) { - var ID, board, thread; - ID = arg.ID, thread = arg.thread, board = arg.board; - return !!Redirect.to('thread', { - postID: ID, - threadID: thread.ID, - boardID: board.ID - }); - }, - subEntries: [] - }; - ref1 = [['Post', 'post'], ['Name', 'name'], ['Tripcode', 'tripcode'], ['Capcode', 'capcode'], ['Subject', 'subject'], ['Flag', 'country'], ['Filename', 'filename'], ['Image MD5', 'MD5']]; - for (i = 0, len = ref1.length; i < len; i++) { - type = ref1[i]; - entry.subEntries.push(this.createSubEntry(type[0], type[1])); - } - return Menu.menu.addEntry(entry); - }, - createSubEntry: function(text, type) { - var el, open; - el = $.el('a', { - textContent: text, - target: '_blank' - }); - open = type === 'post' ? function(arg) { - var ID, board, thread; - ID = arg.ID, thread = arg.thread, board = arg.board; - el.href = Redirect.to('thread', { - postID: ID, - threadID: thread.ID, - boardID: board.ID - }); - return true; - } : function(post) { - var ref, typeParam, value; - typeParam = type === 'country' && post.info.flagCodeTroll ? 'troll_country' : type; - value = type === 'country' ? post.info.flagCode || ((ref = post.info.flagCodeTroll) != null ? ref.toLowerCase() : void 0) : Filter.values(type, post)[0]; - if (!value) { - return false; - } - el.href = Redirect.to('search', { - boardID: post.board.ID, - type: typeParam, - value: value, - isSearch: true - }); - return true; - }; - return { - el: el, - open: open - }; - } - }; - - return ArchiveLink; - -}).call(this); - -CopyTextLink = (function() { - var CopyTextLink; - - CopyTextLink = { - init: function() { - var a, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Copy Text Link'])) { - return; - } - a = $.el('a', { - className: 'copy-text-link', - href: 'javascript:;', - textContent: 'Copy Text' - }); - $.on(a, 'click', CopyTextLink.copy); - return Menu.menu.addEntry({ - el: a, - order: 12, - open: function(post) { - CopyTextLink.text = (post.origin || post).commentOrig(); - return true; - } - }); - }, - copy: function() { - var el; - el = $.el('textarea', { - className: 'copy-text-element', - value: CopyTextLink.text - }); - $.add(d.body, el); - el.select(); - try { - d.execCommand('copy'); - } catch (error) {} - return $.rm(el); - } - }; - - return CopyTextLink; - -}).call(this); - -DeleteLink = (function() { - var DeleteLink; - - DeleteLink = { - auto: [$.dict(), $.dict()], - init: function() { - var div, fileEl, fileEntry, postEl, postEntry, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Delete Link'])) { - return; - } - div = $.el('div', { - className: 'delete-link', - textContent: 'Delete' - }); - postEl = $.el('a', { - className: 'delete-post', - href: 'javascript:;' - }); - fileEl = $.el('a', { - className: 'delete-file', - href: 'javascript:;' - }); - this.nodes = { - menu: div.firstChild, - links: [postEl, fileEl] - }; - postEntry = { - el: postEl, - open: function() { - postEl.textContent = DeleteLink.linkText(false); - $.on(postEl, 'click', DeleteLink.toggle); - return true; - } - }; - fileEntry = { - el: fileEl, - open: function(arg) { - var file; - file = arg.file; - if (!file || file.isDead) { - return false; - } - fileEl.textContent = DeleteLink.linkText(true); - $.on(fileEl, 'click', DeleteLink.toggle); - return true; - } - }; - return Menu.menu.addEntry({ - el: div, - order: 40, - open: function(post) { - if (post.isDead) { - return false; - } - DeleteLink.post = post; - DeleteLink.nodes.menu.textContent = DeleteLink.menuText(); - DeleteLink.cooldown.start(post); - return true; - }, - subEntries: [postEntry, fileEntry] - }); - }, - menuText: function() { - var seconds; - if (seconds = DeleteLink.cooldown.seconds[DeleteLink.post.fullID]) { - return "Delete (" + seconds + ")"; - } else { - return 'Delete'; - } - }, - linkText: function(fileOnly) { - var text; - text = fileOnly ? 'File' : 'Post'; - if (DeleteLink.auto[+fileOnly][DeleteLink.post.fullID]) { - text = "Deleting " + (text.toLowerCase()) + "..."; - } - return text; - }, - toggle: function() { - var auto, fileOnly, post; - post = DeleteLink.post; - fileOnly = $.hasClass(this, 'delete-file'); - auto = DeleteLink.auto[+fileOnly]; - if (auto[post.fullID]) { - delete auto[post.fullID]; - } else { - auto[post.fullID] = true; - } - this.textContent = DeleteLink.linkText(fileOnly); - if (!DeleteLink.cooldown.seconds[post.fullID]) { - return DeleteLink["delete"](post, fileOnly); - } - }, - "delete": function(post, fileOnly) { - var form, link; - link = DeleteLink.nodes.links[+fileOnly]; - delete DeleteLink.auto[+fileOnly][post.fullID]; - if (post.fullID === DeleteLink.post.fullID) { - $.off(link, 'click', DeleteLink.toggle); - } - form = { - mode: 'usrdel', - onlyimgdel: fileOnly, - pwd: QR.persona.getPassword() - }; - form[+post.ID] = 'delete'; - return $.ajax($.id('delform').action.replace("/" + g.BOARD + "/", "/" + post.board + "/"), { - responseType: 'document', - withCredentials: true, - onloadend: function() { - return DeleteLink.load(link, post, fileOnly, this.response); - }, - form: $.formData(form) - }); - }, - load: function(link, post, fileOnly, resDoc) { - var el, msg; - if (!resDoc) { - new Notice('warning', 'Connection error, please retry.', 20); - if (post.fullID === DeleteLink.post.fullID) { - $.on(link, 'click', DeleteLink.toggle); - } - return; - } - link.textContent = DeleteLink.linkText(fileOnly); - if (resDoc.title === '4chan - Banned') { - el = $.el('span', {innerHTML: "You can't delete posts because you are banned."}); - return new Notice('warning', el, 20); - } else if (msg = resDoc.getElementById('errmsg')) { - new Notice('warning', msg.textContent, 20); - if (post.fullID === DeleteLink.post.fullID) { - $.on(link, 'click', DeleteLink.toggle); - } - if (QR.cooldown.data && Conf['Cooldown'] && /\bwait\b/i.test(msg.textContent)) { - DeleteLink.cooldown.start(post, 5); - DeleteLink.auto[+fileOnly][post.fullID] = true; - return DeleteLink.nodes.links[+fileOnly].textContent = DeleteLink.linkText(fileOnly); - } - } else { - if (!fileOnly) { - QR.cooldown["delete"](post); - } - if (resDoc.title === 'Updating index...') { - (post.origin || post).kill(fileOnly); - } - if (post.fullID === DeleteLink.post.fullID) { - return link.textContent = 'Deleted'; - } - } - }, - cooldown: { - seconds: $.dict(), - start: function(post, seconds) { - if (DeleteLink.cooldown.seconds[post.fullID] != null) { - return; - } - if (seconds == null) { - seconds = QR.cooldown.secondsDeletion(post); - } - if (seconds > 0) { - DeleteLink.cooldown.seconds[post.fullID] = seconds; - return DeleteLink.cooldown.count(post); - } - }, - count: function(post) { - var fileOnly, i, len, ref; - if (post.fullID === DeleteLink.post.fullID) { - DeleteLink.nodes.menu.textContent = DeleteLink.menuText(); - } - if (DeleteLink.cooldown.seconds[post.fullID] > 0 && Conf['Cooldown']) { - DeleteLink.cooldown.seconds[post.fullID]--; - setTimeout(DeleteLink.cooldown.count, 1000, post); - } else { - delete DeleteLink.cooldown.seconds[post.fullID]; - ref = [false, true]; - for (i = 0, len = ref.length; i < len; i++) { - fileOnly = ref[i]; - if (DeleteLink.auto[+fileOnly][post.fullID]) { - DeleteLink["delete"](post, fileOnly); - } - } - } - } - } - }; - - return DeleteLink; - -}).call(this); - -DownloadLink = (function() { - var DownloadLink; - - DownloadLink = { - init: function() { - var a, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Download Link'])) { - return; - } - a = $.el('a', { - className: 'download-link', - textContent: 'Download file' - }); - $.on(a, 'click', ImageCommon.download); - return Menu.menu.addEntry({ - el: a, - order: 100, - open: function(arg) { - var file; - file = arg.file; - if (!file) { - return false; - } - a.href = file.url; - a.download = file.name; - return true; - } - }); - } - }; - - return DownloadLink; - -}).call(this); - -Menu = (function() { - var Menu; - - Menu = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'])) { - return; - } - this.button = $.el('a', { - className: 'menu-button', - href: 'javascript:;' - }); - $.extend(this.button, {innerHTML: ""}); - this.menu = new UI.Menu('post'); - Callbacks.Post.push({ - name: 'Menu', - cb: this.node - }); - return Callbacks.CatalogThread.push({ - name: 'Menu', - cb: this.catalogNode - }); - }, - node: function() { - var button; - if (this.isClone) { - button = $('.menu-button', this.nodes.info); - $.rmClass(button, 'active'); - $.rm($('.dialog', this.nodes.info)); - Menu.makeButton(this, button); - return; - } - return $.add(this.nodes.info, Menu.makeButton(this)); - }, - catalogNode: function() { - return $.after(this.nodes.icons, Menu.makeButton(this.thread.OP)); - }, - makeButton: function(post, button) { - button || (button = Menu.button.cloneNode(true)); - $.on(button, 'click', function(e) { - return Menu.menu.toggle(e, this, post); - }); - return button; - } - }; - - return Menu; - -}).call(this); - -ReportLink = (function() { - var ReportLink; - - ReportLink = { - init: function() { - var a, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Report Link'])) { - return; - } - a = $.el('a', { - className: 'report-link', - href: 'javascript:;', - textContent: 'Report' - }); - $.on(a, 'click', ReportLink.report); - return Menu.menu.addEntry({ - el: a, - order: 10, - open: function(post) { - ReportLink.url = "//sys." + (location.hostname.split('.')[1]) + ".org/" + post.board + "/imgboard.php?mode=report&no=" + post; - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - ReportLink.dims = 'width=350,height=275'; - } else { - ReportLink.dims = 'width=400,height=550'; - } - return true; - } - }); - }, - report: function() { - var dims, id, set, url; - url = ReportLink.url, dims = ReportLink.dims; - id = Date.now(); - set = "toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1," + dims; - return window.open(url, id, set); - } - }; - - return ReportLink; - -}).call(this); - -AntiAutoplay = (function() { - var AntiAutoplay; - - AntiAutoplay = { - init: function() { - var audio, i, len, ref; - if (!Conf['Disable Autoplaying Sounds']) { - return; - } - $.addClass(doc, 'anti-autoplay'); - ref = $$('audio[autoplay]', doc); - for (i = 0, len = ref.length; i < len; i++) { - audio = ref[i]; - this.stop(audio); - } - window.addEventListener('loadstart', ((function(_this) { - return function(e) { - return _this.stop(e.target); - }; - })(this)), true); - Callbacks.Post.push({ - name: 'Disable Autoplaying Sounds', - cb: this.node - }); - return $.ready((function(_this) { - return function() { - return _this.process(d.body); - }; - })(this)); - }, - stop: function(audio) { - if (!audio.autoplay) { - return; - } - audio.pause(); - audio.autoplay = false; - if (audio.controls) { - return; - } - audio.controls = true; - return $.addClass(audio, 'controls-added'); - }, - node: function() { - return AntiAutoplay.process(this.nodes.comment); - }, - process: function(root) { - var i, iframe, j, len, len1, object, ref, ref1; - ref = $$('iframe[src*="youtube"][src*="autoplay=1"]', root); - for (i = 0, len = ref.length; i < len; i++) { - iframe = ref[i]; - AntiAutoplay.processVideo(iframe, 'src'); - } - ref1 = $$('object[data*="youtube"][data*="autoplay=1"]', root); - for (j = 0, len1 = ref1.length; j < len1; j++) { - object = ref1[j]; - AntiAutoplay.processVideo(object, 'data'); - } - }, - processVideo: function(el, attr) { - el[attr] = el[attr].replace(/\?autoplay=1&?/, '?').replace('&autoplay=1', ''); - if (window.getComputedStyle(el).display === 'none') { - el.style.display = 'block'; - } - return $.addClass(el, 'autoplay-removed'); - } - }; - - return AntiAutoplay; - -}).call(this); - -Banner = (function() { - var Banner, - slice = [].slice; - - Banner = { - init: function() { - if (Conf['Custom Board Titles']) { - this.db = new DataBoard('customTitles', null, true); - } - $.asap((function() { - return d.body; - }), function() { - return $.asap((function() { - return $('hr'); - }), Banner.ready); - }); - if (g.BOARD.ID !== 'f') { - return Main.ready(function() { - return $.queueTask(Banner.load); - }); - } - }, - ready: function() { - var banner, children; - banner = $(".boardBanner"); - children = banner.children; - if (g.VIEW === 'thread' && Conf['Remove Thread Excerpt']) { - Banner.setTitle(children[1].textContent); - } - children[0].title = "Click to change"; - $.on(children[0], 'click', Banner.cb.toggle); - if (Conf['Custom Board Titles']) { - Banner.custom(children[1]); - if (children[2]) { - return Banner.custom(children[2]); - } - } - }, - load: function() { - var bannerCnt, img; - bannerCnt = $.id('bannerCnt'); - if (!bannerCnt.firstChild) { - img = $.el('img', { - alt: '4chan', - src: '//s.4cdn.org/image/title/' + bannerCnt.dataset.src - }); - return $.add(bannerCnt, img); - } - }, - setTitle: function(title) { - if (Unread.title != null) { - Unread.title = title; - return Unread.update(); - } else { - return d.title = title; - } - }, - cb: { - toggle: function() { - var banner, i, ref; - if (!((ref = Banner.choices) != null ? ref.length : void 0)) { - Banner.choices = Conf['knownBanners'].split(',').slice(); - } - i = Math.floor(Banner.choices.length * Math.random()); - banner = Banner.choices.splice(i, 1); - return $('img', this.parentNode).src = "//s.4cdn.org/image/title/" + banner; - }, - click: function(e) { - var base, br, j, len, name, ref; - if (!(e.ctrlKey || e.metaKey)) { - return; - } - if ((base = Banner.original)[name = this.className] == null) { - base[name] = this.cloneNode(true); - } - this.contentEditable = true; - ref = $$('br', this); - for (j = 0, len = ref.length; j < len; j++) { - br = ref[j]; - $.replace(br, $.tn('\n')); - } - return this.focus(); - }, - keydown: function(e) { - e.stopPropagation(); - if (!e.shiftKey && e.keyCode === 13) { - return this.blur(); - } - }, - blur: function() { - var br, j, len, ref; - ref = $$('br', this); - for (j = 0, len = ref.length; j < len; j++) { - br = ref[j]; - $.replace(br, $.tn('\n')); - } - if (this.textContent = this.textContent.replace(/\n*$/, '')) { - this.contentEditable = false; - return Banner.db.set({ - boardID: g.BOARD.ID, - threadID: this.className, - val: { - title: this.textContent, - orig: Banner.original[this.className].textContent - } - }); - } else { - $.rmAll(this); - $.add(this, slice.call(Banner.original[this.className].cloneNode(true).childNodes)); - return Banner.db["delete"]({ - boardID: g.BOARD.ID, - threadID: this.className - }); - } - } - }, - original: $.dict(), - custom: function(child) { - var className, data, event, j, len, ref; - className = child.className; - child.title = "Ctrl/\u2318+click to edit board " + (className.slice(5).toLowerCase()); - child.spellcheck = false; - ref = ['click', 'keydown', 'blur']; - for (j = 0, len = ref.length; j < len; j++) { - event = ref[j]; - $.on(child, event, Banner.cb[event]); - } - if (data = Banner.db.get({ - boardID: g.BOARD.ID, - threadID: className - })) { - if (Conf['Persistent Custom Board Titles'] || data.orig === child.textContent) { - Banner.original[className] = child.cloneNode(true); - return child.textContent = data.title; - } else { - return Banner.db["delete"]({ - boardID: g.BOARD.ID, - threadID: className - }); - } - } - } - }; - - return Banner; - -}).call(this); - -CatalogLinks = (function() { - var CatalogLinks; - - CatalogLinks = { - init: function() { - var el, input, selector; - if (g.SITE.software === 'yotsuba' && (Conf['External Catalog'] || Conf['JSON Index']) && !(Conf['JSON Index'] && g.VIEW === 'index')) { - selector = (function() { - switch (g.VIEW) { - case 'thread': - case 'archive': - return '.navLinks.desktop > a'; - case 'catalog': - return '.navLinks > :first-child > a'; - case 'index': - return '#ctrl-top > a, .cataloglink > a'; - } - })(); - $.ready(function() { - var base, catalogLink, catalogURL, i, len, link, link2, ref; - ref = $$(selector); - for (i = 0, len = ref.length; i < len; i++) { - link = ref[i]; - switch (link.pathname.replace(/\/+/g, '/')) { - case "/" + g.BOARD + "/": - if (Conf['JSON Index']) { - link.textContent = 'Index'; - } - link.href = CatalogLinks.index(); - break; - case "/" + g.BOARD + "/catalog": - link.href = CatalogLinks.catalog(); - } - if (g.VIEW === 'catalog' && (catalogURL = CatalogLinks.catalog()) !== (typeof (base = g.SITE.urls).catalog === "function" ? base.catalog(g.BOARD) : void 0)) { - catalogLink = link.parentNode.cloneNode(true); - link2 = catalogLink.firstElementChild; - link2.href = catalogURL; - link2.textContent = link2.hostname === location.hostname ? '4chan X Catalog' : 'External Catalog'; - $.after(link.parentNode, [$.tn(' '), catalogLink]); - } - } - }); - } - if (g.SITE.software === 'yotsuba' && Conf['JSON Index'] && Conf['Use 4chan X Catalog']) { - Callbacks.Post.push({ - name: 'Catalog Link Rewrite', - cb: this.node - }); - } - if ((this.enabled = Conf['Catalog Links'])) { - CatalogLinks.el = el = UI.checkbox('Header catalog links', 'Catalog Links'); - el.id = 'toggleCatalog'; - input = $('input', el); - $.on(input, 'change', this.toggle); - $.sync('Header catalog links', CatalogLinks.set); - return Header.menu.addEntry({ - el: el, - order: 95 - }); - } - }, - node: function() { - var a, i, len, m, ref; - ref = $$('a', this.nodes.comment); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - if (m = a.href.match(/^https?:\/\/(boards\.4chan(?:nel)?\.org\/[^\/]+)\/catalog(#s=.*)?/)) { - a.href = "//" + m[1] + "/" + (m[2] || '#catalog'); - } - } - }, - toggle: function() { - $.event('CloseMenu'); - $.set('Header catalog links', this.checked); - return CatalogLinks.set(this.checked); - }, - set: function(useCatalog) { - Conf['Header catalog links'] = useCatalog; - CatalogLinks.setLinks(Header.boardList); - CatalogLinks.setLinks(Header.bottomBoardList); - CatalogLinks.el.title = "Turn catalog links " + (useCatalog ? 'off' : 'on') + "."; - return $('input', CatalogLinks.el).checked = useCatalog; - }, - setLinks: function(list) { - var VIEW, a, board, boardID, i, len, ref, ref1, ref2, ref3, siteID, tail, url; - if (!(((ref = CatalogLinks.enabled) != null ? ref : Conf['Catalog Links']) && list)) { - return; - } - tail = /(?:index)?(?:\.\w+)?$/; - ref1 = $$('a:not([data-only])', list); - for (i = 0, len = ref1.length; i < len; i++) { - a = ref1[i]; - ref2 = a.dataset, siteID = ref2.siteID, boardID = ref2.boardID; - if (!(siteID && boardID)) { - ref3 = Site.parseURL(a), siteID = ref3.siteID, boardID = ref3.boardID, VIEW = ref3.VIEW; - if (!(siteID && boardID && (VIEW === 'index' || VIEW === 'catalog') && (a.dataset.indexOptions || a.href.replace(tail, '') === (Get.url(VIEW, { - siteID: siteID, - boardID: boardID - }) || '').replace(tail, '')))) { - continue; - } - $.extend(a.dataset, { - siteID: siteID, - boardID: boardID - }); - } - board = { - siteID: siteID, - boardID: boardID - }; - url = Conf['Header catalog links'] ? CatalogLinks.catalog(board) : Get.url('index', board); - if (url) { - a.href = url; - if (a.dataset.indexOptions && url.split('#')[0] === Get.url('index', board)) { - a.href += (a.hash ? '/' : '#') + a.dataset.indexOptions; - } - } - } - }, - externalParse: function() { - var board, boards, excludes, i, len, line, ref, ref1, ref2, url; - CatalogLinks.externalList = $.dict(); - ref = Conf['externalCatalogURLs'].split('\n'); - for (i = 0, len = ref.length; i < len; i++) { - line = ref[i]; - if (line[0] === '#') { - continue; - } - url = line.split(';')[0]; - boards = Filter.parseBoards(((ref1 = line.match(/;boards:([^;]+)/)) != null ? ref1[1] : void 0) || '*'); - excludes = Filter.parseBoards((ref2 = line.match(/;exclude:([^;]+)/)) != null ? ref2[1] : void 0) || $.dict(); - for (board in boards) { - if (!(excludes[board] || excludes[board.split('/')[0] + '/*'])) { - CatalogLinks.externalList[board] = url; - } - } - } - }, - external: function(arg) { - var boardID, external, siteID; - siteID = arg.siteID, boardID = arg.boardID; - if (!CatalogLinks.externalList) { - CatalogLinks.externalParse(); - } - external = CatalogLinks.externalList[siteID + "/" + boardID] || CatalogLinks.externalList[siteID + "/*"]; - if (external) { - return external.replace(/%board/g, boardID); - } else { - return void 0; - } - }, - jsonIndex: function(board, hash) { - if (g.SITE.ID === board.siteID && g.BOARD.ID === board.boardID && g.VIEW === 'index') { - return hash; - } else { - return Get.url('index', board) + hash; - } - }, - catalog: function(board) { - var external, nativeCatalog; - if (board == null) { - board = g.BOARD; - } - if (Conf['External Catalog'] && (external = CatalogLinks.external(board))) { - return external; - } else if (Index.enabledOn(board) && Conf['Use 4chan X Catalog']) { - return CatalogLinks.jsonIndex(board, '#catalog'); - } else if ((nativeCatalog = Get.url('catalog', board))) { - return nativeCatalog; - } else { - return CatalogLinks.external(board); - } - }, - index: function(board) { - if (board == null) { - board = g.BOARD; - } - if (Index.enabledOn(board)) { - return CatalogLinks.jsonIndex(board, '#index'); - } else { - return Get.url('index', board); - } - } - }; - - return CatalogLinks; - -}).call(this); - -CustomCSS = (function() { - var CustomCSS; - - CustomCSS = { - init: function() { - if (!Conf['Custom CSS']) { - return; - } - return this.addStyle(); - }, - addStyle: function() { - return this.style = $.addStyle(CSS.sub(Conf['usercss']), 'custom-css', '#fourchanx-css'); - }, - rmStyle: function() { - if (this.style) { - $.rm(this.style); - return delete this.style; - } - }, - update: function() { - if (!this.style) { - return this.addStyle(); - } - return this.style.textContent = CSS.sub(Conf['usercss']); - } - }; - - return CustomCSS; - -}).call(this); - -ExpandComment = (function() { - var ExpandComment; - - ExpandComment = { - init: function() { - if (g.VIEW !== 'index' || !Conf['Comment Expansion'] || Conf['JSON Index']) { - return; - } - return Callbacks.Post.push({ - name: 'Comment Expansion', - cb: this.node - }); - }, - node: function() { - var a; - if (a = $('.abbr > a:not([onclick])', this.nodes.comment)) { - return $.on(a, 'click', ExpandComment.cb); - } - }, - callbacks: [], - cb: function(e) { - e.preventDefault(); - return ExpandComment.expand(Get.postFromNode(this)); - }, - expand: function(post) { - var a; - if (post.nodes.longComment && !post.nodes.longComment.parentNode) { - $.replace(post.nodes.shortComment, post.nodes.longComment); - post.nodes.comment = post.nodes.longComment; - return; - } - if (!(a = $('.abbr > a', post.nodes.comment))) { - return; - } - a.textContent = "Post No." + post + " Loading..."; - return $.cache(g.SITE.urls.threadJSON({ - boardID: post.boardID, - threadID: post.threadID - }), function() { - return ExpandComment.parse(this, a, post); - }); - }, - contract: function(post) { - var a; - if (!post.nodes.shortComment) { - return; - } - a = $('.abbr > a', post.nodes.shortComment); - a.textContent = 'here'; - $.replace(post.nodes.longComment, post.nodes.shortComment); - return post.nodes.comment = post.nodes.shortComment; - }, - parse: function(req, a, post) { - var callback, clone, comment, href, i, j, k, len, len1, len2, postObj, posts, quote, ref, ref1, spoilerRange, status; - status = req.status; - if (status !== 200 && status !== 304) { - a.textContent = status ? "Error " + req.statusText + " (" + status + ")" : 'Connection Error'; - return; - } - posts = req.response.posts; - if (spoilerRange = posts[0].custom_spoiler) { - g.SITE.Build.spoilerRange[g.BOARD] = spoilerRange; - } - for (i = 0, len = posts.length; i < len; i++) { - postObj = posts[i]; - if (postObj.no === post.ID) { - break; - } - } - if (postObj.no !== post.ID) { - a.textContent = "Post No." + post + " not found."; - return; - } - comment = post.nodes.comment; - clone = comment.cloneNode(false); - clone.innerHTML = postObj.com; - ref = $$('.quotelink', clone); - for (j = 0, len1 = ref.length; j < len1; j++) { - quote = ref[j]; - href = quote.getAttribute('href'); - if (href[0] === '/') { - continue; - } - if (href[0] === '#') { - quote.href = "" + (a.pathname.split(/\/+/).splice(0, 4).join('/')) + href; - } else { - quote.href = (a.pathname.split(/\/+/).splice(0, 3).join('/')) + "/" + href; - } - } - post.nodes.shortComment = comment; - $.replace(comment, clone); - post.nodes.comment = post.nodes.longComment = clone; - post.parseComment(); - post.parseQuotes(); - ref1 = ExpandComment.callbacks; - for (k = 0, len2 = ref1.length; k < len2; k++) { - callback = ref1[k]; - callback.call(post); - } - } - }; - - return ExpandComment; - -}).call(this); - -ExpandThread = (function() { - var ExpandThread, - slice = [].slice; - - ExpandThread = { - statuses: $.dict(), - init: function() { - if (!(g.VIEW === 'index' && Conf['Thread Expansion'])) { - return; - } - if (Conf['JSON Index']) { - return $.on(d, 'IndexRefreshInternal', this.onIndexRefresh); - } else { - return Callbacks.Thread.push({ - name: 'Expand Thread', - cb: function() { - return ExpandThread.setButton(this); - } - }); - } - }, - setButton: function(thread) { - var a, ref; - if (!(thread.nodes.root && (a = $('.summary', thread.nodes.root)))) { - return; - } - a.textContent = (ref = g.SITE.Build).summaryText.apply(ref, ['+'].concat(slice.call(a.textContent.match(/\d+/g)))); - a.style.cursor = 'pointer'; - return $.on(a, 'click', ExpandThread.cbToggle); - }, - disconnect: function(refresh) { - var oldReq, ref, status, threadID; - if (g.VIEW === 'thread' || !Conf['Thread Expansion']) { - return; - } - ref = ExpandThread.statuses; - for (threadID in ref) { - status = ref[threadID]; - if ((oldReq = status.req)) { - delete status.req; - oldReq.abort(); - } - delete ExpandThread.statuses[threadID]; - } - if (!refresh) { - return $.off(d, 'IndexRefreshInternal', this.onIndexRefresh); - } - }, - onIndexRefresh: function() { - ExpandThread.disconnect(true); - return g.BOARD.threads.forEach(function(thread) { - return ExpandThread.setButton(thread); - }); - }, - cbToggle: function(e) { - if ($.modifiedClick(e)) { - return; - } - e.preventDefault(); - return ExpandThread.toggle(Get.threadFromNode(this)); - }, - cbToggleBottom: function(e) { - var bottom, thread; - if ($.modifiedClick(e)) { - return; - } - e.preventDefault(); - thread = Get.threadFromNode(this); - $.rm(this); - bottom = thread.nodes.root.getBoundingClientRect().bottom; - ExpandThread.toggle(thread); - return window.scrollBy(0, thread.nodes.root.getBoundingClientRect().bottom - bottom); - }, - toggle: function(thread) { - var a; - if (!(thread.nodes.root && (a = $('.summary', thread.nodes.root)))) { - return; - } - if (thread.ID in ExpandThread.statuses) { - return ExpandThread.contract(thread, a, thread.nodes.root); - } else { - return ExpandThread.expand(thread, a); - } - }, - expand: function(thread, a) { - var ref, status; - ExpandThread.statuses[thread] = status = {}; - a.textContent = (ref = g.SITE.Build).summaryText.apply(ref, ['...'].concat(slice.call(a.textContent.match(/\d+/g)))); - status.req = $.cache(g.SITE.urls.threadJSON({ - boardID: thread.board.ID, - threadID: thread.ID - }), function() { - if (this !== status.req) { - return; - } - delete status.req; - return ExpandThread.parse(this, thread, a); - }); - return status.numReplies = $$(g.SITE.selectors.replyOriginal, thread.nodes.root).length; - }, - contract: function(thread, a, threadRoot) { - var filesCount, i, inlined, len, oldReq, postsCount, ref, replies, reply, status; - status = ExpandThread.statuses[thread]; - delete ExpandThread.statuses[thread]; - if ((oldReq = status.req)) { - delete status.req; - oldReq.abort(); - if (a) { - a.textContent = (ref = g.SITE.Build).summaryText.apply(ref, ['+'].concat(slice.call(a.textContent.match(/\d+/g)))); - } - return; - } - replies = $$('.thread > .replyContainer', threadRoot); - if (status.numReplies) { - replies = replies.slice(0, -status.numReplies); - } - postsCount = 0; - filesCount = 0; - for (i = 0, len = replies.length; i < len; i++) { - reply = replies[i]; - if (Conf['Quote Inlining']) { - while (inlined = $('.inlined', reply)) { - inlined.click(); - } - } - postsCount++; - if ('file' in Get.postFromRoot(reply)) { - filesCount++; - } - $.rm(reply); - } - if (Index.enabled) { - $.event('PostsRemoved', null, a.parentNode); - } - a.textContent = g.SITE.Build.summaryText('+', postsCount, filesCount); - return $.rm($('.summary-bottom', threadRoot)); - }, - parse: function(req, thread, a) { - var a2, filesCount, i, len, post, postData, posts, postsCount, postsRoot, ref, ref1, root; - if ((ref = req.status) !== 200 && ref !== 304) { - a.textContent = req.status ? "Error " + req.statusText + " (" + req.status + ")" : 'Connection Error'; - return; - } - g.SITE.Build.spoilerRange[thread.board] = req.response.posts[0].custom_spoiler; - posts = []; - postsRoot = []; - filesCount = 0; - ref1 = req.response.posts; - for (i = 0, len = ref1.length; i < len; i++) { - postData = ref1[i]; - if (postData.no === thread.ID) { - continue; - } - if ((post = thread.posts.get(postData.no)) && !post.isFetchedQuote) { - if ('file' in post) { - filesCount++; - } - root = post.nodes.root; - postsRoot.push(root); - continue; - } - root = g.SITE.Build.postFromObject(postData, thread.board.ID); - post = new Post(root, thread, thread.board); - if ('file' in post) { - filesCount++; - } - posts.push(post); - postsRoot.push(root); - } - Main.callbackNodes('Post', posts); - $.after(a, postsRoot); - $.event('PostsInserted', null, a.parentNode); - postsCount = postsRoot.length; - a.textContent = g.SITE.Build.summaryText('-', postsCount, filesCount); - if (root) { - a2 = a.cloneNode(true); - a2.classList.add('summary-bottom'); - $.on(a2, 'click', ExpandThread.cbToggleBottom); - return $.after(root, a2); - } - } - }; - - return ExpandThread; - -}).call(this); - -FileInfo = (function() { - var FileInfo; - - FileInfo = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread' && ref !== 'archive') || !Conf['File Info Formatting']) { - return; - } - return Callbacks.Post.push({ - name: 'File Info Formatting', - cb: this.node - }); - }, - node: function() { - var a, i, info, j, len, len1, oldInfo, ref, ref1; - if (!this.file) { - return; - } - if (this.isClone) { - ref = $$('.file-info .download-button', this.file.text); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - $.on(a, 'click', ImageCommon.download); - } - ref1 = $$('.file-info .quick-filter-md5', this.file.text); - for (j = 0, len1 = ref1.length; j < len1; j++) { - a = ref1[j]; - $.on(a, 'click', Filter.quickFilterMD5); - } - return; - } - oldInfo = $.el('span', { - className: 'fileText-original' - }); - $.prepend(this.file.link.parentNode, oldInfo); - $.add(oldInfo, [this.file.link.previousSibling, this.file.link, this.file.link.nextSibling]); - info = $.el('span', { - className: 'file-info' - }); - FileInfo.format(Conf['fileInfo'], this, info); - return $.prepend(this.file.text, info); - }, - format: function(formatString, post, outputNode) { - var a, i, j, len, len1, output, ref, ref1; - output = []; - formatString.replace(/%(.)|[^%]+/g, function(s, c) { - output.push($.hasOwn(FileInfo.formatters, c) ? FileInfo.formatters[c].call(post) : {innerHTML: E(s)}); - return ''; - }); - $.extend(outputNode, {innerHTML: E.cat(output)}); - ref = $$('.download-button', outputNode); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - $.on(a, 'click', ImageCommon.download); - } - ref1 = $$('.quick-filter-md5', outputNode); - for (j = 0, len1 = ref1.length; j < len1; j++) { - a = ref1[j]; - $.on(a, 'click', Filter.quickFilterMD5); - } - }, - formatters: { - t: function() { - return {innerHTML: E(this.file.url.match(/[^/]*$/)[0])}; - }, - T: function() { - return {innerHTML: "" + (FileInfo.formatters.t.call(this)).innerHTML + ""}; - }, - l: function() { - return {innerHTML: "" + (FileInfo.formatters.n.call(this)).innerHTML + ""}; - }, - L: function() { - return {innerHTML: "" + (FileInfo.formatters.N.call(this)).innerHTML + ""}; - }, - n: function() { - var fullname, shortname; - fullname = this.file.name; - shortname = SW.yotsuba.Build.shortFilename(this.file.name, this.isReply); - if (fullname === shortname) { - return {innerHTML: E(fullname)}; - } else { - return {innerHTML: "" + E(shortname) + "" + E(fullname) + ""}; - } - }, - N: function() { - return {innerHTML: E(this.file.name)}; - }, - d: function() { - return {innerHTML: ""}; - }, - f: function() { - return {innerHTML: ""}; - }, - p: function() { - return {innerHTML: ((this.file.isSpoiler) ? "Spoiler, " : "")}; - }, - s: function() { - return {innerHTML: E(this.file.size)}; - }, - B: function() { - return {innerHTML: E(Math.round(this.file.sizeInBytes)) + " Bytes"}; - }, - K: function() { - return {innerHTML: E(Math.round(this.file.sizeInBytes/1024)) + " KB"}; - }, - M: function() { - return {innerHTML: E(Math.round(this.file.sizeInBytes/1048576*100)/100) + " MB"}; - }, - r: function() { - return {innerHTML: E(this.file.dimensions || "PDF")}; - }, - g: function() { - return {innerHTML: ((this.file.tag) ? ", " + E(this.file.tag) : "")}; - }, - '%': function() { - return {innerHTML: "%"}; - } - } - }; - - return FileInfo; - -}).call(this); - -Flash = (function() { - var Flash; - - Flash = { - init: function() { - if (g.BOARD.ID === 'f' && Conf['Enable Native Flash Embedding']) { - return $.ready(Flash.initReady); - } - }, - initReady: function() { - if ($.hasStorage) { - return $.global(function() { - if (JSON.parse(localStorage['4chan-settings'] || '{}').disableAll) { - return window.SWFEmbed.init(); - } - }); - } else { - if (g.VIEW === 'thread') { - $.global(function() { - return window.Main.tid = location.pathname.split(/\/+/)[3]; - }); - } - return $.global(function() { - return window.SWFEmbed.init(); - }); - } - } - }; - - return Flash; - -}).call(this); - -Fourchan = (function() { - var Fourchan; - - Fourchan = { - init: function() { - var ref; - if (!(g.SITE.software === 'yotsuba' && ((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive'))) { - return; - } - BoardConfig.ready(this.initBoard); - return Main.ready(this.initReady); - }, - initBoard: function() { - if (g.BOARD.config.code_tags) { - $.on(window, 'prettyprint:cb', function(e) { - var post, pre; - if (!(post = g.posts.get(e.detail.ID))) { - return; - } - if (!(pre = $$('.prettyprint', post.nodes.comment)[+e.detail.i])) { - return; - } - if (!$.hasClass(pre, 'prettyprinted')) { - pre.innerHTML = e.detail.html; - return $.addClass(pre, 'prettyprinted'); - } - }); - $.global(function() { - return window.addEventListener('prettyprint', function(e) { - return window.dispatchEvent(new CustomEvent('prettyprint:cb', { - detail: { - ID: e.detail.ID, - i: e.detail.i, - html: window.prettyPrintOne(e.detail.html) - } - })); - }, false); - }); - Callbacks.Post.push({ - name: 'Parse [code] tags', - cb: Fourchan.code - }); - g.posts.forEach(function(post) { - if (post.callbacksExecuted) { - return Callbacks.Post.execute(post, ['Parse [code] tags'], true); - } - }); - ExpandComment.callbacks.push(Fourchan.code); - } - if (g.BOARD.config.math_tags) { - $.global(function() { - return window.addEventListener('mathjax', function(e) { - if (window.MathJax) { - return window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, e.target]); - } else { - if (!document.querySelector('script[src^="//cdn.mathjax.org/"]')) { - window.loadMathJax(); - window.loadMathJax = function() {}; - } - if (!e.target.classList.contains('postMessage')) { - return document.querySelector('script[src^="//cdn.mathjax.org/"]').addEventListener('load', function() { - return window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, e.target]); - }, false); - } - } - }, false); - }); - Callbacks.Post.push({ - name: 'Parse [math] tags', - cb: Fourchan.math - }); - g.posts.forEach(function(post) { - if (post.callbacksExecuted) { - return Callbacks.Post.execute(post, ['Parse [math] tags'], true); - } - }); - return ExpandComment.callbacks.push(Fourchan.math); - } - }, - initReady: function() { - return $.global(function() { - var j, len, node, ref; - window.clickable_ids = false; - ref = document.querySelectorAll('.posteruid, .capcode'); - for (j = 0, len = ref.length; j < len; j++) { - node = ref[j]; - node.removeEventListener('click', window.idClick, false); - } - }); - }, - code: function() { - if (this.isClone) { - return; - } - return $.ready((function(_this) { - return function() { - var i, j, len, pre, ref; - ref = $$('.prettyprint', _this.nodes.comment); - for (i = j = 0, len = ref.length; j < len; i = ++j) { - pre = ref[i]; - if (!$.hasClass(pre, 'prettyprinted')) { - $.event('prettyprint', { - ID: _this.fullID, - i: i, - html: pre.innerHTML - }, window); - } - } - }; - })(this)); - }, - math: function() { - var cb, j, len, wbr, wbrs; - if (!/\[(math|eqn)\]/.test(this.nodes.comment.textContent)) { - return; - } - if ((wbrs = $$('wbr', this.nodes.comment)).length) { - for (j = 0, len = wbrs.length; j < len; j++) { - wbr = wbrs[j]; - $.rm(wbr); - } - this.nodes.comment.normalize(); - } - cb = (function(_this) { - return function() { - if (!doc.contains(_this.nodes.comment)) { - return; - } - $.off(d, 'PostsInserted', cb); - return $.event('mathjax', null, _this.nodes.comment); - }; - })(this); - $.on(d, 'PostsInserted', cb); - return cb(); - } - }; - - return Fourchan; - -}).call(this); - -IDColor = (function() { - var IDColor; - - IDColor = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Color User IDs'])) { - return; - } - this.ids = $.dict(); - this.ids['Heaven'] = [0, 0, 0, '#fff']; - return Callbacks.Post.push({ - name: 'Color User IDs', - cb: this.node - }); - }, - node: function() { - var rgb, span, style, uid; - if (this.isClone || !((uid = this.info.uniqueID) && (span = this.nodes.uniqueID))) { - return; - } - rgb = IDColor.ids[uid] || IDColor.compute(uid); - style = span.style; - style.color = rgb[3]; - style.backgroundColor = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")"; - return $.addClass(span, 'painted'); - }, - compute: function(uid) { - var hash, rgb; - hash = g.SITE.uidColor ? g.SITE.uidColor(uid) : parseInt(uid, 16); - rgb = [(hash >> 16) & 0xFF, (hash >> 8) & 0xFF, hash & 0xFF]; - rgb.push($.luma(rgb) > 125 ? '#000' : '#fff'); - return this.ids[uid] = rgb; - } - }; - - return IDColor; - -}).call(this); - -IDHighlight = (function() { - var IDHighlight; - - IDHighlight = { - init: function() { - var ref; - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - return Callbacks.Post.push({ - name: 'Highlight by User ID', - cb: this.node - }); - }, - uniqueID: null, - node: function() { - if (this.nodes.uniqueIDRoot) { - $.on(this.nodes.uniqueIDRoot, 'click', IDHighlight.click(this)); - } - if (this.nodes.capcode) { - $.on(this.nodes.capcode, 'click', IDHighlight.click(this)); - } - if (!this.isClone) { - return IDHighlight.set(this); - } - }, - set: function(post) { - var match; - match = (post.info.uniqueID || post.info.capcode) === IDHighlight.uniqueID; - return $[match ? 'addClass' : 'rmClass'](post.nodes.post, 'highlight'); - }, - click: function(post) { - return function() { - var uniqueID; - uniqueID = post.info.uniqueID || post.info.capcode; - IDHighlight.uniqueID = IDHighlight.uniqueID === uniqueID ? null : uniqueID; - return g.posts.forEach(IDHighlight.set); - }; - } - }; - - return IDHighlight; - -}).call(this); - -IDPostCount = (function() { - var IDPostCount; - - IDPostCount = { - init: function() { - if (!(g.VIEW === 'thread' && Conf['Count Posts by ID'])) { - return; - } - Callbacks.Thread.push({ - name: 'Count Posts by ID', - cb: function() { - return IDPostCount.thread = this; - } - }); - return Callbacks.Post.push({ - name: 'Count Posts by ID', - cb: this.node - }); - }, - node: function() { - if (this.nodes.uniqueID && this.thread === IDPostCount.thread) { - return $.on(this.nodes.uniqueID, 'mouseover', IDPostCount.count); - } - }, - count: function() { - var n, uniqueID; - uniqueID = Get.postFromNode(this).info.uniqueID; - n = 0; - IDPostCount.thread.posts.forEach(function(post) { - if (post.info.uniqueID === uniqueID) { - return n++; - } - }); - return this.title = n + " post" + (n === 1 ? '' : 's') + " by this ID"; - } - }; - - return IDPostCount; - -}).call(this); - -Keybinds = (function() { - var Keybinds; - - Keybinds = { - init: function() { - var hotkey, init; - if (!Conf['Keybinds']) { - return; - } - for (hotkey in Config.hotkeys) { - $.sync(hotkey, Keybinds.sync); - } - init = function() { - var i, len, node, ref; - $.off(d, '4chanXInitFinished', init); - $.on(d, 'keydown', Keybinds.keydown); - ref = $$('[accesskey]'); - for (i = 0, len = ref.length; i < len; i++) { - node = ref[i]; - node.removeAttribute('accesskey'); - } - }; - return $.on(d, '4chanXInitFinished', init); - }, - sync: function(key, hotkey) { - return Conf[hotkey] = key; - }, - keydown: function(e) { - var base, base1, catalog, i, key, len, notification, notifications, post, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, searchInput, target, thread, threadRoot; - if (!(key = Keybinds.keyCode(e))) { - return; - } - target = e.target; - if ((ref = target.nodeName) === 'INPUT' || ref === 'TEXTAREA') { - if (!(/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(key) && !/^Alt\+(\d|Up|Down|Left|Right)$/.test(key))) { - return; - } - } - if ((ref1 = g.VIEW) === 'index' || ref1 === 'thread') { - threadRoot = Nav.getThread(); - thread = Get.threadFromRoot(threadRoot); - } - switch (key) { - case Conf['Toggle board list']: - if (!Conf['Custom Board Navigation']) { - return; - } - Header.toggleBoardList(); - break; - case Conf['Toggle header']: - Header.toggleBarVisibility(); - break; - case Conf['Open empty QR']: - if (!QR.postingIsEnabled) { - return; - } - Keybinds.qr(); - break; - case Conf['Open QR']: - if (!(QR.postingIsEnabled && threadRoot)) { - return; - } - Keybinds.qr(threadRoot); - break; - case Conf['Open settings']: - Settings.open(); - break; - case Conf['Close']: - if (Settings.dialog) { - Settings.close(); - } else if ((notifications = $$('.notification')).length) { - for (i = 0, len = notifications.length; i < len; i++) { - notification = notifications[i]; - $('.close', notification).click(); - } - } else if (QR.nodes && !(QR.nodes.el.hidden || window.getComputedStyle(QR.nodes.form).display === 'none')) { - if (Conf['Persistent QR']) { - QR.hide(); - } else { - QR.close(); - } - } else if (Embedding.lastEmbed) { - Embedding.closeFloat(); - } else { - return; - } - break; - case Conf['Spoiler tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('spoiler', target); - break; - case Conf['Code tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('code', target); - break; - case Conf['Eqn tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('eqn', target); - break; - case Conf['Math tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('math', target); - break; - case Conf['SJIS tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('sjis', target); - break; - case Conf['Toggle sage']: - if (!(QR.nodes && !QR.nodes.el.hidden)) { - return; - } - Keybinds.sage(); - break; - case Conf['Toggle Cooldown']: - if (!(QR.nodes && !QR.nodes.el.hidden && $.hasClass(QR.nodes.fileSubmit, 'custom-cooldown'))) { - return; - } - QR.toggleCustomCooldown(); - break; - case Conf['Post from URL']: - if (!QR.postingIsEnabled) { - return; - } - QR.handleUrl(''); - break; - case Conf['Add new post']: - if (!QR.postingIsEnabled) { - return; - } - QR.addPost(); - break; - case Conf['Submit QR']: - if (!(QR.nodes && !QR.nodes.el.hidden)) { - return; - } - if (!QR.status()) { - QR.submit(); - } - break; - case Conf['Update']: - switch (g.VIEW) { - case 'thread': - if (!ThreadUpdater.enabled) { - return; - } - ThreadUpdater.update(); - break; - case 'index': - if (!Index.enabled) { - return; - } - Index.update(); - break; - default: - return; - } - break; - case Conf['Watch']: - if (!(ThreadWatcher.enabled && thread)) { - return; - } - ThreadWatcher.toggle(thread); - break; - case Conf['Update thread watcher']: - if (!ThreadWatcher.enabled) { - return; - } - ThreadWatcher.buttonFetchAll(); - break; - case Conf['Toggle thread watcher']: - if (!ThreadWatcher.enabled) { - return; - } - ThreadWatcher.toggleWatcher(); - break; - case Conf['Toggle threading']: - if (!QuoteThreading.ready) { - return; - } - QuoteThreading.toggleThreading(); - break; - case Conf['Mark thread read']: - if (!(g.VIEW === 'index' && thread && UnreadIndex.enabled)) { - return; - } - UnreadIndex.markRead.call(threadRoot); - break; - case Conf['Expand image']: - if (!(ImageExpand.enabled && threadRoot)) { - return; - } - post = Get.postFromNode(Keybinds.post(threadRoot)); - if (post.file) { - ImageExpand.toggle(post); - } - break; - case Conf['Expand images']: - if (!ImageExpand.enabled) { - return; - } - ImageExpand.cb.toggleAll(); - break; - case Conf['Open Gallery']: - if (!Gallery.enabled) { - return; - } - Gallery.cb.toggle(); - break; - case Conf['fappeTyme']: - if (!((ref2 = FappeTyme.nodes) != null ? ref2.fappe : void 0)) { - return; - } - FappeTyme.toggle('fappe'); - break; - case Conf['werkTyme']: - if (!((ref3 = FappeTyme.nodes) != null ? ref3.werk : void 0)) { - return; - } - FappeTyme.toggle('werk'); - break; - case Conf['Front page']: - if (Index.enabled) { - Index.userPageNav(1); - } else { - location.href = "/" + g.BOARD + "/"; - } - break; - case Conf['Open front page']: - $.open(location.origin + "/" + g.BOARD + "/"); - break; - case Conf['Next page']: - if (!(g.VIEW === 'index' && !(typeof (base = g.SITE).isOnePage === "function" ? base.isOnePage(g.BOARD) : void 0))) { - return; - } - if (Index.enabled) { - if ((ref4 = Conf['Index Mode']) !== 'paged' && ref4 !== 'infinite') { - return; - } - $('.next button', Index.pagelist).click(); - } else { - if ((ref5 = $(g.SITE.selectors.nav.next)) != null) { - ref5.click(); - } - } - break; - case Conf['Previous page']: - if (!(g.VIEW === 'index' && !(typeof (base1 = g.SITE).isOnePage === "function" ? base1.isOnePage(g.BOARD) : void 0))) { - return; - } - if (Index.enabled) { - if ((ref6 = Conf['Index Mode']) !== 'paged' && ref6 !== 'infinite') { - return; - } - $('.prev button', Index.pagelist).click(); - } else { - if ((ref7 = $(g.SITE.selectors.nav.prev)) != null) { - ref7.click(); - } - } - break; - case Conf['Search form']: - if (g.VIEW !== 'index') { - return; - } - searchInput = Index.enabled ? Index.searchInput : g.SITE.selectors.searchBox ? $(g.SITE.selectors.searchBox) : void 0; - if (!searchInput) { - return; - } - Header.scrollToIfNeeded(searchInput); - searchInput.focus(); - break; - case Conf['Paged mode']: - if (!Index.enabledOn(g.BOARD)) { - return; - } - location.href = g.VIEW === 'index' ? '#paged' : "/" + g.BOARD + "/#paged"; - break; - case Conf['Infinite scrolling mode']: - if (!Index.enabledOn(g.BOARD)) { - return; - } - location.href = g.VIEW === 'index' ? '#infinite' : "/" + g.BOARD + "/#infinite"; - break; - case Conf['All pages mode']: - if (!Index.enabledOn(g.BOARD)) { - return; - } - location.href = g.VIEW === 'index' ? '#all-pages' : "/" + g.BOARD + "/#all-pages"; - break; - case Conf['Open catalog']: - if (!(catalog = CatalogLinks.catalog())) { - return; - } - location.href = catalog; - break; - case Conf['Cycle sort type']: - if (!Index.enabled) { - return; - } - Index.cycleSortType(); - break; - case Conf['Next thread']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - Nav.scroll(+1); - break; - case Conf['Previous thread']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - Nav.scroll(-1); - break; - case Conf['Expand thread']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - ExpandThread.toggle(thread); - Header.scrollTo(threadRoot); - break; - case Conf['Open thread']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - Keybinds.open(thread); - break; - case Conf['Open thread tab']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - Keybinds.open(thread, true); - break; - case Conf['Next reply']: - if (!threadRoot) { - return; - } - Keybinds.hl(+1, threadRoot); - break; - case Conf['Previous reply']: - if (!threadRoot) { - return; - } - Keybinds.hl(-1, threadRoot); - break; - case Conf['Deselect reply']: - if (!threadRoot) { - return; - } - Keybinds.hl(0, threadRoot); - break; - case Conf['Hide']: - if (!(thread && ThreadHiding.db)) { - return; - } - Header.scrollTo(threadRoot); - ThreadHiding.toggle(thread); - break; - case Conf['Quick Filter MD5']: - if (!threadRoot) { - return; - } - post = Keybinds.post(threadRoot); - Keybinds.hl(+1, threadRoot); - Filter.quickFilterMD5.call(post, e); - break; - case Conf['Previous Post Quoting You']: - if (!(threadRoot && QuoteYou.db)) { - return; - } - QuoteYou.cb.seek('preceding'); - break; - case Conf['Next Post Quoting You']: - if (!(threadRoot && QuoteYou.db)) { - return; - } - QuoteYou.cb.seek('following'); - break; - default: - return; - } - e.preventDefault(); - return e.stopPropagation(); - }, - keyCode: function(e) { - var kc, key; - key = (function() { - switch (kc = 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: - if ((48 <= kc && kc <= 57) || (65 <= kc && kc <= 90)) { - return String.fromCharCode(kc).toLowerCase(); - } else if ((96 <= kc && kc <= 105)) { - return String.fromCharCode(kc - 48).toLowerCase(); - } else { - return null; - } - } - })(); - if (key) { - if (e.altKey) { - key = 'Alt+' + key; - } - if (e.ctrlKey) { - key = 'Ctrl+' + key; - } - if (e.metaKey) { - key = 'Meta+' + key; - } - if (e.shiftKey) { - key = 'Shift+' + key; - } - } - return key; - }, - post: function(thread) { - var s; - s = g.SITE.selectors; - return $("" + s.postContainer + s.highlightable.reply + "." + g.SITE.classes.highlight, thread) || $("" + (g.SITE.isOPContainerThread ? s.thread : s.postContainer) + s.highlightable.op, thread); - }, - qr: function(thread) { - QR.open(); - if (thread != null) { - QR.quote.call(Keybinds.post(thread)); - } - return QR.nodes.com.focus(); - }, - tags: function(tag, ta) { - var range, selEnd, selStart, value; - BoardConfig.ready(function() { - var config, supported; - config = g.BOARD.config; - supported = (function() { - switch (tag) { - case 'spoiler': - return !!config.spoilers; - case 'code': - return !!config.code_tags; - case 'math': - case 'eqn': - return !!config.math_tags; - case 'sjis': - return !!config.sjis_tags; - } - })(); - if (!supported) { - return new Notice('warning', "[" + tag + "] tags are not supported on /" + g.BOARD + "/.", 20); - } - }); - value = ta.value; - selStart = ta.selectionStart; - selEnd = ta.selectionEnd; - ta.value = value.slice(0, selStart) + ("[" + tag + "]") + value.slice(selStart, selEnd) + ("[/" + tag + "]") + value.slice(selEnd); - range = ("[" + tag + "]").length + selEnd; - ta.setSelectionRange(range, range); - return $.event('input', null, ta); - }, - sage: function() { - var isSage; - isSage = /sage/i.test(QR.nodes.email.value); - return QR.nodes.email.value = isSage ? "" : "sage"; - }, - open: function(thread, tab) { - var url; - if (g.VIEW !== 'index') { - return; - } - url = Get.url('thread', thread); - if (tab) { - return $.open(url); - } else { - return location.href = url; - } - }, - hl: function(delta, thread) { - var axis, height, highlight, i, len, next, postEl, replies, reply, replySelector, root; - replySelector = "" + g.SITE.selectors.postContainer + g.SITE.selectors.highlightable.reply; - highlight = g.SITE.classes.highlight; - postEl = $(replySelector + "." + highlight, thread); - if (!delta) { - if (postEl) { - $.rmClass(postEl, highlight); - } - return; - } - if (postEl) { - height = postEl.getBoundingClientRect().height; - if (Header.getTopOf(postEl) >= -height && Header.getBottomOf(postEl) >= -height) { - root = Get.postFromNode(postEl).nodes.root; - axis = delta === +1 ? 'following' : 'preceding'; - if (!(next = $.x(axis + "-sibling::" + g.SITE.xpath.replyContainer + "[not(@hidden) and not(child::div[@class='stub'])][1]", root))) { - return; - } - if (!next.matches(replySelector)) { - next = $(replySelector, next); - } - Header.scrollToIfNeeded(next, delta === +1); - $.addClass(next, highlight); - $.rmClass(postEl, highlight); - return; - } - $.rmClass(postEl, highlight); - } - replies = $$(replySelector, thread); - if (delta === -1) { - replies.reverse(); - } - for (i = 0, len = replies.length; i < len; i++) { - reply = replies[i]; - if (delta === +1 && Header.getTopOf(reply) > 0 || delta === -1 && Header.getBottomOf(reply) > 0) { - $.addClass(reply, highlight); - return; - } - } - } - }; - - return Keybinds; - -}).call(this); - -ModContact = (function() { - var ModContact; - - ModContact = { - init: function() { - var ref; - if (!(g.SITE.software === 'yotsuba' && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - return Callbacks.Post.push({ - name: 'Mod Contact Links', - cb: this.node - }); - }, - node: function() { - var links, moveNote, moved; - if (this.isClone || !$.hasOwn(ModContact.specific, this.info.capcode)) { - return; - } - links = $.el('span', { - className: 'contact-links brackets-wrap' - }); - $.extend(links, ModContact.template(this.info.capcode)); - $.after(this.nodes.capcode, links); - if ((moved = this.info.comment.match(/This thread was moved to >>>\/(\w+)\//)) && $.hasOwn(ModContact.moveNote, moved[1])) { - moveNote = $.el('div', { - className: 'move-note' - }); - $.extend(moveNote, ModContact.moveNote[moved[1]]); - return $.add(this.nodes.post, moveNote); - } - }, - template: function(capcode) { - return {innerHTML: "feedback" + (ModContact.specific[capcode]()).innerHTML}; - }, - specific: { - Mod: function() { - return {innerHTML: " IRC"}; - }, - Manager: function() { - return ModContact.specific.Mod(); - }, - Developer: function() { - return {innerHTML: " github"}; - }, - Admin: function() { - return {innerHTML: " twitter"}; - } - }, - moveNote: { - qa: {innerHTML: "Moving a thread to /qa/ does not imply mods will read it. If you wish to contact mods, use feedback (https://www.4chan.org/feedback) or IRC (https://www.4chan-x.net/4chan-irc.html)."} - } - }; - - return ModContact; - -}).call(this); - -Nav = (function() { - var Nav; - - Nav = { - init: function() { - var append, next, prev, span; - switch (g.VIEW) { - case 'index': - if (!Conf['Index Navigation']) { - return; - } - break; - case 'thread': - if (!Conf['Reply Navigation']) { - return; - } - break; - default: - return; - } - span = $.el('span', { - id: 'navlinks' - }); - prev = $.el('a', { - textContent: '▲', - href: 'javascript:;' - }); - next = $.el('a', { - textContent: '▼', - href: 'javascript:;' - }); - $.on(prev, 'click', this.prev); - $.on(next, 'click', this.next); - $.add(span, [prev, $.tn(' '), next]); - append = function() { - $.off(d, '4chanXInitFinished', append); - return $.add(d.body, span); - }; - return $.on(d, '4chanXInitFinished', append); - }, - prev: function() { - if (g.VIEW === 'thread') { - return window.scrollTo(0, 0); - } else { - return Nav.scroll(-1); - } - }, - next: function() { - if (g.VIEW === 'thread') { - return window.scrollTo(0, d.body.scrollHeight); - } else { - return Nav.scroll(+1); - } - }, - getThread: function() { - var i, len, ref, thread, threadRoot; - if (g.VIEW === 'thread') { - return g.threads.get(g.BOARD + "." + g.THREADID).nodes.root; - } - if ($.hasClass(doc, 'catalog-mode')) { - return; - } - ref = $$(g.SITE.selectors.thread); - for (i = 0, len = ref.length; i < len; i++) { - threadRoot = ref[i]; - thread = Get.threadFromRoot(threadRoot); - if (thread.isHidden && !thread.stub) { - continue; - } - if (Header.getTopOf(threadRoot) >= -threadRoot.getBoundingClientRect().height) { - return threadRoot; - } - } - }, - scroll: function(delta) { - var axis, extra, next, ref, thread, top; - if ((ref = d.activeElement) != null) { - ref.blur(); - } - thread = Nav.getThread(); - if (!thread) { - return; - } - axis = delta === +1 ? 'following' : 'preceding'; - if (next = $.x(axis + "-sibling::" + g.SITE.xpath.thread + "[not(@hidden)][1]", thread)) { - top = Header.getTopOf(thread); - if (delta === +1 && top < 5 || delta === -1 && top > -5) { - thread = next; - } - } - extra = Header.getTopOf(thread) + doc.clientHeight - d.body.getBoundingClientRect().bottom; - if (extra > 0) { - d.body.style.marginBottom = extra + "px"; - } - Header.scrollTo(thread); - if (extra > 0 && !Nav.haveExtra) { - Nav.haveExtra = true; - return $.on(d, 'scroll', Nav.removeExtra); - } - }, - removeExtra: function() { - var extra; - extra = doc.clientHeight - d.body.getBoundingClientRect().bottom; - if (extra > 0) { - return d.body.style.marginBottom = extra + "px"; - } else { - d.body.style.marginBottom = ''; - delete Nav.haveExtra; - return $.off(d, 'scroll', Nav.removeExtra); - } - } - }; - - return Nav; - -}).call(this); - -NormalizeURL = (function() { - var NormalizeURL; - - NormalizeURL = { - init: function() { - var pathname; - if (!Conf['Normalize URL']) { - return; - } - pathname = location.pathname.split(/\/+/); - if (g.SITE.software === 'yotsuba') { - switch (g.VIEW) { - case 'thread': - pathname[2] = 'thread'; - pathname = pathname.slice(0, 4); - break; - case 'index': - pathname = pathname.slice(0, 3); - } - } - pathname = pathname.join('/'); - if (location.pathname !== pathname) { - return history.replaceState(history.state, '', location.protocol + "//" + location.host + pathname + location.hash); - } - } - }; - - return NormalizeURL; - -}).call(this); - -PSA = (function() { - var PSA, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - PSA = { - init: function() { - var announcement, el; - if (g.SITE.software === 'yotsuba' && g.BOARD.ID === 'qa') { - announcement = { - innerHTML: "Stay in touch with your /qa/ friends!" - }; - el = $.el('div', { - className: 'fcx-announcement' - }, announcement); - $.onExists(doc, '.boardBanner', function(banner) { - return $.after(banner, el); - }); - } - if ('samachan.org' in Conf['siteProperties'] && indexOf.call(Conf['PSAseen'], 'samachan') < 0) { - el = $.el('span', { - innerHTML: "Looking for a new home?
    Some former Samachan users are regrouping on SushiChan.

    (a message from 4chan X)" - }); - return Main.ready(function() { - new Notice('info', el); - Conf['PSAseen'].push('samachan'); - return $.set('PSAseen', Conf['PSAseen']); - }); - } - } - }; - - return PSA; - -}).call(this); - -PSAHiding = (function() { - var PSAHiding, - slice = [].slice; - - PSAHiding = { - init: function() { - if (!(Conf['Announcement Hiding'] && g.SITE.selectors.psa)) { - return; - } - $.addClass(doc, 'hide-announcement'); - $.onExists(doc, g.SITE.selectors.psa, this.setup); - return $.ready(function() { - if (!$(g.SITE.selectors.psa)) { - return $.rmClass(doc, 'hide-announcement'); - } - }); - }, - setup: function(psa) { - var btn, entry, hr, ref, ref1, ref2; - PSAHiding.psa = psa; - PSAHiding.text = (ref = psa.dataset.utc) != null ? ref : psa.innerHTML; - if (g.SITE.selectors.psaTop && (hr = (ref1 = $(g.SITE.selectors.psaTop)) != null ? ref1.previousElementSibling : void 0) && hr.nodeName === 'HR') { - PSAHiding.hr = hr; - } - PSAHiding.content = $.el('div'); - entry = { - el: $.el('a', { - textContent: 'Show announcement', - className: 'show-announcement', - href: 'javascript:;' - }), - order: 50, - open: function() { - return psa.hidden; - } - }; - Header.menu.addEntry(entry); - $.on(entry.el, 'click', PSAHiding.toggle); - PSAHiding.btn = btn = $.el('a', { - title: 'Mark announcement as read and hide.', - className: 'hide-announcement-button fa fa-minus-square', - href: 'javascript:;' - }); - $.on(btn, 'click', PSAHiding.toggle); - if (((ref2 = psa.firstChild) != null ? ref2.tagName : void 0) === 'HR') { - $.after(psa.firstChild, btn); - } else { - $.prepend(psa, btn); - } - PSAHiding.sync(Conf['hiddenPSAList']); - $.rmClass(doc, 'hide-announcement'); - return $.sync('hiddenPSAList', PSAHiding.sync); - }, - toggle: function() { - var hide, set; - hide = $.hasClass(this, 'hide-announcement-button'); - set = function(hiddenPSAList) { - if (hide) { - return hiddenPSAList[g.SITE.ID] = PSAHiding.text; - } else { - return delete hiddenPSAList[g.SITE.ID]; - } - }; - set(Conf['hiddenPSAList']); - PSAHiding.sync(Conf['hiddenPSAList']); - return $.get('hiddenPSAList', Conf['hiddenPSAList'], function(arg) { - var hiddenPSAList; - hiddenPSAList = arg.hiddenPSAList; - set(hiddenPSAList); - return $.set('hiddenPSAList', hiddenPSAList); - }); - }, - sync: function(hiddenPSAList) { - var content, psa, ref; - psa = PSAHiding.psa, content = PSAHiding.content; - psa.hidden = hiddenPSAList[g.SITE.ID] === PSAHiding.text; - if (psa.hidden) { - $.add(content, slice.call(psa.childNodes)); - } else { - $.add(psa, slice.call(content.childNodes)); - } - return (ref = PSAHiding.hr) != null ? ref.hidden = psa.hidden : void 0; - } - }; - - return PSAHiding; - -}).call(this); - -PassMessage = (function() { - var PassMessage; - - PassMessage = { - init: function() { - var close, msg; - if (Conf['passMessageClosed']) { - return; - } - msg = $.el('div', { - className: 'box-outer top-box' - }, {innerHTML: "

    Trouble buying a 4chan Pass? (a message from 4chan X) ×

    Check the 4chan X wiki for alternative solutions.
    "}); - msg.style.cssText = 'padding-bottom: 0;'; - close = $('a', msg); - $.on(close, 'click', function() { - $.rm(msg); - return $.set('passMessageClosed', true); - }); - return $.ready(function() { - var hd; - if ((hd = $.id('hd'))) { - return $.after(hd, msg); - } else { - return $.prepend(d.body, msg); - } - }); - } - }; - - return PassMessage; - -}).call(this); - -PostJumper = (function() { - var PostJumper; - - PostJumper = { - init: function() { - var ref; - if (!(Conf['Unique ID and Capcode Navigation'] && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - this.buttons = this.makeButtons(); - return Callbacks.Post.push({ - name: 'Post Jumper', - cb: this.node - }); - }, - node: function() { - var buttons, i, len, ref; - if (this.isClone) { - ref = $$('.postJumper', this.nodes.info); - for (i = 0, len = ref.length; i < len; i++) { - buttons = ref[i]; - PostJumper.addListeners(buttons); - } - return; - } - if (this.nodes.uniqueIDRoot) { - PostJumper.addButtons(this, 'uniqueID'); - } - if (this.nodes.capcode) { - return PostJumper.addButtons(this, 'capcode'); - } - }, - addButtons: function(post, type) { - var buttons, value; - value = post.info[type]; - buttons = PostJumper.buttons.cloneNode(true); - $.extend(buttons.dataset, { - type: type, - value: value - }); - $.after(post.nodes[type + (type === 'capcode' ? '' : 'Root')], buttons); - return PostJumper.addListeners(buttons); - }, - addListeners: function(buttons) { - $.on(buttons.firstChild, 'click', PostJumper.buttonClick); - return $.on(buttons.lastChild, 'click', PostJumper.buttonClick); - }, - buttonClick: function() { - var dir, toJumper; - dir = $.hasClass(this, 'prev') ? -1 : 1; - if ((toJumper = PostJumper.find(this.parentNode, dir))) { - return PostJumper.scroll(this.parentNode, toJumper); - } - }, - find: function(jumper, dir) { - var axis, jumper2, ref, type, value, xpath; - ref = jumper.dataset, type = ref.type, value = ref.value; - xpath = "span[contains(@class,\"postJumper\") and @data-value=\"" + value + "\" and @data-type=\"" + type + "\"]"; - axis = dir < 0 ? 'preceding' : 'following'; - jumper2 = jumper; - while ((jumper2 = $.x(axis + "::" + xpath, jumper2))) { - if (jumper2.getBoundingClientRect().height) { - return jumper2; - } - } - if ((jumper2 = $.x("(//" + xpath + ")[" + (dir < 0 ? 'last()' : '1') + "]"))) { - if (jumper2.getBoundingClientRect().height) { - return jumper2; - } - } - while ((jumper2 = $.x(axis + "::" + xpath, jumper2)) && jumper2 !== jumper) { - if (jumper2.getBoundingClientRect().height) { - return jumper2; - } - } - return null; - }, - makeButtons: function() { - var charNext, charPrev, classNext, classPrev, span; - charPrev = '\u23EB'; - charNext = '\u23EC'; - classPrev = 'prev'; - classNext = 'next'; - span = $.el('span', { - className: 'postJumper' - }); - $.extend(span, {innerHTML: "" + E(charPrev) + "" + E(charNext) + ""}); - return span; - }, - scroll: function(fromJumper, toJumper) { - var destPos, prevPos; - prevPos = fromJumper.getBoundingClientRect().top; - destPos = toJumper.getBoundingClientRect().top; - return window.scrollBy(0, destPos - prevPos); - } - }; - - return PostJumper; - -}).call(this); - -RelativeDates = (function() { - var RelativeDates, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - RelativeDates = { - INTERVAL: $.MINUTE / 2, - init: function() { - var ref; - if (((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Relative Post Dates'] && !Conf['Relative Date Title'] || Index.enabled) { - this.flush(); - $.on(d, 'visibilitychange PostsInserted', this.flush); - } - if (Conf['Relative Post Dates']) { - return Callbacks.Post.push({ - name: 'Relative Post Dates', - cb: this.node - }); - } - }, - node: function() { - var dateEl; - if (!this.info.date) { - return; - } - dateEl = this.nodes.date; - if (Conf['Relative Date Title']) { - $.on(dateEl, 'mouseover', (function(_this) { - return function() { - return RelativeDates.hover(_this); - }; - })(this)); - return; - } - if (this.isClone) { - return; - } - dateEl.title = dateEl.textContent; - return RelativeDates.update(this); - }, - relative: function(diff, now, date, abbrev) { - var days, months, number, rounded, unit, years; - unit = (number = diff / $.DAY) >= 1 ? (years = now.getFullYear() - date.getFullYear(), months = now.getMonth() - date.getMonth(), days = now.getDate() - date.getDate(), years > 1 ? (number = years - (months < 0 || months === 0 && days < 0), 'year') : years === 1 && (months > 0 || months === 0 && days >= 0) ? (number = years, 'year') : (months = months + 12 * years) > 1 ? (number = months - (days < 0), 'month') : months === 1 && days >= 0 ? (number = months, 'month') : 'day') : (number = diff / $.HOUR) >= 1 ? 'hour' : (number = diff / $.MINUTE) >= 1 ? 'minute' : (number = Math.max(0, diff) / $.SECOND, 'second'); - rounded = Math.round(number); - if (abbrev) { - unit = unit === 'month' ? 'mo' : unit[0]; - } else { - if (rounded !== 1) { - unit += 's'; - } - } - if (abbrev) { - return "" + rounded + unit; - } else { - return rounded + " " + unit + " ago"; - } - }, - stale: [], - flush: function() { - var data, i, len, now, ref; - if (d.hidden) { - return; - } - now = new Date(); - ref = RelativeDates.stale; - for (i = 0, len = ref.length; i < len; i++) { - data = ref[i]; - RelativeDates.update(data, now); - } - RelativeDates.stale = []; - clearTimeout(RelativeDates.timeout); - return RelativeDates.timeout = setTimeout(RelativeDates.flush, RelativeDates.INTERVAL); - }, - hover: function(post) { - var date, diff, now; - date = post.info.date; - now = new Date(); - diff = now - date; - return post.nodes.date.title = RelativeDates.relative(diff, now, date); - }, - update: function(data, now) { - var abbrev, date, diff, i, isPost, len, ref, relative, singlePost; - isPost = data instanceof Post; - if (isPost) { - date = data.info.date; - abbrev = false; - } else { - date = new Date(+data.dataset.utc); - abbrev = !!data.dataset.abbrev; - } - now || (now = new Date()); - diff = now - date; - relative = RelativeDates.relative(diff, now, date, abbrev); - if (isPost) { - ref = [data].concat(data.clones); - for (i = 0, len = ref.length; i < len; i++) { - singlePost = ref[i]; - singlePost.nodes.date.firstChild.textContent = relative; - } - } else { - data.firstChild.textContent = relative; - } - return RelativeDates.setOwnTimeout(diff, data); - }, - setOwnTimeout: function(diff, data) { - var delay; - delay = diff < $.MINUTE ? $.SECOND - (diff + $.SECOND / 2) % $.SECOND : diff < $.HOUR ? $.MINUTE - (diff + $.MINUTE / 2) % $.MINUTE : diff < $.DAY ? $.HOUR - (diff + $.HOUR / 2) % $.HOUR : $.DAY - (diff + $.DAY / 2) % $.DAY; - return setTimeout(RelativeDates.markStale, delay, data); - }, - markStale: function(data) { - if (indexOf.call(RelativeDates.stale, data) >= 0) { - return; - } - if (data instanceof Post && !g.posts.get(data.fullID)) { - return; - } - if (data instanceof Element && !doc.contains(data)) { - return; - } - return RelativeDates.stale.push(data); - } - }; - - return RelativeDates; - -}).call(this); - -RemoveSpoilers = (function() { - var RemoveSpoilers, - slice = [].slice; - - RemoveSpoilers = { - init: function() { - if (Conf['Reveal Spoilers']) { - $.addClass(doc, 'reveal-spoilers'); - } - if (!Conf['Remove Spoilers']) { - return; - } - Callbacks.Post.push({ - name: 'Reveal Spoilers', - cb: this.node - }); - if (g.VIEW === 'archive') { - return $.ready(function() { - return RemoveSpoilers.unspoiler($.id('arc-list')); - }); - } - }, - node: function() { - return RemoveSpoilers.unspoiler(this.nodes.comment); - }, - unspoiler: function(el) { - var i, len, span, spoiler, spoilers; - spoilers = $$(g.SITE.selectors.spoiler, el); - for (i = 0, len = spoilers.length; i < len; i++) { - spoiler = spoilers[i]; - span = $.el('span', { - className: 'removed-spoiler' - }); - $.replace(spoiler, span); - $.add(span, slice.call(spoiler.childNodes)); - } - } - }; - - return RemoveSpoilers; - -}).call(this); - -Report = (function() { - var Report; - - Report = { - init: function() { - var match; - if (!(match = location.search.match(/\bno=(\d+)/))) { - return; - } - Captcha.replace.init(); - this.postID = +match[1]; - return $.ready(this.ready); - }, - ready: function() { - $.addStyle(CSS.report); - if (Conf['Archive Report']) { - Report.archive(); - } - new MutationObserver(function() { - Report.fit('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); - return Report.fit('body'); - }).observe(d.body, { - childList: true, - attributes: true, - subtree: true - }); - return Report.fit('body'); - }, - fit: function(selector) { - var dy, el; - if (!((el = $(selector, doc)) && getComputedStyle(el).visibility !== 'hidden')) { - return; - } - dy = el.getBoundingClientRect().bottom - doc.clientHeight + 8; - if (dy > 0) { - return window.resizeBy(0, dy); - } - }, - archive: function() { - var enabled, fieldset, form, match, message, reason, submit, types, urls; - if (!(urls = Redirect.report(g.BOARD.ID)).length) { - return; - } - form = $('form'); - types = $.id('reportTypes'); - message = $('h3'); - fieldset = $.el('fieldset', { - id: 'archive-report', - hidden: true - }, {innerHTML: ""}); - enabled = $('#archive-report-enabled', fieldset); - reason = $('#archive-report-reason', fieldset); - submit = $('#archive-report-submit', fieldset); - $.on(enabled, 'change', function() { - return reason.disabled = !this.checked; - }); - if (form && types) { - fieldset.hidden = !$('[value="31"]', types).checked; - $.on(types, 'change', function(e) { - fieldset.hidden = e.target.value !== '31'; - return Report.fit('body'); - }); - $.after(types, fieldset); - Report.fit('body'); - $.one(form, 'submit', function(e) { - if (!fieldset.hidden && enabled.checked) { - e.preventDefault(); - return Report.archiveSubmit(urls, reason.value, (function(_this) { - return function(results) { - _this.action = '#archiveresults=' + encodeURIComponent(JSON.stringify(results)); - return _this.submit(); - }; - })(this)); - } - }); - } else if (message) { - fieldset.hidden = /Report submitted!/.test(message.textContent); - $.on(enabled, 'change', function() { - return submit.hidden = !this.checked; - }); - $.after(message, fieldset); - $.on(submit, 'click', function() { - return Report.archiveSubmit(urls, reason.value, Report.archiveResults); - }); - } - if ((match = location.hash.match(/^#archiveresults=(.*)$/))) { - try { - return Report.archiveResults(JSON.parse(decodeURIComponent(match[1]))); - } catch (error) {} - } - }, - archiveSubmit: function(urls, reason, cb) { - var fn, form, i, len, name, ref, results, url; - form = $.formData({ - board: g.BOARD.ID, - num: Report.postID, - reason: reason - }); - results = []; - fn = function(name, url) { - return $.ajax(url, { - onloadend: function() { - results.push([ - name, this.response || { - error: '' - } - ]); - if (results.length === urls.length) { - return cb(results); - } - }, - form: form - }); - }; - for (i = 0, len = urls.length; i < len; i++) { - ref = urls[i], name = ref[0], url = ref[1]; - fn(name, url); - } - }, - archiveResults: function(results) { - var fieldset, i, len, line, name, ref, response; - fieldset = $.id('archive-report'); - for (i = 0, len = results.length; i < len; i++) { - ref = results[i], name = ref[0], response = ref[1]; - line = $.el('h3', { - className: 'archive-report-response' - }); - if ('success' in response) { - $.addClass(line, 'archive-report-success'); - line.textContent = name + ": " + response.success; - } else { - $.addClass(line, 'archive-report-error'); - line.textContent = name + ": " + (response.error || 'Error reporting post.'); - } - if (fieldset) { - $.before(fieldset, line); - } else { - $.add(d.body, line); - } - } - } - }; - - return Report; - -}).call(this); - -ThreadLinks = (function() { - var ThreadLinks; - - ThreadLinks = { - init: function() { - if (!(g.VIEW === 'index' && Conf['Open Threads in New Tab'])) { - return; - } - Callbacks.Post.push({ - name: 'Thread Links', - cb: this.node - }); - return Callbacks.CatalogThread.push({ - name: 'Thread Links', - cb: this.catalogNode - }); - }, - node: function() { - if (this.isReply || this.isClone) { - return; - } - return ThreadLinks.process(this.nodes.reply); - }, - catalogNode: function() { - return ThreadLinks.process(this.nodes.thumb.parentNode); - }, - process: function(link) { - return link.target = '_blank'; - } - }; - - return ThreadLinks; - -}).call(this); - -Time = (function() { - var Time; - - Time = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Time Formatting'])) { - return; - } - return Callbacks.Post.push({ - name: 'Time Formatting', - cb: this.node - }); - }, - node: function() { - var textContent; - if (!this.info.date || this.isClone) { - return; - } - textContent = this.nodes.date.textContent; - return this.nodes.date.textContent = textContent.match(/^\s*/)[0] + Time.format(Conf['time'], this.info.date) + textContent.match(/\s*$/)[0]; - }, - format: function(formatString, date) { - return formatString.replace(/%(.)/g, function(s, c) { - if ($.hasOwn(Time.formatters, c)) { - return Time.formatters[c].call(date); - } else { - return s; - } - }); - }, - day: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - month: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], - localeFormat: function(date, options, defaultValue) { - if (Conf['timeLocale']) { - try { - return Intl.DateTimeFormat(Conf['timeLocale'], options).format(date); - } catch (error) {} - } - return defaultValue; - }, - localeFormatPart: function(date, options, part, defaultValue) { - var parts; - if (Conf['timeLocale']) { - try { - parts = Intl.DateTimeFormat(Conf['timeLocale'], options).formatToParts(date); - return parts.map(function(x) { - if (x.type === part) { - return x.value; - } else { - return ''; - } - }).join(''); - } catch (error) {} - } - return defaultValue; - }, - zeroPad: function(n) { - if (n < 10) { - return "0" + n; - } else { - return n; - } - }, - formatters: { - a: function() { - return Time.localeFormat(this, { - weekday: 'short' - }, Time.day[this.getDay()].slice(0, 3)); - }, - A: function() { - return Time.localeFormat(this, { - weekday: 'long' - }, Time.day[this.getDay()]); - }, - b: function() { - return Time.localeFormat(this, { - month: 'short' - }, Time.month[this.getMonth()].slice(0, 3)); - }, - B: function() { - return Time.localeFormat(this, { - month: 'long' - }, Time.month[this.getMonth()]); - }, - d: function() { - return Time.zeroPad(this.getDate()); - }, - e: function() { - return this.getDate(); - }, - H: function() { - return Time.zeroPad(this.getHours()); - }, - I: function() { - return Time.zeroPad(this.getHours() % 12 || 12); - }, - k: function() { - return this.getHours(); - }, - l: function() { - return this.getHours() % 12 || 12; - }, - m: function() { - return Time.zeroPad(this.getMonth() + 1); - }, - M: function() { - return Time.zeroPad(this.getMinutes()); - }, - p: function() { - return Time.localeFormatPart(this, { - hour: 'numeric', - hour12: true - }, 'dayperiod', (this.getHours() < 12 ? 'AM' : 'PM')); - }, - P: function() { - return Time.formatters.p.call(this).toLowerCase(); - }, - S: function() { - return Time.zeroPad(this.getSeconds()); - }, - y: function() { - return this.getFullYear().toString().slice(2); - }, - Y: function() { - return this.getFullYear(); - }, - '%': function() { - return '%'; - } - } - }; - - return Time; - -}).call(this); - -Tinyboard = (function() { - var Tinyboard; - - Tinyboard = { - init: function() { - if (g.SITE.software !== 'tinyboard') { - return; - } - if (g.VIEW === 'thread') { - return Main.ready(function() { - return $.global(function() { - var base, boardID, form, originalNoko, ref, ref1, ref2, threadID; - ref = document.currentScript.dataset, boardID = ref.boardID, threadID = ref.threadID; - threadID = +threadID; - form = document.querySelector('form[name="post"]'); - window.$(document).ajaxComplete(function(event, request, settings) { - var detail, noko, postID, redirect, ref1, ref2; - if (settings.url !== form.action) { - return; - } - if (!(postID = +((ref1 = request.responseJSON) != null ? ref1.id : void 0))) { - return; - } - detail = { - boardID: boardID, - threadID: threadID, - postID: postID - }; - try { - ref2 = request.responseJSON, redirect = ref2.redirect, noko = ref2.noko; - if (redirect && (typeof originalNoko !== "undefined" && originalNoko !== null) && !originalNoko && !noko) { - detail.redirect = redirect; - } - } catch (error) {} - event = new CustomEvent('QRPostSuccessful', { - bubbles: true, - detail: detail - }); - return document.dispatchEvent(event); - }); - originalNoko = (ref1 = window.tb_settings) != null ? (ref2 = ref1.ajax) != null ? ref2.always_noko_replies : void 0 : void 0; - return ((base = (window.tb_settings || (window.tb_settings = {}))).ajax || (base.ajax = {})).always_noko_replies = true; - }, { - boardID: g.BOARD.ID, - threadID: g.THREADID - }); - }); - } - } - }; - - return Tinyboard; - -}).call(this); - -Favicon = (function() { - var Favicon; - - Favicon = { - init: function() { - return $.asap((function() { - return d.head && (Favicon.el = $('link[rel="shortcut icon"]', d.head)); - }), Favicon.initAsap); - }, - set: function(status) { - Favicon.status = status; - if (Favicon.el) { - Favicon.el.href = Favicon[status]; - return $.add(d.head, Favicon.el); - } - }, - initAsap: function() { - var href; - Favicon.el.type = 'image/x-icon'; - href = Favicon.el.href; - Favicon.isSFW = /ws\.ico$/.test(href); - Favicon["default"] = href; - Favicon["switch"](); - if (Favicon.status) { - return Favicon.set(Favicon.status); - } - }, - "switch": function() { - var f, i, items, t; - items = { - 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: ['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'], - '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='] - }; - items = $.getOwn(items, Conf['favicon']); - f = Favicon; - t = 'data:image/png;base64,'; - i = 0; - while (items[i]) { - items[i] = t + items[i++]; - } - f.unreadDead = items[0], f.unreadDeadY = items[1], f.unreadSFW = items[2], f.unreadSFWY = items[3], f.unreadNSFW = items[4], f.unreadNSFWY = items[5]; - return f.update(); - }, - update: function() { - if (this.isSFW) { - this.unread = this.unreadSFW; - return this.unreadY = this.unreadSFWY; - } else { - this.unread = this.unreadNSFW; - return 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,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAgMAAAC+UIlYAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAGlJREFUWMPtlkEKADEIA/tJP9lXLttQto2yHxgDHozTi0ToGK2WKZZ+HAQQMZc+xBwI4EZ+wAC2IfPuSIDOZJrSZQEAX9eVJhhwIuUYAnQe8rhAEMAZlTI2MID9f5Clyh0JeE1V1ZEAvB4qDfwuJTSGRAAAAABJRU5ErkJggg==' - }; - - return Favicon; - -}).call(this); - -MarkNewIPs = (function() { - var MarkNewIPs; - - MarkNewIPs = { - init: function() { - if (!(g.SITE.software === 'yotsuba' && g.VIEW === 'thread' && Conf['Mark New IPs'])) { - return; - } - return Callbacks.Thread.push({ - name: 'Mark New IPs', - cb: this.node - }); - }, - node: function() { - MarkNewIPs.ipCount = this.ipCount; - MarkNewIPs.postCount = this.posts.keys.length; - return $.on(d, 'ThreadUpdate', MarkNewIPs.onUpdate); - }, - onUpdate: function(e) { - var deletedPosts, fullID, i, ipCount, j, k, len, len1, newPosts, postCount, ref; - ref = e.detail, ipCount = ref.ipCount, postCount = ref.postCount, newPosts = ref.newPosts, deletedPosts = ref.deletedPosts; - if (ipCount == null) { - return; - } - switch (ipCount - MarkNewIPs.ipCount) { - case postCount - MarkNewIPs.postCount + deletedPosts.length: - i = MarkNewIPs.ipCount; - for (j = 0, len = newPosts.length; j < len; j++) { - fullID = newPosts[j]; - MarkNewIPs.markNew(g.posts.get(fullID), ++i); - } - break; - case -deletedPosts.length: - for (k = 0, len1 = newPosts.length; k < len1; k++) { - fullID = newPosts[k]; - MarkNewIPs.markOld(g.posts.get(fullID)); - } - } - MarkNewIPs.ipCount = ipCount; - return MarkNewIPs.postCount = postCount; - }, - markNew: function(post, ipCount) { - var counter, suffix; - suffix = (Math.floor(ipCount / 10)) % 10 === 1 ? 'th' : ['st', 'nd', 'rd'][ipCount % 10 - 1] || 'th'; - counter = $.el('span', { - className: 'ip-counter', - textContent: "(" + ipCount + ")" - }); - post.nodes.nameBlock.title = "This is the " + ipCount + suffix + " IP in the thread."; - $.add(post.nodes.nameBlock, [$.tn(' '), counter]); - return $.addClass(post.nodes.root, 'new-ip'); - }, - markOld: function(post) { - post.nodes.nameBlock.title = 'Not the first post from this IP.'; - return $.addClass(post.nodes.root, 'old-ip'); - } - }; - - return MarkNewIPs; - -}).call(this); - -ReplyPruning = (function() { - var ReplyPruning; - - ReplyPruning = { - init: function() { - var el, label; - if (!(g.VIEW === 'thread' && Conf['Reply Pruning'])) { - return; - } - this.container = $.frag(); - this.summary = $.el('span', { - hidden: true, - className: 'summary' - }); - this.summary.style.cursor = 'pointer'; - $.on(this.summary, 'click', (function(_this) { - return function() { - _this.inputs.enabled.checked = !_this.inputs.enabled.checked; - return $.event('change', null, _this.inputs.enabled); - }; - })(this)); - label = UI.checkbox('Prune Replies', 'Show Last', Conf['Prune All Threads']); - el = $.el('span', { - title: 'Maximum number of replies to show.' - }, {innerHTML: " "}); - $.prepend(el, label); - this.inputs = { - enabled: label.firstElementChild, - replies: el.lastElementChild - }; - this.setEnabled.call(this.inputs.enabled); - $.on(this.inputs.enabled, 'change', this.setEnabled); - $.on(this.inputs.replies, 'change', $.cb.value); - Header.menu.addEntry({ - el: el, - order: 190 - }); - return Callbacks.Thread.push({ - name: 'Reply Pruning', - cb: this.node - }); - }, - position: 0, - hidden: 0, - hiddenFiles: 0, - total: 0, - totalFiles: 0, - setEnabled: function() { - var other; - other = QuoteThreading.input; - if (this.checked && (other != null ? other.checked : void 0)) { - other.checked = false; - $.event('change', null, other); - } - return ReplyPruning.active = this.checked; - }, - showIfHidden: function(id) { - if (ReplyPruning.container && $("#" + id, ReplyPruning.container)) { - ReplyPruning.inputs.enabled.checked = false; - return $.event('change', null, ReplyPruning.inputs.enabled); - } - }, - node: function() { - var ref; - ReplyPruning.thread = this; - if (this.isSticky) { - ReplyPruning.active = ReplyPruning.inputs.enabled.checked = true; - if (QuoteThreading.input) { - Conf['Thread Quotes'] = QuoteThreading.input.checked = false; - } - } - this.posts.forEach(function(post) { - if (post.isReply) { - ReplyPruning.total++; - if (post.file) { - return ReplyPruning.totalFiles++; - } - } - }); - if (ReplyPruning.active && /^#p\d+$/.test(location.hash) && (1 <= (ref = this.posts.keys.indexOf(location.hash.slice(2))) && ref < 1 + Math.max(ReplyPruning.total - +Conf["Max Replies"], 0))) { - ReplyPruning.active = ReplyPruning.inputs.enabled.checked = false; - } - $.after(this.OP.nodes.root, ReplyPruning.summary); - $.on(ReplyPruning.inputs.enabled, 'change', ReplyPruning.update); - $.on(ReplyPruning.inputs.replies, 'change', ReplyPruning.update); - $.on(d, 'ThreadUpdate', ReplyPruning.updateCount); - $.on(d, 'ThreadUpdate', ReplyPruning.update); - return ReplyPruning.update(); - }, - updateCount: function(e) { - var fullID, i, len, ref; - if (e.detail[404]) { - return; - } - ref = e.detail.newPosts; - for (i = 0, len = ref.length; i < len; i++) { - fullID = ref[i]; - ReplyPruning.total++; - if (g.posts.get(fullID).file) { - ReplyPruning.totalFiles++; - } - } - }, - update: function() { - var boardTop, frag, hidden1, hidden2, node, oldPos, post, posts; - hidden1 = ReplyPruning.hidden; - hidden2 = ReplyPruning.active ? Math.max(ReplyPruning.total - +Conf["Max Replies"], 0) : 0; - oldPos = d.body.clientHeight - window.scrollY; - posts = ReplyPruning.thread.posts; - if (ReplyPruning.hidden < hidden2) { - while (ReplyPruning.hidden < hidden2 && ReplyPruning.position < posts.keys.length) { - post = posts.get(posts.keys[ReplyPruning.position++]); - if (post.isReply && !post.isFetchedQuote) { - while ((node = ReplyPruning.summary.nextSibling) && node !== post.nodes.root) { - $.add(ReplyPruning.container, node); - } - $.add(ReplyPruning.container, post.nodes.root); - ReplyPruning.hidden++; - if (post.file) { - ReplyPruning.hiddenFiles++; - } - } - } - } else if (ReplyPruning.hidden > hidden2) { - frag = $.frag(); - while (ReplyPruning.hidden > hidden2 && ReplyPruning.position > 0) { - post = posts.get(posts.keys[--ReplyPruning.position]); - if (post.isReply && !post.isFetchedQuote) { - while ((node = ReplyPruning.container.lastChild) && node !== post.nodes.root) { - $.prepend(frag, node); - } - $.prepend(frag, post.nodes.root); - ReplyPruning.hidden--; - if (post.file) { - ReplyPruning.hiddenFiles--; - } - } - } - $.after(ReplyPruning.summary, frag); - $.event('PostsInserted', null, ReplyPruning.summary.parentNode); - } - ReplyPruning.summary.textContent = ReplyPruning.active ? g.SITE.Build.summaryText('+', ReplyPruning.hidden, ReplyPruning.hiddenFiles) : g.SITE.Build.summaryText('-', ReplyPruning.total, ReplyPruning.totalFiles); - ReplyPruning.summary.hidden = ReplyPruning.total <= +Conf["Max Replies"]; - if (hidden1 !== hidden2 && (boardTop = Header.getTopOf($('.board'))) < 0) { - return window.scrollBy(0, Math.max(d.body.clientHeight - oldPos, window.scrollY + boardTop) - window.scrollY); - } - } - }; - - return ReplyPruning; - -}).call(this); - -ThreadStats = (function() { - var ThreadStats; - - ThreadStats = { - postCount: 0, - fileCount: 0, - postIndex: 0, - init: function() { - var base, sc, statsHTML, statsTitle; - if (g.VIEW !== 'thread' || !Conf['Thread Stats']) { - return; - } - if (Conf['Page Count in Stats']) { - this[(typeof (base = g.SITE).isPrunedByAge === "function" ? base.isPrunedByAge(g.BOARD) : void 0) ? 'showPurgePos' : 'showPage'] = true; - } - statsHTML = {innerHTML: "? / ?" + ((Conf["IP Count in Stats"] && g.SITE.hasIPCount) ? " / ?" : "") + ((Conf["Page Count in Stats"]) ? " / ?" : "")}; - statsTitle = 'Posts / Files'; - if (Conf['IP Count in Stats'] && g.SITE.hasIPCount) { - statsTitle += ' / IPs'; - } - if (Conf['Page Count in Stats']) { - statsTitle += (this.showPurgePos ? ' / Purge Position' : ' / Page'); - } - if (Conf['Updater and Stats in Header']) { - this.dialog = sc = $.el('span', { - id: 'thread-stats', - title: statsTitle - }); - $.extend(sc, statsHTML); - Header.addShortcut('stats', sc, 200); - } else { - this.dialog = sc = UI.dialog('thread-stats', {innerHTML: "
    " + (statsHTML).innerHTML + "
    "}); - $.addClass(doc, 'float'); - $.ready(function() { - return $.add(d.body, sc); - }); - } - this.postCountEl = $('#post-count', sc); - this.fileCountEl = $('#file-count', sc); - this.ipCountEl = $('#ip-count', sc); - this.pageCountEl = $('#page-count', sc); - if (this.pageCountEl) { - $.on(this.pageCountEl, 'click', ThreadStats.fetchPage); - } - return Callbacks.Thread.push({ - name: 'Thread Stats', - cb: this.node - }); - }, - node: function() { - ThreadStats.thread = this; - ThreadStats.count(); - ThreadStats.update(); - ThreadStats.fetchPage(); - $.on(d, 'PostsInserted', function() { - return $.queueTask(ThreadStats.onPostsInserted); - }); - return $.on(d, 'ThreadUpdate', ThreadStats.onUpdate); - }, - count: function() { - var i, j, n, post, posts, ref, ref1; - posts = ThreadStats.thread.posts; - n = posts.keys.length; - for (i = j = ref = ThreadStats.postIndex, ref1 = n; j < ref1; i = j += 1) { - post = posts.get(posts.keys[i]); - if (!post.isFetchedQuote) { - ThreadStats.postCount++; - ThreadStats.fileCount += post.files.length; - } - } - return ThreadStats.postIndex = n; - }, - onUpdate: function(e) { - var fileCount, postCount, ref; - if (e.detail[404]) { - return; - } - ref = e.detail, postCount = ref.postCount, fileCount = ref.fileCount; - $.extend(ThreadStats, { - postCount: postCount, - fileCount: fileCount - }); - ThreadStats.postIndex = ThreadStats.thread.posts.keys.length; - ThreadStats.update(); - if (ThreadStats.showPage && ThreadStats.pageCountEl.textContent !== '1') { - return ThreadStats.fetchPage(); - } - }, - onPostsInserted: function() { - if (!(ThreadStats.thread.posts.keys.length > ThreadStats.postIndex)) { - return; - } - ThreadStats.count(); - ThreadStats.update(); - if (ThreadStats.showPage && ThreadStats.pageCountEl.textContent !== '1') { - return ThreadStats.fetchPage(); - } - }, - update: function() { - var fileCountEl, ipCountEl, postCountEl, ref, thread; - thread = ThreadStats.thread, postCountEl = ThreadStats.postCountEl, fileCountEl = ThreadStats.fileCountEl, ipCountEl = ThreadStats.ipCountEl; - postCountEl.textContent = ThreadStats.postCount; - fileCountEl.textContent = ThreadStats.fileCount; - if (ipCountEl != null) { - ipCountEl.textContent = (ref = thread.ipCount) != null ? ref : '?'; - } - postCountEl.classList.toggle('warning', thread.postLimit && !thread.isSticky); - return fileCountEl.classList.toggle('warning', thread.fileLimit && !thread.isSticky); - }, - fetchPage: function() { - if (!ThreadStats.pageCountEl) { - return; - } - clearTimeout(ThreadStats.timeout); - if (ThreadStats.thread.isDead) { - ThreadStats.pageCountEl.textContent = 'Dead'; - $.addClass(ThreadStats.pageCountEl, 'warning'); - return; - } - ThreadStats.timeout = setTimeout(ThreadStats.fetchPage, 2 * $.MINUTE); - return $.whenModified(g.SITE.urls.threadsListJSON(ThreadStats.thread), 'ThreadStats', ThreadStats.onThreadsLoad); - }, - onThreadsLoad: function() { - var i, j, k, l, len, len1, len2, len3, len4, m, nThreads, o, page, pageNum, purgePos, ref, ref1, ref2, ref3, ref4, thread; - if (this.status === 200) { - if (ThreadStats.showPurgePos) { - purgePos = 1; - ref = this.response; - for (j = 0, len = ref.length; j < len; j++) { - page = ref[j]; - ref1 = page.threads; - for (k = 0, len1 = ref1.length; k < len1; k++) { - thread = ref1[k]; - if (thread.no < ThreadStats.thread.ID) { - purgePos++; - } - } - } - ThreadStats.pageCountEl.textContent = purgePos; - return ThreadStats.pageCountEl.classList.toggle('warning', purgePos === 1); - } else { - i = nThreads = 0; - ref2 = this.response; - for (l = 0, len2 = ref2.length; l < len2; l++) { - page = ref2[l]; - nThreads += page.threads.length; - } - ref3 = this.response; - for (pageNum = m = 0, len3 = ref3.length; m < len3; pageNum = ++m) { - page = ref3[pageNum]; - ref4 = page.threads; - for (o = 0, len4 = ref4.length; o < len4; o++) { - thread = ref4[o]; - if (thread.no === ThreadStats.thread.ID) { - ThreadStats.pageCountEl.textContent = pageNum + 1; - ThreadStats.pageCountEl.classList.toggle('warning', i >= nThreads - this.response[0].threads.length); - ThreadStats.lastPageUpdate = new Date(thread.last_modified * $.SECOND); - ThreadStats.retry(); - return; - } - i++; - } - } - } - } else if (this.status === 304) { - return ThreadStats.retry(); - } - }, - retry: function() { - if (!(ThreadStats.showPage && ThreadStats.pageCountEl.textContent !== '1' && !g.SITE.threadModTimeIgnoresSage && ThreadStats.thread.posts.get(ThreadStats.thread.lastPost).info.date > ThreadStats.lastPageUpdate)) { - return; - } - clearTimeout(ThreadStats.timeout); - return ThreadStats.timeout = setTimeout(ThreadStats.fetchPage, 5 * $.SECOND); - } - }; - - return ThreadStats; - -}).call(this); - -ThreadUpdater = (function() { - var ThreadUpdater, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - ThreadUpdater = { - init: function() { - var conf, el, input, name, ref, sc, subEntries, updateLink; - if (g.VIEW !== 'thread' || !Conf['Thread Updater']) { - return; - } - this.enabled = true; - this.audio = $.el('audio'); - if ($.engine !== 'gecko') { - this.audio.src = this.beep; - } - if (Conf['Updater and Stats in Header']) { - this.dialog = sc = $.el('span', { - id: 'updater' - }); - $.extend(sc, {innerHTML: ""}); - Header.addShortcut('updater', sc, 100); - } else { - this.dialog = sc = UI.dialog('updater', {innerHTML: "
    "}); - $.addClass(doc, 'float'); - $.ready(function() { - return $.add(d.body, sc); - }); - } - this.checkPostCount = 0; - this.timer = $('#update-timer', sc); - this.status = $('#update-status', sc); - $.on(this.timer, 'click', this.update); - $.on(this.status, 'click', this.update); - updateLink = $.el('span', { - className: 'brackets-wrap updatelink' - }); - $.extend(updateLink, {innerHTML: "Update"}); - Main.ready(function() { - var navLinksBot; - if ((navLinksBot = $('.navLinksBot'))) { - return $.add(navLinksBot, [$.tn(' '), updateLink]); - } - }); - $.on(updateLink.firstElementChild, 'click', this.update); - subEntries = []; - ref = Config.updater.checkbox; - for (name in ref) { - conf = ref[name]; - el = UI.checkbox(name, name); - el.title = conf[1]; - input = el.firstElementChild; - $.on(input, 'change', $.cb.checked); - if (input.name === 'Scroll BG') { - $.on(input, 'change', this.cb.scrollBG); - this.cb.scrollBG(); - } else if (input.name === 'Auto Update') { - $.on(input, 'change', this.setInterval); - } - subEntries.push({ - el: el - }); - } - this.settings = $.el('span', {innerHTML: "Interval"}); - $.on(this.settings, 'click', this.intervalShortcut); - subEntries.push({ - el: this.settings - }); - Header.menu.addEntry(this.entry = { - el: $.el('span', { - textContent: 'Updater' - }), - order: 110, - subEntries: subEntries - }); - return Callbacks.Thread.push({ - name: 'Thread Updater', - cb: this.node - }); - }, - node: function() { - ThreadUpdater.thread = this; - ThreadUpdater.root = this.nodes.root; - ThreadUpdater.outdateCount = 0; - ThreadUpdater.postIDs = []; - ThreadUpdater.fileIDs = []; - this.posts.forEach(function(post) { - ThreadUpdater.postIDs.push(post.ID); - if (post.file) { - return ThreadUpdater.fileIDs.push(post.ID); - } - }); - ThreadUpdater.cb.interval.call($.el('input', { - value: Conf['Interval'] - })); - $.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost); - $.on(d, 'visibilitychange', ThreadUpdater.cb.visibility); - return ThreadUpdater.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: function() { - var audio; - audio = ThreadUpdater.audio; - audio.src || (audio.src = ThreadUpdater.beep); - if (audio.paused) { - return audio.play(); - } else { - return $.one(audio, 'ended', ThreadUpdater.playBeep); - } - }, - cb: { - checkpost: function(e) { - if (e.detail.threadID !== ThreadUpdater.thread.ID) { - return; - } - ThreadUpdater.postID = e.detail.postID; - ThreadUpdater.checkPostCount = 0; - ThreadUpdater.outdateCount = 0; - return ThreadUpdater.setInterval(); - }, - visibility: function() { - if (d.hidden) { - return; - } - ThreadUpdater.outdateCount = 0; - if (ThreadUpdater.seconds > ThreadUpdater.interval) { - return ThreadUpdater.setInterval(); - } - }, - scrollBG: function() { - return ThreadUpdater.scrollBG = Conf['Scroll BG'] ? function() { - return true; - } : function() { - return !d.hidden; - }; - }, - interval: function(e) { - var val; - val = parseInt(this.value, 10); - if (val < 1) { - val = 1; - } - ThreadUpdater.interval = this.value = val; - if (e) { - return $.cb.value.call(this); - } - }, - load: function() { - if (this !== ThreadUpdater.req) { - return; - } - switch (this.status) { - case 200: - ThreadUpdater.parse(this); - if (ThreadUpdater.thread.isArchived) { - return ThreadUpdater.kill(); - } else { - return ThreadUpdater.setInterval(); - } - break; - case 404: - return $.ajax(g.SITE.urls.catalogJSON({ - boardID: ThreadUpdater.thread.board.ID - }), { - onloadend: function() { - var confirmed, i, k, len, len1, page, ref, ref1, thread; - if (this.status === 200) { - confirmed = true; - ref = this.response; - for (i = 0, len = ref.length; i < len; i++) { - page = ref[i]; - ref1 = page.threads; - for (k = 0, len1 = ref1.length; k < len1; k++) { - thread = ref1[k]; - if (thread.no === ThreadUpdater.thread.ID) { - confirmed = false; - break; - } - } - } - } else { - confirmed = false; - } - if (confirmed) { - return ThreadUpdater.kill(); - } else { - return ThreadUpdater.error(this); - } - } - }); - default: - return ThreadUpdater.error(this); - } - } - }, - kill: function() { - ThreadUpdater.thread.kill(); - ThreadUpdater.setInterval(); - return $.event('ThreadUpdate', { - 404: true, - threadID: ThreadUpdater.thread.fullID - }); - }, - error: function(req) { - if (req.status === 304) { - ThreadUpdater.set('status', ''); - } - ThreadUpdater.setInterval(); - if (!req.status) { - return ThreadUpdater.set('status', 'Connection Error', 'warning'); - } else if (req.status !== 304) { - return ThreadUpdater.set('status', req.statusText + " (" + req.status + ")", 'warning'); - } - }, - setInterval: function() { - var cur, interval, j, limit; - clearTimeout(ThreadUpdater.timeoutID); - if (ThreadUpdater.thread.isDead) { - ThreadUpdater.set('status', (ThreadUpdater.thread.isArchived ? 'Archived' : '404'), 'warning'); - ThreadUpdater.set('timer', ''); - return; - } - if (ThreadUpdater.postID && ThreadUpdater.checkPostCount < 5) { - ThreadUpdater.set('timer', '...', 'loading'); - ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND); - return; - } - if (!Conf['Auto Update']) { - ThreadUpdater.set('timer', 'Update'); - return; - } - interval = ThreadUpdater.interval; - if (Conf['Optional Increase']) { - limit = d.hidden ? 10 : 5; - j = Math.min(ThreadUpdater.outdateCount, limit); - cur = (Math.floor(interval * 0.1) || 1) * j * j; - ThreadUpdater.seconds = $.minmax(cur, interval, 300); - } else { - ThreadUpdater.seconds = interval; - } - return ThreadUpdater.timeout(); - }, - intervalShortcut: function() { - var settings; - Settings.open('Advanced'); - settings = $.id('fourchanx-settings'); - return $('input[name=Interval]', settings).focus(); - }, - set: function(name, text, klass) { - var el, node; - el = ThreadUpdater[name]; - if (node = el.firstChild) { - node.data = text; - } else { - el.textContent = text; - } - return el.className = klass != null ? klass : (text === '' ? 'empty' : ''); - }, - timeout: function() { - if (ThreadUpdater.seconds) { - ThreadUpdater.set('timer', ThreadUpdater.seconds); - ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000); - } else { - ThreadUpdater.outdateCount++; - ThreadUpdater.update(); - } - return ThreadUpdater.seconds--; - }, - update: function() { - var oldReq; - clearTimeout(ThreadUpdater.timeoutID); - ThreadUpdater.set('timer', '...', 'loading'); - if ((oldReq = ThreadUpdater.req)) { - delete ThreadUpdater.req; - oldReq.abort(); - } - return ThreadUpdater.req = $.whenModified(g.SITE.urls.threadJSON({ - boardID: ThreadUpdater.thread.board.ID, - threadID: ThreadUpdater.thread.ID - }), 'ThreadUpdater', ThreadUpdater.cb.load, { - timeout: $.MINUTE - }); - }, - updateThreadStatus: function(type, status) { - var change, hasChanged; - if (!(hasChanged = ThreadUpdater.thread["is" + type] !== status)) { - return; - } - ThreadUpdater.thread.setStatus(type, status); - if (type === 'Closed' && ThreadUpdater.thread.isArchived) { - return; - } - change = type === 'Sticky' ? status ? 'now a sticky' : 'not a sticky anymore' : status ? 'now closed' : 'not closed anymore'; - return new Notice('info', "The thread is " + change + ".", 30); - }, - parse: function(req) { - var ID, OP, board, deletedFiles, deletedPosts, files, firstPost, i, index, ipCountEl, k, l, lastPost, len, len1, len2, len3, m, newPosts, node, post, postObject, postObjects, posts, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, scroll, thread, unreadCount, unreadQYCount; - postObjects = req.response.posts; - OP = postObjects[0]; - thread = ThreadUpdater.thread; - board = thread.board; - ref = ThreadUpdater.postIDs, lastPost = ref[ref.length - 1]; - if (postObjects[postObjects.length - 1].no < lastPost && new Date(req.getResponseHeader('Last-Modified')) - thread.posts.get(lastPost).info.date < 30 * $.SECOND) { - return; - } - g.SITE.Build.spoilerRange[board] = OP.custom_spoiler; - thread.setStatus('Archived', !!OP.archived); - ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky); - ThreadUpdater.updateThreadStatus('Closed', !!OP.closed); - thread.postLimit = !!OP.bumplimit; - thread.fileLimit = !!OP.imagelimit; - if (OP.unique_ips != null) { - thread.ipCount = OP.unique_ips; - } - posts = []; - index = []; - files = []; - newPosts = []; - for (i = 0, len = postObjects.length; i < len; i++) { - postObject = postObjects[i]; - ID = postObject.no; - index.push(ID); - if (postObject.fsize) { - files.push(ID); - } - if (ID <= lastPost) { - continue; - } - if ((post = thread.posts.get(ID)) && !post.isFetchedQuote) { - post.resurrect(); - continue; - } - newPosts.push(board + "." + ID); - node = g.SITE.Build.postFromObject(postObject, board.ID); - posts.push(new Post(node, thread, board)); - if (ThreadUpdater.postID === ID) { - delete ThreadUpdater.postID; - } - } - deletedPosts = []; - ref1 = ThreadUpdater.postIDs; - for (k = 0, len1 = ref1.length; k < len1; k++) { - ID = ref1[k]; - if (!(indexOf.call(index, ID) < 0)) { - continue; - } - thread.posts.get(ID).kill(); - deletedPosts.push(board + "." + ID); - } - ThreadUpdater.postIDs = index; - deletedFiles = []; - ref2 = ThreadUpdater.fileIDs; - for (l = 0, len2 = ref2.length; l < len2; l++) { - ID = ref2[l]; - if (!(!(indexOf.call(files, ID) >= 0 || (ref3 = board + "." + ID, indexOf.call(deletedPosts, ref3) >= 0)))) { - continue; - } - thread.posts.get(ID).kill(true); - deletedFiles.push(board + "." + ID); - } - ThreadUpdater.fileIDs = files; - if (!posts.length) { - ThreadUpdater.set('status', ''); - } else { - ThreadUpdater.set('status', "+" + posts.length, 'new'); - ThreadUpdater.outdateCount = 0; - unreadCount = (ref4 = Unread.posts) != null ? ref4.size : void 0; - unreadQYCount = (ref5 = Unread.postsQuotingYou) != null ? ref5.size : void 0; - Main.callbackNodes('Post', posts); - if (d.hidden || !d.hasFocus()) { - if (Conf['Beep Quoting You'] && ((ref6 = Unread.postsQuotingYou) != null ? ref6.size : void 0) > unreadQYCount) { - ThreadUpdater.playBeep(); - if (Conf['Beep']) { - ThreadUpdater.playBeep(); - } - } else if (Conf['Beep'] && ((ref7 = Unread.posts) != null ? ref7.size : void 0) > 0 && unreadCount === 0) { - ThreadUpdater.playBeep(); - } - } - scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight < 25; - firstPost = null; - for (m = 0, len3 = posts.length; m < len3; m++) { - post = posts[m]; - if (!QuoteThreading.insert(post)) { - firstPost || (firstPost = post.nodes.root); - $.add(ThreadUpdater.root, post.nodes.root); - } - } - $.event('PostsInserted', null, ThreadUpdater.root); - if (scroll) { - if (Conf['Bottom Scroll']) { - window.scrollTo(0, d.body.clientHeight); - } else { - if (firstPost) { - Header.scrollTo(firstPost); - } - } - } - } - if ((OP.unique_ips != null) && (ipCountEl = $.id('unique-ips'))) { - ipCountEl.textContent = OP.unique_ips; - ipCountEl.previousSibling.textContent = ipCountEl.previousSibling.textContent.replace(/\b(?:is|are)\b/, OP.unique_ips === 1 ? 'is' : 'are'); - ipCountEl.nextSibling.textContent = ipCountEl.nextSibling.textContent.replace(/\bposters?\b/, OP.unique_ips === 1 ? 'poster' : 'posters'); - } - return $.event('ThreadUpdate', { - 404: false, - threadID: thread.fullID, - newPosts: newPosts, - deletedPosts: deletedPosts, - deletedFiles: deletedFiles, - postCount: OP.replies + 1, - fileCount: OP.images + !!OP.fsize, - ipCount: OP.unique_ips - }); - } - }; - - return ThreadUpdater; - -}).call(this); - -ThreadWatcher = (function() { - var ThreadWatcher, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - ThreadWatcher = { - init: function() { - var ref, sc; - if (!(this.enabled = Conf['Thread Watcher'])) { - return; - } - this.shortcut = sc = $.el('a', { - id: 'watcher-link', - textContent: 'Watcher', - title: 'Thread Watcher', - href: 'javascript:;', - className: 'fa fa-eye' - }); - this.db = new DataBoard('watchedThreads', this.refresh, true); - this.dbLM = new DataBoard('watcherLastModified', null, true); - this.dialog = UI.dialog('thread-watcher', {innerHTML: "
    Thread Watcher ×
    "}); - this.status = $('#watcher-status', this.dialog); - this.list = this.dialog.lastElementChild; - this.refreshButton = $('.refresh', this.dialog); - this.closeButton = $('.move > .close', this.dialog); - this.unreaddb = Unread.db || UnreadIndex.db || new DataBoard('lastReadPosts'); - this.unreadEnabled = Conf['Remember Last Read Post']; - $.on(d, 'QRPostSuccessful', this.cb.post); - $.on(sc, 'click', this.toggleWatcher); - $.on(this.refreshButton, 'click', this.buttonFetchAll); - $.on(this.closeButton, 'click', this.toggleWatcher); - this.menu.addHeaderMenuEntry(); - $.onExists(doc, 'body', this.addDialog); - switch (g.VIEW) { - case 'index': - $.on(d, 'IndexUpdate', this.cb.onIndexUpdate); - break; - case 'thread': - $.on(d, 'ThreadUpdate', this.cb.onThreadRefresh); - } - if (Conf['Fixed Thread Watcher']) { - $.addClass(doc, 'fixed-watcher'); - } - if (!Conf['Persistent Thread Watcher']) { - $.addClass(ThreadWatcher.shortcut, 'disabled'); - this.dialog.hidden = true; - } - Header.addShortcut('watcher', sc, 510); - ThreadWatcher.initLastModified(); - ThreadWatcher.fetchAuto(); - $.on(window, 'visibilitychange focus', function() { - return $.queueTask(ThreadWatcher.fetchAuto); - }); - if (Conf['Menu'] && Index.enabled) { - Menu.menu.addEntry({ - el: $.el('a', { - href: 'javascript:;', - className: 'has-shortcut-text' - }, {innerHTML: "Alt+click"}), - order: 6, - open: function(arg) { - var thread; - thread = arg.thread; - if (Conf['Index Mode'] !== 'catalog') { - return false; - } - this.el.firstElementChild.textContent = ThreadWatcher.isWatched(thread) ? 'Unwatch' : 'Watch'; - if (this.cb) { - $.off(this.el, 'click', this.cb); - } - this.cb = function() { - $.event('CloseMenu'); - return ThreadWatcher.toggle(thread); - }; - $.on(this.el, 'click', this.cb); - return true; - } - }); - } - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - Callbacks.Post.push({ - name: 'Thread Watcher', - cb: this.node - }); - return Callbacks.CatalogThread.push({ - name: 'Thread Watcher', - cb: this.catalogNode - }); - }, - isWatched: function(thread) { - var ref; - return !!((ref = ThreadWatcher.db) != null ? ref.get({ - boardID: thread.board.ID, - threadID: thread.ID - }) : void 0); - }, - isWatchedRaw: function(boardID, threadID) { - var ref; - return !!((ref = ThreadWatcher.db) != null ? ref.get({ - boardID: boardID, - threadID: threadID - }) : void 0); - }, - setToggler: function(toggler, isWatched) { - toggler.classList.toggle('watched', isWatched); - return toggler.title = (isWatched ? 'Unwatch' : 'Watch') + " Thread"; - }, - node: function() { - var boardID, data, siteID, threadID, toggler; - if (this.isReply) { - return; - } - if (this.isClone) { - toggler = $('.watch-thread-link', this.nodes.info); - } else { - toggler = $.el('a', { - href: 'javascript:;', - className: 'watch-thread-link' - }); - $.before($('input', this.nodes.info), toggler); - } - siteID = g.SITE.ID; - boardID = this.board.ID; - threadID = this.thread.ID; - data = ThreadWatcher.db.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }); - ThreadWatcher.setToggler(toggler, !!data); - $.on(toggler, 'click', ThreadWatcher.cb.toggle); - if (data && (data.excerpt == null)) { - return $.queueTask((function(_this) { - return function() { - return ThreadWatcher.update(siteID, boardID, threadID, { - excerpt: Get.threadExcerpt(_this.thread) - }); - }; - })(this)); - } - }, - catalogNode: function() { - if (ThreadWatcher.isWatched(this.thread)) { - $.addClass(this.nodes.root, 'watched'); - } - return $.on(this.nodes.root, 'mousedown click', (function(_this) { - return function(e) { - if (!(e.button === 0 && e.altKey)) { - return; - } - if (e.type === 'click') { - ThreadWatcher.toggle(_this.thread); - } - return e.preventDefault(); - }; - })(this)); - }, - addDialog: function() { - if (!Main.isThisPageLegit()) { - return; - } - ThreadWatcher.build(); - return $.prepend(d.body, ThreadWatcher.dialog); - }, - toggleWatcher: function() { - $.toggleClass(ThreadWatcher.shortcut, 'disabled'); - return ThreadWatcher.dialog.hidden = !ThreadWatcher.dialog.hidden; - }, - cb: { - openAll: function() { - var a, j, len1, ref; - if ($.hasClass(this, 'disabled')) { - return; - } - ref = $$('a.watcher-link', ThreadWatcher.list); - for (j = 0, len1 = ref.length; j < len1; j++) { - a = ref[j]; - $.open(a.href); - } - return $.event('CloseMenu'); - }, - openUnread: function() { - var a, j, len1, ref; - if ($.hasClass(this, 'disabled')) { - return; - } - ref = $$('.replies-unread > a.watcher-link', ThreadWatcher.list); - for (j = 0, len1 = ref.length; j < len1; j++) { - a = ref[j]; - $.open(a.href); - } - return $.event('CloseMenu'); - }, - openDeads: function() { - var a, j, len1, ref; - if ($.hasClass(this, 'disabled')) { - return; - } - ref = $$('.dead-thread > a.watcher-link', ThreadWatcher.list); - for (j = 0, len1 = ref.length; j < len1; j++) { - a = ref[j]; - $.open(a.href); - } - return $.event('CloseMenu'); - }, - pruneDeads: function() { - var boardID, data, j, len1, ref, ref1, siteID, threadID; - if ($.hasClass(this, 'disabled')) { - return; - } - ref = ThreadWatcher.getAll(); - for (j = 0, len1 = ref.length; j < len1; j++) { - ref1 = ref[j], siteID = ref1.siteID, boardID = ref1.boardID, threadID = ref1.threadID, data = ref1.data; - if (data.isDead) { - ThreadWatcher.db["delete"]({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }); - } - } - ThreadWatcher.refresh(); - return $.event('CloseMenu'); - }, - dismiss: function() { - var boardID, data, j, len1, ref, ref1, siteID, threadID; - ref = ThreadWatcher.getAll(); - for (j = 0, len1 = ref.length; j < len1; j++) { - ref1 = ref[j], siteID = ref1.siteID, boardID = ref1.boardID, threadID = ref1.threadID, data = ref1.data; - if (data.quotingYou) { - ThreadWatcher.update(siteID, boardID, threadID, { - dismiss: data.quotingYou || 0 - }); - } - } - return $.event('CloseMenu'); - }, - toggle: function() { - var thread; - thread = Get.postFromNode(this).thread; - return ThreadWatcher.toggle(thread); - }, - rm: function() { - var boardID, ref, siteID, threadID; - siteID = this.parentNode.dataset.siteID; - ref = this.parentNode.dataset.fullID.split('.'), boardID = ref[0], threadID = ref[1]; - return ThreadWatcher.rm(siteID, boardID, +threadID); - }, - post: function(e) { - var boardID, cb, postID, ref, threadID; - ref = e.detail, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - cb = PostRedirect.delay(); - if (postID === threadID) { - if (Conf['Auto Watch']) { - return ThreadWatcher.addRaw(boardID, threadID, {}, cb); - } - } else if (Conf['Auto Watch Reply']) { - return ThreadWatcher.add(g.threads.get(boardID + '.' + threadID) || new Thread(threadID, g.boards[boardID] || new Board(boardID)), cb); - } - }, - onIndexUpdate: function(e) { - var boardID, data, db, nKilled, ref, ref1, siteID, threadID; - db = ThreadWatcher.db; - siteID = g.SITE.ID; - boardID = g.BOARD.ID; - nKilled = 0; - ref = db.data[siteID].boards[boardID]; - for (threadID in ref) { - data = ref[threadID]; - if (!(!(data != null ? data.isDead : void 0) && (ref1 = boardID + "." + threadID, indexOf.call(e.detail.threads, ref1) < 0))) { - continue; - } - if (!e.detail.threads.some(function(fullID) { - return +fullID.split('.')[1] > threadID; - })) { - continue; - } - if (Conf['Auto Prune'] || !(data && typeof data === 'object')) { - db["delete"]({ - boardID: boardID, - threadID: threadID - }); - nKilled++; - } else { - ThreadWatcher.fetchStatus({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - data: data - }); - } - } - if (nKilled) { - return ThreadWatcher.refresh(); - } - }, - onThreadRefresh: function(e) { - var thread; - thread = g.threads.get(e.detail.threadID); - if (!(e.detail[404] && ThreadWatcher.isWatched(thread))) { - return; - } - return ThreadWatcher.add(thread); - } - }, - requests: [], - fetched: 0, - fetch: function(url, arg, args, cb) { - var ajax, force, onloadend, ref, req, siteID; - siteID = arg.siteID, force = arg.force; - if (ThreadWatcher.requests.length === 0) { - ThreadWatcher.status.textContent = '...'; - $.addClass(ThreadWatcher.refreshButton, 'fa-spin'); - } - onloadend = function() { - if (this.finished) { - return; - } - this.finished = true; - ThreadWatcher.fetched++; - if (ThreadWatcher.fetched === ThreadWatcher.requests.length) { - ThreadWatcher.clearRequests(); - } else { - ThreadWatcher.status.textContent = (Math.round(ThreadWatcher.fetched / ThreadWatcher.requests.length * 100)) + "%"; - } - return cb.apply(this, args); - }; - ajax = siteID === g.SITE.ID ? $.ajax : CrossOrigin.ajax; - if (force) { - if ((ref = $.lastModified.ThreadWatcher) != null) { - delete ref[url]; - } - } - req = $.whenModified(url, 'ThreadWatcher', onloadend, { - timeout: $.MINUTE, - ajax: ajax - }); - return ThreadWatcher.requests.push(req); - }, - clearRequests: function() { - ThreadWatcher.requests = []; - ThreadWatcher.fetched = 0; - ThreadWatcher.status.textContent = ''; - return $.rmClass(ThreadWatcher.refreshButton, 'fa-spin'); - }, - abort: function() { - var j, len1, ref, req; - delete ThreadWatcher.syncing; - ref = ThreadWatcher.requests; - for (j = 0, len1 = ref.length; j < len1; j++) { - req = ref[j]; - if (!(!req.finished)) { - continue; - } - req.finished = true; - req.abort(); - } - return ThreadWatcher.clearRequests(); - }, - initLastModified: function() { - var base, boardID, boards, data, date, lm, ref, ref1, siteID, url; - lm = ((base = $.lastModified)['ThreadWatcher'] || (base['ThreadWatcher'] = $.dict())); - ref = ThreadWatcher.dbLM.data; - for (siteID in ref) { - boards = ref[siteID]; - ref1 = boards.boards; - for (boardID in ref1) { - data = ref1[boardID]; - if (ThreadWatcher.db.get({ - siteID: siteID, - boardID: boardID - })) { - for (url in data) { - date = data[url]; - lm[url] = date; - } - } else { - ThreadWatcher.dbLM["delete"]({ - siteID: siteID, - boardID: boardID - }); - } - } - } - }, - fetchAuto: function() { - var db, interval, now, ref; - clearTimeout(ThreadWatcher.timeout); - if (!Conf['Auto Update Thread Watcher']) { - return; - } - db = ThreadWatcher.db; - interval = Conf['Show Page'] || (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) ? 5 * $.MINUTE : 2 * $.HOUR; - now = Date.now(); - if (!((now - interval < (ref = db.data.lastChecked || 0) && ref <= now) || d.hidden || !d.hasFocus())) { - ThreadWatcher.fetchAllStatus(interval); - } - return ThreadWatcher.timeout = setTimeout(ThreadWatcher.fetchAuto, interval); - }, - buttonFetchAll: function() { - if (ThreadWatcher.syncing || ThreadWatcher.requests.length) { - return ThreadWatcher.abort(); - } else { - return ThreadWatcher.fetchAllStatus(); - } - }, - fetchAllStatus: function(interval) { - var dbi, dbs, j, len1, n, results; - if (interval == null) { - interval = 0; - } - ThreadWatcher.status.textContent = '...'; - $.addClass(ThreadWatcher.refreshButton, 'fa-spin'); - ThreadWatcher.syncing = true; - dbs = [ThreadWatcher.db, ThreadWatcher.unreaddb, QuoteYou.db].filter(function(x) { - return x; - }); - n = 0; - results = []; - for (j = 0, len1 = dbs.length; j < len1; j++) { - dbi = dbs[j]; - results.push(dbi.forceSync(function() { - var board, boards, db, deep, k, len2, now, ref, ref1; - if ((++n) === dbs.length) { - if (!ThreadWatcher.syncing) { - return; - } - delete ThreadWatcher.syncing; - if (!((0 <= (ref = Date.now() - (ThreadWatcher.db.data.lastChecked || 0)) && ref < interval))) { - db = ThreadWatcher.db; - now = Date.now(); - deep = !((now - 2 * $.HOUR < (ref1 = db.data.lastChecked2 || 0) && ref1 <= now)); - boards = ThreadWatcher.getAll(true); - for (k = 0, len2 = boards.length; k < len2; k++) { - board = boards[k]; - ThreadWatcher.fetchBoard(board, deep); - } - db.setLastChecked(); - if (deep) { - db.setLastChecked('lastChecked2'); - } - } - if (ThreadWatcher.fetched === ThreadWatcher.requests.length) { - return ThreadWatcher.clearRequests(); - } - } - })); - } - return results; - }, - fetchBoard: function(board, deep) { - var base, boardID, data, force, j, len1, ref, site, siteID, thread, url, urlF; - if (!board.some(function(thread) { - return !thread.data.isDead; - })) { - return; - } - force = false; - for (j = 0, len1 = board.length; j < len1; j++) { - thread = board[j]; - data = thread.data; - if (!data.isDead && data.last !== -1) { - if (Conf['Show Page'] && (data.page == null)) { - force = true; - } - if (data.modified == null) { - force = thread.force = true; - } - } - } - ref = board[0], siteID = ref.siteID, boardID = ref.boardID; - site = g.sites[siteID]; - if (!site) { - return; - } - urlF = deep && site.threadModTimeIgnoresSage ? 'catalogJSON' : 'threadsListJSON'; - url = typeof (base = site.urls)[urlF] === "function" ? base[urlF]({ - siteID: siteID, - boardID: boardID - }) : void 0; - if (!url) { - return; - } - return ThreadWatcher.fetch(url, { - siteID: siteID, - force: force - }, [board, url], ThreadWatcher.parseBoard); - }, - parseBoard: function(board, url) { - var base, boardID, data, i, index, item, j, k, l, lastPage, len1, len2, len3, len4, lmDate, m, modified, nThreads, oldest, page, pageLength, ref, ref1, ref2, ref3, ref4, replies, siteID, thread, threadID, threads; - if (this.status !== 200) { - return; - } - ref = board[0], siteID = ref.siteID, boardID = ref.boardID; - lmDate = this.getResponseHeader('Last-Modified'); - ThreadWatcher.dbLM.extend({ - siteID: siteID, - boardID: boardID, - val: $.item(url, lmDate) - }); - threads = $.dict(); - pageLength = 0; - nThreads = 0; - oldest = null; - try { - pageLength = ((ref1 = this.response[0]) != null ? ref1.threads.length : void 0) || 0; - ref2 = this.response; - for (i = j = 0, len1 = ref2.length; j < len1; i = ++j) { - page = ref2[i]; - ref3 = page.threads; - for (k = 0, len2 = ref3.length; k < len2; k++) { - item = ref3[k]; - threads[item.no] = { - page: i + 1, - index: nThreads, - modified: item.last_modified, - replies: item.replies - }; - nThreads++; - if ((oldest == null) || item.no < oldest) { - oldest = item.no; - } - } - } - } catch (error) { - for (l = 0, len3 = board.length; l < len3; l++) { - thread = board[l]; - ThreadWatcher.fetchStatus(thread); - } - } - for (m = 0, len4 = board.length; m < len4; m++) { - thread = board[m]; - threadID = thread.threadID, data = thread.data; - if (threads[threadID]) { - ref4 = threads[threadID], page = ref4.page, index = ref4.index, modified = ref4.modified, replies = ref4.replies; - if (Conf['Show Page']) { - lastPage = (typeof (base = g.sites[siteID]).isPrunedByAge === "function" ? base.isPrunedByAge({ - siteID: siteID, - boardID: boardID - }) : void 0) ? threadID === oldest : index >= nThreads - pageLength; - ThreadWatcher.update(siteID, boardID, threadID, { - page: page, - lastPage: lastPage - }); - } - if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { - if (modified !== data.modified || ((replies != null) && replies !== data.replies)) { - (thread.newData || (thread.newData = {})).modified = modified; - ThreadWatcher.fetchStatus(thread); - } - } - } else { - ThreadWatcher.fetchStatus(thread); - } - } - }, - fetchStatus: function(thread) { - var base, boardID, data, force, ref, siteID, threadID, url; - siteID = thread.siteID, boardID = thread.boardID, threadID = thread.threadID, data = thread.data, force = thread.force; - url = (ref = g.sites[siteID]) != null ? typeof (base = ref.urls).threadJSON === "function" ? base.threadJSON({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }) : void 0 : void 0; - if (!url) { - return; - } - if (data.isDead && !force) { - return; - } - if (data.last === -1) { - return; - } - return ThreadWatcher.fetch(url, { - siteID: siteID, - force: force - }, [thread], ThreadWatcher.parseStatus); - }, - parseStatus: function(thread, isArchiveURL) { - var archiveURL, base, boardID, data, force, isArchived, isDead, j, last, lastReadPost, len1, match, newData, postObj, quotesYou, quotingYou, ref, ref1, ref2, ref3, regexp, replies, site, siteID, threadID, unread, youOP; - siteID = thread.siteID, boardID = thread.boardID, threadID = thread.threadID, data = thread.data, newData = thread.newData, force = thread.force; - site = g.sites[siteID]; - if (this.status === 200 && this.response) { - last = this.response.posts[this.response.posts.length - 1].no; - replies = this.response.posts.length - 1; - isDead = isArchived = !!(this.response.posts[0].archived || isArchiveURL); - if (isDead && Conf['Auto Prune']) { - ThreadWatcher.rm(siteID, boardID, threadID); - return; - } - if (last === data.last && isDead === data.isDead && isArchived === data.isArchived) { - return; - } - lastReadPost = ThreadWatcher.unreaddb.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - defaultValue: 0 - }); - unread = data.unread || 0; - quotingYou = data.quotingYou || 0; - youOP = !!((ref = QuoteYou.db) != null ? ref.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - postID: threadID - }) : void 0); - ref1 = this.response.posts; - for (j = 0, len1 = ref1.length; j < len1; j++) { - postObj = ref1[j]; - if (!(postObj.no > (data.last || 0) && postObj.no > lastReadPost)) { - continue; - } - if ((ref2 = QuoteYou.db) != null ? ref2.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - postID: postObj.no - }) : void 0) { - continue; - } - quotesYou = false; - if (!Conf['Require OP Quote Link'] && youOP) { - quotesYou = true; - } else if (QuoteYou.db && postObj.com) { - regexp = site.regexp.quotelinkHTML; - regexp.lastIndex = 0; - while ((match = regexp.exec(postObj.com))) { - if (QuoteYou.db.get({ - siteID: siteID, - boardID: match[1] ? encodeURIComponent(match[1]) : boardID, - threadID: match[2] || threadID, - postID: match[3] || match[2] || threadID - })) { - quotesYou = true; - break; - } - } - } - if (!unread || (!quotingYou && quotesYou)) { - if (Filter.isHidden(site.Build.parseJSON(postObj, { - siteID: siteID, - boardID: boardID - }))) { - continue; - } - } - unread++; - if (quotesYou) { - quotingYou = postObj.no; - } - } - newData || (newData = {}); - $.extend(newData, { - last: last, - replies: replies, - isDead: isDead, - isArchived: isArchived, - unread: unread, - quotingYou: quotingYou - }); - return ThreadWatcher.update(siteID, boardID, threadID, newData); - } else if (this.status === 404) { - archiveURL = (ref3 = g.sites[siteID]) != null ? typeof (base = ref3.urls).archivedThreadJSON === "function" ? base.archivedThreadJSON({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }) : void 0 : void 0; - if (!isArchiveURL && archiveURL) { - return ThreadWatcher.fetch(archiveURL, { - siteID: siteID, - force: force - }, [thread, true], ThreadWatcher.parseStatus); - } else if (site.mayLackJSON && (data.last == null)) { - return ThreadWatcher.update(siteID, boardID, threadID, { - last: -1 - }); - } else { - return ThreadWatcher.update(siteID, boardID, threadID, { - isDead: true - }); - } - } - }, - getAll: function(groupByBoard) { - var all, boardID, boards, cont, data, ref, ref1, siteID, threadID, threads; - all = []; - ref = ThreadWatcher.db.data; - for (siteID in ref) { - boards = ref[siteID]; - ref1 = boards.boards; - for (boardID in ref1) { - threads = ref1[boardID]; - if (Conf['Current Board'] && (siteID !== g.SITE.ID || boardID !== g.BOARD.ID)) { - continue; - } - if (groupByBoard) { - all.push((cont = [])); - } - for (threadID in threads) { - data = threads[threadID]; - if (data && typeof data === 'object') { - (groupByBoard ? cont : all).push({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - data: data - }); - } - } - } - } - return all; - }, - makeLine: function(siteID, boardID, threadID, data) { - var count, div, excerpt, fullID, isArchived, link, page, ref, title, x; - x = $.el('a', { - className: 'fa fa-times', - href: 'javascript:;' - }); - $.on(x, 'click', ThreadWatcher.cb.rm); - excerpt = data.excerpt, isArchived = data.isArchived; - excerpt || (excerpt = "/" + boardID + "/ - No." + threadID); - if (Conf['Show Site Prefix']) { - excerpt = ThreadWatcher.prefixes[siteID] + excerpt; - } - link = $.el('a', { - href: ((ref = g.sites[siteID]) != null ? ref.urls.thread({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }, isArchived) : void 0) || '', - title: excerpt, - className: 'watcher-link' - }); - if (Conf['Show Page'] && (data.page != null)) { - page = $.el('span', { - textContent: "[" + data.page + "]", - className: 'watcher-page' - }); - $.add(link, page); - } - if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count'] && (data.unread != null)) { - count = $.el('span', { - textContent: "(" + data.unread + ")", - className: 'watcher-unread' - }); - $.add(link, count); - } - title = $.el('span', { - textContent: excerpt, - className: 'watcher-title' - }); - $.add(link, title); - div = $.el('div'); - fullID = boardID + "." + threadID; - div.dataset.fullID = fullID; - div.dataset.siteID = siteID; - if (g.VIEW === 'thread' && fullID === (g.BOARD + "." + g.THREADID)) { - $.addClass(div, 'current'); - } - if (data.isDead) { - $.addClass(div, 'dead-thread'); - } - if (Conf['Show Page']) { - if (data.lastPage) { - $.addClass(div, 'last-page'); - } - if (data.page != null) { - div.dataset.page = data.page; - } - } - if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { - if (data.unread === 0) { - $.addClass(div, 'replies-read'); - } - if (data.unread) { - $.addClass(div, 'replies-unread'); - } - if ((data.quotingYou || 0) > (data.dismiss || 0)) { - $.addClass(div, 'replies-quoting-you'); - } - } - $.add(div, [x, $.tn(' '), link]); - return div; - }, - setPrefixes: function(threads) { - var conflicts, conflicts2, j, k, len, len1, len2, prefix, prefixes, siteID, siteID2; - prefixes = $.dict(); - for (j = 0, len1 = threads.length; j < len1; j++) { - siteID = threads[j].siteID; - if (siteID in prefixes) { - continue; - } - len = 0; - prefix = ''; - conflicts = Object.keys(prefixes); - while (conflicts.length > 0) { - len++; - prefix = siteID.slice(0, len); - conflicts2 = []; - for (k = 0, len2 = conflicts.length; k < len2; k++) { - siteID2 = conflicts[k]; - if (siteID2.slice(0, len) === prefix) { - conflicts2.push(siteID2); - } else if (prefixes[siteID2].length < len) { - prefixes[siteID2] = siteID2.slice(0, len); - } - } - conflicts = conflicts2; - } - prefixes[siteID] = prefix; - } - return ThreadWatcher.prefixes = prefixes; - }, - build: function() { - var boardID, data, j, len1, list, nodes, ref, siteID, thread, threadID, threads; - nodes = []; - threads = ThreadWatcher.getAll(); - ThreadWatcher.setPrefixes(threads); - for (j = 0, len1 = threads.length; j < len1; j++) { - ref = threads[j], siteID = ref.siteID, boardID = ref.boardID, threadID = ref.threadID, data = ref.data; - if ((data.excerpt == null) && siteID === g.SITE.ID && (thread = g.threads.get(boardID + "." + threadID)) && thread.OP) { - ThreadWatcher.db.extend({ - boardID: boardID, - threadID: threadID, - val: { - excerpt: Get.threadExcerpt(thread) - } - }); - } - nodes.push(ThreadWatcher.makeLine(siteID, boardID, threadID, data)); - } - list = ThreadWatcher.list; - $.rmAll(list); - $.add(list, nodes); - return ThreadWatcher.refreshIcon(); - }, - refresh: function() { - ThreadWatcher.build(); - g.threads.forEach(function(thread) { - var isWatched, j, len1, post, ref, toggler; - isWatched = ThreadWatcher.isWatched(thread); - if (thread.OP) { - ref = [thread.OP].concat(slice.call(thread.OP.clones)); - for (j = 0, len1 = ref.length; j < len1; j++) { - post = ref[j]; - if ((toggler = $('.watch-thread-link', post.nodes.info))) { - ThreadWatcher.setToggler(toggler, isWatched); - } - } - } - if (thread.catalogView) { - return thread.catalogView.nodes.root.classList.toggle('watched', isWatched); - } - }); - if (Conf['Pin Watched Threads']) { - return $.event('SortIndex', { - deferred: Conf['Index Mode'] !== 'catalog' - }); - } - }, - refreshIcon: function() { - var className, j, len1, ref; - ref = ['replies-unread', 'replies-quoting-you']; - for (j = 0, len1 = ref.length; j < len1; j++) { - className = ref[j]; - ThreadWatcher.shortcut.classList.toggle(className, !!$("." + className, ThreadWatcher.dialog)); - } - }, - update: function(siteID, boardID, threadID, newData) { - var data, j, key, len1, line, n, newLine, ref, ref1, val; - if (!(data = (ref = ThreadWatcher.db) != null ? ref.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }) : void 0)) { - return; - } - if (newData.isDead && Conf['Auto Prune']) { - ThreadWatcher.rm(siteID, boardID, threadID); - return; - } - if (newData.isDead || newData.last === -1) { - ref1 = ['isArchived', 'page', 'lastPage', 'unread', 'quotingyou']; - for (j = 0, len1 = ref1.length; j < len1; j++) { - key = ref1[j]; - if (!(key in newData)) { - newData[key] = void 0; - } - } - } - if ((newData.last != null) && newData.last < data.last) { - newData.modified = void 0; - } - n = 0; - for (key in newData) { - val = newData[key]; - if (data[key] !== val) { - n++; - } - } - if (!n) { - return; - } - ThreadWatcher.db.extend({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - val: newData - }); - if ((line = $("#watched-threads > [data-site-i-d='" + siteID + "'][data-full-i-d='" + boardID + "." + threadID + "']", ThreadWatcher.dialog))) { - newLine = ThreadWatcher.makeLine(siteID, boardID, threadID, data); - $.replace(line, newLine); - return ThreadWatcher.refreshIcon(); - } else { - return ThreadWatcher.refresh(); - } - }, - set404: function(boardID, threadID, cb) { - var data, ref; - if (!(data = (ref = ThreadWatcher.db) != null ? ref.get({ - boardID: boardID, - threadID: threadID - }) : void 0)) { - return cb(); - } - if (Conf['Auto Prune']) { - ThreadWatcher.db["delete"]({ - boardID: boardID, - threadID: threadID - }); - return cb(); - } - if (data.isDead && !((data.isArchived != null) || (data.page != null) || (data.lastPage != null) || (data.unread != null) || (data.quotingYou != null))) { - return cb(); - } - return ThreadWatcher.db.extend({ - boardID: boardID, - threadID: threadID, - val: { - isDead: true, - isArchived: void 0, - page: void 0, - lastPage: void 0, - unread: void 0, - quotingYou: void 0 - } - }, cb); - }, - toggle: function(thread) { - var boardID, siteID, threadID; - siteID = g.SITE.ID; - boardID = thread.board.ID; - threadID = thread.ID; - if (ThreadWatcher.db.get({ - boardID: boardID, - threadID: threadID - })) { - return ThreadWatcher.rm(siteID, boardID, threadID); - } else { - return ThreadWatcher.add(thread); - } - }, - add: function(thread, cb) { - var boardID, data, siteID, threadID; - data = {}; - siteID = g.SITE.ID; - boardID = thread.board.ID; - threadID = thread.ID; - if (thread.isDead) { - if (Conf['Auto Prune'] && ThreadWatcher.db.get({ - boardID: boardID, - threadID: threadID - })) { - ThreadWatcher.rm(siteID, boardID, threadID, cb); - return; - } - data.isDead = true; - } - if (thread.OP) { - data.excerpt = Get.threadExcerpt(thread); - } - return ThreadWatcher.addRaw(boardID, threadID, data, cb); - }, - addRaw: function(boardID, threadID, data, cb) { - var oldData, thread; - oldData = ThreadWatcher.db.get({ - boardID: boardID, - threadID: threadID, - defaultValue: $.dict() - }); - delete oldData.last; - delete oldData.modified; - $.extend(oldData, data); - ThreadWatcher.db.set({ - boardID: boardID, - threadID: threadID, - val: oldData - }, cb); - ThreadWatcher.refresh(); - thread = { - siteID: g.SITE.ID, - boardID: boardID, - threadID: threadID, - data: data, - force: true - }; - if (Conf['Show Page'] && !data.isDead) { - return ThreadWatcher.fetchBoard([thread]); - } else if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { - return ThreadWatcher.fetchStatus(thread); - } - }, - rm: function(siteID, boardID, threadID, cb) { - ThreadWatcher.db["delete"]({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }, cb); - return ThreadWatcher.refresh(); - }, - menu: { - init: function() { - var menu; - if (!Conf['Thread Watcher']) { - return; - } - menu = this.menu = new UI.Menu('thread watcher'); - $.on($('.menu-button', ThreadWatcher.dialog), 'click', function(e) { - return menu.toggle(e, this, ThreadWatcher); - }); - return this.addMenuEntries(); - }, - addHeaderMenuEntry: function() { - var entryEl; - if (g.VIEW !== 'thread') { - return; - } - entryEl = $.el('a', { - href: 'javascript:;' - }); - Header.menu.addEntry({ - el: entryEl, - order: 60, - open: function() { - var addClass, ref, rmClass, text; - ref = !!ThreadWatcher.db.get({ - boardID: g.BOARD.ID, - threadID: g.THREADID - }) ? ['unwatch-thread', 'watch-thread', 'Unwatch thread'] : ['watch-thread', 'unwatch-thread', 'Watch thread'], addClass = ref[0], rmClass = ref[1], text = ref[2]; - $.addClass(entryEl, addClass); - $.rmClass(entryEl, rmClass); - entryEl.textContent = text; - return true; - } - }); - return $.on(entryEl, 'click', function() { - return ThreadWatcher.toggle(g.threads.get(g.BOARD + "." + g.THREADID)); - }); - }, - addMenuEntries: function() { - var cb, conf, entries, entry, j, len1, name, open, ref, ref1, text, title; - entries = []; - entries.push({ - text: 'Open all threads', - cb: ThreadWatcher.cb.openAll, - open: function() { - this.el.classList.toggle('disabled', !ThreadWatcher.list.firstElementChild); - return true; - } - }); - entries.push({ - text: 'Open unread threads', - cb: ThreadWatcher.cb.openUnread, - open: function() { - this.el.classList.toggle('disabled', !$('.replies-unread', ThreadWatcher.list)); - return true; - } - }); - entries.push({ - text: 'Open dead threads', - cb: ThreadWatcher.cb.openDeads, - open: function() { - this.el.classList.toggle('disabled', !$('.dead-thread', ThreadWatcher.list)); - return true; - } - }); - entries.push({ - text: 'Prune dead threads', - cb: ThreadWatcher.cb.pruneDeads, - open: function() { - this.el.classList.toggle('disabled', !$('.dead-thread', ThreadWatcher.list)); - return true; - } - }); - entries.push({ - text: 'Dismiss posts quoting you', - title: 'Unhighlight the thread watcher icon and threads until there are new replies quoting you.', - cb: ThreadWatcher.cb.dismiss, - open: function() { - this.el.classList.toggle('disabled', !$.hasClass(ThreadWatcher.shortcut, 'replies-quoting-you')); - return true; - } - }); - for (j = 0, len1 = entries.length; j < len1; j++) { - ref = entries[j], text = ref.text, title = ref.title, cb = ref.cb, open = ref.open; - entry = { - el: $.el('a', { - textContent: text, - href: 'javascript:;' - }) - }; - if (title) { - entry.el.title = title; - } - $.on(entry.el, 'click', cb); - entry.open = open.bind(entry); - this.menu.addEntry(entry); - } - ref1 = Config.threadWatcher; - for (name in ref1) { - conf = ref1[name]; - this.addCheckbox(name, conf[1]); - } - }, - addCheckbox: function(name, desc) { - var entry, input; - entry = { - type: 'thread watcher', - el: UI.checkbox(name, name.replace(' Thread Watcher', '')) - }; - entry.el.title = desc; - input = entry.el.firstElementChild; - if (name === 'Show Unread Count' && !ThreadWatcher.unreadEnabled) { - input.disabled = true; - $.addClass(entry.el, 'disabled'); - entry.el.title += '\n[Remember Last Read Post is disabled.]'; - } - $.on(input, 'change', $.cb.checked); - if (name === 'Current Board' || name === 'Show Page' || name === 'Show Unread Count' || name === 'Show Site Prefix') { - $.on(input, 'change', ThreadWatcher.refresh); - } - if (name === 'Show Page' || name === 'Show Unread Count' || name === 'Auto Update Thread Watcher') { - $.on(input, 'change', ThreadWatcher.fetchAuto); - } - return this.menu.addEntry(entry); - } - } - }; - - return ThreadWatcher; - -}).call(this); - -Unread = (function() { - var Unread; - - Unread = { - init: function() { - if (!(g.VIEW === 'thread' && (Conf['Unread Count'] || Conf['Unread Favicon'] || Conf['Unread Line'] || Conf['Remember Last Read Post'] || Conf['Desktop Notifications'] || Conf['Quote Threading']))) { - return; - } - if (Conf['Remember Last Read Post']) { - $.sync('Remember Last Read Post', function(enabled) { - return Conf['Remember Last Read Post'] = enabled; - }); - this.db = new DataBoard('lastReadPosts', this.sync); - } - this.hr = $.el('hr', { - id: 'unread-line', - className: 'unread-line' - }); - this.posts = new Set(); - this.postsQuotingYou = new Set(); - this.order = new RandomAccessList(); - this.position = null; - Callbacks.Thread.push({ - name: 'Unread', - cb: this.node - }); - return Callbacks.Post.push({ - name: 'Unread', - cb: this.addPost - }); - }, - node: function() { - var ID, j, len, ref, ref1, resetLink; - Unread.thread = this; - Unread.title = d.title; - Unread.lastReadPost = ((ref = Unread.db) != null ? ref.get({ - boardID: this.board.ID, - threadID: this.ID - }) : void 0) || 0; - Unread.readCount = 0; - ref1 = this.posts.keys; - for (j = 0, len = ref1.length; j < len; j++) { - ID = ref1[j]; - if (+ID <= Unread.lastReadPost) { - Unread.readCount++; - } - } - $.one(d, '4chanXInitFinished', Unread.ready); - $.on(d, 'PostsInserted', Unread.onUpdate); - $.on(d, 'ThreadUpdate', function(e) { - if (e.detail[404]) { - return Unread.update(); - } - }); - resetLink = $.el('a', { - href: 'javascript:;', - className: 'unread-reset', - textContent: 'Mark all unread' - }); - $.on(resetLink, 'click', Unread.reset); - return Header.menu.addEntry({ - el: resetLink, - order: 70 - }); - }, - ready: function() { - if (Conf['Remember Last Read Post'] && Conf['Scroll to Last Read Post']) { - Unread.scroll(); - } - Unread.setLine(true); - Unread.read(); - Unread.update(); - $.on(d, 'scroll visibilitychange', Unread.read); - if (Conf['Unread Line']) { - return $.on(d, 'visibilitychange', Unread.setLine); - } - }, - positionPrev: function() { - if (Unread.position) { - return Unread.position.prev; - } else { - return Unread.order.last; - } - }, - scroll: function() { - var bottom, hash, position; - if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { - return; - } - position = Unread.positionPrev(); - while (position) { - bottom = position.data.nodes.bottom; - if (!bottom.getBoundingClientRect().height) { - position = position.prev; - } else { - Header.scrollToIfNeeded(bottom, true); - break; - } - } - }, - reset: function() { - if (Unread.lastReadPost == null) { - return; - } - Unread.posts = new Set(); - Unread.postsQuotingYou = new Set(); - Unread.order = new RandomAccessList(); - Unread.position = null; - Unread.lastReadPost = 0; - Unread.readCount = 0; - Unread.thread.posts.forEach(function(post) { - return Unread.addPost.call(post); - }); - $.forceSync('Remember Last Read Post'); - if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) { - Unread.db.set({ - boardID: Unread.thread.board.ID, - threadID: Unread.thread.ID, - val: 0 - }); - } - Unread.updatePosition(); - Unread.setLine(); - return Unread.update(); - }, - sync: function() { - var ID, i, j, lastReadPost, postIDs, ref, ref1; - if (Unread.lastReadPost == null) { - return; - } - lastReadPost = Unread.db.get({ - boardID: Unread.thread.board.ID, - threadID: Unread.thread.ID, - defaultValue: 0 - }); - if (!(Unread.lastReadPost < lastReadPost)) { - return; - } - Unread.lastReadPost = lastReadPost; - postIDs = Unread.thread.posts.keys; - for (i = j = ref = Unread.readCount, ref1 = postIDs.length; j < ref1; i = j += 1) { - ID = +postIDs[i]; - if (!Unread.thread.posts.get(ID).isFetchedQuote) { - if (ID > Unread.lastReadPost) { - break; - } - Unread.posts["delete"](ID); - Unread.postsQuotingYou["delete"](ID); - } - Unread.readCount++; - } - Unread.updatePosition(); - Unread.setLine(); - return Unread.update(); - }, - addPost: function() { - if (this.isFetchedQuote || this.isClone) { - return; - } - Unread.order.push(this); - if (this.ID <= Unread.lastReadPost || this.isHidden || QuoteYou.isYou(this)) { - return; - } - Unread.posts.add((Unread.posts.last = this.ID)); - Unread.addPostQuotingYou(this); - return Unread.position != null ? Unread.position : Unread.position = Unread.order[this.ID]; - }, - addPostQuotingYou: function(post) { - var j, len, quotelink, ref, ref1; - ref = post.nodes.quotelinks; - for (j = 0, len = ref.length; j < len; j++) { - quotelink = ref[j]; - if (!((ref1 = QuoteYou.db) != null ? ref1.get(Get.postDataFromLink(quotelink)) : void 0)) { - continue; - } - Unread.postsQuotingYou.add((Unread.postsQuotingYou.last = post.ID)); - Unread.openNotification(post); - return; - } - }, - openNotification: function(post, predicate) { - var notif; - if (predicate == null) { - predicate = ' replied to you'; - } - if (!Header.areNotificationsEnabled) { - return; - } - notif = new Notification("" + post.info.nameBlock + predicate, { - body: post.commentDisplay(), - icon: Favicon.logo - }); - notif.onclick = function() { - Header.scrollToIfNeeded(post.nodes.bottom, true); - return window.focus(); - }; - return notif.onshow = function() { - return setTimeout(function() { - return notif.close(); - }, 7 * $.SECOND); - }; - }, - onUpdate: function() { - return $.queueTask(function() { - Unread.setLine(); - Unread.read(); - return Unread.update(); - }); - }, - readSinglePost: function(post) { - var ID; - ID = post.ID; - if (!Unread.posts.has(ID)) { - return; - } - Unread.posts["delete"](ID); - Unread.postsQuotingYou["delete"](ID); - Unread.updatePosition(); - Unread.saveLastReadPost(); - return Unread.update(); - }, - read: $.debounce(100, function(e) { - var ID, bottom, count, data, ref; - if (!Unread.posts.size && Unread.readCount !== Unread.thread.posts.keys.length) { - Unread.saveLastReadPost(); - } - if (d.hidden || !Unread.posts.size) { - return; - } - count = 0; - while (Unread.position) { - ref = Unread.position, ID = ref.ID, data = ref.data; - bottom = data.nodes.bottom; - if (!(!bottom.getBoundingClientRect().height || Header.getBottomOf(bottom) > -1)) { - break; - } - count++; - Unread.posts["delete"](ID); - Unread.postsQuotingYou["delete"](ID); - Unread.position = Unread.position.next; - } - if (!count) { - return; - } - Unread.updatePosition(); - Unread.saveLastReadPost(); - if (e) { - return Unread.update(); - } - }), - updatePosition: function() { - while (Unread.position && !Unread.posts.has(Unread.position.ID)) { - Unread.position = Unread.position.next; - } - }, - saveLastReadPost: $.debounce(2 * $.SECOND, function() { - var ID, i, j, postIDs, ref, ref1; - $.forceSync('Remember Last Read Post'); - if (!(Conf['Remember Last Read Post'] && Unread.db)) { - return; - } - postIDs = Unread.thread.posts.keys; - for (i = j = ref = Unread.readCount, ref1 = postIDs.length; j < ref1; i = j += 1) { - ID = +postIDs[i]; - if (!Unread.thread.posts.get(ID).isFetchedQuote) { - if (Unread.posts.has(ID)) { - break; - } - Unread.lastReadPost = ID; - } - Unread.readCount++; - } - if (Unread.thread.isDead && !Unread.thread.isArchived) { - return; - } - return Unread.db.set({ - boardID: Unread.thread.board.ID, - threadID: Unread.thread.ID, - val: Unread.lastReadPost - }); - }), - setLine: function(force) { - var node, oldPosition, ref; - if (!Conf['Unread Line']) { - return; - } - if (Unread.hr.hidden || d.hidden || (force === true)) { - oldPosition = Unread.linePosition; - if ((Unread.linePosition = Unread.positionPrev())) { - if (Unread.linePosition !== oldPosition) { - node = Unread.linePosition.data.nodes.bottom; - if (((ref = node.nextSibling) != null ? ref.tagName : void 0) === 'BR') { - node = node.nextSibling; - } - $.after(node, Unread.hr); - } - } else { - $.rm(Unread.hr); - } - } - return Unread.hr.hidden = Unread.linePosition === Unread.order.last; - }, - update: function() { - var count, countQuotingYou, isDead, titleCount, titleDead, titleQuotingYou; - count = Unread.posts.size; - countQuotingYou = Unread.postsQuotingYou.size; - if (Conf['Unread Count']) { - titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : ''; - titleCount = count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : ''; - titleDead = Unread.thread.isDead ? Unread.title.replace('-', (Unread.thread.isArchived ? '- Archived -' : '- 404 -')) : Unread.title; - d.title = "" + titleQuotingYou + titleCount + titleDead; - } - Unread.saveThreadWatcherCount(); - if (Conf['Unread Favicon'] && g.SITE.software === 'yotsuba') { - isDead = Unread.thread.isDead; - return Favicon.set((countQuotingYou ? (isDead ? 'unreadDeadY' : 'unreadY') : count ? (isDead ? 'unreadDead' : 'unread') : (isDead ? 'dead' : 'default'))); - } - }, - saveThreadWatcherCount: $.debounce(2 * $.SECOND, function() { - var i, j, posts, quotingYou, ref; - $.forceSync('Remember Last Read Post'); - if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) { - quotingYou = !Conf['Require OP Quote Link'] && QuoteYou.isYou(Unread.thread.OP) ? Unread.posts : Unread.postsQuotingYou; - if (!quotingYou.size) { - quotingYou.last = 0; - } else if (!quotingYou.has(quotingYou.last)) { - quotingYou.last = 0; - posts = Unread.thread.posts.keys; - for (i = j = ref = posts.length - 1; j >= 0; i = j += -1) { - if (quotingYou.has(+posts[i])) { - quotingYou.last = posts[i]; - break; - } - } - } - return ThreadWatcher.update(g.SITE.ID, Unread.thread.board.ID, Unread.thread.ID, { - last: Unread.thread.lastPost, - isDead: Unread.thread.isDead, - isArchived: Unread.thread.isArchived, - unread: Unread.posts.size, - quotingYou: quotingYou.last || 0 - }); - } - }) - }; - - return Unread; - -}).call(this); - -UnreadIndex = (function() { - var UnreadIndex; - - UnreadIndex = { - lastReadPost: $.dict(), - hr: $.dict(), - markReadLink: $.dict(), - init: function() { - if (!(g.VIEW === 'index' && Conf['Remember Last Read Post'] && Conf['Unread Line in Index'])) { - return; - } - this.enabled = true; - this.db = new DataBoard('lastReadPosts', this.sync); - Callbacks.Thread.push({ - name: 'Unread Line in Index', - cb: this.node - }); - $.on(d, 'IndexRefreshInternal', this.onIndexRefresh); - return $.on(d, 'PostsInserted PostsRemoved', this.onPostsInserted); - }, - node: function() { - UnreadIndex.lastReadPost[this.fullID] = UnreadIndex.db.get({ - boardID: this.board.ID, - threadID: this.ID - }) || 0; - if (!Index.enabled) { - return UnreadIndex.update(this); - } - }, - onIndexRefresh: function(e) { - var i, len, ref, results, thread, threadID; - if (e.detail.isCatalog) { - return; - } - ref = e.detail.threadIDs; - results = []; - for (i = 0, len = ref.length; i < len; i++) { - threadID = ref[i]; - thread = g.threads.get(threadID); - results.push(UnreadIndex.update(thread)); - } - return results; - }, - onPostsInserted: function(e) { - var ref, ref1, thread, wasVisible; - if (e.target === Index.root) { - return; - } - thread = Get.threadFromNode(e.target); - if (!thread || thread.nodes.root !== e.target) { - return; - } - wasVisible = !!((ref = UnreadIndex.hr[thread.fullID]) != null ? ref.parentNode : void 0); - UnreadIndex.update(thread); - if (Conf['Scroll to Last Read Post'] && e.type === 'PostsInserted' && !wasVisible && !!((ref1 = UnreadIndex.hr[thread.fullID]) != null ? ref1.parentNode : void 0)) { - return Header.scrollToIfNeeded(UnreadIndex.hr[thread.fullID], true); - } - }, - sync: function() { - return g.threads.forEach(function(thread) { - var lastReadPost, ref; - lastReadPost = UnreadIndex.db.get({ - boardID: thread.board.ID, - threadID: thread.ID - }) || 0; - if (lastReadPost !== UnreadIndex.lastReadPost[thread.fullID]) { - UnreadIndex.lastReadPost[thread.fullID] = lastReadPost; - if ((ref = thread.nodes.root) != null ? ref.parentNode : void 0) { - return UnreadIndex.update(thread); - } - } - }); - }, - update: function(thread) { - var divider, firstUnread, hasUnread, hr, lastReadPost, link, repliesRead, repliesShown; - lastReadPost = UnreadIndex.lastReadPost[thread.fullID]; - repliesShown = 0; - repliesRead = 0; - firstUnread = null; - thread.posts.forEach(function(post) { - if (post.isReply && thread.nodes.root.contains(post.nodes.root)) { - repliesShown++; - if (post.ID <= lastReadPost) { - return repliesRead++; - } else if ((!firstUnread || post.ID < firstUnread.ID) && !post.isHidden && !QuoteYou.isYou(post)) { - return firstUnread = post; - } - } - }); - hr = UnreadIndex.hr[thread.fullID]; - if (firstUnread && (repliesRead || (lastReadPost === thread.OP.ID && (!$(g.SITE.selectors.summary, thread.nodes.root) || thread.ID in ExpandThread.statuses)))) { - if (!hr) { - hr = UnreadIndex.hr[thread.fullID] = $.el('hr', { - className: 'unread-line' - }); - } - $.before(firstUnread.nodes.root, hr); - } else { - $.rm(hr); - } - hasUnread = repliesShown ? firstUnread || !repliesRead : Index.enabled ? thread.lastPost > lastReadPost : thread.OP.ID > lastReadPost; - thread.nodes.root.classList.toggle('unread-thread', hasUnread); - link = UnreadIndex.markReadLink[thread.fullID]; - if (!link) { - link = UnreadIndex.markReadLink[thread.fullID] = $.el('a', { - className: 'unread-mark-read brackets-wrap', - href: 'javascript:;', - textContent: 'Mark Read' - }); - $.on(link, 'click', UnreadIndex.markRead); - } - if ((divider = $(g.SITE.selectors.threadDivider, thread.nodes.root))) { - return $.before(divider, link); - } else { - return $.add(thread.nodes.root, link); - } - }, - markRead: function() { - var thread; - thread = Get.threadFromNode(this); - UnreadIndex.lastReadPost[thread.fullID] = thread.lastPost; - UnreadIndex.db.set({ - boardID: thread.board.ID, - threadID: thread.ID, - val: thread.lastPost - }); - $.rm(UnreadIndex.hr[thread.fullID]); - thread.nodes.root.classList.remove('unread-thread'); - return ThreadWatcher.update(g.SITE.ID, thread.board.ID, thread.ID, { - last: thread.lastPost, - unread: 0, - quotingYou: 0 - }); - } - }; - - return UnreadIndex; - -}).call(this); - -Captcha = {}; - -(function() { - Captcha.cache = { - init: function() { - $.on(d, 'SaveCaptcha', (function(_this) { - return function(e) { - return _this.saveAPI(e.detail); - }; - })(this)); - return $.on(d, 'NoCaptcha', (function(_this) { - return function(e) { - return _this.noCaptcha(e.detail); - }; - })(this)); - }, - captchas: [], - getCount: function() { - return this.captchas.length; - }, - neededRaw: function() { - return !(this.haveCookie() || this.captchas.length || QR.req || this.submitCB) && (QR.posts.length > 1 || Conf['Auto-load captcha'] || !QR.posts[0].isOnlyQuotes() || QR.posts[0].file); - }, - needed: function() { - return this.neededRaw() && $.event('LoadCaptcha'); - }, - prerequest: function() { - if (!Conf['Prerequest Captcha']) { - return; - } - return $.queueTask((function(_this) { - return function() { - var isReply; - if (!_this.prerequested && _this.neededRaw() && !$.event('LoadCaptcha') && !QR.captcha.occupied() && QR.cooldown.seconds <= 60 && QR.selected === QR.posts[QR.posts.length - 1] && !QR.selected.isOnlyQuotes()) { - isReply = QR.selected.thread !== 'new'; - if (!$.event('RequestCaptcha', { - isReply: isReply - })) { - _this.prerequested = true; - _this.submitCB = function(captcha) { - if (captcha) { - return _this.save(captcha); - } - }; - return _this.updateCount(); - } - } - }; - })(this)); - }, - haveCookie: function() { - return /\b_ct=/.test(d.cookie) && QR.posts[0].thread !== 'new'; - }, - getOne: function() { - var captcha; - delete this.prerequested; - this.clear(); - if ((captcha = this.captchas.shift())) { - this.count(); - return captcha; - } else { - return null; - } - }, - request: function(isReply) { - if (!this.submitCB) { - if ($.event('RequestCaptcha', { - isReply: isReply - })) { - return; - } - } - return (function(_this) { - return function(cb) { - _this.submitCB = cb; - return _this.updateCount(); - }; - })(this); - }, - abort: function() { - if (this.submitCB) { - delete this.submitCB; - $.event('AbortCaptcha'); - return this.updateCount(); - } - }, - saveAPI: function(captcha) { - var cb; - if ((cb = this.submitCB)) { - delete this.submitCB; - cb(captcha); - return this.updateCount(); - } else { - return this.save(captcha); - } - }, - noCaptcha: function(detail) { - var cb; - if ((cb = this.submitCB)) { - if (!this.haveCookie() || (detail != null ? detail.error : void 0)) { - QR.error((detail != null ? detail.error : void 0) || 'Failed to retrieve captcha.'); - QR.captcha.setup(d.activeElement === QR.nodes.status); - } - delete this.submitCB; - cb(); - return this.updateCount(); - } - }, - save: function(captcha) { - var cb; - if ((cb = this.submitCB)) { - this.abort(); - cb(captcha); - return; - } - this.captchas.push(captcha); - this.captchas.sort(function(a, b) { - return a.timeout - b.timeout; - }); - return this.count(); - }, - clear: function() { - var captcha, i, j, len, now, ref; - if (this.captchas.length) { - now = Date.now(); - ref = this.captchas; - for (i = j = 0, len = ref.length; j < len; i = ++j) { - captcha = ref[i]; - if (captcha.timeout > now) { - break; - } - } - if (i) { - this.captchas = this.captchas.slice(i); - return this.count(); - } - } - }, - count: function() { - clearTimeout(this.timer); - if (this.captchas.length) { - this.timer = setTimeout(this.clear.bind(this), this.captchas[0].timeout - Date.now()); - } - return this.updateCount(); - }, - updateCount: function() { - return $.event('CaptchaCount', this.captchas.length); - } - }; - -}).call(this); - -(function() { - Captcha.replace = { - init: function() { - var ref; - if (!(g.SITE.software === 'yotsuba' && d.cookie.indexOf('pass_enabled=1') < 0)) { - return; - } - if (Conf['Force Noscript Captcha'] && Main.jsEnabled) { - $.ready(Captcha.replace.noscript); - return; - } - if (Conf['captchaLanguage'].trim()) { - if ((ref = location.hostname) === 'boards.4chan.org' || ref === 'boards.4channel.org') { - return $.onExists(doc, '#captchaFormPart', function(node) { - return $.onExists(node, 'iframe[src^="https://www.google.com/recaptcha/"]', Captcha.replace.iframe); - }); - } else { - return $.onExists(doc, 'iframe[src^="https://www.google.com/recaptcha/"]', Captcha.replace.iframe); - } - } - }, - noscript: function() { - var insert, noscript, original, span, toggle; - if (!((original = $('#g-recaptcha')) && (noscript = $('noscript', original.parentNode)))) { - return; - } - span = $.el('span', { - id: 'captcha-forced-noscript' - }); - $.replace(noscript, span); - $.rm(original); - insert = function() { - span.innerHTML = noscript.textContent; - return Captcha.replace.iframe($('iframe[src^="https://www.google.com/recaptcha/"]', span)); - }; - if ((toggle = $('#togglePostFormLink a, #form-link'))) { - return $.on(toggle, 'click', insert); - } else { - return insert(); - } - }, - iframe: function(iframe) { - var lang, src; - if ((lang = Conf['captchaLanguage'].trim())) { - src = /[?&]hl=/.test(iframe.src) ? iframe.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang)) : iframe.src + ("&hl=" + (encodeURIComponent(lang))); - if (iframe.src !== src) { - iframe.src = src; - } - } - } - }; - -}).call(this); - -(function() { - Captcha.t = { - init: function() { - var root; - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - return; - } - if (!(this.isEnabled = !!$('#t-root') || !$.id('postForm'))) { - return; - } - root = $.el('div', { - className: 'captcha-root' - }); - this.nodes = { - root: root - }; - $.addClass(QR.nodes.el, 'has-captcha', 'captcha-t'); - return $.after(QR.nodes.com.parentNode, root); - }, - moreNeeded: function() {}, - getThread: function() { - var boardID, threadID; - boardID = g.BOARD.ID; - if (QR.posts[0].thread === 'new') { - threadID = '0'; - } else { - threadID = '' + QR.posts[0].thread; - } - return { - boardID: boardID, - threadID: threadID - }; - }, - setup: function(focus) { - if (!this.isEnabled) { - return; - } - if (!this.nodes.container) { - this.nodes.container = $.el('div', { - className: 'captcha-container' - }); - $.prepend(this.nodes.root, this.nodes.container); - Captcha.t.currentThread = Captcha.t.getThread(); - $.global(function() { - var el; - el = document.querySelector('#qr .captcha-container'); - window.TCaptcha.init(el, this.boardID, +this.threadID); - return window.TCaptcha.setErrorCb(function(err) { - return window.dispatchEvent(new CustomEvent('CreateNotification', { - detail: { - type: 'warning', - content: '' + err - } - })); - }); - }, Captcha.t.currentThread); - } - if (focus) { - return $('#t-resp').focus(); - } - }, - destroy: function() { - if (!(this.isEnabled && this.nodes.container)) { - return; - } - $.global(function() { - return window.TCaptcha.destroy(); - }); - $.rm(this.nodes.container); - return delete this.nodes.container; - }, - updateThread: function() { - var boardID, newThread, ref, threadID; - if (!this.isEnabled) { - return; - } - ref = Captcha.t.currentThread || {}, boardID = ref.boardID, threadID = ref.threadID; - newThread = Captcha.t.getThread(); - if (!(newThread.boardID === boardID && newThread.threadID === threadID)) { - Captcha.t.destroy(); - return Captcha.t.setup(); - } - }, - getOne: function() { - var el, i, key, len, ref, response; - response = {}; - if (this.nodes.container) { - ref = ['t-response', 't-challenge']; - for (i = 0, len = ref.length; i < len; i++) { - key = ref[i]; - response[key] = $("[name='" + key + "']", this.nodes.container).value; - } - } - if (!response['t-response'] && !((el = $('#t-msg')) && /Verification not required/i.test(el.textContent))) { - response = null; - } - return response; - }, - setUsed: function() { - if (!this.isEnabled) { - return; - } - if (this.nodes.container) { - return $.global(function() { - return window.TCaptcha.clearChallenge(); - }); - } - }, - occupied: function() { - return !!this.nodes.container; - } - }; - -}).call(this); - -(function() { - var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Captcha.v2 = { - lifetime: 2 * $.MINUTE, - init: function() { - var counter, root; - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - return; - } - if (!(this.isEnabled = !!$('#g-recaptcha, #captcha-forced-noscript') || !$.id('postForm'))) { - return; - } - if ((this.noscript = Conf['Force Noscript Captcha'] || !Main.jsEnabled)) { - $.addClass(QR.nodes.el, 'noscript-captcha'); - } - Captcha.cache.init(); - $.on(d, 'CaptchaCount', this.count.bind(this)); - root = $.el('div', { - className: 'captcha-root' - }); - $.extend(root, {innerHTML: "
    "}); - counter = $('.captcha-counter > a', root); - this.nodes = { - root: root, - counter: counter - }; - this.count(); - $.addClass(QR.nodes.el, 'has-captcha', 'captcha-v2'); - $.after(QR.nodes.com.parentNode, root); - $.on(counter, 'click', this.toggle.bind(this)); - $.on(counter, 'keydown', (function(_this) { - return function(e) { - if (Keybinds.keyCode(e) !== 'Space') { - return; - } - _this.toggle(); - e.preventDefault(); - return e.stopPropagation(); - }; - })(this)); - return $.on(window, 'captcha:success', (function(_this) { - return function() { - return $.queueTask(function() { - return _this.save(false); - }); - }; - })(this)); - }, - timeouts: {}, - prevNeeded: 0, - noscriptURL: function() { - var lang, url; - url = 'https://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc'; - if ((lang = Conf['captchaLanguage'].trim())) { - url += "&hl=" + (encodeURIComponent(lang)); - } - return url; - }, - moreNeeded: function() { - return $.queueTask((function(_this) { - return function() { - var needed; - needed = Captcha.cache.needed(); - if (needed && !_this.prevNeeded) { - _this.setup(QR.cooldown.auto && d.activeElement === QR.nodes.status); - } - return _this.prevNeeded = needed; - }; - })(this)); - }, - toggle: function() { - if (this.nodes.container && !this.timeouts.destroy) { - return this.destroy(); - } else { - return this.setup(true, true); - } - }, - setup: function(focus, force) { - if (!(this.isEnabled && (Captcha.cache.needed() || force))) { - return; - } - if (focus) { - $.addClass(QR.nodes.el, 'focus'); - this.nodes.counter.focus(); - } - if (this.timeouts.destroy) { - clearTimeout(this.timeouts.destroy); - delete this.timeouts.destroy; - return this.reload(); - } - if (this.nodes.container) { - $.queueTask((function(_this) { - return function() { - var iframe; - if (_this.nodes.container && d.activeElement === _this.nodes.counter && (iframe = $('iframe[src^="https://www.google.com/recaptcha/"]', _this.nodes.container))) { - iframe.focus(); - return QR.focus(); - } - }; - })(this)); - return; - } - this.nodes.container = $.el('div', { - className: 'captcha-container' - }); - $.prepend(this.nodes.root, this.nodes.container); - new MutationObserver(this.afterSetup.bind(this)).observe(this.nodes.container, { - childList: true, - subtree: true - }); - if (this.noscript) { - return this.setupNoscript(); - } else { - return this.setupJS(); - } - }, - setupNoscript: function() { - var div, iframe, textarea; - iframe = $.el('iframe', { - id: 'qr-captcha-iframe', - scrolling: 'no', - src: this.noscriptURL() - }); - div = $.el('div'); - textarea = $.el('textarea'); - $.add(div, textarea); - return $.add(this.nodes.container, [iframe, div]); - }, - setupJS: function() { - return $.global(function() { - var cbNative, render, script; - render = function() { - var classList, container; - classList = document.documentElement.classList; - container = document.querySelector('#qr .captcha-container'); - return container.dataset.widgetID = window.grecaptcha.render(container, { - sitekey: '6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc', - theme: classList.contains('tomorrow') || classList.contains('spooky') || classList.contains('dark-captcha') ? 'dark' : 'light', - callback: function(response) { - return window.dispatchEvent(new CustomEvent('captcha:success', { - detail: response - })); - } - }); - }; - if (window.grecaptcha) { - return render(); - } else { - cbNative = window.onRecaptchaLoaded; - window.onRecaptchaLoaded = function() { - render(); - return cbNative(); - }; - if (!document.head.querySelector('script[src^="https://www.google.com/recaptcha/api.js"]')) { - script = document.createElement('script'); - script.src = 'https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoaded&render=explicit'; - return document.head.appendChild(script); - } - } - }); - }, - afterSetup: function(mutations) { - var i, iframe, j, len, len1, mutation, node, ref, textarea; - for (i = 0, len = mutations.length; i < len; i++) { - mutation = mutations[i]; - ref = mutation.addedNodes; - for (j = 0, len1 = ref.length; j < len1; j++) { - node = ref[j]; - if ((iframe = $.x('./descendant-or-self::iframe[starts-with(@src, "https://www.google.com/recaptcha/")]', node))) { - this.setupIFrame(iframe); - } - if ((textarea = $.x('./descendant-or-self::textarea', node))) { - this.setupTextArea(textarea); - } - } - } - }, - setupIFrame: function(iframe) { - var ref, ref1; - if (!doc.contains(iframe)) { - return; - } - Captcha.replace.iframe(iframe); - $.addClass(QR.nodes.el, 'captcha-open'); - this.fixQRPosition(); - $.on(iframe, 'load', this.fixQRPosition); - if (d.activeElement === this.nodes.counter) { - iframe.focus(); - } - if (((ref = $.engine) === 'blink' || ref === 'edge') && (ref1 = iframe.parentNode, indexOf.call($$('#qr .captcha-container > div > div:first-of-type'), ref1) >= 0)) { - return $.on(iframe.parentNode, 'scroll', function() { - return this.scrollTop = 0; - }); - } - }, - fixQRPosition: function() { - if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) { - QR.nodes.el.style.top = ''; - return QR.nodes.el.style.bottom = '0px'; - } - }, - setupTextArea: function(textarea) { - return $.one(textarea, 'input', (function(_this) { - return function() { - return _this.save(true); - }; - })(this)); - }, - destroy: function() { - if (!this.isEnabled) { - return; - } - delete this.timeouts.destroy; - $.rmClass(QR.nodes.el, 'captcha-open'); - if (this.nodes.container) { - $.global(function() { - var container; - container = document.querySelector('#qr .captcha-container'); - return window.grecaptcha.reset(container.dataset.widgetID); - }); - $.rm(this.nodes.container); - return delete this.nodes.container; - } - }, - getOne: function(isReply) { - return Captcha.cache.getOne(isReply); - }, - save: function(pasted, token) { - var base, focus, ref; - Captcha.cache.save({ - response: token || $('textarea', this.nodes.container).value, - timeout: Date.now() + this.lifetime - }); - focus = ((ref = d.activeElement) != null ? ref.nodeName : void 0) === 'IFRAME' && /https?:\/\/www\.google\.com\/recaptcha\//.test(d.activeElement.src); - if (Captcha.cache.needed()) { - if (focus) { - if (QR.cooldown.auto || Conf['Post on Captcha Completion']) { - this.nodes.counter.focus(); - } else { - QR.nodes.status.focus(); - } - } - this.reload(); - } else { - if (pasted) { - this.destroy(); - } else { - if ((base = this.timeouts).destroy == null) { - base.destroy = setTimeout(this.destroy.bind(this), 3 * $.SECOND); - } - } - if (focus) { - QR.nodes.status.focus(); - } - } - if (Conf['Post on Captcha Completion'] && !QR.cooldown.auto) { - return QR.submit(); - } - }, - count: function() { - var count, loading; - count = Captcha.cache.getCount(); - loading = Captcha.cache.submitCB ? '...' : ''; - this.nodes.counter.textContent = "Captchas: " + count + loading; - return this.moreNeeded(); - }, - reload: function() { - if ($('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', this.nodes.container)) { - this.destroy(); - return this.setup(false, true); - } else { - return $.global(function() { - var container; - container = document.querySelector('#qr .captcha-container'); - return window.grecaptcha.reset(container.dataset.widgetID); - }); - } - }, - occupied: function() { - return !!this.nodes.container && !this.timeouts.destroy; - } - }; - -}).call(this); - -PassLink = (function() { - var PassLink; - - PassLink = { - init: function() { - if (!(g.SITE.software === 'yotsuba' && Conf['Pass Link'])) { - return; - } - return Main.ready(this.ready); - }, - ready: function() { - var passLink, styleSelector; - if (!(styleSelector = $.id('styleSelector'))) { - return; - } - passLink = $.el('span', { - className: 'brackets-wrap pass-link-container' - }); - $.extend(passLink, {innerHTML: "4chan Pass"}); - $.on(passLink.firstElementChild, 'click', function() { - return window.open("//sys." + (location.hostname.split('.')[1]) + ".org/auth", Date.now(), 'width=500,height=280,toolbar=0'); - }); - return $.before(styleSelector.previousSibling, [passLink, $.tn('\u00A0\u00A0')]); - } - }; - - return PassLink; - -}).call(this); - -PostRedirect = (function() { - var PostRedirect; - - PostRedirect = { - init: function() { - return $.on(d, 'QRPostSuccessful', (function(_this) { - return function(e) { - if (!e.detail.redirect) { - return; - } - _this.event = e; - _this.delays = 0; - return $.queueTask(function() { - if (e === _this.event && _this.delays === 0) { - return location.href = e.detail.redirect; - } - }); - }; - })(this)); - }, - delays: 0, - delay: function() { - var e; - if (!this.event) { - return null; - } - e = this.event; - this.delays++; - return (function(_this) { - return function() { - if (e !== _this.event) { - return; - } - _this.delays--; - if (_this.delays === 0) { - return location.href = e.detail.redirect; - } - }; - })(this); - } - }; - - return PostRedirect; - -}).call(this); - -PostSuccessful = (function() { - var PostSuccessful; - - PostSuccessful = { - init: function() { - if (!Conf['Remember Your Posts']) { - return; - } - return $.ready(this.ready); - }, - ready: function() { - var _, db, postID, ref, threadID; - if (d.title !== 'Post successful!') { - return; - } - ref = $('h1').nextSibling.textContent.match(/thread:(\d+),no:(\d+)/), _ = ref[0], threadID = ref[1], postID = ref[2]; - postID = +postID; - threadID = +threadID || postID; - db = new DataBoard('yourPosts'); - return db.set({ - boardID: g.BOARD.ID, - threadID: threadID, - postID: postID, - val: true - }); - } - }; - - return PostSuccessful; - -}).call(this); - -QR = (function() { - var QR, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - QR = { - 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: function() { - var sc; - if (!Conf['Quick Reply']) { - return; - } - this.posts = []; - $.on(d, '4chanXInitFinished', function() { - return BoardConfig.ready(QR.initReady); - }); - Callbacks.Post.push({ - name: 'Quick Reply', - cb: this.node - }); - this.shortcut = sc = $.el('a', { - className: 'fa fa-comment-o disabled', - textContent: 'QR', - title: 'Quick Reply', - href: 'javascript:;' - }); - $.on(sc, 'click', function() { - if (!QR.postingIsEnabled) { - return; - } - if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) { - QR.open(); - return QR.nodes.com.focus(); - } else { - return QR.close(); - } - }); - return Header.addShortcut('qr', sc, 540); - }, - initReady: function() { - var captchaVersion, config, link, linkBot, navLinksBot, origToggle, prop; - captchaVersion = $('#g-recaptcha, #captcha-forced-noscript') ? 'v2' : 't'; - QR.captcha = Captcha[captchaVersion]; - QR.postingIsEnabled = true; - config = g.BOARD.config; - prop = function(key, def) { - var ref; - return +((ref = config[key]) != null ? ref : def); - }; - QR.min_width = prop('min_image_width', 1); - QR.min_height = prop('min_image_height', 1); - QR.max_width = QR.max_height = 10000; - QR.max_size = prop('max_filesize', 4194304); - QR.max_size_video = prop('max_webm_filesize', QR.max_size); - QR.max_comment = prop('max_comment_chars', 2000); - QR.max_width_video = QR.max_height_video = 2048; - QR.max_duration_video = prop('max_webm_duration', 120); - QR.forcedAnon = !!config.forced_anon; - QR.spoiler = !!config.spoilers; - if ((origToggle = $.id('togglePostFormLink'))) { - link = $.el('h1', { - className: "qr-link-container" - }); - $.extend(link, {innerHTML: "" + ((g.VIEW === "thread") ? "Reply to Thread" : "Start a Thread") + ""}); - QR.link = link.firstElementChild; - $.on(link.firstChild, 'click', function() { - QR.open(); - return QR.nodes.com.focus(); - }); - $.before(origToggle, link); - origToggle.firstElementChild.textContent = 'Original Form'; - } - if (g.VIEW === 'thread') { - linkBot = $.el('div', { - className: "brackets-wrap qr-link-container-bottom" - }); - $.extend(linkBot, {innerHTML: "Reply to Thread"}); - $.on(linkBot.firstElementChild, 'click', function() { - QR.open(); - return QR.nodes.com.focus(); - }); - if ((navLinksBot = $('.navLinksBot'))) { - $.prepend(navLinksBot, linkBot); - } - } - $.on(d, 'QRGetFile', QR.getFile); - $.on(d, 'QRDrawFile', QR.drawFile); - $.on(d, 'QRSetFile', QR.setFile); - $.on(d, 'paste', QR.paste); - $.on(d, 'dragover', QR.dragOver); - $.on(d, 'drop', QR.dropFile); - $.on(d, 'dragstart dragend', QR.drag); - $.on(d, 'IndexRefreshInternal', QR.generatePostableThreadsList); - $.on(d, 'ThreadUpdate', QR.statusCheck); - if (!Conf['Persistent QR']) { - return; - } - QR.open(); - if (Conf['Auto Hide QR']) { - return QR.hide(); - } - }, - statusCheck: function() { - var thread; - if (!QR.nodes) { - return; - } - thread = QR.posts[0].thread; - if (thread !== 'new' && g.threads.get(g.BOARD + "." + thread).isDead) { - return QR.abort(); - } else { - return QR.status(); - } - }, - node: function() { - $.on(this.nodes.quote, 'click', QR.quote); - if (this.isFetchedQuote) { - return QR.generatePostableThreadsList(); - } - }, - open: function() { - var err; - if (QR.nodes) { - if (QR.nodes.el.hidden) { - QR.captcha.setup(); - } - QR.nodes.el.hidden = false; - QR.unhide(); - } else { - try { - QR.dialog(); - } catch (error) { - err = error; - delete QR.nodes; - Main.handleErrors({ - message: 'Quick Reply dialog creation crashed.', - error: err - }); - return; - } - } - return $.rmClass(QR.shortcut, 'disabled'); - }, - close: function() { - var j, len, post, ref; - if (QR.req) { - QR.abort(); - return; - } - QR.nodes.el.hidden = true; - QR.cleanNotifications(); - QR.blur(); - $.rmClass(QR.nodes.el, 'dump'); - $.addClass(QR.shortcut, 'disabled'); - new QR.post(true); - ref = QR.posts.splice(0, QR.posts.length - 1); - for (j = 0, len = ref.length; j < len; j++) { - post = ref[j]; - post["delete"](); - } - QR.cooldown.auto = false; - QR.status(); - return QR.captcha.destroy(); - }, - focus: function() { - return $.queueTask(function() { - if (!QR.inBubble()) { - QR.hasFocus = d.activeElement && QR.nodes.el.contains(d.activeElement); - return QR.nodes.el.classList.toggle('focus', QR.hasFocus); - } - }); - }, - inBubble: function() { - var bubbles, ref; - bubbles = $$('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); - return (ref = d.activeElement, indexOf.call(bubbles, ref) >= 0) || bubbles.some(function(el) { - return getComputedStyle(el).visibility !== 'hidden' && el.getBoundingClientRect().bottom > 0; - }); - }, - hide: function() { - QR.blur(); - $.addClass(QR.nodes.el, 'autohide'); - return QR.nodes.autohide.checked = true; - }, - unhide: function() { - $.rmClass(QR.nodes.el, 'autohide'); - return QR.nodes.autohide.checked = false; - }, - toggleHide: function() { - if (this.checked) { - return QR.hide(); - } else { - return QR.unhide(); - } - }, - blur: function() { - if (QR.nodes.el.contains(d.activeElement)) { - return d.activeElement.blur(); - } - }, - toggleSJIS: function(e) { - e.preventDefault(); - Conf['sjisPreview'] = !Conf['sjisPreview']; - $.set('sjisPreview', Conf['sjisPreview']); - return QR.nodes.el.classList.toggle('sjis-preview', Conf['sjisPreview']); - }, - texPreviewShow: function() { - if ($.hasClass(QR.nodes.el, 'tex-preview')) { - return QR.texPreviewHide(); - } - $.addClass(QR.nodes.el, 'tex-preview'); - QR.nodes.texPreview.textContent = QR.nodes.com.value; - return $.event('mathjax', null, QR.nodes.texPreview); - }, - texPreviewHide: function() { - return $.rmClass(QR.nodes.el, 'tex-preview'); - }, - addPost: function() { - var wasOpen; - wasOpen = QR.nodes && !QR.nodes.el.hidden; - QR.open(); - if (wasOpen) { - $.addClass(QR.nodes.el, 'dump'); - new QR.post(true); - } - return QR.nodes.com.focus(); - }, - setCustomCooldown: function(enabled) { - Conf['customCooldownEnabled'] = enabled; - QR.cooldown.customCooldown = enabled; - return QR.nodes.customCooldown.classList.toggle('disabled', !enabled); - }, - toggleCustomCooldown: function() { - var enabled; - enabled = $.hasClass(QR.nodes.customCooldown, 'disabled'); - QR.setCustomCooldown(enabled); - return $.set('customCooldownEnabled', enabled); - }, - error: function(err, focusOverride) { - var el, notice, notif; - QR.open(); - if (typeof err === 'string') { - el = $.tn(err); - } else { - el = err; - el.removeAttribute('style'); - } - notice = new Notice('warning', el); - QR.notifications.push(notice); - if (!Header.areNotificationsEnabled) { - if (d.hidden && !QR.cooldown.auto) { - return alert(el.textContent); - } - } else if (d.hidden || !(focusOverride || d.hasFocus())) { - notif = new Notification(el.textContent, { - body: el.textContent, - icon: Favicon.logo - }); - notif.onclick = function() { - return window.focus(); - }; - if ($.engine !== 'gecko') { - notif.onclose = function() { - return notice.close(); - }; - return notif.onshow = function() { - return setTimeout(function() { - notif.onclose = null; - return notif.close(); - }, 7 * $.SECOND); - }; - } - } - }, - connectionError: function() { - return $.el('span', {innerHTML: "Connection error while posting. [More info]"}); - }, - notifications: [], - cleanNotifications: function() { - var j, len, notification, ref; - ref = QR.notifications; - for (j = 0, len = ref.length; j < len; j++) { - notification = ref[j]; - notification.close(); - } - return QR.notifications = []; - }, - status: function() { - var disabled, status, thread, value; - if (!QR.nodes) { - return; - } - thread = QR.posts[0].thread; - if (thread !== 'new' && g.threads.get(g.BOARD + "." + thread).isDead) { - value = 'Dead'; - disabled = true; - QR.cooldown.auto = false; - } - value = QR.req ? QR.req.progress : QR.cooldown.seconds || value; - status = QR.nodes.status; - status.value = !value ? 'Submit' : QR.cooldown.auto ? "Auto " + value : value; - return status.disabled = disabled || false; - }, - openPost: function() { - var index; - QR.open(); - if (QR.selected.isLocked) { - index = QR.posts.indexOf(QR.selected); - (QR.posts[index + 1] || new QR.post()).select(); - $.addClass(QR.nodes.el, 'dump'); - return QR.cooldown.auto = true; - } - }, - quote: function(e) { - var ancestor, base, caretPos, com, frag, i, insideCode, j, k, l, len, len1, len2, len3, n, node, o, post, postRange, range, ref, ref1, ref2, ref3, ref4, ref5, ref6, root, sel, text, thread, wasOnlyQuotes; - if (e != null) { - e.preventDefault(); - } - if (!QR.postingIsEnabled) { - return; - } - sel = d.getSelection(); - post = Get.postFromNode(this); - root = post.nodes.root; - postRange = new Range(); - postRange.selectNode(root); - text = post.board.ID === g.BOARD.ID ? ">>" + post + "\n" : ">>>/" + post.board + "/" + post + "\n"; - for (i = j = 0, ref = sel.rangeCount; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) { - try { - range = sel.getRangeAt(i); - if (range.compareBoundaryPoints(Range.START_TO_START, postRange) < 0) { - range.setStartBefore(root); - } - if (range.compareBoundaryPoints(Range.END_TO_END, postRange) > 0) { - range.setEndAfter(root); - } - if (!range.toString().trim()) { - continue; - } - frag = range.cloneContents(); - ancestor = range.commonAncestorContainer; - if ($.x('ancestor-or-self::*[self::s or contains(@class,"removed-spoiler")]', ancestor)) { - $.prepend(frag, $.tn('[spoiler]')); - $.add(frag, $.tn('[/spoiler]')); - } - if (insideCode = $.x('ancestor-or-self::pre[contains(@class,"prettyprint")]', ancestor)) { - $.prepend(frag, $.tn('[code]')); - $.add(frag, $.tn('[/code]')); - } - ref1 = $$((insideCode ? 'br' : '.prettyprint br'), frag); - for (k = 0, len = ref1.length; k < len; k++) { - node = ref1[k]; - $.replace(node, $.tn('\n')); - } - ref2 = $$('br', frag); - for (l = 0, len1 = ref2.length; l < len1; l++) { - node = ref2[l]; - if (node !== frag.lastChild) { - $.replace(node, $.tn('\n>')); - } - } - if (typeof (base = g.SITE).insertTags === "function") { - base.insertTags(frag); - } - ref3 = $$('.linkify[data-original]', frag); - for (n = 0, len2 = ref3.length; n < len2; n++) { - node = ref3[n]; - $.replace(node, $.tn(node.dataset.original)); - } - ref4 = $$('.embedder', frag); - for (o = 0, len3 = ref4.length; o < len3; o++) { - node = ref4[o]; - if (((ref5 = node.previousSibling) != null ? ref5.nodeValue : void 0) === ' ') { - $.rm(node.previousSibling); - } - $.rm(node); - } - text += ">" + (frag.textContent.trim()) + "\n"; - } catch (error) {} - } - QR.openPost(); - ref6 = QR.nodes, com = ref6.com, thread = ref6.thread; - if (!com.value) { - thread.value = Get.threadFromNode(this); - } - wasOnlyQuotes = QR.selected.isOnlyQuotes(); - caretPos = com.selectionStart; - com.value = com.value.slice(0, caretPos) + text + com.value.slice(com.selectionEnd); - range = caretPos + text.length; - com.setSelectionRange(range, range); - com.focus(); - if (wasOnlyQuotes) { - QR.selected.quotedText = com.value; - } - QR.selected.save(com); - return QR.selected.save(thread); - }, - characterCount: function() { - var count, counter; - counter = QR.nodes.charCount; - count = QR.nodes.com.value.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '_').length; - counter.textContent = count; - counter.hidden = count < QR.max_comment / 2; - return (count > QR.max_comment ? $.addClass : $.rmClass)(counter, 'warning'); - }, - getFile: function() { - var ref; - return $.event('QRFile', (ref = QR.selected) != null ? ref.file : void 0); - }, - drawFile: function(e) { - var el, file, isVideo, ref; - file = (ref = QR.selected) != null ? ref.file : void 0; - if (!(file && /^(image|video)\//.test(file.type))) { - return; - } - isVideo = /^video\//.test(file); - el = $.el((isVideo ? 'video' : 'img')); - $.on(el, 'error', function() { - return QR.openError(); - }); - $.on(el, (isVideo ? 'loadeddata' : 'load'), function() { - e.target.getContext('2d').drawImage(el, 0, 0); - URL.revokeObjectURL(el.src); - return $.event('QRImageDrawn', null, e.target); - }); - return el.src = URL.createObjectURL(file); - }, - openError: function() { - var div; - div = $.el('div'); - $.extend(div, {innerHTML: "Could not open file. [More info]"}); - return QR.error(div); - }, - setFile: function(e) { - var file, name, ref, source; - ref = e.detail, file = ref.file, name = ref.name, source = ref.source; - if (name != null) { - file.name = name; - } - if (source != null) { - file.source = source; - } - QR.open(); - return QR.handleFiles([file]); - }, - drag: function(e) { - var toggle; - toggle = e.type === 'dragstart' ? $.off : $.on; - toggle(d, 'dragover', QR.dragOver); - return toggle(d, 'drop', QR.dropFile); - }, - dragOver: function(e) { - e.preventDefault(); - return e.dataTransfer.dropEffect = 'copy'; - }, - dropFile: function(e) { - if (!e.dataTransfer.files.length) { - return; - } - e.preventDefault(); - QR.open(); - return QR.handleFiles(e.dataTransfer.files); - }, - paste: function(e) { - var blob, file, file2, item, j, len, ref, score, score2, type; - if (!e.clipboardData.items) { - return; - } - file = null; - score = -1; - ref = e.clipboardData.items; - for (j = 0, len = ref.length; j < len; j++) { - item = ref[j]; - if (!(item.kind === 'file' && (file2 = item.getAsFile()))) { - continue; - } - score2 = 2 * (file2.size <= QR.max_size) + (file2.type === 'image/png'); - if (score2 > score) { - file = file2; - score = score2; - } - } - if (file) { - type = file.type; - blob = new Blob([file], { - type: type - }); - blob.name = Conf['pastedname'] + "." + ($.getOwn(QR.extensionFromType, type) || 'jpg'); - QR.open(); - QR.handleFiles([blob]); - $.addClass(QR.nodes.el, 'dump'); - } - }, - pasteFF: function() { - var arr, blob, bstr, i, images, img, j, k, len, m, pasteArea, ref, src; - pasteArea = QR.nodes.pasteArea; - if (!pasteArea.childNodes.length) { - return; - } - images = $$('img', pasteArea); - $.rmAll(pasteArea); - for (j = 0, len = images.length; j < len; j++) { - img = images[j]; - src = img.src; - if (m = src.match(/data:(image\/(\w+));base64,(.+)/)) { - bstr = atob(m[3]); - arr = new Uint8Array(bstr.length); - for (i = k = 0, ref = bstr.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) { - arr[i] = bstr.charCodeAt(i); - } - blob = new Blob([arr], { - type: m[1] - }); - blob.name = Conf['pastedname'] + "." + m[2]; - QR.handleFiles([blob]); - } else if (/^https?:\/\//.test(src)) { - QR.handleUrl(src); - } - } - }, - handleUrl: function(urlDefault) { - QR.open(); - QR.selected.preventAutoPost(); - return CrossOrigin.permission(function() { - var url; - url = prompt('Enter a URL:', urlDefault); - if (url === null) { - return; - } - QR.nodes.fileButton.focus(); - return CrossOrigin.file(url, function(blob) { - if (blob && !/^text\//.test(blob.type)) { - return QR.handleFiles([blob]); - } else { - return QR.error("Can't load file."); - } - }); - }); - }, - handleFiles: function(files) { - var file, j, len; - if (this !== QR) { - files = slice.call(this.files); - this.value = null; - } - if (!files.length) { - return; - } - QR.cleanNotifications(); - for (j = 0, len = files.length; j < len; j++) { - file = files[j]; - QR.handleFile(file, files.length); - } - if (files.length !== 1) { - $.addClass(QR.nodes.el, 'dump'); - } - if (d.activeElement === QR.nodes.fileButton && $.hasClass(QR.nodes.fileSubmit, 'has-file')) { - return QR.nodes.filename.focus(); - } - }, - handleFile: function(file, nfiles) { - var isText, post; - isText = /^text\//.test(file.type); - if (nfiles === 1) { - post = QR.selected; - } else { - post = QR.posts[QR.posts.length - 1]; - if ((isText ? post.com || post.pasting : post.file)) { - post = new QR.post(); - } - } - return post[isText ? 'pasteText' : 'setFile'](file); - }, - openFileInput: function() { - if (QR.nodes.fileButton.disabled) { - return; - } - QR.nodes.fileInput.click(); - return QR.nodes.fileButton.focus(); - }, - generatePostableThreadsList: function() { - var j, len, list, options, ref, thread, val; - if (!QR.nodes) { - return; - } - list = QR.nodes.thread; - options = [list.firstElementChild]; - ref = g.BOARD.threads.keys; - for (j = 0, len = ref.length; j < len; j++) { - thread = ref[j]; - options.push($.el('option', { - value: thread, - textContent: "Thread " + thread - })); - } - val = list.value; - $.rmAll(list); - $.add(list, options); - list.value = val; - if (list.value === val) { - return; - } - list.value = g.VIEW === 'thread' ? g.THREADID : 'new'; - return (g.VIEW === 'thread' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread'); - }, - dialog: function() { - var classList, config, dialog, event, i, items, name, node, nodes, save, setNode; - QR.nodes = nodes = { - el: dialog = UI.dialog('qr', {innerHTML: "
    ×
    No selected file
    "}) - }; - setNode = function(name, query) { - return nodes[name] = $(query, dialog); - }; - setNode('move', '.move'); - setNode('autohide', '#autohide'); - setNode('close', '.close'); - setNode('thread', 'select'); - setNode('form', 'form'); - setNode('sjisToggle', '#sjis-toggle'); - setNode('texButton', '#tex-preview-button'); - setNode('name', '[data-name=name]'); - setNode('email', '[data-name=email]'); - setNode('sub', '[data-name=sub]'); - setNode('com', '[data-name=com]'); - setNode('charCount', '#char-count'); - setNode('texPreview', '#tex-preview'); - setNode('dumpList', '#dump-list'); - setNode('addPost', '#add-post'); - setNode('oekaki', '.oekaki'); - setNode('drawButton', '#qr-draw-button'); - setNode('fileSubmit', '#file-n-submit'); - setNode('fileButton', '#qr-file-button'); - setNode('noFile', '#qr-no-file'); - setNode('filename', '#qr-filename'); - setNode('spoiler', '#qr-file-spoiler'); - setNode('oekakiButton', '#qr-oekaki-button'); - setNode('fileRM', '#qr-filerm'); - setNode('urlButton', '#url-button'); - setNode('pasteArea', '#paste-area'); - setNode('customCooldown', '#custom-cooldown-button'); - setNode('dumpButton', '#dump-button'); - setNode('status', '[type=submit]'); - setNode('flashTag', '[name=filetag]'); - setNode('fileInput', '[type=file]'); - config = g.BOARD.config; - classList = QR.nodes.el.classList; - classList.toggle('forced-anon', QR.forcedAnon); - classList.toggle('has-spoiler', QR.spoiler); - classList.toggle('has-sjis', !!config.sjis_tags); - classList.toggle('has-math', !!config.math_tags); - classList.toggle('sjis-preview', !!config.sjis_tags && Conf['sjisPreview']); - classList.toggle('show-new-thread-option', Conf['Show New Thread Option in Threads']); - if (parseInt(Conf['customCooldown'], 10) > 0) { - $.addClass(QR.nodes.fileSubmit, 'custom-cooldown'); - $.get('customCooldownEnabled', Conf['customCooldownEnabled'], function(arg) { - var customCooldownEnabled; - customCooldownEnabled = arg.customCooldownEnabled; - QR.setCustomCooldown(customCooldownEnabled); - return $.sync('customCooldownEnabled', QR.setCustomCooldown); - }); - } - QR.flagsInput(); - $.on(nodes.autohide, 'change', QR.toggleHide); - $.on(nodes.close, 'click', QR.close); - $.on(nodes.status, 'click', QR.submit); - $.on(nodes.form, 'submit', QR.submit); - $.on(nodes.sjisToggle, 'click', QR.toggleSJIS); - $.on(nodes.texButton, 'mousedown', QR.texPreviewShow); - $.on(nodes.texButton, 'mouseup', QR.texPreviewHide); - $.on(nodes.addPost, 'click', function() { - return new QR.post(true); - }); - $.on(nodes.drawButton, 'click', QR.oekaki.draw); - $.on(nodes.fileButton, 'click', QR.openFileInput); - $.on(nodes.noFile, 'click', QR.openFileInput); - $.on(nodes.filename, 'focus', function() { - return $.addClass(this.parentNode, 'focus'); - }); - $.on(nodes.filename, 'blur', function() { - return $.rmClass(this.parentNode, 'focus'); - }); - $.on(nodes.spoiler, 'change', function() { - return QR.selected.nodes.spoiler.click(); - }); - $.on(nodes.oekakiButton, 'click', QR.oekaki.button); - $.on(nodes.fileRM, 'click', function() { - return QR.selected.rmFile(); - }); - $.on(nodes.urlButton, 'click', function() { - return QR.handleUrl(''); - }); - $.on(nodes.customCooldown, 'click', QR.toggleCustomCooldown); - $.on(nodes.dumpButton, 'click', function() { - return nodes.el.classList.toggle('dump'); - }); - $.on(nodes.fileInput, 'change', QR.handleFiles); - window.addEventListener('focus', QR.focus, true); - window.addEventListener('blur', QR.focus, true); - $.on(d, 'click', QR.focus); - if ($.engine === 'gecko' && !window.DataTransferItemList) { - nodes.pasteArea.hidden = false; - } - new MutationObserver(QR.pasteFF).observe(nodes.pasteArea, { - childList: true - }); - items = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag']; - i = 0; - save = function() { - return QR.selected.save(this); - }; - while (name = items[i++]) { - if (!(node = nodes[name])) { - continue; - } - event = node.nodeName === 'SELECT' ? 'change' : 'input'; - $.on(nodes[name], event, save); - } - if ($.engine === 'gecko' && Conf['Remember QR Size']) { - $.get('QR Size', '', function(item) { - return nodes.com.style.cssText = item['QR Size']; - }); - $.on(nodes.com, 'mouseup', function(e) { - if (e.button !== 0) { - return; - } - return $.set('QR Size', this.style.cssText); - }); - } - QR.generatePostableThreadsList(); - QR.persona.load(); - new QR.post(true); - QR.status(); - QR.cooldown.setup(); - QR.captcha.init(); - $.add(d.body, dialog); - QR.captcha.setup(); - QR.oekaki.setup(); - return $.event('QRDialogCreation', null, dialog); - }, - flags: function() { - var addFlag, ref, select, textContent, value; - select = $.el('select', { - name: 'flag', - className: 'flagSelector' - }); - addFlag = function(value, textContent) { - return $.add(select, $.el('option', { - value: value, - textContent: textContent - })); - }; - addFlag('0', (g.BOARD.config.country_flags ? 'Geographic Location' : 'None')); - ref = g.BOARD.config.board_flags; - for (value in ref) { - textContent = ref[value]; - addFlag(value, textContent); - } - return select; - }, - flagsInput: function() { - var flag, nodes; - nodes = QR.nodes; - if (!nodes) { - return; - } - if (nodes.flag) { - $.rm(nodes.flag); - delete nodes.flag; - } - if (g.BOARD.config.board_flags) { - flag = QR.flags(); - flag.dataset.name = 'flag'; - flag.dataset["default"] = '0'; - nodes.flag = flag; - return $.add(nodes.form, flag); - } - }, - submit: function(e) { - var captcha, cb, err, filetag, force, formData, options, post, ref, thread, threadID; - if (e != null) { - e.preventDefault(); - } - force = e != null ? e.shiftKey : void 0; - if (QR.req) { - QR.abort(); - return; - } - $.forceSync('cooldowns'); - if (QR.cooldown.seconds) { - if (force) { - QR.cooldown.clear(); - } else { - QR.cooldown.auto = !QR.cooldown.auto; - QR.status(); - return; - } - } - post = QR.posts[0]; - delete post.quotedText; - post.forceSave(); - threadID = post.thread; - thread = g.BOARD.threads.get(threadID); - if (g.BOARD.ID === 'f' && threadID === 'new') { - filetag = QR.nodes.flashTag.value; - } - if (threadID === 'new') { - threadID = null; - if (!!g.BOARD.config.require_subject && !post.sub) { - err = 'New threads require a subject.'; - } else if (!(!!g.BOARD.config.text_only || post.file)) { - err = 'No file selected.'; - } - } else if (g.BOARD.threads.get(threadID).isClosed) { - err = 'You can\'t reply to this thread anymore.'; - } else if (!(post.com || post.file)) { - err = 'No comment or file.'; - } else if (post.file && thread.fileLimit) { - err = 'Max limit of image replies has been reached.'; - } - if (g.BOARD.ID === 'r9k' && !((ref = post.com) != null ? ref.match(/[a-z-]/i) : void 0)) { - err || (err = 'Original comment required.'); - } - if (QR.captcha.isEnabled && !(QR.captcha === Captcha.v2 && /\b_ct=/.test(d.cookie) && threadID) && !(err && !force)) { - captcha = QR.captcha.getOne(!!threadID); - if (QR.captcha === Captcha.v2) { - captcha || (captcha = Captcha.cache.request(!!threadID)); - } - if (!captcha) { - err = 'No valid captcha.'; - QR.captcha.setup(!QR.cooldown.auto || d.activeElement === QR.nodes.status); - } - } - QR.cleanNotifications(); - if (err && !force) { - QR.cooldown.auto = false; - QR.status(); - QR.error(err); - return; - } - QR.cooldown.auto = QR.posts.length > 1; - post.lock(); - formData = { - MAX_FILE_SIZE: QR.max_size, - mode: 'regist', - pwd: QR.persona.getPassword(), - resto: threadID, - name: !QR.forcedAnon ? post.name : void 0, - email: post.email, - sub: !(QR.forcedAnon || threadID) ? post.sub : void 0, - com: post.com, - upfile: post.file, - filetag: filetag, - spoiler: post.spoiler, - flag: post.flag - }; - options = { - responseType: 'document', - withCredentials: true, - onloadend: QR.response, - form: $.formData(formData) - }; - if (Conf['Show Upload Progress']) { - options.onprogress = function(e) { - var ref1; - if (this !== ((ref1 = QR.req) != null ? ref1.upload : void 0)) { - return; - } - if (e.loaded < e.total) { - QR.req.progress = (Math.round(e.loaded / e.total * 100)) + "%"; - } else { - QR.req.isUploadFinished = true; - QR.req.progress = '...'; - } - return QR.status(); - }; - } - cb = function(response) { - var key, val; - if (response != null) { - QR.currentCaptcha = response; - if (QR.captcha === Captcha.v2) { - if (response.challenge != null) { - options.form.append('recaptcha_challenge_field', response.challenge); - options.form.append('recaptcha_response_field', response.response); - } else { - options.form.append('g-recaptcha-response', response.response); - } - } else { - for (key in response) { - val = response[key]; - options.form.append(key, val); - } - } - } - QR.req = $.ajax("https://sys." + (location.hostname.split('.')[1]) + ".org/" + g.BOARD + "/post", options); - return QR.req.progress = '...'; - }; - if (typeof captcha === 'function') { - QR.req = { - progress: '...', - abort: function() { - if (QR.captcha === Captcha.v2) { - Captcha.cache.abort(); - } - return cb = null; - } - }; - captcha(function(response) { - if (QR.captcha === Captcha.v2 && Captcha.cache.haveCookie()) { - if (typeof cb === "function") { - cb(); - } - if (response) { - return Captcha.cache.save(response); - } - } else if (response) { - return typeof cb === "function" ? cb(response) : void 0; - } else { - delete QR.req; - post.unlock(); - QR.cooldown.auto = !!Captcha.cache.getCount(); - return QR.status(); - } - }); - } else { - cb(captcha); - } - return QR.status(); - }, - response: function() { - var URL, _, base, connErr, err, h1, isReply, j, lastPostToThread, len, m, mi, open, post, postID, postsCount, ref, ref1, ref2, ref3, seconds, threadID; - if (this !== QR.req) { - return; - } - delete QR.req; - post = QR.posts[0]; - post.unlock(); - if ((err = (ref = this.response) != null ? ref.getElementById('errmsg') : void 0)) { - if ((ref1 = $('a', err)) != null) { - ref1.target = '_blank'; - } - } else if ((connErr = !this.response || this.response.title !== 'Post successful!')) { - err = QR.connectionError(); - if (QR.captcha === Captcha.v2 && QR.currentCaptcha) { - Captcha.cache.save(QR.currentCaptcha); - } - } else if (this.status !== 200) { - err = "Error " + this.statusText + " (" + this.status + ")"; - } - if (!connErr) { - if (typeof (base = QR.captcha).setUsed === "function") { - base.setUsed(); - } - } - delete QR.currentCaptcha; - if (err) { - QR.errorCount = (QR.errorCount || 0) + 1; - if (/captcha|verification/i.test(err.textContent) || connErr) { - if (/mistyped/i.test(err.textContent)) { - err = 'You mistyped the CAPTCHA, or the CAPTCHA malfunctioned.'; - } else if (/expired/i.test(err.textContent)) { - err = 'This CAPTCHA is no longer valid because it has expired.'; - } - if (QR.errorCount >= 5) { - QR.cooldown.auto = false; - } else { - QR.cooldown.auto = QR.captcha.isEnabled || connErr; - QR.cooldown.addDelay(post, 2); - } - } else if (err.textContent && (m = err.textContent.match(/\d+\s+(?:minute|second)/gi)) && !/duplicate|hour/i.test(err.textContent)) { - QR.cooldown.auto = !/have\s+been\s+muted/i.test(err.textContent); - seconds = 0; - for (j = 0, len = m.length; j < len; j++) { - mi = m[j]; - seconds += (/minute/i.test(mi) ? 60 : 1) * (+mi.match(/\d+/)[0]); - } - if (/muted/i.test(err.textContent)) { - QR.cooldown.addMute(seconds); - } else { - QR.cooldown.addDelay(post, seconds); - } - } else { - QR.cooldown.auto = false; - } - QR.captcha.setup(QR.cooldown.auto && ((ref2 = d.activeElement) === QR.nodes.status || ref2 === d.body)); - QR.status(); - QR.error(err); - return; - } - delete QR.errorCount; - h1 = $('h1', this.response); - ref3 = h1.nextSibling.textContent.match(/thread:(\d+),no:(\d+)/), _ = ref3[0], threadID = ref3[1], postID = ref3[2]; - postID = +postID; - threadID = +threadID || postID; - isReply = threadID !== postID; - $.event('QRPostSuccessful', { - boardID: g.BOARD.ID, - threadID: threadID, - postID: postID - }); - $.event('QRPostSuccessful_', { - boardID: g.BOARD.ID, - threadID: threadID, - postID: postID - }); - postsCount = QR.posts.length - 1; - QR.cooldown.auto = postsCount && isReply; - lastPostToThread = !((function() { - var k, len1, p, ref4; - ref4 = QR.posts.slice(1); - for (k = 0, len1 = ref4.length; k < len1; k++) { - p = ref4[k]; - if (p.thread === post.thread) { - return true; - } - } - })()); - if (postsCount) { - post.rm(); - QR.captcha.setup(d.activeElement === QR.nodes.status); - } else if (Conf['Persistent QR']) { - post.rm(); - if (Conf['Auto Hide QR']) { - QR.hide(); - } else { - QR.blur(); - } - } else { - QR.close(); - } - QR.cleanNotifications(); - if (Conf['Posting Success Notifications']) { - QR.notifications.push(new Notice('success', h1.textContent, 5)); - } - QR.cooldown.add(threadID, postID); - URL = threadID === postID ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID : threadID !== g.THREADID && lastPostToThread && Conf['Open Post in New Tab'] ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID + "#p" + postID : void 0; - if (URL) { - open = Conf['Open Post in New Tab'] || postsCount ? function() { - return $.open(URL); - } : function() { - return location.href = URL; - }; - if (threadID === postID) { - QR.waitForThread(URL, open); - } else { - open(); - } - } - return QR.status(); - }, - waitForThread: function(url, cb) { - var attempts, check; - attempts = 0; - check = function() { - return $.ajax(url, { - onloadend: function() { - attempts++; - if (attempts >= 6 || this.status === 200) { - return cb(); - } else { - return setTimeout(check, attempts * $.SECOND); - } - }, - responseType: 'text', - type: 'HEAD' - }); - }; - return check(); - }, - abort: function() { - var oldReq; - if ((oldReq = QR.req) && !QR.req.isUploadFinished) { - delete QR.req; - oldReq.abort(); - if (QR.captcha === Captcha.v2 && QR.currentCaptcha) { - Captcha.cache.save(QR.currentCaptcha); - } - delete QR.currentCaptcha; - QR.posts[0].unlock(); - QR.cooldown.auto = false; - QR.notifications.push(new Notice('info', 'QR upload aborted.', 5)); - } - return QR.status(); - } - }; - - return QR; - -}).call(this); - -(function() { - QR.cooldown = { - seconds: 0, - delays: { - deletion: 60 - }, - init: function() { - if (!Conf['Quick Reply']) { - return; - } - this.data = Conf['cooldowns']; - this.changes = $.dict(); - return $.sync('cooldowns', this.sync); - }, - setup: function() { - var delay, ref, type; - $.extend(QR.cooldown.delays, g.BOARD.cooldowns()); - QR.cooldown.maxDelay = 0; - ref = QR.cooldown.delays; - for (type in ref) { - delay = ref[type]; - if (type !== 'thread' && type !== 'thread_global') { - QR.cooldown.maxDelay = Math.max(QR.cooldown.maxDelay, delay); - } - } - QR.cooldown.isSetup = true; - return QR.cooldown.start(); - }, - start: function() { - var data; - data = QR.cooldown.data; - if (!(Conf['Cooldown'] && QR.cooldown.isSetup && !QR.cooldown.isCounting && Object.keys(data[g.BOARD.ID] || {}).length + Object.keys(data.global || {}).length > 0)) { - return; - } - QR.cooldown.isCounting = true; - return QR.cooldown.count(); - }, - sync: function(data) { - QR.cooldown.data = data || $.dict(); - return QR.cooldown.start(); - }, - add: function(threadID, postID) { - var boardID, start; - if (!Conf['Cooldown']) { - return; - } - start = Date.now(); - boardID = g.BOARD.ID; - QR.cooldown.set(boardID, start, { - threadID: threadID, - postID: postID - }); - if (threadID === postID) { - QR.cooldown.set('global', start, { - boardID: boardID, - threadID: threadID, - postID: postID - }); - } - QR.cooldown.save(); - return QR.cooldown.start(); - }, - addDelay: function(post, delay) { - var cooldown; - if (!Conf['Cooldown']) { - return; - } - cooldown = QR.cooldown.categorize(post); - cooldown.delay = delay; - QR.cooldown.set(g.BOARD.ID, Date.now(), cooldown); - QR.cooldown.save(); - return QR.cooldown.start(); - }, - addMute: function(delay) { - if (!Conf['Cooldown']) { - return; - } - QR.cooldown.set(g.BOARD.ID, Date.now(), { - type: 'mute', - delay: delay - }); - QR.cooldown.save(); - return QR.cooldown.start(); - }, - "delete": function(post) { - var base, cooldown, cooldowns, id, name; - if (!QR.cooldown.data) { - return; - } - cooldowns = ((base = QR.cooldown.data)[name = post.board.ID] || (base[name] = $.dict())); - for (id in cooldowns) { - cooldown = cooldowns[id]; - if ((cooldown.delay == null) && cooldown.threadID === post.thread.ID && cooldown.postID === post.ID) { - QR.cooldown.set(post.board.ID, id, null); - } - } - return QR.cooldown.save(); - }, - secondsDeletion: function(post) { - var cooldown, cooldowns, seconds, start; - if (!(QR.cooldown.data && Conf['Cooldown'])) { - return 0; - } - cooldowns = QR.cooldown.data[post.board.ID] || $.dict(); - for (start in cooldowns) { - cooldown = cooldowns[start]; - if ((cooldown.delay == null) && cooldown.threadID === post.thread.ID && cooldown.postID === post.ID) { - seconds = QR.cooldown.delays.deletion - Math.floor((Date.now() - start) / $.SECOND); - return Math.max(seconds, 0); - } - } - return 0; - }, - categorize: function(post) { - if (post.thread === 'new') { - return { - type: 'thread' - }; - } else { - return { - type: !!post.file ? 'image' : 'reply', - threadID: +post.thread - }; - } - }, - mergeChange: function(data, scope, id, value) { - if (value) { - return (data[scope] || (data[scope] = $.dict()))[id] = value; - } else if (scope in data) { - delete data[scope][id]; - if (Object.keys(data[scope]).length === 0) { - return delete data[scope]; - } - } - }, - set: function(scope, id, value) { - var base; - QR.cooldown.mergeChange(QR.cooldown.data, scope, id, value); - return ((base = QR.cooldown.changes)[scope] || (base[scope] = $.dict()))[id] = value; - }, - save: function() { - var changes; - changes = QR.cooldown.changes; - if (!Object.keys(changes).length) { - return; - } - return $.get('cooldowns', $.dict(), function(arg) { - var cooldowns, id, ref, scope, value; - cooldowns = arg.cooldowns; - for (scope in QR.cooldown.changes) { - ref = QR.cooldown.changes[scope]; - for (id in ref) { - value = ref[id]; - QR.cooldown.mergeChange(cooldowns, scope, id, value); - } - QR.cooldown.data = cooldowns; - } - return $.set('cooldowns', cooldowns, function() { - return QR.cooldown.changes = $.dict(); - }); - }); - }, - clear: function() { - QR.cooldown.data = $.dict(); - QR.cooldown.changes = $.dict(); - QR.cooldown.auto = false; - QR.cooldown.update(); - return $.queueTask($["delete"], 'cooldowns'); - }, - update: function() { - var base, cooldown, cooldowns, elapsed, i, len, maxDelay, nCooldowns, now, ref, ref1, save, scope, seconds, start, suffix, threadID, type, update; - if (!QR.cooldown.isCounting) { - return; - } - save = false; - nCooldowns = 0; - now = Date.now(); - ref = QR.cooldown.categorize(QR.posts[0]), type = ref.type, threadID = ref.threadID; - seconds = 0; - if (Conf['Cooldown']) { - ref1 = [g.BOARD.ID, 'global']; - for (i = 0, len = ref1.length; i < len; i++) { - scope = ref1[i]; - cooldowns = ((base = QR.cooldown.data)[scope] || (base[scope] = $.dict())); - for (start in cooldowns) { - cooldown = cooldowns[start]; - start = +start; - elapsed = Math.floor((now - start) / $.SECOND); - if (elapsed < 0) { - QR.cooldown.set(scope, start, null); - save = true; - continue; - } - if (cooldown.delay != null) { - if (cooldown.delay <= elapsed) { - QR.cooldown.set(scope, start, null); - save = true; - } else if ((cooldown.type === type && cooldown.threadID === threadID) || cooldown.type === 'mute') { - seconds = Math.max(seconds, cooldown.delay - elapsed); - } - continue; - } - maxDelay = cooldown.threadID !== cooldown.postID ? QR.cooldown.maxDelay : QR.cooldown.delays[scope === 'global' ? 'thread_global' : 'thread']; - if (QR.cooldown.customCooldown) { - maxDelay = Math.max(maxDelay, parseInt(Conf['customCooldown'], 10)); - } - if (maxDelay <= elapsed) { - QR.cooldown.set(scope, start, null); - save = true; - continue; - } - if ((type === 'thread') === (cooldown.threadID === cooldown.postID) && cooldown.boardID !== g.BOARD.ID) { - suffix = scope === 'global' ? '_global' : ''; - seconds = Math.max(seconds, QR.cooldown.delays[type + suffix] - elapsed); - if (QR.cooldown.customCooldown) { - seconds = Math.max(seconds, parseInt(Conf['customCooldown'], 10) - elapsed); - } - } - } - nCooldowns += Object.keys(cooldowns).length; - } - } - if (save) { - QR.cooldown.save; - } - if (nCooldowns) { - clearTimeout(QR.cooldown.timeout); - QR.cooldown.timeout = setTimeout(QR.cooldown.count, $.SECOND); - } else { - delete QR.cooldown.isCounting; - } - update = seconds !== QR.cooldown.seconds; - QR.cooldown.seconds = seconds; - if (update) { - return QR.status(); - } - }, - count: function() { - QR.cooldown.update(); - if (QR.cooldown.seconds === 0 && QR.cooldown.auto && !QR.req) { - return QR.submit(); - } - } - }; - -}).call(this); - -(function() { - QR.oekaki = { - menu: { - init: function() { - var a, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Edit Link'] && Conf['Quick Reply'])) { - return; - } - a = $.el('a', { - className: 'edit-link', - href: 'javascript:;', - textContent: 'Edit image' - }); - $.on(a, 'click', this.editFile); - return Menu.menu.addEntry({ - el: a, - order: 90, - open: function(post) { - var file; - QR.oekaki.menu.post = post; - file = post.file; - return QR.postingIsEnabled && !!file && (file.isImage || file.isVideo); - } - }); - }, - editFile: function() { - var currentTime, isVideo, post, ref; - post = QR.oekaki.menu.post; - QR.quote.call(post.nodes.post); - isVideo = post.file.isVideo; - currentTime = ((ref = post.file.fullImage) != null ? ref.currentTime : void 0) || 0; - return CrossOrigin.file(post.file.url, function(blob) { - var video; - if (!blob) { - return QR.error("Can't load file."); - } else if (isVideo) { - video = $.el('video'); - $.on(video, 'loadedmetadata', function() { - $.on(video, 'seeked', function() { - var canvas; - canvas = $.el('canvas', { - width: video.videoWidth, - height: video.videoHeight - }); - canvas.getContext('2d').drawImage(video, 0, 0); - return canvas.toBlob(function(snapshot) { - snapshot.name = post.file.name.replace(/\.\w+$/, '') + '.png'; - QR.handleFiles([snapshot]); - return QR.oekaki.edit(); - }); - }); - return video.currentTime = currentTime; - }); - $.on(video, 'error', function() { - return QR.openError(); - }); - return video.src = URL.createObjectURL(blob); - } else { - blob.name = post.file.name; - QR.handleFiles([blob]); - return QR.oekaki.edit(); - } - }); - } - }, - setup: function() { - return $.global(function() { - var FCX; - FCX = window.FCX; - FCX.oekakiCB = function() { - return window.Tegaki.flatten().toBlob(function(file) { - var source; - source = "oekaki-" + (Date.now()); - FCX.oekakiLatest = source; - return document.dispatchEvent(new CustomEvent('QRSetFile', { - bubbles: true, - detail: { - file: file, - name: FCX.oekakiName, - source: source - } - })); - }); - }; - if (window.Tegaki) { - return document.querySelector('#qr .oekaki').hidden = false; - } - }); - }, - load: function(cb) { - var n, onload, script, style; - if ($('script[src^="//s.4cdn.org/js/tegaki"]', d.head)) { - return cb(); - } else { - style = $.el('link', { - rel: 'stylesheet', - href: "//s.4cdn.org/css/tegaki." + (Date.now()) + ".css" - }); - script = $.el('script', { - src: "//s.4cdn.org/js/tegaki.min." + (Date.now()) + ".js" - }); - n = 0; - onload = function() { - if (++n === 2) { - return cb(); - } - }; - $.on(style, 'load', onload); - $.on(script, 'load', onload); - return $.add(d.head, [style, script]); - } - }, - draw: function() { - return $.global(function() { - var FCX, Tegaki; - Tegaki = window.Tegaki, FCX = window.FCX; - if (Tegaki.bg) { - Tegaki.destroy(); - } - FCX.oekakiName = 'tegaki.png'; - return Tegaki.open({ - onDone: FCX.oekakiCB, - onCancel: function() { - return Tegaki.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: function() { - if (QR.selected.file) { - return QR.oekaki.edit(); - } else { - return QR.oekaki.toggle(); - } - }, - edit: function() { - return QR.oekaki.load(function() { - return $.global(function() { - var FCX, Tegaki, cb, error, name, source; - Tegaki = window.Tegaki, FCX = window.FCX; - name = document.getElementById('qr-filename').value.replace(/\.\w+$/, '') + '.png'; - source = document.getElementById('file-n-submit').dataset.source; - error = function(content) { - return document.dispatchEvent(new CustomEvent('CreateNotification', { - bubbles: true, - detail: { - type: 'warning', - content: content, - lifetime: 20 - } - })); - }; - cb = function(e) { - var canvas, selected; - if (e) { - this.removeEventListener('QRMetadata', cb, false); - } - selected = document.getElementById('selected'); - if (!(selected != null ? selected.dataset.type : void 0)) { - return error('No file to edit.'); - } - if (!/^(image|video)\//.test(selected.dataset.type)) { - return error('Not an image.'); - } - if (!selected.dataset.height) { - return error('Metadata not available.'); - } - if (selected.dataset.height === 'loading') { - selected.addEventListener('QRMetadata', cb, false); - return; - } - if (Tegaki.bg) { - Tegaki.destroy(); - } - FCX.oekakiName = name; - Tegaki.open({ - onDone: FCX.oekakiCB, - onCancel: function() { - return Tegaki.bgColor = '#ffffff'; - }, - width: +selected.dataset.width, - height: +selected.dataset.height, - bgColor: 'transparent' - }); - canvas = document.createElement('canvas'); - canvas.width = canvas.naturalWidth = +selected.dataset.width; - canvas.height = canvas.naturalHeight = +selected.dataset.height; - canvas.hidden = true; - document.body.appendChild(canvas); - canvas.addEventListener('QRImageDrawn', function() { - this.remove(); - return Tegaki.onOpenImageLoaded.call(this); - }, false); - return canvas.dispatchEvent(new CustomEvent('QRDrawFile', { - bubbles: true - })); - }; - if (Tegaki.bg && Tegaki.onDoneCb === FCX.oekakiCB && source === FCX.oekakiLatest) { - FCX.oekakiName = name; - return Tegaki.resume(); - } else { - return cb(); - } - }); - }); - }, - toggle: function() { - return QR.oekaki.load(function() { - return QR.nodes.oekaki.hidden = !QR.nodes.oekaki.hidden; - }); - } - }; - -}).call(this); - -(function() { - var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - QR.persona = { - always: {}, - types: { - name: [], - email: [], - sub: [] - }, - init: function() { - var i, item, len, ref; - if (!(Conf['Quick Reply'] || (Conf['Menu'] && Conf['Delete Link']))) { - return; - } - ref = Conf['QR.personas'].split('\n'); - for (i = 0, len = ref.length; i < len; i++) { - item = ref[i]; - QR.persona.parseItem(item.trim()); - } - }, - parseItem: function(item) { - var boards, match, ref, ref1, ref2, type, val; - if (item[0] === '#') { - return; - } - if (!(match = item.match(/(name|options|email|subject|password):"(.*)"/i))) { - return; - } - ref = match, match = ref[0], type = ref[1], val = ref[2]; - item = item.replace(match, ''); - boards = ((ref1 = item.match(/boards:([^;]+)/i)) != null ? ref1[1].toLowerCase() : void 0) || 'global'; - if (boards !== 'global' && (ref2 = g.BOARD.ID, indexOf.call(boards.split(','), ref2) < 0)) { - return; - } - if (type === 'password') { - QR.persona.pwd = val; - return; - } - if (type === 'options') { - type = 'email'; - } - if (type === 'subject') { - type = 'sub'; - } - if (/always/i.test(item)) { - QR.persona.always[type] = val; - } - if (indexOf.call(QR.persona.types[type], val) < 0) { - return QR.persona.types[type].push(val); - } - }, - load: function() { - var arr, i, len, list, ref, type, val; - ref = QR.persona.types; - for (type in ref) { - arr = ref[type]; - list = $("#list-" + type, QR.nodes.el); - for (i = 0, len = arr.length; i < len; i++) { - val = arr[i]; - if (val) { - $.add(list, $.el('option', { - textContent: val - })); - } - } - } - }, - getPassword: function() { - var m; - if (QR.persona.pwd != null) { - return QR.persona.pwd; - } else if ((m = d.cookie.match(/4chan_pass=([^;]+)/))) { - return decodeURIComponent(m[1]); - } else { - return ''; - } - }, - get: function(cb) { - return $.get('QR.persona', {}, function(arg) { - var persona; - persona = arg['QR.persona']; - return cb(persona); - }); - }, - set: function(post) { - return $.get('QR.persona', {}, function(arg) { - var persona; - persona = arg['QR.persona']; - persona = { - name: post.name, - flag: post.flag - }; - return $.set('QR.persona', persona); - }); - } - }; - -}).call(this); - -(function() { - var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - QR.post = (function() { - function _Class(select) { - this.select = bind(this.select, this); - var el, event, i, j, label, len, len1, prev, ref, ref1; - el = $.el('a', { - className: 'qr-preview', - draggable: true, - href: 'javascript:;' - }); - $.extend(el, {innerHTML: ""}); - this.nodes = { - el: el, - rm: el.firstChild, - spoiler: $('.qr-preview-spoiler input', el), - span: el.lastChild - }; - $.on(el, 'click', this.select); - $.on(this.nodes.rm, 'click', (function(_this) { - return function(e) { - e.stopPropagation(); - return _this.rm(); - }; - })(this)); - $.on(this.nodes.spoiler, 'change', (function(_this) { - return function(e) { - _this.spoiler = e.target.checked; - if (_this === QR.selected) { - QR.nodes.spoiler.checked = _this.spoiler; - } - return _this.preventAutoPost(); - }; - })(this)); - ref = $$('label', el); - for (i = 0, len = ref.length; i < len; i++) { - label = ref[i]; - $.on(label, 'click', function(e) { - return e.stopPropagation(); - }); - } - $.add(QR.nodes.dumpList, el); - ref1 = ['dragStart', 'dragEnter', 'dragLeave', 'dragOver', 'dragEnd', 'drop']; - for (j = 0, len1 = ref1.length; j < len1; j++) { - event = ref1[j]; - $.on(el, event.toLowerCase(), this[event]); - } - this.thread = g.VIEW === 'thread' ? g.THREADID : 'new'; - prev = QR.posts[QR.posts.length - 1]; - QR.posts.push(this); - this.nodes.spoiler.checked = this.spoiler = prev && Conf['Remember Spoiler'] ? prev.spoiler : false; - QR.persona.get((function(_this) { - return function(persona) { - _this.name = 'name' in QR.persona.always ? QR.persona.always.name : prev ? prev.name : persona.name; - _this.email = 'email' in QR.persona.always ? QR.persona.always.email : ''; - _this.sub = 'sub' in QR.persona.always ? QR.persona.always.sub : ''; - if (QR.nodes.flag) { - _this.flag = prev ? prev.flag : persona.flag && persona.flag in g.BOARD.config.board_flags ? persona.flag : void 0; - } - if (QR.selected === _this) { - return _this.load(); - } - }; - })(this)); - if (select) { - this.select(); - } - this.unlock(); - QR.captcha.moreNeeded(); - } - - _Class.prototype.rm = function() { - var base, index; - this["delete"](); - index = QR.posts.indexOf(this); - if (QR.posts.length === 1) { - new QR.post(true); - $.rmClass(QR.nodes.el, 'dump'); - } else if (this === QR.selected) { - (QR.posts[index - 1] || QR.posts[index + 1]).select(); - } - QR.posts.splice(index, 1); - QR.status(); - return typeof (base = QR.captcha).updateThread === "function" ? base.updateThread() : void 0; - }; - - _Class.prototype["delete"] = function() { - $.rm(this.nodes.el); - URL.revokeObjectURL(this.URL); - return this.dismissErrors(); - }; - - _Class.prototype.lock = function(lock) { - var i, len, name, node, ref; - if (lock == null) { - lock = true; - } - this.isLocked = lock; - if (this !== QR.selected) { - return; - } - ref = ['thread', 'name', 'email', 'sub', 'com', 'fileButton', 'filename', 'spoiler', 'flag']; - for (i = 0, len = ref.length; i < len; i++) { - name = ref[i]; - if (node = QR.nodes[name]) { - node.disabled = lock; - } - } - this.nodes.rm.style.visibility = lock ? 'hidden' : ''; - this.nodes.spoiler.disabled = lock; - return this.nodes.el.draggable = !lock; - }; - - _Class.prototype.unlock = function() { - return this.lock(false); - }; - - _Class.prototype.select = function() { - var rectEl, rectList; - if (QR.selected) { - QR.selected.nodes.el.removeAttribute('id'); - QR.selected.forceSave(); - } - QR.selected = this; - this.lock(this.isLocked); - this.nodes.el.id = 'selected'; - rectEl = this.nodes.el.getBoundingClientRect(); - rectList = this.nodes.el.parentNode.getBoundingClientRect(); - this.nodes.el.parentNode.scrollLeft += rectEl.left + rectEl.width / 2 - rectList.left - rectList.width / 2; - return this.load(); - }; - - _Class.prototype.load = function() { - var i, len, name, node, ref; - ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag']; - for (i = 0, len = ref.length; i < len; i++) { - name = ref[i]; - if (!(node = QR.nodes[name])) { - continue; - } - node.value = this[name] || node.dataset["default"] || ''; - } - (this.thread !== 'new' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread'); - this.showFileData(); - return QR.characterCount(); - }; - - _Class.prototype.save = function(input, forced) { - var base, name, prev; - if (input.type === 'checkbox') { - this.spoiler = input.checked; - return; - } - name = input.dataset.name; - if (name !== 'thread' && name !== 'name' && name !== 'email' && name !== 'sub' && name !== 'com' && name !== 'filename' && name !== 'flag') { - return; - } - prev = this[name] || input.dataset["default"] || null; - this[name] = input.value || input.dataset["default"] || null; - switch (name) { - case 'thread': - (this.thread !== 'new' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread'); - QR.status(); - if (typeof (base = QR.captcha).updateThread === "function") { - base.updateThread(); - } - break; - case 'com': - this.updateComment(); - break; - case 'filename': - if (!this.file) { - return; - } - this.saveFilename(); - this.updateFilename(); - break; - case 'name': - case 'flag': - if (this[name] !== prev) { - QR.persona.set(this); - } - } - if (!forced) { - return this.preventAutoPost(); - } - }; - - _Class.prototype.forceSave = function() { - var i, len, name, node, ref; - if (this !== QR.selected) { - return; - } - ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler', 'flag']; - for (i = 0, len = ref.length; i < len; i++) { - name = ref[i]; - if (!(node = QR.nodes[name])) { - continue; - } - this.save(node, true); - } - }; - - _Class.prototype.preventAutoPost = function() { - if (QR.cooldown.auto && this === QR.posts[0]) { - QR.cooldown.update(); - if (QR.cooldown.seconds <= 5) { - return QR.cooldown.auto = false; - } - } - }; - - _Class.prototype.setComment = function(com) { - this.com = com || null; - if (this === QR.selected) { - QR.nodes.com.value = this.com; - } - return this.updateComment(); - }; - - _Class.prototype.updateComment = function() { - if (this === QR.selected) { - QR.characterCount(); - } - this.nodes.span.textContent = this.com; - QR.captcha.moreNeeded(); - if (QR.captcha === Captcha.v2) { - return Captcha.cache.prerequest(); - } - }; - - _Class.prototype.isOnlyQuotes = function() { - return (this.com || '').trim() === (this.quotedText || '').trim(); - }; - - _Class.rmErrored = function(e) { - var error, errors, i, j, len, post, ref; - e.stopPropagation(); - ref = QR.posts; - for (i = ref.length - 1; i >= 0; i += -1) { - post = ref[i]; - if (errors = post.errors) { - for (j = 0, len = errors.length; j < len; j++) { - error = errors[j]; - if (!(doc.contains(error))) { - continue; - } - post.rm(); - break; - } - } - } - }; - - _Class.prototype.error = function(className, message, link) { - var div, ref, rm, rmAll; - div = $.el('div', { - className: className - }); - $.extend(div, {innerHTML: E(message) + ((link) ? " [More info]" : "") + "
    [delete post] [delete all]"}); - (this.errors || (this.errors = [])).push(div); - ref = $$('a', div), rm = ref[0], rmAll = ref[1]; - $.on(div, 'click', (function(_this) { - return function() { - if (indexOf.call(QR.posts, _this) >= 0) { - return _this.select(); - } - }; - })(this)); - $.on(rm, 'click', (function(_this) { - return function(e) { - e.stopPropagation(); - if (indexOf.call(QR.posts, _this) >= 0) { - return _this.rm(); - } - }; - })(this)); - $.on(rmAll, 'click', QR.post.rmErrored); - return QR.error(div, true); - }; - - _Class.prototype.fileError = function(message, link) { - return this.error('file-error', this.filename + ": " + message, link); - }; - - _Class.prototype.dismissErrors = function(test) { - var error, i, len, ref; - if (test == null) { - test = function() { - return true; - }; - } - if (this.errors) { - ref = this.errors; - for (i = 0, len = ref.length; i < len; i++) { - error = ref[i]; - if (doc.contains(error) && test(error)) { - error.parentNode.previousElementSibling.click(); - } - } - } - }; - - _Class.prototype.setFile = function(file1) { - var ext, ref; - this.file = file1; - if (Conf['Randomize Filename'] && g.BOARD.ID !== 'f') { - this.filename = "" + (Date.now() * 1000 - Math.floor(Math.random() * 365 * $.DAY * 1000)); - if (ext = this.file.name.match(QR.validExtension)) { - this.filename += ext[0]; - } - } else { - this.filename = this.file.name; - } - this.filesize = $.bytesToString(this.file.size); - this.checkSize(); - $.addClass(this.nodes.el, 'has-file'); - QR.captcha.moreNeeded(); - URL.revokeObjectURL(this.URL); - this.saveFilename(); - if (this === QR.selected) { - this.showFileData(); - } else { - this.updateFilename(); - } - this.rmMetadata(); - this.nodes.el.dataset.type = this.file.type; - this.nodes.el.style.backgroundImage = ''; - if (ref = this.file.type, indexOf.call(QR.mimeTypes, ref) < 0) { - this.fileError('Unsupported file type.'); - } else if (/^(image|video)\//.test(this.file.type)) { - this.readFile(); - } - return this.preventAutoPost(); - }; - - _Class.prototype.checkSize = function() { - var max; - max = QR.max_size; - if (/^video\//.test(this.file.type)) { - max = Math.min(max, QR.max_size_video); - } - if (this.file.size > max) { - return this.fileError("File too large (file: " + this.filesize + ", max: " + ($.bytesToString(max)) + ")."); - } - }; - - _Class.prototype.readFile = function() { - var el, event, isVideo, onerror, onload; - isVideo = /^video\//.test(this.file.type); - el = $.el(isVideo ? 'video' : 'img'); - if (isVideo && !el.canPlayType(this.file.type)) { - return; - } - event = isVideo ? 'loadeddata' : 'load'; - onload = (function(_this) { - return function() { - $.off(el, event, onload); - $.off(el, 'error', onerror); - _this.checkDimensions(el); - _this.setThumbnail(el); - return $.event('QRMetadata', null, _this.nodes.el); - }; - })(this); - onerror = (function(_this) { - return function() { - $.off(el, event, onload); - $.off(el, 'error', onerror); - _this.fileError("Corrupt " + (isVideo ? 'video' : 'image') + " or error reading metadata.", 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions#error-reading-metadata'); - URL.revokeObjectURL(el.src); - _this.nodes.el.removeAttribute('data-height'); - return $.event('QRMetadata', null, _this.nodes.el); - }; - })(this); - this.nodes.el.dataset.height = 'loading'; - $.on(el, event, onload); - $.on(el, 'error', onerror); - return el.src = URL.createObjectURL(this.file); - }; - - _Class.prototype.checkDimensions = function(el) { - var duration, height, max_height, max_width, videoHeight, videoWidth, width; - if (el.tagName === 'IMG') { - height = el.height, width = el.width; - this.nodes.el.dataset.height = height; - this.nodes.el.dataset.width = width; - if (height > QR.max_height || width > QR.max_width) { - this.fileError("Image too large (image: " + height + "x" + width + "px, max: " + QR.max_height + "x" + QR.max_width + "px)"); - } - if (height < QR.min_height || width < QR.min_width) { - return this.fileError("Image too small (image: " + height + "x" + width + "px, min: " + QR.min_height + "x" + QR.min_width + "px)"); - } - } else { - videoHeight = el.videoHeight, videoWidth = el.videoWidth, duration = el.duration; - this.nodes.el.dataset.height = videoHeight; - this.nodes.el.dataset.width = videoWidth; - this.nodes.el.dataset.duration = duration; - max_height = Math.min(QR.max_height, QR.max_height_video); - max_width = Math.min(QR.max_width, QR.max_width_video); - if (videoHeight > max_height || videoWidth > max_width) { - this.fileError("Video too large (video: " + videoHeight + "x" + videoWidth + "px, max: " + max_height + "x" + max_width + "px)"); - } - if (videoHeight < QR.min_height || videoWidth < QR.min_width) { - this.fileError("Video too small (video: " + videoHeight + "x" + videoWidth + "px, min: " + QR.min_height + "x" + QR.min_width + "px)"); - } - if (!isFinite(duration)) { - this.fileError('Video lacks duration metadata (try remuxing)'); - } else if (duration > QR.max_duration_video) { - this.fileError("Video too long (video: " + duration + "s, max: " + QR.max_duration_video + "s)"); - } - if (BoardConfig.noAudio(g.BOARD.ID) && $.hasAudio(el)) { - return this.fileError('Audio not allowed'); - } - } - }; - - _Class.prototype.setThumbnail = function(el) { - var cv, height, isVideo, s, width; - isVideo = el.tagName === 'VIDEO'; - s = 90 * 2 * window.devicePixelRatio; - if (this.file.type === 'image/gif') { - s *= 3; - } - if (isVideo) { - height = el.videoHeight; - width = el.videoWidth; - } else { - height = el.height, width = el.width; - if (height < s || width < s) { - this.URL = el.src; - this.nodes.el.style.backgroundImage = "url(" + this.URL + ")"; - return; - } - } - if (height <= width) { - width = s / height * width; - height = s; - } else { - height = s / width * height; - width = s; - } - cv = $.el('canvas'); - cv.height = height; - cv.width = width; - cv.getContext('2d').drawImage(el, 0, 0, width, height); - URL.revokeObjectURL(el.src); - return cv.toBlob((function(_this) { - return function(blob) { - _this.URL = URL.createObjectURL(blob); - return _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")"; - }; - })(this)); - }; - - _Class.prototype.rmFile = function() { - if (this.isLocked) { - return; - } - delete this.file; - delete this.filename; - delete this.filesize; - this.nodes.el.removeAttribute('title'); - QR.nodes.filename.removeAttribute('title'); - this.rmMetadata(); - this.nodes.el.style.backgroundImage = ''; - $.rmClass(this.nodes.el, 'has-file'); - this.showFileData(); - URL.revokeObjectURL(this.URL); - this.dismissErrors(function(error) { - return $.hasClass(error, 'file-error'); - }); - return this.preventAutoPost(); - }; - - _Class.prototype.rmMetadata = function() { - var attr, i, len, ref; - ref = ['type', 'height', 'width', 'duration']; - for (i = 0, len = ref.length; i < len; i++) { - attr = ref[i]; - this.nodes.el.removeAttribute("data-" + attr); - } - }; - - _Class.prototype.saveFilename = function() { - this.file.newName = (this.filename || '').replace(/[\/\\]/g, '-'); - if (!QR.validExtension.test(this.filename)) { - return this.file.newName += "." + ($.getOwn(QR.extensionFromType, this.file.type) || 'jpg'); - } - }; - - _Class.prototype.updateFilename = function() { - var long; - long = this.filename + " (" + this.filesize + ")"; - this.nodes.el.title = long; - if (this !== QR.selected) { - return; - } - return QR.nodes.filename.title = long; - }; - - _Class.prototype.showFileData = function() { - var ref; - if (this.file) { - this.updateFilename(); - QR.nodes.filename.value = this.filename; - $.addClass(QR.nodes.oekaki, 'has-file'); - $.addClass(QR.nodes.fileSubmit, 'has-file'); - } else { - $.rmClass(QR.nodes.oekaki, 'has-file'); - $.rmClass(QR.nodes.fileSubmit, 'has-file'); - } - if (((ref = this.file) != null ? ref.source : void 0) != null) { - QR.nodes.fileSubmit.dataset.source = this.file.source; - } else { - QR.nodes.fileSubmit.removeAttribute('data-source'); - } - return QR.nodes.spoiler.checked = this.spoiler; - }; - - _Class.prototype.pasteText = function(file) { - var reader; - this.pasting = true; - this.preventAutoPost(); - reader = new FileReader(); - reader.onload = (function(_this) { - return function(e) { - var result; - result = e.target.result; - _this.setComment((_this.com ? _this.com + "\n" + result : result)); - return delete _this.pasting; - }; - })(this); - return reader.readAsText(file); - }; - - _Class.prototype.dragStart = function(e) { - var left, ref, top; - ref = this.getBoundingClientRect(), left = ref.left, top = ref.top; - e.dataTransfer.setDragImage(this, e.clientX - left, e.clientY - top); - return $.addClass(this, 'drag'); - }; - - _Class.prototype.dragEnd = function() { - return $.rmClass(this, 'drag'); - }; - - _Class.prototype.dragEnter = function() { - return $.addClass(this, 'over'); - }; - - _Class.prototype.dragLeave = function() { - return $.rmClass(this, 'over'); - }; - - _Class.prototype.dragOver = function(e) { - e.preventDefault(); - return e.dataTransfer.dropEffect = 'move'; - }; - - _Class.prototype.drop = function() { - var base, el, index, newIndex, oldIndex, post; - $.rmClass(this, 'over'); - if (!this.draggable) { - return; - } - el = $('.drag', this.parentNode); - index = function(el) { - return slice.call(el.parentNode.children).indexOf(el); - }; - oldIndex = index(el); - newIndex = index(this); - if (QR.posts[oldIndex].isLocked || QR.posts[newIndex].isLocked) { - return; - } - (oldIndex < newIndex ? $.after : $.before)(this, el); - post = QR.posts.splice(oldIndex, 1)[0]; - QR.posts.splice(newIndex, 0, post); - QR.status(); - return typeof (base = QR.captcha).updateThread === "function" ? base.updateThread() : void 0; - }; - - return _Class; - - })(); - -}).call(this); - -QuoteBacklink = (function() { - var QuoteBacklink; - - QuoteBacklink = { - containers: $.dict(), - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Quote Backlinks']) { - return; - } - if ((this.bottomBacklinks = Conf['Bottom Backlinks'])) { - $.addClass(doc, 'bottom-backlinks'); - } - Callbacks.Post.push({ - name: 'Quote Backlinking Part 1', - cb: this.firstNode - }); - return Callbacks.Post.push({ - name: 'Quote Backlinking Part 2', - cb: this.secondNode - }); - }, - firstNode: function() { - var a, clone, container, containers, hash, i, j, k, len, len1, len2, link, markYours, nodes, post, quote, ref, ref1; - if (this.isClone || !this.quotes.length || this.isRebuilt) { - return; - } - markYours = Conf['Mark Quotes of You'] && QuoteYou.isYou(this); - a = $.el('a', { - href: g.SITE.Build.postURL(this.board.ID, this.thread.ID, this.ID), - className: this.isHidden ? 'filtered backlink' : 'backlink', - textContent: Conf['backlink'].replace(/%(?:id|%)/g, (function(_this) { - return function(x) { - return { - '%id': _this.ID, - '%%': '%' - }[x]; - }; - })(this)) - }); - if (markYours) { - $.add(a, QuoteYou.mark.cloneNode(true)); - } - ref = this.quotes; - for (i = 0, len = ref.length; i < len; i++) { - quote = ref[i]; - containers = [QuoteBacklink.getContainer(quote)]; - if ((post = g.posts.get(quote)) && post.nodes.backlinkContainer) { - ref1 = post.clones; - for (j = 0, len1 = ref1.length; j < len1; j++) { - clone = ref1[j]; - containers.push(clone.nodes.backlinkContainer); - } - } - for (k = 0, len2 = containers.length; k < len2; k++) { - container = containers[k]; - link = a.cloneNode(true); - nodes = container.firstChild ? [$.tn(' '), link] : [link]; - if (Conf['Quote Previewing']) { - $.on(link, 'mouseover', QuotePreview.mouseover); - } - if (Conf['Quote Inlining']) { - $.on(link, 'click', QuoteInline.toggle); - if (Conf['Quote Hash Navigation']) { - hash = QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')); - nodes.push(hash); - } - } - $.add(container, nodes); - } - } - }, - secondNode: function() { - var container; - if (this.isClone && (this.origin.isReply || Conf['OP Backlinks'])) { - this.nodes.backlinkContainer = $('.container', this.nodes.post); - return; - } - if (!(this.isReply || Conf['OP Backlinks'])) { - return; - } - container = QuoteBacklink.getContainer(this.fullID); - this.nodes.backlinkContainer = container; - if (QuoteBacklink.bottomBacklinks) { - return $.add(this.nodes.post, container); - } else { - return $.add(this.nodes.info, container); - } - }, - getContainer: function(id) { - var base; - return (base = this.containers)[id] || (base[id] = $.el('span', { - className: 'container' - })); - } - }; - - return QuoteBacklink; - -}).call(this); - -QuoteCT = (function() { - var QuoteCT; - - QuoteCT = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Mark Cross-thread Quotes']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - this.mark = $.el('span', { - textContent: '\u00A0(Cross-thread)', - className: 'qmark-ct' - }); - return Callbacks.Post.push({ - name: 'Mark Cross-thread Quotes', - cb: this.node - }); - }, - node: function() { - var board, boardID, i, len, quotelink, ref, ref1, ref2, thread, threadID; - if (this.isClone && this.thread === this.context.thread) { - return; - } - ref = this.context, board = ref.board, thread = ref.thread; - ref1 = this.nodes.quotelinks; - for (i = 0, len = ref1.length; i < len; i++) { - quotelink = ref1[i]; - ref2 = Get.postDataFromLink(quotelink), boardID = ref2.boardID, threadID = ref2.threadID; - if (!threadID) { - continue; - } - if (this.isClone) { - $.rm($('.qmark-ct', quotelink)); - } - if (boardID === board.ID && threadID !== thread.ID) { - $.add(quotelink, QuoteCT.mark.cloneNode(true)); - } - } - } - }; - - return QuoteCT; - -}).call(this); - -QuoteInline = (function() { - var QuoteInline, - slice = [].slice; - - QuoteInline = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Quote Inlining']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Callbacks.Post.push({ - name: 'Quote Inlining', - cb: this.node - }); - }, - node: function() { - var i, isClone, len, link, process, ref; - process = QuoteInline.process; - isClone = this.isClone; - ref = this.nodes.quotelinks.concat(slice.call(this.nodes.backlinks), this.nodes.archivelinks); - for (i = 0, len = ref.length; i < len; i++) { - link = ref[i]; - process(link, isClone); - } - }, - process: function(link, clone) { - if (Conf['Quote Hash Navigation']) { - if (!clone) { - $.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'))); - } - } - return $.on(link, 'click', QuoteInline.toggle); - }, - qiQuote: function(link, hidden) { - var name; - name = "hashlink"; - if (hidden) { - name += " filtered"; - } - return $.el('a', { - className: name, - textContent: '#', - href: link.href - }); - }, - toggle: function(e) { - var boardID, context, postID, quoter, ref, ref1, threadID; - if ($.modifiedClick(e)) { - return; - } - ref = Get.postDataFromLink(this), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - if (Conf['Inline Cross-thread Quotes Only'] && g.VIEW === 'thread' && ((ref1 = g.posts.get(boardID + "." + postID)) != null ? ref1.nodes.root.offsetParent : void 0)) { - return; - } - if ($.hasClass(doc, 'catalog-mode')) { - return; - } - e.preventDefault(); - quoter = Get.postFromNode(this); - context = quoter.context; - if ($.hasClass(this, 'inlined')) { - QuoteInline.rm(this, boardID, threadID, postID, context); - } else { - if ($.x("ancestor::div[@data-full-i-d='" + boardID + "." + postID + "']", this)) { - return; - } - QuoteInline.add(this, boardID, threadID, postID, context, quoter); - } - return this.classList.toggle('inlined'); - }, - findRoot: function(quotelink, isBacklink) { - if (isBacklink) { - return $.x('ancestor::*[parent::*[contains(@class,"post")]][1]', quotelink); - } else { - return $.x('ancestor-or-self::*[parent::blockquote][1]', quotelink); - } - }, - add: function(quotelink, boardID, threadID, postID, context, quoter) { - var inline, isBacklink, post, qroot, root; - isBacklink = $.hasClass(quotelink, 'backlink'); - inline = $.el('div', { - className: 'inline' - }); - inline.dataset.fullID = boardID + "." + postID; - root = QuoteInline.findRoot(quotelink, isBacklink); - $.after(root, inline); - qroot = $.x('ancestor::*[contains(@class,"postContainer")][1]', root); - $.addClass(qroot, 'hasInline'); - new Fetcher(boardID, threadID, postID, inline, quoter); - if (!((post = g.posts.get(boardID + "." + postID)) && context.thread === post.thread)) { - return; - } - if (isBacklink && Conf['Forward Hiding']) { - $.addClass(post.nodes.root, 'forwarded'); - post.forwarded++ || (post.forwarded = 1); - } - if (!Unread.posts) { - return; - } - return Unread.readSinglePost(post); - }, - rm: function(quotelink, boardID, threadID, postID, context) { - var el, inlined, isBacklink, parentNode, post, qroot, ref, root; - isBacklink = $.hasClass(quotelink, 'backlink'); - root = QuoteInline.findRoot(quotelink, isBacklink); - root = $.x("following-sibling::div[@data-full-i-d='" + boardID + "." + postID + "'][1]", root); - qroot = $.x('ancestor::*[contains(@class,"postContainer")][1]', root); - parentNode = root.parentNode; - $.rm(root); - $.event('PostsRemoved', null, parentNode); - if (!$('.inline', qroot)) { - $.rmClass(qroot, 'hasInline'); - } - if (!(el = root.firstElementChild)) { - return; - } - post = g.posts.get(boardID + "." + postID); - post.rmClone(el.dataset.clone); - if (Conf['Forward Hiding'] && isBacklink && context.thread === g.threads.get(boardID + "." + threadID) && !--post.forwarded) { - delete post.forwarded; - $.rmClass(post.nodes.root, 'forwarded'); - } - while (inlined = $('.inlined', el)) { - ref = Get.postDataFromLink(inlined), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - QuoteInline.rm(inlined, boardID, threadID, postID, context); - $.rmClass(inlined, 'inlined'); - } - } - }; - - return QuoteInline; - -}).call(this); - -QuoteOP = (function() { - var QuoteOP, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - QuoteOP = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Mark OP Quotes']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - this.mark = $.el('span', { - textContent: '\u00A0(OP)', - className: 'qmark-op' - }); - return Callbacks.Post.push({ - name: 'Mark OP Quotes', - cb: this.node - }); - }, - node: function() { - var boardID, fullID, i, postID, quotelink, quotelinks, quotes, ref, ref1; - if (this.isClone && this.thread === this.context.thread) { - return; - } - if (!(quotes = this.quotes).length) { - return; - } - quotelinks = this.nodes.quotelinks; - if (this.isClone && (ref = this.thread.fullID, indexOf.call(quotes, ref) >= 0)) { - i = 0; - while (quotelink = quotelinks[i++]) { - $.rm($('.qmark-op', quotelink)); - } - } - fullID = this.context.thread.fullID; - if (indexOf.call(quotes, fullID) < 0) { - return; - } - i = 0; - while (quotelink = quotelinks[i++]) { - ref1 = Get.postDataFromLink(quotelink), boardID = ref1.boardID, postID = ref1.postID; - if ((boardID + "." + postID) === fullID) { - $.add(quotelink, QuoteOP.mark.cloneNode(true)); - } - } - } - }; - - return QuoteOP; - -}).call(this); - -QuotePreview = (function() { - var QuotePreview, - slice = [].slice; - - QuotePreview = { - init: function() { - var ref; - if (!Conf['Quote Previewing']) { - return; - } - if (g.VIEW === 'archive') { - $.on(d, 'mouseover', function(e) { - if (e.target.nodeName === 'A' && $.hasClass(e.target, 'quotelink')) { - return QuotePreview.mouseover.call(e.target, e); - } - }); - } - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Callbacks.Post.push({ - name: 'Quote Previewing', - cb: this.node - }); - }, - node: function() { - var i, len, link, ref; - ref = this.nodes.quotelinks.concat(slice.call(this.nodes.backlinks), this.nodes.archivelinks); - for (i = 0, len = ref.length; i < len; i++) { - link = ref[i]; - $.on(link, 'mouseover', QuotePreview.mouseover); - } - }, - mouseover: function(e) { - var boardID, i, len, origin, post, postID, posts, qp, ref, threadID; - if (($.hasClass(this, 'inlined') && !$.hasClass(doc, 'catalog-mode')) || !d.contains(this)) { - return; - } - ref = Get.postDataFromLink(this), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - qp = $.el('div', { - id: 'qp', - className: 'dialog' - }); - $.add(Header.hover, qp); - new Fetcher(boardID, threadID, postID, qp, Get.postFromNode(this)); - UI.hover({ - root: this, - el: qp, - latestEvent: e, - endEvents: 'mouseout click', - cb: QuotePreview.mouseout - }); - if (Conf['Quote Highlighting'] && (origin = g.posts.get(boardID + "." + postID))) { - posts = [origin].concat(origin.clones); - posts.pop(); - for (i = 0, len = posts.length; i < len; i++) { - post = posts[i]; - $.addClass(post.nodes.post, 'qphl'); - } - } - }, - mouseout: function() { - var clone, i, len, post, ref, root; - if (!(root = this.el.firstElementChild)) { - return; - } - $.event('PostsRemoved', null, Header.hover); - clone = Get.postFromRoot(root); - post = clone.origin; - post.rmClone(root.dataset.clone); - if (!Conf['Quote Highlighting']) { - return; - } - ref = [post].concat(post.clones); - for (i = 0, len = ref.length; i < len; i++) { - post = ref[i]; - $.rmClass(post.nodes.post, 'qphl'); - } - } - }; - - return QuotePreview; - -}).call(this); - -QuoteStrikeThrough = (function() { - var QuoteStrikeThrough; - - QuoteStrikeThrough = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && (Conf['Reply Hiding Buttons'] || (Conf['Menu'] && Conf['Reply Hiding Link']) || Conf['Filter']))) { - return; - } - return Callbacks.Post.push({ - name: 'Strike-through Quotes', - cb: this.node - }); - }, - node: function() { - var boardID, i, len, postID, quotelink, ref, ref1, ref2; - if (this.isClone) { - return; - } - ref = this.nodes.quotelinks; - for (i = 0, len = ref.length; i < len; i++) { - quotelink = ref[i]; - ref1 = Get.postDataFromLink(quotelink), boardID = ref1.boardID, postID = ref1.postID; - if ((ref2 = g.posts.get(boardID + "." + postID)) != null ? ref2.isHidden : void 0) { - $.addClass(quotelink, 'filtered'); - } - } - } - }; - - return QuoteStrikeThrough; - -}).call(this); - -QuoteThreading = -/* - <3 aeosynth - */ - -(function() { - var QuoteThreading; - - QuoteThreading = { - init: function() { - if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) { - return; - } - this.controls = $.el('label', {innerHTML: " Threading"}); - this.threadNewLink = $.el('span', { - className: 'brackets-wrap threadnewlink', - hidden: true - }); - $.extend(this.threadNewLink, {innerHTML: "Thread New Posts"}); - this.input = $('input', this.controls); - this.input.checked = Conf['Thread Quotes']; - $.on(this.input, 'change', this.setEnabled); - $.on(this.input, 'change', this.rethread); - $.on(this.threadNewLink.firstElementChild, 'click', this.rethread); - $.on(d, '4chanXInitFinished', (function(_this) { - return function() { - return _this.ready = true; - }; - })(this)); - Header.menu.addEntry(this.entry = { - el: this.controls, - order: 99 - }); - Callbacks.Thread.push({ - name: 'Quote Threading', - cb: this.setThread - }); - return Callbacks.Post.push({ - name: 'Quote Threading', - cb: this.node - }); - }, - parent: $.dict(), - children: $.dict(), - inserted: $.dict(), - toggleThreading: function() { - return this.setThreadingState(!Conf['Thread Quotes']); - }, - setThreadingState: function(enabled) { - this.input.checked = enabled; - this.setEnabled.call(this.input); - return this.rethread.call(this.input); - }, - setEnabled: function() { - var other, ref; - if (this.checked) { - $.set('Prune All Threads', false); - other = (ref = ReplyPruning.inputs) != null ? ref.enabled : void 0; - if (other != null ? other.checked : void 0) { - other.checked = false; - $.event('change', null, other); - } - } - return $.cb.checked.call(this); - }, - setThread: function() { - QuoteThreading.thread = this; - return $.asap((function() { - return !Conf['Thread Updater'] || $('.navLinksBot > .updatelink'); - }), function() { - var navLinksBot; - if ((navLinksBot = $('.navLinksBot'))) { - return $.add(navLinksBot, [$.tn(' '), QuoteThreading.threadNewLink]); - } - }); - }, - node: function() { - var ancestor, j, lastParent, len, parent, parents, quote, ref; - if (this.isFetchedQuote || this.isClone || !this.isReply) { - return; - } - parents = new Set(); - lastParent = null; - ref = this.quotes; - for (j = 0, len = ref.length; j < len; j++) { - quote = ref[j]; - if (parent = g.posts.get(quote)) { - if (!parent.isFetchedQuote && parent.isReply && parent.ID < this.ID) { - parents.add(parent.ID); - if (!lastParent || parent.ID > lastParent.ID) { - lastParent = parent; - } - } - } - } - if (!lastParent) { - return; - } - ancestor = lastParent; - while (ancestor = QuoteThreading.parent[ancestor.fullID]) { - parents["delete"](ancestor.ID); - } - if (parents.size === 1) { - return QuoteThreading.parent[this.fullID] = lastParent; - } - }, - descendants: function(post) { - var child, children, j, len, posts; - posts = [post]; - if (children = QuoteThreading.children[post.fullID]) { - for (j = 0, len = children.length; j < len; j++) { - child = children[j]; - posts = posts.concat(QuoteThreading.descendants(child)); - } - } - return posts; - }, - insert: function(post) { - var base, child, children, descendants, i, j, k, l, len, name, next, nodes, order, parent, prev, prev2, threadContainer, x; - if (!(Conf['Thread Quotes'] && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) { - return false; - } - descendants = QuoteThreading.descendants(post); - if (!Unread.posts.has(parent.ID)) { - if ((function() { - var j, len, x; - for (j = 0, len = descendants.length; j < len; j++) { - x = descendants[j]; - if (Unread.posts.has(x.ID)) { - return true; - } - } - })()) { - QuoteThreading.threadNewLink.hidden = false; - return false; - } - } - order = Unread.order; - children = ((base = QuoteThreading.children)[name = parent.fullID] || (base[name] = [])); - threadContainer = parent.nodes.threadContainer || $.el('div', { - className: 'threadContainer' - }); - nodes = [post.nodes.root]; - if (post.nodes.threadContainer) { - nodes.push(post.nodes.threadContainer); - } - i = children.length; - for (j = children.length - 1; j >= 0; j += -1) { - child = children[j]; - if (child.ID >= post.ID) { - i--; - } - } - if (i !== children.length) { - next = children[i]; - for (k = 0, len = descendants.length; k < len; k++) { - x = descendants[k]; - order.before(order[next.ID], order[x.ID]); - } - children.splice(i, 0, post); - $.before(next.nodes.root, nodes); - } else { - prev = parent; - while ((prev2 = QuoteThreading.children[prev.fullID]) && prev2.length) { - prev = prev2[prev2.length - 1]; - } - for (l = descendants.length - 1; l >= 0; l += -1) { - x = descendants[l]; - order.after(order[prev.ID], order[x.ID]); - } - children.push(post); - $.add(threadContainer, nodes); - } - QuoteThreading.inserted[post.fullID] = true; - if (!parent.nodes.threadContainer) { - parent.nodes.threadContainer = threadContainer; - $.addClass(parent.nodes.root, 'threadOP'); - $.after(parent.nodes.root, threadContainer); - } - return true; - }, - rethread: function() { - var nodes, posts, thread; - if (!QuoteThreading.ready) { - return; - } - thread = QuoteThreading.thread; - posts = thread.posts; - QuoteThreading.threadNewLink.hidden = true; - if (Conf['Thread Quotes']) { - posts.forEach(QuoteThreading.insert); - } else { - nodes = []; - Unread.order = new RandomAccessList(); - QuoteThreading.inserted = $.dict(); - posts.forEach(function(post) { - if (post.isFetchedQuote) { - return; - } - Unread.order.push(post); - if (post.isReply) { - nodes.push(post.nodes.root); - } - if (QuoteThreading.children[post.fullID]) { - delete QuoteThreading.children[post.fullID]; - $.rmClass(post.nodes.root, 'threadOP'); - $.rm(post.nodes.threadContainer); - return delete post.nodes.threadContainer; - } - }); - $.add(thread.nodes.root, nodes); - } - Unread.position = Unread.order.first; - Unread.updatePosition(); - Unread.setLine(true); - Unread.read(); - return Unread.update(); - } - }; - - return QuoteThreading; - -}).call(this); - -QuoteYou = (function() { - var QuoteYou; - - QuoteYou = { - init: function() { - var ref; - if (!Conf['Remember Your Posts']) { - return; - } - this.db = new DataBoard('yourPosts'); - $.sync('Remember Your Posts', function(enabled) { - return Conf['Remember Your Posts'] = enabled; - }); - $.on(d, 'QRPostSuccessful', function(e) { - var cb; - cb = PostRedirect.delay(); - return $.get('Remember Your Posts', Conf['Remember Your Posts'], function(items) { - var boardID, postID, ref, threadID; - if (!items['Remember Your Posts']) { - return; - } - ref = e.detail, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - return QuoteYou.db.set({ - boardID: boardID, - threadID: threadID, - postID: postID, - val: true - }, cb); - }); - }); - if ((ref = g.VIEW) !== 'index' && ref !== 'thread' && ref !== 'archive') { - return; - } - if (Conf['Highlight Own Posts']) { - $.addClass(doc, 'highlight-own'); - } - if (Conf['Highlight Posts Quoting You']) { - $.addClass(doc, 'highlight-you'); - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - this.mark = $.el('span', { - textContent: '\u00A0(You)', - className: 'qmark-you' - }); - Callbacks.Post.push({ - name: 'Mark Quotes of You', - cb: this.node - }); - return QuoteYou.menu.init(); - }, - isYou: function(post) { - var ref; - return !!((ref = QuoteYou.db) != null ? ref.get({ - boardID: post.boardID, - threadID: post.threadID, - postID: post.ID - }) : void 0); - }, - node: function() { - var i, len, quotelink, ref; - if (this.isClone) { - return; - } - if (QuoteYou.isYou(this)) { - $.addClass(this.nodes.root, 'yourPost'); - } - if (!this.quotes.length) { - return; - } - ref = this.nodes.quotelinks; - for (i = 0, len = ref.length; i < len; i++) { - quotelink = ref[i]; - if (!(QuoteYou.db.get(Get.postDataFromLink(quotelink)))) { - continue; - } - if (Conf['Mark Quotes of You']) { - $.add(quotelink, QuoteYou.mark.cloneNode(true)); - } - $.addClass(quotelink, 'you'); - $.addClass(this.nodes.root, 'quotesYou'); - } - }, - menu: { - init: function() { - var input, label, ref; - label = $.el('label', { - className: 'toggle-you' - }, {innerHTML: " You"}); - input = $('input', label); - $.on(input, 'change', QuoteYou.menu.toggle); - return (ref = Menu.menu) != null ? ref.addEntry({ - el: label, - order: 80, - open: function(post) { - QuoteYou.menu.post = post.origin || post; - input.checked = QuoteYou.isYou(post); - return true; - } - }) : void 0; - }, - toggle: function() { - var clone, data, i, j, len, len1, post, quotelink, quoter, ref, ref1; - post = QuoteYou.menu.post; - data = { - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID, - val: true - }; - if (this.checked) { - QuoteYou.db.set(data); - } else { - QuoteYou.db["delete"](data); - } - ref = [post].concat(post.clones); - for (i = 0, len = ref.length; i < len; i++) { - clone = ref[i]; - clone.nodes.root.classList.toggle('yourPost', this.checked); - } - ref1 = Get.allQuotelinksLinkingTo(post); - for (j = 0, len1 = ref1.length; j < len1; j++) { - quotelink = ref1[j]; - if (this.checked) { - if (Conf['Mark Quotes of You']) { - $.add(quotelink, QuoteYou.mark.cloneNode(true)); - } - } else { - $.rm($('.qmark-you', quotelink)); - } - quotelink.classList.toggle('you', this.checked); - if ($.hasClass(quotelink, 'quotelink')) { - quoter = Get.postFromNode(quotelink).nodes.root; - quoter.classList.toggle('quotesYou', !!$('.quotelink.you', quoter)); - } - } - } - }, - cb: { - seek: function(type) { - var highlight, highlighted, post, posts, result, str; - highlight = g.SITE.classes.highlight; - if ((highlighted = $("." + highlight))) { - $.rmClass(highlighted, highlight); - } - if (!(QuoteYou.lastRead && doc.contains(QuoteYou.lastRead) && $.hasClass(QuoteYou.lastRead, 'quotesYou'))) { - if (!(post = QuoteYou.lastRead = $('.quotesYou'))) { - new Notice('warning', 'No posts are currently quoting you, loser.', 20); - return; - } - if (QuoteYou.cb.scroll(post)) { - return; - } - } else { - post = QuoteYou.lastRead; - } - str = type + "::div[contains(@class,'quotesYou')]"; - while ((post = (result = $.X(str, post)).snapshotItem(type === 'preceding' ? result.snapshotLength - 1 : 0))) { - if (QuoteYou.cb.scroll(post)) { - return; - } - } - posts = $$('.quotesYou'); - return QuoteYou.cb.scroll(posts[type === 'following' ? 0 : posts.length - 1]); - }, - scroll: function(root) { - var node, post, sel; - post = Get.postFromRoot(root); - if (!post.nodes.post.getBoundingClientRect().height) { - return false; - } else { - QuoteYou.lastRead = root; - location.href = Get.url('post', post); - Header.scrollTo(post.nodes.post); - if (post.isReply) { - sel = "" + g.SITE.selectors.postContainer + g.SITE.selectors.highlightable.reply; - node = post.nodes.root; - if (!node.matches(sel)) { - node = $(sel, node); - } - $.addClass(node, g.SITE.classes.highlight); - } - return true; - } - } - } - }; - - return QuoteYou; - -}).call(this); - -Quotify = (function() { - var Quotify, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - Quotify = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Resurrect Quotes']) { - return; - } - $.addClass(doc, 'resurrect-quotes'); - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Callbacks.Post.push({ - name: 'Resurrect Quotes', - cb: this.node - }); - }, - node: function() { - var deadlink, i, j, len, len1, link, ref, ref1; - if (this.isClone) { - this.nodes.archivelinks = $$('a.linkify.quotelink', this.nodes.comment); - return; - } - ref = $$('a.linkify', this.nodes.comment); - for (i = 0, len = ref.length; i < len; i++) { - link = ref[i]; - Quotify.parseArchivelink.call(this, link); - } - ref1 = $$('.deadlink', this.nodes.comment); - for (j = 0, len1 = ref1.length; j < len1; j++) { - deadlink = ref1[j]; - Quotify.parseDeadlink.call(this, deadlink); - } - }, - parseArchivelink: function(link) { - var boardID, m, postID, ref, threadID; - if (!(m = link.pathname.match(/^\/([^\/]+)\/thread\/S?(\d+)\/?$/))) { - return; - } - if ((ref = link.hostname) === 'boards.4chan.org' || ref === 'boards.4channel.org') { - return; - } - boardID = m[1]; - threadID = m[2]; - postID = link.hash.match(/^#[pq]?(\d+)$|$/)[1] || threadID; - if (Redirect.to('post', { - boardID: boardID, - postID: postID - })) { - $.addClass(link, 'quotelink'); - $.extend(link.dataset, { - boardID: boardID, - threadID: threadID, - postID: postID - }); - return this.nodes.archivelinks.push(link); - } - }, - parseDeadlink: function(deadlink) { - var a, boardID, fetchable, m, post, postID, quote, quoteID, redirect, ref; - if ($.hasClass(deadlink.parentNode, 'prettyprint')) { - Quotify.fixDeadlink(deadlink); - return; - } - quote = deadlink.textContent; - if (!(postID = (ref = quote.match(/\d+$/)) != null ? ref[0] : void 0)) { - return; - } - if (postID[0] === '0') { - Quotify.fixDeadlink(deadlink); - return; - } - boardID = (m = quote.match(/^>>>\/([a-z\d]+)/)) ? m[1] : this.board.ID; - quoteID = boardID + "." + postID; - if (post = g.posts.get(quoteID)) { - if (!post.isDead) { - a = $.el('a', { - href: g.SITE.Build.postURL(boardID, post.thread.ID, postID), - className: 'quotelink', - textContent: quote - }); - } else { - a = $.el('a', { - href: g.SITE.Build.postURL(boardID, post.thread.ID, postID), - className: 'quotelink deadlink', - textContent: quote - }); - $.add(a, Post.deadMark.cloneNode(true)); - $.extend(a.dataset, { - boardID: boardID, - threadID: post.thread.ID, - postID: postID - }); - } - } else { - redirect = Redirect.to('thread', { - boardID: boardID, - threadID: 0, - postID: postID - }); - fetchable = Redirect.to('post', { - boardID: boardID, - postID: postID - }); - if (redirect || fetchable) { - a = $.el('a', { - href: redirect || 'javascript:;', - className: 'deadlink', - textContent: quote - }); - $.add(a, Post.deadMark.cloneNode(true)); - if (fetchable) { - $.addClass(a, 'quotelink'); - $.extend(a.dataset, { - boardID: boardID, - postID: postID - }); - } - } - } - if (indexOf.call(this.quotes, quoteID) < 0) { - this.quotes.push(quoteID); - } - if (!a) { - $.add(deadlink, Post.deadMark.cloneNode(true)); - return; - } - $.replace(deadlink, a); - if ($.hasClass(a, 'quotelink')) { - return this.nodes.quotelinks.push(a); - } - }, - fixDeadlink: function(deadlink) { - var el, green; - if (!(el = deadlink.previousSibling) || el.nodeName === 'BR') { - green = $.el('span', { - className: 'quote' - }); - $.before(deadlink, green); - $.add(green, deadlink); - } - return $.replace(deadlink, slice.call(deadlink.childNodes)); - } - }; - - return Quotify; - -}).call(this); - -Main = (function() { - var Main, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Main = { - init: function() { - var db, flatten, i, items, j, k, key, len, mountedCB, ref, ref1, ref2, w; - try { - w = window; - if ($.platform === 'crx') { - w = w.wrappedJSObject || w; - } - if ('4chan X antidup' in w) { - return; - } - w['4chan X antidup'] = true; - } catch (error1) {} - try { - if (window.frameElement && ((ref = window.frameElement.src) === '' || ref === 'about:blank')) { - return; - } - } catch (error1) {} - if (doc && $.hasClass(doc, 'fourchan-x')) { - return; - } - $.asap(docSet, function() { - $.addClass(doc, 'fourchan-x', 'seaweedchan'); - if ($.engine) { - return $.addClass(doc, "ua-" + $.engine); - } - }); - $.on(d, '4chanXInitFinished', function() { - if (Main.expectInitFinished) { - return delete Main.expectInitFinished; - } else { - new Notice('error', 'Error: Multiple copies of 4chan X are enabled.'); - return $.addClass(doc, 'tainted'); - } - }); - mountedCB = function() { - var cb, j, len, ref1, results; - d.removeEventListener('mounted', mountedCB, true); - Main.isMounted = true; - ref1 = Main.mountedCBs; - results = []; - for (j = 0, len = ref1.length; j < len; j++) { - cb = ref1[j]; - try { - results.push(cb()); - } catch (error1) {} - } - return results; - }; - d.addEventListener('mounted', mountedCB, true); - flatten = function(parent, obj) { - var key, val; - if (obj instanceof Array) { - Conf[parent] = $.dict.clone(obj[0]); - } else if (typeof obj === 'object') { - for (key in obj) { - val = obj[key]; - flatten(key, val); - } - } else { - Conf[parent] = obj; - } - }; - if ((ref1 = location.hostname) === 'boards.4chan.org' || ref1 === 'boards.4channel.org') { - $.global(function() { - var fromCharCode0; - fromCharCode0 = String.fromCharCode; - return String.fromCharCode = function() { - if (document.body) { - String.fromCharCode = fromCharCode0; - } else if (document.currentScript && !document.currentScript.src) { - throw Error(); - } - return fromCharCode0.apply(this, arguments); - }; - }); - $.asap(docSet, function() { - return $.onExists(doc, 'iframe[srcdoc]', $.rm); - }); - } - flatten(null, Config); - ref2 = DataBoard.keys; - for (j = 0, len = ref2.length; j < len; j++) { - db = ref2[j]; - Conf[db] = $.dict(); - } - Conf['customTitles'] = $.dict.clone({ - '4chan.org': { - boards: { - 'qa': { - 'boardTitle': { - orig: '/qa/ - Question & Answer', - title: '/qa/ - 2D/Random' - } - } - } - } - }); - Conf['boardConfig'] = { - boards: $.dict() - }; - Conf['archives'] = Redirect.archives; - Conf['selectedArchives'] = $.dict(); - Conf['cooldowns'] = $.dict(); - Conf['Index Sort'] = $.dict(); - for (i = k = 0; k < 2; i = ++k) { - Conf["Last Long Reply Thresholds " + i] = $.dict(); - } - Conf['siteProperties'] = $.dict(); - Conf['Except Archives from Encryption'] = false; - Conf['JSON Navigation'] = true; - Conf['Oekaki Links'] = true; - Conf['Show Name and Subject'] = false; - Conf['QR Shortcut'] = true; - Conf['Bottom QR Link'] = true; - Conf['Toggleable Thread Watcher'] = true; - Conf['siteSoftware'] = ''; - Conf['Use Faster Image Host'] = 'true'; - Conf['Captcha Fixes'] = true; - Conf['captchaServiceDomain'] = ''; - Conf['captchaServiceKey'] = $.dict(); - if (/\.4chan(?:nel)?\.org$/.test(location.hostname) && !SW.yotsuba.regexp.pass.test(location.href) && !SW.yotsuba.regexp.captcha.test(location.href) && !$$('script:not([src])', d).filter(function(s) { - return /this\[/.test(s.textContent); - }).length) { - ($.getSync || $.get)({ - 'jsWhitelist': Conf['jsWhitelist'] - }, function(arg) { - var jsWhitelist; - jsWhitelist = arg.jsWhitelist; - return $.addCSP("script-src " + (jsWhitelist.replace(/^#.*$/mg, '').replace(/[\s;]+/g, ' ').trim())); - }); - } - items = $.dict(); - for (key in Conf) { - items[key] = void 0; - } - items['previousversion'] = void 0; - return ($.getSync || $.get)(items, function(items) { - var ref3; - if (!$.perProtocolSettings && /\.4chan(?:nel)?\.org$/.test(location.hostname) && ((ref3 = items['Redirect to HTTPS']) != null ? ref3 : Conf['Redirect to HTTPS']) && location.protocol !== 'https:') { - location.replace('https://' + location.host + location.pathname + location.search + location.hash); - return; - } - return $.asap(docSet, function() { - var ref4, val; - if ($.cantSet) { - - } else if (items.previousversion == null) { - Main.isFirstRun = true; - Main.ready(function() { - $.set('previousversion', g.VERSION); - return Settings.open(); - }); - } else if (items.previousversion !== g.VERSION) { - Main.upgrade(items); - } - for (key in Conf) { - val = Conf[key]; - Conf[key] = (ref4 = items[key]) != null ? ref4 : val; - } - return Site.init(Main.initFeatures); - }); - }); - }, - upgrade: function(items) { - var changes, previousversion; - previousversion = items.previousversion; - changes = Settings.upgrade(items, previousversion); - items.previousversion = changes.previousversion = g.VERSION; - return $.set(changes, function() { - var el, ref; - if ((ref = items['Show Updated Notifications']) != null ? ref : true) { - el = $.el('span', {innerHTML: "4chan X has been updated to version " + E(g.VERSION) + "."}); - return new Notice('info', el, 15); - } - }); - }, - parseURL: function(site, url) { - var pathname, r, ref; - if (site == null) { - site = g.SITE; - } - if (url == null) { - url = location; - } - r = {}; - if (!site) { - return r; - } - r.siteID = site.ID; - if (typeof site.isBoardlessPage === "function" ? site.isBoardlessPage(url) : void 0) { - return r; - } - pathname = url.pathname.split(/\/+/); - r.boardID = pathname[1]; - if (site.isFileURL(url)) { - r.VIEW = 'file'; - } else if (typeof site.isAuxiliaryPage === "function" ? site.isAuxiliaryPage(url) : void 0) { - - } else if ((ref = pathname[2]) === 'thread' || ref === 'res') { - r.VIEW = 'thread'; - r.threadID = r.THREADID = +pathname[3].replace(/\.\w+$/, ''); - } else if (pathname[2] === 'archive' && pathname[3] === 'res') { - r.VIEW = 'thread'; - r.threadID = r.THREADID = +pathname[4].replace(/\.\w+$/, ''); - r.threadArchived = true; - } else if (/^(?:catalog|archive)(?:\.\w+)?$/.test(pathname[2])) { - r.VIEW = pathname[2].replace(/\.\w+$/, ''); - } else if (/^(?:index|\d*)(?:\.\w+)?$/.test(pathname[2])) { - r.VIEW = 'index'; - } - return r; - }, - initFeatures: function() { - var base, err, feature, j, len, name, ref, ref1; - $.global(function() { - document.documentElement.classList.add('js-enabled'); - return window.FCX = {}; - }); - Main.jsEnabled = $.hasClass(doc, 'js-enabled'); - if (typeof $.ajaxPageInit === "function") { - $.ajaxPageInit(); - } - $.extend(g, Main.parseURL()); - if (g.boardID) { - g.BOARD = new Board(g.boardID); - } - if (!g.VIEW) { - if (typeof (base = g.SITE).initAuxiliary === "function") { - base.initAuxiliary(); - } - return; - } - if (g.VIEW === 'file') { - $.asap((function() { - return d.readyState !== 'loading'; - }), function() { - var base1, pathname, video; - if (g.SITE.software === 'yotsuba' && Conf['404 Redirect'] && (typeof (base1 = g.SITE).is404 === "function" ? base1.is404() : void 0)) { - pathname = location.pathname.split(/\/+/); - return Redirect.navigate('file', { - boardID: g.BOARD.ID, - filename: pathname[pathname.length - 1] - }); - } else if (video = $('video')) { - if (Conf['Volume in New Tab']) { - Volume.setup(video); - } - if (Conf['Loop in New Tab']) { - video.loop = true; - video.controls = false; - video.play(); - return ImageCommon.addControls(video); - } - } - }); - return; - } - g.threads = new SimpleDict(); - g.posts = new SimpleDict(); - $.onExists(doc, 'body', Main.initStyle); - ref = Main.features; - for (j = 0, len = ref.length; j < len; j++) { - ref1 = ref[j], name = ref1[0], feature = ref1[1]; - if (g.SITE.disabledFeatures && indexOf.call(g.SITE.disabledFeatures, name) >= 0) { - continue; - } - try { - feature.init(); - } catch (error1) { - err = error1; - Main.handleErrors({ - message: "\"" + name + "\" initialization crashed.", - error: err - }); - } - } - return $.ready(Main.initReady); - }, - initStyle: function() { - var keyboard, ref; - if (!Main.isThisPageLegit()) { - return; - } - if ((ref = $('link[href*=mobile]', d.head)) != null) { - ref.disabled = true; - } - doc.dataset.host = location.host; - $.addClass(doc, "sw-" + g.SITE.software); - $.addClass(doc, g.VIEW === 'thread' ? 'thread-view' : g.VIEW); - $.onExists(doc, '.ad-cnt, .adg-rects > .desktop', function(ad) { - return $.onExists(ad, 'img, iframe', function() { - return $.addClass(doc, 'ads-loaded'); - }); - }); - if (Conf['Autohiding Scrollbar']) { - $.addClass(doc, 'autohiding-scrollbar'); - } - $.ready(function() { - if (d.body.clientHeight > doc.clientHeight && (window.innerWidth === doc.clientWidth) !== Conf['Autohiding Scrollbar']) { - Conf['Autohiding Scrollbar'] = !Conf['Autohiding Scrollbar']; - $.set('Autohiding Scrollbar', Conf['Autohiding Scrollbar']); - return $.toggleClass(doc, 'autohiding-scrollbar'); - } - }); - $.addStyle(CSS.sub(CSS.boards), 'fourchanx-css'); - Main.bgColorStyle = $.el('style', { - id: 'fourchanx-bgcolor-css' - }); - keyboard = false; - $.on(d, 'mousedown', function() { - return keyboard = false; - }); - $.on(d, 'keydown', function(e) { - if (e.keyCode === 9) { - return keyboard = true; - } - }); - window.addEventListener('focus', (function() { - return doc.classList.toggle('keyboard-focus', keyboard); - }), true); - return Main.setClass(); - }, - setClass: function() { - var j, knownStyles, len, mainStyleSheet, ref, ref1, setStyle, style, styleSheet, styleSheets; - knownStyles = ['yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'photon', 'tomorrow', 'spooky']; - if (g.SITE.software === 'yotsuba' && g.VIEW === 'catalog') { - if ((mainStyleSheet = $.id('base-css'))) { - style = (ref = mainStyleSheet.href.match(/catalog_(\w+)/)) != null ? ref[1].replace('_new', '').replace(/_+/g, '-') : void 0; - if (indexOf.call(knownStyles, style) >= 0) { - $.addClass(doc, style); - return; - } - } - } - style = mainStyleSheet = styleSheets = null; - setStyle = function() { - var bgColor, css, div, j, len, rgb, s, styleSheet; - if (g.SITE.software === 'yotsuba') { - $.rmClass(doc, style); - style = null; - for (j = 0, len = styleSheets.length; j < len; j++) { - styleSheet = styleSheets[j]; - if (styleSheet.href === (mainStyleSheet != null ? mainStyleSheet.href : void 0)) { - style = styleSheet.title.toLowerCase().replace('new', '').trim().replace(/\s+/g, '-'); - if (style === '_special') { - style = styleSheet.href.match(/[a-z]*(?=[^\/]*$)/)[0]; - } - if (indexOf.call(knownStyles, style) < 0) { - style = null; - } - break; - } - } - if (style) { - $.addClass(doc, style); - $.rm(Main.bgColorStyle); - return; - } - } - div = g.SITE.bgColoredEl(); - div.style.position = 'absolute'; - div.style.visibility = 'hidden'; - $.add(d.body, div); - bgColor = window.getComputedStyle(div).backgroundColor; - $.rm(div); - rgb = bgColor.match(/[\d.]+/g); - if (!/^rgb\(/.test(bgColor)) { - s = window.getComputedStyle(d.body); - bgColor = s.backgroundColor + " " + s.backgroundImage + " " + s.backgroundRepeat + " " + s.backgroundPosition; - } - css = ".dialog, .suboption-list > div:last-of-type, :root.catalog-hover-expand .catalog-container:hover > .post {\n background: " + bgColor + ";\n}\n.unread-mark-read {\n background-color: rgba(" + (rgb.slice(0, 3).join(', ')) + ", " + (0.5 * (rgb[3] || 1)) + ");\n}"; - if ($.luma(rgb) < 100) { - css += ".watch-thread-link {\n background-image: url(\"data:image/svg+xml,\");\n}"; - } - Main.bgColorStyle.textContent = css; - return $.after($.id('fourchanx-css'), Main.bgColorStyle); - }; - $.onExists(d.head, g.SITE.selectors.styleSheet, function(el) { - mainStyleSheet = el; - if (g.SITE.software === 'yotsuba') { - styleSheets = $$('link[rel="alternate stylesheet"]', d.head); - } - new MutationObserver(setStyle).observe(mainStyleSheet, { - attributes: true, - attributeFilter: ['href'] - }); - $.on(mainStyleSheet, 'load', setStyle); - return setStyle(); - }); - if (!mainStyleSheet) { - ref1 = $$('link[rel="stylesheet"]', d.head); - for (j = 0, len = ref1.length; j < len; j++) { - styleSheet = ref1[j]; - $.on(styleSheet, 'load', setStyle); - } - return setStyle(); - } - }, - initReady: function() { - var base, base1, msg; - if (typeof (base = g.SITE).is404 === "function" ? base.is404() : void 0) { - if (g.VIEW === 'thread') { - ThreadWatcher.set404(g.BOARD.ID, g.THREADID, function() { - if (Conf['404 Redirect']) { - return Redirect.navigate('thread', { - boardID: g.BOARD.ID, - threadID: g.THREADID, - postID: +location.hash.match(/\d+/) - }, "/" + g.BOARD + "/"); - } - }); - } - return; - } - if (typeof (base1 = g.SITE).isIncomplete === "function" ? base1.isIncomplete() : void 0) { - msg = $.el('div', {innerHTML: "The page didn't load completely.
    Some features may not work unless you reload."}); - $.on($('a', msg), 'click', function() { - return location.reload(); - }); - new Notice('warning', msg); - } - if (g.VIEW === 'catalog') { - return Main.initCatalog(); - } else if (!Index.enabled) { - if (g.SITE.awaitBoard) { - return g.SITE.awaitBoard(Main.initThread); - } else { - return Main.initThread(); - } - } else { - Main.expectInitFinished = true; - return $.event('4chanXInitFinished'); - } - }, - initThread: function() { - var base, base1, board, errors, posts, ref, s, threads; - s = g.SITE.selectors; - if ((board = $(((ref = s.boardFor) != null ? ref[g.VIEW] : void 0) || s.board))) { - threads = []; - posts = []; - errors = []; - try { - if (typeof (base = g.SITE).preParsingFixes === "function") { - base.preParsingFixes(board); - } - } catch (error1) {} - Main.addThreadsObserver = new MutationObserver(Main.addThreads); - Main.addPostsObserver = new MutationObserver(Main.addPosts); - Main.addThreadsObserver.observe(board, { - childList: true - }); - Main.parseThreads($$(s.thread, board), threads, posts, errors); - if (errors.length) { - Main.handleErrors(errors); - } - if (g.VIEW === 'thread') { - if (g.threadArchived) { - threads[0].isArchived = true; - threads[0].kill(); - } - if (typeof (base1 = g.SITE).parseThreadMetadata === "function") { - base1.parseThreadMetadata(threads[0]); - } - } - Main.callbackNodes('Thread', threads); - return Main.callbackNodesDB('Post', posts, function() { - var j, len, post; - for (j = 0, len = posts.length; j < len; j++) { - post = posts[j]; - QuoteThreading.insert(post); - } - Main.expectInitFinished = true; - return $.event('4chanXInitFinished'); - }); - } else { - Main.expectInitFinished = true; - return $.event('4chanXInitFinished'); - } - }, - parseThreads: function(threadRoots, threads, posts, errors) { - var boardID, boardObj, j, len, postRoots, ref, thread, threadID, threadRoot; - for (j = 0, len = threadRoots.length; j < len; j++) { - threadRoot = threadRoots[j]; - boardObj = (boardID = threadRoot.dataset.board) ? (boardID = encodeURIComponent(boardID), g.boards[boardID] || new Board(boardID)) : g.BOARD; - threadID = +threadRoot.id.match(/\d*$/)[0]; - if (!threadID || ((ref = boardObj.threads.get(threadID)) != null ? ref.nodes.root : void 0)) { - return; - } - thread = new Thread(threadID, boardObj); - thread.nodes.root = threadRoot; - threads.push(thread); - postRoots = $$(g.SITE.selectors.postContainer, threadRoot); - if (g.SITE.isOPContainerThread) { - postRoots.unshift(threadRoot); - } - Main.parsePosts(postRoots, thread, posts, errors); - Main.addPostsObserver.observe(threadRoot, { - childList: true - }); - } - }, - parsePosts: function(postRoots, thread, posts, errors) { - var err, j, len, postRoot; - for (j = 0, len = postRoots.length; j < len; j++) { - postRoot = postRoots[j]; - if (!(postRoot.dataset.fullID && g.posts.get(postRoot.dataset.fullID)) && $(g.SITE.selectors.comment, postRoot)) { - try { - posts.push(new Post(postRoot, thread, thread.board)); - } catch (error1) { - err = error1; - errors.push({ - message: "Parsing of Post No." + (postRoot.id.match(/\d+/)) + " failed. Post will be skipped.", - error: err, - html: postRoot.outerHTML - }); - } - } - } - }, - addThreads: function(records) { - var errors, j, k, len, len1, node, posts, record, ref, threadRoots, threads; - threadRoots = []; - for (j = 0, len = records.length; j < len; j++) { - record = records[j]; - ref = record.addedNodes; - for (k = 0, len1 = ref.length; k < len1; k++) { - node = ref[k]; - if (node.nodeType === Node.ELEMENT_NODE && node.matches(g.SITE.selectors.thread)) { - threadRoots.push(node); - } - } - } - if (!threadRoots.length) { - return; - } - threads = []; - posts = []; - errors = []; - Main.parseThreads(threadRoots, threads, posts, errors); - if (errors.length) { - Main.handleErrors(errors); - } - Main.callbackNodes('Thread', threads); - return Main.callbackNodesDB('Post', posts, function() { - return $.event('PostsInserted', null, records[0].target); - }); - }, - addPosts: function(records) { - var anyRemoved, el, errors, j, k, l, len, len1, len2, n, node, postRoots, posts, record, ref, ref1, ref2, thread, threads, threadsRM; - threads = []; - threadsRM = []; - posts = []; - errors = []; - for (j = 0, len = records.length; j < len; j++) { - record = records[j]; - thread = Get.threadFromRoot(record.target); - postRoots = []; - ref = record.addedNodes; - for (k = 0, len1 = ref.length; k < len1; k++) { - node = ref[k]; - if (node.nodeType === Node.ELEMENT_NODE) { - if (node.matches(g.SITE.selectors.postContainer) || (node = $(g.SITE.selectors.postContainer, node))) { - postRoots.push(node); - } - } - } - n = posts.length; - Main.parsePosts(postRoots, thread, posts, errors); - if (posts.length > n && indexOf.call(threads, thread) < 0) { - threads.push(thread); - } - anyRemoved = false; - ref1 = record.removedNodes; - for (l = 0, len2 = ref1.length; l < len2; l++) { - el = ref1[l]; - if (((ref2 = Get.postFromRoot(el)) != null ? ref2.nodes.root : void 0) === el && !doc.contains(el)) { - anyRemoved = true; - break; - } - } - if (anyRemoved && indexOf.call(threadsRM, thread) < 0) { - threadsRM.push(thread); - } - } - if (errors.length) { - Main.handleErrors(errors); - } - return Main.callbackNodesDB('Post', posts, function() { - var len3, len4, m, o; - for (m = 0, len3 = threads.length; m < len3; m++) { - thread = threads[m]; - $.event('PostsInserted', null, thread.nodes.root); - } - for (o = 0, len4 = threadsRM.length; o < len4; o++) { - thread = threadsRM[o]; - $.event('PostsRemoved', null, thread.nodes.root); - } - }); - }, - initCatalog: function() { - var board, errors, s, threads; - s = g.SITE.selectors.catalog; - if (s && (board = $(s.board))) { - threads = []; - errors = []; - Main.addCatalogThreadsObserver = new MutationObserver(Main.addCatalogThreads); - Main.addCatalogThreadsObserver.observe(board, { - childList: true - }); - Main.parseCatalogThreads($$(s.thread, board), threads, errors); - if (errors.length) { - Main.handleErrors(errors); - } - Main.callbackNodes('CatalogThreadNative', threads); - } - Main.expectInitFinished = true; - return $.event('4chanXInitFinished'); - }, - parseCatalogThreads: function(threadRoots, threads, errors) { - var err, j, len, ref, thread, threadRoot; - for (j = 0, len = threadRoots.length; j < len; j++) { - threadRoot = threadRoots[j]; - try { - thread = new CatalogThreadNative(threadRoot); - if (((ref = thread.thread.catalogViewNative) != null ? ref.nodes.root : void 0) !== threadRoot) { - thread.thread.catalogViewNative = thread; - threads.push(thread); - } - } catch (error1) { - err = error1; - errors.push({ - message: "Parsing of Catalog Thread No." + ((threadRoot.dataset.id || threadRoot.id).match(/\d+/)) + " failed. Thread will be skipped.", - error: err, - html: threadRoot.outerHTML - }); - } - } - }, - addCatalogThreads: function(records) { - var errors, j, k, len, len1, node, record, ref, threadRoots, threads; - threadRoots = []; - for (j = 0, len = records.length; j < len; j++) { - record = records[j]; - ref = record.addedNodes; - for (k = 0, len1 = ref.length; k < len1; k++) { - node = ref[k]; - if (node.nodeType === Node.ELEMENT_NODE && node.matches(g.SITE.selectors.catalog.thread)) { - threadRoots.push(node); - } - } - } - if (!threadRoots.length) { - return; - } - threads = []; - errors = []; - Main.parseCatalogThreads(threadRoots, threads, errors); - if (errors.length) { - Main.handleErrors(errors); - } - return Main.callbackNodes('CatalogThreadNative', threads); - }, - callbackNodes: function(klass, nodes) { - var cb, i, node; - i = 0; - cb = Callbacks[klass]; - while (node = nodes[i++]) { - cb.execute(node); - } - }, - callbackNodesDB: function(klass, nodes, cb) { - var cbs, fn, i, softTask; - i = 0; - cbs = Callbacks[klass]; - fn = function() { - var node; - if (!(node = nodes[i])) { - return false; - } - cbs.execute(node); - return ++i % 25; - }; - softTask = function() { - while (fn()) { - continue; - } - if (!nodes[i]) { - if (cb) { - cb(); - } - return; - } - return setTimeout(softTask, 0); - }; - return softTask(); - }, - handleErrors: function(errors) { - var div, enabled, error, j, len, logs, msg; - if (d.body && $.hasClass(d.body, 'fourchan_x') && !$.hasClass(doc, 'tainted')) { - new Notice('error', 'Error: Multiple copies of 4chan X are enabled.'); - $.addClass(doc, 'tainted'); - } - if (g.SITE.testNativeExtension && !$.hasClass(doc, 'tainted')) { - enabled = g.SITE.testNativeExtension().enabled; - if (enabled) { - $.addClass(doc, 'tainted'); - if (Conf['Disable Native Extension'] && !Main.isFirstRun) { - msg = $.el('div', {innerHTML: "Failed to disable the native extension. You may need to block it."}); - new Notice('error', msg); - } - } - } - if (!(errors instanceof Array)) { - error = errors; - } else if (errors.length === 1) { - error = errors[0]; - } - if (error) { - new Notice('error', Main.parseError(error, Main.reportLink([error])), 15); - return; - } - div = $.el('div', {innerHTML: E(errors.length) + " errors occurred." + (Main.reportLink(errors)).innerHTML + " [show]"}); - $.on(div.lastElementChild, 'click', function() { - var ref; - return ref = this.textContent === 'show' ? ['hide', false] : ['show', true], this.textContent = ref[0], logs.hidden = ref[1], ref; - }); - logs = $.el('div', { - hidden: true - }); - for (j = 0, len = errors.length; j < len; j++) { - error = errors[j]; - $.add(logs, Main.parseError(error)); - } - return new Notice('error', [div, logs], 30); - }, - parseError: function(data, reportLink) { - var context, error, lines, message, ref, ref1; - c.error(data.message, data.error.stack); - message = $.el('div', {innerHTML: E(data.message) + ((reportLink) ? (reportLink).innerHTML : "")}); - error = $.el('div', { - textContent: (data.error.name || 'Error') + ": " + (data.error.message || 'see console for details') - }); - lines = ((ref = data.error.stack) != null ? (ref1 = ref.match(/\d+(?=:\d+\)?$)/mg)) != null ? ref1.join().replace(/^/, ' at ') : void 0 : void 0) || ''; - context = $.el('div', { - textContent: "(4chan X ccd0 v" + g.VERSION + " " + $.platform + " on " + $.engine + lines + ")" - }); - return [message, error, context]; - }, - reportLink: function(errors) { - var addDetails, data, details, info, title, url; - data = errors[0]; - title = data.message; - if (errors.length > 1) { - title += " (+" + (errors.length - 1) + " other errors)"; - } - details = ''; - addDetails = function(text) { - if (!(encodeURIComponent(title + details + text + '\n').length > 8143)) { - return details += text + '\n'; - } - }; - addDetails("[Please describe the steps needed to reproduce this error.]\n\nScript: 4chan X ccd0 v" + g.VERSION + " " + $.platform + "\nURL: " + location.href + "\nUser agent: " + navigator.userAgent); - if ($.platform === 'userscript' && (info = typeof GM !== "undefined" && GM !== null ? GM.info : (typeof GM_info !== "undefined" && GM_info !== null ? GM_info : void 0))) { - addDetails("Userscript manager: " + info.scriptHandler + " " + info.version); - } - addDetails('\n' + data.error); - if (data.error.stack) { - addDetails(data.error.stack.replace(data.error.toString(), '').trim()); - } - if (data.html) { - addDetails('\n`' + data.html + '`'); - } - details = details.replace(/file:\/{3}.+\//g, ''); - url = 'https://github.com/ccd0/4chan-x/issues'.replace('%title', encodeURIComponent(title)).replace('%details', encodeURIComponent(details)); - return {innerHTML: " [report]"}; - }, - isThisPageLegit: function() { - if (!('thisPageIsLegit' in Main)) { - Main.thisPageIsLegit = g.SITE.isThisPageLegit ? g.SITE.isThisPageLegit() : !/^[45]\d\d\b/.test(document.title) && !/\.(?:json|rss)$/.test(location.pathname); - } - return Main.thisPageIsLegit; - }, - ready: function(cb) { - return $.ready(function() { - if (Main.isThisPageLegit()) { - return cb(); - } - }); - }, - mounted: function(cb) { - if (Main.isMounted) { - return cb(); - } else { - return Main.mountedCBs.push(cb); - } - }, - mountedCBs: [], - features: [['Polyfill', Polyfill], ['Board Configuration', BoardConfig], ['Normalize URL', NormalizeURL], ['Delay Redirect on Post', PostRedirect], ['Captcha Configuration', Captcha.replace], ['Image Host Rewriting', ImageHost], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Tinyboard Glue', Tinyboard], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Count Posts by ID', IDPostCount], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply Personas', QR.persona], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Post Jumper', PostJumper], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Copy Text Link', CopyTextLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Edit Link', QR.oekaki.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Favicon', Favicon], ['Unread', Unread], ['Unread Line in Index', UnreadIndex], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Announcements', PSA], ['Flash Features', Flash], ['Reply Pruning', ReplyPruning], ['Mod Contact Links', ModContact]] - }; - - return Main; - -}).call(this); - -Main.init(); - -})(); diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx deleted file mode 100644 index d10688ad624022729f99a52b2275b6f96dae262e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 333478 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%0D=|R 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

    #90E6rUUDVvYYy&QM#`aTER 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�XtM1hLZRCPmL60xB613zoDzJeGU;Hiy2?2}^nVN_Rb@NNfLs27~&K|5r^(;0oOUav`AZ4cARUKjchz*0Saup--NC5(9 z9vnb}XZ?$6F!`l~`D)cjy;Pc!Bm^SL&Lgl`y!mpalYF~T2FShN$KfTCam(Dj(RoE5 zH^Sq}U#n&2m}1`ipXixN6QcE6Eyh_<`{|=**Lo5`h<@MAe1CGRlTauV-1x|$Vks$c)h~&7xpQa2Rx;OD&0{9iJ^Xa`SjszV$LOStPk|6+enA^%mEdz z5S)9Ey`kX5P$B9tT&OQ{W&R;m<#xP` z5P1glJkmEZx*$`hF^n09`lDEm!Rfa_lGzw2&+%Dh?57CrM{ zQ;km#4#;l+S>?NVxjc6UBiODUgAD<+b|H}P>PT%Lxg6{jX&n>+)M{k{Ek1S}uHFz# zw&ggmRAK<=%!s9%qa7@CvX1`9DSk-7Dp)NIE3sM$5+n;tM z{Fr|D6M?G*v`aK`BhN)}f_7A3lEB-Lp}eThs(16gi^8F`P(V$wIFq>j?O;Otl(SAv zW*@n;oX7srO>sElH!uZP$hMGE83YILHBJ&c4xB-!<`sRhy(kPyheFB5WyX}|>iIb_YxUn!&w1v1`SzVYJuC zXPoA{vD3I*F}qA1Kk80uj0uYhY@qnA9KNAyCoydj&g`GQ4l*7|oQoLe!Cewt!}3w2 z?&RbLZW0@X`EZaF2tdJv#Hu+G7a+f*$$|;&M`X})Fv(&>n;~872d&!2Aw`#mXef2} zu8tN72N2tWedp_EqXd}ICeEDS8=_dHRN?>zdYL|XV$-hnzxW*5b~#oqp49KE(JM50 zSU`N0g<0Afiuz|WBS8&eQ?85@FnLzKb+4*Xy?kh&njK`=eYJ3J&v7K~CoI6fo5Ja1RNqn!|X329SdvS|8+lpLj*!O<`5GzWV6<|SG%(IYZ6 zIZ<23+d9EnZFFhNnx=ws(2XraKo_4b`#U#3Ri%?$J>+=5Du|)!tUTxDHKM02x?^WBv!)l7b-wLApritK*Ya=8Vt_6Hfdbh&7uFvpJ3Y(%= zbcCJyS0cWGpfJItsKFm<%2I@083TGl?Tz7$UjR*5Y+Hx?xOh6`?A5^&*MOpZ89QX{ zDDv3UV5r1XyrMy}B?=)D>nD_O=JB`!?F{CfQT5YEn0UIToix5h57)Gk#JTw4npVQS zd47d?gxIBiuY+ZTPr;Kl^%J`#e3Wki?Y|{ibcW!LRKL>?>IYvi z(M%u{C0lrcWm+K|AXBCxORJDnC0dCkxMVYqtm!5KX;0&rda212$sM@#EOaQgdJ>fm z7Kbaf@Wr?Zg|V3i64k_7a;1Q~#Z?r{xl+J0;!5F)Yhg@qvJnNO~2G{B0-FMZvYBk28O{ zaYI+g`DTJ=W=1xSTull7UPRyaVuN+!yzyuMEa%Ow4>T}iq2V*kW zGxkVWHs>i82X0Fb7nLas24tu8(8}P%C!#kofrT9d8>XuomWT4l`DS42paI-Y@#U5q z=UHWrai-5FtMS-1?OI+J!i$~K%0V-L<29{pMp2qF$xw02D6Ap1fpR?r_`;!^wRu!E zZ*-nZ4@5$Ys1jC>i+mRjpg*WiXN#( z>-TYrUh-Cq)x0#NvVT5nmK1^5pt~~~cTWx4mwmX+gI^ef)-blc&i2th8JEaQW8Ez{ zs;Uh2!_@*j(F1eY4;fr{fhy5a;RjR;Guv)53$a$!zIKNvIxRFT>0&h-JvVuAnxWi$;)JADc3SahS&bx6hi z?S9rAnoc=WKnkX%l0P=KL%yUm0*saFwD)a2f*?_d)IC#(Fv7}lLP^|Gdn)_Y4OlUy z$%vF#-xbnzQG47rXn6nAQ(ehAOJ-}4@YkD^i#Js;TPa1fyL>>2-D0qG?9x#MPnhNR zj5v)0!g4)S1|~!*RxyiS6Yl=?=nX}yI7QS=%PfzV(Li3V%p6$Me1}@^H0-3Gr!%VKX>*@JK91I#Z6tzCkjkp zmI8TUr=RYwv+LJG3!bK?*yOy9tlLS{u(u(0!SO~VTz%J$!)$+Swr?sgU)z&?Mh_j; zwX&%fd4Bw2R3DgJfg*5D#(j2y#B4wxnf1=Bqb;?H(_Vr|;pv#Wq>Nb_CLxDtkxA7yov$ z)9rN)vcE@R>pjsdWTnyuH9 zM5Ugg7s)lvMZ`+P%S;Gua>Gf*GcFN0(d>LmpxMpkzA#9Y4p6c8Gf3%>T;qx$pz#87 z!Ccg^uR3)JO*@+W>3**_T_(p09CukR&d@2R^UGjdPT#1rbZL-ljECqM1Z1oh$E; zWYVge$S<;8W^#q`&7r@`)~+g4^=tKdD2Wv55EiSZUgVw20Ur10| zy0bR&vndAT^@y@V0ZlT+W+=y}ji{y#zh}a5mW^-`N0p z$r+P1aj&R!SVmnR{#y<=J!IAq&#k?^$m^H9hMhAgd6v06G^w4Zh81}TxT(ob@R92y zOKF{Vnay(*>38WpJY}TnkozF4B^wZ%udI;OARu=`3vwi5a@3*EgBWB)^v{W&Y6Q}E z5StwGB)Wa_nJ&RcgeY7F8ek*%!IHS02(aDju_)x9;z{&lCsN#pZcztqTGt~uFulPU z$#-?%`adeXL-$78%Kc&sTprD%(s>JaI^Ys#sXy11403|}lilKaU3Dhg-cw790=OwI zj|E2)bL!U7?mixoG`3@R;c5po7<#{*!99OiaC5a9f^5uW5g8FBI$JDFX%np5B3Y73 zhg8_RO@y(YrLe5TKL>yo={iF+%1z~({WifSt9-f1pzS27fnkTR=gS7%qD^@~%`Y%s zLVDyWQ0?`Ys3jRBl;FjGS&a-M9WIRs&WgrVSfC6sOVhG*b3ql?<(5POgS?dujaSU*&7CoK9N+aa*>y>oZh7voc2K>9ZFgTIWChMx|A!5VWY zwaCseDDPL=+GL9Po}!IrxW=K`zF%N0FIP8cAdwUlOLSsgiYO>=(>kMCGw?)^X1(b7 z4s5yh_7h|z29%#-8xr^hbQZ>P!CkqO*|9~OAX9=~?3A^wZrm@ovTK#Gu^=Z*xa6UC zfM0SbE>~Pv&+ld1Vz1VYDx2=*Z2fq>ax=Z^qG{XdmX!+)syAA@v;lH%^^|e3m=k8d z3Rh2imH4%T!kZ8;Y}HUFzlgl#)McV2SVnl3|iux@Ue z^32T-JHHa~rKFSz5)scZXR#l_7*{%BGp>@BDKa6f?o}b49>|BU&YgQ5$R!uG5i3w) zWPsy<&4I9nOX^F4M7@OA7=0Am7ZnJT#arlUT=k=clYtu{+)l><7eXI}m>C%7ufxrh z|5h49@jRfK2(5~pqkzTxjGsX6depRbdV2NdGMpszb7W}xGNkDMp^L8;x*oN5vpAL7 z7kQY+J0rCr0>X5?KOER+iBO(;A_)%|fv6(b`X&Q3@Hg%Km+gsvnqji3?A##Te?7;i z5-n`Gdxc$s`J#GT&sGhUr5ME-IV8Qe6ARcPYHZ#{5{AKO?`k+Gs&5?)lm!AB^6E=j zjD;51#PGFY;DTEPF&@N*q`u;flV=_rQH`Bj?-yW+1YdjS&aHPjn~PuN=@JDV zNF}Y`L>0{%`iT0Whyfi#K&W_|`q%p>k=T5MFK(Wks72-P!sIc-pAzdM<&3LsEa?E> zDh`CsKkKNj_7zRjTON%8R)SEmA>A@M;KqAD?KOBc?%jr9SLf`4v6Ik|nN5NtN3L*+ zDKmplxoKsXw`I}5!+DE%H)~?$5Se{Yu_Y#P?3U6YGyf!B?uVtDFnDO!_yCMo(OQN4V7A(kEb-=+%!*Tl-pN!|5__|+m$uC?}Og2 z+j%g03lZAHiQHCj?n9@u)dF}z0%s+d@^P<(K9ez&K8%cn)VgnMNz_I$cq}AQCD*eD zER3>u*EIk`Dt7!&z3ic@n;pJ~m8HmQ!X7X2ns10B`kwiP?bC^*;;oq%ore4)Csz_w z?&|WrcEIby^m;n+n}D82-iwCrpwA^XT@N`cmoEYQT>egHl57xW&$cB-hjF%w{r{c z@Y@Ja%{dIuW??b)?qp)g3)fXK#d@@hl6DYJn%y`cD}Z$7uope@OVtJPFF`zj!a!oI=5=?Jza?;^V0d5Lm<#f*`cr1uFIRiZaD9#9h*gHl0cwp9I;c( zAy|z$sXRv=3!GY9T(R^4Q15n1Qcl{giZ0`Ji!cKlAOsdYt(Ntq+GYP~ zMsu01g0Q9Pk19jx#=ACq1;+F?Uw3U|{48qPA`AZvRY2HnaaZbsRI|PzJzWD@YIe#(>C!0FOGu@dZs^w(fZ(cU`EygD?nb{Isdt zWX=A(T1@H&LMf;?3Xp}ZbG9fAyha_FQH`-D1FAyjAC1Rin>IY54q8qRnvd#|4oVMj zvbO$DJRvv5JjK(do_}KPe0;wQo64hI=Qx#6696 zUg3t&?0WnZ+B-&6r@8Zt0$hhYLbu0<;0>t|4q@0VUpTOM$c*^MJb7al%lrrVlTotU$IqLF-<6X}xyqW)oA`MPKfl7yukrI6{QNWMyvKOr z2QN_!)n}xIm*vH7aRCkhhk-6$#O}d)kq6a!)(CsG!YFJ=!TfSX5frm#U0&-cn$HO+)*A@J|-4_{q`cBOv}bV@oJ#^X8g1Z|XLa z%gQc6hX&)h)mv*?z14^95w#k%MhS4DEgGObi{t`2q+Kx6iCdV zgK6bl>@(|`_%eEv@)#HOl(!<+W@eL?cEor$6b&hn{c1jfOTmN)W5quiB8(Q<&9hLw ze*G68GK`s&jzR#1iB+KvgTI97#DN_ZlrOtJ>pzvM4wOvLQI4|Pex-awFnKmS#p~Nh zMFH>Ysll7+5VqWd#iG2tf@%V}YN1jnbcwBQff@+D8u1-WBgxr`uS#`*1Q`th8+38y z%;=PR8UrvS?HuA2swO1hf}jfbw%B;e?*_4jNXO5ktbTc}`hic@7L5_cbh+_B<3z4~@s4cG= zc`zLstS?9uy;3tuIx6lawKmKN?P|GXomP;m*xw0LKt|D3p^&h0afJg@OWI7<(VA?W z+~6tICpMM3go;S!^LaIOF%H`a3)ab-TSyQpSS4tX6Fq~C*D+_<9@#)4BYkDqC>ZU* zV@fE2TzN^4H)FDKr*3n0%n;3TSNO^dl|oDxrp>A}!V&cdv=Jh-p_alMM=oz)f2OX&Wreq9*&+L(@EEXV6XCq&v2Fko4Rn>*g3@Q*AWmd(9u&K$MnWVNcD$)b#}PdQ_skCWw64Y@^BYCe z^V!(ouX%dN#bAt4?cQ)~{z3@LWB^J#?uSsS08K!$zpx$N`+xrzj?{<5q|3)1@@gLs zv-s0w1a@LYTyi*DO+_@yL`d}P+gkhxJ&RyYjFUuEe+q-R2kHZB_J<`$j6D8<3hGHwq>yt z4Fd_3*$R;N+LnJ}zON}>8lmHDy@cta$_H*7iir`~<(T$pfszYV|Fen~3ZEqw3f3Lp zW{1;&n>cJK_}c;S;CWdtCDzu8i?Id4ttWrbXg zzOwz1k$CbeG9DMuKG2B=<~wKL&X!NGx(FaqkX^8;7R<9Kt;l2<`nC;dprR0Rm9AF& zWg;brpfT!tz;rFSY@%mtQ!O=t>Tm=WoJhr}hZp`k?1g z+d%Txy@b2CY>zsh}aJszII98)rAsl_LRN5gG#bgOMtHupz*{P_S!9Ufae~ry;!F)kG-hC0!kMa0Bu@ zY9Y<)+&F0)s-WXZaNwnuorrLKI{n67kE(Gi{D7O(vBQy@wCLYB92pai+`Nrft~)!* zNzy8bpoX%%N^9~gR>xqFHnA_u3yWEFyn>?S%25cwp@Ey!q@wD{;ztJDc=v0SF4U90 z%Yb{8KSL4oPTpb!S1W%mP>%p1$xOi{(t`=?M#=(G(X?v{EVUqW>4-a^#xY19DM?5- zdWto|%M>Fk*)ZK}N9_u4uHvv&LKTPU#+`WQcvv$hTWi?jrO6lUE$oa~=x}Xn-_uR7 z$d`CE#gkRC^=IbQMlEMmCH=jOt_0fIL}Ik?*-&EiSm6O1VFtX4ay|0Jipoh9CF>>y z<4*DA8kOqEsUrECyh`gG<8AVBaXi}5B>6+WXEJRl?iGEK*x?)8mOr$vin|3DX&Id} zt{|&AL&9#^nB3nQ@YIv)@fbY@40OzS&C?OiW$@jq9*_FxrOHE~##B$v4p3#!Ko9uhUtmRWwg40F9_lwR7<8B7 z1P4QI7DKqB-M;-{OLXH$N{c2IP>$xhLsZ5Sk|`2yO!NZokE>us+~q}R zzh&XY2|5xqC>TtfP;iS_{I^ahn2=C#%X|xS0N{}b3Li~Q^va{9auN>sj&5a!%f+~d z$@8?E4DC|qD?6&jkg%k)?P5rii7vJ1zBbA7dNNFnzTgCVjJBR%1+l^~hj?C*4>#bvqWC`E8Pw(ee*HzOIx945HYd zQJO@*kvt=!nLCb_TJ=nXD{ZV1@eAdBmbFGhwzrz>vd-t}BV`N5+p_u@8YzA~g_wpw;^y1T`#;!Cq7 z4LE?VU;v+_1BTq1L`dCQhWIg7;j&s3yYOk2WD#H^6N+rVGTk7QrH` z$W6g#2_jrK=kA>4t#dZ^dp0M9J|Uf#P0zVw!JUo@?4G*k)%RWY)S=qIOS1ZOxr2hf zS4YcX@ICj<8|vY_${HfmKXkl9;A_E;1zxf`P8IO(b}_Nc1*lGYErv@*-Gfal8w@d* zM}a2@bal1$7iM!Tn?&t#Y`yK0H+>de}u z@52MdNg(Rw$h&!UElc_Dvk(ZfNa6sBU%N4mPI7{PJD0D_8c~EZ z0bQzwoD;9DlB=Rd0Vld2X62}>T|eDGU%U1L|6EF4cuZ33*R!J zOqU2jo1Q<7_A^bLEZx(A2wXO>a9r%O*(aOna09V$C2sz@Iz&O}Vm7KytHnaNn0YU; z7J`_WSz=d76YQ2{29E4oNtu@G$e{O~p9>~hiuQ#O6%K>Fp}8wD(wj*xT5NigyYZ;x zxPFLkc)N8Q1mhdwb~pyuTx&swFW*4L24?|EZEb#STOVc}ebVo^9lz-VbR)M*U>&Gq z?2_4t2B@#>HgEE#`*wtJDNfhYfN4Itoi~8|Cj0AZq^svQVsPVC&ly#xbucWJ-z$ga|B)W+2zr~}g_!-%%9+Qe37XRXZs z-JE%&B}98G=~&Qqs@MP|!2*Xc8^Av8EtcuMEj$mCA~K~3wQnA~bbr(!=}n`k&vx8s zJ@X$VPdGRL0nIvgrTo7fRcd#gyB*dO z)?wGw1C4i^xr^}~mQ!9r%1HY0WHFoIHMgHbTE78qhct5b8njeDp?wRFIJmA4Mz0|V zvZ&R6{-Uo_lpv1z+V~zN`3d!t5?sTsen?2cS;?MSBq}2kxS{d z>Sa4!C{Xd(-W~)U$+p%s!10F;5{r`Kp+T-!kSHD|g`IpeZK_y}M-3^%AyWEIls9wl zcyDJ9GiSbk?{wvgReMK)k2ojOuH0XLMvMXm*a2uV-f~sx5?KjP@m40Pm_Kn%8NB50 zb#-AiIqY1%M(}y4h8i9qqMaxBOv_1TLBVps?n;CP=Of34bKCryb-1)=IaE}w4aJI# z`W@Q#OzP>Re1~zUG4biRI>qq7Ha6!!>e2EX;>*IzMQlM)&?Hs=_~dq21e-SH-hnn_ z{%$KSu;9q4-QK(HL?Lm>Qz_$Iyx$pD=8TlHO%&DDSaiR@nHBv_;lUpSHn@n)fK6=| zQ$Y}B8^O8T)oQmj;bNVB$ay6gySridd_zaiaC3x zM9JKHBhj+iW&=f>r(IZv9_C8ev-yGl8XfylQWLWS2h<+w6QCN#6%sA75#D@!32&VX zYE%S0K2$k$oseT=r_vrQAa(`brm_T9C%@;;0so|5q7XQd`ZCU?R2IRT1qcY)BX3az z7dw-7Qg|Tb#(a`i!joP5rJ)QTd{=k61k!GA?MPIo;{y6Sp_p$`kh5*r7+XH;21@yq zZ~cq@mylvzX+t66OeWM89X0N%ZGZ-Z2dE*kbGF5YUT{{aK19}TThvZX1@}p~LD?qP zyFzhEQAhbhA@Aa2j|-JTyIF2mJ`QmcG0!sa=yNL*C2a~dk{d}ngk8`Kkt^#nQAowu z?Whi)#rBi^cKHz3Ha)@{9%0fID?Mj!Iy@Uv!foLo<^UIPQPIkdfeQLNX3i{rLVG_q zcU#-#R&98>k=e7O>Zg}a&2;C6+fQ9RM#Y=k+rsH#2jhnoo$dZ|QBS(eaF6`e8+sT=E5_TB%ik~di-UNKUJ9~(UW?mH z&P|V2ZINrafh8Nt8XL#>8z^%$irM8(HHlAI<3~>X@ zw;4$~QK~Io@gs{e_ld*XR8@G5?6A9YBIHOC$m0755p)QJn#hG!6ku)EfkF@w$%rs6 z#s()onHlYRUTq|X^NrmEc1L~0xAQU)%_d#0 zHQ2D@NLmi)5m~*46ap#yZI*@L2|vq8>`kch>Y^r7&QbPFG7OFoceD@KCU)niUQ{8> zb|d3kFaE_7;)gsr$3pxi+WIRr#|Pno;)C!&@*K96i%Ek)u%z4JlSCA$DwrPZ5A zBjts1Ob%gHno=pLbc>#Qt_gy(Uh(5MqEh%=KXT$yLI%5!$=UHT1y2ZUBV*17c(sD4 zxoN2J@W^E2{pjF3s{h-nN)-GfZ#Ek^KH6l%SGLTRmbG%(vpg?nd%AIepp1#?RU-r` z6wZd<$#j;AzvJ&cUa-?_)=?^V8gU-n%k%!Qs-5G+3{2r)Sr=HVh{-!JZGQRC2>;&? z!8Cp>-@PCg-8SI`2Mbqt`xaFM1iHbckYWP)%p$w&V={3g*hSAXwsdJ;;=P-o7VfF= zTyHvAr*z-0v`6vt)j|4P<7Dn>JrXf0Cm@1vO|B)5S81gKBU(y)Qpoy9oR9*MW$hc# zaqjCQS6QSp0Kh*LBe~X=F67EuJFQBmzXt@X7KOCk3teKPmhyUkIqi0iAY66{!4%-v zNuh!%=-3Vq4AXF6i!bjfHJ(^XZ6Wm`peET1L`If#6c-h;7(nd$m;jXK! zjM%`5esheuA}Ydo_>4t3X2V->T#H25e3+c70uS=VIkb@5r*^hIz`%Vq5F3W*+#XE@ zqMXa^24#Iu&M8Y)4T1}(QPfj6iX9k**g(V#AK0<3Xeic63M(yE*Br!Tp-T%r!~=mbncReIDY^X5ko#!fV87d z2$7!ayVT#dbf8ibgO)yADSg;AQ8t$R9iY-dVK;W06~bl0$tz{Com-FWxYh`xe1X13 z5>=~hiN!uY=Cwh}A<7vUTo-7zZpWxBFc>!}1kli^JR6T*R=-MY?b0KMXp8Dswa_CY zQZ6h1(nFCd_RB%`5Gs!WHXTox1~ftk&i)4nfAt`l4$xY?KtK+>c<%T6irsS)97;sC zY9HN|p++)BQIV6DTm7!wq%_j-63!qHNZ{E35pX?R*u;y4Pml*7#O#2}@{N(uma`d# z9^dXn*LirYqQax(Df8z6h?37gdBv_YdnL?er!A?E+Y9KLAtrYh?Rx+GJ{?#5xE z(tZwt8rgB}5^C>XK|0W}5nVhPk+avVUrI2Umy5<46zV zcXPd74PVmW`3U(ahG?@Ig1zNufoV0m_F2K1%RC+Krca7j8Aqx#Ej=O&CAZnm zs^v@GZ**nQ?Z6dc&vIiSQfwUA(%m1LUIL45aVWWtc^akf= z503Ya_sZk`SHsctxIbH*9q+NK8R|LY3e?Ov5IX9BD<}^{m$6se{>m*8$R$l$vN%>LM5}X5XM?ZH^PwV zF4QsWtCel=zHUAU#%V{gs75P8IJ&|LX+he(#7diY5K+bK@h)nF>{X;++uh>mWINZf z3{5}WR4 zrmNH-aX=-^h`doer4e-v6;yD76hw{~eqeDi5`#zsMwYI_q6#>&q}dwgQ^l0VvUo(G zEoEa&isSg;HAks>Nt*{}WWPPZH$+EF$)H}{JfFUr&3%pjayAc(d~dZNwhSmpV2h~m zT~2KTm0S*a_~Gxae z!p|dN#@Pqi2;cCk;dfa*;g%{yf)qw0ZSuoY7+@Hfkv`okE;o3{y4qVo>~h~9 zU4Vu7sdk&hNC)b8rVvXvfHJdxySJkdho&3F`gJr29qu4RJBV5+RLthw>jDz6)2a)OnXH7%BG~4#&s(+#R)5am%=9goFPoa6|;mJfQD{TS4k zq9QIB`1WT8nypa8Ufz0u$ygl@aY30vNZti15lgG^&+k}bUTcE%T53{Aq*gMaXCBcj zd$zluD{!=?B3wfo5P>K8qj1Bzk=?U!wNJw33SOJ3*sr-+%l#}Temg3YhawUc!%pvd z)=B{(TA3>RGX-F~5tclE(RFMgSW1ug8^yNXIIMLGuF)YW#lr)VS}=2oj#RVgEJRag z{C$D%Eni}$l*VKOrts($9mgWvN47+3X4WIO{^SVb;4b8&mN2Ypo>aV>Vylw1XHG6z zJ#t2q%p)doARHGxjYQ)Qe+Y{ZSafC9K_3)bFU)eo{o(ACiA?cq)~9O>`~}w<_CkaU zT-4)nF{p~>O+BAu(usIr2Pny?=jY4G_`u?iR~pfS{%p0RGzm^+Bqz1TNhpR8Cd4@} zr=xL&_brVrlhPYc6c18qSbF{M>$Mm7D?YO3O3R+FLMy=r4R1;|x z^qFnhKQ&nOu_rZ;uZ~6>_^;7vS)G)c_)riBB8nU(0H&mbQi4Bgcnv$_Hnh5TN}=G` zI2I2Db2dxAi)YpI&-Juf`=$A3~j?W;2OVUNN9u>4Nb|HA!5uB z3h_C5$+5zdhi`Kj=+j7e>|!+HE-Wvfa!O*!2dTmBK-|dlye!vi<$GDq7YhA(?w8?z zC`B^&;{{dh58tn0etGt18Q@g73mf(aKiipKXrmpgLOHZ+D*t23$oi9cCKEoyip0s;@%EXq8zSNl9iws6Mp zy9_9PMn3}F$AX*VIszIDAOVDX-W5Uhw;fE3!ua*=_~`GK+}2LfnZN6#Yq;U_mvo&E zIbxL))l!n$o1|pM(%8a2RX12xWXUa>)b4*aDJtj9Y#VN+nJMWhi?9jVsof49RsCHz z39@at0v)yYj4A3S+vbLS6G>x~>)j4p#$dZTU93R`k;A^xX?(<4TZ45=u>k>lA7b*XL@NLxhl~(Rqc01l6!Z*r1TVC}Q~%4;d*nsHMv} z*H1h(veV?Q`(~D0U$M&He5r}OJa}t_FED2&7x`C|dP<3%SbRB|{{o9>r?Jk&11m)a zC~cMzxHqpFJHQT$)nJb>OeCBbz#Pm#X|LG7alwzFwwlWJW;^rY8-hr0C~5E@}`0HMv30<)yx z{1BYI?3{|bdA=YA=#r!v^cD74;h+(dLcqi=hF7sTEgMfeZ1Y0|m<&MR>N7ky1!g}2 zPQ3!CeQ^)dzc}yI-hOhlR5eIR;-}og0;V95MVeRompTBa=j=l~ymFZhJ<6tAxB8$> zS|5|ePJcL?7;K8~iy=-TXxp%ah!uGBbJ_dn$zFYid)A}ijWnE~n|m!OUv|3Jt}Wmm zZu{g@=M?@H_hhq4y)@M17t$fYZD*Iw$JXz%{mA-nL+rNqM>irAN?uz;t+elo59!_g zC}Al_|59?1CSGerBl_ng`oON}O*Bt8s3W&EPFS>p$CmsEqr=opZP;m_#3*1~6wJk2 zSnd{y?6};DAJPCv(-Tk7$}S|L+H^9`ohRC6-B%kKCia3MfKzevi>&n!SHyt6$(l*< zK)Ug(Kxbg!QLZ1qh#S25SgyQO11B(=LD}!W$MX1)$G_?9*dzfaM_+%Bxw$CKzv0xn zPEdroEz#F>50XC!%Z_dHPL><^asyTFw*^W|4vXAg^oE8y$i|xBFX<3eTEdMJ&gvq- zhRxZl$%ImpL0OQ=EziR_Aqamj(GR1BAm#pz$d&kbi~8)(;8 zHk{!4dHIaNfxmsmRyvdD+;t>QvKae3R$32c%jIkm>#WI(b2fh^F9i$nL@8cWE9#AO zg$}T)MQgKB#DZk30-9$xV*&zsRmBtz^uV`Ck0Dpx%_3OFU~{-8?Y+8gH@;iIma=+= zXtRAn)IWP3Zja&09KwYrlT@lGp|QL?R*;| zFO&|M!ZsCXiSe?Um?lR-j&3!CToeZpWj7fOR@j)ZmfCZtbukIB*5Puo8k&`^QuXB4 zQfm=7qNyl1n1UOWfPCjVj%aR{OG$(TYN2i!{npfPQMv zj>(8ZvfTtRaqvl*ZD(Q@vYKCOAQQIKVi|b*NQ-ccePWYH>O5523YNdm)uyl^NL(S4 z=J|ZliEr~rS?qB>yl?g!Y~u}OlfZAXqtxD&9+-(6p7m>dIz{iwDNVx1_b)^kp=pt@ zZWjx7Be3;7ol4zdsDyp(mw+6bp#d-;!EYIGwZ)kNE6%#OSKP=_GO##+2ykY1+`6GL z;D$z9hTDsB;eAT%PBUP7y}hl}GytYxKD9x{T&j5^Rj;a7W%H(cI&F7;-Ux?24v#eO z!tjtWTFLSs{1SH)v_(Mgcc(5e;NWNw8D_ZK^56&&T(3vPen+b0@1T^~w3=OTUzISy z7uE>=IxE0}nEs_33NHrN^h$Sv6_{K4c-~RA*+D(EIAV31DedR((ecI3$6e{}l; z%GQ6-`^`M~uuW=y&XxR!7qju@X^ja#LNgcGD)u!tCCbteA*(=^Qw~Z$Vhnn;oP9T* z4WwJmnfYDPSop1b*@fz+BMuftS-Bu}4HGLe!N5}PL85ejGW+L`^!gAZ(a$h}M_lfr z8oa5OK~YU-XoT6w^spNrmeaRo6SvNjTT55hw;>P0!+{}9Xv$ShVec+D27h=!b|H^m zBY8uTwyM81&sGcJPiuY@ckNPvdiST7KXjAr3ne94e3eVHu%&|Y6+$TjX z=w~D@{{0ZlsMyHsr+T{l_Q7INUUtW#sxz^9O}mp5t==}j?-VZj`|CvXcWC>lwn1_r z^wi>^nbZSAT@%E{=WraLbvB~z5wvllL&pPv4)7E6w&I2A-hAq^^8&l_q$smH#Wo8! z=wY>78lg31hX!kFUo$HlQyj{p6Iuxl4M9sm&+QL0SfAu*S%G?zfQu$rO!_Q7SeggA z2m|XH2_9=F>M2Df1)p;_p4fGHCK*Y8%iKbI1Z)!>Ln|!}lT` z(O(*LHrz`O%b%9!zuv{dV6;q7tiu0y?7(D!dO3#HzJict#eWuwBIlSUp!2#k+jnT# z>GI%q%6imH3`PR!SIiQFD`q>X;W(Sx6%opkZ|ox!XoN`DRwUWaT!hlbe%8H|LM zkJ)6#q12vBX%e^9o7fAja3u?ltU+N3A(Zf#hXIzgPtEr261Mjo)@@_RmwyEoVD?oL4{tk%`p*H_-tG@J*?)wyqW=dkyPQ(<12=u zSS#o`EjtEd`LUX=yjCh`3fO9YUf~7D zGscp0-PCYVjp}6suS)mOR5fhQJbR2^?(CKK{xlsl^Y{2E3YvbX;L}NaK{JpF%DsfY z4yG9YmHh|FqQ#a2s5bD9+-o?d5pQy^a{Jj*aQH5CO0y{fw8$>Dd4pAS` zqqNAhm&3Xq*smLjrCLA*erU@3Z&V*Xw*qMk9FGXO%&y@LnvlMZ7z4LX;_8HQYpPSB zRCPqe*4k7gs)@L%D`Lc4B{WWHAGpd$x)LfNSHtdPrR{j_v>kz>=QZg$%onZZ;8s}I z^IB*)S_E??nr|)3K@aeko9drm&d;l93ED)!5$XA@1aw<|8J21h!8ONND~2FOb=f*IbOPvac*no42TuT%h zt8mpYKrtN3KQWz6D`iB})dRa94D^5+g;=3|gl23e>RkX~*SGHlETZ>^s}K zXNZs$FVsMKy7kRLr(UV9ew z8-Ku)r||=+uMRcS7v~~8HEBbJ<#c&?IUQ=oXbPf4fp3j4f8XrN@@-XIn!}9K7GM_P z#?(Du%%%`8!Kpe1)$*c(Ol9SuQ7I+7l9!~FaowI7bj#}hrd2g+Xre_!GcA@g%uWJh zg=oje)5lX(0@cgHpaoj^Hy9SD>k>De&zdD%R`r|txHeGlceaoAPf&=5L<^u?#VHOJ zvx}x$bedwmsNa^uOFy^nq`ZVsI>6`6{wW*CiLiu7JjYu!KG1g?x!Xv2Mj)Tf-qaw5 zZ}+#CKU_A&y~5DQ=8fTxl8c7!zi~rg zyw#~s7j#A0s{T?J8SsxTGhUi=CXB&Q)NY3ic@pXgm)NTFYuVWiURsN=gW}dVH^2T% zTS%cCI>~eRt62e8I%Z6`u!f497N?8Zr0_>6I?-WD4ub~C!`P%WG6|$Qg{6V>(=N1D zH0QI`cvQ5W_s(VuBiD@gR^J)qc=N?-0DpS3MSWIJlYL0PSygUOBC+@raIV9#76W$hgo^MGBU2byiJB_jtGlTKwS7YHSXs=0luI{j}tL z9$&)<&c?$03Ze|!k#5t3RU8b&I$I!<9P)#w^y)MiLWJ)9>8jool>@qPW5(QWr~ z_+8geEn_I>7?YcjlLKHK6K=$`&WRTaStKOM3@>nRLiB?8fKHbnz8d^7Gz!m*wL>!O z7|z6Rt8tV8rVy3kv<-cp$VIVnSEC4f4BW{3s>C>M=5YX8Ys3TZ>uIxuI~7CT@p3fs z311iKPRtT6ZWjx~Z)90ez66R!jph&=^Pbk44S5j^{Qzd>XqcG>)3AH`f!Q3?Ofxs! z)F~hR&`b?V_4T+bo^oBNBzF@J+nEneNoX>iDH!62Q8@EzmA9%9JPGomdrixAG&hAQ z2Jx}e#n&m(QAG3h*Yc~K0C#3@^Y~|u+VaLhq$xPcR)j#fg=`W0C0`?kGdkQnflHnn zA^Le_w_yqH+@*Rc48)RIg*BIxm$a+F440VH6|GE`$cP`$Q9LvZjUDD16T3ZVQM83K z0vNex3hX{3Ufk(D2IEd>c_2GLLC+lKTv17b{P6wzfXga@iIU!Mp7{VMG!eq_Hv5Kv zs!1-f&)8I-;caoqAf6mDi%`?0AlR6=2+K&~m*%o5F6zj|lS4}|_=UsxFU^*1f`BFjMret~IS&W;#7urNTU2BRXlUq=8Y&2V8*H4^ z=x|&zhl2B}T_95m_>1~Yy~ktgJ$dlAq(o-BH19zs3q-LnoTcNpr*Q~M4Z!QTQ!(vR z59#=pPky^~0%ClyP5psz*CGlQR@y}a$f=PnS(kEVdYdVr$GyHZdv-D~^y6)t zFq{mN5iCr#t_y9-1yvJqzNK{{3mqJc5N^M;N*xcuE5n>srmJ#1zU=87=eWHon2*`} z;IYiddWeZPD@VB9=d27U=a7m^P%P@7WDxou2qCm+;kkpYp%0w=yBichS1teApHM{d zzq4@F$^X6tn`dg}*=n*Y8{F01`+SI$j_UL){QMdMfG(>rwrntVlr7HsL4%?*Rp5mW ziR)XUG>bO^Onv$Y5LLAsT&bAB6?b)sREitZ5N=Fb&nV6nCw+s~C{{yYX(I*$MPr*0 zO5x2(-J*ODa*{iDt)Ye4Bu$sXK}V*Nax3WXlEq_wFg5pR^m^pC^vK1iZ-t}2>WDw& zSB}E*=hqG2f845lwfU-j)w*h5rB+QeK(kI5xj6ScERkxZ1(r5aRciSo1DW;c@U;f% z8f5r7iws|f(^vd{nMV8U@Wau z7~5WM2t~6uv@+zqqxK^nFqy1p=`~x_+ZZtkx*TuJ7Rnp$B58vNHjJ%Cj^WDU%Ja}* z`MXRiHN_=cJkV)(!eqBM84E?0+i(*p^FDI#LkmAr#{-Y9dP}?<;eoW+#Kj{{(Z}C* z3<-DX>qlF3`MGt{J&I7IBQ|a4B&}+VZ<5PXaKy3-k0X*R50|S!qXo&N93~|bR^VC- znd}uG90D9F;*W&Z?m9$WG-o*s<8hNt4)NGwr*Hw+8UB_l!`H?5{D_zU8zG)Vo6q0F z%`VVv;FBr^LXjN~<5{+-pcg5Q7aDyAy zd0>!XKwE|gSZYHSy8+n7E4cwI>e}sw%26;VJh7JUBI-i2d27m*-CyLnI9n}I=eR%* z0eRNG)@5%*Yr;>-#n&5oV0r7$EkkcmUuj6IWB#=vY`n#!+xaiJu;d^_{+iNe{4fvA zL3(^yfWhj;0>YyjHVa$^Z?IO2>V8KJm_`tCSprm14$%3uAMx67f&?qxGEWR(Ug87k zE069LGsIbWmr#WVr)nW|g0b_lCN|KT{m~^#h#20j`lQ(D6EG$7HywoRhf|GYP0?F{ zM44BL(TYx`Q%bJVR~O--Zj+Xh8)#O;VbwIJtFb%h8Uh%slNt}%YxSMRWr4NA$gp`+ z^(&`%`(yyvtJ^-lgPsjJEr)MX_u>JqVAO#>51LnI1mvEowzdJO!FNm|B<&>1kzrtl zNoRS0_odwR@*g+me81@GQ(Sj0U5GZBymx5@Mx{>)8k49`Tx3$tV_DQ}qyKgOAb5IHA)Q8W~?P(E^1&8)Z2`O!) z@>~i>7$P|w|O;I`Lpo1dsI3$IQ4*P`{4_3=r&qxuatFOyZT(#nG zygG|tJ{Vt=mknt%;ccYi4Eh9h94;PD%f$ z20ubse)QHH0%lD(zqeI6E)FT>eM2qFN5w11z%n&7s!8?(G^2P({8aRXRwL)tq6(IY z881X@gVGoc4zm-(UWCvgO};{5lO(0E1@j#uR`LY|6#B`q470v`Bk^`WszlzWZB;;% ziq{4~U9%L$;c76can_hN%#`HI5i_O9-0b0KYoI|g;gFf{GsyZ|4xj;ifvt$=;cjvF z4iLhLmP+46WNI98M1=@!n8d_PZ(L8YJ@Gr*3G|LLp7_H2AS!NP1_FEq`C)&Bl2GNx za`6TpVAT-CZ3QEt1vRKR7>${CnOYAQv!>~>B8S_z^;7RuE30Y!>#C|pP=mfdeWXiF zX86+J1;(LJ@2ZK}9Wih*R`%i&UYw5006de?*EqaKU+d>!9r<`NUta$0r9+Dfew!tZ zONv6N*X$AR%6MNxHBPj7H)S4@@wI9OZc2e`HATd?wg6i9(y&2GetSRpwx z#1tuTBPbjNCr_2eqG3s0@SoLU1|l5=te-INlA zK}!Z@Aj@vRpwTFq89LE^e4+p&3vV7om=@jK$MepzRK6Z(@#(<8Aacp zJ4f+5P!_f9H5-`{+UM|2et7X{U$h z_33hFOZ0JL7n2;pSon$gsl8jGQLMY+0pKF6IDmfg(pT)g3snsFHLGC^SDscuPFrzJ z5&Nst&478{a_y$Z&o)$v;YR0WaUBs_RKY(Vv=l9?xO8yD#fI#0pW?D4VB?$PbZs_j zsI3`YPj+oErWUZO3m$ui;>PJ>HTft0USNCMckM#K$bZ$lVYQeq55%ygq9-UHM5kDP zDHJXLo@N=

    m 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%0DIu2Jr&*vqnE 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 -* http://zixaphir.github.io/appchan-x/ -* 4chan x Copyright © 2009-2011 James Campos -* https://github.com/aeosynth/4chan-x -* 4chan x Copyright © 2012-2014 Nicolas Stepien -* https://4chan-x.just-believe.in/ -* 4chan x Copyright © 2013-2014 Jordan Bates -* 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 -* -* Font Awesome by Dave Gandy (http://fontawesome.io) -* license: http://fontawesome.io/license/ -* -* Icons used to identify various websites are property of the respective websites. -*/ - -(function() { - -'use strict'; - -var $, $$, Anonymize, AntiAutoplay, ArchiveLink, Banner, Board, BoardConfig, CSS, Callbacks, Captcha, CatalogLinks, CatalogThread, CatalogThreadNative, Config, Connection, CopyTextLink, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, Embedding, ExpandComment, ExpandThread, FappeTyme, Favicon, Fetcher, FileInfo, Filter, Flash, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, IDPostCount, ImageCommon, ImageExpand, ImageHost, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Metadata, ModContact, Nav, NormalizeURL, Notice, PSA, PSAHiding, PassLink, PassMessage, Polyfill, Post, PostHiding, PostJumper, PostRedirect, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, ReplyPruning, Report, ReportLink, RevealSpoilers, SW, Sauce, Settings, ShimSet, SimpleDict, Site, Test, Thread, ThreadHiding, ThreadLinks, ThreadStats, ThreadUpdater, ThreadWatcher, Time, Tinyboard, UI, Unread, UnreadIndex, Volume; - -var Conf, E, c, d, doc, docSet, g; - -Conf = Object.create(null); -c = console; -d = document; -doc = d.documentElement; - -// Workaround for userscript managers that run script before document.documentElement is set -docSet = function() { - return (doc = d.documentElement); -}; - -g = { - VERSION: '1.14.22.4', - NAMESPACE: '4chan X.', - sites: Object.create(null), - boards: Object.create(null) -}; - -E = (function() { - var fn, r, regex, str; - str = { - '&': '&', - "'": ''', - '"': '"', - '<': '<', - '>': '>' - }; - r = String.prototype.replace; - regex = /[&"'<>]/g; - fn = function(x) { - return str[x]; - }; - return function(text) { - return r.call(text, regex, fn); - }; -})(); - -E.cat = function(templates) { - var html, i, len; - html = ''; - for (i = 0, len = templates.length; i < len; i++) { - html += templates[i].innerHTML; - } - return html; -}; - -Config = (function() { - var Config; - - Config = { - main: { - 'Miscellaneous': { - 'Redirect to HTTPS': [true, 'Redirect to the HTTPS version of 4chan.'], - 'JSON Index': [true, 'Replace the original board index with one supporting searching, sorting, infinite scrolling, and a catalog mode.'], - 'Use 4chan X Catalog': [true, 'Link to 4chan X\'s catalog instead of the native 4chan one.', 1], - 'Index Refresh Notifications': [false, 'Show a notice at the top of the page when the index is refreshed.', 1], - 'Follow Cursor': [true, 'Image Hover and Quote Preview move with the mouse cursor.'], - 'Open Threads in New Tab': [false, 'Make links to threads in the index / 4chan X catalog open in a new tab.'], - 'External Catalog': [false, 'Link to external catalog instead of the internal one.'], - 'Catalog Links': [false, 'Add toggle link in header menu to turn Navigation links into links to each board\'s catalog.'], - 'Announcement Hiding': [true, 'Add button to hide 4chan announcements.'], - 'Desktop Notifications': [true, 'Enables desktop notifications across various 4chan X features.'], - '404 Redirect': [true, 'Redirect dead threads and images to the archives.'], - 'Archive Report': [true, 'Enable reporting posts to supported archives.'], - 'Exempt Archives from Encryption': [true, 'Permit loading content from, and warningless redirects to, HTTP-only archives from HTTPS pages.'], - 'Keybinds': [true, 'Bind actions to keyboard shortcuts.'], - 'Time Formatting': [true, 'Localize and format timestamps.'], - 'Relative Post Dates': [true, 'Display dates like "3 minutes ago". Tooltip shows the timestamp.'], - 'Relative Date Title': [true, 'Show Relative Post Date only when hovering over dates.', 1], - 'Comment Expansion': [true, 'Expand comments that are too long to display on the index. Not applicable with JSON Index.'], - 'File Info Formatting': [true, 'Reformat the file information.'], - 'Thread Expansion': [true, 'Add buttons to expand threads.'], - 'Index Navigation': [false, 'Add buttons to navigate between threads.'], - 'Reply Navigation': [false, 'Add buttons to navigate to top / bottom of thread.'], - 'Unique ID and Capcode Navigation': [false, 'Add buttons to navigate to posts having the same unique ID or capcode.'], - 'Custom Board Titles': [true, 'Allow editing of the board title and subtitle by ctrl/\u2318+clicking them.'], - 'Persistent Custom Board Titles': [false, 'Force custom board titles to be persistent, even if the board titles are updated.', 1], - 'Show Updated Notifications': [true, 'Show notifications when 4chan X is successfully updated.'], - 'Color User IDs': [true, 'Assign unique colors to user IDs on boards that use them'], - 'Count Posts by ID': [true, 'Display number of posts in the thread when hovering over an ID.'], - 'Remove Spoilers': [false, 'Remove all spoilers in text.'], - 'Reveal Spoilers': [false, 'Indicate spoilers if Remove Spoilers is enabled, or make the text appear hovered if Remove Spoiler is disabled.'], - 'Normalize URL': [true, 'Rewrite the URL of the current page, removing slugs and excess slashes, and changing /res/ to /thread/.'], - 'Work around CORB Bug': [true, 'Leave this checked until your garbage browser is fixed.'], - 'Disable Autoplaying Sounds': [false, 'Prevent sounds on the page from autoplaying.'], - 'Disable Native Extension': [true, '4chan X is NOT designed to work with the native extension.'], - 'Enable Native Flash Embedding': [true, 'Activate the native extension\'s Flash embedding if the native extension is disabled.'] - }, - 'Linkification': { - 'Linkify': [true, 'Convert text into links where applicable.'], - 'Link Title': [true, 'Replace the link of a supported site with its actual title.', 1], - 'Cover Preview': [true, 'Show preview of supported links on hover.', 1], - 'Embedding': [true, 'Embed supported services. Note: Some services don\'t work on HTTPS.', 1], - 'Auto-embed': [false, 'Auto-embed Linkify Embeds.', 2], - 'Floating Embeds': [false, 'Embed content in a frame that remains in place when the page is scrolled.', 2] - }, - 'Filtering': { - 'Anonymize': [false, 'Make everyone Anonymous.'], - 'Filter': [true, 'Self-moderation placebo.'], - 'Filtered Backlinks': [false, 'When enabled, shows backlinks to filtered posts with a line-through decoration. Otherwise, hides the backlinks.', 1], - 'Filter in Native Catalog': [true, 'Apply 4chan X filters in native catalog.', 1], - 'MD5 Quick Filter Notifications': [true, 'Show notification when quick filtering MD5s using the button or keybind.', 1], - 'Recursive Hiding': [true, 'Hide replies of hidden posts, recursively.'], - 'Thread Hiding Buttons': [true, 'Add buttons to hide entire threads.'], - 'Reply Hiding Buttons': [true, 'Add buttons to hide single replies.'], - 'Stubs': [true, 'Show stubs of hidden threads / replies.'] - }, - 'Images and Videos': { - 'Image Expansion': [true, 'Expand images / videos.'], - 'Image Hover': [true, 'Show full image / video on mouseover.'], - 'Image Hover in Catalog': [true, 'Show full image / video on mouseover in 4chan X catalog.'], - 'Gallery': [true, 'Adds a simple and cute image gallery. Has more options in the gallery menu.'], - 'Fullscreen Gallery': [false, 'Open gallery in fullscreen mode.', 1], - 'PDF in Gallery': [false, 'Show PDF files in gallery.', 1], - 'Sauce': [true, 'Add sauce links to images.'], - 'WEBM Metadata': [true, 'Add link to fetch title metadata from webm videos.'], - 'Reveal Spoiler Thumbnails': [false, 'Replace spoiler thumbnails with the original image.'], - 'Replace GIF': [false, 'Replace gif thumbnails with the actual image.'], - 'Replace JPG': [false, 'Replace jpg thumbnails with the actual image.'], - 'Replace PNG': [false, 'Replace png thumbnails with the actual image.'], - 'Replace WEBM': [false, 'Replace webm, mp4, and ogv thumbnails with the actual video. Probably will degrade browser performance ;)'], - 'Image Prefetching': [true, 'Add a shortcut icon to the header to turn on image preloading.'], - 'Fappe Tyme': [true, 'Hide posts without images when header menu item is checked. *hint* *hint*'], - 'Werk Tyme': [true, 'Hide all post images when header menu item is checked.'], - 'Autoplay': [true, 'Videos begin playing immediately when opened.'], - 'Restart when Opened': [false, 'Restart GIFs and WebMs when you hover over or expand them.'], - 'Show Controls': [true, 'Show controls on videos expanded inline.'], - 'Click Passthrough': [false, 'Clicks on videos trigger your browser\'s default behavior. Videos can be contracted with button / dragging to the left.', 1], - 'Allow Sound': [true, 'Open videos with the sound unmuted.'], - 'Mouse Wheel Volume': [true, 'Adjust volume of videos with the mouse wheel over the thumbnail/filename/gallery.'], - 'Loop in New Tab': [true, 'Loop videos opened in their own tabs.'], - 'Volume in New Tab': [true, 'Apply 4chan X mute and volume settings to videos opened in their own tabs.'] - }, - 'Menu': { - 'Menu': [true, 'Add a drop-down menu to posts.'], - 'Report Link': [true, 'Add a report link to the menu.', 1], - 'Copy Text Link': [true, 'Add a link to copy the post\'s text.', 1], - 'Thread Hiding Link': [true, 'Add a link to hide entire threads.', 1], - 'Reply Hiding Link': [true, 'Add a link to hide single replies.', 1], - 'Delete Link': [true, 'Add post and image deletion links to the menu.', 1], - 'Archive Link': [true, 'Add an archive link to the menu.', 1], - 'Edit Link': [true, 'Add a link to edit the image in Tegaki, /i/\'s painting program. Requires Quick Reply.', 1], - 'Download Link': [false, 'Add a download with original filename link to the menu.', 1] - }, - 'Monitoring': { - 'Thread Updater': [true, 'Fetch and insert new replies. Has more options in the header menu and the "Advanced" tab.'], - 'Unread Count': [true, 'Show the unread posts count in the tab title.'], - 'Quoted Title': [false, 'Change the page title to reflect you\'ve been quoted.', 1], - 'Hide Unread Count at (0)': [false, 'Hide the unread posts count in the tab title when it reaches 0.', 1], - 'Unread Favicon': [true, 'Show a different favicon when there are unread posts.'], - 'Unread Line': [true, 'Show a line to distinguish read posts from unread ones.'], - 'Remember Last Read Post': [true, 'Remember how far you\'ve read after you close the thread.'], - 'Scroll to Last Read Post': [true, 'Scroll back to the last read post when reopening a thread.', 1], - 'Unread Line in Index': [false, 'Show a line between read and unread posts in threads in the index.', 1], - 'Remove Thread Excerpt': [false, 'Replace the excerpt of the thread in the tab title with the board title.'], - 'Thread Stats': [true, 'Display reply and image count.'], - 'IP Count in Stats': [true, 'Display the unique IP count in the thread stats.', 1], - 'Page Count in Stats': [true, 'Display the page count in the thread stats.', 1], - 'Updater and Stats in Header': [true, 'Places the thread updater and thread stats in the header instead of floating them.'], - 'Thread Watcher': [true, 'Bookmark threads. Has more options in the thread watcher menu.'], - 'Fixed Thread Watcher': [true, 'Makes the thread watcher scroll with the page.', 1], - 'Persistent Thread Watcher': [false, 'The thread watcher will be visible when the page is loaded.', 1], - 'Mark New IPs': [false, 'Label each post from a new IP with the thread\'s current IP count.'], - 'Reply Pruning': [true, 'Add option in header menu to hide old replies in long threads. Activated by default in stickies.'], - 'Prune All Threads': [false, 'Activate Reply Pruning by default in all threads.', 1] - }, - 'Posting and Captchas': { - 'Quick Reply': [true, 'All-in-one form to reply, create threads, automate dumping and more.'], - 'Persistent QR': [false, 'The Quick reply won\'t disappear after posting.', 1], - 'Auto Hide QR': [true, 'Automatically hide the quick reply when posting.', 2], - 'Open Post in New Tab': [true, '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': [false, 'Remember the size of the Quick reply.', 1], - 'Remember Spoiler': [false, 'Remember the spoiler state, instead of resetting after posting.', 1], - 'Randomize Filename': [false, 'Set the filename to a random timestamp within the past year. Disabled on /f/.', 1], - 'Show New Thread Option in Threads': [true, 'Show the option to post a new / different thread from inside a thread.', 1], - 'Show Upload Progress': [true, 'Track progress of file uploads as percentage in submit button.', 1], - 'Cooldown': [true, 'Indicate the remaining time before posting again.', 1], - 'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.', 1], - 'Auto-load captcha': [false, 'Automatically load the captcha in the QR even if your post is empty.', 1], - 'Post on Captcha Completion': [false, 'Submit the post immediately when the captcha is completed.', 1], - 'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha even if Javascript is enabled.'], - 'Pass Link': [false, 'Add a 4chan Pass login link to the bottom of the page.'] - }, - 'Quote Links': { - 'Quote Backlinks': [true, 'Add quote backlinks.'], - 'OP Backlinks': [true, 'Add backlinks to the OP.', 1], - 'Bottom Backlinks': [false, 'Place backlinks at the bottom of posts.', 1], - 'Quote Inlining': [true, 'Inline quoted post on click.'], - 'Inline Cross-thread Quotes Only': [false, 'Don\'t inline quote links when the posts are visible in the thread.', 1], - 'Quote Hash Navigation': [false, 'Include an extra link after quotes for autoscrolling to quoted posts.', 1], - 'Forward Hiding': [true, 'Hide original posts of inlined backlinks.', 1], - 'Quote Previewing': [true, 'Show quoted post on hover.'], - 'Quote Highlighting': [true, 'Highlight the previewed post.', 1], - 'Resurrect Quotes': [true, 'Link dead quotes to the archives, and support inlining/previewing of archive links like quote links.'], - 'Remember Your Posts': [true, 'Remember your posting history.'], - 'Mark Quotes of You': [true, 'Add \'(You)\' to quotes linking to your posts.', 1], - 'Highlight Posts Quoting You': [true, 'Highlights any posts that contain a quote to your post.', 1], - 'Highlight Own Posts': [true, 'Highlights own posts.', 1], - 'Mark OP Quotes': [true, 'Add \'(OP)\' to OP quotes.'], - 'Mark Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.'], - 'Quote Threading': [true, 'Add option in header menu to thread conversations.'] - } - }, - imageExpansion: { - 'Fit width': [true, ''], - 'Fit height': [false, ''], - 'Scroll into view': [true, 'Scroll down when expanding images to bring the full image into view.'], - 'Expand spoilers': [true, 'Expand all images along with spoilers.'], - 'Expand videos': [true, 'Expand all images also expands videos.'], - 'Expand from here': [false, 'Expand all images only from current position to thread end.'], - 'Expand thread only': [false, 'In index, expand all images only within the current thread.'], - 'Advance on contract': [false, 'Advance to next post when contracting an expanded image.'] - }, - gallery: { - 'Hide Thumbnails': [false], - 'Fit Width': [true], - 'Fit Height': [true], - 'Stretch to Fit': [false], - 'Scroll to Post': [true], - 'Slide Delay': [6.0] - }, - 'Default Volume': 1.0, - threadWatcher: { - 'Current Board': [false, 'Only show watched threads from the current board.'], - 'Auto Update Thread Watcher': [true, 'Periodically check status of watched threads.'], - 'Auto Watch': [true, 'Automatically watch threads you start.'], - 'Auto Watch Reply': [true, 'Automatically watch threads you reply to.'], - 'Auto Prune': [false, 'Automatically remove dead threads.'], - 'Show Page': [true, 'Show what page watched threads are on.'], - 'Show Unread Count': [true, 'Show number of unread posts in watched threads.'], - 'Show Site Prefix': [true, 'When multiple sites are shown in the thread watcher, add a prefix to board names to distinguish them.'], - 'Require OP Quote Link': [false, '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: false - }, - 'Custom CSS': true, - Index: { - 'Index Mode': 'paged', - 'Previous Index Mode': 'paged', - 'Index Size': 'small', - 'Show Replies': [true, 'Show replies in the index, and also in the catalog if "Catalog hover expand" is checked.'], - 'Catalog Hover Expand': [false, 'Expand the comment and show more details when you hover over a thread in the catalog.'], - 'Catalog Hover Toggle': [true, 'Turn "Catalog hover expand" on and off by clicking in the catalog.'], - 'Pin Watched Threads': [false, 'Move watched threads to the start of the index.'], - 'Anchor Hidden Threads': [true, 'Move hidden threads to the end of the index.'], - 'Refreshed Navigation': [false, 'Refresh index when navigating through pages.'] - }, - Header: { - 'Fixed Header': true, - 'Header auto-hide': false, - 'Header auto-hide on scroll': false, - 'Bottom Header': false, - 'Centered links': false, - 'Header catalog links': false, - 'Bottom Board List': true, - 'Shortcut Icons': true, - 'Custom Board Navigation': true - }, - archives: { - archiveLists: 'https://4chenz.github.io/archives.json/archives.json', - lastarchivecheck: 0, - archiveAutoUpdate: true - }, - 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\",\"https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions\"]", - QR: { - 'QR.personas': "#options:\"sage\";boards:jp;always", - sjisPreview: false - }, - 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': [false, 'Beep on new post to completely read thread.'], - 'Beep Quoting You': [false, 'Beep on new post quoting you.'], - 'Auto Scroll': [false, 'Scroll updated posts into view. Only enabled at bottom of page.'], - 'Bottom Scroll': [false, 'Always scroll to the bottom, not the first new post. Useful for event threads.'], - 'Scroll BG': [false, 'Auto-scroll background tabs.'], - 'Auto Update': [true, 'Automatically fetch new posts.'], - 'Optional Increase': [false, 'Increase the intervals between updates on threads without new posts.'] - }, - 'Interval': 5 - }, - customCooldown: 0, - customCooldownEnabled: true, - 'Thread Quotes': false, - 'Max Replies': 1000, - 'Autohiding Scrollbar': false, - 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', - passMessageClosed: false, - 'Prerequest Captcha': false, - 'PSAseen': [[]] - }; - - return Config; - -}).call(this); - -CSS = { - -boards: -"/*!\n\ - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome\n\ - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n\ - */\n\ -@font-face {\n\ - font-family: FontAwesome;\n\ - src: url('data:application/font-woff;base64,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') format('woff');\n\ - font-weight: 400;\n\ - font-style: normal;\n\ -}\n\ -.fa-glass:before {content: \"\\f000\";}\n\ -.fa-music:before {content: \"\\f001\";}\n\ -.fa-search:before {content: \"\\f002\";}\n\ -.fa-envelope-o:before {content: \"\\f003\";}\n\ -.fa-heart:before {content: \"\\f004\";}\n\ -.fa-star:before {content: \"\\f005\";}\n\ -.fa-star-o:before {content: \"\\f006\";}\n\ -.fa-user:before {content: \"\\f007\";}\n\ -.fa-film:before {content: \"\\f008\";}\n\ -.fa-th-large:before {content: \"\\f009\";}\n\ -.fa-th:before {content: \"\\f00a\";}\n\ -.fa-th-list:before {content: \"\\f00b\";}\n\ -.fa-check:before {content: \"\\f00c\";}\n\ -.fa-remove:before, .fa-close:before, .fa-times:before {content: \"\\f00d\";}\n\ -.fa-search-plus:before {content: \"\\f00e\";}\n\ -.fa-search-minus:before {content: \"\\f010\";}\n\ -.fa-power-off:before {content: \"\\f011\";}\n\ -.fa-signal:before {content: \"\\f012\";}\n\ -.fa-gear:before, .fa-cog:before {content: \"\\f013\";}\n\ -.fa-trash-o:before {content: \"\\f014\";}\n\ -.fa-home:before {content: \"\\f015\";}\n\ -.fa-file-o:before {content: \"\\f016\";}\n\ -.fa-clock-o:before {content: \"\\f017\";}\n\ -.fa-road:before {content: \"\\f018\";}\n\ -.fa-download:before {content: \"\\f019\";}\n\ -.fa-arrow-circle-o-down:before {content: \"\\f01a\";}\n\ -.fa-arrow-circle-o-up:before {content: \"\\f01b\";}\n\ -.fa-inbox:before {content: \"\\f01c\";}\n\ -.fa-play-circle-o:before {content: \"\\f01d\";}\n\ -.fa-rotate-right:before, .fa-repeat:before {content: \"\\f01e\";}\n\ -.fa-refresh:before {content: \"\\f021\";}\n\ -.fa-list-alt:before {content: \"\\f022\";}\n\ -.fa-lock:before {content: \"\\f023\";}\n\ -.fa-flag:before {content: \"\\f024\";}\n\ -.fa-headphones:before {content: \"\\f025\";}\n\ -.fa-volume-off:before {content: \"\\f026\";}\n\ -.fa-volume-down:before {content: \"\\f027\";}\n\ -.fa-volume-up:before {content: \"\\f028\";}\n\ -.fa-qrcode:before {content: \"\\f029\";}\n\ -.fa-barcode:before {content: \"\\f02a\";}\n\ -.fa-tag:before {content: \"\\f02b\";}\n\ -.fa-tags:before {content: \"\\f02c\";}\n\ -.fa-book:before {content: \"\\f02d\";}\n\ -.fa-bookmark:before {content: \"\\f02e\";}\n\ -.fa-print:before {content: \"\\f02f\";}\n\ -.fa-camera:before {content: \"\\f030\";}\n\ -.fa-font:before {content: \"\\f031\";}\n\ -.fa-bold:before {content: \"\\f032\";}\n\ -.fa-italic:before {content: \"\\f033\";}\n\ -.fa-text-height:before {content: \"\\f034\";}\n\ -.fa-text-width:before {content: \"\\f035\";}\n\ -.fa-align-left:before {content: \"\\f036\";}\n\ -.fa-align-center:before {content: \"\\f037\";}\n\ -.fa-align-right:before {content: \"\\f038\";}\n\ -.fa-align-justify:before {content: \"\\f039\";}\n\ -.fa-list:before {content: \"\\f03a\";}\n\ -.fa-dedent:before, .fa-outdent:before {content: \"\\f03b\";}\n\ -.fa-indent:before {content: \"\\f03c\";}\n\ -.fa-video-camera:before {content: \"\\f03d\";}\n\ -.fa-photo:before, .fa-image:before, .fa-picture-o:before {content: \"\\f03e\";}\n\ -.fa-pencil:before {content: \"\\f040\";}\n\ -.fa-map-marker:before {content: \"\\f041\";}\n\ -.fa-adjust:before {content: \"\\f042\";}\n\ -.fa-tint:before {content: \"\\f043\";}\n\ -.fa-edit:before, .fa-pencil-square-o:before {content: \"\\f044\";}\n\ -.fa-share-square-o:before {content: \"\\f045\";}\n\ -.fa-check-square-o:before {content: \"\\f046\";}\n\ -.fa-arrows:before {content: \"\\f047\";}\n\ -.fa-step-backward:before {content: \"\\f048\";}\n\ -.fa-fast-backward:before {content: \"\\f049\";}\n\ -.fa-backward:before {content: \"\\f04a\";}\n\ -.fa-play:before {content: \"\\f04b\";}\n\ -.fa-pause:before {content: \"\\f04c\";}\n\ -.fa-stop:before {content: \"\\f04d\";}\n\ -.fa-forward:before {content: \"\\f04e\";}\n\ -.fa-fast-forward:before {content: \"\\f050\";}\n\ -.fa-step-forward:before {content: \"\\f051\";}\n\ -.fa-eject:before {content: \"\\f052\";}\n\ -.fa-chevron-left:before {content: \"\\f053\";}\n\ -.fa-chevron-right:before {content: \"\\f054\";}\n\ -.fa-plus-circle:before {content: \"\\f055\";}\n\ -.fa-minus-circle:before {content: \"\\f056\";}\n\ -.fa-times-circle:before {content: \"\\f057\";}\n\ -.fa-check-circle:before {content: \"\\f058\";}\n\ -.fa-question-circle:before {content: \"\\f059\";}\n\ -.fa-info-circle:before {content: \"\\f05a\";}\n\ -.fa-crosshairs:before {content: \"\\f05b\";}\n\ -.fa-times-circle-o:before {content: \"\\f05c\";}\n\ -.fa-check-circle-o:before {content: \"\\f05d\";}\n\ -.fa-ban:before {content: \"\\f05e\";}\n\ -.fa-arrow-left:before {content: \"\\f060\";}\n\ -.fa-arrow-right:before {content: \"\\f061\";}\n\ -.fa-arrow-up:before {content: \"\\f062\";}\n\ -.fa-arrow-down:before {content: \"\\f063\";}\n\ -.fa-mail-forward:before, .fa-share:before {content: \"\\f064\";}\n\ -.fa-expand:before {content: \"\\f065\";}\n\ -.fa-compress:before {content: \"\\f066\";}\n\ -.fa-plus:before {content: \"\\f067\";}\n\ -.fa-minus:before {content: \"\\f068\";}\n\ -.fa-asterisk:before {content: \"\\f069\";}\n\ -.fa-exclamation-circle:before {content: \"\\f06a\";}\n\ -.fa-gift:before {content: \"\\f06b\";}\n\ -.fa-leaf:before {content: \"\\f06c\";}\n\ -.fa-fire:before {content: \"\\f06d\";}\n\ -.fa-eye:before {content: \"\\f06e\";}\n\ -.fa-eye-slash:before {content: \"\\f070\";}\n\ -.fa-warning:before, .fa-exclamation-triangle:before {content: \"\\f071\";}\n\ -.fa-plane:before {content: \"\\f072\";}\n\ -.fa-calendar:before {content: \"\\f073\";}\n\ -.fa-random:before {content: \"\\f074\";}\n\ -.fa-comment:before {content: \"\\f075\";}\n\ -.fa-magnet:before {content: \"\\f076\";}\n\ -.fa-chevron-up:before {content: \"\\f077\";}\n\ -.fa-chevron-down:before {content: \"\\f078\";}\n\ -.fa-retweet:before {content: \"\\f079\";}\n\ -.fa-shopping-cart:before {content: \"\\f07a\";}\n\ -.fa-folder:before {content: \"\\f07b\";}\n\ -.fa-folder-open:before {content: \"\\f07c\";}\n\ -.fa-arrows-v:before {content: \"\\f07d\";}\n\ -.fa-arrows-h:before {content: \"\\f07e\";}\n\ -.fa-bar-chart-o:before, .fa-bar-chart:before {content: \"\\f080\";}\n\ -.fa-twitter-square:before {content: \"\\f081\";}\n\ -.fa-facebook-square:before {content: \"\\f082\";}\n\ -.fa-camera-retro:before {content: \"\\f083\";}\n\ -.fa-key:before {content: \"\\f084\";}\n\ -.fa-gears:before, .fa-cogs:before {content: \"\\f085\";}\n\ -.fa-comments:before {content: \"\\f086\";}\n\ -.fa-thumbs-o-up:before {content: \"\\f087\";}\n\ -.fa-thumbs-o-down:before {content: \"\\f088\";}\n\ -.fa-star-half:before {content: \"\\f089\";}\n\ -.fa-heart-o:before {content: \"\\f08a\";}\n\ -.fa-sign-out:before {content: \"\\f08b\";}\n\ -.fa-linkedin-square:before {content: \"\\f08c\";}\n\ -.fa-thumb-tack:before {content: \"\\f08d\";}\n\ -.fa-external-link:before {content: \"\\f08e\";}\n\ -.fa-sign-in:before {content: \"\\f090\";}\n\ -.fa-trophy:before {content: \"\\f091\";}\n\ -.fa-github-square:before {content: \"\\f092\";}\n\ -.fa-upload:before {content: \"\\f093\";}\n\ -.fa-lemon-o:before {content: \"\\f094\";}\n\ -.fa-phone:before {content: \"\\f095\";}\n\ -.fa-square-o:before {content: \"\\f096\";}\n\ -.fa-bookmark-o:before {content: \"\\f097\";}\n\ -.fa-phone-square:before {content: \"\\f098\";}\n\ -.fa-twitter:before {content: \"\\f099\";}\n\ -.fa-facebook-f:before, .fa-facebook:before {content: \"\\f09a\";}\n\ -.fa-github:before {content: \"\\f09b\";}\n\ -.fa-unlock:before {content: \"\\f09c\";}\n\ -.fa-credit-card:before {content: \"\\f09d\";}\n\ -.fa-feed:before, .fa-rss:before {content: \"\\f09e\";}\n\ -.fa-hdd-o:before {content: \"\\f0a0\";}\n\ -.fa-bullhorn:before {content: \"\\f0a1\";}\n\ -.fa-bell:before {content: \"\\f0f3\";}\n\ -.fa-certificate:before {content: \"\\f0a3\";}\n\ -.fa-hand-o-right:before {content: \"\\f0a4\";}\n\ -.fa-hand-o-left:before {content: \"\\f0a5\";}\n\ -.fa-hand-o-up:before {content: \"\\f0a6\";}\n\ -.fa-hand-o-down:before {content: \"\\f0a7\";}\n\ -.fa-arrow-circle-left:before {content: \"\\f0a8\";}\n\ -.fa-arrow-circle-right:before {content: \"\\f0a9\";}\n\ -.fa-arrow-circle-up:before {content: \"\\f0aa\";}\n\ -.fa-arrow-circle-down:before {content: \"\\f0ab\";}\n\ -.fa-globe:before {content: \"\\f0ac\";}\n\ -.fa-wrench:before {content: \"\\f0ad\";}\n\ -.fa-tasks:before {content: \"\\f0ae\";}\n\ -.fa-filter:before {content: \"\\f0b0\";}\n\ -.fa-briefcase:before {content: \"\\f0b1\";}\n\ -.fa-arrows-alt:before {content: \"\\f0b2\";}\n\ -.fa-group:before, .fa-users:before {content: \"\\f0c0\";}\n\ -.fa-chain:before, .fa-link:before {content: \"\\f0c1\";}\n\ -.fa-cloud:before {content: \"\\f0c2\";}\n\ -.fa-flask:before {content: \"\\f0c3\";}\n\ -.fa-cut:before, .fa-scissors:before {content: \"\\f0c4\";}\n\ -.fa-copy:before, .fa-files-o:before {content: \"\\f0c5\";}\n\ -.fa-paperclip:before {content: \"\\f0c6\";}\n\ -.fa-save:before, .fa-floppy-o:before {content: \"\\f0c7\";}\n\ -.fa-square:before {content: \"\\f0c8\";}\n\ -.fa-navicon:before, .fa-reorder:before, .fa-bars:before {content: \"\\f0c9\";}\n\ -.fa-list-ul:before {content: \"\\f0ca\";}\n\ -.fa-list-ol:before {content: \"\\f0cb\";}\n\ -.fa-strikethrough:before {content: \"\\f0cc\";}\n\ -.fa-underline:before {content: \"\\f0cd\";}\n\ -.fa-table:before {content: \"\\f0ce\";}\n\ -.fa-magic:before {content: \"\\f0d0\";}\n\ -.fa-truck:before {content: \"\\f0d1\";}\n\ -.fa-pinterest:before {content: \"\\f0d2\";}\n\ -.fa-pinterest-square:before {content: \"\\f0d3\";}\n\ -.fa-google-plus-square:before {content: \"\\f0d4\";}\n\ -.fa-google-plus:before {content: \"\\f0d5\";}\n\ -.fa-money:before {content: \"\\f0d6\";}\n\ -.fa-caret-down:before {content: \"\\f0d7\";}\n\ -.fa-caret-up:before {content: \"\\f0d8\";}\n\ -.fa-caret-left:before {content: \"\\f0d9\";}\n\ -.fa-caret-right:before {content: \"\\f0da\";}\n\ -.fa-columns:before {content: \"\\f0db\";}\n\ -.fa-unsorted:before, .fa-sort:before {content: \"\\f0dc\";}\n\ -.fa-sort-down:before, .fa-sort-desc:before {content: \"\\f0dd\";}\n\ -.fa-sort-up:before, .fa-sort-asc:before {content: \"\\f0de\";}\n\ -.fa-envelope:before {content: \"\\f0e0\";}\n\ -.fa-linkedin:before {content: \"\\f0e1\";}\n\ -.fa-rotate-left:before, .fa-undo:before {content: \"\\f0e2\";}\n\ -.fa-legal:before, .fa-gavel:before {content: \"\\f0e3\";}\n\ -.fa-dashboard:before, .fa-tachometer:before {content: \"\\f0e4\";}\n\ -.fa-comment-o:before {content: \"\\f0e5\";}\n\ -.fa-comments-o:before {content: \"\\f0e6\";}\n\ -.fa-flash:before, .fa-bolt:before {content: \"\\f0e7\";}\n\ -.fa-sitemap:before {content: \"\\f0e8\";}\n\ -.fa-umbrella:before {content: \"\\f0e9\";}\n\ -.fa-paste:before, .fa-clipboard:before {content: \"\\f0ea\";}\n\ -.fa-lightbulb-o:before {content: \"\\f0eb\";}\n\ -.fa-exchange:before {content: \"\\f0ec\";}\n\ -.fa-cloud-download:before {content: \"\\f0ed\";}\n\ -.fa-cloud-upload:before {content: \"\\f0ee\";}\n\ -.fa-user-md:before {content: \"\\f0f0\";}\n\ -.fa-stethoscope:before {content: \"\\f0f1\";}\n\ -.fa-suitcase:before {content: \"\\f0f2\";}\n\ -.fa-bell-o:before {content: \"\\f0a2\";}\n\ -.fa-coffee:before {content: \"\\f0f4\";}\n\ -.fa-cutlery:before {content: \"\\f0f5\";}\n\ -.fa-file-text-o:before {content: \"\\f0f6\";}\n\ -.fa-building-o:before {content: \"\\f0f7\";}\n\ -.fa-hospital-o:before {content: \"\\f0f8\";}\n\ -.fa-ambulance:before {content: \"\\f0f9\";}\n\ -.fa-medkit:before {content: \"\\f0fa\";}\n\ -.fa-fighter-jet:before {content: \"\\f0fb\";}\n\ -.fa-beer:before {content: \"\\f0fc\";}\n\ -.fa-h-square:before {content: \"\\f0fd\";}\n\ -.fa-plus-square:before {content: \"\\f0fe\";}\n\ -.fa-angle-double-left:before {content: \"\\f100\";}\n\ -.fa-angle-double-right:before {content: \"\\f101\";}\n\ -.fa-angle-double-up:before {content: \"\\f102\";}\n\ -.fa-angle-double-down:before {content: \"\\f103\";}\n\ -.fa-angle-left:before {content: \"\\f104\";}\n\ -.fa-angle-right:before {content: \"\\f105\";}\n\ -.fa-angle-up:before {content: \"\\f106\";}\n\ -.fa-angle-down:before {content: \"\\f107\";}\n\ -.fa-desktop:before {content: \"\\f108\";}\n\ -.fa-laptop:before {content: \"\\f109\";}\n\ -.fa-tablet:before {content: \"\\f10a\";}\n\ -.fa-mobile-phone:before, .fa-mobile:before {content: \"\\f10b\";}\n\ -.fa-circle-o:before {content: \"\\f10c\";}\n\ -.fa-quote-left:before {content: \"\\f10d\";}\n\ -.fa-quote-right:before {content: \"\\f10e\";}\n\ -.fa-spinner:before {content: \"\\f110\";}\n\ -.fa-circle:before {content: \"\\f111\";}\n\ -.fa-mail-reply:before, .fa-reply:before {content: \"\\f112\";}\n\ -.fa-github-alt:before {content: \"\\f113\";}\n\ -.fa-folder-o:before {content: \"\\f114\";}\n\ -.fa-folder-open-o:before {content: \"\\f115\";}\n\ -.fa-smile-o:before {content: \"\\f118\";}\n\ -.fa-frown-o:before {content: \"\\f119\";}\n\ -.fa-meh-o:before {content: \"\\f11a\";}\n\ -.fa-gamepad:before {content: \"\\f11b\";}\n\ -.fa-keyboard-o:before {content: \"\\f11c\";}\n\ -.fa-flag-o:before {content: \"\\f11d\";}\n\ -.fa-flag-checkered:before {content: \"\\f11e\";}\n\ -.fa-terminal:before {content: \"\\f120\";}\n\ -.fa-code:before {content: \"\\f121\";}\n\ -.fa-mail-reply-all:before, .fa-reply-all:before {content: \"\\f122\";}\n\ -.fa-star-half-empty:before, .fa-star-half-full:before, .fa-star-half-o:before {content: \"\\f123\";}\n\ -.fa-location-arrow:before {content: \"\\f124\";}\n\ -.fa-crop:before {content: \"\\f125\";}\n\ -.fa-code-fork:before {content: \"\\f126\";}\n\ -.fa-unlink:before, .fa-chain-broken:before {content: \"\\f127\";}\n\ -.fa-question:before {content: \"\\f128\";}\n\ -.fa-info:before {content: \"\\f129\";}\n\ -.fa-exclamation:before {content: \"\\f12a\";}\n\ -.fa-superscript:before {content: \"\\f12b\";}\n\ -.fa-subscript:before {content: \"\\f12c\";}\n\ -.fa-eraser:before {content: \"\\f12d\";}\n\ -.fa-puzzle-piece:before {content: \"\\f12e\";}\n\ -.fa-microphone:before {content: \"\\f130\";}\n\ -.fa-microphone-slash:before {content: \"\\f131\";}\n\ -.fa-shield:before {content: \"\\f132\";}\n\ -.fa-calendar-o:before {content: \"\\f133\";}\n\ -.fa-fire-extinguisher:before {content: \"\\f134\";}\n\ -.fa-rocket:before {content: \"\\f135\";}\n\ -.fa-maxcdn:before {content: \"\\f136\";}\n\ -.fa-chevron-circle-left:before {content: \"\\f137\";}\n\ -.fa-chevron-circle-right:before {content: \"\\f138\";}\n\ -.fa-chevron-circle-up:before {content: \"\\f139\";}\n\ -.fa-chevron-circle-down:before {content: \"\\f13a\";}\n\ -.fa-html5:before {content: \"\\f13b\";}\n\ -.fa-css3:before {content: \"\\f13c\";}\n\ -.fa-anchor:before {content: \"\\f13d\";}\n\ -.fa-unlock-alt:before {content: \"\\f13e\";}\n\ -.fa-bullseye:before {content: \"\\f140\";}\n\ -.fa-ellipsis-h:before {content: \"\\f141\";}\n\ -.fa-ellipsis-v:before {content: \"\\f142\";}\n\ -.fa-rss-square:before {content: \"\\f143\";}\n\ -.fa-play-circle:before {content: \"\\f144\";}\n\ -.fa-ticket:before {content: \"\\f145\";}\n\ -.fa-minus-square:before {content: \"\\f146\";}\n\ -.fa-minus-square-o:before {content: \"\\f147\";}\n\ -.fa-level-up:before {content: \"\\f148\";}\n\ -.fa-level-down:before {content: \"\\f149\";}\n\ -.fa-check-square:before {content: \"\\f14a\";}\n\ -.fa-pencil-square:before {content: \"\\f14b\";}\n\ -.fa-external-link-square:before {content: \"\\f14c\";}\n\ -.fa-share-square:before {content: \"\\f14d\";}\n\ -.fa-compass:before {content: \"\\f14e\";}\n\ -.fa-toggle-down:before, .fa-caret-square-o-down:before {content: \"\\f150\";}\n\ -.fa-toggle-up:before, .fa-caret-square-o-up:before {content: \"\\f151\";}\n\ -.fa-toggle-right:before, .fa-caret-square-o-right:before {content: \"\\f152\";}\n\ -.fa-euro:before, .fa-eur:before {content: \"\\f153\";}\n\ -.fa-gbp:before {content: \"\\f154\";}\n\ -.fa-dollar:before, .fa-usd:before {content: \"\\f155\";}\n\ -.fa-rupee:before, .fa-inr:before {content: \"\\f156\";}\n\ -.fa-cny:before, .fa-rmb:before, .fa-yen:before, .fa-jpy:before {content: \"\\f157\";}\n\ -.fa-ruble:before, .fa-rouble:before, .fa-rub:before {content: \"\\f158\";}\n\ -.fa-won:before, .fa-krw:before {content: \"\\f159\";}\n\ -.fa-bitcoin:before, .fa-btc:before {content: \"\\f15a\";}\n\ -.fa-file:before {content: \"\\f15b\";}\n\ -.fa-file-text:before {content: \"\\f15c\";}\n\ -.fa-sort-alpha-asc:before {content: \"\\f15d\";}\n\ -.fa-sort-alpha-desc:before {content: \"\\f15e\";}\n\ -.fa-sort-amount-asc:before {content: \"\\f160\";}\n\ -.fa-sort-amount-desc:before {content: \"\\f161\";}\n\ -.fa-sort-numeric-asc:before {content: \"\\f162\";}\n\ -.fa-sort-numeric-desc:before {content: \"\\f163\";}\n\ -.fa-thumbs-up:before {content: \"\\f164\";}\n\ -.fa-thumbs-down:before {content: \"\\f165\";}\n\ -.fa-youtube-square:before {content: \"\\f166\";}\n\ -.fa-youtube:before {content: \"\\f167\";}\n\ -.fa-xing:before {content: \"\\f168\";}\n\ -.fa-xing-square:before {content: \"\\f169\";}\n\ -.fa-youtube-play:before {content: \"\\f16a\";}\n\ -.fa-dropbox:before {content: \"\\f16b\";}\n\ -.fa-stack-overflow:before {content: \"\\f16c\";}\n\ -.fa-instagram:before {content: \"\\f16d\";}\n\ -.fa-flickr:before {content: \"\\f16e\";}\n\ -.fa-adn:before {content: \"\\f170\";}\n\ -.fa-bitbucket:before {content: \"\\f171\";}\n\ -.fa-bitbucket-square:before {content: \"\\f172\";}\n\ -.fa-tumblr:before {content: \"\\f173\";}\n\ -.fa-tumblr-square:before {content: \"\\f174\";}\n\ -.fa-long-arrow-down:before {content: \"\\f175\";}\n\ -.fa-long-arrow-up:before {content: \"\\f176\";}\n\ -.fa-long-arrow-left:before {content: \"\\f177\";}\n\ -.fa-long-arrow-right:before {content: \"\\f178\";}\n\ -.fa-apple:before {content: \"\\f179\";}\n\ -.fa-windows:before {content: \"\\f17a\";}\n\ -.fa-android:before {content: \"\\f17b\";}\n\ -.fa-linux:before {content: \"\\f17c\";}\n\ -.fa-dribbble:before {content: \"\\f17d\";}\n\ -.fa-skype:before {content: \"\\f17e\";}\n\ -.fa-foursquare:before {content: \"\\f180\";}\n\ -.fa-trello:before {content: \"\\f181\";}\n\ -.fa-female:before {content: \"\\f182\";}\n\ -.fa-male:before {content: \"\\f183\";}\n\ -.fa-gittip:before, .fa-gratipay:before {content: \"\\f184\";}\n\ -.fa-sun-o:before {content: \"\\f185\";}\n\ -.fa-moon-o:before {content: \"\\f186\";}\n\ -.fa-archive:before {content: \"\\f187\";}\n\ -.fa-bug:before {content: \"\\f188\";}\n\ -.fa-vk:before {content: \"\\f189\";}\n\ -.fa-weibo:before {content: \"\\f18a\";}\n\ -.fa-renren:before {content: \"\\f18b\";}\n\ -.fa-pagelines:before {content: \"\\f18c\";}\n\ -.fa-stack-exchange:before {content: \"\\f18d\";}\n\ -.fa-arrow-circle-o-right:before {content: \"\\f18e\";}\n\ -.fa-arrow-circle-o-left:before {content: \"\\f190\";}\n\ -.fa-toggle-left:before, .fa-caret-square-o-left:before {content: \"\\f191\";}\n\ -.fa-dot-circle-o:before {content: \"\\f192\";}\n\ -.fa-wheelchair:before {content: \"\\f193\";}\n\ -.fa-vimeo-square:before {content: \"\\f194\";}\n\ -.fa-turkish-lira:before, .fa-try:before {content: \"\\f195\";}\n\ -.fa-plus-square-o:before {content: \"\\f196\";}\n\ -.fa-space-shuttle:before {content: \"\\f197\";}\n\ -.fa-slack:before {content: \"\\f198\";}\n\ -.fa-envelope-square:before {content: \"\\f199\";}\n\ -.fa-wordpress:before {content: \"\\f19a\";}\n\ -.fa-openid:before {content: \"\\f19b\";}\n\ -.fa-institution:before, .fa-bank:before, .fa-university:before {content: \"\\f19c\";}\n\ -.fa-mortar-board:before, .fa-graduation-cap:before {content: \"\\f19d\";}\n\ -.fa-yahoo:before {content: \"\\f19e\";}\n\ -.fa-google:before {content: \"\\f1a0\";}\n\ -.fa-reddit:before {content: \"\\f1a1\";}\n\ -.fa-reddit-square:before {content: \"\\f1a2\";}\n\ -.fa-stumbleupon-circle:before {content: \"\\f1a3\";}\n\ -.fa-stumbleupon:before {content: \"\\f1a4\";}\n\ -.fa-delicious:before {content: \"\\f1a5\";}\n\ -.fa-digg:before {content: \"\\f1a6\";}\n\ -.fa-pied-piper-pp:before {content: \"\\f1a7\";}\n\ -.fa-pied-piper-alt:before {content: \"\\f1a8\";}\n\ -.fa-drupal:before {content: \"\\f1a9\";}\n\ -.fa-joomla:before {content: \"\\f1aa\";}\n\ -.fa-language:before {content: \"\\f1ab\";}\n\ -.fa-fax:before {content: \"\\f1ac\";}\n\ -.fa-building:before {content: \"\\f1ad\";}\n\ -.fa-child:before {content: \"\\f1ae\";}\n\ -.fa-paw:before {content: \"\\f1b0\";}\n\ -.fa-spoon:before {content: \"\\f1b1\";}\n\ -.fa-cube:before {content: \"\\f1b2\";}\n\ -.fa-cubes:before {content: \"\\f1b3\";}\n\ -.fa-behance:before {content: \"\\f1b4\";}\n\ -.fa-behance-square:before {content: \"\\f1b5\";}\n\ -.fa-steam:before {content: \"\\f1b6\";}\n\ -.fa-steam-square:before {content: \"\\f1b7\";}\n\ -.fa-recycle:before {content: \"\\f1b8\";}\n\ -.fa-automobile:before, .fa-car:before {content: \"\\f1b9\";}\n\ -.fa-cab:before, .fa-taxi:before {content: \"\\f1ba\";}\n\ -.fa-tree:before {content: \"\\f1bb\";}\n\ -.fa-spotify:before {content: \"\\f1bc\";}\n\ -.fa-deviantart:before {content: \"\\f1bd\";}\n\ -.fa-soundcloud:before {content: \"\\f1be\";}\n\ -.fa-database:before {content: \"\\f1c0\";}\n\ -.fa-file-pdf-o:before {content: \"\\f1c1\";}\n\ -.fa-file-word-o:before {content: \"\\f1c2\";}\n\ -.fa-file-excel-o:before {content: \"\\f1c3\";}\n\ -.fa-file-powerpoint-o:before {content: \"\\f1c4\";}\n\ -.fa-file-photo-o:before, .fa-file-picture-o:before, .fa-file-image-o:before {content: \"\\f1c5\";}\n\ -.fa-file-zip-o:before, .fa-file-archive-o:before {content: \"\\f1c6\";}\n\ -.fa-file-sound-o:before, .fa-file-audio-o:before {content: \"\\f1c7\";}\n\ -.fa-file-movie-o:before, .fa-file-video-o:before {content: \"\\f1c8\";}\n\ -.fa-file-code-o:before {content: \"\\f1c9\";}\n\ -.fa-vine:before {content: \"\\f1ca\";}\n\ -.fa-codepen:before {content: \"\\f1cb\";}\n\ -.fa-jsfiddle:before {content: \"\\f1cc\";}\n\ -.fa-life-bouy:before, .fa-life-buoy:before, .fa-life-saver:before, .fa-support:before, .fa-life-ring:before {content: \"\\f1cd\";}\n\ -.fa-circle-o-notch:before {content: \"\\f1ce\";}\n\ -.fa-ra:before, .fa-resistance:before, .fa-rebel:before {content: \"\\f1d0\";}\n\ -.fa-ge:before, .fa-empire:before {content: \"\\f1d1\";}\n\ -.fa-git-square:before {content: \"\\f1d2\";}\n\ -.fa-git:before {content: \"\\f1d3\";}\n\ -.fa-y-combinator-square:before, .fa-yc-square:before, .fa-hacker-news:before {content: \"\\f1d4\";}\n\ -.fa-tencent-weibo:before {content: \"\\f1d5\";}\n\ -.fa-qq:before {content: \"\\f1d6\";}\n\ -.fa-wechat:before, .fa-weixin:before {content: \"\\f1d7\";}\n\ -.fa-send:before, .fa-paper-plane:before {content: \"\\f1d8\";}\n\ -.fa-send-o:before, .fa-paper-plane-o:before {content: \"\\f1d9\";}\n\ -.fa-history:before {content: \"\\f1da\";}\n\ -.fa-circle-thin:before {content: \"\\f1db\";}\n\ -.fa-header:before {content: \"\\f1dc\";}\n\ -.fa-paragraph:before {content: \"\\f1dd\";}\n\ -.fa-sliders:before {content: \"\\f1de\";}\n\ -.fa-share-alt:before {content: \"\\f1e0\";}\n\ -.fa-share-alt-square:before {content: \"\\f1e1\";}\n\ -.fa-bomb:before {content: \"\\f1e2\";}\n\ -.fa-soccer-ball-o:before, .fa-futbol-o:before {content: \"\\f1e3\";}\n\ -.fa-tty:before {content: \"\\f1e4\";}\n\ -.fa-binoculars:before {content: \"\\f1e5\";}\n\ -.fa-plug:before {content: \"\\f1e6\";}\n\ -.fa-slideshare:before {content: \"\\f1e7\";}\n\ -.fa-twitch:before {content: \"\\f1e8\";}\n\ -.fa-yelp:before {content: \"\\f1e9\";}\n\ -.fa-newspaper-o:before {content: \"\\f1ea\";}\n\ -.fa-wifi:before {content: \"\\f1eb\";}\n\ -.fa-calculator:before {content: \"\\f1ec\";}\n\ -.fa-paypal:before {content: \"\\f1ed\";}\n\ -.fa-google-wallet:before {content: \"\\f1ee\";}\n\ -.fa-cc-visa:before {content: \"\\f1f0\";}\n\ -.fa-cc-mastercard:before {content: \"\\f1f1\";}\n\ -.fa-cc-discover:before {content: \"\\f1f2\";}\n\ -.fa-cc-amex:before {content: \"\\f1f3\";}\n\ -.fa-cc-paypal:before {content: \"\\f1f4\";}\n\ -.fa-cc-stripe:before {content: \"\\f1f5\";}\n\ -.fa-bell-slash:before {content: \"\\f1f6\";}\n\ -.fa-bell-slash-o:before {content: \"\\f1f7\";}\n\ -.fa-trash:before {content: \"\\f1f8\";}\n\ -.fa-copyright:before {content: \"\\f1f9\";}\n\ -.fa-at:before {content: \"\\f1fa\";}\n\ -.fa-eyedropper:before {content: \"\\f1fb\";}\n\ -.fa-paint-brush:before {content: \"\\f1fc\";}\n\ -.fa-birthday-cake:before {content: \"\\f1fd\";}\n\ -.fa-area-chart:before {content: \"\\f1fe\";}\n\ -.fa-pie-chart:before {content: \"\\f200\";}\n\ -.fa-line-chart:before {content: \"\\f201\";}\n\ -.fa-lastfm:before {content: \"\\f202\";}\n\ -.fa-lastfm-square:before {content: \"\\f203\";}\n\ -.fa-toggle-off:before {content: \"\\f204\";}\n\ -.fa-toggle-on:before {content: \"\\f205\";}\n\ -.fa-bicycle:before {content: \"\\f206\";}\n\ -.fa-bus:before {content: \"\\f207\";}\n\ -.fa-ioxhost:before {content: \"\\f208\";}\n\ -.fa-angellist:before {content: \"\\f209\";}\n\ -.fa-cc:before {content: \"\\f20a\";}\n\ -.fa-shekel:before, .fa-sheqel:before, .fa-ils:before {content: \"\\f20b\";}\n\ -.fa-meanpath:before {content: \"\\f20c\";}\n\ -.fa-buysellads:before {content: \"\\f20d\";}\n\ -.fa-connectdevelop:before {content: \"\\f20e\";}\n\ -.fa-dashcube:before {content: \"\\f210\";}\n\ -.fa-forumbee:before {content: \"\\f211\";}\n\ -.fa-leanpub:before {content: \"\\f212\";}\n\ -.fa-sellsy:before {content: \"\\f213\";}\n\ -.fa-shirtsinbulk:before {content: \"\\f214\";}\n\ -.fa-simplybuilt:before {content: \"\\f215\";}\n\ -.fa-skyatlas:before {content: \"\\f216\";}\n\ -.fa-cart-plus:before {content: \"\\f217\";}\n\ -.fa-cart-arrow-down:before {content: \"\\f218\";}\n\ -.fa-diamond:before {content: \"\\f219\";}\n\ -.fa-ship:before {content: \"\\f21a\";}\n\ -.fa-user-secret:before {content: \"\\f21b\";}\n\ -.fa-motorcycle:before {content: \"\\f21c\";}\n\ -.fa-street-view:before {content: \"\\f21d\";}\n\ -.fa-heartbeat:before {content: \"\\f21e\";}\n\ -.fa-venus:before {content: \"\\f221\";}\n\ -.fa-mars:before {content: \"\\f222\";}\n\ -.fa-mercury:before {content: \"\\f223\";}\n\ -.fa-intersex:before, .fa-transgender:before {content: \"\\f224\";}\n\ -.fa-transgender-alt:before {content: \"\\f225\";}\n\ -.fa-venus-double:before {content: \"\\f226\";}\n\ -.fa-mars-double:before {content: \"\\f227\";}\n\ -.fa-venus-mars:before {content: \"\\f228\";}\n\ -.fa-mars-stroke:before {content: \"\\f229\";}\n\ -.fa-mars-stroke-v:before {content: \"\\f22a\";}\n\ -.fa-mars-stroke-h:before {content: \"\\f22b\";}\n\ -.fa-neuter:before {content: \"\\f22c\";}\n\ -.fa-genderless:before {content: \"\\f22d\";}\n\ -.fa-facebook-official:before {content: \"\\f230\";}\n\ -.fa-pinterest-p:before {content: \"\\f231\";}\n\ -.fa-whatsapp:before {content: \"\\f232\";}\n\ -.fa-server:before {content: \"\\f233\";}\n\ -.fa-user-plus:before {content: \"\\f234\";}\n\ -.fa-user-times:before {content: \"\\f235\";}\n\ -.fa-hotel:before, .fa-bed:before {content: \"\\f236\";}\n\ -.fa-viacoin:before {content: \"\\f237\";}\n\ -.fa-train:before {content: \"\\f238\";}\n\ -.fa-subway:before {content: \"\\f239\";}\n\ -.fa-medium:before {content: \"\\f23a\";}\n\ -.fa-yc:before, .fa-y-combinator:before {content: \"\\f23b\";}\n\ -.fa-optin-monster:before {content: \"\\f23c\";}\n\ -.fa-opencart:before {content: \"\\f23d\";}\n\ -.fa-expeditedssl:before {content: \"\\f23e\";}\n\ -.fa-battery-4:before, .fa-battery:before, .fa-battery-full:before {content: \"\\f240\";}\n\ -.fa-battery-3:before, .fa-battery-three-quarters:before {content: \"\\f241\";}\n\ -.fa-battery-2:before, .fa-battery-half:before {content: \"\\f242\";}\n\ -.fa-battery-1:before, .fa-battery-quarter:before {content: \"\\f243\";}\n\ -.fa-battery-0:before, .fa-battery-empty:before {content: \"\\f244\";}\n\ -.fa-mouse-pointer:before {content: \"\\f245\";}\n\ -.fa-i-cursor:before {content: \"\\f246\";}\n\ -.fa-object-group:before {content: \"\\f247\";}\n\ -.fa-object-ungroup:before {content: \"\\f248\";}\n\ -.fa-sticky-note:before {content: \"\\f249\";}\n\ -.fa-sticky-note-o:before {content: \"\\f24a\";}\n\ -.fa-cc-jcb:before {content: \"\\f24b\";}\n\ -.fa-cc-diners-club:before {content: \"\\f24c\";}\n\ -.fa-clone:before {content: \"\\f24d\";}\n\ -.fa-balance-scale:before {content: \"\\f24e\";}\n\ -.fa-hourglass-o:before {content: \"\\f250\";}\n\ -.fa-hourglass-1:before, .fa-hourglass-start:before {content: \"\\f251\";}\n\ -.fa-hourglass-2:before, .fa-hourglass-half:before {content: \"\\f252\";}\n\ -.fa-hourglass-3:before, .fa-hourglass-end:before {content: \"\\f253\";}\n\ -.fa-hourglass:before {content: \"\\f254\";}\n\ -.fa-hand-grab-o:before, .fa-hand-rock-o:before {content: \"\\f255\";}\n\ -.fa-hand-stop-o:before, .fa-hand-paper-o:before {content: \"\\f256\";}\n\ -.fa-hand-scissors-o:before {content: \"\\f257\";}\n\ -.fa-hand-lizard-o:before {content: \"\\f258\";}\n\ -.fa-hand-spock-o:before {content: \"\\f259\";}\n\ -.fa-hand-pointer-o:before {content: \"\\f25a\";}\n\ -.fa-hand-peace-o:before {content: \"\\f25b\";}\n\ -.fa-trademark:before {content: \"\\f25c\";}\n\ -.fa-registered:before {content: \"\\f25d\";}\n\ -.fa-creative-commons:before {content: \"\\f25e\";}\n\ -.fa-gg:before {content: \"\\f260\";}\n\ -.fa-gg-circle:before {content: \"\\f261\";}\n\ -.fa-tripadvisor:before {content: \"\\f262\";}\n\ -.fa-odnoklassniki:before {content: \"\\f263\";}\n\ -.fa-odnoklassniki-square:before {content: \"\\f264\";}\n\ -.fa-get-pocket:before {content: \"\\f265\";}\n\ -.fa-wikipedia-w:before {content: \"\\f266\";}\n\ -.fa-safari:before {content: \"\\f267\";}\n\ -.fa-chrome:before {content: \"\\f268\";}\n\ -.fa-firefox:before {content: \"\\f269\";}\n\ -.fa-opera:before {content: \"\\f26a\";}\n\ -.fa-internet-explorer:before {content: \"\\f26b\";}\n\ -.fa-tv:before, .fa-television:before {content: \"\\f26c\";}\n\ -.fa-contao:before {content: \"\\f26d\";}\n\ -.fa-500px:before {content: \"\\f26e\";}\n\ -.fa-amazon:before {content: \"\\f270\";}\n\ -.fa-calendar-plus-o:before {content: \"\\f271\";}\n\ -.fa-calendar-minus-o:before {content: \"\\f272\";}\n\ -.fa-calendar-times-o:before {content: \"\\f273\";}\n\ -.fa-calendar-check-o:before {content: \"\\f274\";}\n\ -.fa-industry:before {content: \"\\f275\";}\n\ -.fa-map-pin:before {content: \"\\f276\";}\n\ -.fa-map-signs:before {content: \"\\f277\";}\n\ -.fa-map-o:before {content: \"\\f278\";}\n\ -.fa-map:before {content: \"\\f279\";}\n\ -.fa-commenting:before {content: \"\\f27a\";}\n\ -.fa-commenting-o:before {content: \"\\f27b\";}\n\ -.fa-houzz:before {content: \"\\f27c\";}\n\ -.fa-vimeo:before {content: \"\\f27d\";}\n\ -.fa-black-tie:before {content: \"\\f27e\";}\n\ -.fa-fonticons:before {content: \"\\f280\";}\n\ -.fa-reddit-alien:before {content: \"\\f281\";}\n\ -.fa-edge:before {content: \"\\f282\";}\n\ -.fa-credit-card-alt:before {content: \"\\f283\";}\n\ -.fa-codiepie:before {content: \"\\f284\";}\n\ -.fa-modx:before {content: \"\\f285\";}\n\ -.fa-fort-awesome:before {content: \"\\f286\";}\n\ -.fa-usb:before {content: \"\\f287\";}\n\ -.fa-product-hunt:before {content: \"\\f288\";}\n\ -.fa-mixcloud:before {content: \"\\f289\";}\n\ -.fa-scribd:before {content: \"\\f28a\";}\n\ -.fa-pause-circle:before {content: \"\\f28b\";}\n\ -.fa-pause-circle-o:before {content: \"\\f28c\";}\n\ -.fa-stop-circle:before {content: \"\\f28d\";}\n\ -.fa-stop-circle-o:before {content: \"\\f28e\";}\n\ -.fa-shopping-bag:before {content: \"\\f290\";}\n\ -.fa-shopping-basket:before {content: \"\\f291\";}\n\ -.fa-hashtag:before {content: \"\\f292\";}\n\ -.fa-bluetooth:before {content: \"\\f293\";}\n\ -.fa-bluetooth-b:before {content: \"\\f294\";}\n\ -.fa-percent:before {content: \"\\f295\";}\n\ -.fa-gitlab:before {content: \"\\f296\";}\n\ -.fa-wpbeginner:before {content: \"\\f297\";}\n\ -.fa-wpforms:before {content: \"\\f298\";}\n\ -.fa-envira:before {content: \"\\f299\";}\n\ -.fa-universal-access:before {content: \"\\f29a\";}\n\ -.fa-wheelchair-alt:before {content: \"\\f29b\";}\n\ -.fa-question-circle-o:before {content: \"\\f29c\";}\n\ -.fa-blind:before {content: \"\\f29d\";}\n\ -.fa-audio-description:before {content: \"\\f29e\";}\n\ -.fa-volume-control-phone:before {content: \"\\f2a0\";}\n\ -.fa-braille:before {content: \"\\f2a1\";}\n\ -.fa-assistive-listening-systems:before {content: \"\\f2a2\";}\n\ -.fa-asl-interpreting:before, .fa-american-sign-language-interpreting:before {content: \"\\f2a3\";}\n\ -.fa-deafness:before, .fa-hard-of-hearing:before, .fa-deaf:before {content: \"\\f2a4\";}\n\ -.fa-glide:before {content: \"\\f2a5\";}\n\ -.fa-glide-g:before {content: \"\\f2a6\";}\n\ -.fa-signing:before, .fa-sign-language:before {content: \"\\f2a7\";}\n\ -.fa-low-vision:before {content: \"\\f2a8\";}\n\ -.fa-viadeo:before {content: \"\\f2a9\";}\n\ -.fa-viadeo-square:before {content: \"\\f2aa\";}\n\ -.fa-snapchat:before {content: \"\\f2ab\";}\n\ -.fa-snapchat-ghost:before {content: \"\\f2ac\";}\n\ -.fa-snapchat-square:before {content: \"\\f2ad\";}\n\ -.fa-pied-piper:before {content: \"\\f2ae\";}\n\ -.fa-first-order:before {content: \"\\f2b0\";}\n\ -.fa-yoast:before {content: \"\\f2b1\";}\n\ -.fa-themeisle:before {content: \"\\f2b2\";}\n\ -.fa-google-plus-circle:before, .fa-google-plus-official:before {content: \"\\f2b3\";}\n\ -.fa-fa:before, .fa-font-awesome:before {content: \"\\f2b4\";}\n\ -.fa-handshake-o:before {content: \"\\f2b5\";}\n\ -.fa-envelope-open:before {content: \"\\f2b6\";}\n\ -.fa-envelope-open-o:before {content: \"\\f2b7\";}\n\ -.fa-linode:before {content: \"\\f2b8\";}\n\ -.fa-address-book:before {content: \"\\f2b9\";}\n\ -.fa-address-book-o:before {content: \"\\f2ba\";}\n\ -.fa-vcard:before, .fa-address-card:before {content: \"\\f2bb\";}\n\ -.fa-vcard-o:before, .fa-address-card-o:before {content: \"\\f2bc\";}\n\ -.fa-user-circle:before {content: \"\\f2bd\";}\n\ -.fa-user-circle-o:before {content: \"\\f2be\";}\n\ -.fa-user-o:before {content: \"\\f2c0\";}\n\ -.fa-id-badge:before {content: \"\\f2c1\";}\n\ -.fa-drivers-license:before, .fa-id-card:before {content: \"\\f2c2\";}\n\ -.fa-drivers-license-o:before, .fa-id-card-o:before {content: \"\\f2c3\";}\n\ -.fa-quora:before {content: \"\\f2c4\";}\n\ -.fa-free-code-camp:before {content: \"\\f2c5\";}\n\ -.fa-telegram:before {content: \"\\f2c6\";}\n\ -.fa-thermometer-4:before, .fa-thermometer:before, .fa-thermometer-full:before {content: \"\\f2c7\";}\n\ -.fa-thermometer-3:before, .fa-thermometer-three-quarters:before {content: \"\\f2c8\";}\n\ -.fa-thermometer-2:before, .fa-thermometer-half:before {content: \"\\f2c9\";}\n\ -.fa-thermometer-1:before, .fa-thermometer-quarter:before {content: \"\\f2ca\";}\n\ -.fa-thermometer-0:before, .fa-thermometer-empty:before {content: \"\\f2cb\";}\n\ -.fa-shower:before {content: \"\\f2cc\";}\n\ -.fa-bathtub:before, .fa-s15:before, .fa-bath:before {content: \"\\f2cd\";}\n\ -.fa-podcast:before {content: \"\\f2ce\";}\n\ -.fa-window-maximize:before {content: \"\\f2d0\";}\n\ -.fa-window-minimize:before {content: \"\\f2d1\";}\n\ -.fa-window-restore:before {content: \"\\f2d2\";}\n\ -.fa-times-rectangle:before, .fa-window-close:before {content: \"\\f2d3\";}\n\ -.fa-times-rectangle-o:before, .fa-window-close-o:before {content: \"\\f2d4\";}\n\ -.fa-bandcamp:before {content: \"\\f2d5\";}\n\ -.fa-grav:before {content: \"\\f2d6\";}\n\ -.fa-etsy:before {content: \"\\f2d7\";}\n\ -.fa-imdb:before {content: \"\\f2d8\";}\n\ -.fa-ravelry:before {content: \"\\f2d9\";}\n\ -.fa-eercast:before {content: \"\\f2da\";}\n\ -.fa-microchip:before {content: \"\\f2db\";}\n\ -.fa-snowflake-o:before {content: \"\\f2dc\";}\n\ -.fa-superpowers:before {content: \"\\f2dd\";}\n\ -.fa-wpexplorer:before {content: \"\\f2de\";}\n\ -.fa-meetup:before {content: \"\\f2e0\";}\n\ -.fa::before {\n\ - font-family: FontAwesome;\n\ - font-weight: 400;\n\ - font-style: normal;\n\ - -webkit-font-smoothing: antialiased;\n\ - text-decoration: inherit;\n\ - speak: none;\n\ - display: inline-block;\n\ - font-size: 13px;\n\ - visibility: visible;\n\ -}\n\ -:root:not(.shortcut-icons) #shortcuts .fa::before {\n\ - display: none;\n\ -}\n\ -:root.shortcut-icons #shortcuts .fa::before {\n\ - font-size: 15px !important;\n\ - margin-top: -3px !important;\n\ - position: relative;\n\ - top: 1px;\n\ -}\n\ -:root.shortcut-icons #shortcuts .fa, .menu-button .fa {\n\ - font-size: 0;\n\ - visibility: hidden;\n\ -}\n\ -:root.shortcut-icons .shortcut.brackets-wrap::after,\n\ -:root.shortcut-icons .shortcut.brackets-wrap::before {\n\ - display: none;\n\ -}\n\ -:root.shortcut-icons #shortcuts a .fa,\n\ -.menu-button .fa,\n\ -.hide-reply-button .fa,\n\ -.hide-thread-button .fa {\n\ - display: inline;\n\ -}\n\ -.fa-spin::before {\n\ - -webkit-animation:spin 2s infinite linear;\n\ - -moz-animation:spin 2s infinite linear;\n\ - -o-animation:spin 2s infinite linear;\n\ - animation:spin 2s infinite linear;\n\ -}\n\ -@-moz-keyframes spin {\n\ - 0% {-moz-transform:rotate(0deg);}\n\ - 100% {-moz-transform:rotate(359deg);}\n\ -}\n\ -@-webkit-keyframes spin {\n\ - 0% {-webkit-transform:rotate(0deg);}\n\ - 100% {-webkit-transform:rotate(359deg);}\n\ -}\n\ -@keyframes spin {\n\ - 0% {transform:rotate(0deg);}\n\ - 100% {transform:rotate(359deg);}\n\ -}\n\ -/* 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\ -}\n\ -label {\n\ - cursor: pointer;\n\ -}\n\ -a[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\ -}\n\ -body.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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Anti-autoplay */\n\ -audio.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\ -/* 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\ -/* 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\ -/* 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\ -}\n\ -div[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\ -/* 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\ -/* 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\ -/* Copy Text Link's textarea element */\n\ -textarea.copy-text-element {\n\ - height: 0;\n\ - width: 0;\n\ - position: absolute;\n\ - top: -10000px;\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\ -/* 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\ -/* 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\ -/* 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,\");\n\ -}\n\ -.watch-thread-link.watched {\n\ - opacity: 1;\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\ -/* 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\ -/* 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\ -/* File */\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 {\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 */\n\ -input[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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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),\n\ -body: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\ -}\n\ -input.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\ -/* 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\ -/* 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\ -}\n\ -input#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\ -/* 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,\n\ -input[type=\"checkbox\"]:focus ~ .checkbox-letter,\n\ -input[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\ -/* 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\ -/* 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\ -}\n\ -a: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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -: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\ -/* 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\ -/* PostJumper */\n\ -.postJumper > .prev,\n\ -.postJumper > .next {\n\ - font-size: 120%;\n\ -}\n\ -/* PSA */\n\ -.fcx-announcement {\n\ - text-align: center;\n\ -}\n\ -.fcx-announcement a {\n\ - text-decoration: underline;\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.yotsuba .indicator {\n\ - color: #F0E0D6;\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\ -/* 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\ -/* Unread */\n\ -:root.yotsuba .unread-mark-read {\n\ - background-color: rgba(240,224,214,0.5);\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\ -/* Watcher Favicon */\n\ -:root.yotsuba .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.yotsuba-b .indicator {\n\ - color: #D6DAF0;\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\ -/* 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\ -/* Unread */\n\ -:root.yotsuba-b .unread-mark-read {\n\ - background-color: rgba(214,218,240,0.5);\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\ -/* Watcher Favicon */\n\ -:root.yotsuba-b .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.futaba .indicator {\n\ - color: #F0E0D6;\n\ -}\n\ -/* Anonymize */\n\ -:root.futaba.anonymize $site$info$name::before {\n\ - font-size: 12pt;\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\ -/* 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\ -/* Unread */\n\ -:root.futaba .unread-mark-read {\n\ - background-color: rgba(240,224,214,0.5);\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\ -/* Watcher Favicon */\n\ -:root.futaba .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.burichan .indicator {\n\ - color: #D6DAF0;\n\ -}\n\ -/* Anonymize */\n\ -:root.burichan.anonymize $site$info$name::before {\n\ - font-size: 12pt;\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\ -/* 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\ -/* Unread */\n\ -:root.burichan .unread-mark-read {\n\ - background-color: rgba(214,218,240,0.5);\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\ -/* Watcher Favicon */\n\ -:root.burichan .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\n\ -}\n\ -/* General */\n\ -:root.tomorrow .dialog {\n\ - background-color: #282A2E;\n\ - border-color: #111;\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.tomorrow .indicator {\n\ - color: #282A2E;\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Watcher Favicon */\n\ -:root.tomorrow .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.photon .indicator {\n\ - color: #DDD;\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\ -/* 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\ -/* Unread */\n\ -:root.photon .unread-mark-read {\n\ - background-color: rgba(221,221,221,0.5);\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\ -/* Watcher Favicon */\n\ -:root.photon .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.spooky .indicator {\n\ - color: #171526;\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\ -/* 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\ -: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\ -/* 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\ -/* 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\ -/* 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\ -/* Watcher Favicon */\n\ -:root.spooky .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\n\ -}\n\ -/* Link Title Favicons */\n\ -.linkify.audio::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.bitchute::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAadQTFRFAAAAwzw8xDs7cY6O0iws0ysrtF9f0Sws1CwsyzU1zTIy1igoyzQ01icnY7i4t0hI0S4u0ysr1Soq1ikp1ikp1Soq0ysr0S4uu0VFzjEx1Csr1ygo2Ccn2Ccn1ygo1CoqzjExzjAw1Skp2Ccn2Ccn1ikp0TAwxzY21Soq1SoqyzQ00iws1ygo1ygo0yws1Soq1Skp1igo1igo1igo1igo1igo1igo1Coq1Soq0C0t1ygo1ygo0S4unV5e1Csr1ygo1ygo1CsruUdHxzg41Skp1ygo1CsryTU10C4u1igo1ycn1ygo0i0txjo60S0t1ikp1ygo1ikp1Cws1Coq1Coq0yws0S0tyzQ00iws1Soq0ysr0i0txDs72Ccn2CUl2CYm2CQk3EFB2S8v2zw82jY24FZW3D0931FR3EBA3UND8LS04FVV7qys4V9f4WBg+erq766u9t7e7qqq2Ckp54KC9+Pj6pSU+Ojo5XNz9NHR6YqK8bu765ub5G5u9M3N6ImJ88vL5XV165eX3UVF6pWV3UhI2Soq2jU12Coq2jQ02Cgo2Sws////FaxLuAAAAF10Uk5TAAAAAAAAAAAAAAAAAAAAASJnoLy9oWolAhBz1vr72XgTGKf8/a4cCpuiDVvz9mS6xOvy9vzg6aGsPOToRAFv9fh2Awm07XgIMd765UEDOsfemVhhY00nBommbCkEI8horgAAAL5JREFUKBUFwbFKA0EUQNF7387sMq4EmzRpLSSdIBYKFv6Af2prnSYkRT4gWFgkCBJQ0EIFdcZzBCeqqh4qdk7VW2ChPusw02sAYKU7z7wEAAA2piQKFbrWSHazc1J0XWs5pdxPDykcVX+7Y9UxUsSo+s7PibqPFBRV/C5qi4i/UkrJrc7L47Bt4ZWnUaMCAE9GSrtKBQD2fR+bnAEAeOn7dUTOwApe35bDsPz0zsniQlV98IN0tJ3f6P0XAMA/kxou7OXCdnoAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.clyp::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAwUExURTSY22ey5E2l4KbS75rM7Y3F64C/6f///8zl9nS45r/f9PL5/UGe3bPY8Vqr4v///wNjrzUAAAABYktHRA8YugDZAAAAB3RJTUUH4AINEi85AIH95AAAAE9JREFUCNdjYMAGGBWgDGYHCM2a3hkAZmi0dzSBaKaO9o5moCqmLiCjYzNQyw4QowIodQzI6E0AKcpo72gE6+Jyb1kAMehUA9RktgdYbQYAjGIVNGGXBJkAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.dailymotion::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAnUExURQBk3ff6/trp+kKO5wZt3xx54q7P9Ozz/IS17zOG5WKh653E8sbc9/GbbcoAAABZSURBVAjXY2BAASyhDhAGc9oECMOjyAAiESEEYrBYpLWBGcwHxcvBjDDxHelghpF0yDQwY3kVgweEUeEQDWbMEepqAjO8FMsLIeYsU8o+BrbCdWboTAe4AwALXxWGjW41FwAAAABJRU5ErkJggg==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.gfycat::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAjVBMVEWn3gCo3gSr3w2t4BSu4Bav4Ri35C+45DK45DO55DXA50rA50vB50zC6E/D6FTF6VjG6VvL62vN7G/P7XbQ7XfW74vY8JDa8ZTe8qDe8qLf86Pi9Kzj9K7k9LHp9sDp98Lq98Ps+Mr0++L5/O75/fD6/fH6/fL6/fP7/fT7/fb8/ff8/vj8/vn+/v7///91X4cfAAAAcklEQVR42o3M2xKBUACF4aVQckrIuRJK6H//x2sme4/MuPDfre9i6c/Cc3U5Dj87BuAxsXvGu6JvIIXEHRWwNHCHQNrCzkAFkbSBg4EM8i+Yw7PXBa3zRfuxVyf/Bis7nKwGKAcWxgC8prI5Sc315OlnDfzpDar2S9/oAAAAAElFTkSuQmCC') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.gist::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.image::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.installgentoo::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.liveleak::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.pastebin::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB1FBMVEUAAAAAAAAAAABWYWwAAABbY3BbYm5dZnFdZXJeZnMEBAQHCAhYYGpdZnFdZnBgaHIlJyomKCooKi09QkdESU5eZGtdYmhdYmleY2lrcXdqb3Rqb3Rqb3SSmJ+SlJeWmJutr7GtrrCWm6ChpKhbW1tmZmZvb290dHR3d3d4eHh5eXl6enp8fHx+gIJ/f3+CgoKDg4OEhISFhYWHh4eKioqKjI2Li4uMjIyOjo6Pj4+QkJCRkZGSkpKUlJSVl5mWlpaYmZqZm52ampqbm5ucnJydnZ2enp6fn5+hoaGioqKkpKSkpaalpaWmp6mmp6qnqauoqKioqquoqq2qqqqrrK2srKysra6srrCsrrGurq6vr6+wsLCxsbGysrKztLa0tLS1t7m2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr7AwMDAwsTBwcHExcfFxcXFxsnGxsbHx8fIyMjJycnMzMzNzc3Ozs7O0NLPz8/Q0NDR0dHR09XT09PV1dXV1dbV1tfV19rW1tbX19fX19jY2tzZ2dnZ2tva2tra3N3a3N7c3Nze3t7f39/f4OHg4ODi4uLl5+jm5ubs7Ozs7e3u7u7v7+/v8PDw8PDx8fHy8vLz8/P29vYSoLMZAAAAJHRSTlMABAUGCwsNHCAiLzMzMzZEYGJwgIuOnJycnqmqq9bc3+/w8fkZ0N/uAAAA/klEQVQoU2NgYGDl5YMDdgYGBmZZ3964CYFtIR3e9Q7K/AwMHI55KfaFmcHWMy3K3MwlGRg4wz0zdYpcorRbNbL0LaWAAp3ts2umV8wo6MupTauQBgqUG03VL7W3sfZSb1erAgm02M+yzYrVCXUy6zapAQlUx/dEdyX3J3ZHVUYVywAF8o2rDNN1Go2jzGLMokAC2QbuSc42mXmaOXop9iAtCXrJ5qXWjT59Abl2ESJAAX/tSIMMiyrrqQ3T6uS5gQK6kSqpqkUermGTexQFmYACflqR+hlWZSamzQpCLEDPsSmVVDT1TJw0JUhOAMRnYOARFRMTE5cQF+ZiBPIAII5B3EVG0b4AAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.peertube::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABIFBMVEUhHyAAAABzPBnxaA3CWBEnJSYbGRptbW16enpzc3PTayWhb04hHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyApIh+0UhMfHiBWMhvsZg7zaQ0hHyAhHyAXHCHzaQ3xaA3xaA3xaA3xaA0hHyAhHyDxaA3xaA3xaA3xaA3xaA3xaA0oJickIiMdGxwUEhPxaA3xaA3xaA1sbGxwcHB3d3eFhYXxaA3xaA3xaA1zc3Nzc3Nzc3Nzc3Nzc3PxaA3xaA3xaA1zc3Nzc3NtdHjxaA3xaA1yc3STcFnvaA/yaAxzc3N4c2/FbDFzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3MhHyDxaA1zc3MAAAAfljyVAAAAXHRSTlMAAAAAAAAAAAAAAAAZkjMBHOLXYArj8p0u2VsJ1XaGL/OhKyXc1WEN2gwk2/SjKgEYiS4B/tYFGosqAdleAxzj12ML9Z8s850rJWbYeYMs1F8Koiri1V0MGZY0AYbIBFIAAAABYktHRAH/Ai3eAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4wYXFBUVX81QWQAAAKxJREFUGNNVz9UWgkAQANDBtdbu7lZsxe7ubpH//wxBPKDzNvdMAmi0Oj0QQgAYjCazBX7BStvsDqHoAzTtdLklf+Dx+vwICRAIhsKRaCyOvpAwJ6Up8pXOZHOIAFm+UCzJEQuvMhWrIFBUa/WGkodmq40Ad7q9/kDFwnA05lpYYCbT2ZykFvxQDhhmuVpvcvxaHra7vfp72KflcMSYEOB0vlyx+By+3R9PMSfe+P0enM1454kAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDYtMjRUMDM6MjE6MjEtMDc6MDDse6MAAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTA2LTI0VDAzOjIxOjIxLTA3OjAwnSYbvAAAAABJRU5ErkJggg==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.soundcloud::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABsklEQVQ4y5WTy2pUQRCGv2rbzDjJeAlIBmOyipGIIJqFEBDElwh4yULGeRFXPoEIBl/AvQ/gC2RnxCAoxijiwks852S6+3dxzslcHJCpTXVX11/Xv0097gLPgVNMJxnQNfX4zsqleWbnpoMf/oa9d988MM9MC/rp+E0a+A0dsVobMNMCOO8B6McRoABJI+A6gJmN3D2A8jgEBCEkSEMBrcrsDAzDWWn3AjgKFaDMmgRqniGFgsaDp1jrLOngDf1XT1D+A1dFc4MKAkkiCVKjjVu7g9+4Rzx4i1u6hjXbuMWr0O5QPNvCu7IaCZwEKQukLGDrm5x8uI0tr6MkiGlkiv7yLfzN+6S5i6QsIMABkEfcxhbWWYMkVAOjxvYAjc3HNHrbKI9VBQBFwF25XQKSBjqIf1YBuAurEMrczgDygD6/x2LCpFLXLUyQ+PoldphhBhYfIX09XU1+Flaukz7uYqs3SHs7cG4BmTsmkBUF9mmXEwa28BNLPaQPLepuNcbGSWQquQC2/Kdcox1FUGkcB0ykck1nA2+wTzMs8stGnP4rbWGw74EuS/GFQWfK7/wF6P4F7fzIAYkdmdEAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.streamable::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.twitchtv::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAYUExURf///2RBpWRBpWRBpWRBpWRBpWRBpf///+zQyUYAAAAGdFJOUwFdZX0lTzs4r5oAAAABYktHRAcWYYjrAAAAB3RJTUUH4AINEi42iSXRNAAAAD1JREFUCNdjYEiDAAZGGIMtjQEEUBlMCWoEGci6mGEMsxQgIy0BiB3AjLS0FAYQIw0kwABipoI1AhkBQBIAFCIXxiHgq80AAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.twitter::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAEsUExURf///1Cf21Gg3FGi31Gh3VKj4FGh3lKj4VKk4lKl41Ol5FOn51Sp6VSo6FOn5lCf21Gg3FGh3VGi31Gi31Gh3lGg3FGg3FGg3FGg3FGh3lGg3FGi31Kk4lKj4FGh3lGi31Kk4lGh3lGg3FGh3lOm5FOm5VGi31Kj4VSo6FGi31Gh3VGg3FKj4FOn51Gi31So6FWr7VOl5FGi31On51Sq6lKk4lOo51Sp6VOm5FSq61Ws7VOn51Oo51Sq61Ol5FOm5FSq61Wr7VOo51On51Sr7FWs7VSp6lGg3FGh3VOm5FWr7VSp6lKj4VOm5FSo6FSr7FWs7VWs7VWr7VSq6lOo51Om5FOo51So6FOm5VOl5FSq61Ws7VSr7FSp6lSp6VWs7lWr7VKk4lSq6v///6E3MNsAAABVdFJOUwAAAAAAAAAAAAAAAAAAAB0Ii+3xnBVTJhfsMKb+qTEp9GwBF/7lLAbo0m4pLkUTdvk2Ev3+EZnOBo/3Z8ffCRzH/D0OqPxiLnvx3UI8m9n1++GwXQZNS29BAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+ACDRIwBwy67tEAAADKSURBVBjTY2BAB4xogIGRH8IQEBQSFhEVE2eQkJQC8ZmkQ8PCI2Rk5RjkIxUUlRgZlVWioqNjYlXVGNQ14iI1tbR14qLj4+MTdJkZ9PQNosJCE0OjgPz4KEMWBiPjhPiEmKQokIJ4E1MmBmazhHg4MGdlYmCzsLSC8ROsmRkZmFht4Eps7ViADmOzd4DyHZ2YmYACTOzOLmATXd04mIBOd/eQ9owFCXh5c7KB/MLi4+vnHxAYFBzCwcYEEmBi5uLm4eHl42RmAnsSAMZBLgZiFUQ5AAAAAElFTkSuQmCC') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.video::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAxgDGAP8nNqN7AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gMZBjQQLEEqGwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAA5SURBVDjLY2AYaMDIwMDwn1JD/lPCZhpwL+B1wf///ykzgBhDiAoDfIYQZQAjIyP5BuDTPJqQqAQAvW0ZAMk8+EEAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.vidlii::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.vimeo::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAYFBMVEUAAAAIdZUKh6sLlLkLmr4LmsAMp88NrdYVW3MZj7Acstkrt9s1e5E7vN5EfI9JvdtKwuBijp5kpbl30eiDt8aG1uqRr7qTyNehxM+k4PCy3enB3OTg6Ovv9PXw+fz////L9U5WAAAAAXRSTlMAQObYZgAAAIFJREFUeNplz90OwiAMBWAQpAoyxclkP3je/y0H2AQXz0WT8100rRD6kNI9/cRroemQL3hXhoujZYj4OHoAmBvYGcBISwbWBvfXCrytnIDUQMkbsBpagMA7zhtQdyTFQAmIG7IkYniiZuh3XGsPqoOZkMOJOpAcLqUzNFGGu/57fwc1hgtp0mVSyQAAAABJRU5ErkJggg==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.vine::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.vocaroo::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.youtube::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAYAAABr5z2BAAABIklEQVQoz53LvUrDUBjG8bOoOammSf1IoBSvoCB4JeIqOHgBLt6AIMRBBQelWurQ2kERnMRBsBUcIp5FJSBI5oQsJVkkUHh8W0o5nhaFHvjBgef/Mq+Q46RJBMkI/vE+aOus956tnEswIZe1LV0QyJ5sE2GzgZfVMtRNIdiDpccEssdlB1mW4bvTwdvWJtRdErM7U+8S/FJykCRJX5qm+KpVce8UMNLRLbulz4iSjTAMh6Iowsd5BeNadp3nUF0VlxAEwZBotXC0Usa4ll3meZdA1iguwvf9vpvDA2wvmKgYGtSud8suDB4TyGr2PF49D/vra9jRZ1BVdknMzgwuCGSnZEObwu6sBnVTCHZiaC7BhFx2PKdxUidiAH/4lLo9Mv0DELVs9qsOHXwAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -/* 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\ -/* 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(css) { - var variables = { - site: g.SITE.selectors - }; - return css.replace(/\$[\w\$]+/g, function(name) { - var words = name.slice(1).split('$'); - var sel = variables; - for (var i = 0; i < words.length; i++) { - if (typeof sel !== 'object') return ':not(*)'; - sel = $.getOwn(sel, words[i]); - } - if (typeof sel !== 'string') return ':not(*)'; - return sel; - }); -} - -}; - -$ = (function() { - var $, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - $ = function(selector, root) { - if (root == null) { - root = d.body; - } - return root.querySelector(selector); - }; - - $.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000))); - - $.id = function(id) { - return d.getElementById(id); - }; - - $.ready = function(fc) { - var cb; - if (d.readyState !== 'loading') { - $.queueTask(fc); - return; - } - cb = function() { - $.off(d, 'DOMContentLoaded', cb); - return fc(); - }; - return $.on(d, 'DOMContentLoaded', cb); - }; - - $.formData = function(form) { - var fd, key, val; - if (form instanceof HTMLFormElement) { - return new FormData(form); - } - fd = new FormData(); - for (key in form) { - val = form[key]; - if (val) { - if (typeof val === 'object' && 'newName' in val) { - fd.append(key, val, val.newName); - } else { - fd.append(key, val); - } - } - } - return fd; - }; - - $.extend = function(object, properties) { - var key, val; - for (key in properties) { - val = properties[key]; - object[key] = val; - } - }; - - $.dict = function() { - return Object.create(null); - }; - - $.dict.clone = function(obj) { - var arr, i, j, key, map, ref, val; - if (typeof obj !== 'object' || obj === null) { - return obj; - } else if (obj instanceof Array) { - arr = []; - for (i = j = 0, ref = obj.length; j < ref; i = j += 1) { - arr.push($.dict.clone(obj[i])); - } - return arr; - } else { - map = Object.create(null); - for (key in obj) { - val = obj[key]; - map[key] = $.dict.clone(val); - } - return map; - } - }; - - $.dict.json = function(str) { - return $.dict.clone(JSON.parse(str)); - }; - - $.hasOwn = function(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); - }; - - $.getOwn = function(obj, key) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - return obj[key]; - } else { - return void 0; - } - }; - - $.ajax = (function() { - var pageXHR; - if (window.wrappedJSObject && !XMLHttpRequest.wrappedJSObject) { - pageXHR = XPCNativeWrapper(window.wrappedJSObject.XMLHttpRequest); - } else { - pageXHR = XMLHttpRequest; - } - return function(url, options) { - var err, form, headers, key, onloadend, onprogress, r, ref, responseType, timeout, type, value, withCredentials; - if (options == null) { - options = {}; - } - if (options.responseType == null) { - options.responseType = 'json'; - } - options.type || (options.type = options.form && 'post' || 'get'); - url = url.replace(/^((?:https?:)?\/\/(?:\w+\.)?(?:4chan|4channel|4cdn)\.org)\/adv\//, '$1//adv/'); - onloadend = options.onloadend, timeout = options.timeout, responseType = options.responseType, withCredentials = options.withCredentials, type = options.type, onprogress = options.onprogress, form = options.form, headers = options.headers; - r = new pageXHR(); - try { - r.open(type, url, true); - ref = headers || {}; - for (key in ref) { - value = ref[key]; - r.setRequestHeader(key, value); - } - $.extend(r, { - onloadend: onloadend, - timeout: timeout, - responseType: responseType, - withCredentials: withCredentials - }); - $.extend(r.upload, { - onprogress: onprogress - }); - $.on(r, 'error', function() { - if (!r.status) { - return c.warn("4chan X failed to load: " + url); - } - }); - r.send(form); - } catch (error) { - err = error; - if (err.result !== 0x805e0006) { - throw err; - } - r.onloadend = onloadend; - $.queueTask($.event, 'error', null, r); - $.queueTask($.event, 'loadend', null, r); - } - return r; - }; - })(); - - $.lastModified = $.dict(); - - $.whenModified = function(url, bucket, cb, options) { - var ajax, headers, params, r, ref, t, timeout, url0; - if (options == null) { - options = {}; - } - timeout = options.timeout, ajax = options.ajax; - params = []; - if ($.engine === 'blink') { - params.push("s=" + bucket); - } - if (url.split('/')[2] === 'a.4cdn.org') { - params.push("t=" + (Date.now())); - } - url0 = url; - if (params.length) { - url += '?' + params.join('&'); - } - headers = $.dict(); - if ((t = (ref = $.lastModified[bucket]) != null ? ref[url0] : void 0) != null) { - headers['If-Modified-Since'] = t; - } - r = (ajax || $.ajax)(url, { - onloadend: function() { - var base; - ((base = $.lastModified)[bucket] || (base[bucket] = $.dict()))[url0] = this.getResponseHeader('Last-Modified'); - return cb.call(this); - }, - timeout: timeout, - headers: headers - }); - return r; - }; - - (function() { - var reqs; - reqs = $.dict(); - $.cache = function(url, cb, options) { - var ajax, onloadend, req; - if (options == null) { - options = {}; - } - ajax = options.ajax; - if ((req = reqs[url])) { - if (req.callbacks) { - req.callbacks.push(cb); - } else { - $.queueTask(function() { - return cb.call(req, { - isCached: true - }); - }); - } - return req; - } - onloadend = function() { - var fn1, j, len, ref; - if (!this.status) { - delete reqs[url]; - } - ref = this.callbacks; - fn1 = (function(_this) { - return function(cb) { - return $.queueTask(function() { - return cb.call(_this, { - isCached: false - }); - }); - }; - })(this); - for (j = 0, len = ref.length; j < len; j++) { - cb = ref[j]; - fn1(cb); - } - return delete this.callbacks; - }; - req = (ajax || $.ajax)(url, { - onloadend: onloadend - }); - req.callbacks = [cb]; - return reqs[url] = req; - }; - return $.cleanCache = function(testf) { - var url; - for (url in reqs) { - if (testf(url)) { - delete reqs[url]; - } - } - }; - })(); - - $.cb = { - checked: function() { - if ($.hasOwn(Conf, this.name)) { - $.set(this.name, this.checked); - return Conf[this.name] = this.checked; - } - }, - value: function() { - if ($.hasOwn(Conf, this.name)) { - $.set(this.name, this.value.trim()); - return Conf[this.name] = this.value; - } - } - }; - - $.asap = function(test, cb) { - if (test()) { - return cb(); - } else { - return setTimeout($.asap, 25, test, cb); - } - }; - - $.onExists = function(root, selector, cb) { - var el, observer; - if (el = $(selector, root)) { - return cb(el); - } - observer = new MutationObserver(function() { - if (el = $(selector, root)) { - observer.disconnect(); - return cb(el); - } - }); - return observer.observe(root, { - childList: true, - subtree: true - }); - }; - - $.addStyle = function(css, id, test) { - var style; - if (test == null) { - test = 'head'; - } - style = $.el('style', { - textContent: css - }); - if (id != null) { - style.id = id; - } - $.onExists(doc, test, function() { - return $.add(d.head, style); - }); - return style; - }; - - $.addCSP = function(policy) { - var head, meta; - meta = $.el('meta', { - httpEquiv: 'Content-Security-Policy', - content: policy - }); - if (d.head) { - $.add(d.head, meta); - return $.rm(meta); - } else { - head = $.add(doc || d, $.el('head')); - $.add(head, meta); - return $.rm(head); - } - }; - - $.x = function(path, root) { - root || (root = d.body); - return d.evaluate(path, root, null, 8, null).singleNodeValue; - }; - - $.X = function(path, root) { - root || (root = d.body); - return d.evaluate(path, root, null, 7, null); - }; - - $.addClass = function() { - var className, classNames, el, j, len; - el = arguments[0], classNames = 2 <= arguments.length ? slice.call(arguments, 1) : []; - for (j = 0, len = classNames.length; j < len; j++) { - className = classNames[j]; - el.classList.add(className); - } - }; - - $.rmClass = function() { - var className, classNames, el, j, len; - el = arguments[0], classNames = 2 <= arguments.length ? slice.call(arguments, 1) : []; - for (j = 0, len = classNames.length; j < len; j++) { - className = classNames[j]; - el.classList.remove(className); - } - }; - - $.toggleClass = function(el, className) { - return el.classList.toggle(className); - }; - - $.hasClass = function(el, className) { - return indexOf.call(el.classList, className) >= 0; - }; - - $.rm = function(el) { - return el != null ? el.remove() : void 0; - }; - - $.rmAll = function(root) { - return root.textContent = null; - }; - - $.tn = function(s) { - return d.createTextNode(s); - }; - - $.frag = function() { - return d.createDocumentFragment(); - }; - - $.nodes = function(nodes) { - var frag, j, len, node; - if (!(nodes instanceof Array)) { - return nodes; - } - frag = $.frag(); - for (j = 0, len = nodes.length; j < len; j++) { - node = nodes[j]; - frag.appendChild(node); - } - return frag; - }; - - $.add = function(parent, el) { - return parent.appendChild($.nodes(el)); - }; - - $.prepend = function(parent, el) { - return parent.insertBefore($.nodes(el), parent.firstChild); - }; - - $.after = function(root, el) { - return root.parentNode.insertBefore($.nodes(el), root.nextSibling); - }; - - $.before = function(root, el) { - return root.parentNode.insertBefore($.nodes(el), root); - }; - - $.replace = function(root, el) { - return root.parentNode.replaceChild($.nodes(el), root); - }; - - $.el = function(tag, properties, properties2) { - var el; - el = d.createElement(tag); - if (properties) { - $.extend(el, properties); - } - if (properties2) { - $.extend(el, properties2); - } - return el; - }; - - $.on = function(el, events, handler) { - var event, j, len, ref; - ref = events.split(' '); - for (j = 0, len = ref.length; j < len; j++) { - event = ref[j]; - el.addEventListener(event, handler, false); - } - }; - - $.off = function(el, events, handler) { - var event, j, len, ref; - ref = events.split(' '); - for (j = 0, len = ref.length; j < len; j++) { - event = ref[j]; - el.removeEventListener(event, handler, false); - } - }; - - $.one = function(el, events, handler) { - var cb; - cb = function(e) { - $.off(el, events, cb); - return handler.call(this, e); - }; - return $.on(el, events, cb); - }; - - $.event = function(event, detail, root) { - if (root == null) { - root = d; - } - if ((detail != null) && typeof cloneInto === 'function') { - detail = cloneInto(detail, d.defaultView); - } - return root.dispatchEvent(new CustomEvent(event, { - bubbles: true, - cancelable: true, - detail: detail - })); - }; - - (function() { - var clone, err, ref, unsafeConstructors; - if (!(/PaleMoon\//.test(navigator.userAgent) && +(typeof GM_info !== "undefined" && GM_info !== null ? (ref = GM_info.version) != null ? ref.split('.')[0] : void 0 : void 0) >= 2 && typeof cloneInto === 'undefined')) { - return; - } - try { - return new CustomEvent('x', { - detail: {} - }); - } catch (error) { - err = error; - unsafeConstructors = { - Object: unsafeWindow.Object, - Array: unsafeWindow.Array - }; - clone = function(obj) { - var constructor, key, obj2, val; - if ((obj != null) && typeof obj === 'object' && (constructor = unsafeConstructors[obj.constructor.name])) { - obj2 = new constructor(); - for (key in obj) { - val = obj[key]; - obj2[key] = clone(val); - } - return obj2; - } else { - return obj; - } - }; - return $.event = function(event, detail, root) { - if (root == null) { - root = d; - } - return root.dispatchEvent(new CustomEvent(event, { - bubbles: true, - cancelable: true, - detail: clone(detail) - })); - }; - } - })(); - - $.modifiedClick = function(e) { - return e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0; - }; - - $.open = (typeof GM !== "undefined" && GM !== null ? GM.openInTab : void 0) != null ? GM.openInTab : typeof GM_openInTab !== "undefined" && GM_openInTab !== null ? GM_openInTab : function(url) { - return window.open(url, '_blank'); - }; - - $.debounce = function(wait, fn) { - var args, exec, lastCall, that, timeout; - lastCall = 0; - timeout = null; - that = null; - args = null; - exec = function() { - lastCall = Date.now(); - return fn.apply(that, args); - }; - return function() { - args = arguments; - that = this; - if (lastCall < Date.now() - wait) { - return exec(); - } - clearTimeout(timeout); - return timeout = setTimeout(exec, wait); - }; - }; - - $.queueTask = (function() { - var execTask, taskChannel, taskQueue; - taskQueue = []; - execTask = function() { - var args, func, task; - task = taskQueue.shift(); - func = task[0]; - args = Array.prototype.slice.call(task, 1); - return func.apply(func, args); - }; - if (window.MessageChannel) { - taskChannel = new MessageChannel(); - taskChannel.port1.onmessage = execTask; - return function() { - taskQueue.push(arguments); - return taskChannel.port2.postMessage(null); - }; - } else { - return function() { - taskQueue.push(arguments); - return setTimeout(execTask, 0); - }; - } - })(); - - $.global = function(fn, data) { - var script; - if (doc) { - script = $.el('script', { - textContent: "(" + fn + ").call(document.currentScript.dataset);" - }); - if (data) { - $.extend(script.dataset, data); - } - $.add(d.head || doc, script); - $.rm(script); - return script.dataset; - } else { - try { - fn.call(data); - } catch (error) {} - return data; - } - }; - - $.bytesToString = function(size) { - var unit; - unit = 0; - while (size >= 1024) { - size /= 1024; - unit++; - } - size = unit > 1 ? Math.round(size * 100) / 100 : Math.round(size); - return size + " " + ['B', 'KB', 'MB', 'GB'][unit]; - }; - - $.minmax = function(value, min, max) { - return (value < min ? min : value > max ? max : value); - }; - - $.hasAudio = function(video) { - return video.mozHasAudio || !!video.webkitAudioDecodedByteCount; - }; - - $.luma = function(rgb) { - return rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114; - }; - - $.unescape = function(text) { - if (text == null) { - return text; - } - return text.replace(/<[^>]*>/g, '').replace(/&(amp|#039|quot|lt|gt|#44);/g, function(c) { - return { - '&': '&', - ''': "'", - '"': '"', - '<': '<', - '>': '>', - ',': ',' - }[c]; - }); - }; - - $.isImage = function(url) { - return /\.(jpe?g|jfif|png|gif|bmp|webp|avif|jxl)$/i.test(url); - }; - - $.isVideo = function(url) { - return /\.(webm|mp4|ogv)$/i.test(url); - }; - - $.engine = (function() { - if (/Edge\//.test(navigator.userAgent)) { - return 'edge'; - } - if (/Chrome\//.test(navigator.userAgent)) { - return 'blink'; - } - if (/WebKit\//.test(navigator.userAgent)) { - return 'webkit'; - } - if (/Gecko\/|Goanna/.test(navigator.userAgent)) { - return 'gecko'; - } - })(); - - $.platform = 'userscript'; - - $.hasStorage = (function() { - try { - if (localStorage.getItem(g.NAMESPACE + 'hasStorage') === 'true') { - return true; - } - localStorage.setItem(g.NAMESPACE + 'hasStorage', 'true'); - return localStorage.getItem(g.NAMESPACE + 'hasStorage') === 'true'; - } catch (error) { - return false; - } - })(); - - $.item = function(key, val) { - var item; - item = $.dict(); - item[key] = val; - return item; - }; - - $.oneItemSugar = function(fn) { - return function(key, val, cb) { - if (typeof key === 'string') { - return fn($.item(key, val), cb); - } else { - return fn(key, val); - } - }; - }; - - $.syncing = $.dict(); - - $.securityCheck = function(data) { - if (location.protocol !== 'https:') { - return delete data['Redirect to HTTPS']; - } - }; - - if (((typeof GM !== "undefined" && GM !== null ? GM.deleteValue : void 0) != null) && window.BroadcastChannel && (typeof GM_addValueChangeListener === "undefined" || GM_addValueChangeListener === null)) { - $.syncChannel = new BroadcastChannel(g.NAMESPACE + 'sync'); - $.on($.syncChannel, 'message', function(e) { - var cb, key, ref, results, val; - ref = e.data; - results = []; - for (key in ref) { - val = ref[key]; - if ((cb = $.syncing[key])) { - results.push(cb($.dict.json(JSON.stringify(val)), key)); - } - } - return results; - }); - $.sync = function(key, cb) { - return $.syncing[key] = cb; - }; - $.forceSync = function() {}; - $["delete"] = function(keys, cb) { - var key; - if (!(keys instanceof Array)) { - keys = [keys]; - } - return Promise.all((function() { - var j, len, results; - results = []; - for (j = 0, len = keys.length; j < len; j++) { - key = keys[j]; - results.push(GM.deleteValue(g.NAMESPACE + key)); - } - return results; - })()).then(function() { - var items, j, key, len; - items = $.dict(); - for (j = 0, len = keys.length; j < len; j++) { - key = keys[j]; - items[key] = void 0; - } - $.syncChannel.postMessage(items); - return typeof cb === "function" ? cb() : void 0; - }); - }; - $.get = $.oneItemSugar(function(items, cb) { - var key, keys; - keys = Object.keys(items); - return Promise.all((function() { - var j, len, results; - results = []; - for (j = 0, len = keys.length; j < len; j++) { - key = keys[j]; - results.push(GM.getValue(g.NAMESPACE + key)); - } - return results; - })()).then(function(values) { - var i, j, len, val; - for (i = j = 0, len = values.length; j < len; i = ++j) { - val = values[i]; - if (val) { - items[keys[i]] = $.dict.json(val); - } - } - return cb(items); - }); - }); - $.set = $.oneItemSugar(function(items, cb) { - var key, val; - $.securityCheck(items); - return Promise.all((function() { - var results; - results = []; - for (key in items) { - val = items[key]; - results.push(GM.setValue(g.NAMESPACE + key, JSON.stringify(val))); - } - return results; - })()).then(function() { - $.syncChannel.postMessage(items); - return typeof cb === "function" ? cb() : void 0; - }); - }); - $.clear = function(cb) { - return GM.listValues().then(function(keys) { - return $["delete"](keys.map(function(key) { - return key.replace(g.NAMESPACE, ''); - }), cb); - })["catch"](function() { - return $["delete"](Object.keys(Conf).concat(['previousversion', 'QR Size', 'QR.persona']), cb); - }); - }; - } else { - if (typeof GM_deleteValue === "undefined" || GM_deleteValue === null) { - $.perProtocolSettings = true; - } - if (typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) { - $.getValue = GM_getValue; - $.listValues = function() { - return GM_listValues(); - }; - } else if ($.hasStorage) { - $.getValue = function(key) { - return localStorage.getItem(key); - }; - $.listValues = function() { - var key, results; - results = []; - for (key in localStorage) { - if (key.slice(0, g.NAMESPACE.length) === g.NAMESPACE) { - results.push(key); - } - } - return results; - }; - } else { - $.getValue = function() {}; - $.listValues = function() { - return []; - }; - } - if (typeof GM_addValueChangeListener !== "undefined" && GM_addValueChangeListener !== null) { - $.setValue = GM_setValue; - $.deleteValue = GM_deleteValue; - } else if (typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) { - $.oldValue = $.dict(); - $.setValue = function(key, val) { - GM_setValue(key, val); - if (key in $.syncing) { - $.oldValue[key] = val; - if ($.hasStorage) { - return localStorage.setItem(key, val); - } - } - }; - $.deleteValue = function(key) { - GM_deleteValue(key); - if (key in $.syncing) { - delete $.oldValue[key]; - if ($.hasStorage) { - return localStorage.removeItem(key); - } - } - }; - if (!$.hasStorage) { - $.cantSync = true; - } - } else if ($.hasStorage) { - $.oldValue = $.dict(); - $.setValue = function(key, val) { - if (key in $.syncing) { - $.oldValue[key] = val; - } - return localStorage.setItem(key, val); - }; - $.deleteValue = function(key) { - if (key in $.syncing) { - delete $.oldValue[key]; - } - return localStorage.removeItem(key); - }; - } else { - $.setValue = function() {}; - $.deleteValue = function() {}; - $.cantSync = $.cantSet = true; - } - if (typeof GM_addValueChangeListener !== "undefined" && GM_addValueChangeListener !== null) { - $.sync = function(key, cb) { - return $.syncing[key] = GM_addValueChangeListener(g.NAMESPACE + key, function(key2, oldValue, newValue, remote) { - if (remote) { - if (newValue !== void 0) { - newValue = $.dict.json(newValue); - } - return cb(newValue, key); - } - }); - }; - $.forceSync = function() {}; - } else if ((typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) || $.hasStorage) { - $.sync = function(key, cb) { - key = g.NAMESPACE + key; - $.syncing[key] = cb; - return $.oldValue[key] = $.getValue(key); - }; - (function() { - var onChange; - onChange = function(arg) { - var cb, key, newValue; - key = arg.key, newValue = arg.newValue; - if (!(cb = $.syncing[key])) { - return; - } - if (newValue != null) { - if (newValue === $.oldValue[key]) { - return; - } - $.oldValue[key] = newValue; - return cb($.dict.json(newValue), key.slice(g.NAMESPACE.length)); - } else { - if ($.oldValue[key] == null) { - return; - } - delete $.oldValue[key]; - return cb(void 0, key.slice(g.NAMESPACE.length)); - } - }; - $.on(window, 'storage', onChange); - return $.forceSync = function(key) { - key = g.NAMESPACE + key; - return onChange({ - key: key, - newValue: $.getValue(key) - }); - }; - })(); - } else { - $.sync = function() {}; - $.forceSync = function() {}; - } - $["delete"] = function(keys) { - var j, key, len; - if (!(keys instanceof Array)) { - keys = [keys]; - } - for (j = 0, len = keys.length; j < len; j++) { - key = keys[j]; - $.deleteValue(g.NAMESPACE + key); - } - }; - $.get = $.oneItemSugar(function(items, cb) { - return $.queueTask($.getSync, items, cb); - }); - $.getSync = function(items, cb) { - var err, key, val2; - for (key in items) { - if ((val2 = $.getValue(g.NAMESPACE + key))) { - try { - items[key] = $.dict.json(val2); - } catch (error) { - err = error; - if (!/^(?:undefined)*$/.test(val2)) { - throw err; - } - } - } - } - return cb(items); - }; - $.set = $.oneItemSugar(function(items, cb) { - $.securityCheck(items); - return $.queueTask(function() { - var key, value; - for (key in items) { - value = items[key]; - $.setValue(g.NAMESPACE + key, JSON.stringify(value)); - } - return typeof cb === "function" ? cb() : void 0; - }); - }); - $.clear = function(cb) { - $["delete"](Object.keys(Conf)); - $["delete"](['previousversion', 'QR Size', 'QR.persona']); - try { - $["delete"]($.listValues().map(function(key) { - return key.replace(g.NAMESPACE, ''); - })); - } catch (error) {} - return typeof cb === "function" ? cb() : void 0; - }; - } - - return $; - -}).call(this); - -$$ = (function() { - var $$, - slice = [].slice; - - $$ = function(selector, root) { - if (root == null) { - root = d.body; - } - return slice.call(root.querySelectorAll(selector)); - }; - - return $$; - -}).call(this); - -CrossOrigin = (function() { - var CrossOrigin, Request; - - CrossOrigin = { - binary: function(url, cb, headers) { - var fallback, gmOptions; - if (headers == null) { - headers = $.dict(); - } - url = url.replace(/^((?:https?:)?\/\/(?:\w+\.)?(?:4chan|4channel|4cdn)\.org)\/adv\//, '$1//adv/'); - fallback = function() { - return $.ajax(url, { - headers: headers, - responseType: 'arraybuffer', - onloadend: function() { - if (this.status && this.response) { - return cb(new Uint8Array(this.response), this.getAllResponseHeaders()); - } else { - return cb(null); - } - } - }); - }; - if (!(((typeof GM !== "undefined" && GM !== null ? GM.xmlHttpRequest : void 0) != null) || (typeof GM_xmlhttpRequest !== "undefined" && GM_xmlhttpRequest !== null))) { - fallback(); - return; - } - gmOptions = { - method: "GET", - url: url, - headers: headers, - responseType: 'arraybuffer', - overrideMimeType: 'text/plain; charset=x-user-defined', - onload: function(xhr) { - var data, i, r; - if (xhr.response instanceof ArrayBuffer) { - data = new Uint8Array(xhr.response); - } else { - r = xhr.responseText; - data = new Uint8Array(r.length); - i = 0; - while (i < r.length) { - data[i] = r.charCodeAt(i); - i++; - } - } - return cb(data, xhr.responseHeaders); - }, - onerror: function() { - return cb(null); - }, - onabort: function() { - return cb(null); - } - }; - try { - return ((typeof GM !== "undefined" && GM !== null ? GM.xmlHttpRequest : void 0) || GM_xmlhttpRequest)(gmOptions); - } catch (error) { - return fallback(); - } - }, - file: function(url, cb) { - return CrossOrigin.binary(url, function(data, headers) { - var blob, contentDisposition, contentType, match, mime, name, ref, ref1, ref2, ref3, ref4; - if (data == null) { - return cb(null); - } - name = (ref = url.match(/([^\/?#]+)\/*(?:$|[?#])/)) != null ? ref[1] : void 0; - contentType = (ref1 = headers.match(/Content-Type:\s*(.*)/i)) != null ? ref1[1] : void 0; - contentDisposition = (ref2 = headers.match(/Content-Disposition:\s*(.*)/i)) != null ? ref2[1] : void 0; - mime = (contentType != null ? contentType.match(/[^;]*/)[0] : void 0) || 'application/octet-stream'; - match = (contentDisposition != null ? (ref3 = contentDisposition.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)) != null ? ref3[1] : void 0 : void 0) || (contentType != null ? (ref4 = contentType.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)) != null ? ref4[1] : void 0 : void 0); - if (match) { - name = match.replace(/\\"/g, '"'); - } - if (/^text\/plain;\s*charset=x-user-defined$/i.test(mime)) { - mime = $.getOwn(QR.typeFromExtension, name.match(/[^.]*$/)[0].toLowerCase()) || 'application/octet-stream'; - } - blob = new Blob([data], { - type: mime - }); - blob.name = name; - return cb(blob); - }); - }, - Request: Request = (function() { - function Request() {} - - Request.prototype.status = 0; - - Request.prototype.statusText = ''; - - Request.prototype.response = null; - - Request.prototype.responseHeaderString = null; - - Request.prototype.getResponseHeader = function(headerName) { - var header, i, j, key, len, ref, ref1, ref2, val; - if ((this.responseHeaders == null) && (this.responseHeaderString != null)) { - this.responseHeaders = $.dict(); - ref = this.responseHeaderString.split('\r\n'); - for (j = 0, len = ref.length; j < len; j++) { - header = ref[j]; - if ((i = header.indexOf(':')) >= 0) { - key = header.slice(0, i).trim().toLowerCase(); - val = header.slice(i + 1).trim(); - this.responseHeaders[key] = val; - } - } - } - return (ref1 = (ref2 = this.responseHeaders) != null ? ref2[headerName.toLowerCase()] : void 0) != null ? ref1 : null; - }; - - Request.prototype.abort = function() {}; - - Request.prototype.onloadend = function() {}; - - return Request; - - })(), - ajax: function(url, options) { - var gmOptions, gmReq, headers, onloadend, req, responseType, timeout; - if (options == null) { - options = {}; - } - onloadend = options.onloadend, timeout = options.timeout, responseType = options.responseType, headers = options.headers; - if (responseType == null) { - responseType = 'json'; - } - if (!(((typeof GM !== "undefined" && GM !== null ? GM.xmlHttpRequest : void 0) != null) || (typeof GM_xmlhttpRequest !== "undefined" && GM_xmlhttpRequest !== null))) { - return $.ajax(url, options); - } - req = new CrossOrigin.Request(); - req.onloadend = onloadend; - gmOptions = { - method: 'GET', - url: url, - headers: headers, - timeout: timeout, - onload: function(xhr) { - var response; - try { - response = (function() { - switch (responseType) { - case 'json': - if (xhr.responseText) { - return JSON.parse(xhr.responseText); - } else { - return null; - } - break; - default: - return xhr.responseText; - } - })(); - $.extend(req, { - response: response, - status: xhr.status, - statusText: xhr.statusText, - responseHeaderString: xhr.responseHeaders - }); - } catch (error) {} - return req.onloadend(); - }, - onerror: function() { - return req.onloadend(); - }, - onabort: function() { - return req.onloadend(); - }, - ontimeout: function() { - return req.onloadend(); - } - }; - try { - gmReq = ((typeof GM !== "undefined" && GM !== null ? GM.xmlHttpRequest : void 0) || GM_xmlhttpRequest)(gmOptions); - } catch (error) { - return $.ajax(url, options); - } - if (gmReq && typeof gmReq.abort === 'function') { - req.abort = function() { - try { - return gmReq.abort(); - } catch (error) {} - }; - } - return req; - }, - cache: function(url, cb) { - return $.cache(url, cb, { - ajax: CrossOrigin.ajax - }); - }, - permission: function(cb) { - return cb(); - } - }; - - return CrossOrigin; - -}).call(this); - -Board = (function() { - var Board; - - Board = (function() { - Board.prototype.toString = function() { - return this.ID; - }; - - function Board(ID) { - var ref; - this.ID = ID; - this.boardID = this.ID; - this.siteID = g.SITE.ID; - this.threads = new SimpleDict(); - this.posts = new SimpleDict(); - this.config = ((ref = BoardConfig.boards) != null ? ref[this.ID] : void 0) || {}; - g.boards[this] = this; - } - - Board.prototype.cooldowns = function() { - var c, c2, i, key, len, ref; - c2 = (this.config || {}).cooldowns || {}; - c = { - thread: c2.threads || 0, - reply: c2.replies || 0, - image: c2.images || 0, - thread_global: 300 - }; - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - ref = ['reply', 'image']; - for (i = 0, len = ref.length; i < len; i++) { - key = ref[i]; - c[key] = Math.ceil(c[key] / 2); - } - } - return c; - }; - - return Board; - - })(); - - return Board; - -}).call(this); - -Callbacks = (function() { - var Callbacks; - - Callbacks = (function() { - Callbacks.Post = new Callbacks('Post'); - - Callbacks.Thread = new Callbacks('Thread'); - - Callbacks.CatalogThread = new Callbacks('Catalog Thread'); - - Callbacks.CatalogThreadNative = new Callbacks('Catalog Thread'); - - function Callbacks(type) { - this.type = type; - this.keys = []; - } - - Callbacks.prototype.push = function(arg) { - var cb, name; - name = arg.name, cb = arg.cb; - if (!this[name]) { - this.keys.push(name); - } - return this[name] = cb; - }; - - Callbacks.prototype.execute = function(node, keys, force) { - var err, errors, i, len, name, ref, ref1, ref2; - if (keys == null) { - keys = this.keys; - } - if (force == null) { - force = false; - } - if (node.callbacksExecuted && !force) { - return; - } - node.callbacksExecuted = true; - for (i = 0, len = keys.length; i < len; i++) { - name = keys[i]; - try { - if ((ref = this[name]) != null) { - ref.call(node); - } - } catch (error) { - err = error; - if (!errors) { - errors = []; - } - errors.push({ - message: ['"', name, '" crashed on node ', this.type, ' No.', node.ID, ' (', node.board, ').'].join(''), - error: err, - html: (ref1 = node.nodes) != null ? (ref2 = ref1.root) != null ? ref2.outerHTML : void 0 : void 0 - }); - } - } - if (errors) { - return Main.handleErrors(errors); - } - }; - - return Callbacks; - - })(); - - return Callbacks; - -}).call(this); - -CatalogThread = (function() { - var CatalogThread; - - CatalogThread = (function() { - CatalogThread.prototype.toString = function() { - return this.ID; - }; - - function CatalogThread(root, thread) { - var post; - this.thread = thread; - this.ID = this.thread.ID; - this.board = this.thread.board; - post = this.thread.OP.nodes.post; - this.nodes = { - root: root, - thumb: $('.catalog-thumb', post), - icons: $('.catalog-icons', post), - postCount: $('.post-count', post), - fileCount: $('.file-count', post), - pageCount: $('.page-count', post), - replies: null - }; - this.thread.catalogView = this; - } - - return CatalogThread; - - })(); - - return CatalogThread; - -}).call(this); - -CatalogThreadNative = (function() { - var CatalogThreadNative; - - CatalogThreadNative = (function() { - CatalogThreadNative.prototype.toString = function() { - return this.ID; - }; - - function CatalogThreadNative(root) { - this.nodes = { - root: root, - thumb: $(g.SITE.selectors.catalog.thumb, root) - }; - this.siteID = g.SITE.ID; - this.boardID = this.nodes.thumb.parentNode.pathname.split(/\/+/)[1]; - this.board = g.boards[this.boardID] || new Board(this.boardID); - this.ID = this.threadID = +(root.dataset.id || root.id).match(/\d*$/)[0]; - this.thread = this.board.threads.get(this.ID) || new Thread(this.ID, this.board); - } - - return CatalogThreadNative; - - })(); - - return CatalogThreadNative; - -}).call(this); - -Connection = (function() { - var Connection, - bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - - Connection = (function() { - function Connection(target, origin, cb) { - this.target = target; - this.origin = origin; - this.cb = cb != null ? cb : {}; - this.onMessage = bind(this.onMessage, this); - this.send = bind(this.send, this); - $.on(window, 'message', this.onMessage); - } - - Connection.prototype.targetWindow = function() { - if (this.target instanceof window.HTMLIFrameElement) { - return this.target.contentWindow; - } else { - return this.target; - } - }; - - Connection.prototype.send = function(data) { - return this.targetWindow().postMessage("" + g.NAMESPACE + (JSON.stringify(data)), this.origin); - }; - - Connection.prototype.onMessage = function(e) { - var data, type, value; - if (!(e.source === this.targetWindow() && e.origin === this.origin && typeof e.data === 'string' && e.data.slice(0, g.NAMESPACE.length) === g.NAMESPACE)) { - return; - } - data = JSON.parse(e.data.slice(g.NAMESPACE.length)); - for (type in data) { - value = data[type]; - if ($.hasOwn(this.cb, type)) { - this.cb[type](value); - } - } - }; - - return Connection; - - })(); - - return Connection; - -}).call(this); - -DataBoard = (function() { - var DataBoard, - bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - - DataBoard = (function() { - DataBoard.keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads', 'watcherLastModified', 'customTitles']; - - function DataBoard(key1, sync, dontClean) { - var init; - this.key = key1; - this.onSync = bind(this.onSync, this); - this.initData(Conf[this.key]); - $.sync(this.key, this.onSync); - if (!dontClean) { - this.clean(); - } - if (!sync) { - return; - } - init = (function(_this) { - return function() { - $.off(d, '4chanXInitFinished', init); - return _this.sync = sync; - }; - })(this); - $.on(d, '4chanXInitFinished', init); - } - - DataBoard.prototype.initData = function(data1) { - var base, boards, lastChecked, name, ref; - this.data = data1; - if (this.data.boards) { - ref = this.data, boards = ref.boards, lastChecked = ref.lastChecked; - this.data['4chan.org'] = { - boards: boards, - lastChecked: lastChecked - }; - delete this.data.boards; - delete this.data.lastChecked; - } - return (base = this.data)[name = g.SITE.ID] || (base[name] = { - boards: $.dict() - }); - }; - - DataBoard.prototype.changes = []; - - DataBoard.prototype.save = function(change, cb) { - change(); - this.changes.push(change); - return $.get(this.key, { - boards: $.dict() - }, (function(_this) { - return function(items) { - var i, len, needSync, ref; - if (!_this.changes.length) { - return; - } - needSync = (items[_this.key].version || 0) > (_this.data.version || 0); - if (needSync) { - _this.initData(items[_this.key]); - ref = _this.changes; - for (i = 0, len = ref.length; i < len; i++) { - change = ref[i]; - change(); - } - } - _this.changes = []; - _this.data.version = (_this.data.version || 0) + 1; - return $.set(_this.key, _this.data, function() { - if (needSync) { - if (typeof _this.sync === "function") { - _this.sync(); - } - } - return typeof cb === "function" ? cb() : void 0; - }); - }; - })(this)); - }; - - DataBoard.prototype.forceSync = function(cb) { - return $.get(this.key, { - boards: $.dict() - }, (function(_this) { - return function(items) { - var change, i, len, ref; - if ((items[_this.key].version || 0) > (_this.data.version || 0)) { - _this.initData(items[_this.key]); - ref = _this.changes; - for (i = 0, len = ref.length; i < len; i++) { - change = ref[i]; - change(); - } - if (typeof _this.sync === "function") { - _this.sync(); - } - } - return typeof cb === "function" ? cb() : void 0; - }; - })(this)); - }; - - DataBoard.prototype["delete"] = function(arg, cb) { - var boardID, postID, siteID, threadID; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID; - siteID || (siteID = g.SITE.ID); - if (!this.data[siteID]) { - return; - } - return this.save((function(_this) { - return function() { - var ref; - if (postID) { - if (!((ref = _this.data[siteID].boards[boardID]) != null ? ref[threadID] : void 0)) { - return; - } - delete _this.data[siteID].boards[boardID][threadID][postID]; - return _this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }); - } else if (threadID) { - if (!_this.data[siteID].boards[boardID]) { - return; - } - delete _this.data[siteID].boards[boardID][threadID]; - return _this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID - }); - } else { - return delete _this.data[siteID].boards[boardID]; - } - }; - })(this), cb); - }; - - DataBoard.prototype.deleteIfEmpty = function(arg) { - var boardID, siteID, threadID; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID; - if (!this.data[siteID]) { - return; - } - if (threadID) { - if (!Object.keys(this.data[siteID].boards[boardID][threadID]).length) { - delete this.data[siteID].boards[boardID][threadID]; - return this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID - }); - } - } else if (!Object.keys(this.data[siteID].boards[boardID]).length) { - return delete this.data[siteID].boards[boardID]; - } - }; - - DataBoard.prototype.set = function(data, cb) { - return this.save((function(_this) { - return function() { - return _this.setUnsafe(data); - }; - })(this), cb); - }; - - DataBoard.prototype.setUnsafe = function(arg) { - var base, base1, base2, base3, boardID, postID, siteID, threadID, val; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, val = arg.val; - siteID || (siteID = g.SITE.ID); - (base = this.data)[siteID] || (base[siteID] = { - boards: $.dict() - }); - if (postID !== void 0) { - return ((base1 = ((base2 = this.data[siteID].boards)[boardID] || (base2[boardID] = $.dict())))[threadID] || (base1[threadID] = $.dict()))[postID] = val; - } else if (threadID !== void 0) { - return ((base3 = this.data[siteID].boards)[boardID] || (base3[boardID] = $.dict()))[threadID] = val; - } else { - return this.data[siteID].boards[boardID] = val; - } - }; - - DataBoard.prototype.extend = function(arg, cb) { - var boardID, postID, siteID, threadID, val; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, val = arg.val; - return this.save((function(_this) { - return function() { - var key, oldVal, subVal; - oldVal = _this.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - postID: postID, - defaultValue: $.dict() - }); - for (key in val) { - subVal = val[key]; - if (typeof subVal === 'undefined') { - delete oldVal[key]; - } else { - oldVal[key] = subVal; - } - } - return _this.setUnsafe({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - postID: postID, - val: oldVal - }); - }; - })(this), cb); - }; - - DataBoard.prototype.setLastChecked = function(key) { - if (key == null) { - key = 'lastChecked'; - } - return this.save((function(_this) { - return function() { - return _this.data[key] = Date.now(); - }; - })(this)); - }; - - DataBoard.prototype.get = function(arg) { - var ID, board, boardID, defaultValue, i, len, postID, ref, siteID, thread, threadID, val; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, defaultValue = arg.defaultValue; - siteID || (siteID = g.SITE.ID); - if (board = (ref = this.data[siteID]) != null ? ref.boards[boardID] : void 0) { - if (threadID == null) { - if (postID != null) { - for (thread = i = 0, len = board.length; i < len; thread = ++i) { - ID = board[thread]; - if (postID in thread) { - val = thread[postID]; - break; - } - } - } else { - val = board; - } - } else if (thread = board[threadID]) { - val = postID != null ? thread[postID] : thread; - } - } - return val || defaultValue; - }; - - DataBoard.prototype.clean = function() { - var boardID, now, ref, ref1, siteID, val; - siteID = g.SITE.ID; - ref = this.data[siteID].boards; - for (boardID in ref) { - val = ref[boardID]; - this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID - }); - } - now = Date.now(); - if (!((now - 2 * $.HOUR < (ref1 = this.data[siteID].lastChecked || 0) && ref1 <= now))) { - this.data[siteID].lastChecked = now; - for (boardID in this.data[siteID].boards) { - this.ajaxClean(boardID); - } - } - }; - - DataBoard.prototype.ajaxClean = function(boardID) { - var base, siteID, that, threadsList; - that = this; - siteID = g.SITE.ID; - threadsList = typeof (base = g.SITE.urls).threadsListJSON === "function" ? base.threadsListJSON({ - siteID: siteID, - boardID: boardID - }) : void 0; - if (!threadsList) { - return; - } - return $.cache(threadsList, function() { - var archiveList, base1, response1; - if (this.status !== 200) { - return; - } - archiveList = typeof (base1 = g.SITE.urls).archiveListJSON === "function" ? base1.archiveListJSON({ - siteID: siteID, - boardID: boardID - }) : void 0; - if (!archiveList) { - return that.ajaxCleanParse(boardID, this.response); - } - response1 = this.response; - return $.cache(archiveList, function() { - if (!(this.status === 200 || (!g.SITE.archivedBoardsKnown && this.status === 404))) { - return; - } - return that.ajaxCleanParse(boardID, response1, this.response); - }); - }); - }; - - DataBoard.prototype.ajaxCleanParse = function(boardID, response1, response2) { - var ID, board, i, j, k, len, len1, len2, page, ref, siteID, thread, threads; - siteID = g.SITE.ID; - if (!(board = this.data[siteID].boards[boardID])) { - return; - } - threads = $.dict(); - if (response1) { - for (i = 0, len = response1.length; i < len; i++) { - page = response1[i]; - ref = page.threads; - for (j = 0, len1 = ref.length; j < len1; j++) { - thread = ref[j]; - ID = thread.no; - if (ID in board) { - threads[ID] = board[ID]; - } - } - } - } - if (response2) { - for (k = 0, len2 = response2.length; k < len2; k++) { - ID = response2[k]; - if (ID in board) { - threads[ID] = board[ID]; - } - } - } - this.data[siteID].boards[boardID] = threads; - this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID - }); - return $.set(this.key, this.data); - }; - - DataBoard.prototype.onSync = function(data) { - if (!((data.version || 0) > (this.data.version || 0))) { - return; - } - this.initData(data); - return typeof this.sync === "function" ? this.sync() : void 0; - }; - - return DataBoard; - - })(); - - return DataBoard; - -}).call(this); - -Fetcher = (function() { - var Fetcher, - slice = [].slice; - - Fetcher = (function() { - function Fetcher(boardID1, threadID, postID1, root, quoter) { - var board, post, ref, that, thread; - this.boardID = boardID1; - this.threadID = threadID; - this.postID = postID1; - this.root = root; - this.quoter = quoter; - if (post = g.posts.get(this.boardID + "." + this.postID)) { - this.insert(post); - return; - } - if ((post = (ref = Index.replyData) != null ? ref[this.boardID + "." + this.postID] : void 0) && (thread = g.threads.get(this.boardID + "." + this.threadID))) { - board = g.boards[this.boardID]; - post = new Post(g.SITE.Build.postFromObject(post, this.boardID), thread, board, { - isFetchedQuote: true - }); - Main.callbackNodes('Post', [post]); - this.insert(post); - return; - } - this.root.textContent = "Loading post No." + this.postID + "..."; - if (this.threadID) { - that = this; - $.cache(g.SITE.urls.threadJSON({ - boardID: this.boardID, - threadID: this.threadID - }), function(arg) { - var isCached; - isCached = arg.isCached; - return that.fetchedPost(this, isCached); - }); - } else { - this.archivedPost(); - } - } - - Fetcher.prototype.insert = function(post) { - var boardID, clone, cssVersion, k, len, nodes, postID, quote, ref, ref1, ref2; - if (!this.root.parentNode) { - return; - } - this.quoter || (this.quoter = post); - clone = post.addClone(this.quoter.context, $.hasClass(this.root, 'dialog')); - Main.callbackNodes('Post', [clone]); - nodes = clone.nodes; - $.rmAll(nodes.root); - $.add(nodes.root, nodes.post); - ref = clone.nodes.quotelinks.concat(slice.call(clone.nodes.backlinks)); - for (k = 0, len = ref.length; k < len; k++) { - quote = ref[k]; - ref1 = Get.postDataFromLink(quote), boardID = ref1.boardID, postID = ref1.postID; - if (postID === this.quoter.ID && boardID === this.quoter.board.ID) { - $.addClass(quote, 'forwardlink'); - } - } - if (clone.nodes.flag && !(Fetcher.flagCSS || (Fetcher.flagCSS = $('link[href^="//s.4cdn.org/css/flags."]')))) { - cssVersion = ((ref2 = $('link[href^="//s.4cdn.org/css/"]')) != null ? ref2.href.match(/\d+(?=\.css$)|$/)[0] : void 0) || Date.now(); - Fetcher.flagCSS = $.el('link', { - rel: 'stylesheet', - href: "//s.4cdn.org/css/flags." + cssVersion + ".css" - }); - $.add(d.head, Fetcher.flagCSS); - } - $.rmAll(this.root); - $.add(this.root, nodes.root); - return $.event('PostsInserted', null, this.root); - }; - - Fetcher.prototype.fetchedPost = function(req, isCached) { - var api, board, k, len, post, posts, status, that, thread; - if (post = g.posts.get(this.boardID + "." + this.postID)) { - this.insert(post); - return; - } - status = req.status; - if (status !== 200) { - if (status && this.archivedPost()) { - return; - } - $.addClass(this.root, 'warning'); - this.root.textContent = status === 404 ? "Thread No." + this.threadID + " 404'd." : !status ? 'Connection Error' : "Error " + req.statusText + " (" + req.status + ")."; - return; - } - posts = req.response.posts; - g.SITE.Build.spoilerRange[this.boardID] = posts[0].custom_spoiler; - for (k = 0, len = posts.length; k < len; k++) { - post = posts[k]; - if (post.no === this.postID) { - break; - } - } - if (post.no !== this.postID) { - if (isCached) { - api = g.SITE.urls.threadJSON({ - boardID: this.boardID, - threadID: this.threadID - }); - $.cleanCache(function(url) { - return url === api; - }); - that = this; - $.cache(api, function() { - return that.fetchedPost(this, false); - }); - return; - } - if (this.archivedPost()) { - return; - } - $.addClass(this.root, 'warning'); - this.root.textContent = "Post No." + this.postID + " was not found."; - return; - } - board = g.boards[this.boardID] || new Board(this.boardID); - thread = g.threads.get(this.boardID + "." + this.threadID) || new Thread(this.threadID, board); - post = new Post(g.SITE.Build.postFromObject(post, this.boardID), thread, board, { - isFetchedQuote: true - }); - Main.callbackNodes('Post', [post]); - return this.insert(post); - }; - - Fetcher.prototype.archivedPost = function() { - var archive, encryptionOK, that, url; - if (!Conf['Resurrect Quotes']) { - return false; - } - if (!(url = Redirect.to('post', { - boardID: this.boardID, - postID: this.postID - }))) { - return false; - } - archive = Redirect.data.post[this.boardID]; - encryptionOK = /^https:\/\//.test(url) || location.protocol === 'http:'; - if (encryptionOK || Conf['Exempt Archives from Encryption']) { - that = this; - CrossOrigin.cache(url, function() { - var key, media, ref, ref1; - if (!encryptionOK && ((ref = this.response) != null ? ref.media : void 0)) { - media = this.response.media; - for (key in media) { - if (/_link$/.test(key)) { - if (!((ref1 = $.getOwn(media, key)) != null ? ref1.match(/^http:\/\//) : void 0)) { - delete media[key]; - } - } - } - } - return that.parseArchivedPost(this.response, url, archive); - }); - return true; - } - return false; - }; - - Fetcher.prototype.parseArchivedPost = function(data, url, archive) { - var board, comment, greentext, i, j, media_link, o, post, ref, tag, text, text2, thread, thumb_link; - if (post = g.posts.get(this.boardID + "." + this.postID)) { - this.insert(post); - return; - } - if (data == null) { - $.addClass(this.root, 'warning'); - this.root.textContent = "Error fetching Post No." + this.postID + " from " + archive.name + "."; - return; - } - if (data.error) { - $.addClass(this.root, 'warning'); - this.root.textContent = data.error; - return; - } - comment = (data.comment || '').split(/(\n|\[\/?(?:b|spoiler|code|moot|banned|fortune(?: color="#\w+")?|i|red|green|blue)\])/); - comment = (function() { - var k, len, results; - results = []; - for (i = k = 0, len = comment.length; k < len; i = ++k) { - text = comment[i]; - if (i % 2 === 1) { - tag = this.archiveTags[text.replace(/\ .*\]/, ']')]; - if (typeof tag === 'function') { - results.push(tag(text)); - } else { - results.push(tag); - } - } else { - greentext = text[0] === '>'; - text = text.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2'); - text = (function() { - var l, len1, ref, results1; - ref = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g); - results1 = []; - for (j = l = 0, len1 = ref.length; l < len1; j = ++l) { - text2 = ref[j]; - results1.push({innerHTML: ((j % 2) ? "" + E(text2) + "" : E(text2))}); - } - return results1; - })(); - text = {innerHTML: ((greentext) ? "" + E.cat(text) + "" : E.cat(text))}; - results.push(text); - } - } - return results; - }).call(this); - comment = {innerHTML: E.cat(comment)}; - this.threadID = +data.thread_num; - o = { - ID: this.postID, - threadID: this.threadID, - boardID: this.boardID, - isReply: this.postID !== this.threadID - }; - o.info = { - subject: data.title, - email: data.email, - name: data.name || '', - tripcode: data.trip, - capcode: (function() { - switch (data.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: data.poster_hash, - flagCode: data.poster_country, - flagCodeTroll: data.troll_country_code, - flag: data.poster_country_name || data.troll_country_name, - dateUTC: data.timestamp, - dateText: data.fourchan_date, - commentHTML: comment - }; - if (o.info.capcode) { - delete o.info.uniqueID; - } - if (data.media && !!+data.media.banned) { - o.fileDeleted = true; - } else if ((ref = data.media) != null ? ref.media_filename : void 0) { - thumb_link = data.media.thumb_link; - if ((thumb_link != null ? thumb_link[0] : void 0) === '/') { - thumb_link = url.split('/', 3).join('/') + thumb_link; - } - if (!Redirect.securityCheck(thumb_link)) { - thumb_link = ''; - } - media_link = Redirect.to('file', { - boardID: this.boardID, - filename: data.media.media_orig - }); - if (!Redirect.securityCheck(media_link)) { - media_link = ''; - } - o.file = { - name: data.media.media_filename, - url: media_link || (this.boardID === 'f' ? location.protocol + "//" + (ImageHost.flashHost()) + "/" + this.boardID + "/" + (encodeURIComponent(E(data.media.media_filename))) : location.protocol + "//" + (ImageHost.host()) + "/" + this.boardID + "/" + data.media.media_orig), - height: data.media.media_h, - width: data.media.media_w, - MD5: data.media.media_hash, - size: $.bytesToString(data.media.media_size), - thumbURL: thumb_link || (location.protocol + "//" + (ImageHost.thumbHost()) + "/" + this.boardID + "/" + data.media.preview_orig), - theight: data.media.preview_h, - twidth: data.media.preview_w, - isSpoiler: data.media.spoiler === '1' - }; - if (!/\.pdf$/.test(o.file.url)) { - o.file.dimensions = o.file.width + "x" + o.file.height; - } - if (this.boardID === 'f' && data.media.exif) { - o.file.tag = JSON.parse(data.media.exif).Tag; - } - } - o.extra = $.dict(); - board = g.boards[this.boardID] || new Board(this.boardID); - thread = g.threads.get(this.boardID + "." + this.threadID) || new Thread(this.threadID, board); - post = new Post(g.SITE.Build.post(o), thread, board, { - isFetchedQuote: true - }); - post.kill(); - if (post.file) { - post.file.thumbURL = o.file.thumbURL; - } - Main.callbackNodes('Post', [post]); - return this.insert(post); - }; - - Fetcher.prototype.archiveTags = { - '\n': {innerHTML: "
    "}, - '[b]': {innerHTML: ""}, - '[/b]': {innerHTML: ""}, - '[spoiler]': {innerHTML: ""}, - '[/spoiler]': {innerHTML: ""}, - '[code]': {innerHTML: "

    "},
    -      '[/code]': {innerHTML: "
    "}, - '[moot]': {innerHTML: "
    "}, - '[/moot]': {innerHTML: "
    "}, - '[banned]': {innerHTML: ""}, - '[/banned]': {innerHTML: ""}, - '[fortune]': function(text) { - return {innerHTML: ""}; - }, - '[/fortune]': {innerHTML: ""}, - '[i]': {innerHTML: ""}, - '[/i]': {innerHTML: ""}, - '[red]': {innerHTML: ""}, - '[/red]': {innerHTML: ""}, - '[green]': {innerHTML: ""}, - '[/green]': {innerHTML: ""}, - '[blue]': {innerHTML: ""}, - '[/blue]': {innerHTML: ""} - }; - - return Fetcher; - - })(); - - return Fetcher; - -}).call(this); - -Notice = (function() { - var Notice, - bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - - Notice = (function() { - function Notice(type, content, timeout, onclose) { - this.timeout = timeout; - this.onclose = onclose; - this.close = bind(this.close, this); - this.add = bind(this.add, this); - this.el = $.el('div', {innerHTML: "
    "}); - this.el.style.opacity = 0; - this.setType(type); - $.on(this.el.firstElementChild, 'click', this.close); - if (typeof content === 'string') { - content = $.tn(content); - } - $.add(this.el.lastElementChild, content); - $.ready(this.add); - } - - Notice.prototype.setType = function(type) { - return this.el.className = "notification " + type; - }; - - Notice.prototype.add = function() { - if (this.closed) { - return; - } - if (d.hidden) { - $.on(d, 'visibilitychange', this.add); - return; - } - $.off(d, 'visibilitychange', this.add); - $.add(Header.noticesRoot, this.el); - this.el.clientHeight; - this.el.style.opacity = 1; - if (this.timeout) { - return setTimeout(this.close, this.timeout * $.SECOND); - } - }; - - Notice.prototype.close = function() { - this.closed = true; - $.off(d, 'visibilitychange', this.add); - $.rm(this.el); - return typeof this.onclose === "function" ? this.onclose() : void 0; - }; - - return Notice; - - })(); - - return Notice; - -}).call(this); - -Post = (function() { - var Post, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Post = (function() { - Post.prototype.toString = function() { - return this.ID; - }; - - function Post(root, thread, board, flags) { - var clone, j, k, key, len, len1, ref, ref1, ref10, ref11, ref12, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, selector; - this.thread = thread; - this.board = board; - if (flags == null) { - flags = {}; - } - $.extend(this, flags); - this.ID = +root.id.match(/\d*$/)[0]; - this.postID = this.ID; - this.threadID = this.thread.ID; - this.boardID = this.board.ID; - this.siteID = g.SITE.ID; - this.fullID = this.board + "." + this.ID; - this.context = this; - this.isReply = this.ID !== this.threadID; - root.dataset.fullID = this.fullID; - this.nodes = this.parseNodes(root); - if (!this.isReply) { - this.thread.OP = this; - ref = ['isSticky', 'isClosed', 'isArchived']; - for (j = 0, len = ref.length; j < len; j++) { - key = ref[j]; - if ((selector = g.SITE.selectors.icons[key])) { - this.thread[key] = !!$(selector, this.nodes.info); - } - } - if (this.thread.isArchived) { - this.thread.isClosed = true; - this.thread.kill(); - } - } - this.info = { - subject: ((ref1 = this.nodes.subject) != null ? ref1.textContent : void 0) || void 0, - name: (ref2 = this.nodes.name) != null ? ref2.textContent : void 0, - email: this.nodes.email ? decodeURIComponent(this.nodes.email.href.replace(/^mailto:/, '')) : void 0, - tripcode: (ref3 = this.nodes.tripcode) != null ? ref3.textContent : void 0, - uniqueID: (ref4 = this.nodes.uniqueID) != null ? ref4.textContent : void 0, - capcode: (ref5 = this.nodes.capcode) != null ? ref5.textContent.replace('## ', '') : void 0, - pass: (ref6 = this.nodes.pass) != null ? ref6.title.match(/\d*$/)[0] : void 0, - flagCode: (ref7 = this.nodes.flag) != null ? (ref8 = ref7.className.match(/flag-(\w+)/)) != null ? ref8[1].toUpperCase() : void 0 : void 0, - flagCodeTroll: (ref9 = this.nodes.flag) != null ? (ref10 = ref9.className.match(/bfl-(\w+)/)) != null ? ref10[1].toUpperCase() : void 0 : void 0, - flag: (ref11 = this.nodes.flag) != null ? ref11.title : void 0, - date: this.nodes.date ? g.SITE.parseDate(this.nodes.date) : void 0 - }; - if (Conf['Anonymize']) { - this.info.nameBlock = 'Anonymous'; - } else { - this.info.nameBlock = ((this.info.name || '') + " " + (this.info.tripcode || '')).trim(); - } - if (this.info.capcode) { - this.info.nameBlock += " ## " + this.info.capcode; - } - if (this.info.uniqueID) { - this.info.nameBlock += " (ID: " + this.info.uniqueID + ")"; - } - this.parseComment(); - this.parseQuotes(); - this.parseFiles(); - this.isDead = false; - this.isHidden = false; - this.clones = []; - if (g.posts.get(this.fullID)) { - this.isRebuilt = true; - this.clones = g.posts.get(this.fullID).clones; - ref12 = this.clones; - for (k = 0, len1 = ref12.length; k < len1; k++) { - clone = ref12[k]; - clone.origin = this; - } - } - if (!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); - g.posts.push(this.fullID, this); - } - - Post.prototype.parseNodes = function(root) { - var base, info, key, nodes, post, ref, s, selector; - s = g.SITE.selectors; - post = $(s.post, root) || root; - info = $(s.infoRoot, post); - nodes = { - root: root, - bottom: this.isReply || !g.SITE.isOPContainerThread ? root : $(s.opBottom, root), - post: post, - info: info, - comment: $(s.comment, post), - quotelinks: [], - archivelinks: [], - embedlinks: [] - }; - ref = s.info; - for (key in ref) { - selector = ref[key]; - nodes[key] = $(selector, info); - } - if (typeof (base = g.SITE).parseNodes === "function") { - base.parseNodes(this, nodes); - } - nodes.uniqueIDRoot || (nodes.uniqueIDRoot = nodes.uniqueID); - if ($.engine === 'edge') { - Object.defineProperty(nodes, 'backlinks', { - configurable: true, - enumerable: true, - get: function() { - return post.getElementsByClassName('backlink'); - } - }); - } else { - nodes.backlinks = post.getElementsByClassName('backlink'); - } - return nodes; - }; - - Post.prototype.parseComment = function() { - var base, bq; - this.nodes.comment.normalize(); - this.nodes.commentClean = bq = this.nodes.comment.cloneNode(true); - if (typeof (base = g.SITE).cleanComment === "function") { - base.cleanComment(bq); - } - return this.info.comment = this.nodesToText(bq); - }; - - Post.prototype.commentDisplay = function() { - var base, bq; - bq = this.nodes.commentClean.cloneNode(true); - if (!(Conf['Remove Spoilers'] || Conf['Reveal Spoilers'])) { - this.cleanSpoilers(bq); - } - if (typeof (base = g.SITE).cleanCommentDisplay === "function") { - base.cleanCommentDisplay(bq); - } - return this.nodesToText(bq).trim().replace(/\s+$/gm, ''); - }; - - Post.prototype.commentOrig = function() { - var base, bq; - bq = this.nodes.commentClean.cloneNode(true); - if (typeof (base = g.SITE).insertTags === "function") { - base.insertTags(bq); - } - return this.nodesToText(bq); - }; - - Post.prototype.nodesToText = function(bq) { - var i, node, nodes, text; - text = ""; - nodes = $.X('.//br|.//text()', bq); - i = 0; - while (node = nodes.snapshotItem(i++)) { - text += node.data || '\n'; - } - return text; - }; - - Post.prototype.cleanSpoilers = function(bq) { - var j, len, node, spoilers; - spoilers = $$(g.SITE.selectors.spoiler, bq); - for (j = 0, len = spoilers.length; j < len; j++) { - node = spoilers[j]; - $.replace(node, $.tn('[spoiler]')); - } - }; - - Post.prototype.parseQuotes = function() { - var j, len, quotelink, ref; - this.quotes = []; - ref = $$(g.SITE.selectors.quotelink, this.nodes.comment); - for (j = 0, len = ref.length; j < len; j++) { - quotelink = ref[j]; - this.parseQuote(quotelink); - } - }; - - Post.prototype.parseQuote = function(quotelink) { - var fullID, match; - match = quotelink.href.match(g.SITE.regexp.quotelink); - if (!(match || (this.isClone && quotelink.dataset.postID))) { - return; - } - this.nodes.quotelinks.push(quotelink); - if (this.isClone) { - return; - } - fullID = match[1] + "." + match[3]; - if (indexOf.call(this.quotes, fullID) < 0) { - return this.quotes.push(fullID); - } - }; - - Post.prototype.parseFiles = function() { - var docIndex, file, fileRoot, fileRoots, index, j, len; - this.files = []; - fileRoots = this.fileRoots(); - index = 0; - for (docIndex = j = 0, len = fileRoots.length; j < len; docIndex = ++j) { - fileRoot = fileRoots[docIndex]; - if ((file = this.parseFile(fileRoot))) { - file.index = index++; - file.docIndex = docIndex; - this.files.push(file); - } - } - if (this.files.length) { - return this.file = this.files[0]; - } - }; - - Post.prototype.fileRoots = function() { - var roots; - if (g.SITE.selectors.multifile) { - roots = $$(g.SITE.selectors.multifile, this.nodes.root); - if (roots.length) { - return roots; - } - } - return [this.nodes.root]; - }; - - Post.prototype.parseFile = function(fileRoot) { - var file, key, ref, ref1, selector, size, unit; - file = {}; - ref = g.SITE.selectors.file; - for (key in ref) { - selector = ref[key]; - file[key] = $(selector, fileRoot); - } - file.thumbLink = (ref1 = file.thumb) != null ? ref1.parentNode : void 0; - if (!(file.text && file.link)) { - return; - } - if (!g.SITE.parseFile(this, file)) { - return; - } - $.extend(file, { - url: file.link.href, - isImage: $.isImage(file.link.href), - isVideo: $.isVideo(file.link.href) - }); - size = +file.size.match(/[\d.]+/)[0]; - unit = ['B', 'KB', 'MB', 'GB'].indexOf(file.size.match(/\w+$/)[0]); - while (unit-- > 0) { - size *= 1024; - } - file.sizeInBytes = size; - return file; - }; - - Post.deadMark = $.el('span', { - textContent: '\u00A0(Dead)', - className: 'qmark-dead' - }); - - Post.prototype.kill = function(file, index) { - var clone, j, k, len, len1, quotelink, ref, ref1, strong; - if (index == null) { - index = 0; - } - if (file) { - if (this.isDead || this.files[index].isDead) { - return; - } - this.files[index].isDead = true; - $.addClass(this.nodes.root, 'deleted-file'); - } else { - if (this.isDead) { - return; - } - this.isDead = true; - $.rmClass(this.nodes.root, 'deleted-file'); - $.addClass(this.nodes.root, 'deleted-post'); - } - if (!(strong = $('strong.warning', this.nodes.info))) { - strong = $.el('strong', { - className: 'warning' - }); - $.after($('input', this.nodes.info), strong); - } - strong.textContent = file ? '[File deleted]' : '[Deleted]'; - if (this.isClone) { - return; - } - ref = this.clones; - for (j = 0, len = ref.length; j < len; j++) { - clone = ref[j]; - clone.kill(file, index); - } - if (file) { - return; - } - ref1 = Get.allQuotelinksLinkingTo(this); - for (k = 0, len1 = ref1.length; k < len1; k++) { - quotelink = ref1[k]; - if (!(!$.hasClass(quotelink, 'deadlink'))) { - continue; - } - $.add(quotelink, Post.deadMark.cloneNode(true)); - $.addClass(quotelink, 'deadlink'); - } - }; - - Post.prototype.resurrect = function() { - var clone, j, k, len, len1, quotelink, ref, ref1, strong; - this.isDead = false; - $.rmClass(this.nodes.root, 'deleted-post'); - strong = $('strong.warning', this.nodes.info); - if (this.files.some(function(file) { - return file.isDead; - })) { - $.addClass(this.nodes.root, 'deleted-file'); - strong.textContent = '[File deleted]'; - } else { - $.rm(strong); - } - if (this.isClone) { - return; - } - ref = this.clones; - for (j = 0, len = ref.length; j < len; j++) { - clone = ref[j]; - clone.resurrect(); - } - ref1 = Get.allQuotelinksLinkingTo(this); - for (k = 0, len1 = ref1.length; k < len1; k++) { - quotelink = ref1[k]; - if (!($.hasClass(quotelink, 'deadlink'))) { - continue; - } - $.rm($('.qmark-dead', quotelink)); - $.rmClass(quotelink, 'deadlink'); - } - }; - - Post.prototype.collect = function() { - g.posts.rm(this.fullID); - this.thread.posts.rm(this); - return this.board.posts.rm(this); - }; - - Post.prototype.addClone = function(context, contractThumb) { - Callbacks.Post.execute(this); - return new Post.Clone(this, context, contractThumb); - }; - - Post.prototype.rmClone = function(index) { - var clone, j, len, ref; - this.clones.splice(index, 1); - ref = this.clones.slice(index); - for (j = 0, len = ref.length; j < len; j++) { - clone = ref[j]; - clone.nodes.root.dataset.clone = index++; - } - }; - - Post.prototype.setCatalogOP = function(isCatalogOP) { - this.nodes.root.classList.toggle('catalog-container', isCatalogOP); - this.nodes.root.classList.toggle('opContainer', !isCatalogOP); - this.nodes.post.classList.toggle('catalog-post', isCatalogOP); - this.nodes.post.classList.toggle('op', !isCatalogOP); - return this.nodes.post.style.left = this.nodes.post.style.right = null; - }; - - return Post; - - })(); - - return Post; - -}).call(this); - -(function() { - var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, - hasProp = {}.hasOwnProperty, - slice = [].slice; - - Post.Clone = (function(superClass) { - extend(_Class, superClass); - - _Class.prototype.isClone = true; - - function _Class() { - var that; - that = Object.create(Post.Clone.prototype); - that.construct.apply(that, arguments); - return that; - } - - _Class.prototype.construct = function(origin, context, contractThumb) { - var base, file, fileRoot, fileRoots, i, inline, inlined, j, k, key, l, len, len1, len2, len3, len4, m, node, nodes, originFile, ref, ref1, ref2, ref3, ref4, ref5, ref6, root, selector, val; - this.origin = origin; - this.context = context; - ref = ['ID', 'postID', 'threadID', 'boardID', 'siteID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']; - for (i = 0, len = ref.length; i < len; i++) { - key = ref[i]; - this[key] = this.origin[key]; - } - nodes = this.origin.nodes; - root = contractThumb ? this.cloneWithoutVideo(nodes.root) : nodes.root.cloneNode(true); - (base = Post.Clone).suffix || (base.suffix = 0); - ref1 = [root].concat(slice.call($$('[id]', root))); - for (j = 0, len1 = ref1.length; j < len1; j++) { - node = ref1[j]; - node.id += "_" + Post.Clone.suffix; - } - Post.Clone.suffix++; - ref2 = $$('.inline', root); - for (k = 0, len2 = ref2.length; k < len2; k++) { - inline = ref2[k]; - $.rm(inline); - } - ref3 = $$('.inlined', root); - for (l = 0, len3 = ref3.length; l < len3; l++) { - inlined = ref3[l]; - $.rmClass(inlined, 'inlined'); - } - this.nodes = this.parseNodes(root); - root.hidden = false; - $.rmClass(root, 'forwarded'); - $.rmClass(this.nodes.post, 'highlight'); - if (!this.isReply) { - this.setCatalogOP(false); - $.rm($('.catalog-link', this.nodes.post)); - $.rm($('.catalog-stats', this.nodes.post)); - $.rm($('.catalog-replies', this.nodes.post)); - } - this.parseQuotes(); - this.quotes = slice.call(this.origin.quotes); - this.files = []; - if (this.origin.files.length) { - fileRoots = this.fileRoots(); - } - ref4 = this.origin.files; - for (m = 0, len4 = ref4.length; m < len4; m++) { - originFile = ref4[m]; - file = {}; - for (key in originFile) { - val = originFile[key]; - file[key] = val; - } - fileRoot = fileRoots[file.docIndex]; - ref5 = g.SITE.selectors.file; - for (key in ref5) { - selector = ref5[key]; - file[key] = $(selector, fileRoot); - } - file.thumbLink = (ref6 = file.thumb) != null ? ref6.parentNode : void 0; - if (file.thumbLink) { - file.fullImage = $('.full-image', file.thumbLink); - } - file.videoControls = $('.video-controls', file.text); - if (file.videoThumb) { - file.thumb.muted = true; - } - this.files.push(file); - } - if (this.files.length) { - this.file = this.files[0]; - if (this.file.thumb && contractThumb) { - ImageExpand.contract(this); - } - } - if (this.origin.isDead) { - this.isDead = true; - } - return root.dataset.clone = this.origin.clones.push(this) - 1; - }; - - _Class.prototype.cloneWithoutVideo = function(node) { - var child, clone, i, len, ref; - if (node.tagName === 'VIDEO' && !node.dataset.md5) { - return []; - } else if (node.nodeType === Node.ELEMENT_NODE && $('video', node)) { - clone = node.cloneNode(false); - ref = node.childNodes; - for (i = 0, len = ref.length; i < len; i++) { - child = ref[i]; - $.add(clone, this.cloneWithoutVideo(child)); - } - return clone; - } else { - return node.cloneNode(true); - } - }; - - return _Class; - - })(Post); - -}).call(this); - -RandomAccessList = (function() { - var RandomAccessList; - - RandomAccessList = (function() { - function RandomAccessList(items) { - var i, item, len; - this.length = 0; - if (items) { - for (i = 0, len = items.length; i < len; i++) { - item = items[i]; - this.push(item); - } - } - } - - RandomAccessList.prototype.push = function(data) { - var ID, item, last; - ID = data.ID; - ID || (ID = data.id); - if (this[ID]) { - return; - } - last = this.last; - this[ID] = item = { - prev: last, - next: null, - data: data, - ID: ID - }; - item.prev = last; - this.last = last ? last.next = item : this.first = item; - return this.length++; - }; - - RandomAccessList.prototype.before = function(root, item) { - var prev; - if (item.next === root || item === root) { - return; - } - this.rmi(item); - prev = root.prev; - root.prev = item; - item.next = root; - item.prev = prev; - if (prev) { - return prev.next = item; - } else { - return this.first = item; - } - }; - - RandomAccessList.prototype.after = function(root, item) { - var next; - if (item.prev === root || item === root) { - return; - } - this.rmi(item); - next = root.next; - root.next = item; - item.prev = root; - item.next = next; - if (next) { - return next.prev = item; - } else { - return this.last = item; - } - }; - - RandomAccessList.prototype.prepend = function(item) { - var first; - first = this.first; - if (item === first || !this[item.ID]) { - return; - } - this.rmi(item); - item.next = first; - if (first) { - first.prev = item; - } else { - this.last = item; - } - this.first = item; - return delete item.prev; - }; - - RandomAccessList.prototype.shift = function() { - return this.rm(this.first.ID); - }; - - RandomAccessList.prototype.order = function() { - var item, order; - order = [item = this.first]; - while (item = item.next) { - order.push(item); - } - return order; - }; - - RandomAccessList.prototype.rm = function(ID) { - var item; - item = this[ID]; - if (!item) { - return; - } - delete this[ID]; - this.length--; - this.rmi(item); - delete item.next; - return delete item.prev; - }; - - RandomAccessList.prototype.rmi = function(item) { - var next, prev; - prev = item.prev, next = item.next; - if (prev) { - prev.next = next; - } else { - this.first = next; - } - if (next) { - return next.prev = prev; - } else { - return this.last = prev; - } - }; - - return RandomAccessList; - - })(); - - return RandomAccessList; - -}).call(this); - -ShimSet = (function() { - var ShimSet; - - ShimSet = (function() { - function ShimSet() { - this.elements = $.dict(); - this.size = 0; - } - - ShimSet.prototype.has = function(value) { - return value in this.elements; - }; - - ShimSet.prototype.add = function(value) { - if (this.elements[value]) { - return; - } - this.elements[value] = true; - return this.size++; - }; - - ShimSet.prototype["delete"] = function(value) { - if (!this.elements[value]) { - return; - } - delete this.elements[value]; - return this.size--; - }; - - return ShimSet; - - })(); - - if (!('Set' in window)) { - window.Set = ShimSet; - } - - return ShimSet; - -}).call(this); - -SimpleDict = (function() { - var SimpleDict, - slice = [].slice; - - SimpleDict = (function() { - function SimpleDict() { - this.keys = []; - } - - SimpleDict.prototype.push = function(key, data) { - key = "" + key; - if (!this[key]) { - this.keys.push(key); - } - return this[key] = data; - }; - - SimpleDict.prototype.rm = function(key) { - var i; - key = "" + key; - if ((i = this.keys.indexOf(key)) !== -1) { - this.keys.splice(i, 1); - return delete this[key]; - } - }; - - SimpleDict.prototype.forEach = function(fn) { - var j, key, len, ref; - ref = slice.call(this.keys); - for (j = 0, len = ref.length; j < len; j++) { - key = ref[j]; - fn(this[key]); - } - }; - - SimpleDict.prototype.get = function(key) { - if (key === 'keys') { - return void 0; - } else { - return $.getOwn(this, key); - } - }; - - return SimpleDict; - - })(); - - return SimpleDict; - -}).call(this); - -Thread = (function() { - var Thread; - - Thread = (function() { - Thread.prototype.toString = function() { - return this.ID; - }; - - function Thread(ID, board) { - this.board = board; - this.ID = +ID; - this.threadID = this.ID; - this.boardID = this.board.ID; - this.siteID = g.SITE.ID; - this.fullID = this.board + "." + this.ID; - this.posts = new SimpleDict(); - this.isDead = false; - this.isHidden = false; - this.isSticky = false; - this.isClosed = false; - this.isArchived = false; - this.postLimit = false; - this.fileLimit = false; - 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); - g.threads.push(this.fullID, this); - } - - Thread.prototype.setPage = function(pageNum) { - var icon, info, ref, reply; - ref = this.OP.nodes, info = ref.info, reply = ref.reply; - if (!(icon = $('.page-num', info))) { - icon = $.el('span', { - className: 'page-num' - }); - $.replace(reply.parentNode.previousSibling, [$.tn(' '), icon, $.tn(' ')]); - } - icon.title = "This thread is on page " + pageNum + " in the original index."; - icon.textContent = "[" + pageNum + "]"; - if (this.catalogView) { - return this.catalogView.nodes.pageCount.textContent = pageNum; - } - }; - - Thread.prototype.setCount = function(type, count, reachedLimit) { - var el; - if (!this.catalogView) { - return; - } - el = this.catalogView.nodes[type + "Count"]; - el.textContent = count; - return (reachedLimit ? $.addClass : $.rmClass)(el, 'warning'); - }; - - Thread.prototype.setStatus = function(type, status) { - var name; - name = "is" + type; - if (this[name] === status) { - return; - } - this[name] = status; - if (!this.OP) { - return; - } - this.setIcon('Sticky', this.isSticky); - this.setIcon('Closed', this.isClosed && !this.isArchived); - return this.setIcon('Archived', this.isArchived); - }; - - Thread.prototype.setIcon = function(type, status) { - var icon, root, typeLC; - typeLC = type.toLowerCase(); - icon = $("." + typeLC + "Icon", this.OP.nodes.info); - if (!!icon === status) { - return; - } - if (!status) { - $.rm(icon.previousSibling); - $.rm(icon); - if (this.catalogView) { - $.rm($("." + typeLC + "Icon", this.catalogView.nodes.icons)); - } - return; - } - icon = $.el('img', { - src: "" + g.SITE.Build.staticPath + typeLC + g.SITE.Build.gifIcon, - alt: type, - title: type, - className: typeLC + "Icon retina" - }); - if (g.BOARD.ID === 'f') { - icon.style.cssText = 'height: 18px; width: 18px;'; - } - root = type !== 'Sticky' && this.isSticky ? $('.stickyIcon', this.OP.nodes.info) : $('.page-num', this.OP.nodes.info) || this.OP.nodes.quote; - $.after(root, [$.tn(' '), icon]); - if (!this.catalogView) { - return; - } - return (type === 'Sticky' && this.isClosed ? $.prepend : $.add)(this.catalogView.nodes.icons, icon.cloneNode()); - }; - - Thread.prototype.kill = function() { - return this.isDead = true; - }; - - Thread.prototype.collect = function() { - var n; - n = 0; - this.posts.forEach(function(post) { - if (post.clones.length) { - return n++; - } else { - return post.collect(); - } - }); - if (!n) { - g.threads.rm(this.fullID); - return this.board.threads.rm(this); - } - }; - - return Thread; - - })(); - - return Thread; - -}).call(this); - -SW = {}; - -(function() { - var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - SW.tinyboard = { - isOPContainerThread: true, - mayLackJSON: true, - threadModTimeIgnoresSage: true, - 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: function() { - var j, len, m, properties, ref, root, script; - ref = $$('script:not([src])', d.head); - for (j = 0, len = ref.length; j < len; j++) { - script = ref[j]; - if ((m = script.textContent.match(/\bvar configRoot=(".*?")/))) { - properties = $.dict(); - try { - root = JSON.parse(m[1]); - if (root[0] === '/') { - properties.root = location.origin + root; - } else if (/^https?:/.test(root)) { - properties.root = root; - } - } catch (error) {} - return properties; - } - } - return false; - }, - awaitBoard: function(cb) { - var reactUI, s; - if ((reactUI = $.id('react-ui'))) { - s = this.selectors = Object.create(this.selectors); - s.boardFor = { - index: '.page-container' - }; - s.thread = 'div[id^="thread_"]'; - return Main.mounted(cb); - } else { - return cb(); - } - }, - urls: { - thread: function(arg, isArchived) { - var boardID, ref, siteID, threadID; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID; - return "" + (((ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0) || ("http://" + siteID + "/")) + boardID + "/" + (isArchived ? 'archive/' : '') + "res/" + threadID + ".html"; - }, - post: function(arg) { - var postID; - postID = arg.postID; - return "#" + postID; - }, - index: function(arg) { - var boardID, ref, siteID; - siteID = arg.siteID, boardID = arg.boardID; - return "" + (((ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0) || ("http://" + siteID + "/")) + boardID + "/"; - }, - catalog: function(arg) { - var boardID, ref, siteID; - siteID = arg.siteID, boardID = arg.boardID; - return "" + (((ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0) || ("http://" + siteID + "/")) + boardID + "/catalog.html"; - }, - threadJSON: function(arg, isArchived) { - var boardID, ref, root, siteID, threadID; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID; - root = (ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0; - if (root) { - return "" + root + boardID + "/" + (isArchived ? 'archive/' : '') + "res/" + threadID + ".json"; - } else { - return ''; - } - }, - archivedThreadJSON: function(thread) { - return SW.tinyboard.urls.threadJSON(thread, true); - }, - threadsListJSON: function(arg) { - var boardID, ref, root, siteID; - siteID = arg.siteID, boardID = arg.boardID; - root = (ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0; - if (root) { - return "" + root + boardID + "/threads.json"; - } else { - return ''; - } - }, - archiveListJSON: function(arg) { - var boardID, ref, root, siteID; - siteID = arg.siteID, boardID = arg.boardID; - root = (ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0; - if (root) { - return "" + root + boardID + "/archive/archive.json"; - } else { - return ''; - } - }, - catalogJSON: function(arg) { - var boardID, ref, root, siteID; - siteID = arg.siteID, boardID = arg.boardID; - root = (ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0; - if (root) { - return "" + root + boardID + "/catalog.json"; - } else { - return ''; - } - }, - file: function(arg, filename) { - var boardID, ref, siteID; - siteID = arg.siteID, boardID = arg.boardID; - return "" + (((ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0) || ("http://" + siteID + "/")) + boardID + "/" + filename; - }, - thumb: function(board, filename) { - return SW.tinyboard.urls.file(board, filename); - } - }, - 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: /\/([^\/]+)\/res\/(\d+)(?:\.\w+)?#(\d+)$/, - quotelinkHTML: /]*\bhref="[^"]*\/([^\/]+)\/res\/(\d+)(?:\.\w+)?#(\d+)"/g - }, - Build: { - parseJSON: function(data, board) { - var extra_file, file, i, j, len, o, ref; - o = SW.yotsuba.Build.parseJSON(data, board); - if (data.ext === 'deleted') { - delete o.file; - $.extend(o, { - files: [], - fileDeleted: true, - filesDeleted: [0] - }); - } - if (data.extra_files) { - ref = data.extra_files; - for (i = j = 0, len = ref.length; j < len; i = ++j) { - extra_file = ref[i]; - if (extra_file.ext === 'deleted') { - o.filesDeleted.push(i); - } else { - file = SW.yotsuba.Build.parseJSONFile(data, board); - o.files.push(file); - } - } - if (o.files.length) { - o.file = o.files[0]; - } - } - return o; - }, - parseComment: function(html) { - html = html.replace(//gi, '\n').replace(/<[^>]*>/g, ''); - return $.unescape(html); - } - }, - bgColoredEl: function() { - return $.el('div', { - className: 'post reply' - }); - }, - isFileURL: function(url) { - return /\/src\/[^\/]+/.test(url.pathname); - }, - preParsingFixes: function(board) { - var broken; - if ((broken = $('a > input[name="board"]', board))) { - return $.before(broken.parentNode, broken); - } - }, - parseNodes: function(post, nodes) { - var m, nextSibling, node, text, uniqueID; - if (nodes.uniqueID) { - return; - } - text = ''; - node = nodes.nameBlock.nextSibling; - while (node && node.nodeType === 3) { - text += node.textContent; - node = node.nextSibling; - } - if ((m = text.match(/(\s*ID:\s*)(\S+)/))) { - nodes.info.normalize(); - nextSibling = nodes.nameBlock.nextSibling; - nextSibling = nextSibling.splitText(m[1].length); - nextSibling.splitText(m[2].length); - nodes.uniqueID = uniqueID = $.el('span', { - className: 'poster_id' - }); - $.replace(nextSibling, uniqueID); - return $.add(uniqueID, nextSibling); - } - }, - parseDate: function(node) { - var date, ref; - date = Date.parse((ref = node.getAttribute('datetime')) != null ? ref.trim() : void 0); - if (!isNaN(date)) { - return new Date(date); - } - date = Date.parse(node.textContent.trim() + ' UTC'); - if (!isNaN(date)) { - return new Date(date); - } - return void 0; - }, - parseFile: function(post, file) { - var info, infoNode, link, nameNode, ref, ref1, text, thumb; - text = file.text, link = file.link, thumb = file.thumb; - if ($.x("ancestor::" + this.xpath.postContainer + "[1]", text) !== post.nodes.root) { - return false; - } - if (!(infoNode = indexOf.call((ref = link.nextSibling) != null ? ref.textContent : void 0, '(') >= 0 ? link.nextSibling : link.nextElementSibling)) { - return false; - } - if (!(info = infoNode.textContent.match(/\((.*,\s*)?([\d.]+ ?[KMG]?B).*\)/))) { - return false; - } - nameNode = $('.postfilename', text); - $.extend(file, { - name: nameNode ? nameNode.title || nameNode.textContent : link.pathname.match(/[^\/]*$/)[0], - size: info[2], - dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0 - }); - if (thumb) { - $.extend(file, { - thumbURL: /\/static\//.test(thumb.src) && $.isImage(link.href) ? link.href : thumb.src, - isSpoiler: /^Spoiler/i.test(info[1] || '') || link.textContent === 'Spoiler Image' - }); - } - return true; - }, - isThumbExpanded: function(file) { - return $.hasClass(file.thumb.parentNode, 'expanded') || file.thumb.parentNode.dataset.expanded === 'true'; - }, - isLinkified: function(link) { - return /\bnofollow\b/.test(link.rel); - }, - catalogPin: function(threadRoot) { - return threadRoot.dataset.sticky = 'true'; - } - }; - -}).call(this); - -(function() { - var slice = [].slice; - - SW.yotsuba = { - isOPContainerThread: false, - hasIPCount: true, - archivedBoardsKnown: true, - urls: { - thread: function(arg) { - var boardID, threadID; - boardID = arg.boardID, threadID = arg.threadID; - return location.protocol + "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/thread/" + threadID; - }, - post: function(arg) { - var postID; - postID = arg.postID; - return "#p" + postID; - }, - index: function(arg) { - var boardID; - boardID = arg.boardID; - return location.protocol + "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/"; - }, - catalog: function(arg) { - var boardID; - boardID = arg.boardID; - if (boardID === 'f') { - return void 0; - } else { - return location.protocol + "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/catalog"; - } - }, - archive: function(arg) { - var boardID; - boardID = arg.boardID; - if (BoardConfig.isArchived(boardID)) { - return location.protocol + "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/archive"; - } else { - return void 0; - } - }, - threadJSON: function(arg) { - var boardID, threadID; - boardID = arg.boardID, threadID = arg.threadID; - return location.protocol + "//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json"; - }, - threadsListJSON: function(arg) { - var boardID; - boardID = arg.boardID; - return location.protocol + "//a.4cdn.org/" + boardID + "/threads.json"; - }, - archiveListJSON: function(arg) { - var boardID; - boardID = arg.boardID; - if (BoardConfig.isArchived(boardID)) { - return location.protocol + "//a.4cdn.org/" + boardID + "/archive.json"; - } else { - return ''; - } - }, - catalogJSON: function(arg) { - var boardID; - boardID = arg.boardID; - return location.protocol + "//a.4cdn.org/" + boardID + "/catalog.json"; - }, - file: function(arg, filename) { - var boardID, hostname; - boardID = arg.boardID; - hostname = boardID === 'f' ? ImageHost.flashHost() : ImageHost.host(); - return location.protocol + "//" + hostname + "/" + boardID + "/" + filename; - }, - thumb: function(arg, filename) { - var boardID; - boardID = arg.boardID; - return location.protocol + "//" + (ImageHost.thumbHost()) + "/" + boardID + "/" + filename; - } - }, - isPrunedByAge: function(arg) { - var boardID; - boardID = arg.boardID; - return boardID === 'f'; - }, - areMD5sDeferred: function(arg) { - var boardID; - boardID = arg.boardID; - return boardID === 'f'; - }, - isOnePage: function(arg) { - var boardID; - boardID = arg.boardID; - return boardID === 'f'; - }, - noAudio: function(arg) { - var boardID; - boardID = arg.boardID; - return BoardConfig.noAudio(boardID); - }, - 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: /^https?:\/\/boards\.4chan(?:nel)?\.org\/+([^\/]+)\/+thread\/+(\d+)(?:[\/?][^#]*)?(?:#p(\d+))?$/, - quotelinkHTML: /]*\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: function() { - return $.el('div', { - className: 'reply' - }); - }, - isThisPageLegit: function() { - var ref, ref1; - return ((ref = location.hostname) === 'boards.4chan.org' || ref === 'boards.4channel.org') && d.doctype && !$('link[href*="favicon-status.ico"]', d.head) && ((ref1 = d.title) !== '4chan - Temporarily Offline' && ref1 !== '4chan - Error' && ref1 !== '504 Gateway Time-out' && ref1 !== 'MathJax Equation Source'); - }, - is404: function() { - var ref; - return ((ref = d.title) === '4chan - Temporarily Offline' || ref === '4chan - 404 Not Found') || (g.VIEW === 'thread' && $('.board') && !$('.opContainer')); - }, - isIncomplete: function() { - var ref; - return ((ref = g.VIEW) === 'index' || ref === 'thread') && !$('.board + *'); - }, - isBoardlessPage: function(url) { - var ref; - return (ref = url.hostname) === 'www.4chan.org' || ref === 'www.4channel.org'; - }, - isAuxiliaryPage: function(url) { - var ref; - return (ref = url.hostname) !== 'boards.4chan.org' && ref !== 'boards.4channel.org'; - }, - isFileURL: function(url) { - return ImageHost.test(url.hostname); - }, - initAuxiliary: function() { - var match, pathname; - switch (location.hostname) { - case 'www.4chan.org': - case 'www.4channel.org': - if (SW.yotsuba.regexp.pass.test(location.href)) { - PassMessage.init(); - } else { - $.onExists(doc, 'body', function() { - return $.addStyle(CSS.www); - }); - Captcha.replace.init(); - } - break; - case 'sys.4chan.org': - case 'sys.4channel.org': - pathname = location.pathname.split(/\/+/); - if (pathname[2] === 'imgboard.php') { - if (/\bmode=report\b/.test(location.search)) { - Report.init(); - } else if ((match = location.search.match(/\bres=(\d+)/))) { - $.ready(function() { - var ref; - if (Conf['404 Redirect'] && ((ref = $.id('errmsg')) != null ? ref.textContent : void 0) === 'Error: Specified thread does not exist.') { - return Redirect.navigate('thread', { - boardID: g.BOARD.ID, - postID: +match[1] - }); - } - }); - } - } else if (pathname[2] === 'post') { - PostSuccessful.init(); - } - } - }, - scriptData: function() { - var j, len, ref, script; - ref = $$('script:not([src])', d.head); - for (j = 0, len = ref.length; j < len; j++) { - script = ref[j]; - if (/\bcooldowns *=/.test(script.textContent)) { - return script.textContent; - } - } - return ''; - }, - parseThreadMetadata: function(thread) { - var file, m, scriptData; - scriptData = this.scriptData(); - thread.postLimit = /\bbumplimit *= *1\b/.test(scriptData); - thread.fileLimit = /\bimagelimit *= *1\b/.test(scriptData); - thread.ipCount = (m = scriptData.match(/\bunique_ips *= *(\d+)\b/)) ? +m[1] : void 0; - if (g.BOARD.ID === 'f' && thread.OP.file) { - file = thread.OP.file; - return $.ajax(this.urls.threadJSON({ - boardID: 'f', - threadID: thread.ID - }), { - timeout: $.MINUTE, - onloadend: function() { - if (this.response) { - return file.text.dataset.md5 = file.MD5 = this.response.posts[0].md5; - } - } - }); - } - }, - parseNodes: function(post, nodes) { - var icon, j, len, ref, results, type; - if (post.boardID === 'f') { - ref = ['Sticky', 'Closed']; - results = []; - for (j = 0, len = ref.length; j < len; j++) { - type = ref[j]; - if ((icon = $("img[alt=" + type + "]", nodes.info))) { - results.push($.addClass(icon, (type.toLowerCase()) + "Icon", 'retina')); - } - } - return results; - } - }, - parseDate: function(node) { - return new Date(node.dataset.utc * 1000); - }, - parseFile: function(post, file) { - var info, link, m, ref, ref1, ref2, text, thumb; - text = file.text, link = file.link, thumb = file.thumb; - if (!(info = (ref = link.nextSibling) != null ? ref.textContent.match(/\(([\d.]+ [KMG]?B).*\)/) : void 0)) { - return false; - } - $.extend(file, { - name: text.title || link.title || link.textContent, - size: info[1], - dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0, - tag: (ref2 = info[0].match(/,[^,]*, ([a-z]+)\)/i)) != null ? ref2[1] : void 0, - MD5: text.dataset.md5 - }); - if (thumb) { - $.extend(file, { - thumbURL: thumb.src, - MD5: thumb.dataset.md5, - isSpoiler: $.hasClass(thumb.parentNode, 'imgspoiler') - }); - if (file.isSpoiler) { - file.thumbURL = (m = link.href.match(/\d+(?=\.\w+$)/)) ? location.protocol + "//" + (ImageHost.thumbHost()) + "/" + post.board + "/" + m[0] + "s.jpg" : void 0; - } - } - return true; - }, - cleanComment: function(bq) { - var abbr, br, i, j, k, len, node, ref; - if ((abbr = $('.abbr', bq))) { - ref = $$('.abbr + br, .exif', bq); - for (j = 0, len = ref.length; j < len; j++) { - node = ref[j]; - $.rm(node); - } - for (i = k = 0; k < 2; i = ++k) { - if ((br = abbr.previousSibling) && br.nodeName === 'BR') { - $.rm(br); - } - } - return $.rm(abbr); - } - }, - cleanCommentDisplay: function(bq) { - var b; - if ((b = $('b', bq)) && /^Rolled /.test(b.textContent)) { - $.rm(b); - } - return $.rm($('.fortune', bq)); - }, - insertTags: function(bq) { - var j, k, len, len1, node, ref, ref1; - ref = $$('s, .removed-spoiler', bq); - for (j = 0, len = ref.length; j < len; j++) { - node = ref[j]; - $.replace(node, [$.tn('[spoiler]')].concat(slice.call(node.childNodes), [$.tn('[/spoiler]')])); - } - ref1 = $$('.prettyprint', bq); - for (k = 0, len1 = ref1.length; k < len1; k++) { - node = ref1[k]; - $.replace(node, [$.tn('[code]')].concat(slice.call(node.childNodes), [$.tn('[/code]')])); - } - }, - hasCORS: function(url) { - return url.split('/').slice(0, 3).join('/') === location.protocol + '//a.4cdn.org'; - }, - sfwBoards: function(sfw) { - return BoardConfig.sfwBoards(sfw); - }, - uidColor: function(uid) { - var i, msg; - msg = 0; - i = 0; - while (i < 8) { - msg = (msg << 5) - msg + uid.charCodeAt(i++); - } - return (msg >> 8) & 0xFFFFFF; - }, - isLinkified: function(link) { - return ImageHost.test(link.hostname); - }, - testNativeExtension: function() { - return $.global(function() { - if (window.Parser.postMenuIcon) { - return this.enabled = 'true'; - } - }); - }, - transformBoardList: function() { - var a, chr, i, items, j, len, node, nodes, ref, spacer, span; - nodes = []; - spacer = function() { - return $.el('span', { - className: 'spacer' - }); - }; - items = $.X('.//a|.//text()[not(ancestor::a)]', $(SW.yotsuba.selectors.boardList)); - i = 0; - while (node = items.snapshotItem(i++)) { - switch (node.nodeName) { - case '#text': - ref = node.nodeValue; - for (j = 0, len = ref.length; j < len; j++) { - chr = ref[j]; - span = $.el('span', { - textContent: chr - }); - if (chr === ' ') { - span.className = 'space'; - } - if (chr === ']') { - nodes.push(spacer()); - } - nodes.push(span); - if (chr === '[') { - nodes.push(spacer()); - } - } - break; - case 'A': - a = node.cloneNode(true); - nodes.push(a); - } - } - return nodes; - } - }; - -}).call(this); - -(function() { - var Build, - slice = [].slice; - - Build = { - staticPath: '//s.4cdn.org/image/', - gifIcon: window.devicePixelRatio >= 2 ? '@2x.gif' : '.gif', - spoilerRange: $.dict(), - shortFilename: function(filename) { - var ext; - ext = filename.match(/\.?[^\.]*$/)[0]; - if (filename.length - ext.length > 30) { - return (filename.match(/(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[^]){0,25}/)[0]) + "(...)" + ext; - } else { - return filename; - } - }, - spoilerThumb: function(boardID) { - var spoilerRange; - if (spoilerRange = Build.spoilerRange[boardID]) { - return Build.staticPath + "spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png"; - } else { - return Build.staticPath + "spoiler.png"; - } - }, - sameThread: function(boardID, threadID) { - return g.VIEW === 'thread' && g.BOARD.ID === boardID && g.THREADID === +threadID; - }, - threadURL: function(boardID, threadID) { - if (boardID !== g.BOARD.ID) { - return "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/thread/" + threadID; - } else if (g.VIEW !== 'thread' || +threadID !== g.THREADID) { - return "/" + boardID + "/thread/" + threadID; - } else { - return ''; - } - }, - postURL: function(boardID, threadID, postID) { - return (Build.threadURL(boardID, threadID)) + "#p" + postID; - }, - parseJSON: function(data, arg) { - var boardID, key, o, siteID; - siteID = arg.siteID, boardID = arg.boardID; - o = { - ID: data.no, - postID: data.no, - threadID: data.resto || data.no, - boardID: boardID, - siteID: siteID, - isReply: !!data.resto, - isSticky: !!data.sticky, - isClosed: !!data.closed, - isArchived: !!data.archived, - fileDeleted: !!data.filedeleted, - filesDeleted: data.filedeleted ? [0] : [] - }; - o.info = { - subject: $.unescape(data.sub), - email: $.unescape(data.email), - name: $.unescape(data.name) || '', - tripcode: data.trip, - pass: data.since4pass != null ? "" + data.since4pass : void 0, - uniqueID: data.id, - flagCode: data.country, - flagCodeTroll: data.board_flag, - flag: $.unescape(data.country_name || data.flag_name), - dateUTC: data.time, - dateText: data.now, - commentHTML: { - innerHTML: data.com || '' - } - }; - if (data.capcode) { - o.info.capcode = data.capcode.replace(/_highlight$/, '').replace(/_/g, ' ').replace(/\b\w/g, function(c) { - return c.toUpperCase(); - }); - o.capcodeHighlight = /_highlight$/.test(data.capcode); - delete o.info.uniqueID; - } - o.files = []; - if (data.ext) { - o.file = SW.yotsuba.Build.parseJSONFile(data, { - siteID: siteID, - boardID: boardID - }); - o.files.push(o.file); - } - o.extra = $.dict(); - for (key in data) { - if (key[0] === 'x') { - o.extra[key] = data[key]; - } - } - return o; - }, - parseJSONFile: function(data, arg) { - var boardID, filename, o, site, siteID; - siteID = arg.siteID, boardID = arg.boardID; - site = g.sites[siteID]; - filename = site.software === 'yotsuba' && boardID === 'f' ? "" + (encodeURIComponent(data.filename)) + data.ext : "" + data.tim + data.ext; - o = { - name: ($.unescape(data.filename)) + data.ext, - url: site.urls.file({ - siteID: siteID, - boardID: boardID - }, filename), - height: data.h, - width: data.w, - MD5: data.md5, - size: $.bytesToString(data.fsize), - thumbURL: site.urls.thumb({ - siteID: siteID, - boardID: boardID - }, data.tim + "s.jpg"), - theight: data.tn_h, - twidth: data.tn_w, - isSpoiler: !!data.spoiler, - tag: data.tag, - hasDownscale: !!data.m_img - }; - if ((data.h != null) && !/\.pdf$/.test(o.url)) { - o.dimensions = o.width + "x" + o.height; - } - return o; - }, - parseComment: function(html) { - html = html.replace(//gi, '\n').replace(/\n\n]*>/g, ''); - return $.unescape(html); - }, - parseCommentDisplay: function(html) { - var html2; - if (!(Conf['Remove Spoilers'] || Conf['Reveal Spoilers'])) { - while ((html2 = html.replace(/(?:(?!<\/?s>).)*<\/s>/g, '[spoiler]')) !== html) { - html = html2; - } - } - html = html.replace(/^Rolled [^<]*<\/b>/i, '').replace(/ " + ((!o.isReply || boardID === "f" || subject) ? "" + E(subject || "") + " " : "") + "" + ((email) ? "" : "") + "" + E(name) + "" + ((tripcode) ? " " + E(tripcode) + "" : "") + ((pass) ? " " : "") + ((capcode) ? " ## " + E(capcode) + "" : "") + ((email) ? "" : "") + ((boardID === "f" && !o.isReply || capcodeDescription) ? "" : " ") + ((capcodeDescription) ? " \""" : "") + ((uniqueID && !capcode) ? " (ID: " + E(uniqueID) + ")" : "") + ((flagCode) ? " " : "") + ((flagCodeTroll) ? " " : "") + "
    " + E(dateText) + " No." + E(ID) + "" + ((o.isSticky) ? " \"Sticky\"" : "") + ((o.isClosed && !o.isArchived) ? " \"Closed\"" : "") + ((o.isArchived) ? " \"Archived\"" : "") + ((!o.isReply && g.VIEW === "index") ? "   [Reply]" : "") + ""}; - - /* File Info */ - if (file) { - protocol = /^https?:(?=\/\/i\.4cdn\.org\/)/; - fileURL = file.url.replace(protocol, ''); - shortFilename = Build.shortFilename(file.name); - fileThumb = file.isSpoiler ? Build.spoilerThumb(boardID) : file.thumbURL.replace(protocol, ''); - } - fileBlock = {innerHTML: ((file) ? "
    " + ((boardID === "f") ? "
    File: " + E(file.name) + "-(" + E(file.size) + ", " + E(file.dimensions) + ((file.tag) ? ", " + E(file.tag) : "") + ")
    " : "
    File: " + ((file.isSpoiler) ? "Spoiler Image" : E(shortFilename)) + " (" + E(file.size) + ", " + E(file.dimensions || "PDF") + ")
    \""") + "
    " : ((o.fileDeleted) ? "
    \"File
    " : ""))}; - - /* Whole Post */ - postClass = o.isReply ? 'reply' : 'op'; - wholePost = {innerHTML: ((o.isReply) ? "
    >>
    " : "") + "
    " + ((o.isReply) ? (postInfo).innerHTML + (fileBlock).innerHTML : (fileBlock).innerHTML + (postInfo).innerHTML) + "
    " + (commentHTML).innerHTML + "
    "}; - container = $.el('div', { - className: "postContainer " + postClass + "Container", - id: "pc" + ID - }); - $.extend(container, wholePost); - ref1 = $$('.quotelink', container); - for (i = 0, len = ref1.length; i < len; i++) { - quote = ref1[i]; - href = quote.getAttribute('href'); - if (href[0] === '#') { - if (!Build.sameThread(boardID, threadID)) { - quote.href = Build.threadURL(boardID, threadID) + href; - } - } else { - if ((match = quote.href.match(SW.yotsuba.regexp.quotelink)) && (Build.sameThread(match[1], match[2]))) { - quote.href = href.match(/(#[^#]*)?$/)[0] || '#'; - } - } - } - return container; - }, - summaryText: function(status, posts, files) { - var text; - text = ''; - if (status) { - text += status + " "; - } - text += posts + " post" + (posts > 1 ? 's' : ''); - if (+files) { - text += " and " + files + " image repl" + (files > 1 ? 'ies' : 'y'); - } - return text += " " + (status === '-' ? 'shown' : 'omitted') + "."; - }, - summary: function(boardID, threadID, posts, files) { - return $.el('a', { - className: 'summary', - textContent: Build.summaryText('', posts, files), - href: "/" + boardID + "/thread/" + threadID - }); - }, - thread: function(thread, data, withReplies) { - var files, posts, ref, root, summary; - if ((root = thread.nodes.root)) { - $.rmAll(root); - } else { - thread.nodes.root = root = $.el('div', { - className: 'thread', - id: "t" + data.no - }); - } - if (Build.hat) { - $.add(root, Build.hat.cloneNode(false)); - } - $.add(root, thread.OP.nodes.root); - if (data.omitted_posts || !withReplies && data.replies) { - ref = withReplies ? [ - data.omitted_posts, data.images - data.last_replies.filter(function(data) { - return !!data.ext; - }).length - ] : [data.replies, data.images], posts = ref[0], files = ref[1]; - summary = Build.summary(thread.board.ID, data.no, posts, files); - $.add(root, summary); - } - return root; - }, - catalogThread: function(thread, data, pageCount) { - var br, container, cssText, fileCount, gifIcon, i, imgClass, len, postCount, ratio, ref, root, spoilerRange, src, staticPath, tn_h, tn_w; - staticPath = Build.staticPath, gifIcon = Build.gifIcon; - tn_w = data.tn_w, tn_h = data.tn_h; - if (data.spoiler && !Conf['Reveal Spoiler Thumbnails']) { - src = staticPath + "spoiler"; - if (spoilerRange = Build.spoilerRange[thread.board]) { - src += ("-" + thread.board) + Math.floor(1 + spoilerRange * Math.random()); - } - src += '.png'; - imgClass = 'spoiler-file'; - cssText = "--tn-w: 100; --tn-h: 100;"; - } else if (data.filedeleted) { - src = staticPath + "filedeleted-res" + gifIcon; - imgClass = 'deleted-file'; - } else if (thread.OP.file) { - src = thread.OP.file.thumbURL; - ratio = 250 / Math.max(tn_w, tn_h); - cssText = "--tn-w: " + (tn_w * ratio) + "; --tn-h: " + (tn_h * ratio) + ";"; - } else { - src = staticPath + "nofile.png"; - imgClass = 'no-file'; - } - postCount = data.replies + 1; - fileCount = data.images + !!data.ext; - container = $.el('div', {innerHTML: "
    " + E(postCount) + " / " + E(fileCount) + " / " + E(pageCount) + "" + ((thread.isSticky) ? "" : "") + ((thread.isClosed) ? "" : "") + "
    "}); - $.before(thread.OP.nodes.info, slice.call(container.childNodes)); - ref = $$('br', thread.OP.nodes.comment); - for (i = 0, len = ref.length; i < len; i++) { - br = ref[i]; - if (br.previousSibling && br.previousSibling.nodeName === 'BR') { - $.addClass(br, 'extra-linebreak'); - } - } - root = $.el('div', { - className: 'thread catalog-thread', - id: "t" + thread - }); - if (thread.OP.highlights) { - $.addClass.apply($, [root].concat(slice.call(thread.OP.highlights))); - } - if (!thread.OP.file) { - $.addClass(root, 'noFile'); - } - root.style.cssText = cssText || ''; - return root; - }, - catalogReply: function(thread, data) { - var excerpt, link; - excerpt = ''; - if (data.com) { - excerpt = Build.parseCommentDisplay(data.com).replace(/>>\d+/g, '').trim().replace(/\n+/g, ' // '); - } - if (data.ext) { - excerpt || (excerpt = "" + ($.unescape(data.filename)) + data.ext); - } - if (data.com) { - excerpt || (excerpt = $.unescape(data.com.replace(//gi, ' // '))); - } - excerpt || (excerpt = '\xA0'); - if (excerpt.length > 73) { - excerpt = excerpt.slice(0, 70) + "..."; - } - link = Build.postURL(thread.board.ID, thread.ID, data.no); - return $.el('div', { - className: 'catalog-reply' - }, {innerHTML: ": " + E(excerpt) + "..."}); - } - }; - - SW.yotsuba.Build = Build; - -}).call(this); - -Site = (function() { - var Site; - - Site = { - 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: function(cb) { - var hostname; - $.extend(Conf['siteProperties'], Site.defaultProperties); - hostname = Site.resolve(); - if (hostname && $.hasOwn(SW, Conf['siteProperties'][hostname].software)) { - this.set(hostname); - cb(); - } - return $.onExists(doc, 'body', (function(_this) { - return function() { - var base, base1, changed, changes, key, properties, software; - for (software in SW) { - if (!((changes = typeof (base = SW[software]).detect === "function" ? base.detect() : void 0))) { - continue; - } - changes.software = software; - hostname = location.hostname.replace(/^www\./, ''); - properties = ((base1 = Conf['siteProperties'])[hostname] || (base1[hostname] = $.dict())); - changed = 0; - for (key in changes) { - if (!(properties[key] !== changes[key])) { - continue; - } - properties[key] = changes[key]; - changed++; - } - if (changed) { - $.set('siteProperties', Conf['siteProperties']); - } - if (!g.SITE) { - _this.set(hostname); - cb(); - } - return; - } - }; - })(this)); - }, - resolve: function(url) { - var canonical, hostname; - if (url == null) { - url = location; - } - hostname = url.hostname; - while (hostname && !$.hasOwn(Conf['siteProperties'], hostname)) { - hostname = hostname.replace(/^[^.]*\.?/, ''); - } - if (hostname) { - if ((canonical = Conf['siteProperties'][hostname].canonical)) { - hostname = canonical; - } - } - return hostname; - }, - parseURL: function(url) { - var siteID; - siteID = Site.resolve(url); - return Main.parseURL(g.sites[siteID], url); - }, - set: function(hostname) { - var ID, properties, ref, site, software; - ref = Conf['siteProperties']; - for (ID in ref) { - properties = ref[ID]; - if (properties.canonical) { - continue; - } - software = properties.software; - if (!(software && $.hasOwn(SW, software))) { - continue; - } - g.sites[ID] = site = Object.create(SW[software]); - $.extend(site, { - ID: ID, - siteID: ID, - properties: properties, - software: software - }); - } - return g.SITE = g.sites[hostname]; - } - }; - - return Site; - -}).call(this); - -Redirect = (function() { - var Redirect, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Redirect = { - archives: [ - { "uid": 3, "name": "4plebs", "domain": "archive.4plebs.org", "http": true, "https": true, "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": true }, - { "uid": 10, "name": "warosu", "domain": "warosu.org", "http": false, "https": true, "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": true, "https": true, "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": true }, - { "uid": 24, "name": "fireden.net", "domain": "boards.fireden.net", "http": false, "https": true, "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": true, "https": true, "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": true, "https": true, "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": true }, - { "uid": 30, "name": "TheBArchive.com", "domain": "thebarchive.com", "http": true, "https": true, "software": "foolfuuka", "boards": [ "b", "bant" ], "files": [ "b", "bant" ], "reports": true }, - { "uid": 31, "name": "Archive Of Sins", "domain": "archiveofsins.com", "http": true, "https": true, "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": true }, - { "uid": 34, "name": "TokyoChronos", "domain": "www.tokyochronos.net", "http": false, "https": true, "software": "foolfuuka", "boards": [ "c", "g", "jp", "mu", "vp", "vrpg", "vt" ], "files": [], "reports": true }, - { "uid": 36, "name": "palanq.win", "domain": "archive.palanq.win", "http": false, "https": true, "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": true }, - { "uid": 37, "name": "Eientei", "domain": "eientei.xyz", "http": false, "https": true, "software": "Eientei", "boards": [ "3", "i", "sci", "xs" ], "files": [ "3", "i", "sci", "xs" ], "reports": true } - ], - init: function() { - var now, ref; - this.selectArchives(); - if (Conf['archiveAutoUpdate']) { - now = Date.now(); - if (!((now - 2 * $.DAY < (ref = Conf['lastarchivecheck']) && ref <= now))) { - return this.update(); - } - } - }, - selectArchives: function() { - var archive, archives, boardID, boards, data, files, id, j, k, key, l, len, len1, len2, name, o, record, ref, ref1, ref2, software, type, uid; - o = { - thread: $.dict(), - post: $.dict(), - file: $.dict() - }; - archives = $.dict(); - ref = Conf['archives']; - for (j = 0, len = ref.length; j < len; j++) { - data = ref[j]; - ref1 = ['boards', 'files']; - for (k = 0, len1 = ref1.length; k < len1; k++) { - key = ref1[k]; - if (!(data[key] instanceof Array)) { - data[key] = []; - } - } - uid = data.uid, name = data.name, boards = data.boards, files = data.files, software = data.software; - if (software !== 'fuuka' && software !== 'foolfuuka') { - continue; - } - archives[JSON.stringify(uid != null ? uid : name)] = data; - for (l = 0, len2 = boards.length; l < len2; l++) { - boardID = boards[l]; - if (!(boardID in o.thread)) { - o.thread[boardID] = data; - } - if (!(boardID in o.post || software !== 'foolfuuka')) { - o.post[boardID] = data; - } - if (!(boardID in o.file || indexOf.call(files, boardID) < 0)) { - o.file[boardID] = data; - } - } - } - ref2 = Conf['selectedArchives']; - for (boardID in ref2) { - record = ref2[boardID]; - for (type in record) { - id = record[type]; - if (!((archive = archives[JSON.stringify(id)]) && $.hasOwn(o, type))) { - continue; - } - boards = type === 'file' ? archive.files : archive.boards; - if (indexOf.call(boards, boardID) >= 0) { - o[type][boardID] = archive; - } - } - } - return Redirect.data = o; - }, - update: function(cb) { - var err, fail, i, j, k, len, len1, load, nloaded, ref, ref1, response, responses, url, urls; - urls = []; - responses = []; - nloaded = 0; - ref = Conf['archiveLists'].split('\n'); - for (j = 0, len = ref.length; j < len; j++) { - url = ref[j]; - if (!(url[0] !== '#')) { - continue; - } - url = url.trim(); - if (url) { - urls.push(url); - } - } - fail = function(url, action, msg) { - return new Notice('warning', "Error " + action + " archive data from\n" + url + "\n" + msg, 20); - }; - load = function(i) { - return function() { - var response; - if (this.status !== 200) { - return fail(urls[i], 'fetching', (this.status ? "Error " + this.statusText + " (" + this.status + ")" : 'Connection Error')); - } - response = this.response; - if (!(response instanceof Array)) { - response = [response]; - } - responses[i] = response; - nloaded++; - if (nloaded === urls.length) { - return Redirect.parse(responses, cb); - } - }; - }; - if (urls.length) { - for (i = k = 0, len1 = urls.length; k < len1; i = ++k) { - url = urls[i]; - if ((ref1 = url[0]) === '[' || ref1 === '{') { - try { - response = JSON.parse(url); - } catch (error) { - err = error; - fail(url, 'parsing', err.message); - continue; - } - load(i).call({ - status: 200, - response: response - }); - } else { - CrossOrigin.ajax(url, { - onloadend: load(i) - }); - } - } - } else { - Redirect.parse([], cb); - } - }, - parse: function(responses, cb) { - var archiveUIDs, archives, data, items, j, k, len, len1, ref, response, uid; - archives = []; - archiveUIDs = $.dict(); - for (j = 0, len = responses.length; j < len; j++) { - response = responses[j]; - for (k = 0, len1 = response.length; k < len1; k++) { - data = response[k]; - uid = JSON.stringify((ref = data.uid) != null ? ref : data.name); - if (uid in archiveUIDs) { - $.extend(archiveUIDs[uid], data); - } else { - archiveUIDs[uid] = $.dict.clone(data); - archives.push(data); - } - } - } - items = { - archives: archives, - lastarchivecheck: Date.now() - }; - $.set(items); - $.extend(Conf, items); - Redirect.selectArchives(); - return typeof cb === "function" ? cb() : void 0; - }, - to: function(dest, data) { - var archive; - archive = (dest === 'search' || dest === 'board' ? Redirect.data.thread : Redirect.data[dest])[data.boardID]; - if (!archive) { - return ''; - } - return Redirect[dest](archive, data); - }, - protocol: function(archive) { - var protocol; - protocol = location.protocol; - if (!$.getOwn(archive, protocol.slice(0, -1))) { - protocol = protocol === 'https:' ? 'http:' : 'https:'; - } - return protocol + "//"; - }, - thread: function(archive, arg) { - var boardID, path, postID, threadID; - boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID; - path = threadID ? boardID + "/thread/" + threadID : boardID + "/post/" + postID; - if (archive.software === 'foolfuuka') { - path += '/'; - } - if (threadID && postID) { - path += archive.software === 'foolfuuka' ? "#" + postID : "#p" + postID; - } - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; - }, - post: function(archive, arg) { - var boardID, postID, protocol, url; - boardID = arg.boardID, postID = arg.postID; - protocol = Redirect.protocol(archive); - url = "" + protocol + archive.domain + "/_/api/chan/post/?board=" + boardID + "&num=" + postID; - if (!Redirect.securityCheck(url)) { - return ''; - } - return url; - }, - file: function(archive, arg) { - var boardID, filename; - boardID = arg.boardID, filename = arg.filename; - if (!filename) { - return ''; - } - if (boardID === 'f') { - filename = encodeURIComponent($.unescape(decodeURIComponent(filename))); - } else { - if (/[sm]\.jpg$/.test(filename)) { - return ''; - } - } - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/full_image/" + filename; - }, - board: function(archive, arg) { - var boardID; - boardID = arg.boardID; - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/"; - }, - search: function(archive, arg) { - var boardID, path, type, value; - boardID = arg.boardID, type = arg.type, value = arg.value; - type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; - if (type === 'capcode') { - value = $.getOwn({ - 'Developer': 'dev', - 'Verified': 'ver' - }, value) || value.toLowerCase(); - } else if (type === 'image') { - value = value.replace(/[+\/=]/g, function(c) { - return { - '+': '-', - '/': '_', - '=': '' - }[c]; - }); - } - value = encodeURIComponent(value); - path = archive.software === 'foolfuuka' ? boardID + "/search/" + type + "/" + value + "/" : type === 'image' ? boardID + "/image/" + value : boardID + "/?task=search2&search_" + type + "=" + value; - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; - }, - report: function(boardID) { - var archive, boards, domain, https, j, len, name, ref, reports, software, urls; - urls = []; - ref = Conf['archives']; - for (j = 0, len = ref.length; j < len; j++) { - archive = ref[j]; - software = archive.software, https = archive.https, reports = archive.reports, boards = archive.boards, name = archive.name, domain = archive.domain; - if (software === 'foolfuuka' && https && reports && boards instanceof Array && indexOf.call(boards, boardID) >= 0) { - urls.push([name, "https://" + domain + "/_/api/chan/offsite_report/"]); - } - } - return urls; - }, - securityCheck: function(url) { - return /^https:\/\//.test(url) || location.protocol === 'http:' || Conf['Exempt Archives from Encryption']; - }, - navigate: function(dest, data, alternative) { - var url; - if (!Redirect.data) { - Redirect.init(); - } - url = Redirect.to(dest, data); - if (url && (Redirect.securityCheck(url) || confirm("Redirect to " + url + "?\n\nYour connection will not be encrypted."))) { - return location.replace(url); - } else if (alternative) { - return location.replace(alternative); - } - } - }; - - return Redirect; - -}).call(this); - -Anonymize = (function() { - var Anonymize; - - Anonymize = { - init: function() { - if (!Conf['Anonymize']) { - return; - } - return $.addClass(doc, 'anonymize'); - } - }; - - return Anonymize; - -}).call(this); - -Filter = (function() { - var Filter, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - Filter = { - filters: $.dict(), - init: function() { - var base, base1, boards, err, excludes, file, filter, hide, hl, i, isstring, j, key, len, len1, line, mask, noti, op, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, regexp, stub, top, type, types; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'catalog') && Conf['Filter'])) { - return; - } - if (g.VIEW === 'catalog' && !Conf['Filter in Native Catalog']) { - return; - } - if (!Conf['Filtered Backlinks']) { - $.addClass(doc, 'hide-backlinks'); - } - for (key in Config.filter) { - ref1 = Conf[key].split('\n'); - for (i = 0, len = ref1.length; i < len; i++) { - line = ref1[i]; - if (line[0] === '#') { - continue; - } - if (!(regexp = line.match(/\/(.*)\/(\w*)/))) { - continue; - } - filter = line.replace(regexp[0], ''); - boards = this.parseBoards((ref2 = filter.match(/(?:^|;)\s*boards:([^;]+)/)) != null ? ref2[1] : void 0); - excludes = this.parseBoards((ref3 = filter.match(/(?:^|;)\s*exclude:([^;]+)/)) != null ? ref3[1] : void 0); - if ((isstring = (key === 'uniqueID' || key === 'MD5'))) { - regexp = regexp[1]; - } else { - try { - regexp = RegExp(regexp[1], regexp[2]); - } catch (error) { - err = error; - new Notice('warning', [$.tn("Invalid " + key + " filter:"), $.el('br'), $.tn(line), $.el('br'), $.tn(err.message)], 60); - continue; - } - } - op = ((ref4 = filter.match(/(?:^|;)\s*op:(no|only)/)) != null ? ref4[1] : void 0) || ''; - mask = $.getOwn({ - 'no': 1, - 'only': 2 - }, op) || 0; - file = ((ref5 = filter.match(/(?:^|;)\s*file:(no|only)/)) != null ? ref5[1] : void 0) || ''; - mask = mask | ($.getOwn({ - 'no': 4, - 'only': 8 - }, file) || 0); - stub = (function() { - var ref6; - switch ((ref6 = filter.match(/(?:^|;)\s*stub:(yes|no)/)) != null ? ref6[1] : void 0) { - case 'yes': - return true; - case 'no': - return false; - default: - return Conf['Stubs']; - } - })(); - noti = /(?:^|;)\s*notify/.test(filter); - if ((hl = /(?:^|;)\s*highlight/.test(filter))) { - hl = ((ref6 = filter.match(/(?:^|;)\s*highlight:([\w-]+)/)) != null ? ref6[1] : void 0) || 'filter-highlight'; - top = ((ref7 = filter.match(/(?:^|;)\s*top:(yes|no)/)) != null ? ref7[1] : void 0) || 'yes'; - top = top === 'yes'; - } - if (key === 'general') { - if ((types = filter.match(/(?:^|;)\s*type:([^;]*)/))) { - types = types[1].split(','); - } else { - types = ['subject', 'name', 'filename', 'comment']; - } - } - hide = !(hl || noti); - filter = { - isstring: isstring, - regexp: regexp, - boards: boards, - excludes: excludes, - mask: mask, - hide: hide, - stub: stub, - hl: hl, - top: top, - noti: noti - }; - if (key === 'general') { - for (j = 0, len1 = types.length; j < len1; j++) { - type = types[j]; - ((base = this.filters)[type] || (base[type] = [])).push(filter); - } - } else { - ((base1 = this.filters)[key] || (base1[key] = [])).push(filter); - } - } - } - if (!Object.keys(this.filters).length) { - return; - } - if (g.VIEW === 'catalog') { - return Filter.catalog(); - } else { - return Callbacks.Post.push({ - name: 'Filter', - cb: this.node - }); - } - }, - parseBoards: function(boardsRaw) { - var boardID, boardID2, boards, i, j, len, len1, ref, ref1, ref2, ref3, site, siteFilter, siteID; - if (!boardsRaw) { - return false; - } - if ((boards = Filter.parseBoardsMemo[boardsRaw])) { - return boards; - } - boards = $.dict(); - siteFilter = ''; - ref = boardsRaw.split(','); - for (i = 0, len = ref.length; i < len; i++) { - boardID = ref[i]; - if (indexOf.call(boardID, ':') >= 0) { - ref1 = boardID.split(':').slice(-2), siteFilter = ref1[0], boardID = ref1[1]; - } - ref2 = g.sites; - for (siteID in ref2) { - site = ref2[siteID]; - if (siteID.slice(0, siteFilter.length) === siteFilter) { - if (boardID === 'nsfw' || boardID === 'sfw') { - ref3 = (typeof site.sfwBoards === "function" ? site.sfwBoards(boardID === 'sfw') : void 0) || []; - for (j = 0, len1 = ref3.length; j < len1; j++) { - boardID2 = ref3[j]; - boards[siteID + "/" + boardID2] = true; - } - } else { - boards[siteID + "/" + (encodeURIComponent(boardID))] = true; - } - } - } - } - Filter.parseBoardsMemo[boardsRaw] = boards; - return boards; - }, - parseBoardsMemo: $.dict(), - test: function(post, hideable) { - var board, filter, hide, hl, i, j, key, len, len1, mask, noti, ref, ref1, ref2, site, stub, top, value; - if (hideable == null) { - hideable = true; - } - if (post.filterResults) { - return post.filterResults; - } - hide = false; - stub = true; - hl = void 0; - top = false; - noti = false; - if (QuoteYou.isYou(post)) { - hideable = false; - } - mask = (post.isReply ? 2 : 1); - mask = mask | (post.file ? 4 : 8); - board = post.siteID + "/" + post.boardID; - site = post.siteID + "/*"; - for (key in Filter.filters) { - ref = Filter.values(key, post); - for (i = 0, len = ref.length; i < len; i++) { - value = ref[i]; - ref1 = Filter.filters[key]; - for (j = 0, len1 = ref1.length; j < len1; j++) { - filter = ref1[j]; - if ((filter.boards && !(filter.boards[board] || filter.boards[site])) || (filter.excludes && (filter.excludes[board] || filter.excludes[site])) || (filter.mask & mask) || (filter.isstring ? filter.regexp !== value : !filter.regexp.test(value))) { - continue; - } - if (filter.hide) { - if (hideable) { - hide = true; - stub && (stub = filter.stub); - } - } else { - if (!(hl && (ref2 = filter.hl, indexOf.call(hl, ref2) >= 0))) { - (hl || (hl = [])).push(filter.hl); - } - top || (top = filter.top); - if (filter.noti) { - noti = true; - } - } - } - } - } - if (hide) { - return { - hide: hide, - stub: stub - }; - } else { - return { - hl: hl, - top: top, - noti: noti - }; - } - }, - node: function() { - var hide, hl, noti, ref, stub, top; - if (this.isClone) { - return; - } - ref = Filter.test(this, !this.isFetchedQuote && (this.isReply || g.VIEW === 'index')), hide = ref.hide, stub = ref.stub, hl = ref.hl, top = ref.top, noti = ref.noti; - if (hide) { - if (this.isReply) { - PostHiding.hide(this, stub); - } else { - ThreadHiding.hide(this.thread, stub); - } - } else { - if (hl) { - this.highlights = hl; - $.addClass.apply($, [this.nodes.root].concat(slice.call(hl))); - } - } - if (noti && Unread.posts && (this.ID > Unread.lastReadPost) && !QuoteYou.isYou(this)) { - return Unread.openNotification(this, ' triggered a notification filter'); - } - }, - catalog: function() { - var base, url; - if (!(url = typeof (base = g.SITE.urls).catalogJSON === "function" ? base.catalogJSON(g.BOARD) : void 0)) { - return; - } - Filter.catalogData = $.dict(); - $.ajax(url, { - onloadend: Filter.catalogParse - }); - return Callbacks.CatalogThreadNative.push({ - name: 'Filter', - cb: this.catalogNode - }); - }, - catalogParse: function() { - var i, item, j, len, len1, page, ref, ref1, ref2; - if ((ref = this.status) !== 200 && ref !== 404) { - new Notice('warning', "Failed to fetch catalog JSON data. " + (this.status ? "Error " + this.statusText + " (" + this.status + ")" : 'Connection Error'), 1); - return; - } - ref1 = this.response; - for (i = 0, len = ref1.length; i < len; i++) { - page = ref1[i]; - ref2 = page.threads; - for (j = 0, len1 = ref2.length; j < len1; j++) { - item = ref2[j]; - Filter.catalogData[item.no] = item; - } - } - g.BOARD.threads.forEach(function(thread) { - if (thread.catalogViewNative) { - return Filter.catalogNode.call(thread.catalogViewNative); - } - }); - }, - catalogNode: function() { - var base, hide, hl, ref, ref1, top; - if (!(this.boardID === g.BOARD.ID && Filter.catalogData[this.ID])) { - return; - } - if ((ref = QuoteYou.db) != null ? ref.get({ - siteID: g.SITE.ID, - boardID: this.boardID, - threadID: this.ID, - postID: this.ID - }) : void 0) { - return; - } - ref1 = Filter.test(g.SITE.Build.parseJSON(Filter.catalogData[this.ID], this)), hide = ref1.hide, hl = ref1.hl, top = ref1.top; - if (hide) { - return this.nodes.root.hidden = true; - } else { - if (hl) { - this.highlights = hl; - $.addClass.apply($, [this.nodes.root].concat(slice.call(hl))); - } - if (top) { - $.prepend(this.nodes.root.parentNode, this.nodes.root); - return typeof (base = g.SITE).catalogPin === "function" ? base.catalogPin(this.nodes.root) : void 0; - } - } - }, - isHidden: function(post) { - return !!Filter.test(post).hide; - }, - valueF: { - postID: function(post) { - return ["" + post.ID]; - }, - name: function(post) { - return [post.info.name]; - }, - uniqueID: function(post) { - return [post.info.uniqueID || '']; - }, - tripcode: function(post) { - return [post.info.tripcode]; - }, - capcode: function(post) { - return [post.info.capcode]; - }, - pass: function(post) { - return [post.info.pass]; - }, - email: function(post) { - return [post.info.email]; - }, - subject: function(post) { - return [post.info.subject || (post.isReply ? void 0 : '')]; - }, - comment: function(post) { - var base, ref, ref1; - return [((base = post.info).comment != null ? base.comment : base.comment = (ref = g.sites[post.siteID]) != null ? (ref1 = ref.Build) != null ? typeof ref1.parseComment === "function" ? ref1.parseComment(post.info.commentHTML.innerHTML) : void 0 : void 0 : void 0)]; - }, - flag: function(post) { - return [post.info.flag]; - }, - filename: function(post) { - return post.files.map(function(f) { - return f.name; - }); - }, - dimensions: function(post) { - return post.files.map(function(f) { - return f.dimensions; - }); - }, - filesize: function(post) { - return post.files.map(function(f) { - return f.size; - }); - }, - MD5: function(post) { - return post.files.map(function(f) { - return f.MD5; - }); - } - }, - values: function(key, post) { - if ($.hasOwn(Filter.valueF, key)) { - return Filter.valueF[key](post).filter(function(v) { - return v != null; - }); - } else { - return [ - key.split('+').map(function(k) { - var f; - if ((f = $.getOwn(Filter.valueF, k))) { - return f(post).map(function(v) { - return v || ''; - }).join('\n'); - } else { - return ''; - } - }).join('\n') - ]; - } - }, - addFilter: function(type, re, cb) { - if (!$.hasOwn(Config.filter, type)) { - return; - } - return $.get(type, Conf[type], function(item) { - var save; - save = item[type]; - save = save ? save + "\n" + re : re; - return $.set(type, save, cb); - }); - }, - removeFilters: function(type, res, cb) { - return $.get(type, Conf[type], function(item) { - var save; - save = item[type]; - res = res.map(Filter.escape).join('|'); - save = save.replace(RegExp("(?:$\n|^)(?:" + res + ")$", 'mg'), ''); - return $.set(type, save, cb); - }); - }, - showFilters: function(type) { - var section, select; - Settings.open('Filter'); - section = $('.section-container'); - select = $('select[name=filter]', section); - select.value = type; - Settings.selectFilter.call(select); - return $.onExists(section, 'textarea', function(ta) { - var tl; - tl = ta.textLength; - ta.setSelectionRange(tl, tl); - return ta.focus(); - }); - }, - quickFilterMD5: function() { - var files, filter, links, msg, notice, origin, post; - post = Get.postFromNode(this); - files = post.files.filter(function(f) { - return f.MD5; - }); - if (!files.length) { - return; - } - filter = files.map(function(f) { - return "/" + f.MD5 + "/"; - }).join('\n'); - Filter.addFilter('MD5', filter); - origin = post.origin || post; - if (origin.isReply) { - PostHiding.hide(origin); - } else if (g.VIEW === 'index') { - ThreadHiding.hide(origin.thread); - } - if (!Conf['MD5 Quick Filter Notifications']) { - if (post.nodes.post.getBoundingClientRect().height) { - new Notice('info', 'MD5 filtered.', 2); - } - return; - } - notice = Filter.quickFilterMD5.notice; - if (notice) { - notice.filters.push(filter); - notice.posts.push(origin); - return $('span', notice.el).textContent = notice.filters.length + " MD5s filtered."; - } else { - msg = $.el('div', {innerHTML: "MD5 filtered. [show] [undo]"}); - notice = Filter.quickFilterMD5.notice = new Notice('info', msg, void 0, function() { - return delete Filter.quickFilterMD5.notice; - }); - notice.filters = [filter]; - notice.posts = [origin]; - links = $$('a', msg); - $.on(links[0], 'click', Filter.quickFilterCB.show.bind(notice)); - return $.on(links[1], 'click', Filter.quickFilterCB.undo.bind(notice)); - } - }, - quickFilterCB: { - show: function() { - Filter.showFilters('MD5'); - return this.close(); - }, - undo: function() { - var i, len, post, ref; - Filter.removeFilters('MD5', this.filters); - ref = this.posts; - for (i = 0, len = ref.length; i < len; i++) { - post = ref[i]; - if (post.isReply) { - PostHiding.show(post); - } else if (g.VIEW === 'index') { - ThreadHiding.show(post.thread); - } - } - return this.close(); - } - }, - escape: function(value) { - return value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) { - if (c === '\n') { - return '\\n'; - } else if (c === '\\') { - return '\\\\'; - } else { - return "\\" + c; - } - }); - }, - menu: { - init: function() { - var div, entry, i, len, ref, ref1, type; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Filter'])) { - return; - } - div = $.el('div', { - textContent: 'Filter' - }); - entry = { - el: div, - order: 50, - open: function(post) { - Filter.menu.post = post; - return true; - }, - subEntries: [] - }; - ref1 = [['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']]; - for (i = 0, len = ref1.length; i < len; i++) { - type = ref1[i]; - entry.subEntries.push(Filter.menu.createSubEntry(type[0], type[1])); - } - return Menu.menu.addEntry(entry); - }, - createSubEntry: function(text, type) { - var el; - el = $.el('a', { - href: 'javascript:;', - textContent: text - }); - el.dataset.type = type; - $.on(el, 'click', Filter.menu.makeFilter); - return { - el: el, - open: function(post) { - return Filter.values(type, post).length; - } - }; - }, - makeFilter: function() { - var res, type, values; - type = this.dataset.type; - values = Filter.values(type, Filter.menu.post); - res = values.map(function(value) { - var re; - re = type === 'uniqueID' || type === 'MD5' ? value : Filter.escape(value); - if (type === 'uniqueID' || type === 'MD5') { - return "/" + re + "/"; - } else { - return "/^" + re + "$/"; - } - }).join('\n'); - return Filter.addFilter(type, res, function() { - return Filter.showFilters(type); - }); - } - } - }; - - return Filter; - -}).call(this); - -PostHiding = (function() { - var PostHiding; - - PostHiding = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Reply Hiding Buttons'] && !(Conf['Menu'] && Conf['Reply Hiding Link'])) { - return; - } - if (Conf['Reply Hiding Buttons']) { - $.addClass(doc, "reply-hide"); - } - this.db = new DataBoard('hiddenPosts'); - return Callbacks.Post.push({ - name: 'Reply Hiding', - cb: this.node - }); - }, - isHidden: function(boardID, threadID, postID) { - return !!(PostHiding.db && PostHiding.db.get({ - boardID: boardID, - threadID: threadID, - postID: postID - })); - }, - node: function() { - var button, data, sa, sideArrows; - if (!this.isReply || this.isClone || this.isFetchedQuote) { - return; - } - if (data = PostHiding.db.get({ - boardID: this.board.ID, - threadID: this.thread.ID, - postID: this.ID - })) { - if (data.thisPost) { - PostHiding.hide(this, data.makeStub, data.hideRecursively); - } else { - Recursive.apply(PostHiding.hide, this, data.makeStub, true); - Recursive.add(PostHiding.hide, this, data.makeStub, true); - } - } - if (!Conf['Reply Hiding Buttons']) { - return; - } - button = PostHiding.makeButton(this, 'hide'); - if ((sa = g.SITE.selectors.sideArrows)) { - sideArrows = $(sa, this.nodes.root); - $.replace(sideArrows.firstChild, button); - return sideArrows.className = 'replacedSideArrows'; - } else { - return $.prepend(this.nodes.info, button); - } - }, - menu: { - init: function() { - var apply, div, hideStubLink, makeStub, ref, replies, thisPost; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Menu'] || !Conf['Reply Hiding Link']) { - return; - } - div = $.el('div', { - className: 'hide-reply-link', - textContent: 'Hide' - }); - apply = $.el('a', { - textContent: 'Apply', - href: 'javascript:;' - }); - $.on(apply, 'click', PostHiding.menu.hide); - thisPost = UI.checkbox('thisPost', 'This post', true); - replies = UI.checkbox('replies', 'Hide replies', Conf['Recursive Hiding']); - makeStub = UI.checkbox('makeStub', 'Make stub', Conf['Stubs']); - Menu.menu.addEntry({ - el: div, - order: 20, - open: function(post) { - if (!post.isReply || post.isClone || post.isHidden) { - return false; - } - PostHiding.menu.post = post; - return true; - }, - subEntries: [ - { - el: apply - }, { - el: thisPost - }, { - el: replies - }, { - el: makeStub - } - ] - }); - div = $.el('div', { - className: 'show-reply-link', - textContent: 'Show' - }); - apply = $.el('a', { - textContent: 'Apply', - href: 'javascript:;' - }); - $.on(apply, 'click', PostHiding.menu.show); - thisPost = UI.checkbox('thisPost', 'This post', false); - replies = UI.checkbox('replies', 'Show replies', false); - hideStubLink = $.el('a', { - textContent: 'Hide stub', - href: 'javascript:;' - }); - $.on(hideStubLink, 'click', PostHiding.menu.hideStub); - Menu.menu.addEntry({ - el: div, - order: 20, - open: function(post) { - var data; - if (!post.isReply || post.isClone || !post.isHidden) { - return false; - } - if (!(data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }))) { - return false; - } - PostHiding.menu.post = post; - thisPost.firstChild.checked = post.isHidden; - replies.firstChild.checked = (data != null ? data.hideRecursively : void 0) != null ? data.hideRecursively : Conf['Recursive Hiding']; - return true; - }, - subEntries: [ - { - el: apply - }, { - el: thisPost - }, { - el: replies - } - ] - }); - return Menu.menu.addEntry({ - el: hideStubLink, - order: 15, - open: function(post) { - var data; - if (!post.isReply || post.isClone || !post.isHidden) { - return false; - } - if (!(data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }))) { - return false; - } - return PostHiding.menu.post = post; - } - }); - }, - hide: function() { - var makeStub, parent, post, replies, thisPost; - parent = this.parentNode; - thisPost = $('input[name=thisPost]', parent).checked; - replies = $('input[name=replies]', parent).checked; - makeStub = $('input[name=makeStub]', parent).checked; - post = PostHiding.menu.post; - if (thisPost) { - PostHiding.hide(post, makeStub, replies); - } else if (replies) { - Recursive.apply(PostHiding.hide, post, makeStub, true); - Recursive.add(PostHiding.hide, post, makeStub, true); - } else { - return; - } - PostHiding.saveHiddenState(post, true, thisPost, makeStub, replies); - return $.event('CloseMenu'); - }, - show: function() { - var data, parent, post, replies, thisPost; - parent = this.parentNode; - thisPost = $('input[name=thisPost]', parent).checked; - replies = $('input[name=replies]', parent).checked; - post = PostHiding.menu.post; - if (thisPost) { - PostHiding.show(post, replies); - } else if (replies) { - Recursive.apply(PostHiding.show, post, true); - Recursive.rm(PostHiding.hide, post, true); - } else { - return; - } - if (data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - })) { - PostHiding.saveHiddenState(post, !(thisPost && replies), !thisPost, data.makeStub, !replies); - } - return $.event('CloseMenu'); - }, - hideStub: function() { - var data, post; - post = PostHiding.menu.post; - if (data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - })) { - PostHiding.show(post, data.hideRecursively); - PostHiding.hide(post, false, data.hideRecursively); - PostHiding.saveHiddenState(post, true, true, false, data.hideRecursively); - } - $.event('CloseMenu'); - } - }, - makeButton: function(post, type) { - var a, span; - span = $.el('span', { - className: "fa fa-" + (type === 'hide' ? 'minus' : 'plus') + "-square-o", - textContent: "" - }); - a = $.el('a', { - className: type + "-reply-button", - href: 'javascript:;' - }); - $.add(a, span); - $.on(a, 'click', PostHiding.toggle); - return a; - }, - saveHiddenState: function(post, isHiding, thisPost, makeStub, hideRecursively) { - var data; - data = { - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }; - if (isHiding) { - data.val = { - thisPost: thisPost !== false, - makeStub: makeStub, - hideRecursively: hideRecursively - }; - return PostHiding.db.set(data); - } else { - return PostHiding.db["delete"](data); - } - }, - toggle: function() { - var post; - post = Get.postFromNode(this); - PostHiding[(post.isHidden ? 'show' : 'hide')](post); - return PostHiding.saveHiddenState(post, post.isHidden); - }, - hide: function(post, makeStub, hideRecursively) { - var a, i, len, quotelink, ref; - if (makeStub == null) { - makeStub = Conf['Stubs']; - } - if (hideRecursively == null) { - hideRecursively = Conf['Recursive Hiding']; - } - if (post.isHidden) { - return; - } - post.isHidden = true; - if (hideRecursively) { - Recursive.apply(PostHiding.hide, post, makeStub, true); - Recursive.add(PostHiding.hide, post, makeStub, true); - } - ref = Get.allQuotelinksLinkingTo(post); - for (i = 0, len = ref.length; i < len; i++) { - quotelink = ref[i]; - $.addClass(quotelink, 'filtered'); - } - if (!makeStub) { - post.nodes.root.hidden = true; - return; - } - a = PostHiding.makeButton(post, 'show'); - $.add(a, $.tn(" " + post.info.nameBlock)); - post.nodes.stub = $.el('div', { - className: 'stub' - }); - $.add(post.nodes.stub, a); - if (Conf['Menu']) { - $.add(post.nodes.stub, Menu.makeButton(post)); - } - return $.prepend(post.nodes.root, post.nodes.stub); - }, - show: function(post, showRecursively) { - var i, len, quotelink, ref; - if (showRecursively == null) { - showRecursively = Conf['Recursive Hiding']; - } - if (post.nodes.stub) { - $.rm(post.nodes.stub); - delete post.nodes.stub; - } else { - post.nodes.root.hidden = false; - } - post.isHidden = false; - if (showRecursively) { - Recursive.apply(PostHiding.show, post, true); - Recursive.rm(PostHiding.hide, post); - } - ref = Get.allQuotelinksLinkingTo(post); - for (i = 0, len = ref.length; i < len; i++) { - quotelink = ref[i]; - $.rmClass(quotelink, 'filtered'); - } - } - }; - - return PostHiding; - -}).call(this); - -Recursive = (function() { - var Recursive, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Recursive = { - recursives: $.dict(), - init: function() { - var ref; - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - return Callbacks.Post.push({ - name: 'Recursive', - cb: this.node - }); - }, - node: function() { - var i, j, k, len, len1, obj, quote, recursive, ref, ref1; - if (this.isClone || this.isFetchedQuote) { - return; - } - ref = this.quotes; - for (j = 0, len = ref.length; j < len; j++) { - quote = ref[j]; - if (obj = Recursive.recursives[quote]) { - ref1 = obj.recursives; - for (i = k = 0, len1 = ref1.length; k < len1; i = ++k) { - recursive = ref1[i]; - recursive.apply(null, [this].concat(slice.call(obj.args[i]))); - } - } - } - }, - add: function() { - var args, base, name, obj, post, recursive; - recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; - obj = (base = Recursive.recursives)[name = post.fullID] || (base[name] = { - recursives: [], - args: [] - }); - obj.recursives.push(recursive); - return obj.args.push(args); - }, - rm: function(recursive, post) { - var i, j, len, obj, rec, ref; - if (!(obj = Recursive.recursives[post.fullID])) { - return; - } - ref = obj.recursives; - for (i = j = 0, len = ref.length; j < len; i = ++j) { - rec = ref[i]; - if (!(rec === recursive)) { - continue; - } - obj.recursives.splice(i, 1); - obj.args.splice(i, 1); - } - }, - apply: function() { - var args, fullID, post, recursive; - recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; - fullID = post.fullID; - return g.posts.forEach(function(post) { - if (indexOf.call(post.quotes, fullID) >= 0) { - return recursive.apply(null, [post].concat(slice.call(args))); - } - }); - } - }; - - return Recursive; - -}).call(this); - -ThreadHiding = (function() { - var ThreadHiding; - - ThreadHiding = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'catalog') || !Conf['Thread Hiding Buttons'] && !(Conf['Menu'] && Conf['Thread Hiding Link']) && !Conf['JSON Index']) { - return; - } - this.db = new DataBoard('hiddenThreads'); - if (g.VIEW === 'catalog') { - return this.catalogWatch(); - } - this.catalogSet(g.BOARD); - $.on(d, 'IndexRefreshInternal', this.onIndexRefresh); - if (Conf['Thread Hiding Buttons']) { - $.addClass(doc, 'thread-hide'); - } - return Callbacks.Post.push({ - name: 'Thread Hiding', - cb: this.node - }); - }, - catalogSet: function(board) { - var hiddenThreads, threadID; - if (!($.hasStorage && g.SITE.software === 'yotsuba')) { - return; - } - hiddenThreads = ThreadHiding.db.get({ - boardID: board.ID, - defaultValue: $.dict() - }); - for (threadID in hiddenThreads) { - hiddenThreads[threadID] = true; - } - return localStorage.setItem("4chan-hide-t-" + board, JSON.stringify(hiddenThreads)); - }, - catalogWatch: function() { - if (!($.hasStorage && g.SITE.software === 'yotsuba')) { - return; - } - this.hiddenThreads = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; - return Main.ready(function() { - return new MutationObserver(ThreadHiding.catalogSave).observe($.id('threads'), { - attributes: true, - subtree: true, - attributeFilter: ['style'] - }); - }); - }, - catalogSave: function() { - var hiddenThreads2, threadID; - hiddenThreads2 = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; - for (threadID in hiddenThreads2) { - if (!$.hasOwn(ThreadHiding.hiddenThreads, threadID)) { - ThreadHiding.db.set({ - boardID: g.BOARD.ID, - threadID: threadID, - val: { - makeStub: Conf['Stubs'] - } - }); - } - } - for (threadID in ThreadHiding.hiddenThreads) { - if (!$.hasOwn(hiddenThreads2, threadID)) { - ThreadHiding.db["delete"]({ - boardID: g.BOARD.ID, - threadID: threadID - }); - } - } - return ThreadHiding.hiddenThreads = hiddenThreads2; - }, - isHidden: function(boardID, threadID) { - return !!(ThreadHiding.db && ThreadHiding.db.get({ - boardID: boardID, - threadID: threadID - })); - }, - node: function() { - var data; - if (this.isReply || this.isClone || this.isFetchedQuote) { - return; - } - if (Conf['Thread Hiding Buttons']) { - $.prepend(this.nodes.root, ThreadHiding.makeButton(this.thread, 'hide')); - } - if (data = ThreadHiding.db.get({ - boardID: this.board.ID, - threadID: this.ID - })) { - return ThreadHiding.hide(this.thread, data.makeStub); - } - }, - onIndexRefresh: function() { - return g.BOARD.threads.forEach(function(thread) { - var root; - root = thread.nodes.root; - if (thread.isHidden && thread.stub && !root.contains(thread.stub)) { - return ThreadHiding.makeStub(thread, root); - } - }); - }, - menu: { - init: function() { - var apply, div, hideStubLink, makeStub; - if (g.VIEW !== 'index' || !Conf['Menu'] || !Conf['Thread Hiding Link']) { - return; - } - div = $.el('div', { - className: 'hide-thread-link', - textContent: 'Hide' - }); - apply = $.el('a', { - textContent: 'Apply', - href: 'javascript:;' - }); - $.on(apply, 'click', ThreadHiding.menu.hide); - makeStub = UI.checkbox('Stubs', 'Make stub'); - Menu.menu.addEntry({ - el: div, - order: 20, - open: function(arg) { - var isReply, thread; - thread = arg.thread, isReply = arg.isReply; - if (isReply || thread.isHidden || Conf['JSON Index'] && Conf['Index Mode'] === 'catalog') { - return false; - } - ThreadHiding.menu.thread = thread; - return true; - }, - subEntries: [ - { - el: apply - }, { - el: makeStub - } - ] - }); - div = $.el('a', { - className: 'show-thread-link', - textContent: 'Show', - href: 'javascript:;' - }); - $.on(div, 'click', ThreadHiding.menu.show); - Menu.menu.addEntry({ - el: div, - order: 20, - open: function(arg) { - var isReply, thread; - thread = arg.thread, isReply = arg.isReply; - if (isReply || !thread.isHidden || Conf['JSON Index'] && Conf['Index Mode'] === 'catalog') { - return false; - } - ThreadHiding.menu.thread = thread; - return true; - } - }); - hideStubLink = $.el('a', { - textContent: 'Hide stub', - href: 'javascript:;' - }); - $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); - return Menu.menu.addEntry({ - el: hideStubLink, - order: 15, - open: function(arg) { - var isReply, thread; - thread = arg.thread, isReply = arg.isReply; - if (isReply || !thread.isHidden || Conf['JSON Index'] && Conf['Index Mode'] === 'catalog') { - return false; - } - return ThreadHiding.menu.thread = thread; - } - }); - }, - hide: function() { - var makeStub, thread; - makeStub = $('input', this.parentNode).checked; - thread = ThreadHiding.menu.thread; - ThreadHiding.hide(thread, makeStub); - ThreadHiding.saveHiddenState(thread, makeStub); - return $.event('CloseMenu'); - }, - show: function() { - var thread; - thread = ThreadHiding.menu.thread; - ThreadHiding.show(thread); - ThreadHiding.saveHiddenState(thread); - return $.event('CloseMenu'); - }, - hideStub: function() { - var thread; - thread = ThreadHiding.menu.thread; - ThreadHiding.show(thread); - ThreadHiding.hide(thread, false); - ThreadHiding.saveHiddenState(thread, false); - $.event('CloseMenu'); - } - }, - makeButton: function(thread, type) { - var a; - a = $.el('a', { - className: type + "-thread-button", - href: 'javascript:;' - }); - $.extend(a, {innerHTML: ""}); - a.dataset.fullID = thread.fullID; - $.on(a, 'click', ThreadHiding.toggle); - return a; - }, - makeStub: function(thread, root) { - var a, numReplies, summary, threadDivider; - numReplies = $$(g.SITE.selectors.replyOriginal, root).length; - if (summary = $(g.SITE.selectors.summary, root)) { - numReplies += +summary.textContent.match(/\d+/); - } - a = ThreadHiding.makeButton(thread, 'show'); - $.add(a, $.tn(" " + thread.OP.info.nameBlock + " (" + (numReplies === 1 ? '1 reply' : numReplies + " replies") + ")")); - thread.stub = $.el('div', { - className: 'stub' - }); - if (Conf['Menu']) { - $.add(thread.stub, [a, Menu.makeButton(thread.OP)]); - } else { - $.add(thread.stub, a); - } - $.prepend(root, thread.stub); - if ((threadDivider = $(g.SITE.selectors.threadDivider, root))) { - return $.addClass(threadDivider, 'threadDivider'); - } - }, - saveHiddenState: function(thread, makeStub) { - if (thread.isHidden) { - ThreadHiding.db.set({ - boardID: thread.board.ID, - threadID: thread.ID, - val: { - makeStub: makeStub - } - }); - } else { - ThreadHiding.db["delete"]({ - boardID: thread.board.ID, - threadID: thread.ID - }); - } - return ThreadHiding.catalogSet(thread.board); - }, - toggle: function(thread) { - if (!(thread instanceof Thread)) { - thread = g.threads.get(this.dataset.fullID); - } - if (thread.isHidden) { - ThreadHiding.show(thread); - } else { - ThreadHiding.hide(thread); - } - return ThreadHiding.saveHiddenState(thread); - }, - hide: function(thread, makeStub) { - var threadRoot; - if (makeStub == null) { - makeStub = Conf['Stubs']; - } - if (thread.isHidden) { - return; - } - threadRoot = thread.nodes.root; - thread.isHidden = true; - Index.updateHideLabel(); - if (thread.catalogView && !Index.showHiddenThreads) { - $.rm(thread.catalogView.nodes.root); - $.event('PostsRemoved', null, Index.root); - } - if (!makeStub) { - return threadRoot.hidden = true; - } - return ThreadHiding.makeStub(thread, threadRoot); - }, - show: function(thread) { - var threadRoot; - if (thread.stub) { - $.rm(thread.stub); - delete thread.stub; - } - threadRoot = thread.nodes.root; - threadRoot.hidden = thread.isHidden = false; - Index.updateHideLabel(); - if (thread.catalogView && Index.showHiddenThreads) { - $.rm(thread.catalogView.nodes.root); - return $.event('PostsRemoved', null, Index.root); - } - } - }; - - return ThreadHiding; - -}).call(this); - -BoardConfig = (function() { - var BoardConfig; - - BoardConfig = { - cbs: [], - init: function() { - var boards, now, ref; - if (g.SITE.software !== 'yotsuba') { - return; - } - now = Date.now(); - if (!((now - 2 * $.HOUR < (ref = Conf['boardConfig'].lastChecked || 0) && ref <= now))) { - return $.ajax(location.protocol + "//a.4cdn.org/boards.json", { - onloadend: this.load - }); - } else { - boards = Conf['boardConfig'].boards; - return this.set(boards); - } - }, - load: function() { - var board, boards, err, i, len, ref; - if (this.status === 200 && this.response && this.response.boards) { - boards = $.dict(); - ref = this.response.boards; - for (i = 0, len = ref.length; i < len; i++) { - board = ref[i]; - boards[board.board] = board; - } - $.set('boardConfig', { - boards: boards, - lastChecked: Date.now() - }); - } else { - boards = Conf['boardConfig'].boards; - err = (function() { - switch (this.status) { - case 0: - return 'Connection Error'; - case 200: - return 'Invalid Data'; - default: - return "Error " + this.statusText + " (" + this.status + ")"; - } - }).call(this); - new Notice('warning', "Failed to load board configuration. " + err, 20); - } - return BoardConfig.set(boards); - }, - set: function(boards1) { - var ID, board, cb, i, len, ref, ref1; - this.boards = boards1; - ref = g.boards; - for (ID in ref) { - board = ref[ID]; - board.config = this.boards[ID] || {}; - } - ref1 = this.cbs; - for (i = 0, len = ref1.length; i < len; i++) { - cb = ref1[i]; - $.queueTask(cb); - } - }, - ready: function(cb) { - if (this.boards) { - return cb(); - } else { - return this.cbs.push(cb); - } - }, - sfwBoards: function(sfw) { - var board, data, ref, results; - ref = this.boards || Conf['boardConfig'].boards; - results = []; - for (board in ref) { - data = ref[board]; - if (!!data.ws_board === sfw) { - results.push(board); - } - } - return results; - }, - isSFW: function(board) { - var ref; - return !!((ref = (this.boards || Conf['boardConfig'].boards)[board]) != null ? ref.ws_board : void 0); - }, - domain: function(board) { - return "boards." + (BoardConfig.isSFW(board) ? '4channel' : '4chan') + ".org"; - }, - isArchived: function(board) { - var data; - data = (this.boards || Conf['boardConfig'].boards)[board]; - return !data || data.is_archived; - }, - noAudio: function(boardID) { - var boards; - if (g.SITE.software !== 'yotsuba') { - return false; - } - boards = this.boards || Conf['boardConfig'].boards; - return boards && boards[boardID] && !boards[boardID].webm_audio; - }, - title: function(boardID) { - var ref, ref1; - return ((ref = this.boards || Conf['boardConfig'].boards) != null ? (ref1 = ref[boardID]) != null ? ref1.title : void 0 : void 0) || ''; - } - }; - - return BoardConfig; - -}).call(this); - -Get = (function() { - var Get, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Get = { - url: function() { - var IDs, args, f, site, type; - type = arguments[0], IDs = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; - if ((site = g.sites[IDs.siteID]) && (f = $.getOwn(site.urls, type))) { - return f.apply(null, [IDs].concat(slice.call(args))); - } else { - return void 0; - } - }, - threadExcerpt: function(thread) { - var OP, excerpt, ref, ref1; - OP = thread.OP; - excerpt = ("/" + (decodeURIComponent(thread.board.ID)) + "/ - ") + (((ref = OP.info.subject) != null ? ref.trim() : void 0) || OP.commentDisplay().replace(/\n+/g, ' // ') || ((ref1 = OP.file) != null ? ref1.name : void 0) || ("No." + OP)); - if (excerpt.length > 73) { - return excerpt.slice(0, 70) + "..."; - } - return excerpt; - }, - threadFromRoot: function(root) { - var board; - if (root == null) { - return null; - } - board = root.dataset.board; - return g.threads.get((board ? encodeURIComponent(board) : g.BOARD.ID) + "." + (root.id.match(/\d*$/)[0])); - }, - threadFromNode: function(node) { - return Get.threadFromRoot($.x("ancestor-or-self::" + g.SITE.xpath.thread, node)); - }, - postFromRoot: function(root) { - var index, post; - if (root == null) { - return null; - } - post = g.posts.get(root.dataset.fullID); - index = root.dataset.clone; - if (index) { - return post.clones[+index]; - } else { - return post; - } - }, - postFromNode: function(root) { - return Get.postFromRoot($.x("ancestor-or-self::" + g.SITE.xpath.postContainer + "[1]", root)); - }, - postDataFromLink: function(link) { - var boardID, match, postID, ref, ref1, threadID; - if (link.dataset.postID) { - ref = link.dataset, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - threadID || (threadID = 0); - } else { - match = link.href.match(g.SITE.regexp.quotelink); - ref1 = match.slice(1), boardID = ref1[0], threadID = ref1[1], postID = ref1[2]; - postID || (postID = threadID); - } - return { - boardID: boardID, - threadID: +threadID, - postID: +postID - }; - }, - allQuotelinksLinkingTo: function(post) { - var fullID, handleQuotes, i, len, posts, qPost, quote, quotelinks, ref; - quotelinks = []; - posts = g.posts; - fullID = post.fullID; - handleQuotes = function(qPost, type) { - var clone, i, len, ref; - quotelinks.push.apply(quotelinks, qPost.nodes[type]); - ref = qPost.clones; - for (i = 0, len = ref.length; i < len; i++) { - clone = ref[i]; - quotelinks.push.apply(quotelinks, clone.nodes[type]); - } - }; - posts.forEach(function(qPost) { - if (indexOf.call(qPost.quotes, fullID) >= 0) { - return handleQuotes(qPost, 'quotelinks'); - } - }); - if (Conf['Quote Backlinks']) { - ref = post.quotes; - for (i = 0, len = ref.length; i < len; i++) { - quote = ref[i]; - if (qPost = posts.get(quote)) { - handleQuotes(qPost, 'backlinks'); - } - } - } - return quotelinks.filter(function(quotelink) { - var boardID, postID, ref1; - ref1 = Get.postDataFromLink(quotelink), boardID = ref1.boardID, postID = ref1.postID; - return boardID === post.board.ID && postID === post.ID; - }); - } - }; - - return Get; - -}).call(this); - -Header = (function() { - var Header, - slice = [].slice; - - Header = { - init: function() { - var barFixedToggler, barPositionToggler, box, cs, customNavToggler, editCustomNav, footerToggler, headerToggler, linkJustifyToggler, menuButton, scrollHeaderToggler, shortcutToggler; - $.onExists(doc, 'body', (function(_this) { - return function() { - if (!Main.isThisPageLegit()) { - return; - } - $.add(_this.bar, [_this.noticesRoot, _this.toggle]); - $.prepend(d.body, _this.bar); - $.add(d.body, Header.hover); - return _this.setBarPosition(Conf['Bottom Header']); - }; - })(this)); - this.menu = new UI.Menu('header'); - menuButton = $.el('span', { - className: 'menu-button' - }); - $.extend(menuButton, {innerHTML: ""}); - box = UI.checkbox; - barFixedToggler = box('Fixed Header', 'Fixed Header'); - headerToggler = box('Header auto-hide', 'Auto-hide header'); - scrollHeaderToggler = box('Header auto-hide on scroll', 'Auto-hide header on scroll'); - barPositionToggler = box('Bottom Header', 'Bottom header'); - linkJustifyToggler = box('Centered links', 'Centered links'); - customNavToggler = box('Custom Board Navigation', 'Custom board navigation'); - footerToggler = box('Bottom Board List', 'Hide bottom board list'); - shortcutToggler = box('Shortcut Icons', 'Shortcut Icons'); - editCustomNav = $.el('a', { - textContent: 'Edit custom board navigation', - href: 'javascript:;' - }); - this.barFixedToggler = barFixedToggler.firstElementChild; - this.scrollHeaderToggler = scrollHeaderToggler.firstElementChild; - this.barPositionToggler = barPositionToggler.firstElementChild; - this.linkJustifyToggler = linkJustifyToggler.firstElementChild; - this.headerToggler = headerToggler.firstElementChild; - this.footerToggler = footerToggler.firstElementChild; - this.shortcutToggler = shortcutToggler.firstElementChild; - this.customNavToggler = customNavToggler.firstElementChild; - $.on(menuButton, 'click', this.menuToggle); - $.on(this.headerToggler, 'change', this.toggleBarVisibility); - $.on(this.barFixedToggler, 'change', this.toggleBarFixed); - $.on(this.barPositionToggler, 'change', this.toggleBarPosition); - $.on(this.scrollHeaderToggler, 'change', this.toggleHideBarOnScroll); - $.on(this.linkJustifyToggler, 'change', this.toggleLinkJustify); - $.on(this.footerToggler, 'change', this.toggleFooterVisibility); - $.on(this.shortcutToggler, 'change', this.toggleShortcutIcons); - $.on(this.customNavToggler, 'change', this.toggleCustomNav); - $.on(editCustomNav, 'click', this.editCustomNav); - this.setBarFixed(Conf['Fixed Header']); - this.setHideBarOnScroll(Conf['Header auto-hide on scroll']); - this.setBarVisibility(Conf['Header auto-hide']); - this.setLinkJustify(Conf['Centered links']); - this.setShortcutIcons(Conf['Shortcut Icons']); - this.setFooterVisibility(Conf['Bottom Board List']); - $.sync('Fixed Header', this.setBarFixed); - $.sync('Header auto-hide on scroll', this.setHideBarOnScroll); - $.sync('Bottom Header', this.setBarPosition); - $.sync('Shortcut Icons', this.setShortcutIcons); - $.sync('Header auto-hide', this.setBarVisibility); - $.sync('Centered links', this.setLinkJustify); - $.sync('Bottom Board List', this.setFooterVisibility); - this.addShortcut('menu', menuButton, 900); - this.menu.addEntry({ - el: $.el('span', { - textContent: 'Header' - }), - order: 107, - subEntries: [ - { - el: barFixedToggler - }, { - el: headerToggler - }, { - el: scrollHeaderToggler - }, { - el: barPositionToggler - }, { - el: linkJustifyToggler - }, { - el: footerToggler - }, { - el: shortcutToggler - }, { - el: customNavToggler - }, { - el: editCustomNav - } - ] - }); - $.on(window, 'load popstate', Header.hashScroll); - $.on(d, 'CreateNotification', this.createNotification); - this.setBoardList(); - $.onExists(doc, g.SITE.selectors.boardList + " + *", Header.generateFullBoardList); - Main.ready(function() { - var a, absbot, footer, i, len, ref; - if (g.SITE.software === 'yotsuba' && !(footer = $.id('boardNavDesktopFoot'))) { - if (!(absbot = $.id('absbot'))) { - return; - } - footer = $.id('boardNavDesktop').cloneNode(true); - footer.id = 'boardNavDesktopFoot'; - $('#navtopright', footer).id = 'navbotright'; - $('#settingsWindowLink', footer).id = 'settingsWindowLinkBot'; - $.before(absbot, footer); - $.global(function() { - return window.cloneTopNav = function() {}; - }); - } - if ((Header.bottomBoardList = $(g.SITE.selectors.boardListBottom))) { - ref = $$('a', Header.bottomBoardList); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - if (a.hostname === location.hostname && a.pathname.split('/')[1] === g.BOARD.ID) { - a.className = 'current'; - } - } - return CatalogLinks.setLinks(Header.bottomBoardList); - } - }); - if (g.SITE.software === 'yotsuba' && (g.VIEW === 'catalog' || !Conf['Disable Native Extension'])) { - cs = $.el('a', { - href: 'javascript:;' - }); - if (g.VIEW === 'catalog') { - cs.title = cs.textContent = 'Catalog Settings'; - cs.className = 'fa fa-book'; - } else { - cs.title = cs.textContent = '4chan Settings'; - cs.className = 'native-settings'; - } - $.on(cs, 'click', function() { - return $.id('settingsWindowLink').click(); - }); - this.addShortcut('native', cs, 810); - } - return this.enableDesktopNotifications(); - }, - bar: $.el('div', { - id: 'header-bar' - }), - noticesRoot: $.el('div', { - id: 'notifications' - }), - shortcuts: $.el('span', { - id: 'shortcuts' - }), - hover: $.el('div', { - id: 'hoverUI' - }), - toggle: $.el('div', { - id: 'scroll-marker' - }), - setBoardList: function() { - var boardList, btn; - Header.boardList = boardList = $.el('span', { - id: 'board-list' - }); - $.extend(boardList, {innerHTML: ""}); - btn = $('.hide-board-list-button', boardList); - $.on(btn, 'click', Header.toggleBoardList); - $.prepend(Header.bar, [Header.boardList, Header.shortcuts]); - Header.setCustomNav(Conf['Custom Board Navigation']); - Header.generateBoardList(Conf['boardnav']); - $.sync('Custom Board Navigation', Header.setCustomNav); - return $.sync('boardnav', Header.generateBoardList); - }, - generateFullBoardList: function() { - var a, fullBoardList, i, len, nodes, ref; - if (g.SITE.transformBoardList) { - nodes = g.SITE.transformBoardList(); - } else { - nodes = slice.call($(g.SITE.selectors.boardList).cloneNode(true).childNodes); - } - fullBoardList = $('.boardList', Header.boardList); - $.add(fullBoardList, nodes); - ref = $$('a', fullBoardList); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - if (a.hostname === location.hostname && a.pathname.split('/')[1] === g.BOARD.ID) { - a.className = 'current'; - } - } - return CatalogLinks.setLinks(fullBoardList); - }, - generateBoardList: function(boardnav) { - var list, nodes, re, t; - list = $('#custom-board-list', Header.boardList); - $.rmAll(list); - if (!boardnav) { - return; - } - boardnav = boardnav.replace(/(\r\n|\n|\r)/g, ' '); - re = /[\w@]+(-(all|title|replace|full|index|catalog|archive|expired|nt|(mode|sort|text):"[^"]+"(,"[^"]+")?))*|[^\w@]+/g; - nodes = (function() { - var i, len, ref, results; - ref = boardnav.match(re); - results = []; - for (i = 0, len = ref.length; i < len; i++) { - t = ref[i]; - results.push(Header.mapCustomNavigation(t)); - } - return results; - })(); - $.add(list, nodes); - return CatalogLinks.setLinks(list); - }, - mapCustomNavigation: function(t) { - var a, boardID, href, indexOptions, m, ref, ref1, text, url, urlIC; - if (/^[^\w@]/.test(t)) { - return $.tn(t); - } - text = url = null; - t = t.replace(/-text:"([^"]+)"(?:,"([^"]+)")?/g, function(m0, m1, m2) { - text = m1; - url = m2; - return ''; - }); - indexOptions = []; - t = t.replace(/-(?:mode|sort):"([^"]+)"/g, function(m0, m1) { - indexOptions.push(m1.toLowerCase().replace(/\ /g, '-')); - return ''; - }); - indexOptions = indexOptions.join('/'); - if (/^toggle-all/.test(t)) { - a = $.el('a', { - className: 'show-board-list-button', - textContent: text || '+', - href: 'javascript:;' - }); - $.on(a, 'click', Header.toggleBoardList); - return a; - } - if (/^external/.test(t)) { - a = $.el('a', { - href: url || 'javascript:;', - textContent: text || '+', - className: 'external' - }); - if (/-nt/.test(t)) { - a.target = '_blank'; - a.rel = 'noopener'; - } - return a; - } - boardID = t.split('-')[0]; - if (boardID === 'current') { - if ((ref = location.hostname) === 'boards.4chan.org' || ref === 'boards.4channel.org') { - boardID = g.BOARD.ID; - } else { - a = $.el('a', { - href: "/" + g.BOARD.ID + "/", - textContent: text || decodeURIComponent(g.BOARD.ID), - className: 'current' - }); - if (/-nt/.test(t)) { - a.target = '_blank'; - a.rel = 'noopener'; - } - if (/-index/.test(t)) { - a.dataset.only = 'index'; - } else if (/-catalog/.test(t)) { - a.dataset.only = 'catalog'; - a.href += 'catalog.html'; - } else if (/-(archive|expired)/.test(t)) { - a = a.firstChild; - } - return a; - } - } - a = (function() { - var ref1, urlV; - if (boardID === '@') { - return $.el('a', { - href: 'https://twitter.com/4chan', - title: '4chan Twitter', - textContent: '@' - }); - } - a = $.el('a', { - href: "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/", - textContent: boardID, - title: BoardConfig.title(boardID) - }); - if (((ref1 = g.VIEW) === 'catalog' || ref1 === 'archive') && (urlV = Get.url(g.VIEW, { - siteID: '4chan.org', - boardID: boardID - }))) { - a.href = urlV; - } - if (a.hostname === location.hostname && boardID === g.BOARD.ID) { - a.className = 'current'; - } - return a; - })(); - a.textContent = /-title/.test(t) || /-replace/.test(t) && a.hostname === location.hostname && boardID === g.BOARD.ID ? a.title || a.textContent : /-full/.test(t) ? ("/" + boardID + "/") + (a.title ? " - " + a.title : '') : text || boardID; - if (m = t.match(/-(index|catalog)/)) { - urlIC = CatalogLinks[m[1]]({ - siteID: '4chan.org', - boardID: boardID - }); - if (urlIC) { - a.dataset.only = m[1]; - a.href = urlIC; - if (m[1] === 'catalog') { - $.addClass(a, 'catalog'); - } - } else { - return a.firstChild; - } - } - if (Conf['JSON Index'] && indexOptions) { - a.dataset.indexOptions = indexOptions; - if (((ref1 = a.hostname) === 'boards.4chan.org' || ref1 === 'boards.4channel.org') && a.pathname.split('/')[2] === '') { - a.href += (a.hash ? '/' : '#') + indexOptions; - } - } - if (/-archive/.test(t)) { - if (href = Redirect.to('board', { - boardID: boardID - })) { - a.href = href; - } else { - return a.firstChild; - } - } - if (/-expired/.test(t)) { - if (BoardConfig.isArchived(boardID)) { - a.href = "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/archive"; - } else { - return a.firstChild; - } - } - if (/-nt/.test(t)) { - a.target = '_blank'; - a.rel = 'noopener'; - } - if (boardID === '@') { - $.addClass(a, 'navSmall'); - } - return a; - }, - toggleBoardList: function() { - var bar, custom, full, showBoardList; - bar = Header.bar; - custom = $('#custom-board-list', bar); - full = $('#full-board-list', bar); - showBoardList = !full.hidden; - custom.hidden = !showBoardList; - return full.hidden = showBoardList; - }, - setLinkJustify: function(centered) { - Header.linkJustifyToggler.checked = centered; - if (centered) { - return $.addClass(doc, 'centered-links'); - } else { - return $.rmClass(doc, 'centered-links'); - } - }, - toggleLinkJustify: function() { - var centered; - $.event('CloseMenu'); - centered = this.nodeName === 'INPUT' ? this.checked : void 0; - Header.setLinkJustify(centered); - return $.set('Centered links', centered); - }, - setBarFixed: function(fixed) { - Header.barFixedToggler.checked = fixed; - if (fixed) { - $.addClass(doc, 'fixed'); - return $.addClass(Header.bar, 'dialog'); - } else { - $.rmClass(doc, 'fixed'); - return $.rmClass(Header.bar, 'dialog'); - } - }, - toggleBarFixed: function() { - $.event('CloseMenu'); - Header.setBarFixed(this.checked); - Conf['Fixed Header'] = this.checked; - return $.set('Fixed Header', this.checked); - }, - setShortcutIcons: function(show) { - Header.shortcutToggler.checked = show; - if (show) { - return $.addClass(doc, 'shortcut-icons'); - } else { - return $.rmClass(doc, 'shortcut-icons'); - } - }, - toggleShortcutIcons: function() { - $.event('CloseMenu'); - Header.setShortcutIcons(this.checked); - Conf['Shortcut Icons'] = this.checked; - return $.set('Shortcut Icons', this.checked); - }, - setBarVisibility: function(hide) { - Header.headerToggler.checked = hide; - $.event('CloseMenu'); - (hide ? $.addClass : $.rmClass)(Header.bar, 'autohide'); - return (hide ? $.addClass : $.rmClass)(doc, 'autohide'); - }, - toggleBarVisibility: function() { - var hide, message; - hide = this.nodeName === 'INPUT' ? this.checked : !$.hasClass(Header.bar, 'autohide'); - Conf['Header auto-hide'] = hide; - $.set('Header auto-hide', hide); - Header.setBarVisibility(hide); - message = "The header bar will " + (hide ? 'automatically hide itself.' : 'remain visible.'); - return new Notice('info', message, 2); - }, - setHideBarOnScroll: function(hide) { - Header.scrollHeaderToggler.checked = hide; - if (hide) { - $.on(window, 'scroll', Header.hideBarOnScroll); - return; - } - $.off(window, 'scroll', Header.hideBarOnScroll); - $.rmClass(Header.bar, 'scroll'); - return Header.bar.classList.toggle('autohide', Conf['Header auto-hide']); - }, - toggleHideBarOnScroll: function() { - var hide; - hide = this.checked; - $.cb.checked.call(this); - return Header.setHideBarOnScroll(hide); - }, - hideBarOnScroll: function() { - var offsetY; - offsetY = window.pageYOffset; - if (offsetY > (Header.previousOffset || 0)) { - $.addClass(Header.bar, 'autohide', 'scroll'); - } else { - $.rmClass(Header.bar, 'autohide', 'scroll'); - } - return Header.previousOffset = offsetY; - }, - setBarPosition: function(bottom) { - var args, ref; - if ((ref = Header.barPositionToggler) != null) { - ref.checked = bottom; - } - $.event('CloseMenu'); - args = bottom ? ['bottom-header', 'top-header', 'after'] : ['top-header', 'bottom-header', 'add']; - $.addClass(doc, args[0]); - $.rmClass(doc, args[1]); - return $[args[2]](Header.bar, Header.noticesRoot); - }, - toggleBarPosition: function() { - $.cb.checked.call(this); - return Header.setBarPosition(this.checked); - }, - setFooterVisibility: function(hide) { - Header.footerToggler.checked = hide; - return doc.classList.toggle('hide-bottom-board-list', hide); - }, - toggleFooterVisibility: function() { - var hide, message; - $.event('CloseMenu'); - hide = this.nodeName === 'INPUT' ? this.checked : $.hasClass(doc, 'hide-bottom-board-list'); - Header.setFooterVisibility(hide); - $.set('Bottom Board List', hide); - message = hide ? 'The bottom navigation will now be hidden.' : 'The bottom navigation will remain visible.'; - return new Notice('info', message, 2); - }, - setCustomNav: function(show) { - var btn, cust, full, ref; - Header.customNavToggler.checked = show; - cust = $('#custom-board-list', Header.bar); - full = $('#full-board-list', Header.bar); - btn = $('.hide-board-list-container', full); - return ref = show ? [false, true, false] : [true, false, true], cust.hidden = ref[0], full.hidden = ref[1], btn.hidden = ref[2], ref; - }, - toggleCustomNav: function() { - $.cb.checked.call(this); - return Header.setCustomNav(this.checked); - }, - editCustomNav: function() { - var settings; - Settings.open('Advanced'); - settings = $.id('fourchanx-settings'); - return $('[name=boardnav]', settings).focus(); - }, - hashScroll: function(e) { - var el, hash; - if (e) { - if (e.state) { - return; - } - if (!history.state) { - history.replaceState({}, ''); - } - } - if ((hash = location.hash.slice(1))) { - ReplyPruning.showIfHidden(hash); - if ((el = $.id(hash))) { - return $.queueTask(function() { - return Header.scrollTo(el); - }); - } - } - }, - scrollTo: function(root, down, needed) { - var height, x; - if (!root.offsetParent) { - return; - } - if (down) { - x = Header.getBottomOf(root); - if (Conf['Fixed Header'] && Conf['Header auto-hide on scroll'] && Conf['Bottom header']) { - height = Header.bar.getBoundingClientRect().height; - if (x <= 0) { - if (!Header.isHidden()) { - x += height; - } - } else { - if (Header.isHidden()) { - x -= height; - } - } - } - if (!(needed && x >= 0)) { - return window.scrollBy(0, -x); - } - } else { - x = Header.getTopOf(root); - if (Conf['Fixed Header'] && Conf['Header auto-hide on scroll'] && !Conf['Bottom header']) { - height = Header.bar.getBoundingClientRect().height; - if (x >= 0) { - if (!Header.isHidden()) { - x += height; - } - } else { - if (Header.isHidden()) { - x -= height; - } - } - } - if (!(needed && x >= 0)) { - return window.scrollBy(0, x); - } - } - }, - scrollToIfNeeded: function(root, down) { - return Header.scrollTo(root, down, true); - }, - getTopOf: function(root) { - var headRect, top; - top = root.getBoundingClientRect().top; - if (Conf['Fixed Header'] && !Conf['Bottom Header']) { - headRect = Header.toggle.getBoundingClientRect(); - top -= headRect.top + headRect.height; - } - return top; - }, - getBottomOf: function(root) { - var bottom, clientHeight, headRect; - clientHeight = doc.clientHeight; - bottom = clientHeight - root.getBoundingClientRect().bottom; - if (Conf['Fixed Header'] && Conf['Bottom Header']) { - headRect = Header.toggle.getBoundingClientRect(); - bottom -= clientHeight - headRect.bottom + headRect.height; - } - return bottom; - }, - isNodeVisible: function(node) { - var height; - if (d.hidden || !doc.contains(node)) { - return false; - } - height = node.getBoundingClientRect().height; - return Header.getTopOf(node) + height >= 0 && Header.getBottomOf(node) + height >= 0; - }, - isHidden: function() { - var top; - top = Header.bar.getBoundingClientRect().top; - if (Conf['Bottom header']) { - return top === doc.clientHeight; - } else { - return top < 0; - } - }, - addShortcut: function(id, el, index) { - var i, item, len, ref, shortcut; - shortcut = $.el('span', { - id: "shortcut-" + id, - className: 'shortcut brackets-wrap' - }); - $.add(shortcut, el); - shortcut.dataset.index = index; - ref = $$('[data-index]', Header.shortcuts); - for (i = 0, len = ref.length; i < len; i++) { - item = ref[i]; - if (!(+item.dataset.index > +index)) { - continue; - } - $.before(item, shortcut); - return; - } - return $.add(Header.shortcuts, shortcut); - }, - rmShortcut: function(el) { - return $.rm(el.parentElement); - }, - menuToggle: function(e) { - return Header.menu.toggle(e, this, g); - }, - createNotification: function(e) { - var content, lifetime, notice, ref, type; - ref = e.detail, type = ref.type, content = ref.content, lifetime = ref.lifetime; - return notice = new Notice(type, content, lifetime); - }, - areNotificationsEnabled: false, - enableDesktopNotifications: function() { - var authorize, disable, el, notice, ref; - if (!(window.Notification && Conf['Desktop Notifications'])) { - return; - } - switch (Notification.permission) { - case 'granted': - Header.areNotificationsEnabled = true; - return; - case 'denied': - return; - } - el = $.el('span', {innerHTML: "4chan X needs your permission to show desktop notifications. [FAQ]
    or "}); - ref = $$('button', el), authorize = ref[0], disable = ref[1]; - $.on(authorize, 'click', function() { - return Notification.requestPermission(function(status) { - Header.areNotificationsEnabled = status === 'granted'; - if (status === 'default') { - return; - } - return notice.close(); - }); - }); - $.on(disable, 'click', function() { - $.set('Desktop Notifications', false); - return notice.close(); - }); - return notice = new Notice('info', el); - } - }; - - return Header; - -}).call(this); - -Index = (function() { - var Index, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Index = { - showHiddenThreads: false, - changed: {}, - enabledOn: function(arg) { - var boardID, siteID; - siteID = arg.siteID, boardID = arg.boardID; - return Conf['JSON Index'] && g.sites[siteID].software === 'yotsuba' && boardID !== 'f'; - }, - init: function() { - var arr, entries, i, input, inputs, k, l, label, len1, len2, name, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, select, sortEntry, tRaw, watchSettings; - if (g.VIEW !== 'index') { - return; - } - $.one(d, '4chanXInitFinished', this.cb.initFinished); - $.on(d, 'PostsInserted', this.cb.postsInserted); - if (!this.enabledOn(g.BOARD)) { - return; - } - this.enabled = true; - Callbacks.Post.push({ - name: 'Index Page Numbers', - cb: this.node - }); - Callbacks.CatalogThread.push({ - name: 'Catalog Features', - cb: this.catalogNode - }); - this.search = ((ref = history.state) != null ? ref.searched : void 0) || ''; - if ((ref1 = history.state) != null ? ref1.mode : void 0) { - Conf['Index Mode'] = (ref2 = history.state) != null ? ref2.mode : void 0; - } - this.currentSort = (ref3 = history.state) != null ? ref3.sort : void 0; - this.currentSort || (this.currentSort = typeof Conf['Index Sort'] === 'object' ? Conf['Index Sort'][g.BOARD.ID] || 'bump' : Conf['Index Sort']); - this.currentPage = this.getCurrentPage(); - this.processHash(); - $.addClass(doc, 'index-loading', (Conf['Index Mode'].replace(/\ /g, '-')) + "-mode"); - $.on(window, 'popstate', this.cb.popstate); - $.on(d, 'scroll', this.scroll); - $.on(d, 'SortIndex', this.cb.resort); - this.button = $.el('a', { - className: 'fa fa-refresh', - title: 'Refresh', - href: 'javascript:;', - textContent: 'Refresh Index' - }); - $.on(this.button, 'click', function() { - return Index.update(); - }); - Header.addShortcut('index-refresh', this.button, 590); - entries = []; - this.inputs = inputs = $.dict(); - ref4 = Config.Index; - for (name in ref4) { - arr = ref4[name]; - if (!(arr instanceof Array)) { - continue; - } - label = UI.checkbox(name, "" + name[0] + (name.slice(1).toLowerCase())); - label.title = arr[1]; - entries.push({ - el: label - }); - input = label.firstChild; - $.on(input, 'change', $.cb.checked); - inputs[name] = input; - } - $.on(inputs['Show Replies'], 'change', this.cb.replies); - $.on(inputs['Catalog Hover Expand'], 'change', this.cb.hover); - $.on(inputs['Pin Watched Threads'], 'change', this.cb.resort); - $.on(inputs['Anchor Hidden Threads'], 'change', this.cb.resort); - watchSettings = function(e) { - if ((input = $.getOwn(inputs, e.target.name))) { - input.checked = e.target.checked; - return $.event('change', null, input); - } - }; - $.on(d, 'OpenSettings', function() { - return $.on($.id('fourchanx-settings'), 'change', watchSettings); - }); - sortEntry = UI.checkbox('Per-Board Sort Type', 'Per-board sort type', typeof Conf['Index Sort'] === 'object'); - sortEntry.title = 'Set the sorting order of each board independently.'; - $.on(sortEntry.firstChild, 'change', this.cb.perBoardSort); - entries.splice(3, 0, { - el: sortEntry - }); - Header.menu.addEntry({ - el: $.el('span', { - textContent: 'Index Navigation' - }), - order: 100, - subEntries: entries - }); - this.navLinks = $.el('div', { - className: 'navLinks json-index' - }); - $.extend(this.navLinks, {innerHTML: "Index Catalog Archive Bottom ×"}); - $('.cataloglink a', this.navLinks).href = CatalogLinks.catalog(); - if (!BoardConfig.isArchived(g.BOARD.ID)) { - $('.archlistlink', this.navLinks).hidden = true; - } - $.on($('#index-last-refresh a', this.navLinks), 'click', this.cb.refreshFront); - this.searchInput = $('#index-search', this.navLinks); - this.setupSearch(); - $.on(this.searchInput, 'input', this.onSearchInput); - $.on($('#index-search-clear', this.navLinks), 'click', this.clearSearch); - this.hideLabel = $('#hidden-label', this.navLinks); - $.on($('#hidden-toggle a', this.navLinks), 'click', this.cb.toggleHiddenThreads); - this.selectRev = $('#index-rev', this.navLinks); - this.selectMode = $('#index-mode', this.navLinks); - this.selectSort = $('#index-sort', this.navLinks); - this.selectSize = $('#index-size', this.navLinks); - $.on(this.selectRev, 'change', this.cb.sort); - $.on(this.selectMode, 'change', this.cb.mode); - $.on(this.selectSort, 'change', this.cb.sort); - $.on(this.selectSize, 'change', $.cb.value); - $.on(this.selectSize, 'change', this.cb.size); - ref5 = [this.selectMode, this.selectSize]; - for (k = 0, len1 = ref5.length; k < len1; k++) { - select = ref5[k]; - select.value = Conf[select.name]; - } - this.selectRev.checked = /-rev$/.test(Index.currentSort); - this.selectSort.value = Index.currentSort.replace(/-rev$/, ''); - this.lastLongOptions = $('#lastlong-options', this.navLinks); - this.lastLongInputs = $$('input', this.lastLongOptions); - this.lastLongThresholds = [0, 0]; - this.lastLongOptions.hidden = this.selectSort.value !== 'lastlong'; - ref6 = this.lastLongInputs; - for (i = l = 0, len2 = ref6.length; l < len2; i = ++l) { - input = ref6[i]; - $.on(input, 'change', this.cb.lastLongThresholds); - tRaw = Conf["Last Long Reply Thresholds " + i]; - input.value = this.lastLongThresholds[i] = typeof tRaw === 'object' ? (ref7 = tRaw[g.BOARD.ID]) != null ? ref7 : 100 : tRaw; - } - this.root = $.el('div', { - className: 'board json-index' - }); - $.on(this.root, 'click', this.cb.hoverToggle); - this.cb.size(); - this.cb.hover(); - this.pagelist = $.el('div', { - className: 'pagelist json-index' - }); - $.extend(this.pagelist, {innerHTML: "
    "}); - $('.cataloglink a', this.pagelist).href = CatalogLinks.catalog(); - $.on(this.pagelist, 'click', this.cb.pageNav); - this.update(true); - $.onExists(doc, 'title + *', function() { - return d.title = d.title.replace(/\ -\ Page\ \d+/, ''); - }); - $.onExists(doc, '.board > .thread > .postContainer, .board + *', function() { - var board, el, len3, m, ref8, timeEl, topNavPos; - g.SITE.Build.hat = $('.board > .thread > img:first-child'); - if (g.SITE.Build.hat) { - g.BOARD.threads.forEach(function(thread) { - if (thread.nodes.root) { - return $.prepend(thread.nodes.root, g.SITE.Build.hat.cloneNode(false)); - } - }); - $.addClass(doc, 'hats-enabled'); - $.addStyle(".catalog-thread::after {background-image: url(" + g.SITE.Build.hat.src + ");}"); - } - board = $('.board'); - $.replace(board, Index.root); - if (Index.loaded) { - $.event('PostsInserted', null, Index.root); - } - try { - d.implementation.createDocument(null, null, null).appendChild(board); - } catch (error) {} - ref8 = $$('.navLinks'); - for (m = 0, len3 = ref8.length; m < len3; m++) { - el = ref8[m]; - $.rm(el); - } - $.rm($.id('ctrl-top')); - topNavPos = $.id('delform').previousElementSibling; - $.before(topNavPos, $.el('hr')); - $.before(topNavPos, Index.navLinks); - timeEl = $('#index-last-refresh time', Index.navLinks); - if (timeEl.dataset.utc) { - return RelativeDates.update(timeEl); - } - }); - return Main.ready(function() { - var pagelist; - if ((pagelist = $('.pagelist'))) { - $.replace(pagelist, Index.pagelist); - } - return $.rmClass(doc, 'index-loading'); - }); - }, - scroll: function() { - var pageNum, threadIDs; - if (Index.req || !Index.liveThreadData || Conf['Index Mode'] !== 'infinite' || (window.scrollY <= doc.scrollHeight - (300 + window.innerHeight))) { - return; - } - if (Index.pageNum == null) { - Index.pageNum = Index.currentPage; - } - pageNum = ++Index.pageNum; - if (pageNum > Index.pagesNum) { - return Index.endNotice(); - } - threadIDs = Index.threadsOnPage(pageNum); - return Index.buildStructure(threadIDs); - }, - endNotice: (function() { - var notify, reset; - notify = false; - reset = function() { - return notify = false; - }; - return function() { - if (notify) { - return; - } - notify = true; - new Notice('info', "Last page reached.", 2); - return setTimeout(reset, 3 * $.SECOND); - }; - })(), - menu: { - init: function() { - if (!(g.VIEW === 'index' && Conf['Menu'] && Conf['Thread Hiding Link'] && Index.enabledOn(g.BOARD))) { - return; - } - return Menu.menu.addEntry({ - el: $.el('a', { - href: 'javascript:;', - className: 'has-shortcut-text' - }, {innerHTML: "Shift+click"}), - order: 20, - open: function(arg) { - var thread; - thread = arg.thread; - if (Conf['Index Mode'] !== 'catalog') { - return false; - } - this.el.firstElementChild.textContent = thread.isHidden ? 'Unhide' : 'Hide'; - if (this.cb) { - $.off(this.el, 'click', this.cb); - } - this.cb = function() { - $.event('CloseMenu'); - return Index.toggleHide(thread); - }; - $.on(this.el, 'click', this.cb); - return true; - } - }); - } - }, - node: function() { - if (this.isReply || this.isClone || !(Index.threadPosition[this.ID] != null)) { - return; - } - return this.thread.setPage(Math.floor(Index.threadPosition[this.ID] / Index.threadsNumPerPage) + 1); - }, - catalogNode: function() { - return $.on(this.nodes.root, 'mousedown click', (function(_this) { - return function(e) { - if (!(e.button === 0 && e.shiftKey)) { - return; - } - if (e.type === 'click') { - Index.toggleHide(_this.thread); - } - return e.preventDefault(); - }; - })(this)); - }, - toggleHide: function(thread) { - if (Index.showHiddenThreads) { - ThreadHiding.show(thread); - if (!ThreadHiding.db.get({ - boardID: thread.board.ID, - threadID: thread.ID - })) { - return; - } - } else { - ThreadHiding.hide(thread); - } - return ThreadHiding.saveHiddenState(thread); - }, - cycleSortType: function() { - var i, k, len1, type, types; - types = slice.call(Index.selectSort.options).filter(function(option) { - return !option.disabled; - }); - for (i = k = 0, len1 = types.length; k < len1; i = ++k) { - type = types[i]; - if (type.selected) { - break; - } - } - types[(i + 1) % types.length].selected = true; - return $.event('change', null, Index.selectSort); - }, - cb: { - initFinished: function() { - Index.initFinishedFired = true; - return $.queueTask(function() { - return Index.cb.postsInserted(); - }); - }, - postsInserted: function() { - var n; - if (!Index.initFinishedFired) { - return; - } - n = 0; - g.posts.forEach(function(post) { - if (!post.isFetchedQuote && !post.indexRefreshSeen && doc.contains(post.nodes.root)) { - post.indexRefreshSeen = true; - return n++; - } - }); - if (n) { - return $.event('IndexRefresh'); - } - }, - toggleHiddenThreads: function() { - $('#hidden-toggle a', Index.navLinks).textContent = (Index.showHiddenThreads = !Index.showHiddenThreads) ? 'Hide' : 'Show'; - Index.sort(); - return Index.buildIndex(); - }, - mode: function() { - Index.pushState({ - mode: this.value - }); - return Index.pageLoad(false); - }, - sort: function() { - var value; - value = Index.selectRev.checked ? Index.selectSort.value + "-rev" : Index.selectSort.value; - Index.pushState({ - sort: value - }); - return Index.pageLoad(false); - }, - resort: function(e) { - var ref; - Index.changed.order = true; - if (!(e != null ? (ref = e.detail) != null ? ref.deferred : void 0 : void 0)) { - return Index.pageLoad(false); - } - }, - perBoardSort: function() { - var i, k; - Conf['Index Sort'] = this.checked ? $.dict() : ''; - Index.saveSort(); - for (i = k = 0; k < 2; i = ++k) { - Conf["Last Long Reply Thresholds " + i] = this.checked ? $.dict() : ''; - Index.saveLastLongThresholds(i); - } - }, - lastLongThresholds: function() { - var i, value; - i = slice.call(this.parentNode.children).indexOf(this); - value = +this.value; - if (!Number.isFinite(value)) { - this.value = Index.lastLongThresholds[i]; - return; - } - Index.lastLongThresholds[i] = value; - Index.saveLastLongThresholds(i); - Index.changed.order = true; - return Index.pageLoad(false); - }, - size: function(e) { - if (Conf['Index Mode'] !== 'catalog') { - $.rmClass(Index.root, 'catalog-small'); - $.rmClass(Index.root, 'catalog-large'); - } else if (Conf['Index Size'] === 'small') { - $.addClass(Index.root, 'catalog-small'); - $.rmClass(Index.root, 'catalog-large'); - } else { - $.addClass(Index.root, 'catalog-large'); - $.rmClass(Index.root, 'catalog-small'); - } - if (e) { - return Index.buildIndex(); - } - }, - replies: function() { - return Index.buildIndex(); - }, - hover: function() { - return doc.classList.toggle('catalog-hover-expand', Conf['Catalog Hover Expand']); - }, - hoverToggle: function(e) { - var input, thread; - if (Conf['Catalog Hover Toggle'] && $.hasClass(doc, 'catalog-mode') && !$.modifiedClick(e) && !$.x('ancestor-or-self::a', e.target)) { - input = Index.inputs['Catalog Hover Expand']; - input.checked = !input.checked; - $.event('change', null, input); - if ((thread = Get.threadFromNode(e.target))) { - Index.cb.catalogReplies.call(thread); - return Index.cb.hoverAdjust.call(thread.OP.nodes); - } - } - }, - popstate: function(e) { - var mode, nCommands, page, ref, searched, sort; - if (e != null ? e.state : void 0) { - ref = e.state, searched = ref.searched, mode = ref.mode, sort = ref.sort; - page = Index.getCurrentPage(); - Index.setState({ - search: searched, - mode: mode, - sort: sort, - page: page - }); - return Index.pageLoad(false); - } else { - nCommands = Index.processHash(); - if (Conf['Refreshed Navigation'] && nCommands) { - return Index.update(); - } else { - return Index.pageLoad(); - } - } - }, - pageNav: function(e) { - var a; - if ($.modifiedClick(e)) { - return; - } - switch (e.target.nodeName) { - case 'BUTTON': - e.target.blur(); - a = e.target.parentNode; - break; - case 'A': - a = e.target; - break; - default: - return; - } - if (a.textContent === 'Catalog') { - return; - } - e.preventDefault(); - return Index.userPageNav(+a.pathname.split(/\/+/)[2] || 1); - }, - refreshFront: function() { - Index.pushState({ - page: 1 - }); - return Index.update(); - }, - catalogReplies: function() { - if (Conf['Show Replies'] && $.hasClass(doc, 'catalog-hover-expand') && !this.catalogView.nodes.replies) { - return Index.buildCatalogReplies(this); - } - }, - hoverAdjust: function() { - var rect, style, x; - if (!$.hasClass(doc, 'catalog-hover-expand')) { - return; - } - rect = this.post.getBoundingClientRect(); - if ((x = $.minmax(0, -rect.left, doc.clientWidth - rect.right))) { - style = this.post.style; - style.left = x + "px"; - style.right = (-x) + "px"; - return $.one(this.root, 'mouseleave', function() { - return style.left = style.right = null; - }); - } - } - }, - scrollToIndex: function() { - return Header.scrollToIfNeeded((Index.navLinks.getBoundingClientRect().height ? Index.navLinks : Index.root)); - }, - getCurrentPage: function() { - return +window.location.pathname.split(/\/+/)[2] || 1; - }, - userPageNav: function(page) { - Index.pushState({ - page: page - }); - if (Conf['Refreshed Navigation']) { - return Index.update(); - } else { - return Index.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: function() { - var command, commands, hash, k, leftover, len1, mode, ref, sort, state; - hash = ((ref = location.href.match(/#.*/)) != null ? ref[0] : void 0) || ''; - state = { - replace: true - }; - commands = hash.slice(1).split('/'); - leftover = []; - for (k = 0, len1 = commands.length; k < len1; k++) { - command = commands[k]; - if ((mode = $.getOwn(Index.hashCommands.mode, command))) { - state.mode = mode; - } else if (command === 'index') { - state.mode = Conf['Previous Index Mode']; - state.page = 1; - } else if ((sort = $.getOwn(Index.hashCommands.sort, command.replace(/-rev$/, '')))) { - state.sort = sort; - if (/-rev$/.test(command)) { - state.sort += '-rev'; - } - } else if (/^s=/.test(command)) { - state.search = decodeURIComponent(command.slice(2)).replace(/\+/g, ' ').trim(); - } else { - leftover.push(command); - } - } - hash = leftover.join('/'); - if (hash) { - state.hash = "#" + hash; - } - Index.pushState(state); - return commands.length - leftover.length; - }, - pushState: function(state) { - var hash, pageBeforeSearch, pathname, ref, replace, search; - search = state.search, hash = state.hash, replace = state.replace; - pageBeforeSearch = (ref = history.state) != null ? ref.oldpage : void 0; - if ((search != null) && search !== Index.search) { - state.page = search ? 1 : pageBeforeSearch || 1; - if (!search) { - pageBeforeSearch = void 0; - } else if (!Index.search) { - pageBeforeSearch = Index.currentPage; - } - } - Index.setState(state); - pathname = Index.currentPage === 1 ? "/" + g.BOARD + "/" : "/" + g.BOARD + "/" + Index.currentPage; - hash || (hash = ''); - return history[replace ? 'replaceState' : 'pushState']({ - mode: Conf['Index Mode'], - sort: Index.currentSort, - searched: Index.search, - oldpage: pageBeforeSearch - }, '', location.protocol + "//" + location.host + pathname + hash); - }, - setState: function(arg) { - var hash, mode, page, ref, search, sort; - search = arg.search, mode = arg.mode, sort = arg.sort, page = arg.page, hash = arg.hash; - if ((search != null) && search !== Index.search) { - Index.changed.search = true; - Index.search = search; - } - if ((mode != null) && mode !== Conf['Index Mode']) { - Index.changed.mode = true; - Conf['Index Mode'] = mode; - $.set('Index Mode', mode); - if (!(mode === 'catalog' || Conf['Previous Index Mode'] === mode)) { - Conf['Previous Index Mode'] = mode; - $.set('Previous Index Mode', mode); - } - } - if ((sort != null) && sort !== Index.currentSort) { - Index.changed.sort = true; - Index.currentSort = sort; - Index.saveSort(); - } - if ((ref = Conf['Index Mode']) === 'all pages' || ref === 'catalog') { - page = 1; - } - if ((page != null) && page !== Index.currentPage) { - Index.changed.page = true; - Index.currentPage = page; - } - if (hash != null) { - return Index.changed.hash = true; - } - }, - savePerBoard: function(key, value) { - if (typeof Conf[key] === 'object') { - Conf[key][g.BOARD.ID] = value; - } else { - Conf[key] = value; - } - return $.set(key, Conf[key]); - }, - saveSort: function() { - return Index.savePerBoard('Index Sort', Index.currentSort); - }, - saveLastLongThresholds: function(i) { - return Index.savePerBoard("Last Long Reply Thresholds " + i, Index.lastLongThresholds[i]); - }, - pageLoad: function(scroll) { - var hash, mode, order, page, ref, search, sort, threads; - if (scroll == null) { - scroll = true; - } - if (!Index.liveThreadData) { - return; - } - ref = Index.changed, threads = ref.threads, order = ref.order, search = ref.search, mode = ref.mode, sort = ref.sort, page = ref.page, hash = ref.hash; - threads || (threads = search); - order || (order = sort); - if (threads || order) { - Index.sort(); - } - if (threads) { - Index.buildPagelist(); - } - if (search) { - Index.setupSearch(); - } - if (mode) { - Index.setupMode(); - } - if (sort) { - Index.setupSort(); - } - if (threads || mode || page || order) { - Index.buildIndex(); - } - if (threads || page) { - Index.setPage(); - } - if (scroll && !hash) { - Index.scrollToIndex(); - } - if (hash) { - Header.hashScroll(); - } - return Index.changed = {}; - }, - setupMode: function() { - var k, len1, mode, ref; - ref = ['paged', 'infinite', 'all pages', 'catalog']; - for (k = 0, len1 = ref.length; k < len1; k++) { - mode = ref[k]; - $[mode === Conf['Index Mode'] ? 'addClass' : 'rmClass'](doc, (mode.replace(/\ /g, '-')) + "-mode"); - } - Index.selectMode.value = Conf['Index Mode']; - Index.cb.size(); - Index.showHiddenThreads = false; - return $('#hidden-toggle a', Index.navLinks).textContent = 'Show'; - }, - setupSort: function() { - Index.selectRev.checked = /-rev$/.test(Index.currentSort); - Index.selectSort.value = Index.currentSort.replace(/-rev$/, ''); - return Index.lastLongOptions.hidden = Index.selectSort.value !== 'lastlong'; - }, - getPagesNum: function() { - if (Index.search) { - return Math.ceil(Index.sortedThreadIDs.length / Index.threadsNumPerPage); - } else { - return Index.pagesNum; - } - }, - getMaxPageNum: function() { - return Math.max(1, Index.getPagesNum()); - }, - buildPagelist: function() { - var a, i, k, maxPageNum, nodes, pagesRoot, ref; - pagesRoot = $('.pages', Index.pagelist); - maxPageNum = Index.getMaxPageNum(); - if (pagesRoot.childElementCount !== maxPageNum) { - nodes = []; - for (i = k = 1, ref = maxPageNum; k <= ref; i = k += 1) { - a = $.el('a', { - textContent: i, - href: i === 1 ? './' : i - }); - nodes.push($.tn('['), a, $.tn('] ')); - } - $.rmAll(pagesRoot); - return $.add(pagesRoot, nodes); - } - }, - setPage: function() { - var a, href, maxPageNum, next, pageNum, pagesRoot, prev, strong; - pageNum = Index.currentPage; - maxPageNum = Index.getMaxPageNum(); - pagesRoot = $('.pages', Index.pagelist); - prev = pagesRoot.previousSibling.firstChild; - next = pagesRoot.nextSibling.firstChild; - href = Math.max(pageNum - 1, 1); - prev.href = href === 1 ? './' : href; - prev.firstChild.disabled = href === pageNum; - href = Math.min(pageNum + 1, maxPageNum); - next.href = href === 1 ? './' : href; - next.firstChild.disabled = href === pageNum; - if (strong = $('strong', pagesRoot)) { - if (+strong.textContent === pageNum) { - return; - } - $.replace(strong, strong.firstChild); - } else { - strong = $.el('strong'); - } - if ((a = pagesRoot.children[pageNum - 1])) { - $.before(a, strong); - return $.add(strong, a); - } - }, - updateHideLabel: function() { - var hiddenCount, k, len1, ref, threadID; - if (!Index.hideLabel) { - return; - } - hiddenCount = 0; - ref = Index.liveThreadIDs; - for (k = 0, len1 = ref.length; k < len1; k++) { - threadID = ref[k]; - if (Index.isHidden(threadID)) { - hiddenCount++; - } - } - if (!hiddenCount) { - Index.hideLabel.hidden = true; - if (Index.showHiddenThreads) { - Index.cb.toggleHiddenThreads(); - } - return; - } - Index.hideLabel.hidden = false; - return $('#hidden-count', Index.navLinks).textContent = hiddenCount === 1 ? '1 hidden thread' : hiddenCount + " hidden threads"; - }, - update: function(firstTime) { - var oldReq; - if ((oldReq = Index.req)) { - delete Index.req; - oldReq.abort(); - } - if (Conf['Index Refresh Notifications']) { - Index.notice || (Index.notice = new Notice('info', 'Refreshing index...')); - Index.nTimeout || (Index.nTimeout = setTimeout(function() { - var ref; - return (ref = Index.notice) != null ? ref.el.lastElementChild.textContent += ' (disable JSON Index if this takes too long)' : void 0; - }, 3 * $.SECOND)); - } else { - Index.nTimeout || (Index.nTimeout = setTimeout(function() { - return Index.notice || (Index.notice = new Notice('info', 'Refreshing index... (disable JSON Index if this takes too long)')); - }, 3 * $.SECOND)); - } - if (!firstTime && d.readyState !== 'loading' && !$('.board + *')) { - location.reload(); - return; - } - Index.req = $.whenModified(g.SITE.urls.catalogJSON({ - boardID: g.BOARD.ID - }), 'Index', Index.load); - return $.addClass(Index.button, 'fa-spin'); - }, - load: function() { - var err, nTimeout, notice, ref, timeEl; - if (this !== Index.req) { - return; - } - $.rmClass(Index.button, 'fa-spin'); - notice = Index.notice, nTimeout = Index.nTimeout; - if (nTimeout) { - clearTimeout(nTimeout); - } - delete Index.nTimeout; - delete Index.req; - delete Index.notice; - if ((ref = this.status) !== 200 && ref !== 304) { - err = "Index refresh failed. " + (this.status ? "Error " + this.statusText + " (" + this.status + ")" : 'Connection Error'); - if (notice) { - notice.setType('warning'); - notice.el.lastElementChild.textContent = err; - setTimeout(notice.close, $.SECOND); - } else { - new Notice('warning', err, 1); - } - return; - } - try { - if (this.status === 200) { - Index.parse(this.response); - } else if (this.status === 304) { - Index.pageLoad(); - } - } catch (error) { - err = error; - c.error("Index failure: " + err.message, err.stack); - if (notice) { - notice.setType('error'); - notice.el.lastElementChild.textContent = 'Index refresh failed.'; - setTimeout(notice.close, $.SECOND); - } else { - new Notice('error', 'Index refresh failed.', 1); - } - return; - } - if (notice) { - if (Conf['Index Refresh Notifications']) { - notice.setType('success'); - notice.el.lastElementChild.textContent = 'Index refreshed!'; - setTimeout(notice.close, $.SECOND); - } else { - notice.close(); - } - } - timeEl = $('#index-last-refresh time', Index.navLinks); - timeEl.dataset.utc = Date.parse(this.getResponseHeader('Last-Modified')); - return RelativeDates.update(timeEl); - }, - parse: function(pages) { - $.cleanCache(function(url) { - return /^https?:\/\/a\.4cdn\.org\//.test(url); - }); - Index.parseThreadList(pages); - Index.changed.threads = true; - return Index.pageLoad(); - }, - parseThreadList: function(pages) { - var ID, data, i, k, l, len1, len2, obj, ref, ref1, ref2, reply, results; - Index.pagesNum = pages.length; - Index.threadsNumPerPage = ((ref = pages[0]) != null ? ref.threads.length : void 0) || 1; - Index.liveThreadData = pages.reduce((function(arr, next) { - return arr.concat(next.threads); - }), []); - Index.liveThreadIDs = Index.liveThreadData.map(function(data) { - return data.no; - }); - Index.liveThreadDict = $.dict(); - Index.threadPosition = $.dict(); - Index.parsedThreads = $.dict(); - Index.replyData = $.dict(); - ref1 = Index.liveThreadData; - for (i = k = 0, len1 = ref1.length; k < len1; i = ++k) { - data = ref1[i]; - Index.liveThreadDict[data.no] = data; - Index.threadPosition[data.no] = i; - Index.parsedThreads[data.no] = obj = g.SITE.Build.parseJSON(data, g.BOARD); - obj.filterResults = results = Filter.test(obj); - obj.isOnTop = results.top; - obj.isHidden = results.hide || ThreadHiding.isHidden(obj.boardID, obj.threadID); - if (data.last_replies) { - ref2 = data.last_replies; - for (l = 0, len2 = ref2.length; l < len2; l++) { - reply = ref2[l]; - Index.replyData[g.BOARD + "." + reply.no] = reply; - } - } - } - if (Index.liveThreadData[0]) { - g.SITE.Build.spoilerRange[g.BOARD.ID] = Index.liveThreadData[0].custom_spoiler; - } - g.BOARD.threads.forEach(function(thread) { - var ref3; - if (ref3 = thread.ID, indexOf.call(Index.liveThreadIDs, ref3) < 0) { - return thread.collect(); - } - }); - $.event('IndexUpdate', { - threads: (function() { - var len3, m, ref3, results1; - ref3 = Index.liveThreadIDs; - results1 = []; - for (m = 0, len3 = ref3.length; m < len3; m++) { - ID = ref3[m]; - results1.push(g.BOARD + "." + ID); - } - return results1; - })() - }); - }, - isHidden: function(threadID) { - var thread; - if ((thread = g.BOARD.threads.get(threadID)) && thread.OP && !thread.OP.isFetchedQuote) { - return thread.isHidden; - } else { - return Index.parsedThreads[threadID].isHidden; - } - }, - isHiddenReply: function(threadID, replyData) { - return PostHiding.isHidden(g.BOARD.ID, threadID, replyData.no) || Filter.isHidden(g.SITE.Build.parseJSON(replyData, g.BOARD)); - }, - buildThreads: function(threadIDs, isCatalog, withReplies) { - var ID, OP, err, errors, isStale, k, lastPost, len1, newPosts, newThreads, obj, opRoot, t, thread, threadData, threads; - threads = []; - newThreads = []; - newPosts = []; - for (k = 0, len1 = threadIDs.length; k < len1; k++) { - ID = threadIDs[k]; - try { - threadData = Index.liveThreadDict[ID]; - if ((thread = g.BOARD.threads.get(ID))) { - isStale = (thread.json !== threadData) && (JSON.stringify(thread.json) !== JSON.stringify(threadData)); - if (isStale) { - thread.setCount('post', threadData.replies + 1, threadData.bumplimit); - thread.setCount('file', threadData.images + !!threadData.ext, threadData.imagelimit); - thread.setStatus('Sticky', !!threadData.sticky); - thread.setStatus('Closed', !!threadData.closed); - } - if (thread.catalogView) { - $.rm(thread.catalogView.nodes.replies); - thread.catalogView.nodes.replies = null; - } - } else { - thread = new Thread(ID, g.BOARD); - newThreads.push(thread); - } - lastPost = threadData.last_replies && threadData.last_replies.length ? threadData.last_replies[threadData.last_replies.length - 1].no : ID; - if (lastPost > thread.lastPost) { - thread.lastPost = lastPost; - } - thread.json = threadData; - threads.push(thread); - if ((OP = thread.OP) && !OP.isFetchedQuote) { - OP.setCatalogOP(isCatalog); - thread.setPage(Math.floor(Index.threadPosition[ID] / Index.threadsNumPerPage) + 1); - } else { - obj = Index.parsedThreads[ID]; - opRoot = g.SITE.Build.post(obj); - OP = new Post(opRoot, thread, g.BOARD); - OP.filterResults = obj.filterResults; - newPosts.push(OP); - } - if (!(isCatalog && thread.nodes.root)) { - g.SITE.Build.thread(thread, threadData, withReplies); - } - } catch (error) { - err = error; - if (!errors) { - errors = []; - } - errors.push({ - message: "Parsing of Thread No." + thread + " failed. Thread will be skipped.", - error: err, - html: opRoot != null ? opRoot.outerHTML : void 0 - }); - } - } - if (errors) { - Main.handleErrors(errors); - } - if (withReplies) { - newPosts = newPosts.concat(Index.buildReplies(threads)); - } - Main.callbackNodes('Thread', newThreads); - Main.callbackNodes('Post', newPosts); - Index.updateHideLabel(); - $.event('IndexRefreshInternal', { - threadIDs: (function() { - var l, len2, results1; - results1 = []; - for (l = 0, len2 = threads.length; l < len2; l++) { - t = threads[l]; - results1.push(t.fullID); - } - return results1; - })(), - isCatalog: isCatalog - }); - return threads; - }, - buildReplies: function(threads) { - var data, err, errors, k, l, lastReplies, len1, len2, node, nodes, post, posts, thread; - posts = []; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - if (!(lastReplies = Index.liveThreadDict[thread.ID].last_replies)) { - continue; - } - nodes = []; - for (l = 0, len2 = lastReplies.length; l < len2; l++) { - data = lastReplies[l]; - if ((post = thread.posts.get(data.no)) && !post.isFetchedQuote) { - nodes.push(post.nodes.root); - continue; - } - nodes.push(node = g.SITE.Build.postFromObject(data, thread.board.ID)); - try { - posts.push(new Post(node, thread, thread.board)); - } catch (error) { - err = error; - if (!errors) { - errors = []; - } - errors.push({ - message: "Parsing of Post No." + data.no + " failed. Post will be skipped.", - error: err, - html: node != null ? node.outerHTML : void 0 - }); - } - } - $.add(thread.nodes.root, nodes); - } - if (errors) { - Main.handleErrors(errors); - } - return posts; - }, - buildCatalogViews: function(threads) { - var ID, catalogThreads, k, len1, page, root, thread; - catalogThreads = []; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - if (!(!thread.catalogView)) { - continue; - } - ID = thread.ID; - page = Math.floor(Index.threadPosition[ID] / Index.threadsNumPerPage) + 1; - root = g.SITE.Build.catalogThread(thread, Index.liveThreadDict[ID], page); - catalogThreads.push(new CatalogThread(root, thread)); - } - Main.callbackNodes('CatalogThread', catalogThreads); - }, - sizeCatalogViews: function(threads) { - var height, k, len1, ratio, ref, size, thread, thumb, width; - size = Conf['Index Size'] === 'small' ? 150 : 250; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - thumb = thread.catalogView.nodes.thumb; - ref = thumb.dataset, width = ref.width, height = ref.height; - if (!width) { - continue; - } - ratio = size / Math.max(width, height); - thumb.style.width = width * ratio + 'px'; - thumb.style.height = height * ratio + 'px'; - } - }, - buildCatalogReplies: function(thread) { - var data, k, lastReplies, len1, nodes, replies, reply; - nodes = thread.catalogView.nodes; - if (!(lastReplies = Index.liveThreadDict[thread.ID].last_replies)) { - return; - } - replies = []; - for (k = 0, len1 = lastReplies.length; k < len1; k++) { - data = lastReplies[k]; - if (Index.isHiddenReply(thread.ID, data)) { - continue; - } - reply = g.SITE.Build.catalogReply(thread, data); - RelativeDates.update($('time', reply)); - $.on($('.catalog-reply-preview', reply), 'mouseover', QuotePreview.mouseover); - replies.push(reply); - } - nodes.replies = $.el('div', { - className: 'catalog-replies' - }); - $.add(nodes.replies, replies); - $.add(thread.OP.nodes.post, nodes.replies); - }, - sort: function() { - var lastlong, lastlongD, liveThreadData, liveThreadIDs, repliesAvailable, sortType, thread, threadIDs, tmp_time; - liveThreadIDs = Index.liveThreadIDs, liveThreadData = Index.liveThreadData; - if (!liveThreadData) { - return; - } - tmp_time = new Date().getTime() / 1000; - sortType = Index.currentSort.replace(/-rev$/, ''); - Index.sortedThreadIDs = (function() { - var k, len1; - switch (sortType) { - case 'lastreply': - case 'lastlong': - repliesAvailable = liveThreadData.some(function(thread) { - var ref; - return (ref = thread.last_replies) != null ? ref.length : void 0; - }); - lastlong = function(thread) { - var i, k, len, r, ref, ref1; - if (!repliesAvailable) { - return thread.last_modified; - } - ref = thread.last_replies || []; - for (i = k = ref.length - 1; k >= 0; i = k += -1) { - r = ref[i]; - if (Index.isHiddenReply(thread.no, r)) { - continue; - } - if (sortType === 'lastreply') { - return r; - } - len = r.com ? g.SITE.Build.parseComment(r.com).replace(/[^a-z]/ig, '').length : 0; - if (len >= Index.lastLongThresholds[+(!!r.ext)]) { - return r; - } - } - if (thread.omitted_posts && ((ref1 = thread.last_replies) != null ? ref1.length : void 0)) { - return thread.last_replies[0]; - } else { - return thread; - } - }; - lastlongD = $.dict(); - for (k = 0, len1 = liveThreadData.length; k < len1; k++) { - thread = liveThreadData[k]; - lastlongD[thread.no] = lastlong(thread).no; - } - return slice.call(liveThreadData).sort(function(a, b) { - return lastlongD[b.no] - lastlongD[a.no]; - }).map(function(post) { - return post.no; - }); - case 'bump': - return liveThreadIDs; - case 'birth': - return slice.call(liveThreadIDs).sort(function(a, b) { - return b - a; - }); - case 'replycount': - return slice.call(liveThreadData).sort(function(a, b) { - return b.replies - a.replies; - }).map(function(post) { - return post.no; - }); - case 'filecount': - return slice.call(liveThreadData).sort(function(a, b) { - return b.images - a.images; - }).map(function(post) { - return post.no; - }); - case 'activity': - return slice.call(liveThreadData).sort(function(a, b) { - return (tmp_time - a.time) / (a.replies + 1) - (tmp_time - b.time) / (b.replies + 1); - }).map(function(post) { - return post.no; - }); - default: - return liveThreadIDs; - } - })(); - if (/-rev$/.test(Index.currentSort)) { - Index.sortedThreadIDs = slice.call(Index.sortedThreadIDs).reverse(); - } - if (Index.search && (threadIDs = Index.querySearch(Index.search))) { - Index.sortedThreadIDs = threadIDs; - } - Index.sortOnTop(function(obj) { - return obj.isSticky; - }); - Index.sortOnTop(function(obj) { - return obj.isOnTop || Conf['Pin Watched Threads'] && ThreadWatcher.isWatchedRaw(obj.boardID, obj.threadID); - }); - if (Conf['Anchor Hidden Threads']) { - return Index.sortOnTop(function(obj) { - return !Index.isHidden(obj.threadID); - }); - } - }, - sortOnTop: function(match) { - var ID, bottomThreads, k, len1, ref, topThreads; - topThreads = []; - bottomThreads = []; - ref = Index.sortedThreadIDs; - for (k = 0, len1 = ref.length; k < len1; k++) { - ID = ref[k]; - (match(Index.parsedThreads[ID]) ? topThreads : bottomThreads).push(ID); - } - return Index.sortedThreadIDs = topThreads.concat(bottomThreads); - }, - buildIndex: function() { - var threadIDs; - if (!Index.liveThreadData) { - return; - } - switch (Conf['Index Mode']) { - case 'all pages': - threadIDs = Index.sortedThreadIDs; - break; - case 'catalog': - threadIDs = Index.sortedThreadIDs.filter(function(ID) { - return !Index.isHidden(ID) !== Index.showHiddenThreads; - }); - break; - default: - threadIDs = Index.threadsOnPage(Index.currentPage); - } - delete Index.pageNum; - $.rmAll(Index.root); - $.rmAll(Header.hover); - if (Index.loaded && Index.root.parentNode) { - $.event('PostsRemoved', null, Index.root); - } - if (Conf['Index Mode'] === 'catalog') { - Index.buildCatalog(threadIDs); - } else { - Index.buildStructure(threadIDs); - } - }, - threadsOnPage: function(pageNum) { - var nodesPerPage, offset; - nodesPerPage = Index.threadsNumPerPage; - offset = nodesPerPage * (pageNum - 1); - return Index.sortedThreadIDs.slice(offset, offset + nodesPerPage); - }, - buildStructure: function(threadIDs) { - var k, len1, nodes, thread, threads; - threads = Index.buildThreads(threadIDs, false, Conf['Show Replies']); - nodes = []; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - nodes.push(thread.nodes.root, $.el('hr')); - } - $.add(Index.root, nodes); - if (Index.root.parentNode) { - $.event('PostsInserted', null, Index.root); - } - Index.loaded = true; - }, - buildCatalog: function(threadIDs) { - var fn, i, n, node0; - i = 0; - n = threadIDs.length; - node0 = null; - fn = function() { - var j; - if (node0 && !node0.parentNode) { - return; - } - j = i > 0 && Index.root.parentNode ? n : i + 30; - node0 = Index.buildCatalogPart(threadIDs.slice(i, j))[0]; - i = j; - if (i < n) { - return $.queueTask(fn); - } else { - if (Index.root.parentNode) { - $.event('PostsInserted', null, Index.root); - } - return Index.loaded = true; - } - }; - fn(); - }, - buildCatalogPart: function(threadIDs) { - var k, len1, nodes, thread, threads; - threads = Index.buildThreads(threadIDs, true); - Index.buildCatalogViews(threads); - Index.sizeCatalogViews(threads); - nodes = []; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - thread.OP.setCatalogOP(true); - $.add(thread.catalogView.nodes.root, thread.OP.nodes.root); - nodes.push(thread.catalogView.nodes.root); - $.on(thread.catalogView.nodes.root, 'mouseenter', Index.cb.catalogReplies.bind(thread)); - $.on(thread.OP.nodes.root, 'mouseenter', Index.cb.hoverAdjust.bind(thread.OP.nodes)); - } - $.add(Index.root, nodes); - return nodes; - }, - clearSearch: function() { - Index.searchInput.value = ''; - Index.onSearchInput(); - return Index.searchInput.focus(); - }, - setupSearch: function() { - Index.searchInput.value = Index.search; - if (Index.search) { - return Index.searchInput.dataset.searching = 1; - } else { - return Index.searchInput.removeAttribute('data-searching'); - } - }, - onSearchInput: function() { - var search; - search = Index.searchInput.value.trim(); - if (search === Index.search) { - return; - } - Index.pushState({ - search: search, - replace: !!search === !!Index.search - }); - return Index.pageLoad(false); - }, - querySearch: function(query) { - var keywords, match, regexp; - if ((match = query.match(/^([\w+]+):\/(.*)\/(\w*)$/))) { - try { - regexp = RegExp(match[2], match[3]); - } catch (error) { - return []; - } - return Index.sortedThreadIDs.filter(function(ID) { - return regexp.test(Filter.values(match[1], Index.parsedThreads[ID]).join('\n')); - }); - } - if (!(keywords = query.toLowerCase().match(/\S+/g))) { - return; - } - return Index.sortedThreadIDs.filter(function(ID) { - return Index.searchMatch(Index.parsedThreads[ID], keywords); - }); - }, - searchMatch: function(obj, keywords) { - var file, info, k, key, keyword, l, len1, len2, ref, text; - info = obj.info, file = obj.file; - if (info.comment == null) { - info.comment = g.SITE.Build.parseComment(info.commentHTML.innerHTML); - } - text = []; - ref = ['comment', 'subject', 'name', 'tripcode']; - for (k = 0, len1 = ref.length; k < len1; k++) { - key = ref[k]; - if (key in info) { - text.push(info[key]); - } - } - if (file) { - text.push(file.name); - } - text = text.join(' ').toLowerCase(); - for (l = 0, len2 = keywords.length; l < len2; l++) { - keyword = keywords[l]; - if (-1 === text.indexOf(keyword)) { - return false; - } - } - return true; - } - }; - - return Index; - -}).call(this); - -Polyfill = (function() { - var Polyfill; - - Polyfill = { - init: function() { - var base; - this.toBlob(); - $.global(this.toBlob); - (base = Element.prototype).matches || (base.matches = Element.prototype.mozMatchesSelector || Element.prototype.webkitMatchesSelector); - }, - toBlob: function() { - if (HTMLCanvasElement.prototype.toBlob) { - return; - } - HTMLCanvasElement.prototype.toBlob = function(cb, type, encoderOptions) { - var data, i, j, l, ref, ui8a, url; - url = this.toDataURL(type, encoderOptions); - data = atob(url.slice(url.indexOf(',') + 1)); - l = data.length; - ui8a = new Uint8Array(l); - for (i = j = 0, ref = l; j < ref; i = j += 1) { - ui8a[i] = data.charCodeAt(i); - } - return cb(new Blob([ui8a], { - type: type || 'image/png' - })); - }; - } - }; - - return Polyfill; - -}).call(this); - -Settings = (function() { - var Settings, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Settings = { - init: function() { - var add, link; - link = $.el('a', { - className: 'settings-link fa fa-wrench', - textContent: 'Settings', - title: '4chan X Settings', - href: 'javascript:;' - }); - $.on(link, 'click', Settings.open); - Header.addShortcut('settings', link, 820); - add = this.addSection; - add('Main', this.main); - add('Filter', this.filter); - add('Sauce', this.sauce); - add('Advanced', this.advanced); - add('Keybinds', this.keybinds); - $.on(d, 'AddSettingsSection', Settings.addSection); - $.on(d, 'OpenSettings', function(e) { - return Settings.open(e.detail); - }); - if (g.SITE.software === 'yotsuba' && Conf['Disable Native Extension']) { - if ($.hasStorage) { - return $.global(function() { - var settings; - try { - settings = JSON.parse(localStorage.getItem('4chan-settings')) || {}; - if (settings.disableAll) { - return; - } - settings.disableAll = true; - return localStorage.setItem('4chan-settings', JSON.stringify(settings)); - } catch (error) { - return Object.defineProperty(window, 'Config', { - value: { - disableAll: true - } - }); - } - }); - } else { - return $.global(function() { - return Object.defineProperty(window, 'Config', { - value: { - disableAll: true - } - }); - }); - } - } - }, - open: function(openSection) { - var dialog, j, len, link, links, ref, section, sectionToOpen; - if (Settings.dialog) { - return; - } - $.event('CloseMenu'); - Settings.dialog = dialog = $.el('div', { - id: 'overlay' - }, {innerHTML: ""}); - $.on($('.export', dialog), 'click', Settings["export"]); - $.on($('.import', dialog), 'click', Settings["import"]); - $.on($('.reset', dialog), 'click', Settings.reset); - $.on($('input', dialog), 'change', Settings.onImport); - links = []; - ref = Settings.sections; - for (j = 0, len = ref.length; j < len; j++) { - section = ref[j]; - link = $.el('a', { - className: "tab-" + section.hyphenatedTitle, - textContent: section.title, - href: 'javascript:;' - }); - $.on(link, 'click', Settings.openSection.bind(section)); - links.push(link, $.tn(' | ')); - if (section.title === openSection) { - sectionToOpen = link; - } - } - links.pop(); - $.add($('.sections-list', dialog), links); - if (openSection !== 'none') { - (sectionToOpen ? sectionToOpen : links[0]).click(); - } - $.on($('.close', dialog), 'click', Settings.close); - $.on(window, 'beforeunload', Settings.close); - $.on(dialog, 'click', Settings.close); - $.on(dialog.firstElementChild, 'click', function(e) { - return e.stopPropagation(); - }); - $.add(d.body, dialog); - return $.event('OpenSettings', null, dialog); - }, - close: function() { - var ref; - if (!Settings.dialog) { - return; - } - if ((ref = d.activeElement) != null) { - ref.blur(); - } - $.rm(Settings.dialog); - return delete Settings.dialog; - }, - sections: [], - addSection: function(title, open) { - var hyphenatedTitle, ref; - if (typeof title !== 'string') { - ref = title.detail, title = ref.title, open = ref.open; - } - hyphenatedTitle = title.toLowerCase().replace(/\s+/g, '-'); - return Settings.sections.push({ - title: title, - hyphenatedTitle: hyphenatedTitle, - open: open - }); - }, - openSection: function() { - var section, selected; - if (selected = $('.tab-selected', Settings.dialog)) { - $.rmClass(selected, 'tab-selected'); - } - $.addClass($(".tab-" + this.hyphenatedTitle, Settings.dialog), 'tab-selected'); - section = $('section', Settings.dialog); - $.rmAll(section); - section.className = "section-" + this.hyphenatedTitle; - this.open(section, g); - section.scrollTop = 0; - return $.event('OpenSettings', null, section); - }, - warnings: { - localStorage: function(cb) { - var why; - if ($.cantSync) { - why = $.cantSet ? 'save your settings' : 'synchronize settings between tabs'; - return cb($.el('li', { - textContent: "4chan X needs local storage to " + why + ".\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: function(cb) { - return $.onExists(doc, '.adg-rects > .desktop', function(ad) { - return $.onExists(ad, 'iframe', function() { - var url; - url = Redirect.to('thread', { - boardID: 'qa', - threadID: 362590 - }); - return cb($.el('li', {innerHTML: "To protect yourself from malicious ads, you should block ads on 4chan."})); - }); - }); - } - }, - main: function(section) { - var addCheckboxes, addWarning, button, div, fs, inputs, items, key, keyFS, obj, ref, ref1, warning, warnings; - warnings = $.el('fieldset', { - hidden: true - }, {innerHTML: "Warnings
      "}); - addWarning = function(item) { - $.add($('ul', warnings), item); - return warnings.hidden = false; - }; - ref = Settings.warnings; - for (key in ref) { - warning = ref[key]; - warning(addWarning); - } - $.add(section, warnings); - items = $.dict(); - inputs = $.dict(); - addCheckboxes = function(root, obj) { - var arr, container, containers, description, div, input, level, results; - containers = [root]; - results = []; - for (key in obj) { - arr = obj[key]; - if (!(arr instanceof Array)) { - continue; - } - description = arr[1]; - div = $.el('div', {innerHTML: ": " + E(description) + ""}); - div.dataset.name = key; - input = $('input', div); - $.on(input, 'change', $.cb.checked); - $.on(input, 'change', function() { - return this.parentNode.parentNode.dataset.checked = this.checked; - }); - items[key] = Conf[key]; - inputs[key] = input; - level = arr[2] || 0; - if (containers.length <= level) { - container = $.el('div', { - className: 'suboption-list' - }); - $.add(containers[containers.length - 1].lastElementChild, container); - containers[level] = container; - } else if (containers.length > level + 1) { - containers.splice(level + 1, containers.length - (level + 1)); - } - results.push($.add(containers[level], div)); - } - return results; - }; - ref1 = Config.main; - for (keyFS in ref1) { - obj = ref1[keyFS]; - fs = $.el('fieldset', {innerHTML: "" + E(keyFS) + ""}); - addCheckboxes(fs, obj); - if (keyFS === 'Posting and Captchas') { - $.add(fs, $.el('p', {innerHTML: "For more info on captcha options and issues, see the captcha FAQ."})); - } - $.add(section, fs); - } - addCheckboxes($('div[data-name="JSON Index"] > .suboption-list', section), Config.Index); - if ($.engine !== 'gecko') { - $('div[data-name="Remember QR Size"]', section).hidden = true; - } - if ($.perProtocolSettings || location.protocol !== 'https:') { - $('div[data-name="Redirect to HTTPS"]', section).hidden = true; - } - if ($.platform !== 'crx') { - $('div[data-name="Work around CORB Bug"]', section).hidden = true; - } - $.get(items, function(items) { - var val; - for (key in items) { - val = items[key]; - inputs[key].checked = val; - inputs[key].parentNode.parentNode.dataset.checked = val; - } - }); - div = $.el('div', {innerHTML: ": Clear manually-hidden threads and posts on all boards. Reload the page to apply."}); - button = $('button', div); - $.get({ - hiddenThreads: $.dict(), - hiddenPosts: $.dict() - }, function(arg) { - var ID, board, hiddenNum, hiddenPosts, hiddenThreads, ref2, ref3, ref4, ref5, site, thread; - hiddenThreads = arg.hiddenThreads, hiddenPosts = arg.hiddenPosts; - hiddenNum = 0; - for (ID in hiddenThreads) { - site = hiddenThreads[ID]; - if (ID !== 'boards') { - ref2 = site.boards; - for (ID in ref2) { - board = ref2[ID]; - hiddenNum += Object.keys(board).length; - } - } - } - ref3 = hiddenThreads.boards; - for (ID in ref3) { - board = ref3[ID]; - hiddenNum += Object.keys(board).length; - } - for (ID in hiddenPosts) { - site = hiddenPosts[ID]; - if (ID !== 'boards') { - ref4 = site.boards; - for (ID in ref4) { - board = ref4[ID]; - for (ID in board) { - thread = board[ID]; - hiddenNum += Object.keys(thread).length; - } - } - } - } - ref5 = hiddenPosts.boards; - for (ID in ref5) { - board = ref5[ID]; - for (ID in board) { - thread = board[ID]; - hiddenNum += Object.keys(thread).length; - } - } - return button.textContent = "Hidden: " + hiddenNum; - }); - $.on(button, 'click', function() { - this.textContent = 'Hidden: 0'; - return $.get('hiddenThreads', $.dict(), function(arg) { - var boardID, hiddenThreads, ref2; - hiddenThreads = arg.hiddenThreads; - if ($.hasStorage && g.SITE.software === 'yotsuba') { - for (boardID in (ref2 = hiddenThreads['4chan.org']) != null ? ref2.boards : void 0) { - localStorage.removeItem("4chan-hide-t-" + boardID); - } - for (boardID in hiddenThreads.boards) { - localStorage.removeItem("4chan-hide-t-" + boardID); - } - } - return $["delete"](['hiddenThreads', 'hiddenPosts']); - }); - }); - return $.after($('input[name="Stubs"]', section).parentNode.parentNode, div); - }, - "export": function() { - var Conf2; - Conf2 = $.dict(); - $.extend(Conf2, Conf); - return $.get(Conf2, function(Conf2) { - delete Conf2['boardConfig']; - return Settings.downloadExport({ - version: g.VERSION, - date: Date.now(), - Conf: Conf2 - }); - }); - }, - downloadExport: function(data) { - var a, blob, p, url; - blob = new Blob([JSON.stringify(data, null, 2)], { - type: 'application/json' - }); - url = URL.createObjectURL(blob); - a = $.el('a', { - download: "4chan X v" + g.VERSION + "-" + data.date + ".json", - href: url - }); - p = $('.imp-exp-result', Settings.dialog); - $.rmAll(p); - $.add(p, a); - return a.click(); - }, - "import": function() { - return $('input[type=file]', this.parentNode).click(); - }, - onImport: function() { - var file, output, reader; - if (!(file = this.files[0])) { - return; - } - this.value = null; - output = $('.imp-exp-result'); - if (!confirm('Your current settings will be entirely overwritten, are you sure?')) { - output.textContent = 'Import aborted.'; - return; - } - reader = new FileReader(); - reader.onload = function(e) { - var err; - try { - return Settings.loadSettings($.dict.json(e.target.result), function(err) { - if (err) { - return output.textContent = 'Import failed due to an error.'; - } else if (confirm('Import successful. Reload now?')) { - return window.location.reload(); - } - }); - } catch (error) { - err = error; - output.textContent = 'Import failed due to an error.'; - return c.error(err.stack); - } - }; - return reader.readAsText(file); - }, - convertFrom: { - loadletter: function(data) { - var base, boardID, convertSettings, key, ref, ref1, threadData, threadID, threads, val; - convertSettings = function(data, map) { - var newKey, prevKey; - for (prevKey in map) { - newKey = map[prevKey]; - if (newKey) { - data.Conf[newKey] = data.Conf[prevKey]; - } - delete data.Conf[prevKey]; - } - return data; - }; - data = convertSettings(data, { - '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': '' - }); - if ('Always CDN' in data.Conf) { - data.Conf['fourchanImageHost'] = data.Conf['Always CDN'] ? 'i.4cdn.org' : ''; - delete data.Conf['Always CDN']; - } - data.Conf.sauces = data.Conf.sauces.replace(/\$\d/g, function(c) { - switch (c) { - case '$1': - return '%TURL'; - case '$2': - return '%URL'; - case '$3': - return '%MD5'; - case '$4': - return '%board'; - default: - return c; - } - }); - ref = Config.hotkeys; - for (key in ref) { - val = ref[key]; - if (key in data.Conf) { - data.Conf[key] = data.Conf[key].replace(/ctrl|alt|meta/g, function(s) { - return "" + (s[0].toUpperCase()) + s.slice(1); - }).replace(/(^|.+\+)[A-Z]$/g, function(s) { - return "Shift+" + s.slice(0, -1) + (s.slice(-1).toLowerCase()); - }); - } - } - if (data.WatchedThreads) { - data.Conf['watchedThreads'] = $.dict.clone({ - '4chan.org': { - boards: {} - } - }); - ref1 = data.WatchedThreads; - for (boardID in ref1) { - threads = ref1[boardID]; - for (threadID in threads) { - threadData = threads[threadID]; - ((base = data.Conf['watchedThreads']['4chan.org'].boards)[boardID] || (base[boardID] = $.dict()))[threadID] = { - excerpt: threadData.textContent - }; - } - } - } - return data; - } - }, - upgrade: function(data, version) { - var addCSS, addSauces, boardID, boards, changes, compareString, corrupted, db, hostname, j, k, key, l, lastChecked, len, len1, len2, len3, line, list, m, name, record, ref, ref1, ref10, ref11, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, rice, set, setD, siteProperties, software, type, uids, val, val2, value; - changes = $.dict(); - set = function(key, value) { - return data[key] = changes[key] = value; - }; - setD = function(key, value) { - if (data[key] == null) { - return set(key, value); - } - }; - addSauces = function(sauces) { - if (data['sauces'] != null) { - sauces = sauces.filter(function(s) { - return data['sauces'].indexOf(s.match(/[^#;\s]+|$/)[0]) < 0; - }); - if (sauces.length) { - return set('sauces', data['sauces'] + '\n\n' + sauces.join('\n')); - } - } - }; - addCSS = function(css) { - if (data['usercss'] == null) { - set('usercss', Config['usercss']); - } - if (data['usercss'].indexOf(css) < 0) { - return set('usercss', css + '\n\n' + data['usercss']); - } - }; - if ((corrupted = version[0] === '"')) { - try { - version = JSON.parse(version); - } catch (error) {} - } - compareString = version.replace(/\d+/g, function(x) { - return ('0000' + x).slice(-5); - }); - if (compareString < '00001.00013.00014.00008') { - for (key in data) { - val = data[key]; - if (!(typeof val === 'string' && typeof Conf[key] !== 'string' && (key !== 'Index Sort' && key !== 'Last Long Reply Thresholds 0' && key !== 'Last Long Reply Thresholds 1'))) { - continue; - } - corrupted = true; - break; - } - } - if (corrupted) { - for (key in data) { - val = data[key]; - if (typeof val === 'string') { - try { - val2 = JSON.parse(val); - set(key, val2); - } catch (error) {} - } - } - } - if (compareString < '00001.00011.00008.00000') { - if (data['Fixed Thread Watcher'] == null) { - set('Fixed Thread Watcher', (ref = data['Toggleable Thread Watcher']) != null ? ref : true); - } - if (data['Exempt Archives from Encryption'] == null) { - set('Exempt Archives from Encryption', (ref1 = data['Except Archives from Encryption']) != null ? ref1 : false); - } - } - if (compareString < '00001.00011.00010.00001') { - if (data['selectedArchives'] != null) { - uids = { - "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 - }; - ref2 = data['selectedArchives']; - for (boardID in ref2) { - record = ref2[boardID]; - for (type in record) { - name = record[type]; - if ($.hasOwn(uids, name)) { - record[type] = uids[name]; - } - } - } - set('selectedArchives', data['selectedArchives']); - } - } - if (compareString < '00001.00011.00016.00000') { - if ((rice = Config['usercss'].match(/\/\* Board title rice \*\/(?:\n.+)*/)[0])) { - if ((data['usercss'] != null) && data['usercss'].indexOf(rice) < 0) { - set('usercss', rice + '\n\n' + data['usercss']); - } - } - } - if (compareString < '00001.00011.00017.00000') { - ref3 = ['Persistent QR', 'Color User IDs', 'Fappe Tyme', 'Werk Tyme', 'Highlight Posts Quoting You', 'Highlight Own Posts']; - for (j = 0, len = ref3.length; j < len; j++) { - key = ref3[j]; - if (data[key] == null) { - set(key, key === 'Persistent QR'); - } - } - } - if (compareString < '00001.00011.00017.00006') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/iqdb\.org\//mg, '$1//iqdb.org/')); - } - } - if (compareString < '00001.00011.00019.00003' && !Settings.dialog) { - $.queueTask(function() { - return Settings.warnings.ads(function(item) { - return new Notice('warning', slice.call(item.childNodes)); - }); - }); - } - if (compareString < '00001.00011.00020.00003') { - ref4 = { - 'Inline Cross-thread Quotes Only': false, - 'Pass Link': true - }; - for (key in ref4) { - value = ref4[key]; - if (data[key] == null) { - set(key, value); - } - } - } - if (compareString < '00001.00011.00021.00003') { - if (data['Remember Your Posts'] == null) { - set('Remember Your Posts', (ref5 = data['Mark Quotes of You']) != null ? ref5 : true); - } - } - if (compareString < '00001.00011.00022.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(?:IMG|URL))%3Fs\.jpg/mg, '$1')); - set('sauces', data['sauces'].replace(/^#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(?:IMG|T?URL)(?=$|;)/mg, '$&&safe=off')); - } - } - if (compareString < '00001.00011.00022.00002') { - if ((data['Use Recaptcha v1 in Reports'] == null) && data['Use Recaptcha v1'] && !data['Use Recaptcha v2 in Reports']) { - set('Use Recaptcha v1 in Reports', true); - } - } - if (compareString < '00001.00011.00024.00000') { - if ((data['JSON Navigation'] != null) && (data['JSON Index'] == null)) { - set('JSON Index', data['JSON Navigation']); - } - } - if (compareString < '00001.00011.00026.00000') { - if ((data['Oekaki Links'] != null) && (data['Edit Link'] == null)) { - set('Edit Link', data['Oekaki Links']); - } - if (data['Inline Cross-thread Quotes Only'] == null) { - set('Inline Cross-thread Quotes Only', true); - } - } - if (compareString < '00001.00011.00030.00000') { - if (data['Quote Threading'] && (data['Thread Quotes'] == null)) { - set('Thread Quotes', true); - } - } - if (compareString < '00001.00011.00032.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/3d\.iqdb\.org\//mg, '$1//3d.iqdb.org/')); - } - addSauces(['#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']); - } - if (compareString < '00001.00011.00035.00000') { - addSauces(['https://whatanime.ga/?auto&url=%IMG;text:wait']); - } - if (compareString < '00001.00012.00000.00000') { - if (data['Exempt Archives from Encryption'] == null) { - set('Exempt Archives from Encryption', false); - } - if (data['Show New Thread Option in Threads'] == null) { - set('Show New Thread Option in Threads', false); - } - if (data['Show Name and Subject']) { - addCSS('#qr .persona .field {display: block !important;}'); - } - if (data['QR Shortcut'] === false) { - addCSS('#shortcut-qr {display: none;}'); - } - if (data['Bottom QR Link'] === false) { - addCSS('.qr-link-container-bottom {display: none;}'); - } - } - if (compareString < '00001.00012.00000.00006') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)https:\/\/(?:desustorage|cuckchan)\.org\//mg, '$1https://desuarchive.org/')); - } - } - if (compareString < '00001.00012.00001.00000') { - if ((data['Persistent Thread Watcher'] == null) && (data['Toggleable Thread Watcher'] != null)) { - set('Persistent Thread Watcher', !data['Toggleable Thread Watcher']); - } - } - if (compareString < '00001.00012.00003.00000') { - ref6 = ['Image Hover in Catalog', 'Auto Watch', 'Auto Watch Reply']; - for (k = 0, len1 = ref6.length; k < len1; k++) { - key = ref6[k]; - setD(key, false); - } - } - if (compareString < '00001.00013.00001.00002') { - addSauces(['#//www.bing.com/images/search?q=imgurl:%IMG&view=detailv2&iss=sbi#enterInsights']); - } - if (compareString < '00001.00013.00005.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/regex\.info\/exif\.cgi/mg, '$1http://exif.regex.info/exif.cgi')); - } - addSauces(Config['sauces'].match(/# Known filename formats:(?:\n.+)*|$/)[0].split('\n')); - } - if (compareString < '00001.00013.00007.00002') { - setD('Require OP Quote Link', true); - } - if (compareString < '00001.00013.00008.00000') { - setD('Download Link', true); - } - if (compareString < '00001.00013.00009.00003') { - if (data['jsWhitelist'] != null) { - list = data['jsWhitelist'].split('\n'); - if (indexOf.call(list, 'https://cdnjs.cloudflare.com') < 0 && indexOf.call(list, 'https://cdn.mathjax.org') >= 0) { - set('jsWhitelist', data['jsWhitelist'] + '\n\nhttps://cdnjs.cloudflare.com'); - } - } - } - if (compareString < '00001.00014.00000.00006') { - if (data['siteSoftware'] != null) { - set('siteSoftware', data['siteSoftware'] + '\n4cdn.org yotsuba'); - } - } - if (compareString < '00001.00014.00003.00002') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)https:\/\/whatanime\.ga\//mg, '$1https://trace.moe/')); - } - } - if (compareString < '00001.00014.00004.00004') { - if ((data['siteSoftware'] != null) && !/^4channel\.org yotsuba$/m.test(data['siteSoftware'])) { - set('siteSoftware', data['siteSoftware'] + '\n4channel.org yotsuba'); - } - } - if (compareString < '00001.00014.00005.00000') { - ref7 = DataBoard.keys; - for (l = 0, len2 = ref7.length; l < len2; l++) { - db = ref7[l]; - if ((ref8 = data[db]) != null ? ref8.boards : void 0) { - ref9 = data[db], boards = ref9.boards, lastChecked = ref9.lastChecked; - data[db]['4chan.org'] = { - boards: boards, - lastChecked: lastChecked - }; - delete data[db].boards; - delete data[db].lastChecked; - set(db, data[db]); - } - } - if ((data['siteSoftware'] != null) && (data['siteProperties'] == null)) { - siteProperties = $.dict(); - ref10 = data['siteSoftware'].split('\n'); - for (m = 0, len3 = ref10.length; m < len3; m++) { - line = ref10[m]; - ref11 = line.split(' '), hostname = ref11[0], software = ref11[1]; - siteProperties[hostname] = { - software: software - }; - } - set('siteProperties', siteProperties); - } - } - if (compareString < '00001.00014.00006.00006') { - if (data['sauces'] != null) { - set('sauces', data['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}-/')); - } - } - if (compareString < '00001.00014.00008.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/https:\/\/www\.yandex\.com\/images\/search/g, 'https://yandex.com/images/search')); - } - } - if (compareString < '00001.00014.00009.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)(?:http:)?\/\/(www\.pixiv\.net|www\.deviantart\.com|imgur\.com|flickr\.com)\//mg, '$1https://$2/')); - set('sauces', data['sauces'].replace(/https:\/\/yandex\.com\/images\/search\?rpt=imageview&img_url=%IMG/g, 'https://yandex.com/images/search?rpt=imageview&url=%IMG')); - } - } - if (compareString < '00001.00014.00009.00001') { - if ((data['Use Faster Image Host'] != null) && (data['fourchanImageHost'] == null)) { - set('fourchanImageHost', (data['Use Faster Image Host'] ? 'i.4cdn.org' : '')); - } - } - if (compareString < '00001.00014.00010.00001') { - if (data['Filter in Native Catalog'] == null) { - set('Filter in Native Catalog', false); - } - } - if (compareString < '00001.00014.00012.00008') { - if (data['boardnav'] == null) { - set('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\",\"https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions\"]"); - } - } - if (compareString < '00001.00014.00016.00001') { - if (data['archiveLists'] != null) { - set('archiveLists', data['archiveLists'].replace('https://mayhemydg.github.io/archives.json/archives.json', 'https://nstepien.github.io/archives.json/archives.json')); - } - } - if (compareString < '00001.00014.00016.00007') { - if (data['sauces'] != null) { - set('sauces', data['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')); - } - } - if (compareString < '00001.00014.00017.00002') { - if (data['jsWhitelist'] != null) { - set('jsWhitelist', data['jsWhitelist'] + '\n\nhttps://hcaptcha.com\nhttps://*.hcaptcha.com'); - } - } - if (compareString < '00001.00014.00020.00004') { - if (data['archiveLists'] != null) { - set('archiveLists', data['archiveLists'].replace('https://nstepien.github.io/archives.json/archives.json', 'https://4chenz.github.io/archives.json/archives.json')); - } - } - if (compareString < '00001.00014.00022.00003') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(IMG|T?URL)&safe=off(?=$|;)/mg, 'https://www.google.com/searchbyimage?sbisrc=4chanx&image_url=%$1&safe=off')); - if (compareString === '00001.00014.00022.00002' && !/\bsbisrc=/.test(data['sauces'])) { - set('sauces', data['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')); - } - } - addSauces(['#https://lens.google.com/uploadbyurl?url=%IMG;text:lens']); - } - return changes; - }, - loadSettings: function(data, cb) { - if (data.version.split('.')[0] === '2') { - data = Settings.convertFrom.loadletter(data); - } else if (data.version !== g.VERSION) { - Settings.upgrade(data.Conf, data.version); - } - return $.clear(function(err) { - if (err) { - return cb(err); - } - return $.set(data.Conf, cb); - }); - }, - reset: function() { - if (confirm('Your current settings will be entirely wiped, are you sure?')) { - return $.clear(function(err) { - if (err) { - return $('.imp-exp-result').textContent = 'Import failed due to an error.'; - } else if (confirm('Reset successful. Reload now?')) { - return window.location.reload(); - } - }); - } - }, - filter: function(section) { - var select; - $.extend(section, {innerHTML: "
      "}); - select = $('select', section); - $.on(select, 'change', Settings.selectFilter); - return Settings.selectFilter.call(select); - }, - selectFilter: function() { - var div, filterTypes, name, ta; - div = this.nextElementSibling; - if ((name = this.value) !== 'guide') { - if (!$.hasOwn(Config.filter, name)) { - return; - } - $.rmAll(div); - ta = $.el('textarea', { - name: name, - className: 'field', - spellcheck: false - }); - $.on(ta, 'change', $.cb.value); - $.get(name, Conf[name], function(item) { - ta.value = item[name]; - return $.add(div, ta); - }); - return; - } - filterTypes = Object.keys(Config.filter).filter(function(x) { - return x !== 'general'; - }).map(function(x, i) { - return {innerHTML: ((i) ? "," : "") + "" + E(x)}; - }); - $.extend(div, {innerHTML: "
      Filter is disabled.

      Use regular expressions, one per line.
      Lines starting with a # will be ignored.
      For example, /weeaboo/i will filter posts containing the string `weeaboo`, case-insensitive.
      MD5 and Unique ID filtering use exact string matching, not regular expressions.

        You can use these settings with each regular expression, separate them with semicolons:
      • Per boards, separate them with commas. It is global if not specified. Use sfw and nsfw to reference all worksafe or not-worksafe boards.
        For example: boards:a,jp;.
        To specify boards on a particular site, put the beginning of the domain and a slash character before the list.
        Any initial www. should not be included, and all 4chan domains are considered 4chan.org.
        For example: boards:4:a,jp,sama:a,z;.
        An asterisk can be used to specify all boards on a site.
        For example: boards:4:*;.
      • Select boards to be excluded from the filter. The syntax is the same as for the boards: option above.
        For example: exclude:vg,v;.
      • Filter OPs only along with their threads (`only`) or replies only (`no`).
        For example: op:only; or op:no;.
      • Filter only posts with files (`only`) or only posts without files (`no`).
        For example: file:only; or file:no;.
      • Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`).
        For example: stub:yes; or stub:no;.
      • Highlight instead of hiding. You can specify a class name to use with a userstyle.
        For example: highlight; or highlight:wallpaper;.
      • Highlighted OPs will have their threads put on top of the board index by default.
        For example: top:yes; or top:no;.
      • Show a desktop notification instead of hiding.
        For example: notify;.
      • Filters in the \"General\" section apply to multiple fields, by default subject,name,filename,comment.
        The fields can be specified with the type option, separated by commas.
        For example: type:" + E.cat(filterTypes) + ";.
        Types can also be combined with a + sign; this indicates the filter applies to the given fields joined by newlines.
        For example: type:filename+filesize+dimensions;.
      "}); - return $('.warning', div).hidden = Conf['Filter']; - }, - sauce: function(section) { - var ta; - $.extend(section, {innerHTML: "
      Sauce is disabled.
      These parameters will be replaced by their corresponding values in the URL and displayed text:
      • %IMG: Full image URL for GIF, JPG, and PNG; thumbnail URL for other types.
      • %URL: Full image URL.
      • %TURL: Thumbnail URL.
      • %name: Original file name.
      • %board: Current board.
      • %MD5: MD5 hash in base64.
      • %sMD5: MD5 hash in base64 using - and _.
      • %hMD5: MD5 hash in hexadecimal.
      • %$0: Matched regular expression within the filename.
      • %$1, %$2, %$3, ... : Subexpressions within the matched regular expression.
      • %%, %semi: Literal % and ;.
      Lines starting with a # will be ignored.
      You can specify a display text by appending ;text:[text] to the URL.
      You can specify the applicable boards/sites by appending ;boards:[board1],[board2]. See the Filter guide for details.
      You can specify the applicable file types by appending ;types:[extension1],[extension2].
      You can specify a regular expression the filename must match by appending ;regexp:[regular expression].
      "}); - $('.warning', section).hidden = Conf['Sauce']; - ta = $('textarea', section); - $.get('sauces', Conf['sauces'], function(item) { - ta.value = item['sauces']; - return ta.hidden = false; - }); - return $.on(ta, 'change', $.cb.value); - }, - advanced: function(section) { - var applyCSS, boardSelect, customCSS, event, input, inputs, interval, items, itemsArchive, j, k, l, len, len1, len2, len3, listImageHost, m, name, ref, ref1, ref2, ref3, ref4, table, textContent, updateArchives, warning; - $.extend(section, {innerHTML: "
      Archives
      404 Redirect is disabled.
      Thread redirectionPost fetchingFile redirection

      Archive Lists: Each line below should be an archive list in this format or a URL to load an archive list from.
      Archive properties can be overriden by another item with the same uid (or if absent, its name).
      Last updated:
      External Catalog
      External Catalog is disabled. This will be used only as a fallback.
      URLs of external catalog sites, where %board is to be replaced by the board name.
      Each URL should be followed by ;boards: and optionally ;exclude: and a list of supported/excluded boards in the format explained in the Filter guide.
      Override 4chan Image Host
      Change 4chan image links to this domain. Leave blank for no change.
      Captcha Language
      Choose from list of language codes. Leave blank to autoselect.
      Custom Board Navigation
      New lines will be converted into spaces.

      In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
      Board link: g
      Archive link: g-archive
      Internal archive link: g-expired
      Title link: g-title
      Board link (Replace with title when on that board): g-replace
      Full text link: g-full
      Custom text link: g-text:"Install Gentoo"
      Index-only link: g-index
      Catalog-only link: g-catalog
      Index mode: g-mode:"infinite scrolling"
      Index sort: g-sort:"creation date rev"
      External link: external-text:"Google","http://www.google.com"
      Open in new tab: g-nt
      Combinations are possible: g-index-text:"Technology Index"
      Full board list toggle: toggle-all

      [ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:"Piracy"]
      will give you
      [ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
      if you are on /g/.
      Time Formatting is disabled.
      :
      Day: %a, %A, %d, %e
      Month: %m, %b, %B
      Year: %y, %Y
      Hour: %k, %H, %l, %I, %p, %P
      Minute: %M
      Second: %S
      Literal %: %%
      Quote Backlinks formatting is disabled.
      :
      Default pasted content filename
      .png
      File Info Formatting is disabled.
      :
      Link: %l (truncated), %L (untruncated), %T (4chan filename)
      Filename: %n (truncated), %N (untruncated), %t (4chan filename)
      Download button: %d
      Quick filter MD5: %f
      Spoiler indicator: %p
      Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
      Resolution: %r (Displays 'PDF' for PDF files)
      Tag: %g
      Literal %: %%
      Quick Reply Personas

      One item per line.
      Items will be added in the relevant input's auto-completion list.
      Password items will always be used, since there is no password input.
      Lines starting with a # will be ignored.

        You can use these settings with each item, separate them with semicolons:
      • Possible items are: name, options (or equivalently email), subject and password.
      • Wrap values of items with quotes, like this: options:"sage".
      • Force values as defaults with the always keyword, for example: options:"sage";always.
      • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
      Unread Favicon is disabled.
      Thread Updater is disabled.
      Interval: seconds
      Custom Cooldown Time
      Seconds:
      For more information about customizing 4chan X's CSS, see the styling guide.
      Javascript Whitelist
      Sources from which Javascript is allowed to be loaded by Content Security Policy.
      Lines starting with a # will be ignored.
      Known Banners
      List of known banners, used for click-to-change feature.
      "}); - ref = $$('.warning', section); - for (j = 0, len = ref.length; j < len; j++) { - warning = ref[j]; - warning.hidden = Conf[warning.dataset.feature]; - } - inputs = $.dict(); - ref1 = $$('[name]', section); - for (k = 0, len1 = ref1.length; k < len1; k++) { - input = ref1[k]; - inputs[input.name] = input; - } - $.on(inputs['archiveLists'], 'change', function() { - $.set('lastarchivecheck', 0); - Conf['lastarchivecheck'] = 0; - return $.id('lastarchivecheck').textContent = 'never'; - }); - items = $.dict(); - for (name in inputs) { - input = inputs[name]; - if (!(name !== 'Interval' && name !== 'Custom CSS')) { - continue; - } - items[name] = Conf[name]; - event = (input.nodeName === 'SELECT' || ((ref2 = input.type) === 'checkbox' || ref2 === 'radio') || (input.nodeName === 'TEXTAREA' && !(name in Settings))) ? 'change' : 'input'; - $.on(input, event, $.cb[input.type === 'checkbox' ? 'checked' : 'value']); - if (name in Settings) { - $.on(input, event, Settings[name]); - } - } - $.get(items, function(items) { - var key, val; - for (key in items) { - val = items[key]; - input = inputs[key]; - input[input.type === 'checkbox' ? 'checked' : 'value'] = val; - input.hidden = false; - if (key in Settings) { - Settings[key].call(input); - } - } - }); - listImageHost = $.id('list-fourchanImageHost'); - ref3 = ImageHost.suggestions; - for (l = 0, len2 = ref3.length; l < len2; l++) { - textContent = ref3[l]; - $.add(listImageHost, $.el('option', { - textContent: textContent - })); - } - interval = inputs['Interval']; - customCSS = inputs['Custom CSS']; - applyCSS = $('#apply-css', section); - interval.value = Conf['Interval']; - customCSS.checked = Conf['Custom CSS']; - inputs['usercss'].disabled = !Conf['Custom CSS']; - applyCSS.disabled = !Conf['Custom CSS']; - $.on(interval, 'change', ThreadUpdater.cb.interval); - $.on(customCSS, 'change', Settings.togglecss); - $.on(applyCSS, 'click', function() { - return CustomCSS.update(); - }); - itemsArchive = $.dict(); - ref4 = ['archives', 'selectedArchives', 'lastarchivecheck']; - for (m = 0, len3 = ref4.length; m < len3; m++) { - name = ref4[m]; - itemsArchive[name] = Conf[name]; - } - $.get(itemsArchive, function(itemsArchive) { - $.extend(Conf, itemsArchive); - Redirect.selectArchives(); - return Settings.addArchiveTable(section); - }); - boardSelect = $('#archive-board-select', section); - table = $('#archive-table', section); - updateArchives = $('#update-archives', section); - $.on(boardSelect, 'change', function() { - $('tbody > :not([hidden])', table).hidden = true; - return $("tbody > ." + this.value, table).hidden = false; - }); - return $.on(updateArchives, 'click', function() { - return Redirect.update(function() { - return Settings.addArchiveTable(section); - }); - }); - }, - addArchiveTable: function(section) { - var archBoards, archive, boardID, boardOptions, boardSelect, boards, data, files, id, item, j, k, l, len, len1, len2, len3, m, name, o, ref, ref1, ref2, ref3, ref4, row, rows, select, software, table, tbody, type, uid; - $('#lastarchivecheck', section).textContent = Conf['lastarchivecheck'] === 0 ? 'never' : new Date(Conf['lastarchivecheck']).toLocaleString(); - boardSelect = $('#archive-board-select', section); - table = $('#archive-table', section); - tbody = $('tbody', section); - $.rmAll(boardSelect); - $.rmAll(tbody); - archBoards = $.dict(); - ref = Conf['archives']; - for (j = 0, len = ref.length; j < len; j++) { - ref1 = ref[j], uid = ref1.uid, name = ref1.name, boards = ref1.boards, files = ref1.files, software = ref1.software; - if (software !== 'fuuka' && software !== 'foolfuuka') { - continue; - } - for (k = 0, len1 = boards.length; k < len1; k++) { - boardID = boards[k]; - o = archBoards[boardID] || (archBoards[boardID] = { - thread: [], - post: [], - file: [] - }); - archive = [uid != null ? uid : name, name]; - o.thread.push(archive); - if (software === 'foolfuuka') { - o.post.push(archive); - } - if (indexOf.call(files, boardID) >= 0) { - o.file.push(archive); - } - } - } - rows = []; - boardOptions = []; - ref2 = Object.keys(archBoards).sort(); - for (l = 0, len2 = ref2.length; l < len2; l++) { - boardID = ref2[l]; - row = $.el('tr', { - className: "board-" + boardID - }); - row.hidden = boardID !== g.BOARD.ID; - boardOptions.push($.el('option', { - textContent: "/" + boardID + "/", - value: "board-" + boardID, - selected: boardID === g.BOARD.ID - })); - o = archBoards[boardID]; - ref3 = ['thread', 'post', 'file']; - for (m = 0, len3 = ref3.length; m < len3; m++) { - item = ref3[m]; - $.add(row, Settings.addArchiveCell(boardID, o, item)); - } - rows.push(row); - } - if (rows.length === 0) { - boardSelect.hidden = table.hidden = true; - return; - } - boardSelect.hidden = table.hidden = false; - if (!(g.BOARD.ID in archBoards)) { - rows[0].hidden = false; - } - $.add(boardSelect, boardOptions); - $.add(tbody, rows); - ref4 = Conf['selectedArchives']; - for (boardID in ref4) { - data = ref4[boardID]; - for (type in data) { - id = data[type]; - if ((select = $("select[data-boardid='" + boardID + "'][data-type='" + type + "']", tbody))) { - select.value = JSON.stringify(id); - if (!select.value) { - select.value = select.firstChild.value; - } - } - } - } - }, - addArchiveCell: function(boardID, data, type) { - var archive, i, length, options, select, td; - length = data[type].length; - td = $.el('td', { - className: 'archive-cell' - }); - if (!length) { - td.textContent = '--'; - return td; - } - options = []; - i = 0; - while (i < length) { - archive = data[type][i++]; - options.push($.el('option', { - value: JSON.stringify(archive[0]), - textContent: archive[1] - })); - } - $.extend(td, {innerHTML: ""}); - select = td.firstElementChild; - if (!(select.disabled = length === 1)) { - select.setAttribute('data-boardid', boardID); - select.setAttribute('data-type', type); - $.on(select, 'change', Settings.saveSelectedArchive); - } - $.add(select, options); - return td; - }, - saveSelectedArchive: function() { - return $.get('selectedArchives', Conf['selectedArchives'], (function(_this) { - return function(arg) { - var name1, selectedArchives; - selectedArchives = arg.selectedArchives; - (selectedArchives[name1 = _this.dataset.boardid] || (selectedArchives[name1] = $.dict()))[_this.dataset.type] = JSON.parse(_this.value); - $.set('selectedArchives', selectedArchives); - Conf['selectedArchives'] = selectedArchives; - return Redirect.selectArchives(); - }; - })(this)); - }, - boardnav: function() { - return Header.generateBoardList(this.value); - }, - time: function() { - return this.nextElementSibling.textContent = Time.format(this.value, new Date()); - }, - timeLocale: function() { - return Settings.time.call($('[name=time]', Settings.dialog)); - }, - backlink: function() { - return this.nextElementSibling.textContent = this.value.replace(/%(?:id|%)/g, function(x) { - return { - '%id': '123456789', - '%%': '%' - }[x]; - }); - }, - fileInfo: function() { - var data; - data = { - isReply: true, - file: { - url: "//" + (ImageHost.host()) + "/g/1334437723720.jpg", - name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg', - size: '276 KB', - sizeInBytes: 276 * 1024, - dimensions: '1280x720', - isImage: true, - isVideo: false, - isSpoiler: true, - tag: 'Loop' - } - }; - return FileInfo.format(this.value, data, this.nextElementSibling); - }, - favicon: function() { - var f, i, icon, img, j, len, ref; - Favicon["switch"](); - if (g.VIEW === 'thread' && Conf['Unread Favicon']) { - Unread.update(); - } - img = this.nextElementSibling.children; - f = Favicon; - ref = [f.SFW, f.unreadSFW, f.unreadSFWY, f.NSFW, f.unreadNSFW, f.unreadNSFWY, f.dead, f.unreadDead, f.unreadDeadY]; - for (i = j = 0, len = ref.length; j < len; i = ++j) { - icon = ref[i]; - if (!img[i]) { - $.add(this.nextElementSibling, $.el('img')); - } - img[i].src = icon; - } - }, - togglecss: function() { - if ($('textarea[name=usercss]', $.x('ancestor::fieldset[1]', this)).disabled = $.id('apply-css').disabled = !this.checked) { - CustomCSS.rmStyle(); - } else { - CustomCSS.addStyle(); - } - return $.cb.checked.call(this); - }, - keybinds: function(section) { - var arr, input, inputs, items, key, ref, tbody, tr; - $.extend(section, {innerHTML: "
      Keybinds are disabled.
      Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
      Press Backspace to disable a keybind.
      ActionsKeybinds
      "}); - $('.warning', section).hidden = Conf['Keybinds']; - tbody = $('tbody', section); - items = $.dict(); - inputs = $.dict(); - ref = Config.hotkeys; - for (key in ref) { - arr = ref[key]; - tr = $.el('tr', {innerHTML: "" + E(arr[1]) + ""}); - input = $('input', tr); - input.name = key; - input.spellcheck = false; - items[key] = Conf[key]; - inputs[key] = input; - $.on(input, 'keydown', Settings.keybind); - $.add(tbody, tr); - } - return $.get(items, function(items) { - var val; - for (key in items) { - val = items[key]; - inputs[key].value = val; - } - }); - }, - keybind: function(e) { - var key; - if (e.keyCode === 9) { - return; - } - e.preventDefault(); - e.stopPropagation(); - if ((key = Keybinds.keyCode(e)) == null) { - return; - } - this.value = key; - return $.cb.value.call(this); - } - }; - - return Settings; - -}).call(this); - -Test = (function() { - return Test; - -}).call(this); - -UI = (function() { - var Menu, UI, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove, - bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - slice = [].slice; - - dialog = function(id, properties) { - var child, el, i, len, move, ref; - el = $.el('div', { - className: 'dialog', - id: id - }); - $.extend(el, properties); - el.style.cssText = Conf[id + ".position"]; - move = $('.move', el); - $.on(move, 'touchstart mousedown', dragstart); - ref = move.children; - for (i = 0, len = ref.length; i < len; i++) { - child = ref[i]; - if (!child.tagName) { - continue; - } - $.on(child, 'touchstart mousedown', function(e) { - return e.stopPropagation(); - }); - } - return el; - }; - - Menu = (function() { - var currentMenu, lastToggledButton; - - currentMenu = null; - - lastToggledButton = null; - - function Menu(type) { - this.type = type; - this.addEntry = bind(this.addEntry, this); - this.onFocus = bind(this.onFocus, this); - this.keybinds = bind(this.keybinds, this); - this.close = bind(this.close, this); - this.setPosition = bind(this.setPosition, this); - $.on(d, 'AddMenuEntry', (function(_this) { - return function(arg) { - var detail; - detail = arg.detail; - if (detail.type !== _this.type) { - return; - } - delete detail.open; - return _this.addEntry(detail); - }; - })(this)); - this.entries = []; - } - - Menu.prototype.makeMenu = function() { - var menu; - menu = $.el('div', { - className: 'dialog', - id: 'menu', - tabIndex: 0 - }); - menu.dataset.type = this.type; - $.on(menu, 'click', function(e) { - return e.stopPropagation(); - }); - $.on(menu, 'keydown', this.keybinds); - return menu; - }; - - Menu.prototype.toggle = function(e, button, data) { - var previousButton; - e.preventDefault(); - e.stopPropagation(); - if (currentMenu) { - previousButton = lastToggledButton; - currentMenu.close(); - if (previousButton === button) { - return; - } - } - if (!this.entries.length) { - return; - } - return this.open(button, data); - }; - - Menu.prototype.open = function(button, data) { - var entry, i, len, menu, ref; - menu = this.menu = this.makeMenu(); - currentMenu = this; - lastToggledButton = button; - this.entries.sort(function(first, second) { - return first.order - second.order; - }); - ref = this.entries; - for (i = 0, len = ref.length; i < len; i++) { - entry = ref[i]; - this.insertEntry(entry, menu, data); - } - $.addClass(lastToggledButton, 'active'); - $.on(d, 'click CloseMenu', this.close); - $.on(d, 'scroll', this.setPosition); - $.on(window, 'resize', this.setPosition); - $.after(button, menu); - this.setPosition(); - entry = $('.entry', menu); - this.focus(entry); - return menu.focus(); - }; - - Menu.prototype.setPosition = function() { - var bLeft, bRect, bTop, bottom, cHeight, cWidth, left, mRect, ref, ref1, right, top; - mRect = this.menu.getBoundingClientRect(); - bRect = lastToggledButton.getBoundingClientRect(); - bTop = window.scrollY + bRect.top; - bLeft = window.scrollX + bRect.left; - cHeight = doc.clientHeight; - cWidth = doc.clientWidth; - ref = bRect.top + bRect.height + mRect.height < cHeight ? [bRect.bottom + "px", ''] : ['', (cHeight - bRect.top) + "px"], top = ref[0], bottom = ref[1]; - ref1 = bRect.left + mRect.width < cWidth ? [bRect.left + "px", ''] : ['', (cWidth - bRect.right) + "px"], left = ref1[0], right = ref1[1]; - $.extend(this.menu.style, { - top: top, - right: right, - bottom: bottom, - left: left - }); - return this.menu.classList.toggle('left', right); - }; - - Menu.prototype.insertEntry = function(entry, parent, data) { - var err, i, len, ref, subEntry, submenu; - if (typeof entry.open === 'function') { - try { - if (!entry.open(data)) { - return; - } - } catch (error) { - err = error; - Main.handleErrors({ - message: "Error in building the " + this.type + " menu.", - error: err - }); - return; - } - } - $.add(parent, entry.el); - if (!entry.subEntries) { - return; - } - if (submenu = $('.submenu', entry.el)) { - $.rm(submenu); - } - submenu = $.el('div', { - className: 'dialog submenu' - }); - ref = entry.subEntries; - for (i = 0, len = ref.length; i < len; i++) { - subEntry = ref[i]; - this.insertEntry(subEntry, submenu, data); - } - $.add(entry.el, submenu); - }; - - Menu.prototype.close = function() { - $.rm(this.menu); - delete this.menu; - $.rmClass(lastToggledButton, 'active'); - currentMenu = null; - lastToggledButton = null; - $.off(d, 'click scroll CloseMenu', this.close); - $.off(d, 'scroll', this.setPosition); - return $.off(window, 'resize', this.setPosition); - }; - - Menu.prototype.findNextEntry = function(entry, direction) { - var entries; - entries = slice.call(entry.parentNode.children); - entries.sort(function(first, second) { - return first.style.order - second.style.order; - }); - return entries[entries.indexOf(entry) + direction]; - }; - - Menu.prototype.keybinds = function(e) { - var entry, next, nextPrev, subEntry, submenu; - entry = $('.focused', this.menu); - while (subEntry = $('.focused', entry)) { - entry = subEntry; - } - switch (e.keyCode) { - case 27: - lastToggledButton.focus(); - this.close(); - break; - case 13: - case 32: - entry.click(); - break; - case 38: - if (next = this.findNextEntry(entry, -1)) { - this.focus(next); - } - break; - case 40: - if (next = this.findNextEntry(entry, +1)) { - this.focus(next); - } - break; - case 39: - if ((submenu = $('.submenu', entry)) && (next = submenu.firstElementChild)) { - while (nextPrev = this.findNextEntry(next, -1)) { - next = nextPrev; - } - this.focus(next); - } - break; - case 37: - if (next = $.x('parent::*[contains(@class,"submenu")]/parent::*', entry)) { - this.focus(next); - } - break; - default: - return; - } - e.preventDefault(); - return e.stopPropagation(); - }; - - Menu.prototype.onFocus = function(e) { - e.stopPropagation(); - return this.focus(e.target); - }; - - Menu.prototype.focus = function(entry) { - var bottom, cHeight, cWidth, eRect, focused, i, left, len, ref, ref1, ref2, right, sRect, style, submenu, top; - while (focused = $.x('parent::*/child::*[contains(@class,"focused")]', entry)) { - $.rmClass(focused, 'focused'); - } - ref = $$('.focused', entry); - for (i = 0, len = ref.length; i < len; i++) { - focused = ref[i]; - $.rmClass(focused, 'focused'); - } - $.addClass(entry, 'focused'); - if (!(submenu = $('.submenu', entry))) { - return; - } - sRect = submenu.getBoundingClientRect(); - eRect = entry.getBoundingClientRect(); - cHeight = doc.clientHeight; - cWidth = doc.clientWidth; - ref1 = eRect.top + sRect.height < cHeight ? ['0px', 'auto'] : ['auto', '0px'], top = ref1[0], bottom = ref1[1]; - ref2 = eRect.right + sRect.width < cWidth - 150 ? ['100%', 'auto'] : ['auto', '100%'], left = ref2[0], right = ref2[1]; - style = submenu.style; - style.top = top; - style.bottom = bottom; - style.left = left; - return style.right = right; - }; - - Menu.prototype.addEntry = function(entry) { - this.parseEntry(entry); - return this.entries.push(entry); - }; - - Menu.prototype.parseEntry = function(entry) { - var el, i, len, subEntries, subEntry; - el = entry.el, subEntries = entry.subEntries; - $.addClass(el, 'entry'); - $.on(el, 'focus mouseover', this.onFocus); - el.style.order = entry.order || 100; - if (!subEntries) { - return; - } - $.addClass(el, 'has-submenu'); - for (i = 0, len = subEntries.length; i < len; i++) { - subEntry = subEntries[i]; - this.parseEntry(subEntry); - } - }; - - return Menu; - - })(); - - dragstart = function(e) { - var el, isTouching, o, rect, ref, screenHeight, screenWidth; - if (e.type === 'mousedown' && e.button !== 0) { - return; - } - e.preventDefault(); - if (isTouching = e.type === 'touchstart') { - e = e.changedTouches[e.changedTouches.length - 1]; - } - el = $.x('ancestor::div[contains(@class,"dialog")][1]', this); - rect = el.getBoundingClientRect(); - screenHeight = doc.clientHeight; - screenWidth = doc.clientWidth; - o = { - id: el.id, - style: el.style, - dx: e.clientX - rect.left, - dy: e.clientY - rect.top, - height: screenHeight - rect.height, - width: screenWidth - rect.width, - screenHeight: screenHeight, - screenWidth: screenWidth, - isTouching: isTouching - }; - ref = Conf['Header auto-hide'] || !Conf['Fixed Header'] ? [0, 0] : Conf['Bottom Header'] ? [0, Header.bar.getBoundingClientRect().height] : [Header.bar.getBoundingClientRect().height, 0], o.topBorder = ref[0], o.bottomBorder = ref[1]; - if (isTouching) { - o.identifier = e.identifier; - o.move = touchmove.bind(o); - o.up = touchend.bind(o); - $.on(d, 'touchmove', o.move); - return $.on(d, 'touchend touchcancel', o.up); - } else { - o.move = drag.bind(o); - o.up = dragend.bind(o); - $.on(d, 'mousemove', o.move); - return $.on(d, 'mouseup', o.up); - } - }; - - touchmove = function(e) { - var i, len, ref, touch; - ref = e.changedTouches; - for (i = 0, len = ref.length; i < len; i++) { - touch = ref[i]; - if (touch.identifier === this.identifier) { - drag.call(this, touch); - return; - } - } - }; - - drag = function(e) { - var bottom, clientX, clientY, left, right, style, top; - clientX = e.clientX, clientY = e.clientY; - left = clientX - this.dx; - left = left < 10 ? 0 : this.width - left < 10 ? '' : left / this.screenWidth * 100 + '%'; - top = clientY - this.dy; - top = top < (10 + this.topBorder) ? this.topBorder + 'px' : this.height - top < (10 + this.bottomBorder) ? '' : top / this.screenHeight * 100 + '%'; - right = left === '' ? 0 : ''; - bottom = top === '' ? this.bottomBorder + 'px' : ''; - style = this.style; - style.left = left; - style.right = right; - style.top = top; - return style.bottom = bottom; - }; - - touchend = function(e) { - var i, len, ref, touch; - ref = e.changedTouches; - for (i = 0, len = ref.length; i < len; i++) { - touch = ref[i]; - if (touch.identifier === this.identifier) { - dragend.call(this); - return; - } - } - }; - - dragend = function() { - if (this.isTouching) { - $.off(d, 'touchmove', this.move); - $.off(d, 'touchend touchcancel', this.up); - } else { - $.off(d, 'mousemove', this.move); - $.off(d, 'mouseup', this.up); - } - return $.set(this.id + ".position", this.style.cssText); - }; - - hoverstart = function(arg) { - var cb, el, endEvents, height, latestEvent, noRemove, o, rect, ref, root, width; - root = arg.root, el = arg.el, latestEvent = arg.latestEvent, endEvents = arg.endEvents, height = arg.height, width = arg.width, cb = arg.cb, noRemove = arg.noRemove; - rect = root.getBoundingClientRect(); - o = { - root: root, - el: el, - style: el.style, - isImage: (ref = el.nodeName) === 'IMG' || ref === 'VIDEO', - cb: cb, - endEvents: endEvents, - latestEvent: latestEvent, - clientHeight: doc.clientHeight, - clientWidth: doc.clientWidth, - height: height, - width: width, - noRemove: noRemove, - clientX: (rect.left + rect.right) / 2, - clientY: (rect.top + rect.bottom) / 2 - }; - o.hover = hover.bind(o); - o.hoverend = hoverend.bind(o); - o.hover(o.latestEvent); - new MutationObserver(function() { - if (el.parentNode) { - return o.hover(o.latestEvent); - } - }).observe(el, { - childList: true - }); - $.on(root, endEvents, o.hoverend); - if ($.x('ancestor::div[contains(@class,"inline")][1]', root)) { - $.on(d, 'keydown', o.hoverend); - } - $.on(root, 'mousemove', o.hover); - o.workaround = function(e) { - if (!root.contains(e.target)) { - return o.hoverend(e); - } - }; - return $.on(doc, 'mousemove', o.workaround); - }; - - hoverstart.padding = 25; - - hover = function(e) { - var clientX, clientY, height, left, marginX, ref, ref1, right, style, threshold, top, width; - this.latestEvent = e; - height = (this.height || this.el.offsetHeight) + hoverstart.padding; - width = this.width || this.el.offsetWidth; - ref = Conf['Follow Cursor'] ? e : this, clientX = ref.clientX, clientY = ref.clientY; - top = this.isImage ? Math.max(0, clientY * (this.clientHeight - height) / this.clientHeight) : Math.max(0, Math.min(this.clientHeight - height, clientY - 120)); - threshold = this.clientWidth / 2; - if (!this.isImage) { - threshold = Math.max(threshold, this.clientWidth - 400); - } - marginX = (clientX <= threshold ? clientX : this.clientWidth - clientX) + 45; - if (this.isImage) { - marginX = Math.min(marginX, this.clientWidth - width); - } - marginX += 'px'; - ref1 = clientX <= threshold ? [marginX, ''] : ['', marginX], left = ref1[0], right = ref1[1]; - style = this.style; - style.top = top + 'px'; - style.left = left; - return style.right = right; - }; - - hoverend = function(e) { - if (e.type === 'keydown' && e.keyCode !== 13 || e.target.nodeName === "TEXTAREA") { - return; - } - if (!this.noRemove) { - $.rm(this.el); - } - $.off(this.root, this.endEvents, this.hoverend); - $.off(d, 'keydown', this.hoverend); - $.off(this.root, 'mousemove', this.hover); - $.off(doc, 'mousemove', this.workaround); - if (this.cb) { - return this.cb.call(this); - } - }; - - checkbox = function(name, text, checked) { - var input, label; - if (checked == null) { - checked = Conf[name]; - } - label = $.el('label'); - input = $.el('input', { - type: 'checkbox', - name: name, - checked: checked - }); - $.add(label, [input, $.tn(" " + text)]); - return label; - }; - - UI = { - dialog: dialog, - Menu: Menu, - hover: hoverstart, - checkbox: checkbox - }; - - return UI; - -}).call(this); - -FappeTyme = (function() { - var FappeTyme; - - FappeTyme = { - init: function() { - var el, i, indicator, lc, len, ref, ref1, type; - if (!((Conf['Fappe Tyme'] || Conf['Werk Tyme']) && ((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive'))) { - return; - } - this.nodes = {}; - this.enabled = { - fappe: false, - werk: Conf['werk'] - }; - ref1 = ["Fappe", "Werk"]; - for (i = 0, len = ref1.length; i < len; i++) { - type = ref1[i]; - if (!Conf[type + " Tyme"]) { - continue; - } - lc = type.toLowerCase(); - el = UI.checkbox(lc, type + " Tyme", false); - el.title = type + " Tyme"; - this.nodes[lc] = el.firstElementChild; - if (Conf[lc]) { - this.set(lc, true); - } - $.on(this.nodes[lc], 'change', this.toggle.bind(this, lc)); - Header.menu.addEntry({ - el: el, - order: 97 - }); - indicator = $.el('span', { - className: 'indicator', - textContent: type[0], - title: type + " Tyme active" - }); - $.on(indicator, 'click', function() { - var check; - check = $.getOwn(FappeTyme.nodes, this.parentNode.id.replace('shortcut-', '')); - check.checked = !check.checked; - return $.event('change', null, check); - }); - Header.addShortcut(lc, indicator, 410); - } - if (Conf['Werk Tyme']) { - $.sync('werk', this.set.bind(this, 'werk')); - } - Callbacks.Post.push({ - name: 'Fappe Tyme', - cb: this.node - }); - return Callbacks.CatalogThread.push({ - name: 'Werk Tyme', - cb: this.catalogNode - }); - }, - node: function() { - return this.nodes.root.classList.toggle('noFile', !this.files.length); - }, - catalogNode: function() { - var file, filename; - file = this.thread.OP.files[0]; - if (!file) { - return; - } - filename = $.el('div', { - textContent: file.name, - className: 'werkTyme-filename' - }); - return $.add(this.nodes.thumb.parentNode, filename); - }, - set: function(type, enabled) { - this.enabled[type] = this.nodes[type].checked = enabled; - return $[(enabled ? 'add' : 'rm') + "Class"](doc, type + "Tyme"); - }, - toggle: function(type) { - this.set(type, !this.enabled[type]); - if (type === 'werk') { - return $.cb.checked.call(this.nodes[type]); - } - } - }; - - return FappeTyme; - -}).call(this); - -Gallery = (function() { - var Gallery; - - Gallery = { - init: function() { - var el, ref; - if (!(this.enabled = Conf['Gallery'] && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - this.delay = Conf['Slide Delay']; - el = $.el('a', { - href: 'javascript:;', - title: 'Gallery', - className: 'fa fa-picture-o', - textContent: 'Gallery' - }); - $.on(el, 'click', this.cb.toggle); - Header.addShortcut('gallery', el, 530); - return Callbacks.Post.push({ - name: 'Gallery', - cb: this.node - }); - }, - node: function() { - var file, i, len, ref, results; - ref = this.files; - results = []; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if (!file.thumb) { - continue; - } - if (Gallery.nodes) { - Gallery.generateThumb(this, file); - Gallery.nodes.total.textContent = Gallery.images.length; - } - if (!(Conf['Image Expansion'] || (g.SITE.software === 'tinyboard' && Main.jsEnabled))) { - results.push($.on(file.thumbLink, 'click', Gallery.cb.image)); - } else { - results.push(void 0); - } - } - return results; - }, - build: function(image) { - var candidate, cb, dialog, entry, file, i, j, k, key, len, len1, len2, menuButton, nodes, post, postThumb, ref, ref1, ref2, ref3, thumb, value; - cb = Gallery.cb; - if (Conf['Fullscreen Gallery']) { - $.one(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', function() { - return $.on(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', cb.close); - }); - if (typeof doc.mozRequestFullScreen === "function") { - doc.mozRequestFullScreen(); - } - if (typeof doc.webkitRequestFullScreen === "function") { - doc.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT); - } - } - Gallery.images = []; - nodes = Gallery.nodes = {}; - Gallery.fileIDs = $.dict(); - Gallery.slideshow = false; - nodes.el = dialog = $.el('div', { - id: 'a-gallery' - }); - $.extend(dialog, {innerHTML: "
      ×
      /
      "}); - ref = { - 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 (key in ref) { - value = ref[key]; - nodes[key] = $(value, dialog); - } - menuButton = $('.menu-button', dialog); - nodes.menu = new UI.Menu('gallery'); - $.on(nodes.frame, 'click', cb.blank); - if (Conf['Mouse Wheel Volume']) { - $.on(nodes.frame, 'wheel', Volume.wheel); - } - $.on(nodes.next, 'click', cb.click); - $.on(nodes.name, 'click', ImageCommon.download); - $.on($('.gal-prev', dialog), 'click', cb.prev); - $.on($('.gal-next', dialog), 'click', cb.next); - $.on($('.gal-start', dialog), 'click', cb.start); - $.on($('.gal-stop', dialog), 'click', cb.stop); - $.on($('.gal-close', dialog), 'click', cb.close); - $.on(menuButton, 'click', function(e) { - return nodes.menu.toggle(e, this, g); - }); - ref1 = Gallery.menu.createSubEntries(); - for (i = 0, len = ref1.length; i < len; i++) { - entry = ref1[i]; - entry.order = 0; - nodes.menu.addEntry(entry); - } - $.on(d, 'keydown', cb.keybinds); - if (Conf['Keybinds']) { - $.off(d, 'keydown', Keybinds.keydown); - } - $.on(window, 'resize', Gallery.cb.setHeight); - ref2 = $$(g.SITE.selectors.file.thumb); - for (j = 0, len1 = ref2.length; j < len1; j++) { - postThumb = ref2[j]; - if (!(post = Get.postFromNode(postThumb))) { - continue; - } - ref3 = post.files; - for (k = 0, len2 = ref3.length; k < len2; k++) { - file = ref3[k]; - if (!file.thumb) { - continue; - } - Gallery.generateThumb(post, file); - if (!image && Gallery.fileIDs[post.fullID + "." + file.index]) { - candidate = file.thumbLink; - if (Header.getTopOf(candidate) + candidate.getBoundingClientRect().height >= 0) { - image = candidate; - } - } - } - } - $.addClass(doc, 'gallery-open'); - $.add(d.body, dialog); - nodes.thumbs.scrollTop = 0; - nodes.current.parentElement.scrollTop = 0; - if (image) { - thumb = $("[href='" + image.href + "']", nodes.thumbs); - } - thumb || (thumb = Gallery.images[Gallery.images.length - 1]); - if (thumb) { - Gallery.open(thumb); - } - doc.style.overflow = 'hidden'; - return nodes.total.textContent = Gallery.images.length; - }, - generateThumb: function(post, file) { - var thumb, thumbImg; - if (post.isClone || post.isHidden) { - return; - } - if (!(file && file.thumb && (file.isImage || file.isVideo || Conf['PDF in Gallery']))) { - return; - } - if (Gallery.fileIDs[post.fullID + "." + file.index]) { - return; - } - Gallery.fileIDs[post.fullID + "." + file.index] = true; - thumb = $.el('a', { - className: 'gal-thumb', - href: file.url, - target: '_blank', - title: file.name - }); - thumb.dataset.id = Gallery.images.length; - thumb.dataset.post = post.fullID; - thumb.dataset.file = file.index; - thumbImg = file.thumb.cloneNode(false); - thumbImg.style.cssText = ''; - $.add(thumb, thumbImg); - $.on(thumb, 'click', Gallery.cb.open); - Gallery.images.push(thumb); - return $.add(Gallery.nodes.thumbs, thumb); - }, - load: function(thumb, errorCB) { - var elType, ext, file; - ext = thumb.href.match(/\w*$/); - elType = $.getOwn({ - 'webm': 'video', - 'mp4': 'video', - 'ogv': 'video', - 'pdf': 'iframe' - }, ext) || 'img'; - file = $.el(elType); - $.extend(file.dataset, thumb.dataset); - $.on(file, 'error', errorCB); - file.src = thumb.href; - return file; - }, - open: function(thumb) { - var el, file, i, len, link, newID, node, nodes, oldID, post, ref, ref1, sauces; - nodes = Gallery.nodes; - oldID = +nodes.current.dataset.id; - newID = +thumb.dataset.id; - if (el = Gallery.images[oldID]) { - $.rmClass(el, 'gal-highlight'); - } - $.addClass(thumb, 'gal-highlight'); - nodes.thumbs.scrollTop = thumb.offsetTop + thumb.offsetHeight / 2 - nodes.thumbs.clientHeight / 2; - if (((ref = Gallery.cache) != null ? ref.dataset.id : void 0) === '' + newID) { - file = Gallery.cache; - $.off(file, 'error', Gallery.cacheError); - $.on(file, 'error', Gallery.error); - } else { - file = Gallery.load(thumb, Gallery.error); - } - $.off(nodes.current, 'error', Gallery.error); - ImageCommon.pause(nodes.current); - $.replace(nodes.current, file); - nodes.current = file; - if (file.nodeName === 'VIDEO') { - file.loop = true; - Volume.setup(file); - if (Conf['Autoplay']) { - file.play(); - } - if (Conf['Show Controls']) { - ImageCommon.addControls(file); - } - } - doc.classList.toggle('gal-pdf', file.nodeName === 'IFRAME'); - Gallery.cb.setHeight(); - nodes.count.textContent = +thumb.dataset.id + 1; - nodes.name.download = nodes.name.textContent = thumb.title; - nodes.name.href = thumb.href; - nodes.frame.scrollTop = 0; - nodes.next.focus(); - $.rmAll(nodes.sauce); - if (Conf['Sauce'] && Sauce.links && (post = g.posts.get(file.dataset.post))) { - sauces = []; - ref1 = Sauce.links; - for (i = 0, len = ref1.length; i < len; i++) { - link = ref1[i]; - if ((node = Sauce.createSauceLink(link, post, post.files[+file.dataset.file]))) { - sauces.push($.tn(' '), node); - } - } - $.add(nodes.sauce, sauces); - } - if (Gallery.slideshow && (newID > oldID || (oldID === Gallery.images.length - 1 && newID === 0))) { - Gallery.setupTimer(); - } else { - Gallery.cb.stop(); - } - if (Conf['Scroll to Post'] && (post = g.posts.get(file.dataset.post))) { - Header.scrollTo(post.nodes.root); - } - if (isNaN(oldID) || newID === (oldID + 1) % Gallery.images.length) { - return Gallery.cache = Gallery.load(Gallery.images[(newID + 1) % Gallery.images.length], Gallery.cacheError); - } - }, - error: function() { - var file, post, ref; - if (((ref = this.error) != null ? ref.code : void 0) === MediaError.MEDIA_ERR_DECODE) { - return new Notice('error', 'Corrupt or unplayable video', 30); - } - if (ImageCommon.isFromArchive(this)) { - return; - } - post = g.posts.get(this.dataset.post); - file = post.files[+this.dataset.file]; - return ImageCommon.error(this, post, file, null, (function(_this) { - return function(url) { - if (!url) { - return; - } - Gallery.images[+_this.dataset.id].href = url; - if (Gallery.nodes.current === _this) { - return _this.src = url; - } - }; - })(this)); - }, - cacheError: function() { - return delete Gallery.cache; - }, - cleanupTimer: function() { - var current; - clearTimeout(Gallery.timeoutID); - current = Gallery.nodes.current; - $.off(current, 'canplaythrough load', Gallery.startTimer); - return $.off(current, 'ended', Gallery.cb.next); - }, - startTimer: function() { - return Gallery.timeoutID = setTimeout(Gallery.checkTimer, Gallery.delay * $.SECOND); - }, - setupTimer: function() { - var current, isVideo; - Gallery.cleanupTimer(); - current = Gallery.nodes.current; - isVideo = current.nodeName === 'VIDEO'; - if (isVideo) { - current.play(); - } - if ((isVideo ? current.readyState >= 4 : current.complete) || current.nodeName === 'IFRAME') { - return Gallery.startTimer(); - } else { - return $.on(current, (isVideo ? 'canplaythrough' : 'load'), Gallery.startTimer); - } - }, - checkTimer: function() { - var current; - current = Gallery.nodes.current; - if (current.nodeName === 'VIDEO' && !current.paused) { - $.on(current, 'ended', Gallery.cb.next); - return current.loop = false; - } else { - return Gallery.cb.next(); - } - }, - cb: { - keybinds: function(e) { - var cb, key; - if (!(key = Keybinds.keyCode(e))) { - return; - } - cb = (function() { - switch (key) { - case Conf['Close']: - case Conf['Open Gallery']: - return Gallery.cb.close; - case Conf['Next Gallery Image']: - return Gallery.cb.next; - case Conf['Advance Gallery']: - return Gallery.cb.advance; - case Conf['Previous Gallery Image']: - return Gallery.cb.prev; - case Conf['Pause']: - return Gallery.cb.pause; - case Conf['Slideshow']: - return Gallery.cb.toggleSlideshow; - case Conf['Rotate image anticlockwise']: - return Gallery.cb.rotateLeft; - case Conf['Rotate image clockwise']: - return Gallery.cb.rotateRight; - case Conf['Download Gallery Image']: - return Gallery.cb.download; - } - })(); - if (!cb) { - return; - } - e.stopPropagation(); - e.preventDefault(); - return cb(); - }, - open: function(e) { - if (e) { - e.preventDefault(); - } - if (this) { - return Gallery.open(this); - } - }, - image: function(e) { - e.preventDefault(); - e.stopPropagation(); - return Gallery.build(this); - }, - prev: function() { - return Gallery.cb.open.call(Gallery.images[+Gallery.nodes.current.dataset.id - 1] || Gallery.images[Gallery.images.length - 1]); - }, - next: function() { - return Gallery.cb.open.call(Gallery.images[+Gallery.nodes.current.dataset.id + 1] || Gallery.images[0]); - }, - click: function(e) { - if (ImageCommon.onControls(e)) { - return; - } - e.preventDefault(); - return Gallery.cb.advance(); - }, - advance: function() { - if (!Conf['Autoplay'] && Gallery.nodes.current.paused) { - return Gallery.nodes.current.play(); - } else { - return Gallery.cb.next(); - } - }, - toggle: function() { - return (Gallery.nodes ? Gallery.cb.close : Gallery.build)(); - }, - blank: function(e) { - if (e.target === this) { - return Gallery.cb.close(); - } - }, - toggleSlideshow: function() { - return Gallery.cb[Gallery.slideshow ? 'stop' : 'start'](); - }, - download: function() { - var name; - name = $('.gal-name'); - return name.click(); - }, - pause: function() { - var current; - Gallery.cb.stop(); - current = Gallery.nodes.current; - if (current.nodeName === 'VIDEO') { - return current[current.paused ? 'play' : 'pause'](); - } - }, - start: function() { - $.addClass(Gallery.nodes.buttons, 'gal-playing'); - Gallery.slideshow = true; - return Gallery.setupTimer(); - }, - stop: function() { - var current; - if (!Gallery.slideshow) { - return; - } - Gallery.cleanupTimer(); - current = Gallery.nodes.current; - if (current.nodeName === 'VIDEO') { - current.loop = true; - } - $.rmClass(Gallery.nodes.buttons, 'gal-playing'); - return Gallery.slideshow = false; - }, - rotateLeft: function() { - return Gallery.cb.rotate(270); - }, - rotateRight: function() { - return Gallery.cb.rotate(90); - }, - rotate: $.debounce(100, function(delta) { - var current; - current = Gallery.nodes.current; - if (current.nodeName === 'IFRAME') { - return; - } - current.dataRotate = ((current.dataRotate || 0) + delta) % 360; - current.style.transform = "rotate(" + current.dataRotate + "deg)"; - return Gallery.cb.setHeight(); - }), - close: function() { - $.off(Gallery.nodes.current, 'error', Gallery.error); - ImageCommon.pause(Gallery.nodes.current); - $.rm(Gallery.nodes.el); - $.rmClass(doc, 'gallery-open'); - if (Conf['Fullscreen Gallery']) { - $.off(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', Gallery.cb.close); - if (typeof d.mozCancelFullScreen === "function") { - d.mozCancelFullScreen(); - } - if (typeof d.webkitExitFullscreen === "function") { - d.webkitExitFullscreen(); - } - } - delete Gallery.nodes; - delete Gallery.fileIDs; - doc.style.overflow = ''; - $.off(d, 'keydown', Gallery.cb.keybinds); - if (Conf['Keybinds']) { - $.on(d, 'keydown', Keybinds.keydown); - } - $.off(window, 'resize', Gallery.cb.setHeight); - return clearTimeout(Gallery.timeoutID); - }, - setFitness: function() { - return (this.checked ? $.addClass : $.rmClass)(doc, "gal-" + (this.name.toLowerCase().replace(/\s+/g, '-'))); - }, - setHeight: $.debounce(100, function() { - var containerHeight, containerWidth, current, dim, frame, height, margin, minHeight, ref, ref1, ref2, ref3, style, width; - ref = Gallery.nodes, current = ref.current, frame = ref.frame; - style = current.style; - if (Conf['Stretch to Fit'] && (dim = (ref1 = g.posts.get(current.dataset.post)) != null ? ref1.files[+current.dataset.file].dimensions : void 0)) { - ref2 = dim.split('x'), width = ref2[0], height = ref2[1]; - containerWidth = frame.clientWidth; - containerHeight = doc.clientHeight - 25; - if ((current.dataRotate || 0) % 180 === 90) { - ref3 = [containerHeight, containerWidth], containerWidth = ref3[0], containerHeight = ref3[1]; - } - minHeight = Math.min(containerHeight, height / width * containerWidth); - style.minHeight = minHeight + 'px'; - style.minWidth = (width / height * minHeight) + 'px'; - } else { - style.minHeight = style.minWidth = ''; - } - if ((current.dataRotate || 0) % 180 === 90) { - style.maxWidth = Conf['Fit Height'] ? (doc.clientHeight - 25) + "px" : 'none'; - style.maxHeight = Conf['Fit Width'] ? frame.clientWidth + "px" : 'none'; - margin = (current.clientWidth - current.clientHeight) / 2; - return style.margin = margin + "px " + (-margin) + "px"; - } else { - return style.maxWidth = style.maxHeight = style.margin = ''; - } - }), - setDelay: function() { - return Gallery.delay = +this.value; - } - }, - menu: { - init: function() { - var el; - if (!Gallery.enabled) { - return; - } - el = $.el('span', { - textContent: 'Gallery', - className: 'gallery-link' - }); - return Header.menu.addEntry({ - el: el, - order: 105, - subEntries: Gallery.menu.createSubEntries() - }); - }, - createSubEntry: function(name) { - var input, label; - label = UI.checkbox(name, name); - input = label.firstElementChild; - if (name === 'Hide Thumbnails' || name === 'Fit Width' || name === 'Fit Height') { - $.on(input, 'change', Gallery.cb.setFitness); - } - $.event('change', null, input); - $.on(input, 'change', $.cb.checked); - if (name === 'Hide Thumbnails' || name === 'Fit Width' || name === 'Fit Height' || name === 'Stretch to Fit') { - $.on(input, 'change', Gallery.cb.setHeight); - } - return { - el: label - }; - }, - createSubEntries: function() { - var delayInput, delayLabel, item, subEntries; - subEntries = (function() { - var i, len, ref, results; - ref = ['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Stretch to Fit', 'Scroll to Post']; - results = []; - for (i = 0, len = ref.length; i < len; i++) { - item = ref[i]; - results.push(Gallery.menu.createSubEntry(item)); - } - return results; - })(); - delayLabel = $.el('label', {innerHTML: "Slide Delay: "}); - delayInput = delayLabel.firstElementChild; - delayInput.value = Gallery.delay; - $.on(delayInput, 'change', Gallery.cb.setDelay); - $.on(delayInput, 'change', $.cb.value); - subEntries.push({ - el: delayLabel - }); - return subEntries; - } - } - }; - - return Gallery; - -}).call(this); - -ImageCommon = (function() { - var ImageCommon, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - ImageCommon = { - pause: function(video) { - if (video.nodeName !== 'VIDEO') { - return; - } - video.pause(); - $.off(video, 'volumechange', Volume.change); - return video.muted = true; - }, - rewind: function(el) { - if (el.nodeName === 'VIDEO') { - if (el.readyState >= el.HAVE_METADATA) { - return el.currentTime = 0; - } - } else if (/\.gif$/.test(el.src)) { - return $.queueTask(function() { - return el.src = el.src; - }); - } - }, - pushCache: function(el) { - ImageCommon.cache = el; - return $.on(el, 'error', ImageCommon.cacheError); - }, - popCache: function() { - var el; - el = ImageCommon.cache; - $.off(el, 'error', ImageCommon.cacheError); - delete ImageCommon.cache; - return el; - }, - cacheError: function() { - if (ImageCommon.cache === this) { - return delete ImageCommon.cache; - } - }, - decodeError: function(file, fileObj) { - var message, ref; - if (((ref = file.error) != null ? ref.code : void 0) !== MediaError.MEDIA_ERR_DECODE) { - return false; - } - if (!(message = $('.warning', fileObj.thumb.parentNode))) { - message = $.el('div', { - className: 'warning' - }); - $.after(fileObj.thumb, message); - } - message.textContent = 'Error: Corrupt or unplayable video'; - return true; - }, - isFromArchive: function(file) { - return g.SITE.software === 'yotsuba' && !ImageHost.test(file.src.split('/')[2]); - }, - error: function(file, post, fileObj, delay, cb) { - var base, parseJSON, redirect, src, threadJSON, timeoutID, url; - src = fileObj.url.split('/'); - url = null; - if (g.SITE.software === 'yotsuba' && Conf['404 Redirect']) { - url = Redirect.to('file', { - boardID: post.board.ID, - filename: src[src.length - 1] - }); - } - if (!(url && Redirect.securityCheck(url))) { - url = null; - } - if ((post.isDead || fileObj.isDead) && !ImageCommon.isFromArchive(file)) { - return cb(url); - } - if (delay != null) { - timeoutID = setTimeout((function() { - return cb(url); - }), delay); - } - if (post.isDead || fileObj.isDead) { - return; - } - redirect = function() { - if (!ImageCommon.isFromArchive(file)) { - if (delay != null) { - clearTimeout(timeoutID); - } - return cb(url); - } - }; - threadJSON = typeof (base = g.SITE.urls).threadJSON === "function" ? base.threadJSON(post) : void 0; - if (!threadJSON) { - return; - } - parseJSON = function(isArchiveURL) { - var archivedThreadJSON, base1, i, len, postObj, ref, ref1; - if (this.status === 404) { - if (!isArchiveURL && (archivedThreadJSON = typeof (base1 = g.SITE.urls).archivedThreadJSON === "function" ? base1.archivedThreadJSON(post) : void 0)) { - $.ajax(archivedThreadJSON, { - onloadend: function() { - return parseJSON.call(this, true); - } - }); - } else { - post.kill(!post.isClone, fileObj.index); - } - } - if (this.status !== 200) { - return redirect(); - } - ref = this.response.posts; - for (i = 0, len = ref.length; i < len; i++) { - postObj = ref[i]; - if (postObj.no === post.ID) { - break; - } - } - if (postObj.no !== post.ID) { - post.kill(); - return redirect(); - } else if (ref1 = fileObj.docIndex, indexOf.call(g.SITE.Build.parseJSON(postObj, post.board).filesDeleted, ref1) >= 0) { - post.kill(true); - return redirect(); - } else { - return url = fileObj.url; - } - }; - return $.ajax(threadJSON, { - onloadend: function() { - return parseJSON.call(this); - } - }); - }, - addControls: function(video) { - var handler; - handler = function() { - var t; - $.off(video, 'mouseover', handler); - t = new Date().getTime(); - return $.asap((function() { - return $.engine !== 'gecko' || (video.readyState >= 3 && video.currentTime <= Math.max(0.1, video.duration - 0.5)) || new Date().getTime() >= t + 1000; - }), function() { - return video.controls = true; - }); - }; - return $.on(video, 'mouseover', handler); - }, - onControls: function(e) { - return (Conf['Show Controls'] && Conf['Click Passthrough'] && e.target.nodeName === 'VIDEO') || (e.target.controls && e.target.getBoundingClientRect().bottom - e.clientY < 35); - }, - download: function(e) { - var download, href, ref; - if (this.protocol === 'blob:') { - return true; - } - e.preventDefault(); - ref = this, href = ref.href, download = ref.download; - return CrossOrigin.file(href, function(blob) { - var a; - if (blob) { - a = $.el('a', { - href: URL.createObjectURL(blob), - download: download, - hidden: true - }); - $.add(d.body, a); - a.click(); - return $.rm(a); - } else { - return new Notice('warning', "Could not download " + href, 20); - } - }); - } - }; - - return ImageCommon; - -}).call(this); - -ImageExpand = (function() { - var ImageExpand, - slice = [].slice; - - ImageExpand = { - init: function() { - var ref; - if (!(this.enabled = Conf['Image Expansion'] && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - this.EAI = $.el('a', { - className: 'expand-all-shortcut fa fa-expand', - textContent: 'EAI', - title: 'Expand All Images', - href: 'javascript:;' - }); - $.on(this.EAI, 'click', this.cb.toggleAll); - Header.addShortcut('expand-all', this.EAI, 520); - $.on(d, 'scroll visibilitychange', this.cb.playVideos); - this.videoControls = $.el('span', { - className: 'video-controls' - }); - $.extend(this.videoControls, {innerHTML: " contract"}); - return Callbacks.Post.push({ - name: 'Image Expansion', - cb: this.node - }); - }, - node: function() { - var ref; - if (!(this.file && (this.file.isImage || this.file.isVideo))) { - return; - } - $.on(this.file.thumbLink, 'click', ImageExpand.cb.toggle); - if (this.isClone) { - if (this.file.isExpanding) { - ImageExpand.contract(this); - return ImageExpand.expand(this); - } else if (this.file.isExpanded && this.file.isVideo) { - Volume.setup(this.file.fullImage); - ImageExpand.setupVideoCB(this); - return ImageExpand.setupVideo(this, !((ref = this.origin.file.fullImage) != null ? ref.paused : void 0) || this.origin.file.wasPlaying, this.file.fullImage.controls); - } - } else if (ImageExpand.on && !this.isHidden && !this.isFetchedQuote && (Conf['Expand spoilers'] || !this.file.isSpoiler) && (Conf['Expand videos'] || !this.file.isVideo)) { - return ImageExpand.expand(this); - } - }, - cb: { - toggle: function(e) { - var file, post, ref; - if ($.modifiedClick(e)) { - return; - } - post = Get.postFromNode(this); - file = post.file; - if (file.isExpanded && ImageCommon.onControls(e)) { - return; - } - e.preventDefault(); - if (!Conf['Autoplay'] && ((ref = file.fullImage) != null ? ref.paused : void 0)) { - return file.fullImage.play(); - } else { - return ImageExpand.toggle(post); - } - }, - toggleAll: function() { - var func, threadRoot, toggle; - $.event('CloseMenu'); - threadRoot = Nav.getThread(); - toggle = function(post) { - var file; - file = post.file; - if (!(file && (file.isImage || file.isVideo) && doc.contains(post.nodes.root))) { - return; - } - if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || !Conf['Expand videos'] && file.isVideo || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0 || Conf['Expand thread only'] && g.VIEW === 'index' && !(threadRoot != null ? threadRoot.contains(file.thumb) : void 0))) { - return; - } - return $.queueTask(func, post); - }; - if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) { - ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress'; - ImageExpand.EAI.title = 'Contract All Images'; - func = ImageExpand.expand; - } else { - ImageExpand.EAI.className = 'expand-all-shortcut fa fa-expand'; - ImageExpand.EAI.title = 'Expand All Images'; - func = ImageExpand.contract; - } - return g.posts.forEach(function(post) { - var i, len, ref; - ref = [post].concat(slice.call(post.clones)); - for (i = 0, len = ref.length; i < len; i++) { - post = ref[i]; - toggle(post); - } - }); - }, - playVideos: function() { - return g.posts.forEach(function(post) { - var file, i, len, ref, video, visible; - ref = [post].concat(slice.call(post.clones)); - for (i = 0, len = ref.length; i < len; i++) { - post = ref[i]; - file = post.file; - if (!(file && file.isVideo && file.isExpanded)) { - continue; - } - video = file.fullImage; - visible = ($.hasAudio(video) && !video.muted) || Header.isNodeVisible(video); - if (visible && file.wasPlaying) { - delete file.wasPlaying; - video.play(); - } else if (!visible && !video.paused) { - file.wasPlaying = true; - video.pause(); - } - } - }); - }, - setFitness: function() { - return $[this.checked ? 'addClass' : 'rmClass'](doc, this.name.toLowerCase().replace(/\s+/g, '-')); - } - }, - toggle: function(post) { - var next; - if (!(post.file.isExpanding || post.file.isExpanded)) { - post.file.scrollIntoView = Conf['Scroll into view']; - ImageExpand.expand(post); - return; - } - ImageExpand.contract(post); - if (Conf['Advance on contract']) { - next = post.nodes.root; - while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) { - if (!($('.stub', next) || next.offsetHeight === 0)) { - break; - } - } - if (next) { - return Header.scrollTo(next); - } - } - }, - contract: function(post) { - var bottom, cb, el, eventName, file, i, len, oldHeight, ref, ref1, scrollY, top, x; - file = post.file; - if (el = file.fullImage) { - top = Header.getTopOf(el); - bottom = top + el.getBoundingClientRect().height; - oldHeight = d.body.clientHeight; - scrollY = window.scrollY; - } - $.rmClass(post.nodes.root, 'expanded-image'); - $.rmClass(file.thumb, 'expanding'); - $.rm(file.videoControls); - file.thumbLink.href = file.url; - file.thumbLink.target = '_blank'; - ref = ['isExpanding', 'isExpanded', 'videoControls', 'wasPlaying', 'scrollIntoView']; - for (i = 0, len = ref.length; i < len; i++) { - x = ref[i]; - delete file[x]; - } - if (!el) { - return; - } - if (doc.contains(el)) { - if (bottom <= 0) { - window.scrollBy(0, scrollY - window.scrollY + d.body.clientHeight - oldHeight); - } else { - Header.scrollToIfNeeded(post.nodes.root); - } - if (window.scrollX > 0) { - window.scrollBy(-window.scrollX, 0); - } - } - $.off(el, 'error', ImageExpand.error); - ImageCommon.pushCache(el); - if (file.isVideo) { - ImageCommon.pause(el); - ref1 = ImageExpand.videoCB; - for (eventName in ref1) { - cb = ref1[eventName]; - $.off(el, eventName, cb); - } - } - if (Conf['Restart when Opened']) { - ImageCommon.rewind(file.thumb); - } - delete file.fullImage; - return $.queueTask(function() { - if (file.isExpanding || file.isExpanded) { - return; - } - $.rmClass(el, 'full-image'); - if (el.id) { - return; - } - return $.rm(el); - }); - }, - expand: function(post, src) { - var el, file, isVideo, ref, thumb, thumbLink; - file = post.file; - thumb = file.thumb, thumbLink = file.thumbLink, isVideo = file.isVideo; - if (post.isHidden || file.isExpanding || file.isExpanded) { - return; - } - $.addClass(thumb, 'expanding'); - file.isExpanding = true; - if (file.fullImage) { - el = file.fullImage; - } else if (((ref = ImageCommon.cache) != null ? ref.dataset.fileID : void 0) === (post.fullID + "." + file.index)) { - el = file.fullImage = ImageCommon.popCache(); - $.on(el, 'error', ImageExpand.error); - if (Conf['Restart when Opened'] && el.id !== 'ihover') { - ImageCommon.rewind(el); - } - el.removeAttribute('id'); - } else { - el = file.fullImage = $.el((isVideo ? 'video' : 'img')); - el.dataset.fileID = post.fullID + "." + file.index; - $.on(el, 'error', ImageExpand.error); - el.src = src || file.url; - } - el.className = 'full-image'; - $.after(thumb, el); - if (isVideo) { - if (!file.videoControls) { - file.videoControls = ImageExpand.videoControls.cloneNode(true); - $.add(file.text, file.videoControls); - } - thumbLink.removeAttribute('href'); - thumbLink.removeAttribute('target'); - el.loop = true; - Volume.setup(el); - ImageExpand.setupVideoCB(post); - } - if (!isVideo) { - return $.asap((function() { - return el.naturalHeight; - }), function() { - return ImageExpand.completeExpand(post); - }); - } else if (el.readyState >= el.HAVE_METADATA) { - return ImageExpand.completeExpand(post); - } else { - return $.on(el, 'loadedmetadata', function() { - return ImageExpand.completeExpand(post); - }); - } - }, - completeExpand: function(post) { - var bottom, file, imageBottom, oldHeight, scrollY; - file = post.file; - if (!file.isExpanding) { - return; - } - bottom = Header.getTopOf(file.thumb) + file.thumb.getBoundingClientRect().height; - oldHeight = d.body.clientHeight; - scrollY = window.scrollY; - $.addClass(post.nodes.root, 'expanded-image'); - $.rmClass(file.thumb, 'expanding'); - file.isExpanded = true; - delete file.isExpanding; - if (doc.contains(post.nodes.root) && bottom <= 0) { - window.scrollBy(0, scrollY - window.scrollY + d.body.clientHeight - oldHeight); - } - if (file.scrollIntoView) { - delete file.scrollIntoView; - imageBottom = Math.min(doc.clientHeight - file.fullImage.getBoundingClientRect().bottom - 25, Header.getBottomOf(file.fullImage)); - if (imageBottom < 0) { - window.scrollBy(0, Math.min(-imageBottom, Header.getTopOf(file.fullImage))); - } - } - if (file.isVideo) { - return ImageExpand.setupVideo(post, Conf['Autoplay'], Conf['Show Controls']); - } - }, - setupVideo: function(post, playing, controls) { - var fullImage; - fullImage = post.file.fullImage; - if (!playing) { - fullImage.controls = controls; - return; - } - fullImage.controls = false; - $.asap((function() { - return doc.contains(fullImage); - }), function() { - if (!d.hidden && Header.isNodeVisible(fullImage)) { - return fullImage.play(); - } else { - return post.file.wasPlaying = true; - } - }); - if (controls) { - return ImageCommon.addControls(fullImage); - } - }, - videoCB: (function() { - var mousedown; - mousedown = false; - return { - mouseover: function() { - return mousedown = false; - }, - mousedown: function(e) { - if (e.button === 0) { - return mousedown = true; - } - }, - mouseup: function(e) { - if (e.button === 0) { - return mousedown = false; - } - }, - mouseout: function(e) { - if (((e.buttons & 1) || mousedown) && e.clientX <= this.getBoundingClientRect().left) { - return ImageExpand.toggle(Get.postFromNode(this)); - } - } - }; - })(), - setupVideoCB: function(post) { - var cb, eventName, ref; - ref = ImageExpand.videoCB; - for (eventName in ref) { - cb = ref[eventName]; - $.on(post.file.fullImage, eventName, cb); - } - if (post.file.videoControls) { - return $.on(post.file.videoControls.firstElementChild, 'click', function() { - return ImageExpand.toggle(post); - }); - } - }, - error: function() { - var post; - post = Get.postFromNode(this); - $.rm(this); - delete post.file.fullImage; - if (!(post.file.isExpanding || post.file.isExpanded)) { - return; - } - if (ImageCommon.decodeError(this, post.file)) { - return ImageExpand.contract(post); - } - if (ImageCommon.isFromArchive(this)) { - return ImageExpand.contract(post); - } - return ImageCommon.error(this, post, post.file, 10 * $.SECOND, function(URL) { - if (post.file.isExpanding || post.file.isExpanded) { - ImageExpand.contract(post); - if (URL) { - return ImageExpand.expand(post, URL); - } - } - }); - }, - menu: { - init: function() { - var conf, createSubEntry, el, name, ref, subEntries; - if (!ImageExpand.enabled) { - return; - } - el = $.el('span', { - textContent: 'Image Expansion', - className: 'image-expansion-link' - }); - createSubEntry = ImageExpand.menu.createSubEntry; - subEntries = []; - ref = Config.imageExpansion; - for (name in ref) { - conf = ref[name]; - subEntries.push(createSubEntry(name, conf[1])); - } - return Header.menu.addEntry({ - el: el, - order: 105, - subEntries: subEntries - }); - }, - createSubEntry: function(name, desc) { - var input, label; - label = UI.checkbox(name, name); - label.title = desc; - input = label.firstElementChild; - if (name === 'Fit width' || name === 'Fit height') { - $.on(input, 'change', ImageExpand.cb.setFitness); - } - $.event('change', null, input); - $.on(input, 'change', $.cb.checked); - return { - el: label - }; - } - } - }; - - return ImageExpand; - -}).call(this); - -ImageHost = (function() { - var ImageHost; - - ImageHost = { - init: function() { - var ref; - if (!((this.useFaster = /\S/.test(Conf['fourchanImageHost'])) && g.SITE.software === 'yotsuba' && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - return Callbacks.Post.push({ - name: 'Image Host Rewriting', - cb: this.node - }); - }, - suggestions: ['i.4cdn.org', 'is2.4chan.org'], - host: function() { - return Conf['fourchanImageHost'].trim() || 'i.4cdn.org'; - }, - flashHost: function() { - return 'i.4cdn.org'; - }, - thumbHost: function() { - return 'i.4cdn.org'; - }, - test: function(hostname) { - return hostname === 'i.4cdn.org' || ImageHost.regex.test(hostname); - }, - regex: /^is\d*\.4chan(?:nel)?\.org$/, - node: function() { - var host; - if (this.isClone) { - return; - } - host = ImageHost.host(); - if (this.file && ImageHost.test(this.file.url.split('/')[2]) && !/\.swf$/.test(this.file.url)) { - this.file.link.hostname = host; - if (this.file.thumbLink) { - this.file.thumbLink.hostname = host; - } - this.file.url = this.file.link.href; - } - return ImageHost.fixLinks($$('a', this.nodes.comment)); - }, - fixLinks: function(links) { - var host, i, len, link; - for (i = 0, len = links.length; i < len; i++) { - link = links[i]; - if (!(ImageHost.test(link.hostname) && !/\.swf$/.test(link.pathname))) { - continue; - } - host = ImageHost.host(); - if (link.hostname !== host) { - link.hostname = host; - } - } - } - }; - - return ImageHost; - -}).call(this); - -ImageHover = (function() { - var ImageHover; - - ImageHover = { - init: function() { - var ref; - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - if (Conf['Image Hover']) { - Callbacks.Post.push({ - name: 'Image Hover', - cb: this.node - }); - } - if (Conf['Image Hover in Catalog']) { - return Callbacks.CatalogThread.push({ - name: 'Image Hover', - cb: this.catalogNode - }); - } - }, - node: function() { - var file, i, len, ref, results; - ref = this.files; - results = []; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if ((file.isImage || file.isVideo) && file.thumb) { - results.push($.on(file.thumb, 'mouseover', ImageHover.mouseover(this, file))); - } - } - return results; - }, - catalogNode: function() { - var file; - file = this.thread.OP.files[0]; - if (!(file && (file.isImage || file.isVideo))) { - return; - } - return $.on(this.nodes.thumb, 'mouseover', ImageHover.mouseover(this.thread.OP, file)); - }, - mouseover: function(post, file) { - return function(e) { - var base, el, error, height, isVideo, maxHeight, maxWidth, ref, ref1, scale, width, x; - if (!doc.contains(this)) { - return; - } - isVideo = file.isVideo; - if (file.isExpanding || file.isExpanded || (typeof (base = g.SITE).isThumbExpanded === "function" ? base.isThumbExpanded(file) : void 0)) { - return; - } - error = ImageHover.error(post, file); - if (((ref = ImageCommon.cache) != null ? ref.dataset.fileID : void 0) === (post.fullID + "." + file.index)) { - el = ImageCommon.popCache(); - $.on(el, 'error', error); - } else { - el = $.el((isVideo ? 'video' : 'img')); - el.dataset.fileID = post.fullID + "." + file.index; - $.on(el, 'error', error); - el.src = file.url; - } - if (Conf['Restart when Opened']) { - ImageCommon.rewind(el); - ImageCommon.rewind(this); - } - el.id = 'ihover'; - $.add(Header.hover, el); - if (isVideo) { - el.loop = true; - el.controls = false; - Volume.setup(el); - if (Conf['Autoplay']) { - el.play(); - if (this.nodeName === 'VIDEO') { - this.currentTime = el.currentTime; - } - } - } - if (file.dimensions) { - ref1 = (function() { - var i, len, ref1, results; - ref1 = file.dimensions.split('x'); - results = []; - for (i = 0, len = ref1.length; i < len; i++) { - x = ref1[i]; - results.push(+x); - } - return results; - })(), width = ref1[0], height = ref1[1]; - maxWidth = doc.clientWidth; - maxHeight = doc.clientHeight - UI.hover.padding; - scale = Math.min(1, maxWidth / width, maxHeight / height); - width *= scale; - height *= scale; - el.style.maxWidth = width + "px"; - el.style.maxHeight = height + "px"; - } - return UI.hover({ - root: this, - el: el, - latestEvent: e, - endEvents: 'mouseout click', - height: height, - width: width, - noRemove: true, - cb: function() { - $.off(el, 'error', error); - ImageCommon.pushCache(el); - ImageCommon.pause(el); - $.rm(el); - return el.removeAttribute('style'); - } - }); - }; - }, - error: function(post, file) { - return function() { - if (ImageCommon.decodeError(this, file)) { - return; - } - return ImageCommon.error(this, post, file, 3 * $.SECOND, (function(_this) { - return function(URL) { - if (URL) { - return _this.src = URL + (_this.src === URL ? '?' + Date.now() : ''); - } else { - return $.rm(_this); - } - }; - })(this)); - }; - } - }; - - return ImageHover; - -}).call(this); - -ImageLoader = (function() { - var ImageLoader, - slice = [].slice; - - ImageLoader = { - init: function() { - var el, ref, ref1, replace; - if ((ref = g.VIEW) !== 'index' && ref !== 'thread' && ref !== 'archive') { - return; - } - replace = Conf['Replace JPG'] || Conf['Replace PNG'] || Conf['Replace GIF'] || Conf['Replace WEBM']; - if (!(Conf['Image Prefetching'] || replace)) { - return; - } - Callbacks.Post.push({ - name: 'Image Replace', - cb: this.node - }); - $.on(d, 'PostsInserted', function() { - if (ImageLoader.prefetchEnabled || replace) { - return g.posts.forEach(ImageLoader.prefetchAll); - } - }); - if (Conf['Replace WEBM']) { - $.on(d, 'scroll visibilitychange 4chanXInitFinished PostsInserted', this.playVideos); - } - if (!(Conf['Image Prefetching'] && ((ref1 = g.VIEW) === 'index' || ref1 === 'thread'))) { - return; - } - el = $.el('a', { - href: 'javascript:;', - title: 'Prefetch Images', - className: 'fa fa-bolt disabled', - textContent: 'Prefetch' - }); - $.on(el, 'click', this.toggle); - return Header.addShortcut('prefetch', el, 525); - }, - node: function() { - var file, i, len, ref; - if (this.isClone) { - return; - } - ref = this.files; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if (Conf['Replace WEBM'] && file.isVideo) { - ImageLoader.replaceVideo(this, file); - } - ImageLoader.prefetch(this, file); - } - }, - replaceVideo: function(post, file) { - var attr, i, len, ref, thumb, video; - thumb = file.thumb; - video = $.el('video', { - preload: 'none', - loop: true, - muted: true, - poster: thumb.src || thumb.dataset.src, - textContent: thumb.alt, - className: thumb.className - }); - video.setAttribute('muted', 'muted'); - video.dataset.md5 = thumb.dataset.md5; - ref = ['height', 'width', 'maxHeight', 'maxWidth']; - for (i = 0, len = ref.length; i < len; i++) { - attr = ref[i]; - video.style[attr] = thumb.style[attr]; - } - video.src = file.url; - $.replace(thumb, video); - file.thumb = video; - return file.videoThumb = true; - }, - prefetch: function(post, file) { - var clone, el, i, isImage, isVideo, len, ref, ref1, replace, thumb, type, url; - isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, url = file.url; - if (file.isPrefetched || !(isImage || isVideo) || post.isHidden || post.thread.isHidden) { - return; - } - if (isVideo) { - type = 'WEBM'; - } else { - type = (ref = url.match(/\.([^.]+)$/)) != null ? ref[1].toUpperCase() : void 0; - if (type === 'JPEG') { - type = 'JPG'; - } - } - replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src || thumb.dataset.src); - if (!(replace || ImageLoader.prefetchEnabled)) { - return; - } - if ($.hasClass(doc, 'catalog-mode')) { - return; - } - if (![post].concat(slice.call(post.clones)).some(function(clone) { - return doc.contains(clone.nodes.root); - })) { - return; - } - file.isPrefetched = true; - if (file.videoThumb) { - ref1 = post.clones; - for (i = 0, len = ref1.length; i < len; i++) { - clone = ref1[i]; - clone.file.thumb.preload = 'auto'; - } - thumb.preload = 'auto'; - if ($.engine === 'gecko') { - $.on(thumb, 'loadeddata', function() { - return this.removeAttribute('poster'); - }); - } - return; - } - el = $.el(isImage ? 'img' : 'video'); - if (isVideo) { - el.preload = 'auto'; - } - if (replace && isImage) { - $.on(el, 'load', function() { - var j, len1, ref2; - ref2 = post.clones; - for (j = 0, len1 = ref2.length; j < len1; j++) { - clone = ref2[j]; - clone.file.thumb.src = url; - } - return thumb.src = url; - }); - } - return el.src = url; - }, - prefetchAll: function(post) { - var file, i, len, ref; - ref = post.files; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - ImageLoader.prefetch(post, file); - } - }, - toggle: function() { - ImageLoader.prefetchEnabled = !ImageLoader.prefetchEnabled; - this.classList.toggle('disabled', !ImageLoader.prefetchEnabled); - if (ImageLoader.prefetchEnabled) { - g.posts.forEach(ImageLoader.prefetchAll); - } - }, - playVideos: function() { - var qpClone, ref; - qpClone = (ref = $.id('qp')) != null ? ref.firstElementChild : void 0; - return g.posts.forEach(function(post) { - var file, i, j, len, len1, ref1, ref2, thumb; - ref1 = [post].concat(slice.call(post.clones)); - for (i = 0, len = ref1.length; i < len; i++) { - post = ref1[i]; - ref2 = post.files; - for (j = 0, len1 = ref2.length; j < len1; j++) { - file = ref2[j]; - if (!file.videoThumb) { - continue; - } - thumb = file.thumb; - if (Header.isNodeVisible(thumb) || post.nodes.root === qpClone) { - thumb.play(); - } else { - thumb.pause(); - } - } - } - }); - } - }; - - return ImageLoader; - -}).call(this); - -Metadata = (function() { - var Metadata; - - Metadata = { - init: function() { - var ref; - if (!(Conf['WEBM Metadata'] && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - return Callbacks.Post.push({ - name: 'WEBM Metadata', - cb: this.node - }); - }, - node: function() { - var el, file, i, j, len1, ref; - ref = this.files; - for (i = j = 0, len1 = ref.length; j < len1; i = ++j) { - file = ref[i]; - if (!(/webm$/i.test(file.url))) { - continue; - } - if (this.isClone) { - el = $('.webm-title', file.text); - } else { - el = $.el('span', { - className: 'webm-title' - }); - el.dataset.index = i; - $.extend(el, {innerHTML: ""}); - $.add(file.text, [$.tn(' '), el]); - } - if (el.children.length === 1) { - $.one(el.lastElementChild, 'mouseover focus', Metadata.load); - } - } - }, - load: function() { - var index; - $.rmClass(this.parentNode, 'error'); - $.addClass(this.parentNode, 'loading'); - index = this.parentNode.dataset.index; - return CrossOrigin.binary(Get.postFromNode(this).files[+index].url, (function(_this) { - return function(data) { - var output, title; - $.rmClass(_this.parentNode, 'loading'); - if (data != null) { - title = Metadata.parse(data); - output = $.el('span', { - textContent: title || '' - }); - if (title == null) { - $.addClass(_this.parentNode, 'not-found'); - } - $.before(_this, output); - _this.parentNode.tabIndex = 0; - if (d.activeElement === _this) { - _this.parentNode.focus(); - } - return _this.tabIndex = -1; - } else { - $.addClass(_this.parentNode, 'error'); - return $.one(_this, 'click', Metadata.load); - } - }; - })(this), { - Range: 'bytes=0-9999' - }); - }, - parse: function(data) { - var element, i, readInt, size, title; - readInt = function() { - var len, n; - n = data[i++]; - len = 0; - while (n < (0x80 >> len)) { - len++; - } - n ^= 0x80 >> len; - while (len-- && i < data.length) { - n = (n << 8) ^ data[i++]; - } - return n; - }; - i = 0; - while (i < data.length) { - element = readInt(); - size = readInt(); - if (element === 0x3BA9) { - title = ''; - while (size-- && i < data.length) { - title += String.fromCharCode(data[i++]); - } - return decodeURIComponent(escape(title)); - } else if (element !== 0x8538067 && element !== 0x549A966) { - i += size; - } - } - return null; - } - }; - - return Metadata; - -}).call(this); - -RevealSpoilers = (function() { - var RevealSpoilers; - - RevealSpoilers = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Reveal Spoiler Thumbnails'])) { - return; - } - return Callbacks.Post.push({ - name: 'Reveal Spoiler Thumbnails', - cb: this.node - }); - }, - node: function() { - var file, i, len, ref, thumb; - if (this.isClone) { - return; - } - ref = this.files; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if (!(file.thumb && file.isSpoiler)) { - continue; - } - thumb = file.thumb; - thumb.removeAttribute('style'); - thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; - if (thumb.src) { - thumb.src = file.thumbURL; - } else { - thumb.dataset.src = file.thumbURL; - } - } - } - }; - - return RevealSpoilers; - -}).call(this); - -Sauce = (function() { - var Sauce, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Sauce = { - init: function() { - var j, len, link, linkData, links, ref, ref1; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Sauce'])) { - return; - } - $.addClass(doc, 'show-sauce'); - links = []; - ref1 = Conf['sauces'].split('\n'); - for (j = 0, len = ref1.length; j < len; j++) { - link = ref1[j]; - if (link[0] !== '#' && (linkData = this.parseLink(link))) { - links.push(linkData); - } - } - if (!links.length) { - return; - } - this.links = links; - this.link = $.el('a', { - target: '_blank', - className: 'sauce' - }); - return Callbacks.Post.push({ - name: 'Sauce', - cb: this.node - }); - }, - parseLink: function(link) { - var err, i, j, len, m, part, parts, ref, ref1, regexp; - if (!(link = link.trim())) { - return null; - } - parts = $.dict(); - ref = link.split(/;(?=(?:text|boards|types|regexp|sandbox):?)/); - for (i = j = 0, len = ref.length; j < len; i = ++j) { - part = ref[i]; - if (i === 0) { - parts['url'] = part; - } else { - m = part.match(/^(\w*):?(.*)$/); - parts[m[1]] = m[2]; - } - } - parts['text'] || (parts['text'] = ((ref1 = parts['url'].match(/(\w+)\.\w+\//)) != null ? ref1[1] : void 0) || '?'); - if ('boards' in parts) { - parts['boards'] = Filter.parseBoards(parts['boards']); - } - if ('regexp' in parts) { - try { - if ((regexp = parts['regexp'].match(/^\/(.*)\/(\w*)$/))) { - parts['regexp'] = RegExp(regexp[1], regexp[2]); - } else { - parts['regexp'] = RegExp(parts['regexp']); - } - } catch (error) { - err = error; - new Notice('warning', [$.tn("Invalid regexp for Sauce link:"), $.el('br'), $.tn(link), $.el('br'), $.tn(err.message)], 60); - return null; - } - } - return parts; - }, - createSauceLink: function(link, post, file) { - var a, base, ext, j, key, len, matches, missing, parts, ref; - ext = file.url.match(/[^.]*$/)[0]; - parts = $.dict(); - $.extend(parts, link); - if (!(!parts['boards'] || parts['boards'][post.siteID + "/" + post.boardID] || parts['boards'][post.siteID + "/*"])) { - return null; - } - if (!(!parts['types'] || indexOf.call(parts['types'].split(','), ext) >= 0)) { - return null; - } - if (!(!parts['regexp'] || (matches = file.name.match(parts['regexp'])))) { - return null; - } - missing = []; - ref = ['url', 'text']; - for (j = 0, len = ref.length; j < len; j++) { - key = ref[j]; - parts[key] = parts[key].replace(/%(T?URL|IMG|[sh]?MD5|board|name|%|semi|\$\d+)/g, function(orig, parameter) { - var type; - if (parameter[0] === '$') { - if (!matches) { - return orig; - } - type = matches[parameter.slice(1)] || ''; - } else { - type = Sauce.formatters[parameter](post, file, ext); - if (type == null) { - missing.push(parameter); - return ''; - } - } - if (key === 'url' && (parameter !== '%' && parameter !== 'semi')) { - if (/^javascript:/i.test(parts['url'])) { - type = JSON.stringify(type); - } - type = encodeURIComponent(type); - } - return type; - }); - } - if ((typeof (base = g.SITE).areMD5sDeferred === "function" ? base.areMD5sDeferred(post.board) : void 0) && missing.length && !missing.filter(function(x) { - return !/^.?MD5$/.test(x); - }).length) { - a = Sauce.link.cloneNode(false); - a.dataset.skip = '1'; - return a; - } - if (missing.length) { - return null; - } - a = Sauce.link.cloneNode(false); - a.href = parts['url']; - a.textContent = parts['text']; - if (/^javascript:/i.test(parts['url'])) { - a.removeAttribute('target'); - } - return a; - }, - node: function() { - var file, j, len, ref; - if (this.isClone) { - return; - } - ref = this.files; - for (j = 0, len = ref.length; j < len; j++) { - file = ref[j]; - Sauce.file(this, file); - } - }, - file: function(post, file) { - var j, len, link, node, nodes, observer, ref, skipped; - nodes = []; - skipped = []; - ref = Sauce.links; - for (j = 0, len = ref.length; j < len; j++) { - link = ref[j]; - if ((node = Sauce.createSauceLink(link, post, file))) { - nodes.push($.tn(' '), node); - if (node.dataset.skip) { - skipped.push([link, node]); - } - } - } - $.add(file.text, nodes); - if (skipped.length) { - observer = new MutationObserver(function() { - var k, len1, node2, ref1; - if (file.text.dataset.md5) { - for (k = 0, len1 = skipped.length; k < len1; k++) { - ref1 = skipped[k], link = ref1[0], node = ref1[1]; - if ((node2 = Sauce.createSauceLink(link, post, file))) { - $.replace(node, node2); - } - } - return observer.disconnect(); - } - }); - return observer.observe(file.text, { - attributes: true - }); - } - }, - formatters: { - TURL: function(post, file) { - return file.thumbURL; - }, - URL: function(post, file) { - return file.url; - }, - IMG: function(post, file, ext) { - if (ext === 'gif' || ext === 'jpg' || ext === 'jpeg' || ext === 'png') { - return file.url; - } else { - return file.thumbURL; - } - }, - MD5: function(post, file) { - return file.MD5; - }, - sMD5: function(post, file) { - var ref; - return (ref = file.MD5) != null ? ref.replace(/[+\/=]/g, function(c) { - return { - '+': '-', - '/': '_', - '=': '' - }[c]; - }) : void 0; - }, - hMD5: function(post, file) { - var c; - if (file.MD5) { - return ((function() { - var j, len, ref, results; - ref = atob(file.MD5); - results = []; - for (j = 0, len = ref.length; j < len; j++) { - c = ref[j]; - results.push(("0" + (c.charCodeAt(0).toString(16))).slice(-2)); - } - return results; - })()).join(''); - } - }, - board: function(post) { - return post.board.ID; - }, - name: function(post, file) { - return file.name; - }, - '%': function() { - return '%'; - }, - semi: function() { - return ';'; - } - } - }; - - return Sauce; - -}).call(this); - -Volume = (function() { - var Volume; - - Volume = { - init: function() { - var base, ref, unmuteEntry, volumeEntry; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && (Conf['Image Expansion'] || Conf['Image Hover'] || Conf['Image Hover in Catalog'] || Conf['Gallery']))) { - return; - } - $.sync('Allow Sound', function(x) { - var ref1; - Conf['Allow Sound'] = x; - return (ref1 = Volume.inputs) != null ? ref1.unmute.checked = x : void 0; - }); - $.sync('Default Volume', function(x) { - var ref1; - Conf['Default Volume'] = x; - return (ref1 = Volume.inputs) != null ? ref1.volume.value = x : void 0; - }); - if (Conf['Mouse Wheel Volume']) { - Callbacks.Post.push({ - name: 'Mouse Wheel Volume', - cb: this.node - }); - } - if (typeof (base = g.SITE).noAudio === "function" ? base.noAudio(g.BOARD) : void 0) { - return; - } - if (Conf['Mouse Wheel Volume']) { - Callbacks.CatalogThread.push({ - name: 'Mouse Wheel Volume', - cb: this.catalogNode - }); - } - unmuteEntry = UI.checkbox('Allow Sound', 'Allow Sound'); - unmuteEntry.title = Config.main['Images and Videos']['Allow Sound'][1]; - volumeEntry = $.el('label', { - title: 'Default volume for videos.' - }); - $.extend(volumeEntry, {innerHTML: " Volume"}); - this.inputs = { - unmute: unmuteEntry.firstElementChild, - volume: volumeEntry.firstElementChild - }; - $.on(this.inputs.unmute, 'change', $.cb.checked); - $.on(this.inputs.volume, 'change', $.cb.value); - Header.menu.addEntry({ - el: unmuteEntry, - order: 200 - }); - return Header.menu.addEntry({ - el: volumeEntry, - order: 201 - }); - }, - setup: function(video) { - video.muted = !Conf['Allow Sound']; - video.volume = Conf['Default Volume']; - return $.on(video, 'volumechange', Volume.change); - }, - change: function() { - var items, key, muted, ref, val, volume; - ref = this, muted = ref.muted, volume = ref.volume; - items = { - 'Allow Sound': !muted, - 'Default Volume': volume - }; - for (key in items) { - val = items[key]; - if (Conf[key] === val) { - delete items[key]; - } - } - $.set(items); - $.extend(Conf, items); - if (Volume.inputs) { - Volume.inputs.unmute.checked = !muted; - return Volume.inputs.volume.value = volume; - } - }, - node: function() { - var base, file, i, len, ref; - if (typeof (base = g.SITE).noAudio === "function" ? base.noAudio(this.board) : void 0) { - return; - } - ref = this.files; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if (!file.isVideo) { - continue; - } - if (file.thumb) { - $.on(file.thumb, 'wheel', Volume.wheel.bind(Header.hover)); - } - $.on($('.file-info', file.text) || file.link, 'wheel', Volume.wheel.bind(file.thumbLink)); - } - }, - catalogNode: function() { - var file; - file = this.thread.OP.files[0]; - if (!(file != null ? file.isVideo : void 0)) { - return; - } - return $.on(this.nodes.thumb, 'wheel', Volume.wheel.bind(Header.hover)); - }, - wheel: function(e) { - var el, volume; - if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { - return; - } - if (!(el = $('video:not([data-md5])', this))) { - return; - } - if (el.muted || !$.hasAudio(el)) { - return; - } - volume = el.volume + 0.1; - if (e.deltaY < 0) { - volume *= 1.1; - } - if (e.deltaY > 0) { - volume /= 1.1; - } - el.volume = $.minmax(volume - 0.1, 0, 1); - return e.preventDefault(); - } - }; - - return Volume; - -}).call(this); - -Embedding = (function() { - var Embedding, - slice = [].slice; - - Embedding = { - init: function() { - var j, len, ref, ref1, type; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Linkify'] && (Conf['Embedding'] || Conf['Link Title'] || Conf['Cover Preview']))) { - return; - } - this.types = $.dict(); - ref1 = this.ordered_types; - for (j = 0, len = ref1.length; j < len; j++) { - type = ref1[j]; - this.types[type.key] = type; - } - if (Conf['Embedding'] && g.VIEW !== 'archive') { - this.dialog = UI.dialog('embedding', {innerHTML: "
      "}); - this.media = $('#media-embed', this.dialog); - $.one(d, '4chanXInitFinished', this.ready); - $.on(d, 'IndexRefreshInternal', function() { - return g.posts.forEach(function(post) { - var embed, k, l, len1, len2, ref2, ref3; - ref2 = [post].concat(slice.call(post.clones)); - for (k = 0, len1 = ref2.length; k < len1; k++) { - post = ref2[k]; - ref3 = post.nodes.embedlinks; - for (l = 0, len2 = ref3.length; l < len2; l++) { - embed = ref3[l]; - Embedding.cb.catalogRemove.call(embed); - } - } - }); - }); - } - if (Conf['Link Title']) { - return $.on(d, '4chanXInitFinished PostsInserted', function() { - var key, ref2, ref3, service; - ref2 = Embedding.types; - for (key in ref2) { - service = ref2[key]; - if ((ref3 = service.title) != null ? ref3.batchSize : void 0) { - Embedding.flushTitles(service.title); - } - } - }); - } - }, - events: function(post) { - var data, el, i, items; - if (g.VIEW === 'archive') { - return; - } - if (Conf['Embedding']) { - i = 0; - items = post.nodes.embedlinks = $$('.embedder', post.nodes.comment); - while (el = items[i++]) { - $.on(el, 'click', Embedding.cb.click); - if ($.hasClass(el, 'embedded')) { - Embedding.cb.toggle.call(el); - } - } - } - if (Conf['Cover Preview']) { - i = 0; - items = $$('.linkify', post.nodes.comment); - while (el = items[i++]) { - if ((data = Embedding.services(el))) { - Embedding.preview(data); - } - } - } - }, - process: function(link, post) { - var data; - if (!(Conf['Embedding'] || Conf['Link Title'] || Conf['Cover Preview'])) { - return; - } - if ($.x('ancestor::pre', link)) { - return; - } - if (data = Embedding.services(link)) { - data.post = post; - if (Conf['Embedding'] && g.VIEW !== 'archive') { - Embedding.embed(data); - } - if (Conf['Link Title']) { - Embedding.title(data); - } - if (Conf['Cover Preview'] && g.VIEW !== 'archive') { - return Embedding.preview(data); - } - } - }, - services: function(link) { - var href, j, len, match, ref, type; - href = link.href; - ref = Embedding.ordered_types; - for (j = 0, len = ref.length; j < len; j++) { - type = ref[j]; - if ((match = type.regExp.exec(href))) { - return { - key: type.key, - uid: match[1], - options: match[2], - link: link - }; - } - } - }, - embed: function(data) { - var embed, href, key, link, name, options, post, ref, uid, value; - key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; - href = link.href; - $.addClass(link, key.toLowerCase()); - embed = $.el('a', { - className: 'embedder', - href: 'javascript:;' - }, {innerHTML: "(unembed)"}); - ref = { - key: key, - uid: uid, - options: options, - href: href - }; - for (name in ref) { - value = ref[name]; - embed.dataset[name] = value; - } - $.on(embed, 'click', Embedding.cb.click); - $.after(link, [$.tn(' '), embed]); - post.nodes.embedlinks.push(embed); - if (Conf['Auto-embed'] && !Conf['Floating Embeds'] && !post.isFetchedQuote) { - if ($.hasClass(doc, 'catalog-mode')) { - return $.addClass(embed, 'embed-removed'); - } else { - return Embedding.cb.toggle.call(embed); - } - } - }, - ready: function() { - if (!Main.isThisPageLegit()) { - return; - } - $.addClass(Embedding.dialog, 'empty'); - $.on($('.close', Embedding.dialog), 'click', Embedding.closeFloat); - $.on($('.move', Embedding.dialog), 'mousedown', Embedding.dragEmbed); - $.on($('.jump', Embedding.dialog), 'click', function() { - if (doc.contains(Embedding.lastEmbed)) { - return Header.scrollTo(Embedding.lastEmbed); - } - }); - return $.add(d.body, Embedding.dialog); - }, - closeFloat: function() { - delete Embedding.lastEmbed; - $.addClass(Embedding.dialog, 'empty'); - return $.replace(Embedding.media.firstChild, $.el('div')); - }, - dragEmbed: function() { - var style; - style = Embedding.media.style; - if (Embedding.dragEmbed.mouseup) { - $.off(d, 'mouseup', Embedding.dragEmbed); - Embedding.dragEmbed.mouseup = false; - style.pointerEvents = ''; - return; - } - $.on(d, 'mouseup', Embedding.dragEmbed); - Embedding.dragEmbed.mouseup = true; - return style.pointerEvents = 'none'; - }, - title: function(data) { - var key, link, options, post, service, uid; - key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; - if (!(service = Embedding.types[key].title)) { - return; - } - $.addClass(link, key.toLowerCase()); - if (service.batchSize) { - (service.queue || (service.queue = [])).push(data); - if (service.queue.length >= service.batchSize) { - return Embedding.flushTitles(service); - } - } else { - return CrossOrigin.cache(service.api(uid), (function() { - return Embedding.cb.title(this, data); - })); - } - }, - flushTitles: function(service) { - var cb, data, queue; - queue = service.queue; - if (!(queue != null ? queue.length : void 0)) { - return; - } - service.queue = []; - cb = function() { - var data, j, len; - for (j = 0, len = queue.length; j < len; j++) { - data = queue[j]; - Embedding.cb.title(this, data); - } - }; - return CrossOrigin.cache(service.api((function() { - var j, len, results; - results = []; - for (j = 0, len = queue.length; j < len; j++) { - data = queue[j]; - results.push(data.uid); - } - return results; - })()), cb); - }, - preview: function(data) { - var key, link, service, uid; - key = data.key, uid = data.uid, link = data.link; - if (!(service = Embedding.types[key].preview)) { - return; - } - return $.on(link, 'mouseover', function(e) { - var el, height, src; - src = service.url(uid); - height = service.height; - el = $.el('img', { - src: src, - id: 'ihover' - }); - $.add(Header.hover, el); - return UI.hover({ - root: link, - el: el, - latestEvent: e, - endEvents: 'mouseout click', - height: height - }); - }); - }, - cb: { - click: function(e) { - var div; - e.preventDefault(); - if (!$.hasClass(this, 'embedded') && (Conf['Floating Embeds'] || $.hasClass(doc, 'catalog-mode'))) { - if (!(div = Embedding.media.firstChild)) { - return; - } - $.replace(div, Embedding.cb.embed(this)); - Embedding.lastEmbed = Get.postFromNode(this).nodes.root; - return $.rmClass(Embedding.dialog, 'empty'); - } else { - return Embedding.cb.toggle.call(this); - } - }, - toggle: function() { - if ($.hasClass(this, "embedded")) { - $.rm(this.nextElementSibling); - } else { - $.after(this, Embedding.cb.embed(this)); - } - return $.toggleClass(this, 'embedded'); - }, - embed: function(a) { - var container, el, type; - container = $.el('div', { - className: 'media-embed' - }); - $.add(container, el = (type = Embedding.types[a.dataset.key]).el(a)); - el.style.cssText = type.style != null ? type.style : 'border: none; width: 640px; height: 360px;'; - return container; - }, - catalogRemove: function() { - var isCatalog; - isCatalog = $.hasClass(doc, 'catalog-mode'); - if ((isCatalog && $.hasClass(this, 'embedded')) || (!isCatalog && $.hasClass(this, 'embed-removed'))) { - Embedding.cb.toggle.call(this); - return $.toggleClass(this, 'embed-removed'); - } - }, - title: function(req, data) { - var base1, j, k, key, len, len1, link, link2, options, post, post2, ref, ref1, service, status, text, uid; - key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; - service = Embedding.types[key].title; - status = req.status; - if ((status === 200 || status === 304) && service.status) { - status = service.status(req.response)[0]; - } - if (!status) { - return; - } - text = "[" + key + "] " + ((function() { - switch (status) { - case 200: - case 304: - text = service.text(req.response, uid); - if (typeof text === 'string') { - return text; - } else { - return text = link.textContent; - } - break; - case 404: - return "Not Found"; - case 403: - case 401: - return "Forbidden or Private"; - default: - return status + "'d"; - } - })()); - link.dataset.original = link.textContent; - link.textContent = text; - ref = post.clones; - for (j = 0, len = ref.length; j < len; j++) { - post2 = ref[j]; - ref1 = $$('a.linkify', post2.nodes.comment); - for (k = 0, len1 = ref1.length; k < len1; k++) { - link2 = ref1[k]; - if (!(link2.href === link.href)) { - continue; - } - if ((base1 = link2.dataset).original == null) { - base1.original = link2.textContent; - } - link2.textContent = text; - } - } - } - }, - ordered_types: [ - { - key: 'audio', - regExp: /^[^?#]+\.(?:mp3|m4a|oga|wav|flac)(?:[?#]|$)/i, - style: '', - el: function(a) { - return $.el('audio', { - controls: true, - preload: 'auto', - src: a.dataset.href - }); - } - }, { - key: 'image', - regExp: /^[^?#]+\.(?:gif|png|jpg|jpeg|bmp|webp)(?::\w+)?(?:[?#]|$)/i, - style: '', - el: function(a) { - return $.el('div', {innerHTML: ""}); - } - }, { - key: 'video', - regExp: /^[^?#]+\.(?:og[gv]|webm|mp4)(?:[?#]|$)/i, - style: 'max-width: 80vw; max-height: 80vh;', - el: function(a) { - var el; - el = $.el('video', { - hidden: true, - controls: true, - preload: 'auto', - src: a.dataset.href, - loop: ImageHost.test(a.dataset.href.split('/')[2]) - }); - $.on(el, 'loadedmetadata', function() { - if (el.videoHeight === 0 && el.parentNode) { - return $.replace(el, Embedding.types.audio.el(a)); - } else { - return el.hidden = false; - } - }); - return el; - } - }, { - key: 'PeerTube', - regExp: /^(\w+:\/\/[^\/]+\/videos\/watch\/\w{8}-\w{4}-\w{4}-\w{4}-\w{12})(.*)/, - el: function(a) { - var el, options, start; - options = (start = a.dataset.options.match(/[?&](start=\w+)/)) ? "?" + start[1] : ''; - el = $.el('iframe', { - src: a.dataset.uid.replace('/videos/watch/', '/videos/embed/') + options - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'BitChute', - regExp: /^\w+:\/\/(?:www\.)?bitchute\.com\/video\/([\w\-]+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://www.bitchute.com/embed/" + a.dataset.uid + "/" - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Clyp', - regExp: /^\w+:\/\/(?:www\.)?clyp\.it\/(\w{8})/, - style: 'border: 0; width: 640px; height: 160px;', - el: function(a) { - return $.el('iframe', { - src: "https://clyp.it/" + a.dataset.uid + "/widget" - }); - }, - title: { - api: function(uid) { - return "https://api.clyp.it/oembed?url=https://clyp.it/" + uid; - }, - text: function(_) { - return _.title; - } - } - }, { - key: 'Dailymotion', - regExp: /^\w+:\/\/(?:(?:www\.)?dailymotion\.com\/(?:embed\/)?video|dai\.ly)\/([A-Za-z0-9]+)[^?]*(.*)/, - el: function(a) { - var el, options, start; - options = (start = a.dataset.options.match(/[?&](start=\d+)/)) ? "?" + start[1] : ''; - el = $.el('iframe', { - src: "//www.dailymotion.com/embed/video/" + a.dataset.uid + options - }); - el.setAttribute("allowfullscreen", "true"); - return el; - }, - title: { - api: function(uid) { - return "https://api.dailymotion.com/video/" + uid; - }, - text: function(_) { - return _.title; - } - }, - preview: { - url: function(uid) { - return "https://www.dailymotion.com/thumbnail/video/" + uid; - }, - height: 240 - } - }, { - key: 'Gfycat', - regExp: /^\w+:\/\/(?:www\.)?gfycat\.com\/(?:iframe\/)?(\w+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "//gfycat.com/ifr/" + a.dataset.uid - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Gist', - regExp: /^\w+:\/\/gist\.github\.com\/[\w\-]+\/(\w+)/, - style: '', - el: (function() { - var counter; - counter = 0; - return function(a) { - var el; - el = $.el('pre', { - hidden: true, - id: "gist-embed-" + (counter++) - }); - CrossOrigin.cache("https://api.github.com/gists/" + a.dataset.uid, function() { - el.textContent = Object.values(this.response.files)[0].content; - el.className = 'prettyprint'; - $.global(function() { - return typeof window.prettyPrint === "function" ? window.prettyPrint((function() {}), document.getElementById(document.currentScript.dataset.id).parentNode) : void 0; - }, { - id: el.id - }); - return el.hidden = false; - }); - return el; - }; - })(), - title: { - api: function(uid) { - return "https://api.github.com/gists/" + uid; - }, - text: function(arg) { - var file, files; - files = arg.files; - for (file in files) { - if (files.hasOwnProperty(file)) { - return file; - } - } - } - } - }, { - key: 'InstallGentoo', - regExp: /^\w+:\/\/paste\.installgentoo\.com\/view\/(?:raw\/|download\/|embed\/)?(\w+)/, - el: function(a) { - return $.el('iframe', { - src: "https://paste.installgentoo.com/view/embed/" + a.dataset.uid - }); - } - }, { - key: 'LiveLeak', - regExp: /^\w+:\/\/(?:\w+\.)?liveleak\.com\/.*\?.*[tif]=(\w+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://www.liveleak.com/e/" + a.dataset.uid - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - 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: function(a) { - var _, base, el, host, j, k, l, len, len1, len2, name, names, ref, ref1, type, types, url, urls; - el = $.el('video', { - controls: true, - preload: 'auto', - loop: true - }); - if (/^http/.test(a.dataset.uid)) { - $.add(el, $.el('source', { - src: a.dataset.uid - })); - return el; - } - ref = a.dataset.uid.match(/(\w+)\/(.*)/), _ = ref[0], host = ref[1], names = ref[2]; - types = (function() { - switch (host) { - case 'gd': - case 'wu': - case 'fc': - return ['']; - case 'gc': - return ['giant', 'fat', 'zippy']; - default: - return ['.webm', '.mp4']; - } - })(); - ref1 = names.split(','); - for (j = 0, len = ref1.length; j < len; j++) { - name = ref1[j]; - for (k = 0, len1 = types.length; k < len1; k++) { - type = types[k]; - base = "" + name + type; - urls = (function() { - switch (host) { - case 'pf': - return ["https://kastden.org/_loopvid_media/pf/" + base, "https://web.archive.org/web/2/http://a.pomf.se/" + base]; - case 'kd': - return ["https://kastden.org/loopvid/" + base]; - case 'lv': - return ["https://lv.kastden.org/" + base]; - case 'gd': - return ["https://docs.google.com/uc?export=download&id=" + base]; - case 'gh': - return ["https://googledrive.com/host/" + base]; - case 'db': - return ["https://dl.dropboxusercontent.com/u/" + base]; - case 'dx': - return ["https://dl.dropboxusercontent.com/" + base]; - case 'nn': - return ["https://kastden.org/_loopvid_media/nn/" + base]; - case 'cp': - return ["https://copy.com/" + base]; - case 'wu': - return ["http://webmup.com/" + base + "/vid.webm"]; - case 'ig': - return ["https://i.imgur.com/" + base]; - case 'ky': - return ["https://kastden.org/_loopvid_media/ky/" + base]; - case 'mf': - return ["https://kastden.org/_loopvid_media/mf/" + base, "https://web.archive.org/web/2/https://d.maxfile.ro/" + base]; - case 'm2': - return ["https://kastden.org/_loopvid_media/m2/" + base]; - case 'pc': - return ["https://kastden.org/_loopvid_media/pc/" + base, "https://web.archive.org/web/2/http://a.pomf.cat/" + base]; - case '1c': - return ["http://b.1339.cf/" + base]; - case 'pi': - return ["https://kastden.org/_loopvid_media/pi/" + base, "https://web.archive.org/web/2/https://u.pomf.is/" + base]; - case 'ni': - return ["https://kastden.org/_loopvid_media/ni/" + base, "https://web.archive.org/web/2/https://u.nya.is/" + base]; - case 'wl': - return ["http://webm.land/media/" + base]; - case 'ko': - return ["https://kordy.kastden.org/loopvid/" + base]; - case 'mm': - return ["https://kastden.org/_loopvid_media/mm/" + base, "https://web.archive.org/web/2/https://my.mixtape.moe/" + base]; - case 'ic': - return ["https://media.8ch.net/file_store/" + base]; - case 'fc': - return ["//" + (ImageHost.host()) + "/" + base + ".webm"]; - case 'gc': - return ["https://" + type + ".gfycat.com/" + name + ".webm"]; - } - })(); - for (l = 0, len2 = urls.length; l < len2; l++) { - url = urls[l]; - $.add(el, $.el('source', { - src: url - })); - } - } - } - return el; - } - }, { - key: 'Openings.moe', - regExp: /^\w+:\/\/openings.moe\/\?video=([^.&=]+)/, - style: 'width: 1280px; height: 720px; max-width: 80vw; max-height: 80vh;', - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://openings.moe/?video=" + a.dataset.uid - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Pastebin', - regExp: /^\w+:\/\/(?:\w+\.)?pastebin\.com\/(?!u\/)(?:[\w.]+(?:\/|\?i\=))?(\w+)/, - el: function(a) { - var div; - return div = $.el('iframe', { - src: "//pastebin.com/embed_iframe.php?i=" + a.dataset.uid - }); - } - }, { - key: 'SoundCloud', - regExp: /^\w+:\/\/(?:www\.)?(?:soundcloud\.com\/|snd\.sc\/)([\w\-\/]+)/, - style: 'border: 0; width: 500px; height: 400px;', - el: function(a) { - return $.el('iframe', { - src: "https://w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F" + (encodeURIComponent(a.dataset.uid)) - }); - }, - title: { - api: function(uid) { - return location.protocol + "//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F" + (encodeURIComponent(uid)); - }, - text: function(_) { - return _.title; - } - } - }, { - key: 'StrawPoll', - regExp: /^\w+:\/\/(?:www\.)?strawpoll\.me\/(?:embed_\d+\/)?(\d+(?:\/r)?)/, - style: 'border: 0; width: 600px; height: 406px;', - el: function(a) { - return $.el('iframe', { - src: "https://www.strawpoll.me/embed_1/" + a.dataset.uid - }); - } - }, { - key: 'Streamable', - regExp: /^\w+:\/\/(?:www\.)?streamable\.com\/(\w+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://streamable.com/o/" + a.dataset.uid - }); - el.setAttribute("allowfullscreen", "true"); - return el; - }, - title: { - api: function(uid) { - return "https://api.streamable.com/oembed?url=https://streamable.com/" + uid; - }, - text: function(_) { - return _.title; - } - } - }, { - key: 'TwitchTV', - regExp: /^\w+:\/\/(?:www\.|secure\.|clips\.|m\.)?twitch\.tv\/(\w[^#\&\?]*)/, - el: function(a) { - var el, m, time, url; - m = a.dataset.href.match(/^\w+:\/\/(?:(clips\.)|\w+\.)?twitch\.tv\/(?:\w+\/)?(clip\/)?(\w[^#\&\?]*)/); - if (m[1] || m[2]) { - url = "//clips.twitch.tv/embed?clip=" + m[3] + "&parent=" + location.hostname; - } else { - m = a.dataset.uid.match(/(\w+)(?:\/(?:v\/)?(\d+))?/); - url = "//player.twitch.tv/?" + (m[2] ? "video=v" + m[2] : "channel=" + m[1]) + "&autoplay=false&parent=" + location.hostname; - if ((time = a.dataset.href.match(/\bt=(\w+)/))) { - url += "&time=" + time[1]; - } - } - el = $.el('iframe', { - src: url - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Twitter', - regExp: /^\w+:\/\/(?:www\.|mobile\.)?twitter\.com\/(\w+\/status\/\d+)/, - style: 'border: none; width: 550px; height: 250px; overflow: hidden; resize: both;', - el: function(a) { - var cont, el, onMessage; - el = $.el('iframe'); - $.on(el, 'load', function() { - return this.contentWindow.postMessage({ - element: 't', - query: 'height' - }, 'https://twitframe.com'); - }); - onMessage = function(e) { - if (e.source === el.contentWindow && e.origin === 'https://twitframe.com') { - $.off(window, 'message', onMessage); - return (cont || el).style.height = (+$.minmax(e.data.height, 250, 0.8 * doc.clientHeight)) + "px"; - } - }; - $.on(window, 'message', onMessage); - el.src = "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid; - if ($.engine === 'gecko') { - el.style.cssText = 'border: none; width: 100%; height: 100%;'; - cont = $.el('div'); - $.add(cont, el); - return cont; - } else { - return el; - } - } - }, { - key: 'VidLii', - regExp: /^\w+:\/\/(?:www\.)?vidlii\.com\/watch\?v=(\w{11})/, - style: 'border: none; width: 640px; height: 392px;', - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://www.vidlii.com/embed?v=" + a.dataset.uid + "&a=0" - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Vimeo', - regExp: /^\w+:\/\/(?:www\.)?vimeo\.com\/(\d+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "//player.vimeo.com/video/" + a.dataset.uid + "?wmode=opaque" - }); - el.setAttribute("allowfullscreen", "true"); - return el; - }, - title: { - api: function(uid) { - return "https://vimeo.com/api/oembed.json?url=https://vimeo.com/" + uid; - }, - text: function(_) { - return _.title; - } - } - }, { - key: 'Vine', - regExp: /^\w+:\/\/(?:www\.)?vine\.co\/v\/(\w+)/, - style: 'border: none; width: 500px; height: 500px;', - el: function(a) { - return $.el('iframe', { - src: "https://vine.co/v/" + a.dataset.uid + "/card" - }); - } - }, { - key: 'Vocaroo', - regExp: /^\w+:\/\/(?:(?:www\.|old\.)?vocaroo\.com|voca\.ro)\/((?:i\/)?\w+)/, - style: '', - el: function(a) { - var el; - el = $.el('iframe'); - el.width = 300; - el.height = 60; - el.setAttribute('frameborder', 0); - el.src = "https://vocaroo.com/embed/" + (a.dataset.uid.replace(/^i\//, '')) + "?autoplay=0"; - return el; - } - }, { - key: 'YouTube', - regExp: /^\w+:\/\/(?:youtu.be\/|[\w.]*youtube[\w.]*\/.*(?:v=|\bembed\/|\bv\/))([\w\-]{11})(.*)/, - el: function(a) { - var el, start; - start = a.dataset.options.match(/\b(?:star)?t\=(\w+)/); - if (start) { - start = start[1]; - } - if (start && !/^\d+$/.test(start)) { - start += ' 0h0m0s'; - start = 3600 * start.match(/(\d+)h/)[1] + 60 * start.match(/(\d+)m/)[1] + 1 * start.match(/(\d+)s/)[1]; - } - el = $.el('iframe', { - src: "//www.youtube.com/embed/" + a.dataset.uid + "?rel=0&wmode=opaque" + (start ? '&start=' + start : '') - }); - el.setAttribute("allowfullscreen", "true"); - return el; - }, - title: { - api: function(uid) { - return "https://www.youtube.com/oembed?url=https%3A//www.youtube.com/watch%3Fv%3D" + uid + "&format=json"; - }, - text: function(_) { - return _.title; - }, - status: function(_) { - var m; - if (_.error) { - m = _.error.match(/^(\d*)\s*(.*)/); - return [+m[1], m[2]]; - } else { - return [200, 'OK']; - } - } - }, - preview: { - url: function(uid) { - return "https://img.youtube.com/vi/" + uid + "/0.jpg"; - }, - height: 360 - } - } - ] - }; - - return Embedding; - -}).call(this); - -Linkify = (function() { - var Linkify; - - Linkify = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread' && ref !== 'archive') || !Conf['Linkify']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - Callbacks.Post.push({ - name: 'Linkify', - cb: this.node - }); - return Embedding.init(); - }, - node: function() { - var base, j, k, len, len1, link, links, ref; - if (this.isClone) { - return Embedding.events(this); - } - if (!Linkify.regString.test(this.info.comment)) { - return; - } - ref = $$('a', this.nodes.comment); - for (j = 0, len = ref.length; j < len; j++) { - link = ref[j]; - if (!(typeof (base = g.SITE).isLinkified === "function" ? base.isLinkified(link) : void 0)) { - continue; - } - $.addClass(link, 'linkify'); - if (ImageHost.useFaster) { - ImageHost.fixLinks([link]); - } - Embedding.process(link, this); - } - links = Linkify.process(this.nodes.comment); - if (ImageHost.useFaster) { - ImageHost.fixLinks(links); - } - for (k = 0, len1 = links.length; k < len1; k++) { - link = links[k]; - Embedding.process(link, this); - } - }, - process: function(node) { - var data, end, endNode, i, index, length, links, part1, part2, ref, ref1, result, saved, snapshot, space, test, word; - test = /[^\s"]+/g; - space = /[\s"]/; - snapshot = $.X('.//br|.//text()', node); - i = 0; - links = []; - while (node = snapshot.snapshotItem(i++)) { - data = node.data; - if (!data || node.parentElement.nodeName === "A") { - continue; - } - while (result = test.exec(data)) { - index = result.index; - endNode = node; - word = result[0]; - if ((length = index + word.length) === data.length) { - test.lastIndex = 0; - while ((saved = snapshot.snapshotItem(i++))) { - if (saved.nodeName === 'BR' || (saved.parentElement.nodeName === 'P' && !saved.previousSibling)) { - if ((part1 = word.match(/(https?:\/\/)?([a-z\d-]+\.)*[a-z\d-]+$/i)) && (part2 = (ref = snapshot.snapshotItem(i)) != null ? (ref1 = ref.data) != null ? ref1.match(/^(\.[a-z\d-]+)*\//i) : void 0 : void 0) && (part1[0] + part2[0]).search(Linkify.regString) === 0) { - continue; - } else { - break; - } - } - if (saved.parentElement.nodeName === "A" && !Linkify.regString.test(word)) { - break; - } - endNode = saved; - data = saved.data; - if (end = space.exec(data)) { - word += data.slice(0, end.index); - test.lastIndex = length = end.index; - i--; - break; - } else { - length = data.length; - word += data; - } - } - } - if (Linkify.regString.test(word)) { - links.push(Linkify.makeRange(node, endNode, index, length)); - } - if (!(test.lastIndex && node === endNode)) { - break; - } - } - } - i = links.length; - while (i--) { - links[i] = Linkify.makeLink(links[i]); - } - return links; - }, - regString: /((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: function(startNode, endNode, startOffset, endOffset) { - var range; - range = document.createRange(); - range.setStart(startNode, startOffset); - range.setEnd(endNode, endOffset); - return range; - }, - makeLink: function(range) { - var a, encodedDomain, i, t, text; - text = range.toString(); - i = text.search(Linkify.regString); - if (i > 0) { - text = text.slice(i); - while (range.startOffset + i >= range.startContainer.data.length) { - i--; - } - if (i) { - range.setStart(range.startContainer, range.startOffset + i); - } - } - i = 0; - while (/[)\]}>.,]/.test(t = text.charAt(text.length - (1 + i)))) { - if (!(/[.,]/.test(t) || (text.match(/[()\[\]{}<>]/g)).length % 2)) { - break; - } - i++; - } - if (i) { - text = text.slice(0, -i); - while (range.endOffset - i < 0) { - i--; - } - if (i) { - range.setEnd(range.endContainer, range.endOffset - i); - } - } - if (!/((mailto|magnet):|.+:\/\/)/.test(text)) { - text = (/@/.test(text) ? 'mailto:' : 'http://') + text; - } - if (encodedDomain = text.match(/^(https?:\/\/[^\/]*%[0-9a-f]{2})(.*)$/i)) { - text = encodedDomain[1].replace(/%([0-9a-f]{2})/ig, function(x, y) { - if (y === '25') { - return x; - } else { - return String.fromCharCode(parseInt(y, 16)); - } - }) + encodedDomain[2]; - } - a = $.el('a', { - className: 'linkify', - rel: 'noreferrer noopener', - target: '_blank', - href: text - }); - $.add(a, range.extractContents()); - range.insertNode(a); - return a; - } - }; - - return Linkify; - -}).call(this); - -ArchiveLink = (function() { - var ArchiveLink; - - ArchiveLink = { - init: function() { - var div, entry, i, len, ref, ref1, type; - if (!(g.SITE.software === 'yotsuba' && ((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Archive Link'])) { - return; - } - div = $.el('div', { - textContent: 'Archive' - }); - entry = { - el: div, - order: 60, - open: function(arg) { - var ID, board, thread; - ID = arg.ID, thread = arg.thread, board = arg.board; - return !!Redirect.to('thread', { - postID: ID, - threadID: thread.ID, - boardID: board.ID - }); - }, - subEntries: [] - }; - ref1 = [['Post', 'post'], ['Name', 'name'], ['Tripcode', 'tripcode'], ['Capcode', 'capcode'], ['Subject', 'subject'], ['Flag', 'country'], ['Filename', 'filename'], ['Image MD5', 'MD5']]; - for (i = 0, len = ref1.length; i < len; i++) { - type = ref1[i]; - entry.subEntries.push(this.createSubEntry(type[0], type[1])); - } - return Menu.menu.addEntry(entry); - }, - createSubEntry: function(text, type) { - var el, open; - el = $.el('a', { - textContent: text, - target: '_blank' - }); - open = type === 'post' ? function(arg) { - var ID, board, thread; - ID = arg.ID, thread = arg.thread, board = arg.board; - el.href = Redirect.to('thread', { - postID: ID, - threadID: thread.ID, - boardID: board.ID - }); - return true; - } : function(post) { - var ref, typeParam, value; - typeParam = type === 'country' && post.info.flagCodeTroll ? 'troll_country' : type; - value = type === 'country' ? post.info.flagCode || ((ref = post.info.flagCodeTroll) != null ? ref.toLowerCase() : void 0) : Filter.values(type, post)[0]; - if (!value) { - return false; - } - el.href = Redirect.to('search', { - boardID: post.board.ID, - type: typeParam, - value: value, - isSearch: true - }); - return true; - }; - return { - el: el, - open: open - }; - } - }; - - return ArchiveLink; - -}).call(this); - -CopyTextLink = (function() { - var CopyTextLink; - - CopyTextLink = { - init: function() { - var a, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Copy Text Link'])) { - return; - } - a = $.el('a', { - className: 'copy-text-link', - href: 'javascript:;', - textContent: 'Copy Text' - }); - $.on(a, 'click', CopyTextLink.copy); - return Menu.menu.addEntry({ - el: a, - order: 12, - open: function(post) { - CopyTextLink.text = (post.origin || post).commentOrig(); - return true; - } - }); - }, - copy: function() { - var el; - el = $.el('textarea', { - className: 'copy-text-element', - value: CopyTextLink.text - }); - $.add(d.body, el); - el.select(); - try { - d.execCommand('copy'); - } catch (error) {} - return $.rm(el); - } - }; - - return CopyTextLink; - -}).call(this); - -DeleteLink = (function() { - var DeleteLink; - - DeleteLink = { - auto: [$.dict(), $.dict()], - init: function() { - var div, fileEl, fileEntry, postEl, postEntry, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Delete Link'])) { - return; - } - div = $.el('div', { - className: 'delete-link', - textContent: 'Delete' - }); - postEl = $.el('a', { - className: 'delete-post', - href: 'javascript:;' - }); - fileEl = $.el('a', { - className: 'delete-file', - href: 'javascript:;' - }); - this.nodes = { - menu: div.firstChild, - links: [postEl, fileEl] - }; - postEntry = { - el: postEl, - open: function() { - postEl.textContent = DeleteLink.linkText(false); - $.on(postEl, 'click', DeleteLink.toggle); - return true; - } - }; - fileEntry = { - el: fileEl, - open: function(arg) { - var file; - file = arg.file; - if (!file || file.isDead) { - return false; - } - fileEl.textContent = DeleteLink.linkText(true); - $.on(fileEl, 'click', DeleteLink.toggle); - return true; - } - }; - return Menu.menu.addEntry({ - el: div, - order: 40, - open: function(post) { - if (post.isDead) { - return false; - } - DeleteLink.post = post; - DeleteLink.nodes.menu.textContent = DeleteLink.menuText(); - DeleteLink.cooldown.start(post); - return true; - }, - subEntries: [postEntry, fileEntry] - }); - }, - menuText: function() { - var seconds; - if (seconds = DeleteLink.cooldown.seconds[DeleteLink.post.fullID]) { - return "Delete (" + seconds + ")"; - } else { - return 'Delete'; - } - }, - linkText: function(fileOnly) { - var text; - text = fileOnly ? 'File' : 'Post'; - if (DeleteLink.auto[+fileOnly][DeleteLink.post.fullID]) { - text = "Deleting " + (text.toLowerCase()) + "..."; - } - return text; - }, - toggle: function() { - var auto, fileOnly, post; - post = DeleteLink.post; - fileOnly = $.hasClass(this, 'delete-file'); - auto = DeleteLink.auto[+fileOnly]; - if (auto[post.fullID]) { - delete auto[post.fullID]; - } else { - auto[post.fullID] = true; - } - this.textContent = DeleteLink.linkText(fileOnly); - if (!DeleteLink.cooldown.seconds[post.fullID]) { - return DeleteLink["delete"](post, fileOnly); - } - }, - "delete": function(post, fileOnly) { - var form, link; - link = DeleteLink.nodes.links[+fileOnly]; - delete DeleteLink.auto[+fileOnly][post.fullID]; - if (post.fullID === DeleteLink.post.fullID) { - $.off(link, 'click', DeleteLink.toggle); - } - form = { - mode: 'usrdel', - onlyimgdel: fileOnly, - pwd: QR.persona.getPassword() - }; - form[+post.ID] = 'delete'; - return $.ajax($.id('delform').action.replace("/" + g.BOARD + "/", "/" + post.board + "/"), { - responseType: 'document', - withCredentials: true, - onloadend: function() { - return DeleteLink.load(link, post, fileOnly, this.response); - }, - form: $.formData(form) - }); - }, - load: function(link, post, fileOnly, resDoc) { - var el, msg; - if (!resDoc) { - new Notice('warning', 'Connection error, please retry.', 20); - if (post.fullID === DeleteLink.post.fullID) { - $.on(link, 'click', DeleteLink.toggle); - } - return; - } - link.textContent = DeleteLink.linkText(fileOnly); - if (resDoc.title === '4chan - Banned') { - el = $.el('span', {innerHTML: "You can't delete posts because you are banned."}); - return new Notice('warning', el, 20); - } else if (msg = resDoc.getElementById('errmsg')) { - new Notice('warning', msg.textContent, 20); - if (post.fullID === DeleteLink.post.fullID) { - $.on(link, 'click', DeleteLink.toggle); - } - if (QR.cooldown.data && Conf['Cooldown'] && /\bwait\b/i.test(msg.textContent)) { - DeleteLink.cooldown.start(post, 5); - DeleteLink.auto[+fileOnly][post.fullID] = true; - return DeleteLink.nodes.links[+fileOnly].textContent = DeleteLink.linkText(fileOnly); - } - } else { - if (!fileOnly) { - QR.cooldown["delete"](post); - } - if (resDoc.title === 'Updating index...') { - (post.origin || post).kill(fileOnly); - } - if (post.fullID === DeleteLink.post.fullID) { - return link.textContent = 'Deleted'; - } - } - }, - cooldown: { - seconds: $.dict(), - start: function(post, seconds) { - if (DeleteLink.cooldown.seconds[post.fullID] != null) { - return; - } - if (seconds == null) { - seconds = QR.cooldown.secondsDeletion(post); - } - if (seconds > 0) { - DeleteLink.cooldown.seconds[post.fullID] = seconds; - return DeleteLink.cooldown.count(post); - } - }, - count: function(post) { - var fileOnly, i, len, ref; - if (post.fullID === DeleteLink.post.fullID) { - DeleteLink.nodes.menu.textContent = DeleteLink.menuText(); - } - if (DeleteLink.cooldown.seconds[post.fullID] > 0 && Conf['Cooldown']) { - DeleteLink.cooldown.seconds[post.fullID]--; - setTimeout(DeleteLink.cooldown.count, 1000, post); - } else { - delete DeleteLink.cooldown.seconds[post.fullID]; - ref = [false, true]; - for (i = 0, len = ref.length; i < len; i++) { - fileOnly = ref[i]; - if (DeleteLink.auto[+fileOnly][post.fullID]) { - DeleteLink["delete"](post, fileOnly); - } - } - } - } - } - }; - - return DeleteLink; - -}).call(this); - -DownloadLink = (function() { - var DownloadLink; - - DownloadLink = { - init: function() { - var a, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Download Link'])) { - return; - } - a = $.el('a', { - className: 'download-link', - textContent: 'Download file' - }); - $.on(a, 'click', ImageCommon.download); - return Menu.menu.addEntry({ - el: a, - order: 100, - open: function(arg) { - var file; - file = arg.file; - if (!file) { - return false; - } - a.href = file.url; - a.download = file.name; - return true; - } - }); - } - }; - - return DownloadLink; - -}).call(this); - -Menu = (function() { - var Menu; - - Menu = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'])) { - return; - } - this.button = $.el('a', { - className: 'menu-button', - href: 'javascript:;' - }); - $.extend(this.button, {innerHTML: ""}); - this.menu = new UI.Menu('post'); - Callbacks.Post.push({ - name: 'Menu', - cb: this.node - }); - return Callbacks.CatalogThread.push({ - name: 'Menu', - cb: this.catalogNode - }); - }, - node: function() { - var button; - if (this.isClone) { - button = $('.menu-button', this.nodes.info); - $.rmClass(button, 'active'); - $.rm($('.dialog', this.nodes.info)); - Menu.makeButton(this, button); - return; - } - return $.add(this.nodes.info, Menu.makeButton(this)); - }, - catalogNode: function() { - return $.after(this.nodes.icons, Menu.makeButton(this.thread.OP)); - }, - makeButton: function(post, button) { - button || (button = Menu.button.cloneNode(true)); - $.on(button, 'click', function(e) { - return Menu.menu.toggle(e, this, post); - }); - return button; - } - }; - - return Menu; - -}).call(this); - -ReportLink = (function() { - var ReportLink; - - ReportLink = { - init: function() { - var a, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Report Link'])) { - return; - } - a = $.el('a', { - className: 'report-link', - href: 'javascript:;', - textContent: 'Report' - }); - $.on(a, 'click', ReportLink.report); - return Menu.menu.addEntry({ - el: a, - order: 10, - open: function(post) { - ReportLink.url = "//sys." + (location.hostname.split('.')[1]) + ".org/" + post.board + "/imgboard.php?mode=report&no=" + post; - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - ReportLink.dims = 'width=350,height=275'; - } else { - ReportLink.dims = 'width=400,height=550'; - } - return true; - } - }); - }, - report: function() { - var dims, id, set, url; - url = ReportLink.url, dims = ReportLink.dims; - id = Date.now(); - set = "toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1," + dims; - return window.open(url, id, set); - } - }; - - return ReportLink; - -}).call(this); - -AntiAutoplay = (function() { - var AntiAutoplay; - - AntiAutoplay = { - init: function() { - var audio, i, len, ref; - if (!Conf['Disable Autoplaying Sounds']) { - return; - } - $.addClass(doc, 'anti-autoplay'); - ref = $$('audio[autoplay]', doc); - for (i = 0, len = ref.length; i < len; i++) { - audio = ref[i]; - this.stop(audio); - } - window.addEventListener('loadstart', ((function(_this) { - return function(e) { - return _this.stop(e.target); - }; - })(this)), true); - Callbacks.Post.push({ - name: 'Disable Autoplaying Sounds', - cb: this.node - }); - return $.ready((function(_this) { - return function() { - return _this.process(d.body); - }; - })(this)); - }, - stop: function(audio) { - if (!audio.autoplay) { - return; - } - audio.pause(); - audio.autoplay = false; - if (audio.controls) { - return; - } - audio.controls = true; - return $.addClass(audio, 'controls-added'); - }, - node: function() { - return AntiAutoplay.process(this.nodes.comment); - }, - process: function(root) { - var i, iframe, j, len, len1, object, ref, ref1; - ref = $$('iframe[src*="youtube"][src*="autoplay=1"]', root); - for (i = 0, len = ref.length; i < len; i++) { - iframe = ref[i]; - AntiAutoplay.processVideo(iframe, 'src'); - } - ref1 = $$('object[data*="youtube"][data*="autoplay=1"]', root); - for (j = 0, len1 = ref1.length; j < len1; j++) { - object = ref1[j]; - AntiAutoplay.processVideo(object, 'data'); - } - }, - processVideo: function(el, attr) { - el[attr] = el[attr].replace(/\?autoplay=1&?/, '?').replace('&autoplay=1', ''); - if (window.getComputedStyle(el).display === 'none') { - el.style.display = 'block'; - } - return $.addClass(el, 'autoplay-removed'); - } - }; - - return AntiAutoplay; - -}).call(this); - -Banner = (function() { - var Banner, - slice = [].slice; - - Banner = { - init: function() { - if (Conf['Custom Board Titles']) { - this.db = new DataBoard('customTitles', null, true); - } - $.asap((function() { - return d.body; - }), function() { - return $.asap((function() { - return $('hr'); - }), Banner.ready); - }); - if (g.BOARD.ID !== 'f') { - return Main.ready(function() { - return $.queueTask(Banner.load); - }); - } - }, - ready: function() { - var banner, children; - banner = $(".boardBanner"); - children = banner.children; - if (g.VIEW === 'thread' && Conf['Remove Thread Excerpt']) { - Banner.setTitle(children[1].textContent); - } - children[0].title = "Click to change"; - $.on(children[0], 'click', Banner.cb.toggle); - if (Conf['Custom Board Titles']) { - Banner.custom(children[1]); - if (children[2]) { - return Banner.custom(children[2]); - } - } - }, - load: function() { - var bannerCnt, img; - bannerCnt = $.id('bannerCnt'); - if (!bannerCnt.firstChild) { - img = $.el('img', { - alt: '4chan', - src: '//s.4cdn.org/image/title/' + bannerCnt.dataset.src - }); - return $.add(bannerCnt, img); - } - }, - setTitle: function(title) { - if (Unread.title != null) { - Unread.title = title; - return Unread.update(); - } else { - return d.title = title; - } - }, - cb: { - toggle: function() { - var banner, i, ref; - if (!((ref = Banner.choices) != null ? ref.length : void 0)) { - Banner.choices = Conf['knownBanners'].split(',').slice(); - } - i = Math.floor(Banner.choices.length * Math.random()); - banner = Banner.choices.splice(i, 1); - return $('img', this.parentNode).src = "//s.4cdn.org/image/title/" + banner; - }, - click: function(e) { - var base, br, j, len, name, ref; - if (!(e.ctrlKey || e.metaKey)) { - return; - } - if ((base = Banner.original)[name = this.className] == null) { - base[name] = this.cloneNode(true); - } - this.contentEditable = true; - ref = $$('br', this); - for (j = 0, len = ref.length; j < len; j++) { - br = ref[j]; - $.replace(br, $.tn('\n')); - } - return this.focus(); - }, - keydown: function(e) { - e.stopPropagation(); - if (!e.shiftKey && e.keyCode === 13) { - return this.blur(); - } - }, - blur: function() { - var br, j, len, ref; - ref = $$('br', this); - for (j = 0, len = ref.length; j < len; j++) { - br = ref[j]; - $.replace(br, $.tn('\n')); - } - if (this.textContent = this.textContent.replace(/\n*$/, '')) { - this.contentEditable = false; - return Banner.db.set({ - boardID: g.BOARD.ID, - threadID: this.className, - val: { - title: this.textContent, - orig: Banner.original[this.className].textContent - } - }); - } else { - $.rmAll(this); - $.add(this, slice.call(Banner.original[this.className].cloneNode(true).childNodes)); - return Banner.db["delete"]({ - boardID: g.BOARD.ID, - threadID: this.className - }); - } - } - }, - original: $.dict(), - custom: function(child) { - var className, data, event, j, len, ref; - className = child.className; - child.title = "Ctrl/\u2318+click to edit board " + (className.slice(5).toLowerCase()); - child.spellcheck = false; - ref = ['click', 'keydown', 'blur']; - for (j = 0, len = ref.length; j < len; j++) { - event = ref[j]; - $.on(child, event, Banner.cb[event]); - } - if (data = Banner.db.get({ - boardID: g.BOARD.ID, - threadID: className - })) { - if (Conf['Persistent Custom Board Titles'] || data.orig === child.textContent) { - Banner.original[className] = child.cloneNode(true); - return child.textContent = data.title; - } else { - return Banner.db["delete"]({ - boardID: g.BOARD.ID, - threadID: className - }); - } - } - } - }; - - return Banner; - -}).call(this); - -CatalogLinks = (function() { - var CatalogLinks; - - CatalogLinks = { - init: function() { - var el, input, selector; - if (g.SITE.software === 'yotsuba' && (Conf['External Catalog'] || Conf['JSON Index']) && !(Conf['JSON Index'] && g.VIEW === 'index')) { - selector = (function() { - switch (g.VIEW) { - case 'thread': - case 'archive': - return '.navLinks.desktop > a'; - case 'catalog': - return '.navLinks > :first-child > a'; - case 'index': - return '#ctrl-top > a, .cataloglink > a'; - } - })(); - $.ready(function() { - var base, catalogLink, catalogURL, i, len, link, link2, ref; - ref = $$(selector); - for (i = 0, len = ref.length; i < len; i++) { - link = ref[i]; - switch (link.pathname.replace(/\/+/g, '/')) { - case "/" + g.BOARD + "/": - if (Conf['JSON Index']) { - link.textContent = 'Index'; - } - link.href = CatalogLinks.index(); - break; - case "/" + g.BOARD + "/catalog": - link.href = CatalogLinks.catalog(); - } - if (g.VIEW === 'catalog' && (catalogURL = CatalogLinks.catalog()) !== (typeof (base = g.SITE.urls).catalog === "function" ? base.catalog(g.BOARD) : void 0)) { - catalogLink = link.parentNode.cloneNode(true); - link2 = catalogLink.firstElementChild; - link2.href = catalogURL; - link2.textContent = link2.hostname === location.hostname ? '4chan X Catalog' : 'External Catalog'; - $.after(link.parentNode, [$.tn(' '), catalogLink]); - } - } - }); - } - if (g.SITE.software === 'yotsuba' && Conf['JSON Index'] && Conf['Use 4chan X Catalog']) { - Callbacks.Post.push({ - name: 'Catalog Link Rewrite', - cb: this.node - }); - } - if ((this.enabled = Conf['Catalog Links'])) { - CatalogLinks.el = el = UI.checkbox('Header catalog links', 'Catalog Links'); - el.id = 'toggleCatalog'; - input = $('input', el); - $.on(input, 'change', this.toggle); - $.sync('Header catalog links', CatalogLinks.set); - return Header.menu.addEntry({ - el: el, - order: 95 - }); - } - }, - node: function() { - var a, i, len, m, ref; - ref = $$('a', this.nodes.comment); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - if (m = a.href.match(/^https?:\/\/(boards\.4chan(?:nel)?\.org\/[^\/]+)\/catalog(#s=.*)?/)) { - a.href = "//" + m[1] + "/" + (m[2] || '#catalog'); - } - } - }, - toggle: function() { - $.event('CloseMenu'); - $.set('Header catalog links', this.checked); - return CatalogLinks.set(this.checked); - }, - set: function(useCatalog) { - Conf['Header catalog links'] = useCatalog; - CatalogLinks.setLinks(Header.boardList); - CatalogLinks.setLinks(Header.bottomBoardList); - CatalogLinks.el.title = "Turn catalog links " + (useCatalog ? 'off' : 'on') + "."; - return $('input', CatalogLinks.el).checked = useCatalog; - }, - setLinks: function(list) { - var VIEW, a, board, boardID, i, len, ref, ref1, ref2, ref3, siteID, tail, url; - if (!(((ref = CatalogLinks.enabled) != null ? ref : Conf['Catalog Links']) && list)) { - return; - } - tail = /(?:index)?(?:\.\w+)?$/; - ref1 = $$('a:not([data-only])', list); - for (i = 0, len = ref1.length; i < len; i++) { - a = ref1[i]; - ref2 = a.dataset, siteID = ref2.siteID, boardID = ref2.boardID; - if (!(siteID && boardID)) { - ref3 = Site.parseURL(a), siteID = ref3.siteID, boardID = ref3.boardID, VIEW = ref3.VIEW; - if (!(siteID && boardID && (VIEW === 'index' || VIEW === 'catalog') && (a.dataset.indexOptions || a.href.replace(tail, '') === (Get.url(VIEW, { - siteID: siteID, - boardID: boardID - }) || '').replace(tail, '')))) { - continue; - } - $.extend(a.dataset, { - siteID: siteID, - boardID: boardID - }); - } - board = { - siteID: siteID, - boardID: boardID - }; - url = Conf['Header catalog links'] ? CatalogLinks.catalog(board) : Get.url('index', board); - if (url) { - a.href = url; - if (a.dataset.indexOptions && url.split('#')[0] === Get.url('index', board)) { - a.href += (a.hash ? '/' : '#') + a.dataset.indexOptions; - } - } - } - }, - externalParse: function() { - var board, boards, excludes, i, len, line, ref, ref1, ref2, url; - CatalogLinks.externalList = $.dict(); - ref = Conf['externalCatalogURLs'].split('\n'); - for (i = 0, len = ref.length; i < len; i++) { - line = ref[i]; - if (line[0] === '#') { - continue; - } - url = line.split(';')[0]; - boards = Filter.parseBoards(((ref1 = line.match(/;boards:([^;]+)/)) != null ? ref1[1] : void 0) || '*'); - excludes = Filter.parseBoards((ref2 = line.match(/;exclude:([^;]+)/)) != null ? ref2[1] : void 0) || $.dict(); - for (board in boards) { - if (!(excludes[board] || excludes[board.split('/')[0] + '/*'])) { - CatalogLinks.externalList[board] = url; - } - } - } - }, - external: function(arg) { - var boardID, external, siteID; - siteID = arg.siteID, boardID = arg.boardID; - if (!CatalogLinks.externalList) { - CatalogLinks.externalParse(); - } - external = CatalogLinks.externalList[siteID + "/" + boardID] || CatalogLinks.externalList[siteID + "/*"]; - if (external) { - return external.replace(/%board/g, boardID); - } else { - return void 0; - } - }, - jsonIndex: function(board, hash) { - if (g.SITE.ID === board.siteID && g.BOARD.ID === board.boardID && g.VIEW === 'index') { - return hash; - } else { - return Get.url('index', board) + hash; - } - }, - catalog: function(board) { - var external, nativeCatalog; - if (board == null) { - board = g.BOARD; - } - if (Conf['External Catalog'] && (external = CatalogLinks.external(board))) { - return external; - } else if (Index.enabledOn(board) && Conf['Use 4chan X Catalog']) { - return CatalogLinks.jsonIndex(board, '#catalog'); - } else if ((nativeCatalog = Get.url('catalog', board))) { - return nativeCatalog; - } else { - return CatalogLinks.external(board); - } - }, - index: function(board) { - if (board == null) { - board = g.BOARD; - } - if (Index.enabledOn(board)) { - return CatalogLinks.jsonIndex(board, '#index'); - } else { - return Get.url('index', board); - } - } - }; - - return CatalogLinks; - -}).call(this); - -CustomCSS = (function() { - var CustomCSS; - - CustomCSS = { - init: function() { - if (!Conf['Custom CSS']) { - return; - } - return this.addStyle(); - }, - addStyle: function() { - return this.style = $.addStyle(CSS.sub(Conf['usercss']), 'custom-css', '#fourchanx-css'); - }, - rmStyle: function() { - if (this.style) { - $.rm(this.style); - return delete this.style; - } - }, - update: function() { - if (!this.style) { - return this.addStyle(); - } - return this.style.textContent = CSS.sub(Conf['usercss']); - } - }; - - return CustomCSS; - -}).call(this); - -ExpandComment = (function() { - var ExpandComment; - - ExpandComment = { - init: function() { - if (g.VIEW !== 'index' || !Conf['Comment Expansion'] || Conf['JSON Index']) { - return; - } - return Callbacks.Post.push({ - name: 'Comment Expansion', - cb: this.node - }); - }, - node: function() { - var a; - if (a = $('.abbr > a:not([onclick])', this.nodes.comment)) { - return $.on(a, 'click', ExpandComment.cb); - } - }, - callbacks: [], - cb: function(e) { - e.preventDefault(); - return ExpandComment.expand(Get.postFromNode(this)); - }, - expand: function(post) { - var a; - if (post.nodes.longComment && !post.nodes.longComment.parentNode) { - $.replace(post.nodes.shortComment, post.nodes.longComment); - post.nodes.comment = post.nodes.longComment; - return; - } - if (!(a = $('.abbr > a', post.nodes.comment))) { - return; - } - a.textContent = "Post No." + post + " Loading..."; - return $.cache(g.SITE.urls.threadJSON({ - boardID: post.boardID, - threadID: post.threadID - }), function() { - return ExpandComment.parse(this, a, post); - }); - }, - contract: function(post) { - var a; - if (!post.nodes.shortComment) { - return; - } - a = $('.abbr > a', post.nodes.shortComment); - a.textContent = 'here'; - $.replace(post.nodes.longComment, post.nodes.shortComment); - return post.nodes.comment = post.nodes.shortComment; - }, - parse: function(req, a, post) { - var callback, clone, comment, href, i, j, k, len, len1, len2, postObj, posts, quote, ref, ref1, spoilerRange, status; - status = req.status; - if (status !== 200 && status !== 304) { - a.textContent = status ? "Error " + req.statusText + " (" + status + ")" : 'Connection Error'; - return; - } - posts = req.response.posts; - if (spoilerRange = posts[0].custom_spoiler) { - g.SITE.Build.spoilerRange[g.BOARD] = spoilerRange; - } - for (i = 0, len = posts.length; i < len; i++) { - postObj = posts[i]; - if (postObj.no === post.ID) { - break; - } - } - if (postObj.no !== post.ID) { - a.textContent = "Post No." + post + " not found."; - return; - } - comment = post.nodes.comment; - clone = comment.cloneNode(false); - clone.innerHTML = postObj.com; - ref = $$('.quotelink', clone); - for (j = 0, len1 = ref.length; j < len1; j++) { - quote = ref[j]; - href = quote.getAttribute('href'); - if (href[0] === '/') { - continue; - } - if (href[0] === '#') { - quote.href = "" + (a.pathname.split(/\/+/).splice(0, 4).join('/')) + href; - } else { - quote.href = (a.pathname.split(/\/+/).splice(0, 3).join('/')) + "/" + href; - } - } - post.nodes.shortComment = comment; - $.replace(comment, clone); - post.nodes.comment = post.nodes.longComment = clone; - post.parseComment(); - post.parseQuotes(); - ref1 = ExpandComment.callbacks; - for (k = 0, len2 = ref1.length; k < len2; k++) { - callback = ref1[k]; - callback.call(post); - } - } - }; - - return ExpandComment; - -}).call(this); - -ExpandThread = (function() { - var ExpandThread, - slice = [].slice; - - ExpandThread = { - statuses: $.dict(), - init: function() { - if (!(g.VIEW === 'index' && Conf['Thread Expansion'])) { - return; - } - if (Conf['JSON Index']) { - return $.on(d, 'IndexRefreshInternal', this.onIndexRefresh); - } else { - return Callbacks.Thread.push({ - name: 'Expand Thread', - cb: function() { - return ExpandThread.setButton(this); - } - }); - } - }, - setButton: function(thread) { - var a, ref; - if (!(thread.nodes.root && (a = $('.summary', thread.nodes.root)))) { - return; - } - a.textContent = (ref = g.SITE.Build).summaryText.apply(ref, ['+'].concat(slice.call(a.textContent.match(/\d+/g)))); - a.style.cursor = 'pointer'; - return $.on(a, 'click', ExpandThread.cbToggle); - }, - disconnect: function(refresh) { - var oldReq, ref, status, threadID; - if (g.VIEW === 'thread' || !Conf['Thread Expansion']) { - return; - } - ref = ExpandThread.statuses; - for (threadID in ref) { - status = ref[threadID]; - if ((oldReq = status.req)) { - delete status.req; - oldReq.abort(); - } - delete ExpandThread.statuses[threadID]; - } - if (!refresh) { - return $.off(d, 'IndexRefreshInternal', this.onIndexRefresh); - } - }, - onIndexRefresh: function() { - ExpandThread.disconnect(true); - return g.BOARD.threads.forEach(function(thread) { - return ExpandThread.setButton(thread); - }); - }, - cbToggle: function(e) { - if ($.modifiedClick(e)) { - return; - } - e.preventDefault(); - return ExpandThread.toggle(Get.threadFromNode(this)); - }, - cbToggleBottom: function(e) { - var bottom, thread; - if ($.modifiedClick(e)) { - return; - } - e.preventDefault(); - thread = Get.threadFromNode(this); - $.rm(this); - bottom = thread.nodes.root.getBoundingClientRect().bottom; - ExpandThread.toggle(thread); - return window.scrollBy(0, thread.nodes.root.getBoundingClientRect().bottom - bottom); - }, - toggle: function(thread) { - var a; - if (!(thread.nodes.root && (a = $('.summary', thread.nodes.root)))) { - return; - } - if (thread.ID in ExpandThread.statuses) { - return ExpandThread.contract(thread, a, thread.nodes.root); - } else { - return ExpandThread.expand(thread, a); - } - }, - expand: function(thread, a) { - var ref, status; - ExpandThread.statuses[thread] = status = {}; - a.textContent = (ref = g.SITE.Build).summaryText.apply(ref, ['...'].concat(slice.call(a.textContent.match(/\d+/g)))); - status.req = $.cache(g.SITE.urls.threadJSON({ - boardID: thread.board.ID, - threadID: thread.ID - }), function() { - if (this !== status.req) { - return; - } - delete status.req; - return ExpandThread.parse(this, thread, a); - }); - return status.numReplies = $$(g.SITE.selectors.replyOriginal, thread.nodes.root).length; - }, - contract: function(thread, a, threadRoot) { - var filesCount, i, inlined, len, oldReq, postsCount, ref, replies, reply, status; - status = ExpandThread.statuses[thread]; - delete ExpandThread.statuses[thread]; - if ((oldReq = status.req)) { - delete status.req; - oldReq.abort(); - if (a) { - a.textContent = (ref = g.SITE.Build).summaryText.apply(ref, ['+'].concat(slice.call(a.textContent.match(/\d+/g)))); - } - return; - } - replies = $$('.thread > .replyContainer', threadRoot); - if (status.numReplies) { - replies = replies.slice(0, -status.numReplies); - } - postsCount = 0; - filesCount = 0; - for (i = 0, len = replies.length; i < len; i++) { - reply = replies[i]; - if (Conf['Quote Inlining']) { - while (inlined = $('.inlined', reply)) { - inlined.click(); - } - } - postsCount++; - if ('file' in Get.postFromRoot(reply)) { - filesCount++; - } - $.rm(reply); - } - if (Index.enabled) { - $.event('PostsRemoved', null, a.parentNode); - } - a.textContent = g.SITE.Build.summaryText('+', postsCount, filesCount); - return $.rm($('.summary-bottom', threadRoot)); - }, - parse: function(req, thread, a) { - var a2, filesCount, i, len, post, postData, posts, postsCount, postsRoot, ref, ref1, root; - if ((ref = req.status) !== 200 && ref !== 304) { - a.textContent = req.status ? "Error " + req.statusText + " (" + req.status + ")" : 'Connection Error'; - return; - } - g.SITE.Build.spoilerRange[thread.board] = req.response.posts[0].custom_spoiler; - posts = []; - postsRoot = []; - filesCount = 0; - ref1 = req.response.posts; - for (i = 0, len = ref1.length; i < len; i++) { - postData = ref1[i]; - if (postData.no === thread.ID) { - continue; - } - if ((post = thread.posts.get(postData.no)) && !post.isFetchedQuote) { - if ('file' in post) { - filesCount++; - } - root = post.nodes.root; - postsRoot.push(root); - continue; - } - root = g.SITE.Build.postFromObject(postData, thread.board.ID); - post = new Post(root, thread, thread.board); - if ('file' in post) { - filesCount++; - } - posts.push(post); - postsRoot.push(root); - } - Main.callbackNodes('Post', posts); - $.after(a, postsRoot); - $.event('PostsInserted', null, a.parentNode); - postsCount = postsRoot.length; - a.textContent = g.SITE.Build.summaryText('-', postsCount, filesCount); - if (root) { - a2 = a.cloneNode(true); - a2.classList.add('summary-bottom'); - $.on(a2, 'click', ExpandThread.cbToggleBottom); - return $.after(root, a2); - } - } - }; - - return ExpandThread; - -}).call(this); - -FileInfo = (function() { - var FileInfo; - - FileInfo = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread' && ref !== 'archive') || !Conf['File Info Formatting']) { - return; - } - return Callbacks.Post.push({ - name: 'File Info Formatting', - cb: this.node - }); - }, - node: function() { - var a, i, info, j, len, len1, oldInfo, ref, ref1; - if (!this.file) { - return; - } - if (this.isClone) { - ref = $$('.file-info .download-button', this.file.text); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - $.on(a, 'click', ImageCommon.download); - } - ref1 = $$('.file-info .quick-filter-md5', this.file.text); - for (j = 0, len1 = ref1.length; j < len1; j++) { - a = ref1[j]; - $.on(a, 'click', Filter.quickFilterMD5); - } - return; - } - oldInfo = $.el('span', { - className: 'fileText-original' - }); - $.prepend(this.file.link.parentNode, oldInfo); - $.add(oldInfo, [this.file.link.previousSibling, this.file.link, this.file.link.nextSibling]); - info = $.el('span', { - className: 'file-info' - }); - FileInfo.format(Conf['fileInfo'], this, info); - return $.prepend(this.file.text, info); - }, - format: function(formatString, post, outputNode) { - var a, i, j, len, len1, output, ref, ref1; - output = []; - formatString.replace(/%(.)|[^%]+/g, function(s, c) { - output.push($.hasOwn(FileInfo.formatters, c) ? FileInfo.formatters[c].call(post) : {innerHTML: E(s)}); - return ''; - }); - $.extend(outputNode, {innerHTML: E.cat(output)}); - ref = $$('.download-button', outputNode); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - $.on(a, 'click', ImageCommon.download); - } - ref1 = $$('.quick-filter-md5', outputNode); - for (j = 0, len1 = ref1.length; j < len1; j++) { - a = ref1[j]; - $.on(a, 'click', Filter.quickFilterMD5); - } - }, - formatters: { - t: function() { - return {innerHTML: E(this.file.url.match(/[^/]*$/)[0])}; - }, - T: function() { - return {innerHTML: "" + (FileInfo.formatters.t.call(this)).innerHTML + ""}; - }, - l: function() { - return {innerHTML: "" + (FileInfo.formatters.n.call(this)).innerHTML + ""}; - }, - L: function() { - return {innerHTML: "" + (FileInfo.formatters.N.call(this)).innerHTML + ""}; - }, - n: function() { - var fullname, shortname; - fullname = this.file.name; - shortname = SW.yotsuba.Build.shortFilename(this.file.name, this.isReply); - if (fullname === shortname) { - return {innerHTML: E(fullname)}; - } else { - return {innerHTML: "" + E(shortname) + "" + E(fullname) + ""}; - } - }, - N: function() { - return {innerHTML: E(this.file.name)}; - }, - d: function() { - return {innerHTML: ""}; - }, - f: function() { - return {innerHTML: ""}; - }, - p: function() { - return {innerHTML: ((this.file.isSpoiler) ? "Spoiler, " : "")}; - }, - s: function() { - return {innerHTML: E(this.file.size)}; - }, - B: function() { - return {innerHTML: E(Math.round(this.file.sizeInBytes)) + " Bytes"}; - }, - K: function() { - return {innerHTML: E(Math.round(this.file.sizeInBytes/1024)) + " KB"}; - }, - M: function() { - return {innerHTML: E(Math.round(this.file.sizeInBytes/1048576*100)/100) + " MB"}; - }, - r: function() { - return {innerHTML: E(this.file.dimensions || "PDF")}; - }, - g: function() { - return {innerHTML: ((this.file.tag) ? ", " + E(this.file.tag) : "")}; - }, - '%': function() { - return {innerHTML: "%"}; - } - } - }; - - return FileInfo; - -}).call(this); - -Flash = (function() { - var Flash; - - Flash = { - init: function() { - if (g.BOARD.ID === 'f' && Conf['Enable Native Flash Embedding']) { - return $.ready(Flash.initReady); - } - }, - initReady: function() { - if ($.hasStorage) { - return $.global(function() { - if (JSON.parse(localStorage['4chan-settings'] || '{}').disableAll) { - return window.SWFEmbed.init(); - } - }); - } else { - if (g.VIEW === 'thread') { - $.global(function() { - return window.Main.tid = location.pathname.split(/\/+/)[3]; - }); - } - return $.global(function() { - return window.SWFEmbed.init(); - }); - } - } - }; - - return Flash; - -}).call(this); - -Fourchan = (function() { - var Fourchan; - - Fourchan = { - init: function() { - var ref; - if (!(g.SITE.software === 'yotsuba' && ((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive'))) { - return; - } - BoardConfig.ready(this.initBoard); - return Main.ready(this.initReady); - }, - initBoard: function() { - if (g.BOARD.config.code_tags) { - $.on(window, 'prettyprint:cb', function(e) { - var post, pre; - if (!(post = g.posts.get(e.detail.ID))) { - return; - } - if (!(pre = $$('.prettyprint', post.nodes.comment)[+e.detail.i])) { - return; - } - if (!$.hasClass(pre, 'prettyprinted')) { - pre.innerHTML = e.detail.html; - return $.addClass(pre, 'prettyprinted'); - } - }); - $.global(function() { - return window.addEventListener('prettyprint', function(e) { - return window.dispatchEvent(new CustomEvent('prettyprint:cb', { - detail: { - ID: e.detail.ID, - i: e.detail.i, - html: window.prettyPrintOne(e.detail.html) - } - })); - }, false); - }); - Callbacks.Post.push({ - name: 'Parse [code] tags', - cb: Fourchan.code - }); - g.posts.forEach(function(post) { - if (post.callbacksExecuted) { - return Callbacks.Post.execute(post, ['Parse [code] tags'], true); - } - }); - ExpandComment.callbacks.push(Fourchan.code); - } - if (g.BOARD.config.math_tags) { - $.global(function() { - return window.addEventListener('mathjax', function(e) { - if (window.MathJax) { - return window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, e.target]); - } else { - if (!document.querySelector('script[src^="//cdn.mathjax.org/"]')) { - window.loadMathJax(); - window.loadMathJax = function() {}; - } - if (!e.target.classList.contains('postMessage')) { - return document.querySelector('script[src^="//cdn.mathjax.org/"]').addEventListener('load', function() { - return window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, e.target]); - }, false); - } - } - }, false); - }); - Callbacks.Post.push({ - name: 'Parse [math] tags', - cb: Fourchan.math - }); - g.posts.forEach(function(post) { - if (post.callbacksExecuted) { - return Callbacks.Post.execute(post, ['Parse [math] tags'], true); - } - }); - return ExpandComment.callbacks.push(Fourchan.math); - } - }, - initReady: function() { - return $.global(function() { - var j, len, node, ref; - window.clickable_ids = false; - ref = document.querySelectorAll('.posteruid, .capcode'); - for (j = 0, len = ref.length; j < len; j++) { - node = ref[j]; - node.removeEventListener('click', window.idClick, false); - } - }); - }, - code: function() { - if (this.isClone) { - return; - } - return $.ready((function(_this) { - return function() { - var i, j, len, pre, ref; - ref = $$('.prettyprint', _this.nodes.comment); - for (i = j = 0, len = ref.length; j < len; i = ++j) { - pre = ref[i]; - if (!$.hasClass(pre, 'prettyprinted')) { - $.event('prettyprint', { - ID: _this.fullID, - i: i, - html: pre.innerHTML - }, window); - } - } - }; - })(this)); - }, - math: function() { - var cb, j, len, wbr, wbrs; - if (!/\[(math|eqn)\]/.test(this.nodes.comment.textContent)) { - return; - } - if ((wbrs = $$('wbr', this.nodes.comment)).length) { - for (j = 0, len = wbrs.length; j < len; j++) { - wbr = wbrs[j]; - $.rm(wbr); - } - this.nodes.comment.normalize(); - } - cb = (function(_this) { - return function() { - if (!doc.contains(_this.nodes.comment)) { - return; - } - $.off(d, 'PostsInserted', cb); - return $.event('mathjax', null, _this.nodes.comment); - }; - })(this); - $.on(d, 'PostsInserted', cb); - return cb(); - } - }; - - return Fourchan; - -}).call(this); - -IDColor = (function() { - var IDColor; - - IDColor = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Color User IDs'])) { - return; - } - this.ids = $.dict(); - this.ids['Heaven'] = [0, 0, 0, '#fff']; - return Callbacks.Post.push({ - name: 'Color User IDs', - cb: this.node - }); - }, - node: function() { - var rgb, span, style, uid; - if (this.isClone || !((uid = this.info.uniqueID) && (span = this.nodes.uniqueID))) { - return; - } - rgb = IDColor.ids[uid] || IDColor.compute(uid); - style = span.style; - style.color = rgb[3]; - style.backgroundColor = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")"; - return $.addClass(span, 'painted'); - }, - compute: function(uid) { - var hash, rgb; - hash = g.SITE.uidColor ? g.SITE.uidColor(uid) : parseInt(uid, 16); - rgb = [(hash >> 16) & 0xFF, (hash >> 8) & 0xFF, hash & 0xFF]; - rgb.push($.luma(rgb) > 125 ? '#000' : '#fff'); - return this.ids[uid] = rgb; - } - }; - - return IDColor; - -}).call(this); - -IDHighlight = (function() { - var IDHighlight; - - IDHighlight = { - init: function() { - var ref; - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - return Callbacks.Post.push({ - name: 'Highlight by User ID', - cb: this.node - }); - }, - uniqueID: null, - node: function() { - if (this.nodes.uniqueIDRoot) { - $.on(this.nodes.uniqueIDRoot, 'click', IDHighlight.click(this)); - } - if (this.nodes.capcode) { - $.on(this.nodes.capcode, 'click', IDHighlight.click(this)); - } - if (!this.isClone) { - return IDHighlight.set(this); - } - }, - set: function(post) { - var match; - match = (post.info.uniqueID || post.info.capcode) === IDHighlight.uniqueID; - return $[match ? 'addClass' : 'rmClass'](post.nodes.post, 'highlight'); - }, - click: function(post) { - return function() { - var uniqueID; - uniqueID = post.info.uniqueID || post.info.capcode; - IDHighlight.uniqueID = IDHighlight.uniqueID === uniqueID ? null : uniqueID; - return g.posts.forEach(IDHighlight.set); - }; - } - }; - - return IDHighlight; - -}).call(this); - -IDPostCount = (function() { - var IDPostCount; - - IDPostCount = { - init: function() { - if (!(g.VIEW === 'thread' && Conf['Count Posts by ID'])) { - return; - } - Callbacks.Thread.push({ - name: 'Count Posts by ID', - cb: function() { - return IDPostCount.thread = this; - } - }); - return Callbacks.Post.push({ - name: 'Count Posts by ID', - cb: this.node - }); - }, - node: function() { - if (this.nodes.uniqueID && this.thread === IDPostCount.thread) { - return $.on(this.nodes.uniqueID, 'mouseover', IDPostCount.count); - } - }, - count: function() { - var n, uniqueID; - uniqueID = Get.postFromNode(this).info.uniqueID; - n = 0; - IDPostCount.thread.posts.forEach(function(post) { - if (post.info.uniqueID === uniqueID) { - return n++; - } - }); - return this.title = n + " post" + (n === 1 ? '' : 's') + " by this ID"; - } - }; - - return IDPostCount; - -}).call(this); - -Keybinds = (function() { - var Keybinds; - - Keybinds = { - init: function() { - var hotkey, init; - if (!Conf['Keybinds']) { - return; - } - for (hotkey in Config.hotkeys) { - $.sync(hotkey, Keybinds.sync); - } - init = function() { - var i, len, node, ref; - $.off(d, '4chanXInitFinished', init); - $.on(d, 'keydown', Keybinds.keydown); - ref = $$('[accesskey]'); - for (i = 0, len = ref.length; i < len; i++) { - node = ref[i]; - node.removeAttribute('accesskey'); - } - }; - return $.on(d, '4chanXInitFinished', init); - }, - sync: function(key, hotkey) { - return Conf[hotkey] = key; - }, - keydown: function(e) { - var base, base1, catalog, i, key, len, notification, notifications, post, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, searchInput, target, thread, threadRoot; - if (!(key = Keybinds.keyCode(e))) { - return; - } - target = e.target; - if ((ref = target.nodeName) === 'INPUT' || ref === 'TEXTAREA') { - if (!(/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(key) && !/^Alt\+(\d|Up|Down|Left|Right)$/.test(key))) { - return; - } - } - if ((ref1 = g.VIEW) === 'index' || ref1 === 'thread') { - threadRoot = Nav.getThread(); - thread = Get.threadFromRoot(threadRoot); - } - switch (key) { - case Conf['Toggle board list']: - if (!Conf['Custom Board Navigation']) { - return; - } - Header.toggleBoardList(); - break; - case Conf['Toggle header']: - Header.toggleBarVisibility(); - break; - case Conf['Open empty QR']: - if (!QR.postingIsEnabled) { - return; - } - Keybinds.qr(); - break; - case Conf['Open QR']: - if (!(QR.postingIsEnabled && threadRoot)) { - return; - } - Keybinds.qr(threadRoot); - break; - case Conf['Open settings']: - Settings.open(); - break; - case Conf['Close']: - if (Settings.dialog) { - Settings.close(); - } else if ((notifications = $$('.notification')).length) { - for (i = 0, len = notifications.length; i < len; i++) { - notification = notifications[i]; - $('.close', notification).click(); - } - } else if (QR.nodes && !(QR.nodes.el.hidden || window.getComputedStyle(QR.nodes.form).display === 'none')) { - if (Conf['Persistent QR']) { - QR.hide(); - } else { - QR.close(); - } - } else if (Embedding.lastEmbed) { - Embedding.closeFloat(); - } else { - return; - } - break; - case Conf['Spoiler tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('spoiler', target); - break; - case Conf['Code tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('code', target); - break; - case Conf['Eqn tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('eqn', target); - break; - case Conf['Math tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('math', target); - break; - case Conf['SJIS tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('sjis', target); - break; - case Conf['Toggle sage']: - if (!(QR.nodes && !QR.nodes.el.hidden)) { - return; - } - Keybinds.sage(); - break; - case Conf['Toggle Cooldown']: - if (!(QR.nodes && !QR.nodes.el.hidden && $.hasClass(QR.nodes.fileSubmit, 'custom-cooldown'))) { - return; - } - QR.toggleCustomCooldown(); - break; - case Conf['Post from URL']: - if (!QR.postingIsEnabled) { - return; - } - QR.handleUrl(''); - break; - case Conf['Add new post']: - if (!QR.postingIsEnabled) { - return; - } - QR.addPost(); - break; - case Conf['Submit QR']: - if (!(QR.nodes && !QR.nodes.el.hidden)) { - return; - } - if (!QR.status()) { - QR.submit(); - } - break; - case Conf['Update']: - switch (g.VIEW) { - case 'thread': - if (!ThreadUpdater.enabled) { - return; - } - ThreadUpdater.update(); - break; - case 'index': - if (!Index.enabled) { - return; - } - Index.update(); - break; - default: - return; - } - break; - case Conf['Watch']: - if (!(ThreadWatcher.enabled && thread)) { - return; - } - ThreadWatcher.toggle(thread); - break; - case Conf['Update thread watcher']: - if (!ThreadWatcher.enabled) { - return; - } - ThreadWatcher.buttonFetchAll(); - break; - case Conf['Toggle thread watcher']: - if (!ThreadWatcher.enabled) { - return; - } - ThreadWatcher.toggleWatcher(); - break; - case Conf['Toggle threading']: - if (!QuoteThreading.ready) { - return; - } - QuoteThreading.toggleThreading(); - break; - case Conf['Mark thread read']: - if (!(g.VIEW === 'index' && thread && UnreadIndex.enabled)) { - return; - } - UnreadIndex.markRead.call(threadRoot); - break; - case Conf['Expand image']: - if (!(ImageExpand.enabled && threadRoot)) { - return; - } - post = Get.postFromNode(Keybinds.post(threadRoot)); - if (post.file) { - ImageExpand.toggle(post); - } - break; - case Conf['Expand images']: - if (!ImageExpand.enabled) { - return; - } - ImageExpand.cb.toggleAll(); - break; - case Conf['Open Gallery']: - if (!Gallery.enabled) { - return; - } - Gallery.cb.toggle(); - break; - case Conf['fappeTyme']: - if (!((ref2 = FappeTyme.nodes) != null ? ref2.fappe : void 0)) { - return; - } - FappeTyme.toggle('fappe'); - break; - case Conf['werkTyme']: - if (!((ref3 = FappeTyme.nodes) != null ? ref3.werk : void 0)) { - return; - } - FappeTyme.toggle('werk'); - break; - case Conf['Front page']: - if (Index.enabled) { - Index.userPageNav(1); - } else { - location.href = "/" + g.BOARD + "/"; - } - break; - case Conf['Open front page']: - $.open(location.origin + "/" + g.BOARD + "/"); - break; - case Conf['Next page']: - if (!(g.VIEW === 'index' && !(typeof (base = g.SITE).isOnePage === "function" ? base.isOnePage(g.BOARD) : void 0))) { - return; - } - if (Index.enabled) { - if ((ref4 = Conf['Index Mode']) !== 'paged' && ref4 !== 'infinite') { - return; - } - $('.next button', Index.pagelist).click(); - } else { - if ((ref5 = $(g.SITE.selectors.nav.next)) != null) { - ref5.click(); - } - } - break; - case Conf['Previous page']: - if (!(g.VIEW === 'index' && !(typeof (base1 = g.SITE).isOnePage === "function" ? base1.isOnePage(g.BOARD) : void 0))) { - return; - } - if (Index.enabled) { - if ((ref6 = Conf['Index Mode']) !== 'paged' && ref6 !== 'infinite') { - return; - } - $('.prev button', Index.pagelist).click(); - } else { - if ((ref7 = $(g.SITE.selectors.nav.prev)) != null) { - ref7.click(); - } - } - break; - case Conf['Search form']: - if (g.VIEW !== 'index') { - return; - } - searchInput = Index.enabled ? Index.searchInput : g.SITE.selectors.searchBox ? $(g.SITE.selectors.searchBox) : void 0; - if (!searchInput) { - return; - } - Header.scrollToIfNeeded(searchInput); - searchInput.focus(); - break; - case Conf['Paged mode']: - if (!Index.enabledOn(g.BOARD)) { - return; - } - location.href = g.VIEW === 'index' ? '#paged' : "/" + g.BOARD + "/#paged"; - break; - case Conf['Infinite scrolling mode']: - if (!Index.enabledOn(g.BOARD)) { - return; - } - location.href = g.VIEW === 'index' ? '#infinite' : "/" + g.BOARD + "/#infinite"; - break; - case Conf['All pages mode']: - if (!Index.enabledOn(g.BOARD)) { - return; - } - location.href = g.VIEW === 'index' ? '#all-pages' : "/" + g.BOARD + "/#all-pages"; - break; - case Conf['Open catalog']: - if (!(catalog = CatalogLinks.catalog())) { - return; - } - location.href = catalog; - break; - case Conf['Cycle sort type']: - if (!Index.enabled) { - return; - } - Index.cycleSortType(); - break; - case Conf['Next thread']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - Nav.scroll(+1); - break; - case Conf['Previous thread']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - Nav.scroll(-1); - break; - case Conf['Expand thread']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - ExpandThread.toggle(thread); - Header.scrollTo(threadRoot); - break; - case Conf['Open thread']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - Keybinds.open(thread); - break; - case Conf['Open thread tab']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - Keybinds.open(thread, true); - break; - case Conf['Next reply']: - if (!threadRoot) { - return; - } - Keybinds.hl(+1, threadRoot); - break; - case Conf['Previous reply']: - if (!threadRoot) { - return; - } - Keybinds.hl(-1, threadRoot); - break; - case Conf['Deselect reply']: - if (!threadRoot) { - return; - } - Keybinds.hl(0, threadRoot); - break; - case Conf['Hide']: - if (!(thread && ThreadHiding.db)) { - return; - } - Header.scrollTo(threadRoot); - ThreadHiding.toggle(thread); - break; - case Conf['Quick Filter MD5']: - if (!threadRoot) { - return; - } - post = Keybinds.post(threadRoot); - Keybinds.hl(+1, threadRoot); - Filter.quickFilterMD5.call(post, e); - break; - case Conf['Previous Post Quoting You']: - if (!(threadRoot && QuoteYou.db)) { - return; - } - QuoteYou.cb.seek('preceding'); - break; - case Conf['Next Post Quoting You']: - if (!(threadRoot && QuoteYou.db)) { - return; - } - QuoteYou.cb.seek('following'); - break; - default: - return; - } - e.preventDefault(); - return e.stopPropagation(); - }, - keyCode: function(e) { - var kc, key; - key = (function() { - switch (kc = 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: - if ((48 <= kc && kc <= 57) || (65 <= kc && kc <= 90)) { - return String.fromCharCode(kc).toLowerCase(); - } else if ((96 <= kc && kc <= 105)) { - return String.fromCharCode(kc - 48).toLowerCase(); - } else { - return null; - } - } - })(); - if (key) { - if (e.altKey) { - key = 'Alt+' + key; - } - if (e.ctrlKey) { - key = 'Ctrl+' + key; - } - if (e.metaKey) { - key = 'Meta+' + key; - } - if (e.shiftKey) { - key = 'Shift+' + key; - } - } - return key; - }, - post: function(thread) { - var s; - s = g.SITE.selectors; - return $("" + s.postContainer + s.highlightable.reply + "." + g.SITE.classes.highlight, thread) || $("" + (g.SITE.isOPContainerThread ? s.thread : s.postContainer) + s.highlightable.op, thread); - }, - qr: function(thread) { - QR.open(); - if (thread != null) { - QR.quote.call(Keybinds.post(thread)); - } - return QR.nodes.com.focus(); - }, - tags: function(tag, ta) { - var range, selEnd, selStart, value; - BoardConfig.ready(function() { - var config, supported; - config = g.BOARD.config; - supported = (function() { - switch (tag) { - case 'spoiler': - return !!config.spoilers; - case 'code': - return !!config.code_tags; - case 'math': - case 'eqn': - return !!config.math_tags; - case 'sjis': - return !!config.sjis_tags; - } - })(); - if (!supported) { - return new Notice('warning', "[" + tag + "] tags are not supported on /" + g.BOARD + "/.", 20); - } - }); - value = ta.value; - selStart = ta.selectionStart; - selEnd = ta.selectionEnd; - ta.value = value.slice(0, selStart) + ("[" + tag + "]") + value.slice(selStart, selEnd) + ("[/" + tag + "]") + value.slice(selEnd); - range = ("[" + tag + "]").length + selEnd; - ta.setSelectionRange(range, range); - return $.event('input', null, ta); - }, - sage: function() { - var isSage; - isSage = /sage/i.test(QR.nodes.email.value); - return QR.nodes.email.value = isSage ? "" : "sage"; - }, - open: function(thread, tab) { - var url; - if (g.VIEW !== 'index') { - return; - } - url = Get.url('thread', thread); - if (tab) { - return $.open(url); - } else { - return location.href = url; - } - }, - hl: function(delta, thread) { - var axis, height, highlight, i, len, next, postEl, replies, reply, replySelector, root; - replySelector = "" + g.SITE.selectors.postContainer + g.SITE.selectors.highlightable.reply; - highlight = g.SITE.classes.highlight; - postEl = $(replySelector + "." + highlight, thread); - if (!delta) { - if (postEl) { - $.rmClass(postEl, highlight); - } - return; - } - if (postEl) { - height = postEl.getBoundingClientRect().height; - if (Header.getTopOf(postEl) >= -height && Header.getBottomOf(postEl) >= -height) { - root = Get.postFromNode(postEl).nodes.root; - axis = delta === +1 ? 'following' : 'preceding'; - if (!(next = $.x(axis + "-sibling::" + g.SITE.xpath.replyContainer + "[not(@hidden) and not(child::div[@class='stub'])][1]", root))) { - return; - } - if (!next.matches(replySelector)) { - next = $(replySelector, next); - } - Header.scrollToIfNeeded(next, delta === +1); - $.addClass(next, highlight); - $.rmClass(postEl, highlight); - return; - } - $.rmClass(postEl, highlight); - } - replies = $$(replySelector, thread); - if (delta === -1) { - replies.reverse(); - } - for (i = 0, len = replies.length; i < len; i++) { - reply = replies[i]; - if (delta === +1 && Header.getTopOf(reply) > 0 || delta === -1 && Header.getBottomOf(reply) > 0) { - $.addClass(reply, highlight); - return; - } - } - } - }; - - return Keybinds; - -}).call(this); - -ModContact = (function() { - var ModContact; - - ModContact = { - init: function() { - var ref; - if (!(g.SITE.software === 'yotsuba' && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - return Callbacks.Post.push({ - name: 'Mod Contact Links', - cb: this.node - }); - }, - node: function() { - var links, moveNote, moved; - if (this.isClone || !$.hasOwn(ModContact.specific, this.info.capcode)) { - return; - } - links = $.el('span', { - className: 'contact-links brackets-wrap' - }); - $.extend(links, ModContact.template(this.info.capcode)); - $.after(this.nodes.capcode, links); - if ((moved = this.info.comment.match(/This thread was moved to >>>\/(\w+)\//)) && $.hasOwn(ModContact.moveNote, moved[1])) { - moveNote = $.el('div', { - className: 'move-note' - }); - $.extend(moveNote, ModContact.moveNote[moved[1]]); - return $.add(this.nodes.post, moveNote); - } - }, - template: function(capcode) { - return {innerHTML: "feedback" + (ModContact.specific[capcode]()).innerHTML}; - }, - specific: { - Mod: function() { - return {innerHTML: " IRC"}; - }, - Manager: function() { - return ModContact.specific.Mod(); - }, - Developer: function() { - return {innerHTML: " github"}; - }, - Admin: function() { - return {innerHTML: " twitter"}; - } - }, - moveNote: { - qa: {innerHTML: "Moving a thread to /qa/ does not imply mods will read it. If you wish to contact mods, use feedback (https://www.4chan.org/feedback) or IRC (https://www.4chan-x.net/4chan-irc.html)."} - } - }; - - return ModContact; - -}).call(this); - -Nav = (function() { - var Nav; - - Nav = { - init: function() { - var append, next, prev, span; - switch (g.VIEW) { - case 'index': - if (!Conf['Index Navigation']) { - return; - } - break; - case 'thread': - if (!Conf['Reply Navigation']) { - return; - } - break; - default: - return; - } - span = $.el('span', { - id: 'navlinks' - }); - prev = $.el('a', { - textContent: '▲', - href: 'javascript:;' - }); - next = $.el('a', { - textContent: '▼', - href: 'javascript:;' - }); - $.on(prev, 'click', this.prev); - $.on(next, 'click', this.next); - $.add(span, [prev, $.tn(' '), next]); - append = function() { - $.off(d, '4chanXInitFinished', append); - return $.add(d.body, span); - }; - return $.on(d, '4chanXInitFinished', append); - }, - prev: function() { - if (g.VIEW === 'thread') { - return window.scrollTo(0, 0); - } else { - return Nav.scroll(-1); - } - }, - next: function() { - if (g.VIEW === 'thread') { - return window.scrollTo(0, d.body.scrollHeight); - } else { - return Nav.scroll(+1); - } - }, - getThread: function() { - var i, len, ref, thread, threadRoot; - if (g.VIEW === 'thread') { - return g.threads.get(g.BOARD + "." + g.THREADID).nodes.root; - } - if ($.hasClass(doc, 'catalog-mode')) { - return; - } - ref = $$(g.SITE.selectors.thread); - for (i = 0, len = ref.length; i < len; i++) { - threadRoot = ref[i]; - thread = Get.threadFromRoot(threadRoot); - if (thread.isHidden && !thread.stub) { - continue; - } - if (Header.getTopOf(threadRoot) >= -threadRoot.getBoundingClientRect().height) { - return threadRoot; - } - } - }, - scroll: function(delta) { - var axis, extra, next, ref, thread, top; - if ((ref = d.activeElement) != null) { - ref.blur(); - } - thread = Nav.getThread(); - if (!thread) { - return; - } - axis = delta === +1 ? 'following' : 'preceding'; - if (next = $.x(axis + "-sibling::" + g.SITE.xpath.thread + "[not(@hidden)][1]", thread)) { - top = Header.getTopOf(thread); - if (delta === +1 && top < 5 || delta === -1 && top > -5) { - thread = next; - } - } - extra = Header.getTopOf(thread) + doc.clientHeight - d.body.getBoundingClientRect().bottom; - if (extra > 0) { - d.body.style.marginBottom = extra + "px"; - } - Header.scrollTo(thread); - if (extra > 0 && !Nav.haveExtra) { - Nav.haveExtra = true; - return $.on(d, 'scroll', Nav.removeExtra); - } - }, - removeExtra: function() { - var extra; - extra = doc.clientHeight - d.body.getBoundingClientRect().bottom; - if (extra > 0) { - return d.body.style.marginBottom = extra + "px"; - } else { - d.body.style.marginBottom = ''; - delete Nav.haveExtra; - return $.off(d, 'scroll', Nav.removeExtra); - } - } - }; - - return Nav; - -}).call(this); - -NormalizeURL = (function() { - var NormalizeURL; - - NormalizeURL = { - init: function() { - var pathname; - if (!Conf['Normalize URL']) { - return; - } - pathname = location.pathname.split(/\/+/); - if (g.SITE.software === 'yotsuba') { - switch (g.VIEW) { - case 'thread': - pathname[2] = 'thread'; - pathname = pathname.slice(0, 4); - break; - case 'index': - pathname = pathname.slice(0, 3); - } - } - pathname = pathname.join('/'); - if (location.pathname !== pathname) { - return history.replaceState(history.state, '', location.protocol + "//" + location.host + pathname + location.hash); - } - } - }; - - return NormalizeURL; - -}).call(this); - -PSA = (function() { - var PSA, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - PSA = { - init: function() { - var announcement, el; - if (g.SITE.software === 'yotsuba' && g.BOARD.ID === 'qa') { - announcement = { - innerHTML: "Stay in touch with your /qa/ friends!" - }; - el = $.el('div', { - className: 'fcx-announcement' - }, announcement); - $.onExists(doc, '.boardBanner', function(banner) { - return $.after(banner, el); - }); - } - if ('samachan.org' in Conf['siteProperties'] && indexOf.call(Conf['PSAseen'], 'samachan') < 0) { - el = $.el('span', { - innerHTML: "Looking for a new home?
      Some former Samachan users are regrouping on SushiChan.

      (a message from 4chan X)" - }); - return Main.ready(function() { - new Notice('info', el); - Conf['PSAseen'].push('samachan'); - return $.set('PSAseen', Conf['PSAseen']); - }); - } - } - }; - - return PSA; - -}).call(this); - -PSAHiding = (function() { - var PSAHiding, - slice = [].slice; - - PSAHiding = { - init: function() { - if (!(Conf['Announcement Hiding'] && g.SITE.selectors.psa)) { - return; - } - $.addClass(doc, 'hide-announcement'); - $.onExists(doc, g.SITE.selectors.psa, this.setup); - return $.ready(function() { - if (!$(g.SITE.selectors.psa)) { - return $.rmClass(doc, 'hide-announcement'); - } - }); - }, - setup: function(psa) { - var btn, entry, hr, ref, ref1, ref2; - PSAHiding.psa = psa; - PSAHiding.text = (ref = psa.dataset.utc) != null ? ref : psa.innerHTML; - if (g.SITE.selectors.psaTop && (hr = (ref1 = $(g.SITE.selectors.psaTop)) != null ? ref1.previousElementSibling : void 0) && hr.nodeName === 'HR') { - PSAHiding.hr = hr; - } - PSAHiding.content = $.el('div'); - entry = { - el: $.el('a', { - textContent: 'Show announcement', - className: 'show-announcement', - href: 'javascript:;' - }), - order: 50, - open: function() { - return psa.hidden; - } - }; - Header.menu.addEntry(entry); - $.on(entry.el, 'click', PSAHiding.toggle); - PSAHiding.btn = btn = $.el('a', { - title: 'Mark announcement as read and hide.', - className: 'hide-announcement-button fa fa-minus-square', - href: 'javascript:;' - }); - $.on(btn, 'click', PSAHiding.toggle); - if (((ref2 = psa.firstChild) != null ? ref2.tagName : void 0) === 'HR') { - $.after(psa.firstChild, btn); - } else { - $.prepend(psa, btn); - } - PSAHiding.sync(Conf['hiddenPSAList']); - $.rmClass(doc, 'hide-announcement'); - return $.sync('hiddenPSAList', PSAHiding.sync); - }, - toggle: function() { - var hide, set; - hide = $.hasClass(this, 'hide-announcement-button'); - set = function(hiddenPSAList) { - if (hide) { - return hiddenPSAList[g.SITE.ID] = PSAHiding.text; - } else { - return delete hiddenPSAList[g.SITE.ID]; - } - }; - set(Conf['hiddenPSAList']); - PSAHiding.sync(Conf['hiddenPSAList']); - return $.get('hiddenPSAList', Conf['hiddenPSAList'], function(arg) { - var hiddenPSAList; - hiddenPSAList = arg.hiddenPSAList; - set(hiddenPSAList); - return $.set('hiddenPSAList', hiddenPSAList); - }); - }, - sync: function(hiddenPSAList) { - var content, psa, ref; - psa = PSAHiding.psa, content = PSAHiding.content; - psa.hidden = hiddenPSAList[g.SITE.ID] === PSAHiding.text; - if (psa.hidden) { - $.add(content, slice.call(psa.childNodes)); - } else { - $.add(psa, slice.call(content.childNodes)); - } - return (ref = PSAHiding.hr) != null ? ref.hidden = psa.hidden : void 0; - } - }; - - return PSAHiding; - -}).call(this); - -PassMessage = (function() { - var PassMessage; - - PassMessage = { - init: function() { - var close, msg; - if (Conf['passMessageClosed']) { - return; - } - msg = $.el('div', { - className: 'box-outer top-box' - }, {innerHTML: "

      Trouble buying a 4chan Pass? (a message from 4chan X) ×

      Check the 4chan X wiki for alternative solutions.
      "}); - msg.style.cssText = 'padding-bottom: 0;'; - close = $('a', msg); - $.on(close, 'click', function() { - $.rm(msg); - return $.set('passMessageClosed', true); - }); - return $.ready(function() { - var hd; - if ((hd = $.id('hd'))) { - return $.after(hd, msg); - } else { - return $.prepend(d.body, msg); - } - }); - } - }; - - return PassMessage; - -}).call(this); - -PostJumper = (function() { - var PostJumper; - - PostJumper = { - init: function() { - var ref; - if (!(Conf['Unique ID and Capcode Navigation'] && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - this.buttons = this.makeButtons(); - return Callbacks.Post.push({ - name: 'Post Jumper', - cb: this.node - }); - }, - node: function() { - var buttons, i, len, ref; - if (this.isClone) { - ref = $$('.postJumper', this.nodes.info); - for (i = 0, len = ref.length; i < len; i++) { - buttons = ref[i]; - PostJumper.addListeners(buttons); - } - return; - } - if (this.nodes.uniqueIDRoot) { - PostJumper.addButtons(this, 'uniqueID'); - } - if (this.nodes.capcode) { - return PostJumper.addButtons(this, 'capcode'); - } - }, - addButtons: function(post, type) { - var buttons, value; - value = post.info[type]; - buttons = PostJumper.buttons.cloneNode(true); - $.extend(buttons.dataset, { - type: type, - value: value - }); - $.after(post.nodes[type + (type === 'capcode' ? '' : 'Root')], buttons); - return PostJumper.addListeners(buttons); - }, - addListeners: function(buttons) { - $.on(buttons.firstChild, 'click', PostJumper.buttonClick); - return $.on(buttons.lastChild, 'click', PostJumper.buttonClick); - }, - buttonClick: function() { - var dir, toJumper; - dir = $.hasClass(this, 'prev') ? -1 : 1; - if ((toJumper = PostJumper.find(this.parentNode, dir))) { - return PostJumper.scroll(this.parentNode, toJumper); - } - }, - find: function(jumper, dir) { - var axis, jumper2, ref, type, value, xpath; - ref = jumper.dataset, type = ref.type, value = ref.value; - xpath = "span[contains(@class,\"postJumper\") and @data-value=\"" + value + "\" and @data-type=\"" + type + "\"]"; - axis = dir < 0 ? 'preceding' : 'following'; - jumper2 = jumper; - while ((jumper2 = $.x(axis + "::" + xpath, jumper2))) { - if (jumper2.getBoundingClientRect().height) { - return jumper2; - } - } - if ((jumper2 = $.x("(//" + xpath + ")[" + (dir < 0 ? 'last()' : '1') + "]"))) { - if (jumper2.getBoundingClientRect().height) { - return jumper2; - } - } - while ((jumper2 = $.x(axis + "::" + xpath, jumper2)) && jumper2 !== jumper) { - if (jumper2.getBoundingClientRect().height) { - return jumper2; - } - } - return null; - }, - makeButtons: function() { - var charNext, charPrev, classNext, classPrev, span; - charPrev = '\u23EB'; - charNext = '\u23EC'; - classPrev = 'prev'; - classNext = 'next'; - span = $.el('span', { - className: 'postJumper' - }); - $.extend(span, {innerHTML: "" + E(charPrev) + "" + E(charNext) + ""}); - return span; - }, - scroll: function(fromJumper, toJumper) { - var destPos, prevPos; - prevPos = fromJumper.getBoundingClientRect().top; - destPos = toJumper.getBoundingClientRect().top; - return window.scrollBy(0, destPos - prevPos); - } - }; - - return PostJumper; - -}).call(this); - -RelativeDates = (function() { - var RelativeDates, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - RelativeDates = { - INTERVAL: $.MINUTE / 2, - init: function() { - var ref; - if (((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Relative Post Dates'] && !Conf['Relative Date Title'] || Index.enabled) { - this.flush(); - $.on(d, 'visibilitychange PostsInserted', this.flush); - } - if (Conf['Relative Post Dates']) { - return Callbacks.Post.push({ - name: 'Relative Post Dates', - cb: this.node - }); - } - }, - node: function() { - var dateEl; - if (!this.info.date) { - return; - } - dateEl = this.nodes.date; - if (Conf['Relative Date Title']) { - $.on(dateEl, 'mouseover', (function(_this) { - return function() { - return RelativeDates.hover(_this); - }; - })(this)); - return; - } - if (this.isClone) { - return; - } - dateEl.title = dateEl.textContent; - return RelativeDates.update(this); - }, - relative: function(diff, now, date, abbrev) { - var days, months, number, rounded, unit, years; - unit = (number = diff / $.DAY) >= 1 ? (years = now.getFullYear() - date.getFullYear(), months = now.getMonth() - date.getMonth(), days = now.getDate() - date.getDate(), years > 1 ? (number = years - (months < 0 || months === 0 && days < 0), 'year') : years === 1 && (months > 0 || months === 0 && days >= 0) ? (number = years, 'year') : (months = months + 12 * years) > 1 ? (number = months - (days < 0), 'month') : months === 1 && days >= 0 ? (number = months, 'month') : 'day') : (number = diff / $.HOUR) >= 1 ? 'hour' : (number = diff / $.MINUTE) >= 1 ? 'minute' : (number = Math.max(0, diff) / $.SECOND, 'second'); - rounded = Math.round(number); - if (abbrev) { - unit = unit === 'month' ? 'mo' : unit[0]; - } else { - if (rounded !== 1) { - unit += 's'; - } - } - if (abbrev) { - return "" + rounded + unit; - } else { - return rounded + " " + unit + " ago"; - } - }, - stale: [], - flush: function() { - var data, i, len, now, ref; - if (d.hidden) { - return; - } - now = new Date(); - ref = RelativeDates.stale; - for (i = 0, len = ref.length; i < len; i++) { - data = ref[i]; - RelativeDates.update(data, now); - } - RelativeDates.stale = []; - clearTimeout(RelativeDates.timeout); - return RelativeDates.timeout = setTimeout(RelativeDates.flush, RelativeDates.INTERVAL); - }, - hover: function(post) { - var date, diff, now; - date = post.info.date; - now = new Date(); - diff = now - date; - return post.nodes.date.title = RelativeDates.relative(diff, now, date); - }, - update: function(data, now) { - var abbrev, date, diff, i, isPost, len, ref, relative, singlePost; - isPost = data instanceof Post; - if (isPost) { - date = data.info.date; - abbrev = false; - } else { - date = new Date(+data.dataset.utc); - abbrev = !!data.dataset.abbrev; - } - now || (now = new Date()); - diff = now - date; - relative = RelativeDates.relative(diff, now, date, abbrev); - if (isPost) { - ref = [data].concat(data.clones); - for (i = 0, len = ref.length; i < len; i++) { - singlePost = ref[i]; - singlePost.nodes.date.firstChild.textContent = relative; - } - } else { - data.firstChild.textContent = relative; - } - return RelativeDates.setOwnTimeout(diff, data); - }, - setOwnTimeout: function(diff, data) { - var delay; - delay = diff < $.MINUTE ? $.SECOND - (diff + $.SECOND / 2) % $.SECOND : diff < $.HOUR ? $.MINUTE - (diff + $.MINUTE / 2) % $.MINUTE : diff < $.DAY ? $.HOUR - (diff + $.HOUR / 2) % $.HOUR : $.DAY - (diff + $.DAY / 2) % $.DAY; - return setTimeout(RelativeDates.markStale, delay, data); - }, - markStale: function(data) { - if (indexOf.call(RelativeDates.stale, data) >= 0) { - return; - } - if (data instanceof Post && !g.posts.get(data.fullID)) { - return; - } - if (data instanceof Element && !doc.contains(data)) { - return; - } - return RelativeDates.stale.push(data); - } - }; - - return RelativeDates; - -}).call(this); - -RemoveSpoilers = (function() { - var RemoveSpoilers, - slice = [].slice; - - RemoveSpoilers = { - init: function() { - if (Conf['Reveal Spoilers']) { - $.addClass(doc, 'reveal-spoilers'); - } - if (!Conf['Remove Spoilers']) { - return; - } - Callbacks.Post.push({ - name: 'Reveal Spoilers', - cb: this.node - }); - if (g.VIEW === 'archive') { - return $.ready(function() { - return RemoveSpoilers.unspoiler($.id('arc-list')); - }); - } - }, - node: function() { - return RemoveSpoilers.unspoiler(this.nodes.comment); - }, - unspoiler: function(el) { - var i, len, span, spoiler, spoilers; - spoilers = $$(g.SITE.selectors.spoiler, el); - for (i = 0, len = spoilers.length; i < len; i++) { - spoiler = spoilers[i]; - span = $.el('span', { - className: 'removed-spoiler' - }); - $.replace(spoiler, span); - $.add(span, slice.call(spoiler.childNodes)); - } - } - }; - - return RemoveSpoilers; - -}).call(this); - -Report = (function() { - var Report; - - Report = { - init: function() { - var match; - if (!(match = location.search.match(/\bno=(\d+)/))) { - return; - } - Captcha.replace.init(); - this.postID = +match[1]; - return $.ready(this.ready); - }, - ready: function() { - $.addStyle(CSS.report); - if (Conf['Archive Report']) { - Report.archive(); - } - new MutationObserver(function() { - Report.fit('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); - return Report.fit('body'); - }).observe(d.body, { - childList: true, - attributes: true, - subtree: true - }); - return Report.fit('body'); - }, - fit: function(selector) { - var dy, el; - if (!((el = $(selector, doc)) && getComputedStyle(el).visibility !== 'hidden')) { - return; - } - dy = el.getBoundingClientRect().bottom - doc.clientHeight + 8; - if (dy > 0) { - return window.resizeBy(0, dy); - } - }, - archive: function() { - var enabled, fieldset, form, match, message, reason, submit, types, urls; - if (!(urls = Redirect.report(g.BOARD.ID)).length) { - return; - } - form = $('form'); - types = $.id('reportTypes'); - message = $('h3'); - fieldset = $.el('fieldset', { - id: 'archive-report', - hidden: true - }, {innerHTML: ""}); - enabled = $('#archive-report-enabled', fieldset); - reason = $('#archive-report-reason', fieldset); - submit = $('#archive-report-submit', fieldset); - $.on(enabled, 'change', function() { - return reason.disabled = !this.checked; - }); - if (form && types) { - fieldset.hidden = !$('[value="31"]', types).checked; - $.on(types, 'change', function(e) { - fieldset.hidden = e.target.value !== '31'; - return Report.fit('body'); - }); - $.after(types, fieldset); - Report.fit('body'); - $.one(form, 'submit', function(e) { - if (!fieldset.hidden && enabled.checked) { - e.preventDefault(); - return Report.archiveSubmit(urls, reason.value, (function(_this) { - return function(results) { - _this.action = '#archiveresults=' + encodeURIComponent(JSON.stringify(results)); - return _this.submit(); - }; - })(this)); - } - }); - } else if (message) { - fieldset.hidden = /Report submitted!/.test(message.textContent); - $.on(enabled, 'change', function() { - return submit.hidden = !this.checked; - }); - $.after(message, fieldset); - $.on(submit, 'click', function() { - return Report.archiveSubmit(urls, reason.value, Report.archiveResults); - }); - } - if ((match = location.hash.match(/^#archiveresults=(.*)$/))) { - try { - return Report.archiveResults(JSON.parse(decodeURIComponent(match[1]))); - } catch (error) {} - } - }, - archiveSubmit: function(urls, reason, cb) { - var fn, form, i, len, name, ref, results, url; - form = $.formData({ - board: g.BOARD.ID, - num: Report.postID, - reason: reason - }); - results = []; - fn = function(name, url) { - return $.ajax(url, { - onloadend: function() { - results.push([ - name, this.response || { - error: '' - } - ]); - if (results.length === urls.length) { - return cb(results); - } - }, - form: form - }); - }; - for (i = 0, len = urls.length; i < len; i++) { - ref = urls[i], name = ref[0], url = ref[1]; - fn(name, url); - } - }, - archiveResults: function(results) { - var fieldset, i, len, line, name, ref, response; - fieldset = $.id('archive-report'); - for (i = 0, len = results.length; i < len; i++) { - ref = results[i], name = ref[0], response = ref[1]; - line = $.el('h3', { - className: 'archive-report-response' - }); - if ('success' in response) { - $.addClass(line, 'archive-report-success'); - line.textContent = name + ": " + response.success; - } else { - $.addClass(line, 'archive-report-error'); - line.textContent = name + ": " + (response.error || 'Error reporting post.'); - } - if (fieldset) { - $.before(fieldset, line); - } else { - $.add(d.body, line); - } - } - } - }; - - return Report; - -}).call(this); - -ThreadLinks = (function() { - var ThreadLinks; - - ThreadLinks = { - init: function() { - if (!(g.VIEW === 'index' && Conf['Open Threads in New Tab'])) { - return; - } - Callbacks.Post.push({ - name: 'Thread Links', - cb: this.node - }); - return Callbacks.CatalogThread.push({ - name: 'Thread Links', - cb: this.catalogNode - }); - }, - node: function() { - if (this.isReply || this.isClone) { - return; - } - return ThreadLinks.process(this.nodes.reply); - }, - catalogNode: function() { - return ThreadLinks.process(this.nodes.thumb.parentNode); - }, - process: function(link) { - return link.target = '_blank'; - } - }; - - return ThreadLinks; - -}).call(this); - -Time = (function() { - var Time; - - Time = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Time Formatting'])) { - return; - } - return Callbacks.Post.push({ - name: 'Time Formatting', - cb: this.node - }); - }, - node: function() { - var textContent; - if (!this.info.date || this.isClone) { - return; - } - textContent = this.nodes.date.textContent; - return this.nodes.date.textContent = textContent.match(/^\s*/)[0] + Time.format(Conf['time'], this.info.date) + textContent.match(/\s*$/)[0]; - }, - format: function(formatString, date) { - return formatString.replace(/%(.)/g, function(s, c) { - if ($.hasOwn(Time.formatters, c)) { - return Time.formatters[c].call(date); - } else { - return s; - } - }); - }, - day: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - month: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], - localeFormat: function(date, options, defaultValue) { - if (Conf['timeLocale']) { - try { - return Intl.DateTimeFormat(Conf['timeLocale'], options).format(date); - } catch (error) {} - } - return defaultValue; - }, - localeFormatPart: function(date, options, part, defaultValue) { - var parts; - if (Conf['timeLocale']) { - try { - parts = Intl.DateTimeFormat(Conf['timeLocale'], options).formatToParts(date); - return parts.map(function(x) { - if (x.type === part) { - return x.value; - } else { - return ''; - } - }).join(''); - } catch (error) {} - } - return defaultValue; - }, - zeroPad: function(n) { - if (n < 10) { - return "0" + n; - } else { - return n; - } - }, - formatters: { - a: function() { - return Time.localeFormat(this, { - weekday: 'short' - }, Time.day[this.getDay()].slice(0, 3)); - }, - A: function() { - return Time.localeFormat(this, { - weekday: 'long' - }, Time.day[this.getDay()]); - }, - b: function() { - return Time.localeFormat(this, { - month: 'short' - }, Time.month[this.getMonth()].slice(0, 3)); - }, - B: function() { - return Time.localeFormat(this, { - month: 'long' - }, Time.month[this.getMonth()]); - }, - d: function() { - return Time.zeroPad(this.getDate()); - }, - e: function() { - return this.getDate(); - }, - H: function() { - return Time.zeroPad(this.getHours()); - }, - I: function() { - return Time.zeroPad(this.getHours() % 12 || 12); - }, - k: function() { - return this.getHours(); - }, - l: function() { - return this.getHours() % 12 || 12; - }, - m: function() { - return Time.zeroPad(this.getMonth() + 1); - }, - M: function() { - return Time.zeroPad(this.getMinutes()); - }, - p: function() { - return Time.localeFormatPart(this, { - hour: 'numeric', - hour12: true - }, 'dayperiod', (this.getHours() < 12 ? 'AM' : 'PM')); - }, - P: function() { - return Time.formatters.p.call(this).toLowerCase(); - }, - S: function() { - return Time.zeroPad(this.getSeconds()); - }, - y: function() { - return this.getFullYear().toString().slice(2); - }, - Y: function() { - return this.getFullYear(); - }, - '%': function() { - return '%'; - } - } - }; - - return Time; - -}).call(this); - -Tinyboard = (function() { - var Tinyboard; - - Tinyboard = { - init: function() { - if (g.SITE.software !== 'tinyboard') { - return; - } - if (g.VIEW === 'thread') { - return Main.ready(function() { - return $.global(function() { - var base, boardID, form, originalNoko, ref, ref1, ref2, threadID; - ref = document.currentScript.dataset, boardID = ref.boardID, threadID = ref.threadID; - threadID = +threadID; - form = document.querySelector('form[name="post"]'); - window.$(document).ajaxComplete(function(event, request, settings) { - var detail, noko, postID, redirect, ref1, ref2; - if (settings.url !== form.action) { - return; - } - if (!(postID = +((ref1 = request.responseJSON) != null ? ref1.id : void 0))) { - return; - } - detail = { - boardID: boardID, - threadID: threadID, - postID: postID - }; - try { - ref2 = request.responseJSON, redirect = ref2.redirect, noko = ref2.noko; - if (redirect && (typeof originalNoko !== "undefined" && originalNoko !== null) && !originalNoko && !noko) { - detail.redirect = redirect; - } - } catch (error) {} - event = new CustomEvent('QRPostSuccessful', { - bubbles: true, - detail: detail - }); - return document.dispatchEvent(event); - }); - originalNoko = (ref1 = window.tb_settings) != null ? (ref2 = ref1.ajax) != null ? ref2.always_noko_replies : void 0 : void 0; - return ((base = (window.tb_settings || (window.tb_settings = {}))).ajax || (base.ajax = {})).always_noko_replies = true; - }, { - boardID: g.BOARD.ID, - threadID: g.THREADID - }); - }); - } - } - }; - - return Tinyboard; - -}).call(this); - -Favicon = (function() { - var Favicon; - - Favicon = { - init: function() { - return $.asap((function() { - return d.head && (Favicon.el = $('link[rel="shortcut icon"]', d.head)); - }), Favicon.initAsap); - }, - set: function(status) { - Favicon.status = status; - if (Favicon.el) { - Favicon.el.href = Favicon[status]; - return $.add(d.head, Favicon.el); - } - }, - initAsap: function() { - var href; - Favicon.el.type = 'image/x-icon'; - href = Favicon.el.href; - Favicon.isSFW = /ws\.ico$/.test(href); - Favicon["default"] = href; - Favicon["switch"](); - if (Favicon.status) { - return Favicon.set(Favicon.status); - } - }, - "switch": function() { - var f, i, items, t; - items = { - 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: ['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'], - '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='] - }; - items = $.getOwn(items, Conf['favicon']); - f = Favicon; - t = 'data:image/png;base64,'; - i = 0; - while (items[i]) { - items[i] = t + items[i++]; - } - f.unreadDead = items[0], f.unreadDeadY = items[1], f.unreadSFW = items[2], f.unreadSFWY = items[3], f.unreadNSFW = items[4], f.unreadNSFWY = items[5]; - return f.update(); - }, - update: function() { - if (this.isSFW) { - this.unread = this.unreadSFW; - return this.unreadY = this.unreadSFWY; - } else { - this.unread = this.unreadNSFW; - return 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,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAgMAAAC+UIlYAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAGlJREFUWMPtlkEKADEIA/tJP9lXLttQto2yHxgDHozTi0ToGK2WKZZ+HAQQMZc+xBwI4EZ+wAC2IfPuSIDOZJrSZQEAX9eVJhhwIuUYAnQe8rhAEMAZlTI2MID9f5Clyh0JeE1V1ZEAvB4qDfwuJTSGRAAAAABJRU5ErkJggg==' - }; - - return Favicon; - -}).call(this); - -MarkNewIPs = (function() { - var MarkNewIPs; - - MarkNewIPs = { - init: function() { - if (!(g.SITE.software === 'yotsuba' && g.VIEW === 'thread' && Conf['Mark New IPs'])) { - return; - } - return Callbacks.Thread.push({ - name: 'Mark New IPs', - cb: this.node - }); - }, - node: function() { - MarkNewIPs.ipCount = this.ipCount; - MarkNewIPs.postCount = this.posts.keys.length; - return $.on(d, 'ThreadUpdate', MarkNewIPs.onUpdate); - }, - onUpdate: function(e) { - var deletedPosts, fullID, i, ipCount, j, k, len, len1, newPosts, postCount, ref; - ref = e.detail, ipCount = ref.ipCount, postCount = ref.postCount, newPosts = ref.newPosts, deletedPosts = ref.deletedPosts; - if (ipCount == null) { - return; - } - switch (ipCount - MarkNewIPs.ipCount) { - case postCount - MarkNewIPs.postCount + deletedPosts.length: - i = MarkNewIPs.ipCount; - for (j = 0, len = newPosts.length; j < len; j++) { - fullID = newPosts[j]; - MarkNewIPs.markNew(g.posts.get(fullID), ++i); - } - break; - case -deletedPosts.length: - for (k = 0, len1 = newPosts.length; k < len1; k++) { - fullID = newPosts[k]; - MarkNewIPs.markOld(g.posts.get(fullID)); - } - } - MarkNewIPs.ipCount = ipCount; - return MarkNewIPs.postCount = postCount; - }, - markNew: function(post, ipCount) { - var counter, suffix; - suffix = (Math.floor(ipCount / 10)) % 10 === 1 ? 'th' : ['st', 'nd', 'rd'][ipCount % 10 - 1] || 'th'; - counter = $.el('span', { - className: 'ip-counter', - textContent: "(" + ipCount + ")" - }); - post.nodes.nameBlock.title = "This is the " + ipCount + suffix + " IP in the thread."; - $.add(post.nodes.nameBlock, [$.tn(' '), counter]); - return $.addClass(post.nodes.root, 'new-ip'); - }, - markOld: function(post) { - post.nodes.nameBlock.title = 'Not the first post from this IP.'; - return $.addClass(post.nodes.root, 'old-ip'); - } - }; - - return MarkNewIPs; - -}).call(this); - -ReplyPruning = (function() { - var ReplyPruning; - - ReplyPruning = { - init: function() { - var el, label; - if (!(g.VIEW === 'thread' && Conf['Reply Pruning'])) { - return; - } - this.container = $.frag(); - this.summary = $.el('span', { - hidden: true, - className: 'summary' - }); - this.summary.style.cursor = 'pointer'; - $.on(this.summary, 'click', (function(_this) { - return function() { - _this.inputs.enabled.checked = !_this.inputs.enabled.checked; - return $.event('change', null, _this.inputs.enabled); - }; - })(this)); - label = UI.checkbox('Prune Replies', 'Show Last', Conf['Prune All Threads']); - el = $.el('span', { - title: 'Maximum number of replies to show.' - }, {innerHTML: " "}); - $.prepend(el, label); - this.inputs = { - enabled: label.firstElementChild, - replies: el.lastElementChild - }; - this.setEnabled.call(this.inputs.enabled); - $.on(this.inputs.enabled, 'change', this.setEnabled); - $.on(this.inputs.replies, 'change', $.cb.value); - Header.menu.addEntry({ - el: el, - order: 190 - }); - return Callbacks.Thread.push({ - name: 'Reply Pruning', - cb: this.node - }); - }, - position: 0, - hidden: 0, - hiddenFiles: 0, - total: 0, - totalFiles: 0, - setEnabled: function() { - var other; - other = QuoteThreading.input; - if (this.checked && (other != null ? other.checked : void 0)) { - other.checked = false; - $.event('change', null, other); - } - return ReplyPruning.active = this.checked; - }, - showIfHidden: function(id) { - if (ReplyPruning.container && $("#" + id, ReplyPruning.container)) { - ReplyPruning.inputs.enabled.checked = false; - return $.event('change', null, ReplyPruning.inputs.enabled); - } - }, - node: function() { - var ref; - ReplyPruning.thread = this; - if (this.isSticky) { - ReplyPruning.active = ReplyPruning.inputs.enabled.checked = true; - if (QuoteThreading.input) { - Conf['Thread Quotes'] = QuoteThreading.input.checked = false; - } - } - this.posts.forEach(function(post) { - if (post.isReply) { - ReplyPruning.total++; - if (post.file) { - return ReplyPruning.totalFiles++; - } - } - }); - if (ReplyPruning.active && /^#p\d+$/.test(location.hash) && (1 <= (ref = this.posts.keys.indexOf(location.hash.slice(2))) && ref < 1 + Math.max(ReplyPruning.total - +Conf["Max Replies"], 0))) { - ReplyPruning.active = ReplyPruning.inputs.enabled.checked = false; - } - $.after(this.OP.nodes.root, ReplyPruning.summary); - $.on(ReplyPruning.inputs.enabled, 'change', ReplyPruning.update); - $.on(ReplyPruning.inputs.replies, 'change', ReplyPruning.update); - $.on(d, 'ThreadUpdate', ReplyPruning.updateCount); - $.on(d, 'ThreadUpdate', ReplyPruning.update); - return ReplyPruning.update(); - }, - updateCount: function(e) { - var fullID, i, len, ref; - if (e.detail[404]) { - return; - } - ref = e.detail.newPosts; - for (i = 0, len = ref.length; i < len; i++) { - fullID = ref[i]; - ReplyPruning.total++; - if (g.posts.get(fullID).file) { - ReplyPruning.totalFiles++; - } - } - }, - update: function() { - var boardTop, frag, hidden1, hidden2, node, oldPos, post, posts; - hidden1 = ReplyPruning.hidden; - hidden2 = ReplyPruning.active ? Math.max(ReplyPruning.total - +Conf["Max Replies"], 0) : 0; - oldPos = d.body.clientHeight - window.scrollY; - posts = ReplyPruning.thread.posts; - if (ReplyPruning.hidden < hidden2) { - while (ReplyPruning.hidden < hidden2 && ReplyPruning.position < posts.keys.length) { - post = posts.get(posts.keys[ReplyPruning.position++]); - if (post.isReply && !post.isFetchedQuote) { - while ((node = ReplyPruning.summary.nextSibling) && node !== post.nodes.root) { - $.add(ReplyPruning.container, node); - } - $.add(ReplyPruning.container, post.nodes.root); - ReplyPruning.hidden++; - if (post.file) { - ReplyPruning.hiddenFiles++; - } - } - } - } else if (ReplyPruning.hidden > hidden2) { - frag = $.frag(); - while (ReplyPruning.hidden > hidden2 && ReplyPruning.position > 0) { - post = posts.get(posts.keys[--ReplyPruning.position]); - if (post.isReply && !post.isFetchedQuote) { - while ((node = ReplyPruning.container.lastChild) && node !== post.nodes.root) { - $.prepend(frag, node); - } - $.prepend(frag, post.nodes.root); - ReplyPruning.hidden--; - if (post.file) { - ReplyPruning.hiddenFiles--; - } - } - } - $.after(ReplyPruning.summary, frag); - $.event('PostsInserted', null, ReplyPruning.summary.parentNode); - } - ReplyPruning.summary.textContent = ReplyPruning.active ? g.SITE.Build.summaryText('+', ReplyPruning.hidden, ReplyPruning.hiddenFiles) : g.SITE.Build.summaryText('-', ReplyPruning.total, ReplyPruning.totalFiles); - ReplyPruning.summary.hidden = ReplyPruning.total <= +Conf["Max Replies"]; - if (hidden1 !== hidden2 && (boardTop = Header.getTopOf($('.board'))) < 0) { - return window.scrollBy(0, Math.max(d.body.clientHeight - oldPos, window.scrollY + boardTop) - window.scrollY); - } - } - }; - - return ReplyPruning; - -}).call(this); - -ThreadStats = (function() { - var ThreadStats; - - ThreadStats = { - postCount: 0, - fileCount: 0, - postIndex: 0, - init: function() { - var base, sc, statsHTML, statsTitle; - if (g.VIEW !== 'thread' || !Conf['Thread Stats']) { - return; - } - if (Conf['Page Count in Stats']) { - this[(typeof (base = g.SITE).isPrunedByAge === "function" ? base.isPrunedByAge(g.BOARD) : void 0) ? 'showPurgePos' : 'showPage'] = true; - } - statsHTML = {innerHTML: "? / ?" + ((Conf["IP Count in Stats"] && g.SITE.hasIPCount) ? " / ?" : "") + ((Conf["Page Count in Stats"]) ? " / ?" : "")}; - statsTitle = 'Posts / Files'; - if (Conf['IP Count in Stats'] && g.SITE.hasIPCount) { - statsTitle += ' / IPs'; - } - if (Conf['Page Count in Stats']) { - statsTitle += (this.showPurgePos ? ' / Purge Position' : ' / Page'); - } - if (Conf['Updater and Stats in Header']) { - this.dialog = sc = $.el('span', { - id: 'thread-stats', - title: statsTitle - }); - $.extend(sc, statsHTML); - Header.addShortcut('stats', sc, 200); - } else { - this.dialog = sc = UI.dialog('thread-stats', {innerHTML: "
      " + (statsHTML).innerHTML + "
      "}); - $.addClass(doc, 'float'); - $.ready(function() { - return $.add(d.body, sc); - }); - } - this.postCountEl = $('#post-count', sc); - this.fileCountEl = $('#file-count', sc); - this.ipCountEl = $('#ip-count', sc); - this.pageCountEl = $('#page-count', sc); - if (this.pageCountEl) { - $.on(this.pageCountEl, 'click', ThreadStats.fetchPage); - } - return Callbacks.Thread.push({ - name: 'Thread Stats', - cb: this.node - }); - }, - node: function() { - ThreadStats.thread = this; - ThreadStats.count(); - ThreadStats.update(); - ThreadStats.fetchPage(); - $.on(d, 'PostsInserted', function() { - return $.queueTask(ThreadStats.onPostsInserted); - }); - return $.on(d, 'ThreadUpdate', ThreadStats.onUpdate); - }, - count: function() { - var i, j, n, post, posts, ref, ref1; - posts = ThreadStats.thread.posts; - n = posts.keys.length; - for (i = j = ref = ThreadStats.postIndex, ref1 = n; j < ref1; i = j += 1) { - post = posts.get(posts.keys[i]); - if (!post.isFetchedQuote) { - ThreadStats.postCount++; - ThreadStats.fileCount += post.files.length; - } - } - return ThreadStats.postIndex = n; - }, - onUpdate: function(e) { - var fileCount, postCount, ref; - if (e.detail[404]) { - return; - } - ref = e.detail, postCount = ref.postCount, fileCount = ref.fileCount; - $.extend(ThreadStats, { - postCount: postCount, - fileCount: fileCount - }); - ThreadStats.postIndex = ThreadStats.thread.posts.keys.length; - ThreadStats.update(); - if (ThreadStats.showPage && ThreadStats.pageCountEl.textContent !== '1') { - return ThreadStats.fetchPage(); - } - }, - onPostsInserted: function() { - if (!(ThreadStats.thread.posts.keys.length > ThreadStats.postIndex)) { - return; - } - ThreadStats.count(); - ThreadStats.update(); - if (ThreadStats.showPage && ThreadStats.pageCountEl.textContent !== '1') { - return ThreadStats.fetchPage(); - } - }, - update: function() { - var fileCountEl, ipCountEl, postCountEl, ref, thread; - thread = ThreadStats.thread, postCountEl = ThreadStats.postCountEl, fileCountEl = ThreadStats.fileCountEl, ipCountEl = ThreadStats.ipCountEl; - postCountEl.textContent = ThreadStats.postCount; - fileCountEl.textContent = ThreadStats.fileCount; - if (ipCountEl != null) { - ipCountEl.textContent = (ref = thread.ipCount) != null ? ref : '?'; - } - postCountEl.classList.toggle('warning', thread.postLimit && !thread.isSticky); - return fileCountEl.classList.toggle('warning', thread.fileLimit && !thread.isSticky); - }, - fetchPage: function() { - if (!ThreadStats.pageCountEl) { - return; - } - clearTimeout(ThreadStats.timeout); - if (ThreadStats.thread.isDead) { - ThreadStats.pageCountEl.textContent = 'Dead'; - $.addClass(ThreadStats.pageCountEl, 'warning'); - return; - } - ThreadStats.timeout = setTimeout(ThreadStats.fetchPage, 2 * $.MINUTE); - return $.whenModified(g.SITE.urls.threadsListJSON(ThreadStats.thread), 'ThreadStats', ThreadStats.onThreadsLoad); - }, - onThreadsLoad: function() { - var i, j, k, l, len, len1, len2, len3, len4, m, nThreads, o, page, pageNum, purgePos, ref, ref1, ref2, ref3, ref4, thread; - if (this.status === 200) { - if (ThreadStats.showPurgePos) { - purgePos = 1; - ref = this.response; - for (j = 0, len = ref.length; j < len; j++) { - page = ref[j]; - ref1 = page.threads; - for (k = 0, len1 = ref1.length; k < len1; k++) { - thread = ref1[k]; - if (thread.no < ThreadStats.thread.ID) { - purgePos++; - } - } - } - ThreadStats.pageCountEl.textContent = purgePos; - return ThreadStats.pageCountEl.classList.toggle('warning', purgePos === 1); - } else { - i = nThreads = 0; - ref2 = this.response; - for (l = 0, len2 = ref2.length; l < len2; l++) { - page = ref2[l]; - nThreads += page.threads.length; - } - ref3 = this.response; - for (pageNum = m = 0, len3 = ref3.length; m < len3; pageNum = ++m) { - page = ref3[pageNum]; - ref4 = page.threads; - for (o = 0, len4 = ref4.length; o < len4; o++) { - thread = ref4[o]; - if (thread.no === ThreadStats.thread.ID) { - ThreadStats.pageCountEl.textContent = pageNum + 1; - ThreadStats.pageCountEl.classList.toggle('warning', i >= nThreads - this.response[0].threads.length); - ThreadStats.lastPageUpdate = new Date(thread.last_modified * $.SECOND); - ThreadStats.retry(); - return; - } - i++; - } - } - } - } else if (this.status === 304) { - return ThreadStats.retry(); - } - }, - retry: function() { - if (!(ThreadStats.showPage && ThreadStats.pageCountEl.textContent !== '1' && !g.SITE.threadModTimeIgnoresSage && ThreadStats.thread.posts.get(ThreadStats.thread.lastPost).info.date > ThreadStats.lastPageUpdate)) { - return; - } - clearTimeout(ThreadStats.timeout); - return ThreadStats.timeout = setTimeout(ThreadStats.fetchPage, 5 * $.SECOND); - } - }; - - return ThreadStats; - -}).call(this); - -ThreadUpdater = (function() { - var ThreadUpdater, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - ThreadUpdater = { - init: function() { - var conf, el, input, name, ref, sc, subEntries, updateLink; - if (g.VIEW !== 'thread' || !Conf['Thread Updater']) { - return; - } - this.enabled = true; - this.audio = $.el('audio'); - if ($.engine !== 'gecko') { - this.audio.src = this.beep; - } - if (Conf['Updater and Stats in Header']) { - this.dialog = sc = $.el('span', { - id: 'updater' - }); - $.extend(sc, {innerHTML: ""}); - Header.addShortcut('updater', sc, 100); - } else { - this.dialog = sc = UI.dialog('updater', {innerHTML: "
      "}); - $.addClass(doc, 'float'); - $.ready(function() { - return $.add(d.body, sc); - }); - } - this.checkPostCount = 0; - this.timer = $('#update-timer', sc); - this.status = $('#update-status', sc); - $.on(this.timer, 'click', this.update); - $.on(this.status, 'click', this.update); - updateLink = $.el('span', { - className: 'brackets-wrap updatelink' - }); - $.extend(updateLink, {innerHTML: "Update"}); - Main.ready(function() { - var navLinksBot; - if ((navLinksBot = $('.navLinksBot'))) { - return $.add(navLinksBot, [$.tn(' '), updateLink]); - } - }); - $.on(updateLink.firstElementChild, 'click', this.update); - subEntries = []; - ref = Config.updater.checkbox; - for (name in ref) { - conf = ref[name]; - el = UI.checkbox(name, name); - el.title = conf[1]; - input = el.firstElementChild; - $.on(input, 'change', $.cb.checked); - if (input.name === 'Scroll BG') { - $.on(input, 'change', this.cb.scrollBG); - this.cb.scrollBG(); - } else if (input.name === 'Auto Update') { - $.on(input, 'change', this.setInterval); - } - subEntries.push({ - el: el - }); - } - this.settings = $.el('span', {innerHTML: "Interval"}); - $.on(this.settings, 'click', this.intervalShortcut); - subEntries.push({ - el: this.settings - }); - Header.menu.addEntry(this.entry = { - el: $.el('span', { - textContent: 'Updater' - }), - order: 110, - subEntries: subEntries - }); - return Callbacks.Thread.push({ - name: 'Thread Updater', - cb: this.node - }); - }, - node: function() { - ThreadUpdater.thread = this; - ThreadUpdater.root = this.nodes.root; - ThreadUpdater.outdateCount = 0; - ThreadUpdater.postIDs = []; - ThreadUpdater.fileIDs = []; - this.posts.forEach(function(post) { - ThreadUpdater.postIDs.push(post.ID); - if (post.file) { - return ThreadUpdater.fileIDs.push(post.ID); - } - }); - ThreadUpdater.cb.interval.call($.el('input', { - value: Conf['Interval'] - })); - $.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost); - $.on(d, 'visibilitychange', ThreadUpdater.cb.visibility); - return ThreadUpdater.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: function() { - var audio; - audio = ThreadUpdater.audio; - audio.src || (audio.src = ThreadUpdater.beep); - if (audio.paused) { - return audio.play(); - } else { - return $.one(audio, 'ended', ThreadUpdater.playBeep); - } - }, - cb: { - checkpost: function(e) { - if (e.detail.threadID !== ThreadUpdater.thread.ID) { - return; - } - ThreadUpdater.postID = e.detail.postID; - ThreadUpdater.checkPostCount = 0; - ThreadUpdater.outdateCount = 0; - return ThreadUpdater.setInterval(); - }, - visibility: function() { - if (d.hidden) { - return; - } - ThreadUpdater.outdateCount = 0; - if (ThreadUpdater.seconds > ThreadUpdater.interval) { - return ThreadUpdater.setInterval(); - } - }, - scrollBG: function() { - return ThreadUpdater.scrollBG = Conf['Scroll BG'] ? function() { - return true; - } : function() { - return !d.hidden; - }; - }, - interval: function(e) { - var val; - val = parseInt(this.value, 10); - if (val < 1) { - val = 1; - } - ThreadUpdater.interval = this.value = val; - if (e) { - return $.cb.value.call(this); - } - }, - load: function() { - if (this !== ThreadUpdater.req) { - return; - } - switch (this.status) { - case 200: - ThreadUpdater.parse(this); - if (ThreadUpdater.thread.isArchived) { - return ThreadUpdater.kill(); - } else { - return ThreadUpdater.setInterval(); - } - break; - case 404: - return $.ajax(g.SITE.urls.catalogJSON({ - boardID: ThreadUpdater.thread.board.ID - }), { - onloadend: function() { - var confirmed, i, k, len, len1, page, ref, ref1, thread; - if (this.status === 200) { - confirmed = true; - ref = this.response; - for (i = 0, len = ref.length; i < len; i++) { - page = ref[i]; - ref1 = page.threads; - for (k = 0, len1 = ref1.length; k < len1; k++) { - thread = ref1[k]; - if (thread.no === ThreadUpdater.thread.ID) { - confirmed = false; - break; - } - } - } - } else { - confirmed = false; - } - if (confirmed) { - return ThreadUpdater.kill(); - } else { - return ThreadUpdater.error(this); - } - } - }); - default: - return ThreadUpdater.error(this); - } - } - }, - kill: function() { - ThreadUpdater.thread.kill(); - ThreadUpdater.setInterval(); - return $.event('ThreadUpdate', { - 404: true, - threadID: ThreadUpdater.thread.fullID - }); - }, - error: function(req) { - if (req.status === 304) { - ThreadUpdater.set('status', ''); - } - ThreadUpdater.setInterval(); - if (!req.status) { - return ThreadUpdater.set('status', 'Connection Error', 'warning'); - } else if (req.status !== 304) { - return ThreadUpdater.set('status', req.statusText + " (" + req.status + ")", 'warning'); - } - }, - setInterval: function() { - var cur, interval, j, limit; - clearTimeout(ThreadUpdater.timeoutID); - if (ThreadUpdater.thread.isDead) { - ThreadUpdater.set('status', (ThreadUpdater.thread.isArchived ? 'Archived' : '404'), 'warning'); - ThreadUpdater.set('timer', ''); - return; - } - if (ThreadUpdater.postID && ThreadUpdater.checkPostCount < 5) { - ThreadUpdater.set('timer', '...', 'loading'); - ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND); - return; - } - if (!Conf['Auto Update']) { - ThreadUpdater.set('timer', 'Update'); - return; - } - interval = ThreadUpdater.interval; - if (Conf['Optional Increase']) { - limit = d.hidden ? 10 : 5; - j = Math.min(ThreadUpdater.outdateCount, limit); - cur = (Math.floor(interval * 0.1) || 1) * j * j; - ThreadUpdater.seconds = $.minmax(cur, interval, 300); - } else { - ThreadUpdater.seconds = interval; - } - return ThreadUpdater.timeout(); - }, - intervalShortcut: function() { - var settings; - Settings.open('Advanced'); - settings = $.id('fourchanx-settings'); - return $('input[name=Interval]', settings).focus(); - }, - set: function(name, text, klass) { - var el, node; - el = ThreadUpdater[name]; - if (node = el.firstChild) { - node.data = text; - } else { - el.textContent = text; - } - return el.className = klass != null ? klass : (text === '' ? 'empty' : ''); - }, - timeout: function() { - if (ThreadUpdater.seconds) { - ThreadUpdater.set('timer', ThreadUpdater.seconds); - ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000); - } else { - ThreadUpdater.outdateCount++; - ThreadUpdater.update(); - } - return ThreadUpdater.seconds--; - }, - update: function() { - var oldReq; - clearTimeout(ThreadUpdater.timeoutID); - ThreadUpdater.set('timer', '...', 'loading'); - if ((oldReq = ThreadUpdater.req)) { - delete ThreadUpdater.req; - oldReq.abort(); - } - return ThreadUpdater.req = $.whenModified(g.SITE.urls.threadJSON({ - boardID: ThreadUpdater.thread.board.ID, - threadID: ThreadUpdater.thread.ID - }), 'ThreadUpdater', ThreadUpdater.cb.load, { - timeout: $.MINUTE - }); - }, - updateThreadStatus: function(type, status) { - var change, hasChanged; - if (!(hasChanged = ThreadUpdater.thread["is" + type] !== status)) { - return; - } - ThreadUpdater.thread.setStatus(type, status); - if (type === 'Closed' && ThreadUpdater.thread.isArchived) { - return; - } - change = type === 'Sticky' ? status ? 'now a sticky' : 'not a sticky anymore' : status ? 'now closed' : 'not closed anymore'; - return new Notice('info', "The thread is " + change + ".", 30); - }, - parse: function(req) { - var ID, OP, board, deletedFiles, deletedPosts, files, firstPost, i, index, ipCountEl, k, l, lastPost, len, len1, len2, len3, m, newPosts, node, post, postObject, postObjects, posts, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, scroll, thread, unreadCount, unreadQYCount; - postObjects = req.response.posts; - OP = postObjects[0]; - thread = ThreadUpdater.thread; - board = thread.board; - ref = ThreadUpdater.postIDs, lastPost = ref[ref.length - 1]; - if (postObjects[postObjects.length - 1].no < lastPost && new Date(req.getResponseHeader('Last-Modified')) - thread.posts.get(lastPost).info.date < 30 * $.SECOND) { - return; - } - g.SITE.Build.spoilerRange[board] = OP.custom_spoiler; - thread.setStatus('Archived', !!OP.archived); - ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky); - ThreadUpdater.updateThreadStatus('Closed', !!OP.closed); - thread.postLimit = !!OP.bumplimit; - thread.fileLimit = !!OP.imagelimit; - if (OP.unique_ips != null) { - thread.ipCount = OP.unique_ips; - } - posts = []; - index = []; - files = []; - newPosts = []; - for (i = 0, len = postObjects.length; i < len; i++) { - postObject = postObjects[i]; - ID = postObject.no; - index.push(ID); - if (postObject.fsize) { - files.push(ID); - } - if (ID <= lastPost) { - continue; - } - if ((post = thread.posts.get(ID)) && !post.isFetchedQuote) { - post.resurrect(); - continue; - } - newPosts.push(board + "." + ID); - node = g.SITE.Build.postFromObject(postObject, board.ID); - posts.push(new Post(node, thread, board)); - if (ThreadUpdater.postID === ID) { - delete ThreadUpdater.postID; - } - } - deletedPosts = []; - ref1 = ThreadUpdater.postIDs; - for (k = 0, len1 = ref1.length; k < len1; k++) { - ID = ref1[k]; - if (!(indexOf.call(index, ID) < 0)) { - continue; - } - thread.posts.get(ID).kill(); - deletedPosts.push(board + "." + ID); - } - ThreadUpdater.postIDs = index; - deletedFiles = []; - ref2 = ThreadUpdater.fileIDs; - for (l = 0, len2 = ref2.length; l < len2; l++) { - ID = ref2[l]; - if (!(!(indexOf.call(files, ID) >= 0 || (ref3 = board + "." + ID, indexOf.call(deletedPosts, ref3) >= 0)))) { - continue; - } - thread.posts.get(ID).kill(true); - deletedFiles.push(board + "." + ID); - } - ThreadUpdater.fileIDs = files; - if (!posts.length) { - ThreadUpdater.set('status', ''); - } else { - ThreadUpdater.set('status', "+" + posts.length, 'new'); - ThreadUpdater.outdateCount = 0; - unreadCount = (ref4 = Unread.posts) != null ? ref4.size : void 0; - unreadQYCount = (ref5 = Unread.postsQuotingYou) != null ? ref5.size : void 0; - Main.callbackNodes('Post', posts); - if (d.hidden || !d.hasFocus()) { - if (Conf['Beep Quoting You'] && ((ref6 = Unread.postsQuotingYou) != null ? ref6.size : void 0) > unreadQYCount) { - ThreadUpdater.playBeep(); - if (Conf['Beep']) { - ThreadUpdater.playBeep(); - } - } else if (Conf['Beep'] && ((ref7 = Unread.posts) != null ? ref7.size : void 0) > 0 && unreadCount === 0) { - ThreadUpdater.playBeep(); - } - } - scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight < 25; - firstPost = null; - for (m = 0, len3 = posts.length; m < len3; m++) { - post = posts[m]; - if (!QuoteThreading.insert(post)) { - firstPost || (firstPost = post.nodes.root); - $.add(ThreadUpdater.root, post.nodes.root); - } - } - $.event('PostsInserted', null, ThreadUpdater.root); - if (scroll) { - if (Conf['Bottom Scroll']) { - window.scrollTo(0, d.body.clientHeight); - } else { - if (firstPost) { - Header.scrollTo(firstPost); - } - } - } - } - if ((OP.unique_ips != null) && (ipCountEl = $.id('unique-ips'))) { - ipCountEl.textContent = OP.unique_ips; - ipCountEl.previousSibling.textContent = ipCountEl.previousSibling.textContent.replace(/\b(?:is|are)\b/, OP.unique_ips === 1 ? 'is' : 'are'); - ipCountEl.nextSibling.textContent = ipCountEl.nextSibling.textContent.replace(/\bposters?\b/, OP.unique_ips === 1 ? 'poster' : 'posters'); - } - return $.event('ThreadUpdate', { - 404: false, - threadID: thread.fullID, - newPosts: newPosts, - deletedPosts: deletedPosts, - deletedFiles: deletedFiles, - postCount: OP.replies + 1, - fileCount: OP.images + !!OP.fsize, - ipCount: OP.unique_ips - }); - } - }; - - return ThreadUpdater; - -}).call(this); - -ThreadWatcher = (function() { - var ThreadWatcher, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - ThreadWatcher = { - init: function() { - var ref, sc; - if (!(this.enabled = Conf['Thread Watcher'])) { - return; - } - this.shortcut = sc = $.el('a', { - id: 'watcher-link', - textContent: 'Watcher', - title: 'Thread Watcher', - href: 'javascript:;', - className: 'fa fa-eye' - }); - this.db = new DataBoard('watchedThreads', this.refresh, true); - this.dbLM = new DataBoard('watcherLastModified', null, true); - this.dialog = UI.dialog('thread-watcher', {innerHTML: "
      Thread Watcher ×
      "}); - this.status = $('#watcher-status', this.dialog); - this.list = this.dialog.lastElementChild; - this.refreshButton = $('.refresh', this.dialog); - this.closeButton = $('.move > .close', this.dialog); - this.unreaddb = Unread.db || UnreadIndex.db || new DataBoard('lastReadPosts'); - this.unreadEnabled = Conf['Remember Last Read Post']; - $.on(d, 'QRPostSuccessful', this.cb.post); - $.on(sc, 'click', this.toggleWatcher); - $.on(this.refreshButton, 'click', this.buttonFetchAll); - $.on(this.closeButton, 'click', this.toggleWatcher); - this.menu.addHeaderMenuEntry(); - $.onExists(doc, 'body', this.addDialog); - switch (g.VIEW) { - case 'index': - $.on(d, 'IndexUpdate', this.cb.onIndexUpdate); - break; - case 'thread': - $.on(d, 'ThreadUpdate', this.cb.onThreadRefresh); - } - if (Conf['Fixed Thread Watcher']) { - $.addClass(doc, 'fixed-watcher'); - } - if (!Conf['Persistent Thread Watcher']) { - $.addClass(ThreadWatcher.shortcut, 'disabled'); - this.dialog.hidden = true; - } - Header.addShortcut('watcher', sc, 510); - ThreadWatcher.initLastModified(); - ThreadWatcher.fetchAuto(); - $.on(window, 'visibilitychange focus', function() { - return $.queueTask(ThreadWatcher.fetchAuto); - }); - if (Conf['Menu'] && Index.enabled) { - Menu.menu.addEntry({ - el: $.el('a', { - href: 'javascript:;', - className: 'has-shortcut-text' - }, {innerHTML: "Alt+click"}), - order: 6, - open: function(arg) { - var thread; - thread = arg.thread; - if (Conf['Index Mode'] !== 'catalog') { - return false; - } - this.el.firstElementChild.textContent = ThreadWatcher.isWatched(thread) ? 'Unwatch' : 'Watch'; - if (this.cb) { - $.off(this.el, 'click', this.cb); - } - this.cb = function() { - $.event('CloseMenu'); - return ThreadWatcher.toggle(thread); - }; - $.on(this.el, 'click', this.cb); - return true; - } - }); - } - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - Callbacks.Post.push({ - name: 'Thread Watcher', - cb: this.node - }); - return Callbacks.CatalogThread.push({ - name: 'Thread Watcher', - cb: this.catalogNode - }); - }, - isWatched: function(thread) { - var ref; - return !!((ref = ThreadWatcher.db) != null ? ref.get({ - boardID: thread.board.ID, - threadID: thread.ID - }) : void 0); - }, - isWatchedRaw: function(boardID, threadID) { - var ref; - return !!((ref = ThreadWatcher.db) != null ? ref.get({ - boardID: boardID, - threadID: threadID - }) : void 0); - }, - setToggler: function(toggler, isWatched) { - toggler.classList.toggle('watched', isWatched); - return toggler.title = (isWatched ? 'Unwatch' : 'Watch') + " Thread"; - }, - node: function() { - var boardID, data, siteID, threadID, toggler; - if (this.isReply) { - return; - } - if (this.isClone) { - toggler = $('.watch-thread-link', this.nodes.info); - } else { - toggler = $.el('a', { - href: 'javascript:;', - className: 'watch-thread-link' - }); - $.before($('input', this.nodes.info), toggler); - } - siteID = g.SITE.ID; - boardID = this.board.ID; - threadID = this.thread.ID; - data = ThreadWatcher.db.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }); - ThreadWatcher.setToggler(toggler, !!data); - $.on(toggler, 'click', ThreadWatcher.cb.toggle); - if (data && (data.excerpt == null)) { - return $.queueTask((function(_this) { - return function() { - return ThreadWatcher.update(siteID, boardID, threadID, { - excerpt: Get.threadExcerpt(_this.thread) - }); - }; - })(this)); - } - }, - catalogNode: function() { - if (ThreadWatcher.isWatched(this.thread)) { - $.addClass(this.nodes.root, 'watched'); - } - return $.on(this.nodes.root, 'mousedown click', (function(_this) { - return function(e) { - if (!(e.button === 0 && e.altKey)) { - return; - } - if (e.type === 'click') { - ThreadWatcher.toggle(_this.thread); - } - return e.preventDefault(); - }; - })(this)); - }, - addDialog: function() { - if (!Main.isThisPageLegit()) { - return; - } - ThreadWatcher.build(); - return $.prepend(d.body, ThreadWatcher.dialog); - }, - toggleWatcher: function() { - $.toggleClass(ThreadWatcher.shortcut, 'disabled'); - return ThreadWatcher.dialog.hidden = !ThreadWatcher.dialog.hidden; - }, - cb: { - openAll: function() { - var a, j, len1, ref; - if ($.hasClass(this, 'disabled')) { - return; - } - ref = $$('a.watcher-link', ThreadWatcher.list); - for (j = 0, len1 = ref.length; j < len1; j++) { - a = ref[j]; - $.open(a.href); - } - return $.event('CloseMenu'); - }, - openUnread: function() { - var a, j, len1, ref; - if ($.hasClass(this, 'disabled')) { - return; - } - ref = $$('.replies-unread > a.watcher-link', ThreadWatcher.list); - for (j = 0, len1 = ref.length; j < len1; j++) { - a = ref[j]; - $.open(a.href); - } - return $.event('CloseMenu'); - }, - openDeads: function() { - var a, j, len1, ref; - if ($.hasClass(this, 'disabled')) { - return; - } - ref = $$('.dead-thread > a.watcher-link', ThreadWatcher.list); - for (j = 0, len1 = ref.length; j < len1; j++) { - a = ref[j]; - $.open(a.href); - } - return $.event('CloseMenu'); - }, - pruneDeads: function() { - var boardID, data, j, len1, ref, ref1, siteID, threadID; - if ($.hasClass(this, 'disabled')) { - return; - } - ref = ThreadWatcher.getAll(); - for (j = 0, len1 = ref.length; j < len1; j++) { - ref1 = ref[j], siteID = ref1.siteID, boardID = ref1.boardID, threadID = ref1.threadID, data = ref1.data; - if (data.isDead) { - ThreadWatcher.db["delete"]({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }); - } - } - ThreadWatcher.refresh(); - return $.event('CloseMenu'); - }, - dismiss: function() { - var boardID, data, j, len1, ref, ref1, siteID, threadID; - ref = ThreadWatcher.getAll(); - for (j = 0, len1 = ref.length; j < len1; j++) { - ref1 = ref[j], siteID = ref1.siteID, boardID = ref1.boardID, threadID = ref1.threadID, data = ref1.data; - if (data.quotingYou) { - ThreadWatcher.update(siteID, boardID, threadID, { - dismiss: data.quotingYou || 0 - }); - } - } - return $.event('CloseMenu'); - }, - toggle: function() { - var thread; - thread = Get.postFromNode(this).thread; - return ThreadWatcher.toggle(thread); - }, - rm: function() { - var boardID, ref, siteID, threadID; - siteID = this.parentNode.dataset.siteID; - ref = this.parentNode.dataset.fullID.split('.'), boardID = ref[0], threadID = ref[1]; - return ThreadWatcher.rm(siteID, boardID, +threadID); - }, - post: function(e) { - var boardID, cb, postID, ref, threadID; - ref = e.detail, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - cb = PostRedirect.delay(); - if (postID === threadID) { - if (Conf['Auto Watch']) { - return ThreadWatcher.addRaw(boardID, threadID, {}, cb); - } - } else if (Conf['Auto Watch Reply']) { - return ThreadWatcher.add(g.threads.get(boardID + '.' + threadID) || new Thread(threadID, g.boards[boardID] || new Board(boardID)), cb); - } - }, - onIndexUpdate: function(e) { - var boardID, data, db, nKilled, ref, ref1, siteID, threadID; - db = ThreadWatcher.db; - siteID = g.SITE.ID; - boardID = g.BOARD.ID; - nKilled = 0; - ref = db.data[siteID].boards[boardID]; - for (threadID in ref) { - data = ref[threadID]; - if (!(!(data != null ? data.isDead : void 0) && (ref1 = boardID + "." + threadID, indexOf.call(e.detail.threads, ref1) < 0))) { - continue; - } - if (!e.detail.threads.some(function(fullID) { - return +fullID.split('.')[1] > threadID; - })) { - continue; - } - if (Conf['Auto Prune'] || !(data && typeof data === 'object')) { - db["delete"]({ - boardID: boardID, - threadID: threadID - }); - nKilled++; - } else { - ThreadWatcher.fetchStatus({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - data: data - }); - } - } - if (nKilled) { - return ThreadWatcher.refresh(); - } - }, - onThreadRefresh: function(e) { - var thread; - thread = g.threads.get(e.detail.threadID); - if (!(e.detail[404] && ThreadWatcher.isWatched(thread))) { - return; - } - return ThreadWatcher.add(thread); - } - }, - requests: [], - fetched: 0, - fetch: function(url, arg, args, cb) { - var ajax, force, onloadend, ref, req, siteID; - siteID = arg.siteID, force = arg.force; - if (ThreadWatcher.requests.length === 0) { - ThreadWatcher.status.textContent = '...'; - $.addClass(ThreadWatcher.refreshButton, 'fa-spin'); - } - onloadend = function() { - if (this.finished) { - return; - } - this.finished = true; - ThreadWatcher.fetched++; - if (ThreadWatcher.fetched === ThreadWatcher.requests.length) { - ThreadWatcher.clearRequests(); - } else { - ThreadWatcher.status.textContent = (Math.round(ThreadWatcher.fetched / ThreadWatcher.requests.length * 100)) + "%"; - } - return cb.apply(this, args); - }; - ajax = siteID === g.SITE.ID ? $.ajax : CrossOrigin.ajax; - if (force) { - if ((ref = $.lastModified.ThreadWatcher) != null) { - delete ref[url]; - } - } - req = $.whenModified(url, 'ThreadWatcher', onloadend, { - timeout: $.MINUTE, - ajax: ajax - }); - return ThreadWatcher.requests.push(req); - }, - clearRequests: function() { - ThreadWatcher.requests = []; - ThreadWatcher.fetched = 0; - ThreadWatcher.status.textContent = ''; - return $.rmClass(ThreadWatcher.refreshButton, 'fa-spin'); - }, - abort: function() { - var j, len1, ref, req; - delete ThreadWatcher.syncing; - ref = ThreadWatcher.requests; - for (j = 0, len1 = ref.length; j < len1; j++) { - req = ref[j]; - if (!(!req.finished)) { - continue; - } - req.finished = true; - req.abort(); - } - return ThreadWatcher.clearRequests(); - }, - initLastModified: function() { - var base, boardID, boards, data, date, lm, ref, ref1, siteID, url; - lm = ((base = $.lastModified)['ThreadWatcher'] || (base['ThreadWatcher'] = $.dict())); - ref = ThreadWatcher.dbLM.data; - for (siteID in ref) { - boards = ref[siteID]; - ref1 = boards.boards; - for (boardID in ref1) { - data = ref1[boardID]; - if (ThreadWatcher.db.get({ - siteID: siteID, - boardID: boardID - })) { - for (url in data) { - date = data[url]; - lm[url] = date; - } - } else { - ThreadWatcher.dbLM["delete"]({ - siteID: siteID, - boardID: boardID - }); - } - } - } - }, - fetchAuto: function() { - var db, interval, now, ref; - clearTimeout(ThreadWatcher.timeout); - if (!Conf['Auto Update Thread Watcher']) { - return; - } - db = ThreadWatcher.db; - interval = Conf['Show Page'] || (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) ? 5 * $.MINUTE : 2 * $.HOUR; - now = Date.now(); - if (!((now - interval < (ref = db.data.lastChecked || 0) && ref <= now) || d.hidden || !d.hasFocus())) { - ThreadWatcher.fetchAllStatus(interval); - } - return ThreadWatcher.timeout = setTimeout(ThreadWatcher.fetchAuto, interval); - }, - buttonFetchAll: function() { - if (ThreadWatcher.syncing || ThreadWatcher.requests.length) { - return ThreadWatcher.abort(); - } else { - return ThreadWatcher.fetchAllStatus(); - } - }, - fetchAllStatus: function(interval) { - var dbi, dbs, j, len1, n, results; - if (interval == null) { - interval = 0; - } - ThreadWatcher.status.textContent = '...'; - $.addClass(ThreadWatcher.refreshButton, 'fa-spin'); - ThreadWatcher.syncing = true; - dbs = [ThreadWatcher.db, ThreadWatcher.unreaddb, QuoteYou.db].filter(function(x) { - return x; - }); - n = 0; - results = []; - for (j = 0, len1 = dbs.length; j < len1; j++) { - dbi = dbs[j]; - results.push(dbi.forceSync(function() { - var board, boards, db, deep, k, len2, now, ref, ref1; - if ((++n) === dbs.length) { - if (!ThreadWatcher.syncing) { - return; - } - delete ThreadWatcher.syncing; - if (!((0 <= (ref = Date.now() - (ThreadWatcher.db.data.lastChecked || 0)) && ref < interval))) { - db = ThreadWatcher.db; - now = Date.now(); - deep = !((now - 2 * $.HOUR < (ref1 = db.data.lastChecked2 || 0) && ref1 <= now)); - boards = ThreadWatcher.getAll(true); - for (k = 0, len2 = boards.length; k < len2; k++) { - board = boards[k]; - ThreadWatcher.fetchBoard(board, deep); - } - db.setLastChecked(); - if (deep) { - db.setLastChecked('lastChecked2'); - } - } - if (ThreadWatcher.fetched === ThreadWatcher.requests.length) { - return ThreadWatcher.clearRequests(); - } - } - })); - } - return results; - }, - fetchBoard: function(board, deep) { - var base, boardID, data, force, j, len1, ref, site, siteID, thread, url, urlF; - if (!board.some(function(thread) { - return !thread.data.isDead; - })) { - return; - } - force = false; - for (j = 0, len1 = board.length; j < len1; j++) { - thread = board[j]; - data = thread.data; - if (!data.isDead && data.last !== -1) { - if (Conf['Show Page'] && (data.page == null)) { - force = true; - } - if (data.modified == null) { - force = thread.force = true; - } - } - } - ref = board[0], siteID = ref.siteID, boardID = ref.boardID; - site = g.sites[siteID]; - if (!site) { - return; - } - urlF = deep && site.threadModTimeIgnoresSage ? 'catalogJSON' : 'threadsListJSON'; - url = typeof (base = site.urls)[urlF] === "function" ? base[urlF]({ - siteID: siteID, - boardID: boardID - }) : void 0; - if (!url) { - return; - } - return ThreadWatcher.fetch(url, { - siteID: siteID, - force: force - }, [board, url], ThreadWatcher.parseBoard); - }, - parseBoard: function(board, url) { - var base, boardID, data, i, index, item, j, k, l, lastPage, len1, len2, len3, len4, lmDate, m, modified, nThreads, oldest, page, pageLength, ref, ref1, ref2, ref3, ref4, replies, siteID, thread, threadID, threads; - if (this.status !== 200) { - return; - } - ref = board[0], siteID = ref.siteID, boardID = ref.boardID; - lmDate = this.getResponseHeader('Last-Modified'); - ThreadWatcher.dbLM.extend({ - siteID: siteID, - boardID: boardID, - val: $.item(url, lmDate) - }); - threads = $.dict(); - pageLength = 0; - nThreads = 0; - oldest = null; - try { - pageLength = ((ref1 = this.response[0]) != null ? ref1.threads.length : void 0) || 0; - ref2 = this.response; - for (i = j = 0, len1 = ref2.length; j < len1; i = ++j) { - page = ref2[i]; - ref3 = page.threads; - for (k = 0, len2 = ref3.length; k < len2; k++) { - item = ref3[k]; - threads[item.no] = { - page: i + 1, - index: nThreads, - modified: item.last_modified, - replies: item.replies - }; - nThreads++; - if ((oldest == null) || item.no < oldest) { - oldest = item.no; - } - } - } - } catch (error) { - for (l = 0, len3 = board.length; l < len3; l++) { - thread = board[l]; - ThreadWatcher.fetchStatus(thread); - } - } - for (m = 0, len4 = board.length; m < len4; m++) { - thread = board[m]; - threadID = thread.threadID, data = thread.data; - if (threads[threadID]) { - ref4 = threads[threadID], page = ref4.page, index = ref4.index, modified = ref4.modified, replies = ref4.replies; - if (Conf['Show Page']) { - lastPage = (typeof (base = g.sites[siteID]).isPrunedByAge === "function" ? base.isPrunedByAge({ - siteID: siteID, - boardID: boardID - }) : void 0) ? threadID === oldest : index >= nThreads - pageLength; - ThreadWatcher.update(siteID, boardID, threadID, { - page: page, - lastPage: lastPage - }); - } - if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { - if (modified !== data.modified || ((replies != null) && replies !== data.replies)) { - (thread.newData || (thread.newData = {})).modified = modified; - ThreadWatcher.fetchStatus(thread); - } - } - } else { - ThreadWatcher.fetchStatus(thread); - } - } - }, - fetchStatus: function(thread) { - var base, boardID, data, force, ref, siteID, threadID, url; - siteID = thread.siteID, boardID = thread.boardID, threadID = thread.threadID, data = thread.data, force = thread.force; - url = (ref = g.sites[siteID]) != null ? typeof (base = ref.urls).threadJSON === "function" ? base.threadJSON({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }) : void 0 : void 0; - if (!url) { - return; - } - if (data.isDead && !force) { - return; - } - if (data.last === -1) { - return; - } - return ThreadWatcher.fetch(url, { - siteID: siteID, - force: force - }, [thread], ThreadWatcher.parseStatus); - }, - parseStatus: function(thread, isArchiveURL) { - var archiveURL, base, boardID, data, force, isArchived, isDead, j, last, lastReadPost, len1, match, newData, postObj, quotesYou, quotingYou, ref, ref1, ref2, ref3, regexp, replies, site, siteID, threadID, unread, youOP; - siteID = thread.siteID, boardID = thread.boardID, threadID = thread.threadID, data = thread.data, newData = thread.newData, force = thread.force; - site = g.sites[siteID]; - if (this.status === 200 && this.response) { - last = this.response.posts[this.response.posts.length - 1].no; - replies = this.response.posts.length - 1; - isDead = isArchived = !!(this.response.posts[0].archived || isArchiveURL); - if (isDead && Conf['Auto Prune']) { - ThreadWatcher.rm(siteID, boardID, threadID); - return; - } - if (last === data.last && isDead === data.isDead && isArchived === data.isArchived) { - return; - } - lastReadPost = ThreadWatcher.unreaddb.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - defaultValue: 0 - }); - unread = data.unread || 0; - quotingYou = data.quotingYou || 0; - youOP = !!((ref = QuoteYou.db) != null ? ref.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - postID: threadID - }) : void 0); - ref1 = this.response.posts; - for (j = 0, len1 = ref1.length; j < len1; j++) { - postObj = ref1[j]; - if (!(postObj.no > (data.last || 0) && postObj.no > lastReadPost)) { - continue; - } - if ((ref2 = QuoteYou.db) != null ? ref2.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - postID: postObj.no - }) : void 0) { - continue; - } - quotesYou = false; - if (!Conf['Require OP Quote Link'] && youOP) { - quotesYou = true; - } else if (QuoteYou.db && postObj.com) { - regexp = site.regexp.quotelinkHTML; - regexp.lastIndex = 0; - while ((match = regexp.exec(postObj.com))) { - if (QuoteYou.db.get({ - siteID: siteID, - boardID: match[1] ? encodeURIComponent(match[1]) : boardID, - threadID: match[2] || threadID, - postID: match[3] || match[2] || threadID - })) { - quotesYou = true; - break; - } - } - } - if (!unread || (!quotingYou && quotesYou)) { - if (Filter.isHidden(site.Build.parseJSON(postObj, { - siteID: siteID, - boardID: boardID - }))) { - continue; - } - } - unread++; - if (quotesYou) { - quotingYou = postObj.no; - } - } - newData || (newData = {}); - $.extend(newData, { - last: last, - replies: replies, - isDead: isDead, - isArchived: isArchived, - unread: unread, - quotingYou: quotingYou - }); - return ThreadWatcher.update(siteID, boardID, threadID, newData); - } else if (this.status === 404) { - archiveURL = (ref3 = g.sites[siteID]) != null ? typeof (base = ref3.urls).archivedThreadJSON === "function" ? base.archivedThreadJSON({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }) : void 0 : void 0; - if (!isArchiveURL && archiveURL) { - return ThreadWatcher.fetch(archiveURL, { - siteID: siteID, - force: force - }, [thread, true], ThreadWatcher.parseStatus); - } else if (site.mayLackJSON && (data.last == null)) { - return ThreadWatcher.update(siteID, boardID, threadID, { - last: -1 - }); - } else { - return ThreadWatcher.update(siteID, boardID, threadID, { - isDead: true - }); - } - } - }, - getAll: function(groupByBoard) { - var all, boardID, boards, cont, data, ref, ref1, siteID, threadID, threads; - all = []; - ref = ThreadWatcher.db.data; - for (siteID in ref) { - boards = ref[siteID]; - ref1 = boards.boards; - for (boardID in ref1) { - threads = ref1[boardID]; - if (Conf['Current Board'] && (siteID !== g.SITE.ID || boardID !== g.BOARD.ID)) { - continue; - } - if (groupByBoard) { - all.push((cont = [])); - } - for (threadID in threads) { - data = threads[threadID]; - if (data && typeof data === 'object') { - (groupByBoard ? cont : all).push({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - data: data - }); - } - } - } - } - return all; - }, - makeLine: function(siteID, boardID, threadID, data) { - var count, div, excerpt, fullID, isArchived, link, page, ref, title, x; - x = $.el('a', { - className: 'fa fa-times', - href: 'javascript:;' - }); - $.on(x, 'click', ThreadWatcher.cb.rm); - excerpt = data.excerpt, isArchived = data.isArchived; - excerpt || (excerpt = "/" + boardID + "/ - No." + threadID); - if (Conf['Show Site Prefix']) { - excerpt = ThreadWatcher.prefixes[siteID] + excerpt; - } - link = $.el('a', { - href: ((ref = g.sites[siteID]) != null ? ref.urls.thread({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }, isArchived) : void 0) || '', - title: excerpt, - className: 'watcher-link' - }); - if (Conf['Show Page'] && (data.page != null)) { - page = $.el('span', { - textContent: "[" + data.page + "]", - className: 'watcher-page' - }); - $.add(link, page); - } - if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count'] && (data.unread != null)) { - count = $.el('span', { - textContent: "(" + data.unread + ")", - className: 'watcher-unread' - }); - $.add(link, count); - } - title = $.el('span', { - textContent: excerpt, - className: 'watcher-title' - }); - $.add(link, title); - div = $.el('div'); - fullID = boardID + "." + threadID; - div.dataset.fullID = fullID; - div.dataset.siteID = siteID; - if (g.VIEW === 'thread' && fullID === (g.BOARD + "." + g.THREADID)) { - $.addClass(div, 'current'); - } - if (data.isDead) { - $.addClass(div, 'dead-thread'); - } - if (Conf['Show Page']) { - if (data.lastPage) { - $.addClass(div, 'last-page'); - } - if (data.page != null) { - div.dataset.page = data.page; - } - } - if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { - if (data.unread === 0) { - $.addClass(div, 'replies-read'); - } - if (data.unread) { - $.addClass(div, 'replies-unread'); - } - if ((data.quotingYou || 0) > (data.dismiss || 0)) { - $.addClass(div, 'replies-quoting-you'); - } - } - $.add(div, [x, $.tn(' '), link]); - return div; - }, - setPrefixes: function(threads) { - var conflicts, conflicts2, j, k, len, len1, len2, prefix, prefixes, siteID, siteID2; - prefixes = $.dict(); - for (j = 0, len1 = threads.length; j < len1; j++) { - siteID = threads[j].siteID; - if (siteID in prefixes) { - continue; - } - len = 0; - prefix = ''; - conflicts = Object.keys(prefixes); - while (conflicts.length > 0) { - len++; - prefix = siteID.slice(0, len); - conflicts2 = []; - for (k = 0, len2 = conflicts.length; k < len2; k++) { - siteID2 = conflicts[k]; - if (siteID2.slice(0, len) === prefix) { - conflicts2.push(siteID2); - } else if (prefixes[siteID2].length < len) { - prefixes[siteID2] = siteID2.slice(0, len); - } - } - conflicts = conflicts2; - } - prefixes[siteID] = prefix; - } - return ThreadWatcher.prefixes = prefixes; - }, - build: function() { - var boardID, data, j, len1, list, nodes, ref, siteID, thread, threadID, threads; - nodes = []; - threads = ThreadWatcher.getAll(); - ThreadWatcher.setPrefixes(threads); - for (j = 0, len1 = threads.length; j < len1; j++) { - ref = threads[j], siteID = ref.siteID, boardID = ref.boardID, threadID = ref.threadID, data = ref.data; - if ((data.excerpt == null) && siteID === g.SITE.ID && (thread = g.threads.get(boardID + "." + threadID)) && thread.OP) { - ThreadWatcher.db.extend({ - boardID: boardID, - threadID: threadID, - val: { - excerpt: Get.threadExcerpt(thread) - } - }); - } - nodes.push(ThreadWatcher.makeLine(siteID, boardID, threadID, data)); - } - list = ThreadWatcher.list; - $.rmAll(list); - $.add(list, nodes); - return ThreadWatcher.refreshIcon(); - }, - refresh: function() { - ThreadWatcher.build(); - g.threads.forEach(function(thread) { - var isWatched, j, len1, post, ref, toggler; - isWatched = ThreadWatcher.isWatched(thread); - if (thread.OP) { - ref = [thread.OP].concat(slice.call(thread.OP.clones)); - for (j = 0, len1 = ref.length; j < len1; j++) { - post = ref[j]; - if ((toggler = $('.watch-thread-link', post.nodes.info))) { - ThreadWatcher.setToggler(toggler, isWatched); - } - } - } - if (thread.catalogView) { - return thread.catalogView.nodes.root.classList.toggle('watched', isWatched); - } - }); - if (Conf['Pin Watched Threads']) { - return $.event('SortIndex', { - deferred: Conf['Index Mode'] !== 'catalog' - }); - } - }, - refreshIcon: function() { - var className, j, len1, ref; - ref = ['replies-unread', 'replies-quoting-you']; - for (j = 0, len1 = ref.length; j < len1; j++) { - className = ref[j]; - ThreadWatcher.shortcut.classList.toggle(className, !!$("." + className, ThreadWatcher.dialog)); - } - }, - update: function(siteID, boardID, threadID, newData) { - var data, j, key, len1, line, n, newLine, ref, ref1, val; - if (!(data = (ref = ThreadWatcher.db) != null ? ref.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }) : void 0)) { - return; - } - if (newData.isDead && Conf['Auto Prune']) { - ThreadWatcher.rm(siteID, boardID, threadID); - return; - } - if (newData.isDead || newData.last === -1) { - ref1 = ['isArchived', 'page', 'lastPage', 'unread', 'quotingyou']; - for (j = 0, len1 = ref1.length; j < len1; j++) { - key = ref1[j]; - if (!(key in newData)) { - newData[key] = void 0; - } - } - } - if ((newData.last != null) && newData.last < data.last) { - newData.modified = void 0; - } - n = 0; - for (key in newData) { - val = newData[key]; - if (data[key] !== val) { - n++; - } - } - if (!n) { - return; - } - ThreadWatcher.db.extend({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - val: newData - }); - if ((line = $("#watched-threads > [data-site-i-d='" + siteID + "'][data-full-i-d='" + boardID + "." + threadID + "']", ThreadWatcher.dialog))) { - newLine = ThreadWatcher.makeLine(siteID, boardID, threadID, data); - $.replace(line, newLine); - return ThreadWatcher.refreshIcon(); - } else { - return ThreadWatcher.refresh(); - } - }, - set404: function(boardID, threadID, cb) { - var data, ref; - if (!(data = (ref = ThreadWatcher.db) != null ? ref.get({ - boardID: boardID, - threadID: threadID - }) : void 0)) { - return cb(); - } - if (Conf['Auto Prune']) { - ThreadWatcher.db["delete"]({ - boardID: boardID, - threadID: threadID - }); - return cb(); - } - if (data.isDead && !((data.isArchived != null) || (data.page != null) || (data.lastPage != null) || (data.unread != null) || (data.quotingYou != null))) { - return cb(); - } - return ThreadWatcher.db.extend({ - boardID: boardID, - threadID: threadID, - val: { - isDead: true, - isArchived: void 0, - page: void 0, - lastPage: void 0, - unread: void 0, - quotingYou: void 0 - } - }, cb); - }, - toggle: function(thread) { - var boardID, siteID, threadID; - siteID = g.SITE.ID; - boardID = thread.board.ID; - threadID = thread.ID; - if (ThreadWatcher.db.get({ - boardID: boardID, - threadID: threadID - })) { - return ThreadWatcher.rm(siteID, boardID, threadID); - } else { - return ThreadWatcher.add(thread); - } - }, - add: function(thread, cb) { - var boardID, data, siteID, threadID; - data = {}; - siteID = g.SITE.ID; - boardID = thread.board.ID; - threadID = thread.ID; - if (thread.isDead) { - if (Conf['Auto Prune'] && ThreadWatcher.db.get({ - boardID: boardID, - threadID: threadID - })) { - ThreadWatcher.rm(siteID, boardID, threadID, cb); - return; - } - data.isDead = true; - } - if (thread.OP) { - data.excerpt = Get.threadExcerpt(thread); - } - return ThreadWatcher.addRaw(boardID, threadID, data, cb); - }, - addRaw: function(boardID, threadID, data, cb) { - var oldData, thread; - oldData = ThreadWatcher.db.get({ - boardID: boardID, - threadID: threadID, - defaultValue: $.dict() - }); - delete oldData.last; - delete oldData.modified; - $.extend(oldData, data); - ThreadWatcher.db.set({ - boardID: boardID, - threadID: threadID, - val: oldData - }, cb); - ThreadWatcher.refresh(); - thread = { - siteID: g.SITE.ID, - boardID: boardID, - threadID: threadID, - data: data, - force: true - }; - if (Conf['Show Page'] && !data.isDead) { - return ThreadWatcher.fetchBoard([thread]); - } else if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { - return ThreadWatcher.fetchStatus(thread); - } - }, - rm: function(siteID, boardID, threadID, cb) { - ThreadWatcher.db["delete"]({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }, cb); - return ThreadWatcher.refresh(); - }, - menu: { - init: function() { - var menu; - if (!Conf['Thread Watcher']) { - return; - } - menu = this.menu = new UI.Menu('thread watcher'); - $.on($('.menu-button', ThreadWatcher.dialog), 'click', function(e) { - return menu.toggle(e, this, ThreadWatcher); - }); - return this.addMenuEntries(); - }, - addHeaderMenuEntry: function() { - var entryEl; - if (g.VIEW !== 'thread') { - return; - } - entryEl = $.el('a', { - href: 'javascript:;' - }); - Header.menu.addEntry({ - el: entryEl, - order: 60, - open: function() { - var addClass, ref, rmClass, text; - ref = !!ThreadWatcher.db.get({ - boardID: g.BOARD.ID, - threadID: g.THREADID - }) ? ['unwatch-thread', 'watch-thread', 'Unwatch thread'] : ['watch-thread', 'unwatch-thread', 'Watch thread'], addClass = ref[0], rmClass = ref[1], text = ref[2]; - $.addClass(entryEl, addClass); - $.rmClass(entryEl, rmClass); - entryEl.textContent = text; - return true; - } - }); - return $.on(entryEl, 'click', function() { - return ThreadWatcher.toggle(g.threads.get(g.BOARD + "." + g.THREADID)); - }); - }, - addMenuEntries: function() { - var cb, conf, entries, entry, j, len1, name, open, ref, ref1, text, title; - entries = []; - entries.push({ - text: 'Open all threads', - cb: ThreadWatcher.cb.openAll, - open: function() { - this.el.classList.toggle('disabled', !ThreadWatcher.list.firstElementChild); - return true; - } - }); - entries.push({ - text: 'Open unread threads', - cb: ThreadWatcher.cb.openUnread, - open: function() { - this.el.classList.toggle('disabled', !$('.replies-unread', ThreadWatcher.list)); - return true; - } - }); - entries.push({ - text: 'Open dead threads', - cb: ThreadWatcher.cb.openDeads, - open: function() { - this.el.classList.toggle('disabled', !$('.dead-thread', ThreadWatcher.list)); - return true; - } - }); - entries.push({ - text: 'Prune dead threads', - cb: ThreadWatcher.cb.pruneDeads, - open: function() { - this.el.classList.toggle('disabled', !$('.dead-thread', ThreadWatcher.list)); - return true; - } - }); - entries.push({ - text: 'Dismiss posts quoting you', - title: 'Unhighlight the thread watcher icon and threads until there are new replies quoting you.', - cb: ThreadWatcher.cb.dismiss, - open: function() { - this.el.classList.toggle('disabled', !$.hasClass(ThreadWatcher.shortcut, 'replies-quoting-you')); - return true; - } - }); - for (j = 0, len1 = entries.length; j < len1; j++) { - ref = entries[j], text = ref.text, title = ref.title, cb = ref.cb, open = ref.open; - entry = { - el: $.el('a', { - textContent: text, - href: 'javascript:;' - }) - }; - if (title) { - entry.el.title = title; - } - $.on(entry.el, 'click', cb); - entry.open = open.bind(entry); - this.menu.addEntry(entry); - } - ref1 = Config.threadWatcher; - for (name in ref1) { - conf = ref1[name]; - this.addCheckbox(name, conf[1]); - } - }, - addCheckbox: function(name, desc) { - var entry, input; - entry = { - type: 'thread watcher', - el: UI.checkbox(name, name.replace(' Thread Watcher', '')) - }; - entry.el.title = desc; - input = entry.el.firstElementChild; - if (name === 'Show Unread Count' && !ThreadWatcher.unreadEnabled) { - input.disabled = true; - $.addClass(entry.el, 'disabled'); - entry.el.title += '\n[Remember Last Read Post is disabled.]'; - } - $.on(input, 'change', $.cb.checked); - if (name === 'Current Board' || name === 'Show Page' || name === 'Show Unread Count' || name === 'Show Site Prefix') { - $.on(input, 'change', ThreadWatcher.refresh); - } - if (name === 'Show Page' || name === 'Show Unread Count' || name === 'Auto Update Thread Watcher') { - $.on(input, 'change', ThreadWatcher.fetchAuto); - } - return this.menu.addEntry(entry); - } - } - }; - - return ThreadWatcher; - -}).call(this); - -Unread = (function() { - var Unread; - - Unread = { - init: function() { - if (!(g.VIEW === 'thread' && (Conf['Unread Count'] || Conf['Unread Favicon'] || Conf['Unread Line'] || Conf['Remember Last Read Post'] || Conf['Desktop Notifications'] || Conf['Quote Threading']))) { - return; - } - if (Conf['Remember Last Read Post']) { - $.sync('Remember Last Read Post', function(enabled) { - return Conf['Remember Last Read Post'] = enabled; - }); - this.db = new DataBoard('lastReadPosts', this.sync); - } - this.hr = $.el('hr', { - id: 'unread-line', - className: 'unread-line' - }); - this.posts = new Set(); - this.postsQuotingYou = new Set(); - this.order = new RandomAccessList(); - this.position = null; - Callbacks.Thread.push({ - name: 'Unread', - cb: this.node - }); - return Callbacks.Post.push({ - name: 'Unread', - cb: this.addPost - }); - }, - node: function() { - var ID, j, len, ref, ref1, resetLink; - Unread.thread = this; - Unread.title = d.title; - Unread.lastReadPost = ((ref = Unread.db) != null ? ref.get({ - boardID: this.board.ID, - threadID: this.ID - }) : void 0) || 0; - Unread.readCount = 0; - ref1 = this.posts.keys; - for (j = 0, len = ref1.length; j < len; j++) { - ID = ref1[j]; - if (+ID <= Unread.lastReadPost) { - Unread.readCount++; - } - } - $.one(d, '4chanXInitFinished', Unread.ready); - $.on(d, 'PostsInserted', Unread.onUpdate); - $.on(d, 'ThreadUpdate', function(e) { - if (e.detail[404]) { - return Unread.update(); - } - }); - resetLink = $.el('a', { - href: 'javascript:;', - className: 'unread-reset', - textContent: 'Mark all unread' - }); - $.on(resetLink, 'click', Unread.reset); - return Header.menu.addEntry({ - el: resetLink, - order: 70 - }); - }, - ready: function() { - if (Conf['Remember Last Read Post'] && Conf['Scroll to Last Read Post']) { - Unread.scroll(); - } - Unread.setLine(true); - Unread.read(); - Unread.update(); - $.on(d, 'scroll visibilitychange', Unread.read); - if (Conf['Unread Line']) { - return $.on(d, 'visibilitychange', Unread.setLine); - } - }, - positionPrev: function() { - if (Unread.position) { - return Unread.position.prev; - } else { - return Unread.order.last; - } - }, - scroll: function() { - var bottom, hash, position; - if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { - return; - } - position = Unread.positionPrev(); - while (position) { - bottom = position.data.nodes.bottom; - if (!bottom.getBoundingClientRect().height) { - position = position.prev; - } else { - Header.scrollToIfNeeded(bottom, true); - break; - } - } - }, - reset: function() { - if (Unread.lastReadPost == null) { - return; - } - Unread.posts = new Set(); - Unread.postsQuotingYou = new Set(); - Unread.order = new RandomAccessList(); - Unread.position = null; - Unread.lastReadPost = 0; - Unread.readCount = 0; - Unread.thread.posts.forEach(function(post) { - return Unread.addPost.call(post); - }); - $.forceSync('Remember Last Read Post'); - if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) { - Unread.db.set({ - boardID: Unread.thread.board.ID, - threadID: Unread.thread.ID, - val: 0 - }); - } - Unread.updatePosition(); - Unread.setLine(); - return Unread.update(); - }, - sync: function() { - var ID, i, j, lastReadPost, postIDs, ref, ref1; - if (Unread.lastReadPost == null) { - return; - } - lastReadPost = Unread.db.get({ - boardID: Unread.thread.board.ID, - threadID: Unread.thread.ID, - defaultValue: 0 - }); - if (!(Unread.lastReadPost < lastReadPost)) { - return; - } - Unread.lastReadPost = lastReadPost; - postIDs = Unread.thread.posts.keys; - for (i = j = ref = Unread.readCount, ref1 = postIDs.length; j < ref1; i = j += 1) { - ID = +postIDs[i]; - if (!Unread.thread.posts.get(ID).isFetchedQuote) { - if (ID > Unread.lastReadPost) { - break; - } - Unread.posts["delete"](ID); - Unread.postsQuotingYou["delete"](ID); - } - Unread.readCount++; - } - Unread.updatePosition(); - Unread.setLine(); - return Unread.update(); - }, - addPost: function() { - if (this.isFetchedQuote || this.isClone) { - return; - } - Unread.order.push(this); - if (this.ID <= Unread.lastReadPost || this.isHidden || QuoteYou.isYou(this)) { - return; - } - Unread.posts.add((Unread.posts.last = this.ID)); - Unread.addPostQuotingYou(this); - return Unread.position != null ? Unread.position : Unread.position = Unread.order[this.ID]; - }, - addPostQuotingYou: function(post) { - var j, len, quotelink, ref, ref1; - ref = post.nodes.quotelinks; - for (j = 0, len = ref.length; j < len; j++) { - quotelink = ref[j]; - if (!((ref1 = QuoteYou.db) != null ? ref1.get(Get.postDataFromLink(quotelink)) : void 0)) { - continue; - } - Unread.postsQuotingYou.add((Unread.postsQuotingYou.last = post.ID)); - Unread.openNotification(post); - return; - } - }, - openNotification: function(post, predicate) { - var notif; - if (predicate == null) { - predicate = ' replied to you'; - } - if (!Header.areNotificationsEnabled) { - return; - } - notif = new Notification("" + post.info.nameBlock + predicate, { - body: post.commentDisplay(), - icon: Favicon.logo - }); - notif.onclick = function() { - Header.scrollToIfNeeded(post.nodes.bottom, true); - return window.focus(); - }; - return notif.onshow = function() { - return setTimeout(function() { - return notif.close(); - }, 7 * $.SECOND); - }; - }, - onUpdate: function() { - return $.queueTask(function() { - Unread.setLine(); - Unread.read(); - return Unread.update(); - }); - }, - readSinglePost: function(post) { - var ID; - ID = post.ID; - if (!Unread.posts.has(ID)) { - return; - } - Unread.posts["delete"](ID); - Unread.postsQuotingYou["delete"](ID); - Unread.updatePosition(); - Unread.saveLastReadPost(); - return Unread.update(); - }, - read: $.debounce(100, function(e) { - var ID, bottom, count, data, ref; - if (!Unread.posts.size && Unread.readCount !== Unread.thread.posts.keys.length) { - Unread.saveLastReadPost(); - } - if (d.hidden || !Unread.posts.size) { - return; - } - count = 0; - while (Unread.position) { - ref = Unread.position, ID = ref.ID, data = ref.data; - bottom = data.nodes.bottom; - if (!(!bottom.getBoundingClientRect().height || Header.getBottomOf(bottom) > -1)) { - break; - } - count++; - Unread.posts["delete"](ID); - Unread.postsQuotingYou["delete"](ID); - Unread.position = Unread.position.next; - } - if (!count) { - return; - } - Unread.updatePosition(); - Unread.saveLastReadPost(); - if (e) { - return Unread.update(); - } - }), - updatePosition: function() { - while (Unread.position && !Unread.posts.has(Unread.position.ID)) { - Unread.position = Unread.position.next; - } - }, - saveLastReadPost: $.debounce(2 * $.SECOND, function() { - var ID, i, j, postIDs, ref, ref1; - $.forceSync('Remember Last Read Post'); - if (!(Conf['Remember Last Read Post'] && Unread.db)) { - return; - } - postIDs = Unread.thread.posts.keys; - for (i = j = ref = Unread.readCount, ref1 = postIDs.length; j < ref1; i = j += 1) { - ID = +postIDs[i]; - if (!Unread.thread.posts.get(ID).isFetchedQuote) { - if (Unread.posts.has(ID)) { - break; - } - Unread.lastReadPost = ID; - } - Unread.readCount++; - } - if (Unread.thread.isDead && !Unread.thread.isArchived) { - return; - } - return Unread.db.set({ - boardID: Unread.thread.board.ID, - threadID: Unread.thread.ID, - val: Unread.lastReadPost - }); - }), - setLine: function(force) { - var node, oldPosition, ref; - if (!Conf['Unread Line']) { - return; - } - if (Unread.hr.hidden || d.hidden || (force === true)) { - oldPosition = Unread.linePosition; - if ((Unread.linePosition = Unread.positionPrev())) { - if (Unread.linePosition !== oldPosition) { - node = Unread.linePosition.data.nodes.bottom; - if (((ref = node.nextSibling) != null ? ref.tagName : void 0) === 'BR') { - node = node.nextSibling; - } - $.after(node, Unread.hr); - } - } else { - $.rm(Unread.hr); - } - } - return Unread.hr.hidden = Unread.linePosition === Unread.order.last; - }, - update: function() { - var count, countQuotingYou, isDead, titleCount, titleDead, titleQuotingYou; - count = Unread.posts.size; - countQuotingYou = Unread.postsQuotingYou.size; - if (Conf['Unread Count']) { - titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : ''; - titleCount = count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : ''; - titleDead = Unread.thread.isDead ? Unread.title.replace('-', (Unread.thread.isArchived ? '- Archived -' : '- 404 -')) : Unread.title; - d.title = "" + titleQuotingYou + titleCount + titleDead; - } - Unread.saveThreadWatcherCount(); - if (Conf['Unread Favicon'] && g.SITE.software === 'yotsuba') { - isDead = Unread.thread.isDead; - return Favicon.set((countQuotingYou ? (isDead ? 'unreadDeadY' : 'unreadY') : count ? (isDead ? 'unreadDead' : 'unread') : (isDead ? 'dead' : 'default'))); - } - }, - saveThreadWatcherCount: $.debounce(2 * $.SECOND, function() { - var i, j, posts, quotingYou, ref; - $.forceSync('Remember Last Read Post'); - if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) { - quotingYou = !Conf['Require OP Quote Link'] && QuoteYou.isYou(Unread.thread.OP) ? Unread.posts : Unread.postsQuotingYou; - if (!quotingYou.size) { - quotingYou.last = 0; - } else if (!quotingYou.has(quotingYou.last)) { - quotingYou.last = 0; - posts = Unread.thread.posts.keys; - for (i = j = ref = posts.length - 1; j >= 0; i = j += -1) { - if (quotingYou.has(+posts[i])) { - quotingYou.last = posts[i]; - break; - } - } - } - return ThreadWatcher.update(g.SITE.ID, Unread.thread.board.ID, Unread.thread.ID, { - last: Unread.thread.lastPost, - isDead: Unread.thread.isDead, - isArchived: Unread.thread.isArchived, - unread: Unread.posts.size, - quotingYou: quotingYou.last || 0 - }); - } - }) - }; - - return Unread; - -}).call(this); - -UnreadIndex = (function() { - var UnreadIndex; - - UnreadIndex = { - lastReadPost: $.dict(), - hr: $.dict(), - markReadLink: $.dict(), - init: function() { - if (!(g.VIEW === 'index' && Conf['Remember Last Read Post'] && Conf['Unread Line in Index'])) { - return; - } - this.enabled = true; - this.db = new DataBoard('lastReadPosts', this.sync); - Callbacks.Thread.push({ - name: 'Unread Line in Index', - cb: this.node - }); - $.on(d, 'IndexRefreshInternal', this.onIndexRefresh); - return $.on(d, 'PostsInserted PostsRemoved', this.onPostsInserted); - }, - node: function() { - UnreadIndex.lastReadPost[this.fullID] = UnreadIndex.db.get({ - boardID: this.board.ID, - threadID: this.ID - }) || 0; - if (!Index.enabled) { - return UnreadIndex.update(this); - } - }, - onIndexRefresh: function(e) { - var i, len, ref, results, thread, threadID; - if (e.detail.isCatalog) { - return; - } - ref = e.detail.threadIDs; - results = []; - for (i = 0, len = ref.length; i < len; i++) { - threadID = ref[i]; - thread = g.threads.get(threadID); - results.push(UnreadIndex.update(thread)); - } - return results; - }, - onPostsInserted: function(e) { - var ref, ref1, thread, wasVisible; - if (e.target === Index.root) { - return; - } - thread = Get.threadFromNode(e.target); - if (!thread || thread.nodes.root !== e.target) { - return; - } - wasVisible = !!((ref = UnreadIndex.hr[thread.fullID]) != null ? ref.parentNode : void 0); - UnreadIndex.update(thread); - if (Conf['Scroll to Last Read Post'] && e.type === 'PostsInserted' && !wasVisible && !!((ref1 = UnreadIndex.hr[thread.fullID]) != null ? ref1.parentNode : void 0)) { - return Header.scrollToIfNeeded(UnreadIndex.hr[thread.fullID], true); - } - }, - sync: function() { - return g.threads.forEach(function(thread) { - var lastReadPost, ref; - lastReadPost = UnreadIndex.db.get({ - boardID: thread.board.ID, - threadID: thread.ID - }) || 0; - if (lastReadPost !== UnreadIndex.lastReadPost[thread.fullID]) { - UnreadIndex.lastReadPost[thread.fullID] = lastReadPost; - if ((ref = thread.nodes.root) != null ? ref.parentNode : void 0) { - return UnreadIndex.update(thread); - } - } - }); - }, - update: function(thread) { - var divider, firstUnread, hasUnread, hr, lastReadPost, link, repliesRead, repliesShown; - lastReadPost = UnreadIndex.lastReadPost[thread.fullID]; - repliesShown = 0; - repliesRead = 0; - firstUnread = null; - thread.posts.forEach(function(post) { - if (post.isReply && thread.nodes.root.contains(post.nodes.root)) { - repliesShown++; - if (post.ID <= lastReadPost) { - return repliesRead++; - } else if ((!firstUnread || post.ID < firstUnread.ID) && !post.isHidden && !QuoteYou.isYou(post)) { - return firstUnread = post; - } - } - }); - hr = UnreadIndex.hr[thread.fullID]; - if (firstUnread && (repliesRead || (lastReadPost === thread.OP.ID && (!$(g.SITE.selectors.summary, thread.nodes.root) || thread.ID in ExpandThread.statuses)))) { - if (!hr) { - hr = UnreadIndex.hr[thread.fullID] = $.el('hr', { - className: 'unread-line' - }); - } - $.before(firstUnread.nodes.root, hr); - } else { - $.rm(hr); - } - hasUnread = repliesShown ? firstUnread || !repliesRead : Index.enabled ? thread.lastPost > lastReadPost : thread.OP.ID > lastReadPost; - thread.nodes.root.classList.toggle('unread-thread', hasUnread); - link = UnreadIndex.markReadLink[thread.fullID]; - if (!link) { - link = UnreadIndex.markReadLink[thread.fullID] = $.el('a', { - className: 'unread-mark-read brackets-wrap', - href: 'javascript:;', - textContent: 'Mark Read' - }); - $.on(link, 'click', UnreadIndex.markRead); - } - if ((divider = $(g.SITE.selectors.threadDivider, thread.nodes.root))) { - return $.before(divider, link); - } else { - return $.add(thread.nodes.root, link); - } - }, - markRead: function() { - var thread; - thread = Get.threadFromNode(this); - UnreadIndex.lastReadPost[thread.fullID] = thread.lastPost; - UnreadIndex.db.set({ - boardID: thread.board.ID, - threadID: thread.ID, - val: thread.lastPost - }); - $.rm(UnreadIndex.hr[thread.fullID]); - thread.nodes.root.classList.remove('unread-thread'); - return ThreadWatcher.update(g.SITE.ID, thread.board.ID, thread.ID, { - last: thread.lastPost, - unread: 0, - quotingYou: 0 - }); - } - }; - - return UnreadIndex; - -}).call(this); - -Captcha = {}; - -(function() { - Captcha.cache = { - init: function() { - $.on(d, 'SaveCaptcha', (function(_this) { - return function(e) { - return _this.saveAPI(e.detail); - }; - })(this)); - return $.on(d, 'NoCaptcha', (function(_this) { - return function(e) { - return _this.noCaptcha(e.detail); - }; - })(this)); - }, - captchas: [], - getCount: function() { - return this.captchas.length; - }, - neededRaw: function() { - return !(this.haveCookie() || this.captchas.length || QR.req || this.submitCB) && (QR.posts.length > 1 || Conf['Auto-load captcha'] || !QR.posts[0].isOnlyQuotes() || QR.posts[0].file); - }, - needed: function() { - return this.neededRaw() && $.event('LoadCaptcha'); - }, - prerequest: function() { - if (!Conf['Prerequest Captcha']) { - return; - } - return $.queueTask((function(_this) { - return function() { - var isReply; - if (!_this.prerequested && _this.neededRaw() && !$.event('LoadCaptcha') && !QR.captcha.occupied() && QR.cooldown.seconds <= 60 && QR.selected === QR.posts[QR.posts.length - 1] && !QR.selected.isOnlyQuotes()) { - isReply = QR.selected.thread !== 'new'; - if (!$.event('RequestCaptcha', { - isReply: isReply - })) { - _this.prerequested = true; - _this.submitCB = function(captcha) { - if (captcha) { - return _this.save(captcha); - } - }; - return _this.updateCount(); - } - } - }; - })(this)); - }, - haveCookie: function() { - return /\b_ct=/.test(d.cookie) && QR.posts[0].thread !== 'new'; - }, - getOne: function() { - var captcha; - delete this.prerequested; - this.clear(); - if ((captcha = this.captchas.shift())) { - this.count(); - return captcha; - } else { - return null; - } - }, - request: function(isReply) { - if (!this.submitCB) { - if ($.event('RequestCaptcha', { - isReply: isReply - })) { - return; - } - } - return (function(_this) { - return function(cb) { - _this.submitCB = cb; - return _this.updateCount(); - }; - })(this); - }, - abort: function() { - if (this.submitCB) { - delete this.submitCB; - $.event('AbortCaptcha'); - return this.updateCount(); - } - }, - saveAPI: function(captcha) { - var cb; - if ((cb = this.submitCB)) { - delete this.submitCB; - cb(captcha); - return this.updateCount(); - } else { - return this.save(captcha); - } - }, - noCaptcha: function(detail) { - var cb; - if ((cb = this.submitCB)) { - if (!this.haveCookie() || (detail != null ? detail.error : void 0)) { - QR.error((detail != null ? detail.error : void 0) || 'Failed to retrieve captcha.'); - QR.captcha.setup(d.activeElement === QR.nodes.status); - } - delete this.submitCB; - cb(); - return this.updateCount(); - } - }, - save: function(captcha) { - var cb; - if ((cb = this.submitCB)) { - this.abort(); - cb(captcha); - return; - } - this.captchas.push(captcha); - this.captchas.sort(function(a, b) { - return a.timeout - b.timeout; - }); - return this.count(); - }, - clear: function() { - var captcha, i, j, len, now, ref; - if (this.captchas.length) { - now = Date.now(); - ref = this.captchas; - for (i = j = 0, len = ref.length; j < len; i = ++j) { - captcha = ref[i]; - if (captcha.timeout > now) { - break; - } - } - if (i) { - this.captchas = this.captchas.slice(i); - return this.count(); - } - } - }, - count: function() { - clearTimeout(this.timer); - if (this.captchas.length) { - this.timer = setTimeout(this.clear.bind(this), this.captchas[0].timeout - Date.now()); - } - return this.updateCount(); - }, - updateCount: function() { - return $.event('CaptchaCount', this.captchas.length); - } - }; - -}).call(this); - -(function() { - Captcha.replace = { - init: function() { - var ref; - if (!(g.SITE.software === 'yotsuba' && d.cookie.indexOf('pass_enabled=1') < 0)) { - return; - } - if (Conf['Force Noscript Captcha'] && Main.jsEnabled) { - $.ready(Captcha.replace.noscript); - return; - } - if (Conf['captchaLanguage'].trim()) { - if ((ref = location.hostname) === 'boards.4chan.org' || ref === 'boards.4channel.org') { - return $.onExists(doc, '#captchaFormPart', function(node) { - return $.onExists(node, 'iframe[src^="https://www.google.com/recaptcha/"]', Captcha.replace.iframe); - }); - } else { - return $.onExists(doc, 'iframe[src^="https://www.google.com/recaptcha/"]', Captcha.replace.iframe); - } - } - }, - noscript: function() { - var insert, noscript, original, span, toggle; - if (!((original = $('#g-recaptcha')) && (noscript = $('noscript', original.parentNode)))) { - return; - } - span = $.el('span', { - id: 'captcha-forced-noscript' - }); - $.replace(noscript, span); - $.rm(original); - insert = function() { - span.innerHTML = noscript.textContent; - return Captcha.replace.iframe($('iframe[src^="https://www.google.com/recaptcha/"]', span)); - }; - if ((toggle = $('#togglePostFormLink a, #form-link'))) { - return $.on(toggle, 'click', insert); - } else { - return insert(); - } - }, - iframe: function(iframe) { - var lang, src; - if ((lang = Conf['captchaLanguage'].trim())) { - src = /[?&]hl=/.test(iframe.src) ? iframe.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang)) : iframe.src + ("&hl=" + (encodeURIComponent(lang))); - if (iframe.src !== src) { - iframe.src = src; - } - } - } - }; - -}).call(this); - -(function() { - Captcha.t = { - init: function() { - var root; - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - return; - } - if (!(this.isEnabled = !!$('#t-root') || !$.id('postForm'))) { - return; - } - root = $.el('div', { - className: 'captcha-root' - }); - this.nodes = { - root: root - }; - $.addClass(QR.nodes.el, 'has-captcha', 'captcha-t'); - return $.after(QR.nodes.com.parentNode, root); - }, - moreNeeded: function() {}, - getThread: function() { - var boardID, threadID; - boardID = g.BOARD.ID; - if (QR.posts[0].thread === 'new') { - threadID = '0'; - } else { - threadID = '' + QR.posts[0].thread; - } - return { - boardID: boardID, - threadID: threadID - }; - }, - setup: function(focus) { - if (!this.isEnabled) { - return; - } - if (!this.nodes.container) { - this.nodes.container = $.el('div', { - className: 'captcha-container' - }); - $.prepend(this.nodes.root, this.nodes.container); - Captcha.t.currentThread = Captcha.t.getThread(); - $.global(function() { - var el; - el = document.querySelector('#qr .captcha-container'); - window.TCaptcha.init(el, this.boardID, +this.threadID); - return window.TCaptcha.setErrorCb(function(err) { - return window.dispatchEvent(new CustomEvent('CreateNotification', { - detail: { - type: 'warning', - content: '' + err - } - })); - }); - }, Captcha.t.currentThread); - } - if (focus) { - return $('#t-resp').focus(); - } - }, - destroy: function() { - if (!(this.isEnabled && this.nodes.container)) { - return; - } - $.global(function() { - return window.TCaptcha.destroy(); - }); - $.rm(this.nodes.container); - return delete this.nodes.container; - }, - updateThread: function() { - var boardID, newThread, ref, threadID; - if (!this.isEnabled) { - return; - } - ref = Captcha.t.currentThread || {}, boardID = ref.boardID, threadID = ref.threadID; - newThread = Captcha.t.getThread(); - if (!(newThread.boardID === boardID && newThread.threadID === threadID)) { - Captcha.t.destroy(); - return Captcha.t.setup(); - } - }, - getOne: function() { - var el, i, key, len, ref, response; - response = {}; - if (this.nodes.container) { - ref = ['t-response', 't-challenge']; - for (i = 0, len = ref.length; i < len; i++) { - key = ref[i]; - response[key] = $("[name='" + key + "']", this.nodes.container).value; - } - } - if (!response['t-response'] && !((el = $('#t-msg')) && /Verification not required/i.test(el.textContent))) { - response = null; - } - return response; - }, - setUsed: function() { - if (!this.isEnabled) { - return; - } - if (this.nodes.container) { - return $.global(function() { - return window.TCaptcha.clearChallenge(); - }); - } - }, - occupied: function() { - return !!this.nodes.container; - } - }; - -}).call(this); - -(function() { - var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Captcha.v2 = { - lifetime: 2 * $.MINUTE, - init: function() { - var counter, root; - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - return; - } - if (!(this.isEnabled = !!$('#g-recaptcha, #captcha-forced-noscript') || !$.id('postForm'))) { - return; - } - if ((this.noscript = Conf['Force Noscript Captcha'] || !Main.jsEnabled)) { - $.addClass(QR.nodes.el, 'noscript-captcha'); - } - Captcha.cache.init(); - $.on(d, 'CaptchaCount', this.count.bind(this)); - root = $.el('div', { - className: 'captcha-root' - }); - $.extend(root, {innerHTML: "
      "}); - counter = $('.captcha-counter > a', root); - this.nodes = { - root: root, - counter: counter - }; - this.count(); - $.addClass(QR.nodes.el, 'has-captcha', 'captcha-v2'); - $.after(QR.nodes.com.parentNode, root); - $.on(counter, 'click', this.toggle.bind(this)); - $.on(counter, 'keydown', (function(_this) { - return function(e) { - if (Keybinds.keyCode(e) !== 'Space') { - return; - } - _this.toggle(); - e.preventDefault(); - return e.stopPropagation(); - }; - })(this)); - return $.on(window, 'captcha:success', (function(_this) { - return function() { - return $.queueTask(function() { - return _this.save(false); - }); - }; - })(this)); - }, - timeouts: {}, - prevNeeded: 0, - noscriptURL: function() { - var lang, url; - url = 'https://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc'; - if ((lang = Conf['captchaLanguage'].trim())) { - url += "&hl=" + (encodeURIComponent(lang)); - } - return url; - }, - moreNeeded: function() { - return $.queueTask((function(_this) { - return function() { - var needed; - needed = Captcha.cache.needed(); - if (needed && !_this.prevNeeded) { - _this.setup(QR.cooldown.auto && d.activeElement === QR.nodes.status); - } - return _this.prevNeeded = needed; - }; - })(this)); - }, - toggle: function() { - if (this.nodes.container && !this.timeouts.destroy) { - return this.destroy(); - } else { - return this.setup(true, true); - } - }, - setup: function(focus, force) { - if (!(this.isEnabled && (Captcha.cache.needed() || force))) { - return; - } - if (focus) { - $.addClass(QR.nodes.el, 'focus'); - this.nodes.counter.focus(); - } - if (this.timeouts.destroy) { - clearTimeout(this.timeouts.destroy); - delete this.timeouts.destroy; - return this.reload(); - } - if (this.nodes.container) { - $.queueTask((function(_this) { - return function() { - var iframe; - if (_this.nodes.container && d.activeElement === _this.nodes.counter && (iframe = $('iframe[src^="https://www.google.com/recaptcha/"]', _this.nodes.container))) { - iframe.focus(); - return QR.focus(); - } - }; - })(this)); - return; - } - this.nodes.container = $.el('div', { - className: 'captcha-container' - }); - $.prepend(this.nodes.root, this.nodes.container); - new MutationObserver(this.afterSetup.bind(this)).observe(this.nodes.container, { - childList: true, - subtree: true - }); - if (this.noscript) { - return this.setupNoscript(); - } else { - return this.setupJS(); - } - }, - setupNoscript: function() { - var div, iframe, textarea; - iframe = $.el('iframe', { - id: 'qr-captcha-iframe', - scrolling: 'no', - src: this.noscriptURL() - }); - div = $.el('div'); - textarea = $.el('textarea'); - $.add(div, textarea); - return $.add(this.nodes.container, [iframe, div]); - }, - setupJS: function() { - return $.global(function() { - var cbNative, render, script; - render = function() { - var classList, container; - classList = document.documentElement.classList; - container = document.querySelector('#qr .captcha-container'); - return container.dataset.widgetID = window.grecaptcha.render(container, { - sitekey: '6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc', - theme: classList.contains('tomorrow') || classList.contains('spooky') || classList.contains('dark-captcha') ? 'dark' : 'light', - callback: function(response) { - return window.dispatchEvent(new CustomEvent('captcha:success', { - detail: response - })); - } - }); - }; - if (window.grecaptcha) { - return render(); - } else { - cbNative = window.onRecaptchaLoaded; - window.onRecaptchaLoaded = function() { - render(); - return cbNative(); - }; - if (!document.head.querySelector('script[src^="https://www.google.com/recaptcha/api.js"]')) { - script = document.createElement('script'); - script.src = 'https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoaded&render=explicit'; - return document.head.appendChild(script); - } - } - }); - }, - afterSetup: function(mutations) { - var i, iframe, j, len, len1, mutation, node, ref, textarea; - for (i = 0, len = mutations.length; i < len; i++) { - mutation = mutations[i]; - ref = mutation.addedNodes; - for (j = 0, len1 = ref.length; j < len1; j++) { - node = ref[j]; - if ((iframe = $.x('./descendant-or-self::iframe[starts-with(@src, "https://www.google.com/recaptcha/")]', node))) { - this.setupIFrame(iframe); - } - if ((textarea = $.x('./descendant-or-self::textarea', node))) { - this.setupTextArea(textarea); - } - } - } - }, - setupIFrame: function(iframe) { - var ref, ref1; - if (!doc.contains(iframe)) { - return; - } - Captcha.replace.iframe(iframe); - $.addClass(QR.nodes.el, 'captcha-open'); - this.fixQRPosition(); - $.on(iframe, 'load', this.fixQRPosition); - if (d.activeElement === this.nodes.counter) { - iframe.focus(); - } - if (((ref = $.engine) === 'blink' || ref === 'edge') && (ref1 = iframe.parentNode, indexOf.call($$('#qr .captcha-container > div > div:first-of-type'), ref1) >= 0)) { - return $.on(iframe.parentNode, 'scroll', function() { - return this.scrollTop = 0; - }); - } - }, - fixQRPosition: function() { - if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) { - QR.nodes.el.style.top = ''; - return QR.nodes.el.style.bottom = '0px'; - } - }, - setupTextArea: function(textarea) { - return $.one(textarea, 'input', (function(_this) { - return function() { - return _this.save(true); - }; - })(this)); - }, - destroy: function() { - if (!this.isEnabled) { - return; - } - delete this.timeouts.destroy; - $.rmClass(QR.nodes.el, 'captcha-open'); - if (this.nodes.container) { - $.global(function() { - var container; - container = document.querySelector('#qr .captcha-container'); - return window.grecaptcha.reset(container.dataset.widgetID); - }); - $.rm(this.nodes.container); - return delete this.nodes.container; - } - }, - getOne: function(isReply) { - return Captcha.cache.getOne(isReply); - }, - save: function(pasted, token) { - var base, focus, ref; - Captcha.cache.save({ - response: token || $('textarea', this.nodes.container).value, - timeout: Date.now() + this.lifetime - }); - focus = ((ref = d.activeElement) != null ? ref.nodeName : void 0) === 'IFRAME' && /https?:\/\/www\.google\.com\/recaptcha\//.test(d.activeElement.src); - if (Captcha.cache.needed()) { - if (focus) { - if (QR.cooldown.auto || Conf['Post on Captcha Completion']) { - this.nodes.counter.focus(); - } else { - QR.nodes.status.focus(); - } - } - this.reload(); - } else { - if (pasted) { - this.destroy(); - } else { - if ((base = this.timeouts).destroy == null) { - base.destroy = setTimeout(this.destroy.bind(this), 3 * $.SECOND); - } - } - if (focus) { - QR.nodes.status.focus(); - } - } - if (Conf['Post on Captcha Completion'] && !QR.cooldown.auto) { - return QR.submit(); - } - }, - count: function() { - var count, loading; - count = Captcha.cache.getCount(); - loading = Captcha.cache.submitCB ? '...' : ''; - this.nodes.counter.textContent = "Captchas: " + count + loading; - return this.moreNeeded(); - }, - reload: function() { - if ($('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', this.nodes.container)) { - this.destroy(); - return this.setup(false, true); - } else { - return $.global(function() { - var container; - container = document.querySelector('#qr .captcha-container'); - return window.grecaptcha.reset(container.dataset.widgetID); - }); - } - }, - occupied: function() { - return !!this.nodes.container && !this.timeouts.destroy; - } - }; - -}).call(this); - -PassLink = (function() { - var PassLink; - - PassLink = { - init: function() { - if (!(g.SITE.software === 'yotsuba' && Conf['Pass Link'])) { - return; - } - return Main.ready(this.ready); - }, - ready: function() { - var passLink, styleSelector; - if (!(styleSelector = $.id('styleSelector'))) { - return; - } - passLink = $.el('span', { - className: 'brackets-wrap pass-link-container' - }); - $.extend(passLink, {innerHTML: "4chan Pass"}); - $.on(passLink.firstElementChild, 'click', function() { - return window.open("//sys." + (location.hostname.split('.')[1]) + ".org/auth", Date.now(), 'width=500,height=280,toolbar=0'); - }); - return $.before(styleSelector.previousSibling, [passLink, $.tn('\u00A0\u00A0')]); - } - }; - - return PassLink; - -}).call(this); - -PostRedirect = (function() { - var PostRedirect; - - PostRedirect = { - init: function() { - return $.on(d, 'QRPostSuccessful', (function(_this) { - return function(e) { - if (!e.detail.redirect) { - return; - } - _this.event = e; - _this.delays = 0; - return $.queueTask(function() { - if (e === _this.event && _this.delays === 0) { - return location.href = e.detail.redirect; - } - }); - }; - })(this)); - }, - delays: 0, - delay: function() { - var e; - if (!this.event) { - return null; - } - e = this.event; - this.delays++; - return (function(_this) { - return function() { - if (e !== _this.event) { - return; - } - _this.delays--; - if (_this.delays === 0) { - return location.href = e.detail.redirect; - } - }; - })(this); - } - }; - - return PostRedirect; - -}).call(this); - -PostSuccessful = (function() { - var PostSuccessful; - - PostSuccessful = { - init: function() { - if (!Conf['Remember Your Posts']) { - return; - } - return $.ready(this.ready); - }, - ready: function() { - var _, db, postID, ref, threadID; - if (d.title !== 'Post successful!') { - return; - } - ref = $('h1').nextSibling.textContent.match(/thread:(\d+),no:(\d+)/), _ = ref[0], threadID = ref[1], postID = ref[2]; - postID = +postID; - threadID = +threadID || postID; - db = new DataBoard('yourPosts'); - return db.set({ - boardID: g.BOARD.ID, - threadID: threadID, - postID: postID, - val: true - }); - } - }; - - return PostSuccessful; - -}).call(this); - -QR = (function() { - var QR, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - QR = { - 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: function() { - var sc; - if (!Conf['Quick Reply']) { - return; - } - this.posts = []; - $.on(d, '4chanXInitFinished', function() { - return BoardConfig.ready(QR.initReady); - }); - Callbacks.Post.push({ - name: 'Quick Reply', - cb: this.node - }); - this.shortcut = sc = $.el('a', { - className: 'fa fa-comment-o disabled', - textContent: 'QR', - title: 'Quick Reply', - href: 'javascript:;' - }); - $.on(sc, 'click', function() { - if (!QR.postingIsEnabled) { - return; - } - if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) { - QR.open(); - return QR.nodes.com.focus(); - } else { - return QR.close(); - } - }); - return Header.addShortcut('qr', sc, 540); - }, - initReady: function() { - var captchaVersion, config, link, linkBot, navLinksBot, origToggle, prop; - captchaVersion = $('#g-recaptcha, #captcha-forced-noscript') ? 'v2' : 't'; - QR.captcha = Captcha[captchaVersion]; - QR.postingIsEnabled = true; - config = g.BOARD.config; - prop = function(key, def) { - var ref; - return +((ref = config[key]) != null ? ref : def); - }; - QR.min_width = prop('min_image_width', 1); - QR.min_height = prop('min_image_height', 1); - QR.max_width = QR.max_height = 10000; - QR.max_size = prop('max_filesize', 4194304); - QR.max_size_video = prop('max_webm_filesize', QR.max_size); - QR.max_comment = prop('max_comment_chars', 2000); - QR.max_width_video = QR.max_height_video = 2048; - QR.max_duration_video = prop('max_webm_duration', 120); - QR.forcedAnon = !!config.forced_anon; - QR.spoiler = !!config.spoilers; - if ((origToggle = $.id('togglePostFormLink'))) { - link = $.el('h1', { - className: "qr-link-container" - }); - $.extend(link, {innerHTML: "" + ((g.VIEW === "thread") ? "Reply to Thread" : "Start a Thread") + ""}); - QR.link = link.firstElementChild; - $.on(link.firstChild, 'click', function() { - QR.open(); - return QR.nodes.com.focus(); - }); - $.before(origToggle, link); - origToggle.firstElementChild.textContent = 'Original Form'; - } - if (g.VIEW === 'thread') { - linkBot = $.el('div', { - className: "brackets-wrap qr-link-container-bottom" - }); - $.extend(linkBot, {innerHTML: "Reply to Thread"}); - $.on(linkBot.firstElementChild, 'click', function() { - QR.open(); - return QR.nodes.com.focus(); - }); - if ((navLinksBot = $('.navLinksBot'))) { - $.prepend(navLinksBot, linkBot); - } - } - $.on(d, 'QRGetFile', QR.getFile); - $.on(d, 'QRDrawFile', QR.drawFile); - $.on(d, 'QRSetFile', QR.setFile); - $.on(d, 'paste', QR.paste); - $.on(d, 'dragover', QR.dragOver); - $.on(d, 'drop', QR.dropFile); - $.on(d, 'dragstart dragend', QR.drag); - $.on(d, 'IndexRefreshInternal', QR.generatePostableThreadsList); - $.on(d, 'ThreadUpdate', QR.statusCheck); - if (!Conf['Persistent QR']) { - return; - } - QR.open(); - if (Conf['Auto Hide QR']) { - return QR.hide(); - } - }, - statusCheck: function() { - var thread; - if (!QR.nodes) { - return; - } - thread = QR.posts[0].thread; - if (thread !== 'new' && g.threads.get(g.BOARD + "." + thread).isDead) { - return QR.abort(); - } else { - return QR.status(); - } - }, - node: function() { - $.on(this.nodes.quote, 'click', QR.quote); - if (this.isFetchedQuote) { - return QR.generatePostableThreadsList(); - } - }, - open: function() { - var err; - if (QR.nodes) { - if (QR.nodes.el.hidden) { - QR.captcha.setup(); - } - QR.nodes.el.hidden = false; - QR.unhide(); - } else { - try { - QR.dialog(); - } catch (error) { - err = error; - delete QR.nodes; - Main.handleErrors({ - message: 'Quick Reply dialog creation crashed.', - error: err - }); - return; - } - } - return $.rmClass(QR.shortcut, 'disabled'); - }, - close: function() { - var j, len, post, ref; - if (QR.req) { - QR.abort(); - return; - } - QR.nodes.el.hidden = true; - QR.cleanNotifications(); - QR.blur(); - $.rmClass(QR.nodes.el, 'dump'); - $.addClass(QR.shortcut, 'disabled'); - new QR.post(true); - ref = QR.posts.splice(0, QR.posts.length - 1); - for (j = 0, len = ref.length; j < len; j++) { - post = ref[j]; - post["delete"](); - } - QR.cooldown.auto = false; - QR.status(); - return QR.captcha.destroy(); - }, - focus: function() { - return $.queueTask(function() { - if (!QR.inBubble()) { - QR.hasFocus = d.activeElement && QR.nodes.el.contains(d.activeElement); - return QR.nodes.el.classList.toggle('focus', QR.hasFocus); - } - }); - }, - inBubble: function() { - var bubbles, ref; - bubbles = $$('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); - return (ref = d.activeElement, indexOf.call(bubbles, ref) >= 0) || bubbles.some(function(el) { - return getComputedStyle(el).visibility !== 'hidden' && el.getBoundingClientRect().bottom > 0; - }); - }, - hide: function() { - QR.blur(); - $.addClass(QR.nodes.el, 'autohide'); - return QR.nodes.autohide.checked = true; - }, - unhide: function() { - $.rmClass(QR.nodes.el, 'autohide'); - return QR.nodes.autohide.checked = false; - }, - toggleHide: function() { - if (this.checked) { - return QR.hide(); - } else { - return QR.unhide(); - } - }, - blur: function() { - if (QR.nodes.el.contains(d.activeElement)) { - return d.activeElement.blur(); - } - }, - toggleSJIS: function(e) { - e.preventDefault(); - Conf['sjisPreview'] = !Conf['sjisPreview']; - $.set('sjisPreview', Conf['sjisPreview']); - return QR.nodes.el.classList.toggle('sjis-preview', Conf['sjisPreview']); - }, - texPreviewShow: function() { - if ($.hasClass(QR.nodes.el, 'tex-preview')) { - return QR.texPreviewHide(); - } - $.addClass(QR.nodes.el, 'tex-preview'); - QR.nodes.texPreview.textContent = QR.nodes.com.value; - return $.event('mathjax', null, QR.nodes.texPreview); - }, - texPreviewHide: function() { - return $.rmClass(QR.nodes.el, 'tex-preview'); - }, - addPost: function() { - var wasOpen; - wasOpen = QR.nodes && !QR.nodes.el.hidden; - QR.open(); - if (wasOpen) { - $.addClass(QR.nodes.el, 'dump'); - new QR.post(true); - } - return QR.nodes.com.focus(); - }, - setCustomCooldown: function(enabled) { - Conf['customCooldownEnabled'] = enabled; - QR.cooldown.customCooldown = enabled; - return QR.nodes.customCooldown.classList.toggle('disabled', !enabled); - }, - toggleCustomCooldown: function() { - var enabled; - enabled = $.hasClass(QR.nodes.customCooldown, 'disabled'); - QR.setCustomCooldown(enabled); - return $.set('customCooldownEnabled', enabled); - }, - error: function(err, focusOverride) { - var el, notice, notif; - QR.open(); - if (typeof err === 'string') { - el = $.tn(err); - } else { - el = err; - el.removeAttribute('style'); - } - notice = new Notice('warning', el); - QR.notifications.push(notice); - if (!Header.areNotificationsEnabled) { - if (d.hidden && !QR.cooldown.auto) { - return alert(el.textContent); - } - } else if (d.hidden || !(focusOverride || d.hasFocus())) { - notif = new Notification(el.textContent, { - body: el.textContent, - icon: Favicon.logo - }); - notif.onclick = function() { - return window.focus(); - }; - if ($.engine !== 'gecko') { - notif.onclose = function() { - return notice.close(); - }; - return notif.onshow = function() { - return setTimeout(function() { - notif.onclose = null; - return notif.close(); - }, 7 * $.SECOND); - }; - } - } - }, - connectionError: function() { - return $.el('span', {innerHTML: "Connection error while posting. [More info]"}); - }, - notifications: [], - cleanNotifications: function() { - var j, len, notification, ref; - ref = QR.notifications; - for (j = 0, len = ref.length; j < len; j++) { - notification = ref[j]; - notification.close(); - } - return QR.notifications = []; - }, - status: function() { - var disabled, status, thread, value; - if (!QR.nodes) { - return; - } - thread = QR.posts[0].thread; - if (thread !== 'new' && g.threads.get(g.BOARD + "." + thread).isDead) { - value = 'Dead'; - disabled = true; - QR.cooldown.auto = false; - } - value = QR.req ? QR.req.progress : QR.cooldown.seconds || value; - status = QR.nodes.status; - status.value = !value ? 'Submit' : QR.cooldown.auto ? "Auto " + value : value; - return status.disabled = disabled || false; - }, - openPost: function() { - var index; - QR.open(); - if (QR.selected.isLocked) { - index = QR.posts.indexOf(QR.selected); - (QR.posts[index + 1] || new QR.post()).select(); - $.addClass(QR.nodes.el, 'dump'); - return QR.cooldown.auto = true; - } - }, - quote: function(e) { - var ancestor, base, caretPos, com, frag, i, insideCode, j, k, l, len, len1, len2, len3, n, node, o, post, postRange, range, ref, ref1, ref2, ref3, ref4, ref5, ref6, root, sel, text, thread, wasOnlyQuotes; - if (e != null) { - e.preventDefault(); - } - if (!QR.postingIsEnabled) { - return; - } - sel = d.getSelection(); - post = Get.postFromNode(this); - root = post.nodes.root; - postRange = new Range(); - postRange.selectNode(root); - text = post.board.ID === g.BOARD.ID ? ">>" + post + "\n" : ">>>/" + post.board + "/" + post + "\n"; - for (i = j = 0, ref = sel.rangeCount; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) { - try { - range = sel.getRangeAt(i); - if (range.compareBoundaryPoints(Range.START_TO_START, postRange) < 0) { - range.setStartBefore(root); - } - if (range.compareBoundaryPoints(Range.END_TO_END, postRange) > 0) { - range.setEndAfter(root); - } - if (!range.toString().trim()) { - continue; - } - frag = range.cloneContents(); - ancestor = range.commonAncestorContainer; - if ($.x('ancestor-or-self::*[self::s or contains(@class,"removed-spoiler")]', ancestor)) { - $.prepend(frag, $.tn('[spoiler]')); - $.add(frag, $.tn('[/spoiler]')); - } - if (insideCode = $.x('ancestor-or-self::pre[contains(@class,"prettyprint")]', ancestor)) { - $.prepend(frag, $.tn('[code]')); - $.add(frag, $.tn('[/code]')); - } - ref1 = $$((insideCode ? 'br' : '.prettyprint br'), frag); - for (k = 0, len = ref1.length; k < len; k++) { - node = ref1[k]; - $.replace(node, $.tn('\n')); - } - ref2 = $$('br', frag); - for (l = 0, len1 = ref2.length; l < len1; l++) { - node = ref2[l]; - if (node !== frag.lastChild) { - $.replace(node, $.tn('\n>')); - } - } - if (typeof (base = g.SITE).insertTags === "function") { - base.insertTags(frag); - } - ref3 = $$('.linkify[data-original]', frag); - for (n = 0, len2 = ref3.length; n < len2; n++) { - node = ref3[n]; - $.replace(node, $.tn(node.dataset.original)); - } - ref4 = $$('.embedder', frag); - for (o = 0, len3 = ref4.length; o < len3; o++) { - node = ref4[o]; - if (((ref5 = node.previousSibling) != null ? ref5.nodeValue : void 0) === ' ') { - $.rm(node.previousSibling); - } - $.rm(node); - } - text += ">" + (frag.textContent.trim()) + "\n"; - } catch (error) {} - } - QR.openPost(); - ref6 = QR.nodes, com = ref6.com, thread = ref6.thread; - if (!com.value) { - thread.value = Get.threadFromNode(this); - } - wasOnlyQuotes = QR.selected.isOnlyQuotes(); - caretPos = com.selectionStart; - com.value = com.value.slice(0, caretPos) + text + com.value.slice(com.selectionEnd); - range = caretPos + text.length; - com.setSelectionRange(range, range); - com.focus(); - if (wasOnlyQuotes) { - QR.selected.quotedText = com.value; - } - QR.selected.save(com); - return QR.selected.save(thread); - }, - characterCount: function() { - var count, counter; - counter = QR.nodes.charCount; - count = QR.nodes.com.value.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '_').length; - counter.textContent = count; - counter.hidden = count < QR.max_comment / 2; - return (count > QR.max_comment ? $.addClass : $.rmClass)(counter, 'warning'); - }, - getFile: function() { - var ref; - return $.event('QRFile', (ref = QR.selected) != null ? ref.file : void 0); - }, - drawFile: function(e) { - var el, file, isVideo, ref; - file = (ref = QR.selected) != null ? ref.file : void 0; - if (!(file && /^(image|video)\//.test(file.type))) { - return; - } - isVideo = /^video\//.test(file); - el = $.el((isVideo ? 'video' : 'img')); - $.on(el, 'error', function() { - return QR.openError(); - }); - $.on(el, (isVideo ? 'loadeddata' : 'load'), function() { - e.target.getContext('2d').drawImage(el, 0, 0); - URL.revokeObjectURL(el.src); - return $.event('QRImageDrawn', null, e.target); - }); - return el.src = URL.createObjectURL(file); - }, - openError: function() { - var div; - div = $.el('div'); - $.extend(div, {innerHTML: "Could not open file. [More info]"}); - return QR.error(div); - }, - setFile: function(e) { - var file, name, ref, source; - ref = e.detail, file = ref.file, name = ref.name, source = ref.source; - if (name != null) { - file.name = name; - } - if (source != null) { - file.source = source; - } - QR.open(); - return QR.handleFiles([file]); - }, - drag: function(e) { - var toggle; - toggle = e.type === 'dragstart' ? $.off : $.on; - toggle(d, 'dragover', QR.dragOver); - return toggle(d, 'drop', QR.dropFile); - }, - dragOver: function(e) { - e.preventDefault(); - return e.dataTransfer.dropEffect = 'copy'; - }, - dropFile: function(e) { - if (!e.dataTransfer.files.length) { - return; - } - e.preventDefault(); - QR.open(); - return QR.handleFiles(e.dataTransfer.files); - }, - paste: function(e) { - var blob, file, file2, item, j, len, ref, score, score2, type; - if (!e.clipboardData.items) { - return; - } - file = null; - score = -1; - ref = e.clipboardData.items; - for (j = 0, len = ref.length; j < len; j++) { - item = ref[j]; - if (!(item.kind === 'file' && (file2 = item.getAsFile()))) { - continue; - } - score2 = 2 * (file2.size <= QR.max_size) + (file2.type === 'image/png'); - if (score2 > score) { - file = file2; - score = score2; - } - } - if (file) { - type = file.type; - blob = new Blob([file], { - type: type - }); - blob.name = Conf['pastedname'] + "." + ($.getOwn(QR.extensionFromType, type) || 'jpg'); - QR.open(); - QR.handleFiles([blob]); - $.addClass(QR.nodes.el, 'dump'); - } - }, - pasteFF: function() { - var arr, blob, bstr, i, images, img, j, k, len, m, pasteArea, ref, src; - pasteArea = QR.nodes.pasteArea; - if (!pasteArea.childNodes.length) { - return; - } - images = $$('img', pasteArea); - $.rmAll(pasteArea); - for (j = 0, len = images.length; j < len; j++) { - img = images[j]; - src = img.src; - if (m = src.match(/data:(image\/(\w+));base64,(.+)/)) { - bstr = atob(m[3]); - arr = new Uint8Array(bstr.length); - for (i = k = 0, ref = bstr.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) { - arr[i] = bstr.charCodeAt(i); - } - blob = new Blob([arr], { - type: m[1] - }); - blob.name = Conf['pastedname'] + "." + m[2]; - QR.handleFiles([blob]); - } else if (/^https?:\/\//.test(src)) { - QR.handleUrl(src); - } - } - }, - handleUrl: function(urlDefault) { - QR.open(); - QR.selected.preventAutoPost(); - return CrossOrigin.permission(function() { - var url; - url = prompt('Enter a URL:', urlDefault); - if (url === null) { - return; - } - QR.nodes.fileButton.focus(); - return CrossOrigin.file(url, function(blob) { - if (blob && !/^text\//.test(blob.type)) { - return QR.handleFiles([blob]); - } else { - return QR.error("Can't load file."); - } - }); - }); - }, - handleFiles: function(files) { - var file, j, len; - if (this !== QR) { - files = slice.call(this.files); - this.value = null; - } - if (!files.length) { - return; - } - QR.cleanNotifications(); - for (j = 0, len = files.length; j < len; j++) { - file = files[j]; - QR.handleFile(file, files.length); - } - if (files.length !== 1) { - $.addClass(QR.nodes.el, 'dump'); - } - if (d.activeElement === QR.nodes.fileButton && $.hasClass(QR.nodes.fileSubmit, 'has-file')) { - return QR.nodes.filename.focus(); - } - }, - handleFile: function(file, nfiles) { - var isText, post; - isText = /^text\//.test(file.type); - if (nfiles === 1) { - post = QR.selected; - } else { - post = QR.posts[QR.posts.length - 1]; - if ((isText ? post.com || post.pasting : post.file)) { - post = new QR.post(); - } - } - return post[isText ? 'pasteText' : 'setFile'](file); - }, - openFileInput: function() { - if (QR.nodes.fileButton.disabled) { - return; - } - QR.nodes.fileInput.click(); - return QR.nodes.fileButton.focus(); - }, - generatePostableThreadsList: function() { - var j, len, list, options, ref, thread, val; - if (!QR.nodes) { - return; - } - list = QR.nodes.thread; - options = [list.firstElementChild]; - ref = g.BOARD.threads.keys; - for (j = 0, len = ref.length; j < len; j++) { - thread = ref[j]; - options.push($.el('option', { - value: thread, - textContent: "Thread " + thread - })); - } - val = list.value; - $.rmAll(list); - $.add(list, options); - list.value = val; - if (list.value === val) { - return; - } - list.value = g.VIEW === 'thread' ? g.THREADID : 'new'; - return (g.VIEW === 'thread' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread'); - }, - dialog: function() { - var classList, config, dialog, event, i, items, name, node, nodes, save, setNode; - QR.nodes = nodes = { - el: dialog = UI.dialog('qr', {innerHTML: "
      ×
      No selected file
      "}) - }; - setNode = function(name, query) { - return nodes[name] = $(query, dialog); - }; - setNode('move', '.move'); - setNode('autohide', '#autohide'); - setNode('close', '.close'); - setNode('thread', 'select'); - setNode('form', 'form'); - setNode('sjisToggle', '#sjis-toggle'); - setNode('texButton', '#tex-preview-button'); - setNode('name', '[data-name=name]'); - setNode('email', '[data-name=email]'); - setNode('sub', '[data-name=sub]'); - setNode('com', '[data-name=com]'); - setNode('charCount', '#char-count'); - setNode('texPreview', '#tex-preview'); - setNode('dumpList', '#dump-list'); - setNode('addPost', '#add-post'); - setNode('oekaki', '.oekaki'); - setNode('drawButton', '#qr-draw-button'); - setNode('fileSubmit', '#file-n-submit'); - setNode('fileButton', '#qr-file-button'); - setNode('noFile', '#qr-no-file'); - setNode('filename', '#qr-filename'); - setNode('spoiler', '#qr-file-spoiler'); - setNode('oekakiButton', '#qr-oekaki-button'); - setNode('fileRM', '#qr-filerm'); - setNode('urlButton', '#url-button'); - setNode('pasteArea', '#paste-area'); - setNode('customCooldown', '#custom-cooldown-button'); - setNode('dumpButton', '#dump-button'); - setNode('status', '[type=submit]'); - setNode('flashTag', '[name=filetag]'); - setNode('fileInput', '[type=file]'); - config = g.BOARD.config; - classList = QR.nodes.el.classList; - classList.toggle('forced-anon', QR.forcedAnon); - classList.toggle('has-spoiler', QR.spoiler); - classList.toggle('has-sjis', !!config.sjis_tags); - classList.toggle('has-math', !!config.math_tags); - classList.toggle('sjis-preview', !!config.sjis_tags && Conf['sjisPreview']); - classList.toggle('show-new-thread-option', Conf['Show New Thread Option in Threads']); - if (parseInt(Conf['customCooldown'], 10) > 0) { - $.addClass(QR.nodes.fileSubmit, 'custom-cooldown'); - $.get('customCooldownEnabled', Conf['customCooldownEnabled'], function(arg) { - var customCooldownEnabled; - customCooldownEnabled = arg.customCooldownEnabled; - QR.setCustomCooldown(customCooldownEnabled); - return $.sync('customCooldownEnabled', QR.setCustomCooldown); - }); - } - QR.flagsInput(); - $.on(nodes.autohide, 'change', QR.toggleHide); - $.on(nodes.close, 'click', QR.close); - $.on(nodes.status, 'click', QR.submit); - $.on(nodes.form, 'submit', QR.submit); - $.on(nodes.sjisToggle, 'click', QR.toggleSJIS); - $.on(nodes.texButton, 'mousedown', QR.texPreviewShow); - $.on(nodes.texButton, 'mouseup', QR.texPreviewHide); - $.on(nodes.addPost, 'click', function() { - return new QR.post(true); - }); - $.on(nodes.drawButton, 'click', QR.oekaki.draw); - $.on(nodes.fileButton, 'click', QR.openFileInput); - $.on(nodes.noFile, 'click', QR.openFileInput); - $.on(nodes.filename, 'focus', function() { - return $.addClass(this.parentNode, 'focus'); - }); - $.on(nodes.filename, 'blur', function() { - return $.rmClass(this.parentNode, 'focus'); - }); - $.on(nodes.spoiler, 'change', function() { - return QR.selected.nodes.spoiler.click(); - }); - $.on(nodes.oekakiButton, 'click', QR.oekaki.button); - $.on(nodes.fileRM, 'click', function() { - return QR.selected.rmFile(); - }); - $.on(nodes.urlButton, 'click', function() { - return QR.handleUrl(''); - }); - $.on(nodes.customCooldown, 'click', QR.toggleCustomCooldown); - $.on(nodes.dumpButton, 'click', function() { - return nodes.el.classList.toggle('dump'); - }); - $.on(nodes.fileInput, 'change', QR.handleFiles); - window.addEventListener('focus', QR.focus, true); - window.addEventListener('blur', QR.focus, true); - $.on(d, 'click', QR.focus); - if ($.engine === 'gecko' && !window.DataTransferItemList) { - nodes.pasteArea.hidden = false; - } - new MutationObserver(QR.pasteFF).observe(nodes.pasteArea, { - childList: true - }); - items = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag']; - i = 0; - save = function() { - return QR.selected.save(this); - }; - while (name = items[i++]) { - if (!(node = nodes[name])) { - continue; - } - event = node.nodeName === 'SELECT' ? 'change' : 'input'; - $.on(nodes[name], event, save); - } - if ($.engine === 'gecko' && Conf['Remember QR Size']) { - $.get('QR Size', '', function(item) { - return nodes.com.style.cssText = item['QR Size']; - }); - $.on(nodes.com, 'mouseup', function(e) { - if (e.button !== 0) { - return; - } - return $.set('QR Size', this.style.cssText); - }); - } - QR.generatePostableThreadsList(); - QR.persona.load(); - new QR.post(true); - QR.status(); - QR.cooldown.setup(); - QR.captcha.init(); - $.add(d.body, dialog); - QR.captcha.setup(); - QR.oekaki.setup(); - return $.event('QRDialogCreation', null, dialog); - }, - flags: function() { - var addFlag, ref, select, textContent, value; - select = $.el('select', { - name: 'flag', - className: 'flagSelector' - }); - addFlag = function(value, textContent) { - return $.add(select, $.el('option', { - value: value, - textContent: textContent - })); - }; - addFlag('0', (g.BOARD.config.country_flags ? 'Geographic Location' : 'None')); - ref = g.BOARD.config.board_flags; - for (value in ref) { - textContent = ref[value]; - addFlag(value, textContent); - } - return select; - }, - flagsInput: function() { - var flag, nodes; - nodes = QR.nodes; - if (!nodes) { - return; - } - if (nodes.flag) { - $.rm(nodes.flag); - delete nodes.flag; - } - if (g.BOARD.config.board_flags) { - flag = QR.flags(); - flag.dataset.name = 'flag'; - flag.dataset["default"] = '0'; - nodes.flag = flag; - return $.add(nodes.form, flag); - } - }, - submit: function(e) { - var captcha, cb, err, filetag, force, formData, options, post, ref, thread, threadID; - if (e != null) { - e.preventDefault(); - } - force = e != null ? e.shiftKey : void 0; - if (QR.req) { - QR.abort(); - return; - } - $.forceSync('cooldowns'); - if (QR.cooldown.seconds) { - if (force) { - QR.cooldown.clear(); - } else { - QR.cooldown.auto = !QR.cooldown.auto; - QR.status(); - return; - } - } - post = QR.posts[0]; - delete post.quotedText; - post.forceSave(); - threadID = post.thread; - thread = g.BOARD.threads.get(threadID); - if (g.BOARD.ID === 'f' && threadID === 'new') { - filetag = QR.nodes.flashTag.value; - } - if (threadID === 'new') { - threadID = null; - if (!!g.BOARD.config.require_subject && !post.sub) { - err = 'New threads require a subject.'; - } else if (!(!!g.BOARD.config.text_only || post.file)) { - err = 'No file selected.'; - } - } else if (g.BOARD.threads.get(threadID).isClosed) { - err = 'You can\'t reply to this thread anymore.'; - } else if (!(post.com || post.file)) { - err = 'No comment or file.'; - } else if (post.file && thread.fileLimit) { - err = 'Max limit of image replies has been reached.'; - } - if (g.BOARD.ID === 'r9k' && !((ref = post.com) != null ? ref.match(/[a-z-]/i) : void 0)) { - err || (err = 'Original comment required.'); - } - if (QR.captcha.isEnabled && !(QR.captcha === Captcha.v2 && /\b_ct=/.test(d.cookie) && threadID) && !(err && !force)) { - captcha = QR.captcha.getOne(!!threadID); - if (QR.captcha === Captcha.v2) { - captcha || (captcha = Captcha.cache.request(!!threadID)); - } - if (!captcha) { - err = 'No valid captcha.'; - QR.captcha.setup(!QR.cooldown.auto || d.activeElement === QR.nodes.status); - } - } - QR.cleanNotifications(); - if (err && !force) { - QR.cooldown.auto = false; - QR.status(); - QR.error(err); - return; - } - QR.cooldown.auto = QR.posts.length > 1; - post.lock(); - formData = { - MAX_FILE_SIZE: QR.max_size, - mode: 'regist', - pwd: QR.persona.getPassword(), - resto: threadID, - name: !QR.forcedAnon ? post.name : void 0, - email: post.email, - sub: !(QR.forcedAnon || threadID) ? post.sub : void 0, - com: post.com, - upfile: post.file, - filetag: filetag, - spoiler: post.spoiler, - flag: post.flag - }; - options = { - responseType: 'document', - withCredentials: true, - onloadend: QR.response, - form: $.formData(formData) - }; - if (Conf['Show Upload Progress']) { - options.onprogress = function(e) { - var ref1; - if (this !== ((ref1 = QR.req) != null ? ref1.upload : void 0)) { - return; - } - if (e.loaded < e.total) { - QR.req.progress = (Math.round(e.loaded / e.total * 100)) + "%"; - } else { - QR.req.isUploadFinished = true; - QR.req.progress = '...'; - } - return QR.status(); - }; - } - cb = function(response) { - var key, val; - if (response != null) { - QR.currentCaptcha = response; - if (QR.captcha === Captcha.v2) { - if (response.challenge != null) { - options.form.append('recaptcha_challenge_field', response.challenge); - options.form.append('recaptcha_response_field', response.response); - } else { - options.form.append('g-recaptcha-response', response.response); - } - } else { - for (key in response) { - val = response[key]; - options.form.append(key, val); - } - } - } - QR.req = $.ajax("https://sys." + (location.hostname.split('.')[1]) + ".org/" + g.BOARD + "/post", options); - return QR.req.progress = '...'; - }; - if (typeof captcha === 'function') { - QR.req = { - progress: '...', - abort: function() { - if (QR.captcha === Captcha.v2) { - Captcha.cache.abort(); - } - return cb = null; - } - }; - captcha(function(response) { - if (QR.captcha === Captcha.v2 && Captcha.cache.haveCookie()) { - if (typeof cb === "function") { - cb(); - } - if (response) { - return Captcha.cache.save(response); - } - } else if (response) { - return typeof cb === "function" ? cb(response) : void 0; - } else { - delete QR.req; - post.unlock(); - QR.cooldown.auto = !!Captcha.cache.getCount(); - return QR.status(); - } - }); - } else { - cb(captcha); - } - return QR.status(); - }, - response: function() { - var URL, _, base, connErr, err, h1, isReply, j, lastPostToThread, len, m, mi, open, post, postID, postsCount, ref, ref1, ref2, ref3, seconds, threadID; - if (this !== QR.req) { - return; - } - delete QR.req; - post = QR.posts[0]; - post.unlock(); - if ((err = (ref = this.response) != null ? ref.getElementById('errmsg') : void 0)) { - if ((ref1 = $('a', err)) != null) { - ref1.target = '_blank'; - } - } else if ((connErr = !this.response || this.response.title !== 'Post successful!')) { - err = QR.connectionError(); - if (QR.captcha === Captcha.v2 && QR.currentCaptcha) { - Captcha.cache.save(QR.currentCaptcha); - } - } else if (this.status !== 200) { - err = "Error " + this.statusText + " (" + this.status + ")"; - } - if (!connErr) { - if (typeof (base = QR.captcha).setUsed === "function") { - base.setUsed(); - } - } - delete QR.currentCaptcha; - if (err) { - QR.errorCount = (QR.errorCount || 0) + 1; - if (/captcha|verification/i.test(err.textContent) || connErr) { - if (/mistyped/i.test(err.textContent)) { - err = 'You mistyped the CAPTCHA, or the CAPTCHA malfunctioned.'; - } else if (/expired/i.test(err.textContent)) { - err = 'This CAPTCHA is no longer valid because it has expired.'; - } - if (QR.errorCount >= 5) { - QR.cooldown.auto = false; - } else { - QR.cooldown.auto = QR.captcha.isEnabled || connErr; - QR.cooldown.addDelay(post, 2); - } - } else if (err.textContent && (m = err.textContent.match(/\d+\s+(?:minute|second)/gi)) && !/duplicate|hour/i.test(err.textContent)) { - QR.cooldown.auto = !/have\s+been\s+muted/i.test(err.textContent); - seconds = 0; - for (j = 0, len = m.length; j < len; j++) { - mi = m[j]; - seconds += (/minute/i.test(mi) ? 60 : 1) * (+mi.match(/\d+/)[0]); - } - if (/muted/i.test(err.textContent)) { - QR.cooldown.addMute(seconds); - } else { - QR.cooldown.addDelay(post, seconds); - } - } else { - QR.cooldown.auto = false; - } - QR.captcha.setup(QR.cooldown.auto && ((ref2 = d.activeElement) === QR.nodes.status || ref2 === d.body)); - QR.status(); - QR.error(err); - return; - } - delete QR.errorCount; - h1 = $('h1', this.response); - ref3 = h1.nextSibling.textContent.match(/thread:(\d+),no:(\d+)/), _ = ref3[0], threadID = ref3[1], postID = ref3[2]; - postID = +postID; - threadID = +threadID || postID; - isReply = threadID !== postID; - $.event('QRPostSuccessful', { - boardID: g.BOARD.ID, - threadID: threadID, - postID: postID - }); - $.event('QRPostSuccessful_', { - boardID: g.BOARD.ID, - threadID: threadID, - postID: postID - }); - postsCount = QR.posts.length - 1; - QR.cooldown.auto = postsCount && isReply; - lastPostToThread = !((function() { - var k, len1, p, ref4; - ref4 = QR.posts.slice(1); - for (k = 0, len1 = ref4.length; k < len1; k++) { - p = ref4[k]; - if (p.thread === post.thread) { - return true; - } - } - })()); - if (postsCount) { - post.rm(); - QR.captcha.setup(d.activeElement === QR.nodes.status); - } else if (Conf['Persistent QR']) { - post.rm(); - if (Conf['Auto Hide QR']) { - QR.hide(); - } else { - QR.blur(); - } - } else { - QR.close(); - } - QR.cleanNotifications(); - if (Conf['Posting Success Notifications']) { - QR.notifications.push(new Notice('success', h1.textContent, 5)); - } - QR.cooldown.add(threadID, postID); - URL = threadID === postID ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID : threadID !== g.THREADID && lastPostToThread && Conf['Open Post in New Tab'] ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID + "#p" + postID : void 0; - if (URL) { - open = Conf['Open Post in New Tab'] || postsCount ? function() { - return $.open(URL); - } : function() { - return location.href = URL; - }; - if (threadID === postID) { - QR.waitForThread(URL, open); - } else { - open(); - } - } - return QR.status(); - }, - waitForThread: function(url, cb) { - var attempts, check; - attempts = 0; - check = function() { - return $.ajax(url, { - onloadend: function() { - attempts++; - if (attempts >= 6 || this.status === 200) { - return cb(); - } else { - return setTimeout(check, attempts * $.SECOND); - } - }, - responseType: 'text', - type: 'HEAD' - }); - }; - return check(); - }, - abort: function() { - var oldReq; - if ((oldReq = QR.req) && !QR.req.isUploadFinished) { - delete QR.req; - oldReq.abort(); - if (QR.captcha === Captcha.v2 && QR.currentCaptcha) { - Captcha.cache.save(QR.currentCaptcha); - } - delete QR.currentCaptcha; - QR.posts[0].unlock(); - QR.cooldown.auto = false; - QR.notifications.push(new Notice('info', 'QR upload aborted.', 5)); - } - return QR.status(); - } - }; - - return QR; - -}).call(this); - -(function() { - QR.cooldown = { - seconds: 0, - delays: { - deletion: 60 - }, - init: function() { - if (!Conf['Quick Reply']) { - return; - } - this.data = Conf['cooldowns']; - this.changes = $.dict(); - return $.sync('cooldowns', this.sync); - }, - setup: function() { - var delay, ref, type; - $.extend(QR.cooldown.delays, g.BOARD.cooldowns()); - QR.cooldown.maxDelay = 0; - ref = QR.cooldown.delays; - for (type in ref) { - delay = ref[type]; - if (type !== 'thread' && type !== 'thread_global') { - QR.cooldown.maxDelay = Math.max(QR.cooldown.maxDelay, delay); - } - } - QR.cooldown.isSetup = true; - return QR.cooldown.start(); - }, - start: function() { - var data; - data = QR.cooldown.data; - if (!(Conf['Cooldown'] && QR.cooldown.isSetup && !QR.cooldown.isCounting && Object.keys(data[g.BOARD.ID] || {}).length + Object.keys(data.global || {}).length > 0)) { - return; - } - QR.cooldown.isCounting = true; - return QR.cooldown.count(); - }, - sync: function(data) { - QR.cooldown.data = data || $.dict(); - return QR.cooldown.start(); - }, - add: function(threadID, postID) { - var boardID, start; - if (!Conf['Cooldown']) { - return; - } - start = Date.now(); - boardID = g.BOARD.ID; - QR.cooldown.set(boardID, start, { - threadID: threadID, - postID: postID - }); - if (threadID === postID) { - QR.cooldown.set('global', start, { - boardID: boardID, - threadID: threadID, - postID: postID - }); - } - QR.cooldown.save(); - return QR.cooldown.start(); - }, - addDelay: function(post, delay) { - var cooldown; - if (!Conf['Cooldown']) { - return; - } - cooldown = QR.cooldown.categorize(post); - cooldown.delay = delay; - QR.cooldown.set(g.BOARD.ID, Date.now(), cooldown); - QR.cooldown.save(); - return QR.cooldown.start(); - }, - addMute: function(delay) { - if (!Conf['Cooldown']) { - return; - } - QR.cooldown.set(g.BOARD.ID, Date.now(), { - type: 'mute', - delay: delay - }); - QR.cooldown.save(); - return QR.cooldown.start(); - }, - "delete": function(post) { - var base, cooldown, cooldowns, id, name; - if (!QR.cooldown.data) { - return; - } - cooldowns = ((base = QR.cooldown.data)[name = post.board.ID] || (base[name] = $.dict())); - for (id in cooldowns) { - cooldown = cooldowns[id]; - if ((cooldown.delay == null) && cooldown.threadID === post.thread.ID && cooldown.postID === post.ID) { - QR.cooldown.set(post.board.ID, id, null); - } - } - return QR.cooldown.save(); - }, - secondsDeletion: function(post) { - var cooldown, cooldowns, seconds, start; - if (!(QR.cooldown.data && Conf['Cooldown'])) { - return 0; - } - cooldowns = QR.cooldown.data[post.board.ID] || $.dict(); - for (start in cooldowns) { - cooldown = cooldowns[start]; - if ((cooldown.delay == null) && cooldown.threadID === post.thread.ID && cooldown.postID === post.ID) { - seconds = QR.cooldown.delays.deletion - Math.floor((Date.now() - start) / $.SECOND); - return Math.max(seconds, 0); - } - } - return 0; - }, - categorize: function(post) { - if (post.thread === 'new') { - return { - type: 'thread' - }; - } else { - return { - type: !!post.file ? 'image' : 'reply', - threadID: +post.thread - }; - } - }, - mergeChange: function(data, scope, id, value) { - if (value) { - return (data[scope] || (data[scope] = $.dict()))[id] = value; - } else if (scope in data) { - delete data[scope][id]; - if (Object.keys(data[scope]).length === 0) { - return delete data[scope]; - } - } - }, - set: function(scope, id, value) { - var base; - QR.cooldown.mergeChange(QR.cooldown.data, scope, id, value); - return ((base = QR.cooldown.changes)[scope] || (base[scope] = $.dict()))[id] = value; - }, - save: function() { - var changes; - changes = QR.cooldown.changes; - if (!Object.keys(changes).length) { - return; - } - return $.get('cooldowns', $.dict(), function(arg) { - var cooldowns, id, ref, scope, value; - cooldowns = arg.cooldowns; - for (scope in QR.cooldown.changes) { - ref = QR.cooldown.changes[scope]; - for (id in ref) { - value = ref[id]; - QR.cooldown.mergeChange(cooldowns, scope, id, value); - } - QR.cooldown.data = cooldowns; - } - return $.set('cooldowns', cooldowns, function() { - return QR.cooldown.changes = $.dict(); - }); - }); - }, - clear: function() { - QR.cooldown.data = $.dict(); - QR.cooldown.changes = $.dict(); - QR.cooldown.auto = false; - QR.cooldown.update(); - return $.queueTask($["delete"], 'cooldowns'); - }, - update: function() { - var base, cooldown, cooldowns, elapsed, i, len, maxDelay, nCooldowns, now, ref, ref1, save, scope, seconds, start, suffix, threadID, type, update; - if (!QR.cooldown.isCounting) { - return; - } - save = false; - nCooldowns = 0; - now = Date.now(); - ref = QR.cooldown.categorize(QR.posts[0]), type = ref.type, threadID = ref.threadID; - seconds = 0; - if (Conf['Cooldown']) { - ref1 = [g.BOARD.ID, 'global']; - for (i = 0, len = ref1.length; i < len; i++) { - scope = ref1[i]; - cooldowns = ((base = QR.cooldown.data)[scope] || (base[scope] = $.dict())); - for (start in cooldowns) { - cooldown = cooldowns[start]; - start = +start; - elapsed = Math.floor((now - start) / $.SECOND); - if (elapsed < 0) { - QR.cooldown.set(scope, start, null); - save = true; - continue; - } - if (cooldown.delay != null) { - if (cooldown.delay <= elapsed) { - QR.cooldown.set(scope, start, null); - save = true; - } else if ((cooldown.type === type && cooldown.threadID === threadID) || cooldown.type === 'mute') { - seconds = Math.max(seconds, cooldown.delay - elapsed); - } - continue; - } - maxDelay = cooldown.threadID !== cooldown.postID ? QR.cooldown.maxDelay : QR.cooldown.delays[scope === 'global' ? 'thread_global' : 'thread']; - if (QR.cooldown.customCooldown) { - maxDelay = Math.max(maxDelay, parseInt(Conf['customCooldown'], 10)); - } - if (maxDelay <= elapsed) { - QR.cooldown.set(scope, start, null); - save = true; - continue; - } - if ((type === 'thread') === (cooldown.threadID === cooldown.postID) && cooldown.boardID !== g.BOARD.ID) { - suffix = scope === 'global' ? '_global' : ''; - seconds = Math.max(seconds, QR.cooldown.delays[type + suffix] - elapsed); - if (QR.cooldown.customCooldown) { - seconds = Math.max(seconds, parseInt(Conf['customCooldown'], 10) - elapsed); - } - } - } - nCooldowns += Object.keys(cooldowns).length; - } - } - if (save) { - QR.cooldown.save; - } - if (nCooldowns) { - clearTimeout(QR.cooldown.timeout); - QR.cooldown.timeout = setTimeout(QR.cooldown.count, $.SECOND); - } else { - delete QR.cooldown.isCounting; - } - update = seconds !== QR.cooldown.seconds; - QR.cooldown.seconds = seconds; - if (update) { - return QR.status(); - } - }, - count: function() { - QR.cooldown.update(); - if (QR.cooldown.seconds === 0 && QR.cooldown.auto && !QR.req) { - return QR.submit(); - } - } - }; - -}).call(this); - -(function() { - QR.oekaki = { - menu: { - init: function() { - var a, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Edit Link'] && Conf['Quick Reply'])) { - return; - } - a = $.el('a', { - className: 'edit-link', - href: 'javascript:;', - textContent: 'Edit image' - }); - $.on(a, 'click', this.editFile); - return Menu.menu.addEntry({ - el: a, - order: 90, - open: function(post) { - var file; - QR.oekaki.menu.post = post; - file = post.file; - return QR.postingIsEnabled && !!file && (file.isImage || file.isVideo); - } - }); - }, - editFile: function() { - var currentTime, isVideo, post, ref; - post = QR.oekaki.menu.post; - QR.quote.call(post.nodes.post); - isVideo = post.file.isVideo; - currentTime = ((ref = post.file.fullImage) != null ? ref.currentTime : void 0) || 0; - return CrossOrigin.file(post.file.url, function(blob) { - var video; - if (!blob) { - return QR.error("Can't load file."); - } else if (isVideo) { - video = $.el('video'); - $.on(video, 'loadedmetadata', function() { - $.on(video, 'seeked', function() { - var canvas; - canvas = $.el('canvas', { - width: video.videoWidth, - height: video.videoHeight - }); - canvas.getContext('2d').drawImage(video, 0, 0); - return canvas.toBlob(function(snapshot) { - snapshot.name = post.file.name.replace(/\.\w+$/, '') + '.png'; - QR.handleFiles([snapshot]); - return QR.oekaki.edit(); - }); - }); - return video.currentTime = currentTime; - }); - $.on(video, 'error', function() { - return QR.openError(); - }); - return video.src = URL.createObjectURL(blob); - } else { - blob.name = post.file.name; - QR.handleFiles([blob]); - return QR.oekaki.edit(); - } - }); - } - }, - setup: function() { - return $.global(function() { - var FCX; - FCX = window.FCX; - FCX.oekakiCB = function() { - return window.Tegaki.flatten().toBlob(function(file) { - var source; - source = "oekaki-" + (Date.now()); - FCX.oekakiLatest = source; - return document.dispatchEvent(new CustomEvent('QRSetFile', { - bubbles: true, - detail: { - file: file, - name: FCX.oekakiName, - source: source - } - })); - }); - }; - if (window.Tegaki) { - return document.querySelector('#qr .oekaki').hidden = false; - } - }); - }, - load: function(cb) { - var n, onload, script, style; - if ($('script[src^="//s.4cdn.org/js/tegaki"]', d.head)) { - return cb(); - } else { - style = $.el('link', { - rel: 'stylesheet', - href: "//s.4cdn.org/css/tegaki." + (Date.now()) + ".css" - }); - script = $.el('script', { - src: "//s.4cdn.org/js/tegaki.min." + (Date.now()) + ".js" - }); - n = 0; - onload = function() { - if (++n === 2) { - return cb(); - } - }; - $.on(style, 'load', onload); - $.on(script, 'load', onload); - return $.add(d.head, [style, script]); - } - }, - draw: function() { - return $.global(function() { - var FCX, Tegaki; - Tegaki = window.Tegaki, FCX = window.FCX; - if (Tegaki.bg) { - Tegaki.destroy(); - } - FCX.oekakiName = 'tegaki.png'; - return Tegaki.open({ - onDone: FCX.oekakiCB, - onCancel: function() { - return Tegaki.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: function() { - if (QR.selected.file) { - return QR.oekaki.edit(); - } else { - return QR.oekaki.toggle(); - } - }, - edit: function() { - return QR.oekaki.load(function() { - return $.global(function() { - var FCX, Tegaki, cb, error, name, source; - Tegaki = window.Tegaki, FCX = window.FCX; - name = document.getElementById('qr-filename').value.replace(/\.\w+$/, '') + '.png'; - source = document.getElementById('file-n-submit').dataset.source; - error = function(content) { - return document.dispatchEvent(new CustomEvent('CreateNotification', { - bubbles: true, - detail: { - type: 'warning', - content: content, - lifetime: 20 - } - })); - }; - cb = function(e) { - var canvas, selected; - if (e) { - this.removeEventListener('QRMetadata', cb, false); - } - selected = document.getElementById('selected'); - if (!(selected != null ? selected.dataset.type : void 0)) { - return error('No file to edit.'); - } - if (!/^(image|video)\//.test(selected.dataset.type)) { - return error('Not an image.'); - } - if (!selected.dataset.height) { - return error('Metadata not available.'); - } - if (selected.dataset.height === 'loading') { - selected.addEventListener('QRMetadata', cb, false); - return; - } - if (Tegaki.bg) { - Tegaki.destroy(); - } - FCX.oekakiName = name; - Tegaki.open({ - onDone: FCX.oekakiCB, - onCancel: function() { - return Tegaki.bgColor = '#ffffff'; - }, - width: +selected.dataset.width, - height: +selected.dataset.height, - bgColor: 'transparent' - }); - canvas = document.createElement('canvas'); - canvas.width = canvas.naturalWidth = +selected.dataset.width; - canvas.height = canvas.naturalHeight = +selected.dataset.height; - canvas.hidden = true; - document.body.appendChild(canvas); - canvas.addEventListener('QRImageDrawn', function() { - this.remove(); - return Tegaki.onOpenImageLoaded.call(this); - }, false); - return canvas.dispatchEvent(new CustomEvent('QRDrawFile', { - bubbles: true - })); - }; - if (Tegaki.bg && Tegaki.onDoneCb === FCX.oekakiCB && source === FCX.oekakiLatest) { - FCX.oekakiName = name; - return Tegaki.resume(); - } else { - return cb(); - } - }); - }); - }, - toggle: function() { - return QR.oekaki.load(function() { - return QR.nodes.oekaki.hidden = !QR.nodes.oekaki.hidden; - }); - } - }; - -}).call(this); - -(function() { - var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - QR.persona = { - always: {}, - types: { - name: [], - email: [], - sub: [] - }, - init: function() { - var i, item, len, ref; - if (!(Conf['Quick Reply'] || (Conf['Menu'] && Conf['Delete Link']))) { - return; - } - ref = Conf['QR.personas'].split('\n'); - for (i = 0, len = ref.length; i < len; i++) { - item = ref[i]; - QR.persona.parseItem(item.trim()); - } - }, - parseItem: function(item) { - var boards, match, ref, ref1, ref2, type, val; - if (item[0] === '#') { - return; - } - if (!(match = item.match(/(name|options|email|subject|password):"(.*)"/i))) { - return; - } - ref = match, match = ref[0], type = ref[1], val = ref[2]; - item = item.replace(match, ''); - boards = ((ref1 = item.match(/boards:([^;]+)/i)) != null ? ref1[1].toLowerCase() : void 0) || 'global'; - if (boards !== 'global' && (ref2 = g.BOARD.ID, indexOf.call(boards.split(','), ref2) < 0)) { - return; - } - if (type === 'password') { - QR.persona.pwd = val; - return; - } - if (type === 'options') { - type = 'email'; - } - if (type === 'subject') { - type = 'sub'; - } - if (/always/i.test(item)) { - QR.persona.always[type] = val; - } - if (indexOf.call(QR.persona.types[type], val) < 0) { - return QR.persona.types[type].push(val); - } - }, - load: function() { - var arr, i, len, list, ref, type, val; - ref = QR.persona.types; - for (type in ref) { - arr = ref[type]; - list = $("#list-" + type, QR.nodes.el); - for (i = 0, len = arr.length; i < len; i++) { - val = arr[i]; - if (val) { - $.add(list, $.el('option', { - textContent: val - })); - } - } - } - }, - getPassword: function() { - var m; - if (QR.persona.pwd != null) { - return QR.persona.pwd; - } else if ((m = d.cookie.match(/4chan_pass=([^;]+)/))) { - return decodeURIComponent(m[1]); - } else { - return ''; - } - }, - get: function(cb) { - return $.get('QR.persona', {}, function(arg) { - var persona; - persona = arg['QR.persona']; - return cb(persona); - }); - }, - set: function(post) { - return $.get('QR.persona', {}, function(arg) { - var persona; - persona = arg['QR.persona']; - persona = { - name: post.name, - flag: post.flag - }; - return $.set('QR.persona', persona); - }); - } - }; - -}).call(this); - -(function() { - var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - QR.post = (function() { - function _Class(select) { - this.select = bind(this.select, this); - var el, event, i, j, label, len, len1, prev, ref, ref1; - el = $.el('a', { - className: 'qr-preview', - draggable: true, - href: 'javascript:;' - }); - $.extend(el, {innerHTML: ""}); - this.nodes = { - el: el, - rm: el.firstChild, - spoiler: $('.qr-preview-spoiler input', el), - span: el.lastChild - }; - $.on(el, 'click', this.select); - $.on(this.nodes.rm, 'click', (function(_this) { - return function(e) { - e.stopPropagation(); - return _this.rm(); - }; - })(this)); - $.on(this.nodes.spoiler, 'change', (function(_this) { - return function(e) { - _this.spoiler = e.target.checked; - if (_this === QR.selected) { - QR.nodes.spoiler.checked = _this.spoiler; - } - return _this.preventAutoPost(); - }; - })(this)); - ref = $$('label', el); - for (i = 0, len = ref.length; i < len; i++) { - label = ref[i]; - $.on(label, 'click', function(e) { - return e.stopPropagation(); - }); - } - $.add(QR.nodes.dumpList, el); - ref1 = ['dragStart', 'dragEnter', 'dragLeave', 'dragOver', 'dragEnd', 'drop']; - for (j = 0, len1 = ref1.length; j < len1; j++) { - event = ref1[j]; - $.on(el, event.toLowerCase(), this[event]); - } - this.thread = g.VIEW === 'thread' ? g.THREADID : 'new'; - prev = QR.posts[QR.posts.length - 1]; - QR.posts.push(this); - this.nodes.spoiler.checked = this.spoiler = prev && Conf['Remember Spoiler'] ? prev.spoiler : false; - QR.persona.get((function(_this) { - return function(persona) { - _this.name = 'name' in QR.persona.always ? QR.persona.always.name : prev ? prev.name : persona.name; - _this.email = 'email' in QR.persona.always ? QR.persona.always.email : ''; - _this.sub = 'sub' in QR.persona.always ? QR.persona.always.sub : ''; - if (QR.nodes.flag) { - _this.flag = prev ? prev.flag : persona.flag && persona.flag in g.BOARD.config.board_flags ? persona.flag : void 0; - } - if (QR.selected === _this) { - return _this.load(); - } - }; - })(this)); - if (select) { - this.select(); - } - this.unlock(); - QR.captcha.moreNeeded(); - } - - _Class.prototype.rm = function() { - var base, index; - this["delete"](); - index = QR.posts.indexOf(this); - if (QR.posts.length === 1) { - new QR.post(true); - $.rmClass(QR.nodes.el, 'dump'); - } else if (this === QR.selected) { - (QR.posts[index - 1] || QR.posts[index + 1]).select(); - } - QR.posts.splice(index, 1); - QR.status(); - return typeof (base = QR.captcha).updateThread === "function" ? base.updateThread() : void 0; - }; - - _Class.prototype["delete"] = function() { - $.rm(this.nodes.el); - URL.revokeObjectURL(this.URL); - return this.dismissErrors(); - }; - - _Class.prototype.lock = function(lock) { - var i, len, name, node, ref; - if (lock == null) { - lock = true; - } - this.isLocked = lock; - if (this !== QR.selected) { - return; - } - ref = ['thread', 'name', 'email', 'sub', 'com', 'fileButton', 'filename', 'spoiler', 'flag']; - for (i = 0, len = ref.length; i < len; i++) { - name = ref[i]; - if (node = QR.nodes[name]) { - node.disabled = lock; - } - } - this.nodes.rm.style.visibility = lock ? 'hidden' : ''; - this.nodes.spoiler.disabled = lock; - return this.nodes.el.draggable = !lock; - }; - - _Class.prototype.unlock = function() { - return this.lock(false); - }; - - _Class.prototype.select = function() { - var rectEl, rectList; - if (QR.selected) { - QR.selected.nodes.el.removeAttribute('id'); - QR.selected.forceSave(); - } - QR.selected = this; - this.lock(this.isLocked); - this.nodes.el.id = 'selected'; - rectEl = this.nodes.el.getBoundingClientRect(); - rectList = this.nodes.el.parentNode.getBoundingClientRect(); - this.nodes.el.parentNode.scrollLeft += rectEl.left + rectEl.width / 2 - rectList.left - rectList.width / 2; - return this.load(); - }; - - _Class.prototype.load = function() { - var i, len, name, node, ref; - ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag']; - for (i = 0, len = ref.length; i < len; i++) { - name = ref[i]; - if (!(node = QR.nodes[name])) { - continue; - } - node.value = this[name] || node.dataset["default"] || ''; - } - (this.thread !== 'new' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread'); - this.showFileData(); - return QR.characterCount(); - }; - - _Class.prototype.save = function(input, forced) { - var base, name, prev; - if (input.type === 'checkbox') { - this.spoiler = input.checked; - return; - } - name = input.dataset.name; - if (name !== 'thread' && name !== 'name' && name !== 'email' && name !== 'sub' && name !== 'com' && name !== 'filename' && name !== 'flag') { - return; - } - prev = this[name] || input.dataset["default"] || null; - this[name] = input.value || input.dataset["default"] || null; - switch (name) { - case 'thread': - (this.thread !== 'new' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread'); - QR.status(); - if (typeof (base = QR.captcha).updateThread === "function") { - base.updateThread(); - } - break; - case 'com': - this.updateComment(); - break; - case 'filename': - if (!this.file) { - return; - } - this.saveFilename(); - this.updateFilename(); - break; - case 'name': - case 'flag': - if (this[name] !== prev) { - QR.persona.set(this); - } - } - if (!forced) { - return this.preventAutoPost(); - } - }; - - _Class.prototype.forceSave = function() { - var i, len, name, node, ref; - if (this !== QR.selected) { - return; - } - ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler', 'flag']; - for (i = 0, len = ref.length; i < len; i++) { - name = ref[i]; - if (!(node = QR.nodes[name])) { - continue; - } - this.save(node, true); - } - }; - - _Class.prototype.preventAutoPost = function() { - if (QR.cooldown.auto && this === QR.posts[0]) { - QR.cooldown.update(); - if (QR.cooldown.seconds <= 5) { - return QR.cooldown.auto = false; - } - } - }; - - _Class.prototype.setComment = function(com) { - this.com = com || null; - if (this === QR.selected) { - QR.nodes.com.value = this.com; - } - return this.updateComment(); - }; - - _Class.prototype.updateComment = function() { - if (this === QR.selected) { - QR.characterCount(); - } - this.nodes.span.textContent = this.com; - QR.captcha.moreNeeded(); - if (QR.captcha === Captcha.v2) { - return Captcha.cache.prerequest(); - } - }; - - _Class.prototype.isOnlyQuotes = function() { - return (this.com || '').trim() === (this.quotedText || '').trim(); - }; - - _Class.rmErrored = function(e) { - var error, errors, i, j, len, post, ref; - e.stopPropagation(); - ref = QR.posts; - for (i = ref.length - 1; i >= 0; i += -1) { - post = ref[i]; - if (errors = post.errors) { - for (j = 0, len = errors.length; j < len; j++) { - error = errors[j]; - if (!(doc.contains(error))) { - continue; - } - post.rm(); - break; - } - } - } - }; - - _Class.prototype.error = function(className, message, link) { - var div, ref, rm, rmAll; - div = $.el('div', { - className: className - }); - $.extend(div, {innerHTML: E(message) + ((link) ? " [More info]" : "") + "
      [delete post] [delete all]"}); - (this.errors || (this.errors = [])).push(div); - ref = $$('a', div), rm = ref[0], rmAll = ref[1]; - $.on(div, 'click', (function(_this) { - return function() { - if (indexOf.call(QR.posts, _this) >= 0) { - return _this.select(); - } - }; - })(this)); - $.on(rm, 'click', (function(_this) { - return function(e) { - e.stopPropagation(); - if (indexOf.call(QR.posts, _this) >= 0) { - return _this.rm(); - } - }; - })(this)); - $.on(rmAll, 'click', QR.post.rmErrored); - return QR.error(div, true); - }; - - _Class.prototype.fileError = function(message, link) { - return this.error('file-error', this.filename + ": " + message, link); - }; - - _Class.prototype.dismissErrors = function(test) { - var error, i, len, ref; - if (test == null) { - test = function() { - return true; - }; - } - if (this.errors) { - ref = this.errors; - for (i = 0, len = ref.length; i < len; i++) { - error = ref[i]; - if (doc.contains(error) && test(error)) { - error.parentNode.previousElementSibling.click(); - } - } - } - }; - - _Class.prototype.setFile = function(file1) { - var ext, ref; - this.file = file1; - if (Conf['Randomize Filename'] && g.BOARD.ID !== 'f') { - this.filename = "" + (Date.now() * 1000 - Math.floor(Math.random() * 365 * $.DAY * 1000)); - if (ext = this.file.name.match(QR.validExtension)) { - this.filename += ext[0]; - } - } else { - this.filename = this.file.name; - } - this.filesize = $.bytesToString(this.file.size); - this.checkSize(); - $.addClass(this.nodes.el, 'has-file'); - QR.captcha.moreNeeded(); - URL.revokeObjectURL(this.URL); - this.saveFilename(); - if (this === QR.selected) { - this.showFileData(); - } else { - this.updateFilename(); - } - this.rmMetadata(); - this.nodes.el.dataset.type = this.file.type; - this.nodes.el.style.backgroundImage = ''; - if (ref = this.file.type, indexOf.call(QR.mimeTypes, ref) < 0) { - this.fileError('Unsupported file type.'); - } else if (/^(image|video)\//.test(this.file.type)) { - this.readFile(); - } - return this.preventAutoPost(); - }; - - _Class.prototype.checkSize = function() { - var max; - max = QR.max_size; - if (/^video\//.test(this.file.type)) { - max = Math.min(max, QR.max_size_video); - } - if (this.file.size > max) { - return this.fileError("File too large (file: " + this.filesize + ", max: " + ($.bytesToString(max)) + ")."); - } - }; - - _Class.prototype.readFile = function() { - var el, event, isVideo, onerror, onload; - isVideo = /^video\//.test(this.file.type); - el = $.el(isVideo ? 'video' : 'img'); - if (isVideo && !el.canPlayType(this.file.type)) { - return; - } - event = isVideo ? 'loadeddata' : 'load'; - onload = (function(_this) { - return function() { - $.off(el, event, onload); - $.off(el, 'error', onerror); - _this.checkDimensions(el); - _this.setThumbnail(el); - return $.event('QRMetadata', null, _this.nodes.el); - }; - })(this); - onerror = (function(_this) { - return function() { - $.off(el, event, onload); - $.off(el, 'error', onerror); - _this.fileError("Corrupt " + (isVideo ? 'video' : 'image') + " or error reading metadata.", 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions#error-reading-metadata'); - URL.revokeObjectURL(el.src); - _this.nodes.el.removeAttribute('data-height'); - return $.event('QRMetadata', null, _this.nodes.el); - }; - })(this); - this.nodes.el.dataset.height = 'loading'; - $.on(el, event, onload); - $.on(el, 'error', onerror); - return el.src = URL.createObjectURL(this.file); - }; - - _Class.prototype.checkDimensions = function(el) { - var duration, height, max_height, max_width, videoHeight, videoWidth, width; - if (el.tagName === 'IMG') { - height = el.height, width = el.width; - this.nodes.el.dataset.height = height; - this.nodes.el.dataset.width = width; - if (height > QR.max_height || width > QR.max_width) { - this.fileError("Image too large (image: " + height + "x" + width + "px, max: " + QR.max_height + "x" + QR.max_width + "px)"); - } - if (height < QR.min_height || width < QR.min_width) { - return this.fileError("Image too small (image: " + height + "x" + width + "px, min: " + QR.min_height + "x" + QR.min_width + "px)"); - } - } else { - videoHeight = el.videoHeight, videoWidth = el.videoWidth, duration = el.duration; - this.nodes.el.dataset.height = videoHeight; - this.nodes.el.dataset.width = videoWidth; - this.nodes.el.dataset.duration = duration; - max_height = Math.min(QR.max_height, QR.max_height_video); - max_width = Math.min(QR.max_width, QR.max_width_video); - if (videoHeight > max_height || videoWidth > max_width) { - this.fileError("Video too large (video: " + videoHeight + "x" + videoWidth + "px, max: " + max_height + "x" + max_width + "px)"); - } - if (videoHeight < QR.min_height || videoWidth < QR.min_width) { - this.fileError("Video too small (video: " + videoHeight + "x" + videoWidth + "px, min: " + QR.min_height + "x" + QR.min_width + "px)"); - } - if (!isFinite(duration)) { - this.fileError('Video lacks duration metadata (try remuxing)'); - } else if (duration > QR.max_duration_video) { - this.fileError("Video too long (video: " + duration + "s, max: " + QR.max_duration_video + "s)"); - } - if (BoardConfig.noAudio(g.BOARD.ID) && $.hasAudio(el)) { - return this.fileError('Audio not allowed'); - } - } - }; - - _Class.prototype.setThumbnail = function(el) { - var cv, height, isVideo, s, width; - isVideo = el.tagName === 'VIDEO'; - s = 90 * 2 * window.devicePixelRatio; - if (this.file.type === 'image/gif') { - s *= 3; - } - if (isVideo) { - height = el.videoHeight; - width = el.videoWidth; - } else { - height = el.height, width = el.width; - if (height < s || width < s) { - this.URL = el.src; - this.nodes.el.style.backgroundImage = "url(" + this.URL + ")"; - return; - } - } - if (height <= width) { - width = s / height * width; - height = s; - } else { - height = s / width * height; - width = s; - } - cv = $.el('canvas'); - cv.height = height; - cv.width = width; - cv.getContext('2d').drawImage(el, 0, 0, width, height); - URL.revokeObjectURL(el.src); - return cv.toBlob((function(_this) { - return function(blob) { - _this.URL = URL.createObjectURL(blob); - return _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")"; - }; - })(this)); - }; - - _Class.prototype.rmFile = function() { - if (this.isLocked) { - return; - } - delete this.file; - delete this.filename; - delete this.filesize; - this.nodes.el.removeAttribute('title'); - QR.nodes.filename.removeAttribute('title'); - this.rmMetadata(); - this.nodes.el.style.backgroundImage = ''; - $.rmClass(this.nodes.el, 'has-file'); - this.showFileData(); - URL.revokeObjectURL(this.URL); - this.dismissErrors(function(error) { - return $.hasClass(error, 'file-error'); - }); - return this.preventAutoPost(); - }; - - _Class.prototype.rmMetadata = function() { - var attr, i, len, ref; - ref = ['type', 'height', 'width', 'duration']; - for (i = 0, len = ref.length; i < len; i++) { - attr = ref[i]; - this.nodes.el.removeAttribute("data-" + attr); - } - }; - - _Class.prototype.saveFilename = function() { - this.file.newName = (this.filename || '').replace(/[\/\\]/g, '-'); - if (!QR.validExtension.test(this.filename)) { - return this.file.newName += "." + ($.getOwn(QR.extensionFromType, this.file.type) || 'jpg'); - } - }; - - _Class.prototype.updateFilename = function() { - var long; - long = this.filename + " (" + this.filesize + ")"; - this.nodes.el.title = long; - if (this !== QR.selected) { - return; - } - return QR.nodes.filename.title = long; - }; - - _Class.prototype.showFileData = function() { - var ref; - if (this.file) { - this.updateFilename(); - QR.nodes.filename.value = this.filename; - $.addClass(QR.nodes.oekaki, 'has-file'); - $.addClass(QR.nodes.fileSubmit, 'has-file'); - } else { - $.rmClass(QR.nodes.oekaki, 'has-file'); - $.rmClass(QR.nodes.fileSubmit, 'has-file'); - } - if (((ref = this.file) != null ? ref.source : void 0) != null) { - QR.nodes.fileSubmit.dataset.source = this.file.source; - } else { - QR.nodes.fileSubmit.removeAttribute('data-source'); - } - return QR.nodes.spoiler.checked = this.spoiler; - }; - - _Class.prototype.pasteText = function(file) { - var reader; - this.pasting = true; - this.preventAutoPost(); - reader = new FileReader(); - reader.onload = (function(_this) { - return function(e) { - var result; - result = e.target.result; - _this.setComment((_this.com ? _this.com + "\n" + result : result)); - return delete _this.pasting; - }; - })(this); - return reader.readAsText(file); - }; - - _Class.prototype.dragStart = function(e) { - var left, ref, top; - ref = this.getBoundingClientRect(), left = ref.left, top = ref.top; - e.dataTransfer.setDragImage(this, e.clientX - left, e.clientY - top); - return $.addClass(this, 'drag'); - }; - - _Class.prototype.dragEnd = function() { - return $.rmClass(this, 'drag'); - }; - - _Class.prototype.dragEnter = function() { - return $.addClass(this, 'over'); - }; - - _Class.prototype.dragLeave = function() { - return $.rmClass(this, 'over'); - }; - - _Class.prototype.dragOver = function(e) { - e.preventDefault(); - return e.dataTransfer.dropEffect = 'move'; - }; - - _Class.prototype.drop = function() { - var base, el, index, newIndex, oldIndex, post; - $.rmClass(this, 'over'); - if (!this.draggable) { - return; - } - el = $('.drag', this.parentNode); - index = function(el) { - return slice.call(el.parentNode.children).indexOf(el); - }; - oldIndex = index(el); - newIndex = index(this); - if (QR.posts[oldIndex].isLocked || QR.posts[newIndex].isLocked) { - return; - } - (oldIndex < newIndex ? $.after : $.before)(this, el); - post = QR.posts.splice(oldIndex, 1)[0]; - QR.posts.splice(newIndex, 0, post); - QR.status(); - return typeof (base = QR.captcha).updateThread === "function" ? base.updateThread() : void 0; - }; - - return _Class; - - })(); - -}).call(this); - -QuoteBacklink = (function() { - var QuoteBacklink; - - QuoteBacklink = { - containers: $.dict(), - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Quote Backlinks']) { - return; - } - if ((this.bottomBacklinks = Conf['Bottom Backlinks'])) { - $.addClass(doc, 'bottom-backlinks'); - } - Callbacks.Post.push({ - name: 'Quote Backlinking Part 1', - cb: this.firstNode - }); - return Callbacks.Post.push({ - name: 'Quote Backlinking Part 2', - cb: this.secondNode - }); - }, - firstNode: function() { - var a, clone, container, containers, hash, i, j, k, len, len1, len2, link, markYours, nodes, post, quote, ref, ref1; - if (this.isClone || !this.quotes.length || this.isRebuilt) { - return; - } - markYours = Conf['Mark Quotes of You'] && QuoteYou.isYou(this); - a = $.el('a', { - href: g.SITE.Build.postURL(this.board.ID, this.thread.ID, this.ID), - className: this.isHidden ? 'filtered backlink' : 'backlink', - textContent: Conf['backlink'].replace(/%(?:id|%)/g, (function(_this) { - return function(x) { - return { - '%id': _this.ID, - '%%': '%' - }[x]; - }; - })(this)) - }); - if (markYours) { - $.add(a, QuoteYou.mark.cloneNode(true)); - } - ref = this.quotes; - for (i = 0, len = ref.length; i < len; i++) { - quote = ref[i]; - containers = [QuoteBacklink.getContainer(quote)]; - if ((post = g.posts.get(quote)) && post.nodes.backlinkContainer) { - ref1 = post.clones; - for (j = 0, len1 = ref1.length; j < len1; j++) { - clone = ref1[j]; - containers.push(clone.nodes.backlinkContainer); - } - } - for (k = 0, len2 = containers.length; k < len2; k++) { - container = containers[k]; - link = a.cloneNode(true); - nodes = container.firstChild ? [$.tn(' '), link] : [link]; - if (Conf['Quote Previewing']) { - $.on(link, 'mouseover', QuotePreview.mouseover); - } - if (Conf['Quote Inlining']) { - $.on(link, 'click', QuoteInline.toggle); - if (Conf['Quote Hash Navigation']) { - hash = QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')); - nodes.push(hash); - } - } - $.add(container, nodes); - } - } - }, - secondNode: function() { - var container; - if (this.isClone && (this.origin.isReply || Conf['OP Backlinks'])) { - this.nodes.backlinkContainer = $('.container', this.nodes.post); - return; - } - if (!(this.isReply || Conf['OP Backlinks'])) { - return; - } - container = QuoteBacklink.getContainer(this.fullID); - this.nodes.backlinkContainer = container; - if (QuoteBacklink.bottomBacklinks) { - return $.add(this.nodes.post, container); - } else { - return $.add(this.nodes.info, container); - } - }, - getContainer: function(id) { - var base; - return (base = this.containers)[id] || (base[id] = $.el('span', { - className: 'container' - })); - } - }; - - return QuoteBacklink; - -}).call(this); - -QuoteCT = (function() { - var QuoteCT; - - QuoteCT = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Mark Cross-thread Quotes']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - this.mark = $.el('span', { - textContent: '\u00A0(Cross-thread)', - className: 'qmark-ct' - }); - return Callbacks.Post.push({ - name: 'Mark Cross-thread Quotes', - cb: this.node - }); - }, - node: function() { - var board, boardID, i, len, quotelink, ref, ref1, ref2, thread, threadID; - if (this.isClone && this.thread === this.context.thread) { - return; - } - ref = this.context, board = ref.board, thread = ref.thread; - ref1 = this.nodes.quotelinks; - for (i = 0, len = ref1.length; i < len; i++) { - quotelink = ref1[i]; - ref2 = Get.postDataFromLink(quotelink), boardID = ref2.boardID, threadID = ref2.threadID; - if (!threadID) { - continue; - } - if (this.isClone) { - $.rm($('.qmark-ct', quotelink)); - } - if (boardID === board.ID && threadID !== thread.ID) { - $.add(quotelink, QuoteCT.mark.cloneNode(true)); - } - } - } - }; - - return QuoteCT; - -}).call(this); - -QuoteInline = (function() { - var QuoteInline, - slice = [].slice; - - QuoteInline = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Quote Inlining']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Callbacks.Post.push({ - name: 'Quote Inlining', - cb: this.node - }); - }, - node: function() { - var i, isClone, len, link, process, ref; - process = QuoteInline.process; - isClone = this.isClone; - ref = this.nodes.quotelinks.concat(slice.call(this.nodes.backlinks), this.nodes.archivelinks); - for (i = 0, len = ref.length; i < len; i++) { - link = ref[i]; - process(link, isClone); - } - }, - process: function(link, clone) { - if (Conf['Quote Hash Navigation']) { - if (!clone) { - $.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'))); - } - } - return $.on(link, 'click', QuoteInline.toggle); - }, - qiQuote: function(link, hidden) { - var name; - name = "hashlink"; - if (hidden) { - name += " filtered"; - } - return $.el('a', { - className: name, - textContent: '#', - href: link.href - }); - }, - toggle: function(e) { - var boardID, context, postID, quoter, ref, ref1, threadID; - if ($.modifiedClick(e)) { - return; - } - ref = Get.postDataFromLink(this), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - if (Conf['Inline Cross-thread Quotes Only'] && g.VIEW === 'thread' && ((ref1 = g.posts.get(boardID + "." + postID)) != null ? ref1.nodes.root.offsetParent : void 0)) { - return; - } - if ($.hasClass(doc, 'catalog-mode')) { - return; - } - e.preventDefault(); - quoter = Get.postFromNode(this); - context = quoter.context; - if ($.hasClass(this, 'inlined')) { - QuoteInline.rm(this, boardID, threadID, postID, context); - } else { - if ($.x("ancestor::div[@data-full-i-d='" + boardID + "." + postID + "']", this)) { - return; - } - QuoteInline.add(this, boardID, threadID, postID, context, quoter); - } - return this.classList.toggle('inlined'); - }, - findRoot: function(quotelink, isBacklink) { - if (isBacklink) { - return $.x('ancestor::*[parent::*[contains(@class,"post")]][1]', quotelink); - } else { - return $.x('ancestor-or-self::*[parent::blockquote][1]', quotelink); - } - }, - add: function(quotelink, boardID, threadID, postID, context, quoter) { - var inline, isBacklink, post, qroot, root; - isBacklink = $.hasClass(quotelink, 'backlink'); - inline = $.el('div', { - className: 'inline' - }); - inline.dataset.fullID = boardID + "." + postID; - root = QuoteInline.findRoot(quotelink, isBacklink); - $.after(root, inline); - qroot = $.x('ancestor::*[contains(@class,"postContainer")][1]', root); - $.addClass(qroot, 'hasInline'); - new Fetcher(boardID, threadID, postID, inline, quoter); - if (!((post = g.posts.get(boardID + "." + postID)) && context.thread === post.thread)) { - return; - } - if (isBacklink && Conf['Forward Hiding']) { - $.addClass(post.nodes.root, 'forwarded'); - post.forwarded++ || (post.forwarded = 1); - } - if (!Unread.posts) { - return; - } - return Unread.readSinglePost(post); - }, - rm: function(quotelink, boardID, threadID, postID, context) { - var el, inlined, isBacklink, parentNode, post, qroot, ref, root; - isBacklink = $.hasClass(quotelink, 'backlink'); - root = QuoteInline.findRoot(quotelink, isBacklink); - root = $.x("following-sibling::div[@data-full-i-d='" + boardID + "." + postID + "'][1]", root); - qroot = $.x('ancestor::*[contains(@class,"postContainer")][1]', root); - parentNode = root.parentNode; - $.rm(root); - $.event('PostsRemoved', null, parentNode); - if (!$('.inline', qroot)) { - $.rmClass(qroot, 'hasInline'); - } - if (!(el = root.firstElementChild)) { - return; - } - post = g.posts.get(boardID + "." + postID); - post.rmClone(el.dataset.clone); - if (Conf['Forward Hiding'] && isBacklink && context.thread === g.threads.get(boardID + "." + threadID) && !--post.forwarded) { - delete post.forwarded; - $.rmClass(post.nodes.root, 'forwarded'); - } - while (inlined = $('.inlined', el)) { - ref = Get.postDataFromLink(inlined), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - QuoteInline.rm(inlined, boardID, threadID, postID, context); - $.rmClass(inlined, 'inlined'); - } - } - }; - - return QuoteInline; - -}).call(this); - -QuoteOP = (function() { - var QuoteOP, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - QuoteOP = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Mark OP Quotes']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - this.mark = $.el('span', { - textContent: '\u00A0(OP)', - className: 'qmark-op' - }); - return Callbacks.Post.push({ - name: 'Mark OP Quotes', - cb: this.node - }); - }, - node: function() { - var boardID, fullID, i, postID, quotelink, quotelinks, quotes, ref, ref1; - if (this.isClone && this.thread === this.context.thread) { - return; - } - if (!(quotes = this.quotes).length) { - return; - } - quotelinks = this.nodes.quotelinks; - if (this.isClone && (ref = this.thread.fullID, indexOf.call(quotes, ref) >= 0)) { - i = 0; - while (quotelink = quotelinks[i++]) { - $.rm($('.qmark-op', quotelink)); - } - } - fullID = this.context.thread.fullID; - if (indexOf.call(quotes, fullID) < 0) { - return; - } - i = 0; - while (quotelink = quotelinks[i++]) { - ref1 = Get.postDataFromLink(quotelink), boardID = ref1.boardID, postID = ref1.postID; - if ((boardID + "." + postID) === fullID) { - $.add(quotelink, QuoteOP.mark.cloneNode(true)); - } - } - } - }; - - return QuoteOP; - -}).call(this); - -QuotePreview = (function() { - var QuotePreview, - slice = [].slice; - - QuotePreview = { - init: function() { - var ref; - if (!Conf['Quote Previewing']) { - return; - } - if (g.VIEW === 'archive') { - $.on(d, 'mouseover', function(e) { - if (e.target.nodeName === 'A' && $.hasClass(e.target, 'quotelink')) { - return QuotePreview.mouseover.call(e.target, e); - } - }); - } - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Callbacks.Post.push({ - name: 'Quote Previewing', - cb: this.node - }); - }, - node: function() { - var i, len, link, ref; - ref = this.nodes.quotelinks.concat(slice.call(this.nodes.backlinks), this.nodes.archivelinks); - for (i = 0, len = ref.length; i < len; i++) { - link = ref[i]; - $.on(link, 'mouseover', QuotePreview.mouseover); - } - }, - mouseover: function(e) { - var boardID, i, len, origin, post, postID, posts, qp, ref, threadID; - if (($.hasClass(this, 'inlined') && !$.hasClass(doc, 'catalog-mode')) || !d.contains(this)) { - return; - } - ref = Get.postDataFromLink(this), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - qp = $.el('div', { - id: 'qp', - className: 'dialog' - }); - $.add(Header.hover, qp); - new Fetcher(boardID, threadID, postID, qp, Get.postFromNode(this)); - UI.hover({ - root: this, - el: qp, - latestEvent: e, - endEvents: 'mouseout click', - cb: QuotePreview.mouseout - }); - if (Conf['Quote Highlighting'] && (origin = g.posts.get(boardID + "." + postID))) { - posts = [origin].concat(origin.clones); - posts.pop(); - for (i = 0, len = posts.length; i < len; i++) { - post = posts[i]; - $.addClass(post.nodes.post, 'qphl'); - } - } - }, - mouseout: function() { - var clone, i, len, post, ref, root; - if (!(root = this.el.firstElementChild)) { - return; - } - $.event('PostsRemoved', null, Header.hover); - clone = Get.postFromRoot(root); - post = clone.origin; - post.rmClone(root.dataset.clone); - if (!Conf['Quote Highlighting']) { - return; - } - ref = [post].concat(post.clones); - for (i = 0, len = ref.length; i < len; i++) { - post = ref[i]; - $.rmClass(post.nodes.post, 'qphl'); - } - } - }; - - return QuotePreview; - -}).call(this); - -QuoteStrikeThrough = (function() { - var QuoteStrikeThrough; - - QuoteStrikeThrough = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && (Conf['Reply Hiding Buttons'] || (Conf['Menu'] && Conf['Reply Hiding Link']) || Conf['Filter']))) { - return; - } - return Callbacks.Post.push({ - name: 'Strike-through Quotes', - cb: this.node - }); - }, - node: function() { - var boardID, i, len, postID, quotelink, ref, ref1, ref2; - if (this.isClone) { - return; - } - ref = this.nodes.quotelinks; - for (i = 0, len = ref.length; i < len; i++) { - quotelink = ref[i]; - ref1 = Get.postDataFromLink(quotelink), boardID = ref1.boardID, postID = ref1.postID; - if ((ref2 = g.posts.get(boardID + "." + postID)) != null ? ref2.isHidden : void 0) { - $.addClass(quotelink, 'filtered'); - } - } - } - }; - - return QuoteStrikeThrough; - -}).call(this); - -QuoteThreading = -/* - <3 aeosynth - */ - -(function() { - var QuoteThreading; - - QuoteThreading = { - init: function() { - if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) { - return; - } - this.controls = $.el('label', {innerHTML: " Threading"}); - this.threadNewLink = $.el('span', { - className: 'brackets-wrap threadnewlink', - hidden: true - }); - $.extend(this.threadNewLink, {innerHTML: "Thread New Posts"}); - this.input = $('input', this.controls); - this.input.checked = Conf['Thread Quotes']; - $.on(this.input, 'change', this.setEnabled); - $.on(this.input, 'change', this.rethread); - $.on(this.threadNewLink.firstElementChild, 'click', this.rethread); - $.on(d, '4chanXInitFinished', (function(_this) { - return function() { - return _this.ready = true; - }; - })(this)); - Header.menu.addEntry(this.entry = { - el: this.controls, - order: 99 - }); - Callbacks.Thread.push({ - name: 'Quote Threading', - cb: this.setThread - }); - return Callbacks.Post.push({ - name: 'Quote Threading', - cb: this.node - }); - }, - parent: $.dict(), - children: $.dict(), - inserted: $.dict(), - toggleThreading: function() { - return this.setThreadingState(!Conf['Thread Quotes']); - }, - setThreadingState: function(enabled) { - this.input.checked = enabled; - this.setEnabled.call(this.input); - return this.rethread.call(this.input); - }, - setEnabled: function() { - var other, ref; - if (this.checked) { - $.set('Prune All Threads', false); - other = (ref = ReplyPruning.inputs) != null ? ref.enabled : void 0; - if (other != null ? other.checked : void 0) { - other.checked = false; - $.event('change', null, other); - } - } - return $.cb.checked.call(this); - }, - setThread: function() { - QuoteThreading.thread = this; - return $.asap((function() { - return !Conf['Thread Updater'] || $('.navLinksBot > .updatelink'); - }), function() { - var navLinksBot; - if ((navLinksBot = $('.navLinksBot'))) { - return $.add(navLinksBot, [$.tn(' '), QuoteThreading.threadNewLink]); - } - }); - }, - node: function() { - var ancestor, j, lastParent, len, parent, parents, quote, ref; - if (this.isFetchedQuote || this.isClone || !this.isReply) { - return; - } - parents = new Set(); - lastParent = null; - ref = this.quotes; - for (j = 0, len = ref.length; j < len; j++) { - quote = ref[j]; - if (parent = g.posts.get(quote)) { - if (!parent.isFetchedQuote && parent.isReply && parent.ID < this.ID) { - parents.add(parent.ID); - if (!lastParent || parent.ID > lastParent.ID) { - lastParent = parent; - } - } - } - } - if (!lastParent) { - return; - } - ancestor = lastParent; - while (ancestor = QuoteThreading.parent[ancestor.fullID]) { - parents["delete"](ancestor.ID); - } - if (parents.size === 1) { - return QuoteThreading.parent[this.fullID] = lastParent; - } - }, - descendants: function(post) { - var child, children, j, len, posts; - posts = [post]; - if (children = QuoteThreading.children[post.fullID]) { - for (j = 0, len = children.length; j < len; j++) { - child = children[j]; - posts = posts.concat(QuoteThreading.descendants(child)); - } - } - return posts; - }, - insert: function(post) { - var base, child, children, descendants, i, j, k, l, len, name, next, nodes, order, parent, prev, prev2, threadContainer, x; - if (!(Conf['Thread Quotes'] && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) { - return false; - } - descendants = QuoteThreading.descendants(post); - if (!Unread.posts.has(parent.ID)) { - if ((function() { - var j, len, x; - for (j = 0, len = descendants.length; j < len; j++) { - x = descendants[j]; - if (Unread.posts.has(x.ID)) { - return true; - } - } - })()) { - QuoteThreading.threadNewLink.hidden = false; - return false; - } - } - order = Unread.order; - children = ((base = QuoteThreading.children)[name = parent.fullID] || (base[name] = [])); - threadContainer = parent.nodes.threadContainer || $.el('div', { - className: 'threadContainer' - }); - nodes = [post.nodes.root]; - if (post.nodes.threadContainer) { - nodes.push(post.nodes.threadContainer); - } - i = children.length; - for (j = children.length - 1; j >= 0; j += -1) { - child = children[j]; - if (child.ID >= post.ID) { - i--; - } - } - if (i !== children.length) { - next = children[i]; - for (k = 0, len = descendants.length; k < len; k++) { - x = descendants[k]; - order.before(order[next.ID], order[x.ID]); - } - children.splice(i, 0, post); - $.before(next.nodes.root, nodes); - } else { - prev = parent; - while ((prev2 = QuoteThreading.children[prev.fullID]) && prev2.length) { - prev = prev2[prev2.length - 1]; - } - for (l = descendants.length - 1; l >= 0; l += -1) { - x = descendants[l]; - order.after(order[prev.ID], order[x.ID]); - } - children.push(post); - $.add(threadContainer, nodes); - } - QuoteThreading.inserted[post.fullID] = true; - if (!parent.nodes.threadContainer) { - parent.nodes.threadContainer = threadContainer; - $.addClass(parent.nodes.root, 'threadOP'); - $.after(parent.nodes.root, threadContainer); - } - return true; - }, - rethread: function() { - var nodes, posts, thread; - if (!QuoteThreading.ready) { - return; - } - thread = QuoteThreading.thread; - posts = thread.posts; - QuoteThreading.threadNewLink.hidden = true; - if (Conf['Thread Quotes']) { - posts.forEach(QuoteThreading.insert); - } else { - nodes = []; - Unread.order = new RandomAccessList(); - QuoteThreading.inserted = $.dict(); - posts.forEach(function(post) { - if (post.isFetchedQuote) { - return; - } - Unread.order.push(post); - if (post.isReply) { - nodes.push(post.nodes.root); - } - if (QuoteThreading.children[post.fullID]) { - delete QuoteThreading.children[post.fullID]; - $.rmClass(post.nodes.root, 'threadOP'); - $.rm(post.nodes.threadContainer); - return delete post.nodes.threadContainer; - } - }); - $.add(thread.nodes.root, nodes); - } - Unread.position = Unread.order.first; - Unread.updatePosition(); - Unread.setLine(true); - Unread.read(); - return Unread.update(); - } - }; - - return QuoteThreading; - -}).call(this); - -QuoteYou = (function() { - var QuoteYou; - - QuoteYou = { - init: function() { - var ref; - if (!Conf['Remember Your Posts']) { - return; - } - this.db = new DataBoard('yourPosts'); - $.sync('Remember Your Posts', function(enabled) { - return Conf['Remember Your Posts'] = enabled; - }); - $.on(d, 'QRPostSuccessful', function(e) { - var cb; - cb = PostRedirect.delay(); - return $.get('Remember Your Posts', Conf['Remember Your Posts'], function(items) { - var boardID, postID, ref, threadID; - if (!items['Remember Your Posts']) { - return; - } - ref = e.detail, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - return QuoteYou.db.set({ - boardID: boardID, - threadID: threadID, - postID: postID, - val: true - }, cb); - }); - }); - if ((ref = g.VIEW) !== 'index' && ref !== 'thread' && ref !== 'archive') { - return; - } - if (Conf['Highlight Own Posts']) { - $.addClass(doc, 'highlight-own'); - } - if (Conf['Highlight Posts Quoting You']) { - $.addClass(doc, 'highlight-you'); - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - this.mark = $.el('span', { - textContent: '\u00A0(You)', - className: 'qmark-you' - }); - Callbacks.Post.push({ - name: 'Mark Quotes of You', - cb: this.node - }); - return QuoteYou.menu.init(); - }, - isYou: function(post) { - var ref; - return !!((ref = QuoteYou.db) != null ? ref.get({ - boardID: post.boardID, - threadID: post.threadID, - postID: post.ID - }) : void 0); - }, - node: function() { - var i, len, quotelink, ref; - if (this.isClone) { - return; - } - if (QuoteYou.isYou(this)) { - $.addClass(this.nodes.root, 'yourPost'); - } - if (!this.quotes.length) { - return; - } - ref = this.nodes.quotelinks; - for (i = 0, len = ref.length; i < len; i++) { - quotelink = ref[i]; - if (!(QuoteYou.db.get(Get.postDataFromLink(quotelink)))) { - continue; - } - if (Conf['Mark Quotes of You']) { - $.add(quotelink, QuoteYou.mark.cloneNode(true)); - } - $.addClass(quotelink, 'you'); - $.addClass(this.nodes.root, 'quotesYou'); - } - }, - menu: { - init: function() { - var input, label, ref; - label = $.el('label', { - className: 'toggle-you' - }, {innerHTML: " You"}); - input = $('input', label); - $.on(input, 'change', QuoteYou.menu.toggle); - return (ref = Menu.menu) != null ? ref.addEntry({ - el: label, - order: 80, - open: function(post) { - QuoteYou.menu.post = post.origin || post; - input.checked = QuoteYou.isYou(post); - return true; - } - }) : void 0; - }, - toggle: function() { - var clone, data, i, j, len, len1, post, quotelink, quoter, ref, ref1; - post = QuoteYou.menu.post; - data = { - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID, - val: true - }; - if (this.checked) { - QuoteYou.db.set(data); - } else { - QuoteYou.db["delete"](data); - } - ref = [post].concat(post.clones); - for (i = 0, len = ref.length; i < len; i++) { - clone = ref[i]; - clone.nodes.root.classList.toggle('yourPost', this.checked); - } - ref1 = Get.allQuotelinksLinkingTo(post); - for (j = 0, len1 = ref1.length; j < len1; j++) { - quotelink = ref1[j]; - if (this.checked) { - if (Conf['Mark Quotes of You']) { - $.add(quotelink, QuoteYou.mark.cloneNode(true)); - } - } else { - $.rm($('.qmark-you', quotelink)); - } - quotelink.classList.toggle('you', this.checked); - if ($.hasClass(quotelink, 'quotelink')) { - quoter = Get.postFromNode(quotelink).nodes.root; - quoter.classList.toggle('quotesYou', !!$('.quotelink.you', quoter)); - } - } - } - }, - cb: { - seek: function(type) { - var highlight, highlighted, post, posts, result, str; - highlight = g.SITE.classes.highlight; - if ((highlighted = $("." + highlight))) { - $.rmClass(highlighted, highlight); - } - if (!(QuoteYou.lastRead && doc.contains(QuoteYou.lastRead) && $.hasClass(QuoteYou.lastRead, 'quotesYou'))) { - if (!(post = QuoteYou.lastRead = $('.quotesYou'))) { - new Notice('warning', 'No posts are currently quoting you, loser.', 20); - return; - } - if (QuoteYou.cb.scroll(post)) { - return; - } - } else { - post = QuoteYou.lastRead; - } - str = type + "::div[contains(@class,'quotesYou')]"; - while ((post = (result = $.X(str, post)).snapshotItem(type === 'preceding' ? result.snapshotLength - 1 : 0))) { - if (QuoteYou.cb.scroll(post)) { - return; - } - } - posts = $$('.quotesYou'); - return QuoteYou.cb.scroll(posts[type === 'following' ? 0 : posts.length - 1]); - }, - scroll: function(root) { - var node, post, sel; - post = Get.postFromRoot(root); - if (!post.nodes.post.getBoundingClientRect().height) { - return false; - } else { - QuoteYou.lastRead = root; - location.href = Get.url('post', post); - Header.scrollTo(post.nodes.post); - if (post.isReply) { - sel = "" + g.SITE.selectors.postContainer + g.SITE.selectors.highlightable.reply; - node = post.nodes.root; - if (!node.matches(sel)) { - node = $(sel, node); - } - $.addClass(node, g.SITE.classes.highlight); - } - return true; - } - } - } - }; - - return QuoteYou; - -}).call(this); - -Quotify = (function() { - var Quotify, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - Quotify = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Resurrect Quotes']) { - return; - } - $.addClass(doc, 'resurrect-quotes'); - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Callbacks.Post.push({ - name: 'Resurrect Quotes', - cb: this.node - }); - }, - node: function() { - var deadlink, i, j, len, len1, link, ref, ref1; - if (this.isClone) { - this.nodes.archivelinks = $$('a.linkify.quotelink', this.nodes.comment); - return; - } - ref = $$('a.linkify', this.nodes.comment); - for (i = 0, len = ref.length; i < len; i++) { - link = ref[i]; - Quotify.parseArchivelink.call(this, link); - } - ref1 = $$('.deadlink', this.nodes.comment); - for (j = 0, len1 = ref1.length; j < len1; j++) { - deadlink = ref1[j]; - Quotify.parseDeadlink.call(this, deadlink); - } - }, - parseArchivelink: function(link) { - var boardID, m, postID, ref, threadID; - if (!(m = link.pathname.match(/^\/([^\/]+)\/thread\/S?(\d+)\/?$/))) { - return; - } - if ((ref = link.hostname) === 'boards.4chan.org' || ref === 'boards.4channel.org') { - return; - } - boardID = m[1]; - threadID = m[2]; - postID = link.hash.match(/^#[pq]?(\d+)$|$/)[1] || threadID; - if (Redirect.to('post', { - boardID: boardID, - postID: postID - })) { - $.addClass(link, 'quotelink'); - $.extend(link.dataset, { - boardID: boardID, - threadID: threadID, - postID: postID - }); - return this.nodes.archivelinks.push(link); - } - }, - parseDeadlink: function(deadlink) { - var a, boardID, fetchable, m, post, postID, quote, quoteID, redirect, ref; - if ($.hasClass(deadlink.parentNode, 'prettyprint')) { - Quotify.fixDeadlink(deadlink); - return; - } - quote = deadlink.textContent; - if (!(postID = (ref = quote.match(/\d+$/)) != null ? ref[0] : void 0)) { - return; - } - if (postID[0] === '0') { - Quotify.fixDeadlink(deadlink); - return; - } - boardID = (m = quote.match(/^>>>\/([a-z\d]+)/)) ? m[1] : this.board.ID; - quoteID = boardID + "." + postID; - if (post = g.posts.get(quoteID)) { - if (!post.isDead) { - a = $.el('a', { - href: g.SITE.Build.postURL(boardID, post.thread.ID, postID), - className: 'quotelink', - textContent: quote - }); - } else { - a = $.el('a', { - href: g.SITE.Build.postURL(boardID, post.thread.ID, postID), - className: 'quotelink deadlink', - textContent: quote - }); - $.add(a, Post.deadMark.cloneNode(true)); - $.extend(a.dataset, { - boardID: boardID, - threadID: post.thread.ID, - postID: postID - }); - } - } else { - redirect = Redirect.to('thread', { - boardID: boardID, - threadID: 0, - postID: postID - }); - fetchable = Redirect.to('post', { - boardID: boardID, - postID: postID - }); - if (redirect || fetchable) { - a = $.el('a', { - href: redirect || 'javascript:;', - className: 'deadlink', - textContent: quote - }); - $.add(a, Post.deadMark.cloneNode(true)); - if (fetchable) { - $.addClass(a, 'quotelink'); - $.extend(a.dataset, { - boardID: boardID, - postID: postID - }); - } - } - } - if (indexOf.call(this.quotes, quoteID) < 0) { - this.quotes.push(quoteID); - } - if (!a) { - $.add(deadlink, Post.deadMark.cloneNode(true)); - return; - } - $.replace(deadlink, a); - if ($.hasClass(a, 'quotelink')) { - return this.nodes.quotelinks.push(a); - } - }, - fixDeadlink: function(deadlink) { - var el, green; - if (!(el = deadlink.previousSibling) || el.nodeName === 'BR') { - green = $.el('span', { - className: 'quote' - }); - $.before(deadlink, green); - $.add(green, deadlink); - } - return $.replace(deadlink, slice.call(deadlink.childNodes)); - } - }; - - return Quotify; - -}).call(this); - -Main = (function() { - var Main, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Main = { - init: function() { - var db, flatten, i, items, j, k, key, len, mountedCB, ref, ref1, ref2, w; - try { - w = window; - if ($.platform === 'crx') { - w = w.wrappedJSObject || w; - } - if ('4chan X antidup' in w) { - return; - } - w['4chan X antidup'] = true; - } catch (error1) {} - try { - if (window.frameElement && ((ref = window.frameElement.src) === '' || ref === 'about:blank')) { - return; - } - } catch (error1) {} - if (doc && $.hasClass(doc, 'fourchan-x')) { - return; - } - $.asap(docSet, function() { - $.addClass(doc, 'fourchan-x', 'seaweedchan'); - if ($.engine) { - return $.addClass(doc, "ua-" + $.engine); - } - }); - $.on(d, '4chanXInitFinished', function() { - if (Main.expectInitFinished) { - return delete Main.expectInitFinished; - } else { - new Notice('error', 'Error: Multiple copies of 4chan X are enabled.'); - return $.addClass(doc, 'tainted'); - } - }); - mountedCB = function() { - var cb, j, len, ref1, results; - d.removeEventListener('mounted', mountedCB, true); - Main.isMounted = true; - ref1 = Main.mountedCBs; - results = []; - for (j = 0, len = ref1.length; j < len; j++) { - cb = ref1[j]; - try { - results.push(cb()); - } catch (error1) {} - } - return results; - }; - d.addEventListener('mounted', mountedCB, true); - flatten = function(parent, obj) { - var key, val; - if (obj instanceof Array) { - Conf[parent] = $.dict.clone(obj[0]); - } else if (typeof obj === 'object') { - for (key in obj) { - val = obj[key]; - flatten(key, val); - } - } else { - Conf[parent] = obj; - } - }; - if ((ref1 = location.hostname) === 'boards.4chan.org' || ref1 === 'boards.4channel.org') { - $.global(function() { - var fromCharCode0; - fromCharCode0 = String.fromCharCode; - return String.fromCharCode = function() { - if (document.body) { - String.fromCharCode = fromCharCode0; - } else if (document.currentScript && !document.currentScript.src) { - throw Error(); - } - return fromCharCode0.apply(this, arguments); - }; - }); - $.asap(docSet, function() { - return $.onExists(doc, 'iframe[srcdoc]', $.rm); - }); - } - flatten(null, Config); - ref2 = DataBoard.keys; - for (j = 0, len = ref2.length; j < len; j++) { - db = ref2[j]; - Conf[db] = $.dict(); - } - Conf['customTitles'] = $.dict.clone({ - '4chan.org': { - boards: { - 'qa': { - 'boardTitle': { - orig: '/qa/ - Question & Answer', - title: '/qa/ - 2D/Random' - } - } - } - } - }); - Conf['boardConfig'] = { - boards: $.dict() - }; - Conf['archives'] = Redirect.archives; - Conf['selectedArchives'] = $.dict(); - Conf['cooldowns'] = $.dict(); - Conf['Index Sort'] = $.dict(); - for (i = k = 0; k < 2; i = ++k) { - Conf["Last Long Reply Thresholds " + i] = $.dict(); - } - Conf['siteProperties'] = $.dict(); - Conf['Except Archives from Encryption'] = false; - Conf['JSON Navigation'] = true; - Conf['Oekaki Links'] = true; - Conf['Show Name and Subject'] = false; - Conf['QR Shortcut'] = true; - Conf['Bottom QR Link'] = true; - Conf['Toggleable Thread Watcher'] = true; - Conf['siteSoftware'] = ''; - Conf['Use Faster Image Host'] = 'true'; - Conf['Captcha Fixes'] = true; - Conf['captchaServiceDomain'] = ''; - Conf['captchaServiceKey'] = $.dict(); - if (/\.4chan(?:nel)?\.org$/.test(location.hostname) && !SW.yotsuba.regexp.pass.test(location.href) && !SW.yotsuba.regexp.captcha.test(location.href) && !$$('script:not([src])', d).filter(function(s) { - return /this\[/.test(s.textContent); - }).length) { - ($.getSync || $.get)({ - 'jsWhitelist': Conf['jsWhitelist'] - }, function(arg) { - var jsWhitelist; - jsWhitelist = arg.jsWhitelist; - return $.addCSP("script-src " + (jsWhitelist.replace(/^#.*$/mg, '').replace(/[\s;]+/g, ' ').trim())); - }); - } - items = $.dict(); - for (key in Conf) { - items[key] = void 0; - } - items['previousversion'] = void 0; - return ($.getSync || $.get)(items, function(items) { - var ref3; - if (!$.perProtocolSettings && /\.4chan(?:nel)?\.org$/.test(location.hostname) && ((ref3 = items['Redirect to HTTPS']) != null ? ref3 : Conf['Redirect to HTTPS']) && location.protocol !== 'https:') { - location.replace('https://' + location.host + location.pathname + location.search + location.hash); - return; - } - return $.asap(docSet, function() { - var ref4, val; - if ($.cantSet) { - - } else if (items.previousversion == null) { - Main.isFirstRun = true; - Main.ready(function() { - $.set('previousversion', g.VERSION); - return Settings.open(); - }); - } else if (items.previousversion !== g.VERSION) { - Main.upgrade(items); - } - for (key in Conf) { - val = Conf[key]; - Conf[key] = (ref4 = items[key]) != null ? ref4 : val; - } - return Site.init(Main.initFeatures); - }); - }); - }, - upgrade: function(items) { - var changes, previousversion; - previousversion = items.previousversion; - changes = Settings.upgrade(items, previousversion); - items.previousversion = changes.previousversion = g.VERSION; - return $.set(changes, function() { - var el, ref; - if ((ref = items['Show Updated Notifications']) != null ? ref : true) { - el = $.el('span', {innerHTML: "4chan X has been updated to version " + E(g.VERSION) + "."}); - return new Notice('info', el, 15); - } - }); - }, - parseURL: function(site, url) { - var pathname, r, ref; - if (site == null) { - site = g.SITE; - } - if (url == null) { - url = location; - } - r = {}; - if (!site) { - return r; - } - r.siteID = site.ID; - if (typeof site.isBoardlessPage === "function" ? site.isBoardlessPage(url) : void 0) { - return r; - } - pathname = url.pathname.split(/\/+/); - r.boardID = pathname[1]; - if (site.isFileURL(url)) { - r.VIEW = 'file'; - } else if (typeof site.isAuxiliaryPage === "function" ? site.isAuxiliaryPage(url) : void 0) { - - } else if ((ref = pathname[2]) === 'thread' || ref === 'res') { - r.VIEW = 'thread'; - r.threadID = r.THREADID = +pathname[3].replace(/\.\w+$/, ''); - } else if (pathname[2] === 'archive' && pathname[3] === 'res') { - r.VIEW = 'thread'; - r.threadID = r.THREADID = +pathname[4].replace(/\.\w+$/, ''); - r.threadArchived = true; - } else if (/^(?:catalog|archive)(?:\.\w+)?$/.test(pathname[2])) { - r.VIEW = pathname[2].replace(/\.\w+$/, ''); - } else if (/^(?:index|\d*)(?:\.\w+)?$/.test(pathname[2])) { - r.VIEW = 'index'; - } - return r; - }, - initFeatures: function() { - var base, err, feature, j, len, name, ref, ref1; - $.global(function() { - document.documentElement.classList.add('js-enabled'); - return window.FCX = {}; - }); - Main.jsEnabled = $.hasClass(doc, 'js-enabled'); - if (typeof $.ajaxPageInit === "function") { - $.ajaxPageInit(); - } - $.extend(g, Main.parseURL()); - if (g.boardID) { - g.BOARD = new Board(g.boardID); - } - if (!g.VIEW) { - if (typeof (base = g.SITE).initAuxiliary === "function") { - base.initAuxiliary(); - } - return; - } - if (g.VIEW === 'file') { - $.asap((function() { - return d.readyState !== 'loading'; - }), function() { - var base1, pathname, video; - if (g.SITE.software === 'yotsuba' && Conf['404 Redirect'] && (typeof (base1 = g.SITE).is404 === "function" ? base1.is404() : void 0)) { - pathname = location.pathname.split(/\/+/); - return Redirect.navigate('file', { - boardID: g.BOARD.ID, - filename: pathname[pathname.length - 1] - }); - } else if (video = $('video')) { - if (Conf['Volume in New Tab']) { - Volume.setup(video); - } - if (Conf['Loop in New Tab']) { - video.loop = true; - video.controls = false; - video.play(); - return ImageCommon.addControls(video); - } - } - }); - return; - } - g.threads = new SimpleDict(); - g.posts = new SimpleDict(); - $.onExists(doc, 'body', Main.initStyle); - ref = Main.features; - for (j = 0, len = ref.length; j < len; j++) { - ref1 = ref[j], name = ref1[0], feature = ref1[1]; - if (g.SITE.disabledFeatures && indexOf.call(g.SITE.disabledFeatures, name) >= 0) { - continue; - } - try { - feature.init(); - } catch (error1) { - err = error1; - Main.handleErrors({ - message: "\"" + name + "\" initialization crashed.", - error: err - }); - } - } - return $.ready(Main.initReady); - }, - initStyle: function() { - var keyboard, ref; - if (!Main.isThisPageLegit()) { - return; - } - if ((ref = $('link[href*=mobile]', d.head)) != null) { - ref.disabled = true; - } - doc.dataset.host = location.host; - $.addClass(doc, "sw-" + g.SITE.software); - $.addClass(doc, g.VIEW === 'thread' ? 'thread-view' : g.VIEW); - $.onExists(doc, '.ad-cnt, .adg-rects > .desktop', function(ad) { - return $.onExists(ad, 'img, iframe', function() { - return $.addClass(doc, 'ads-loaded'); - }); - }); - if (Conf['Autohiding Scrollbar']) { - $.addClass(doc, 'autohiding-scrollbar'); - } - $.ready(function() { - if (d.body.clientHeight > doc.clientHeight && (window.innerWidth === doc.clientWidth) !== Conf['Autohiding Scrollbar']) { - Conf['Autohiding Scrollbar'] = !Conf['Autohiding Scrollbar']; - $.set('Autohiding Scrollbar', Conf['Autohiding Scrollbar']); - return $.toggleClass(doc, 'autohiding-scrollbar'); - } - }); - $.addStyle(CSS.sub(CSS.boards), 'fourchanx-css'); - Main.bgColorStyle = $.el('style', { - id: 'fourchanx-bgcolor-css' - }); - keyboard = false; - $.on(d, 'mousedown', function() { - return keyboard = false; - }); - $.on(d, 'keydown', function(e) { - if (e.keyCode === 9) { - return keyboard = true; - } - }); - window.addEventListener('focus', (function() { - return doc.classList.toggle('keyboard-focus', keyboard); - }), true); - return Main.setClass(); - }, - setClass: function() { - var j, knownStyles, len, mainStyleSheet, ref, ref1, setStyle, style, styleSheet, styleSheets; - knownStyles = ['yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'photon', 'tomorrow', 'spooky']; - if (g.SITE.software === 'yotsuba' && g.VIEW === 'catalog') { - if ((mainStyleSheet = $.id('base-css'))) { - style = (ref = mainStyleSheet.href.match(/catalog_(\w+)/)) != null ? ref[1].replace('_new', '').replace(/_+/g, '-') : void 0; - if (indexOf.call(knownStyles, style) >= 0) { - $.addClass(doc, style); - return; - } - } - } - style = mainStyleSheet = styleSheets = null; - setStyle = function() { - var bgColor, css, div, j, len, rgb, s, styleSheet; - if (g.SITE.software === 'yotsuba') { - $.rmClass(doc, style); - style = null; - for (j = 0, len = styleSheets.length; j < len; j++) { - styleSheet = styleSheets[j]; - if (styleSheet.href === (mainStyleSheet != null ? mainStyleSheet.href : void 0)) { - style = styleSheet.title.toLowerCase().replace('new', '').trim().replace(/\s+/g, '-'); - if (style === '_special') { - style = styleSheet.href.match(/[a-z]*(?=[^\/]*$)/)[0]; - } - if (indexOf.call(knownStyles, style) < 0) { - style = null; - } - break; - } - } - if (style) { - $.addClass(doc, style); - $.rm(Main.bgColorStyle); - return; - } - } - div = g.SITE.bgColoredEl(); - div.style.position = 'absolute'; - div.style.visibility = 'hidden'; - $.add(d.body, div); - bgColor = window.getComputedStyle(div).backgroundColor; - $.rm(div); - rgb = bgColor.match(/[\d.]+/g); - if (!/^rgb\(/.test(bgColor)) { - s = window.getComputedStyle(d.body); - bgColor = s.backgroundColor + " " + s.backgroundImage + " " + s.backgroundRepeat + " " + s.backgroundPosition; - } - css = ".dialog, .suboption-list > div:last-of-type, :root.catalog-hover-expand .catalog-container:hover > .post {\n background: " + bgColor + ";\n}\n.unread-mark-read {\n background-color: rgba(" + (rgb.slice(0, 3).join(', ')) + ", " + (0.5 * (rgb[3] || 1)) + ");\n}"; - if ($.luma(rgb) < 100) { - css += ".watch-thread-link {\n background-image: url(\"data:image/svg+xml,\");\n}"; - } - Main.bgColorStyle.textContent = css; - return $.after($.id('fourchanx-css'), Main.bgColorStyle); - }; - $.onExists(d.head, g.SITE.selectors.styleSheet, function(el) { - mainStyleSheet = el; - if (g.SITE.software === 'yotsuba') { - styleSheets = $$('link[rel="alternate stylesheet"]', d.head); - } - new MutationObserver(setStyle).observe(mainStyleSheet, { - attributes: true, - attributeFilter: ['href'] - }); - $.on(mainStyleSheet, 'load', setStyle); - return setStyle(); - }); - if (!mainStyleSheet) { - ref1 = $$('link[rel="stylesheet"]', d.head); - for (j = 0, len = ref1.length; j < len; j++) { - styleSheet = ref1[j]; - $.on(styleSheet, 'load', setStyle); - } - return setStyle(); - } - }, - initReady: function() { - var base, base1, msg; - if (typeof (base = g.SITE).is404 === "function" ? base.is404() : void 0) { - if (g.VIEW === 'thread') { - ThreadWatcher.set404(g.BOARD.ID, g.THREADID, function() { - if (Conf['404 Redirect']) { - return Redirect.navigate('thread', { - boardID: g.BOARD.ID, - threadID: g.THREADID, - postID: +location.hash.match(/\d+/) - }, "/" + g.BOARD + "/"); - } - }); - } - return; - } - if (typeof (base1 = g.SITE).isIncomplete === "function" ? base1.isIncomplete() : void 0) { - msg = $.el('div', {innerHTML: "The page didn't load completely.
      Some features may not work unless you reload."}); - $.on($('a', msg), 'click', function() { - return location.reload(); - }); - new Notice('warning', msg); - } - if (g.VIEW === 'catalog') { - return Main.initCatalog(); - } else if (!Index.enabled) { - if (g.SITE.awaitBoard) { - return g.SITE.awaitBoard(Main.initThread); - } else { - return Main.initThread(); - } - } else { - Main.expectInitFinished = true; - return $.event('4chanXInitFinished'); - } - }, - initThread: function() { - var base, base1, board, errors, posts, ref, s, threads; - s = g.SITE.selectors; - if ((board = $(((ref = s.boardFor) != null ? ref[g.VIEW] : void 0) || s.board))) { - threads = []; - posts = []; - errors = []; - try { - if (typeof (base = g.SITE).preParsingFixes === "function") { - base.preParsingFixes(board); - } - } catch (error1) {} - Main.addThreadsObserver = new MutationObserver(Main.addThreads); - Main.addPostsObserver = new MutationObserver(Main.addPosts); - Main.addThreadsObserver.observe(board, { - childList: true - }); - Main.parseThreads($$(s.thread, board), threads, posts, errors); - if (errors.length) { - Main.handleErrors(errors); - } - if (g.VIEW === 'thread') { - if (g.threadArchived) { - threads[0].isArchived = true; - threads[0].kill(); - } - if (typeof (base1 = g.SITE).parseThreadMetadata === "function") { - base1.parseThreadMetadata(threads[0]); - } - } - Main.callbackNodes('Thread', threads); - return Main.callbackNodesDB('Post', posts, function() { - var j, len, post; - for (j = 0, len = posts.length; j < len; j++) { - post = posts[j]; - QuoteThreading.insert(post); - } - Main.expectInitFinished = true; - return $.event('4chanXInitFinished'); - }); - } else { - Main.expectInitFinished = true; - return $.event('4chanXInitFinished'); - } - }, - parseThreads: function(threadRoots, threads, posts, errors) { - var boardID, boardObj, j, len, postRoots, ref, thread, threadID, threadRoot; - for (j = 0, len = threadRoots.length; j < len; j++) { - threadRoot = threadRoots[j]; - boardObj = (boardID = threadRoot.dataset.board) ? (boardID = encodeURIComponent(boardID), g.boards[boardID] || new Board(boardID)) : g.BOARD; - threadID = +threadRoot.id.match(/\d*$/)[0]; - if (!threadID || ((ref = boardObj.threads.get(threadID)) != null ? ref.nodes.root : void 0)) { - return; - } - thread = new Thread(threadID, boardObj); - thread.nodes.root = threadRoot; - threads.push(thread); - postRoots = $$(g.SITE.selectors.postContainer, threadRoot); - if (g.SITE.isOPContainerThread) { - postRoots.unshift(threadRoot); - } - Main.parsePosts(postRoots, thread, posts, errors); - Main.addPostsObserver.observe(threadRoot, { - childList: true - }); - } - }, - parsePosts: function(postRoots, thread, posts, errors) { - var err, j, len, postRoot; - for (j = 0, len = postRoots.length; j < len; j++) { - postRoot = postRoots[j]; - if (!(postRoot.dataset.fullID && g.posts.get(postRoot.dataset.fullID)) && $(g.SITE.selectors.comment, postRoot)) { - try { - posts.push(new Post(postRoot, thread, thread.board)); - } catch (error1) { - err = error1; - errors.push({ - message: "Parsing of Post No." + (postRoot.id.match(/\d+/)) + " failed. Post will be skipped.", - error: err, - html: postRoot.outerHTML - }); - } - } - } - }, - addThreads: function(records) { - var errors, j, k, len, len1, node, posts, record, ref, threadRoots, threads; - threadRoots = []; - for (j = 0, len = records.length; j < len; j++) { - record = records[j]; - ref = record.addedNodes; - for (k = 0, len1 = ref.length; k < len1; k++) { - node = ref[k]; - if (node.nodeType === Node.ELEMENT_NODE && node.matches(g.SITE.selectors.thread)) { - threadRoots.push(node); - } - } - } - if (!threadRoots.length) { - return; - } - threads = []; - posts = []; - errors = []; - Main.parseThreads(threadRoots, threads, posts, errors); - if (errors.length) { - Main.handleErrors(errors); - } - Main.callbackNodes('Thread', threads); - return Main.callbackNodesDB('Post', posts, function() { - return $.event('PostsInserted', null, records[0].target); - }); - }, - addPosts: function(records) { - var anyRemoved, el, errors, j, k, l, len, len1, len2, n, node, postRoots, posts, record, ref, ref1, ref2, thread, threads, threadsRM; - threads = []; - threadsRM = []; - posts = []; - errors = []; - for (j = 0, len = records.length; j < len; j++) { - record = records[j]; - thread = Get.threadFromRoot(record.target); - postRoots = []; - ref = record.addedNodes; - for (k = 0, len1 = ref.length; k < len1; k++) { - node = ref[k]; - if (node.nodeType === Node.ELEMENT_NODE) { - if (node.matches(g.SITE.selectors.postContainer) || (node = $(g.SITE.selectors.postContainer, node))) { - postRoots.push(node); - } - } - } - n = posts.length; - Main.parsePosts(postRoots, thread, posts, errors); - if (posts.length > n && indexOf.call(threads, thread) < 0) { - threads.push(thread); - } - anyRemoved = false; - ref1 = record.removedNodes; - for (l = 0, len2 = ref1.length; l < len2; l++) { - el = ref1[l]; - if (((ref2 = Get.postFromRoot(el)) != null ? ref2.nodes.root : void 0) === el && !doc.contains(el)) { - anyRemoved = true; - break; - } - } - if (anyRemoved && indexOf.call(threadsRM, thread) < 0) { - threadsRM.push(thread); - } - } - if (errors.length) { - Main.handleErrors(errors); - } - return Main.callbackNodesDB('Post', posts, function() { - var len3, len4, m, o; - for (m = 0, len3 = threads.length; m < len3; m++) { - thread = threads[m]; - $.event('PostsInserted', null, thread.nodes.root); - } - for (o = 0, len4 = threadsRM.length; o < len4; o++) { - thread = threadsRM[o]; - $.event('PostsRemoved', null, thread.nodes.root); - } - }); - }, - initCatalog: function() { - var board, errors, s, threads; - s = g.SITE.selectors.catalog; - if (s && (board = $(s.board))) { - threads = []; - errors = []; - Main.addCatalogThreadsObserver = new MutationObserver(Main.addCatalogThreads); - Main.addCatalogThreadsObserver.observe(board, { - childList: true - }); - Main.parseCatalogThreads($$(s.thread, board), threads, errors); - if (errors.length) { - Main.handleErrors(errors); - } - Main.callbackNodes('CatalogThreadNative', threads); - } - Main.expectInitFinished = true; - return $.event('4chanXInitFinished'); - }, - parseCatalogThreads: function(threadRoots, threads, errors) { - var err, j, len, ref, thread, threadRoot; - for (j = 0, len = threadRoots.length; j < len; j++) { - threadRoot = threadRoots[j]; - try { - thread = new CatalogThreadNative(threadRoot); - if (((ref = thread.thread.catalogViewNative) != null ? ref.nodes.root : void 0) !== threadRoot) { - thread.thread.catalogViewNative = thread; - threads.push(thread); - } - } catch (error1) { - err = error1; - errors.push({ - message: "Parsing of Catalog Thread No." + ((threadRoot.dataset.id || threadRoot.id).match(/\d+/)) + " failed. Thread will be skipped.", - error: err, - html: threadRoot.outerHTML - }); - } - } - }, - addCatalogThreads: function(records) { - var errors, j, k, len, len1, node, record, ref, threadRoots, threads; - threadRoots = []; - for (j = 0, len = records.length; j < len; j++) { - record = records[j]; - ref = record.addedNodes; - for (k = 0, len1 = ref.length; k < len1; k++) { - node = ref[k]; - if (node.nodeType === Node.ELEMENT_NODE && node.matches(g.SITE.selectors.catalog.thread)) { - threadRoots.push(node); - } - } - } - if (!threadRoots.length) { - return; - } - threads = []; - errors = []; - Main.parseCatalogThreads(threadRoots, threads, errors); - if (errors.length) { - Main.handleErrors(errors); - } - return Main.callbackNodes('CatalogThreadNative', threads); - }, - callbackNodes: function(klass, nodes) { - var cb, i, node; - i = 0; - cb = Callbacks[klass]; - while (node = nodes[i++]) { - cb.execute(node); - } - }, - callbackNodesDB: function(klass, nodes, cb) { - var cbs, fn, i, softTask; - i = 0; - cbs = Callbacks[klass]; - fn = function() { - var node; - if (!(node = nodes[i])) { - return false; - } - cbs.execute(node); - return ++i % 25; - }; - softTask = function() { - while (fn()) { - continue; - } - if (!nodes[i]) { - if (cb) { - cb(); - } - return; - } - return setTimeout(softTask, 0); - }; - return softTask(); - }, - handleErrors: function(errors) { - var div, enabled, error, j, len, logs, msg; - if (d.body && $.hasClass(d.body, 'fourchan_x') && !$.hasClass(doc, 'tainted')) { - new Notice('error', 'Error: Multiple copies of 4chan X are enabled.'); - $.addClass(doc, 'tainted'); - } - if (g.SITE.testNativeExtension && !$.hasClass(doc, 'tainted')) { - enabled = g.SITE.testNativeExtension().enabled; - if (enabled) { - $.addClass(doc, 'tainted'); - if (Conf['Disable Native Extension'] && !Main.isFirstRun) { - msg = $.el('div', {innerHTML: "Failed to disable the native extension. You may need to block it."}); - new Notice('error', msg); - } - } - } - if (!(errors instanceof Array)) { - error = errors; - } else if (errors.length === 1) { - error = errors[0]; - } - if (error) { - new Notice('error', Main.parseError(error, Main.reportLink([error])), 15); - return; - } - div = $.el('div', {innerHTML: E(errors.length) + " errors occurred." + (Main.reportLink(errors)).innerHTML + " [show]"}); - $.on(div.lastElementChild, 'click', function() { - var ref; - return ref = this.textContent === 'show' ? ['hide', false] : ['show', true], this.textContent = ref[0], logs.hidden = ref[1], ref; - }); - logs = $.el('div', { - hidden: true - }); - for (j = 0, len = errors.length; j < len; j++) { - error = errors[j]; - $.add(logs, Main.parseError(error)); - } - return new Notice('error', [div, logs], 30); - }, - parseError: function(data, reportLink) { - var context, error, lines, message, ref, ref1; - c.error(data.message, data.error.stack); - message = $.el('div', {innerHTML: E(data.message) + ((reportLink) ? (reportLink).innerHTML : "")}); - error = $.el('div', { - textContent: (data.error.name || 'Error') + ": " + (data.error.message || 'see console for details') - }); - lines = ((ref = data.error.stack) != null ? (ref1 = ref.match(/\d+(?=:\d+\)?$)/mg)) != null ? ref1.join().replace(/^/, ' at ') : void 0 : void 0) || ''; - context = $.el('div', { - textContent: "(4chan X ccd0 v" + g.VERSION + " " + $.platform + " on " + $.engine + lines + ")" - }); - return [message, error, context]; - }, - reportLink: function(errors) { - var addDetails, data, details, info, title, url; - data = errors[0]; - title = data.message; - if (errors.length > 1) { - title += " (+" + (errors.length - 1) + " other errors)"; - } - details = ''; - addDetails = function(text) { - if (!(encodeURIComponent(title + details + text + '\n').length > 8143)) { - return details += text + '\n'; - } - }; - addDetails("[Please describe the steps needed to reproduce this error.]\n\nScript: 4chan X ccd0 v" + g.VERSION + " " + $.platform + "\nURL: " + location.href + "\nUser agent: " + navigator.userAgent); - if ($.platform === 'userscript' && (info = typeof GM !== "undefined" && GM !== null ? GM.info : (typeof GM_info !== "undefined" && GM_info !== null ? GM_info : void 0))) { - addDetails("Userscript manager: " + info.scriptHandler + " " + info.version); - } - addDetails('\n' + data.error); - if (data.error.stack) { - addDetails(data.error.stack.replace(data.error.toString(), '').trim()); - } - if (data.html) { - addDetails('\n`' + data.html + '`'); - } - details = details.replace(/file:\/{3}.+\//g, ''); - url = 'https://github.com/ccd0/4chan-x/issues'.replace('%title', encodeURIComponent(title)).replace('%details', encodeURIComponent(details)); - return {innerHTML: " [report]"}; - }, - isThisPageLegit: function() { - if (!('thisPageIsLegit' in Main)) { - Main.thisPageIsLegit = g.SITE.isThisPageLegit ? g.SITE.isThisPageLegit() : !/^[45]\d\d\b/.test(document.title) && !/\.(?:json|rss)$/.test(location.pathname); - } - return Main.thisPageIsLegit; - }, - ready: function(cb) { - return $.ready(function() { - if (Main.isThisPageLegit()) { - return cb(); - } - }); - }, - mounted: function(cb) { - if (Main.isMounted) { - return cb(); - } else { - return Main.mountedCBs.push(cb); - } - }, - mountedCBs: [], - features: [['Polyfill', Polyfill], ['Board Configuration', BoardConfig], ['Normalize URL', NormalizeURL], ['Delay Redirect on Post', PostRedirect], ['Captcha Configuration', Captcha.replace], ['Image Host Rewriting', ImageHost], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Tinyboard Glue', Tinyboard], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Count Posts by ID', IDPostCount], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply Personas', QR.persona], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Post Jumper', PostJumper], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Copy Text Link', CopyTextLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Edit Link', QR.oekaki.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Favicon', Favicon], ['Unread', Unread], ['Unread Line in Index', UnreadIndex], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Announcements', PSA], ['Flash Features', Flash], ['Reply Pruning', ReplyPruning], ['Mod Contact Links', ModContact]] - }; - - return Main; - -}).call(this); - -Main.init(); - -})(); diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx deleted file mode 100644 index d6deffe5ab53119e133af329a41c0f91cc4f77fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 333535 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

      h)WLU+q7y_G1HyR1 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

      }6kd>0O&Kd4S;i>j+vFVJ?J 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

      D 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 Q0CYV~ukU&32(Nel0Sy;H!vFvP diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js deleted file mode 100644 index 1e2bf8e71..000000000 --- a/builds/4chan-X.meta.js +++ /dev/null @@ -1,113 +0,0 @@ -// ==UserScript== -// @name 4chan X -// @version 1.14.22.4 -// @minGMVer 1.14 -// @minFFVer 26 -// @namespace 4chan-X -// @description 4chan X is a script that adds various features to anonymous imageboards. -// @license MIT; https://github.com/ccd0/4chan-x/blob/master/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 -// @updateURL https://www.4chan-x.net/builds/4chan-X.meta.js -// @downloadURL https://www.4chan-x.net/builds/4chan-X.user.js -// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAF5JREFUeNrtkTESABAQxPD/R6tsE2dUGYUtFJvLDKf93KevHJAjpBorAQWSBIKqFASC4G0pCAkm4GfaEvgYXl0T6HBaE97f0vmnfYHbZOMLZCx9ISdKWwjOWZSC8GYm4SUGwfYgqI4AAAAASUVORK5CYII= -// ==/UserScript== diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js deleted file mode 100644 index 2cbbe7fb1..000000000 --- a/builds/4chan-X.user.js +++ /dev/null @@ -1,27999 +0,0 @@ -// ==UserScript== -// @name 4chan X -// @version 1.14.22.4 -// @minGMVer 1.14 -// @minFFVer 26 -// @namespace 4chan-X -// @description 4chan X is a script that adds various features to anonymous imageboards. -// @license MIT; https://github.com/ccd0/4chan-x/blob/master/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 -// @updateURL https://www.4chan-x.net/builds/4chan-X.meta.js -// @downloadURL https://www.4chan-x.net/builds/4chan-X.user.js -// @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 -* http://zixaphir.github.io/appchan-x/ -* 4chan x Copyright © 2009-2011 James Campos -* https://github.com/aeosynth/4chan-x -* 4chan x Copyright © 2012-2014 Nicolas Stepien -* https://4chan-x.just-believe.in/ -* 4chan x Copyright © 2013-2014 Jordan Bates -* 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 -* -* Font Awesome by Dave Gandy (http://fontawesome.io) -* license: http://fontawesome.io/license/ -* -* Icons used to identify various websites are property of the respective websites. -*/ - -(function() { - -'use strict'; - -var $, $$, Anonymize, AntiAutoplay, ArchiveLink, Banner, Board, BoardConfig, CSS, Callbacks, Captcha, CatalogLinks, CatalogThread, CatalogThreadNative, Config, Connection, CopyTextLink, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, Embedding, ExpandComment, ExpandThread, FappeTyme, Favicon, Fetcher, FileInfo, Filter, Flash, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, IDPostCount, ImageCommon, ImageExpand, ImageHost, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Metadata, ModContact, Nav, NormalizeURL, Notice, PSA, PSAHiding, PassLink, PassMessage, Polyfill, Post, PostHiding, PostJumper, PostRedirect, PostSuccessful, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, ReplyPruning, Report, ReportLink, RevealSpoilers, SW, Sauce, Settings, ShimSet, SimpleDict, Site, Test, Thread, ThreadHiding, ThreadLinks, ThreadStats, ThreadUpdater, ThreadWatcher, Time, Tinyboard, UI, Unread, UnreadIndex, Volume; - -var Conf, E, c, d, doc, docSet, g; - -Conf = Object.create(null); -c = console; -d = document; -doc = d.documentElement; - -// Workaround for userscript managers that run script before document.documentElement is set -docSet = function() { - return (doc = d.documentElement); -}; - -g = { - VERSION: '1.14.22.4', - NAMESPACE: '4chan X.', - sites: Object.create(null), - boards: Object.create(null) -}; - -E = (function() { - var fn, r, regex, str; - str = { - '&': '&', - "'": ''', - '"': '"', - '<': '<', - '>': '>' - }; - r = String.prototype.replace; - regex = /[&"'<>]/g; - fn = function(x) { - return str[x]; - }; - return function(text) { - return r.call(text, regex, fn); - }; -})(); - -E.cat = function(templates) { - var html, i, len; - html = ''; - for (i = 0, len = templates.length; i < len; i++) { - html += templates[i].innerHTML; - } - return html; -}; - -Config = (function() { - var Config; - - Config = { - main: { - 'Miscellaneous': { - 'Redirect to HTTPS': [true, 'Redirect to the HTTPS version of 4chan.'], - 'JSON Index': [true, 'Replace the original board index with one supporting searching, sorting, infinite scrolling, and a catalog mode.'], - 'Use 4chan X Catalog': [true, 'Link to 4chan X\'s catalog instead of the native 4chan one.', 1], - 'Index Refresh Notifications': [false, 'Show a notice at the top of the page when the index is refreshed.', 1], - 'Follow Cursor': [true, 'Image Hover and Quote Preview move with the mouse cursor.'], - 'Open Threads in New Tab': [false, 'Make links to threads in the index / 4chan X catalog open in a new tab.'], - 'External Catalog': [false, 'Link to external catalog instead of the internal one.'], - 'Catalog Links': [false, 'Add toggle link in header menu to turn Navigation links into links to each board\'s catalog.'], - 'Announcement Hiding': [true, 'Add button to hide 4chan announcements.'], - 'Desktop Notifications': [true, 'Enables desktop notifications across various 4chan X features.'], - '404 Redirect': [true, 'Redirect dead threads and images to the archives.'], - 'Archive Report': [true, 'Enable reporting posts to supported archives.'], - 'Exempt Archives from Encryption': [true, 'Permit loading content from, and warningless redirects to, HTTP-only archives from HTTPS pages.'], - 'Keybinds': [true, 'Bind actions to keyboard shortcuts.'], - 'Time Formatting': [true, 'Localize and format timestamps.'], - 'Relative Post Dates': [true, 'Display dates like "3 minutes ago". Tooltip shows the timestamp.'], - 'Relative Date Title': [true, 'Show Relative Post Date only when hovering over dates.', 1], - 'Comment Expansion': [true, 'Expand comments that are too long to display on the index. Not applicable with JSON Index.'], - 'File Info Formatting': [true, 'Reformat the file information.'], - 'Thread Expansion': [true, 'Add buttons to expand threads.'], - 'Index Navigation': [false, 'Add buttons to navigate between threads.'], - 'Reply Navigation': [false, 'Add buttons to navigate to top / bottom of thread.'], - 'Unique ID and Capcode Navigation': [false, 'Add buttons to navigate to posts having the same unique ID or capcode.'], - 'Custom Board Titles': [true, 'Allow editing of the board title and subtitle by ctrl/\u2318+clicking them.'], - 'Persistent Custom Board Titles': [false, 'Force custom board titles to be persistent, even if the board titles are updated.', 1], - 'Show Updated Notifications': [true, 'Show notifications when 4chan X is successfully updated.'], - 'Color User IDs': [true, 'Assign unique colors to user IDs on boards that use them'], - 'Count Posts by ID': [true, 'Display number of posts in the thread when hovering over an ID.'], - 'Remove Spoilers': [false, 'Remove all spoilers in text.'], - 'Reveal Spoilers': [false, 'Indicate spoilers if Remove Spoilers is enabled, or make the text appear hovered if Remove Spoiler is disabled.'], - 'Normalize URL': [true, 'Rewrite the URL of the current page, removing slugs and excess slashes, and changing /res/ to /thread/.'], - 'Work around CORB Bug': [true, 'Leave this checked until your garbage browser is fixed.'], - 'Disable Autoplaying Sounds': [false, 'Prevent sounds on the page from autoplaying.'], - 'Disable Native Extension': [true, '4chan X is NOT designed to work with the native extension.'], - 'Enable Native Flash Embedding': [true, 'Activate the native extension\'s Flash embedding if the native extension is disabled.'] - }, - 'Linkification': { - 'Linkify': [true, 'Convert text into links where applicable.'], - 'Link Title': [true, 'Replace the link of a supported site with its actual title.', 1], - 'Cover Preview': [true, 'Show preview of supported links on hover.', 1], - 'Embedding': [true, 'Embed supported services. Note: Some services don\'t work on HTTPS.', 1], - 'Auto-embed': [false, 'Auto-embed Linkify Embeds.', 2], - 'Floating Embeds': [false, 'Embed content in a frame that remains in place when the page is scrolled.', 2] - }, - 'Filtering': { - 'Anonymize': [false, 'Make everyone Anonymous.'], - 'Filter': [true, 'Self-moderation placebo.'], - 'Filtered Backlinks': [false, 'When enabled, shows backlinks to filtered posts with a line-through decoration. Otherwise, hides the backlinks.', 1], - 'Filter in Native Catalog': [true, 'Apply 4chan X filters in native catalog.', 1], - 'MD5 Quick Filter Notifications': [true, 'Show notification when quick filtering MD5s using the button or keybind.', 1], - 'Recursive Hiding': [true, 'Hide replies of hidden posts, recursively.'], - 'Thread Hiding Buttons': [true, 'Add buttons to hide entire threads.'], - 'Reply Hiding Buttons': [true, 'Add buttons to hide single replies.'], - 'Stubs': [true, 'Show stubs of hidden threads / replies.'] - }, - 'Images and Videos': { - 'Image Expansion': [true, 'Expand images / videos.'], - 'Image Hover': [true, 'Show full image / video on mouseover.'], - 'Image Hover in Catalog': [true, 'Show full image / video on mouseover in 4chan X catalog.'], - 'Gallery': [true, 'Adds a simple and cute image gallery. Has more options in the gallery menu.'], - 'Fullscreen Gallery': [false, 'Open gallery in fullscreen mode.', 1], - 'PDF in Gallery': [false, 'Show PDF files in gallery.', 1], - 'Sauce': [true, 'Add sauce links to images.'], - 'WEBM Metadata': [true, 'Add link to fetch title metadata from webm videos.'], - 'Reveal Spoiler Thumbnails': [false, 'Replace spoiler thumbnails with the original image.'], - 'Replace GIF': [false, 'Replace gif thumbnails with the actual image.'], - 'Replace JPG': [false, 'Replace jpg thumbnails with the actual image.'], - 'Replace PNG': [false, 'Replace png thumbnails with the actual image.'], - 'Replace WEBM': [false, 'Replace webm, mp4, and ogv thumbnails with the actual video. Probably will degrade browser performance ;)'], - 'Image Prefetching': [true, 'Add a shortcut icon to the header to turn on image preloading.'], - 'Fappe Tyme': [true, 'Hide posts without images when header menu item is checked. *hint* *hint*'], - 'Werk Tyme': [true, 'Hide all post images when header menu item is checked.'], - 'Autoplay': [true, 'Videos begin playing immediately when opened.'], - 'Restart when Opened': [false, 'Restart GIFs and WebMs when you hover over or expand them.'], - 'Show Controls': [true, 'Show controls on videos expanded inline.'], - 'Click Passthrough': [false, 'Clicks on videos trigger your browser\'s default behavior. Videos can be contracted with button / dragging to the left.', 1], - 'Allow Sound': [true, 'Open videos with the sound unmuted.'], - 'Mouse Wheel Volume': [true, 'Adjust volume of videos with the mouse wheel over the thumbnail/filename/gallery.'], - 'Loop in New Tab': [true, 'Loop videos opened in their own tabs.'], - 'Volume in New Tab': [true, 'Apply 4chan X mute and volume settings to videos opened in their own tabs.'] - }, - 'Menu': { - 'Menu': [true, 'Add a drop-down menu to posts.'], - 'Report Link': [true, 'Add a report link to the menu.', 1], - 'Copy Text Link': [true, 'Add a link to copy the post\'s text.', 1], - 'Thread Hiding Link': [true, 'Add a link to hide entire threads.', 1], - 'Reply Hiding Link': [true, 'Add a link to hide single replies.', 1], - 'Delete Link': [true, 'Add post and image deletion links to the menu.', 1], - 'Archive Link': [true, 'Add an archive link to the menu.', 1], - 'Edit Link': [true, 'Add a link to edit the image in Tegaki, /i/\'s painting program. Requires Quick Reply.', 1], - 'Download Link': [false, 'Add a download with original filename link to the menu.', 1] - }, - 'Monitoring': { - 'Thread Updater': [true, 'Fetch and insert new replies. Has more options in the header menu and the "Advanced" tab.'], - 'Unread Count': [true, 'Show the unread posts count in the tab title.'], - 'Quoted Title': [false, 'Change the page title to reflect you\'ve been quoted.', 1], - 'Hide Unread Count at (0)': [false, 'Hide the unread posts count in the tab title when it reaches 0.', 1], - 'Unread Favicon': [true, 'Show a different favicon when there are unread posts.'], - 'Unread Line': [true, 'Show a line to distinguish read posts from unread ones.'], - 'Remember Last Read Post': [true, 'Remember how far you\'ve read after you close the thread.'], - 'Scroll to Last Read Post': [true, 'Scroll back to the last read post when reopening a thread.', 1], - 'Unread Line in Index': [false, 'Show a line between read and unread posts in threads in the index.', 1], - 'Remove Thread Excerpt': [false, 'Replace the excerpt of the thread in the tab title with the board title.'], - 'Thread Stats': [true, 'Display reply and image count.'], - 'IP Count in Stats': [true, 'Display the unique IP count in the thread stats.', 1], - 'Page Count in Stats': [true, 'Display the page count in the thread stats.', 1], - 'Updater and Stats in Header': [true, 'Places the thread updater and thread stats in the header instead of floating them.'], - 'Thread Watcher': [true, 'Bookmark threads. Has more options in the thread watcher menu.'], - 'Fixed Thread Watcher': [true, 'Makes the thread watcher scroll with the page.', 1], - 'Persistent Thread Watcher': [false, 'The thread watcher will be visible when the page is loaded.', 1], - 'Mark New IPs': [false, 'Label each post from a new IP with the thread\'s current IP count.'], - 'Reply Pruning': [true, 'Add option in header menu to hide old replies in long threads. Activated by default in stickies.'], - 'Prune All Threads': [false, 'Activate Reply Pruning by default in all threads.', 1] - }, - 'Posting and Captchas': { - 'Quick Reply': [true, 'All-in-one form to reply, create threads, automate dumping and more.'], - 'Persistent QR': [false, 'The Quick reply won\'t disappear after posting.', 1], - 'Auto Hide QR': [true, 'Automatically hide the quick reply when posting.', 2], - 'Open Post in New Tab': [true, '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': [false, 'Remember the size of the Quick reply.', 1], - 'Remember Spoiler': [false, 'Remember the spoiler state, instead of resetting after posting.', 1], - 'Randomize Filename': [false, 'Set the filename to a random timestamp within the past year. Disabled on /f/.', 1], - 'Show New Thread Option in Threads': [true, 'Show the option to post a new / different thread from inside a thread.', 1], - 'Show Upload Progress': [true, 'Track progress of file uploads as percentage in submit button.', 1], - 'Cooldown': [true, 'Indicate the remaining time before posting again.', 1], - 'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.', 1], - 'Auto-load captcha': [false, 'Automatically load the captcha in the QR even if your post is empty.', 1], - 'Post on Captcha Completion': [false, 'Submit the post immediately when the captcha is completed.', 1], - 'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha even if Javascript is enabled.'], - 'Pass Link': [false, 'Add a 4chan Pass login link to the bottom of the page.'] - }, - 'Quote Links': { - 'Quote Backlinks': [true, 'Add quote backlinks.'], - 'OP Backlinks': [true, 'Add backlinks to the OP.', 1], - 'Bottom Backlinks': [false, 'Place backlinks at the bottom of posts.', 1], - 'Quote Inlining': [true, 'Inline quoted post on click.'], - 'Inline Cross-thread Quotes Only': [false, 'Don\'t inline quote links when the posts are visible in the thread.', 1], - 'Quote Hash Navigation': [false, 'Include an extra link after quotes for autoscrolling to quoted posts.', 1], - 'Forward Hiding': [true, 'Hide original posts of inlined backlinks.', 1], - 'Quote Previewing': [true, 'Show quoted post on hover.'], - 'Quote Highlighting': [true, 'Highlight the previewed post.', 1], - 'Resurrect Quotes': [true, 'Link dead quotes to the archives, and support inlining/previewing of archive links like quote links.'], - 'Remember Your Posts': [true, 'Remember your posting history.'], - 'Mark Quotes of You': [true, 'Add \'(You)\' to quotes linking to your posts.', 1], - 'Highlight Posts Quoting You': [true, 'Highlights any posts that contain a quote to your post.', 1], - 'Highlight Own Posts': [true, 'Highlights own posts.', 1], - 'Mark OP Quotes': [true, 'Add \'(OP)\' to OP quotes.'], - 'Mark Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.'], - 'Quote Threading': [true, 'Add option in header menu to thread conversations.'] - } - }, - imageExpansion: { - 'Fit width': [true, ''], - 'Fit height': [false, ''], - 'Scroll into view': [true, 'Scroll down when expanding images to bring the full image into view.'], - 'Expand spoilers': [true, 'Expand all images along with spoilers.'], - 'Expand videos': [true, 'Expand all images also expands videos.'], - 'Expand from here': [false, 'Expand all images only from current position to thread end.'], - 'Expand thread only': [false, 'In index, expand all images only within the current thread.'], - 'Advance on contract': [false, 'Advance to next post when contracting an expanded image.'] - }, - gallery: { - 'Hide Thumbnails': [false], - 'Fit Width': [true], - 'Fit Height': [true], - 'Stretch to Fit': [false], - 'Scroll to Post': [true], - 'Slide Delay': [6.0] - }, - 'Default Volume': 1.0, - threadWatcher: { - 'Current Board': [false, 'Only show watched threads from the current board.'], - 'Auto Update Thread Watcher': [true, 'Periodically check status of watched threads.'], - 'Auto Watch': [true, 'Automatically watch threads you start.'], - 'Auto Watch Reply': [true, 'Automatically watch threads you reply to.'], - 'Auto Prune': [false, 'Automatically remove dead threads.'], - 'Show Page': [true, 'Show what page watched threads are on.'], - 'Show Unread Count': [true, 'Show number of unread posts in watched threads.'], - 'Show Site Prefix': [true, 'When multiple sites are shown in the thread watcher, add a prefix to board names to distinguish them.'], - 'Require OP Quote Link': [false, '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: false - }, - 'Custom CSS': true, - Index: { - 'Index Mode': 'paged', - 'Previous Index Mode': 'paged', - 'Index Size': 'small', - 'Show Replies': [true, 'Show replies in the index, and also in the catalog if "Catalog hover expand" is checked.'], - 'Catalog Hover Expand': [false, 'Expand the comment and show more details when you hover over a thread in the catalog.'], - 'Catalog Hover Toggle': [true, 'Turn "Catalog hover expand" on and off by clicking in the catalog.'], - 'Pin Watched Threads': [false, 'Move watched threads to the start of the index.'], - 'Anchor Hidden Threads': [true, 'Move hidden threads to the end of the index.'], - 'Refreshed Navigation': [false, 'Refresh index when navigating through pages.'] - }, - Header: { - 'Fixed Header': true, - 'Header auto-hide': false, - 'Header auto-hide on scroll': false, - 'Bottom Header': false, - 'Centered links': false, - 'Header catalog links': false, - 'Bottom Board List': true, - 'Shortcut Icons': true, - 'Custom Board Navigation': true - }, - archives: { - archiveLists: 'https://4chenz.github.io/archives.json/archives.json', - lastarchivecheck: 0, - archiveAutoUpdate: true - }, - 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\",\"https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions\"]", - QR: { - 'QR.personas': "#options:\"sage\";boards:jp;always", - sjisPreview: false - }, - 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': [false, 'Beep on new post to completely read thread.'], - 'Beep Quoting You': [false, 'Beep on new post quoting you.'], - 'Auto Scroll': [false, 'Scroll updated posts into view. Only enabled at bottom of page.'], - 'Bottom Scroll': [false, 'Always scroll to the bottom, not the first new post. Useful for event threads.'], - 'Scroll BG': [false, 'Auto-scroll background tabs.'], - 'Auto Update': [true, 'Automatically fetch new posts.'], - 'Optional Increase': [false, 'Increase the intervals between updates on threads without new posts.'] - }, - 'Interval': 5 - }, - customCooldown: 0, - customCooldownEnabled: true, - 'Thread Quotes': false, - 'Max Replies': 1000, - 'Autohiding Scrollbar': false, - 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', - passMessageClosed: false, - 'Prerequest Captcha': false, - 'PSAseen': [[]] - }; - - return Config; - -}).call(this); - -CSS = { - -boards: -"/*!\n\ - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome\n\ - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)\n\ - */\n\ -@font-face {\n\ - font-family: FontAwesome;\n\ - src: url('data:application/font-woff;base64,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') format('woff');\n\ - font-weight: 400;\n\ - font-style: normal;\n\ -}\n\ -.fa-glass:before {content: \"\\f000\";}\n\ -.fa-music:before {content: \"\\f001\";}\n\ -.fa-search:before {content: \"\\f002\";}\n\ -.fa-envelope-o:before {content: \"\\f003\";}\n\ -.fa-heart:before {content: \"\\f004\";}\n\ -.fa-star:before {content: \"\\f005\";}\n\ -.fa-star-o:before {content: \"\\f006\";}\n\ -.fa-user:before {content: \"\\f007\";}\n\ -.fa-film:before {content: \"\\f008\";}\n\ -.fa-th-large:before {content: \"\\f009\";}\n\ -.fa-th:before {content: \"\\f00a\";}\n\ -.fa-th-list:before {content: \"\\f00b\";}\n\ -.fa-check:before {content: \"\\f00c\";}\n\ -.fa-remove:before, .fa-close:before, .fa-times:before {content: \"\\f00d\";}\n\ -.fa-search-plus:before {content: \"\\f00e\";}\n\ -.fa-search-minus:before {content: \"\\f010\";}\n\ -.fa-power-off:before {content: \"\\f011\";}\n\ -.fa-signal:before {content: \"\\f012\";}\n\ -.fa-gear:before, .fa-cog:before {content: \"\\f013\";}\n\ -.fa-trash-o:before {content: \"\\f014\";}\n\ -.fa-home:before {content: \"\\f015\";}\n\ -.fa-file-o:before {content: \"\\f016\";}\n\ -.fa-clock-o:before {content: \"\\f017\";}\n\ -.fa-road:before {content: \"\\f018\";}\n\ -.fa-download:before {content: \"\\f019\";}\n\ -.fa-arrow-circle-o-down:before {content: \"\\f01a\";}\n\ -.fa-arrow-circle-o-up:before {content: \"\\f01b\";}\n\ -.fa-inbox:before {content: \"\\f01c\";}\n\ -.fa-play-circle-o:before {content: \"\\f01d\";}\n\ -.fa-rotate-right:before, .fa-repeat:before {content: \"\\f01e\";}\n\ -.fa-refresh:before {content: \"\\f021\";}\n\ -.fa-list-alt:before {content: \"\\f022\";}\n\ -.fa-lock:before {content: \"\\f023\";}\n\ -.fa-flag:before {content: \"\\f024\";}\n\ -.fa-headphones:before {content: \"\\f025\";}\n\ -.fa-volume-off:before {content: \"\\f026\";}\n\ -.fa-volume-down:before {content: \"\\f027\";}\n\ -.fa-volume-up:before {content: \"\\f028\";}\n\ -.fa-qrcode:before {content: \"\\f029\";}\n\ -.fa-barcode:before {content: \"\\f02a\";}\n\ -.fa-tag:before {content: \"\\f02b\";}\n\ -.fa-tags:before {content: \"\\f02c\";}\n\ -.fa-book:before {content: \"\\f02d\";}\n\ -.fa-bookmark:before {content: \"\\f02e\";}\n\ -.fa-print:before {content: \"\\f02f\";}\n\ -.fa-camera:before {content: \"\\f030\";}\n\ -.fa-font:before {content: \"\\f031\";}\n\ -.fa-bold:before {content: \"\\f032\";}\n\ -.fa-italic:before {content: \"\\f033\";}\n\ -.fa-text-height:before {content: \"\\f034\";}\n\ -.fa-text-width:before {content: \"\\f035\";}\n\ -.fa-align-left:before {content: \"\\f036\";}\n\ -.fa-align-center:before {content: \"\\f037\";}\n\ -.fa-align-right:before {content: \"\\f038\";}\n\ -.fa-align-justify:before {content: \"\\f039\";}\n\ -.fa-list:before {content: \"\\f03a\";}\n\ -.fa-dedent:before, .fa-outdent:before {content: \"\\f03b\";}\n\ -.fa-indent:before {content: \"\\f03c\";}\n\ -.fa-video-camera:before {content: \"\\f03d\";}\n\ -.fa-photo:before, .fa-image:before, .fa-picture-o:before {content: \"\\f03e\";}\n\ -.fa-pencil:before {content: \"\\f040\";}\n\ -.fa-map-marker:before {content: \"\\f041\";}\n\ -.fa-adjust:before {content: \"\\f042\";}\n\ -.fa-tint:before {content: \"\\f043\";}\n\ -.fa-edit:before, .fa-pencil-square-o:before {content: \"\\f044\";}\n\ -.fa-share-square-o:before {content: \"\\f045\";}\n\ -.fa-check-square-o:before {content: \"\\f046\";}\n\ -.fa-arrows:before {content: \"\\f047\";}\n\ -.fa-step-backward:before {content: \"\\f048\";}\n\ -.fa-fast-backward:before {content: \"\\f049\";}\n\ -.fa-backward:before {content: \"\\f04a\";}\n\ -.fa-play:before {content: \"\\f04b\";}\n\ -.fa-pause:before {content: \"\\f04c\";}\n\ -.fa-stop:before {content: \"\\f04d\";}\n\ -.fa-forward:before {content: \"\\f04e\";}\n\ -.fa-fast-forward:before {content: \"\\f050\";}\n\ -.fa-step-forward:before {content: \"\\f051\";}\n\ -.fa-eject:before {content: \"\\f052\";}\n\ -.fa-chevron-left:before {content: \"\\f053\";}\n\ -.fa-chevron-right:before {content: \"\\f054\";}\n\ -.fa-plus-circle:before {content: \"\\f055\";}\n\ -.fa-minus-circle:before {content: \"\\f056\";}\n\ -.fa-times-circle:before {content: \"\\f057\";}\n\ -.fa-check-circle:before {content: \"\\f058\";}\n\ -.fa-question-circle:before {content: \"\\f059\";}\n\ -.fa-info-circle:before {content: \"\\f05a\";}\n\ -.fa-crosshairs:before {content: \"\\f05b\";}\n\ -.fa-times-circle-o:before {content: \"\\f05c\";}\n\ -.fa-check-circle-o:before {content: \"\\f05d\";}\n\ -.fa-ban:before {content: \"\\f05e\";}\n\ -.fa-arrow-left:before {content: \"\\f060\";}\n\ -.fa-arrow-right:before {content: \"\\f061\";}\n\ -.fa-arrow-up:before {content: \"\\f062\";}\n\ -.fa-arrow-down:before {content: \"\\f063\";}\n\ -.fa-mail-forward:before, .fa-share:before {content: \"\\f064\";}\n\ -.fa-expand:before {content: \"\\f065\";}\n\ -.fa-compress:before {content: \"\\f066\";}\n\ -.fa-plus:before {content: \"\\f067\";}\n\ -.fa-minus:before {content: \"\\f068\";}\n\ -.fa-asterisk:before {content: \"\\f069\";}\n\ -.fa-exclamation-circle:before {content: \"\\f06a\";}\n\ -.fa-gift:before {content: \"\\f06b\";}\n\ -.fa-leaf:before {content: \"\\f06c\";}\n\ -.fa-fire:before {content: \"\\f06d\";}\n\ -.fa-eye:before {content: \"\\f06e\";}\n\ -.fa-eye-slash:before {content: \"\\f070\";}\n\ -.fa-warning:before, .fa-exclamation-triangle:before {content: \"\\f071\";}\n\ -.fa-plane:before {content: \"\\f072\";}\n\ -.fa-calendar:before {content: \"\\f073\";}\n\ -.fa-random:before {content: \"\\f074\";}\n\ -.fa-comment:before {content: \"\\f075\";}\n\ -.fa-magnet:before {content: \"\\f076\";}\n\ -.fa-chevron-up:before {content: \"\\f077\";}\n\ -.fa-chevron-down:before {content: \"\\f078\";}\n\ -.fa-retweet:before {content: \"\\f079\";}\n\ -.fa-shopping-cart:before {content: \"\\f07a\";}\n\ -.fa-folder:before {content: \"\\f07b\";}\n\ -.fa-folder-open:before {content: \"\\f07c\";}\n\ -.fa-arrows-v:before {content: \"\\f07d\";}\n\ -.fa-arrows-h:before {content: \"\\f07e\";}\n\ -.fa-bar-chart-o:before, .fa-bar-chart:before {content: \"\\f080\";}\n\ -.fa-twitter-square:before {content: \"\\f081\";}\n\ -.fa-facebook-square:before {content: \"\\f082\";}\n\ -.fa-camera-retro:before {content: \"\\f083\";}\n\ -.fa-key:before {content: \"\\f084\";}\n\ -.fa-gears:before, .fa-cogs:before {content: \"\\f085\";}\n\ -.fa-comments:before {content: \"\\f086\";}\n\ -.fa-thumbs-o-up:before {content: \"\\f087\";}\n\ -.fa-thumbs-o-down:before {content: \"\\f088\";}\n\ -.fa-star-half:before {content: \"\\f089\";}\n\ -.fa-heart-o:before {content: \"\\f08a\";}\n\ -.fa-sign-out:before {content: \"\\f08b\";}\n\ -.fa-linkedin-square:before {content: \"\\f08c\";}\n\ -.fa-thumb-tack:before {content: \"\\f08d\";}\n\ -.fa-external-link:before {content: \"\\f08e\";}\n\ -.fa-sign-in:before {content: \"\\f090\";}\n\ -.fa-trophy:before {content: \"\\f091\";}\n\ -.fa-github-square:before {content: \"\\f092\";}\n\ -.fa-upload:before {content: \"\\f093\";}\n\ -.fa-lemon-o:before {content: \"\\f094\";}\n\ -.fa-phone:before {content: \"\\f095\";}\n\ -.fa-square-o:before {content: \"\\f096\";}\n\ -.fa-bookmark-o:before {content: \"\\f097\";}\n\ -.fa-phone-square:before {content: \"\\f098\";}\n\ -.fa-twitter:before {content: \"\\f099\";}\n\ -.fa-facebook-f:before, .fa-facebook:before {content: \"\\f09a\";}\n\ -.fa-github:before {content: \"\\f09b\";}\n\ -.fa-unlock:before {content: \"\\f09c\";}\n\ -.fa-credit-card:before {content: \"\\f09d\";}\n\ -.fa-feed:before, .fa-rss:before {content: \"\\f09e\";}\n\ -.fa-hdd-o:before {content: \"\\f0a0\";}\n\ -.fa-bullhorn:before {content: \"\\f0a1\";}\n\ -.fa-bell:before {content: \"\\f0f3\";}\n\ -.fa-certificate:before {content: \"\\f0a3\";}\n\ -.fa-hand-o-right:before {content: \"\\f0a4\";}\n\ -.fa-hand-o-left:before {content: \"\\f0a5\";}\n\ -.fa-hand-o-up:before {content: \"\\f0a6\";}\n\ -.fa-hand-o-down:before {content: \"\\f0a7\";}\n\ -.fa-arrow-circle-left:before {content: \"\\f0a8\";}\n\ -.fa-arrow-circle-right:before {content: \"\\f0a9\";}\n\ -.fa-arrow-circle-up:before {content: \"\\f0aa\";}\n\ -.fa-arrow-circle-down:before {content: \"\\f0ab\";}\n\ -.fa-globe:before {content: \"\\f0ac\";}\n\ -.fa-wrench:before {content: \"\\f0ad\";}\n\ -.fa-tasks:before {content: \"\\f0ae\";}\n\ -.fa-filter:before {content: \"\\f0b0\";}\n\ -.fa-briefcase:before {content: \"\\f0b1\";}\n\ -.fa-arrows-alt:before {content: \"\\f0b2\";}\n\ -.fa-group:before, .fa-users:before {content: \"\\f0c0\";}\n\ -.fa-chain:before, .fa-link:before {content: \"\\f0c1\";}\n\ -.fa-cloud:before {content: \"\\f0c2\";}\n\ -.fa-flask:before {content: \"\\f0c3\";}\n\ -.fa-cut:before, .fa-scissors:before {content: \"\\f0c4\";}\n\ -.fa-copy:before, .fa-files-o:before {content: \"\\f0c5\";}\n\ -.fa-paperclip:before {content: \"\\f0c6\";}\n\ -.fa-save:before, .fa-floppy-o:before {content: \"\\f0c7\";}\n\ -.fa-square:before {content: \"\\f0c8\";}\n\ -.fa-navicon:before, .fa-reorder:before, .fa-bars:before {content: \"\\f0c9\";}\n\ -.fa-list-ul:before {content: \"\\f0ca\";}\n\ -.fa-list-ol:before {content: \"\\f0cb\";}\n\ -.fa-strikethrough:before {content: \"\\f0cc\";}\n\ -.fa-underline:before {content: \"\\f0cd\";}\n\ -.fa-table:before {content: \"\\f0ce\";}\n\ -.fa-magic:before {content: \"\\f0d0\";}\n\ -.fa-truck:before {content: \"\\f0d1\";}\n\ -.fa-pinterest:before {content: \"\\f0d2\";}\n\ -.fa-pinterest-square:before {content: \"\\f0d3\";}\n\ -.fa-google-plus-square:before {content: \"\\f0d4\";}\n\ -.fa-google-plus:before {content: \"\\f0d5\";}\n\ -.fa-money:before {content: \"\\f0d6\";}\n\ -.fa-caret-down:before {content: \"\\f0d7\";}\n\ -.fa-caret-up:before {content: \"\\f0d8\";}\n\ -.fa-caret-left:before {content: \"\\f0d9\";}\n\ -.fa-caret-right:before {content: \"\\f0da\";}\n\ -.fa-columns:before {content: \"\\f0db\";}\n\ -.fa-unsorted:before, .fa-sort:before {content: \"\\f0dc\";}\n\ -.fa-sort-down:before, .fa-sort-desc:before {content: \"\\f0dd\";}\n\ -.fa-sort-up:before, .fa-sort-asc:before {content: \"\\f0de\";}\n\ -.fa-envelope:before {content: \"\\f0e0\";}\n\ -.fa-linkedin:before {content: \"\\f0e1\";}\n\ -.fa-rotate-left:before, .fa-undo:before {content: \"\\f0e2\";}\n\ -.fa-legal:before, .fa-gavel:before {content: \"\\f0e3\";}\n\ -.fa-dashboard:before, .fa-tachometer:before {content: \"\\f0e4\";}\n\ -.fa-comment-o:before {content: \"\\f0e5\";}\n\ -.fa-comments-o:before {content: \"\\f0e6\";}\n\ -.fa-flash:before, .fa-bolt:before {content: \"\\f0e7\";}\n\ -.fa-sitemap:before {content: \"\\f0e8\";}\n\ -.fa-umbrella:before {content: \"\\f0e9\";}\n\ -.fa-paste:before, .fa-clipboard:before {content: \"\\f0ea\";}\n\ -.fa-lightbulb-o:before {content: \"\\f0eb\";}\n\ -.fa-exchange:before {content: \"\\f0ec\";}\n\ -.fa-cloud-download:before {content: \"\\f0ed\";}\n\ -.fa-cloud-upload:before {content: \"\\f0ee\";}\n\ -.fa-user-md:before {content: \"\\f0f0\";}\n\ -.fa-stethoscope:before {content: \"\\f0f1\";}\n\ -.fa-suitcase:before {content: \"\\f0f2\";}\n\ -.fa-bell-o:before {content: \"\\f0a2\";}\n\ -.fa-coffee:before {content: \"\\f0f4\";}\n\ -.fa-cutlery:before {content: \"\\f0f5\";}\n\ -.fa-file-text-o:before {content: \"\\f0f6\";}\n\ -.fa-building-o:before {content: \"\\f0f7\";}\n\ -.fa-hospital-o:before {content: \"\\f0f8\";}\n\ -.fa-ambulance:before {content: \"\\f0f9\";}\n\ -.fa-medkit:before {content: \"\\f0fa\";}\n\ -.fa-fighter-jet:before {content: \"\\f0fb\";}\n\ -.fa-beer:before {content: \"\\f0fc\";}\n\ -.fa-h-square:before {content: \"\\f0fd\";}\n\ -.fa-plus-square:before {content: \"\\f0fe\";}\n\ -.fa-angle-double-left:before {content: \"\\f100\";}\n\ -.fa-angle-double-right:before {content: \"\\f101\";}\n\ -.fa-angle-double-up:before {content: \"\\f102\";}\n\ -.fa-angle-double-down:before {content: \"\\f103\";}\n\ -.fa-angle-left:before {content: \"\\f104\";}\n\ -.fa-angle-right:before {content: \"\\f105\";}\n\ -.fa-angle-up:before {content: \"\\f106\";}\n\ -.fa-angle-down:before {content: \"\\f107\";}\n\ -.fa-desktop:before {content: \"\\f108\";}\n\ -.fa-laptop:before {content: \"\\f109\";}\n\ -.fa-tablet:before {content: \"\\f10a\";}\n\ -.fa-mobile-phone:before, .fa-mobile:before {content: \"\\f10b\";}\n\ -.fa-circle-o:before {content: \"\\f10c\";}\n\ -.fa-quote-left:before {content: \"\\f10d\";}\n\ -.fa-quote-right:before {content: \"\\f10e\";}\n\ -.fa-spinner:before {content: \"\\f110\";}\n\ -.fa-circle:before {content: \"\\f111\";}\n\ -.fa-mail-reply:before, .fa-reply:before {content: \"\\f112\";}\n\ -.fa-github-alt:before {content: \"\\f113\";}\n\ -.fa-folder-o:before {content: \"\\f114\";}\n\ -.fa-folder-open-o:before {content: \"\\f115\";}\n\ -.fa-smile-o:before {content: \"\\f118\";}\n\ -.fa-frown-o:before {content: \"\\f119\";}\n\ -.fa-meh-o:before {content: \"\\f11a\";}\n\ -.fa-gamepad:before {content: \"\\f11b\";}\n\ -.fa-keyboard-o:before {content: \"\\f11c\";}\n\ -.fa-flag-o:before {content: \"\\f11d\";}\n\ -.fa-flag-checkered:before {content: \"\\f11e\";}\n\ -.fa-terminal:before {content: \"\\f120\";}\n\ -.fa-code:before {content: \"\\f121\";}\n\ -.fa-mail-reply-all:before, .fa-reply-all:before {content: \"\\f122\";}\n\ -.fa-star-half-empty:before, .fa-star-half-full:before, .fa-star-half-o:before {content: \"\\f123\";}\n\ -.fa-location-arrow:before {content: \"\\f124\";}\n\ -.fa-crop:before {content: \"\\f125\";}\n\ -.fa-code-fork:before {content: \"\\f126\";}\n\ -.fa-unlink:before, .fa-chain-broken:before {content: \"\\f127\";}\n\ -.fa-question:before {content: \"\\f128\";}\n\ -.fa-info:before {content: \"\\f129\";}\n\ -.fa-exclamation:before {content: \"\\f12a\";}\n\ -.fa-superscript:before {content: \"\\f12b\";}\n\ -.fa-subscript:before {content: \"\\f12c\";}\n\ -.fa-eraser:before {content: \"\\f12d\";}\n\ -.fa-puzzle-piece:before {content: \"\\f12e\";}\n\ -.fa-microphone:before {content: \"\\f130\";}\n\ -.fa-microphone-slash:before {content: \"\\f131\";}\n\ -.fa-shield:before {content: \"\\f132\";}\n\ -.fa-calendar-o:before {content: \"\\f133\";}\n\ -.fa-fire-extinguisher:before {content: \"\\f134\";}\n\ -.fa-rocket:before {content: \"\\f135\";}\n\ -.fa-maxcdn:before {content: \"\\f136\";}\n\ -.fa-chevron-circle-left:before {content: \"\\f137\";}\n\ -.fa-chevron-circle-right:before {content: \"\\f138\";}\n\ -.fa-chevron-circle-up:before {content: \"\\f139\";}\n\ -.fa-chevron-circle-down:before {content: \"\\f13a\";}\n\ -.fa-html5:before {content: \"\\f13b\";}\n\ -.fa-css3:before {content: \"\\f13c\";}\n\ -.fa-anchor:before {content: \"\\f13d\";}\n\ -.fa-unlock-alt:before {content: \"\\f13e\";}\n\ -.fa-bullseye:before {content: \"\\f140\";}\n\ -.fa-ellipsis-h:before {content: \"\\f141\";}\n\ -.fa-ellipsis-v:before {content: \"\\f142\";}\n\ -.fa-rss-square:before {content: \"\\f143\";}\n\ -.fa-play-circle:before {content: \"\\f144\";}\n\ -.fa-ticket:before {content: \"\\f145\";}\n\ -.fa-minus-square:before {content: \"\\f146\";}\n\ -.fa-minus-square-o:before {content: \"\\f147\";}\n\ -.fa-level-up:before {content: \"\\f148\";}\n\ -.fa-level-down:before {content: \"\\f149\";}\n\ -.fa-check-square:before {content: \"\\f14a\";}\n\ -.fa-pencil-square:before {content: \"\\f14b\";}\n\ -.fa-external-link-square:before {content: \"\\f14c\";}\n\ -.fa-share-square:before {content: \"\\f14d\";}\n\ -.fa-compass:before {content: \"\\f14e\";}\n\ -.fa-toggle-down:before, .fa-caret-square-o-down:before {content: \"\\f150\";}\n\ -.fa-toggle-up:before, .fa-caret-square-o-up:before {content: \"\\f151\";}\n\ -.fa-toggle-right:before, .fa-caret-square-o-right:before {content: \"\\f152\";}\n\ -.fa-euro:before, .fa-eur:before {content: \"\\f153\";}\n\ -.fa-gbp:before {content: \"\\f154\";}\n\ -.fa-dollar:before, .fa-usd:before {content: \"\\f155\";}\n\ -.fa-rupee:before, .fa-inr:before {content: \"\\f156\";}\n\ -.fa-cny:before, .fa-rmb:before, .fa-yen:before, .fa-jpy:before {content: \"\\f157\";}\n\ -.fa-ruble:before, .fa-rouble:before, .fa-rub:before {content: \"\\f158\";}\n\ -.fa-won:before, .fa-krw:before {content: \"\\f159\";}\n\ -.fa-bitcoin:before, .fa-btc:before {content: \"\\f15a\";}\n\ -.fa-file:before {content: \"\\f15b\";}\n\ -.fa-file-text:before {content: \"\\f15c\";}\n\ -.fa-sort-alpha-asc:before {content: \"\\f15d\";}\n\ -.fa-sort-alpha-desc:before {content: \"\\f15e\";}\n\ -.fa-sort-amount-asc:before {content: \"\\f160\";}\n\ -.fa-sort-amount-desc:before {content: \"\\f161\";}\n\ -.fa-sort-numeric-asc:before {content: \"\\f162\";}\n\ -.fa-sort-numeric-desc:before {content: \"\\f163\";}\n\ -.fa-thumbs-up:before {content: \"\\f164\";}\n\ -.fa-thumbs-down:before {content: \"\\f165\";}\n\ -.fa-youtube-square:before {content: \"\\f166\";}\n\ -.fa-youtube:before {content: \"\\f167\";}\n\ -.fa-xing:before {content: \"\\f168\";}\n\ -.fa-xing-square:before {content: \"\\f169\";}\n\ -.fa-youtube-play:before {content: \"\\f16a\";}\n\ -.fa-dropbox:before {content: \"\\f16b\";}\n\ -.fa-stack-overflow:before {content: \"\\f16c\";}\n\ -.fa-instagram:before {content: \"\\f16d\";}\n\ -.fa-flickr:before {content: \"\\f16e\";}\n\ -.fa-adn:before {content: \"\\f170\";}\n\ -.fa-bitbucket:before {content: \"\\f171\";}\n\ -.fa-bitbucket-square:before {content: \"\\f172\";}\n\ -.fa-tumblr:before {content: \"\\f173\";}\n\ -.fa-tumblr-square:before {content: \"\\f174\";}\n\ -.fa-long-arrow-down:before {content: \"\\f175\";}\n\ -.fa-long-arrow-up:before {content: \"\\f176\";}\n\ -.fa-long-arrow-left:before {content: \"\\f177\";}\n\ -.fa-long-arrow-right:before {content: \"\\f178\";}\n\ -.fa-apple:before {content: \"\\f179\";}\n\ -.fa-windows:before {content: \"\\f17a\";}\n\ -.fa-android:before {content: \"\\f17b\";}\n\ -.fa-linux:before {content: \"\\f17c\";}\n\ -.fa-dribbble:before {content: \"\\f17d\";}\n\ -.fa-skype:before {content: \"\\f17e\";}\n\ -.fa-foursquare:before {content: \"\\f180\";}\n\ -.fa-trello:before {content: \"\\f181\";}\n\ -.fa-female:before {content: \"\\f182\";}\n\ -.fa-male:before {content: \"\\f183\";}\n\ -.fa-gittip:before, .fa-gratipay:before {content: \"\\f184\";}\n\ -.fa-sun-o:before {content: \"\\f185\";}\n\ -.fa-moon-o:before {content: \"\\f186\";}\n\ -.fa-archive:before {content: \"\\f187\";}\n\ -.fa-bug:before {content: \"\\f188\";}\n\ -.fa-vk:before {content: \"\\f189\";}\n\ -.fa-weibo:before {content: \"\\f18a\";}\n\ -.fa-renren:before {content: \"\\f18b\";}\n\ -.fa-pagelines:before {content: \"\\f18c\";}\n\ -.fa-stack-exchange:before {content: \"\\f18d\";}\n\ -.fa-arrow-circle-o-right:before {content: \"\\f18e\";}\n\ -.fa-arrow-circle-o-left:before {content: \"\\f190\";}\n\ -.fa-toggle-left:before, .fa-caret-square-o-left:before {content: \"\\f191\";}\n\ -.fa-dot-circle-o:before {content: \"\\f192\";}\n\ -.fa-wheelchair:before {content: \"\\f193\";}\n\ -.fa-vimeo-square:before {content: \"\\f194\";}\n\ -.fa-turkish-lira:before, .fa-try:before {content: \"\\f195\";}\n\ -.fa-plus-square-o:before {content: \"\\f196\";}\n\ -.fa-space-shuttle:before {content: \"\\f197\";}\n\ -.fa-slack:before {content: \"\\f198\";}\n\ -.fa-envelope-square:before {content: \"\\f199\";}\n\ -.fa-wordpress:before {content: \"\\f19a\";}\n\ -.fa-openid:before {content: \"\\f19b\";}\n\ -.fa-institution:before, .fa-bank:before, .fa-university:before {content: \"\\f19c\";}\n\ -.fa-mortar-board:before, .fa-graduation-cap:before {content: \"\\f19d\";}\n\ -.fa-yahoo:before {content: \"\\f19e\";}\n\ -.fa-google:before {content: \"\\f1a0\";}\n\ -.fa-reddit:before {content: \"\\f1a1\";}\n\ -.fa-reddit-square:before {content: \"\\f1a2\";}\n\ -.fa-stumbleupon-circle:before {content: \"\\f1a3\";}\n\ -.fa-stumbleupon:before {content: \"\\f1a4\";}\n\ -.fa-delicious:before {content: \"\\f1a5\";}\n\ -.fa-digg:before {content: \"\\f1a6\";}\n\ -.fa-pied-piper-pp:before {content: \"\\f1a7\";}\n\ -.fa-pied-piper-alt:before {content: \"\\f1a8\";}\n\ -.fa-drupal:before {content: \"\\f1a9\";}\n\ -.fa-joomla:before {content: \"\\f1aa\";}\n\ -.fa-language:before {content: \"\\f1ab\";}\n\ -.fa-fax:before {content: \"\\f1ac\";}\n\ -.fa-building:before {content: \"\\f1ad\";}\n\ -.fa-child:before {content: \"\\f1ae\";}\n\ -.fa-paw:before {content: \"\\f1b0\";}\n\ -.fa-spoon:before {content: \"\\f1b1\";}\n\ -.fa-cube:before {content: \"\\f1b2\";}\n\ -.fa-cubes:before {content: \"\\f1b3\";}\n\ -.fa-behance:before {content: \"\\f1b4\";}\n\ -.fa-behance-square:before {content: \"\\f1b5\";}\n\ -.fa-steam:before {content: \"\\f1b6\";}\n\ -.fa-steam-square:before {content: \"\\f1b7\";}\n\ -.fa-recycle:before {content: \"\\f1b8\";}\n\ -.fa-automobile:before, .fa-car:before {content: \"\\f1b9\";}\n\ -.fa-cab:before, .fa-taxi:before {content: \"\\f1ba\";}\n\ -.fa-tree:before {content: \"\\f1bb\";}\n\ -.fa-spotify:before {content: \"\\f1bc\";}\n\ -.fa-deviantart:before {content: \"\\f1bd\";}\n\ -.fa-soundcloud:before {content: \"\\f1be\";}\n\ -.fa-database:before {content: \"\\f1c0\";}\n\ -.fa-file-pdf-o:before {content: \"\\f1c1\";}\n\ -.fa-file-word-o:before {content: \"\\f1c2\";}\n\ -.fa-file-excel-o:before {content: \"\\f1c3\";}\n\ -.fa-file-powerpoint-o:before {content: \"\\f1c4\";}\n\ -.fa-file-photo-o:before, .fa-file-picture-o:before, .fa-file-image-o:before {content: \"\\f1c5\";}\n\ -.fa-file-zip-o:before, .fa-file-archive-o:before {content: \"\\f1c6\";}\n\ -.fa-file-sound-o:before, .fa-file-audio-o:before {content: \"\\f1c7\";}\n\ -.fa-file-movie-o:before, .fa-file-video-o:before {content: \"\\f1c8\";}\n\ -.fa-file-code-o:before {content: \"\\f1c9\";}\n\ -.fa-vine:before {content: \"\\f1ca\";}\n\ -.fa-codepen:before {content: \"\\f1cb\";}\n\ -.fa-jsfiddle:before {content: \"\\f1cc\";}\n\ -.fa-life-bouy:before, .fa-life-buoy:before, .fa-life-saver:before, .fa-support:before, .fa-life-ring:before {content: \"\\f1cd\";}\n\ -.fa-circle-o-notch:before {content: \"\\f1ce\";}\n\ -.fa-ra:before, .fa-resistance:before, .fa-rebel:before {content: \"\\f1d0\";}\n\ -.fa-ge:before, .fa-empire:before {content: \"\\f1d1\";}\n\ -.fa-git-square:before {content: \"\\f1d2\";}\n\ -.fa-git:before {content: \"\\f1d3\";}\n\ -.fa-y-combinator-square:before, .fa-yc-square:before, .fa-hacker-news:before {content: \"\\f1d4\";}\n\ -.fa-tencent-weibo:before {content: \"\\f1d5\";}\n\ -.fa-qq:before {content: \"\\f1d6\";}\n\ -.fa-wechat:before, .fa-weixin:before {content: \"\\f1d7\";}\n\ -.fa-send:before, .fa-paper-plane:before {content: \"\\f1d8\";}\n\ -.fa-send-o:before, .fa-paper-plane-o:before {content: \"\\f1d9\";}\n\ -.fa-history:before {content: \"\\f1da\";}\n\ -.fa-circle-thin:before {content: \"\\f1db\";}\n\ -.fa-header:before {content: \"\\f1dc\";}\n\ -.fa-paragraph:before {content: \"\\f1dd\";}\n\ -.fa-sliders:before {content: \"\\f1de\";}\n\ -.fa-share-alt:before {content: \"\\f1e0\";}\n\ -.fa-share-alt-square:before {content: \"\\f1e1\";}\n\ -.fa-bomb:before {content: \"\\f1e2\";}\n\ -.fa-soccer-ball-o:before, .fa-futbol-o:before {content: \"\\f1e3\";}\n\ -.fa-tty:before {content: \"\\f1e4\";}\n\ -.fa-binoculars:before {content: \"\\f1e5\";}\n\ -.fa-plug:before {content: \"\\f1e6\";}\n\ -.fa-slideshare:before {content: \"\\f1e7\";}\n\ -.fa-twitch:before {content: \"\\f1e8\";}\n\ -.fa-yelp:before {content: \"\\f1e9\";}\n\ -.fa-newspaper-o:before {content: \"\\f1ea\";}\n\ -.fa-wifi:before {content: \"\\f1eb\";}\n\ -.fa-calculator:before {content: \"\\f1ec\";}\n\ -.fa-paypal:before {content: \"\\f1ed\";}\n\ -.fa-google-wallet:before {content: \"\\f1ee\";}\n\ -.fa-cc-visa:before {content: \"\\f1f0\";}\n\ -.fa-cc-mastercard:before {content: \"\\f1f1\";}\n\ -.fa-cc-discover:before {content: \"\\f1f2\";}\n\ -.fa-cc-amex:before {content: \"\\f1f3\";}\n\ -.fa-cc-paypal:before {content: \"\\f1f4\";}\n\ -.fa-cc-stripe:before {content: \"\\f1f5\";}\n\ -.fa-bell-slash:before {content: \"\\f1f6\";}\n\ -.fa-bell-slash-o:before {content: \"\\f1f7\";}\n\ -.fa-trash:before {content: \"\\f1f8\";}\n\ -.fa-copyright:before {content: \"\\f1f9\";}\n\ -.fa-at:before {content: \"\\f1fa\";}\n\ -.fa-eyedropper:before {content: \"\\f1fb\";}\n\ -.fa-paint-brush:before {content: \"\\f1fc\";}\n\ -.fa-birthday-cake:before {content: \"\\f1fd\";}\n\ -.fa-area-chart:before {content: \"\\f1fe\";}\n\ -.fa-pie-chart:before {content: \"\\f200\";}\n\ -.fa-line-chart:before {content: \"\\f201\";}\n\ -.fa-lastfm:before {content: \"\\f202\";}\n\ -.fa-lastfm-square:before {content: \"\\f203\";}\n\ -.fa-toggle-off:before {content: \"\\f204\";}\n\ -.fa-toggle-on:before {content: \"\\f205\";}\n\ -.fa-bicycle:before {content: \"\\f206\";}\n\ -.fa-bus:before {content: \"\\f207\";}\n\ -.fa-ioxhost:before {content: \"\\f208\";}\n\ -.fa-angellist:before {content: \"\\f209\";}\n\ -.fa-cc:before {content: \"\\f20a\";}\n\ -.fa-shekel:before, .fa-sheqel:before, .fa-ils:before {content: \"\\f20b\";}\n\ -.fa-meanpath:before {content: \"\\f20c\";}\n\ -.fa-buysellads:before {content: \"\\f20d\";}\n\ -.fa-connectdevelop:before {content: \"\\f20e\";}\n\ -.fa-dashcube:before {content: \"\\f210\";}\n\ -.fa-forumbee:before {content: \"\\f211\";}\n\ -.fa-leanpub:before {content: \"\\f212\";}\n\ -.fa-sellsy:before {content: \"\\f213\";}\n\ -.fa-shirtsinbulk:before {content: \"\\f214\";}\n\ -.fa-simplybuilt:before {content: \"\\f215\";}\n\ -.fa-skyatlas:before {content: \"\\f216\";}\n\ -.fa-cart-plus:before {content: \"\\f217\";}\n\ -.fa-cart-arrow-down:before {content: \"\\f218\";}\n\ -.fa-diamond:before {content: \"\\f219\";}\n\ -.fa-ship:before {content: \"\\f21a\";}\n\ -.fa-user-secret:before {content: \"\\f21b\";}\n\ -.fa-motorcycle:before {content: \"\\f21c\";}\n\ -.fa-street-view:before {content: \"\\f21d\";}\n\ -.fa-heartbeat:before {content: \"\\f21e\";}\n\ -.fa-venus:before {content: \"\\f221\";}\n\ -.fa-mars:before {content: \"\\f222\";}\n\ -.fa-mercury:before {content: \"\\f223\";}\n\ -.fa-intersex:before, .fa-transgender:before {content: \"\\f224\";}\n\ -.fa-transgender-alt:before {content: \"\\f225\";}\n\ -.fa-venus-double:before {content: \"\\f226\";}\n\ -.fa-mars-double:before {content: \"\\f227\";}\n\ -.fa-venus-mars:before {content: \"\\f228\";}\n\ -.fa-mars-stroke:before {content: \"\\f229\";}\n\ -.fa-mars-stroke-v:before {content: \"\\f22a\";}\n\ -.fa-mars-stroke-h:before {content: \"\\f22b\";}\n\ -.fa-neuter:before {content: \"\\f22c\";}\n\ -.fa-genderless:before {content: \"\\f22d\";}\n\ -.fa-facebook-official:before {content: \"\\f230\";}\n\ -.fa-pinterest-p:before {content: \"\\f231\";}\n\ -.fa-whatsapp:before {content: \"\\f232\";}\n\ -.fa-server:before {content: \"\\f233\";}\n\ -.fa-user-plus:before {content: \"\\f234\";}\n\ -.fa-user-times:before {content: \"\\f235\";}\n\ -.fa-hotel:before, .fa-bed:before {content: \"\\f236\";}\n\ -.fa-viacoin:before {content: \"\\f237\";}\n\ -.fa-train:before {content: \"\\f238\";}\n\ -.fa-subway:before {content: \"\\f239\";}\n\ -.fa-medium:before {content: \"\\f23a\";}\n\ -.fa-yc:before, .fa-y-combinator:before {content: \"\\f23b\";}\n\ -.fa-optin-monster:before {content: \"\\f23c\";}\n\ -.fa-opencart:before {content: \"\\f23d\";}\n\ -.fa-expeditedssl:before {content: \"\\f23e\";}\n\ -.fa-battery-4:before, .fa-battery:before, .fa-battery-full:before {content: \"\\f240\";}\n\ -.fa-battery-3:before, .fa-battery-three-quarters:before {content: \"\\f241\";}\n\ -.fa-battery-2:before, .fa-battery-half:before {content: \"\\f242\";}\n\ -.fa-battery-1:before, .fa-battery-quarter:before {content: \"\\f243\";}\n\ -.fa-battery-0:before, .fa-battery-empty:before {content: \"\\f244\";}\n\ -.fa-mouse-pointer:before {content: \"\\f245\";}\n\ -.fa-i-cursor:before {content: \"\\f246\";}\n\ -.fa-object-group:before {content: \"\\f247\";}\n\ -.fa-object-ungroup:before {content: \"\\f248\";}\n\ -.fa-sticky-note:before {content: \"\\f249\";}\n\ -.fa-sticky-note-o:before {content: \"\\f24a\";}\n\ -.fa-cc-jcb:before {content: \"\\f24b\";}\n\ -.fa-cc-diners-club:before {content: \"\\f24c\";}\n\ -.fa-clone:before {content: \"\\f24d\";}\n\ -.fa-balance-scale:before {content: \"\\f24e\";}\n\ -.fa-hourglass-o:before {content: \"\\f250\";}\n\ -.fa-hourglass-1:before, .fa-hourglass-start:before {content: \"\\f251\";}\n\ -.fa-hourglass-2:before, .fa-hourglass-half:before {content: \"\\f252\";}\n\ -.fa-hourglass-3:before, .fa-hourglass-end:before {content: \"\\f253\";}\n\ -.fa-hourglass:before {content: \"\\f254\";}\n\ -.fa-hand-grab-o:before, .fa-hand-rock-o:before {content: \"\\f255\";}\n\ -.fa-hand-stop-o:before, .fa-hand-paper-o:before {content: \"\\f256\";}\n\ -.fa-hand-scissors-o:before {content: \"\\f257\";}\n\ -.fa-hand-lizard-o:before {content: \"\\f258\";}\n\ -.fa-hand-spock-o:before {content: \"\\f259\";}\n\ -.fa-hand-pointer-o:before {content: \"\\f25a\";}\n\ -.fa-hand-peace-o:before {content: \"\\f25b\";}\n\ -.fa-trademark:before {content: \"\\f25c\";}\n\ -.fa-registered:before {content: \"\\f25d\";}\n\ -.fa-creative-commons:before {content: \"\\f25e\";}\n\ -.fa-gg:before {content: \"\\f260\";}\n\ -.fa-gg-circle:before {content: \"\\f261\";}\n\ -.fa-tripadvisor:before {content: \"\\f262\";}\n\ -.fa-odnoklassniki:before {content: \"\\f263\";}\n\ -.fa-odnoklassniki-square:before {content: \"\\f264\";}\n\ -.fa-get-pocket:before {content: \"\\f265\";}\n\ -.fa-wikipedia-w:before {content: \"\\f266\";}\n\ -.fa-safari:before {content: \"\\f267\";}\n\ -.fa-chrome:before {content: \"\\f268\";}\n\ -.fa-firefox:before {content: \"\\f269\";}\n\ -.fa-opera:before {content: \"\\f26a\";}\n\ -.fa-internet-explorer:before {content: \"\\f26b\";}\n\ -.fa-tv:before, .fa-television:before {content: \"\\f26c\";}\n\ -.fa-contao:before {content: \"\\f26d\";}\n\ -.fa-500px:before {content: \"\\f26e\";}\n\ -.fa-amazon:before {content: \"\\f270\";}\n\ -.fa-calendar-plus-o:before {content: \"\\f271\";}\n\ -.fa-calendar-minus-o:before {content: \"\\f272\";}\n\ -.fa-calendar-times-o:before {content: \"\\f273\";}\n\ -.fa-calendar-check-o:before {content: \"\\f274\";}\n\ -.fa-industry:before {content: \"\\f275\";}\n\ -.fa-map-pin:before {content: \"\\f276\";}\n\ -.fa-map-signs:before {content: \"\\f277\";}\n\ -.fa-map-o:before {content: \"\\f278\";}\n\ -.fa-map:before {content: \"\\f279\";}\n\ -.fa-commenting:before {content: \"\\f27a\";}\n\ -.fa-commenting-o:before {content: \"\\f27b\";}\n\ -.fa-houzz:before {content: \"\\f27c\";}\n\ -.fa-vimeo:before {content: \"\\f27d\";}\n\ -.fa-black-tie:before {content: \"\\f27e\";}\n\ -.fa-fonticons:before {content: \"\\f280\";}\n\ -.fa-reddit-alien:before {content: \"\\f281\";}\n\ -.fa-edge:before {content: \"\\f282\";}\n\ -.fa-credit-card-alt:before {content: \"\\f283\";}\n\ -.fa-codiepie:before {content: \"\\f284\";}\n\ -.fa-modx:before {content: \"\\f285\";}\n\ -.fa-fort-awesome:before {content: \"\\f286\";}\n\ -.fa-usb:before {content: \"\\f287\";}\n\ -.fa-product-hunt:before {content: \"\\f288\";}\n\ -.fa-mixcloud:before {content: \"\\f289\";}\n\ -.fa-scribd:before {content: \"\\f28a\";}\n\ -.fa-pause-circle:before {content: \"\\f28b\";}\n\ -.fa-pause-circle-o:before {content: \"\\f28c\";}\n\ -.fa-stop-circle:before {content: \"\\f28d\";}\n\ -.fa-stop-circle-o:before {content: \"\\f28e\";}\n\ -.fa-shopping-bag:before {content: \"\\f290\";}\n\ -.fa-shopping-basket:before {content: \"\\f291\";}\n\ -.fa-hashtag:before {content: \"\\f292\";}\n\ -.fa-bluetooth:before {content: \"\\f293\";}\n\ -.fa-bluetooth-b:before {content: \"\\f294\";}\n\ -.fa-percent:before {content: \"\\f295\";}\n\ -.fa-gitlab:before {content: \"\\f296\";}\n\ -.fa-wpbeginner:before {content: \"\\f297\";}\n\ -.fa-wpforms:before {content: \"\\f298\";}\n\ -.fa-envira:before {content: \"\\f299\";}\n\ -.fa-universal-access:before {content: \"\\f29a\";}\n\ -.fa-wheelchair-alt:before {content: \"\\f29b\";}\n\ -.fa-question-circle-o:before {content: \"\\f29c\";}\n\ -.fa-blind:before {content: \"\\f29d\";}\n\ -.fa-audio-description:before {content: \"\\f29e\";}\n\ -.fa-volume-control-phone:before {content: \"\\f2a0\";}\n\ -.fa-braille:before {content: \"\\f2a1\";}\n\ -.fa-assistive-listening-systems:before {content: \"\\f2a2\";}\n\ -.fa-asl-interpreting:before, .fa-american-sign-language-interpreting:before {content: \"\\f2a3\";}\n\ -.fa-deafness:before, .fa-hard-of-hearing:before, .fa-deaf:before {content: \"\\f2a4\";}\n\ -.fa-glide:before {content: \"\\f2a5\";}\n\ -.fa-glide-g:before {content: \"\\f2a6\";}\n\ -.fa-signing:before, .fa-sign-language:before {content: \"\\f2a7\";}\n\ -.fa-low-vision:before {content: \"\\f2a8\";}\n\ -.fa-viadeo:before {content: \"\\f2a9\";}\n\ -.fa-viadeo-square:before {content: \"\\f2aa\";}\n\ -.fa-snapchat:before {content: \"\\f2ab\";}\n\ -.fa-snapchat-ghost:before {content: \"\\f2ac\";}\n\ -.fa-snapchat-square:before {content: \"\\f2ad\";}\n\ -.fa-pied-piper:before {content: \"\\f2ae\";}\n\ -.fa-first-order:before {content: \"\\f2b0\";}\n\ -.fa-yoast:before {content: \"\\f2b1\";}\n\ -.fa-themeisle:before {content: \"\\f2b2\";}\n\ -.fa-google-plus-circle:before, .fa-google-plus-official:before {content: \"\\f2b3\";}\n\ -.fa-fa:before, .fa-font-awesome:before {content: \"\\f2b4\";}\n\ -.fa-handshake-o:before {content: \"\\f2b5\";}\n\ -.fa-envelope-open:before {content: \"\\f2b6\";}\n\ -.fa-envelope-open-o:before {content: \"\\f2b7\";}\n\ -.fa-linode:before {content: \"\\f2b8\";}\n\ -.fa-address-book:before {content: \"\\f2b9\";}\n\ -.fa-address-book-o:before {content: \"\\f2ba\";}\n\ -.fa-vcard:before, .fa-address-card:before {content: \"\\f2bb\";}\n\ -.fa-vcard-o:before, .fa-address-card-o:before {content: \"\\f2bc\";}\n\ -.fa-user-circle:before {content: \"\\f2bd\";}\n\ -.fa-user-circle-o:before {content: \"\\f2be\";}\n\ -.fa-user-o:before {content: \"\\f2c0\";}\n\ -.fa-id-badge:before {content: \"\\f2c1\";}\n\ -.fa-drivers-license:before, .fa-id-card:before {content: \"\\f2c2\";}\n\ -.fa-drivers-license-o:before, .fa-id-card-o:before {content: \"\\f2c3\";}\n\ -.fa-quora:before {content: \"\\f2c4\";}\n\ -.fa-free-code-camp:before {content: \"\\f2c5\";}\n\ -.fa-telegram:before {content: \"\\f2c6\";}\n\ -.fa-thermometer-4:before, .fa-thermometer:before, .fa-thermometer-full:before {content: \"\\f2c7\";}\n\ -.fa-thermometer-3:before, .fa-thermometer-three-quarters:before {content: \"\\f2c8\";}\n\ -.fa-thermometer-2:before, .fa-thermometer-half:before {content: \"\\f2c9\";}\n\ -.fa-thermometer-1:before, .fa-thermometer-quarter:before {content: \"\\f2ca\";}\n\ -.fa-thermometer-0:before, .fa-thermometer-empty:before {content: \"\\f2cb\";}\n\ -.fa-shower:before {content: \"\\f2cc\";}\n\ -.fa-bathtub:before, .fa-s15:before, .fa-bath:before {content: \"\\f2cd\";}\n\ -.fa-podcast:before {content: \"\\f2ce\";}\n\ -.fa-window-maximize:before {content: \"\\f2d0\";}\n\ -.fa-window-minimize:before {content: \"\\f2d1\";}\n\ -.fa-window-restore:before {content: \"\\f2d2\";}\n\ -.fa-times-rectangle:before, .fa-window-close:before {content: \"\\f2d3\";}\n\ -.fa-times-rectangle-o:before, .fa-window-close-o:before {content: \"\\f2d4\";}\n\ -.fa-bandcamp:before {content: \"\\f2d5\";}\n\ -.fa-grav:before {content: \"\\f2d6\";}\n\ -.fa-etsy:before {content: \"\\f2d7\";}\n\ -.fa-imdb:before {content: \"\\f2d8\";}\n\ -.fa-ravelry:before {content: \"\\f2d9\";}\n\ -.fa-eercast:before {content: \"\\f2da\";}\n\ -.fa-microchip:before {content: \"\\f2db\";}\n\ -.fa-snowflake-o:before {content: \"\\f2dc\";}\n\ -.fa-superpowers:before {content: \"\\f2dd\";}\n\ -.fa-wpexplorer:before {content: \"\\f2de\";}\n\ -.fa-meetup:before {content: \"\\f2e0\";}\n\ -.fa::before {\n\ - font-family: FontAwesome;\n\ - font-weight: 400;\n\ - font-style: normal;\n\ - -webkit-font-smoothing: antialiased;\n\ - text-decoration: inherit;\n\ - speak: none;\n\ - display: inline-block;\n\ - font-size: 13px;\n\ - visibility: visible;\n\ -}\n\ -:root:not(.shortcut-icons) #shortcuts .fa::before {\n\ - display: none;\n\ -}\n\ -:root.shortcut-icons #shortcuts .fa::before {\n\ - font-size: 15px !important;\n\ - margin-top: -3px !important;\n\ - position: relative;\n\ - top: 1px;\n\ -}\n\ -:root.shortcut-icons #shortcuts .fa, .menu-button .fa {\n\ - font-size: 0;\n\ - visibility: hidden;\n\ -}\n\ -:root.shortcut-icons .shortcut.brackets-wrap::after,\n\ -:root.shortcut-icons .shortcut.brackets-wrap::before {\n\ - display: none;\n\ -}\n\ -:root.shortcut-icons #shortcuts a .fa,\n\ -.menu-button .fa,\n\ -.hide-reply-button .fa,\n\ -.hide-thread-button .fa {\n\ - display: inline;\n\ -}\n\ -.fa-spin::before {\n\ - -webkit-animation:spin 2s infinite linear;\n\ - -moz-animation:spin 2s infinite linear;\n\ - -o-animation:spin 2s infinite linear;\n\ - animation:spin 2s infinite linear;\n\ -}\n\ -@-moz-keyframes spin {\n\ - 0% {-moz-transform:rotate(0deg);}\n\ - 100% {-moz-transform:rotate(359deg);}\n\ -}\n\ -@-webkit-keyframes spin {\n\ - 0% {-webkit-transform:rotate(0deg);}\n\ - 100% {-webkit-transform:rotate(359deg);}\n\ -}\n\ -@keyframes spin {\n\ - 0% {transform:rotate(0deg);}\n\ - 100% {transform:rotate(359deg);}\n\ -}\n\ -/* 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\ -}\n\ -label {\n\ - cursor: pointer;\n\ -}\n\ -a[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\ -}\n\ -body.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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Anti-autoplay */\n\ -audio.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\ -/* 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\ -/* 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\ -/* 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\ -}\n\ -div[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\ -/* 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\ -/* 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\ -/* Copy Text Link's textarea element */\n\ -textarea.copy-text-element {\n\ - height: 0;\n\ - width: 0;\n\ - position: absolute;\n\ - top: -10000px;\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\ -/* 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\ -/* 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\ -/* 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,\");\n\ -}\n\ -.watch-thread-link.watched {\n\ - opacity: 1;\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\ -/* 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\ -/* 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\ -/* File */\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 {\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 */\n\ -input[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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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),\n\ -body: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\ -}\n\ -input.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\ -/* 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\ -/* 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\ -}\n\ -input#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\ -/* 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,\n\ -input[type=\"checkbox\"]:focus ~ .checkbox-letter,\n\ -input[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\ -/* 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\ -/* 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\ -}\n\ -a: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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -: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\ -/* 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\ -/* PostJumper */\n\ -.postJumper > .prev,\n\ -.postJumper > .next {\n\ - font-size: 120%;\n\ -}\n\ -/* PSA */\n\ -.fcx-announcement {\n\ - text-align: center;\n\ -}\n\ -.fcx-announcement a {\n\ - text-decoration: underline;\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.yotsuba .indicator {\n\ - color: #F0E0D6;\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\ -/* 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\ -/* Unread */\n\ -:root.yotsuba .unread-mark-read {\n\ - background-color: rgba(240,224,214,0.5);\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\ -/* Watcher Favicon */\n\ -:root.yotsuba .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.yotsuba-b .indicator {\n\ - color: #D6DAF0;\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\ -/* 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\ -/* Unread */\n\ -:root.yotsuba-b .unread-mark-read {\n\ - background-color: rgba(214,218,240,0.5);\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\ -/* Watcher Favicon */\n\ -:root.yotsuba-b .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.futaba .indicator {\n\ - color: #F0E0D6;\n\ -}\n\ -/* Anonymize */\n\ -:root.futaba.anonymize $site$info$name::before {\n\ - font-size: 12pt;\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\ -/* 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\ -/* Unread */\n\ -:root.futaba .unread-mark-read {\n\ - background-color: rgba(240,224,214,0.5);\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\ -/* Watcher Favicon */\n\ -:root.futaba .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.burichan .indicator {\n\ - color: #D6DAF0;\n\ -}\n\ -/* Anonymize */\n\ -:root.burichan.anonymize $site$info$name::before {\n\ - font-size: 12pt;\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\ -/* 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\ -/* Unread */\n\ -:root.burichan .unread-mark-read {\n\ - background-color: rgba(214,218,240,0.5);\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\ -/* Watcher Favicon */\n\ -:root.burichan .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\n\ -}\n\ -/* General */\n\ -:root.tomorrow .dialog {\n\ - background-color: #282A2E;\n\ - border-color: #111;\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.tomorrow .indicator {\n\ - color: #282A2E;\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Watcher Favicon */\n\ -:root.tomorrow .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.photon .indicator {\n\ - color: #DDD;\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\ -/* 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\ -/* Unread */\n\ -:root.photon .unread-mark-read {\n\ - background-color: rgba(221,221,221,0.5);\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\ -/* Watcher Favicon */\n\ -:root.photon .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* 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\ -/* Fappe and Werk Tyme */\n\ -:root.spooky .indicator {\n\ - color: #171526;\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\ -/* 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\ -: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\ -/* 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\ -/* 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\ -/* 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\ -/* Watcher Favicon */\n\ -:root.spooky .watch-thread-link\n\ -{\n\ - background-image: url(\"data:image/svg+xml,\");\n\ -}\n\ -/* Link Title Favicons */\n\ -.linkify.audio::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.bitchute::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAadQTFRFAAAAwzw8xDs7cY6O0iws0ysrtF9f0Sws1CwsyzU1zTIy1igoyzQ01icnY7i4t0hI0S4u0ysr1Soq1ikp1ikp1Soq0ysr0S4uu0VFzjEx1Csr1ygo2Ccn2Ccn1ygo1CoqzjExzjAw1Skp2Ccn2Ccn1ikp0TAwxzY21Soq1SoqyzQ00iws1ygo1ygo0yws1Soq1Skp1igo1igo1igo1igo1igo1igo1Coq1Soq0C0t1ygo1ygo0S4unV5e1Csr1ygo1ygo1CsruUdHxzg41Skp1ygo1CsryTU10C4u1igo1ycn1ygo0i0txjo60S0t1ikp1ygo1ikp1Cws1Coq1Coq0yws0S0tyzQ00iws1Soq0ysr0i0txDs72Ccn2CUl2CYm2CQk3EFB2S8v2zw82jY24FZW3D0931FR3EBA3UND8LS04FVV7qys4V9f4WBg+erq766u9t7e7qqq2Ckp54KC9+Pj6pSU+Ojo5XNz9NHR6YqK8bu765ub5G5u9M3N6ImJ88vL5XV165eX3UVF6pWV3UhI2Soq2jU12Coq2jQ02Cgo2Sws////FaxLuAAAAF10Uk5TAAAAAAAAAAAAAAAAAAAAASJnoLy9oWolAhBz1vr72XgTGKf8/a4cCpuiDVvz9mS6xOvy9vzg6aGsPOToRAFv9fh2Awm07XgIMd765UEDOsfemVhhY00nBommbCkEI8horgAAAL5JREFUKBUFwbFKA0EUQNF7387sMq4EmzRpLSSdIBYKFv6Af2prnSYkRT4gWFgkCBJQ0EIFdcZzBCeqqh4qdk7VW2ChPusw02sAYKU7z7wEAAA2piQKFbrWSHazc1J0XWs5pdxPDykcVX+7Y9UxUsSo+s7PibqPFBRV/C5qi4i/UkrJrc7L47Bt4ZWnUaMCAE9GSrtKBQD2fR+bnAEAeOn7dUTOwApe35bDsPz0zsniQlV98IN0tJ3f6P0XAMA/kxou7OXCdnoAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.clyp::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAwUExURTSY22ey5E2l4KbS75rM7Y3F64C/6f///8zl9nS45r/f9PL5/UGe3bPY8Vqr4v///wNjrzUAAAABYktHRA8YugDZAAAAB3RJTUUH4AINEi85AIH95AAAAE9JREFUCNdjYMAGGBWgDGYHCM2a3hkAZmi0dzSBaKaO9o5moCqmLiCjYzNQyw4QowIodQzI6E0AKcpo72gE6+Jyb1kAMehUA9RktgdYbQYAjGIVNGGXBJkAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.dailymotion::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAnUExURQBk3ff6/trp+kKO5wZt3xx54q7P9Ozz/IS17zOG5WKh653E8sbc9/GbbcoAAABZSURBVAjXY2BAASyhDhAGc9oECMOjyAAiESEEYrBYpLWBGcwHxcvBjDDxHelghpF0yDQwY3kVgweEUeEQDWbMEepqAjO8FMsLIeYsU8o+BrbCdWboTAe4AwALXxWGjW41FwAAAABJRU5ErkJggg==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.gfycat::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAjVBMVEWn3gCo3gSr3w2t4BSu4Bav4Ri35C+45DK45DO55DXA50rA50vB50zC6E/D6FTF6VjG6VvL62vN7G/P7XbQ7XfW74vY8JDa8ZTe8qDe8qLf86Pi9Kzj9K7k9LHp9sDp98Lq98Ps+Mr0++L5/O75/fD6/fH6/fL6/fP7/fT7/fb8/ff8/vj8/vn+/v7///91X4cfAAAAcklEQVR42o3M2xKBUACF4aVQckrIuRJK6H//x2sme4/MuPDfre9i6c/Cc3U5Dj87BuAxsXvGu6JvIIXEHRWwNHCHQNrCzkAFkbSBg4EM8i+Yw7PXBa3zRfuxVyf/Bis7nKwGKAcWxgC8prI5Sc315OlnDfzpDar2S9/oAAAAAElFTkSuQmCC') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.gist::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.image::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.installgentoo::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.liveleak::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.pastebin::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB1FBMVEUAAAAAAAAAAABWYWwAAABbY3BbYm5dZnFdZXJeZnMEBAQHCAhYYGpdZnFdZnBgaHIlJyomKCooKi09QkdESU5eZGtdYmhdYmleY2lrcXdqb3Rqb3Rqb3SSmJ+SlJeWmJutr7GtrrCWm6ChpKhbW1tmZmZvb290dHR3d3d4eHh5eXl6enp8fHx+gIJ/f3+CgoKDg4OEhISFhYWHh4eKioqKjI2Li4uMjIyOjo6Pj4+QkJCRkZGSkpKUlJSVl5mWlpaYmZqZm52ampqbm5ucnJydnZ2enp6fn5+hoaGioqKkpKSkpaalpaWmp6mmp6qnqauoqKioqquoqq2qqqqrrK2srKysra6srrCsrrGurq6vr6+wsLCxsbGysrKztLa0tLS1t7m2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr7AwMDAwsTBwcHExcfFxcXFxsnGxsbHx8fIyMjJycnMzMzNzc3Ozs7O0NLPz8/Q0NDR0dHR09XT09PV1dXV1dbV1tfV19rW1tbX19fX19jY2tzZ2dnZ2tva2tra3N3a3N7c3Nze3t7f39/f4OHg4ODi4uLl5+jm5ubs7Ozs7e3u7u7v7+/v8PDw8PDx8fHy8vLz8/P29vYSoLMZAAAAJHRSTlMABAUGCwsNHCAiLzMzMzZEYGJwgIuOnJycnqmqq9bc3+/w8fkZ0N/uAAAA/klEQVQoU2NgYGDl5YMDdgYGBmZZ3964CYFtIR3e9Q7K/AwMHI55KfaFmcHWMy3K3MwlGRg4wz0zdYpcorRbNbL0LaWAAp3ts2umV8wo6MupTauQBgqUG03VL7W3sfZSb1erAgm02M+yzYrVCXUy6zapAQlUx/dEdyX3J3ZHVUYVywAF8o2rDNN1Go2jzGLMokAC2QbuSc42mXmaOXop9iAtCXrJ5qXWjT59Abl2ESJAAX/tSIMMiyrrqQ3T6uS5gQK6kSqpqkUermGTexQFmYACflqR+hlWZSamzQpCLEDPsSmVVDT1TJw0JUhOAMRnYOARFRMTE5cQF+ZiBPIAII5B3EVG0b4AAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.peertube::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABIFBMVEUhHyAAAABzPBnxaA3CWBEnJSYbGRptbW16enpzc3PTayWhb04hHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyApIh+0UhMfHiBWMhvsZg7zaQ0hHyAhHyAXHCHzaQ3xaA3xaA3xaA3xaA0hHyAhHyDxaA3xaA3xaA3xaA3xaA3xaA0oJickIiMdGxwUEhPxaA3xaA3xaA1sbGxwcHB3d3eFhYXxaA3xaA3xaA1zc3Nzc3Nzc3Nzc3Nzc3PxaA3xaA3xaA1zc3Nzc3NtdHjxaA3xaA1yc3STcFnvaA/yaAxzc3N4c2/FbDFzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3MhHyDxaA1zc3MAAAAfljyVAAAAXHRSTlMAAAAAAAAAAAAAAAAZkjMBHOLXYArj8p0u2VsJ1XaGL/OhKyXc1WEN2gwk2/SjKgEYiS4B/tYFGosqAdleAxzj12ML9Z8s850rJWbYeYMs1F8Koiri1V0MGZY0AYbIBFIAAAABYktHRAH/Ai3eAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4wYXFBUVX81QWQAAAKxJREFUGNNVz9UWgkAQANDBtdbu7lZsxe7ubpH//wxBPKDzNvdMAmi0Oj0QQgAYjCazBX7BStvsDqHoAzTtdLklf+Dx+vwICRAIhsKRaCyOvpAwJ6Up8pXOZHOIAFm+UCzJEQuvMhWrIFBUa/WGkodmq40Ad7q9/kDFwnA05lpYYCbT2ZykFvxQDhhmuVpvcvxaHra7vfp72KflcMSYEOB0vlyx+By+3R9PMSfe+P0enM1454kAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDYtMjRUMDM6MjE6MjEtMDc6MDDse6MAAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTA2LTI0VDAzOjIxOjIxLTA3OjAwnSYbvAAAAABJRU5ErkJggg==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.soundcloud::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABsklEQVQ4y5WTy2pUQRCGv2rbzDjJeAlIBmOyipGIIJqFEBDElwh4yULGeRFXPoEIBl/AvQ/gC2RnxCAoxijiwks852S6+3dxzslcHJCpTXVX11/Xv0097gLPgVNMJxnQNfX4zsqleWbnpoMf/oa9d988MM9MC/rp+E0a+A0dsVobMNMCOO8B6McRoABJI+A6gJmN3D2A8jgEBCEkSEMBrcrsDAzDWWn3AjgKFaDMmgRqniGFgsaDp1jrLOngDf1XT1D+A1dFc4MKAkkiCVKjjVu7g9+4Rzx4i1u6hjXbuMWr0O5QPNvCu7IaCZwEKQukLGDrm5x8uI0tr6MkiGlkiv7yLfzN+6S5i6QsIMABkEfcxhbWWYMkVAOjxvYAjc3HNHrbKI9VBQBFwF25XQKSBjqIf1YBuAurEMrczgDygD6/x2LCpFLXLUyQ+PoldphhBhYfIX09XU1+Flaukz7uYqs3SHs7cG4BmTsmkBUF9mmXEwa28BNLPaQPLepuNcbGSWQquQC2/Kdcox1FUGkcB0ykck1nA2+wTzMs8stGnP4rbWGw74EuS/GFQWfK7/wF6P4F7fzIAYkdmdEAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.streamable::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.twitchtv::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAYUExURf///2RBpWRBpWRBpWRBpWRBpWRBpf///+zQyUYAAAAGdFJOUwFdZX0lTzs4r5oAAAABYktHRAcWYYjrAAAAB3RJTUUH4AINEi42iSXRNAAAAD1JREFUCNdjYEiDAAZGGIMtjQEEUBlMCWoEGci6mGEMsxQgIy0BiB3AjLS0FAYQIw0kwABipoI1AhkBQBIAFCIXxiHgq80AAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.twitter::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAEsUExURf///1Cf21Gg3FGi31Gh3VKj4FGh3lKj4VKk4lKl41Ol5FOn51Sp6VSo6FOn5lCf21Gg3FGh3VGi31Gi31Gh3lGg3FGg3FGg3FGg3FGh3lGg3FGi31Kk4lKj4FGh3lGi31Kk4lGh3lGg3FGh3lOm5FOm5VGi31Kj4VSo6FGi31Gh3VGg3FKj4FOn51Gi31So6FWr7VOl5FGi31On51Sq6lKk4lOo51Sp6VOm5FSq61Ws7VOn51Oo51Sq61Ol5FOm5FSq61Wr7VOo51On51Sr7FWs7VSp6lGg3FGh3VOm5FWr7VSp6lKj4VOm5FSo6FSr7FWs7VWs7VWr7VSq6lOo51Om5FOo51So6FOm5VOl5FSq61Ws7VSr7FSp6lSp6VWs7lWr7VKk4lSq6v///6E3MNsAAABVdFJOUwAAAAAAAAAAAAAAAAAAAB0Ii+3xnBVTJhfsMKb+qTEp9GwBF/7lLAbo0m4pLkUTdvk2Ev3+EZnOBo/3Z8ffCRzH/D0OqPxiLnvx3UI8m9n1++GwXQZNS29BAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+ACDRIwBwy67tEAAADKSURBVBjTY2BAB4xogIGRH8IQEBQSFhEVE2eQkJQC8ZmkQ8PCI2Rk5RjkIxUUlRgZlVWioqNjYlXVGNQ14iI1tbR14qLj4+MTdJkZ9PQNosJCE0OjgPz4KEMWBiPjhPiEmKQokIJ4E1MmBmazhHg4MGdlYmCzsLSC8ROsmRkZmFht4Eps7ViADmOzd4DyHZ2YmYACTOzOLmATXd04mIBOd/eQ9owFCXh5c7KB/MLi4+vnHxAYFBzCwcYEEmBi5uLm4eHl42RmAnsSAMZBLgZiFUQ5AAAAAElFTkSuQmCC') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.video::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAxgDGAP8nNqN7AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gMZBjQQLEEqGwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAA5SURBVDjLY2AYaMDIwMDwn1JD/lPCZhpwL+B1wf///ykzgBhDiAoDfIYQZQAjIyP5BuDTPJqQqAQAvW0ZAMk8+EEAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.vidlii::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.vimeo::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAYFBMVEUAAAAIdZUKh6sLlLkLmr4LmsAMp88NrdYVW3MZj7Acstkrt9s1e5E7vN5EfI9JvdtKwuBijp5kpbl30eiDt8aG1uqRr7qTyNehxM+k4PCy3enB3OTg6Ovv9PXw+fz////L9U5WAAAAAXRSTlMAQObYZgAAAIFJREFUeNplz90OwiAMBWAQpAoyxclkP3je/y0H2AQXz0WT8100rRD6kNI9/cRroemQL3hXhoujZYj4OHoAmBvYGcBISwbWBvfXCrytnIDUQMkbsBpagMA7zhtQdyTFQAmIG7IkYniiZuh3XGsPqoOZkMOJOpAcLqUzNFGGu/57fwc1hgtp0mVSyQAAAABJRU5ErkJggg==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.vine::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.vocaroo::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,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==') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -.linkify.youtube::before {\n\ - content: \"\";\n\ - background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAYAAABr5z2BAAABIklEQVQoz53LvUrDUBjG8bOoOammSf1IoBSvoCB4JeIqOHgBLt6AIMRBBQelWurQ2kERnMRBsBUcIp5FJSBI5oQsJVkkUHh8W0o5nhaFHvjBgef/Mq+Q46RJBMkI/vE+aOus956tnEswIZe1LV0QyJ5sE2GzgZfVMtRNIdiDpccEssdlB1mW4bvTwdvWJtRdErM7U+8S/FJykCRJX5qm+KpVce8UMNLRLbulz4iSjTAMh6Iowsd5BeNadp3nUF0VlxAEwZBotXC0Usa4ll3meZdA1iguwvf9vpvDA2wvmKgYGtSud8suDB4TyGr2PF49D/vra9jRZ1BVdknMzgwuCGSnZEObwu6sBnVTCHZiaC7BhFx2PKdxUidiAH/4lLo9Mv0DELVs9qsOHXwAAAAASUVORK5CYII=') center left no-repeat!important;\n\ - padding-left: 18px;\n\ -}\n\ -/* 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\ -/* 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(css) { - var variables = { - site: g.SITE.selectors - }; - return css.replace(/\$[\w\$]+/g, function(name) { - var words = name.slice(1).split('$'); - var sel = variables; - for (var i = 0; i < words.length; i++) { - if (typeof sel !== 'object') return ':not(*)'; - sel = $.getOwn(sel, words[i]); - } - if (typeof sel !== 'string') return ':not(*)'; - return sel; - }); -} - -}; - -$ = (function() { - var $, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - $ = function(selector, root) { - if (root == null) { - root = d.body; - } - return root.querySelector(selector); - }; - - $.DAY = 24 * ($.HOUR = 60 * ($.MINUTE = 60 * ($.SECOND = 1000))); - - $.id = function(id) { - return d.getElementById(id); - }; - - $.ready = function(fc) { - var cb; - if (d.readyState !== 'loading') { - $.queueTask(fc); - return; - } - cb = function() { - $.off(d, 'DOMContentLoaded', cb); - return fc(); - }; - return $.on(d, 'DOMContentLoaded', cb); - }; - - $.formData = function(form) { - var fd, key, val; - if (form instanceof HTMLFormElement) { - return new FormData(form); - } - fd = new FormData(); - for (key in form) { - val = form[key]; - if (val) { - if (typeof val === 'object' && 'newName' in val) { - fd.append(key, val, val.newName); - } else { - fd.append(key, val); - } - } - } - return fd; - }; - - $.extend = function(object, properties) { - var key, val; - for (key in properties) { - val = properties[key]; - object[key] = val; - } - }; - - $.dict = function() { - return Object.create(null); - }; - - $.dict.clone = function(obj) { - var arr, i, j, key, map, ref, val; - if (typeof obj !== 'object' || obj === null) { - return obj; - } else if (obj instanceof Array) { - arr = []; - for (i = j = 0, ref = obj.length; j < ref; i = j += 1) { - arr.push($.dict.clone(obj[i])); - } - return arr; - } else { - map = Object.create(null); - for (key in obj) { - val = obj[key]; - map[key] = $.dict.clone(val); - } - return map; - } - }; - - $.dict.json = function(str) { - return $.dict.clone(JSON.parse(str)); - }; - - $.hasOwn = function(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); - }; - - $.getOwn = function(obj, key) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - return obj[key]; - } else { - return void 0; - } - }; - - $.ajax = (function() { - var pageXHR; - if (window.wrappedJSObject && !XMLHttpRequest.wrappedJSObject) { - pageXHR = XPCNativeWrapper(window.wrappedJSObject.XMLHttpRequest); - } else { - pageXHR = XMLHttpRequest; - } - return function(url, options) { - var err, form, headers, key, onloadend, onprogress, r, ref, responseType, timeout, type, value, withCredentials; - if (options == null) { - options = {}; - } - if (options.responseType == null) { - options.responseType = 'json'; - } - options.type || (options.type = options.form && 'post' || 'get'); - url = url.replace(/^((?:https?:)?\/\/(?:\w+\.)?(?:4chan|4channel|4cdn)\.org)\/adv\//, '$1//adv/'); - onloadend = options.onloadend, timeout = options.timeout, responseType = options.responseType, withCredentials = options.withCredentials, type = options.type, onprogress = options.onprogress, form = options.form, headers = options.headers; - r = new pageXHR(); - try { - r.open(type, url, true); - ref = headers || {}; - for (key in ref) { - value = ref[key]; - r.setRequestHeader(key, value); - } - $.extend(r, { - onloadend: onloadend, - timeout: timeout, - responseType: responseType, - withCredentials: withCredentials - }); - $.extend(r.upload, { - onprogress: onprogress - }); - $.on(r, 'error', function() { - if (!r.status) { - return c.warn("4chan X failed to load: " + url); - } - }); - r.send(form); - } catch (error) { - err = error; - if (err.result !== 0x805e0006) { - throw err; - } - r.onloadend = onloadend; - $.queueTask($.event, 'error', null, r); - $.queueTask($.event, 'loadend', null, r); - } - return r; - }; - })(); - - $.lastModified = $.dict(); - - $.whenModified = function(url, bucket, cb, options) { - var ajax, headers, params, r, ref, t, timeout, url0; - if (options == null) { - options = {}; - } - timeout = options.timeout, ajax = options.ajax; - params = []; - if ($.engine === 'blink') { - params.push("s=" + bucket); - } - if (url.split('/')[2] === 'a.4cdn.org') { - params.push("t=" + (Date.now())); - } - url0 = url; - if (params.length) { - url += '?' + params.join('&'); - } - headers = $.dict(); - if ((t = (ref = $.lastModified[bucket]) != null ? ref[url0] : void 0) != null) { - headers['If-Modified-Since'] = t; - } - r = (ajax || $.ajax)(url, { - onloadend: function() { - var base; - ((base = $.lastModified)[bucket] || (base[bucket] = $.dict()))[url0] = this.getResponseHeader('Last-Modified'); - return cb.call(this); - }, - timeout: timeout, - headers: headers - }); - return r; - }; - - (function() { - var reqs; - reqs = $.dict(); - $.cache = function(url, cb, options) { - var ajax, onloadend, req; - if (options == null) { - options = {}; - } - ajax = options.ajax; - if ((req = reqs[url])) { - if (req.callbacks) { - req.callbacks.push(cb); - } else { - $.queueTask(function() { - return cb.call(req, { - isCached: true - }); - }); - } - return req; - } - onloadend = function() { - var fn1, j, len, ref; - if (!this.status) { - delete reqs[url]; - } - ref = this.callbacks; - fn1 = (function(_this) { - return function(cb) { - return $.queueTask(function() { - return cb.call(_this, { - isCached: false - }); - }); - }; - })(this); - for (j = 0, len = ref.length; j < len; j++) { - cb = ref[j]; - fn1(cb); - } - return delete this.callbacks; - }; - req = (ajax || $.ajax)(url, { - onloadend: onloadend - }); - req.callbacks = [cb]; - return reqs[url] = req; - }; - return $.cleanCache = function(testf) { - var url; - for (url in reqs) { - if (testf(url)) { - delete reqs[url]; - } - } - }; - })(); - - $.cb = { - checked: function() { - if ($.hasOwn(Conf, this.name)) { - $.set(this.name, this.checked); - return Conf[this.name] = this.checked; - } - }, - value: function() { - if ($.hasOwn(Conf, this.name)) { - $.set(this.name, this.value.trim()); - return Conf[this.name] = this.value; - } - } - }; - - $.asap = function(test, cb) { - if (test()) { - return cb(); - } else { - return setTimeout($.asap, 25, test, cb); - } - }; - - $.onExists = function(root, selector, cb) { - var el, observer; - if (el = $(selector, root)) { - return cb(el); - } - observer = new MutationObserver(function() { - if (el = $(selector, root)) { - observer.disconnect(); - return cb(el); - } - }); - return observer.observe(root, { - childList: true, - subtree: true - }); - }; - - $.addStyle = function(css, id, test) { - var style; - if (test == null) { - test = 'head'; - } - style = $.el('style', { - textContent: css - }); - if (id != null) { - style.id = id; - } - $.onExists(doc, test, function() { - return $.add(d.head, style); - }); - return style; - }; - - $.addCSP = function(policy) { - var head, meta; - meta = $.el('meta', { - httpEquiv: 'Content-Security-Policy', - content: policy - }); - if (d.head) { - $.add(d.head, meta); - return $.rm(meta); - } else { - head = $.add(doc || d, $.el('head')); - $.add(head, meta); - return $.rm(head); - } - }; - - $.x = function(path, root) { - root || (root = d.body); - return d.evaluate(path, root, null, 8, null).singleNodeValue; - }; - - $.X = function(path, root) { - root || (root = d.body); - return d.evaluate(path, root, null, 7, null); - }; - - $.addClass = function() { - var className, classNames, el, j, len; - el = arguments[0], classNames = 2 <= arguments.length ? slice.call(arguments, 1) : []; - for (j = 0, len = classNames.length; j < len; j++) { - className = classNames[j]; - el.classList.add(className); - } - }; - - $.rmClass = function() { - var className, classNames, el, j, len; - el = arguments[0], classNames = 2 <= arguments.length ? slice.call(arguments, 1) : []; - for (j = 0, len = classNames.length; j < len; j++) { - className = classNames[j]; - el.classList.remove(className); - } - }; - - $.toggleClass = function(el, className) { - return el.classList.toggle(className); - }; - - $.hasClass = function(el, className) { - return indexOf.call(el.classList, className) >= 0; - }; - - $.rm = function(el) { - return el != null ? el.remove() : void 0; - }; - - $.rmAll = function(root) { - return root.textContent = null; - }; - - $.tn = function(s) { - return d.createTextNode(s); - }; - - $.frag = function() { - return d.createDocumentFragment(); - }; - - $.nodes = function(nodes) { - var frag, j, len, node; - if (!(nodes instanceof Array)) { - return nodes; - } - frag = $.frag(); - for (j = 0, len = nodes.length; j < len; j++) { - node = nodes[j]; - frag.appendChild(node); - } - return frag; - }; - - $.add = function(parent, el) { - return parent.appendChild($.nodes(el)); - }; - - $.prepend = function(parent, el) { - return parent.insertBefore($.nodes(el), parent.firstChild); - }; - - $.after = function(root, el) { - return root.parentNode.insertBefore($.nodes(el), root.nextSibling); - }; - - $.before = function(root, el) { - return root.parentNode.insertBefore($.nodes(el), root); - }; - - $.replace = function(root, el) { - return root.parentNode.replaceChild($.nodes(el), root); - }; - - $.el = function(tag, properties, properties2) { - var el; - el = d.createElement(tag); - if (properties) { - $.extend(el, properties); - } - if (properties2) { - $.extend(el, properties2); - } - return el; - }; - - $.on = function(el, events, handler) { - var event, j, len, ref; - ref = events.split(' '); - for (j = 0, len = ref.length; j < len; j++) { - event = ref[j]; - el.addEventListener(event, handler, false); - } - }; - - $.off = function(el, events, handler) { - var event, j, len, ref; - ref = events.split(' '); - for (j = 0, len = ref.length; j < len; j++) { - event = ref[j]; - el.removeEventListener(event, handler, false); - } - }; - - $.one = function(el, events, handler) { - var cb; - cb = function(e) { - $.off(el, events, cb); - return handler.call(this, e); - }; - return $.on(el, events, cb); - }; - - $.event = function(event, detail, root) { - if (root == null) { - root = d; - } - if ((detail != null) && typeof cloneInto === 'function') { - detail = cloneInto(detail, d.defaultView); - } - return root.dispatchEvent(new CustomEvent(event, { - bubbles: true, - cancelable: true, - detail: detail - })); - }; - - (function() { - var clone, err, ref, unsafeConstructors; - if (!(/PaleMoon\//.test(navigator.userAgent) && +(typeof GM_info !== "undefined" && GM_info !== null ? (ref = GM_info.version) != null ? ref.split('.')[0] : void 0 : void 0) >= 2 && typeof cloneInto === 'undefined')) { - return; - } - try { - return new CustomEvent('x', { - detail: {} - }); - } catch (error) { - err = error; - unsafeConstructors = { - Object: unsafeWindow.Object, - Array: unsafeWindow.Array - }; - clone = function(obj) { - var constructor, key, obj2, val; - if ((obj != null) && typeof obj === 'object' && (constructor = unsafeConstructors[obj.constructor.name])) { - obj2 = new constructor(); - for (key in obj) { - val = obj[key]; - obj2[key] = clone(val); - } - return obj2; - } else { - return obj; - } - }; - return $.event = function(event, detail, root) { - if (root == null) { - root = d; - } - return root.dispatchEvent(new CustomEvent(event, { - bubbles: true, - cancelable: true, - detail: clone(detail) - })); - }; - } - })(); - - $.modifiedClick = function(e) { - return e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0; - }; - - $.open = (typeof GM !== "undefined" && GM !== null ? GM.openInTab : void 0) != null ? GM.openInTab : typeof GM_openInTab !== "undefined" && GM_openInTab !== null ? GM_openInTab : function(url) { - return window.open(url, '_blank'); - }; - - $.debounce = function(wait, fn) { - var args, exec, lastCall, that, timeout; - lastCall = 0; - timeout = null; - that = null; - args = null; - exec = function() { - lastCall = Date.now(); - return fn.apply(that, args); - }; - return function() { - args = arguments; - that = this; - if (lastCall < Date.now() - wait) { - return exec(); - } - clearTimeout(timeout); - return timeout = setTimeout(exec, wait); - }; - }; - - $.queueTask = (function() { - var execTask, taskChannel, taskQueue; - taskQueue = []; - execTask = function() { - var args, func, task; - task = taskQueue.shift(); - func = task[0]; - args = Array.prototype.slice.call(task, 1); - return func.apply(func, args); - }; - if (window.MessageChannel) { - taskChannel = new MessageChannel(); - taskChannel.port1.onmessage = execTask; - return function() { - taskQueue.push(arguments); - return taskChannel.port2.postMessage(null); - }; - } else { - return function() { - taskQueue.push(arguments); - return setTimeout(execTask, 0); - }; - } - })(); - - $.global = function(fn, data) { - var script; - if (doc) { - script = $.el('script', { - textContent: "(" + fn + ").call(document.currentScript.dataset);" - }); - if (data) { - $.extend(script.dataset, data); - } - $.add(d.head || doc, script); - $.rm(script); - return script.dataset; - } else { - try { - fn.call(data); - } catch (error) {} - return data; - } - }; - - $.bytesToString = function(size) { - var unit; - unit = 0; - while (size >= 1024) { - size /= 1024; - unit++; - } - size = unit > 1 ? Math.round(size * 100) / 100 : Math.round(size); - return size + " " + ['B', 'KB', 'MB', 'GB'][unit]; - }; - - $.minmax = function(value, min, max) { - return (value < min ? min : value > max ? max : value); - }; - - $.hasAudio = function(video) { - return video.mozHasAudio || !!video.webkitAudioDecodedByteCount; - }; - - $.luma = function(rgb) { - return rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114; - }; - - $.unescape = function(text) { - if (text == null) { - return text; - } - return text.replace(/<[^>]*>/g, '').replace(/&(amp|#039|quot|lt|gt|#44);/g, function(c) { - return { - '&': '&', - ''': "'", - '"': '"', - '<': '<', - '>': '>', - ',': ',' - }[c]; - }); - }; - - $.isImage = function(url) { - return /\.(jpe?g|jfif|png|gif|bmp|webp|avif|jxl)$/i.test(url); - }; - - $.isVideo = function(url) { - return /\.(webm|mp4|ogv)$/i.test(url); - }; - - $.engine = (function() { - if (/Edge\//.test(navigator.userAgent)) { - return 'edge'; - } - if (/Chrome\//.test(navigator.userAgent)) { - return 'blink'; - } - if (/WebKit\//.test(navigator.userAgent)) { - return 'webkit'; - } - if (/Gecko\/|Goanna/.test(navigator.userAgent)) { - return 'gecko'; - } - })(); - - $.platform = 'userscript'; - - $.hasStorage = (function() { - try { - if (localStorage.getItem(g.NAMESPACE + 'hasStorage') === 'true') { - return true; - } - localStorage.setItem(g.NAMESPACE + 'hasStorage', 'true'); - return localStorage.getItem(g.NAMESPACE + 'hasStorage') === 'true'; - } catch (error) { - return false; - } - })(); - - $.item = function(key, val) { - var item; - item = $.dict(); - item[key] = val; - return item; - }; - - $.oneItemSugar = function(fn) { - return function(key, val, cb) { - if (typeof key === 'string') { - return fn($.item(key, val), cb); - } else { - return fn(key, val); - } - }; - }; - - $.syncing = $.dict(); - - $.securityCheck = function(data) { - if (location.protocol !== 'https:') { - return delete data['Redirect to HTTPS']; - } - }; - - if (((typeof GM !== "undefined" && GM !== null ? GM.deleteValue : void 0) != null) && window.BroadcastChannel && (typeof GM_addValueChangeListener === "undefined" || GM_addValueChangeListener === null)) { - $.syncChannel = new BroadcastChannel(g.NAMESPACE + 'sync'); - $.on($.syncChannel, 'message', function(e) { - var cb, key, ref, results, val; - ref = e.data; - results = []; - for (key in ref) { - val = ref[key]; - if ((cb = $.syncing[key])) { - results.push(cb($.dict.json(JSON.stringify(val)), key)); - } - } - return results; - }); - $.sync = function(key, cb) { - return $.syncing[key] = cb; - }; - $.forceSync = function() {}; - $["delete"] = function(keys, cb) { - var key; - if (!(keys instanceof Array)) { - keys = [keys]; - } - return Promise.all((function() { - var j, len, results; - results = []; - for (j = 0, len = keys.length; j < len; j++) { - key = keys[j]; - results.push(GM.deleteValue(g.NAMESPACE + key)); - } - return results; - })()).then(function() { - var items, j, key, len; - items = $.dict(); - for (j = 0, len = keys.length; j < len; j++) { - key = keys[j]; - items[key] = void 0; - } - $.syncChannel.postMessage(items); - return typeof cb === "function" ? cb() : void 0; - }); - }; - $.get = $.oneItemSugar(function(items, cb) { - var key, keys; - keys = Object.keys(items); - return Promise.all((function() { - var j, len, results; - results = []; - for (j = 0, len = keys.length; j < len; j++) { - key = keys[j]; - results.push(GM.getValue(g.NAMESPACE + key)); - } - return results; - })()).then(function(values) { - var i, j, len, val; - for (i = j = 0, len = values.length; j < len; i = ++j) { - val = values[i]; - if (val) { - items[keys[i]] = $.dict.json(val); - } - } - return cb(items); - }); - }); - $.set = $.oneItemSugar(function(items, cb) { - var key, val; - $.securityCheck(items); - return Promise.all((function() { - var results; - results = []; - for (key in items) { - val = items[key]; - results.push(GM.setValue(g.NAMESPACE + key, JSON.stringify(val))); - } - return results; - })()).then(function() { - $.syncChannel.postMessage(items); - return typeof cb === "function" ? cb() : void 0; - }); - }); - $.clear = function(cb) { - return GM.listValues().then(function(keys) { - return $["delete"](keys.map(function(key) { - return key.replace(g.NAMESPACE, ''); - }), cb); - })["catch"](function() { - return $["delete"](Object.keys(Conf).concat(['previousversion', 'QR Size', 'QR.persona']), cb); - }); - }; - } else { - if (typeof GM_deleteValue === "undefined" || GM_deleteValue === null) { - $.perProtocolSettings = true; - } - if (typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) { - $.getValue = GM_getValue; - $.listValues = function() { - return GM_listValues(); - }; - } else if ($.hasStorage) { - $.getValue = function(key) { - return localStorage.getItem(key); - }; - $.listValues = function() { - var key, results; - results = []; - for (key in localStorage) { - if (key.slice(0, g.NAMESPACE.length) === g.NAMESPACE) { - results.push(key); - } - } - return results; - }; - } else { - $.getValue = function() {}; - $.listValues = function() { - return []; - }; - } - if (typeof GM_addValueChangeListener !== "undefined" && GM_addValueChangeListener !== null) { - $.setValue = GM_setValue; - $.deleteValue = GM_deleteValue; - } else if (typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) { - $.oldValue = $.dict(); - $.setValue = function(key, val) { - GM_setValue(key, val); - if (key in $.syncing) { - $.oldValue[key] = val; - if ($.hasStorage) { - return localStorage.setItem(key, val); - } - } - }; - $.deleteValue = function(key) { - GM_deleteValue(key); - if (key in $.syncing) { - delete $.oldValue[key]; - if ($.hasStorage) { - return localStorage.removeItem(key); - } - } - }; - if (!$.hasStorage) { - $.cantSync = true; - } - } else if ($.hasStorage) { - $.oldValue = $.dict(); - $.setValue = function(key, val) { - if (key in $.syncing) { - $.oldValue[key] = val; - } - return localStorage.setItem(key, val); - }; - $.deleteValue = function(key) { - if (key in $.syncing) { - delete $.oldValue[key]; - } - return localStorage.removeItem(key); - }; - } else { - $.setValue = function() {}; - $.deleteValue = function() {}; - $.cantSync = $.cantSet = true; - } - if (typeof GM_addValueChangeListener !== "undefined" && GM_addValueChangeListener !== null) { - $.sync = function(key, cb) { - return $.syncing[key] = GM_addValueChangeListener(g.NAMESPACE + key, function(key2, oldValue, newValue, remote) { - if (remote) { - if (newValue !== void 0) { - newValue = $.dict.json(newValue); - } - return cb(newValue, key); - } - }); - }; - $.forceSync = function() {}; - } else if ((typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) || $.hasStorage) { - $.sync = function(key, cb) { - key = g.NAMESPACE + key; - $.syncing[key] = cb; - return $.oldValue[key] = $.getValue(key); - }; - (function() { - var onChange; - onChange = function(arg) { - var cb, key, newValue; - key = arg.key, newValue = arg.newValue; - if (!(cb = $.syncing[key])) { - return; - } - if (newValue != null) { - if (newValue === $.oldValue[key]) { - return; - } - $.oldValue[key] = newValue; - return cb($.dict.json(newValue), key.slice(g.NAMESPACE.length)); - } else { - if ($.oldValue[key] == null) { - return; - } - delete $.oldValue[key]; - return cb(void 0, key.slice(g.NAMESPACE.length)); - } - }; - $.on(window, 'storage', onChange); - return $.forceSync = function(key) { - key = g.NAMESPACE + key; - return onChange({ - key: key, - newValue: $.getValue(key) - }); - }; - })(); - } else { - $.sync = function() {}; - $.forceSync = function() {}; - } - $["delete"] = function(keys) { - var j, key, len; - if (!(keys instanceof Array)) { - keys = [keys]; - } - for (j = 0, len = keys.length; j < len; j++) { - key = keys[j]; - $.deleteValue(g.NAMESPACE + key); - } - }; - $.get = $.oneItemSugar(function(items, cb) { - return $.queueTask($.getSync, items, cb); - }); - $.getSync = function(items, cb) { - var err, key, val2; - for (key in items) { - if ((val2 = $.getValue(g.NAMESPACE + key))) { - try { - items[key] = $.dict.json(val2); - } catch (error) { - err = error; - if (!/^(?:undefined)*$/.test(val2)) { - throw err; - } - } - } - } - return cb(items); - }; - $.set = $.oneItemSugar(function(items, cb) { - $.securityCheck(items); - return $.queueTask(function() { - var key, value; - for (key in items) { - value = items[key]; - $.setValue(g.NAMESPACE + key, JSON.stringify(value)); - } - return typeof cb === "function" ? cb() : void 0; - }); - }); - $.clear = function(cb) { - $["delete"](Object.keys(Conf)); - $["delete"](['previousversion', 'QR Size', 'QR.persona']); - try { - $["delete"]($.listValues().map(function(key) { - return key.replace(g.NAMESPACE, ''); - })); - } catch (error) {} - return typeof cb === "function" ? cb() : void 0; - }; - } - - return $; - -}).call(this); - -$$ = (function() { - var $$, - slice = [].slice; - - $$ = function(selector, root) { - if (root == null) { - root = d.body; - } - return slice.call(root.querySelectorAll(selector)); - }; - - return $$; - -}).call(this); - -CrossOrigin = (function() { - var CrossOrigin, Request; - - CrossOrigin = { - binary: function(url, cb, headers) { - var fallback, gmOptions; - if (headers == null) { - headers = $.dict(); - } - url = url.replace(/^((?:https?:)?\/\/(?:\w+\.)?(?:4chan|4channel|4cdn)\.org)\/adv\//, '$1//adv/'); - fallback = function() { - return $.ajax(url, { - headers: headers, - responseType: 'arraybuffer', - onloadend: function() { - if (this.status && this.response) { - return cb(new Uint8Array(this.response), this.getAllResponseHeaders()); - } else { - return cb(null); - } - } - }); - }; - if (!(((typeof GM !== "undefined" && GM !== null ? GM.xmlHttpRequest : void 0) != null) || (typeof GM_xmlhttpRequest !== "undefined" && GM_xmlhttpRequest !== null))) { - fallback(); - return; - } - gmOptions = { - method: "GET", - url: url, - headers: headers, - responseType: 'arraybuffer', - overrideMimeType: 'text/plain; charset=x-user-defined', - onload: function(xhr) { - var data, i, r; - if (xhr.response instanceof ArrayBuffer) { - data = new Uint8Array(xhr.response); - } else { - r = xhr.responseText; - data = new Uint8Array(r.length); - i = 0; - while (i < r.length) { - data[i] = r.charCodeAt(i); - i++; - } - } - return cb(data, xhr.responseHeaders); - }, - onerror: function() { - return cb(null); - }, - onabort: function() { - return cb(null); - } - }; - try { - return ((typeof GM !== "undefined" && GM !== null ? GM.xmlHttpRequest : void 0) || GM_xmlhttpRequest)(gmOptions); - } catch (error) { - return fallback(); - } - }, - file: function(url, cb) { - return CrossOrigin.binary(url, function(data, headers) { - var blob, contentDisposition, contentType, match, mime, name, ref, ref1, ref2, ref3, ref4; - if (data == null) { - return cb(null); - } - name = (ref = url.match(/([^\/?#]+)\/*(?:$|[?#])/)) != null ? ref[1] : void 0; - contentType = (ref1 = headers.match(/Content-Type:\s*(.*)/i)) != null ? ref1[1] : void 0; - contentDisposition = (ref2 = headers.match(/Content-Disposition:\s*(.*)/i)) != null ? ref2[1] : void 0; - mime = (contentType != null ? contentType.match(/[^;]*/)[0] : void 0) || 'application/octet-stream'; - match = (contentDisposition != null ? (ref3 = contentDisposition.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)) != null ? ref3[1] : void 0 : void 0) || (contentType != null ? (ref4 = contentType.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)) != null ? ref4[1] : void 0 : void 0); - if (match) { - name = match.replace(/\\"/g, '"'); - } - if (/^text\/plain;\s*charset=x-user-defined$/i.test(mime)) { - mime = $.getOwn(QR.typeFromExtension, name.match(/[^.]*$/)[0].toLowerCase()) || 'application/octet-stream'; - } - blob = new Blob([data], { - type: mime - }); - blob.name = name; - return cb(blob); - }); - }, - Request: Request = (function() { - function Request() {} - - Request.prototype.status = 0; - - Request.prototype.statusText = ''; - - Request.prototype.response = null; - - Request.prototype.responseHeaderString = null; - - Request.prototype.getResponseHeader = function(headerName) { - var header, i, j, key, len, ref, ref1, ref2, val; - if ((this.responseHeaders == null) && (this.responseHeaderString != null)) { - this.responseHeaders = $.dict(); - ref = this.responseHeaderString.split('\r\n'); - for (j = 0, len = ref.length; j < len; j++) { - header = ref[j]; - if ((i = header.indexOf(':')) >= 0) { - key = header.slice(0, i).trim().toLowerCase(); - val = header.slice(i + 1).trim(); - this.responseHeaders[key] = val; - } - } - } - return (ref1 = (ref2 = this.responseHeaders) != null ? ref2[headerName.toLowerCase()] : void 0) != null ? ref1 : null; - }; - - Request.prototype.abort = function() {}; - - Request.prototype.onloadend = function() {}; - - return Request; - - })(), - ajax: function(url, options) { - var gmOptions, gmReq, headers, onloadend, req, responseType, timeout; - if (options == null) { - options = {}; - } - onloadend = options.onloadend, timeout = options.timeout, responseType = options.responseType, headers = options.headers; - if (responseType == null) { - responseType = 'json'; - } - if (!(((typeof GM !== "undefined" && GM !== null ? GM.xmlHttpRequest : void 0) != null) || (typeof GM_xmlhttpRequest !== "undefined" && GM_xmlhttpRequest !== null))) { - return $.ajax(url, options); - } - req = new CrossOrigin.Request(); - req.onloadend = onloadend; - gmOptions = { - method: 'GET', - url: url, - headers: headers, - timeout: timeout, - onload: function(xhr) { - var response; - try { - response = (function() { - switch (responseType) { - case 'json': - if (xhr.responseText) { - return JSON.parse(xhr.responseText); - } else { - return null; - } - break; - default: - return xhr.responseText; - } - })(); - $.extend(req, { - response: response, - status: xhr.status, - statusText: xhr.statusText, - responseHeaderString: xhr.responseHeaders - }); - } catch (error) {} - return req.onloadend(); - }, - onerror: function() { - return req.onloadend(); - }, - onabort: function() { - return req.onloadend(); - }, - ontimeout: function() { - return req.onloadend(); - } - }; - try { - gmReq = ((typeof GM !== "undefined" && GM !== null ? GM.xmlHttpRequest : void 0) || GM_xmlhttpRequest)(gmOptions); - } catch (error) { - return $.ajax(url, options); - } - if (gmReq && typeof gmReq.abort === 'function') { - req.abort = function() { - try { - return gmReq.abort(); - } catch (error) {} - }; - } - return req; - }, - cache: function(url, cb) { - return $.cache(url, cb, { - ajax: CrossOrigin.ajax - }); - }, - permission: function(cb) { - return cb(); - } - }; - - return CrossOrigin; - -}).call(this); - -Board = (function() { - var Board; - - Board = (function() { - Board.prototype.toString = function() { - return this.ID; - }; - - function Board(ID) { - var ref; - this.ID = ID; - this.boardID = this.ID; - this.siteID = g.SITE.ID; - this.threads = new SimpleDict(); - this.posts = new SimpleDict(); - this.config = ((ref = BoardConfig.boards) != null ? ref[this.ID] : void 0) || {}; - g.boards[this] = this; - } - - Board.prototype.cooldowns = function() { - var c, c2, i, key, len, ref; - c2 = (this.config || {}).cooldowns || {}; - c = { - thread: c2.threads || 0, - reply: c2.replies || 0, - image: c2.images || 0, - thread_global: 300 - }; - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - ref = ['reply', 'image']; - for (i = 0, len = ref.length; i < len; i++) { - key = ref[i]; - c[key] = Math.ceil(c[key] / 2); - } - } - return c; - }; - - return Board; - - })(); - - return Board; - -}).call(this); - -Callbacks = (function() { - var Callbacks; - - Callbacks = (function() { - Callbacks.Post = new Callbacks('Post'); - - Callbacks.Thread = new Callbacks('Thread'); - - Callbacks.CatalogThread = new Callbacks('Catalog Thread'); - - Callbacks.CatalogThreadNative = new Callbacks('Catalog Thread'); - - function Callbacks(type) { - this.type = type; - this.keys = []; - } - - Callbacks.prototype.push = function(arg) { - var cb, name; - name = arg.name, cb = arg.cb; - if (!this[name]) { - this.keys.push(name); - } - return this[name] = cb; - }; - - Callbacks.prototype.execute = function(node, keys, force) { - var err, errors, i, len, name, ref, ref1, ref2; - if (keys == null) { - keys = this.keys; - } - if (force == null) { - force = false; - } - if (node.callbacksExecuted && !force) { - return; - } - node.callbacksExecuted = true; - for (i = 0, len = keys.length; i < len; i++) { - name = keys[i]; - try { - if ((ref = this[name]) != null) { - ref.call(node); - } - } catch (error) { - err = error; - if (!errors) { - errors = []; - } - errors.push({ - message: ['"', name, '" crashed on node ', this.type, ' No.', node.ID, ' (', node.board, ').'].join(''), - error: err, - html: (ref1 = node.nodes) != null ? (ref2 = ref1.root) != null ? ref2.outerHTML : void 0 : void 0 - }); - } - } - if (errors) { - return Main.handleErrors(errors); - } - }; - - return Callbacks; - - })(); - - return Callbacks; - -}).call(this); - -CatalogThread = (function() { - var CatalogThread; - - CatalogThread = (function() { - CatalogThread.prototype.toString = function() { - return this.ID; - }; - - function CatalogThread(root, thread) { - var post; - this.thread = thread; - this.ID = this.thread.ID; - this.board = this.thread.board; - post = this.thread.OP.nodes.post; - this.nodes = { - root: root, - thumb: $('.catalog-thumb', post), - icons: $('.catalog-icons', post), - postCount: $('.post-count', post), - fileCount: $('.file-count', post), - pageCount: $('.page-count', post), - replies: null - }; - this.thread.catalogView = this; - } - - return CatalogThread; - - })(); - - return CatalogThread; - -}).call(this); - -CatalogThreadNative = (function() { - var CatalogThreadNative; - - CatalogThreadNative = (function() { - CatalogThreadNative.prototype.toString = function() { - return this.ID; - }; - - function CatalogThreadNative(root) { - this.nodes = { - root: root, - thumb: $(g.SITE.selectors.catalog.thumb, root) - }; - this.siteID = g.SITE.ID; - this.boardID = this.nodes.thumb.parentNode.pathname.split(/\/+/)[1]; - this.board = g.boards[this.boardID] || new Board(this.boardID); - this.ID = this.threadID = +(root.dataset.id || root.id).match(/\d*$/)[0]; - this.thread = this.board.threads.get(this.ID) || new Thread(this.ID, this.board); - } - - return CatalogThreadNative; - - })(); - - return CatalogThreadNative; - -}).call(this); - -Connection = (function() { - var Connection, - bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - - Connection = (function() { - function Connection(target, origin, cb) { - this.target = target; - this.origin = origin; - this.cb = cb != null ? cb : {}; - this.onMessage = bind(this.onMessage, this); - this.send = bind(this.send, this); - $.on(window, 'message', this.onMessage); - } - - Connection.prototype.targetWindow = function() { - if (this.target instanceof window.HTMLIFrameElement) { - return this.target.contentWindow; - } else { - return this.target; - } - }; - - Connection.prototype.send = function(data) { - return this.targetWindow().postMessage("" + g.NAMESPACE + (JSON.stringify(data)), this.origin); - }; - - Connection.prototype.onMessage = function(e) { - var data, type, value; - if (!(e.source === this.targetWindow() && e.origin === this.origin && typeof e.data === 'string' && e.data.slice(0, g.NAMESPACE.length) === g.NAMESPACE)) { - return; - } - data = JSON.parse(e.data.slice(g.NAMESPACE.length)); - for (type in data) { - value = data[type]; - if ($.hasOwn(this.cb, type)) { - this.cb[type](value); - } - } - }; - - return Connection; - - })(); - - return Connection; - -}).call(this); - -DataBoard = (function() { - var DataBoard, - bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - - DataBoard = (function() { - DataBoard.keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads', 'watcherLastModified', 'customTitles']; - - function DataBoard(key1, sync, dontClean) { - var init; - this.key = key1; - this.onSync = bind(this.onSync, this); - this.initData(Conf[this.key]); - $.sync(this.key, this.onSync); - if (!dontClean) { - this.clean(); - } - if (!sync) { - return; - } - init = (function(_this) { - return function() { - $.off(d, '4chanXInitFinished', init); - return _this.sync = sync; - }; - })(this); - $.on(d, '4chanXInitFinished', init); - } - - DataBoard.prototype.initData = function(data1) { - var base, boards, lastChecked, name, ref; - this.data = data1; - if (this.data.boards) { - ref = this.data, boards = ref.boards, lastChecked = ref.lastChecked; - this.data['4chan.org'] = { - boards: boards, - lastChecked: lastChecked - }; - delete this.data.boards; - delete this.data.lastChecked; - } - return (base = this.data)[name = g.SITE.ID] || (base[name] = { - boards: $.dict() - }); - }; - - DataBoard.prototype.changes = []; - - DataBoard.prototype.save = function(change, cb) { - change(); - this.changes.push(change); - return $.get(this.key, { - boards: $.dict() - }, (function(_this) { - return function(items) { - var i, len, needSync, ref; - if (!_this.changes.length) { - return; - } - needSync = (items[_this.key].version || 0) > (_this.data.version || 0); - if (needSync) { - _this.initData(items[_this.key]); - ref = _this.changes; - for (i = 0, len = ref.length; i < len; i++) { - change = ref[i]; - change(); - } - } - _this.changes = []; - _this.data.version = (_this.data.version || 0) + 1; - return $.set(_this.key, _this.data, function() { - if (needSync) { - if (typeof _this.sync === "function") { - _this.sync(); - } - } - return typeof cb === "function" ? cb() : void 0; - }); - }; - })(this)); - }; - - DataBoard.prototype.forceSync = function(cb) { - return $.get(this.key, { - boards: $.dict() - }, (function(_this) { - return function(items) { - var change, i, len, ref; - if ((items[_this.key].version || 0) > (_this.data.version || 0)) { - _this.initData(items[_this.key]); - ref = _this.changes; - for (i = 0, len = ref.length; i < len; i++) { - change = ref[i]; - change(); - } - if (typeof _this.sync === "function") { - _this.sync(); - } - } - return typeof cb === "function" ? cb() : void 0; - }; - })(this)); - }; - - DataBoard.prototype["delete"] = function(arg, cb) { - var boardID, postID, siteID, threadID; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID; - siteID || (siteID = g.SITE.ID); - if (!this.data[siteID]) { - return; - } - return this.save((function(_this) { - return function() { - var ref; - if (postID) { - if (!((ref = _this.data[siteID].boards[boardID]) != null ? ref[threadID] : void 0)) { - return; - } - delete _this.data[siteID].boards[boardID][threadID][postID]; - return _this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }); - } else if (threadID) { - if (!_this.data[siteID].boards[boardID]) { - return; - } - delete _this.data[siteID].boards[boardID][threadID]; - return _this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID - }); - } else { - return delete _this.data[siteID].boards[boardID]; - } - }; - })(this), cb); - }; - - DataBoard.prototype.deleteIfEmpty = function(arg) { - var boardID, siteID, threadID; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID; - if (!this.data[siteID]) { - return; - } - if (threadID) { - if (!Object.keys(this.data[siteID].boards[boardID][threadID]).length) { - delete this.data[siteID].boards[boardID][threadID]; - return this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID - }); - } - } else if (!Object.keys(this.data[siteID].boards[boardID]).length) { - return delete this.data[siteID].boards[boardID]; - } - }; - - DataBoard.prototype.set = function(data, cb) { - return this.save((function(_this) { - return function() { - return _this.setUnsafe(data); - }; - })(this), cb); - }; - - DataBoard.prototype.setUnsafe = function(arg) { - var base, base1, base2, base3, boardID, postID, siteID, threadID, val; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, val = arg.val; - siteID || (siteID = g.SITE.ID); - (base = this.data)[siteID] || (base[siteID] = { - boards: $.dict() - }); - if (postID !== void 0) { - return ((base1 = ((base2 = this.data[siteID].boards)[boardID] || (base2[boardID] = $.dict())))[threadID] || (base1[threadID] = $.dict()))[postID] = val; - } else if (threadID !== void 0) { - return ((base3 = this.data[siteID].boards)[boardID] || (base3[boardID] = $.dict()))[threadID] = val; - } else { - return this.data[siteID].boards[boardID] = val; - } - }; - - DataBoard.prototype.extend = function(arg, cb) { - var boardID, postID, siteID, threadID, val; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, val = arg.val; - return this.save((function(_this) { - return function() { - var key, oldVal, subVal; - oldVal = _this.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - postID: postID, - defaultValue: $.dict() - }); - for (key in val) { - subVal = val[key]; - if (typeof subVal === 'undefined') { - delete oldVal[key]; - } else { - oldVal[key] = subVal; - } - } - return _this.setUnsafe({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - postID: postID, - val: oldVal - }); - }; - })(this), cb); - }; - - DataBoard.prototype.setLastChecked = function(key) { - if (key == null) { - key = 'lastChecked'; - } - return this.save((function(_this) { - return function() { - return _this.data[key] = Date.now(); - }; - })(this)); - }; - - DataBoard.prototype.get = function(arg) { - var ID, board, boardID, defaultValue, i, len, postID, ref, siteID, thread, threadID, val; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, defaultValue = arg.defaultValue; - siteID || (siteID = g.SITE.ID); - if (board = (ref = this.data[siteID]) != null ? ref.boards[boardID] : void 0) { - if (threadID == null) { - if (postID != null) { - for (thread = i = 0, len = board.length; i < len; thread = ++i) { - ID = board[thread]; - if (postID in thread) { - val = thread[postID]; - break; - } - } - } else { - val = board; - } - } else if (thread = board[threadID]) { - val = postID != null ? thread[postID] : thread; - } - } - return val || defaultValue; - }; - - DataBoard.prototype.clean = function() { - var boardID, now, ref, ref1, siteID, val; - siteID = g.SITE.ID; - ref = this.data[siteID].boards; - for (boardID in ref) { - val = ref[boardID]; - this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID - }); - } - now = Date.now(); - if (!((now - 2 * $.HOUR < (ref1 = this.data[siteID].lastChecked || 0) && ref1 <= now))) { - this.data[siteID].lastChecked = now; - for (boardID in this.data[siteID].boards) { - this.ajaxClean(boardID); - } - } - }; - - DataBoard.prototype.ajaxClean = function(boardID) { - var base, siteID, that, threadsList; - that = this; - siteID = g.SITE.ID; - threadsList = typeof (base = g.SITE.urls).threadsListJSON === "function" ? base.threadsListJSON({ - siteID: siteID, - boardID: boardID - }) : void 0; - if (!threadsList) { - return; - } - return $.cache(threadsList, function() { - var archiveList, base1, response1; - if (this.status !== 200) { - return; - } - archiveList = typeof (base1 = g.SITE.urls).archiveListJSON === "function" ? base1.archiveListJSON({ - siteID: siteID, - boardID: boardID - }) : void 0; - if (!archiveList) { - return that.ajaxCleanParse(boardID, this.response); - } - response1 = this.response; - return $.cache(archiveList, function() { - if (!(this.status === 200 || (!g.SITE.archivedBoardsKnown && this.status === 404))) { - return; - } - return that.ajaxCleanParse(boardID, response1, this.response); - }); - }); - }; - - DataBoard.prototype.ajaxCleanParse = function(boardID, response1, response2) { - var ID, board, i, j, k, len, len1, len2, page, ref, siteID, thread, threads; - siteID = g.SITE.ID; - if (!(board = this.data[siteID].boards[boardID])) { - return; - } - threads = $.dict(); - if (response1) { - for (i = 0, len = response1.length; i < len; i++) { - page = response1[i]; - ref = page.threads; - for (j = 0, len1 = ref.length; j < len1; j++) { - thread = ref[j]; - ID = thread.no; - if (ID in board) { - threads[ID] = board[ID]; - } - } - } - } - if (response2) { - for (k = 0, len2 = response2.length; k < len2; k++) { - ID = response2[k]; - if (ID in board) { - threads[ID] = board[ID]; - } - } - } - this.data[siteID].boards[boardID] = threads; - this.deleteIfEmpty({ - siteID: siteID, - boardID: boardID - }); - return $.set(this.key, this.data); - }; - - DataBoard.prototype.onSync = function(data) { - if (!((data.version || 0) > (this.data.version || 0))) { - return; - } - this.initData(data); - return typeof this.sync === "function" ? this.sync() : void 0; - }; - - return DataBoard; - - })(); - - return DataBoard; - -}).call(this); - -Fetcher = (function() { - var Fetcher, - slice = [].slice; - - Fetcher = (function() { - function Fetcher(boardID1, threadID, postID1, root, quoter) { - var board, post, ref, that, thread; - this.boardID = boardID1; - this.threadID = threadID; - this.postID = postID1; - this.root = root; - this.quoter = quoter; - if (post = g.posts.get(this.boardID + "." + this.postID)) { - this.insert(post); - return; - } - if ((post = (ref = Index.replyData) != null ? ref[this.boardID + "." + this.postID] : void 0) && (thread = g.threads.get(this.boardID + "." + this.threadID))) { - board = g.boards[this.boardID]; - post = new Post(g.SITE.Build.postFromObject(post, this.boardID), thread, board, { - isFetchedQuote: true - }); - Main.callbackNodes('Post', [post]); - this.insert(post); - return; - } - this.root.textContent = "Loading post No." + this.postID + "..."; - if (this.threadID) { - that = this; - $.cache(g.SITE.urls.threadJSON({ - boardID: this.boardID, - threadID: this.threadID - }), function(arg) { - var isCached; - isCached = arg.isCached; - return that.fetchedPost(this, isCached); - }); - } else { - this.archivedPost(); - } - } - - Fetcher.prototype.insert = function(post) { - var boardID, clone, cssVersion, k, len, nodes, postID, quote, ref, ref1, ref2; - if (!this.root.parentNode) { - return; - } - this.quoter || (this.quoter = post); - clone = post.addClone(this.quoter.context, $.hasClass(this.root, 'dialog')); - Main.callbackNodes('Post', [clone]); - nodes = clone.nodes; - $.rmAll(nodes.root); - $.add(nodes.root, nodes.post); - ref = clone.nodes.quotelinks.concat(slice.call(clone.nodes.backlinks)); - for (k = 0, len = ref.length; k < len; k++) { - quote = ref[k]; - ref1 = Get.postDataFromLink(quote), boardID = ref1.boardID, postID = ref1.postID; - if (postID === this.quoter.ID && boardID === this.quoter.board.ID) { - $.addClass(quote, 'forwardlink'); - } - } - if (clone.nodes.flag && !(Fetcher.flagCSS || (Fetcher.flagCSS = $('link[href^="//s.4cdn.org/css/flags."]')))) { - cssVersion = ((ref2 = $('link[href^="//s.4cdn.org/css/"]')) != null ? ref2.href.match(/\d+(?=\.css$)|$/)[0] : void 0) || Date.now(); - Fetcher.flagCSS = $.el('link', { - rel: 'stylesheet', - href: "//s.4cdn.org/css/flags." + cssVersion + ".css" - }); - $.add(d.head, Fetcher.flagCSS); - } - $.rmAll(this.root); - $.add(this.root, nodes.root); - return $.event('PostsInserted', null, this.root); - }; - - Fetcher.prototype.fetchedPost = function(req, isCached) { - var api, board, k, len, post, posts, status, that, thread; - if (post = g.posts.get(this.boardID + "." + this.postID)) { - this.insert(post); - return; - } - status = req.status; - if (status !== 200) { - if (status && this.archivedPost()) { - return; - } - $.addClass(this.root, 'warning'); - this.root.textContent = status === 404 ? "Thread No." + this.threadID + " 404'd." : !status ? 'Connection Error' : "Error " + req.statusText + " (" + req.status + ")."; - return; - } - posts = req.response.posts; - g.SITE.Build.spoilerRange[this.boardID] = posts[0].custom_spoiler; - for (k = 0, len = posts.length; k < len; k++) { - post = posts[k]; - if (post.no === this.postID) { - break; - } - } - if (post.no !== this.postID) { - if (isCached) { - api = g.SITE.urls.threadJSON({ - boardID: this.boardID, - threadID: this.threadID - }); - $.cleanCache(function(url) { - return url === api; - }); - that = this; - $.cache(api, function() { - return that.fetchedPost(this, false); - }); - return; - } - if (this.archivedPost()) { - return; - } - $.addClass(this.root, 'warning'); - this.root.textContent = "Post No." + this.postID + " was not found."; - return; - } - board = g.boards[this.boardID] || new Board(this.boardID); - thread = g.threads.get(this.boardID + "." + this.threadID) || new Thread(this.threadID, board); - post = new Post(g.SITE.Build.postFromObject(post, this.boardID), thread, board, { - isFetchedQuote: true - }); - Main.callbackNodes('Post', [post]); - return this.insert(post); - }; - - Fetcher.prototype.archivedPost = function() { - var archive, encryptionOK, that, url; - if (!Conf['Resurrect Quotes']) { - return false; - } - if (!(url = Redirect.to('post', { - boardID: this.boardID, - postID: this.postID - }))) { - return false; - } - archive = Redirect.data.post[this.boardID]; - encryptionOK = /^https:\/\//.test(url) || location.protocol === 'http:'; - if (encryptionOK || Conf['Exempt Archives from Encryption']) { - that = this; - CrossOrigin.cache(url, function() { - var key, media, ref, ref1; - if (!encryptionOK && ((ref = this.response) != null ? ref.media : void 0)) { - media = this.response.media; - for (key in media) { - if (/_link$/.test(key)) { - if (!((ref1 = $.getOwn(media, key)) != null ? ref1.match(/^http:\/\//) : void 0)) { - delete media[key]; - } - } - } - } - return that.parseArchivedPost(this.response, url, archive); - }); - return true; - } - return false; - }; - - Fetcher.prototype.parseArchivedPost = function(data, url, archive) { - var board, comment, greentext, i, j, media_link, o, post, ref, tag, text, text2, thread, thumb_link; - if (post = g.posts.get(this.boardID + "." + this.postID)) { - this.insert(post); - return; - } - if (data == null) { - $.addClass(this.root, 'warning'); - this.root.textContent = "Error fetching Post No." + this.postID + " from " + archive.name + "."; - return; - } - if (data.error) { - $.addClass(this.root, 'warning'); - this.root.textContent = data.error; - return; - } - comment = (data.comment || '').split(/(\n|\[\/?(?:b|spoiler|code|moot|banned|fortune(?: color="#\w+")?|i|red|green|blue)\])/); - comment = (function() { - var k, len, results; - results = []; - for (i = k = 0, len = comment.length; k < len; i = ++k) { - text = comment[i]; - if (i % 2 === 1) { - tag = this.archiveTags[text.replace(/\ .*\]/, ']')]; - if (typeof tag === 'function') { - results.push(tag(text)); - } else { - results.push(tag); - } - } else { - greentext = text[0] === '>'; - text = text.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2'); - text = (function() { - var l, len1, ref, results1; - ref = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g); - results1 = []; - for (j = l = 0, len1 = ref.length; l < len1; j = ++l) { - text2 = ref[j]; - results1.push({innerHTML: ((j % 2) ? "" + E(text2) + "" : E(text2))}); - } - return results1; - })(); - text = {innerHTML: ((greentext) ? "" + E.cat(text) + "" : E.cat(text))}; - results.push(text); - } - } - return results; - }).call(this); - comment = {innerHTML: E.cat(comment)}; - this.threadID = +data.thread_num; - o = { - ID: this.postID, - threadID: this.threadID, - boardID: this.boardID, - isReply: this.postID !== this.threadID - }; - o.info = { - subject: data.title, - email: data.email, - name: data.name || '', - tripcode: data.trip, - capcode: (function() { - switch (data.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: data.poster_hash, - flagCode: data.poster_country, - flagCodeTroll: data.troll_country_code, - flag: data.poster_country_name || data.troll_country_name, - dateUTC: data.timestamp, - dateText: data.fourchan_date, - commentHTML: comment - }; - if (o.info.capcode) { - delete o.info.uniqueID; - } - if (data.media && !!+data.media.banned) { - o.fileDeleted = true; - } else if ((ref = data.media) != null ? ref.media_filename : void 0) { - thumb_link = data.media.thumb_link; - if ((thumb_link != null ? thumb_link[0] : void 0) === '/') { - thumb_link = url.split('/', 3).join('/') + thumb_link; - } - if (!Redirect.securityCheck(thumb_link)) { - thumb_link = ''; - } - media_link = Redirect.to('file', { - boardID: this.boardID, - filename: data.media.media_orig - }); - if (!Redirect.securityCheck(media_link)) { - media_link = ''; - } - o.file = { - name: data.media.media_filename, - url: media_link || (this.boardID === 'f' ? location.protocol + "//" + (ImageHost.flashHost()) + "/" + this.boardID + "/" + (encodeURIComponent(E(data.media.media_filename))) : location.protocol + "//" + (ImageHost.host()) + "/" + this.boardID + "/" + data.media.media_orig), - height: data.media.media_h, - width: data.media.media_w, - MD5: data.media.media_hash, - size: $.bytesToString(data.media.media_size), - thumbURL: thumb_link || (location.protocol + "//" + (ImageHost.thumbHost()) + "/" + this.boardID + "/" + data.media.preview_orig), - theight: data.media.preview_h, - twidth: data.media.preview_w, - isSpoiler: data.media.spoiler === '1' - }; - if (!/\.pdf$/.test(o.file.url)) { - o.file.dimensions = o.file.width + "x" + o.file.height; - } - if (this.boardID === 'f' && data.media.exif) { - o.file.tag = JSON.parse(data.media.exif).Tag; - } - } - o.extra = $.dict(); - board = g.boards[this.boardID] || new Board(this.boardID); - thread = g.threads.get(this.boardID + "." + this.threadID) || new Thread(this.threadID, board); - post = new Post(g.SITE.Build.post(o), thread, board, { - isFetchedQuote: true - }); - post.kill(); - if (post.file) { - post.file.thumbURL = o.file.thumbURL; - } - Main.callbackNodes('Post', [post]); - return this.insert(post); - }; - - Fetcher.prototype.archiveTags = { - '\n': {innerHTML: "
      "}, - '[b]': {innerHTML: ""}, - '[/b]': {innerHTML: ""}, - '[spoiler]': {innerHTML: ""}, - '[/spoiler]': {innerHTML: ""}, - '[code]': {innerHTML: "

      "},
      -      '[/code]': {innerHTML: "
      "}, - '[moot]': {innerHTML: "
      "}, - '[/moot]': {innerHTML: "
      "}, - '[banned]': {innerHTML: ""}, - '[/banned]': {innerHTML: ""}, - '[fortune]': function(text) { - return {innerHTML: ""}; - }, - '[/fortune]': {innerHTML: ""}, - '[i]': {innerHTML: ""}, - '[/i]': {innerHTML: ""}, - '[red]': {innerHTML: ""}, - '[/red]': {innerHTML: ""}, - '[green]': {innerHTML: ""}, - '[/green]': {innerHTML: ""}, - '[blue]': {innerHTML: ""}, - '[/blue]': {innerHTML: ""} - }; - - return Fetcher; - - })(); - - return Fetcher; - -}).call(this); - -Notice = (function() { - var Notice, - bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - - Notice = (function() { - function Notice(type, content, timeout, onclose) { - this.timeout = timeout; - this.onclose = onclose; - this.close = bind(this.close, this); - this.add = bind(this.add, this); - this.el = $.el('div', {innerHTML: "
      "}); - this.el.style.opacity = 0; - this.setType(type); - $.on(this.el.firstElementChild, 'click', this.close); - if (typeof content === 'string') { - content = $.tn(content); - } - $.add(this.el.lastElementChild, content); - $.ready(this.add); - } - - Notice.prototype.setType = function(type) { - return this.el.className = "notification " + type; - }; - - Notice.prototype.add = function() { - if (this.closed) { - return; - } - if (d.hidden) { - $.on(d, 'visibilitychange', this.add); - return; - } - $.off(d, 'visibilitychange', this.add); - $.add(Header.noticesRoot, this.el); - this.el.clientHeight; - this.el.style.opacity = 1; - if (this.timeout) { - return setTimeout(this.close, this.timeout * $.SECOND); - } - }; - - Notice.prototype.close = function() { - this.closed = true; - $.off(d, 'visibilitychange', this.add); - $.rm(this.el); - return typeof this.onclose === "function" ? this.onclose() : void 0; - }; - - return Notice; - - })(); - - return Notice; - -}).call(this); - -Post = (function() { - var Post, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Post = (function() { - Post.prototype.toString = function() { - return this.ID; - }; - - function Post(root, thread, board, flags) { - var clone, j, k, key, len, len1, ref, ref1, ref10, ref11, ref12, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, selector; - this.thread = thread; - this.board = board; - if (flags == null) { - flags = {}; - } - $.extend(this, flags); - this.ID = +root.id.match(/\d*$/)[0]; - this.postID = this.ID; - this.threadID = this.thread.ID; - this.boardID = this.board.ID; - this.siteID = g.SITE.ID; - this.fullID = this.board + "." + this.ID; - this.context = this; - this.isReply = this.ID !== this.threadID; - root.dataset.fullID = this.fullID; - this.nodes = this.parseNodes(root); - if (!this.isReply) { - this.thread.OP = this; - ref = ['isSticky', 'isClosed', 'isArchived']; - for (j = 0, len = ref.length; j < len; j++) { - key = ref[j]; - if ((selector = g.SITE.selectors.icons[key])) { - this.thread[key] = !!$(selector, this.nodes.info); - } - } - if (this.thread.isArchived) { - this.thread.isClosed = true; - this.thread.kill(); - } - } - this.info = { - subject: ((ref1 = this.nodes.subject) != null ? ref1.textContent : void 0) || void 0, - name: (ref2 = this.nodes.name) != null ? ref2.textContent : void 0, - email: this.nodes.email ? decodeURIComponent(this.nodes.email.href.replace(/^mailto:/, '')) : void 0, - tripcode: (ref3 = this.nodes.tripcode) != null ? ref3.textContent : void 0, - uniqueID: (ref4 = this.nodes.uniqueID) != null ? ref4.textContent : void 0, - capcode: (ref5 = this.nodes.capcode) != null ? ref5.textContent.replace('## ', '') : void 0, - pass: (ref6 = this.nodes.pass) != null ? ref6.title.match(/\d*$/)[0] : void 0, - flagCode: (ref7 = this.nodes.flag) != null ? (ref8 = ref7.className.match(/flag-(\w+)/)) != null ? ref8[1].toUpperCase() : void 0 : void 0, - flagCodeTroll: (ref9 = this.nodes.flag) != null ? (ref10 = ref9.className.match(/bfl-(\w+)/)) != null ? ref10[1].toUpperCase() : void 0 : void 0, - flag: (ref11 = this.nodes.flag) != null ? ref11.title : void 0, - date: this.nodes.date ? g.SITE.parseDate(this.nodes.date) : void 0 - }; - if (Conf['Anonymize']) { - this.info.nameBlock = 'Anonymous'; - } else { - this.info.nameBlock = ((this.info.name || '') + " " + (this.info.tripcode || '')).trim(); - } - if (this.info.capcode) { - this.info.nameBlock += " ## " + this.info.capcode; - } - if (this.info.uniqueID) { - this.info.nameBlock += " (ID: " + this.info.uniqueID + ")"; - } - this.parseComment(); - this.parseQuotes(); - this.parseFiles(); - this.isDead = false; - this.isHidden = false; - this.clones = []; - if (g.posts.get(this.fullID)) { - this.isRebuilt = true; - this.clones = g.posts.get(this.fullID).clones; - ref12 = this.clones; - for (k = 0, len1 = ref12.length; k < len1; k++) { - clone = ref12[k]; - clone.origin = this; - } - } - if (!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); - g.posts.push(this.fullID, this); - } - - Post.prototype.parseNodes = function(root) { - var base, info, key, nodes, post, ref, s, selector; - s = g.SITE.selectors; - post = $(s.post, root) || root; - info = $(s.infoRoot, post); - nodes = { - root: root, - bottom: this.isReply || !g.SITE.isOPContainerThread ? root : $(s.opBottom, root), - post: post, - info: info, - comment: $(s.comment, post), - quotelinks: [], - archivelinks: [], - embedlinks: [] - }; - ref = s.info; - for (key in ref) { - selector = ref[key]; - nodes[key] = $(selector, info); - } - if (typeof (base = g.SITE).parseNodes === "function") { - base.parseNodes(this, nodes); - } - nodes.uniqueIDRoot || (nodes.uniqueIDRoot = nodes.uniqueID); - if ($.engine === 'edge') { - Object.defineProperty(nodes, 'backlinks', { - configurable: true, - enumerable: true, - get: function() { - return post.getElementsByClassName('backlink'); - } - }); - } else { - nodes.backlinks = post.getElementsByClassName('backlink'); - } - return nodes; - }; - - Post.prototype.parseComment = function() { - var base, bq; - this.nodes.comment.normalize(); - this.nodes.commentClean = bq = this.nodes.comment.cloneNode(true); - if (typeof (base = g.SITE).cleanComment === "function") { - base.cleanComment(bq); - } - return this.info.comment = this.nodesToText(bq); - }; - - Post.prototype.commentDisplay = function() { - var base, bq; - bq = this.nodes.commentClean.cloneNode(true); - if (!(Conf['Remove Spoilers'] || Conf['Reveal Spoilers'])) { - this.cleanSpoilers(bq); - } - if (typeof (base = g.SITE).cleanCommentDisplay === "function") { - base.cleanCommentDisplay(bq); - } - return this.nodesToText(bq).trim().replace(/\s+$/gm, ''); - }; - - Post.prototype.commentOrig = function() { - var base, bq; - bq = this.nodes.commentClean.cloneNode(true); - if (typeof (base = g.SITE).insertTags === "function") { - base.insertTags(bq); - } - return this.nodesToText(bq); - }; - - Post.prototype.nodesToText = function(bq) { - var i, node, nodes, text; - text = ""; - nodes = $.X('.//br|.//text()', bq); - i = 0; - while (node = nodes.snapshotItem(i++)) { - text += node.data || '\n'; - } - return text; - }; - - Post.prototype.cleanSpoilers = function(bq) { - var j, len, node, spoilers; - spoilers = $$(g.SITE.selectors.spoiler, bq); - for (j = 0, len = spoilers.length; j < len; j++) { - node = spoilers[j]; - $.replace(node, $.tn('[spoiler]')); - } - }; - - Post.prototype.parseQuotes = function() { - var j, len, quotelink, ref; - this.quotes = []; - ref = $$(g.SITE.selectors.quotelink, this.nodes.comment); - for (j = 0, len = ref.length; j < len; j++) { - quotelink = ref[j]; - this.parseQuote(quotelink); - } - }; - - Post.prototype.parseQuote = function(quotelink) { - var fullID, match; - match = quotelink.href.match(g.SITE.regexp.quotelink); - if (!(match || (this.isClone && quotelink.dataset.postID))) { - return; - } - this.nodes.quotelinks.push(quotelink); - if (this.isClone) { - return; - } - fullID = match[1] + "." + match[3]; - if (indexOf.call(this.quotes, fullID) < 0) { - return this.quotes.push(fullID); - } - }; - - Post.prototype.parseFiles = function() { - var docIndex, file, fileRoot, fileRoots, index, j, len; - this.files = []; - fileRoots = this.fileRoots(); - index = 0; - for (docIndex = j = 0, len = fileRoots.length; j < len; docIndex = ++j) { - fileRoot = fileRoots[docIndex]; - if ((file = this.parseFile(fileRoot))) { - file.index = index++; - file.docIndex = docIndex; - this.files.push(file); - } - } - if (this.files.length) { - return this.file = this.files[0]; - } - }; - - Post.prototype.fileRoots = function() { - var roots; - if (g.SITE.selectors.multifile) { - roots = $$(g.SITE.selectors.multifile, this.nodes.root); - if (roots.length) { - return roots; - } - } - return [this.nodes.root]; - }; - - Post.prototype.parseFile = function(fileRoot) { - var file, key, ref, ref1, selector, size, unit; - file = {}; - ref = g.SITE.selectors.file; - for (key in ref) { - selector = ref[key]; - file[key] = $(selector, fileRoot); - } - file.thumbLink = (ref1 = file.thumb) != null ? ref1.parentNode : void 0; - if (!(file.text && file.link)) { - return; - } - if (!g.SITE.parseFile(this, file)) { - return; - } - $.extend(file, { - url: file.link.href, - isImage: $.isImage(file.link.href), - isVideo: $.isVideo(file.link.href) - }); - size = +file.size.match(/[\d.]+/)[0]; - unit = ['B', 'KB', 'MB', 'GB'].indexOf(file.size.match(/\w+$/)[0]); - while (unit-- > 0) { - size *= 1024; - } - file.sizeInBytes = size; - return file; - }; - - Post.deadMark = $.el('span', { - textContent: '\u00A0(Dead)', - className: 'qmark-dead' - }); - - Post.prototype.kill = function(file, index) { - var clone, j, k, len, len1, quotelink, ref, ref1, strong; - if (index == null) { - index = 0; - } - if (file) { - if (this.isDead || this.files[index].isDead) { - return; - } - this.files[index].isDead = true; - $.addClass(this.nodes.root, 'deleted-file'); - } else { - if (this.isDead) { - return; - } - this.isDead = true; - $.rmClass(this.nodes.root, 'deleted-file'); - $.addClass(this.nodes.root, 'deleted-post'); - } - if (!(strong = $('strong.warning', this.nodes.info))) { - strong = $.el('strong', { - className: 'warning' - }); - $.after($('input', this.nodes.info), strong); - } - strong.textContent = file ? '[File deleted]' : '[Deleted]'; - if (this.isClone) { - return; - } - ref = this.clones; - for (j = 0, len = ref.length; j < len; j++) { - clone = ref[j]; - clone.kill(file, index); - } - if (file) { - return; - } - ref1 = Get.allQuotelinksLinkingTo(this); - for (k = 0, len1 = ref1.length; k < len1; k++) { - quotelink = ref1[k]; - if (!(!$.hasClass(quotelink, 'deadlink'))) { - continue; - } - $.add(quotelink, Post.deadMark.cloneNode(true)); - $.addClass(quotelink, 'deadlink'); - } - }; - - Post.prototype.resurrect = function() { - var clone, j, k, len, len1, quotelink, ref, ref1, strong; - this.isDead = false; - $.rmClass(this.nodes.root, 'deleted-post'); - strong = $('strong.warning', this.nodes.info); - if (this.files.some(function(file) { - return file.isDead; - })) { - $.addClass(this.nodes.root, 'deleted-file'); - strong.textContent = '[File deleted]'; - } else { - $.rm(strong); - } - if (this.isClone) { - return; - } - ref = this.clones; - for (j = 0, len = ref.length; j < len; j++) { - clone = ref[j]; - clone.resurrect(); - } - ref1 = Get.allQuotelinksLinkingTo(this); - for (k = 0, len1 = ref1.length; k < len1; k++) { - quotelink = ref1[k]; - if (!($.hasClass(quotelink, 'deadlink'))) { - continue; - } - $.rm($('.qmark-dead', quotelink)); - $.rmClass(quotelink, 'deadlink'); - } - }; - - Post.prototype.collect = function() { - g.posts.rm(this.fullID); - this.thread.posts.rm(this); - return this.board.posts.rm(this); - }; - - Post.prototype.addClone = function(context, contractThumb) { - Callbacks.Post.execute(this); - return new Post.Clone(this, context, contractThumb); - }; - - Post.prototype.rmClone = function(index) { - var clone, j, len, ref; - this.clones.splice(index, 1); - ref = this.clones.slice(index); - for (j = 0, len = ref.length; j < len; j++) { - clone = ref[j]; - clone.nodes.root.dataset.clone = index++; - } - }; - - Post.prototype.setCatalogOP = function(isCatalogOP) { - this.nodes.root.classList.toggle('catalog-container', isCatalogOP); - this.nodes.root.classList.toggle('opContainer', !isCatalogOP); - this.nodes.post.classList.toggle('catalog-post', isCatalogOP); - this.nodes.post.classList.toggle('op', !isCatalogOP); - return this.nodes.post.style.left = this.nodes.post.style.right = null; - }; - - return Post; - - })(); - - return Post; - -}).call(this); - -(function() { - var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, - hasProp = {}.hasOwnProperty, - slice = [].slice; - - Post.Clone = (function(superClass) { - extend(_Class, superClass); - - _Class.prototype.isClone = true; - - function _Class() { - var that; - that = Object.create(Post.Clone.prototype); - that.construct.apply(that, arguments); - return that; - } - - _Class.prototype.construct = function(origin, context, contractThumb) { - var base, file, fileRoot, fileRoots, i, inline, inlined, j, k, key, l, len, len1, len2, len3, len4, m, node, nodes, originFile, ref, ref1, ref2, ref3, ref4, ref5, ref6, root, selector, val; - this.origin = origin; - this.context = context; - ref = ['ID', 'postID', 'threadID', 'boardID', 'siteID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']; - for (i = 0, len = ref.length; i < len; i++) { - key = ref[i]; - this[key] = this.origin[key]; - } - nodes = this.origin.nodes; - root = contractThumb ? this.cloneWithoutVideo(nodes.root) : nodes.root.cloneNode(true); - (base = Post.Clone).suffix || (base.suffix = 0); - ref1 = [root].concat(slice.call($$('[id]', root))); - for (j = 0, len1 = ref1.length; j < len1; j++) { - node = ref1[j]; - node.id += "_" + Post.Clone.suffix; - } - Post.Clone.suffix++; - ref2 = $$('.inline', root); - for (k = 0, len2 = ref2.length; k < len2; k++) { - inline = ref2[k]; - $.rm(inline); - } - ref3 = $$('.inlined', root); - for (l = 0, len3 = ref3.length; l < len3; l++) { - inlined = ref3[l]; - $.rmClass(inlined, 'inlined'); - } - this.nodes = this.parseNodes(root); - root.hidden = false; - $.rmClass(root, 'forwarded'); - $.rmClass(this.nodes.post, 'highlight'); - if (!this.isReply) { - this.setCatalogOP(false); - $.rm($('.catalog-link', this.nodes.post)); - $.rm($('.catalog-stats', this.nodes.post)); - $.rm($('.catalog-replies', this.nodes.post)); - } - this.parseQuotes(); - this.quotes = slice.call(this.origin.quotes); - this.files = []; - if (this.origin.files.length) { - fileRoots = this.fileRoots(); - } - ref4 = this.origin.files; - for (m = 0, len4 = ref4.length; m < len4; m++) { - originFile = ref4[m]; - file = {}; - for (key in originFile) { - val = originFile[key]; - file[key] = val; - } - fileRoot = fileRoots[file.docIndex]; - ref5 = g.SITE.selectors.file; - for (key in ref5) { - selector = ref5[key]; - file[key] = $(selector, fileRoot); - } - file.thumbLink = (ref6 = file.thumb) != null ? ref6.parentNode : void 0; - if (file.thumbLink) { - file.fullImage = $('.full-image', file.thumbLink); - } - file.videoControls = $('.video-controls', file.text); - if (file.videoThumb) { - file.thumb.muted = true; - } - this.files.push(file); - } - if (this.files.length) { - this.file = this.files[0]; - if (this.file.thumb && contractThumb) { - ImageExpand.contract(this); - } - } - if (this.origin.isDead) { - this.isDead = true; - } - return root.dataset.clone = this.origin.clones.push(this) - 1; - }; - - _Class.prototype.cloneWithoutVideo = function(node) { - var child, clone, i, len, ref; - if (node.tagName === 'VIDEO' && !node.dataset.md5) { - return []; - } else if (node.nodeType === Node.ELEMENT_NODE && $('video', node)) { - clone = node.cloneNode(false); - ref = node.childNodes; - for (i = 0, len = ref.length; i < len; i++) { - child = ref[i]; - $.add(clone, this.cloneWithoutVideo(child)); - } - return clone; - } else { - return node.cloneNode(true); - } - }; - - return _Class; - - })(Post); - -}).call(this); - -RandomAccessList = (function() { - var RandomAccessList; - - RandomAccessList = (function() { - function RandomAccessList(items) { - var i, item, len; - this.length = 0; - if (items) { - for (i = 0, len = items.length; i < len; i++) { - item = items[i]; - this.push(item); - } - } - } - - RandomAccessList.prototype.push = function(data) { - var ID, item, last; - ID = data.ID; - ID || (ID = data.id); - if (this[ID]) { - return; - } - last = this.last; - this[ID] = item = { - prev: last, - next: null, - data: data, - ID: ID - }; - item.prev = last; - this.last = last ? last.next = item : this.first = item; - return this.length++; - }; - - RandomAccessList.prototype.before = function(root, item) { - var prev; - if (item.next === root || item === root) { - return; - } - this.rmi(item); - prev = root.prev; - root.prev = item; - item.next = root; - item.prev = prev; - if (prev) { - return prev.next = item; - } else { - return this.first = item; - } - }; - - RandomAccessList.prototype.after = function(root, item) { - var next; - if (item.prev === root || item === root) { - return; - } - this.rmi(item); - next = root.next; - root.next = item; - item.prev = root; - item.next = next; - if (next) { - return next.prev = item; - } else { - return this.last = item; - } - }; - - RandomAccessList.prototype.prepend = function(item) { - var first; - first = this.first; - if (item === first || !this[item.ID]) { - return; - } - this.rmi(item); - item.next = first; - if (first) { - first.prev = item; - } else { - this.last = item; - } - this.first = item; - return delete item.prev; - }; - - RandomAccessList.prototype.shift = function() { - return this.rm(this.first.ID); - }; - - RandomAccessList.prototype.order = function() { - var item, order; - order = [item = this.first]; - while (item = item.next) { - order.push(item); - } - return order; - }; - - RandomAccessList.prototype.rm = function(ID) { - var item; - item = this[ID]; - if (!item) { - return; - } - delete this[ID]; - this.length--; - this.rmi(item); - delete item.next; - return delete item.prev; - }; - - RandomAccessList.prototype.rmi = function(item) { - var next, prev; - prev = item.prev, next = item.next; - if (prev) { - prev.next = next; - } else { - this.first = next; - } - if (next) { - return next.prev = prev; - } else { - return this.last = prev; - } - }; - - return RandomAccessList; - - })(); - - return RandomAccessList; - -}).call(this); - -ShimSet = (function() { - var ShimSet; - - ShimSet = (function() { - function ShimSet() { - this.elements = $.dict(); - this.size = 0; - } - - ShimSet.prototype.has = function(value) { - return value in this.elements; - }; - - ShimSet.prototype.add = function(value) { - if (this.elements[value]) { - return; - } - this.elements[value] = true; - return this.size++; - }; - - ShimSet.prototype["delete"] = function(value) { - if (!this.elements[value]) { - return; - } - delete this.elements[value]; - return this.size--; - }; - - return ShimSet; - - })(); - - if (!('Set' in window)) { - window.Set = ShimSet; - } - - return ShimSet; - -}).call(this); - -SimpleDict = (function() { - var SimpleDict, - slice = [].slice; - - SimpleDict = (function() { - function SimpleDict() { - this.keys = []; - } - - SimpleDict.prototype.push = function(key, data) { - key = "" + key; - if (!this[key]) { - this.keys.push(key); - } - return this[key] = data; - }; - - SimpleDict.prototype.rm = function(key) { - var i; - key = "" + key; - if ((i = this.keys.indexOf(key)) !== -1) { - this.keys.splice(i, 1); - return delete this[key]; - } - }; - - SimpleDict.prototype.forEach = function(fn) { - var j, key, len, ref; - ref = slice.call(this.keys); - for (j = 0, len = ref.length; j < len; j++) { - key = ref[j]; - fn(this[key]); - } - }; - - SimpleDict.prototype.get = function(key) { - if (key === 'keys') { - return void 0; - } else { - return $.getOwn(this, key); - } - }; - - return SimpleDict; - - })(); - - return SimpleDict; - -}).call(this); - -Thread = (function() { - var Thread; - - Thread = (function() { - Thread.prototype.toString = function() { - return this.ID; - }; - - function Thread(ID, board) { - this.board = board; - this.ID = +ID; - this.threadID = this.ID; - this.boardID = this.board.ID; - this.siteID = g.SITE.ID; - this.fullID = this.board + "." + this.ID; - this.posts = new SimpleDict(); - this.isDead = false; - this.isHidden = false; - this.isSticky = false; - this.isClosed = false; - this.isArchived = false; - this.postLimit = false; - this.fileLimit = false; - 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); - g.threads.push(this.fullID, this); - } - - Thread.prototype.setPage = function(pageNum) { - var icon, info, ref, reply; - ref = this.OP.nodes, info = ref.info, reply = ref.reply; - if (!(icon = $('.page-num', info))) { - icon = $.el('span', { - className: 'page-num' - }); - $.replace(reply.parentNode.previousSibling, [$.tn(' '), icon, $.tn(' ')]); - } - icon.title = "This thread is on page " + pageNum + " in the original index."; - icon.textContent = "[" + pageNum + "]"; - if (this.catalogView) { - return this.catalogView.nodes.pageCount.textContent = pageNum; - } - }; - - Thread.prototype.setCount = function(type, count, reachedLimit) { - var el; - if (!this.catalogView) { - return; - } - el = this.catalogView.nodes[type + "Count"]; - el.textContent = count; - return (reachedLimit ? $.addClass : $.rmClass)(el, 'warning'); - }; - - Thread.prototype.setStatus = function(type, status) { - var name; - name = "is" + type; - if (this[name] === status) { - return; - } - this[name] = status; - if (!this.OP) { - return; - } - this.setIcon('Sticky', this.isSticky); - this.setIcon('Closed', this.isClosed && !this.isArchived); - return this.setIcon('Archived', this.isArchived); - }; - - Thread.prototype.setIcon = function(type, status) { - var icon, root, typeLC; - typeLC = type.toLowerCase(); - icon = $("." + typeLC + "Icon", this.OP.nodes.info); - if (!!icon === status) { - return; - } - if (!status) { - $.rm(icon.previousSibling); - $.rm(icon); - if (this.catalogView) { - $.rm($("." + typeLC + "Icon", this.catalogView.nodes.icons)); - } - return; - } - icon = $.el('img', { - src: "" + g.SITE.Build.staticPath + typeLC + g.SITE.Build.gifIcon, - alt: type, - title: type, - className: typeLC + "Icon retina" - }); - if (g.BOARD.ID === 'f') { - icon.style.cssText = 'height: 18px; width: 18px;'; - } - root = type !== 'Sticky' && this.isSticky ? $('.stickyIcon', this.OP.nodes.info) : $('.page-num', this.OP.nodes.info) || this.OP.nodes.quote; - $.after(root, [$.tn(' '), icon]); - if (!this.catalogView) { - return; - } - return (type === 'Sticky' && this.isClosed ? $.prepend : $.add)(this.catalogView.nodes.icons, icon.cloneNode()); - }; - - Thread.prototype.kill = function() { - return this.isDead = true; - }; - - Thread.prototype.collect = function() { - var n; - n = 0; - this.posts.forEach(function(post) { - if (post.clones.length) { - return n++; - } else { - return post.collect(); - } - }); - if (!n) { - g.threads.rm(this.fullID); - return this.board.threads.rm(this); - } - }; - - return Thread; - - })(); - - return Thread; - -}).call(this); - -SW = {}; - -(function() { - var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - SW.tinyboard = { - isOPContainerThread: true, - mayLackJSON: true, - threadModTimeIgnoresSage: true, - 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: function() { - var j, len, m, properties, ref, root, script; - ref = $$('script:not([src])', d.head); - for (j = 0, len = ref.length; j < len; j++) { - script = ref[j]; - if ((m = script.textContent.match(/\bvar configRoot=(".*?")/))) { - properties = $.dict(); - try { - root = JSON.parse(m[1]); - if (root[0] === '/') { - properties.root = location.origin + root; - } else if (/^https?:/.test(root)) { - properties.root = root; - } - } catch (error) {} - return properties; - } - } - return false; - }, - awaitBoard: function(cb) { - var reactUI, s; - if ((reactUI = $.id('react-ui'))) { - s = this.selectors = Object.create(this.selectors); - s.boardFor = { - index: '.page-container' - }; - s.thread = 'div[id^="thread_"]'; - return Main.mounted(cb); - } else { - return cb(); - } - }, - urls: { - thread: function(arg, isArchived) { - var boardID, ref, siteID, threadID; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID; - return "" + (((ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0) || ("http://" + siteID + "/")) + boardID + "/" + (isArchived ? 'archive/' : '') + "res/" + threadID + ".html"; - }, - post: function(arg) { - var postID; - postID = arg.postID; - return "#" + postID; - }, - index: function(arg) { - var boardID, ref, siteID; - siteID = arg.siteID, boardID = arg.boardID; - return "" + (((ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0) || ("http://" + siteID + "/")) + boardID + "/"; - }, - catalog: function(arg) { - var boardID, ref, siteID; - siteID = arg.siteID, boardID = arg.boardID; - return "" + (((ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0) || ("http://" + siteID + "/")) + boardID + "/catalog.html"; - }, - threadJSON: function(arg, isArchived) { - var boardID, ref, root, siteID, threadID; - siteID = arg.siteID, boardID = arg.boardID, threadID = arg.threadID; - root = (ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0; - if (root) { - return "" + root + boardID + "/" + (isArchived ? 'archive/' : '') + "res/" + threadID + ".json"; - } else { - return ''; - } - }, - archivedThreadJSON: function(thread) { - return SW.tinyboard.urls.threadJSON(thread, true); - }, - threadsListJSON: function(arg) { - var boardID, ref, root, siteID; - siteID = arg.siteID, boardID = arg.boardID; - root = (ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0; - if (root) { - return "" + root + boardID + "/threads.json"; - } else { - return ''; - } - }, - archiveListJSON: function(arg) { - var boardID, ref, root, siteID; - siteID = arg.siteID, boardID = arg.boardID; - root = (ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0; - if (root) { - return "" + root + boardID + "/archive/archive.json"; - } else { - return ''; - } - }, - catalogJSON: function(arg) { - var boardID, ref, root, siteID; - siteID = arg.siteID, boardID = arg.boardID; - root = (ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0; - if (root) { - return "" + root + boardID + "/catalog.json"; - } else { - return ''; - } - }, - file: function(arg, filename) { - var boardID, ref, siteID; - siteID = arg.siteID, boardID = arg.boardID; - return "" + (((ref = Conf['siteProperties'][siteID]) != null ? ref.root : void 0) || ("http://" + siteID + "/")) + boardID + "/" + filename; - }, - thumb: function(board, filename) { - return SW.tinyboard.urls.file(board, filename); - } - }, - 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: /\/([^\/]+)\/res\/(\d+)(?:\.\w+)?#(\d+)$/, - quotelinkHTML: /]*\bhref="[^"]*\/([^\/]+)\/res\/(\d+)(?:\.\w+)?#(\d+)"/g - }, - Build: { - parseJSON: function(data, board) { - var extra_file, file, i, j, len, o, ref; - o = SW.yotsuba.Build.parseJSON(data, board); - if (data.ext === 'deleted') { - delete o.file; - $.extend(o, { - files: [], - fileDeleted: true, - filesDeleted: [0] - }); - } - if (data.extra_files) { - ref = data.extra_files; - for (i = j = 0, len = ref.length; j < len; i = ++j) { - extra_file = ref[i]; - if (extra_file.ext === 'deleted') { - o.filesDeleted.push(i); - } else { - file = SW.yotsuba.Build.parseJSONFile(data, board); - o.files.push(file); - } - } - if (o.files.length) { - o.file = o.files[0]; - } - } - return o; - }, - parseComment: function(html) { - html = html.replace(//gi, '\n').replace(/<[^>]*>/g, ''); - return $.unescape(html); - } - }, - bgColoredEl: function() { - return $.el('div', { - className: 'post reply' - }); - }, - isFileURL: function(url) { - return /\/src\/[^\/]+/.test(url.pathname); - }, - preParsingFixes: function(board) { - var broken; - if ((broken = $('a > input[name="board"]', board))) { - return $.before(broken.parentNode, broken); - } - }, - parseNodes: function(post, nodes) { - var m, nextSibling, node, text, uniqueID; - if (nodes.uniqueID) { - return; - } - text = ''; - node = nodes.nameBlock.nextSibling; - while (node && node.nodeType === 3) { - text += node.textContent; - node = node.nextSibling; - } - if ((m = text.match(/(\s*ID:\s*)(\S+)/))) { - nodes.info.normalize(); - nextSibling = nodes.nameBlock.nextSibling; - nextSibling = nextSibling.splitText(m[1].length); - nextSibling.splitText(m[2].length); - nodes.uniqueID = uniqueID = $.el('span', { - className: 'poster_id' - }); - $.replace(nextSibling, uniqueID); - return $.add(uniqueID, nextSibling); - } - }, - parseDate: function(node) { - var date, ref; - date = Date.parse((ref = node.getAttribute('datetime')) != null ? ref.trim() : void 0); - if (!isNaN(date)) { - return new Date(date); - } - date = Date.parse(node.textContent.trim() + ' UTC'); - if (!isNaN(date)) { - return new Date(date); - } - return void 0; - }, - parseFile: function(post, file) { - var info, infoNode, link, nameNode, ref, ref1, text, thumb; - text = file.text, link = file.link, thumb = file.thumb; - if ($.x("ancestor::" + this.xpath.postContainer + "[1]", text) !== post.nodes.root) { - return false; - } - if (!(infoNode = indexOf.call((ref = link.nextSibling) != null ? ref.textContent : void 0, '(') >= 0 ? link.nextSibling : link.nextElementSibling)) { - return false; - } - if (!(info = infoNode.textContent.match(/\((.*,\s*)?([\d.]+ ?[KMG]?B).*\)/))) { - return false; - } - nameNode = $('.postfilename', text); - $.extend(file, { - name: nameNode ? nameNode.title || nameNode.textContent : link.pathname.match(/[^\/]*$/)[0], - size: info[2], - dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0 - }); - if (thumb) { - $.extend(file, { - thumbURL: /\/static\//.test(thumb.src) && $.isImage(link.href) ? link.href : thumb.src, - isSpoiler: /^Spoiler/i.test(info[1] || '') || link.textContent === 'Spoiler Image' - }); - } - return true; - }, - isThumbExpanded: function(file) { - return $.hasClass(file.thumb.parentNode, 'expanded') || file.thumb.parentNode.dataset.expanded === 'true'; - }, - isLinkified: function(link) { - return /\bnofollow\b/.test(link.rel); - }, - catalogPin: function(threadRoot) { - return threadRoot.dataset.sticky = 'true'; - } - }; - -}).call(this); - -(function() { - var slice = [].slice; - - SW.yotsuba = { - isOPContainerThread: false, - hasIPCount: true, - archivedBoardsKnown: true, - urls: { - thread: function(arg) { - var boardID, threadID; - boardID = arg.boardID, threadID = arg.threadID; - return location.protocol + "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/thread/" + threadID; - }, - post: function(arg) { - var postID; - postID = arg.postID; - return "#p" + postID; - }, - index: function(arg) { - var boardID; - boardID = arg.boardID; - return location.protocol + "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/"; - }, - catalog: function(arg) { - var boardID; - boardID = arg.boardID; - if (boardID === 'f') { - return void 0; - } else { - return location.protocol + "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/catalog"; - } - }, - archive: function(arg) { - var boardID; - boardID = arg.boardID; - if (BoardConfig.isArchived(boardID)) { - return location.protocol + "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/archive"; - } else { - return void 0; - } - }, - threadJSON: function(arg) { - var boardID, threadID; - boardID = arg.boardID, threadID = arg.threadID; - return location.protocol + "//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json"; - }, - threadsListJSON: function(arg) { - var boardID; - boardID = arg.boardID; - return location.protocol + "//a.4cdn.org/" + boardID + "/threads.json"; - }, - archiveListJSON: function(arg) { - var boardID; - boardID = arg.boardID; - if (BoardConfig.isArchived(boardID)) { - return location.protocol + "//a.4cdn.org/" + boardID + "/archive.json"; - } else { - return ''; - } - }, - catalogJSON: function(arg) { - var boardID; - boardID = arg.boardID; - return location.protocol + "//a.4cdn.org/" + boardID + "/catalog.json"; - }, - file: function(arg, filename) { - var boardID, hostname; - boardID = arg.boardID; - hostname = boardID === 'f' ? ImageHost.flashHost() : ImageHost.host(); - return location.protocol + "//" + hostname + "/" + boardID + "/" + filename; - }, - thumb: function(arg, filename) { - var boardID; - boardID = arg.boardID; - return location.protocol + "//" + (ImageHost.thumbHost()) + "/" + boardID + "/" + filename; - } - }, - isPrunedByAge: function(arg) { - var boardID; - boardID = arg.boardID; - return boardID === 'f'; - }, - areMD5sDeferred: function(arg) { - var boardID; - boardID = arg.boardID; - return boardID === 'f'; - }, - isOnePage: function(arg) { - var boardID; - boardID = arg.boardID; - return boardID === 'f'; - }, - noAudio: function(arg) { - var boardID; - boardID = arg.boardID; - return BoardConfig.noAudio(boardID); - }, - 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: /^https?:\/\/boards\.4chan(?:nel)?\.org\/+([^\/]+)\/+thread\/+(\d+)(?:[\/?][^#]*)?(?:#p(\d+))?$/, - quotelinkHTML: /]*\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: function() { - return $.el('div', { - className: 'reply' - }); - }, - isThisPageLegit: function() { - var ref, ref1; - return ((ref = location.hostname) === 'boards.4chan.org' || ref === 'boards.4channel.org') && d.doctype && !$('link[href*="favicon-status.ico"]', d.head) && ((ref1 = d.title) !== '4chan - Temporarily Offline' && ref1 !== '4chan - Error' && ref1 !== '504 Gateway Time-out' && ref1 !== 'MathJax Equation Source'); - }, - is404: function() { - var ref; - return ((ref = d.title) === '4chan - Temporarily Offline' || ref === '4chan - 404 Not Found') || (g.VIEW === 'thread' && $('.board') && !$('.opContainer')); - }, - isIncomplete: function() { - var ref; - return ((ref = g.VIEW) === 'index' || ref === 'thread') && !$('.board + *'); - }, - isBoardlessPage: function(url) { - var ref; - return (ref = url.hostname) === 'www.4chan.org' || ref === 'www.4channel.org'; - }, - isAuxiliaryPage: function(url) { - var ref; - return (ref = url.hostname) !== 'boards.4chan.org' && ref !== 'boards.4channel.org'; - }, - isFileURL: function(url) { - return ImageHost.test(url.hostname); - }, - initAuxiliary: function() { - var match, pathname; - switch (location.hostname) { - case 'www.4chan.org': - case 'www.4channel.org': - if (SW.yotsuba.regexp.pass.test(location.href)) { - PassMessage.init(); - } else { - $.onExists(doc, 'body', function() { - return $.addStyle(CSS.www); - }); - Captcha.replace.init(); - } - break; - case 'sys.4chan.org': - case 'sys.4channel.org': - pathname = location.pathname.split(/\/+/); - if (pathname[2] === 'imgboard.php') { - if (/\bmode=report\b/.test(location.search)) { - Report.init(); - } else if ((match = location.search.match(/\bres=(\d+)/))) { - $.ready(function() { - var ref; - if (Conf['404 Redirect'] && ((ref = $.id('errmsg')) != null ? ref.textContent : void 0) === 'Error: Specified thread does not exist.') { - return Redirect.navigate('thread', { - boardID: g.BOARD.ID, - postID: +match[1] - }); - } - }); - } - } else if (pathname[2] === 'post') { - PostSuccessful.init(); - } - } - }, - scriptData: function() { - var j, len, ref, script; - ref = $$('script:not([src])', d.head); - for (j = 0, len = ref.length; j < len; j++) { - script = ref[j]; - if (/\bcooldowns *=/.test(script.textContent)) { - return script.textContent; - } - } - return ''; - }, - parseThreadMetadata: function(thread) { - var file, m, scriptData; - scriptData = this.scriptData(); - thread.postLimit = /\bbumplimit *= *1\b/.test(scriptData); - thread.fileLimit = /\bimagelimit *= *1\b/.test(scriptData); - thread.ipCount = (m = scriptData.match(/\bunique_ips *= *(\d+)\b/)) ? +m[1] : void 0; - if (g.BOARD.ID === 'f' && thread.OP.file) { - file = thread.OP.file; - return $.ajax(this.urls.threadJSON({ - boardID: 'f', - threadID: thread.ID - }), { - timeout: $.MINUTE, - onloadend: function() { - if (this.response) { - return file.text.dataset.md5 = file.MD5 = this.response.posts[0].md5; - } - } - }); - } - }, - parseNodes: function(post, nodes) { - var icon, j, len, ref, results, type; - if (post.boardID === 'f') { - ref = ['Sticky', 'Closed']; - results = []; - for (j = 0, len = ref.length; j < len; j++) { - type = ref[j]; - if ((icon = $("img[alt=" + type + "]", nodes.info))) { - results.push($.addClass(icon, (type.toLowerCase()) + "Icon", 'retina')); - } - } - return results; - } - }, - parseDate: function(node) { - return new Date(node.dataset.utc * 1000); - }, - parseFile: function(post, file) { - var info, link, m, ref, ref1, ref2, text, thumb; - text = file.text, link = file.link, thumb = file.thumb; - if (!(info = (ref = link.nextSibling) != null ? ref.textContent.match(/\(([\d.]+ [KMG]?B).*\)/) : void 0)) { - return false; - } - $.extend(file, { - name: text.title || link.title || link.textContent, - size: info[1], - dimensions: (ref1 = info[0].match(/\d+x\d+/)) != null ? ref1[0] : void 0, - tag: (ref2 = info[0].match(/,[^,]*, ([a-z]+)\)/i)) != null ? ref2[1] : void 0, - MD5: text.dataset.md5 - }); - if (thumb) { - $.extend(file, { - thumbURL: thumb.src, - MD5: thumb.dataset.md5, - isSpoiler: $.hasClass(thumb.parentNode, 'imgspoiler') - }); - if (file.isSpoiler) { - file.thumbURL = (m = link.href.match(/\d+(?=\.\w+$)/)) ? location.protocol + "//" + (ImageHost.thumbHost()) + "/" + post.board + "/" + m[0] + "s.jpg" : void 0; - } - } - return true; - }, - cleanComment: function(bq) { - var abbr, br, i, j, k, len, node, ref; - if ((abbr = $('.abbr', bq))) { - ref = $$('.abbr + br, .exif', bq); - for (j = 0, len = ref.length; j < len; j++) { - node = ref[j]; - $.rm(node); - } - for (i = k = 0; k < 2; i = ++k) { - if ((br = abbr.previousSibling) && br.nodeName === 'BR') { - $.rm(br); - } - } - return $.rm(abbr); - } - }, - cleanCommentDisplay: function(bq) { - var b; - if ((b = $('b', bq)) && /^Rolled /.test(b.textContent)) { - $.rm(b); - } - return $.rm($('.fortune', bq)); - }, - insertTags: function(bq) { - var j, k, len, len1, node, ref, ref1; - ref = $$('s, .removed-spoiler', bq); - for (j = 0, len = ref.length; j < len; j++) { - node = ref[j]; - $.replace(node, [$.tn('[spoiler]')].concat(slice.call(node.childNodes), [$.tn('[/spoiler]')])); - } - ref1 = $$('.prettyprint', bq); - for (k = 0, len1 = ref1.length; k < len1; k++) { - node = ref1[k]; - $.replace(node, [$.tn('[code]')].concat(slice.call(node.childNodes), [$.tn('[/code]')])); - } - }, - hasCORS: function(url) { - return url.split('/').slice(0, 3).join('/') === location.protocol + '//a.4cdn.org'; - }, - sfwBoards: function(sfw) { - return BoardConfig.sfwBoards(sfw); - }, - uidColor: function(uid) { - var i, msg; - msg = 0; - i = 0; - while (i < 8) { - msg = (msg << 5) - msg + uid.charCodeAt(i++); - } - return (msg >> 8) & 0xFFFFFF; - }, - isLinkified: function(link) { - return ImageHost.test(link.hostname); - }, - testNativeExtension: function() { - return $.global(function() { - if (window.Parser.postMenuIcon) { - return this.enabled = 'true'; - } - }); - }, - transformBoardList: function() { - var a, chr, i, items, j, len, node, nodes, ref, spacer, span; - nodes = []; - spacer = function() { - return $.el('span', { - className: 'spacer' - }); - }; - items = $.X('.//a|.//text()[not(ancestor::a)]', $(SW.yotsuba.selectors.boardList)); - i = 0; - while (node = items.snapshotItem(i++)) { - switch (node.nodeName) { - case '#text': - ref = node.nodeValue; - for (j = 0, len = ref.length; j < len; j++) { - chr = ref[j]; - span = $.el('span', { - textContent: chr - }); - if (chr === ' ') { - span.className = 'space'; - } - if (chr === ']') { - nodes.push(spacer()); - } - nodes.push(span); - if (chr === '[') { - nodes.push(spacer()); - } - } - break; - case 'A': - a = node.cloneNode(true); - nodes.push(a); - } - } - return nodes; - } - }; - -}).call(this); - -(function() { - var Build, - slice = [].slice; - - Build = { - staticPath: '//s.4cdn.org/image/', - gifIcon: window.devicePixelRatio >= 2 ? '@2x.gif' : '.gif', - spoilerRange: $.dict(), - shortFilename: function(filename) { - var ext; - ext = filename.match(/\.?[^\.]*$/)[0]; - if (filename.length - ext.length > 30) { - return (filename.match(/(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[^]){0,25}/)[0]) + "(...)" + ext; - } else { - return filename; - } - }, - spoilerThumb: function(boardID) { - var spoilerRange; - if (spoilerRange = Build.spoilerRange[boardID]) { - return Build.staticPath + "spoiler-" + boardID + (Math.floor(1 + spoilerRange * Math.random())) + ".png"; - } else { - return Build.staticPath + "spoiler.png"; - } - }, - sameThread: function(boardID, threadID) { - return g.VIEW === 'thread' && g.BOARD.ID === boardID && g.THREADID === +threadID; - }, - threadURL: function(boardID, threadID) { - if (boardID !== g.BOARD.ID) { - return "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/thread/" + threadID; - } else if (g.VIEW !== 'thread' || +threadID !== g.THREADID) { - return "/" + boardID + "/thread/" + threadID; - } else { - return ''; - } - }, - postURL: function(boardID, threadID, postID) { - return (Build.threadURL(boardID, threadID)) + "#p" + postID; - }, - parseJSON: function(data, arg) { - var boardID, key, o, siteID; - siteID = arg.siteID, boardID = arg.boardID; - o = { - ID: data.no, - postID: data.no, - threadID: data.resto || data.no, - boardID: boardID, - siteID: siteID, - isReply: !!data.resto, - isSticky: !!data.sticky, - isClosed: !!data.closed, - isArchived: !!data.archived, - fileDeleted: !!data.filedeleted, - filesDeleted: data.filedeleted ? [0] : [] - }; - o.info = { - subject: $.unescape(data.sub), - email: $.unescape(data.email), - name: $.unescape(data.name) || '', - tripcode: data.trip, - pass: data.since4pass != null ? "" + data.since4pass : void 0, - uniqueID: data.id, - flagCode: data.country, - flagCodeTroll: data.board_flag, - flag: $.unescape(data.country_name || data.flag_name), - dateUTC: data.time, - dateText: data.now, - commentHTML: { - innerHTML: data.com || '' - } - }; - if (data.capcode) { - o.info.capcode = data.capcode.replace(/_highlight$/, '').replace(/_/g, ' ').replace(/\b\w/g, function(c) { - return c.toUpperCase(); - }); - o.capcodeHighlight = /_highlight$/.test(data.capcode); - delete o.info.uniqueID; - } - o.files = []; - if (data.ext) { - o.file = SW.yotsuba.Build.parseJSONFile(data, { - siteID: siteID, - boardID: boardID - }); - o.files.push(o.file); - } - o.extra = $.dict(); - for (key in data) { - if (key[0] === 'x') { - o.extra[key] = data[key]; - } - } - return o; - }, - parseJSONFile: function(data, arg) { - var boardID, filename, o, site, siteID; - siteID = arg.siteID, boardID = arg.boardID; - site = g.sites[siteID]; - filename = site.software === 'yotsuba' && boardID === 'f' ? "" + (encodeURIComponent(data.filename)) + data.ext : "" + data.tim + data.ext; - o = { - name: ($.unescape(data.filename)) + data.ext, - url: site.urls.file({ - siteID: siteID, - boardID: boardID - }, filename), - height: data.h, - width: data.w, - MD5: data.md5, - size: $.bytesToString(data.fsize), - thumbURL: site.urls.thumb({ - siteID: siteID, - boardID: boardID - }, data.tim + "s.jpg"), - theight: data.tn_h, - twidth: data.tn_w, - isSpoiler: !!data.spoiler, - tag: data.tag, - hasDownscale: !!data.m_img - }; - if ((data.h != null) && !/\.pdf$/.test(o.url)) { - o.dimensions = o.width + "x" + o.height; - } - return o; - }, - parseComment: function(html) { - html = html.replace(//gi, '\n').replace(/\n\n]*>/g, ''); - return $.unescape(html); - }, - parseCommentDisplay: function(html) { - var html2; - if (!(Conf['Remove Spoilers'] || Conf['Reveal Spoilers'])) { - while ((html2 = html.replace(/(?:(?!<\/?s>).)*<\/s>/g, '[spoiler]')) !== html) { - html = html2; - } - } - html = html.replace(/^Rolled [^<]*<\/b>/i, '').replace(/ " + ((!o.isReply || boardID === "f" || subject) ? "" + E(subject || "") + " " : "") + "" + ((email) ? "" : "") + "" + E(name) + "" + ((tripcode) ? " " + E(tripcode) + "" : "") + ((pass) ? " " : "") + ((capcode) ? " ## " + E(capcode) + "" : "") + ((email) ? "" : "") + ((boardID === "f" && !o.isReply || capcodeDescription) ? "" : " ") + ((capcodeDescription) ? " \""" : "") + ((uniqueID && !capcode) ? " (ID: " + E(uniqueID) + ")" : "") + ((flagCode) ? " " : "") + ((flagCodeTroll) ? " " : "") + " " + E(dateText) + " No." + E(ID) + "" + ((o.isSticky) ? " \"Sticky\"" : "") + ((o.isClosed && !o.isArchived) ? " \"Closed\"" : "") + ((o.isArchived) ? " \"Archived\"" : "") + ((!o.isReply && g.VIEW === "index") ? "   [Reply]" : "") + ""}; - - /* File Info */ - if (file) { - protocol = /^https?:(?=\/\/i\.4cdn\.org\/)/; - fileURL = file.url.replace(protocol, ''); - shortFilename = Build.shortFilename(file.name); - fileThumb = file.isSpoiler ? Build.spoilerThumb(boardID) : file.thumbURL.replace(protocol, ''); - } - fileBlock = {innerHTML: ((file) ? "
      " + ((boardID === "f") ? "
      File: " + E(file.name) + "-(" + E(file.size) + ", " + E(file.dimensions) + ((file.tag) ? ", " + E(file.tag) : "") + ")
      " : "
      File: " + ((file.isSpoiler) ? "Spoiler Image" : E(shortFilename)) + " (" + E(file.size) + ", " + E(file.dimensions || "PDF") + ")
      \""") + "
      " : ((o.fileDeleted) ? "
      \"File
      " : ""))}; - - /* Whole Post */ - postClass = o.isReply ? 'reply' : 'op'; - wholePost = {innerHTML: ((o.isReply) ? "
      >>
      " : "") + "
      " + ((o.isReply) ? (postInfo).innerHTML + (fileBlock).innerHTML : (fileBlock).innerHTML + (postInfo).innerHTML) + "
      " + (commentHTML).innerHTML + "
      "}; - container = $.el('div', { - className: "postContainer " + postClass + "Container", - id: "pc" + ID - }); - $.extend(container, wholePost); - ref1 = $$('.quotelink', container); - for (i = 0, len = ref1.length; i < len; i++) { - quote = ref1[i]; - href = quote.getAttribute('href'); - if (href[0] === '#') { - if (!Build.sameThread(boardID, threadID)) { - quote.href = Build.threadURL(boardID, threadID) + href; - } - } else { - if ((match = quote.href.match(SW.yotsuba.regexp.quotelink)) && (Build.sameThread(match[1], match[2]))) { - quote.href = href.match(/(#[^#]*)?$/)[0] || '#'; - } - } - } - return container; - }, - summaryText: function(status, posts, files) { - var text; - text = ''; - if (status) { - text += status + " "; - } - text += posts + " post" + (posts > 1 ? 's' : ''); - if (+files) { - text += " and " + files + " image repl" + (files > 1 ? 'ies' : 'y'); - } - return text += " " + (status === '-' ? 'shown' : 'omitted') + "."; - }, - summary: function(boardID, threadID, posts, files) { - return $.el('a', { - className: 'summary', - textContent: Build.summaryText('', posts, files), - href: "/" + boardID + "/thread/" + threadID - }); - }, - thread: function(thread, data, withReplies) { - var files, posts, ref, root, summary; - if ((root = thread.nodes.root)) { - $.rmAll(root); - } else { - thread.nodes.root = root = $.el('div', { - className: 'thread', - id: "t" + data.no - }); - } - if (Build.hat) { - $.add(root, Build.hat.cloneNode(false)); - } - $.add(root, thread.OP.nodes.root); - if (data.omitted_posts || !withReplies && data.replies) { - ref = withReplies ? [ - data.omitted_posts, data.images - data.last_replies.filter(function(data) { - return !!data.ext; - }).length - ] : [data.replies, data.images], posts = ref[0], files = ref[1]; - summary = Build.summary(thread.board.ID, data.no, posts, files); - $.add(root, summary); - } - return root; - }, - catalogThread: function(thread, data, pageCount) { - var br, container, cssText, fileCount, gifIcon, i, imgClass, len, postCount, ratio, ref, root, spoilerRange, src, staticPath, tn_h, tn_w; - staticPath = Build.staticPath, gifIcon = Build.gifIcon; - tn_w = data.tn_w, tn_h = data.tn_h; - if (data.spoiler && !Conf['Reveal Spoiler Thumbnails']) { - src = staticPath + "spoiler"; - if (spoilerRange = Build.spoilerRange[thread.board]) { - src += ("-" + thread.board) + Math.floor(1 + spoilerRange * Math.random()); - } - src += '.png'; - imgClass = 'spoiler-file'; - cssText = "--tn-w: 100; --tn-h: 100;"; - } else if (data.filedeleted) { - src = staticPath + "filedeleted-res" + gifIcon; - imgClass = 'deleted-file'; - } else if (thread.OP.file) { - src = thread.OP.file.thumbURL; - ratio = 250 / Math.max(tn_w, tn_h); - cssText = "--tn-w: " + (tn_w * ratio) + "; --tn-h: " + (tn_h * ratio) + ";"; - } else { - src = staticPath + "nofile.png"; - imgClass = 'no-file'; - } - postCount = data.replies + 1; - fileCount = data.images + !!data.ext; - container = $.el('div', {innerHTML: "
      " + E(postCount) + " / " + E(fileCount) + " / " + E(pageCount) + "" + ((thread.isSticky) ? "" : "") + ((thread.isClosed) ? "" : "") + "
      "}); - $.before(thread.OP.nodes.info, slice.call(container.childNodes)); - ref = $$('br', thread.OP.nodes.comment); - for (i = 0, len = ref.length; i < len; i++) { - br = ref[i]; - if (br.previousSibling && br.previousSibling.nodeName === 'BR') { - $.addClass(br, 'extra-linebreak'); - } - } - root = $.el('div', { - className: 'thread catalog-thread', - id: "t" + thread - }); - if (thread.OP.highlights) { - $.addClass.apply($, [root].concat(slice.call(thread.OP.highlights))); - } - if (!thread.OP.file) { - $.addClass(root, 'noFile'); - } - root.style.cssText = cssText || ''; - return root; - }, - catalogReply: function(thread, data) { - var excerpt, link; - excerpt = ''; - if (data.com) { - excerpt = Build.parseCommentDisplay(data.com).replace(/>>\d+/g, '').trim().replace(/\n+/g, ' // '); - } - if (data.ext) { - excerpt || (excerpt = "" + ($.unescape(data.filename)) + data.ext); - } - if (data.com) { - excerpt || (excerpt = $.unescape(data.com.replace(//gi, ' // '))); - } - excerpt || (excerpt = '\xA0'); - if (excerpt.length > 73) { - excerpt = excerpt.slice(0, 70) + "..."; - } - link = Build.postURL(thread.board.ID, thread.ID, data.no); - return $.el('div', { - className: 'catalog-reply' - }, {innerHTML: ": " + E(excerpt) + "..."}); - } - }; - - SW.yotsuba.Build = Build; - -}).call(this); - -Site = (function() { - var Site; - - Site = { - 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: function(cb) { - var hostname; - $.extend(Conf['siteProperties'], Site.defaultProperties); - hostname = Site.resolve(); - if (hostname && $.hasOwn(SW, Conf['siteProperties'][hostname].software)) { - this.set(hostname); - cb(); - } - return $.onExists(doc, 'body', (function(_this) { - return function() { - var base, base1, changed, changes, key, properties, software; - for (software in SW) { - if (!((changes = typeof (base = SW[software]).detect === "function" ? base.detect() : void 0))) { - continue; - } - changes.software = software; - hostname = location.hostname.replace(/^www\./, ''); - properties = ((base1 = Conf['siteProperties'])[hostname] || (base1[hostname] = $.dict())); - changed = 0; - for (key in changes) { - if (!(properties[key] !== changes[key])) { - continue; - } - properties[key] = changes[key]; - changed++; - } - if (changed) { - $.set('siteProperties', Conf['siteProperties']); - } - if (!g.SITE) { - _this.set(hostname); - cb(); - } - return; - } - }; - })(this)); - }, - resolve: function(url) { - var canonical, hostname; - if (url == null) { - url = location; - } - hostname = url.hostname; - while (hostname && !$.hasOwn(Conf['siteProperties'], hostname)) { - hostname = hostname.replace(/^[^.]*\.?/, ''); - } - if (hostname) { - if ((canonical = Conf['siteProperties'][hostname].canonical)) { - hostname = canonical; - } - } - return hostname; - }, - parseURL: function(url) { - var siteID; - siteID = Site.resolve(url); - return Main.parseURL(g.sites[siteID], url); - }, - set: function(hostname) { - var ID, properties, ref, site, software; - ref = Conf['siteProperties']; - for (ID in ref) { - properties = ref[ID]; - if (properties.canonical) { - continue; - } - software = properties.software; - if (!(software && $.hasOwn(SW, software))) { - continue; - } - g.sites[ID] = site = Object.create(SW[software]); - $.extend(site, { - ID: ID, - siteID: ID, - properties: properties, - software: software - }); - } - return g.SITE = g.sites[hostname]; - } - }; - - return Site; - -}).call(this); - -Redirect = (function() { - var Redirect, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Redirect = { - archives: [ - { "uid": 3, "name": "4plebs", "domain": "archive.4plebs.org", "http": true, "https": true, "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": true }, - { "uid": 10, "name": "warosu", "domain": "warosu.org", "http": false, "https": true, "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": true, "https": true, "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": true }, - { "uid": 24, "name": "fireden.net", "domain": "boards.fireden.net", "http": false, "https": true, "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": true, "https": true, "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": true, "https": true, "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": true }, - { "uid": 30, "name": "TheBArchive.com", "domain": "thebarchive.com", "http": true, "https": true, "software": "foolfuuka", "boards": [ "b", "bant" ], "files": [ "b", "bant" ], "reports": true }, - { "uid": 31, "name": "Archive Of Sins", "domain": "archiveofsins.com", "http": true, "https": true, "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": true }, - { "uid": 34, "name": "TokyoChronos", "domain": "www.tokyochronos.net", "http": false, "https": true, "software": "foolfuuka", "boards": [ "c", "g", "jp", "mu", "vp", "vrpg", "vt" ], "files": [], "reports": true }, - { "uid": 36, "name": "palanq.win", "domain": "archive.palanq.win", "http": false, "https": true, "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": true }, - { "uid": 37, "name": "Eientei", "domain": "eientei.xyz", "http": false, "https": true, "software": "Eientei", "boards": [ "3", "i", "sci", "xs" ], "files": [ "3", "i", "sci", "xs" ], "reports": true } - ], - init: function() { - var now, ref; - this.selectArchives(); - if (Conf['archiveAutoUpdate']) { - now = Date.now(); - if (!((now - 2 * $.DAY < (ref = Conf['lastarchivecheck']) && ref <= now))) { - return this.update(); - } - } - }, - selectArchives: function() { - var archive, archives, boardID, boards, data, files, id, j, k, key, l, len, len1, len2, name, o, record, ref, ref1, ref2, software, type, uid; - o = { - thread: $.dict(), - post: $.dict(), - file: $.dict() - }; - archives = $.dict(); - ref = Conf['archives']; - for (j = 0, len = ref.length; j < len; j++) { - data = ref[j]; - ref1 = ['boards', 'files']; - for (k = 0, len1 = ref1.length; k < len1; k++) { - key = ref1[k]; - if (!(data[key] instanceof Array)) { - data[key] = []; - } - } - uid = data.uid, name = data.name, boards = data.boards, files = data.files, software = data.software; - if (software !== 'fuuka' && software !== 'foolfuuka') { - continue; - } - archives[JSON.stringify(uid != null ? uid : name)] = data; - for (l = 0, len2 = boards.length; l < len2; l++) { - boardID = boards[l]; - if (!(boardID in o.thread)) { - o.thread[boardID] = data; - } - if (!(boardID in o.post || software !== 'foolfuuka')) { - o.post[boardID] = data; - } - if (!(boardID in o.file || indexOf.call(files, boardID) < 0)) { - o.file[boardID] = data; - } - } - } - ref2 = Conf['selectedArchives']; - for (boardID in ref2) { - record = ref2[boardID]; - for (type in record) { - id = record[type]; - if (!((archive = archives[JSON.stringify(id)]) && $.hasOwn(o, type))) { - continue; - } - boards = type === 'file' ? archive.files : archive.boards; - if (indexOf.call(boards, boardID) >= 0) { - o[type][boardID] = archive; - } - } - } - return Redirect.data = o; - }, - update: function(cb) { - var err, fail, i, j, k, len, len1, load, nloaded, ref, ref1, response, responses, url, urls; - urls = []; - responses = []; - nloaded = 0; - ref = Conf['archiveLists'].split('\n'); - for (j = 0, len = ref.length; j < len; j++) { - url = ref[j]; - if (!(url[0] !== '#')) { - continue; - } - url = url.trim(); - if (url) { - urls.push(url); - } - } - fail = function(url, action, msg) { - return new Notice('warning', "Error " + action + " archive data from\n" + url + "\n" + msg, 20); - }; - load = function(i) { - return function() { - var response; - if (this.status !== 200) { - return fail(urls[i], 'fetching', (this.status ? "Error " + this.statusText + " (" + this.status + ")" : 'Connection Error')); - } - response = this.response; - if (!(response instanceof Array)) { - response = [response]; - } - responses[i] = response; - nloaded++; - if (nloaded === urls.length) { - return Redirect.parse(responses, cb); - } - }; - }; - if (urls.length) { - for (i = k = 0, len1 = urls.length; k < len1; i = ++k) { - url = urls[i]; - if ((ref1 = url[0]) === '[' || ref1 === '{') { - try { - response = JSON.parse(url); - } catch (error) { - err = error; - fail(url, 'parsing', err.message); - continue; - } - load(i).call({ - status: 200, - response: response - }); - } else { - CrossOrigin.ajax(url, { - onloadend: load(i) - }); - } - } - } else { - Redirect.parse([], cb); - } - }, - parse: function(responses, cb) { - var archiveUIDs, archives, data, items, j, k, len, len1, ref, response, uid; - archives = []; - archiveUIDs = $.dict(); - for (j = 0, len = responses.length; j < len; j++) { - response = responses[j]; - for (k = 0, len1 = response.length; k < len1; k++) { - data = response[k]; - uid = JSON.stringify((ref = data.uid) != null ? ref : data.name); - if (uid in archiveUIDs) { - $.extend(archiveUIDs[uid], data); - } else { - archiveUIDs[uid] = $.dict.clone(data); - archives.push(data); - } - } - } - items = { - archives: archives, - lastarchivecheck: Date.now() - }; - $.set(items); - $.extend(Conf, items); - Redirect.selectArchives(); - return typeof cb === "function" ? cb() : void 0; - }, - to: function(dest, data) { - var archive; - archive = (dest === 'search' || dest === 'board' ? Redirect.data.thread : Redirect.data[dest])[data.boardID]; - if (!archive) { - return ''; - } - return Redirect[dest](archive, data); - }, - protocol: function(archive) { - var protocol; - protocol = location.protocol; - if (!$.getOwn(archive, protocol.slice(0, -1))) { - protocol = protocol === 'https:' ? 'http:' : 'https:'; - } - return protocol + "//"; - }, - thread: function(archive, arg) { - var boardID, path, postID, threadID; - boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID; - path = threadID ? boardID + "/thread/" + threadID : boardID + "/post/" + postID; - if (archive.software === 'foolfuuka') { - path += '/'; - } - if (threadID && postID) { - path += archive.software === 'foolfuuka' ? "#" + postID : "#p" + postID; - } - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; - }, - post: function(archive, arg) { - var boardID, postID, protocol, url; - boardID = arg.boardID, postID = arg.postID; - protocol = Redirect.protocol(archive); - url = "" + protocol + archive.domain + "/_/api/chan/post/?board=" + boardID + "&num=" + postID; - if (!Redirect.securityCheck(url)) { - return ''; - } - return url; - }, - file: function(archive, arg) { - var boardID, filename; - boardID = arg.boardID, filename = arg.filename; - if (!filename) { - return ''; - } - if (boardID === 'f') { - filename = encodeURIComponent($.unescape(decodeURIComponent(filename))); - } else { - if (/[sm]\.jpg$/.test(filename)) { - return ''; - } - } - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/full_image/" + filename; - }, - board: function(archive, arg) { - var boardID; - boardID = arg.boardID; - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + boardID + "/"; - }, - search: function(archive, arg) { - var boardID, path, type, value; - boardID = arg.boardID, type = arg.type, value = arg.value; - type = type === 'name' ? 'username' : type === 'MD5' ? 'image' : type; - if (type === 'capcode') { - value = $.getOwn({ - 'Developer': 'dev', - 'Verified': 'ver' - }, value) || value.toLowerCase(); - } else if (type === 'image') { - value = value.replace(/[+\/=]/g, function(c) { - return { - '+': '-', - '/': '_', - '=': '' - }[c]; - }); - } - value = encodeURIComponent(value); - path = archive.software === 'foolfuuka' ? boardID + "/search/" + type + "/" + value + "/" : type === 'image' ? boardID + "/image/" + value : boardID + "/?task=search2&search_" + type + "=" + value; - return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path; - }, - report: function(boardID) { - var archive, boards, domain, https, j, len, name, ref, reports, software, urls; - urls = []; - ref = Conf['archives']; - for (j = 0, len = ref.length; j < len; j++) { - archive = ref[j]; - software = archive.software, https = archive.https, reports = archive.reports, boards = archive.boards, name = archive.name, domain = archive.domain; - if (software === 'foolfuuka' && https && reports && boards instanceof Array && indexOf.call(boards, boardID) >= 0) { - urls.push([name, "https://" + domain + "/_/api/chan/offsite_report/"]); - } - } - return urls; - }, - securityCheck: function(url) { - return /^https:\/\//.test(url) || location.protocol === 'http:' || Conf['Exempt Archives from Encryption']; - }, - navigate: function(dest, data, alternative) { - var url; - if (!Redirect.data) { - Redirect.init(); - } - url = Redirect.to(dest, data); - if (url && (Redirect.securityCheck(url) || confirm("Redirect to " + url + "?\n\nYour connection will not be encrypted."))) { - return location.replace(url); - } else if (alternative) { - return location.replace(alternative); - } - } - }; - - return Redirect; - -}).call(this); - -Anonymize = (function() { - var Anonymize; - - Anonymize = { - init: function() { - if (!Conf['Anonymize']) { - return; - } - return $.addClass(doc, 'anonymize'); - } - }; - - return Anonymize; - -}).call(this); - -Filter = (function() { - var Filter, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - Filter = { - filters: $.dict(), - init: function() { - var base, base1, boards, err, excludes, file, filter, hide, hl, i, isstring, j, key, len, len1, line, mask, noti, op, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, regexp, stub, top, type, types; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'catalog') && Conf['Filter'])) { - return; - } - if (g.VIEW === 'catalog' && !Conf['Filter in Native Catalog']) { - return; - } - if (!Conf['Filtered Backlinks']) { - $.addClass(doc, 'hide-backlinks'); - } - for (key in Config.filter) { - ref1 = Conf[key].split('\n'); - for (i = 0, len = ref1.length; i < len; i++) { - line = ref1[i]; - if (line[0] === '#') { - continue; - } - if (!(regexp = line.match(/\/(.*)\/(\w*)/))) { - continue; - } - filter = line.replace(regexp[0], ''); - boards = this.parseBoards((ref2 = filter.match(/(?:^|;)\s*boards:([^;]+)/)) != null ? ref2[1] : void 0); - excludes = this.parseBoards((ref3 = filter.match(/(?:^|;)\s*exclude:([^;]+)/)) != null ? ref3[1] : void 0); - if ((isstring = (key === 'uniqueID' || key === 'MD5'))) { - regexp = regexp[1]; - } else { - try { - regexp = RegExp(regexp[1], regexp[2]); - } catch (error) { - err = error; - new Notice('warning', [$.tn("Invalid " + key + " filter:"), $.el('br'), $.tn(line), $.el('br'), $.tn(err.message)], 60); - continue; - } - } - op = ((ref4 = filter.match(/(?:^|;)\s*op:(no|only)/)) != null ? ref4[1] : void 0) || ''; - mask = $.getOwn({ - 'no': 1, - 'only': 2 - }, op) || 0; - file = ((ref5 = filter.match(/(?:^|;)\s*file:(no|only)/)) != null ? ref5[1] : void 0) || ''; - mask = mask | ($.getOwn({ - 'no': 4, - 'only': 8 - }, file) || 0); - stub = (function() { - var ref6; - switch ((ref6 = filter.match(/(?:^|;)\s*stub:(yes|no)/)) != null ? ref6[1] : void 0) { - case 'yes': - return true; - case 'no': - return false; - default: - return Conf['Stubs']; - } - })(); - noti = /(?:^|;)\s*notify/.test(filter); - if ((hl = /(?:^|;)\s*highlight/.test(filter))) { - hl = ((ref6 = filter.match(/(?:^|;)\s*highlight:([\w-]+)/)) != null ? ref6[1] : void 0) || 'filter-highlight'; - top = ((ref7 = filter.match(/(?:^|;)\s*top:(yes|no)/)) != null ? ref7[1] : void 0) || 'yes'; - top = top === 'yes'; - } - if (key === 'general') { - if ((types = filter.match(/(?:^|;)\s*type:([^;]*)/))) { - types = types[1].split(','); - } else { - types = ['subject', 'name', 'filename', 'comment']; - } - } - hide = !(hl || noti); - filter = { - isstring: isstring, - regexp: regexp, - boards: boards, - excludes: excludes, - mask: mask, - hide: hide, - stub: stub, - hl: hl, - top: top, - noti: noti - }; - if (key === 'general') { - for (j = 0, len1 = types.length; j < len1; j++) { - type = types[j]; - ((base = this.filters)[type] || (base[type] = [])).push(filter); - } - } else { - ((base1 = this.filters)[key] || (base1[key] = [])).push(filter); - } - } - } - if (!Object.keys(this.filters).length) { - return; - } - if (g.VIEW === 'catalog') { - return Filter.catalog(); - } else { - return Callbacks.Post.push({ - name: 'Filter', - cb: this.node - }); - } - }, - parseBoards: function(boardsRaw) { - var boardID, boardID2, boards, i, j, len, len1, ref, ref1, ref2, ref3, site, siteFilter, siteID; - if (!boardsRaw) { - return false; - } - if ((boards = Filter.parseBoardsMemo[boardsRaw])) { - return boards; - } - boards = $.dict(); - siteFilter = ''; - ref = boardsRaw.split(','); - for (i = 0, len = ref.length; i < len; i++) { - boardID = ref[i]; - if (indexOf.call(boardID, ':') >= 0) { - ref1 = boardID.split(':').slice(-2), siteFilter = ref1[0], boardID = ref1[1]; - } - ref2 = g.sites; - for (siteID in ref2) { - site = ref2[siteID]; - if (siteID.slice(0, siteFilter.length) === siteFilter) { - if (boardID === 'nsfw' || boardID === 'sfw') { - ref3 = (typeof site.sfwBoards === "function" ? site.sfwBoards(boardID === 'sfw') : void 0) || []; - for (j = 0, len1 = ref3.length; j < len1; j++) { - boardID2 = ref3[j]; - boards[siteID + "/" + boardID2] = true; - } - } else { - boards[siteID + "/" + (encodeURIComponent(boardID))] = true; - } - } - } - } - Filter.parseBoardsMemo[boardsRaw] = boards; - return boards; - }, - parseBoardsMemo: $.dict(), - test: function(post, hideable) { - var board, filter, hide, hl, i, j, key, len, len1, mask, noti, ref, ref1, ref2, site, stub, top, value; - if (hideable == null) { - hideable = true; - } - if (post.filterResults) { - return post.filterResults; - } - hide = false; - stub = true; - hl = void 0; - top = false; - noti = false; - if (QuoteYou.isYou(post)) { - hideable = false; - } - mask = (post.isReply ? 2 : 1); - mask = mask | (post.file ? 4 : 8); - board = post.siteID + "/" + post.boardID; - site = post.siteID + "/*"; - for (key in Filter.filters) { - ref = Filter.values(key, post); - for (i = 0, len = ref.length; i < len; i++) { - value = ref[i]; - ref1 = Filter.filters[key]; - for (j = 0, len1 = ref1.length; j < len1; j++) { - filter = ref1[j]; - if ((filter.boards && !(filter.boards[board] || filter.boards[site])) || (filter.excludes && (filter.excludes[board] || filter.excludes[site])) || (filter.mask & mask) || (filter.isstring ? filter.regexp !== value : !filter.regexp.test(value))) { - continue; - } - if (filter.hide) { - if (hideable) { - hide = true; - stub && (stub = filter.stub); - } - } else { - if (!(hl && (ref2 = filter.hl, indexOf.call(hl, ref2) >= 0))) { - (hl || (hl = [])).push(filter.hl); - } - top || (top = filter.top); - if (filter.noti) { - noti = true; - } - } - } - } - } - if (hide) { - return { - hide: hide, - stub: stub - }; - } else { - return { - hl: hl, - top: top, - noti: noti - }; - } - }, - node: function() { - var hide, hl, noti, ref, stub, top; - if (this.isClone) { - return; - } - ref = Filter.test(this, !this.isFetchedQuote && (this.isReply || g.VIEW === 'index')), hide = ref.hide, stub = ref.stub, hl = ref.hl, top = ref.top, noti = ref.noti; - if (hide) { - if (this.isReply) { - PostHiding.hide(this, stub); - } else { - ThreadHiding.hide(this.thread, stub); - } - } else { - if (hl) { - this.highlights = hl; - $.addClass.apply($, [this.nodes.root].concat(slice.call(hl))); - } - } - if (noti && Unread.posts && (this.ID > Unread.lastReadPost) && !QuoteYou.isYou(this)) { - return Unread.openNotification(this, ' triggered a notification filter'); - } - }, - catalog: function() { - var base, url; - if (!(url = typeof (base = g.SITE.urls).catalogJSON === "function" ? base.catalogJSON(g.BOARD) : void 0)) { - return; - } - Filter.catalogData = $.dict(); - $.ajax(url, { - onloadend: Filter.catalogParse - }); - return Callbacks.CatalogThreadNative.push({ - name: 'Filter', - cb: this.catalogNode - }); - }, - catalogParse: function() { - var i, item, j, len, len1, page, ref, ref1, ref2; - if ((ref = this.status) !== 200 && ref !== 404) { - new Notice('warning', "Failed to fetch catalog JSON data. " + (this.status ? "Error " + this.statusText + " (" + this.status + ")" : 'Connection Error'), 1); - return; - } - ref1 = this.response; - for (i = 0, len = ref1.length; i < len; i++) { - page = ref1[i]; - ref2 = page.threads; - for (j = 0, len1 = ref2.length; j < len1; j++) { - item = ref2[j]; - Filter.catalogData[item.no] = item; - } - } - g.BOARD.threads.forEach(function(thread) { - if (thread.catalogViewNative) { - return Filter.catalogNode.call(thread.catalogViewNative); - } - }); - }, - catalogNode: function() { - var base, hide, hl, ref, ref1, top; - if (!(this.boardID === g.BOARD.ID && Filter.catalogData[this.ID])) { - return; - } - if ((ref = QuoteYou.db) != null ? ref.get({ - siteID: g.SITE.ID, - boardID: this.boardID, - threadID: this.ID, - postID: this.ID - }) : void 0) { - return; - } - ref1 = Filter.test(g.SITE.Build.parseJSON(Filter.catalogData[this.ID], this)), hide = ref1.hide, hl = ref1.hl, top = ref1.top; - if (hide) { - return this.nodes.root.hidden = true; - } else { - if (hl) { - this.highlights = hl; - $.addClass.apply($, [this.nodes.root].concat(slice.call(hl))); - } - if (top) { - $.prepend(this.nodes.root.parentNode, this.nodes.root); - return typeof (base = g.SITE).catalogPin === "function" ? base.catalogPin(this.nodes.root) : void 0; - } - } - }, - isHidden: function(post) { - return !!Filter.test(post).hide; - }, - valueF: { - postID: function(post) { - return ["" + post.ID]; - }, - name: function(post) { - return [post.info.name]; - }, - uniqueID: function(post) { - return [post.info.uniqueID || '']; - }, - tripcode: function(post) { - return [post.info.tripcode]; - }, - capcode: function(post) { - return [post.info.capcode]; - }, - pass: function(post) { - return [post.info.pass]; - }, - email: function(post) { - return [post.info.email]; - }, - subject: function(post) { - return [post.info.subject || (post.isReply ? void 0 : '')]; - }, - comment: function(post) { - var base, ref, ref1; - return [((base = post.info).comment != null ? base.comment : base.comment = (ref = g.sites[post.siteID]) != null ? (ref1 = ref.Build) != null ? typeof ref1.parseComment === "function" ? ref1.parseComment(post.info.commentHTML.innerHTML) : void 0 : void 0 : void 0)]; - }, - flag: function(post) { - return [post.info.flag]; - }, - filename: function(post) { - return post.files.map(function(f) { - return f.name; - }); - }, - dimensions: function(post) { - return post.files.map(function(f) { - return f.dimensions; - }); - }, - filesize: function(post) { - return post.files.map(function(f) { - return f.size; - }); - }, - MD5: function(post) { - return post.files.map(function(f) { - return f.MD5; - }); - } - }, - values: function(key, post) { - if ($.hasOwn(Filter.valueF, key)) { - return Filter.valueF[key](post).filter(function(v) { - return v != null; - }); - } else { - return [ - key.split('+').map(function(k) { - var f; - if ((f = $.getOwn(Filter.valueF, k))) { - return f(post).map(function(v) { - return v || ''; - }).join('\n'); - } else { - return ''; - } - }).join('\n') - ]; - } - }, - addFilter: function(type, re, cb) { - if (!$.hasOwn(Config.filter, type)) { - return; - } - return $.get(type, Conf[type], function(item) { - var save; - save = item[type]; - save = save ? save + "\n" + re : re; - return $.set(type, save, cb); - }); - }, - removeFilters: function(type, res, cb) { - return $.get(type, Conf[type], function(item) { - var save; - save = item[type]; - res = res.map(Filter.escape).join('|'); - save = save.replace(RegExp("(?:$\n|^)(?:" + res + ")$", 'mg'), ''); - return $.set(type, save, cb); - }); - }, - showFilters: function(type) { - var section, select; - Settings.open('Filter'); - section = $('.section-container'); - select = $('select[name=filter]', section); - select.value = type; - Settings.selectFilter.call(select); - return $.onExists(section, 'textarea', function(ta) { - var tl; - tl = ta.textLength; - ta.setSelectionRange(tl, tl); - return ta.focus(); - }); - }, - quickFilterMD5: function() { - var files, filter, links, msg, notice, origin, post; - post = Get.postFromNode(this); - files = post.files.filter(function(f) { - return f.MD5; - }); - if (!files.length) { - return; - } - filter = files.map(function(f) { - return "/" + f.MD5 + "/"; - }).join('\n'); - Filter.addFilter('MD5', filter); - origin = post.origin || post; - if (origin.isReply) { - PostHiding.hide(origin); - } else if (g.VIEW === 'index') { - ThreadHiding.hide(origin.thread); - } - if (!Conf['MD5 Quick Filter Notifications']) { - if (post.nodes.post.getBoundingClientRect().height) { - new Notice('info', 'MD5 filtered.', 2); - } - return; - } - notice = Filter.quickFilterMD5.notice; - if (notice) { - notice.filters.push(filter); - notice.posts.push(origin); - return $('span', notice.el).textContent = notice.filters.length + " MD5s filtered."; - } else { - msg = $.el('div', {innerHTML: "MD5 filtered. [show] [undo]"}); - notice = Filter.quickFilterMD5.notice = new Notice('info', msg, void 0, function() { - return delete Filter.quickFilterMD5.notice; - }); - notice.filters = [filter]; - notice.posts = [origin]; - links = $$('a', msg); - $.on(links[0], 'click', Filter.quickFilterCB.show.bind(notice)); - return $.on(links[1], 'click', Filter.quickFilterCB.undo.bind(notice)); - } - }, - quickFilterCB: { - show: function() { - Filter.showFilters('MD5'); - return this.close(); - }, - undo: function() { - var i, len, post, ref; - Filter.removeFilters('MD5', this.filters); - ref = this.posts; - for (i = 0, len = ref.length; i < len; i++) { - post = ref[i]; - if (post.isReply) { - PostHiding.show(post); - } else if (g.VIEW === 'index') { - ThreadHiding.show(post.thread); - } - } - return this.close(); - } - }, - escape: function(value) { - return value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) { - if (c === '\n') { - return '\\n'; - } else if (c === '\\') { - return '\\\\'; - } else { - return "\\" + c; - } - }); - }, - menu: { - init: function() { - var div, entry, i, len, ref, ref1, type; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Filter'])) { - return; - } - div = $.el('div', { - textContent: 'Filter' - }); - entry = { - el: div, - order: 50, - open: function(post) { - Filter.menu.post = post; - return true; - }, - subEntries: [] - }; - ref1 = [['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']]; - for (i = 0, len = ref1.length; i < len; i++) { - type = ref1[i]; - entry.subEntries.push(Filter.menu.createSubEntry(type[0], type[1])); - } - return Menu.menu.addEntry(entry); - }, - createSubEntry: function(text, type) { - var el; - el = $.el('a', { - href: 'javascript:;', - textContent: text - }); - el.dataset.type = type; - $.on(el, 'click', Filter.menu.makeFilter); - return { - el: el, - open: function(post) { - return Filter.values(type, post).length; - } - }; - }, - makeFilter: function() { - var res, type, values; - type = this.dataset.type; - values = Filter.values(type, Filter.menu.post); - res = values.map(function(value) { - var re; - re = type === 'uniqueID' || type === 'MD5' ? value : Filter.escape(value); - if (type === 'uniqueID' || type === 'MD5') { - return "/" + re + "/"; - } else { - return "/^" + re + "$/"; - } - }).join('\n'); - return Filter.addFilter(type, res, function() { - return Filter.showFilters(type); - }); - } - } - }; - - return Filter; - -}).call(this); - -PostHiding = (function() { - var PostHiding; - - PostHiding = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Reply Hiding Buttons'] && !(Conf['Menu'] && Conf['Reply Hiding Link'])) { - return; - } - if (Conf['Reply Hiding Buttons']) { - $.addClass(doc, "reply-hide"); - } - this.db = new DataBoard('hiddenPosts'); - return Callbacks.Post.push({ - name: 'Reply Hiding', - cb: this.node - }); - }, - isHidden: function(boardID, threadID, postID) { - return !!(PostHiding.db && PostHiding.db.get({ - boardID: boardID, - threadID: threadID, - postID: postID - })); - }, - node: function() { - var button, data, sa, sideArrows; - if (!this.isReply || this.isClone || this.isFetchedQuote) { - return; - } - if (data = PostHiding.db.get({ - boardID: this.board.ID, - threadID: this.thread.ID, - postID: this.ID - })) { - if (data.thisPost) { - PostHiding.hide(this, data.makeStub, data.hideRecursively); - } else { - Recursive.apply(PostHiding.hide, this, data.makeStub, true); - Recursive.add(PostHiding.hide, this, data.makeStub, true); - } - } - if (!Conf['Reply Hiding Buttons']) { - return; - } - button = PostHiding.makeButton(this, 'hide'); - if ((sa = g.SITE.selectors.sideArrows)) { - sideArrows = $(sa, this.nodes.root); - $.replace(sideArrows.firstChild, button); - return sideArrows.className = 'replacedSideArrows'; - } else { - return $.prepend(this.nodes.info, button); - } - }, - menu: { - init: function() { - var apply, div, hideStubLink, makeStub, ref, replies, thisPost; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Menu'] || !Conf['Reply Hiding Link']) { - return; - } - div = $.el('div', { - className: 'hide-reply-link', - textContent: 'Hide' - }); - apply = $.el('a', { - textContent: 'Apply', - href: 'javascript:;' - }); - $.on(apply, 'click', PostHiding.menu.hide); - thisPost = UI.checkbox('thisPost', 'This post', true); - replies = UI.checkbox('replies', 'Hide replies', Conf['Recursive Hiding']); - makeStub = UI.checkbox('makeStub', 'Make stub', Conf['Stubs']); - Menu.menu.addEntry({ - el: div, - order: 20, - open: function(post) { - if (!post.isReply || post.isClone || post.isHidden) { - return false; - } - PostHiding.menu.post = post; - return true; - }, - subEntries: [ - { - el: apply - }, { - el: thisPost - }, { - el: replies - }, { - el: makeStub - } - ] - }); - div = $.el('div', { - className: 'show-reply-link', - textContent: 'Show' - }); - apply = $.el('a', { - textContent: 'Apply', - href: 'javascript:;' - }); - $.on(apply, 'click', PostHiding.menu.show); - thisPost = UI.checkbox('thisPost', 'This post', false); - replies = UI.checkbox('replies', 'Show replies', false); - hideStubLink = $.el('a', { - textContent: 'Hide stub', - href: 'javascript:;' - }); - $.on(hideStubLink, 'click', PostHiding.menu.hideStub); - Menu.menu.addEntry({ - el: div, - order: 20, - open: function(post) { - var data; - if (!post.isReply || post.isClone || !post.isHidden) { - return false; - } - if (!(data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }))) { - return false; - } - PostHiding.menu.post = post; - thisPost.firstChild.checked = post.isHidden; - replies.firstChild.checked = (data != null ? data.hideRecursively : void 0) != null ? data.hideRecursively : Conf['Recursive Hiding']; - return true; - }, - subEntries: [ - { - el: apply - }, { - el: thisPost - }, { - el: replies - } - ] - }); - return Menu.menu.addEntry({ - el: hideStubLink, - order: 15, - open: function(post) { - var data; - if (!post.isReply || post.isClone || !post.isHidden) { - return false; - } - if (!(data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }))) { - return false; - } - return PostHiding.menu.post = post; - } - }); - }, - hide: function() { - var makeStub, parent, post, replies, thisPost; - parent = this.parentNode; - thisPost = $('input[name=thisPost]', parent).checked; - replies = $('input[name=replies]', parent).checked; - makeStub = $('input[name=makeStub]', parent).checked; - post = PostHiding.menu.post; - if (thisPost) { - PostHiding.hide(post, makeStub, replies); - } else if (replies) { - Recursive.apply(PostHiding.hide, post, makeStub, true); - Recursive.add(PostHiding.hide, post, makeStub, true); - } else { - return; - } - PostHiding.saveHiddenState(post, true, thisPost, makeStub, replies); - return $.event('CloseMenu'); - }, - show: function() { - var data, parent, post, replies, thisPost; - parent = this.parentNode; - thisPost = $('input[name=thisPost]', parent).checked; - replies = $('input[name=replies]', parent).checked; - post = PostHiding.menu.post; - if (thisPost) { - PostHiding.show(post, replies); - } else if (replies) { - Recursive.apply(PostHiding.show, post, true); - Recursive.rm(PostHiding.hide, post, true); - } else { - return; - } - if (data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - })) { - PostHiding.saveHiddenState(post, !(thisPost && replies), !thisPost, data.makeStub, !replies); - } - return $.event('CloseMenu'); - }, - hideStub: function() { - var data, post; - post = PostHiding.menu.post; - if (data = PostHiding.db.get({ - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - })) { - PostHiding.show(post, data.hideRecursively); - PostHiding.hide(post, false, data.hideRecursively); - PostHiding.saveHiddenState(post, true, true, false, data.hideRecursively); - } - $.event('CloseMenu'); - } - }, - makeButton: function(post, type) { - var a, span; - span = $.el('span', { - className: "fa fa-" + (type === 'hide' ? 'minus' : 'plus') + "-square-o", - textContent: "" - }); - a = $.el('a', { - className: type + "-reply-button", - href: 'javascript:;' - }); - $.add(a, span); - $.on(a, 'click', PostHiding.toggle); - return a; - }, - saveHiddenState: function(post, isHiding, thisPost, makeStub, hideRecursively) { - var data; - data = { - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID - }; - if (isHiding) { - data.val = { - thisPost: thisPost !== false, - makeStub: makeStub, - hideRecursively: hideRecursively - }; - return PostHiding.db.set(data); - } else { - return PostHiding.db["delete"](data); - } - }, - toggle: function() { - var post; - post = Get.postFromNode(this); - PostHiding[(post.isHidden ? 'show' : 'hide')](post); - return PostHiding.saveHiddenState(post, post.isHidden); - }, - hide: function(post, makeStub, hideRecursively) { - var a, i, len, quotelink, ref; - if (makeStub == null) { - makeStub = Conf['Stubs']; - } - if (hideRecursively == null) { - hideRecursively = Conf['Recursive Hiding']; - } - if (post.isHidden) { - return; - } - post.isHidden = true; - if (hideRecursively) { - Recursive.apply(PostHiding.hide, post, makeStub, true); - Recursive.add(PostHiding.hide, post, makeStub, true); - } - ref = Get.allQuotelinksLinkingTo(post); - for (i = 0, len = ref.length; i < len; i++) { - quotelink = ref[i]; - $.addClass(quotelink, 'filtered'); - } - if (!makeStub) { - post.nodes.root.hidden = true; - return; - } - a = PostHiding.makeButton(post, 'show'); - $.add(a, $.tn(" " + post.info.nameBlock)); - post.nodes.stub = $.el('div', { - className: 'stub' - }); - $.add(post.nodes.stub, a); - if (Conf['Menu']) { - $.add(post.nodes.stub, Menu.makeButton(post)); - } - return $.prepend(post.nodes.root, post.nodes.stub); - }, - show: function(post, showRecursively) { - var i, len, quotelink, ref; - if (showRecursively == null) { - showRecursively = Conf['Recursive Hiding']; - } - if (post.nodes.stub) { - $.rm(post.nodes.stub); - delete post.nodes.stub; - } else { - post.nodes.root.hidden = false; - } - post.isHidden = false; - if (showRecursively) { - Recursive.apply(PostHiding.show, post, true); - Recursive.rm(PostHiding.hide, post); - } - ref = Get.allQuotelinksLinkingTo(post); - for (i = 0, len = ref.length; i < len; i++) { - quotelink = ref[i]; - $.rmClass(quotelink, 'filtered'); - } - } - }; - - return PostHiding; - -}).call(this); - -Recursive = (function() { - var Recursive, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Recursive = { - recursives: $.dict(), - init: function() { - var ref; - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - return Callbacks.Post.push({ - name: 'Recursive', - cb: this.node - }); - }, - node: function() { - var i, j, k, len, len1, obj, quote, recursive, ref, ref1; - if (this.isClone || this.isFetchedQuote) { - return; - } - ref = this.quotes; - for (j = 0, len = ref.length; j < len; j++) { - quote = ref[j]; - if (obj = Recursive.recursives[quote]) { - ref1 = obj.recursives; - for (i = k = 0, len1 = ref1.length; k < len1; i = ++k) { - recursive = ref1[i]; - recursive.apply(null, [this].concat(slice.call(obj.args[i]))); - } - } - } - }, - add: function() { - var args, base, name, obj, post, recursive; - recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; - obj = (base = Recursive.recursives)[name = post.fullID] || (base[name] = { - recursives: [], - args: [] - }); - obj.recursives.push(recursive); - return obj.args.push(args); - }, - rm: function(recursive, post) { - var i, j, len, obj, rec, ref; - if (!(obj = Recursive.recursives[post.fullID])) { - return; - } - ref = obj.recursives; - for (i = j = 0, len = ref.length; j < len; i = ++j) { - rec = ref[i]; - if (!(rec === recursive)) { - continue; - } - obj.recursives.splice(i, 1); - obj.args.splice(i, 1); - } - }, - apply: function() { - var args, fullID, post, recursive; - recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; - fullID = post.fullID; - return g.posts.forEach(function(post) { - if (indexOf.call(post.quotes, fullID) >= 0) { - return recursive.apply(null, [post].concat(slice.call(args))); - } - }); - } - }; - - return Recursive; - -}).call(this); - -ThreadHiding = (function() { - var ThreadHiding; - - ThreadHiding = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'catalog') || !Conf['Thread Hiding Buttons'] && !(Conf['Menu'] && Conf['Thread Hiding Link']) && !Conf['JSON Index']) { - return; - } - this.db = new DataBoard('hiddenThreads'); - if (g.VIEW === 'catalog') { - return this.catalogWatch(); - } - this.catalogSet(g.BOARD); - $.on(d, 'IndexRefreshInternal', this.onIndexRefresh); - if (Conf['Thread Hiding Buttons']) { - $.addClass(doc, 'thread-hide'); - } - return Callbacks.Post.push({ - name: 'Thread Hiding', - cb: this.node - }); - }, - catalogSet: function(board) { - var hiddenThreads, threadID; - if (!($.hasStorage && g.SITE.software === 'yotsuba')) { - return; - } - hiddenThreads = ThreadHiding.db.get({ - boardID: board.ID, - defaultValue: $.dict() - }); - for (threadID in hiddenThreads) { - hiddenThreads[threadID] = true; - } - return localStorage.setItem("4chan-hide-t-" + board, JSON.stringify(hiddenThreads)); - }, - catalogWatch: function() { - if (!($.hasStorage && g.SITE.software === 'yotsuba')) { - return; - } - this.hiddenThreads = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; - return Main.ready(function() { - return new MutationObserver(ThreadHiding.catalogSave).observe($.id('threads'), { - attributes: true, - subtree: true, - attributeFilter: ['style'] - }); - }); - }, - catalogSave: function() { - var hiddenThreads2, threadID; - hiddenThreads2 = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {}; - for (threadID in hiddenThreads2) { - if (!$.hasOwn(ThreadHiding.hiddenThreads, threadID)) { - ThreadHiding.db.set({ - boardID: g.BOARD.ID, - threadID: threadID, - val: { - makeStub: Conf['Stubs'] - } - }); - } - } - for (threadID in ThreadHiding.hiddenThreads) { - if (!$.hasOwn(hiddenThreads2, threadID)) { - ThreadHiding.db["delete"]({ - boardID: g.BOARD.ID, - threadID: threadID - }); - } - } - return ThreadHiding.hiddenThreads = hiddenThreads2; - }, - isHidden: function(boardID, threadID) { - return !!(ThreadHiding.db && ThreadHiding.db.get({ - boardID: boardID, - threadID: threadID - })); - }, - node: function() { - var data; - if (this.isReply || this.isClone || this.isFetchedQuote) { - return; - } - if (Conf['Thread Hiding Buttons']) { - $.prepend(this.nodes.root, ThreadHiding.makeButton(this.thread, 'hide')); - } - if (data = ThreadHiding.db.get({ - boardID: this.board.ID, - threadID: this.ID - })) { - return ThreadHiding.hide(this.thread, data.makeStub); - } - }, - onIndexRefresh: function() { - return g.BOARD.threads.forEach(function(thread) { - var root; - root = thread.nodes.root; - if (thread.isHidden && thread.stub && !root.contains(thread.stub)) { - return ThreadHiding.makeStub(thread, root); - } - }); - }, - menu: { - init: function() { - var apply, div, hideStubLink, makeStub; - if (g.VIEW !== 'index' || !Conf['Menu'] || !Conf['Thread Hiding Link']) { - return; - } - div = $.el('div', { - className: 'hide-thread-link', - textContent: 'Hide' - }); - apply = $.el('a', { - textContent: 'Apply', - href: 'javascript:;' - }); - $.on(apply, 'click', ThreadHiding.menu.hide); - makeStub = UI.checkbox('Stubs', 'Make stub'); - Menu.menu.addEntry({ - el: div, - order: 20, - open: function(arg) { - var isReply, thread; - thread = arg.thread, isReply = arg.isReply; - if (isReply || thread.isHidden || Conf['JSON Index'] && Conf['Index Mode'] === 'catalog') { - return false; - } - ThreadHiding.menu.thread = thread; - return true; - }, - subEntries: [ - { - el: apply - }, { - el: makeStub - } - ] - }); - div = $.el('a', { - className: 'show-thread-link', - textContent: 'Show', - href: 'javascript:;' - }); - $.on(div, 'click', ThreadHiding.menu.show); - Menu.menu.addEntry({ - el: div, - order: 20, - open: function(arg) { - var isReply, thread; - thread = arg.thread, isReply = arg.isReply; - if (isReply || !thread.isHidden || Conf['JSON Index'] && Conf['Index Mode'] === 'catalog') { - return false; - } - ThreadHiding.menu.thread = thread; - return true; - } - }); - hideStubLink = $.el('a', { - textContent: 'Hide stub', - href: 'javascript:;' - }); - $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); - return Menu.menu.addEntry({ - el: hideStubLink, - order: 15, - open: function(arg) { - var isReply, thread; - thread = arg.thread, isReply = arg.isReply; - if (isReply || !thread.isHidden || Conf['JSON Index'] && Conf['Index Mode'] === 'catalog') { - return false; - } - return ThreadHiding.menu.thread = thread; - } - }); - }, - hide: function() { - var makeStub, thread; - makeStub = $('input', this.parentNode).checked; - thread = ThreadHiding.menu.thread; - ThreadHiding.hide(thread, makeStub); - ThreadHiding.saveHiddenState(thread, makeStub); - return $.event('CloseMenu'); - }, - show: function() { - var thread; - thread = ThreadHiding.menu.thread; - ThreadHiding.show(thread); - ThreadHiding.saveHiddenState(thread); - return $.event('CloseMenu'); - }, - hideStub: function() { - var thread; - thread = ThreadHiding.menu.thread; - ThreadHiding.show(thread); - ThreadHiding.hide(thread, false); - ThreadHiding.saveHiddenState(thread, false); - $.event('CloseMenu'); - } - }, - makeButton: function(thread, type) { - var a; - a = $.el('a', { - className: type + "-thread-button", - href: 'javascript:;' - }); - $.extend(a, {innerHTML: ""}); - a.dataset.fullID = thread.fullID; - $.on(a, 'click', ThreadHiding.toggle); - return a; - }, - makeStub: function(thread, root) { - var a, numReplies, summary, threadDivider; - numReplies = $$(g.SITE.selectors.replyOriginal, root).length; - if (summary = $(g.SITE.selectors.summary, root)) { - numReplies += +summary.textContent.match(/\d+/); - } - a = ThreadHiding.makeButton(thread, 'show'); - $.add(a, $.tn(" " + thread.OP.info.nameBlock + " (" + (numReplies === 1 ? '1 reply' : numReplies + " replies") + ")")); - thread.stub = $.el('div', { - className: 'stub' - }); - if (Conf['Menu']) { - $.add(thread.stub, [a, Menu.makeButton(thread.OP)]); - } else { - $.add(thread.stub, a); - } - $.prepend(root, thread.stub); - if ((threadDivider = $(g.SITE.selectors.threadDivider, root))) { - return $.addClass(threadDivider, 'threadDivider'); - } - }, - saveHiddenState: function(thread, makeStub) { - if (thread.isHidden) { - ThreadHiding.db.set({ - boardID: thread.board.ID, - threadID: thread.ID, - val: { - makeStub: makeStub - } - }); - } else { - ThreadHiding.db["delete"]({ - boardID: thread.board.ID, - threadID: thread.ID - }); - } - return ThreadHiding.catalogSet(thread.board); - }, - toggle: function(thread) { - if (!(thread instanceof Thread)) { - thread = g.threads.get(this.dataset.fullID); - } - if (thread.isHidden) { - ThreadHiding.show(thread); - } else { - ThreadHiding.hide(thread); - } - return ThreadHiding.saveHiddenState(thread); - }, - hide: function(thread, makeStub) { - var threadRoot; - if (makeStub == null) { - makeStub = Conf['Stubs']; - } - if (thread.isHidden) { - return; - } - threadRoot = thread.nodes.root; - thread.isHidden = true; - Index.updateHideLabel(); - if (thread.catalogView && !Index.showHiddenThreads) { - $.rm(thread.catalogView.nodes.root); - $.event('PostsRemoved', null, Index.root); - } - if (!makeStub) { - return threadRoot.hidden = true; - } - return ThreadHiding.makeStub(thread, threadRoot); - }, - show: function(thread) { - var threadRoot; - if (thread.stub) { - $.rm(thread.stub); - delete thread.stub; - } - threadRoot = thread.nodes.root; - threadRoot.hidden = thread.isHidden = false; - Index.updateHideLabel(); - if (thread.catalogView && Index.showHiddenThreads) { - $.rm(thread.catalogView.nodes.root); - return $.event('PostsRemoved', null, Index.root); - } - } - }; - - return ThreadHiding; - -}).call(this); - -BoardConfig = (function() { - var BoardConfig; - - BoardConfig = { - cbs: [], - init: function() { - var boards, now, ref; - if (g.SITE.software !== 'yotsuba') { - return; - } - now = Date.now(); - if (!((now - 2 * $.HOUR < (ref = Conf['boardConfig'].lastChecked || 0) && ref <= now))) { - return $.ajax(location.protocol + "//a.4cdn.org/boards.json", { - onloadend: this.load - }); - } else { - boards = Conf['boardConfig'].boards; - return this.set(boards); - } - }, - load: function() { - var board, boards, err, i, len, ref; - if (this.status === 200 && this.response && this.response.boards) { - boards = $.dict(); - ref = this.response.boards; - for (i = 0, len = ref.length; i < len; i++) { - board = ref[i]; - boards[board.board] = board; - } - $.set('boardConfig', { - boards: boards, - lastChecked: Date.now() - }); - } else { - boards = Conf['boardConfig'].boards; - err = (function() { - switch (this.status) { - case 0: - return 'Connection Error'; - case 200: - return 'Invalid Data'; - default: - return "Error " + this.statusText + " (" + this.status + ")"; - } - }).call(this); - new Notice('warning', "Failed to load board configuration. " + err, 20); - } - return BoardConfig.set(boards); - }, - set: function(boards1) { - var ID, board, cb, i, len, ref, ref1; - this.boards = boards1; - ref = g.boards; - for (ID in ref) { - board = ref[ID]; - board.config = this.boards[ID] || {}; - } - ref1 = this.cbs; - for (i = 0, len = ref1.length; i < len; i++) { - cb = ref1[i]; - $.queueTask(cb); - } - }, - ready: function(cb) { - if (this.boards) { - return cb(); - } else { - return this.cbs.push(cb); - } - }, - sfwBoards: function(sfw) { - var board, data, ref, results; - ref = this.boards || Conf['boardConfig'].boards; - results = []; - for (board in ref) { - data = ref[board]; - if (!!data.ws_board === sfw) { - results.push(board); - } - } - return results; - }, - isSFW: function(board) { - var ref; - return !!((ref = (this.boards || Conf['boardConfig'].boards)[board]) != null ? ref.ws_board : void 0); - }, - domain: function(board) { - return "boards." + (BoardConfig.isSFW(board) ? '4channel' : '4chan') + ".org"; - }, - isArchived: function(board) { - var data; - data = (this.boards || Conf['boardConfig'].boards)[board]; - return !data || data.is_archived; - }, - noAudio: function(boardID) { - var boards; - if (g.SITE.software !== 'yotsuba') { - return false; - } - boards = this.boards || Conf['boardConfig'].boards; - return boards && boards[boardID] && !boards[boardID].webm_audio; - }, - title: function(boardID) { - var ref, ref1; - return ((ref = this.boards || Conf['boardConfig'].boards) != null ? (ref1 = ref[boardID]) != null ? ref1.title : void 0 : void 0) || ''; - } - }; - - return BoardConfig; - -}).call(this); - -Get = (function() { - var Get, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Get = { - url: function() { - var IDs, args, f, site, type; - type = arguments[0], IDs = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : []; - if ((site = g.sites[IDs.siteID]) && (f = $.getOwn(site.urls, type))) { - return f.apply(null, [IDs].concat(slice.call(args))); - } else { - return void 0; - } - }, - threadExcerpt: function(thread) { - var OP, excerpt, ref, ref1; - OP = thread.OP; - excerpt = ("/" + (decodeURIComponent(thread.board.ID)) + "/ - ") + (((ref = OP.info.subject) != null ? ref.trim() : void 0) || OP.commentDisplay().replace(/\n+/g, ' // ') || ((ref1 = OP.file) != null ? ref1.name : void 0) || ("No." + OP)); - if (excerpt.length > 73) { - return excerpt.slice(0, 70) + "..."; - } - return excerpt; - }, - threadFromRoot: function(root) { - var board; - if (root == null) { - return null; - } - board = root.dataset.board; - return g.threads.get((board ? encodeURIComponent(board) : g.BOARD.ID) + "." + (root.id.match(/\d*$/)[0])); - }, - threadFromNode: function(node) { - return Get.threadFromRoot($.x("ancestor-or-self::" + g.SITE.xpath.thread, node)); - }, - postFromRoot: function(root) { - var index, post; - if (root == null) { - return null; - } - post = g.posts.get(root.dataset.fullID); - index = root.dataset.clone; - if (index) { - return post.clones[+index]; - } else { - return post; - } - }, - postFromNode: function(root) { - return Get.postFromRoot($.x("ancestor-or-self::" + g.SITE.xpath.postContainer + "[1]", root)); - }, - postDataFromLink: function(link) { - var boardID, match, postID, ref, ref1, threadID; - if (link.dataset.postID) { - ref = link.dataset, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - threadID || (threadID = 0); - } else { - match = link.href.match(g.SITE.regexp.quotelink); - ref1 = match.slice(1), boardID = ref1[0], threadID = ref1[1], postID = ref1[2]; - postID || (postID = threadID); - } - return { - boardID: boardID, - threadID: +threadID, - postID: +postID - }; - }, - allQuotelinksLinkingTo: function(post) { - var fullID, handleQuotes, i, len, posts, qPost, quote, quotelinks, ref; - quotelinks = []; - posts = g.posts; - fullID = post.fullID; - handleQuotes = function(qPost, type) { - var clone, i, len, ref; - quotelinks.push.apply(quotelinks, qPost.nodes[type]); - ref = qPost.clones; - for (i = 0, len = ref.length; i < len; i++) { - clone = ref[i]; - quotelinks.push.apply(quotelinks, clone.nodes[type]); - } - }; - posts.forEach(function(qPost) { - if (indexOf.call(qPost.quotes, fullID) >= 0) { - return handleQuotes(qPost, 'quotelinks'); - } - }); - if (Conf['Quote Backlinks']) { - ref = post.quotes; - for (i = 0, len = ref.length; i < len; i++) { - quote = ref[i]; - if (qPost = posts.get(quote)) { - handleQuotes(qPost, 'backlinks'); - } - } - } - return quotelinks.filter(function(quotelink) { - var boardID, postID, ref1; - ref1 = Get.postDataFromLink(quotelink), boardID = ref1.boardID, postID = ref1.postID; - return boardID === post.board.ID && postID === post.ID; - }); - } - }; - - return Get; - -}).call(this); - -Header = (function() { - var Header, - slice = [].slice; - - Header = { - init: function() { - var barFixedToggler, barPositionToggler, box, cs, customNavToggler, editCustomNav, footerToggler, headerToggler, linkJustifyToggler, menuButton, scrollHeaderToggler, shortcutToggler; - $.onExists(doc, 'body', (function(_this) { - return function() { - if (!Main.isThisPageLegit()) { - return; - } - $.add(_this.bar, [_this.noticesRoot, _this.toggle]); - $.prepend(d.body, _this.bar); - $.add(d.body, Header.hover); - return _this.setBarPosition(Conf['Bottom Header']); - }; - })(this)); - this.menu = new UI.Menu('header'); - menuButton = $.el('span', { - className: 'menu-button' - }); - $.extend(menuButton, {innerHTML: ""}); - box = UI.checkbox; - barFixedToggler = box('Fixed Header', 'Fixed Header'); - headerToggler = box('Header auto-hide', 'Auto-hide header'); - scrollHeaderToggler = box('Header auto-hide on scroll', 'Auto-hide header on scroll'); - barPositionToggler = box('Bottom Header', 'Bottom header'); - linkJustifyToggler = box('Centered links', 'Centered links'); - customNavToggler = box('Custom Board Navigation', 'Custom board navigation'); - footerToggler = box('Bottom Board List', 'Hide bottom board list'); - shortcutToggler = box('Shortcut Icons', 'Shortcut Icons'); - editCustomNav = $.el('a', { - textContent: 'Edit custom board navigation', - href: 'javascript:;' - }); - this.barFixedToggler = barFixedToggler.firstElementChild; - this.scrollHeaderToggler = scrollHeaderToggler.firstElementChild; - this.barPositionToggler = barPositionToggler.firstElementChild; - this.linkJustifyToggler = linkJustifyToggler.firstElementChild; - this.headerToggler = headerToggler.firstElementChild; - this.footerToggler = footerToggler.firstElementChild; - this.shortcutToggler = shortcutToggler.firstElementChild; - this.customNavToggler = customNavToggler.firstElementChild; - $.on(menuButton, 'click', this.menuToggle); - $.on(this.headerToggler, 'change', this.toggleBarVisibility); - $.on(this.barFixedToggler, 'change', this.toggleBarFixed); - $.on(this.barPositionToggler, 'change', this.toggleBarPosition); - $.on(this.scrollHeaderToggler, 'change', this.toggleHideBarOnScroll); - $.on(this.linkJustifyToggler, 'change', this.toggleLinkJustify); - $.on(this.footerToggler, 'change', this.toggleFooterVisibility); - $.on(this.shortcutToggler, 'change', this.toggleShortcutIcons); - $.on(this.customNavToggler, 'change', this.toggleCustomNav); - $.on(editCustomNav, 'click', this.editCustomNav); - this.setBarFixed(Conf['Fixed Header']); - this.setHideBarOnScroll(Conf['Header auto-hide on scroll']); - this.setBarVisibility(Conf['Header auto-hide']); - this.setLinkJustify(Conf['Centered links']); - this.setShortcutIcons(Conf['Shortcut Icons']); - this.setFooterVisibility(Conf['Bottom Board List']); - $.sync('Fixed Header', this.setBarFixed); - $.sync('Header auto-hide on scroll', this.setHideBarOnScroll); - $.sync('Bottom Header', this.setBarPosition); - $.sync('Shortcut Icons', this.setShortcutIcons); - $.sync('Header auto-hide', this.setBarVisibility); - $.sync('Centered links', this.setLinkJustify); - $.sync('Bottom Board List', this.setFooterVisibility); - this.addShortcut('menu', menuButton, 900); - this.menu.addEntry({ - el: $.el('span', { - textContent: 'Header' - }), - order: 107, - subEntries: [ - { - el: barFixedToggler - }, { - el: headerToggler - }, { - el: scrollHeaderToggler - }, { - el: barPositionToggler - }, { - el: linkJustifyToggler - }, { - el: footerToggler - }, { - el: shortcutToggler - }, { - el: customNavToggler - }, { - el: editCustomNav - } - ] - }); - $.on(window, 'load popstate', Header.hashScroll); - $.on(d, 'CreateNotification', this.createNotification); - this.setBoardList(); - $.onExists(doc, g.SITE.selectors.boardList + " + *", Header.generateFullBoardList); - Main.ready(function() { - var a, absbot, footer, i, len, ref; - if (g.SITE.software === 'yotsuba' && !(footer = $.id('boardNavDesktopFoot'))) { - if (!(absbot = $.id('absbot'))) { - return; - } - footer = $.id('boardNavDesktop').cloneNode(true); - footer.id = 'boardNavDesktopFoot'; - $('#navtopright', footer).id = 'navbotright'; - $('#settingsWindowLink', footer).id = 'settingsWindowLinkBot'; - $.before(absbot, footer); - $.global(function() { - return window.cloneTopNav = function() {}; - }); - } - if ((Header.bottomBoardList = $(g.SITE.selectors.boardListBottom))) { - ref = $$('a', Header.bottomBoardList); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - if (a.hostname === location.hostname && a.pathname.split('/')[1] === g.BOARD.ID) { - a.className = 'current'; - } - } - return CatalogLinks.setLinks(Header.bottomBoardList); - } - }); - if (g.SITE.software === 'yotsuba' && (g.VIEW === 'catalog' || !Conf['Disable Native Extension'])) { - cs = $.el('a', { - href: 'javascript:;' - }); - if (g.VIEW === 'catalog') { - cs.title = cs.textContent = 'Catalog Settings'; - cs.className = 'fa fa-book'; - } else { - cs.title = cs.textContent = '4chan Settings'; - cs.className = 'native-settings'; - } - $.on(cs, 'click', function() { - return $.id('settingsWindowLink').click(); - }); - this.addShortcut('native', cs, 810); - } - return this.enableDesktopNotifications(); - }, - bar: $.el('div', { - id: 'header-bar' - }), - noticesRoot: $.el('div', { - id: 'notifications' - }), - shortcuts: $.el('span', { - id: 'shortcuts' - }), - hover: $.el('div', { - id: 'hoverUI' - }), - toggle: $.el('div', { - id: 'scroll-marker' - }), - setBoardList: function() { - var boardList, btn; - Header.boardList = boardList = $.el('span', { - id: 'board-list' - }); - $.extend(boardList, {innerHTML: ""}); - btn = $('.hide-board-list-button', boardList); - $.on(btn, 'click', Header.toggleBoardList); - $.prepend(Header.bar, [Header.boardList, Header.shortcuts]); - Header.setCustomNav(Conf['Custom Board Navigation']); - Header.generateBoardList(Conf['boardnav']); - $.sync('Custom Board Navigation', Header.setCustomNav); - return $.sync('boardnav', Header.generateBoardList); - }, - generateFullBoardList: function() { - var a, fullBoardList, i, len, nodes, ref; - if (g.SITE.transformBoardList) { - nodes = g.SITE.transformBoardList(); - } else { - nodes = slice.call($(g.SITE.selectors.boardList).cloneNode(true).childNodes); - } - fullBoardList = $('.boardList', Header.boardList); - $.add(fullBoardList, nodes); - ref = $$('a', fullBoardList); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - if (a.hostname === location.hostname && a.pathname.split('/')[1] === g.BOARD.ID) { - a.className = 'current'; - } - } - return CatalogLinks.setLinks(fullBoardList); - }, - generateBoardList: function(boardnav) { - var list, nodes, re, t; - list = $('#custom-board-list', Header.boardList); - $.rmAll(list); - if (!boardnav) { - return; - } - boardnav = boardnav.replace(/(\r\n|\n|\r)/g, ' '); - re = /[\w@]+(-(all|title|replace|full|index|catalog|archive|expired|nt|(mode|sort|text):"[^"]+"(,"[^"]+")?))*|[^\w@]+/g; - nodes = (function() { - var i, len, ref, results; - ref = boardnav.match(re); - results = []; - for (i = 0, len = ref.length; i < len; i++) { - t = ref[i]; - results.push(Header.mapCustomNavigation(t)); - } - return results; - })(); - $.add(list, nodes); - return CatalogLinks.setLinks(list); - }, - mapCustomNavigation: function(t) { - var a, boardID, href, indexOptions, m, ref, ref1, text, url, urlIC; - if (/^[^\w@]/.test(t)) { - return $.tn(t); - } - text = url = null; - t = t.replace(/-text:"([^"]+)"(?:,"([^"]+)")?/g, function(m0, m1, m2) { - text = m1; - url = m2; - return ''; - }); - indexOptions = []; - t = t.replace(/-(?:mode|sort):"([^"]+)"/g, function(m0, m1) { - indexOptions.push(m1.toLowerCase().replace(/\ /g, '-')); - return ''; - }); - indexOptions = indexOptions.join('/'); - if (/^toggle-all/.test(t)) { - a = $.el('a', { - className: 'show-board-list-button', - textContent: text || '+', - href: 'javascript:;' - }); - $.on(a, 'click', Header.toggleBoardList); - return a; - } - if (/^external/.test(t)) { - a = $.el('a', { - href: url || 'javascript:;', - textContent: text || '+', - className: 'external' - }); - if (/-nt/.test(t)) { - a.target = '_blank'; - a.rel = 'noopener'; - } - return a; - } - boardID = t.split('-')[0]; - if (boardID === 'current') { - if ((ref = location.hostname) === 'boards.4chan.org' || ref === 'boards.4channel.org') { - boardID = g.BOARD.ID; - } else { - a = $.el('a', { - href: "/" + g.BOARD.ID + "/", - textContent: text || decodeURIComponent(g.BOARD.ID), - className: 'current' - }); - if (/-nt/.test(t)) { - a.target = '_blank'; - a.rel = 'noopener'; - } - if (/-index/.test(t)) { - a.dataset.only = 'index'; - } else if (/-catalog/.test(t)) { - a.dataset.only = 'catalog'; - a.href += 'catalog.html'; - } else if (/-(archive|expired)/.test(t)) { - a = a.firstChild; - } - return a; - } - } - a = (function() { - var ref1, urlV; - if (boardID === '@') { - return $.el('a', { - href: 'https://twitter.com/4chan', - title: '4chan Twitter', - textContent: '@' - }); - } - a = $.el('a', { - href: "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/", - textContent: boardID, - title: BoardConfig.title(boardID) - }); - if (((ref1 = g.VIEW) === 'catalog' || ref1 === 'archive') && (urlV = Get.url(g.VIEW, { - siteID: '4chan.org', - boardID: boardID - }))) { - a.href = urlV; - } - if (a.hostname === location.hostname && boardID === g.BOARD.ID) { - a.className = 'current'; - } - return a; - })(); - a.textContent = /-title/.test(t) || /-replace/.test(t) && a.hostname === location.hostname && boardID === g.BOARD.ID ? a.title || a.textContent : /-full/.test(t) ? ("/" + boardID + "/") + (a.title ? " - " + a.title : '') : text || boardID; - if (m = t.match(/-(index|catalog)/)) { - urlIC = CatalogLinks[m[1]]({ - siteID: '4chan.org', - boardID: boardID - }); - if (urlIC) { - a.dataset.only = m[1]; - a.href = urlIC; - if (m[1] === 'catalog') { - $.addClass(a, 'catalog'); - } - } else { - return a.firstChild; - } - } - if (Conf['JSON Index'] && indexOptions) { - a.dataset.indexOptions = indexOptions; - if (((ref1 = a.hostname) === 'boards.4chan.org' || ref1 === 'boards.4channel.org') && a.pathname.split('/')[2] === '') { - a.href += (a.hash ? '/' : '#') + indexOptions; - } - } - if (/-archive/.test(t)) { - if (href = Redirect.to('board', { - boardID: boardID - })) { - a.href = href; - } else { - return a.firstChild; - } - } - if (/-expired/.test(t)) { - if (BoardConfig.isArchived(boardID)) { - a.href = "//" + (BoardConfig.domain(boardID)) + "/" + boardID + "/archive"; - } else { - return a.firstChild; - } - } - if (/-nt/.test(t)) { - a.target = '_blank'; - a.rel = 'noopener'; - } - if (boardID === '@') { - $.addClass(a, 'navSmall'); - } - return a; - }, - toggleBoardList: function() { - var bar, custom, full, showBoardList; - bar = Header.bar; - custom = $('#custom-board-list', bar); - full = $('#full-board-list', bar); - showBoardList = !full.hidden; - custom.hidden = !showBoardList; - return full.hidden = showBoardList; - }, - setLinkJustify: function(centered) { - Header.linkJustifyToggler.checked = centered; - if (centered) { - return $.addClass(doc, 'centered-links'); - } else { - return $.rmClass(doc, 'centered-links'); - } - }, - toggleLinkJustify: function() { - var centered; - $.event('CloseMenu'); - centered = this.nodeName === 'INPUT' ? this.checked : void 0; - Header.setLinkJustify(centered); - return $.set('Centered links', centered); - }, - setBarFixed: function(fixed) { - Header.barFixedToggler.checked = fixed; - if (fixed) { - $.addClass(doc, 'fixed'); - return $.addClass(Header.bar, 'dialog'); - } else { - $.rmClass(doc, 'fixed'); - return $.rmClass(Header.bar, 'dialog'); - } - }, - toggleBarFixed: function() { - $.event('CloseMenu'); - Header.setBarFixed(this.checked); - Conf['Fixed Header'] = this.checked; - return $.set('Fixed Header', this.checked); - }, - setShortcutIcons: function(show) { - Header.shortcutToggler.checked = show; - if (show) { - return $.addClass(doc, 'shortcut-icons'); - } else { - return $.rmClass(doc, 'shortcut-icons'); - } - }, - toggleShortcutIcons: function() { - $.event('CloseMenu'); - Header.setShortcutIcons(this.checked); - Conf['Shortcut Icons'] = this.checked; - return $.set('Shortcut Icons', this.checked); - }, - setBarVisibility: function(hide) { - Header.headerToggler.checked = hide; - $.event('CloseMenu'); - (hide ? $.addClass : $.rmClass)(Header.bar, 'autohide'); - return (hide ? $.addClass : $.rmClass)(doc, 'autohide'); - }, - toggleBarVisibility: function() { - var hide, message; - hide = this.nodeName === 'INPUT' ? this.checked : !$.hasClass(Header.bar, 'autohide'); - Conf['Header auto-hide'] = hide; - $.set('Header auto-hide', hide); - Header.setBarVisibility(hide); - message = "The header bar will " + (hide ? 'automatically hide itself.' : 'remain visible.'); - return new Notice('info', message, 2); - }, - setHideBarOnScroll: function(hide) { - Header.scrollHeaderToggler.checked = hide; - if (hide) { - $.on(window, 'scroll', Header.hideBarOnScroll); - return; - } - $.off(window, 'scroll', Header.hideBarOnScroll); - $.rmClass(Header.bar, 'scroll'); - return Header.bar.classList.toggle('autohide', Conf['Header auto-hide']); - }, - toggleHideBarOnScroll: function() { - var hide; - hide = this.checked; - $.cb.checked.call(this); - return Header.setHideBarOnScroll(hide); - }, - hideBarOnScroll: function() { - var offsetY; - offsetY = window.pageYOffset; - if (offsetY > (Header.previousOffset || 0)) { - $.addClass(Header.bar, 'autohide', 'scroll'); - } else { - $.rmClass(Header.bar, 'autohide', 'scroll'); - } - return Header.previousOffset = offsetY; - }, - setBarPosition: function(bottom) { - var args, ref; - if ((ref = Header.barPositionToggler) != null) { - ref.checked = bottom; - } - $.event('CloseMenu'); - args = bottom ? ['bottom-header', 'top-header', 'after'] : ['top-header', 'bottom-header', 'add']; - $.addClass(doc, args[0]); - $.rmClass(doc, args[1]); - return $[args[2]](Header.bar, Header.noticesRoot); - }, - toggleBarPosition: function() { - $.cb.checked.call(this); - return Header.setBarPosition(this.checked); - }, - setFooterVisibility: function(hide) { - Header.footerToggler.checked = hide; - return doc.classList.toggle('hide-bottom-board-list', hide); - }, - toggleFooterVisibility: function() { - var hide, message; - $.event('CloseMenu'); - hide = this.nodeName === 'INPUT' ? this.checked : $.hasClass(doc, 'hide-bottom-board-list'); - Header.setFooterVisibility(hide); - $.set('Bottom Board List', hide); - message = hide ? 'The bottom navigation will now be hidden.' : 'The bottom navigation will remain visible.'; - return new Notice('info', message, 2); - }, - setCustomNav: function(show) { - var btn, cust, full, ref; - Header.customNavToggler.checked = show; - cust = $('#custom-board-list', Header.bar); - full = $('#full-board-list', Header.bar); - btn = $('.hide-board-list-container', full); - return ref = show ? [false, true, false] : [true, false, true], cust.hidden = ref[0], full.hidden = ref[1], btn.hidden = ref[2], ref; - }, - toggleCustomNav: function() { - $.cb.checked.call(this); - return Header.setCustomNav(this.checked); - }, - editCustomNav: function() { - var settings; - Settings.open('Advanced'); - settings = $.id('fourchanx-settings'); - return $('[name=boardnav]', settings).focus(); - }, - hashScroll: function(e) { - var el, hash; - if (e) { - if (e.state) { - return; - } - if (!history.state) { - history.replaceState({}, ''); - } - } - if ((hash = location.hash.slice(1))) { - ReplyPruning.showIfHidden(hash); - if ((el = $.id(hash))) { - return $.queueTask(function() { - return Header.scrollTo(el); - }); - } - } - }, - scrollTo: function(root, down, needed) { - var height, x; - if (!root.offsetParent) { - return; - } - if (down) { - x = Header.getBottomOf(root); - if (Conf['Fixed Header'] && Conf['Header auto-hide on scroll'] && Conf['Bottom header']) { - height = Header.bar.getBoundingClientRect().height; - if (x <= 0) { - if (!Header.isHidden()) { - x += height; - } - } else { - if (Header.isHidden()) { - x -= height; - } - } - } - if (!(needed && x >= 0)) { - return window.scrollBy(0, -x); - } - } else { - x = Header.getTopOf(root); - if (Conf['Fixed Header'] && Conf['Header auto-hide on scroll'] && !Conf['Bottom header']) { - height = Header.bar.getBoundingClientRect().height; - if (x >= 0) { - if (!Header.isHidden()) { - x += height; - } - } else { - if (Header.isHidden()) { - x -= height; - } - } - } - if (!(needed && x >= 0)) { - return window.scrollBy(0, x); - } - } - }, - scrollToIfNeeded: function(root, down) { - return Header.scrollTo(root, down, true); - }, - getTopOf: function(root) { - var headRect, top; - top = root.getBoundingClientRect().top; - if (Conf['Fixed Header'] && !Conf['Bottom Header']) { - headRect = Header.toggle.getBoundingClientRect(); - top -= headRect.top + headRect.height; - } - return top; - }, - getBottomOf: function(root) { - var bottom, clientHeight, headRect; - clientHeight = doc.clientHeight; - bottom = clientHeight - root.getBoundingClientRect().bottom; - if (Conf['Fixed Header'] && Conf['Bottom Header']) { - headRect = Header.toggle.getBoundingClientRect(); - bottom -= clientHeight - headRect.bottom + headRect.height; - } - return bottom; - }, - isNodeVisible: function(node) { - var height; - if (d.hidden || !doc.contains(node)) { - return false; - } - height = node.getBoundingClientRect().height; - return Header.getTopOf(node) + height >= 0 && Header.getBottomOf(node) + height >= 0; - }, - isHidden: function() { - var top; - top = Header.bar.getBoundingClientRect().top; - if (Conf['Bottom header']) { - return top === doc.clientHeight; - } else { - return top < 0; - } - }, - addShortcut: function(id, el, index) { - var i, item, len, ref, shortcut; - shortcut = $.el('span', { - id: "shortcut-" + id, - className: 'shortcut brackets-wrap' - }); - $.add(shortcut, el); - shortcut.dataset.index = index; - ref = $$('[data-index]', Header.shortcuts); - for (i = 0, len = ref.length; i < len; i++) { - item = ref[i]; - if (!(+item.dataset.index > +index)) { - continue; - } - $.before(item, shortcut); - return; - } - return $.add(Header.shortcuts, shortcut); - }, - rmShortcut: function(el) { - return $.rm(el.parentElement); - }, - menuToggle: function(e) { - return Header.menu.toggle(e, this, g); - }, - createNotification: function(e) { - var content, lifetime, notice, ref, type; - ref = e.detail, type = ref.type, content = ref.content, lifetime = ref.lifetime; - return notice = new Notice(type, content, lifetime); - }, - areNotificationsEnabled: false, - enableDesktopNotifications: function() { - var authorize, disable, el, notice, ref; - if (!(window.Notification && Conf['Desktop Notifications'])) { - return; - } - switch (Notification.permission) { - case 'granted': - Header.areNotificationsEnabled = true; - return; - case 'denied': - return; - } - el = $.el('span', {innerHTML: "4chan X needs your permission to show desktop notifications. [FAQ]
      or "}); - ref = $$('button', el), authorize = ref[0], disable = ref[1]; - $.on(authorize, 'click', function() { - return Notification.requestPermission(function(status) { - Header.areNotificationsEnabled = status === 'granted'; - if (status === 'default') { - return; - } - return notice.close(); - }); - }); - $.on(disable, 'click', function() { - $.set('Desktop Notifications', false); - return notice.close(); - }); - return notice = new Notice('info', el); - } - }; - - return Header; - -}).call(this); - -Index = (function() { - var Index, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Index = { - showHiddenThreads: false, - changed: {}, - enabledOn: function(arg) { - var boardID, siteID; - siteID = arg.siteID, boardID = arg.boardID; - return Conf['JSON Index'] && g.sites[siteID].software === 'yotsuba' && boardID !== 'f'; - }, - init: function() { - var arr, entries, i, input, inputs, k, l, label, len1, len2, name, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, select, sortEntry, tRaw, watchSettings; - if (g.VIEW !== 'index') { - return; - } - $.one(d, '4chanXInitFinished', this.cb.initFinished); - $.on(d, 'PostsInserted', this.cb.postsInserted); - if (!this.enabledOn(g.BOARD)) { - return; - } - this.enabled = true; - Callbacks.Post.push({ - name: 'Index Page Numbers', - cb: this.node - }); - Callbacks.CatalogThread.push({ - name: 'Catalog Features', - cb: this.catalogNode - }); - this.search = ((ref = history.state) != null ? ref.searched : void 0) || ''; - if ((ref1 = history.state) != null ? ref1.mode : void 0) { - Conf['Index Mode'] = (ref2 = history.state) != null ? ref2.mode : void 0; - } - this.currentSort = (ref3 = history.state) != null ? ref3.sort : void 0; - this.currentSort || (this.currentSort = typeof Conf['Index Sort'] === 'object' ? Conf['Index Sort'][g.BOARD.ID] || 'bump' : Conf['Index Sort']); - this.currentPage = this.getCurrentPage(); - this.processHash(); - $.addClass(doc, 'index-loading', (Conf['Index Mode'].replace(/\ /g, '-')) + "-mode"); - $.on(window, 'popstate', this.cb.popstate); - $.on(d, 'scroll', this.scroll); - $.on(d, 'SortIndex', this.cb.resort); - this.button = $.el('a', { - className: 'fa fa-refresh', - title: 'Refresh', - href: 'javascript:;', - textContent: 'Refresh Index' - }); - $.on(this.button, 'click', function() { - return Index.update(); - }); - Header.addShortcut('index-refresh', this.button, 590); - entries = []; - this.inputs = inputs = $.dict(); - ref4 = Config.Index; - for (name in ref4) { - arr = ref4[name]; - if (!(arr instanceof Array)) { - continue; - } - label = UI.checkbox(name, "" + name[0] + (name.slice(1).toLowerCase())); - label.title = arr[1]; - entries.push({ - el: label - }); - input = label.firstChild; - $.on(input, 'change', $.cb.checked); - inputs[name] = input; - } - $.on(inputs['Show Replies'], 'change', this.cb.replies); - $.on(inputs['Catalog Hover Expand'], 'change', this.cb.hover); - $.on(inputs['Pin Watched Threads'], 'change', this.cb.resort); - $.on(inputs['Anchor Hidden Threads'], 'change', this.cb.resort); - watchSettings = function(e) { - if ((input = $.getOwn(inputs, e.target.name))) { - input.checked = e.target.checked; - return $.event('change', null, input); - } - }; - $.on(d, 'OpenSettings', function() { - return $.on($.id('fourchanx-settings'), 'change', watchSettings); - }); - sortEntry = UI.checkbox('Per-Board Sort Type', 'Per-board sort type', typeof Conf['Index Sort'] === 'object'); - sortEntry.title = 'Set the sorting order of each board independently.'; - $.on(sortEntry.firstChild, 'change', this.cb.perBoardSort); - entries.splice(3, 0, { - el: sortEntry - }); - Header.menu.addEntry({ - el: $.el('span', { - textContent: 'Index Navigation' - }), - order: 100, - subEntries: entries - }); - this.navLinks = $.el('div', { - className: 'navLinks json-index' - }); - $.extend(this.navLinks, {innerHTML: "Index Catalog Archive Bottom ×"}); - $('.cataloglink a', this.navLinks).href = CatalogLinks.catalog(); - if (!BoardConfig.isArchived(g.BOARD.ID)) { - $('.archlistlink', this.navLinks).hidden = true; - } - $.on($('#index-last-refresh a', this.navLinks), 'click', this.cb.refreshFront); - this.searchInput = $('#index-search', this.navLinks); - this.setupSearch(); - $.on(this.searchInput, 'input', this.onSearchInput); - $.on($('#index-search-clear', this.navLinks), 'click', this.clearSearch); - this.hideLabel = $('#hidden-label', this.navLinks); - $.on($('#hidden-toggle a', this.navLinks), 'click', this.cb.toggleHiddenThreads); - this.selectRev = $('#index-rev', this.navLinks); - this.selectMode = $('#index-mode', this.navLinks); - this.selectSort = $('#index-sort', this.navLinks); - this.selectSize = $('#index-size', this.navLinks); - $.on(this.selectRev, 'change', this.cb.sort); - $.on(this.selectMode, 'change', this.cb.mode); - $.on(this.selectSort, 'change', this.cb.sort); - $.on(this.selectSize, 'change', $.cb.value); - $.on(this.selectSize, 'change', this.cb.size); - ref5 = [this.selectMode, this.selectSize]; - for (k = 0, len1 = ref5.length; k < len1; k++) { - select = ref5[k]; - select.value = Conf[select.name]; - } - this.selectRev.checked = /-rev$/.test(Index.currentSort); - this.selectSort.value = Index.currentSort.replace(/-rev$/, ''); - this.lastLongOptions = $('#lastlong-options', this.navLinks); - this.lastLongInputs = $$('input', this.lastLongOptions); - this.lastLongThresholds = [0, 0]; - this.lastLongOptions.hidden = this.selectSort.value !== 'lastlong'; - ref6 = this.lastLongInputs; - for (i = l = 0, len2 = ref6.length; l < len2; i = ++l) { - input = ref6[i]; - $.on(input, 'change', this.cb.lastLongThresholds); - tRaw = Conf["Last Long Reply Thresholds " + i]; - input.value = this.lastLongThresholds[i] = typeof tRaw === 'object' ? (ref7 = tRaw[g.BOARD.ID]) != null ? ref7 : 100 : tRaw; - } - this.root = $.el('div', { - className: 'board json-index' - }); - $.on(this.root, 'click', this.cb.hoverToggle); - this.cb.size(); - this.cb.hover(); - this.pagelist = $.el('div', { - className: 'pagelist json-index' - }); - $.extend(this.pagelist, {innerHTML: "
      "}); - $('.cataloglink a', this.pagelist).href = CatalogLinks.catalog(); - $.on(this.pagelist, 'click', this.cb.pageNav); - this.update(true); - $.onExists(doc, 'title + *', function() { - return d.title = d.title.replace(/\ -\ Page\ \d+/, ''); - }); - $.onExists(doc, '.board > .thread > .postContainer, .board + *', function() { - var board, el, len3, m, ref8, timeEl, topNavPos; - g.SITE.Build.hat = $('.board > .thread > img:first-child'); - if (g.SITE.Build.hat) { - g.BOARD.threads.forEach(function(thread) { - if (thread.nodes.root) { - return $.prepend(thread.nodes.root, g.SITE.Build.hat.cloneNode(false)); - } - }); - $.addClass(doc, 'hats-enabled'); - $.addStyle(".catalog-thread::after {background-image: url(" + g.SITE.Build.hat.src + ");}"); - } - board = $('.board'); - $.replace(board, Index.root); - if (Index.loaded) { - $.event('PostsInserted', null, Index.root); - } - try { - d.implementation.createDocument(null, null, null).appendChild(board); - } catch (error) {} - ref8 = $$('.navLinks'); - for (m = 0, len3 = ref8.length; m < len3; m++) { - el = ref8[m]; - $.rm(el); - } - $.rm($.id('ctrl-top')); - topNavPos = $.id('delform').previousElementSibling; - $.before(topNavPos, $.el('hr')); - $.before(topNavPos, Index.navLinks); - timeEl = $('#index-last-refresh time', Index.navLinks); - if (timeEl.dataset.utc) { - return RelativeDates.update(timeEl); - } - }); - return Main.ready(function() { - var pagelist; - if ((pagelist = $('.pagelist'))) { - $.replace(pagelist, Index.pagelist); - } - return $.rmClass(doc, 'index-loading'); - }); - }, - scroll: function() { - var pageNum, threadIDs; - if (Index.req || !Index.liveThreadData || Conf['Index Mode'] !== 'infinite' || (window.scrollY <= doc.scrollHeight - (300 + window.innerHeight))) { - return; - } - if (Index.pageNum == null) { - Index.pageNum = Index.currentPage; - } - pageNum = ++Index.pageNum; - if (pageNum > Index.pagesNum) { - return Index.endNotice(); - } - threadIDs = Index.threadsOnPage(pageNum); - return Index.buildStructure(threadIDs); - }, - endNotice: (function() { - var notify, reset; - notify = false; - reset = function() { - return notify = false; - }; - return function() { - if (notify) { - return; - } - notify = true; - new Notice('info', "Last page reached.", 2); - return setTimeout(reset, 3 * $.SECOND); - }; - })(), - menu: { - init: function() { - if (!(g.VIEW === 'index' && Conf['Menu'] && Conf['Thread Hiding Link'] && Index.enabledOn(g.BOARD))) { - return; - } - return Menu.menu.addEntry({ - el: $.el('a', { - href: 'javascript:;', - className: 'has-shortcut-text' - }, {innerHTML: "Shift+click"}), - order: 20, - open: function(arg) { - var thread; - thread = arg.thread; - if (Conf['Index Mode'] !== 'catalog') { - return false; - } - this.el.firstElementChild.textContent = thread.isHidden ? 'Unhide' : 'Hide'; - if (this.cb) { - $.off(this.el, 'click', this.cb); - } - this.cb = function() { - $.event('CloseMenu'); - return Index.toggleHide(thread); - }; - $.on(this.el, 'click', this.cb); - return true; - } - }); - } - }, - node: function() { - if (this.isReply || this.isClone || !(Index.threadPosition[this.ID] != null)) { - return; - } - return this.thread.setPage(Math.floor(Index.threadPosition[this.ID] / Index.threadsNumPerPage) + 1); - }, - catalogNode: function() { - return $.on(this.nodes.root, 'mousedown click', (function(_this) { - return function(e) { - if (!(e.button === 0 && e.shiftKey)) { - return; - } - if (e.type === 'click') { - Index.toggleHide(_this.thread); - } - return e.preventDefault(); - }; - })(this)); - }, - toggleHide: function(thread) { - if (Index.showHiddenThreads) { - ThreadHiding.show(thread); - if (!ThreadHiding.db.get({ - boardID: thread.board.ID, - threadID: thread.ID - })) { - return; - } - } else { - ThreadHiding.hide(thread); - } - return ThreadHiding.saveHiddenState(thread); - }, - cycleSortType: function() { - var i, k, len1, type, types; - types = slice.call(Index.selectSort.options).filter(function(option) { - return !option.disabled; - }); - for (i = k = 0, len1 = types.length; k < len1; i = ++k) { - type = types[i]; - if (type.selected) { - break; - } - } - types[(i + 1) % types.length].selected = true; - return $.event('change', null, Index.selectSort); - }, - cb: { - initFinished: function() { - Index.initFinishedFired = true; - return $.queueTask(function() { - return Index.cb.postsInserted(); - }); - }, - postsInserted: function() { - var n; - if (!Index.initFinishedFired) { - return; - } - n = 0; - g.posts.forEach(function(post) { - if (!post.isFetchedQuote && !post.indexRefreshSeen && doc.contains(post.nodes.root)) { - post.indexRefreshSeen = true; - return n++; - } - }); - if (n) { - return $.event('IndexRefresh'); - } - }, - toggleHiddenThreads: function() { - $('#hidden-toggle a', Index.navLinks).textContent = (Index.showHiddenThreads = !Index.showHiddenThreads) ? 'Hide' : 'Show'; - Index.sort(); - return Index.buildIndex(); - }, - mode: function() { - Index.pushState({ - mode: this.value - }); - return Index.pageLoad(false); - }, - sort: function() { - var value; - value = Index.selectRev.checked ? Index.selectSort.value + "-rev" : Index.selectSort.value; - Index.pushState({ - sort: value - }); - return Index.pageLoad(false); - }, - resort: function(e) { - var ref; - Index.changed.order = true; - if (!(e != null ? (ref = e.detail) != null ? ref.deferred : void 0 : void 0)) { - return Index.pageLoad(false); - } - }, - perBoardSort: function() { - var i, k; - Conf['Index Sort'] = this.checked ? $.dict() : ''; - Index.saveSort(); - for (i = k = 0; k < 2; i = ++k) { - Conf["Last Long Reply Thresholds " + i] = this.checked ? $.dict() : ''; - Index.saveLastLongThresholds(i); - } - }, - lastLongThresholds: function() { - var i, value; - i = slice.call(this.parentNode.children).indexOf(this); - value = +this.value; - if (!Number.isFinite(value)) { - this.value = Index.lastLongThresholds[i]; - return; - } - Index.lastLongThresholds[i] = value; - Index.saveLastLongThresholds(i); - Index.changed.order = true; - return Index.pageLoad(false); - }, - size: function(e) { - if (Conf['Index Mode'] !== 'catalog') { - $.rmClass(Index.root, 'catalog-small'); - $.rmClass(Index.root, 'catalog-large'); - } else if (Conf['Index Size'] === 'small') { - $.addClass(Index.root, 'catalog-small'); - $.rmClass(Index.root, 'catalog-large'); - } else { - $.addClass(Index.root, 'catalog-large'); - $.rmClass(Index.root, 'catalog-small'); - } - if (e) { - return Index.buildIndex(); - } - }, - replies: function() { - return Index.buildIndex(); - }, - hover: function() { - return doc.classList.toggle('catalog-hover-expand', Conf['Catalog Hover Expand']); - }, - hoverToggle: function(e) { - var input, thread; - if (Conf['Catalog Hover Toggle'] && $.hasClass(doc, 'catalog-mode') && !$.modifiedClick(e) && !$.x('ancestor-or-self::a', e.target)) { - input = Index.inputs['Catalog Hover Expand']; - input.checked = !input.checked; - $.event('change', null, input); - if ((thread = Get.threadFromNode(e.target))) { - Index.cb.catalogReplies.call(thread); - return Index.cb.hoverAdjust.call(thread.OP.nodes); - } - } - }, - popstate: function(e) { - var mode, nCommands, page, ref, searched, sort; - if (e != null ? e.state : void 0) { - ref = e.state, searched = ref.searched, mode = ref.mode, sort = ref.sort; - page = Index.getCurrentPage(); - Index.setState({ - search: searched, - mode: mode, - sort: sort, - page: page - }); - return Index.pageLoad(false); - } else { - nCommands = Index.processHash(); - if (Conf['Refreshed Navigation'] && nCommands) { - return Index.update(); - } else { - return Index.pageLoad(); - } - } - }, - pageNav: function(e) { - var a; - if ($.modifiedClick(e)) { - return; - } - switch (e.target.nodeName) { - case 'BUTTON': - e.target.blur(); - a = e.target.parentNode; - break; - case 'A': - a = e.target; - break; - default: - return; - } - if (a.textContent === 'Catalog') { - return; - } - e.preventDefault(); - return Index.userPageNav(+a.pathname.split(/\/+/)[2] || 1); - }, - refreshFront: function() { - Index.pushState({ - page: 1 - }); - return Index.update(); - }, - catalogReplies: function() { - if (Conf['Show Replies'] && $.hasClass(doc, 'catalog-hover-expand') && !this.catalogView.nodes.replies) { - return Index.buildCatalogReplies(this); - } - }, - hoverAdjust: function() { - var rect, style, x; - if (!$.hasClass(doc, 'catalog-hover-expand')) { - return; - } - rect = this.post.getBoundingClientRect(); - if ((x = $.minmax(0, -rect.left, doc.clientWidth - rect.right))) { - style = this.post.style; - style.left = x + "px"; - style.right = (-x) + "px"; - return $.one(this.root, 'mouseleave', function() { - return style.left = style.right = null; - }); - } - } - }, - scrollToIndex: function() { - return Header.scrollToIfNeeded((Index.navLinks.getBoundingClientRect().height ? Index.navLinks : Index.root)); - }, - getCurrentPage: function() { - return +window.location.pathname.split(/\/+/)[2] || 1; - }, - userPageNav: function(page) { - Index.pushState({ - page: page - }); - if (Conf['Refreshed Navigation']) { - return Index.update(); - } else { - return Index.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: function() { - var command, commands, hash, k, leftover, len1, mode, ref, sort, state; - hash = ((ref = location.href.match(/#.*/)) != null ? ref[0] : void 0) || ''; - state = { - replace: true - }; - commands = hash.slice(1).split('/'); - leftover = []; - for (k = 0, len1 = commands.length; k < len1; k++) { - command = commands[k]; - if ((mode = $.getOwn(Index.hashCommands.mode, command))) { - state.mode = mode; - } else if (command === 'index') { - state.mode = Conf['Previous Index Mode']; - state.page = 1; - } else if ((sort = $.getOwn(Index.hashCommands.sort, command.replace(/-rev$/, '')))) { - state.sort = sort; - if (/-rev$/.test(command)) { - state.sort += '-rev'; - } - } else if (/^s=/.test(command)) { - state.search = decodeURIComponent(command.slice(2)).replace(/\+/g, ' ').trim(); - } else { - leftover.push(command); - } - } - hash = leftover.join('/'); - if (hash) { - state.hash = "#" + hash; - } - Index.pushState(state); - return commands.length - leftover.length; - }, - pushState: function(state) { - var hash, pageBeforeSearch, pathname, ref, replace, search; - search = state.search, hash = state.hash, replace = state.replace; - pageBeforeSearch = (ref = history.state) != null ? ref.oldpage : void 0; - if ((search != null) && search !== Index.search) { - state.page = search ? 1 : pageBeforeSearch || 1; - if (!search) { - pageBeforeSearch = void 0; - } else if (!Index.search) { - pageBeforeSearch = Index.currentPage; - } - } - Index.setState(state); - pathname = Index.currentPage === 1 ? "/" + g.BOARD + "/" : "/" + g.BOARD + "/" + Index.currentPage; - hash || (hash = ''); - return history[replace ? 'replaceState' : 'pushState']({ - mode: Conf['Index Mode'], - sort: Index.currentSort, - searched: Index.search, - oldpage: pageBeforeSearch - }, '', location.protocol + "//" + location.host + pathname + hash); - }, - setState: function(arg) { - var hash, mode, page, ref, search, sort; - search = arg.search, mode = arg.mode, sort = arg.sort, page = arg.page, hash = arg.hash; - if ((search != null) && search !== Index.search) { - Index.changed.search = true; - Index.search = search; - } - if ((mode != null) && mode !== Conf['Index Mode']) { - Index.changed.mode = true; - Conf['Index Mode'] = mode; - $.set('Index Mode', mode); - if (!(mode === 'catalog' || Conf['Previous Index Mode'] === mode)) { - Conf['Previous Index Mode'] = mode; - $.set('Previous Index Mode', mode); - } - } - if ((sort != null) && sort !== Index.currentSort) { - Index.changed.sort = true; - Index.currentSort = sort; - Index.saveSort(); - } - if ((ref = Conf['Index Mode']) === 'all pages' || ref === 'catalog') { - page = 1; - } - if ((page != null) && page !== Index.currentPage) { - Index.changed.page = true; - Index.currentPage = page; - } - if (hash != null) { - return Index.changed.hash = true; - } - }, - savePerBoard: function(key, value) { - if (typeof Conf[key] === 'object') { - Conf[key][g.BOARD.ID] = value; - } else { - Conf[key] = value; - } - return $.set(key, Conf[key]); - }, - saveSort: function() { - return Index.savePerBoard('Index Sort', Index.currentSort); - }, - saveLastLongThresholds: function(i) { - return Index.savePerBoard("Last Long Reply Thresholds " + i, Index.lastLongThresholds[i]); - }, - pageLoad: function(scroll) { - var hash, mode, order, page, ref, search, sort, threads; - if (scroll == null) { - scroll = true; - } - if (!Index.liveThreadData) { - return; - } - ref = Index.changed, threads = ref.threads, order = ref.order, search = ref.search, mode = ref.mode, sort = ref.sort, page = ref.page, hash = ref.hash; - threads || (threads = search); - order || (order = sort); - if (threads || order) { - Index.sort(); - } - if (threads) { - Index.buildPagelist(); - } - if (search) { - Index.setupSearch(); - } - if (mode) { - Index.setupMode(); - } - if (sort) { - Index.setupSort(); - } - if (threads || mode || page || order) { - Index.buildIndex(); - } - if (threads || page) { - Index.setPage(); - } - if (scroll && !hash) { - Index.scrollToIndex(); - } - if (hash) { - Header.hashScroll(); - } - return Index.changed = {}; - }, - setupMode: function() { - var k, len1, mode, ref; - ref = ['paged', 'infinite', 'all pages', 'catalog']; - for (k = 0, len1 = ref.length; k < len1; k++) { - mode = ref[k]; - $[mode === Conf['Index Mode'] ? 'addClass' : 'rmClass'](doc, (mode.replace(/\ /g, '-')) + "-mode"); - } - Index.selectMode.value = Conf['Index Mode']; - Index.cb.size(); - Index.showHiddenThreads = false; - return $('#hidden-toggle a', Index.navLinks).textContent = 'Show'; - }, - setupSort: function() { - Index.selectRev.checked = /-rev$/.test(Index.currentSort); - Index.selectSort.value = Index.currentSort.replace(/-rev$/, ''); - return Index.lastLongOptions.hidden = Index.selectSort.value !== 'lastlong'; - }, - getPagesNum: function() { - if (Index.search) { - return Math.ceil(Index.sortedThreadIDs.length / Index.threadsNumPerPage); - } else { - return Index.pagesNum; - } - }, - getMaxPageNum: function() { - return Math.max(1, Index.getPagesNum()); - }, - buildPagelist: function() { - var a, i, k, maxPageNum, nodes, pagesRoot, ref; - pagesRoot = $('.pages', Index.pagelist); - maxPageNum = Index.getMaxPageNum(); - if (pagesRoot.childElementCount !== maxPageNum) { - nodes = []; - for (i = k = 1, ref = maxPageNum; k <= ref; i = k += 1) { - a = $.el('a', { - textContent: i, - href: i === 1 ? './' : i - }); - nodes.push($.tn('['), a, $.tn('] ')); - } - $.rmAll(pagesRoot); - return $.add(pagesRoot, nodes); - } - }, - setPage: function() { - var a, href, maxPageNum, next, pageNum, pagesRoot, prev, strong; - pageNum = Index.currentPage; - maxPageNum = Index.getMaxPageNum(); - pagesRoot = $('.pages', Index.pagelist); - prev = pagesRoot.previousSibling.firstChild; - next = pagesRoot.nextSibling.firstChild; - href = Math.max(pageNum - 1, 1); - prev.href = href === 1 ? './' : href; - prev.firstChild.disabled = href === pageNum; - href = Math.min(pageNum + 1, maxPageNum); - next.href = href === 1 ? './' : href; - next.firstChild.disabled = href === pageNum; - if (strong = $('strong', pagesRoot)) { - if (+strong.textContent === pageNum) { - return; - } - $.replace(strong, strong.firstChild); - } else { - strong = $.el('strong'); - } - if ((a = pagesRoot.children[pageNum - 1])) { - $.before(a, strong); - return $.add(strong, a); - } - }, - updateHideLabel: function() { - var hiddenCount, k, len1, ref, threadID; - if (!Index.hideLabel) { - return; - } - hiddenCount = 0; - ref = Index.liveThreadIDs; - for (k = 0, len1 = ref.length; k < len1; k++) { - threadID = ref[k]; - if (Index.isHidden(threadID)) { - hiddenCount++; - } - } - if (!hiddenCount) { - Index.hideLabel.hidden = true; - if (Index.showHiddenThreads) { - Index.cb.toggleHiddenThreads(); - } - return; - } - Index.hideLabel.hidden = false; - return $('#hidden-count', Index.navLinks).textContent = hiddenCount === 1 ? '1 hidden thread' : hiddenCount + " hidden threads"; - }, - update: function(firstTime) { - var oldReq; - if ((oldReq = Index.req)) { - delete Index.req; - oldReq.abort(); - } - if (Conf['Index Refresh Notifications']) { - Index.notice || (Index.notice = new Notice('info', 'Refreshing index...')); - Index.nTimeout || (Index.nTimeout = setTimeout(function() { - var ref; - return (ref = Index.notice) != null ? ref.el.lastElementChild.textContent += ' (disable JSON Index if this takes too long)' : void 0; - }, 3 * $.SECOND)); - } else { - Index.nTimeout || (Index.nTimeout = setTimeout(function() { - return Index.notice || (Index.notice = new Notice('info', 'Refreshing index... (disable JSON Index if this takes too long)')); - }, 3 * $.SECOND)); - } - if (!firstTime && d.readyState !== 'loading' && !$('.board + *')) { - location.reload(); - return; - } - Index.req = $.whenModified(g.SITE.urls.catalogJSON({ - boardID: g.BOARD.ID - }), 'Index', Index.load); - return $.addClass(Index.button, 'fa-spin'); - }, - load: function() { - var err, nTimeout, notice, ref, timeEl; - if (this !== Index.req) { - return; - } - $.rmClass(Index.button, 'fa-spin'); - notice = Index.notice, nTimeout = Index.nTimeout; - if (nTimeout) { - clearTimeout(nTimeout); - } - delete Index.nTimeout; - delete Index.req; - delete Index.notice; - if ((ref = this.status) !== 200 && ref !== 304) { - err = "Index refresh failed. " + (this.status ? "Error " + this.statusText + " (" + this.status + ")" : 'Connection Error'); - if (notice) { - notice.setType('warning'); - notice.el.lastElementChild.textContent = err; - setTimeout(notice.close, $.SECOND); - } else { - new Notice('warning', err, 1); - } - return; - } - try { - if (this.status === 200) { - Index.parse(this.response); - } else if (this.status === 304) { - Index.pageLoad(); - } - } catch (error) { - err = error; - c.error("Index failure: " + err.message, err.stack); - if (notice) { - notice.setType('error'); - notice.el.lastElementChild.textContent = 'Index refresh failed.'; - setTimeout(notice.close, $.SECOND); - } else { - new Notice('error', 'Index refresh failed.', 1); - } - return; - } - if (notice) { - if (Conf['Index Refresh Notifications']) { - notice.setType('success'); - notice.el.lastElementChild.textContent = 'Index refreshed!'; - setTimeout(notice.close, $.SECOND); - } else { - notice.close(); - } - } - timeEl = $('#index-last-refresh time', Index.navLinks); - timeEl.dataset.utc = Date.parse(this.getResponseHeader('Last-Modified')); - return RelativeDates.update(timeEl); - }, - parse: function(pages) { - $.cleanCache(function(url) { - return /^https?:\/\/a\.4cdn\.org\//.test(url); - }); - Index.parseThreadList(pages); - Index.changed.threads = true; - return Index.pageLoad(); - }, - parseThreadList: function(pages) { - var ID, data, i, k, l, len1, len2, obj, ref, ref1, ref2, reply, results; - Index.pagesNum = pages.length; - Index.threadsNumPerPage = ((ref = pages[0]) != null ? ref.threads.length : void 0) || 1; - Index.liveThreadData = pages.reduce((function(arr, next) { - return arr.concat(next.threads); - }), []); - Index.liveThreadIDs = Index.liveThreadData.map(function(data) { - return data.no; - }); - Index.liveThreadDict = $.dict(); - Index.threadPosition = $.dict(); - Index.parsedThreads = $.dict(); - Index.replyData = $.dict(); - ref1 = Index.liveThreadData; - for (i = k = 0, len1 = ref1.length; k < len1; i = ++k) { - data = ref1[i]; - Index.liveThreadDict[data.no] = data; - Index.threadPosition[data.no] = i; - Index.parsedThreads[data.no] = obj = g.SITE.Build.parseJSON(data, g.BOARD); - obj.filterResults = results = Filter.test(obj); - obj.isOnTop = results.top; - obj.isHidden = results.hide || ThreadHiding.isHidden(obj.boardID, obj.threadID); - if (data.last_replies) { - ref2 = data.last_replies; - for (l = 0, len2 = ref2.length; l < len2; l++) { - reply = ref2[l]; - Index.replyData[g.BOARD + "." + reply.no] = reply; - } - } - } - if (Index.liveThreadData[0]) { - g.SITE.Build.spoilerRange[g.BOARD.ID] = Index.liveThreadData[0].custom_spoiler; - } - g.BOARD.threads.forEach(function(thread) { - var ref3; - if (ref3 = thread.ID, indexOf.call(Index.liveThreadIDs, ref3) < 0) { - return thread.collect(); - } - }); - $.event('IndexUpdate', { - threads: (function() { - var len3, m, ref3, results1; - ref3 = Index.liveThreadIDs; - results1 = []; - for (m = 0, len3 = ref3.length; m < len3; m++) { - ID = ref3[m]; - results1.push(g.BOARD + "." + ID); - } - return results1; - })() - }); - }, - isHidden: function(threadID) { - var thread; - if ((thread = g.BOARD.threads.get(threadID)) && thread.OP && !thread.OP.isFetchedQuote) { - return thread.isHidden; - } else { - return Index.parsedThreads[threadID].isHidden; - } - }, - isHiddenReply: function(threadID, replyData) { - return PostHiding.isHidden(g.BOARD.ID, threadID, replyData.no) || Filter.isHidden(g.SITE.Build.parseJSON(replyData, g.BOARD)); - }, - buildThreads: function(threadIDs, isCatalog, withReplies) { - var ID, OP, err, errors, isStale, k, lastPost, len1, newPosts, newThreads, obj, opRoot, t, thread, threadData, threads; - threads = []; - newThreads = []; - newPosts = []; - for (k = 0, len1 = threadIDs.length; k < len1; k++) { - ID = threadIDs[k]; - try { - threadData = Index.liveThreadDict[ID]; - if ((thread = g.BOARD.threads.get(ID))) { - isStale = (thread.json !== threadData) && (JSON.stringify(thread.json) !== JSON.stringify(threadData)); - if (isStale) { - thread.setCount('post', threadData.replies + 1, threadData.bumplimit); - thread.setCount('file', threadData.images + !!threadData.ext, threadData.imagelimit); - thread.setStatus('Sticky', !!threadData.sticky); - thread.setStatus('Closed', !!threadData.closed); - } - if (thread.catalogView) { - $.rm(thread.catalogView.nodes.replies); - thread.catalogView.nodes.replies = null; - } - } else { - thread = new Thread(ID, g.BOARD); - newThreads.push(thread); - } - lastPost = threadData.last_replies && threadData.last_replies.length ? threadData.last_replies[threadData.last_replies.length - 1].no : ID; - if (lastPost > thread.lastPost) { - thread.lastPost = lastPost; - } - thread.json = threadData; - threads.push(thread); - if ((OP = thread.OP) && !OP.isFetchedQuote) { - OP.setCatalogOP(isCatalog); - thread.setPage(Math.floor(Index.threadPosition[ID] / Index.threadsNumPerPage) + 1); - } else { - obj = Index.parsedThreads[ID]; - opRoot = g.SITE.Build.post(obj); - OP = new Post(opRoot, thread, g.BOARD); - OP.filterResults = obj.filterResults; - newPosts.push(OP); - } - if (!(isCatalog && thread.nodes.root)) { - g.SITE.Build.thread(thread, threadData, withReplies); - } - } catch (error) { - err = error; - if (!errors) { - errors = []; - } - errors.push({ - message: "Parsing of Thread No." + thread + " failed. Thread will be skipped.", - error: err, - html: opRoot != null ? opRoot.outerHTML : void 0 - }); - } - } - if (errors) { - Main.handleErrors(errors); - } - if (withReplies) { - newPosts = newPosts.concat(Index.buildReplies(threads)); - } - Main.callbackNodes('Thread', newThreads); - Main.callbackNodes('Post', newPosts); - Index.updateHideLabel(); - $.event('IndexRefreshInternal', { - threadIDs: (function() { - var l, len2, results1; - results1 = []; - for (l = 0, len2 = threads.length; l < len2; l++) { - t = threads[l]; - results1.push(t.fullID); - } - return results1; - })(), - isCatalog: isCatalog - }); - return threads; - }, - buildReplies: function(threads) { - var data, err, errors, k, l, lastReplies, len1, len2, node, nodes, post, posts, thread; - posts = []; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - if (!(lastReplies = Index.liveThreadDict[thread.ID].last_replies)) { - continue; - } - nodes = []; - for (l = 0, len2 = lastReplies.length; l < len2; l++) { - data = lastReplies[l]; - if ((post = thread.posts.get(data.no)) && !post.isFetchedQuote) { - nodes.push(post.nodes.root); - continue; - } - nodes.push(node = g.SITE.Build.postFromObject(data, thread.board.ID)); - try { - posts.push(new Post(node, thread, thread.board)); - } catch (error) { - err = error; - if (!errors) { - errors = []; - } - errors.push({ - message: "Parsing of Post No." + data.no + " failed. Post will be skipped.", - error: err, - html: node != null ? node.outerHTML : void 0 - }); - } - } - $.add(thread.nodes.root, nodes); - } - if (errors) { - Main.handleErrors(errors); - } - return posts; - }, - buildCatalogViews: function(threads) { - var ID, catalogThreads, k, len1, page, root, thread; - catalogThreads = []; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - if (!(!thread.catalogView)) { - continue; - } - ID = thread.ID; - page = Math.floor(Index.threadPosition[ID] / Index.threadsNumPerPage) + 1; - root = g.SITE.Build.catalogThread(thread, Index.liveThreadDict[ID], page); - catalogThreads.push(new CatalogThread(root, thread)); - } - Main.callbackNodes('CatalogThread', catalogThreads); - }, - sizeCatalogViews: function(threads) { - var height, k, len1, ratio, ref, size, thread, thumb, width; - size = Conf['Index Size'] === 'small' ? 150 : 250; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - thumb = thread.catalogView.nodes.thumb; - ref = thumb.dataset, width = ref.width, height = ref.height; - if (!width) { - continue; - } - ratio = size / Math.max(width, height); - thumb.style.width = width * ratio + 'px'; - thumb.style.height = height * ratio + 'px'; - } - }, - buildCatalogReplies: function(thread) { - var data, k, lastReplies, len1, nodes, replies, reply; - nodes = thread.catalogView.nodes; - if (!(lastReplies = Index.liveThreadDict[thread.ID].last_replies)) { - return; - } - replies = []; - for (k = 0, len1 = lastReplies.length; k < len1; k++) { - data = lastReplies[k]; - if (Index.isHiddenReply(thread.ID, data)) { - continue; - } - reply = g.SITE.Build.catalogReply(thread, data); - RelativeDates.update($('time', reply)); - $.on($('.catalog-reply-preview', reply), 'mouseover', QuotePreview.mouseover); - replies.push(reply); - } - nodes.replies = $.el('div', { - className: 'catalog-replies' - }); - $.add(nodes.replies, replies); - $.add(thread.OP.nodes.post, nodes.replies); - }, - sort: function() { - var lastlong, lastlongD, liveThreadData, liveThreadIDs, repliesAvailable, sortType, thread, threadIDs, tmp_time; - liveThreadIDs = Index.liveThreadIDs, liveThreadData = Index.liveThreadData; - if (!liveThreadData) { - return; - } - tmp_time = new Date().getTime() / 1000; - sortType = Index.currentSort.replace(/-rev$/, ''); - Index.sortedThreadIDs = (function() { - var k, len1; - switch (sortType) { - case 'lastreply': - case 'lastlong': - repliesAvailable = liveThreadData.some(function(thread) { - var ref; - return (ref = thread.last_replies) != null ? ref.length : void 0; - }); - lastlong = function(thread) { - var i, k, len, r, ref, ref1; - if (!repliesAvailable) { - return thread.last_modified; - } - ref = thread.last_replies || []; - for (i = k = ref.length - 1; k >= 0; i = k += -1) { - r = ref[i]; - if (Index.isHiddenReply(thread.no, r)) { - continue; - } - if (sortType === 'lastreply') { - return r; - } - len = r.com ? g.SITE.Build.parseComment(r.com).replace(/[^a-z]/ig, '').length : 0; - if (len >= Index.lastLongThresholds[+(!!r.ext)]) { - return r; - } - } - if (thread.omitted_posts && ((ref1 = thread.last_replies) != null ? ref1.length : void 0)) { - return thread.last_replies[0]; - } else { - return thread; - } - }; - lastlongD = $.dict(); - for (k = 0, len1 = liveThreadData.length; k < len1; k++) { - thread = liveThreadData[k]; - lastlongD[thread.no] = lastlong(thread).no; - } - return slice.call(liveThreadData).sort(function(a, b) { - return lastlongD[b.no] - lastlongD[a.no]; - }).map(function(post) { - return post.no; - }); - case 'bump': - return liveThreadIDs; - case 'birth': - return slice.call(liveThreadIDs).sort(function(a, b) { - return b - a; - }); - case 'replycount': - return slice.call(liveThreadData).sort(function(a, b) { - return b.replies - a.replies; - }).map(function(post) { - return post.no; - }); - case 'filecount': - return slice.call(liveThreadData).sort(function(a, b) { - return b.images - a.images; - }).map(function(post) { - return post.no; - }); - case 'activity': - return slice.call(liveThreadData).sort(function(a, b) { - return (tmp_time - a.time) / (a.replies + 1) - (tmp_time - b.time) / (b.replies + 1); - }).map(function(post) { - return post.no; - }); - default: - return liveThreadIDs; - } - })(); - if (/-rev$/.test(Index.currentSort)) { - Index.sortedThreadIDs = slice.call(Index.sortedThreadIDs).reverse(); - } - if (Index.search && (threadIDs = Index.querySearch(Index.search))) { - Index.sortedThreadIDs = threadIDs; - } - Index.sortOnTop(function(obj) { - return obj.isSticky; - }); - Index.sortOnTop(function(obj) { - return obj.isOnTop || Conf['Pin Watched Threads'] && ThreadWatcher.isWatchedRaw(obj.boardID, obj.threadID); - }); - if (Conf['Anchor Hidden Threads']) { - return Index.sortOnTop(function(obj) { - return !Index.isHidden(obj.threadID); - }); - } - }, - sortOnTop: function(match) { - var ID, bottomThreads, k, len1, ref, topThreads; - topThreads = []; - bottomThreads = []; - ref = Index.sortedThreadIDs; - for (k = 0, len1 = ref.length; k < len1; k++) { - ID = ref[k]; - (match(Index.parsedThreads[ID]) ? topThreads : bottomThreads).push(ID); - } - return Index.sortedThreadIDs = topThreads.concat(bottomThreads); - }, - buildIndex: function() { - var threadIDs; - if (!Index.liveThreadData) { - return; - } - switch (Conf['Index Mode']) { - case 'all pages': - threadIDs = Index.sortedThreadIDs; - break; - case 'catalog': - threadIDs = Index.sortedThreadIDs.filter(function(ID) { - return !Index.isHidden(ID) !== Index.showHiddenThreads; - }); - break; - default: - threadIDs = Index.threadsOnPage(Index.currentPage); - } - delete Index.pageNum; - $.rmAll(Index.root); - $.rmAll(Header.hover); - if (Index.loaded && Index.root.parentNode) { - $.event('PostsRemoved', null, Index.root); - } - if (Conf['Index Mode'] === 'catalog') { - Index.buildCatalog(threadIDs); - } else { - Index.buildStructure(threadIDs); - } - }, - threadsOnPage: function(pageNum) { - var nodesPerPage, offset; - nodesPerPage = Index.threadsNumPerPage; - offset = nodesPerPage * (pageNum - 1); - return Index.sortedThreadIDs.slice(offset, offset + nodesPerPage); - }, - buildStructure: function(threadIDs) { - var k, len1, nodes, thread, threads; - threads = Index.buildThreads(threadIDs, false, Conf['Show Replies']); - nodes = []; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - nodes.push(thread.nodes.root, $.el('hr')); - } - $.add(Index.root, nodes); - if (Index.root.parentNode) { - $.event('PostsInserted', null, Index.root); - } - Index.loaded = true; - }, - buildCatalog: function(threadIDs) { - var fn, i, n, node0; - i = 0; - n = threadIDs.length; - node0 = null; - fn = function() { - var j; - if (node0 && !node0.parentNode) { - return; - } - j = i > 0 && Index.root.parentNode ? n : i + 30; - node0 = Index.buildCatalogPart(threadIDs.slice(i, j))[0]; - i = j; - if (i < n) { - return $.queueTask(fn); - } else { - if (Index.root.parentNode) { - $.event('PostsInserted', null, Index.root); - } - return Index.loaded = true; - } - }; - fn(); - }, - buildCatalogPart: function(threadIDs) { - var k, len1, nodes, thread, threads; - threads = Index.buildThreads(threadIDs, true); - Index.buildCatalogViews(threads); - Index.sizeCatalogViews(threads); - nodes = []; - for (k = 0, len1 = threads.length; k < len1; k++) { - thread = threads[k]; - thread.OP.setCatalogOP(true); - $.add(thread.catalogView.nodes.root, thread.OP.nodes.root); - nodes.push(thread.catalogView.nodes.root); - $.on(thread.catalogView.nodes.root, 'mouseenter', Index.cb.catalogReplies.bind(thread)); - $.on(thread.OP.nodes.root, 'mouseenter', Index.cb.hoverAdjust.bind(thread.OP.nodes)); - } - $.add(Index.root, nodes); - return nodes; - }, - clearSearch: function() { - Index.searchInput.value = ''; - Index.onSearchInput(); - return Index.searchInput.focus(); - }, - setupSearch: function() { - Index.searchInput.value = Index.search; - if (Index.search) { - return Index.searchInput.dataset.searching = 1; - } else { - return Index.searchInput.removeAttribute('data-searching'); - } - }, - onSearchInput: function() { - var search; - search = Index.searchInput.value.trim(); - if (search === Index.search) { - return; - } - Index.pushState({ - search: search, - replace: !!search === !!Index.search - }); - return Index.pageLoad(false); - }, - querySearch: function(query) { - var keywords, match, regexp; - if ((match = query.match(/^([\w+]+):\/(.*)\/(\w*)$/))) { - try { - regexp = RegExp(match[2], match[3]); - } catch (error) { - return []; - } - return Index.sortedThreadIDs.filter(function(ID) { - return regexp.test(Filter.values(match[1], Index.parsedThreads[ID]).join('\n')); - }); - } - if (!(keywords = query.toLowerCase().match(/\S+/g))) { - return; - } - return Index.sortedThreadIDs.filter(function(ID) { - return Index.searchMatch(Index.parsedThreads[ID], keywords); - }); - }, - searchMatch: function(obj, keywords) { - var file, info, k, key, keyword, l, len1, len2, ref, text; - info = obj.info, file = obj.file; - if (info.comment == null) { - info.comment = g.SITE.Build.parseComment(info.commentHTML.innerHTML); - } - text = []; - ref = ['comment', 'subject', 'name', 'tripcode']; - for (k = 0, len1 = ref.length; k < len1; k++) { - key = ref[k]; - if (key in info) { - text.push(info[key]); - } - } - if (file) { - text.push(file.name); - } - text = text.join(' ').toLowerCase(); - for (l = 0, len2 = keywords.length; l < len2; l++) { - keyword = keywords[l]; - if (-1 === text.indexOf(keyword)) { - return false; - } - } - return true; - } - }; - - return Index; - -}).call(this); - -Polyfill = (function() { - var Polyfill; - - Polyfill = { - init: function() { - var base; - this.toBlob(); - $.global(this.toBlob); - (base = Element.prototype).matches || (base.matches = Element.prototype.mozMatchesSelector || Element.prototype.webkitMatchesSelector); - }, - toBlob: function() { - if (HTMLCanvasElement.prototype.toBlob) { - return; - } - HTMLCanvasElement.prototype.toBlob = function(cb, type, encoderOptions) { - var data, i, j, l, ref, ui8a, url; - url = this.toDataURL(type, encoderOptions); - data = atob(url.slice(url.indexOf(',') + 1)); - l = data.length; - ui8a = new Uint8Array(l); - for (i = j = 0, ref = l; j < ref; i = j += 1) { - ui8a[i] = data.charCodeAt(i); - } - return cb(new Blob([ui8a], { - type: type || 'image/png' - })); - }; - } - }; - - return Polyfill; - -}).call(this); - -Settings = (function() { - var Settings, - slice = [].slice, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Settings = { - init: function() { - var add, link; - link = $.el('a', { - className: 'settings-link fa fa-wrench', - textContent: 'Settings', - title: '4chan X Settings', - href: 'javascript:;' - }); - $.on(link, 'click', Settings.open); - Header.addShortcut('settings', link, 820); - add = this.addSection; - add('Main', this.main); - add('Filter', this.filter); - add('Sauce', this.sauce); - add('Advanced', this.advanced); - add('Keybinds', this.keybinds); - $.on(d, 'AddSettingsSection', Settings.addSection); - $.on(d, 'OpenSettings', function(e) { - return Settings.open(e.detail); - }); - if (g.SITE.software === 'yotsuba' && Conf['Disable Native Extension']) { - if ($.hasStorage) { - return $.global(function() { - var settings; - try { - settings = JSON.parse(localStorage.getItem('4chan-settings')) || {}; - if (settings.disableAll) { - return; - } - settings.disableAll = true; - return localStorage.setItem('4chan-settings', JSON.stringify(settings)); - } catch (error) { - return Object.defineProperty(window, 'Config', { - value: { - disableAll: true - } - }); - } - }); - } else { - return $.global(function() { - return Object.defineProperty(window, 'Config', { - value: { - disableAll: true - } - }); - }); - } - } - }, - open: function(openSection) { - var dialog, j, len, link, links, ref, section, sectionToOpen; - if (Settings.dialog) { - return; - } - $.event('CloseMenu'); - Settings.dialog = dialog = $.el('div', { - id: 'overlay' - }, {innerHTML: ""}); - $.on($('.export', dialog), 'click', Settings["export"]); - $.on($('.import', dialog), 'click', Settings["import"]); - $.on($('.reset', dialog), 'click', Settings.reset); - $.on($('input', dialog), 'change', Settings.onImport); - links = []; - ref = Settings.sections; - for (j = 0, len = ref.length; j < len; j++) { - section = ref[j]; - link = $.el('a', { - className: "tab-" + section.hyphenatedTitle, - textContent: section.title, - href: 'javascript:;' - }); - $.on(link, 'click', Settings.openSection.bind(section)); - links.push(link, $.tn(' | ')); - if (section.title === openSection) { - sectionToOpen = link; - } - } - links.pop(); - $.add($('.sections-list', dialog), links); - if (openSection !== 'none') { - (sectionToOpen ? sectionToOpen : links[0]).click(); - } - $.on($('.close', dialog), 'click', Settings.close); - $.on(window, 'beforeunload', Settings.close); - $.on(dialog, 'click', Settings.close); - $.on(dialog.firstElementChild, 'click', function(e) { - return e.stopPropagation(); - }); - $.add(d.body, dialog); - return $.event('OpenSettings', null, dialog); - }, - close: function() { - var ref; - if (!Settings.dialog) { - return; - } - if ((ref = d.activeElement) != null) { - ref.blur(); - } - $.rm(Settings.dialog); - return delete Settings.dialog; - }, - sections: [], - addSection: function(title, open) { - var hyphenatedTitle, ref; - if (typeof title !== 'string') { - ref = title.detail, title = ref.title, open = ref.open; - } - hyphenatedTitle = title.toLowerCase().replace(/\s+/g, '-'); - return Settings.sections.push({ - title: title, - hyphenatedTitle: hyphenatedTitle, - open: open - }); - }, - openSection: function() { - var section, selected; - if (selected = $('.tab-selected', Settings.dialog)) { - $.rmClass(selected, 'tab-selected'); - } - $.addClass($(".tab-" + this.hyphenatedTitle, Settings.dialog), 'tab-selected'); - section = $('section', Settings.dialog); - $.rmAll(section); - section.className = "section-" + this.hyphenatedTitle; - this.open(section, g); - section.scrollTop = 0; - return $.event('OpenSettings', null, section); - }, - warnings: { - localStorage: function(cb) { - var why; - if ($.cantSync) { - why = $.cantSet ? 'save your settings' : 'synchronize settings between tabs'; - return cb($.el('li', { - textContent: "4chan X needs local storage to " + why + ".\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: function(cb) { - return $.onExists(doc, '.adg-rects > .desktop', function(ad) { - return $.onExists(ad, 'iframe', function() { - var url; - url = Redirect.to('thread', { - boardID: 'qa', - threadID: 362590 - }); - return cb($.el('li', {innerHTML: "To protect yourself from malicious ads, you should block ads on 4chan."})); - }); - }); - } - }, - main: function(section) { - var addCheckboxes, addWarning, button, div, fs, inputs, items, key, keyFS, obj, ref, ref1, warning, warnings; - warnings = $.el('fieldset', { - hidden: true - }, {innerHTML: "Warnings
        "}); - addWarning = function(item) { - $.add($('ul', warnings), item); - return warnings.hidden = false; - }; - ref = Settings.warnings; - for (key in ref) { - warning = ref[key]; - warning(addWarning); - } - $.add(section, warnings); - items = $.dict(); - inputs = $.dict(); - addCheckboxes = function(root, obj) { - var arr, container, containers, description, div, input, level, results; - containers = [root]; - results = []; - for (key in obj) { - arr = obj[key]; - if (!(arr instanceof Array)) { - continue; - } - description = arr[1]; - div = $.el('div', {innerHTML: ": " + E(description) + ""}); - div.dataset.name = key; - input = $('input', div); - $.on(input, 'change', $.cb.checked); - $.on(input, 'change', function() { - return this.parentNode.parentNode.dataset.checked = this.checked; - }); - items[key] = Conf[key]; - inputs[key] = input; - level = arr[2] || 0; - if (containers.length <= level) { - container = $.el('div', { - className: 'suboption-list' - }); - $.add(containers[containers.length - 1].lastElementChild, container); - containers[level] = container; - } else if (containers.length > level + 1) { - containers.splice(level + 1, containers.length - (level + 1)); - } - results.push($.add(containers[level], div)); - } - return results; - }; - ref1 = Config.main; - for (keyFS in ref1) { - obj = ref1[keyFS]; - fs = $.el('fieldset', {innerHTML: "" + E(keyFS) + ""}); - addCheckboxes(fs, obj); - if (keyFS === 'Posting and Captchas') { - $.add(fs, $.el('p', {innerHTML: "For more info on captcha options and issues, see the captcha FAQ."})); - } - $.add(section, fs); - } - addCheckboxes($('div[data-name="JSON Index"] > .suboption-list', section), Config.Index); - if ($.engine !== 'gecko') { - $('div[data-name="Remember QR Size"]', section).hidden = true; - } - if ($.perProtocolSettings || location.protocol !== 'https:') { - $('div[data-name="Redirect to HTTPS"]', section).hidden = true; - } - if ($.platform !== 'crx') { - $('div[data-name="Work around CORB Bug"]', section).hidden = true; - } - $.get(items, function(items) { - var val; - for (key in items) { - val = items[key]; - inputs[key].checked = val; - inputs[key].parentNode.parentNode.dataset.checked = val; - } - }); - div = $.el('div', {innerHTML: ": Clear manually-hidden threads and posts on all boards. Reload the page to apply."}); - button = $('button', div); - $.get({ - hiddenThreads: $.dict(), - hiddenPosts: $.dict() - }, function(arg) { - var ID, board, hiddenNum, hiddenPosts, hiddenThreads, ref2, ref3, ref4, ref5, site, thread; - hiddenThreads = arg.hiddenThreads, hiddenPosts = arg.hiddenPosts; - hiddenNum = 0; - for (ID in hiddenThreads) { - site = hiddenThreads[ID]; - if (ID !== 'boards') { - ref2 = site.boards; - for (ID in ref2) { - board = ref2[ID]; - hiddenNum += Object.keys(board).length; - } - } - } - ref3 = hiddenThreads.boards; - for (ID in ref3) { - board = ref3[ID]; - hiddenNum += Object.keys(board).length; - } - for (ID in hiddenPosts) { - site = hiddenPosts[ID]; - if (ID !== 'boards') { - ref4 = site.boards; - for (ID in ref4) { - board = ref4[ID]; - for (ID in board) { - thread = board[ID]; - hiddenNum += Object.keys(thread).length; - } - } - } - } - ref5 = hiddenPosts.boards; - for (ID in ref5) { - board = ref5[ID]; - for (ID in board) { - thread = board[ID]; - hiddenNum += Object.keys(thread).length; - } - } - return button.textContent = "Hidden: " + hiddenNum; - }); - $.on(button, 'click', function() { - this.textContent = 'Hidden: 0'; - return $.get('hiddenThreads', $.dict(), function(arg) { - var boardID, hiddenThreads, ref2; - hiddenThreads = arg.hiddenThreads; - if ($.hasStorage && g.SITE.software === 'yotsuba') { - for (boardID in (ref2 = hiddenThreads['4chan.org']) != null ? ref2.boards : void 0) { - localStorage.removeItem("4chan-hide-t-" + boardID); - } - for (boardID in hiddenThreads.boards) { - localStorage.removeItem("4chan-hide-t-" + boardID); - } - } - return $["delete"](['hiddenThreads', 'hiddenPosts']); - }); - }); - return $.after($('input[name="Stubs"]', section).parentNode.parentNode, div); - }, - "export": function() { - var Conf2; - Conf2 = $.dict(); - $.extend(Conf2, Conf); - return $.get(Conf2, function(Conf2) { - delete Conf2['boardConfig']; - return Settings.downloadExport({ - version: g.VERSION, - date: Date.now(), - Conf: Conf2 - }); - }); - }, - downloadExport: function(data) { - var a, blob, p, url; - blob = new Blob([JSON.stringify(data, null, 2)], { - type: 'application/json' - }); - url = URL.createObjectURL(blob); - a = $.el('a', { - download: "4chan X v" + g.VERSION + "-" + data.date + ".json", - href: url - }); - p = $('.imp-exp-result', Settings.dialog); - $.rmAll(p); - $.add(p, a); - return a.click(); - }, - "import": function() { - return $('input[type=file]', this.parentNode).click(); - }, - onImport: function() { - var file, output, reader; - if (!(file = this.files[0])) { - return; - } - this.value = null; - output = $('.imp-exp-result'); - if (!confirm('Your current settings will be entirely overwritten, are you sure?')) { - output.textContent = 'Import aborted.'; - return; - } - reader = new FileReader(); - reader.onload = function(e) { - var err; - try { - return Settings.loadSettings($.dict.json(e.target.result), function(err) { - if (err) { - return output.textContent = 'Import failed due to an error.'; - } else if (confirm('Import successful. Reload now?')) { - return window.location.reload(); - } - }); - } catch (error) { - err = error; - output.textContent = 'Import failed due to an error.'; - return c.error(err.stack); - } - }; - return reader.readAsText(file); - }, - convertFrom: { - loadletter: function(data) { - var base, boardID, convertSettings, key, ref, ref1, threadData, threadID, threads, val; - convertSettings = function(data, map) { - var newKey, prevKey; - for (prevKey in map) { - newKey = map[prevKey]; - if (newKey) { - data.Conf[newKey] = data.Conf[prevKey]; - } - delete data.Conf[prevKey]; - } - return data; - }; - data = convertSettings(data, { - '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': '' - }); - if ('Always CDN' in data.Conf) { - data.Conf['fourchanImageHost'] = data.Conf['Always CDN'] ? 'i.4cdn.org' : ''; - delete data.Conf['Always CDN']; - } - data.Conf.sauces = data.Conf.sauces.replace(/\$\d/g, function(c) { - switch (c) { - case '$1': - return '%TURL'; - case '$2': - return '%URL'; - case '$3': - return '%MD5'; - case '$4': - return '%board'; - default: - return c; - } - }); - ref = Config.hotkeys; - for (key in ref) { - val = ref[key]; - if (key in data.Conf) { - data.Conf[key] = data.Conf[key].replace(/ctrl|alt|meta/g, function(s) { - return "" + (s[0].toUpperCase()) + s.slice(1); - }).replace(/(^|.+\+)[A-Z]$/g, function(s) { - return "Shift+" + s.slice(0, -1) + (s.slice(-1).toLowerCase()); - }); - } - } - if (data.WatchedThreads) { - data.Conf['watchedThreads'] = $.dict.clone({ - '4chan.org': { - boards: {} - } - }); - ref1 = data.WatchedThreads; - for (boardID in ref1) { - threads = ref1[boardID]; - for (threadID in threads) { - threadData = threads[threadID]; - ((base = data.Conf['watchedThreads']['4chan.org'].boards)[boardID] || (base[boardID] = $.dict()))[threadID] = { - excerpt: threadData.textContent - }; - } - } - } - return data; - } - }, - upgrade: function(data, version) { - var addCSS, addSauces, boardID, boards, changes, compareString, corrupted, db, hostname, j, k, key, l, lastChecked, len, len1, len2, len3, line, list, m, name, record, ref, ref1, ref10, ref11, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, rice, set, setD, siteProperties, software, type, uids, val, val2, value; - changes = $.dict(); - set = function(key, value) { - return data[key] = changes[key] = value; - }; - setD = function(key, value) { - if (data[key] == null) { - return set(key, value); - } - }; - addSauces = function(sauces) { - if (data['sauces'] != null) { - sauces = sauces.filter(function(s) { - return data['sauces'].indexOf(s.match(/[^#;\s]+|$/)[0]) < 0; - }); - if (sauces.length) { - return set('sauces', data['sauces'] + '\n\n' + sauces.join('\n')); - } - } - }; - addCSS = function(css) { - if (data['usercss'] == null) { - set('usercss', Config['usercss']); - } - if (data['usercss'].indexOf(css) < 0) { - return set('usercss', css + '\n\n' + data['usercss']); - } - }; - if ((corrupted = version[0] === '"')) { - try { - version = JSON.parse(version); - } catch (error) {} - } - compareString = version.replace(/\d+/g, function(x) { - return ('0000' + x).slice(-5); - }); - if (compareString < '00001.00013.00014.00008') { - for (key in data) { - val = data[key]; - if (!(typeof val === 'string' && typeof Conf[key] !== 'string' && (key !== 'Index Sort' && key !== 'Last Long Reply Thresholds 0' && key !== 'Last Long Reply Thresholds 1'))) { - continue; - } - corrupted = true; - break; - } - } - if (corrupted) { - for (key in data) { - val = data[key]; - if (typeof val === 'string') { - try { - val2 = JSON.parse(val); - set(key, val2); - } catch (error) {} - } - } - } - if (compareString < '00001.00011.00008.00000') { - if (data['Fixed Thread Watcher'] == null) { - set('Fixed Thread Watcher', (ref = data['Toggleable Thread Watcher']) != null ? ref : true); - } - if (data['Exempt Archives from Encryption'] == null) { - set('Exempt Archives from Encryption', (ref1 = data['Except Archives from Encryption']) != null ? ref1 : false); - } - } - if (compareString < '00001.00011.00010.00001') { - if (data['selectedArchives'] != null) { - uids = { - "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 - }; - ref2 = data['selectedArchives']; - for (boardID in ref2) { - record = ref2[boardID]; - for (type in record) { - name = record[type]; - if ($.hasOwn(uids, name)) { - record[type] = uids[name]; - } - } - } - set('selectedArchives', data['selectedArchives']); - } - } - if (compareString < '00001.00011.00016.00000') { - if ((rice = Config['usercss'].match(/\/\* Board title rice \*\/(?:\n.+)*/)[0])) { - if ((data['usercss'] != null) && data['usercss'].indexOf(rice) < 0) { - set('usercss', rice + '\n\n' + data['usercss']); - } - } - } - if (compareString < '00001.00011.00017.00000') { - ref3 = ['Persistent QR', 'Color User IDs', 'Fappe Tyme', 'Werk Tyme', 'Highlight Posts Quoting You', 'Highlight Own Posts']; - for (j = 0, len = ref3.length; j < len; j++) { - key = ref3[j]; - if (data[key] == null) { - set(key, key === 'Persistent QR'); - } - } - } - if (compareString < '00001.00011.00017.00006') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/iqdb\.org\//mg, '$1//iqdb.org/')); - } - } - if (compareString < '00001.00011.00019.00003' && !Settings.dialog) { - $.queueTask(function() { - return Settings.warnings.ads(function(item) { - return new Notice('warning', slice.call(item.childNodes)); - }); - }); - } - if (compareString < '00001.00011.00020.00003') { - ref4 = { - 'Inline Cross-thread Quotes Only': false, - 'Pass Link': true - }; - for (key in ref4) { - value = ref4[key]; - if (data[key] == null) { - set(key, value); - } - } - } - if (compareString < '00001.00011.00021.00003') { - if (data['Remember Your Posts'] == null) { - set('Remember Your Posts', (ref5 = data['Mark Quotes of You']) != null ? ref5 : true); - } - } - if (compareString < '00001.00011.00022.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(?:IMG|URL))%3Fs\.jpg/mg, '$1')); - set('sauces', data['sauces'].replace(/^#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(?:IMG|T?URL)(?=$|;)/mg, '$&&safe=off')); - } - } - if (compareString < '00001.00011.00022.00002') { - if ((data['Use Recaptcha v1 in Reports'] == null) && data['Use Recaptcha v1'] && !data['Use Recaptcha v2 in Reports']) { - set('Use Recaptcha v1 in Reports', true); - } - } - if (compareString < '00001.00011.00024.00000') { - if ((data['JSON Navigation'] != null) && (data['JSON Index'] == null)) { - set('JSON Index', data['JSON Navigation']); - } - } - if (compareString < '00001.00011.00026.00000') { - if ((data['Oekaki Links'] != null) && (data['Edit Link'] == null)) { - set('Edit Link', data['Oekaki Links']); - } - if (data['Inline Cross-thread Quotes Only'] == null) { - set('Inline Cross-thread Quotes Only', true); - } - } - if (compareString < '00001.00011.00030.00000') { - if (data['Quote Threading'] && (data['Thread Quotes'] == null)) { - set('Thread Quotes', true); - } - } - if (compareString < '00001.00011.00032.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/3d\.iqdb\.org\//mg, '$1//3d.iqdb.org/')); - } - addSauces(['#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']); - } - if (compareString < '00001.00011.00035.00000') { - addSauces(['https://whatanime.ga/?auto&url=%IMG;text:wait']); - } - if (compareString < '00001.00012.00000.00000') { - if (data['Exempt Archives from Encryption'] == null) { - set('Exempt Archives from Encryption', false); - } - if (data['Show New Thread Option in Threads'] == null) { - set('Show New Thread Option in Threads', false); - } - if (data['Show Name and Subject']) { - addCSS('#qr .persona .field {display: block !important;}'); - } - if (data['QR Shortcut'] === false) { - addCSS('#shortcut-qr {display: none;}'); - } - if (data['Bottom QR Link'] === false) { - addCSS('.qr-link-container-bottom {display: none;}'); - } - } - if (compareString < '00001.00012.00000.00006') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)https:\/\/(?:desustorage|cuckchan)\.org\//mg, '$1https://desuarchive.org/')); - } - } - if (compareString < '00001.00012.00001.00000') { - if ((data['Persistent Thread Watcher'] == null) && (data['Toggleable Thread Watcher'] != null)) { - set('Persistent Thread Watcher', !data['Toggleable Thread Watcher']); - } - } - if (compareString < '00001.00012.00003.00000') { - ref6 = ['Image Hover in Catalog', 'Auto Watch', 'Auto Watch Reply']; - for (k = 0, len1 = ref6.length; k < len1; k++) { - key = ref6[k]; - setD(key, false); - } - } - if (compareString < '00001.00013.00001.00002') { - addSauces(['#//www.bing.com/images/search?q=imgurl:%IMG&view=detailv2&iss=sbi#enterInsights']); - } - if (compareString < '00001.00013.00005.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/regex\.info\/exif\.cgi/mg, '$1http://exif.regex.info/exif.cgi')); - } - addSauces(Config['sauces'].match(/# Known filename formats:(?:\n.+)*|$/)[0].split('\n')); - } - if (compareString < '00001.00013.00007.00002') { - setD('Require OP Quote Link', true); - } - if (compareString < '00001.00013.00008.00000') { - setD('Download Link', true); - } - if (compareString < '00001.00013.00009.00003') { - if (data['jsWhitelist'] != null) { - list = data['jsWhitelist'].split('\n'); - if (indexOf.call(list, 'https://cdnjs.cloudflare.com') < 0 && indexOf.call(list, 'https://cdn.mathjax.org') >= 0) { - set('jsWhitelist', data['jsWhitelist'] + '\n\nhttps://cdnjs.cloudflare.com'); - } - } - } - if (compareString < '00001.00014.00000.00006') { - if (data['siteSoftware'] != null) { - set('siteSoftware', data['siteSoftware'] + '\n4cdn.org yotsuba'); - } - } - if (compareString < '00001.00014.00003.00002') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)https:\/\/whatanime\.ga\//mg, '$1https://trace.moe/')); - } - } - if (compareString < '00001.00014.00004.00004') { - if ((data['siteSoftware'] != null) && !/^4channel\.org yotsuba$/m.test(data['siteSoftware'])) { - set('siteSoftware', data['siteSoftware'] + '\n4channel.org yotsuba'); - } - } - if (compareString < '00001.00014.00005.00000') { - ref7 = DataBoard.keys; - for (l = 0, len2 = ref7.length; l < len2; l++) { - db = ref7[l]; - if ((ref8 = data[db]) != null ? ref8.boards : void 0) { - ref9 = data[db], boards = ref9.boards, lastChecked = ref9.lastChecked; - data[db]['4chan.org'] = { - boards: boards, - lastChecked: lastChecked - }; - delete data[db].boards; - delete data[db].lastChecked; - set(db, data[db]); - } - } - if ((data['siteSoftware'] != null) && (data['siteProperties'] == null)) { - siteProperties = $.dict(); - ref10 = data['siteSoftware'].split('\n'); - for (m = 0, len3 = ref10.length; m < len3; m++) { - line = ref10[m]; - ref11 = line.split(' '), hostname = ref11[0], software = ref11[1]; - siteProperties[hostname] = { - software: software - }; - } - set('siteProperties', siteProperties); - } - } - if (compareString < '00001.00014.00006.00006') { - if (data['sauces'] != null) { - set('sauces', data['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}-/')); - } - } - if (compareString < '00001.00014.00008.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/https:\/\/www\.yandex\.com\/images\/search/g, 'https://yandex.com/images/search')); - } - } - if (compareString < '00001.00014.00009.00000') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^(#?\s*)(?:http:)?\/\/(www\.pixiv\.net|www\.deviantart\.com|imgur\.com|flickr\.com)\//mg, '$1https://$2/')); - set('sauces', data['sauces'].replace(/https:\/\/yandex\.com\/images\/search\?rpt=imageview&img_url=%IMG/g, 'https://yandex.com/images/search?rpt=imageview&url=%IMG')); - } - } - if (compareString < '00001.00014.00009.00001') { - if ((data['Use Faster Image Host'] != null) && (data['fourchanImageHost'] == null)) { - set('fourchanImageHost', (data['Use Faster Image Host'] ? 'i.4cdn.org' : '')); - } - } - if (compareString < '00001.00014.00010.00001') { - if (data['Filter in Native Catalog'] == null) { - set('Filter in Native Catalog', false); - } - } - if (compareString < '00001.00014.00012.00008') { - if (data['boardnav'] == null) { - set('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\",\"https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions\"]"); - } - } - if (compareString < '00001.00014.00016.00001') { - if (data['archiveLists'] != null) { - set('archiveLists', data['archiveLists'].replace('https://mayhemydg.github.io/archives.json/archives.json', 'https://nstepien.github.io/archives.json/archives.json')); - } - } - if (compareString < '00001.00014.00016.00007') { - if (data['sauces'] != null) { - set('sauces', data['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')); - } - } - if (compareString < '00001.00014.00017.00002') { - if (data['jsWhitelist'] != null) { - set('jsWhitelist', data['jsWhitelist'] + '\n\nhttps://hcaptcha.com\nhttps://*.hcaptcha.com'); - } - } - if (compareString < '00001.00014.00020.00004') { - if (data['archiveLists'] != null) { - set('archiveLists', data['archiveLists'].replace('https://nstepien.github.io/archives.json/archives.json', 'https://4chenz.github.io/archives.json/archives.json')); - } - } - if (compareString < '00001.00014.00022.00003') { - if (data['sauces'] != null) { - set('sauces', data['sauces'].replace(/^#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(IMG|T?URL)&safe=off(?=$|;)/mg, 'https://www.google.com/searchbyimage?sbisrc=4chanx&image_url=%$1&safe=off')); - if (compareString === '00001.00014.00022.00002' && !/\bsbisrc=/.test(data['sauces'])) { - set('sauces', data['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')); - } - } - addSauces(['#https://lens.google.com/uploadbyurl?url=%IMG;text:lens']); - } - return changes; - }, - loadSettings: function(data, cb) { - if (data.version.split('.')[0] === '2') { - data = Settings.convertFrom.loadletter(data); - } else if (data.version !== g.VERSION) { - Settings.upgrade(data.Conf, data.version); - } - return $.clear(function(err) { - if (err) { - return cb(err); - } - return $.set(data.Conf, cb); - }); - }, - reset: function() { - if (confirm('Your current settings will be entirely wiped, are you sure?')) { - return $.clear(function(err) { - if (err) { - return $('.imp-exp-result').textContent = 'Import failed due to an error.'; - } else if (confirm('Reset successful. Reload now?')) { - return window.location.reload(); - } - }); - } - }, - filter: function(section) { - var select; - $.extend(section, {innerHTML: "
        "}); - select = $('select', section); - $.on(select, 'change', Settings.selectFilter); - return Settings.selectFilter.call(select); - }, - selectFilter: function() { - var div, filterTypes, name, ta; - div = this.nextElementSibling; - if ((name = this.value) !== 'guide') { - if (!$.hasOwn(Config.filter, name)) { - return; - } - $.rmAll(div); - ta = $.el('textarea', { - name: name, - className: 'field', - spellcheck: false - }); - $.on(ta, 'change', $.cb.value); - $.get(name, Conf[name], function(item) { - ta.value = item[name]; - return $.add(div, ta); - }); - return; - } - filterTypes = Object.keys(Config.filter).filter(function(x) { - return x !== 'general'; - }).map(function(x, i) { - return {innerHTML: ((i) ? "," : "") + "" + E(x)}; - }); - $.extend(div, {innerHTML: "
        Filter is disabled.

        Use regular expressions, one per line.
        Lines starting with a # will be ignored.
        For example, /weeaboo/i will filter posts containing the string `weeaboo`, case-insensitive.
        MD5 and Unique ID filtering use exact string matching, not regular expressions.

          You can use these settings with each regular expression, separate them with semicolons:
        • Per boards, separate them with commas. It is global if not specified. Use sfw and nsfw to reference all worksafe or not-worksafe boards.
          For example: boards:a,jp;.
          To specify boards on a particular site, put the beginning of the domain and a slash character before the list.
          Any initial www. should not be included, and all 4chan domains are considered 4chan.org.
          For example: boards:4:a,jp,sama:a,z;.
          An asterisk can be used to specify all boards on a site.
          For example: boards:4:*;.
        • Select boards to be excluded from the filter. The syntax is the same as for the boards: option above.
          For example: exclude:vg,v;.
        • Filter OPs only along with their threads (`only`) or replies only (`no`).
          For example: op:only; or op:no;.
        • Filter only posts with files (`only`) or only posts without files (`no`).
          For example: file:only; or file:no;.
        • Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`).
          For example: stub:yes; or stub:no;.
        • Highlight instead of hiding. You can specify a class name to use with a userstyle.
          For example: highlight; or highlight:wallpaper;.
        • Highlighted OPs will have their threads put on top of the board index by default.
          For example: top:yes; or top:no;.
        • Show a desktop notification instead of hiding.
          For example: notify;.
        • Filters in the \"General\" section apply to multiple fields, by default subject,name,filename,comment.
          The fields can be specified with the type option, separated by commas.
          For example: type:" + E.cat(filterTypes) + ";.
          Types can also be combined with a + sign; this indicates the filter applies to the given fields joined by newlines.
          For example: type:filename+filesize+dimensions;.
        "}); - return $('.warning', div).hidden = Conf['Filter']; - }, - sauce: function(section) { - var ta; - $.extend(section, {innerHTML: "
        Sauce is disabled.
        These parameters will be replaced by their corresponding values in the URL and displayed text:
        • %IMG: Full image URL for GIF, JPG, and PNG; thumbnail URL for other types.
        • %URL: Full image URL.
        • %TURL: Thumbnail URL.
        • %name: Original file name.
        • %board: Current board.
        • %MD5: MD5 hash in base64.
        • %sMD5: MD5 hash in base64 using - and _.
        • %hMD5: MD5 hash in hexadecimal.
        • %$0: Matched regular expression within the filename.
        • %$1, %$2, %$3, ... : Subexpressions within the matched regular expression.
        • %%, %semi: Literal % and ;.
        Lines starting with a # will be ignored.
        You can specify a display text by appending ;text:[text] to the URL.
        You can specify the applicable boards/sites by appending ;boards:[board1],[board2]. See the Filter guide for details.
        You can specify the applicable file types by appending ;types:[extension1],[extension2].
        You can specify a regular expression the filename must match by appending ;regexp:[regular expression].
        "}); - $('.warning', section).hidden = Conf['Sauce']; - ta = $('textarea', section); - $.get('sauces', Conf['sauces'], function(item) { - ta.value = item['sauces']; - return ta.hidden = false; - }); - return $.on(ta, 'change', $.cb.value); - }, - advanced: function(section) { - var applyCSS, boardSelect, customCSS, event, input, inputs, interval, items, itemsArchive, j, k, l, len, len1, len2, len3, listImageHost, m, name, ref, ref1, ref2, ref3, ref4, table, textContent, updateArchives, warning; - $.extend(section, {innerHTML: "
        Archives
        404 Redirect is disabled.
        Thread redirectionPost fetchingFile redirection

        Archive Lists: Each line below should be an archive list in this format or a URL to load an archive list from.
        Archive properties can be overriden by another item with the same uid (or if absent, its name).
        Last updated:
        External Catalog
        External Catalog is disabled. This will be used only as a fallback.
        URLs of external catalog sites, where %board is to be replaced by the board name.
        Each URL should be followed by ;boards: and optionally ;exclude: and a list of supported/excluded boards in the format explained in the Filter guide.
        Override 4chan Image Host
        Change 4chan image links to this domain. Leave blank for no change.
        Captcha Language
        Choose from list of language codes. Leave blank to autoselect.
        Custom Board Navigation
        New lines will be converted into spaces.

        In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
        Board link: g
        Archive link: g-archive
        Internal archive link: g-expired
        Title link: g-title
        Board link (Replace with title when on that board): g-replace
        Full text link: g-full
        Custom text link: g-text:"Install Gentoo"
        Index-only link: g-index
        Catalog-only link: g-catalog
        Index mode: g-mode:"infinite scrolling"
        Index sort: g-sort:"creation date rev"
        External link: external-text:"Google","http://www.google.com"
        Open in new tab: g-nt
        Combinations are possible: g-index-text:"Technology Index"
        Full board list toggle: toggle-all

        [ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:"Piracy"]
        will give you
        [ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
        if you are on /g/.
        Time Formatting is disabled.
        :
        Day: %a, %A, %d, %e
        Month: %m, %b, %B
        Year: %y, %Y
        Hour: %k, %H, %l, %I, %p, %P
        Minute: %M
        Second: %S
        Literal %: %%
        Quote Backlinks formatting is disabled.
        :
        Default pasted content filename
        .png
        File Info Formatting is disabled.
        :
        Link: %l (truncated), %L (untruncated), %T (4chan filename)
        Filename: %n (truncated), %N (untruncated), %t (4chan filename)
        Download button: %d
        Quick filter MD5: %f
        Spoiler indicator: %p
        Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
        Resolution: %r (Displays 'PDF' for PDF files)
        Tag: %g
        Literal %: %%
        Quick Reply Personas

        One item per line.
        Items will be added in the relevant input's auto-completion list.
        Password items will always be used, since there is no password input.
        Lines starting with a # will be ignored.

          You can use these settings with each item, separate them with semicolons:
        • Possible items are: name, options (or equivalently email), subject and password.
        • Wrap values of items with quotes, like this: options:"sage".
        • Force values as defaults with the always keyword, for example: options:"sage";always.
        • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
        Unread Favicon is disabled.
        Thread Updater is disabled.
        Interval: seconds
        Custom Cooldown Time
        Seconds:
        For more information about customizing 4chan X's CSS, see the styling guide.
        Javascript Whitelist
        Sources from which Javascript is allowed to be loaded by Content Security Policy.
        Lines starting with a # will be ignored.
        Known Banners
        List of known banners, used for click-to-change feature.
        "}); - ref = $$('.warning', section); - for (j = 0, len = ref.length; j < len; j++) { - warning = ref[j]; - warning.hidden = Conf[warning.dataset.feature]; - } - inputs = $.dict(); - ref1 = $$('[name]', section); - for (k = 0, len1 = ref1.length; k < len1; k++) { - input = ref1[k]; - inputs[input.name] = input; - } - $.on(inputs['archiveLists'], 'change', function() { - $.set('lastarchivecheck', 0); - Conf['lastarchivecheck'] = 0; - return $.id('lastarchivecheck').textContent = 'never'; - }); - items = $.dict(); - for (name in inputs) { - input = inputs[name]; - if (!(name !== 'Interval' && name !== 'Custom CSS')) { - continue; - } - items[name] = Conf[name]; - event = (input.nodeName === 'SELECT' || ((ref2 = input.type) === 'checkbox' || ref2 === 'radio') || (input.nodeName === 'TEXTAREA' && !(name in Settings))) ? 'change' : 'input'; - $.on(input, event, $.cb[input.type === 'checkbox' ? 'checked' : 'value']); - if (name in Settings) { - $.on(input, event, Settings[name]); - } - } - $.get(items, function(items) { - var key, val; - for (key in items) { - val = items[key]; - input = inputs[key]; - input[input.type === 'checkbox' ? 'checked' : 'value'] = val; - input.hidden = false; - if (key in Settings) { - Settings[key].call(input); - } - } - }); - listImageHost = $.id('list-fourchanImageHost'); - ref3 = ImageHost.suggestions; - for (l = 0, len2 = ref3.length; l < len2; l++) { - textContent = ref3[l]; - $.add(listImageHost, $.el('option', { - textContent: textContent - })); - } - interval = inputs['Interval']; - customCSS = inputs['Custom CSS']; - applyCSS = $('#apply-css', section); - interval.value = Conf['Interval']; - customCSS.checked = Conf['Custom CSS']; - inputs['usercss'].disabled = !Conf['Custom CSS']; - applyCSS.disabled = !Conf['Custom CSS']; - $.on(interval, 'change', ThreadUpdater.cb.interval); - $.on(customCSS, 'change', Settings.togglecss); - $.on(applyCSS, 'click', function() { - return CustomCSS.update(); - }); - itemsArchive = $.dict(); - ref4 = ['archives', 'selectedArchives', 'lastarchivecheck']; - for (m = 0, len3 = ref4.length; m < len3; m++) { - name = ref4[m]; - itemsArchive[name] = Conf[name]; - } - $.get(itemsArchive, function(itemsArchive) { - $.extend(Conf, itemsArchive); - Redirect.selectArchives(); - return Settings.addArchiveTable(section); - }); - boardSelect = $('#archive-board-select', section); - table = $('#archive-table', section); - updateArchives = $('#update-archives', section); - $.on(boardSelect, 'change', function() { - $('tbody > :not([hidden])', table).hidden = true; - return $("tbody > ." + this.value, table).hidden = false; - }); - return $.on(updateArchives, 'click', function() { - return Redirect.update(function() { - return Settings.addArchiveTable(section); - }); - }); - }, - addArchiveTable: function(section) { - var archBoards, archive, boardID, boardOptions, boardSelect, boards, data, files, id, item, j, k, l, len, len1, len2, len3, m, name, o, ref, ref1, ref2, ref3, ref4, row, rows, select, software, table, tbody, type, uid; - $('#lastarchivecheck', section).textContent = Conf['lastarchivecheck'] === 0 ? 'never' : new Date(Conf['lastarchivecheck']).toLocaleString(); - boardSelect = $('#archive-board-select', section); - table = $('#archive-table', section); - tbody = $('tbody', section); - $.rmAll(boardSelect); - $.rmAll(tbody); - archBoards = $.dict(); - ref = Conf['archives']; - for (j = 0, len = ref.length; j < len; j++) { - ref1 = ref[j], uid = ref1.uid, name = ref1.name, boards = ref1.boards, files = ref1.files, software = ref1.software; - if (software !== 'fuuka' && software !== 'foolfuuka') { - continue; - } - for (k = 0, len1 = boards.length; k < len1; k++) { - boardID = boards[k]; - o = archBoards[boardID] || (archBoards[boardID] = { - thread: [], - post: [], - file: [] - }); - archive = [uid != null ? uid : name, name]; - o.thread.push(archive); - if (software === 'foolfuuka') { - o.post.push(archive); - } - if (indexOf.call(files, boardID) >= 0) { - o.file.push(archive); - } - } - } - rows = []; - boardOptions = []; - ref2 = Object.keys(archBoards).sort(); - for (l = 0, len2 = ref2.length; l < len2; l++) { - boardID = ref2[l]; - row = $.el('tr', { - className: "board-" + boardID - }); - row.hidden = boardID !== g.BOARD.ID; - boardOptions.push($.el('option', { - textContent: "/" + boardID + "/", - value: "board-" + boardID, - selected: boardID === g.BOARD.ID - })); - o = archBoards[boardID]; - ref3 = ['thread', 'post', 'file']; - for (m = 0, len3 = ref3.length; m < len3; m++) { - item = ref3[m]; - $.add(row, Settings.addArchiveCell(boardID, o, item)); - } - rows.push(row); - } - if (rows.length === 0) { - boardSelect.hidden = table.hidden = true; - return; - } - boardSelect.hidden = table.hidden = false; - if (!(g.BOARD.ID in archBoards)) { - rows[0].hidden = false; - } - $.add(boardSelect, boardOptions); - $.add(tbody, rows); - ref4 = Conf['selectedArchives']; - for (boardID in ref4) { - data = ref4[boardID]; - for (type in data) { - id = data[type]; - if ((select = $("select[data-boardid='" + boardID + "'][data-type='" + type + "']", tbody))) { - select.value = JSON.stringify(id); - if (!select.value) { - select.value = select.firstChild.value; - } - } - } - } - }, - addArchiveCell: function(boardID, data, type) { - var archive, i, length, options, select, td; - length = data[type].length; - td = $.el('td', { - className: 'archive-cell' - }); - if (!length) { - td.textContent = '--'; - return td; - } - options = []; - i = 0; - while (i < length) { - archive = data[type][i++]; - options.push($.el('option', { - value: JSON.stringify(archive[0]), - textContent: archive[1] - })); - } - $.extend(td, {innerHTML: ""}); - select = td.firstElementChild; - if (!(select.disabled = length === 1)) { - select.setAttribute('data-boardid', boardID); - select.setAttribute('data-type', type); - $.on(select, 'change', Settings.saveSelectedArchive); - } - $.add(select, options); - return td; - }, - saveSelectedArchive: function() { - return $.get('selectedArchives', Conf['selectedArchives'], (function(_this) { - return function(arg) { - var name1, selectedArchives; - selectedArchives = arg.selectedArchives; - (selectedArchives[name1 = _this.dataset.boardid] || (selectedArchives[name1] = $.dict()))[_this.dataset.type] = JSON.parse(_this.value); - $.set('selectedArchives', selectedArchives); - Conf['selectedArchives'] = selectedArchives; - return Redirect.selectArchives(); - }; - })(this)); - }, - boardnav: function() { - return Header.generateBoardList(this.value); - }, - time: function() { - return this.nextElementSibling.textContent = Time.format(this.value, new Date()); - }, - timeLocale: function() { - return Settings.time.call($('[name=time]', Settings.dialog)); - }, - backlink: function() { - return this.nextElementSibling.textContent = this.value.replace(/%(?:id|%)/g, function(x) { - return { - '%id': '123456789', - '%%': '%' - }[x]; - }); - }, - fileInfo: function() { - var data; - data = { - isReply: true, - file: { - url: "//" + (ImageHost.host()) + "/g/1334437723720.jpg", - name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg', - size: '276 KB', - sizeInBytes: 276 * 1024, - dimensions: '1280x720', - isImage: true, - isVideo: false, - isSpoiler: true, - tag: 'Loop' - } - }; - return FileInfo.format(this.value, data, this.nextElementSibling); - }, - favicon: function() { - var f, i, icon, img, j, len, ref; - Favicon["switch"](); - if (g.VIEW === 'thread' && Conf['Unread Favicon']) { - Unread.update(); - } - img = this.nextElementSibling.children; - f = Favicon; - ref = [f.SFW, f.unreadSFW, f.unreadSFWY, f.NSFW, f.unreadNSFW, f.unreadNSFWY, f.dead, f.unreadDead, f.unreadDeadY]; - for (i = j = 0, len = ref.length; j < len; i = ++j) { - icon = ref[i]; - if (!img[i]) { - $.add(this.nextElementSibling, $.el('img')); - } - img[i].src = icon; - } - }, - togglecss: function() { - if ($('textarea[name=usercss]', $.x('ancestor::fieldset[1]', this)).disabled = $.id('apply-css').disabled = !this.checked) { - CustomCSS.rmStyle(); - } else { - CustomCSS.addStyle(); - } - return $.cb.checked.call(this); - }, - keybinds: function(section) { - var arr, input, inputs, items, key, ref, tbody, tr; - $.extend(section, {innerHTML: "
        Keybinds are disabled.
        Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
        Press Backspace to disable a keybind.
        ActionsKeybinds
        "}); - $('.warning', section).hidden = Conf['Keybinds']; - tbody = $('tbody', section); - items = $.dict(); - inputs = $.dict(); - ref = Config.hotkeys; - for (key in ref) { - arr = ref[key]; - tr = $.el('tr', {innerHTML: "" + E(arr[1]) + ""}); - input = $('input', tr); - input.name = key; - input.spellcheck = false; - items[key] = Conf[key]; - inputs[key] = input; - $.on(input, 'keydown', Settings.keybind); - $.add(tbody, tr); - } - return $.get(items, function(items) { - var val; - for (key in items) { - val = items[key]; - inputs[key].value = val; - } - }); - }, - keybind: function(e) { - var key; - if (e.keyCode === 9) { - return; - } - e.preventDefault(); - e.stopPropagation(); - if ((key = Keybinds.keyCode(e)) == null) { - return; - } - this.value = key; - return $.cb.value.call(this); - } - }; - - return Settings; - -}).call(this); - -Test = (function() { - return Test; - -}).call(this); - -UI = (function() { - var Menu, UI, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove, - bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - slice = [].slice; - - dialog = function(id, properties) { - var child, el, i, len, move, ref; - el = $.el('div', { - className: 'dialog', - id: id - }); - $.extend(el, properties); - el.style.cssText = Conf[id + ".position"]; - move = $('.move', el); - $.on(move, 'touchstart mousedown', dragstart); - ref = move.children; - for (i = 0, len = ref.length; i < len; i++) { - child = ref[i]; - if (!child.tagName) { - continue; - } - $.on(child, 'touchstart mousedown', function(e) { - return e.stopPropagation(); - }); - } - return el; - }; - - Menu = (function() { - var currentMenu, lastToggledButton; - - currentMenu = null; - - lastToggledButton = null; - - function Menu(type) { - this.type = type; - this.addEntry = bind(this.addEntry, this); - this.onFocus = bind(this.onFocus, this); - this.keybinds = bind(this.keybinds, this); - this.close = bind(this.close, this); - this.setPosition = bind(this.setPosition, this); - $.on(d, 'AddMenuEntry', (function(_this) { - return function(arg) { - var detail; - detail = arg.detail; - if (detail.type !== _this.type) { - return; - } - delete detail.open; - return _this.addEntry(detail); - }; - })(this)); - this.entries = []; - } - - Menu.prototype.makeMenu = function() { - var menu; - menu = $.el('div', { - className: 'dialog', - id: 'menu', - tabIndex: 0 - }); - menu.dataset.type = this.type; - $.on(menu, 'click', function(e) { - return e.stopPropagation(); - }); - $.on(menu, 'keydown', this.keybinds); - return menu; - }; - - Menu.prototype.toggle = function(e, button, data) { - var previousButton; - e.preventDefault(); - e.stopPropagation(); - if (currentMenu) { - previousButton = lastToggledButton; - currentMenu.close(); - if (previousButton === button) { - return; - } - } - if (!this.entries.length) { - return; - } - return this.open(button, data); - }; - - Menu.prototype.open = function(button, data) { - var entry, i, len, menu, ref; - menu = this.menu = this.makeMenu(); - currentMenu = this; - lastToggledButton = button; - this.entries.sort(function(first, second) { - return first.order - second.order; - }); - ref = this.entries; - for (i = 0, len = ref.length; i < len; i++) { - entry = ref[i]; - this.insertEntry(entry, menu, data); - } - $.addClass(lastToggledButton, 'active'); - $.on(d, 'click CloseMenu', this.close); - $.on(d, 'scroll', this.setPosition); - $.on(window, 'resize', this.setPosition); - $.after(button, menu); - this.setPosition(); - entry = $('.entry', menu); - this.focus(entry); - return menu.focus(); - }; - - Menu.prototype.setPosition = function() { - var bLeft, bRect, bTop, bottom, cHeight, cWidth, left, mRect, ref, ref1, right, top; - mRect = this.menu.getBoundingClientRect(); - bRect = lastToggledButton.getBoundingClientRect(); - bTop = window.scrollY + bRect.top; - bLeft = window.scrollX + bRect.left; - cHeight = doc.clientHeight; - cWidth = doc.clientWidth; - ref = bRect.top + bRect.height + mRect.height < cHeight ? [bRect.bottom + "px", ''] : ['', (cHeight - bRect.top) + "px"], top = ref[0], bottom = ref[1]; - ref1 = bRect.left + mRect.width < cWidth ? [bRect.left + "px", ''] : ['', (cWidth - bRect.right) + "px"], left = ref1[0], right = ref1[1]; - $.extend(this.menu.style, { - top: top, - right: right, - bottom: bottom, - left: left - }); - return this.menu.classList.toggle('left', right); - }; - - Menu.prototype.insertEntry = function(entry, parent, data) { - var err, i, len, ref, subEntry, submenu; - if (typeof entry.open === 'function') { - try { - if (!entry.open(data)) { - return; - } - } catch (error) { - err = error; - Main.handleErrors({ - message: "Error in building the " + this.type + " menu.", - error: err - }); - return; - } - } - $.add(parent, entry.el); - if (!entry.subEntries) { - return; - } - if (submenu = $('.submenu', entry.el)) { - $.rm(submenu); - } - submenu = $.el('div', { - className: 'dialog submenu' - }); - ref = entry.subEntries; - for (i = 0, len = ref.length; i < len; i++) { - subEntry = ref[i]; - this.insertEntry(subEntry, submenu, data); - } - $.add(entry.el, submenu); - }; - - Menu.prototype.close = function() { - $.rm(this.menu); - delete this.menu; - $.rmClass(lastToggledButton, 'active'); - currentMenu = null; - lastToggledButton = null; - $.off(d, 'click scroll CloseMenu', this.close); - $.off(d, 'scroll', this.setPosition); - return $.off(window, 'resize', this.setPosition); - }; - - Menu.prototype.findNextEntry = function(entry, direction) { - var entries; - entries = slice.call(entry.parentNode.children); - entries.sort(function(first, second) { - return first.style.order - second.style.order; - }); - return entries[entries.indexOf(entry) + direction]; - }; - - Menu.prototype.keybinds = function(e) { - var entry, next, nextPrev, subEntry, submenu; - entry = $('.focused', this.menu); - while (subEntry = $('.focused', entry)) { - entry = subEntry; - } - switch (e.keyCode) { - case 27: - lastToggledButton.focus(); - this.close(); - break; - case 13: - case 32: - entry.click(); - break; - case 38: - if (next = this.findNextEntry(entry, -1)) { - this.focus(next); - } - break; - case 40: - if (next = this.findNextEntry(entry, +1)) { - this.focus(next); - } - break; - case 39: - if ((submenu = $('.submenu', entry)) && (next = submenu.firstElementChild)) { - while (nextPrev = this.findNextEntry(next, -1)) { - next = nextPrev; - } - this.focus(next); - } - break; - case 37: - if (next = $.x('parent::*[contains(@class,"submenu")]/parent::*', entry)) { - this.focus(next); - } - break; - default: - return; - } - e.preventDefault(); - return e.stopPropagation(); - }; - - Menu.prototype.onFocus = function(e) { - e.stopPropagation(); - return this.focus(e.target); - }; - - Menu.prototype.focus = function(entry) { - var bottom, cHeight, cWidth, eRect, focused, i, left, len, ref, ref1, ref2, right, sRect, style, submenu, top; - while (focused = $.x('parent::*/child::*[contains(@class,"focused")]', entry)) { - $.rmClass(focused, 'focused'); - } - ref = $$('.focused', entry); - for (i = 0, len = ref.length; i < len; i++) { - focused = ref[i]; - $.rmClass(focused, 'focused'); - } - $.addClass(entry, 'focused'); - if (!(submenu = $('.submenu', entry))) { - return; - } - sRect = submenu.getBoundingClientRect(); - eRect = entry.getBoundingClientRect(); - cHeight = doc.clientHeight; - cWidth = doc.clientWidth; - ref1 = eRect.top + sRect.height < cHeight ? ['0px', 'auto'] : ['auto', '0px'], top = ref1[0], bottom = ref1[1]; - ref2 = eRect.right + sRect.width < cWidth - 150 ? ['100%', 'auto'] : ['auto', '100%'], left = ref2[0], right = ref2[1]; - style = submenu.style; - style.top = top; - style.bottom = bottom; - style.left = left; - return style.right = right; - }; - - Menu.prototype.addEntry = function(entry) { - this.parseEntry(entry); - return this.entries.push(entry); - }; - - Menu.prototype.parseEntry = function(entry) { - var el, i, len, subEntries, subEntry; - el = entry.el, subEntries = entry.subEntries; - $.addClass(el, 'entry'); - $.on(el, 'focus mouseover', this.onFocus); - el.style.order = entry.order || 100; - if (!subEntries) { - return; - } - $.addClass(el, 'has-submenu'); - for (i = 0, len = subEntries.length; i < len; i++) { - subEntry = subEntries[i]; - this.parseEntry(subEntry); - } - }; - - return Menu; - - })(); - - dragstart = function(e) { - var el, isTouching, o, rect, ref, screenHeight, screenWidth; - if (e.type === 'mousedown' && e.button !== 0) { - return; - } - e.preventDefault(); - if (isTouching = e.type === 'touchstart') { - e = e.changedTouches[e.changedTouches.length - 1]; - } - el = $.x('ancestor::div[contains(@class,"dialog")][1]', this); - rect = el.getBoundingClientRect(); - screenHeight = doc.clientHeight; - screenWidth = doc.clientWidth; - o = { - id: el.id, - style: el.style, - dx: e.clientX - rect.left, - dy: e.clientY - rect.top, - height: screenHeight - rect.height, - width: screenWidth - rect.width, - screenHeight: screenHeight, - screenWidth: screenWidth, - isTouching: isTouching - }; - ref = Conf['Header auto-hide'] || !Conf['Fixed Header'] ? [0, 0] : Conf['Bottom Header'] ? [0, Header.bar.getBoundingClientRect().height] : [Header.bar.getBoundingClientRect().height, 0], o.topBorder = ref[0], o.bottomBorder = ref[1]; - if (isTouching) { - o.identifier = e.identifier; - o.move = touchmove.bind(o); - o.up = touchend.bind(o); - $.on(d, 'touchmove', o.move); - return $.on(d, 'touchend touchcancel', o.up); - } else { - o.move = drag.bind(o); - o.up = dragend.bind(o); - $.on(d, 'mousemove', o.move); - return $.on(d, 'mouseup', o.up); - } - }; - - touchmove = function(e) { - var i, len, ref, touch; - ref = e.changedTouches; - for (i = 0, len = ref.length; i < len; i++) { - touch = ref[i]; - if (touch.identifier === this.identifier) { - drag.call(this, touch); - return; - } - } - }; - - drag = function(e) { - var bottom, clientX, clientY, left, right, style, top; - clientX = e.clientX, clientY = e.clientY; - left = clientX - this.dx; - left = left < 10 ? 0 : this.width - left < 10 ? '' : left / this.screenWidth * 100 + '%'; - top = clientY - this.dy; - top = top < (10 + this.topBorder) ? this.topBorder + 'px' : this.height - top < (10 + this.bottomBorder) ? '' : top / this.screenHeight * 100 + '%'; - right = left === '' ? 0 : ''; - bottom = top === '' ? this.bottomBorder + 'px' : ''; - style = this.style; - style.left = left; - style.right = right; - style.top = top; - return style.bottom = bottom; - }; - - touchend = function(e) { - var i, len, ref, touch; - ref = e.changedTouches; - for (i = 0, len = ref.length; i < len; i++) { - touch = ref[i]; - if (touch.identifier === this.identifier) { - dragend.call(this); - return; - } - } - }; - - dragend = function() { - if (this.isTouching) { - $.off(d, 'touchmove', this.move); - $.off(d, 'touchend touchcancel', this.up); - } else { - $.off(d, 'mousemove', this.move); - $.off(d, 'mouseup', this.up); - } - return $.set(this.id + ".position", this.style.cssText); - }; - - hoverstart = function(arg) { - var cb, el, endEvents, height, latestEvent, noRemove, o, rect, ref, root, width; - root = arg.root, el = arg.el, latestEvent = arg.latestEvent, endEvents = arg.endEvents, height = arg.height, width = arg.width, cb = arg.cb, noRemove = arg.noRemove; - rect = root.getBoundingClientRect(); - o = { - root: root, - el: el, - style: el.style, - isImage: (ref = el.nodeName) === 'IMG' || ref === 'VIDEO', - cb: cb, - endEvents: endEvents, - latestEvent: latestEvent, - clientHeight: doc.clientHeight, - clientWidth: doc.clientWidth, - height: height, - width: width, - noRemove: noRemove, - clientX: (rect.left + rect.right) / 2, - clientY: (rect.top + rect.bottom) / 2 - }; - o.hover = hover.bind(o); - o.hoverend = hoverend.bind(o); - o.hover(o.latestEvent); - new MutationObserver(function() { - if (el.parentNode) { - return o.hover(o.latestEvent); - } - }).observe(el, { - childList: true - }); - $.on(root, endEvents, o.hoverend); - if ($.x('ancestor::div[contains(@class,"inline")][1]', root)) { - $.on(d, 'keydown', o.hoverend); - } - $.on(root, 'mousemove', o.hover); - o.workaround = function(e) { - if (!root.contains(e.target)) { - return o.hoverend(e); - } - }; - return $.on(doc, 'mousemove', o.workaround); - }; - - hoverstart.padding = 25; - - hover = function(e) { - var clientX, clientY, height, left, marginX, ref, ref1, right, style, threshold, top, width; - this.latestEvent = e; - height = (this.height || this.el.offsetHeight) + hoverstart.padding; - width = this.width || this.el.offsetWidth; - ref = Conf['Follow Cursor'] ? e : this, clientX = ref.clientX, clientY = ref.clientY; - top = this.isImage ? Math.max(0, clientY * (this.clientHeight - height) / this.clientHeight) : Math.max(0, Math.min(this.clientHeight - height, clientY - 120)); - threshold = this.clientWidth / 2; - if (!this.isImage) { - threshold = Math.max(threshold, this.clientWidth - 400); - } - marginX = (clientX <= threshold ? clientX : this.clientWidth - clientX) + 45; - if (this.isImage) { - marginX = Math.min(marginX, this.clientWidth - width); - } - marginX += 'px'; - ref1 = clientX <= threshold ? [marginX, ''] : ['', marginX], left = ref1[0], right = ref1[1]; - style = this.style; - style.top = top + 'px'; - style.left = left; - return style.right = right; - }; - - hoverend = function(e) { - if (e.type === 'keydown' && e.keyCode !== 13 || e.target.nodeName === "TEXTAREA") { - return; - } - if (!this.noRemove) { - $.rm(this.el); - } - $.off(this.root, this.endEvents, this.hoverend); - $.off(d, 'keydown', this.hoverend); - $.off(this.root, 'mousemove', this.hover); - $.off(doc, 'mousemove', this.workaround); - if (this.cb) { - return this.cb.call(this); - } - }; - - checkbox = function(name, text, checked) { - var input, label; - if (checked == null) { - checked = Conf[name]; - } - label = $.el('label'); - input = $.el('input', { - type: 'checkbox', - name: name, - checked: checked - }); - $.add(label, [input, $.tn(" " + text)]); - return label; - }; - - UI = { - dialog: dialog, - Menu: Menu, - hover: hoverstart, - checkbox: checkbox - }; - - return UI; - -}).call(this); - -FappeTyme = (function() { - var FappeTyme; - - FappeTyme = { - init: function() { - var el, i, indicator, lc, len, ref, ref1, type; - if (!((Conf['Fappe Tyme'] || Conf['Werk Tyme']) && ((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive'))) { - return; - } - this.nodes = {}; - this.enabled = { - fappe: false, - werk: Conf['werk'] - }; - ref1 = ["Fappe", "Werk"]; - for (i = 0, len = ref1.length; i < len; i++) { - type = ref1[i]; - if (!Conf[type + " Tyme"]) { - continue; - } - lc = type.toLowerCase(); - el = UI.checkbox(lc, type + " Tyme", false); - el.title = type + " Tyme"; - this.nodes[lc] = el.firstElementChild; - if (Conf[lc]) { - this.set(lc, true); - } - $.on(this.nodes[lc], 'change', this.toggle.bind(this, lc)); - Header.menu.addEntry({ - el: el, - order: 97 - }); - indicator = $.el('span', { - className: 'indicator', - textContent: type[0], - title: type + " Tyme active" - }); - $.on(indicator, 'click', function() { - var check; - check = $.getOwn(FappeTyme.nodes, this.parentNode.id.replace('shortcut-', '')); - check.checked = !check.checked; - return $.event('change', null, check); - }); - Header.addShortcut(lc, indicator, 410); - } - if (Conf['Werk Tyme']) { - $.sync('werk', this.set.bind(this, 'werk')); - } - Callbacks.Post.push({ - name: 'Fappe Tyme', - cb: this.node - }); - return Callbacks.CatalogThread.push({ - name: 'Werk Tyme', - cb: this.catalogNode - }); - }, - node: function() { - return this.nodes.root.classList.toggle('noFile', !this.files.length); - }, - catalogNode: function() { - var file, filename; - file = this.thread.OP.files[0]; - if (!file) { - return; - } - filename = $.el('div', { - textContent: file.name, - className: 'werkTyme-filename' - }); - return $.add(this.nodes.thumb.parentNode, filename); - }, - set: function(type, enabled) { - this.enabled[type] = this.nodes[type].checked = enabled; - return $[(enabled ? 'add' : 'rm') + "Class"](doc, type + "Tyme"); - }, - toggle: function(type) { - this.set(type, !this.enabled[type]); - if (type === 'werk') { - return $.cb.checked.call(this.nodes[type]); - } - } - }; - - return FappeTyme; - -}).call(this); - -Gallery = (function() { - var Gallery; - - Gallery = { - init: function() { - var el, ref; - if (!(this.enabled = Conf['Gallery'] && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - this.delay = Conf['Slide Delay']; - el = $.el('a', { - href: 'javascript:;', - title: 'Gallery', - className: 'fa fa-picture-o', - textContent: 'Gallery' - }); - $.on(el, 'click', this.cb.toggle); - Header.addShortcut('gallery', el, 530); - return Callbacks.Post.push({ - name: 'Gallery', - cb: this.node - }); - }, - node: function() { - var file, i, len, ref, results; - ref = this.files; - results = []; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if (!file.thumb) { - continue; - } - if (Gallery.nodes) { - Gallery.generateThumb(this, file); - Gallery.nodes.total.textContent = Gallery.images.length; - } - if (!(Conf['Image Expansion'] || (g.SITE.software === 'tinyboard' && Main.jsEnabled))) { - results.push($.on(file.thumbLink, 'click', Gallery.cb.image)); - } else { - results.push(void 0); - } - } - return results; - }, - build: function(image) { - var candidate, cb, dialog, entry, file, i, j, k, key, len, len1, len2, menuButton, nodes, post, postThumb, ref, ref1, ref2, ref3, thumb, value; - cb = Gallery.cb; - if (Conf['Fullscreen Gallery']) { - $.one(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', function() { - return $.on(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', cb.close); - }); - if (typeof doc.mozRequestFullScreen === "function") { - doc.mozRequestFullScreen(); - } - if (typeof doc.webkitRequestFullScreen === "function") { - doc.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT); - } - } - Gallery.images = []; - nodes = Gallery.nodes = {}; - Gallery.fileIDs = $.dict(); - Gallery.slideshow = false; - nodes.el = dialog = $.el('div', { - id: 'a-gallery' - }); - $.extend(dialog, {innerHTML: "
        ×
        /
        "}); - ref = { - 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 (key in ref) { - value = ref[key]; - nodes[key] = $(value, dialog); - } - menuButton = $('.menu-button', dialog); - nodes.menu = new UI.Menu('gallery'); - $.on(nodes.frame, 'click', cb.blank); - if (Conf['Mouse Wheel Volume']) { - $.on(nodes.frame, 'wheel', Volume.wheel); - } - $.on(nodes.next, 'click', cb.click); - $.on(nodes.name, 'click', ImageCommon.download); - $.on($('.gal-prev', dialog), 'click', cb.prev); - $.on($('.gal-next', dialog), 'click', cb.next); - $.on($('.gal-start', dialog), 'click', cb.start); - $.on($('.gal-stop', dialog), 'click', cb.stop); - $.on($('.gal-close', dialog), 'click', cb.close); - $.on(menuButton, 'click', function(e) { - return nodes.menu.toggle(e, this, g); - }); - ref1 = Gallery.menu.createSubEntries(); - for (i = 0, len = ref1.length; i < len; i++) { - entry = ref1[i]; - entry.order = 0; - nodes.menu.addEntry(entry); - } - $.on(d, 'keydown', cb.keybinds); - if (Conf['Keybinds']) { - $.off(d, 'keydown', Keybinds.keydown); - } - $.on(window, 'resize', Gallery.cb.setHeight); - ref2 = $$(g.SITE.selectors.file.thumb); - for (j = 0, len1 = ref2.length; j < len1; j++) { - postThumb = ref2[j]; - if (!(post = Get.postFromNode(postThumb))) { - continue; - } - ref3 = post.files; - for (k = 0, len2 = ref3.length; k < len2; k++) { - file = ref3[k]; - if (!file.thumb) { - continue; - } - Gallery.generateThumb(post, file); - if (!image && Gallery.fileIDs[post.fullID + "." + file.index]) { - candidate = file.thumbLink; - if (Header.getTopOf(candidate) + candidate.getBoundingClientRect().height >= 0) { - image = candidate; - } - } - } - } - $.addClass(doc, 'gallery-open'); - $.add(d.body, dialog); - nodes.thumbs.scrollTop = 0; - nodes.current.parentElement.scrollTop = 0; - if (image) { - thumb = $("[href='" + image.href + "']", nodes.thumbs); - } - thumb || (thumb = Gallery.images[Gallery.images.length - 1]); - if (thumb) { - Gallery.open(thumb); - } - doc.style.overflow = 'hidden'; - return nodes.total.textContent = Gallery.images.length; - }, - generateThumb: function(post, file) { - var thumb, thumbImg; - if (post.isClone || post.isHidden) { - return; - } - if (!(file && file.thumb && (file.isImage || file.isVideo || Conf['PDF in Gallery']))) { - return; - } - if (Gallery.fileIDs[post.fullID + "." + file.index]) { - return; - } - Gallery.fileIDs[post.fullID + "." + file.index] = true; - thumb = $.el('a', { - className: 'gal-thumb', - href: file.url, - target: '_blank', - title: file.name - }); - thumb.dataset.id = Gallery.images.length; - thumb.dataset.post = post.fullID; - thumb.dataset.file = file.index; - thumbImg = file.thumb.cloneNode(false); - thumbImg.style.cssText = ''; - $.add(thumb, thumbImg); - $.on(thumb, 'click', Gallery.cb.open); - Gallery.images.push(thumb); - return $.add(Gallery.nodes.thumbs, thumb); - }, - load: function(thumb, errorCB) { - var elType, ext, file; - ext = thumb.href.match(/\w*$/); - elType = $.getOwn({ - 'webm': 'video', - 'mp4': 'video', - 'ogv': 'video', - 'pdf': 'iframe' - }, ext) || 'img'; - file = $.el(elType); - $.extend(file.dataset, thumb.dataset); - $.on(file, 'error', errorCB); - file.src = thumb.href; - return file; - }, - open: function(thumb) { - var el, file, i, len, link, newID, node, nodes, oldID, post, ref, ref1, sauces; - nodes = Gallery.nodes; - oldID = +nodes.current.dataset.id; - newID = +thumb.dataset.id; - if (el = Gallery.images[oldID]) { - $.rmClass(el, 'gal-highlight'); - } - $.addClass(thumb, 'gal-highlight'); - nodes.thumbs.scrollTop = thumb.offsetTop + thumb.offsetHeight / 2 - nodes.thumbs.clientHeight / 2; - if (((ref = Gallery.cache) != null ? ref.dataset.id : void 0) === '' + newID) { - file = Gallery.cache; - $.off(file, 'error', Gallery.cacheError); - $.on(file, 'error', Gallery.error); - } else { - file = Gallery.load(thumb, Gallery.error); - } - $.off(nodes.current, 'error', Gallery.error); - ImageCommon.pause(nodes.current); - $.replace(nodes.current, file); - nodes.current = file; - if (file.nodeName === 'VIDEO') { - file.loop = true; - Volume.setup(file); - if (Conf['Autoplay']) { - file.play(); - } - if (Conf['Show Controls']) { - ImageCommon.addControls(file); - } - } - doc.classList.toggle('gal-pdf', file.nodeName === 'IFRAME'); - Gallery.cb.setHeight(); - nodes.count.textContent = +thumb.dataset.id + 1; - nodes.name.download = nodes.name.textContent = thumb.title; - nodes.name.href = thumb.href; - nodes.frame.scrollTop = 0; - nodes.next.focus(); - $.rmAll(nodes.sauce); - if (Conf['Sauce'] && Sauce.links && (post = g.posts.get(file.dataset.post))) { - sauces = []; - ref1 = Sauce.links; - for (i = 0, len = ref1.length; i < len; i++) { - link = ref1[i]; - if ((node = Sauce.createSauceLink(link, post, post.files[+file.dataset.file]))) { - sauces.push($.tn(' '), node); - } - } - $.add(nodes.sauce, sauces); - } - if (Gallery.slideshow && (newID > oldID || (oldID === Gallery.images.length - 1 && newID === 0))) { - Gallery.setupTimer(); - } else { - Gallery.cb.stop(); - } - if (Conf['Scroll to Post'] && (post = g.posts.get(file.dataset.post))) { - Header.scrollTo(post.nodes.root); - } - if (isNaN(oldID) || newID === (oldID + 1) % Gallery.images.length) { - return Gallery.cache = Gallery.load(Gallery.images[(newID + 1) % Gallery.images.length], Gallery.cacheError); - } - }, - error: function() { - var file, post, ref; - if (((ref = this.error) != null ? ref.code : void 0) === MediaError.MEDIA_ERR_DECODE) { - return new Notice('error', 'Corrupt or unplayable video', 30); - } - if (ImageCommon.isFromArchive(this)) { - return; - } - post = g.posts.get(this.dataset.post); - file = post.files[+this.dataset.file]; - return ImageCommon.error(this, post, file, null, (function(_this) { - return function(url) { - if (!url) { - return; - } - Gallery.images[+_this.dataset.id].href = url; - if (Gallery.nodes.current === _this) { - return _this.src = url; - } - }; - })(this)); - }, - cacheError: function() { - return delete Gallery.cache; - }, - cleanupTimer: function() { - var current; - clearTimeout(Gallery.timeoutID); - current = Gallery.nodes.current; - $.off(current, 'canplaythrough load', Gallery.startTimer); - return $.off(current, 'ended', Gallery.cb.next); - }, - startTimer: function() { - return Gallery.timeoutID = setTimeout(Gallery.checkTimer, Gallery.delay * $.SECOND); - }, - setupTimer: function() { - var current, isVideo; - Gallery.cleanupTimer(); - current = Gallery.nodes.current; - isVideo = current.nodeName === 'VIDEO'; - if (isVideo) { - current.play(); - } - if ((isVideo ? current.readyState >= 4 : current.complete) || current.nodeName === 'IFRAME') { - return Gallery.startTimer(); - } else { - return $.on(current, (isVideo ? 'canplaythrough' : 'load'), Gallery.startTimer); - } - }, - checkTimer: function() { - var current; - current = Gallery.nodes.current; - if (current.nodeName === 'VIDEO' && !current.paused) { - $.on(current, 'ended', Gallery.cb.next); - return current.loop = false; - } else { - return Gallery.cb.next(); - } - }, - cb: { - keybinds: function(e) { - var cb, key; - if (!(key = Keybinds.keyCode(e))) { - return; - } - cb = (function() { - switch (key) { - case Conf['Close']: - case Conf['Open Gallery']: - return Gallery.cb.close; - case Conf['Next Gallery Image']: - return Gallery.cb.next; - case Conf['Advance Gallery']: - return Gallery.cb.advance; - case Conf['Previous Gallery Image']: - return Gallery.cb.prev; - case Conf['Pause']: - return Gallery.cb.pause; - case Conf['Slideshow']: - return Gallery.cb.toggleSlideshow; - case Conf['Rotate image anticlockwise']: - return Gallery.cb.rotateLeft; - case Conf['Rotate image clockwise']: - return Gallery.cb.rotateRight; - case Conf['Download Gallery Image']: - return Gallery.cb.download; - } - })(); - if (!cb) { - return; - } - e.stopPropagation(); - e.preventDefault(); - return cb(); - }, - open: function(e) { - if (e) { - e.preventDefault(); - } - if (this) { - return Gallery.open(this); - } - }, - image: function(e) { - e.preventDefault(); - e.stopPropagation(); - return Gallery.build(this); - }, - prev: function() { - return Gallery.cb.open.call(Gallery.images[+Gallery.nodes.current.dataset.id - 1] || Gallery.images[Gallery.images.length - 1]); - }, - next: function() { - return Gallery.cb.open.call(Gallery.images[+Gallery.nodes.current.dataset.id + 1] || Gallery.images[0]); - }, - click: function(e) { - if (ImageCommon.onControls(e)) { - return; - } - e.preventDefault(); - return Gallery.cb.advance(); - }, - advance: function() { - if (!Conf['Autoplay'] && Gallery.nodes.current.paused) { - return Gallery.nodes.current.play(); - } else { - return Gallery.cb.next(); - } - }, - toggle: function() { - return (Gallery.nodes ? Gallery.cb.close : Gallery.build)(); - }, - blank: function(e) { - if (e.target === this) { - return Gallery.cb.close(); - } - }, - toggleSlideshow: function() { - return Gallery.cb[Gallery.slideshow ? 'stop' : 'start'](); - }, - download: function() { - var name; - name = $('.gal-name'); - return name.click(); - }, - pause: function() { - var current; - Gallery.cb.stop(); - current = Gallery.nodes.current; - if (current.nodeName === 'VIDEO') { - return current[current.paused ? 'play' : 'pause'](); - } - }, - start: function() { - $.addClass(Gallery.nodes.buttons, 'gal-playing'); - Gallery.slideshow = true; - return Gallery.setupTimer(); - }, - stop: function() { - var current; - if (!Gallery.slideshow) { - return; - } - Gallery.cleanupTimer(); - current = Gallery.nodes.current; - if (current.nodeName === 'VIDEO') { - current.loop = true; - } - $.rmClass(Gallery.nodes.buttons, 'gal-playing'); - return Gallery.slideshow = false; - }, - rotateLeft: function() { - return Gallery.cb.rotate(270); - }, - rotateRight: function() { - return Gallery.cb.rotate(90); - }, - rotate: $.debounce(100, function(delta) { - var current; - current = Gallery.nodes.current; - if (current.nodeName === 'IFRAME') { - return; - } - current.dataRotate = ((current.dataRotate || 0) + delta) % 360; - current.style.transform = "rotate(" + current.dataRotate + "deg)"; - return Gallery.cb.setHeight(); - }), - close: function() { - $.off(Gallery.nodes.current, 'error', Gallery.error); - ImageCommon.pause(Gallery.nodes.current); - $.rm(Gallery.nodes.el); - $.rmClass(doc, 'gallery-open'); - if (Conf['Fullscreen Gallery']) { - $.off(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', Gallery.cb.close); - if (typeof d.mozCancelFullScreen === "function") { - d.mozCancelFullScreen(); - } - if (typeof d.webkitExitFullscreen === "function") { - d.webkitExitFullscreen(); - } - } - delete Gallery.nodes; - delete Gallery.fileIDs; - doc.style.overflow = ''; - $.off(d, 'keydown', Gallery.cb.keybinds); - if (Conf['Keybinds']) { - $.on(d, 'keydown', Keybinds.keydown); - } - $.off(window, 'resize', Gallery.cb.setHeight); - return clearTimeout(Gallery.timeoutID); - }, - setFitness: function() { - return (this.checked ? $.addClass : $.rmClass)(doc, "gal-" + (this.name.toLowerCase().replace(/\s+/g, '-'))); - }, - setHeight: $.debounce(100, function() { - var containerHeight, containerWidth, current, dim, frame, height, margin, minHeight, ref, ref1, ref2, ref3, style, width; - ref = Gallery.nodes, current = ref.current, frame = ref.frame; - style = current.style; - if (Conf['Stretch to Fit'] && (dim = (ref1 = g.posts.get(current.dataset.post)) != null ? ref1.files[+current.dataset.file].dimensions : void 0)) { - ref2 = dim.split('x'), width = ref2[0], height = ref2[1]; - containerWidth = frame.clientWidth; - containerHeight = doc.clientHeight - 25; - if ((current.dataRotate || 0) % 180 === 90) { - ref3 = [containerHeight, containerWidth], containerWidth = ref3[0], containerHeight = ref3[1]; - } - minHeight = Math.min(containerHeight, height / width * containerWidth); - style.minHeight = minHeight + 'px'; - style.minWidth = (width / height * minHeight) + 'px'; - } else { - style.minHeight = style.minWidth = ''; - } - if ((current.dataRotate || 0) % 180 === 90) { - style.maxWidth = Conf['Fit Height'] ? (doc.clientHeight - 25) + "px" : 'none'; - style.maxHeight = Conf['Fit Width'] ? frame.clientWidth + "px" : 'none'; - margin = (current.clientWidth - current.clientHeight) / 2; - return style.margin = margin + "px " + (-margin) + "px"; - } else { - return style.maxWidth = style.maxHeight = style.margin = ''; - } - }), - setDelay: function() { - return Gallery.delay = +this.value; - } - }, - menu: { - init: function() { - var el; - if (!Gallery.enabled) { - return; - } - el = $.el('span', { - textContent: 'Gallery', - className: 'gallery-link' - }); - return Header.menu.addEntry({ - el: el, - order: 105, - subEntries: Gallery.menu.createSubEntries() - }); - }, - createSubEntry: function(name) { - var input, label; - label = UI.checkbox(name, name); - input = label.firstElementChild; - if (name === 'Hide Thumbnails' || name === 'Fit Width' || name === 'Fit Height') { - $.on(input, 'change', Gallery.cb.setFitness); - } - $.event('change', null, input); - $.on(input, 'change', $.cb.checked); - if (name === 'Hide Thumbnails' || name === 'Fit Width' || name === 'Fit Height' || name === 'Stretch to Fit') { - $.on(input, 'change', Gallery.cb.setHeight); - } - return { - el: label - }; - }, - createSubEntries: function() { - var delayInput, delayLabel, item, subEntries; - subEntries = (function() { - var i, len, ref, results; - ref = ['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Stretch to Fit', 'Scroll to Post']; - results = []; - for (i = 0, len = ref.length; i < len; i++) { - item = ref[i]; - results.push(Gallery.menu.createSubEntry(item)); - } - return results; - })(); - delayLabel = $.el('label', {innerHTML: "Slide Delay: "}); - delayInput = delayLabel.firstElementChild; - delayInput.value = Gallery.delay; - $.on(delayInput, 'change', Gallery.cb.setDelay); - $.on(delayInput, 'change', $.cb.value); - subEntries.push({ - el: delayLabel - }); - return subEntries; - } - } - }; - - return Gallery; - -}).call(this); - -ImageCommon = (function() { - var ImageCommon, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - ImageCommon = { - pause: function(video) { - if (video.nodeName !== 'VIDEO') { - return; - } - video.pause(); - $.off(video, 'volumechange', Volume.change); - return video.muted = true; - }, - rewind: function(el) { - if (el.nodeName === 'VIDEO') { - if (el.readyState >= el.HAVE_METADATA) { - return el.currentTime = 0; - } - } else if (/\.gif$/.test(el.src)) { - return $.queueTask(function() { - return el.src = el.src; - }); - } - }, - pushCache: function(el) { - ImageCommon.cache = el; - return $.on(el, 'error', ImageCommon.cacheError); - }, - popCache: function() { - var el; - el = ImageCommon.cache; - $.off(el, 'error', ImageCommon.cacheError); - delete ImageCommon.cache; - return el; - }, - cacheError: function() { - if (ImageCommon.cache === this) { - return delete ImageCommon.cache; - } - }, - decodeError: function(file, fileObj) { - var message, ref; - if (((ref = file.error) != null ? ref.code : void 0) !== MediaError.MEDIA_ERR_DECODE) { - return false; - } - if (!(message = $('.warning', fileObj.thumb.parentNode))) { - message = $.el('div', { - className: 'warning' - }); - $.after(fileObj.thumb, message); - } - message.textContent = 'Error: Corrupt or unplayable video'; - return true; - }, - isFromArchive: function(file) { - return g.SITE.software === 'yotsuba' && !ImageHost.test(file.src.split('/')[2]); - }, - error: function(file, post, fileObj, delay, cb) { - var base, parseJSON, redirect, src, threadJSON, timeoutID, url; - src = fileObj.url.split('/'); - url = null; - if (g.SITE.software === 'yotsuba' && Conf['404 Redirect']) { - url = Redirect.to('file', { - boardID: post.board.ID, - filename: src[src.length - 1] - }); - } - if (!(url && Redirect.securityCheck(url))) { - url = null; - } - if ((post.isDead || fileObj.isDead) && !ImageCommon.isFromArchive(file)) { - return cb(url); - } - if (delay != null) { - timeoutID = setTimeout((function() { - return cb(url); - }), delay); - } - if (post.isDead || fileObj.isDead) { - return; - } - redirect = function() { - if (!ImageCommon.isFromArchive(file)) { - if (delay != null) { - clearTimeout(timeoutID); - } - return cb(url); - } - }; - threadJSON = typeof (base = g.SITE.urls).threadJSON === "function" ? base.threadJSON(post) : void 0; - if (!threadJSON) { - return; - } - parseJSON = function(isArchiveURL) { - var archivedThreadJSON, base1, i, len, postObj, ref, ref1; - if (this.status === 404) { - if (!isArchiveURL && (archivedThreadJSON = typeof (base1 = g.SITE.urls).archivedThreadJSON === "function" ? base1.archivedThreadJSON(post) : void 0)) { - $.ajax(archivedThreadJSON, { - onloadend: function() { - return parseJSON.call(this, true); - } - }); - } else { - post.kill(!post.isClone, fileObj.index); - } - } - if (this.status !== 200) { - return redirect(); - } - ref = this.response.posts; - for (i = 0, len = ref.length; i < len; i++) { - postObj = ref[i]; - if (postObj.no === post.ID) { - break; - } - } - if (postObj.no !== post.ID) { - post.kill(); - return redirect(); - } else if (ref1 = fileObj.docIndex, indexOf.call(g.SITE.Build.parseJSON(postObj, post.board).filesDeleted, ref1) >= 0) { - post.kill(true); - return redirect(); - } else { - return url = fileObj.url; - } - }; - return $.ajax(threadJSON, { - onloadend: function() { - return parseJSON.call(this); - } - }); - }, - addControls: function(video) { - var handler; - handler = function() { - var t; - $.off(video, 'mouseover', handler); - t = new Date().getTime(); - return $.asap((function() { - return $.engine !== 'gecko' || (video.readyState >= 3 && video.currentTime <= Math.max(0.1, video.duration - 0.5)) || new Date().getTime() >= t + 1000; - }), function() { - return video.controls = true; - }); - }; - return $.on(video, 'mouseover', handler); - }, - onControls: function(e) { - return (Conf['Show Controls'] && Conf['Click Passthrough'] && e.target.nodeName === 'VIDEO') || (e.target.controls && e.target.getBoundingClientRect().bottom - e.clientY < 35); - }, - download: function(e) { - var download, href, ref; - if (this.protocol === 'blob:') { - return true; - } - e.preventDefault(); - ref = this, href = ref.href, download = ref.download; - return CrossOrigin.file(href, function(blob) { - var a; - if (blob) { - a = $.el('a', { - href: URL.createObjectURL(blob), - download: download, - hidden: true - }); - $.add(d.body, a); - a.click(); - return $.rm(a); - } else { - return new Notice('warning', "Could not download " + href, 20); - } - }); - } - }; - - return ImageCommon; - -}).call(this); - -ImageExpand = (function() { - var ImageExpand, - slice = [].slice; - - ImageExpand = { - init: function() { - var ref; - if (!(this.enabled = Conf['Image Expansion'] && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - this.EAI = $.el('a', { - className: 'expand-all-shortcut fa fa-expand', - textContent: 'EAI', - title: 'Expand All Images', - href: 'javascript:;' - }); - $.on(this.EAI, 'click', this.cb.toggleAll); - Header.addShortcut('expand-all', this.EAI, 520); - $.on(d, 'scroll visibilitychange', this.cb.playVideos); - this.videoControls = $.el('span', { - className: 'video-controls' - }); - $.extend(this.videoControls, {innerHTML: " contract"}); - return Callbacks.Post.push({ - name: 'Image Expansion', - cb: this.node - }); - }, - node: function() { - var ref; - if (!(this.file && (this.file.isImage || this.file.isVideo))) { - return; - } - $.on(this.file.thumbLink, 'click', ImageExpand.cb.toggle); - if (this.isClone) { - if (this.file.isExpanding) { - ImageExpand.contract(this); - return ImageExpand.expand(this); - } else if (this.file.isExpanded && this.file.isVideo) { - Volume.setup(this.file.fullImage); - ImageExpand.setupVideoCB(this); - return ImageExpand.setupVideo(this, !((ref = this.origin.file.fullImage) != null ? ref.paused : void 0) || this.origin.file.wasPlaying, this.file.fullImage.controls); - } - } else if (ImageExpand.on && !this.isHidden && !this.isFetchedQuote && (Conf['Expand spoilers'] || !this.file.isSpoiler) && (Conf['Expand videos'] || !this.file.isVideo)) { - return ImageExpand.expand(this); - } - }, - cb: { - toggle: function(e) { - var file, post, ref; - if ($.modifiedClick(e)) { - return; - } - post = Get.postFromNode(this); - file = post.file; - if (file.isExpanded && ImageCommon.onControls(e)) { - return; - } - e.preventDefault(); - if (!Conf['Autoplay'] && ((ref = file.fullImage) != null ? ref.paused : void 0)) { - return file.fullImage.play(); - } else { - return ImageExpand.toggle(post); - } - }, - toggleAll: function() { - var func, threadRoot, toggle; - $.event('CloseMenu'); - threadRoot = Nav.getThread(); - toggle = function(post) { - var file; - file = post.file; - if (!(file && (file.isImage || file.isVideo) && doc.contains(post.nodes.root))) { - return; - } - if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || !Conf['Expand videos'] && file.isVideo || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0 || Conf['Expand thread only'] && g.VIEW === 'index' && !(threadRoot != null ? threadRoot.contains(file.thumb) : void 0))) { - return; - } - return $.queueTask(func, post); - }; - if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) { - ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress'; - ImageExpand.EAI.title = 'Contract All Images'; - func = ImageExpand.expand; - } else { - ImageExpand.EAI.className = 'expand-all-shortcut fa fa-expand'; - ImageExpand.EAI.title = 'Expand All Images'; - func = ImageExpand.contract; - } - return g.posts.forEach(function(post) { - var i, len, ref; - ref = [post].concat(slice.call(post.clones)); - for (i = 0, len = ref.length; i < len; i++) { - post = ref[i]; - toggle(post); - } - }); - }, - playVideos: function() { - return g.posts.forEach(function(post) { - var file, i, len, ref, video, visible; - ref = [post].concat(slice.call(post.clones)); - for (i = 0, len = ref.length; i < len; i++) { - post = ref[i]; - file = post.file; - if (!(file && file.isVideo && file.isExpanded)) { - continue; - } - video = file.fullImage; - visible = ($.hasAudio(video) && !video.muted) || Header.isNodeVisible(video); - if (visible && file.wasPlaying) { - delete file.wasPlaying; - video.play(); - } else if (!visible && !video.paused) { - file.wasPlaying = true; - video.pause(); - } - } - }); - }, - setFitness: function() { - return $[this.checked ? 'addClass' : 'rmClass'](doc, this.name.toLowerCase().replace(/\s+/g, '-')); - } - }, - toggle: function(post) { - var next; - if (!(post.file.isExpanding || post.file.isExpanded)) { - post.file.scrollIntoView = Conf['Scroll into view']; - ImageExpand.expand(post); - return; - } - ImageExpand.contract(post); - if (Conf['Advance on contract']) { - next = post.nodes.root; - while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) { - if (!($('.stub', next) || next.offsetHeight === 0)) { - break; - } - } - if (next) { - return Header.scrollTo(next); - } - } - }, - contract: function(post) { - var bottom, cb, el, eventName, file, i, len, oldHeight, ref, ref1, scrollY, top, x; - file = post.file; - if (el = file.fullImage) { - top = Header.getTopOf(el); - bottom = top + el.getBoundingClientRect().height; - oldHeight = d.body.clientHeight; - scrollY = window.scrollY; - } - $.rmClass(post.nodes.root, 'expanded-image'); - $.rmClass(file.thumb, 'expanding'); - $.rm(file.videoControls); - file.thumbLink.href = file.url; - file.thumbLink.target = '_blank'; - ref = ['isExpanding', 'isExpanded', 'videoControls', 'wasPlaying', 'scrollIntoView']; - for (i = 0, len = ref.length; i < len; i++) { - x = ref[i]; - delete file[x]; - } - if (!el) { - return; - } - if (doc.contains(el)) { - if (bottom <= 0) { - window.scrollBy(0, scrollY - window.scrollY + d.body.clientHeight - oldHeight); - } else { - Header.scrollToIfNeeded(post.nodes.root); - } - if (window.scrollX > 0) { - window.scrollBy(-window.scrollX, 0); - } - } - $.off(el, 'error', ImageExpand.error); - ImageCommon.pushCache(el); - if (file.isVideo) { - ImageCommon.pause(el); - ref1 = ImageExpand.videoCB; - for (eventName in ref1) { - cb = ref1[eventName]; - $.off(el, eventName, cb); - } - } - if (Conf['Restart when Opened']) { - ImageCommon.rewind(file.thumb); - } - delete file.fullImage; - return $.queueTask(function() { - if (file.isExpanding || file.isExpanded) { - return; - } - $.rmClass(el, 'full-image'); - if (el.id) { - return; - } - return $.rm(el); - }); - }, - expand: function(post, src) { - var el, file, isVideo, ref, thumb, thumbLink; - file = post.file; - thumb = file.thumb, thumbLink = file.thumbLink, isVideo = file.isVideo; - if (post.isHidden || file.isExpanding || file.isExpanded) { - return; - } - $.addClass(thumb, 'expanding'); - file.isExpanding = true; - if (file.fullImage) { - el = file.fullImage; - } else if (((ref = ImageCommon.cache) != null ? ref.dataset.fileID : void 0) === (post.fullID + "." + file.index)) { - el = file.fullImage = ImageCommon.popCache(); - $.on(el, 'error', ImageExpand.error); - if (Conf['Restart when Opened'] && el.id !== 'ihover') { - ImageCommon.rewind(el); - } - el.removeAttribute('id'); - } else { - el = file.fullImage = $.el((isVideo ? 'video' : 'img')); - el.dataset.fileID = post.fullID + "." + file.index; - $.on(el, 'error', ImageExpand.error); - el.src = src || file.url; - } - el.className = 'full-image'; - $.after(thumb, el); - if (isVideo) { - if (!file.videoControls) { - file.videoControls = ImageExpand.videoControls.cloneNode(true); - $.add(file.text, file.videoControls); - } - thumbLink.removeAttribute('href'); - thumbLink.removeAttribute('target'); - el.loop = true; - Volume.setup(el); - ImageExpand.setupVideoCB(post); - } - if (!isVideo) { - return $.asap((function() { - return el.naturalHeight; - }), function() { - return ImageExpand.completeExpand(post); - }); - } else if (el.readyState >= el.HAVE_METADATA) { - return ImageExpand.completeExpand(post); - } else { - return $.on(el, 'loadedmetadata', function() { - return ImageExpand.completeExpand(post); - }); - } - }, - completeExpand: function(post) { - var bottom, file, imageBottom, oldHeight, scrollY; - file = post.file; - if (!file.isExpanding) { - return; - } - bottom = Header.getTopOf(file.thumb) + file.thumb.getBoundingClientRect().height; - oldHeight = d.body.clientHeight; - scrollY = window.scrollY; - $.addClass(post.nodes.root, 'expanded-image'); - $.rmClass(file.thumb, 'expanding'); - file.isExpanded = true; - delete file.isExpanding; - if (doc.contains(post.nodes.root) && bottom <= 0) { - window.scrollBy(0, scrollY - window.scrollY + d.body.clientHeight - oldHeight); - } - if (file.scrollIntoView) { - delete file.scrollIntoView; - imageBottom = Math.min(doc.clientHeight - file.fullImage.getBoundingClientRect().bottom - 25, Header.getBottomOf(file.fullImage)); - if (imageBottom < 0) { - window.scrollBy(0, Math.min(-imageBottom, Header.getTopOf(file.fullImage))); - } - } - if (file.isVideo) { - return ImageExpand.setupVideo(post, Conf['Autoplay'], Conf['Show Controls']); - } - }, - setupVideo: function(post, playing, controls) { - var fullImage; - fullImage = post.file.fullImage; - if (!playing) { - fullImage.controls = controls; - return; - } - fullImage.controls = false; - $.asap((function() { - return doc.contains(fullImage); - }), function() { - if (!d.hidden && Header.isNodeVisible(fullImage)) { - return fullImage.play(); - } else { - return post.file.wasPlaying = true; - } - }); - if (controls) { - return ImageCommon.addControls(fullImage); - } - }, - videoCB: (function() { - var mousedown; - mousedown = false; - return { - mouseover: function() { - return mousedown = false; - }, - mousedown: function(e) { - if (e.button === 0) { - return mousedown = true; - } - }, - mouseup: function(e) { - if (e.button === 0) { - return mousedown = false; - } - }, - mouseout: function(e) { - if (((e.buttons & 1) || mousedown) && e.clientX <= this.getBoundingClientRect().left) { - return ImageExpand.toggle(Get.postFromNode(this)); - } - } - }; - })(), - setupVideoCB: function(post) { - var cb, eventName, ref; - ref = ImageExpand.videoCB; - for (eventName in ref) { - cb = ref[eventName]; - $.on(post.file.fullImage, eventName, cb); - } - if (post.file.videoControls) { - return $.on(post.file.videoControls.firstElementChild, 'click', function() { - return ImageExpand.toggle(post); - }); - } - }, - error: function() { - var post; - post = Get.postFromNode(this); - $.rm(this); - delete post.file.fullImage; - if (!(post.file.isExpanding || post.file.isExpanded)) { - return; - } - if (ImageCommon.decodeError(this, post.file)) { - return ImageExpand.contract(post); - } - if (ImageCommon.isFromArchive(this)) { - return ImageExpand.contract(post); - } - return ImageCommon.error(this, post, post.file, 10 * $.SECOND, function(URL) { - if (post.file.isExpanding || post.file.isExpanded) { - ImageExpand.contract(post); - if (URL) { - return ImageExpand.expand(post, URL); - } - } - }); - }, - menu: { - init: function() { - var conf, createSubEntry, el, name, ref, subEntries; - if (!ImageExpand.enabled) { - return; - } - el = $.el('span', { - textContent: 'Image Expansion', - className: 'image-expansion-link' - }); - createSubEntry = ImageExpand.menu.createSubEntry; - subEntries = []; - ref = Config.imageExpansion; - for (name in ref) { - conf = ref[name]; - subEntries.push(createSubEntry(name, conf[1])); - } - return Header.menu.addEntry({ - el: el, - order: 105, - subEntries: subEntries - }); - }, - createSubEntry: function(name, desc) { - var input, label; - label = UI.checkbox(name, name); - label.title = desc; - input = label.firstElementChild; - if (name === 'Fit width' || name === 'Fit height') { - $.on(input, 'change', ImageExpand.cb.setFitness); - } - $.event('change', null, input); - $.on(input, 'change', $.cb.checked); - return { - el: label - }; - } - } - }; - - return ImageExpand; - -}).call(this); - -ImageHost = (function() { - var ImageHost; - - ImageHost = { - init: function() { - var ref; - if (!((this.useFaster = /\S/.test(Conf['fourchanImageHost'])) && g.SITE.software === 'yotsuba' && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - return Callbacks.Post.push({ - name: 'Image Host Rewriting', - cb: this.node - }); - }, - suggestions: ['i.4cdn.org', 'is2.4chan.org'], - host: function() { - return Conf['fourchanImageHost'].trim() || 'i.4cdn.org'; - }, - flashHost: function() { - return 'i.4cdn.org'; - }, - thumbHost: function() { - return 'i.4cdn.org'; - }, - test: function(hostname) { - return hostname === 'i.4cdn.org' || ImageHost.regex.test(hostname); - }, - regex: /^is\d*\.4chan(?:nel)?\.org$/, - node: function() { - var host; - if (this.isClone) { - return; - } - host = ImageHost.host(); - if (this.file && ImageHost.test(this.file.url.split('/')[2]) && !/\.swf$/.test(this.file.url)) { - this.file.link.hostname = host; - if (this.file.thumbLink) { - this.file.thumbLink.hostname = host; - } - this.file.url = this.file.link.href; - } - return ImageHost.fixLinks($$('a', this.nodes.comment)); - }, - fixLinks: function(links) { - var host, i, len, link; - for (i = 0, len = links.length; i < len; i++) { - link = links[i]; - if (!(ImageHost.test(link.hostname) && !/\.swf$/.test(link.pathname))) { - continue; - } - host = ImageHost.host(); - if (link.hostname !== host) { - link.hostname = host; - } - } - } - }; - - return ImageHost; - -}).call(this); - -ImageHover = (function() { - var ImageHover; - - ImageHover = { - init: function() { - var ref; - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - if (Conf['Image Hover']) { - Callbacks.Post.push({ - name: 'Image Hover', - cb: this.node - }); - } - if (Conf['Image Hover in Catalog']) { - return Callbacks.CatalogThread.push({ - name: 'Image Hover', - cb: this.catalogNode - }); - } - }, - node: function() { - var file, i, len, ref, results; - ref = this.files; - results = []; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if ((file.isImage || file.isVideo) && file.thumb) { - results.push($.on(file.thumb, 'mouseover', ImageHover.mouseover(this, file))); - } - } - return results; - }, - catalogNode: function() { - var file; - file = this.thread.OP.files[0]; - if (!(file && (file.isImage || file.isVideo))) { - return; - } - return $.on(this.nodes.thumb, 'mouseover', ImageHover.mouseover(this.thread.OP, file)); - }, - mouseover: function(post, file) { - return function(e) { - var base, el, error, height, isVideo, maxHeight, maxWidth, ref, ref1, scale, width, x; - if (!doc.contains(this)) { - return; - } - isVideo = file.isVideo; - if (file.isExpanding || file.isExpanded || (typeof (base = g.SITE).isThumbExpanded === "function" ? base.isThumbExpanded(file) : void 0)) { - return; - } - error = ImageHover.error(post, file); - if (((ref = ImageCommon.cache) != null ? ref.dataset.fileID : void 0) === (post.fullID + "." + file.index)) { - el = ImageCommon.popCache(); - $.on(el, 'error', error); - } else { - el = $.el((isVideo ? 'video' : 'img')); - el.dataset.fileID = post.fullID + "." + file.index; - $.on(el, 'error', error); - el.src = file.url; - } - if (Conf['Restart when Opened']) { - ImageCommon.rewind(el); - ImageCommon.rewind(this); - } - el.id = 'ihover'; - $.add(Header.hover, el); - if (isVideo) { - el.loop = true; - el.controls = false; - Volume.setup(el); - if (Conf['Autoplay']) { - el.play(); - if (this.nodeName === 'VIDEO') { - this.currentTime = el.currentTime; - } - } - } - if (file.dimensions) { - ref1 = (function() { - var i, len, ref1, results; - ref1 = file.dimensions.split('x'); - results = []; - for (i = 0, len = ref1.length; i < len; i++) { - x = ref1[i]; - results.push(+x); - } - return results; - })(), width = ref1[0], height = ref1[1]; - maxWidth = doc.clientWidth; - maxHeight = doc.clientHeight - UI.hover.padding; - scale = Math.min(1, maxWidth / width, maxHeight / height); - width *= scale; - height *= scale; - el.style.maxWidth = width + "px"; - el.style.maxHeight = height + "px"; - } - return UI.hover({ - root: this, - el: el, - latestEvent: e, - endEvents: 'mouseout click', - height: height, - width: width, - noRemove: true, - cb: function() { - $.off(el, 'error', error); - ImageCommon.pushCache(el); - ImageCommon.pause(el); - $.rm(el); - return el.removeAttribute('style'); - } - }); - }; - }, - error: function(post, file) { - return function() { - if (ImageCommon.decodeError(this, file)) { - return; - } - return ImageCommon.error(this, post, file, 3 * $.SECOND, (function(_this) { - return function(URL) { - if (URL) { - return _this.src = URL + (_this.src === URL ? '?' + Date.now() : ''); - } else { - return $.rm(_this); - } - }; - })(this)); - }; - } - }; - - return ImageHover; - -}).call(this); - -ImageLoader = (function() { - var ImageLoader, - slice = [].slice; - - ImageLoader = { - init: function() { - var el, ref, ref1, replace; - if ((ref = g.VIEW) !== 'index' && ref !== 'thread' && ref !== 'archive') { - return; - } - replace = Conf['Replace JPG'] || Conf['Replace PNG'] || Conf['Replace GIF'] || Conf['Replace WEBM']; - if (!(Conf['Image Prefetching'] || replace)) { - return; - } - Callbacks.Post.push({ - name: 'Image Replace', - cb: this.node - }); - $.on(d, 'PostsInserted', function() { - if (ImageLoader.prefetchEnabled || replace) { - return g.posts.forEach(ImageLoader.prefetchAll); - } - }); - if (Conf['Replace WEBM']) { - $.on(d, 'scroll visibilitychange 4chanXInitFinished PostsInserted', this.playVideos); - } - if (!(Conf['Image Prefetching'] && ((ref1 = g.VIEW) === 'index' || ref1 === 'thread'))) { - return; - } - el = $.el('a', { - href: 'javascript:;', - title: 'Prefetch Images', - className: 'fa fa-bolt disabled', - textContent: 'Prefetch' - }); - $.on(el, 'click', this.toggle); - return Header.addShortcut('prefetch', el, 525); - }, - node: function() { - var file, i, len, ref; - if (this.isClone) { - return; - } - ref = this.files; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if (Conf['Replace WEBM'] && file.isVideo) { - ImageLoader.replaceVideo(this, file); - } - ImageLoader.prefetch(this, file); - } - }, - replaceVideo: function(post, file) { - var attr, i, len, ref, thumb, video; - thumb = file.thumb; - video = $.el('video', { - preload: 'none', - loop: true, - muted: true, - poster: thumb.src || thumb.dataset.src, - textContent: thumb.alt, - className: thumb.className - }); - video.setAttribute('muted', 'muted'); - video.dataset.md5 = thumb.dataset.md5; - ref = ['height', 'width', 'maxHeight', 'maxWidth']; - for (i = 0, len = ref.length; i < len; i++) { - attr = ref[i]; - video.style[attr] = thumb.style[attr]; - } - video.src = file.url; - $.replace(thumb, video); - file.thumb = video; - return file.videoThumb = true; - }, - prefetch: function(post, file) { - var clone, el, i, isImage, isVideo, len, ref, ref1, replace, thumb, type, url; - isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, url = file.url; - if (file.isPrefetched || !(isImage || isVideo) || post.isHidden || post.thread.isHidden) { - return; - } - if (isVideo) { - type = 'WEBM'; - } else { - type = (ref = url.match(/\.([^.]+)$/)) != null ? ref[1].toUpperCase() : void 0; - if (type === 'JPEG') { - type = 'JPG'; - } - } - replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src || thumb.dataset.src); - if (!(replace || ImageLoader.prefetchEnabled)) { - return; - } - if ($.hasClass(doc, 'catalog-mode')) { - return; - } - if (![post].concat(slice.call(post.clones)).some(function(clone) { - return doc.contains(clone.nodes.root); - })) { - return; - } - file.isPrefetched = true; - if (file.videoThumb) { - ref1 = post.clones; - for (i = 0, len = ref1.length; i < len; i++) { - clone = ref1[i]; - clone.file.thumb.preload = 'auto'; - } - thumb.preload = 'auto'; - if ($.engine === 'gecko') { - $.on(thumb, 'loadeddata', function() { - return this.removeAttribute('poster'); - }); - } - return; - } - el = $.el(isImage ? 'img' : 'video'); - if (isVideo) { - el.preload = 'auto'; - } - if (replace && isImage) { - $.on(el, 'load', function() { - var j, len1, ref2; - ref2 = post.clones; - for (j = 0, len1 = ref2.length; j < len1; j++) { - clone = ref2[j]; - clone.file.thumb.src = url; - } - return thumb.src = url; - }); - } - return el.src = url; - }, - prefetchAll: function(post) { - var file, i, len, ref; - ref = post.files; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - ImageLoader.prefetch(post, file); - } - }, - toggle: function() { - ImageLoader.prefetchEnabled = !ImageLoader.prefetchEnabled; - this.classList.toggle('disabled', !ImageLoader.prefetchEnabled); - if (ImageLoader.prefetchEnabled) { - g.posts.forEach(ImageLoader.prefetchAll); - } - }, - playVideos: function() { - var qpClone, ref; - qpClone = (ref = $.id('qp')) != null ? ref.firstElementChild : void 0; - return g.posts.forEach(function(post) { - var file, i, j, len, len1, ref1, ref2, thumb; - ref1 = [post].concat(slice.call(post.clones)); - for (i = 0, len = ref1.length; i < len; i++) { - post = ref1[i]; - ref2 = post.files; - for (j = 0, len1 = ref2.length; j < len1; j++) { - file = ref2[j]; - if (!file.videoThumb) { - continue; - } - thumb = file.thumb; - if (Header.isNodeVisible(thumb) || post.nodes.root === qpClone) { - thumb.play(); - } else { - thumb.pause(); - } - } - } - }); - } - }; - - return ImageLoader; - -}).call(this); - -Metadata = (function() { - var Metadata; - - Metadata = { - init: function() { - var ref; - if (!(Conf['WEBM Metadata'] && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - return Callbacks.Post.push({ - name: 'WEBM Metadata', - cb: this.node - }); - }, - node: function() { - var el, file, i, j, len1, ref; - ref = this.files; - for (i = j = 0, len1 = ref.length; j < len1; i = ++j) { - file = ref[i]; - if (!(/webm$/i.test(file.url))) { - continue; - } - if (this.isClone) { - el = $('.webm-title', file.text); - } else { - el = $.el('span', { - className: 'webm-title' - }); - el.dataset.index = i; - $.extend(el, {innerHTML: ""}); - $.add(file.text, [$.tn(' '), el]); - } - if (el.children.length === 1) { - $.one(el.lastElementChild, 'mouseover focus', Metadata.load); - } - } - }, - load: function() { - var index; - $.rmClass(this.parentNode, 'error'); - $.addClass(this.parentNode, 'loading'); - index = this.parentNode.dataset.index; - return CrossOrigin.binary(Get.postFromNode(this).files[+index].url, (function(_this) { - return function(data) { - var output, title; - $.rmClass(_this.parentNode, 'loading'); - if (data != null) { - title = Metadata.parse(data); - output = $.el('span', { - textContent: title || '' - }); - if (title == null) { - $.addClass(_this.parentNode, 'not-found'); - } - $.before(_this, output); - _this.parentNode.tabIndex = 0; - if (d.activeElement === _this) { - _this.parentNode.focus(); - } - return _this.tabIndex = -1; - } else { - $.addClass(_this.parentNode, 'error'); - return $.one(_this, 'click', Metadata.load); - } - }; - })(this), { - Range: 'bytes=0-9999' - }); - }, - parse: function(data) { - var element, i, readInt, size, title; - readInt = function() { - var len, n; - n = data[i++]; - len = 0; - while (n < (0x80 >> len)) { - len++; - } - n ^= 0x80 >> len; - while (len-- && i < data.length) { - n = (n << 8) ^ data[i++]; - } - return n; - }; - i = 0; - while (i < data.length) { - element = readInt(); - size = readInt(); - if (element === 0x3BA9) { - title = ''; - while (size-- && i < data.length) { - title += String.fromCharCode(data[i++]); - } - return decodeURIComponent(escape(title)); - } else if (element !== 0x8538067 && element !== 0x549A966) { - i += size; - } - } - return null; - } - }; - - return Metadata; - -}).call(this); - -RevealSpoilers = (function() { - var RevealSpoilers; - - RevealSpoilers = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Reveal Spoiler Thumbnails'])) { - return; - } - return Callbacks.Post.push({ - name: 'Reveal Spoiler Thumbnails', - cb: this.node - }); - }, - node: function() { - var file, i, len, ref, thumb; - if (this.isClone) { - return; - } - ref = this.files; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if (!(file.thumb && file.isSpoiler)) { - continue; - } - thumb = file.thumb; - thumb.removeAttribute('style'); - thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; - if (thumb.src) { - thumb.src = file.thumbURL; - } else { - thumb.dataset.src = file.thumbURL; - } - } - } - }; - - return RevealSpoilers; - -}).call(this); - -Sauce = (function() { - var Sauce, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Sauce = { - init: function() { - var j, len, link, linkData, links, ref, ref1; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Sauce'])) { - return; - } - $.addClass(doc, 'show-sauce'); - links = []; - ref1 = Conf['sauces'].split('\n'); - for (j = 0, len = ref1.length; j < len; j++) { - link = ref1[j]; - if (link[0] !== '#' && (linkData = this.parseLink(link))) { - links.push(linkData); - } - } - if (!links.length) { - return; - } - this.links = links; - this.link = $.el('a', { - target: '_blank', - className: 'sauce' - }); - return Callbacks.Post.push({ - name: 'Sauce', - cb: this.node - }); - }, - parseLink: function(link) { - var err, i, j, len, m, part, parts, ref, ref1, regexp; - if (!(link = link.trim())) { - return null; - } - parts = $.dict(); - ref = link.split(/;(?=(?:text|boards|types|regexp|sandbox):?)/); - for (i = j = 0, len = ref.length; j < len; i = ++j) { - part = ref[i]; - if (i === 0) { - parts['url'] = part; - } else { - m = part.match(/^(\w*):?(.*)$/); - parts[m[1]] = m[2]; - } - } - parts['text'] || (parts['text'] = ((ref1 = parts['url'].match(/(\w+)\.\w+\//)) != null ? ref1[1] : void 0) || '?'); - if ('boards' in parts) { - parts['boards'] = Filter.parseBoards(parts['boards']); - } - if ('regexp' in parts) { - try { - if ((regexp = parts['regexp'].match(/^\/(.*)\/(\w*)$/))) { - parts['regexp'] = RegExp(regexp[1], regexp[2]); - } else { - parts['regexp'] = RegExp(parts['regexp']); - } - } catch (error) { - err = error; - new Notice('warning', [$.tn("Invalid regexp for Sauce link:"), $.el('br'), $.tn(link), $.el('br'), $.tn(err.message)], 60); - return null; - } - } - return parts; - }, - createSauceLink: function(link, post, file) { - var a, base, ext, j, key, len, matches, missing, parts, ref; - ext = file.url.match(/[^.]*$/)[0]; - parts = $.dict(); - $.extend(parts, link); - if (!(!parts['boards'] || parts['boards'][post.siteID + "/" + post.boardID] || parts['boards'][post.siteID + "/*"])) { - return null; - } - if (!(!parts['types'] || indexOf.call(parts['types'].split(','), ext) >= 0)) { - return null; - } - if (!(!parts['regexp'] || (matches = file.name.match(parts['regexp'])))) { - return null; - } - missing = []; - ref = ['url', 'text']; - for (j = 0, len = ref.length; j < len; j++) { - key = ref[j]; - parts[key] = parts[key].replace(/%(T?URL|IMG|[sh]?MD5|board|name|%|semi|\$\d+)/g, function(orig, parameter) { - var type; - if (parameter[0] === '$') { - if (!matches) { - return orig; - } - type = matches[parameter.slice(1)] || ''; - } else { - type = Sauce.formatters[parameter](post, file, ext); - if (type == null) { - missing.push(parameter); - return ''; - } - } - if (key === 'url' && (parameter !== '%' && parameter !== 'semi')) { - if (/^javascript:/i.test(parts['url'])) { - type = JSON.stringify(type); - } - type = encodeURIComponent(type); - } - return type; - }); - } - if ((typeof (base = g.SITE).areMD5sDeferred === "function" ? base.areMD5sDeferred(post.board) : void 0) && missing.length && !missing.filter(function(x) { - return !/^.?MD5$/.test(x); - }).length) { - a = Sauce.link.cloneNode(false); - a.dataset.skip = '1'; - return a; - } - if (missing.length) { - return null; - } - a = Sauce.link.cloneNode(false); - a.href = parts['url']; - a.textContent = parts['text']; - if (/^javascript:/i.test(parts['url'])) { - a.removeAttribute('target'); - } - return a; - }, - node: function() { - var file, j, len, ref; - if (this.isClone) { - return; - } - ref = this.files; - for (j = 0, len = ref.length; j < len; j++) { - file = ref[j]; - Sauce.file(this, file); - } - }, - file: function(post, file) { - var j, len, link, node, nodes, observer, ref, skipped; - nodes = []; - skipped = []; - ref = Sauce.links; - for (j = 0, len = ref.length; j < len; j++) { - link = ref[j]; - if ((node = Sauce.createSauceLink(link, post, file))) { - nodes.push($.tn(' '), node); - if (node.dataset.skip) { - skipped.push([link, node]); - } - } - } - $.add(file.text, nodes); - if (skipped.length) { - observer = new MutationObserver(function() { - var k, len1, node2, ref1; - if (file.text.dataset.md5) { - for (k = 0, len1 = skipped.length; k < len1; k++) { - ref1 = skipped[k], link = ref1[0], node = ref1[1]; - if ((node2 = Sauce.createSauceLink(link, post, file))) { - $.replace(node, node2); - } - } - return observer.disconnect(); - } - }); - return observer.observe(file.text, { - attributes: true - }); - } - }, - formatters: { - TURL: function(post, file) { - return file.thumbURL; - }, - URL: function(post, file) { - return file.url; - }, - IMG: function(post, file, ext) { - if (ext === 'gif' || ext === 'jpg' || ext === 'jpeg' || ext === 'png') { - return file.url; - } else { - return file.thumbURL; - } - }, - MD5: function(post, file) { - return file.MD5; - }, - sMD5: function(post, file) { - var ref; - return (ref = file.MD5) != null ? ref.replace(/[+\/=]/g, function(c) { - return { - '+': '-', - '/': '_', - '=': '' - }[c]; - }) : void 0; - }, - hMD5: function(post, file) { - var c; - if (file.MD5) { - return ((function() { - var j, len, ref, results; - ref = atob(file.MD5); - results = []; - for (j = 0, len = ref.length; j < len; j++) { - c = ref[j]; - results.push(("0" + (c.charCodeAt(0).toString(16))).slice(-2)); - } - return results; - })()).join(''); - } - }, - board: function(post) { - return post.board.ID; - }, - name: function(post, file) { - return file.name; - }, - '%': function() { - return '%'; - }, - semi: function() { - return ';'; - } - } - }; - - return Sauce; - -}).call(this); - -Volume = (function() { - var Volume; - - Volume = { - init: function() { - var base, ref, unmuteEntry, volumeEntry; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && (Conf['Image Expansion'] || Conf['Image Hover'] || Conf['Image Hover in Catalog'] || Conf['Gallery']))) { - return; - } - $.sync('Allow Sound', function(x) { - var ref1; - Conf['Allow Sound'] = x; - return (ref1 = Volume.inputs) != null ? ref1.unmute.checked = x : void 0; - }); - $.sync('Default Volume', function(x) { - var ref1; - Conf['Default Volume'] = x; - return (ref1 = Volume.inputs) != null ? ref1.volume.value = x : void 0; - }); - if (Conf['Mouse Wheel Volume']) { - Callbacks.Post.push({ - name: 'Mouse Wheel Volume', - cb: this.node - }); - } - if (typeof (base = g.SITE).noAudio === "function" ? base.noAudio(g.BOARD) : void 0) { - return; - } - if (Conf['Mouse Wheel Volume']) { - Callbacks.CatalogThread.push({ - name: 'Mouse Wheel Volume', - cb: this.catalogNode - }); - } - unmuteEntry = UI.checkbox('Allow Sound', 'Allow Sound'); - unmuteEntry.title = Config.main['Images and Videos']['Allow Sound'][1]; - volumeEntry = $.el('label', { - title: 'Default volume for videos.' - }); - $.extend(volumeEntry, {innerHTML: " Volume"}); - this.inputs = { - unmute: unmuteEntry.firstElementChild, - volume: volumeEntry.firstElementChild - }; - $.on(this.inputs.unmute, 'change', $.cb.checked); - $.on(this.inputs.volume, 'change', $.cb.value); - Header.menu.addEntry({ - el: unmuteEntry, - order: 200 - }); - return Header.menu.addEntry({ - el: volumeEntry, - order: 201 - }); - }, - setup: function(video) { - video.muted = !Conf['Allow Sound']; - video.volume = Conf['Default Volume']; - return $.on(video, 'volumechange', Volume.change); - }, - change: function() { - var items, key, muted, ref, val, volume; - ref = this, muted = ref.muted, volume = ref.volume; - items = { - 'Allow Sound': !muted, - 'Default Volume': volume - }; - for (key in items) { - val = items[key]; - if (Conf[key] === val) { - delete items[key]; - } - } - $.set(items); - $.extend(Conf, items); - if (Volume.inputs) { - Volume.inputs.unmute.checked = !muted; - return Volume.inputs.volume.value = volume; - } - }, - node: function() { - var base, file, i, len, ref; - if (typeof (base = g.SITE).noAudio === "function" ? base.noAudio(this.board) : void 0) { - return; - } - ref = this.files; - for (i = 0, len = ref.length; i < len; i++) { - file = ref[i]; - if (!file.isVideo) { - continue; - } - if (file.thumb) { - $.on(file.thumb, 'wheel', Volume.wheel.bind(Header.hover)); - } - $.on($('.file-info', file.text) || file.link, 'wheel', Volume.wheel.bind(file.thumbLink)); - } - }, - catalogNode: function() { - var file; - file = this.thread.OP.files[0]; - if (!(file != null ? file.isVideo : void 0)) { - return; - } - return $.on(this.nodes.thumb, 'wheel', Volume.wheel.bind(Header.hover)); - }, - wheel: function(e) { - var el, volume; - if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { - return; - } - if (!(el = $('video:not([data-md5])', this))) { - return; - } - if (el.muted || !$.hasAudio(el)) { - return; - } - volume = el.volume + 0.1; - if (e.deltaY < 0) { - volume *= 1.1; - } - if (e.deltaY > 0) { - volume /= 1.1; - } - el.volume = $.minmax(volume - 0.1, 0, 1); - return e.preventDefault(); - } - }; - - return Volume; - -}).call(this); - -Embedding = (function() { - var Embedding, - slice = [].slice; - - Embedding = { - init: function() { - var j, len, ref, ref1, type; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Linkify'] && (Conf['Embedding'] || Conf['Link Title'] || Conf['Cover Preview']))) { - return; - } - this.types = $.dict(); - ref1 = this.ordered_types; - for (j = 0, len = ref1.length; j < len; j++) { - type = ref1[j]; - this.types[type.key] = type; - } - if (Conf['Embedding'] && g.VIEW !== 'archive') { - this.dialog = UI.dialog('embedding', {innerHTML: "
        "}); - this.media = $('#media-embed', this.dialog); - $.one(d, '4chanXInitFinished', this.ready); - $.on(d, 'IndexRefreshInternal', function() { - return g.posts.forEach(function(post) { - var embed, k, l, len1, len2, ref2, ref3; - ref2 = [post].concat(slice.call(post.clones)); - for (k = 0, len1 = ref2.length; k < len1; k++) { - post = ref2[k]; - ref3 = post.nodes.embedlinks; - for (l = 0, len2 = ref3.length; l < len2; l++) { - embed = ref3[l]; - Embedding.cb.catalogRemove.call(embed); - } - } - }); - }); - } - if (Conf['Link Title']) { - return $.on(d, '4chanXInitFinished PostsInserted', function() { - var key, ref2, ref3, service; - ref2 = Embedding.types; - for (key in ref2) { - service = ref2[key]; - if ((ref3 = service.title) != null ? ref3.batchSize : void 0) { - Embedding.flushTitles(service.title); - } - } - }); - } - }, - events: function(post) { - var data, el, i, items; - if (g.VIEW === 'archive') { - return; - } - if (Conf['Embedding']) { - i = 0; - items = post.nodes.embedlinks = $$('.embedder', post.nodes.comment); - while (el = items[i++]) { - $.on(el, 'click', Embedding.cb.click); - if ($.hasClass(el, 'embedded')) { - Embedding.cb.toggle.call(el); - } - } - } - if (Conf['Cover Preview']) { - i = 0; - items = $$('.linkify', post.nodes.comment); - while (el = items[i++]) { - if ((data = Embedding.services(el))) { - Embedding.preview(data); - } - } - } - }, - process: function(link, post) { - var data; - if (!(Conf['Embedding'] || Conf['Link Title'] || Conf['Cover Preview'])) { - return; - } - if ($.x('ancestor::pre', link)) { - return; - } - if (data = Embedding.services(link)) { - data.post = post; - if (Conf['Embedding'] && g.VIEW !== 'archive') { - Embedding.embed(data); - } - if (Conf['Link Title']) { - Embedding.title(data); - } - if (Conf['Cover Preview'] && g.VIEW !== 'archive') { - return Embedding.preview(data); - } - } - }, - services: function(link) { - var href, j, len, match, ref, type; - href = link.href; - ref = Embedding.ordered_types; - for (j = 0, len = ref.length; j < len; j++) { - type = ref[j]; - if ((match = type.regExp.exec(href))) { - return { - key: type.key, - uid: match[1], - options: match[2], - link: link - }; - } - } - }, - embed: function(data) { - var embed, href, key, link, name, options, post, ref, uid, value; - key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; - href = link.href; - $.addClass(link, key.toLowerCase()); - embed = $.el('a', { - className: 'embedder', - href: 'javascript:;' - }, {innerHTML: "(unembed)"}); - ref = { - key: key, - uid: uid, - options: options, - href: href - }; - for (name in ref) { - value = ref[name]; - embed.dataset[name] = value; - } - $.on(embed, 'click', Embedding.cb.click); - $.after(link, [$.tn(' '), embed]); - post.nodes.embedlinks.push(embed); - if (Conf['Auto-embed'] && !Conf['Floating Embeds'] && !post.isFetchedQuote) { - if ($.hasClass(doc, 'catalog-mode')) { - return $.addClass(embed, 'embed-removed'); - } else { - return Embedding.cb.toggle.call(embed); - } - } - }, - ready: function() { - if (!Main.isThisPageLegit()) { - return; - } - $.addClass(Embedding.dialog, 'empty'); - $.on($('.close', Embedding.dialog), 'click', Embedding.closeFloat); - $.on($('.move', Embedding.dialog), 'mousedown', Embedding.dragEmbed); - $.on($('.jump', Embedding.dialog), 'click', function() { - if (doc.contains(Embedding.lastEmbed)) { - return Header.scrollTo(Embedding.lastEmbed); - } - }); - return $.add(d.body, Embedding.dialog); - }, - closeFloat: function() { - delete Embedding.lastEmbed; - $.addClass(Embedding.dialog, 'empty'); - return $.replace(Embedding.media.firstChild, $.el('div')); - }, - dragEmbed: function() { - var style; - style = Embedding.media.style; - if (Embedding.dragEmbed.mouseup) { - $.off(d, 'mouseup', Embedding.dragEmbed); - Embedding.dragEmbed.mouseup = false; - style.pointerEvents = ''; - return; - } - $.on(d, 'mouseup', Embedding.dragEmbed); - Embedding.dragEmbed.mouseup = true; - return style.pointerEvents = 'none'; - }, - title: function(data) { - var key, link, options, post, service, uid; - key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; - if (!(service = Embedding.types[key].title)) { - return; - } - $.addClass(link, key.toLowerCase()); - if (service.batchSize) { - (service.queue || (service.queue = [])).push(data); - if (service.queue.length >= service.batchSize) { - return Embedding.flushTitles(service); - } - } else { - return CrossOrigin.cache(service.api(uid), (function() { - return Embedding.cb.title(this, data); - })); - } - }, - flushTitles: function(service) { - var cb, data, queue; - queue = service.queue; - if (!(queue != null ? queue.length : void 0)) { - return; - } - service.queue = []; - cb = function() { - var data, j, len; - for (j = 0, len = queue.length; j < len; j++) { - data = queue[j]; - Embedding.cb.title(this, data); - } - }; - return CrossOrigin.cache(service.api((function() { - var j, len, results; - results = []; - for (j = 0, len = queue.length; j < len; j++) { - data = queue[j]; - results.push(data.uid); - } - return results; - })()), cb); - }, - preview: function(data) { - var key, link, service, uid; - key = data.key, uid = data.uid, link = data.link; - if (!(service = Embedding.types[key].preview)) { - return; - } - return $.on(link, 'mouseover', function(e) { - var el, height, src; - src = service.url(uid); - height = service.height; - el = $.el('img', { - src: src, - id: 'ihover' - }); - $.add(Header.hover, el); - return UI.hover({ - root: link, - el: el, - latestEvent: e, - endEvents: 'mouseout click', - height: height - }); - }); - }, - cb: { - click: function(e) { - var div; - e.preventDefault(); - if (!$.hasClass(this, 'embedded') && (Conf['Floating Embeds'] || $.hasClass(doc, 'catalog-mode'))) { - if (!(div = Embedding.media.firstChild)) { - return; - } - $.replace(div, Embedding.cb.embed(this)); - Embedding.lastEmbed = Get.postFromNode(this).nodes.root; - return $.rmClass(Embedding.dialog, 'empty'); - } else { - return Embedding.cb.toggle.call(this); - } - }, - toggle: function() { - if ($.hasClass(this, "embedded")) { - $.rm(this.nextElementSibling); - } else { - $.after(this, Embedding.cb.embed(this)); - } - return $.toggleClass(this, 'embedded'); - }, - embed: function(a) { - var container, el, type; - container = $.el('div', { - className: 'media-embed' - }); - $.add(container, el = (type = Embedding.types[a.dataset.key]).el(a)); - el.style.cssText = type.style != null ? type.style : 'border: none; width: 640px; height: 360px;'; - return container; - }, - catalogRemove: function() { - var isCatalog; - isCatalog = $.hasClass(doc, 'catalog-mode'); - if ((isCatalog && $.hasClass(this, 'embedded')) || (!isCatalog && $.hasClass(this, 'embed-removed'))) { - Embedding.cb.toggle.call(this); - return $.toggleClass(this, 'embed-removed'); - } - }, - title: function(req, data) { - var base1, j, k, key, len, len1, link, link2, options, post, post2, ref, ref1, service, status, text, uid; - key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post; - service = Embedding.types[key].title; - status = req.status; - if ((status === 200 || status === 304) && service.status) { - status = service.status(req.response)[0]; - } - if (!status) { - return; - } - text = "[" + key + "] " + ((function() { - switch (status) { - case 200: - case 304: - text = service.text(req.response, uid); - if (typeof text === 'string') { - return text; - } else { - return text = link.textContent; - } - break; - case 404: - return "Not Found"; - case 403: - case 401: - return "Forbidden or Private"; - default: - return status + "'d"; - } - })()); - link.dataset.original = link.textContent; - link.textContent = text; - ref = post.clones; - for (j = 0, len = ref.length; j < len; j++) { - post2 = ref[j]; - ref1 = $$('a.linkify', post2.nodes.comment); - for (k = 0, len1 = ref1.length; k < len1; k++) { - link2 = ref1[k]; - if (!(link2.href === link.href)) { - continue; - } - if ((base1 = link2.dataset).original == null) { - base1.original = link2.textContent; - } - link2.textContent = text; - } - } - } - }, - ordered_types: [ - { - key: 'audio', - regExp: /^[^?#]+\.(?:mp3|m4a|oga|wav|flac)(?:[?#]|$)/i, - style: '', - el: function(a) { - return $.el('audio', { - controls: true, - preload: 'auto', - src: a.dataset.href - }); - } - }, { - key: 'image', - regExp: /^[^?#]+\.(?:gif|png|jpg|jpeg|bmp|webp)(?::\w+)?(?:[?#]|$)/i, - style: '', - el: function(a) { - return $.el('div', {innerHTML: ""}); - } - }, { - key: 'video', - regExp: /^[^?#]+\.(?:og[gv]|webm|mp4)(?:[?#]|$)/i, - style: 'max-width: 80vw; max-height: 80vh;', - el: function(a) { - var el; - el = $.el('video', { - hidden: true, - controls: true, - preload: 'auto', - src: a.dataset.href, - loop: ImageHost.test(a.dataset.href.split('/')[2]) - }); - $.on(el, 'loadedmetadata', function() { - if (el.videoHeight === 0 && el.parentNode) { - return $.replace(el, Embedding.types.audio.el(a)); - } else { - return el.hidden = false; - } - }); - return el; - } - }, { - key: 'PeerTube', - regExp: /^(\w+:\/\/[^\/]+\/videos\/watch\/\w{8}-\w{4}-\w{4}-\w{4}-\w{12})(.*)/, - el: function(a) { - var el, options, start; - options = (start = a.dataset.options.match(/[?&](start=\w+)/)) ? "?" + start[1] : ''; - el = $.el('iframe', { - src: a.dataset.uid.replace('/videos/watch/', '/videos/embed/') + options - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'BitChute', - regExp: /^\w+:\/\/(?:www\.)?bitchute\.com\/video\/([\w\-]+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://www.bitchute.com/embed/" + a.dataset.uid + "/" - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Clyp', - regExp: /^\w+:\/\/(?:www\.)?clyp\.it\/(\w{8})/, - style: 'border: 0; width: 640px; height: 160px;', - el: function(a) { - return $.el('iframe', { - src: "https://clyp.it/" + a.dataset.uid + "/widget" - }); - }, - title: { - api: function(uid) { - return "https://api.clyp.it/oembed?url=https://clyp.it/" + uid; - }, - text: function(_) { - return _.title; - } - } - }, { - key: 'Dailymotion', - regExp: /^\w+:\/\/(?:(?:www\.)?dailymotion\.com\/(?:embed\/)?video|dai\.ly)\/([A-Za-z0-9]+)[^?]*(.*)/, - el: function(a) { - var el, options, start; - options = (start = a.dataset.options.match(/[?&](start=\d+)/)) ? "?" + start[1] : ''; - el = $.el('iframe', { - src: "//www.dailymotion.com/embed/video/" + a.dataset.uid + options - }); - el.setAttribute("allowfullscreen", "true"); - return el; - }, - title: { - api: function(uid) { - return "https://api.dailymotion.com/video/" + uid; - }, - text: function(_) { - return _.title; - } - }, - preview: { - url: function(uid) { - return "https://www.dailymotion.com/thumbnail/video/" + uid; - }, - height: 240 - } - }, { - key: 'Gfycat', - regExp: /^\w+:\/\/(?:www\.)?gfycat\.com\/(?:iframe\/)?(\w+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "//gfycat.com/ifr/" + a.dataset.uid - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Gist', - regExp: /^\w+:\/\/gist\.github\.com\/[\w\-]+\/(\w+)/, - style: '', - el: (function() { - var counter; - counter = 0; - return function(a) { - var el; - el = $.el('pre', { - hidden: true, - id: "gist-embed-" + (counter++) - }); - CrossOrigin.cache("https://api.github.com/gists/" + a.dataset.uid, function() { - el.textContent = Object.values(this.response.files)[0].content; - el.className = 'prettyprint'; - $.global(function() { - return typeof window.prettyPrint === "function" ? window.prettyPrint((function() {}), document.getElementById(document.currentScript.dataset.id).parentNode) : void 0; - }, { - id: el.id - }); - return el.hidden = false; - }); - return el; - }; - })(), - title: { - api: function(uid) { - return "https://api.github.com/gists/" + uid; - }, - text: function(arg) { - var file, files; - files = arg.files; - for (file in files) { - if (files.hasOwnProperty(file)) { - return file; - } - } - } - } - }, { - key: 'InstallGentoo', - regExp: /^\w+:\/\/paste\.installgentoo\.com\/view\/(?:raw\/|download\/|embed\/)?(\w+)/, - el: function(a) { - return $.el('iframe', { - src: "https://paste.installgentoo.com/view/embed/" + a.dataset.uid - }); - } - }, { - key: 'LiveLeak', - regExp: /^\w+:\/\/(?:\w+\.)?liveleak\.com\/.*\?.*[tif]=(\w+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://www.liveleak.com/e/" + a.dataset.uid - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - 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: function(a) { - var _, base, el, host, j, k, l, len, len1, len2, name, names, ref, ref1, type, types, url, urls; - el = $.el('video', { - controls: true, - preload: 'auto', - loop: true - }); - if (/^http/.test(a.dataset.uid)) { - $.add(el, $.el('source', { - src: a.dataset.uid - })); - return el; - } - ref = a.dataset.uid.match(/(\w+)\/(.*)/), _ = ref[0], host = ref[1], names = ref[2]; - types = (function() { - switch (host) { - case 'gd': - case 'wu': - case 'fc': - return ['']; - case 'gc': - return ['giant', 'fat', 'zippy']; - default: - return ['.webm', '.mp4']; - } - })(); - ref1 = names.split(','); - for (j = 0, len = ref1.length; j < len; j++) { - name = ref1[j]; - for (k = 0, len1 = types.length; k < len1; k++) { - type = types[k]; - base = "" + name + type; - urls = (function() { - switch (host) { - case 'pf': - return ["https://kastden.org/_loopvid_media/pf/" + base, "https://web.archive.org/web/2/http://a.pomf.se/" + base]; - case 'kd': - return ["https://kastden.org/loopvid/" + base]; - case 'lv': - return ["https://lv.kastden.org/" + base]; - case 'gd': - return ["https://docs.google.com/uc?export=download&id=" + base]; - case 'gh': - return ["https://googledrive.com/host/" + base]; - case 'db': - return ["https://dl.dropboxusercontent.com/u/" + base]; - case 'dx': - return ["https://dl.dropboxusercontent.com/" + base]; - case 'nn': - return ["https://kastden.org/_loopvid_media/nn/" + base]; - case 'cp': - return ["https://copy.com/" + base]; - case 'wu': - return ["http://webmup.com/" + base + "/vid.webm"]; - case 'ig': - return ["https://i.imgur.com/" + base]; - case 'ky': - return ["https://kastden.org/_loopvid_media/ky/" + base]; - case 'mf': - return ["https://kastden.org/_loopvid_media/mf/" + base, "https://web.archive.org/web/2/https://d.maxfile.ro/" + base]; - case 'm2': - return ["https://kastden.org/_loopvid_media/m2/" + base]; - case 'pc': - return ["https://kastden.org/_loopvid_media/pc/" + base, "https://web.archive.org/web/2/http://a.pomf.cat/" + base]; - case '1c': - return ["http://b.1339.cf/" + base]; - case 'pi': - return ["https://kastden.org/_loopvid_media/pi/" + base, "https://web.archive.org/web/2/https://u.pomf.is/" + base]; - case 'ni': - return ["https://kastden.org/_loopvid_media/ni/" + base, "https://web.archive.org/web/2/https://u.nya.is/" + base]; - case 'wl': - return ["http://webm.land/media/" + base]; - case 'ko': - return ["https://kordy.kastden.org/loopvid/" + base]; - case 'mm': - return ["https://kastden.org/_loopvid_media/mm/" + base, "https://web.archive.org/web/2/https://my.mixtape.moe/" + base]; - case 'ic': - return ["https://media.8ch.net/file_store/" + base]; - case 'fc': - return ["//" + (ImageHost.host()) + "/" + base + ".webm"]; - case 'gc': - return ["https://" + type + ".gfycat.com/" + name + ".webm"]; - } - })(); - for (l = 0, len2 = urls.length; l < len2; l++) { - url = urls[l]; - $.add(el, $.el('source', { - src: url - })); - } - } - } - return el; - } - }, { - key: 'Openings.moe', - regExp: /^\w+:\/\/openings.moe\/\?video=([^.&=]+)/, - style: 'width: 1280px; height: 720px; max-width: 80vw; max-height: 80vh;', - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://openings.moe/?video=" + a.dataset.uid - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Pastebin', - regExp: /^\w+:\/\/(?:\w+\.)?pastebin\.com\/(?!u\/)(?:[\w.]+(?:\/|\?i\=))?(\w+)/, - el: function(a) { - var div; - return div = $.el('iframe', { - src: "//pastebin.com/embed_iframe.php?i=" + a.dataset.uid - }); - } - }, { - key: 'SoundCloud', - regExp: /^\w+:\/\/(?:www\.)?(?:soundcloud\.com\/|snd\.sc\/)([\w\-\/]+)/, - style: 'border: 0; width: 500px; height: 400px;', - el: function(a) { - return $.el('iframe', { - src: "https://w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F" + (encodeURIComponent(a.dataset.uid)) - }); - }, - title: { - api: function(uid) { - return location.protocol + "//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F" + (encodeURIComponent(uid)); - }, - text: function(_) { - return _.title; - } - } - }, { - key: 'StrawPoll', - regExp: /^\w+:\/\/(?:www\.)?strawpoll\.me\/(?:embed_\d+\/)?(\d+(?:\/r)?)/, - style: 'border: 0; width: 600px; height: 406px;', - el: function(a) { - return $.el('iframe', { - src: "https://www.strawpoll.me/embed_1/" + a.dataset.uid - }); - } - }, { - key: 'Streamable', - regExp: /^\w+:\/\/(?:www\.)?streamable\.com\/(\w+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://streamable.com/o/" + a.dataset.uid - }); - el.setAttribute("allowfullscreen", "true"); - return el; - }, - title: { - api: function(uid) { - return "https://api.streamable.com/oembed?url=https://streamable.com/" + uid; - }, - text: function(_) { - return _.title; - } - } - }, { - key: 'TwitchTV', - regExp: /^\w+:\/\/(?:www\.|secure\.|clips\.|m\.)?twitch\.tv\/(\w[^#\&\?]*)/, - el: function(a) { - var el, m, time, url; - m = a.dataset.href.match(/^\w+:\/\/(?:(clips\.)|\w+\.)?twitch\.tv\/(?:\w+\/)?(clip\/)?(\w[^#\&\?]*)/); - if (m[1] || m[2]) { - url = "//clips.twitch.tv/embed?clip=" + m[3] + "&parent=" + location.hostname; - } else { - m = a.dataset.uid.match(/(\w+)(?:\/(?:v\/)?(\d+))?/); - url = "//player.twitch.tv/?" + (m[2] ? "video=v" + m[2] : "channel=" + m[1]) + "&autoplay=false&parent=" + location.hostname; - if ((time = a.dataset.href.match(/\bt=(\w+)/))) { - url += "&time=" + time[1]; - } - } - el = $.el('iframe', { - src: url - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Twitter', - regExp: /^\w+:\/\/(?:www\.|mobile\.)?twitter\.com\/(\w+\/status\/\d+)/, - style: 'border: none; width: 550px; height: 250px; overflow: hidden; resize: both;', - el: function(a) { - var cont, el, onMessage; - el = $.el('iframe'); - $.on(el, 'load', function() { - return this.contentWindow.postMessage({ - element: 't', - query: 'height' - }, 'https://twitframe.com'); - }); - onMessage = function(e) { - if (e.source === el.contentWindow && e.origin === 'https://twitframe.com') { - $.off(window, 'message', onMessage); - return (cont || el).style.height = (+$.minmax(e.data.height, 250, 0.8 * doc.clientHeight)) + "px"; - } - }; - $.on(window, 'message', onMessage); - el.src = "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid; - if ($.engine === 'gecko') { - el.style.cssText = 'border: none; width: 100%; height: 100%;'; - cont = $.el('div'); - $.add(cont, el); - return cont; - } else { - return el; - } - } - }, { - key: 'VidLii', - regExp: /^\w+:\/\/(?:www\.)?vidlii\.com\/watch\?v=(\w{11})/, - style: 'border: none; width: 640px; height: 392px;', - el: function(a) { - var el; - el = $.el('iframe', { - src: "https://www.vidlii.com/embed?v=" + a.dataset.uid + "&a=0" - }); - el.setAttribute("allowfullscreen", "true"); - return el; - } - }, { - key: 'Vimeo', - regExp: /^\w+:\/\/(?:www\.)?vimeo\.com\/(\d+)/, - el: function(a) { - var el; - el = $.el('iframe', { - src: "//player.vimeo.com/video/" + a.dataset.uid + "?wmode=opaque" - }); - el.setAttribute("allowfullscreen", "true"); - return el; - }, - title: { - api: function(uid) { - return "https://vimeo.com/api/oembed.json?url=https://vimeo.com/" + uid; - }, - text: function(_) { - return _.title; - } - } - }, { - key: 'Vine', - regExp: /^\w+:\/\/(?:www\.)?vine\.co\/v\/(\w+)/, - style: 'border: none; width: 500px; height: 500px;', - el: function(a) { - return $.el('iframe', { - src: "https://vine.co/v/" + a.dataset.uid + "/card" - }); - } - }, { - key: 'Vocaroo', - regExp: /^\w+:\/\/(?:(?:www\.|old\.)?vocaroo\.com|voca\.ro)\/((?:i\/)?\w+)/, - style: '', - el: function(a) { - var el; - el = $.el('iframe'); - el.width = 300; - el.height = 60; - el.setAttribute('frameborder', 0); - el.src = "https://vocaroo.com/embed/" + (a.dataset.uid.replace(/^i\//, '')) + "?autoplay=0"; - return el; - } - }, { - key: 'YouTube', - regExp: /^\w+:\/\/(?:youtu.be\/|[\w.]*youtube[\w.]*\/.*(?:v=|\bembed\/|\bv\/))([\w\-]{11})(.*)/, - el: function(a) { - var el, start; - start = a.dataset.options.match(/\b(?:star)?t\=(\w+)/); - if (start) { - start = start[1]; - } - if (start && !/^\d+$/.test(start)) { - start += ' 0h0m0s'; - start = 3600 * start.match(/(\d+)h/)[1] + 60 * start.match(/(\d+)m/)[1] + 1 * start.match(/(\d+)s/)[1]; - } - el = $.el('iframe', { - src: "//www.youtube.com/embed/" + a.dataset.uid + "?rel=0&wmode=opaque" + (start ? '&start=' + start : '') - }); - el.setAttribute("allowfullscreen", "true"); - return el; - }, - title: { - api: function(uid) { - return "https://www.youtube.com/oembed?url=https%3A//www.youtube.com/watch%3Fv%3D" + uid + "&format=json"; - }, - text: function(_) { - return _.title; - }, - status: function(_) { - var m; - if (_.error) { - m = _.error.match(/^(\d*)\s*(.*)/); - return [+m[1], m[2]]; - } else { - return [200, 'OK']; - } - } - }, - preview: { - url: function(uid) { - return "https://img.youtube.com/vi/" + uid + "/0.jpg"; - }, - height: 360 - } - } - ] - }; - - return Embedding; - -}).call(this); - -Linkify = (function() { - var Linkify; - - Linkify = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread' && ref !== 'archive') || !Conf['Linkify']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - Callbacks.Post.push({ - name: 'Linkify', - cb: this.node - }); - return Embedding.init(); - }, - node: function() { - var base, j, k, len, len1, link, links, ref; - if (this.isClone) { - return Embedding.events(this); - } - if (!Linkify.regString.test(this.info.comment)) { - return; - } - ref = $$('a', this.nodes.comment); - for (j = 0, len = ref.length; j < len; j++) { - link = ref[j]; - if (!(typeof (base = g.SITE).isLinkified === "function" ? base.isLinkified(link) : void 0)) { - continue; - } - $.addClass(link, 'linkify'); - if (ImageHost.useFaster) { - ImageHost.fixLinks([link]); - } - Embedding.process(link, this); - } - links = Linkify.process(this.nodes.comment); - if (ImageHost.useFaster) { - ImageHost.fixLinks(links); - } - for (k = 0, len1 = links.length; k < len1; k++) { - link = links[k]; - Embedding.process(link, this); - } - }, - process: function(node) { - var data, end, endNode, i, index, length, links, part1, part2, ref, ref1, result, saved, snapshot, space, test, word; - test = /[^\s"]+/g; - space = /[\s"]/; - snapshot = $.X('.//br|.//text()', node); - i = 0; - links = []; - while (node = snapshot.snapshotItem(i++)) { - data = node.data; - if (!data || node.parentElement.nodeName === "A") { - continue; - } - while (result = test.exec(data)) { - index = result.index; - endNode = node; - word = result[0]; - if ((length = index + word.length) === data.length) { - test.lastIndex = 0; - while ((saved = snapshot.snapshotItem(i++))) { - if (saved.nodeName === 'BR' || (saved.parentElement.nodeName === 'P' && !saved.previousSibling)) { - if ((part1 = word.match(/(https?:\/\/)?([a-z\d-]+\.)*[a-z\d-]+$/i)) && (part2 = (ref = snapshot.snapshotItem(i)) != null ? (ref1 = ref.data) != null ? ref1.match(/^(\.[a-z\d-]+)*\//i) : void 0 : void 0) && (part1[0] + part2[0]).search(Linkify.regString) === 0) { - continue; - } else { - break; - } - } - if (saved.parentElement.nodeName === "A" && !Linkify.regString.test(word)) { - break; - } - endNode = saved; - data = saved.data; - if (end = space.exec(data)) { - word += data.slice(0, end.index); - test.lastIndex = length = end.index; - i--; - break; - } else { - length = data.length; - word += data; - } - } - } - if (Linkify.regString.test(word)) { - links.push(Linkify.makeRange(node, endNode, index, length)); - } - if (!(test.lastIndex && node === endNode)) { - break; - } - } - } - i = links.length; - while (i--) { - links[i] = Linkify.makeLink(links[i]); - } - return links; - }, - regString: /((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: function(startNode, endNode, startOffset, endOffset) { - var range; - range = document.createRange(); - range.setStart(startNode, startOffset); - range.setEnd(endNode, endOffset); - return range; - }, - makeLink: function(range) { - var a, encodedDomain, i, t, text; - text = range.toString(); - i = text.search(Linkify.regString); - if (i > 0) { - text = text.slice(i); - while (range.startOffset + i >= range.startContainer.data.length) { - i--; - } - if (i) { - range.setStart(range.startContainer, range.startOffset + i); - } - } - i = 0; - while (/[)\]}>.,]/.test(t = text.charAt(text.length - (1 + i)))) { - if (!(/[.,]/.test(t) || (text.match(/[()\[\]{}<>]/g)).length % 2)) { - break; - } - i++; - } - if (i) { - text = text.slice(0, -i); - while (range.endOffset - i < 0) { - i--; - } - if (i) { - range.setEnd(range.endContainer, range.endOffset - i); - } - } - if (!/((mailto|magnet):|.+:\/\/)/.test(text)) { - text = (/@/.test(text) ? 'mailto:' : 'http://') + text; - } - if (encodedDomain = text.match(/^(https?:\/\/[^\/]*%[0-9a-f]{2})(.*)$/i)) { - text = encodedDomain[1].replace(/%([0-9a-f]{2})/ig, function(x, y) { - if (y === '25') { - return x; - } else { - return String.fromCharCode(parseInt(y, 16)); - } - }) + encodedDomain[2]; - } - a = $.el('a', { - className: 'linkify', - rel: 'noreferrer noopener', - target: '_blank', - href: text - }); - $.add(a, range.extractContents()); - range.insertNode(a); - return a; - } - }; - - return Linkify; - -}).call(this); - -ArchiveLink = (function() { - var ArchiveLink; - - ArchiveLink = { - init: function() { - var div, entry, i, len, ref, ref1, type; - if (!(g.SITE.software === 'yotsuba' && ((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Archive Link'])) { - return; - } - div = $.el('div', { - textContent: 'Archive' - }); - entry = { - el: div, - order: 60, - open: function(arg) { - var ID, board, thread; - ID = arg.ID, thread = arg.thread, board = arg.board; - return !!Redirect.to('thread', { - postID: ID, - threadID: thread.ID, - boardID: board.ID - }); - }, - subEntries: [] - }; - ref1 = [['Post', 'post'], ['Name', 'name'], ['Tripcode', 'tripcode'], ['Capcode', 'capcode'], ['Subject', 'subject'], ['Flag', 'country'], ['Filename', 'filename'], ['Image MD5', 'MD5']]; - for (i = 0, len = ref1.length; i < len; i++) { - type = ref1[i]; - entry.subEntries.push(this.createSubEntry(type[0], type[1])); - } - return Menu.menu.addEntry(entry); - }, - createSubEntry: function(text, type) { - var el, open; - el = $.el('a', { - textContent: text, - target: '_blank' - }); - open = type === 'post' ? function(arg) { - var ID, board, thread; - ID = arg.ID, thread = arg.thread, board = arg.board; - el.href = Redirect.to('thread', { - postID: ID, - threadID: thread.ID, - boardID: board.ID - }); - return true; - } : function(post) { - var ref, typeParam, value; - typeParam = type === 'country' && post.info.flagCodeTroll ? 'troll_country' : type; - value = type === 'country' ? post.info.flagCode || ((ref = post.info.flagCodeTroll) != null ? ref.toLowerCase() : void 0) : Filter.values(type, post)[0]; - if (!value) { - return false; - } - el.href = Redirect.to('search', { - boardID: post.board.ID, - type: typeParam, - value: value, - isSearch: true - }); - return true; - }; - return { - el: el, - open: open - }; - } - }; - - return ArchiveLink; - -}).call(this); - -CopyTextLink = (function() { - var CopyTextLink; - - CopyTextLink = { - init: function() { - var a, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Copy Text Link'])) { - return; - } - a = $.el('a', { - className: 'copy-text-link', - href: 'javascript:;', - textContent: 'Copy Text' - }); - $.on(a, 'click', CopyTextLink.copy); - return Menu.menu.addEntry({ - el: a, - order: 12, - open: function(post) { - CopyTextLink.text = (post.origin || post).commentOrig(); - return true; - } - }); - }, - copy: function() { - var el; - el = $.el('textarea', { - className: 'copy-text-element', - value: CopyTextLink.text - }); - $.add(d.body, el); - el.select(); - try { - d.execCommand('copy'); - } catch (error) {} - return $.rm(el); - } - }; - - return CopyTextLink; - -}).call(this); - -DeleteLink = (function() { - var DeleteLink; - - DeleteLink = { - auto: [$.dict(), $.dict()], - init: function() { - var div, fileEl, fileEntry, postEl, postEntry, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Delete Link'])) { - return; - } - div = $.el('div', { - className: 'delete-link', - textContent: 'Delete' - }); - postEl = $.el('a', { - className: 'delete-post', - href: 'javascript:;' - }); - fileEl = $.el('a', { - className: 'delete-file', - href: 'javascript:;' - }); - this.nodes = { - menu: div.firstChild, - links: [postEl, fileEl] - }; - postEntry = { - el: postEl, - open: function() { - postEl.textContent = DeleteLink.linkText(false); - $.on(postEl, 'click', DeleteLink.toggle); - return true; - } - }; - fileEntry = { - el: fileEl, - open: function(arg) { - var file; - file = arg.file; - if (!file || file.isDead) { - return false; - } - fileEl.textContent = DeleteLink.linkText(true); - $.on(fileEl, 'click', DeleteLink.toggle); - return true; - } - }; - return Menu.menu.addEntry({ - el: div, - order: 40, - open: function(post) { - if (post.isDead) { - return false; - } - DeleteLink.post = post; - DeleteLink.nodes.menu.textContent = DeleteLink.menuText(); - DeleteLink.cooldown.start(post); - return true; - }, - subEntries: [postEntry, fileEntry] - }); - }, - menuText: function() { - var seconds; - if (seconds = DeleteLink.cooldown.seconds[DeleteLink.post.fullID]) { - return "Delete (" + seconds + ")"; - } else { - return 'Delete'; - } - }, - linkText: function(fileOnly) { - var text; - text = fileOnly ? 'File' : 'Post'; - if (DeleteLink.auto[+fileOnly][DeleteLink.post.fullID]) { - text = "Deleting " + (text.toLowerCase()) + "..."; - } - return text; - }, - toggle: function() { - var auto, fileOnly, post; - post = DeleteLink.post; - fileOnly = $.hasClass(this, 'delete-file'); - auto = DeleteLink.auto[+fileOnly]; - if (auto[post.fullID]) { - delete auto[post.fullID]; - } else { - auto[post.fullID] = true; - } - this.textContent = DeleteLink.linkText(fileOnly); - if (!DeleteLink.cooldown.seconds[post.fullID]) { - return DeleteLink["delete"](post, fileOnly); - } - }, - "delete": function(post, fileOnly) { - var form, link; - link = DeleteLink.nodes.links[+fileOnly]; - delete DeleteLink.auto[+fileOnly][post.fullID]; - if (post.fullID === DeleteLink.post.fullID) { - $.off(link, 'click', DeleteLink.toggle); - } - form = { - mode: 'usrdel', - onlyimgdel: fileOnly, - pwd: QR.persona.getPassword() - }; - form[+post.ID] = 'delete'; - return $.ajax($.id('delform').action.replace("/" + g.BOARD + "/", "/" + post.board + "/"), { - responseType: 'document', - withCredentials: true, - onloadend: function() { - return DeleteLink.load(link, post, fileOnly, this.response); - }, - form: $.formData(form) - }); - }, - load: function(link, post, fileOnly, resDoc) { - var el, msg; - if (!resDoc) { - new Notice('warning', 'Connection error, please retry.', 20); - if (post.fullID === DeleteLink.post.fullID) { - $.on(link, 'click', DeleteLink.toggle); - } - return; - } - link.textContent = DeleteLink.linkText(fileOnly); - if (resDoc.title === '4chan - Banned') { - el = $.el('span', {innerHTML: "You can't delete posts because you are banned."}); - return new Notice('warning', el, 20); - } else if (msg = resDoc.getElementById('errmsg')) { - new Notice('warning', msg.textContent, 20); - if (post.fullID === DeleteLink.post.fullID) { - $.on(link, 'click', DeleteLink.toggle); - } - if (QR.cooldown.data && Conf['Cooldown'] && /\bwait\b/i.test(msg.textContent)) { - DeleteLink.cooldown.start(post, 5); - DeleteLink.auto[+fileOnly][post.fullID] = true; - return DeleteLink.nodes.links[+fileOnly].textContent = DeleteLink.linkText(fileOnly); - } - } else { - if (!fileOnly) { - QR.cooldown["delete"](post); - } - if (resDoc.title === 'Updating index...') { - (post.origin || post).kill(fileOnly); - } - if (post.fullID === DeleteLink.post.fullID) { - return link.textContent = 'Deleted'; - } - } - }, - cooldown: { - seconds: $.dict(), - start: function(post, seconds) { - if (DeleteLink.cooldown.seconds[post.fullID] != null) { - return; - } - if (seconds == null) { - seconds = QR.cooldown.secondsDeletion(post); - } - if (seconds > 0) { - DeleteLink.cooldown.seconds[post.fullID] = seconds; - return DeleteLink.cooldown.count(post); - } - }, - count: function(post) { - var fileOnly, i, len, ref; - if (post.fullID === DeleteLink.post.fullID) { - DeleteLink.nodes.menu.textContent = DeleteLink.menuText(); - } - if (DeleteLink.cooldown.seconds[post.fullID] > 0 && Conf['Cooldown']) { - DeleteLink.cooldown.seconds[post.fullID]--; - setTimeout(DeleteLink.cooldown.count, 1000, post); - } else { - delete DeleteLink.cooldown.seconds[post.fullID]; - ref = [false, true]; - for (i = 0, len = ref.length; i < len; i++) { - fileOnly = ref[i]; - if (DeleteLink.auto[+fileOnly][post.fullID]) { - DeleteLink["delete"](post, fileOnly); - } - } - } - } - } - }; - - return DeleteLink; - -}).call(this); - -DownloadLink = (function() { - var DownloadLink; - - DownloadLink = { - init: function() { - var a, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Download Link'])) { - return; - } - a = $.el('a', { - className: 'download-link', - textContent: 'Download file' - }); - $.on(a, 'click', ImageCommon.download); - return Menu.menu.addEntry({ - el: a, - order: 100, - open: function(arg) { - var file; - file = arg.file; - if (!file) { - return false; - } - a.href = file.url; - a.download = file.name; - return true; - } - }); - } - }; - - return DownloadLink; - -}).call(this); - -Menu = (function() { - var Menu; - - Menu = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'])) { - return; - } - this.button = $.el('a', { - className: 'menu-button', - href: 'javascript:;' - }); - $.extend(this.button, {innerHTML: ""}); - this.menu = new UI.Menu('post'); - Callbacks.Post.push({ - name: 'Menu', - cb: this.node - }); - return Callbacks.CatalogThread.push({ - name: 'Menu', - cb: this.catalogNode - }); - }, - node: function() { - var button; - if (this.isClone) { - button = $('.menu-button', this.nodes.info); - $.rmClass(button, 'active'); - $.rm($('.dialog', this.nodes.info)); - Menu.makeButton(this, button); - return; - } - return $.add(this.nodes.info, Menu.makeButton(this)); - }, - catalogNode: function() { - return $.after(this.nodes.icons, Menu.makeButton(this.thread.OP)); - }, - makeButton: function(post, button) { - button || (button = Menu.button.cloneNode(true)); - $.on(button, 'click', function(e) { - return Menu.menu.toggle(e, this, post); - }); - return button; - } - }; - - return Menu; - -}).call(this); - -ReportLink = (function() { - var ReportLink; - - ReportLink = { - init: function() { - var a, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Report Link'])) { - return; - } - a = $.el('a', { - className: 'report-link', - href: 'javascript:;', - textContent: 'Report' - }); - $.on(a, 'click', ReportLink.report); - return Menu.menu.addEntry({ - el: a, - order: 10, - open: function(post) { - ReportLink.url = "//sys." + (location.hostname.split('.')[1]) + ".org/" + post.board + "/imgboard.php?mode=report&no=" + post; - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - ReportLink.dims = 'width=350,height=275'; - } else { - ReportLink.dims = 'width=400,height=550'; - } - return true; - } - }); - }, - report: function() { - var dims, id, set, url; - url = ReportLink.url, dims = ReportLink.dims; - id = Date.now(); - set = "toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1," + dims; - return window.open(url, id, set); - } - }; - - return ReportLink; - -}).call(this); - -AntiAutoplay = (function() { - var AntiAutoplay; - - AntiAutoplay = { - init: function() { - var audio, i, len, ref; - if (!Conf['Disable Autoplaying Sounds']) { - return; - } - $.addClass(doc, 'anti-autoplay'); - ref = $$('audio[autoplay]', doc); - for (i = 0, len = ref.length; i < len; i++) { - audio = ref[i]; - this.stop(audio); - } - window.addEventListener('loadstart', ((function(_this) { - return function(e) { - return _this.stop(e.target); - }; - })(this)), true); - Callbacks.Post.push({ - name: 'Disable Autoplaying Sounds', - cb: this.node - }); - return $.ready((function(_this) { - return function() { - return _this.process(d.body); - }; - })(this)); - }, - stop: function(audio) { - if (!audio.autoplay) { - return; - } - audio.pause(); - audio.autoplay = false; - if (audio.controls) { - return; - } - audio.controls = true; - return $.addClass(audio, 'controls-added'); - }, - node: function() { - return AntiAutoplay.process(this.nodes.comment); - }, - process: function(root) { - var i, iframe, j, len, len1, object, ref, ref1; - ref = $$('iframe[src*="youtube"][src*="autoplay=1"]', root); - for (i = 0, len = ref.length; i < len; i++) { - iframe = ref[i]; - AntiAutoplay.processVideo(iframe, 'src'); - } - ref1 = $$('object[data*="youtube"][data*="autoplay=1"]', root); - for (j = 0, len1 = ref1.length; j < len1; j++) { - object = ref1[j]; - AntiAutoplay.processVideo(object, 'data'); - } - }, - processVideo: function(el, attr) { - el[attr] = el[attr].replace(/\?autoplay=1&?/, '?').replace('&autoplay=1', ''); - if (window.getComputedStyle(el).display === 'none') { - el.style.display = 'block'; - } - return $.addClass(el, 'autoplay-removed'); - } - }; - - return AntiAutoplay; - -}).call(this); - -Banner = (function() { - var Banner, - slice = [].slice; - - Banner = { - init: function() { - if (Conf['Custom Board Titles']) { - this.db = new DataBoard('customTitles', null, true); - } - $.asap((function() { - return d.body; - }), function() { - return $.asap((function() { - return $('hr'); - }), Banner.ready); - }); - if (g.BOARD.ID !== 'f') { - return Main.ready(function() { - return $.queueTask(Banner.load); - }); - } - }, - ready: function() { - var banner, children; - banner = $(".boardBanner"); - children = banner.children; - if (g.VIEW === 'thread' && Conf['Remove Thread Excerpt']) { - Banner.setTitle(children[1].textContent); - } - children[0].title = "Click to change"; - $.on(children[0], 'click', Banner.cb.toggle); - if (Conf['Custom Board Titles']) { - Banner.custom(children[1]); - if (children[2]) { - return Banner.custom(children[2]); - } - } - }, - load: function() { - var bannerCnt, img; - bannerCnt = $.id('bannerCnt'); - if (!bannerCnt.firstChild) { - img = $.el('img', { - alt: '4chan', - src: '//s.4cdn.org/image/title/' + bannerCnt.dataset.src - }); - return $.add(bannerCnt, img); - } - }, - setTitle: function(title) { - if (Unread.title != null) { - Unread.title = title; - return Unread.update(); - } else { - return d.title = title; - } - }, - cb: { - toggle: function() { - var banner, i, ref; - if (!((ref = Banner.choices) != null ? ref.length : void 0)) { - Banner.choices = Conf['knownBanners'].split(',').slice(); - } - i = Math.floor(Banner.choices.length * Math.random()); - banner = Banner.choices.splice(i, 1); - return $('img', this.parentNode).src = "//s.4cdn.org/image/title/" + banner; - }, - click: function(e) { - var base, br, j, len, name, ref; - if (!(e.ctrlKey || e.metaKey)) { - return; - } - if ((base = Banner.original)[name = this.className] == null) { - base[name] = this.cloneNode(true); - } - this.contentEditable = true; - ref = $$('br', this); - for (j = 0, len = ref.length; j < len; j++) { - br = ref[j]; - $.replace(br, $.tn('\n')); - } - return this.focus(); - }, - keydown: function(e) { - e.stopPropagation(); - if (!e.shiftKey && e.keyCode === 13) { - return this.blur(); - } - }, - blur: function() { - var br, j, len, ref; - ref = $$('br', this); - for (j = 0, len = ref.length; j < len; j++) { - br = ref[j]; - $.replace(br, $.tn('\n')); - } - if (this.textContent = this.textContent.replace(/\n*$/, '')) { - this.contentEditable = false; - return Banner.db.set({ - boardID: g.BOARD.ID, - threadID: this.className, - val: { - title: this.textContent, - orig: Banner.original[this.className].textContent - } - }); - } else { - $.rmAll(this); - $.add(this, slice.call(Banner.original[this.className].cloneNode(true).childNodes)); - return Banner.db["delete"]({ - boardID: g.BOARD.ID, - threadID: this.className - }); - } - } - }, - original: $.dict(), - custom: function(child) { - var className, data, event, j, len, ref; - className = child.className; - child.title = "Ctrl/\u2318+click to edit board " + (className.slice(5).toLowerCase()); - child.spellcheck = false; - ref = ['click', 'keydown', 'blur']; - for (j = 0, len = ref.length; j < len; j++) { - event = ref[j]; - $.on(child, event, Banner.cb[event]); - } - if (data = Banner.db.get({ - boardID: g.BOARD.ID, - threadID: className - })) { - if (Conf['Persistent Custom Board Titles'] || data.orig === child.textContent) { - Banner.original[className] = child.cloneNode(true); - return child.textContent = data.title; - } else { - return Banner.db["delete"]({ - boardID: g.BOARD.ID, - threadID: className - }); - } - } - } - }; - - return Banner; - -}).call(this); - -CatalogLinks = (function() { - var CatalogLinks; - - CatalogLinks = { - init: function() { - var el, input, selector; - if (g.SITE.software === 'yotsuba' && (Conf['External Catalog'] || Conf['JSON Index']) && !(Conf['JSON Index'] && g.VIEW === 'index')) { - selector = (function() { - switch (g.VIEW) { - case 'thread': - case 'archive': - return '.navLinks.desktop > a'; - case 'catalog': - return '.navLinks > :first-child > a'; - case 'index': - return '#ctrl-top > a, .cataloglink > a'; - } - })(); - $.ready(function() { - var base, catalogLink, catalogURL, i, len, link, link2, ref; - ref = $$(selector); - for (i = 0, len = ref.length; i < len; i++) { - link = ref[i]; - switch (link.pathname.replace(/\/+/g, '/')) { - case "/" + g.BOARD + "/": - if (Conf['JSON Index']) { - link.textContent = 'Index'; - } - link.href = CatalogLinks.index(); - break; - case "/" + g.BOARD + "/catalog": - link.href = CatalogLinks.catalog(); - } - if (g.VIEW === 'catalog' && (catalogURL = CatalogLinks.catalog()) !== (typeof (base = g.SITE.urls).catalog === "function" ? base.catalog(g.BOARD) : void 0)) { - catalogLink = link.parentNode.cloneNode(true); - link2 = catalogLink.firstElementChild; - link2.href = catalogURL; - link2.textContent = link2.hostname === location.hostname ? '4chan X Catalog' : 'External Catalog'; - $.after(link.parentNode, [$.tn(' '), catalogLink]); - } - } - }); - } - if (g.SITE.software === 'yotsuba' && Conf['JSON Index'] && Conf['Use 4chan X Catalog']) { - Callbacks.Post.push({ - name: 'Catalog Link Rewrite', - cb: this.node - }); - } - if ((this.enabled = Conf['Catalog Links'])) { - CatalogLinks.el = el = UI.checkbox('Header catalog links', 'Catalog Links'); - el.id = 'toggleCatalog'; - input = $('input', el); - $.on(input, 'change', this.toggle); - $.sync('Header catalog links', CatalogLinks.set); - return Header.menu.addEntry({ - el: el, - order: 95 - }); - } - }, - node: function() { - var a, i, len, m, ref; - ref = $$('a', this.nodes.comment); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - if (m = a.href.match(/^https?:\/\/(boards\.4chan(?:nel)?\.org\/[^\/]+)\/catalog(#s=.*)?/)) { - a.href = "//" + m[1] + "/" + (m[2] || '#catalog'); - } - } - }, - toggle: function() { - $.event('CloseMenu'); - $.set('Header catalog links', this.checked); - return CatalogLinks.set(this.checked); - }, - set: function(useCatalog) { - Conf['Header catalog links'] = useCatalog; - CatalogLinks.setLinks(Header.boardList); - CatalogLinks.setLinks(Header.bottomBoardList); - CatalogLinks.el.title = "Turn catalog links " + (useCatalog ? 'off' : 'on') + "."; - return $('input', CatalogLinks.el).checked = useCatalog; - }, - setLinks: function(list) { - var VIEW, a, board, boardID, i, len, ref, ref1, ref2, ref3, siteID, tail, url; - if (!(((ref = CatalogLinks.enabled) != null ? ref : Conf['Catalog Links']) && list)) { - return; - } - tail = /(?:index)?(?:\.\w+)?$/; - ref1 = $$('a:not([data-only])', list); - for (i = 0, len = ref1.length; i < len; i++) { - a = ref1[i]; - ref2 = a.dataset, siteID = ref2.siteID, boardID = ref2.boardID; - if (!(siteID && boardID)) { - ref3 = Site.parseURL(a), siteID = ref3.siteID, boardID = ref3.boardID, VIEW = ref3.VIEW; - if (!(siteID && boardID && (VIEW === 'index' || VIEW === 'catalog') && (a.dataset.indexOptions || a.href.replace(tail, '') === (Get.url(VIEW, { - siteID: siteID, - boardID: boardID - }) || '').replace(tail, '')))) { - continue; - } - $.extend(a.dataset, { - siteID: siteID, - boardID: boardID - }); - } - board = { - siteID: siteID, - boardID: boardID - }; - url = Conf['Header catalog links'] ? CatalogLinks.catalog(board) : Get.url('index', board); - if (url) { - a.href = url; - if (a.dataset.indexOptions && url.split('#')[0] === Get.url('index', board)) { - a.href += (a.hash ? '/' : '#') + a.dataset.indexOptions; - } - } - } - }, - externalParse: function() { - var board, boards, excludes, i, len, line, ref, ref1, ref2, url; - CatalogLinks.externalList = $.dict(); - ref = Conf['externalCatalogURLs'].split('\n'); - for (i = 0, len = ref.length; i < len; i++) { - line = ref[i]; - if (line[0] === '#') { - continue; - } - url = line.split(';')[0]; - boards = Filter.parseBoards(((ref1 = line.match(/;boards:([^;]+)/)) != null ? ref1[1] : void 0) || '*'); - excludes = Filter.parseBoards((ref2 = line.match(/;exclude:([^;]+)/)) != null ? ref2[1] : void 0) || $.dict(); - for (board in boards) { - if (!(excludes[board] || excludes[board.split('/')[0] + '/*'])) { - CatalogLinks.externalList[board] = url; - } - } - } - }, - external: function(arg) { - var boardID, external, siteID; - siteID = arg.siteID, boardID = arg.boardID; - if (!CatalogLinks.externalList) { - CatalogLinks.externalParse(); - } - external = CatalogLinks.externalList[siteID + "/" + boardID] || CatalogLinks.externalList[siteID + "/*"]; - if (external) { - return external.replace(/%board/g, boardID); - } else { - return void 0; - } - }, - jsonIndex: function(board, hash) { - if (g.SITE.ID === board.siteID && g.BOARD.ID === board.boardID && g.VIEW === 'index') { - return hash; - } else { - return Get.url('index', board) + hash; - } - }, - catalog: function(board) { - var external, nativeCatalog; - if (board == null) { - board = g.BOARD; - } - if (Conf['External Catalog'] && (external = CatalogLinks.external(board))) { - return external; - } else if (Index.enabledOn(board) && Conf['Use 4chan X Catalog']) { - return CatalogLinks.jsonIndex(board, '#catalog'); - } else if ((nativeCatalog = Get.url('catalog', board))) { - return nativeCatalog; - } else { - return CatalogLinks.external(board); - } - }, - index: function(board) { - if (board == null) { - board = g.BOARD; - } - if (Index.enabledOn(board)) { - return CatalogLinks.jsonIndex(board, '#index'); - } else { - return Get.url('index', board); - } - } - }; - - return CatalogLinks; - -}).call(this); - -CustomCSS = (function() { - var CustomCSS; - - CustomCSS = { - init: function() { - if (!Conf['Custom CSS']) { - return; - } - return this.addStyle(); - }, - addStyle: function() { - return this.style = $.addStyle(CSS.sub(Conf['usercss']), 'custom-css', '#fourchanx-css'); - }, - rmStyle: function() { - if (this.style) { - $.rm(this.style); - return delete this.style; - } - }, - update: function() { - if (!this.style) { - return this.addStyle(); - } - return this.style.textContent = CSS.sub(Conf['usercss']); - } - }; - - return CustomCSS; - -}).call(this); - -ExpandComment = (function() { - var ExpandComment; - - ExpandComment = { - init: function() { - if (g.VIEW !== 'index' || !Conf['Comment Expansion'] || Conf['JSON Index']) { - return; - } - return Callbacks.Post.push({ - name: 'Comment Expansion', - cb: this.node - }); - }, - node: function() { - var a; - if (a = $('.abbr > a:not([onclick])', this.nodes.comment)) { - return $.on(a, 'click', ExpandComment.cb); - } - }, - callbacks: [], - cb: function(e) { - e.preventDefault(); - return ExpandComment.expand(Get.postFromNode(this)); - }, - expand: function(post) { - var a; - if (post.nodes.longComment && !post.nodes.longComment.parentNode) { - $.replace(post.nodes.shortComment, post.nodes.longComment); - post.nodes.comment = post.nodes.longComment; - return; - } - if (!(a = $('.abbr > a', post.nodes.comment))) { - return; - } - a.textContent = "Post No." + post + " Loading..."; - return $.cache(g.SITE.urls.threadJSON({ - boardID: post.boardID, - threadID: post.threadID - }), function() { - return ExpandComment.parse(this, a, post); - }); - }, - contract: function(post) { - var a; - if (!post.nodes.shortComment) { - return; - } - a = $('.abbr > a', post.nodes.shortComment); - a.textContent = 'here'; - $.replace(post.nodes.longComment, post.nodes.shortComment); - return post.nodes.comment = post.nodes.shortComment; - }, - parse: function(req, a, post) { - var callback, clone, comment, href, i, j, k, len, len1, len2, postObj, posts, quote, ref, ref1, spoilerRange, status; - status = req.status; - if (status !== 200 && status !== 304) { - a.textContent = status ? "Error " + req.statusText + " (" + status + ")" : 'Connection Error'; - return; - } - posts = req.response.posts; - if (spoilerRange = posts[0].custom_spoiler) { - g.SITE.Build.spoilerRange[g.BOARD] = spoilerRange; - } - for (i = 0, len = posts.length; i < len; i++) { - postObj = posts[i]; - if (postObj.no === post.ID) { - break; - } - } - if (postObj.no !== post.ID) { - a.textContent = "Post No." + post + " not found."; - return; - } - comment = post.nodes.comment; - clone = comment.cloneNode(false); - clone.innerHTML = postObj.com; - ref = $$('.quotelink', clone); - for (j = 0, len1 = ref.length; j < len1; j++) { - quote = ref[j]; - href = quote.getAttribute('href'); - if (href[0] === '/') { - continue; - } - if (href[0] === '#') { - quote.href = "" + (a.pathname.split(/\/+/).splice(0, 4).join('/')) + href; - } else { - quote.href = (a.pathname.split(/\/+/).splice(0, 3).join('/')) + "/" + href; - } - } - post.nodes.shortComment = comment; - $.replace(comment, clone); - post.nodes.comment = post.nodes.longComment = clone; - post.parseComment(); - post.parseQuotes(); - ref1 = ExpandComment.callbacks; - for (k = 0, len2 = ref1.length; k < len2; k++) { - callback = ref1[k]; - callback.call(post); - } - } - }; - - return ExpandComment; - -}).call(this); - -ExpandThread = (function() { - var ExpandThread, - slice = [].slice; - - ExpandThread = { - statuses: $.dict(), - init: function() { - if (!(g.VIEW === 'index' && Conf['Thread Expansion'])) { - return; - } - if (Conf['JSON Index']) { - return $.on(d, 'IndexRefreshInternal', this.onIndexRefresh); - } else { - return Callbacks.Thread.push({ - name: 'Expand Thread', - cb: function() { - return ExpandThread.setButton(this); - } - }); - } - }, - setButton: function(thread) { - var a, ref; - if (!(thread.nodes.root && (a = $('.summary', thread.nodes.root)))) { - return; - } - a.textContent = (ref = g.SITE.Build).summaryText.apply(ref, ['+'].concat(slice.call(a.textContent.match(/\d+/g)))); - a.style.cursor = 'pointer'; - return $.on(a, 'click', ExpandThread.cbToggle); - }, - disconnect: function(refresh) { - var oldReq, ref, status, threadID; - if (g.VIEW === 'thread' || !Conf['Thread Expansion']) { - return; - } - ref = ExpandThread.statuses; - for (threadID in ref) { - status = ref[threadID]; - if ((oldReq = status.req)) { - delete status.req; - oldReq.abort(); - } - delete ExpandThread.statuses[threadID]; - } - if (!refresh) { - return $.off(d, 'IndexRefreshInternal', this.onIndexRefresh); - } - }, - onIndexRefresh: function() { - ExpandThread.disconnect(true); - return g.BOARD.threads.forEach(function(thread) { - return ExpandThread.setButton(thread); - }); - }, - cbToggle: function(e) { - if ($.modifiedClick(e)) { - return; - } - e.preventDefault(); - return ExpandThread.toggle(Get.threadFromNode(this)); - }, - cbToggleBottom: function(e) { - var bottom, thread; - if ($.modifiedClick(e)) { - return; - } - e.preventDefault(); - thread = Get.threadFromNode(this); - $.rm(this); - bottom = thread.nodes.root.getBoundingClientRect().bottom; - ExpandThread.toggle(thread); - return window.scrollBy(0, thread.nodes.root.getBoundingClientRect().bottom - bottom); - }, - toggle: function(thread) { - var a; - if (!(thread.nodes.root && (a = $('.summary', thread.nodes.root)))) { - return; - } - if (thread.ID in ExpandThread.statuses) { - return ExpandThread.contract(thread, a, thread.nodes.root); - } else { - return ExpandThread.expand(thread, a); - } - }, - expand: function(thread, a) { - var ref, status; - ExpandThread.statuses[thread] = status = {}; - a.textContent = (ref = g.SITE.Build).summaryText.apply(ref, ['...'].concat(slice.call(a.textContent.match(/\d+/g)))); - status.req = $.cache(g.SITE.urls.threadJSON({ - boardID: thread.board.ID, - threadID: thread.ID - }), function() { - if (this !== status.req) { - return; - } - delete status.req; - return ExpandThread.parse(this, thread, a); - }); - return status.numReplies = $$(g.SITE.selectors.replyOriginal, thread.nodes.root).length; - }, - contract: function(thread, a, threadRoot) { - var filesCount, i, inlined, len, oldReq, postsCount, ref, replies, reply, status; - status = ExpandThread.statuses[thread]; - delete ExpandThread.statuses[thread]; - if ((oldReq = status.req)) { - delete status.req; - oldReq.abort(); - if (a) { - a.textContent = (ref = g.SITE.Build).summaryText.apply(ref, ['+'].concat(slice.call(a.textContent.match(/\d+/g)))); - } - return; - } - replies = $$('.thread > .replyContainer', threadRoot); - if (status.numReplies) { - replies = replies.slice(0, -status.numReplies); - } - postsCount = 0; - filesCount = 0; - for (i = 0, len = replies.length; i < len; i++) { - reply = replies[i]; - if (Conf['Quote Inlining']) { - while (inlined = $('.inlined', reply)) { - inlined.click(); - } - } - postsCount++; - if ('file' in Get.postFromRoot(reply)) { - filesCount++; - } - $.rm(reply); - } - if (Index.enabled) { - $.event('PostsRemoved', null, a.parentNode); - } - a.textContent = g.SITE.Build.summaryText('+', postsCount, filesCount); - return $.rm($('.summary-bottom', threadRoot)); - }, - parse: function(req, thread, a) { - var a2, filesCount, i, len, post, postData, posts, postsCount, postsRoot, ref, ref1, root; - if ((ref = req.status) !== 200 && ref !== 304) { - a.textContent = req.status ? "Error " + req.statusText + " (" + req.status + ")" : 'Connection Error'; - return; - } - g.SITE.Build.spoilerRange[thread.board] = req.response.posts[0].custom_spoiler; - posts = []; - postsRoot = []; - filesCount = 0; - ref1 = req.response.posts; - for (i = 0, len = ref1.length; i < len; i++) { - postData = ref1[i]; - if (postData.no === thread.ID) { - continue; - } - if ((post = thread.posts.get(postData.no)) && !post.isFetchedQuote) { - if ('file' in post) { - filesCount++; - } - root = post.nodes.root; - postsRoot.push(root); - continue; - } - root = g.SITE.Build.postFromObject(postData, thread.board.ID); - post = new Post(root, thread, thread.board); - if ('file' in post) { - filesCount++; - } - posts.push(post); - postsRoot.push(root); - } - Main.callbackNodes('Post', posts); - $.after(a, postsRoot); - $.event('PostsInserted', null, a.parentNode); - postsCount = postsRoot.length; - a.textContent = g.SITE.Build.summaryText('-', postsCount, filesCount); - if (root) { - a2 = a.cloneNode(true); - a2.classList.add('summary-bottom'); - $.on(a2, 'click', ExpandThread.cbToggleBottom); - return $.after(root, a2); - } - } - }; - - return ExpandThread; - -}).call(this); - -FileInfo = (function() { - var FileInfo; - - FileInfo = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread' && ref !== 'archive') || !Conf['File Info Formatting']) { - return; - } - return Callbacks.Post.push({ - name: 'File Info Formatting', - cb: this.node - }); - }, - node: function() { - var a, i, info, j, len, len1, oldInfo, ref, ref1; - if (!this.file) { - return; - } - if (this.isClone) { - ref = $$('.file-info .download-button', this.file.text); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - $.on(a, 'click', ImageCommon.download); - } - ref1 = $$('.file-info .quick-filter-md5', this.file.text); - for (j = 0, len1 = ref1.length; j < len1; j++) { - a = ref1[j]; - $.on(a, 'click', Filter.quickFilterMD5); - } - return; - } - oldInfo = $.el('span', { - className: 'fileText-original' - }); - $.prepend(this.file.link.parentNode, oldInfo); - $.add(oldInfo, [this.file.link.previousSibling, this.file.link, this.file.link.nextSibling]); - info = $.el('span', { - className: 'file-info' - }); - FileInfo.format(Conf['fileInfo'], this, info); - return $.prepend(this.file.text, info); - }, - format: function(formatString, post, outputNode) { - var a, i, j, len, len1, output, ref, ref1; - output = []; - formatString.replace(/%(.)|[^%]+/g, function(s, c) { - output.push($.hasOwn(FileInfo.formatters, c) ? FileInfo.formatters[c].call(post) : {innerHTML: E(s)}); - return ''; - }); - $.extend(outputNode, {innerHTML: E.cat(output)}); - ref = $$('.download-button', outputNode); - for (i = 0, len = ref.length; i < len; i++) { - a = ref[i]; - $.on(a, 'click', ImageCommon.download); - } - ref1 = $$('.quick-filter-md5', outputNode); - for (j = 0, len1 = ref1.length; j < len1; j++) { - a = ref1[j]; - $.on(a, 'click', Filter.quickFilterMD5); - } - }, - formatters: { - t: function() { - return {innerHTML: E(this.file.url.match(/[^/]*$/)[0])}; - }, - T: function() { - return {innerHTML: "" + (FileInfo.formatters.t.call(this)).innerHTML + ""}; - }, - l: function() { - return {innerHTML: "" + (FileInfo.formatters.n.call(this)).innerHTML + ""}; - }, - L: function() { - return {innerHTML: "" + (FileInfo.formatters.N.call(this)).innerHTML + ""}; - }, - n: function() { - var fullname, shortname; - fullname = this.file.name; - shortname = SW.yotsuba.Build.shortFilename(this.file.name, this.isReply); - if (fullname === shortname) { - return {innerHTML: E(fullname)}; - } else { - return {innerHTML: "" + E(shortname) + "" + E(fullname) + ""}; - } - }, - N: function() { - return {innerHTML: E(this.file.name)}; - }, - d: function() { - return {innerHTML: ""}; - }, - f: function() { - return {innerHTML: ""}; - }, - p: function() { - return {innerHTML: ((this.file.isSpoiler) ? "Spoiler, " : "")}; - }, - s: function() { - return {innerHTML: E(this.file.size)}; - }, - B: function() { - return {innerHTML: E(Math.round(this.file.sizeInBytes)) + " Bytes"}; - }, - K: function() { - return {innerHTML: E(Math.round(this.file.sizeInBytes/1024)) + " KB"}; - }, - M: function() { - return {innerHTML: E(Math.round(this.file.sizeInBytes/1048576*100)/100) + " MB"}; - }, - r: function() { - return {innerHTML: E(this.file.dimensions || "PDF")}; - }, - g: function() { - return {innerHTML: ((this.file.tag) ? ", " + E(this.file.tag) : "")}; - }, - '%': function() { - return {innerHTML: "%"}; - } - } - }; - - return FileInfo; - -}).call(this); - -Flash = (function() { - var Flash; - - Flash = { - init: function() { - if (g.BOARD.ID === 'f' && Conf['Enable Native Flash Embedding']) { - return $.ready(Flash.initReady); - } - }, - initReady: function() { - if ($.hasStorage) { - return $.global(function() { - if (JSON.parse(localStorage['4chan-settings'] || '{}').disableAll) { - return window.SWFEmbed.init(); - } - }); - } else { - if (g.VIEW === 'thread') { - $.global(function() { - return window.Main.tid = location.pathname.split(/\/+/)[3]; - }); - } - return $.global(function() { - return window.SWFEmbed.init(); - }); - } - } - }; - - return Flash; - -}).call(this); - -Fourchan = (function() { - var Fourchan; - - Fourchan = { - init: function() { - var ref; - if (!(g.SITE.software === 'yotsuba' && ((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive'))) { - return; - } - BoardConfig.ready(this.initBoard); - return Main.ready(this.initReady); - }, - initBoard: function() { - if (g.BOARD.config.code_tags) { - $.on(window, 'prettyprint:cb', function(e) { - var post, pre; - if (!(post = g.posts.get(e.detail.ID))) { - return; - } - if (!(pre = $$('.prettyprint', post.nodes.comment)[+e.detail.i])) { - return; - } - if (!$.hasClass(pre, 'prettyprinted')) { - pre.innerHTML = e.detail.html; - return $.addClass(pre, 'prettyprinted'); - } - }); - $.global(function() { - return window.addEventListener('prettyprint', function(e) { - return window.dispatchEvent(new CustomEvent('prettyprint:cb', { - detail: { - ID: e.detail.ID, - i: e.detail.i, - html: window.prettyPrintOne(e.detail.html) - } - })); - }, false); - }); - Callbacks.Post.push({ - name: 'Parse [code] tags', - cb: Fourchan.code - }); - g.posts.forEach(function(post) { - if (post.callbacksExecuted) { - return Callbacks.Post.execute(post, ['Parse [code] tags'], true); - } - }); - ExpandComment.callbacks.push(Fourchan.code); - } - if (g.BOARD.config.math_tags) { - $.global(function() { - return window.addEventListener('mathjax', function(e) { - if (window.MathJax) { - return window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, e.target]); - } else { - if (!document.querySelector('script[src^="//cdn.mathjax.org/"]')) { - window.loadMathJax(); - window.loadMathJax = function() {}; - } - if (!e.target.classList.contains('postMessage')) { - return document.querySelector('script[src^="//cdn.mathjax.org/"]').addEventListener('load', function() { - return window.MathJax.Hub.Queue(['Typeset', window.MathJax.Hub, e.target]); - }, false); - } - } - }, false); - }); - Callbacks.Post.push({ - name: 'Parse [math] tags', - cb: Fourchan.math - }); - g.posts.forEach(function(post) { - if (post.callbacksExecuted) { - return Callbacks.Post.execute(post, ['Parse [math] tags'], true); - } - }); - return ExpandComment.callbacks.push(Fourchan.math); - } - }, - initReady: function() { - return $.global(function() { - var j, len, node, ref; - window.clickable_ids = false; - ref = document.querySelectorAll('.posteruid, .capcode'); - for (j = 0, len = ref.length; j < len; j++) { - node = ref[j]; - node.removeEventListener('click', window.idClick, false); - } - }); - }, - code: function() { - if (this.isClone) { - return; - } - return $.ready((function(_this) { - return function() { - var i, j, len, pre, ref; - ref = $$('.prettyprint', _this.nodes.comment); - for (i = j = 0, len = ref.length; j < len; i = ++j) { - pre = ref[i]; - if (!$.hasClass(pre, 'prettyprinted')) { - $.event('prettyprint', { - ID: _this.fullID, - i: i, - html: pre.innerHTML - }, window); - } - } - }; - })(this)); - }, - math: function() { - var cb, j, len, wbr, wbrs; - if (!/\[(math|eqn)\]/.test(this.nodes.comment.textContent)) { - return; - } - if ((wbrs = $$('wbr', this.nodes.comment)).length) { - for (j = 0, len = wbrs.length; j < len; j++) { - wbr = wbrs[j]; - $.rm(wbr); - } - this.nodes.comment.normalize(); - } - cb = (function(_this) { - return function() { - if (!doc.contains(_this.nodes.comment)) { - return; - } - $.off(d, 'PostsInserted', cb); - return $.event('mathjax', null, _this.nodes.comment); - }; - })(this); - $.on(d, 'PostsInserted', cb); - return cb(); - } - }; - - return Fourchan; - -}).call(this); - -IDColor = (function() { - var IDColor; - - IDColor = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Color User IDs'])) { - return; - } - this.ids = $.dict(); - this.ids['Heaven'] = [0, 0, 0, '#fff']; - return Callbacks.Post.push({ - name: 'Color User IDs', - cb: this.node - }); - }, - node: function() { - var rgb, span, style, uid; - if (this.isClone || !((uid = this.info.uniqueID) && (span = this.nodes.uniqueID))) { - return; - } - rgb = IDColor.ids[uid] || IDColor.compute(uid); - style = span.style; - style.color = rgb[3]; - style.backgroundColor = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")"; - return $.addClass(span, 'painted'); - }, - compute: function(uid) { - var hash, rgb; - hash = g.SITE.uidColor ? g.SITE.uidColor(uid) : parseInt(uid, 16); - rgb = [(hash >> 16) & 0xFF, (hash >> 8) & 0xFF, hash & 0xFF]; - rgb.push($.luma(rgb) > 125 ? '#000' : '#fff'); - return this.ids[uid] = rgb; - } - }; - - return IDColor; - -}).call(this); - -IDHighlight = (function() { - var IDHighlight; - - IDHighlight = { - init: function() { - var ref; - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - return Callbacks.Post.push({ - name: 'Highlight by User ID', - cb: this.node - }); - }, - uniqueID: null, - node: function() { - if (this.nodes.uniqueIDRoot) { - $.on(this.nodes.uniqueIDRoot, 'click', IDHighlight.click(this)); - } - if (this.nodes.capcode) { - $.on(this.nodes.capcode, 'click', IDHighlight.click(this)); - } - if (!this.isClone) { - return IDHighlight.set(this); - } - }, - set: function(post) { - var match; - match = (post.info.uniqueID || post.info.capcode) === IDHighlight.uniqueID; - return $[match ? 'addClass' : 'rmClass'](post.nodes.post, 'highlight'); - }, - click: function(post) { - return function() { - var uniqueID; - uniqueID = post.info.uniqueID || post.info.capcode; - IDHighlight.uniqueID = IDHighlight.uniqueID === uniqueID ? null : uniqueID; - return g.posts.forEach(IDHighlight.set); - }; - } - }; - - return IDHighlight; - -}).call(this); - -IDPostCount = (function() { - var IDPostCount; - - IDPostCount = { - init: function() { - if (!(g.VIEW === 'thread' && Conf['Count Posts by ID'])) { - return; - } - Callbacks.Thread.push({ - name: 'Count Posts by ID', - cb: function() { - return IDPostCount.thread = this; - } - }); - return Callbacks.Post.push({ - name: 'Count Posts by ID', - cb: this.node - }); - }, - node: function() { - if (this.nodes.uniqueID && this.thread === IDPostCount.thread) { - return $.on(this.nodes.uniqueID, 'mouseover', IDPostCount.count); - } - }, - count: function() { - var n, uniqueID; - uniqueID = Get.postFromNode(this).info.uniqueID; - n = 0; - IDPostCount.thread.posts.forEach(function(post) { - if (post.info.uniqueID === uniqueID) { - return n++; - } - }); - return this.title = n + " post" + (n === 1 ? '' : 's') + " by this ID"; - } - }; - - return IDPostCount; - -}).call(this); - -Keybinds = (function() { - var Keybinds; - - Keybinds = { - init: function() { - var hotkey, init; - if (!Conf['Keybinds']) { - return; - } - for (hotkey in Config.hotkeys) { - $.sync(hotkey, Keybinds.sync); - } - init = function() { - var i, len, node, ref; - $.off(d, '4chanXInitFinished', init); - $.on(d, 'keydown', Keybinds.keydown); - ref = $$('[accesskey]'); - for (i = 0, len = ref.length; i < len; i++) { - node = ref[i]; - node.removeAttribute('accesskey'); - } - }; - return $.on(d, '4chanXInitFinished', init); - }, - sync: function(key, hotkey) { - return Conf[hotkey] = key; - }, - keydown: function(e) { - var base, base1, catalog, i, key, len, notification, notifications, post, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, searchInput, target, thread, threadRoot; - if (!(key = Keybinds.keyCode(e))) { - return; - } - target = e.target; - if ((ref = target.nodeName) === 'INPUT' || ref === 'TEXTAREA') { - if (!(/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(key) && !/^Alt\+(\d|Up|Down|Left|Right)$/.test(key))) { - return; - } - } - if ((ref1 = g.VIEW) === 'index' || ref1 === 'thread') { - threadRoot = Nav.getThread(); - thread = Get.threadFromRoot(threadRoot); - } - switch (key) { - case Conf['Toggle board list']: - if (!Conf['Custom Board Navigation']) { - return; - } - Header.toggleBoardList(); - break; - case Conf['Toggle header']: - Header.toggleBarVisibility(); - break; - case Conf['Open empty QR']: - if (!QR.postingIsEnabled) { - return; - } - Keybinds.qr(); - break; - case Conf['Open QR']: - if (!(QR.postingIsEnabled && threadRoot)) { - return; - } - Keybinds.qr(threadRoot); - break; - case Conf['Open settings']: - Settings.open(); - break; - case Conf['Close']: - if (Settings.dialog) { - Settings.close(); - } else if ((notifications = $$('.notification')).length) { - for (i = 0, len = notifications.length; i < len; i++) { - notification = notifications[i]; - $('.close', notification).click(); - } - } else if (QR.nodes && !(QR.nodes.el.hidden || window.getComputedStyle(QR.nodes.form).display === 'none')) { - if (Conf['Persistent QR']) { - QR.hide(); - } else { - QR.close(); - } - } else if (Embedding.lastEmbed) { - Embedding.closeFloat(); - } else { - return; - } - break; - case Conf['Spoiler tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('spoiler', target); - break; - case Conf['Code tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('code', target); - break; - case Conf['Eqn tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('eqn', target); - break; - case Conf['Math tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('math', target); - break; - case Conf['SJIS tags']: - if (target.nodeName !== 'TEXTAREA') { - return; - } - Keybinds.tags('sjis', target); - break; - case Conf['Toggle sage']: - if (!(QR.nodes && !QR.nodes.el.hidden)) { - return; - } - Keybinds.sage(); - break; - case Conf['Toggle Cooldown']: - if (!(QR.nodes && !QR.nodes.el.hidden && $.hasClass(QR.nodes.fileSubmit, 'custom-cooldown'))) { - return; - } - QR.toggleCustomCooldown(); - break; - case Conf['Post from URL']: - if (!QR.postingIsEnabled) { - return; - } - QR.handleUrl(''); - break; - case Conf['Add new post']: - if (!QR.postingIsEnabled) { - return; - } - QR.addPost(); - break; - case Conf['Submit QR']: - if (!(QR.nodes && !QR.nodes.el.hidden)) { - return; - } - if (!QR.status()) { - QR.submit(); - } - break; - case Conf['Update']: - switch (g.VIEW) { - case 'thread': - if (!ThreadUpdater.enabled) { - return; - } - ThreadUpdater.update(); - break; - case 'index': - if (!Index.enabled) { - return; - } - Index.update(); - break; - default: - return; - } - break; - case Conf['Watch']: - if (!(ThreadWatcher.enabled && thread)) { - return; - } - ThreadWatcher.toggle(thread); - break; - case Conf['Update thread watcher']: - if (!ThreadWatcher.enabled) { - return; - } - ThreadWatcher.buttonFetchAll(); - break; - case Conf['Toggle thread watcher']: - if (!ThreadWatcher.enabled) { - return; - } - ThreadWatcher.toggleWatcher(); - break; - case Conf['Toggle threading']: - if (!QuoteThreading.ready) { - return; - } - QuoteThreading.toggleThreading(); - break; - case Conf['Mark thread read']: - if (!(g.VIEW === 'index' && thread && UnreadIndex.enabled)) { - return; - } - UnreadIndex.markRead.call(threadRoot); - break; - case Conf['Expand image']: - if (!(ImageExpand.enabled && threadRoot)) { - return; - } - post = Get.postFromNode(Keybinds.post(threadRoot)); - if (post.file) { - ImageExpand.toggle(post); - } - break; - case Conf['Expand images']: - if (!ImageExpand.enabled) { - return; - } - ImageExpand.cb.toggleAll(); - break; - case Conf['Open Gallery']: - if (!Gallery.enabled) { - return; - } - Gallery.cb.toggle(); - break; - case Conf['fappeTyme']: - if (!((ref2 = FappeTyme.nodes) != null ? ref2.fappe : void 0)) { - return; - } - FappeTyme.toggle('fappe'); - break; - case Conf['werkTyme']: - if (!((ref3 = FappeTyme.nodes) != null ? ref3.werk : void 0)) { - return; - } - FappeTyme.toggle('werk'); - break; - case Conf['Front page']: - if (Index.enabled) { - Index.userPageNav(1); - } else { - location.href = "/" + g.BOARD + "/"; - } - break; - case Conf['Open front page']: - $.open(location.origin + "/" + g.BOARD + "/"); - break; - case Conf['Next page']: - if (!(g.VIEW === 'index' && !(typeof (base = g.SITE).isOnePage === "function" ? base.isOnePage(g.BOARD) : void 0))) { - return; - } - if (Index.enabled) { - if ((ref4 = Conf['Index Mode']) !== 'paged' && ref4 !== 'infinite') { - return; - } - $('.next button', Index.pagelist).click(); - } else { - if ((ref5 = $(g.SITE.selectors.nav.next)) != null) { - ref5.click(); - } - } - break; - case Conf['Previous page']: - if (!(g.VIEW === 'index' && !(typeof (base1 = g.SITE).isOnePage === "function" ? base1.isOnePage(g.BOARD) : void 0))) { - return; - } - if (Index.enabled) { - if ((ref6 = Conf['Index Mode']) !== 'paged' && ref6 !== 'infinite') { - return; - } - $('.prev button', Index.pagelist).click(); - } else { - if ((ref7 = $(g.SITE.selectors.nav.prev)) != null) { - ref7.click(); - } - } - break; - case Conf['Search form']: - if (g.VIEW !== 'index') { - return; - } - searchInput = Index.enabled ? Index.searchInput : g.SITE.selectors.searchBox ? $(g.SITE.selectors.searchBox) : void 0; - if (!searchInput) { - return; - } - Header.scrollToIfNeeded(searchInput); - searchInput.focus(); - break; - case Conf['Paged mode']: - if (!Index.enabledOn(g.BOARD)) { - return; - } - location.href = g.VIEW === 'index' ? '#paged' : "/" + g.BOARD + "/#paged"; - break; - case Conf['Infinite scrolling mode']: - if (!Index.enabledOn(g.BOARD)) { - return; - } - location.href = g.VIEW === 'index' ? '#infinite' : "/" + g.BOARD + "/#infinite"; - break; - case Conf['All pages mode']: - if (!Index.enabledOn(g.BOARD)) { - return; - } - location.href = g.VIEW === 'index' ? '#all-pages' : "/" + g.BOARD + "/#all-pages"; - break; - case Conf['Open catalog']: - if (!(catalog = CatalogLinks.catalog())) { - return; - } - location.href = catalog; - break; - case Conf['Cycle sort type']: - if (!Index.enabled) { - return; - } - Index.cycleSortType(); - break; - case Conf['Next thread']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - Nav.scroll(+1); - break; - case Conf['Previous thread']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - Nav.scroll(-1); - break; - case Conf['Expand thread']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - ExpandThread.toggle(thread); - Header.scrollTo(threadRoot); - break; - case Conf['Open thread']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - Keybinds.open(thread); - break; - case Conf['Open thread tab']: - if (!(g.VIEW === 'index' && threadRoot)) { - return; - } - Keybinds.open(thread, true); - break; - case Conf['Next reply']: - if (!threadRoot) { - return; - } - Keybinds.hl(+1, threadRoot); - break; - case Conf['Previous reply']: - if (!threadRoot) { - return; - } - Keybinds.hl(-1, threadRoot); - break; - case Conf['Deselect reply']: - if (!threadRoot) { - return; - } - Keybinds.hl(0, threadRoot); - break; - case Conf['Hide']: - if (!(thread && ThreadHiding.db)) { - return; - } - Header.scrollTo(threadRoot); - ThreadHiding.toggle(thread); - break; - case Conf['Quick Filter MD5']: - if (!threadRoot) { - return; - } - post = Keybinds.post(threadRoot); - Keybinds.hl(+1, threadRoot); - Filter.quickFilterMD5.call(post, e); - break; - case Conf['Previous Post Quoting You']: - if (!(threadRoot && QuoteYou.db)) { - return; - } - QuoteYou.cb.seek('preceding'); - break; - case Conf['Next Post Quoting You']: - if (!(threadRoot && QuoteYou.db)) { - return; - } - QuoteYou.cb.seek('following'); - break; - default: - return; - } - e.preventDefault(); - return e.stopPropagation(); - }, - keyCode: function(e) { - var kc, key; - key = (function() { - switch (kc = 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: - if ((48 <= kc && kc <= 57) || (65 <= kc && kc <= 90)) { - return String.fromCharCode(kc).toLowerCase(); - } else if ((96 <= kc && kc <= 105)) { - return String.fromCharCode(kc - 48).toLowerCase(); - } else { - return null; - } - } - })(); - if (key) { - if (e.altKey) { - key = 'Alt+' + key; - } - if (e.ctrlKey) { - key = 'Ctrl+' + key; - } - if (e.metaKey) { - key = 'Meta+' + key; - } - if (e.shiftKey) { - key = 'Shift+' + key; - } - } - return key; - }, - post: function(thread) { - var s; - s = g.SITE.selectors; - return $("" + s.postContainer + s.highlightable.reply + "." + g.SITE.classes.highlight, thread) || $("" + (g.SITE.isOPContainerThread ? s.thread : s.postContainer) + s.highlightable.op, thread); - }, - qr: function(thread) { - QR.open(); - if (thread != null) { - QR.quote.call(Keybinds.post(thread)); - } - return QR.nodes.com.focus(); - }, - tags: function(tag, ta) { - var range, selEnd, selStart, value; - BoardConfig.ready(function() { - var config, supported; - config = g.BOARD.config; - supported = (function() { - switch (tag) { - case 'spoiler': - return !!config.spoilers; - case 'code': - return !!config.code_tags; - case 'math': - case 'eqn': - return !!config.math_tags; - case 'sjis': - return !!config.sjis_tags; - } - })(); - if (!supported) { - return new Notice('warning', "[" + tag + "] tags are not supported on /" + g.BOARD + "/.", 20); - } - }); - value = ta.value; - selStart = ta.selectionStart; - selEnd = ta.selectionEnd; - ta.value = value.slice(0, selStart) + ("[" + tag + "]") + value.slice(selStart, selEnd) + ("[/" + tag + "]") + value.slice(selEnd); - range = ("[" + tag + "]").length + selEnd; - ta.setSelectionRange(range, range); - return $.event('input', null, ta); - }, - sage: function() { - var isSage; - isSage = /sage/i.test(QR.nodes.email.value); - return QR.nodes.email.value = isSage ? "" : "sage"; - }, - open: function(thread, tab) { - var url; - if (g.VIEW !== 'index') { - return; - } - url = Get.url('thread', thread); - if (tab) { - return $.open(url); - } else { - return location.href = url; - } - }, - hl: function(delta, thread) { - var axis, height, highlight, i, len, next, postEl, replies, reply, replySelector, root; - replySelector = "" + g.SITE.selectors.postContainer + g.SITE.selectors.highlightable.reply; - highlight = g.SITE.classes.highlight; - postEl = $(replySelector + "." + highlight, thread); - if (!delta) { - if (postEl) { - $.rmClass(postEl, highlight); - } - return; - } - if (postEl) { - height = postEl.getBoundingClientRect().height; - if (Header.getTopOf(postEl) >= -height && Header.getBottomOf(postEl) >= -height) { - root = Get.postFromNode(postEl).nodes.root; - axis = delta === +1 ? 'following' : 'preceding'; - if (!(next = $.x(axis + "-sibling::" + g.SITE.xpath.replyContainer + "[not(@hidden) and not(child::div[@class='stub'])][1]", root))) { - return; - } - if (!next.matches(replySelector)) { - next = $(replySelector, next); - } - Header.scrollToIfNeeded(next, delta === +1); - $.addClass(next, highlight); - $.rmClass(postEl, highlight); - return; - } - $.rmClass(postEl, highlight); - } - replies = $$(replySelector, thread); - if (delta === -1) { - replies.reverse(); - } - for (i = 0, len = replies.length; i < len; i++) { - reply = replies[i]; - if (delta === +1 && Header.getTopOf(reply) > 0 || delta === -1 && Header.getBottomOf(reply) > 0) { - $.addClass(reply, highlight); - return; - } - } - } - }; - - return Keybinds; - -}).call(this); - -ModContact = (function() { - var ModContact; - - ModContact = { - init: function() { - var ref; - if (!(g.SITE.software === 'yotsuba' && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - return Callbacks.Post.push({ - name: 'Mod Contact Links', - cb: this.node - }); - }, - node: function() { - var links, moveNote, moved; - if (this.isClone || !$.hasOwn(ModContact.specific, this.info.capcode)) { - return; - } - links = $.el('span', { - className: 'contact-links brackets-wrap' - }); - $.extend(links, ModContact.template(this.info.capcode)); - $.after(this.nodes.capcode, links); - if ((moved = this.info.comment.match(/This thread was moved to >>>\/(\w+)\//)) && $.hasOwn(ModContact.moveNote, moved[1])) { - moveNote = $.el('div', { - className: 'move-note' - }); - $.extend(moveNote, ModContact.moveNote[moved[1]]); - return $.add(this.nodes.post, moveNote); - } - }, - template: function(capcode) { - return {innerHTML: "feedback" + (ModContact.specific[capcode]()).innerHTML}; - }, - specific: { - Mod: function() { - return {innerHTML: " IRC"}; - }, - Manager: function() { - return ModContact.specific.Mod(); - }, - Developer: function() { - return {innerHTML: " github"}; - }, - Admin: function() { - return {innerHTML: " twitter"}; - } - }, - moveNote: { - qa: {innerHTML: "Moving a thread to /qa/ does not imply mods will read it. If you wish to contact mods, use feedback (https://www.4chan.org/feedback) or IRC (https://www.4chan-x.net/4chan-irc.html)."} - } - }; - - return ModContact; - -}).call(this); - -Nav = (function() { - var Nav; - - Nav = { - init: function() { - var append, next, prev, span; - switch (g.VIEW) { - case 'index': - if (!Conf['Index Navigation']) { - return; - } - break; - case 'thread': - if (!Conf['Reply Navigation']) { - return; - } - break; - default: - return; - } - span = $.el('span', { - id: 'navlinks' - }); - prev = $.el('a', { - textContent: '▲', - href: 'javascript:;' - }); - next = $.el('a', { - textContent: '▼', - href: 'javascript:;' - }); - $.on(prev, 'click', this.prev); - $.on(next, 'click', this.next); - $.add(span, [prev, $.tn(' '), next]); - append = function() { - $.off(d, '4chanXInitFinished', append); - return $.add(d.body, span); - }; - return $.on(d, '4chanXInitFinished', append); - }, - prev: function() { - if (g.VIEW === 'thread') { - return window.scrollTo(0, 0); - } else { - return Nav.scroll(-1); - } - }, - next: function() { - if (g.VIEW === 'thread') { - return window.scrollTo(0, d.body.scrollHeight); - } else { - return Nav.scroll(+1); - } - }, - getThread: function() { - var i, len, ref, thread, threadRoot; - if (g.VIEW === 'thread') { - return g.threads.get(g.BOARD + "." + g.THREADID).nodes.root; - } - if ($.hasClass(doc, 'catalog-mode')) { - return; - } - ref = $$(g.SITE.selectors.thread); - for (i = 0, len = ref.length; i < len; i++) { - threadRoot = ref[i]; - thread = Get.threadFromRoot(threadRoot); - if (thread.isHidden && !thread.stub) { - continue; - } - if (Header.getTopOf(threadRoot) >= -threadRoot.getBoundingClientRect().height) { - return threadRoot; - } - } - }, - scroll: function(delta) { - var axis, extra, next, ref, thread, top; - if ((ref = d.activeElement) != null) { - ref.blur(); - } - thread = Nav.getThread(); - if (!thread) { - return; - } - axis = delta === +1 ? 'following' : 'preceding'; - if (next = $.x(axis + "-sibling::" + g.SITE.xpath.thread + "[not(@hidden)][1]", thread)) { - top = Header.getTopOf(thread); - if (delta === +1 && top < 5 || delta === -1 && top > -5) { - thread = next; - } - } - extra = Header.getTopOf(thread) + doc.clientHeight - d.body.getBoundingClientRect().bottom; - if (extra > 0) { - d.body.style.marginBottom = extra + "px"; - } - Header.scrollTo(thread); - if (extra > 0 && !Nav.haveExtra) { - Nav.haveExtra = true; - return $.on(d, 'scroll', Nav.removeExtra); - } - }, - removeExtra: function() { - var extra; - extra = doc.clientHeight - d.body.getBoundingClientRect().bottom; - if (extra > 0) { - return d.body.style.marginBottom = extra + "px"; - } else { - d.body.style.marginBottom = ''; - delete Nav.haveExtra; - return $.off(d, 'scroll', Nav.removeExtra); - } - } - }; - - return Nav; - -}).call(this); - -NormalizeURL = (function() { - var NormalizeURL; - - NormalizeURL = { - init: function() { - var pathname; - if (!Conf['Normalize URL']) { - return; - } - pathname = location.pathname.split(/\/+/); - if (g.SITE.software === 'yotsuba') { - switch (g.VIEW) { - case 'thread': - pathname[2] = 'thread'; - pathname = pathname.slice(0, 4); - break; - case 'index': - pathname = pathname.slice(0, 3); - } - } - pathname = pathname.join('/'); - if (location.pathname !== pathname) { - return history.replaceState(history.state, '', location.protocol + "//" + location.host + pathname + location.hash); - } - } - }; - - return NormalizeURL; - -}).call(this); - -PSA = (function() { - var PSA, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - PSA = { - init: function() { - var announcement, el; - if (g.SITE.software === 'yotsuba' && g.BOARD.ID === 'qa') { - announcement = { - innerHTML: "Stay in touch with your /qa/ friends!" - }; - el = $.el('div', { - className: 'fcx-announcement' - }, announcement); - $.onExists(doc, '.boardBanner', function(banner) { - return $.after(banner, el); - }); - } - if ('samachan.org' in Conf['siteProperties'] && indexOf.call(Conf['PSAseen'], 'samachan') < 0) { - el = $.el('span', { - innerHTML: "Looking for a new home?
        Some former Samachan users are regrouping on SushiChan.

        (a message from 4chan X)" - }); - return Main.ready(function() { - new Notice('info', el); - Conf['PSAseen'].push('samachan'); - return $.set('PSAseen', Conf['PSAseen']); - }); - } - } - }; - - return PSA; - -}).call(this); - -PSAHiding = (function() { - var PSAHiding, - slice = [].slice; - - PSAHiding = { - init: function() { - if (!(Conf['Announcement Hiding'] && g.SITE.selectors.psa)) { - return; - } - $.addClass(doc, 'hide-announcement'); - $.onExists(doc, g.SITE.selectors.psa, this.setup); - return $.ready(function() { - if (!$(g.SITE.selectors.psa)) { - return $.rmClass(doc, 'hide-announcement'); - } - }); - }, - setup: function(psa) { - var btn, entry, hr, ref, ref1, ref2; - PSAHiding.psa = psa; - PSAHiding.text = (ref = psa.dataset.utc) != null ? ref : psa.innerHTML; - if (g.SITE.selectors.psaTop && (hr = (ref1 = $(g.SITE.selectors.psaTop)) != null ? ref1.previousElementSibling : void 0) && hr.nodeName === 'HR') { - PSAHiding.hr = hr; - } - PSAHiding.content = $.el('div'); - entry = { - el: $.el('a', { - textContent: 'Show announcement', - className: 'show-announcement', - href: 'javascript:;' - }), - order: 50, - open: function() { - return psa.hidden; - } - }; - Header.menu.addEntry(entry); - $.on(entry.el, 'click', PSAHiding.toggle); - PSAHiding.btn = btn = $.el('a', { - title: 'Mark announcement as read and hide.', - className: 'hide-announcement-button fa fa-minus-square', - href: 'javascript:;' - }); - $.on(btn, 'click', PSAHiding.toggle); - if (((ref2 = psa.firstChild) != null ? ref2.tagName : void 0) === 'HR') { - $.after(psa.firstChild, btn); - } else { - $.prepend(psa, btn); - } - PSAHiding.sync(Conf['hiddenPSAList']); - $.rmClass(doc, 'hide-announcement'); - return $.sync('hiddenPSAList', PSAHiding.sync); - }, - toggle: function() { - var hide, set; - hide = $.hasClass(this, 'hide-announcement-button'); - set = function(hiddenPSAList) { - if (hide) { - return hiddenPSAList[g.SITE.ID] = PSAHiding.text; - } else { - return delete hiddenPSAList[g.SITE.ID]; - } - }; - set(Conf['hiddenPSAList']); - PSAHiding.sync(Conf['hiddenPSAList']); - return $.get('hiddenPSAList', Conf['hiddenPSAList'], function(arg) { - var hiddenPSAList; - hiddenPSAList = arg.hiddenPSAList; - set(hiddenPSAList); - return $.set('hiddenPSAList', hiddenPSAList); - }); - }, - sync: function(hiddenPSAList) { - var content, psa, ref; - psa = PSAHiding.psa, content = PSAHiding.content; - psa.hidden = hiddenPSAList[g.SITE.ID] === PSAHiding.text; - if (psa.hidden) { - $.add(content, slice.call(psa.childNodes)); - } else { - $.add(psa, slice.call(content.childNodes)); - } - return (ref = PSAHiding.hr) != null ? ref.hidden = psa.hidden : void 0; - } - }; - - return PSAHiding; - -}).call(this); - -PassMessage = (function() { - var PassMessage; - - PassMessage = { - init: function() { - var close, msg; - if (Conf['passMessageClosed']) { - return; - } - msg = $.el('div', { - className: 'box-outer top-box' - }, {innerHTML: "

        Trouble buying a 4chan Pass? (a message from 4chan X) ×

        Check the 4chan X wiki for alternative solutions.
        "}); - msg.style.cssText = 'padding-bottom: 0;'; - close = $('a', msg); - $.on(close, 'click', function() { - $.rm(msg); - return $.set('passMessageClosed', true); - }); - return $.ready(function() { - var hd; - if ((hd = $.id('hd'))) { - return $.after(hd, msg); - } else { - return $.prepend(d.body, msg); - } - }); - } - }; - - return PassMessage; - -}).call(this); - -PostJumper = (function() { - var PostJumper; - - PostJumper = { - init: function() { - var ref; - if (!(Conf['Unique ID and Capcode Navigation'] && ((ref = g.VIEW) === 'index' || ref === 'thread'))) { - return; - } - this.buttons = this.makeButtons(); - return Callbacks.Post.push({ - name: 'Post Jumper', - cb: this.node - }); - }, - node: function() { - var buttons, i, len, ref; - if (this.isClone) { - ref = $$('.postJumper', this.nodes.info); - for (i = 0, len = ref.length; i < len; i++) { - buttons = ref[i]; - PostJumper.addListeners(buttons); - } - return; - } - if (this.nodes.uniqueIDRoot) { - PostJumper.addButtons(this, 'uniqueID'); - } - if (this.nodes.capcode) { - return PostJumper.addButtons(this, 'capcode'); - } - }, - addButtons: function(post, type) { - var buttons, value; - value = post.info[type]; - buttons = PostJumper.buttons.cloneNode(true); - $.extend(buttons.dataset, { - type: type, - value: value - }); - $.after(post.nodes[type + (type === 'capcode' ? '' : 'Root')], buttons); - return PostJumper.addListeners(buttons); - }, - addListeners: function(buttons) { - $.on(buttons.firstChild, 'click', PostJumper.buttonClick); - return $.on(buttons.lastChild, 'click', PostJumper.buttonClick); - }, - buttonClick: function() { - var dir, toJumper; - dir = $.hasClass(this, 'prev') ? -1 : 1; - if ((toJumper = PostJumper.find(this.parentNode, dir))) { - return PostJumper.scroll(this.parentNode, toJumper); - } - }, - find: function(jumper, dir) { - var axis, jumper2, ref, type, value, xpath; - ref = jumper.dataset, type = ref.type, value = ref.value; - xpath = "span[contains(@class,\"postJumper\") and @data-value=\"" + value + "\" and @data-type=\"" + type + "\"]"; - axis = dir < 0 ? 'preceding' : 'following'; - jumper2 = jumper; - while ((jumper2 = $.x(axis + "::" + xpath, jumper2))) { - if (jumper2.getBoundingClientRect().height) { - return jumper2; - } - } - if ((jumper2 = $.x("(//" + xpath + ")[" + (dir < 0 ? 'last()' : '1') + "]"))) { - if (jumper2.getBoundingClientRect().height) { - return jumper2; - } - } - while ((jumper2 = $.x(axis + "::" + xpath, jumper2)) && jumper2 !== jumper) { - if (jumper2.getBoundingClientRect().height) { - return jumper2; - } - } - return null; - }, - makeButtons: function() { - var charNext, charPrev, classNext, classPrev, span; - charPrev = '\u23EB'; - charNext = '\u23EC'; - classPrev = 'prev'; - classNext = 'next'; - span = $.el('span', { - className: 'postJumper' - }); - $.extend(span, {innerHTML: "" + E(charPrev) + "" + E(charNext) + ""}); - return span; - }, - scroll: function(fromJumper, toJumper) { - var destPos, prevPos; - prevPos = fromJumper.getBoundingClientRect().top; - destPos = toJumper.getBoundingClientRect().top; - return window.scrollBy(0, destPos - prevPos); - } - }; - - return PostJumper; - -}).call(this); - -RelativeDates = (function() { - var RelativeDates, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - RelativeDates = { - INTERVAL: $.MINUTE / 2, - init: function() { - var ref; - if (((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Relative Post Dates'] && !Conf['Relative Date Title'] || Index.enabled) { - this.flush(); - $.on(d, 'visibilitychange PostsInserted', this.flush); - } - if (Conf['Relative Post Dates']) { - return Callbacks.Post.push({ - name: 'Relative Post Dates', - cb: this.node - }); - } - }, - node: function() { - var dateEl; - if (!this.info.date) { - return; - } - dateEl = this.nodes.date; - if (Conf['Relative Date Title']) { - $.on(dateEl, 'mouseover', (function(_this) { - return function() { - return RelativeDates.hover(_this); - }; - })(this)); - return; - } - if (this.isClone) { - return; - } - dateEl.title = dateEl.textContent; - return RelativeDates.update(this); - }, - relative: function(diff, now, date, abbrev) { - var days, months, number, rounded, unit, years; - unit = (number = diff / $.DAY) >= 1 ? (years = now.getFullYear() - date.getFullYear(), months = now.getMonth() - date.getMonth(), days = now.getDate() - date.getDate(), years > 1 ? (number = years - (months < 0 || months === 0 && days < 0), 'year') : years === 1 && (months > 0 || months === 0 && days >= 0) ? (number = years, 'year') : (months = months + 12 * years) > 1 ? (number = months - (days < 0), 'month') : months === 1 && days >= 0 ? (number = months, 'month') : 'day') : (number = diff / $.HOUR) >= 1 ? 'hour' : (number = diff / $.MINUTE) >= 1 ? 'minute' : (number = Math.max(0, diff) / $.SECOND, 'second'); - rounded = Math.round(number); - if (abbrev) { - unit = unit === 'month' ? 'mo' : unit[0]; - } else { - if (rounded !== 1) { - unit += 's'; - } - } - if (abbrev) { - return "" + rounded + unit; - } else { - return rounded + " " + unit + " ago"; - } - }, - stale: [], - flush: function() { - var data, i, len, now, ref; - if (d.hidden) { - return; - } - now = new Date(); - ref = RelativeDates.stale; - for (i = 0, len = ref.length; i < len; i++) { - data = ref[i]; - RelativeDates.update(data, now); - } - RelativeDates.stale = []; - clearTimeout(RelativeDates.timeout); - return RelativeDates.timeout = setTimeout(RelativeDates.flush, RelativeDates.INTERVAL); - }, - hover: function(post) { - var date, diff, now; - date = post.info.date; - now = new Date(); - diff = now - date; - return post.nodes.date.title = RelativeDates.relative(diff, now, date); - }, - update: function(data, now) { - var abbrev, date, diff, i, isPost, len, ref, relative, singlePost; - isPost = data instanceof Post; - if (isPost) { - date = data.info.date; - abbrev = false; - } else { - date = new Date(+data.dataset.utc); - abbrev = !!data.dataset.abbrev; - } - now || (now = new Date()); - diff = now - date; - relative = RelativeDates.relative(diff, now, date, abbrev); - if (isPost) { - ref = [data].concat(data.clones); - for (i = 0, len = ref.length; i < len; i++) { - singlePost = ref[i]; - singlePost.nodes.date.firstChild.textContent = relative; - } - } else { - data.firstChild.textContent = relative; - } - return RelativeDates.setOwnTimeout(diff, data); - }, - setOwnTimeout: function(diff, data) { - var delay; - delay = diff < $.MINUTE ? $.SECOND - (diff + $.SECOND / 2) % $.SECOND : diff < $.HOUR ? $.MINUTE - (diff + $.MINUTE / 2) % $.MINUTE : diff < $.DAY ? $.HOUR - (diff + $.HOUR / 2) % $.HOUR : $.DAY - (diff + $.DAY / 2) % $.DAY; - return setTimeout(RelativeDates.markStale, delay, data); - }, - markStale: function(data) { - if (indexOf.call(RelativeDates.stale, data) >= 0) { - return; - } - if (data instanceof Post && !g.posts.get(data.fullID)) { - return; - } - if (data instanceof Element && !doc.contains(data)) { - return; - } - return RelativeDates.stale.push(data); - } - }; - - return RelativeDates; - -}).call(this); - -RemoveSpoilers = (function() { - var RemoveSpoilers, - slice = [].slice; - - RemoveSpoilers = { - init: function() { - if (Conf['Reveal Spoilers']) { - $.addClass(doc, 'reveal-spoilers'); - } - if (!Conf['Remove Spoilers']) { - return; - } - Callbacks.Post.push({ - name: 'Reveal Spoilers', - cb: this.node - }); - if (g.VIEW === 'archive') { - return $.ready(function() { - return RemoveSpoilers.unspoiler($.id('arc-list')); - }); - } - }, - node: function() { - return RemoveSpoilers.unspoiler(this.nodes.comment); - }, - unspoiler: function(el) { - var i, len, span, spoiler, spoilers; - spoilers = $$(g.SITE.selectors.spoiler, el); - for (i = 0, len = spoilers.length; i < len; i++) { - spoiler = spoilers[i]; - span = $.el('span', { - className: 'removed-spoiler' - }); - $.replace(spoiler, span); - $.add(span, slice.call(spoiler.childNodes)); - } - } - }; - - return RemoveSpoilers; - -}).call(this); - -Report = (function() { - var Report; - - Report = { - init: function() { - var match; - if (!(match = location.search.match(/\bno=(\d+)/))) { - return; - } - Captcha.replace.init(); - this.postID = +match[1]; - return $.ready(this.ready); - }, - ready: function() { - $.addStyle(CSS.report); - if (Conf['Archive Report']) { - Report.archive(); - } - new MutationObserver(function() { - Report.fit('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); - return Report.fit('body'); - }).observe(d.body, { - childList: true, - attributes: true, - subtree: true - }); - return Report.fit('body'); - }, - fit: function(selector) { - var dy, el; - if (!((el = $(selector, doc)) && getComputedStyle(el).visibility !== 'hidden')) { - return; - } - dy = el.getBoundingClientRect().bottom - doc.clientHeight + 8; - if (dy > 0) { - return window.resizeBy(0, dy); - } - }, - archive: function() { - var enabled, fieldset, form, match, message, reason, submit, types, urls; - if (!(urls = Redirect.report(g.BOARD.ID)).length) { - return; - } - form = $('form'); - types = $.id('reportTypes'); - message = $('h3'); - fieldset = $.el('fieldset', { - id: 'archive-report', - hidden: true - }, {innerHTML: ""}); - enabled = $('#archive-report-enabled', fieldset); - reason = $('#archive-report-reason', fieldset); - submit = $('#archive-report-submit', fieldset); - $.on(enabled, 'change', function() { - return reason.disabled = !this.checked; - }); - if (form && types) { - fieldset.hidden = !$('[value="31"]', types).checked; - $.on(types, 'change', function(e) { - fieldset.hidden = e.target.value !== '31'; - return Report.fit('body'); - }); - $.after(types, fieldset); - Report.fit('body'); - $.one(form, 'submit', function(e) { - if (!fieldset.hidden && enabled.checked) { - e.preventDefault(); - return Report.archiveSubmit(urls, reason.value, (function(_this) { - return function(results) { - _this.action = '#archiveresults=' + encodeURIComponent(JSON.stringify(results)); - return _this.submit(); - }; - })(this)); - } - }); - } else if (message) { - fieldset.hidden = /Report submitted!/.test(message.textContent); - $.on(enabled, 'change', function() { - return submit.hidden = !this.checked; - }); - $.after(message, fieldset); - $.on(submit, 'click', function() { - return Report.archiveSubmit(urls, reason.value, Report.archiveResults); - }); - } - if ((match = location.hash.match(/^#archiveresults=(.*)$/))) { - try { - return Report.archiveResults(JSON.parse(decodeURIComponent(match[1]))); - } catch (error) {} - } - }, - archiveSubmit: function(urls, reason, cb) { - var fn, form, i, len, name, ref, results, url; - form = $.formData({ - board: g.BOARD.ID, - num: Report.postID, - reason: reason - }); - results = []; - fn = function(name, url) { - return $.ajax(url, { - onloadend: function() { - results.push([ - name, this.response || { - error: '' - } - ]); - if (results.length === urls.length) { - return cb(results); - } - }, - form: form - }); - }; - for (i = 0, len = urls.length; i < len; i++) { - ref = urls[i], name = ref[0], url = ref[1]; - fn(name, url); - } - }, - archiveResults: function(results) { - var fieldset, i, len, line, name, ref, response; - fieldset = $.id('archive-report'); - for (i = 0, len = results.length; i < len; i++) { - ref = results[i], name = ref[0], response = ref[1]; - line = $.el('h3', { - className: 'archive-report-response' - }); - if ('success' in response) { - $.addClass(line, 'archive-report-success'); - line.textContent = name + ": " + response.success; - } else { - $.addClass(line, 'archive-report-error'); - line.textContent = name + ": " + (response.error || 'Error reporting post.'); - } - if (fieldset) { - $.before(fieldset, line); - } else { - $.add(d.body, line); - } - } - } - }; - - return Report; - -}).call(this); - -ThreadLinks = (function() { - var ThreadLinks; - - ThreadLinks = { - init: function() { - if (!(g.VIEW === 'index' && Conf['Open Threads in New Tab'])) { - return; - } - Callbacks.Post.push({ - name: 'Thread Links', - cb: this.node - }); - return Callbacks.CatalogThread.push({ - name: 'Thread Links', - cb: this.catalogNode - }); - }, - node: function() { - if (this.isReply || this.isClone) { - return; - } - return ThreadLinks.process(this.nodes.reply); - }, - catalogNode: function() { - return ThreadLinks.process(this.nodes.thumb.parentNode); - }, - process: function(link) { - return link.target = '_blank'; - } - }; - - return ThreadLinks; - -}).call(this); - -Time = (function() { - var Time; - - Time = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Time Formatting'])) { - return; - } - return Callbacks.Post.push({ - name: 'Time Formatting', - cb: this.node - }); - }, - node: function() { - var textContent; - if (!this.info.date || this.isClone) { - return; - } - textContent = this.nodes.date.textContent; - return this.nodes.date.textContent = textContent.match(/^\s*/)[0] + Time.format(Conf['time'], this.info.date) + textContent.match(/\s*$/)[0]; - }, - format: function(formatString, date) { - return formatString.replace(/%(.)/g, function(s, c) { - if ($.hasOwn(Time.formatters, c)) { - return Time.formatters[c].call(date); - } else { - return s; - } - }); - }, - day: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], - month: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], - localeFormat: function(date, options, defaultValue) { - if (Conf['timeLocale']) { - try { - return Intl.DateTimeFormat(Conf['timeLocale'], options).format(date); - } catch (error) {} - } - return defaultValue; - }, - localeFormatPart: function(date, options, part, defaultValue) { - var parts; - if (Conf['timeLocale']) { - try { - parts = Intl.DateTimeFormat(Conf['timeLocale'], options).formatToParts(date); - return parts.map(function(x) { - if (x.type === part) { - return x.value; - } else { - return ''; - } - }).join(''); - } catch (error) {} - } - return defaultValue; - }, - zeroPad: function(n) { - if (n < 10) { - return "0" + n; - } else { - return n; - } - }, - formatters: { - a: function() { - return Time.localeFormat(this, { - weekday: 'short' - }, Time.day[this.getDay()].slice(0, 3)); - }, - A: function() { - return Time.localeFormat(this, { - weekday: 'long' - }, Time.day[this.getDay()]); - }, - b: function() { - return Time.localeFormat(this, { - month: 'short' - }, Time.month[this.getMonth()].slice(0, 3)); - }, - B: function() { - return Time.localeFormat(this, { - month: 'long' - }, Time.month[this.getMonth()]); - }, - d: function() { - return Time.zeroPad(this.getDate()); - }, - e: function() { - return this.getDate(); - }, - H: function() { - return Time.zeroPad(this.getHours()); - }, - I: function() { - return Time.zeroPad(this.getHours() % 12 || 12); - }, - k: function() { - return this.getHours(); - }, - l: function() { - return this.getHours() % 12 || 12; - }, - m: function() { - return Time.zeroPad(this.getMonth() + 1); - }, - M: function() { - return Time.zeroPad(this.getMinutes()); - }, - p: function() { - return Time.localeFormatPart(this, { - hour: 'numeric', - hour12: true - }, 'dayperiod', (this.getHours() < 12 ? 'AM' : 'PM')); - }, - P: function() { - return Time.formatters.p.call(this).toLowerCase(); - }, - S: function() { - return Time.zeroPad(this.getSeconds()); - }, - y: function() { - return this.getFullYear().toString().slice(2); - }, - Y: function() { - return this.getFullYear(); - }, - '%': function() { - return '%'; - } - } - }; - - return Time; - -}).call(this); - -Tinyboard = (function() { - var Tinyboard; - - Tinyboard = { - init: function() { - if (g.SITE.software !== 'tinyboard') { - return; - } - if (g.VIEW === 'thread') { - return Main.ready(function() { - return $.global(function() { - var base, boardID, form, originalNoko, ref, ref1, ref2, threadID; - ref = document.currentScript.dataset, boardID = ref.boardID, threadID = ref.threadID; - threadID = +threadID; - form = document.querySelector('form[name="post"]'); - window.$(document).ajaxComplete(function(event, request, settings) { - var detail, noko, postID, redirect, ref1, ref2; - if (settings.url !== form.action) { - return; - } - if (!(postID = +((ref1 = request.responseJSON) != null ? ref1.id : void 0))) { - return; - } - detail = { - boardID: boardID, - threadID: threadID, - postID: postID - }; - try { - ref2 = request.responseJSON, redirect = ref2.redirect, noko = ref2.noko; - if (redirect && (typeof originalNoko !== "undefined" && originalNoko !== null) && !originalNoko && !noko) { - detail.redirect = redirect; - } - } catch (error) {} - event = new CustomEvent('QRPostSuccessful', { - bubbles: true, - detail: detail - }); - return document.dispatchEvent(event); - }); - originalNoko = (ref1 = window.tb_settings) != null ? (ref2 = ref1.ajax) != null ? ref2.always_noko_replies : void 0 : void 0; - return ((base = (window.tb_settings || (window.tb_settings = {}))).ajax || (base.ajax = {})).always_noko_replies = true; - }, { - boardID: g.BOARD.ID, - threadID: g.THREADID - }); - }); - } - } - }; - - return Tinyboard; - -}).call(this); - -Favicon = (function() { - var Favicon; - - Favicon = { - init: function() { - return $.asap((function() { - return d.head && (Favicon.el = $('link[rel="shortcut icon"]', d.head)); - }), Favicon.initAsap); - }, - set: function(status) { - Favicon.status = status; - if (Favicon.el) { - Favicon.el.href = Favicon[status]; - return $.add(d.head, Favicon.el); - } - }, - initAsap: function() { - var href; - Favicon.el.type = 'image/x-icon'; - href = Favicon.el.href; - Favicon.isSFW = /ws\.ico$/.test(href); - Favicon["default"] = href; - Favicon["switch"](); - if (Favicon.status) { - return Favicon.set(Favicon.status); - } - }, - "switch": function() { - var f, i, items, t; - items = { - 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: ['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'], - '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='] - }; - items = $.getOwn(items, Conf['favicon']); - f = Favicon; - t = 'data:image/png;base64,'; - i = 0; - while (items[i]) { - items[i] = t + items[i++]; - } - f.unreadDead = items[0], f.unreadDeadY = items[1], f.unreadSFW = items[2], f.unreadSFWY = items[3], f.unreadNSFW = items[4], f.unreadNSFWY = items[5]; - return f.update(); - }, - update: function() { - if (this.isSFW) { - this.unread = this.unreadSFW; - return this.unreadY = this.unreadSFWY; - } else { - this.unread = this.unreadNSFW; - return 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,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAgMAAAC+UIlYAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAGlJREFUWMPtlkEKADEIA/tJP9lXLttQto2yHxgDHozTi0ToGK2WKZZ+HAQQMZc+xBwI4EZ+wAC2IfPuSIDOZJrSZQEAX9eVJhhwIuUYAnQe8rhAEMAZlTI2MID9f5Clyh0JeE1V1ZEAvB4qDfwuJTSGRAAAAABJRU5ErkJggg==' - }; - - return Favicon; - -}).call(this); - -MarkNewIPs = (function() { - var MarkNewIPs; - - MarkNewIPs = { - init: function() { - if (!(g.SITE.software === 'yotsuba' && g.VIEW === 'thread' && Conf['Mark New IPs'])) { - return; - } - return Callbacks.Thread.push({ - name: 'Mark New IPs', - cb: this.node - }); - }, - node: function() { - MarkNewIPs.ipCount = this.ipCount; - MarkNewIPs.postCount = this.posts.keys.length; - return $.on(d, 'ThreadUpdate', MarkNewIPs.onUpdate); - }, - onUpdate: function(e) { - var deletedPosts, fullID, i, ipCount, j, k, len, len1, newPosts, postCount, ref; - ref = e.detail, ipCount = ref.ipCount, postCount = ref.postCount, newPosts = ref.newPosts, deletedPosts = ref.deletedPosts; - if (ipCount == null) { - return; - } - switch (ipCount - MarkNewIPs.ipCount) { - case postCount - MarkNewIPs.postCount + deletedPosts.length: - i = MarkNewIPs.ipCount; - for (j = 0, len = newPosts.length; j < len; j++) { - fullID = newPosts[j]; - MarkNewIPs.markNew(g.posts.get(fullID), ++i); - } - break; - case -deletedPosts.length: - for (k = 0, len1 = newPosts.length; k < len1; k++) { - fullID = newPosts[k]; - MarkNewIPs.markOld(g.posts.get(fullID)); - } - } - MarkNewIPs.ipCount = ipCount; - return MarkNewIPs.postCount = postCount; - }, - markNew: function(post, ipCount) { - var counter, suffix; - suffix = (Math.floor(ipCount / 10)) % 10 === 1 ? 'th' : ['st', 'nd', 'rd'][ipCount % 10 - 1] || 'th'; - counter = $.el('span', { - className: 'ip-counter', - textContent: "(" + ipCount + ")" - }); - post.nodes.nameBlock.title = "This is the " + ipCount + suffix + " IP in the thread."; - $.add(post.nodes.nameBlock, [$.tn(' '), counter]); - return $.addClass(post.nodes.root, 'new-ip'); - }, - markOld: function(post) { - post.nodes.nameBlock.title = 'Not the first post from this IP.'; - return $.addClass(post.nodes.root, 'old-ip'); - } - }; - - return MarkNewIPs; - -}).call(this); - -ReplyPruning = (function() { - var ReplyPruning; - - ReplyPruning = { - init: function() { - var el, label; - if (!(g.VIEW === 'thread' && Conf['Reply Pruning'])) { - return; - } - this.container = $.frag(); - this.summary = $.el('span', { - hidden: true, - className: 'summary' - }); - this.summary.style.cursor = 'pointer'; - $.on(this.summary, 'click', (function(_this) { - return function() { - _this.inputs.enabled.checked = !_this.inputs.enabled.checked; - return $.event('change', null, _this.inputs.enabled); - }; - })(this)); - label = UI.checkbox('Prune Replies', 'Show Last', Conf['Prune All Threads']); - el = $.el('span', { - title: 'Maximum number of replies to show.' - }, {innerHTML: " "}); - $.prepend(el, label); - this.inputs = { - enabled: label.firstElementChild, - replies: el.lastElementChild - }; - this.setEnabled.call(this.inputs.enabled); - $.on(this.inputs.enabled, 'change', this.setEnabled); - $.on(this.inputs.replies, 'change', $.cb.value); - Header.menu.addEntry({ - el: el, - order: 190 - }); - return Callbacks.Thread.push({ - name: 'Reply Pruning', - cb: this.node - }); - }, - position: 0, - hidden: 0, - hiddenFiles: 0, - total: 0, - totalFiles: 0, - setEnabled: function() { - var other; - other = QuoteThreading.input; - if (this.checked && (other != null ? other.checked : void 0)) { - other.checked = false; - $.event('change', null, other); - } - return ReplyPruning.active = this.checked; - }, - showIfHidden: function(id) { - if (ReplyPruning.container && $("#" + id, ReplyPruning.container)) { - ReplyPruning.inputs.enabled.checked = false; - return $.event('change', null, ReplyPruning.inputs.enabled); - } - }, - node: function() { - var ref; - ReplyPruning.thread = this; - if (this.isSticky) { - ReplyPruning.active = ReplyPruning.inputs.enabled.checked = true; - if (QuoteThreading.input) { - Conf['Thread Quotes'] = QuoteThreading.input.checked = false; - } - } - this.posts.forEach(function(post) { - if (post.isReply) { - ReplyPruning.total++; - if (post.file) { - return ReplyPruning.totalFiles++; - } - } - }); - if (ReplyPruning.active && /^#p\d+$/.test(location.hash) && (1 <= (ref = this.posts.keys.indexOf(location.hash.slice(2))) && ref < 1 + Math.max(ReplyPruning.total - +Conf["Max Replies"], 0))) { - ReplyPruning.active = ReplyPruning.inputs.enabled.checked = false; - } - $.after(this.OP.nodes.root, ReplyPruning.summary); - $.on(ReplyPruning.inputs.enabled, 'change', ReplyPruning.update); - $.on(ReplyPruning.inputs.replies, 'change', ReplyPruning.update); - $.on(d, 'ThreadUpdate', ReplyPruning.updateCount); - $.on(d, 'ThreadUpdate', ReplyPruning.update); - return ReplyPruning.update(); - }, - updateCount: function(e) { - var fullID, i, len, ref; - if (e.detail[404]) { - return; - } - ref = e.detail.newPosts; - for (i = 0, len = ref.length; i < len; i++) { - fullID = ref[i]; - ReplyPruning.total++; - if (g.posts.get(fullID).file) { - ReplyPruning.totalFiles++; - } - } - }, - update: function() { - var boardTop, frag, hidden1, hidden2, node, oldPos, post, posts; - hidden1 = ReplyPruning.hidden; - hidden2 = ReplyPruning.active ? Math.max(ReplyPruning.total - +Conf["Max Replies"], 0) : 0; - oldPos = d.body.clientHeight - window.scrollY; - posts = ReplyPruning.thread.posts; - if (ReplyPruning.hidden < hidden2) { - while (ReplyPruning.hidden < hidden2 && ReplyPruning.position < posts.keys.length) { - post = posts.get(posts.keys[ReplyPruning.position++]); - if (post.isReply && !post.isFetchedQuote) { - while ((node = ReplyPruning.summary.nextSibling) && node !== post.nodes.root) { - $.add(ReplyPruning.container, node); - } - $.add(ReplyPruning.container, post.nodes.root); - ReplyPruning.hidden++; - if (post.file) { - ReplyPruning.hiddenFiles++; - } - } - } - } else if (ReplyPruning.hidden > hidden2) { - frag = $.frag(); - while (ReplyPruning.hidden > hidden2 && ReplyPruning.position > 0) { - post = posts.get(posts.keys[--ReplyPruning.position]); - if (post.isReply && !post.isFetchedQuote) { - while ((node = ReplyPruning.container.lastChild) && node !== post.nodes.root) { - $.prepend(frag, node); - } - $.prepend(frag, post.nodes.root); - ReplyPruning.hidden--; - if (post.file) { - ReplyPruning.hiddenFiles--; - } - } - } - $.after(ReplyPruning.summary, frag); - $.event('PostsInserted', null, ReplyPruning.summary.parentNode); - } - ReplyPruning.summary.textContent = ReplyPruning.active ? g.SITE.Build.summaryText('+', ReplyPruning.hidden, ReplyPruning.hiddenFiles) : g.SITE.Build.summaryText('-', ReplyPruning.total, ReplyPruning.totalFiles); - ReplyPruning.summary.hidden = ReplyPruning.total <= +Conf["Max Replies"]; - if (hidden1 !== hidden2 && (boardTop = Header.getTopOf($('.board'))) < 0) { - return window.scrollBy(0, Math.max(d.body.clientHeight - oldPos, window.scrollY + boardTop) - window.scrollY); - } - } - }; - - return ReplyPruning; - -}).call(this); - -ThreadStats = (function() { - var ThreadStats; - - ThreadStats = { - postCount: 0, - fileCount: 0, - postIndex: 0, - init: function() { - var base, sc, statsHTML, statsTitle; - if (g.VIEW !== 'thread' || !Conf['Thread Stats']) { - return; - } - if (Conf['Page Count in Stats']) { - this[(typeof (base = g.SITE).isPrunedByAge === "function" ? base.isPrunedByAge(g.BOARD) : void 0) ? 'showPurgePos' : 'showPage'] = true; - } - statsHTML = {innerHTML: "? / ?" + ((Conf["IP Count in Stats"] && g.SITE.hasIPCount) ? " / ?" : "") + ((Conf["Page Count in Stats"]) ? " / ?" : "")}; - statsTitle = 'Posts / Files'; - if (Conf['IP Count in Stats'] && g.SITE.hasIPCount) { - statsTitle += ' / IPs'; - } - if (Conf['Page Count in Stats']) { - statsTitle += (this.showPurgePos ? ' / Purge Position' : ' / Page'); - } - if (Conf['Updater and Stats in Header']) { - this.dialog = sc = $.el('span', { - id: 'thread-stats', - title: statsTitle - }); - $.extend(sc, statsHTML); - Header.addShortcut('stats', sc, 200); - } else { - this.dialog = sc = UI.dialog('thread-stats', {innerHTML: "
        " + (statsHTML).innerHTML + "
        "}); - $.addClass(doc, 'float'); - $.ready(function() { - return $.add(d.body, sc); - }); - } - this.postCountEl = $('#post-count', sc); - this.fileCountEl = $('#file-count', sc); - this.ipCountEl = $('#ip-count', sc); - this.pageCountEl = $('#page-count', sc); - if (this.pageCountEl) { - $.on(this.pageCountEl, 'click', ThreadStats.fetchPage); - } - return Callbacks.Thread.push({ - name: 'Thread Stats', - cb: this.node - }); - }, - node: function() { - ThreadStats.thread = this; - ThreadStats.count(); - ThreadStats.update(); - ThreadStats.fetchPage(); - $.on(d, 'PostsInserted', function() { - return $.queueTask(ThreadStats.onPostsInserted); - }); - return $.on(d, 'ThreadUpdate', ThreadStats.onUpdate); - }, - count: function() { - var i, j, n, post, posts, ref, ref1; - posts = ThreadStats.thread.posts; - n = posts.keys.length; - for (i = j = ref = ThreadStats.postIndex, ref1 = n; j < ref1; i = j += 1) { - post = posts.get(posts.keys[i]); - if (!post.isFetchedQuote) { - ThreadStats.postCount++; - ThreadStats.fileCount += post.files.length; - } - } - return ThreadStats.postIndex = n; - }, - onUpdate: function(e) { - var fileCount, postCount, ref; - if (e.detail[404]) { - return; - } - ref = e.detail, postCount = ref.postCount, fileCount = ref.fileCount; - $.extend(ThreadStats, { - postCount: postCount, - fileCount: fileCount - }); - ThreadStats.postIndex = ThreadStats.thread.posts.keys.length; - ThreadStats.update(); - if (ThreadStats.showPage && ThreadStats.pageCountEl.textContent !== '1') { - return ThreadStats.fetchPage(); - } - }, - onPostsInserted: function() { - if (!(ThreadStats.thread.posts.keys.length > ThreadStats.postIndex)) { - return; - } - ThreadStats.count(); - ThreadStats.update(); - if (ThreadStats.showPage && ThreadStats.pageCountEl.textContent !== '1') { - return ThreadStats.fetchPage(); - } - }, - update: function() { - var fileCountEl, ipCountEl, postCountEl, ref, thread; - thread = ThreadStats.thread, postCountEl = ThreadStats.postCountEl, fileCountEl = ThreadStats.fileCountEl, ipCountEl = ThreadStats.ipCountEl; - postCountEl.textContent = ThreadStats.postCount; - fileCountEl.textContent = ThreadStats.fileCount; - if (ipCountEl != null) { - ipCountEl.textContent = (ref = thread.ipCount) != null ? ref : '?'; - } - postCountEl.classList.toggle('warning', thread.postLimit && !thread.isSticky); - return fileCountEl.classList.toggle('warning', thread.fileLimit && !thread.isSticky); - }, - fetchPage: function() { - if (!ThreadStats.pageCountEl) { - return; - } - clearTimeout(ThreadStats.timeout); - if (ThreadStats.thread.isDead) { - ThreadStats.pageCountEl.textContent = 'Dead'; - $.addClass(ThreadStats.pageCountEl, 'warning'); - return; - } - ThreadStats.timeout = setTimeout(ThreadStats.fetchPage, 2 * $.MINUTE); - return $.whenModified(g.SITE.urls.threadsListJSON(ThreadStats.thread), 'ThreadStats', ThreadStats.onThreadsLoad); - }, - onThreadsLoad: function() { - var i, j, k, l, len, len1, len2, len3, len4, m, nThreads, o, page, pageNum, purgePos, ref, ref1, ref2, ref3, ref4, thread; - if (this.status === 200) { - if (ThreadStats.showPurgePos) { - purgePos = 1; - ref = this.response; - for (j = 0, len = ref.length; j < len; j++) { - page = ref[j]; - ref1 = page.threads; - for (k = 0, len1 = ref1.length; k < len1; k++) { - thread = ref1[k]; - if (thread.no < ThreadStats.thread.ID) { - purgePos++; - } - } - } - ThreadStats.pageCountEl.textContent = purgePos; - return ThreadStats.pageCountEl.classList.toggle('warning', purgePos === 1); - } else { - i = nThreads = 0; - ref2 = this.response; - for (l = 0, len2 = ref2.length; l < len2; l++) { - page = ref2[l]; - nThreads += page.threads.length; - } - ref3 = this.response; - for (pageNum = m = 0, len3 = ref3.length; m < len3; pageNum = ++m) { - page = ref3[pageNum]; - ref4 = page.threads; - for (o = 0, len4 = ref4.length; o < len4; o++) { - thread = ref4[o]; - if (thread.no === ThreadStats.thread.ID) { - ThreadStats.pageCountEl.textContent = pageNum + 1; - ThreadStats.pageCountEl.classList.toggle('warning', i >= nThreads - this.response[0].threads.length); - ThreadStats.lastPageUpdate = new Date(thread.last_modified * $.SECOND); - ThreadStats.retry(); - return; - } - i++; - } - } - } - } else if (this.status === 304) { - return ThreadStats.retry(); - } - }, - retry: function() { - if (!(ThreadStats.showPage && ThreadStats.pageCountEl.textContent !== '1' && !g.SITE.threadModTimeIgnoresSage && ThreadStats.thread.posts.get(ThreadStats.thread.lastPost).info.date > ThreadStats.lastPageUpdate)) { - return; - } - clearTimeout(ThreadStats.timeout); - return ThreadStats.timeout = setTimeout(ThreadStats.fetchPage, 5 * $.SECOND); - } - }; - - return ThreadStats; - -}).call(this); - -ThreadUpdater = (function() { - var ThreadUpdater, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - ThreadUpdater = { - init: function() { - var conf, el, input, name, ref, sc, subEntries, updateLink; - if (g.VIEW !== 'thread' || !Conf['Thread Updater']) { - return; - } - this.enabled = true; - this.audio = $.el('audio'); - if ($.engine !== 'gecko') { - this.audio.src = this.beep; - } - if (Conf['Updater and Stats in Header']) { - this.dialog = sc = $.el('span', { - id: 'updater' - }); - $.extend(sc, {innerHTML: ""}); - Header.addShortcut('updater', sc, 100); - } else { - this.dialog = sc = UI.dialog('updater', {innerHTML: "
        "}); - $.addClass(doc, 'float'); - $.ready(function() { - return $.add(d.body, sc); - }); - } - this.checkPostCount = 0; - this.timer = $('#update-timer', sc); - this.status = $('#update-status', sc); - $.on(this.timer, 'click', this.update); - $.on(this.status, 'click', this.update); - updateLink = $.el('span', { - className: 'brackets-wrap updatelink' - }); - $.extend(updateLink, {innerHTML: "Update"}); - Main.ready(function() { - var navLinksBot; - if ((navLinksBot = $('.navLinksBot'))) { - return $.add(navLinksBot, [$.tn(' '), updateLink]); - } - }); - $.on(updateLink.firstElementChild, 'click', this.update); - subEntries = []; - ref = Config.updater.checkbox; - for (name in ref) { - conf = ref[name]; - el = UI.checkbox(name, name); - el.title = conf[1]; - input = el.firstElementChild; - $.on(input, 'change', $.cb.checked); - if (input.name === 'Scroll BG') { - $.on(input, 'change', this.cb.scrollBG); - this.cb.scrollBG(); - } else if (input.name === 'Auto Update') { - $.on(input, 'change', this.setInterval); - } - subEntries.push({ - el: el - }); - } - this.settings = $.el('span', {innerHTML: "Interval"}); - $.on(this.settings, 'click', this.intervalShortcut); - subEntries.push({ - el: this.settings - }); - Header.menu.addEntry(this.entry = { - el: $.el('span', { - textContent: 'Updater' - }), - order: 110, - subEntries: subEntries - }); - return Callbacks.Thread.push({ - name: 'Thread Updater', - cb: this.node - }); - }, - node: function() { - ThreadUpdater.thread = this; - ThreadUpdater.root = this.nodes.root; - ThreadUpdater.outdateCount = 0; - ThreadUpdater.postIDs = []; - ThreadUpdater.fileIDs = []; - this.posts.forEach(function(post) { - ThreadUpdater.postIDs.push(post.ID); - if (post.file) { - return ThreadUpdater.fileIDs.push(post.ID); - } - }); - ThreadUpdater.cb.interval.call($.el('input', { - value: Conf['Interval'] - })); - $.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost); - $.on(d, 'visibilitychange', ThreadUpdater.cb.visibility); - return ThreadUpdater.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: function() { - var audio; - audio = ThreadUpdater.audio; - audio.src || (audio.src = ThreadUpdater.beep); - if (audio.paused) { - return audio.play(); - } else { - return $.one(audio, 'ended', ThreadUpdater.playBeep); - } - }, - cb: { - checkpost: function(e) { - if (e.detail.threadID !== ThreadUpdater.thread.ID) { - return; - } - ThreadUpdater.postID = e.detail.postID; - ThreadUpdater.checkPostCount = 0; - ThreadUpdater.outdateCount = 0; - return ThreadUpdater.setInterval(); - }, - visibility: function() { - if (d.hidden) { - return; - } - ThreadUpdater.outdateCount = 0; - if (ThreadUpdater.seconds > ThreadUpdater.interval) { - return ThreadUpdater.setInterval(); - } - }, - scrollBG: function() { - return ThreadUpdater.scrollBG = Conf['Scroll BG'] ? function() { - return true; - } : function() { - return !d.hidden; - }; - }, - interval: function(e) { - var val; - val = parseInt(this.value, 10); - if (val < 1) { - val = 1; - } - ThreadUpdater.interval = this.value = val; - if (e) { - return $.cb.value.call(this); - } - }, - load: function() { - if (this !== ThreadUpdater.req) { - return; - } - switch (this.status) { - case 200: - ThreadUpdater.parse(this); - if (ThreadUpdater.thread.isArchived) { - return ThreadUpdater.kill(); - } else { - return ThreadUpdater.setInterval(); - } - break; - case 404: - return $.ajax(g.SITE.urls.catalogJSON({ - boardID: ThreadUpdater.thread.board.ID - }), { - onloadend: function() { - var confirmed, i, k, len, len1, page, ref, ref1, thread; - if (this.status === 200) { - confirmed = true; - ref = this.response; - for (i = 0, len = ref.length; i < len; i++) { - page = ref[i]; - ref1 = page.threads; - for (k = 0, len1 = ref1.length; k < len1; k++) { - thread = ref1[k]; - if (thread.no === ThreadUpdater.thread.ID) { - confirmed = false; - break; - } - } - } - } else { - confirmed = false; - } - if (confirmed) { - return ThreadUpdater.kill(); - } else { - return ThreadUpdater.error(this); - } - } - }); - default: - return ThreadUpdater.error(this); - } - } - }, - kill: function() { - ThreadUpdater.thread.kill(); - ThreadUpdater.setInterval(); - return $.event('ThreadUpdate', { - 404: true, - threadID: ThreadUpdater.thread.fullID - }); - }, - error: function(req) { - if (req.status === 304) { - ThreadUpdater.set('status', ''); - } - ThreadUpdater.setInterval(); - if (!req.status) { - return ThreadUpdater.set('status', 'Connection Error', 'warning'); - } else if (req.status !== 304) { - return ThreadUpdater.set('status', req.statusText + " (" + req.status + ")", 'warning'); - } - }, - setInterval: function() { - var cur, interval, j, limit; - clearTimeout(ThreadUpdater.timeoutID); - if (ThreadUpdater.thread.isDead) { - ThreadUpdater.set('status', (ThreadUpdater.thread.isArchived ? 'Archived' : '404'), 'warning'); - ThreadUpdater.set('timer', ''); - return; - } - if (ThreadUpdater.postID && ThreadUpdater.checkPostCount < 5) { - ThreadUpdater.set('timer', '...', 'loading'); - ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND); - return; - } - if (!Conf['Auto Update']) { - ThreadUpdater.set('timer', 'Update'); - return; - } - interval = ThreadUpdater.interval; - if (Conf['Optional Increase']) { - limit = d.hidden ? 10 : 5; - j = Math.min(ThreadUpdater.outdateCount, limit); - cur = (Math.floor(interval * 0.1) || 1) * j * j; - ThreadUpdater.seconds = $.minmax(cur, interval, 300); - } else { - ThreadUpdater.seconds = interval; - } - return ThreadUpdater.timeout(); - }, - intervalShortcut: function() { - var settings; - Settings.open('Advanced'); - settings = $.id('fourchanx-settings'); - return $('input[name=Interval]', settings).focus(); - }, - set: function(name, text, klass) { - var el, node; - el = ThreadUpdater[name]; - if (node = el.firstChild) { - node.data = text; - } else { - el.textContent = text; - } - return el.className = klass != null ? klass : (text === '' ? 'empty' : ''); - }, - timeout: function() { - if (ThreadUpdater.seconds) { - ThreadUpdater.set('timer', ThreadUpdater.seconds); - ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000); - } else { - ThreadUpdater.outdateCount++; - ThreadUpdater.update(); - } - return ThreadUpdater.seconds--; - }, - update: function() { - var oldReq; - clearTimeout(ThreadUpdater.timeoutID); - ThreadUpdater.set('timer', '...', 'loading'); - if ((oldReq = ThreadUpdater.req)) { - delete ThreadUpdater.req; - oldReq.abort(); - } - return ThreadUpdater.req = $.whenModified(g.SITE.urls.threadJSON({ - boardID: ThreadUpdater.thread.board.ID, - threadID: ThreadUpdater.thread.ID - }), 'ThreadUpdater', ThreadUpdater.cb.load, { - timeout: $.MINUTE - }); - }, - updateThreadStatus: function(type, status) { - var change, hasChanged; - if (!(hasChanged = ThreadUpdater.thread["is" + type] !== status)) { - return; - } - ThreadUpdater.thread.setStatus(type, status); - if (type === 'Closed' && ThreadUpdater.thread.isArchived) { - return; - } - change = type === 'Sticky' ? status ? 'now a sticky' : 'not a sticky anymore' : status ? 'now closed' : 'not closed anymore'; - return new Notice('info', "The thread is " + change + ".", 30); - }, - parse: function(req) { - var ID, OP, board, deletedFiles, deletedPosts, files, firstPost, i, index, ipCountEl, k, l, lastPost, len, len1, len2, len3, m, newPosts, node, post, postObject, postObjects, posts, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, scroll, thread, unreadCount, unreadQYCount; - postObjects = req.response.posts; - OP = postObjects[0]; - thread = ThreadUpdater.thread; - board = thread.board; - ref = ThreadUpdater.postIDs, lastPost = ref[ref.length - 1]; - if (postObjects[postObjects.length - 1].no < lastPost && new Date(req.getResponseHeader('Last-Modified')) - thread.posts.get(lastPost).info.date < 30 * $.SECOND) { - return; - } - g.SITE.Build.spoilerRange[board] = OP.custom_spoiler; - thread.setStatus('Archived', !!OP.archived); - ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky); - ThreadUpdater.updateThreadStatus('Closed', !!OP.closed); - thread.postLimit = !!OP.bumplimit; - thread.fileLimit = !!OP.imagelimit; - if (OP.unique_ips != null) { - thread.ipCount = OP.unique_ips; - } - posts = []; - index = []; - files = []; - newPosts = []; - for (i = 0, len = postObjects.length; i < len; i++) { - postObject = postObjects[i]; - ID = postObject.no; - index.push(ID); - if (postObject.fsize) { - files.push(ID); - } - if (ID <= lastPost) { - continue; - } - if ((post = thread.posts.get(ID)) && !post.isFetchedQuote) { - post.resurrect(); - continue; - } - newPosts.push(board + "." + ID); - node = g.SITE.Build.postFromObject(postObject, board.ID); - posts.push(new Post(node, thread, board)); - if (ThreadUpdater.postID === ID) { - delete ThreadUpdater.postID; - } - } - deletedPosts = []; - ref1 = ThreadUpdater.postIDs; - for (k = 0, len1 = ref1.length; k < len1; k++) { - ID = ref1[k]; - if (!(indexOf.call(index, ID) < 0)) { - continue; - } - thread.posts.get(ID).kill(); - deletedPosts.push(board + "." + ID); - } - ThreadUpdater.postIDs = index; - deletedFiles = []; - ref2 = ThreadUpdater.fileIDs; - for (l = 0, len2 = ref2.length; l < len2; l++) { - ID = ref2[l]; - if (!(!(indexOf.call(files, ID) >= 0 || (ref3 = board + "." + ID, indexOf.call(deletedPosts, ref3) >= 0)))) { - continue; - } - thread.posts.get(ID).kill(true); - deletedFiles.push(board + "." + ID); - } - ThreadUpdater.fileIDs = files; - if (!posts.length) { - ThreadUpdater.set('status', ''); - } else { - ThreadUpdater.set('status', "+" + posts.length, 'new'); - ThreadUpdater.outdateCount = 0; - unreadCount = (ref4 = Unread.posts) != null ? ref4.size : void 0; - unreadQYCount = (ref5 = Unread.postsQuotingYou) != null ? ref5.size : void 0; - Main.callbackNodes('Post', posts); - if (d.hidden || !d.hasFocus()) { - if (Conf['Beep Quoting You'] && ((ref6 = Unread.postsQuotingYou) != null ? ref6.size : void 0) > unreadQYCount) { - ThreadUpdater.playBeep(); - if (Conf['Beep']) { - ThreadUpdater.playBeep(); - } - } else if (Conf['Beep'] && ((ref7 = Unread.posts) != null ? ref7.size : void 0) > 0 && unreadCount === 0) { - ThreadUpdater.playBeep(); - } - } - scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight < 25; - firstPost = null; - for (m = 0, len3 = posts.length; m < len3; m++) { - post = posts[m]; - if (!QuoteThreading.insert(post)) { - firstPost || (firstPost = post.nodes.root); - $.add(ThreadUpdater.root, post.nodes.root); - } - } - $.event('PostsInserted', null, ThreadUpdater.root); - if (scroll) { - if (Conf['Bottom Scroll']) { - window.scrollTo(0, d.body.clientHeight); - } else { - if (firstPost) { - Header.scrollTo(firstPost); - } - } - } - } - if ((OP.unique_ips != null) && (ipCountEl = $.id('unique-ips'))) { - ipCountEl.textContent = OP.unique_ips; - ipCountEl.previousSibling.textContent = ipCountEl.previousSibling.textContent.replace(/\b(?:is|are)\b/, OP.unique_ips === 1 ? 'is' : 'are'); - ipCountEl.nextSibling.textContent = ipCountEl.nextSibling.textContent.replace(/\bposters?\b/, OP.unique_ips === 1 ? 'poster' : 'posters'); - } - return $.event('ThreadUpdate', { - 404: false, - threadID: thread.fullID, - newPosts: newPosts, - deletedPosts: deletedPosts, - deletedFiles: deletedFiles, - postCount: OP.replies + 1, - fileCount: OP.images + !!OP.fsize, - ipCount: OP.unique_ips - }); - } - }; - - return ThreadUpdater; - -}).call(this); - -ThreadWatcher = (function() { - var ThreadWatcher, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - ThreadWatcher = { - init: function() { - var ref, sc; - if (!(this.enabled = Conf['Thread Watcher'])) { - return; - } - this.shortcut = sc = $.el('a', { - id: 'watcher-link', - textContent: 'Watcher', - title: 'Thread Watcher', - href: 'javascript:;', - className: 'fa fa-eye' - }); - this.db = new DataBoard('watchedThreads', this.refresh, true); - this.dbLM = new DataBoard('watcherLastModified', null, true); - this.dialog = UI.dialog('thread-watcher', {innerHTML: "
        Thread Watcher ×
        "}); - this.status = $('#watcher-status', this.dialog); - this.list = this.dialog.lastElementChild; - this.refreshButton = $('.refresh', this.dialog); - this.closeButton = $('.move > .close', this.dialog); - this.unreaddb = Unread.db || UnreadIndex.db || new DataBoard('lastReadPosts'); - this.unreadEnabled = Conf['Remember Last Read Post']; - $.on(d, 'QRPostSuccessful', this.cb.post); - $.on(sc, 'click', this.toggleWatcher); - $.on(this.refreshButton, 'click', this.buttonFetchAll); - $.on(this.closeButton, 'click', this.toggleWatcher); - this.menu.addHeaderMenuEntry(); - $.onExists(doc, 'body', this.addDialog); - switch (g.VIEW) { - case 'index': - $.on(d, 'IndexUpdate', this.cb.onIndexUpdate); - break; - case 'thread': - $.on(d, 'ThreadUpdate', this.cb.onThreadRefresh); - } - if (Conf['Fixed Thread Watcher']) { - $.addClass(doc, 'fixed-watcher'); - } - if (!Conf['Persistent Thread Watcher']) { - $.addClass(ThreadWatcher.shortcut, 'disabled'); - this.dialog.hidden = true; - } - Header.addShortcut('watcher', sc, 510); - ThreadWatcher.initLastModified(); - ThreadWatcher.fetchAuto(); - $.on(window, 'visibilitychange focus', function() { - return $.queueTask(ThreadWatcher.fetchAuto); - }); - if (Conf['Menu'] && Index.enabled) { - Menu.menu.addEntry({ - el: $.el('a', { - href: 'javascript:;', - className: 'has-shortcut-text' - }, {innerHTML: "Alt+click"}), - order: 6, - open: function(arg) { - var thread; - thread = arg.thread; - if (Conf['Index Mode'] !== 'catalog') { - return false; - } - this.el.firstElementChild.textContent = ThreadWatcher.isWatched(thread) ? 'Unwatch' : 'Watch'; - if (this.cb) { - $.off(this.el, 'click', this.cb); - } - this.cb = function() { - $.event('CloseMenu'); - return ThreadWatcher.toggle(thread); - }; - $.on(this.el, 'click', this.cb); - return true; - } - }); - } - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - Callbacks.Post.push({ - name: 'Thread Watcher', - cb: this.node - }); - return Callbacks.CatalogThread.push({ - name: 'Thread Watcher', - cb: this.catalogNode - }); - }, - isWatched: function(thread) { - var ref; - return !!((ref = ThreadWatcher.db) != null ? ref.get({ - boardID: thread.board.ID, - threadID: thread.ID - }) : void 0); - }, - isWatchedRaw: function(boardID, threadID) { - var ref; - return !!((ref = ThreadWatcher.db) != null ? ref.get({ - boardID: boardID, - threadID: threadID - }) : void 0); - }, - setToggler: function(toggler, isWatched) { - toggler.classList.toggle('watched', isWatched); - return toggler.title = (isWatched ? 'Unwatch' : 'Watch') + " Thread"; - }, - node: function() { - var boardID, data, siteID, threadID, toggler; - if (this.isReply) { - return; - } - if (this.isClone) { - toggler = $('.watch-thread-link', this.nodes.info); - } else { - toggler = $.el('a', { - href: 'javascript:;', - className: 'watch-thread-link' - }); - $.before($('input', this.nodes.info), toggler); - } - siteID = g.SITE.ID; - boardID = this.board.ID; - threadID = this.thread.ID; - data = ThreadWatcher.db.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }); - ThreadWatcher.setToggler(toggler, !!data); - $.on(toggler, 'click', ThreadWatcher.cb.toggle); - if (data && (data.excerpt == null)) { - return $.queueTask((function(_this) { - return function() { - return ThreadWatcher.update(siteID, boardID, threadID, { - excerpt: Get.threadExcerpt(_this.thread) - }); - }; - })(this)); - } - }, - catalogNode: function() { - if (ThreadWatcher.isWatched(this.thread)) { - $.addClass(this.nodes.root, 'watched'); - } - return $.on(this.nodes.root, 'mousedown click', (function(_this) { - return function(e) { - if (!(e.button === 0 && e.altKey)) { - return; - } - if (e.type === 'click') { - ThreadWatcher.toggle(_this.thread); - } - return e.preventDefault(); - }; - })(this)); - }, - addDialog: function() { - if (!Main.isThisPageLegit()) { - return; - } - ThreadWatcher.build(); - return $.prepend(d.body, ThreadWatcher.dialog); - }, - toggleWatcher: function() { - $.toggleClass(ThreadWatcher.shortcut, 'disabled'); - return ThreadWatcher.dialog.hidden = !ThreadWatcher.dialog.hidden; - }, - cb: { - openAll: function() { - var a, j, len1, ref; - if ($.hasClass(this, 'disabled')) { - return; - } - ref = $$('a.watcher-link', ThreadWatcher.list); - for (j = 0, len1 = ref.length; j < len1; j++) { - a = ref[j]; - $.open(a.href); - } - return $.event('CloseMenu'); - }, - openUnread: function() { - var a, j, len1, ref; - if ($.hasClass(this, 'disabled')) { - return; - } - ref = $$('.replies-unread > a.watcher-link', ThreadWatcher.list); - for (j = 0, len1 = ref.length; j < len1; j++) { - a = ref[j]; - $.open(a.href); - } - return $.event('CloseMenu'); - }, - openDeads: function() { - var a, j, len1, ref; - if ($.hasClass(this, 'disabled')) { - return; - } - ref = $$('.dead-thread > a.watcher-link', ThreadWatcher.list); - for (j = 0, len1 = ref.length; j < len1; j++) { - a = ref[j]; - $.open(a.href); - } - return $.event('CloseMenu'); - }, - pruneDeads: function() { - var boardID, data, j, len1, ref, ref1, siteID, threadID; - if ($.hasClass(this, 'disabled')) { - return; - } - ref = ThreadWatcher.getAll(); - for (j = 0, len1 = ref.length; j < len1; j++) { - ref1 = ref[j], siteID = ref1.siteID, boardID = ref1.boardID, threadID = ref1.threadID, data = ref1.data; - if (data.isDead) { - ThreadWatcher.db["delete"]({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }); - } - } - ThreadWatcher.refresh(); - return $.event('CloseMenu'); - }, - dismiss: function() { - var boardID, data, j, len1, ref, ref1, siteID, threadID; - ref = ThreadWatcher.getAll(); - for (j = 0, len1 = ref.length; j < len1; j++) { - ref1 = ref[j], siteID = ref1.siteID, boardID = ref1.boardID, threadID = ref1.threadID, data = ref1.data; - if (data.quotingYou) { - ThreadWatcher.update(siteID, boardID, threadID, { - dismiss: data.quotingYou || 0 - }); - } - } - return $.event('CloseMenu'); - }, - toggle: function() { - var thread; - thread = Get.postFromNode(this).thread; - return ThreadWatcher.toggle(thread); - }, - rm: function() { - var boardID, ref, siteID, threadID; - siteID = this.parentNode.dataset.siteID; - ref = this.parentNode.dataset.fullID.split('.'), boardID = ref[0], threadID = ref[1]; - return ThreadWatcher.rm(siteID, boardID, +threadID); - }, - post: function(e) { - var boardID, cb, postID, ref, threadID; - ref = e.detail, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - cb = PostRedirect.delay(); - if (postID === threadID) { - if (Conf['Auto Watch']) { - return ThreadWatcher.addRaw(boardID, threadID, {}, cb); - } - } else if (Conf['Auto Watch Reply']) { - return ThreadWatcher.add(g.threads.get(boardID + '.' + threadID) || new Thread(threadID, g.boards[boardID] || new Board(boardID)), cb); - } - }, - onIndexUpdate: function(e) { - var boardID, data, db, nKilled, ref, ref1, siteID, threadID; - db = ThreadWatcher.db; - siteID = g.SITE.ID; - boardID = g.BOARD.ID; - nKilled = 0; - ref = db.data[siteID].boards[boardID]; - for (threadID in ref) { - data = ref[threadID]; - if (!(!(data != null ? data.isDead : void 0) && (ref1 = boardID + "." + threadID, indexOf.call(e.detail.threads, ref1) < 0))) { - continue; - } - if (!e.detail.threads.some(function(fullID) { - return +fullID.split('.')[1] > threadID; - })) { - continue; - } - if (Conf['Auto Prune'] || !(data && typeof data === 'object')) { - db["delete"]({ - boardID: boardID, - threadID: threadID - }); - nKilled++; - } else { - ThreadWatcher.fetchStatus({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - data: data - }); - } - } - if (nKilled) { - return ThreadWatcher.refresh(); - } - }, - onThreadRefresh: function(e) { - var thread; - thread = g.threads.get(e.detail.threadID); - if (!(e.detail[404] && ThreadWatcher.isWatched(thread))) { - return; - } - return ThreadWatcher.add(thread); - } - }, - requests: [], - fetched: 0, - fetch: function(url, arg, args, cb) { - var ajax, force, onloadend, ref, req, siteID; - siteID = arg.siteID, force = arg.force; - if (ThreadWatcher.requests.length === 0) { - ThreadWatcher.status.textContent = '...'; - $.addClass(ThreadWatcher.refreshButton, 'fa-spin'); - } - onloadend = function() { - if (this.finished) { - return; - } - this.finished = true; - ThreadWatcher.fetched++; - if (ThreadWatcher.fetched === ThreadWatcher.requests.length) { - ThreadWatcher.clearRequests(); - } else { - ThreadWatcher.status.textContent = (Math.round(ThreadWatcher.fetched / ThreadWatcher.requests.length * 100)) + "%"; - } - return cb.apply(this, args); - }; - ajax = siteID === g.SITE.ID ? $.ajax : CrossOrigin.ajax; - if (force) { - if ((ref = $.lastModified.ThreadWatcher) != null) { - delete ref[url]; - } - } - req = $.whenModified(url, 'ThreadWatcher', onloadend, { - timeout: $.MINUTE, - ajax: ajax - }); - return ThreadWatcher.requests.push(req); - }, - clearRequests: function() { - ThreadWatcher.requests = []; - ThreadWatcher.fetched = 0; - ThreadWatcher.status.textContent = ''; - return $.rmClass(ThreadWatcher.refreshButton, 'fa-spin'); - }, - abort: function() { - var j, len1, ref, req; - delete ThreadWatcher.syncing; - ref = ThreadWatcher.requests; - for (j = 0, len1 = ref.length; j < len1; j++) { - req = ref[j]; - if (!(!req.finished)) { - continue; - } - req.finished = true; - req.abort(); - } - return ThreadWatcher.clearRequests(); - }, - initLastModified: function() { - var base, boardID, boards, data, date, lm, ref, ref1, siteID, url; - lm = ((base = $.lastModified)['ThreadWatcher'] || (base['ThreadWatcher'] = $.dict())); - ref = ThreadWatcher.dbLM.data; - for (siteID in ref) { - boards = ref[siteID]; - ref1 = boards.boards; - for (boardID in ref1) { - data = ref1[boardID]; - if (ThreadWatcher.db.get({ - siteID: siteID, - boardID: boardID - })) { - for (url in data) { - date = data[url]; - lm[url] = date; - } - } else { - ThreadWatcher.dbLM["delete"]({ - siteID: siteID, - boardID: boardID - }); - } - } - } - }, - fetchAuto: function() { - var db, interval, now, ref; - clearTimeout(ThreadWatcher.timeout); - if (!Conf['Auto Update Thread Watcher']) { - return; - } - db = ThreadWatcher.db; - interval = Conf['Show Page'] || (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) ? 5 * $.MINUTE : 2 * $.HOUR; - now = Date.now(); - if (!((now - interval < (ref = db.data.lastChecked || 0) && ref <= now) || d.hidden || !d.hasFocus())) { - ThreadWatcher.fetchAllStatus(interval); - } - return ThreadWatcher.timeout = setTimeout(ThreadWatcher.fetchAuto, interval); - }, - buttonFetchAll: function() { - if (ThreadWatcher.syncing || ThreadWatcher.requests.length) { - return ThreadWatcher.abort(); - } else { - return ThreadWatcher.fetchAllStatus(); - } - }, - fetchAllStatus: function(interval) { - var dbi, dbs, j, len1, n, results; - if (interval == null) { - interval = 0; - } - ThreadWatcher.status.textContent = '...'; - $.addClass(ThreadWatcher.refreshButton, 'fa-spin'); - ThreadWatcher.syncing = true; - dbs = [ThreadWatcher.db, ThreadWatcher.unreaddb, QuoteYou.db].filter(function(x) { - return x; - }); - n = 0; - results = []; - for (j = 0, len1 = dbs.length; j < len1; j++) { - dbi = dbs[j]; - results.push(dbi.forceSync(function() { - var board, boards, db, deep, k, len2, now, ref, ref1; - if ((++n) === dbs.length) { - if (!ThreadWatcher.syncing) { - return; - } - delete ThreadWatcher.syncing; - if (!((0 <= (ref = Date.now() - (ThreadWatcher.db.data.lastChecked || 0)) && ref < interval))) { - db = ThreadWatcher.db; - now = Date.now(); - deep = !((now - 2 * $.HOUR < (ref1 = db.data.lastChecked2 || 0) && ref1 <= now)); - boards = ThreadWatcher.getAll(true); - for (k = 0, len2 = boards.length; k < len2; k++) { - board = boards[k]; - ThreadWatcher.fetchBoard(board, deep); - } - db.setLastChecked(); - if (deep) { - db.setLastChecked('lastChecked2'); - } - } - if (ThreadWatcher.fetched === ThreadWatcher.requests.length) { - return ThreadWatcher.clearRequests(); - } - } - })); - } - return results; - }, - fetchBoard: function(board, deep) { - var base, boardID, data, force, j, len1, ref, site, siteID, thread, url, urlF; - if (!board.some(function(thread) { - return !thread.data.isDead; - })) { - return; - } - force = false; - for (j = 0, len1 = board.length; j < len1; j++) { - thread = board[j]; - data = thread.data; - if (!data.isDead && data.last !== -1) { - if (Conf['Show Page'] && (data.page == null)) { - force = true; - } - if (data.modified == null) { - force = thread.force = true; - } - } - } - ref = board[0], siteID = ref.siteID, boardID = ref.boardID; - site = g.sites[siteID]; - if (!site) { - return; - } - urlF = deep && site.threadModTimeIgnoresSage ? 'catalogJSON' : 'threadsListJSON'; - url = typeof (base = site.urls)[urlF] === "function" ? base[urlF]({ - siteID: siteID, - boardID: boardID - }) : void 0; - if (!url) { - return; - } - return ThreadWatcher.fetch(url, { - siteID: siteID, - force: force - }, [board, url], ThreadWatcher.parseBoard); - }, - parseBoard: function(board, url) { - var base, boardID, data, i, index, item, j, k, l, lastPage, len1, len2, len3, len4, lmDate, m, modified, nThreads, oldest, page, pageLength, ref, ref1, ref2, ref3, ref4, replies, siteID, thread, threadID, threads; - if (this.status !== 200) { - return; - } - ref = board[0], siteID = ref.siteID, boardID = ref.boardID; - lmDate = this.getResponseHeader('Last-Modified'); - ThreadWatcher.dbLM.extend({ - siteID: siteID, - boardID: boardID, - val: $.item(url, lmDate) - }); - threads = $.dict(); - pageLength = 0; - nThreads = 0; - oldest = null; - try { - pageLength = ((ref1 = this.response[0]) != null ? ref1.threads.length : void 0) || 0; - ref2 = this.response; - for (i = j = 0, len1 = ref2.length; j < len1; i = ++j) { - page = ref2[i]; - ref3 = page.threads; - for (k = 0, len2 = ref3.length; k < len2; k++) { - item = ref3[k]; - threads[item.no] = { - page: i + 1, - index: nThreads, - modified: item.last_modified, - replies: item.replies - }; - nThreads++; - if ((oldest == null) || item.no < oldest) { - oldest = item.no; - } - } - } - } catch (error) { - for (l = 0, len3 = board.length; l < len3; l++) { - thread = board[l]; - ThreadWatcher.fetchStatus(thread); - } - } - for (m = 0, len4 = board.length; m < len4; m++) { - thread = board[m]; - threadID = thread.threadID, data = thread.data; - if (threads[threadID]) { - ref4 = threads[threadID], page = ref4.page, index = ref4.index, modified = ref4.modified, replies = ref4.replies; - if (Conf['Show Page']) { - lastPage = (typeof (base = g.sites[siteID]).isPrunedByAge === "function" ? base.isPrunedByAge({ - siteID: siteID, - boardID: boardID - }) : void 0) ? threadID === oldest : index >= nThreads - pageLength; - ThreadWatcher.update(siteID, boardID, threadID, { - page: page, - lastPage: lastPage - }); - } - if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { - if (modified !== data.modified || ((replies != null) && replies !== data.replies)) { - (thread.newData || (thread.newData = {})).modified = modified; - ThreadWatcher.fetchStatus(thread); - } - } - } else { - ThreadWatcher.fetchStatus(thread); - } - } - }, - fetchStatus: function(thread) { - var base, boardID, data, force, ref, siteID, threadID, url; - siteID = thread.siteID, boardID = thread.boardID, threadID = thread.threadID, data = thread.data, force = thread.force; - url = (ref = g.sites[siteID]) != null ? typeof (base = ref.urls).threadJSON === "function" ? base.threadJSON({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }) : void 0 : void 0; - if (!url) { - return; - } - if (data.isDead && !force) { - return; - } - if (data.last === -1) { - return; - } - return ThreadWatcher.fetch(url, { - siteID: siteID, - force: force - }, [thread], ThreadWatcher.parseStatus); - }, - parseStatus: function(thread, isArchiveURL) { - var archiveURL, base, boardID, data, force, isArchived, isDead, j, last, lastReadPost, len1, match, newData, postObj, quotesYou, quotingYou, ref, ref1, ref2, ref3, regexp, replies, site, siteID, threadID, unread, youOP; - siteID = thread.siteID, boardID = thread.boardID, threadID = thread.threadID, data = thread.data, newData = thread.newData, force = thread.force; - site = g.sites[siteID]; - if (this.status === 200 && this.response) { - last = this.response.posts[this.response.posts.length - 1].no; - replies = this.response.posts.length - 1; - isDead = isArchived = !!(this.response.posts[0].archived || isArchiveURL); - if (isDead && Conf['Auto Prune']) { - ThreadWatcher.rm(siteID, boardID, threadID); - return; - } - if (last === data.last && isDead === data.isDead && isArchived === data.isArchived) { - return; - } - lastReadPost = ThreadWatcher.unreaddb.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - defaultValue: 0 - }); - unread = data.unread || 0; - quotingYou = data.quotingYou || 0; - youOP = !!((ref = QuoteYou.db) != null ? ref.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - postID: threadID - }) : void 0); - ref1 = this.response.posts; - for (j = 0, len1 = ref1.length; j < len1; j++) { - postObj = ref1[j]; - if (!(postObj.no > (data.last || 0) && postObj.no > lastReadPost)) { - continue; - } - if ((ref2 = QuoteYou.db) != null ? ref2.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - postID: postObj.no - }) : void 0) { - continue; - } - quotesYou = false; - if (!Conf['Require OP Quote Link'] && youOP) { - quotesYou = true; - } else if (QuoteYou.db && postObj.com) { - regexp = site.regexp.quotelinkHTML; - regexp.lastIndex = 0; - while ((match = regexp.exec(postObj.com))) { - if (QuoteYou.db.get({ - siteID: siteID, - boardID: match[1] ? encodeURIComponent(match[1]) : boardID, - threadID: match[2] || threadID, - postID: match[3] || match[2] || threadID - })) { - quotesYou = true; - break; - } - } - } - if (!unread || (!quotingYou && quotesYou)) { - if (Filter.isHidden(site.Build.parseJSON(postObj, { - siteID: siteID, - boardID: boardID - }))) { - continue; - } - } - unread++; - if (quotesYou) { - quotingYou = postObj.no; - } - } - newData || (newData = {}); - $.extend(newData, { - last: last, - replies: replies, - isDead: isDead, - isArchived: isArchived, - unread: unread, - quotingYou: quotingYou - }); - return ThreadWatcher.update(siteID, boardID, threadID, newData); - } else if (this.status === 404) { - archiveURL = (ref3 = g.sites[siteID]) != null ? typeof (base = ref3.urls).archivedThreadJSON === "function" ? base.archivedThreadJSON({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }) : void 0 : void 0; - if (!isArchiveURL && archiveURL) { - return ThreadWatcher.fetch(archiveURL, { - siteID: siteID, - force: force - }, [thread, true], ThreadWatcher.parseStatus); - } else if (site.mayLackJSON && (data.last == null)) { - return ThreadWatcher.update(siteID, boardID, threadID, { - last: -1 - }); - } else { - return ThreadWatcher.update(siteID, boardID, threadID, { - isDead: true - }); - } - } - }, - getAll: function(groupByBoard) { - var all, boardID, boards, cont, data, ref, ref1, siteID, threadID, threads; - all = []; - ref = ThreadWatcher.db.data; - for (siteID in ref) { - boards = ref[siteID]; - ref1 = boards.boards; - for (boardID in ref1) { - threads = ref1[boardID]; - if (Conf['Current Board'] && (siteID !== g.SITE.ID || boardID !== g.BOARD.ID)) { - continue; - } - if (groupByBoard) { - all.push((cont = [])); - } - for (threadID in threads) { - data = threads[threadID]; - if (data && typeof data === 'object') { - (groupByBoard ? cont : all).push({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - data: data - }); - } - } - } - } - return all; - }, - makeLine: function(siteID, boardID, threadID, data) { - var count, div, excerpt, fullID, isArchived, link, page, ref, title, x; - x = $.el('a', { - className: 'fa fa-times', - href: 'javascript:;' - }); - $.on(x, 'click', ThreadWatcher.cb.rm); - excerpt = data.excerpt, isArchived = data.isArchived; - excerpt || (excerpt = "/" + boardID + "/ - No." + threadID); - if (Conf['Show Site Prefix']) { - excerpt = ThreadWatcher.prefixes[siteID] + excerpt; - } - link = $.el('a', { - href: ((ref = g.sites[siteID]) != null ? ref.urls.thread({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }, isArchived) : void 0) || '', - title: excerpt, - className: 'watcher-link' - }); - if (Conf['Show Page'] && (data.page != null)) { - page = $.el('span', { - textContent: "[" + data.page + "]", - className: 'watcher-page' - }); - $.add(link, page); - } - if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count'] && (data.unread != null)) { - count = $.el('span', { - textContent: "(" + data.unread + ")", - className: 'watcher-unread' - }); - $.add(link, count); - } - title = $.el('span', { - textContent: excerpt, - className: 'watcher-title' - }); - $.add(link, title); - div = $.el('div'); - fullID = boardID + "." + threadID; - div.dataset.fullID = fullID; - div.dataset.siteID = siteID; - if (g.VIEW === 'thread' && fullID === (g.BOARD + "." + g.THREADID)) { - $.addClass(div, 'current'); - } - if (data.isDead) { - $.addClass(div, 'dead-thread'); - } - if (Conf['Show Page']) { - if (data.lastPage) { - $.addClass(div, 'last-page'); - } - if (data.page != null) { - div.dataset.page = data.page; - } - } - if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { - if (data.unread === 0) { - $.addClass(div, 'replies-read'); - } - if (data.unread) { - $.addClass(div, 'replies-unread'); - } - if ((data.quotingYou || 0) > (data.dismiss || 0)) { - $.addClass(div, 'replies-quoting-you'); - } - } - $.add(div, [x, $.tn(' '), link]); - return div; - }, - setPrefixes: function(threads) { - var conflicts, conflicts2, j, k, len, len1, len2, prefix, prefixes, siteID, siteID2; - prefixes = $.dict(); - for (j = 0, len1 = threads.length; j < len1; j++) { - siteID = threads[j].siteID; - if (siteID in prefixes) { - continue; - } - len = 0; - prefix = ''; - conflicts = Object.keys(prefixes); - while (conflicts.length > 0) { - len++; - prefix = siteID.slice(0, len); - conflicts2 = []; - for (k = 0, len2 = conflicts.length; k < len2; k++) { - siteID2 = conflicts[k]; - if (siteID2.slice(0, len) === prefix) { - conflicts2.push(siteID2); - } else if (prefixes[siteID2].length < len) { - prefixes[siteID2] = siteID2.slice(0, len); - } - } - conflicts = conflicts2; - } - prefixes[siteID] = prefix; - } - return ThreadWatcher.prefixes = prefixes; - }, - build: function() { - var boardID, data, j, len1, list, nodes, ref, siteID, thread, threadID, threads; - nodes = []; - threads = ThreadWatcher.getAll(); - ThreadWatcher.setPrefixes(threads); - for (j = 0, len1 = threads.length; j < len1; j++) { - ref = threads[j], siteID = ref.siteID, boardID = ref.boardID, threadID = ref.threadID, data = ref.data; - if ((data.excerpt == null) && siteID === g.SITE.ID && (thread = g.threads.get(boardID + "." + threadID)) && thread.OP) { - ThreadWatcher.db.extend({ - boardID: boardID, - threadID: threadID, - val: { - excerpt: Get.threadExcerpt(thread) - } - }); - } - nodes.push(ThreadWatcher.makeLine(siteID, boardID, threadID, data)); - } - list = ThreadWatcher.list; - $.rmAll(list); - $.add(list, nodes); - return ThreadWatcher.refreshIcon(); - }, - refresh: function() { - ThreadWatcher.build(); - g.threads.forEach(function(thread) { - var isWatched, j, len1, post, ref, toggler; - isWatched = ThreadWatcher.isWatched(thread); - if (thread.OP) { - ref = [thread.OP].concat(slice.call(thread.OP.clones)); - for (j = 0, len1 = ref.length; j < len1; j++) { - post = ref[j]; - if ((toggler = $('.watch-thread-link', post.nodes.info))) { - ThreadWatcher.setToggler(toggler, isWatched); - } - } - } - if (thread.catalogView) { - return thread.catalogView.nodes.root.classList.toggle('watched', isWatched); - } - }); - if (Conf['Pin Watched Threads']) { - return $.event('SortIndex', { - deferred: Conf['Index Mode'] !== 'catalog' - }); - } - }, - refreshIcon: function() { - var className, j, len1, ref; - ref = ['replies-unread', 'replies-quoting-you']; - for (j = 0, len1 = ref.length; j < len1; j++) { - className = ref[j]; - ThreadWatcher.shortcut.classList.toggle(className, !!$("." + className, ThreadWatcher.dialog)); - } - }, - update: function(siteID, boardID, threadID, newData) { - var data, j, key, len1, line, n, newLine, ref, ref1, val; - if (!(data = (ref = ThreadWatcher.db) != null ? ref.get({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }) : void 0)) { - return; - } - if (newData.isDead && Conf['Auto Prune']) { - ThreadWatcher.rm(siteID, boardID, threadID); - return; - } - if (newData.isDead || newData.last === -1) { - ref1 = ['isArchived', 'page', 'lastPage', 'unread', 'quotingyou']; - for (j = 0, len1 = ref1.length; j < len1; j++) { - key = ref1[j]; - if (!(key in newData)) { - newData[key] = void 0; - } - } - } - if ((newData.last != null) && newData.last < data.last) { - newData.modified = void 0; - } - n = 0; - for (key in newData) { - val = newData[key]; - if (data[key] !== val) { - n++; - } - } - if (!n) { - return; - } - ThreadWatcher.db.extend({ - siteID: siteID, - boardID: boardID, - threadID: threadID, - val: newData - }); - if ((line = $("#watched-threads > [data-site-i-d='" + siteID + "'][data-full-i-d='" + boardID + "." + threadID + "']", ThreadWatcher.dialog))) { - newLine = ThreadWatcher.makeLine(siteID, boardID, threadID, data); - $.replace(line, newLine); - return ThreadWatcher.refreshIcon(); - } else { - return ThreadWatcher.refresh(); - } - }, - set404: function(boardID, threadID, cb) { - var data, ref; - if (!(data = (ref = ThreadWatcher.db) != null ? ref.get({ - boardID: boardID, - threadID: threadID - }) : void 0)) { - return cb(); - } - if (Conf['Auto Prune']) { - ThreadWatcher.db["delete"]({ - boardID: boardID, - threadID: threadID - }); - return cb(); - } - if (data.isDead && !((data.isArchived != null) || (data.page != null) || (data.lastPage != null) || (data.unread != null) || (data.quotingYou != null))) { - return cb(); - } - return ThreadWatcher.db.extend({ - boardID: boardID, - threadID: threadID, - val: { - isDead: true, - isArchived: void 0, - page: void 0, - lastPage: void 0, - unread: void 0, - quotingYou: void 0 - } - }, cb); - }, - toggle: function(thread) { - var boardID, siteID, threadID; - siteID = g.SITE.ID; - boardID = thread.board.ID; - threadID = thread.ID; - if (ThreadWatcher.db.get({ - boardID: boardID, - threadID: threadID - })) { - return ThreadWatcher.rm(siteID, boardID, threadID); - } else { - return ThreadWatcher.add(thread); - } - }, - add: function(thread, cb) { - var boardID, data, siteID, threadID; - data = {}; - siteID = g.SITE.ID; - boardID = thread.board.ID; - threadID = thread.ID; - if (thread.isDead) { - if (Conf['Auto Prune'] && ThreadWatcher.db.get({ - boardID: boardID, - threadID: threadID - })) { - ThreadWatcher.rm(siteID, boardID, threadID, cb); - return; - } - data.isDead = true; - } - if (thread.OP) { - data.excerpt = Get.threadExcerpt(thread); - } - return ThreadWatcher.addRaw(boardID, threadID, data, cb); - }, - addRaw: function(boardID, threadID, data, cb) { - var oldData, thread; - oldData = ThreadWatcher.db.get({ - boardID: boardID, - threadID: threadID, - defaultValue: $.dict() - }); - delete oldData.last; - delete oldData.modified; - $.extend(oldData, data); - ThreadWatcher.db.set({ - boardID: boardID, - threadID: threadID, - val: oldData - }, cb); - ThreadWatcher.refresh(); - thread = { - siteID: g.SITE.ID, - boardID: boardID, - threadID: threadID, - data: data, - force: true - }; - if (Conf['Show Page'] && !data.isDead) { - return ThreadWatcher.fetchBoard([thread]); - } else if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { - return ThreadWatcher.fetchStatus(thread); - } - }, - rm: function(siteID, boardID, threadID, cb) { - ThreadWatcher.db["delete"]({ - siteID: siteID, - boardID: boardID, - threadID: threadID - }, cb); - return ThreadWatcher.refresh(); - }, - menu: { - init: function() { - var menu; - if (!Conf['Thread Watcher']) { - return; - } - menu = this.menu = new UI.Menu('thread watcher'); - $.on($('.menu-button', ThreadWatcher.dialog), 'click', function(e) { - return menu.toggle(e, this, ThreadWatcher); - }); - return this.addMenuEntries(); - }, - addHeaderMenuEntry: function() { - var entryEl; - if (g.VIEW !== 'thread') { - return; - } - entryEl = $.el('a', { - href: 'javascript:;' - }); - Header.menu.addEntry({ - el: entryEl, - order: 60, - open: function() { - var addClass, ref, rmClass, text; - ref = !!ThreadWatcher.db.get({ - boardID: g.BOARD.ID, - threadID: g.THREADID - }) ? ['unwatch-thread', 'watch-thread', 'Unwatch thread'] : ['watch-thread', 'unwatch-thread', 'Watch thread'], addClass = ref[0], rmClass = ref[1], text = ref[2]; - $.addClass(entryEl, addClass); - $.rmClass(entryEl, rmClass); - entryEl.textContent = text; - return true; - } - }); - return $.on(entryEl, 'click', function() { - return ThreadWatcher.toggle(g.threads.get(g.BOARD + "." + g.THREADID)); - }); - }, - addMenuEntries: function() { - var cb, conf, entries, entry, j, len1, name, open, ref, ref1, text, title; - entries = []; - entries.push({ - text: 'Open all threads', - cb: ThreadWatcher.cb.openAll, - open: function() { - this.el.classList.toggle('disabled', !ThreadWatcher.list.firstElementChild); - return true; - } - }); - entries.push({ - text: 'Open unread threads', - cb: ThreadWatcher.cb.openUnread, - open: function() { - this.el.classList.toggle('disabled', !$('.replies-unread', ThreadWatcher.list)); - return true; - } - }); - entries.push({ - text: 'Open dead threads', - cb: ThreadWatcher.cb.openDeads, - open: function() { - this.el.classList.toggle('disabled', !$('.dead-thread', ThreadWatcher.list)); - return true; - } - }); - entries.push({ - text: 'Prune dead threads', - cb: ThreadWatcher.cb.pruneDeads, - open: function() { - this.el.classList.toggle('disabled', !$('.dead-thread', ThreadWatcher.list)); - return true; - } - }); - entries.push({ - text: 'Dismiss posts quoting you', - title: 'Unhighlight the thread watcher icon and threads until there are new replies quoting you.', - cb: ThreadWatcher.cb.dismiss, - open: function() { - this.el.classList.toggle('disabled', !$.hasClass(ThreadWatcher.shortcut, 'replies-quoting-you')); - return true; - } - }); - for (j = 0, len1 = entries.length; j < len1; j++) { - ref = entries[j], text = ref.text, title = ref.title, cb = ref.cb, open = ref.open; - entry = { - el: $.el('a', { - textContent: text, - href: 'javascript:;' - }) - }; - if (title) { - entry.el.title = title; - } - $.on(entry.el, 'click', cb); - entry.open = open.bind(entry); - this.menu.addEntry(entry); - } - ref1 = Config.threadWatcher; - for (name in ref1) { - conf = ref1[name]; - this.addCheckbox(name, conf[1]); - } - }, - addCheckbox: function(name, desc) { - var entry, input; - entry = { - type: 'thread watcher', - el: UI.checkbox(name, name.replace(' Thread Watcher', '')) - }; - entry.el.title = desc; - input = entry.el.firstElementChild; - if (name === 'Show Unread Count' && !ThreadWatcher.unreadEnabled) { - input.disabled = true; - $.addClass(entry.el, 'disabled'); - entry.el.title += '\n[Remember Last Read Post is disabled.]'; - } - $.on(input, 'change', $.cb.checked); - if (name === 'Current Board' || name === 'Show Page' || name === 'Show Unread Count' || name === 'Show Site Prefix') { - $.on(input, 'change', ThreadWatcher.refresh); - } - if (name === 'Show Page' || name === 'Show Unread Count' || name === 'Auto Update Thread Watcher') { - $.on(input, 'change', ThreadWatcher.fetchAuto); - } - return this.menu.addEntry(entry); - } - } - }; - - return ThreadWatcher; - -}).call(this); - -Unread = (function() { - var Unread; - - Unread = { - init: function() { - if (!(g.VIEW === 'thread' && (Conf['Unread Count'] || Conf['Unread Favicon'] || Conf['Unread Line'] || Conf['Remember Last Read Post'] || Conf['Desktop Notifications'] || Conf['Quote Threading']))) { - return; - } - if (Conf['Remember Last Read Post']) { - $.sync('Remember Last Read Post', function(enabled) { - return Conf['Remember Last Read Post'] = enabled; - }); - this.db = new DataBoard('lastReadPosts', this.sync); - } - this.hr = $.el('hr', { - id: 'unread-line', - className: 'unread-line' - }); - this.posts = new Set(); - this.postsQuotingYou = new Set(); - this.order = new RandomAccessList(); - this.position = null; - Callbacks.Thread.push({ - name: 'Unread', - cb: this.node - }); - return Callbacks.Post.push({ - name: 'Unread', - cb: this.addPost - }); - }, - node: function() { - var ID, j, len, ref, ref1, resetLink; - Unread.thread = this; - Unread.title = d.title; - Unread.lastReadPost = ((ref = Unread.db) != null ? ref.get({ - boardID: this.board.ID, - threadID: this.ID - }) : void 0) || 0; - Unread.readCount = 0; - ref1 = this.posts.keys; - for (j = 0, len = ref1.length; j < len; j++) { - ID = ref1[j]; - if (+ID <= Unread.lastReadPost) { - Unread.readCount++; - } - } - $.one(d, '4chanXInitFinished', Unread.ready); - $.on(d, 'PostsInserted', Unread.onUpdate); - $.on(d, 'ThreadUpdate', function(e) { - if (e.detail[404]) { - return Unread.update(); - } - }); - resetLink = $.el('a', { - href: 'javascript:;', - className: 'unread-reset', - textContent: 'Mark all unread' - }); - $.on(resetLink, 'click', Unread.reset); - return Header.menu.addEntry({ - el: resetLink, - order: 70 - }); - }, - ready: function() { - if (Conf['Remember Last Read Post'] && Conf['Scroll to Last Read Post']) { - Unread.scroll(); - } - Unread.setLine(true); - Unread.read(); - Unread.update(); - $.on(d, 'scroll visibilitychange', Unread.read); - if (Conf['Unread Line']) { - return $.on(d, 'visibilitychange', Unread.setLine); - } - }, - positionPrev: function() { - if (Unread.position) { - return Unread.position.prev; - } else { - return Unread.order.last; - } - }, - scroll: function() { - var bottom, hash, position; - if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { - return; - } - position = Unread.positionPrev(); - while (position) { - bottom = position.data.nodes.bottom; - if (!bottom.getBoundingClientRect().height) { - position = position.prev; - } else { - Header.scrollToIfNeeded(bottom, true); - break; - } - } - }, - reset: function() { - if (Unread.lastReadPost == null) { - return; - } - Unread.posts = new Set(); - Unread.postsQuotingYou = new Set(); - Unread.order = new RandomAccessList(); - Unread.position = null; - Unread.lastReadPost = 0; - Unread.readCount = 0; - Unread.thread.posts.forEach(function(post) { - return Unread.addPost.call(post); - }); - $.forceSync('Remember Last Read Post'); - if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) { - Unread.db.set({ - boardID: Unread.thread.board.ID, - threadID: Unread.thread.ID, - val: 0 - }); - } - Unread.updatePosition(); - Unread.setLine(); - return Unread.update(); - }, - sync: function() { - var ID, i, j, lastReadPost, postIDs, ref, ref1; - if (Unread.lastReadPost == null) { - return; - } - lastReadPost = Unread.db.get({ - boardID: Unread.thread.board.ID, - threadID: Unread.thread.ID, - defaultValue: 0 - }); - if (!(Unread.lastReadPost < lastReadPost)) { - return; - } - Unread.lastReadPost = lastReadPost; - postIDs = Unread.thread.posts.keys; - for (i = j = ref = Unread.readCount, ref1 = postIDs.length; j < ref1; i = j += 1) { - ID = +postIDs[i]; - if (!Unread.thread.posts.get(ID).isFetchedQuote) { - if (ID > Unread.lastReadPost) { - break; - } - Unread.posts["delete"](ID); - Unread.postsQuotingYou["delete"](ID); - } - Unread.readCount++; - } - Unread.updatePosition(); - Unread.setLine(); - return Unread.update(); - }, - addPost: function() { - if (this.isFetchedQuote || this.isClone) { - return; - } - Unread.order.push(this); - if (this.ID <= Unread.lastReadPost || this.isHidden || QuoteYou.isYou(this)) { - return; - } - Unread.posts.add((Unread.posts.last = this.ID)); - Unread.addPostQuotingYou(this); - return Unread.position != null ? Unread.position : Unread.position = Unread.order[this.ID]; - }, - addPostQuotingYou: function(post) { - var j, len, quotelink, ref, ref1; - ref = post.nodes.quotelinks; - for (j = 0, len = ref.length; j < len; j++) { - quotelink = ref[j]; - if (!((ref1 = QuoteYou.db) != null ? ref1.get(Get.postDataFromLink(quotelink)) : void 0)) { - continue; - } - Unread.postsQuotingYou.add((Unread.postsQuotingYou.last = post.ID)); - Unread.openNotification(post); - return; - } - }, - openNotification: function(post, predicate) { - var notif; - if (predicate == null) { - predicate = ' replied to you'; - } - if (!Header.areNotificationsEnabled) { - return; - } - notif = new Notification("" + post.info.nameBlock + predicate, { - body: post.commentDisplay(), - icon: Favicon.logo - }); - notif.onclick = function() { - Header.scrollToIfNeeded(post.nodes.bottom, true); - return window.focus(); - }; - return notif.onshow = function() { - return setTimeout(function() { - return notif.close(); - }, 7 * $.SECOND); - }; - }, - onUpdate: function() { - return $.queueTask(function() { - Unread.setLine(); - Unread.read(); - return Unread.update(); - }); - }, - readSinglePost: function(post) { - var ID; - ID = post.ID; - if (!Unread.posts.has(ID)) { - return; - } - Unread.posts["delete"](ID); - Unread.postsQuotingYou["delete"](ID); - Unread.updatePosition(); - Unread.saveLastReadPost(); - return Unread.update(); - }, - read: $.debounce(100, function(e) { - var ID, bottom, count, data, ref; - if (!Unread.posts.size && Unread.readCount !== Unread.thread.posts.keys.length) { - Unread.saveLastReadPost(); - } - if (d.hidden || !Unread.posts.size) { - return; - } - count = 0; - while (Unread.position) { - ref = Unread.position, ID = ref.ID, data = ref.data; - bottom = data.nodes.bottom; - if (!(!bottom.getBoundingClientRect().height || Header.getBottomOf(bottom) > -1)) { - break; - } - count++; - Unread.posts["delete"](ID); - Unread.postsQuotingYou["delete"](ID); - Unread.position = Unread.position.next; - } - if (!count) { - return; - } - Unread.updatePosition(); - Unread.saveLastReadPost(); - if (e) { - return Unread.update(); - } - }), - updatePosition: function() { - while (Unread.position && !Unread.posts.has(Unread.position.ID)) { - Unread.position = Unread.position.next; - } - }, - saveLastReadPost: $.debounce(2 * $.SECOND, function() { - var ID, i, j, postIDs, ref, ref1; - $.forceSync('Remember Last Read Post'); - if (!(Conf['Remember Last Read Post'] && Unread.db)) { - return; - } - postIDs = Unread.thread.posts.keys; - for (i = j = ref = Unread.readCount, ref1 = postIDs.length; j < ref1; i = j += 1) { - ID = +postIDs[i]; - if (!Unread.thread.posts.get(ID).isFetchedQuote) { - if (Unread.posts.has(ID)) { - break; - } - Unread.lastReadPost = ID; - } - Unread.readCount++; - } - if (Unread.thread.isDead && !Unread.thread.isArchived) { - return; - } - return Unread.db.set({ - boardID: Unread.thread.board.ID, - threadID: Unread.thread.ID, - val: Unread.lastReadPost - }); - }), - setLine: function(force) { - var node, oldPosition, ref; - if (!Conf['Unread Line']) { - return; - } - if (Unread.hr.hidden || d.hidden || (force === true)) { - oldPosition = Unread.linePosition; - if ((Unread.linePosition = Unread.positionPrev())) { - if (Unread.linePosition !== oldPosition) { - node = Unread.linePosition.data.nodes.bottom; - if (((ref = node.nextSibling) != null ? ref.tagName : void 0) === 'BR') { - node = node.nextSibling; - } - $.after(node, Unread.hr); - } - } else { - $.rm(Unread.hr); - } - } - return Unread.hr.hidden = Unread.linePosition === Unread.order.last; - }, - update: function() { - var count, countQuotingYou, isDead, titleCount, titleDead, titleQuotingYou; - count = Unread.posts.size; - countQuotingYou = Unread.postsQuotingYou.size; - if (Conf['Unread Count']) { - titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : ''; - titleCount = count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : ''; - titleDead = Unread.thread.isDead ? Unread.title.replace('-', (Unread.thread.isArchived ? '- Archived -' : '- 404 -')) : Unread.title; - d.title = "" + titleQuotingYou + titleCount + titleDead; - } - Unread.saveThreadWatcherCount(); - if (Conf['Unread Favicon'] && g.SITE.software === 'yotsuba') { - isDead = Unread.thread.isDead; - return Favicon.set((countQuotingYou ? (isDead ? 'unreadDeadY' : 'unreadY') : count ? (isDead ? 'unreadDead' : 'unread') : (isDead ? 'dead' : 'default'))); - } - }, - saveThreadWatcherCount: $.debounce(2 * $.SECOND, function() { - var i, j, posts, quotingYou, ref; - $.forceSync('Remember Last Read Post'); - if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) { - quotingYou = !Conf['Require OP Quote Link'] && QuoteYou.isYou(Unread.thread.OP) ? Unread.posts : Unread.postsQuotingYou; - if (!quotingYou.size) { - quotingYou.last = 0; - } else if (!quotingYou.has(quotingYou.last)) { - quotingYou.last = 0; - posts = Unread.thread.posts.keys; - for (i = j = ref = posts.length - 1; j >= 0; i = j += -1) { - if (quotingYou.has(+posts[i])) { - quotingYou.last = posts[i]; - break; - } - } - } - return ThreadWatcher.update(g.SITE.ID, Unread.thread.board.ID, Unread.thread.ID, { - last: Unread.thread.lastPost, - isDead: Unread.thread.isDead, - isArchived: Unread.thread.isArchived, - unread: Unread.posts.size, - quotingYou: quotingYou.last || 0 - }); - } - }) - }; - - return Unread; - -}).call(this); - -UnreadIndex = (function() { - var UnreadIndex; - - UnreadIndex = { - lastReadPost: $.dict(), - hr: $.dict(), - markReadLink: $.dict(), - init: function() { - if (!(g.VIEW === 'index' && Conf['Remember Last Read Post'] && Conf['Unread Line in Index'])) { - return; - } - this.enabled = true; - this.db = new DataBoard('lastReadPosts', this.sync); - Callbacks.Thread.push({ - name: 'Unread Line in Index', - cb: this.node - }); - $.on(d, 'IndexRefreshInternal', this.onIndexRefresh); - return $.on(d, 'PostsInserted PostsRemoved', this.onPostsInserted); - }, - node: function() { - UnreadIndex.lastReadPost[this.fullID] = UnreadIndex.db.get({ - boardID: this.board.ID, - threadID: this.ID - }) || 0; - if (!Index.enabled) { - return UnreadIndex.update(this); - } - }, - onIndexRefresh: function(e) { - var i, len, ref, results, thread, threadID; - if (e.detail.isCatalog) { - return; - } - ref = e.detail.threadIDs; - results = []; - for (i = 0, len = ref.length; i < len; i++) { - threadID = ref[i]; - thread = g.threads.get(threadID); - results.push(UnreadIndex.update(thread)); - } - return results; - }, - onPostsInserted: function(e) { - var ref, ref1, thread, wasVisible; - if (e.target === Index.root) { - return; - } - thread = Get.threadFromNode(e.target); - if (!thread || thread.nodes.root !== e.target) { - return; - } - wasVisible = !!((ref = UnreadIndex.hr[thread.fullID]) != null ? ref.parentNode : void 0); - UnreadIndex.update(thread); - if (Conf['Scroll to Last Read Post'] && e.type === 'PostsInserted' && !wasVisible && !!((ref1 = UnreadIndex.hr[thread.fullID]) != null ? ref1.parentNode : void 0)) { - return Header.scrollToIfNeeded(UnreadIndex.hr[thread.fullID], true); - } - }, - sync: function() { - return g.threads.forEach(function(thread) { - var lastReadPost, ref; - lastReadPost = UnreadIndex.db.get({ - boardID: thread.board.ID, - threadID: thread.ID - }) || 0; - if (lastReadPost !== UnreadIndex.lastReadPost[thread.fullID]) { - UnreadIndex.lastReadPost[thread.fullID] = lastReadPost; - if ((ref = thread.nodes.root) != null ? ref.parentNode : void 0) { - return UnreadIndex.update(thread); - } - } - }); - }, - update: function(thread) { - var divider, firstUnread, hasUnread, hr, lastReadPost, link, repliesRead, repliesShown; - lastReadPost = UnreadIndex.lastReadPost[thread.fullID]; - repliesShown = 0; - repliesRead = 0; - firstUnread = null; - thread.posts.forEach(function(post) { - if (post.isReply && thread.nodes.root.contains(post.nodes.root)) { - repliesShown++; - if (post.ID <= lastReadPost) { - return repliesRead++; - } else if ((!firstUnread || post.ID < firstUnread.ID) && !post.isHidden && !QuoteYou.isYou(post)) { - return firstUnread = post; - } - } - }); - hr = UnreadIndex.hr[thread.fullID]; - if (firstUnread && (repliesRead || (lastReadPost === thread.OP.ID && (!$(g.SITE.selectors.summary, thread.nodes.root) || thread.ID in ExpandThread.statuses)))) { - if (!hr) { - hr = UnreadIndex.hr[thread.fullID] = $.el('hr', { - className: 'unread-line' - }); - } - $.before(firstUnread.nodes.root, hr); - } else { - $.rm(hr); - } - hasUnread = repliesShown ? firstUnread || !repliesRead : Index.enabled ? thread.lastPost > lastReadPost : thread.OP.ID > lastReadPost; - thread.nodes.root.classList.toggle('unread-thread', hasUnread); - link = UnreadIndex.markReadLink[thread.fullID]; - if (!link) { - link = UnreadIndex.markReadLink[thread.fullID] = $.el('a', { - className: 'unread-mark-read brackets-wrap', - href: 'javascript:;', - textContent: 'Mark Read' - }); - $.on(link, 'click', UnreadIndex.markRead); - } - if ((divider = $(g.SITE.selectors.threadDivider, thread.nodes.root))) { - return $.before(divider, link); - } else { - return $.add(thread.nodes.root, link); - } - }, - markRead: function() { - var thread; - thread = Get.threadFromNode(this); - UnreadIndex.lastReadPost[thread.fullID] = thread.lastPost; - UnreadIndex.db.set({ - boardID: thread.board.ID, - threadID: thread.ID, - val: thread.lastPost - }); - $.rm(UnreadIndex.hr[thread.fullID]); - thread.nodes.root.classList.remove('unread-thread'); - return ThreadWatcher.update(g.SITE.ID, thread.board.ID, thread.ID, { - last: thread.lastPost, - unread: 0, - quotingYou: 0 - }); - } - }; - - return UnreadIndex; - -}).call(this); - -Captcha = {}; - -(function() { - Captcha.cache = { - init: function() { - $.on(d, 'SaveCaptcha', (function(_this) { - return function(e) { - return _this.saveAPI(e.detail); - }; - })(this)); - return $.on(d, 'NoCaptcha', (function(_this) { - return function(e) { - return _this.noCaptcha(e.detail); - }; - })(this)); - }, - captchas: [], - getCount: function() { - return this.captchas.length; - }, - neededRaw: function() { - return !(this.haveCookie() || this.captchas.length || QR.req || this.submitCB) && (QR.posts.length > 1 || Conf['Auto-load captcha'] || !QR.posts[0].isOnlyQuotes() || QR.posts[0].file); - }, - needed: function() { - return this.neededRaw() && $.event('LoadCaptcha'); - }, - prerequest: function() { - if (!Conf['Prerequest Captcha']) { - return; - } - return $.queueTask((function(_this) { - return function() { - var isReply; - if (!_this.prerequested && _this.neededRaw() && !$.event('LoadCaptcha') && !QR.captcha.occupied() && QR.cooldown.seconds <= 60 && QR.selected === QR.posts[QR.posts.length - 1] && !QR.selected.isOnlyQuotes()) { - isReply = QR.selected.thread !== 'new'; - if (!$.event('RequestCaptcha', { - isReply: isReply - })) { - _this.prerequested = true; - _this.submitCB = function(captcha) { - if (captcha) { - return _this.save(captcha); - } - }; - return _this.updateCount(); - } - } - }; - })(this)); - }, - haveCookie: function() { - return /\b_ct=/.test(d.cookie) && QR.posts[0].thread !== 'new'; - }, - getOne: function() { - var captcha; - delete this.prerequested; - this.clear(); - if ((captcha = this.captchas.shift())) { - this.count(); - return captcha; - } else { - return null; - } - }, - request: function(isReply) { - if (!this.submitCB) { - if ($.event('RequestCaptcha', { - isReply: isReply - })) { - return; - } - } - return (function(_this) { - return function(cb) { - _this.submitCB = cb; - return _this.updateCount(); - }; - })(this); - }, - abort: function() { - if (this.submitCB) { - delete this.submitCB; - $.event('AbortCaptcha'); - return this.updateCount(); - } - }, - saveAPI: function(captcha) { - var cb; - if ((cb = this.submitCB)) { - delete this.submitCB; - cb(captcha); - return this.updateCount(); - } else { - return this.save(captcha); - } - }, - noCaptcha: function(detail) { - var cb; - if ((cb = this.submitCB)) { - if (!this.haveCookie() || (detail != null ? detail.error : void 0)) { - QR.error((detail != null ? detail.error : void 0) || 'Failed to retrieve captcha.'); - QR.captcha.setup(d.activeElement === QR.nodes.status); - } - delete this.submitCB; - cb(); - return this.updateCount(); - } - }, - save: function(captcha) { - var cb; - if ((cb = this.submitCB)) { - this.abort(); - cb(captcha); - return; - } - this.captchas.push(captcha); - this.captchas.sort(function(a, b) { - return a.timeout - b.timeout; - }); - return this.count(); - }, - clear: function() { - var captcha, i, j, len, now, ref; - if (this.captchas.length) { - now = Date.now(); - ref = this.captchas; - for (i = j = 0, len = ref.length; j < len; i = ++j) { - captcha = ref[i]; - if (captcha.timeout > now) { - break; - } - } - if (i) { - this.captchas = this.captchas.slice(i); - return this.count(); - } - } - }, - count: function() { - clearTimeout(this.timer); - if (this.captchas.length) { - this.timer = setTimeout(this.clear.bind(this), this.captchas[0].timeout - Date.now()); - } - return this.updateCount(); - }, - updateCount: function() { - return $.event('CaptchaCount', this.captchas.length); - } - }; - -}).call(this); - -(function() { - Captcha.replace = { - init: function() { - var ref; - if (!(g.SITE.software === 'yotsuba' && d.cookie.indexOf('pass_enabled=1') < 0)) { - return; - } - if (Conf['Force Noscript Captcha'] && Main.jsEnabled) { - $.ready(Captcha.replace.noscript); - return; - } - if (Conf['captchaLanguage'].trim()) { - if ((ref = location.hostname) === 'boards.4chan.org' || ref === 'boards.4channel.org') { - return $.onExists(doc, '#captchaFormPart', function(node) { - return $.onExists(node, 'iframe[src^="https://www.google.com/recaptcha/"]', Captcha.replace.iframe); - }); - } else { - return $.onExists(doc, 'iframe[src^="https://www.google.com/recaptcha/"]', Captcha.replace.iframe); - } - } - }, - noscript: function() { - var insert, noscript, original, span, toggle; - if (!((original = $('#g-recaptcha')) && (noscript = $('noscript', original.parentNode)))) { - return; - } - span = $.el('span', { - id: 'captcha-forced-noscript' - }); - $.replace(noscript, span); - $.rm(original); - insert = function() { - span.innerHTML = noscript.textContent; - return Captcha.replace.iframe($('iframe[src^="https://www.google.com/recaptcha/"]', span)); - }; - if ((toggle = $('#togglePostFormLink a, #form-link'))) { - return $.on(toggle, 'click', insert); - } else { - return insert(); - } - }, - iframe: function(iframe) { - var lang, src; - if ((lang = Conf['captchaLanguage'].trim())) { - src = /[?&]hl=/.test(iframe.src) ? iframe.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang)) : iframe.src + ("&hl=" + (encodeURIComponent(lang))); - if (iframe.src !== src) { - iframe.src = src; - } - } - } - }; - -}).call(this); - -(function() { - Captcha.t = { - init: function() { - var root; - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - return; - } - if (!(this.isEnabled = !!$('#t-root') || !$.id('postForm'))) { - return; - } - root = $.el('div', { - className: 'captcha-root' - }); - this.nodes = { - root: root - }; - $.addClass(QR.nodes.el, 'has-captcha', 'captcha-t'); - return $.after(QR.nodes.com.parentNode, root); - }, - moreNeeded: function() {}, - getThread: function() { - var boardID, threadID; - boardID = g.BOARD.ID; - if (QR.posts[0].thread === 'new') { - threadID = '0'; - } else { - threadID = '' + QR.posts[0].thread; - } - return { - boardID: boardID, - threadID: threadID - }; - }, - setup: function(focus) { - if (!this.isEnabled) { - return; - } - if (!this.nodes.container) { - this.nodes.container = $.el('div', { - className: 'captcha-container' - }); - $.prepend(this.nodes.root, this.nodes.container); - Captcha.t.currentThread = Captcha.t.getThread(); - $.global(function() { - var el; - el = document.querySelector('#qr .captcha-container'); - window.TCaptcha.init(el, this.boardID, +this.threadID); - return window.TCaptcha.setErrorCb(function(err) { - return window.dispatchEvent(new CustomEvent('CreateNotification', { - detail: { - type: 'warning', - content: '' + err - } - })); - }); - }, Captcha.t.currentThread); - } - if (focus) { - return $('#t-resp').focus(); - } - }, - destroy: function() { - if (!(this.isEnabled && this.nodes.container)) { - return; - } - $.global(function() { - return window.TCaptcha.destroy(); - }); - $.rm(this.nodes.container); - return delete this.nodes.container; - }, - updateThread: function() { - var boardID, newThread, ref, threadID; - if (!this.isEnabled) { - return; - } - ref = Captcha.t.currentThread || {}, boardID = ref.boardID, threadID = ref.threadID; - newThread = Captcha.t.getThread(); - if (!(newThread.boardID === boardID && newThread.threadID === threadID)) { - Captcha.t.destroy(); - return Captcha.t.setup(); - } - }, - getOne: function() { - var el, i, key, len, ref, response; - response = {}; - if (this.nodes.container) { - ref = ['t-response', 't-challenge']; - for (i = 0, len = ref.length; i < len; i++) { - key = ref[i]; - response[key] = $("[name='" + key + "']", this.nodes.container).value; - } - } - if (!response['t-response'] && !((el = $('#t-msg')) && /Verification not required/i.test(el.textContent))) { - response = null; - } - return response; - }, - setUsed: function() { - if (!this.isEnabled) { - return; - } - if (this.nodes.container) { - return $.global(function() { - return window.TCaptcha.clearChallenge(); - }); - } - }, - occupied: function() { - return !!this.nodes.container; - } - }; - -}).call(this); - -(function() { - var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Captcha.v2 = { - lifetime: 2 * $.MINUTE, - init: function() { - var counter, root; - if (d.cookie.indexOf('pass_enabled=1') >= 0) { - return; - } - if (!(this.isEnabled = !!$('#g-recaptcha, #captcha-forced-noscript') || !$.id('postForm'))) { - return; - } - if ((this.noscript = Conf['Force Noscript Captcha'] || !Main.jsEnabled)) { - $.addClass(QR.nodes.el, 'noscript-captcha'); - } - Captcha.cache.init(); - $.on(d, 'CaptchaCount', this.count.bind(this)); - root = $.el('div', { - className: 'captcha-root' - }); - $.extend(root, {innerHTML: "
        "}); - counter = $('.captcha-counter > a', root); - this.nodes = { - root: root, - counter: counter - }; - this.count(); - $.addClass(QR.nodes.el, 'has-captcha', 'captcha-v2'); - $.after(QR.nodes.com.parentNode, root); - $.on(counter, 'click', this.toggle.bind(this)); - $.on(counter, 'keydown', (function(_this) { - return function(e) { - if (Keybinds.keyCode(e) !== 'Space') { - return; - } - _this.toggle(); - e.preventDefault(); - return e.stopPropagation(); - }; - })(this)); - return $.on(window, 'captcha:success', (function(_this) { - return function() { - return $.queueTask(function() { - return _this.save(false); - }); - }; - })(this)); - }, - timeouts: {}, - prevNeeded: 0, - noscriptURL: function() { - var lang, url; - url = 'https://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc'; - if ((lang = Conf['captchaLanguage'].trim())) { - url += "&hl=" + (encodeURIComponent(lang)); - } - return url; - }, - moreNeeded: function() { - return $.queueTask((function(_this) { - return function() { - var needed; - needed = Captcha.cache.needed(); - if (needed && !_this.prevNeeded) { - _this.setup(QR.cooldown.auto && d.activeElement === QR.nodes.status); - } - return _this.prevNeeded = needed; - }; - })(this)); - }, - toggle: function() { - if (this.nodes.container && !this.timeouts.destroy) { - return this.destroy(); - } else { - return this.setup(true, true); - } - }, - setup: function(focus, force) { - if (!(this.isEnabled && (Captcha.cache.needed() || force))) { - return; - } - if (focus) { - $.addClass(QR.nodes.el, 'focus'); - this.nodes.counter.focus(); - } - if (this.timeouts.destroy) { - clearTimeout(this.timeouts.destroy); - delete this.timeouts.destroy; - return this.reload(); - } - if (this.nodes.container) { - $.queueTask((function(_this) { - return function() { - var iframe; - if (_this.nodes.container && d.activeElement === _this.nodes.counter && (iframe = $('iframe[src^="https://www.google.com/recaptcha/"]', _this.nodes.container))) { - iframe.focus(); - return QR.focus(); - } - }; - })(this)); - return; - } - this.nodes.container = $.el('div', { - className: 'captcha-container' - }); - $.prepend(this.nodes.root, this.nodes.container); - new MutationObserver(this.afterSetup.bind(this)).observe(this.nodes.container, { - childList: true, - subtree: true - }); - if (this.noscript) { - return this.setupNoscript(); - } else { - return this.setupJS(); - } - }, - setupNoscript: function() { - var div, iframe, textarea; - iframe = $.el('iframe', { - id: 'qr-captcha-iframe', - scrolling: 'no', - src: this.noscriptURL() - }); - div = $.el('div'); - textarea = $.el('textarea'); - $.add(div, textarea); - return $.add(this.nodes.container, [iframe, div]); - }, - setupJS: function() { - return $.global(function() { - var cbNative, render, script; - render = function() { - var classList, container; - classList = document.documentElement.classList; - container = document.querySelector('#qr .captcha-container'); - return container.dataset.widgetID = window.grecaptcha.render(container, { - sitekey: '6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc', - theme: classList.contains('tomorrow') || classList.contains('spooky') || classList.contains('dark-captcha') ? 'dark' : 'light', - callback: function(response) { - return window.dispatchEvent(new CustomEvent('captcha:success', { - detail: response - })); - } - }); - }; - if (window.grecaptcha) { - return render(); - } else { - cbNative = window.onRecaptchaLoaded; - window.onRecaptchaLoaded = function() { - render(); - return cbNative(); - }; - if (!document.head.querySelector('script[src^="https://www.google.com/recaptcha/api.js"]')) { - script = document.createElement('script'); - script.src = 'https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoaded&render=explicit'; - return document.head.appendChild(script); - } - } - }); - }, - afterSetup: function(mutations) { - var i, iframe, j, len, len1, mutation, node, ref, textarea; - for (i = 0, len = mutations.length; i < len; i++) { - mutation = mutations[i]; - ref = mutation.addedNodes; - for (j = 0, len1 = ref.length; j < len1; j++) { - node = ref[j]; - if ((iframe = $.x('./descendant-or-self::iframe[starts-with(@src, "https://www.google.com/recaptcha/")]', node))) { - this.setupIFrame(iframe); - } - if ((textarea = $.x('./descendant-or-self::textarea', node))) { - this.setupTextArea(textarea); - } - } - } - }, - setupIFrame: function(iframe) { - var ref, ref1; - if (!doc.contains(iframe)) { - return; - } - Captcha.replace.iframe(iframe); - $.addClass(QR.nodes.el, 'captcha-open'); - this.fixQRPosition(); - $.on(iframe, 'load', this.fixQRPosition); - if (d.activeElement === this.nodes.counter) { - iframe.focus(); - } - if (((ref = $.engine) === 'blink' || ref === 'edge') && (ref1 = iframe.parentNode, indexOf.call($$('#qr .captcha-container > div > div:first-of-type'), ref1) >= 0)) { - return $.on(iframe.parentNode, 'scroll', function() { - return this.scrollTop = 0; - }); - } - }, - fixQRPosition: function() { - if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) { - QR.nodes.el.style.top = ''; - return QR.nodes.el.style.bottom = '0px'; - } - }, - setupTextArea: function(textarea) { - return $.one(textarea, 'input', (function(_this) { - return function() { - return _this.save(true); - }; - })(this)); - }, - destroy: function() { - if (!this.isEnabled) { - return; - } - delete this.timeouts.destroy; - $.rmClass(QR.nodes.el, 'captcha-open'); - if (this.nodes.container) { - $.global(function() { - var container; - container = document.querySelector('#qr .captcha-container'); - return window.grecaptcha.reset(container.dataset.widgetID); - }); - $.rm(this.nodes.container); - return delete this.nodes.container; - } - }, - getOne: function(isReply) { - return Captcha.cache.getOne(isReply); - }, - save: function(pasted, token) { - var base, focus, ref; - Captcha.cache.save({ - response: token || $('textarea', this.nodes.container).value, - timeout: Date.now() + this.lifetime - }); - focus = ((ref = d.activeElement) != null ? ref.nodeName : void 0) === 'IFRAME' && /https?:\/\/www\.google\.com\/recaptcha\//.test(d.activeElement.src); - if (Captcha.cache.needed()) { - if (focus) { - if (QR.cooldown.auto || Conf['Post on Captcha Completion']) { - this.nodes.counter.focus(); - } else { - QR.nodes.status.focus(); - } - } - this.reload(); - } else { - if (pasted) { - this.destroy(); - } else { - if ((base = this.timeouts).destroy == null) { - base.destroy = setTimeout(this.destroy.bind(this), 3 * $.SECOND); - } - } - if (focus) { - QR.nodes.status.focus(); - } - } - if (Conf['Post on Captcha Completion'] && !QR.cooldown.auto) { - return QR.submit(); - } - }, - count: function() { - var count, loading; - count = Captcha.cache.getCount(); - loading = Captcha.cache.submitCB ? '...' : ''; - this.nodes.counter.textContent = "Captchas: " + count + loading; - return this.moreNeeded(); - }, - reload: function() { - if ($('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', this.nodes.container)) { - this.destroy(); - return this.setup(false, true); - } else { - return $.global(function() { - var container; - container = document.querySelector('#qr .captcha-container'); - return window.grecaptcha.reset(container.dataset.widgetID); - }); - } - }, - occupied: function() { - return !!this.nodes.container && !this.timeouts.destroy; - } - }; - -}).call(this); - -PassLink = (function() { - var PassLink; - - PassLink = { - init: function() { - if (!(g.SITE.software === 'yotsuba' && Conf['Pass Link'])) { - return; - } - return Main.ready(this.ready); - }, - ready: function() { - var passLink, styleSelector; - if (!(styleSelector = $.id('styleSelector'))) { - return; - } - passLink = $.el('span', { - className: 'brackets-wrap pass-link-container' - }); - $.extend(passLink, {innerHTML: "4chan Pass"}); - $.on(passLink.firstElementChild, 'click', function() { - return window.open("//sys." + (location.hostname.split('.')[1]) + ".org/auth", Date.now(), 'width=500,height=280,toolbar=0'); - }); - return $.before(styleSelector.previousSibling, [passLink, $.tn('\u00A0\u00A0')]); - } - }; - - return PassLink; - -}).call(this); - -PostRedirect = (function() { - var PostRedirect; - - PostRedirect = { - init: function() { - return $.on(d, 'QRPostSuccessful', (function(_this) { - return function(e) { - if (!e.detail.redirect) { - return; - } - _this.event = e; - _this.delays = 0; - return $.queueTask(function() { - if (e === _this.event && _this.delays === 0) { - return location.href = e.detail.redirect; - } - }); - }; - })(this)); - }, - delays: 0, - delay: function() { - var e; - if (!this.event) { - return null; - } - e = this.event; - this.delays++; - return (function(_this) { - return function() { - if (e !== _this.event) { - return; - } - _this.delays--; - if (_this.delays === 0) { - return location.href = e.detail.redirect; - } - }; - })(this); - } - }; - - return PostRedirect; - -}).call(this); - -PostSuccessful = (function() { - var PostSuccessful; - - PostSuccessful = { - init: function() { - if (!Conf['Remember Your Posts']) { - return; - } - return $.ready(this.ready); - }, - ready: function() { - var _, db, postID, ref, threadID; - if (d.title !== 'Post successful!') { - return; - } - ref = $('h1').nextSibling.textContent.match(/thread:(\d+),no:(\d+)/), _ = ref[0], threadID = ref[1], postID = ref[2]; - postID = +postID; - threadID = +threadID || postID; - db = new DataBoard('yourPosts'); - return db.set({ - boardID: g.BOARD.ID, - threadID: threadID, - postID: postID, - val: true - }); - } - }; - - return PostSuccessful; - -}).call(this); - -QR = (function() { - var QR, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - QR = { - 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: function() { - var sc; - if (!Conf['Quick Reply']) { - return; - } - this.posts = []; - $.on(d, '4chanXInitFinished', function() { - return BoardConfig.ready(QR.initReady); - }); - Callbacks.Post.push({ - name: 'Quick Reply', - cb: this.node - }); - this.shortcut = sc = $.el('a', { - className: 'fa fa-comment-o disabled', - textContent: 'QR', - title: 'Quick Reply', - href: 'javascript:;' - }); - $.on(sc, 'click', function() { - if (!QR.postingIsEnabled) { - return; - } - if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) { - QR.open(); - return QR.nodes.com.focus(); - } else { - return QR.close(); - } - }); - return Header.addShortcut('qr', sc, 540); - }, - initReady: function() { - var captchaVersion, config, link, linkBot, navLinksBot, origToggle, prop; - captchaVersion = $('#g-recaptcha, #captcha-forced-noscript') ? 'v2' : 't'; - QR.captcha = Captcha[captchaVersion]; - QR.postingIsEnabled = true; - config = g.BOARD.config; - prop = function(key, def) { - var ref; - return +((ref = config[key]) != null ? ref : def); - }; - QR.min_width = prop('min_image_width', 1); - QR.min_height = prop('min_image_height', 1); - QR.max_width = QR.max_height = 10000; - QR.max_size = prop('max_filesize', 4194304); - QR.max_size_video = prop('max_webm_filesize', QR.max_size); - QR.max_comment = prop('max_comment_chars', 2000); - QR.max_width_video = QR.max_height_video = 2048; - QR.max_duration_video = prop('max_webm_duration', 120); - QR.forcedAnon = !!config.forced_anon; - QR.spoiler = !!config.spoilers; - if ((origToggle = $.id('togglePostFormLink'))) { - link = $.el('h1', { - className: "qr-link-container" - }); - $.extend(link, {innerHTML: "" + ((g.VIEW === "thread") ? "Reply to Thread" : "Start a Thread") + ""}); - QR.link = link.firstElementChild; - $.on(link.firstChild, 'click', function() { - QR.open(); - return QR.nodes.com.focus(); - }); - $.before(origToggle, link); - origToggle.firstElementChild.textContent = 'Original Form'; - } - if (g.VIEW === 'thread') { - linkBot = $.el('div', { - className: "brackets-wrap qr-link-container-bottom" - }); - $.extend(linkBot, {innerHTML: "Reply to Thread"}); - $.on(linkBot.firstElementChild, 'click', function() { - QR.open(); - return QR.nodes.com.focus(); - }); - if ((navLinksBot = $('.navLinksBot'))) { - $.prepend(navLinksBot, linkBot); - } - } - $.on(d, 'QRGetFile', QR.getFile); - $.on(d, 'QRDrawFile', QR.drawFile); - $.on(d, 'QRSetFile', QR.setFile); - $.on(d, 'paste', QR.paste); - $.on(d, 'dragover', QR.dragOver); - $.on(d, 'drop', QR.dropFile); - $.on(d, 'dragstart dragend', QR.drag); - $.on(d, 'IndexRefreshInternal', QR.generatePostableThreadsList); - $.on(d, 'ThreadUpdate', QR.statusCheck); - if (!Conf['Persistent QR']) { - return; - } - QR.open(); - if (Conf['Auto Hide QR']) { - return QR.hide(); - } - }, - statusCheck: function() { - var thread; - if (!QR.nodes) { - return; - } - thread = QR.posts[0].thread; - if (thread !== 'new' && g.threads.get(g.BOARD + "." + thread).isDead) { - return QR.abort(); - } else { - return QR.status(); - } - }, - node: function() { - $.on(this.nodes.quote, 'click', QR.quote); - if (this.isFetchedQuote) { - return QR.generatePostableThreadsList(); - } - }, - open: function() { - var err; - if (QR.nodes) { - if (QR.nodes.el.hidden) { - QR.captcha.setup(); - } - QR.nodes.el.hidden = false; - QR.unhide(); - } else { - try { - QR.dialog(); - } catch (error) { - err = error; - delete QR.nodes; - Main.handleErrors({ - message: 'Quick Reply dialog creation crashed.', - error: err - }); - return; - } - } - return $.rmClass(QR.shortcut, 'disabled'); - }, - close: function() { - var j, len, post, ref; - if (QR.req) { - QR.abort(); - return; - } - QR.nodes.el.hidden = true; - QR.cleanNotifications(); - QR.blur(); - $.rmClass(QR.nodes.el, 'dump'); - $.addClass(QR.shortcut, 'disabled'); - new QR.post(true); - ref = QR.posts.splice(0, QR.posts.length - 1); - for (j = 0, len = ref.length; j < len; j++) { - post = ref[j]; - post["delete"](); - } - QR.cooldown.auto = false; - QR.status(); - return QR.captcha.destroy(); - }, - focus: function() { - return $.queueTask(function() { - if (!QR.inBubble()) { - QR.hasFocus = d.activeElement && QR.nodes.el.contains(d.activeElement); - return QR.nodes.el.classList.toggle('focus', QR.hasFocus); - } - }); - }, - inBubble: function() { - var bubbles, ref; - bubbles = $$('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); - return (ref = d.activeElement, indexOf.call(bubbles, ref) >= 0) || bubbles.some(function(el) { - return getComputedStyle(el).visibility !== 'hidden' && el.getBoundingClientRect().bottom > 0; - }); - }, - hide: function() { - QR.blur(); - $.addClass(QR.nodes.el, 'autohide'); - return QR.nodes.autohide.checked = true; - }, - unhide: function() { - $.rmClass(QR.nodes.el, 'autohide'); - return QR.nodes.autohide.checked = false; - }, - toggleHide: function() { - if (this.checked) { - return QR.hide(); - } else { - return QR.unhide(); - } - }, - blur: function() { - if (QR.nodes.el.contains(d.activeElement)) { - return d.activeElement.blur(); - } - }, - toggleSJIS: function(e) { - e.preventDefault(); - Conf['sjisPreview'] = !Conf['sjisPreview']; - $.set('sjisPreview', Conf['sjisPreview']); - return QR.nodes.el.classList.toggle('sjis-preview', Conf['sjisPreview']); - }, - texPreviewShow: function() { - if ($.hasClass(QR.nodes.el, 'tex-preview')) { - return QR.texPreviewHide(); - } - $.addClass(QR.nodes.el, 'tex-preview'); - QR.nodes.texPreview.textContent = QR.nodes.com.value; - return $.event('mathjax', null, QR.nodes.texPreview); - }, - texPreviewHide: function() { - return $.rmClass(QR.nodes.el, 'tex-preview'); - }, - addPost: function() { - var wasOpen; - wasOpen = QR.nodes && !QR.nodes.el.hidden; - QR.open(); - if (wasOpen) { - $.addClass(QR.nodes.el, 'dump'); - new QR.post(true); - } - return QR.nodes.com.focus(); - }, - setCustomCooldown: function(enabled) { - Conf['customCooldownEnabled'] = enabled; - QR.cooldown.customCooldown = enabled; - return QR.nodes.customCooldown.classList.toggle('disabled', !enabled); - }, - toggleCustomCooldown: function() { - var enabled; - enabled = $.hasClass(QR.nodes.customCooldown, 'disabled'); - QR.setCustomCooldown(enabled); - return $.set('customCooldownEnabled', enabled); - }, - error: function(err, focusOverride) { - var el, notice, notif; - QR.open(); - if (typeof err === 'string') { - el = $.tn(err); - } else { - el = err; - el.removeAttribute('style'); - } - notice = new Notice('warning', el); - QR.notifications.push(notice); - if (!Header.areNotificationsEnabled) { - if (d.hidden && !QR.cooldown.auto) { - return alert(el.textContent); - } - } else if (d.hidden || !(focusOverride || d.hasFocus())) { - notif = new Notification(el.textContent, { - body: el.textContent, - icon: Favicon.logo - }); - notif.onclick = function() { - return window.focus(); - }; - if ($.engine !== 'gecko') { - notif.onclose = function() { - return notice.close(); - }; - return notif.onshow = function() { - return setTimeout(function() { - notif.onclose = null; - return notif.close(); - }, 7 * $.SECOND); - }; - } - } - }, - connectionError: function() { - return $.el('span', {innerHTML: "Connection error while posting. [More info]"}); - }, - notifications: [], - cleanNotifications: function() { - var j, len, notification, ref; - ref = QR.notifications; - for (j = 0, len = ref.length; j < len; j++) { - notification = ref[j]; - notification.close(); - } - return QR.notifications = []; - }, - status: function() { - var disabled, status, thread, value; - if (!QR.nodes) { - return; - } - thread = QR.posts[0].thread; - if (thread !== 'new' && g.threads.get(g.BOARD + "." + thread).isDead) { - value = 'Dead'; - disabled = true; - QR.cooldown.auto = false; - } - value = QR.req ? QR.req.progress : QR.cooldown.seconds || value; - status = QR.nodes.status; - status.value = !value ? 'Submit' : QR.cooldown.auto ? "Auto " + value : value; - return status.disabled = disabled || false; - }, - openPost: function() { - var index; - QR.open(); - if (QR.selected.isLocked) { - index = QR.posts.indexOf(QR.selected); - (QR.posts[index + 1] || new QR.post()).select(); - $.addClass(QR.nodes.el, 'dump'); - return QR.cooldown.auto = true; - } - }, - quote: function(e) { - var ancestor, base, caretPos, com, frag, i, insideCode, j, k, l, len, len1, len2, len3, n, node, o, post, postRange, range, ref, ref1, ref2, ref3, ref4, ref5, ref6, root, sel, text, thread, wasOnlyQuotes; - if (e != null) { - e.preventDefault(); - } - if (!QR.postingIsEnabled) { - return; - } - sel = d.getSelection(); - post = Get.postFromNode(this); - root = post.nodes.root; - postRange = new Range(); - postRange.selectNode(root); - text = post.board.ID === g.BOARD.ID ? ">>" + post + "\n" : ">>>/" + post.board + "/" + post + "\n"; - for (i = j = 0, ref = sel.rangeCount; 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) { - try { - range = sel.getRangeAt(i); - if (range.compareBoundaryPoints(Range.START_TO_START, postRange) < 0) { - range.setStartBefore(root); - } - if (range.compareBoundaryPoints(Range.END_TO_END, postRange) > 0) { - range.setEndAfter(root); - } - if (!range.toString().trim()) { - continue; - } - frag = range.cloneContents(); - ancestor = range.commonAncestorContainer; - if ($.x('ancestor-or-self::*[self::s or contains(@class,"removed-spoiler")]', ancestor)) { - $.prepend(frag, $.tn('[spoiler]')); - $.add(frag, $.tn('[/spoiler]')); - } - if (insideCode = $.x('ancestor-or-self::pre[contains(@class,"prettyprint")]', ancestor)) { - $.prepend(frag, $.tn('[code]')); - $.add(frag, $.tn('[/code]')); - } - ref1 = $$((insideCode ? 'br' : '.prettyprint br'), frag); - for (k = 0, len = ref1.length; k < len; k++) { - node = ref1[k]; - $.replace(node, $.tn('\n')); - } - ref2 = $$('br', frag); - for (l = 0, len1 = ref2.length; l < len1; l++) { - node = ref2[l]; - if (node !== frag.lastChild) { - $.replace(node, $.tn('\n>')); - } - } - if (typeof (base = g.SITE).insertTags === "function") { - base.insertTags(frag); - } - ref3 = $$('.linkify[data-original]', frag); - for (n = 0, len2 = ref3.length; n < len2; n++) { - node = ref3[n]; - $.replace(node, $.tn(node.dataset.original)); - } - ref4 = $$('.embedder', frag); - for (o = 0, len3 = ref4.length; o < len3; o++) { - node = ref4[o]; - if (((ref5 = node.previousSibling) != null ? ref5.nodeValue : void 0) === ' ') { - $.rm(node.previousSibling); - } - $.rm(node); - } - text += ">" + (frag.textContent.trim()) + "\n"; - } catch (error) {} - } - QR.openPost(); - ref6 = QR.nodes, com = ref6.com, thread = ref6.thread; - if (!com.value) { - thread.value = Get.threadFromNode(this); - } - wasOnlyQuotes = QR.selected.isOnlyQuotes(); - caretPos = com.selectionStart; - com.value = com.value.slice(0, caretPos) + text + com.value.slice(com.selectionEnd); - range = caretPos + text.length; - com.setSelectionRange(range, range); - com.focus(); - if (wasOnlyQuotes) { - QR.selected.quotedText = com.value; - } - QR.selected.save(com); - return QR.selected.save(thread); - }, - characterCount: function() { - var count, counter; - counter = QR.nodes.charCount; - count = QR.nodes.com.value.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '_').length; - counter.textContent = count; - counter.hidden = count < QR.max_comment / 2; - return (count > QR.max_comment ? $.addClass : $.rmClass)(counter, 'warning'); - }, - getFile: function() { - var ref; - return $.event('QRFile', (ref = QR.selected) != null ? ref.file : void 0); - }, - drawFile: function(e) { - var el, file, isVideo, ref; - file = (ref = QR.selected) != null ? ref.file : void 0; - if (!(file && /^(image|video)\//.test(file.type))) { - return; - } - isVideo = /^video\//.test(file); - el = $.el((isVideo ? 'video' : 'img')); - $.on(el, 'error', function() { - return QR.openError(); - }); - $.on(el, (isVideo ? 'loadeddata' : 'load'), function() { - e.target.getContext('2d').drawImage(el, 0, 0); - URL.revokeObjectURL(el.src); - return $.event('QRImageDrawn', null, e.target); - }); - return el.src = URL.createObjectURL(file); - }, - openError: function() { - var div; - div = $.el('div'); - $.extend(div, {innerHTML: "Could not open file. [More info]"}); - return QR.error(div); - }, - setFile: function(e) { - var file, name, ref, source; - ref = e.detail, file = ref.file, name = ref.name, source = ref.source; - if (name != null) { - file.name = name; - } - if (source != null) { - file.source = source; - } - QR.open(); - return QR.handleFiles([file]); - }, - drag: function(e) { - var toggle; - toggle = e.type === 'dragstart' ? $.off : $.on; - toggle(d, 'dragover', QR.dragOver); - return toggle(d, 'drop', QR.dropFile); - }, - dragOver: function(e) { - e.preventDefault(); - return e.dataTransfer.dropEffect = 'copy'; - }, - dropFile: function(e) { - if (!e.dataTransfer.files.length) { - return; - } - e.preventDefault(); - QR.open(); - return QR.handleFiles(e.dataTransfer.files); - }, - paste: function(e) { - var blob, file, file2, item, j, len, ref, score, score2, type; - if (!e.clipboardData.items) { - return; - } - file = null; - score = -1; - ref = e.clipboardData.items; - for (j = 0, len = ref.length; j < len; j++) { - item = ref[j]; - if (!(item.kind === 'file' && (file2 = item.getAsFile()))) { - continue; - } - score2 = 2 * (file2.size <= QR.max_size) + (file2.type === 'image/png'); - if (score2 > score) { - file = file2; - score = score2; - } - } - if (file) { - type = file.type; - blob = new Blob([file], { - type: type - }); - blob.name = Conf['pastedname'] + "." + ($.getOwn(QR.extensionFromType, type) || 'jpg'); - QR.open(); - QR.handleFiles([blob]); - $.addClass(QR.nodes.el, 'dump'); - } - }, - pasteFF: function() { - var arr, blob, bstr, i, images, img, j, k, len, m, pasteArea, ref, src; - pasteArea = QR.nodes.pasteArea; - if (!pasteArea.childNodes.length) { - return; - } - images = $$('img', pasteArea); - $.rmAll(pasteArea); - for (j = 0, len = images.length; j < len; j++) { - img = images[j]; - src = img.src; - if (m = src.match(/data:(image\/(\w+));base64,(.+)/)) { - bstr = atob(m[3]); - arr = new Uint8Array(bstr.length); - for (i = k = 0, ref = bstr.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) { - arr[i] = bstr.charCodeAt(i); - } - blob = new Blob([arr], { - type: m[1] - }); - blob.name = Conf['pastedname'] + "." + m[2]; - QR.handleFiles([blob]); - } else if (/^https?:\/\//.test(src)) { - QR.handleUrl(src); - } - } - }, - handleUrl: function(urlDefault) { - QR.open(); - QR.selected.preventAutoPost(); - return CrossOrigin.permission(function() { - var url; - url = prompt('Enter a URL:', urlDefault); - if (url === null) { - return; - } - QR.nodes.fileButton.focus(); - return CrossOrigin.file(url, function(blob) { - if (blob && !/^text\//.test(blob.type)) { - return QR.handleFiles([blob]); - } else { - return QR.error("Can't load file."); - } - }); - }); - }, - handleFiles: function(files) { - var file, j, len; - if (this !== QR) { - files = slice.call(this.files); - this.value = null; - } - if (!files.length) { - return; - } - QR.cleanNotifications(); - for (j = 0, len = files.length; j < len; j++) { - file = files[j]; - QR.handleFile(file, files.length); - } - if (files.length !== 1) { - $.addClass(QR.nodes.el, 'dump'); - } - if (d.activeElement === QR.nodes.fileButton && $.hasClass(QR.nodes.fileSubmit, 'has-file')) { - return QR.nodes.filename.focus(); - } - }, - handleFile: function(file, nfiles) { - var isText, post; - isText = /^text\//.test(file.type); - if (nfiles === 1) { - post = QR.selected; - } else { - post = QR.posts[QR.posts.length - 1]; - if ((isText ? post.com || post.pasting : post.file)) { - post = new QR.post(); - } - } - return post[isText ? 'pasteText' : 'setFile'](file); - }, - openFileInput: function() { - if (QR.nodes.fileButton.disabled) { - return; - } - QR.nodes.fileInput.click(); - return QR.nodes.fileButton.focus(); - }, - generatePostableThreadsList: function() { - var j, len, list, options, ref, thread, val; - if (!QR.nodes) { - return; - } - list = QR.nodes.thread; - options = [list.firstElementChild]; - ref = g.BOARD.threads.keys; - for (j = 0, len = ref.length; j < len; j++) { - thread = ref[j]; - options.push($.el('option', { - value: thread, - textContent: "Thread " + thread - })); - } - val = list.value; - $.rmAll(list); - $.add(list, options); - list.value = val; - if (list.value === val) { - return; - } - list.value = g.VIEW === 'thread' ? g.THREADID : 'new'; - return (g.VIEW === 'thread' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread'); - }, - dialog: function() { - var classList, config, dialog, event, i, items, name, node, nodes, save, setNode; - QR.nodes = nodes = { - el: dialog = UI.dialog('qr', {innerHTML: "
        ×
        No selected file
        "}) - }; - setNode = function(name, query) { - return nodes[name] = $(query, dialog); - }; - setNode('move', '.move'); - setNode('autohide', '#autohide'); - setNode('close', '.close'); - setNode('thread', 'select'); - setNode('form', 'form'); - setNode('sjisToggle', '#sjis-toggle'); - setNode('texButton', '#tex-preview-button'); - setNode('name', '[data-name=name]'); - setNode('email', '[data-name=email]'); - setNode('sub', '[data-name=sub]'); - setNode('com', '[data-name=com]'); - setNode('charCount', '#char-count'); - setNode('texPreview', '#tex-preview'); - setNode('dumpList', '#dump-list'); - setNode('addPost', '#add-post'); - setNode('oekaki', '.oekaki'); - setNode('drawButton', '#qr-draw-button'); - setNode('fileSubmit', '#file-n-submit'); - setNode('fileButton', '#qr-file-button'); - setNode('noFile', '#qr-no-file'); - setNode('filename', '#qr-filename'); - setNode('spoiler', '#qr-file-spoiler'); - setNode('oekakiButton', '#qr-oekaki-button'); - setNode('fileRM', '#qr-filerm'); - setNode('urlButton', '#url-button'); - setNode('pasteArea', '#paste-area'); - setNode('customCooldown', '#custom-cooldown-button'); - setNode('dumpButton', '#dump-button'); - setNode('status', '[type=submit]'); - setNode('flashTag', '[name=filetag]'); - setNode('fileInput', '[type=file]'); - config = g.BOARD.config; - classList = QR.nodes.el.classList; - classList.toggle('forced-anon', QR.forcedAnon); - classList.toggle('has-spoiler', QR.spoiler); - classList.toggle('has-sjis', !!config.sjis_tags); - classList.toggle('has-math', !!config.math_tags); - classList.toggle('sjis-preview', !!config.sjis_tags && Conf['sjisPreview']); - classList.toggle('show-new-thread-option', Conf['Show New Thread Option in Threads']); - if (parseInt(Conf['customCooldown'], 10) > 0) { - $.addClass(QR.nodes.fileSubmit, 'custom-cooldown'); - $.get('customCooldownEnabled', Conf['customCooldownEnabled'], function(arg) { - var customCooldownEnabled; - customCooldownEnabled = arg.customCooldownEnabled; - QR.setCustomCooldown(customCooldownEnabled); - return $.sync('customCooldownEnabled', QR.setCustomCooldown); - }); - } - QR.flagsInput(); - $.on(nodes.autohide, 'change', QR.toggleHide); - $.on(nodes.close, 'click', QR.close); - $.on(nodes.status, 'click', QR.submit); - $.on(nodes.form, 'submit', QR.submit); - $.on(nodes.sjisToggle, 'click', QR.toggleSJIS); - $.on(nodes.texButton, 'mousedown', QR.texPreviewShow); - $.on(nodes.texButton, 'mouseup', QR.texPreviewHide); - $.on(nodes.addPost, 'click', function() { - return new QR.post(true); - }); - $.on(nodes.drawButton, 'click', QR.oekaki.draw); - $.on(nodes.fileButton, 'click', QR.openFileInput); - $.on(nodes.noFile, 'click', QR.openFileInput); - $.on(nodes.filename, 'focus', function() { - return $.addClass(this.parentNode, 'focus'); - }); - $.on(nodes.filename, 'blur', function() { - return $.rmClass(this.parentNode, 'focus'); - }); - $.on(nodes.spoiler, 'change', function() { - return QR.selected.nodes.spoiler.click(); - }); - $.on(nodes.oekakiButton, 'click', QR.oekaki.button); - $.on(nodes.fileRM, 'click', function() { - return QR.selected.rmFile(); - }); - $.on(nodes.urlButton, 'click', function() { - return QR.handleUrl(''); - }); - $.on(nodes.customCooldown, 'click', QR.toggleCustomCooldown); - $.on(nodes.dumpButton, 'click', function() { - return nodes.el.classList.toggle('dump'); - }); - $.on(nodes.fileInput, 'change', QR.handleFiles); - window.addEventListener('focus', QR.focus, true); - window.addEventListener('blur', QR.focus, true); - $.on(d, 'click', QR.focus); - if ($.engine === 'gecko' && !window.DataTransferItemList) { - nodes.pasteArea.hidden = false; - } - new MutationObserver(QR.pasteFF).observe(nodes.pasteArea, { - childList: true - }); - items = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag']; - i = 0; - save = function() { - return QR.selected.save(this); - }; - while (name = items[i++]) { - if (!(node = nodes[name])) { - continue; - } - event = node.nodeName === 'SELECT' ? 'change' : 'input'; - $.on(nodes[name], event, save); - } - if ($.engine === 'gecko' && Conf['Remember QR Size']) { - $.get('QR Size', '', function(item) { - return nodes.com.style.cssText = item['QR Size']; - }); - $.on(nodes.com, 'mouseup', function(e) { - if (e.button !== 0) { - return; - } - return $.set('QR Size', this.style.cssText); - }); - } - QR.generatePostableThreadsList(); - QR.persona.load(); - new QR.post(true); - QR.status(); - QR.cooldown.setup(); - QR.captcha.init(); - $.add(d.body, dialog); - QR.captcha.setup(); - QR.oekaki.setup(); - return $.event('QRDialogCreation', null, dialog); - }, - flags: function() { - var addFlag, ref, select, textContent, value; - select = $.el('select', { - name: 'flag', - className: 'flagSelector' - }); - addFlag = function(value, textContent) { - return $.add(select, $.el('option', { - value: value, - textContent: textContent - })); - }; - addFlag('0', (g.BOARD.config.country_flags ? 'Geographic Location' : 'None')); - ref = g.BOARD.config.board_flags; - for (value in ref) { - textContent = ref[value]; - addFlag(value, textContent); - } - return select; - }, - flagsInput: function() { - var flag, nodes; - nodes = QR.nodes; - if (!nodes) { - return; - } - if (nodes.flag) { - $.rm(nodes.flag); - delete nodes.flag; - } - if (g.BOARD.config.board_flags) { - flag = QR.flags(); - flag.dataset.name = 'flag'; - flag.dataset["default"] = '0'; - nodes.flag = flag; - return $.add(nodes.form, flag); - } - }, - submit: function(e) { - var captcha, cb, err, filetag, force, formData, options, post, ref, thread, threadID; - if (e != null) { - e.preventDefault(); - } - force = e != null ? e.shiftKey : void 0; - if (QR.req) { - QR.abort(); - return; - } - $.forceSync('cooldowns'); - if (QR.cooldown.seconds) { - if (force) { - QR.cooldown.clear(); - } else { - QR.cooldown.auto = !QR.cooldown.auto; - QR.status(); - return; - } - } - post = QR.posts[0]; - delete post.quotedText; - post.forceSave(); - threadID = post.thread; - thread = g.BOARD.threads.get(threadID); - if (g.BOARD.ID === 'f' && threadID === 'new') { - filetag = QR.nodes.flashTag.value; - } - if (threadID === 'new') { - threadID = null; - if (!!g.BOARD.config.require_subject && !post.sub) { - err = 'New threads require a subject.'; - } else if (!(!!g.BOARD.config.text_only || post.file)) { - err = 'No file selected.'; - } - } else if (g.BOARD.threads.get(threadID).isClosed) { - err = 'You can\'t reply to this thread anymore.'; - } else if (!(post.com || post.file)) { - err = 'No comment or file.'; - } else if (post.file && thread.fileLimit) { - err = 'Max limit of image replies has been reached.'; - } - if (g.BOARD.ID === 'r9k' && !((ref = post.com) != null ? ref.match(/[a-z-]/i) : void 0)) { - err || (err = 'Original comment required.'); - } - if (QR.captcha.isEnabled && !(QR.captcha === Captcha.v2 && /\b_ct=/.test(d.cookie) && threadID) && !(err && !force)) { - captcha = QR.captcha.getOne(!!threadID); - if (QR.captcha === Captcha.v2) { - captcha || (captcha = Captcha.cache.request(!!threadID)); - } - if (!captcha) { - err = 'No valid captcha.'; - QR.captcha.setup(!QR.cooldown.auto || d.activeElement === QR.nodes.status); - } - } - QR.cleanNotifications(); - if (err && !force) { - QR.cooldown.auto = false; - QR.status(); - QR.error(err); - return; - } - QR.cooldown.auto = QR.posts.length > 1; - post.lock(); - formData = { - MAX_FILE_SIZE: QR.max_size, - mode: 'regist', - pwd: QR.persona.getPassword(), - resto: threadID, - name: !QR.forcedAnon ? post.name : void 0, - email: post.email, - sub: !(QR.forcedAnon || threadID) ? post.sub : void 0, - com: post.com, - upfile: post.file, - filetag: filetag, - spoiler: post.spoiler, - flag: post.flag - }; - options = { - responseType: 'document', - withCredentials: true, - onloadend: QR.response, - form: $.formData(formData) - }; - if (Conf['Show Upload Progress']) { - options.onprogress = function(e) { - var ref1; - if (this !== ((ref1 = QR.req) != null ? ref1.upload : void 0)) { - return; - } - if (e.loaded < e.total) { - QR.req.progress = (Math.round(e.loaded / e.total * 100)) + "%"; - } else { - QR.req.isUploadFinished = true; - QR.req.progress = '...'; - } - return QR.status(); - }; - } - cb = function(response) { - var key, val; - if (response != null) { - QR.currentCaptcha = response; - if (QR.captcha === Captcha.v2) { - if (response.challenge != null) { - options.form.append('recaptcha_challenge_field', response.challenge); - options.form.append('recaptcha_response_field', response.response); - } else { - options.form.append('g-recaptcha-response', response.response); - } - } else { - for (key in response) { - val = response[key]; - options.form.append(key, val); - } - } - } - QR.req = $.ajax("https://sys." + (location.hostname.split('.')[1]) + ".org/" + g.BOARD + "/post", options); - return QR.req.progress = '...'; - }; - if (typeof captcha === 'function') { - QR.req = { - progress: '...', - abort: function() { - if (QR.captcha === Captcha.v2) { - Captcha.cache.abort(); - } - return cb = null; - } - }; - captcha(function(response) { - if (QR.captcha === Captcha.v2 && Captcha.cache.haveCookie()) { - if (typeof cb === "function") { - cb(); - } - if (response) { - return Captcha.cache.save(response); - } - } else if (response) { - return typeof cb === "function" ? cb(response) : void 0; - } else { - delete QR.req; - post.unlock(); - QR.cooldown.auto = !!Captcha.cache.getCount(); - return QR.status(); - } - }); - } else { - cb(captcha); - } - return QR.status(); - }, - response: function() { - var URL, _, base, connErr, err, h1, isReply, j, lastPostToThread, len, m, mi, open, post, postID, postsCount, ref, ref1, ref2, ref3, seconds, threadID; - if (this !== QR.req) { - return; - } - delete QR.req; - post = QR.posts[0]; - post.unlock(); - if ((err = (ref = this.response) != null ? ref.getElementById('errmsg') : void 0)) { - if ((ref1 = $('a', err)) != null) { - ref1.target = '_blank'; - } - } else if ((connErr = !this.response || this.response.title !== 'Post successful!')) { - err = QR.connectionError(); - if (QR.captcha === Captcha.v2 && QR.currentCaptcha) { - Captcha.cache.save(QR.currentCaptcha); - } - } else if (this.status !== 200) { - err = "Error " + this.statusText + " (" + this.status + ")"; - } - if (!connErr) { - if (typeof (base = QR.captcha).setUsed === "function") { - base.setUsed(); - } - } - delete QR.currentCaptcha; - if (err) { - QR.errorCount = (QR.errorCount || 0) + 1; - if (/captcha|verification/i.test(err.textContent) || connErr) { - if (/mistyped/i.test(err.textContent)) { - err = 'You mistyped the CAPTCHA, or the CAPTCHA malfunctioned.'; - } else if (/expired/i.test(err.textContent)) { - err = 'This CAPTCHA is no longer valid because it has expired.'; - } - if (QR.errorCount >= 5) { - QR.cooldown.auto = false; - } else { - QR.cooldown.auto = QR.captcha.isEnabled || connErr; - QR.cooldown.addDelay(post, 2); - } - } else if (err.textContent && (m = err.textContent.match(/\d+\s+(?:minute|second)/gi)) && !/duplicate|hour/i.test(err.textContent)) { - QR.cooldown.auto = !/have\s+been\s+muted/i.test(err.textContent); - seconds = 0; - for (j = 0, len = m.length; j < len; j++) { - mi = m[j]; - seconds += (/minute/i.test(mi) ? 60 : 1) * (+mi.match(/\d+/)[0]); - } - if (/muted/i.test(err.textContent)) { - QR.cooldown.addMute(seconds); - } else { - QR.cooldown.addDelay(post, seconds); - } - } else { - QR.cooldown.auto = false; - } - QR.captcha.setup(QR.cooldown.auto && ((ref2 = d.activeElement) === QR.nodes.status || ref2 === d.body)); - QR.status(); - QR.error(err); - return; - } - delete QR.errorCount; - h1 = $('h1', this.response); - ref3 = h1.nextSibling.textContent.match(/thread:(\d+),no:(\d+)/), _ = ref3[0], threadID = ref3[1], postID = ref3[2]; - postID = +postID; - threadID = +threadID || postID; - isReply = threadID !== postID; - $.event('QRPostSuccessful', { - boardID: g.BOARD.ID, - threadID: threadID, - postID: postID - }); - $.event('QRPostSuccessful_', { - boardID: g.BOARD.ID, - threadID: threadID, - postID: postID - }); - postsCount = QR.posts.length - 1; - QR.cooldown.auto = postsCount && isReply; - lastPostToThread = !((function() { - var k, len1, p, ref4; - ref4 = QR.posts.slice(1); - for (k = 0, len1 = ref4.length; k < len1; k++) { - p = ref4[k]; - if (p.thread === post.thread) { - return true; - } - } - })()); - if (postsCount) { - post.rm(); - QR.captcha.setup(d.activeElement === QR.nodes.status); - } else if (Conf['Persistent QR']) { - post.rm(); - if (Conf['Auto Hide QR']) { - QR.hide(); - } else { - QR.blur(); - } - } else { - QR.close(); - } - QR.cleanNotifications(); - if (Conf['Posting Success Notifications']) { - QR.notifications.push(new Notice('success', h1.textContent, 5)); - } - QR.cooldown.add(threadID, postID); - URL = threadID === postID ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID : threadID !== g.THREADID && lastPostToThread && Conf['Open Post in New Tab'] ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID + "#p" + postID : void 0; - if (URL) { - open = Conf['Open Post in New Tab'] || postsCount ? function() { - return $.open(URL); - } : function() { - return location.href = URL; - }; - if (threadID === postID) { - QR.waitForThread(URL, open); - } else { - open(); - } - } - return QR.status(); - }, - waitForThread: function(url, cb) { - var attempts, check; - attempts = 0; - check = function() { - return $.ajax(url, { - onloadend: function() { - attempts++; - if (attempts >= 6 || this.status === 200) { - return cb(); - } else { - return setTimeout(check, attempts * $.SECOND); - } - }, - responseType: 'text', - type: 'HEAD' - }); - }; - return check(); - }, - abort: function() { - var oldReq; - if ((oldReq = QR.req) && !QR.req.isUploadFinished) { - delete QR.req; - oldReq.abort(); - if (QR.captcha === Captcha.v2 && QR.currentCaptcha) { - Captcha.cache.save(QR.currentCaptcha); - } - delete QR.currentCaptcha; - QR.posts[0].unlock(); - QR.cooldown.auto = false; - QR.notifications.push(new Notice('info', 'QR upload aborted.', 5)); - } - return QR.status(); - } - }; - - return QR; - -}).call(this); - -(function() { - QR.cooldown = { - seconds: 0, - delays: { - deletion: 60 - }, - init: function() { - if (!Conf['Quick Reply']) { - return; - } - this.data = Conf['cooldowns']; - this.changes = $.dict(); - return $.sync('cooldowns', this.sync); - }, - setup: function() { - var delay, ref, type; - $.extend(QR.cooldown.delays, g.BOARD.cooldowns()); - QR.cooldown.maxDelay = 0; - ref = QR.cooldown.delays; - for (type in ref) { - delay = ref[type]; - if (type !== 'thread' && type !== 'thread_global') { - QR.cooldown.maxDelay = Math.max(QR.cooldown.maxDelay, delay); - } - } - QR.cooldown.isSetup = true; - return QR.cooldown.start(); - }, - start: function() { - var data; - data = QR.cooldown.data; - if (!(Conf['Cooldown'] && QR.cooldown.isSetup && !QR.cooldown.isCounting && Object.keys(data[g.BOARD.ID] || {}).length + Object.keys(data.global || {}).length > 0)) { - return; - } - QR.cooldown.isCounting = true; - return QR.cooldown.count(); - }, - sync: function(data) { - QR.cooldown.data = data || $.dict(); - return QR.cooldown.start(); - }, - add: function(threadID, postID) { - var boardID, start; - if (!Conf['Cooldown']) { - return; - } - start = Date.now(); - boardID = g.BOARD.ID; - QR.cooldown.set(boardID, start, { - threadID: threadID, - postID: postID - }); - if (threadID === postID) { - QR.cooldown.set('global', start, { - boardID: boardID, - threadID: threadID, - postID: postID - }); - } - QR.cooldown.save(); - return QR.cooldown.start(); - }, - addDelay: function(post, delay) { - var cooldown; - if (!Conf['Cooldown']) { - return; - } - cooldown = QR.cooldown.categorize(post); - cooldown.delay = delay; - QR.cooldown.set(g.BOARD.ID, Date.now(), cooldown); - QR.cooldown.save(); - return QR.cooldown.start(); - }, - addMute: function(delay) { - if (!Conf['Cooldown']) { - return; - } - QR.cooldown.set(g.BOARD.ID, Date.now(), { - type: 'mute', - delay: delay - }); - QR.cooldown.save(); - return QR.cooldown.start(); - }, - "delete": function(post) { - var base, cooldown, cooldowns, id, name; - if (!QR.cooldown.data) { - return; - } - cooldowns = ((base = QR.cooldown.data)[name = post.board.ID] || (base[name] = $.dict())); - for (id in cooldowns) { - cooldown = cooldowns[id]; - if ((cooldown.delay == null) && cooldown.threadID === post.thread.ID && cooldown.postID === post.ID) { - QR.cooldown.set(post.board.ID, id, null); - } - } - return QR.cooldown.save(); - }, - secondsDeletion: function(post) { - var cooldown, cooldowns, seconds, start; - if (!(QR.cooldown.data && Conf['Cooldown'])) { - return 0; - } - cooldowns = QR.cooldown.data[post.board.ID] || $.dict(); - for (start in cooldowns) { - cooldown = cooldowns[start]; - if ((cooldown.delay == null) && cooldown.threadID === post.thread.ID && cooldown.postID === post.ID) { - seconds = QR.cooldown.delays.deletion - Math.floor((Date.now() - start) / $.SECOND); - return Math.max(seconds, 0); - } - } - return 0; - }, - categorize: function(post) { - if (post.thread === 'new') { - return { - type: 'thread' - }; - } else { - return { - type: !!post.file ? 'image' : 'reply', - threadID: +post.thread - }; - } - }, - mergeChange: function(data, scope, id, value) { - if (value) { - return (data[scope] || (data[scope] = $.dict()))[id] = value; - } else if (scope in data) { - delete data[scope][id]; - if (Object.keys(data[scope]).length === 0) { - return delete data[scope]; - } - } - }, - set: function(scope, id, value) { - var base; - QR.cooldown.mergeChange(QR.cooldown.data, scope, id, value); - return ((base = QR.cooldown.changes)[scope] || (base[scope] = $.dict()))[id] = value; - }, - save: function() { - var changes; - changes = QR.cooldown.changes; - if (!Object.keys(changes).length) { - return; - } - return $.get('cooldowns', $.dict(), function(arg) { - var cooldowns, id, ref, scope, value; - cooldowns = arg.cooldowns; - for (scope in QR.cooldown.changes) { - ref = QR.cooldown.changes[scope]; - for (id in ref) { - value = ref[id]; - QR.cooldown.mergeChange(cooldowns, scope, id, value); - } - QR.cooldown.data = cooldowns; - } - return $.set('cooldowns', cooldowns, function() { - return QR.cooldown.changes = $.dict(); - }); - }); - }, - clear: function() { - QR.cooldown.data = $.dict(); - QR.cooldown.changes = $.dict(); - QR.cooldown.auto = false; - QR.cooldown.update(); - return $.queueTask($["delete"], 'cooldowns'); - }, - update: function() { - var base, cooldown, cooldowns, elapsed, i, len, maxDelay, nCooldowns, now, ref, ref1, save, scope, seconds, start, suffix, threadID, type, update; - if (!QR.cooldown.isCounting) { - return; - } - save = false; - nCooldowns = 0; - now = Date.now(); - ref = QR.cooldown.categorize(QR.posts[0]), type = ref.type, threadID = ref.threadID; - seconds = 0; - if (Conf['Cooldown']) { - ref1 = [g.BOARD.ID, 'global']; - for (i = 0, len = ref1.length; i < len; i++) { - scope = ref1[i]; - cooldowns = ((base = QR.cooldown.data)[scope] || (base[scope] = $.dict())); - for (start in cooldowns) { - cooldown = cooldowns[start]; - start = +start; - elapsed = Math.floor((now - start) / $.SECOND); - if (elapsed < 0) { - QR.cooldown.set(scope, start, null); - save = true; - continue; - } - if (cooldown.delay != null) { - if (cooldown.delay <= elapsed) { - QR.cooldown.set(scope, start, null); - save = true; - } else if ((cooldown.type === type && cooldown.threadID === threadID) || cooldown.type === 'mute') { - seconds = Math.max(seconds, cooldown.delay - elapsed); - } - continue; - } - maxDelay = cooldown.threadID !== cooldown.postID ? QR.cooldown.maxDelay : QR.cooldown.delays[scope === 'global' ? 'thread_global' : 'thread']; - if (QR.cooldown.customCooldown) { - maxDelay = Math.max(maxDelay, parseInt(Conf['customCooldown'], 10)); - } - if (maxDelay <= elapsed) { - QR.cooldown.set(scope, start, null); - save = true; - continue; - } - if ((type === 'thread') === (cooldown.threadID === cooldown.postID) && cooldown.boardID !== g.BOARD.ID) { - suffix = scope === 'global' ? '_global' : ''; - seconds = Math.max(seconds, QR.cooldown.delays[type + suffix] - elapsed); - if (QR.cooldown.customCooldown) { - seconds = Math.max(seconds, parseInt(Conf['customCooldown'], 10) - elapsed); - } - } - } - nCooldowns += Object.keys(cooldowns).length; - } - } - if (save) { - QR.cooldown.save; - } - if (nCooldowns) { - clearTimeout(QR.cooldown.timeout); - QR.cooldown.timeout = setTimeout(QR.cooldown.count, $.SECOND); - } else { - delete QR.cooldown.isCounting; - } - update = seconds !== QR.cooldown.seconds; - QR.cooldown.seconds = seconds; - if (update) { - return QR.status(); - } - }, - count: function() { - QR.cooldown.update(); - if (QR.cooldown.seconds === 0 && QR.cooldown.auto && !QR.req) { - return QR.submit(); - } - } - }; - -}).call(this); - -(function() { - QR.oekaki = { - menu: { - init: function() { - var a, ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Edit Link'] && Conf['Quick Reply'])) { - return; - } - a = $.el('a', { - className: 'edit-link', - href: 'javascript:;', - textContent: 'Edit image' - }); - $.on(a, 'click', this.editFile); - return Menu.menu.addEntry({ - el: a, - order: 90, - open: function(post) { - var file; - QR.oekaki.menu.post = post; - file = post.file; - return QR.postingIsEnabled && !!file && (file.isImage || file.isVideo); - } - }); - }, - editFile: function() { - var currentTime, isVideo, post, ref; - post = QR.oekaki.menu.post; - QR.quote.call(post.nodes.post); - isVideo = post.file.isVideo; - currentTime = ((ref = post.file.fullImage) != null ? ref.currentTime : void 0) || 0; - return CrossOrigin.file(post.file.url, function(blob) { - var video; - if (!blob) { - return QR.error("Can't load file."); - } else if (isVideo) { - video = $.el('video'); - $.on(video, 'loadedmetadata', function() { - $.on(video, 'seeked', function() { - var canvas; - canvas = $.el('canvas', { - width: video.videoWidth, - height: video.videoHeight - }); - canvas.getContext('2d').drawImage(video, 0, 0); - return canvas.toBlob(function(snapshot) { - snapshot.name = post.file.name.replace(/\.\w+$/, '') + '.png'; - QR.handleFiles([snapshot]); - return QR.oekaki.edit(); - }); - }); - return video.currentTime = currentTime; - }); - $.on(video, 'error', function() { - return QR.openError(); - }); - return video.src = URL.createObjectURL(blob); - } else { - blob.name = post.file.name; - QR.handleFiles([blob]); - return QR.oekaki.edit(); - } - }); - } - }, - setup: function() { - return $.global(function() { - var FCX; - FCX = window.FCX; - FCX.oekakiCB = function() { - return window.Tegaki.flatten().toBlob(function(file) { - var source; - source = "oekaki-" + (Date.now()); - FCX.oekakiLatest = source; - return document.dispatchEvent(new CustomEvent('QRSetFile', { - bubbles: true, - detail: { - file: file, - name: FCX.oekakiName, - source: source - } - })); - }); - }; - if (window.Tegaki) { - return document.querySelector('#qr .oekaki').hidden = false; - } - }); - }, - load: function(cb) { - var n, onload, script, style; - if ($('script[src^="//s.4cdn.org/js/tegaki"]', d.head)) { - return cb(); - } else { - style = $.el('link', { - rel: 'stylesheet', - href: "//s.4cdn.org/css/tegaki." + (Date.now()) + ".css" - }); - script = $.el('script', { - src: "//s.4cdn.org/js/tegaki.min." + (Date.now()) + ".js" - }); - n = 0; - onload = function() { - if (++n === 2) { - return cb(); - } - }; - $.on(style, 'load', onload); - $.on(script, 'load', onload); - return $.add(d.head, [style, script]); - } - }, - draw: function() { - return $.global(function() { - var FCX, Tegaki; - Tegaki = window.Tegaki, FCX = window.FCX; - if (Tegaki.bg) { - Tegaki.destroy(); - } - FCX.oekakiName = 'tegaki.png'; - return Tegaki.open({ - onDone: FCX.oekakiCB, - onCancel: function() { - return Tegaki.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: function() { - if (QR.selected.file) { - return QR.oekaki.edit(); - } else { - return QR.oekaki.toggle(); - } - }, - edit: function() { - return QR.oekaki.load(function() { - return $.global(function() { - var FCX, Tegaki, cb, error, name, source; - Tegaki = window.Tegaki, FCX = window.FCX; - name = document.getElementById('qr-filename').value.replace(/\.\w+$/, '') + '.png'; - source = document.getElementById('file-n-submit').dataset.source; - error = function(content) { - return document.dispatchEvent(new CustomEvent('CreateNotification', { - bubbles: true, - detail: { - type: 'warning', - content: content, - lifetime: 20 - } - })); - }; - cb = function(e) { - var canvas, selected; - if (e) { - this.removeEventListener('QRMetadata', cb, false); - } - selected = document.getElementById('selected'); - if (!(selected != null ? selected.dataset.type : void 0)) { - return error('No file to edit.'); - } - if (!/^(image|video)\//.test(selected.dataset.type)) { - return error('Not an image.'); - } - if (!selected.dataset.height) { - return error('Metadata not available.'); - } - if (selected.dataset.height === 'loading') { - selected.addEventListener('QRMetadata', cb, false); - return; - } - if (Tegaki.bg) { - Tegaki.destroy(); - } - FCX.oekakiName = name; - Tegaki.open({ - onDone: FCX.oekakiCB, - onCancel: function() { - return Tegaki.bgColor = '#ffffff'; - }, - width: +selected.dataset.width, - height: +selected.dataset.height, - bgColor: 'transparent' - }); - canvas = document.createElement('canvas'); - canvas.width = canvas.naturalWidth = +selected.dataset.width; - canvas.height = canvas.naturalHeight = +selected.dataset.height; - canvas.hidden = true; - document.body.appendChild(canvas); - canvas.addEventListener('QRImageDrawn', function() { - this.remove(); - return Tegaki.onOpenImageLoaded.call(this); - }, false); - return canvas.dispatchEvent(new CustomEvent('QRDrawFile', { - bubbles: true - })); - }; - if (Tegaki.bg && Tegaki.onDoneCb === FCX.oekakiCB && source === FCX.oekakiLatest) { - FCX.oekakiName = name; - return Tegaki.resume(); - } else { - return cb(); - } - }); - }); - }, - toggle: function() { - return QR.oekaki.load(function() { - return QR.nodes.oekaki.hidden = !QR.nodes.oekaki.hidden; - }); - } - }; - -}).call(this); - -(function() { - var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - QR.persona = { - always: {}, - types: { - name: [], - email: [], - sub: [] - }, - init: function() { - var i, item, len, ref; - if (!(Conf['Quick Reply'] || (Conf['Menu'] && Conf['Delete Link']))) { - return; - } - ref = Conf['QR.personas'].split('\n'); - for (i = 0, len = ref.length; i < len; i++) { - item = ref[i]; - QR.persona.parseItem(item.trim()); - } - }, - parseItem: function(item) { - var boards, match, ref, ref1, ref2, type, val; - if (item[0] === '#') { - return; - } - if (!(match = item.match(/(name|options|email|subject|password):"(.*)"/i))) { - return; - } - ref = match, match = ref[0], type = ref[1], val = ref[2]; - item = item.replace(match, ''); - boards = ((ref1 = item.match(/boards:([^;]+)/i)) != null ? ref1[1].toLowerCase() : void 0) || 'global'; - if (boards !== 'global' && (ref2 = g.BOARD.ID, indexOf.call(boards.split(','), ref2) < 0)) { - return; - } - if (type === 'password') { - QR.persona.pwd = val; - return; - } - if (type === 'options') { - type = 'email'; - } - if (type === 'subject') { - type = 'sub'; - } - if (/always/i.test(item)) { - QR.persona.always[type] = val; - } - if (indexOf.call(QR.persona.types[type], val) < 0) { - return QR.persona.types[type].push(val); - } - }, - load: function() { - var arr, i, len, list, ref, type, val; - ref = QR.persona.types; - for (type in ref) { - arr = ref[type]; - list = $("#list-" + type, QR.nodes.el); - for (i = 0, len = arr.length; i < len; i++) { - val = arr[i]; - if (val) { - $.add(list, $.el('option', { - textContent: val - })); - } - } - } - }, - getPassword: function() { - var m; - if (QR.persona.pwd != null) { - return QR.persona.pwd; - } else if ((m = d.cookie.match(/4chan_pass=([^;]+)/))) { - return decodeURIComponent(m[1]); - } else { - return ''; - } - }, - get: function(cb) { - return $.get('QR.persona', {}, function(arg) { - var persona; - persona = arg['QR.persona']; - return cb(persona); - }); - }, - set: function(post) { - return $.get('QR.persona', {}, function(arg) { - var persona; - persona = arg['QR.persona']; - persona = { - name: post.name, - flag: post.flag - }; - return $.set('QR.persona', persona); - }); - } - }; - -}).call(this); - -(function() { - var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - QR.post = (function() { - function _Class(select) { - this.select = bind(this.select, this); - var el, event, i, j, label, len, len1, prev, ref, ref1; - el = $.el('a', { - className: 'qr-preview', - draggable: true, - href: 'javascript:;' - }); - $.extend(el, {innerHTML: ""}); - this.nodes = { - el: el, - rm: el.firstChild, - spoiler: $('.qr-preview-spoiler input', el), - span: el.lastChild - }; - $.on(el, 'click', this.select); - $.on(this.nodes.rm, 'click', (function(_this) { - return function(e) { - e.stopPropagation(); - return _this.rm(); - }; - })(this)); - $.on(this.nodes.spoiler, 'change', (function(_this) { - return function(e) { - _this.spoiler = e.target.checked; - if (_this === QR.selected) { - QR.nodes.spoiler.checked = _this.spoiler; - } - return _this.preventAutoPost(); - }; - })(this)); - ref = $$('label', el); - for (i = 0, len = ref.length; i < len; i++) { - label = ref[i]; - $.on(label, 'click', function(e) { - return e.stopPropagation(); - }); - } - $.add(QR.nodes.dumpList, el); - ref1 = ['dragStart', 'dragEnter', 'dragLeave', 'dragOver', 'dragEnd', 'drop']; - for (j = 0, len1 = ref1.length; j < len1; j++) { - event = ref1[j]; - $.on(el, event.toLowerCase(), this[event]); - } - this.thread = g.VIEW === 'thread' ? g.THREADID : 'new'; - prev = QR.posts[QR.posts.length - 1]; - QR.posts.push(this); - this.nodes.spoiler.checked = this.spoiler = prev && Conf['Remember Spoiler'] ? prev.spoiler : false; - QR.persona.get((function(_this) { - return function(persona) { - _this.name = 'name' in QR.persona.always ? QR.persona.always.name : prev ? prev.name : persona.name; - _this.email = 'email' in QR.persona.always ? QR.persona.always.email : ''; - _this.sub = 'sub' in QR.persona.always ? QR.persona.always.sub : ''; - if (QR.nodes.flag) { - _this.flag = prev ? prev.flag : persona.flag && persona.flag in g.BOARD.config.board_flags ? persona.flag : void 0; - } - if (QR.selected === _this) { - return _this.load(); - } - }; - })(this)); - if (select) { - this.select(); - } - this.unlock(); - QR.captcha.moreNeeded(); - } - - _Class.prototype.rm = function() { - var base, index; - this["delete"](); - index = QR.posts.indexOf(this); - if (QR.posts.length === 1) { - new QR.post(true); - $.rmClass(QR.nodes.el, 'dump'); - } else if (this === QR.selected) { - (QR.posts[index - 1] || QR.posts[index + 1]).select(); - } - QR.posts.splice(index, 1); - QR.status(); - return typeof (base = QR.captcha).updateThread === "function" ? base.updateThread() : void 0; - }; - - _Class.prototype["delete"] = function() { - $.rm(this.nodes.el); - URL.revokeObjectURL(this.URL); - return this.dismissErrors(); - }; - - _Class.prototype.lock = function(lock) { - var i, len, name, node, ref; - if (lock == null) { - lock = true; - } - this.isLocked = lock; - if (this !== QR.selected) { - return; - } - ref = ['thread', 'name', 'email', 'sub', 'com', 'fileButton', 'filename', 'spoiler', 'flag']; - for (i = 0, len = ref.length; i < len; i++) { - name = ref[i]; - if (node = QR.nodes[name]) { - node.disabled = lock; - } - } - this.nodes.rm.style.visibility = lock ? 'hidden' : ''; - this.nodes.spoiler.disabled = lock; - return this.nodes.el.draggable = !lock; - }; - - _Class.prototype.unlock = function() { - return this.lock(false); - }; - - _Class.prototype.select = function() { - var rectEl, rectList; - if (QR.selected) { - QR.selected.nodes.el.removeAttribute('id'); - QR.selected.forceSave(); - } - QR.selected = this; - this.lock(this.isLocked); - this.nodes.el.id = 'selected'; - rectEl = this.nodes.el.getBoundingClientRect(); - rectList = this.nodes.el.parentNode.getBoundingClientRect(); - this.nodes.el.parentNode.scrollLeft += rectEl.left + rectEl.width / 2 - rectList.left - rectList.width / 2; - return this.load(); - }; - - _Class.prototype.load = function() { - var i, len, name, node, ref; - ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag']; - for (i = 0, len = ref.length; i < len; i++) { - name = ref[i]; - if (!(node = QR.nodes[name])) { - continue; - } - node.value = this[name] || node.dataset["default"] || ''; - } - (this.thread !== 'new' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread'); - this.showFileData(); - return QR.characterCount(); - }; - - _Class.prototype.save = function(input, forced) { - var base, name, prev; - if (input.type === 'checkbox') { - this.spoiler = input.checked; - return; - } - name = input.dataset.name; - if (name !== 'thread' && name !== 'name' && name !== 'email' && name !== 'sub' && name !== 'com' && name !== 'filename' && name !== 'flag') { - return; - } - prev = this[name] || input.dataset["default"] || null; - this[name] = input.value || input.dataset["default"] || null; - switch (name) { - case 'thread': - (this.thread !== 'new' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread'); - QR.status(); - if (typeof (base = QR.captcha).updateThread === "function") { - base.updateThread(); - } - break; - case 'com': - this.updateComment(); - break; - case 'filename': - if (!this.file) { - return; - } - this.saveFilename(); - this.updateFilename(); - break; - case 'name': - case 'flag': - if (this[name] !== prev) { - QR.persona.set(this); - } - } - if (!forced) { - return this.preventAutoPost(); - } - }; - - _Class.prototype.forceSave = function() { - var i, len, name, node, ref; - if (this !== QR.selected) { - return; - } - ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler', 'flag']; - for (i = 0, len = ref.length; i < len; i++) { - name = ref[i]; - if (!(node = QR.nodes[name])) { - continue; - } - this.save(node, true); - } - }; - - _Class.prototype.preventAutoPost = function() { - if (QR.cooldown.auto && this === QR.posts[0]) { - QR.cooldown.update(); - if (QR.cooldown.seconds <= 5) { - return QR.cooldown.auto = false; - } - } - }; - - _Class.prototype.setComment = function(com) { - this.com = com || null; - if (this === QR.selected) { - QR.nodes.com.value = this.com; - } - return this.updateComment(); - }; - - _Class.prototype.updateComment = function() { - if (this === QR.selected) { - QR.characterCount(); - } - this.nodes.span.textContent = this.com; - QR.captcha.moreNeeded(); - if (QR.captcha === Captcha.v2) { - return Captcha.cache.prerequest(); - } - }; - - _Class.prototype.isOnlyQuotes = function() { - return (this.com || '').trim() === (this.quotedText || '').trim(); - }; - - _Class.rmErrored = function(e) { - var error, errors, i, j, len, post, ref; - e.stopPropagation(); - ref = QR.posts; - for (i = ref.length - 1; i >= 0; i += -1) { - post = ref[i]; - if (errors = post.errors) { - for (j = 0, len = errors.length; j < len; j++) { - error = errors[j]; - if (!(doc.contains(error))) { - continue; - } - post.rm(); - break; - } - } - } - }; - - _Class.prototype.error = function(className, message, link) { - var div, ref, rm, rmAll; - div = $.el('div', { - className: className - }); - $.extend(div, {innerHTML: E(message) + ((link) ? " [More info]" : "") + "
        [delete post] [delete all]"}); - (this.errors || (this.errors = [])).push(div); - ref = $$('a', div), rm = ref[0], rmAll = ref[1]; - $.on(div, 'click', (function(_this) { - return function() { - if (indexOf.call(QR.posts, _this) >= 0) { - return _this.select(); - } - }; - })(this)); - $.on(rm, 'click', (function(_this) { - return function(e) { - e.stopPropagation(); - if (indexOf.call(QR.posts, _this) >= 0) { - return _this.rm(); - } - }; - })(this)); - $.on(rmAll, 'click', QR.post.rmErrored); - return QR.error(div, true); - }; - - _Class.prototype.fileError = function(message, link) { - return this.error('file-error', this.filename + ": " + message, link); - }; - - _Class.prototype.dismissErrors = function(test) { - var error, i, len, ref; - if (test == null) { - test = function() { - return true; - }; - } - if (this.errors) { - ref = this.errors; - for (i = 0, len = ref.length; i < len; i++) { - error = ref[i]; - if (doc.contains(error) && test(error)) { - error.parentNode.previousElementSibling.click(); - } - } - } - }; - - _Class.prototype.setFile = function(file1) { - var ext, ref; - this.file = file1; - if (Conf['Randomize Filename'] && g.BOARD.ID !== 'f') { - this.filename = "" + (Date.now() * 1000 - Math.floor(Math.random() * 365 * $.DAY * 1000)); - if (ext = this.file.name.match(QR.validExtension)) { - this.filename += ext[0]; - } - } else { - this.filename = this.file.name; - } - this.filesize = $.bytesToString(this.file.size); - this.checkSize(); - $.addClass(this.nodes.el, 'has-file'); - QR.captcha.moreNeeded(); - URL.revokeObjectURL(this.URL); - this.saveFilename(); - if (this === QR.selected) { - this.showFileData(); - } else { - this.updateFilename(); - } - this.rmMetadata(); - this.nodes.el.dataset.type = this.file.type; - this.nodes.el.style.backgroundImage = ''; - if (ref = this.file.type, indexOf.call(QR.mimeTypes, ref) < 0) { - this.fileError('Unsupported file type.'); - } else if (/^(image|video)\//.test(this.file.type)) { - this.readFile(); - } - return this.preventAutoPost(); - }; - - _Class.prototype.checkSize = function() { - var max; - max = QR.max_size; - if (/^video\//.test(this.file.type)) { - max = Math.min(max, QR.max_size_video); - } - if (this.file.size > max) { - return this.fileError("File too large (file: " + this.filesize + ", max: " + ($.bytesToString(max)) + ")."); - } - }; - - _Class.prototype.readFile = function() { - var el, event, isVideo, onerror, onload; - isVideo = /^video\//.test(this.file.type); - el = $.el(isVideo ? 'video' : 'img'); - if (isVideo && !el.canPlayType(this.file.type)) { - return; - } - event = isVideo ? 'loadeddata' : 'load'; - onload = (function(_this) { - return function() { - $.off(el, event, onload); - $.off(el, 'error', onerror); - _this.checkDimensions(el); - _this.setThumbnail(el); - return $.event('QRMetadata', null, _this.nodes.el); - }; - })(this); - onerror = (function(_this) { - return function() { - $.off(el, event, onload); - $.off(el, 'error', onerror); - _this.fileError("Corrupt " + (isVideo ? 'video' : 'image') + " or error reading metadata.", 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions#error-reading-metadata'); - URL.revokeObjectURL(el.src); - _this.nodes.el.removeAttribute('data-height'); - return $.event('QRMetadata', null, _this.nodes.el); - }; - })(this); - this.nodes.el.dataset.height = 'loading'; - $.on(el, event, onload); - $.on(el, 'error', onerror); - return el.src = URL.createObjectURL(this.file); - }; - - _Class.prototype.checkDimensions = function(el) { - var duration, height, max_height, max_width, videoHeight, videoWidth, width; - if (el.tagName === 'IMG') { - height = el.height, width = el.width; - this.nodes.el.dataset.height = height; - this.nodes.el.dataset.width = width; - if (height > QR.max_height || width > QR.max_width) { - this.fileError("Image too large (image: " + height + "x" + width + "px, max: " + QR.max_height + "x" + QR.max_width + "px)"); - } - if (height < QR.min_height || width < QR.min_width) { - return this.fileError("Image too small (image: " + height + "x" + width + "px, min: " + QR.min_height + "x" + QR.min_width + "px)"); - } - } else { - videoHeight = el.videoHeight, videoWidth = el.videoWidth, duration = el.duration; - this.nodes.el.dataset.height = videoHeight; - this.nodes.el.dataset.width = videoWidth; - this.nodes.el.dataset.duration = duration; - max_height = Math.min(QR.max_height, QR.max_height_video); - max_width = Math.min(QR.max_width, QR.max_width_video); - if (videoHeight > max_height || videoWidth > max_width) { - this.fileError("Video too large (video: " + videoHeight + "x" + videoWidth + "px, max: " + max_height + "x" + max_width + "px)"); - } - if (videoHeight < QR.min_height || videoWidth < QR.min_width) { - this.fileError("Video too small (video: " + videoHeight + "x" + videoWidth + "px, min: " + QR.min_height + "x" + QR.min_width + "px)"); - } - if (!isFinite(duration)) { - this.fileError('Video lacks duration metadata (try remuxing)'); - } else if (duration > QR.max_duration_video) { - this.fileError("Video too long (video: " + duration + "s, max: " + QR.max_duration_video + "s)"); - } - if (BoardConfig.noAudio(g.BOARD.ID) && $.hasAudio(el)) { - return this.fileError('Audio not allowed'); - } - } - }; - - _Class.prototype.setThumbnail = function(el) { - var cv, height, isVideo, s, width; - isVideo = el.tagName === 'VIDEO'; - s = 90 * 2 * window.devicePixelRatio; - if (this.file.type === 'image/gif') { - s *= 3; - } - if (isVideo) { - height = el.videoHeight; - width = el.videoWidth; - } else { - height = el.height, width = el.width; - if (height < s || width < s) { - this.URL = el.src; - this.nodes.el.style.backgroundImage = "url(" + this.URL + ")"; - return; - } - } - if (height <= width) { - width = s / height * width; - height = s; - } else { - height = s / width * height; - width = s; - } - cv = $.el('canvas'); - cv.height = height; - cv.width = width; - cv.getContext('2d').drawImage(el, 0, 0, width, height); - URL.revokeObjectURL(el.src); - return cv.toBlob((function(_this) { - return function(blob) { - _this.URL = URL.createObjectURL(blob); - return _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")"; - }; - })(this)); - }; - - _Class.prototype.rmFile = function() { - if (this.isLocked) { - return; - } - delete this.file; - delete this.filename; - delete this.filesize; - this.nodes.el.removeAttribute('title'); - QR.nodes.filename.removeAttribute('title'); - this.rmMetadata(); - this.nodes.el.style.backgroundImage = ''; - $.rmClass(this.nodes.el, 'has-file'); - this.showFileData(); - URL.revokeObjectURL(this.URL); - this.dismissErrors(function(error) { - return $.hasClass(error, 'file-error'); - }); - return this.preventAutoPost(); - }; - - _Class.prototype.rmMetadata = function() { - var attr, i, len, ref; - ref = ['type', 'height', 'width', 'duration']; - for (i = 0, len = ref.length; i < len; i++) { - attr = ref[i]; - this.nodes.el.removeAttribute("data-" + attr); - } - }; - - _Class.prototype.saveFilename = function() { - this.file.newName = (this.filename || '').replace(/[\/\\]/g, '-'); - if (!QR.validExtension.test(this.filename)) { - return this.file.newName += "." + ($.getOwn(QR.extensionFromType, this.file.type) || 'jpg'); - } - }; - - _Class.prototype.updateFilename = function() { - var long; - long = this.filename + " (" + this.filesize + ")"; - this.nodes.el.title = long; - if (this !== QR.selected) { - return; - } - return QR.nodes.filename.title = long; - }; - - _Class.prototype.showFileData = function() { - var ref; - if (this.file) { - this.updateFilename(); - QR.nodes.filename.value = this.filename; - $.addClass(QR.nodes.oekaki, 'has-file'); - $.addClass(QR.nodes.fileSubmit, 'has-file'); - } else { - $.rmClass(QR.nodes.oekaki, 'has-file'); - $.rmClass(QR.nodes.fileSubmit, 'has-file'); - } - if (((ref = this.file) != null ? ref.source : void 0) != null) { - QR.nodes.fileSubmit.dataset.source = this.file.source; - } else { - QR.nodes.fileSubmit.removeAttribute('data-source'); - } - return QR.nodes.spoiler.checked = this.spoiler; - }; - - _Class.prototype.pasteText = function(file) { - var reader; - this.pasting = true; - this.preventAutoPost(); - reader = new FileReader(); - reader.onload = (function(_this) { - return function(e) { - var result; - result = e.target.result; - _this.setComment((_this.com ? _this.com + "\n" + result : result)); - return delete _this.pasting; - }; - })(this); - return reader.readAsText(file); - }; - - _Class.prototype.dragStart = function(e) { - var left, ref, top; - ref = this.getBoundingClientRect(), left = ref.left, top = ref.top; - e.dataTransfer.setDragImage(this, e.clientX - left, e.clientY - top); - return $.addClass(this, 'drag'); - }; - - _Class.prototype.dragEnd = function() { - return $.rmClass(this, 'drag'); - }; - - _Class.prototype.dragEnter = function() { - return $.addClass(this, 'over'); - }; - - _Class.prototype.dragLeave = function() { - return $.rmClass(this, 'over'); - }; - - _Class.prototype.dragOver = function(e) { - e.preventDefault(); - return e.dataTransfer.dropEffect = 'move'; - }; - - _Class.prototype.drop = function() { - var base, el, index, newIndex, oldIndex, post; - $.rmClass(this, 'over'); - if (!this.draggable) { - return; - } - el = $('.drag', this.parentNode); - index = function(el) { - return slice.call(el.parentNode.children).indexOf(el); - }; - oldIndex = index(el); - newIndex = index(this); - if (QR.posts[oldIndex].isLocked || QR.posts[newIndex].isLocked) { - return; - } - (oldIndex < newIndex ? $.after : $.before)(this, el); - post = QR.posts.splice(oldIndex, 1)[0]; - QR.posts.splice(newIndex, 0, post); - QR.status(); - return typeof (base = QR.captcha).updateThread === "function" ? base.updateThread() : void 0; - }; - - return _Class; - - })(); - -}).call(this); - -QuoteBacklink = (function() { - var QuoteBacklink; - - QuoteBacklink = { - containers: $.dict(), - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Quote Backlinks']) { - return; - } - if ((this.bottomBacklinks = Conf['Bottom Backlinks'])) { - $.addClass(doc, 'bottom-backlinks'); - } - Callbacks.Post.push({ - name: 'Quote Backlinking Part 1', - cb: this.firstNode - }); - return Callbacks.Post.push({ - name: 'Quote Backlinking Part 2', - cb: this.secondNode - }); - }, - firstNode: function() { - var a, clone, container, containers, hash, i, j, k, len, len1, len2, link, markYours, nodes, post, quote, ref, ref1; - if (this.isClone || !this.quotes.length || this.isRebuilt) { - return; - } - markYours = Conf['Mark Quotes of You'] && QuoteYou.isYou(this); - a = $.el('a', { - href: g.SITE.Build.postURL(this.board.ID, this.thread.ID, this.ID), - className: this.isHidden ? 'filtered backlink' : 'backlink', - textContent: Conf['backlink'].replace(/%(?:id|%)/g, (function(_this) { - return function(x) { - return { - '%id': _this.ID, - '%%': '%' - }[x]; - }; - })(this)) - }); - if (markYours) { - $.add(a, QuoteYou.mark.cloneNode(true)); - } - ref = this.quotes; - for (i = 0, len = ref.length; i < len; i++) { - quote = ref[i]; - containers = [QuoteBacklink.getContainer(quote)]; - if ((post = g.posts.get(quote)) && post.nodes.backlinkContainer) { - ref1 = post.clones; - for (j = 0, len1 = ref1.length; j < len1; j++) { - clone = ref1[j]; - containers.push(clone.nodes.backlinkContainer); - } - } - for (k = 0, len2 = containers.length; k < len2; k++) { - container = containers[k]; - link = a.cloneNode(true); - nodes = container.firstChild ? [$.tn(' '), link] : [link]; - if (Conf['Quote Previewing']) { - $.on(link, 'mouseover', QuotePreview.mouseover); - } - if (Conf['Quote Inlining']) { - $.on(link, 'click', QuoteInline.toggle); - if (Conf['Quote Hash Navigation']) { - hash = QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')); - nodes.push(hash); - } - } - $.add(container, nodes); - } - } - }, - secondNode: function() { - var container; - if (this.isClone && (this.origin.isReply || Conf['OP Backlinks'])) { - this.nodes.backlinkContainer = $('.container', this.nodes.post); - return; - } - if (!(this.isReply || Conf['OP Backlinks'])) { - return; - } - container = QuoteBacklink.getContainer(this.fullID); - this.nodes.backlinkContainer = container; - if (QuoteBacklink.bottomBacklinks) { - return $.add(this.nodes.post, container); - } else { - return $.add(this.nodes.info, container); - } - }, - getContainer: function(id) { - var base; - return (base = this.containers)[id] || (base[id] = $.el('span', { - className: 'container' - })); - } - }; - - return QuoteBacklink; - -}).call(this); - -QuoteCT = (function() { - var QuoteCT; - - QuoteCT = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Mark Cross-thread Quotes']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - this.mark = $.el('span', { - textContent: '\u00A0(Cross-thread)', - className: 'qmark-ct' - }); - return Callbacks.Post.push({ - name: 'Mark Cross-thread Quotes', - cb: this.node - }); - }, - node: function() { - var board, boardID, i, len, quotelink, ref, ref1, ref2, thread, threadID; - if (this.isClone && this.thread === this.context.thread) { - return; - } - ref = this.context, board = ref.board, thread = ref.thread; - ref1 = this.nodes.quotelinks; - for (i = 0, len = ref1.length; i < len; i++) { - quotelink = ref1[i]; - ref2 = Get.postDataFromLink(quotelink), boardID = ref2.boardID, threadID = ref2.threadID; - if (!threadID) { - continue; - } - if (this.isClone) { - $.rm($('.qmark-ct', quotelink)); - } - if (boardID === board.ID && threadID !== thread.ID) { - $.add(quotelink, QuoteCT.mark.cloneNode(true)); - } - } - } - }; - - return QuoteCT; - -}).call(this); - -QuoteInline = (function() { - var QuoteInline, - slice = [].slice; - - QuoteInline = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Quote Inlining']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Callbacks.Post.push({ - name: 'Quote Inlining', - cb: this.node - }); - }, - node: function() { - var i, isClone, len, link, process, ref; - process = QuoteInline.process; - isClone = this.isClone; - ref = this.nodes.quotelinks.concat(slice.call(this.nodes.backlinks), this.nodes.archivelinks); - for (i = 0, len = ref.length; i < len; i++) { - link = ref[i]; - process(link, isClone); - } - }, - process: function(link, clone) { - if (Conf['Quote Hash Navigation']) { - if (!clone) { - $.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered'))); - } - } - return $.on(link, 'click', QuoteInline.toggle); - }, - qiQuote: function(link, hidden) { - var name; - name = "hashlink"; - if (hidden) { - name += " filtered"; - } - return $.el('a', { - className: name, - textContent: '#', - href: link.href - }); - }, - toggle: function(e) { - var boardID, context, postID, quoter, ref, ref1, threadID; - if ($.modifiedClick(e)) { - return; - } - ref = Get.postDataFromLink(this), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - if (Conf['Inline Cross-thread Quotes Only'] && g.VIEW === 'thread' && ((ref1 = g.posts.get(boardID + "." + postID)) != null ? ref1.nodes.root.offsetParent : void 0)) { - return; - } - if ($.hasClass(doc, 'catalog-mode')) { - return; - } - e.preventDefault(); - quoter = Get.postFromNode(this); - context = quoter.context; - if ($.hasClass(this, 'inlined')) { - QuoteInline.rm(this, boardID, threadID, postID, context); - } else { - if ($.x("ancestor::div[@data-full-i-d='" + boardID + "." + postID + "']", this)) { - return; - } - QuoteInline.add(this, boardID, threadID, postID, context, quoter); - } - return this.classList.toggle('inlined'); - }, - findRoot: function(quotelink, isBacklink) { - if (isBacklink) { - return $.x('ancestor::*[parent::*[contains(@class,"post")]][1]', quotelink); - } else { - return $.x('ancestor-or-self::*[parent::blockquote][1]', quotelink); - } - }, - add: function(quotelink, boardID, threadID, postID, context, quoter) { - var inline, isBacklink, post, qroot, root; - isBacklink = $.hasClass(quotelink, 'backlink'); - inline = $.el('div', { - className: 'inline' - }); - inline.dataset.fullID = boardID + "." + postID; - root = QuoteInline.findRoot(quotelink, isBacklink); - $.after(root, inline); - qroot = $.x('ancestor::*[contains(@class,"postContainer")][1]', root); - $.addClass(qroot, 'hasInline'); - new Fetcher(boardID, threadID, postID, inline, quoter); - if (!((post = g.posts.get(boardID + "." + postID)) && context.thread === post.thread)) { - return; - } - if (isBacklink && Conf['Forward Hiding']) { - $.addClass(post.nodes.root, 'forwarded'); - post.forwarded++ || (post.forwarded = 1); - } - if (!Unread.posts) { - return; - } - return Unread.readSinglePost(post); - }, - rm: function(quotelink, boardID, threadID, postID, context) { - var el, inlined, isBacklink, parentNode, post, qroot, ref, root; - isBacklink = $.hasClass(quotelink, 'backlink'); - root = QuoteInline.findRoot(quotelink, isBacklink); - root = $.x("following-sibling::div[@data-full-i-d='" + boardID + "." + postID + "'][1]", root); - qroot = $.x('ancestor::*[contains(@class,"postContainer")][1]', root); - parentNode = root.parentNode; - $.rm(root); - $.event('PostsRemoved', null, parentNode); - if (!$('.inline', qroot)) { - $.rmClass(qroot, 'hasInline'); - } - if (!(el = root.firstElementChild)) { - return; - } - post = g.posts.get(boardID + "." + postID); - post.rmClone(el.dataset.clone); - if (Conf['Forward Hiding'] && isBacklink && context.thread === g.threads.get(boardID + "." + threadID) && !--post.forwarded) { - delete post.forwarded; - $.rmClass(post.nodes.root, 'forwarded'); - } - while (inlined = $('.inlined', el)) { - ref = Get.postDataFromLink(inlined), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - QuoteInline.rm(inlined, boardID, threadID, postID, context); - $.rmClass(inlined, 'inlined'); - } - } - }; - - return QuoteInline; - -}).call(this); - -QuoteOP = (function() { - var QuoteOP, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - QuoteOP = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Mark OP Quotes']) { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - this.mark = $.el('span', { - textContent: '\u00A0(OP)', - className: 'qmark-op' - }); - return Callbacks.Post.push({ - name: 'Mark OP Quotes', - cb: this.node - }); - }, - node: function() { - var boardID, fullID, i, postID, quotelink, quotelinks, quotes, ref, ref1; - if (this.isClone && this.thread === this.context.thread) { - return; - } - if (!(quotes = this.quotes).length) { - return; - } - quotelinks = this.nodes.quotelinks; - if (this.isClone && (ref = this.thread.fullID, indexOf.call(quotes, ref) >= 0)) { - i = 0; - while (quotelink = quotelinks[i++]) { - $.rm($('.qmark-op', quotelink)); - } - } - fullID = this.context.thread.fullID; - if (indexOf.call(quotes, fullID) < 0) { - return; - } - i = 0; - while (quotelink = quotelinks[i++]) { - ref1 = Get.postDataFromLink(quotelink), boardID = ref1.boardID, postID = ref1.postID; - if ((boardID + "." + postID) === fullID) { - $.add(quotelink, QuoteOP.mark.cloneNode(true)); - } - } - } - }; - - return QuoteOP; - -}).call(this); - -QuotePreview = (function() { - var QuotePreview, - slice = [].slice; - - QuotePreview = { - init: function() { - var ref; - if (!Conf['Quote Previewing']) { - return; - } - if (g.VIEW === 'archive') { - $.on(d, 'mouseover', function(e) { - if (e.target.nodeName === 'A' && $.hasClass(e.target, 'quotelink')) { - return QuotePreview.mouseover.call(e.target, e); - } - }); - } - if ((ref = g.VIEW) !== 'index' && ref !== 'thread') { - return; - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Callbacks.Post.push({ - name: 'Quote Previewing', - cb: this.node - }); - }, - node: function() { - var i, len, link, ref; - ref = this.nodes.quotelinks.concat(slice.call(this.nodes.backlinks), this.nodes.archivelinks); - for (i = 0, len = ref.length; i < len; i++) { - link = ref[i]; - $.on(link, 'mouseover', QuotePreview.mouseover); - } - }, - mouseover: function(e) { - var boardID, i, len, origin, post, postID, posts, qp, ref, threadID; - if (($.hasClass(this, 'inlined') && !$.hasClass(doc, 'catalog-mode')) || !d.contains(this)) { - return; - } - ref = Get.postDataFromLink(this), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - qp = $.el('div', { - id: 'qp', - className: 'dialog' - }); - $.add(Header.hover, qp); - new Fetcher(boardID, threadID, postID, qp, Get.postFromNode(this)); - UI.hover({ - root: this, - el: qp, - latestEvent: e, - endEvents: 'mouseout click', - cb: QuotePreview.mouseout - }); - if (Conf['Quote Highlighting'] && (origin = g.posts.get(boardID + "." + postID))) { - posts = [origin].concat(origin.clones); - posts.pop(); - for (i = 0, len = posts.length; i < len; i++) { - post = posts[i]; - $.addClass(post.nodes.post, 'qphl'); - } - } - }, - mouseout: function() { - var clone, i, len, post, ref, root; - if (!(root = this.el.firstElementChild)) { - return; - } - $.event('PostsRemoved', null, Header.hover); - clone = Get.postFromRoot(root); - post = clone.origin; - post.rmClone(root.dataset.clone); - if (!Conf['Quote Highlighting']) { - return; - } - ref = [post].concat(post.clones); - for (i = 0, len = ref.length; i < len; i++) { - post = ref[i]; - $.rmClass(post.nodes.post, 'qphl'); - } - } - }; - - return QuotePreview; - -}).call(this); - -QuoteStrikeThrough = (function() { - var QuoteStrikeThrough; - - QuoteStrikeThrough = { - init: function() { - var ref; - if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && (Conf['Reply Hiding Buttons'] || (Conf['Menu'] && Conf['Reply Hiding Link']) || Conf['Filter']))) { - return; - } - return Callbacks.Post.push({ - name: 'Strike-through Quotes', - cb: this.node - }); - }, - node: function() { - var boardID, i, len, postID, quotelink, ref, ref1, ref2; - if (this.isClone) { - return; - } - ref = this.nodes.quotelinks; - for (i = 0, len = ref.length; i < len; i++) { - quotelink = ref[i]; - ref1 = Get.postDataFromLink(quotelink), boardID = ref1.boardID, postID = ref1.postID; - if ((ref2 = g.posts.get(boardID + "." + postID)) != null ? ref2.isHidden : void 0) { - $.addClass(quotelink, 'filtered'); - } - } - } - }; - - return QuoteStrikeThrough; - -}).call(this); - -QuoteThreading = -/* - <3 aeosynth - */ - -(function() { - var QuoteThreading; - - QuoteThreading = { - init: function() { - if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) { - return; - } - this.controls = $.el('label', {innerHTML: " Threading"}); - this.threadNewLink = $.el('span', { - className: 'brackets-wrap threadnewlink', - hidden: true - }); - $.extend(this.threadNewLink, {innerHTML: "Thread New Posts"}); - this.input = $('input', this.controls); - this.input.checked = Conf['Thread Quotes']; - $.on(this.input, 'change', this.setEnabled); - $.on(this.input, 'change', this.rethread); - $.on(this.threadNewLink.firstElementChild, 'click', this.rethread); - $.on(d, '4chanXInitFinished', (function(_this) { - return function() { - return _this.ready = true; - }; - })(this)); - Header.menu.addEntry(this.entry = { - el: this.controls, - order: 99 - }); - Callbacks.Thread.push({ - name: 'Quote Threading', - cb: this.setThread - }); - return Callbacks.Post.push({ - name: 'Quote Threading', - cb: this.node - }); - }, - parent: $.dict(), - children: $.dict(), - inserted: $.dict(), - toggleThreading: function() { - return this.setThreadingState(!Conf['Thread Quotes']); - }, - setThreadingState: function(enabled) { - this.input.checked = enabled; - this.setEnabled.call(this.input); - return this.rethread.call(this.input); - }, - setEnabled: function() { - var other, ref; - if (this.checked) { - $.set('Prune All Threads', false); - other = (ref = ReplyPruning.inputs) != null ? ref.enabled : void 0; - if (other != null ? other.checked : void 0) { - other.checked = false; - $.event('change', null, other); - } - } - return $.cb.checked.call(this); - }, - setThread: function() { - QuoteThreading.thread = this; - return $.asap((function() { - return !Conf['Thread Updater'] || $('.navLinksBot > .updatelink'); - }), function() { - var navLinksBot; - if ((navLinksBot = $('.navLinksBot'))) { - return $.add(navLinksBot, [$.tn(' '), QuoteThreading.threadNewLink]); - } - }); - }, - node: function() { - var ancestor, j, lastParent, len, parent, parents, quote, ref; - if (this.isFetchedQuote || this.isClone || !this.isReply) { - return; - } - parents = new Set(); - lastParent = null; - ref = this.quotes; - for (j = 0, len = ref.length; j < len; j++) { - quote = ref[j]; - if (parent = g.posts.get(quote)) { - if (!parent.isFetchedQuote && parent.isReply && parent.ID < this.ID) { - parents.add(parent.ID); - if (!lastParent || parent.ID > lastParent.ID) { - lastParent = parent; - } - } - } - } - if (!lastParent) { - return; - } - ancestor = lastParent; - while (ancestor = QuoteThreading.parent[ancestor.fullID]) { - parents["delete"](ancestor.ID); - } - if (parents.size === 1) { - return QuoteThreading.parent[this.fullID] = lastParent; - } - }, - descendants: function(post) { - var child, children, j, len, posts; - posts = [post]; - if (children = QuoteThreading.children[post.fullID]) { - for (j = 0, len = children.length; j < len; j++) { - child = children[j]; - posts = posts.concat(QuoteThreading.descendants(child)); - } - } - return posts; - }, - insert: function(post) { - var base, child, children, descendants, i, j, k, l, len, name, next, nodes, order, parent, prev, prev2, threadContainer, x; - if (!(Conf['Thread Quotes'] && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) { - return false; - } - descendants = QuoteThreading.descendants(post); - if (!Unread.posts.has(parent.ID)) { - if ((function() { - var j, len, x; - for (j = 0, len = descendants.length; j < len; j++) { - x = descendants[j]; - if (Unread.posts.has(x.ID)) { - return true; - } - } - })()) { - QuoteThreading.threadNewLink.hidden = false; - return false; - } - } - order = Unread.order; - children = ((base = QuoteThreading.children)[name = parent.fullID] || (base[name] = [])); - threadContainer = parent.nodes.threadContainer || $.el('div', { - className: 'threadContainer' - }); - nodes = [post.nodes.root]; - if (post.nodes.threadContainer) { - nodes.push(post.nodes.threadContainer); - } - i = children.length; - for (j = children.length - 1; j >= 0; j += -1) { - child = children[j]; - if (child.ID >= post.ID) { - i--; - } - } - if (i !== children.length) { - next = children[i]; - for (k = 0, len = descendants.length; k < len; k++) { - x = descendants[k]; - order.before(order[next.ID], order[x.ID]); - } - children.splice(i, 0, post); - $.before(next.nodes.root, nodes); - } else { - prev = parent; - while ((prev2 = QuoteThreading.children[prev.fullID]) && prev2.length) { - prev = prev2[prev2.length - 1]; - } - for (l = descendants.length - 1; l >= 0; l += -1) { - x = descendants[l]; - order.after(order[prev.ID], order[x.ID]); - } - children.push(post); - $.add(threadContainer, nodes); - } - QuoteThreading.inserted[post.fullID] = true; - if (!parent.nodes.threadContainer) { - parent.nodes.threadContainer = threadContainer; - $.addClass(parent.nodes.root, 'threadOP'); - $.after(parent.nodes.root, threadContainer); - } - return true; - }, - rethread: function() { - var nodes, posts, thread; - if (!QuoteThreading.ready) { - return; - } - thread = QuoteThreading.thread; - posts = thread.posts; - QuoteThreading.threadNewLink.hidden = true; - if (Conf['Thread Quotes']) { - posts.forEach(QuoteThreading.insert); - } else { - nodes = []; - Unread.order = new RandomAccessList(); - QuoteThreading.inserted = $.dict(); - posts.forEach(function(post) { - if (post.isFetchedQuote) { - return; - } - Unread.order.push(post); - if (post.isReply) { - nodes.push(post.nodes.root); - } - if (QuoteThreading.children[post.fullID]) { - delete QuoteThreading.children[post.fullID]; - $.rmClass(post.nodes.root, 'threadOP'); - $.rm(post.nodes.threadContainer); - return delete post.nodes.threadContainer; - } - }); - $.add(thread.nodes.root, nodes); - } - Unread.position = Unread.order.first; - Unread.updatePosition(); - Unread.setLine(true); - Unread.read(); - return Unread.update(); - } - }; - - return QuoteThreading; - -}).call(this); - -QuoteYou = (function() { - var QuoteYou; - - QuoteYou = { - init: function() { - var ref; - if (!Conf['Remember Your Posts']) { - return; - } - this.db = new DataBoard('yourPosts'); - $.sync('Remember Your Posts', function(enabled) { - return Conf['Remember Your Posts'] = enabled; - }); - $.on(d, 'QRPostSuccessful', function(e) { - var cb; - cb = PostRedirect.delay(); - return $.get('Remember Your Posts', Conf['Remember Your Posts'], function(items) { - var boardID, postID, ref, threadID; - if (!items['Remember Your Posts']) { - return; - } - ref = e.detail, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID; - return QuoteYou.db.set({ - boardID: boardID, - threadID: threadID, - postID: postID, - val: true - }, cb); - }); - }); - if ((ref = g.VIEW) !== 'index' && ref !== 'thread' && ref !== 'archive') { - return; - } - if (Conf['Highlight Own Posts']) { - $.addClass(doc, 'highlight-own'); - } - if (Conf['Highlight Posts Quoting You']) { - $.addClass(doc, 'highlight-you'); - } - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - this.mark = $.el('span', { - textContent: '\u00A0(You)', - className: 'qmark-you' - }); - Callbacks.Post.push({ - name: 'Mark Quotes of You', - cb: this.node - }); - return QuoteYou.menu.init(); - }, - isYou: function(post) { - var ref; - return !!((ref = QuoteYou.db) != null ? ref.get({ - boardID: post.boardID, - threadID: post.threadID, - postID: post.ID - }) : void 0); - }, - node: function() { - var i, len, quotelink, ref; - if (this.isClone) { - return; - } - if (QuoteYou.isYou(this)) { - $.addClass(this.nodes.root, 'yourPost'); - } - if (!this.quotes.length) { - return; - } - ref = this.nodes.quotelinks; - for (i = 0, len = ref.length; i < len; i++) { - quotelink = ref[i]; - if (!(QuoteYou.db.get(Get.postDataFromLink(quotelink)))) { - continue; - } - if (Conf['Mark Quotes of You']) { - $.add(quotelink, QuoteYou.mark.cloneNode(true)); - } - $.addClass(quotelink, 'you'); - $.addClass(this.nodes.root, 'quotesYou'); - } - }, - menu: { - init: function() { - var input, label, ref; - label = $.el('label', { - className: 'toggle-you' - }, {innerHTML: " You"}); - input = $('input', label); - $.on(input, 'change', QuoteYou.menu.toggle); - return (ref = Menu.menu) != null ? ref.addEntry({ - el: label, - order: 80, - open: function(post) { - QuoteYou.menu.post = post.origin || post; - input.checked = QuoteYou.isYou(post); - return true; - } - }) : void 0; - }, - toggle: function() { - var clone, data, i, j, len, len1, post, quotelink, quoter, ref, ref1; - post = QuoteYou.menu.post; - data = { - boardID: post.board.ID, - threadID: post.thread.ID, - postID: post.ID, - val: true - }; - if (this.checked) { - QuoteYou.db.set(data); - } else { - QuoteYou.db["delete"](data); - } - ref = [post].concat(post.clones); - for (i = 0, len = ref.length; i < len; i++) { - clone = ref[i]; - clone.nodes.root.classList.toggle('yourPost', this.checked); - } - ref1 = Get.allQuotelinksLinkingTo(post); - for (j = 0, len1 = ref1.length; j < len1; j++) { - quotelink = ref1[j]; - if (this.checked) { - if (Conf['Mark Quotes of You']) { - $.add(quotelink, QuoteYou.mark.cloneNode(true)); - } - } else { - $.rm($('.qmark-you', quotelink)); - } - quotelink.classList.toggle('you', this.checked); - if ($.hasClass(quotelink, 'quotelink')) { - quoter = Get.postFromNode(quotelink).nodes.root; - quoter.classList.toggle('quotesYou', !!$('.quotelink.you', quoter)); - } - } - } - }, - cb: { - seek: function(type) { - var highlight, highlighted, post, posts, result, str; - highlight = g.SITE.classes.highlight; - if ((highlighted = $("." + highlight))) { - $.rmClass(highlighted, highlight); - } - if (!(QuoteYou.lastRead && doc.contains(QuoteYou.lastRead) && $.hasClass(QuoteYou.lastRead, 'quotesYou'))) { - if (!(post = QuoteYou.lastRead = $('.quotesYou'))) { - new Notice('warning', 'No posts are currently quoting you, loser.', 20); - return; - } - if (QuoteYou.cb.scroll(post)) { - return; - } - } else { - post = QuoteYou.lastRead; - } - str = type + "::div[contains(@class,'quotesYou')]"; - while ((post = (result = $.X(str, post)).snapshotItem(type === 'preceding' ? result.snapshotLength - 1 : 0))) { - if (QuoteYou.cb.scroll(post)) { - return; - } - } - posts = $$('.quotesYou'); - return QuoteYou.cb.scroll(posts[type === 'following' ? 0 : posts.length - 1]); - }, - scroll: function(root) { - var node, post, sel; - post = Get.postFromRoot(root); - if (!post.nodes.post.getBoundingClientRect().height) { - return false; - } else { - QuoteYou.lastRead = root; - location.href = Get.url('post', post); - Header.scrollTo(post.nodes.post); - if (post.isReply) { - sel = "" + g.SITE.selectors.postContainer + g.SITE.selectors.highlightable.reply; - node = post.nodes.root; - if (!node.matches(sel)) { - node = $(sel, node); - } - $.addClass(node, g.SITE.classes.highlight); - } - return true; - } - } - } - }; - - return QuoteYou; - -}).call(this); - -Quotify = (function() { - var Quotify, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - slice = [].slice; - - Quotify = { - init: function() { - var ref; - if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Resurrect Quotes']) { - return; - } - $.addClass(doc, 'resurrect-quotes'); - if (Conf['Comment Expansion']) { - ExpandComment.callbacks.push(this.node); - } - return Callbacks.Post.push({ - name: 'Resurrect Quotes', - cb: this.node - }); - }, - node: function() { - var deadlink, i, j, len, len1, link, ref, ref1; - if (this.isClone) { - this.nodes.archivelinks = $$('a.linkify.quotelink', this.nodes.comment); - return; - } - ref = $$('a.linkify', this.nodes.comment); - for (i = 0, len = ref.length; i < len; i++) { - link = ref[i]; - Quotify.parseArchivelink.call(this, link); - } - ref1 = $$('.deadlink', this.nodes.comment); - for (j = 0, len1 = ref1.length; j < len1; j++) { - deadlink = ref1[j]; - Quotify.parseDeadlink.call(this, deadlink); - } - }, - parseArchivelink: function(link) { - var boardID, m, postID, ref, threadID; - if (!(m = link.pathname.match(/^\/([^\/]+)\/thread\/S?(\d+)\/?$/))) { - return; - } - if ((ref = link.hostname) === 'boards.4chan.org' || ref === 'boards.4channel.org') { - return; - } - boardID = m[1]; - threadID = m[2]; - postID = link.hash.match(/^#[pq]?(\d+)$|$/)[1] || threadID; - if (Redirect.to('post', { - boardID: boardID, - postID: postID - })) { - $.addClass(link, 'quotelink'); - $.extend(link.dataset, { - boardID: boardID, - threadID: threadID, - postID: postID - }); - return this.nodes.archivelinks.push(link); - } - }, - parseDeadlink: function(deadlink) { - var a, boardID, fetchable, m, post, postID, quote, quoteID, redirect, ref; - if ($.hasClass(deadlink.parentNode, 'prettyprint')) { - Quotify.fixDeadlink(deadlink); - return; - } - quote = deadlink.textContent; - if (!(postID = (ref = quote.match(/\d+$/)) != null ? ref[0] : void 0)) { - return; - } - if (postID[0] === '0') { - Quotify.fixDeadlink(deadlink); - return; - } - boardID = (m = quote.match(/^>>>\/([a-z\d]+)/)) ? m[1] : this.board.ID; - quoteID = boardID + "." + postID; - if (post = g.posts.get(quoteID)) { - if (!post.isDead) { - a = $.el('a', { - href: g.SITE.Build.postURL(boardID, post.thread.ID, postID), - className: 'quotelink', - textContent: quote - }); - } else { - a = $.el('a', { - href: g.SITE.Build.postURL(boardID, post.thread.ID, postID), - className: 'quotelink deadlink', - textContent: quote - }); - $.add(a, Post.deadMark.cloneNode(true)); - $.extend(a.dataset, { - boardID: boardID, - threadID: post.thread.ID, - postID: postID - }); - } - } else { - redirect = Redirect.to('thread', { - boardID: boardID, - threadID: 0, - postID: postID - }); - fetchable = Redirect.to('post', { - boardID: boardID, - postID: postID - }); - if (redirect || fetchable) { - a = $.el('a', { - href: redirect || 'javascript:;', - className: 'deadlink', - textContent: quote - }); - $.add(a, Post.deadMark.cloneNode(true)); - if (fetchable) { - $.addClass(a, 'quotelink'); - $.extend(a.dataset, { - boardID: boardID, - postID: postID - }); - } - } - } - if (indexOf.call(this.quotes, quoteID) < 0) { - this.quotes.push(quoteID); - } - if (!a) { - $.add(deadlink, Post.deadMark.cloneNode(true)); - return; - } - $.replace(deadlink, a); - if ($.hasClass(a, 'quotelink')) { - return this.nodes.quotelinks.push(a); - } - }, - fixDeadlink: function(deadlink) { - var el, green; - if (!(el = deadlink.previousSibling) || el.nodeName === 'BR') { - green = $.el('span', { - className: 'quote' - }); - $.before(deadlink, green); - $.add(green, deadlink); - } - return $.replace(deadlink, slice.call(deadlink.childNodes)); - } - }; - - return Quotify; - -}).call(this); - -Main = (function() { - var Main, - indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; - - Main = { - init: function() { - var db, flatten, i, items, j, k, key, len, mountedCB, ref, ref1, ref2, w; - try { - w = window; - if ($.platform === 'crx') { - w = w.wrappedJSObject || w; - } - if ('4chan X antidup' in w) { - return; - } - w['4chan X antidup'] = true; - } catch (error1) {} - try { - if (window.frameElement && ((ref = window.frameElement.src) === '' || ref === 'about:blank')) { - return; - } - } catch (error1) {} - if (doc && $.hasClass(doc, 'fourchan-x')) { - return; - } - $.asap(docSet, function() { - $.addClass(doc, 'fourchan-x', 'seaweedchan'); - if ($.engine) { - return $.addClass(doc, "ua-" + $.engine); - } - }); - $.on(d, '4chanXInitFinished', function() { - if (Main.expectInitFinished) { - return delete Main.expectInitFinished; - } else { - new Notice('error', 'Error: Multiple copies of 4chan X are enabled.'); - return $.addClass(doc, 'tainted'); - } - }); - mountedCB = function() { - var cb, j, len, ref1, results; - d.removeEventListener('mounted', mountedCB, true); - Main.isMounted = true; - ref1 = Main.mountedCBs; - results = []; - for (j = 0, len = ref1.length; j < len; j++) { - cb = ref1[j]; - try { - results.push(cb()); - } catch (error1) {} - } - return results; - }; - d.addEventListener('mounted', mountedCB, true); - flatten = function(parent, obj) { - var key, val; - if (obj instanceof Array) { - Conf[parent] = $.dict.clone(obj[0]); - } else if (typeof obj === 'object') { - for (key in obj) { - val = obj[key]; - flatten(key, val); - } - } else { - Conf[parent] = obj; - } - }; - if ((ref1 = location.hostname) === 'boards.4chan.org' || ref1 === 'boards.4channel.org') { - $.global(function() { - var fromCharCode0; - fromCharCode0 = String.fromCharCode; - return String.fromCharCode = function() { - if (document.body) { - String.fromCharCode = fromCharCode0; - } else if (document.currentScript && !document.currentScript.src) { - throw Error(); - } - return fromCharCode0.apply(this, arguments); - }; - }); - $.asap(docSet, function() { - return $.onExists(doc, 'iframe[srcdoc]', $.rm); - }); - } - flatten(null, Config); - ref2 = DataBoard.keys; - for (j = 0, len = ref2.length; j < len; j++) { - db = ref2[j]; - Conf[db] = $.dict(); - } - Conf['customTitles'] = $.dict.clone({ - '4chan.org': { - boards: { - 'qa': { - 'boardTitle': { - orig: '/qa/ - Question & Answer', - title: '/qa/ - 2D/Random' - } - } - } - } - }); - Conf['boardConfig'] = { - boards: $.dict() - }; - Conf['archives'] = Redirect.archives; - Conf['selectedArchives'] = $.dict(); - Conf['cooldowns'] = $.dict(); - Conf['Index Sort'] = $.dict(); - for (i = k = 0; k < 2; i = ++k) { - Conf["Last Long Reply Thresholds " + i] = $.dict(); - } - Conf['siteProperties'] = $.dict(); - Conf['Except Archives from Encryption'] = false; - Conf['JSON Navigation'] = true; - Conf['Oekaki Links'] = true; - Conf['Show Name and Subject'] = false; - Conf['QR Shortcut'] = true; - Conf['Bottom QR Link'] = true; - Conf['Toggleable Thread Watcher'] = true; - Conf['siteSoftware'] = ''; - Conf['Use Faster Image Host'] = 'true'; - Conf['Captcha Fixes'] = true; - Conf['captchaServiceDomain'] = ''; - Conf['captchaServiceKey'] = $.dict(); - if (/\.4chan(?:nel)?\.org$/.test(location.hostname) && !SW.yotsuba.regexp.pass.test(location.href) && !SW.yotsuba.regexp.captcha.test(location.href) && !$$('script:not([src])', d).filter(function(s) { - return /this\[/.test(s.textContent); - }).length) { - ($.getSync || $.get)({ - 'jsWhitelist': Conf['jsWhitelist'] - }, function(arg) { - var jsWhitelist; - jsWhitelist = arg.jsWhitelist; - return $.addCSP("script-src " + (jsWhitelist.replace(/^#.*$/mg, '').replace(/[\s;]+/g, ' ').trim())); - }); - } - items = $.dict(); - for (key in Conf) { - items[key] = void 0; - } - items['previousversion'] = void 0; - return ($.getSync || $.get)(items, function(items) { - var ref3; - if (!$.perProtocolSettings && /\.4chan(?:nel)?\.org$/.test(location.hostname) && ((ref3 = items['Redirect to HTTPS']) != null ? ref3 : Conf['Redirect to HTTPS']) && location.protocol !== 'https:') { - location.replace('https://' + location.host + location.pathname + location.search + location.hash); - return; - } - return $.asap(docSet, function() { - var ref4, val; - if ($.cantSet) { - - } else if (items.previousversion == null) { - Main.isFirstRun = true; - Main.ready(function() { - $.set('previousversion', g.VERSION); - return Settings.open(); - }); - } else if (items.previousversion !== g.VERSION) { - Main.upgrade(items); - } - for (key in Conf) { - val = Conf[key]; - Conf[key] = (ref4 = items[key]) != null ? ref4 : val; - } - return Site.init(Main.initFeatures); - }); - }); - }, - upgrade: function(items) { - var changes, previousversion; - previousversion = items.previousversion; - changes = Settings.upgrade(items, previousversion); - items.previousversion = changes.previousversion = g.VERSION; - return $.set(changes, function() { - var el, ref; - if ((ref = items['Show Updated Notifications']) != null ? ref : true) { - el = $.el('span', {innerHTML: "4chan X has been updated to version " + E(g.VERSION) + "."}); - return new Notice('info', el, 15); - } - }); - }, - parseURL: function(site, url) { - var pathname, r, ref; - if (site == null) { - site = g.SITE; - } - if (url == null) { - url = location; - } - r = {}; - if (!site) { - return r; - } - r.siteID = site.ID; - if (typeof site.isBoardlessPage === "function" ? site.isBoardlessPage(url) : void 0) { - return r; - } - pathname = url.pathname.split(/\/+/); - r.boardID = pathname[1]; - if (site.isFileURL(url)) { - r.VIEW = 'file'; - } else if (typeof site.isAuxiliaryPage === "function" ? site.isAuxiliaryPage(url) : void 0) { - - } else if ((ref = pathname[2]) === 'thread' || ref === 'res') { - r.VIEW = 'thread'; - r.threadID = r.THREADID = +pathname[3].replace(/\.\w+$/, ''); - } else if (pathname[2] === 'archive' && pathname[3] === 'res') { - r.VIEW = 'thread'; - r.threadID = r.THREADID = +pathname[4].replace(/\.\w+$/, ''); - r.threadArchived = true; - } else if (/^(?:catalog|archive)(?:\.\w+)?$/.test(pathname[2])) { - r.VIEW = pathname[2].replace(/\.\w+$/, ''); - } else if (/^(?:index|\d*)(?:\.\w+)?$/.test(pathname[2])) { - r.VIEW = 'index'; - } - return r; - }, - initFeatures: function() { - var base, err, feature, j, len, name, ref, ref1; - $.global(function() { - document.documentElement.classList.add('js-enabled'); - return window.FCX = {}; - }); - Main.jsEnabled = $.hasClass(doc, 'js-enabled'); - if (typeof $.ajaxPageInit === "function") { - $.ajaxPageInit(); - } - $.extend(g, Main.parseURL()); - if (g.boardID) { - g.BOARD = new Board(g.boardID); - } - if (!g.VIEW) { - if (typeof (base = g.SITE).initAuxiliary === "function") { - base.initAuxiliary(); - } - return; - } - if (g.VIEW === 'file') { - $.asap((function() { - return d.readyState !== 'loading'; - }), function() { - var base1, pathname, video; - if (g.SITE.software === 'yotsuba' && Conf['404 Redirect'] && (typeof (base1 = g.SITE).is404 === "function" ? base1.is404() : void 0)) { - pathname = location.pathname.split(/\/+/); - return Redirect.navigate('file', { - boardID: g.BOARD.ID, - filename: pathname[pathname.length - 1] - }); - } else if (video = $('video')) { - if (Conf['Volume in New Tab']) { - Volume.setup(video); - } - if (Conf['Loop in New Tab']) { - video.loop = true; - video.controls = false; - video.play(); - return ImageCommon.addControls(video); - } - } - }); - return; - } - g.threads = new SimpleDict(); - g.posts = new SimpleDict(); - $.onExists(doc, 'body', Main.initStyle); - ref = Main.features; - for (j = 0, len = ref.length; j < len; j++) { - ref1 = ref[j], name = ref1[0], feature = ref1[1]; - if (g.SITE.disabledFeatures && indexOf.call(g.SITE.disabledFeatures, name) >= 0) { - continue; - } - try { - feature.init(); - } catch (error1) { - err = error1; - Main.handleErrors({ - message: "\"" + name + "\" initialization crashed.", - error: err - }); - } - } - return $.ready(Main.initReady); - }, - initStyle: function() { - var keyboard, ref; - if (!Main.isThisPageLegit()) { - return; - } - if ((ref = $('link[href*=mobile]', d.head)) != null) { - ref.disabled = true; - } - doc.dataset.host = location.host; - $.addClass(doc, "sw-" + g.SITE.software); - $.addClass(doc, g.VIEW === 'thread' ? 'thread-view' : g.VIEW); - $.onExists(doc, '.ad-cnt, .adg-rects > .desktop', function(ad) { - return $.onExists(ad, 'img, iframe', function() { - return $.addClass(doc, 'ads-loaded'); - }); - }); - if (Conf['Autohiding Scrollbar']) { - $.addClass(doc, 'autohiding-scrollbar'); - } - $.ready(function() { - if (d.body.clientHeight > doc.clientHeight && (window.innerWidth === doc.clientWidth) !== Conf['Autohiding Scrollbar']) { - Conf['Autohiding Scrollbar'] = !Conf['Autohiding Scrollbar']; - $.set('Autohiding Scrollbar', Conf['Autohiding Scrollbar']); - return $.toggleClass(doc, 'autohiding-scrollbar'); - } - }); - $.addStyle(CSS.sub(CSS.boards), 'fourchanx-css'); - Main.bgColorStyle = $.el('style', { - id: 'fourchanx-bgcolor-css' - }); - keyboard = false; - $.on(d, 'mousedown', function() { - return keyboard = false; - }); - $.on(d, 'keydown', function(e) { - if (e.keyCode === 9) { - return keyboard = true; - } - }); - window.addEventListener('focus', (function() { - return doc.classList.toggle('keyboard-focus', keyboard); - }), true); - return Main.setClass(); - }, - setClass: function() { - var j, knownStyles, len, mainStyleSheet, ref, ref1, setStyle, style, styleSheet, styleSheets; - knownStyles = ['yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'photon', 'tomorrow', 'spooky']; - if (g.SITE.software === 'yotsuba' && g.VIEW === 'catalog') { - if ((mainStyleSheet = $.id('base-css'))) { - style = (ref = mainStyleSheet.href.match(/catalog_(\w+)/)) != null ? ref[1].replace('_new', '').replace(/_+/g, '-') : void 0; - if (indexOf.call(knownStyles, style) >= 0) { - $.addClass(doc, style); - return; - } - } - } - style = mainStyleSheet = styleSheets = null; - setStyle = function() { - var bgColor, css, div, j, len, rgb, s, styleSheet; - if (g.SITE.software === 'yotsuba') { - $.rmClass(doc, style); - style = null; - for (j = 0, len = styleSheets.length; j < len; j++) { - styleSheet = styleSheets[j]; - if (styleSheet.href === (mainStyleSheet != null ? mainStyleSheet.href : void 0)) { - style = styleSheet.title.toLowerCase().replace('new', '').trim().replace(/\s+/g, '-'); - if (style === '_special') { - style = styleSheet.href.match(/[a-z]*(?=[^\/]*$)/)[0]; - } - if (indexOf.call(knownStyles, style) < 0) { - style = null; - } - break; - } - } - if (style) { - $.addClass(doc, style); - $.rm(Main.bgColorStyle); - return; - } - } - div = g.SITE.bgColoredEl(); - div.style.position = 'absolute'; - div.style.visibility = 'hidden'; - $.add(d.body, div); - bgColor = window.getComputedStyle(div).backgroundColor; - $.rm(div); - rgb = bgColor.match(/[\d.]+/g); - if (!/^rgb\(/.test(bgColor)) { - s = window.getComputedStyle(d.body); - bgColor = s.backgroundColor + " " + s.backgroundImage + " " + s.backgroundRepeat + " " + s.backgroundPosition; - } - css = ".dialog, .suboption-list > div:last-of-type, :root.catalog-hover-expand .catalog-container:hover > .post {\n background: " + bgColor + ";\n}\n.unread-mark-read {\n background-color: rgba(" + (rgb.slice(0, 3).join(', ')) + ", " + (0.5 * (rgb[3] || 1)) + ");\n}"; - if ($.luma(rgb) < 100) { - css += ".watch-thread-link {\n background-image: url(\"data:image/svg+xml,\");\n}"; - } - Main.bgColorStyle.textContent = css; - return $.after($.id('fourchanx-css'), Main.bgColorStyle); - }; - $.onExists(d.head, g.SITE.selectors.styleSheet, function(el) { - mainStyleSheet = el; - if (g.SITE.software === 'yotsuba') { - styleSheets = $$('link[rel="alternate stylesheet"]', d.head); - } - new MutationObserver(setStyle).observe(mainStyleSheet, { - attributes: true, - attributeFilter: ['href'] - }); - $.on(mainStyleSheet, 'load', setStyle); - return setStyle(); - }); - if (!mainStyleSheet) { - ref1 = $$('link[rel="stylesheet"]', d.head); - for (j = 0, len = ref1.length; j < len; j++) { - styleSheet = ref1[j]; - $.on(styleSheet, 'load', setStyle); - } - return setStyle(); - } - }, - initReady: function() { - var base, base1, msg; - if (typeof (base = g.SITE).is404 === "function" ? base.is404() : void 0) { - if (g.VIEW === 'thread') { - ThreadWatcher.set404(g.BOARD.ID, g.THREADID, function() { - if (Conf['404 Redirect']) { - return Redirect.navigate('thread', { - boardID: g.BOARD.ID, - threadID: g.THREADID, - postID: +location.hash.match(/\d+/) - }, "/" + g.BOARD + "/"); - } - }); - } - return; - } - if (typeof (base1 = g.SITE).isIncomplete === "function" ? base1.isIncomplete() : void 0) { - msg = $.el('div', {innerHTML: "The page didn't load completely.
        Some features may not work unless you reload."}); - $.on($('a', msg), 'click', function() { - return location.reload(); - }); - new Notice('warning', msg); - } - if (g.VIEW === 'catalog') { - return Main.initCatalog(); - } else if (!Index.enabled) { - if (g.SITE.awaitBoard) { - return g.SITE.awaitBoard(Main.initThread); - } else { - return Main.initThread(); - } - } else { - Main.expectInitFinished = true; - return $.event('4chanXInitFinished'); - } - }, - initThread: function() { - var base, base1, board, errors, posts, ref, s, threads; - s = g.SITE.selectors; - if ((board = $(((ref = s.boardFor) != null ? ref[g.VIEW] : void 0) || s.board))) { - threads = []; - posts = []; - errors = []; - try { - if (typeof (base = g.SITE).preParsingFixes === "function") { - base.preParsingFixes(board); - } - } catch (error1) {} - Main.addThreadsObserver = new MutationObserver(Main.addThreads); - Main.addPostsObserver = new MutationObserver(Main.addPosts); - Main.addThreadsObserver.observe(board, { - childList: true - }); - Main.parseThreads($$(s.thread, board), threads, posts, errors); - if (errors.length) { - Main.handleErrors(errors); - } - if (g.VIEW === 'thread') { - if (g.threadArchived) { - threads[0].isArchived = true; - threads[0].kill(); - } - if (typeof (base1 = g.SITE).parseThreadMetadata === "function") { - base1.parseThreadMetadata(threads[0]); - } - } - Main.callbackNodes('Thread', threads); - return Main.callbackNodesDB('Post', posts, function() { - var j, len, post; - for (j = 0, len = posts.length; j < len; j++) { - post = posts[j]; - QuoteThreading.insert(post); - } - Main.expectInitFinished = true; - return $.event('4chanXInitFinished'); - }); - } else { - Main.expectInitFinished = true; - return $.event('4chanXInitFinished'); - } - }, - parseThreads: function(threadRoots, threads, posts, errors) { - var boardID, boardObj, j, len, postRoots, ref, thread, threadID, threadRoot; - for (j = 0, len = threadRoots.length; j < len; j++) { - threadRoot = threadRoots[j]; - boardObj = (boardID = threadRoot.dataset.board) ? (boardID = encodeURIComponent(boardID), g.boards[boardID] || new Board(boardID)) : g.BOARD; - threadID = +threadRoot.id.match(/\d*$/)[0]; - if (!threadID || ((ref = boardObj.threads.get(threadID)) != null ? ref.nodes.root : void 0)) { - return; - } - thread = new Thread(threadID, boardObj); - thread.nodes.root = threadRoot; - threads.push(thread); - postRoots = $$(g.SITE.selectors.postContainer, threadRoot); - if (g.SITE.isOPContainerThread) { - postRoots.unshift(threadRoot); - } - Main.parsePosts(postRoots, thread, posts, errors); - Main.addPostsObserver.observe(threadRoot, { - childList: true - }); - } - }, - parsePosts: function(postRoots, thread, posts, errors) { - var err, j, len, postRoot; - for (j = 0, len = postRoots.length; j < len; j++) { - postRoot = postRoots[j]; - if (!(postRoot.dataset.fullID && g.posts.get(postRoot.dataset.fullID)) && $(g.SITE.selectors.comment, postRoot)) { - try { - posts.push(new Post(postRoot, thread, thread.board)); - } catch (error1) { - err = error1; - errors.push({ - message: "Parsing of Post No." + (postRoot.id.match(/\d+/)) + " failed. Post will be skipped.", - error: err, - html: postRoot.outerHTML - }); - } - } - } - }, - addThreads: function(records) { - var errors, j, k, len, len1, node, posts, record, ref, threadRoots, threads; - threadRoots = []; - for (j = 0, len = records.length; j < len; j++) { - record = records[j]; - ref = record.addedNodes; - for (k = 0, len1 = ref.length; k < len1; k++) { - node = ref[k]; - if (node.nodeType === Node.ELEMENT_NODE && node.matches(g.SITE.selectors.thread)) { - threadRoots.push(node); - } - } - } - if (!threadRoots.length) { - return; - } - threads = []; - posts = []; - errors = []; - Main.parseThreads(threadRoots, threads, posts, errors); - if (errors.length) { - Main.handleErrors(errors); - } - Main.callbackNodes('Thread', threads); - return Main.callbackNodesDB('Post', posts, function() { - return $.event('PostsInserted', null, records[0].target); - }); - }, - addPosts: function(records) { - var anyRemoved, el, errors, j, k, l, len, len1, len2, n, node, postRoots, posts, record, ref, ref1, ref2, thread, threads, threadsRM; - threads = []; - threadsRM = []; - posts = []; - errors = []; - for (j = 0, len = records.length; j < len; j++) { - record = records[j]; - thread = Get.threadFromRoot(record.target); - postRoots = []; - ref = record.addedNodes; - for (k = 0, len1 = ref.length; k < len1; k++) { - node = ref[k]; - if (node.nodeType === Node.ELEMENT_NODE) { - if (node.matches(g.SITE.selectors.postContainer) || (node = $(g.SITE.selectors.postContainer, node))) { - postRoots.push(node); - } - } - } - n = posts.length; - Main.parsePosts(postRoots, thread, posts, errors); - if (posts.length > n && indexOf.call(threads, thread) < 0) { - threads.push(thread); - } - anyRemoved = false; - ref1 = record.removedNodes; - for (l = 0, len2 = ref1.length; l < len2; l++) { - el = ref1[l]; - if (((ref2 = Get.postFromRoot(el)) != null ? ref2.nodes.root : void 0) === el && !doc.contains(el)) { - anyRemoved = true; - break; - } - } - if (anyRemoved && indexOf.call(threadsRM, thread) < 0) { - threadsRM.push(thread); - } - } - if (errors.length) { - Main.handleErrors(errors); - } - return Main.callbackNodesDB('Post', posts, function() { - var len3, len4, m, o; - for (m = 0, len3 = threads.length; m < len3; m++) { - thread = threads[m]; - $.event('PostsInserted', null, thread.nodes.root); - } - for (o = 0, len4 = threadsRM.length; o < len4; o++) { - thread = threadsRM[o]; - $.event('PostsRemoved', null, thread.nodes.root); - } - }); - }, - initCatalog: function() { - var board, errors, s, threads; - s = g.SITE.selectors.catalog; - if (s && (board = $(s.board))) { - threads = []; - errors = []; - Main.addCatalogThreadsObserver = new MutationObserver(Main.addCatalogThreads); - Main.addCatalogThreadsObserver.observe(board, { - childList: true - }); - Main.parseCatalogThreads($$(s.thread, board), threads, errors); - if (errors.length) { - Main.handleErrors(errors); - } - Main.callbackNodes('CatalogThreadNative', threads); - } - Main.expectInitFinished = true; - return $.event('4chanXInitFinished'); - }, - parseCatalogThreads: function(threadRoots, threads, errors) { - var err, j, len, ref, thread, threadRoot; - for (j = 0, len = threadRoots.length; j < len; j++) { - threadRoot = threadRoots[j]; - try { - thread = new CatalogThreadNative(threadRoot); - if (((ref = thread.thread.catalogViewNative) != null ? ref.nodes.root : void 0) !== threadRoot) { - thread.thread.catalogViewNative = thread; - threads.push(thread); - } - } catch (error1) { - err = error1; - errors.push({ - message: "Parsing of Catalog Thread No." + ((threadRoot.dataset.id || threadRoot.id).match(/\d+/)) + " failed. Thread will be skipped.", - error: err, - html: threadRoot.outerHTML - }); - } - } - }, - addCatalogThreads: function(records) { - var errors, j, k, len, len1, node, record, ref, threadRoots, threads; - threadRoots = []; - for (j = 0, len = records.length; j < len; j++) { - record = records[j]; - ref = record.addedNodes; - for (k = 0, len1 = ref.length; k < len1; k++) { - node = ref[k]; - if (node.nodeType === Node.ELEMENT_NODE && node.matches(g.SITE.selectors.catalog.thread)) { - threadRoots.push(node); - } - } - } - if (!threadRoots.length) { - return; - } - threads = []; - errors = []; - Main.parseCatalogThreads(threadRoots, threads, errors); - if (errors.length) { - Main.handleErrors(errors); - } - return Main.callbackNodes('CatalogThreadNative', threads); - }, - callbackNodes: function(klass, nodes) { - var cb, i, node; - i = 0; - cb = Callbacks[klass]; - while (node = nodes[i++]) { - cb.execute(node); - } - }, - callbackNodesDB: function(klass, nodes, cb) { - var cbs, fn, i, softTask; - i = 0; - cbs = Callbacks[klass]; - fn = function() { - var node; - if (!(node = nodes[i])) { - return false; - } - cbs.execute(node); - return ++i % 25; - }; - softTask = function() { - while (fn()) { - continue; - } - if (!nodes[i]) { - if (cb) { - cb(); - } - return; - } - return setTimeout(softTask, 0); - }; - return softTask(); - }, - handleErrors: function(errors) { - var div, enabled, error, j, len, logs, msg; - if (d.body && $.hasClass(d.body, 'fourchan_x') && !$.hasClass(doc, 'tainted')) { - new Notice('error', 'Error: Multiple copies of 4chan X are enabled.'); - $.addClass(doc, 'tainted'); - } - if (g.SITE.testNativeExtension && !$.hasClass(doc, 'tainted')) { - enabled = g.SITE.testNativeExtension().enabled; - if (enabled) { - $.addClass(doc, 'tainted'); - if (Conf['Disable Native Extension'] && !Main.isFirstRun) { - msg = $.el('div', {innerHTML: "Failed to disable the native extension. You may need to block it."}); - new Notice('error', msg); - } - } - } - if (!(errors instanceof Array)) { - error = errors; - } else if (errors.length === 1) { - error = errors[0]; - } - if (error) { - new Notice('error', Main.parseError(error, Main.reportLink([error])), 15); - return; - } - div = $.el('div', {innerHTML: E(errors.length) + " errors occurred." + (Main.reportLink(errors)).innerHTML + " [show]"}); - $.on(div.lastElementChild, 'click', function() { - var ref; - return ref = this.textContent === 'show' ? ['hide', false] : ['show', true], this.textContent = ref[0], logs.hidden = ref[1], ref; - }); - logs = $.el('div', { - hidden: true - }); - for (j = 0, len = errors.length; j < len; j++) { - error = errors[j]; - $.add(logs, Main.parseError(error)); - } - return new Notice('error', [div, logs], 30); - }, - parseError: function(data, reportLink) { - var context, error, lines, message, ref, ref1; - c.error(data.message, data.error.stack); - message = $.el('div', {innerHTML: E(data.message) + ((reportLink) ? (reportLink).innerHTML : "")}); - error = $.el('div', { - textContent: (data.error.name || 'Error') + ": " + (data.error.message || 'see console for details') - }); - lines = ((ref = data.error.stack) != null ? (ref1 = ref.match(/\d+(?=:\d+\)?$)/mg)) != null ? ref1.join().replace(/^/, ' at ') : void 0 : void 0) || ''; - context = $.el('div', { - textContent: "(4chan X ccd0 v" + g.VERSION + " " + $.platform + " on " + $.engine + lines + ")" - }); - return [message, error, context]; - }, - reportLink: function(errors) { - var addDetails, data, details, info, title, url; - data = errors[0]; - title = data.message; - if (errors.length > 1) { - title += " (+" + (errors.length - 1) + " other errors)"; - } - details = ''; - addDetails = function(text) { - if (!(encodeURIComponent(title + details + text + '\n').length > 8143)) { - return details += text + '\n'; - } - }; - addDetails("[Please describe the steps needed to reproduce this error.]\n\nScript: 4chan X ccd0 v" + g.VERSION + " " + $.platform + "\nURL: " + location.href + "\nUser agent: " + navigator.userAgent); - if ($.platform === 'userscript' && (info = typeof GM !== "undefined" && GM !== null ? GM.info : (typeof GM_info !== "undefined" && GM_info !== null ? GM_info : void 0))) { - addDetails("Userscript manager: " + info.scriptHandler + " " + info.version); - } - addDetails('\n' + data.error); - if (data.error.stack) { - addDetails(data.error.stack.replace(data.error.toString(), '').trim()); - } - if (data.html) { - addDetails('\n`' + data.html + '`'); - } - details = details.replace(/file:\/{3}.+\//g, ''); - url = 'https://github.com/ccd0/4chan-x/issues'.replace('%title', encodeURIComponent(title)).replace('%details', encodeURIComponent(details)); - return {innerHTML: " [report]"}; - }, - isThisPageLegit: function() { - if (!('thisPageIsLegit' in Main)) { - Main.thisPageIsLegit = g.SITE.isThisPageLegit ? g.SITE.isThisPageLegit() : !/^[45]\d\d\b/.test(document.title) && !/\.(?:json|rss)$/.test(location.pathname); - } - return Main.thisPageIsLegit; - }, - ready: function(cb) { - return $.ready(function() { - if (Main.isThisPageLegit()) { - return cb(); - } - }); - }, - mounted: function(cb) { - if (Main.isMounted) { - return cb(); - } else { - return Main.mountedCBs.push(cb); - } - }, - mountedCBs: [], - features: [['Polyfill', Polyfill], ['Board Configuration', BoardConfig], ['Normalize URL', NormalizeURL], ['Delay Redirect on Post', PostRedirect], ['Captcha Configuration', Captcha.replace], ['Image Host Rewriting', ImageHost], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Tinyboard Glue', Tinyboard], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['Count Posts by ID', IDPostCount], ['Custom CSS', CustomCSS], ['Thread Links', ThreadLinks], ['Linkify', Linkify], ['Reveal Spoilers', RemoveSpoilers], ['Resurrect Quotes', Quotify], ['Filter', Filter], ['Thread Hiding Buttons', ThreadHiding], ['Reply Hiding Buttons', PostHiding], ['Recursive', Recursive], ['Strike-through Quotes', QuoteStrikeThrough], ['Quick Reply Personas', QR.persona], ['Quick Reply', QR], ['Cooldown', QR.cooldown], ['Post Jumper', PostJumper], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['Copy Text Link', CopyTextLink], ['Thread Hiding (Menu)', ThreadHiding.menu], ['Reply Hiding (Menu)', PostHiding.menu], ['Delete Link', DeleteLink], ['Filter (Menu)', Filter.menu], ['Edit Link', QR.oekaki.menu], ['Download Link', DownloadLink], ['Archive Link', ArchiveLink], ['Quote Inlining', QuoteInline], ['Quote Previewing', QuotePreview], ['Quote Backlinks', QuoteBacklink], ['Mark Quotes of You', QuoteYou], ['Mark OP Quotes', QuoteOP], ['Mark Cross-thread Quotes', QuoteCT], ['Anonymize', Anonymize], ['Time Formatting', Time], ['Relative Post Dates', RelativeDates], ['File Info Formatting', FileInfo], ['Fappe Tyme', FappeTyme], ['Gallery', Gallery], ['Gallery (menu)', Gallery.menu], ['Sauce', Sauce], ['Image Expansion', ImageExpand], ['Image Expansion (Menu)', ImageExpand.menu], ['Reveal Spoiler Thumbnails', RevealSpoilers], ['Image Loading', ImageLoader], ['Image Hover', ImageHover], ['Volume Control', Volume], ['WEBM Metadata', Metadata], ['Comment Expansion', ExpandComment], ['Thread Expansion', ExpandThread], ['Favicon', Favicon], ['Unread', Unread], ['Unread Line in Index', UnreadIndex], ['Quote Threading', QuoteThreading], ['Thread Stats', ThreadStats], ['Thread Updater', ThreadUpdater], ['Thread Watcher', ThreadWatcher], ['Thread Watcher (Menu)', ThreadWatcher.menu], ['Mark New IPs', MarkNewIPs], ['Index Navigation', Nav], ['Keybinds', Keybinds], ['Banner', Banner], ['Announcements', PSA], ['Flash Features', Flash], ['Reply Pruning', ReplyPruning], ['Mod Contact Links', ModContact]] - }; - - return Main; - -}).call(this); - -Main.init(); - -})(); diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip deleted file mode 100644 index b927d4fc9a86bfbe9243dff8a8d4fd6dac9e5f5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 330469 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 z�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

        d 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 Cj%$Me diff --git a/builds/4chan-XT-noupdate.user.js b/builds/4chan-XT-noupdate.user.js new file mode 100644 index 000000000..6720af429 --- /dev/null +++ b/builds/4chan-XT-noupdate.user.js @@ -0,0 +1,27297 @@ +// ==UserScript== +// @name 4chan XT +// @version XT 2.0.0 +// @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/master/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 +* http://zixaphir.github.io/appchan-x/ +* 4chan x Copyright © 2009-2011 James Campos +* https://github.com/aeosynth/4chan-x +* 4chan x Copyright © 2012-2014 Nicolas Stepien +* https://4chan-x.just-believe.in/ +* 4chan x Copyright © 2013-2014 Jordan Bates +* 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 version = { + "version": "XT 2.0.0", + "date": "2023-04-30T13:46:25Z" + }; + + var meta = { + "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/TuxedoTako/4chan-xt/wiki/Frequently-Asked-Questions", + "captchaFAQ": "https://github.com/TuxedoTako/4chan-xt/wiki/Captcha-FAQ", + "cssGuide": "https://github.com/TuxedoTako/4chan-xt/wiki/Styling-Guide", + "license": "https://github.com/TuxedoTako/4chan-xt/blob/master/LICENSE", + "changelog": "https://github.com/TuxedoTako/4chan-xt/blob/master/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 Conf = Object.create(null); + const g = { + VERSION: version.version, + NAMESPACE: meta.name, + sites: Object.create(null), + boards: Object.create(null) + }; + const E = (function () { + const str = { + '&': '&', + "'": ''', + '"': '"', + '<': '<', + '>': '>' + }; + const regex = /[&"'<>]/g; + const fn = function (x) { + return str[x]; + }; + const output = function (text) { + return text.toString().replace(regex, fn); + }; + output.cat = function (templates) { + let html = ''; + for (let i = 0; i < templates.length; i++) { + html += templates[i].innerHTML; + } + return html; + }; + return output; + })(); + const d$1 = document; + const doc$1 = d$1.documentElement; + const c = console; + const docSet = function () { + // return (doc = d.documentElement); + return doc$1; + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS206: Consider reworking classes to avoid initClass + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class Callbacks { + static initClass() { + this.Post = new Callbacks('Post'); + this.Thread = new Callbacks('Thread'); + this.CatalogThread = new Callbacks('Catalog Thread'); + this.CatalogThreadNative = new Callbacks('Catalog Thread'); + } + + constructor(type) { + this.type = type; + this.keys = []; + } + + push({name, cb}) { + if (!this[name]) { this.keys.push(name); } + return this[name] = cb; + } + + execute(node, keys=this.keys, force=false) { + let errors; + if (node.callbacksExecuted && !force) { return; } + node.callbacksExecuted = true; + for (var name of keys) { + try { + this[name]?.call(node); + } catch (err) { + if (!errors) { errors = []; } + errors.push({ + message: ['"', name, '" crashed on node ', this.type, ' No.', node.ID, ' (', node.board, ').'].join(''), + error: err, + html: node.nodes?.root?.outerHTML + }); + } + } + + if (errors) { return Main$1.handleErrors(errors); } + } + } + Callbacks.initClass(); + + var userCss = `/* Board title rice */ +div.boardTitle { + font-weight: 400 !important; +} +:root.yotsuba div.boardTitle { + font-family: sans-serif !important; + text-shadow: 1px 1px 1px rgba(100,0,0,0.6); +} +:root.yotsuba-b div.boardTitle { + font-family: sans-serif !important; + text-shadow: 1px 1px 1px rgba(105,10,15,0.6); +} +:root.photon div.boardTitle { + font-family: sans-serif !important; + text-shadow: 1px 1px 1px rgba(0,74,153,0.6); +} +:root.tomorrow div.boardTitle { + font-family: sans-serif !important; + text-shadow: 1px 1px 1px rgba(167,170,168,0.6); +} +`; + + var banners = ["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"]; + + const Config = { + main: { + 'Miscellaneous': { + 'Redirect to HTTPS': [ + true, + 'Redirect to the HTTPS version of 4chan.' + ], + 'JSON Index': [ + true, + 'Replace the original board index with one supporting searching, sorting, infinite scrolling, and a catalog mode.' + ], + [`Use ${meta.name} Catalog`]: [ + true, + `Link to ${meta.name}'s catalog instead of the native 4chan one.`, + 1 + ], + 'Index Refresh Notifications': [ + false, + 'Show a notice at the top of the page when the index is refreshed.', + 1 + ], + 'Follow Cursor': [ + true, + 'Image Hover and Quote Preview move with the mouse cursor.' + ], + 'Open Threads in New Tab': [ + false, + `Make links to threads in the index / ${meta.name} catalog open in a new tab.` + ], + 'External Catalog': [ + false, + 'Link to external catalog instead of the internal one.' + ], + 'Catalog Links': [ + false, + 'Add toggle link in header menu to turn Navigation links into links to each board\'s catalog.' + ], + 'Announcement Hiding': [ + true, + 'Add button to hide 4chan announcements.' + ], + 'Desktop Notifications': [ + true, + `Enables desktop notifications across various ${meta.name} features.` + ], + '404 Redirect': [ + true, + 'Redirect dead threads and images to the archives.' + ], + 'Archive Report': [ + true, + 'Enable reporting posts to supported archives.' + ], + 'Exempt Archives from Encryption': [ + true, + 'Permit loading content from, and warningless redirects to, HTTP-only archives from HTTPS pages.' + ], + 'Keybinds': [ + true, + 'Bind actions to keyboard shortcuts.' + ], + 'Time Formatting': [ + true, + 'Localize and format timestamps.' + ], + 'Relative Post Dates': [ + true, + 'Display dates like "3 minutes ago". Tooltip shows the timestamp.' + ], + 'Relative Date Title': [ + true, + 'Show Relative Post Date only when hovering over dates.', + 1 + ], + 'Comment Expansion': [ + true, + 'Expand comments that are too long to display on the index. Not applicable with JSON Index.' + ], + 'File Info Formatting': [ + true, + 'Reformat the file information.' + ], + 'Thread Expansion': [ + true, + 'Add buttons to expand threads.' + ], + 'Index Navigation': [ + false, + 'Add buttons to navigate between threads.' + ], + 'Reply Navigation': [ + false, + 'Add buttons to navigate to top / bottom of thread.' + ], + 'Unique ID and Capcode Navigation': [ + false, + 'Add buttons to navigate to posts having the same unique ID or capcode.' + ], + 'Custom Board Titles': [ + true, + 'Allow editing of the board title and subtitle by ctrl/\u2318+clicking them.' + ], + 'Persistent Custom Board Titles': [ + false, + 'Force custom board titles to be persistent, even if the board titles are updated.', + 1 + ], + 'Show Updated Notifications': [ + true, + `Show notifications when ${meta.name} is successfully updated.` + ], + 'Color User IDs': [ + true, + 'Assign unique colors to user IDs on boards that use them' + ], + 'Count Posts by ID': [ + true, + 'Display number of posts in the thread when hovering over an ID.' + ], + 'Remove Spoilers': [ + false, + 'Remove all spoilers in text.' + ], + 'Reveal Spoilers': [ + false, + 'Indicate spoilers if Remove Spoilers is enabled, or make the text appear hovered if Remove Spoiler is disabled.' + ], + 'Normalize URL': [ + true, + 'Rewrite the URL of the current page, removing slugs and excess slashes, and changing /res/ to /thread/.' + ], + 'Work around CORB Bug': [ + true, + 'Leave this checked until your garbage browser is fixed.' + ], + 'Disable Autoplaying Sounds': [ + false, + 'Prevent sounds on the page from autoplaying.' + ], + 'Disable Native Extension': [ + true, + `${meta.name} is NOT designed to work with the native extension.` + ], + 'Enable Native Flash Embedding': [ + true, + 'Activate the native extension\'s Flash embedding if the native extension is disabled.' + ] + }, + + 'Linkification': { + 'Linkify': [ + true, + 'Convert text into links where applicable.' + ], + 'Link Title': [ + true, + 'Replace the link of a supported site with its actual title.', + 1 + ], + 'Cover Preview': [ + true, + 'Show preview of supported links on hover.', + 1 + ], + 'Embedding': [ + true, + 'Embed supported services. Note: Some services don\'t work on HTTPS.', + 1 + ], + 'Auto-embed': [ + false, + 'Auto-embed Linkify Embeds.', + 2 + ], + 'Floating Embeds': [ + false, + 'Embed content in a frame that remains in place when the page is scrolled.', + 2 + ] + }, + + 'Filtering': { + 'Anonymize': [ + false, + 'Make everyone Anonymous.' + ], + 'Filter': [ + true, + 'Self-moderation placebo.' + ], + 'Filtered Backlinks': [ + false, + 'When enabled, shows backlinks to filtered posts with a line-through decoration. Otherwise, hides the backlinks.', + 1 + ], + 'Filter in Native Catalog': [ + true, + 'Apply 4chan X filters in native catalog.', + 1 + ], + 'MD5 Quick Filter Notifications': [ + true, + 'Show notification when quick filtering MD5s using the button or keybind.', + 1 + ], + 'Recursive Hiding': [ + true, + 'Hide replies of hidden posts, recursively.' + ], + 'Thread Hiding Buttons': [ + true, + 'Add buttons to hide entire threads.' + ], + 'Reply Hiding Buttons': [ + true, + 'Add buttons to hide single replies.' + ], + 'Stubs': [ + true, + 'Show stubs of hidden threads / replies.' + ] + }, + + 'Images and Videos': { + 'Image Expansion': [ + true, + 'Expand images / videos.' + ], + 'Image Hover': [ + true, + 'Show full image / video on mouseover.' + ], + 'Image Hover in Catalog': [ + true, + `Show full image / video on mouseover in ${meta.name} catalog.` + ], + 'Gallery': [ + true, + 'Adds a simple and cute image gallery. Has more options in the gallery menu.' + ], + 'Fullscreen Gallery': [ + false, + 'Open gallery in fullscreen mode.', + 1 + ], + 'PDF in Gallery': [ + false, + 'Show PDF files in gallery.', + 1 + ], + 'Sauce': [ + true, + 'Add sauce links to images.' + ], + 'WEBM Metadata': [ + true, + 'Add link to fetch title metadata from webm videos.' + ], + 'Reveal Spoiler Thumbnails': [ + false, + 'Replace spoiler thumbnails with the original image.' + ], + 'Replace GIF': [ + false, + 'Replace gif thumbnails with the actual image.' + ], + 'Replace JPG': [ + false, + 'Replace jpg thumbnails with the actual image.' + ], + 'Replace PNG': [ + false, + 'Replace png thumbnails with the actual image.' + ], + 'Replace WEBM': [ + false, + 'Replace webm, mp4, and ogv thumbnails with the actual video. Probably will degrade browser performance ;)' + ], + 'Image Prefetching': [ + true, + 'Add a shortcut icon to the header to turn on image preloading.' + ], + 'Fappe Tyme': [ + true, + 'Hide posts without images when header menu item is checked. *hint* *hint*' + ], + 'Werk Tyme': [ + true, + 'Hide all post images when header menu item is checked.' + ], + 'Autoplay': [ + true, + 'Videos begin playing immediately when opened.' + ], + 'Restart when Opened': [ + false, + 'Restart GIFs and WebMs when you hover over or expand them.' + ], + 'Show Controls': [ + true, + 'Show controls on videos expanded inline.' + ], + 'Click Passthrough': [ + false, + 'Clicks on videos trigger your browser\'s default behavior. Videos can be contracted with button / dragging to the left.', + 1 + ], + 'Allow Sound': [ + true, + 'Open videos with the sound unmuted.' + ], + 'Mouse Wheel Volume': [ + true, + 'Adjust volume of videos with the mouse wheel over the thumbnail/filename/gallery.' + ], + 'Loop in New Tab': [ + true, + 'Loop videos opened in their own tabs.' + ], + 'Volume in New Tab': [ + true, + `Apply ${meta.name} mute and volume settings to videos opened in their own tabs.` + ] + }, + + 'Menu': { + 'Menu': [ + true, + 'Add a drop-down menu to posts.' + ], + 'Report Link': [ + true, + 'Add a report link to the menu.', + 1 + ], + 'Copy Text Link': [ + true, + 'Add a link to copy the post\'s text.', + 1 + ], + 'Thread Hiding Link': [ + true, + 'Add a link to hide entire threads.', + 1 + ], + 'Reply Hiding Link': [ + true, + 'Add a link to hide single replies.', + 1 + ], + 'Delete Link': [ + true, + 'Add post and image deletion links to the menu.', + 1 + ], + 'Archive Link': [ + true, + 'Add an archive link to the menu.', + 1 + ], + 'Edit Link': [ + true, + 'Add a link to edit the image in Tegaki, /i/\'s painting program. Requires Quick Reply.', + 1 + ], + 'Download Link': [ + false, + 'Add a download with original filename link to the menu.', + 1 + ] + }, + + 'Monitoring': { + 'Thread Updater': [ + true, + 'Fetch and insert new replies. Has more options in the header menu and the "Advanced" tab.' + ], + 'Unread Count': [ + true, + 'Show the unread posts count in the tab title.' + ], + 'Quoted Title': [ + false, + 'Change the page title to reflect you\'ve been quoted.', + 1 + ], + 'Hide Unread Count at (0)': [ + false, + 'Hide the unread posts count in the tab title when it reaches 0.', + 1 + ], + 'Unread Favicon': [ + true, + 'Show a different favicon when there are unread posts.' + ], + 'Unread Line': [ + true, + 'Show a line to distinguish read posts from unread ones.' + ], + 'Remember Last Read Post': [ + true, + 'Remember how far you\'ve read after you close the thread.' + ], + 'Scroll to Last Read Post': [ + true, + 'Scroll back to the last read post when reopening a thread.', + 1 + ], + 'Unread Line in Index': [ + false, + 'Show a line between read and unread posts in threads in the index.', + 1 + ], + 'Remove Thread Excerpt': [ + false, + 'Replace the excerpt of the thread in the tab title with the board title.' + ], + 'Thread Stats': [ + true, + 'Display reply and image count.' + ], + 'IP Count in Stats': [ + true, + 'Display the unique IP count in the thread stats.', + 1 + ], + 'Page Count in Stats': [ + true, + 'Display the page count in the thread stats.', + 1 + ], + 'Updater and Stats in Header': [ + true, + 'Places the thread updater and thread stats in the header instead of floating them.' + ], + 'Thread Watcher': [ + true, + 'Bookmark threads. Has more options in the thread watcher menu.' + ], + 'Fixed Thread Watcher': [ + true, + 'Makes the thread watcher scroll with the page.', + 1 + ], + 'Persistent Thread Watcher': [ + false, + 'The thread watcher will be visible when the page is loaded.', + 1 + ], + 'Mark New IPs': [ + false, + 'Label each post from a new IP with the thread\'s current IP count.' + ], + 'Reply Pruning': [ + true, + 'Add option in header menu to hide old replies in long threads. Activated by default in stickies.' + ], + 'Prune All Threads': [ + false, + 'Activate Reply Pruning by default in all threads.', + 1 + ] + }, + + 'Posting and Captchas': { + 'Quick Reply': [ + true, + 'All-in-one form to reply, create threads, automate dumping and more.' + ], + 'Persistent QR': [ + false, + 'The Quick reply won\'t disappear after posting.', + 1 + ], + 'Auto Hide QR': [ + true, + 'Automatically hide the quick reply when posting.', + 2 + ], + 'Open Post in New Tab': [ + true, + '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': [ + false, + 'Remember the size of the Quick reply.', + 1 + ], + 'Remember Spoiler': [ + false, + 'Remember the spoiler state, instead of resetting after posting.', + 1 + ], + 'Randomize Filename': [ + false, + 'Set the filename to a random timestamp within the past year. Disabled on /f/.', + 1 + ], + 'Show New Thread Option in Threads': [ + true, + 'Show the option to post a new / different thread from inside a thread.', + 1 + ], + 'Show Upload Progress': [ + true, + 'Track progress of file uploads as percentage in submit button.', + 1 + ], + 'Cooldown': [ + true, + 'Indicate the remaining time before posting again.', + 1 + ], + 'Posting Success Notifications': [ + true, + 'Show notifications on successful post creation or file uploading.', + 1 + ], + 'Auto-load captcha': [ + false, + 'Automatically load the captcha in the QR even if your post is empty.', + 1 + ], + 'Post on Captcha Completion': [ + false, + 'Submit the post immediately when the captcha is completed.', + 1 + ], + 'Force Noscript Captcha': [ + false, + 'Use the non-Javascript fallback captcha even if Javascript is enabled.' + ], + 'Pass Link': [ + false, + 'Add a 4chan Pass login link to the bottom of the page.' + ] + }, + + 'Quote Links': { + 'Quote Backlinks': [ + true, + 'Add quote backlinks.' + ], + 'OP Backlinks': [ + true, + 'Add backlinks to the OP.', + 1 + ], + 'Bottom Backlinks': [ + false, + 'Place backlinks at the bottom of posts.', + 1 + ], + 'Quote Inlining': [ + true, + 'Inline quoted post on click.' + ], + 'Inline Cross-thread Quotes Only': [ + false, + 'Don\'t inline quote links when the posts are visible in the thread.', + 1 + ], + 'Quote Hash Navigation': [ + false, + 'Include an extra link after quotes for autoscrolling to quoted posts.', + 1 + ], + 'Forward Hiding': [ + true, + 'Hide original posts of inlined backlinks.', + 1 + ], + 'Quote Previewing': [ + true, + 'Show quoted post on hover.' + ], + 'Quote Highlighting': [ + true, + 'Highlight the previewed post.', + 1 + ], + 'Resurrect Quotes': [ + true, + 'Link dead quotes to the archives, and support inlining/previewing of archive links like quote links.' + ], + 'Remember Your Posts': [ + true, + 'Remember your posting history.' + ], + 'Mark Quotes of You': [ + true, + 'Add \'(You)\' to quotes linking to your posts.', + 1 + ], + 'Highlight Posts Quoting You': [ + true, + 'Highlights any posts that contain a quote to your post.', + 1 + ], + 'Highlight Own Posts': [ + true, + 'Highlights own posts.', + 1 + ], + 'Mark OP Quotes': [ + true, + 'Add \'(OP)\' to OP quotes.' + ], + 'Mark Cross-thread Quotes': [ + true, + 'Add \'(Cross-thread)\' to cross-threads quotes.' + ], + 'Quote Threading': [ + true, + 'Add option in header menu to thread conversations.' + ] + } + }, + + imageExpansion: { + 'Fit width': [ + true, + '' + ], + 'Fit height': [ + false, + '' + ], + 'Scroll into view': [ + true, + 'Scroll down when expanding images to bring the full image into view.' + ], + 'Expand spoilers': [ + true, + 'Expand all images along with spoilers.' + ], + 'Expand videos': [ + true, + 'Expand all images also expands videos.' + ], + 'Expand from here': [ + false, + 'Expand all images only from current position to thread end.' + ], + 'Expand thread only': [ + false, + 'In index, expand all images only within the current thread.' + ], + 'Advance on contract': [ + false, + 'Advance to next post when contracting an expanded image.' + ] + }, + + gallery: { + 'Hide Thumbnails': [ + false + ], + 'Fit Width': [ // 'Fit width' (lowercase W) belongs to Image Expansion. Engine limitations, heh. + true + ], + 'Fit Height': [ + true + ], + 'Stretch to Fit': [ + false + ], + 'Scroll to Post': [ + true + ], + 'Slide Delay': [ + 6.0 + ] + }, + + 'Default Volume': 1.0, + + threadWatcher: { + 'Current Board': [ + false, + 'Only show watched threads from the current board.' + ], + 'Auto Update Thread Watcher': [ + true, + 'Periodically check status of watched threads.' + ], + 'Auto Watch': [ + true, + 'Automatically watch threads you start.' + ], + 'Auto Watch Reply': [ + true, + 'Automatically watch threads you reply to.' + ], + 'Auto Prune': [ + false, + 'Automatically remove dead threads.' + ], + 'Show Page': [ + true, + 'Show what page watched threads are on.' + ], + 'Show Unread Count': [ + true, + 'Show number of unread posts in watched threads.' + ], + 'Show Site Prefix': [ + true, + 'When multiple sites are shown in the thread watcher, add a prefix to board names to distinguish them.' + ], + 'Require OP Quote Link': [ + false, + '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]: +#/(\\d)\\1$/;highlight;top:no;boards:s4s\ +`, + + name: `\ +# Filter any namefags: +#/^(?!Anonymous$)/\ +`, + + uniqueID: `\ +# Filter a specific ID: +#/Txhvk1Tl/\ +`, + + tripcode: `\ +# Filter any tripfag +#/^!/\ +`, + + capcode: `\ +# Set a custom class for mods: +#/Mod$/;highlight:mod;op:yes +# Set a custom class for admins: +#/Admin$/;highlight:admin;op:yes\ +`, + + pass: `\ +# Filter anyone using since4pass: +#/./\ +`, + + email: '', + + subject: `\ +# Filter Generals on /v/: +#/general/i;boards:v;op:only\ +`, + + comment: `\ +# Filter Stallman copypasta on /g/: +#/what you\'re refer+ing to as linux/i;boards:g +# Filter posts with 20 or more quote links: +#/(?:>>\\d(?:(?!>>\\d)[^])*){20}/ +# Filter posts like T H I S / H / I / S: +#/^>?\\s?\\w\\s?(\\w)\\s?(\\w)\\s?(\\w).*$[\\s>]+\\1[\\s>]+\\2[\\s>]+\\3/im\ +`, + + flag: '', + filename: '', + dimensions: `\ +# Highlight potential wallpapers: +#/1920x1080/;op:yes;highlight;top:no;boards:w,wg\ +`, + + filesize: '', + + MD5: '' + }, + + sauces: `\ +# Known filename formats: +https://www.pixiv.net/member_illust.php?mode=medium&illust_id=%$1;regexp:/^(\\d+)_p\\d+/ +javascript:void(open("https://www.deviantart.com/"+%$1.replace(/_/g,"-")+"/art/"+parseInt(%$2,36)));regexp:/^\\w+_by_(\\w+)[_-]d([\\da-z]{6})\\b/ +https://imgur.com/%$1;regexp:/^(?![a-zA-Z][a-z]{6})(?![A-Z]{7})(?!\\d{7})([\\da-zA-Z]{7})(?: \\(\\d+\\))?\\.\\w+$/ +https://flickr.com/photo.gne?id=%$1;regexp:/^(\\d+)_[\\da-f]{10}(?:_\\w)*\\b/ +https://www.facebook.com/photo.php?fbid=%$1;regexp:/^\\d+_(\\d+)_\\d+_[no]\\b/ + +# Reverse image search: +https://www.google.com/searchbyimage?sbisrc=4chanx&image_url=%IMG&safe=off +https://yandex.com/images/search?rpt=imageview&url=%IMG +#//tineye.com/search?url=%IMG +#//www.bing.com/images/search?q=imgurl:%IMG&view=detailv2&iss=sbi#enterInsights +#https://lens.google.com/uploadbyurl?url=%IMG;text:lens + +# Specialized reverse image search: +//iqdb.org/?url=%IMG +https://trace.moe/?auto&url=%IMG;text:wait +#//3d.iqdb.org/?url=%IMG +#//saucenao.com/search.php?url=%IMG + +# "View Same" in archives: +http://eye.swfchan.com/search/?q=%name;types:swf +#https://desuarchive.org/_/search/image/%sMD5/ +#https://archive.4plebs.org/_/search/image/%sMD5/ +#https://boards.fireden.net/_/search/image/%sMD5/ +#https://foolz.fireden.net/_/search/image/%sMD5/ + +# Other tools: +#http://exif.regex.info/exif.cgi?imgurl=%URL +#//imgops.com/start?url=%URL;types:gif,jpg,png +#//www.gif-explode.com/%URL;types:gif\ +`, + + FappeT: { + werk: false + }, + + 'Custom CSS': true, + + Index: { + 'Index Mode': 'paged', + 'Previous Index Mode': 'paged', + 'Index Size': 'small', + 'Show Replies': [true, 'Show replies in the index, and also in the catalog if "Catalog hover expand" is checked.'], + 'Catalog Hover Expand': [false, 'Expand the comment and show more details when you hover over a thread in the catalog.'], + 'Catalog Hover Toggle': [true, 'Turn "Catalog hover expand" on and off by clicking in the catalog.'], + 'Pin Watched Threads': [false, 'Move watched threads to the start of the index.'], + 'Anchor Hidden Threads': [true, 'Move hidden threads to the end of the index.'], + 'Refreshed Navigation': [false, 'Refresh index when navigating through pages.'] + }, + + Header: { + 'Fixed Header': true, + 'Header auto-hide': false, + 'Header auto-hide on scroll': false, + 'Bottom Header': false, + 'Centered links': false, + 'Header catalog links': false, + 'Bottom Board List': true, + 'Shortcut Icons': true, + 'Custom Board Navigation': true + }, + + archives: { + archiveLists: 'https://4chenz.github.io/archives.json/archives.json', + lastarchivecheck: 0, + archiveAutoUpdate: true + }, + + 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 ] +[current-index-text:"Index" +current-catalog-text:"Catalog" +current-expired-text:"Expired" +current-archive-text:"Archive"] +[external-text:"FAQ","${meta.name}"]\ +`, + + QR: { + 'QR.personas': `\ +#options:"sage";boards:jp;always\ +`, + sjisPreview: false + }, + + jsWhitelist: `\ +http://s.4cdn.org +https://s.4cdn.org +http://www.google.com +https://www.google.com +https://www.gstatic.com +http://cdn.mathjax.org +https://cdn.mathjax.org +https://cdnjs.cloudflare.com +https://hcaptcha.com +https://*.hcaptcha.com +'self' +'unsafe-inline' +'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: userCss, + + hotkeys: { + // QR & Options + '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.' + ], + // Thread related + '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").' + ], + // Images + '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.' + ], + // Board Navigation + '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.' + ], + // Thread Navigation + '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.' + ], + // Reply Navigation + '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': [ + false, + 'Beep on new post to completely read thread.' + ], + 'Beep Quoting You': [ + false, + 'Beep on new post quoting you.' + ], + 'Auto Scroll': [ + false, + 'Scroll updated posts into view. Only enabled at bottom of page.' + ], + 'Bottom Scroll': [ + false, + 'Always scroll to the bottom, not the first new post. Useful for event threads.' + ], + 'Scroll BG': [ + false, + 'Auto-scroll background tabs.' + ], + 'Auto Update': [ + true, + 'Automatically fetch new posts.' + ], + 'Optional Increase': [ + false, + 'Increase the intervals between updates on threads without new posts.' + ] + }, + 'Interval': 5 + }, + + customCooldown: 0, + customCooldownEnabled: true, + + 'Thread Quotes': false, + + 'Max Replies': 1000, + + 'Autohiding Scrollbar': false, + + 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: banners.join(','), + + passMessageClosed: false, + + 'Prerequest Captcha': false, + + 'PSAseen': [[]] + }; + + var QuickReplyPage = `

        + + × + +
        +
        +
        + + + + + +
        +
        + + +
        +
        +
        +
        + + +
        + +
        + + + No selected file + + + ✎︎ + + 🔗︎ + + 🕒︎ + + + + +
        + + +
        + + + +`; + + var ferongr_unreadDead = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///9zBQC/AADpDAP/gID/q6voCwJJTwpOAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC'; + + var ferongr_unreadDeadY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxUlEQVR42q1TOwrCQBB9s0FRtJI0WoqFtSLYegoP4gVSeJsUHsHSI3iFeIqRXXgwrhlXwYHHhLwPTB7B36abBCV+0pA4DUBQUNZYQptGtW3jtoKyxgoe0yrBCoyZfL/5ioQ3URZOXW9I341l3oo+NXEZiW4CEuIzvPECopED4OaZ3RNmeAm4u+a8Jr5f17VyVoL8fr8qcltzwlyyj2iqcgPOQ9ExkHAITgD75bYBe0A5S4H/P9htuWMF3QXoQpwaKeT+lnsC6JE5I6aq6fEAAAAASUVORK5CYII='; + + var ferongr_unreadSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///8AcH4AtswA2PJ55fKi6fIA1/FtpPADAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC'; + + var ferongr_unreadSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxElEQVQ4y2NgoBq4/vE/HJOsBiRQUIfA2AzBqQYqUfn00/9FLz+BaQxDCKqBmX7jExijKEDSDJPHrnnbGQhGV4RmOFwdVkNwhQMheYwQxhaIi7b9Z9A3gWAQm2BUoQOgRhgA8o7j1ozLC4LCyAZcx6kZI5qg4kLKqggDFFWxJySsUQVzlb4pwgAJaTRvokcVNgOqOv8zcHBCsL07DgNg8YsczzA5MxtUL+DMD8g0slxI/H8GQ/P/DJKyeKIRpglXZsIiBwBhP5O+VbI/JgAAAABJRU5ErkJggg=='; + + var ferongr_unreadNSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///8oeQBJ3ABV/wHM/7Lu/+ZU/gAqUP3dAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC'; + + var ferongr_unreadNSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAx0lEQVQ4y2NgoBYI+cfwH4ZJVgMS0KhEYGyG4FQDkzjzf9P/d/+fgWl0QwiqgSkI/c8IxsgKkDXD5LFq9rwDweiK0A2HqcNqCK5wICSPEcLYAtH+AMN/IXMIBrEJRie6OEgjDAC5x3FqxuUFNiEUA67j1IweTTBxBQ1puAG86jgSEraogskJWSBcwCGF5k30qMJmgMFEhv/MXBAs5oLDAFj8IsczTE7UEeECbhU8+QGZRpaTi2b4L2zF8J9TGk80wjThykzY5AAW/2O1C2mIbgAAAABJRU5ErkJggg=='; + + var xat_unreadDead = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAG1BMVEX+AACLkZFub2yfaF3zZGIAAAD/AAD/iYr/zs8IPcF6AAAABXRSTlMAeprJ7xzg6IEAAABZSURBVAjXY2DABKGBSkqioQwMrGmpxsZhaQEMDGFpIa5pqSCRtPDSNJBIaGh5eShQDYOye0V7iREKAyQFYoiCFAcyILQDGcGmEEZYkGoqiMHKysAQEICwGwAAjBmBqhYlagAAAABJRU5ErkJggg=='; + + var xat_unreadDeadY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAPFBMVEUAAACEgoBva2ilamDxcG7IaWYgFBNOSEf//f0PDQwBAAA7LCwAAAD/AAD+hIX+m5z+zc5HAADPAAAGAADl032uAAAADHRSTlMAzNv0/vz+6v3+7ALrmfyXAAAAaUlEQVQY042PyxKAIAhFAc1eV7T6/3/N8VXOtAgWwBm4ANEPA8AswpySXHvvYZLlpBNrh9pDtcSqAQ1BUTVIjNUQY5icmwfglmXNgE0d6QBF9GigrU0A9LoM53U1kFzk6SBQuWfD/vHqDUCpBmVKTTM4AAAAAElFTkSuQmCC'; + + var xat_unreadSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIVBMVEUAAACRjop4dXVpZ2tdcI9dfKdisfMAAAAumMN9xv+s2/+PADT2AAAAB3RSTlMAepGdv83v3HIc4QAAAFxJREFUCNdjYMAE5YXKRuLlDAzsHe2uIRUdBQwMFR1l6R3tIJGOyukdIJHy8lkry4FqGEwzV62aFozMUAFJOQEZ4iDFhQwI7UBGaTiEUVFs3g5isLMzMBQUIOwGAJRlIu9hk08QAAAAAElFTkSuQmCC'; + + var xat_unreadSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEUAAACAgYVlc4ljsu4AAAAAAAAAAAAumMODyP6b1P6e1f/g8v89msgSIiwNFxwbPU3tQYj5AAAABnRSTlMAxej+9VTmD9ciAAAAZElEQVQI12NgwARpiUKKYmkMDGzlZUpK6eUJDAzp5clm5WUgkfKMtnKQSFpa54o0oBoGJYvZO88+gjJu7wMyhIBS2SCGGFDxaxADpP32NjAjSe0bSFd6epIaWISNjYEhJRVhNwAGlyJpYtcvcAAAAABJRU5ErkJggg=='; + + var xat_unreadNSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAHlBMVEUfJSCRi5Frbm9dn19082KR/30AAABmzDOq/5vZ/9Gt/vt2AAAABnRSTlMAe5rJ7/4vxEp4AAAAWUlEQVQI12NgwARpiUpKYmkMDGzlZcbG6eUJDAzp5Slu5WUgkfLUsHKQSFpaRGsaUA2DsmvnjBAjFAZICsQQAylOZEBoBzKSzSCM9CS1MhCDjY2BISEBYTcAtgAcKSK2vuIAAAAASUVORK5CYII='; + + var xat_unreadNSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAM1BMVEUAAACBj39tfm1qj2RepFlu2VQAAQAAAAAAAABmyzOX/oSr/pus/pzk/98PGgtatC4CBAI1ENblAAAACHRSTlMA09/p9v77ig0SBcQAAABnSURBVBjTjY9LDsAgCEQRsR2xWu9/2hK/adJFYQG8wABEPwyAYzNnSatjjPAiviWLhPCqI1R7HBrQdCmGBrEETTmnUAq/QMm5dODHyAQOXXR1zLUGsIEI7lonMGfeHQTq9xw4P159AIxSBSC53km7AAAAAElFTkSuQmCC'; + + var Mayhem_unreadDead = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABFklEQVR4AZ2R4WqEMBCEFy1yiJQQ14gcIhIuFBFR+qPQ93+v66QMksrlTwMfkZ2ZZbMKTgVqYIDl3YAbeCM31lJP/Zul4MAEPJjBQGNDLGsz8PQ6aqLAP5PTdd1WlmU09mSKtdTDRgrkzspJPKq6RxMahfj9yhOzQEZwZAwfzrk1ox3MXibIN8hO4MAjeV72CemJGWblnRsOYOdoGw0jebB20BPAwKzUQPlrFhrXFw1Wagu9yuzZwINzVAZCURRL+gRr7Wd8Vtqg4Th/lsUmewyk9WQ/A7NiwJz5VV/GmO+MNjMrFvh/NPDMigHTaeJN09a27ZHRJmalBg54CgfvAGYSLpoHjlmpuAwFdzDy7oGS/qIpM9UPFGg1b1kUlssAAAAASUVORK5CYII='; + + var Mayhem_unreadDeadY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABR0lEQVR4AYWSQWq0QBCFCw0SRIK0PQ4hiIhEZBhEySLyewUPEMgqR/JIXiDhzz7kKKYePIZajEzDRxfV9dWU3SO6IiVWUsVxT5R75Y4gTmwNnUh4kCulUiuV8sjChDjmKtaUcHgmHsnNrMPh0IVhiMIjKZGzNXDoyhMzF7C89z2KtFGD+FoNXEUKZdgpaPM8P++cDXTtBDca7EyQK8+bXTufYBccuvLAG26UnqN1LCgI4g/lm7zTgSux4vk0J8rnKw3+m1//pBPbBrVyGZVNmiAITviEtm3t+D+2QcJx7GUxlN4594K4ZY75Xzh0JVWqnad6TdP0H+LRNBjHcYNDV5xS32qwaC4my7Lwn6guu5QoomgbdFmWDYhnM8E8zxscuhLzPWtKA/dGqUizrityX9M0YX+DQ1ciXobnP6vgfmTOM7Znnk70B58pPaEvx+epAAAAAElFTkSuQmCC'; + + var Mayhem_unreadSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/ElEQVR4AZ3RUWqEMBSF4ftQZAhSREQJIiIXpQwi+tSldkFdWPsLhyEE0ocKH2Fyzg1mNJ4KAQ1arTUeeJMH6qwTUJmCHjMcC6KKtbSIylzdXpl18J/k4fdTpUFmPLOOa9bGe+P4+n5RYYfLXuiMsAlXofBxK2QXpvwN/jqg+AY91vR+pStk+apZe0fEhhMXDhUmWXEoO9WNmrWAzvRPq7jnB2jvUGfWTEgPcJzZFTbZk/0Tnh5QI+af6lVGvq/Do2atwVL4VJ+3QrZo1lr4Pw5wzVqDWaV7SUvHrZDNmrWAHq7g0rphkS3LXDMBVqFGhxGT1gGdDFnWaab6BRmXRvbxDmYiAAAAAElFTkSuQmCC'; + + var Mayhem_unreadSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4AY2SQUrEQBBFS9CMNFEkhAQdYmiCIUgcZlYGc4VsBcGVF/AuWXme4F7RtXiVWF9+Y9MYtOHRTdX/NZWaEj2RYpQTJeEdK4fKPuA7DjSGXiQkU0qlUqxySmFMEsYsNSU8zEmK4OwdEbmkKCclYoGmolfWCGyenh1O0EJE2gXNWpFC2S0IGrCQ29EbdPCPAmEHmXIxByf8hDAPD71yzAnXypatbSgoAN8Pyju5h4deMUrqJk1z+0uBN+/XX+gxfoFK2QafUJO2aRq//Q+/QIx2wr+Kwq0rusrP/QKf9MTCtbQLf9U1wNvYnz3qug45S68kSvVXgbPbx3nvYPXNOI7cRPWySukK+DcGCvA+urqZ3RmGAbmSXjFK5rpwW8nhWVJP04TYa9/3uO/goVciDiPlZhW8c8ZAHuRSeqIv32FK/GYGL8YAAAAASUVORK5CYII='; + + var Mayhem_unreadNSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/ElEQVR4AZ3RUWqEMBSF4ftQZAihDCKKiAQJShERQx+6o662e2p/4TCEQF468BEm95yLovFr4PBEq9PjgTd5wBcZp6559AiIWDAq6KXV3aJMUMfDOsTf7Mf/XaFBAvYiE9W16b74/vl8UeBAlKOSmWAzUiXwcavMkrrFE9QXVJ+gx5q9XvUVivmqrr1jxIYLCacCs6y6S8psGNU1hw4Bu4JHuUB3pzJBHZcviLiKV9jkyO4vxHyBx1h+qlcY5b2Wj+raE0vlU33dKrNFXWsR/7EgqmtPBIXuIw+dt8osqGsOPaIGSeeGRbZiFtVxsAYeHSbMOgd0MhSzTp3mD4RaQX4aW3NMAAAAAElFTkSuQmCC'; + + var Mayhem_unreadNSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABP0lEQVR4AYWS0UqFQBCGhziImNRBRImDmUgiIaF0kWSP4AMEXXXTE/QiPpL3UdR19Crb/PAvLEtyFj5mmfn/cdxd0RUokbJXEsZYCZUd4D72NBG8wkKmlEqtVMoFhTFJmKuoKelBTVIkjbNE5IainJTIeZqaXjkg8fp+Z7GCjiLQbWgOihTKsCFowUZtoNef4HgDf4JMuTbe8n/Br8NDr5zxhBul52i3FBQE+xflmzzTA69ESmpPmubunwZfztc/6IncBrXSe7/QkK5tW3f8H7dBjHH8q6Kwt033V6Hb4JeeWPgsq42rugfYZ92psWscRwMPvZIo9bEGD2+F2YUnBizLwpeoXnYpbQM34kAB9peP58aueZ4NPPRKxPusaRoYG6UizbquyH1O04T4RA+8EvAwUr6sgjFnDuReLaUn+ANygUa7+9SCWgAAAABJRU5ErkJggg=='; + + var fourChanJS_unreadDead = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAD/AABnZ2f///8nFk05AAAAAXRSTlMAQObYZgAAAEFJREFUeNqNjgEKACAMAjvX/98cAkkxgmSgO8Bt/Ai4ApJ6KKhzF3OiEMDASrGB/QWgPEHsUpN+Ng9xAETMYhDrWmeHAMcmvycWAAAAAElFTkSuQmCC'; + + var fourChanJS_unreadDeadY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAD1BMVEUAAAAAAAD/AABmZmYA/wBD99DBAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAE9JREFUCNdljcsRACEIQ5MOiNKAdGAJ9N/Uiu7nsMzABHgB4B8ygFoZA2hhVWavhhGeURPJU9q45+17hGbfGxa82Ndex3hEM44SJGD2/b4AzDgGlHbl388AAAAASUVORK5CYII='; + + var fourChanJS_unreadSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAAul8NnZ2f////82iC9AAAAAXRSTlMAQObYZgAAAEFJREFUeNqNjgEKACAMAjvX/98cAkkxgmSgO8Bt/Ai4ApJ6KKhzF3OiEMDASrGB/QWgPEHsUpN+Ng9xAETMYhDrWmeHAMcmvycWAAAAAElFTkSuQmCC'; + + var fourChanJS_unreadSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAD1BMVEUAAAAAAAAul8NnZ2f/AAD7B+mqAAAAAXRSTlMAQObYZgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAE9JREFUCNdljcsRACEIQ5MOiNKAdGAJ9N/Uiu7nsMzABHgB4B8ygFoZA2hhVWavhhGeURPJU9q45+17hGbfGxa82Ndex3hEM44SJGD2/b4AzDgGlHbl388AAAAASUVORK5CYII='; + + var fourChanJS_unreadNSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAElBMVEUBAAAAAABmzDNlyjJnZ2f///+6o7dfAAAAAXRSTlMAQObYZgAAAERJREFUeF6NjkEKADEIA51o///lJZfQxUsHITogWi8AvwZJuxmYa25xDooBLEwOWFTYAsYVhdorLZt9Ng9xCUTCUCQ2H3F4ANrZ2WNiAAAAAElFTkSuQmCC'; + + var fourChanJS_unreadNSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAD1BMVEUAAAAAAABmzDNmZmb/AAC8/wCMAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAE9JREFUCNdljcsRACEIQ5MOiNKAdGAJ9N/Uiu7nsMzABHgB4B8ygFoZA2hhVWavhhGeURPJU9q45+17hGbfGxa82Ndex3hEM44SJGD2/b4AzDgGlHbl388AAAAASUVORK5CYII='; + + var Original_unreadDead = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX/////AAD///8AAABBZmS3AAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII='; + + var Original_unreadDeadY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhElEQVR42q1RwQnAMAjMu5M4guAKXa4j5dUROo5tipSDcrFChUONd0di2m/hEGVOHDyIPufgwAFASDkpoSzmBrkJ2UMyR9LsJ3rvrqo3Rt1YMIMhhNnOxLMnoMFBxHyJAr2IOBFzA8U+6pLBdmEJTA0aMVjpDd6Loks0s5HZNwYx8tfZCZ0kll7ORffZAAAAAElFTkSuQmCC'; + + var Original_unreadSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX///8ul8P///8AAACaqgkzAAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII='; + + var Original_unreadSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAABBQcHFx4KISoNLToaVW4oKCgul8M4ODg7OzvBwcH///8uS/CdAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eILZO5/XI0UAgm7H9tOsu0yGWAQSOoFijHOxOANGqm/LczpOaXs4gISrPZ+gc2+hO5w2xdwgOjBFUIF+sEJrhUl9JFr+badFwR+BfqlmGUJAAAAAElFTkSuQmCC'; + + var Original_unreadNSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX///9mzDP///8AAACT0n1lAAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII='; + + var Original_unreadNSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAAECAIQIAgWLAsePA8oKCg4ODg6dB07OztmzDPBwcH///+rsf3XAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eIDhbn/cTVSCCTsfmw7ybbLZIBBIKkXKKU0E4M3aKT+tjCn5xiziwuIsNr7BTb7ErrDZV/AAaIHdwgV6AcnuFaU0Eeu5dt2XiUyBjCQ2bIrAAAAAElFTkSuQmCC'; + + var Metro_unreadDead = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAC/AABrZQDiAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg=='; + + var Metro_unreadDeadY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAC/AAD///8dAAApAABsAAAHAAA4AACQAAAsAABMCpCvAAAAA3RSTlMAPse+s4iwAAAAMklEQVQI12NggAFmY2MDECaNAQZCilAzVJyg5oS4GqAxUtygjIp2KGOKJ5SxepcB3BUAcdYRqxAtgFoAAAAASUVORK5CYII='; + + var Metro_unreadSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAAA1/GhpCidAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg=='; + + var Metro_unreadSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAAA1/H///8AISUALzQAeokACAkAQEcAorYAMTcE9WFNAAAAA3RSTlMAPse+s4iwAAAAMklEQVQI12NggAFmY2MDECaNAQZCilAzVJyg5oS4GqAxUtygjIp2KGOKJ5SxepcB3BUAcdYRqxAtgFoAAAAASUVORK5CYII='; + + var Metro_unreadNSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAABV/wErM5hwAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg=='; + + var Metro_unreadNSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAABV/wH///8NKAASOAAwkQADCgAZTABAwQATOwC5e3VGAAAAA3RSTlMAPse+s4iwAAAAMklEQVQI12NggAFmY2MDECaNAQZCilAzVJyg5oS4GqAxUtygjIp2KGOKJ5SxepcB3BUAcdYRqxAtgFoAAAAASUVORK5CYII='; + + var dead = 'R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw=='; + + var empty = 'R0lGODlhEAAQAJEAAAAAAP///9vb2////yH5BAEAAAMALAAAAAAQABAAAAIvnI+pq+D9DBAUoFkPFnbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw=='; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var Favicon = { + init() { + return $$1.asap((() => d$1.head && (Favicon.el = $$1('link[rel="shortcut icon"]', d$1.head))), Favicon.initAsap); + }, + + set(status) { + Favicon.status = status; + if (Favicon.el) { + Favicon.el.href = Favicon[status]; + // `favicon.href = href` doesn't work on Firefox. + return $$1.add(d$1.head, Favicon.el); + } + }, + + initAsap() { + Favicon.el.type = 'image/x-icon'; + const {href} = Favicon.el; + Favicon.isSFW = /ws\.ico$/.test(href); + Favicon.default = href; + Favicon.switch(); + if (Favicon.status) { + return Favicon.set(Favicon.status); + } + }, + + switch() { + let items = { + ferongr: [ + ferongr_unreadDead, + ferongr_unreadDeadY, + ferongr_unreadSFW, + ferongr_unreadSFWY, + ferongr_unreadNSFW, + ferongr_unreadNSFWY, + ], + 'xat-': [ + xat_unreadDead, + xat_unreadDeadY, + xat_unreadSFW, + xat_unreadSFWY, + xat_unreadNSFW, + xat_unreadNSFWY, + ], + Mayhem: [ + Mayhem_unreadDead, + Mayhem_unreadDeadY, + Mayhem_unreadSFW, + Mayhem_unreadSFWY, + Mayhem_unreadNSFW, + Mayhem_unreadNSFWY, + ], + '4chanJS': [ + fourChanJS_unreadDead, + fourChanJS_unreadDeadY, + fourChanJS_unreadSFW, + fourChanJS_unreadSFWY, + fourChanJS_unreadNSFW, + fourChanJS_unreadNSFWY, + ], + Original: [ + Original_unreadDead, + Original_unreadDeadY, + Original_unreadSFW, + Original_unreadSFWY, + Original_unreadNSFW, + Original_unreadNSFWY, + ], + 'Metro': [ + Metro_unreadDead, + Metro_unreadDeadY, + Metro_unreadSFW, + Metro_unreadSFWY, + Metro_unreadNSFW, + Metro_unreadNSFWY, + ] + }; + items = $$1.getOwn(items, Conf['favicon']); + + const f = Favicon; + const t = 'data:image/png;base64,'; + let i = 0; + while (items[i]) { + items[i] = t + items[i++]; + } + + [f.unreadDead, f.unreadDeadY, f.unreadSFW, f.unreadSFWY, f.unreadNSFW, f.unreadNSFWY] = Array.from(items); + return f.update(); + }, + + update() { + if (this.isSFW) { + this.unread = this.unreadSFW; + return this.unreadY = this.unreadSFWY; + } else { + this.unread = this.unreadNSFW; + return this.unreadY = this.unreadNSFWY; + } + }, + + SFW: '//s.4cdn.org/image/favicon-ws.ico', + NSFW: '//s.4cdn.org/image/favicon.ico', + dead: `data:image/gif;base64,${dead}`, + logo: `data:image/png;base64,${empty}`, + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const $$ = (selector, root = d$1.body) => [...Array.from(root.querySelectorAll(selector))]; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const CaptchaReplace = { + init() { + if ((g.SITE.software !== 'yotsuba') || (d$1.cookie.indexOf('pass_enabled=1') >= 0)) { return; } + + if (Conf['Force Noscript Captcha'] && Main$1.jsEnabled) { + $$1.ready(Captcha.replace.noscript); + return; + } + + if (Conf['captchaLanguage'].trim()) { + if (['boards.4chan.org', 'boards.4channel.org'].includes(location.hostname)) { + return $$1.onExists(doc$1, '#captchaFormPart', node => $$1.onExists(node, 'iframe[src^="https://www.google.com/recaptcha/"]', Captcha.replace.iframe)); + } else { + return $$1.onExists(doc$1, 'iframe[src^="https://www.google.com/recaptcha/"]', Captcha.replace.iframe); + } + } + }, + + noscript() { + let noscript, original, toggle; + if (!((original = $$1('#g-recaptcha')) && (noscript = $$1('noscript', original.parentNode)))) { return; } + const span = $$1.el('span', + {id: 'captcha-forced-noscript'}); + $$1.replace(noscript, span); + $$1.rm(original); + const insert = function() { + span.innerHTML = noscript.textContent; + return Captcha.replace.iframe($$1('iframe[src^="https://www.google.com/recaptcha/"]', span)); + }; + if (toggle = $$1('#togglePostFormLink a, #form-link')) { + return $$1.on(toggle, 'click', insert); + } else { + return insert(); + } + }, + + iframe(iframe) { + let lang; + if (lang = Conf['captchaLanguage'].trim()) { + const src = /[?&]hl=/.test(iframe.src) ? + iframe.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang)) + : + iframe.src + `&hl=${encodeURIComponent(lang)}`; + if (iframe.src !== src) { iframe.src = src; } + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const CaptchaT = { + init() { + if (d$1.cookie.indexOf('pass_enabled=1') >= 0) { return; } + if (!(this.isEnabled = !!$$1('#t-root') || !$$1.id('postForm'))) { return; } + + const root = $$1.el('div', {className: 'captcha-root'}); + this.nodes = {root}; + + $$1.addClass(QR.nodes.el, 'has-captcha', 'captcha-t'); + return $$1.after(QR.nodes.com.parentNode, root); + }, + + moreNeeded() { + }, + + getThread() { + let threadID; + const boardID = g.BOARD.ID; + if (QR.posts[0].thread === 'new') { + threadID = '0'; + } else { + threadID = '' + QR.posts[0].thread; + } + return {boardID, threadID}; + }, + + setup(focus) { + if (!this.isEnabled) { return; } + + if (!this.nodes.container) { + this.nodes.container = $$1.el('div', {className: 'captcha-container'}); + $$1.prepend(this.nodes.root, this.nodes.container); + CaptchaT.currentThread = CaptchaT.getThread(); + $$1.global(function() { + const el = document.querySelector('#qr .captcha-container'); + window.TCaptcha.init(el, this.boardID, +this.threadID); + return window.TCaptcha.setErrorCb(err => window.dispatchEvent(new CustomEvent('CreateNotification', {detail: { + type: 'warning', + content: '' + err + }}) + )); + } + , CaptchaT.currentThread); + } + + if (focus) { + return $$1('#t-resp').focus(); + } + }, + + destroy() { + if (!this.isEnabled || !this.nodes.container) { return; } + $$1.global(() => window.TCaptcha.destroy()); + $$1.rm(this.nodes.container); + return delete this.nodes.container; + }, + + updateThread() { + if (!this.isEnabled) { return; } + const {boardID, threadID} = (CaptchaT.currentThread || {}); + const newThread = CaptchaT.getThread(); + if ((newThread.boardID !== boardID) || (newThread.threadID !== threadID)) { + CaptchaT.destroy(); + return CaptchaT.setup(); + } + }, + + getOne() { + let el; + let response = {}; + if (this.nodes.container) { + for (var key of ['t-response', 't-challenge']) { + response[key] = $$1(`[name='${key}']`, this.nodes.container).value; + } + } + if (!response['t-response'] && !((el = $$1('#t-msg')) && /Verification not required/i.test(el.textContent))) { + response = null; + } + return response; + }, + + setUsed() { + if (!this.isEnabled) { return; } + if (this.nodes.container) { + return $$1.global(() => window.TCaptcha.clearChallenge()); + } + }, + + occupied() { + return !!this.nodes.container; + } + }; + + // This file was created because these functions on $ were sometimes not initialized yet because of circular + // dependencies, so try to keep this file without dependencies, so these functions don't have to wait for something else + const debounce = (wait, fn) => { + let lastCall = 0; + let timeout = null; + let that = null; + let args = null; + const exec = function () { + lastCall = Date.now(); + return fn.apply(that, args); + }; + return function () { + args = arguments; + that = this; + if (lastCall < (Date.now() - wait)) { + return exec(); + } + // stop current reset + clearTimeout(timeout); + // after wait, let next invocation execute immediately + return timeout = setTimeout(exec, wait); + }; + }; + const dict = () => Object.create(null); + dict.clone = function (obj) { + if ((typeof obj !== 'object') || (obj === null)) { + return obj; + } + else if (obj instanceof Array) { + const arr = []; + for (let i = 0, end = obj.length; i < end; i++) { + arr.push(dict.clone(obj[i])); + } + return arr; + } + else { + const map = Object.create(null); + for (var key in obj) { + var val = obj[key]; + map[key] = dict.clone(val); + } + return map; + } + }; + dict.json = (str) => dict.clone(JSON.parse(str)); + const SECOND = 1000; + const MINUTE = SECOND * 60; + const HOUR = MINUTE * 60; + const DAY = HOUR * 24; + const platform = window.GM_xmlhttpRequest ? 'userscript' : 'crx'; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS104: Avoid inline assignments + * DS206: Consider reworking classes to avoid initClass + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class DataBoard { + static initClass() { + this.keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads', 'watcherLastModified', 'customTitles']; + + this.changes = []; + } + + constructor(key, sync, dontClean) { + this.onSync = this.onSync.bind(this); + this.key = key; + this.initData(Conf[this.key]); + $$1.sync(this.key, this.onSync); + if (!dontClean) { this.clean(); } + if (!sync) { return; } + // Chrome also fires the onChanged callback on the current tab, + // so we only start syncing when we're ready. + var init = () => { + $$1.off(d$1, '4chanXInitFinished', init); + return this.sync = sync; + }; + $$1.on(d$1, '4chanXInitFinished', init); + } + + initData(data) { + let boards; + this.data = data; + if (this.data.boards) { + let lastChecked; + ({boards, lastChecked} = this.data); + this.data['4chan.org'] = {boards, lastChecked}; + delete this.data.boards; + delete this.data.lastChecked; + } + return this.data[g.SITE.ID] || (this.data[g.SITE.ID] = { boards: dict() }); + } + + save(change, cb) { + change(); + DataBoard.changes.push(change); + return $$1.get(this.key, { boards: dict() }, items => { + if (!DataBoard.changes.length) { return; } + const needSync = ((items[this.key].version || 0) > (this.data.version || 0)); + if (needSync) { + this.initData(items[this.key]); + for (change of DataBoard.changes) { change(); } + } + DataBoard.changes = []; + this.data.version = (this.data.version || 0) + 1; + return $$1.set(this.key, this.data, () => { + if (needSync) { this.sync?.(); } + return cb?.(); + }); + }); + } + + forceSync(cb) { + return $$1.get(this.key, { boards: dict() }, items => { + if ((items[this.key].version || 0) > (this.data.version || 0)) { + this.initData(items[this.key]); + for (var change of DataBoard.changes) { change(); } + this.sync?.(); + } + return cb?.(); + }); + } + + delete({siteID, boardID, threadID, postID}, cb) { + if (!siteID) { siteID = g.SITE.ID; } + if (!this.data[siteID]) { return; } + return this.save(() => { + if (postID) { + if (!this.data[siteID].boards[boardID]?.[threadID]) { return; } + delete this.data[siteID].boards[boardID][threadID][postID]; + return this.deleteIfEmpty({siteID, boardID, threadID}); + } else if (threadID) { + if (!this.data[siteID].boards[boardID]) { return; } + delete this.data[siteID].boards[boardID][threadID]; + return this.deleteIfEmpty({siteID, boardID}); + } else { + return delete this.data[siteID].boards[boardID]; + } + } + , cb); + } + + deleteIfEmpty({siteID, boardID, threadID}) { + if (!this.data[siteID]) { return; } + if (threadID) { + if (!Object.keys(this.data[siteID].boards[boardID][threadID]).length) { + delete this.data[siteID].boards[boardID][threadID]; + return this.deleteIfEmpty({siteID, boardID}); + } + } else if (!Object.keys(this.data[siteID].boards[boardID]).length) { + return delete this.data[siteID].boards[boardID]; + } + } + + set(data, cb) { + return this.save(() => { + return this.setUnsafe(data); + } + , cb); + } + + setUnsafe({siteID, boardID, threadID, postID, val}) { + if (!siteID) { siteID = g.SITE.ID; } + if (!this.data[siteID]) { this.data[siteID] = { boards: dict() }; } + if (postID !== undefined) { + let base; + return (((base = this.data[siteID].boards[boardID] || (this.data[siteID].boards[boardID] = dict())))[threadID] || (base[threadID] = dict()))[postID] = val; + } else if (threadID !== undefined) { + return (this.data[siteID].boards[boardID] || (this.data[siteID].boards[boardID] = dict()))[threadID] = val; + } else { + return this.data[siteID].boards[boardID] = val; + } + } + + extend({siteID, boardID, threadID, postID, val}, cb) { + return this.save(() => { + const oldVal = this.get({ siteID, boardID, threadID, postID, defaultValue: dict() }); + for (var key in val) { + var subVal = val[key]; + if (typeof subVal === 'undefined') { + delete oldVal[key]; + } else { + oldVal[key] = subVal; + } + } + return this.setUnsafe({siteID, boardID, threadID, postID, val: oldVal}); + } + , cb); + } + + setLastChecked(key='lastChecked') { + return this.save(() => { + return this.data[key] = Date.now(); + }); + } + + get({siteID, boardID, threadID, postID, defaultValue}) { + let board, val; + if (!siteID) { siteID = g.SITE.ID; } + if (board = this.data[siteID]?.boards[boardID]) { + let thread; + if (threadID == null) { + if (postID != null) { + for (thread = 0; thread < board.length; thread++) { + board[thread]; + if (postID in thread) { + val = thread[postID]; + break; + } + } + } else { + val = board; + } + } else if (thread = board[threadID]) { + val = (postID != null) ? + thread[postID] + : + thread; + } + } + return val || defaultValue; + } + + clean() { + let boardID, middle; + const siteID = g.SITE.ID; + for (boardID in this.data[siteID].boards) { + this.data[siteID].boards[boardID]; + this.deleteIfEmpty({siteID, boardID}); + } + const now = Date.now(); + if (now - (2 * HOUR) >= ((middle = this.data[siteID].lastChecked || 0)) || middle > now) { + this.data[siteID].lastChecked = now; + for (boardID in this.data[siteID].boards) { + this.ajaxClean(boardID); + } + } + } + + ajaxClean(boardID) { + const that = this; + const siteID = g.SITE.ID; + const threadsList = g.SITE.urls.threadsListJSON?.({siteID, boardID}); + if (!threadsList) { return; } + return $$1.cache(threadsList, function() { + if (this.status !== 200) { return; } + const archiveList = g.SITE.urls.archiveListJSON?.({siteID, boardID}); + if (!archiveList) { return that.ajaxCleanParse(boardID, this.response); } + const response1 = this.response; + return $$1.cache(archiveList, function() { + if ((this.status !== 200) && (!!g.SITE.archivedBoardsKnown || (this.status !== 404))) { return; } + return that.ajaxCleanParse(boardID, response1, this.response); + }); + }); + } + + ajaxCleanParse(boardID, response1, response2) { + let board, ID; + const siteID = g.SITE.ID; + if (!(board = this.data[siteID].boards[boardID])) { return; } + const threads = dict(); + if (response1) { + for (var page of response1) { + for (var thread of page.threads) { + ID = thread.no; + if (ID in board) { threads[ID] = board[ID]; } + } + } + } + if (response2) { + for (ID of response2) { + if (ID in board) { threads[ID] = board[ID]; } + } + } + this.data[siteID].boards[boardID] = threads; + this.deleteIfEmpty({siteID, boardID}); + return $$1.set(this.key, this.data); + } + + onSync(data) { + if ((data.version || 0) <= (this.data.version || 0)) { return; } + this.initData(data); + return this.sync?.(); + } + } + DataBoard.initClass(); + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class SimpleDict { + constructor() { + this.keys = []; + } + push(key, data) { + key = `${key}`; + if (!this[key]) { + this.keys.push(key); + } + return this[key] = data; + } + rm(key) { + let i; + key = `${key}`; + if ((i = this.keys.indexOf(key)) !== -1) { + this.keys.splice(i, 1); + return delete this[key]; + } + } + forEach(fn) { + for (var key of [...Array.from(this.keys)]) { + fn(this[key]); + } + } + get(key) { + if (key === 'keys') { + return undefined; + } + else { + return $$1.getOwn(this, key); + } + } + } + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class Thread { + toString() { return this.ID; } + + constructor(ID, board) { + this.board = board; + this.ID = +ID; + this.threadID = this.ID; + this.boardID = this.board.ID; + this.siteID = g.SITE.ID; + this.fullID = `${this.board}.${this.ID}`; + this.posts = new SimpleDict(); + this.isDead = false; + this.isHidden = false; + this.isSticky = false; + this.isClosed = false; + this.isArchived = false; + this.postLimit = false; + this.fileLimit = false; + this.lastPost = 0; + this.ipCount = undefined; + this.json = null; + + this.OP = null; + this.catalogView = null; + + this.nodes = + {root: null}; + + this.board.threads.push(this.ID, this); + g.threads.push(this.fullID, this); + } + + setPage(pageNum) { + let icon; + const {info, reply} = this.OP.nodes; + if (!(icon = $$1('.page-num', info))) { + icon = $$1.el('span', {className: 'page-num'}); + $$1.replace(reply.parentNode.previousSibling, [$$1.tn(' '), icon, $$1.tn(' ')]); + } + icon.title = `This thread is on page ${pageNum} in the original index.`; + icon.textContent = `[${pageNum}]`; + if (this.catalogView) { return this.catalogView.nodes.pageCount.textContent = pageNum; } + } + + setCount(type, count, reachedLimit) { + if (!this.catalogView) { return; } + const el = this.catalogView.nodes[`${type}Count`]; + el.textContent = count; + return (reachedLimit ? $$1.addClass : $$1.rmClass)(el, 'warning'); + } + + setStatus(type, status) { + const name = `is${type}`; + if (this[name] === status) { return; } + this[name] = status; + if (!this.OP) { return; } + this.setIcon('Sticky', this.isSticky); + this.setIcon('Closed', this.isClosed && !this.isArchived); + return this.setIcon('Archived', this.isArchived); + } + + setIcon(type, status) { + const typeLC = type.toLowerCase(); + let icon = $$1(`.${typeLC}Icon`, this.OP.nodes.info); + if (!!icon === status) { return; } + + if (!status) { + $$1.rm(icon.previousSibling); + $$1.rm(icon); + if (this.catalogView) { $$1.rm($$1(`.${typeLC}Icon`, this.catalogView.nodes.icons)); } + return; + } + icon = $$1.el('img', { + src: `${g.SITE.Build.staticPath}${typeLC}${g.SITE.Build.gifIcon}`, + alt: type, + title: type, + className: `${typeLC}Icon retina` + } + ); + if (g.BOARD.ID === 'f') { + icon.style.cssText = 'height: 18px; width: 18px;'; + } + + const root = (type !== 'Sticky') && this.isSticky ? + $$1('.stickyIcon', this.OP.nodes.info) + : + $$1('.page-num', this.OP.nodes.info) || this.OP.nodes.quote; + $$1.after(root, [$$1.tn(' '), icon]); + + if (!this.catalogView) { return; } + return ((type === 'Sticky') && this.isClosed ? $$1.prepend : $$1.add)(this.catalogView.nodes.icons, icon.cloneNode()); + } + + kill() { + return this.isDead = true; + } + + collect() { + let n = 0; + this.posts.forEach(function(post) { + if (post.clones.length) { + return n++; + } else { + return post.collect(); + } + }); + if (!n) { + g.threads.rm(this.fullID); + return this.board.threads.rm(this); + } + } + } + + class CatalogThread { + toString() { return this.ID; } + + constructor(root, thread) { + this.thread = thread; + this.ID = this.thread.ID; + this.board = this.thread.board; + const {post} = this.thread.OP.nodes; + this.nodes = { + root, + thumb: $$1('.catalog-thumb', post), + icons: $$1('.catalog-icons', post), + postCount: $$1('.post-count', post), + fileCount: $$1('.file-count', post), + pageCount: $$1('.page-count', post), + replies: null + }; + this.thread.catalogView = this; + } + } + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS206: Consider reworking classes to avoid initClass + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const dialog = function(id, properties) { + const el = $$1.el('div', { + className: 'dialog', + id + } + ); + $$1.extend(el, properties); + el.style.cssText = Conf[`${id}.position`]; + + const move = $$1('.move', el); + $$1.on(move, 'touchstart mousedown', dragstart); + for (var child of move.children) { + if (!child.tagName) { continue; } + $$1.on(child, 'touchstart mousedown', e => e.stopPropagation()); + } + + return el; + }; + + var Menu$1 = (function() { + let currentMenu = undefined; + let lastToggledButton = undefined; + Menu$1 = class Menu { + static initClass() { + currentMenu = null; + lastToggledButton = null; + } + + constructor(type) { + // XXX AddMenuEntry event is deprecated + 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 = type; + $$1.on(d$1, 'AddMenuEntry', ({detail}) => { + if (detail.type !== this.type) { return; } + delete detail.open; + return this.addEntry(detail); + }); + this.entries = []; + } + + makeMenu() { + const menu = $$1.el('div', { + className: 'dialog', + id: 'menu', + tabIndex: 0 + } + ); + menu.dataset.type = this.type; + $$1.on(menu, 'click', e => e.stopPropagation()); + $$1.on(menu, 'keydown', this.keybinds); + return menu; + } + + toggle(e, button, data) { + e.preventDefault(); + e.stopPropagation(); + + if (currentMenu) { + // Close if it's already opened. + // Reopen if we clicked on another button. + const previousButton = lastToggledButton; + currentMenu.close(); + if (previousButton === button) { return; } + } + + if (!this.entries.length) { return; } + return this.open(button, data); + } + + open(button, data) { + let entry; + const menu = (this.menu = this.makeMenu()); + currentMenu = this; + lastToggledButton = button; + + this.entries.sort((first, second) => first.order - second.order); + + for (entry of this.entries) { + this.insertEntry(entry, menu, data); + } + + $$1.addClass(lastToggledButton, 'active'); + + $$1.on(d$1, 'click CloseMenu', this.close); + $$1.on(d$1, 'scroll', this.setPosition); + $$1.on(window, 'resize', this.setPosition); + $$1.after(button, menu); + + this.setPosition(); + + entry = $$1('.entry', menu); + // We've removed flexbox, so we don't use order anymore. + // while prevEntry = @findNextEntry entry, -1 + // entry = prevEntry + this.focus(entry); + + return menu.focus(); + } + + setPosition() { + const mRect = this.menu.getBoundingClientRect(); + const bRect = lastToggledButton.getBoundingClientRect(); + window.scrollY + bRect.top; + window.scrollX + bRect.left; + const cHeight = doc$1.clientHeight; + const cWidth = doc$1.clientWidth; + const [top, bottom] = Array.from((bRect.top + bRect.height + mRect.height) < cHeight ? + [`${bRect.bottom}px`, ''] + : + ['', `${cHeight - bRect.top}px`]); + const [left, right] = Array.from((bRect.left + mRect.width) < cWidth ? + [`${bRect.left}px`, ''] + : + ['', `${cWidth - bRect.right}px`]); + $$1.extend(this.menu.style, {top, right, bottom, left}); + return this.menu.classList.toggle('left', right); + } + + insertEntry(entry, parent, data) { + let submenu; + if (typeof entry.open === 'function') { + try { + if (!entry.open(data)) { return; } + } catch (err) { + Main$1.handleErrors({ + message: `Error in building the ${this.type} menu.`, + error: err + }); + return; + } + } + $$1.add(parent, entry.el); + + if (!entry.subEntries) { return; } + if (submenu = $$1('.submenu', entry.el)) { + // Reset sub menu, remove irrelevant entries. + $$1.rm(submenu); + } + submenu = $$1.el('div', + {className: 'dialog submenu'}); + for (var subEntry of entry.subEntries) { + this.insertEntry(subEntry, submenu, data); + } + $$1.add(entry.el, submenu); + } + + close() { + $$1.rm(this.menu); + delete this.menu; + $$1.rmClass(lastToggledButton, 'active'); + currentMenu = null; + lastToggledButton = null; + $$1.off(d$1, 'click scroll CloseMenu', this.close); + $$1.off(d$1, 'scroll', this.setPosition); + return $$1.off(window, 'resize', this.setPosition); + } + + findNextEntry(entry, direction) { + const entries = [...Array.from(entry.parentNode.children)]; + entries.sort((first, second) => first.style.order - second.style.order); + return entries[entries.indexOf(entry) + direction]; + } + + keybinds(e) { + let subEntry; + let next, submenu; + let entry = $$1('.focused', this.menu); + while ((subEntry = $$1('.focused', entry))) { + entry = subEntry; + } + + switch (e.keyCode) { + case 27: // Esc + lastToggledButton.focus(); + this.close(); + break; + case 13: case 32: // Enter, Space + entry.click(); + break; + case 38: // Up + if (next = this.findNextEntry(entry, -1)) { + this.focus(next); + } + break; + case 40: // Down + if (next = this.findNextEntry(entry, +1)) { + this.focus(next); + } + break; + case 39: // Right + if ((submenu = $$1('.submenu', entry)) && (next = submenu.firstElementChild)) { + let nextPrev; + while ((nextPrev = this.findNextEntry(next, -1))) { + next = nextPrev; + } + this.focus(next); + } + break; + case 37: // Left + if (next = $$1.x('parent::*[contains(@class,"submenu")]/parent::*', entry)) { + this.focus(next); + } + break; + default: + return; + } + + e.preventDefault(); + return e.stopPropagation(); + } + + onFocus(e) { + e.stopPropagation(); + return this.focus(e.target); + } + + focus(entry) { + let focused, submenu; + while ((focused = $$1.x('parent::*/child::*[contains(@class,"focused")]', entry))) { + $$1.rmClass(focused, 'focused'); + } + for (focused of $$('.focused', entry)) { + $$1.rmClass(focused, 'focused'); + } + $$1.addClass(entry, 'focused'); + + // Submenu positioning. + if (!(submenu = $$1('.submenu', entry))) { return; } + const sRect = submenu.getBoundingClientRect(); + const eRect = entry.getBoundingClientRect(); + const cHeight = doc$1.clientHeight; + const cWidth = doc$1.clientWidth; + const [top, bottom] = Array.from((eRect.top + sRect.height) < cHeight ? + ['0px', 'auto'] + : + ['auto', '0px']); + const [left, right] = Array.from((eRect.right + sRect.width) < (cWidth - 150) ? + ['100%', 'auto'] + : + ['auto', '100%']); + const {style} = submenu; + style.top = top; + style.bottom = bottom; + style.left = left; + return style.right = right; + } + + addEntry(entry) { + this.parseEntry(entry); + return this.entries.push(entry); + } + + parseEntry(entry) { + const {el, subEntries} = entry; + $$1.addClass(el, 'entry'); + $$1.on(el, 'focus mouseover', this.onFocus); + el.style.order = entry.order || 100; + if (!subEntries) { return; } + $$1.addClass(el, 'has-submenu'); + for (var subEntry of subEntries) { + this.parseEntry(subEntry); + } + } + }; + Menu$1.initClass(); + return Menu$1; + })(); + + var dragstart = function (e) { + let isTouching; + if ((e.type === 'mousedown') && (e.button !== 0)) { return; } // not LMB + // prevent text selection + e.preventDefault(); + if (isTouching = e.type === 'touchstart') { + e = e.changedTouches[e.changedTouches.length - 1]; + } + // distance from pointer to el edge is constant; calculate it here. + const el = $$1.x('ancestor::div[contains(@class,"dialog")][1]', this); + const rect = el.getBoundingClientRect(); + const screenHeight = doc$1.clientHeight; + const screenWidth = doc$1.clientWidth; + const o = { + id: el.id, + style: el.style, + dx: e.clientX - rect.left, + dy: e.clientY - rect.top, + height: screenHeight - rect.height, + width: screenWidth - rect.width, + screenHeight, + screenWidth, + isTouching + }; + + [o.topBorder, o.bottomBorder] = Array.from(Conf['Header auto-hide'] || !Conf['Fixed Header'] ? + [0, 0] + : Conf['Bottom Header'] ? + [0, Header$1.bar.getBoundingClientRect().height] + : + [Header$1.bar.getBoundingClientRect().height, 0]); + + if (isTouching) { + o.identifier = e.identifier; + o.move = touchmove.bind(o); + o.up = touchend.bind(o); + $$1.on(d$1, 'touchmove', o.move); + return $$1.on(d$1, 'touchend touchcancel', o.up); + } else { // mousedown + o.move = drag.bind(o); + o.up = dragend.bind(o); + $$1.on(d$1, 'mousemove', o.move); + return $$1.on(d$1, 'mouseup', o.up); + } + }; + + var touchmove = function (e) { + for (var touch of e.changedTouches) { + if (touch.identifier === this.identifier) { + drag.call(this, touch); + return; + } + } + }; + + var drag = function (e) { + const {clientX, clientY} = e; + + let left = clientX - this.dx; + left = left < 10 ? + 0 + : (this.width - left) < 10 ? + '' + : + ((left / this.screenWidth) * 100) + '%'; + + let top = clientY - this.dy; + top = top < (10 + this.topBorder) ? + this.topBorder + 'px' + : (this.height - top) < (10 + this.bottomBorder) ? + '' + : + ((top / this.screenHeight) * 100) + '%'; + + const right = left === '' ? + 0 + : + ''; + + const bottom = top === '' ? + this.bottomBorder + 'px' + : + ''; + + const {style} = this; + style.left = left; + style.right = right; + style.top = top; + return style.bottom = bottom; + }; + + var touchend = function (e) { + for (var touch of e.changedTouches) { + if (touch.identifier === this.identifier) { + dragend.call(this); + return; + } + } + }; + + var dragend = function () { + if (this.isTouching) { + $$1.off(d$1, 'touchmove', this.move); + $$1.off(d$1, 'touchend touchcancel', this.up); + } else { // mouseup + $$1.off(d$1, 'mousemove', this.move); + $$1.off(d$1, 'mouseup', this.up); + } + return $$1.set(`${this.id}.position`, this.style.cssText); + }; + + const hoverstart = function ({ root, el, latestEvent, endEvents, height, width, cb, noRemove }) { + const rect = root.getBoundingClientRect(); + const o = { + root, + el, + style: el.style, + isImage: ['IMG', 'VIDEO'].includes(el.nodeName), + cb, + endEvents, + latestEvent, + clientHeight: doc$1.clientHeight, + clientWidth: doc$1.clientWidth, + height, + width, + noRemove, + clientX: (rect.left + rect.right) / 2, + clientY: (rect.top + rect.bottom) / 2 + }; + o.hover = hover.bind(o); + o.hoverend = hoverend.bind(o); + + o.hover(o.latestEvent); + new MutationObserver(function() { + if (el.parentNode) { return o.hover(o.latestEvent); } + }).observe(el, {childList: true}); + + $$1.on(root, endEvents, o.hoverend); + if ($$1.x('ancestor::div[contains(@class,"inline")][1]', root)) { + $$1.on(d$1, 'keydown', o.hoverend); + } + $$1.on(root, 'mousemove', o.hover); + + // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=674955 + o.workaround = function(e) { if (!root.contains(e.target)) { return o.hoverend(e); } }; + return $$1.on(doc$1, 'mousemove', o.workaround); + }; + + hoverstart.padding = 25; + + var hover = function (e) { + this.latestEvent = e; + const height = (this.height || this.el.offsetHeight) + hoverstart.padding; + const width = (this.width || this.el.offsetWidth); + const {clientX, clientY} = Conf['Follow Cursor'] ? e : this; + + const top = this.isImage ? + Math.max(0, (clientY * (this.clientHeight - height)) / this.clientHeight) + : + Math.max(0, Math.min(this.clientHeight - height, clientY - 120)); + + let threshold = this.clientWidth / 2; + if (!this.isImage) { threshold = Math.max(threshold, this.clientWidth - 400); } + let marginX = (clientX <= threshold ? clientX : this.clientWidth - clientX) + 45; + if (this.isImage) { marginX = Math.min(marginX, this.clientWidth - width); } + marginX += 'px'; + const [left, right] = Array.from(clientX <= threshold ? [marginX, ''] : ['', marginX]); + + const {style} = this; + style.top = top + 'px'; + style.left = left; + return style.right = right; + }; + + var hoverend = function (e) { + if (((e.type === 'keydown') && (e.keyCode !== 13)) || (e.target.nodeName === "TEXTAREA")) { return; } + if (!this.noRemove) { $$1.rm(this.el); } + $$1.off(this.root, this.endEvents, this.hoverend); + $$1.off(d$1, 'keydown', this.hoverend); + $$1.off(this.root, 'mousemove', this.hover); + // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=674955 + $$1.off(doc$1, 'mousemove', this.workaround); + if (this.cb) { return this.cb.call(this); } + }; + + const checkbox = function (name, text, checked) { + if (checked == null) { checked = Conf[name]; } + const label = $$1.el('label'); + const input = $$1.el('input', {type: 'checkbox', name, checked}); + $$1.add(label, [input, $$1.tn(` ${text}`)]); + return label; + }; + + const UI = { + dialog, + Menu: Menu$1, + hover: hoverstart, + checkbox + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Nav = { + init() { + switch (g.VIEW) { + case 'index': + if (!Conf['Index Navigation']) { return; } + break; + case 'thread': + if (!Conf['Reply Navigation']) { return; } + break; + default: + return; + } + + const span = $$1.el('span', + {id: 'navlinks'}); + const prev = $$1.el('a', { + textContent: '▲', + href: 'javascript:;' + } + ); + const next = $$1.el('a', { + textContent: '▼', + href: 'javascript:;' + } + ); + + $$1.on(prev, 'click', this.prev); + $$1.on(next, 'click', this.next); + + $$1.add(span, [prev, $$1.tn(' '), next]); + var append = function() { + $$1.off(d$1, '4chanXInitFinished', append); + return $$1.add(d$1.body, span); + }; + return $$1.on(d$1, '4chanXInitFinished', append); + }, + + prev() { + if (g.VIEW === 'thread') { + return window.scrollTo(0, 0); + } else { + return Nav.scroll(-1); + } + }, + + next() { + if (g.VIEW === 'thread') { + return window.scrollTo(0, d$1.body.scrollHeight); + } else { + return Nav.scroll(+1); + } + }, + + getThread() { + if (g.VIEW === 'thread') { return g.threads.get(`${g.BOARD}.${g.THREADID}`).nodes.root; } + if ($$1.hasClass(doc$1, 'catalog-mode')) { return; } + for (var threadRoot of $$(g.SITE.selectors.thread)) { + var thread = Get$1.threadFromRoot(threadRoot); + if (thread.isHidden && !thread.stub) { continue; } + if (Header$1.getTopOf(threadRoot) >= -threadRoot.getBoundingClientRect().height) { // not scrolled past + return threadRoot; + } + } + }, + + scroll(delta) { + let next; + d$1.activeElement?.blur(); + let thread = Nav.getThread(); + if (!thread) { return; } + const axis = delta === +1 ? + 'following' + : + 'preceding'; + if (next = $$1.x(`${axis}-sibling::${g.SITE.xpath.thread}[not(@hidden)][1]`, thread)) { + // Unless we're not at the beginning of the current thread, + // and thus wanting to move to beginning, + // or we're above the first thread and don't want to skip it. + const top = Header$1.getTopOf(thread); + if (((delta === +1) && (top < 5)) || ((delta === -1) && (top > -5))) { thread = next; } + } + // Add extra space to the end of the page if necessary so that all threads can be selected by keybinds. + const extra = (Header$1.getTopOf(thread) + doc$1.clientHeight) - d$1.body.getBoundingClientRect().bottom; + if (extra > 0) { d$1.body.style.marginBottom = `${extra}px`; } + + Header$1.scrollTo(thread); + + if ((extra > 0) && !Nav.haveExtra) { + Nav.haveExtra = true; + return $$1.on(d$1, 'scroll', Nav.removeExtra); + } + }, + + removeExtra() { + const extra = doc$1.clientHeight - d$1.body.getBoundingClientRect().bottom; + if (extra > 0) { + return d$1.body.style.marginBottom = `${extra}px`; + } else { + d$1.body.style.marginBottom = ''; + delete Nav.haveExtra; + return $$1.off(d$1, 'scroll', Nav.removeExtra); + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ImageHost = { + init() { + if ((!(this.useFaster = /\S/.test(Conf['fourchanImageHost']))) || (g.SITE.software !== 'yotsuba') || !['index', 'thread'].includes(g.VIEW)) { return; } + return Callbacks.Post.push({ + name: 'Image Host Rewriting', + cb: this.node + }); + }, + + suggestions: ['i.4cdn.org', 'is2.4chan.org'], + + host() { + return Conf['fourchanImageHost'].trim() || 'i.4cdn.org'; + }, + flashHost() { + return 'i.4cdn.org'; + }, + thumbHost() { + return 'i.4cdn.org'; + }, + test(hostname) { + return (hostname === 'i.4cdn.org') || ImageHost.regex.test(hostname); + }, + + regex: /^is\d*\.4chan(?:nel)?\.org$/, + + node() { + if (this.isClone) { return; } + const host = ImageHost.host(); + if (this.file && ImageHost.test(this.file.url.split('/')[2]) && !/\.swf$/.test(this.file.url)) { + this.file.link.hostname = host; + if (this.file.thumbLink) { this.file.thumbLink.hostname = host; } + this.file.url = this.file.link.href; + } + return ImageHost.fixLinks($$('a', this.nodes.comment)); + }, + + fixLinks(links) { + for (var link of links) { + if (ImageHost.test(link.hostname) && !/\.swf$/.test(link.pathname)) { + var host = ImageHost.host(); + if (link.hostname !== host) { link.hostname = host; } + } + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Volume = { + init() { + if (!['index', 'thread'].includes(g.VIEW) || + (!Conf['Image Expansion'] && !Conf['Image Hover'] && !Conf['Image Hover in Catalog'] && !Conf['Gallery'])) { return; } + + $$1.sync('Allow Sound', function(x) { + Conf['Allow Sound'] = x; + if (Volume.inputs) Volume.inputs.unmute.checked = x; + }); + + $$1.sync('Default Volume', function(x) { + Conf['Default Volume'] = x; + if (Volume.inputs) Volume.inputs.volume.value = x; + }); + + if (Conf['Mouse Wheel Volume']) { + Callbacks.Post.push({ + name: 'Mouse Wheel Volume', + cb: this.node + }); + } + + if (g.SITE.noAudio?.(g.BOARD)) { return; } + + if (Conf['Mouse Wheel Volume']) { + Callbacks.CatalogThread.push({ + name: 'Mouse Wheel Volume', + cb: this.catalogNode + }); + } + + const unmuteEntry = UI.checkbox('Allow Sound', 'Allow Sound'); + unmuteEntry.title = Config.main['Images and Videos']['Allow Sound'][1]; + + const volumeEntry = $$1.el('label', + {title: 'Default volume for videos.'}); + $$1.extend(volumeEntry, + {innerHTML: " Volume"}); + + this.inputs = { + unmute: unmuteEntry.firstElementChild, + volume: volumeEntry.firstElementChild + }; + + $$1.on(this.inputs.unmute, 'change', $$1.cb.checked); + $$1.on(this.inputs.volume, 'change', $$1.cb.value); + + Header$1.menu.addEntry({el: unmuteEntry, order: 200}); + return Header$1.menu.addEntry({el: volumeEntry, order: 201}); + }, + + setup(video) { + video.muted = !Conf['Allow Sound']; + video.volume = Conf['Default Volume']; + return $$1.on(video, 'volumechange', Volume.change); + }, + + change() { + const {muted, volume} = this; + const items = { + 'Allow Sound': !muted, + 'Default Volume': volume + }; + for (var key in items) { + var val = items[key]; + if (Conf[key] === val) { + delete items[key]; + } + } + $$1.set(items); + $$1.extend(Conf, items); + if (Volume.inputs) { + Volume.inputs.unmute.checked = !muted; + return Volume.inputs.volume.value = volume; + } + }, + + node() { + if (g.SITE.noAudio?.(this.board)) { return; } + for (var file of this.files) { + if (file.isVideo) { + if (file.thumb) { $$1.on(file.thumb, 'wheel', Volume.wheel.bind(Header$1.hover)); } + $$1.on(($$1('.file-info', file.text) || file.link), 'wheel', Volume.wheel.bind(file.thumbLink)); + } + } + }, + + catalogNode() { + const file = this.thread.OP.files[0]; + if (!file?.isVideo) { return; } + return $$1.on(this.nodes.thumb, 'wheel', Volume.wheel.bind(Header$1.hover)); + }, + + wheel(e) { + let el; + if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { return; } + if (!(el = $$1('video:not([data-md5])', this))) { return; } + if (el.muted || !$$1.hasAudio(el)) { return; } + let volume = el.volume + 0.1; + if (e.deltaY < 0) { volume *= 1.1; } + if (e.deltaY > 0) { volume /= 1.1; } + el.volume = $$1.minmax(volume - 0.1, 0, 1); + return e.preventDefault(); + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS104: Avoid inline assignments + * DS204: Change includes calls to have a more natural evaluation order + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ImageCommon = { + // Pause and mute video in preparation for removing the element from the document. + pause(video) { + if (video.nodeName !== 'VIDEO') { return; } + video.pause(); + $$1.off(video, 'volumechange', Volume.change); + return video.muted = true; + }, + + rewind(el) { + if (el.nodeName === 'VIDEO') { + if (el.readyState >= el.HAVE_METADATA) { return el.currentTime = 0; } + } else if (/\.gif$/.test(el.src)) { + return $$1.queueTask(() => el.src = el.src); + } + }, + + pushCache(el) { + ImageCommon.cache = el; + return $$1.on(el, 'error', ImageCommon.cacheError); + }, + + popCache() { + const el = ImageCommon.cache; + $$1.off(el, 'error', ImageCommon.cacheError); + delete ImageCommon.cache; + return el; + }, + + cacheError() { + if (ImageCommon.cache === this) { return delete ImageCommon.cache; } + }, + + decodeError(file, fileObj) { + let message; + if (file.error?.code !== MediaError.MEDIA_ERR_DECODE) { return false; } + if (!(message = $$1('.warning', fileObj.thumb.parentNode))) { + message = $$1.el('div', {className: 'warning'}); + $$1.after(fileObj.thumb, message); + } + message.textContent = 'Error: Corrupt or unplayable video'; + return true; + }, + + isFromArchive(file) { + return (g.SITE.software === 'yotsuba') && !ImageHost.test(file.src.split('/')[2]); + }, + + error(file, post, fileObj, delay, cb) { + let timeoutID; + const src = fileObj.url.split('/'); + let url = null; + if ((g.SITE.software === 'yotsuba') && Conf['404 Redirect']) { + url = Redirect$1.to('file', { + boardID: post.board.ID, + filename: src[src.length - 1] + }); + } + if (!url || !Redirect$1.securityCheck(url)) { url = null; } + + if ((post.isDead || fileObj.isDead) && !ImageCommon.isFromArchive(file)) { return cb(url); } + + if (delay != null) { timeoutID = setTimeout((() => cb(url)), delay); } + if (post.isDead || fileObj.isDead) { return; } + const redirect = function() { + if (!ImageCommon.isFromArchive(file)) { + if (delay != null) { clearTimeout(timeoutID); } + return cb(url); + } + }; + + const threadJSON = g.SITE.urls.threadJSON?.(post); + if (!threadJSON) { return; } + var parseJSON = function(isArchiveURL) { + let needle, postObj; + if (this.status === 404) { + let archivedThreadJSON; + if (!isArchiveURL && (archivedThreadJSON = g.SITE.urls.archivedThreadJSON?.(post))) { + $$1.ajax(archivedThreadJSON, {onloadend() { return parseJSON.call(this, true); }}); + } else { + post.kill(!post.isClone, fileObj.index); + } + } + if (this.status !== 200) { return redirect(); } + for (postObj of this.response.posts) { + if (postObj.no === post.ID) { break; } + } + if (postObj.no !== post.ID) { + post.kill(); + return redirect(); + } else if ((needle = fileObj.docIndex, g.SITE.Build.parseJSON(postObj, post.board).filesDeleted.includes(needle))) { + post.kill(true); + return redirect(); + } else { + return url = fileObj.url; + } + }; + return $$1.ajax(threadJSON, {onloadend() { return parseJSON.call(this); }}); + }, + + // Add controls, but not until the mouse is moved over the video. + addControls(video) { + var handler = function() { + $$1.off(video, 'mouseover', handler); + // Hacky workaround for Firefox forever-loading bug for very short videos + const t = new Date().getTime(); + return $$1.asap((() => ($$1.engine !== 'gecko') || ((video.readyState >= 3) && (video.currentTime <= Math.max(0.1, (video.duration - 0.5)))) || (new Date().getTime() >= (t + 1000))), () => video.controls = true); + }; + return $$1.on(video, 'mouseover', handler); + }, + + // XXX Estimate whether clicks are on the video controls and should be ignored. + onControls(e) { + return (Conf['Show Controls'] && Conf['Click Passthrough'] && (e.target.nodeName === 'VIDEO')) || + (e.target.controls && ((e.target.getBoundingClientRect().bottom - e.clientY) < 35)); + }, + + download(e) { + if (this.protocol === 'blob:') { return true; } + e.preventDefault(); + const {href, download} = this; + return CrossOrigin$1.file(href, function(blob) { + if (blob) { + const a = $$1.el('a', { + href: URL.createObjectURL(blob), + download, + hidden: true + } + ); + $$1.add(d$1.body, a); + a.click(); + return $$1.rm(a); + } else { + return new Notice('warning', `Could not download ${href}`, 20); + } + }); + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ImageExpand = { + init() { + if (!(this.enabled = Conf['Image Expansion'] && ['index', 'thread'].includes(g.VIEW))) { return; } + + this.EAI = $$1.el('a', { + className: 'expand-all-shortcut', + textContent: '➕︎', + title: 'Expand All Images', + href: 'javascript:;' + } + ); + + $$1.on(this.EAI, 'click', this.cb.toggleAll); + Header$1.addShortcut('expand-all', this.EAI, 520); + $$1.on(d$1, 'scroll visibilitychange', this.cb.playVideos); + this.videoControls = $$1.el('span', {className: 'video-controls'}); + $$1.extend(this.videoControls, {innerHTML: " contract"}); + + return Callbacks.Post.push({ + name: 'Image Expansion', + cb: this.node + }); + }, + + node() { + if (!this.file || (!this.file.isImage && !this.file.isVideo)) { return; } + $$1.on(this.file.thumbLink, 'click', ImageExpand.cb.toggle); + + if (this.isClone) { + if (this.file.isExpanding) { + // If we clone a post where the image is still loading, + // make it loading in the clone too. + ImageExpand.contract(this); + return ImageExpand.expand(this); + + } else if (this.file.isExpanded && this.file.isVideo) { + Volume.setup(this.file.fullImage); + ImageExpand.setupVideoCB(this); + return ImageExpand.setupVideo(this, !this.origin.file.fullImage?.paused || this.origin.file.wasPlaying, this.file.fullImage.controls); + } + + } else if (ImageExpand.on && !this.isHidden && !this.isFetchedQuote && + (Conf['Expand spoilers'] || !this.file.isSpoiler) && + (Conf['Expand videos'] || !this.file.isVideo)) { + return ImageExpand.expand(this); + } + }, + + cb: { + toggle(e) { + if ($$1.modifiedClick(e)) { return; } + const post = Get$1.postFromNode(this); + const {file} = post; + if (file.isExpanded && ImageCommon.onControls(e)) { return; } + e.preventDefault(); + if (!Conf['Autoplay'] && file.fullImage?.paused) { + return file.fullImage.play(); + } else { + return ImageExpand.toggle(post); + } + }, + + toggleAll() { + let func; + $$1.event('CloseMenu'); + const threadRoot = Nav.getThread(); + const toggle = function(post) { + const {file} = post; + if (!file || (!file.isImage && !file.isVideo) || !doc$1.contains(post.nodes.root)) { return; } + if (ImageExpand.on && + ((!Conf['Expand spoilers'] && file.isSpoiler) || + (!Conf['Expand videos'] && file.isVideo) || + (Conf['Expand from here'] && (Header$1.getTopOf(file.thumb) < 0)) || + (Conf['Expand thread only'] && (g.VIEW === 'index') && !threadRoot?.contains(file.thumb)))) { + return; + } + return $$1.queueTask(func, post); + }; + + if (ImageExpand.on = $$1.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) { + ImageExpand.EAI.className = 'contract-all-shortcut'; + ImageExpand.EAI.title = 'Contract All Images'; + ImageExpand.EAI.textContent = '➖︎'; + func = ImageExpand.expand; + } else { + ImageExpand.EAI.className = 'expand-all-shortcut'; + ImageExpand.EAI.title = 'Expand All Images'; + ImageExpand.EAI.textContent = '➕︎'; + func = ImageExpand.contract; + } + + return g.posts.forEach(function(post) { + for (post of [post, ...Array.from(post.clones)]) { toggle(post); } + }); + }, + + playVideos() { + return g.posts.forEach(function(post) { + for (post of [post, ...Array.from(post.clones)]) { + var {file} = post; + if (!file || !file.isVideo || !file.isExpanded) { continue; } + + var video = file.fullImage; + var visible = ($$1.hasAudio(video) && !video.muted) || Header$1.isNodeVisible(video); + if (visible && file.wasPlaying) { + delete file.wasPlaying; + video.play(); + } else if (!visible && !video.paused) { + file.wasPlaying = true; + video.pause(); + } + } + }); + }, + + setFitness() { + return $$1[this.checked ? 'addClass' : 'rmClass'](doc$1, this.name.toLowerCase().replace(/\s+/g, '-')); + } + }, + + toggle(post) { + if (!post.file.isExpanding && !post.file.isExpanded) { + post.file.scrollIntoView = Conf['Scroll into view']; + ImageExpand.expand(post); + return; + } + + ImageExpand.contract(post); + + if (Conf['Advance on contract']) { + let next = post.nodes.root; + while ((next = $$1.x("following::div[contains(@class,'postContainer')][1]", next))) { + if (!$$1('.stub', next) && (next.offsetHeight !== 0)) { break; } + } + if (next) { + return Header$1.scrollTo(next); + } + } + }, + + contract(post) { + let bottom, el, oldHeight, scrollY; + const {file} = post; + + if (el = file.fullImage) { + const top = Header$1.getTopOf(el); + bottom = top + el.getBoundingClientRect().height; + oldHeight = d$1.body.clientHeight; + ({scrollY} = window); + } + + $$1.rmClass(post.nodes.root, 'expanded-image'); + $$1.rmClass(file.thumb, 'expanding'); + $$1.rm(file.videoControls); + file.thumbLink.href = file.url; + file.thumbLink.target = '_blank'; + for (var x of ['isExpanding', 'isExpanded', 'videoControls', 'wasPlaying', 'scrollIntoView']) { + delete file[x]; + } + + if (!el) { return; } + + if (doc$1.contains(el)) { + if (bottom <= 0) { + // For images entirely above us, scroll to remain in place. + window.scrollBy(0, ((scrollY - window.scrollY) + d$1.body.clientHeight) - oldHeight); + } else { + // For images not above us that would be moved above us, scroll to the thumbnail. + Header$1.scrollToIfNeeded(post.nodes.root); + } + if (window.scrollX > 0) { + // If we have scrolled right viewing an expanded image, return to the left. + window.scrollBy(-window.scrollX, 0); + } + } + + $$1.off(el, 'error', ImageExpand.error); + ImageCommon.pushCache(el); + if (file.isVideo) { + ImageCommon.pause(el); + for (var eventName in ImageExpand.videoCB) { + var cb = ImageExpand.videoCB[eventName]; + $$1.off(el, eventName, cb); + } + } + if (Conf['Restart when Opened']) { ImageCommon.rewind(file.thumb); } + delete file.fullImage; + return $$1.queueTask(function() { + // XXX Work around Chrome/Chromium not firing mouseover on the thumbnail. + if (file.isExpanding || file.isExpanded) { return; } + $$1.rmClass(el, 'full-image'); + if (el.id) { return; } + return $$1.rm(el); + }); + }, + + expand(post, src) { + // Do not expand images of hidden/filtered replies, or already expanded pictures. + let el; + const {file} = post; + const {thumb, thumbLink, isVideo} = file; + if (post.isHidden || file.isExpanding || file.isExpanded) { return; } + + $$1.addClass(thumb, 'expanding'); + file.isExpanding = true; + + if (file.fullImage) { + el = file.fullImage; + } else if (ImageCommon.cache?.dataset.fileID === `${post.fullID}.${file.index}`) { + el = (file.fullImage = ImageCommon.popCache()); + $$1.on(el, 'error', ImageExpand.error); + if (Conf['Restart when Opened'] && (el.id !== 'ihover')) { ImageCommon.rewind(el); } + el.removeAttribute('id'); + } else { + el = (file.fullImage = $$1.el((isVideo ? 'video' : 'img'))); + el.dataset.fileID = `${post.fullID}.${file.index}`; + $$1.on(el, 'error', ImageExpand.error); + el.src = src || file.url; + } + + el.className = 'full-image'; + $$1.after(thumb, el); + + if (isVideo) { + // add contract link to file info + if (!file.videoControls) { + file.videoControls = ImageExpand.videoControls.cloneNode(true); + $$1.add(file.text, file.videoControls); + } + + // disable link to file so native controls can work + thumbLink.removeAttribute('href'); + thumbLink.removeAttribute('target'); + + el.loop = true; + Volume.setup(el); + ImageExpand.setupVideoCB(post); + } + + if (!isVideo) { + return $$1.asap((() => el.naturalHeight), () => ImageExpand.completeExpand(post)); + } else if (el.readyState >= el.HAVE_METADATA) { + return ImageExpand.completeExpand(post); + } else { + return $$1.on(el, 'loadedmetadata', () => ImageExpand.completeExpand(post)); + } + }, + + completeExpand(post) { + const {file} = post; + if (!file.isExpanding) { return; } // contracted before the image loaded + + const bottom = Header$1.getTopOf(file.thumb) + file.thumb.getBoundingClientRect().height; + const oldHeight = d$1.body.clientHeight; + const {scrollY} = window; + + $$1.addClass(post.nodes.root, 'expanded-image'); + $$1.rmClass(file.thumb, 'expanding'); + file.isExpanded = true; + delete file.isExpanding; + + // Scroll to keep our place in the thread when images are expanded above us. + if (doc$1.contains(post.nodes.root) && (bottom <= 0)) { + window.scrollBy(0, ((scrollY - window.scrollY) + d$1.body.clientHeight) - oldHeight); + } + + // Scroll to display full image. + if (file.scrollIntoView) { + delete file.scrollIntoView; + const imageBottom = Math.min(doc$1.clientHeight - file.fullImage.getBoundingClientRect().bottom - 25, Header$1.getBottomOf(file.fullImage)); + if (imageBottom < 0) { + window.scrollBy(0, Math.min(-imageBottom, Header$1.getTopOf(file.fullImage))); + } + } + + if (file.isVideo) { + return ImageExpand.setupVideo(post, Conf['Autoplay'], Conf['Show Controls']); + } + }, + + setupVideo(post, playing, controls) { + const {fullImage} = post.file; + if (!playing) { + fullImage.controls = controls; + return; + } + fullImage.controls = false; + $$1.asap((() => doc$1.contains(fullImage)), function() { + if (!d$1.hidden && Header$1.isNodeVisible(fullImage)) { + return fullImage.play(); + } else { + return post.file.wasPlaying = true; + } + }); + if (controls) { + return ImageCommon.addControls(fullImage); + } + }, + + videoCB: (function() { + // dragging to the left contracts the video + let mousedown = false; + return { + mouseover() { return mousedown = false; }, + mousedown(e) { if (e.button === 0) { return mousedown = true; } }, + mouseup(e) { if (e.button === 0) { return mousedown = false; } }, + mouseout(e) { if (((e.buttons & 1) || mousedown) && (e.clientX <= this.getBoundingClientRect().left)) { return ImageExpand.toggle(Get$1.postFromNode(this)); } } + }; + })(), + + setupVideoCB(post) { + for (var eventName in ImageExpand.videoCB) { + var cb = ImageExpand.videoCB[eventName]; + $$1.on(post.file.fullImage, eventName, cb); + } + if (post.file.videoControls) { + return $$1.on(post.file.videoControls.firstElementChild, 'click', () => ImageExpand.toggle(post)); + } + }, + + error() { + const post = Get$1.postFromNode(this); + $$1.rm(this); + delete post.file.fullImage; + // Images can error: + // - before the image started loading. + // - after the image started loading. + // Don't try to re-expand if it was already contracted. + if (!post.file.isExpanding && !post.file.isExpanded) { return; } + if (ImageCommon.decodeError(this, post.file)) { + return ImageExpand.contract(post); + } + // Don't autoretry images from the archive. + if (ImageCommon.isFromArchive(this)) { + return ImageExpand.contract(post); + } + return ImageCommon.error(this, post, post.file, 10 * SECOND, function(URL) { + if (post.file.isExpanding || post.file.isExpanded) { + ImageExpand.contract(post); + if (URL) { return ImageExpand.expand(post, URL); } + } + }); + }, + + menu: { + init() { + if (!ImageExpand.enabled) { return; } + + const el = $$1.el('span', { + textContent: 'Image Expansion', + className: 'image-expansion-link' + } + ); + + const {createSubEntry} = ImageExpand.menu; + const subEntries = []; + for (var name in Config.imageExpansion) { + var conf = Config.imageExpansion[name]; + subEntries.push(createSubEntry(name, conf[1])); + } + + return Header$1.menu.addEntry({ + el, + order: 105, + subEntries + }); + }, + + createSubEntry(name, desc) { + const label = UI.checkbox(name, name); + label.title = desc; + const input = label.firstElementChild; + if (['Fit width', 'Fit height'].includes(name)) { + $$1.on(input, 'change', ImageExpand.cb.setFitness); + } + $$1.event('change', null, input); + $$1.on(input, 'change', $$1.cb.checked); + return {el: label}; + } + } + }; + + class Post { + toString() { return this.ID; } + constructor(root, thread, board, flags = {}) { + // <% if (readJSON('/.tests_enabled')) { %> + // @normalizedOriginal = Test.normalize root + // <% } %> + // Skip initialization for PostClone + if (root === undefined && thread === undefined && board === undefined) + return; + this.root = root; + this.thread = thread; + this.board = board; + $$1.extend(this, flags); + this.ID = +root.id.match(/\d*$/)[0]; + this.postID = this.ID; + this.threadID = this.thread.ID; + this.boardID = this.board.ID; + this.siteID = g.SITE.ID; + this.fullID = `${this.board}.${this.ID}`; + this.context = this; + this.isReply = (this.ID !== this.threadID); + root.dataset.fullID = this.fullID; + this.nodes = this.parseNodes(root); + if (!this.isReply) { + this.thread.OP = this; + for (var key of ['isSticky', 'isClosed', 'isArchived']) { + var selector; + if (selector = g.SITE.selectors.icons[key]) { + this.thread[key] = !!$$1(selector, this.nodes.info); + } + } + if (this.thread.isArchived) { + this.thread.isClosed = true; + this.thread.kill(); + } + } + const name = this.nodes.name?.textContent; + const tripcode = this.nodes.tripcode?.textContent; + this.info = { + subject: this.nodes.subject?.textContent || undefined, + name, + email: this.nodes.email ? decodeURIComponent(this.nodes.email.href.replace(/^mailto:/, '')) : undefined, + tripcode, + 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 ? g.SITE.parseDate(this.nodes.date) : undefined, + nameBlock: Conf['Anonymize'] ? 'Anonymous' : `${name || ''} ${tripcode || ''}`.trim(), + }; + if (this.info.capcode) { + this.info.nameBlock += ` ## ${this.info.capcode}`; + } + if (this.info.uniqueID) { + this.info.nameBlock += ` (ID: ${this.info.uniqueID})`; + } + this.parseComment(); + this.parseQuotes(); + this.parseFiles(); + this.isDead = false; + this.isHidden = false; + this.clones = []; + // <% if (readJSON('/.tests_enabled')) { %> + // return if @forBuildTest + // <% } %> + if (g.posts.get(this.fullID)) { + this.isRebuilt = true; + this.clones = g.posts.get(this.fullID).clones; + for (var clone of this.clones) { + clone.origin = this; + } + } + if (!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); + g.posts.push(this.fullID, this); + this.isFetchedQuote = false; + this.isClone = false; + } + parseNodes(root) { + const s = g.SITE.selectors; + const post = $$1(s.post, root) || root; + const info = $$1(s.infoRoot, post); + const nodes = { + root, + bottom: this.isReply || !g.SITE.isOPContainerThread ? root : $$1(s.opBottom, root), + post, + info, + comment: $$1(s.comment, post), + quotelinks: [], + archivelinks: [], + embedlinks: [], + backlinks: post.getElementsByClassName('backlink'), + uniqueIDRoot: undefined, + uniqueID: undefined, + }; + for (var key in s.info) { + var selector = s.info[key]; + nodes[key] = $$1(selector, info); + } + g.SITE.parseNodes?.(this, nodes); + if (!nodes.uniqueIDRoot) { + nodes.uniqueIDRoot = nodes.uniqueID; + } + return nodes; + } + parseComment() { + // Merge text nodes and remove empty ones. + let bq; + this.nodes.comment.normalize(); + // Get the comment's text. + //
        -> \n + // Remove: + // 'Comment too long'... + // EXIF data. (/p/) + this.nodes.commentClean = (bq = this.nodes.comment.cloneNode(true)); + g.SITE.cleanComment?.(bq); + return this.info.comment = this.nodesToText(bq); + } + commentDisplay() { + // Get the comment's text for display purposes (e.g. notifications, excerpts). + // In addition to what's done in generating `@info.comment`, remove: + // Spoilers. (filter to '[spoiler]') + // Rolls. (/tg/, /qst/) + // Fortunes. (/s4s/) + // Preceding and following new lines. + // Trailing spaces. + const bq = this.nodes.commentClean.cloneNode(true); + if (!Conf['Remove Spoilers'] && !Conf['Reveal Spoilers']) { + this.cleanSpoilers(bq); + } + g.SITE.cleanCommentDisplay?.(bq); + return this.nodesToText(bq).trim().replace(/\s+$/gm, ''); + } + commentOrig() { + // Get the comment's text for reposting purposes. + const bq = this.nodes.commentClean.cloneNode(true); + g.SITE.insertTags?.(bq); + return this.nodesToText(bq); + } + nodesToText(bq) { + let node; + let text = ""; + const nodes = $$1.X('.//br|.//text()', bq); + let i = 0; + while ((node = nodes.snapshotItem(i++))) { + text += node.data || '\n'; + } + return text; + } + cleanSpoilers(bq) { + const spoilers = $$(g.SITE.selectors.spoiler, bq); + for (var node of spoilers) { + $$1.replace(node, $$1.tn('[spoiler]')); + } + } + parseQuotes() { + this.quotes = []; + for (var quotelink of $$(g.SITE.selectors.quotelink, this.nodes.comment)) { + this.parseQuote(quotelink); + } + } + parseQuote(quotelink) { + // Only add quotes that link to posts on an imageboard. + // Don't add: + // - board links. (>>>/b/) + // - catalog links. (>>>/b/catalog or >>>/b/search) + // - rules links. (>>>/a/rules) + // - text-board quotelinks. (>>>/img/1234) + const match = quotelink.href.match(g.SITE.regexp.quotelink); + if (!match && (!this.isClone || !quotelink.dataset.postID)) { + return; + } // normal or resurrected quote + this.nodes.quotelinks.push(quotelink); + if (this.isClone) { + return; + } + // ES6 Set when? + const fullID = `${match[1]}.${match[3]}`; + if (!this.quotes.includes(fullID)) + this.quotes.push(fullID); + } + parseFiles() { + let file; + this.files = []; + const fileRoots = this.fileRoots(); + let index = 0; + for (let docIndex = 0; docIndex < fileRoots.length; docIndex++) { + var fileRoot = fileRoots[docIndex]; + if (file = this.parseFile(fileRoot)) { + file.index = (index++); + file.docIndex = docIndex; + this.files.push(file); + } + } + if (this.files.length) { + return this.file = this.files[0]; + } + } + fileRoots() { + if (g.SITE.selectors.multifile) { + const roots = $$(g.SITE.selectors.multifile, this.nodes.root); + if (roots.length) { + return roots; + } + } + return [this.nodes.root]; + } + parseFile(fileRoot) { + const file = { isDead: false }; + for (var key in g.SITE.selectors.file) { + var selector = g.SITE.selectors.file[key]; + file[key] = $$1(selector, fileRoot); + } + file.thumbLink = file.thumb?.parentNode; + if (!(file.text && file.link)) { + return; + } + if (!g.SITE.parseFile(this, file)) { + return; + } + $$1.extend(file, { + url: file.link.href, + isImage: $$1.isImage(file.link.href), + isVideo: $$1.isVideo(file.link.href) + }); + let size = +file.size.match(/[\d.]+/)[0]; + let unit = ['B', 'KB', 'MB', 'GB'].indexOf(file.size.match(/\w+$/)[0]); + while (unit-- > 0) { + size *= 1024; + } + file.sizeInBytes = size; + return file; + } + kill(file, index = 0) { + let strong; + if (file) { + if (this.isDead || this.files[index].isDead) { + return; + } + this.files[index].isDead = true; + $$1.addClass(this.nodes.root, 'deleted-file'); + } + else { + if (this.isDead) { + return; + } + this.isDead = true; + $$1.rmClass(this.nodes.root, 'deleted-file'); + $$1.addClass(this.nodes.root, 'deleted-post'); + } + if (!(strong = $$1('strong.warning', this.nodes.info))) { + strong = $$1.el('strong', { className: 'warning' }); + $$1.after($$1('input', this.nodes.info), strong); + } + strong.textContent = file ? '[File deleted]' : '[Deleted]'; + if (this.isClone) { + return; + } + for (var clone of this.clones) { + clone.kill(file, index); + } + if (file) { + return; + } + // Get quotelinks/backlinks to this post + // and paint them (Dead). + for (var quotelink of Get$1.allQuotelinksLinkingTo(this)) { + if (!$$1.hasClass(quotelink, 'deadlink')) { + $$1.add(quotelink, Post.deadMark.cloneNode(true)); + $$1.addClass(quotelink, 'deadlink'); + } + } + } + // XXX Workaround for 4chan's racing condition + // giving us false-positive dead posts. + resurrect() { + this.isDead = false; + $$1.rmClass(this.nodes.root, 'deleted-post'); + const strong = $$1('strong.warning', this.nodes.info); + // no false-positive files + if (this.files.some(file => file.isDead)) { + $$1.addClass(this.nodes.root, 'deleted-file'); + strong.textContent = '[File deleted]'; + } + else { + $$1.rm(strong); + } + if (this.isClone) { + return; + } + for (var clone of this.clones) { + clone.resurrect(); + } + for (var quotelink of Get$1.allQuotelinksLinkingTo(this)) { + if ($$1.hasClass(quotelink, 'deadlink')) { + $$1.rm($$1('.qmark-dead', quotelink)); + $$1.rmClass(quotelink, 'deadlink'); + } + } + } + collect() { + g.posts.rm(this.fullID); + this.thread.posts.rm(this); + this.board.posts.rm(this); + } + addClone(context, contractThumb) { + // Callbacks may not have been run yet due to anti-browser-lock delay in Main.callbackNodesDB. + Callbacks.Post.execute(this); + return new PostClone(this, context, contractThumb); + } + rmClone(index) { + this.clones.splice(index, 1); + for (var clone of this.clones.slice(index)) { + clone.nodes.root.dataset.clone = index++; + } + } + setCatalogOP(isCatalogOP) { + this.nodes.root.classList.toggle('catalog-container', isCatalogOP); + this.nodes.root.classList.toggle('opContainer', !isCatalogOP); + this.nodes.post.classList.toggle('catalog-post', isCatalogOP); + this.nodes.post.classList.toggle('op', !isCatalogOP); + this.nodes.post.style.left = (this.nodes.post.style.right = null); + } + } + // because of a circular dependency $ might not be initialized, so we can't use $.el + Post.deadMark = (() => { + const el = document.createElement('span'); + // \u00A0 is nbsp + el.textContent = '\u00A0(Dead)'; + el.className = 'qmark-dead'; + return el; + })(); + class PostClone extends Post { + constructor(origin, context, contractThumb) { + super(); + this.isClone = true; + let file, fileRoots, key; + this.origin = origin; + this.context = context; + for (key of ['ID', 'postID', 'threadID', 'boardID', 'siteID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']) { + // Copy or point to the origin's key value. + this[key] = this.origin[key]; + } + const { nodes } = this.origin; + const root = contractThumb ? this.cloneWithoutVideo(nodes.root) : nodes.root.cloneNode(true); + for (var node of [root, ...$$('[id]', root)]) { + node.id += `_${PostClone.suffix}`; + } + PostClone.suffix++; + // Remove inlined posts inside of this post. + for (var inline of $$('.inline', root)) { + $$1.rm(inline); + } + for (var inlined of $$('.inlined', root)) { + $$1.rmClass(inlined, 'inlined'); + } + this.nodes = this.parseNodes(root); + root.hidden = false; // post hiding + $$1.rmClass(root, 'forwarded'); // quote inlining + $$1.rmClass(this.nodes.post, 'highlight'); // keybind navigation, ID highlighting + // Remove catalog stuff. + if (!this.isReply) { + this.setCatalogOP(false); + $$1.rm($$1('.catalog-link', this.nodes.post)); + $$1.rm($$1('.catalog-stats', this.nodes.post)); + $$1.rm($$1('.catalog-replies', this.nodes.post)); + } + this.parseQuotes(); + this.quotes = [...this.origin.quotes]; + this.files = []; + if (this.origin.files.length) { + fileRoots = this.fileRoots(); + } + for (var originFile of this.origin.files) { + // Copy values, point to relevant elements. + file = { ...originFile }; + var fileRoot = fileRoots[file.docIndex]; + for (key in g.SITE.selectors.file) { + var selector = g.SITE.selectors.file[key]; + file[key] = $$1(selector, fileRoot); + } + file.thumbLink = file.thumb?.parentNode; + if (file.thumbLink) { + file.fullImage = $$1('.full-image', file.thumbLink); + } + file.videoControls = $$1('.video-controls', file.text); + if (file.videoThumb) { + file.thumb.muted = true; + } + this.files.push(file); + } + if (this.files.length) { + this.file = this.files[0]; + // Contract thumbnails in quote preview + if (this.file.thumb && contractThumb) { + ImageExpand.contract(this); + } + } + if (this.origin.isDead) { + this.isDead = true; + } + root.dataset.clone = this.origin.clones.push(this) - 1; + return this; + } + cloneWithoutVideo(node) { + if ((node.tagName === 'VIDEO') && !node.dataset.md5) { // (exception for WebM thumbnails) + return []; + } + else if ((node.nodeType === Node.ELEMENT_NODE) && $$1('video', node)) { + const clone = node.cloneNode(false); + for (var child of node.childNodes) { + $$1.add(clone, this.cloneWithoutVideo(child)); + } + return clone; + } + else { + return node.cloneNode(true); + } + } + } + PostClone.suffix = 0; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Menu = { + init() { + if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu']) { return; } + + this.button = $$1.el('a', { + className: 'menu-button', + href: 'javascript:;' + } + ); + + $$1.extend(this.button, {textContent: "🞃"}); + + this.menu = new UI.Menu('post'); + Callbacks.Post.push({ + name: 'Menu', + cb: this.node + }); + + return Callbacks.CatalogThread.push({ + name: 'Menu', + cb: this.catalogNode + }); + }, + + node() { + if (this.isClone) { + const button = $$1('.menu-button', this.nodes.info); + $$1.rmClass(button, 'active'); + $$1.rm($$1('.dialog', this.nodes.info)); + Menu.makeButton(this, button); + return; + } + return $$1.add(this.nodes.info, Menu.makeButton(this)); + }, + + catalogNode() { + return $$1.after(this.nodes.icons, Menu.makeButton(this.thread.OP)); + }, + + makeButton(post, button) { + if (!button) { button = Menu.button.cloneNode(true); } + $$1.on(button, 'click', function(e) { + return Menu.menu.toggle(e, this, post); + }); + return button; + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Recursive = { + recursives: dict(), + init() { + if (!['index', 'thread'].includes(g.VIEW)) { return; } + return Callbacks.Post.push({ + name: 'Recursive', + cb: this.node + }); + }, + + node() { + if (this.isClone || this.isFetchedQuote) { return; } + for (var quote of this.quotes) { + var obj; + if ((obj = Recursive.recursives[quote])) { + for (var i = 0; i < obj.recursives.length; i++) { + var recursive = obj.recursives[i]; + recursive(this, ...Array.from(obj.args[i])); + } + } + } + }, + + add(recursive, post, ...args) { + const obj = Recursive.recursives[post.fullID] || (Recursive.recursives[post.fullID] = { + recursives: [], + args: [] + }); + obj.recursives.push(recursive); + return obj.args.push(args); + }, + + rm(recursive, post) { + let obj; + if (!(obj = Recursive.recursives[post.fullID])) { return; } + for (let i = 0; i < obj.recursives.length; i++) { + var rec = obj.recursives[i]; + if (rec === recursive) { + obj.recursives.splice(i, 1); + obj.args.splice(i, 1); + } + } + }, + + apply(recursive, post, ...args) { + const {fullID} = post; + return g.posts.forEach(function(post) { + if (post.quotes.includes(fullID)) { + return recursive(post, ...Array.from(args)); + } + }); + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var PostHiding = { + init() { + if (!['index', 'thread'].includes(g.VIEW) || (!Conf['Reply Hiding Buttons'] && !(Conf['Menu'] && Conf['Reply Hiding Link']))) { return; } + + if (Conf['Reply Hiding Buttons']) { + $$1.addClass(doc$1, "reply-hide"); + } + + this.db = new DataBoard('hiddenPosts'); + return Callbacks.Post.push({ + name: 'Reply Hiding', + cb: this.node + }); + }, + + isHidden(boardID, threadID, postID) { + return !!(PostHiding.db && PostHiding.db.get({boardID, threadID, postID})); + }, + + node() { + let data, sa; + if (!this.isReply || this.isClone || this.isFetchedQuote) { return; } + + if (data = PostHiding.db.get({boardID: this.board.ID, threadID: this.thread.ID, postID: this.ID})) { + if (data.thisPost) { + PostHiding.hide(this, data.makeStub, data.hideRecursively); + } else { + Recursive.apply(PostHiding.hide, this, data.makeStub, true); + Recursive.add(PostHiding.hide, this, data.makeStub, true); + } + } + + if (!Conf['Reply Hiding Buttons']) { return; } + + const button = PostHiding.makeButton(this, 'hide'); + if (sa = g.SITE.selectors.sideArrows) { + const sideArrows = $$1(sa, this.nodes.root); + $$1.replace(sideArrows.firstChild, button); + return sideArrows.className = 'replacedSideArrows'; + } else { + return $$1.prepend(this.nodes.info, button); + } + }, + + menu: { + init() { + if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu'] || !Conf['Reply Hiding Link']) { return; } + + // Hide + let div = $$1.el('div', { + className: 'hide-reply-link', + textContent: 'Hide' + } + ); + + let apply = $$1.el('a', { + textContent: 'Apply', + href: 'javascript:;' + } + ); + $$1.on(apply, 'click', PostHiding.menu.hide); + + let thisPost = UI.checkbox('thisPost', 'This post', true); + let replies = UI.checkbox('replies', 'Hide replies', Conf['Recursive Hiding']); + const makeStub = UI.checkbox('makeStub', 'Make stub', Conf['Stubs']); + + Menu.menu.addEntry({ + el: div, + order: 20, + open(post) { + if (!post.isReply || post.isClone || post.isHidden) { + return false; + } + PostHiding.menu.post = post; + return true; + }, + subEntries: [ + {el: apply} + , + {el: thisPost} + , + {el: replies} + , + {el: makeStub} + ]}); + + // Show + div = $$1.el('div', { + className: 'show-reply-link', + textContent: 'Show' + } + ); + + apply = $$1.el('a', { + textContent: 'Apply', + href: 'javascript:;' + } + ); + $$1.on(apply, 'click', PostHiding.menu.show); + + thisPost = UI.checkbox('thisPost', 'This post', false); + replies = UI.checkbox('replies', 'Show replies', false); + const hideStubLink = $$1.el('a', { + textContent: 'Hide stub', + href: 'javascript:;' + } + ); + $$1.on(hideStubLink, 'click', PostHiding.menu.hideStub); + + Menu.menu.addEntry({ + el: div, + order: 20, + open(post) { + let data; + if (!post.isReply || post.isClone || !post.isHidden) { + return false; + } + if (!(data = PostHiding.db.get({boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID}))) { + return false; + } + PostHiding.menu.post = post; + thisPost.firstChild.checked = post.isHidden; + replies.firstChild.checked = (data?.hideRecursively != null) ? data.hideRecursively : Conf['Recursive Hiding']; + return true; + }, + subEntries: [ + {el: apply} + , + {el: thisPost} + , + {el: replies} + ]}); + + return Menu.menu.addEntry({ + el: hideStubLink, + order: 15, + open(post) { + if (!post.isReply || post.isClone || !post.isHidden) { + return false; + } + if (!(PostHiding.db.get({boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID}))) { + return false; + } + return PostHiding.menu.post = post; + } + }); + }, + + hide() { + const parent = this.parentNode; + const thisPost = $$1('input[name=thisPost]', parent).checked; + const replies = $$1('input[name=replies]', parent).checked; + const makeStub = $$1('input[name=makeStub]', parent).checked; + const {post} = PostHiding.menu; + if (thisPost) { + PostHiding.hide(post, makeStub, replies); + } else if (replies) { + Recursive.apply(PostHiding.hide, post, makeStub, true); + Recursive.add(PostHiding.hide, post, makeStub, true); + } else { + return; + } + PostHiding.saveHiddenState(post, true, thisPost, makeStub, replies); + return $$1.event('CloseMenu'); + }, + + show() { + let data; + const parent = this.parentNode; + const thisPost = $$1('input[name=thisPost]', parent).checked; + const replies = $$1('input[name=replies]', parent).checked; + const {post} = PostHiding.menu; + if (thisPost) { + PostHiding.show(post, replies); + } else if (replies) { + Recursive.apply(PostHiding.show, post, true); + Recursive.rm(PostHiding.hide, post, true); + } else { + return; + } + if (data = PostHiding.db.get({boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID})) { + PostHiding.saveHiddenState(post, !(thisPost && replies), !thisPost, data.makeStub, !replies); + } + return $$1.event('CloseMenu'); + }, + hideStub() { + let data; + const {post} = PostHiding.menu; + if (data = PostHiding.db.get({boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID})) { + PostHiding.show(post, data.hideRecursively); + PostHiding.hide(post, false, data.hideRecursively); + PostHiding.saveHiddenState(post, true, true, false, data.hideRecursively); + } + $$1.event('CloseMenu'); + } + }, + + makeButton(post, type) { + const span = $$1.el('span', { + textContent: type === 'hide' ? '➖︎' : '➕︎', + }); + const a = $$1.el('a', { + className: `${type}-reply-button`, + href: 'javascript:;' + } + ); + $$1.add(a, span); + $$1.on(a, 'click', PostHiding.toggle); + return a; + }, + + saveHiddenState(post, isHiding, thisPost, makeStub, hideRecursively) { + const data = { + boardID: post.board.ID, + threadID: post.thread.ID, + postID: post.ID + }; + if (isHiding) { + data.val = { + thisPost: thisPost !== false, // undefined -> true + makeStub, + hideRecursively + }; + return PostHiding.db.set(data); + } else { + return PostHiding.db.delete(data); + } + }, + + toggle() { + const post = Get$1.postFromNode(this); + PostHiding[(post.isHidden ? 'show' : 'hide')](post); + return PostHiding.saveHiddenState(post, post.isHidden); + }, + + hide(post, makeStub=Conf['Stubs'], hideRecursively=Conf['Recursive Hiding']) { + if (post.isHidden) { return; } + post.isHidden = true; + + if (hideRecursively) { + Recursive.apply(PostHiding.hide, post, makeStub, true); + Recursive.add(PostHiding.hide, post, makeStub, true); + } + + for (var quotelink of Get$1.allQuotelinksLinkingTo(post)) { + $$1.addClass(quotelink, 'filtered'); + } + + if (!makeStub) { + post.nodes.root.hidden = true; + return; + } + + const a = PostHiding.makeButton(post, 'show'); + $$1.add(a, $$1.tn(` ${post.info.nameBlock}`)); + post.nodes.stub = $$1.el('div', + {className: 'stub'}); + $$1.add(post.nodes.stub, a); + if (Conf['Menu']) { + $$1.add(post.nodes.stub, Menu.makeButton(post)); + } + return $$1.prepend(post.nodes.root, post.nodes.stub); + }, + + show(post, showRecursively=Conf['Recursive Hiding']) { + if (post.nodes.stub) { + $$1.rm(post.nodes.stub); + delete post.nodes.stub; + } else { + post.nodes.root.hidden = false; + } + post.isHidden = false; + if (showRecursively) { + Recursive.apply(PostHiding.show, post, true); + Recursive.rm(PostHiding.hide, post); + } + for (var quotelink of Get$1.allQuotelinksLinkingTo(post)) { + $$1.rmClass(quotelink, 'filtered'); + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var RelativeDates = { + INTERVAL: 30000, + + init() { + if ( + (['index', 'thread', 'archive'].includes(g.VIEW) && Conf['Relative Post Dates'] && !Conf['Relative Date Title']) || + Index$1.enabled + ) { + this.flush(); + $$1.on(d$1, 'visibilitychange PostsInserted', this.flush); + } + + if (Conf['Relative Post Dates']) { + return Callbacks.Post.push({ + name: 'Relative Post Dates', + cb: this.node + }); + } + }, + + node() { + if (!this.info.date) { return; } + const dateEl = this.nodes.date; + if (Conf['Relative Date Title']) { + $$1.on(dateEl, 'mouseover', () => RelativeDates.hover(this)); + return; + } + if (this.isClone) { return; } + + // Show original absolute time as tooltip so users can still know exact times + // Since "Time Formatting" runs its `node` before us, the title tooltip will + // pick up the user-formatted time instead of 4chan time when enabled. + dateEl.title = dateEl.textContent; + + return RelativeDates.update(this); + }, + + // diff is milliseconds from now. + relative(diff, now, date, abbrev) { + let number; + let unit = (() => { + if ((number = (diff / DAY)) >= 1) { + const years = now.getFullYear() - date.getFullYear(); + let months = now.getMonth() - date.getMonth(); + const days = now.getDate() - date.getDate(); + if (years > 1) { + number = years - ((months < 0) || ((months === 0) && (days < 0))); + return 'year'; + } else if ((years === 1) && ((months > 0) || ((months === 0) && (days >= 0)))) { + number = years; + return 'year'; + } else if ((months = months + (12*years)) > 1) { + number = months - (days < 0); + return 'month'; + } else if ((months === 1) && (days >= 0)) { + number = months; + return 'month'; + } else { + return 'day'; + } + } else if ((number = (diff / HOUR)) >= 1) { + return 'hour'; + } else if ((number = (diff / MINUTE)) >= 1) { + return 'minute'; + } else { + // prevent "-1 seconds ago" + number = Math.max(0, diff) / SECOND; + return 'second'; + } + })(); + + const rounded = Math.round(number); + + if (abbrev) { + unit = unit === 'month' ? 'mo' : unit[0]; + } else { + if (rounded !== 1) { unit += 's'; } // pluralize + } + + if (abbrev) { return `${rounded}${unit}`; } else { return `${rounded} ${unit} ago`; } + }, + + // Changing all relative dates as soon as possible incurs many annoying + // redraws and scroll stuttering. Thus, sacrifice accuracy for UX/CPU economy, + // and perform redraws when the DOM is otherwise being manipulated (and scroll + // stuttering won't be noticed), falling back to INTERVAL while the page + // is visible. + // + // Each individual dateTime element will add its update() function to the stale list + // when it is to be called. + stale: [], + flush() { + // No point in changing the dates until the user sees them. + if (d$1.hidden) { return; } + + const now = new Date(); + for (var data of RelativeDates.stale) { RelativeDates.update(data, now); } + RelativeDates.stale = []; + + // Reset automatic flush. + clearTimeout(RelativeDates.timeout); + return RelativeDates.timeout = setTimeout(RelativeDates.flush, RelativeDates.INTERVAL); + }, + + hover(post) { + const { + date + } = post.info; + const now = new Date(); + const diff = now - date; + return post.nodes.date.title = RelativeDates.relative(diff, now, date); + }, + + // `update()`, when called from `flush()`, updates the elements, + // and re-calls `setOwnTimeout()` to re-add `data` to the stale list later. + update(data, now) { + let abbrev, date; + const isPost = data instanceof Post; + if (isPost) { + ({ + date + } = data.info); + abbrev = false; + } else { + date = new Date(+data.dataset.utc); + abbrev = !!data.dataset.abbrev; + } + if (!now) { now = new Date(); } + const diff = now - date; + const relative = RelativeDates.relative(diff, now, date, abbrev); + if (isPost) { + for (var singlePost of [data].concat(data.clones)) { + singlePost.nodes.date.firstChild.textContent = relative; + } + } else { + data.firstChild.textContent = relative; + } + return RelativeDates.setOwnTimeout(diff, data); + }, + + setOwnTimeout(diff, data) { + const delay = diff < MINUTE ? + SECOND - ((diff + (SECOND / 2)) % SECOND) + : diff < HOUR ? + MINUTE - ((diff + (MINUTE / 2)) % MINUTE) + : diff < DAY ? + HOUR - ((diff + (HOUR / 2)) % HOUR) + : + DAY - ((diff + (DAY / 2)) % DAY); + return setTimeout(RelativeDates.markStale, delay, data); + }, + + markStale(data) { + if (RelativeDates.stale.includes(data)) { return; } // We can call RelativeDates.update() multiple times. + if (data instanceof Post && !g.posts.get(data.fullID)) { return; } // collected post. + if (data instanceof Element && !doc$1.contains(data)) { return; } // removed catalog reply. + return RelativeDates.stale.push(data); + } + }; + + var ThreadWatcherPage = `
        + Thread Watcher 🗘 + + 🞃 + × +
        +
        +`; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS104: Avoid inline assignments + * DS205: Consider reworking code to avoid use of IIFEs + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var BoardConfig = { + cbs: [], + + init() { + let middle; + if (g.SITE.software !== 'yotsuba') { return; } + const now = Date.now(); + if (now - (2 * HOUR) >= ((middle = Conf['boardConfig'].lastChecked || 0)) || middle > now) { + return $$1.ajax(`${location.protocol}//a.4cdn.org/boards.json`, + {onloadend: this.load}); + } else { + const {boards} = Conf['boardConfig']; + return this.set(boards); + } + }, + + load() { + let boards; + if ((this.status === 200) && this.response && this.response.boards) { + boards = dict(); + for (var board of this.response.boards) { + boards[board.board] = board; + } + $$1.set('boardConfig', {boards, lastChecked: Date.now()}); + } else { + ({boards} = Conf['boardConfig']); + const err = (() => { switch (this.status) { + case 0: return 'Connection Error'; + case 200: return 'Invalid Data'; + default: return `Error ${this.statusText} (${this.status})`; + } })(); + new Notice('warning', `Failed to load board configuration. ${err}`, 20); + } + return BoardConfig.set(boards); + }, + + set(boards) { + this.boards = boards; + for (var ID in g.boards) { + var board = g.boards[ID]; + board.config = this.boards[ID] || {}; + } + for (var cb of this.cbs) { + $$1.queueTask(cb); + } + }, + + ready(cb) { + if (this.boards) { + return cb(); + } else { + return this.cbs.push(cb); + } + }, + + sfwBoards(sfw) { + return (() => { + const result = []; + const object = this.boards || Conf['boardConfig'].boards; + for (var board in object) { + var data = object[board]; + if (!!data.ws_board === sfw) { + result.push(board); + } + } + return result; + })(); + }, + + isSFW(board) { + return !!(this.boards || Conf['boardConfig'].boards)[board]?.ws_board; + }, + + domain(board) { + return `boards.${BoardConfig.isSFW(board) ? '4channel' : '4chan'}.org`; + }, + + isArchived(board) { + // assume archive exists if no data available to prevent cleaning of archived threads + const data = (this.boards || Conf['boardConfig'].boards)[board]; + return !data || data.is_archived; + }, + + noAudio(boardID) { + if (g.SITE.software !== 'yotsuba') { return false; } + const boards = this.boards || Conf['boardConfig'].boards; + return boards && boards[boardID] && !boards[boardID].webm_audio; + }, + + title(boardID) { + return (this.boards || Conf['boardConfig'].boards)?.[boardID]?.title || ''; + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class Board { + toString() { return this.ID; } + + constructor(ID) { + this.ID = ID; + this.boardID = this.ID; + this.siteID = g.SITE.ID; + this.threads = new SimpleDict(); + this.posts = new SimpleDict(); + this.config = BoardConfig.boards?.[this.ID] || {}; + + g.boards[this] = this; + } + + cooldowns() { + const c2 = (this.config || {}).cooldowns || {}; + const c = { + thread: c2.threads || 0, + reply: c2.replies || 0, + image: c2.images || 0, + thread_global: 300 // inter-board thread cooldown + }; + // Pass users have reduced cooldowns. + if (d$1.cookie.indexOf('pass_enabled=1') >= 0) { + for (var key of ['reply', 'image']) { + c[key] = Math.ceil(c[key] / 2); + } + } + return c; + } + } + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const PostRedirect = { + init() { + return $$1.on(d$1, 'QRPostSuccessful', e => { + if (!e.detail.redirect) { return; } + this.event = e; + this.delays = 0; + return $$1.queueTask(() => { + if ((e === this.event) && (this.delays === 0)) { + return location.href = e.detail.redirect; + } + }); + }); + }, + + delays: 0, + + delay() { + if (!this.event) { return null; } + const e = this.event; + this.delays++; + return () => { + if (e !== this.event) { return; } + this.delays--; + if (this.delays === 0) { + return location.href = e.detail.redirect; + } + }; + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ExpandComment = { + init() { + if ((g.VIEW !== 'index') || !Conf['Comment Expansion'] || Conf['JSON Index']) { return; } + + return Callbacks.Post.push({ + name: 'Comment Expansion', + cb: this.node + }); + }, + + node() { + let a; + if (a = $$1('.abbr > a:not([onclick])', this.nodes.comment)) { + return $$1.on(a, 'click', ExpandComment.cb); + } + }, + + callbacks: [], + + cb(e) { + e.preventDefault(); + return ExpandComment.expand(Get$1.postFromNode(this)); + }, + + expand(post) { + let a; + if (post.nodes.longComment && !post.nodes.longComment.parentNode) { + $$1.replace(post.nodes.shortComment, post.nodes.longComment); + post.nodes.comment = post.nodes.longComment; + return; + } + if (!(a = $$1('.abbr > a', post.nodes.comment))) { return; } + a.textContent = `Post No.${post} Loading...`; + return $$1.cache(g.SITE.urls.threadJSON({boardID: post.boardID, threadID: post.threadID}), function() { return ExpandComment.parse(this, a, post); }); + }, + + contract(post) { + if (!post.nodes.shortComment) { return; } + const a = $$1('.abbr > a', post.nodes.shortComment); + a.textContent = 'here'; + $$1.replace(post.nodes.longComment, post.nodes.shortComment); + return post.nodes.comment = post.nodes.shortComment; + }, + + parse(req, a, post) { + let postObj, spoilerRange; + const {status} = req; + if (![200, 304].includes(status)) { + a.textContent = status ? `Error ${req.statusText} (${status})` : 'Connection Error'; + return; + } + + const { + posts + } = req.response; + if (spoilerRange = posts[0].custom_spoiler) { + g.SITE.Build.spoilerRange[g.BOARD] = spoilerRange; + } + + for (postObj of posts) { + if (postObj.no === post.ID) { break; } + } + if (postObj.no !== post.ID) { + a.textContent = `Post No.${post} not found.`; + return; + } + + const {comment} = post.nodes; + const clone = comment.cloneNode(false); + clone.innerHTML = postObj.com; + // Fix pathnames + for (var quote of $$('.quotelink', clone)) { + var href = quote.getAttribute('href'); + if (href[0] === '/') { continue; } // Cross-board quote, or board link + if (href[0] === '#') { + quote.href = `${a.pathname.split(/\/+/).splice(0,4).join('/')}${href}`; + } else { + quote.href = `${a.pathname.split(/\/+/).splice(0,3).join('/')}/${href}`; + } + } + post.nodes.shortComment = comment; + $$1.replace(comment, clone); + post.nodes.comment = (post.nodes.longComment = clone); + post.parseComment(); + post.parseQuotes(); + + for (var callback of ExpandComment.callbacks) { + callback.call(post); + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var QuoteYou = { + init() { + if (!Conf['Remember Your Posts']) { return; } + + this.db = new DataBoard('yourPosts'); + $$1.sync('Remember Your Posts', enabled => Conf['Remember Your Posts'] = enabled); + $$1.on(d$1, 'QRPostSuccessful', function(e) { + const cb = PostRedirect.delay(); + return $$1.get('Remember Your Posts', Conf['Remember Your Posts'], function(items) { + if (!items['Remember Your Posts']) { return; } + const {boardID, threadID, postID} = e.detail; + return QuoteYou.db.set({boardID, threadID, postID, val: true}, cb); + }); + }); + + if (!['index', 'thread', 'archive'].includes(g.VIEW)) { return; } + + if (Conf['Highlight Own Posts']) { + $$1.addClass(doc$1, 'highlight-own'); + } + + if (Conf['Highlight Posts Quoting You']) { + $$1.addClass(doc$1, 'highlight-you'); + } + + if (Conf['Comment Expansion']) { + ExpandComment.callbacks.push(this.node); + } + + // \u00A0 is nbsp + this.mark = $$1.el('span', { + textContent: '\u00A0(You)', + className: 'qmark-you' + } + ); + Callbacks.Post.push({ + name: 'Mark Quotes of You', + cb: this.node + }); + + return QuoteYou.menu.init(); + }, + + isYou(post) { + return !!QuoteYou.db?.get({ + boardID: post.boardID, + threadID: post.threadID, + postID: post.ID + }); + }, + + node() { + if (this.isClone) { return; } + + if (QuoteYou.isYou(this)) { + $$1.addClass(this.nodes.root, 'yourPost'); + } + + // Stop there if there's no quotes in that post. + if (!this.quotes.length) { return; } + + for (var quotelink of this.nodes.quotelinks) { + if (QuoteYou.db.get(Get$1.postDataFromLink(quotelink))) { + if (Conf['Mark Quotes of You']) { $$1.add(quotelink, QuoteYou.mark.cloneNode(true)); } + $$1.addClass(quotelink, 'you'); + $$1.addClass(this.nodes.root, 'quotesYou'); + } + } + }, + + menu: { + init() { + const label = $$1.el('label', + {className: 'toggle-you'} + , + {innerHTML: ' You'}); + const input = $$1('input', label); + $$1.on(input, 'change', QuoteYou.menu.toggle); + return Menu.menu?.addEntry({ + el: label, + order: 80, + open(post) { + QuoteYou.menu.post = (post.origin || post); + input.checked = QuoteYou.isYou(post); + return true; + } + }); + }, + + toggle() { + const {post} = QuoteYou.menu; + const data = {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID, val: true}; + if (this.checked) { + QuoteYou.db.set(data); + } else { + QuoteYou.db.delete(data); + } + for (var clone of [post].concat(post.clones)) { + clone.nodes.root.classList.toggle('yourPost', this.checked); + } + for (var quotelink of Get$1.allQuotelinksLinkingTo(post)) { + if (this.checked) { + if (Conf['Mark Quotes of You']) { $$1.add(quotelink, QuoteYou.mark.cloneNode(true)); } + } else { + $$1.rm($$1('.qmark-you', quotelink)); + } + quotelink.classList.toggle('you', this.checked); + if ($$1.hasClass(quotelink, 'quotelink')) { + var quoter = Get$1.postFromNode(quotelink).nodes.root; + quoter.classList.toggle('quotesYou', !!$$1('.quotelink.you', quoter)); + } + } + } + }, + + cb: { + seek(type) { + let highlighted, post; + let result; + const {highlight} = g.SITE.classes; + if (highlighted = $$1(`.${highlight}`)) { $$1.rmClass(highlighted, highlight); } + + if (!QuoteYou.lastRead || !doc$1.contains(QuoteYou.lastRead) || !$$1.hasClass(QuoteYou.lastRead, 'quotesYou')) { + if (!(post = (QuoteYou.lastRead = $$1('.quotesYou')))) { + new Notice('warning', 'No posts are currently quoting you, loser.', 20); + return; + } + if (QuoteYou.cb.scroll(post)) { return; } + } else { + post = QuoteYou.lastRead; + } + + const str = `${type}::div[contains(@class,'quotesYou')]`; + + while (post = (result = $$1.X(str, post)).snapshotItem(type === 'preceding' ? result.snapshotLength - 1 : 0)) { + if (QuoteYou.cb.scroll(post)) { return; } + } + + const posts = $$('.quotesYou'); + return QuoteYou.cb.scroll(posts[type === 'following' ? 0 : posts.length - 1]); + }, + + scroll(root) { + const post = Get$1.postFromRoot(root); + if (!post.nodes.post.getBoundingClientRect().height) { + return false; + } else { + QuoteYou.lastRead = root; + location.href = Get$1.url('post', post); + Header$1.scrollTo(post.nodes.post); + if (post.isReply) { + const sel = `${g.SITE.selectors.postContainer}${g.SITE.selectors.highlightable.reply}`; + let node = post.nodes.root; + if (!node.matches(sel)) { node = $$1(sel, node); } + $$1.addClass(node, g.SITE.classes.highlight); + } + return true; + } + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class RandomAccessList { + constructor(items) { + this.length = 0; + if (items) { for (var item of items) { this.push(item); } } + } + + push(data) { + let item; + let {ID} = data; + if (!ID) { ID = data.id; } + if (this[ID]) { return; } + const {last} = this; + this[ID] = (item = { + prev: last, + next: null, + data, + ID + }); + item.prev = last; + this.last = last ? + (last.next = item) + : + (this.first = item); + return this.length++; + } + + before(root, item) { + if ((item.next === root) || (item === root)) { return; } + + this.rmi(item); + + const {prev} = root; + root.prev = item; + item.next = root; + item.prev = prev; + if (prev) { + return prev.next = item; + } else { + return this.first = item; + } + } + + after(root, item) { + if ((item.prev === root) || (item === root)) { return; } + + this.rmi(item); + + const {next} = root; + root.next = item; + item.prev = root; + item.next = next; + if (next) { + return next.prev = item; + } else { + return this.last = item; + } + } + + prepend(item) { + const {first} = this; + if ((item === first) || !this[item.ID]) { return; } + this.rmi(item); + item.next = first; + if (first) { + first.prev = item; + } else { + this.last = item; + } + this.first = item; + return delete item.prev; + } + + shift() { + return this.rm(this.first.ID); + } + + order() { + let item; + const order = [(item = this.first)]; + while ((item = item.next)) { order.push(item); } + return order; + } + + rm(ID) { + const item = this[ID]; + if (!item) { return; } + delete this[ID]; + this.length--; + this.rmi(item); + delete item.next; + return delete item.prev; + } + + rmi(item) { + const {prev, next} = item; + if (prev) { + prev.next = next; + } else { + this.first = next; + } + if (next) { + return next.prev = prev; + } else { + return this.last = prev; + } + } + } + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Unread = { + init() { + if ((g.VIEW !== 'thread') || ( + !Conf['Unread Count'] && + !Conf['Unread Favicon'] && + !Conf['Unread Line'] && + !Conf['Remember Last Read Post'] && + !Conf['Desktop Notifications'] && + !Conf['Quote Threading'] + )) { return; } + + if (Conf['Remember Last Read Post']) { + $$1.sync('Remember Last Read Post', enabled => Conf['Remember Last Read Post'] = enabled); + this.db = new DataBoard('lastReadPosts', this.sync); + } + + this.hr = $$1.el('hr', { + id: 'unread-line', + className: 'unread-line' + } + ); + this.posts = new Set(); + this.postsQuotingYou = new Set(); + this.order = new RandomAccessList(); + this.position = null; + + Callbacks.Thread.push({ + name: 'Unread', + cb: this.node + }); + + return Callbacks.Post.push({ + name: 'Unread', + cb: this.addPost + }); + }, + + node() { + Unread.thread = this; + Unread.title = d$1.title; + Unread.lastReadPost = Unread.db?.get({ + boardID: this.board.ID, + threadID: this.ID + }) || 0; + Unread.readCount = 0; + for (var ID of this.posts.keys) { if (+ID <= Unread.lastReadPost) { Unread.readCount++; } } + $$1.one(d$1, '4chanXInitFinished', Unread.ready); + $$1.on(d$1, 'PostsInserted', Unread.onUpdate); + $$1.on(d$1, 'ThreadUpdate', function(e) { if (e.detail[404]) { return Unread.update(); } }); + const resetLink = $$1.el('a', { + href: 'javascript:;', + className: 'unread-reset', + textContent: 'Mark all unread' + } + ); + $$1.on(resetLink, 'click', Unread.reset); + return Header$1.menu.addEntry({ + el: resetLink, + order: 70 + }); + }, + + ready() { + if (Conf['Remember Last Read Post'] && Conf['Scroll to Last Read Post']) { Unread.scroll(); } + Unread.setLine(true); + Unread.read(); + Unread.update(); + $$1.on(d$1, 'scroll visibilitychange', Unread.read); + if (Conf['Unread Line']) { return $$1.on(d$1, 'visibilitychange', Unread.setLine); } + }, + + positionPrev() { + if (Unread.position) { return Unread.position.prev; } else { return Unread.order.last; } + }, + + scroll() { + // Let the header's onload callback handle it. + let hash; + if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { return; } + + let position = Unread.positionPrev(); + while (position) { + var {bottom} = position.data.nodes; + if (!bottom.getBoundingClientRect().height) { + // Don't try to scroll to posts with display: none + position = position.prev; + } else { + Header$1.scrollToIfNeeded(bottom, true); + break; + } + } + }, + + reset() { + if (Unread.lastReadPost == null) { return; } + + Unread.posts = new Set(); + Unread.postsQuotingYou = new Set(); + Unread.order = new RandomAccessList(); + Unread.position = null; + Unread.lastReadPost = 0; + Unread.readCount = 0; + Unread.thread.posts.forEach(post => Unread.addPost.call(post)); + + $$1.forceSync('Remember Last Read Post'); + if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) { + Unread.db.set({ + boardID: Unread.thread.board.ID, + threadID: Unread.thread.ID, + val: 0 + }); + } + + Unread.updatePosition(); + Unread.setLine(); + return Unread.update(); + }, + + sync() { + if (Unread.lastReadPost == null) { return; } + const lastReadPost = Unread.db.get({ + boardID: Unread.thread.board.ID, + threadID: Unread.thread.ID, + defaultValue: 0 + }); + if (Unread.lastReadPost >= lastReadPost) { return; } + Unread.lastReadPost = lastReadPost; + + const postIDs = Unread.thread.posts.keys; + for (let i = Unread.readCount, end = postIDs.length; i < end; i++) { + var ID = +postIDs[i]; + if (!Unread.thread.posts.get(ID).isFetchedQuote) { + if (ID > Unread.lastReadPost) { break; } + Unread.posts.delete(ID); + Unread.postsQuotingYou.delete(ID); + } + Unread.readCount++; + } + + Unread.updatePosition(); + Unread.setLine(); + return Unread.update(); + }, + + addPost() { + if (this.isFetchedQuote || this.isClone) { return; } + Unread.order.push(this); + if ((this.ID <= Unread.lastReadPost) || this.isHidden || QuoteYou.isYou(this)) { return; } + Unread.posts.add((Unread.posts.last = this.ID)); + Unread.addPostQuotingYou(this); + return Unread.position != null ? Unread.position : (Unread.position = Unread.order[this.ID]); + }, + + addPostQuotingYou(post) { + for (var quotelink of post.nodes.quotelinks) { + if (QuoteYou.db?.get(Get$1.postDataFromLink(quotelink))) { + Unread.postsQuotingYou.add((Unread.postsQuotingYou.last = post.ID)); + Unread.openNotification(post); + return; + } + } + }, + + openNotification(post, predicate=' replied to you') { + if (!Header$1.areNotificationsEnabled) { return; } + const notif = new Notification(`${post.info.nameBlock}${predicate}`, { + body: post.commentDisplay(), + icon: Favicon.logo + } + ); + notif.onclick = function() { + Header$1.scrollToIfNeeded(post.nodes.bottom, true); + return window.focus(); + }; + return notif.onshow = () => setTimeout(() => notif.close() + , 7 * SECOND); + }, + + onUpdate() { + return $$1.queueTask(function() { // ThreadUpdater may scroll immediately after inserting posts + Unread.setLine(); + Unread.read(); + return Unread.update(); + }); + }, + + readSinglePost(post) { + const {ID} = post; + if (!Unread.posts.has(ID)) { return; } + Unread.posts.delete(ID); + Unread.postsQuotingYou.delete(ID); + Unread.updatePosition(); + Unread.saveLastReadPost(); + return Unread.update(); + }, + + read: debounce(100, function(e) { + // Update the lastReadPost when hidden posts are added to the thread. + if (!Unread.posts.size && (Unread.readCount !== Unread.thread.posts.keys.length)) { + Unread.saveLastReadPost(); + } + + if (d$1.hidden || !Unread.posts.size) { return; } + + let count = 0; + while (Unread.position) { + var {ID, data} = Unread.position; + var {bottom} = data.nodes; + if (!!bottom.getBoundingClientRect().height && // post has been hidden + (Header$1.getBottomOf(bottom) <= -1)) { break; } // post is completely read + count++; + Unread.posts.delete(ID); + Unread.postsQuotingYou.delete(ID); + Unread.position = Unread.position.next; + } + + if (!count) { return; } + Unread.updatePosition(); + Unread.saveLastReadPost(); + if (e) { return Unread.update(); } + }), + + updatePosition() { + while (Unread.position && !Unread.posts.has(Unread.position.ID)) { + Unread.position = Unread.position.next; + } + }, + + saveLastReadPost: debounce(2 * SECOND, function() { + let ID; + $$1.forceSync('Remember Last Read Post'); + if (!Conf['Remember Last Read Post'] || !Unread.db) { return; } + const postIDs = Unread.thread.posts.keys; + for (let i = Unread.readCount, end = postIDs.length; i < end; i++) { + ID = +postIDs[i]; + if (!Unread.thread.posts.get(ID).isFetchedQuote) { + if (Unread.posts.has(ID)) { break; } + Unread.lastReadPost = ID; + } + Unread.readCount++; + } + if (Unread.thread.isDead && !Unread.thread.isArchived) { return; } + return Unread.db.set({ + boardID: Unread.thread.board.ID, + threadID: Unread.thread.ID, + val: Unread.lastReadPost + }); + }), + + setLine(force) { + if (!Conf['Unread Line']) { return; } + if (Unread.hr.hidden || d$1.hidden || (force === true)) { + const oldPosition = Unread.linePosition; + if (Unread.linePosition = Unread.positionPrev()) { + if (Unread.linePosition !== oldPosition) { + let node = Unread.linePosition.data.nodes.bottom; + if (node.nextSibling?.tagName === 'BR') { node = node.nextSibling; } + $$1.after(node, Unread.hr); + } + } else { + $$1.rm(Unread.hr); + } + } + return Unread.hr.hidden = Unread.linePosition === Unread.order.last; + }, + + update() { + const count = Unread.posts.size; + const countQuotingYou = Unread.postsQuotingYou.size; + + if (Conf['Unread Count']) { + const titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : ''; + const titleCount = count || !Conf['Hide Unread Count at (0)'] ? `(${count}) ` : ''; + const titleDead = Unread.thread.isDead ? + Unread.title.replace('-', (Unread.thread.isArchived ? '- Archived -' : '- 404 -')) + : + Unread.title; + d$1.title = `${titleQuotingYou}${titleCount}${titleDead}`; + } + + Unread.saveThreadWatcherCount(); + + if (Conf['Unread Favicon'] && (g.SITE.software === 'yotsuba')) { + const {isDead} = Unread.thread; + return Favicon.set(( + countQuotingYou ? + (isDead ? 'unreadDeadY' : 'unreadY') + : count ? + (isDead ? 'unreadDead' : 'unread') + : + (isDead ? 'dead' : 'default') + ) + ); + } + }, + + saveThreadWatcherCount: debounce(2 * SECOND, function() { + $$1.forceSync('Remember Last Read Post'); + if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) { + let posts; + const quotingYou = !Conf['Require OP Quote Link'] && QuoteYou.isYou(Unread.thread.OP) ? Unread.posts : Unread.postsQuotingYou; + if (!quotingYou.size) { + quotingYou.last = 0; + } else if (!quotingYou.has(quotingYou.last)) { + quotingYou.last = 0; + posts = Unread.thread.posts.keys; + for (let i = posts.length - 1; i >= 0; i--) { + if (quotingYou.has(+posts[i])) { + quotingYou.last = posts[i]; + break; + } + } + } + return ThreadWatcher$1.update(g.SITE.ID, Unread.thread.board.ID, Unread.thread.ID, { + last: Unread.thread.lastPost, + isDead: Unread.thread.isDead, + isArchived: Unread.thread.isArchived, + unread: Unread.posts.size, + quotingYou: (quotingYou.last || 0) + } + ); + } + }) + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ExpandThread = { + statuses: dict(), + init() { + if (!((g.VIEW === 'index') && Conf['Thread Expansion'])) { return; } + if (Conf['JSON Index']) { + return $$1.on(d$1, 'IndexRefreshInternal', this.onIndexRefresh); + } else { + return Callbacks.Thread.push({ + name: 'Expand Thread', + cb() { return ExpandThread.setButton(this); } + }); + } + }, + + setButton(thread) { + let a; + if (!(thread.nodes.root && (a = $$1('.summary', thread.nodes.root)))) { return; } + a.textContent = g.SITE.Build.summaryText('+', ...Array.from(a.textContent.match(/\d+/g))); + a.style.cursor = 'pointer'; + return $$1.on(a, 'click', ExpandThread.cbToggle); + }, + + disconnect(refresh) { + if ((g.VIEW === 'thread') || !Conf['Thread Expansion']) { return; } + for (var threadID in ExpandThread.statuses) { + var oldReq; + var status = ExpandThread.statuses[threadID]; + if (oldReq = status.req) { + delete status.req; + oldReq.abort(); + } + delete ExpandThread.statuses[threadID]; + } + + if (!refresh) { return $$1.off(d$1, 'IndexRefreshInternal', this.onIndexRefresh); } + }, + + onIndexRefresh() { + ExpandThread.disconnect(true); + return g.BOARD.threads.forEach(thread => ExpandThread.setButton(thread)); + }, + + cbToggle(e) { + if ($$1.modifiedClick(e)) { return; } + e.preventDefault(); + return ExpandThread.toggle(Get$1.threadFromNode(this)); + }, + + cbToggleBottom(e) { + if ($$1.modifiedClick(e)) { return; } + e.preventDefault(); + const thread = Get$1.threadFromNode(this); + $$1.rm(this); // remove before fixing bottom of thread position + const {bottom} = thread.nodes.root.getBoundingClientRect(); + ExpandThread.toggle(thread); + return window.scrollBy(0, (thread.nodes.root.getBoundingClientRect().bottom - bottom)); + }, + + toggle(thread) { + let a; + if (!(thread.nodes.root && (a = $$1('.summary', thread.nodes.root)))) { return; } + if (thread.ID in ExpandThread.statuses) { + return ExpandThread.contract(thread, a, thread.nodes.root); + } else { + return ExpandThread.expand(thread, a); + } + }, + + expand(thread, a) { + let status; + ExpandThread.statuses[thread] = (status = {}); + a.textContent = g.SITE.Build.summaryText('...', ...Array.from(a.textContent.match(/\d+/g))); + status.req = $$1.cache(g.SITE.urls.threadJSON({boardID: thread.board.ID, threadID: thread.ID}), function() { + if (this !== status.req) { return; } // aborted + delete status.req; + return ExpandThread.parse(this, thread, a); + }); + return status.numReplies = $$(g.SITE.selectors.replyOriginal, thread.nodes.root).length; + }, + + contract(thread, a, threadRoot) { + let oldReq; + const status = ExpandThread.statuses[thread]; + delete ExpandThread.statuses[thread]; + if (oldReq = status.req) { + delete status.req; + oldReq.abort(); + if (a) { a.textContent = g.SITE.Build.summaryText('+', ...Array.from(a.textContent.match(/\d+/g))); } + return; + } + + let replies = $$('.thread > .replyContainer', threadRoot); + if (status.numReplies) { replies = replies.slice(0, (-status.numReplies)); } + let postsCount = 0; + let filesCount = 0; + for (var reply of replies) { + // rm clones + if (Conf['Quote Inlining']) { var inlined; + while ((inlined = $$1('.inlined', reply))) { inlined.click(); } } + postsCount++; + if ('file' in Get$1.postFromRoot(reply)) { filesCount++; } + $$1.rm(reply); + } + if (Index$1.enabled) { // otherwise handled by Main.addPosts + $$1.event('PostsRemoved', null, a.parentNode); + } + a.textContent = g.SITE.Build.summaryText('+', postsCount, filesCount); + return $$1.rm($$1('.summary-bottom', threadRoot)); + }, + + parse(req, thread, a) { + let root; + if (![200, 304].includes(req.status)) { + a.textContent = req.status ? `Error ${req.statusText} (${req.status})` : 'Connection Error'; + return; + } + + g.SITE.Build.spoilerRange[thread.board] = req.response.posts[0].custom_spoiler; + + const posts = []; + const postsRoot = []; + let filesCount = 0; + for (var postData of req.response.posts) { + var post; + if (postData.no === thread.ID) { continue; } + if ((post = thread.posts.get(postData.no)) && !post.isFetchedQuote) { + if ('file' in post) { filesCount++; } + ({root} = post.nodes); + postsRoot.push(root); + continue; + } + root = g.SITE.Build.postFromObject(postData, thread.board.ID); + post = new Post(root, thread, thread.board); + if ('file' in post) { filesCount++; } + posts.push(post); + postsRoot.push(root); + } + Main$1.callbackNodes('Post', posts); + $$1.after(a, postsRoot); + $$1.event('PostsInserted', null, a.parentNode); + + const postsCount = postsRoot.length; + a.textContent = g.SITE.Build.summaryText('-', postsCount, filesCount); + + if (root) { + const a2 = a.cloneNode(true); + a2.classList.add('summary-bottom'); + $$1.on(a2, 'click', ExpandThread.cbToggleBottom); + return $$1.after(root, a2); + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var UnreadIndex = { + lastReadPost: dict(), + hr: dict(), + markReadLink: dict(), + + init() { + if ((g.VIEW !== 'index') || !Conf['Remember Last Read Post'] || !Conf['Unread Line in Index']) { return; } + + this.enabled = true; + this.db = new DataBoard('lastReadPosts', this.sync); + + Callbacks.Thread.push({ + name: 'Unread Line in Index', + cb: this.node + }); + + $$1.on(d$1, 'IndexRefreshInternal', this.onIndexRefresh); + return $$1.on(d$1, 'PostsInserted PostsRemoved', this.onPostsInserted); + }, + + node() { + UnreadIndex.lastReadPost[this.fullID] = UnreadIndex.db.get({ + boardID: this.board.ID, + threadID: this.ID + }) || 0; + if (!Index$1.enabled) { // let onIndexRefresh handle JSON Index + return UnreadIndex.update(this); + } + }, + + onIndexRefresh(e) { + if (e.detail.isCatalog) { return; } + return (() => { + const result = []; + for (var threadID of e.detail.threadIDs) { + var thread = g.threads.get(threadID); + result.push(UnreadIndex.update(thread)); + } + return result; + })(); + }, + + onPostsInserted(e) { + if (e.target === Index$1.root) { return; } // onIndexRefresh handles this case + const thread = Get$1.threadFromNode(e.target); + if (!thread || (thread.nodes.root !== e.target)) { return; } + const wasVisible = !!UnreadIndex.hr[thread.fullID]?.parentNode; + UnreadIndex.update(thread); + if (Conf['Scroll to Last Read Post'] && (e.type === 'PostsInserted') && !wasVisible && !!UnreadIndex.hr[thread.fullID]?.parentNode) { + return Header$1.scrollToIfNeeded(UnreadIndex.hr[thread.fullID], true); + } + }, + + sync() { + return g.threads.forEach(function(thread) { + const lastReadPost = UnreadIndex.db.get({ + boardID: thread.board.ID, + threadID: thread.ID + }) || 0; + if (lastReadPost !== UnreadIndex.lastReadPost[thread.fullID]) { + UnreadIndex.lastReadPost[thread.fullID] = lastReadPost; + if (thread.nodes.root?.parentNode) { + return UnreadIndex.update(thread); + } + } + }); + }, + + update(thread) { + let divider; + const lastReadPost = UnreadIndex.lastReadPost[thread.fullID]; + let repliesShown = 0; + let repliesRead = 0; + let firstUnread = null; + thread.posts.forEach(function(post) { + if (post.isReply && thread.nodes.root.contains(post.nodes.root)) { + repliesShown++; + if (post.ID <= lastReadPost) { + return repliesRead++; + } else if ((!firstUnread || (post.ID < firstUnread.ID)) && !post.isHidden && !QuoteYou.isYou(post)) { + return firstUnread = post; + } + } + }); + + let hr = UnreadIndex.hr[thread.fullID]; + if (firstUnread && (repliesRead || ((lastReadPost === thread.OP.ID) && (!$$1(g.SITE.selectors.summary, thread.nodes.root) || thread.ID in ExpandThread.statuses)))) { + if (!hr) { + hr = (UnreadIndex.hr[thread.fullID] = $$1.el('hr', + {className: 'unread-line'})); + } + $$1.before(firstUnread.nodes.root, hr); + } else { + $$1.rm(hr); + } + + const hasUnread = repliesShown ? + firstUnread || !repliesRead + : Index$1.enabled ? + thread.lastPost > lastReadPost + : + thread.OP.ID > lastReadPost; + thread.nodes.root.classList.toggle('unread-thread', hasUnread); + + let link = UnreadIndex.markReadLink[thread.fullID]; + if (!link) { + link = (UnreadIndex.markReadLink[thread.fullID] = $$1.el('a', { + className: 'unread-mark-read brackets-wrap', + href: 'javascript:;', + textContent: 'Mark Read' + } + )); + $$1.on(link, 'click', UnreadIndex.markRead); + } + if (divider = $$1(g.SITE.selectors.threadDivider, thread.nodes.root)) { // divider inside thread as in Tinyboard + return $$1.before(divider, link); + } else { + return $$1.add(thread.nodes.root, link); + } + }, + + markRead() { + const thread = Get$1.threadFromNode(this); + UnreadIndex.lastReadPost[thread.fullID] = thread.lastPost; + UnreadIndex.db.set({ + boardID: thread.board.ID, + threadID: thread.ID, + val: thread.lastPost + }); + $$1.rm(UnreadIndex.hr[thread.fullID]); + thread.nodes.root.classList.remove('unread-thread'); + return ThreadWatcher$1.update(g.SITE.ID, thread.board.ID, thread.ID, { + last: thread.lastPost, + unread: 0, + quotingYou: 0 + } + ); + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS104: Avoid inline assignments + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var ThreadWatcher = { + init() { + let sc; + if (!(this.enabled = Conf['Thread Watcher'])) { return; } + + this.shortcut = (sc = $$1.el('a', { + id: 'watcher-link', + textContent: '👁︎', + title: 'Thread Watcher', + href: 'javascript:;', + } + )); + + this.db = new DataBoard('watchedThreads', this.refresh, true); + this.dbLM = new DataBoard('watcherLastModified', null, true); + this.dialog = UI.dialog('thread-watcher', { innerHTML: ThreadWatcherPage }); + this.status = $$1('#watcher-status', this.dialog); + this.list = this.dialog.lastElementChild; + this.refreshButton = $$1('.refresh', this.dialog); + this.closeButton = $$1('.move > .close', this.dialog); + this.unreaddb = Unread.db || UnreadIndex.db || new DataBoard('lastReadPosts'); + this.unreadEnabled = Conf['Remember Last Read Post']; + + $$1.on(d$1, 'QRPostSuccessful', this.cb.post); + $$1.on(sc, 'click', this.toggleWatcher); + $$1.on(this.refreshButton, 'click', this.buttonFetchAll); + $$1.on(this.closeButton, 'click', this.toggleWatcher); + + this.menu.addHeaderMenuEntry(); + $$1.onExists(doc$1, 'body', this.addDialog); + + switch (g.VIEW) { + case 'index': + $$1.on(d$1, 'IndexUpdate', this.cb.onIndexUpdate); + break; + case 'thread': + $$1.on(d$1, 'ThreadUpdate', this.cb.onThreadRefresh); + break; + } + + if (Conf['Fixed Thread Watcher']) { + $$1.addClass(doc$1, 'fixed-watcher'); + } + if (!Conf['Persistent Thread Watcher']) { + $$1.addClass(ThreadWatcher.shortcut, 'disabled'); + this.dialog.hidden = true; + } + + Header$1.addShortcut('watcher', sc, 510); + + ThreadWatcher.initLastModified(); + ThreadWatcher.fetchAuto(); + $$1.on(window, 'visibilitychange focus', () => $$1.queueTask(ThreadWatcher.fetchAuto)); + + if (Conf['Menu'] && Index$1.enabled) { + Menu.menu.addEntry({ + el: $$1.el('a', { + href: 'javascript:;', + className: 'has-shortcut-text' + } + , {innerHTML: 'Alt+click'}), + order: 6, + open({thread}) { + if (Conf['Index Mode'] !== 'catalog') { return false; } + this.el.firstElementChild.textContent = ThreadWatcher.isWatched(thread) ? + 'Unwatch' + : + 'Watch'; + if (this.cb) { $$1.off(this.el, 'click', this.cb); } + this.cb = function() { + $$1.event('CloseMenu'); + return ThreadWatcher.toggle(thread); + }; + $$1.on(this.el, 'click', this.cb); + return true; + } + }); + } + + if (!['index', 'thread'].includes(g.VIEW)) { return; } + + Callbacks.Post.push({ + name: 'Thread Watcher', + cb: this.node + }); + return Callbacks.CatalogThread.push({ + name: 'Thread Watcher', + cb: this.catalogNode + }); + }, + + isWatched(thread) { + return !!ThreadWatcher.db?.get({boardID: thread.board.ID, threadID: thread.ID}); + }, + + isWatchedRaw(boardID, threadID) { + return !!ThreadWatcher.db?.get({boardID, threadID}); + }, + + setToggler(toggler, isWatched) { + toggler.classList.toggle('watched', isWatched); + return toggler.title = `${isWatched ? 'Unwatch' : 'Watch'} Thread`; + }, + + node() { + let toggler; + if (this.isReply) { return; } + if (this.isClone) { + toggler = $$1('.watch-thread-link', this.nodes.info); + } else { + toggler = $$1.el('a', { + href: 'javascript:;', + className: 'watch-thread-link' + } + ); + $$1.before($$1('input', this.nodes.info), toggler); + } + const siteID = g.SITE.ID; + const boardID = this.board.ID; + const threadID = this.thread.ID; + const data = ThreadWatcher.db.get({siteID, boardID, threadID}); + ThreadWatcher.setToggler(toggler, !!data); + $$1.on(toggler, 'click', ThreadWatcher.cb.toggle); + // Add missing excerpt for threads added by Auto Watch + if (data && (data.excerpt == null)) { + return $$1.queueTask(() => { + return ThreadWatcher.update(siteID, boardID, threadID, {excerpt: Get$1.threadExcerpt(this.thread)}); + }); + } + }, + + catalogNode() { + if (ThreadWatcher.isWatched(this.thread)) { $$1.addClass(this.nodes.root, 'watched'); } + return $$1.on(this.nodes.root, 'mousedown click', e => { + if ((e.button !== 0) || !e.altKey) { return; } + if (e.type === 'click') { ThreadWatcher.toggle(this.thread); } + return e.preventDefault(); + }); + }, // Also on mousedown to prevent highlighting thumbnail in Firefox. + + addDialog() { + if (!Main$1.isThisPageLegit()) { return; } + ThreadWatcher.build(); + return $$1.prepend(d$1.body, ThreadWatcher.dialog); + }, + + toggleWatcher() { + $$1.toggleClass(ThreadWatcher.shortcut, 'disabled'); + return ThreadWatcher.dialog.hidden = !ThreadWatcher.dialog.hidden; + }, + + cb: { + openAll() { + if ($$1.hasClass(this, 'disabled')) { return; } + for (var a of $$('a.watcher-link', ThreadWatcher.list)) { + $$1.open(a.href); + } + return $$1.event('CloseMenu'); + }, + openUnread() { + if ($$1.hasClass(this, 'disabled')) { return; } + for (var a of $$('.replies-unread > a.watcher-link', ThreadWatcher.list)) { + $$1.open(a.href); + } + return $$1.event('CloseMenu'); + }, + openDeads() { + if ($$1.hasClass(this, 'disabled')) { return; } + for (var a of $$('.dead-thread > a.watcher-link', ThreadWatcher.list)) { + $$1.open(a.href); + } + return $$1.event('CloseMenu'); + }, + pruneDeads() { + if ($$1.hasClass(this, 'disabled')) { return; } + for (var {siteID, boardID, threadID, data} of ThreadWatcher.getAll()) { + if (data.isDead) { + ThreadWatcher.db.delete({siteID, boardID, threadID}); + } + } + ThreadWatcher.refresh(); + return $$1.event('CloseMenu'); + }, + dismiss() { + for (var {siteID, boardID, threadID, data} of ThreadWatcher.getAll()) { + if (data.quotingYou) { + ThreadWatcher.update(siteID, boardID, threadID, {dismiss: data.quotingYou || 0}); + } + } + return $$1.event('CloseMenu'); + }, + toggle() { + const {thread} = Get$1.postFromNode(this); + return ThreadWatcher.toggle(thread); + }, + rm() { + const {siteID} = this.parentNode.dataset; + const [boardID, threadID] = Array.from(this.parentNode.dataset.fullID.split('.')); + return ThreadWatcher.rm(siteID, boardID, +threadID); + }, + post(e) { + const {boardID, threadID, postID} = e.detail; + const cb = PostRedirect.delay(); + if (postID === threadID) { + if (Conf['Auto Watch']) { + return ThreadWatcher.addRaw(boardID, threadID, {}, cb); + } + } else if (Conf['Auto Watch Reply']) { + return ThreadWatcher.add((g.threads.get(boardID + '.' + threadID) || new Thread(threadID, g.boards[boardID] || new Board(boardID))), cb); + } + }, + onIndexUpdate(e) { + const {db} = ThreadWatcher; + const siteID = g.SITE.ID; + const boardID = g.BOARD.ID; + let nKilled = 0; + for (var threadID in db.data[siteID].boards[boardID]) { + // Don't prune threads that have yet to appear in index. + var data = db.data[siteID].boards[boardID][threadID]; + if (!data?.isDead && !e.detail.threads.includes(`${boardID}.${threadID}`)) { + if (!e.detail.threads.some(fullID => +fullID.split('.')[1] > threadID)) { continue; } + if (Conf['Auto Prune'] || !(data && (typeof data === 'object'))) { // corrupt data + db.delete({boardID, threadID}); + nKilled++; + } else { + ThreadWatcher.fetchStatus({siteID, boardID, threadID, data}); + } + } + } + if (nKilled) { return ThreadWatcher.refresh(); } + }, + onThreadRefresh(e) { + const thread = g.threads.get(e.detail.threadID); + if (!e.detail[404] || !ThreadWatcher.isWatched(thread)) { return; } + // Update dead status. + return ThreadWatcher.add(thread); + } + }, + + requests: [], + fetched: 0, + + fetch(url, {siteID, force}, args, cb) { + if (ThreadWatcher.requests.length === 0) { + ThreadWatcher.status.textContent = '...'; + $$1.addClass(ThreadWatcher.refreshButton, 'spin'); + } + const onloadend = function() { + if (this.finished) { return; } + this.finished = true; + ThreadWatcher.fetched++; + if (ThreadWatcher.fetched === ThreadWatcher.requests.length) { + ThreadWatcher.clearRequests(); + } else { + ThreadWatcher.status.textContent = `${Math.round((ThreadWatcher.fetched / ThreadWatcher.requests.length) * 100)}%`; + } + return cb.apply(this, args); + }; + const ajax = siteID === g.SITE.ID ? $$1.ajax : CrossOrigin$1.ajax; + if (force) { + delete $$1.lastModified.ThreadWatcher?.[url]; + } + const req = $$1.whenModified( + url, + 'ThreadWatcher', + onloadend, + { timeout: MINUTE, ajax } + ); + return ThreadWatcher.requests.push(req); + }, + + clearRequests() { + ThreadWatcher.requests = []; + ThreadWatcher.fetched = 0; + ThreadWatcher.status.textContent = ''; + return $$1.rmClass(ThreadWatcher.refreshButton, 'spin'); + }, + + abort() { + delete ThreadWatcher.syncing; + for (var req of ThreadWatcher.requests) { + if (!req.finished) { + req.finished = true; + req.abort(); + } + } + return ThreadWatcher.clearRequests(); + }, + + initLastModified() { + const lm = ($$1.lastModified['ThreadWatcher'] || ($$1.lastModified['ThreadWatcher'] = dict())); + for (var siteID in ThreadWatcher.dbLM.data) { + var boards = ThreadWatcher.dbLM.data[siteID]; + for (var boardID in boards.boards) { + var data = boards.boards[boardID]; + if (ThreadWatcher.db.get({siteID, boardID})) { + for (var url in data) { + var date = data[url]; + lm[url] = date; + } + } else { + ThreadWatcher.dbLM.delete({siteID, boardID}); + } + } + } + }, + + fetchAuto() { + let middle; + clearTimeout(ThreadWatcher.timeout); + if (!Conf['Auto Update Thread Watcher']) { return; } + const {db} = ThreadWatcher; + const interval = Conf['Show Page'] || (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) ? 5 * MINUTE : 2 * HOUR; + const now = Date.now(); + if ((now - interval >= ((middle = db.data.lastChecked || 0)) || middle > now) && !d$1.hidden && !!d$1.hasFocus()) { + ThreadWatcher.fetchAllStatus(interval); + } + return ThreadWatcher.timeout = setTimeout(ThreadWatcher.fetchAuto, interval); + }, + + buttonFetchAll() { + if (ThreadWatcher.syncing || ThreadWatcher.requests.length) { + return ThreadWatcher.abort(); + } else { + return ThreadWatcher.fetchAllStatus(); + } + }, + + fetchAllStatus(interval=0) { + ThreadWatcher.status.textContent = '...'; + $$1.addClass(ThreadWatcher.refreshButton, 'spin'); + ThreadWatcher.syncing = true; + const dbs = [ThreadWatcher.db, ThreadWatcher.unreaddb, QuoteYou.db].filter(x => x); + let n = 0; + return dbs.map((dbi) => + dbi.forceSync(function() { + if ((++n) === dbs.length) { + let middle; + if (!ThreadWatcher.syncing) { return; } // aborted + delete ThreadWatcher.syncing; + if (0 > (middle = Date.now() - (ThreadWatcher.db.data.lastChecked || 0)) || middle >= interval) { // not checked in another tab + // XXX On vichan boards, last_modified field of threads.json does not account for sage posts. + // Occasionally check replies field of catalog.json to find these posts. + let middle1; + const {db} = ThreadWatcher; + const now = Date.now(); + const deep = !(now - (2 * HOUR) < ((middle1 = db.data.lastChecked2 || 0)) && middle1 <= now); + const boards = ThreadWatcher.getAll(true); + for (var board of boards) { + ThreadWatcher.fetchBoard(board, deep); + } + db.setLastChecked(); + if (deep) { db.setLastChecked('lastChecked2'); } + } + if (ThreadWatcher.fetched === ThreadWatcher.requests.length) { + return ThreadWatcher.clearRequests(); + } + } + })); + }, + + fetchBoard(board, deep) { + if (!board.some(thread => !thread.data.isDead)) { return; } + let force = false; + for (var thread of board) { + var {data} = thread; + if (!data.isDead && (data.last !== -1)) { + if (Conf['Show Page'] && (data.page == null)) { force = true; } + if ((data.modified == null)) { force = (thread.force = true); } + } + } + const {siteID, boardID} = board[0]; + const site = g.sites[siteID]; + if (!site) { return; } + const urlF = deep && site.threadModTimeIgnoresSage ? 'catalogJSON' : 'threadsListJSON'; + const url = site.urls[urlF]?.({siteID, boardID}); + if (!url) { return; } + return ThreadWatcher.fetch(url, {siteID, force}, [board, url], ThreadWatcher.parseBoard); + }, + + parseBoard(board, url) { + let page, thread; + if (this.status !== 200) { return; } + const {siteID, boardID} = board[0]; + const lmDate = this.getResponseHeader('Last-Modified'); + ThreadWatcher.dbLM.extend({siteID, boardID, val: $$1.item(url, lmDate)}); + const threads = dict(); + let pageLength = 0; + let nThreads = 0; + let oldest = null; + try { + pageLength = this.response[0]?.threads.length || 0; + for (let i = 0; i < this.response.length; i++) { + page = this.response[i]; + for (var item of page.threads) { + threads[item.no] = { + page: i + 1, + index: nThreads, + modified: item.last_modified, + replies: item.replies + }; + nThreads++; + if ((oldest == null) || (item.no < oldest)) { + oldest = item.no; + } + } + } + } catch (error) { + for (thread of board) { + ThreadWatcher.fetchStatus(thread); + } + } + for (thread of board) { + var {threadID, data} = thread; + if (threads[threadID]) { + var index, modified, replies; + ({page, index, modified, replies} = threads[threadID]); + if (Conf['Show Page']) { + var lastPage = g.sites[siteID].isPrunedByAge?.({siteID, boardID}) ? + threadID === oldest + : + index >= (nThreads - pageLength); + ThreadWatcher.update(siteID, boardID, threadID, {page, lastPage}); + } + if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { + if ((modified !== data.modified) || ((replies != null) && (replies !== data.replies))) { + (thread.newData || (thread.newData = {})).modified = modified; + ThreadWatcher.fetchStatus(thread); + } + } + } else { + ThreadWatcher.fetchStatus(thread); + } + } + }, + + fetchStatus(thread) { + const {siteID, boardID, threadID, data, force} = thread; + const url = g.sites[siteID]?.urls.threadJSON?.({siteID, boardID, threadID}); + if (!url) { return; } + if (data.isDead && !force) { return; } + if (data.last === -1) { return; } // 404 or no JSON API + return ThreadWatcher.fetch(url, {siteID, force}, [thread], ThreadWatcher.parseStatus); + }, + + parseStatus(thread, isArchiveURL) { + let isDead, last; + let {siteID, boardID, threadID, data, newData, force} = thread; + const site = g.sites[siteID]; + if ((this.status === 200) && this.response) { + let isArchived; + last = this.response.posts[this.response.posts.length-1].no; + const replies = this.response.posts.length-1; + isDead = (isArchived = !!(this.response.posts[0].archived || isArchiveURL)); + if (isDead && Conf['Auto Prune']) { + ThreadWatcher.rm(siteID, boardID, threadID); + return; + } + + if ((last === data.last) && (isDead === data.isDead) && (isArchived === data.isArchived)) { return; } + + const lastReadPost = ThreadWatcher.unreaddb.get({siteID, boardID, threadID, defaultValue: 0}); + let unread = data.unread || 0; + let quotingYou = data.quotingYou || 0; + const youOP = !!QuoteYou.db?.get({siteID, boardID, threadID, postID: threadID}); + + for (var postObj of this.response.posts) { + if ((postObj.no <= (data.last || 0)) || (postObj.no <= lastReadPost)) { continue; } + if (QuoteYou.db?.get({siteID, boardID, threadID, postID: postObj.no})) { continue; } + + var quotesYou = false; + if (!Conf['Require OP Quote Link'] && youOP) { + quotesYou = true; + } else if (QuoteYou.db && postObj.com) { + var match; + var regexp = site.regexp.quotelinkHTML; + regexp.lastIndex = 0; + while (match = regexp.exec(postObj.com)) { + if (QuoteYou.db.get({ + siteID, + boardID: match[1] ? encodeURIComponent(match[1]) : boardID, + threadID: match[2] || threadID, + postID: match[3] || match[2] || threadID + })) { + quotesYou = true; + break; + } + } + } + + if (!unread || (!quotingYou && quotesYou)) { + if (Filter.isHidden(site.Build.parseJSON(postObj, {siteID, boardID}))) { continue; } + } + + unread++; + if (quotesYou) { quotingYou = postObj.no; } + } + + if (!newData) { newData = {}; } + $$1.extend(newData, {last, replies, isDead, isArchived, unread, quotingYou}); + return ThreadWatcher.update(siteID, boardID, threadID, newData); + + } else if (this.status === 404) { + const archiveURL = g.sites[siteID]?.urls.archivedThreadJSON?.({siteID, boardID, threadID}); + if (!isArchiveURL && archiveURL) { + return ThreadWatcher.fetch(archiveURL, {siteID, force}, [thread, true], ThreadWatcher.parseStatus); + } else if (site.mayLackJSON && (data.last == null)) { + return ThreadWatcher.update(siteID, boardID, threadID, {last: -1}); + } else { + return ThreadWatcher.update(siteID, boardID, threadID, {isDead: true}); + } + } + }, + + getAll(groupByBoard) { + const all = []; + for (var siteID in ThreadWatcher.db.data) { + var boards = ThreadWatcher.db.data[siteID]; + for (var boardID in boards.boards) { + var cont; + var threads = boards.boards[boardID]; + if (Conf['Current Board'] && ((siteID !== g.SITE.ID) || (boardID !== g.BOARD.ID))) { + continue; + } + if (groupByBoard) { + all.push((cont = [])); + } + for (var threadID in threads) { + var data = threads[threadID]; + if (data && (typeof data === 'object')) { + (groupByBoard ? cont : all).push({siteID, boardID, threadID, data}); + } + } + } + } + return all; + }, + + makeLine(siteID, boardID, threadID, data) { + let page; + const x = $$1.el('a', { + textContent: '✕', + href: 'javascript:;' + } + ); + $$1.on(x, 'click', ThreadWatcher.cb.rm); + + let {excerpt, isArchived} = data; + if (!excerpt) { excerpt = `/${boardID}/ - No.${threadID}`; } + if (Conf['Show Site Prefix']) { excerpt = ThreadWatcher.prefixes[siteID] + excerpt; } + + const link = $$1.el('a', { + href: g.sites[siteID]?.urls.thread({siteID, boardID, threadID}, isArchived) || '', + title: excerpt, + className: 'watcher-link' + } + ); + + if (Conf['Show Page'] && (data.page != null)) { + page = $$1.el('span', { + textContent: `[${data.page}]`, + className: 'watcher-page' + } + ); + $$1.add(link, page); + } + + if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count'] && (data.unread != null)) { + const count = $$1.el('span', { + textContent: `(${data.unread})`, + className: 'watcher-unread' + } + ); + $$1.add(link, count); + } + + const title = $$1.el('span', { + textContent: excerpt, + className: 'watcher-title' + } + ); + $$1.add(link, title); + + const div = $$1.el('div'); + const fullID = `${boardID}.${threadID}`; + div.dataset.fullID = fullID; + div.dataset.siteID = siteID; + if ((g.VIEW === 'thread') && (fullID === `${g.BOARD}.${g.THREADID}`)) { $$1.addClass(div, 'current'); } + if (data.isDead) { $$1.addClass(div, 'dead-thread'); } + if (Conf['Show Page']) { + if (data.lastPage) { $$1.addClass(div, 'last-page'); } + if (data.page != null) { div.dataset.page = data.page; } + } + if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { + if (data.unread === 0) { $$1.addClass(div, 'replies-read'); } + if (data.unread) { $$1.addClass(div, 'replies-unread'); } + if ((data.quotingYou || 0) > (data.dismiss || 0)) { $$1.addClass(div, 'replies-quoting-you'); } + } + $$1.add(div, [x, $$1.tn(' '), link]); + return div; + }, + + setPrefixes(threads) { + const prefixes = dict(); + for (var {siteID} of threads) { + if (siteID in prefixes) { continue; } + var len = 0; + var prefix = ''; + var conflicts = Object.keys(prefixes); + while (conflicts.length > 0) { + len++; + prefix = siteID.slice(0, len); + var conflicts2 = []; + for (var siteID2 of conflicts) { + if (siteID2.slice(0, len) === prefix) { + conflicts2.push(siteID2); + } else if (prefixes[siteID2].length < len) { + prefixes[siteID2] = siteID2.slice(0, len); + } + } + conflicts = conflicts2; + } + prefixes[siteID] = prefix; + } + return ThreadWatcher.prefixes = prefixes; + }, + + build() { + const nodes = []; + const threads = ThreadWatcher.getAll(); + ThreadWatcher.setPrefixes(threads); + for (var {siteID, boardID, threadID, data} of threads) { + // Add missing excerpt for threads added by Auto Watch + var thread; + if ((data.excerpt == null) && (siteID === g.SITE.ID) && (thread = g.threads.get(`${boardID}.${threadID}`)) && thread.OP) { + ThreadWatcher.db.extend({boardID, threadID, val: {excerpt: Get$1.threadExcerpt(thread)}}); + } + nodes.push(ThreadWatcher.makeLine(siteID, boardID, threadID, data)); + } + const {list} = ThreadWatcher; + $$1.rmAll(list); + $$1.add(list, nodes); + + return ThreadWatcher.refreshIcon(); + }, + + refresh() { + ThreadWatcher.build(); + + g.threads.forEach(function(thread) { + const isWatched = ThreadWatcher.isWatched(thread); + if (thread.OP) { + for (var post of [thread.OP, ...Array.from(thread.OP.clones)]) { + var toggler; + if (toggler = $$1('.watch-thread-link', post.nodes.info)) { + ThreadWatcher.setToggler(toggler, isWatched); + } + } + } + if (thread.catalogView) { return thread.catalogView.nodes.root.classList.toggle('watched', isWatched); } + }); + + if (Conf['Pin Watched Threads']) { + return $$1.event('SortIndex', {deferred: Conf['Index Mode'] !== 'catalog'}); + } + }, + + refreshIcon() { + for (var className of ['replies-unread', 'replies-quoting-you']) { + ThreadWatcher.shortcut.classList.toggle(className, !!$$1(`.${className}`, ThreadWatcher.dialog)); + } + }, + + update(siteID, boardID, threadID, newData) { + let data, key, line, val; + if (!(data = ThreadWatcher.db?.get({siteID, boardID, threadID}))) { return; } + if (newData.isDead && Conf['Auto Prune']) { + ThreadWatcher.rm(siteID, boardID, threadID); + return; + } + if (newData.isDead || (newData.last === -1)) { + for (key of ['isArchived', 'page', 'lastPage', 'unread', 'quotingyou']) { + if (!(key in newData)) { + newData[key] = undefined; + } + } + } + if ((newData.last != null) && (newData.last < data.last)) { + newData.modified = undefined; + } + let n = 0; + for (key in newData) { val = newData[key]; if (data[key] !== val) { n++; } } + if (!n) { return; } + ThreadWatcher.db.extend({siteID, boardID, threadID, val: newData}); + if (line = $$1(`#watched-threads > [data-site-i-d='${siteID}'][data-full-i-d='${boardID}.${threadID}']`, ThreadWatcher.dialog)) { + const newLine = ThreadWatcher.makeLine(siteID, boardID, threadID, data); + $$1.replace(line, newLine); + return ThreadWatcher.refreshIcon(); + } else { + return ThreadWatcher.refresh(); + } + }, + + set404(boardID, threadID, cb) { + let data; + if (!(data = ThreadWatcher.db?.get({boardID, threadID}))) { return cb(); } + if (Conf['Auto Prune']) { + ThreadWatcher.db.delete({boardID, threadID}); + return cb(); + } + if (data.isDead && !((data.isArchived != null) || (data.page != null) || (data.lastPage != null) || (data.unread != null) || (data.quotingYou != null))) { return cb(); } + return ThreadWatcher.db.extend({boardID, threadID, val: {isDead: true, isArchived: undefined, page: undefined, lastPage: undefined, unread: undefined, quotingYou: undefined}}, cb); + }, + + toggle(thread) { + const siteID = g.SITE.ID; + const boardID = thread.board.ID; + const threadID = thread.ID; + if (ThreadWatcher.db.get({boardID, threadID})) { + return ThreadWatcher.rm(siteID, boardID, threadID); + } else { + return ThreadWatcher.add(thread); + } + }, + + add(thread, cb) { + const data = {}; + const siteID = g.SITE.ID; + const boardID = thread.board.ID; + const threadID = thread.ID; + if (thread.isDead) { + if (Conf['Auto Prune'] && ThreadWatcher.db.get({boardID, threadID})) { + ThreadWatcher.rm(siteID, boardID, threadID, cb); + return; + } + data.isDead = true; + } + if (thread.OP) { data.excerpt = Get$1.threadExcerpt(thread); } + return ThreadWatcher.addRaw(boardID, threadID, data, cb); + }, + + addRaw(boardID, threadID, data, cb) { + const oldData = ThreadWatcher.db.get({ boardID, threadID, defaultValue: dict() }); + delete oldData.last; + delete oldData.modified; + $$1.extend(oldData, data); + ThreadWatcher.db.set({boardID, threadID, val: oldData}, cb); + ThreadWatcher.refresh(); + const thread = {siteID: g.SITE.ID, boardID, threadID, data, force: true}; + if (Conf['Show Page'] && !data.isDead) { + return ThreadWatcher.fetchBoard([thread]); + } else if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { + return ThreadWatcher.fetchStatus(thread); + } + }, + + rm(siteID, boardID, threadID, cb) { + ThreadWatcher.db.delete({siteID, boardID, threadID}, cb); + return ThreadWatcher.refresh(); + }, + + menu: { + init() { + if (!Conf['Thread Watcher']) { return; } + const menu = (this.menu = new UI.Menu('thread watcher')); + $$1.on($$1('.menu-button', ThreadWatcher.dialog), 'click', function(e) { + return menu.toggle(e, this, ThreadWatcher); + }); + return this.addMenuEntries(); + }, + + addHeaderMenuEntry() { + if (g.VIEW !== 'thread') { return; } + const entryEl = $$1.el('a', + {href: 'javascript:;'}); + Header$1.menu.addEntry({ + el: entryEl, + order: 60, + open() { + const [addClass, rmClass, text] = Array.from(!!ThreadWatcher.db.get({boardID: g.BOARD.ID, threadID: g.THREADID}) ? + ['unwatch-thread', 'watch-thread', 'Unwatch thread'] + : + ['watch-thread', 'unwatch-thread', 'Watch thread']); + $$1.addClass(entryEl, addClass); + $$1.rmClass(entryEl, rmClass); + entryEl.textContent = text; + return true; + } + }); + return $$1.on(entryEl, 'click', () => ThreadWatcher.toggle(g.threads.get(`${g.BOARD}.${g.THREADID}`))); + }, + + addMenuEntries() { + const entries = []; + + // `Open all` entry + entries.push({ + text: 'Open all threads', + cb: ThreadWatcher.cb.openAll, + open() { + this.el.classList.toggle('disabled', !ThreadWatcher.list.firstElementChild); + return true; + } + }); + + // `Open Unread` entry + entries.push({ + text: 'Open unread threads', + cb: ThreadWatcher.cb.openUnread, + open() { + this.el.classList.toggle('disabled', !$$1('.replies-unread', ThreadWatcher.list)); + return true; + } + }); + + // `Open dead threads` entry + entries.push({ + text: 'Open dead threads', + cb: ThreadWatcher.cb.openDeads, + open() { + this.el.classList.toggle('disabled', !$$1('.dead-thread', ThreadWatcher.list)); + return true; + } + }); + + // `Prune dead threads` entry + entries.push({ + text: 'Prune dead threads', + cb: ThreadWatcher.cb.pruneDeads, + open() { + this.el.classList.toggle('disabled', !$$1('.dead-thread', ThreadWatcher.list)); + return true; + } + }); + + // `Dismiss posts quoting you` entry + entries.push({ + text: 'Dismiss posts quoting you', + title: 'Unhighlight the thread watcher icon and threads until there are new replies quoting you.', + cb: ThreadWatcher.cb.dismiss, + open() { + this.el.classList.toggle('disabled', !$$1.hasClass(ThreadWatcher.shortcut, 'replies-quoting-you')); + return true; + } + }); + + for (var {text, title, cb, open} of entries) { + var entry = { + el: $$1.el('a', { + textContent: text, + href: 'javascript:;' + } + ) + }; + if (title) { entry.el.title = title; } + $$1.on(entry.el, 'click', cb); + entry.open = open.bind(entry); + this.menu.addEntry(entry); + } + + // Settings checkbox entries: + for (var name in Config.threadWatcher) { + var conf = Config.threadWatcher[name]; + this.addCheckbox(name, conf[1]); + } + + }, + + addCheckbox(name, desc) { + const entry = { + type: 'thread watcher', + el: UI.checkbox(name, name.replace(' Thread Watcher', '')) + }; + entry.el.title = desc; + const input = entry.el.firstElementChild; + if ((name === 'Show Unread Count') && !ThreadWatcher.unreadEnabled) { + input.disabled = true; + $$1.addClass(entry.el, 'disabled'); + entry.el.title += '\n[Remember Last Read Post is disabled.]'; + } + $$1.on(input, 'change', $$1.cb.checked); + if (['Current Board', 'Show Page', 'Show Unread Count', 'Show Site Prefix'].includes(name)) { $$1.on(input, 'change', ThreadWatcher.refresh); } + if (['Show Page', 'Show Unread Count', 'Auto Update Thread Watcher'].includes(name)) { $$1.on(input, 'change', ThreadWatcher.fetchAuto); } + return this.menu.addEntry(entry); + } + } + }; + var ThreadWatcher$1 = ThreadWatcher; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * DS206: Consider reworking classes to avoid initClass + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class Fetcher { + static initClass() { + + this.prototype.archiveTags = { + '\n': {innerHTML: "
        "}, + '[b]': {innerHTML: ""}, + '[/b]': {innerHTML: ""}, + '[spoiler]': {innerHTML: ""}, + '[/spoiler]': {innerHTML: ""}, + '[code]': {innerHTML: "
        "},
        +        '[/code]':    {innerHTML: "
        "}, + '[moot]': {innerHTML: "
        "}, + '[/moot]': {innerHTML: "
        "}, + '[banned]': {innerHTML: ""}, + '[/banned]': {innerHTML: ""}, + '[fortune]'(text) { return {innerHTML: ""}; }, + '[/fortune]': {innerHTML: ""}, + '[i]': {innerHTML: ""}, + '[/i]': {innerHTML: ""}, + '[red]': {innerHTML: ""}, + '[/red]': {innerHTML: ""}, + '[green]': {innerHTML: ""}, + '[/green]': {innerHTML: ""}, + '[blue]': {innerHTML: ""}, + '[/blue]': {innerHTML: ""} + }; + } + constructor(boardID, threadID, postID, root, quoter) { + let post, thread; + this.boardID = boardID; + this.threadID = threadID; + this.postID = postID; + this.root = root; + this.quoter = quoter; + if (post = g.posts.get(`${this.boardID}.${this.postID}`)) { + this.insert(post); + return; + } + + // 4chan X catalog data + if ((post = Index$1.replyData?.[`${this.boardID}.${this.postID}`]) && (thread = g.threads.get(`${this.boardID}.${this.threadID}`))) { + const board = g.boards[this.boardID]; + post = new Post(g.SITE.Build.postFromObject(post, this.boardID), thread, board, {isFetchedQuote: true}); + Main$1.callbackNodes('Post', [post]); + this.insert(post); + return; + } + + this.root.textContent = `Loading post No.${this.postID}...`; + if (this.threadID) { + const that = this; + $$1.cache(g.SITE.urls.threadJSON({boardID: this.boardID, threadID: this.threadID}), function({isCached}) { + return that.fetchedPost(this, isCached); + }); + } else { + this.archivedPost(); + } + } + + insert(post) { + // Stop here if the container has been removed while loading. + if (!this.root.parentNode) { return; } + if (!this.quoter) { this.quoter = post; } + const clone = post.addClone(this.quoter.context, ($$1.hasClass(this.root, 'dialog'))); + Main$1.callbackNodes('Post', [clone]); + + // Get rid of the side arrows/stubs. + const {nodes} = clone; + $$1.rmAll(nodes.root); + $$1.add(nodes.root, nodes.post); + + // Indicate links to the containing post. + const quotes = [...clone.nodes.quotelinks, ...clone.nodes.backlinks]; + for (var quote of quotes) { + var {boardID, postID} = Get$1.postDataFromLink(quote); + if ((postID === this.quoter.ID) && (boardID === this.quoter.board.ID)) { + $$1.addClass(quote, 'forwardlink'); + } + } + + // Set up flag CSS for cross-board links to boards with flags + if (clone.nodes.flag && !(Fetcher.flagCSS || (Fetcher.flagCSS = $$1('link[href^="//s.4cdn.org/css/flags."]')))) { + const cssVersion = $$1('link[href^="//s.4cdn.org/css/"]')?.href.match(/\d+(?=\.css$)|$/)[0] || Date.now(); + Fetcher.flagCSS = $$1.el('link', { + rel: 'stylesheet', + href: `//s.4cdn.org/css/flags.${cssVersion}.css` + } + ); + $$1.add(d$1.head, Fetcher.flagCSS); + } + + $$1.rmAll(this.root); + $$1.add(this.root, nodes.root); + return $$1.event('PostsInserted', null, this.root); + } + + fetchedPost(req, isCached) { + // In case of multiple callbacks for the same request, + // don't parse the same original post more than once. + let post; + if (post = g.posts.get(`${this.boardID}.${this.postID}`)) { + this.insert(post); + return; + } + + const {status} = req; + if (status !== 200) { + // The thread can die by the time we check a quote. + if (status && this.archivedPost()) { return; } + + $$1.addClass(this.root, 'warning'); + this.root.textContent = + status === 404 ? + `Thread No.${this.threadID} 404'd.` + : !status ? + 'Connection Error' + : + `Error ${req.statusText} (${req.status}).`; + return; + } + + const {posts} = req.response; + g.SITE.Build.spoilerRange[this.boardID] = posts[0].custom_spoiler; + for (post of posts) { + if (post.no === this.postID) { break; } + } // we found it! + + if (post.no !== this.postID) { + // Cached requests can be stale and must be rechecked. + if (isCached) { + const api = g.SITE.urls.threadJSON({boardID: this.boardID, threadID: this.threadID}); + $$1.cleanCache(url => url === api); + const that = this; + $$1.cache(api, function() { + return that.fetchedPost(this, false); + }); + return; + } + + // The post can be deleted by the time we check a quote. + if (this.archivedPost()) { return; } + + $$1.addClass(this.root, 'warning'); + this.root.textContent = `Post No.${this.postID} was not found.`; + return; + } + + const board = g.boards[this.boardID] || + new Board(this.boardID); + const thread = g.threads.get(`${this.boardID}.${this.threadID}`) || + new Thread(this.threadID, board); + post = new Post(g.SITE.Build.postFromObject(post, this.boardID), thread, board, {isFetchedQuote: true}); + Main$1.callbackNodes('Post', [post]); + return this.insert(post); + } + + archivedPost() { + let url; + if (!Conf['Resurrect Quotes']) { return false; } + if (!(url = Redirect$1.to('post', {boardID: this.boardID, postID: this.postID}))) { return false; } + const archive = Redirect$1.data.post[this.boardID]; + const encryptionOK = /^https:\/\//.test(url) || (location.protocol === 'http:'); + if (encryptionOK || Conf['Exempt Archives from Encryption']) { + const that = this; + CrossOrigin$1.cache(url, function() { + if (!encryptionOK && this.response?.media) { + const {media} = this.response; + for (var key in media) { + // Image/thumbnail URLs loaded over HTTP can be modified in transit. + // Require them to be from an HTTP host so that no referrer is sent to them from an HTTPS page. + if (/_link$/.test(key)) { + if (!$$1.getOwn(media, key)?.match(/^http:\/\//)) { delete media[key]; } + } + } + } + return that.parseArchivedPost(this.response, url, archive); + }); + return true; + } + return false; + } + + parseArchivedPost(data, url, archive) { + // In case of multiple callbacks for the same request, + // don't parse the same original post more than once. + let post; + if (post = g.posts.get(`${this.boardID}.${this.postID}`)) { + this.insert(post); + return; + } + + if (data == null) { + $$1.addClass(this.root, 'warning'); + this.root.textContent = `Error fetching Post No.${this.postID} from ${archive.name}.`; + return; + } + + if (data.error) { + $$1.addClass(this.root, 'warning'); + this.root.textContent = data.error; + return; + } + + // https://github.com/eksopl/asagi/blob/v0.4.0b74/src/main/java/net/easymodo/asagi/YotsubaAbstract.java#L82-L129 + // https://github.com/FoolCode/FoolFuuka/blob/800bd090835489e7e24371186db6e336f04b85c0/src/Model/Comment.php#L368-L428 + // https://github.com/bstats/b-stats/blob/6abe7bffaf6e5f523498d760e54b110df5331fbb/inc/classes/Yotsuba.php#L157-L168 + let comment = (data.comment || '').split(/(\n|\[\/?(?:b|spoiler|code|moot|banned|fortune(?: color="#\w+")?|i|red|green|blue)\])/); + comment = (() => { + const result = []; + for (let i = 0; i < comment.length; i++) { + var text = comment[i]; + if ((i % 2) === 1) { + var tag = Fetcher.archiveTags[text.replace(/\ .*\]/, ']')]; + if (typeof tag === 'function') { result.push(tag(text)); } else { result.push(tag); } + } else { + var greentext = text[0] === '>'; + text = text.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2'); + text = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g).map((text2, j) => + {((j % 2) ? "" + E(text2) + "" : E(text2));}); + text = {innerHTML: ((greentext) ? "" + E.cat(text) + "" : E.cat(text))}; + result.push(text); + } + } + return result; + })(); + comment = {innerHTML: E.cat(comment)}; + + this.threadID = +data.thread_num; + const o = { + ID: this.postID, + threadID: this.threadID, + boardID: this.boardID, + isReply: this.postID !== this.threadID + }; + o.info = { + subject: data.title, + email: data.email, + name: data.name || '', + tripcode: data.trip, + capcode: (() => { switch (data.capcode) { + // https://github.com/pleebe/FoolFuuka/blob/bf4224eed04637a4d0bd4411c2bf5f9945dfec0b/assets/themes/foolz/foolfuuka-theme-fuuka/src/Partial/Board.php#L77 + 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: data.poster_hash, + flagCode: data.poster_country, + flagCodeTroll: data.troll_country_code, + flag: data.poster_country_name || data.troll_country_name, + dateUTC: data.timestamp, + dateText: data.fourchan_date, + commentHTML: comment + }; + if (o.info.capcode) { delete o.info.uniqueID; } + if (data.media && !!+data.media.banned) { + o.fileDeleted = true; + } else if (data.media?.media_filename) { + let {thumb_link} = data.media; + // Fix URLs missing origin + if (thumb_link?.[0] === '/') { thumb_link = url.split('/', 3).join('/') + thumb_link; } + if (!Redirect$1.securityCheck(thumb_link)) { thumb_link = ''; } + let media_link = Redirect$1.to('file', {boardID: this.boardID, filename: data.media.media_orig}); + if (!Redirect$1.securityCheck(media_link)) { media_link = ''; } + o.file = { + name: data.media.media_filename, + url: media_link || + (this.boardID === 'f' ? + `${location.protocol}//${ImageHost.flashHost()}/${this.boardID}/${encodeURIComponent(E(data.media.media_filename))}` + : + `${location.protocol}//${ImageHost.host()}/${this.boardID}/${data.media.media_orig}`), + height: data.media.media_h, + width: data.media.media_w, + MD5: data.media.media_hash, + size: $$1.bytesToString(data.media.media_size), + thumbURL: thumb_link || `${location.protocol}//${ImageHost.thumbHost()}/${this.boardID}/${data.media.preview_orig}`, + theight: data.media.preview_h, + twidth: data.media.preview_w, + isSpoiler: data.media.spoiler === '1' + }; + if (!/\.pdf$/.test(o.file.url)) { o.file.dimensions = `${o.file.width}x${o.file.height}`; } + if ((this.boardID === 'f') && data.media.exif) { o.file.tag = JSON.parse(data.media.exif).Tag; } + } + o.extra = dict(); + + const board = g.boards[this.boardID] || + new Board(this.boardID); + const thread = g.threads.get(`${this.boardID}.${this.threadID}`) || + new Thread(this.threadID, board); + post = new Post(g.SITE.Build.post(o), thread, board, {isFetchedQuote: true}); + post.kill(); + if (post.file) { post.file.thumbURL = o.file.thumbURL; } + Main$1.callbackNodes('Post', [post]); + return this.insert(post); + } + } + Fetcher.initClass(); + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var QuotePreview = { + init() { + if (!Conf['Quote Previewing']) { return; } + + if (g.VIEW === 'archive') { + $$1.on(d$1, 'mouseover', function(e) { + if ((e.target.nodeName === 'A') && $$1.hasClass(e.target, 'quotelink')) { + return QuotePreview.mouseover.call(e.target, e); + } + }); + } + + if (!['index', 'thread'].includes(g.VIEW)) { return; } + + if (Conf['Comment Expansion']) { + ExpandComment.callbacks.push(this.node); + } + + return Callbacks.Post.push({ + name: 'Quote Previewing', + cb: this.node + }); + }, + + node() { + for (var link of this.nodes.quotelinks.concat([...Array.from(this.nodes.backlinks)], this.nodes.archivelinks)) { + $$1.on(link, 'mouseover', QuotePreview.mouseover); + } + }, + + mouseover(e) { + let origin; + if (($$1.hasClass(this, 'inlined') && !$$1.hasClass(doc, 'catalog-mode')) || !d$1.contains(this)) { return; } + + const {boardID, threadID, postID} = Get$1.postDataFromLink(this); + + const qp = $$1.el('div', { + id: 'qp', + className: 'dialog' + } + ); + + $$1.add(Header$1.hover, qp); + new Fetcher(boardID, threadID, postID, qp, Get$1.postFromNode(this)); + + UI.hover({ + root: this, + el: qp, + latestEvent: e, + endEvents: 'mouseout click', + cb: QuotePreview.mouseout + }); + + if (Conf['Quote Highlighting'] && (origin = g.posts.get(`${boardID}.${postID}`))) { + const posts = [origin].concat(origin.clones); + // Remove the clone that's in the qp from the array. + posts.pop(); + for (var post of posts) { + $$1.addClass(post.nodes.post, 'qphl'); + } + } + }, + + mouseout() { + // Stop if it only contains text. + let root; + if (!(root = this.el.firstElementChild)) { return; } + + $$1.event('PostsRemoved', null, Header$1.hover); + + const clone = Get$1.postFromRoot(root); + let post = clone.origin; + post.rmClone(root.dataset.clone); + + if (!Conf['Quote Highlighting']) { return; } + for (post of [post].concat(post.clones)) { + $$1.rmClass(post.nodes.post, 'qphl'); + } + } + }; + + var NavLinksPage = `Index +Catalog +Archive +Bottom + + +× + + + + + + + + +`; + + var PageList = ` +
        + + +`; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var Index = { + showHiddenThreads: false, + changed: {}, + + enabledOn({siteID, boardID}) { + return Conf['JSON Index'] && (g.sites[siteID].software === 'yotsuba') && (boardID !== 'f'); + }, + + init() { + let input, inputs, name; + if (g.VIEW !== 'index') { return; } + + // For IndexRefresh events + $$1.one(d$1, '4chanXInitFinished', this.cb.initFinished); + $$1.on(d$1, 'PostsInserted', this.cb.postsInserted); + + if (!this.enabledOn(g.BOARD)) { return; } + + this.enabled = true; + + Callbacks.Post.push({ + name: 'Index Page Numbers', + cb: this.node + }); + Callbacks.CatalogThread.push({ + name: 'Catalog Features', + cb: this.catalogNode + }); + + this.search = history.state?.searched || ''; + if (history.state?.mode) { + Conf['Index Mode'] = history.state?.mode; + } + this.currentSort = history.state?.sort; + if (!this.currentSort) { this.currentSort = typeof Conf['Index Sort'] === 'object' ? ( + Conf['Index Sort'][g.BOARD.ID] || 'bump' + ) : ( + Conf['Index Sort'] + ); } + this.currentPage = this.getCurrentPage(); + this.processHash(); + + $$1.addClass(doc$1, 'index-loading', `${Conf['Index Mode'].replace(/\ /g, '-')}-mode`); + $$1.on(window, 'popstate', this.cb.popstate); + $$1.on(d$1, 'scroll', this.scroll); + $$1.on(d$1, 'SortIndex', this.cb.resort); + + // Header refresh button + this.button = $$1.el('a', { + title: 'Refresh', + href: 'javascript:;', + textContent: '🗘' + } + ); + $$1.on(this.button, 'click', () => Index.update()); + Header$1.addShortcut('index-refresh', this.button, 590); + + // Header "Index Navigation" submenu + const entries = []; + this.inputs = (inputs = dict()); + for (name in Config.Index) { + var arr = Config.Index[name]; + if (arr instanceof Array) { + var label = UI.checkbox(name, `${name[0]}${name.slice(1).toLowerCase()}`); + label.title = arr[1]; + entries.push({el: label}); + input = label.firstChild; + $$1.on(input, 'change', $$1.cb.checked); + inputs[name] = input; + } + } + $$1.on(inputs['Show Replies'], 'change', this.cb.replies); + $$1.on(inputs['Catalog Hover Expand'], 'change', this.cb.hover); + $$1.on(inputs['Pin Watched Threads'], 'change', this.cb.resort); + $$1.on(inputs['Anchor Hidden Threads'], 'change', this.cb.resort); + + const watchSettings = function(e) { + if (input = $$1.getOwn(inputs, e.target.name)) { + input.checked = e.target.checked; + return $$1.event('change', null, input); + } + }; + $$1.on(d$1, 'OpenSettings', () => $$1.on($$1.id('fourchanx-settings'), 'change', watchSettings)); + + const sortEntry = UI.checkbox('Per-Board Sort Type', 'Per-board sort type', (typeof Conf['Index Sort'] === 'object')); + sortEntry.title = 'Set the sorting order of each board independently.'; + $$1.on(sortEntry.firstChild, 'change', this.cb.perBoardSort); + entries.splice(3, 0, {el: sortEntry}); + + Header$1.menu.addEntry({ + el: $$1.el('span', + {textContent: 'Index Navigation'}), + order: 100, + subEntries: entries + }); + + // Navigation links at top of index + this.navLinks = $$1.el('div', {className: 'navLinks json-index'}); + $$1.extend(this.navLinks, {innerHTML: NavLinksPage}); + $$1('.cataloglink a', this.navLinks).href = CatalogLinks.catalog(); + if (!BoardConfig.isArchived(g.BOARD.ID)) { $$1('.archlistlink', this.navLinks).hidden = true; } + $$1.on($$1('#index-last-refresh a', this.navLinks), 'click', this.cb.refreshFront); + + // Search field + this.searchInput = $$1('#index-search', this.navLinks); + this.setupSearch(); + $$1.on(this.searchInput, 'input', this.onSearchInput); + $$1.on($$1('#index-search-clear', this.navLinks), 'click', this.clearSearch); + + // Hidden threads toggle + this.hideLabel = $$1('#hidden-label', this.navLinks); + $$1.on($$1('#hidden-toggle a', this.navLinks), 'click', this.cb.toggleHiddenThreads); + + // Drop-down menus and reverse sort toggle + this.selectRev = $$1('#index-rev', this.navLinks); + this.selectMode = $$1('#index-mode', this.navLinks); + this.selectSort = $$1('#index-sort', this.navLinks); + this.selectSize = $$1('#index-size', this.navLinks); + $$1.on(this.selectRev, 'change', this.cb.sort); + $$1.on(this.selectMode, 'change', this.cb.mode); + $$1.on(this.selectSort, 'change', this.cb.sort); + $$1.on(this.selectSize, 'change', $$1.cb.value); + $$1.on(this.selectSize, 'change', this.cb.size); + for (var select of [this.selectMode, this.selectSize]) { + select.value = Conf[select.name]; + } + this.selectRev.checked = /-rev$/.test(Index.currentSort); + this.selectSort.value = Index.currentSort.replace(/-rev$/, ''); + + // Last Long Reply options + this.lastLongOptions = $$1('#lastlong-options', this.navLinks); + this.lastLongInputs = $$('input', this.lastLongOptions); + this.lastLongThresholds = [0, 0]; + this.lastLongOptions.hidden = (this.selectSort.value !== 'lastlong'); + for (let i = 0; i < this.lastLongInputs.length; i++) { + input = this.lastLongInputs[i]; + $$1.on(input, 'change', this.cb.lastLongThresholds); + var tRaw = Conf[`Last Long Reply Thresholds ${i}`]; + input.value = (this.lastLongThresholds[i] = + typeof tRaw === 'object' ? (tRaw[g.BOARD.ID] ?? 100) : tRaw); + } + + // Thread container + this.root = $$1.el('div', {className: 'board json-index'}); + $$1.on(this.root, 'click', this.cb.hoverToggle); + this.cb.size(); + this.cb.hover(); + + // Page list + this.pagelist = $$1.el('div', {className: 'pagelist json-index'}); + $$1.extend(this.pagelist, {innerHTML: PageList}); + $$1('.cataloglink a', this.pagelist).href = CatalogLinks.catalog(); + $$1.on(this.pagelist, 'click', this.cb.pageNav); + + this.update(true); + + $$1.onExists(doc$1, 'title + *', () => d$1.title = d$1.title.replace(/\ -\ Page\ \d+/, '')); + + $$1.onExists(doc$1, '.board > .thread > .postContainer, .board + *', function() { + let el; + g.SITE.Build.hat = $$1('.board > .thread > img:first-child'); + if (g.SITE.Build.hat) { + g.BOARD.threads.forEach(function(thread) { + if (thread.nodes.root) { + return $$1.prepend(thread.nodes.root, g.SITE.Build.hat.cloneNode(false)); + } + }); + $$1.addClass(doc$1, 'hats-enabled'); + $$1.addStyle(`.catalog-thread::after {background-image: url(${g.SITE.Build.hat.src});}`); + } + + const board = $$1('.board'); + $$1.replace(board, Index.root); + if (Index.loaded) { + $$1.event('PostsInserted', null, Index.root); + } + // Hacks: + // - When removing an element from the document during page load, + // its ancestors will still be correctly created inside of it. + // - Creating loadable elements inside of an origin-less document + // will not download them. + // - Combine the two and you get a download canceller! + // Does not work on Firefox unfortunately. bugzil.la/939713 + try { + d$1.implementation.createDocument(null, null, null).appendChild(board); + } catch (error) {} + + for (el of $$('.navLinks')) { $$1.rm(el); } + $$1.rm($$1.id('ctrl-top')); + const topNavPos = $$1.id('delform').previousElementSibling; + $$1.before(topNavPos, $$1.el('hr')); + $$1.before(topNavPos, Index.navLinks); + const timeEl = $$1('#index-last-refresh time', Index.navLinks); + if (timeEl.dataset.utc) { return RelativeDates.update(timeEl); } + }); + + return Main$1.ready(function() { + let pagelist; + if (pagelist = $$1('.pagelist')) { + $$1.replace(pagelist, Index.pagelist); + } + return $$1.rmClass(doc$1, 'index-loading'); + }); + }, + + scroll() { + if (Index.req || !Index.liveThreadData || (Conf['Index Mode'] !== 'infinite') || (window.scrollY <= (doc$1.scrollHeight - (300 + window.innerHeight)))) { return; } + if (Index.pageNum == null) { Index.pageNum = Index.currentPage; } // Avoid having to pushState to keep track of the current page + + const pageNum = ++Index.pageNum; + if (pageNum > Index.pagesNum) { return Index.endNotice(); } + + const threadIDs = Index.threadsOnPage(pageNum); + return Index.buildStructure(threadIDs); + }, + + endNotice: (function() { + let notify = false; + const reset = () => notify = false; + return function() { + if (notify) { return; } + notify = true; + new Notice('info', "Last page reached.", 2); + return setTimeout(reset, 3 * SECOND); + }; + })(), + + menu: { + init() { + if ((g.VIEW !== 'index') || !Conf['Menu'] || !Conf['Thread Hiding Link'] || !Index.enabledOn(g.BOARD)) { return; } + + return Menu.menu.addEntry({ + el: $$1.el('a', { + href: 'javascript:;', + className: 'has-shortcut-text' + } + , {innerHTML: "Shift+click"}), + order: 20, + open({thread}) { + if (Conf['Index Mode'] !== 'catalog') { return false; } + this.el.firstElementChild.textContent = thread.isHidden ? + 'Unhide' + : + 'Hide'; + if (this.cb) { $$1.off(this.el, 'click', this.cb); } + this.cb = function() { + $$1.event('CloseMenu'); + return Index.toggleHide(thread); + }; + $$1.on(this.el, 'click', this.cb); + return true; + } + }); + } + }, + + node() { + if (this.isReply || this.isClone || (Index.threadPosition[this.ID] == null)) { return; } + return this.thread.setPage(Math.floor(Index.threadPosition[this.ID] / Index.threadsNumPerPage) + 1); + }, + + catalogNode() { + return $$1.on(this.nodes.root, 'mousedown click', e => { + if ((e.button !== 0) || !e.shiftKey) { return; } + if (e.type === 'click') { Index.toggleHide(this.thread); } + return e.preventDefault(); + }); + }, // Also on mousedown to prevent highlighting text. + + toggleHide(thread) { + if (Index.showHiddenThreads) { + ThreadHiding.show(thread); + if (!ThreadHiding.db.get({boardID: thread.board.ID, threadID: thread.ID})) { return; } + // Don't save when un-hiding filtered threads. + } else { + ThreadHiding.hide(thread); + } + return ThreadHiding.saveHiddenState(thread); + }, + + cycleSortType() { + let i; + const types = [...Array.from(Index.selectSort.options)].filter(option => !option.disabled); + for (i = 0; i < types.length; i++) { + var type = types[i]; + if (type.selected) { break; } + } + types[(i + 1) % types.length].selected = true; + return $$1.event('change', null, Index.selectSort); + }, + + cb: { + initFinished() { + Index.initFinishedFired = true; + return $$1.queueTask(() => Index.cb.postsInserted()); + }, + + postsInserted() { + if (!Index.initFinishedFired) { return; } + let n = 0; + g.posts.forEach(function(post) { + if (!post.isFetchedQuote && !post.indexRefreshSeen && doc$1.contains(post.nodes.root)) { + post.indexRefreshSeen = true; + return n++; + } + }); + if (n) { return $$1.event('IndexRefresh'); } + }, + + toggleHiddenThreads() { + $$1('#hidden-toggle a', Index.navLinks).textContent = (Index.showHiddenThreads = !Index.showHiddenThreads) ? + 'Hide' + : + 'Show'; + Index.sort(); + return Index.buildIndex(); + }, + + mode() { + Index.pushState({mode: this.value}); + return Index.pageLoad(false); + }, + + sort() { + const value = Index.selectRev.checked ? Index.selectSort.value + "-rev" : Index.selectSort.value; + Index.pushState({sort: value}); + return Index.pageLoad(false); + }, + + resort(e) { + Index.changed.order = true; + if (!e?.detail?.deferred) { return Index.pageLoad(false); } + }, + + perBoardSort() { + Conf['Index Sort'] = this.checked ? dict() : ''; + Index.saveSort(); + for (let i = 0; i < 2; i++) { + Conf[`Last Long Reply Thresholds ${i}`] = this.checked ? dict() : ''; + Index.saveLastLongThresholds(i); + } + }, + + lastLongThresholds() { + const i = [...Array.from(this.parentNode.children)].indexOf(this); + const value = +this.value; + if (!Number.isFinite(value)) { + this.value = Index.lastLongThresholds[i]; + return; + } + Index.lastLongThresholds[i] = value; + Index.saveLastLongThresholds(i); + Index.changed.order = true; + return Index.pageLoad(false); + }, + + size(e) { + if (Conf['Index Mode'] !== 'catalog') { + $$1.rmClass(Index.root, 'catalog-small'); + $$1.rmClass(Index.root, 'catalog-large'); + } else if (Conf['Index Size'] === 'small') { + $$1.addClass(Index.root, 'catalog-small'); + $$1.rmClass(Index.root, 'catalog-large'); + } else { + $$1.addClass(Index.root, 'catalog-large'); + $$1.rmClass(Index.root, 'catalog-small'); + } + if (e) { return Index.buildIndex(); } + }, + + replies() { + return Index.buildIndex(); + }, + + hover() { + return doc$1.classList.toggle('catalog-hover-expand', Conf['Catalog Hover Expand']); + }, + + hoverToggle(e) { + if (Conf['Catalog Hover Toggle'] && $$1.hasClass(doc$1, 'catalog-mode') && !$$1.modifiedClick(e) && !$$1.x('ancestor-or-self::a', e.target)) { + let thread; + const input = Index.inputs['Catalog Hover Expand']; + input.checked = !input.checked; + $$1.event('change', null, input); + if (thread = Get$1.threadFromNode(e.target)) { + Index.cb.catalogReplies.call(thread); + return Index.cb.hoverAdjust.call(thread.OP.nodes); + } + } + }, + + popstate(e) { + if (e?.state) { + const {searched, mode, sort} = e.state; + const page = Index.getCurrentPage(); + Index.setState({search: searched, mode, sort, page}); + return Index.pageLoad(false); + } else { + // page load or hash change + const nCommands = Index.processHash(); + if (Conf['Refreshed Navigation'] && nCommands) { + return Index.update(); + } else { + return Index.pageLoad(); + } + } + }, + + pageNav(e) { + let a; + if ($$1.modifiedClick(e)) { return; } + switch (e.target.nodeName) { + case 'BUTTON': + e.target.blur(); + a = e.target.parentNode; + break; + case 'A': + a = e.target; + break; + default: + return; + } + if (a.textContent === 'Catalog') { return; } + e.preventDefault(); + return Index.userPageNav(+a.pathname.split(/\/+/)[2] || 1); + }, + + refreshFront() { + Index.pushState({page: 1}); + return Index.update(); + }, + + catalogReplies() { + if (Conf['Show Replies'] && $$1.hasClass(doc$1, 'catalog-hover-expand') && !this.catalogView.nodes.replies) { + return Index.buildCatalogReplies(this); + } + }, + + hoverAdjust() { + // Prevent hovered catalog threads from going offscreen. + let x; + if (!$$1.hasClass(doc$1, 'catalog-hover-expand')) { return; } + const rect = this.post.getBoundingClientRect(); + if (x = $$1.minmax(0, -rect.left, doc$1.clientWidth - rect.right)) { + const {style} = this.post; + style.left = `${x}px`; + style.right = `${-x}px`; + return $$1.one(this.root, 'mouseleave', () => style.left = (style.right = null)); + } + } + }, + + scrollToIndex() { + // Scroll to navlinks, or top of board if navlinks are hidden. + return Header$1.scrollToIfNeeded((Index.navLinks.getBoundingClientRect().height ? Index.navLinks : Index.root)); + }, + + getCurrentPage() { + return +window.location.pathname.split(/\/+/)[2] || 1; + }, + + userPageNav(page) { + Index.pushState({page}); + if (Conf['Refreshed Navigation']) { + return Index.update(); + } else { + return Index.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() { + // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=483304 + let hash = location.href.match(/#.*/)?.[0] || ''; + const state = + {replace: true}; + const commands = hash.slice(1).split('/'); + const leftover = []; + for (var command of commands) { + var mode, sort; + if (mode = $$1.getOwn(Index.hashCommands.mode, command)) { + state.mode = mode; + } else if (command === 'index') { + state.mode = Conf['Previous Index Mode']; + state.page = 1; + } else if (sort = $$1.getOwn(Index.hashCommands.sort, command.replace(/-rev$/, ''))) { + state.sort = sort; + if (/-rev$/.test(command)) { state.sort += '-rev'; } + } else if (/^s=/.test(command)) { + state.search = decodeURIComponent(command.slice(2)).replace(/\+/g, ' ').trim(); + } else { + leftover.push(command); + } + } + hash = leftover.join('/'); + if (hash) { state.hash = `#${hash}`; } + Index.pushState(state); + return commands.length - leftover.length; + }, + + pushState(state) { + let {search, hash, replace} = state; + let pageBeforeSearch = history.state?.oldpage; + if ((search != null) && (search !== Index.search)) { + state.page = search ? 1 : (pageBeforeSearch || 1); + if (!search) { + pageBeforeSearch = undefined; + } else if (!Index.search) { + pageBeforeSearch = Index.currentPage; + } + } + Index.setState(state); + const pathname = Index.currentPage === 1 ? `/${g.BOARD}/` : `/${g.BOARD}/${Index.currentPage}`; + if (!hash) { hash = ''; } + return history[replace ? 'replaceState' : 'pushState']({ + mode: Conf['Index Mode'], + sort: Index.currentSort, + searched: Index.search, + oldpage: pageBeforeSearch + } + , '', `${location.protocol}//${location.host}${pathname}${hash}`); + }, + + setState({search, mode, sort, page, hash}) { + if ((search != null) && (search !== Index.search)) { + Index.changed.search = true; + Index.search = search; + } + if ((mode != null) && (mode !== Conf['Index Mode'])) { + Index.changed.mode = true; + Conf['Index Mode'] = mode; + $$1.set('Index Mode', mode); + if ((mode !== 'catalog') && (Conf['Previous Index Mode'] !== mode)) { + Conf['Previous Index Mode'] = mode; + $$1.set('Previous Index Mode', mode); + } + } + if ((sort != null) && (sort !== Index.currentSort)) { + Index.changed.sort = true; + Index.currentSort = sort; + Index.saveSort(); + } + if (['all pages', 'catalog'].includes(Conf['Index Mode'])) { page = 1; } + if ((page != null) && (page !== Index.currentPage)) { + Index.changed.page = true; + Index.currentPage = page; + } + if (hash != null) { + return Index.changed.hash = true; + } + }, + + savePerBoard(key, value) { + if (typeof Conf[key] === 'object') { + Conf[key][g.BOARD.ID] = value; + } else { + Conf[key] = value; + } + return $$1.set(key, Conf[key]); + }, + + saveSort() { + return Index.savePerBoard('Index Sort', Index.currentSort); + }, + + saveLastLongThresholds(i) { + return Index.savePerBoard(`Last Long Reply Thresholds ${i}`, Index.lastLongThresholds[i]); + }, + + pageLoad(scroll=true) { + if (!Index.liveThreadData) { return; } + let {threads, order, search, mode, sort, page, hash} = Index.changed; + if (!threads) { threads = search; } + if (!order) { order = sort; } + if (threads || order) { Index.sort(); } + if (threads) { Index.buildPagelist(); } + if (search) { Index.setupSearch(); } + if (mode) { Index.setupMode(); } + if (sort) { Index.setupSort(); } + if (threads || mode || page || order) { Index.buildIndex(); } + if (threads || page) { Index.setPage(); } + if (scroll && !hash) { Index.scrollToIndex(); } + if (hash) { Header$1.hashScroll(); } + return Index.changed = {}; + }, + + setupMode() { + for (var mode of ['paged', 'infinite', 'all pages', 'catalog']) { + $$1[mode === Conf['Index Mode'] ? 'addClass' : 'rmClass'](doc$1, `${mode.replace(/\ /g, '-')}-mode`); + } + Index.selectMode.value = Conf['Index Mode']; + Index.cb.size(); + Index.showHiddenThreads = false; + return $$1('#hidden-toggle a', Index.navLinks).textContent = 'Show'; + }, + + setupSort() { + Index.selectRev.checked = /-rev$/.test(Index.currentSort); + Index.selectSort.value = Index.currentSort.replace(/-rev$/, ''); + return Index.lastLongOptions.hidden = (Index.selectSort.value !== 'lastlong'); + }, + + getPagesNum() { + if (Index.search) { + return Math.ceil(Index.sortedThreadIDs.length / Index.threadsNumPerPage); + } else { + return Index.pagesNum; + } + }, + + getMaxPageNum() { + return Math.max(1, Index.getPagesNum()); + }, + + buildPagelist() { + const pagesRoot = $$1('.pages', Index.pagelist); + const maxPageNum = Index.getMaxPageNum(); + if (pagesRoot.childElementCount !== maxPageNum) { + const nodes = []; + for (let i = 1, end = maxPageNum; i <= end; i++) { + var a = $$1.el('a', { + textContent: i, + href: i === 1 ? './' : i + } + ); + nodes.push($$1.tn('['), a, $$1.tn('] ')); + } + $$1.rmAll(pagesRoot); + return $$1.add(pagesRoot, nodes); + } + }, + + setPage() { + let a, strong; + const pageNum = Index.currentPage; + const maxPageNum = Index.getMaxPageNum(); + const pagesRoot = $$1('.pages', Index.pagelist); + + // Previous/Next buttons + const prev = pagesRoot.previousElementSibling.firstElementChild; + const next = pagesRoot.nextElementSibling.firstElementChild; + let href = Math.max(pageNum - 1, 1); + prev.href = href === 1 ? './' : href; + prev.firstElementChild.disabled = href === pageNum; + href = Math.min(pageNum + 1, maxPageNum); + next.href = href === 1 ? './' : href; + next.firstElementChild.disabled = href === pageNum; + + // current page + if (strong = $$1('strong', pagesRoot)) { + if (+strong.textContent === pageNum) { return; } + $$1.replace(strong, strong.firstChild); + } else { + strong = $$1.el('strong'); + } + + if (a = pagesRoot.children[pageNum - 1]) { + $$1.before(a, strong); + return $$1.add(strong, a); + } + }, + + updateHideLabel() { + if (!Index.hideLabel) { return; } + let hiddenCount = 0; + for (var threadID of Index.liveThreadIDs) { + if (Index.isHidden(threadID)) { + hiddenCount++; + } + } + if (!hiddenCount) { + Index.hideLabel.hidden = true; + if (Index.showHiddenThreads) { Index.cb.toggleHiddenThreads(); } + return; + } + Index.hideLabel.hidden = false; + return $$1('#hidden-count', Index.navLinks).textContent = hiddenCount === 1 ? + '1 hidden thread' + : + `${hiddenCount} hidden threads`; + }, + + update(firstTime) { + let oldReq; + if (oldReq = Index.req) { + delete Index.req; + oldReq.abort(); + } + + if (Conf['Index Refresh Notifications']) { + // Optional notification for manual refreshes + if (!Index.notice) { Index.notice = new Notice('info', 'Refreshing index...'); } + if (!Index.nTimeout) { Index.nTimeout = setTimeout(() => { + if (Index.notice) { + Index.notice.el.lastElementChild.textContent += ' (disable JSON Index if this takes too long)'; + } + } + , 3 * SECOND); } + } else { + // Also display notice if Index Refresh is taking too long + if (!Index.nTimeout) { Index.nTimeout = setTimeout(() => Index.notice || (Index.notice = new Notice('info', 'Refreshing index... (disable JSON Index if this takes too long)')) + , 3 * SECOND); } + } + + // Hard refresh in case of incomplete page load. + if (!firstTime && (d$1.readyState !== 'loading') && !$$1('.board + *')) { + location.reload(); + return; + } + + Index.req = $$1.whenModified( + g.SITE.urls.catalogJSON({boardID: g.BOARD.ID}), + 'Index', + Index.load + ); + return $$1.addClass(Index.button, 'spin'); + }, + + load() { + let err; + if (this !== Index.req) { return; } // aborted + + $$1.rmClass(Index.button, 'spin'); + const {notice, nTimeout} = Index; + if (nTimeout) { clearTimeout(nTimeout); } + delete Index.nTimeout; + delete Index.req; + delete Index.notice; + + if (![200, 304].includes(this.status)) { + err = `Index refresh failed. ${this.status ? `Error ${this.statusText} (${this.status})` : 'Connection Error'}`; + if (notice) { + notice.setType('warning'); + notice.el.lastElementChild.textContent = err; + setTimeout(notice.close, SECOND); + } else { + new Notice('warning', err, 1); + } + return; + } + + try { + if (this.status === 200) { + Index.parse(this.response); + } else if (this.status === 304) { + Index.pageLoad(); + } + } catch (error) { + err = error; + c.error(`Index failure: ${err.message}`, err.stack); + if (notice) { + notice.setType('error'); + notice.el.lastElementChild.textContent = 'Index refresh failed.'; + setTimeout(notice.close, SECOND); + } else { + new Notice('error', 'Index refresh failed.', 1); + } + return; + } + + if (notice) { + if (Conf['Index Refresh Notifications']) { + notice.setType('success'); + notice.el.lastElementChild.textContent = 'Index refreshed!'; + setTimeout(notice.close, SECOND); + } else { + notice.close(); + } + } + + const timeEl = $$1('#index-last-refresh time', Index.navLinks); + timeEl.dataset.utc = Date.parse(this.getResponseHeader('Last-Modified')); + return RelativeDates.update(timeEl); + }, + + parse(pages) { + $$1.cleanCache(url => /^https?:\/\/a\.4cdn\.org\//.test(url)); + Index.parseThreadList(pages); + Index.changed.threads = true; + return Index.pageLoad(); + }, + + parseThreadList(pages) { + Index.pagesNum = pages.length; + Index.threadsNumPerPage = pages[0]?.threads.length || 1; + Index.liveThreadData = pages.reduce(((arr, next) => arr.concat(next.threads)), []); + Index.liveThreadIDs = Index.liveThreadData.map(data => data.no); + Index.liveThreadDict = dict(); + Index.threadPosition = dict(); + Index.parsedThreads = dict(); + Index.replyData = dict(); + for (let i = 0; i < Index.liveThreadData.length; i++) { + var obj, results; + var data = Index.liveThreadData[i]; + Index.liveThreadDict[data.no] = data; + Index.threadPosition[data.no] = i; + Index.parsedThreads[data.no] = (obj = g.SITE.Build.parseJSON(data, g.BOARD)); + obj.filterResults = (results = Filter.test(obj)); + obj.isOnTop = results.top; + obj.isHidden = results.hide || ThreadHiding.isHidden(obj.boardID, obj.threadID); + if (data.last_replies) { + for (var reply of data.last_replies) { + Index.replyData[`${g.BOARD}.${reply.no}`] = reply; + } + } + } + if (Index.liveThreadData[0]) { + g.SITE.Build.spoilerRange[g.BOARD.ID] = Index.liveThreadData[0].custom_spoiler; + } + g.BOARD.threads.forEach(function(thread) { + if (!Index.liveThreadIDs.includes(thread.ID)) { return thread.collect(); } + }); + $$1.event('IndexUpdate', + {threads: ((Index.liveThreadIDs.map((ID) => `${g.BOARD}.${ID}`)))}); + }, + + isHidden(threadID) { + let thread; + if ((thread = g.BOARD.threads.get(threadID)) && thread.OP && !thread.OP.isFetchedQuote) { + return thread.isHidden; + } else { + return Index.parsedThreads[threadID].isHidden; + } + }, + + isHiddenReply(threadID, replyData) { + return PostHiding.isHidden(g.BOARD.ID, threadID, replyData.no) || Filter.isHidden(g.SITE.Build.parseJSON(replyData, g.BOARD)); + }, + + buildThreads(threadIDs, isCatalog, withReplies) { + let errors; + const threads = []; + const newThreads = []; + let newPosts = []; + for (var ID of threadIDs) { + var opRoot, thread; + try { + var OP; + var threadData = Index.liveThreadDict[ID]; + + if (thread = g.BOARD.threads.get(ID)) { + var isStale = (thread.json !== threadData) && (JSON.stringify(thread.json) !== JSON.stringify(threadData)); + if (isStale) { + thread.setCount('post', threadData.replies + 1, threadData.bumplimit); + thread.setCount('file', threadData.images + !!threadData.ext, threadData.imagelimit); + thread.setStatus('Sticky', !!threadData.sticky); + thread.setStatus('Closed', !!threadData.closed); + } + if (thread.catalogView) { + $$1.rm(thread.catalogView.nodes.replies); + thread.catalogView.nodes.replies = null; + } + } else { + thread = new Thread(ID, g.BOARD); + newThreads.push(thread); + } + var lastPost = threadData.last_replies && threadData.last_replies.length ? threadData.last_replies[threadData.last_replies.length - 1].no : ID; + if (lastPost > thread.lastPost) { thread.lastPost = lastPost; } + thread.json = threadData; + threads.push(thread); + + if ((OP = thread.OP) && !OP.isFetchedQuote) { + OP.setCatalogOP(isCatalog); + thread.setPage(Math.floor(Index.threadPosition[ID] / Index.threadsNumPerPage) + 1); + } else { + var obj = Index.parsedThreads[ID]; + opRoot = g.SITE.Build.post(obj); + OP = new Post(opRoot, thread, g.BOARD); + OP.filterResults = obj.filterResults; + newPosts.push(OP); + } + + if (!isCatalog || !thread.nodes.root) { + g.SITE.Build.thread(thread, threadData, withReplies); + } + } catch (err) { + // Skip posts that we failed to parse. + if (!errors) { errors = []; } + errors.push({ + message: `Parsing of Thread No.${thread} failed. Thread will be skipped.`, + error: err, + html: opRoot?.outerHTML + }); + } + } + if (errors) { Main$1.handleErrors(errors); } + + if (withReplies) { + newPosts = newPosts.concat(Index.buildReplies(threads)); + } + + Main$1.callbackNodes('Thread', newThreads); + Main$1.callbackNodes('Post', newPosts); + Index.updateHideLabel(); + $$1.event('IndexRefreshInternal', {threadIDs: (threads.map((t) => t.fullID)), isCatalog}); + + return threads; + }, + + buildReplies(threads) { + let errors; + const posts = []; + for (var thread of threads) { + var lastReplies; + if (!(lastReplies = Index.liveThreadDict[thread.ID].last_replies)) { continue; } + var nodes = []; + for (var data of lastReplies) { + var node, post; + if ((post = thread.posts.get(data.no)) && !post.isFetchedQuote) { + nodes.push(post.nodes.root); + continue; + } + nodes.push(node = g.SITE.Build.postFromObject(data, thread.board.ID)); + try { + posts.push(new Post(node, thread, thread.board)); + } catch (err) { + // Skip posts that we failed to parse. + if (!errors) { errors = []; } + errors.push({ + message: `Parsing of Post No.${data.no} failed. Post will be skipped.`, + error: err, + html: node?.outerHTML + }); + } + } + $$1.add(thread.nodes.root, nodes); + } + + if (errors) { Main$1.handleErrors(errors); } + return posts; + }, + + buildCatalogViews(threads) { + const catalogThreads = []; + for (var thread of threads) { + if (!thread.catalogView) { + var {ID} = thread; + var page = Math.floor(Index.threadPosition[ID] / Index.threadsNumPerPage) + 1; + var root = g.SITE.Build.catalogThread(thread, Index.liveThreadDict[ID], page); + catalogThreads.push(new CatalogThread(root, thread)); + } + } + Main$1.callbackNodes('CatalogThread', catalogThreads); + }, + + sizeCatalogViews(threads) { + // XXX When browsers support CSS3 attr(), use it instead. + const size = Conf['Index Size'] === 'small' ? 150 : 250; + for (var thread of threads) { + var {thumb} = thread.catalogView.nodes; + var {width, height} = thumb.dataset; + if (!width) { continue; } + var ratio = size / Math.max(width, height); + thumb.style.width = (width * ratio) + 'px'; + thumb.style.height = (height * ratio) + 'px'; + } + }, + + buildCatalogReplies(thread) { + let lastReplies; + const {nodes} = thread.catalogView; + if (!(lastReplies = Index.liveThreadDict[thread.ID].last_replies)) { return; } + + const replies = []; + for (var data of lastReplies) { + if (Index.isHiddenReply(thread.ID, data)) { continue; } + var reply = g.SITE.Build.catalogReply(thread, data); + RelativeDates.update($$1('time', reply)); + $$1.on($$1('.catalog-reply-preview', reply), 'mouseover', QuotePreview.mouseover); + replies.push(reply); + } + + nodes.replies = $$1.el('div', {className: 'catalog-replies'}); + $$1.add(nodes.replies, replies); + $$1.add(thread.OP.nodes.post, nodes.replies); + }, + + sort() { + let threadIDs; + const {liveThreadIDs, liveThreadData} = Index; + if (!liveThreadData) { return; } + const tmp_time = new Date().getTime()/1000; + const sortType = Index.currentSort.replace(/-rev$/, ''); + Index.sortedThreadIDs = (() => { switch (sortType) { + case 'lastreply': case 'lastlong': + var repliesAvailable = liveThreadData.some(thread => thread.last_replies?.length); + var lastlong = function(thread) { + if (!repliesAvailable) { + return thread.last_modified; + } + const iterable = thread.last_replies || []; + for (let i = iterable.length - 1; i >= 0; i--) { + var r = iterable[i]; + if (Index.isHiddenReply(thread.no, r)) { continue; } + if (sortType === 'lastreply') { + return r; + } + var len = r.com ? g.SITE.Build.parseComment(r.com).replace(/[^a-z]/ig, '').length : 0; + if (len >= Index.lastLongThresholds[+!!r.ext]) { + return r; + } + } + if (thread.omitted_posts && thread.last_replies?.length) { return thread.last_replies[0]; } else { return thread; } + }; + var lastlongD = dict(); + for (var thread of liveThreadData) { + lastlongD[thread.no] = lastlong(thread).no; + } + return [...Array.from(liveThreadData)].sort((a, b) => lastlongD[b.no] - lastlongD[a.no]).map(post => post.no); + case 'bump': return liveThreadIDs; + case 'birth': return [...Array.from(liveThreadIDs) ].sort((a, b) => b - a); + case 'replycount': return [...Array.from(liveThreadData)].sort((a, b) => b.replies - a.replies).map(post => post.no); + case 'filecount': return [...Array.from(liveThreadData)].sort((a, b) => b.images - a.images).map(post => post.no); + case 'activity': return [...Array.from(liveThreadData)].sort((a, b) => ((tmp_time-a.time)/(a.replies+1)) - ((tmp_time-b.time)/(b.replies+1))).map(post => post.no); + default: return liveThreadIDs; + } })(); + if (/-rev$/.test(Index.currentSort)) { + Index.sortedThreadIDs = [...Array.from(Index.sortedThreadIDs)].reverse(); + } + if (Index.search && (threadIDs = Index.querySearch(Index.search))) { + Index.sortedThreadIDs = threadIDs; + } + // Sticky threads + Index.sortOnTop(obj => obj.isSticky); + // Highlighted threads + Index.sortOnTop(obj => obj.isOnTop || (Conf['Pin Watched Threads'] && ThreadWatcher$1.isWatchedRaw(obj.boardID, obj.threadID))); + // Non-hidden threads + if (Conf['Anchor Hidden Threads']) { return Index.sortOnTop(obj => !Index.isHidden(obj.threadID)); } + }, + + sortOnTop(match) { + const topThreads = []; + const bottomThreads = []; + for (var ID of Index.sortedThreadIDs) { + (match(Index.parsedThreads[ID]) ? topThreads : bottomThreads).push(ID); + } + return Index.sortedThreadIDs = topThreads.concat(bottomThreads); + }, + + buildIndex() { + let threadIDs; + if (!Index.liveThreadData) { return; } + switch (Conf['Index Mode']) { + case 'all pages': + threadIDs = Index.sortedThreadIDs; + break; + case 'catalog': + threadIDs = Index.sortedThreadIDs.filter(ID => !Index.isHidden(ID) !== Index.showHiddenThreads); + break; + default: + threadIDs = Index.threadsOnPage(Index.currentPage); + } + delete Index.pageNum; + $$1.rmAll(Index.root); + $$1.rmAll(Header$1.hover); + if (Index.loaded && Index.root.parentNode) { + $$1.event('PostsRemoved', null, Index.root); + } + if (Conf['Index Mode'] === 'catalog') { + Index.buildCatalog(threadIDs); + } else { + Index.buildStructure(threadIDs); + } + }, + + threadsOnPage(pageNum) { + const nodesPerPage = Index.threadsNumPerPage; + const offset = nodesPerPage * (pageNum - 1); + return Index.sortedThreadIDs.slice(offset , offset + nodesPerPage); + }, + + buildStructure(threadIDs) { + const threads = Index.buildThreads(threadIDs, false, Conf['Show Replies']); + const nodes = []; + for (var thread of threads) { + nodes.push(thread.nodes.root, $$1.el('hr')); + } + $$1.add(Index.root, nodes); + if (Index.root.parentNode) { + $$1.event('PostsInserted', null, Index.root); + } + Index.loaded = true; + }, + + buildCatalog(threadIDs) { + let i = 0; + const n = threadIDs.length; + let node0 = null; + var fn = function() { + if (node0 && !node0.parentNode) { return; } // Index.root cleared + const j = (i > 0) && Index.root.parentNode ? n : i + 30; + node0 = Index.buildCatalogPart(threadIDs.slice(i, j))[0]; + i = j; + if (i < n) { + return $$1.queueTask(fn); + } else { + if (Index.root.parentNode) { + $$1.event('PostsInserted', null, Index.root); + } + return Index.loaded = true; + } + }; + fn(); + }, + + buildCatalogPart(threadIDs) { + const threads = Index.buildThreads(threadIDs, true); + Index.buildCatalogViews(threads); + Index.sizeCatalogViews(threads); + const nodes = []; + for (var thread of threads) { + thread.OP.setCatalogOP(true); + $$1.add(thread.catalogView.nodes.root, thread.OP.nodes.root); + nodes.push(thread.catalogView.nodes.root); + $$1.on(thread.catalogView.nodes.root, 'mouseenter', Index.cb.catalogReplies.bind(thread)); + $$1.on(thread.OP.nodes.root, 'mouseenter', Index.cb.hoverAdjust.bind(thread.OP.nodes)); + } + $$1.add(Index.root, nodes); + return nodes; + }, + + clearSearch() { + Index.searchInput.value = ''; + Index.onSearchInput(); + return Index.searchInput.focus(); + }, + + setupSearch() { + Index.searchInput.value = Index.search; + if (Index.search) { + return Index.searchInput.dataset.searching = 1; + } else { + // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=1021289 + return Index.searchInput.removeAttribute('data-searching'); + } + }, + + onSearchInput() { + const search = Index.searchInput.value.trim(); + if (search === Index.search) { return; } + Index.pushState({ + search, + replace: !!search === !!Index.search + }); + return Index.pageLoad(false); + }, + + querySearch(query) { + let keywords, match; + if (match = query.match(/^([\w+]+):\/(.*)\/(\w*)$/)) { + let regexp; + try { + regexp = RegExp(match[2], match[3]); + } catch (error) { + return []; + } + return Index.sortedThreadIDs.filter(ID => regexp.test(Filter.values(match[1], Index.parsedThreads[ID]).join('\n'))); + } + if (!(keywords = query.toLowerCase().match(/\S+/g))) { return; } + return Index.sortedThreadIDs.filter(ID => Index.searchMatch(Index.parsedThreads[ID], keywords)); + }, + + searchMatch(obj, keywords) { + const {info, file} = obj; + if (info.comment == null) { info.comment = g.SITE.Build.parseComment(info.commentHTML.innerHTML); } + let text = []; + for (var key of ['comment', 'subject', 'name', 'tripcode']) { + if (key in info) { text.push(info[key]); } + } + if (file) { text.push(file.name); } + text = text.join(' ').toLowerCase(); + for (var keyword of keywords) { + if (-1 === text.indexOf(keyword)) { return false; } + } + return true; + } + }; + var Index$1 = Index; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ThreadHiding = { + init() { + if (!['index', 'catalog'].includes(g.VIEW) || (!Conf['Thread Hiding Buttons'] && !(Conf['Menu'] && Conf['Thread Hiding Link']) && !Conf['JSON Index'])) { return; } + this.db = new DataBoard('hiddenThreads'); + if (g.VIEW === 'catalog') { return this.catalogWatch(); } + this.catalogSet(g.BOARD); + $$1.on(d$1, 'IndexRefreshInternal', this.onIndexRefresh); + if (Conf['Thread Hiding Buttons']) { + $$1.addClass(doc$1, 'thread-hide'); + } + return Callbacks.Post.push({ + name: 'Thread Hiding', + cb: this.node + }); + }, + + catalogSet(board) { + if (!$$1.hasStorage || (g.SITE.software !== 'yotsuba')) { return; } + const hiddenThreads = ThreadHiding.db.get({ + boardID: board.ID, + defaultValue: dict() + }); + for (var threadID in hiddenThreads) { hiddenThreads[threadID] = true; } + return localStorage.setItem(`4chan-hide-t-${board}`, JSON.stringify(hiddenThreads)); + }, + + catalogWatch() { + if (!$$1.hasStorage || (g.SITE.software !== 'yotsuba')) { return; } + this.hiddenThreads = JSON.parse(localStorage.getItem(`4chan-hide-t-${g.BOARD}`)) || {}; + return Main$1.ready(() => // 4chan's catalog sets the style to "display: none;" when hiding or unhiding a thread. + new MutationObserver(ThreadHiding.catalogSave).observe($$1.id('threads'), { + attributes: true, + subtree: true, + attributeFilter: ['style'] + })); + }, + + catalogSave() { + let threadID; + const hiddenThreads2 = JSON.parse(localStorage.getItem(`4chan-hide-t-${g.BOARD}`)) || {}; + for (threadID in hiddenThreads2) { + if (!$$1.hasOwn(ThreadHiding.hiddenThreads, threadID)) { + ThreadHiding.db.set({ + boardID: g.BOARD.ID, + threadID, + val: {makeStub: Conf['Stubs']}}); + } + } + for (threadID in ThreadHiding.hiddenThreads) { + if (!$$1.hasOwn(hiddenThreads2, threadID)) { + ThreadHiding.db.delete({ + boardID: g.BOARD.ID, + threadID + }); + } + } + return ThreadHiding.hiddenThreads = hiddenThreads2; + }, + + isHidden(boardID, threadID) { + return !!(ThreadHiding.db && ThreadHiding.db.get({boardID, threadID})); + }, + + node() { + let data; + if (this.isReply || this.isClone || this.isFetchedQuote) { return; } + + if (Conf['Thread Hiding Buttons']) { + $$1.prepend(this.nodes.root, ThreadHiding.makeButton(this.thread, 'hide')); + } + + if (data = ThreadHiding.db.get({boardID: this.board.ID, threadID: this.ID})) { + return ThreadHiding.hide(this.thread, data.makeStub); + } + }, + + onIndexRefresh() { + return g.BOARD.threads.forEach(function(thread) { + const {root} = thread.nodes; + if (thread.isHidden && thread.stub && !root.contains(thread.stub)) { + return ThreadHiding.makeStub(thread, root); + } + }); + }, + + menu: { + init() { + if ((g.VIEW !== 'index') || !Conf['Menu'] || !Conf['Thread Hiding Link']) { return; } + + let div = $$1.el('div', { + className: 'hide-thread-link', + textContent: 'Hide' + } + ); + + const apply = $$1.el('a', { + textContent: 'Apply', + href: 'javascript:;' + } + ); + $$1.on(apply, 'click', ThreadHiding.menu.hide); + + const makeStub = UI.checkbox('Stubs', 'Make stub'); + + Menu.menu.addEntry({ + el: div, + order: 20, + open({thread, isReply}) { + if (isReply || thread.isHidden || (Conf['JSON Index'] && (Conf['Index Mode'] === 'catalog'))) { + return false; + } + ThreadHiding.menu.thread = thread; + return true; + }, + subEntries: [{el: apply}, {el: makeStub}]}); + + div = $$1.el('a', { + className: 'show-thread-link', + textContent: 'Show', + href: 'javascript:;' + } + ); + $$1.on(div, 'click', ThreadHiding.menu.show); + + Menu.menu.addEntry({ + el: div, + order: 20, + open({thread, isReply}) { + if (isReply || !thread.isHidden || (Conf['JSON Index'] && (Conf['Index Mode'] === 'catalog'))) { + return false; + } + ThreadHiding.menu.thread = thread; + return true; + } + }); + + const hideStubLink = $$1.el('a', { + textContent: 'Hide stub', + href: 'javascript:;' + } + ); + $$1.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); + + return Menu.menu.addEntry({ + el: hideStubLink, + order: 15, + open({thread, isReply}) { + if (isReply || !thread.isHidden || (Conf['JSON Index'] && (Conf['Index Mode'] === 'catalog'))) { + return false; + } + return ThreadHiding.menu.thread = thread; + } + }); + }, + + hide() { + const makeStub = $$1('input', this.parentNode).checked; + const {thread} = ThreadHiding.menu; + ThreadHiding.hide(thread, makeStub); + ThreadHiding.saveHiddenState(thread, makeStub); + return $$1.event('CloseMenu'); + }, + + show() { + const {thread} = ThreadHiding.menu; + ThreadHiding.show(thread); + ThreadHiding.saveHiddenState(thread); + return $$1.event('CloseMenu'); + }, + + hideStub() { + const {thread} = ThreadHiding.menu; + ThreadHiding.show(thread); + ThreadHiding.hide(thread, false); + ThreadHiding.saveHiddenState(thread, false); + $$1.event('CloseMenu'); + } + }, + + makeButton(thread, type) { + const a = $$1.el('a', { + className: `${type}-thread-button`, + href: 'javascript:;' + } + ); + $$1.extend(a, {textContent: type === "hide" ? '➖︎' : '➕︎' }); + a.dataset.fullID = thread.fullID; + $$1.on(a, 'click', ThreadHiding.toggle); + return a; + }, + + makeStub(thread, root) { + let summary, threadDivider; + let numReplies = $$(g.SITE.selectors.replyOriginal, root).length; + if (summary = $$1(g.SITE.selectors.summary, root)) { numReplies += +summary.textContent.match(/\d+/); } + + const a = ThreadHiding.makeButton(thread, 'show'); + $$1.add(a, $$1.tn(` ${thread.OP.info.nameBlock} (${numReplies === 1 ? '1 reply' : `${numReplies} replies`})`)); + thread.stub = $$1.el('div', + {className: 'stub'}); + if (Conf['Menu']) { + $$1.add(thread.stub, [a, Menu.makeButton(thread.OP)]); + } else { + $$1.add(thread.stub, a); + } + $$1.prepend(root, thread.stub); + + // Prevent hiding of thread divider on sites that put it inside the thread + if (threadDivider = $$1(g.SITE.selectors.threadDivider, root)) { + return $$1.addClass(threadDivider, 'threadDivider'); + } + }, + + saveHiddenState(thread, makeStub) { + if (thread.isHidden) { + ThreadHiding.db.set({ + boardID: thread.board.ID, + threadID: thread.ID, + val: {makeStub}}); + } else { + ThreadHiding.db.delete({ + boardID: thread.board.ID, + threadID: thread.ID + }); + } + return ThreadHiding.catalogSet(thread.board); + }, + + toggle(thread) { + if (!(thread instanceof Thread)) { + thread = g.threads.get(this.dataset.fullID); + } + if (thread.isHidden) { + ThreadHiding.show(thread); + } else { + ThreadHiding.hide(thread); + } + return ThreadHiding.saveHiddenState(thread); + }, + + hide(thread, makeStub=Conf['Stubs']) { + if (thread.isHidden) { return; } + const threadRoot = thread.nodes.root; + thread.isHidden = true; + Index$1.updateHideLabel(); + if (thread.catalogView && !Index$1.showHiddenThreads) { + $$1.rm(thread.catalogView.nodes.root); + $$1.event('PostsRemoved', null, Index$1.root); + } + + if (!makeStub) { return threadRoot.hidden = true; } + + return ThreadHiding.makeStub(thread, threadRoot); + }, + + show(thread) { + if (thread.stub) { + $$1.rm(thread.stub); + delete thread.stub; + } + const threadRoot = thread.nodes.root; + threadRoot.hidden = (thread.isHidden = false); + Index$1.updateHideLabel(); + if (thread.catalogView && Index$1.showHiddenThreads) { + $$1.rm(thread.catalogView.nodes.root); + return $$1.event('PostsRemoved', null, Index$1.root); + } + } + }; + + /* + * This file has the code for the jsx to { innerHTML: "safe string" } + * + * Usage: import h from this file. + * Attributes are stringified raw, so the names must be like html text: eg class and not className. + * Boolean values are stringified as followed: true will mean the attribute is there, false means it will be omitted. + * Strings bound to attributes and children will be escaped automatically. + * It returns interface EscapedHtml { innerHTML: "safe string", [isEscaped]: true } + * + * For strings that don't have a parent element you can use fragments: <>. + * Note that you need to import hFragment, which for some reason isn't auto imported on "add all missing imports" + */ + /** + * The symbol indicating that a string is safely escaped. + * This is a symbol so it can't be faked by a json blob from the internet. + */ + const isEscaped = Symbol('isEscaped'); + const voidElements = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'source', 'track', 'wbr',]); + const hFragment = Symbol('hFragment'); + /** Function that jsx/tsx will be compiled to. */ + function h(tag, attributes, ...children) { + let innerHTML = tag === hFragment ? '' : `<${tag}`; + if (attributes) { + for (const [attribute, value] of Object.entries(attributes)) { + if (!value && value !== 0) + continue; + innerHTML += ` ${attribute}`; + if (value === true) + continue; + innerHTML += `="${E(value.toString())}"`; + } + } + if (tag !== hFragment) + innerHTML += '>'; + const isVoid = tag !== hFragment && voidElements.has(tag); + if (isVoid) { + if (children.length) + throw new TypeError(`${tag} is a void html element and can't have child elements`); + } + else { + for (const child of children) { + if (child === null || child === undefined || child === '') + continue; + if (child instanceof Object && "innerHTML" in child && child[isEscaped]) { + innerHTML += child.innerHTML; + continue; + } + innerHTML += E(child.toString()); + } + } + if (!isVoid && tag !== hFragment) + innerHTML += ``; + return { innerHTML, [isEscaped]: true }; + } + + // \u00A0 is non breaking space + const separator = '\u00A0|\u00A0'; + const settingsHtml = h("div", { id: "fourchanx-settings", class: "dialog" }, + h("nav", null, + h("div", { class: "sections-list" }), + h("p", { class: "imp-exp-result warning" }), + h("div", { class: "credits" }, + h("a", { class: "export" }, "Export"), + separator, + h("a", { class: "import" }, "Import"), + separator, + h("a", { class: "reset" }, "Reset Settings"), + separator, + h("input", { type: "file", hidden: true }), + h("a", { href: meta.page, target: "_blank" }, meta.name), + separator, + h("a", { href: meta.changelog, target: "_blank" }, g.VERSION), + separator, + h("a", { href: meta.issues, target: "_blank" }, "Issues"), + separator, + h("a", { href: "javascript:;", class: "close", title: "Close" }, "\u2715"))), + h("div", { class: "section-container" }, + h("section", null))); + + var FilterGuidePage = `
        Filter is disabled.
        +

        + Use regular expressions, one per line.
        + Lines starting with a # will be ignored.
        + For example, /weeaboo/i will filter posts containing the string \`weeaboo\`, case-insensitive.
        + MD5 and Unique ID filtering use exact string matching, not regular expressions. +

        +
          You can use these settings with each regular expression, separate them with semicolons: +
        • + Per boards, separate them with commas. It is global if not specified. Use sfw and nsfw to reference all worksafe or not-worksafe boards.
          + For example: boards:a,jp;.
          + To specify boards on a particular site, put the beginning of the domain and a slash character before the list.
          + Any initial www. should not be included, and all 4chan domains are considered 4chan.org.
          + For example: boards:4:a,jp,sama:a,z;.
          + An asterisk can be used to specify all boards on a site.
          + For example: boards:4:*;.
          +
        • +
        • + Select boards to be excluded from the filter. The syntax is the same as for the boards: option above.
          + For example: exclude:vg,v;. +
        • +
        • + Filter OPs only along with their threads (\`only\`) or replies only (\`no\`).
          + For example: op:only; or op:no;. +
        • +
        • + Filter only posts with files (\`only\`) or only posts without files (\`no\`).
          + For example: file:only; or file:no;. +
        • +
        • + Overrule the \`Show Stubs\` setting if specified: create a stub (\`yes\`) or not (\`no\`).
          + For example: stub:yes; or stub:no;. +
        • +
        • + Highlight instead of hiding. You can specify a class name to use with a userstyle.
          + For example: highlight; or highlight:wallpaper;. +
        • +
        • + Highlighted OPs will have their threads put on top of the board index by default.
          + For example: top:yes; or top:no;. +
        • +
        • + Show a desktop notification instead of hiding.
          + For example: notify;. +
        • +
        • + Filters in the "General" section apply to multiple fields, by default subject,name,filename,comment.
          + The fields can be specified with the type option, separated by commas.
          + For example: type:@{filterTypes};.
          + Types can also be combined with a + sign; this indicates the filter applies to the given fields joined by newlines.
          + For example: type:filename+filesize+dimensions;.
          +
        • +
        +`; + + var SaucePage = `
        Sauce is disabled.
        + +
        + +
        These parameters will be replaced by their corresponding values in the URL and displayed text:
        +
          +
        • %IMG: Full image URL for GIF, JPG, and PNG; thumbnail URL for other types.
        • +
        • %URL: Full image URL.
        • +
        • %TURL: Thumbnail URL.
        • +
        • %name: Original file name.
        • +
        • %board: Current board.
        • +
        • %MD5: MD5 hash in base64.
        • +
        • %sMD5: MD5 hash in base64 using - and _.
        • +
        • %hMD5: MD5 hash in hexadecimal.
        • +
        • %$0: Matched regular expression within the filename.
        • +
        • %$1, %$2, %$3, ... : Subexpressions within the matched regular expression.
        • +
        • %%, %semi: Literal % and ;.
        • +
        +
        Lines starting with a # will be ignored.
        +
        You can specify a display text by appending ;text:[text] to the URL.
        +
        You can specify the applicable boards/sites by appending ;boards:[board1],[board2]. See the Filter guide for details.
        +
        You can specify the applicable file types by appending ;types:[extension1],[extension2].
        +
        You can specify a regular expression the filename must match by appending ;regexp:[regular expression].
        +
        + +`; + + var AdvancedPage = `
        + Archives +
        404 Redirect is disabled.
        + + + + + + + + +
        Thread redirectionPost fetchingFile redirection
        +
        +
        + Archive Lists: Each line below should be an archive list in this format or a URL to load an archive list from.
        + Archive properties can be overriden by another item with the same uid (or if absent, its name). +
        + + Last updated: +
        + +
        + External Catalog +
        External Catalog is disabled. This will be used only as a fallback.
        +
        + URLs of external catalog sites, where %board is to be replaced by the board name.
        + Each URL should be followed by ;boards: and optionally ;exclude: and a list of supported/excluded boards in the format explained in the Filter guide. +
        + +
        + +
        + Override 4chan Image Host +
        Change 4chan image links to this domain. Leave blank for no change.
        +
        + +
        + +
        + Captcha Language +
        Choose from list of language codes. Leave blank to autoselect.
        +
        +
        + +
        + Custom Board Navigation +
        + New lines will be converted into spaces.

        +
        In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
        +
        Board link: g
        +
        Archive link: g-archive
        +
        Internal archive link: g-expired
        +
        Title link: g-title
        +
        Board link (Replace with title when on that board): g-replace
        +
        Full text link: g-full
        +
        Custom text link: g-text:"Install Gentoo"
        +
        Index-only link: g-index
        +
        Catalog-only link: g-catalog
        +
        Index mode: g-mode:"infinite scrolling"
        +
        Index sort: g-sort:"creation date rev"
        +
        External link: external-text:"Google","http://www.google.com"
        +
        Open in new tab: g-nt
        +
        Combinations are possible: g-index-text:"Technology Index"
        +
        Full board list toggle: toggle-all
        +
        +
        + [ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:"Piracy"]
        + will give you
        + [ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
        + if you are on /g/. +
        +
        + +
        + Time Formatting is disabled. +
        :
        + +
        Day: %a, %A, %d, %e
        +
        Month: %m, %b, %B
        +
        Year: %y, %Y
        +
        Hour: %k, %H, %l, %I, %p, %P
        +
        Minute: %M
        +
        Second: %S
        +
        Literal %: %%
        + +
        + +
        + Quote Backlinks formatting is disabled. +
        :
        +
        + +
        + Default pasted content filename +
        .png
        +
        + +
        + File Info Formatting is disabled. +
        :
        +
        Link: %l (truncated), %L (untruncated), %T (4chan filename)
        +
        Filename: %n (truncated), %N (untruncated), %t (4chan filename)
        +
        Download button: %d
        +
        Quick filter MD5: %f
        +
        Spoiler indicator: %p
        +
        Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
        +
        Resolution: %r (Displays 'PDF' for PDF files)
        +
        Tag: %g +
        Literal %: %%
        +
        + +
        + Quick Reply Personas + +

        + One item per line.
        + Items will be added in the relevant input's auto-completion list.
        + Password items will always be used, since there is no password input.
        + Lines starting with a # will be ignored. +

        +
          You can use these settings with each item, separate them with semicolons: +
        • Possible items are: name, options (or equivalently email), subject and password.
        • +
        • Wrap values of items with quotes, like this: options:"sage".
        • +
        • Force values as defaults with the always keyword, for example: options:"sage";always.
        • +
        • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
        • +
        +
        + +
        + Unread Favicon is disabled. + + +
        + +
        + Thread Updater is disabled. +
        + Interval: seconds +
        +
        + +
        + Custom Cooldown Time +
        + Seconds: +
        +
        + +
        + + + +
        For more information about customizing 4chan X's CSS, see the styling guide.
        + + +
        + +
        + Javascript Whitelist +
        + Sources from which Javascript is allowed to be loaded by Content Security Policy.
        + Lines starting with a # will be ignored. +
        + +
        + +
        + Known Banners +
        List of known banners, used for click-to-change feature.
        + +
        +`; + + var KeybindsPage = `
        Keybinds are disabled.
        +
        Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
        +
        Press Backspace to disable a keybind.
        + + +
        ActionsKeybinds
        +`; + + var FilterSelectPage = ` +
        +`; + + var burichan = `/* General */ +:root.burichan .dialog { + background-color: #D6DAF0; + border-color: #B7C5D9; +} +:root.burichan .field:focus, +:root.burichan .field.focus { + border-color: #98E; +} + +/* Header */ +:root.burichan #header-bar.dialog { + background-color: rgba(214,218,240,0.98); +} +:root.burichan:not(.fixed) #header-bar, :root.burichan #header-bar #notifications { + font-size: 11pt; +} +:root.burichan #header-bar, :root.burichan #header-bar #notifications { + color: #89A; +} +:root.burichan #header-bar a, :root.burichan #header-bar #notifications a { + color: #34345C; +} + +/* Settings */ +:root.burichan #fourchanx-settings fieldset, :root.burichan .section-main div::before { + border-color: #B7C5D9; +} +:root.burichan .suboption-list > div:last-of-type { + background-color: #D6DAF0; +} + +/* Catalog */ +:root.burichan.catalog-hover-expand .catalog-container:hover > .post { + background-color: #D6DAF0; +} +:root.burichan.werkTyme .catalog-thread:not(:hover), +:root.burichan.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.burichan.catalog-hover-expand .catalog-container:hover > .post, +:root.burichan.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #B7C5D9; +} + +/* Quote */ +:root.burichan .backlink.deadlink { + color: #34345C !important; +} +:root.burichan .inline { + border-color: #B7C5D9; + background-color: rgba(255, 255, 255, .14); +} + +/* Fappe and Werk Tyme */ +:root.burichan .indicator { + color: #D6DAF0; +} + +/* Anonymize */ +:root.burichan.anonymize $site$info$name::before { + font-size: 12pt; +} + +/* QR */ +.burichan #dump-list::-webkit-scrollbar-thumb { + background-color: #D6DAF0; + border-color: #B7C5D9; +} +:root.burichan .qr-preview { + background-color: rgba(0, 0, 0, .15); +} +:root.burichan .qr-link { + border-color: rgb(199, 203, 225) rgb(199, 203, 225) rgb(184, 188, 210); + background: linear-gradient(#E5E9FF, #D6DAF0) repeat scroll 0% 0% transparent; +} +:root.burichan .qr-link:hover { + background: #D9DDF3; +} + +/* Menu */ +:root.burichan #menu { + color: #000000; +} +:root.burichan .entry { + font-size: 12pt; +} +:root.burichan .focused.entry { + background: rgba(255, 255, 255, .33); +} + +/* Unread */ +:root.burichan .unread-mark-read { + background-color: rgba(214,218,240,0.5); +} + +/* Thread Watcher */ +:root.burichan .replies-quoting-you > a, :root.burichan #watcher-link.replies-quoting-you, :root.burichan .last-page > a > .watcher-page { + color: #F00; +} + +/* Watcher Favicon */ +:root.burichan .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + var futaba = `/* General */ +:root.futaba .dialog { + background-color: #F0E0D6; + border-color: #D9BFB7; +} +:root.futaba .field:focus, +:root.futaba .field.focus { + border-color: #EA8; +} + +/* Header */ +:root.futaba #header-bar.dialog { + background-color: rgba(240,224,214,0.98); +} +:root.futaba:not(.fixed) #header-bar, :root.futaba #notifications { + font-size: 11pt; +} +:root.futaba #header-bar, :root.futaba #notifications { + color: #B86; +} +:root.futaba #header-bar a, :root.futaba #notifications a { + color: #800000; +} + +/* Settings */ +:root.futaba #fourchanx-settings fieldset, :root.futaba .section-main div::before { + border-color: #D9BFB7; +} +:root.futaba .suboption-list > div:last-of-type { + background-color: #F0E0D6; +} + +/* Catalog */ +:root.futaba.catalog-hover-expand .catalog-container:hover > .post { + background-color: #F0E0D6; +} +:root.futaba.werkTyme .catalog-thread:not(:hover), +:root.futaba.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.futaba.catalog-hover-expand .catalog-container:hover > .post, +:root.futaba.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #D9BFB7; +} + +/* Quote */ +:root.futaba .backlink.deadlink { + color: #00E !important; +} +:root.futaba .inline { + border-color: #D9BFB7; + background-color: rgba(255, 255, 255, .14); +} + +/* Fappe and Werk Tyme */ +:root.futaba .indicator { + color: #F0E0D6; +} + +/* Anonymize */ +:root.futaba.anonymize $site$info$name::before { + font-size: 12pt; +} + +/* QR */ +.futaba #dump-list::-webkit-scrollbar-thumb { + background-color: #F0E0D6; + border-color: #D9BFB7; +} +:root.futaba .qr-preview { + background-color: rgba(0, 0, 0, .15); +} +:root.futaba .qr-link { + border-color: rgb(225, 209, 199) rgb(225, 209, 199) rgb(210, 194, 184); + background: linear-gradient(#FFEFE5, #F0E0D6) repeat scroll 0% 0% transparent; +} +:root.futaba .qr-link:hover { + background: #F0E0D6; +} + +/* Menu */ +:root.futaba #menu { + color: #800000; +} +:root.futaba .entry { + font-size: 12pt; +} +:root.futaba .focused.entry { + background: rgba(255, 255, 255, .33); +} + +/* Unread */ +:root.futaba .unread-mark-read { + background-color: rgba(240,224,214,0.5); +} + +/* Thread Watcher */ +:root.futaba .replies-quoting-you > a, :root.futaba #watcher-link.replies-quoting-you, :root.futaba .last-page > a > .watcher-page { + color: #F00; +} + +/* Watcher Favicon */ +:root.futaba .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + var linkifyAudio = '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=='; + + var linkifyBitchute = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAadQTFRFAAAAwzw8xDs7cY6O0iws0ysrtF9f0Sws1CwsyzU1zTIy1igoyzQ01icnY7i4t0hI0S4u0ysr1Soq1ikp1ikp1Soq0ysr0S4uu0VFzjEx1Csr1ygo2Ccn2Ccn1ygo1CoqzjExzjAw1Skp2Ccn2Ccn1ikp0TAwxzY21Soq1SoqyzQ00iws1ygo1ygo0yws1Soq1Skp1igo1igo1igo1igo1igo1igo1Coq1Soq0C0t1ygo1ygo0S4unV5e1Csr1ygo1ygo1CsruUdHxzg41Skp1ygo1CsryTU10C4u1igo1ycn1ygo0i0txjo60S0t1ikp1ygo1ikp1Cws1Coq1Coq0yws0S0tyzQ00iws1Soq0ysr0i0txDs72Ccn2CUl2CYm2CQk3EFB2S8v2zw82jY24FZW3D0931FR3EBA3UND8LS04FVV7qys4V9f4WBg+erq766u9t7e7qqq2Ckp54KC9+Pj6pSU+Ojo5XNz9NHR6YqK8bu765ub5G5u9M3N6ImJ88vL5XV165eX3UVF6pWV3UhI2Soq2jU12Coq2jQ02Cgo2Sws////FaxLuAAAAF10Uk5TAAAAAAAAAAAAAAAAAAAAASJnoLy9oWolAhBz1vr72XgTGKf8/a4cCpuiDVvz9mS6xOvy9vzg6aGsPOToRAFv9fh2Awm07XgIMd765UEDOsfemVhhY00nBommbCkEI8horgAAAL5JREFUKBUFwbFKA0EUQNF7387sMq4EmzRpLSSdIBYKFv6Af2prnSYkRT4gWFgkCBJQ0EIFdcZzBCeqqh4qdk7VW2ChPusw02sAYKU7z7wEAAA2piQKFbrWSHazc1J0XWs5pdxPDykcVX+7Y9UxUsSo+s7PibqPFBRV/C5qi4i/UkrJrc7L47Bt4ZWnUaMCAE9GSrtKBQD2fR+bnAEAeOn7dUTOwApe35bDsPz0zsniQlV98IN0tJ3f6P0XAMA/kxou7OXCdnoAAAAASUVORK5CYII='; + + var linkifyClyp = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAwUExURTSY22ey5E2l4KbS75rM7Y3F64C/6f///8zl9nS45r/f9PL5/UGe3bPY8Vqr4v///wNjrzUAAAABYktHRA8YugDZAAAAB3RJTUUH4AINEi85AIH95AAAAE9JREFUCNdjYMAGGBWgDGYHCM2a3hkAZmi0dzSBaKaO9o5moCqmLiCjYzNQyw4QowIodQzI6E0AKcpo72gE6+Jyb1kAMehUA9RktgdYbQYAjGIVNGGXBJkAAAAASUVORK5CYII='; + + var linkifyDailymotion = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAnUExURQBk3ff6/trp+kKO5wZt3xx54q7P9Ozz/IS17zOG5WKh653E8sbc9/GbbcoAAABZSURBVAjXY2BAASyhDhAGc9oECMOjyAAiESEEYrBYpLWBGcwHxcvBjDDxHelghpF0yDQwY3kVgweEUeEQDWbMEepqAjO8FMsLIeYsU8o+BrbCdWboTAe4AwALXxWGjW41FwAAAABJRU5ErkJggg=='; + + var linkifyGfycat = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAjVBMVEWn3gCo3gSr3w2t4BSu4Bav4Ri35C+45DK45DO55DXA50rA50vB50zC6E/D6FTF6VjG6VvL62vN7G/P7XbQ7XfW74vY8JDa8ZTe8qDe8qLf86Pi9Kzj9K7k9LHp9sDp98Lq98Ps+Mr0++L5/O75/fD6/fH6/fL6/fP7/fT7/fb8/ff8/vj8/vn+/v7///91X4cfAAAAcklEQVR42o3M2xKBUACF4aVQckrIuRJK6H//x2sme4/MuPDfre9i6c/Cc3U5Dj87BuAxsXvGu6JvIIXEHRWwNHCHQNrCzkAFkbSBg4EM8i+Yw7PXBa3zRfuxVyf/Bis7nKwGKAcWxgC8prI5Sc315OlnDfzpDar2S9/oAAAAAElFTkSuQmCC'; + + var linkifyGist = '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=='; + + var linkifyImage = '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='; + + var linkifyInstallgentoo = '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'; + + var linkifyLiveleak = '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='; + + var linkifyPastebin = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB1FBMVEUAAAAAAAAAAABWYWwAAABbY3BbYm5dZnFdZXJeZnMEBAQHCAhYYGpdZnFdZnBgaHIlJyomKCooKi09QkdESU5eZGtdYmhdYmleY2lrcXdqb3Rqb3Rqb3SSmJ+SlJeWmJutr7GtrrCWm6ChpKhbW1tmZmZvb290dHR3d3d4eHh5eXl6enp8fHx+gIJ/f3+CgoKDg4OEhISFhYWHh4eKioqKjI2Li4uMjIyOjo6Pj4+QkJCRkZGSkpKUlJSVl5mWlpaYmZqZm52ampqbm5ucnJydnZ2enp6fn5+hoaGioqKkpKSkpaalpaWmp6mmp6qnqauoqKioqquoqq2qqqqrrK2srKysra6srrCsrrGurq6vr6+wsLCxsbGysrKztLa0tLS1t7m2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr7AwMDAwsTBwcHExcfFxcXFxsnGxsbHx8fIyMjJycnMzMzNzc3Ozs7O0NLPz8/Q0NDR0dHR09XT09PV1dXV1dbV1tfV19rW1tbX19fX19jY2tzZ2dnZ2tva2tra3N3a3N7c3Nze3t7f39/f4OHg4ODi4uLl5+jm5ubs7Ozs7e3u7u7v7+/v8PDw8PDx8fHy8vLz8/P29vYSoLMZAAAAJHRSTlMABAUGCwsNHCAiLzMzMzZEYGJwgIuOnJycnqmqq9bc3+/w8fkZ0N/uAAAA/klEQVQoU2NgYGDl5YMDdgYGBmZZ3964CYFtIR3e9Q7K/AwMHI55KfaFmcHWMy3K3MwlGRg4wz0zdYpcorRbNbL0LaWAAp3ts2umV8wo6MupTauQBgqUG03VL7W3sfZSb1erAgm02M+yzYrVCXUy6zapAQlUx/dEdyX3J3ZHVUYVywAF8o2rDNN1Go2jzGLMokAC2QbuSc42mXmaOXop9iAtCXrJ5qXWjT59Abl2ESJAAX/tSIMMiyrrqQ3T6uS5gQK6kSqpqkUermGTexQFmYACflqR+hlWZSamzQpCLEDPsSmVVDT1TJw0JUhOAMRnYOARFRMTE5cQF+ZiBPIAII5B3EVG0b4AAAAASUVORK5CYII='; + + var linkifyPeertube = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABIFBMVEUhHyAAAABzPBnxaA3CWBEnJSYbGRptbW16enpzc3PTayWhb04hHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyApIh+0UhMfHiBWMhvsZg7zaQ0hHyAhHyAXHCHzaQ3xaA3xaA3xaA3xaA0hHyAhHyDxaA3xaA3xaA3xaA3xaA3xaA0oJickIiMdGxwUEhPxaA3xaA3xaA1sbGxwcHB3d3eFhYXxaA3xaA3xaA1zc3Nzc3Nzc3Nzc3Nzc3PxaA3xaA3xaA1zc3Nzc3NtdHjxaA3xaA1yc3STcFnvaA/yaAxzc3N4c2/FbDFzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3MhHyDxaA1zc3MAAAAfljyVAAAAXHRSTlMAAAAAAAAAAAAAAAAZkjMBHOLXYArj8p0u2VsJ1XaGL/OhKyXc1WEN2gwk2/SjKgEYiS4B/tYFGosqAdleAxzj12ML9Z8s850rJWbYeYMs1F8Koiri1V0MGZY0AYbIBFIAAAABYktHRAH/Ai3eAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4wYXFBUVX81QWQAAAKxJREFUGNNVz9UWgkAQANDBtdbu7lZsxe7ubpH//wxBPKDzNvdMAmi0Oj0QQgAYjCazBX7BStvsDqHoAzTtdLklf+Dx+vwICRAIhsKRaCyOvpAwJ6Up8pXOZHOIAFm+UCzJEQuvMhWrIFBUa/WGkodmq40Ad7q9/kDFwnA05lpYYCbT2ZykFvxQDhhmuVpvcvxaHra7vfp72KflcMSYEOB0vlyx+By+3R9PMSfe+P0enM1454kAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDYtMjRUMDM6MjE6MjEtMDc6MDDse6MAAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTA2LTI0VDAzOjIxOjIxLTA3OjAwnSYbvAAAAABJRU5ErkJggg=='; + + var linkifySoundcloud = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABsklEQVQ4y5WTy2pUQRCGv2rbzDjJeAlIBmOyipGIIJqFEBDElwh4yULGeRFXPoEIBl/AvQ/gC2RnxCAoxijiwks852S6+3dxzslcHJCpTXVX11/Xv0097gLPgVNMJxnQNfX4zsqleWbnpoMf/oa9d988MM9MC/rp+E0a+A0dsVobMNMCOO8B6McRoABJI+A6gJmN3D2A8jgEBCEkSEMBrcrsDAzDWWn3AjgKFaDMmgRqniGFgsaDp1jrLOngDf1XT1D+A1dFc4MKAkkiCVKjjVu7g9+4Rzx4i1u6hjXbuMWr0O5QPNvCu7IaCZwEKQukLGDrm5x8uI0tr6MkiGlkiv7yLfzN+6S5i6QsIMABkEfcxhbWWYMkVAOjxvYAjc3HNHrbKI9VBQBFwF25XQKSBjqIf1YBuAurEMrczgDygD6/x2LCpFLXLUyQ+PoldphhBhYfIX09XU1+Flaukz7uYqs3SHs7cG4BmTsmkBUF9mmXEwa28BNLPaQPLepuNcbGSWQquQC2/Kdcox1FUGkcB0ykck1nA2+wTzMs8stGnP4rbWGw74EuS/GFQWfK7/wF6P4F7fzIAYkdmdEAAAAASUVORK5CYII='; + + var linkifyStreamable = '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'; + + var linkifyTwitchtv = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAYUExURf///2RBpWRBpWRBpWRBpWRBpWRBpf///+zQyUYAAAAGdFJOUwFdZX0lTzs4r5oAAAABYktHRAcWYYjrAAAAB3RJTUUH4AINEi42iSXRNAAAAD1JREFUCNdjYEiDAAZGGIMtjQEEUBlMCWoEGci6mGEMsxQgIy0BiB3AjLS0FAYQIw0kwABipoI1AhkBQBIAFCIXxiHgq80AAAAASUVORK5CYII='; + + var linkifyTwitter = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAEsUExURf///1Cf21Gg3FGi31Gh3VKj4FGh3lKj4VKk4lKl41Ol5FOn51Sp6VSo6FOn5lCf21Gg3FGh3VGi31Gi31Gh3lGg3FGg3FGg3FGg3FGh3lGg3FGi31Kk4lKj4FGh3lGi31Kk4lGh3lGg3FGh3lOm5FOm5VGi31Kj4VSo6FGi31Gh3VGg3FKj4FOn51Gi31So6FWr7VOl5FGi31On51Sq6lKk4lOo51Sp6VOm5FSq61Ws7VOn51Oo51Sq61Ol5FOm5FSq61Wr7VOo51On51Sr7FWs7VSp6lGg3FGh3VOm5FWr7VSp6lKj4VOm5FSo6FSr7FWs7VWs7VWr7VSq6lOo51Om5FOo51So6FOm5VOl5FSq61Ws7VSr7FSp6lSp6VWs7lWr7VKk4lSq6v///6E3MNsAAABVdFJOUwAAAAAAAAAAAAAAAAAAAB0Ii+3xnBVTJhfsMKb+qTEp9GwBF/7lLAbo0m4pLkUTdvk2Ev3+EZnOBo/3Z8ffCRzH/D0OqPxiLnvx3UI8m9n1++GwXQZNS29BAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+ACDRIwBwy67tEAAADKSURBVBjTY2BAB4xogIGRH8IQEBQSFhEVE2eQkJQC8ZmkQ8PCI2Rk5RjkIxUUlRgZlVWioqNjYlXVGNQ14iI1tbR14qLj4+MTdJkZ9PQNosJCE0OjgPz4KEMWBiPjhPiEmKQokIJ4E1MmBmazhHg4MGdlYmCzsLSC8ROsmRkZmFht4Eps7ViADmOzd4DyHZ2YmYACTOzOLmATXd04mIBOd/eQ9owFCXh5c7KB/MLi4+vnHxAYFBzCwcYEEmBi5uLm4eHl42RmAnsSAMZBLgZiFUQ5AAAAAElFTkSuQmCC'; + + var linkifyVideo = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAxgDGAP8nNqN7AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gMZBjQQLEEqGwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAA5SURBVDjLY2AYaMDIwMDwn1JD/lPCZhpwL+B1wf///ykzgBhDiAoDfIYQZQAjIyP5BuDTPJqQqAQAvW0ZAMk8+EEAAAAASUVORK5CYII='; + + var linkifyVidlii = '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='; + + var linkifyCimeo = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAYFBMVEUAAAAIdZUKh6sLlLkLmr4LmsAMp88NrdYVW3MZj7Acstkrt9s1e5E7vN5EfI9JvdtKwuBijp5kpbl30eiDt8aG1uqRr7qTyNehxM+k4PCy3enB3OTg6Ovv9PXw+fz////L9U5WAAAAAXRSTlMAQObYZgAAAIFJREFUeNplz90OwiAMBWAQpAoyxclkP3je/y0H2AQXz0WT8100rRD6kNI9/cRroemQL3hXhoujZYj4OHoAmBvYGcBISwbWBvfXCrytnIDUQMkbsBpagMA7zhtQdyTFQAmIG7IkYniiZuh3XGsPqoOZkMOJOpAcLqUzNFGGu/57fwc1hgtp0mVSyQAAAABJRU5ErkJggg=='; + + var linkifyVine = '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'; + + var linkifyVocaroo = '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=='; + + var linkifyYoutube = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAYAAABr5z2BAAABIklEQVQoz53LvUrDUBjG8bOoOammSf1IoBSvoCB4JeIqOHgBLt6AIMRBBQelWurQ2kERnMRBsBUcIp5FJSBI5oQsJVkkUHh8W0o5nhaFHvjBgef/Mq+Q46RJBMkI/vE+aOus956tnEswIZe1LV0QyJ5sE2GzgZfVMtRNIdiDpccEssdlB1mW4bvTwdvWJtRdErM7U+8S/FJykCRJX5qm+KpVce8UMNLRLbulz4iSjTAMh6Iowsd5BeNadp3nUF0VlxAEwZBotXC0Usa4ll3meZdA1iguwvf9vpvDA2wvmKgYGtSud8suDB4TyGr2PF49D/vra9jRZ1BVdknMzgwuCGSnZEObwu6sBnVTCHZiaC7BhFx2PKdxUidiAH/4lLo9Mv0DELVs9qsOHXwAAAAASUVORK5CYII='; + + var photon = `/* General */ +:root.photon .dialog { + background-color: #DDD; + border-color: #CCC; +} +:root.photon .field:focus, +:root.photon .field.focus { + border-color: #EA8; +} + +/* 4chan style fixes */ +:root.photon #arc-list tr:nth-of-type(odd) span.quote { + color: #C0E17A; +} +:root.photon.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(221, 0, 0, .8) !important; +} +:root.photon.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(221, 0, 0, .8) !important; +} + +/* Header */ +:root.photon #header-bar.dialog { + background-color: rgba(221,221,221,0.98); +} +:root.photon:not(.fixed) #header-bar, :root.photon #notifications { + font-size: 9pt; +} +:root.photon #header-bar, :root.photon #notifications { + color: #333; +} +:root.photon #header-bar a, :root.photon #notifications a { + color: #FF6600; +} + +/* Settings */ +:root.photon #fourchanx-settings fieldset, :root.photon .section-main div::before { + border-color: #CCC; +} +:root.photon .suboption-list > div:last-of-type { + background-color: #DDD; +} + +/* Catalog */ +:root.photon.catalog-hover-expand .catalog-container:hover > .post { + background-color: #DDD; +} +:root.photon.werkTyme .catalog-thread:not(:hover), +:root.photon.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.photon.catalog-hover-expand .catalog-container:hover > .post, +:root.photon.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #CCC; +} + +/* Quote */ +:root.photon .backlink.deadlink { + color: #F60 !important; +} +:root.photon .inline { + border-color: #CCC; + background-color: rgba(255, 255, 255, .14); +} + +/* Fappe and Werk Tyme */ +:root.photon .indicator { + color: #DDD; +} + +/* QR */ +.photon #dump-list::-webkit-scrollbar-thumb { + background-color: #DDD; + border-color: #CCC; +} +:root.photon .qr-preview { + background-color: rgba(0, 0, 0, .15); +} +:root.photon .qr-link { + border-color: rgb(206, 206, 206) rgb(206, 206, 206) rgb(191, 191, 191); + background: linear-gradient(#ECECEC, #DDD) repeat scroll 0% 0% transparent; +} +:root.photon .qr-link:hover { + background: #DDDDDD; +} + +/* Menu */ +:root.photon #menu { + color: #333; +} +:root.photon .entry { + font-size: 10pt; +} +:root.photon .focused.entry { + background: rgba(255, 255, 255, .33); +} + +/* Unread */ +:root.photon .unread-mark-read { + background-color: rgba(221,221,221,0.5); +} + +/* Thread Watcher */ +:root.photon .replies-quoting-you > a, :root.photon #watcher-link.replies-quoting-you, :root.photon .last-page > a > .watcher-page { + color: #00F !important; +} + +/* Watcher Favicon */ +:root.photon .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + var report = `#g-recaptcha, +:root:not(.js-enabled) #captchaContainerAlt { + height: auto; +} +#captchaContainerAlt td:nth-child(2) { + display: table-cell !important; +} + +/* Archive reports */ +#archive-report { + padding: 3px; +} +#archive-report-enabled { + vertical-align: middle; +} +#archive-report > label { + display: block; +} +#archive-report-reason { + display: block; + width: 98%; +} +.archive-report-success { + color: green; +} +.archive-report-error { + color: red; +}`; + + var spooky = `/* General */ +:root.spooky .dialog { + background-color: #171526; + border-color: #707070; +} +:root.spooky .field:focus, +:root.spooky .field.focus { + border-color: #98E; +} + +/* 4chan style fixes */ +:root.spooky #arc-list span.quote { + color: #634C2C; +} +:root.spooky.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(145, 182, 214, .8) !important; +} +:root.spooky.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(145, 182, 214, .8) !important; +} + +/* Header */ +:root.spooky #header-bar.dialog { + background-color: rgba(23,21,38,0.98); +} +:root.spooky:not(.fixed) #header-bar, :root.spooky #notifications { + font-size: 9pt; +} +:root.spooky #header-bar, :root.spooky #notifications { + color: #C49756; +} +:root.spooky #board-list a, :root.spooky #shortcuts a { + color: #FE9600; +} +:root.spooky.shortcut-icons .native-settings { + background-image: url('//s.4cdn.org/image/favicon-ws.ico'); +} + +/* Settings */ +:root.spooky #fourchanx-settings fieldset, :root.spooky .section-main div::before { + border-color: #707070; +} +:root.spooky .suboption-list > div:last-of-type { + background-color: #171526; +} + +/* Catalog */ +:root.spooky.catalog-hover-expand .catalog-container:hover > .post { + background-color: #171526; +} +:root.spooky.werkTyme .catalog-thread:not(:hover), +:root.spooky.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.spooky.catalog-hover-expand .catalog-container:hover > .post, +:root.spooky.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #707070; +} + +/* Quote */ +:root.spooky .backlink.deadlink { + color: #FE9600 !important; +} +:root.spooky .inline { + border-color: #707070; + background-color: rgba(255, 255, 255, .14); +} + +/* Fappe and Werk Tyme */ +:root.spooky .indicator { + color: #171526; +} + +/* Highlighting */ +:root.spooky .qphl { + outline: 2px solid rgba(145, 182, 214, .8); +} +:root.spooky.highlight-you .quotesYou$site$highlightable$op, +:root.spooky.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(145, 182, 214, .8); +} +:root.spooky.highlight-own .yourPost$site$highlightable$op, +:root.spooky.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(145, 182, 214, .8); +} +:root.spooky .filter-highlight$site$highlightable$op, +:root.spooky .filter-highlight$site$highlightable$reply { + box-shadow: inset 5px 0 rgba(145, 182, 214, .5); +} +:root.spooky.highlight-own .yourPost > $site$sideArrows, +:root.spooky.highlight-you .quotesYou > $site$sideArrows, +:root.spooky .filter-highlight > $site$sideArrows { + color: rgb(155, 185, 210); +} + +/* QR */ +.spooky #dump-list::-webkit-scrollbar-thumb { + background-color: #171526; + border-color: #707070; +} +:root.spooky .qr-preview { + background-color: rgba(0, 0, 0, .15); +} +:root.spooky #qr .field { + background-color: rgb(26, 27, 29); + color: rgb(197,200,198); + border-color: rgb(40, 41, 42); +} +:root.spooky #qr .field:focus, +:root.spooky #qr .field.focus { + border-color: rgb(254, 150, 0) !important; + background-color: rgb(30,32,36); +} +:root.spooky .persona button { + background: linear-gradient(to bottom, #2E3035, #222427) no-repeat; + color: rgb(197,200,198); + border-color: rgb(40, 41, 42); + outline: none; +} +:root.spooky .persona button::-moz-focus-inner { + border: none; +} +:root.spooky .persona button:focus { + border-color: rgb(254, 150, 0); +} +:root.spooky #qr.sjis-preview #sjis-toggle, +:root.spooky #qr.tex-preview #tex-preview-button { + background: rgb(26, 27, 29); +} +:root.spooky #qr select, +:root.spooky #file-n-submit > input, +:root.spooky #qr-draw-button { + border-color: rgb(40, 41, 42); +} +:root.spooky #qr-filename { + color: rgb(197,200,198); +} + +:root.spooky .qr-link { + border-color: rgb(8, 6, 23) rgb(8, 6, 23) rgb(0, 0, 8); + background: linear-gradient(#262435, #171526) repeat scroll 0% 0% transparent; +} +:root.spooky .qr-link:hover { + background: #1A1829; +} + + +/* Menu */ +:root.spooky #menu { + color: #FE9600; +} +:root.spooky .entry { + font-size: 10pt; +} +:root.spooky .focused.entry { + background: rgba(255, 255, 255, .33); +} + +/* Unread */ +:root.spooky .unread-line { + border-color: rgb(197, 200, 198); + visibility: visible; + opacity: 1; +} +:root.spooky .unread-mark-read { + background-color: rgba(23,21,38,0.5); +} + +/* Thread Watcher */ +:root.spooky .replies-quoting-you > a, :root.spooky #watcher-link.replies-quoting-you, :root.spooky .last-page > a > .watcher-page { + color: #F00 !important; +} + +/* Watcher Favicon */ +:root.spooky .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + var style = `/* General */ +.dialog { + border: 1px solid; + display: block; + background-color: inherit; +} +.dialog:not(#qr):not(#thread-watcher):not(#header-bar) { + box-shadow: 0 1px 2px rgba(0, 0, 0, .15); +} +#qr, +#thread-watcher { + box-shadow: -1px 2px 2px rgba(0, 0, 0, 0.25); +} +.captcha-img, +.field { + background-color: #FFF; + border: 1px solid #CCC; + -moz-box-sizing: border-box; + box-sizing: border-box; + color: #333; + font: 13px sans-serif; + outline: none; + transition: color .25s, border-color .25s; +} +.field::-moz-placeholder { + color: #AAA; + font-size: 13px; + opacity: 1; +} +.captch-img:hover, +.field:hover { + border-color: #999; +} +.field:hover, .field:focus, .field.focus { + color: #000; +} +.field[disabled] { + background-color: #F2F2F2; + color: #888; +} +.field::-webkit-search-decoration { + display: none; +} +.move { + cursor: move; + overflow: hidden; +} +label { + cursor: pointer; +} +a[href="javascript:;"] { + text-decoration: none; +} +.warning { + color: red; +} +:root.sw-yotsuba #boardNavDesktop, :root.sw-yotsuba #boardNavMobile { + display: none !important; +} +:root.hide-bottom-board-list $site$boardListBottom { + display: none; +} +body.hasDropDownNav{ + margin-top: 5px; +} +:root:not(.keyboard-focus) a { + outline: none; +} +.painted { + border-radius: 3px; + padding: 0px 2px; +} +[hidden] { + display: none !important; +} + +/* 4chan style fixes */ +/* overrides 4chan CSS on div.opContainer, div.op */ +:root.sw-yotsuba .opContainer, :root.sw-yotsuba .op { + display: block; + overflow: visible; +} +:root.sw-yotsuba .reply > .file > .fileText { + margin: 0 20px; +} +:root.sw-yotsuba #arc-list span.quote { + color: #789922; +} +:root.sw-yotsuba .fileText a { + unicode-bidi: -moz-isolate; + unicode-bidi: -webkit-isolate; +} +:root.sw-yotsuba #g-recaptcha { + min-height: 78px; + height: auto; +} +:root.sw-yotsuba:not(.js-enabled) #postForm { + display: table; +} +:root.sw-yotsuba #captchaContainerAlt td:nth-child(2) { + display: table-cell !important; +} +:root.sw-yotsuba canvas#tegaki-canvas { + background: none; +} +/* Disable obnoxious captcha fade-in. */ +:root.sw-yotsuba > body > div:last-of-type { + transition: none !important; +} +/* Fix captcha scrolling to top of page. */ +:root.sw-yotsuba > body > div[style*=" top: -10000px;"] { + visibility: hidden !important; +} +/* Make long filenames wrap properly: https://github.com/ccd0/4chan-x/issues/1082 */ +:root.sw-yotsuba .post > .file { + /* 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 */ + word-break: break-word; +} +:root.sw-yotsuba:not(.ua-webkit):not(.ua-blink) .fileText { + word-wrap: break-word; + max-width: calc(100vw - 90px); +} +:root.sw-yotsuba > body.is_catalog .thread > a > img { + display: inline-block; +} +/* Links to NSFW boards */ +:root.sw-yotsuba .nwsb { + display: inline; +} +:root.sw-yotsuba .fileText { + max-width: auto; + white-space: normal; +} + +/* Ads */ +:root.sw-yotsuba .ad-cnt > *, :root.sw-yotsuba .adg-rects > *, :root.sw-yotsuba .bsa-cnt { + height: auto !important; +} +:root.sw-yotsuba:not(.ads-loaded) hr.abovePostForm, +:root.sw-yotsuba:not(.ads-loaded) .adg-rects > hr, +:root.sw-yotsuba #adg-ol + hr, +:root.sw-yotsuba .danbo-slot:empty { + display: none; +} +:root.sw-yotsuba .adg-rects { + margin: 0; + font-size: 0; +} +:root.sw-yotsuba div.center[style] { + display: none !important; +} + +/* Tinyboard / vichan conflicts */ +#menu > .hide-thread-link { + width: auto; + height: auto; + overflow: visible; + background-image: none; +} +#menu label.entry { + display: block; +} +#fourchanx-settings label { + display: inline; +} +.intro a[href="javascript:;"], +#menu a { + margin: 0; +} +.gal-buttons.gal-buttons a { + font-size: inherit; +} +:root.sw-tinyboard.fixed.top-header:not(.autohide) .boardlist, +:root.sw-tinyboard.fixed.top-header:not(.autohide) .bar.top { + position: static; +} +:root.sw-tinyboard.fixed.top-header:not(.autohide) div.pages.top { + top: auto; + bottom: 0; +} +:root.sw-tinyboard.fixed.top-header.autohide .boardlist, +:root.sw-tinyboard.fixed.top-header.autohide .bar.top { + z-index: 3; +} + +/* Tinyboard site style conflicts */ +:root[data-host="fufufu.moe"].fixed.top-header:not(.autohide) div.pages.top { + top: 26px; + bottom: auto; +} +:root[data-host="merorin.com"].fixed.top-header:not(.autohide) span.settings { + top: 26px; +} +:root[data-host="fufufu.moe"]:not(.fixed) #header-bar { + margin-top: 38px; +} +:root[data-host="lainchan.org"]:not(.fixed) #header-bar { + margin-top: 17px; +} +:root[data-host="smuglo.li"]:not(.fixed) #header-bar { + margin-top: 8px; +} + +/* Anti-autoplay */ +audio.controls-added { + display: block; + margin: auto; + white-space: normal; +} +:root.anti-autoplay div.embed { + position: static; + width: auto; + height: auto; + text-align: center; +} +:root.anti-autoplay .autoplay-removed { + visibility: visible !important; + min-width: 640px; + min-height: 360px; +} + +/* fixed, z-index */ +#overlay, +#qp, #ihover, +#navlinks, .fixed #header-bar, +:root.float #updater, +:root.float #thread-stats, +#qr { + position: fixed; +} +#overlay { + z-index: 999; +} +#qp, #ihover { + z-index: 60; +} +#menu, .gal-buttons { + z-index: 50; +} +#updater, #thread-stats { + z-index: 40; +} +:root.fixed #header-bar, #notifications { + z-index: 35; +} +#a-gallery { + z-index: 30; +} +#navlinks { + z-index: 25; +} +#qr { + z-index: 20; +} +#embedding { + z-index: 11; +} +:root.fixed-watcher #thread-watcher { + z-index: 10; +} +:root.fixed:not(.gallery-open) #header-bar:not(:hover) { + z-index: 8; +} +#thread-watcher { + z-index: 5; +} + +/* Header */ +.fixed.top-header body { + padding-top: 2em; +} +.fixed.bottom-header body { + padding-bottom: 2em; +} +.fixed #header-bar { + right: 0; + left: 0; + padding: 3px 4px 4px; + font-size: 12px; +} +.fixed.top-header #header-bar { + top: 0; +} +.fixed.bottom-header #header-bar { + bottom: 0; +} +#header-bar { + border-width: 0; + transition: all .1s .05s ease-in-out; +} +:root.fixed #header-bar { + box-shadow: -5px 1px 10px rgba(0, 0, 0, 0.20); +} +:root.centered-links #shortcuts { + width: 300px; + text-align: right; +} +:root.centered-links #header-bar { + text-align: center; +} +#custom-board-list { + font-size: 13px; + vertical-align: middle; +} +#full-board-list { + vertical-align: middle; +} +:root.centered-links #custom-board-list { + position: relative; + left: 150px; +} +.fixed.top-header #header-bar { + border-bottom-width: 1px; +} +.fixed.bottom-header #header-bar { + box-shadow: 0 -1px 2px rgba(0, 0, 0, .15); + border-top-width: 1px; +} +.fixed.bottom-header #header-bar .menu-button i { + border-top: none; + border-bottom: 6px solid; +} +.fixed #header-bar.autohide:not(:hover) { + box-shadow: none; + transition: all .8s .6s cubic-bezier(.55, .055, .675, .19); +} +.fixed.top-header #header-bar.autohide:not(:hover) { + margin-bottom: -1em; + -webkit-transform: translateY(-100%); + transform: translateY(-100%); +} +.fixed.bottom-header #header-bar.autohide:not(:hover) { + -webkit-transform: translateY(100%); + transform: translateY(100%); +} +#scroll-marker { + left: 0; + right: 0; + height: 10px; + position: absolute; +} +#header-bar:not(.autohide) #scroll-marker { + pointer-events: none; +} +#header-bar #scroll-marker { + display: none; +} +.fixed #header-bar #scroll-marker { + display: block; +} +.fixed.top-header #header-bar #scroll-marker { + top: 100%; +} +.fixed.bottom-header #header-bar #scroll-marker { + bottom: 100%; +} +#board-list a, #shortcuts a:not(.entry) { + text-decoration: none; + padding: 1px; +} +#shortcuts:empty { + display: none; +} +.brackets-wrap::before { + content: "\\00a0["; +} +.brackets-wrap::after { + content: "]\\00a0"; +} +.dead-thread, +.disabled:not(.replies-quoting-you) { + opacity: .45; +} +#shortcuts { + float: right; +} +:root.autohiding-scrollbar #shortcuts { + margin-right: 12px; +} +.shortcut { + margin-left: 3px; + vertical-align: middle; +} +:root.shortcut-icons .native-settings { + font-size: 0; + color: transparent; + display: inline-block; + vertical-align: top; + height: 12px; + width: 14px; + background: url('//s.4cdn.org/image/favicon.ico') 0px -1px no-repeat; +} +#navbotright, +#navtopright { + display: none; +} +#toggleMsgBtn { + display: none !important; +} +.current, +:root.sw-yotsuba div#boardNavDesktopFoot a.current { + font-weight: bold; +} +@media (min-width: 1300px) { + :root.sw-yotsuba.fixed:not(.centered-links) #header-bar { + white-space: nowrap; + display: -webkit-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + } + :root.sw-yotsuba.fixed:not(.centered-links) #board-list { + -webkit-flex: auto; + flex: auto; + } + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list { + display: -webkit-flex; + display: flex; + } + :root.sw-yotsuba.fixed:not(.centered-links) .hide-board-list-container { + -webkit-flex: none; + flex: none; + margin-right: 5px; + } + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList { + -webkit-flex: auto; + flex: auto; + display: -webkit-flex; + display: flex; + width: 0px; /* XXX Fixes Edge not shrinking the board list below default size when needed */ + } + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > a, + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > span:not(.space):not(.spacer) { + -webkit-flex: none; + flex: none; + padding: .17em; + margin: -.17em -.32em; + } + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > span { + pointer-events: none; + } + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > span.space { + -webkit-flex: 0 .63 .63em; + flex: 0 .63 .63em; + } + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > span.spacer { + -webkit-flex: 0 .38 .38em; + flex: 0 .38 .38em; + } + :root.sw-yotsuba.fixed:not(.centered-links) #shortcuts { + float: initial; + -webkit-flex: none; + flex: none; + display: -webkit-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + } +} +/* 4chan X link brackets */ +.brackets-wrap::before { + content: "["; +} +.brackets-wrap::after { + content: "]"; +} +/* Notifications */ +#notifications { + position: fixed; + top: 0; + height: 0; + text-align: center; + right: 0; + left: 0; + visibility: visible; +} +#notifications:empty { + display: none; +} +:root.fixed.top-header:not(.gallery-open) #header-bar #notifications, +:root.fixed.top-header #header-bar.autohide #notifications { + position: absolute; + top: 100%; +} +.notification { + color: #FFF; + font-weight: 700; + text-shadow: 0 1px 2px rgba(0, 0, 0, .5); + box-shadow: 0 1px 2px rgba(0, 0, 0, .15); + border-radius: 2px; + margin: 1px auto; + width: 550px; + max-width: 100%; + position: relative; + transition: all .25s ease-in-out; +} +.notification.error { + background-color: hsla(0, 100%, 38%, .9); +} +.notification.warning { + background-color: hsla(36, 100%, 38%, .9); +} +.notification.info { + background-color: hsla(200, 100%, 38%, .9); +} +.notification.success { + background-color: hsla(104, 100%, 38%, .9); +} +.notification a { + color: white; +} +.notification > .close { + padding: 7px; + top: 0px; + right: 5px; + position: absolute; +} +.notification > .fa-times::before { + font-size: 11px !important; +} +.message { + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 6px 20px; + max-height: 200px; + width: 100%; + overflow: auto; + white-space: pre-line; +} +.message a { + text-decoration: underline; +} +:root.tainted .report-error { + display: none; +} + +/* Settings */ +:root.fourchan-x body { + -moz-box-sizing: border-box; + box-sizing: border-box; +} +#overlay { + background-color: rgba(0, 0, 0, .5); + display: -webkit-flex; + display: flex; + top: 0; + left: 0; + height: 100%; + width: 100%; +} +#fourchanx-settings { + -moz-box-sizing: border-box; + box-sizing: border-box; + box-shadow: 0 0 15px rgba(0, 0, 0, .15); + height: 600px; + max-height: 100%; + width: 900px; + max-width: 100%; + margin: auto; + padding: 5px; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: column; + flex-direction: column; +} +#fourchanx-settings > nav { + padding: 2px 2px 8px; + display: -webkit-flex; + display: flex; +} +#fourchanx-settings > nav a { + text-decoration: underline; +} +#fourchanx-settings > nav a.close { + text-decoration: none; + padding: 0 2px; + margin: 0; +} +.section-container { + -webkit-flex: 1; + flex: 1; + position: relative; + overflow: auto; + padding-right: 5px; + overscroll-behavior: contain; +} +.sections-list { + -webkit-flex: 1; + flex: 1; +} +.export, .import, .reset { + cursor: pointer; + text-decoration: none !important; +} +.tab-selected { + font-weight: 700; +} +.section-sauce ul, +.section-advanced ul { + list-style: none; + margin: 0; +} +.section-sauce ul { + padding: 8px; +} +.section-advanced ul { + padding: 0px; +} +.section-sauce li, +.section-advanced li { + padding-left: 4px; +} +.section-main ul { + margin: 0; + padding: 0 0 0 16px; +} +.section-main li { + white-space: pre-line; + list-style: disc; +} +.section-main li:not(:first-of-type) { + margin-top: 4px; +} +.section-main label { + text-decoration: underline; +} +div[data-checked="false"] > .suboption-list { + display: none; +} +.suboption-list { + position: relative; +} +.suboption-list::before { + content: ""; + display: inline-block; + position: absolute; + left: .7em; + width: 0; + height: 100%; + border-left: 1px solid; +} +.suboption-list > div { + position: relative; + padding-left: 1.4em; +} +.suboption-list > div::before { + content: ""; + display: inline-block; + position: absolute; + left: .7em; + width: .7em; + height: .6em; + border-left: 1px solid; + border-bottom: 1px solid; +} +#fourchanx-settings .section-main p { + margin: .5em 0 0; +} +.section-filter ul { + padding: 0; +} +.section-filter li { + margin: 10px 40px; + list-style: disc; +} +.section-filter textarea { + height: 500px; +} +.section-main a, .section-filter a, .section-advanced a { + text-decoration: underline; +} +#sauce-doc-expand:not(:checked) ~ #sauce-doc { + max-height: 130px; + overflow: auto; +} +#sauce-doc > label { + float: right; + margin: 0 5px; +} +/* XXX for OneeChan */ +#sauce-doc-expand + .riceCheck { + display: none; +} +.section-sauce textarea { + height: 430px; +} +.section-advanced .field[name="boardnav"] { + width: 100%; +} +.section-advanced textarea { + height: 150px; +} +.section-advanced textarea[name="archiveLists"], +.section-advanced textarea[name="externalCatalogURLs"], +.section-advanced textarea[name="knownBanners"] { + height: 75px; +} +.section-advanced .archive-cell { + min-width: 160px; + text-align: center; +} +.section-advanced #archive-board-select { + position: absolute; +} +.section-advanced .note { + font-size: 0.8em; + font-style: italic; + margin-left: 10px; +} +.section-advanced .note code { + font-style: normal; + font-size: 11px; +} +.favicon-preview > img { + vertical-align: middle; +} +.favicon-preview > img:nth-of-type(3n+1) { + margin-left: 4px; +} +.section-keybinds .field { + font-family: monospace; +} +#fourchanx-settings fieldset { + border: 1px solid; + border-radius: 3px; + padding: 0.35em 0.625em 0.75em; + margin: 0px 2px; +} +#fourchanx-settings legend { + font-weight: 700; + color: inherit; +} +#fourchanx-settings textarea { + font-family: monospace; + width: 100%; + resize: vertical; +} +#fourchanx-settings code { + color: #000; + background-color: #FFF; + padding: 0 2px; +} +#fourchanx-settings th { + text-align: center; + font-weight: bold; +} +#fourchanx-settings p { + margin: 1em 0px; +} +#fourchanx-settings table { + margin: auto; +} + +/* Index */ +:root.index-loading .navLinks:not(.json-index), +:root.index-loading .board:not(.json-index), +:root.index-loading .pagelist:not(.json-index), +:root.infinite-mode .pagelist, +:root.all-pages-mode .pagelist, +:root.catalog-mode .pagelist, +:root:not(.catalog-mode) .indexlink, +:root.catalog-mode .cataloglink, +:root:not(.catalog-mode) #hidden-label, +:root:not(.catalog-mode) #index-size { + display: none; +} +#index-search { + padding-right: 1.5em; + width: 100px; + transition: color .25s, border-color .25s, width .25s; +} +#index-search:focus, +#index-search[data-searching] { + width: 200px; +} +#index-search-clear { + color: gray; + display: inline-block; + position: relative; + left: -1em; + width: 0; +} +/* \`\`::-webkit-*'' selectors break selector lists on Firefox. */ +#index-search::-webkit-search-cancel-button { + display: none; +} +#index-search:not([data-searching]) + #index-search-clear { + display: none; +} +#index-options { + float: right; +} +#lastlong-options { + display: inline-block; + vertical-align: middle; + height: 28px; + margin: -14px 0; +} +#lastlong-options > input { + padding: 0; + border: 0 !important; + text-align: center; + background: transparent; + display: block; + font-size: 12px; + height: 12px; + width: 30px; + margin: 1px 0; +} +.summary { + text-decoration: none; +} + +/* Catalog */ +:root.catalog-mode .board { + text-align: center; +} +.catalog-thread { + display: inline-block; + -moz-box-sizing: border-box; + box-sizing: border-box; + border: 1px solid transparent; + word-wrap: break-word; + vertical-align: top; + position: relative; +} +/* overrides 4chan CSS on div.thread */ +.catalog-thread.catalog-thread { + margin: 2px; +} +.catalog-small > .catalog-thread { + width: 165px; + height: 320px; +} +.catalog-large > .catalog-thread { + width: 270px; + height: 410px; +} +:root.catalog-hover-expand .catalog-thread:hover { + z-index: 1; +} +.catalog-container { + position: absolute; + top: -4px; + left: 0; + right: 0; + bottom: 0; +} +.catalog-container:not(:hover), +:root:not(.catalog-hover-expand) .catalog-container { + overflow: hidden; +} +.catalog-post { + position: absolute; + top: 4px; + left: 0; + right: 0; + border: 1px solid transparent; + padding-top: 20px; +} +/* overrides inline CSS from Index.cb.hoverAdjust */ +:root:not(.catalog-hover-expand) .catalog-post { + left: 0 !important; + right: 0 !important; +} +/* overrides 4chan CSS on div.post */ +.catalog-post.catalog-post { + margin: -21px -1px -1px; + overflow: visible; +} +.catalog-thread.noFile > * > .catalog-post { + margin-top: -7px; + padding-top: 6px; +} +:root.catalog-hover-expand .catalog-container:hover > .catalog-post { + margin-left: -61px; + margin-right: -61px; +} +:root.catalog-hover-expand .catalog-container:hover > * > :not(.catalog-replies) { + padding-left: 2px; + padding-right: 2px; +} +.catalog-link { + display: block; + position: relative; +} +.catalog-thumb { + border-radius: 2px; + box-shadow: 0 0 5px rgba(0, 0, 0, .25); + vertical-align: top; +} +.catalog-thumb.spoiler-file { + width: 100px; + height: 100px; +} +.catalog-thumb.deleted-file { + width: 127px; + height: 13px; + padding: 20px 11px; +} +.catalog-thumb.no-file { + width: 77px; + height: 13px; + padding: 20px 36px; +} +.catalog-icons > img, +.catalog-stats > .menu-button { + width: 1em; + height: 1em; + margin: 0; + vertical-align: text-top; + padding-left: 2px; +} +.catalog-stats > .menu-button { + font-weight: normal; +} +.catalog-stats > .menu-button > i::before { + line-height: 11px; +} +.catalog-stats { + font-size: 10px; + font-weight: 700; + padding-top: 2px; +} +.catalog-stats > [title] { + cursor: help; +} +.catalog-post > .postMessage { + margin: 0; + padding-bottom: .3em; +} +.catalog-container:not(:hover) > * > .file, +.catalog-container:not(:hover) > * > .postInfo > :not(.subject), +.catalog-container:not(:hover) > * > .catalog-replies, +.catalog-container:not(:hover) .extra-linebreak, +.catalog-container:not(:hover) .abbr, +:root:not(.catalog-hover-expand) .catalog-container > * > .file, +:root:not(.catalog-hover-expand) .catalog-container > * > .postInfo > :not(.subject), +:root:not(.catalog-hover-expand) .catalog-container > * > .catalog-replies, +:root:not(.catalog-hover-expand) .catalog-container .extra-linebreak, +:root:not(.catalog-hover-expand) .catalog-container .abbr, +.catalog-thread > .catalog-container > :not(.catalog-post), +.catalog-post > .file > :not(.fileText), +.catalog-post > * > .fileText > :not(:first-child), +.catalog-post > .postInfo > :not(.subject):not(.nameBlock):not(.dateTime), +.catalog-post > .postInfo > .nameBlock > .contact-links, +.catalog-post > * > * > .posteruid, +.catalog-post > * > * > .postJumper, +:root.bottom-backlinks .catalog-post > .container, +.post:not(.catalog-post) > .catalog-link, +.post:not(.catalog-post) > .catalog-stats, +.post:not(.catalog-post) > .catalog-replies { + display: none; +} +.catalog-post > .file { + position: absolute; + left: 0; + right: 0; + top: 0; + min-height: 20px; + background-color: inherit; +} +.catalog-post > * > .fileText { + position: relative; + padding: 2px; + background-color: inherit; +} +.catalog-small .catalog-post > * .fileText { + font-size: 10px; +} +.catalog-post > * > .fileText:not(:hover) { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.catalog-post > * > .fileText:hover { + z-index: 1; +} +/* overrides 4chan CSS on div.post div.postInfo */ +.catalog-post > .postInfo.postInfo { + width: auto; +} +.catalog-post > * > .subject { + display: block; +} +.catalog-post > * > .dateTime { + display: inline-block; + font-style: italic; +} +:root.catalog-hover-expand .catalog-container:hover > * > * > .nameBlock, +:root.catalog-hover-expand .catalog-container:hover > * > * > .dateTime, +:root.catalog-hover-expand .catalog-container:hover > * > .postMessage:not(:empty) { + padding-top: .3em; +} +.catalog-post .extra-linebreak { + content: ''; /* makes this work in Blink/WebKit */ + display: block; + margin-top: .3em; +} +.catalog-reply { + text-align: left; + white-space: nowrap; + border-top: 1px solid transparent; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: row; + flex-direction: row; + -webkit-align-items: stretch; + align-items: stretch; +} +.catalog-reply > * { + padding: 3px; + overflow: hidden; + -webkit-flex: none; + flex: none; +} +.catalog-reply > span { + font-style: italic; + font-weight: bold; +} +.catalog-reply-excerpt { + -webkit-flex: 1 1 auto; + flex: 1 1 auto; +} +.catalog-post .prettyprinted { + max-width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.catalog-post .MathJax_Display { + text-align: center !important; +} +.catalog-container:not(:hover) .exif, +:root:not(.catalog-hover-expand) .catalog-container .exif { + display: none !important; +} +.catalog-post > * > .exif { + border-collapse: collapse; +} +:root.catalog-hover-expand .catalog-container:hover .exif[style*="display: block;"] { + display: inline-block !important; +} +.catalog-post > * > .exif, +.catalog-post > * > .exif > tbody { + background-color: inherit; +} +.catalog-post > * > .exif, +.catalog-post > * > .exif td { + min-width: 0; +} +.catalog-post > * > .exif td { + padding-top: 1px; +} +:root.hats-enabled .catalog-thread::after { + content: ''; + pointer-events: none; + position: absolute; + background-size: contain; +} +:root.hats-enabled .catalog-small > .catalog-thread::after { + left: -8px; + top: -59px; + width: 96px; + height: 96px; +} +:root.hats-enabled:not(.werkTyme) .catalog-small > .catalog-thread:not(.noFile)::after { + left: calc(67px - .3px * var(--tn-w)); +} +:root.hats-enabled .catalog-large > .catalog-thread::after { + left: -15px; + top: -98px; + width: 160px; + height: 160px; +} +:root.hats-enabled:not(.werkTyme) .catalog-large > .catalog-thread:not(.noFile)::after { + left: calc(110px - .5px * var(--tn-w)); +} + +/* Copy Text Link's textarea element */ +textarea.copy-text-element { + height: 0; + width: 0; + position: absolute; + top: -10000px; +} + +/* Announcement Hiding */ +:root.hide-announcement $site$psa { + display: none; +} +.hide-announcement-button { + opacity: 0.4; + float: left; +} + +/* Unread */ +.unread-line { + margin: 0; + border-color: rgb(255,0,0); +} +.unread-line + br { + display: none; +} +.unread-mark-read { + float: right; + clear: both; + width: 100%; + text-align: right; +} +:not(.unread-thread) > .unread-mark-read { + display: none; +} + +/* Thread Updater */ +#updater { + background: none; + border: none; + box-shadow: none; +} +#updater > .move { + position: absolute; + top: -5px; + bottom: -5px; + left: -5px; + right: -5px; + z-index: -1; +} +#updater > div:last-child { + text-align: center; +} +#updater input[type="number"] { + width: 4em; +} +:root.float #updater { + padding: 0px 3px; +} +:root:not(.float).shortcut-icons #updater { + display: inline-block; + min-width: 12pt; + text-align: right; +} +.new { + color: limegreen; +} +#update-status:not(.empty) + #update-timer:not(.empty):not(.loading) { + margin-left: 5px; +} +#update-timer { + cursor: pointer; +} + +/* Thread Watcher */ +#thread-watcher { + position: absolute; +} +#thread-watcher { + padding-bottom: 3px; + padding-left: 3px; + white-space: nowrap; + min-width: 146px; +} +#watched-threads { + overflow-x: hidden; + overflow-y: auto; +} +#thread-watcher .refresh { + padding: 0px 3px; +} +:root.fixed-watcher #thread-watcher { + position: fixed; +} +:root.fixed-watcher #watched-threads { + /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */ + max-height: 85vh; + max-height: calc(100vh - 75px); +} +:root:not(.fixed-watcher) #watched-threads:not(:hover) { + max-height: 210px; + overflow-y: hidden; +} +#thread-watcher > .move { + padding-top: 3px; +} +#watched-threads > div { + padding-left: 3px; + padding-right: 3px; +} +#watched-threads .watcher-link { + max-width: 250px; + display: -webkit-inline-flex; + display: inline-flex; + -webkit-flex-direction: row; + flex-direction: row; +} +#watched-threads .watcher-page, +#watched-threads .watcher-unread { + -webkit-flex: 0 0 auto; + flex: 0 0 auto; + margin-right: 2px; +} +#watched-threads .watcher-title { + overflow: hidden; + text-overflow: ellipsis; + -webkit-flex: 0 1 auto; + flex: 0 1 auto; +} +#watched-threads .watcher-title:not(:first-child) { + margin-left: 2px; +} +.replies-quoting-you > a, #watcher-link.replies-quoting-you, .last-page > a > .watcher-page { + color: #F00; +} +#thread-watcher a { + text-decoration: none; +} +#thread-watcher .move > .close { + position: absolute; + right: 0px; + top: 0px; + padding: 0px 4px; +} +.watch-thread-link { + padding-top: 18px; + width: 18px; + height: 0px; + display: inline-block; + background-repeat: no-repeat; + opacity: 0.2; + position: relative; + top: 1px; + background-image: url("data:image/svg+xml,"); +} +.watch-thread-link.watched { + opacity: 1; +} + + +/* Thread Stats */ +#thread-stats { + background: none; + border: none; + box-shadow: none; +} +:root.float #thread-stats > .move > :not(#page-count) { + pointer-events: none; +} +:root.float #thread-stats { + padding: 0px 3px; +} +#page-count { + cursor: pointer; +} + +/* Quote */ +.hashlink::before { + content: ' '; + visibility: hidden; +} +.inline + .hashlink { + display: none !important; +} +:root.resurrect-quotes .deadlink { + text-decoration: none !important; +} +.catalog-post .qmark-ct { + display: none; +} +.backlink.deadlink:not(.forwardlink), +.quotelink.deadlink:not(.forwardlink) { + text-decoration: underline !important; +} +:root:not(.catalog-mode) .inlined { + opacity: .5; +} +#qp input, .forwarded { + display: none; +} +.quotelink.forwardlink, +.backlink.forwardlink { + text-decoration: none; + border-bottom: 1px dashed; +} +.filtered { + text-decoration: underline line-through; +} +:root.hide-backlinks .backlink.filtered, +:root.hide-backlinks .backlink.filtered + .hashlink.filtered { + display: none; +} +.postNum + .container::before { + content: " "; +} +:root.bottom-backlinks .container { + display: block; + clear: both; + margin: 0 4px; +} +:root.bottom-backlinks .backlink { + font-size: 90%; +} +.inline { + border: 1px solid; + display: table; + margin: 2px 0; +} +.container ~ .inline { + margin-left: 20px; +} +:root.catalog-mode .inline { + display: none; +} +.inline .post { + border: 0 !important; + background-color: transparent !important; + display: table !important; + margin: 0 !important; + padding: 1px 2px !important; +} +#qp > .opContainer::after { + content: ''; + clear: both; + display: table; +} +#qp .post { + border: none; + margin: 0; + padding: 2px 2px 5px; +} +#qp img { + max-height: 80vh; + max-width: 50vw; +} + +/* Quote Threading */ +.threadContainer { + margin-left: 20px; + border-left: 1px solid rgba(128,128,128,.3); +} +.threadOP { + clear: both; +} + +/* File */ +.fileText-original, +.fnswitch:hover > .fntrunc, +.fnswitch:not(:hover) > .fnfull, +.expanded-image > .post > .file > .fileThumb > video[data-md5], +.expanded-image > .post > .file > .fileThumb > img[data-md5] { + display: none; +} +.full-image[data-file-i-d] { + display: none; + cursor: pointer; +} +.expanded-image > .post > .file > .fileThumb > .full-image { + display: inline; +} +.expanded-image { + clear: left; +} +.expanding { + opacity: .5; +} +:root.fit-height .full-image { + max-height: 100vh; +} +:root.fit-height.fixed .full-image { + /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */ + max-height: 93vh; + max-height: calc(100vh - 35px); +} +:root.fit-width .full-image { + max-width: 100%; +} +:root.ua-gecko.fit-width .full-image { + width: 100%; +} +.fileThumb > .warning { + clear: both; +} +#ihover { + pointer-events: none; + /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */ + max-height: 95vh; + max-height: calc(100vh - 25px); + max-width: 100vw; +} +/* WEBM Metadata */ +.webm-title > a::before { + content: "title"; + text-decoration: underline; +} +.webm-title.loading > a::after { + content: "..."; +} +.webm-title.error > a:hover::before, +.webm-title.error > a:focus::before { + content: "error"; + text-decoration: none; +} +.webm-title > span { + cursor: text; +} +.webm-title.not-found > span::before { + content: "not found"; +} +.webm-title:not(:hover):not(:focus) > span, +.webm-title:hover > span + a, +.webm-title:focus > span + a { + display: none; +} +/* Volume control */ +input[name="Default Volume"] { + width: 4em; + height: 1ex; + vertical-align: middle; + margin: 0px; +} +/* Fappe and Werk Tyme */ +:root.fappeTyme $site$replyOriginal.noFile, +:root.fappeTyme $site$replyOriginal.noFile + br { + display: none; +} +:root.werkTyme $site$thumbLink, +:root.werkTyme $site$file$thumb, +:root.werkTyme .catalog-thumb:not(.deleted-file):not(.no-file), +:root:not(.werkTyme) .werkTyme-filename { + display: none; +} +.werkTyme-filename { + font-weight: bold; + font-size: 110%; +} +:root.werkTyme .catalog-link { + box-shadow: 0 0 5px rgba(0, 0, 0, .25); + padding: 8px; + text-align: center; +} +:root.werkTyme .catalog-thumb { + box-shadow: none; + padding: 0; + vertical-align: middle; +} +.indicator { + background: rgba(255,0,0,0.8); + font-weight: bold; + display: inline-block; + min-width: 9px; + padding: 0px 2px; + margin: 0 1px; + text-align: center; + color: white; + border-radius: 2px; + cursor: pointer; +} +:root:not(.fappeTyme) #shortcut-fappe, +:root:not(.werkTyme) #shortcut-werk { + display: none; +} + +/* Index/Reply Navigation */ +#navlinks { + font-size: 16px; + top: 25px; + right: 10px; +} +:root.catalog-mode #navlinks { + display: none; +} + +/* Highlighting */ +.qphl { + outline: 2px solid rgba(216, 94, 49, .8); +} +:root.highlight-you .quotesYou$site$highlightable$op, +:root.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(221, 0, 0, .8); +} +:root.highlight-own .yourPost$site$highlightable$op, +:root.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(221, 0, 0, .8); +} +.filter-highlight$site$highlightable$op, +.filter-highlight$site$highlightable$reply { + box-shadow: inset 5px 0 rgba(221, 0, 0, .5); +} +:root.highlight-own .yourPost > $site$sideArrows, +:root.highlight-you .quotesYou > $site$sideArrows, +.filter-highlight > $site$sideArrows { + color: rgba(221, 0, 0, .8); +} +:root.highlight-own .yourPost$site$highlightable$op::after, +:root.highlight-you .quotesYou$site$highlightable$op::after, +.filter-highlight$site$highlightable$op::after { + content: ""; + display: block; + clear: both; +} +:root:not(.werkTyme) .catalog-thread.filter-highlight .catalog-thumb, +:root.werkTyme .catalog-thread.filter-highlight:not(:hover), +:root.werkTyme:not(.catalog-hover-expand) .catalog-thread.filter-highlight, +:root.werkTyme.catalog-hover-expand .catalog-thread.filter-highlight > .catalog-container:hover > .catalog-post, +:root.catalog $site$catalog$thread.filter-highlight$site$highlightable$catalog { + box-shadow: 0 0 3px 3px rgba(255, 0, 0, .5); +} +:root:not(.werkTyme) .catalog-thread.watched .catalog-thumb, +:root:root.werkTyme .catalog-thread.watched:not(:hover), +:root:root.werkTyme:not(.catalog-hover-expand) .catalog-thread.watched, +:root.werkTyme.catalog-hover-expand .catalog-thread.watched > .catalog-container:hover > .catalog-post { + border: 2px solid rgba(255, 0, 0, .75); +} + +/* Spoiler text */ +:root.reveal-spoilers $site$spoiler, +:root.reveal-spoilers $site$spoiler > a { + color: white !important; +} +:root.reveal-spoilers .removed-spoiler::before { + content: "[spoiler]"; +} +:root.reveal-spoilers .removed-spoiler::after { + content: "[/spoiler]"; +} + +/* Thread & Reply Hiding */ +.hide-thread-button, +.hide-reply-button { + float: left; + margin-right: 4px; + padding: 2px; +} +$site$infoRoot a.hide-reply-button { + margin-right: 6px; + padding: 0; +} +.replacedSideArrows { + float: left; +} +.hide-thread-button:not(:hover), +.hide-reply-button:not(:hover) { + opacity: 0.4; +} +.threadContainer .hide-reply-button { + margin-left: 2px !important; + position: relative; + left: 1px; +} +.hide-thread-button { + margin-top: -1px; + width: 11px; +} +.stub ~ :not(.threadDivider) { + display: none !important; +} +.stub input { + display: inline-block; +} +$site$thread[hidden] + hr { + display: none; +} +:root.reply-hide $site$sideArrows { + display: none; +} +:root.sw-yotsuba.thread-hide .party-hat { + left: 19px; +} + +/* Anonymize */ +:root.anonymize $site$info$name, +:root.sw-yotsuba.anonymize .post-author:not([class*=capcode]) { + font-size: 0; +} +:root.anonymize $site$info$tripcode, +:root.sw-yotsuba.anonymize .n-pu { + display: none; +} +:root.anonymize $site$info$name::before, +:root.sw-yotsuba.anonymize .post-author:not([class*=capcode])::before { + content: "Anonymous"; + font-size: 10pt; +} +:root.sw-yotsuba.anonymize .flashListing .name::before, +:root.sw-yotsuba.anonymize .post-last > .post-author:not([class*=capcode])::before { + font-size: 9pt; +} + +/* QR */ +:root.hide-original-post-form #togglePostFormLink, +#qr.autohide:not(.focus):not(:hover):not(:active) > form, +:root.thread-view #qr:not(.show-new-thread-option) select[data-name="thread"], +#file-n-submit:not(.has-file) #qr-filerm { + display: none; +} +:root.hide-original-post-form #postForm { + display: none !important; +} +#qr select, +#qr-filename-container > a, +.remove, +.captcha-img { + cursor: pointer; +} +#qr { + position: fixed; + padding: 1px; + border: 1px solid transparent; + min-width: 300px; + border-radius: 3px 3px 0 0; +} +#qr > form { + /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */ + max-height: 85vh; + max-height: calc(100vh - 75px); + overflow-y: auto; + overflow-x: hidden; +} +#qrtab { + border-radius: 3px 3px 0 0; +} +#qrtab { + margin-bottom: 1px; +} +#qr .close { + float: right; + padding: 0 3px; +} +.qr-link-container { + text-align: center; + margin: 16px 0; +} +.qr-link-container-bottom { + width: 200px; + position: absolute; + left: -100px; + margin-left: 50%; + text-align: center; +} +.qr-link { + border-radius: 3px; + padding: 6px 10px 5px; + font-weight: bold; + vertical-align: middle; + border-style: solid; + border-width: 1px; + font-size: 10pt; +} +.qr-link-container + #togglePostFormLink { + font-size: 10pt; + font-weight: normal; + margin: -8px 0 3.5px; +} +.persona { + width: 100%; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: row; + flex-direction: row; +} +.persona .field { + -webkit-flex: 1; + flex: 1; + width: 0; +} +#qr.forced-anon input[data-name="name"]:not(.force-show), +#qr.forced-anon input[data-name="sub"]:not(.force-show), +#qr.reply-to-thread input[data-name="sub"]:not(.force-show), +body:not(.board_f) #qr select[name="filetag"], +#qr.reply-to-thread select[name="filetag"], +#qr:not(.has-sjis) #sjis-toggle, +#qr:not(.has-math) #tex-preview-button, +#qr.tex-preview .textarea > :not(#tex-preview), +#qr:not(.tex-preview) #tex-preview { + display: none; +} +.persona button { + -webkit-flex: 0 0 23px; + flex: 0 0 23px; + -webkit-align-self: stretch; + align-self: stretch; + border: 1px solid #BBB; + padding: 0; + background: linear-gradient(to bottom, #F8F8F8, #DCDCDC) no-repeat; + color: #000; +} +#qr.sjis-preview #sjis-toggle, #qr.tex-preview #tex-preview-button { + background: #DCDCDC; +} +#sjis-toggle, #qr.sjis-preview textarea.field { + font-family: "IPAMonaPGothic","Mona","MS PGothic",monospace; + font-size: 16px; + line-height: 17px; +} +#tex-preview-button { + font-size: 10px; +} +#tex-preview { + white-space: pre-line; +} +#qr textarea.field { + height: 14.8em; + min-height: 9em; +} +#qr.has-captcha textarea.field { + height: 9em; +} +input.field.tripped:not(:hover):not(:focus) { + color: transparent !important; + text-shadow: none !important; +} +#qr textarea { + min-width: 300px; + resize: both; +} +.field { + -moz-box-sizing: border-box; + box-sizing: border-box; + margin: 0px; + padding: 2px 4px 3px; +} +#qr label input[type="checkbox"] { + position: relative; + top: 2px; +} + +/* Recaptcha v2 */ +#qr .captcha-root { + position: relative; +} +#qr .captcha-container > div { + margin: auto; + width: 304px; +} +/* XXX scrollable with scroll bar hidden; prevents scroll on space press */ +:root.ua-blink #qr .captcha-container > div, +:root.ua-edge #qr .captcha-container > div { + overflow: hidden; +} +:root.ua-blink #qr .captcha-container > div > div:first-of-type, +:root.ua-edge #qr .captcha-container > div > div:first-of-type { + overflow-y: scroll; + overflow-x: hidden; + padding-right: 30px; + height: 99%; + width: 100%; +} +#qr .captcha-counter { + display: block; + width: 100%; + text-align: center; + pointer-events: none; +} +#qr.captcha-open .captcha-counter { + position: absolute; + bottom: 3px; +} +#qr .captcha-counter > a { + pointer-events: auto; + display: inline-block; /* XXX https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8851747/ */ +} +#qr:not(.captcha-open) .captcha-counter > a { + display: block; + width: 100%; +} +#qr.captcha-v2 #qr-captcha-iframe { + width: 302px; + height: 423px; + border: 0; + display: block; + margin: auto; +} +.goog-bubble-content { + max-width: 100vw; + max-height: 100vh; + overflow: auto; +} +.goog-bubble-content iframe { + position: static !important; +} + +/* File Input, Submit Button, Oekaki */ +#file-n-submit, #qr .oekaki { + display: -webkit-flex; + display: flex; + -webkit-align-items: stretch; + align-items: stretch; + height: 25px; + margin-top: 1px; +} +#file-n-submit > input, #qr-draw-button { + background: linear-gradient(to bottom, #F8F8F8, #DCDCDC) no-repeat; + border: 1px solid #BBB; + border-radius: 2px; + height: 100%; +} +#qr-file-button, #qr-draw-button { + width: 15%; +} +#file-n-submit input[type="submit"] { + width: 25%; +} +#qr-filename-container { + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + width: 0; + display: -webkit-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + position: relative; + padding: 1px; +} +input#qr-filename { + border: none !important; + background: none !important; + outline: none; +} +#qr-filename, +.has-file #qr-no-file { + display: none; +} +#qr-no-file, +.has-file #qr-filename { + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + width: 0px; /* XXX Fixes filename not shrinking to allow space for buttons in Edge */ + display: inline-block; + padding: 0; + padding-left: 3px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +#qr-no-file { + color: #AAA; +} +#qr .oekaki.has-file { + display: none; +} +#qr .oekaki > label { + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + width: 0; + display: -webkit-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + height: 100%; +} +#qr .oekaki > label > span { + margin: 0 3px; +} +#qr .oekaki > label > input { + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + width: 0; + height: 100%; +} +#qr .oekaki-bg { + position: relative; + display: inline-block; + height: 100%; + width: 10%; + margin-left: 3px; +} +#qr .oekaki-bg > * { + position: absolute; + top: 0; + left: 0; + margin: 0; +} +#qr .oekaki-bg > :not([name="oekaki-bgcolor"]) { + z-index: 1; +} +#qr [name="oekaki-bgcolor"] { + height: 100%; + width: 100%; + border: none; + padding: 0; +} +#qr [name="oekaki-bg"]:not(:checked) ~ [name="oekaki-bgcolor"] { + visibility: hidden; +} +#qr input[type="file"] { + visibility: hidden; + position: absolute; +} + +/* Spoiler Checkbox, QR Icons */ +#qr-filename-container > label, #qr-filename-container > a { + -webkit-flex: none; + flex: none; + margin: 0; + margin-right: 3px; +} +#qr:not(.has-spoiler) #qr-spoiler-label, +#file-n-submit:not(.has-file) #qr-spoiler-label, +.has-file #paste-area, +.has-file #url-button, +#file-n-submit:not(.custom-cooldown) #custom-cooldown-button { + display: none; +} +#qr-filename-container > label { + position: relative; +} +#qr-filename-container input[type="checkbox"] { + margin: 0; +} +.checkbox-letter { + font-size: 13px; + font-weight: bold; +} +#qr-filename-container label:not(:hover) > input[type="checkbox"]:not(:focus):not(:checked), +#qr-filename-container label:not(:hover) > input[type="checkbox"]:not(:focus):not(:checked) ~ :not(.checkbox-letter), +#qr-filename-container label:hover > .checkbox-letter, +input[type="checkbox"]:focus ~ .checkbox-letter, +input[type="checkbox"]:checked ~ .checkbox-letter { + /* not displayed but still focusable */ + position: absolute; + opacity: 0; + pointer-events: none; +} +.checkbox-letter, #paste-area, #url-button, #custom-cooldown-button, #dump-button { + opacity: 0.6; +} +#paste-area { + font-size: 0; +} +#paste-area:focus { + opacity: 1; +} +#custom-cooldown-button.disabled { + opacity: 0.27; +} + +/* Thread and Flash Tag Select */ +#qr select { + background: white; + border: 1px solid #CCC; +} +#qr select[data-name="thread"] { + float: right; +} +#qr > form > select { + margin-top: 1px; +} + +/* Dumping UI */ +.dump #dump-list-container { + display: block; +} +#dump-list-container { + display: none; + position: relative; + overflow-y: hidden; + margin-top: 1px; +} +#dump-list { + overflow-x: auto; + overflow-y: auto; + white-space: nowrap; + width: 248px; + max-height: 248px; + min-height: 90px; + max-width: 100%; + min-width: 100%; + display: -webkit-flex; + display: flex; + -webkit-flex-wrap: wrap; + flex-wrap: wrap; +} +#dump-list:hover { + overflow-x: auto; +} +.qr-preview { + -moz-box-sizing: border-box; + box-sizing: border-box; + counter-increment: thumbnails; + cursor: move; + display: inline-block; + height: 90px; + width: 90px; + padding: 2px; + opacity: .5; + overflow: hidden; + position: relative; + text-shadow: 0 0 2px #000; + -webkit-transition: opacity .25s ease-in-out, -webkit-transform .25s ease-in-out; + transition: opacity .25s ease-in-out, transform .25s ease-in-out, -webkit-transform .25s ease-in-out; + vertical-align: top; + background-size: cover; + -webkit-flex: none; + flex: none; +} +.qr-preview:hover, +.qr-preview:focus { + opacity: .9; +} +.qr-preview::before { + content: counter(thumbnails); + color: #fff; + position: absolute; + top: 3px; + right: 3px; + text-shadow: 0 0 3px #000, 0 0 8px #000; +} +.qr-preview#selected { + opacity: 1; +} +.qr-preview.drag { + box-shadow: 0 0 10px rgba(0,0,0,.5); + -webkit-transform: scale(.8); + transform: scale(.8); +} +.qr-preview.over { + border-color: #fff; + -webkit-transform: scale(1.1); + transform: scale(1.1); + opacity: 0.9; + z-index: 10; +} +.qr-preview > span { + color: #fff; +} +.remove { + background: none; + color: #e00; + padding: 1px; +} +a:only-of-type > .remove { + display: none; +} +.remove:hover::after { + content: " Remove"; +} +.qr-preview:not(.has-file) label, +#qr:not(.has-spoiler) .qr-preview-spoiler { + display: none; +} +.qr-preview > label { + background: rgba(0,0,0,.5); + color: #fff; + right: 0; + bottom: 0; + left: 0; + position: absolute; + text-align: center; +} +.qr-preview > label > input { + margin: 0; +} +#add-post { + cursor: pointer; + font-size: 2em; + position: absolute; + bottom: 20px; + right: 10px; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); +} +.textarea { + position: relative; + display: -webkit-flex; + display: flex; +} +#char-count { + color: #000; + background: hsla(0, 0%, 100%, .5); + font-size: 8pt; + position: absolute; + bottom: 1px; + right: 1px; + pointer-events: none; +} +#char-count.warning { + color: red; +} + +/* Menu */ +.menu-button:not(.fa-bars) { + display: inline-block; + position: relative; + cursor: pointer; +} +#header-bar .menu-button i { + border-top: 6px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + display: inline-block; + margin: 2px; + vertical-align: middle; +} +.postInfo > .menu-button, +#thread-watcher .menu-button { + width: 18px; + height: 15px; + text-align: center; +} +#menu { + position: fixed; + outline: none; + font-weight: normal; +} +#menu, .submenu { + border-radius: 3px; + padding-top: 1px; + padding-bottom: 3px; +} +.entry { + cursor: pointer; + display: block; + outline: none; + padding: 2px 10px; + position: relative; + text-decoration: none; + white-space: nowrap; + min-width: 70px; + text-align: left; + text-shadow: none; + font-size: 10pt; +} +.left>.entry.has-submenu { + padding-right: 17px !important; +} +.entry input[type="checkbox"], +.entry input[type="radio"] { + margin: 0px; + position: relative; + top: 2px; +} +.entry input[type="number"] { + width: 4.5em; +} +.entry.has-shortcut-text { + display: flex; + justify-content: space-between; + align-items: center; +} +.entry .shortcut-text { + opacity: 0.5; + font-size: 70%; + margin-left: 5px; +} +.has-submenu::after { + content: ""; + border-left: .5em solid; + border-top: .3em solid transparent; + border-bottom: .3em solid transparent; + display: inline-block; + margin: .3em; + position: absolute; + right: 3px; +} +.left .has-submenu::after { + border-left: 0; + border-right: .5em solid; +} +.submenu { + display: none; + position: absolute; + left: 100%; + top: -1px; + margin-left: 0px; + margin-top: -2px; +} +.focused > .submenu { + display: block; +} +.imp-exp-result { + position: absolute; + text-align: center; + margin: auto; + right: 0px; + left: 0px; + width: 200px; +} + +/* Custom Board Titles */ +.boardTitle, .boardSubtitle { + white-space: pre-line; +} +.boardTitle[contenteditable="true"], +.boardSubtitle[contenteditable="true"] { + cursor: text !important; +} + +/* Embedding */ +.embedder:not(.embedded) > span { + display: none; +} +#embedding { + padding: 1px 4px 1px 4px; + position: fixed; +} +#embedding.empty { + display: none; +} +#embedding > div:first-child { + display: -webkit-flex; + display: flex; +} +#embedding .move { + -webkit-flex: 1; + flex: 1; +} +#embedding .jump { + margin: -1px 4px; + text-decoration: none; +} + +/* Gallery */ +#a-gallery { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: row; + flex-direction: row; + background: rgba(0,0,0,0.7); +} +.gal-viewport { + display: -webkit-flex; + display: flex; + -webkit-align-items: stretch; + align-items: stretch; + -webkit-flex-direction: row; + flex-direction: row; + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + overflow: hidden; +} +.gal-thumbnails { + -webkit-flex: 0 0 150px; + flex: 0 0 150px; + overflow-y: auto; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: column; + flex-direction: column; + -webkit-align-items: stretch; + align-items: stretch; + text-align: center; + background: rgba(0,0,0,.5); + border-left: 1px solid #222; +} +.gal-hide-thumbnails .gal-thumbnails { + display: none; +} +.gal-thumb img, +.gal-thumb video { + max-width: 125px; + max-height: 125px; + height: auto; + width: auto; +} +.gal-thumb { + -webkit-flex: 0 0 auto; + flex: 0 0 auto; + padding: 3px; + line-height: 0; + transition: background .2s linear; +} +.gal-highlight { + background: rgba(0, 190, 255,.8); +} +.gal-prev { + border-right: 1px solid #222; +} +.gal-next { + border-left: 1px solid #222; +} +.gal-prev, +.gal-next { + -webkit-flex: 0 0 20px; + flex: 0 0 20px; + position: relative; + cursor: pointer; + opacity: 0.7; + background-color: rgba(0, 0, 0, 0.3); +} +.gal-prev:hover, +.gal-next:hover { + opacity: 1; +} +.gal-prev::after, +.gal-next::after { + position: absolute; + top: 48.6%; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); + display: inline-block; + border-top: 11px solid transparent; + border-bottom: 11px solid transparent; + content: ""; +} +.gal-prev::after { + border-right: 12px solid #fff; + right: 5px; +} +.gal-next::after { + border-left: 12px solid #fff; + right: 3px; +} +.gal-image { + -webkit-flex: 1 0 auto; + flex: 1 0 auto; + display: -webkit-flex; + display: flex; + -webkit-align-items: flex-start; + align-items: flex-start; + -webkit-justify-content: space-around; + justify-content: space-around; + overflow: hidden; + /* Flex > Non-Flex child max-width and overflow fix (Firefox only?) */ + width: 1%; +} +:root:not(.gal-fit-height):not(.gal-pdf) .gal-image { + overflow-y: scroll !important; +} +:root:not(.gal-fit-width):not(.gal-pdf) .gal-image { + overflow-x: scroll !important; +} +.gal-image a { + display: -webkit-flex; + display: flex; + -webkit-align-items: flex-start; + align-items: flex-start; + margin: auto; + line-height: 0; + max-width: 100%; +} +:root.gal-pdf .gal-image a { + width: 100%; + height: 100%; +} +.gal-image img, +.gal-image video { + -webkit-flex: none; + flex: none; +} +.gal-fit-width .gal-image img, +.gal-fit-width .gal-image video { + max-width: 100%; +} +.gal-fit-height .gal-image img, +.gal-fit-height .gal-image video { + /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */ + max-height: 95vh; + max-height: calc(100vh - 25px); +} +.gal-image iframe { + width: 100%; + height: 100%; +} +.gal-buttons { + font-size: 2em; + margin-right: 3px; + padding-left: 7px; + padding-right: 7px; + top: 5px; +} +:root.gal-pdf .gal-buttons { + top: 40px; + background: rgba(0,0,0,0.6) !important; + border-radius: 3px; +} +.gal-buttons a { + color: #ffffff; + text-shadow: 0px 0px 1px #000000; +} +.gal-buttons i { + display: inline-block; + margin: 2px; + position: relative; +} +.gal-start i { + border-left: 10px solid; + border-top: 6px solid transparent; + border-bottom: 6px solid transparent; + bottom: 1px; +} +.gal-stop i { + border: 5px solid; + bottom: 2px; +} +.gal-buttons.gal-playing > .gal-start, +.gal-buttons:not(.gal-playing) > .gal-stop { + display: none; +} +.gal-buttons .menu-button i { + border-top: 10px solid; + border-right: 6px solid transparent; + border-left: 6px solid transparent; + bottom: 2px; + vertical-align: baseline; +} +.gal-labels { + position: fixed; + bottom: 6px; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: column; + flex-direction: column; + -webkit-align-items: flex-end; + align-items: flex-end; + +} +:root:not(.show-sauce) .gal-sauce { + display: none; +} +.gal-name, +.gal-count, +.gal-sauce { + background: rgba(0,0,0,0.6) !important; + border-radius: 3px; + padding: 1px 5px 2px 5px; + margin-top: 3px; + color: #ffffff !important; + text-decoration: none !important; +} +.gal-sauce a { + color: #ffffff !important; +} +.gal-name:hover, +.gal-buttons a:hover, +.gal-sauce a:hover { + color: rgb(95, 95, 101) !important; +} +:root.gal-pdf .gal-buttons a:hover { + color: rgb(204, 204, 204) !important; +} +.gal-buttons, +.gal-labels { + position: fixed; + right: 195px; +} +.gal-hide-thumbnails .gal-buttons, +.gal-hide-thumbnails .gal-labels { + right: 44px; +} +:root:not(.gal-fit-width):not(.gal-pdf) .gal-labels { + bottom: 23px !important; +} +:root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-buttons, +:root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-labels { + right: 178px !important; +} +:root.gal-hide-thumbnails.gal-fit-height:not(.gal-pdf) .gal-buttons, +:root.gal-hide-thumbnails.gal-fit-height:not(.gal-pdf) .gal-labels { + right: 28px !important; +} +:root.gallery-open.fixed #header-bar:not(.autohide), +:root.gallery-open.fixed #header-bar:not(.autohide) #shortcuts .fa::before { + visibility: hidden; +} + +/* Mod Contact Links */ +.contact-links { + margin-left: 2px; +} +.move-note > a { + text-decoration: underline; +} +.invisible { + font-size: 0; +} + +/* PostJumper */ +.postJumper > .prev, +.postJumper > .next { + font-size: 120%; +} + +/* PSA */ +.fcx-announcement { + text-align: center; +} +.fcx-announcement a { + text-decoration: underline; +} + +@keyframes spin { + 0% {transform:rotate(0deg);} + 100% {transform:rotate(359deg);} +} + +.spin { + animation:spin 2s infinite linear; +} +`; + + var supports = `/* XXX Moved to end of stylesheet to avoid breaking whole stylesheet in Maxthon. */ +@supports (text-decoration-style: dashed) or (-moz-text-decoration-style: dashed) { + .quotelink.forwardlink, + .backlink.forwardlink { + text-decoration: underline; + -moz-text-decoration-style: dashed; + text-decoration-style: dashed; + border-bottom: none; + } +} +`; + + var tomorrow = `/* General */ +:root.tomorrow .dialog { + background-color: #282A2E; + border-color: #111; +} + +/* 4chan style fixes */ +:root.tomorrow #arc-list span.quote { + color: #B5BD68; +} +:root.tomorrow.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(145, 182, 214, .8) !important; +} +:root.tomorrow.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(145, 182, 214, .8) !important; +} + +/* Header */ +:root.tomorrow #header-bar.dialog { + background-color: rgba(40,42,46,0.9); +} +:root.tomorrow:not(.fixed) #header-bar, :root.tomorrow #notifications { + font-size: 9pt; +} +:root.tomorrow #header-bar, :root.tomorrow #notifications { + color: #C5C8C6; +} +:root.tomorrow #header-bar a, :root.tomorrow #notifications a { + color: #81A2BE; +} +:root.tomorrow.shortcut-icons .native-settings { + background-image: url('//s.4cdn.org/image/favicon-ws.ico'); +} + +/* Settings */ +:root.tomorrow #fourchanx-settings fieldset, :root.tomorrow .section-main div::before { + border-color: #111; +} +:root.tomorrow .suboption-list > div:last-of-type { + background-color: #282A2E; +} + +/* Catalog */ +:root.tomorrow.catalog-hover-expand .catalog-container:hover > .post { + background-color: #282A2E; +} +:root.tomorrow.werkTyme .catalog-thread:not(:hover), +:root.tomorrow.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.tomorrow.catalog-hover-expand .catalog-container:hover > .post, +:root.tomorrow.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #111; +} + +/* Quote */ +:root.tomorrow .backlink.deadlink { + color: #81A2BE !important; +} +:root.tomorrow .inline { + border-color: #111; + background-color: rgba(0, 0, 0, .14); +} + +/* Fappe and Werk Tyme */ +:root.tomorrow .indicator { + color: #282A2E; +} + +/* Highlighting */ +:root.tomorrow .qphl { + outline: 2px solid rgba(145, 182, 214, .8); +} +:root.tomorrow.highlight-you .quotesYou$site$highlightable$op, +:root.tomorrow.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(145, 182, 214, .8); +} +:root.tomorrow.highlight-own .yourPost$site$highlightable$op, +:root.tomorrow.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(145, 182, 214, .8); +} +:root.tomorrow .filter-highlight$site$highlightable$op, +:root.tomorrow .filter-highlight$site$highlightable$reply { + box-shadow: inset 5px 0 rgba(145, 182, 214, .5); +} +:root.tomorrow.highlight-own .yourPost > $site$sideArrows, +:root.tomorrow.highlight-you .quotesYou > $site$sideArrows, +:root.tomorrow .filter-highlight > $site$sideArrows { + color: rgb(155, 185, 210); +} +:root.tomorrow .catalog-thread.filter-highlight .catalog-thumb, +:root.tomorrow.werkTyme .catalog-thread.filter-highlight:not(:hover), +:root.tomorrow.werkTyme:not(.catalog-hover-expand) .catalog-thread.filter-highlight, +:root.tomorrow.werkTyme.catalog-hover-expand .catalog-thread.filter-highlight > .catalog-container:hover > .catalog-post { + box-shadow: 0 0 3px 3px rgba(64, 192, 255, .7); +} +:root.tomorrow .catalog-thread.watched .catalog-thumb, +:root.tomorrow.werkTyme .catalog-thread.watched:not(:hover), +:root.tomorrow.werkTyme:not(.catalog-hover-expand) .catalog-thread.watched, +:root.tomorrow.werkTyme.catalog-hover-expand .catalog-thread.watched > .catalog-container:hover > .catalog-post { + border: 2px solid rgb(64, 192, 255); +} + + +/* QR */ +.tomorrow #dump-list::-webkit-scrollbar-thumb { + background-color: #282A2E; + border-color: #111; +} +:root.tomorrow .qr-preview { + background-color: rgba(255, 255, 255, .15); +} +:root.tomorrow #qr .field { + background-color: rgb(26, 27, 29); + color: rgb(197,200,198); + border-color: rgb(40, 41, 42); +} +:root.tomorrow #qr .field:focus, +:root.tomorrow #qr .field.focus { + border-color: rgb(129, 162, 190) !important; + background-color: rgb(30,32,36); +} +:root.tomorrow .persona button { + background: linear-gradient(to bottom, #2E3035, #222427) no-repeat; + color: rgb(197,200,198); + border-color: rgb(40, 41, 42); + outline: none; +} +:root.tomorrow .persona button::-moz-focus-inner { + border: none; +} +:root.tomorrow .persona button:focus { + border-color: rgb(129, 162, 190); +} +:root.tomorrow #qr.sjis-preview #sjis-toggle, +:root.tomorrow #qr.tex-preview #tex-preview-button { + background: rgb(26, 27, 29); +} +:root.tomorrow #qr select, +:root.tomorrow #file-n-submit > input, +:root.tomorrow #qr-draw-button { + border-color: rgb(40, 41, 42); +} +:root.tomorrow #qr-filename { + color: rgb(197,200,198); +} +:root.tomorrow .qr-link { + border-color: rgb(25, 27, 31) rgb(25, 27, 31) rgb(10, 12, 16); + background: linear-gradient(#37393D, #282A2E) repeat scroll 0% 0% transparent; +} +:root.tomorrow .qr-link:hover { + background: #282A2E; +} + +/* Menu */ +:root.tomorrow #menu { + color: #C5C8C6; +} +:root.tomorrow .entry { + font-size: 10pt; +} +:root.tomorrow .focused.entry { + background: rgba(0, 0, 0, .33); +} + +/* Unread */ +:root.tomorrow .unread-line { + border-color: rgb(197, 200, 198); +} +:root.tomorrow .unread-mark-read { + background-color: rgba(40,42,46,0.5); +} + +/* Thread Watcher */ +:root.tomorrow .replies-quoting-you > a, :root.tomorrow #watcher-link.replies-quoting-you, :root.tomorrow .last-page > a > .watcher-page { + color: #F00 !important; +} + +/* Watcher Favicon */ +:root.tomorrow .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + var www = `#captcha-cnt { + height: auto; +} +:root:not(.js-enabled) #form { + display: block; +} +#bd > div[style], #bd > div[style] > * { + height: auto !important; + margin: 0 !important; + font-size: 0; +} +`; + + var yotsubaB = `/* General */ +:root.yotsuba-b .dialog { + background-color: #D6DAF0; + border-color: #B7C5D9; +} +:root.yotsuba-b .field:focus, +:root.yotsuba-b .field.focus { + border-color: #98E; +} + +/* 4chan style fixes */ +:root.yotsuba-b.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(221, 0, 0, .8) !important; +} +:root.yotsuba-b.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(221, 0, 0, .8) !important; +} + +/* Header */ +:root.yotsuba-b #header-bar.dialog { + background-color: rgba(214,218,240,0.98); +} +:root.yotsuba-b:not(.fixed) #header-bar, :root.yotsuba-b #notifications { + font-size: 9pt; +} +:root.yotsuba-b #header-bar, :root.yotsuba-b #notifications { + color: #89A; +} +:root.yotsuba-b #board-list a, :root.yotsuba-b #shortcuts a { + color: #34345C; +} + +/* Settings */ +:root.yotsuba-b #fourchanx-settings fieldset, :root.yotsuba-b .section-main div::before { + border-color: #B7C5D9; +} +:root.yotsuba-b .suboption-list > div:last-of-type { + background-color: #D6DAF0; +} + +/* Catalog */ +:root.yotsuba-b.catalog-hover-expand .catalog-container:hover > .post { + background-color: #D6DAF0; +} +:root.yotsuba-b.werkTyme .catalog-thread:not(:hover), +:root.yotsuba-b.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.yotsuba-b.catalog-hover-expand .catalog-container:hover > .post, +:root.yotsuba-b.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #B7C5D9; +} + +/* Quote */ +:root.yotsuba-b .backlink.deadlink { + color: #34345C !important; +} +:root.yotsuba-b .inline { + border-color: #B7C5D9; + background-color: rgba(255, 255, 255, .14); +} + +/* Fappe and Werk Tyme */ +:root.yotsuba-b .indicator { + color: #D6DAF0; +} + +/* QR */ +.yotsuba-b #dump-list::-webkit-scrollbar-thumb { + background-color: #D6DAF0; + border-color: #B7C5D9; +} +:root.yotsuba-b .qr-preview { + background-color: rgba(0, 0, 0, .15); +} +:root.yotsuba-b .qr-link { + border-color: rgb(199, 203, 225) rgb(199, 203, 225) rgb(184, 188, 210); + background: linear-gradient(#E5E9FF, #D6DAF0) repeat scroll 0% 0% transparent; +} +:root.yotsuba-b .qr-link:hover { + background: #D9DDF3; +} + + +/* Menu */ +:root.yotsuba-b #menu { + color: #000; +} +:root.yotsuba-b .entry { + font-size: 10pt; +} +:root.yotsuba-b .focused.entry { + background: rgba(255, 255, 255, .33); +} + +/* Unread */ +:root.yotsuba-b .unread-mark-read { + background-color: rgba(214,218,240,0.5); +} + +/* Thread Watcher */ +:root.yotsuba-b .replies-quoting-you > a, :root.yotsuba-b #watcher-link.replies-quoting-you { + color: #F00; +} + +/* Watcher Favicon */ +:root.yotsuba-b .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + var yotsuba = `/* General */ +:root.yotsuba .dialog { + background-color: #F0E0D6; + border-color: #D9BFB7; +} +:root.yotsuba .field:focus, +:root.yotsuba .field.focus { + border-color: #EA8; +} + +/* 4chan style fixes */ +:root.yotsuba.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(221, 0, 0, .8) !important; +} +:root.yotsuba.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(221, 0, 0, .8) !important; +} + +/* Header */ +:root.yotsuba #header-bar.dialog { + background-color: rgba(240,224,214,0.98); +} +:root.yotsuba:not(.fixed) #header-bar, :root.yotsuba #notifications { + font-size: 9pt; +} +:root.yotsuba #header-bar, :root.yotsuba #notifications { + color: #B86; +} +:root.yotsuba #board-list a, :root.yotsuba #shortcuts a { + color: #800000; +} + +/* Settings */ +:root.yotsuba #fourchanx-settings fieldset, :root.yotsuba .section-main div::before { + border-color: #D9BFB7; +} +:root.yotsuba .suboption-list > div:last-of-type { + background-color: #F0E0D6; +} + +/* Catalog */ +:root.yotsuba.catalog-hover-expand .catalog-container:hover > .post { + background-color: #F0E0D6; +} +:root.yotsuba.werkTyme .catalog-thread:not(:hover), +:root.yotsuba.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.yotsuba.catalog-hover-expand .catalog-container:hover > .post, +:root.yotsuba.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #D9BFB7; +} + +/* Quote */ +:root.yotsuba .backlink.deadlink { + color: #00E !important; +} +:root.yotsuba .inline { + border-color: #D9BFB7; + background-color: rgba(255, 255, 255, .14); +} + +/* Fappe and Werk Tyme */ +:root.yotsuba .indicator { + color: #F0E0D6; +} + +/* QR */ +.yotsuba #dump-list::-webkit-scrollbar-thumb { + background-color: #F0E0D6; + border-color: #D9BFB7; +} +:root.yotsuba .qr-preview { + background-color: rgba(0, 0, 0, .15); +} +:root.yotsuba .qr-link { + border-color: rgb(225, 209, 199) rgb(225, 209, 199) rgb(210, 194, 184); + background: linear-gradient(#FFEFE5, #F0E0D6) repeat scroll 0% 0% transparent; +} +:root.yotsuba .qr-link:hover { + background: #F0E0D6; +} + +/* Menu */ +:root.yotsuba #menu { + color: #800000; +} +:root.yotsuba .entry { + font-size: 10pt; +} +:root.yotsuba .focused.entry { + background: rgba(255, 255, 255, .33); +} + +/* Unread */ +:root.yotsuba .unread-mark-read { + background-color: rgba(240,224,214,0.5); +} + +/* Thread Watcher */ +:root.yotsuba .replies-quoting-you > a, :root.yotsuba #watcher-link.replies-quoting-you, :root.yotsuba .last-page > a > .watcher-page { + color: #F00; +} + +/* Watcher Favicon */ +:root.yotsuba .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + // == Create CSS for Link Title Favicons == // + const icons = (data) => ('/* Link Title Favicons */\n' + + data.map(({ name, data }) => `.linkify.${name}::before { + content: ""; + background: transparent url('data:image/png;base64,${data}') center left no-repeat!important; + padding-left: 18px; +} +`).join('')); + + // cSpell:ignore installGentoo, webfont + // <% + // var inc = require['style']; + // var faCSS = read('/node_modules/font-awesome/css/font-awesome.css'); + // var mainCSS = ['font-awesome', 'style', 'yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon', 'spooky'].map(x => read(`${x}.css`)).join(''); + // var iconNames = files.filter(f => /^linkify\.[^.]+\.png$/.test(f)); + // var icons = iconNames.map(readBase64); + // %> + const mainCSS = style + yotsuba + yotsubaB + futaba + burichan + tomorrow + photon + spooky; + const faIcons = [ + { name: "Audio", data: linkifyAudio }, + { name: "Bitchute", data: linkifyBitchute }, + { name: "Clyp", data: linkifyClyp }, + { name: "Dailymotion", data: linkifyDailymotion }, + { name: "Gfycat", data: linkifyGfycat }, + { name: "Gist", data: linkifyGist }, + { name: "Image", data: linkifyImage }, + { name: "Installgentoo", data: linkifyInstallgentoo }, + { name: "Liveleak", data: linkifyLiveleak }, + { name: "Pastebin", data: linkifyPastebin }, + { name: "Peertube", data: linkifyPeertube }, + { name: "Soundcloud", data: linkifySoundcloud }, + { name: "Streamable", data: linkifyStreamable }, + { name: "Twitchtv", data: linkifyTwitchtv }, + { name: "Twitter", data: linkifyTwitter }, + { name: "Video", data: linkifyVideo }, + { name: "Vidlii", data: linkifyVidlii }, + { name: "Cimeo", data: linkifyCimeo }, + { name: "Vine", data: linkifyVine }, + { name: "Vocaroo", data: linkifyVocaroo }, + { name: "Youtube", data: linkifyYoutube }, + ]; + const CSS = { + boards: mainCSS + icons(faIcons) + supports, + report, + www, + sub: function (css) { + var variables = { + site: g.SITE.selectors + }; + return css.replace(/\$[\w\$]+/g, function (name) { + var words = name.slice(1).split('$'); + var sel = variables; + for (var i = 0; i < words.length; i++) { + if (typeof sel !== 'object') + return ':not(*)'; + sel = $$1.getOwn(sel, words[i]); + } + if (typeof sel !== 'string') + return ':not(*)'; + return sel; + }); + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const CustomCSS = { + init() { + if (!Conf['Custom CSS']) { return; } + return this.addStyle(); + }, + + addStyle() { + return this.style = $$1.addStyle(CSS.sub(Conf['usercss']), 'custom-css', '#fourchanx-css'); + }, + + rmStyle() { + if (this.style) { + $$1.rm(this.style); + return delete this.style; + } + }, + + update() { + if (!this.style) { + return this.addStyle(); + } + return this.style.textContent = CSS.sub(Conf['usercss']); + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const SWTinyboard = { + isOPContainerThread: true, + mayLackJSON: true, + threadModTimeIgnoresSage: true, + + 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 script of $$('script:not([src])', d$1.head)) { + var m; + if (m = script.textContent.match(/\bvar configRoot=(".*?")/)) { + var properties = dict(); + try { + var root = JSON.parse(m[1]); + if (root[0] === '/') { + properties.root = location.origin + root; + } else if (/^https?:/.test(root)) { + properties.root = root; + } + } catch (error) {} + return properties; + } + } + return false; + }, + + awaitBoard(cb) { + if ($$1.id('react-ui')) { + const s = (this.selectors = Object.create(this.selectors)); + s.boardFor = {index: '.page-container'}; + s.thread = 'div[id^="thread_"]'; + return Main$1.mounted(cb); + } else { + return cb(); + } + }, + + urls: { + thread({siteID, boardID, threadID}, isArchived) { + return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/${isArchived ? 'archive/' : ''}res/${threadID}.html`; + }, + post({postID}) { return `#${postID}`; }, + index({siteID, boardID}) { return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/`; }, + catalog({siteID, boardID}) { return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/catalog.html`; }, + threadJSON({siteID, boardID, threadID}, isArchived) { + const root = Conf['siteProperties'][siteID]?.root; + if (root) { return `${root}${boardID}/${isArchived ? 'archive/' : ''}res/${threadID}.json`; } else { return ''; } + }, + archivedThreadJSON(thread) { + return SWTinyboard.urls.threadJSON(thread, true); + }, + threadsListJSON({siteID, boardID}) { + const root = Conf['siteProperties'][siteID]?.root; + if (root) { return `${root}${boardID}/threads.json`; } else { return ''; } + }, + archiveListJSON({siteID, boardID}) { + const root = Conf['siteProperties'][siteID]?.root; + if (root) { return `${root}${boardID}/archive/archive.json`; } else { return ''; } + }, + catalogJSON({siteID, boardID}) { + const root = Conf['siteProperties'][siteID]?.root; + if (root) { return `${root}${boardID}/catalog.json`; } else { return ''; } + }, + file({siteID, boardID}, filename) { + return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/${filename}`; + }, + thumb(board, filename) { + return SWTinyboard.urls.file(board, filename); + } + }, + + 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)', // postContainer is thread for OP + 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: + /]*\bhref="[^"]*\/([^\/]+)\/res\/(\d+)(?:\.\w+)?#(\d+)"/g + }, + + Build: { + parseJSON(data, board) { + const o = this.parseJSON(data, board); + if (data.ext === 'deleted') { + delete o.file; + $$1.extend(o, { + files: [], + fileDeleted: true, + filesDeleted: [0] + }); + } + if (data.extra_files) { + let file; + for (let i = 0; i < data.extra_files.length; i++) { + var extra_file = data.extra_files[i]; + if (extra_file.ext === 'deleted') { + o.filesDeleted.push(i); + } else { + file = this.parseJSONFile(data, board); + o.files.push(file); + } + } + if (o.files.length) { + o.file = o.files[0]; + } + } + return o; + }, + + parseComment(html) { + html = html + .replace(//gi, '\n') + .replace(/<[^>]*>/g, ''); + return $$1.unescape(html); + } + }, + + bgColoredEl() { + return $$1.el('div', {className: 'post reply'}); + }, + + isFileURL(url) { + return /\/src\/[^\/]+/.test(url.pathname); + }, + + preParsingFixes(board) { + // fixes effects of unclosed link in announcement + let broken; + if (broken = $$1('a > input[name="board"]', board)) { + return $$1.before(broken.parentNode, broken); + } + }, + + parseNodes(post, nodes) { + // Add vichan's span.poster_id around the ID if not already present. + let m; + if (nodes.uniqueID) { return; } + let text = ''; + let node = nodes.nameBlock.nextSibling; + while (node && (node.nodeType === 3)) { + text += node.textContent; + node = node.nextSibling; + } + if (m = text.match(/(\s*ID:\s*)(\S+)/)) { + let uniqueID; + nodes.info.normalize(); + let {nextSibling} = nodes.nameBlock; + nextSibling = nextSibling.splitText(m[1].length); + nextSibling.splitText(m[2].length); + nodes.uniqueID = (uniqueID = $$1.el('span', {className: 'poster_id'})); + $$1.replace(nextSibling, uniqueID); + return $$1.add(uniqueID, nextSibling); + } + }, + + parseDate(node) { + let date = Date.parse(node.getAttribute('datetime')?.trim()); + if (!isNaN(date)) { return new Date(date); } + date = Date.parse(node.textContent.trim() + ' UTC'); // e.g. onesixtwo.club + if (!isNaN(date)) { return new Date(date); } + return undefined; + }, + + parseFile(post, file) { + let info, infoNode; + const {text, link, thumb} = file; + if ($$1.x(`ancestor::${this.xpath.postContainer}[1]`, text) !== post.nodes.root) { return false; } // file belongs to a reply + if (!(infoNode = link.nextSibling?.textContent.includes('(') ? link.nextSibling : link.nextElementSibling)) { return false; } + if (!(info = infoNode.textContent.match(/\((.*,\s*)?([\d.]+ ?[KMG]?B).*\)/))) { return false; } + const nameNode = $$1('.postfilename', text); + $$1.extend(file, { + name: nameNode ? (nameNode.title || nameNode.textContent) : link.pathname.match(/[^/]*$/)[0], + size: info[2], + dimensions: info[0].match(/\d+x\d+/)?.[0] + }); + if (thumb) { + $$1.extend(file, { + thumbURL: /\/static\//.test(thumb.src) && $$1.isImage(link.href) ? link.href : thumb.src, + isSpoiler: /^Spoiler/i.test(info[1] || '') || (link.textContent === 'Spoiler Image') + } + ); + } + return true; + }, + + isThumbExpanded(file) { + // Detect old Tinyboard image expansion that changes src attribute on thumbnail. + return $$1.hasClass(file.thumb.parentNode, 'expanded') || (file.thumb.parentNode.dataset.expanded === 'true'); + }, + + isLinkified(link) { + return /\bnofollow\b/.test(link.rel); + }, + + catalogPin(threadRoot) { + return threadRoot.dataset.sticky = 'true'; + } + }; + + const passMessagePage = h("div", { class: "box-inner" }, + h("div", { class: "boxbar" }, + h("h2", null, + "Trouble buying a 4chan Pass? (a message from 4chan X)", + h("a", { href: "javascript:;", style: "text-decoration: none; float: right; margin-right: 4px;", title: "Close" }, "\u00D7"))), + h("div", { class: "boxcontent" }, + "Check the 4chan X wiki for ", + h("a", { href: `${meta.captchaFAQ}#alternatives`, target: "_blank", rel: "noopener" }, "alternative solutions"), + ".")); + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + const PassMessage = { + init() { + if (Conf['passMessageClosed']) { return; } + const msg = $$1.el('div', + {className: 'box-outer top-box'} + , + passMessagePage); + msg.style.cssText = 'padding-bottom: 0;'; + const close = $$1('a', msg); + $$1.on(close, 'click', function() { + $$1.rm(msg); + return $$1.set('passMessageClosed', true); + }); + return $$1.ready(function() { + let hd; + if (hd = $$1.id('hd')) { + return $$1.after(hd, msg); + } else { + return $$1.prepend(d$1.body, msg); + } + }); + } + }; + + var ReportPage = ` + + + +`; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var Report = { + init() { + let match; + if (!(match = location.search.match(/\bno=(\d+)/))) { return; } + Captcha.replace.init(); + this.postID = +match[1]; + return $$1.ready(this.ready); + }, + + ready() { + $$1.addStyle(CSS.report); + + if (Conf['Archive Report']) { Report.archive(); } + + new MutationObserver(function() { + Report.fit('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); + return Report.fit('body'); + }).observe(d$1.body, { + childList: true, + attributes: true, + subtree: true + } + ); + return Report.fit('body'); + }, + + fit(selector) { + let el; + if (!((el = $$1(selector, doc)) && (getComputedStyle(el).visibility !== 'hidden'))) { return; } + const dy = (el.getBoundingClientRect().bottom - doc.clientHeight) + 8; + if (dy > 0) { return window.resizeBy(0, dy); } + }, + + archive() { + let match, urls; + if (!(urls = Redirect$1.report(g.BOARD.ID)).length) { return; } + + const form = $$1('form'); + const types = $$1.id('reportTypes'); + const message = $$1('h3'); + + const fieldset = $$1.el('fieldset', { + id: 'archive-report', + hidden: true + } + , + { innerHTML: ReportPage }); + const enabled = $$1('#archive-report-enabled', fieldset); + const reason = $$1('#archive-report-reason', fieldset); + const submit = $$1('#archive-report-submit', fieldset); + + $$1.on(enabled, 'change', function() { + return reason.disabled = !this.checked; + }); + + if (form && types) { + fieldset.hidden = !$$1('[value="31"]', types).checked; + $$1.on(types, 'change', function(e) { + fieldset.hidden = (e.target.value !== '31'); + return Report.fit('body'); + }); + $$1.after(types, fieldset); + Report.fit('body'); + $$1.one(form, 'submit', function(e) { + if (!fieldset.hidden && enabled.checked) { + e.preventDefault(); + return Report.archiveSubmit(urls, reason.value, results => { + this.action = '#archiveresults=' + encodeURIComponent(JSON.stringify(results)); + return this.submit(); + }); + } + }); + } else if (message) { + fieldset.hidden = /Report submitted!/.test(message.textContent); + $$1.on(enabled, 'change', function() { + return submit.hidden = !this.checked; + }); + $$1.after(message, fieldset); + $$1.on(submit, 'click', () => Report.archiveSubmit(urls, reason.value, Report.archiveResults)); + } + + if (match = location.hash.match(/^#archiveresults=(.*)$/)) { + try { + return Report.archiveResults(JSON.parse(decodeURIComponent(match[1]))); + } catch (error) {} + } + }, + + archiveSubmit(urls, reason, cb) { + const form = $$1.formData({ + board: g.BOARD.ID, + num: Report.postID, + reason + }); + const results = []; + for (var [name, url] of urls) { + (function(name, url) { + return $$1.ajax(url, { + onloadend() { + results.push([name, this.response || {error: ''}]); + if (results.length === urls.length) { + return cb(results); + } + }, + form + }); + })(name, url); + } + }, + + archiveResults(results) { + const fieldset = $$1.id('archive-report'); + for (var [name, response] of results) { + var line = $$1.el('h3', + {className: 'archive-report-response'}); + if ('success' in response) { + $$1.addClass(line, 'archive-report-success'); + line.textContent = `${name}: ${response.success}`; + } else { + $$1.addClass(line, 'archive-report-error'); + line.textContent = `${name}: ${response.error || 'Error reporting post.'}`; + } + if (fieldset) { + $$1.before(fieldset, line); + } else { + $$1.add(d$1.body, line); + } + } + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const PostSuccessful = { + init() { + if (!Conf['Remember Your Posts']) { return; } + return $$1.ready(this.ready); + }, + + ready() { + if (d$1.title !== 'Post successful!') { return; } + + let [_, threadID, postID] = Array.from($$1('h1').nextSibling.textContent.match(/thread:(\d+),no:(\d+)/)); + postID = +postID; + threadID = +threadID || postID; + + const db = new DataBoard('yourPosts'); + return db.set({ + boardID: g.BOARD.ID, + threadID, + postID, + val: true + }); + } + }; + + function generatePostInfoHtml(ID, o, subject, capcode, email, name, tripcode, pass, capcodeLC, capcodePlural, staticPath, gifIcon, capcodeDescription, uniqueID, flag, flagCode, flagCodeTroll, dateUTC, dateText, postLink, quoteLink, boardID, threadID) { + const nameHtml = [h("span", { class: `name${capcode ? ' ' + capcode : ''}` }, name)]; + if (tripcode) + nameHtml.push(' ', h("span", { class: "postertrip" }, tripcode)); + if (pass) + nameHtml.push(' ', h("span", { title: `Pass user since ${pass}`, class: "n-pu" })); + if (capcode) { + nameHtml.push(' ', h("strong", { class: `capcode hand id_${capcodeLC}`, title: `Highlight posts by ${capcodePlural}` }, + "## ", + capcode)); + } + const nameBlockContent = email ? [' ', h("a", { href: `mailto:${email}`, class: "useremail" }, ...nameHtml)] : nameHtml; + if (!(boardID === "f" && !o.isReply || capcodeDescription)) + nameBlockContent.push(' '); + if (capcodeDescription) { + nameBlockContent.push(h("img", { src: `${staticPath}${capcodeLC}icon${gifIcon}`, alt: `${capcode} Icon}`, title: `This user is ${capcodeDescription}.`, class: "identityIcon retina" })); + if (uniqueID && !capcode) { + nameBlockContent.push(h("span", { class: `posteruid id_${uniqueID}` }, + "(ID: ", + h("span", { class: "hand", title: "Highlight posts by this ID" }, + "$", + uniqueID), + ")")); + } + } + if (flagCode) + nameBlockContent.push(' ', h("span", { title: flag, class: `flag flag-${flagCode.toLowerCase()}` })); + if (flagCodeTroll) + nameBlockContent.push(' ', h("span", { title: flag, class: `bfl bfl-${flagCodeTroll.toLowerCase()}` })); + const postNumContent = [ + h("a", { href: postLink, title: "Link to this post" }, "No."), + h("a", { href: quoteLink, title: "Reply to this post" }, ID), + ]; + if (o.isSticky) { + const src = `${staticPath}sticky${gifIcon}`; + postNumContent.push(' '); + if (boardID === "f") { + postNumContent.push(h("img", { src: src, alt: "Sticky", title: "Sticky", style: "height: 18px; width: 18px;" })); + } + else { + postNumContent.push(h("img", { src: src, alt: "Sticky", title: "Sticky", class: "stickyIcon retina" })); + } + } + if (o.isClosed && !o.isArchived) { + postNumContent.push(' '); + const src = `${staticPath}closed${gifIcon}`; + if (boardID === "f") { + postNumContent.push(h("img", { src: src, alt: "Closed", title: "Closed", style: "height: 18px; width: 18px;" })); + } + else { + postNumContent.push(h("img", { src: src, alt: "Closed", title: "Closed", class: "closedIcon retina" })); + } + } + if (o.isArchived) { + postNumContent.push(' ', h("img", { src: `${staticPath}archived${gifIcon}`, alt: "Archived", title: "Archived", class: "archivedIcon retina" })); + } + if (!o.isReply && g.VIEW === "index") { + // \u00A0 is nbsp + postNumContent.push(' \u00A0 '); + postNumContent.push(h("span", null, + "[", + h("a", { href: `/${boardID}/thread/${threadID}`, class: "replylink" }, "Reply"), + "]")); + } + return h("div", { class: "postInfo desktop", id: `pi${ID}` }, + h("input", { type: "checkbox", name: ID, value: "delete" }), + ' ', + ...((!o.isReply || boardID === "f" || subject) ? [h("span", { class: "subject" }, subject), ' '] : []), + h("span", { class: `nameBlock${capcode || ''}` }, ...nameBlockContent), + ' ', + h("span", { class: "dateTime", "data-utc": dateUTC }, dateText), + ' ', + h("span", { class: `postNum${!(boardID === " f" && !o.isReply) ? ' desktop' : ''}` }, ...postNumContent)); + } + + function generateFileHtml(file, ID, boardID, fileURL, shortFilename, fileThumb, o, staticPath, gifIcon) { + if (file) { + const fileContent = []; + if (boardID === "f") { + fileContent.push(h("div", { class: "fileInfo", "data-md5": file.MD5 }, + h("span", { class: "fileText", id: `fT${ID}` }, + 'File: ', + h("a", { "data-width": file.width, "data-height": file.height, href: fileURL, target: "_blank" }, file.name), + "-(", + file.size, + ", ", + file.dimensions, + file.tag ? ', ' + file.tag : '', + ")"))); + } + else { + fileContent.push(h("div", { class: "fileText", id: `fT${ID}`, title: file.isSpoiler ? file.name : null }, + 'File: ', + h("a", { title: file.name === shortFilename || file.isSpoiler ? null : file.name, href: fileURL, target: "_blank" }, file.isSpoiler ? 'Spoiler Image' : shortFilename), + ` (${file.size}, ${file.dimensions || "PDF"})`), h("a", { class: `fileThumb${file.isSpoiler ? ' imgspoiler' : ''}`, href: fileURL, target: "_blank", "data-m": file.hasDownscale ? '' : null }, + h("img", { src: fileThumb, alt: file.size, "data-md5": file.MD5, style: `height: ${file.isSpoiler ? '100' : file.theight}px; width: ${file.isSpoiler ? '100' : file.twidth}px;`, loading: "lazy" }))); + } + return h("div", { class: "file", id: `f${ID}` }, ...fileContent); + } + else if (o.fileDeleted) { + return h("div", { class: "file", id: `f${ID}` }, + h("span", { class: "fileThumb" }, + h("img", { src: `${staticPath}filedeleted-res${gifIcon}`, alt: "File deleted.", class: "fileDeletedRes retina" }))); + } + return { innerHTML: '', [isEscaped]: true }; + } + + function generateCatalogThreadHtml(thread, src, imgClass, data, postCount, fileCount, pageCount, staticPath, gifIcon) { + return h(hFragment, null, + h("a", { class: "catalog-link", href: `/${thread.board}/thread/${thread.ID}` }, imgClass ? + h("img", { src: src, class: `catalog-thumb ${imgClass}` }) : + h("img", { src: src, class: "catalog-thumb", "data-width": data.tn_w, "data-height": data.tn_h })), + h("div", { class: "catalog-stats" }, + h("span", { title: "Posts / Files / Page" }, + h("span", { class: `post-count${data.bumplimit ? ' warning' : ''}` }, postCount), + ' / ', + h("span", { class: `file-count${data.imagelimit ? ' warning' : ''}` }, fileCount), + ' / ', + h("span", { class: "page-count" }, pageCount)), + h("span", { class: "catalog-icons" }, + thread.isSticky ? h("img", { src: `${staticPath}sticky${gifIcon}`, class: "stickyIcon", title: "Sticky" }) : '', + thread.isClosed ? h("img", { src: `${staticPath}closed${gifIcon}`, class: "closedIcon", title: "Closed" }) : ''))); + } + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const SWYotsuba = { + isOPContainerThread: false, + hasIPCount: true, + archivedBoardsKnown: true, + urls: { + thread({ boardID, threadID }) { return `${location.protocol}//${BoardConfig.domain(boardID)}/${boardID}/thread/${threadID}`; }, + post({ postID }) { return `#p${postID}`; }, + index({ boardID }) { return `${location.protocol}//${BoardConfig.domain(boardID)}/${boardID}/`; }, + catalog({ boardID }) { if (boardID === 'f') { + return undefined; + } + else { + return `${location.protocol}//${BoardConfig.domain(boardID)}/${boardID}/catalog`; + } }, + archive({ boardID }) { if (BoardConfig.isArchived(boardID)) { + return `${location.protocol}//${BoardConfig.domain(boardID)}/${boardID}/archive`; + } + else { + return undefined; + } }, + threadJSON({ boardID, threadID }) { return `${location.protocol}//a.4cdn.org/${boardID}/thread/${threadID}.json`; }, + threadsListJSON({ boardID }) { return `${location.protocol}//a.4cdn.org/${boardID}/threads.json`; }, + archiveListJSON({ boardID }) { if (BoardConfig.isArchived(boardID)) { + return `${location.protocol}//a.4cdn.org/${boardID}/archive.json`; + } + else { + return ''; + } }, + catalogJSON({ boardID }) { return `${location.protocol}//a.4cdn.org/${boardID}/catalog.json`; }, + file({ boardID }, filename) { + const hostname = boardID === 'f' ? ImageHost.flashHost() : ImageHost.host(); + return `${location.protocol}//${hostname}/${boardID}/${filename}`; + }, + thumb({ boardID }, filename) { + return `${location.protocol}//${ImageHost.thumbHost()}/${boardID}/${filename}`; + } + }, + isPrunedByAge({ boardID }) { return boardID === 'f'; }, + areMD5sDeferred({ boardID }) { return boardID === 'f'; }, + isOnePage({ boardID }) { return boardID === 'f'; }, + noAudio({ boardID }) { return BoardConfig.noAudio(boardID); }, + 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: /]*\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() { + return $$1.el('div', { className: 'reply' }); + }, + isThisPageLegit() { + // not 404 error page or similar. + return ['boards.4chan.org', 'boards.4channel.org'].includes(location.hostname) && + d$1.doctype && + !$$1('link[href*="favicon-status.ico"]', d$1.head) && + !['4chan - Temporarily Offline', '4chan - Error', '504 Gateway Time-out', 'MathJax Equation Source'].includes(d$1.title); + }, + is404() { + // XXX Sometimes threads don't 404 but are left over as stubs containing one garbage reply post. + return ['4chan - Temporarily Offline', '4chan - 404 Not Found'].includes(d$1.title) || ((g.VIEW === 'thread') && $$1('.board') && !$$1('.opContainer')); + }, + isIncomplete() { + return ['index', 'thread'].includes(g.VIEW) && !$$1('.board + *'); + }, + isBoardlessPage(url) { + return ['www.4chan.org', 'www.4channel.org'].includes(url.hostname); + }, + isAuxiliaryPage(url) { + return !['boards.4chan.org', 'boards.4channel.org'].includes(url.hostname); + }, + isFileURL(url) { + return ImageHost.test(url.hostname); + }, + initAuxiliary() { + switch (location.hostname) { + case 'www.4chan.org': + case 'www.4channel.org': + if (SWYotsuba.regexp.pass.test(location.href)) { + PassMessage.init(); + } + else { + $$1.onExists(doc$1, 'body', () => $$1.addStyle(CSS.www)); + Captcha.replace.init(); + } + return; + case 'sys.4chan.org': + case 'sys.4channel.org': + var pathname = location.pathname.split(/\/+/); + if (pathname[2] === 'imgboard.php') { + let match; + if (/\bmode=report\b/.test(location.search)) { + Report.init(); + } + else if (match = location.search.match(/\bres=(\d+)/)) { + $$1.ready(function () { + if (Conf['404 Redirect'] && ($$1.id('errmsg')?.textContent === 'Error: Specified thread does not exist.')) { + return Redirect$1.navigate('thread', { + boardID: g.BOARD.ID, + postID: +match[1] + }); + } + }); + } + } + else if (pathname[2] === 'post') { + PostSuccessful.init(); + } + return; + } + }, + scriptData() { + for (var script of $$('script:not([src])', d$1.head)) { + if (/\bcooldowns *=/.test(script.textContent)) { + return script.textContent; + } + } + return ''; + }, + parseThreadMetadata(thread) { + let m; + const scriptData = this.scriptData(); + thread.postLimit = /\bbumplimit *= *1\b/.test(scriptData); + thread.fileLimit = /\bimagelimit *= *1\b/.test(scriptData); + thread.ipCount = (m = scriptData.match(/\bunique_ips *= *(\d+)\b/)) ? +m[1] : undefined; + if ((g.BOARD.ID === 'f') && thread.OP.file) { + const { file } = thread.OP; + return $$1.ajax(this.urls.threadJSON({ boardID: 'f', threadID: thread.ID }), { + timeout: MINUTE, + onloadend() { + if (this.response) { + return file.text.dataset.md5 = (file.MD5 = this.response.posts[0].md5); + } + } + }); + } + }, + parseNodes(post, nodes) { + // Add CSS classes to sticky/closed icons on /f/ to match other boards. + if (post.boardID === 'f') { + return (() => { + const result = []; + for (var type of ['Sticky', 'Closed']) { + var icon; + if (icon = $$1(`img[alt=${type}]`, nodes.info)) { + result.push($$1.addClass(icon, `${type.toLowerCase()}Icon`, 'retina')); + } + } + return result; + })(); + } + }, + parseDate(node) { + return new Date(node.dataset.utc * 1000); + }, + parseFile(post, file) { + let info; + const { text, link, thumb } = file; + if (!(info = link.nextSibling?.textContent.match(/\(([\d.]+ [KMG]?B).*\)/))) { + return false; + } + $$1.extend(file, { + name: text.title || link.title || link.textContent, + size: info[1], + dimensions: info[0].match(/\d+x\d+/)?.[0], + tag: info[0].match(/,[^,]*, ([a-z]+)\)/i)?.[1], + MD5: text.dataset.md5 + }); + if (thumb) { + $$1.extend(file, { + thumbURL: thumb.src, + MD5: thumb.dataset.md5, + isSpoiler: $$1.hasClass(thumb.parentNode, 'imgspoiler') + }); + if (file.isSpoiler) { + let m; + file.thumbURL = (m = link.href.match(/\d+(?=\.\w+$)/)) ? `${location.protocol}//${ImageHost.thumbHost()}/${post.board}/${m[0]}s.jpg` : undefined; + } + } + return true; + }, + cleanComment(bq) { + let abbr; + if (abbr = $$1('.abbr', bq)) { // 'Comment too long' or 'EXIF data available' + for (var node of $$('.abbr + br, .exif', bq)) { + $$1.rm(node); + } + for (let i = 0; i < 2; i++) { + var br; + if ((br = abbr.previousSibling) && (br.nodeName === 'BR')) { + $$1.rm(br); + } + } + return $$1.rm(abbr); + } + }, + cleanCommentDisplay(bq) { + let b; + if ((b = $$1('b', bq)) && /^Rolled /.test(b.textContent)) { + $$1.rm(b); + } + return $$1.rm($$1('.fortune', bq)); + }, + insertTags(bq) { + let node; + for (node of $$('s, .removed-spoiler', bq)) { + $$1.replace(node, [$$1.tn('[spoiler]'), ...Array.from(node.childNodes), $$1.tn('[/spoiler]')]); + } + for (node of $$('.prettyprint', bq)) { + $$1.replace(node, [$$1.tn('[code]'), ...Array.from(node.childNodes), $$1.tn('[/code]')]); + } + }, + hasCORS(url) { + return url.split('/').slice(0, 3).join('/') === (location.protocol + '//a.4cdn.org'); + }, + sfwBoards(sfw) { + return BoardConfig.sfwBoards(sfw); + }, + uidColor(uid) { + let msg = 0; + let i = 0; + while (i < 8) { + msg = ((msg << 5) - msg) + uid.charCodeAt(i++); + } + return (msg >> 8) & 0xFFFFFF; + }, + isLinkified(link) { + return ImageHost.test(link.hostname); + }, + testNativeExtension() { + return $$1.global(function () { + if (window.Parser?.postMenuIcon) { + return this.enabled = 'true'; + } + }); + }, + transformBoardList() { + let node; + const nodes = []; + const spacer = () => $$1.el('span', { className: 'spacer' }); + const items = $$1.X('.//a|.//text()[not(ancestor::a)]', $$1(SWYotsuba.selectors.boardList)); + let i = 0; + while ((node = items.snapshotItem(i++))) { + switch (node.nodeName) { + case '#text': + for (var chr of node.nodeValue) { + var span = $$1.el('span', { textContent: chr }); + if (chr === ' ') { + span.className = 'space'; + } + if (chr === ']') { + nodes.push(spacer()); + } + nodes.push(span); + if (chr === '[') { + nodes.push(spacer()); + } + } + break; + case 'A': + var a = node.cloneNode(true); + nodes.push(a); + break; + } + } + return nodes; + }, + Build: { + staticPath: '//s.4cdn.org/image/', + gifIcon: window.devicePixelRatio >= 2 ? '@2x.gif' : '.gif', + spoilerRange: Object.create(null), + shortFilename(filename) { + const ext = filename.match(/\.?[^\.]*$/)[0]; + if ((filename.length - ext.length) > 30) { + return `${filename.match(/(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[^]){0,25}/)[0]}(...)${ext}`; + } + else { + return filename; + } + }, + spoilerThumb(boardID) { + let spoilerRange; + if ((spoilerRange = this.spoilerRange[boardID])) { + // Randomize the spoiler image. + return `${this.staticPath}spoiler-${boardID}${Math.floor(1 + (spoilerRange * Math.random()))}.png`; + } + else { + return `${this.staticPath}spoiler.png`; + } + }, + sameThread(boardID, threadID) { + return (g.VIEW === 'thread') && (g.BOARD.ID === boardID) && (g.THREADID === +threadID); + }, + threadURL(boardID, threadID) { + if (boardID !== g.BOARD.ID) { + return `//${BoardConfig.domain(boardID)}/${boardID}/thread/${threadID}`; + } + else if ((g.VIEW !== 'thread') || (+threadID !== g.THREADID)) { + return `/${boardID}/thread/${threadID}`; + } + else { + return ''; + } + }, + postURL(boardID, threadID, postID) { + return `${this.threadURL(boardID, threadID)}#p${postID}`; + }, + parseJSON(data, { siteID, boardID }) { + const o = { + // id + ID: data.no, + postID: data.no, + threadID: data.resto || data.no, + boardID, + siteID, + isReply: !!data.resto, + // thread status + isSticky: !!data.sticky, + isClosed: !!data.closed, + isArchived: !!data.archived, + // file status + fileDeleted: !!data.filedeleted, + filesDeleted: data.filedeleted ? [0] : [] + }; + o.info = { + subject: $$1.unescape(data.sub), + email: $$1.unescape(data.email), + name: $$1.unescape(data.name) || '', + tripcode: data.trip, + pass: (data.since4pass != null) ? `${data.since4pass}` : undefined, + uniqueID: data.id, + flagCode: data.country, + flagCodeTroll: data.board_flag, + flag: $$1.unescape((data.country_name || data.flag_name)), + dateUTC: data.time, + dateText: data.now, + // Yes, we use the raw string here + commentHTML: { innerHTML: data.com || '', [isEscaped]: true } + }; + if (data.capcode) { + o.info.capcode = data.capcode.replace(/_highlight$/, '').replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase()); + o.capcodeHighlight = /_highlight$/.test(data.capcode); + delete o.info.uniqueID; + } + o.files = []; + if (data.ext) { + o.file = this.parseJSONFile(data, { siteID, boardID }); + o.files.push(o.file); + } + // Temporary JSON properties for events such as April 1 / Halloween + o.extra = dict(); + for (var key in data) { + if (key[0] === 'x') { + o.extra[key] = data[key]; + } + } + return o; + }, + parseJSONFile(data, { siteID, boardID }) { + const site = g.sites[siteID]; + const filename = (site.software === 'yotsuba') && (boardID === 'f') ? + `${encodeURIComponent(data.filename)}${data.ext}` + : + `${data.tim}${data.ext}`; + const o = { + name: ($$1.unescape(data.filename)) + data.ext, + url: site.urls.file({ siteID, boardID }, filename), + height: data.h, + width: data.w, + MD5: data.md5, + size: $$1.bytesToString(data.fsize), + thumbURL: site.urls.thumb({ siteID, boardID }, `${data.tim}s.jpg`), + theight: data.tn_h, + twidth: data.tn_w, + isSpoiler: !!data.spoiler, + tag: data.tag, + hasDownscale: !!data.m_img + }; + if ((data.h != null) && !/\.pdf$/.test(o.url)) { + o.dimensions = `${o.width}x${o.height}`; + } + return o; + }, + parseComment(html) { + html = html + .replace(//gi, '\n') + .replace(/\n\n]*>/g, ''); + return $$1.unescape(html); + }, + parseCommentDisplay(html) { + // Hide spoilers. + if (!Conf['Remove Spoilers'] && !Conf['Reveal Spoilers']) { + let html2; + while ((html2 = html.replace(/(?:(?!<\/?s>).)*<\/s>/g, '[spoiler]')) !== html) { + html = html2; + } + } + html = html + .replace(/^Rolled [^<]*<\/b>/i, '') // Rolls (/tg/, /qst/) + .replace(/>") : ''), + h("div", { id: `p${ID}`, class: `post ${postClass}${o.capcodeHighlight ? ' highlightPost' : ''}` }, + (o.isReply ? h(hFragment, null, + postInfo, + fileBlock) : h(hFragment, null, + fileBlock, + postInfo)), + h("blockquote", { class: "postMessage", id: `m${ID}` }, commentHTML))); + const container = $$1.el('div', { + className: `postContainer ${postClass}Container`, + id: `pc${ID}` + }); + $$1.extend(container, wholePost); + // Fix quotelinks + for (var quote of $$('.quotelink', container)) { + var href = quote.getAttribute('href'); + if (href[0] === '#') { + if (!this.sameThread(boardID, threadID)) { + quote.href = this.threadURL(boardID, threadID) + href; + } + } + else { + var match; + if ((match = quote.href.match(SWYotsuba.regexp.quotelink)) && (this.sameThread(match[1], match[2]))) { + quote.href = href.match(/(#[^#]*)?$/)[0] || '#'; + } + } + } + return container; + }, + summaryText(status, posts, files) { + let text = ''; + if (status) { + text += `${status} `; + } + text += `${posts} post${posts > 1 ? 's' : ''}`; + if (+files) { + text += ` and ${files} image repl${files > 1 ? 'ies' : 'y'}`; + } + return text += ` ${status === '-' ? 'shown' : 'omitted'}.`; + }, + summary(boardID, threadID, posts, files) { + return $$1.el('a', { + className: 'summary', + textContent: this.summaryText('', posts, files), + href: `/${boardID}/thread/${threadID}` + }); + }, + thread(thread, data, withReplies) { + let root; + if (root = thread.nodes.root) { + $$1.rmAll(root); + } + else { + thread.nodes.root = (root = $$1.el('div', { + className: 'thread', + id: `t${data.no}` + })); + } + if (this.hat) { + $$1.add(root, this.hat.cloneNode(false)); + } + $$1.add(root, thread.OP.nodes.root); + if (data.omitted_posts || (!withReplies && data.replies)) { + const [posts, files] = Array.from(withReplies ? + // XXX data.omitted_images is not accurate. + [data.omitted_posts, data.images - data.last_replies.filter(data => !!data.ext).length] + : + [data.replies, data.images]); + const summary = this.summary(thread.board.ID, data.no, posts, files); + $$1.add(root, summary); + } + return root; + }, + catalogThread(thread, data, pageCount) { + let cssText, imgClass, src; + const { staticPath, gifIcon } = this; + const { tn_w, tn_h } = data; + if (data.spoiler && !Conf['Reveal Spoiler Thumbnails']) { + let spoilerRange; + src = `${staticPath}spoiler`; + if (spoilerRange = this.spoilerRange[thread.board]) { + // Randomize the spoiler image. + src += (`-${thread.board}`) + Math.floor(1 + (spoilerRange * Math.random())); + } + src += '.png'; + imgClass = 'spoiler-file'; + cssText = "--tn-w: 100; --tn-h: 100;"; + } + else if (data.filedeleted) { + src = `${staticPath}filedeleted-res${gifIcon}`; + imgClass = 'deleted-file'; + } + else if (thread.OP.file) { + src = thread.OP.file.thumbURL; + const ratio = 250 / Math.max(tn_w, tn_h); + cssText = `--tn-w: ${tn_w * ratio}; --tn-h: ${tn_h * ratio};`; + } + else { + src = `${staticPath}nofile.png`; + imgClass = 'no-file'; + } + const postCount = data.replies + 1; + const fileCount = data.images + !!data.ext; + const container = $$1.el('div', generateCatalogThreadHtml(thread, src, imgClass, data, postCount, fileCount, pageCount, staticPath, gifIcon)); + $$1.before(thread.OP.nodes.info, [...Array.from(container.childNodes)]); + for (var br of $$('br', thread.OP.nodes.comment)) { + if (br.previousSibling && (br.previousSibling.nodeName === 'BR')) { + $$1.addClass(br, 'extra-linebreak'); + } + } + const root = $$1.el('div', { + className: 'thread catalog-thread', + id: `t${thread}` + }); + if (thread.OP.highlights) { + $$1.addClass(root, ...Array.from(thread.OP.highlights)); + } + if (!thread.OP.file) { + $$1.addClass(root, 'noFile'); + } + root.style.cssText = cssText || ''; + return root; + }, + catalogReply(thread, data) { + let excerpt = ''; + if (data.com) { + excerpt = this.parseCommentDisplay(data.com).replace(/>>\d+/g, '').trim().replace(/\n+/g, ' // '); + } + if (data.ext) { + if (!excerpt) { + excerpt = `${$$1.unescape(data.filename)}${data.ext}`; + } + } + if (data.com) { + if (!excerpt) { + excerpt = $$1.unescape(data.com.replace(//gi, ' // ')); + } + } + if (!excerpt) { + excerpt = '\xA0'; + } + if (excerpt.length > 73) { + excerpt = `${excerpt.slice(0, 70)}...`; + } + const link = this.postURL(thread.board.ID, thread.ID, data.no); + return $$1.el('div', { className: 'catalog-reply' }, h(hFragment, null, + h("span", null, + h("time", { "data-utc": data.time * 1000, "data-abbrev": "1" }, "..."), + ": "), + h("a", { class: "catalog-reply-excerpt", href: link }, excerpt), + h("a", { class: "catalog-reply-preview", href: link }, "..."))); + } + } + }; + + const SW = { tinyboard: SWTinyboard, yotsuba: SWYotsuba }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var FileInfo = { + init() { + if (!['index', 'thread', 'archive'].includes(g.VIEW) || !Conf['File Info Formatting']) { + return; + } + return Callbacks.Post.push({ + name: 'File Info Formatting', + cb: this.node + }); + }, + node() { + if (!this.file) { + return; + } + if (this.isClone) { + let a; + for (a of $$('.file-info .download-button', this.file.text)) { + $$1.on(a, 'click', ImageCommon.download); + } + for (a of $$('.file-info .quick-filter-md5', this.file.text)) { + $$1.on(a, 'click', Filter.quickFilterMD5); + } + return; + } + const oldInfo = $$1.el('span', { className: 'fileText-original' }); + $$1.prepend(this.file.link.parentNode, oldInfo); + $$1.add(oldInfo, [this.file.link.previousSibling, this.file.link, this.file.link.nextSibling]); + const info = $$1.el('span', { className: 'file-info' }); + FileInfo.format(Conf['fileInfo'], this, info); + return $$1.prepend(this.file.text, info); + }, + format(formatString, post, outputNode) { + let a; + const output = []; + formatString.replace(/%(.)|[^%]+/g, function (s, c) { + output.push($$1.hasOwn(FileInfo.formatters, c) ? + FileInfo.formatters[c].call(post) + : + { innerHTML: E(s) }); + return ''; + }); + $$1.extend(outputNode, { innerHTML: E.cat(output) }); + for (a of $$('.download-button', outputNode)) { + $$1.on(a, 'click', ImageCommon.download); + } + for (a of $$('.quick-filter-md5', outputNode)) { + $$1.on(a, 'click', Filter.quickFilterMD5); + } + }, + formatters: { + t() { return { innerHTML: E(this.file.url.match(/[^/]*$/)[0]), [isEscaped]: true }; }, + T() { return h("a", { href: this.file.url, target: "_blank" }, FileInfo.formatters.t.call(this)); }, + l() { return h("a", { href: this.file.url, target: "_blank" }, FileInfo.formatters.n.call(this)); }, + L() { return h("a", { href: this.file.url, target: "_blank" }, FileInfo.formatters.N.call(this)); }, + n() { + const fullname = this.file.name; + const shortname = SW.yotsuba.Build.shortFilename(this.file.name, this.isReply); + if (fullname === shortname) { + return { innerHTML: E(fullname), [isEscaped]: true }; + } + else { + return h("span", { class: "fnswitch" }, + h("span", { class: "fntrunc" }, shortname), + h("span", { class: "fnfull" }, fullname)); + } + }, + N() { return { innerHTML: E(this.file.name), [isEscaped]: true }; }, + d() { return h("a", { href: this.file.url, download: this.file.name, class: "download-button" }, "\uD83D\uDCE5\uFE0E"); }, + f() { + return { innerHTML: "", [isEscaped]: true }; + }, + p() { return { innerHTML: ((this.file.isSpoiler) ? "Spoiler, " : ""), [isEscaped]: true }; }, + s() { return { innerHTML: E(this.file.size), [isEscaped]: true }; }, + B() { return { innerHTML: Math.round(this.file.sizeInBytes) + " Bytes", [isEscaped]: true }; }, + K() { return { innerHTML: (Math.round(this.file.sizeInBytes / 1024)) + " KB", [isEscaped]: true }; }, + M() { return { innerHTML: (Math.round(this.file.sizeInBytes / 1048576 * 100) / 100) + " MB", [isEscaped]: true }; }, + r() { return { innerHTML: E(this.file.dimensions || "PDF"), [isEscaped]: true }; }, + g() { return { innerHTML: ((this.file.tag) ? ", " + E(this.file.tag) : ""), [isEscaped]: true }; }, + '%'() { return { innerHTML: "%", [isEscaped]: true }; } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Time = { + init() { + if (!['index', 'thread', 'archive'].includes(g.VIEW) || !Conf['Time Formatting']) { return; } + + return Callbacks.Post.push({ + name: 'Time Formatting', + cb: this.node + }); + }, + + node() { + if (!this.info.date || this.isClone) { return; } + const {textContent} = this.nodes.date; + return this.nodes.date.textContent = textContent.match(/^\s*/)[0] + Time.format(Conf['time'], this.info.date) + textContent.match(/\s*$/)[0]; + }, + + format(formatString, date) { + return formatString.replace(/%(.)/g, function(s, c) { + if ($$1.hasOwn(Time.formatters, c)) { + return Time.formatters[c].call(date); + } else { + return s; + } + }); + }, + + day: [ + 'Sunday', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday' + ], + + month: [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' + ], + + localeFormat(date, options, defaultValue) { + if (Conf['timeLocale']) { + try { + return Intl.DateTimeFormat(Conf['timeLocale'], options).format(date); + } catch (error) {} + } + return defaultValue; + }, + + localeFormatPart(date, options, part, defaultValue) { + if (Conf['timeLocale']) { + try { + const parts = Intl.DateTimeFormat(Conf['timeLocale'], options).formatToParts(date); + return parts.map(function(x) { if (x.type === part) { return x.value; } else { return ''; } }).join(''); + } catch (error) {} + } + return defaultValue; + }, + + zeroPad(n) { if (n < 10) { return `0${n}`; } else { return n; } }, + + formatters: { + a() { return Time.localeFormat(this, {weekday: 'short'}, Time.day[this.getDay()].slice(0, 3)); }, + A() { return Time.localeFormat(this, {weekday: 'long'}, Time.day[this.getDay()]); }, + b() { return Time.localeFormat(this, {month: 'short'}, Time.month[this.getMonth()].slice(0, 3)); }, + B() { return Time.localeFormat(this, {month: 'long'}, Time.month[this.getMonth()]); }, + d() { return Time.zeroPad(this.getDate()); }, + e() { return this.getDate(); }, + H() { return Time.zeroPad(this.getHours()); }, + I() { return Time.zeroPad((this.getHours() % 12) || 12); }, + k() { return this.getHours(); }, + l() { return (this.getHours() % 12) || 12; }, + m() { return Time.zeroPad(this.getMonth() + 1); }, + M() { return Time.zeroPad(this.getMinutes()); }, + p() { return Time.localeFormatPart(this, {hour: 'numeric', hour12: true}, 'dayperiod', (this.getHours() < 12 ? 'AM' : 'PM')); }, + P() { return Time.formatters.p.call(this).toLowerCase(); }, + S() { return Time.zeroPad(this.getSeconds()); }, + y() { return this.getFullYear().toString().slice(2); }, + Y() { return this.getFullYear(); }, + '%'() { return '%'; } + } + }; + + var Beep = 'UklGRjQDAABXQVZFZm10IBAAAAABAAEAgD4AAIA+AAABAAgAc21wbDwAAABBAAADAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkYXRhzAIAAGMms8em0tleMV4zIpLVo8nhfSlcPR102Ki+5JspVEkdVtKzs+K1NEhUIT7DwKrcy0g6WygsrM2k1NpiLl0zIY/WpMrjgCdbPhxw2Kq+5Z4qUkkdU9K1s+K5NkVTITzBwqnczko3WikrqM+l1NxlLF0zIIvXpsnjgydZPhxs2ay95aIrUEkdUdC3suK8N0NUIjq+xKrcz002WioppdGm091pK1w0IIjYp8jkhydXPxxq2K295aUrTkoeTs65suK+OUFUIzi7xqrb0VA0WSoootKm0t5tKlo1H4TYqMfkiydWQBxm16+85actTEseS8y7seHAPD9TIza5yKra01QyWSson9On0d5wKVk2H4DYqcfkjidUQB1j1rG75KsvSkseScu8seDCPz1TJDW2yara1FYxWSwnm9Sn0N9zKVg2H33ZqsXkkihSQR1g1bK65K0wSEsfR8i+seDEQTxUJTOzy6rY1VowWC0mmNWoz993KVc3H3rYq8TklSlRQh1d1LS647AyR0wgRMbAsN/GRDpTJTKwzKrX1l4vVy4lldWpzt97KVY4IXbUr8LZljVPRCxhw7W3z6ZISkw1VK+4sMWvXEhSPk6buay9sm5JVkZNiLWqtrJ+TldNTnquqbCwilZXU1BwpKirrpNgWFhTaZmnpquZbFlbVmWOpaOonHZcXlljhaGhpZ1+YWBdYn2cn6GdhmdhYGN3lp2enIttY2Jjco+bnJuOdGZlZXCImJqakHpoZ2Zug5WYmZJ/bGlobX6RlpeSg3BqaW16jZSVkoZ0bGtteImSk5KIeG5tbnaFkJKRinxxbm91gY2QkIt/c3BwdH6Kj4+LgnZxcXR8iI2OjIR5c3J0e4WLjYuFe3VzdHmCioyLhn52dHR5gIiKioeAeHV1eH+GiYqHgXp2dnh9hIiJh4J8eHd4fIKHiIeDfXl4eHyBhoeHhH96eHmA'; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS104: Avoid inline assignments + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ReplyPruning = { + init() { + if ((g.VIEW !== 'thread') || !Conf['Reply Pruning']) { return; } + + this.container = $$1.frag(); + + this.summary = $$1.el('span', { + hidden: true, + className: 'summary' + } + ); + this.summary.style.cursor = 'pointer'; + $$1.on(this.summary, 'click', () => { + this.inputs.enabled.checked = !this.inputs.enabled.checked; + return $$1.event('change', null, this.inputs.enabled); + }); + + const label = UI.checkbox('Prune Replies', 'Show Last', Conf['Prune All Threads']); + const el = $$1.el('span', + {title: 'Maximum number of replies to show.'} + , + {innerHTML: " "}); + $$1.prepend(el, label); + + this.inputs = { + enabled: label.firstElementChild, + replies: el.lastElementChild + }; + + this.setEnabled.call(this.inputs.enabled); + $$1.on(this.inputs.enabled, 'change', this.setEnabled); + $$1.on(this.inputs.replies, 'change', $$1.cb.value); + + Header$1.menu.addEntry({ + el, + order: 190 + }); + + return Callbacks.Thread.push({ + name: 'Reply Pruning', + cb: this.node + }); + }, + + position: 0, + hidden: 0, + hiddenFiles: 0, + total: 0, + totalFiles: 0, + + setEnabled() { + const other = QuoteThreading.input; + if (this.checked && other?.checked) { + other.checked = false; + $$1.event('change', null, other); + } + return ReplyPruning.active = this.checked; + }, + + showIfHidden(id) { + if (ReplyPruning.container && $$1(`#${id}`, ReplyPruning.container)) { + ReplyPruning.inputs.enabled.checked = false; + return $$1.event('change', null, ReplyPruning.inputs.enabled); + } + }, + + node() { + let middle; + ReplyPruning.thread = this; + + if (this.isSticky) { + ReplyPruning.active = (ReplyPruning.inputs.enabled.checked = true); + if (QuoteThreading.input) { + // Disable Quote Threading for this thread but don't save the setting. + Conf['Thread Quotes'] = (QuoteThreading.input.checked = false); + } + } + + this.posts.forEach(function(post) { + if (post.isReply) { + ReplyPruning.total++; + if (post.file) { return ReplyPruning.totalFiles++; } + } + }); + + // If we're linked to a post that we would hide, don't hide the posts in the first place. + if ( + ReplyPruning.active && + /^#p\d+$/.test(location.hash) && + (1 <= (middle = this.posts.keys.indexOf(location.hash.slice(2))) && middle < 1 + Math.max(ReplyPruning.total - +Conf["Max Replies"], 0)) + ) { + ReplyPruning.active = (ReplyPruning.inputs.enabled.checked = false); + } + + $$1.after(this.OP.nodes.root, ReplyPruning.summary); + + $$1.on(ReplyPruning.inputs.enabled, 'change', ReplyPruning.update); + $$1.on(ReplyPruning.inputs.replies, 'change', ReplyPruning.update); + $$1.on(d$1, 'ThreadUpdate', ReplyPruning.updateCount); + $$1.on(d$1, 'ThreadUpdate', ReplyPruning.update); + + return ReplyPruning.update(); + }, + + updateCount(e) { + if (e.detail[404]) { return; } + for (var fullID of e.detail.newPosts) { + ReplyPruning.total++; + if (g.posts.get(fullID).file) { ReplyPruning.totalFiles++; } + } + }, + + update() { + let boardTop, node, post; + const hidden1 = ReplyPruning.hidden; + const hidden2 = ReplyPruning.active ? + Math.max(ReplyPruning.total - +Conf["Max Replies"], 0) + : + 0; + + // Record position from bottom of document + const oldPos = d$1.body.clientHeight - window.scrollY; + + const {posts} = ReplyPruning.thread; + + if (ReplyPruning.hidden < hidden2) { + while ((ReplyPruning.hidden < hidden2) && (ReplyPruning.position < posts.keys.length)) { + post = posts.get(posts.keys[ReplyPruning.position++]); + if (post.isReply && !post.isFetchedQuote) { + while ((node = ReplyPruning.summary.nextSibling) && (node !== post.nodes.root)) { $$1.add(ReplyPruning.container, node); } + $$1.add(ReplyPruning.container, post.nodes.root); + ReplyPruning.hidden++; + if (post.file) { ReplyPruning.hiddenFiles++; } + } + } + + } else if (ReplyPruning.hidden > hidden2) { + const frag = $$1.frag(); + while ((ReplyPruning.hidden > hidden2) && (ReplyPruning.position > 0)) { + post = posts.get(posts.keys[--ReplyPruning.position]); + if (post.isReply && !post.isFetchedQuote) { + while ((node = ReplyPruning.container.lastChild) && (node !== post.nodes.root)) { $$1.prepend(frag, node); } + $$1.prepend(frag, post.nodes.root); + ReplyPruning.hidden--; + if (post.file) { ReplyPruning.hiddenFiles--; } + } + } + $$1.after(ReplyPruning.summary, frag); + $$1.event('PostsInserted', null, ReplyPruning.summary.parentNode); + } + + ReplyPruning.summary.textContent = ReplyPruning.active ? + g.SITE.Build.summaryText('+', ReplyPruning.hidden, ReplyPruning.hiddenFiles) + : + g.SITE.Build.summaryText('-', ReplyPruning.total, ReplyPruning.totalFiles); + ReplyPruning.summary.hidden = (ReplyPruning.total <= +Conf["Max Replies"]); + + // Maintain position in thread when posts are added/removed above + if ((hidden1 !== hidden2) && ((boardTop = Header$1.getTopOf($$1('.board'))) < 0)) { + return window.scrollBy(0, Math.max(d$1.body.clientHeight - oldPos, window.scrollY + boardTop) - window.scrollY); + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + /* + <3 aeosynth + */ + + var QuoteThreading = { + init() { + if (!Conf['Quote Threading'] || (g.VIEW !== 'thread')) { return; } + + this.controls = $$1.el('label', + {innerHTML: " Threading"}); + + this.threadNewLink = $$1.el('span', { + className: 'brackets-wrap threadnewlink', + hidden: true + } + ); + $$1.extend(this.threadNewLink, {innerHTML: "Thread New Posts"}); + + this.input = $$1('input', this.controls); + this.input.checked = Conf['Thread Quotes']; + + $$1.on(this.input, 'change', this.setEnabled); + $$1.on(this.input, 'change', this.rethread); + $$1.on(this.threadNewLink.firstElementChild, 'click', this.rethread); + $$1.on(d$1, '4chanXInitFinished', () => { return this.ready = true; }); + + Header$1.menu.addEntry(this.entry = { + el: this.controls, + order: 99 + } + ); + + Callbacks.Thread.push({ + name: 'Quote Threading', + cb: this.setThread + }); + + return Callbacks.Post.push({ + name: 'Quote Threading', + cb: this.node + }); + }, + + parent: dict(), + children: dict(), + inserted: dict(), + + toggleThreading() { + return this.setThreadingState(!Conf['Thread Quotes']); + }, + + setThreadingState(enabled) { + this.input.checked = enabled; + this.setEnabled.call(this.input); + return this.rethread.call(this.input); + }, + + setEnabled() { + if (this.checked) { + $$1.set('Prune All Threads', false); + const other = ReplyPruning.inputs?.enabled; + if (other?.checked) { + other.checked = false; + $$1.event('change', null, other); + } + } + return $$1.cb.checked.call(this); + }, + + setThread() { + QuoteThreading.thread = this; + return $$1.asap((() => !Conf['Thread Updater'] || $$1('.navLinksBot > .updatelink')), function() { + let navLinksBot; + if (navLinksBot = $$1('.navLinksBot')) { return $$1.add(navLinksBot, [$$1.tn(' '), QuoteThreading.threadNewLink]); } + }); + }, + + node() { + let parent; + if (this.isFetchedQuote || this.isClone || !this.isReply) { return; } + + const parents = new Set(); + let lastParent = null; + for (var quote of this.quotes) { + if ((parent = g.posts.get(quote))) { + if (!parent.isFetchedQuote && parent.isReply && (parent.ID < this.ID)) { + parents.add(parent.ID); + if (!lastParent || (parent.ID > lastParent.ID)) { lastParent = parent; } + } + } + } + + if (!lastParent) { return; } + + let ancestor = lastParent; + while ((ancestor = QuoteThreading.parent[ancestor.fullID])) { + parents.delete(ancestor.ID); + } + + if (parents.size === 1) { + return QuoteThreading.parent[this.fullID] = lastParent; + } + }, + + descendants(post) { + let children; + let posts = [post]; + if (children = QuoteThreading.children[post.fullID]) { + for (var child of children) { + posts = posts.concat(QuoteThreading.descendants(child)); + } + } + return posts; + }, + + insert(post) { + let parent, x; + if (!( + Conf['Thread Quotes'] && + (parent = QuoteThreading.parent[post.fullID]) && + !QuoteThreading.inserted[post.fullID] + )) { return false; } + + const descendants = QuoteThreading.descendants(post); + if (!Unread.posts.has(parent.ID)) { + if ((function() { for (var x of descendants) { if (Unread.posts.has(x.ID)) { return true; } } })()) { + QuoteThreading.threadNewLink.hidden = false; + return false; + } + } + + const {order} = Unread; + const children = (QuoteThreading.children[parent.fullID] || (QuoteThreading.children[parent.fullID] = [])); + const threadContainer = parent.nodes.threadContainer || $$1.el('div', {className: 'threadContainer'}); + const nodes = [post.nodes.root]; + if (post.nodes.threadContainer) { nodes.push(post.nodes.threadContainer); } + + let i = children.length; + for (let j = children.length - 1; j >= 0; j--) { var child = children[j]; if (child.ID >= post.ID) { i--; } } + if (i !== children.length) { + const next = children[i]; + for (x of descendants) { order.before(order[next.ID], order[x.ID]); } + children.splice(i, 0, post); + $$1.before(next.nodes.root, nodes); + } else { + let prev2; + let prev = parent; + while ((prev2 = QuoteThreading.children[prev.fullID]) && prev2.length) { + prev = prev2[prev2.length-1]; + } + for (let k = descendants.length - 1; k >= 0; k--) { x = descendants[k]; order.after(order[prev.ID], order[x.ID]); } + children.push(post); + $$1.add(threadContainer, nodes); + } + + QuoteThreading.inserted[post.fullID] = true; + + if (!parent.nodes.threadContainer) { + parent.nodes.threadContainer = threadContainer; + $$1.addClass(parent.nodes.root, 'threadOP'); + $$1.after(parent.nodes.root, threadContainer); + } + + return true; + }, + + rethread() { + if (!QuoteThreading.ready) { return; } + const {thread} = QuoteThreading; + const {posts} = thread; + + QuoteThreading.threadNewLink.hidden = true; + + if (Conf['Thread Quotes']) { + posts.forEach(QuoteThreading.insert); + } else { + const nodes = []; + Unread.order = new RandomAccessList(); + QuoteThreading.inserted = dict(); + posts.forEach(function(post) { + if (post.isFetchedQuote) { return; } + Unread.order.push(post); + if (post.isReply) { nodes.push(post.nodes.root); } + if (QuoteThreading.children[post.fullID]) { + delete QuoteThreading.children[post.fullID]; + $$1.rmClass(post.nodes.root, 'threadOP'); + $$1.rm(post.nodes.threadContainer); + return delete post.nodes.threadContainer; + } + }); + $$1.add(thread.nodes.root, nodes); + } + + Unread.position = Unread.order.first; + Unread.updatePosition(); + Unread.setLine(true); + Unread.read(); + return Unread.update(); + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS201: Simplify complex destructure assignments + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var ThreadUpdater = { + init() { + let el, name, sc; + if ((g.VIEW !== 'thread') || !Conf['Thread Updater']) { return; } + this.enabled = true; + + // Chromium won't play audio created in an inactive tab until the tab has been focused, so set it up now. + // XXX Sometimes the loading stalls in Firefox, esp. when opening in private browsing window followed by normal window. + // Don't let it keep the loading icon on indefinitely. + this.audio = $$1.el('audio'); + if ($$1.engine !== 'gecko') { this.audio.src = this.beep; } + + if (Conf['Updater and Stats in Header']) { + this.dialog = (sc = $$1.el('span', + {id: 'updater'})); + $$1.extend(sc, {innerHTML: ''}); + Header$1.addShortcut('updater', sc, 100); + } else { + this.dialog = (sc = UI.dialog('updater', + {innerHTML: '
        '})); + $$1.addClass(doc$1, 'float'); + $$1.ready(() => $$1.add(d$1.body, sc)); + } + + this.checkPostCount = 0; + + this.timer = $$1('#update-timer', sc); + this.status = $$1('#update-status', sc); + + $$1.on(this.timer, 'click', this.update); + $$1.on(this.status, 'click', this.update); + + const updateLink = $$1.el('span', + {className: 'brackets-wrap updatelink'}); + $$1.extend(updateLink, {innerHTML: 'Update'}); + Main$1.ready(function() { + let navLinksBot; + if (navLinksBot = $$1('.navLinksBot')) { return $$1.add(navLinksBot, [$$1.tn(' '), updateLink]); } + }); + $$1.on(updateLink.firstElementChild, 'click', this.update); + + const subEntries = []; + for (name in Config.updater.checkbox) { + var conf = Config.updater.checkbox[name]; + el = UI.checkbox(name, name); + el.title = conf[1]; + var input = el.firstElementChild; + $$1.on(input, 'change', $$1.cb.checked); + if (input.name === 'Scroll BG') { + $$1.on(input, 'change', this.cb.scrollBG); + this.cb.scrollBG(); + } else if (input.name === 'Auto Update') { + $$1.on(input, 'change', this.setInterval); + } + subEntries.push({el}); + } + + this.settings = $$1.el('span', + {innerHTML: 'Interval'}); + + $$1.on(this.settings, 'click', this.intervalShortcut); + + subEntries.push({el: this.settings}); + + Header$1.menu.addEntry(this.entry = { + el: $$1.el('span', + {textContent: 'Updater'}), + order: 110, + subEntries + } + ); + + return Callbacks.Thread.push({ + name: 'Thread Updater', + cb: this.node + }); + }, + + node() { + ThreadUpdater.thread = this; + ThreadUpdater.root = this.nodes.root; + ThreadUpdater.outdateCount = 0; + + // We must keep track of our own list of live posts/files + // to provide an accurate deletedPosts/deletedFiles on update + // as posts may be `kill`ed elsewhere. + ThreadUpdater.postIDs = []; + ThreadUpdater.fileIDs = []; + this.posts.forEach(function(post) { + ThreadUpdater.postIDs.push(post.ID); + if (post.file) { return ThreadUpdater.fileIDs.push(post.ID); } + }); + + ThreadUpdater.cb.interval.call($$1.el('input', {value: Conf['Interval']})); + + $$1.on(d$1, 'QRPostSuccessful', ThreadUpdater.cb.checkpost); + $$1.on(d$1, 'visibilitychange', ThreadUpdater.cb.visibility); + + return ThreadUpdater.setInterval(); + }, + + /* + http://freesound.org/people/pierrecartoons1979/sounds/90112/ + cc-by-nc-3.0 + */ + beep: `data:audio/wav;base64,${Beep}`, + + playBeep() { + const {audio} = ThreadUpdater; + if (!audio.src) { audio.src = ThreadUpdater.beep; } + if (audio.paused) { + return audio.play(); + } else { + return $$1.one(audio, 'ended', ThreadUpdater.playBeep); + } + }, + + cb: { + checkpost(e) { + if (e.detail.threadID !== ThreadUpdater.thread.ID) { return; } + ThreadUpdater.postID = e.detail.postID; + ThreadUpdater.checkPostCount = 0; + ThreadUpdater.outdateCount = 0; + return ThreadUpdater.setInterval(); + }, + + visibility() { + if (d$1.hidden) { return; } + // Reset the counter when we focus this tab. + ThreadUpdater.outdateCount = 0; + if (ThreadUpdater.seconds > ThreadUpdater.interval) { + return ThreadUpdater.setInterval(); + } + }, + + scrollBG() { + return ThreadUpdater.scrollBG = Conf['Scroll BG'] ? + () => true + : + () => !d$1.hidden; + }, + + interval(e) { + let val = parseInt(this.value, 10); + if (val < 1) { val = 1; } + ThreadUpdater.interval = (this.value = val); + if (e) { return $$1.cb.value.call(this); } + }, + + load() { + if (this !== ThreadUpdater.req) { return; } // aborted + switch (this.status) { + case 200: + ThreadUpdater.parse(this); + if (ThreadUpdater.thread.isArchived) { + return ThreadUpdater.kill(); + } else { + return ThreadUpdater.setInterval(); + } + case 404: + // XXX workaround for 4chan sending false 404s + return $$1.ajax(g.SITE.urls.catalogJSON({boardID: ThreadUpdater.thread.board.ID}), { onloadend() { + let confirmed; + if (this.status === 200) { + confirmed = true; + for (var page of this.response) { + for (var thread of page.threads) { + if (thread.no === ThreadUpdater.thread.ID) { + confirmed = false; + break; + } + } + } + } else { + confirmed = false; + } + if (confirmed) { + return ThreadUpdater.kill(); + } else { + return ThreadUpdater.error(this); + } + } + } + ); + default: + return ThreadUpdater.error(this); + } + } + }, + + kill() { + ThreadUpdater.thread.kill(); + ThreadUpdater.setInterval(); + return $$1.event('ThreadUpdate', { + 404: true, + threadID: ThreadUpdater.thread.fullID + } + ); + }, + + error(req) { + if (req.status === 304) { + ThreadUpdater.set('status', ''); + } + ThreadUpdater.setInterval(); + if (!req.status) { + return ThreadUpdater.set('status', 'Connection Error', 'warning'); + } else if (req.status !== 304) { + return ThreadUpdater.set('status', `${req.statusText} (${req.status})`, 'warning'); + } + }, + + setInterval() { + clearTimeout(ThreadUpdater.timeoutID); + + if (ThreadUpdater.thread.isDead) { + ThreadUpdater.set('status', (ThreadUpdater.thread.isArchived ? 'Archived' : '404'), 'warning'); + ThreadUpdater.set('timer', ''); + return; + } + + // Fetching your own posts after posting + if (ThreadUpdater.postID && (ThreadUpdater.checkPostCount < 5)) { + ThreadUpdater.set('timer', '...', 'loading'); + ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * SECOND); + return; + } + + if (!Conf['Auto Update']) { + ThreadUpdater.set('timer', 'Update'); + return; + } + + const {interval} = ThreadUpdater; + if (Conf['Optional Increase']) { + // Lower the max refresh rate limit on visible tabs. + const limit = d$1.hidden ? 10 : 5; + const j = Math.min(ThreadUpdater.outdateCount, limit); + + // 1 second to 100, 30 to 300. + const cur = (Math.floor(interval * 0.1) || 1) * j * j; + ThreadUpdater.seconds = $$1.minmax(cur, interval, 300); + } else { + ThreadUpdater.seconds = interval; + } + + return ThreadUpdater.timeout(); + }, + + intervalShortcut() { + Settings.open('Advanced'); + const settings = $$1.id('fourchanx-settings'); + return $$1('input[name=Interval]', settings).focus(); + }, + + set(name, text, klass) { + let node; + const el = ThreadUpdater[name]; + if ((node = el.firstChild)) { + // Prevent the creation of a new DOM Node + // by setting the text node's data. + node.data = text; + } else { + el.textContent = text; + } + return el.className = klass ?? (text === '' ? 'empty' : ''); + }, + + timeout() { + if (ThreadUpdater.seconds) { + ThreadUpdater.set('timer', ThreadUpdater.seconds); + ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000); + } else { + ThreadUpdater.outdateCount++; + ThreadUpdater.update(); + } + return ThreadUpdater.seconds--; + }, + + update() { + let oldReq; + clearTimeout(ThreadUpdater.timeoutID); + ThreadUpdater.set('timer', '...', 'loading'); + if (oldReq = ThreadUpdater.req) { + delete ThreadUpdater.req; + oldReq.abort(); + } + return ThreadUpdater.req = $$1.whenModified( + g.SITE.urls.threadJSON({boardID: ThreadUpdater.thread.board.ID, threadID: ThreadUpdater.thread.ID}), + 'ThreadUpdater', + ThreadUpdater.cb.load, + { timeout: MINUTE } + ); + }, + + updateThreadStatus(type, status) { + if (!(ThreadUpdater.thread[`is${type}`] !== status)) { return; } + ThreadUpdater.thread.setStatus(type, status); + if ((type === 'Closed') && ThreadUpdater.thread.isArchived) { return; } + const change = type === 'Sticky' ? + status ? + 'now a sticky' + : + 'not a sticky anymore' + : + status ? + 'now closed' + : + 'not closed anymore'; + return new Notice('info', `The thread is ${change}.`, 30); + }, + + parse(req) { + let ID, ipCountEl, post; + const postObjects = req.response.posts; + const OP = postObjects[0]; + const {thread} = ThreadUpdater; + const {board} = thread; + const lastPost = ThreadUpdater.postIDs[ThreadUpdater.postIDs.length - 1]; + + // XXX Reject updates that falsely delete the last post. + if ((postObjects[postObjects.length-1].no < lastPost) && + ((new Date(req.getResponseHeader('Last-Modified')) - thread.posts.get(lastPost).info.date) < (30 * SECOND))) { return; } + + g.SITE.Build.spoilerRange[board] = OP.custom_spoiler; + thread.setStatus('Archived', !!OP.archived); + ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky); + ThreadUpdater.updateThreadStatus('Closed', !!OP.closed); + thread.postLimit = !!OP.bumplimit; + thread.fileLimit = !!OP.imagelimit; + if (OP.unique_ips != null) { thread.ipCount = OP.unique_ips; } + + const posts = []; // new post objects + const index = []; // existing posts + const files = []; // existing files + const newPosts = []; // new post fullID list for API + + // Build the index, create posts. + for (var postObject of postObjects) { + ID = postObject.no; + index.push(ID); + if (postObject.fsize) { files.push(ID); } + + // Insert new posts, not older ones. + if (ID <= lastPost) { continue; } + + // XXX Resurrect wrongly deleted posts. + if ((post = thread.posts.get(ID)) && !post.isFetchedQuote) { + post.resurrect(); + continue; + } + + newPosts.push(`${board}.${ID}`); + var node = g.SITE.Build.postFromObject(postObject, board.ID); + posts.push(new Post(node, thread, board)); + // Fetching your own posts after posting + if (ThreadUpdater.postID === ID) { delete ThreadUpdater.postID; } + } + + // Check for deleted posts. + const deletedPosts = []; + for (ID of ThreadUpdater.postIDs) { + if (!index.includes(ID)) { + thread.posts.get(ID).kill(); + deletedPosts.push(`${board}.${ID}`); + } + } + ThreadUpdater.postIDs = index; + + // Check for deleted files. + const deletedFiles = []; + for (ID of ThreadUpdater.fileIDs) { + if (!(files.includes(ID) || deletedPosts.includes(`${board}.${ID}`))) { + thread.posts.get(ID).kill(true); + deletedFiles.push(`${board}.${ID}`); + } + } + ThreadUpdater.fileIDs = files; + + if (!posts.length) { + ThreadUpdater.set('status', ''); + } else { + ThreadUpdater.set('status', `+${posts.length}`, 'new'); + ThreadUpdater.outdateCount = 0; + + const unreadCount = Unread.posts?.size; + const unreadQYCount = Unread.postsQuotingYou?.size; + + Main$1.callbackNodes('Post', posts); + + if (d$1.hidden || !d$1.hasFocus()) { + if (Conf['Beep Quoting You'] && (Unread.postsQuotingYou?.size > unreadQYCount)) { + ThreadUpdater.playBeep(); + if (Conf['Beep']) { ThreadUpdater.playBeep(); } + } else if (Conf['Beep'] && (Unread.posts?.size > 0) && (unreadCount === 0)) { + ThreadUpdater.playBeep(); + } + } + + const scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && + ((ThreadUpdater.root.getBoundingClientRect().bottom - doc$1.clientHeight) < 25); + + let firstPost = null; + for (post of posts) { + if (!QuoteThreading.insert(post)) { + if (!firstPost) { firstPost = post.nodes.root; } + $$1.add(ThreadUpdater.root, post.nodes.root); + } + } + $$1.event('PostsInserted', null, ThreadUpdater.root); + + if (scroll) { + if (Conf['Bottom Scroll']) { + window.scrollTo(0, d$1.body.clientHeight); + } else { + if (firstPost) { Header$1.scrollTo(firstPost); } + } + } + } + + // Update IP count in original post form. + if ((OP.unique_ips != null) && (ipCountEl = $$1.id('unique-ips'))) { + ipCountEl.textContent = OP.unique_ips; + ipCountEl.previousSibling.textContent = ipCountEl.previousSibling.textContent.replace(/\b(?:is|are)\b/, OP.unique_ips === 1 ? 'is' : 'are'); + ipCountEl.nextSibling.textContent = ipCountEl.nextSibling.textContent.replace(/\bposters?\b/, OP.unique_ips === 1 ? 'poster' : 'posters'); + } + + return $$1.event('ThreadUpdate', { + 404: false, + threadID: thread.fullID, + newPosts, + deletedPosts, + deletedFiles, + postCount: OP.replies + 1, + fileCount: OP.images + !!OP.fsize, + ipCount: OP.unique_ips + } + ); + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Settings = { + dialog: undefined, + init() { + // 4chan X settings link + const link = $$1.el('a', { + className: 'settings-link', + textContent: '🔧︎', + title: `${meta.name} Settings`, + href: 'javascript:;' + }); + $$1.on(link, 'click', Settings.open); + Header$1.addShortcut('settings', link, 820); + const add = this.addSection; + add('Main', this.main); + add('Filter', this.filter); + add('Sauce', this.sauce); + add('Advanced', this.advanced); + add('Keybinds', this.keybinds); + $$1.on(d$1, 'AddSettingsSection', Settings.addSection); + $$1.on(d$1, 'OpenSettings', e => Settings.open(e.detail)); + if ((g.SITE.software === 'yotsuba') && Conf['Disable Native Extension']) { + if ($$1.hasStorage) { + // Run in page context to handle case where 4chan X has localStorage access but not the page. + // (e.g. Pale Moon 26.2.2, GM 3.8, cookies disabled for 4chan only) + return $$1.global(function () { + try { + const settings = JSON.parse(localStorage.getItem('4chan-settings')) || {}; + if (settings.disableAll) { + return; + } + settings.disableAll = true; + return localStorage.setItem('4chan-settings', JSON.stringify(settings)); + } + catch (error) { + return Object.defineProperty(window, 'Config', { value: { disableAll: true } }); + } + }); + } + else { + return $$1.global(() => Object.defineProperty(window, 'Config', { value: { disableAll: true } })); + } + } + }, + open(openSection) { + let dialog, sectionToOpen; + if (Settings.dialog) { + return; + } + $$1.event('CloseMenu'); + Settings.dialog = (dialog = $$1.el('div', { id: 'overlay' }, settingsHtml)); + $$1.on($$1('.export', dialog), 'click', Settings.export); + $$1.on($$1('.import', dialog), 'click', Settings.import); + $$1.on($$1('.reset', dialog), 'click', Settings.reset); + $$1.on($$1('input', dialog), 'change', Settings.onImport); + const links = []; + for (var section of Settings.sections) { + var link = $$1.el('a', { + className: `tab-${section.hyphenatedTitle}`, + textContent: section.title, + href: 'javascript:;' + }); + $$1.on(link, 'click', Settings.openSection.bind(section)); + links.push(link, $$1.tn(' | ')); + if (section.title === openSection) { + sectionToOpen = link; + } + } + links.pop(); + $$1.add($$1('.sections-list', dialog), links); + if (openSection !== 'none') { + (sectionToOpen ? sectionToOpen : links[0]).click(); + } + $$1.on($$1('.close', dialog), 'click', Settings.close); + $$1.on(window, 'beforeunload', Settings.close); + $$1.on(dialog, 'click', Settings.close); + $$1.on(dialog.firstElementChild, 'click', e => e.stopPropagation()); + $$1.add(d$1.body, dialog); + return $$1.event('OpenSettings', null, dialog); + }, + close() { + if (!Settings.dialog) { + return; + } + // Unfocus current field to trigger change event. + d$1.activeElement?.blur(); + $$1.rm(Settings.dialog); + return delete Settings.dialog; + }, + sections: [], + addSection(title, open) { + if (typeof title !== 'string') { + ({ title, open } = title.detail); + } + const hyphenatedTitle = title.toLowerCase().replace(/\s+/g, '-'); + return Settings.sections.push({ title, hyphenatedTitle, open }); + }, + openSection() { + let selected; + if (selected = $$1('.tab-selected', Settings.dialog)) { + $$1.rmClass(selected, 'tab-selected'); + } + $$1.addClass($$1(`.tab-${this.hyphenatedTitle}`, Settings.dialog), 'tab-selected'); + const section = $$1('section', Settings.dialog); + $$1.rmAll(section); + section.className = `section-${this.hyphenatedTitle}`; + this.open(section, g); + section.scrollTop = 0; + return $$1.event('OpenSettings', null, section); + }, + warnings: { + localStorage(cb) { + if ($$1.cantSync) { + const why = $$1.cantSet ? 'save your settings' : 'synchronize settings between tabs'; + return cb($$1.el('li', { + textContent: `\ +${meta.name} needs local storage to ${why}. +Enable 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(cb) { + return $$1.onExists(doc$1, '.adg-rects > .desktop', ad => $$1.onExists(ad, 'iframe', function () { + const url = Redirect$1.to('thread', { boardID: 'qa', threadID: 362590 }); + return cb($$1.el('li', h(hFragment, null, + "To protect yourself from ", + h("a", { href: url, target: "_blank" }, "malicious ads"), + ", you should ", + h("a", { href: "https://github.com/gorhill/uBlock#ublock-origin", target: "_blank" }, "block ads"), + " on 4chan."))); + })); + } + }, + main(section) { + let key; + const warnings = $$1.el('fieldset', { hidden: true }, { innerHTML: 'Warnings
          ' }); + const addWarning = function (item) { + $$1.add($$1('ul', warnings), item); + return warnings.hidden = false; + }; + for (key in Settings.warnings) { + var warning = Settings.warnings[key]; + warning(addWarning); + } + $$1.add(section, warnings); + const items = dict(); + const inputs = dict(); + const addCheckboxes = function (root, obj) { + const containers = [root]; + return (() => { + const result = []; + for (key in obj) { + var arr = obj[key]; + if (arr instanceof Array) { + var description = arr[1]; + var div = $$1.el('div', { innerHTML: `: ${description}` }); + div.dataset.name = key; + var input = $$1('input', div); + $$1.on(input, 'change', $$1.cb.checked); + $$1.on(input, 'change', function () { return this.parentNode.parentNode.dataset.checked = this.checked; }); + items[key] = Conf[key]; + inputs[key] = input; + var level = arr[2] || 0; + if (containers.length <= level) { + var container = $$1.el('div', { className: 'suboption-list' }); + $$1.add(containers[containers.length - 1].lastElementChild, container); + containers[level] = container; + } + else if (containers.length > (level + 1)) { + containers.splice(level + 1, containers.length - (level + 1)); + } + result.push($$1.add(containers[level], div)); + } + } + return result; + })(); + }; + for (var keyFS in Config.main) { + var obj = Config.main[keyFS]; + var fs = $$1.el('fieldset', { innerHTML: `${keyFS}` }); + addCheckboxes(fs, obj); + if (keyFS === 'Posting and Captchas') { + $$1.add(fs, $$1.el('p', { innerHTML: 'For more info on captcha options and issues, see the captcha FAQ.' })); + } + $$1.add(section, fs); + } + addCheckboxes($$1('div[data-name="JSON Index"] > .suboption-list', section), Config.Index); + // Unsupported options + if ($$1.engine !== 'gecko') { + $$1('div[data-name="Remember QR Size"]', section).hidden = true; + } + if ($$1.perProtocolSettings || (location.protocol !== 'https:')) { + $$1('div[data-name="Redirect to HTTPS"]', section).hidden = true; + } + if (platform !== 'crx') { + $$1('div[data-name="Work around CORB Bug"]', section).hidden = true; + } + $$1.get(items, function (items) { + for (key in items) { + var val = items[key]; + inputs[key].checked = val; + inputs[key].parentNode.parentNode.dataset.checked = val; + } + }); + const div = $$1.el('div', { innerHTML: ': Clear manually-hidden threads and posts on all boards. Reload the page to apply.' }); + const button = $$1('button', div); + $$1.get({ hiddenThreads: dict(), hiddenPosts: dict() }, function ({ hiddenThreads, hiddenPosts }) { + let board, ID, site, thread; + let hiddenNum = 0; + for (ID in hiddenThreads) { + site = hiddenThreads[ID]; + if (ID !== 'boards') { + for (ID in site.boards) { + board = site.boards[ID]; + hiddenNum += Object.keys(board).length; + } + } + } + for (ID in hiddenThreads.boards) { + board = hiddenThreads.boards[ID]; + hiddenNum += Object.keys(board).length; + } + for (ID in hiddenPosts) { + site = hiddenPosts[ID]; + if (ID !== 'boards') { + for (ID in site.boards) { + board = site.boards[ID]; + for (ID in board) { + thread = board[ID]; + hiddenNum += Object.keys(thread).length; + } + } + } + } + for (ID in hiddenPosts.boards) { + board = hiddenPosts.boards[ID]; + for (ID in board) { + thread = board[ID]; + hiddenNum += Object.keys(thread).length; + } + } + return button.textContent = `Hidden: ${hiddenNum}`; + }); + $$1.on(button, 'click', function () { + this.textContent = 'Hidden: 0'; + return $$1.get('hiddenThreads', dict(), function ({ hiddenThreads }) { + if ($$1.hasStorage && (g.SITE.software === 'yotsuba')) { + let boardID; + for (boardID in hiddenThreads['4chan.org']?.boards) { + localStorage.removeItem(`4chan-hide-t-${boardID}`); + } + for (boardID in hiddenThreads.boards) { + localStorage.removeItem(`4chan-hide-t-${boardID}`); + } + } + return ($$1.delete(['hiddenThreads', 'hiddenPosts'])); + }); + }); + return $$1.after($$1('input[name="Stubs"]', section).parentNode.parentNode, div); + }, + export() { + // Make sure to export the most recent data, but don't overwrite existing `Conf` object. + const Conf2 = dict(); + $$1.extend(Conf2, Conf); + return $$1.get(Conf2, function (Conf2) { + // Don't export cached JSON data. + delete Conf2['boardConfig']; + return (Settings.downloadExport({ version: g.VERSION, date: Date.now(), Conf: Conf2 })); + }); + }, + downloadExport(data) { + const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); + const url = URL.createObjectURL(blob); + const a = $$1.el('a', { + download: `${meta.name} v${g.VERSION}-${data.date}.json`, + href: url + }); + const p = $$1('.imp-exp-result', Settings.dialog); + $$1.rmAll(p); + $$1.add(p, a); + return a.click(); + }, + import() { + return $$1('input[type=file]', this.parentNode).click(); + }, + onImport() { + let file; + if (!(file = this.files[0])) { + return; + } + this.value = null; + const output = $$1('.imp-exp-result'); + if (!confirm('Your current settings will be entirely overwritten, are you sure?')) { + output.textContent = 'Import aborted.'; + return; + } + const reader = new FileReader(); + reader.onload = function (e) { + try { + return Settings.loadSettings(dict.json(e.target.result), function (err) { + if (err) { + return output.textContent = 'Import failed due to an error.'; + } + else if (confirm('Import successful. Reload now?')) { + return window.location.reload(); + } + }); + } + catch (error) { + const err = error; + output.textContent = 'Import failed due to an error.'; + return c.error(err.stack); + } + }; + return reader.readAsText(file); + }, + convertFrom: { + loadletter(data) { + const convertSettings = function (data, map) { + for (var prevKey in map) { + var newKey = map[prevKey]; + if (newKey) { + data.Conf[newKey] = data.Conf[prevKey]; + } + delete data.Conf[prevKey]; + } + return data; + }; + data = convertSettings(data, { + // General confs + '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', + // filter + 'uniqueid': 'uniqueID', + 'mod': 'capcode', + 'email': '', + 'country': 'flag', + 'md5': 'MD5', + // keybinds + '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', + // updater + 'Scrolling': 'Auto Scroll', + 'Verbose': '' + }); + if ('Always CDN' in data.Conf) { + data.Conf['fourchanImageHost'] = data.Conf['Always CDN'] ? 'i.4cdn.org' : ''; + delete data.Conf['Always CDN']; + } + data.Conf.sauces = data.Conf.sauces.replace(/\$\d/g, function (c) { + switch (c) { + case '$1': + return '%TURL'; + case '$2': + return '%URL'; + case '$3': + return '%MD5'; + case '$4': + return '%board'; + default: + return c; + } + }); + for (var key in Config.hotkeys) { + Config.hotkeys[key]; + if (key in data.Conf) { + data.Conf[key] = data.Conf[key].replace(/ctrl|alt|meta/g, s => `${s[0].toUpperCase()}${s.slice(1)}`).replace(/(^|.+\+)[A-Z]$/g, s => `Shift+${s.slice(0, -1)}${s.slice(-1).toLowerCase()}`); + } + } + if (data.WatchedThreads) { + data.Conf['watchedThreads'] = dict.clone({ '4chan.org': { boards: {} } }); + for (var boardID in data.WatchedThreads) { + var threads = data.WatchedThreads[boardID]; + for (var threadID in threads) { + var threadData = threads[threadID]; + (data.Conf['watchedThreads']['4chan.org'].boards[boardID] || (data.Conf['watchedThreads']['4chan.org'].boards[boardID] = dict()))[threadID] = { excerpt: threadData.textContent }; + } + } + } + return data; + } + }, + upgrade(data, version) { + let corrupted, key, val; + const changes = dict(); + const set = (key, value) => data[key] = (changes[key] = value); + const setD = function (key, value) { + if (data[key] == null) { + return set(key, value); + } + }; + const addSauces = function (sauces) { + if (data['sauces'] != null) { + sauces = sauces.filter(s => data['sauces'].indexOf(s.match(/[^#;\s]+|$/)[0]) < 0); + if (sauces.length) { + return set('sauces', data['sauces'] + '\n\n' + sauces.join('\n')); + } + } + }; + const addCSS = function (css) { + if (data['usercss'] == null) { + set('usercss', Config['usercss']); + } + if (data['usercss'].indexOf(css) < 0) { + return set('usercss', css + '\n\n' + data['usercss']); + } + }; + // XXX https://github.com/greasemonkey/greasemonkey/issues/2600 + if (corrupted = (version[0] === '"')) { + try { + version = JSON.parse(version); + } + catch (error) { } + } + const compareString = version.replace(/\d+/g, x => ('0000' + x).slice(-5)); + if (compareString < '00001.00013.00014.00008') { + for (key in data) { + val = data[key]; + if ((typeof val === 'string') && (typeof Conf[key] !== 'string') && !['Index Sort', 'Last Long Reply Thresholds 0', 'Last Long Reply Thresholds 1'].includes(key)) { + corrupted = true; + break; + } + } + } + if (corrupted) { + for (key in data) { + val = data[key]; + if (typeof val === 'string') { + try { + var val2 = JSON.parse(val); + set(key, val2); + } + catch (error1) { } + } + } + } + if (compareString < '00001.00011.00008.00000') { + if (data['Fixed Thread Watcher'] == null) { + set('Fixed Thread Watcher', data['Toggleable Thread Watcher'] ?? true); + } + if (data['Exempt Archives from Encryption'] == null) { + set('Exempt Archives from Encryption', data['Except Archives from Encryption'] ?? false); + } + } + if (compareString < '00001.00011.00010.00001') { + if (data['selectedArchives'] != null) { + const uids = { "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 boardID in data['selectedArchives']) { + var record = data['selectedArchives'][boardID]; + for (var type in record) { + var name = record[type]; + if ($$1.hasOwn(uids, name)) { + record[type] = uids[name]; + } + } + } + set('selectedArchives', data['selectedArchives']); + } + } + if (compareString < '00001.00011.00016.00000') { + let rice; + if (rice = Config['usercss'].match(/\/\* Board title rice \*\/(?:\n.+)*/)[0]) { + if ((data['usercss'] != null) && (data['usercss'].indexOf(rice) < 0)) { + set('usercss', rice + '\n\n' + data['usercss']); + } + } + } + if (compareString < '00001.00011.00017.00000') { + for (key of ['Persistent QR', 'Color User IDs', 'Fappe Tyme', 'Werk Tyme', 'Highlight Posts Quoting You', 'Highlight Own Posts']) { + if (data[key] == null) { + set(key, (key === 'Persistent QR')); + } + } + } + if (compareString < '00001.00011.00017.00006') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/iqdb\.org\//mg, '$1//iqdb.org/')); + } + } + if ((compareString < '00001.00011.00019.00003') && !Settings.dialog) { + $$1.queueTask(() => Settings.warnings.ads(item => new Notice('warning', [...Array.from(item.childNodes)]))); + } + if (compareString < '00001.00011.00020.00003') { + const object = { 'Inline Cross-thread Quotes Only': false, 'Pass Link': true }; + for (key in object) { + var value = object[key]; + if (data[key] == null) { + set(key, value); + } + } + } + if (compareString < '00001.00011.00021.00003') { + if (data['Remember Your Posts'] == null) { + set('Remember Your Posts', data['Mark Quotes of You'] ?? true); + } + } + if (compareString < '00001.00011.00022.00000') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(?:IMG|URL))%3Fs\.jpg/mg, '$1')); + set('sauces', data['sauces'].replace(/^#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(?:IMG|T?URL)(?=$|;)/mg, '$&&safe=off')); + } + } + if (compareString < '00001.00011.00022.00002') { + if ((data['Use Recaptcha v1 in Reports'] == null) && data['Use Recaptcha v1'] && !data['Use Recaptcha v2 in Reports']) { + set('Use Recaptcha v1 in Reports', true); + } + } + if (compareString < '00001.00011.00024.00000') { + if ((data['JSON Navigation'] != null) && (data['JSON Index'] == null)) { + set('JSON Index', data['JSON Navigation']); + } + } + if (compareString < '00001.00011.00026.00000') { + if ((data['Oekaki Links'] != null) && (data['Edit Link'] == null)) { + set('Edit Link', data['Oekaki Links']); + } + if (data['Inline Cross-thread Quotes Only'] == null) { + set('Inline Cross-thread Quotes Only', true); + } + } + if (compareString < '00001.00011.00030.00000') { + if (data['Quote Threading'] && (data['Thread Quotes'] == null)) { + set('Thread Quotes', true); + } + } + if (compareString < '00001.00011.00032.00000') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/3d\.iqdb\.org\//mg, '$1//3d.iqdb.org/')); + } + addSauces([ + '#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' + ]); + } + if (compareString < '00001.00011.00035.00000') { + addSauces(['https://whatanime.ga/?auto&url=%IMG;text:wait']); + } + if (compareString < '00001.00012.00000.00000') { + if (data['Exempt Archives from Encryption'] == null) { + set('Exempt Archives from Encryption', false); + } + if (data['Show New Thread Option in Threads'] == null) { + set('Show New Thread Option in Threads', false); + } + if (data['Show Name and Subject']) { + addCSS('#qr .persona .field {display: block !important;}'); + } + if (data['QR Shortcut'] === false) { + addCSS('#shortcut-qr {display: none;}'); + } + if (data['Bottom QR Link'] === false) { + addCSS('.qr-link-container-bottom {display: none;}'); + } + } + if (compareString < '00001.00012.00000.00006') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*)https:\/\/(?:desustorage|cuckchan)\.org\//mg, '$1https://desuarchive.org/')); + } + } + if (compareString < '00001.00012.00001.00000') { + if ((data['Persistent Thread Watcher'] == null) && (data['Toggleable Thread Watcher'] != null)) { + set('Persistent Thread Watcher', !data['Toggleable Thread Watcher']); + } + } + if (compareString < '00001.00012.00003.00000') { + for (key of ['Image Hover in Catalog', 'Auto Watch', 'Auto Watch Reply']) { + setD(key, false); + } + } + if (compareString < '00001.00013.00001.00002') { + addSauces(['#//www.bing.com/images/search?q=imgurl:%IMG&view=detailv2&iss=sbi#enterInsights']); + } + if (compareString < '00001.00013.00005.00000') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/regex\.info\/exif\.cgi/mg, '$1http://exif.regex.info/exif.cgi')); + } + addSauces(Config['sauces'].match(/# Known filename formats:(?:\n.+)*|$/)[0].split('\n')); + } + if (compareString < '00001.00013.00007.00002') { + setD('Require OP Quote Link', true); + } + if (compareString < '00001.00013.00008.00000') { + setD('Download Link', true); + } + if (compareString < '00001.00013.00009.00003') { + if (data['jsWhitelist'] != null) { + const list = data['jsWhitelist'].split('\n'); + if (!list.includes('https://cdnjs.cloudflare.com') && list.includes('https://cdn.mathjax.org')) { + set('jsWhitelist', data['jsWhitelist'] + '\n\nhttps://cdnjs.cloudflare.com'); + } + } + } + if (compareString < '00001.00014.00000.00006') { + if (data['siteSoftware'] != null) { + set('siteSoftware', data['siteSoftware'] + '\n4cdn.org yotsuba'); + } + } + if (compareString < '00001.00014.00003.00002') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*)https:\/\/whatanime\.ga\//mg, '$1https://trace.moe/')); + } + } + if (compareString < '00001.00014.00004.00004') { + if ((data['siteSoftware'] != null) && !/^4channel\.org yotsuba$/m.test(data['siteSoftware'])) { + set('siteSoftware', data['siteSoftware'] + '\n4channel.org yotsuba'); + } + } + if (compareString < '00001.00014.00005.00000') { + for (var db of DataBoard.keys) { + if (data[db]?.boards) { + var { boards, lastChecked } = data[db]; + data[db]['4chan.org'] = { boards, lastChecked }; + delete data[db].boards; + delete data[db].lastChecked; + set(db, data[db]); + } + } + if ((data['siteSoftware'] != null) && (data['siteProperties'] == null)) { + const siteProperties = dict(); + for (var line of data['siteSoftware'].split('\n')) { + var [hostname, software] = Array.from(line.split(' ')); + siteProperties[hostname] = { software }; + } + set('siteProperties', siteProperties); + } + } + if (compareString < '00001.00014.00006.00006') { + if (data['sauces'] != null) { + set('sauces', data['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}-/')); + } + } + if (compareString < '00001.00014.00008.00000') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/https:\/\/www\.yandex\.com\/images\/search/g, 'https://yandex.com/images/search')); + } + } + if (compareString < '00001.00014.00009.00000') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*)(?:http:)?\/\/(www\.pixiv\.net|www\.deviantart\.com|imgur\.com|flickr\.com)\//mg, '$1https://$2/')); + set('sauces', data['sauces'].replace(/https:\/\/yandex\.com\/images\/search\?rpt=imageview&img_url=%IMG/g, 'https://yandex.com/images/search?rpt=imageview&url=%IMG')); + } + } + if (compareString < '00001.00014.00009.00001') { + if ((data['Use Faster Image Host'] != null) && (data['fourchanImageHost'] == null)) { + set('fourchanImageHost', (data['Use Faster Image Host'] ? 'i.4cdn.org' : '')); + } + } + if (compareString < '00001.00014.00010.00001') { + if (data['Filter in Native Catalog'] == null) { + set('Filter in Native Catalog', false); + } + } + if (compareString < '00001.00014.00012.00008') { + if (data['boardnav'] == null) { + set('boardnav', `\ +[ toggle-all ] +a-replace +c-replace +g-replace +k-replace +v-replace +vg-replace +vr-replace +ck-replace +co-replace +fit-replace +jp-replace +mu-replace +sp-replace +tv-replace +vp-replace +[external-text:"FAQ","${meta.faq}"]\ +`); + } + } + if (compareString < '00001.00014.00016.00001') { + if (data['archiveLists'] != null) { + set('archiveLists', data['archiveLists'].replace('https://mayhemydg.github.io/archives.json/archives.json', 'https://nstepien.github.io/archives.json/archives.json')); + } + } + if (compareString < '00001.00014.00016.00007') { + if (data['sauces'] != null) { + set('sauces', data['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')); + } + } + if (compareString < '00001.00014.00017.00002') { + if (data['jsWhitelist'] != null) { + set('jsWhitelist', data['jsWhitelist'] + '\n\nhttps://hcaptcha.com\nhttps://*.hcaptcha.com'); + } + } + if (compareString < '00001.00014.00020.00004') { + if (data['archiveLists'] != null) { + set('archiveLists', data['archiveLists'].replace('https://nstepien.github.io/archives.json/archives.json', 'https://4chenz.github.io/archives.json/archives.json')); + } + } + if (compareString < '00001.00014.00022.00003') { + if (data['sauces']) { + set('sauces', data['sauces'].replace(/^#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(IMG|T?URL)&safe=off(?=$|;)/mg, 'https://www.google.com/searchbyimage?sbisrc=4chanx&image_url=%$1&safe=off')); + if (compareString === '00001.00014.00022.00002' && !/\bsbisrc=/.test(data['sauces'])) { + set('sauces', data['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')); + } + } + } + return changes; + }, + loadSettings(data, cb) { + if (data.version.split('.')[0] === '2') { // https://github.com/loadletter/4chan-x + data = Settings.convertFrom.loadletter(data); + } + else if (data.version !== g.VERSION) { + Settings.upgrade(data.Conf, data.version); + } + return $$1.clear(function (err) { + if (err) { + return cb(err); + } + return $$1.set(data.Conf, cb); + }); + }, + reset() { + if (confirm('Your current settings will be entirely wiped, are you sure?')) { + return $$1.clear(function (err) { + if (err) { + return $$1('.imp-exp-result').textContent = 'Import failed due to an error.'; + } + else if (confirm('Reset successful. Reload now?')) { + return window.location.reload(); + } + }); + } + }, + filter(section) { + $$1.extend(section, { innerHTML: FilterSelectPage }); + const select = $$1('select', section); + $$1.on(select, 'change', Settings.selectFilter); + return Settings.selectFilter.call(select); + }, + selectFilter() { + let name; + const div = this.nextElementSibling; + if ((name = this.value) !== 'guide') { + if (!$$1.hasOwn(Config.filter, name)) { + return; + } + $$1.rmAll(div); + const ta = $$1.el('textarea', { + name, + className: 'field', + spellcheck: false + }); + $$1.on(ta, 'change', $$1.cb.value); + $$1.get(name, Conf[name], function (item) { + ta.value = item[name]; + return $$1.add(div, ta); + }); + return; + } + Object.keys(Config.filter).filter(x => x !== 'general').map((x, i) => ({ + innerHTML: (i ? "," : "") + `${E(x)}` + })); + $$1.extend(div, { innerHTML: FilterGuidePage }); + return $$1('.warning', div).hidden = Conf['Filter']; + }, + sauce(section) { + $$1.extend(section, { innerHTML: SaucePage }); + $$1('.warning', section).hidden = Conf['Sauce']; + const ta = $$1('textarea', section); + $$1.get('sauces', Conf['sauces'], function (item) { + ta.value = item['sauces']; + return (ta.hidden = false); + }); // XXX prevent Firefox from adding initialization to undo queue + return $$1.on(ta, 'change', $$1.cb.value); + }, + advanced(section) { + let input, name; + $$1.extend(section, { innerHTML: AdvancedPage }); + for (var warning of $$('.warning', section)) { + warning.hidden = Conf[warning.dataset.feature]; + } + const inputs = dict(); + for (input of $$('[name]', section)) { + inputs[input.name] = input; + } + $$1.on(inputs['archiveLists'], 'change', function () { + $$1.set('lastarchivecheck', 0); + Conf['lastarchivecheck'] = 0; + return $$1.id('lastarchivecheck').textContent = 'never'; + }); + const items = dict(); + for (name in inputs) { + input = inputs[name]; + if (!['Interval', 'Custom CSS'].includes(name)) { + items[name] = Conf[name]; + var event = ((input.nodeName === 'SELECT') || + ['checkbox', 'radio'].includes(input.type) || + ((input.nodeName === 'TEXTAREA') && !(name in Settings))) ? 'change' : 'input'; + $$1.on(input, event, $$1.cb[input.type === 'checkbox' ? 'checked' : 'value']); + if (name in Settings) { + $$1.on(input, event, Settings[name]); + } + } + } + $$1.get(items, function (items) { + for (var key in items) { + var val = items[key]; + input = inputs[key]; + input[input.type === 'checkbox' ? 'checked' : 'value'] = val; + input.hidden = false; // XXX prevent Firefox from adding initialization to undo queue + if (key in Settings) { + Settings[key].call(input); + } + } + }); + const listImageHost = $$1.id('list-fourchanImageHost'); + for (var textContent of ImageHost.suggestions) { + $$1.add(listImageHost, $$1.el('option', { textContent })); + } + const interval = inputs['Interval']; + const customCSS = inputs['Custom CSS']; + const applyCSS = $$1('#apply-css', section); + interval.value = Conf['Interval']; + customCSS.checked = Conf['Custom CSS']; + inputs['usercss'].disabled = !Conf['Custom CSS']; + applyCSS.disabled = !Conf['Custom CSS']; + $$1.on(interval, 'change', ThreadUpdater.cb.interval); + $$1.on(customCSS, 'change', Settings.togglecss); + $$1.on(applyCSS, 'click', () => CustomCSS.update()); + const itemsArchive = dict(); + for (name of ['archives', 'selectedArchives', 'lastarchivecheck']) { + itemsArchive[name] = Conf[name]; + } + $$1.get(itemsArchive, function (itemsArchive) { + $$1.extend(Conf, itemsArchive); + Redirect$1.selectArchives(); + return Settings.addArchiveTable(section); + }); + const boardSelect = $$1('#archive-board-select', section); + const table = $$1('#archive-table', section); + const updateArchives = $$1('#update-archives', section); + $$1.on(boardSelect, 'change', function () { + $$1('tbody > :not([hidden])', table).hidden = true; + return $$1(`tbody > .${this.value}`, table).hidden = false; + }); + return $$1.on(updateArchives, 'click', () => Redirect$1.update(() => Settings.addArchiveTable(section))); + }, + addArchiveTable(section) { + let boardID, o; + $$1('#lastarchivecheck', section).textContent = Conf['lastarchivecheck'] === 0 ? + 'never' + : + new Date(Conf['lastarchivecheck']).toLocaleString(); + const boardSelect = $$1('#archive-board-select', section); + const table = $$1('#archive-table', section); + const tbody = $$1('tbody', section); + $$1.rmAll(boardSelect); + $$1.rmAll(tbody); + const archBoards = dict(); + for (var { uid, name, boards, files, software } of Conf['archives']) { + if (!['fuuka', 'foolfuuka'].includes(software)) { + continue; + } + for (boardID of boards) { + o = archBoards[boardID] || (archBoards[boardID] = { + thread: [], + post: [], + file: [] + }); + var archive = [uid ?? name, name]; + o.thread.push(archive); + if (software === 'foolfuuka') { + o.post.push(archive); + } + if (files.includes(boardID)) { + o.file.push(archive); + } + } + } + const rows = []; + const boardOptions = []; + for (boardID of Object.keys(archBoards).sort()) { // Alphabetical order + var row = $$1.el('tr', { className: `board-${boardID}` }); + row.hidden = boardID !== g.BOARD.ID; + boardOptions.push($$1.el('option', { + textContent: `/${boardID}/`, + value: `board-${boardID}`, + selected: boardID === g.BOARD.ID + })); + o = archBoards[boardID]; + for (var item of ['thread', 'post', 'file']) { + $$1.add(row, Settings.addArchiveCell(boardID, o, item)); + } + rows.push(row); + } + if (rows.length === 0) { + boardSelect.hidden = (table.hidden = true); + return; + } + boardSelect.hidden = (table.hidden = false); + if (!(g.BOARD.ID in archBoards)) { + rows[0].hidden = false; + } + $$1.add(boardSelect, boardOptions); + $$1.add(tbody, rows); + for (boardID in Conf['selectedArchives']) { + var data = Conf['selectedArchives'][boardID]; + for (var type in data) { + var select; + var id = data[type]; + if (select = $$1(`select[data-boardid='${boardID}'][data-type='${type}']`, tbody)) { + select.value = JSON.stringify(id); + if (!select.value) { + select.value = select.firstChild.value; + } + } + } + } + }, + addArchiveCell(boardID, data, type) { + const { length } = data[type]; + const td = $$1.el('td', { className: 'archive-cell' }); + if (!length) { + td.textContent = '--'; + return td; + } + const options = []; + let i = 0; + while (i < length) { + var archive = data[type][i++]; + options.push($$1.el('option', { + value: JSON.stringify(archive[0]), + textContent: archive[1] + })); + } + $$1.extend(td, { innerHTML: '' }); + const select = td.firstElementChild; + if (!(select.disabled = length === 1)) { + // XXX GM can't into datasets + select.setAttribute('data-boardid', boardID); + select.setAttribute('data-type', type); + $$1.on(select, 'change', Settings.saveSelectedArchive); + } + $$1.add(select, options); + return td; + }, + saveSelectedArchive() { + return $$1.get('selectedArchives', Conf['selectedArchives'], ({ selectedArchives }) => { + (selectedArchives[this.dataset.boardid] || (selectedArchives[this.dataset.boardid] = dict()))[this.dataset.type] = JSON.parse(this.value); + $$1.set('selectedArchives', selectedArchives); + Conf['selectedArchives'] = selectedArchives; + return Redirect$1.selectArchives(); + }); + }, + boardnav() { + return Header$1.generateBoardList(this.value); + }, + time() { + return this.nextElementSibling.textContent = Time.format(this.value, new Date()); + }, + timeLocale() { + return Settings.time.call($$1('[name=time]', Settings.dialog)); + }, + backlink() { + return this.nextElementSibling.textContent = this.value.replace(/%(?:id|%)/g, x => ({ '%id': '123456789', '%%': '%' })[x]); + }, + fileInfo() { + const data = { + isReply: true, + file: { + url: `//${ImageHost.host()}/g/1334437723720.jpg`, + name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg', + size: '276 KB', + sizeInBytes: 276 * 1024, + dimensions: '1280x720', + isImage: true, + isVideo: false, + isSpoiler: true, + tag: 'Loop' + } + }; + return FileInfo.format(this.value, data, this.nextElementSibling); + }, + favicon() { + Favicon.switch(); + if ((g.VIEW === 'thread') && Conf['Unread Favicon']) { + Unread.update(); + } + const img = this.nextElementSibling.children; + const f = Favicon; + const iterable = [f.SFW, f.unreadSFW, f.unreadSFWY, f.NSFW, f.unreadNSFW, f.unreadNSFWY, f.dead, f.unreadDead, f.unreadDeadY]; + for (let i = 0; i < iterable.length; i++) { + var icon = iterable[i]; + if (!img[i]) { + $$1.add(this.nextElementSibling, $$1.el('img')); + } + img[i].src = icon; + } + }, + togglecss() { + if (($$1('textarea[name=usercss]', $$1.x('ancestor::fieldset[1]', this)).disabled = ($$1.id('apply-css').disabled = !this.checked))) { + CustomCSS.rmStyle(); + } + else { + CustomCSS.addStyle(); + } + return $$1.cb.checked.call(this); + }, + keybinds(section) { + let key; + $$1.extend(section, { innerHTML: KeybindsPage }); + $$1('.warning', section).hidden = Conf['Keybinds']; + const tbody = $$1('tbody', section); + const items = dict(); + const inputs = dict(); + for (key in Config.hotkeys) { + var arr = Config.hotkeys[key]; + var tr = $$1.el('tr', { innerHTML: `${arr[1]}` }); + var input = $$1('input', tr); + input.name = key; + input.spellcheck = false; + items[key] = Conf[key]; + inputs[key] = input; + $$1.on(input, 'keydown', Settings.keybind); + $$1.add(tbody, tr); + } + return $$1.get(items, function (items) { + for (key in items) { + var val = items[key]; + inputs[key].value = val; + } + }); + }, + keybind(e) { + let key; + if (e.keyCode === 9) { + return; + } // tab + e.preventDefault(); + e.stopPropagation(); + if ((key = Keybinds.keyCode(e)) == null) { + return; + } + this.value = key; + return $$1.cb.value.call(this); + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var FappeTyme = { + init() { + if ((!Conf['Fappe Tyme'] && !Conf['Werk Tyme']) || !['index', 'thread', 'archive'].includes(g.VIEW)) { return; } + + this.nodes = {}; + this.enabled = { + fappe: false, + werk: Conf['werk'] + }; + + for (var type of ["Fappe", "Werk"]) { + if (Conf[`${type} Tyme`]) { + var lc = type.toLowerCase(); + var el = UI.checkbox(lc, `${type} Tyme`, false); + el.title = `${type} Tyme`; + + this.nodes[lc] = el.firstElementChild; + if (Conf[lc]) { this.set(lc, true); } + $$1.on(this.nodes[lc], 'change', this.toggle.bind(this, lc)); + + Header$1.menu.addEntry({ + el, + order: 97 + }); + + var indicator = $$1.el('span', { + className: 'indicator', + textContent: type[0], + title: `${type} Tyme active` + } + ); + $$1.on(indicator, 'click', function() { + const check = $$1.getOwn(FappeTyme.nodes, this.parentNode.id.replace('shortcut-', '')); + check.checked = !check.checked; + return $$1.event('change', null, check); + }); + Header$1.addShortcut(lc, indicator, 410); + } + } + + if (Conf['Werk Tyme']) { + $$1.sync('werk', this.set.bind(this, 'werk')); + } + + Callbacks.Post.push({ + name: 'Fappe Tyme', + cb: this.node + }); + + return Callbacks.CatalogThread.push({ + name: 'Werk Tyme', + cb: this.catalogNode + }); + }, + + node() { + return this.nodes.root.classList.toggle('noFile', !this.files.length); + }, + + catalogNode() { + const file = this.thread.OP.files[0]; + if (!file) { return; } + const filename = $$1.el('div', { + textContent: file.name, + className: 'werkTyme-filename' + } + ); + return $$1.add(this.nodes.thumb.parentNode, filename); + }, + + set(type, enabled) { + this.enabled[type] = (this.nodes[type].checked = enabled); + return $$1[`${enabled ? 'add' : 'rm'}Class`](doc$1, `${type}Tyme`); + }, + + toggle(type) { + this.set(type, !this.enabled[type]); + if (type === 'werk') { return $$1.cb.checked.call(this.nodes[type]); } + } + }; + + var galleryPage = `
          + + + + + × + +
          + + / + + + +
          +
          +
          + +
          +
          +
          +
          +`; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS104: Avoid inline assignments + * DS204: Change includes calls to have a more natural evaluation order + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Sauce = { + init() { + let link; + if (!['index', 'thread'].includes(g.VIEW) || !Conf['Sauce']) { return; } + $$1.addClass(doc$1, 'show-sauce'); + + const links = []; + for (link of Conf['sauces'].split('\n')) { + var linkData; + if ((link[0] !== '#') && (linkData = this.parseLink(link))) { + links.push(linkData); + } + } + if (!links.length) { return; } + + this.links = links; + this.link = $$1.el('a', { + target: '_blank', + className: 'sauce' + } + ); + return Callbacks.Post.push({ + name: 'Sauce', + cb: this.node + }); + }, + + parseLink(link) { + if (!(link = link.trim())) { return null; } + const parts = dict(); + const iterable = link.split(/;(?=(?:text|boards|types|regexp|sandbox):?)/); + for (let i = 0; i < iterable.length; i++) { + var part = iterable[i]; + if (i === 0) { + parts['url'] = part; + } else { + var m = part.match(/^(\w*):?(.*)$/); + parts[m[1]] = m[2]; + } + } + if (!parts['text']) { parts['text'] = parts['url'].match(/(\w+)\.\w+\//)?.[1] || '?'; } + if ('boards' in parts) { + parts['boards'] = Filter.parseBoards(parts['boards']); + } + if ('regexp' in parts) { + try { + let regexp; + if (regexp = parts['regexp'].match(/^\/(.*)\/(\w*)$/)) { + parts['regexp'] = RegExp(regexp[1], regexp[2]); + } else { + parts['regexp'] = RegExp(parts['regexp']); + } + } catch (err) { + new Notice('warning', [ + $$1.tn("Invalid regexp for Sauce link:"), + $$1.el('br'), + $$1.tn(link), + $$1.el('br'), + $$1.tn(err.message) + ], 60); + return null; + } + } + return parts; + }, + + createSauceLink(link, post, file) { + let a, matches, needle; + const ext = file.url.match(/[^.]*$/)[0]; + const parts = dict(); + $$1.extend(parts, link); + + if (!!parts['boards'] && !parts['boards'][`${post.siteID}/${post.boardID}`] && !parts['boards'][`${post.siteID}/*`]) { return null; } + if (!!parts['types'] && (needle = ext, !parts['types'].split(',').includes(needle))) { return null; } + if (!!parts['regexp'] && (!(matches = file.name.match(parts['regexp'])))) { return null; } + + const missing = []; + for (var key of ['url', 'text']) { + parts[key] = parts[key].replace(/%(T?URL|IMG|[sh]?MD5|board|name|%|semi|\$\d+)/g, function(orig, parameter) { + let type; + if (parameter[0] === '$') { + if (!matches) { return orig; } + type = matches[parameter.slice(1)] || ''; + } else { + type = Sauce.formatters[parameter](post, file, ext); + if ((type == null)) { + missing.push(parameter); + return ''; + } + } + + if ((key === 'url') && !['%', 'semi'].includes(parameter)) { + if (/^javascript:/i.test(parts['url'])) { type = JSON.stringify(type); } + type = encodeURIComponent(type); + } + return type; + }); + } + + if (g.SITE.areMD5sDeferred?.(post.board) && missing.length && !missing.filter(x => !/^.?MD5$/.test(x)).length) { + a = Sauce.link.cloneNode(false); + a.dataset.skip = '1'; + return a; + } + + if (missing.length) { return null; } + + a = Sauce.link.cloneNode(false); + a.href = parts['url']; + a.textContent = parts['text']; + if (/^javascript:/i.test(parts['url'])) { a.removeAttribute('target'); } + return a; + }, + + node() { + if (this.isClone) { return; } + for (var file of this.files) { + Sauce.file(this, file); + } + }, + + file(post, file) { + let link, node; + const nodes = []; + const skipped = []; + for (link of Sauce.links) { + if (node = Sauce.createSauceLink(link, post, file)) { + nodes.push($$1.tn(' '), node); + if (node.dataset.skip) { skipped.push([link, node]); } + } + } + $$1.add(file.text, nodes); + + if (skipped.length) { + var observer = new MutationObserver(function() { + if (file.text.dataset.md5) { + for ([link, node] of skipped) { + var node2; + if (node2 = Sauce.createSauceLink(link, post, file)) { + $$1.replace(node, node2); + } + } + return observer.disconnect(); + } + }); + return observer.observe(file.text, {attributes: true}); + } + }, + + formatters: { + TURL(post, file) { return file.thumbURL; }, + URL(post, file) { return file.url; }, + IMG(post, file, ext) { if (['gif', 'jpg', 'jpeg', 'png'].includes(ext)) { return file.url; } else { return file.thumbURL; } }, + MD5(post, file) { return file.MD5; }, + sMD5(post, file) { return file.MD5?.replace(/[+/=]/g, c => ({'+': '-', '/': '_', '=': ''})[c]); }, + hMD5(post, file) { if (file.MD5) { return (atob(file.MD5).map((c) => `0${c.charCodeAt(0).toString(16)}`.slice(-2))).join(''); } }, + board(post) { return post.board.ID; }, + name(post, file) { return file.name; }, + '%'() { return '%'; }, + semi() { return ';'; } + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var Gallery = { + init() { + if (!(this.enabled = Conf['Gallery'] && ['index', 'thread'].includes(g.VIEW))) { return; } + + this.delay = Conf['Slide Delay']; + + const el = $$1.el('a', { + href: 'javascript:;', + title: 'Gallery', + textContent: '🖼︎', + }); + + $$1.on(el, 'click', this.cb.toggle); + + Header$1.addShortcut('gallery', el, 530); + + return Callbacks.Post.push({ + name: 'Gallery', + cb: this.node + }); + }, + + node() { + return (() => { + const result = []; + for (var file of this.files) { + if (file.thumb) { + if (Gallery.nodes) { + Gallery.generateThumb(this, file); + Gallery.nodes.total.textContent = Gallery.images.length; + } + + if (!Conf['Image Expansion'] && ((g.SITE.software !== 'tinyboard') || !Main$1.jsEnabled)) { + result.push($$1.on(file.thumbLink, 'click', Gallery.cb.image)); + } else { + result.push(undefined); + } + } + } + return result; + })(); + }, + + build(image) { + let dialog, thumb; + const {cb} = Gallery; + + if (Conf['Fullscreen Gallery']) { + $$1.one(d$1, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', () => $$1.on(d$1, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', cb.close)); + doc$1.mozRequestFullScreen?.(); + doc$1.webkitRequestFullScreen?.(Element.ALLOW_KEYBOARD_INPUT); + } + + Gallery.images = []; + const nodes = (Gallery.nodes = {}); + Gallery.fileIDs = dict(); + Gallery.slideshow = false; + + nodes.el = (dialog = $$1.el('div', + {id: 'a-gallery'})); + $$1.extend(dialog, {innerHTML: galleryPage }); + + const object = { + 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 key in object) { var value = object[key]; nodes[key] = $$1(value, dialog); } + + const menuButton = $$1('.menu-button', dialog); + nodes.menu = new UI.Menu('gallery'); + + $$1.on(nodes.frame, 'click', cb.blank); + if (Conf['Mouse Wheel Volume']) { $$1.on(nodes.frame, 'wheel', Volume.wheel); } + $$1.on(nodes.next, 'click', cb.click); + $$1.on(nodes.name, 'click', ImageCommon.download); + + $$1.on($$1('.gal-prev', dialog), 'click', cb.prev); + $$1.on($$1('.gal-next', dialog), 'click', cb.next); + $$1.on($$1('.gal-start', dialog), 'click', cb.start); + $$1.on($$1('.gal-stop', dialog), 'click', cb.stop); + $$1.on($$1('.gal-close', dialog), 'click', cb.close); + + $$1.on(menuButton, 'click', function(e) { + return nodes.menu.toggle(e, this, g); + }); + + for (var entry of Gallery.menu.createSubEntries()) { + entry.order = 0; + nodes.menu.addEntry(entry); + } + + $$1.on(d$1, 'keydown', cb.keybinds); + if (Conf['Keybinds']) { $$1.off(d$1, 'keydown', Keybinds.keydown); } + + $$1.on(window, 'resize', Gallery.cb.setHeight); + + for (var postThumb of $$(g.SITE.selectors.file.thumb)) { + var post; + if (!(post = Get$1.postFromNode(postThumb))) { continue; } + for (var file of post.files) { + if (file.thumb) { + Gallery.generateThumb(post, file); + // If no image to open is given, pick image we have scrolled to. + if (!image && Gallery.fileIDs[`${post.fullID}.${file.index}`]) { + var candidate = file.thumbLink; + if ((Header$1.getTopOf(candidate) + candidate.getBoundingClientRect().height) >= 0) { + image = candidate; + } + } + } + } + } + $$1.addClass(doc$1, 'gallery-open'); + + $$1.add(d$1.body, dialog); + + nodes.thumbs.scrollTop = 0; + nodes.current.parentElement.scrollTop = 0; + + if (image) { thumb = $$1(`[href='${image.href}']`, nodes.thumbs); } + if (!thumb) { thumb = Gallery.images[Gallery.images.length-1]; } + if (thumb) { Gallery.open(thumb); } + + doc$1.style.overflow = 'hidden'; + return nodes.total.textContent = Gallery.images.length; + }, + + generateThumb(post, file) { + if (post.isClone || post.isHidden) { return; } + if (!file || !file.thumb || (!file.isImage && !file.isVideo && !Conf['PDF in Gallery'])) { return; } + if (Gallery.fileIDs[`${post.fullID}.${file.index}`]) { return; } + + Gallery.fileIDs[`${post.fullID}.${file.index}`] = true; + + const thumb = $$1.el('a', { + className: 'gal-thumb', + href: file.url, + target: '_blank', + title: file.name + } + ); + + thumb.dataset.id = Gallery.images.length; + thumb.dataset.post = post.fullID; + thumb.dataset.file = file.index; + + const thumbImg = file.thumb.cloneNode(false); + thumbImg.style.cssText = ''; + $$1.add(thumb, thumbImg); + + $$1.on(thumb, 'click', Gallery.cb.open); + + Gallery.images.push(thumb); + return $$1.add(Gallery.nodes.thumbs, thumb); + }, + + load(thumb, errorCB) { + const ext = thumb.href.match(/\w*$/); + const elType = $$1.getOwn({'webm': 'video', 'mp4': 'video', 'ogv': 'video', 'pdf': 'iframe'}, ext) || 'img'; + const file = $$1.el(elType); + $$1.extend(file.dataset, thumb.dataset); + $$1.on(file, 'error', errorCB); + file.src = thumb.href; + return file; + }, + + open(thumb) { + let el, file, post; + const {nodes} = Gallery; + const oldID = +nodes.current.dataset.id; + const newID = +thumb.dataset.id; + + // Highlight, center selected thumbnail + if (el = Gallery.images[oldID]) { $$1.rmClass(el, 'gal-highlight'); } + $$1.addClass(thumb, 'gal-highlight'); + nodes.thumbs.scrollTop = (thumb.offsetTop + (thumb.offsetHeight/2)) - (nodes.thumbs.clientHeight/2); + + // Load image or use preloaded image + if (Gallery.cache?.dataset.id === (''+newID)) { + file = Gallery.cache; + $$1.off(file, 'error', Gallery.cacheError); + $$1.on(file, 'error', Gallery.error); + } else { + file = Gallery.load(thumb, Gallery.error); + } + + // Replace old image with new one + $$1.off(nodes.current, 'error', Gallery.error); + ImageCommon.pause(nodes.current); + $$1.replace(nodes.current, file); + nodes.current = file; + + if (file.nodeName === 'VIDEO') { + file.loop = true; + Volume.setup(file); + if (Conf['Autoplay']) { file.play(); } + if (Conf['Show Controls']) { ImageCommon.addControls(file); } + } + + doc$1.classList.toggle('gal-pdf', file.nodeName === 'IFRAME'); + Gallery.cb.setHeight(); + nodes.count.textContent = +thumb.dataset.id + 1; + nodes.name.download = (nodes.name.textContent = thumb.title); + nodes.name.href = thumb.href; + nodes.frame.scrollTop = 0; + nodes.next.focus(); + + // Set sauce links + $$1.rmAll(nodes.sauce); + if (Conf['Sauce'] && Sauce.links && (post = g.posts.get(file.dataset.post))) { + const sauces = []; + for (var link of Sauce.links) { + var node; + if (node = Sauce.createSauceLink(link, post, post.files[+file.dataset.file])) { + sauces.push($$1.tn(' '), node); + } + } + $$1.add(nodes.sauce, sauces); + } + + // Continue slideshow if moving forward, stop otherwise + if (Gallery.slideshow && ((newID > oldID) || ((oldID === (Gallery.images.length-1)) && (newID === 0)))) { + Gallery.setupTimer(); + } else { + Gallery.cb.stop(); + } + + // Scroll to post + if (Conf['Scroll to Post'] && (post = g.posts.get(file.dataset.post))) { + Header$1.scrollTo(post.nodes.root); + } + + // Preload next image + if (isNaN(oldID) || (newID === ((oldID + 1) % Gallery.images.length))) { + return Gallery.cache = Gallery.load(Gallery.images[(newID + 1) % Gallery.images.length], Gallery.cacheError); + } + }, + + error() { + if (this.error?.code === MediaError.MEDIA_ERR_DECODE) { + return new Notice('error', 'Corrupt or unplayable video', 30); + } + if (ImageCommon.isFromArchive(this)) { return; } + const post = g.posts.get(this.dataset.post); + const file = post.files[+this.dataset.file]; + return ImageCommon.error(this, post, file, null, url => { + if (!url) { return; } + Gallery.images[+this.dataset.id].href = url; + if (Gallery.nodes.current === this) { return this.src = url; } + }); + }, + + cacheError() { + return delete Gallery.cache; + }, + + cleanupTimer() { + clearTimeout(Gallery.timeoutID); + const {current} = Gallery.nodes; + $$1.off(current, 'canplaythrough load', Gallery.startTimer); + return $$1.off(current, 'ended', Gallery.cb.next); + }, + + startTimer() { + return Gallery.timeoutID = setTimeout(Gallery.checkTimer, Gallery.delay * SECOND); + }, + + setupTimer() { + Gallery.cleanupTimer(); + const {current} = Gallery.nodes; + const isVideo = current.nodeName === 'VIDEO'; + if (isVideo) { current.play(); } + if ((isVideo ? current.readyState >= 4 : current.complete) || (current.nodeName === 'IFRAME')) { + return Gallery.startTimer(); + } else { + return $$1.on(current, (isVideo ? 'canplaythrough' : 'load'), Gallery.startTimer); + } + }, + + checkTimer() { + const {current} = Gallery.nodes; + if ((current.nodeName === 'VIDEO') && !current.paused) { + $$1.on(current, 'ended', Gallery.cb.next); + return current.loop = false; + } else { + return Gallery.cb.next(); + } + }, + + cb: { + keybinds(e) { + let key; + if (!(key = Keybinds.keyCode(e))) { return; } + + const cb = (() => { switch (key) { + case Conf['Close']: case Conf['Open Gallery']: + return Gallery.cb.close; + case Conf['Next Gallery Image']: + return Gallery.cb.next; + case Conf['Advance Gallery']: + return Gallery.cb.advance; + case Conf['Previous Gallery Image']: + return Gallery.cb.prev; + case Conf['Pause']: + return Gallery.cb.pause; + case Conf['Slideshow']: + return Gallery.cb.toggleSlideshow; + case Conf['Rotate image anticlockwise']: + return Gallery.cb.rotateLeft; + case Conf['Rotate image clockwise']: + return Gallery.cb.rotateRight; + case Conf['Download Gallery Image']: + return Gallery.cb.download; + } })(); + + if (!cb) { return; } + e.stopPropagation(); + e.preventDefault(); + return cb(); + }, + + open(e) { + if (e) { e.preventDefault(); } + if (this) { return Gallery.open(this); } + }, + + image(e) { + e.preventDefault(); + e.stopPropagation(); + return Gallery.build(this); + }, + + prev() { + return Gallery.cb.open.call( + Gallery.images[+Gallery.nodes.current.dataset.id - 1] || Gallery.images[Gallery.images.length - 1] + ); + }, + next() { + return Gallery.cb.open.call( + Gallery.images[+Gallery.nodes.current.dataset.id + 1] || Gallery.images[0] + ); + }, + + click(e) { + if (ImageCommon.onControls(e)) { return; } + e.preventDefault(); + return Gallery.cb.advance(); + }, + + advance() { if (!Conf['Autoplay'] && Gallery.nodes.current.paused) { return Gallery.nodes.current.play(); } else { return Gallery.cb.next(); } }, + toggle() { return (Gallery.nodes ? Gallery.cb.close : Gallery.build)(); }, + blank(e) { if (e.target === this) { return Gallery.cb.close(); } }, + toggleSlideshow() { return Gallery.cb[Gallery.slideshow ? 'stop' : 'start'](); }, + + download() { + const name = $$1('.gal-name'); + return name.click(); + }, + + pause() { + Gallery.cb.stop(); + const {current} = Gallery.nodes; + if (current.nodeName === 'VIDEO') { return current[current.paused ? 'play' : 'pause'](); } + }, + + start() { + $$1.addClass(Gallery.nodes.buttons, 'gal-playing'); + Gallery.slideshow = true; + return Gallery.setupTimer(); + }, + + stop() { + if (!Gallery.slideshow) { return; } + Gallery.cleanupTimer(); + const {current} = Gallery.nodes; + if (current.nodeName === 'VIDEO') { current.loop = true; } + $$1.rmClass(Gallery.nodes.buttons, 'gal-playing'); + return Gallery.slideshow = false; + }, + + rotateLeft() { return Gallery.cb.rotate(270); }, + rotateRight() { return Gallery.cb.rotate(90); }, + + rotate: debounce(100, function(delta) { + const {current} = Gallery.nodes; + if (current.nodeName === 'IFRAME') { return; } + current.dataRotate = ((current.dataRotate || 0) + delta) % 360; + current.style.transform = `rotate(${current.dataRotate}deg)`; + return Gallery.cb.setHeight(); + }), + + close() { + $$1.off(Gallery.nodes.current, 'error', Gallery.error); + ImageCommon.pause(Gallery.nodes.current); + $$1.rm(Gallery.nodes.el); + $$1.rmClass(doc$1, 'gallery-open'); + if (Conf['Fullscreen Gallery']) { + $$1.off(d$1, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', Gallery.cb.close); + d$1.mozCancelFullScreen?.(); + d$1.webkitExitFullscreen?.(); + } + delete Gallery.nodes; + delete Gallery.fileIDs; + doc$1.style.overflow = ''; + + $$1.off(d$1, 'keydown', Gallery.cb.keybinds); + if (Conf['Keybinds']) { $$1.on(d$1, 'keydown', Keybinds.keydown); } + $$1.off(window, 'resize', Gallery.cb.setHeight); + return clearTimeout(Gallery.timeoutID); + }, + + setFitness() { + return (this.checked ? $$1.addClass : $$1.rmClass)(doc$1, `gal-${this.name.toLowerCase().replace(/\s+/g, '-')}`); + }, + + setHeight: debounce(100, function () { + let dim, margin, minHeight; + const {current, frame} = Gallery.nodes; + const {style} = current; + + if (Conf['Stretch to Fit'] && (dim = g.posts.get(current.dataset.post)?.files[+current.dataset.file].dimensions)) { + const [width, height] = Array.from(dim.split('x')); + let containerWidth = frame.clientWidth; + let containerHeight = doc$1.clientHeight - 25; + if (((current.dataRotate || 0) % 180) === 90) { + [containerWidth, containerHeight] = Array.from([containerHeight, containerWidth]); + } + minHeight = Math.min(containerHeight, (height / width) * containerWidth); + style.minHeight = minHeight + 'px'; + style.minWidth = ((width / height) * minHeight) + 'px'; + } else { + style.minHeight = (style.minWidth = ''); + } + + if (((current.dataRotate || 0) % 180) === 90) { + style.maxWidth = Conf['Fit Height'] ? `${doc$1.clientHeight - 25}px` : 'none'; + style.maxHeight = Conf['Fit Width'] ? `${frame.clientWidth}px` : 'none'; + margin = (current.clientWidth - current.clientHeight)/2; + return style.margin = `${margin}px ${-margin}px`; + } else { + return style.maxWidth = (style.maxHeight = (style.margin = '')); + } + }), + + setDelay() { return Gallery.delay = +this.value; } + }, + + menu: { + init() { + if (!Gallery.enabled) { return; } + + const el = $$1.el('span', { + textContent: 'Gallery', + className: 'gallery-link' + } + ); + + return Header$1.menu.addEntry({ + el, + order: 105, + subEntries: Gallery.menu.createSubEntries() + }); + }, + + createSubEntry(name) { + const label = UI.checkbox(name, name); + const input = label.firstElementChild; + if (['Hide Thumbnails', 'Fit Width', 'Fit Height'].includes(name)) { $$1.on(input, 'change', Gallery.cb.setFitness); } + $$1.event('change', null, input); + $$1.on(input, 'change', $$1.cb.checked); + if (['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Stretch to Fit'].includes(name)) { $$1.on(input, 'change', Gallery.cb.setHeight); } + return {el: label}; + }, + + createSubEntries() { + const subEntries = (['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Stretch to Fit', 'Scroll to Post'].map((item) => Gallery.menu.createSubEntry(item))); + + const delayLabel = $$1.el('label', {innerHTML: 'Slide Delay: '}); + const delayInput = delayLabel.firstElementChild; + delayInput.value = Gallery.delay; + $$1.on(delayInput, 'change', Gallery.cb.setDelay); + $$1.on(delayInput, 'change', $$1.cb.value); + subEntries.push({el: delayLabel}); + + return subEntries; + } + } + }; + + var EmbeddingPage = `
          +
          + + × +
          +
          +`; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var Embedding = { + init() { + if (!['index', 'thread', 'archive'].includes(g.VIEW) || !Conf['Linkify'] || (!Conf['Embedding'] && !Conf['Link Title'] && !Conf['Cover Preview'])) { return; } + this.types = dict(); + for (var type of this.ordered_types) { this.types[type.key] = type; } + + if (Conf['Embedding'] && (g.VIEW !== 'archive')) { + this.dialog = UI.dialog('embedding', + { innerHTML: EmbeddingPage }); + this.media = $$1('#media-embed', this.dialog); + $$1.one(d$1, '4chanXInitFinished', this.ready); + $$1.on(d$1, 'IndexRefreshInternal', () => g.posts.forEach(function(post) { + for (post of [post, ...Array.from(post.clones)]) { + for (var embed of post.nodes.embedlinks) { + Embedding.cb.catalogRemove.call(embed); + } + } + })); + } + if (Conf['Link Title']) { + return $$1.on(d$1, '4chanXInitFinished PostsInserted', function() { + for (var key in Embedding.types) { + var service = Embedding.types[key]; + if (service.title?.batchSize) { + Embedding.flushTitles(service.title); + } + } + }); + } + }, + + events(post) { + let el, i, items; + if (g.VIEW === 'archive') { return; } + if (Conf['Embedding']) { + i = 0; + items = (post.nodes.embedlinks = $$('.embedder', post.nodes.comment)); + while ((el = items[i++])) { + $$1.on(el, 'click', Embedding.cb.click); + if ($$1.hasClass(el, 'embedded')) { Embedding.cb.toggle.call(el); } + } + } + if (Conf['Cover Preview']) { + i = 0; + items = $$('.linkify', post.nodes.comment); + while ((el = items[i++])) { + var data; + if (data = Embedding.services(el)) { + Embedding.preview(data); + } + } + return; + } + }, + + process(link, post) { + let data; + if (!Conf['Embedding'] && !Conf['Link Title'] && !Conf['Cover Preview']) { return; } + if ($$1.x('ancestor::pre', link)) { return; } + if (data = Embedding.services(link)) { + data.post = post; + if (Conf['Embedding'] && (g.VIEW !== 'archive')) { Embedding.embed(data); } + if (Conf['Link Title']) { Embedding.title(data); } + if (Conf['Cover Preview'] && (g.VIEW !== 'archive')) { return Embedding.preview(data); } + } + }, + + services(link) { + const {href} = link; + for (var type of Embedding.ordered_types) { + var match; + if (match = type.regExp.exec(href)) { + return {key: type.key, uid: match[1], options: match[2], link}; + } + } + }, + + embed(data) { + const {key, uid, options, link, post} = data; + const {href} = link; + + $$1.addClass(link, key.toLowerCase()); + + const embed = $$1.el('a', { + className: 'embedder', + href: 'javascript:;' + } + , + {innerHTML: '(unembed)'}); + + const object = {key, uid, options, href}; + for (var name in object) { var value = object[name]; embed.dataset[name] = value; } + + $$1.on(embed, 'click', Embedding.cb.click); + $$1.after(link, [$$1.tn(' '), embed]); + post.nodes.embedlinks.push(embed); + + if (Conf['Auto-embed'] && !Conf['Floating Embeds'] && !post.isFetchedQuote) { + if ($$1.hasClass(doc$1, 'catalog-mode')) { + return $$1.addClass(embed, 'embed-removed'); + } else { + return Embedding.cb.toggle.call(embed); + } + } + }, + + ready() { + if (!Main$1.isThisPageLegit()) { return; } + $$1.addClass(Embedding.dialog, 'empty'); + $$1.on($$1('.close', Embedding.dialog), 'click', Embedding.closeFloat); + $$1.on($$1('.move', Embedding.dialog), 'mousedown', Embedding.dragEmbed); + $$1.on($$1('.jump', Embedding.dialog), 'click', function() { + if (doc$1.contains(Embedding.lastEmbed)) { return Header$1.scrollTo(Embedding.lastEmbed); } + }); + return $$1.add(d$1.body, Embedding.dialog); + }, + + closeFloat() { + delete Embedding.lastEmbed; + $$1.addClass(Embedding.dialog, 'empty'); + return $$1.replace(Embedding.media.firstChild, $$1.el('div')); + }, + + dragEmbed() { + // only webkit can handle a blocking div + const {style} = Embedding.media; + if (Embedding.dragEmbed.mouseup) { + $$1.off(d$1, 'mouseup', Embedding.dragEmbed); + Embedding.dragEmbed.mouseup = false; + style.pointerEvents = ''; + return; + } + $$1.on(d$1, 'mouseup', Embedding.dragEmbed); + Embedding.dragEmbed.mouseup = true; + return style.pointerEvents = 'none'; + }, + + title(data) { + let service; + const {key, uid, options, link, post} = data; + if (!(service = Embedding.types[key].title)) { return; } + $$1.addClass(link, key.toLowerCase()); + if (service.batchSize) { + (service.queue || (service.queue = [])).push(data); + if (service.queue.length >= service.batchSize) { + return Embedding.flushTitles(service); + } + } else { + return CrossOrigin$1.cache(service.api(uid), (function() { return Embedding.cb.title(this, data); })); + } + }, + + flushTitles(service) { + let data; + const {queue} = service; + if (!queue?.length) { return; } + service.queue = []; + const cb = function() { + for (data of queue) { Embedding.cb.title(this, data); } + }; + return CrossOrigin$1.cache(service.api((() => { + const result = []; + for (data of queue) { result.push(data.uid); + } + return result; + })()), cb); + }, + + preview(data) { + let service; + const {key, uid, link} = data; + if (!(service = Embedding.types[key].preview)) { return; } + return $$1.on(link, 'mouseover', function(e) { + const src = service.url(uid); + const {height} = service; + const el = $$1.el('img', { + src, + id: 'ihover' + } + ); + $$1.add(Header$1.hover, el); + return UI.hover({ + root: link, + el, + latestEvent: e, + endEvents: 'mouseout click', + height + }); + }); + }, + + cb: { + click(e) { + e.preventDefault(); + if (!$$1.hasClass(this, 'embedded') && (Conf['Floating Embeds'] || $$1.hasClass(doc$1, 'catalog-mode'))) { + let div; + if (!(div = Embedding.media.firstChild)) { return; } + $$1.replace(div, Embedding.cb.embed(this)); + Embedding.lastEmbed = Get$1.postFromNode(this).nodes.root; + return $$1.rmClass(Embedding.dialog, 'empty'); + } else { + return Embedding.cb.toggle.call(this); + } + }, + + toggle() { + if ($$1.hasClass(this, "embedded")) { + $$1.rm(this.nextElementSibling); + } else { + $$1.after(this, Embedding.cb.embed(this)); + } + return $$1.toggleClass(this, 'embedded'); + }, + + embed(a) { + // We create an element to embed + let el, type; + const container = $$1.el('div', {className: 'media-embed'}); + $$1.add(container, (el = (type = Embedding.types[a.dataset.key]).el(a))); + + // Set style values. + el.style.cssText = (type.style != null) ? + type.style + : + 'border: none; width: 640px; height: 360px;'; + + return container; + }, + + catalogRemove() { + const isCatalog = $$1.hasClass(doc$1, 'catalog-mode'); + if ((isCatalog && $$1.hasClass(this, 'embedded')) || (!isCatalog && $$1.hasClass(this, 'embed-removed'))) { + Embedding.cb.toggle.call(this); + return $$1.toggleClass(this, 'embed-removed'); + } + }, + + title(req, data) { + let text; + const {key, uid, options, link, post} = data; + const service = Embedding.types[key].title; + + let {status} = req; + if ([200, 304].includes(status) && service.status) { + status = service.status(req.response)[0]; + } + + if (!status) { return; } + + text = `[${key}] ${(() => { switch (status) { + case 200: case 304: + text = service.text(req.response, uid); + if (typeof text === 'string') { + return text; + } else { + return text = link.textContent; + } + case 404: + return "Not Found"; + case 403: case 401: + return "Forbidden or Private"; + default: + return `${status}'d`; + } })() + }`; + + link.dataset.original = link.textContent; + link.textContent = text; + for (var post2 of post.clones) { + for (var link2 of $$('a.linkify', post2.nodes.comment)) { + if (link2.href === link.href) { + if (link2.dataset.original == null) { link2.dataset.original = link2.textContent; } + link2.textContent = text; + } + } + } + } + }, + + ordered_types: [{ + key: 'audio', + regExp: /^[^?#]+\.(?:mp3|m4a|oga|wav|flac)(?:[?#]|$)/i, + style: '', + el(a) { + return $$1.el('audio', { + controls: true, + preload: 'auto', + src: a.dataset.href + } + ); + } + } + , { + key: 'image', + regExp: /^[^?#]+\.(?:gif|png|jpg|jpeg|bmp|webp)(?::\w+)?(?:[?#]|$)/i, + style: '', + el(a) { + const hrefEsc = E(a.dataset.href); + return $$1.el('div', { innerHTML: ``}); + } + } + , { + key: 'video', + regExp: /^[^?#]+\.(?:og[gv]|webm|mp4)(?:[?#]|$)/i, + style: 'max-width: 80vw; max-height: 80vh;', + el(a) { + const el = $$1.el('video', { + hidden: true, + controls: true, + preload: 'auto', + src: a.dataset.href, + loop: ImageHost.test(a.dataset.href.split('/')[2]) + }); + $$1.on(el, 'loadedmetadata', function() { + if ((el.videoHeight === 0) && el.parentNode) { + return $$1.replace(el, Embedding.types.audio.el(a)); + } else { + return el.hidden = false; + } + }); + return el; + } + } + , { + key: 'PeerTube', + regExp: /^(\w+:\/\/[^\/]+\/videos\/watch\/\w{8}-\w{4}-\w{4}-\w{4}-\w{12})(.*)/, + el(a) { + let start; + const options = (start = a.dataset.options.match(/[?&](start=\w+)/)) ? `?${start[1]}` : ''; + const el = $$1.el('iframe', + {src: a.dataset.uid.replace('/videos/watch/', '/videos/embed/') + options}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + key: 'BitChute', + regExp: /^\w+:\/\/(?:www\.)?bitchute\.com\/video\/([\w\-]+)/, + el(a) { + const el = $$1.el('iframe', + {src: `https://www.bitchute.com/embed/${a.dataset.uid}/`}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + key: 'Clyp', + regExp: /^\w+:\/\/(?:www\.)?clyp\.it\/(\w{8})/, + style: 'border: 0; width: 640px; height: 160px;', + el(a) { + return $$1.el('iframe', + {src: `https://clyp.it/${a.dataset.uid}/widget`}); + }, + title: { + api(uid) { return `https://api.clyp.it/oembed?url=https://clyp.it/${uid}`; }, + text(_) { return _.title; } + } + } + , { + key: 'Dailymotion', + regExp: /^\w+:\/\/(?:(?:www\.)?dailymotion\.com\/(?:embed\/)?video|dai\.ly)\/([A-Za-z0-9]+)[^?]*(.*)/, + el(a) { + let start; + const options = (start = a.dataset.options.match(/[?&](start=\d+)/)) ? `?${start[1]}` : ''; + const el = $$1.el('iframe', + {src: `//www.dailymotion.com/embed/video/${a.dataset.uid}${options}`}); + el.setAttribute("allowfullscreen", "true"); + return el; + }, + title: { + api(uid) { return `https://api.dailymotion.com/video/${uid}`; }, + text(_) { return _.title; } + }, + preview: { + url(uid) { return `https://www.dailymotion.com/thumbnail/video/${uid}`; }, + height: 240 + } + } + , { + key: 'Gfycat', + regExp: /^\w+:\/\/(?:www\.)?gfycat\.com\/(?:iframe\/)?(\w+)/, + el(a) { + const el = $$1.el('iframe', + {src: `//gfycat.com/ifr/${a.dataset.uid}`}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + key: 'Gist', + regExp: /^\w+:\/\/gist\.github\.com\/[\w\-]+\/(\w+)/, + style: '', + el: (function() { + let counter = 0; + return function(a) { + const el = $$1.el('pre', { + hidden: true, + id: `gist-embed-${counter++}` + } + ); + CrossOrigin$1.cache(`https://api.github.com/gists/${a.dataset.uid}`, function() { + el.textContent = Object.values(this.response.files)[0].content; + el.className = 'prettyprint'; + $$1.global(() => window.prettyPrint?.((function() {}), document.getElementById(document.currentScript.dataset.id).parentNode) + , {id: el.id}); + return el.hidden = false; + }); + return el; + }; + })(), + title: { + api(uid) { return `https://api.github.com/gists/${uid}`; }, + text({files}) { + for (var file in files) { if (files.hasOwnProperty(file)) { return file; } } + } + } + } + , { + key: 'InstallGentoo', + regExp: /^\w+:\/\/paste\.installgentoo\.com\/view\/(?:raw\/|download\/|embed\/)?(\w+)/, + el(a) { + return $$1.el('iframe', + {src: `https://paste.installgentoo.com/view/embed/${a.dataset.uid}`}); + } + } + , { + key: 'LiveLeak', + regExp: /^\w+:\/\/(?:\w+\.)?liveleak\.com\/.*\?.*[tif]=(\w+)/, + el(a) { + const el = $$1.el('iframe', + {src: `https://www.liveleak.com/e/${a.dataset.uid}`,}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + 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(a) { + const el = $$1.el('video', { + controls: true, + preload: 'auto', + loop: true + } + ); + if (/^http/.test(a.dataset.uid)) { + $$1.add(el, $$1.el('source', {src: a.dataset.uid})); + return el; + } + const [_, host, names] = Array.from(a.dataset.uid.match(/(\w+)\/(.*)/)); + const types = (() => { switch (host) { + case 'gd': case 'wu': case 'fc': return ['']; + case 'gc': return ['giant', 'fat', 'zippy']; + default: return ['.webm', '.mp4']; + } })(); + for (var name of names.split(',')) { + for (var type of types) { + var base = `${name}${type}`; + var urls = (() => { switch (host) { + // list from src/common.py at http://loopvid.appspot.com/source.html + case 'pf': return [`https://kastden.org/_loopvid_media/pf/${base}`, `https://web.archive.org/web/2/http://a.pomf.se/${base}`]; + case 'kd': return [`https://kastden.org/loopvid/${base}`]; + case 'lv': return [`https://lv.kastden.org/${base}`]; + case 'gd': return [`https://docs.google.com/uc?export=download&id=${base}`]; + case 'gh': return [`https://googledrive.com/host/${base}`]; + case 'db': return [`https://dl.dropboxusercontent.com/u/${base}`]; + case 'dx': return [`https://dl.dropboxusercontent.com/${base}`]; + case 'nn': return [`https://kastden.org/_loopvid_media/nn/${base}`]; + case 'cp': return [`https://copy.com/${base}`]; + case 'wu': return [`http://webmup.com/${base}/vid.webm`]; + case 'ig': return [`https://i.imgur.com/${base}`]; + case 'ky': return [`https://kastden.org/_loopvid_media/ky/${base}`]; + case 'mf': return [`https://kastden.org/_loopvid_media/mf/${base}`, `https://web.archive.org/web/2/https://d.maxfile.ro/${base}`]; + case 'm2': return [`https://kastden.org/_loopvid_media/m2/${base}`]; + case 'pc': return [`https://kastden.org/_loopvid_media/pc/${base}`, `https://web.archive.org/web/2/http://a.pomf.cat/${base}`]; + case '1c': return [`http://b.1339.cf/${base}`]; + case 'pi': return [`https://kastden.org/_loopvid_media/pi/${base}`, `https://web.archive.org/web/2/https://u.pomf.is/${base}`]; + case 'ni': return [`https://kastden.org/_loopvid_media/ni/${base}`, `https://web.archive.org/web/2/https://u.nya.is/${base}`]; + case 'wl': return [`http://webm.land/media/${base}`]; + case 'ko': return [`https://kordy.kastden.org/loopvid/${base}`]; + case 'mm': return [`https://kastden.org/_loopvid_media/mm/${base}`, `https://web.archive.org/web/2/https://my.mixtape.moe/${base}`]; + case 'ic': return [`https://media.8ch.net/file_store/${base}`]; + case 'fc': return [`//${ImageHost.host()}/${base}.webm`]; + case 'gc': return [`https://${type}.gfycat.com/${name}.webm`]; + } })(); + + for (var url of urls) { + $$1.add(el, $$1.el('source', {src: url})); + } + } + } + return el; + } + } + , { + key: 'Openings.moe', + regExp: /^\w+:\/\/openings.moe\/\?video=([^.&=]+)/, + style: 'width: 1280px; height: 720px; max-width: 80vw; max-height: 80vh;', + el(a) { + const el = $$1.el('iframe', + {src: `https://openings.moe/?video=${a.dataset.uid}`,}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + key: 'Pastebin', + regExp: /^\w+:\/\/(?:\w+\.)?pastebin\.com\/(?!u\/)(?:[\w.]+(?:\/|\?i\=))?(\w+)/, + el(a) { + return $$1.el('iframe', + {src: `//pastebin.com/embed_iframe.php?i=${a.dataset.uid}`}); + } + } + , { + key: 'SoundCloud', + regExp: /^\w+:\/\/(?:www\.)?(?:soundcloud\.com\/|snd\.sc\/)([\w\-\/]+)/, + style: 'border: 0; width: 500px; height: 400px;', + el(a) { + return $$1.el('iframe', + {src: `https://w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F${encodeURIComponent(a.dataset.uid)}`}); + }, + title: { + api(uid) { return `${location.protocol}//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F${encodeURIComponent(uid)}`; }, + text(_) { return _.title; } + } + } + , { + key: 'StrawPoll', + regExp: /^\w+:\/\/(?:www\.)?strawpoll\.me\/(?:embed_\d+\/)?(\d+(?:\/r)?)/, + style: 'border: 0; width: 600px; height: 406px;', + el(a) { + return $$1.el('iframe', + {src: `https://www.strawpoll.me/embed_1/${a.dataset.uid}`}); + } + } + , { + key: 'Streamable', + regExp: /^\w+:\/\/(?:www\.)?streamable\.com\/(\w+)/, + el(a) { + const el = $$1.el('iframe', + {src: `https://streamable.com/o/${a.dataset.uid}`}); + el.setAttribute("allowfullscreen", "true"); + return el; + }, + title: { + api(uid) { return `https://api.streamable.com/oembed?url=https://streamable.com/${uid}`; }, + text(_) { return _.title; } + } + } + , { + key: 'TwitchTV', + regExp: /^\w+:\/\/(?:www\.|secure\.|clips\.|m\.)?twitch\.tv\/(\w[^#\&\?]*)/, + el(a) { + let url; + let m = a.dataset.href.match(/^\w+:\/\/(?:(clips\.)|\w+\.)?twitch\.tv\/(?:\w+\/)?(clip\/)?(\w[^#\&\?]*)/); + if (m[1] || m[2]) { + url = `//clips.twitch.tv/embed?clip=${m[3]}&parent=${location.hostname}`; + } else { + let time; + m = a.dataset.uid.match(/(\w+)(?:\/(?:v\/)?(\d+))?/); + url = `//player.twitch.tv/?${m[2] ? `video=v${m[2]}` : `channel=${m[1]}`}&autoplay=false&parent=${location.hostname}`; + if (time = a.dataset.href.match(/\bt=(\w+)/)) { + url += `&time=${time[1]}`; + } + } + const el = $$1.el('iframe', + {src: url}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + key: 'Twitter', + regExp: /^\w+:\/\/(?:www\.|mobile\.)?twitter\.com\/(\w+\/status\/\d+)/, + style: 'border: none; width: 550px; height: 250px; overflow: hidden; resize: both;', + el(a) { + const el = $$1.el('iframe'); + $$1.on(el, 'load', function() { + return this.contentWindow.postMessage({element: 't', query: 'height'}, 'https://twitframe.com'); + }); + var onMessage = function(e) { + if ((e.source === el.contentWindow) && (e.origin === 'https://twitframe.com')) { + $$1.off(window, 'message', onMessage); + return (cont || el).style.height = `${+$$1.minmax(e.data.height, 250, 0.8 * doc$1.clientHeight)}px`; + } + }; + $$1.on(window, 'message', onMessage); + el.src = `https://twitframe.com/show?url=https://twitter.com/${a.dataset.uid}`; + if ($$1.engine === 'gecko') { + // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=680823 + el.style.cssText = 'border: none; width: 100%; height: 100%;'; + var cont = $$1.el('div'); + $$1.add(cont, el); + return cont; + } else { + return el; + } + } + } + , { + key: 'VidLii', + regExp: /^\w+:\/\/(?:www\.)?vidlii\.com\/watch\?v=(\w{11})/, + style: 'border: none; width: 640px; height: 392px;', + el(a) { + const el = $$1.el('iframe', + {src: `https://www.vidlii.com/embed?v=${a.dataset.uid}&a=0`}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + key: 'Vimeo', + regExp: /^\w+:\/\/(?:www\.)?vimeo\.com\/(\d+)/, + el(a) { + const el = $$1.el('iframe', + {src: `//player.vimeo.com/video/${a.dataset.uid}?wmode=opaque`}); + el.setAttribute("allowfullscreen", "true"); + return el; + }, + title: { + api(uid) { return `https://vimeo.com/api/oembed.json?url=https://vimeo.com/${uid}`; }, + text(_) { return _.title; } + } + } + , { + key: 'Vine', + regExp: /^\w+:\/\/(?:www\.)?vine\.co\/v\/(\w+)/, + style: 'border: none; width: 500px; height: 500px;', + el(a) { + return $$1.el('iframe', + {src: `https://vine.co/v/${a.dataset.uid}/card`}); + } + } + , { + key: 'Vocaroo', + regExp: /^\w+:\/\/(?:(?:www\.|old\.)?vocaroo\.com|voca\.ro)\/((?:i\/)?\w+)/, + style: '', + el(a) { + const el = $$1.el('iframe'); + el.width = 300; + el.height = 60; + el.setAttribute('frameborder', 0); + el.src = `https://vocaroo.com/embed/${a.dataset.uid.replace(/^i\//, '')}?autoplay=0`; + return el; + } + } + , { + key: 'YouTube', + regExp: /^\w+:\/\/(?:youtu.be\/|[\w.]*youtube[\w.]*\/.*(?:v=|\bembed\/|\bv\/|live\/))([\w\-]{11})(.*)/, + el(a) { + let start = a.dataset.options.match(/\b(?:star)?t\=(\w+)/); + if (start) { start = start[1]; } + if (start && !/^\d+$/.test(start)) { + start += ' 0h0m0s'; + start = (3600 * start.match(/(\d+)h/)[1]) + (60 * start.match(/(\d+)m/)[1]) + (1 * start.match(/(\d+)s/)[1]); + } + const el = $$1.el('iframe', + {src: `//www.youtube.com/embed/${a.dataset.uid}?rel=0&wmode=opaque${start ? '&start=' + start : ''}`}); + el.setAttribute("allowfullscreen", "true"); + return el; + }, + title: { + api(uid) { return `https://www.youtube.com/oembed?url=https%3A//www.youtube.com/watch%3Fv%3D${uid}&format=json`; }, + text(_) { return _.title; }, + status(_) { + if (_.error) { + const m = _.error.match(/^(\d*)\s*(.*)/); + return [+m[1], m[2]]; + } else { + return [200, 'OK']; + } + } + }, + preview: { + url(uid) { return `https://img.youtube.com/vi/${uid}/0.jpg`; }, + height: 360 + } + } + ] + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Keybinds = { + init() { + if (!Conf['Keybinds']) { return; } + + for (var hotkey in Config.hotkeys) { + $$1.sync(hotkey, Keybinds.sync); + } + + var init = function() { + $$1.off(d$1, '4chanXInitFinished', init); + $$1.on(d$1, 'keydown', Keybinds.keydown); + for (var node of $$('[accesskey]')) { + node.removeAttribute('accesskey'); + } + }; + return $$1.on(d$1, '4chanXInitFinished', init); + }, + + sync(key, hotkey) { + return Conf[hotkey] = key; + }, + + keydown(e) { + let key, thread, threadRoot; + let catalog, notifications; + if (!(key = Keybinds.keyCode(e))) { return; } + const {target} = e; + if (['INPUT', 'TEXTAREA'].includes(target.nodeName)) { + if (!/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(key) || !!/^Alt\+(\d|Up|Down|Left|Right)$/.test(key)) { return; } + } + if (['index', 'thread'].includes(g.VIEW)) { + threadRoot = Nav.getThread(); + thread = Get$1.threadFromRoot(threadRoot); + } + switch (key) { + // QR & Options + case Conf['Toggle board list']: + if (!Conf['Custom Board Navigation']) { return; } + Header$1.toggleBoardList(); + break; + case Conf['Toggle header']: + Header$1.toggleBarVisibility(); + break; + case Conf['Open empty QR']: + if (!QR.postingIsEnabled) { return; } + Keybinds.qr(); + break; + case Conf['Open QR']: + if (!QR.postingIsEnabled || !threadRoot) { return; } + Keybinds.qr(threadRoot); + break; + case Conf['Open settings']: + Settings.open(); + break; + case Conf['Close']: + if (Settings.dialog) { + Settings.close(); + } else if ((notifications = $$('.notification')).length) { + for (var notification of notifications) { + $$1('.close', notification).click(); + } + } else if (QR.nodes && !(QR.nodes.el.hidden || (window.getComputedStyle(QR.nodes.form).display === 'none'))) { + if (Conf['Persistent QR']) { + QR.hide(); + } else { + QR.close(); + } + } else if (Embedding.lastEmbed) { + Embedding.closeFloat(); + } else { + return; + } + break; + case Conf['Spoiler tags']: + if (target.nodeName !== 'TEXTAREA') { return; } + Keybinds.tags('spoiler', target); + break; + case Conf['Code tags']: + if (target.nodeName !== 'TEXTAREA') { return; } + Keybinds.tags('code', target); + break; + case Conf['Eqn tags']: + if (target.nodeName !== 'TEXTAREA') { return; } + Keybinds.tags('eqn', target); + break; + case Conf['Math tags']: + if (target.nodeName !== 'TEXTAREA') { return; } + Keybinds.tags('math', target); + break; + case Conf['SJIS tags']: + if (target.nodeName !== 'TEXTAREA') { return; } + Keybinds.tags('sjis', target); + break; + case Conf['Toggle sage']: + if (!QR.nodes || !!QR.nodes.el.hidden) { return; } + Keybinds.sage(); + break; + case Conf['Toggle Cooldown']: + if (!QR.nodes || !!QR.nodes.el.hidden || !$$1.hasClass(QR.nodes.fileSubmit, 'custom-cooldown')) { return; } + QR.toggleCustomCooldown(); + break; + case Conf['Post from URL']: + if (!QR.postingIsEnabled) { return; } + QR.handleUrl(''); + break; + case Conf['Add new post']: + if (!QR.postingIsEnabled) { return; } + QR.addPost(); + break; + case Conf['Submit QR']: + if (!QR.nodes || !!QR.nodes.el.hidden) { return; } + if (!QR.status()) { QR.submit(); } + break; + // Index/Thread related + case Conf['Update']: + switch (g.VIEW) { + case 'thread': + if (!ThreadUpdater.enabled) { return; } + ThreadUpdater.update(); + break; + case 'index': + if (!Index$1.enabled) { return; } + Index$1.update(); + break; + default: + return; + } + break; + case Conf['Watch']: + if (!ThreadWatcher$1.enabled || !thread) { return; } + ThreadWatcher$1.toggle(thread); + break; + case Conf['Update thread watcher']: + if (!ThreadWatcher$1.enabled) { return; } + ThreadWatcher$1.buttonFetchAll(); + break; + case Conf['Toggle thread watcher']: + if (!ThreadWatcher$1.enabled) { return; } + ThreadWatcher$1.toggleWatcher(); + break; + case Conf['Toggle threading']: + if (!QuoteThreading.ready) { return; } + QuoteThreading.toggleThreading(); + break; + case Conf['Mark thread read']: + if ((g.VIEW !== 'index') || !thread || !UnreadIndex.enabled) { return; } + UnreadIndex.markRead.call(threadRoot); + break; + // Images + case Conf['Expand image']: + if (!ImageExpand.enabled || !threadRoot) { return; } + var post = Get$1.postFromNode(Keybinds.post(threadRoot)); + if (post.file) { ImageExpand.toggle(post); } + break; + case Conf['Expand images']: + if (!ImageExpand.enabled) { return; } + ImageExpand.cb.toggleAll(); + break; + case Conf['Open Gallery']: + if (!Gallery.enabled) { return; } + Gallery.cb.toggle(); + break; + case Conf['fappeTyme']: + if (!FappeTyme.nodes?.fappe) { return; } + FappeTyme.toggle('fappe'); + break; + case Conf['werkTyme']: + if (!FappeTyme.nodes?.werk) { return; } + FappeTyme.toggle('werk'); + break; + // Board Navigation + case Conf['Front page']: + if (Index$1.enabled) { + Index$1.userPageNav(1); + } else { + location.href = `/${g.BOARD}/`; + } + break; + case Conf['Open front page']: + $$1.open(`${location.origin}/${g.BOARD}/`); + break; + case Conf['Next page']: + if ((g.VIEW !== 'index') || !!g.SITE.isOnePage?.(g.BOARD)) { return; } + if (Index$1.enabled) { + if (!['paged', 'infinite'].includes(Conf['Index Mode'])) { return; } + $$1('.next button', Index$1.pagelist).click(); + } else { + $$1(g.SITE.selectors.nav.next)?.click(); + } + break; + case Conf['Previous page']: + if ((g.VIEW !== 'index') || !!g.SITE.isOnePage?.(g.BOARD)) { return; } + if (Index$1.enabled) { + if (!['paged', 'infinite'].includes(Conf['Index Mode'])) { return; } + $$1('.prev button', Index$1.pagelist).click(); + } else { + $$1(g.SITE.selectors.nav.prev)?.click(); + } + break; + case Conf['Search form']: + if (g.VIEW !== 'index') { return; } + var searchInput = Index$1.enabled ? + Index$1.searchInput + : g.SITE.selectors.searchBox ? + $$1(g.SITE.selectors.searchBox) + : + undefined; + if (!searchInput) { return; } + Header$1.scrollToIfNeeded(searchInput); + searchInput.focus(); + break; + case Conf['Paged mode']: + if (!Index$1.enabledOn(g.BOARD)) { return; } + location.href = g.VIEW === 'index' ? '#paged' : `/${g.BOARD}/#paged`; + break; + case Conf['Infinite scrolling mode']: + if (!Index$1.enabledOn(g.BOARD)) { return; } + location.href = g.VIEW === 'index' ? '#infinite' : `/${g.BOARD}/#infinite`; + break; + case Conf['All pages mode']: + if (!Index$1.enabledOn(g.BOARD)) { return; } + location.href = g.VIEW === 'index' ? '#all-pages' : `/${g.BOARD}/#all-pages`; + break; + case Conf['Open catalog']: + if (!(catalog = CatalogLinks.catalog())) { return; } + location.href = catalog; + break; + case Conf['Cycle sort type']: + if (!Index$1.enabled) { return; } + Index$1.cycleSortType(); + break; + // Thread Navigation + case Conf['Next thread']: + if ((g.VIEW !== 'index') || !threadRoot) { return; } + Nav.scroll(+1); + break; + case Conf['Previous thread']: + if ((g.VIEW !== 'index') || !threadRoot) { return; } + Nav.scroll(-1); + break; + case Conf['Expand thread']: + if ((g.VIEW !== 'index') || !threadRoot) { return; } + ExpandThread.toggle(thread); + // Keep thread from moving off screen when contracted. + Header$1.scrollTo(threadRoot); + break; + case Conf['Open thread']: + if ((g.VIEW !== 'index') || !threadRoot) { return; } + Keybinds.open(thread); + break; + case Conf['Open thread tab']: + if ((g.VIEW !== 'index') || !threadRoot) { return; } + Keybinds.open(thread, true); + break; + // Reply Navigation + case Conf['Next reply']: + if (!threadRoot) { return; } + Keybinds.hl(+1, threadRoot); + break; + case Conf['Previous reply']: + if (!threadRoot) { return; } + Keybinds.hl(-1, threadRoot); + break; + case Conf['Deselect reply']: + if (!threadRoot) { return; } + Keybinds.hl(0, threadRoot); + break; + case Conf['Hide']: + if (!thread || !ThreadHiding.db) { return; } + Header$1.scrollTo(threadRoot); + ThreadHiding.toggle(thread); + break; + case Conf['Quick Filter MD5']: + if (!threadRoot) { return; } + post = Keybinds.post(threadRoot); + Keybinds.hl(+1, threadRoot); + Filter.quickFilterMD5.call(post, e); + break; + case Conf['Previous Post Quoting You']: + if (!threadRoot || !QuoteYou.db) { return; } + QuoteYou.cb.seek('preceding'); + break; + case Conf['Next Post Quoting You']: + if (!threadRoot || !QuoteYou.db) { return; } + QuoteYou.cb.seek('following'); + break; + default: + return; + } + e.preventDefault(); + return e.stopPropagation(); + }, + + keyCode(e) { + let key = (() => { let kc; + switch ((kc = e.keyCode)) { + case 8: // return + 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: + if ((48 <= kc && kc <= 57) || (65 <= kc && kc <= 90)) { // 0-9, A-Z + return String.fromCharCode(kc).toLowerCase(); + } else if (96 <= kc && kc <= 105) { // numpad 0-9 + return String.fromCharCode(kc - 48).toLowerCase(); + } else { + return null; + } + } })(); + if (key) { + if (e.altKey) { key = 'Alt+' + key; } + if (e.ctrlKey) { key = 'Ctrl+' + key; } + if (e.metaKey) { key = 'Meta+' + key; } + if (e.shiftKey) { key = 'Shift+' + key; } + } + return key; + }, + + post(thread) { + const s = g.SITE.selectors; + return ( + $$1(`${s.postContainer}${s.highlightable.reply}.${g.SITE.classes.highlight}`, thread) || + $$1(`${g.SITE.isOPContainerThread ? s.thread : s.postContainer}${s.highlightable.op}`, thread) + ); + }, + + qr(thread) { + QR.open(); + if (thread != null) { + QR.quote.call(Keybinds.post(thread)); + } + return QR.nodes.com.focus(); + }, + + tags(tag, ta) { + BoardConfig.ready(function() { + const {config} = g.BOARD; + const supported = (() => { switch (tag) { + case 'spoiler': return !!config.spoilers; + case 'code': return !!config.code_tags; + case 'math': case 'eqn': return !!config.math_tags; + case 'sjis': return !!config.sjis_tags; + } })(); + if (!supported) { return new Notice('warning', `[${tag}] tags are not supported on /${g.BOARD}/.`, 20); } + }); + + const { + value + } = ta; + const selStart = ta.selectionStart; + const selEnd = ta.selectionEnd; + + ta.value = + value.slice(0, selStart) + + `[${tag}]` + value.slice(selStart, selEnd) + `[/${tag}]` + + value.slice(selEnd); + + // Move the caret to the end of the selection. + const range = (`[${tag}]`).length + selEnd; + ta.setSelectionRange(range, range); + + // Fire the 'input' event + return $$1.event('input', null, ta); + }, + + sage() { + const isSage = /sage/i.test(QR.nodes.email.value); + return QR.nodes.email.value = isSage ? + "" + : "sage"; + }, + + open(thread, tab) { + if (g.VIEW !== 'index') { return; } + const url = Get$1.url('thread', thread); + if (tab) { + return $$1.open(url); + } else { + return location.href = url; + } + }, + + hl(delta, thread) { + const replySelector = `${g.SITE.selectors.postContainer}${g.SITE.selectors.highlightable.reply}`; + const {highlight} = g.SITE.classes; + + const postEl = $$1(`${replySelector}.${highlight}`, thread); + + if (!delta) { + if (postEl) { $$1.rmClass(postEl, highlight); } + return; + } + + if (postEl) { + const {height} = postEl.getBoundingClientRect(); + if ((Header$1.getTopOf(postEl) >= -height) && (Header$1.getBottomOf(postEl) >= -height)) { // We're at least partially visible + let next; + const {root} = Get$1.postFromNode(postEl).nodes; + const axis = delta === +1 ? + 'following' + : + 'preceding'; + if (!(next = $$1.x(`${axis}-sibling::${g.SITE.xpath.replyContainer}[not(@hidden) and not(child::div[@class='stub'])][1]`, root))) { return; } + if (!next.matches(replySelector)) { next = $$1(replySelector, next); } + Header$1.scrollToIfNeeded(next, delta === +1); + $$1.addClass(next, highlight); + $$1.rmClass(postEl, highlight); + return; + } + $$1.rmClass(postEl, highlight); + } + + const replies = $$(replySelector, thread); + if (delta === -1) { replies.reverse(); } + for (var reply of replies) { + if (((delta === +1) && (Header$1.getTopOf(reply) > 0)) || ((delta === -1) && (Header$1.getBottomOf(reply) > 0))) { + $$1.addClass(reply, highlight); + return; + } + } + } + }; + + const Captcha = { + Cache: { + init() { + $$1.on(d$1, 'SaveCaptcha', e => { + return this.saveAPI(e.detail); + }); + return $$1.on(d$1, 'NoCaptcha', e => { + return this.noCaptcha(e.detail); + }); + }, + + captchas: [], + + getCount() { + return this.captchas.length; + }, + + neededRaw() { + return !( + this.haveCookie() || this.captchas.length || QR.req || this.submitCB + ) && ( + (QR.posts.length > 1) || Conf['Auto-load captcha'] || !QR.posts[0].isOnlyQuotes() || QR.posts[0].file + ); + }, + + needed() { + return this.neededRaw() && $$1.event('LoadCaptcha'); + }, + + prerequest() { + if (!Conf['Prerequest Captcha']) { return; } + // Post count temporarily off by 1 when called from QR.post.rm, QR.close, or QR.submit + return $$1.queueTask(() => { + if ( + !this.prerequested && + this.neededRaw() && + !$$1.event('LoadCaptcha') && + !QR.captcha.occupied() && + (QR.cooldown.seconds <= 60) && + (QR.selected === QR.posts[QR.posts.length - 1]) && + !QR.selected.isOnlyQuotes() + ) { + const isReply = (QR.selected.thread !== 'new'); + if (!$$1.event('RequestCaptcha', { isReply })) { + this.prerequested = true; + this.submitCB = captcha => { + if (captcha) { return this.save(captcha); } + }; + return this.updateCount(); + } + } + }); + }, + + haveCookie() { + return /\b_ct=/.test(d$1.cookie) && (QR.posts[0].thread !== 'new'); + }, + + getOne() { + let captcha; + delete this.prerequested; + this.clear(); + if (captcha = this.captchas.shift()) { + this.count(); + return captcha; + } else { + return null; + } + }, + + request(isReply) { + if (!this.submitCB) { + if ($$1.event('RequestCaptcha', { isReply })) { return; } + } + return cb => { + this.submitCB = cb; + return this.updateCount(); + }; + }, + + abort() { + if (this.submitCB) { + delete this.submitCB; + $$1.event('AbortCaptcha'); + return this.updateCount(); + } + }, + + saveAPI(captcha) { + let cb; + if (cb = this.submitCB) { + delete this.submitCB; + cb(captcha); + return this.updateCount(); + } else { + return this.save(captcha); + } + }, + + noCaptcha(detail) { + let cb; + if (cb = this.submitCB) { + if (!this.haveCookie() || detail?.error) { + QR.error(detail?.error || 'Failed to retrieve captcha.'); + QR.captcha.setup(d$1.activeElement === QR.nodes.status); + } + delete this.submitCB; + cb(); + return this.updateCount(); + } + }, + + save(captcha) { + let cb; + if (cb = this.submitCB) { + this.abort(); + cb(captcha); + return; + } + this.captchas.push(captcha); + this.captchas.sort((a, b) => a.timeout - b.timeout); + return this.count(); + }, + + clear() { + if (this.captchas.length) { + let i; + const now = Date.now(); + for (i = 0; i < this.captchas.length; i++) { + var captcha = this.captchas[i]; + if (captcha.timeout > now) { break; } + } + if (i) { + this.captchas = this.captchas.slice(i); + return this.count(); + } + } + }, + + count() { + clearTimeout(this.timer); + if (this.captchas.length) { + this.timer = setTimeout(this.clear.bind(this), this.captchas[0].timeout - Date.now()); + } + return this.updateCount(); + }, + + updateCount() { + return $$1.event('CaptchaCount', this.captchas.length); + } + }, Replace: CaptchaReplace, t: CaptchaT, v2: { + lifetime: 2 * MINUTE, + + init() { + if (d$1.cookie.indexOf('pass_enabled=1') >= 0) { return; } + if (!(this.isEnabled = !!$$1('#g-recaptcha, #captcha-forced-noscript') || !$$1.id('postForm'))) { return; } + + if (this.noscript = Conf['Force Noscript Captcha'] || !Main$1.jsEnabled) { + $$1.addClass(QR.nodes.el, 'noscript-captcha'); + } + + Captcha.cache.init(); + $$1.on(d$1, 'CaptchaCount', this.count.bind(this)); + + const root = $$1.el('div', { className: 'captcha-root' }); + $$1.extend(root, { + innerHTML: + '
          ' + } + ); + const counter = $$1('.captcha-counter > a', root); + this.nodes = { root, counter }; + this.count(); + $$1.addClass(QR.nodes.el, 'has-captcha', 'captcha-v2'); + $$1.after(QR.nodes.com.parentNode, root); + + $$1.on(counter, 'click', this.toggle.bind(this)); + $$1.on(counter, 'keydown', e => { + if (Keybinds.keyCode(e) !== 'Space') { return; } + this.toggle(); + e.preventDefault(); + return e.stopPropagation(); + }); + return $$1.on(window, 'captcha:success', () => { + // XXX Greasemonkey 1.x workaround to gain access to GM_* functions. + return $$1.queueTask(() => this.save(false)); + }); + }, + + timeouts: {}, + prevNeeded: 0, + + noscriptURL() { + let lang; + let url = `https://www.google.com/recaptcha/api/fallback?k=${meta.recaptchaKey}`; + if (lang = Conf['captchaLanguage'].trim()) { + url += `&hl=${encodeURIComponent(lang)}`; + } + return url; + }, + + moreNeeded() { + // Post count temporarily off by 1 when called from QR.post.rm, QR.close, or QR.submit + return $$1.queueTask(() => { + const needed = Captcha.cache.needed(); + if (needed && !this.prevNeeded) { + this.setup(QR.cooldown.auto && (d$1.activeElement === QR.nodes.status)); + } + return this.prevNeeded = needed; + }); + }, + + toggle() { + if (this.nodes.container && !this.timeouts.destroy) { + return this.destroy(); + } else { + return this.setup(true, true); + } + }, + + setup(focus, force) { + if (!this.isEnabled || (!Captcha.cache.needed() && !force)) { return; } + + if (focus) { + $$1.addClass(QR.nodes.el, 'focus'); + this.nodes.counter.focus(); + } + + if (this.timeouts.destroy) { + clearTimeout(this.timeouts.destroy); + delete this.timeouts.destroy; + return this.reload(); + } + + if (this.nodes.container) { + // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=1226835 + $$1.queueTask(() => { + let iframe; + if (this.nodes.container && (d$1.activeElement === this.nodes.counter) && (iframe = $$1('iframe[src^="https://www.google.com/recaptcha/"]', this.nodes.container))) { + iframe.focus(); + return QR.focus(); + } + }); // Event handler not fired in Firefox + return; + } + + this.nodes.container = $$1.el('div', { className: 'captcha-container' }); + $$1.prepend(this.nodes.root, this.nodes.container); + new MutationObserver(this.afterSetup.bind(this)).observe(this.nodes.container, { + childList: true, + subtree: true + } + ); + + if (this.noscript) { + return this.setupNoscript(); + } else { + return this.setupJS(); + } + }, + + setupNoscript() { + const iframe = $$1.el('iframe', { + id: 'qr-captcha-iframe', + scrolling: 'no', + src: this.noscriptURL() + } + ); + const div = $$1.el('div'); + const textarea = $$1.el('textarea'); + $$1.add(div, textarea); + return $$1.add(this.nodes.container, [iframe, div]); + }, + + setupJS() { + return $$1.global(function () { + const render = function () { + const { classList } = document.documentElement; + const container = document.querySelector('#qr .captcha-container'); + return container.dataset.widgetID = window.grecaptcha.render(container, { + sitekey: meta.recaptchaKey, + theme: classList.contains('tomorrow') || classList.contains('spooky') || classList.contains('dark-captcha') ? 'dark' : 'light', + callback(response) { + return window.dispatchEvent(new CustomEvent('captcha:success', { detail: response })); + } + } + ); + }; + if (window.grecaptcha) { + return render(); + } else { + const cbNative = window.onRecaptchaLoaded; + window.onRecaptchaLoaded = function () { + render(); + return cbNative(); + }; + if (!document.head.querySelector('script[src^="https://www.google.com/recaptcha/api.js"]')) { + const script = document.createElement('script'); + script.src = 'https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoaded&render=explicit'; + return document.head.appendChild(script); + } + } + }); + }, + + afterSetup(mutations) { + for (var mutation of mutations) { + for (var node of mutation.addedNodes) { + var iframe, textarea; + if (iframe = $$1.x('./descendant-or-self::iframe[starts-with(@src, "https://www.google.com/recaptcha/")]', node)) { this.setupIFrame(iframe); } + if (textarea = $$1.x('./descendant-or-self::textarea', node)) { this.setupTextArea(textarea); } + } + } + }, + + setupIFrame(iframe) { + let needle; + if (!doc.contains(iframe)) { return; } + Captcha.replace.iframe(iframe); + $$1.addClass(QR.nodes.el, 'captcha-open'); + this.fixQRPosition(); + $$1.on(iframe, 'load', this.fixQRPosition); + if (d$1.activeElement === this.nodes.counter) { iframe.focus(); } + // XXX Make sure scroll on space prevention (see src/css/style.css) doesn't cause scrolling of div + if (['blink', 'edge'].includes($$1.engine) && (needle = iframe.parentNode, $$('#qr .captcha-container > div > div:first-of-type').includes(needle))) { + return $$1.on(iframe.parentNode, 'scroll', function () { return this.scrollTop = 0; }); + } + }, + + fixQRPosition() { + if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) { + QR.nodes.el.style.top = ''; + return QR.nodes.el.style.bottom = '0px'; + } + }, + + setupTextArea(textarea) { + return $$1.one(textarea, 'input', () => this.save(true)); + }, + + destroy() { + if (!this.isEnabled) { return; } + delete this.timeouts.destroy; + $$1.rmClass(QR.nodes.el, 'captcha-open'); + if (this.nodes.container) { + $$1.global(function () { + const container = document.querySelector('#qr .captcha-container'); + return window.grecaptcha.reset(container.dataset.widgetID); + }); + $$1.rm(this.nodes.container); + return delete this.nodes.container; + } + }, + + getOne(isReply) { + return Captcha.cache.getOne(isReply); + }, + + save(pasted, token) { + Captcha.cache.save({ + response: token || $$1('textarea', this.nodes.container).value, + timeout: Date.now() + this.lifetime + }); + + const focus = (d$1.activeElement?.nodeName === 'IFRAME') && /https?:\/\/www\.google\.com\/recaptcha\//.test(d$1.activeElement.src); + if (Captcha.cache.needed()) { + if (focus) { + if (QR.cooldown.auto || Conf['Post on Captcha Completion']) { + this.nodes.counter.focus(); + } else { + QR.nodes.status.focus(); + } + } + this.reload(); + } else { + if (pasted) { + this.destroy(); + } else { + if (this.timeouts.destroy == null) { this.timeouts.destroy = setTimeout(this.destroy.bind(this), 3 * SECOND); } + } + if (focus) { QR.nodes.status.focus(); } + } + + if (Conf['Post on Captcha Completion'] && !QR.cooldown.auto) { return QR.submit(); } + }, + + count() { + const count = Captcha.cache.getCount(); + const loading = Captcha.cache.submitCB ? '...' : ''; + this.nodes.counter.textContent = `Captchas: ${count}${loading}`; + return this.moreNeeded(); + }, + + reload() { + if ($$1('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', this.nodes.container)) { + this.destroy(); + return this.setup(false, true); + } else { + return $$1.global(function () { + const container = document.querySelector('#qr .captcha-container'); + return window.grecaptcha.reset(container.dataset.widgetID); + }); + } + }, + + occupied() { + return !!this.nodes.container && !this.timeouts.destroy; + } + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS202: Simplify dynamic range loops + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var QR = { + 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 sc; + if (!Conf['Quick Reply']) { return; } + + this.posts = []; + + $$1.on(d$1, '4chanXInitFinished', () => BoardConfig.ready(QR.initReady)); + + Callbacks.Post.push({ + name: 'Quick Reply', + cb: this.node + }); + + this.shortcut = (sc = $$1.el('a', { + className: 'disabled', + textContent: '↩', + title: 'Quick Reply', + href: 'javascript:;' + } + )); + $$1.on(sc, 'click', function() { + if (!QR.postingIsEnabled) { return; } + if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) { + QR.open(); + return QR.nodes.com.focus(); + } else { + return QR.close(); + } + }); + + return Header$1.addShortcut('qr', sc, 540); + }, + + initReady() { + let origToggle; + const captchaVersion = $$1('#g-recaptcha, #captcha-forced-noscript') ? 'v2' : 't'; + QR.captcha = Captcha[captchaVersion]; + QR.postingIsEnabled = true; + + const {config} = g.BOARD; + const prop = (key, def) => +(config[key] ?? def); + + QR.min_width = prop('min_image_width', 1); + QR.min_height = prop('min_image_height', 1); + QR.max_width = (QR.max_height = 10000); + + QR.max_size = prop('max_filesize', 4194304); + QR.max_size_video = prop('max_webm_filesize', QR.max_size); + QR.max_comment = prop('max_comment_chars', 2000); + + QR.max_width_video = (QR.max_height_video = 2048); + QR.max_duration_video = prop('max_webm_duration', 120); + + QR.forcedAnon = !!config.forced_anon; + QR.spoiler = !!config.spoilers; + + if (origToggle = $$1.id('togglePostFormLink')) { + const link = $$1.el('h1', + {className: "qr-link-container"}); + $$1.extend(link, { + innerHTML: + `${g.VIEW === "thread" ? "Reply to Thread" : "Start a Thread"}` + }); + + QR.link = link.firstElementChild; + $$1.on(link.firstChild, 'click', function() { + QR.open(); + return QR.nodes.com.focus(); + }); + + $$1.before(origToggle, link); + origToggle.firstElementChild.textContent = 'Original Form'; + } + + if (g.VIEW === 'thread') { + let navLinksBot; + const linkBot = $$1.el('div', + {className: "brackets-wrap qr-link-container-bottom"}); + $$1.extend(linkBot, {innerHTML: 'Reply to Thread'}); + + $$1.on(linkBot.firstElementChild, 'click', function() { + QR.open(); + return QR.nodes.com.focus(); + }); + + if (navLinksBot = $$1('.navLinksBot')) { $$1.prepend(navLinksBot, linkBot); } + } + + $$1.on(d$1, 'QRGetFile', QR.getFile); + $$1.on(d$1, 'QRDrawFile', QR.drawFile); + $$1.on(d$1, 'QRSetFile', QR.setFile); + + $$1.on(d$1, 'paste', QR.paste); + $$1.on(d$1, 'dragover', QR.dragOver); + $$1.on(d$1, 'drop', QR.dropFile); + $$1.on(d$1, 'dragstart dragend', QR.drag); + + $$1.on(d$1, 'IndexRefreshInternal', QR.generatePostableThreadsList); + $$1.on(d$1, 'ThreadUpdate', QR.statusCheck); + + if (!Conf['Persistent QR']) { return; } + QR.open(); + if (Conf['Auto Hide QR']) { return QR.hide(); } + }, + + statusCheck() { + if (!QR.nodes) { return; } + const {thread} = QR.posts[0]; + if ((thread !== 'new') && g.threads.get(`${g.BOARD}.${thread}`).isDead) { + return QR.abort(); + } else { + return QR.status(); + } + }, + + node() { + $$1.on(this.nodes.quote, 'click', QR.quote); + if (this.isFetchedQuote) { return QR.generatePostableThreadsList(); } + }, + + open() { + if (QR.nodes) { + if (QR.nodes.el.hidden) { QR.captcha.setup(); } + QR.nodes.el.hidden = false; + QR.unhide(); + } else { + try { + QR.dialog(); + } catch (err) { + delete QR.nodes; + Main$1.handleErrors({ + message: 'Quick Reply dialog creation crashed.', + error: err + }); + return; + } + } + return $$1.rmClass(QR.shortcut, 'disabled'); + }, + + close() { + if (QR.req) { + QR.abort(); + return; + } + QR.nodes.el.hidden = true; + QR.cleanNotifications(); + QR.blur(); + $$1.rmClass(QR.nodes.el, 'dump'); + $$1.addClass(QR.shortcut, 'disabled'); + new QR.post(true); + for (var post of QR.posts.splice(0, QR.posts.length - 1)) { + post.delete(); + } + QR.cooldown.auto = false; + QR.status(); + return QR.captcha.destroy(); + }, + + focus() { + return $$1.queueTask(function() { + if (!QR.inBubble()) { + QR.hasFocus = d$1.activeElement && QR.nodes.el.contains(d$1.activeElement); + return QR.nodes.el.classList.toggle('focus', QR.hasFocus); + } + }); + }, + + inBubble() { + const bubbles = $$('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); + return bubbles.includes(d$1.activeElement) || bubbles.some(el => (getComputedStyle(el).visibility !== 'hidden') && (el.getBoundingClientRect().bottom > 0)); + }, + + hide() { + QR.blur(); + $$1.addClass(QR.nodes.el, 'autohide'); + return QR.nodes.autohide.checked = true; + }, + + unhide() { + $$1.rmClass(QR.nodes.el, 'autohide'); + return QR.nodes.autohide.checked = false; + }, + + toggleHide() { + if (this.checked) { + return QR.hide(); + } else { + return QR.unhide(); + } + }, + + blur() { + if (QR.nodes.el.contains(d$1.activeElement)) { return d$1.activeElement.blur(); } + }, + + toggleSJIS(e) { + e.preventDefault(); + Conf['sjisPreview'] = !Conf['sjisPreview']; + $$1.set('sjisPreview', Conf['sjisPreview']); + return QR.nodes.el.classList.toggle('sjis-preview', Conf['sjisPreview']); + }, + + texPreviewShow() { + if ($$1.hasClass(QR.nodes.el, 'tex-preview')) { return QR.texPreviewHide(); } + $$1.addClass(QR.nodes.el, 'tex-preview'); + QR.nodes.texPreview.textContent = QR.nodes.com.value; + return $$1.event('mathjax', null, QR.nodes.texPreview); + }, + + texPreviewHide() { + return $$1.rmClass(QR.nodes.el, 'tex-preview'); + }, + + addPost() { + const wasOpen = (QR.nodes && !QR.nodes.el.hidden); + QR.open(); + if (wasOpen) { + $$1.addClass(QR.nodes.el, 'dump'); + new QR.post(true); + } + return QR.nodes.com.focus(); + }, + + setCustomCooldown(enabled) { + Conf['customCooldownEnabled'] = enabled; + QR.cooldown.customCooldown = enabled; + return QR.nodes.customCooldown.classList.toggle('disabled', !enabled); + }, + + toggleCustomCooldown() { + const enabled = $$1.hasClass(QR.nodes.customCooldown, 'disabled'); + QR.setCustomCooldown(enabled); + return $$1.set('customCooldownEnabled', enabled); + }, + + error(err, focusOverride) { + let el; + QR.open(); + if (typeof err === 'string') { + el = $$1.tn(err); + } else { + el = err; + el.removeAttribute('style'); + } + const notice = new Notice('warning', el); + QR.notifications.push(notice); + if (!Header$1.areNotificationsEnabled) { + if (d$1.hidden && !QR.cooldown.auto) { return alert(el.textContent); } + } else if (d$1.hidden || !(focusOverride || d$1.hasFocus())) { + const notif = new Notification(el.textContent, { + body: el.textContent, + icon: Favicon.logo + } + ); + notif.onclick = () => window.focus(); + if ($$1.engine !== 'gecko') { + // Firefox automatically closes notifications + // so we can't control the onclose properly. + notif.onclose = () => notice.close(); + return notif.onshow = () => setTimeout(function() { + notif.onclose = null; + return notif.close(); + } + , 7 * SECOND); + } + } + }, + + connectionError() { + return $$1.el('span', + { innerHTML: + 'Connection error while posting. ' + + '[More info]' + } + ); + }, + + notifications: [], + + cleanNotifications() { + for (var notification of QR.notifications) { + notification.close(); + } + return QR.notifications = []; + }, + + status() { + let disabled, value; + if (!QR.nodes) { return; } + const {thread} = QR.posts[0]; + if ((thread !== 'new') && g.threads.get(`${g.BOARD}.${thread}`).isDead) { + value = 'Dead'; + disabled = true; + QR.cooldown.auto = false; + } + + value = QR.req ? + QR.req.progress + : + QR.cooldown.seconds || value; + + const {status} = QR.nodes; + status.value = !value ? + 'Submit' + : QR.cooldown.auto ? + `Auto ${value}` + : + value; + return status.disabled = disabled || false; + }, + + openPost() { + QR.open(); + if (QR.selected.isLocked) { + const index = QR.posts.indexOf(QR.selected); + (QR.posts[index+1] || new QR.post()).select(); + $$1.addClass(QR.nodes.el, 'dump'); + return QR.cooldown.auto = true; + } + }, + + quote(e) { + let range; + e?.preventDefault(); + if (!QR.postingIsEnabled) { return; } + const sel = d$1.getSelection(); + const post = Get$1.postFromNode(this); + const {root} = post.nodes; + const postRange = new Range(); + postRange.selectNode(root); + let text = post.board.ID === g.BOARD.ID ? `>>${post}\n` : `>>>/${post.board}/${post}\n`; + for (let i = 0, end = sel.rangeCount, asc = 0 <= end; asc ? i < end : i > end; asc ? i++ : i--) { + try { + var insideCode, node; + range = sel.getRangeAt(i); + // Trim range to be fully inside post + if (range.compareBoundaryPoints(Range.START_TO_START, postRange) < 0) { + range.setStartBefore(root); + } + if (range.compareBoundaryPoints(Range.END_TO_END, postRange) > 0) { + range.setEndAfter(root); + } + + if (!range.toString().trim()) { continue; } + + var frag = range.cloneContents(); + var ancestor = range.commonAncestorContainer; + // Quoting the insides of a spoiler/code tag. + if ($$1.x('ancestor-or-self::*[self::s or contains(@class,"removed-spoiler")]', ancestor)) { + $$1.prepend(frag, $$1.tn('[spoiler]')); + $$1.add(frag, $$1.tn('[/spoiler]')); + } + if (insideCode = $$1.x('ancestor-or-self::pre[contains(@class,"prettyprint")]', ancestor)) { + $$1.prepend(frag, $$1.tn('[code]')); + $$1.add(frag, $$1.tn('[/code]')); + } + for (node of $$((insideCode ? 'br' : '.prettyprint br'), frag)) { + $$1.replace(node, $$1.tn('\n')); + } + for (node of $$('br', frag)) { + if (node !== frag.lastChild) { $$1.replace(node, $$1.tn('\n>')); } + } + g.SITE.insertTags?.(frag); + for (node of $$('.linkify[data-original]', frag)) { + $$1.replace(node, $$1.tn(node.dataset.original)); + } + for (node of $$('.embedder', frag)) { + if (node.previousSibling?.nodeValue === ' ') { $$1.rm(node.previousSibling); } + $$1.rm(node); + } + text += `>${frag.textContent.trim()}\n`; + } catch (error) { } + } + + QR.openPost(); + const {com, thread} = QR.nodes; + if (!com.value) { thread.value = Get$1.threadFromNode(this); } + + const wasOnlyQuotes = QR.selected.isOnlyQuotes(); + + const caretPos = com.selectionStart; + // Replace selection for text. + com.value = com.value.slice(0, caretPos) + text + com.value.slice(com.selectionEnd); + // Move the caret to the end of the new quote. + range = caretPos + text.length; + com.setSelectionRange(range, range); + com.focus(); + + // This allows us to determine if any text other than quotes has been typed. + if (wasOnlyQuotes) { QR.selected.quotedText = com.value; } + + QR.selected.save(com); + return QR.selected.save(thread); + }, + + characterCount() { + const counter = QR.nodes.charCount; + const count = QR.nodes.com.value.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '_').length; + counter.textContent = count; + counter.hidden = count < (QR.max_comment/2); + return (count > QR.max_comment ? $$1.addClass : $$1.rmClass)(counter, 'warning'); + }, + + getFile() { + return $$1.event('QRFile', QR.selected?.file); + }, + + drawFile(e) { + const file = QR.selected?.file; + if (!file || !/^(image|video)\//.test(file.type)) { return; } + const isVideo = /^video\//.test(file); + const el = $$1.el((isVideo ? 'video' : 'img')); + $$1.on(el, 'error', () => QR.openError()); + $$1.on(el, (isVideo ? 'loadeddata' : 'load'), function() { + e.target.getContext('2d').drawImage(el, 0, 0); + URL.revokeObjectURL(el.src); + return $$1.event('QRImageDrawn', null, e.target); + }); + return el.src = URL.createObjectURL(file); + }, + + openError() { + const div = $$1.el('div'); + $$1.extend(div, { + innerHTML: + 'Could not open file. [More info]' + }); + return QR.error(div); + }, + + setFile(e) { + const {file, name, source} = e.detail; + if (name != null) { file.name = name; } + if (source != null) { file.source = source; } + QR.open(); + return QR.handleFiles([file]); + }, + + drag(e) { + // Let it drag anything from the page. + const toggle = e.type === 'dragstart' ? $$1.off : $$1.on; + toggle(d$1, 'dragover', QR.dragOver); + return toggle(d$1, 'drop', QR.dropFile); + }, + + dragOver(e) { + e.preventDefault(); + return e.dataTransfer.dropEffect = 'copy'; + }, // cursor feedback + + dropFile(e) { + // Let it only handle files from the desktop. + if (!e.dataTransfer.files.length) { return; } + e.preventDefault(); + QR.open(); + return QR.handleFiles(e.dataTransfer.files); + }, + + paste(e) { + if (!e.clipboardData.items) { return; } + let file = null; + let score = -1; + for (var item of e.clipboardData.items) { + var file2; + if ((item.kind === 'file') && (file2 = item.getAsFile())) { + var score2 = (2*(file2.size <= QR.max_size)) + (file2.type === 'image/png'); + if (score2 > score) { + file = file2; + score = score2; + } + } + } + if (file) { + const {type} = file; + const blob = new Blob([file], {type}); + blob.name = `${Conf['pastedname']}.${$$1.getOwn(QR.extensionFromType, type) || 'jpg'}`; + QR.open(); + QR.handleFiles([blob]); + $$1.addClass(QR.nodes.el, 'dump'); + } + }, + + pasteFF() { + const {pasteArea} = QR.nodes; + if (!pasteArea.childNodes.length) { return; } + const images = $$('img', pasteArea); + $$1.rmAll(pasteArea); + for (var img of images) { + var m; + var {src} = img; + if (m = src.match(/data:(image\/(\w+));base64,(.+)/)) { + var bstr = atob(m[3]); + var arr = new Uint8Array(bstr.length); + for (var i = 0, end = bstr.length, asc = 0 <= end; asc ? i < end : i > end; asc ? i++ : i--) { + arr[i] = bstr.charCodeAt(i); + } + var blob = new Blob([arr], {type: m[1]}); + blob.name = `${Conf['pastedname']}.${m[2]}`; + QR.handleFiles([blob]); + } else if (/^https?:\/\//.test(src)) { + QR.handleUrl(src); + } + } + }, + + handleUrl(urlDefault) { + QR.open(); + QR.selected.preventAutoPost(); + return CrossOrigin$1.permission(function() { + const url = prompt('Enter a URL:', urlDefault); + if (url === null) { return; } + QR.nodes.fileButton.focus(); + return CrossOrigin$1.file(url, function(blob) { + if (blob && !/^text\//.test(blob.type)) { + return QR.handleFiles([blob]); + } else { + return QR.error("Can't load file."); + } + }); + }); + }, + + handleFiles(files) { + if (this !== QR) { // file input + files = [...Array.from(this.files)]; + this.value = null; + } + if (!files.length) { return; } + QR.cleanNotifications(); + for (var file of files) { + QR.handleFile(file, files.length); + } + if (files.length !== 1) { $$1.addClass(QR.nodes.el, 'dump'); } + if ((d$1.activeElement === QR.nodes.fileButton) && $$1.hasClass(QR.nodes.fileSubmit, 'has-file')) { + return QR.nodes.filename.focus(); + } + }, + + handleFile(file, nfiles) { + let post; + const isText = /^text\//.test(file.type); + if (nfiles === 1) { + post = QR.selected; + } else { + post = QR.posts[QR.posts.length - 1]; + if (isText ? post.com || post.pasting : post.file) { + post = new QR.post(); + } + } + return post[isText ? 'pasteText' : 'setFile'](file); + }, + + openFileInput() { + if (QR.nodes.fileButton.disabled) { return; } + QR.nodes.fileInput.click(); + return QR.nodes.fileButton.focus(); + }, + + generatePostableThreadsList() { + if (!QR.nodes) { return; } + const list = QR.nodes.thread; + const options = [list.firstElementChild]; + for (var thread of g.BOARD.threads.keys) { + options.push($$1.el('option', { + value: thread, + textContent: `Thread ${thread}` + } + ) + ); + } + const val = list.value; + $$1.rmAll(list); + $$1.add(list, options); + list.value = val; + if (list.value === val) { return; } + // Fix the value if the option disappeared. + list.value = g.VIEW === 'thread' ? + g.THREADID + : + 'new'; + return (g.VIEW === 'thread' ? $$1.addClass : $$1.rmClass)(QR.nodes.el, 'reply-to-thread'); + }, + + dialog() { + let dialog, event, nodes; + let name; + QR.nodes = (nodes = { + el: (dialog = UI.dialog('qr', + { innerHTML: QuickReplyPage })) + }); + + const setNode = (name, query) => nodes[name] = $$1(query, dialog); + + setNode('move', '.move'); + setNode('autohide', '#autohide'); + setNode('close', '.close'); + setNode('thread', 'select'); + setNode('form', 'form'); + setNode('sjisToggle', '#sjis-toggle'); + setNode('texButton', '#tex-preview-button'); + setNode('name', '[data-name=name]'); + setNode('email', '[data-name=email]'); + setNode('sub', '[data-name=sub]'); + setNode('com', '[data-name=com]'); + setNode('charCount', '#char-count'); + setNode('texPreview', '#tex-preview'); + setNode('dumpList', '#dump-list'); + setNode('addPost', '#add-post'); + setNode('oekaki', '.oekaki'); + setNode('drawButton', '#qr-draw-button'); + setNode('fileSubmit', '#file-n-submit'); + setNode('fileButton', '#qr-file-button'); + setNode('noFile', '#qr-no-file'); + setNode('filename', '#qr-filename'); + setNode('spoiler', '#qr-file-spoiler'); + setNode('oekakiButton', '#qr-oekaki-button'); + setNode('fileRM', '#qr-filerm'); + setNode('urlButton', '#url-button'); + setNode('pasteArea', '#paste-area'); + setNode('customCooldown', '#custom-cooldown-button'); + setNode('dumpButton', '#dump-button'); + setNode('status', '[type=submit]'); + setNode('flashTag', '[name=filetag]'); + setNode('fileInput', '[type=file]'); + + const {config} = g.BOARD; + const {classList} = QR.nodes.el; + classList.toggle('forced-anon', QR.forcedAnon); + classList.toggle('has-spoiler', QR.spoiler); + classList.toggle('has-sjis', !!config.sjis_tags); + classList.toggle('has-math', !!config.math_tags); + classList.toggle('sjis-preview', !!config.sjis_tags && Conf['sjisPreview']); + classList.toggle('show-new-thread-option', Conf['Show New Thread Option in Threads']); + + if (parseInt(Conf['customCooldown'], 10) > 0) { + $$1.addClass(QR.nodes.fileSubmit, 'custom-cooldown'); + $$1.get('customCooldownEnabled', Conf['customCooldownEnabled'], function({customCooldownEnabled}) { + QR.setCustomCooldown(customCooldownEnabled); + return $$1.sync('customCooldownEnabled', QR.setCustomCooldown); + }); + } + + QR.flagsInput(); + + $$1.on(nodes.autohide, 'change', QR.toggleHide); + $$1.on(nodes.close, 'click', QR.close); + $$1.on(nodes.status, 'click', QR.submit); + $$1.on(nodes.form, 'submit', QR.submit); + $$1.on(nodes.sjisToggle, 'click', QR.toggleSJIS); + $$1.on(nodes.texButton, 'mousedown', QR.texPreviewShow); + $$1.on(nodes.texButton, 'mouseup', QR.texPreviewHide); + $$1.on(nodes.addPost, 'click', () => new QR.post(true)); + $$1.on(nodes.drawButton, 'click', QR.oekaki.draw); + $$1.on(nodes.fileButton, 'click', QR.openFileInput); + $$1.on(nodes.noFile, 'click', QR.openFileInput); + $$1.on(nodes.filename, 'focus', function() { return $$1.addClass(this.parentNode, 'focus'); }); + $$1.on(nodes.filename, 'blur', function() { return $$1.rmClass(this.parentNode, 'focus'); }); + $$1.on(nodes.spoiler, 'change', () => QR.selected.nodes.spoiler.click()); + $$1.on(nodes.oekakiButton, 'click', QR.oekaki.button); + $$1.on(nodes.fileRM, 'click', () => QR.selected.rmFile()); + $$1.on(nodes.urlButton, 'click', () => QR.handleUrl('')); + $$1.on(nodes.customCooldown, 'click', QR.toggleCustomCooldown); + $$1.on(nodes.dumpButton, 'click', () => nodes.el.classList.toggle('dump')); + $$1.on(nodes.fileInput, 'change', QR.handleFiles); + + window.addEventListener('focus', QR.focus, true); + window.addEventListener('blur', QR.focus, true); + // We don't receive blur events from captcha iframe. + $$1.on(d$1, 'click', QR.focus); + + // XXX Workaround for image pasting in Firefox, obsolete as of v50. + // https://bugzilla.mozilla.org/show_bug.cgi?id=906420 + if (($$1.engine === 'gecko') && !window.DataTransferItemList) { + nodes.pasteArea.hidden = false; + } + new MutationObserver(QR.pasteFF).observe(nodes.pasteArea, {childList: true}); + + // save selected post's data + const items = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag']; + let i = 0; + const save = function() { return QR.selected.save(this); }; + while ((name = items[i++])) { + var node; + if (!(node = nodes[name])) { continue; } + event = node.nodeName === 'SELECT' ? 'change' : 'input'; + $$1.on(nodes[name], event, save); + } + + // XXX Blink and WebKit treat width and height of \n\n'}),s=He("#archive-report-enabled",r),l=He("#archive-report-reason",r),d=He("#archive-report-submit",r);if(He.on(s,"change",(function(){return l.disabled=!this.checked})),o&&a?(r.hidden=!He('[value="31"]',a).checked,He.on(a,"change",(function(e){return r.hidden="31"!==e.target.value,xe.fit("body")})),He.after(a,r),xe.fit("body"),He.one(o,"submit",(function(e){if(!r.hidden&&s.checked)return e.preventDefault(),xe.archiveSubmit(t,l.value,(e=>(this.action="#archiveresults="+encodeURIComponent(JSON.stringify(e)), +this.submit())))}))):i&&(r.hidden=/Report submitted!/.test(i.textContent),He.on(s,"change",(function(){return d.hidden=!this.checked})),He.after(i,r),He.on(d,"click",(()=>xe.archiveSubmit(t,l.value,xe.archiveResults)))),e=location.hash.match(/^#archiveresults=(.*)$/))try{return xe.archiveResults(JSON.parse(decodeURIComponent(e[1])))}catch(e){}},archiveSubmit(e,t,o){const a=He.formData({board:n.BOARD.ID,num:xe.postID,reason:t}),i=[];for(var[r,s]of e)!function(t,n){He.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=He.id("archive-report");for(var[n,o]of e){var i=He.el("h3",{className:"archive-report-response"});"success"in o?(He.addClass(i,"archive-report-success"),i.textContent=`${n}: ${o.success}`):(He.addClass(i,"archive-report-error"),i.textContent=`${n}: ${o.error||"Error reporting post."}`),t?He.before(t,i):He.add(a.body,i)}}};const ye={init(){ +if(t["Remember Your Posts"])return He.ready(this.ready)},ready(){if("Post successful!"!==a.title)return;let[e,t,o]=Array.from(He("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 ke={isOPContainerThread:!1,hasIPCount:!0,archivedBoardsKnown:!0,urls:{thread:({boardID:e,threadID:t})=>`${location.protocol}//${G.domain(e)}/${e}/thread/${t}`,post:({postID:e})=>`#p${e}`,index:({boardID:e})=>`${location.protocol}//${G.domain(e)}/${e}/`,catalog:({boardID:e})=>"f"===e?void 0:`${location.protocol}//${G.domain(e)}/${e}/catalog`,archive:({boardID:e})=>G.isArchived(e)?`${location.protocol}//${G.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})=>G.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})=>G.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:/]*\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:()=>He.el("div",{className:"reply"}),isThisPageLegit:()=>["boards.4chan.org","boards.4channel.org"].includes(location.hostname)&&a.doctype&&!He('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&&He(".board")&&!He(".opContainer"),isIncomplete:()=>["index","thread"].includes(n.VIEW)&&!He(".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(ke.regexp.pass.test(location.href)?we.init():(He.onExists(i,"body",(()=>He.addStyle(fe.www))),Le.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)?xe.init():(e=location.search.match(/\bres=(\d+)/))&&He.ready((function(){if(t["404 Redirect"]&&"Error: Specified thread does not exist."===He.id("errmsg")?.textContent)return _e.navigate("thread",{boardID:n.BOARD.ID,postID:+e[1]})}))}else"post"===e[2]&&ye.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 He.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=He(`img[alt=${n}]`,t.info))&&e.push(He.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(He.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&&(He.extend(t,{thumbURL:i.src,MD5:i.dataset.md5,isSpoiler:He.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=He(".abbr",e)){for(var n of u(".abbr + br, .exif",e))He.rm(n);for(let e=0;e<2;e++){var o;(o=t.previousSibling)&&"BR"===o.nodeName&&He.rm(o)}return He.rm(t)}},cleanCommentDisplay(e){let t;return(t=He("b",e))&&/^Rolled /.test(t.textContent)&&He.rm(t),He.rm(He(".fortune",e))},insertTags(e){let t;for(t of u("s, .removed-spoiler",e))He.replace(t,[He.tn("[spoiler]"),...Array.from(t.childNodes),He.tn("[/spoiler]")]);for(t of u(".prettyprint",e))He.replace(t,[He.tn("[code]"),...Array.from(t.childNodes),He.tn("[/code]")])},hasCORS:e=>e.split("/").slice(0,3).join("/")===location.protocol+"//a.4cdn.org",sfwBoards:e=>G.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:()=>He.global((function(){ +if(window.Parser?.postMenuIcon)return this.enabled="true"})),transformBoardList(){let e;const t=[],n=()=>He.el("span",{className:"spacer"}),o=He.X(".//a|.//text()[not(ancestor::a)]",He(ke.selectors.boardList));let a=0;for(;e=o.snapshotItem(a++);)switch(e.nodeName){case"#text":for(var i of e.nodeValue){var r=He.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?`//${G.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:He.unescape(e.sub),email:He.unescape(e.email),name:He.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:He.unescape(e.country_name||e.flag_name),dateUTC:e.time,dateText:e.now,commentHTML:{innerHTML:e.com||"",[de]:!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:He.unescape(e.filename)+e.ext,url:a.urls.file({siteID:t,boardID:o},i),height:e.h,width:e.w,MD5:e.md5,size:He.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(//gi,"\n").replace(/\n\n]*>/g,""),He.unescape(e)),parseCommentDisplay(e){if(!t["Remove Spoilers"]&&!t["Reveal Spoilers"]){let t;for(;(t=e.replace(/(?:(?!<\/?s>).)*<\/s>/g,"[spoiler]"))!==e;)e=t} +return e=e.replace(/^Rolled [^<]*<\/b>/i,"").replace(/>"):"",ue("div",{id:`p${t}`,class:`post ${P}${e.capcodeHighlight?" highlightPost":""}`},e.isReply?ue(he,null,D,B):ue(he,null,B,D),ue("blockquote",{class:"postMessage",id:`m${t}`},v))),N=He.el("div",{className:`postContainer ${P}Container`,id:`pc${t}`});for(var F of(He.extend(N,M),u(".quotelink",N))){var L,O=F.getAttribute("href");if("#"===O[0])this.sameThread(a,o)||(F.href=this.threadURL(a,o)+O);else(L=F.href.match(ke.regexp.quotelink))&&this.sameThread(L[1],L[2])&&(F.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 He.el("a",{className:"summary", +textContent:this.summaryText("",n,o),href:`/${e}/thread/${t}`})},thread(e,t,n){let o;if((o=e.nodes.root)?He.rmAll(o):e.nodes.root=o=He.el("div",{className:"thread",id:`t${t.no}`}),this.hat&&He.add(o,this.hat.cloneNode(!1)),He.add(o,e.OP.nodes.root),t.omitted_posts||!n&&t.replies){const[a,i]=Array.from(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);He.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=He.el("div",function(e,t,n,o,a,i,r,s,l){return ue(he,null,ue("a",{class:"catalog-link",href:`/${e.board}/thread/${e.ID}`},ue("img",n?{src:t,class:`catalog-thumb ${n}`}:{src:t,class:"catalog-thumb","data-width":o.tn_w,"data-height":o.tn_h})),ue("div",{class:"catalog-stats"},ue("span",{title:"Posts / Files / Page"},ue("span",{class:"post-count"+(o.bumplimit?" warning":"")},a)," / ",ue("span",{class:"file-count"+(o.imagelimit?" warning":"")},i)," / ",ue("span",{class:"page-count"},r)),ue("span",{class:"catalog-icons"},e.isSticky?ue("img",{src:`${s}sticky${l}`,class:"stickyIcon",title:"Sticky"}):"",e.isClosed?ue("img",{src:`${s}closed${l}`,class:"closedIcon",title:"Closed"}):"")))}(e,r,i,n,h,p,o,s,l));for(var f of(He.before(e.OP.nodes.info,[...Array.from(g.childNodes)]),u("br",e.OP.nodes.comment)))f.previousSibling&&"BR"===f.previousSibling.nodeName&&He.addClass(f,"extra-linebreak");const m=He.el("div",{className:"thread catalog-thread",id:`t${e}` +});return e.OP.highlights&&He.addClass(m,...Array.from(e.OP.highlights)),e.OP.file||He.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=`${He.unescape(t.filename)}${t.ext}`)),t.com&&(n||(n=He.unescape(t.com.replace(//gi," // ")))),n||(n=" "),n.length>73&&(n=`${n.slice(0,70)}...`);const o=this.postURL(e.board.ID,e.ID,t.no);return He.el("div",{className:"catalog-reply"},ue(he,null,ue("span",null,ue("time",{"data-utc":1e3*t.time,"data-abbrev":"1"},"..."),": "),ue("a",{class:"catalog-reply-excerpt",href:o},n),ue("a",{class:"catalog-reply-preview",href:o},"...")))}}},Ie={tinyboard:Ae,yotsuba:ke};var Ce={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))He.on(e,"click",j.download);for(e of u(".file-info .quick-filter-md5",this.file.text))He.on(e,"click",ze.quickFilterMD5);return}const e=He.el("span",{className:"fileText-original"});He.prepend(this.file.link.parentNode,e),He.add(e,[this.file.link.previousSibling,this.file.link,this.file.link.nextSibling]);const n=He.el("span",{className:"file-info"});return Ce.format(t.fileInfo,this,n),He.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(He.hasOwn(Ce.formatters,n)?Ce.formatters[n].call(t):{innerHTML:o(e)}),""})),He.extend(n,{innerHTML:o.cat(i)}),u(".download-button",n)))He.on(a,"click",j.download);for(a of u(".quick-filter-md5",n))He.on(a,"click",ze.quickFilterMD5)},formatters:{t(){return{innerHTML:o(this.file.url.match(/[^/]*$/)[0]),[de]:!0}},T(){return ue("a",{href:this.file.url,target:"_blank"},Ce.formatters.t.call(this))},l(){return ue("a",{ +href:this.file.url,target:"_blank"},Ce.formatters.n.call(this))},L(){return ue("a",{href:this.file.url,target:"_blank"},Ce.formatters.N.call(this))},n(){const e=this.file.name,t=Ie.yotsuba.Build.shortFilename(this.file.name,this.isReply);return e===t?{innerHTML:o(e),[de]:!0}:ue("span",{class:"fnswitch"},ue("span",{class:"fntrunc"},t),ue("span",{class:"fnfull"},e))},N(){return{innerHTML:o(this.file.name),[de]:!0}},d(){return ue("a",{href:this.file.url,download:this.file.name,class:"download-button"},"📥︎")},f:()=>({innerHTML:'',[de]:!0}),p(){return{innerHTML:this.file.isSpoiler?"Spoiler, ":"",[de]:!0}},s(){return{innerHTML:o(this.file.size),[de]:!0}},B(){return{innerHTML:Math.round(this.file.sizeInBytes)+" Bytes",[de]:!0}},K(){return{innerHTML:Math.round(this.file.sizeInBytes/1024)+" KB",[de]:!0}},M(){return{innerHTML:Math.round(this.file.sizeInBytes/1048576*100)/100+" MB",[de]:!0}},r(){return{innerHTML:o(this.file.dimensions||"PDF"), +[de]:!0}},g(){return{innerHTML:this.file.tag?", "+o(this.file.tag):"",[de]:!0}},"%":()=>({innerHTML:"%",[de]:!0})}},De={init(){if(["index","thread","archive"].includes(n.VIEW)&&t["Time Formatting"])return l.Post.push({name:"Time Formatting",cb:this.node})},node(){if(!this.info.date||this.isClone)return;const{textContent:e}=this.nodes.date;return this.nodes.date.textContent=e.match(/^\s*/)[0]+De.format(t.time,this.info.date)+e.match(/\s*$/)[0]},format:(e,t)=>e.replace(/%(.)/g,(function(e,n){return He.hasOwn(De.formatters,n)?De.formatters[n].call(t):e})),day:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],month:["January","February","March","April","May","June","July","August","September","October","November","December"],localeFormat(e,n,o){if(t.timeLocale)try{return Intl.DateTimeFormat(t.timeLocale,n).format(e)}catch(e){}return o},localeFormatPart(e,n,o,a){if(t.timeLocale)try{return Intl.DateTimeFormat(t.timeLocale,n).formatToParts(e).map((function(e){ +return e.type===o?e.value:""})).join("")}catch(e){}return a},zeroPad:e=>e<10?`0${e}`:e,formatters:{a(){return De.localeFormat(this,{weekday:"short"},De.day[this.getDay()].slice(0,3))},A(){return De.localeFormat(this,{weekday:"long"},De.day[this.getDay()])},b(){return De.localeFormat(this,{month:"short"},De.month[this.getMonth()].slice(0,3))},B(){return De.localeFormat(this,{month:"long"},De.month[this.getMonth()])},d(){return De.zeroPad(this.getDate())},e(){return this.getDate()},H(){return De.zeroPad(this.getHours())},I(){return De.zeroPad(this.getHours()%12||12)},k(){return this.getHours()},l(){return this.getHours()%12||12},m(){return De.zeroPad(this.getMonth()+1)},M(){return De.zeroPad(this.getMinutes())},p(){return De.localeFormatPart(this,{hour:"numeric",hour12:!0},"dayperiod",this.getHours()<12?"AM":"PM")},P(){return De.formatters.p.call(this).toLowerCase()},S(){return De.zeroPad(this.getSeconds())},y(){return this.getFullYear().toString().slice(2)},Y(){return this.getFullYear() +},"%":()=>"%"}},Ee={init(){if("thread"!==n.VIEW||!t["Reply Pruning"])return;this.container=He.frag(),this.summary=He.el("span",{hidden:!0,className:"summary"}),this.summary.style.cursor="pointer",He.on(this.summary,"click",(()=>(this.inputs.enabled.checked=!this.inputs.enabled.checked,He.event("change",null,this.inputs.enabled))));const e=F.checkbox("Prune Replies","Show Last",t["Prune All Threads"]),a=He.el("span",{title:"Maximum number of replies to show."},{innerHTML:' '});return He.prepend(a,e),this.inputs={enabled:e.firstElementChild,replies:a.lastElementChild},this.setEnabled.call(this.inputs.enabled),He.on(this.inputs.enabled,"change",this.setEnabled),He.on(this.inputs.replies,"change",He.cb.value),Je.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=Se.input +;return this.checked&&e?.checked&&(e.checked=!1,He.event("change",null,e)),Ee.active=this.checked},showIfHidden(e){if(Ee.container&&He(`#${e}`,Ee.container))return Ee.inputs.enabled.checked=!1,He.event("change",null,Ee.inputs.enabled)},node(){let e;return Ee.thread=this,this.isSticky&&(Ee.active=Ee.inputs.enabled.checked=!0,Se.input&&(t["Thread Quotes"]=Se.input.checked=!1)),this.posts.forEach((function(e){if(e.isReply&&(Ee.total++,e.file))return Ee.totalFiles++})),Ee.active&&/^#p\d+$/.test(location.hash)&&1<=(e=this.posts.keys.indexOf(location.hash.slice(2)))&&e<1+Math.max(Ee.total-+t["Max Replies"],0)&&(Ee.active=Ee.inputs.enabled.checked=!1),He.after(this.OP.nodes.root,Ee.summary),He.on(Ee.inputs.enabled,"change",Ee.update),He.on(Ee.inputs.replies,"change",Ee.update),He.on(a,"ThreadUpdate",Ee.updateCount),He.on(a,"ThreadUpdate",Ee.update),Ee.update()},updateCount(e){if(!e.detail[404])for(var t of e.detail.newPosts)Ee.total++,n.posts.get(t).file&&Ee.totalFiles++},update(){let e,o,i +;const r=Ee.hidden,s=Ee.active?Math.max(Ee.total-+t["Max Replies"],0):0,l=a.body.clientHeight-window.scrollY,{posts:d}=Ee.thread;if(Ee.hiddens){const e=He.frag();for(;Ee.hidden>s&&Ee.position>0;)if(i=d.get(d.keys[--Ee.position]),i.isReply&&!i.isFetchedQuote){for(;(o=Ee.container.lastChild)&&o!==i.nodes.root;)He.prepend(e,o);He.prepend(e,i.nodes.root),Ee.hidden--,i.file&&Ee.hiddenFiles--}He.after(Ee.summary,e),He.event("PostsInserted",null,Ee.summary.parentNode)}if(Ee.summary.textContent=Ee.active?n.SITE.Build.summaryText("+",Ee.hidden,Ee.hiddenFiles):n.SITE.Build.summaryText("-",Ee.total,Ee.totalFiles),Ee.summary.hidden=Ee.total<=+t["Max Replies"], +r!==s&&(e=Je.getTopOf(He(".board")))<0)return window.scrollBy(0,Math.max(a.body.clientHeight-l,window.scrollY+e)-window.scrollY)}},Se={init(){if(t["Quote Threading"]&&"thread"===n.VIEW)return this.controls=He.el("label",{innerHTML:' Threading'}),this.threadNewLink=He.el("span",{className:"brackets-wrap threadnewlink",hidden:!0}),He.extend(this.threadNewLink,{innerHTML:'Thread New Posts'}),this.input=He("input",this.controls),this.input.checked=t["Thread Quotes"],He.on(this.input,"change",this.setEnabled),He.on(this.input,"change",this.rethread),He.on(this.threadNewLink.firstElementChild,"click",this.rethread),He.on(a,"4chanXInitFinished",(()=>this.ready=!0)),Je.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){He.set("Prune All Threads",!1);const e=Ee.inputs?.enabled;e?.checked&&(e.checked=!1,He.event("change",null,e))}return He.cb.checked.call(this)},setThread(){return Se.thread=this,He.asap((()=>!t["Thread Updater"]||He(".navLinksBot > .updatelink")),(function(){let e;if(e=He(".navLinksBot"))return He.add(e,[He.tn(" "),Se.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.IDo.ID)&&(o=e));if(!o)return;let i=o;for(;i=Se.parent[i.fullID];)t.delete(i.ID);return 1===t.size?Se.parent[this.fullID]=o:void 0},descendants(e){let t,n=[e];if(t=Se.children[e.fullID])for(var o of t)n=n.concat(Se.descendants(o));return n},insert(e){ +let n,o;if(!t["Thread Quotes"]||!(n=Se.parent[e.fullID])||Se.inserted[e.fullID])return!1;const a=Se.descendants(e);if(!Z.posts.has(n.ID)&&function(){for(var e of a)if(Z.posts.has(e.ID))return!0}())return Se.threadNewLink.hidden=!1,!1;const{order:i}=Z,r=Se.children[n.fullID]||(Se.children[n.fullID]=[]),s=n.nodes.threadContainer||He.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),He.before(t.nodes.root,l)}else{let t,d=n;for(;(t=Se.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),He.add(s,l)}return Se.inserted[e.fullID]=!0,n.nodes.threadContainer||(n.nodes.threadContainer=s,He.addClass(n.nodes.root,"threadOP"),He.after(n.nodes.root,s)),!0},rethread(){if(!Se.ready)return;const{thread:e}=Se,{posts:n}=e +;if(Se.threadNewLink.hidden=!0,t["Thread Quotes"])n.forEach(Se.insert);else{const t=[];Z.order=new _,Se.inserted=m(),n.forEach((function(e){if(!e.isFetchedQuote)return Z.order.push(e),e.isReply&&t.push(e.nodes.root),Se.children[e.fullID]?(delete Se.children[e.fullID],He.rmClass(e.nodes.root,"threadOP"),He.rm(e.nodes.threadContainer),delete e.nodes.threadContainer):void 0})),He.add(e.nodes.root,t)}return Z.position=Z.order.first,Z.updatePosition(),Z.setLine(!0),Z.read(),Z.update()}},Te={init(){let e,o,r;if("thread"!==n.VIEW||!t["Thread Updater"])return;this.enabled=!0,this.audio=He.el("audio"),"gecko"!==He.engine&&(this.audio.src=this.beep),t["Updater and Stats in Header"]?(this.dialog=r=He.el("span",{id:"updater"}),He.extend(r,{innerHTML:''}),Je.addShortcut("updater",r,100)):(this.dialog=r=F.dialog("updater",{ +innerHTML:'
          '}),He.addClass(i,"float"),He.ready((()=>He.add(a.body,r)))),this.checkPostCount=0,this.timer=He("#update-timer",r),this.status=He("#update-status",r),He.on(this.timer,"click",this.update),He.on(this.status,"click",this.update);const s=He.el("span",{className:"brackets-wrap updatelink"});He.extend(s,{innerHTML:'Update'}),Lt.ready((function(){let e;if(e=He(".navLinksBot"))return He.add(e,[He.tn(" "),s])})),He.on(s.firstElementChild,"click",this.update);const d=[];for(o in c.updater.checkbox){var h=c.updater.checkbox[o];e=F.checkbox(o,o),e.title=h[1];var u=e.firstElementChild;He.on(u,"change",He.cb.checked),"Scroll BG"===u.name?(He.on(u,"change",this.cb.scrollBG),this.cb.scrollBG()):"Auto Update"===u.name&&He.on(u,"change",this.setInterval),d.push({el:e})}return this.settings=He.el("span",{ +innerHTML:'Interval'}),He.on(this.settings,"click",this.intervalShortcut),d.push({el:this.settings}),Je.menu.addEntry(this.entry={el:He.el("span",{textContent:"Updater"}),order:110,subEntries:d}),l.Thread.push({name:"Thread Updater",cb:this.node})},node(){return Te.thread=this,Te.root=this.nodes.root,Te.outdateCount=0,Te.postIDs=[],Te.fileIDs=[],this.posts.forEach((function(e){if(Te.postIDs.push(e.ID),e.file)return Te.fileIDs.push(e.ID)})),Te.cb.interval.call(He.el("input",{value:t.Interval})),He.on(a,"QRPostSuccessful",Te.cb.checkpost),He.on(a,"visibilitychange",Te.cb.visibility),Te.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}=Te;return e.src||(e.src=Te.beep),e.paused?e.play():He.one(e,"ended",Te.playBeep)},cb:{checkpost(e){if(e.detail.threadID===Te.thread.ID)return Te.postID=e.detail.postID,Te.checkPostCount=0,Te.outdateCount=0,Te.setInterval()},visibility(){if(!a.hidden)return Te.outdateCount=0,Te.seconds>Te.interval?Te.setInterval():void 0},scrollBG:()=>Te.scrollBG=t["Scroll BG"]?()=>!0:()=>!a.hidden,interval(e){let t=parseInt(this.value,10);if(t<1&&(t=1),Te.interval=this.value=t,e)return He.cb.value.call(this)},load(){if(this===Te.req)switch(this.status){case 200:return Te.parse(this),Te.thread.isArchived?Te.kill():Te.setInterval();case 404:return He.ajax(n.SITE.urls.catalogJSON({boardID:Te.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===Te.thread.ID){e=!1;break}}else e=!1;return e?Te.kill():Te.error(this)}});default:return Te.error(this)}}},kill:()=>(Te.thread.kill(),Te.setInterval(), +He.event("ThreadUpdate",{404:!0,threadID:Te.thread.fullID})),error:e=>(304===e.status&&Te.set("status",""),Te.setInterval(),e.status?304!==e.status?Te.set("status",`${e.statusText} (${e.status})`,"warning"):void 0:Te.set("status","Connection Error","warning")),setInterval(){if(clearTimeout(Te.timeoutID),Te.thread.isDead)return Te.set("status",Te.thread.isArchived?"Archived":"404","warning"),void Te.set("timer","");if(Te.postID&&Te.checkPostCount<5)return Te.set("timer","...","loading"),void(Te.timeoutID=setTimeout(Te.update,++Te.checkPostCount*b));if(!t["Auto Update"])return void Te.set("timer","Update");const{interval:e}=Te;if(t["Optional Increase"]){const t=a.hidden?10:5,n=Math.min(Te.outdateCount,t),o=(Math.floor(.1*e)||1)*n*n;Te.seconds=He.minmax(o,e,300)}else Te.seconds=e;return Te.timeout()},intervalShortcut(){Re.open("Advanced");const e=He.id("fourchanx-settings");return He("input[name=Interval]",e).focus()},set(e,t,n){let o;const a=Te[e] +;return(o=a.firstChild)?o.data=t:a.textContent=t,a.className=n??(""===t?"empty":"")},timeout:()=>(Te.seconds?(Te.set("timer",Te.seconds),Te.timeoutID=setTimeout(Te.timeout,1e3)):(Te.outdateCount++,Te.update()),Te.seconds--),update(){let e;return clearTimeout(Te.timeoutID),Te.set("timer","...","loading"),(e=Te.req)&&(delete Te.req,e.abort()),Te.req=He.whenModified(n.SITE.urls.threadJSON({boardID:Te.thread.board.ID,threadID:Te.thread.ID}),"ThreadUpdater",Te.cb.load,{timeout:A})},updateThreadStatus(e,t){if(Te.thread[`is${e}`]===t)return;if(Te.thread.setStatus(e,t),"Closed"===e&&Te.thread.isArchived)return;return new Ke("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}=Te,{board:h}=c,u=Te.postIDs[Te.postIDs.length-1];if(l[l.length-1].non?(Te.playBeep(), +t.Beep&&Te.playBeep()):t.Beep&&Z.posts?.size>0&&0===e&&Te.playBeep());const o=t["Auto Scroll"]&&Te.scrollBG()&&Te.root.getBoundingClientRect().bottom-i.clientHeight<25;let r=null;for(s of p)Se.insert(s)||(r||(r=s.nodes.root),He.add(Te.root,s.nodes.root));He.event("PostsInserted",null,Te.root),o&&(t["Bottom Scroll"]?window.scrollTo(0,a.body.clientHeight):r&&Je.scrollTo(r))}else Te.set("status","");return null!=d.unique_ips&&(r=He.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")),He.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})}},Re={dialog:void 0,init(){const o=He.el("a",{className:"settings-link",textContent:"🔧︎",title:`${e.name} Settings`, +href:"javascript:;"});He.on(o,"click",Re.open),Je.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),He.on(a,"AddSettingsSection",Re.addSection),He.on(a,"OpenSettings",(e=>Re.open(e.detail))),"yotsuba"===n.SITE.software&&t["Disable Native Extension"])return He.hasStorage?He.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}})}})):He.global((()=>Object.defineProperty(window,"Config",{value:{disableAll:!0}})))},open(e){let t,n;if(Re.dialog)return;He.event("CloseMenu"),Re.dialog=t=He.el("div",{id:"overlay"},ge),He.on(He(".export",t),"click",Re.export),He.on(He(".import",t),"click",Re.import),He.on(He(".reset",t),"click",Re.reset), +He.on(He("input",t),"change",Re.onImport);const o=[];for(var i of Re.sections){var r=He.el("a",{className:`tab-${i.hyphenatedTitle}`,textContent:i.title,href:"javascript:;"});He.on(r,"click",Re.openSection.bind(i)),o.push(r,He.tn(" | ")),i.title===e&&(n=r)}return o.pop(),He.add(He(".sections-list",t),o),"none"!==e&&(n||o[0]).click(),He.on(He(".close",t),"click",Re.close),He.on(window,"beforeunload",Re.close),He.on(t,"click",Re.close),He.on(t.firstElementChild,"click",(e=>e.stopPropagation())),He.add(a.body,t),He.event("OpenSettings",null,t)},close(){if(Re.dialog)return a.activeElement?.blur(),He.rm(Re.dialog),delete Re.dialog},sections:[],addSection(e,t){"string"!=typeof e&&({title:e,open:t}=e.detail);const n=e.toLowerCase().replace(/\s+/g,"-");return Re.sections.push({title:e,hyphenatedTitle:n,open:t})},openSection(){let e;(e=He(".tab-selected",Re.dialog))&&He.rmClass(e,"tab-selected"),He.addClass(He(`.tab-${this.hyphenatedTitle}`,Re.dialog),"tab-selected") +;const t=He("section",Re.dialog);return He.rmAll(t),t.className=`section-${this.hyphenatedTitle}`,this.open(t,n),t.scrollTop=0,He.event("OpenSettings",null,t)},warnings:{localStorage(t){if(He.cantSync){const n=He.cantSet?"save your settings":"synchronize settings between tabs";return t(He.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=>He.onExists(i,".adg-rects > .desktop",(t=>He.onExists(t,"iframe",(function(){const t=_e.to("thread",{boardID:"qa",threadID:362590});return e(He.el("li",ue(he,null,"To protect yourself from ",ue("a",{href:t,target:"_blank"},"malicious ads"),", you should ",ue("a",{href:"https://github.com/gorhill/uBlock#ublock-origin",target:"_blank"},"block ads")," on 4chan.")))}))))},main(o){let a;const i=He.el("fieldset",{hidden:!0},{innerHTML:"Warnings
            "}),r=function(e){ +return He.add(He("ul",i),e),i.hidden=!1};for(a in Re.warnings){(0,Re.warnings[a])(r)}He.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=He.el("div",{innerHTML:`: ${r}`});d.dataset.name=a;var c=He("input",d);He.on(c,"change",He.cb.checked),He.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=He.el("div",{className:"suboption-list"});He.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(He.add(o[h],d))}}return e})()};for(var h in c.main){var u=c.main[h],p=He.el("fieldset",{innerHTML:`${h}`});d(p,u),"Posting and Captchas"===h&&He.add(p,He.el("p",{ +innerHTML:'For more info on captcha options and issues, see the captcha FAQ.'})),He.add(o,p)}d(He('div[data-name="JSON Index"] > .suboption-list',o),c.Index),"gecko"!==He.engine&&(He('div[data-name="Remember QR Size"]',o).hidden=!0),(He.perProtocolSettings||"https:"!==location.protocol)&&(He('div[data-name="Redirect to HTTPS"]',o).hidden=!0),"crx"!==x&&(He('div[data-name="Work around CORB Bug"]',o).hidden=!0),He.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=He.el("div",{innerHTML:': Clear manually-hidden threads and posts on all boards. Reload the page to apply.'}),f=He("button",g);return He.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}`})),He.on(f,"click",(function(){return this.textContent="Hidden: 0",He.get("hiddenThreads",m(),(function({hiddenThreads:e}){if(He.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 He.delete(["hiddenThreads","hiddenPosts"])}))})),He.after(He('input[name="Stubs"]',o).parentNode.parentNode,g)},export(){const e=m();return He.extend(e,t),He.get(e,(function(e){return delete e.boardConfig,Re.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=He.el("a",{ +download:`${e.name} v${n.VERSION}-${t.date}.json`,href:a}),r=He(".imp-exp-result",Re.dialog);return He.rmAll(r),He.add(r,i),i.click()},import(){return He("input[type=file]",this.parentNode).click()},onImport(){let e;if(!(e=this.files[0]))return;this.value=null;const t=He(".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 Re.loadSettings(m.json(e.target.result),(function(e){return e?t.textContent="Import failed due to an error.":confirm("Import successful. Reload now?")?window.location.reload():void 0}))}catch(e){const n=e;return t.textContent="Import failed due to an error.",r.error(n.stack)}},n.readAsText(e)},convertFrom:{loadletter(e){for(var t in"Always CDN"in(e=function(e,t){for(var n in t){var o=t[n];o&&(e.Conf[o]=e.Conf[n]),delete e.Conf[n]}return e}(e,{"Disable 4chan's extension":"Disable Native Extension", +"Comment Auto-Expansion":"","Remove Slug":"","Always HTTPS":"Redirect to HTTPS","Check for Updates":"","Recursive Filtering":"Recursive Hiding","Reply Hiding":"Reply Hiding Buttons","Thread Hiding":"Thread Hiding Buttons","Show Stubs":"Stubs","Image Auto-Gif":"Replace GIF","Expand All WebM":"Expand videos","Reveal Spoilers":"Reveal Spoiler Thumbnails","Expand From Current":"Expand from here","Current Page":"Page Count in Stats","Current Page Position":"","Alternative captcha":"Use Recaptcha v1","Alt index captcha":"Use Recaptcha v1 on Index","Auto Submit":"Post on Captcha Completion","Open Reply in New Tab":"Open Post in New Tab","Remember QR size":"Remember QR Size","Remember Subject":"","Quote Inline":"Quote Inlining","Quote Preview":"Quote Previewing","Indicate OP quote":"Mark OP Quotes","Indicate You quote":"Mark Quotes of You","Indicate Cross-thread Quotes":"Mark Cross-thread Quotes",uniqueid:"uniqueID",mod:"capcode",email:"",country:"flag",md5:"MD5",openEmptyQR:"Open empty QR", +openQR:"Open QR",openOptions:"Open settings",close:"Close",spoiler:"Spoiler tags",sageru:"Toggle sage",code:"Code tags",sjis:"SJIS tags",submit:"Submit QR",watch:"Watch",update:"Update",unreadCountTo0:"",expandAllImages:"Expand images",expandImage:"Expand image",zero:"Front page",nextPage:"Next page",previousPage:"Previous page",nextThread:"Next thread",previousThread:"Previous thread",expandThread:"Expand thread",openThreadTab:"Open thread",openThread:"Open thread tab",nextReply:"Next reply",previousReply:"Previous reply",hide:"Hide",Scrolling:"Auto Scroll",Verbose:""})).Conf&&(e.Conf.fourchanImageHost=e.Conf["Always CDN"]?"i.4cdn.org":"",delete e.Conf["Always CDN"]),e.Conf.sauces=e.Conf.sauces.replace(/\$\d/g,(function(e){switch(e){case"$1":return"%TURL";case"$2":return"%URL";case"$3":return"%MD5";case"$4":return"%board";default:return e}})),c.hotkeys)c.hotkeys[t], +t in e.Conf&&(e.Conf[t]=e.Conf[t].replace(/ctrl|alt|meta/g,(e=>`${e[0].toUpperCase()}${e.slice(1)}`)).replace(/(^|.+\+)[A-Z]$/g,(e=>`Shift+${e.slice(0,-1)}${e.slice(-1).toLowerCase()}`)));if(e.WatchedThreads)for(var n in e.Conf.watchedThreads=m.clone({"4chan.org":{boards:{}}}),e.WatchedThreads){var o=e.WatchedThreads[n];for(var a in o){var i=o[a];(e.Conf.watchedThreads["4chan.org"].boards[n]||(e.Conf.watchedThreads["4chan.org"].boards[n]=m()))[a]={excerpt:i.textContent}}}return e}},upgrade(n,o){let a,i,r;const s=m(),l=(e,t)=>n[e]=s[e]=t,d=function(e,t){if(null==n[e])return l(e,t)},h=function(e){if(null!=n.sauces&&(e=e.filter((e=>n.sauces.indexOf(e.match(/[^#;\s]+|$/)[0])<0))).length)return l("sauces",n.sauces+"\n\n"+e.join("\n"))},u=function(e){if(null==n.usercss&&l("usercss",c.usercss),n.usercss.indexOf(e)<0)return l("usercss",e+"\n\n"+n.usercss)};if(a='"'===o[0])try{o=JSON.parse(o)}catch(e){}const p=o.replace(/\d+/g,(e=>("0000"+e).slice(-5))) +;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];He.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"&&!Re.dialog&&He.queueTask((()=>Re.warnings.ads((e=>new Ke("warning",[...Array.from(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]=Array.from(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=Re.convertFrom.loadletter(e):e.version!==n.VERSION&&Re.upgrade(e.Conf,e.version),He.clear((function(n){return n?t(n):He.set(e.Conf,t)}))),reset(){if(confirm("Your current settings will be entirely wiped, are you sure?"))return He.clear((function(e){return e?He(".imp-exp-result").textContent="Import failed due to an error.":confirm("Reset successful. Reload now?")?window.location.reload():void 0}))},filter(e){He.extend(e,{ +innerHTML:'\n
            \n'});const t=He("select",e);return He.on(t,"change",Re.selectFilter),Re.selectFilter.call(t)},selectFilter(){let e;const n=this.nextElementSibling;if("guide"!==(e=this.value)){if(!He.hasOwn(c.filter,e))return;He.rmAll(n) +;const o=He.el("textarea",{name:e,className:"field",spellcheck:!1});return He.on(o,"change",He.cb.value),void He.get(e,t[e],(function(t){return o.value=t[e],He.add(n,o)}))}return Object.keys(c.filter).filter((e=>"general"!==e)).map(((e,t)=>({innerHTML:(t?",":"")+`${o(e)}`}))),He.extend(n,{ +innerHTML:'
            Filter is disabled.
            \n

            \n Use regular expressions, one per line.
            \n Lines starting with a # will be ignored.
            \n For example, /weeaboo/i will filter posts containing the string `weeaboo`, case-insensitive.
            \n MD5 and Unique ID filtering use exact string matching, not regular expressions.\n

            \n
              You can use these settings with each regular expression, separate them with semicolons:\n
            • \n Per boards, separate them with commas. It is global if not specified. Use sfw and nsfw to reference all worksafe or not-worksafe boards.
              \n For example: boards:a,jp;.
              \n To specify boards on a particular site, put the beginning of the domain and a slash character before the list.
              \n Any initial www. should not be included, and all 4chan domains are considered 4chan.org.
              \n For example: boards:4:a,jp,sama:a,z;.
              \n An asterisk can be used to specify all boards on a site.
              \n For example: boards:4:*;.
              \n
            • \n
            • \n Select boards to be excluded from the filter. The syntax is the same as for the boards: option above.
              \n For example: exclude:vg,v;.\n
            • \n
            • \n Filter OPs only along with their threads (`only`) or replies only (`no`).
              \n For example: op:only; or op:no;.\n
            • \n
            • \n Filter only posts with files (`only`) or only posts without files (`no`).
              \n For example: file:only; or file:no;.\n
            • \n
            • \n Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`).
              \n For example: stub:yes; or stub:no;.\n
            • \n
            • \n Highlight instead of hiding. You can specify a class name to use with a userstyle.
              \n For example: highlight; or highlight:wallpaper;.\n
            • \n
            • \n Highlighted OPs will have their threads put on top of the board index by default.
              \n For example: top:yes; or top:no;.\n
            • \n
            • \n Show a desktop notification instead of hiding.
              \n For example: notify;.\n
            • \n
            • \n Filters in the "General" section apply to multiple fields, by default subject,name,filename,comment.
              \n The fields can be specified with the type option, separated by commas.
              \n For example: type:@{filterTypes};.
              \n Types can also be combined with a + sign; this indicates the filter applies to the given fields joined by newlines.
              \n For example: type:filename+filesize+dimensions;.
              \n
            • \n
            \n' +}),He(".warning",n).hidden=t.Filter},sauce(e){He.extend(e,{ +innerHTML:'
            Sauce is disabled.
            \n\n
            \n \n
            These parameters will be replaced by their corresponding values in the URL and displayed text:
            \n
              \n
            • %IMG: Full image URL for GIF, JPG, and PNG; thumbnail URL for other types.
            • \n
            • %URL: Full image URL.
            • \n
            • %TURL: Thumbnail URL.
            • \n
            • %name: Original file name.
            • \n
            • %board: Current board.
            • \n
            • %MD5: MD5 hash in base64.
            • \n
            • %sMD5: MD5 hash in base64 using - and _.
            • \n
            • %hMD5: MD5 hash in hexadecimal.
            • \n
            • %$0: Matched regular expression within the filename.
            • \n
            • %$1, %$2, %$3, ... : Subexpressions within the matched regular expression.
            • \n
            • %%, %semi: Literal % and ;.
            • \n
            \n
            Lines starting with a # will be ignored.
            \n
            You can specify a display text by appending ;text:[text] to the URL.
            \n
            You can specify the applicable boards/sites by appending ;boards:[board1],[board2]. See the Filter guide for details.
            \n
            You can specify the applicable file types by appending ;types:[extension1],[extension2].
            \n
            You can specify a regular expression the filename must match by appending ;regexp:[regular expression].
            \n
            \n\n' +}),He(".warning",e).hidden=t.Sauce;const n=He("textarea",e);return He.get("sauces",t.sauces,(function(e){return n.value=e.sauces,n.hidden=!1})),He.on(n,"change",He.cb.value)},advanced(e){let n,o;for(var a of(He.extend(e,{ +innerHTML:'
            \n Archives\n
            404 Redirect is disabled.
            \n \n \n \n \n \n \n \n \n
            Thread redirectionPost fetchingFile redirection
            \n
            \n
            \n Archive Lists: Each line below should be an archive list in this format or a URL to load an archive list from.
            \n Archive properties can be overriden by another item with the same uid (or if absent, its name).\n
            \n \n Last updated: \n
            \n\n
            \n External Catalog\n
            External Catalog is disabled. This will be used only as a fallback.
            \n
            \n URLs of external catalog sites, where %board is to be replaced by the board name.
            \n Each URL should be followed by ;boards: and optionally ;exclude: and a list of supported/excluded boards in the format explained in the Filter guide.\n
            \n \n
            \n\n
            \n Override 4chan Image Host\n
            Change 4chan image links to this domain. Leave blank for no change.
            \n
            \n \n
            \n\n
            \n Captcha Language\n
            Choose from list of language codes. Leave blank to autoselect.
            \n
            \n
            \n\n
            \n Custom Board Navigation\n
            \n New lines will be converted into spaces.

            \n
            In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
            \n
            Board link: g
            \n
            Archive link: g-archive
            \n
            Internal archive link: g-expired
            \n
            Title link: g-title
            \n
            Board link (Replace with title when on that board): g-replace
            \n
            Full text link: g-full
            \n
            Custom text link: g-text:"Install Gentoo"
            \n
            Index-only link: g-index
            \n
            Catalog-only link: g-catalog
            \n
            Index mode: g-mode:"infinite scrolling"
            \n
            Index sort: g-sort:"creation date rev"
            \n
            External link: external-text:"Google","http://www.google.com"
            \n
            Open in new tab: g-nt
            \n
            Combinations are possible: g-index-text:"Technology Index"
            \n
            Full board list toggle: toggle-all
            \n
            \n
            \n [ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:"Piracy"]
            \n will give you
            \n [ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
            \n if you are on /g/.\n
            \n
            \n\n
            \n Time Formatting is disabled.\n
            :
            \n \n
            Day: %a, %A, %d, %e
            \n
            Month: %m, %b, %B
            \n
            Year: %y, %Y
            \n
            Hour: %k, %H, %l, %I, %p, %P
            \n
            Minute: %M
            \n
            Second: %S
            \n
            Literal %: %%
            \n \n
            \n\n
            \n Quote Backlinks formatting is disabled.\n
            :
            \n
            \n\n
            \n Default pasted content filename\n
            .png
            \n
            \n\n
            \n File Info Formatting is disabled.\n
            :
            \n
            Link: %l (truncated), %L (untruncated), %T (4chan filename)
            \n
            Filename: %n (truncated), %N (untruncated), %t (4chan filename)
            \n
            Download button: %d
            \n
            Quick filter MD5: %f
            \n
            Spoiler indicator: %p
            \n
            Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
            \n
            Resolution: %r (Displays 'PDF' for PDF files)
            \n
            Tag: %g\n
            Literal %: %%
            \n
            \n\n
            \n Quick Reply Personas\n \n

            \n One item per line.
            \n Items will be added in the relevant input's auto-completion list.
            \n Password items will always be used, since there is no password input.
            \n Lines starting with a # will be ignored.\n

            \n
              You can use these settings with each item, separate them with semicolons:\n
            • Possible items are: name, options (or equivalently email), subject and password.
            • \n
            • Wrap values of items with quotes, like this: options:"sage".
            • \n
            • Force values as defaults with the always keyword, for example: options:"sage";always.
            • \n
            • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
            • \n
            \n
            \n\n
            \n Unread Favicon is disabled.\n \n \n
            \n\n
            \n Thread Updater is disabled.\n
            \n Interval: seconds\n
            \n
            \n\n
            \n Custom Cooldown Time\n
            \n Seconds: \n
            \n
            \n\n
            \n \n \n \n
            For more information about customizing 4chan X's CSS, see the styling guide.
            \n \n \n
            \n\n
            \n Javascript Whitelist\n
            \n Sources from which Javascript is allowed to be loaded by Content Security Policy.
            \n Lines starting with a # will be ignored.\n
            \n \n
            \n\n
            \n Known Banners\n
            List of known banners, used for click-to-change feature.
            \n \n
            \n' +}),u(".warning",e)))a.hidden=t[a.dataset.feature];const i=m();for(n of u("[name]",e))i[n.name]=n;He.on(i.archiveLists,"change",(function(){return He.set("lastarchivecheck",0),t.lastarchivecheck=0,He.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 Re)?"change":"input";He.on(n,s,He.cb["checkbox"===n.type?"checked":"value"]),o in Re&&He.on(n,s,Re[o])}He.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 Re&&Re[t].call(n)}}));const l=He.id("list-fourchanImageHost");for(var d of O.suggestions)He.add(l,He.el("option",{textContent:d}));const c=i.Interval,h=i["Custom CSS"],p=He("#apply-css",e);c.value=t.Interval,h.checked=t["Custom CSS"],i.usercss.disabled=!t["Custom CSS"],p.disabled=!t["Custom CSS"],He.on(c,"change",Te.cb.interval), +He.on(h,"change",Re.togglecss),He.on(p,"click",(()=>be.update()));const g=m();for(o of["archives","selectedArchives","lastarchivecheck"])g[o]=t[o];He.get(g,(function(n){return He.extend(t,n),_e.selectArchives(),Re.addArchiveTable(e)}));const f=He("#archive-board-select",e),b=He("#archive-table",e),A=He("#update-archives",e);return He.on(f,"change",(function(){return He("tbody > :not([hidden])",b).hidden=!0,He(`tbody > .${this.value}`,b).hidden=!1})),He.on(A,"click",(()=>_e.update((()=>Re.addArchiveTable(e)))))},addArchiveTable(e){let o,a;He("#lastarchivecheck",e).textContent=0===t.lastarchivecheck?"never":new Date(t.lastarchivecheck).toLocaleString();const i=He("#archive-board-select",e),r=He("#archive-table",e),s=He("tbody",e);He.rmAll(i),He.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=He.el("tr",{className:`board-${o}`});for(var v of(A.hidden=o!==n.BOARD.ID,b.push(He.el("option",{textContent:`/${o}/`,value:`board-${o}`,selected:o===n.BOARD.ID})),a=l[o],["thread","post","file"]))He.add(A,Re.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),He.add(i,b),He.add(s,f),t.selectedArchives){var w=t.selectedArchives[o];for(var x in w){var y,k=w[x];(y=He(`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=He.el("td",{className:"archive-cell"});if(!o)return a.textContent="--",a;const i=[];let r=0;for(;r"});const l=a.firstElementChild +;return(l.disabled=1===o)||(l.setAttribute("data-boardid",e),l.setAttribute("data-type",n),He.on(l,"change",Re.saveSelectedArchive)),He.add(l,i),a},saveSelectedArchive(){return He.get("selectedArchives",t.selectedArchives,(({selectedArchives:e})=>((e[this.dataset.boardid]||(e[this.dataset.boardid]=m()))[this.dataset.type]=JSON.parse(this.value),He.set("selectedArchives",e),t.selectedArchives=e,_e.selectArchives())))},boardnav(){return Je.generateBoardList(this.value)},time(){return this.nextElementSibling.textContent=De.format(this.value,new Date)},timeLocale:()=>Re.time.call(He("[name=time]",Re.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 Ce.format(this.value,e,this.nextElementSibling)},favicon(){h.switch(),"thread"===n.VIEW&&t["Unread Favicon"]&&Z.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;tKeybinds are disabled.\n
            Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
            \n
            Press Backspace to disable a keybind.
            \n\n \n
            ActionsKeybinds
            \n'}),He(".warning",e).hidden=t.Keybinds;const o=He("tbody",e),a=m(),i=m();for(n in c.hotkeys){var r=c.hotkeys[n],s=He.el("tr",{innerHTML:`${r[1]}`}),l=He("input",s);l.name=n,l.spellcheck=!1,a[n]=t[n],i[n]=l,He.on(l,"keydown",Re.keybind),He.add(o,s)}return He.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,He.cb.value.call(this)}},Be={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=F.checkbox(o,`${e} Tyme`,!1);a.title=`${e} Tyme`,this.nodes[o]=a.firstElementChild,t[o]&&this.set(o,!0),He.on(this.nodes[o],"change",this.toggle.bind(this,o)),Je.menu.addEntry({el:a,order:97});var i=He.el("span",{className:"indicator",textContent:e[0],title:`${e} Tyme active`});He.on(i,"click",(function(){const e=He.getOwn(Be.nodes,this.parentNode.id.replace("shortcut-",""));return e.checked=!e.checked,He.event("change",null,e)})),Je.addShortcut(o,i,410)}return t["Werk Tyme"]&&He.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=He.el("div",{ +textContent:e.name,className:"werkTyme-filename"});return He.add(this.nodes.thumb.parentNode,t)},set(e,t){return this.enabled[e]=this.nodes[e].checked=t,He[(t?"add":"rm")+"Class"](i,`${e}Tyme`)},toggle(e){if(this.set(e,!this.enabled[e]),"werk"===e)return He.cb.checked.call(this.nodes[e])}},Pe={init(){let e;if(!["index","thread"].includes(n.VIEW)||!t.Sauce)return;He.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=He.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!/^.?MD5$/.test(e))).length?(a=Pe.link.cloneNode(!1),a.dataset.skip="1",a):d.length?null:(a=Pe.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)Pe.file(this,e)},file(e,t){let n,o;const a=[],i=[];for(n of Pe.links)(o=Pe.createSauceLink(n,e,t))&&(a.push(He.tn(" "),o),o.dataset.skip&&i.push([n,o]));if(He.add(t.text,a),i.length){var r=new MutationObserver((function(){if(t.text.dataset.md5){for([n,o]of i){var a;(a=Pe.createSauceLink(n,e,t))&&He.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:()=>";"}},Me={init(){if(!(this.enabled=t.Gallery&&["index","thread"].includes(n.VIEW)))return;this.delay=t["Slide Delay"];const e=He.el("a",{href:"javascript:;",title:"Gallery",textContent:"🖼︎"});return He.on(e,"click",this.cb.toggle),Je.addShortcut("gallery",e,530),l.Post.push({name:"Gallery",cb:this.node})},node(){return(()=>{const e=[];for(var o of this.files)o.thumb&&(Me.nodes&&(Me.generateThumb(this,o),Me.nodes.total.textContent=Me.images.length),t["Image Expansion"]||"tinyboard"===n.SITE.software&&Lt.jsEnabled?e.push(void 0):e.push(He.on(o.thumbLink,"click",Me.cb.image)));return e})()},build(e){let o,r;const{cb:s}=Me;t["Fullscreen Gallery"]&&(He.one(a,"fullscreenchange mozfullscreenchange webkitfullscreenchange",(()=>He.on(a,"fullscreenchange mozfullscreenchange webkitfullscreenchange",s.close))),i.mozRequestFullScreen?.(), +i.webkitRequestFullScreen?.(Element.ALLOW_KEYBOARD_INPUT)),Me.images=[];const l=Me.nodes={};Me.fileIDs=m(),Me.slideshow=!1,l.el=o=He.el("div",{id:"a-gallery"}),He.extend(o,{innerHTML:'
            \n \n \n \n \n ×\n \n
            \n \n / \n \n \n \n
            \n
            \n
            \n \n
            \n
            \n
            \n
            \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]=He(h,o)}const p=He(".menu-button",o);for(var g of(l.menu=new F.Menu("gallery"),He.on(l.frame,"click",s.blank),t["Mouse Wheel Volume"]&&He.on(l.frame,"wheel",$.wheel),He.on(l.next,"click",s.click),He.on(l.name,"click",j.download),He.on(He(".gal-prev",o),"click",s.prev),He.on(He(".gal-next",o),"click",s.next),He.on(He(".gal-start",o),"click",s.start),He.on(He(".gal-stop",o),"click",s.stop),He.on(He(".gal-close",o),"click",s.close),He.on(p,"click",(function(e){return l.menu.toggle(e,this,n)})),Me.menu.createSubEntries()))g.order=0,l.menu.addEntry(g);for(var f of(He.on(a,"keydown",s.keybinds),t.Keybinds&&He.off(a,"keydown",Fe.keydown),He.on(window,"resize",Me.cb.setHeight),u(n.SITE.selectors.file.thumb))){var b;if(b=Qe.postFromNode(f))for(var A of b.files)if(A.thumb&&(Me.generateThumb(b,A), +!e&&Me.fileIDs[`${b.fullID}.${A.index}`])){var v=A.thumbLink;Je.getTopOf(v)+v.getBoundingClientRect().height>=0&&(e=v)}}return He.addClass(i,"gallery-open"),He.add(a.body,o),l.thumbs.scrollTop=0,l.current.parentElement.scrollTop=0,e&&(r=He(`[href='${e.href}']`,l.thumbs)),r||(r=Me.images[Me.images.length-1]),r&&Me.open(r),i.style.overflow="hidden",l.total.textContent=Me.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(Me.fileIDs[`${e.fullID}.${n.index}`])return;Me.fileIDs[`${e.fullID}.${n.index}`]=!0;const o=He.el("a",{className:"gal-thumb",href:n.url,target:"_blank",title:n.name});o.dataset.id=Me.images.length,o.dataset.post=e.fullID,o.dataset.file=n.index;const a=n.thumb.cloneNode(!1);return a.style.cssText="",He.add(o,a),He.on(o,"click",Me.cb.open),Me.images.push(o),He.add(Me.nodes.thumbs,o)},load(e,t){const n=e.href.match(/\w*$/),o=He.getOwn({webm:"video",mp4:"video",ogv:"video",pdf:"iframe" +},n)||"img",a=He.el(o);return He.extend(a.dataset,e.dataset),He.on(a,"error",t),a.src=e.href,a},open(e){let o,a,r;const{nodes:s}=Me,l=+s.current.dataset.id,d=+e.dataset.id;if((o=Me.images[l])&&He.rmClass(o,"gal-highlight"),He.addClass(e,"gal-highlight"),s.thumbs.scrollTop=e.offsetTop+e.offsetHeight/2-s.thumbs.clientHeight/2,Me.cache?.dataset.id===""+d?(a=Me.cache,He.off(a,"error",Me.cacheError),He.on(a,"error",Me.error)):a=Me.load(e,Me.error),He.off(s.current,"error",Me.error),j.pause(s.current),He.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),Me.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(),He.rmAll(s.sauce),t.Sauce&&Pe.links&&(r=n.posts.get(a.dataset.post))){const e=[];for(var c of Pe.links){var h +;(h=Pe.createSauceLink(c,r,r.files[+a.dataset.file]))&&e.push(He.tn(" "),h)}He.add(s.sauce,e)}if(Me.slideshow&&(d>l||l===Me.images.length-1&&0===d)?Me.setupTimer():Me.cb.stop(),t["Scroll to Post"]&&(r=n.posts.get(a.dataset.post))&&Je.scrollTo(r.nodes.root),isNaN(l)||d===(l+1)%Me.images.length)return Me.cache=Me.load(Me.images[(d+1)%Me.images.length],Me.cacheError)},error(){if(this.error?.code===MediaError.MEDIA_ERR_DECODE)return new Ke("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 Me.images[+this.dataset.id].href=e,Me.nodes.current===this?this.src=e:void 0}))},cacheError:()=>delete Me.cache,cleanupTimer(){clearTimeout(Me.timeoutID);const{current:e}=Me.nodes;return He.off(e,"canplaythrough load",Me.startTimer),He.off(e,"ended",Me.cb.next)},startTimer:()=>Me.timeoutID=setTimeout(Me.checkTimer,Me.delay*b),setupTimer(){Me.cleanupTimer() +;const{current:e}=Me.nodes,t="VIDEO"===e.nodeName;return t&&e.play(),(t?e.readyState>=4:e.complete)||"IFRAME"===e.nodeName?Me.startTimer():He.on(e,t?"canplaythrough":"load",Me.startTimer)},checkTimer(){const{current:e}=Me.nodes;return"VIDEO"!==e.nodeName||e.paused?Me.cb.next():(He.on(e,"ended",Me.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 Me.cb.close;case t["Next Gallery Image"]:return Me.cb.next;case t["Advance Gallery"]:return Me.cb.advance;case t["Previous Gallery Image"]:return Me.cb.prev;case t.Pause:return Me.cb.pause;case t.Slideshow:return Me.cb.toggleSlideshow;case t["Rotate image anticlockwise"]:return Me.cb.rotateLeft;case t["Rotate image clockwise"]:return Me.cb.rotateRight;case t["Download Gallery Image"]:return Me.cb.download}})();return o?(e.stopPropagation(),e.preventDefault(),o()):void 0},open(e){if(e&&e.preventDefault(),this)return Me.open(this)},image(e){ +return e.preventDefault(),e.stopPropagation(),Me.build(this)},prev:()=>Me.cb.open.call(Me.images[+Me.nodes.current.dataset.id-1]||Me.images[Me.images.length-1]),next:()=>Me.cb.open.call(Me.images[+Me.nodes.current.dataset.id+1]||Me.images[0]),click(e){if(!j.onControls(e))return e.preventDefault(),Me.cb.advance()},advance:()=>!t.Autoplay&&Me.nodes.current.paused?Me.nodes.current.play():Me.cb.next(),toggle:()=>(Me.nodes?Me.cb.close:Me.build)(),blank(e){if(e.target===this)return Me.cb.close()},toggleSlideshow:()=>Me.cb[Me.slideshow?"stop":"start"](),download:()=>He(".gal-name").click(),pause(){Me.cb.stop();const{current:e}=Me.nodes;if("VIDEO"===e.nodeName)return e[e.paused?"play":"pause"]()},start:()=>(He.addClass(Me.nodes.buttons,"gal-playing"),Me.slideshow=!0,Me.setupTimer()),stop(){if(!Me.slideshow)return;Me.cleanupTimer();const{current:e}=Me.nodes;return"VIDEO"===e.nodeName&&(e.loop=!0),He.rmClass(Me.nodes.buttons,"gal-playing"),Me.slideshow=!1},rotateLeft:()=>Me.cb.rotate(270), +rotateRight:()=>Me.cb.rotate(90),rotate:f(100,(function(e){const{current:t}=Me.nodes;if("IFRAME"!==t.nodeName)return t.dataRotate=((t.dataRotate||0)+e)%360,t.style.transform=`rotate(${t.dataRotate}deg)`,Me.cb.setHeight()})),close:()=>(He.off(Me.nodes.current,"error",Me.error),j.pause(Me.nodes.current),He.rm(Me.nodes.el),He.rmClass(i,"gallery-open"),t["Fullscreen Gallery"]&&(He.off(a,"fullscreenchange mozfullscreenchange webkitfullscreenchange",Me.cb.close),a.mozCancelFullScreen?.(),a.webkitExitFullscreen?.()),delete Me.nodes,delete Me.fileIDs,i.style.overflow="",He.off(a,"keydown",Me.cb.keybinds),t.Keybinds&&He.on(a,"keydown",Fe.keydown),He.off(window,"resize",Me.cb.setHeight),clearTimeout(Me.timeoutID)),setFitness(){return(this.checked?He.addClass:He.rmClass)(i,`gal-${this.name.toLowerCase().replace(/\s+/g,"-")}`)},setHeight:f(100,(function(){let e,o,a;const{current:r,frame:s}=Me.nodes,{style:l}=r +;if(t["Stretch to Fit"]&&(e=n.posts.get(r.dataset.post)?.files[+r.dataset.file].dimensions)){const[t,n]=Array.from(e.split("x"));let o=s.clientWidth,d=i.clientHeight-25;(r.dataRotate||0)%180==90&&([o,d]=Array.from([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 Me.delay=+this.value}},menu:{init(){if(!Me.enabled)return;const e=He.el("span",{textContent:"Gallery",className:"gallery-link"});return Je.menu.addEntry({el:e,order:105,subEntries:Me.menu.createSubEntries()})},createSubEntry(e){const t=F.checkbox(e,e),n=t.firstElementChild;return["Hide Thumbnails","Fit Width","Fit Height"].includes(e)&&He.on(n,"change",Me.cb.setFitness),He.event("change",null,n), +He.on(n,"change",He.cb.checked),["Hide Thumbnails","Fit Width","Fit Height","Stretch to Fit"].includes(e)&&He.on(n,"change",Me.cb.setHeight),{el:t}},createSubEntries(){const e=["Hide Thumbnails","Fit Width","Fit Height","Stretch to Fit","Scroll to Post"].map((e=>Me.menu.createSubEntry(e))),t=He.el("label",{innerHTML:'Slide Delay: '}),n=t.firstElementChild;return n.value=Me.delay,He.on(n,"change",Me.cb.setDelay),He.on(n,"change",He.cb.value),e.push({el:t}),e}}},Ne={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=F.dialog("embedding",{ +innerHTML:'
            \n
            \n \n ×\n
            \n
            \n'}),this.media=He("#media-embed",this.dialog),He.one(a,"4chanXInitFinished",this.ready),He.on(a,"IndexRefreshInternal",(()=>n.posts.forEach((function(e){for(e of[e,...Array.from(e.clones)])for(var t of e.nodes.embedlinks)Ne.cb.catalogRemove.call(t)}))))),t["Link Title"]?He.on(a,"4chanXInitFinished PostsInserted",(function(){for(var e in Ne.types){var t=Ne.types[e];t.title?.batchSize&&Ne.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++];)He.on(o,"click",Ne.cb.click),He.hasClass(o,"embedded")&&Ne.cb.toggle.call(o);if(t["Cover Preview"])for(a=0,i=u(".linkify",e.nodes.comment);o=i[a++];){var r;(r=Ne.services(o))&&Ne.preview(r)}else;}},process(e,o){let a +;if((t.Embedding||t["Link Title"]||t["Cover Preview"])&&!He.x("ancestor::pre",e))return(a=Ne.services(e))&&(a.post=o,t.Embedding&&"archive"!==n.VIEW&&Ne.embed(a),t["Link Title"]&&Ne.title(a),t["Cover Preview"]&&"archive"!==n.VIEW)?Ne.preview(a):void 0},services(e){const{href:t}=e;for(var n of Ne.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;He.addClass(r,n.toLowerCase());const d=He.el("a",{className:"embedder",href:"javascript:;"},{innerHTML:"(unembed)"}),c={key:n,uid:o,options:a,href:l};for(var h in c){var u=c[h];d.dataset[h]=u}if(He.on(d,"click",Ne.cb.click),He.after(r,[He.tn(" "),d]),s.nodes.embedlinks.push(d),t["Auto-embed"]&&!t["Floating Embeds"]&&!s.isFetchedQuote)return He.hasClass(i,"catalog-mode")?He.addClass(d,"embed-removed"):Ne.cb.toggle.call(d)},ready(){if(Lt.isThisPageLegit())return He.addClass(Ne.dialog,"empty"), +He.on(He(".close",Ne.dialog),"click",Ne.closeFloat),He.on(He(".move",Ne.dialog),"mousedown",Ne.dragEmbed),He.on(He(".jump",Ne.dialog),"click",(function(){if(i.contains(Ne.lastEmbed))return Je.scrollTo(Ne.lastEmbed)})),He.add(a.body,Ne.dialog)},closeFloat:()=>(delete Ne.lastEmbed,He.addClass(Ne.dialog,"empty"),He.replace(Ne.media.firstChild,He.el("div"))),dragEmbed(){const{style:e}=Ne.media;return Ne.dragEmbed.mouseup?(He.off(a,"mouseup",Ne.dragEmbed),Ne.dragEmbed.mouseup=!1,void(e.pointerEvents="")):(He.on(a,"mouseup",Ne.dragEmbed),Ne.dragEmbed.mouseup=!0,e.pointerEvents="none")},title(e){let t;const{key:n,uid:o,options:a,link:i,post:r}=e;if(t=Ne.types[n].title)return He.addClass(i,n.toLowerCase()),t.batchSize?((t.queue||(t.queue=[])).push(e),t.queue.length>=t.batchSize?Ne.flushTitles(t):void 0):qe.cache(t.api(o),(function(){return Ne.cb.title(this,e)}))},flushTitles(e){let t;const{queue:n}=e;if(!n?.length)return;e.queue=[];return qe.cache(e.api((()=>{const e=[] +;for(t of n)e.push(t.uid);return e})()),(function(){for(t of n)Ne.cb.title(this,t)}))},preview(e){let t;const{key:n,uid:o,link:a}=e;if(t=Ne.types[n].preview)return He.on(a,"mouseover",(function(e){const n=t.url(o),{height:i}=t,r=He.el("img",{src:n,id:"ihover"});return He.add(Je.hover,r),F.hover({root:a,el:r,latestEvent:e,endEvents:"mouseout click",height:i})}))},cb:{click(e){if(e.preventDefault(),He.hasClass(this,"embedded")||!t["Floating Embeds"]&&!He.hasClass(i,"catalog-mode"))return Ne.cb.toggle.call(this);{let e;if(!(e=Ne.media.firstChild))return;return He.replace(e,Ne.cb.embed(this)),Ne.lastEmbed=Qe.postFromNode(this).nodes.root,He.rmClass(Ne.dialog,"empty")}},toggle(){return He.hasClass(this,"embedded")?He.rm(this.nextElementSibling):He.after(this,Ne.cb.embed(this)),He.toggleClass(this,"embedded")},embed(e){let t,n;const o=He.el("div",{className:"media-embed"});return He.add(o,t=(n=Ne.types[e.dataset.key]).el(e)), +t.style.cssText=null!=n.style?n.style:"border: none; width: 640px; height: 360px;",o},catalogRemove(){const e=He.hasClass(i,"catalog-mode");if(e&&He.hasClass(this,"embedded")||!e&&He.hasClass(this,"embed-removed"))return Ne.cb.toggle.call(this),He.toggleClass(this,"embed-removed")},title(e,t){let n;const{key:o,uid:a,options:i,link:r,post:s}=t,l=Ne.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=>He.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 He.el("div",{innerHTML:``})}},{key:"video",regExp:/^[^?#]+\.(?:og[gv]|webm|mp4)(?:[?#]|$)/i,style:"max-width: 80vw; max-height: 80vh;",el(e){const t=He.el("video",{hidden:!0,controls:!0,preload:"auto",src:e.dataset.href,loop:O.test(e.dataset.href.split("/")[2])});return He.on(t,"loadedmetadata",(function(){return 0===t.videoHeight&&t.parentNode?He.replace(t,Ne.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=He.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=He.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=>He.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=He.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=He.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=He.el("pre",{hidden:!0,id:"gist-embed-"+e++});return qe.cache(`https://api.github.com/gists/${t.dataset.uid}`,(function(){return n.textContent=Object.values(this.response.files)[0].content,n.className="prettyprint",He.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=>He.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=He.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=He.el("video",{controls:!0,preload:"auto",loop:!0});if(/^http/.test(e.dataset.uid))return He.add(t,He.el("source",{src:e.dataset.uid})),t;const[n,o,a]=Array.from(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)He.add(t,He.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=He.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=>He.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=>He.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=>He.el("iframe",{src:`https://www.strawpoll.me/embed_1/${e.dataset.uid}`})},{key:"Streamable",regExp:/^\w+:\/\/(?:www\.)?streamable\.com\/(\w+)/,el(e){const t=He.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=He.el("iframe",{src:t});return o.setAttribute("allowfullscreen","true"),o}},{key:"Twitter",regExp:/^\w+:\/\/(?:www\.|mobile\.)?twitter\.com\/(\w+\/status\/\d+)/,style:"border: none; width: 550px; height: 250px; overflow: hidden; resize: both;",el(e){const t=He.el("iframe");He.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 He.off(window,"message",n),(o||t).style.height=+He.minmax(e.data.height,250,.8*i.clientHeight)+"px"};if(He.on(window,"message",n),t.src=`https://twitframe.com/show?url=https://twitter.com/${e.dataset.uid}`,"gecko"===He.engine){t.style.cssText="border: none; width: 100%; height: 100%;";var o=He.el("div");return He.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=He.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=He.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=>He.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=He.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=He.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)He.sync(e,Fe.sync);var n=function(){for(var e of(He.off(a,"4chanXInitFinished",n),He.on(a,"keydown",Fe.keydown),u("[accesskey]")))e.removeAttribute("accesskey")};return He.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=L.getThread(),a=Qe.threadFromRoot(i)),o){case t["Toggle board list"]:if(!t["Custom Board Navigation"])return;Je.toggleBoardList() +;break;case t["Toggle header"]:Je.toggleBarVisibility();break;case t["Open empty QR"]:if(!Oe.postingIsEnabled)return;Fe.qr();break;case t["Open QR"]:if(!Oe.postingIsEnabled||!i)return;Fe.qr(i);break;case t["Open settings"]:Re.open();break;case t.Close:if(Re.dialog)Re.close();else if((s=u(".notification")).length)for(var d of s)He(".close",d).click();else if(Oe.nodes&&!Oe.nodes.el.hidden&&"none"!==window.getComputedStyle(Oe.nodes.form).display)t["Persistent QR"]?Oe.hide():Oe.close();else{if(!Ne.lastEmbed)return;Ne.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(!Oe.nodes||Oe.nodes.el.hidden)return +;Fe.sage();break;case t["Toggle Cooldown"]:if(!Oe.nodes||Oe.nodes.el.hidden||!He.hasClass(Oe.nodes.fileSubmit,"custom-cooldown"))return;Oe.toggleCustomCooldown();break;case t["Post from URL"]:if(!Oe.postingIsEnabled)return;Oe.handleUrl("");break;case t["Add new post"]:if(!Oe.postingIsEnabled)return;Oe.addPost();break;case t["Submit QR"]:if(!Oe.nodes||Oe.nodes.el.hidden)return;Oe.status()||Oe.submit();break;case t.Update:switch(n.VIEW){case"thread":if(!Te.enabled)return;Te.update();break;case"index":if(!se.enabled)return;se.update();break;default:return}break;case t.Watch:if(!oe.enabled||!a)return;oe.toggle(a);break;case t["Update thread watcher"]:if(!oe.enabled)return;oe.buttonFetchAll();break;case t["Toggle thread watcher"]:if(!oe.enabled)return;oe.toggleWatcher();break;case t["Toggle threading"]:if(!Se.ready)return;Se.toggleThreading();break;case t["Mark thread read"]:if("index"!==n.VIEW||!a||!te.enabled)return;te.markRead.call(i);break;case t["Expand image"]:if(!q.enabled||!i)return +;var c=Qe.postFromNode(Fe.post(i));c.file&&q.toggle(c);break;case t["Expand images"]:if(!q.enabled)return;q.cb.toggleAll();break;case t["Open Gallery"]:if(!Me.enabled)return;Me.cb.toggle();break;case t.fappeTyme:if(!Be.nodes?.fappe)return;Be.toggle("fappe");break;case t.werkTyme:if(!Be.nodes?.werk)return;Be.toggle("werk");break;case t["Front page"]:se.enabled?se.userPageNav(1):location.href=`/${n.BOARD}/`;break;case t["Open front page"]:He.open(`${location.origin}/${n.BOARD}/`);break;case t["Next page"]:if("index"!==n.VIEW||n.SITE.isOnePage?.(n.BOARD))return;if(se.enabled){if(!["paged","infinite"].includes(t["Index Mode"]))return;He(".next button",se.pagelist).click()}else He(n.SITE.selectors.nav.next)?.click();break;case t["Previous page"]:if("index"!==n.VIEW||n.SITE.isOnePage?.(n.BOARD))return;if(se.enabled){if(!["paged","infinite"].includes(t["Index Mode"]))return;He(".prev button",se.pagelist).click()}else He(n.SITE.selectors.nav.prev)?.click();break;case t["Search form"]: +if("index"!==n.VIEW)return;var h=se.enabled?se.searchInput:n.SITE.selectors.searchBox?He(n.SITE.selectors.searchBox):void 0;if(!h)return;Je.scrollToIfNeeded(h),h.focus();break;case t["Paged mode"]:if(!se.enabledOn(n.BOARD))return;location.href="index"===n.VIEW?"#paged":`/${n.BOARD}/#paged`;break;case t["Infinite scrolling mode"]:if(!se.enabledOn(n.BOARD))return;location.href="index"===n.VIEW?"#infinite":`/${n.BOARD}/#infinite`;break;case t["All pages mode"]:if(!se.enabledOn(n.BOARD))return;location.href="index"===n.VIEW?"#all-pages":`/${n.BOARD}/#all-pages`;break;case t["Open catalog"]:if(!(r=Ge.catalog()))return;location.href=r;break;case t["Cycle sort type"]:if(!se.enabled)return;se.cycleSortType();break;case t["Next thread"]:if("index"!==n.VIEW||!i)return;L.scroll(1);break;case t["Previous thread"]:if("index"!==n.VIEW||!i)return;L.scroll(-1);break;case t["Expand thread"]:if("index"!==n.VIEW||!i)return;ee.toggle(a),Je.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||!le.db)return;Je.scrollTo(i),le.toggle(a);break;case t["Quick Filter MD5"]:if(!i)return;c=Fe.post(i),Fe.hl(1,i),ze.quickFilterMD5.call(c,e);break;case t["Previous Post Quoting You"]:if(!i||!X.db)return;X.cb.seek("preceding");break;case t["Next Post Quoting You"]:if(!i||!X.db)return;X.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 He(`${t.postContainer}${t.highlightable.reply}.${n.SITE.classes.highlight}`,e)||He(`${n.SITE.isOPContainerThread?t.thread:t.postContainer}${t.highlightable.op}`,e)},qr:e=>(Oe.open(),null!=e&&Oe.quote.call(Fe.post(e)),Oe.nodes.com.focus()),tags(e,t){G.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 Ke("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),He.event("input",null,t)},sage(){const e=/sage/i.test(Oe.nodes.email.value);return Oe.nodes.email.value=e?"":"sage"},open(e,t){if("index"!==n.VIEW)return;const o=Qe.url("thread",e);return t?He.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=He(`${o}.${a}`,t);if(!e)return void(i&&He.rmClass(i,a));if(i){const{height:t}=i.getBoundingClientRect();if(Je.getTopOf(i)>=-t&&Je.getBottomOf(i)>=-t){let t;const{root:r}=Qe.postFromNode(i).nodes,s=1===e?"following":"preceding";if(!(t=He.x(`${s}-sibling::${n.SITE.xpath.replyContainer}[not(@hidden) and not(child::div[@class='stub'])][1]`,r)))return;return t.matches(o)||(t=He(o,t)),Je.scrollToIfNeeded(t,1===e),He.addClass(t,a),void He.rmClass(i,a)}He.rmClass(i,a)}const r=u(o,t);for(var s of(-1===e&&r.reverse(),r))if(1===e&&Je.getTopOf(s)>0||-1===e&&Je.getBottomOf(s)>0)return void He.addClass(s,a)}};const Le={Cache:{init(){ +return He.on(a,"SaveCaptcha",(e=>this.saveAPI(e.detail))),He.on(a,"NoCaptcha",(e=>this.noCaptcha(e.detail)))},captchas:[],getCount(){return this.captchas.length},neededRaw(){return!(this.haveCookie()||this.captchas.length||Oe.req||this.submitCB)&&(Oe.posts.length>1||t["Auto-load captcha"]||!Oe.posts[0].isOnlyQuotes()||Oe.posts[0].file)},needed(){return this.neededRaw()&&He.event("LoadCaptcha")},prerequest(){if(t["Prerequest Captcha"])return He.queueTask((()=>{if(!this.prerequested&&this.neededRaw()&&!He.event("LoadCaptcha")&&!Oe.captcha.occupied()&&Oe.cooldown.seconds<=60&&Oe.selected===Oe.posts[Oe.posts.length-1]&&!Oe.selected.isOnlyQuotes()){const e="new"!==Oe.selected.thread;if(!He.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"!==Oe.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||!He.event("RequestCaptcha",{isReply:e}))return e=>(this.submitCB=e,this.updateCount())},abort(){if(this.submitCB)return delete this.submitCB,He.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||(Oe.error(e?.error||"Failed to retrieve captcha."),Oe.captcha.setup(a.activeElement===Oe.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;et)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 He.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=!!He("#g-recaptcha, #captcha-forced-noscript")||!He.id("postForm")))return;(this.noscript=t["Force Noscript Captcha"]||!Lt.jsEnabled)&&He.addClass(Oe.nodes.el,"noscript-captcha"),Le.cache.init(),He.on(a,"CaptchaCount",this.count.bind(this));const e=He.el("div",{className:"captcha-root"});He.extend(e,{innerHTML:'
            '});const n=He(".captcha-counter > a",e);return this.nodes={root:e,counter:n},this.count(),He.addClass(Oe.nodes.el,"has-captcha","captcha-v2"),He.after(Oe.nodes.com.parentNode,e),He.on(n,"click",this.toggle.bind(this)),He.on(n,"keydown",(e=>{if("Space"===Fe.keyCode(e))return this.toggle(),e.preventDefault(), +e.stopPropagation()})),He.on(window,"captcha:success",(()=>He.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 He.queueTask((()=>{const e=Le.cache.needed();return e&&!this.prevNeeded&&this.setup(Oe.cooldown.auto&&a.activeElement===Oe.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&&(Le.cache.needed()||t)){if(e&&(He.addClass(Oe.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=He.el("div",{className:"captcha-container"}),He.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();He.queueTask((()=>{let e;if(this.nodes.container&&a.activeElement===this.nodes.counter&&(e=He('iframe[src^="https://www.google.com/recaptcha/"]',this.nodes.container)))return e.focus(),Oe.focus()}))}},setupNoscript(){const e=He.el("iframe",{id:"qr-captcha-iframe",scrolling:"no",src:this.noscriptURL()}),t=He.el("div"),n=He.el("textarea");return He.add(t,n),He.add(this.nodes.container,[e,t])},setupJS:()=>He.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=He.x('./descendant-or-self::iframe[starts-with(@src, "https://www.google.com/recaptcha/")]',n))&&this.setupIFrame(o),(a=He.x("./descendant-or-self::textarea",n))&&this.setupTextArea(a)}},setupIFrame(e){let t;if(doc.contains(e))return Le.replace.iframe(e),He.addClass(Oe.nodes.el,"captcha-open"),this.fixQRPosition(),He.on(e,"load",this.fixQRPosition),a.activeElement===this.nodes.counter&&e.focus(),["blink","edge"].includes(He.engine)&&(t=e.parentNode,u("#qr .captcha-container > div > div:first-of-type").includes(t))?He.on(e.parentNode,"scroll",(function(){return this.scrollTop=0 +})):void 0},fixQRPosition(){if(Oe.nodes.el.getBoundingClientRect().bottom>doc.clientHeight)return Oe.nodes.el.style.top="",Oe.nodes.el.style.bottom="0px"},setupTextArea(e){return He.one(e,"input",(()=>this.save(!0)))},destroy(){if(this.isEnabled)return delete this.timeouts.destroy,He.rmClass(Oe.nodes.el,"captcha-open"),this.nodes.container?(He.global((function(){const e=document.querySelector("#qr .captcha-container");return window.grecaptcha.reset(e.dataset.widgetID)})),He.rm(this.nodes.container),delete this.nodes.container):void 0},getOne:e=>Le.cache.getOne(e),save(e,n){Le.cache.save({response:n||He("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(Le.cache.needed()?(o&&(Oe.cooldown.auto||t["Post on Captcha Completion"]?this.nodes.counter.focus():Oe.nodes.status.focus()), +this.reload()):(e?this.destroy():null==this.timeouts.destroy&&(this.timeouts.destroy=setTimeout(this.destroy.bind(this),3e3)),o&&Oe.nodes.status.focus()),t["Post on Captcha Completion"]&&!Oe.cooldown.auto)return Oe.submit()},count(){const e=Le.cache.getCount(),t=Le.cache.submitCB?"...":"";return this.nodes.counter.textContent=`Captchas: ${e}${t}`,this.moreNeeded()},reload(){return He('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]',this.nodes.container)?(this.destroy(),this.setup(!1,!0)):He.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 Oe={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=[],He.on(a,"4chanXInitFinished",(()=>G.ready(Oe.initReady))),l.Post.push({name:"Quick Reply",cb:this.node}),this.shortcut=e=He.el("a",{className:"disabled",textContent:"↩",title:"Quick Reply",href:"javascript:;"}),He.on(e,"click",(function(){if(Oe.postingIsEnabled)return t["Persistent QR"]||!Oe.nodes||Oe.nodes.el.hidden?(Oe.open(),Oe.nodes.com.focus()):Oe.close()})),Je.addShortcut("qr",e,540)},initReady(){let e;const o=He("#g-recaptcha, #captcha-forced-noscript")?"v2":"t";Oe.captcha=Le[o],Oe.postingIsEnabled=!0;const{config:i}=n.BOARD,r=(e,t)=>+(i[e]??t);if(Oe.min_width=r("min_image_width",1),Oe.min_height=r("min_image_height",1), +Oe.max_width=Oe.max_height=1e4,Oe.max_size=r("max_filesize",4194304),Oe.max_size_video=r("max_webm_filesize",Oe.max_size),Oe.max_comment=r("max_comment_chars",2e3),Oe.max_width_video=Oe.max_height_video=2048,Oe.max_duration_video=r("max_webm_duration",120),Oe.forcedAnon=!!i.forced_anon,Oe.spoiler=!!i.spoilers,e=He.id("togglePostFormLink")){const t=He.el("h1",{className:"qr-link-container"});He.extend(t,{innerHTML:`${"thread"===n.VIEW?"Reply to Thread":"Start a Thread"}`}),Oe.link=t.firstElementChild,He.on(t.firstChild,"click",(function(){return Oe.open(),Oe.nodes.com.focus()})),He.before(e,t),e.firstElementChild.textContent="Original Form"}if("thread"===n.VIEW){let e;const t=He.el("div",{className:"brackets-wrap qr-link-container-bottom"});He.extend(t,{innerHTML:'Reply to Thread'}),He.on(t.firstElementChild,"click",(function(){return Oe.open(),Oe.nodes.com.focus()})), +(e=He(".navLinksBot"))&&He.prepend(e,t)}if(He.on(a,"QRGetFile",Oe.getFile),He.on(a,"QRDrawFile",Oe.drawFile),He.on(a,"QRSetFile",Oe.setFile),He.on(a,"paste",Oe.paste),He.on(a,"dragover",Oe.dragOver),He.on(a,"drop",Oe.dropFile),He.on(a,"dragstart dragend",Oe.drag),He.on(a,"IndexRefreshInternal",Oe.generatePostableThreadsList),He.on(a,"ThreadUpdate",Oe.statusCheck),t["Persistent QR"])return Oe.open(),t["Auto Hide QR"]?Oe.hide():void 0},statusCheck(){if(!Oe.nodes)return;const{thread:e}=Oe.posts[0];return"new"!==e&&n.threads.get(`${n.BOARD}.${e}`).isDead?Oe.abort():Oe.status()},node(){if(He.on(this.nodes.quote,"click",Oe.quote),this.isFetchedQuote)return Oe.generatePostableThreadsList()},open(){if(Oe.nodes)Oe.nodes.el.hidden&&Oe.captcha.setup(),Oe.nodes.el.hidden=!1,Oe.unhide();else try{Oe.dialog()}catch(e){return delete Oe.nodes,void Lt.handleErrors({message:"Quick Reply dialog creation crashed.",error:e})}return He.rmClass(Oe.shortcut,"disabled")},close(){if(!Oe.req){ +for(var e of(Oe.nodes.el.hidden=!0,Oe.cleanNotifications(),Oe.blur(),He.rmClass(Oe.nodes.el,"dump"),He.addClass(Oe.shortcut,"disabled"),new Oe.post(!0),Oe.posts.splice(0,Oe.posts.length-1)))e.delete();return Oe.cooldown.auto=!1,Oe.status(),Oe.captcha.destroy()}Oe.abort()},focus:()=>He.queueTask((function(){if(!Oe.inBubble())return Oe.hasFocus=a.activeElement&&Oe.nodes.el.contains(a.activeElement),Oe.nodes.el.classList.toggle("focus",Oe.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:()=>(Oe.blur(),He.addClass(Oe.nodes.el,"autohide"),Oe.nodes.autohide.checked=!0),unhide:()=>(He.rmClass(Oe.nodes.el,"autohide"),Oe.nodes.autohide.checked=!1),toggleHide(){return this.checked?Oe.hide():Oe.unhide()},blur(){if(Oe.nodes.el.contains(a.activeElement))return a.activeElement.blur()},toggleSJIS:e=>(e.preventDefault(), +t.sjisPreview=!t.sjisPreview,He.set("sjisPreview",t.sjisPreview),Oe.nodes.el.classList.toggle("sjis-preview",t.sjisPreview)),texPreviewShow:()=>He.hasClass(Oe.nodes.el,"tex-preview")?Oe.texPreviewHide():(He.addClass(Oe.nodes.el,"tex-preview"),Oe.nodes.texPreview.textContent=Oe.nodes.com.value,He.event("mathjax",null,Oe.nodes.texPreview)),texPreviewHide:()=>He.rmClass(Oe.nodes.el,"tex-preview"),addPost(){const e=Oe.nodes&&!Oe.nodes.el.hidden;return Oe.open(),e&&(He.addClass(Oe.nodes.el,"dump"),new Oe.post(!0)),Oe.nodes.com.focus()},setCustomCooldown:e=>(t.customCooldownEnabled=e,Oe.cooldown.customCooldown=e,Oe.nodes.customCooldown.classList.toggle("disabled",!e)),toggleCustomCooldown(){const e=He.hasClass(Oe.nodes.customCooldown,"disabled");return Oe.setCustomCooldown(e),He.set("customCooldownEnabled",e)},error(e,t){let n;Oe.open(),"string"==typeof e?n=He.tn(e):(n=e,n.removeAttribute("style"));const o=new Ke("warning",n);if(Oe.notifications.push(o),Je.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"!==He.engine)return e.onclose=()=>o.close(),e.onshow=()=>setTimeout((function(){return e.onclose=null,e.close()}),7e3)}}else if(a.hidden&&!Oe.cooldown.auto)return alert(n.textContent)},connectionError:()=>He.el("span",{innerHTML:'Connection error while posting. [More info]'}),notifications:[],cleanNotifications(){for(var e of Oe.notifications)e.close();return Oe.notifications=[]},status(){let e,t;if(!Oe.nodes)return;const{thread:o}=Oe.posts[0];"new"!==o&&n.threads.get(`${n.BOARD}.${o}`).isDead&&(t="Dead",e=!0,Oe.cooldown.auto=!1),t=Oe.req?Oe.req.progress:Oe.cooldown.seconds||t;const{status:a}=Oe.nodes;return a.value=t?Oe.cooldown.auto?`Auto ${t}`:t:"Submit",a.disabled=e||!1},openPost(){if(Oe.open(),Oe.selected.isLocked){const e=Oe.posts.indexOf(Oe.selected) +;return(Oe.posts[e+1]||new Oe.post).select(),He.addClass(Oe.nodes.el,"dump"),Oe.cooldown.auto=!0}},quote(e){let t;if(e?.preventDefault(),!Oe.postingIsEnabled)return;const o=a.getSelection(),i=Qe.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?ea;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(He.x('ancestor-or-self::*[self::s or contains(@class,"removed-spoiler")]',p)&&(He.prepend(h,He.tn("[spoiler]")),He.add(h,He.tn("[/spoiler]"))),(d=He.x('ancestor-or-self::pre[contains(@class,"prettyprint")]',p))&&(He.prepend(h,He.tn("[code]")),He.add(h,He.tn("[/code]"))),u(d?"br":".prettyprint br",h)))He.replace(c,He.tn("\n")) +;for(c of u("br",h))c!==h.lastChild&&He.replace(c,He.tn("\n>"));for(c of(n.SITE.insertTags?.(h),u(".linkify[data-original]",h)))He.replace(c,He.tn(c.dataset.original));for(c of u(".embedder",h))" "===c.previousSibling?.nodeValue&&He.rm(c.previousSibling),He.rm(c);l+=`>${h.textContent.trim()}\n`}catch(e){}Oe.openPost();const{com:g,thread:f}=Oe.nodes;g.value||(f.value=Qe.threadFromNode(this));const m=Oe.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&&(Oe.selected.quotedText=g.value),Oe.selected.save(g),Oe.selected.save(f)},characterCount(){const e=Oe.nodes.charCount,t=Oe.nodes.com.value.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"_").length;return e.textContent=t,e.hidden=tOe.max_comment?He.addClass:He.rmClass)(e,"warning")},getFile:()=>He.event("QRFile",Oe.selected?.file),drawFile(e){const t=Oe.selected?.file;if(!t||!/^(image|video)\//.test(t.type))return +;const n=/^video\//.test(t),o=He.el(n?"video":"img");return He.on(o,"error",(()=>Oe.openError())),He.on(o,n?"loadeddata":"load",(function(){return e.target.getContext("2d").drawImage(o,0,0),URL.revokeObjectURL(o.src),He.event("QRImageDrawn",null,e.target)})),o.src=URL.createObjectURL(t)},openError(){const t=He.el("div");return He.extend(t,{innerHTML:'Could not open file. [More info]'}),Oe.error(t)},setFile(e){const{file:t,name:n,source:o}=e.detail;return null!=n&&(t.name=n),null!=o&&(t.source=o),Oe.open(),Oe.handleFiles([t])},drag(e){const t="dragstart"===e.type?He.off:He.on;return t(a,"dragover",Oe.dragOver),t(a,"drop",Oe.dropFile)},dragOver:e=>(e.preventDefault(),e.dataTransfer.dropEffect="copy"),dropFile(e){if(e.dataTransfer.files.length)return e.preventDefault(),Oe.open(),Oe.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<=Oe.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}.${He.getOwn(Oe.extensionFromType,e)||"jpg"}`,Oe.open(),Oe.handleFiles([o]),He.addClass(Oe.nodes.el,"dump")}},pasteFF(){const{pasteArea:e}=Oe.nodes;if(!e.childNodes.length)return;const n=u("img",e);for(var o of(He.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?ld;c?l++:l--)s[l]=r.charCodeAt(l);var h=new Blob([s],{type:a[1]});h.name=`${t.pastedname}.${a[2]}`,Oe.handleFiles([h])}else/^https?:\/\//.test(i)&&Oe.handleUrl(i)}},handleUrl:e=>(Oe.open(),Oe.selected.preventAutoPost(),qe.permission((function(){const t=prompt("Enter a URL:",e);if(null!==t)return Oe.nodes.fileButton.focus(),qe.file(t,(function(e){return e&&!/^text\//.test(e.type)?Oe.handleFiles([e]):Oe.error("Can't load file.")}))}))), +handleFiles(e){if(this!==Oe&&(e=[...Array.from(this.files)],this.value=null),e.length){for(var t of(Oe.cleanNotifications(),e))Oe.handleFile(t,e.length);return 1!==e.length&&He.addClass(Oe.nodes.el,"dump"),a.activeElement===Oe.nodes.fileButton&&He.hasClass(Oe.nodes.fileSubmit,"has-file")?Oe.nodes.filename.focus():void 0}},handleFile(e,t){let n;const o=/^text\//.test(e.type);return 1===t?n=Oe.selected:(n=Oe.posts[Oe.posts.length-1],(o?n.com||n.pasting:n.file)&&(n=new Oe.post)),n[o?"pasteText":"setFile"](e)},openFileInput(){if(!Oe.nodes.fileButton.disabled)return Oe.nodes.fileInput.click(),Oe.nodes.fileButton.focus()},generatePostableThreadsList(){if(!Oe.nodes)return;const e=Oe.nodes.thread,t=[e.firstElementChild];for(var o of n.BOARD.threads.keys)t.push(He.el("option",{value:o,textContent:`Thread ${o}`}));const a=e.value;return He.rmAll(e),He.add(e,t),e.value=a,e.value!==a?(e.value="thread"===n.VIEW?n.THREADID:"new", +("thread"===n.VIEW?He.addClass:He.rmClass)(Oe.nodes.el,"reply-to-thread")):void 0},dialog(){let e,o,i,r;Oe.nodes=i={el:e=F.dialog("qr",{ +innerHTML:'
            \n \n ×\n \n
            \n
            \n
            \n \n \n \n \n \n
            \n
            \n \n \n
            \n
            \n
            \n
            \n +\n
            \n \n
            \n \n \n No selected file\n \n \n ✎︎\n \n 🔗︎\n \n 🕒︎\n +\n \n \n
            \n \n \n
            \n\n\n\n' +})};const s=(t,n)=>i[t]=He(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}=Oe.nodes.el +;d.toggle("forced-anon",Oe.forcedAnon),d.toggle("has-spoiler",Oe.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&&(He.addClass(Oe.nodes.fileSubmit,"custom-cooldown"),He.get("customCooldownEnabled",t.customCooldownEnabled,(function({customCooldownEnabled:e}){return Oe.setCustomCooldown(e),He.sync("customCooldownEnabled",Oe.setCustomCooldown)}))),Oe.flagsInput(),He.on(i.autohide,"change",Oe.toggleHide),He.on(i.close,"click",Oe.close),He.on(i.status,"click",Oe.submit),He.on(i.form,"submit",Oe.submit),He.on(i.sjisToggle,"click",Oe.toggleSJIS),He.on(i.texButton,"mousedown",Oe.texPreviewShow),He.on(i.texButton,"mouseup",Oe.texPreviewHide),He.on(i.addPost,"click",(()=>new Oe.post(!0))),He.on(i.drawButton,"click",Oe.oekaki.draw),He.on(i.fileButton,"click",Oe.openFileInput), +He.on(i.noFile,"click",Oe.openFileInput),He.on(i.filename,"focus",(function(){return He.addClass(this.parentNode,"focus")})),He.on(i.filename,"blur",(function(){return He.rmClass(this.parentNode,"focus")})),He.on(i.spoiler,"change",(()=>Oe.selected.nodes.spoiler.click())),He.on(i.oekakiButton,"click",Oe.oekaki.button),He.on(i.fileRM,"click",(()=>Oe.selected.rmFile())),He.on(i.urlButton,"click",(()=>Oe.handleUrl(""))),He.on(i.customCooldown,"click",Oe.toggleCustomCooldown),He.on(i.dumpButton,"click",(()=>i.el.classList.toggle("dump"))),He.on(i.fileInput,"change",Oe.handleFiles),window.addEventListener("focus",Oe.focus,!0),window.addEventListener("blur",Oe.focus,!0),He.on(a,"click",Oe.focus),"gecko"!==He.engine||window.DataTransferItemList||(i.pasteArea.hidden=!1),new MutationObserver(Oe.pasteFF).observe(i.pasteArea,{childList:!0});const c=["thread","name","email","sub","com","filename","flag"];let h=0;const u=function(){return Oe.selected.save(this)};for(;r=c[h++];){var p +;(p=i[r])&&(o="SELECT"===p.nodeName?"change":"input",He.on(i[r],o,u))}return"gecko"===He.engine&&t["Remember QR Size"]&&(He.get("QR Size","",(e=>i.com.style.cssText=e["QR Size"])),He.on(i.com,"mouseup",(function(e){if(0===e.button)return He.set("QR Size",this.style.cssText)}))),Oe.generatePostableThreadsList(),Oe.persona.load(),new Oe.post(!0),Oe.status(),Oe.cooldown.setup(),Oe.captcha.init(),He.add(a.body,e),Oe.captcha.setup(),Oe.oekaki.setup(),He.event("QRDialogCreation",null,e)},flags(){const e=He.el("select",{name:"flag",className:"flagSelector"}),t=(t,n)=>He.add(e,He.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}=Oe;if(e&&(e.flag&&(He.rm(e.flag),delete e.flag),n.BOARD.config.board_flags)){const t=Oe.flags();return t.dataset.name="flag",t.dataset.default="0",e.flag=t,He.add(e.form,t)}},submit(e){let o,i,r +;e?.preventDefault();const s=e?.shiftKey;if(Oe.req)return void Oe.abort();if(He.forceSync("cooldowns"),Oe.cooldown.seconds){if(!s)return Oe.cooldown.auto=!Oe.cooldown.auto,void Oe.status();Oe.cooldown.clear()}const l=Oe.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=Oe.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."),!Oe.captcha.isEnabled||Oe.captcha===Le.v2&&/\b_ct=/.test(a.cookie)&&d||i&&!s||(o=Oe.captcha.getOne(!!d),Oe.captcha===Le.v2&&(o||(o=Le.cache.request(!!d))),o||(i="No valid captcha.", +Oe.captcha.setup(!Oe.cooldown.auto||a.activeElement===Oe.nodes.status))),Oe.cleanNotifications(),i&&!s)return Oe.cooldown.auto=!1,Oe.status(),void Oe.error(i);Oe.cooldown.auto=Oe.posts.length>1,l.lock();const h={MAX_FILE_SIZE:Oe.max_size,mode:"regist",pwd:Oe.persona.getPassword(),resto:d,name:Oe.forcedAnon?void 0:l.name,email:l.email,sub:Oe.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:Oe.response,form:He.formData(h)};t["Show Upload Progress"]&&(u.onprogress=function(e){if(this===Oe.req?.upload)return e.loaded(Oe.captcha===Le.v2&&Le.cache.abort(),p=null)},o((function(e){return Oe.captcha===Le.v2&&Le.cache.haveCookie()?(p?.(),e?Le.cache.save(e):void 0):e?p?.(e):(delete Oe.req,l.unlock(),Oe.cooldown.auto=!!Le.cache.getCount(),Oe.status())}))):p(o),Oe.status()},response(){let e,o;if(this!==Oe.req)return;delete Oe.req;const i=Oe.posts[0];if(i.unlock(),o=this.response?.getElementById("errmsg")){const e=He("a",o);e&&(e.target="_blank")}else(e=!this.response||"Post successful!"!==this.response.title)?(o=Oe.connectionError(),Oe.captcha===Le.v2&&Oe.currentCaptcha&&Le.cache.save(Oe.currentCaptcha)):200!==this.status&&(o=`Error ${this.statusText} (${this.status})`) +;if(e||Oe.captcha.setUsed?.(),delete Oe.currentCaptcha,o){let t;if(Oe.errorCount=(Oe.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."),Oe.errorCount>=5?Oe.cooldown.auto=!1:(Oe.cooldown.auto=Oe.captcha.isEnabled||e,Oe.cooldown.addDelay(i,2));else if(o.textContent&&(t=o.textContent.match(/\d+\s+(?:minute|second)/gi))&&!/duplicate|hour/i.test(o.textContent)){Oe.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)?Oe.cooldown.addMute(e):Oe.cooldown.addDelay(i,e)}else Oe.cooldown.auto=!1;return Oe.captcha.setup(Oe.cooldown.auto&&[Oe.nodes.status,a.body].includes(a.activeElement)),Oe.status(),void Oe.error(o)}delete Oe.errorCount;const s=He("h1",this.response) +;let[l,d,c]=Array.from(s.nextSibling.textContent.match(/thread:(\d+),no:(\d+)/));c=+c,d=+d||c;const h=d!==c;He.event("QRPostSuccessful",{boardID:n.BOARD.ID,threadID:d,postID:c}),He.event("QRPostSuccessful_",{boardID:n.BOARD.ID,threadID:d,postID:c});const u=Oe.posts.length-1;Oe.cooldown.auto=u&&h;const p=!function(){for(var e of Oe.posts.slice(1))if(e.thread===i.thread)return!0}();u?(i.rm(),Oe.captcha.setup(a.activeElement===Oe.nodes.status)):t["Persistent QR"]?(i.rm(),t["Auto Hide QR"]?Oe.hide():Oe.blur()):Oe.close(),Oe.cleanNotifications(),t["Posting Success Notifications"]&&Oe.notifications.push(new Ke("success",s.textContent,5)),Oe.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?()=>He.open(g):()=>location.href=g;d===c?Oe.waitForThread(g,e):e()}return Oe.status()},waitForThread(e,t){let n=0 +;var o=function(){return He.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=Oe.req)&&!Oe.req.isUploadFinished&&(delete Oe.req,e.abort(),Oe.captcha===Le.v2&&Oe.currentCaptcha&&Le.cache.save(Oe.currentCaptcha),delete Oe.currentCaptcha,Oe.posts[0].unlock(),Oe.cooldown.auto=!1,Oe.notifications.push(new Ke("info","QR upload aborted.",5))),Oe.status()},cooldown:{seconds:0,delays:{deletion:60},init(){if(t["Quick Reply"])return this.data=t.cooldowns,this.changes=m(),He.sync("cooldowns",this.sync)},setup(){for(var e in He.extend(Oe.cooldown.delays,n.BOARD.cooldowns()),Oe.cooldown.maxDelay=0,Oe.cooldown.delays){var t=Oe.cooldown.delays[e];["thread","thread_global"].includes(e)||(Oe.cooldown.maxDelay=Math.max(Oe.cooldown.maxDelay,t))}return Oe.cooldown.isSetup=!0,Oe.cooldown.start()},start(){const{data:e}=Oe.cooldown +;if(t.Cooldown&&Oe.cooldown.isSetup&&!Oe.cooldown.isCounting&&!(Object.keys(e[n.BOARD.ID]||{}).length+Object.keys(e.global||{}).length<=0))return Oe.cooldown.isCounting=!0,Oe.cooldown.count()},sync:e=>(Oe.cooldown.data=e||m(),Oe.cooldown.start()),add(e,o){if(!t.Cooldown)return;const a=Date.now(),i=n.BOARD.ID;return Oe.cooldown.set(i,a,{threadID:e,postID:o}),e===o&&Oe.cooldown.set("global",a,{boardID:i,threadID:e,postID:o}),Oe.cooldown.save(),Oe.cooldown.start()},addDelay(e,o){if(!t.Cooldown)return;const a=Oe.cooldown.categorize(e);return a.delay=o,Oe.cooldown.set(n.BOARD.ID,Date.now(),a),Oe.cooldown.save(),Oe.cooldown.start()},addMute(e){if(t.Cooldown)return Oe.cooldown.set(n.BOARD.ID,Date.now(),{type:"mute",delay:e}),Oe.cooldown.save(),Oe.cooldown.start()},delete(e){let t;if(!Oe.cooldown.data)return;const n=Oe.cooldown.data[e.board.ID]||(Oe.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&&Oe.cooldown.set(e.board.ID,o,null) +;return Oe.cooldown.save()},secondsDeletion(e){if(!Oe.cooldown.data||!t.Cooldown)return 0;const n=Oe.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=Oe.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)=>(Oe.cooldown.mergeChange(Oe.cooldown.data,e,t,n),(Oe.cooldown.changes[e]||(Oe.cooldown.changes[e]=m()))[t]=n),save(){const{changes:e}=Oe.cooldown;if(Object.keys(e).length)return He.get("cooldowns",m(),(function({cooldowns:e}){for(var t in Oe.cooldown.changes){for(var n in Oe.cooldown.changes[t]){var o=Oe.cooldown.changes[t][n];Oe.cooldown.mergeChange(e,t,n,o)}Oe.cooldown.data=e}return He.set("cooldowns",e,(()=>Oe.cooldown.changes=m()))}))}, +clear:()=>(Oe.cooldown.data=m(),Oe.cooldown.changes=m(),Oe.cooldown.auto=!1,Oe.cooldown.update(),He.queueTask(He.delete,"cooldowns")),update(){let e;if(!Oe.cooldown.isCounting)return;let o=!1,a=0;const i=Date.now(),{type:r,threadID:s}=Oe.cooldown.categorize(Oe.posts[0]);let l=0;if(t.Cooldown)for(var d of[n.BOARD.ID,"global"]){var c=Oe.cooldown.data[d]||(Oe.cooldown.data[d]=m());for(var h in c){e=c[h],h=+h;var u=Math.floor((i-h)/b);if(u<0)Oe.cooldown.set(d,h,null),o=!0;else if(null==e.delay){var p=e.threadID!==e.postID?Oe.cooldown.maxDelay:Oe.cooldown.delays["global"===d?"thread_global":"thread"];if(Oe.cooldown.customCooldown&&(p=Math.max(p,parseInt(t.customCooldown,10))),p<=u)Oe.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,Oe.cooldown.delays[r+g]-u),Oe.cooldown.customCooldown&&(l=Math.max(l,parseInt(t.customCooldown,10)-u))}}else e.delay<=u?(Oe.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&&Oe.cooldown.save,a?(clearTimeout(Oe.cooldown.timeout),Oe.cooldown.timeout=setTimeout(Oe.cooldown.count,b)):delete Oe.cooldown.isCounting;const f=l!==Oe.cooldown.seconds;return Oe.cooldown.seconds=l,f?Oe.status():void 0},count(){if(Oe.cooldown.update(),0===Oe.cooldown.seconds&&Oe.cooldown.auto&&!Oe.req)return Oe.submit()}},oekaki:{menu:{init(){if(!(["index","thread"].includes(n.VIEW)&&t.Menu&&t["Edit Link"]&&t["Quick Reply"]))return;const e=He.el("a",{className:"edit-link",href:"javascript:;",textContent:"Edit image"});return He.on(e,"click",this.editFile),V.menu.addEntry({el:e,order:90,open(e){Oe.oekaki.menu.post=e;const{file:t}=e;return Oe.postingIsEnabled&&!!t&&(t.isImage||t.isVideo)}})},editFile(){const{post:e}=Oe.oekaki.menu;Oe.quote.call(e.nodes.post);const{isVideo:t}=e.file,n=e.file.fullImage?.currentTime||0;return qe.file(e.file.url,(function(o){if(o){if(t){ +const t=He.el("video");return He.on(t,"loadedmetadata",(function(){return He.on(t,"seeked",(function(){const n=He.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",Oe.handleFiles([t]),Oe.oekaki.edit()}))})),t.currentTime=n})),He.on(t,"error",(()=>Oe.openError())),t.src=URL.createObjectURL(o)}return o.name=e.file.name,Oe.handleFiles([o]),Oe.oekaki.edit()}return Oe.error("Can't load file.")}))}},setup:()=>He.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(He('script[src^="//s.4cdn.org/js/tegaki"]',a.head))return e();{const t=He.el("link",{rel:"stylesheet", +href:`//s.4cdn.org/css/tegaki.${Date.now()}.css`}),n=He.el("script",{src:`//s.4cdn.org/js/tegaki.min.${Date.now()}.js`});let o=0;const i=function(){if(2==++o)return e()};return He.on(t,"load",i),He.on(n,"load",i),He.add(a.head,[t,n])}},draw:()=>He.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:()=>Oe.selected.file?Oe.oekaki.edit():Oe.oekaki.toggle(),edit:()=>Oe.oekaki.load((()=>He.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:()=>Oe.oekaki.load((()=>Oe.nodes.oekaki.hidden=!Oe.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"))Oe.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]=Array.from(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)&&(Oe.persona.always[a]=i),Oe.persona.types[a].includes(i)?void 0:Oe.persona.types[a].push(i) +;Oe.persona.pwd=i}},load(){for(var e in Oe.persona.types){var t=Oe.persona.types[e],n=He(`#list-${e}`,Oe.nodes.el);for(var o of t)o&&He.add(n,He.el("option",{textContent:o}))}},getPassword(){let e;return null!=Oe.persona.pwd?Oe.persona.pwd:(e=a.cookie.match(/4chan_pass=([^;]+)/))?decodeURIComponent(e[1]):""},get:e=>He.get("QR.persona",{},(({"QR.persona":t})=>e(t))),set:e=>He.get("QR.persona",{},(function({"QR.persona":t}){return t={name:e.name,flag:e.flag},He.set("QR.persona",t)}))},post:class{constructor(e){this.select=this.select.bind(this);const o=He.el("a",{className:"qr-preview",draggable:!0,href:"javascript:;"});for(var a of(He.extend(o,{innerHTML:''}),this.nodes={el:o,rm:o.firstChild,spoiler:He(".qr-preview-spoiler input",o),span:o.lastChild},He.on(o,"click",this.select),He.on(this.nodes.rm,"click",(e=>(e.stopPropagation(),this.rm()))), +He.on(this.nodes.spoiler,"change",(e=>(this.spoiler=e.target.checked,this===Oe.selected&&(Oe.nodes.spoiler.checked=this.spoiler),this.preventAutoPost()))),u("label",o)))He.on(a,"click",(e=>e.stopPropagation()));for(var i of(He.add(Oe.nodes.dumpList,o),["dragStart","dragEnter","dragLeave","dragOver","dragEnd","drop"]))He.on(o,i.toLowerCase(),this[i]);this.thread="thread"===n.VIEW?n.THREADID:"new";const r=Oe.posts[Oe.posts.length-1];Oe.posts.push(this),this.nodes.spoiler.checked=this.spoiler=!(!r||!t["Remember Spoiler"])&&r.spoiler,Oe.persona.get((e=>{if(this.name="name"in Oe.persona.always?Oe.persona.always.name:r?r.name:e.name,this.email="email"in Oe.persona.always?Oe.persona.always.email:"",this.sub="sub"in Oe.persona.always?Oe.persona.always.sub:"",Oe.nodes.flag&&(this.flag=r?r.flag:e.flag&&e.flag in n.BOARD.config.board_flags?e.flag:void 0),Oe.selected===this)return this.load()})),e&&this.select(),this.unlock(),Oe.captcha.moreNeeded()}rm(){this.delete() +;const e=Oe.posts.indexOf(this);return 1===Oe.posts.length?(new Oe.post(!0),He.rmClass(Oe.nodes.el,"dump")):this===Oe.selected&&(Oe.posts[e-1]||Oe.posts[e+1]).select(),Oe.posts.splice(e,1),Oe.status(),Oe.captcha.updateThread?.()}delete(){return He.rm(this.nodes.el),URL.revokeObjectURL(this.URL),this.dismissErrors()}lock(e=!0){if(this.isLocked=e,this===Oe.selected){for(var t of["thread","name","email","sub","com","fileButton","filename","spoiler","flag"]){var n;(n=Oe.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(){Oe.selected&&(Oe.selected.nodes.el.removeAttribute("id"),Oe.selected.forceSave()),Oe.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=Oe.nodes[e])&&(t.value=this[e]||t.dataset.default||"")}return("new"!==this.thread?He.addClass:He.rmClass)(Oe.nodes.el,"reply-to-thread"),this.showFileData(),Oe.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?He.addClass:He.rmClass)(Oe.nodes.el,"reply-to-thread"),Oe.status(),Oe.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&&Oe.persona.set(this)}return t?void 0:this.preventAutoPost()}forceSave(){if(this===Oe.selected)for(var e of["thread","name","email","sub","com","filename","spoiler","flag"]){var t +;(t=Oe.nodes[e])&&this.save(t,!0)}}preventAutoPost(){if(Oe.cooldown.auto&&this===Oe.posts[0]&&(Oe.cooldown.update(),Oe.cooldown.seconds<=5))return Oe.cooldown.auto=!1}setComment(e){return this.com=e||null,this===Oe.selected&&(Oe.nodes.com.value=this.com),this.updateComment()}updateComment(){if(this===Oe.selected&&Oe.characterCount(),this.nodes.span.textContent=this.com,Oe.captcha.moreNeeded(),Oe.captcha===Le.v2)return Le.cache.prerequest()}isOnlyQuotes(){return(this.com||"").trim()===(this.quotedText||"").trim()}static rmErrored(e){e.stopPropagation();for(let e=Oe.posts.length-1;e>=0;e--){var t,n=Oe.posts[e];if(t=n.errors)for(var o of t)if(i.contains(o)){n.rm();break}}}error(e,t,n){const a=He.el("div",{className:e});He.extend(a,{innerHTML:t+(n?` [More info]`:"")+'
            [delete post] [delete all]'}),(this.errors||(this.errors=[])).push(a);const[i,r]=Array.from(u("a",a)) +;return He.on(a,"click",(()=>{if(Oe.posts.includes(this))return this.select()})),He.on(i,"click",(e=>{if(e.stopPropagation(),Oe.posts.includes(this))return this.rm()})),He.on(r,"click",Oe.post.rmErrored),Oe.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(Oe.validExtension))&&(this.filename+=e[0])}else this.filename=this.file.name;return this.filesize=He.bytesToString(this.file.size),this.checkSize(),He.addClass(this.nodes.el,"has-file"),Oe.captcha.moreNeeded(),URL.revokeObjectURL(this.URL),this.saveFilename(),this===Oe.selected?this.showFileData():this.updateFilename(),this.rmMetadata(),this.nodes.el.dataset.type=this.file.type, +this.nodes.el.style.backgroundImage="",Oe.mimeTypes.includes(this.file.type)?/^(image|video)\//.test(this.file.type)&&this.readFile():this.fileError("Unsupported file type."),this.preventAutoPost()}checkSize(){let e=Oe.max_size;if(/^video\//.test(this.file.type)&&(e=Math.min(e,Oe.max_size_video)),this.file.size>e)return this.fileError(`File too large (file: ${this.filesize}, max: ${He.bytesToString(e)}).`)}readFile(){const t=/^video\//.test(this.file.type),n=He.el(t?"video":"img");if(t&&!n.canPlayType(this.file.type))return;const o=t?"loadeddata":"load";var a=()=>(He.off(n,o,a),He.off(n,"error",i),this.checkDimensions(n),this.setThumbnail(n),He.event("QRMetadata",null,this.nodes.el)),i=()=>(He.off(n,o,a),He.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"),He.event("QRMetadata",null,this.nodes.el)) +;return this.nodes.el.dataset.height="loading",He.on(n,o,a),He.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>Oe.max_height||o>Oe.max_width)&&this.fileError(`Image too large (image: ${t}x${o}px, max: ${Oe.max_height}x${Oe.max_width}px)`),ti||o>r)&&this.fileError(`Video too large (video: ${t}x${o}px, max: ${i}x${r}px)`),(tOe.max_duration_video&&this.fileError(`Video too long (video: ${a}s, max: ${Oe.max_duration_video}s)`):this.fileError("Video lacks duration metadata (try remuxing)"),G.noAudio(n.BOARD.ID)&&He.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(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"),Oe.nodes.filename.removeAttribute("title"),this.rmMetadata(), +this.nodes.el.style.backgroundImage="",He.rmClass(this.nodes.el,"has-file"),this.showFileData(),URL.revokeObjectURL(this.URL),this.dismissErrors((e=>He.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,"-"),!Oe.validExtension.test(this.filename))return this.file.newName+=`.${He.getOwn(Oe.extensionFromType,this.file.type)||"jpg"}`}updateFilename(){const e=`${this.filename} (${this.filesize})`;if(this.nodes.el.title=e,this===Oe.selected)return Oe.nodes.filename.title=e}showFileData(){return this.file?(this.updateFilename(),Oe.nodes.filename.value=this.filename,He.addClass(Oe.nodes.oekaki,"has-file"),He.addClass(Oe.nodes.fileSubmit,"has-file")):(He.rmClass(Oe.nodes.oekaki,"has-file"),He.rmClass(Oe.nodes.fileSubmit,"has-file")), +null!=this.file?.source?Oe.nodes.fileSubmit.dataset.source=this.file.source:Oe.nodes.fileSubmit.removeAttribute("data-source"),Oe.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),He.addClass(this,"drag")}dragEnd(){return He.rmClass(this,"drag")}dragEnter(){return He.addClass(this,"over")}dragLeave(){return He.rmClass(this,"over")}dragOver(e){return e.preventDefault(),e.dataTransfer.dropEffect="move"}drop(){if(He.rmClass(this,"over"),!this.draggable)return;const e=He(".drag",this.parentNode),t=e=>[...Array.from(e.parentNode.children)].indexOf(e),n=t(e),o=t(this);if(Oe.posts[n].isLocked||Oe.posts[o].isLocked)return;(nchrome.runtime.sendMessage(t,(t=>e[t]=n))}());var je={binary(e,t,n=m()){if(e=e.replace(/^((?:https?:)?\/\/(?:\w+\.)?(?:4chan|4channel|4cdn)\.org)\/adv\//,"$1//adv/"),"crx"===x)$e({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 He.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(;ot(null),onabort:()=>t(null)};try{return(GM?.xmlHttpRequest||GM_xmlhttpRequest)(a)}catch(e){return o()}}},file:(e,t)=>je.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=He.getOwn(Oe.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 He.ajax(e,t);const s=new je.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;He.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 He.ajax(e,t)}n&&"function"==typeof n.abort&&(s.abort=function(){try{return n.abort()}catch(e){}})}else $e({type:"ajax",url:e,responseType:i,headers:r,timeout:a},(function(e){return e.status&&He.extend(s,e),s.onloadend()}));return s},cache:(e,t)=>He.cache(e,t,{ajax:je.ajax}),permission:(e,t,n)=>"crx"===x?$e({type:"permission",origins:n},(function(n){return n?e():t()})):e()},qe=je;const Ue=(e,t=document.body)=>t.querySelector(e);Ue.id=e=>a.getElementById(e),Ue.ready=function(e){if("loading"===a.readyState){var t=function(){return Ue.off(a,"DOMContentLoaded",t),e()};return Ue.on(a,"DOMContentLoaded",t)}Ue.queueTask(e)},Ue.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},Ue.extend=function(e,t){for(var n in t){var o=t[n];e[n]=o}},Ue.hasOwn=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),Ue.getOwn=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)?e[t]:void 0},Ue.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 Ue.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)} +Ue.extend(g,{onloadend:i,timeout:s,responseType:l,withCredentials:d}),Ue.extend(g.upload,{onprogress:h}),Ue.on(g,"error",(function(){if(!g.status)return r.warn(`4chan X failed to load: ${o}`)})),"crx"===x&&Ue.on(g,"load",(()=>{t["Work around CORB Bug"]||4!==g.readyState||200!==g.status||""!==g.statusText||null!==g.response||Ue.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,Ue.queueTask(Ue.event,"error",null,g),Ue.queueTask(Ue.event,"loadend",null,g)}return g};{let e=0;const t=m();return Ue.ajaxPageInit=function(){return Ue.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)})),Ue.on(a,"4chanXAjaxProgress",(function(e){let n;if(n=t[e.detail.id])return n.upload.onprogress.call(n.upload,e.detail)})), +Ue.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()}}))},Ue.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 qe.Request,Ue.extend(a,{responseType:s,onloadend:i}),a.upload={onprogress:c},a.abort=()=>Ue.event("4chanXAjaxAbort",{id:p}),h&&(h=Array.from(h.entries())),Ue.event("4chanXAjax",{url:n,timeout:r,responseType:s,withCredentials:l,type:d,onprogress:!!c,form:h,headers:u,id:p}),a}}}(),Ue.lastModified=m(),Ue.whenModified=function(e,t,n,o={}){let a;const{timeout:i,ajax:r}=o,s=[];"blink"===Ue.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=Ue.lastModified[t]?.[l])&&(d["If-Modified-Since"]=a);return(r||Ue.ajax)(e,{onloadend(){return(Ue.lastModified[t]||(Ue.lastModified[t]=m()))[l]=this.getResponseHeader("Last-Modified"),n.call(this)},timeout:i,headers:d})},function(){const e=m();Ue.cache=function(t,n,o={}){let a;const{ajax:i}=o;if(a=e[t])return a.callbacks?a.callbacks.push(n):Ue.queueTask((()=>n.call(a,{isCached:!0}))),a;return a=(i||Ue.ajax)(t,{onloadend:function(){for(n of(this.status||delete e[t],this.callbacks))(e=>{Ue.queueTask((()=>e.call(this,{isCached:!1})))})(n);return delete this.callbacks}}),a.callbacks=[n],e[t]=a},Ue.cleanCache=function(t){for(var n in e)t(n)&&delete e[n]}}(),Ue.cb={checked(){if(Ue.hasOwn(t,this.name))return Ue.set(this.name,this.checked),t[this.name]=this.checked},value(){if(Ue.hasOwn(t,this.name))return Ue.set(this.name,this.value.trim()),t[this.name]=this.value}},Ue.asap=function(e,t){return e()?t():setTimeout(Ue.asap,25,e,t)},Ue.onExists=function(e,t,n){let o +;if(o=Ue(t,e))return n(o);var a=new MutationObserver((function(){if(o=Ue(t,e))return a.disconnect(),n(o)}));return a.observe(e,{childList:!0,subtree:!0})},Ue.addStyle=function(e,t,n="head"){const o=Ue.el("style",{textContent:e});return null!=t&&(o.id=t),Ue.onExists(i,n,(()=>Ue.add(a.head,o))),o},Ue.addCSP=function(e){const t=Ue.el("meta",{httpEquiv:"Content-Security-Policy",content:e});if(a.head)return Ue.add(a.head,t),Ue.rm(t);{const e=Ue.add(i||a,Ue.el("head"));return Ue.add(e,t),Ue.rm(e)}},Ue.x=function(e,t){return t||(t=a.body),a.evaluate(e,t,null,8,null).singleNodeValue},Ue.X=function(e,t){return t||(t=a.body),a.evaluate(e,t,null,7,null)},Ue.addClass=function(e,...t){for(var n of t)e.classList.add(n)},Ue.rmClass=function(e,...t){for(var n of t)e.classList.remove(n)},Ue.toggleClass=(e,t)=>e.classList.toggle(t),Ue.hasClass=(e,t)=>e.classList.contains(t),Ue.rm=e=>e?.remove(),Ue.rmAll=e=>e.textContent=null,Ue.tn=e=>a.createTextNode(e),Ue.frag=()=>a.createDocumentFragment(), +Ue.nodes=function(e){if(!(e instanceof Array))return e;const t=Ue.frag();for(var n of e)t.appendChild(n);return t},Ue.add=(e,t)=>e.appendChild(Ue.nodes(t)),Ue.prepend=(e,t)=>e.insertBefore(Ue.nodes(t),e.firstChild),Ue.after=(e,t)=>e.parentNode.insertBefore(Ue.nodes(t),e.nextSibling),Ue.before=(e,t)=>e.parentNode.insertBefore(Ue.nodes(t),e),Ue.replace=(e,t)=>e.parentNode.replaceChild(Ue.nodes(t),e),Ue.el=function(e,t,n){const o=a.createElement(e);return t&&Ue.extend(o,t),n&&Ue.extend(o,n),o},Ue.on=function(e,t,n){for(var o of t.split(" "))e.addEventListener(o,n,!1)},Ue.off=function(e,t,n){for(var o of t.split(" "))e.removeEventListener(o,n,!1)},Ue.one=function(e,t,n){var o=function(a){return Ue.off(e,t,o),n.call(this,a)};return Ue.on(e,t,o)},Ue.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 Ue.event=(t,n,o=a)=>o.dispatchEvent(new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:e(n)}))}}(),Ue.modifiedClick=e=>e.shiftKey||e.altKey||e.ctrlKey||e.metaKey||0!==e.button,Ue.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"),Ue.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=1024;)e/=1024,t++;return`${e=t>1?Math.round(100*e)/100:Math.round(e)} ${["B","KB","MB","GB"][t]}`},Ue.minmax=(e,t,n)=>en?n:e,Ue.hasAudio=e=>e.mozHasAudio||!!e.webkitAudioDecodedByteCount,Ue.luma=e=>.299*e[0]+.587*e[1]+.114*e[2],Ue.unescape=function(e){return null==e?e:e.replace(/<[^>]*>/g,"").replace(/&(amp|#039|quot|lt|gt|#44);/g,(e=>({"&":"&","'":"'",""":'"',"<":"<",">":">",",":","}[e]))) +},Ue.isImage=e=>/\.(jpe?g|jfif|png|gif|bmp|webp|avif|jxl)$/i.test(e),Ue.isVideo=e=>/\.(webm|mp4|ogv)$/i.test(e),Ue.engine=/Edge\//.test(navigator.userAgent)?"edge":/Chrome\//.test(navigator.userAgent)?"blink":/WebKit\//.test(navigator.userAgent)?"webkit":/Gecko\/|Goanna/.test(navigator.userAgent)?"gecko":void 0,Ue.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}}(),Ue.item=function(e,t){const n=m();return n[e]=t,n},Ue.oneItemSugar=e=>function(t,n,o){return"string"==typeof t?e(Ue.item(t,n),o):e(t,n)},Ue.syncing=m(),Ue.securityCheck=function(e){if("https:"!==location.protocol)return delete e["Redirect to HTTPS"]},"crx"===x?(Ue.oldValue={local:m(),sync:m()},chrome.storage.onChanged.addListener((function(e,t){for(var n in e){var o=Ue.oldValue.local[n]??Ue.oldValue.sync[n];Ue.oldValue[t][n]=m.clone(e[n].newValue) +;var a=Ue.oldValue.local[n]??Ue.oldValue.sync[n],i=Ue.syncing[n];i&&JSON.stringify(a)!==JSON.stringify(o)&&i(a,n)}})),Ue.sync=(e,t)=>Ue.syncing[e]=t,Ue.forceSync=function(){},Ue.crxWorking=function(){try{if(chrome.runtime.getManifest())return!0}catch(e){}if(!Ue.crxWarningShown){const e=Ue.el("div",{innerHTML:'4chan X seems to have been updated. You will need to reload the page.'});Ue.on(Ue("a",e),"click",(()=>location.reload())),new Ke("warning",e),Ue.crxWarningShown=!0}return!1},Ue.get=Ue.oneItemSugar((function(e,t){if(!Ue.crxWorking())return;const n={},o=function(o){let a=Object.keys(e);return"gecko"===Ue.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];Ue.hasOwn(e,s)&&(t[s]=l)}i=t}for(s in e)Ue.oldValue[o][s]=i[s];if(n[o]=i,n.local&&n.sync)return Ue.extend(e,n.sync),Ue.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;Ue.delete=function(t){if(Ue.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(Ue.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")));Ue.set=Ue.oneItemSugar((function(t,n){ +if(Ue.crxWorking())return Ue.securityCheck(t),Ue.extend(e.local,t),o("local",n)})),Ue.clear=function(t){if(!Ue.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||(Ue.perProtocolSettings=!0),"undefined"!=typeof GM_deleteValue&&null!==GM_deleteValue?(Ue.getValue=GM_getValue,Ue.listValues=()=>GM_listValues()):Ue.hasStorage?(Ue.getValue=e=>localStorage.getItem(e),Ue.listValues=()=>(()=>{const e=[];for(var t in localStorage)t.slice(0,n.NAMESPACE.length)===n.NAMESPACE&&e.push(t);return e})()):(Ue.getValue=function(){},Ue.listValues=()=>[]), +"undefined"!=typeof GM_addValueChangeListener&&null!==GM_addValueChangeListener?(Ue.setValue=GM_setValue,Ue.deleteValue=GM_deleteValue):"undefined"!=typeof GM_deleteValue&&null!==GM_deleteValue?(Ue.oldValue=m(),Ue.setValue=function(e,t){if(GM_setValue(e,t),e in Ue.syncing&&(Ue.oldValue[e]=t,Ue.hasStorage))return localStorage.setItem(e,t)},Ue.deleteValue=function(e){if(GM_deleteValue(e),e in Ue.syncing&&(delete Ue.oldValue[e],Ue.hasStorage))return localStorage.removeItem(e)},Ue.hasStorage||(Ue.cantSync=!0)):Ue.hasStorage?(Ue.oldValue=m(),Ue.setValue=function(e,t){return e in Ue.syncing&&(Ue.oldValue[e]=t),localStorage.setItem(e,t)},Ue.deleteValue=function(e){return e in Ue.syncing&&delete Ue.oldValue[e],localStorage.removeItem(e)}):(Ue.setValue=function(){},Ue.deleteValue=function(){},Ue.cantSync=Ue.cantSet=!0),"undefined"!=typeof GM_addValueChangeListener&&null!==GM_addValueChangeListener?(Ue.sync=(e,t)=>Ue.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)})),Ue.forceSync=function(){}):"undefined"!=typeof GM_deleteValue&&null!==GM_deleteValue||Ue.hasStorage?(Ue.sync=function(e,t){return e=n.NAMESPACE+e,Ue.syncing[e]=t,Ue.oldValue[e]=Ue.getValue(e)},function(){const e=function({key:e,newValue:t}){let o;if(o=Ue.syncing[e]){if(null!=t){if(t===Ue.oldValue[e])return;return Ue.oldValue[e]=t,o(m.json(t),e.slice(n.NAMESPACE.length))}if(null!=Ue.oldValue[e])return delete Ue.oldValue[e],o(void 0,e.slice(n.NAMESPACE.length))}};Ue.on(window,"storage",e),Ue.forceSync=function(t){return t=n.NAMESPACE+t,e({key:t,newValue:Ue.getValue(t)})}}()):(Ue.sync=function(){},Ue.forceSync=function(){}),Ue.delete=function(e){for(var t of(e instanceof Array||(e=[e]),e))Ue.deleteValue(n.NAMESPACE+t)},Ue.get=Ue.oneItemSugar(((e,t)=>Ue.queueTask(Ue.getSync,e,t))),Ue.getSync=function(e,t){for(var o in e){var a;if(a=Ue.getValue(n.NAMESPACE+o))try{e[o]=m.json(a)}catch(e){if(!/^(?:undefined)*$/.test(a))throw e}}return t(e)}, +Ue.set=Ue.oneItemSugar((function(e,t){return Ue.securityCheck(e),Ue.queueTask((function(){for(var o in e){var a=e[o];Ue.setValue(n.NAMESPACE+o,JSON.stringify(a))}return t?.()}))})),Ue.clear=function(e){Ue.delete(Object.keys(t)),Ue.delete(["previousversion","QR Size","QR.persona"]);try{Ue.delete(Ue.listValues().map((e=>e.replace(n.NAMESPACE,""))))}catch(e){}return e?.()}):(Ue.syncChannel=new BroadcastChannel(n.NAMESPACE+"sync"),Ue.on(Ue.syncChannel,"message",(e=>(()=>{const t=[];for(var n in e.data){var o,a=e.data[n];(o=Ue.syncing[n])&&t.push(o(m.json(JSON.stringify(a)),n))}return t})())),Ue.sync=(e,t)=>Ue.syncing[e]=t,Ue.forceSync=function(){},Ue.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 Ue.syncChannel.postMessage(n),t?.()}))},Ue.get=Ue.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{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 Ue.syncChannel.postMessage(e),t?.()}))})),Ue.clear=e=>GM.listValues().then((t=>Ue.delete(t.map((e=>e.replace(n.NAMESPACE,""))),e))).catch((()=>Ue.delete(Object.keys(t).concat(["previousversion","QR Size","QR.persona"]),e))));var He=Ue,Ve={url(e,t,...o){let a,i;return(i=n.sites[t.siteID])&&(a=He.getOwn(i.urls,e))?a(t,...Array.from(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=>Ve.threadFromRoot(He.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=>Ve.postFromRoot(He.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]=Array.from(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(...Array.from(e.nodes[t]||[])),e.clones))o.push(...Array.from(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}=Ve.postDataFromLink(t);return n===e.board.ID&&o===e.ID}))}},Qe=Ve,ze={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"]||He.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 Ke("warning",[He.tn(`Invalid ${e} filter:`),He.el("br"),He.tn(o),He.el("br"),He.tn(t.message)],60);continue}var d=a.match(/(?:^|;)\s*op:(no|only)/)?.[1]||"",h=He.getOwn({no:1,only:2},d)||0,u=a.match(/(?:^|;)\s*file:(no|only)/)?.[1]||"";h|=He.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?ze.catalog():l.Post.push({name:"Filter",cb:this.node})}}},parseBoards(e){let t;if(!e)return!1;if(t=ze.parseBoardsMemo[e])return t;t=m();let o="" +;for(var a of e.split(","))for(var i in a.includes(":")&&([o,a]=Array.from(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 ze.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;X.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 ze.filters.keys())for(const h of ze.values(c,e)){const e=ze.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}=ze.test(this,!this.isFetchedQuote&&(this.isReply||"index"===n.VIEW));return e?this.isReply?z.hide(this,t):le.hide(this.thread,t):o&&(this.highlights=o,He.addClass(this.nodes.root,...Array.from(o))),i&&Z.posts&&this.ID>Z.lastReadPost&&!X.isYou(this)?Z.openNotification(this," triggered a notification filter"):void 0},catalog(){let e;if(e=n.SITE.urls.catalogJSON?.(n.BOARD))return ze.catalogData=m(),He.ajax(e,{onloadend:ze.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)ze.catalogData[t.no]=t;n.BOARD.threads.forEach((function(e){if(e.catalogViewNative)return ze.catalogNode.call(e.catalogViewNative)}))}else new Ke("warning","Failed to fetch catalog JSON data. "+(this.status?`Error ${this.statusText} (${this.status})`:"Connection Error"),1)},catalogNode(){if(this.boardID!==n.BOARD.ID||!ze.catalogData[this.ID])return +;if(X.db?.get({siteID:n.SITE.ID,boardID:this.boardID,threadID:this.ID,postID:this.ID}))return;const{hide:e,hl:t,top:o}=ze.test(n.SITE.Build.parseJSON(ze.catalogData[this.ID],this));return e?this.nodes.root.hidden=!0:(t&&(this.highlights=t,He.addClass(this.nodes.root,...Array.from(t))),o?(He.prepend(this.nodes.root.parentNode,this.nodes.root),n.SITE.catalogPin?.(this.nodes.root)):void 0)},isHidden:e=>!!ze.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)=>He.hasOwn(ze.valueF,e)?ze.valueF[e](t).filter((e=>null!=e)):[e.split("+").map((function(e){let n;return(n=He.getOwn(ze.valueF,e))?n(t).map((e=>e||"")).join("\n"):""})).join("\n")],addFilter(e,n,o){if(He.hasOwn(c.filter,e))return He.get(e,t[e],(function(t){let a=t[e];return a=a?`${a}\n${n}`:n,He.set(e,a,o)}))},removeFilters:(e,n,o)=>He.get(e,t[e],(function(t){let a=t[e];const i=(Array.isArray(n)?n:[...n.values()].flat()).map(ze.escape).join("|");return a=a.replace(RegExp(`(?:$\n|^)(?:${i})$`,"mg"),""),He.set(e,a,o)})),showFilters(e){Re.open("Filter");const t=He(".section-container"),n=He("select[name=filter]",t);return n.value=e,Re.selectFilter.call(n),He.onExists(t,"textarea",(function(e){const t=e.textLength;return e.setSelectionRange(t,t),e.focus()}))},quickFilterMD5(){const e=Qe.postFromNode(this),o=e.files.filter((e=>e.MD5));if(!o.length)return +;const a=o.map((e=>`/${e.MD5}/`)).join("\n");ze.addFilter("MD5",a);const i=e.origin||e;if(i.isReply?z.hide(i):"index"===n.VIEW&&le.hide(i.thread),!t["MD5 Quick Filter Notifications"])return void(e.nodes.post.getBoundingClientRect().height&&new Ke("info","MD5 filtered.",2));let{notice:r}=ze.quickFilterMD5;if(r)return r.filters.push(a),r.posts.push(i),He("span",r.el).textContent=`${r.filters.length} MD5s filtered.`;{const e=He.el("div",{innerHTML:'MD5 filtered. [show] [undo]'});r=ze.quickFilterMD5.notice=new Ke("info",e,void 0,(()=>delete ze.quickFilterMD5.notice)),r.filters=[a],r.posts=[i];const t=u("a",e);return He.on(t[0],"click",ze.quickFilterCB.show.bind(r)),He.on(t[1],"click",ze.quickFilterCB.undo.bind(r))}},quickFilterCB:{show(){return ze.showFilters("MD5"),this.close()},undo(){for(var e of(ze.removeFilters("MD5",this.filters),this.posts))e.isReply?z.show(e):"index"===n.VIEW&&le.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:He.el("div",{textContent:"Filter"}),order:50,open:e=>(ze.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(ze.menu.createSubEntry(o[0],o[1]));return V.menu.addEntry(e)},createSubEntry(e,t){const n=He.el("a",{href:"javascript:;",textContent:e});return n.dataset.type=t,He.on(n,"click",ze.menu.makeFilter),{el:n,open:e=>ze.values(t,e).length}},makeFilter(){const{type:e}=this.dataset,t=ze.values(e,ze.menu.post).map((function(t){ +const n=["uniqueID","MD5"].includes(e)?t:ze.escape(t);return["uniqueID","MD5"].includes(e)?`/${n}/`:`/^${n}$/`})).join("\n");return ze.addFilter(e,t,(()=>ze.showFilters(e)))}}},We={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){He.extend(t.siteProperties,We.defaultProperties);let o=We.resolve();return o&&He.hasOwn(Ie,t.siteProperties[o].software)&&(this.set(o),e()),He.onExists(i,"body",(()=>{for(var a in Ie){var i;if(i=Ie[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&&He.set("siteProperties",t.siteProperties),void(n.SITE||(this.set(o),e()))}}}))},resolve(e=location){let{hostname:n}=e;for(;n&&!He.hasOwn(t.siteProperties,n);)n=n.replace(/^[^.]*\.?/,"") +;if(n){let e;(e=t.siteProperties[n].canonical)&&(n=e)}return n},parseURL(e){const t=We.resolve(e);return Lt.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&&He.hasOwn(Ie,r)&&(n.sites[o]=a=Object.create(Ie[r]),He.extend(a,{ID:o,siteID:o,properties:i,software:r}))}}return n.SITE=n.sites[e]}},Ge={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"}})();He.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=Ge.index();break;case`/${n.BOARD}/catalog`:a.href=Ge.catalog()}if("catalog"===n.VIEW&&(i=Ge.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",He.after(a.parentNode,[He.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;Ge.el=e=F.checkbox("Header catalog links","Catalog Links"),e.id="toggleCatalog";const t=He("input",e);return He.on(t,"change",this.toggle),He.sync("Header catalog links",Ge.set),Je.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 He.event("CloseMenu"),He.set("Header catalog links",this.checked),Ge.set(this.checked)},set:e=>(t["Header catalog links"]=e,Ge.setLinks(Je.boardList),Ge.setLinks(Je.bottomBoardList), +Ge.el.title=`Turn catalog links ${e?"off":"on"}.`,He("input",Ge.el).checked=e),setLinks(e){if(!(Ge.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}=We.parseURL(o)),!a||!i||!["index","catalog"].includes(r)||!o.dataset.indexOptions&&o.href.replace(n,"")!==(Qe.url(r,{siteID:a,boardID:i})||"").replace(n,""))continue;He.extend(o.dataset,{siteID:a,boardID:i})}var s={siteID:a,boardID:i},l=t["Header catalog links"]?Ge.catalog(s):Qe.url("index",s);l&&(o.href=l,o.dataset.indexOptions&&l.split("#")[0]===Qe.url("index",s)&&(o.href+=(o.hash?"/":"#")+o.dataset.indexOptions))}},externalParse(){for(var e of(Ge.externalList=m(),t.externalCatalogURLs.split("\n")))if("#"!==e[0]){var n=e.split(";")[0],o=ze.parseBoards(e.match(/;boards:([^;]+)/)?.[1]||"*"),a=ze.parseBoards(e.match(/;exclude:([^;]+)/)?.[1])||m() +;for(var i in o)a[i]||a[i.split("/")[0]+"/*"]||(Ge.externalList[i]=n)}},external({siteID:e,boardID:t}){Ge.externalList||Ge.externalParse();const n=Ge.externalList[`${e}/${t}`]||Ge.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:Qe.url("index",e)+t,catalog(o=n.BOARD){let a,i;return t["External Catalog"]&&(a=Ge.external(o))?a:se.enabledOn(o)&&t[`Use ${e.name} Catalog`]?Ge.jsonIndex(o,"#catalog"):(i=Qe.url("catalog",o))?i:Ge.external(o)},index:(e=n.BOARD)=>se.enabledOn(e)?Ge.jsonIndex(e,"#index"):Qe.url("index",e)},Ye={init(){He.onExists(i,"body",(()=>{if(Lt.isThisPageLegit())return He.add(this.bar,[this.noticesRoot,this.toggle]),He.prepend(a.body,this.bar),He.add(a.body,Ye.hover),this.setBarPosition(t["Bottom Header"])})),this.menu=new F.Menu("header");const e=He.el("span",{className:"menu-button"});He.extend(e,{innerHTML:""}) +;const o=F.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=He.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,He.on(e,"click",this.menuToggle),He.on(this.headerToggler,"change",this.toggleBarVisibility),He.on(this.barFixedToggler,"change",this.toggleBarFixed), +He.on(this.barPositionToggler,"change",this.toggleBarPosition),He.on(this.scrollHeaderToggler,"change",this.toggleHideBarOnScroll),He.on(this.linkJustifyToggler,"change",this.toggleLinkJustify),He.on(this.footerToggler,"change",this.toggleFooterVisibility),He.on(this.shortcutToggler,"change",this.toggleShortcutIcons),He.on(this.customNavToggler,"change",this.toggleCustomNav),He.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"]),He.sync("Fixed Header",this.setBarFixed),He.sync("Header auto-hide on scroll",this.setHideBarOnScroll),He.sync("Bottom Header",this.setBarPosition),He.sync("Shortcut Icons",this.setShortcutIcons),He.sync("Header auto-hide",this.setBarVisibility),He.sync("Centered links",this.setLinkJustify), +He.sync("Bottom Board List",this.setFooterVisibility),this.addShortcut("menu",e,900),this.menu.addEntry({el:He.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}]}),He.on(window,"load popstate",Ye.hashScroll),He.on(a,"CreateNotification",this.createNotification),this.setBoardList(),He.onExists(i,`${n.SITE.selectors.boardList} + *`,Ye.generateFullBoardList),Lt.ready((function(){let e;if("yotsuba"===n.SITE.software&&!(e=He.id("boardNavDesktopFoot"))){let t;if(!(t=He.id("absbot")))return;e=He.id("boardNavDesktop").cloneNode(!0),e.id="boardNavDesktopFoot",He("#navtopright",e).id="navbotright",He("#settingsWindowLink",e).id="settingsWindowLinkBot",He.before(t,e),He.global((()=>window.cloneTopNav=function(){}))}if(Ye.bottomBoardList=He(n.SITE.selectors.boardListBottom)){for(var t of u("a",Ye.bottomBoardList))t.hostname===location.hostname&&t.pathname.split("/")[1]===n.BOARD.ID&&(t.className="current") +;return Ge.setLinks(Ye.bottomBoardList)}})),"yotsuba"===n.SITE.software&&("catalog"===n.VIEW||!t["Disable Native Extension"])){const e=He.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"),He.on(e,"click",(()=>He.id("settingsWindowLink").click())),this.addShortcut("native",e,810)}return this.enableDesktopNotifications()},bar:He.el("div",{id:"header-bar"}),noticesRoot:He.el("div",{id:"notifications"}),shortcuts:He.el("span",{id:"shortcuts"}),hover:He.el("div",{id:"hoverUI"}),toggle:He.el("div",{id:"scroll-marker"}),setBoardList(){let e;Ye.boardList=e=He.el("span",{id:"board-list"}),He.extend(e,{innerHTML:''}) +;const n=He(".hide-board-list-button",e);return He.on(n,"click",Ye.toggleBoardList),He.prepend(Ye.bar,[Ye.boardList,Ye.shortcuts]),Ye.setCustomNav(t["Custom Board Navigation"]),Ye.generateBoardList(t.boardnav),He.sync("Custom Board Navigation",Ye.setCustomNav),He.sync("boardnav",Ye.generateBoardList)},generateFullBoardList(){let e;e=n.SITE.transformBoardList?n.SITE.transformBoardList():[...Array.from(He(n.SITE.selectors.boardList).cloneNode(!0).childNodes)];const t=He(".boardList",Ye.boardList);for(var o of(He.add(t,e),u("a",t)))o.hostname===location.hostname&&o.pathname.split("/")[1]===n.BOARD.ID&&(o.className="current");return Ge.setLinks(t)},generateBoardList(e){const t=He("#custom-board-list",Ye.boardList);if(He.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=>Ye.mapCustomNavigation(e)));return He.add(t,n),Ge.setLinks(t)}, +mapCustomNavigation(e){let o,a,i,r;if(/^[^\w@]/.test(e))return He.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=He.el("a",{className:"show-board-list-button",textContent:s||"+",href:"javascript:;"}),He.on(o,"click",Ye.toggleBoardList),o;if(/^external/.test(e))return o=He.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=He.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?He.el("a",{href:"https://twitter.com/4chan",title:"4chan Twitter",textContent:"@"}):(o=He.el("a",{href:`//${G.domain(d)}/${d}/`,textContent:d,title:G.title(d)}),["catalog","archive"].includes(n.VIEW)&&(e=Qe.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=Ge[i[1]]({siteID:"4chan.org",boardID:d});if(!e)return o.firstChild;o.dataset.only=i[1],o.href=e,"catalog"===i[1]&&He.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=_e.to("board",{boardID:d})))return o.firstChild;o.href=a}if(/-expired/.test(e)){if(!G.isArchived(d))return o.firstChild;o.href=`//${G.domain(d)}/${d}/archive`}return/-nt/.test(e)&&(o.target="_blank",o.rel="noopener"),"@"===d&&He.addClass(o,"navSmall"),o},toggleBoardList(){const{bar:e}=Ye,t=He("#custom-board-list",e),n=He("#full-board-list",e),o=!n.hidden;return t.hidden=!o,n.hidden=o},setLinkJustify:e=>(Ye.linkJustifyToggler.checked=e,e?He.addClass(i,"centered-links"):He.rmClass(i,"centered-links")),toggleLinkJustify(){He.event("CloseMenu");const e="INPUT"===this.nodeName?this.checked:void 0;return Ye.setLinkJustify(e),He.set("Centered links",e)},setBarFixed:e=>(Ye.barFixedToggler.checked=e,e?(He.addClass(i,"fixed"),He.addClass(Ye.bar,"dialog")):(He.rmClass(i,"fixed"),He.rmClass(Ye.bar,"dialog"))),toggleBarFixed(){return He.event("CloseMenu"),Ye.setBarFixed(this.checked),t["Fixed Header"]=this.checked,He.set("Fixed Header",this.checked)}, +setShortcutIcons:e=>(Ye.shortcutToggler.checked=e,e?He.addClass(i,"shortcut-icons"):He.rmClass(i,"shortcut-icons")),toggleShortcutIcons(){return He.event("CloseMenu"),Ye.setShortcutIcons(this.checked),t["Shortcut Icons"]=this.checked,He.set("Shortcut Icons",this.checked)},setBarVisibility:e=>(Ye.headerToggler.checked=e,He.event("CloseMenu"),(e?He.addClass:He.rmClass)(Ye.bar,"autohide"),(e?He.addClass:He.rmClass)(i,"autohide")),toggleBarVisibility(){const e="INPUT"===this.nodeName?this.checked:!He.hasClass(Ye.bar,"autohide");t["Header auto-hide"]=e,He.set("Header auto-hide",e),Ye.setBarVisibility(e);return new Ke("info","The header bar will "+(e?"automatically hide itself.":"remain visible."),2)},setHideBarOnScroll(e){if(Ye.scrollHeaderToggler.checked=e,!e)return He.off(window,"scroll",Ye.hideBarOnScroll),He.rmClass(Ye.bar,"scroll"),Ye.bar.classList.toggle("autohide",t["Header auto-hide"]);He.on(window,"scroll",Ye.hideBarOnScroll)},toggleHideBarOnScroll(){const e=this.checked +;return He.cb.checked.call(this),Ye.setHideBarOnScroll(e)},hideBarOnScroll(){const e=window.pageYOffset;return e>(Ye.previousOffset||0)?He.addClass(Ye.bar,"autohide","scroll"):He.rmClass(Ye.bar,"autohide","scroll"),Ye.previousOffset=e},setBarPosition(e){Ye.barPositionToggler&&(Ye.barPositionToggler.checked=e),He.event("CloseMenu");const t=e?["bottom-header","top-header","after"]:["top-header","bottom-header","add"];return He.addClass(i,t[0]),He.rmClass(i,t[1]),He[t[2]](Ye.bar,Ye.noticesRoot)},toggleBarPosition(){return He.cb.checked.call(this),Ye.setBarPosition(this.checked)},setFooterVisibility:e=>(Ye.footerToggler.checked=e,i.classList.toggle("hide-bottom-board-list",e)),toggleFooterVisibility(){He.event("CloseMenu");const e="INPUT"===this.nodeName?this.checked:He.hasClass(i,"hide-bottom-board-list");Ye.setFooterVisibility(e),He.set("Bottom Board List",e);return new Ke("info",e?"The bottom navigation will now be hidden.":"The bottom navigation will remain visible.",2)}, +setCustomNav(e){let t;Ye.customNavToggler.checked=e;const n=He("#custom-board-list",Ye.bar),o=He("#full-board-list",Ye.bar),a=He(".hide-board-list-container",o);return[n.hidden,o.hidden,a.hidden]=Array.from(t=e?[!1,!0,!1]:[!0,!1,!0]),t},toggleCustomNav(){return He.cb.checked.call(this),Ye.setCustomNav(this.checked)},editCustomNav(){Re.open("Advanced");const e=He.id("fourchanx-settings");return He("[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(Ee.showIfHidden(t),e=He.id(t))return He.queueTask((()=>Ye.scrollTo(e)))}},scrollTo(e,n,o){let a,i;if(e.offsetParent)if(n){if(i=Ye.getBottomOf(e),t["Fixed Header"]&&t["Header auto-hide on scroll"]&&t["Bottom header"]&&(({height:a}=Ye.bar.getBoundingClientRect()),i<=0?Ye.isHidden()||(i+=a):Ye.isHidden()&&(i-=a)),!o||i<0)return window.scrollBy(0,-i)}else if(i=Ye.getTopOf(e), +t["Fixed Header"]&&t["Header auto-hide on scroll"]&&!t["Bottom header"]&&(({height:a}=Ye.bar.getBoundingClientRect()),i>=0?Ye.isHidden()||(i+=a):Ye.isHidden()&&(i-=a)),!o||i<0)return window.scrollBy(0,i)},scrollToIfNeeded:(e,t)=>Ye.scrollTo(e,t,!0),getTopOf(e){let{top:n}=e.getBoundingClientRect();if(t["Fixed Header"]&&!t["Bottom Header"]){const e=Ye.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=Ye.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 Ye.getTopOf(e)+t>=0&&Ye.getBottomOf(e)+t>=0},isHidden(){const{top:e}=Ye.bar.getBoundingClientRect();return t["Bottom header"]?e===i.clientHeight:e<0},addShortcut(e,t,n){const o=He.el("span",{id:`shortcut-${e}`,className:"shortcut brackets-wrap"});for(var a of(He.add(o,t), +o.dataset.index=n,u("[data-index]",Ye.shortcuts)))if(+a.dataset.index>+n)return void He.before(a,o);return He.add(Ye.shortcuts,o)},rmShortcut:e=>He.rm(e.parentElement),menuToggle(e){return Ye.menu.toggle(e,this,n)},createNotification(e){const{type:t,content:n,lifetime:o}=e.detail;return new Ke(t,n,o)},areNotificationsEnabled:!1,enableDesktopNotifications(){let n;if(!window.Notification||!t["Desktop Notifications"])return;switch(Notification.permission){case"granted":return void(Ye.areNotificationsEnabled=!0);case"denied":return}const o=He.el("span",{innerHTML:`${e.name} needs your permission to show desktop notifications. [FAQ]
            or `}),[a,i]=Array.from(u("button",o));return He.on(a,"click",(()=>Notification.requestPermission((function(e){if(Ye.areNotificationsEnabled="granted"===e,"default"!==e)return n.close()})))), +He.on(i,"click",(function(){return He.set("Desktop Notifications",!1),n.close()})),n=new Ke("info",o)}},Je=Ye;class Ke{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=He.el("div",{innerHTML:'
            '}),this.el.style.opacity=0,this.setType(e),He.on(this.el.firstElementChild,"click",this.close),"string"==typeof t&&(t=He.tn(t)),He.add(this.el.lastElementChild,t),He.ready(this.add)}setType(e){return this.el.className=`notification ${e}`}add(){if(!this.closed){if(!a.hidden)return He.off(a,"visibilitychange",this.add),He.add(Je.noticesRoot,this.el),this.el.clientHeight,this.el.style.opacity=1,this.timeout?setTimeout(this.close,this.timeout*b):void 0;He.on(a,"visibilitychange",this.add)}}close(){return this.closed=!0,He.off(a,"visibilitychange",this.add),He.rm(this.el),this.onclose?.()}}var Xe={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)])&&He.hasOwn(i,u)&&(n="file"===u?p.files:p.boards,n.includes(e)&&(i[u][e]=p))}}return Xe.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 Ke("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?Xe.parse(a,e):void 0};if(o.length)for(let e=0;e`${Xe.protocol(e)}${e.domain}/${t}/`,search(e,{boardID:t,type:n,value:o}){"capcode"===(n="name"===n?"username":"MD5"===n?"image":n)?o=He.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`${Xe.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){Xe.data||Xe.init();const o=Xe.to(e,t) +;return o&&(Xe.securityCheck(o)||confirm(`Redirect to ${o}?\n\nYour connection will not be encrypted.`))?location.replace(o):n?location.replace(n):void 0}},_e=Xe;class Ze{toString(){return this.ID}constructor(e){this.nodes={root:e,thumb:He(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 Y(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 et={init(){if(t.Anonymize)return He.addClass(i,"anonymize")}};var tt={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=>He.on(e.thumb,"mouseover",tt.mouseover(this,e))))},catalogNode(){ +const e=this.thread.OP.files[0];if(e&&(e.isImage||e.isVideo))return He.on(this.nodes.thumb,"mouseover",tt.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=tt.error(e,o);if(j.cache?.dataset.fileID===`${e.fullID}.${o.index}`?(r=j.popCache(),He.on(r,"error",c)):(r=He.el(d?"video":"img"),r.dataset.fileID=`${e.fullID}.${o.index}`,He.on(r,"error",c),r.src=o.url),t["Restart when Opened"]&&(j.rewind(r),j.rewind(this)),r.id="ihover",He.add(Je.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]=Array.from(o.dimensions.split("x").map((e=>+e)));const e=i.clientWidth,t=i.clientHeight-F.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 F.hover({root:this,el:r,latestEvent:a,endEvents:"mouseout click",height:s, +width:l,noRemove:!0,cb:()=>(He.off(r,"error",c),j.pushCache(r),j.pause(r),He.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():""):He.rm(this)))}},nt={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}),He.on(a,"PostsInserted",(function(){if(nt.prefetchEnabled||e)return n.posts.forEach(nt.prefetchAll)})),t["Replace WEBM"]&&He.on(a,"scroll visibilitychange 4chanXInitFinished PostsInserted",this.playVideos),!t["Image Prefetching"]||!["index","thread"].includes(n.VIEW))return;const o=He.el("a",{href:"javascript:;",title:"Prefetch Images",innerHTML:"🗲︎"});return He.on(o,"click",this.toggle),Je.addShortcut("prefetch",o,525)},node(){ +if(!this.isClone)for(var e of this.files)t["Replace WEBM"]&&e.isVideo&&nt.replaceVideo(this,e),nt.prefetch(this,e)},replaceVideo(e,t){const{thumb:n}=t,o=He.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,He.replace(n,o),t.thumb=o,t.videoThumb=!0},prefetch(e,n){let o,a;const{isImage:i,isVideo:r,thumb:s,url:l}=n;if(n.isPrefetched||!i&&!r||e.isHidden||e.thread.isHidden)return;r?a="WEBM":(a=l.match(/\.([^.]+)$/)?.[1].toUpperCase(),"JPEG"===a&&(a="JPG"));const d=t[`Replace ${a}`]&&!/spoiler/.test(s.src||s.dataset.src);if(!d&&!nt.prefetchEnabled)return;if(He.hasClass(doc,"catalog-mode"))return;if(![e,...Array.from(e.clones)].some((e=>doc.contains(e.nodes.root))))return;if(n.isPrefetched=!0,n.videoThumb){for(o of e.clones)o.file.thumb.preload="auto";return s.preload="auto", +void("gecko"===He.engine&&He.on(s,"loadeddata",(function(){return this.removeAttribute("poster")})))}const c=He.el(i?"img":"video");return r&&(c.preload="auto"),d&&i&&He.on(c,"load",(function(){for(o of e.clones)o.file.thumb.src=l;return s.src=l})),c.src=l},prefetchAll(e){for(var t of e.files)nt.prefetch(e,t)},toggle(){nt.prefetchEnabled=!nt.prefetchEnabled,this.classList.toggle("disabled",!nt.prefetchEnabled),nt.prefetchEnabled&&n.posts.forEach(nt.prefetchAll)},playVideos(){const e=He.id("qp")?.firstElementChild;return n.posts.forEach((function(t){for(t of[t,...Array.from(t.clones)])for(var n of t.files)if(n.videoThumb){var{thumb:o}=n;Je.isNodeVisible(o)||t.nodes.root===e?o.play():o.pause()}}))}},ot={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'}),He.add(t.text,[He.tn(" "),e])),1===e.children.length&&He.one(e.lastElementChild,"mouseover focus",ot.load)}},load(){He.rmClass(this.parentNode,"error"),He.addClass(this.parentNode,"loading");const{index:e}=this.parentNode.dataset;return qe.binary(Qe.postFromNode(this).files[+e].url,(e=>{if(He.rmClass(this.parentNode,"loading"),null!=e){const t=ot.parse(e),n=He.el("span",{textContent:t||""});return null==t&&He.addClass(this.parentNode,"not-found"),He.before(this,n),this.parentNode.tabIndex=0,a.activeElement===this&&this.parentNode.focus(),this.tabIndex=-1}return He.addClass(this.parentNode,"error"),He.one(this,"click",ot.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--&&n0){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=He.el("a",{className:"linkify",rel:"noreferrer noopener",target:"_blank",href:o});return He.add(i,e.extractContents()),e.insertNode(i),i}};const rt={init(){if("yotsuba"!==n.SITE.software||!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Archive Link"])return;const e={el:He.el("div",{textContent:"Archive"}),order:60,open:({ID:e,thread:t,board:n})=>!!_e.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 V.menu.addEntry(e)},createSubEntry(e,t){const n=He.el("a",{textContent:e,target:"_blank"}),o="post"===t?function({ID:e,thread:t,board:o}){return n.href=_e.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():ze.values(t,e)[0];return!!a&&(n.href=_e.to("search",{boardID:e.board.ID,type:o,value:a,isSearch:!0}),!0)};return{el:n,open:o}}};var st={init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Copy Text Link"])return;const e=He.el("a",{className:"copy-text-link",href:"javascript:;",textContent:"Copy Text"});return He.on(e,"click",st.copy),V.menu.addEntry({el:e,order:12,open:e=>(st.text=(e.origin||e).commentOrig(),!0)})},copy(){const e=He.el("textarea",{className:"copy-text-element",value:st.text});He.add(a.body,e),e.select();try{a.execCommand("copy")}catch(e){}return He.rm(e)}},lt={auto:[m(),m()],init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Delete Link"])return;const e=He.el("div",{className:"delete-link",textContent:"Delete"}),o=He.el("a",{className:"delete-post",href:"javascript:;"}),a=He.el("a",{className:"delete-file", +href:"javascript:;"});this.nodes={menu:e.firstChild,links:[o,a]};const i={el:o,open:()=>(o.textContent=lt.linkText(!1),He.on(o,"click",lt.toggle),!0)},r={el:a,open:({file:e})=>!(!e||e.isDead)&&(a.textContent=lt.linkText(!0),He.on(a,"click",lt.toggle),!0)};return V.menu.addEntry({el:e,order:40,open:e=>!e.isDead&&(lt.post=e,lt.nodes.menu.textContent=lt.menuText(),lt.cooldown.start(e),!0),subEntries:[i,r]})},menuText(){let e;return(e=lt.cooldown.seconds[lt.post.fullID])?`Delete (${e})`:"Delete"},linkText(e){let t=e?"File":"Post";return lt.auto[+e][lt.post.fullID]&&(t=`Deleting ${t.toLowerCase()}...`),t},toggle(){const{post:e}=lt,t=He.hasClass(this,"delete-file"),n=lt.auto[+t];if(n[e.fullID]?delete n[e.fullID]:n[e.fullID]=!0,this.textContent=lt.linkText(t),!lt.cooldown.seconds[e.fullID])return lt.delete(e,t)},delete(e,t){const o=lt.nodes.links[+t];delete lt.auto[+t][e.fullID],e.fullID===lt.post.fullID&&He.off(o,"click",lt.toggle);const a={mode:"usrdel",onlyimgdel:t, +pwd:Oe.persona.getPassword()};return a[+e.ID]="delete",He.ajax(He.id("delform").action.replace(`/${n.BOARD}/`,`/${e.board}/`),{responseType:"document",withCredentials:!0,onloadend(){return lt.load(o,e,t,this.response)},form:He.formData(a)})},load(e,n,o,a){let i;if(!a)return new Ke("warning","Connection error, please retry.",20),void(n.fullID===lt.post.fullID&&He.on(e,"click",lt.toggle));if(e.textContent=lt.linkText(o),"4chan - Banned"===a.title){const e=He.el("span",{innerHTML:'You can't delete posts because you are banned.'});return new Ke("warning",e,20)}if(i=a.getElementById("errmsg")){if(new Ke("warning",i.textContent,20),n.fullID===lt.post.fullID&&He.on(e,"click",lt.toggle),Oe.cooldown.data&&t.Cooldown&&/\bwait\b/i.test(i.textContent))return lt.cooldown.start(n,5),lt.auto[+o][n.fullID]=!0,lt.nodes.links[+o].textContent=lt.linkText(o)}else if(o||Oe.cooldown.delete(n),"Updating index..."===a.title&&(n.origin||n).kill(o), +n.fullID===lt.post.fullID)return e.textContent="Deleted"},cooldown:{seconds:m(),start(e,t){if(null==lt.cooldown.seconds[e.fullID])return null==t&&(t=Oe.cooldown.secondsDeletion(e)),t>0?(lt.cooldown.seconds[e.fullID]=t,lt.cooldown.count(e)):void 0},count(e){if(e.fullID===lt.post.fullID&&(lt.nodes.menu.textContent=lt.menuText()),lt.cooldown.seconds[e.fullID]>0&&t.Cooldown)lt.cooldown.seconds[e.fullID]--,setTimeout(lt.cooldown.count,1e3,e);else for(var n of(delete lt.cooldown.seconds[e.fullID],[!1,!0]))lt.auto[+n][e.fullID]&<.delete(e,n)}}};const dt={init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Download Link"])return;const e=He.el("a",{className:"download-link",textContent:"Download file"});return He.on(e,"click",j.download),V.menu.addEntry({el:e,order:100,open:({file:t})=>!!t&&(e.href=t.url,e.download=t.name,!0)})}};var ct={init(){if(!["index","thread"].includes(n.VIEW)||!t.Menu||!t["Report Link"])return;const e=He.el("a",{className:"report-link",href:"javascript:;", +textContent:"Report"});return He.on(e,"click",ct.report),V.menu.addEntry({el:e,order:10,open:e=>(ct.url=`//sys.${location.hostname.split(".")[1]}.org/${e.board}/imgboard.php?mode=report&no=${e}`,a.cookie.indexOf("pass_enabled=1")>=0?ct.dims="width=350,height=275":ct.dims="width=400,height=550",!0)})},report(){const{url:e,dims:t}=ct,n=Date.now(),o=`toolbar=0,scrollbars=1,location=0,status=1,menubar=0,resizable=1,${t}`;return window.open(e,n,o)}},ht={init(){if(t["Disable Autoplaying Sounds"]){for(var e of(He.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}),He.ready((()=>this.process(d.body)))}},stop(e){if(e.autoplay&&(e.pause(),e.autoplay=!1,!e.controls))return e.controls=!0,He.addClass(e,"controls-added")},node(){return ht.process(this.nodes.comment)},process(e){ +for(var t of u('iframe[src*="youtube"][src*="autoplay=1"]',e))ht.processVideo(t,"src");for(var n of u('object[data*="youtube"][data*="autoplay=1"]',e))ht.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"),He.addClass(e,"autoplay-removed"))},ut={init(){if(t["Custom Board Titles"]&&(this.db=new y("customTitles",null,!0)),He.asap((()=>a.body),(()=>He.asap((()=>He("hr")),ut.ready))),"f"!==n.BOARD.ID)return Lt.ready((()=>He.queueTask(ut.load)))},ready(){const e=He(".boardBanner"),{children:o}=e;if("thread"===n.VIEW&&t["Remove Thread Excerpt"]&&ut.setTitle(o[1].textContent),o[0].title="Click to change",He.on(o[0],"click",ut.cb.toggle),t["Custom Board Titles"]&&(ut.custom(o[1]),o[2]))return ut.custom(o[2])},load(){const e=He.id("bannerCnt");if(!e.firstChild){const t=He.el("img",{alt:"4chan",src:"//s.4cdn.org/image/title/"+e.dataset.src});return He.add(e,t)}}, +setTitle:e=>null!=Z.title?(Z.title=e,Z.update()):a.title=e,cb:{toggle(){ut.choices?.length||(ut.choices=t.knownBanners.split(",").slice());const e=Math.floor(ut.choices.length*Math.random()),n=ut.choices.splice(e,1);return He("img",this.parentNode).src=`//s.4cdn.org/image/title/${n}`},click(e){if(e.ctrlKey||e.metaKey){for(var t of(null==ut.original[this.className]&&(ut.original[this.className]=this.cloneNode(!0)),this.contentEditable=!0,u("br",this)))He.replace(t,He.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))He.replace(e,He.tn("\n"));return(this.textContent=this.textContent.replace(/\n*$/,""))?(this.contentEditable=!1,ut.db.set({boardID:n.BOARD.ID,threadID:this.className,val:{title:this.textContent,orig:ut.original[this.className].textContent}})):(He.rmAll(this),He.add(this,[...Array.from(ut.original[this.className].cloneNode(!0).childNodes)]),ut.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"]))He.on(e,i,ut.cb[i]);if(o=ut.db.get({boardID:n.BOARD.ID,threadID:a}))return t["Persistent Custom Board Titles"]||o.orig===e.textContent?(ut.original[a]=e.cloneNode(!0),e.textContent=o.title):ut.db.delete({boardID:n.BOARD.ID,threadID:a})}},pt={init(){if("f"===n.BOARD.ID&&t["Enable Native Flash Embedding"])return He.ready(pt.initReady)},initReady:()=>He.hasStorage?He.global((function(){if(JSON.parse(localStorage["4chan-settings"]||"{}").disableAll)return window.SWFEmbed.init()})):("thread"===n.VIEW&&He.global((()=>window.Main.tid=location.pathname.split(/\/+/)[3])),He.global((()=>window.SWFEmbed.init())))},gt={init(){if("yotsuba"===n.SITE.software&&["index","thread","archive"].includes(n.VIEW))return G.ready(this.initBoard),Lt.ready(this.initReady)},initBoard(){ +if(n.BOARD.config.code_tags&&(He.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 He.hasClass(o,"prettyprinted")?void 0:(o.innerHTML=e.detail.html,He.addClass(o,"prettyprinted"))})),He.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:gt.code}),n.posts.forEach((function(e){if(e.callbacksExecuted)return l.Post.execute(e,["Parse [code] tags"],!0)})),K.callbacks.push(gt.code)),n.BOARD.config.math_tags)return He.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:gt.math}),n.posts.forEach((function(e){if(e.callbacksExecuted)return l.Post.execute(e,["Parse [math] tags"],!0)})),K.callbacks.push(gt.math)},initReady:()=>He.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 He.ready((()=>{const e=u(".prettyprint",this.nodes.comment);for(let n=0;n{ +if(i.contains(this.nodes.comment))return He.off(a,"PostsInserted",n),He.event("mathjax",null,this.nodes.comment)};return He.on(a,"PostsInserted",n),n()}}},ft={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=ft.ids[t]||ft.compute(t),{style:o}=e;return o.color=n[3],o.backgroundColor=`rgb(${n[0]},${n[1]},${n[2]})`,He.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(He.luma(o)>125?"#000":"#fff"),this.ids[e]=o}},mt={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&&He.on(this.nodes.uniqueIDRoot,"click",mt.click(this)), +this.nodes.capcode&&He.on(this.nodes.capcode,"click",mt.click(this)),!this.isClone)return mt.set(this)},set(e){const t=(e.info.uniqueID||e.info.capcode)===mt.uniqueID;return He[t?"addClass":"rmClass"](e.nodes.post,"highlight")},click:e=>function(){const t=e.info.uniqueID||e.info.capcode;return mt.uniqueID=mt.uniqueID===t?null:t,n.posts.forEach(mt.set)}},bt={init(){if("thread"===n.VIEW&&t["Count Posts by ID"])return l.Thread.push({name:"Count Posts by ID",cb(){return bt.thread=this}}),l.Post.push({name:"Count Posts by ID",cb:this.node})},node(){if(this.nodes.uniqueID&&this.thread===bt.thread)return He.on(this.nodes.uniqueID,"mouseover",bt.count)},count(){const{uniqueID:e}=Qe.postFromNode(this).info;let t=0;return bt.thread.posts.forEach((function(n){if(n.info.uniqueID===e)return t++})),this.title=`${t} post${1===t?"":"s"} by this ID`}},At={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||!He.hasOwn(At.specific,this.info.capcode))return;const t=He.el("span",{className:"contact-links brackets-wrap"});if(He.extend(t,At.template(this.info.capcode)),He.after(this.nodes.capcode,t),(e=this.info.comment.match(/This thread was moved to >>>\/(\w+)\//))&&He.hasOwn(At.moveNote,e[1])){const t=He.el("div",{className:"move-note"});return He.extend(t,At.moveNote[e[1]]),He.add(this.nodes.post,t)}},template:e=>({innerHTML:'feedback'+At.specific[e]().innerHTML}),specific:{Mod:()=>({innerHTML:' IRC'}),Manager:()=>At.specific.Mod(),Developer:()=>({innerHTML:' github'}),Admin:()=>({innerHTML:' twitter'})},moveNote:{qa:{ +innerHTML:'Moving a thread to /qa/ does not imply mods will read it. If you wish to contact mods, use feedback or IRC.'}}};const vt={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 wt={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))wt.addListeners(e);else if(this.nodes.uniqueIDRoot&&wt.addButtons(this,"uniqueID"),this.nodes.capcode)return wt.addButtons(this,"capcode")},addButtons(e,t){const n=e.info[t],o=wt.buttons.cloneNode(!0);return He.extend(o.dataset,{type:t,value:n}),He.after(e.nodes[t+("capcode"===t?"":"Root")],o),wt.addListeners(o)},addListeners:e=>(He.on(e.firstChild,"click",wt.buttonClick),He.on(e.lastChild,"click",wt.buttonClick)),buttonClick(){let e;const t=He.hasClass(this,"prev")?-1:1;if(e=wt.find(this.parentNode,t))return wt.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=He.x(`${i}::${a}`,r);)if(r.getBoundingClientRect().height)return r;if((r=He.x(`(//${a})[${t<0?"last()":"1"}]`))&&r.getBoundingClientRect().height)return r +;for(;(r=He.x(`${i}::${a}`,r))&&r!==e;)if(r.getBoundingClientRect().height)return r;return null},makeButtons(){const e=He.el("span",{className:"postJumper"});return He.extend(e,{innerHTML:''+o("⏫")+''+o("⏬")+""}),e},scroll(e,t){const n=e.getBoundingClientRect().top,o=t.getBoundingClientRect().top;return window.scrollBy(0,o-n)}};const xt={init(){let e;if("yotsuba"===n.SITE.software&&"qa"===n.BOARD.ID){const t={innerHTML:'Stay in touch with your /qa/ friends!'};e=He.el("div",{className:"fcx-announcement"},t),He.onExists(i,".boardBanner",(t=>He.after(t,e)))}if("samachan.org"in t.siteProperties&&!t.PSAseen.includes("samachan"))return e=He.el("span",{ +innerHTML:'Looking for a new home?
            Some former Samachan users are regrouping on SushiChan.

            (a message from 4chan X)'}),Lt.ready((function(){return new Ke("info",e),t.PSAseen.push("samachan"),He.set("PSAseen",t.PSAseen)}))}};var yt={init(){if(t["Announcement Hiding"]&&n.SITE.selectors.psa)return He.addClass(i,"hide-announcement"),He.onExists(i,n.SITE.selectors.psa,this.setup),He.ready((function(){if(!He(n.SITE.selectors.psa))return He.rmClass(i,"hide-announcement")}))},setup(e){let o,a;yt.psa=e,yt.text=e.dataset.utc??e.innerHTML,n.SITE.selectors.psaTop&&(a=He(n.SITE.selectors.psaTop)?.previousElementSibling)&&"HR"===a.nodeName&&(yt.hr=a),yt.content=He.el("div");const r={el:He.el("a",{textContent:"Show announcement",className:"show-announcement",href:"javascript:;"}),order:50,open:()=>e.hidden};return Je.menu.addEntry(r),He.on(r.el,"click",yt.toggle),yt.btn=o=He.el("a",{ +title:"Mark announcement as read and hide.",className:"hide-announcement-button",href:"javascript:;",textContent:"➖︎"}),He.on(o,"click",yt.toggle),"HR"===e.firstChild?.tagName?He.after(e.firstChild,o):He.prepend(e,o),yt.sync(t.hiddenPSAList),He.rmClass(i,"hide-announcement"),He.sync("hiddenPSAList",yt.sync)},toggle(){const e=He.hasClass(this,"hide-announcement-button"),o=function(t){return e?t[n.SITE.ID]=yt.text:delete t[n.SITE.ID]};return o(t.hiddenPSAList),yt.sync(t.hiddenPSAList),He.get("hiddenPSAList",t.hiddenPSAList,(function({hiddenPSAList:e}){return o(e),He.set("hiddenPSAList",e)}))},sync(e){const{psa:t,content:o}=yt;t.hidden=e[n.SITE.ID]===yt.text,t.hidden?He.add(o,[...Array.from(t.childNodes)]):He.add(t,[...Array.from(o.childNodes)]),yt.hr&&(yt.hr.hidden=t.hidden)}},kt={init(){if(t["Reveal Spoilers"]&&He.addClass(i,"reveal-spoilers"),t["Remove Spoilers"])return l.Post.push({name:"Reveal Spoilers",cb:this.node}), +"archive"===n.VIEW?He.ready((()=>kt.unspoiler(He.id("arc-list")))):void 0},node(){return kt.unspoiler(this.nodes.comment)},unspoiler(e){const t=u(n.SITE.selectors.spoiler,e);for(var o of t){var a=He.el("span",{className:"removed-spoiler"});He.replace(o,a),He.add(a,[...Array.from(o.childNodes)])}}},It={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 It.process(this.nodes.reply)},catalogNode(){return It.process(this.nodes.thumb.parentNode)},process:e=>e.target="_blank"};const Ct={init(){if("tinyboard"===n.SITE.software)return"thread"===n.VIEW?Lt.ready((()=>He.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 Dt={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 Dt.ipCount=this.ipCount,Dt.postCount=this.posts.keys.length,He.on(a,"ThreadUpdate",Dt.onUpdate)},onUpdate(e){let t;const{ipCount:o,postCount:a,newPosts:i,deletedPosts:r}=e.detail;if(null!=o){switch(o-Dt.ipCount){case a-Dt.postCount+r.length:var s=Dt.ipCount;for(t of i)Dt.markNew(n.posts.get(t),++s);break;case-r.length:for(t of i)Dt.markOld(n.posts.get(t))}return Dt.ipCount=o,Dt.postCount=a}},markNew(e,t){ +const n=Math.floor(t/10)%10==1?"th":["st","nd","rd"][t%10-1]||"th",o=He.el("span",{className:"ip-counter",textContent:`(${t})`});return e.nodes.nameBlock.title=`This is the ${t}${n} IP in the thread.`,He.add(e.nodes.nameBlock,[He.tn(" "),o]),He.addClass(e.nodes.root,"new-ip")},markOld:e=>(e.nodes.nameBlock.title="Not the first post from this IP.",He.addClass(e.nodes.root,"old-ip"))},Et={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:'? / ?'+(t["IP Count in Stats"]&&n.SITE.hasIPCount?' / ?':"")+(t["Page Count in Stats"]?' / ?':"")};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=He.el("span",{id:"thread-stats",title:s}),He.extend(e,r),Je.addShortcut("stats",e,200)):(this.dialog=e=F.dialog("thread-stats",{innerHTML:'
            '+r.innerHTML+"
            "}),He.addClass(i,"float"),He.ready((()=>He.add(a.body,e)))),this.postCountEl=He("#post-count",e),this.fileCountEl=He("#file-count",e),this.ipCountEl=He("#ip-count",e),this.pageCountEl=He("#page-count",e),this.pageCountEl&&He.on(this.pageCountEl,"click",Et.fetchPage),l.Thread.push({name:"Thread Stats",cb:this.node})},node(){return Et.thread=this,Et.count(),Et.update(),Et.fetchPage(),He.on(a,"PostsInserted",(()=>He.queueTask(Et.onPostsInserted))),He.on(a,"ThreadUpdate",Et.onUpdate)},count(){const{posts:e}=Et.thread,t=e.keys.length;for(let o=Et.postIndex,a=t;o=n-this.response[0].threads.length),Et.lastPageUpdate=new Date(t.last_modified*b),void Et.retry();o++}}}else if(304===this.status)return Et.retry()},retry(){if(!(!Et.showPage||"1"===Et.pageCountEl.textContent||n.SITE.threadModTimeIgnoresSage||Et.thread.posts.get(Et.thread.lastPost).info.date<=Et.lastPageUpdate))return clearTimeout(Et.timeout),Et.timeout=setTimeout(Et.fetchPage,5e3)}};const St={init(){if("yotsuba"===n.SITE.software&&t["Pass Link"])return Lt.ready(this.ready)},ready(){let e;if(!(e=He.id("styleSelector")))return;const t=He.el("span",{className:"brackets-wrap pass-link-container"}) +;return He.extend(t,{innerHTML:'4chan Pass'}),He.on(t.firstElementChild,"click",(()=>window.open(`//sys.${location.hostname.split(".")[1]}.org/auth`,Date.now(),"width=500,height=280,toolbar=0"))),He.before(e.previousSibling,[t,He.tn("  ")])}};var Tt={init(){if(["index","thread"].includes(n.VIEW)&&t["Quote Inlining"])return t["Comment Expansion"]&&K.callbacks.push(this.node),l.Post.push({name:"Quote Inlining",cb:this.node})},node(){const{process:e}=Tt,{isClone:t}=this;for(var n of this.nodes.quotelinks.concat([...Array.from(this.nodes.backlinks)],this.nodes.archivelinks))e(n,t)},process:(e,n)=>(t["Quote Hash Navigation"]&&(n||He.after(e,Tt.qiQuote(e,He.hasClass(e,"filtered")))),He.on(e,"click",Tt.toggle)),qiQuote(e,t){let n="hashlink";return t&&(n+=" filtered"),He.el("a",{className:n,textContent:"#",href:e.href})},toggle(e){if(He.modifiedClick(e))return;const{boardID:o,threadID:a,postID:r}=Qe.postDataFromLink(this) +;if(t["Inline Cross-thread Quotes Only"]&&"thread"===n.VIEW&&n.posts.get(`${o}.${r}`)?.nodes.root.offsetParent)return;if(He.hasClass(i,"catalog-mode"))return;e.preventDefault();const s=Qe.postFromNode(this),{context:l}=s;if(He.hasClass(this,"inlined"))Tt.rm(this,o,a,r,l);else{if(He.x(`ancestor::div[@data-full-i-d='${o}.${r}']`,this))return;Tt.add(this,o,a,r,l,s)}return this.classList.toggle("inlined")},findRoot:(e,t)=>t?He.x('ancestor::*[parent::*[contains(@class,"post")]][1]',e):He.x("ancestor-or-self::*[parent::blockquote][1]",e),add(e,o,a,i,r,s){let l;const d=He.hasClass(e,"backlink"),c=He.el("div",{className:"inline"});c.dataset.fullID=`${o}.${i}`;const h=Tt.findRoot(e,d);He.after(h,c);const u=He.x('ancestor::*[contains(@class,"postContainer")][1]',h);if(He.addClass(u,"hasInline"),new ae(o,a,i,c,s),(l=n.posts.get(`${o}.${i}`))&&r.thread===l.thread&&(d&&t["Forward Hiding"]&&(He.addClass(l.nodes.root,"forwarded"),l.forwarded++||(l.forwarded=1)),Z.posts))return Z.readSinglePost(l)}, +rm(e,o,a,i,r){let s,l;const d=He.hasClass(e,"backlink");let c=Tt.findRoot(e,d);c=He.x(`following-sibling::div[@data-full-i-d='${o}.${i}'][1]`,c);const h=He.x('ancestor::*[contains(@class,"postContainer")][1]',c),{parentNode:u}=c;if(He.rm(c),He.event("PostsRemoved",null,u),He(".inline",h)||He.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,He.rmClass(p.nodes.root,"forwarded"));l=He(".inlined",s);)({boardID:o,threadID:a,postID:i}=Qe.postDataFromLink(l)),Tt.rm(l,o,a,i,r),He.rmClass(l,"inlined")}},Rt={containers:m(),init(){if(["index","thread"].includes(n.VIEW)&&t["Quote Backlinks"])return(this.bottomBacklinks=t["Bottom Backlinks"])&&He.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"]&&X.isYou(this),o=He.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&&He.add(o,X.mark.cloneNode(!0)),this.quotes)){var i,r=[Rt.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?[He.tn(" "),d]:[d];if(t["Quote Previewing"]&&He.on(d,"mouseover",ie.mouseover),t["Quote Inlining"]&&(He.on(d,"click",Tt.toggle),t["Quote Hash Navigation"])){var h=Tt.qiQuote(d,He.hasClass(d,"filtered"));c.push(h)}He.add(l,c)}}},secondNode(){if(this.isClone&&(this.origin.isReply||t["OP Backlinks"]))return void(this.nodes.backlinkContainer=He(".container",this.nodes.post));if(!this.isReply&&!t["OP Backlinks"])return +;const e=Rt.getContainer(this.fullID);return this.nodes.backlinkContainer=e,Rt.bottomBacklinks?He.add(this.nodes.post,e):He.add(this.nodes.info,e)},getContainer(e){return this.containers[e]||(this.containers[e]=He.el("span",{className:"container"}))}},Bt={init(){if(["index","thread"].includes(n.VIEW)&&t["Mark Cross-thread Quotes"])return t["Comment Expansion"]&&K.callbacks.push(this.node),this.mark=He.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}=Qe.postDataFromLink(n);a&&(this.isClone&&He.rm(He(".qmark-ct",n)),o===e.ID&&a!==t.ID&&He.add(n,Bt.mark.cloneNode(!0)))}}},Pt={init(){if(["index","thread"].includes(n.VIEW)&&t["Mark OP Quotes"])return t["Comment Expansion"]&&K.callbacks.push(this.node),this.mark=He.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++];)He.rm(He(".qmark-op",t));const{fullID:a}=this.context.thread;if(n.includes(a))for(e=0;t=o[e++];){var{boardID:i,postID:r}=Qe.postDataFromLink(t);`${i}.${r}`===a&&He.add(t,Pt.mark.cloneNode(!0))}}};var Mt={init(){if(["index","thread"].includes(n.VIEW)&&t["Resurrect Quotes"])return He.addClass(i,"resurrect-quotes"),t["Comment Expansion"]&&K.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))Mt.parseArchivelink.call(this,e);for(var t of u(".deadlink",this.nodes.comment))Mt.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 _e.to("post",{boardID:n,postID:a})?(He.addClass(e,"quotelink"),He.extend(e.dataset,{boardID:n,threadID:o,postID:a}),this.nodes.archivelinks.push(e)):void 0},parseDeadlink(e){let t,o,a,i;if(He.hasClass(e.parentNode,"prettyprint"))return void Mt.fixDeadlink(e);const r=e.textContent;if(!(i=r.match(/\d+$/)?.[0]))return;if("0"===i[0])return void Mt.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=He.el("a",{href:n.SITE.Build.postURL(s,a.thread.ID,i),className:"quotelink deadlink",textContent:r}),He.add(t,U.deadMark.cloneNode(!0)),He.extend(t.dataset,{boardID:s,threadID:a.thread.ID,postID:i})):t=He.el("a",{href:n.SITE.Build.postURL(s,a.thread.ID,i),className:"quotelink",textContent:r});else{const e=_e.to("thread",{ +boardID:s,threadID:0,postID:i}),n=_e.to("post",{boardID:s,postID:i});(e||n)&&(t=He.el("a",{href:e||"javascript:;",className:"deadlink",textContent:r}),He.add(t,U.deadMark.cloneNode(!0)),n&&(He.addClass(t,"quotelink"),He.extend(t.dataset,{boardID:s,postID:i})))}if(this.quotes.includes(l)||this.quotes.push(l),t)return He.replace(e,t),He.hasClass(t,"quotelink")?this.nodes.quotelinks.push(t):void 0;He.add(e,U.deadMark.cloneNode(!0))},fixDeadlink(e){let t;if(!(t=e.previousSibling)||"BR"===t.nodeName){const t=He.el("span",{className:"quote"});He.before(e,t),He.add(t,e)}return He.replace(e,[...Array.from(e.childNodes)])}};const Nt={init(){this.toBlob(),He.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(()=>{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)&&(He.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)}})),He.asap(s,(()=>He.onExists(i,"iframe[srcdoc]",He.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=_e.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)||Ie.yotsuba.regexp.pass.test(location.href)||Ie.yotsuba.regexp.captcha.test(location.href)||u("script:not([src])",a).filter((e=>/this\[/.test(e.textContent))).length||(He.getSync||He.get)({jsWhitelist:t.jsWhitelist},(({jsWhitelist:e})=>He.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,(He.getSync||He.get)(h,(function(e){if(He.perProtocolSettings||!/\.4chan(?:nel)?\.org$/.test(location.hostname)||!(e["Redirect to HTTPS"]??t["Redirect to HTTPS"])||"https:"===location.protocol)return He.asap(s,(function(){for(o in He.cantSet||(null==e.previousversion?(Ft.isFirstRun=!0,Ft.ready((function(){return He.set("previousversion",n.VERSION),Re.open() +}))):e.previousversion!==n.VERSION&&Ft.upgrade(e)),t){var a=t[o];t[o]=e[o]??a}return We.init(Ft.initFeatures)}));location.replace("https://"+location.host+location.pathname+location.search+location.hash)}))},upgrade(t){const{previousversion:o}=t,a=Re.upgrade(t,o);return t.previousversion=a.previousversion=n.VERSION,He.set(a,(function(){if(t["Show Updated Notifications"]??1){const t=He.el("span",{innerHTML:`${e.name} has been updated to version ${n.VERSION}.`});return new Ke("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(He.global((function(){return document.documentElement.classList.add("js-enabled"),window.FCX={}})),Ft.jsEnabled=He.hasClass(i,"js-enabled"),He.ajaxPageInit?.(),He.extend(n,Ft.parseURL()),n.boardID&&(n.BOARD=new Y(n.boardID)),n.VIEW){if("file"!==n.VIEW){for(var[e,o]of(n.threads=new k,n.posts=new k,He.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 He.ready(Ft.initReady)}He.asap((()=>"loading"!==a.readyState),(function(){let e;if("yotsuba"===n.SITE.software&&t["404 Redirect"]&&n.SITE.is404?.()){const e=location.pathname.split(/\/+/);return _e.navigate("file",{boardID:n.BOARD.ID,filename:e[e.length-1]})} +if((e=He("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=He("link[href*=mobile]",a.head);e&&(e.disabled=!0),i.dataset.host=location.host,He.addClass(i,`sw-${n.SITE.software}`),He.addClass(i,"thread"===n.VIEW?"thread-view":n.VIEW),He.onExists(i,".ad-cnt, .adg-rects > .desktop",(e=>He.onExists(e,"img, iframe",(()=>He.addClass(i,"ads-loaded"))))),t["Autohiding Scrollbar"]&&He.addClass(i,"autohiding-scrollbar"),He.ready((function(){if(a.body.clientHeight>i.clientHeight&&window.innerWidth===i.clientWidth!==t["Autohiding Scrollbar"])return t["Autohiding Scrollbar"]=!t["Autohiding Scrollbar"],He.set("Autohiding Scrollbar",t["Autohiding Scrollbar"]),He.toggleClass(i,"autohiding-scrollbar")})),He.addStyle(fe.sub(fe.boards),"fourchanx-css"),Ft.bgColorStyle=He.el("style",{id:"fourchanx-bgcolor-css"});let o=!1 +;return He.on(a,"mousedown",(()=>o=!1)),He.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=He.id("base-css"))&&(t=e.href.match(/catalog_(\w+)/)?.[1].replace("_new","").replace(/_+/g,"-"),r.includes(t)))return void He.addClass(i,t);t=e=o=null;const s=function(){if("yotsuba"===n.SITE.software){for(var s of(He.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 He.addClass(i,t),void He.rm(Ft.bgColorStyle)}const l=n.SITE.bgColoredEl();l.style.position="absolute",l.style.visibility="hidden",He.add(a.body,l);let d=window.getComputedStyle(l).backgroundColor;He.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 He.luma(c)<100&&(h+=".watch-thread-link {\n background-image: url(\"data:image/svg+xml,\");\n}"),Ft.bgColorStyle.textContent=h,He.after(He.id("fourchanx-css"),Ft.bgColorStyle)} +;if(He.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"]}),He.on(e,"load",s),s()})),!e){for(var l of u('link[rel="stylesheet"]',a.head))He.on(l,"load",s);return s()}},initReady(){if(!n.SITE.is404?.()){if(n.SITE.isIncomplete?.()){const e=He.el("div",{innerHTML:'The page didn't load completely.
            Some features may not work unless you reload.'});He.on(He("a",e),"click",(()=>location.reload())),new Ke("warning",e)}return"catalog"===n.VIEW?Ft.initCatalog():se.enabled?(Ft.expectInitFinished=!0,He.event("4chanXInitFinished")):n.SITE.awaitBoard?n.SITE.awaitBoard(Ft.initThread):Ft.initThread()}"thread"===n.VIEW&&oe.set404(n.BOARD.ID,n.THREADID,(function(){if(t["404 Redirect"])return _e.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=He(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)Se.insert(e);return Ft.expectInitFinished=!0,He.event("4chanXInitFinished")}))}return Ft.expectInitFinished=!0,He.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 Y(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))&&He(n.SITE.selectors.comment,i))try{o.push(new U(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,(()=>He.event("PostsInserted",null,e[0].target)))},addPosts(e){let t;const o=[],a=[],r=[],s=[];for(var l of e){t=Qe.threadFromRoot(l.target);var d=[] +;for(var c of l.addedNodes)c.nodeType===Node.ELEMENT_NODE&&(c.matches(n.SITE.selectors.postContainer)||(c=He(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(Qe.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)He.event("PostsInserted",null,t.nodes.root);for(t of a)He.event("PostsRemoved",null,t.nodes.root)}))},initCatalog(){let e;const t=n.SITE.selectors.catalog;if(t&&(e=He(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,He.event("4chanXInitFinished")},parseCatalogThreads(e,t,n){for(var o of e)try{ +var a=new Ze(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%25)};var r=function(){for(;i(););if(t[o])return setTimeout(r,0);n&&n()};return r()},handleErrors(r){let s;if(a.body&&He.hasClass(a.body,"fourchan_x")&&!He.hasClass(i,"tainted")&&(new Ke("error","Error: Multiple copies of 4chan X are enabled."),He.addClass(i,"tainted")), +n.SITE.testNativeExtension&&!He.hasClass(i,"tainted")){const{enabled:a}=n.SITE.testNativeExtension();if(a&&(He.addClass(i,"tainted"),t["Disable Native Extension"]&&!Ft.isFirstRun)){const t=He.el("div",{innerHTML:'Failed to disable the native extension. You may need to block it.'});new Ke("error",t)}}if(r instanceof Array?1===r.length&&(s=r[0]):s=r,s)return void new Ke("error",Ft.parseError(s,Ft.reportLink([s])),15);const l=He.el("div",{innerHTML:`${r.length} errors occurred.${Ft.reportLink(r).innerHTML} [show]`});He.on(l.lastElementChild,"click",(function(){let e;return[this.textContent,d.hidden]=Array.from(e="show"===this.textContent?["hide",!1]:["show",!0]),e}));var d=He.el("div",{hidden:!0});for(s of r)He.add(d,Ft.parseError(s));return new Ke("error",[l,d],30)},parseError(t,a){r.error(t.message,t.error.stack);const i=He.el("div",{innerHTML:o(t.message)+(a?a.innerHTML:"")}),s=He.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,He.el("div",{textContent:`(${e.name} ${e.fork} v${n.VERSION} ${x} on ${He.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:` [report]`}},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=>He.ready((function(){if(Ft.isThisPageLegit())return e()})),mounted:e=>Ft.isMounted?e():Ft.mountedCBs.push(e),mountedCBs:[], +features:[["Polyfill",Nt],["Board Configuration",G],["Normalize URL",vt],["Delay Redirect on Post",J],["Captcha Configuration",p],["Image Host Rewriting",O],["Redirect",_e],["Header",Je],["Catalog Links",Ge],["Settings",Re],["Index Generator",se],["Disable Autoplay",ht],["Announcement Hiding",yt],["Fourchan thingies",gt],["Tinyboard Glue",Ct],["Color User IDs",ft],["Highlight by User ID",mt],["Count Posts by ID",bt],["Custom CSS",be],["Thread Links",It],["Linkify",it],["Reveal Spoilers",kt],["Resurrect Quotes",Mt],["Filter",ze],["Thread Hiding Buttons",le],["Reply Hiding Buttons",z],["Recursive",Q],["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}=Qe.postDataFromLink(e);n.posts.get(`${t}.${o}`)?.isHidden&&He.addClass(e,"filtered")}} +}],["Quick Reply Personas",Oe.persona],["Quick Reply",Oe],["Cooldown",Oe.cooldown],["Post Jumper",wt],["Pass Link",St],["Menu",V],["Index Generator (Menu)",se.menu],["Report Link",ct],["Copy Text Link",st],["Thread Hiding (Menu)",le.menu],["Reply Hiding (Menu)",z.menu],["Delete Link",lt],["Filter (Menu)",ze.menu],["Edit Link",Oe.oekaki.menu],["Download Link",dt],["Archive Link",rt],["Quote Inlining",Tt],["Quote Previewing",ie],["Quote Backlinks",Rt],["Mark Quotes of You",X],["Mark OP Quotes",Pt],["Mark Cross-thread Quotes",Bt],["Anonymize",et],["Time Formatting",De],["Relative Post Dates",W],["File Info Formatting",Ce],["Fappe Tyme",Be],["Gallery",Me],["Gallery (menu)",Me.menu],["Sauce",Pe],["Image Expansion",q],["Image Expansion (Menu)",q.menu],["Reveal Spoiler Thumbnails",at],["Image Loading",nt],["Image Hover",tt],["Volume Control",$],["WEBM Metadata",ot],["Comment Expansion",K],["Thread Expansion",ee],["Favicon",h],["Unread",Z],["Unread Line in Index",te],["Quote Threading",Se],["Thread Stats",Et],["Thread Updater",Te],["Thread Watcher",oe],["Thread Watcher (Menu)",oe.menu],["Mark New IPs",Dt],["Index Navigation",L],["Keybinds",Fe],["Banner",ut],["Announcements",xt],["Flash Features",pt],["Reply Pruning",Ee],["Mod Contact Links",At]] +},Lt=Ft;He.ready((()=>Ft.init()))}(); +//# sourceMappingURL=4chan-XT-noupdate.user.min.js.map diff --git a/builds/4chan-XT-noupdate.user.min.js.map b/builds/4chan-XT-noupdate.user.min.js.map new file mode 100644 index 000000000..2bd0c8f60 --- /dev/null +++ b/builds/4chan-XT-noupdate.user.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"4chan-XT-noupdate.user.min.js","sources":["../../../../src/globals/globals.ts","../src/classes/Callbacks.js","../src/config/Config.js","../src/Monitoring/Favicon.js","../src/Monitoring/Favicon/ferongr.unreadDead.png","../src/Monitoring/Favicon/ferongr.unreadDeadY.png","../src/Monitoring/Favicon/ferongr.unreadSFW.png","../src/Monitoring/Favicon/ferongr.unreadSFWY.png","../src/Monitoring/Favicon/ferongr.unreadNSFW.png","../src/Monitoring/Favicon/ferongr.unreadNSFWY.png","../src/Monitoring/Favicon/xat-.unreadDead.png","../src/Monitoring/Favicon/xat-.unreadDeadY.png","../src/Monitoring/Favicon/xat-.unreadSFW.png","../src/Monitoring/Favicon/xat-.unreadSFWY.png","../src/Monitoring/Favicon/xat-.unreadNSFW.png","../src/Monitoring/Favicon/xat-.unreadNSFWY.png","../src/Monitoring/Favicon/Mayhem.unreadDead.png","../src/Monitoring/Favicon/Mayhem.unreadDeadY.png","../src/Monitoring/Favicon/Mayhem.unreadSFW.png","../src/Monitoring/Favicon/Mayhem.unreadSFWY.png","../src/Monitoring/Favicon/Mayhem.unreadNSFW.png","../src/Monitoring/Favicon/Mayhem.unreadNSFWY.png","../src/Monitoring/Favicon/4chanJS.unreadDead.png","../src/Monitoring/Favicon/4chanJS.unreadDeadY.png","../src/Monitoring/Favicon/4chanJS.unreadSFW.png","../src/Monitoring/Favicon/4chanJS.unreadSFWY.png","../src/Monitoring/Favicon/4chanJS.unreadNSFW.png","../src/Monitoring/Favicon/4chanJS.unreadNSFWY.png","../src/Monitoring/Favicon/Original.unreadDead.png","../src/Monitoring/Favicon/Original.unreadDeadY.png","../src/Monitoring/Favicon/Original.unreadSFW.png","../src/Monitoring/Favicon/Original.unreadSFWY.png","../src/Monitoring/Favicon/Original.unreadNSFW.png","../src/Monitoring/Favicon/Original.unreadNSFWY.png","../src/Monitoring/Favicon/Metro.unreadDead.png","../src/Monitoring/Favicon/Metro.unreadDeadY.png","../src/Monitoring/Favicon/Metro.unreadSFW.png","../src/Monitoring/Favicon/Metro.unreadSFWY.png","../src/Monitoring/Favicon/Metro.unreadNSFW.png","../src/Monitoring/Favicon/Metro.unreadNSFWY.png","../src/platform/$$.js","../src/Posting/Captcha.replace.js","../src/Posting/Captcha.t.js","../../../../src/platform/helpers.ts","../src/classes/DataBoard.js","../../../../src/classes/SimpleDict.ts","../src/classes/Thread.js","../src/classes/CatalogThread.js","../src/General/UI.js","../src/Miscellaneous/Nav.js","../src/Images/ImageHost.js","../src/Images/Volume.js","../src/Images/ImageCommon.js","../src/Images/ImageExpand.js","../../../../src/classes/Post.ts","../src/Menu/Menu.js","../src/Filtering/Recursive.js","../src/Filtering/PostHiding.js","../src/Miscellaneous/RelativeDates.js","../src/General/BoardConfig.js","../src/classes/Board.js","../src/Posting/PostRedirect.js","../src/Miscellaneous/ExpandComment.js","../src/Quotelinks/QuoteYou.js","../src/classes/RandomAccessList.js","../src/Monitoring/Unread.js","../src/Miscellaneous/ExpandThread.js","../src/Monitoring/UnreadIndex.js","../src/Monitoring/ThreadWatcher.js","../src/classes/Fetcher.js","../src/Quotelinks/QuotePreview.js","../src/General/Index.js","../src/Filtering/ThreadHiding.js","../../../../src/globals/jsx.ts","../../../../src/General/Settings/SettingsHtml.tsx","../../../../src/css/style.ts","../../../../src/css/CSS.ts","../src/css/linkify.audio.png","../src/css/linkify.bitchute.png","../src/css/linkify.clyp.png","../src/css/linkify.dailymotion.png","../src/css/linkify.gfycat.png","../src/css/linkify.gist.png","../src/css/linkify.image.png","../src/css/linkify.installgentoo.png","../src/css/linkify.liveleak.png","../src/css/linkify.pastebin.png","../src/css/linkify.peertube.png","../src/css/linkify.soundcloud.png","../src/css/linkify.streamable.png","../src/css/linkify.twitchtv.png","../src/css/linkify.twitter.png","../src/css/linkify.video.png","../src/css/linkify.vidlii.png","../src/css/linkify.vimeo.png","../src/css/linkify.vine.png","../src/css/linkify.vocaroo.png","../src/css/linkify.youtube.png","../src/Miscellaneous/CustomCSS.js","../src/site/SW.tinyboard.js","../../../../src/Miscellaneous/PassMessage/PassMessageHtml.tsx","../src/Miscellaneous/PassMessage.js","../src/Miscellaneous/Report.js","../src/Posting/PostSuccessful.js","../../../../src/site/SW.yotsuba.tsx","../../../../src/site/SW.yotsuba.Build/PostInfoHtml.tsx","../../../../src/site/SW.yotsuba.Build/FileHtml.tsx","../../../../src/site/SW.yotsuba.Build/CatalogThreadHtml.tsx","../src/site/SW.js","../../../../src/Miscellaneous/FileInfo.tsx","../src/Miscellaneous/Time.js","../src/Monitoring/ReplyPruning.js","../src/Quotelinks/QuoteThreading.js","../src/Monitoring/ThreadUpdater.js","../../../../src/General/Settings.tsx","../src/Images/FappeTyme.js","../src/Images/Sauce.js","../src/Images/Gallery.js","../src/Linkification/Embedding.js","../src/Miscellaneous/Keybinds.js","../src/Posting/Captcha.js","../src/Posting/QR.js","../src/platform/CrossOrigin.js","../src/platform/$.js","../src/General/Get.js","../../../../src/Filtering/Filter.ts","../src/site/Site.js","../src/Miscellaneous/CatalogLinks.js","../src/General/Header.js","../src/classes/Notice.js","../src/Archive/Redirect.js","../src/classes/CatalogThreadNative.js","../src/Filtering/Anonymize.js","../src/Images/ImageHover.js","../src/Images/ImageLoader.js","../src/Images/Metadata.js","../src/Images/RevealSpoilers.js","../src/Linkification/Linkify.js","../src/Menu/ArchiveLink.js","../src/Menu/CopyTextLink.js","../src/Menu/DeleteLink.js","../src/Menu/DownloadLink.js","../src/Menu/ReportLink.js","../src/Miscellaneous/AntiAutoplay.js","../src/Miscellaneous/Banner.js","../src/Miscellaneous/Flash.js","../src/Miscellaneous/Fourchan.js","../src/Miscellaneous/IDColor.js","../src/Miscellaneous/IDHighlight.js","../src/Miscellaneous/IDPostCount.js","../src/Miscellaneous/ModContact.js","../src/Miscellaneous/NormalizeURL.js","../src/Miscellaneous/PostJumper.js","../src/Miscellaneous/PSA.js","../src/Miscellaneous/PSAHiding.js","../src/Miscellaneous/RemoveSpoilers.js","../src/Miscellaneous/ThreadLinks.js","../src/Miscellaneous/Tinyboard.js","../src/Monitoring/MarkNewIPs.js","../src/Monitoring/ThreadStats.js","../src/Posting/PassLink.js","../src/Quotelinks/QuoteInline.js","../src/Quotelinks/QuoteBacklink.js","../src/Quotelinks/QuoteCT.js","../src/Quotelinks/QuoteOP.js","../src/Quotelinks/Quotify.js","../src/General/Polyfill.js","../src/main/Main.js","../src/Quotelinks/QuoteStrikeThrough.js"],"sourcesContent":[null,"import Main from \"../main/Main\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS206: Consider reworking classes to avoid initClass\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nexport default class Callbacks {\r\n static initClass() {\r\n this.Post = new Callbacks('Post');\r\n this.Thread = new Callbacks('Thread');\r\n this.CatalogThread = new Callbacks('Catalog Thread');\r\n this.CatalogThreadNative = new Callbacks('Catalog Thread');\r\n }\r\n\r\n constructor(type) {\r\n this.type = type;\r\n this.keys = [];\r\n }\r\n\r\n push({name, cb}) {\r\n if (!this[name]) { this.keys.push(name); }\r\n return this[name] = cb;\r\n }\r\n\r\n execute(node, keys=this.keys, force=false) {\r\n let errors;\r\n if (node.callbacksExecuted && !force) { return; }\r\n node.callbacksExecuted = true;\r\n for (var name of keys) {\r\n try {\r\n this[name]?.call(node);\r\n } catch (err) {\r\n if (!errors) { errors = []; }\r\n errors.push({\r\n message: ['\"', name, '\" crashed on node ', this.type, ' No.', node.ID, ' (', node.board, ').'].join(''),\r\n error: err,\r\n html: node.nodes?.root?.outerHTML\r\n });\r\n }\r\n }\r\n\r\n if (errors) { return Main.handleErrors(errors); }\r\n }\r\n}\r\nCallbacks.initClass();\r\n","import userCss from './user.css';\r\nimport banners from './banners.json';\r\nimport meta from '../../package.json';\r\n\r\nconst Config = {\r\n main: {\r\n 'Miscellaneous': {\r\n 'Redirect to HTTPS': [\r\n true,\r\n 'Redirect to the HTTPS version of 4chan.'\r\n ],\r\n 'JSON Index': [\r\n true,\r\n 'Replace the original board index with one supporting searching, sorting, infinite scrolling, and a catalog mode.'\r\n ],\r\n [`Use ${meta.name} Catalog`]: [\r\n true,\r\n `Link to ${meta.name}'s catalog instead of the native 4chan one.`,\r\n 1\r\n ],\r\n 'Index Refresh Notifications': [\r\n false,\r\n 'Show a notice at the top of the page when the index is refreshed.',\r\n 1\r\n ],\r\n 'Follow Cursor': [\r\n true,\r\n 'Image Hover and Quote Preview move with the mouse cursor.'\r\n ],\r\n 'Open Threads in New Tab': [\r\n false,\r\n `Make links to threads in the index / ${meta.name} catalog open in a new tab.`\r\n ],\r\n 'External Catalog': [\r\n false,\r\n 'Link to external catalog instead of the internal one.'\r\n ],\r\n 'Catalog Links': [\r\n false,\r\n 'Add toggle link in header menu to turn Navigation links into links to each board\\'s catalog.'\r\n ],\r\n 'Announcement Hiding': [\r\n true,\r\n 'Add button to hide 4chan announcements.'\r\n ],\r\n 'Desktop Notifications': [\r\n true,\r\n `Enables desktop notifications across various ${meta.name} features.`\r\n ],\r\n '404 Redirect': [\r\n true,\r\n 'Redirect dead threads and images to the archives.'\r\n ],\r\n 'Archive Report': [\r\n true,\r\n 'Enable reporting posts to supported archives.'\r\n ],\r\n 'Exempt Archives from Encryption': [\r\n true,\r\n 'Permit loading content from, and warningless redirects to, HTTP-only archives from HTTPS pages.'\r\n ],\r\n 'Keybinds': [\r\n true,\r\n 'Bind actions to keyboard shortcuts.'\r\n ],\r\n 'Time Formatting': [\r\n true,\r\n 'Localize and format timestamps.'\r\n ],\r\n 'Relative Post Dates': [\r\n true,\r\n 'Display dates like \"3 minutes ago\". Tooltip shows the timestamp.'\r\n ],\r\n 'Relative Date Title': [\r\n true,\r\n 'Show Relative Post Date only when hovering over dates.',\r\n 1\r\n ],\r\n 'Comment Expansion': [\r\n true,\r\n 'Expand comments that are too long to display on the index. Not applicable with JSON Index.'\r\n ],\r\n 'File Info Formatting': [\r\n true,\r\n 'Reformat the file information.'\r\n ],\r\n 'Thread Expansion': [\r\n true,\r\n 'Add buttons to expand threads.'\r\n ],\r\n 'Index Navigation': [\r\n false,\r\n 'Add buttons to navigate between threads.'\r\n ],\r\n 'Reply Navigation': [\r\n false,\r\n 'Add buttons to navigate to top / bottom of thread.'\r\n ],\r\n 'Unique ID and Capcode Navigation': [\r\n false,\r\n 'Add buttons to navigate to posts having the same unique ID or capcode.'\r\n ],\r\n 'Custom Board Titles': [\r\n true,\r\n 'Allow editing of the board title and subtitle by ctrl/\\u2318+clicking them.'\r\n ],\r\n 'Persistent Custom Board Titles': [\r\n false,\r\n 'Force custom board titles to be persistent, even if the board titles are updated.',\r\n 1\r\n ],\r\n 'Show Updated Notifications': [\r\n true,\r\n `Show notifications when ${meta.name} is successfully updated.`\r\n ],\r\n 'Color User IDs': [\r\n true,\r\n 'Assign unique colors to user IDs on boards that use them'\r\n ],\r\n 'Count Posts by ID': [\r\n true,\r\n 'Display number of posts in the thread when hovering over an ID.'\r\n ],\r\n 'Remove Spoilers': [\r\n false,\r\n 'Remove all spoilers in text.'\r\n ],\r\n 'Reveal Spoilers': [\r\n false,\r\n 'Indicate spoilers if Remove Spoilers is enabled, or make the text appear hovered if Remove Spoiler is disabled.'\r\n ],\r\n 'Normalize URL': [\r\n true,\r\n 'Rewrite the URL of the current page, removing slugs and excess slashes, and changing /res/ to /thread/.'\r\n ],\r\n 'Work around CORB Bug': [\r\n true,\r\n 'Leave this checked until your garbage browser is fixed.'\r\n ],\r\n 'Disable Autoplaying Sounds': [\r\n false,\r\n 'Prevent sounds on the page from autoplaying.'\r\n ],\r\n 'Disable Native Extension': [\r\n true,\r\n `${meta.name} is NOT designed to work with the native extension.`\r\n ],\r\n 'Enable Native Flash Embedding': [\r\n true,\r\n 'Activate the native extension\\'s Flash embedding if the native extension is disabled.'\r\n ]\r\n },\r\n\r\n 'Linkification': {\r\n 'Linkify': [\r\n true,\r\n 'Convert text into links where applicable.'\r\n ],\r\n 'Link Title': [\r\n true,\r\n 'Replace the link of a supported site with its actual title.',\r\n 1\r\n ],\r\n 'Cover Preview': [\r\n true,\r\n 'Show preview of supported links on hover.',\r\n 1\r\n ],\r\n 'Embedding': [\r\n true,\r\n 'Embed supported services. Note: Some services don\\'t work on HTTPS.',\r\n 1\r\n ],\r\n 'Auto-embed': [\r\n false,\r\n 'Auto-embed Linkify Embeds.',\r\n 2\r\n ],\r\n 'Floating Embeds': [\r\n false,\r\n 'Embed content in a frame that remains in place when the page is scrolled.',\r\n 2\r\n ]\r\n },\r\n\r\n 'Filtering': {\r\n 'Anonymize': [\r\n false,\r\n 'Make everyone Anonymous.'\r\n ],\r\n 'Filter': [\r\n true,\r\n 'Self-moderation placebo.'\r\n ],\r\n 'Filtered Backlinks': [\r\n false,\r\n 'When enabled, shows backlinks to filtered posts with a line-through decoration. Otherwise, hides the backlinks.',\r\n 1\r\n ],\r\n 'Filter in Native Catalog': [\r\n true,\r\n 'Apply 4chan X filters in native catalog.',\r\n 1\r\n ],\r\n 'MD5 Quick Filter Notifications': [\r\n true,\r\n 'Show notification when quick filtering MD5s using the button or keybind.',\r\n 1\r\n ],\r\n 'Recursive Hiding': [\r\n true,\r\n 'Hide replies of hidden posts, recursively.'\r\n ],\r\n 'Thread Hiding Buttons': [\r\n true,\r\n 'Add buttons to hide entire threads.'\r\n ],\r\n 'Reply Hiding Buttons': [\r\n true,\r\n 'Add buttons to hide single replies.'\r\n ],\r\n 'Stubs': [\r\n true,\r\n 'Show stubs of hidden threads / replies.'\r\n ]\r\n },\r\n\r\n 'Images and Videos': {\r\n 'Image Expansion': [\r\n true,\r\n 'Expand images / videos.'\r\n ],\r\n 'Image Hover': [\r\n true,\r\n 'Show full image / video on mouseover.'\r\n ],\r\n 'Image Hover in Catalog': [\r\n true,\r\n `Show full image / video on mouseover in ${meta.name} catalog.`\r\n ],\r\n 'Gallery': [\r\n true,\r\n 'Adds a simple and cute image gallery. Has more options in the gallery menu.'\r\n ],\r\n 'Fullscreen Gallery': [\r\n false,\r\n 'Open gallery in fullscreen mode.',\r\n 1\r\n ],\r\n 'PDF in Gallery': [\r\n false,\r\n 'Show PDF files in gallery.',\r\n 1\r\n ],\r\n 'Sauce': [\r\n true,\r\n 'Add sauce links to images.'\r\n ],\r\n 'WEBM Metadata': [\r\n true,\r\n 'Add link to fetch title metadata from webm videos.'\r\n ],\r\n 'Reveal Spoiler Thumbnails': [\r\n false,\r\n 'Replace spoiler thumbnails with the original image.'\r\n ],\r\n 'Replace GIF': [\r\n false,\r\n 'Replace gif thumbnails with the actual image.'\r\n ],\r\n 'Replace JPG': [\r\n false,\r\n 'Replace jpg thumbnails with the actual image.'\r\n ],\r\n 'Replace PNG': [\r\n false,\r\n 'Replace png thumbnails with the actual image.'\r\n ],\r\n 'Replace WEBM': [\r\n false,\r\n 'Replace webm, mp4, and ogv thumbnails with the actual video. Probably will degrade browser performance ;)'\r\n ],\r\n 'Image Prefetching': [\r\n true,\r\n 'Add a shortcut icon to the header to turn on image preloading.'\r\n ],\r\n 'Fappe Tyme': [\r\n true,\r\n 'Hide posts without images when header menu item is checked. *hint* *hint*'\r\n ],\r\n 'Werk Tyme': [\r\n true,\r\n 'Hide all post images when header menu item is checked.'\r\n ],\r\n 'Autoplay': [\r\n true,\r\n 'Videos begin playing immediately when opened.'\r\n ],\r\n 'Restart when Opened': [\r\n false,\r\n 'Restart GIFs and WebMs when you hover over or expand them.'\r\n ],\r\n 'Show Controls': [\r\n true,\r\n 'Show controls on videos expanded inline.'\r\n ],\r\n 'Click Passthrough': [\r\n false,\r\n 'Clicks on videos trigger your browser\\'s default behavior. Videos can be contracted with button / dragging to the left.',\r\n 1\r\n ],\r\n 'Allow Sound': [\r\n true,\r\n 'Open videos with the sound unmuted.'\r\n ],\r\n 'Mouse Wheel Volume': [\r\n true,\r\n 'Adjust volume of videos with the mouse wheel over the thumbnail/filename/gallery.'\r\n ],\r\n 'Loop in New Tab': [\r\n true,\r\n 'Loop videos opened in their own tabs.'\r\n ],\r\n 'Volume in New Tab': [\r\n true,\r\n `Apply ${meta.name} mute and volume settings to videos opened in their own tabs.`\r\n ]\r\n },\r\n\r\n 'Menu': {\r\n 'Menu': [\r\n true,\r\n 'Add a drop-down menu to posts.'\r\n ],\r\n 'Report Link': [\r\n true,\r\n 'Add a report link to the menu.',\r\n 1\r\n ],\r\n 'Copy Text Link': [\r\n true,\r\n 'Add a link to copy the post\\'s text.',\r\n 1\r\n ],\r\n 'Thread Hiding Link': [\r\n true,\r\n 'Add a link to hide entire threads.',\r\n 1\r\n ],\r\n 'Reply Hiding Link': [\r\n true,\r\n 'Add a link to hide single replies.',\r\n 1\r\n ],\r\n 'Delete Link': [\r\n true,\r\n 'Add post and image deletion links to the menu.',\r\n 1\r\n ],\r\n 'Archive Link': [\r\n true,\r\n 'Add an archive link to the menu.',\r\n 1\r\n ],\r\n 'Edit Link': [\r\n true,\r\n 'Add a link to edit the image in Tegaki, /i/\\'s painting program. Requires Quick Reply.',\r\n 1\r\n ],\r\n 'Download Link': [\r\n false,\r\n 'Add a download with original filename link to the menu.',\r\n 1\r\n ]\r\n },\r\n\r\n 'Monitoring': {\r\n 'Thread Updater': [\r\n true,\r\n 'Fetch and insert new replies. Has more options in the header menu and the \"Advanced\" tab.'\r\n ],\r\n 'Unread Count': [\r\n true,\r\n 'Show the unread posts count in the tab title.'\r\n ],\r\n 'Quoted Title': [\r\n false,\r\n 'Change the page title to reflect you\\'ve been quoted.',\r\n 1\r\n ],\r\n 'Hide Unread Count at (0)': [\r\n false,\r\n 'Hide the unread posts count in the tab title when it reaches 0.',\r\n 1\r\n ],\r\n 'Unread Favicon': [\r\n true,\r\n 'Show a different favicon when there are unread posts.'\r\n ],\r\n 'Unread Line': [\r\n true,\r\n 'Show a line to distinguish read posts from unread ones.'\r\n ],\r\n 'Remember Last Read Post': [\r\n true,\r\n 'Remember how far you\\'ve read after you close the thread.'\r\n ],\r\n 'Scroll to Last Read Post': [\r\n true,\r\n 'Scroll back to the last read post when reopening a thread.',\r\n 1\r\n ],\r\n 'Unread Line in Index': [\r\n false,\r\n 'Show a line between read and unread posts in threads in the index.',\r\n 1\r\n ],\r\n 'Remove Thread Excerpt': [\r\n false,\r\n 'Replace the excerpt of the thread in the tab title with the board title.'\r\n ],\r\n 'Thread Stats': [\r\n true,\r\n 'Display reply and image count.'\r\n ],\r\n 'IP Count in Stats': [\r\n true,\r\n 'Display the unique IP count in the thread stats.',\r\n 1\r\n ],\r\n 'Page Count in Stats': [\r\n true,\r\n 'Display the page count in the thread stats.',\r\n 1\r\n ],\r\n 'Updater and Stats in Header': [\r\n true,\r\n 'Places the thread updater and thread stats in the header instead of floating them.'\r\n ],\r\n 'Thread Watcher': [\r\n true,\r\n 'Bookmark threads. Has more options in the thread watcher menu.'\r\n ],\r\n 'Fixed Thread Watcher': [\r\n true,\r\n 'Makes the thread watcher scroll with the page.',\r\n 1\r\n ],\r\n 'Persistent Thread Watcher': [\r\n false,\r\n 'The thread watcher will be visible when the page is loaded.',\r\n 1\r\n ],\r\n 'Mark New IPs': [\r\n false,\r\n 'Label each post from a new IP with the thread\\'s current IP count.'\r\n ],\r\n 'Reply Pruning': [\r\n true,\r\n 'Add option in header menu to hide old replies in long threads. Activated by default in stickies.'\r\n ],\r\n 'Prune All Threads': [\r\n false,\r\n 'Activate Reply Pruning by default in all threads.',\r\n 1\r\n ]\r\n },\r\n\r\n 'Posting and Captchas': {\r\n 'Quick Reply': [\r\n true,\r\n 'All-in-one form to reply, create threads, automate dumping and more.'\r\n ],\r\n 'Persistent QR': [\r\n false,\r\n 'The Quick reply won\\'t disappear after posting.',\r\n 1\r\n ],\r\n 'Auto Hide QR': [\r\n true,\r\n 'Automatically hide the quick reply when posting.',\r\n 2\r\n ],\r\n 'Open Post in New Tab': [\r\n true,\r\n 'Open new threads in a new tab, and open replies in a new tab if you\\'re not already in the thread.',\r\n 1\r\n ],\r\n 'Remember QR Size': [\r\n false,\r\n 'Remember the size of the Quick reply.',\r\n 1\r\n ],\r\n 'Remember Spoiler': [\r\n false,\r\n 'Remember the spoiler state, instead of resetting after posting.',\r\n 1\r\n ],\r\n 'Randomize Filename': [\r\n false,\r\n 'Set the filename to a random timestamp within the past year. Disabled on /f/.',\r\n 1\r\n ],\r\n 'Show New Thread Option in Threads': [\r\n true,\r\n 'Show the option to post a new / different thread from inside a thread.',\r\n 1\r\n ],\r\n 'Show Upload Progress': [\r\n true,\r\n 'Track progress of file uploads as percentage in submit button.',\r\n 1\r\n ],\r\n 'Cooldown': [\r\n true,\r\n 'Indicate the remaining time before posting again.',\r\n 1\r\n ],\r\n 'Posting Success Notifications': [\r\n true,\r\n 'Show notifications on successful post creation or file uploading.',\r\n 1\r\n ],\r\n 'Auto-load captcha': [\r\n false,\r\n 'Automatically load the captcha in the QR even if your post is empty.',\r\n 1\r\n ],\r\n 'Post on Captcha Completion': [\r\n false,\r\n 'Submit the post immediately when the captcha is completed.',\r\n 1\r\n ],\r\n 'Force Noscript Captcha': [\r\n false,\r\n 'Use the non-Javascript fallback captcha even if Javascript is enabled.'\r\n ],\r\n 'Pass Link': [\r\n false,\r\n 'Add a 4chan Pass login link to the bottom of the page.'\r\n ]\r\n },\r\n\r\n 'Quote Links': {\r\n 'Quote Backlinks': [\r\n true,\r\n 'Add quote backlinks.'\r\n ],\r\n 'OP Backlinks': [\r\n true,\r\n 'Add backlinks to the OP.',\r\n 1\r\n ],\r\n 'Bottom Backlinks': [\r\n false,\r\n 'Place backlinks at the bottom of posts.',\r\n 1\r\n ],\r\n 'Quote Inlining': [\r\n true,\r\n 'Inline quoted post on click.'\r\n ],\r\n 'Inline Cross-thread Quotes Only': [\r\n false,\r\n 'Don\\'t inline quote links when the posts are visible in the thread.',\r\n 1\r\n ],\r\n 'Quote Hash Navigation': [\r\n false,\r\n 'Include an extra link after quotes for autoscrolling to quoted posts.',\r\n 1\r\n ],\r\n 'Forward Hiding': [\r\n true,\r\n 'Hide original posts of inlined backlinks.',\r\n 1\r\n ],\r\n 'Quote Previewing': [\r\n true,\r\n 'Show quoted post on hover.'\r\n ],\r\n 'Quote Highlighting': [\r\n true,\r\n 'Highlight the previewed post.',\r\n 1\r\n ],\r\n 'Resurrect Quotes': [\r\n true,\r\n 'Link dead quotes to the archives, and support inlining/previewing of archive links like quote links.'\r\n ],\r\n 'Remember Your Posts': [\r\n true,\r\n 'Remember your posting history.'\r\n ],\r\n 'Mark Quotes of You': [\r\n true,\r\n 'Add \\'(You)\\' to quotes linking to your posts.',\r\n 1\r\n ],\r\n 'Highlight Posts Quoting You': [\r\n true,\r\n 'Highlights any posts that contain a quote to your post.',\r\n 1\r\n ],\r\n 'Highlight Own Posts': [\r\n true,\r\n 'Highlights own posts.',\r\n 1\r\n ],\r\n 'Mark OP Quotes': [\r\n true,\r\n 'Add \\'(OP)\\' to OP quotes.'\r\n ],\r\n 'Mark Cross-thread Quotes': [\r\n true,\r\n 'Add \\'(Cross-thread)\\' to cross-threads quotes.'\r\n ],\r\n 'Quote Threading': [\r\n true,\r\n 'Add option in header menu to thread conversations.'\r\n ]\r\n }\r\n },\r\n\r\n imageExpansion: {\r\n 'Fit width': [\r\n true,\r\n ''\r\n ],\r\n 'Fit height': [\r\n false,\r\n ''\r\n ],\r\n 'Scroll into view': [\r\n true,\r\n 'Scroll down when expanding images to bring the full image into view.'\r\n ],\r\n 'Expand spoilers': [\r\n true,\r\n 'Expand all images along with spoilers.'\r\n ],\r\n 'Expand videos': [\r\n true,\r\n 'Expand all images also expands videos.'\r\n ],\r\n 'Expand from here': [\r\n false,\r\n 'Expand all images only from current position to thread end.'\r\n ],\r\n 'Expand thread only': [\r\n false,\r\n 'In index, expand all images only within the current thread.'\r\n ],\r\n 'Advance on contract': [\r\n false,\r\n 'Advance to next post when contracting an expanded image.'\r\n ]\r\n },\r\n\r\n gallery: {\r\n 'Hide Thumbnails': [\r\n false\r\n ],\r\n 'Fit Width': [ // 'Fit width' (lowercase W) belongs to Image Expansion. Engine limitations, heh.\r\n true\r\n ],\r\n 'Fit Height': [\r\n true\r\n ],\r\n 'Stretch to Fit': [\r\n false\r\n ],\r\n 'Scroll to Post': [\r\n true\r\n ],\r\n 'Slide Delay': [\r\n 6.0\r\n ]\r\n },\r\n\r\n 'Default Volume': 1.0,\r\n\r\n threadWatcher: {\r\n 'Current Board': [\r\n false,\r\n 'Only show watched threads from the current board.'\r\n ],\r\n 'Auto Update Thread Watcher': [\r\n true,\r\n 'Periodically check status of watched threads.'\r\n ],\r\n 'Auto Watch': [\r\n true,\r\n 'Automatically watch threads you start.'\r\n ],\r\n 'Auto Watch Reply': [\r\n true,\r\n 'Automatically watch threads you reply to.'\r\n ],\r\n 'Auto Prune': [\r\n false,\r\n 'Automatically remove dead threads.'\r\n ],\r\n 'Show Page': [\r\n true,\r\n 'Show what page watched threads are on.'\r\n ],\r\n 'Show Unread Count': [\r\n true,\r\n 'Show number of unread posts in watched threads.'\r\n ],\r\n 'Show Site Prefix': [\r\n true,\r\n 'When multiple sites are shown in the thread watcher, add a prefix to board names to distinguish them.'\r\n ],\r\n 'Require OP Quote Link': [\r\n false,\r\n 'For purposes of thread watcher highlighting, only consider posts with a quote link to the OP as replies to the OP.'\r\n ]\r\n },\r\n\r\n filter: {\r\n general: '',\r\n\r\n postID: `\\\r\n# Highlight dubs on [s4s]:\r\n#/(\\\\d)\\\\1$/;highlight;top:no;boards:s4s\\\r\n`,\r\n\r\n name: `\\\r\n# Filter any namefags:\r\n#/^(?!Anonymous$)/\\\r\n`,\r\n\r\n uniqueID: `\\\r\n# Filter a specific ID:\r\n#/Txhvk1Tl/\\\r\n`,\r\n\r\n tripcode: `\\\r\n# Filter any tripfag\r\n#/^!/\\\r\n`,\r\n\r\n capcode: `\\\r\n# Set a custom class for mods:\r\n#/Mod$/;highlight:mod;op:yes\r\n# Set a custom class for admins:\r\n#/Admin$/;highlight:admin;op:yes\\\r\n`,\r\n\r\n pass: `\\\r\n# Filter anyone using since4pass:\r\n#/./\\\r\n`,\r\n\r\n email: '',\r\n\r\n subject: `\\\r\n# Filter Generals on /v/:\r\n#/general/i;boards:v;op:only\\\r\n`,\r\n\r\n comment: `\\\r\n# Filter Stallman copypasta on /g/:\r\n#/what you\\'re refer+ing to as linux/i;boards:g\r\n# Filter posts with 20 or more quote links:\r\n#/(?:>>\\\\d(?:(?!>>\\\\d)[^])*){20}/\r\n# Filter posts like T H I S / H / I / S:\r\n#/^>?\\\\s?\\\\w\\\\s?(\\\\w)\\\\s?(\\\\w)\\\\s?(\\\\w).*$[\\\\s>]+\\\\1[\\\\s>]+\\\\2[\\\\s>]+\\\\3/im\\\r\n`,\r\n\r\n flag: '',\r\n filename: '',\r\n dimensions: `\\\r\n# Highlight potential wallpapers:\r\n#/1920x1080/;op:yes;highlight;top:no;boards:w,wg\\\r\n`,\r\n\r\n filesize: '',\r\n\r\n MD5: ''\r\n },\r\n\r\n sauces: `\\\r\n# Known filename formats:\r\nhttps://www.pixiv.net/member_illust.php?mode=medium&illust_id=%$1;regexp:/^(\\\\d+)_p\\\\d+/\r\njavascript:void(open(\"https://www.deviantart.com/\"+%$1.replace(/_/g,\"-\")+\"/art/\"+parseInt(%$2,36)));regexp:/^\\\\w+_by_(\\\\w+)[_-]d([\\\\da-z]{6})\\\\b/\r\nhttps://imgur.com/%$1;regexp:/^(?![a-zA-Z][a-z]{6})(?![A-Z]{7})(?!\\\\d{7})([\\\\da-zA-Z]{7})(?: \\\\(\\\\d+\\\\))?\\\\.\\\\w+$/\r\nhttps://flickr.com/photo.gne?id=%$1;regexp:/^(\\\\d+)_[\\\\da-f]{10}(?:_\\\\w)*\\\\b/\r\nhttps://www.facebook.com/photo.php?fbid=%$1;regexp:/^\\\\d+_(\\\\d+)_\\\\d+_[no]\\\\b/\r\n\r\n# Reverse image search:\r\nhttps://www.google.com/searchbyimage?sbisrc=4chanx&image_url=%IMG&safe=off\r\nhttps://yandex.com/images/search?rpt=imageview&url=%IMG\r\n#//tineye.com/search?url=%IMG\r\n#//www.bing.com/images/search?q=imgurl:%IMG&view=detailv2&iss=sbi#enterInsights\r\n#https://lens.google.com/uploadbyurl?url=%IMG;text:lens\r\n\r\n# Specialized reverse image search:\r\n//iqdb.org/?url=%IMG\r\nhttps://trace.moe/?auto&url=%IMG;text:wait\r\n#//3d.iqdb.org/?url=%IMG\r\n#//saucenao.com/search.php?url=%IMG\r\n\r\n# \"View Same\" in archives:\r\nhttp://eye.swfchan.com/search/?q=%name;types:swf\r\n#https://desuarchive.org/_/search/image/%sMD5/\r\n#https://archive.4plebs.org/_/search/image/%sMD5/\r\n#https://boards.fireden.net/_/search/image/%sMD5/\r\n#https://foolz.fireden.net/_/search/image/%sMD5/\r\n\r\n# Other tools:\r\n#http://exif.regex.info/exif.cgi?imgurl=%URL\r\n#//imgops.com/start?url=%URL;types:gif,jpg,png\r\n#//www.gif-explode.com/%URL;types:gif\\\r\n`,\r\n\r\n FappeT: {\r\n werk: false\r\n },\r\n\r\n 'Custom CSS': true,\r\n\r\n Index: {\r\n 'Index Mode': 'paged',\r\n 'Previous Index Mode': 'paged',\r\n 'Index Size': 'small',\r\n 'Show Replies': [true, 'Show replies in the index, and also in the catalog if \"Catalog hover expand\" is checked.'],\r\n 'Catalog Hover Expand': [false, 'Expand the comment and show more details when you hover over a thread in the catalog.'],\r\n 'Catalog Hover Toggle': [true, 'Turn \"Catalog hover expand\" on and off by clicking in the catalog.'],\r\n 'Pin Watched Threads': [false, 'Move watched threads to the start of the index.'],\r\n 'Anchor Hidden Threads': [true, 'Move hidden threads to the end of the index.'],\r\n 'Refreshed Navigation': [false, 'Refresh index when navigating through pages.']\r\n },\r\n\r\n Header: {\r\n 'Fixed Header': true,\r\n 'Header auto-hide': false,\r\n 'Header auto-hide on scroll': false,\r\n 'Bottom Header': false,\r\n 'Centered links': false,\r\n 'Header catalog links': false,\r\n 'Bottom Board List': true,\r\n 'Shortcut Icons': true,\r\n 'Custom Board Navigation': true\r\n },\r\n\r\n archives: {\r\n archiveLists: 'https://4chenz.github.io/archives.json/archives.json',\r\n lastarchivecheck: 0,\r\n archiveAutoUpdate: true\r\n },\r\n\r\n externalCatalogURLs: `\\\r\n//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\\\r\n`,\r\n\r\n boardnav: `\\\r\n[ toggle-all ]\r\n[current-index-text:\"Index\"\r\ncurrent-catalog-text:\"Catalog\"\r\ncurrent-expired-text:\"Expired\"\r\ncurrent-archive-text:\"Archive\"]\r\n[external-text:\"FAQ\",\"${meta.name}\"]\\\r\n`,\r\n\r\n QR: {\r\n 'QR.personas': `\\\r\n#options:\"sage\";boards:jp;always\\\r\n`,\r\n sjisPreview: false\r\n },\r\n\r\n jsWhitelist: `\\\r\nhttp://s.4cdn.org\r\nhttps://s.4cdn.org\r\nhttp://www.google.com\r\nhttps://www.google.com\r\nhttps://www.gstatic.com\r\nhttp://cdn.mathjax.org\r\nhttps://cdn.mathjax.org\r\nhttps://cdnjs.cloudflare.com\r\nhttps://hcaptcha.com\r\nhttps://*.hcaptcha.com\r\n'self'\r\n'unsafe-inline'\r\n'unsafe-eval'\\\r\n`,\r\n\r\n captchaLanguage: '',\r\n\r\n time: '%m/%d/%y(%a)%H:%M:%S',\r\n timeLocale: '',\r\n\r\n backlink: '>>%id',\r\n\r\n pastedname: 'file',\r\n\r\n fileInfo: '%l %d (%p%s, %r%g)',\r\n\r\n favicon: 'ferongr',\r\n\r\n usercss: userCss,\r\n\r\n hotkeys: {\r\n // QR & Options\r\n 'Toggle board list': [\r\n 'Ctrl+b',\r\n 'Toggle the full board list.'\r\n ],\r\n 'Toggle header': [\r\n 'Shift+h',\r\n 'Toggle the auto-hide option of the header.'\r\n ],\r\n 'Open empty QR': [\r\n 'q',\r\n 'Open QR without post number inserted.'\r\n ],\r\n 'Open QR': [\r\n 'Shift+q',\r\n 'Open QR with post number inserted.'\r\n ],\r\n 'Open settings': [\r\n 'Alt+o',\r\n 'Open Settings.'\r\n ],\r\n 'Close': [\r\n 'Esc',\r\n 'Close dialogs or notifications.'\r\n ],\r\n 'Spoiler tags': [\r\n 'Ctrl+s',\r\n 'Insert spoiler tags.'\r\n ],\r\n 'Code tags': [\r\n 'Alt+c',\r\n 'Insert code tags.'\r\n ],\r\n 'Eqn tags': [\r\n 'Alt+e',\r\n 'Insert eqn tags.'\r\n ],\r\n 'Math tags': [\r\n 'Alt+m',\r\n 'Insert math tags.'\r\n ],\r\n 'SJIS tags': [\r\n 'Alt+a',\r\n 'Insert SJIS tags.'\r\n ],\r\n 'Toggle sage': [\r\n 'Alt+s',\r\n 'Toggle sage in options field.'\r\n ],\r\n 'Toggle Cooldown': [\r\n 'Alt+Comma',\r\n 'Toggle custom cooldown timer.'\r\n ],\r\n 'Post from URL': [\r\n 'Alt+l',\r\n 'Post from URL.'\r\n ],\r\n 'Add new post': [\r\n 'Alt+n',\r\n 'Add new post to the QR dump list.'\r\n ],\r\n 'Submit QR': [\r\n 'Ctrl+Enter',\r\n 'Submit post.'\r\n ],\r\n // Thread related\r\n 'Watch': [\r\n 'w',\r\n 'Watch thread.'\r\n ],\r\n 'Update': [\r\n 'r',\r\n 'Update the thread / refresh the index.'\r\n ],\r\n 'Update thread watcher': [\r\n 'Shift+r',\r\n 'Manually refresh thread watcher.'\r\n ],\r\n 'Toggle thread watcher': [\r\n 't',\r\n 'Toggle visibility of thread watcher.'\r\n ],\r\n 'Toggle threading': [\r\n 'Shift+t',\r\n 'Toggle threading.'\r\n ],\r\n 'Mark thread read': [\r\n 'Ctrl+0',\r\n 'Mark thread read from index (requires \"Unread Line in Index\").'\r\n ],\r\n // Images\r\n 'Expand image': [\r\n 'Shift+e',\r\n 'Expand selected image.'\r\n ],\r\n 'Expand images': [\r\n 'e',\r\n 'Expand all images.'\r\n ],\r\n 'Open Gallery': [\r\n 'g',\r\n 'Opens the gallery.'\r\n ],\r\n 'Next Gallery Image': [\r\n 'Right',\r\n 'Go to the next image in gallery mode.'\r\n ],\r\n 'Previous Gallery Image': [\r\n 'Left',\r\n 'Go to the previous image in gallery mode.'\r\n ],\r\n 'Advance Gallery': [\r\n 'Enter',\r\n 'Go to next image or, if Autoplay is off, play video.'\r\n ],\r\n 'Pause': [\r\n 'p',\r\n 'Pause/play videos in the gallery.'\r\n ],\r\n 'Slideshow': [\r\n 'Ctrl+Right',\r\n 'Toggle the gallery slideshow mode.'\r\n ],\r\n 'Rotate image clockwise': [\r\n 'Shift+Right',\r\n 'Rotate image clockwise in gallery.'\r\n ],\r\n 'Rotate image anticlockwise': [\r\n 'Shift+Left',\r\n 'Rotate image anticlockwise in gallery.'\r\n ],\r\n 'Download Gallery Image': [\r\n 'Shift+j',\r\n 'Download current image in gallery.'\r\n ],\r\n 'fappeTyme': [\r\n 'f',\r\n 'Toggle Fappe Tyme.'\r\n ],\r\n 'werkTyme': [\r\n 'Shift+w',\r\n 'Toggle Werk Tyme.'\r\n ],\r\n // Board Navigation\r\n 'Front page': [\r\n '1',\r\n 'Jump to front page.'\r\n ],\r\n 'Open front page': [\r\n 'Shift+1',\r\n 'Open front page in a new tab.'\r\n ],\r\n 'Next page': [\r\n 'Ctrl+Right',\r\n 'Jump to the next page.'\r\n ],\r\n 'Previous page': [\r\n 'Ctrl+Left',\r\n 'Jump to the previous page.'\r\n ],\r\n 'Paged mode': [\r\n 'Alt+1',\r\n 'Open the index in paged mode.'\r\n ],\r\n 'Infinite scrolling mode': [\r\n 'Alt+2',\r\n 'Open the index in infinite scrolling mode.'\r\n ],\r\n 'All pages mode': [\r\n 'Alt+3',\r\n 'Open the index in all threads mode.'\r\n ],\r\n 'Open catalog': [\r\n 'Shift+c',\r\n 'Open the catalog of the current board.'\r\n ],\r\n 'Search form': [\r\n 'Ctrl+Alt+s',\r\n 'Focus the search field on the board index.'\r\n ],\r\n 'Cycle sort type': [\r\n 'Alt+x',\r\n 'Cycle through index sort types.'\r\n ],\r\n // Thread Navigation\r\n 'Next thread': [\r\n 'Ctrl+Down',\r\n 'See next thread.'\r\n ],\r\n 'Previous thread': [\r\n 'Ctrl+Up',\r\n 'See previous thread.'\r\n ],\r\n 'Expand thread': [\r\n 'Ctrl+e',\r\n 'Expand thread.'\r\n ],\r\n 'Open thread': [\r\n 'o',\r\n 'Open thread in current tab.'\r\n ],\r\n 'Open thread tab': [\r\n 'Shift+o',\r\n 'Open thread in new tab.'\r\n ],\r\n // Reply Navigation\r\n 'Next reply': [\r\n 'j',\r\n 'Select next reply.'\r\n ],\r\n 'Previous reply': [\r\n 'k',\r\n 'Select previous reply.'\r\n ],\r\n 'Deselect reply': [\r\n 'Shift+d',\r\n 'Deselect reply.'\r\n ],\r\n 'Hide': [\r\n 'x',\r\n 'Hide thread.'\r\n ],\r\n 'Quick Filter MD5': [\r\n '5',\r\n 'Add the MD5 of the selected image to the filter list.'\r\n ],\r\n 'Previous Post Quoting You': [\r\n 'Alt+Up',\r\n 'Scroll to the previous post that quotes you.'\r\n ],\r\n 'Next Post Quoting You': [\r\n 'Alt+Down',\r\n 'Scroll to the next post that quotes you.'\r\n ]\r\n },\r\n\r\n updater: {\r\n checkbox: {\r\n 'Beep': [\r\n false,\r\n 'Beep on new post to completely read thread.'\r\n ],\r\n 'Beep Quoting You': [\r\n false,\r\n 'Beep on new post quoting you.'\r\n ],\r\n 'Auto Scroll': [\r\n false,\r\n 'Scroll updated posts into view. Only enabled at bottom of page.'\r\n ],\r\n 'Bottom Scroll': [\r\n false,\r\n 'Always scroll to the bottom, not the first new post. Useful for event threads.'\r\n ],\r\n 'Scroll BG': [\r\n false,\r\n 'Auto-scroll background tabs.'\r\n ],\r\n 'Auto Update': [\r\n true,\r\n 'Automatically fetch new posts.'\r\n ],\r\n 'Optional Increase': [\r\n false,\r\n 'Increase the intervals between updates on threads without new posts.'\r\n ]\r\n },\r\n 'Interval': 5\r\n },\r\n\r\n customCooldown: 0,\r\n customCooldownEnabled: true,\r\n\r\n 'Thread Quotes': false,\r\n\r\n 'Max Replies': 1000,\r\n\r\n 'Autohiding Scrollbar': false,\r\n\r\n position: {\r\n 'embedding.position': 'top: 50px; right: 0px;',\r\n 'thread-stats.position': 'bottom: 0px; right: 0px;',\r\n 'updater.position': 'bottom: 0px; left: 0px;',\r\n 'thread-watcher.position': 'top: 50px; left: 0px;',\r\n 'qr.position': 'top: 50px; right: 0px;'\r\n },\r\n\r\n fourchanImageHost: 'i.4cdn.org',\r\n\r\n hiddenPSAList: [{}],\r\n\r\n knownBanners: banners.join(','),\r\n\r\n passMessageClosed: false,\r\n\r\n 'Prerequest Captcha': false,\r\n\r\n 'PSAseen': [[]]\r\n};\r\nexport default Config;\r\n","import ferongr_unreadDead from './Favicon/ferongr.unreadDead.png';\r\nimport ferongr_unreadDeadY from './Favicon/ferongr.unreadDeadY.png';\r\nimport ferongr_unreadSFW from './Favicon/ferongr.unreadSFW.png';\r\nimport ferongr_unreadSFWY from './Favicon/ferongr.unreadSFWY.png';\r\nimport ferongr_unreadNSFW from './Favicon/ferongr.unreadNSFW.png';\r\nimport ferongr_unreadNSFWY from './Favicon/ferongr.unreadNSFWY.png';\r\nimport xat_unreadDead from './Favicon/xat-.unreadDead.png';\r\nimport xat_unreadDeadY from './Favicon/xat-.unreadDeadY.png';\r\nimport xat_unreadSFW from './Favicon/xat-.unreadSFW.png';\r\nimport xat_unreadSFWY from './Favicon/xat-.unreadSFWY.png';\r\nimport xat_unreadNSFW from './Favicon/xat-.unreadNSFW.png';\r\nimport xat_unreadNSFWY from './Favicon/xat-.unreadNSFWY.png';\r\nimport Mayhem_unreadDead from './Favicon/Mayhem.unreadDead.png';\r\nimport Mayhem_unreadDeadY from './Favicon/Mayhem.unreadDeadY.png';\r\nimport Mayhem_unreadSFW from './Favicon/Mayhem.unreadSFW.png';\r\nimport Mayhem_unreadSFWY from './Favicon/Mayhem.unreadSFWY.png';\r\nimport Mayhem_unreadNSFW from './Favicon/Mayhem.unreadNSFW.png';\r\nimport Mayhem_unreadNSFWY from './Favicon/Mayhem.unreadNSFWY.png';\r\nimport fourChanJS_unreadDead from './Favicon/4chanJS.unreadDead.png';\r\nimport fourChanJS_unreadDeadY from './Favicon/4chanJS.unreadDeadY.png';\r\nimport fourChanJS_unreadSFW from './Favicon/4chanJS.unreadSFW.png';\r\nimport fourChanJS_unreadSFWY from './Favicon/4chanJS.unreadSFWY.png';\r\nimport fourChanJS_unreadNSFW from './Favicon/4chanJS.unreadNSFW.png';\r\nimport fourChanJS_unreadNSFWY from './Favicon/4chanJS.unreadNSFWY.png';\r\nimport Original_unreadDead from './Favicon/Original.unreadDead.png';\r\nimport Original_unreadDeadY from './Favicon/Original.unreadDeadY.png';\r\nimport Original_unreadSFW from './Favicon/Original.unreadSFW.png';\r\nimport Original_unreadSFWY from './Favicon/Original.unreadSFWY.png';\r\nimport Original_unreadNSFW from './Favicon/Original.unreadNSFW.png';\r\nimport Original_unreadNSFWY from './Favicon/Original.unreadNSFWY.png';\r\nimport Metro_unreadDead from './Favicon/Metro.unreadDead.png';\r\nimport Metro_unreadDeadY from './Favicon/Metro.unreadDeadY.png';\r\nimport Metro_unreadSFW from './Favicon/Metro.unreadSFW.png';\r\nimport Metro_unreadSFWY from './Favicon/Metro.unreadSFWY.png';\r\nimport Metro_unreadNSFW from './Favicon/Metro.unreadNSFW.png';\r\nimport Metro_unreadNSFWY from './Favicon/Metro.unreadNSFWY.png';\r\nimport dead from './Favicon/dead.gif';\r\nimport empty from './Favicon/empty.gif';\r\nimport $ from '../platform/$';\r\nimport { Conf, d } from '../globals/globals';\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\n\r\nvar Favicon = {\r\n init() {\r\n return $.asap((() => d.head && (Favicon.el = $('link[rel=\"shortcut icon\"]', d.head))), Favicon.initAsap);\r\n },\r\n\r\n set(status) {\r\n Favicon.status = status;\r\n if (Favicon.el) {\r\n Favicon.el.href = Favicon[status];\r\n // `favicon.href = href` doesn't work on Firefox.\r\n return $.add(d.head, Favicon.el);\r\n }\r\n },\r\n\r\n initAsap() {\r\n Favicon.el.type = 'image/x-icon';\r\n const {href} = Favicon.el;\r\n Favicon.isSFW = /ws\\.ico$/.test(href);\r\n Favicon.default = href;\r\n Favicon.switch();\r\n if (Favicon.status) {\r\n return Favicon.set(Favicon.status);\r\n }\r\n },\r\n\r\n switch() {\r\n let items = {\r\n ferongr: [\r\n ferongr_unreadDead,\r\n ferongr_unreadDeadY,\r\n ferongr_unreadSFW,\r\n ferongr_unreadSFWY,\r\n ferongr_unreadNSFW,\r\n ferongr_unreadNSFWY,\r\n ],\r\n 'xat-': [\r\n xat_unreadDead,\r\n xat_unreadDeadY,\r\n xat_unreadSFW,\r\n xat_unreadSFWY,\r\n xat_unreadNSFW,\r\n xat_unreadNSFWY,\r\n ],\r\n Mayhem: [\r\n Mayhem_unreadDead,\r\n Mayhem_unreadDeadY,\r\n Mayhem_unreadSFW,\r\n Mayhem_unreadSFWY,\r\n Mayhem_unreadNSFW,\r\n Mayhem_unreadNSFWY,\r\n ],\r\n '4chanJS': [\r\n fourChanJS_unreadDead,\r\n fourChanJS_unreadDeadY,\r\n fourChanJS_unreadSFW,\r\n fourChanJS_unreadSFWY,\r\n fourChanJS_unreadNSFW,\r\n fourChanJS_unreadNSFWY,\r\n ],\r\n Original: [\r\n Original_unreadDead,\r\n Original_unreadDeadY,\r\n Original_unreadSFW,\r\n Original_unreadSFWY,\r\n Original_unreadNSFW,\r\n Original_unreadNSFWY,\r\n ],\r\n 'Metro': [\r\n Metro_unreadDead,\r\n Metro_unreadDeadY,\r\n Metro_unreadSFW,\r\n Metro_unreadSFWY,\r\n Metro_unreadNSFW,\r\n Metro_unreadNSFWY,\r\n ]\r\n };\r\n items = $.getOwn(items, Conf['favicon']);\r\n\r\n const f = Favicon;\r\n const t = 'data:image/png;base64,';\r\n let i = 0;\r\n while (items[i]) {\r\n items[i] = t + items[i++];\r\n }\r\n\r\n [f.unreadDead, f.unreadDeadY, f.unreadSFW, f.unreadSFWY, f.unreadNSFW, f.unreadNSFWY] = Array.from(items);\r\n return f.update();\r\n },\r\n\r\n update() {\r\n if (this.isSFW) {\r\n this.unread = this.unreadSFW;\r\n return this.unreadY = this.unreadSFWY;\r\n } else {\r\n this.unread = this.unreadNSFW;\r\n return this.unreadY = this.unreadNSFWY;\r\n }\r\n },\r\n\r\n SFW: '//s.4cdn.org/image/favicon-ws.ico',\r\n NSFW: '//s.4cdn.org/image/favicon.ico',\r\n dead: `data:image/gif;base64,${dead}`,\r\n logo: `data:image/png;base64,${empty}`,\r\n};\r\nexport default Favicon;\r\n","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///9zBQC/AADpDAP/gID/q6voCwJJTwpOAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxUlEQVR42q1TOwrCQBB9s0FRtJI0WoqFtSLYegoP4gVSeJsUHsHSI3iFeIqRXXgwrhlXwYHHhLwPTB7B36abBCV+0pA4DUBQUNZYQptGtW3jtoKyxgoe0yrBCoyZfL/5ioQ3URZOXW9I341l3oo+NXEZiW4CEuIzvPECopED4OaZ3RNmeAm4u+a8Jr5f17VyVoL8fr8qcltzwlyyj2iqcgPOQ9ExkHAITgD75bYBe0A5S4H/P9htuWMF3QXoQpwaKeT+lnsC6JE5I6aq6fEAAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///8AcH4AtswA2PJ55fKi6fIA1/FtpPADAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxElEQVQ4y2NgoBq4/vE/HJOsBiRQUIfA2AzBqQYqUfn00/9FLz+BaQxDCKqBmX7jExijKEDSDJPHrnnbGQhGV4RmOFwdVkNwhQMheYwQxhaIi7b9Z9A3gWAQm2BUoQOgRhgA8o7j1ozLC4LCyAZcx6kZI5qg4kLKqggDFFWxJySsUQVzlb4pwgAJaTRvokcVNgOqOv8zcHBCsL07DgNg8YsczzA5MxtUL+DMD8g0slxI/H8GQ/P/DJKyeKIRpglXZsIiBwBhP5O+VbI/JgAAAABJRU5ErkJggg==';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///8oeQBJ3ABV/wHM/7Lu/+ZU/gAqUP3dAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAx0lEQVQ4y2NgoBYI+cfwH4ZJVgMS0KhEYGyG4FQDkzjzf9P/d/+fgWl0QwiqgSkI/c8IxsgKkDXD5LFq9rwDweiK0A2HqcNqCK5wICSPEcLYAtH+AMN/IXMIBrEJRie6OEgjDAC5x3FqxuUFNiEUA67j1IweTTBxBQ1puAG86jgSEraogskJWSBcwCGF5k30qMJmgMFEhv/MXBAs5oLDAFj8IsczTE7UEeECbhU8+QGZRpaTi2b4L2zF8J9TGk80wjThykzY5AAW/2O1C2mIbgAAAABJRU5ErkJggg==';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAG1BMVEX+AACLkZFub2yfaF3zZGIAAAD/AAD/iYr/zs8IPcF6AAAABXRSTlMAeprJ7xzg6IEAAABZSURBVAjXY2DABKGBSkqioQwMrGmpxsZhaQEMDGFpIa5pqSCRtPDSNJBIaGh5eShQDYOye0V7iREKAyQFYoiCFAcyILQDGcGmEEZYkGoqiMHKysAQEICwGwAAjBmBqhYlagAAAABJRU5ErkJggg==';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAPFBMVEUAAACEgoBva2ilamDxcG7IaWYgFBNOSEf//f0PDQwBAAA7LCwAAAD/AAD+hIX+m5z+zc5HAADPAAAGAADl032uAAAADHRSTlMAzNv0/vz+6v3+7ALrmfyXAAAAaUlEQVQY042PyxKAIAhFAc1eV7T6/3/N8VXOtAgWwBm4ANEPA8AswpySXHvvYZLlpBNrh9pDtcSqAQ1BUTVIjNUQY5icmwfglmXNgE0d6QBF9GigrU0A9LoM53U1kFzk6SBQuWfD/vHqDUCpBmVKTTM4AAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIVBMVEUAAACRjop4dXVpZ2tdcI9dfKdisfMAAAAumMN9xv+s2/+PADT2AAAAB3RSTlMAepGdv83v3HIc4QAAAFxJREFUCNdjYMAE5YXKRuLlDAzsHe2uIRUdBQwMFR1l6R3tIJGOyukdIJHy8lkry4FqGEwzV62aFozMUAFJOQEZ4iDFhQwI7UBGaTiEUVFs3g5isLMzMBQUIOwGAJRlIu9hk08QAAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEUAAACAgYVlc4ljsu4AAAAAAAAAAAAumMODyP6b1P6e1f/g8v89msgSIiwNFxwbPU3tQYj5AAAABnRSTlMAxej+9VTmD9ciAAAAZElEQVQI12NgwARpiUKKYmkMDGzlZUpK6eUJDAzp5clm5WUgkfKMtnKQSFpa54o0oBoGJYvZO88+gjJu7wMyhIBS2SCGGFDxaxADpP32NjAjSe0bSFd6epIaWISNjYEhJRVhNwAGlyJpYtcvcAAAAABJRU5ErkJggg==';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAHlBMVEUfJSCRi5Frbm9dn19082KR/30AAABmzDOq/5vZ/9Gt/vt2AAAABnRSTlMAe5rJ7/4vxEp4AAAAWUlEQVQI12NgwARpiUpKYmkMDGzlZcbG6eUJDAzp5Slu5WUgkfLUsHKQSFpaRGsaUA2DsmvnjBAjFAZICsQQAylOZEBoBzKSzSCM9CS1MhCDjY2BISEBYTcAtgAcKSK2vuIAAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAM1BMVEUAAACBj39tfm1qj2RepFlu2VQAAQAAAAAAAABmyzOX/oSr/pus/pzk/98PGgtatC4CBAI1ENblAAAACHRSTlMA09/p9v77ig0SBcQAAABnSURBVBjTjY9LDsAgCEQRsR2xWu9/2hK/adJFYQG8wABEPwyAYzNnSatjjPAiviWLhPCqI1R7HBrQdCmGBrEETTmnUAq/QMm5dODHyAQOXXR1zLUGsIEI7lonMGfeHQTq9xw4P159AIxSBSC53km7AAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABFklEQVR4AZ2R4WqEMBCEFy1yiJQQ14gcIhIuFBFR+qPQ93+v66QMksrlTwMfkZ2ZZbMKTgVqYIDl3YAbeCM31lJP/Zul4MAEPJjBQGNDLGsz8PQ6aqLAP5PTdd1WlmU09mSKtdTDRgrkzspJPKq6RxMahfj9yhOzQEZwZAwfzrk1ox3MXibIN8hO4MAjeV72CemJGWblnRsOYOdoGw0jebB20BPAwKzUQPlrFhrXFw1Wagu9yuzZwINzVAZCURRL+gRr7Wd8Vtqg4Th/lsUmewyk9WQ/A7NiwJz5VV/GmO+MNjMrFvh/NPDMigHTaeJN09a27ZHRJmalBg54CgfvAGYSLpoHjlmpuAwFdzDy7oGS/qIpM9UPFGg1b1kUlssAAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABR0lEQVR4AYWSQWq0QBCFCw0SRIK0PQ4hiIhEZBhEySLyewUPEMgqR/JIXiDhzz7kKKYePIZajEzDRxfV9dWU3SO6IiVWUsVxT5R75Y4gTmwNnUh4kCulUiuV8sjChDjmKtaUcHgmHsnNrMPh0IVhiMIjKZGzNXDoyhMzF7C89z2KtFGD+FoNXEUKZdgpaPM8P++cDXTtBDca7EyQK8+bXTufYBccuvLAG26UnqN1LCgI4g/lm7zTgSux4vk0J8rnKw3+m1//pBPbBrVyGZVNmiAITviEtm3t+D+2QcJx7GUxlN4594K4ZY75Xzh0JVWqnad6TdP0H+LRNBjHcYNDV5xS32qwaC4my7Lwn6guu5QoomgbdFmWDYhnM8E8zxscuhLzPWtKA/dGqUizrityX9M0YX+DQ1ciXobnP6vgfmTOM7Znnk70B58pPaEvx+epAAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/ElEQVR4AZ3RUWqEMBSF4ftQZAhSREQJIiIXpQwi+tSldkFdWPsLhyEE0ocKH2Fyzg1mNJ4KAQ1arTUeeJMH6qwTUJmCHjMcC6KKtbSIylzdXpl18J/k4fdTpUFmPLOOa9bGe+P4+n5RYYfLXuiMsAlXofBxK2QXpvwN/jqg+AY91vR+pStk+apZe0fEhhMXDhUmWXEoO9WNmrWAzvRPq7jnB2jvUGfWTEgPcJzZFTbZk/0Tnh5QI+af6lVGvq/Do2atwVL4VJ+3QrZo1lr4Pw5wzVqDWaV7SUvHrZDNmrWAHq7g0rphkS3LXDMBVqFGhxGT1gGdDFnWaab6BRmXRvbxDmYiAAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4AY2SQUrEQBBFS9CMNFEkhAQdYmiCIUgcZlYGc4VsBcGVF/AuWXme4F7RtXiVWF9+Y9MYtOHRTdX/NZWaEj2RYpQTJeEdK4fKPuA7DjSGXiQkU0qlUqxySmFMEsYsNSU8zEmK4OwdEbmkKCclYoGmolfWCGyenh1O0EJE2gXNWpFC2S0IGrCQ29EbdPCPAmEHmXIxByf8hDAPD71yzAnXypatbSgoAN8Pyju5h4deMUrqJk1z+0uBN+/XX+gxfoFK2QafUJO2aRq//Q+/QIx2wr+Kwq0rusrP/QKf9MTCtbQLf9U1wNvYnz3qug45S68kSvVXgbPbx3nvYPXNOI7cRPWySukK+DcGCvA+urqZ3RmGAbmSXjFK5rpwW8nhWVJP04TYa9/3uO/goVciDiPlZhW8c8ZAHuRSeqIv32FK/GYGL8YAAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/ElEQVR4AZ3RUWqEMBSF4ftQZAihDCKKiAQJShERQx+6o662e2p/4TCEQF468BEm95yLovFr4PBEq9PjgTd5wBcZp6559AiIWDAq6KXV3aJMUMfDOsTf7Mf/XaFBAvYiE9W16b74/vl8UeBAlKOSmWAzUiXwcavMkrrFE9QXVJ+gx5q9XvUVivmqrr1jxIYLCacCs6y6S8psGNU1hw4Bu4JHuUB3pzJBHZcviLiKV9jkyO4vxHyBx1h+qlcY5b2Wj+raE0vlU33dKrNFXWsR/7EgqmtPBIXuIw+dt8osqGsOPaIGSeeGRbZiFtVxsAYeHSbMOgd0MhSzTp3mD4RaQX4aW3NMAAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABP0lEQVR4AYWS0UqFQBCGhziImNRBRImDmUgiIaF0kWSP4AMEXXXTE/QiPpL3UdR19Crb/PAvLEtyFj5mmfn/cdxd0RUokbJXEsZYCZUd4D72NBG8wkKmlEqtVMoFhTFJmKuoKelBTVIkjbNE5IainJTIeZqaXjkg8fp+Z7GCjiLQbWgOihTKsCFowUZtoNef4HgDf4JMuTbe8n/Br8NDr5zxhBul52i3FBQE+xflmzzTA69ESmpPmubunwZfztc/6IncBrXSe7/QkK5tW3f8H7dBjHH8q6Kwt033V6Hb4JeeWPgsq42rugfYZ92psWscRwMPvZIo9bEGD2+F2YUnBizLwpeoXnYpbQM34kAB9peP58aueZ4NPPRKxPusaRoYG6UizbquyH1O04T4RA+8EvAwUr6sgjFnDuReLaUn+ANygUa7+9SCWgAAAABJRU5ErkJggg==';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAD/AABnZ2f///8nFk05AAAAAXRSTlMAQObYZgAAAEFJREFUeNqNjgEKACAMAjvX/98cAkkxgmSgO8Bt/Ai4ApJ6KKhzF3OiEMDASrGB/QWgPEHsUpN+Ng9xAETMYhDrWmeHAMcmvycWAAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAD1BMVEUAAAAAAAD/AABmZmYA/wBD99DBAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAE9JREFUCNdljcsRACEIQ5MOiNKAdGAJ9N/Uiu7nsMzABHgB4B8ygFoZA2hhVWavhhGeURPJU9q45+17hGbfGxa82Ndex3hEM44SJGD2/b4AzDgGlHbl388AAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAAul8NnZ2f////82iC9AAAAAXRSTlMAQObYZgAAAEFJREFUeNqNjgEKACAMAjvX/98cAkkxgmSgO8Bt/Ai4ApJ6KKhzF3OiEMDASrGB/QWgPEHsUpN+Ng9xAETMYhDrWmeHAMcmvycWAAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAD1BMVEUAAAAAAAAul8NnZ2f/AAD7B+mqAAAAAXRSTlMAQObYZgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAE9JREFUCNdljcsRACEIQ5MOiNKAdGAJ9N/Uiu7nsMzABHgB4B8ygFoZA2hhVWavhhGeURPJU9q45+17hGbfGxa82Ndex3hEM44SJGD2/b4AzDgGlHbl388AAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAElBMVEUBAAAAAABmzDNlyjJnZ2f///+6o7dfAAAAAXRSTlMAQObYZgAAAERJREFUeF6NjkEKADEIA51o///lJZfQxUsHITogWi8AvwZJuxmYa25xDooBLEwOWFTYAsYVhdorLZt9Ng9xCUTCUCQ2H3F4ANrZ2WNiAAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAD1BMVEUAAAAAAABmzDNmZmb/AAC8/wCMAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAE9JREFUCNdljcsRACEIQ5MOiNKAdGAJ9N/Uiu7nsMzABHgB4B8ygFoZA2hhVWavhhGeURPJU9q45+17hGbfGxa82Ndex3hEM44SJGD2/b4AzDgGlHbl388AAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX/////AAD///8AAABBZmS3AAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhElEQVR42q1RwQnAMAjMu5M4guAKXa4j5dUROo5tipSDcrFChUONd0di2m/hEGVOHDyIPufgwAFASDkpoSzmBrkJ2UMyR9LsJ3rvrqo3Rt1YMIMhhNnOxLMnoMFBxHyJAr2IOBFzA8U+6pLBdmEJTA0aMVjpDd6Loks0s5HZNwYx8tfZCZ0kll7ORffZAAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX///8ul8P///8AAACaqgkzAAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAABBQcHFx4KISoNLToaVW4oKCgul8M4ODg7OzvBwcH///8uS/CdAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eILZO5/XI0UAgm7H9tOsu0yGWAQSOoFijHOxOANGqm/LczpOaXs4gISrPZ+gc2+hO5w2xdwgOjBFUIF+sEJrhUl9JFr+badFwR+BfqlmGUJAAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX///9mzDP///8AAACT0n1lAAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAAECAIQIAgWLAsePA8oKCg4ODg6dB07OztmzDPBwcH///+rsf3XAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eIDhbn/cTVSCCTsfmw7ybbLZIBBIKkXKKU0E4M3aKT+tjCn5xiziwuIsNr7BTb7ErrDZV/AAaIHdwgV6AcnuFaU0Eeu5dt2XiUyBjCQ2bIrAAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAC/AABrZQDiAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAC/AAD///8dAAApAABsAAAHAAA4AACQAAAsAABMCpCvAAAAA3RSTlMAPse+s4iwAAAAMklEQVQI12NggAFmY2MDECaNAQZCilAzVJyg5oS4GqAxUtygjIp2KGOKJ5SxepcB3BUAcdYRqxAtgFoAAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAAA1/GhpCidAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAAA1/H///8AISUALzQAeokACAkAQEcAorYAMTcE9WFNAAAAA3RSTlMAPse+s4iwAAAAMklEQVQI12NggAFmY2MDECaNAQZCilAzVJyg5oS4GqAxUtygjIp2KGOKJ5SxepcB3BUAcdYRqxAtgFoAAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAABV/wErM5hwAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAABV/wH///8NKAASOAAwkQADCgAZTABAwQATOwC5e3VGAAAAA3RSTlMAPse+s4iwAAAAMklEQVQI12NggAFmY2MDECaNAQZCilAzVJyg5oS4GqAxUtygjIp2KGOKJ5SxepcB3BUAcdYRqxAtgFoAAAAASUVORK5CYII=';","import { d } from \"../globals/globals\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nconst $$ = (selector, root = d.body) => [...Array.from(root.querySelectorAll(selector))];\r\nexport default $$;\r\n","import { g, Conf, doc, d } from \"../globals/globals\";\r\nimport Main from \"../main/Main\";\r\nimport $ from \"../platform/$\";\r\nimport Captcha from \"./Captcha\";\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nconst CaptchaReplace = {\r\n init() {\r\n if ((g.SITE.software !== 'yotsuba') || (d.cookie.indexOf('pass_enabled=1') >= 0)) { return; }\r\n\r\n if (Conf['Force Noscript Captcha'] && Main.jsEnabled) {\r\n $.ready(Captcha.replace.noscript);\r\n return;\r\n }\r\n\r\n if (Conf['captchaLanguage'].trim()) {\r\n if (['boards.4chan.org', 'boards.4channel.org'].includes(location.hostname)) {\r\n return $.onExists(doc, '#captchaFormPart', node => $.onExists(node, 'iframe[src^=\"https://www.google.com/recaptcha/\"]', Captcha.replace.iframe));\r\n } else {\r\n return $.onExists(doc, 'iframe[src^=\"https://www.google.com/recaptcha/\"]', Captcha.replace.iframe);\r\n }\r\n }\r\n },\r\n\r\n noscript() {\r\n let noscript, original, toggle;\r\n if (!((original = $('#g-recaptcha')) && (noscript = $('noscript', original.parentNode)))) { return; }\r\n const span = $.el('span',\r\n {id: 'captcha-forced-noscript'});\r\n $.replace(noscript, span);\r\n $.rm(original);\r\n const insert = function() {\r\n span.innerHTML = noscript.textContent;\r\n return Captcha.replace.iframe($('iframe[src^=\"https://www.google.com/recaptcha/\"]', span));\r\n };\r\n if (toggle = $('#togglePostFormLink a, #form-link')) {\r\n return $.on(toggle, 'click', insert);\r\n } else {\r\n return insert();\r\n }\r\n },\r\n\r\n iframe(iframe) {\r\n let lang;\r\n if (lang = Conf['captchaLanguage'].trim()) {\r\n const src = /[?&]hl=/.test(iframe.src) ?\r\n iframe.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang))\r\n :\r\n iframe.src + `&hl=${encodeURIComponent(lang)}`;\r\n if (iframe.src !== src) { iframe.src = src; }\r\n }\r\n }\r\n};\r\nexport default CaptchaReplace;\r\n","import { d, g } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\nimport QR from \"./QR\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nconst CaptchaT = {\r\n init() {\r\n if (d.cookie.indexOf('pass_enabled=1') >= 0) { return; }\r\n if (!(this.isEnabled = !!$('#t-root') || !$.id('postForm'))) { return; }\r\n\r\n const root = $.el('div', {className: 'captcha-root'});\r\n this.nodes = {root};\r\n\r\n $.addClass(QR.nodes.el, 'has-captcha', 'captcha-t');\r\n return $.after(QR.nodes.com.parentNode, root);\r\n },\r\n\r\n moreNeeded() {\r\n },\r\n\r\n getThread() {\r\n let threadID;\r\n const boardID = g.BOARD.ID;\r\n if (QR.posts[0].thread === 'new') {\r\n threadID = '0';\r\n } else {\r\n threadID = '' + QR.posts[0].thread;\r\n }\r\n return {boardID, threadID};\r\n },\r\n\r\n setup(focus) {\r\n if (!this.isEnabled) { return; }\r\n\r\n if (!this.nodes.container) {\r\n this.nodes.container = $.el('div', {className: 'captcha-container'});\r\n $.prepend(this.nodes.root, this.nodes.container);\r\n CaptchaT.currentThread = CaptchaT.getThread();\r\n $.global(function() {\r\n const el = document.querySelector('#qr .captcha-container');\r\n window.TCaptcha.init(el, this.boardID, +this.threadID);\r\n return window.TCaptcha.setErrorCb(err => window.dispatchEvent(new CustomEvent('CreateNotification', {detail: {\r\n type: 'warning',\r\n content: '' + err\r\n }})\r\n ));\r\n }\r\n , CaptchaT.currentThread);\r\n }\r\n\r\n if (focus) {\r\n return $('#t-resp').focus();\r\n }\r\n },\r\n\r\n destroy() {\r\n if (!this.isEnabled || !this.nodes.container) { return; }\r\n $.global(() => window.TCaptcha.destroy());\r\n $.rm(this.nodes.container);\r\n return delete this.nodes.container;\r\n },\r\n\r\n updateThread() {\r\n if (!this.isEnabled) { return; }\r\n const {boardID, threadID} = (CaptchaT.currentThread || {});\r\n const newThread = CaptchaT.getThread();\r\n if ((newThread.boardID !== boardID) || (newThread.threadID !== threadID)) {\r\n CaptchaT.destroy();\r\n return CaptchaT.setup();\r\n }\r\n },\r\n\r\n getOne() {\r\n let el;\r\n let response = {};\r\n if (this.nodes.container) {\r\n for (var key of ['t-response', 't-challenge']) {\r\n response[key] = $(`[name='${key}']`, this.nodes.container).value;\r\n }\r\n }\r\n if (!response['t-response'] && !((el = $('#t-msg')) && /Verification not required/i.test(el.textContent))) {\r\n response = null;\r\n }\r\n return response;\r\n },\r\n\r\n setUsed() {\r\n if (!this.isEnabled) { return; }\r\n if (this.nodes.container) {\r\n return $.global(() => window.TCaptcha.clearChallenge());\r\n }\r\n },\r\n\r\n occupied() {\r\n return !!this.nodes.container;\r\n }\r\n};\r\nexport default CaptchaT;\r\n",null,"import { Conf, d, g } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\nimport { dict, HOUR } from \"../platform/helpers\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS104: Avoid inline assignments\r\n * DS206: Consider reworking classes to avoid initClass\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nexport default class DataBoard {\r\n static initClass() {\r\n this.keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads', 'watcherLastModified', 'customTitles'];\r\n\r\n this.changes = [];\r\n }\r\n\r\n constructor(key, sync, dontClean) {\r\n this.onSync = this.onSync.bind(this);\r\n this.key = key;\r\n this.initData(Conf[this.key]);\r\n $.sync(this.key, this.onSync);\r\n if (!dontClean) { this.clean(); }\r\n if (!sync) { return; }\r\n // Chrome also fires the onChanged callback on the current tab,\r\n // so we only start syncing when we're ready.\r\n var init = () => {\r\n $.off(d, '4chanXInitFinished', init);\r\n return this.sync = sync;\r\n };\r\n $.on(d, '4chanXInitFinished', init);\r\n }\r\n\r\n initData(data) {\r\n let boards;\r\n this.data = data;\r\n if (this.data.boards) {\r\n let lastChecked;\r\n ({boards, lastChecked} = this.data);\r\n this.data['4chan.org'] = {boards, lastChecked};\r\n delete this.data.boards;\r\n delete this.data.lastChecked;\r\n }\r\n return this.data[g.SITE.ID] || (this.data[g.SITE.ID] = { boards: dict() });\r\n }\r\n\r\n save(change, cb) {\r\n change();\r\n DataBoard.changes.push(change);\r\n return $.get(this.key, { boards: dict() }, items => {\r\n if (!DataBoard.changes.length) { return; }\r\n const needSync = ((items[this.key].version || 0) > (this.data.version || 0));\r\n if (needSync) {\r\n this.initData(items[this.key]);\r\n for (change of DataBoard.changes) { change(); }\r\n }\r\n DataBoard.changes = [];\r\n this.data.version = (this.data.version || 0) + 1;\r\n return $.set(this.key, this.data, () => {\r\n if (needSync) { this.sync?.(); }\r\n return cb?.();\r\n });\r\n });\r\n }\r\n\r\n forceSync(cb) {\r\n return $.get(this.key, { boards: dict() }, items => {\r\n if ((items[this.key].version || 0) > (this.data.version || 0)) {\r\n this.initData(items[this.key]);\r\n for (var change of DataBoard.changes) { change(); }\r\n this.sync?.();\r\n }\r\n return cb?.();\r\n });\r\n }\r\n\r\n delete({siteID, boardID, threadID, postID}, cb) {\r\n if (!siteID) { siteID = g.SITE.ID; }\r\n if (!this.data[siteID]) { return; }\r\n return this.save(() => {\r\n if (postID) {\r\n if (!this.data[siteID].boards[boardID]?.[threadID]) { return; }\r\n delete this.data[siteID].boards[boardID][threadID][postID];\r\n return this.deleteIfEmpty({siteID, boardID, threadID});\r\n } else if (threadID) {\r\n if (!this.data[siteID].boards[boardID]) { return; }\r\n delete this.data[siteID].boards[boardID][threadID];\r\n return this.deleteIfEmpty({siteID, boardID});\r\n } else {\r\n return delete this.data[siteID].boards[boardID];\r\n }\r\n }\r\n , cb);\r\n }\r\n\r\n deleteIfEmpty({siteID, boardID, threadID}) {\r\n if (!this.data[siteID]) { return; }\r\n if (threadID) {\r\n if (!Object.keys(this.data[siteID].boards[boardID][threadID]).length) {\r\n delete this.data[siteID].boards[boardID][threadID];\r\n return this.deleteIfEmpty({siteID, boardID});\r\n }\r\n } else if (!Object.keys(this.data[siteID].boards[boardID]).length) {\r\n return delete this.data[siteID].boards[boardID];\r\n }\r\n }\r\n\r\n set(data, cb) {\r\n return this.save(() => {\r\n return this.setUnsafe(data);\r\n }\r\n , cb);\r\n }\r\n\r\n setUnsafe({siteID, boardID, threadID, postID, val}) {\r\n if (!siteID) { siteID = g.SITE.ID; }\r\n if (!this.data[siteID]) { this.data[siteID] = { boards: dict() }; }\r\n if (postID !== undefined) {\r\n let base;\r\n return (((base = this.data[siteID].boards[boardID] || (this.data[siteID].boards[boardID] = dict())))[threadID] || (base[threadID] = dict()))[postID] = val;\r\n } else if (threadID !== undefined) {\r\n return (this.data[siteID].boards[boardID] || (this.data[siteID].boards[boardID] = dict()))[threadID] = val;\r\n } else {\r\n return this.data[siteID].boards[boardID] = val;\r\n }\r\n }\r\n\r\n extend({siteID, boardID, threadID, postID, val}, cb) {\r\n return this.save(() => {\r\n const oldVal = this.get({ siteID, boardID, threadID, postID, defaultValue: dict() });\r\n for (var key in val) {\r\n var subVal = val[key];\r\n if (typeof subVal === 'undefined') {\r\n delete oldVal[key];\r\n } else {\r\n oldVal[key] = subVal;\r\n }\r\n }\r\n return this.setUnsafe({siteID, boardID, threadID, postID, val: oldVal});\r\n }\r\n , cb);\r\n }\r\n\r\n setLastChecked(key='lastChecked') {\r\n return this.save(() => {\r\n return this.data[key] = Date.now();\r\n });\r\n }\r\n\r\n get({siteID, boardID, threadID, postID, defaultValue}) {\r\n let board, val;\r\n if (!siteID) { siteID = g.SITE.ID; }\r\n if (board = this.data[siteID]?.boards[boardID]) {\r\n let thread;\r\n if (threadID == null) {\r\n if (postID != null) {\r\n for (thread = 0; thread < board.length; thread++) {\r\n var ID = board[thread];\r\n if (postID in thread) {\r\n val = thread[postID];\r\n break;\r\n }\r\n }\r\n } else {\r\n val = board;\r\n }\r\n } else if (thread = board[threadID]) {\r\n val = (postID != null) ?\r\n thread[postID]\r\n :\r\n thread;\r\n }\r\n }\r\n return val || defaultValue;\r\n }\r\n\r\n clean() {\r\n let boardID, middle;\r\n const siteID = g.SITE.ID;\r\n for (boardID in this.data[siteID].boards) {\r\n var val = this.data[siteID].boards[boardID];\r\n this.deleteIfEmpty({siteID, boardID});\r\n }\r\n const now = Date.now();\r\n if (now - (2 * HOUR) >= ((middle = this.data[siteID].lastChecked || 0)) || middle > now) {\r\n this.data[siteID].lastChecked = now;\r\n for (boardID in this.data[siteID].boards) {\r\n this.ajaxClean(boardID);\r\n }\r\n }\r\n }\r\n\r\n ajaxClean(boardID) {\r\n const that = this;\r\n const siteID = g.SITE.ID;\r\n const threadsList = g.SITE.urls.threadsListJSON?.({siteID, boardID});\r\n if (!threadsList) { return; }\r\n return $.cache(threadsList, function() {\r\n if (this.status !== 200) { return; }\r\n const archiveList = g.SITE.urls.archiveListJSON?.({siteID, boardID});\r\n if (!archiveList) { return that.ajaxCleanParse(boardID, this.response); }\r\n const response1 = this.response;\r\n return $.cache(archiveList, function() {\r\n if ((this.status !== 200) && (!!g.SITE.archivedBoardsKnown || (this.status !== 404))) { return; }\r\n return that.ajaxCleanParse(boardID, response1, this.response);\r\n });\r\n });\r\n }\r\n\r\n ajaxCleanParse(boardID, response1, response2) {\r\n let board, ID;\r\n const siteID = g.SITE.ID;\r\n if (!(board = this.data[siteID].boards[boardID])) { return; }\r\n const threads = dict();\r\n if (response1) {\r\n for (var page of response1) {\r\n for (var thread of page.threads) {\r\n ID = thread.no;\r\n if (ID in board) { threads[ID] = board[ID]; }\r\n }\r\n }\r\n }\r\n if (response2) {\r\n for (ID of response2) {\r\n if (ID in board) { threads[ID] = board[ID]; }\r\n }\r\n }\r\n this.data[siteID].boards[boardID] = threads;\r\n this.deleteIfEmpty({siteID, boardID});\r\n return $.set(this.key, this.data);\r\n }\r\n\r\n onSync(data) {\r\n if ((data.version || 0) <= (this.data.version || 0)) { return; }\r\n this.initData(data);\r\n return this.sync?.();\r\n }\r\n}\r\nDataBoard.initClass();\r\n",null,"import SimpleDict from \"./SimpleDict\";\r\nimport $ from \"../platform/$\";\r\nimport { g } from \"../globals/globals\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nexport default class Thread {\r\n toString() { return this.ID; }\r\n\r\n constructor(ID, board) {\r\n this.board = board;\r\n this.ID = +ID;\r\n this.threadID = this.ID;\r\n this.boardID = this.board.ID;\r\n this.siteID = g.SITE.ID;\r\n this.fullID = `${this.board}.${this.ID}`;\r\n this.posts = new SimpleDict();\r\n this.isDead = false;\r\n this.isHidden = false;\r\n this.isSticky = false;\r\n this.isClosed = false;\r\n this.isArchived = false;\r\n this.postLimit = false;\r\n this.fileLimit = false;\r\n this.lastPost = 0;\r\n this.ipCount = undefined;\r\n this.json = null;\r\n\r\n this.OP = null;\r\n this.catalogView = null;\r\n\r\n this.nodes =\r\n {root: null};\r\n\r\n this.board.threads.push(this.ID, this);\r\n g.threads.push(this.fullID, this);\r\n }\r\n\r\n setPage(pageNum) {\r\n let icon;\r\n const {info, reply} = this.OP.nodes;\r\n if (!(icon = $('.page-num', info))) {\r\n icon = $.el('span', {className: 'page-num'});\r\n $.replace(reply.parentNode.previousSibling, [$.tn(' '), icon, $.tn(' ')]);\r\n }\r\n icon.title = `This thread is on page ${pageNum} in the original index.`;\r\n icon.textContent = `[${pageNum}]`;\r\n if (this.catalogView) { return this.catalogView.nodes.pageCount.textContent = pageNum; }\r\n }\r\n\r\n setCount(type, count, reachedLimit) {\r\n if (!this.catalogView) { return; }\r\n const el = this.catalogView.nodes[`${type}Count`];\r\n el.textContent = count;\r\n return (reachedLimit ? $.addClass : $.rmClass)(el, 'warning');\r\n }\r\n\r\n setStatus(type, status) {\r\n const name = `is${type}`;\r\n if (this[name] === status) { return; }\r\n this[name] = status;\r\n if (!this.OP) { return; }\r\n this.setIcon('Sticky', this.isSticky);\r\n this.setIcon('Closed', this.isClosed && !this.isArchived);\r\n return this.setIcon('Archived', this.isArchived);\r\n }\r\n\r\n setIcon(type, status) {\r\n const typeLC = type.toLowerCase();\r\n let icon = $(`.${typeLC}Icon`, this.OP.nodes.info);\r\n if (!!icon === status) { return; }\r\n\r\n if (!status) {\r\n $.rm(icon.previousSibling);\r\n $.rm(icon);\r\n if (this.catalogView) { $.rm($(`.${typeLC}Icon`, this.catalogView.nodes.icons)); }\r\n return;\r\n }\r\n icon = $.el('img', {\r\n src: `${g.SITE.Build.staticPath}${typeLC}${g.SITE.Build.gifIcon}`,\r\n alt: type,\r\n title: type,\r\n className: `${typeLC}Icon retina`\r\n }\r\n );\r\n if (g.BOARD.ID === 'f') {\r\n icon.style.cssText = 'height: 18px; width: 18px;';\r\n }\r\n\r\n const root = (type !== 'Sticky') && this.isSticky ?\r\n $('.stickyIcon', this.OP.nodes.info)\r\n :\r\n $('.page-num', this.OP.nodes.info) || this.OP.nodes.quote;\r\n $.after(root, [$.tn(' '), icon]);\r\n\r\n if (!this.catalogView) { return; }\r\n return ((type === 'Sticky') && this.isClosed ? $.prepend : $.add)(this.catalogView.nodes.icons, icon.cloneNode());\r\n }\r\n\r\n kill() {\r\n return this.isDead = true;\r\n }\r\n\r\n collect() {\r\n let n = 0;\r\n this.posts.forEach(function(post) {\r\n if (post.clones.length) {\r\n return n++;\r\n } else {\r\n return post.collect();\r\n }\r\n });\r\n if (!n) {\r\n g.threads.rm(this.fullID);\r\n return this.board.threads.rm(this);\r\n }\r\n }\r\n}\r\n","import $ from \"../platform/$\";\r\n\r\nexport default class CatalogThread {\r\n toString() { return this.ID; }\r\n\r\n constructor(root, thread) {\r\n this.thread = thread;\r\n this.ID = this.thread.ID;\r\n this.board = this.thread.board;\r\n const {post} = this.thread.OP.nodes;\r\n this.nodes = {\r\n root,\r\n thumb: $('.catalog-thumb', post),\r\n icons: $('.catalog-icons', post),\r\n postCount: $('.post-count', post),\r\n fileCount: $('.file-count', post),\r\n pageCount: $('.page-count', post),\r\n replies: null\r\n };\r\n this.thread.catalogView = this;\r\n }\r\n}\r\n","import { Conf, d, doc } from \"../globals/globals\";\r\nimport Main from \"../main/Main\";\r\nimport $ from \"../platform/$\";\r\nimport $$ from \"../platform/$$\";\r\nimport Header from \"./Header\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS206: Consider reworking classes to avoid initClass\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nconst dialog = function(id, properties) {\r\n const el = $.el('div', {\r\n className: 'dialog',\r\n id\r\n }\r\n );\r\n $.extend(el, properties);\r\n el.style.cssText = Conf[`${id}.position`];\r\n\r\n const move = $('.move', el);\r\n $.on(move, 'touchstart mousedown', dragstart);\r\n for (var child of move.children) {\r\n if (!child.tagName) { continue; }\r\n $.on(child, 'touchstart mousedown', e => e.stopPropagation());\r\n }\r\n\r\n return el;\r\n};\r\n\r\nvar Menu = (function() {\r\n let currentMenu = undefined;\r\n let lastToggledButton = undefined;\r\n Menu = class Menu {\r\n static initClass() {\r\n currentMenu = null;\r\n lastToggledButton = null;\r\n }\r\n\r\n constructor(type) {\r\n // XXX AddMenuEntry event is deprecated\r\n this.setPosition = this.setPosition.bind(this);\r\n this.close = this.close.bind(this);\r\n this.keybinds = this.keybinds.bind(this);\r\n this.onFocus = this.onFocus.bind(this);\r\n this.addEntry = this.addEntry.bind(this);\r\n this.type = type;\r\n $.on(d, 'AddMenuEntry', ({detail}) => {\r\n if (detail.type !== this.type) { return; }\r\n delete detail.open;\r\n return this.addEntry(detail);\r\n });\r\n this.entries = [];\r\n }\r\n\r\n makeMenu() {\r\n const menu = $.el('div', {\r\n className: 'dialog',\r\n id: 'menu',\r\n tabIndex: 0\r\n }\r\n );\r\n menu.dataset.type = this.type;\r\n $.on(menu, 'click', e => e.stopPropagation());\r\n $.on(menu, 'keydown', this.keybinds);\r\n return menu;\r\n }\r\n\r\n toggle(e, button, data) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n\r\n if (currentMenu) {\r\n // Close if it's already opened.\r\n // Reopen if we clicked on another button.\r\n const previousButton = lastToggledButton;\r\n currentMenu.close();\r\n if (previousButton === button) { return; }\r\n }\r\n\r\n if (!this.entries.length) { return; }\r\n return this.open(button, data);\r\n }\r\n\r\n open(button, data) {\r\n let entry;\r\n const menu = (this.menu = this.makeMenu());\r\n currentMenu = this;\r\n lastToggledButton = button;\r\n\r\n this.entries.sort((first, second) => first.order - second.order);\r\n\r\n for (entry of this.entries) {\r\n this.insertEntry(entry, menu, data);\r\n }\r\n\r\n $.addClass(lastToggledButton, 'active');\r\n\r\n $.on(d, 'click CloseMenu', this.close);\r\n $.on(d, 'scroll', this.setPosition);\r\n $.on(window, 'resize', this.setPosition);\r\n $.after(button, menu);\r\n\r\n this.setPosition();\r\n\r\n entry = $('.entry', menu);\r\n // We've removed flexbox, so we don't use order anymore.\r\n // while prevEntry = @findNextEntry entry, -1\r\n // entry = prevEntry\r\n this.focus(entry);\r\n\r\n return menu.focus();\r\n }\r\n\r\n setPosition() {\r\n const mRect = this.menu.getBoundingClientRect();\r\n const bRect = lastToggledButton.getBoundingClientRect();\r\n const bTop = window.scrollY + bRect.top;\r\n const bLeft = window.scrollX + bRect.left;\r\n const cHeight = doc.clientHeight;\r\n const cWidth = doc.clientWidth;\r\n const [top, bottom] = Array.from((bRect.top + bRect.height + mRect.height) < cHeight ?\r\n [`${bRect.bottom}px`, '']\r\n :\r\n ['', `${cHeight - bRect.top}px`]);\r\n const [left, right] = Array.from((bRect.left + mRect.width) < cWidth ?\r\n [`${bRect.left}px`, '']\r\n :\r\n ['', `${cWidth - bRect.right}px`]);\r\n $.extend(this.menu.style, {top, right, bottom, left});\r\n return this.menu.classList.toggle('left', right);\r\n }\r\n\r\n insertEntry(entry, parent, data) {\r\n let submenu;\r\n if (typeof entry.open === 'function') {\r\n try {\r\n if (!entry.open(data)) { return; }\r\n } catch (err) {\r\n Main.handleErrors({\r\n message: `Error in building the ${this.type} menu.`,\r\n error: err\r\n });\r\n return;\r\n }\r\n }\r\n $.add(parent, entry.el);\r\n\r\n if (!entry.subEntries) { return; }\r\n if (submenu = $('.submenu', entry.el)) {\r\n // Reset sub menu, remove irrelevant entries.\r\n $.rm(submenu);\r\n }\r\n submenu = $.el('div',\r\n {className: 'dialog submenu'});\r\n for (var subEntry of entry.subEntries) {\r\n this.insertEntry(subEntry, submenu, data);\r\n }\r\n $.add(entry.el, submenu);\r\n }\r\n\r\n close() {\r\n $.rm(this.menu);\r\n delete this.menu;\r\n $.rmClass(lastToggledButton, 'active');\r\n currentMenu = null;\r\n lastToggledButton = null;\r\n $.off(d, 'click scroll CloseMenu', this.close);\r\n $.off(d, 'scroll', this.setPosition);\r\n return $.off(window, 'resize', this.setPosition);\r\n }\r\n\r\n findNextEntry(entry, direction) {\r\n const entries = [...Array.from(entry.parentNode.children)];\r\n entries.sort((first, second) => first.style.order - second.style.order);\r\n return entries[entries.indexOf(entry) + direction];\r\n }\r\n\r\n keybinds(e) {\r\n let subEntry;\r\n let next, submenu;\r\n let entry = $('.focused', this.menu);\r\n while ((subEntry = $('.focused', entry))) {\r\n entry = subEntry;\r\n }\r\n\r\n switch (e.keyCode) {\r\n case 27: // Esc\r\n lastToggledButton.focus();\r\n this.close();\r\n break;\r\n case 13: case 32: // Enter, Space\r\n entry.click();\r\n break;\r\n case 38: // Up\r\n if (next = this.findNextEntry(entry, -1)) {\r\n this.focus(next);\r\n }\r\n break;\r\n case 40: // Down\r\n if (next = this.findNextEntry(entry, +1)) {\r\n this.focus(next);\r\n }\r\n break;\r\n case 39: // Right\r\n if ((submenu = $('.submenu', entry)) && (next = submenu.firstElementChild)) {\r\n let nextPrev;\r\n while ((nextPrev = this.findNextEntry(next, -1))) {\r\n next = nextPrev;\r\n }\r\n this.focus(next);\r\n }\r\n break;\r\n case 37: // Left\r\n if (next = $.x('parent::*[contains(@class,\"submenu\")]/parent::*', entry)) {\r\n this.focus(next);\r\n }\r\n break;\r\n default:\r\n return;\r\n }\r\n\r\n e.preventDefault();\r\n return e.stopPropagation();\r\n }\r\n\r\n onFocus(e) {\r\n e.stopPropagation();\r\n return this.focus(e.target);\r\n }\r\n\r\n focus(entry) {\r\n let focused, submenu;\r\n while ((focused = $.x('parent::*/child::*[contains(@class,\"focused\")]', entry))) {\r\n $.rmClass(focused, 'focused');\r\n }\r\n for (focused of $$('.focused', entry)) {\r\n $.rmClass(focused, 'focused');\r\n }\r\n $.addClass(entry, 'focused');\r\n\r\n // Submenu positioning.\r\n if (!(submenu = $('.submenu', entry))) { return; }\r\n const sRect = submenu.getBoundingClientRect();\r\n const eRect = entry.getBoundingClientRect();\r\n const cHeight = doc.clientHeight;\r\n const cWidth = doc.clientWidth;\r\n const [top, bottom] = Array.from((eRect.top + sRect.height) < cHeight ?\r\n ['0px', 'auto']\r\n :\r\n ['auto', '0px']);\r\n const [left, right] = Array.from((eRect.right + sRect.width) < (cWidth - 150) ?\r\n ['100%', 'auto']\r\n :\r\n ['auto', '100%']);\r\n const {style} = submenu;\r\n style.top = top;\r\n style.bottom = bottom;\r\n style.left = left;\r\n return style.right = right;\r\n }\r\n\r\n addEntry(entry) {\r\n this.parseEntry(entry);\r\n return this.entries.push(entry);\r\n }\r\n\r\n parseEntry(entry) {\r\n const {el, subEntries} = entry;\r\n $.addClass(el, 'entry');\r\n $.on(el, 'focus mouseover', this.onFocus);\r\n el.style.order = entry.order || 100;\r\n if (!subEntries) { return; }\r\n $.addClass(el, 'has-submenu');\r\n for (var subEntry of subEntries) {\r\n this.parseEntry(subEntry);\r\n }\r\n }\r\n };\r\n Menu.initClass();\r\n return Menu;\r\n})();\r\n\r\nexport var dragstart = function (e) {\r\n let isTouching;\r\n if ((e.type === 'mousedown') && (e.button !== 0)) { return; } // not LMB\r\n // prevent text selection\r\n e.preventDefault();\r\n if (isTouching = e.type === 'touchstart') {\r\n e = e.changedTouches[e.changedTouches.length - 1];\r\n }\r\n // distance from pointer to el edge is constant; calculate it here.\r\n const el = $.x('ancestor::div[contains(@class,\"dialog\")][1]', this);\r\n const rect = el.getBoundingClientRect();\r\n const screenHeight = doc.clientHeight;\r\n const screenWidth = doc.clientWidth;\r\n const o = {\r\n id: el.id,\r\n style: el.style,\r\n dx: e.clientX - rect.left,\r\n dy: e.clientY - rect.top,\r\n height: screenHeight - rect.height,\r\n width: screenWidth - rect.width,\r\n screenHeight,\r\n screenWidth,\r\n isTouching\r\n };\r\n\r\n [o.topBorder, o.bottomBorder] = Array.from(Conf['Header auto-hide'] || !Conf['Fixed Header'] ?\r\n [0, 0]\r\n : Conf['Bottom Header'] ?\r\n [0, Header.bar.getBoundingClientRect().height]\r\n :\r\n [Header.bar.getBoundingClientRect().height, 0]);\r\n\r\n if (isTouching) {\r\n o.identifier = e.identifier;\r\n o.move = touchmove.bind(o);\r\n o.up = touchend.bind(o);\r\n $.on(d, 'touchmove', o.move);\r\n return $.on(d, 'touchend touchcancel', o.up);\r\n } else { // mousedown\r\n o.move = drag.bind(o);\r\n o.up = dragend.bind(o);\r\n $.on(d, 'mousemove', o.move);\r\n return $.on(d, 'mouseup', o.up);\r\n }\r\n};\r\n\r\nexport var touchmove = function (e) {\r\n for (var touch of e.changedTouches) {\r\n if (touch.identifier === this.identifier) {\r\n drag.call(this, touch);\r\n return;\r\n }\r\n }\r\n};\r\n\r\nexport var drag = function (e) {\r\n const {clientX, clientY} = e;\r\n\r\n let left = clientX - this.dx;\r\n left = left < 10 ?\r\n 0\r\n : (this.width - left) < 10 ?\r\n ''\r\n :\r\n ((left / this.screenWidth) * 100) + '%';\r\n\r\n let top = clientY - this.dy;\r\n top = top < (10 + this.topBorder) ?\r\n this.topBorder + 'px'\r\n : (this.height - top) < (10 + this.bottomBorder) ?\r\n ''\r\n :\r\n ((top / this.screenHeight) * 100) + '%';\r\n\r\n const right = left === '' ?\r\n 0\r\n :\r\n '';\r\n\r\n const bottom = top === '' ?\r\n this.bottomBorder + 'px'\r\n :\r\n '';\r\n\r\n const {style} = this;\r\n style.left = left;\r\n style.right = right;\r\n style.top = top;\r\n return style.bottom = bottom;\r\n};\r\n\r\nexport var touchend = function (e) {\r\n for (var touch of e.changedTouches) {\r\n if (touch.identifier === this.identifier) {\r\n dragend.call(this);\r\n return;\r\n }\r\n }\r\n};\r\n\r\nexport var dragend = function () {\r\n if (this.isTouching) {\r\n $.off(d, 'touchmove', this.move);\r\n $.off(d, 'touchend touchcancel', this.up);\r\n } else { // mouseup\r\n $.off(d, 'mousemove', this.move);\r\n $.off(d, 'mouseup', this.up);\r\n }\r\n return $.set(`${this.id}.position`, this.style.cssText);\r\n};\r\n\r\nconst hoverstart = function ({ root, el, latestEvent, endEvents, height, width, cb, noRemove }) {\r\n const rect = root.getBoundingClientRect();\r\n const o = {\r\n root,\r\n el,\r\n style: el.style,\r\n isImage: ['IMG', 'VIDEO'].includes(el.nodeName),\r\n cb,\r\n endEvents,\r\n latestEvent,\r\n clientHeight: doc.clientHeight,\r\n clientWidth: doc.clientWidth,\r\n height,\r\n width,\r\n noRemove,\r\n clientX: (rect.left + rect.right) / 2,\r\n clientY: (rect.top + rect.bottom) / 2\r\n };\r\n o.hover = hover.bind(o);\r\n o.hoverend = hoverend.bind(o);\r\n\r\n o.hover(o.latestEvent);\r\n new MutationObserver(function() {\r\n if (el.parentNode) { return o.hover(o.latestEvent); }\r\n }).observe(el, {childList: true});\r\n\r\n $.on(root, endEvents, o.hoverend);\r\n if ($.x('ancestor::div[contains(@class,\"inline\")][1]', root)) {\r\n $.on(d, 'keydown', o.hoverend);\r\n }\r\n $.on(root, 'mousemove', o.hover);\r\n\r\n // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=674955\r\n o.workaround = function(e) { if (!root.contains(e.target)) { return o.hoverend(e); } };\r\n return $.on(doc, 'mousemove', o.workaround);\r\n};\r\n\r\nhoverstart.padding = 25;\r\n\r\nexport var hover = function (e) {\r\n this.latestEvent = e;\r\n const height = (this.height || this.el.offsetHeight) + hoverstart.padding;\r\n const width = (this.width || this.el.offsetWidth);\r\n const {clientX, clientY} = Conf['Follow Cursor'] ? e : this;\r\n\r\n const top = this.isImage ?\r\n Math.max(0, (clientY * (this.clientHeight - height)) / this.clientHeight)\r\n :\r\n Math.max(0, Math.min(this.clientHeight - height, clientY - 120));\r\n\r\n let threshold = this.clientWidth / 2;\r\n if (!this.isImage) { threshold = Math.max(threshold, this.clientWidth - 400); }\r\n let marginX = (clientX <= threshold ? clientX : this.clientWidth - clientX) + 45;\r\n if (this.isImage) { marginX = Math.min(marginX, this.clientWidth - width); }\r\n marginX += 'px';\r\n const [left, right] = Array.from(clientX <= threshold ? [marginX, ''] : ['', marginX]);\r\n\r\n const {style} = this;\r\n style.top = top + 'px';\r\n style.left = left;\r\n return style.right = right;\r\n};\r\n\r\nexport var hoverend = function (e) {\r\n if (((e.type === 'keydown') && (e.keyCode !== 13)) || (e.target.nodeName === \"TEXTAREA\")) { return; }\r\n if (!this.noRemove) { $.rm(this.el); }\r\n $.off(this.root, this.endEvents, this.hoverend);\r\n $.off(d, 'keydown', this.hoverend);\r\n $.off(this.root, 'mousemove', this.hover);\r\n // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=674955\r\n $.off(doc, 'mousemove', this.workaround);\r\n if (this.cb) { return this.cb.call(this); }\r\n};\r\n\r\nexport const checkbox = function (name, text, checked) {\r\n if (checked == null) { checked = Conf[name]; }\r\n const label = $.el('label');\r\n const input = $.el('input', {type: 'checkbox', name, checked});\r\n $.add(label, [input, $.tn(` ${text}`)]);\r\n return label;\r\n};\r\n\r\nconst UI = {\r\n dialog,\r\n Menu,\r\n hover: hoverstart,\r\n checkbox\r\n};\r\nexport default UI;\r\n","import Get from \"../General/Get\";\r\nimport Header from \"../General/Header\";\r\nimport { g, Conf, d, doc } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\nimport $$ from \"../platform/$$\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar Nav = {\r\n init() {\r\n switch (g.VIEW) {\r\n case 'index':\r\n if (!Conf['Index Navigation']) { return; }\r\n break;\r\n case 'thread':\r\n if (!Conf['Reply Navigation']) { return; }\r\n break;\r\n default:\r\n return;\r\n }\r\n\r\n const span = $.el('span',\r\n {id: 'navlinks'});\r\n const prev = $.el('a', {\r\n textContent: '▲',\r\n href: 'javascript:;'\r\n }\r\n );\r\n const next = $.el('a', {\r\n textContent: '▼',\r\n href: 'javascript:;'\r\n }\r\n );\r\n\r\n $.on(prev, 'click', this.prev);\r\n $.on(next, 'click', this.next);\r\n\r\n $.add(span, [prev, $.tn(' '), next]);\r\n var append = function() {\r\n $.off(d, '4chanXInitFinished', append);\r\n return $.add(d.body, span);\r\n };\r\n return $.on(d, '4chanXInitFinished', append);\r\n },\r\n\r\n prev() {\r\n if (g.VIEW === 'thread') {\r\n return window.scrollTo(0, 0);\r\n } else {\r\n return Nav.scroll(-1);\r\n }\r\n },\r\n\r\n next() {\r\n if (g.VIEW === 'thread') {\r\n return window.scrollTo(0, d.body.scrollHeight);\r\n } else {\r\n return Nav.scroll(+1);\r\n }\r\n },\r\n\r\n getThread() {\r\n if (g.VIEW === 'thread') { return g.threads.get(`${g.BOARD}.${g.THREADID}`).nodes.root; }\r\n if ($.hasClass(doc, 'catalog-mode')) { return; }\r\n for (var threadRoot of $$(g.SITE.selectors.thread)) {\r\n var thread = Get.threadFromRoot(threadRoot);\r\n if (thread.isHidden && !thread.stub) { continue; }\r\n if (Header.getTopOf(threadRoot) >= -threadRoot.getBoundingClientRect().height) { // not scrolled past\r\n return threadRoot;\r\n }\r\n }\r\n },\r\n\r\n scroll(delta) {\r\n let next;\r\n d.activeElement?.blur();\r\n let thread = Nav.getThread();\r\n if (!thread) { return; }\r\n const axis = delta === +1 ?\r\n 'following'\r\n :\r\n 'preceding';\r\n if (next = $.x(`${axis}-sibling::${g.SITE.xpath.thread}[not(@hidden)][1]`, thread)) {\r\n // Unless we're not at the beginning of the current thread,\r\n // and thus wanting to move to beginning,\r\n // or we're above the first thread and don't want to skip it.\r\n const top = Header.getTopOf(thread);\r\n if (((delta === +1) && (top < 5)) || ((delta === -1) && (top > -5))) { thread = next; }\r\n }\r\n // Add extra space to the end of the page if necessary so that all threads can be selected by keybinds.\r\n const extra = (Header.getTopOf(thread) + doc.clientHeight) - d.body.getBoundingClientRect().bottom;\r\n if (extra > 0) { d.body.style.marginBottom = `${extra}px`; }\r\n\r\n Header.scrollTo(thread);\r\n\r\n if ((extra > 0) && !Nav.haveExtra) {\r\n Nav.haveExtra = true;\r\n return $.on(d, 'scroll', Nav.removeExtra);\r\n }\r\n },\r\n\r\n removeExtra() {\r\n const extra = doc.clientHeight - d.body.getBoundingClientRect().bottom;\r\n if (extra > 0) {\r\n return d.body.style.marginBottom = `${extra}px`;\r\n } else {\r\n d.body.style.marginBottom = '';\r\n delete Nav.haveExtra;\r\n return $.off(d, 'scroll', Nav.removeExtra);\r\n }\r\n }\r\n};\r\nexport default Nav;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport { Conf, g } from \"../globals/globals\";\r\nimport $$ from \"../platform/$$\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar ImageHost = {\r\n init() {\r\n if ((!(this.useFaster = /\\S/.test(Conf['fourchanImageHost']))) || (g.SITE.software !== 'yotsuba') || !['index', 'thread'].includes(g.VIEW)) { return; }\r\n return Callbacks.Post.push({\r\n name: 'Image Host Rewriting',\r\n cb: this.node\r\n });\r\n },\r\n\r\n suggestions: ['i.4cdn.org', 'is2.4chan.org'],\r\n\r\n host() {\r\n return Conf['fourchanImageHost'].trim() || 'i.4cdn.org';\r\n },\r\n flashHost() {\r\n return 'i.4cdn.org';\r\n },\r\n thumbHost() {\r\n return 'i.4cdn.org';\r\n },\r\n test(hostname) {\r\n return (hostname === 'i.4cdn.org') || ImageHost.regex.test(hostname);\r\n },\r\n\r\n regex: /^is\\d*\\.4chan(?:nel)?\\.org$/,\r\n\r\n node() {\r\n if (this.isClone) { return; }\r\n const host = ImageHost.host();\r\n if (this.file && ImageHost.test(this.file.url.split('/')[2]) && !/\\.swf$/.test(this.file.url)) {\r\n this.file.link.hostname = host;\r\n if (this.file.thumbLink) { this.file.thumbLink.hostname = host; }\r\n this.file.url = this.file.link.href;\r\n }\r\n return ImageHost.fixLinks($$('a', this.nodes.comment));\r\n },\r\n\r\n fixLinks(links) {\r\n for (var link of links) {\r\n if (ImageHost.test(link.hostname) && !/\\.swf$/.test(link.pathname)) {\r\n var host = ImageHost.host();\r\n if (link.hostname !== host) { link.hostname = host; }\r\n }\r\n }\r\n }\r\n};\r\nexport default ImageHost;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport Config from \"../config/Config\";\r\nimport Header from \"../General/Header\";\r\nimport UI from \"../General/UI\";\r\nimport { g, Conf, E } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar Volume = {\r\n init() {\r\n if (!['index', 'thread'].includes(g.VIEW) ||\r\n (!Conf['Image Expansion'] && !Conf['Image Hover'] && !Conf['Image Hover in Catalog'] && !Conf['Gallery'])) { return; }\r\n\r\n $.sync('Allow Sound', function(x) {\r\n Conf['Allow Sound'] = x;\r\n if (Volume.inputs) Volume.inputs.unmute.checked = x;\r\n });\r\n\r\n $.sync('Default Volume', function(x) {\r\n Conf['Default Volume'] = x;\r\n if (Volume.inputs) Volume.inputs.volume.value = x;\r\n });\r\n\r\n if (Conf['Mouse Wheel Volume']) {\r\n Callbacks.Post.push({\r\n name: 'Mouse Wheel Volume',\r\n cb: this.node\r\n });\r\n }\r\n\r\n if (g.SITE.noAudio?.(g.BOARD)) { return; }\r\n\r\n if (Conf['Mouse Wheel Volume']) {\r\n Callbacks.CatalogThread.push({\r\n name: 'Mouse Wheel Volume',\r\n cb: this.catalogNode\r\n });\r\n }\r\n\r\n const unmuteEntry = UI.checkbox('Allow Sound', 'Allow Sound');\r\n unmuteEntry.title = Config.main['Images and Videos']['Allow Sound'][1];\r\n\r\n const volumeEntry = $.el('label',\r\n {title: 'Default volume for videos.'});\r\n $.extend(volumeEntry,\r\n {innerHTML: \" Volume\"});\r\n\r\n this.inputs = {\r\n unmute: unmuteEntry.firstElementChild,\r\n volume: volumeEntry.firstElementChild\r\n };\r\n\r\n $.on(this.inputs.unmute, 'change', $.cb.checked);\r\n $.on(this.inputs.volume, 'change', $.cb.value);\r\n\r\n Header.menu.addEntry({el: unmuteEntry, order: 200});\r\n return Header.menu.addEntry({el: volumeEntry, order: 201});\r\n },\r\n\r\n setup(video) {\r\n video.muted = !Conf['Allow Sound'];\r\n video.volume = Conf['Default Volume'];\r\n return $.on(video, 'volumechange', Volume.change);\r\n },\r\n\r\n change() {\r\n const {muted, volume} = this;\r\n const items = {\r\n 'Allow Sound': !muted,\r\n 'Default Volume': volume\r\n };\r\n for (var key in items) {\r\n var val = items[key];\r\n if (Conf[key] === val) {\r\n delete items[key];\r\n }\r\n }\r\n $.set(items);\r\n $.extend(Conf, items);\r\n if (Volume.inputs) {\r\n Volume.inputs.unmute.checked = !muted;\r\n return Volume.inputs.volume.value = volume;\r\n }\r\n },\r\n\r\n node() {\r\n if (g.SITE.noAudio?.(this.board)) { return; }\r\n for (var file of this.files) {\r\n if (file.isVideo) {\r\n if (file.thumb) { $.on(file.thumb, 'wheel', Volume.wheel.bind(Header.hover)); }\r\n $.on(($('.file-info', file.text) || file.link), 'wheel', Volume.wheel.bind(file.thumbLink));\r\n }\r\n }\r\n },\r\n\r\n catalogNode() {\r\n const file = this.thread.OP.files[0];\r\n if (!file?.isVideo) { return; }\r\n return $.on(this.nodes.thumb, 'wheel', Volume.wheel.bind(Header.hover));\r\n },\r\n\r\n wheel(e) {\r\n let el;\r\n if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { return; }\r\n if (!(el = $('video:not([data-md5])', this))) { return; }\r\n if (el.muted || !$.hasAudio(el)) { return; }\r\n let volume = el.volume + 0.1;\r\n if (e.deltaY < 0) { volume *= 1.1; }\r\n if (e.deltaY > 0) { volume /= 1.1; }\r\n el.volume = $.minmax(volume - 0.1, 0, 1);\r\n return e.preventDefault();\r\n }\r\n};\r\nexport default Volume;\r\n","import Redirect from \"../Archive/Redirect\";\r\nimport Notice from \"../classes/Notice\";\r\nimport { g, Conf, d } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\nimport CrossOrigin from \"../platform/CrossOrigin\";\r\nimport ImageHost from \"./ImageHost\";\r\nimport Volume from \"./Volume\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS104: Avoid inline assignments\r\n * DS204: Change includes calls to have a more natural evaluation order\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar ImageCommon = {\r\n // Pause and mute video in preparation for removing the element from the document.\r\n pause(video) {\r\n if (video.nodeName !== 'VIDEO') { return; }\r\n video.pause();\r\n $.off(video, 'volumechange', Volume.change);\r\n return video.muted = true;\r\n },\r\n\r\n rewind(el) {\r\n if (el.nodeName === 'VIDEO') {\r\n if (el.readyState >= el.HAVE_METADATA) { return el.currentTime = 0; }\r\n } else if (/\\.gif$/.test(el.src)) {\r\n return $.queueTask(() => el.src = el.src);\r\n }\r\n },\r\n\r\n pushCache(el) {\r\n ImageCommon.cache = el;\r\n return $.on(el, 'error', ImageCommon.cacheError);\r\n },\r\n\r\n popCache() {\r\n const el = ImageCommon.cache;\r\n $.off(el, 'error', ImageCommon.cacheError);\r\n delete ImageCommon.cache;\r\n return el;\r\n },\r\n\r\n cacheError() {\r\n if (ImageCommon.cache === this) { return delete ImageCommon.cache; }\r\n },\r\n\r\n decodeError(file, fileObj) {\r\n let message;\r\n if (file.error?.code !== MediaError.MEDIA_ERR_DECODE) { return false; }\r\n if (!(message = $('.warning', fileObj.thumb.parentNode))) {\r\n message = $.el('div', {className: 'warning'});\r\n $.after(fileObj.thumb, message);\r\n }\r\n message.textContent = 'Error: Corrupt or unplayable video';\r\n return true;\r\n },\r\n\r\n isFromArchive(file) {\r\n return (g.SITE.software === 'yotsuba') && !ImageHost.test(file.src.split('/')[2]);\r\n },\r\n\r\n error(file, post, fileObj, delay, cb) {\r\n let timeoutID;\r\n const src = fileObj.url.split('/');\r\n let url = null;\r\n if ((g.SITE.software === 'yotsuba') && Conf['404 Redirect']) {\r\n url = Redirect.to('file', {\r\n boardID: post.board.ID,\r\n filename: src[src.length - 1]\r\n });\r\n }\r\n if (!url || !Redirect.securityCheck(url)) { url = null; }\r\n\r\n if ((post.isDead || fileObj.isDead) && !ImageCommon.isFromArchive(file)) { return cb(url); }\r\n\r\n if (delay != null) { timeoutID = setTimeout((() => cb(url)), delay); }\r\n if (post.isDead || fileObj.isDead) { return; }\r\n const redirect = function() {\r\n if (!ImageCommon.isFromArchive(file)) {\r\n if (delay != null) { clearTimeout(timeoutID); }\r\n return cb(url);\r\n }\r\n };\r\n\r\n const threadJSON = g.SITE.urls.threadJSON?.(post);\r\n if (!threadJSON) { return; }\r\n var parseJSON = function(isArchiveURL) {\r\n let needle, postObj;\r\n if (this.status === 404) {\r\n let archivedThreadJSON;\r\n if (!isArchiveURL && (archivedThreadJSON = g.SITE.urls.archivedThreadJSON?.(post))) {\r\n $.ajax(archivedThreadJSON, {onloadend() { return parseJSON.call(this, true); }});\r\n } else {\r\n post.kill(!post.isClone, fileObj.index);\r\n }\r\n }\r\n if (this.status !== 200) { return redirect(); }\r\n for (postObj of this.response.posts) {\r\n if (postObj.no === post.ID) { break; }\r\n }\r\n if (postObj.no !== post.ID) {\r\n post.kill();\r\n return redirect();\r\n } else if ((needle = fileObj.docIndex, g.SITE.Build.parseJSON(postObj, post.board).filesDeleted.includes(needle))) {\r\n post.kill(true);\r\n return redirect();\r\n } else {\r\n return url = fileObj.url;\r\n }\r\n };\r\n return $.ajax(threadJSON, {onloadend() { return parseJSON.call(this); }});\r\n },\r\n\r\n // Add controls, but not until the mouse is moved over the video.\r\n addControls(video) {\r\n var handler = function() {\r\n $.off(video, 'mouseover', handler);\r\n // Hacky workaround for Firefox forever-loading bug for very short videos\r\n const t = new Date().getTime();\r\n return $.asap((() => ($.engine !== 'gecko') || ((video.readyState >= 3) && (video.currentTime <= Math.max(0.1, (video.duration - 0.5)))) || (new Date().getTime() >= (t + 1000))), () => video.controls = true);\r\n };\r\n return $.on(video, 'mouseover', handler);\r\n },\r\n\r\n // XXX Estimate whether clicks are on the video controls and should be ignored.\r\n onControls(e) {\r\n return (Conf['Show Controls'] && Conf['Click Passthrough'] && (e.target.nodeName === 'VIDEO')) ||\r\n (e.target.controls && ((e.target.getBoundingClientRect().bottom - e.clientY) < 35));\r\n },\r\n\r\n download(e) {\r\n if (this.protocol === 'blob:') { return true; }\r\n e.preventDefault();\r\n const {href, download} = this;\r\n return CrossOrigin.file(href, function(blob) {\r\n if (blob) {\r\n const a = $.el('a', {\r\n href: URL.createObjectURL(blob),\r\n download,\r\n hidden: true\r\n }\r\n );\r\n $.add(d.body, a);\r\n a.click();\r\n return $.rm(a);\r\n } else {\r\n return new Notice('warning', `Could not download ${href}`, 20);\r\n }\r\n });\r\n }\r\n};\r\nexport default ImageCommon;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport Config from \"../config/Config\";\r\nimport Get from \"../General/Get\";\r\nimport Header from \"../General/Header\";\r\nimport UI from \"../General/UI\";\r\nimport { Conf, d, doc, g } from \"../globals/globals\";\r\nimport Nav from \"../Miscellaneous/Nav\";\r\nimport $ from \"../platform/$\";\r\nimport { SECOND } from \"../platform/helpers\";\r\nimport ImageCommon from \"./ImageCommon\";\r\nimport Volume from \"./Volume\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar ImageExpand = {\r\n init() {\r\n if (!(this.enabled = Conf['Image Expansion'] && ['index', 'thread'].includes(g.VIEW))) { return; }\r\n\r\n this.EAI = $.el('a', {\r\n className: 'expand-all-shortcut',\r\n textContent: '➕︎',\r\n title: 'Expand All Images',\r\n href: 'javascript:;'\r\n }\r\n );\r\n\r\n $.on(this.EAI, 'click', this.cb.toggleAll);\r\n Header.addShortcut('expand-all', this.EAI, 520);\r\n $.on(d, 'scroll visibilitychange', this.cb.playVideos);\r\n this.videoControls = $.el('span', {className: 'video-controls'});\r\n $.extend(this.videoControls, {innerHTML: \" contract\"});\r\n\r\n return Callbacks.Post.push({\r\n name: 'Image Expansion',\r\n cb: this.node\r\n });\r\n },\r\n\r\n node() {\r\n if (!this.file || (!this.file.isImage && !this.file.isVideo)) { return; }\r\n $.on(this.file.thumbLink, 'click', ImageExpand.cb.toggle);\r\n\r\n if (this.isClone) {\r\n if (this.file.isExpanding) {\r\n // If we clone a post where the image is still loading,\r\n // make it loading in the clone too.\r\n ImageExpand.contract(this);\r\n return ImageExpand.expand(this);\r\n\r\n } else if (this.file.isExpanded && this.file.isVideo) {\r\n Volume.setup(this.file.fullImage);\r\n ImageExpand.setupVideoCB(this);\r\n return ImageExpand.setupVideo(this, !this.origin.file.fullImage?.paused || this.origin.file.wasPlaying, this.file.fullImage.controls);\r\n }\r\n\r\n } else if (ImageExpand.on && !this.isHidden && !this.isFetchedQuote &&\r\n (Conf['Expand spoilers'] || !this.file.isSpoiler) &&\r\n (Conf['Expand videos'] || !this.file.isVideo)) {\r\n return ImageExpand.expand(this);\r\n }\r\n },\r\n\r\n cb: {\r\n toggle(e) {\r\n if ($.modifiedClick(e)) { return; }\r\n const post = Get.postFromNode(this);\r\n const {file} = post;\r\n if (file.isExpanded && ImageCommon.onControls(e)) { return; }\r\n e.preventDefault();\r\n if (!Conf['Autoplay'] && file.fullImage?.paused) {\r\n return file.fullImage.play();\r\n } else {\r\n return ImageExpand.toggle(post);\r\n }\r\n },\r\n\r\n toggleAll() {\r\n let func;\r\n $.event('CloseMenu');\r\n const threadRoot = Nav.getThread();\r\n const toggle = function(post) {\r\n const {file} = post;\r\n if (!file || (!file.isImage && !file.isVideo) || !doc.contains(post.nodes.root)) { return; }\r\n if (ImageExpand.on &&\r\n ((!Conf['Expand spoilers'] && file.isSpoiler) ||\r\n (!Conf['Expand videos'] && file.isVideo) ||\r\n (Conf['Expand from here'] && (Header.getTopOf(file.thumb) < 0)) ||\r\n (Conf['Expand thread only'] && (g.VIEW === 'index') && !threadRoot?.contains(file.thumb)))) {\r\n return;\r\n }\r\n return $.queueTask(func, post);\r\n };\r\n\r\n if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) {\r\n ImageExpand.EAI.className = 'contract-all-shortcut';\r\n ImageExpand.EAI.title = 'Contract All Images';\r\n ImageExpand.EAI.textContent = '➖︎';\r\n func = ImageExpand.expand;\r\n } else {\r\n ImageExpand.EAI.className = 'expand-all-shortcut';\r\n ImageExpand.EAI.title = 'Expand All Images';\r\n ImageExpand.EAI.textContent = '➕︎';\r\n func = ImageExpand.contract;\r\n }\r\n\r\n return g.posts.forEach(function(post) {\r\n for (post of [post, ...Array.from(post.clones)]) { toggle(post); }\r\n });\r\n },\r\n\r\n playVideos() {\r\n return g.posts.forEach(function(post) {\r\n for (post of [post, ...Array.from(post.clones)]) {\r\n var {file} = post;\r\n if (!file || !file.isVideo || !file.isExpanded) { continue; }\r\n\r\n var video = file.fullImage;\r\n var visible = ($.hasAudio(video) && !video.muted) || Header.isNodeVisible(video);\r\n if (visible && file.wasPlaying) {\r\n delete file.wasPlaying;\r\n video.play();\r\n } else if (!visible && !video.paused) {\r\n file.wasPlaying = true;\r\n video.pause();\r\n }\r\n }\r\n });\r\n },\r\n\r\n setFitness() {\r\n return $[this.checked ? 'addClass' : 'rmClass'](doc, this.name.toLowerCase().replace(/\\s+/g, '-'));\r\n }\r\n },\r\n\r\n toggle(post) {\r\n if (!post.file.isExpanding && !post.file.isExpanded) {\r\n post.file.scrollIntoView = Conf['Scroll into view'];\r\n ImageExpand.expand(post);\r\n return;\r\n }\r\n\r\n ImageExpand.contract(post);\r\n\r\n if (Conf['Advance on contract']) {\r\n let next = post.nodes.root;\r\n while ((next = $.x(\"following::div[contains(@class,'postContainer')][1]\", next))) {\r\n if (!$('.stub', next) && (next.offsetHeight !== 0)) { break; }\r\n }\r\n if (next) {\r\n return Header.scrollTo(next);\r\n }\r\n }\r\n },\r\n\r\n contract(post) {\r\n let bottom, el, oldHeight, scrollY;\r\n const {file} = post;\r\n\r\n if (el = file.fullImage) {\r\n const top = Header.getTopOf(el);\r\n bottom = top + el.getBoundingClientRect().height;\r\n oldHeight = d.body.clientHeight;\r\n ({scrollY} = window);\r\n }\r\n\r\n $.rmClass(post.nodes.root, 'expanded-image');\r\n $.rmClass(file.thumb, 'expanding');\r\n $.rm(file.videoControls);\r\n file.thumbLink.href = file.url;\r\n file.thumbLink.target = '_blank';\r\n for (var x of ['isExpanding', 'isExpanded', 'videoControls', 'wasPlaying', 'scrollIntoView']) {\r\n delete file[x];\r\n }\r\n\r\n if (!el) { return; }\r\n\r\n if (doc.contains(el)) {\r\n if (bottom <= 0) {\r\n // For images entirely above us, scroll to remain in place.\r\n window.scrollBy(0, ((scrollY - window.scrollY) + d.body.clientHeight) - oldHeight);\r\n } else {\r\n // For images not above us that would be moved above us, scroll to the thumbnail.\r\n Header.scrollToIfNeeded(post.nodes.root);\r\n }\r\n if (window.scrollX > 0) {\r\n // If we have scrolled right viewing an expanded image, return to the left.\r\n window.scrollBy(-window.scrollX, 0);\r\n }\r\n }\r\n\r\n $.off(el, 'error', ImageExpand.error);\r\n ImageCommon.pushCache(el);\r\n if (file.isVideo) {\r\n ImageCommon.pause(el);\r\n for (var eventName in ImageExpand.videoCB) {\r\n var cb = ImageExpand.videoCB[eventName];\r\n $.off(el, eventName, cb);\r\n }\r\n }\r\n if (Conf['Restart when Opened']) { ImageCommon.rewind(file.thumb); }\r\n delete file.fullImage;\r\n return $.queueTask(function() {\r\n // XXX Work around Chrome/Chromium not firing mouseover on the thumbnail.\r\n if (file.isExpanding || file.isExpanded) { return; }\r\n $.rmClass(el, 'full-image');\r\n if (el.id) { return; }\r\n return $.rm(el);\r\n });\r\n },\r\n\r\n expand(post, src) {\r\n // Do not expand images of hidden/filtered replies, or already expanded pictures.\r\n let el;\r\n const {file} = post;\r\n const {thumb, thumbLink, isVideo} = file;\r\n if (post.isHidden || file.isExpanding || file.isExpanded) { return; }\r\n\r\n $.addClass(thumb, 'expanding');\r\n file.isExpanding = true;\r\n\r\n if (file.fullImage) {\r\n el = file.fullImage;\r\n } else if (ImageCommon.cache?.dataset.fileID === `${post.fullID}.${file.index}`) {\r\n el = (file.fullImage = ImageCommon.popCache());\r\n $.on(el, 'error', ImageExpand.error);\r\n if (Conf['Restart when Opened'] && (el.id !== 'ihover')) { ImageCommon.rewind(el); }\r\n el.removeAttribute('id');\r\n } else {\r\n el = (file.fullImage = $.el((isVideo ? 'video' : 'img')));\r\n el.dataset.fileID = `${post.fullID}.${file.index}`;\r\n $.on(el, 'error', ImageExpand.error);\r\n el.src = src || file.url;\r\n }\r\n\r\n el.className = 'full-image';\r\n $.after(thumb, el);\r\n\r\n if (isVideo) {\r\n // add contract link to file info\r\n if (!file.videoControls) {\r\n file.videoControls = ImageExpand.videoControls.cloneNode(true);\r\n $.add(file.text, file.videoControls);\r\n }\r\n\r\n // disable link to file so native controls can work\r\n thumbLink.removeAttribute('href');\r\n thumbLink.removeAttribute('target');\r\n\r\n el.loop = true;\r\n Volume.setup(el);\r\n ImageExpand.setupVideoCB(post);\r\n }\r\n\r\n if (!isVideo) {\r\n return $.asap((() => el.naturalHeight), () => ImageExpand.completeExpand(post));\r\n } else if (el.readyState >= el.HAVE_METADATA) {\r\n return ImageExpand.completeExpand(post);\r\n } else {\r\n return $.on(el, 'loadedmetadata', () => ImageExpand.completeExpand(post));\r\n }\r\n },\r\n\r\n completeExpand(post) {\r\n const {file} = post;\r\n if (!file.isExpanding) { return; } // contracted before the image loaded\r\n\r\n const bottom = Header.getTopOf(file.thumb) + file.thumb.getBoundingClientRect().height;\r\n const oldHeight = d.body.clientHeight;\r\n const {scrollY} = window;\r\n\r\n $.addClass(post.nodes.root, 'expanded-image');\r\n $.rmClass(file.thumb, 'expanding');\r\n file.isExpanded = true;\r\n delete file.isExpanding;\r\n\r\n // Scroll to keep our place in the thread when images are expanded above us.\r\n if (doc.contains(post.nodes.root) && (bottom <= 0)) {\r\n window.scrollBy(0, ((scrollY - window.scrollY) + d.body.clientHeight) - oldHeight);\r\n }\r\n\r\n // Scroll to display full image.\r\n if (file.scrollIntoView) {\r\n delete file.scrollIntoView;\r\n const imageBottom = Math.min(doc.clientHeight - file.fullImage.getBoundingClientRect().bottom - 25, Header.getBottomOf(file.fullImage));\r\n if (imageBottom < 0) {\r\n window.scrollBy(0, Math.min(-imageBottom, Header.getTopOf(file.fullImage)));\r\n }\r\n }\r\n\r\n if (file.isVideo) {\r\n return ImageExpand.setupVideo(post, Conf['Autoplay'], Conf['Show Controls']);\r\n }\r\n },\r\n\r\n setupVideo(post, playing, controls) {\r\n const {fullImage} = post.file;\r\n if (!playing) {\r\n fullImage.controls = controls;\r\n return;\r\n }\r\n fullImage.controls = false;\r\n $.asap((() => doc.contains(fullImage)), function() {\r\n if (!d.hidden && Header.isNodeVisible(fullImage)) {\r\n return fullImage.play();\r\n } else {\r\n return post.file.wasPlaying = true;\r\n }\r\n });\r\n if (controls) {\r\n return ImageCommon.addControls(fullImage);\r\n }\r\n },\r\n\r\n videoCB: (function() {\r\n // dragging to the left contracts the video\r\n let mousedown = false;\r\n return {\r\n mouseover() { return mousedown = false; },\r\n mousedown(e) { if (e.button === 0) { return mousedown = true; } },\r\n mouseup(e) { if (e.button === 0) { return mousedown = false; } },\r\n mouseout(e) { if (((e.buttons & 1) || mousedown) && (e.clientX <= this.getBoundingClientRect().left)) { return ImageExpand.toggle(Get.postFromNode(this)); } }\r\n };\r\n })(),\r\n\r\n setupVideoCB(post) {\r\n for (var eventName in ImageExpand.videoCB) {\r\n var cb = ImageExpand.videoCB[eventName];\r\n $.on(post.file.fullImage, eventName, cb);\r\n }\r\n if (post.file.videoControls) {\r\n return $.on(post.file.videoControls.firstElementChild, 'click', () => ImageExpand.toggle(post));\r\n }\r\n },\r\n\r\n error() {\r\n const post = Get.postFromNode(this);\r\n $.rm(this);\r\n delete post.file.fullImage;\r\n // Images can error:\r\n // - before the image started loading.\r\n // - after the image started loading.\r\n // Don't try to re-expand if it was already contracted.\r\n if (!post.file.isExpanding && !post.file.isExpanded) { return; }\r\n if (ImageCommon.decodeError(this, post.file)) {\r\n return ImageExpand.contract(post);\r\n }\r\n // Don't autoretry images from the archive.\r\n if (ImageCommon.isFromArchive(this)) {\r\n return ImageExpand.contract(post);\r\n }\r\n return ImageCommon.error(this, post, post.file, 10 * SECOND, function(URL) {\r\n if (post.file.isExpanding || post.file.isExpanded) {\r\n ImageExpand.contract(post);\r\n if (URL) { return ImageExpand.expand(post, URL); }\r\n }\r\n });\r\n },\r\n\r\n menu: {\r\n init() {\r\n if (!ImageExpand.enabled) { return; }\r\n\r\n const el = $.el('span', {\r\n textContent: 'Image Expansion',\r\n className: 'image-expansion-link'\r\n }\r\n );\r\n\r\n const {createSubEntry} = ImageExpand.menu;\r\n const subEntries = [];\r\n for (var name in Config.imageExpansion) {\r\n var conf = Config.imageExpansion[name];\r\n subEntries.push(createSubEntry(name, conf[1]));\r\n }\r\n\r\n return Header.menu.addEntry({\r\n el,\r\n order: 105,\r\n subEntries\r\n });\r\n },\r\n\r\n createSubEntry(name, desc) {\r\n const label = UI.checkbox(name, name);\r\n label.title = desc;\r\n const input = label.firstElementChild;\r\n if (['Fit width', 'Fit height'].includes(name)) {\r\n $.on(input, 'change', ImageExpand.cb.setFitness);\r\n }\r\n $.event('change', null, input);\r\n $.on(input, 'change', $.cb.checked);\r\n return {el: label};\r\n }\r\n }\r\n};\r\nexport default ImageExpand;\r\n",null,"import Callbacks from \"../classes/Callbacks\";\r\nimport UI from \"../General/UI\";\r\nimport { g, Conf } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar Menu = {\r\n init() {\r\n if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu']) { return; }\r\n\r\n this.button = $.el('a', {\r\n className: 'menu-button',\r\n href: 'javascript:;'\r\n }\r\n );\r\n\r\n $.extend(this.button, {textContent: \"🞃\"});\r\n\r\n this.menu = new UI.Menu('post');\r\n Callbacks.Post.push({\r\n name: 'Menu',\r\n cb: this.node\r\n });\r\n\r\n return Callbacks.CatalogThread.push({\r\n name: 'Menu',\r\n cb: this.catalogNode\r\n });\r\n },\r\n\r\n node() {\r\n if (this.isClone) {\r\n const button = $('.menu-button', this.nodes.info);\r\n $.rmClass(button, 'active');\r\n $.rm($('.dialog', this.nodes.info));\r\n Menu.makeButton(this, button);\r\n return;\r\n }\r\n return $.add(this.nodes.info, Menu.makeButton(this));\r\n },\r\n\r\n catalogNode() {\r\n return $.after(this.nodes.icons, Menu.makeButton(this.thread.OP));\r\n },\r\n\r\n makeButton(post, button) {\r\n if (!button) { button = Menu.button.cloneNode(true); }\r\n $.on(button, 'click', function(e) {\r\n return Menu.menu.toggle(e, this, post);\r\n });\r\n return button;\r\n }\r\n};\r\nexport default Menu;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport { g } from \"../globals/globals\";\r\nimport { dict } from \"../platform/helpers\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar Recursive = {\r\n recursives: dict(),\r\n init() {\r\n if (!['index', 'thread'].includes(g.VIEW)) { return; }\r\n return Callbacks.Post.push({\r\n name: 'Recursive',\r\n cb: this.node\r\n });\r\n },\r\n\r\n node() {\r\n if (this.isClone || this.isFetchedQuote) { return; }\r\n for (var quote of this.quotes) {\r\n var obj;\r\n if ((obj = Recursive.recursives[quote])) {\r\n for (var i = 0; i < obj.recursives.length; i++) {\r\n var recursive = obj.recursives[i];\r\n recursive(this, ...Array.from(obj.args[i]));\r\n }\r\n }\r\n }\r\n },\r\n\r\n add(recursive, post, ...args) {\r\n const obj = Recursive.recursives[post.fullID] || (Recursive.recursives[post.fullID] = {\r\n recursives: [],\r\n args: []\r\n });\r\n obj.recursives.push(recursive);\r\n return obj.args.push(args);\r\n },\r\n\r\n rm(recursive, post) {\r\n let obj;\r\n if (!(obj = Recursive.recursives[post.fullID])) { return; }\r\n for (let i = 0; i < obj.recursives.length; i++) {\r\n var rec = obj.recursives[i];\r\n if (rec === recursive) {\r\n obj.recursives.splice(i, 1);\r\n obj.args.splice(i, 1);\r\n }\r\n }\r\n },\r\n\r\n apply(recursive, post, ...args) {\r\n const {fullID} = post;\r\n return g.posts.forEach(function(post) {\r\n if (post.quotes.includes(fullID)) {\r\n return recursive(post, ...Array.from(args));\r\n }\r\n });\r\n }\r\n};\r\nexport default Recursive;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport DataBoard from \"../classes/DataBoard\";\r\nimport Get from \"../General/Get\";\r\nimport UI from \"../General/UI\";\r\nimport { g, Conf, doc } from \"../globals/globals\";\r\nimport Menu from \"../Menu/Menu\";\r\nimport $ from \"../platform/$\";\r\nimport Recursive from \"./Recursive\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar PostHiding = {\r\n init() {\r\n if (!['index', 'thread'].includes(g.VIEW) || (!Conf['Reply Hiding Buttons'] && !(Conf['Menu'] && Conf['Reply Hiding Link']))) { return; }\r\n\r\n if (Conf['Reply Hiding Buttons']) {\r\n $.addClass(doc, \"reply-hide\");\r\n }\r\n\r\n this.db = new DataBoard('hiddenPosts');\r\n return Callbacks.Post.push({\r\n name: 'Reply Hiding',\r\n cb: this.node\r\n });\r\n },\r\n\r\n isHidden(boardID, threadID, postID) {\r\n return !!(PostHiding.db && PostHiding.db.get({boardID, threadID, postID}));\r\n },\r\n\r\n node() {\r\n let data, sa;\r\n if (!this.isReply || this.isClone || this.isFetchedQuote) { return; }\r\n\r\n if (data = PostHiding.db.get({boardID: this.board.ID, threadID: this.thread.ID, postID: this.ID})) {\r\n if (data.thisPost) {\r\n PostHiding.hide(this, data.makeStub, data.hideRecursively);\r\n } else {\r\n Recursive.apply(PostHiding.hide, this, data.makeStub, true);\r\n Recursive.add(PostHiding.hide, this, data.makeStub, true);\r\n }\r\n }\r\n\r\n if (!Conf['Reply Hiding Buttons']) { return; }\r\n\r\n const button = PostHiding.makeButton(this, 'hide');\r\n if (sa = g.SITE.selectors.sideArrows) {\r\n const sideArrows = $(sa, this.nodes.root);\r\n $.replace(sideArrows.firstChild, button);\r\n return sideArrows.className = 'replacedSideArrows';\r\n } else {\r\n return $.prepend(this.nodes.info, button);\r\n }\r\n },\r\n\r\n menu: {\r\n init() {\r\n if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu'] || !Conf['Reply Hiding Link']) { return; }\r\n\r\n // Hide\r\n let div = $.el('div', {\r\n className: 'hide-reply-link',\r\n textContent: 'Hide'\r\n }\r\n );\r\n\r\n let apply = $.el('a', {\r\n textContent: 'Apply',\r\n href: 'javascript:;'\r\n }\r\n );\r\n $.on(apply, 'click', PostHiding.menu.hide);\r\n\r\n let thisPost = UI.checkbox('thisPost', 'This post', true);\r\n let replies = UI.checkbox('replies', 'Hide replies', Conf['Recursive Hiding']);\r\n const makeStub = UI.checkbox('makeStub', 'Make stub', Conf['Stubs']);\r\n\r\n Menu.menu.addEntry({\r\n el: div,\r\n order: 20,\r\n open(post) {\r\n if (!post.isReply || post.isClone || post.isHidden) {\r\n return false;\r\n }\r\n PostHiding.menu.post = post;\r\n return true;\r\n },\r\n subEntries: [\r\n {el: apply}\r\n ,\r\n {el: thisPost}\r\n ,\r\n {el: replies}\r\n ,\r\n {el: makeStub}\r\n ]});\r\n\r\n // Show\r\n div = $.el('div', {\r\n className: 'show-reply-link',\r\n textContent: 'Show'\r\n }\r\n );\r\n\r\n apply = $.el('a', {\r\n textContent: 'Apply',\r\n href: 'javascript:;'\r\n }\r\n );\r\n $.on(apply, 'click', PostHiding.menu.show);\r\n\r\n thisPost = UI.checkbox('thisPost', 'This post', false);\r\n replies = UI.checkbox('replies', 'Show replies', false);\r\n const hideStubLink = $.el('a', {\r\n textContent: 'Hide stub',\r\n href: 'javascript:;'\r\n }\r\n );\r\n $.on(hideStubLink, 'click', PostHiding.menu.hideStub);\r\n\r\n Menu.menu.addEntry({\r\n el: div,\r\n order: 20,\r\n open(post) {\r\n let data;\r\n if (!post.isReply || post.isClone || !post.isHidden) {\r\n return false;\r\n }\r\n if (!(data = PostHiding.db.get({boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID}))) {\r\n return false;\r\n }\r\n PostHiding.menu.post = post;\r\n thisPost.firstChild.checked = post.isHidden;\r\n replies.firstChild.checked = (data?.hideRecursively != null) ? data.hideRecursively : Conf['Recursive Hiding'];\r\n return true;\r\n },\r\n subEntries: [\r\n {el: apply}\r\n ,\r\n {el: thisPost}\r\n ,\r\n {el: replies}\r\n ]});\r\n\r\n return Menu.menu.addEntry({\r\n el: hideStubLink,\r\n order: 15,\r\n open(post) {\r\n let data;\r\n if (!post.isReply || post.isClone || !post.isHidden) {\r\n return false;\r\n }\r\n if (!(data = PostHiding.db.get({boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID}))) {\r\n return false;\r\n }\r\n return PostHiding.menu.post = post;\r\n }\r\n });\r\n },\r\n\r\n hide() {\r\n const parent = this.parentNode;\r\n const thisPost = $('input[name=thisPost]', parent).checked;\r\n const replies = $('input[name=replies]', parent).checked;\r\n const makeStub = $('input[name=makeStub]', parent).checked;\r\n const {post} = PostHiding.menu;\r\n if (thisPost) {\r\n PostHiding.hide(post, makeStub, replies);\r\n } else if (replies) {\r\n Recursive.apply(PostHiding.hide, post, makeStub, true);\r\n Recursive.add(PostHiding.hide, post, makeStub, true);\r\n } else {\r\n return;\r\n }\r\n PostHiding.saveHiddenState(post, true, thisPost, makeStub, replies);\r\n return $.event('CloseMenu');\r\n },\r\n\r\n show() {\r\n let data;\r\n const parent = this.parentNode;\r\n const thisPost = $('input[name=thisPost]', parent).checked;\r\n const replies = $('input[name=replies]', parent).checked;\r\n const {post} = PostHiding.menu;\r\n if (thisPost) {\r\n PostHiding.show(post, replies);\r\n } else if (replies) {\r\n Recursive.apply(PostHiding.show, post, true);\r\n Recursive.rm(PostHiding.hide, post, true);\r\n } else {\r\n return;\r\n }\r\n if (data = PostHiding.db.get({boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID})) {\r\n PostHiding.saveHiddenState(post, !(thisPost && replies), !thisPost, data.makeStub, !replies);\r\n }\r\n return $.event('CloseMenu');\r\n },\r\n hideStub() {\r\n let data;\r\n const {post} = PostHiding.menu;\r\n if (data = PostHiding.db.get({boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID})) {\r\n PostHiding.show(post, data.hideRecursively);\r\n PostHiding.hide(post, false, data.hideRecursively);\r\n PostHiding.saveHiddenState(post, true, true, false, data.hideRecursively);\r\n }\r\n $.event('CloseMenu');\r\n }\r\n },\r\n\r\n makeButton(post, type) {\r\n const span = $.el('span', {\r\n textContent: type === 'hide' ? '➖︎' : '➕︎',\r\n });\r\n const a = $.el('a', {\r\n className: `${type}-reply-button`,\r\n href: 'javascript:;'\r\n }\r\n );\r\n $.add(a, span);\r\n $.on(a, 'click', PostHiding.toggle);\r\n return a;\r\n },\r\n\r\n saveHiddenState(post, isHiding, thisPost, makeStub, hideRecursively) {\r\n const data = {\r\n boardID: post.board.ID,\r\n threadID: post.thread.ID,\r\n postID: post.ID\r\n };\r\n if (isHiding) {\r\n data.val = {\r\n thisPost: thisPost !== false, // undefined -> true\r\n makeStub,\r\n hideRecursively\r\n };\r\n return PostHiding.db.set(data);\r\n } else {\r\n return PostHiding.db.delete(data);\r\n }\r\n },\r\n\r\n toggle() {\r\n const post = Get.postFromNode(this);\r\n PostHiding[(post.isHidden ? 'show' : 'hide')](post);\r\n return PostHiding.saveHiddenState(post, post.isHidden);\r\n },\r\n\r\n hide(post, makeStub=Conf['Stubs'], hideRecursively=Conf['Recursive Hiding']) {\r\n if (post.isHidden) { return; }\r\n post.isHidden = true;\r\n\r\n if (hideRecursively) {\r\n Recursive.apply(PostHiding.hide, post, makeStub, true);\r\n Recursive.add(PostHiding.hide, post, makeStub, true);\r\n }\r\n\r\n for (var quotelink of Get.allQuotelinksLinkingTo(post)) {\r\n $.addClass(quotelink, 'filtered');\r\n }\r\n\r\n if (!makeStub) {\r\n post.nodes.root.hidden = true;\r\n return;\r\n }\r\n\r\n const a = PostHiding.makeButton(post, 'show');\r\n $.add(a, $.tn(` ${post.info.nameBlock}`));\r\n post.nodes.stub = $.el('div',\r\n {className: 'stub'});\r\n $.add(post.nodes.stub, a);\r\n if (Conf['Menu']) {\r\n $.add(post.nodes.stub, Menu.makeButton(post));\r\n }\r\n return $.prepend(post.nodes.root, post.nodes.stub);\r\n },\r\n\r\n show(post, showRecursively=Conf['Recursive Hiding']) {\r\n if (post.nodes.stub) {\r\n $.rm(post.nodes.stub);\r\n delete post.nodes.stub;\r\n } else {\r\n post.nodes.root.hidden = false;\r\n }\r\n post.isHidden = false;\r\n if (showRecursively) {\r\n Recursive.apply(PostHiding.show, post, true);\r\n Recursive.rm(PostHiding.hide, post);\r\n }\r\n for (var quotelink of Get.allQuotelinksLinkingTo(post)) {\r\n $.rmClass(quotelink, 'filtered');\r\n }\r\n }\r\n};\r\nexport default PostHiding;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport Post from \"../classes/Post\";\r\nimport Index from \"../General/Index\";\r\nimport { g, Conf, d, doc } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\nimport { DAY, HOUR, MINUTE, SECOND } from \"../platform/helpers\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS205: Consider reworking code to avoid use of IIFEs\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar RelativeDates = {\r\n INTERVAL: 30000,\r\n\r\n init() {\r\n if (\r\n (['index', 'thread', 'archive'].includes(g.VIEW) && Conf['Relative Post Dates'] && !Conf['Relative Date Title']) ||\r\n Index.enabled\r\n ) {\r\n this.flush();\r\n $.on(d, 'visibilitychange PostsInserted', this.flush);\r\n }\r\n\r\n if (Conf['Relative Post Dates']) {\r\n return Callbacks.Post.push({\r\n name: 'Relative Post Dates',\r\n cb: this.node\r\n });\r\n }\r\n },\r\n\r\n node() {\r\n if (!this.info.date) { return; }\r\n const dateEl = this.nodes.date;\r\n if (Conf['Relative Date Title']) {\r\n $.on(dateEl, 'mouseover', () => RelativeDates.hover(this));\r\n return;\r\n }\r\n if (this.isClone) { return; }\r\n\r\n // Show original absolute time as tooltip so users can still know exact times\r\n // Since \"Time Formatting\" runs its `node` before us, the title tooltip will\r\n // pick up the user-formatted time instead of 4chan time when enabled.\r\n dateEl.title = dateEl.textContent;\r\n\r\n return RelativeDates.update(this);\r\n },\r\n\r\n // diff is milliseconds from now.\r\n relative(diff, now, date, abbrev) {\r\n let number;\r\n let unit = (() => {\r\n if ((number = (diff / DAY)) >= 1) {\r\n const years = now.getFullYear() - date.getFullYear();\r\n let months = now.getMonth() - date.getMonth();\r\n const days = now.getDate() - date.getDate();\r\n if (years > 1) {\r\n number = years - ((months < 0) || ((months === 0) && (days < 0)));\r\n return 'year';\r\n } else if ((years === 1) && ((months > 0) || ((months === 0) && (days >= 0)))) {\r\n number = years;\r\n return 'year';\r\n } else if ((months = months + (12*years)) > 1) {\r\n number = months - (days < 0);\r\n return 'month';\r\n } else if ((months === 1) && (days >= 0)) {\r\n number = months;\r\n return 'month';\r\n } else {\r\n return 'day';\r\n }\r\n } else if ((number = (diff / HOUR)) >= 1) {\r\n return 'hour';\r\n } else if ((number = (diff / MINUTE)) >= 1) {\r\n return 'minute';\r\n } else {\r\n // prevent \"-1 seconds ago\"\r\n number = Math.max(0, diff) / SECOND;\r\n return 'second';\r\n }\r\n })();\r\n\r\n const rounded = Math.round(number);\r\n\r\n if (abbrev) {\r\n unit = unit === 'month' ? 'mo' : unit[0];\r\n } else {\r\n if (rounded !== 1) { unit += 's'; } // pluralize\r\n }\r\n\r\n if (abbrev) { return `${rounded}${unit}`; } else { return `${rounded} ${unit} ago`; }\r\n },\r\n\r\n // Changing all relative dates as soon as possible incurs many annoying\r\n // redraws and scroll stuttering. Thus, sacrifice accuracy for UX/CPU economy,\r\n // and perform redraws when the DOM is otherwise being manipulated (and scroll\r\n // stuttering won't be noticed), falling back to INTERVAL while the page\r\n // is visible.\r\n //\r\n // Each individual dateTime element will add its update() function to the stale list\r\n // when it is to be called.\r\n stale: [],\r\n flush() {\r\n // No point in changing the dates until the user sees them.\r\n if (d.hidden) { return; }\r\n\r\n const now = new Date();\r\n for (var data of RelativeDates.stale) { RelativeDates.update(data, now); }\r\n RelativeDates.stale = [];\r\n\r\n // Reset automatic flush.\r\n clearTimeout(RelativeDates.timeout);\r\n return RelativeDates.timeout = setTimeout(RelativeDates.flush, RelativeDates.INTERVAL);\r\n },\r\n\r\n hover(post) {\r\n const {\r\n date\r\n } = post.info;\r\n const now = new Date();\r\n const diff = now - date;\r\n return post.nodes.date.title = RelativeDates.relative(diff, now, date);\r\n },\r\n\r\n // `update()`, when called from `flush()`, updates the elements,\r\n // and re-calls `setOwnTimeout()` to re-add `data` to the stale list later.\r\n update(data, now) {\r\n let abbrev, date;\r\n const isPost = data instanceof Post;\r\n if (isPost) {\r\n ({\r\n date\r\n } = data.info);\r\n abbrev = false;\r\n } else {\r\n date = new Date(+data.dataset.utc);\r\n abbrev = !!data.dataset.abbrev;\r\n }\r\n if (!now) { now = new Date(); }\r\n const diff = now - date;\r\n const relative = RelativeDates.relative(diff, now, date, abbrev);\r\n if (isPost) {\r\n for (var singlePost of [data].concat(data.clones)) {\r\n singlePost.nodes.date.firstChild.textContent = relative;\r\n }\r\n } else {\r\n data.firstChild.textContent = relative;\r\n }\r\n return RelativeDates.setOwnTimeout(diff, data);\r\n },\r\n\r\n setOwnTimeout(diff, data) {\r\n const delay = diff < MINUTE ?\r\n SECOND - ((diff + (SECOND / 2)) % SECOND)\r\n : diff < HOUR ?\r\n MINUTE - ((diff + (MINUTE / 2)) % MINUTE)\r\n : diff < DAY ?\r\n HOUR - ((diff + (HOUR / 2)) % HOUR)\r\n :\r\n DAY - ((diff + (DAY / 2)) % DAY);\r\n return setTimeout(RelativeDates.markStale, delay, data);\r\n },\r\n\r\n markStale(data) {\r\n if (RelativeDates.stale.includes(data)) { return; } // We can call RelativeDates.update() multiple times.\r\n if (data instanceof Post && !g.posts.get(data.fullID)) { return; } // collected post.\r\n if (data instanceof Element && !doc.contains(data)) { return; } // removed catalog reply.\r\n return RelativeDates.stale.push(data);\r\n }\r\n};\r\nexport default RelativeDates;\r\n","import Notice from \"../classes/Notice\";\r\nimport { g, Conf } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\nimport { dict, HOUR } from \"../platform/helpers\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS104: Avoid inline assignments\r\n * DS205: Consider reworking code to avoid use of IIFEs\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar BoardConfig = {\r\n cbs: [],\r\n\r\n init() {\r\n let middle;\r\n if (g.SITE.software !== 'yotsuba') { return; }\r\n const now = Date.now();\r\n if (now - (2 * HOUR) >= ((middle = Conf['boardConfig'].lastChecked || 0)) || middle > now) {\r\n return $.ajax(`${location.protocol}//a.4cdn.org/boards.json`,\r\n {onloadend: this.load});\r\n } else {\r\n const {boards} = Conf['boardConfig'];\r\n return this.set(boards);\r\n }\r\n },\r\n\r\n load() {\r\n let boards;\r\n if ((this.status === 200) && this.response && this.response.boards) {\r\n boards = dict();\r\n for (var board of this.response.boards) {\r\n boards[board.board] = board;\r\n }\r\n $.set('boardConfig', {boards, lastChecked: Date.now()});\r\n } else {\r\n ({boards} = Conf['boardConfig']);\r\n const err = (() => { switch (this.status) {\r\n case 0: return 'Connection Error';\r\n case 200: return 'Invalid Data';\r\n default: return `Error ${this.statusText} (${this.status})`;\r\n } })();\r\n new Notice('warning', `Failed to load board configuration. ${err}`, 20);\r\n }\r\n return BoardConfig.set(boards);\r\n },\r\n\r\n set(boards) {\r\n this.boards = boards;\r\n for (var ID in g.boards) {\r\n var board = g.boards[ID];\r\n board.config = this.boards[ID] || {};\r\n }\r\n for (var cb of this.cbs) {\r\n $.queueTask(cb);\r\n }\r\n },\r\n\r\n ready(cb) {\r\n if (this.boards) {\r\n return cb();\r\n } else {\r\n return this.cbs.push(cb);\r\n }\r\n },\r\n\r\n sfwBoards(sfw) {\r\n return (() => {\r\n const result = [];\r\n const object = this.boards || Conf['boardConfig'].boards;\r\n for (var board in object) {\r\n var data = object[board];\r\n if (!!data.ws_board === sfw) {\r\n result.push(board);\r\n }\r\n }\r\n return result;\r\n })();\r\n },\r\n\r\n isSFW(board) {\r\n return !!(this.boards || Conf['boardConfig'].boards)[board]?.ws_board;\r\n },\r\n\r\n domain(board) {\r\n return `boards.${BoardConfig.isSFW(board) ? '4channel' : '4chan'}.org`;\r\n },\r\n\r\n isArchived(board) {\r\n // assume archive exists if no data available to prevent cleaning of archived threads\r\n const data = (this.boards || Conf['boardConfig'].boards)[board];\r\n return !data || data.is_archived;\r\n },\r\n\r\n noAudio(boardID) {\r\n if (g.SITE.software !== 'yotsuba') { return false; }\r\n const boards = this.boards || Conf['boardConfig'].boards;\r\n return boards && boards[boardID] && !boards[boardID].webm_audio;\r\n },\r\n\r\n title(boardID) {\r\n return (this.boards || Conf['boardConfig'].boards)?.[boardID]?.title || '';\r\n }\r\n};\r\nexport default BoardConfig;\r\n","import BoardConfig from \"../General/BoardConfig\";\r\nimport { d, g } from \"../globals/globals\";\r\nimport SimpleDict from \"./SimpleDict\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nexport default class Board {\r\n toString() { return this.ID; }\r\n\r\n constructor(ID) {\r\n this.ID = ID;\r\n this.boardID = this.ID;\r\n this.siteID = g.SITE.ID;\r\n this.threads = new SimpleDict();\r\n this.posts = new SimpleDict();\r\n this.config = BoardConfig.boards?.[this.ID] || {};\r\n\r\n g.boards[this] = this;\r\n }\r\n\r\n cooldowns() {\r\n const c2 = (this.config || {}).cooldowns || {};\r\n const c = {\r\n thread: c2.threads || 0,\r\n reply: c2.replies || 0,\r\n image: c2.images || 0,\r\n thread_global: 300 // inter-board thread cooldown\r\n };\r\n // Pass users have reduced cooldowns.\r\n if (d.cookie.indexOf('pass_enabled=1') >= 0) {\r\n for (var key of ['reply', 'image']) {\r\n c[key] = Math.ceil(c[key] / 2);\r\n }\r\n }\r\n return c;\r\n }\r\n}\r\n","import { d } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nconst PostRedirect = {\r\n init() {\r\n return $.on(d, 'QRPostSuccessful', e => {\r\n if (!e.detail.redirect) { return; }\r\n this.event = e;\r\n this.delays = 0;\r\n return $.queueTask(() => {\r\n if ((e === this.event) && (this.delays === 0)) {\r\n return location.href = e.detail.redirect;\r\n }\r\n });\r\n });\r\n },\r\n\r\n delays: 0,\r\n\r\n delay() {\r\n if (!this.event) { return null; }\r\n const e = this.event;\r\n this.delays++;\r\n return () => {\r\n if (e !== this.event) { return; }\r\n this.delays--;\r\n if (this.delays === 0) {\r\n return location.href = e.detail.redirect;\r\n }\r\n };\r\n }\r\n};\r\nexport default PostRedirect;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport Get from \"../General/Get\";\r\nimport { g, Conf } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\nimport $$ from \"../platform/$$\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar ExpandComment = {\r\n init() {\r\n if ((g.VIEW !== 'index') || !Conf['Comment Expansion'] || Conf['JSON Index']) { return; }\r\n\r\n return Callbacks.Post.push({\r\n name: 'Comment Expansion',\r\n cb: this.node\r\n });\r\n },\r\n\r\n node() {\r\n let a;\r\n if (a = $('.abbr > a:not([onclick])', this.nodes.comment)) {\r\n return $.on(a, 'click', ExpandComment.cb);\r\n }\r\n },\r\n\r\n callbacks: [],\r\n\r\n cb(e) {\r\n e.preventDefault();\r\n return ExpandComment.expand(Get.postFromNode(this));\r\n },\r\n\r\n expand(post) {\r\n let a;\r\n if (post.nodes.longComment && !post.nodes.longComment.parentNode) {\r\n $.replace(post.nodes.shortComment, post.nodes.longComment);\r\n post.nodes.comment = post.nodes.longComment;\r\n return;\r\n }\r\n if (!(a = $('.abbr > a', post.nodes.comment))) { return; }\r\n a.textContent = `Post No.${post} Loading...`;\r\n return $.cache(g.SITE.urls.threadJSON({boardID: post.boardID, threadID: post.threadID}), function() { return ExpandComment.parse(this, a, post); });\r\n },\r\n\r\n contract(post) {\r\n if (!post.nodes.shortComment) { return; }\r\n const a = $('.abbr > a', post.nodes.shortComment);\r\n a.textContent = 'here';\r\n $.replace(post.nodes.longComment, post.nodes.shortComment);\r\n return post.nodes.comment = post.nodes.shortComment;\r\n },\r\n\r\n parse(req, a, post) {\r\n let postObj, spoilerRange;\r\n const {status} = req;\r\n if (![200, 304].includes(status)) {\r\n a.textContent = status ? `Error ${req.statusText} (${status})` : 'Connection Error';\r\n return;\r\n }\r\n\r\n const {\r\n posts\r\n } = req.response;\r\n if (spoilerRange = posts[0].custom_spoiler) {\r\n g.SITE.Build.spoilerRange[g.BOARD] = spoilerRange;\r\n }\r\n\r\n for (postObj of posts) {\r\n if (postObj.no === post.ID) { break; }\r\n }\r\n if (postObj.no !== post.ID) {\r\n a.textContent = `Post No.${post} not found.`;\r\n return;\r\n }\r\n\r\n const {comment} = post.nodes;\r\n const clone = comment.cloneNode(false);\r\n clone.innerHTML = postObj.com;\r\n // Fix pathnames\r\n for (var quote of $$('.quotelink', clone)) {\r\n var href = quote.getAttribute('href');\r\n if (href[0] === '/') { continue; } // Cross-board quote, or board link\r\n if (href[0] === '#') {\r\n quote.href = `${a.pathname.split(/\\/+/).splice(0,4).join('/')}${href}`;\r\n } else {\r\n quote.href = `${a.pathname.split(/\\/+/).splice(0,3).join('/')}/${href}`;\r\n }\r\n }\r\n post.nodes.shortComment = comment;\r\n $.replace(comment, clone);\r\n post.nodes.comment = (post.nodes.longComment = clone);\r\n post.parseComment();\r\n post.parseQuotes();\r\n\r\n for (var callback of ExpandComment.callbacks) {\r\n callback.call(post);\r\n }\r\n }\r\n};\r\nexport default ExpandComment;;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport DataBoard from \"../classes/DataBoard\";\r\nimport Notice from \"../classes/Notice\";\r\nimport Get from \"../General/Get\";\r\nimport Header from \"../General/Header\";\r\nimport { Conf, d, doc, g } from \"../globals/globals\";\r\nimport Menu from \"../Menu/Menu\";\r\nimport ExpandComment from \"../Miscellaneous/ExpandComment\";\r\nimport $ from \"../platform/$\";\r\nimport $$ from \"../platform/$$\";\r\nimport PostRedirect from \"../Posting/PostRedirect\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar QuoteYou = {\r\n init() {\r\n if (!Conf['Remember Your Posts']) { return; }\r\n\r\n this.db = new DataBoard('yourPosts');\r\n $.sync('Remember Your Posts', enabled => Conf['Remember Your Posts'] = enabled);\r\n $.on(d, 'QRPostSuccessful', function(e) {\r\n const cb = PostRedirect.delay();\r\n return $.get('Remember Your Posts', Conf['Remember Your Posts'], function(items) {\r\n if (!items['Remember Your Posts']) { return; }\r\n const {boardID, threadID, postID} = e.detail;\r\n return QuoteYou.db.set({boardID, threadID, postID, val: true}, cb);\r\n });\r\n });\r\n\r\n if (!['index', 'thread', 'archive'].includes(g.VIEW)) { return; }\r\n\r\n if (Conf['Highlight Own Posts']) {\r\n $.addClass(doc, 'highlight-own');\r\n }\r\n\r\n if (Conf['Highlight Posts Quoting You']) {\r\n $.addClass(doc, 'highlight-you');\r\n }\r\n\r\n if (Conf['Comment Expansion']) {\r\n ExpandComment.callbacks.push(this.node);\r\n }\r\n\r\n // \\u00A0 is nbsp\r\n this.mark = $.el('span', {\r\n textContent: '\\u00A0(You)',\r\n className: 'qmark-you'\r\n }\r\n );\r\n Callbacks.Post.push({\r\n name: 'Mark Quotes of You',\r\n cb: this.node\r\n });\r\n\r\n return QuoteYou.menu.init();\r\n },\r\n\r\n isYou(post) {\r\n return !!QuoteYou.db?.get({\r\n boardID: post.boardID,\r\n threadID: post.threadID,\r\n postID: post.ID\r\n });\r\n },\r\n\r\n node() {\r\n if (this.isClone) { return; }\r\n\r\n if (QuoteYou.isYou(this)) {\r\n $.addClass(this.nodes.root, 'yourPost');\r\n }\r\n\r\n // Stop there if there's no quotes in that post.\r\n if (!this.quotes.length) { return; }\r\n\r\n for (var quotelink of this.nodes.quotelinks) {\r\n if (QuoteYou.db.get(Get.postDataFromLink(quotelink))) {\r\n if (Conf['Mark Quotes of You']) { $.add(quotelink, QuoteYou.mark.cloneNode(true)); }\r\n $.addClass(quotelink, 'you');\r\n $.addClass(this.nodes.root, 'quotesYou');\r\n }\r\n }\r\n },\r\n\r\n menu: {\r\n init() {\r\n const label = $.el('label',\r\n {className: 'toggle-you'}\r\n ,\r\n {innerHTML: ' You'});\r\n const input = $('input', label);\r\n $.on(input, 'change', QuoteYou.menu.toggle);\r\n return Menu.menu?.addEntry({\r\n el: label,\r\n order: 80,\r\n open(post) {\r\n QuoteYou.menu.post = (post.origin || post);\r\n input.checked = QuoteYou.isYou(post);\r\n return true;\r\n }\r\n });\r\n },\r\n\r\n toggle() {\r\n const {post} = QuoteYou.menu;\r\n const data = {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID, val: true};\r\n if (this.checked) {\r\n QuoteYou.db.set(data);\r\n } else {\r\n QuoteYou.db.delete(data);\r\n }\r\n for (var clone of [post].concat(post.clones)) {\r\n clone.nodes.root.classList.toggle('yourPost', this.checked);\r\n }\r\n for (var quotelink of Get.allQuotelinksLinkingTo(post)) {\r\n if (this.checked) {\r\n if (Conf['Mark Quotes of You']) { $.add(quotelink, QuoteYou.mark.cloneNode(true)); }\r\n } else {\r\n $.rm($('.qmark-you', quotelink));\r\n }\r\n quotelink.classList.toggle('you', this.checked);\r\n if ($.hasClass(quotelink, 'quotelink')) {\r\n var quoter = Get.postFromNode(quotelink).nodes.root;\r\n quoter.classList.toggle('quotesYou', !!$('.quotelink.you', quoter));\r\n }\r\n }\r\n }\r\n },\r\n\r\n cb: {\r\n seek(type) {\r\n let highlighted, post;\r\n let result;\r\n const {highlight} = g.SITE.classes;\r\n if (highlighted = $(`.${highlight}`)) { $.rmClass(highlighted, highlight); }\r\n\r\n if (!QuoteYou.lastRead || !doc.contains(QuoteYou.lastRead) || !$.hasClass(QuoteYou.lastRead, 'quotesYou')) {\r\n if (!(post = (QuoteYou.lastRead = $('.quotesYou')))) {\r\n new Notice('warning', 'No posts are currently quoting you, loser.', 20);\r\n return;\r\n }\r\n if (QuoteYou.cb.scroll(post)) { return; }\r\n } else {\r\n post = QuoteYou.lastRead;\r\n }\r\n\r\n const str = `${type}::div[contains(@class,'quotesYou')]`;\r\n\r\n while (post = (result = $.X(str, post)).snapshotItem(type === 'preceding' ? result.snapshotLength - 1 : 0)) {\r\n if (QuoteYou.cb.scroll(post)) { return; }\r\n }\r\n\r\n const posts = $$('.quotesYou');\r\n return QuoteYou.cb.scroll(posts[type === 'following' ? 0 : posts.length - 1]);\r\n },\r\n\r\n scroll(root) {\r\n const post = Get.postFromRoot(root);\r\n if (!post.nodes.post.getBoundingClientRect().height) {\r\n return false;\r\n } else {\r\n QuoteYou.lastRead = root;\r\n location.href = Get.url('post', post);\r\n Header.scrollTo(post.nodes.post);\r\n if (post.isReply) {\r\n const sel = `${g.SITE.selectors.postContainer}${g.SITE.selectors.highlightable.reply}`;\r\n let node = post.nodes.root;\r\n if (!node.matches(sel)) { node = $(sel, node); }\r\n $.addClass(node, g.SITE.classes.highlight);\r\n }\r\n return true;\r\n }\r\n }\r\n }\r\n};\r\nexport default QuoteYou;\r\n","/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nexport default class RandomAccessList {\r\n constructor(items) {\r\n this.length = 0;\r\n if (items) { for (var item of items) { this.push(item); } }\r\n }\r\n\r\n push(data) {\r\n let item;\r\n let {ID} = data;\r\n if (!ID) { ID = data.id; }\r\n if (this[ID]) { return; }\r\n const {last} = this;\r\n this[ID] = (item = {\r\n prev: last,\r\n next: null,\r\n data,\r\n ID\r\n });\r\n item.prev = last;\r\n this.last = last ?\r\n (last.next = item)\r\n :\r\n (this.first = item);\r\n return this.length++;\r\n }\r\n\r\n before(root, item) {\r\n if ((item.next === root) || (item === root)) { return; }\r\n\r\n this.rmi(item);\r\n\r\n const {prev} = root;\r\n root.prev = item;\r\n item.next = root;\r\n item.prev = prev;\r\n if (prev) {\r\n return prev.next = item;\r\n } else {\r\n return this.first = item;\r\n }\r\n }\r\n\r\n after(root, item) {\r\n if ((item.prev === root) || (item === root)) { return; }\r\n\r\n this.rmi(item);\r\n\r\n const {next} = root;\r\n root.next = item;\r\n item.prev = root;\r\n item.next = next;\r\n if (next) {\r\n return next.prev = item;\r\n } else {\r\n return this.last = item;\r\n }\r\n }\r\n\r\n prepend(item) {\r\n const {first} = this;\r\n if ((item === first) || !this[item.ID]) { return; }\r\n this.rmi(item);\r\n item.next = first;\r\n if (first) {\r\n first.prev = item;\r\n } else {\r\n this.last = item;\r\n }\r\n this.first = item;\r\n return delete item.prev;\r\n }\r\n\r\n shift() {\r\n return this.rm(this.first.ID);\r\n }\r\n\r\n order() {\r\n let item;\r\n const order = [(item = this.first)];\r\n while ((item = item.next)) { order.push(item); }\r\n return order;\r\n }\r\n\r\n rm(ID) {\r\n const item = this[ID];\r\n if (!item) { return; }\r\n delete this[ID];\r\n this.length--;\r\n this.rmi(item);\r\n delete item.next;\r\n return delete item.prev;\r\n }\r\n\r\n rmi(item) {\r\n const {prev, next} = item;\r\n if (prev) {\r\n prev.next = next;\r\n } else {\r\n this.first = next;\r\n }\r\n if (next) {\r\n return next.prev = prev;\r\n } else {\r\n return this.last = prev;\r\n }\r\n }\r\n}\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport DataBoard from \"../classes/DataBoard\";\r\nimport RandomAccessList from \"../classes/RandomAccessList\";\r\nimport Get from \"../General/Get\";\r\nimport Header from \"../General/Header\";\r\nimport { g, Conf, d } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\nimport { debounce, SECOND } from \"../platform/helpers\";\r\nimport QuoteYou from \"../Quotelinks/QuoteYou\";\r\nimport Favicon from \"./Favicon\";\r\nimport ThreadWatcher from \"./ThreadWatcher\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar Unread = {\r\n init() {\r\n if ((g.VIEW !== 'thread') || (\r\n !Conf['Unread Count'] &&\r\n !Conf['Unread Favicon'] &&\r\n !Conf['Unread Line'] &&\r\n !Conf['Remember Last Read Post'] &&\r\n !Conf['Desktop Notifications'] &&\r\n !Conf['Quote Threading']\r\n )) { return; }\r\n\r\n if (Conf['Remember Last Read Post']) {\r\n $.sync('Remember Last Read Post', enabled => Conf['Remember Last Read Post'] = enabled);\r\n this.db = new DataBoard('lastReadPosts', this.sync);\r\n }\r\n\r\n this.hr = $.el('hr', {\r\n id: 'unread-line',\r\n className: 'unread-line'\r\n }\r\n );\r\n this.posts = new Set();\r\n this.postsQuotingYou = new Set();\r\n this.order = new RandomAccessList();\r\n this.position = null;\r\n\r\n Callbacks.Thread.push({\r\n name: 'Unread',\r\n cb: this.node\r\n });\r\n\r\n return Callbacks.Post.push({\r\n name: 'Unread',\r\n cb: this.addPost\r\n });\r\n },\r\n\r\n node() {\r\n Unread.thread = this;\r\n Unread.title = d.title;\r\n Unread.lastReadPost = Unread.db?.get({\r\n boardID: this.board.ID,\r\n threadID: this.ID\r\n }) || 0;\r\n Unread.readCount = 0;\r\n for (var ID of this.posts.keys) { if (+ID <= Unread.lastReadPost) { Unread.readCount++; } }\r\n $.one(d, '4chanXInitFinished', Unread.ready);\r\n $.on(d, 'PostsInserted', Unread.onUpdate);\r\n $.on(d, 'ThreadUpdate', function(e) { if (e.detail[404]) { return Unread.update(); } });\r\n const resetLink = $.el('a', {\r\n href: 'javascript:;',\r\n className: 'unread-reset',\r\n textContent: 'Mark all unread'\r\n }\r\n );\r\n $.on(resetLink, 'click', Unread.reset);\r\n return Header.menu.addEntry({\r\n el: resetLink,\r\n order: 70\r\n });\r\n },\r\n\r\n ready() {\r\n if (Conf['Remember Last Read Post'] && Conf['Scroll to Last Read Post']) { Unread.scroll(); }\r\n Unread.setLine(true);\r\n Unread.read();\r\n Unread.update();\r\n $.on(d, 'scroll visibilitychange', Unread.read);\r\n if (Conf['Unread Line']) { return $.on(d, 'visibilitychange', Unread.setLine); }\r\n },\r\n\r\n positionPrev() {\r\n if (Unread.position) { return Unread.position.prev; } else { return Unread.order.last; }\r\n },\r\n\r\n scroll() {\r\n // Let the header's onload callback handle it.\r\n let hash;\r\n if ((hash = location.hash.match(/\\d+/)) && hash[0] in Unread.thread.posts) { return; }\r\n\r\n let position = Unread.positionPrev();\r\n while (position) {\r\n var {bottom} = position.data.nodes;\r\n if (!bottom.getBoundingClientRect().height) {\r\n // Don't try to scroll to posts with display: none\r\n position = position.prev;\r\n } else {\r\n Header.scrollToIfNeeded(bottom, true);\r\n break;\r\n }\r\n }\r\n },\r\n\r\n reset() {\r\n if (Unread.lastReadPost == null) { return; }\r\n\r\n Unread.posts = new Set();\r\n Unread.postsQuotingYou = new Set();\r\n Unread.order = new RandomAccessList();\r\n Unread.position = null;\r\n Unread.lastReadPost = 0;\r\n Unread.readCount = 0;\r\n Unread.thread.posts.forEach(post => Unread.addPost.call(post));\r\n\r\n $.forceSync('Remember Last Read Post');\r\n if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) {\r\n Unread.db.set({\r\n boardID: Unread.thread.board.ID,\r\n threadID: Unread.thread.ID,\r\n val: 0\r\n });\r\n }\r\n\r\n Unread.updatePosition();\r\n Unread.setLine();\r\n return Unread.update();\r\n },\r\n\r\n sync() {\r\n if (Unread.lastReadPost == null) { return; }\r\n const lastReadPost = Unread.db.get({\r\n boardID: Unread.thread.board.ID,\r\n threadID: Unread.thread.ID,\r\n defaultValue: 0\r\n });\r\n if (Unread.lastReadPost >= lastReadPost) { return; }\r\n Unread.lastReadPost = lastReadPost;\r\n\r\n const postIDs = Unread.thread.posts.keys;\r\n for (let i = Unread.readCount, end = postIDs.length; i < end; i++) {\r\n var ID = +postIDs[i];\r\n if (!Unread.thread.posts.get(ID).isFetchedQuote) {\r\n if (ID > Unread.lastReadPost) { break; }\r\n Unread.posts.delete(ID);\r\n Unread.postsQuotingYou.delete(ID);\r\n }\r\n Unread.readCount++;\r\n }\r\n\r\n Unread.updatePosition();\r\n Unread.setLine();\r\n return Unread.update();\r\n },\r\n\r\n addPost() {\r\n if (this.isFetchedQuote || this.isClone) { return; }\r\n Unread.order.push(this);\r\n if ((this.ID <= Unread.lastReadPost) || this.isHidden || QuoteYou.isYou(this)) { return; }\r\n Unread.posts.add((Unread.posts.last = this.ID));\r\n Unread.addPostQuotingYou(this);\r\n return Unread.position != null ? Unread.position : (Unread.position = Unread.order[this.ID]);\r\n },\r\n\r\n addPostQuotingYou(post) {\r\n for (var quotelink of post.nodes.quotelinks) {\r\n if (QuoteYou.db?.get(Get.postDataFromLink(quotelink))) {\r\n Unread.postsQuotingYou.add((Unread.postsQuotingYou.last = post.ID));\r\n Unread.openNotification(post);\r\n return;\r\n }\r\n }\r\n },\r\n\r\n openNotification(post, predicate=' replied to you') {\r\n if (!Header.areNotificationsEnabled) { return; }\r\n const notif = new Notification(`${post.info.nameBlock}${predicate}`, {\r\n body: post.commentDisplay(),\r\n icon: Favicon.logo\r\n }\r\n );\r\n notif.onclick = function() {\r\n Header.scrollToIfNeeded(post.nodes.bottom, true);\r\n return window.focus();\r\n };\r\n return notif.onshow = () => setTimeout(() => notif.close()\r\n , 7 * SECOND);\r\n },\r\n\r\n onUpdate() {\r\n return $.queueTask(function() { // ThreadUpdater may scroll immediately after inserting posts\r\n Unread.setLine();\r\n Unread.read();\r\n return Unread.update();\r\n });\r\n },\r\n\r\n readSinglePost(post) {\r\n const {ID} = post;\r\n if (!Unread.posts.has(ID)) { return; }\r\n Unread.posts.delete(ID);\r\n Unread.postsQuotingYou.delete(ID);\r\n Unread.updatePosition();\r\n Unread.saveLastReadPost();\r\n return Unread.update();\r\n },\r\n\r\n read: debounce(100, function(e) {\r\n // Update the lastReadPost when hidden posts are added to the thread.\r\n if (!Unread.posts.size && (Unread.readCount !== Unread.thread.posts.keys.length)) {\r\n Unread.saveLastReadPost();\r\n }\r\n\r\n if (d.hidden || !Unread.posts.size) { return; }\r\n\r\n let count = 0;\r\n while (Unread.position) {\r\n var {ID, data} = Unread.position;\r\n var {bottom} = data.nodes;\r\n if (!!bottom.getBoundingClientRect().height && // post has been hidden\r\n (Header.getBottomOf(bottom) <= -1)) { break; } // post is completely read\r\n count++;\r\n Unread.posts.delete(ID);\r\n Unread.postsQuotingYou.delete(ID);\r\n Unread.position = Unread.position.next;\r\n }\r\n\r\n if (!count) { return; }\r\n Unread.updatePosition();\r\n Unread.saveLastReadPost();\r\n if (e) { return Unread.update(); }\r\n }),\r\n\r\n updatePosition() {\r\n while (Unread.position && !Unread.posts.has(Unread.position.ID)) {\r\n Unread.position = Unread.position.next;\r\n }\r\n },\r\n\r\n saveLastReadPost: debounce(2 * SECOND, function() {\r\n let ID;\r\n $.forceSync('Remember Last Read Post');\r\n if (!Conf['Remember Last Read Post'] || !Unread.db) { return; }\r\n const postIDs = Unread.thread.posts.keys;\r\n for (let i = Unread.readCount, end = postIDs.length; i < end; i++) {\r\n ID = +postIDs[i];\r\n if (!Unread.thread.posts.get(ID).isFetchedQuote) {\r\n if (Unread.posts.has(ID)) { break; }\r\n Unread.lastReadPost = ID;\r\n }\r\n Unread.readCount++;\r\n }\r\n if (Unread.thread.isDead && !Unread.thread.isArchived) { return; }\r\n return Unread.db.set({\r\n boardID: Unread.thread.board.ID,\r\n threadID: Unread.thread.ID,\r\n val: Unread.lastReadPost\r\n });\r\n }),\r\n\r\n setLine(force) {\r\n if (!Conf['Unread Line']) { return; }\r\n if (Unread.hr.hidden || d.hidden || (force === true)) {\r\n const oldPosition = Unread.linePosition;\r\n if (Unread.linePosition = Unread.positionPrev()) {\r\n if (Unread.linePosition !== oldPosition) {\r\n let node = Unread.linePosition.data.nodes.bottom;\r\n if (node.nextSibling?.tagName === 'BR') { node = node.nextSibling; }\r\n $.after(node, Unread.hr);\r\n }\r\n } else {\r\n $.rm(Unread.hr);\r\n }\r\n }\r\n return Unread.hr.hidden = Unread.linePosition === Unread.order.last;\r\n },\r\n\r\n update() {\r\n const count = Unread.posts.size;\r\n const countQuotingYou = Unread.postsQuotingYou.size;\r\n\r\n if (Conf['Unread Count']) {\r\n const titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : '';\r\n const titleCount = count || !Conf['Hide Unread Count at (0)'] ? `(${count}) ` : '';\r\n const titleDead = Unread.thread.isDead ?\r\n Unread.title.replace('-', (Unread.thread.isArchived ? '- Archived -' : '- 404 -'))\r\n :\r\n Unread.title;\r\n d.title = `${titleQuotingYou}${titleCount}${titleDead}`;\r\n }\r\n\r\n Unread.saveThreadWatcherCount();\r\n\r\n if (Conf['Unread Favicon'] && (g.SITE.software === 'yotsuba')) {\r\n const {isDead} = Unread.thread;\r\n return Favicon.set((\r\n countQuotingYou ?\r\n (isDead ? 'unreadDeadY' : 'unreadY')\r\n : count ?\r\n (isDead ? 'unreadDead' : 'unread')\r\n :\r\n (isDead ? 'dead' : 'default')\r\n )\r\n );\r\n }\r\n },\r\n\r\n saveThreadWatcherCount: debounce(2 * SECOND, function() {\r\n $.forceSync('Remember Last Read Post');\r\n if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) {\r\n let posts;\r\n const quotingYou = !Conf['Require OP Quote Link'] && QuoteYou.isYou(Unread.thread.OP) ? Unread.posts : Unread.postsQuotingYou;\r\n if (!quotingYou.size) {\r\n quotingYou.last = 0;\r\n } else if (!quotingYou.has(quotingYou.last)) {\r\n quotingYou.last = 0;\r\n posts = Unread.thread.posts.keys;\r\n for (let i = posts.length - 1; i >= 0; i--) {\r\n if (quotingYou.has(+posts[i])) {\r\n quotingYou.last = posts[i];\r\n break;\r\n }\r\n }\r\n }\r\n return ThreadWatcher.update(g.SITE.ID, Unread.thread.board.ID, Unread.thread.ID, {\r\n last: Unread.thread.lastPost,\r\n isDead: Unread.thread.isDead,\r\n isArchived: Unread.thread.isArchived,\r\n unread: Unread.posts.size,\r\n quotingYou: (quotingYou.last || 0)\r\n }\r\n );\r\n }\r\n })\r\n};\r\nexport default Unread;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport Post from \"../classes/Post\";\r\nimport Get from \"../General/Get\";\r\nimport Index from \"../General/Index\";\r\nimport { g, Conf, d } from \"../globals/globals\";\r\nimport Main from \"../main/Main\";\r\nimport $ from \"../platform/$\";\r\nimport $$ from \"../platform/$$\";\r\nimport { dict } from \"../platform/helpers\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar ExpandThread = {\r\n statuses: dict(),\r\n init() {\r\n if (!((g.VIEW === 'index') && Conf['Thread Expansion'])) { return; }\r\n if (Conf['JSON Index']) {\r\n return $.on(d, 'IndexRefreshInternal', this.onIndexRefresh);\r\n } else {\r\n return Callbacks.Thread.push({\r\n name: 'Expand Thread',\r\n cb() { return ExpandThread.setButton(this); }\r\n });\r\n }\r\n },\r\n\r\n setButton(thread) {\r\n let a;\r\n if (!(thread.nodes.root && (a = $('.summary', thread.nodes.root)))) { return; }\r\n a.textContent = g.SITE.Build.summaryText('+', ...Array.from(a.textContent.match(/\\d+/g)));\r\n a.style.cursor = 'pointer';\r\n return $.on(a, 'click', ExpandThread.cbToggle);\r\n },\r\n \r\n disconnect(refresh) {\r\n if ((g.VIEW === 'thread') || !Conf['Thread Expansion']) { return; }\r\n for (var threadID in ExpandThread.statuses) {\r\n var oldReq;\r\n var status = ExpandThread.statuses[threadID];\r\n if (oldReq = status.req) {\r\n delete status.req;\r\n oldReq.abort();\r\n }\r\n delete ExpandThread.statuses[threadID];\r\n }\r\n\r\n if (!refresh) { return $.off(d, 'IndexRefreshInternal', this.onIndexRefresh); }\r\n },\r\n\r\n onIndexRefresh() {\r\n ExpandThread.disconnect(true);\r\n return g.BOARD.threads.forEach(thread => ExpandThread.setButton(thread));\r\n },\r\n\r\n cbToggle(e) {\r\n if ($.modifiedClick(e)) { return; }\r\n e.preventDefault();\r\n return ExpandThread.toggle(Get.threadFromNode(this));\r\n },\r\n\r\n cbToggleBottom(e) {\r\n if ($.modifiedClick(e)) { return; }\r\n e.preventDefault();\r\n const thread = Get.threadFromNode(this);\r\n $.rm(this); // remove before fixing bottom of thread position\r\n const {bottom} = thread.nodes.root.getBoundingClientRect();\r\n ExpandThread.toggle(thread);\r\n return window.scrollBy(0, (thread.nodes.root.getBoundingClientRect().bottom - bottom));\r\n },\r\n\r\n toggle(thread) {\r\n let a;\r\n if (!(thread.nodes.root && (a = $('.summary', thread.nodes.root)))) { return; }\r\n if (thread.ID in ExpandThread.statuses) {\r\n return ExpandThread.contract(thread, a, thread.nodes.root);\r\n } else {\r\n return ExpandThread.expand(thread, a);\r\n }\r\n },\r\n\r\n expand(thread, a) {\r\n let status;\r\n ExpandThread.statuses[thread] = (status = {});\r\n a.textContent = g.SITE.Build.summaryText('...', ...Array.from(a.textContent.match(/\\d+/g)));\r\n status.req = $.cache(g.SITE.urls.threadJSON({boardID: thread.board.ID, threadID: thread.ID}), function() {\r\n if (this !== status.req) { return; } // aborted\r\n delete status.req;\r\n return ExpandThread.parse(this, thread, a);\r\n });\r\n return status.numReplies = $$(g.SITE.selectors.replyOriginal, thread.nodes.root).length;\r\n },\r\n\r\n contract(thread, a, threadRoot) {\r\n let oldReq;\r\n const status = ExpandThread.statuses[thread];\r\n delete ExpandThread.statuses[thread];\r\n if (oldReq = status.req) {\r\n delete status.req;\r\n oldReq.abort();\r\n if (a) { a.textContent = g.SITE.Build.summaryText('+', ...Array.from(a.textContent.match(/\\d+/g))); }\r\n return;\r\n }\r\n\r\n let replies = $$('.thread > .replyContainer', threadRoot);\r\n if (status.numReplies) { replies = replies.slice(0, (-status.numReplies)); }\r\n let postsCount = 0;\r\n let filesCount = 0;\r\n for (var reply of replies) {\r\n // rm clones\r\n if (Conf['Quote Inlining']) { var inlined;\r\n while ((inlined = $('.inlined', reply))) { inlined.click(); } }\r\n postsCount++;\r\n if ('file' in Get.postFromRoot(reply)) { filesCount++; }\r\n $.rm(reply);\r\n }\r\n if (Index.enabled) { // otherwise handled by Main.addPosts\r\n $.event('PostsRemoved', null, a.parentNode);\r\n }\r\n a.textContent = g.SITE.Build.summaryText('+', postsCount, filesCount);\r\n return $.rm($('.summary-bottom', threadRoot));\r\n },\r\n\r\n parse(req, thread, a) {\r\n let root;\r\n if (![200, 304].includes(req.status)) {\r\n a.textContent = req.status ? `Error ${req.statusText} (${req.status})` : 'Connection Error';\r\n return;\r\n }\r\n\r\n g.SITE.Build.spoilerRange[thread.board] = req.response.posts[0].custom_spoiler;\r\n\r\n const posts = [];\r\n const postsRoot = [];\r\n let filesCount = 0;\r\n for (var postData of req.response.posts) {\r\n var post;\r\n if (postData.no === thread.ID) { continue; }\r\n if ((post = thread.posts.get(postData.no)) && !post.isFetchedQuote) {\r\n if ('file' in post) { filesCount++; }\r\n ({root} = post.nodes);\r\n postsRoot.push(root);\r\n continue;\r\n }\r\n root = g.SITE.Build.postFromObject(postData, thread.board.ID);\r\n post = new Post(root, thread, thread.board);\r\n if ('file' in post) { filesCount++; }\r\n posts.push(post);\r\n postsRoot.push(root);\r\n }\r\n Main.callbackNodes('Post', posts);\r\n $.after(a, postsRoot);\r\n $.event('PostsInserted', null, a.parentNode);\r\n\r\n const postsCount = postsRoot.length;\r\n a.textContent = g.SITE.Build.summaryText('-', postsCount, filesCount);\r\n\r\n if (root) {\r\n const a2 = a.cloneNode(true);\r\n a2.classList.add('summary-bottom');\r\n $.on(a2, 'click', ExpandThread.cbToggleBottom);\r\n return $.after(root, a2);\r\n }\r\n }\r\n};\r\nexport default ExpandThread;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport DataBoard from \"../classes/DataBoard\";\r\nimport Get from \"../General/Get\";\r\nimport Header from \"../General/Header\";\r\nimport Index from \"../General/Index\";\r\nimport { g, Conf, d } from \"../globals/globals\";\r\nimport ExpandThread from \"../Miscellaneous/ExpandThread\";\r\nimport $ from \"../platform/$\";\r\nimport { dict } from \"../platform/helpers\";\r\nimport QuoteYou from \"../Quotelinks/QuoteYou\";\r\nimport ThreadWatcher from \"./ThreadWatcher\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS205: Consider reworking code to avoid use of IIFEs\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar UnreadIndex = {\r\n lastReadPost: dict(),\r\n hr: dict(),\r\n markReadLink: dict(),\r\n\r\n init() {\r\n if ((g.VIEW !== 'index') || !Conf['Remember Last Read Post'] || !Conf['Unread Line in Index']) { return; }\r\n\r\n this.enabled = true;\r\n this.db = new DataBoard('lastReadPosts', this.sync);\r\n\r\n Callbacks.Thread.push({\r\n name: 'Unread Line in Index',\r\n cb: this.node\r\n });\r\n\r\n $.on(d, 'IndexRefreshInternal', this.onIndexRefresh);\r\n return $.on(d, 'PostsInserted PostsRemoved', this.onPostsInserted);\r\n },\r\n\r\n node() {\r\n UnreadIndex.lastReadPost[this.fullID] = UnreadIndex.db.get({\r\n boardID: this.board.ID,\r\n threadID: this.ID\r\n }) || 0;\r\n if (!Index.enabled) { // let onIndexRefresh handle JSON Index\r\n return UnreadIndex.update(this);\r\n }\r\n },\r\n\r\n onIndexRefresh(e) {\r\n if (e.detail.isCatalog) { return; }\r\n return (() => {\r\n const result = [];\r\n for (var threadID of e.detail.threadIDs) {\r\n var thread = g.threads.get(threadID);\r\n result.push(UnreadIndex.update(thread));\r\n }\r\n return result;\r\n })();\r\n },\r\n\r\n onPostsInserted(e) {\r\n if (e.target === Index.root) { return; } // onIndexRefresh handles this case\r\n const thread = Get.threadFromNode(e.target);\r\n if (!thread || (thread.nodes.root !== e.target)) { return; }\r\n const wasVisible = !!UnreadIndex.hr[thread.fullID]?.parentNode;\r\n UnreadIndex.update(thread);\r\n if (Conf['Scroll to Last Read Post'] && (e.type === 'PostsInserted') && !wasVisible && !!UnreadIndex.hr[thread.fullID]?.parentNode) {\r\n return Header.scrollToIfNeeded(UnreadIndex.hr[thread.fullID], true);\r\n }\r\n },\r\n\r\n sync() {\r\n return g.threads.forEach(function(thread) {\r\n const lastReadPost = UnreadIndex.db.get({\r\n boardID: thread.board.ID,\r\n threadID: thread.ID\r\n }) || 0;\r\n if (lastReadPost !== UnreadIndex.lastReadPost[thread.fullID]) {\r\n UnreadIndex.lastReadPost[thread.fullID] = lastReadPost;\r\n if (thread.nodes.root?.parentNode) {\r\n return UnreadIndex.update(thread);\r\n }\r\n }\r\n });\r\n },\r\n\r\n update(thread) {\r\n let divider;\r\n const lastReadPost = UnreadIndex.lastReadPost[thread.fullID];\r\n let repliesShown = 0;\r\n let repliesRead = 0;\r\n let firstUnread = null;\r\n thread.posts.forEach(function(post) {\r\n if (post.isReply && thread.nodes.root.contains(post.nodes.root)) {\r\n repliesShown++;\r\n if (post.ID <= lastReadPost) {\r\n return repliesRead++;\r\n } else if ((!firstUnread || (post.ID < firstUnread.ID)) && !post.isHidden && !QuoteYou.isYou(post)) {\r\n return firstUnread = post;\r\n }\r\n }\r\n });\r\n\r\n let hr = UnreadIndex.hr[thread.fullID];\r\n if (firstUnread && (repliesRead || ((lastReadPost === thread.OP.ID) && (!$(g.SITE.selectors.summary, thread.nodes.root) || thread.ID in ExpandThread.statuses)))) {\r\n if (!hr) {\r\n hr = (UnreadIndex.hr[thread.fullID] = $.el('hr',\r\n {className: 'unread-line'}));\r\n }\r\n $.before(firstUnread.nodes.root, hr);\r\n } else {\r\n $.rm(hr);\r\n }\r\n\r\n const hasUnread = repliesShown ?\r\n firstUnread || !repliesRead\r\n : Index.enabled ?\r\n thread.lastPost > lastReadPost\r\n :\r\n thread.OP.ID > lastReadPost;\r\n thread.nodes.root.classList.toggle('unread-thread', hasUnread);\r\n\r\n let link = UnreadIndex.markReadLink[thread.fullID];\r\n if (!link) {\r\n link = (UnreadIndex.markReadLink[thread.fullID] = $.el('a', {\r\n className: 'unread-mark-read brackets-wrap',\r\n href: 'javascript:;',\r\n textContent: 'Mark Read'\r\n }\r\n ));\r\n $.on(link, 'click', UnreadIndex.markRead);\r\n }\r\n if (divider = $(g.SITE.selectors.threadDivider, thread.nodes.root)) { // divider inside thread as in Tinyboard\r\n return $.before(divider, link);\r\n } else {\r\n return $.add(thread.nodes.root, link);\r\n }\r\n },\r\n\r\n markRead() {\r\n const thread = Get.threadFromNode(this);\r\n UnreadIndex.lastReadPost[thread.fullID] = thread.lastPost;\r\n UnreadIndex.db.set({\r\n boardID: thread.board.ID,\r\n threadID: thread.ID,\r\n val: thread.lastPost\r\n });\r\n $.rm(UnreadIndex.hr[thread.fullID]);\r\n thread.nodes.root.classList.remove('unread-thread');\r\n return ThreadWatcher.update(g.SITE.ID, thread.board.ID, thread.ID, {\r\n last: thread.lastPost,\r\n unread: 0,\r\n quotingYou: 0\r\n }\r\n );\r\n }\r\n};\r\nexport default UnreadIndex;\r\n","import ThreadWatcherPage from './ThreadWatcher/ThreadWatcher.html';\r\nimport $ from \"../platform/$\";\r\nimport Board from '../classes/Board';\r\nimport Callbacks from '../classes/Callbacks';\r\nimport DataBoard from '../classes/DataBoard';\r\nimport Thread from '../classes/Thread';\r\nimport Filter from '../Filtering/Filter';\r\nimport Main from '../main/Main';\r\nimport $$ from '../platform/$$';\r\nimport Config from '../config/Config';\r\nimport CrossOrigin from '../platform/CrossOrigin';\r\nimport PostRedirect from '../Posting/PostRedirect';\r\nimport QuoteYou from '../Quotelinks/QuoteYou';\r\nimport Unread from './Unread';\r\nimport UnreadIndex from './UnreadIndex';\r\nimport Header from '../General/Header';\r\nimport Index from '../General/Index';\r\nimport { Conf, d, doc, g } from '../globals/globals';\r\nimport Menu from '../Menu/Menu';\r\nimport UI from '../General/UI';\r\nimport Get from '../General/Get';\r\nimport { dict, HOUR, MINUTE } from '../platform/helpers';\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS104: Avoid inline assignments\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\n\r\nvar ThreadWatcher = {\r\n init() {\r\n let sc;\r\n if (!(this.enabled = Conf['Thread Watcher'])) { return; }\r\n\r\n this.shortcut = (sc = $.el('a', {\r\n id: 'watcher-link',\r\n textContent: '👁︎',\r\n title: 'Thread Watcher',\r\n href: 'javascript:;',\r\n }\r\n ));\r\n\r\n this.db = new DataBoard('watchedThreads', this.refresh, true);\r\n this.dbLM = new DataBoard('watcherLastModified', null, true);\r\n this.dialog = UI.dialog('thread-watcher', { innerHTML: ThreadWatcherPage });\r\n this.status = $('#watcher-status', this.dialog);\r\n this.list = this.dialog.lastElementChild;\r\n this.refreshButton = $('.refresh', this.dialog);\r\n this.closeButton = $('.move > .close', this.dialog);\r\n this.unreaddb = Unread.db || UnreadIndex.db || new DataBoard('lastReadPosts');\r\n this.unreadEnabled = Conf['Remember Last Read Post'];\r\n\r\n $.on(d, 'QRPostSuccessful', this.cb.post);\r\n $.on(sc, 'click', this.toggleWatcher);\r\n $.on(this.refreshButton, 'click', this.buttonFetchAll);\r\n $.on(this.closeButton, 'click', this.toggleWatcher);\r\n\r\n this.menu.addHeaderMenuEntry();\r\n $.onExists(doc, 'body', this.addDialog);\r\n\r\n switch (g.VIEW) {\r\n case 'index':\r\n $.on(d, 'IndexUpdate', this.cb.onIndexUpdate);\r\n break;\r\n case 'thread':\r\n $.on(d, 'ThreadUpdate', this.cb.onThreadRefresh);\r\n break;\r\n }\r\n\r\n if (Conf['Fixed Thread Watcher']) {\r\n $.addClass(doc, 'fixed-watcher');\r\n }\r\n if (!Conf['Persistent Thread Watcher']) {\r\n $.addClass(ThreadWatcher.shortcut, 'disabled');\r\n this.dialog.hidden = true;\r\n }\r\n\r\n Header.addShortcut('watcher', sc, 510);\r\n\r\n ThreadWatcher.initLastModified();\r\n ThreadWatcher.fetchAuto();\r\n $.on(window, 'visibilitychange focus', () => $.queueTask(ThreadWatcher.fetchAuto));\r\n\r\n if (Conf['Menu'] && Index.enabled) {\r\n Menu.menu.addEntry({\r\n el: $.el('a', {\r\n href: 'javascript:;',\r\n className: 'has-shortcut-text'\r\n }\r\n , {innerHTML: 'Alt+click'}),\r\n order: 6,\r\n open({thread}) {\r\n if (Conf['Index Mode'] !== 'catalog') { return false; }\r\n this.el.firstElementChild.textContent = ThreadWatcher.isWatched(thread) ?\r\n 'Unwatch'\r\n :\r\n 'Watch';\r\n if (this.cb) { $.off(this.el, 'click', this.cb); }\r\n this.cb = function() {\r\n $.event('CloseMenu');\r\n return ThreadWatcher.toggle(thread);\r\n };\r\n $.on(this.el, 'click', this.cb);\r\n return true;\r\n }\r\n });\r\n }\r\n\r\n if (!['index', 'thread'].includes(g.VIEW)) { return; }\r\n\r\n Callbacks.Post.push({\r\n name: 'Thread Watcher',\r\n cb: this.node\r\n });\r\n return Callbacks.CatalogThread.push({\r\n name: 'Thread Watcher',\r\n cb: this.catalogNode\r\n });\r\n },\r\n\r\n isWatched(thread) {\r\n return !!ThreadWatcher.db?.get({boardID: thread.board.ID, threadID: thread.ID});\r\n },\r\n\r\n isWatchedRaw(boardID, threadID) {\r\n return !!ThreadWatcher.db?.get({boardID, threadID});\r\n },\r\n\r\n setToggler(toggler, isWatched) {\r\n toggler.classList.toggle('watched', isWatched);\r\n return toggler.title = `${isWatched ? 'Unwatch' : 'Watch'} Thread`;\r\n },\r\n\r\n node() {\r\n let toggler;\r\n if (this.isReply) { return; }\r\n if (this.isClone) {\r\n toggler = $('.watch-thread-link', this.nodes.info);\r\n } else {\r\n toggler = $.el('a', {\r\n href: 'javascript:;',\r\n className: 'watch-thread-link'\r\n }\r\n );\r\n $.before($('input', this.nodes.info), toggler);\r\n }\r\n const siteID = g.SITE.ID;\r\n const boardID = this.board.ID;\r\n const threadID = this.thread.ID;\r\n const data = ThreadWatcher.db.get({siteID, boardID, threadID});\r\n ThreadWatcher.setToggler(toggler, !!data);\r\n $.on(toggler, 'click', ThreadWatcher.cb.toggle);\r\n // Add missing excerpt for threads added by Auto Watch\r\n if (data && (data.excerpt == null)) {\r\n return $.queueTask(() => {\r\n return ThreadWatcher.update(siteID, boardID, threadID, {excerpt: Get.threadExcerpt(this.thread)});\r\n });\r\n }\r\n },\r\n\r\n catalogNode() {\r\n if (ThreadWatcher.isWatched(this.thread)) { $.addClass(this.nodes.root, 'watched'); }\r\n return $.on(this.nodes.root, 'mousedown click', e => {\r\n if ((e.button !== 0) || !e.altKey) { return; }\r\n if (e.type === 'click') { ThreadWatcher.toggle(this.thread); }\r\n return e.preventDefault();\r\n });\r\n }, // Also on mousedown to prevent highlighting thumbnail in Firefox.\r\n\r\n addDialog() {\r\n if (!Main.isThisPageLegit()) { return; }\r\n ThreadWatcher.build();\r\n return $.prepend(d.body, ThreadWatcher.dialog);\r\n },\r\n\r\n toggleWatcher() {\r\n $.toggleClass(ThreadWatcher.shortcut, 'disabled');\r\n return ThreadWatcher.dialog.hidden = !ThreadWatcher.dialog.hidden;\r\n },\r\n\r\n cb: {\r\n openAll() {\r\n if ($.hasClass(this, 'disabled')) { return; }\r\n for (var a of $$('a.watcher-link', ThreadWatcher.list)) {\r\n $.open(a.href);\r\n }\r\n return $.event('CloseMenu');\r\n },\r\n openUnread() {\r\n if ($.hasClass(this, 'disabled')) { return; }\r\n for (var a of $$('.replies-unread > a.watcher-link', ThreadWatcher.list)) {\r\n $.open(a.href);\r\n }\r\n return $.event('CloseMenu');\r\n },\r\n openDeads() {\r\n if ($.hasClass(this, 'disabled')) { return; }\r\n for (var a of $$('.dead-thread > a.watcher-link', ThreadWatcher.list)) {\r\n $.open(a.href);\r\n }\r\n return $.event('CloseMenu');\r\n },\r\n pruneDeads() {\r\n if ($.hasClass(this, 'disabled')) { return; }\r\n for (var {siteID, boardID, threadID, data} of ThreadWatcher.getAll()) {\r\n if (data.isDead) {\r\n ThreadWatcher.db.delete({siteID, boardID, threadID});\r\n }\r\n }\r\n ThreadWatcher.refresh();\r\n return $.event('CloseMenu');\r\n },\r\n dismiss() {\r\n for (var {siteID, boardID, threadID, data} of ThreadWatcher.getAll()) {\r\n if (data.quotingYou) {\r\n ThreadWatcher.update(siteID, boardID, threadID, {dismiss: data.quotingYou || 0});\r\n }\r\n }\r\n return $.event('CloseMenu');\r\n },\r\n toggle() {\r\n const {thread} = Get.postFromNode(this);\r\n return ThreadWatcher.toggle(thread);\r\n },\r\n rm() {\r\n const {siteID} = this.parentNode.dataset;\r\n const [boardID, threadID] = Array.from(this.parentNode.dataset.fullID.split('.'));\r\n return ThreadWatcher.rm(siteID, boardID, +threadID);\r\n },\r\n post(e) {\r\n const {boardID, threadID, postID} = e.detail;\r\n const cb = PostRedirect.delay();\r\n if (postID === threadID) {\r\n if (Conf['Auto Watch']) {\r\n return ThreadWatcher.addRaw(boardID, threadID, {}, cb);\r\n }\r\n } else if (Conf['Auto Watch Reply']) {\r\n return ThreadWatcher.add((g.threads.get(boardID + '.' + threadID) || new Thread(threadID, g.boards[boardID] || new Board(boardID))), cb);\r\n }\r\n },\r\n onIndexUpdate(e) {\r\n const {db} = ThreadWatcher;\r\n const siteID = g.SITE.ID;\r\n const boardID = g.BOARD.ID;\r\n let nKilled = 0;\r\n for (var threadID in db.data[siteID].boards[boardID]) {\r\n // Don't prune threads that have yet to appear in index.\r\n var data = db.data[siteID].boards[boardID][threadID];\r\n if (!data?.isDead && !e.detail.threads.includes(`${boardID}.${threadID}`)) {\r\n if (!e.detail.threads.some(fullID => +fullID.split('.')[1] > threadID)) { continue; }\r\n if (Conf['Auto Prune'] || !(data && (typeof data === 'object'))) { // corrupt data\r\n db.delete({boardID, threadID});\r\n nKilled++;\r\n } else {\r\n ThreadWatcher.fetchStatus({siteID, boardID, threadID, data});\r\n }\r\n }\r\n }\r\n if (nKilled) { return ThreadWatcher.refresh(); }\r\n },\r\n onThreadRefresh(e) {\r\n const thread = g.threads.get(e.detail.threadID);\r\n if (!e.detail[404] || !ThreadWatcher.isWatched(thread)) { return; }\r\n // Update dead status.\r\n return ThreadWatcher.add(thread);\r\n }\r\n },\r\n\r\n requests: [],\r\n fetched: 0,\r\n\r\n fetch(url, {siteID, force}, args, cb) {\r\n if (ThreadWatcher.requests.length === 0) {\r\n ThreadWatcher.status.textContent = '...';\r\n $.addClass(ThreadWatcher.refreshButton, 'spin');\r\n }\r\n const onloadend = function() {\r\n if (this.finished) { return; }\r\n this.finished = true;\r\n ThreadWatcher.fetched++;\r\n if (ThreadWatcher.fetched === ThreadWatcher.requests.length) {\r\n ThreadWatcher.clearRequests();\r\n } else {\r\n ThreadWatcher.status.textContent = `${Math.round((ThreadWatcher.fetched / ThreadWatcher.requests.length) * 100)}%`;\r\n }\r\n return cb.apply(this, args);\r\n };\r\n const ajax = siteID === g.SITE.ID ? $.ajax : CrossOrigin.ajax;\r\n if (force) {\r\n delete $.lastModified.ThreadWatcher?.[url];\r\n }\r\n const req = $.whenModified(\r\n url,\r\n 'ThreadWatcher',\r\n onloadend,\r\n { timeout: MINUTE, ajax }\r\n );\r\n return ThreadWatcher.requests.push(req);\r\n },\r\n\r\n clearRequests() {\r\n ThreadWatcher.requests = [];\r\n ThreadWatcher.fetched = 0;\r\n ThreadWatcher.status.textContent = '';\r\n return $.rmClass(ThreadWatcher.refreshButton, 'spin');\r\n },\r\n\r\n abort() {\r\n delete ThreadWatcher.syncing;\r\n for (var req of ThreadWatcher.requests) {\r\n if (!req.finished) {\r\n req.finished = true;\r\n req.abort();\r\n }\r\n }\r\n return ThreadWatcher.clearRequests();\r\n },\r\n\r\n initLastModified() {\r\n const lm = ($.lastModified['ThreadWatcher'] || ($.lastModified['ThreadWatcher'] = dict()));\r\n for (var siteID in ThreadWatcher.dbLM.data) {\r\n var boards = ThreadWatcher.dbLM.data[siteID];\r\n for (var boardID in boards.boards) {\r\n var data = boards.boards[boardID];\r\n if (ThreadWatcher.db.get({siteID, boardID})) {\r\n for (var url in data) {\r\n var date = data[url];\r\n lm[url] = date;\r\n }\r\n } else {\r\n ThreadWatcher.dbLM.delete({siteID, boardID});\r\n }\r\n }\r\n }\r\n },\r\n\r\n fetchAuto() {\r\n let middle;\r\n clearTimeout(ThreadWatcher.timeout);\r\n if (!Conf['Auto Update Thread Watcher']) { return; }\r\n const {db} = ThreadWatcher;\r\n const interval = Conf['Show Page'] || (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) ? 5 * MINUTE : 2 * HOUR;\r\n const now = Date.now();\r\n if ((now - interval >= ((middle = db.data.lastChecked || 0)) || middle > now) && !d.hidden && !!d.hasFocus()) {\r\n ThreadWatcher.fetchAllStatus(interval);\r\n }\r\n return ThreadWatcher.timeout = setTimeout(ThreadWatcher.fetchAuto, interval);\r\n },\r\n\r\n buttonFetchAll() {\r\n if (ThreadWatcher.syncing || ThreadWatcher.requests.length) {\r\n return ThreadWatcher.abort();\r\n } else {\r\n return ThreadWatcher.fetchAllStatus();\r\n }\r\n },\r\n\r\n fetchAllStatus(interval=0) {\r\n ThreadWatcher.status.textContent = '...';\r\n $.addClass(ThreadWatcher.refreshButton, 'spin');\r\n ThreadWatcher.syncing = true;\r\n const dbs = [ThreadWatcher.db, ThreadWatcher.unreaddb, QuoteYou.db].filter(x => x);\r\n let n = 0;\r\n return dbs.map((dbi) =>\r\n dbi.forceSync(function() {\r\n if ((++n) === dbs.length) {\r\n let middle;\r\n if (!ThreadWatcher.syncing) { return; } // aborted\r\n delete ThreadWatcher.syncing;\r\n if (0 > (middle = Date.now() - (ThreadWatcher.db.data.lastChecked || 0)) || middle >= interval) { // not checked in another tab\r\n // XXX On vichan boards, last_modified field of threads.json does not account for sage posts.\r\n // Occasionally check replies field of catalog.json to find these posts.\r\n let middle1;\r\n const {db} = ThreadWatcher;\r\n const now = Date.now();\r\n const deep = !(now - (2 * HOUR) < ((middle1 = db.data.lastChecked2 || 0)) && middle1 <= now);\r\n const boards = ThreadWatcher.getAll(true);\r\n for (var board of boards) {\r\n ThreadWatcher.fetchBoard(board, deep);\r\n }\r\n db.setLastChecked();\r\n if (deep) { db.setLastChecked('lastChecked2'); }\r\n }\r\n if (ThreadWatcher.fetched === ThreadWatcher.requests.length) {\r\n return ThreadWatcher.clearRequests();\r\n }\r\n }\r\n }));\r\n },\r\n\r\n fetchBoard(board, deep) {\r\n if (!board.some(thread => !thread.data.isDead)) { return; }\r\n let force = false;\r\n for (var thread of board) {\r\n var {data} = thread;\r\n if (!data.isDead && (data.last !== -1)) {\r\n if (Conf['Show Page'] && (data.page == null)) { force = true; }\r\n if ((data.modified == null)) { force = (thread.force = true); }\r\n }\r\n }\r\n const {siteID, boardID} = board[0];\r\n const site = g.sites[siteID];\r\n if (!site) { return; }\r\n const urlF = deep && site.threadModTimeIgnoresSage ? 'catalogJSON' : 'threadsListJSON';\r\n const url = site.urls[urlF]?.({siteID, boardID});\r\n if (!url) { return; }\r\n return ThreadWatcher.fetch(url, {siteID, force}, [board, url], ThreadWatcher.parseBoard);\r\n },\r\n\r\n parseBoard(board, url) {\r\n let page, thread;\r\n if (this.status !== 200) { return; }\r\n const {siteID, boardID} = board[0];\r\n const lmDate = this.getResponseHeader('Last-Modified');\r\n ThreadWatcher.dbLM.extend({siteID, boardID, val: $.item(url, lmDate)});\r\n const threads = dict();\r\n let pageLength = 0;\r\n let nThreads = 0;\r\n let oldest = null;\r\n try {\r\n pageLength = this.response[0]?.threads.length || 0;\r\n for (let i = 0; i < this.response.length; i++) {\r\n page = this.response[i];\r\n for (var item of page.threads) {\r\n threads[item.no] = {\r\n page: i + 1,\r\n index: nThreads,\r\n modified: item.last_modified,\r\n replies: item.replies\r\n };\r\n nThreads++;\r\n if ((oldest == null) || (item.no < oldest)) {\r\n oldest = item.no;\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n for (thread of board) {\r\n ThreadWatcher.fetchStatus(thread);\r\n }\r\n }\r\n for (thread of board) {\r\n var {threadID, data} = thread;\r\n if (threads[threadID]) {\r\n var index, modified, replies;\r\n ({page, index, modified, replies} = threads[threadID]);\r\n if (Conf['Show Page']) {\r\n var lastPage = g.sites[siteID].isPrunedByAge?.({siteID, boardID}) ?\r\n threadID === oldest\r\n :\r\n index >= (nThreads - pageLength);\r\n ThreadWatcher.update(siteID, boardID, threadID, {page, lastPage});\r\n }\r\n if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) {\r\n if ((modified !== data.modified) || ((replies != null) && (replies !== data.replies))) {\r\n (thread.newData || (thread.newData = {})).modified = modified;\r\n ThreadWatcher.fetchStatus(thread);\r\n }\r\n }\r\n } else {\r\n ThreadWatcher.fetchStatus(thread);\r\n }\r\n }\r\n },\r\n\r\n fetchStatus(thread) {\r\n const {siteID, boardID, threadID, data, force} = thread;\r\n const url = g.sites[siteID]?.urls.threadJSON?.({siteID, boardID, threadID});\r\n if (!url) { return; }\r\n if (data.isDead && !force) { return; }\r\n if (data.last === -1) { return; } // 404 or no JSON API\r\n return ThreadWatcher.fetch(url, {siteID, force}, [thread], ThreadWatcher.parseStatus);\r\n },\r\n\r\n parseStatus(thread, isArchiveURL) {\r\n let isDead, last;\r\n let {siteID, boardID, threadID, data, newData, force} = thread;\r\n const site = g.sites[siteID];\r\n if ((this.status === 200) && this.response) {\r\n let isArchived;\r\n last = this.response.posts[this.response.posts.length-1].no;\r\n const replies = this.response.posts.length-1;\r\n isDead = (isArchived = !!(this.response.posts[0].archived || isArchiveURL));\r\n if (isDead && Conf['Auto Prune']) {\r\n ThreadWatcher.rm(siteID, boardID, threadID);\r\n return;\r\n }\r\n\r\n if ((last === data.last) && (isDead === data.isDead) && (isArchived === data.isArchived)) { return; }\r\n\r\n const lastReadPost = ThreadWatcher.unreaddb.get({siteID, boardID, threadID, defaultValue: 0});\r\n let unread = data.unread || 0;\r\n let quotingYou = data.quotingYou || 0;\r\n const youOP = !!QuoteYou.db?.get({siteID, boardID, threadID, postID: threadID});\r\n\r\n for (var postObj of this.response.posts) {\r\n if ((postObj.no <= (data.last || 0)) || (postObj.no <= lastReadPost)) { continue; }\r\n if (QuoteYou.db?.get({siteID, boardID, threadID, postID: postObj.no})) { continue; }\r\n\r\n var quotesYou = false;\r\n if (!Conf['Require OP Quote Link'] && youOP) {\r\n quotesYou = true;\r\n } else if (QuoteYou.db && postObj.com) {\r\n var match;\r\n var regexp = site.regexp.quotelinkHTML;\r\n regexp.lastIndex = 0;\r\n while (match = regexp.exec(postObj.com)) {\r\n if (QuoteYou.db.get({\r\n siteID,\r\n boardID: match[1] ? encodeURIComponent(match[1]) : boardID,\r\n threadID: match[2] || threadID,\r\n postID: match[3] || match[2] || threadID\r\n })) {\r\n quotesYou = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (!unread || (!quotingYou && quotesYou)) {\r\n if (Filter.isHidden(site.Build.parseJSON(postObj, {siteID, boardID}))) { continue; }\r\n }\r\n\r\n unread++;\r\n if (quotesYou) { quotingYou = postObj.no; }\r\n }\r\n\r\n if (!newData) { newData = {}; }\r\n $.extend(newData, {last, replies, isDead, isArchived, unread, quotingYou});\r\n return ThreadWatcher.update(siteID, boardID, threadID, newData);\r\n\r\n } else if (this.status === 404) {\r\n const archiveURL = g.sites[siteID]?.urls.archivedThreadJSON?.({siteID, boardID, threadID});\r\n if (!isArchiveURL && archiveURL) {\r\n return ThreadWatcher.fetch(archiveURL, {siteID, force}, [thread, true], ThreadWatcher.parseStatus);\r\n } else if (site.mayLackJSON && (data.last == null)) {\r\n return ThreadWatcher.update(siteID, boardID, threadID, {last: -1});\r\n } else {\r\n return ThreadWatcher.update(siteID, boardID, threadID, {isDead: true});\r\n }\r\n }\r\n },\r\n\r\n getAll(groupByBoard) {\r\n const all = [];\r\n for (var siteID in ThreadWatcher.db.data) {\r\n var boards = ThreadWatcher.db.data[siteID];\r\n for (var boardID in boards.boards) {\r\n var cont;\r\n var threads = boards.boards[boardID];\r\n if (Conf['Current Board'] && ((siteID !== g.SITE.ID) || (boardID !== g.BOARD.ID))) {\r\n continue;\r\n }\r\n if (groupByBoard) {\r\n all.push((cont = []));\r\n }\r\n for (var threadID in threads) {\r\n var data = threads[threadID];\r\n if (data && (typeof data === 'object')) {\r\n (groupByBoard ? cont : all).push({siteID, boardID, threadID, data});\r\n }\r\n }\r\n }\r\n }\r\n return all;\r\n },\r\n\r\n makeLine(siteID, boardID, threadID, data) {\r\n let page;\r\n const x = $.el('a', {\r\n textContent: '✕',\r\n href: 'javascript:;'\r\n }\r\n );\r\n $.on(x, 'click', ThreadWatcher.cb.rm);\r\n\r\n let {excerpt, isArchived} = data;\r\n if (!excerpt) { excerpt = `/${boardID}/ - No.${threadID}`; }\r\n if (Conf['Show Site Prefix']) { excerpt = ThreadWatcher.prefixes[siteID] + excerpt; }\r\n\r\n const link = $.el('a', {\r\n href: g.sites[siteID]?.urls.thread({siteID, boardID, threadID}, isArchived) || '',\r\n title: excerpt,\r\n className: 'watcher-link'\r\n }\r\n );\r\n\r\n if (Conf['Show Page'] && (data.page != null)) {\r\n page = $.el('span', {\r\n textContent: `[${data.page}]`,\r\n className: 'watcher-page'\r\n }\r\n );\r\n $.add(link, page);\r\n }\r\n\r\n if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count'] && (data.unread != null)) {\r\n const count = $.el('span', {\r\n textContent: `(${data.unread})`,\r\n className: 'watcher-unread'\r\n }\r\n );\r\n $.add(link, count);\r\n }\r\n\r\n const title = $.el('span', {\r\n textContent: excerpt,\r\n className: 'watcher-title'\r\n }\r\n );\r\n $.add(link, title);\r\n\r\n const div = $.el('div');\r\n const fullID = `${boardID}.${threadID}`;\r\n div.dataset.fullID = fullID;\r\n div.dataset.siteID = siteID;\r\n if ((g.VIEW === 'thread') && (fullID === `${g.BOARD}.${g.THREADID}`)) { $.addClass(div, 'current'); }\r\n if (data.isDead) { $.addClass(div, 'dead-thread'); }\r\n if (Conf['Show Page']) {\r\n if (data.lastPage) { $.addClass(div, 'last-page'); }\r\n if (data.page != null) { div.dataset.page = data.page; }\r\n }\r\n if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) {\r\n if (data.unread === 0) { $.addClass(div, 'replies-read'); }\r\n if (data.unread) { $.addClass(div, 'replies-unread'); }\r\n if ((data.quotingYou || 0) > (data.dismiss || 0)) { $.addClass(div, 'replies-quoting-you'); }\r\n }\r\n $.add(div, [x, $.tn(' '), link]);\r\n return div;\r\n },\r\n\r\n setPrefixes(threads) {\r\n const prefixes = dict();\r\n for (var {siteID} of threads) {\r\n if (siteID in prefixes) { continue; }\r\n var len = 0;\r\n var prefix = '';\r\n var conflicts = Object.keys(prefixes);\r\n while (conflicts.length > 0) {\r\n len++;\r\n prefix = siteID.slice(0, len);\r\n var conflicts2 = [];\r\n for (var siteID2 of conflicts) {\r\n if (siteID2.slice(0, len) === prefix) {\r\n conflicts2.push(siteID2);\r\n } else if (prefixes[siteID2].length < len) {\r\n prefixes[siteID2] = siteID2.slice(0, len);\r\n }\r\n }\r\n conflicts = conflicts2;\r\n }\r\n prefixes[siteID] = prefix;\r\n }\r\n return ThreadWatcher.prefixes = prefixes;\r\n },\r\n\r\n build() {\r\n const nodes = [];\r\n const threads = ThreadWatcher.getAll();\r\n ThreadWatcher.setPrefixes(threads);\r\n for (var {siteID, boardID, threadID, data} of threads) {\r\n // Add missing excerpt for threads added by Auto Watch\r\n var thread;\r\n if ((data.excerpt == null) && (siteID === g.SITE.ID) && (thread = g.threads.get(`${boardID}.${threadID}`)) && thread.OP) {\r\n ThreadWatcher.db.extend({boardID, threadID, val: {excerpt: Get.threadExcerpt(thread)}});\r\n }\r\n nodes.push(ThreadWatcher.makeLine(siteID, boardID, threadID, data));\r\n }\r\n const {list} = ThreadWatcher;\r\n $.rmAll(list);\r\n $.add(list, nodes);\r\n\r\n return ThreadWatcher.refreshIcon();\r\n },\r\n\r\n refresh() {\r\n ThreadWatcher.build();\r\n\r\n g.threads.forEach(function(thread) {\r\n const isWatched = ThreadWatcher.isWatched(thread);\r\n if (thread.OP) {\r\n for (var post of [thread.OP, ...Array.from(thread.OP.clones)]) {\r\n var toggler;\r\n if (toggler = $('.watch-thread-link', post.nodes.info)) {\r\n ThreadWatcher.setToggler(toggler, isWatched);\r\n }\r\n }\r\n }\r\n if (thread.catalogView) { return thread.catalogView.nodes.root.classList.toggle('watched', isWatched); }\r\n });\r\n\r\n if (Conf['Pin Watched Threads']) {\r\n return $.event('SortIndex', {deferred: Conf['Index Mode'] !== 'catalog'});\r\n }\r\n },\r\n\r\n refreshIcon() {\r\n for (var className of ['replies-unread', 'replies-quoting-you']) {\r\n ThreadWatcher.shortcut.classList.toggle(className, !!$(`.${className}`, ThreadWatcher.dialog));\r\n }\r\n },\r\n\r\n update(siteID, boardID, threadID, newData) {\r\n let data, key, line, val;\r\n if (!(data = ThreadWatcher.db?.get({siteID, boardID, threadID}))) { return; }\r\n if (newData.isDead && Conf['Auto Prune']) {\r\n ThreadWatcher.rm(siteID, boardID, threadID);\r\n return;\r\n }\r\n if (newData.isDead || (newData.last === -1)) {\r\n for (key of ['isArchived', 'page', 'lastPage', 'unread', 'quotingyou']) {\r\n if (!(key in newData)) {\r\n newData[key] = undefined;\r\n }\r\n }\r\n }\r\n if ((newData.last != null) && (newData.last < data.last)) {\r\n newData.modified = undefined;\r\n }\r\n let n = 0;\r\n for (key in newData) { val = newData[key]; if (data[key] !== val) { n++; } }\r\n if (!n) { return; }\r\n ThreadWatcher.db.extend({siteID, boardID, threadID, val: newData});\r\n if (line = $(`#watched-threads > [data-site-i-d='${siteID}'][data-full-i-d='${boardID}.${threadID}']`, ThreadWatcher.dialog)) {\r\n const newLine = ThreadWatcher.makeLine(siteID, boardID, threadID, data);\r\n $.replace(line, newLine);\r\n return ThreadWatcher.refreshIcon();\r\n } else {\r\n return ThreadWatcher.refresh();\r\n }\r\n },\r\n\r\n set404(boardID, threadID, cb) {\r\n let data;\r\n if (!(data = ThreadWatcher.db?.get({boardID, threadID}))) { return cb(); }\r\n if (Conf['Auto Prune']) {\r\n ThreadWatcher.db.delete({boardID, threadID});\r\n return cb();\r\n }\r\n if (data.isDead && !((data.isArchived != null) || (data.page != null) || (data.lastPage != null) || (data.unread != null) || (data.quotingYou != null))) { return cb(); }\r\n return ThreadWatcher.db.extend({boardID, threadID, val: {isDead: true, isArchived: undefined, page: undefined, lastPage: undefined, unread: undefined, quotingYou: undefined}}, cb);\r\n },\r\n\r\n toggle(thread) {\r\n const siteID = g.SITE.ID;\r\n const boardID = thread.board.ID;\r\n const threadID = thread.ID;\r\n if (ThreadWatcher.db.get({boardID, threadID})) {\r\n return ThreadWatcher.rm(siteID, boardID, threadID);\r\n } else {\r\n return ThreadWatcher.add(thread);\r\n }\r\n },\r\n\r\n add(thread, cb) {\r\n const data = {};\r\n const siteID = g.SITE.ID;\r\n const boardID = thread.board.ID;\r\n const threadID = thread.ID;\r\n if (thread.isDead) {\r\n if (Conf['Auto Prune'] && ThreadWatcher.db.get({boardID, threadID})) {\r\n ThreadWatcher.rm(siteID, boardID, threadID, cb);\r\n return;\r\n }\r\n data.isDead = true;\r\n }\r\n if (thread.OP) { data.excerpt = Get.threadExcerpt(thread); }\r\n return ThreadWatcher.addRaw(boardID, threadID, data, cb);\r\n },\r\n\r\n addRaw(boardID, threadID, data, cb) {\r\n const oldData = ThreadWatcher.db.get({ boardID, threadID, defaultValue: dict() });\r\n delete oldData.last;\r\n delete oldData.modified;\r\n $.extend(oldData, data);\r\n ThreadWatcher.db.set({boardID, threadID, val: oldData}, cb);\r\n ThreadWatcher.refresh();\r\n const thread = {siteID: g.SITE.ID, boardID, threadID, data, force: true};\r\n if (Conf['Show Page'] && !data.isDead) {\r\n return ThreadWatcher.fetchBoard([thread]);\r\n } else if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) {\r\n return ThreadWatcher.fetchStatus(thread);\r\n }\r\n },\r\n\r\n rm(siteID, boardID, threadID, cb) {\r\n ThreadWatcher.db.delete({siteID, boardID, threadID}, cb);\r\n return ThreadWatcher.refresh();\r\n },\r\n\r\n menu: {\r\n init() {\r\n if (!Conf['Thread Watcher']) { return; }\r\n const menu = (this.menu = new UI.Menu('thread watcher'));\r\n $.on($('.menu-button', ThreadWatcher.dialog), 'click', function(e) {\r\n return menu.toggle(e, this, ThreadWatcher);\r\n });\r\n return this.addMenuEntries();\r\n },\r\n\r\n addHeaderMenuEntry() {\r\n if (g.VIEW !== 'thread') { return; }\r\n const entryEl = $.el('a',\r\n {href: 'javascript:;'});\r\n Header.menu.addEntry({\r\n el: entryEl,\r\n order: 60,\r\n open() {\r\n const [addClass, rmClass, text] = Array.from(!!ThreadWatcher.db.get({boardID: g.BOARD.ID, threadID: g.THREADID}) ?\r\n ['unwatch-thread', 'watch-thread', 'Unwatch thread']\r\n :\r\n ['watch-thread', 'unwatch-thread', 'Watch thread']);\r\n $.addClass(entryEl, addClass);\r\n $.rmClass(entryEl, rmClass);\r\n entryEl.textContent = text;\r\n return true;\r\n }\r\n });\r\n return $.on(entryEl, 'click', () => ThreadWatcher.toggle(g.threads.get(`${g.BOARD}.${g.THREADID}`)));\r\n },\r\n\r\n addMenuEntries() {\r\n const entries = [];\r\n\r\n // `Open all` entry\r\n entries.push({\r\n text: 'Open all threads',\r\n cb: ThreadWatcher.cb.openAll,\r\n open() {\r\n this.el.classList.toggle('disabled', !ThreadWatcher.list.firstElementChild);\r\n return true;\r\n }\r\n });\r\n\r\n // `Open Unread` entry\r\n entries.push({\r\n text: 'Open unread threads',\r\n cb: ThreadWatcher.cb.openUnread,\r\n open() {\r\n this.el.classList.toggle('disabled', !$('.replies-unread', ThreadWatcher.list));\r\n return true;\r\n }\r\n });\r\n\r\n // `Open dead threads` entry\r\n entries.push({\r\n text: 'Open dead threads',\r\n cb: ThreadWatcher.cb.openDeads,\r\n open() {\r\n this.el.classList.toggle('disabled', !$('.dead-thread', ThreadWatcher.list));\r\n return true;\r\n }\r\n });\r\n\r\n // `Prune dead threads` entry\r\n entries.push({\r\n text: 'Prune dead threads',\r\n cb: ThreadWatcher.cb.pruneDeads,\r\n open() {\r\n this.el.classList.toggle('disabled', !$('.dead-thread', ThreadWatcher.list));\r\n return true;\r\n }\r\n });\r\n\r\n // `Dismiss posts quoting you` entry\r\n entries.push({\r\n text: 'Dismiss posts quoting you',\r\n title: 'Unhighlight the thread watcher icon and threads until there are new replies quoting you.',\r\n cb: ThreadWatcher.cb.dismiss,\r\n open() {\r\n this.el.classList.toggle('disabled', !$.hasClass(ThreadWatcher.shortcut, 'replies-quoting-you'));\r\n return true;\r\n }\r\n });\r\n\r\n for (var {text, title, cb, open} of entries) {\r\n var entry = {\r\n el: $.el('a', {\r\n textContent: text,\r\n href: 'javascript:;'\r\n }\r\n )\r\n };\r\n if (title) { entry.el.title = title; }\r\n $.on(entry.el, 'click', cb);\r\n entry.open = open.bind(entry);\r\n this.menu.addEntry(entry);\r\n }\r\n\r\n // Settings checkbox entries:\r\n for (var name in Config.threadWatcher) {\r\n var conf = Config.threadWatcher[name];\r\n this.addCheckbox(name, conf[1]);\r\n }\r\n\r\n },\r\n\r\n addCheckbox(name, desc) {\r\n const entry = {\r\n type: 'thread watcher',\r\n el: UI.checkbox(name, name.replace(' Thread Watcher', ''))\r\n };\r\n entry.el.title = desc;\r\n const input = entry.el.firstElementChild;\r\n if ((name === 'Show Unread Count') && !ThreadWatcher.unreadEnabled) {\r\n input.disabled = true;\r\n $.addClass(entry.el, 'disabled');\r\n entry.el.title += '\\n[Remember Last Read Post is disabled.]';\r\n }\r\n $.on(input, 'change', $.cb.checked);\r\n if (['Current Board', 'Show Page', 'Show Unread Count', 'Show Site Prefix'].includes(name)) { $.on(input, 'change', ThreadWatcher.refresh); }\r\n if (['Show Page', 'Show Unread Count', 'Auto Update Thread Watcher'].includes(name)) { $.on(input, 'change', ThreadWatcher.fetchAuto); }\r\n return this.menu.addEntry(entry);\r\n }\r\n }\r\n};\r\nexport default ThreadWatcher;\r\n","import Redirect from \"../Archive/Redirect\";\r\nimport Board from \"./Board\";\r\nimport Post from \"./Post\";\r\nimport Thread from \"./Thread\";\r\nimport $ from \"../platform/$\";\r\nimport Main from \"../main/Main\";\r\nimport Index from \"../General/Index\";\r\nimport { E, g, Conf, d } from \"../globals/globals\";\r\nimport ImageHost from \"../Images/ImageHost\";\r\nimport CrossOrigin from \"../platform/CrossOrigin\";\r\nimport Get from \"../General/Get\";\r\nimport { dict } from \"../platform/helpers\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS205: Consider reworking code to avoid use of IIFEs\r\n * DS206: Consider reworking classes to avoid initClass\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nexport default class Fetcher {\r\n static initClass() {\r\n \r\n this.prototype.archiveTags = {\r\n '\\n': {innerHTML: \"
            \"},\r\n '[b]': {innerHTML: \"\"},\r\n '[/b]': {innerHTML: \"\"},\r\n '[spoiler]': {innerHTML: \"\"},\r\n '[/spoiler]': {innerHTML: \"\"},\r\n '[code]': {innerHTML: \"
            \"},\r\n      '[/code]':    {innerHTML: \"
            \"},\r\n '[moot]': {innerHTML: \"
            \"},\r\n '[/moot]': {innerHTML: \"
            \"},\r\n '[banned]': {innerHTML: \"\"},\r\n '[/banned]': {innerHTML: \"\"},\r\n '[fortune]'(text) { return {innerHTML: \"\"}; },\r\n '[/fortune]': {innerHTML: \"\"},\r\n '[i]': {innerHTML: \"\"},\r\n '[/i]': {innerHTML: \"\"},\r\n '[red]': {innerHTML: \"\"},\r\n '[/red]': {innerHTML: \"\"},\r\n '[green]': {innerHTML: \"\"},\r\n '[/green]': {innerHTML: \"\"},\r\n '[blue]': {innerHTML: \"\"},\r\n '[/blue]': {innerHTML: \"\"}\r\n };\r\n }\r\n constructor(boardID, threadID, postID, root, quoter) {\r\n let post, thread;\r\n this.boardID = boardID;\r\n this.threadID = threadID;\r\n this.postID = postID;\r\n this.root = root;\r\n this.quoter = quoter;\r\n if (post = g.posts.get(`${this.boardID}.${this.postID}`)) {\r\n this.insert(post);\r\n return;\r\n }\r\n\r\n // 4chan X catalog data\r\n if ((post = Index.replyData?.[`${this.boardID}.${this.postID}`]) && (thread = g.threads.get(`${this.boardID}.${this.threadID}`))) {\r\n const board = g.boards[this.boardID];\r\n post = new Post(g.SITE.Build.postFromObject(post, this.boardID), thread, board, {isFetchedQuote: true});\r\n Main.callbackNodes('Post', [post]);\r\n this.insert(post);\r\n return;\r\n }\r\n\r\n this.root.textContent = `Loading post No.${this.postID}...`;\r\n if (this.threadID) {\r\n const that = this;\r\n $.cache(g.SITE.urls.threadJSON({boardID: this.boardID, threadID: this.threadID}), function({isCached}) {\r\n return that.fetchedPost(this, isCached);\r\n });\r\n } else {\r\n this.archivedPost();\r\n }\r\n }\r\n\r\n insert(post) {\r\n // Stop here if the container has been removed while loading.\r\n if (!this.root.parentNode) { return; }\r\n if (!this.quoter) { this.quoter = post; }\r\n const clone = post.addClone(this.quoter.context, ($.hasClass(this.root, 'dialog')));\r\n Main.callbackNodes('Post', [clone]);\r\n\r\n // Get rid of the side arrows/stubs.\r\n const {nodes} = clone;\r\n $.rmAll(nodes.root);\r\n $.add(nodes.root, nodes.post);\r\n\r\n // Indicate links to the containing post.\r\n const quotes = [...clone.nodes.quotelinks, ...clone.nodes.backlinks];\r\n for (var quote of quotes) {\r\n var {boardID, postID} = Get.postDataFromLink(quote);\r\n if ((postID === this.quoter.ID) && (boardID === this.quoter.board.ID)) {\r\n $.addClass(quote, 'forwardlink');\r\n }\r\n }\r\n\r\n // Set up flag CSS for cross-board links to boards with flags\r\n if (clone.nodes.flag && !(Fetcher.flagCSS || (Fetcher.flagCSS = $('link[href^=\"//s.4cdn.org/css/flags.\"]')))) {\r\n const cssVersion = $('link[href^=\"//s.4cdn.org/css/\"]')?.href.match(/\\d+(?=\\.css$)|$/)[0] || Date.now();\r\n Fetcher.flagCSS = $.el('link', {\r\n rel: 'stylesheet',\r\n href: `//s.4cdn.org/css/flags.${cssVersion}.css`\r\n }\r\n );\r\n $.add(d.head, Fetcher.flagCSS);\r\n }\r\n\r\n $.rmAll(this.root);\r\n $.add(this.root, nodes.root);\r\n return $.event('PostsInserted', null, this.root);\r\n }\r\n\r\n fetchedPost(req, isCached) {\r\n // In case of multiple callbacks for the same request,\r\n // don't parse the same original post more than once.\r\n let post;\r\n if (post = g.posts.get(`${this.boardID}.${this.postID}`)) {\r\n this.insert(post);\r\n return;\r\n }\r\n\r\n const {status} = req;\r\n if (status !== 200) {\r\n // The thread can die by the time we check a quote.\r\n if (status && this.archivedPost()) { return; }\r\n\r\n $.addClass(this.root, 'warning');\r\n this.root.textContent =\r\n status === 404 ?\r\n `Thread No.${this.threadID} 404'd.`\r\n : !status ?\r\n 'Connection Error'\r\n :\r\n `Error ${req.statusText} (${req.status}).`;\r\n return;\r\n }\r\n\r\n const {posts} = req.response;\r\n g.SITE.Build.spoilerRange[this.boardID] = posts[0].custom_spoiler;\r\n for (post of posts) {\r\n if (post.no === this.postID) { break; }\r\n } // we found it!\r\n\r\n if (post.no !== this.postID) {\r\n // Cached requests can be stale and must be rechecked.\r\n if (isCached) {\r\n const api = g.SITE.urls.threadJSON({boardID: this.boardID, threadID: this.threadID});\r\n $.cleanCache(url => url === api);\r\n const that = this;\r\n $.cache(api, function() {\r\n return that.fetchedPost(this, false);\r\n });\r\n return;\r\n }\r\n\r\n // The post can be deleted by the time we check a quote.\r\n if (this.archivedPost()) { return; }\r\n\r\n $.addClass(this.root, 'warning');\r\n this.root.textContent = `Post No.${this.postID} was not found.`;\r\n return;\r\n }\r\n\r\n const board = g.boards[this.boardID] ||\r\n new Board(this.boardID);\r\n const thread = g.threads.get(`${this.boardID}.${this.threadID}`) ||\r\n new Thread(this.threadID, board);\r\n post = new Post(g.SITE.Build.postFromObject(post, this.boardID), thread, board, {isFetchedQuote: true});\r\n Main.callbackNodes('Post', [post]);\r\n return this.insert(post);\r\n }\r\n\r\n archivedPost() {\r\n let url;\r\n if (!Conf['Resurrect Quotes']) { return false; }\r\n if (!(url = Redirect.to('post', {boardID: this.boardID, postID: this.postID}))) { return false; }\r\n const archive = Redirect.data.post[this.boardID];\r\n const encryptionOK = /^https:\\/\\//.test(url) || (location.protocol === 'http:');\r\n if (encryptionOK || Conf['Exempt Archives from Encryption']) {\r\n const that = this;\r\n CrossOrigin.cache(url, function() {\r\n if (!encryptionOK && this.response?.media) {\r\n const {media} = this.response;\r\n for (var key in media) {\r\n // Image/thumbnail URLs loaded over HTTP can be modified in transit.\r\n // Require them to be from an HTTP host so that no referrer is sent to them from an HTTPS page.\r\n if (/_link$/.test(key)) {\r\n if (!$.getOwn(media, key)?.match(/^http:\\/\\//)) { delete media[key]; }\r\n }\r\n }\r\n }\r\n return that.parseArchivedPost(this.response, url, archive);\r\n });\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n parseArchivedPost(data, url, archive) {\r\n // In case of multiple callbacks for the same request,\r\n // don't parse the same original post more than once.\r\n let post;\r\n if (post = g.posts.get(`${this.boardID}.${this.postID}`)) {\r\n this.insert(post);\r\n return;\r\n }\r\n\r\n if (data == null) {\r\n $.addClass(this.root, 'warning');\r\n this.root.textContent = `Error fetching Post No.${this.postID} from ${archive.name}.`;\r\n return;\r\n }\r\n\r\n if (data.error) {\r\n $.addClass(this.root, 'warning');\r\n this.root.textContent = data.error;\r\n return;\r\n }\r\n\r\n // https://github.com/eksopl/asagi/blob/v0.4.0b74/src/main/java/net/easymodo/asagi/YotsubaAbstract.java#L82-L129\r\n // https://github.com/FoolCode/FoolFuuka/blob/800bd090835489e7e24371186db6e336f04b85c0/src/Model/Comment.php#L368-L428\r\n // https://github.com/bstats/b-stats/blob/6abe7bffaf6e5f523498d760e54b110df5331fbb/inc/classes/Yotsuba.php#L157-L168\r\n let comment = (data.comment || '').split(/(\\n|\\[\\/?(?:b|spoiler|code|moot|banned|fortune(?: color=\"#\\w+\")?|i|red|green|blue)\\])/);\r\n comment = (() => {\r\n const result = [];\r\n for (let i = 0; i < comment.length; i++) {\r\n var text = comment[i];\r\n if ((i % 2) === 1) {\r\n var tag = Fetcher.archiveTags[text.replace(/\\ .*\\]/, ']')];\r\n if (typeof tag === 'function') { result.push(tag(text)); } else { result.push(tag); }\r\n } else {\r\n var greentext = text[0] === '>';\r\n text = text.replace(/(\\[\\/?[a-z]+):lit(\\])/g, '$1$2');\r\n text = text.split(/(>>(?:>\\/[a-z\\d]+\\/)?\\d+)/g).map((text2, j) =>\r\n {innerHTML: ((j % 2) ? \"\" + E(text2) + \"\" : E(text2));});\r\n text = {innerHTML: ((greentext) ? \"\" + E.cat(text) + \"\" : E.cat(text))};\r\n result.push(text);\r\n }\r\n }\r\n return result;\r\n })();\r\n comment = {innerHTML: E.cat(comment)};\r\n\r\n this.threadID = +data.thread_num;\r\n const o = {\r\n ID: this.postID,\r\n threadID: this.threadID,\r\n boardID: this.boardID,\r\n isReply: this.postID !== this.threadID\r\n };\r\n o.info = {\r\n subject: data.title,\r\n email: data.email,\r\n name: data.name || '',\r\n tripcode: data.trip,\r\n capcode: (() => { switch (data.capcode) {\r\n // https://github.com/pleebe/FoolFuuka/blob/bf4224eed04637a4d0bd4411c2bf5f9945dfec0b/assets/themes/foolz/foolfuuka-theme-fuuka/src/Partial/Board.php#L77\r\n case 'M': return 'Mod';\r\n case 'A': return 'Admin';\r\n case 'D': return 'Developer';\r\n case 'V': return 'Verified';\r\n case 'F': return 'Founder';\r\n case 'G': return 'Manager';\r\n } })(),\r\n uniqueID: data.poster_hash,\r\n flagCode: data.poster_country,\r\n flagCodeTroll: data.troll_country_code,\r\n flag: data.poster_country_name || data.troll_country_name,\r\n dateUTC: data.timestamp,\r\n dateText: data.fourchan_date,\r\n commentHTML: comment\r\n };\r\n if (o.info.capcode) { delete o.info.uniqueID; }\r\n if (data.media && !!+data.media.banned) {\r\n o.fileDeleted = true;\r\n } else if (data.media?.media_filename) {\r\n let {thumb_link} = data.media;\r\n // Fix URLs missing origin\r\n if (thumb_link?.[0] === '/') { thumb_link = url.split('/', 3).join('/') + thumb_link; }\r\n if (!Redirect.securityCheck(thumb_link)) { thumb_link = ''; }\r\n let media_link = Redirect.to('file', {boardID: this.boardID, filename: data.media.media_orig});\r\n if (!Redirect.securityCheck(media_link)) { media_link = ''; }\r\n o.file = {\r\n name: data.media.media_filename,\r\n url: media_link ||\r\n (this.boardID === 'f' ?\r\n `${location.protocol}//${ImageHost.flashHost()}/${this.boardID}/${encodeURIComponent(E(data.media.media_filename))}`\r\n :\r\n `${location.protocol}//${ImageHost.host()}/${this.boardID}/${data.media.media_orig}`),\r\n height: data.media.media_h,\r\n width: data.media.media_w,\r\n MD5: data.media.media_hash,\r\n size: $.bytesToString(data.media.media_size),\r\n thumbURL: thumb_link || `${location.protocol}//${ImageHost.thumbHost()}/${this.boardID}/${data.media.preview_orig}`,\r\n theight: data.media.preview_h,\r\n twidth: data.media.preview_w,\r\n isSpoiler: data.media.spoiler === '1'\r\n };\r\n if (!/\\.pdf$/.test(o.file.url)) { o.file.dimensions = `${o.file.width}x${o.file.height}`; }\r\n if ((this.boardID === 'f') && data.media.exif) { o.file.tag = JSON.parse(data.media.exif).Tag; }\r\n }\r\n o.extra = dict();\r\n\r\n const board = g.boards[this.boardID] ||\r\n new Board(this.boardID);\r\n const thread = g.threads.get(`${this.boardID}.${this.threadID}`) ||\r\n new Thread(this.threadID, board);\r\n post = new Post(g.SITE.Build.post(o), thread, board, {isFetchedQuote: true});\r\n post.kill();\r\n if (post.file) { post.file.thumbURL = o.file.thumbURL; }\r\n Main.callbackNodes('Post', [post]);\r\n return this.insert(post);\r\n }\r\n}\r\nFetcher.initClass();\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport Fetcher from \"../classes/Fetcher\";\r\nimport Get from \"../General/Get\";\r\nimport Header from \"../General/Header\";\r\nimport UI from \"../General/UI\";\r\nimport { Conf, d, g } from \"../globals/globals\";\r\nimport ExpandComment from \"../Miscellaneous/ExpandComment\";\r\nimport $ from \"../platform/$\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar QuotePreview = {\r\n init() {\r\n if (!Conf['Quote Previewing']) { return; }\r\n\r\n if (g.VIEW === 'archive') {\r\n $.on(d, 'mouseover', function(e) {\r\n if ((e.target.nodeName === 'A') && $.hasClass(e.target, 'quotelink')) {\r\n return QuotePreview.mouseover.call(e.target, e);\r\n }\r\n });\r\n }\r\n\r\n if (!['index', 'thread'].includes(g.VIEW)) { return; }\r\n\r\n if (Conf['Comment Expansion']) {\r\n ExpandComment.callbacks.push(this.node);\r\n }\r\n\r\n return Callbacks.Post.push({\r\n name: 'Quote Previewing',\r\n cb: this.node\r\n });\r\n },\r\n\r\n node() {\r\n for (var link of this.nodes.quotelinks.concat([...Array.from(this.nodes.backlinks)], this.nodes.archivelinks)) {\r\n $.on(link, 'mouseover', QuotePreview.mouseover);\r\n }\r\n },\r\n\r\n mouseover(e) {\r\n let origin;\r\n if (($.hasClass(this, 'inlined') && !$.hasClass(doc, 'catalog-mode')) || !d.contains(this)) { return; }\r\n\r\n const {boardID, threadID, postID} = Get.postDataFromLink(this);\r\n\r\n const qp = $.el('div', {\r\n id: 'qp',\r\n className: 'dialog'\r\n }\r\n );\r\n\r\n $.add(Header.hover, qp);\r\n new Fetcher(boardID, threadID, postID, qp, Get.postFromNode(this));\r\n\r\n UI.hover({\r\n root: this,\r\n el: qp,\r\n latestEvent: e,\r\n endEvents: 'mouseout click',\r\n cb: QuotePreview.mouseout\r\n });\r\n\r\n if (Conf['Quote Highlighting'] && (origin = g.posts.get(`${boardID}.${postID}`))) {\r\n const posts = [origin].concat(origin.clones);\r\n // Remove the clone that's in the qp from the array.\r\n posts.pop();\r\n for (var post of posts) {\r\n $.addClass(post.nodes.post, 'qphl');\r\n }\r\n }\r\n },\r\n\r\n mouseout() {\r\n // Stop if it only contains text.\r\n let root;\r\n if (!(root = this.el.firstElementChild)) { return; }\r\n\r\n $.event('PostsRemoved', null, Header.hover);\r\n\r\n const clone = Get.postFromRoot(root);\r\n let post = clone.origin;\r\n post.rmClone(root.dataset.clone);\r\n\r\n if (!Conf['Quote Highlighting']) { return; }\r\n for (post of [post].concat(post.clones)) {\r\n $.rmClass(post.nodes.post, 'qphl');\r\n }\r\n }\r\n};\r\nexport default QuotePreview;\r\n","/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS205: Consider reworking code to avoid use of IIFEs\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nimport Callbacks from '../classes/Callbacks';\r\nimport CatalogThread from '../classes/CatalogThread';\r\nimport Notice from '../classes/Notice';\r\nimport Post from '../classes/Post';\r\nimport Thread from '../classes/Thread';\r\nimport Config from '../config/Config';\r\nimport Filter from '../Filtering/Filter';\r\nimport PostHiding from '../Filtering/PostHiding';\r\nimport ThreadHiding from '../Filtering/ThreadHiding';\r\nimport Main from '../main/Main';\r\nimport CatalogLinks from '../Miscellaneous/CatalogLinks';\r\nimport RelativeDates from '../Miscellaneous/RelativeDates';\r\nimport ThreadWatcher from '../Monitoring/ThreadWatcher';\r\nimport $$ from '../platform/$$';\r\nimport $ from '../platform/$';\r\nimport QuotePreview from '../Quotelinks/QuotePreview';\r\nimport { c, Conf, d, doc, g } from '../globals/globals';\r\nimport Header from './Header';\r\nimport UI from './UI';\r\nimport Menu from '../Menu/Menu';\r\n\r\nimport NavLinksPage from './Index/NavLinks.html';\r\nimport PageList from './Index/PageList.html';\r\nimport BoardConfig from './BoardConfig';\r\nimport Get from './Get';\r\nimport { dict, SECOND } from '../platform/helpers';\r\n\r\nvar Index = {\r\n showHiddenThreads: false,\r\n changed: {},\r\n\r\n enabledOn({siteID, boardID}) {\r\n return Conf['JSON Index'] && (g.sites[siteID].software === 'yotsuba') && (boardID !== 'f');\r\n },\r\n\r\n init() {\r\n let input, inputs, name;\r\n if (g.VIEW !== 'index') { return; }\r\n\r\n // For IndexRefresh events\r\n $.one(d, '4chanXInitFinished', this.cb.initFinished);\r\n $.on(d, 'PostsInserted', this.cb.postsInserted);\r\n\r\n if (!this.enabledOn(g.BOARD)) { return; }\r\n\r\n this.enabled = true;\r\n\r\n Callbacks.Post.push({\r\n name: 'Index Page Numbers',\r\n cb: this.node\r\n });\r\n Callbacks.CatalogThread.push({\r\n name: 'Catalog Features',\r\n cb: this.catalogNode\r\n });\r\n\r\n this.search = history.state?.searched || '';\r\n if (history.state?.mode) {\r\n Conf['Index Mode'] = history.state?.mode;\r\n }\r\n this.currentSort = history.state?.sort;\r\n if (!this.currentSort) { this.currentSort = typeof Conf['Index Sort'] === 'object' ? (\r\n Conf['Index Sort'][g.BOARD.ID] || 'bump'\r\n ) : (\r\n Conf['Index Sort']\r\n ); }\r\n this.currentPage = this.getCurrentPage();\r\n this.processHash();\r\n\r\n $.addClass(doc, 'index-loading', `${Conf['Index Mode'].replace(/\\ /g, '-')}-mode`);\r\n $.on(window, 'popstate', this.cb.popstate);\r\n $.on(d, 'scroll', this.scroll);\r\n $.on(d, 'SortIndex', this.cb.resort);\r\n\r\n // Header refresh button\r\n this.button = $.el('a', {\r\n title: 'Refresh',\r\n href: 'javascript:;',\r\n textContent: '🗘'\r\n }\r\n );\r\n $.on(this.button, 'click', () => Index.update());\r\n Header.addShortcut('index-refresh', this.button, 590);\r\n\r\n // Header \"Index Navigation\" submenu\r\n const entries = [];\r\n this.inputs = (inputs = dict());\r\n for (name in Config.Index) {\r\n var arr = Config.Index[name];\r\n if (arr instanceof Array) {\r\n var label = UI.checkbox(name, `${name[0]}${name.slice(1).toLowerCase()}`);\r\n label.title = arr[1];\r\n entries.push({el: label});\r\n input = label.firstChild;\r\n $.on(input, 'change', $.cb.checked);\r\n inputs[name] = input;\r\n }\r\n }\r\n $.on(inputs['Show Replies'], 'change', this.cb.replies);\r\n $.on(inputs['Catalog Hover Expand'], 'change', this.cb.hover);\r\n $.on(inputs['Pin Watched Threads'], 'change', this.cb.resort);\r\n $.on(inputs['Anchor Hidden Threads'], 'change', this.cb.resort);\r\n\r\n const watchSettings = function(e) {\r\n if (input = $.getOwn(inputs, e.target.name)) {\r\n input.checked = e.target.checked;\r\n return $.event('change', null, input);\r\n }\r\n };\r\n $.on(d, 'OpenSettings', () => $.on($.id('fourchanx-settings'), 'change', watchSettings));\r\n\r\n const sortEntry = UI.checkbox('Per-Board Sort Type', 'Per-board sort type', (typeof Conf['Index Sort'] === 'object'));\r\n sortEntry.title = 'Set the sorting order of each board independently.';\r\n $.on(sortEntry.firstChild, 'change', this.cb.perBoardSort);\r\n entries.splice(3, 0, {el: sortEntry});\r\n\r\n Header.menu.addEntry({\r\n el: $.el('span',\r\n {textContent: 'Index Navigation'}),\r\n order: 100,\r\n subEntries: entries\r\n });\r\n\r\n // Navigation links at top of index\r\n this.navLinks = $.el('div', {className: 'navLinks json-index'});\r\n $.extend(this.navLinks, {innerHTML: NavLinksPage});\r\n $('.cataloglink a', this.navLinks).href = CatalogLinks.catalog();\r\n if (!BoardConfig.isArchived(g.BOARD.ID)) { $('.archlistlink', this.navLinks).hidden = true; }\r\n $.on($('#index-last-refresh a', this.navLinks), 'click', this.cb.refreshFront);\r\n\r\n // Search field\r\n this.searchInput = $('#index-search', this.navLinks);\r\n this.setupSearch();\r\n $.on(this.searchInput, 'input', this.onSearchInput);\r\n $.on($('#index-search-clear', this.navLinks), 'click', this.clearSearch);\r\n\r\n // Hidden threads toggle\r\n this.hideLabel = $('#hidden-label', this.navLinks);\r\n $.on($('#hidden-toggle a', this.navLinks), 'click', this.cb.toggleHiddenThreads);\r\n\r\n // Drop-down menus and reverse sort toggle\r\n this.selectRev = $('#index-rev', this.navLinks);\r\n this.selectMode = $('#index-mode', this.navLinks);\r\n this.selectSort = $('#index-sort', this.navLinks);\r\n this.selectSize = $('#index-size', this.navLinks);\r\n $.on(this.selectRev, 'change', this.cb.sort);\r\n $.on(this.selectMode, 'change', this.cb.mode);\r\n $.on(this.selectSort, 'change', this.cb.sort);\r\n $.on(this.selectSize, 'change', $.cb.value);\r\n $.on(this.selectSize, 'change', this.cb.size);\r\n for (var select of [this.selectMode, this.selectSize]) {\r\n select.value = Conf[select.name];\r\n }\r\n this.selectRev.checked = /-rev$/.test(Index.currentSort);\r\n this.selectSort.value = Index.currentSort.replace(/-rev$/, '');\r\n\r\n // Last Long Reply options\r\n this.lastLongOptions = $('#lastlong-options', this.navLinks);\r\n this.lastLongInputs = $$('input', this.lastLongOptions);\r\n this.lastLongThresholds = [0, 0];\r\n this.lastLongOptions.hidden = (this.selectSort.value !== 'lastlong');\r\n for (let i = 0; i < this.lastLongInputs.length; i++) {\r\n input = this.lastLongInputs[i];\r\n $.on(input, 'change', this.cb.lastLongThresholds);\r\n var tRaw = Conf[`Last Long Reply Thresholds ${i}`];\r\n input.value = (this.lastLongThresholds[i] =\r\n typeof tRaw === 'object' ? (tRaw[g.BOARD.ID] ?? 100) : tRaw);\r\n }\r\n\r\n // Thread container\r\n this.root = $.el('div', {className: 'board json-index'});\r\n $.on(this.root, 'click', this.cb.hoverToggle);\r\n this.cb.size();\r\n this.cb.hover();\r\n\r\n // Page list\r\n this.pagelist = $.el('div', {className: 'pagelist json-index'});\r\n $.extend(this.pagelist, {innerHTML: PageList});\r\n $('.cataloglink a', this.pagelist).href = CatalogLinks.catalog();\r\n $.on(this.pagelist, 'click', this.cb.pageNav);\r\n\r\n this.update(true);\r\n\r\n $.onExists(doc, 'title + *', () => d.title = d.title.replace(/\\ -\\ Page\\ \\d+/, ''));\r\n\r\n $.onExists(doc, '.board > .thread > .postContainer, .board + *', function() {\r\n let el;\r\n g.SITE.Build.hat = $('.board > .thread > img:first-child');\r\n if (g.SITE.Build.hat) {\r\n g.BOARD.threads.forEach(function(thread) {\r\n if (thread.nodes.root) {\r\n return $.prepend(thread.nodes.root, g.SITE.Build.hat.cloneNode(false));\r\n }\r\n });\r\n $.addClass(doc, 'hats-enabled');\r\n $.addStyle(`.catalog-thread::after {background-image: url(${g.SITE.Build.hat.src});}`);\r\n }\r\n\r\n const board = $('.board');\r\n $.replace(board, Index.root);\r\n if (Index.loaded) {\r\n $.event('PostsInserted', null, Index.root);\r\n }\r\n // Hacks:\r\n // - When removing an element from the document during page load,\r\n // its ancestors will still be correctly created inside of it.\r\n // - Creating loadable elements inside of an origin-less document\r\n // will not download them.\r\n // - Combine the two and you get a download canceller!\r\n // Does not work on Firefox unfortunately. bugzil.la/939713\r\n try {\r\n d.implementation.createDocument(null, null, null).appendChild(board);\r\n } catch (error) {}\r\n\r\n for (el of $$('.navLinks')) { $.rm(el); }\r\n $.rm($.id('ctrl-top'));\r\n const topNavPos = $.id('delform').previousElementSibling;\r\n $.before(topNavPos, $.el('hr'));\r\n $.before(topNavPos, Index.navLinks);\r\n const timeEl = $('#index-last-refresh time', Index.navLinks);\r\n if (timeEl.dataset.utc) { return RelativeDates.update(timeEl); }\r\n });\r\n\r\n return Main.ready(function() {\r\n let pagelist;\r\n if (pagelist = $('.pagelist')) {\r\n $.replace(pagelist, Index.pagelist);\r\n }\r\n return $.rmClass(doc, 'index-loading');\r\n });\r\n },\r\n\r\n scroll() {\r\n if (Index.req || !Index.liveThreadData || (Conf['Index Mode'] !== 'infinite') || (window.scrollY <= (doc.scrollHeight - (300 + window.innerHeight)))) { return; }\r\n if (Index.pageNum == null) { Index.pageNum = Index.currentPage; } // Avoid having to pushState to keep track of the current page\r\n\r\n const pageNum = ++Index.pageNum;\r\n if (pageNum > Index.pagesNum) { return Index.endNotice(); }\r\n\r\n const threadIDs = Index.threadsOnPage(pageNum);\r\n return Index.buildStructure(threadIDs);\r\n },\r\n\r\n endNotice: (function() {\r\n let notify = false;\r\n const reset = () => notify = false;\r\n return function() {\r\n if (notify) { return; }\r\n notify = true;\r\n new Notice('info', \"Last page reached.\", 2);\r\n return setTimeout(reset, 3 * SECOND);\r\n };\r\n })(),\r\n\r\n menu: {\r\n init() {\r\n if ((g.VIEW !== 'index') || !Conf['Menu'] || !Conf['Thread Hiding Link'] || !Index.enabledOn(g.BOARD)) { return; }\r\n\r\n return Menu.menu.addEntry({\r\n el: $.el('a', {\r\n href: 'javascript:;',\r\n className: 'has-shortcut-text'\r\n }\r\n , {innerHTML: \"Shift+click\"}),\r\n order: 20,\r\n open({thread}) {\r\n if (Conf['Index Mode'] !== 'catalog') { return false; }\r\n this.el.firstElementChild.textContent = thread.isHidden ?\r\n 'Unhide'\r\n :\r\n 'Hide';\r\n if (this.cb) { $.off(this.el, 'click', this.cb); }\r\n this.cb = function() {\r\n $.event('CloseMenu');\r\n return Index.toggleHide(thread);\r\n };\r\n $.on(this.el, 'click', this.cb);\r\n return true;\r\n }\r\n });\r\n }\r\n },\r\n\r\n node() {\r\n if (this.isReply || this.isClone || (Index.threadPosition[this.ID] == null)) { return; }\r\n return this.thread.setPage(Math.floor(Index.threadPosition[this.ID] / Index.threadsNumPerPage) + 1);\r\n },\r\n\r\n catalogNode() {\r\n return $.on(this.nodes.root, 'mousedown click', e => {\r\n if ((e.button !== 0) || !e.shiftKey) { return; }\r\n if (e.type === 'click') { Index.toggleHide(this.thread); }\r\n return e.preventDefault();\r\n });\r\n }, // Also on mousedown to prevent highlighting text.\r\n\r\n toggleHide(thread) {\r\n if (Index.showHiddenThreads) {\r\n ThreadHiding.show(thread);\r\n if (!ThreadHiding.db.get({boardID: thread.board.ID, threadID: thread.ID})) { return; }\r\n // Don't save when un-hiding filtered threads.\r\n } else {\r\n ThreadHiding.hide(thread);\r\n }\r\n return ThreadHiding.saveHiddenState(thread);\r\n },\r\n\r\n cycleSortType() {\r\n let i;\r\n const types = [...Array.from(Index.selectSort.options)].filter(option => !option.disabled);\r\n for (i = 0; i < types.length; i++) {\r\n var type = types[i];\r\n if (type.selected) { break; }\r\n }\r\n types[(i + 1) % types.length].selected = true;\r\n return $.event('change', null, Index.selectSort);\r\n },\r\n\r\n cb: {\r\n initFinished() {\r\n Index.initFinishedFired = true;\r\n return $.queueTask(() => Index.cb.postsInserted());\r\n },\r\n\r\n postsInserted() {\r\n if (!Index.initFinishedFired) { return; }\r\n let n = 0;\r\n g.posts.forEach(function(post) {\r\n if (!post.isFetchedQuote && !post.indexRefreshSeen && doc.contains(post.nodes.root)) {\r\n post.indexRefreshSeen = true;\r\n return n++;\r\n }\r\n });\r\n if (n) { return $.event('IndexRefresh'); }\r\n },\r\n\r\n toggleHiddenThreads() {\r\n $('#hidden-toggle a', Index.navLinks).textContent = (Index.showHiddenThreads = !Index.showHiddenThreads) ?\r\n 'Hide'\r\n :\r\n 'Show';\r\n Index.sort();\r\n return Index.buildIndex();\r\n },\r\n\r\n mode() {\r\n Index.pushState({mode: this.value});\r\n return Index.pageLoad(false);\r\n },\r\n\r\n sort() {\r\n const value = Index.selectRev.checked ? Index.selectSort.value + \"-rev\" : Index.selectSort.value;\r\n Index.pushState({sort: value});\r\n return Index.pageLoad(false);\r\n },\r\n\r\n resort(e) {\r\n Index.changed.order = true;\r\n if (!e?.detail?.deferred) { return Index.pageLoad(false); }\r\n },\r\n\r\n perBoardSort() {\r\n Conf['Index Sort'] = this.checked ? dict() : '';\r\n Index.saveSort();\r\n for (let i = 0; i < 2; i++) {\r\n Conf[`Last Long Reply Thresholds ${i}`] = this.checked ? dict() : '';\r\n Index.saveLastLongThresholds(i);\r\n }\r\n },\r\n\r\n lastLongThresholds() {\r\n const i = [...Array.from(this.parentNode.children)].indexOf(this);\r\n const value = +this.value;\r\n if (!Number.isFinite(value)) {\r\n this.value = Index.lastLongThresholds[i];\r\n return;\r\n }\r\n Index.lastLongThresholds[i] = value;\r\n Index.saveLastLongThresholds(i);\r\n Index.changed.order = true;\r\n return Index.pageLoad(false);\r\n },\r\n\r\n size(e) {\r\n if (Conf['Index Mode'] !== 'catalog') {\r\n $.rmClass(Index.root, 'catalog-small');\r\n $.rmClass(Index.root, 'catalog-large');\r\n } else if (Conf['Index Size'] === 'small') {\r\n $.addClass(Index.root, 'catalog-small');\r\n $.rmClass(Index.root, 'catalog-large');\r\n } else {\r\n $.addClass(Index.root, 'catalog-large');\r\n $.rmClass(Index.root, 'catalog-small');\r\n }\r\n if (e) { return Index.buildIndex(); }\r\n },\r\n\r\n replies() {\r\n return Index.buildIndex();\r\n },\r\n\r\n hover() {\r\n return doc.classList.toggle('catalog-hover-expand', Conf['Catalog Hover Expand']);\r\n },\r\n\r\n hoverToggle(e) {\r\n if (Conf['Catalog Hover Toggle'] && $.hasClass(doc, 'catalog-mode') && !$.modifiedClick(e) && !$.x('ancestor-or-self::a', e.target)) {\r\n let thread;\r\n const input = Index.inputs['Catalog Hover Expand'];\r\n input.checked = !input.checked;\r\n $.event('change', null, input);\r\n if (thread = Get.threadFromNode(e.target)) {\r\n Index.cb.catalogReplies.call(thread);\r\n return Index.cb.hoverAdjust.call(thread.OP.nodes);\r\n }\r\n }\r\n },\r\n\r\n popstate(e) {\r\n if (e?.state) {\r\n const {searched, mode, sort} = e.state;\r\n const page = Index.getCurrentPage();\r\n Index.setState({search: searched, mode, sort, page});\r\n return Index.pageLoad(false);\r\n } else {\r\n // page load or hash change\r\n const nCommands = Index.processHash();\r\n if (Conf['Refreshed Navigation'] && nCommands) {\r\n return Index.update();\r\n } else {\r\n return Index.pageLoad();\r\n }\r\n }\r\n },\r\n\r\n pageNav(e) {\r\n let a;\r\n if ($.modifiedClick(e)) { return; }\r\n switch (e.target.nodeName) {\r\n case 'BUTTON':\r\n e.target.blur();\r\n a = e.target.parentNode;\r\n break;\r\n case 'A':\r\n a = e.target;\r\n break;\r\n default:\r\n return;\r\n }\r\n if (a.textContent === 'Catalog') { return; }\r\n e.preventDefault();\r\n return Index.userPageNav(+a.pathname.split(/\\/+/)[2] || 1);\r\n },\r\n\r\n refreshFront() {\r\n Index.pushState({page: 1});\r\n return Index.update();\r\n },\r\n\r\n catalogReplies() {\r\n if (Conf['Show Replies'] && $.hasClass(doc, 'catalog-hover-expand') && !this.catalogView.nodes.replies) {\r\n return Index.buildCatalogReplies(this);\r\n }\r\n },\r\n\r\n hoverAdjust() {\r\n // Prevent hovered catalog threads from going offscreen.\r\n let x;\r\n if (!$.hasClass(doc, 'catalog-hover-expand')) { return; }\r\n const rect = this.post.getBoundingClientRect();\r\n if (x = $.minmax(0, -rect.left, doc.clientWidth - rect.right)) {\r\n const {style} = this.post;\r\n style.left = `${x}px`;\r\n style.right = `${-x}px`;\r\n return $.one(this.root, 'mouseleave', () => style.left = (style.right = null));\r\n }\r\n }\r\n },\r\n\r\n scrollToIndex() {\r\n // Scroll to navlinks, or top of board if navlinks are hidden.\r\n return Header.scrollToIfNeeded((Index.navLinks.getBoundingClientRect().height ? Index.navLinks : Index.root));\r\n },\r\n\r\n getCurrentPage() {\r\n return +window.location.pathname.split(/\\/+/)[2] || 1;\r\n },\r\n\r\n userPageNav(page) {\r\n Index.pushState({page});\r\n if (Conf['Refreshed Navigation']) {\r\n return Index.update();\r\n } else {\r\n return Index.pageLoad();\r\n }\r\n },\r\n\r\n hashCommands: {\r\n mode: {\r\n 'paged': 'paged',\r\n 'infinite-scrolling': 'infinite',\r\n 'infinite': 'infinite',\r\n 'all-threads': 'all pages',\r\n 'all-pages': 'all pages',\r\n 'catalog': 'catalog'\r\n },\r\n sort: {\r\n 'bump-order': 'bump',\r\n 'last-reply': 'lastreply',\r\n 'last-long-reply': 'lastlong',\r\n 'creation-date': 'birth',\r\n 'reply-count': 'replycount',\r\n 'file-count': 'filecount',\r\n 'posts-per-minute': 'activity'\r\n }\r\n },\r\n\r\n processHash() {\r\n // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=483304\r\n let hash = location.href.match(/#.*/)?.[0] || '';\r\n const state =\r\n {replace: true};\r\n const commands = hash.slice(1).split('/');\r\n const leftover = [];\r\n for (var command of commands) {\r\n var mode, sort;\r\n if (mode = $.getOwn(Index.hashCommands.mode, command)) {\r\n state.mode = mode;\r\n } else if (command === 'index') {\r\n state.mode = Conf['Previous Index Mode'];\r\n state.page = 1;\r\n } else if (sort = $.getOwn(Index.hashCommands.sort, command.replace(/-rev$/, ''))) {\r\n state.sort = sort;\r\n if (/-rev$/.test(command)) { state.sort += '-rev'; }\r\n } else if (/^s=/.test(command)) {\r\n state.search = decodeURIComponent(command.slice(2)).replace(/\\+/g, ' ').trim();\r\n } else {\r\n leftover.push(command);\r\n }\r\n }\r\n hash = leftover.join('/');\r\n if (hash) { state.hash = `#${hash}`; }\r\n Index.pushState(state);\r\n return commands.length - leftover.length;\r\n },\r\n\r\n pushState(state) {\r\n let {search, hash, replace} = state;\r\n let pageBeforeSearch = history.state?.oldpage;\r\n if ((search != null) && (search !== Index.search)) {\r\n state.page = search ? 1 : (pageBeforeSearch || 1);\r\n if (!search) {\r\n pageBeforeSearch = undefined;\r\n } else if (!Index.search) {\r\n pageBeforeSearch = Index.currentPage;\r\n }\r\n }\r\n Index.setState(state);\r\n const pathname = Index.currentPage === 1 ? `/${g.BOARD}/` : `/${g.BOARD}/${Index.currentPage}`;\r\n if (!hash) { hash = ''; }\r\n return history[replace ? 'replaceState' : 'pushState']({\r\n mode: Conf['Index Mode'],\r\n sort: Index.currentSort,\r\n searched: Index.search,\r\n oldpage: pageBeforeSearch\r\n }\r\n , '', `${location.protocol}//${location.host}${pathname}${hash}`);\r\n },\r\n\r\n setState({search, mode, sort, page, hash}) {\r\n if ((search != null) && (search !== Index.search)) {\r\n Index.changed.search = true;\r\n Index.search = search;\r\n }\r\n if ((mode != null) && (mode !== Conf['Index Mode'])) {\r\n Index.changed.mode = true;\r\n Conf['Index Mode'] = mode;\r\n $.set('Index Mode', mode);\r\n if ((mode !== 'catalog') && (Conf['Previous Index Mode'] !== mode)) {\r\n Conf['Previous Index Mode'] = mode;\r\n $.set('Previous Index Mode', mode);\r\n }\r\n }\r\n if ((sort != null) && (sort !== Index.currentSort)) {\r\n Index.changed.sort = true;\r\n Index.currentSort = sort;\r\n Index.saveSort();\r\n }\r\n if (['all pages', 'catalog'].includes(Conf['Index Mode'])) { page = 1; }\r\n if ((page != null) && (page !== Index.currentPage)) {\r\n Index.changed.page = true;\r\n Index.currentPage = page;\r\n }\r\n if (hash != null) {\r\n return Index.changed.hash = true;\r\n }\r\n },\r\n\r\n savePerBoard(key, value) {\r\n if (typeof Conf[key] === 'object') {\r\n Conf[key][g.BOARD.ID] = value;\r\n } else {\r\n Conf[key] = value;\r\n }\r\n return $.set(key, Conf[key]);\r\n },\r\n\r\n saveSort() {\r\n return Index.savePerBoard('Index Sort', Index.currentSort);\r\n },\r\n\r\n saveLastLongThresholds(i) {\r\n return Index.savePerBoard(`Last Long Reply Thresholds ${i}`, Index.lastLongThresholds[i]);\r\n },\r\n\r\n pageLoad(scroll=true) {\r\n if (!Index.liveThreadData) { return; }\r\n let {threads, order, search, mode, sort, page, hash} = Index.changed;\r\n if (!threads) { threads = search; }\r\n if (!order) { order = sort; }\r\n if (threads || order) { Index.sort(); }\r\n if (threads) { Index.buildPagelist(); }\r\n if (search) { Index.setupSearch(); }\r\n if (mode) { Index.setupMode(); }\r\n if (sort) { Index.setupSort(); }\r\n if (threads || mode || page || order) { Index.buildIndex(); }\r\n if (threads || page) { Index.setPage(); }\r\n if (scroll && !hash) { Index.scrollToIndex(); }\r\n if (hash) { Header.hashScroll(); }\r\n return Index.changed = {};\r\n },\r\n\r\n setupMode() {\r\n for (var mode of ['paged', 'infinite', 'all pages', 'catalog']) {\r\n $[mode === Conf['Index Mode'] ? 'addClass' : 'rmClass'](doc, `${mode.replace(/\\ /g, '-')}-mode`);\r\n }\r\n Index.selectMode.value = Conf['Index Mode'];\r\n Index.cb.size();\r\n Index.showHiddenThreads = false;\r\n return $('#hidden-toggle a', Index.navLinks).textContent = 'Show';\r\n },\r\n\r\n setupSort() {\r\n Index.selectRev.checked = /-rev$/.test(Index.currentSort);\r\n Index.selectSort.value = Index.currentSort.replace(/-rev$/, '');\r\n return Index.lastLongOptions.hidden = (Index.selectSort.value !== 'lastlong');\r\n },\r\n\r\n getPagesNum() {\r\n if (Index.search) {\r\n return Math.ceil(Index.sortedThreadIDs.length / Index.threadsNumPerPage);\r\n } else {\r\n return Index.pagesNum;\r\n }\r\n },\r\n\r\n getMaxPageNum() {\r\n return Math.max(1, Index.getPagesNum());\r\n },\r\n\r\n buildPagelist() {\r\n const pagesRoot = $('.pages', Index.pagelist);\r\n const maxPageNum = Index.getMaxPageNum();\r\n if (pagesRoot.childElementCount !== maxPageNum) {\r\n const nodes = [];\r\n for (let i = 1, end = maxPageNum; i <= end; i++) {\r\n var a = $.el('a', {\r\n textContent: i,\r\n href: i === 1 ? './' : i\r\n }\r\n );\r\n nodes.push($.tn('['), a, $.tn('] '));\r\n }\r\n $.rmAll(pagesRoot);\r\n return $.add(pagesRoot, nodes);\r\n }\r\n },\r\n\r\n setPage() {\r\n let a, strong;\r\n const pageNum = Index.currentPage;\r\n const maxPageNum = Index.getMaxPageNum();\r\n const pagesRoot = $('.pages', Index.pagelist);\r\n\r\n // Previous/Next buttons\r\n const prev = pagesRoot.previousElementSibling.firstElementChild;\r\n const next = pagesRoot.nextElementSibling.firstElementChild;\r\n let href = Math.max(pageNum - 1, 1);\r\n prev.href = href === 1 ? './' : href;\r\n prev.firstElementChild.disabled = href === pageNum;\r\n href = Math.min(pageNum + 1, maxPageNum);\r\n next.href = href === 1 ? './' : href;\r\n next.firstElementChild.disabled = href === pageNum;\r\n\r\n // current page\r\n if (strong = $('strong', pagesRoot)) {\r\n if (+strong.textContent === pageNum) { return; }\r\n $.replace(strong, strong.firstChild);\r\n } else {\r\n strong = $.el('strong');\r\n }\r\n\r\n if (a = pagesRoot.children[pageNum - 1]) {\r\n $.before(a, strong);\r\n return $.add(strong, a);\r\n }\r\n },\r\n\r\n updateHideLabel() {\r\n if (!Index.hideLabel) { return; }\r\n let hiddenCount = 0;\r\n for (var threadID of Index.liveThreadIDs) {\r\n if (Index.isHidden(threadID)) {\r\n hiddenCount++;\r\n }\r\n }\r\n if (!hiddenCount) {\r\n Index.hideLabel.hidden = true;\r\n if (Index.showHiddenThreads) { Index.cb.toggleHiddenThreads(); }\r\n return;\r\n }\r\n Index.hideLabel.hidden = false;\r\n return $('#hidden-count', Index.navLinks).textContent = hiddenCount === 1 ?\r\n '1 hidden thread'\r\n :\r\n `${hiddenCount} hidden threads`;\r\n },\r\n\r\n update(firstTime) {\r\n let oldReq;\r\n if (oldReq = Index.req) {\r\n delete Index.req;\r\n oldReq.abort();\r\n }\r\n\r\n if (Conf['Index Refresh Notifications']) {\r\n // Optional notification for manual refreshes\r\n if (!Index.notice) { Index.notice = new Notice('info', 'Refreshing index...'); }\r\n if (!Index.nTimeout) { Index.nTimeout = setTimeout(() => {\r\n if (Index.notice) {\r\n Index.notice.el.lastElementChild.textContent += ' (disable JSON Index if this takes too long)';\r\n }\r\n }\r\n , 3 * SECOND); }\r\n } else {\r\n // Also display notice if Index Refresh is taking too long\r\n if (!Index.nTimeout) { Index.nTimeout = setTimeout(() => Index.notice || (Index.notice = new Notice('info', 'Refreshing index... (disable JSON Index if this takes too long)'))\r\n , 3 * SECOND); }\r\n }\r\n\r\n // Hard refresh in case of incomplete page load.\r\n if (!firstTime && (d.readyState !== 'loading') && !$('.board + *')) {\r\n location.reload();\r\n return;\r\n }\r\n\r\n Index.req = $.whenModified(\r\n g.SITE.urls.catalogJSON({boardID: g.BOARD.ID}),\r\n 'Index',\r\n Index.load\r\n );\r\n return $.addClass(Index.button, 'spin');\r\n },\r\n\r\n load() {\r\n let err;\r\n if (this !== Index.req) { return; } // aborted\r\n\r\n $.rmClass(Index.button, 'spin');\r\n const {notice, nTimeout} = Index;\r\n if (nTimeout) { clearTimeout(nTimeout); }\r\n delete Index.nTimeout;\r\n delete Index.req;\r\n delete Index.notice;\r\n\r\n if (![200, 304].includes(this.status)) {\r\n err = `Index refresh failed. ${this.status ? `Error ${this.statusText} (${this.status})` : 'Connection Error'}`;\r\n if (notice) {\r\n notice.setType('warning');\r\n notice.el.lastElementChild.textContent = err;\r\n setTimeout(notice.close, SECOND);\r\n } else {\r\n new Notice('warning', err, 1);\r\n }\r\n return;\r\n }\r\n\r\n try {\r\n if (this.status === 200) {\r\n Index.parse(this.response);\r\n } else if (this.status === 304) {\r\n Index.pageLoad();\r\n }\r\n } catch (error) {\r\n err = error;\r\n c.error(`Index failure: ${err.message}`, err.stack);\r\n if (notice) {\r\n notice.setType('error');\r\n notice.el.lastElementChild.textContent = 'Index refresh failed.';\r\n setTimeout(notice.close, SECOND);\r\n } else {\r\n new Notice('error', 'Index refresh failed.', 1);\r\n }\r\n return;\r\n }\r\n\r\n if (notice) {\r\n if (Conf['Index Refresh Notifications']) {\r\n notice.setType('success');\r\n notice.el.lastElementChild.textContent = 'Index refreshed!';\r\n setTimeout(notice.close, SECOND);\r\n } else {\r\n notice.close();\r\n }\r\n }\r\n\r\n const timeEl = $('#index-last-refresh time', Index.navLinks);\r\n timeEl.dataset.utc = Date.parse(this.getResponseHeader('Last-Modified'));\r\n return RelativeDates.update(timeEl);\r\n },\r\n\r\n parse(pages) {\r\n $.cleanCache(url => /^https?:\\/\\/a\\.4cdn\\.org\\//.test(url));\r\n Index.parseThreadList(pages);\r\n Index.changed.threads = true;\r\n return Index.pageLoad();\r\n },\r\n\r\n parseThreadList(pages) {\r\n Index.pagesNum = pages.length;\r\n Index.threadsNumPerPage = pages[0]?.threads.length || 1;\r\n Index.liveThreadData = pages.reduce(((arr, next) => arr.concat(next.threads)), []);\r\n Index.liveThreadIDs = Index.liveThreadData.map(data => data.no);\r\n Index.liveThreadDict = dict();\r\n Index.threadPosition = dict();\r\n Index.parsedThreads = dict();\r\n Index.replyData = dict();\r\n for (let i = 0; i < Index.liveThreadData.length; i++) {\r\n var obj, results;\r\n var data = Index.liveThreadData[i];\r\n Index.liveThreadDict[data.no] = data;\r\n Index.threadPosition[data.no] = i;\r\n Index.parsedThreads[data.no] = (obj = g.SITE.Build.parseJSON(data, g.BOARD));\r\n obj.filterResults = (results = Filter.test(obj));\r\n obj.isOnTop = results.top;\r\n obj.isHidden = results.hide || ThreadHiding.isHidden(obj.boardID, obj.threadID);\r\n if (data.last_replies) {\r\n for (var reply of data.last_replies) {\r\n Index.replyData[`${g.BOARD}.${reply.no}`] = reply;\r\n }\r\n }\r\n }\r\n if (Index.liveThreadData[0]) {\r\n g.SITE.Build.spoilerRange[g.BOARD.ID] = Index.liveThreadData[0].custom_spoiler;\r\n }\r\n g.BOARD.threads.forEach(function(thread) {\r\n if (!Index.liveThreadIDs.includes(thread.ID)) { return thread.collect(); }\r\n });\r\n $.event('IndexUpdate',\r\n {threads: ((Index.liveThreadIDs.map((ID) => `${g.BOARD}.${ID}`)))});\r\n },\r\n\r\n isHidden(threadID) {\r\n let thread;\r\n if ((thread = g.BOARD.threads.get(threadID)) && thread.OP && !thread.OP.isFetchedQuote) {\r\n return thread.isHidden;\r\n } else {\r\n return Index.parsedThreads[threadID].isHidden;\r\n }\r\n },\r\n\r\n isHiddenReply(threadID, replyData) {\r\n return PostHiding.isHidden(g.BOARD.ID, threadID, replyData.no) || Filter.isHidden(g.SITE.Build.parseJSON(replyData, g.BOARD));\r\n },\r\n\r\n buildThreads(threadIDs, isCatalog, withReplies) {\r\n let errors;\r\n const threads = [];\r\n const newThreads = [];\r\n let newPosts = [];\r\n for (var ID of threadIDs) {\r\n var opRoot, thread;\r\n try {\r\n var OP;\r\n var threadData = Index.liveThreadDict[ID];\r\n\r\n if (thread = g.BOARD.threads.get(ID)) {\r\n var isStale = (thread.json !== threadData) && (JSON.stringify(thread.json) !== JSON.stringify(threadData));\r\n if (isStale) {\r\n thread.setCount('post', threadData.replies + 1, threadData.bumplimit);\r\n thread.setCount('file', threadData.images + !!threadData.ext, threadData.imagelimit);\r\n thread.setStatus('Sticky', !!threadData.sticky);\r\n thread.setStatus('Closed', !!threadData.closed);\r\n }\r\n if (thread.catalogView) {\r\n $.rm(thread.catalogView.nodes.replies);\r\n thread.catalogView.nodes.replies = null;\r\n }\r\n } else {\r\n thread = new Thread(ID, g.BOARD);\r\n newThreads.push(thread);\r\n }\r\n var lastPost = threadData.last_replies && threadData.last_replies.length ? threadData.last_replies[threadData.last_replies.length - 1].no : ID;\r\n if (lastPost > thread.lastPost) { thread.lastPost = lastPost; }\r\n thread.json = threadData;\r\n threads.push(thread);\r\n\r\n if ((OP = thread.OP) && !OP.isFetchedQuote) {\r\n OP.setCatalogOP(isCatalog);\r\n thread.setPage(Math.floor(Index.threadPosition[ID] / Index.threadsNumPerPage) + 1);\r\n } else {\r\n var obj = Index.parsedThreads[ID];\r\n opRoot = g.SITE.Build.post(obj);\r\n OP = new Post(opRoot, thread, g.BOARD);\r\n OP.filterResults = obj.filterResults;\r\n newPosts.push(OP);\r\n }\r\n\r\n if (!isCatalog || !thread.nodes.root) {\r\n g.SITE.Build.thread(thread, threadData, withReplies);\r\n }\r\n } catch (err) {\r\n // Skip posts that we failed to parse.\r\n if (!errors) { errors = []; }\r\n errors.push({\r\n message: `Parsing of Thread No.${thread} failed. Thread will be skipped.`,\r\n error: err,\r\n html: opRoot?.outerHTML\r\n });\r\n }\r\n }\r\n if (errors) { Main.handleErrors(errors); }\r\n\r\n if (withReplies) {\r\n newPosts = newPosts.concat(Index.buildReplies(threads));\r\n }\r\n\r\n Main.callbackNodes('Thread', newThreads);\r\n Main.callbackNodes('Post', newPosts);\r\n Index.updateHideLabel();\r\n $.event('IndexRefreshInternal', {threadIDs: (threads.map((t) => t.fullID)), isCatalog});\r\n\r\n return threads;\r\n },\r\n\r\n buildReplies(threads) {\r\n let errors;\r\n const posts = [];\r\n for (var thread of threads) {\r\n var lastReplies;\r\n if (!(lastReplies = Index.liveThreadDict[thread.ID].last_replies)) { continue; }\r\n var nodes = [];\r\n for (var data of lastReplies) {\r\n var node, post;\r\n if ((post = thread.posts.get(data.no)) && !post.isFetchedQuote) {\r\n nodes.push(post.nodes.root);\r\n continue;\r\n }\r\n nodes.push(node = g.SITE.Build.postFromObject(data, thread.board.ID));\r\n try {\r\n posts.push(new Post(node, thread, thread.board));\r\n } catch (err) {\r\n // Skip posts that we failed to parse.\r\n if (!errors) { errors = []; }\r\n errors.push({\r\n message: `Parsing of Post No.${data.no} failed. Post will be skipped.`,\r\n error: err,\r\n html: node?.outerHTML\r\n });\r\n }\r\n }\r\n $.add(thread.nodes.root, nodes);\r\n }\r\n\r\n if (errors) { Main.handleErrors(errors); }\r\n return posts;\r\n },\r\n\r\n buildCatalogViews(threads) {\r\n const catalogThreads = [];\r\n for (var thread of threads) {\r\n if (!thread.catalogView) {\r\n var {ID} = thread;\r\n var page = Math.floor(Index.threadPosition[ID] / Index.threadsNumPerPage) + 1;\r\n var root = g.SITE.Build.catalogThread(thread, Index.liveThreadDict[ID], page);\r\n catalogThreads.push(new CatalogThread(root, thread));\r\n }\r\n }\r\n Main.callbackNodes('CatalogThread', catalogThreads);\r\n },\r\n\r\n sizeCatalogViews(threads) {\r\n // XXX When browsers support CSS3 attr(), use it instead.\r\n const size = Conf['Index Size'] === 'small' ? 150 : 250;\r\n for (var thread of threads) {\r\n var {thumb} = thread.catalogView.nodes;\r\n var {width, height} = thumb.dataset;\r\n if (!width) { continue; }\r\n var ratio = size / Math.max(width, height);\r\n thumb.style.width = (width * ratio) + 'px';\r\n thumb.style.height = (height * ratio) + 'px';\r\n }\r\n },\r\n\r\n buildCatalogReplies(thread) {\r\n let lastReplies;\r\n const {nodes} = thread.catalogView;\r\n if (!(lastReplies = Index.liveThreadDict[thread.ID].last_replies)) { return; }\r\n\r\n const replies = [];\r\n for (var data of lastReplies) {\r\n if (Index.isHiddenReply(thread.ID, data)) { continue; }\r\n var reply = g.SITE.Build.catalogReply(thread, data);\r\n RelativeDates.update($('time', reply));\r\n $.on($('.catalog-reply-preview', reply), 'mouseover', QuotePreview.mouseover);\r\n replies.push(reply);\r\n }\r\n\r\n nodes.replies = $.el('div', {className: 'catalog-replies'});\r\n $.add(nodes.replies, replies);\r\n $.add(thread.OP.nodes.post, nodes.replies);\r\n },\r\n\r\n sort() {\r\n let threadIDs;\r\n const {liveThreadIDs, liveThreadData} = Index;\r\n if (!liveThreadData) { return; }\r\n const tmp_time = new Date().getTime()/1000;\r\n const sortType = Index.currentSort.replace(/-rev$/, '');\r\n Index.sortedThreadIDs = (() => { switch (sortType) {\r\n case 'lastreply': case 'lastlong':\r\n var repliesAvailable = liveThreadData.some(thread => thread.last_replies?.length);\r\n var lastlong = function(thread) {\r\n if (!repliesAvailable) {\r\n return thread.last_modified;\r\n }\r\n const iterable = thread.last_replies || [];\r\n for (let i = iterable.length - 1; i >= 0; i--) {\r\n var r = iterable[i];\r\n if (Index.isHiddenReply(thread.no, r)) { continue; }\r\n if (sortType === 'lastreply') {\r\n return r;\r\n }\r\n var len = r.com ? g.SITE.Build.parseComment(r.com).replace(/[^a-z]/ig, '').length : 0;\r\n if (len >= Index.lastLongThresholds[+!!r.ext]) {\r\n return r;\r\n }\r\n }\r\n if (thread.omitted_posts && thread.last_replies?.length) { return thread.last_replies[0]; } else { return thread; }\r\n };\r\n var lastlongD = dict();\r\n for (var thread of liveThreadData) {\r\n lastlongD[thread.no] = lastlong(thread).no;\r\n }\r\n return [...Array.from(liveThreadData)].sort((a, b) => lastlongD[b.no] - lastlongD[a.no]).map(post => post.no);\r\n case 'bump': return liveThreadIDs;\r\n case 'birth': return [...Array.from(liveThreadIDs) ].sort((a, b) => b - a);\r\n case 'replycount': return [...Array.from(liveThreadData)].sort((a, b) => b.replies - a.replies).map(post => post.no);\r\n case 'filecount': return [...Array.from(liveThreadData)].sort((a, b) => b.images - a.images).map(post => post.no);\r\n case 'activity': return [...Array.from(liveThreadData)].sort((a, b) => ((tmp_time-a.time)/(a.replies+1)) - ((tmp_time-b.time)/(b.replies+1))).map(post => post.no);\r\n default: return liveThreadIDs;\r\n } })();\r\n if (/-rev$/.test(Index.currentSort)) {\r\n Index.sortedThreadIDs = [...Array.from(Index.sortedThreadIDs)].reverse();\r\n }\r\n if (Index.search && (threadIDs = Index.querySearch(Index.search))) {\r\n Index.sortedThreadIDs = threadIDs;\r\n }\r\n // Sticky threads\r\n Index.sortOnTop(obj => obj.isSticky);\r\n // Highlighted threads\r\n Index.sortOnTop(obj => obj.isOnTop || (Conf['Pin Watched Threads'] && ThreadWatcher.isWatchedRaw(obj.boardID, obj.threadID)));\r\n // Non-hidden threads\r\n if (Conf['Anchor Hidden Threads']) { return Index.sortOnTop(obj => !Index.isHidden(obj.threadID)); }\r\n },\r\n\r\n sortOnTop(match) {\r\n const topThreads = [];\r\n const bottomThreads = [];\r\n for (var ID of Index.sortedThreadIDs) {\r\n (match(Index.parsedThreads[ID]) ? topThreads : bottomThreads).push(ID);\r\n }\r\n return Index.sortedThreadIDs = topThreads.concat(bottomThreads);\r\n },\r\n\r\n buildIndex() {\r\n let threadIDs;\r\n if (!Index.liveThreadData) { return; }\r\n switch (Conf['Index Mode']) {\r\n case 'all pages':\r\n threadIDs = Index.sortedThreadIDs;\r\n break;\r\n case 'catalog':\r\n threadIDs = Index.sortedThreadIDs.filter(ID => !Index.isHidden(ID) !== Index.showHiddenThreads);\r\n break;\r\n default:\r\n threadIDs = Index.threadsOnPage(Index.currentPage);\r\n }\r\n delete Index.pageNum;\r\n $.rmAll(Index.root);\r\n $.rmAll(Header.hover);\r\n if (Index.loaded && Index.root.parentNode) {\r\n $.event('PostsRemoved', null, Index.root);\r\n }\r\n if (Conf['Index Mode'] === 'catalog') {\r\n Index.buildCatalog(threadIDs);\r\n } else {\r\n Index.buildStructure(threadIDs);\r\n }\r\n },\r\n\r\n threadsOnPage(pageNum) {\r\n const nodesPerPage = Index.threadsNumPerPage;\r\n const offset = nodesPerPage * (pageNum - 1);\r\n return Index.sortedThreadIDs.slice(offset , offset + nodesPerPage);\r\n },\r\n\r\n buildStructure(threadIDs) {\r\n const threads = Index.buildThreads(threadIDs, false, Conf['Show Replies']);\r\n const nodes = [];\r\n for (var thread of threads) {\r\n nodes.push(thread.nodes.root, $.el('hr'));\r\n }\r\n $.add(Index.root, nodes);\r\n if (Index.root.parentNode) {\r\n $.event('PostsInserted', null, Index.root);\r\n }\r\n Index.loaded = true;\r\n },\r\n\r\n buildCatalog(threadIDs) {\r\n let i = 0;\r\n const n = threadIDs.length;\r\n let node0 = null;\r\n var fn = function() {\r\n if (node0 && !node0.parentNode) { return; } // Index.root cleared\r\n const j = (i > 0) && Index.root.parentNode ? n : i + 30;\r\n node0 = Index.buildCatalogPart(threadIDs.slice(i, j))[0];\r\n i = j;\r\n if (i < n) {\r\n return $.queueTask(fn);\r\n } else {\r\n if (Index.root.parentNode) {\r\n $.event('PostsInserted', null, Index.root);\r\n }\r\n return Index.loaded = true;\r\n }\r\n };\r\n fn();\r\n },\r\n\r\n buildCatalogPart(threadIDs) {\r\n const threads = Index.buildThreads(threadIDs, true);\r\n Index.buildCatalogViews(threads);\r\n Index.sizeCatalogViews(threads);\r\n const nodes = [];\r\n for (var thread of threads) {\r\n thread.OP.setCatalogOP(true);\r\n $.add(thread.catalogView.nodes.root, thread.OP.nodes.root);\r\n nodes.push(thread.catalogView.nodes.root);\r\n $.on(thread.catalogView.nodes.root, 'mouseenter', Index.cb.catalogReplies.bind(thread));\r\n $.on(thread.OP.nodes.root, 'mouseenter', Index.cb.hoverAdjust.bind(thread.OP.nodes));\r\n }\r\n $.add(Index.root, nodes);\r\n return nodes;\r\n },\r\n\r\n clearSearch() {\r\n Index.searchInput.value = '';\r\n Index.onSearchInput();\r\n return Index.searchInput.focus();\r\n },\r\n\r\n setupSearch() {\r\n Index.searchInput.value = Index.search;\r\n if (Index.search) {\r\n return Index.searchInput.dataset.searching = 1;\r\n } else {\r\n // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=1021289\r\n return Index.searchInput.removeAttribute('data-searching');\r\n }\r\n },\r\n\r\n onSearchInput() {\r\n const search = Index.searchInput.value.trim();\r\n if (search === Index.search) { return; }\r\n Index.pushState({\r\n search,\r\n replace: !!search === !!Index.search\r\n });\r\n return Index.pageLoad(false);\r\n },\r\n\r\n querySearch(query) {\r\n let keywords, match;\r\n if (match = query.match(/^([\\w+]+):\\/(.*)\\/(\\w*)$/)) {\r\n let regexp;\r\n try {\r\n regexp = RegExp(match[2], match[3]);\r\n } catch (error) {\r\n return [];\r\n }\r\n return Index.sortedThreadIDs.filter(ID => regexp.test(Filter.values(match[1], Index.parsedThreads[ID]).join('\\n')));\r\n }\r\n if (!(keywords = query.toLowerCase().match(/\\S+/g))) { return; }\r\n return Index.sortedThreadIDs.filter(ID => Index.searchMatch(Index.parsedThreads[ID], keywords));\r\n },\r\n\r\n searchMatch(obj, keywords) {\r\n const {info, file} = obj;\r\n if (info.comment == null) { info.comment = g.SITE.Build.parseComment(info.commentHTML.innerHTML); }\r\n let text = [];\r\n for (var key of ['comment', 'subject', 'name', 'tripcode']) {\r\n if (key in info) { text.push(info[key]); }\r\n }\r\n if (file) { text.push(file.name); }\r\n text = text.join(' ').toLowerCase();\r\n for (var keyword of keywords) {\r\n if (-1 === text.indexOf(keyword)) { return false; }\r\n }\r\n return true;\r\n }\r\n};\r\nexport default Index;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport DataBoard from \"../classes/DataBoard\";\r\nimport Thread from \"../classes/Thread\";\r\nimport Index from \"../General/Index\";\r\nimport UI from \"../General/UI\";\r\nimport { g, Conf, d, doc } from \"../globals/globals\";\r\nimport Main from \"../main/Main\";\r\nimport Menu from \"../Menu/Menu\";\r\nimport $ from \"../platform/$\";\r\nimport $$ from \"../platform/$$\";\r\nimport { dict } from \"../platform/helpers\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar ThreadHiding = {\r\n init() {\r\n if (!['index', 'catalog'].includes(g.VIEW) || (!Conf['Thread Hiding Buttons'] && !(Conf['Menu'] && Conf['Thread Hiding Link']) && !Conf['JSON Index'])) { return; }\r\n this.db = new DataBoard('hiddenThreads');\r\n if (g.VIEW === 'catalog') { return this.catalogWatch(); }\r\n this.catalogSet(g.BOARD);\r\n $.on(d, 'IndexRefreshInternal', this.onIndexRefresh);\r\n if (Conf['Thread Hiding Buttons']) {\r\n $.addClass(doc, 'thread-hide');\r\n }\r\n return Callbacks.Post.push({\r\n name: 'Thread Hiding',\r\n cb: this.node\r\n });\r\n },\r\n\r\n catalogSet(board) {\r\n if (!$.hasStorage || (g.SITE.software !== 'yotsuba')) { return; }\r\n const hiddenThreads = ThreadHiding.db.get({\r\n boardID: board.ID,\r\n defaultValue: dict()\r\n });\r\n for (var threadID in hiddenThreads) { hiddenThreads[threadID] = true; }\r\n return localStorage.setItem(`4chan-hide-t-${board}`, JSON.stringify(hiddenThreads));\r\n },\r\n\r\n catalogWatch() {\r\n if (!$.hasStorage || (g.SITE.software !== 'yotsuba')) { return; }\r\n this.hiddenThreads = JSON.parse(localStorage.getItem(`4chan-hide-t-${g.BOARD}`)) || {};\r\n return Main.ready(() => // 4chan's catalog sets the style to \"display: none;\" when hiding or unhiding a thread.\r\n new MutationObserver(ThreadHiding.catalogSave).observe($.id('threads'), {\r\n attributes: true,\r\n subtree: true,\r\n attributeFilter: ['style']\r\n }));\r\n },\r\n\r\n catalogSave() {\r\n let threadID;\r\n const hiddenThreads2 = JSON.parse(localStorage.getItem(`4chan-hide-t-${g.BOARD}`)) || {};\r\n for (threadID in hiddenThreads2) {\r\n if (!$.hasOwn(ThreadHiding.hiddenThreads, threadID)) {\r\n ThreadHiding.db.set({\r\n boardID: g.BOARD.ID,\r\n threadID,\r\n val: {makeStub: Conf['Stubs']}});\r\n }\r\n }\r\n for (threadID in ThreadHiding.hiddenThreads) {\r\n if (!$.hasOwn(hiddenThreads2, threadID)) {\r\n ThreadHiding.db.delete({\r\n boardID: g.BOARD.ID,\r\n threadID\r\n });\r\n }\r\n }\r\n return ThreadHiding.hiddenThreads = hiddenThreads2;\r\n },\r\n\r\n isHidden(boardID, threadID) {\r\n return !!(ThreadHiding.db && ThreadHiding.db.get({boardID, threadID}));\r\n },\r\n\r\n node() {\r\n let data;\r\n if (this.isReply || this.isClone || this.isFetchedQuote) { return; }\r\n\r\n if (Conf['Thread Hiding Buttons']) {\r\n $.prepend(this.nodes.root, ThreadHiding.makeButton(this.thread, 'hide'));\r\n }\r\n\r\n if (data = ThreadHiding.db.get({boardID: this.board.ID, threadID: this.ID})) {\r\n return ThreadHiding.hide(this.thread, data.makeStub);\r\n }\r\n },\r\n\r\n onIndexRefresh() {\r\n return g.BOARD.threads.forEach(function(thread) {\r\n const {root} = thread.nodes;\r\n if (thread.isHidden && thread.stub && !root.contains(thread.stub)) {\r\n return ThreadHiding.makeStub(thread, root);\r\n }\r\n });\r\n },\r\n\r\n menu: {\r\n init() {\r\n if ((g.VIEW !== 'index') || !Conf['Menu'] || !Conf['Thread Hiding Link']) { return; }\r\n\r\n let div = $.el('div', {\r\n className: 'hide-thread-link',\r\n textContent: 'Hide'\r\n }\r\n );\r\n\r\n const apply = $.el('a', {\r\n textContent: 'Apply',\r\n href: 'javascript:;'\r\n }\r\n );\r\n $.on(apply, 'click', ThreadHiding.menu.hide);\r\n\r\n const makeStub = UI.checkbox('Stubs', 'Make stub');\r\n\r\n Menu.menu.addEntry({\r\n el: div,\r\n order: 20,\r\n open({thread, isReply}) {\r\n if (isReply || thread.isHidden || (Conf['JSON Index'] && (Conf['Index Mode'] === 'catalog'))) {\r\n return false;\r\n }\r\n ThreadHiding.menu.thread = thread;\r\n return true;\r\n },\r\n subEntries: [{el: apply}, {el: makeStub}]});\r\n\r\n div = $.el('a', {\r\n className: 'show-thread-link',\r\n textContent: 'Show',\r\n href: 'javascript:;'\r\n }\r\n );\r\n $.on(div, 'click', ThreadHiding.menu.show);\r\n\r\n Menu.menu.addEntry({\r\n el: div,\r\n order: 20,\r\n open({thread, isReply}) {\r\n if (isReply || !thread.isHidden || (Conf['JSON Index'] && (Conf['Index Mode'] === 'catalog'))) {\r\n return false;\r\n }\r\n ThreadHiding.menu.thread = thread;\r\n return true;\r\n }\r\n });\r\n\r\n const hideStubLink = $.el('a', {\r\n textContent: 'Hide stub',\r\n href: 'javascript:;'\r\n }\r\n );\r\n $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub);\r\n\r\n return Menu.menu.addEntry({\r\n el: hideStubLink,\r\n order: 15,\r\n open({thread, isReply}) {\r\n if (isReply || !thread.isHidden || (Conf['JSON Index'] && (Conf['Index Mode'] === 'catalog'))) {\r\n return false;\r\n }\r\n return ThreadHiding.menu.thread = thread;\r\n }\r\n });\r\n },\r\n\r\n hide() {\r\n const makeStub = $('input', this.parentNode).checked;\r\n const {thread} = ThreadHiding.menu;\r\n ThreadHiding.hide(thread, makeStub);\r\n ThreadHiding.saveHiddenState(thread, makeStub);\r\n return $.event('CloseMenu');\r\n },\r\n\r\n show() {\r\n const {thread} = ThreadHiding.menu;\r\n ThreadHiding.show(thread);\r\n ThreadHiding.saveHiddenState(thread);\r\n return $.event('CloseMenu');\r\n },\r\n\r\n hideStub() {\r\n const {thread} = ThreadHiding.menu;\r\n ThreadHiding.show(thread);\r\n ThreadHiding.hide(thread, false);\r\n ThreadHiding.saveHiddenState(thread, false);\r\n $.event('CloseMenu');\r\n }\r\n },\r\n\r\n makeButton(thread, type) {\r\n const a = $.el('a', {\r\n className: `${type}-thread-button`,\r\n href: 'javascript:;'\r\n }\r\n );\r\n $.extend(a, {textContent: type === \"hide\" ? '➖︎' : '➕︎' });\r\n a.dataset.fullID = thread.fullID;\r\n $.on(a, 'click', ThreadHiding.toggle);\r\n return a;\r\n },\r\n\r\n makeStub(thread, root) {\r\n let summary, threadDivider;\r\n let numReplies = $$(g.SITE.selectors.replyOriginal, root).length;\r\n if (summary = $(g.SITE.selectors.summary, root)) { numReplies += +summary.textContent.match(/\\d+/); }\r\n\r\n const a = ThreadHiding.makeButton(thread, 'show');\r\n $.add(a, $.tn(` ${thread.OP.info.nameBlock} (${numReplies === 1 ? '1 reply' : `${numReplies} replies`})`));\r\n thread.stub = $.el('div',\r\n {className: 'stub'});\r\n if (Conf['Menu']) {\r\n $.add(thread.stub, [a, Menu.makeButton(thread.OP)]);\r\n } else {\r\n $.add(thread.stub, a);\r\n }\r\n $.prepend(root, thread.stub);\r\n\r\n // Prevent hiding of thread divider on sites that put it inside the thread\r\n if (threadDivider = $(g.SITE.selectors.threadDivider, root)) {\r\n return $.addClass(threadDivider, 'threadDivider');\r\n }\r\n },\r\n\r\n saveHiddenState(thread, makeStub) {\r\n if (thread.isHidden) {\r\n ThreadHiding.db.set({\r\n boardID: thread.board.ID,\r\n threadID: thread.ID,\r\n val: {makeStub}});\r\n } else {\r\n ThreadHiding.db.delete({\r\n boardID: thread.board.ID,\r\n threadID: thread.ID\r\n });\r\n }\r\n return ThreadHiding.catalogSet(thread.board);\r\n },\r\n\r\n toggle(thread) {\r\n if (!(thread instanceof Thread)) {\r\n thread = g.threads.get(this.dataset.fullID);\r\n }\r\n if (thread.isHidden) {\r\n ThreadHiding.show(thread);\r\n } else {\r\n ThreadHiding.hide(thread);\r\n }\r\n return ThreadHiding.saveHiddenState(thread);\r\n },\r\n\r\n hide(thread, makeStub=Conf['Stubs']) {\r\n if (thread.isHidden) { return; }\r\n const threadRoot = thread.nodes.root;\r\n thread.isHidden = true;\r\n Index.updateHideLabel();\r\n if (thread.catalogView && !Index.showHiddenThreads) {\r\n $.rm(thread.catalogView.nodes.root);\r\n $.event('PostsRemoved', null, Index.root);\r\n }\r\n\r\n if (!makeStub) { return threadRoot.hidden = true; }\r\n\r\n return ThreadHiding.makeStub(thread, threadRoot);\r\n },\r\n\r\n show(thread) {\r\n if (thread.stub) {\r\n $.rm(thread.stub);\r\n delete thread.stub;\r\n }\r\n const threadRoot = thread.nodes.root;\r\n threadRoot.hidden = (thread.isHidden = false);\r\n Index.updateHideLabel();\r\n if (thread.catalogView && Index.showHiddenThreads) {\r\n $.rm(thread.catalogView.nodes.root);\r\n return $.event('PostsRemoved', null, Index.root);\r\n }\r\n }\r\n};\r\nexport default ThreadHiding;\r\n",null,null,null,null,"export default '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==';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAadQTFRFAAAAwzw8xDs7cY6O0iws0ysrtF9f0Sws1CwsyzU1zTIy1igoyzQ01icnY7i4t0hI0S4u0ysr1Soq1ikp1ikp1Soq0ysr0S4uu0VFzjEx1Csr1ygo2Ccn2Ccn1ygo1CoqzjExzjAw1Skp2Ccn2Ccn1ikp0TAwxzY21Soq1SoqyzQ00iws1ygo1ygo0yws1Soq1Skp1igo1igo1igo1igo1igo1igo1Coq1Soq0C0t1ygo1ygo0S4unV5e1Csr1ygo1ygo1CsruUdHxzg41Skp1ygo1CsryTU10C4u1igo1ycn1ygo0i0txjo60S0t1ikp1ygo1ikp1Cws1Coq1Coq0yws0S0tyzQ00iws1Soq0ysr0i0txDs72Ccn2CUl2CYm2CQk3EFB2S8v2zw82jY24FZW3D0931FR3EBA3UND8LS04FVV7qys4V9f4WBg+erq766u9t7e7qqq2Ckp54KC9+Pj6pSU+Ojo5XNz9NHR6YqK8bu765ub5G5u9M3N6ImJ88vL5XV165eX3UVF6pWV3UhI2Soq2jU12Coq2jQ02Cgo2Sws////FaxLuAAAAF10Uk5TAAAAAAAAAAAAAAAAAAAAASJnoLy9oWolAhBz1vr72XgTGKf8/a4cCpuiDVvz9mS6xOvy9vzg6aGsPOToRAFv9fh2Awm07XgIMd765UEDOsfemVhhY00nBommbCkEI8horgAAAL5JREFUKBUFwbFKA0EUQNF7387sMq4EmzRpLSSdIBYKFv6Af2prnSYkRT4gWFgkCBJQ0EIFdcZzBCeqqh4qdk7VW2ChPusw02sAYKU7z7wEAAA2piQKFbrWSHazc1J0XWs5pdxPDykcVX+7Y9UxUsSo+s7PibqPFBRV/C5qi4i/UkrJrc7L47Bt4ZWnUaMCAE9GSrtKBQD2fR+bnAEAeOn7dUTOwApe35bDsPz0zsniQlV98IN0tJ3f6P0XAMA/kxou7OXCdnoAAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAwUExURTSY22ey5E2l4KbS75rM7Y3F64C/6f///8zl9nS45r/f9PL5/UGe3bPY8Vqr4v///wNjrzUAAAABYktHRA8YugDZAAAAB3RJTUUH4AINEi85AIH95AAAAE9JREFUCNdjYMAGGBWgDGYHCM2a3hkAZmi0dzSBaKaO9o5moCqmLiCjYzNQyw4QowIodQzI6E0AKcpo72gE6+Jyb1kAMehUA9RktgdYbQYAjGIVNGGXBJkAAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAnUExURQBk3ff6/trp+kKO5wZt3xx54q7P9Ozz/IS17zOG5WKh653E8sbc9/GbbcoAAABZSURBVAjXY2BAASyhDhAGc9oECMOjyAAiESEEYrBYpLWBGcwHxcvBjDDxHelghpF0yDQwY3kVgweEUeEQDWbMEepqAjO8FMsLIeYsU8o+BrbCdWboTAe4AwALXxWGjW41FwAAAABJRU5ErkJggg==';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAjVBMVEWn3gCo3gSr3w2t4BSu4Bav4Ri35C+45DK45DO55DXA50rA50vB50zC6E/D6FTF6VjG6VvL62vN7G/P7XbQ7XfW74vY8JDa8ZTe8qDe8qLf86Pi9Kzj9K7k9LHp9sDp98Lq98Ps+Mr0++L5/O75/fD6/fH6/fL6/fP7/fT7/fb8/ff8/vj8/vn+/v7///91X4cfAAAAcklEQVR42o3M2xKBUACF4aVQckrIuRJK6H//x2sme4/MuPDfre9i6c/Cc3U5Dj87BuAxsXvGu6JvIIXEHRWwNHCHQNrCzkAFkbSBg4EM8i+Yw7PXBa3zRfuxVyf/Bis7nKwGKAcWxgC8prI5Sc315OlnDfzpDar2S9/oAAAAAElFTkSuQmCC';","export default '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==';","export default '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=';","export default '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';","export default '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=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB1FBMVEUAAAAAAAAAAABWYWwAAABbY3BbYm5dZnFdZXJeZnMEBAQHCAhYYGpdZnFdZnBgaHIlJyomKCooKi09QkdESU5eZGtdYmhdYmleY2lrcXdqb3Rqb3Rqb3SSmJ+SlJeWmJutr7GtrrCWm6ChpKhbW1tmZmZvb290dHR3d3d4eHh5eXl6enp8fHx+gIJ/f3+CgoKDg4OEhISFhYWHh4eKioqKjI2Li4uMjIyOjo6Pj4+QkJCRkZGSkpKUlJSVl5mWlpaYmZqZm52ampqbm5ucnJydnZ2enp6fn5+hoaGioqKkpKSkpaalpaWmp6mmp6qnqauoqKioqquoqq2qqqqrrK2srKysra6srrCsrrGurq6vr6+wsLCxsbGysrKztLa0tLS1t7m2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr7AwMDAwsTBwcHExcfFxcXFxsnGxsbHx8fIyMjJycnMzMzNzc3Ozs7O0NLPz8/Q0NDR0dHR09XT09PV1dXV1dbV1tfV19rW1tbX19fX19jY2tzZ2dnZ2tva2tra3N3a3N7c3Nze3t7f39/f4OHg4ODi4uLl5+jm5ubs7Ozs7e3u7u7v7+/v8PDw8PDx8fHy8vLz8/P29vYSoLMZAAAAJHRSTlMABAUGCwsNHCAiLzMzMzZEYGJwgIuOnJycnqmqq9bc3+/w8fkZ0N/uAAAA/klEQVQoU2NgYGDl5YMDdgYGBmZZ3964CYFtIR3e9Q7K/AwMHI55KfaFmcHWMy3K3MwlGRg4wz0zdYpcorRbNbL0LaWAAp3ts2umV8wo6MupTauQBgqUG03VL7W3sfZSb1erAgm02M+yzYrVCXUy6zapAQlUx/dEdyX3J3ZHVUYVywAF8o2rDNN1Go2jzGLMokAC2QbuSc42mXmaOXop9iAtCXrJ5qXWjT59Abl2ESJAAX/tSIMMiyrrqQ3T6uS5gQK6kSqpqkUermGTexQFmYACflqR+hlWZSamzQpCLEDPsSmVVDT1TJw0JUhOAMRnYOARFRMTE5cQF+ZiBPIAII5B3EVG0b4AAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABIFBMVEUhHyAAAABzPBnxaA3CWBEnJSYbGRptbW16enpzc3PTayWhb04hHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyApIh+0UhMfHiBWMhvsZg7zaQ0hHyAhHyAXHCHzaQ3xaA3xaA3xaA3xaA0hHyAhHyDxaA3xaA3xaA3xaA3xaA3xaA0oJickIiMdGxwUEhPxaA3xaA3xaA1sbGxwcHB3d3eFhYXxaA3xaA3xaA1zc3Nzc3Nzc3Nzc3Nzc3PxaA3xaA3xaA1zc3Nzc3NtdHjxaA3xaA1yc3STcFnvaA/yaAxzc3N4c2/FbDFzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3MhHyDxaA1zc3MAAAAfljyVAAAAXHRSTlMAAAAAAAAAAAAAAAAZkjMBHOLXYArj8p0u2VsJ1XaGL/OhKyXc1WEN2gwk2/SjKgEYiS4B/tYFGosqAdleAxzj12ML9Z8s850rJWbYeYMs1F8Koiri1V0MGZY0AYbIBFIAAAABYktHRAH/Ai3eAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4wYXFBUVX81QWQAAAKxJREFUGNNVz9UWgkAQANDBtdbu7lZsxe7ubpH//wxBPKDzNvdMAmi0Oj0QQgAYjCazBX7BStvsDqHoAzTtdLklf+Dx+vwICRAIhsKRaCyOvpAwJ6Up8pXOZHOIAFm+UCzJEQuvMhWrIFBUa/WGkodmq40Ad7q9/kDFwnA05lpYYCbT2ZykFvxQDhhmuVpvcvxaHra7vfp72KflcMSYEOB0vlyx+By+3R9PMSfe+P0enM1454kAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDYtMjRUMDM6MjE6MjEtMDc6MDDse6MAAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTA2LTI0VDAzOjIxOjIxLTA3OjAwnSYbvAAAAABJRU5ErkJggg==';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABsklEQVQ4y5WTy2pUQRCGv2rbzDjJeAlIBmOyipGIIJqFEBDElwh4yULGeRFXPoEIBl/AvQ/gC2RnxCAoxijiwks852S6+3dxzslcHJCpTXVX11/Xv0097gLPgVNMJxnQNfX4zsqleWbnpoMf/oa9d988MM9MC/rp+E0a+A0dsVobMNMCOO8B6McRoABJI+A6gJmN3D2A8jgEBCEkSEMBrcrsDAzDWWn3AjgKFaDMmgRqniGFgsaDp1jrLOngDf1XT1D+A1dFc4MKAkkiCVKjjVu7g9+4Rzx4i1u6hjXbuMWr0O5QPNvCu7IaCZwEKQukLGDrm5x8uI0tr6MkiGlkiv7yLfzN+6S5i6QsIMABkEfcxhbWWYMkVAOjxvYAjc3HNHrbKI9VBQBFwF25XQKSBjqIf1YBuAurEMrczgDygD6/x2LCpFLXLUyQ+PoldphhBhYfIX09XU1+Flaukz7uYqs3SHs7cG4BmTsmkBUF9mmXEwa28BNLPaQPLepuNcbGSWQquQC2/Kdcox1FUGkcB0ykck1nA2+wTzMs8stGnP4rbWGw74EuS/GFQWfK7/wF6P4F7fzIAYkdmdEAAAAASUVORK5CYII=';","export default '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';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAYUExURf///2RBpWRBpWRBpWRBpWRBpWRBpf///+zQyUYAAAAGdFJOUwFdZX0lTzs4r5oAAAABYktHRAcWYYjrAAAAB3RJTUUH4AINEi42iSXRNAAAAD1JREFUCNdjYEiDAAZGGIMtjQEEUBlMCWoEGci6mGEMsxQgIy0BiB3AjLS0FAYQIw0kwABipoI1AhkBQBIAFCIXxiHgq80AAAAASUVORK5CYII=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAEsUExURf///1Cf21Gg3FGi31Gh3VKj4FGh3lKj4VKk4lKl41Ol5FOn51Sp6VSo6FOn5lCf21Gg3FGh3VGi31Gi31Gh3lGg3FGg3FGg3FGg3FGh3lGg3FGi31Kk4lKj4FGh3lGi31Kk4lGh3lGg3FGh3lOm5FOm5VGi31Kj4VSo6FGi31Gh3VGg3FKj4FOn51Gi31So6FWr7VOl5FGi31On51Sq6lKk4lOo51Sp6VOm5FSq61Ws7VOn51Oo51Sq61Ol5FOm5FSq61Wr7VOo51On51Sr7FWs7VSp6lGg3FGh3VOm5FWr7VSp6lKj4VOm5FSo6FSr7FWs7VWs7VWr7VSq6lOo51Om5FOo51So6FOm5VOl5FSq61Ws7VSr7FSp6lSp6VWs7lWr7VKk4lSq6v///6E3MNsAAABVdFJOUwAAAAAAAAAAAAAAAAAAAB0Ii+3xnBVTJhfsMKb+qTEp9GwBF/7lLAbo0m4pLkUTdvk2Ev3+EZnOBo/3Z8ffCRzH/D0OqPxiLnvx3UI8m9n1++GwXQZNS29BAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+ACDRIwBwy67tEAAADKSURBVBjTY2BAB4xogIGRH8IQEBQSFhEVE2eQkJQC8ZmkQ8PCI2Rk5RjkIxUUlRgZlVWioqNjYlXVGNQ14iI1tbR14qLj4+MTdJkZ9PQNosJCE0OjgPz4KEMWBiPjhPiEmKQokIJ4E1MmBmazhHg4MGdlYmCzsLSC8ROsmRkZmFht4Eps7ViADmOzd4DyHZ2YmYACTOzOLmATXd04mIBOd/eQ9owFCXh5c7KB/MLi4+vnHxAYFBzCwcYEEmBi5uLm4eHl42RmAnsSAMZBLgZiFUQ5AAAAAElFTkSuQmCC';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAxgDGAP8nNqN7AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gMZBjQQLEEqGwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAA5SURBVDjLY2AYaMDIwMDwn1JD/lPCZhpwL+B1wf///ykzgBhDiAoDfIYQZQAjIyP5BuDTPJqQqAQAvW0ZAMk8+EEAAAAASUVORK5CYII=';","export default '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=';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAYFBMVEUAAAAIdZUKh6sLlLkLmr4LmsAMp88NrdYVW3MZj7Acstkrt9s1e5E7vN5EfI9JvdtKwuBijp5kpbl30eiDt8aG1uqRr7qTyNehxM+k4PCy3enB3OTg6Ovv9PXw+fz////L9U5WAAAAAXRSTlMAQObYZgAAAIFJREFUeNplz90OwiAMBWAQpAoyxclkP3je/y0H2AQXz0WT8100rRD6kNI9/cRroemQL3hXhoujZYj4OHoAmBvYGcBISwbWBvfXCrytnIDUQMkbsBpagMA7zhtQdyTFQAmIG7IkYniiZuh3XGsPqoOZkMOJOpAcLqUzNFGGu/57fwc1hgtp0mVSyQAAAABJRU5ErkJggg==';","export default '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';","export default '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==';","export default 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAYAAABr5z2BAAABIklEQVQoz53LvUrDUBjG8bOoOammSf1IoBSvoCB4JeIqOHgBLt6AIMRBBQelWurQ2kERnMRBsBUcIp5FJSBI5oQsJVkkUHh8W0o5nhaFHvjBgef/Mq+Q46RJBMkI/vE+aOus956tnEswIZe1LV0QyJ5sE2GzgZfVMtRNIdiDpccEssdlB1mW4bvTwdvWJtRdErM7U+8S/FJykCRJX5qm+KpVce8UMNLRLbulz4iSjTAMh6Iowsd5BeNadp3nUF0VlxAEwZBotXC0Usa4ll3meZdA1iguwvf9vpvDA2wvmKgYGtSud8suDB4TyGr2PF49D/vra9jRZ1BVdknMzgwuCGSnZEObwu6sBnVTCHZiaC7BhFx2PKdxUidiAH/4lLo9Mv0DELVs9qsOHXwAAAAASUVORK5CYII=';","import $ from \"../platform/$\";\r\nimport CSS from \"../css/CSS\";\r\nimport { Conf } from \"../globals/globals\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nconst CustomCSS = {\r\n init() {\r\n if (!Conf['Custom CSS']) { return; }\r\n return this.addStyle();\r\n },\r\n\r\n addStyle() {\r\n return this.style = $.addStyle(CSS.sub(Conf['usercss']), 'custom-css', '#fourchanx-css');\r\n },\r\n\r\n rmStyle() {\r\n if (this.style) {\r\n $.rm(this.style);\r\n return delete this.style;\r\n }\r\n },\r\n\r\n update() {\r\n if (!this.style) {\r\n return this.addStyle();\r\n }\r\n return this.style.textContent = CSS.sub(Conf['usercss']);\r\n }\r\n};\r\nexport default CustomCSS;\r\n","import { Conf, d } from \"../globals/globals\";\r\nimport Main from \"../main/Main\";\r\nimport $ from \"../platform/$\";\r\nimport $$ from \"../platform/$$\";\r\nimport { dict } from \"../platform/helpers\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nconst SWTinyboard = {\r\n isOPContainerThread: true,\r\n mayLackJSON: true,\r\n threadModTimeIgnoresSage: true,\r\n\r\n disabledFeatures: [\r\n 'Resurrect Quotes',\r\n 'Quick Reply Personas',\r\n 'Quick Reply',\r\n 'Cooldown',\r\n 'Report Link',\r\n 'Delete Link',\r\n 'Edit Link',\r\n 'Quote Inlining',\r\n 'Quote Previewing',\r\n 'Quote Backlinks',\r\n 'File Info Formatting',\r\n 'Image Expansion',\r\n 'Image Expansion (Menu)',\r\n 'Comment Expansion',\r\n 'Thread Expansion',\r\n 'Favicon',\r\n 'Quote Threading',\r\n 'Thread Updater',\r\n 'Banner',\r\n 'Flash Features',\r\n 'Reply Pruning'\r\n ],\r\n\r\n detect() {\r\n for (var script of $$('script:not([src])', d.head)) {\r\n var m;\r\n if (m = script.textContent.match(/\\bvar configRoot=(\".*?\")/)) {\r\n var properties = dict();\r\n try {\r\n var root = JSON.parse(m[1]);\r\n if (root[0] === '/') {\r\n properties.root = location.origin + root;\r\n } else if (/^https?:/.test(root)) {\r\n properties.root = root;\r\n }\r\n } catch (error) {}\r\n return properties;\r\n }\r\n }\r\n return false;\r\n },\r\n\r\n awaitBoard(cb) {\r\n let reactUI;\r\n if (reactUI = $.id('react-ui')) {\r\n const s = (this.selectors = Object.create(this.selectors));\r\n s.boardFor = {index: '.page-container'};\r\n s.thread = 'div[id^=\"thread_\"]';\r\n return Main.mounted(cb);\r\n } else {\r\n return cb();\r\n }\r\n },\r\n\r\n urls: {\r\n thread({siteID, boardID, threadID}, isArchived) {\r\n return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/${isArchived ? 'archive/' : ''}res/${threadID}.html`;\r\n },\r\n post({postID}) { return `#${postID}`; },\r\n index({siteID, boardID}) { return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/`; },\r\n catalog({siteID, boardID}) { return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/catalog.html`; },\r\n threadJSON({siteID, boardID, threadID}, isArchived) {\r\n const root = Conf['siteProperties'][siteID]?.root;\r\n if (root) { return `${root}${boardID}/${isArchived ? 'archive/' : ''}res/${threadID}.json`; } else { return ''; }\r\n },\r\n archivedThreadJSON(thread) {\r\n return SWTinyboard.urls.threadJSON(thread, true);\r\n },\r\n threadsListJSON({siteID, boardID}) {\r\n const root = Conf['siteProperties'][siteID]?.root;\r\n if (root) { return `${root}${boardID}/threads.json`; } else { return ''; }\r\n },\r\n archiveListJSON({siteID, boardID}) {\r\n const root = Conf['siteProperties'][siteID]?.root;\r\n if (root) { return `${root}${boardID}/archive/archive.json`; } else { return ''; }\r\n },\r\n catalogJSON({siteID, boardID}) {\r\n const root = Conf['siteProperties'][siteID]?.root;\r\n if (root) { return `${root}${boardID}/catalog.json`; } else { return ''; }\r\n },\r\n file({siteID, boardID}, filename) {\r\n return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/${filename}`;\r\n },\r\n thumb(board, filename) {\r\n return SWTinyboard.urls.file(board, filename);\r\n }\r\n },\r\n\r\n selectors: {\r\n board: 'form[name=\"postcontrols\"]',\r\n thread: 'input[name=\"board\"] ~ div[id^=\"thread_\"]',\r\n threadDivider: 'div[id^=\"thread_\"] > hr:last-child',\r\n summary: '.omitted',\r\n postContainer: 'div[id^=\"reply_\"]:not(.hidden)', // postContainer is thread for OP\r\n opBottom: '.op',\r\n replyOriginal: 'div[id^=\"reply_\"]:not(.hidden)',\r\n infoRoot: '.intro',\r\n info: {\r\n subject: '.subject',\r\n name: '.name',\r\n email: '.email',\r\n tripcode: '.trip',\r\n uniqueID: '.poster_id',\r\n capcode: '.capcode',\r\n flag: '.flag',\r\n date: 'time',\r\n nameBlock: 'label',\r\n quote: 'a[href*=\"#q\"]',\r\n reply: 'a[href*=\"/res/\"]:not([href*=\"#\"])'\r\n },\r\n icons: {\r\n isSticky: '.fa-thumb-tack',\r\n isClosed: '.fa-lock'\r\n },\r\n file: {\r\n text: '.fileinfo',\r\n link: '.fileinfo > a',\r\n thumb: 'a > .post-image'\r\n },\r\n thumbLink: '.file > a',\r\n multifile: '.files > .file',\r\n highlightable: {\r\n op: ' > .op',\r\n reply: '.reply',\r\n catalog: ' > .thread'\r\n },\r\n comment: '.body',\r\n spoiler: '.spoiler',\r\n quotelink: 'a[onclick*=\"highlightReply(\"]',\r\n catalog: {\r\n board: '#Grid',\r\n thread: '.mix',\r\n thumb: '.thread-image'\r\n },\r\n boardList: '.boardlist',\r\n boardListBottom: '.boardlist.bottom',\r\n styleSheet: '#stylesheet',\r\n psa: '.blotter',\r\n nav: {\r\n prev: '.pages > form > [value=Previous]',\r\n next: '.pages > form > [value=Next]'\r\n }\r\n },\r\n\r\n classes: {\r\n highlight: 'highlighted'\r\n },\r\n\r\n xpath: {\r\n thread: 'div[starts-with(@id,\"thread_\")]',\r\n postContainer: 'div[starts-with(@id,\"reply_\") or starts-with(@id,\"thread_\")]',\r\n replyContainer: 'div[starts-with(@id,\"reply_\")]'\r\n },\r\n\r\n regexp: {\r\n quotelink:\r\n new RegExp(`\\\r\n/\\\r\n([^/]+)\\\r\n/res/\\\r\n(\\\\d+)\\\r\n(?:\\\\.\\\\w+)?#\\\r\n(\\\\d+)\\\r\n$\\\r\n`),\r\n quotelinkHTML:\r\n /]*\\bhref=\"[^\"]*\\/([^\\/]+)\\/res\\/(\\d+)(?:\\.\\w+)?#(\\d+)\"/g\r\n },\r\n\r\n Build: {\r\n parseJSON(data, board) {\r\n const o = this.parseJSON(data, board);\r\n if (data.ext === 'deleted') {\r\n delete o.file;\r\n $.extend(o, {\r\n files: [],\r\n fileDeleted: true,\r\n filesDeleted: [0]\r\n });\r\n }\r\n if (data.extra_files) {\r\n let file;\r\n for (let i = 0; i < data.extra_files.length; i++) {\r\n var extra_file = data.extra_files[i];\r\n if (extra_file.ext === 'deleted') {\r\n o.filesDeleted.push(i);\r\n } else {\r\n file = this.parseJSONFile(data, board);\r\n o.files.push(file);\r\n }\r\n }\r\n if (o.files.length) {\r\n o.file = o.files[0];\r\n }\r\n }\r\n return o;\r\n },\r\n\r\n parseComment(html) {\r\n html = html\r\n .replace(//gi, '\\n')\r\n .replace(/<[^>]*>/g, '');\r\n return $.unescape(html);\r\n }\r\n },\r\n\r\n bgColoredEl() {\r\n return $.el('div', {className: 'post reply'});\r\n },\r\n\r\n isFileURL(url) {\r\n return /\\/src\\/[^\\/]+/.test(url.pathname);\r\n },\r\n\r\n preParsingFixes(board) {\r\n // fixes effects of unclosed link in announcement\r\n let broken;\r\n if (broken = $('a > input[name=\"board\"]', board)) {\r\n return $.before(broken.parentNode, broken);\r\n }\r\n },\r\n\r\n parseNodes(post, nodes) {\r\n // Add vichan's span.poster_id around the ID if not already present.\r\n let m;\r\n if (nodes.uniqueID) { return; }\r\n let text = '';\r\n let node = nodes.nameBlock.nextSibling;\r\n while (node && (node.nodeType === 3)) {\r\n text += node.textContent;\r\n node = node.nextSibling;\r\n }\r\n if (m = text.match(/(\\s*ID:\\s*)(\\S+)/)) {\r\n let uniqueID;\r\n nodes.info.normalize();\r\n let {nextSibling} = nodes.nameBlock;\r\n nextSibling = nextSibling.splitText(m[1].length);\r\n nextSibling.splitText(m[2].length);\r\n nodes.uniqueID = (uniqueID = $.el('span', {className: 'poster_id'}));\r\n $.replace(nextSibling, uniqueID);\r\n return $.add(uniqueID, nextSibling);\r\n }\r\n },\r\n\r\n parseDate(node) {\r\n let date = Date.parse(node.getAttribute('datetime')?.trim());\r\n if (!isNaN(date)) { return new Date(date); }\r\n date = Date.parse(node.textContent.trim() + ' UTC'); // e.g. onesixtwo.club\r\n if (!isNaN(date)) { return new Date(date); }\r\n return undefined;\r\n },\r\n\r\n parseFile(post, file) {\r\n let info, infoNode;\r\n const {text, link, thumb} = file;\r\n if ($.x(`ancestor::${this.xpath.postContainer}[1]`, text) !== post.nodes.root) { return false; } // file belongs to a reply\r\n if (!(infoNode = link.nextSibling?.textContent.includes('(') ? link.nextSibling : link.nextElementSibling)) { return false; }\r\n if (!(info = infoNode.textContent.match(/\\((.*,\\s*)?([\\d.]+ ?[KMG]?B).*\\)/))) { return false; }\r\n const nameNode = $('.postfilename', text);\r\n $.extend(file, {\r\n name: nameNode ? (nameNode.title || nameNode.textContent) : link.pathname.match(/[^/]*$/)[0],\r\n size: info[2],\r\n dimensions: info[0].match(/\\d+x\\d+/)?.[0]\r\n });\r\n if (thumb) {\r\n $.extend(file, {\r\n thumbURL: /\\/static\\//.test(thumb.src) && $.isImage(link.href) ? link.href : thumb.src,\r\n isSpoiler: /^Spoiler/i.test(info[1] || '') || (link.textContent === 'Spoiler Image')\r\n }\r\n );\r\n }\r\n return true;\r\n },\r\n\r\n isThumbExpanded(file) {\r\n // Detect old Tinyboard image expansion that changes src attribute on thumbnail.\r\n return $.hasClass(file.thumb.parentNode, 'expanded') || (file.thumb.parentNode.dataset.expanded === 'true');\r\n },\r\n\r\n isLinkified(link) {\r\n return /\\bnofollow\\b/.test(link.rel);\r\n },\r\n\r\n catalogPin(threadRoot) {\r\n return threadRoot.dataset.sticky = 'true';\r\n }\r\n};\r\nexport default SWTinyboard;\r\n",null,"import { Conf, d } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\nimport PassMessagePage from './PassMessage/PassMessageHtml';\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\n\r\nconst PassMessage = {\r\n init() {\r\n if (Conf['passMessageClosed']) { return; }\r\n const msg = $.el('div',\r\n {className: 'box-outer top-box'}\r\n ,\r\n PassMessagePage);\r\n msg.style.cssText = 'padding-bottom: 0;';\r\n const close = $('a', msg);\r\n $.on(close, 'click', function() {\r\n $.rm(msg);\r\n return $.set('passMessageClosed', true);\r\n });\r\n return $.ready(function() {\r\n let hd;\r\n if (hd = $.id('hd')) {\r\n return $.after(hd, msg);\r\n } else {\r\n return $.prepend(d.body, msg);\r\n }\r\n });\r\n }\r\n};\r\nexport default PassMessage;\r\n","import Redirect from \"../Archive/Redirect\";\r\nimport $ from \"../platform/$\";\r\nimport ReportPage from './Report/ArchiveReport.html';\r\nimport CSS from \"../css/CSS\";\r\nimport Captcha from \"../Posting/Captcha\";\r\nimport { Conf, d, g } from \"../globals/globals\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\n\r\nvar Report = {\r\n init() {\r\n let match;\r\n if (!(match = location.search.match(/\\bno=(\\d+)/))) { return; }\r\n Captcha.replace.init();\r\n this.postID = +match[1];\r\n return $.ready(this.ready);\r\n },\r\n\r\n ready() {\r\n $.addStyle(CSS.report);\r\n\r\n if (Conf['Archive Report']) { Report.archive(); }\r\n\r\n new MutationObserver(function() {\r\n Report.fit('iframe[src^=\"https://www.google.com/recaptcha/api2/frame\"]');\r\n return Report.fit('body');\r\n }).observe(d.body, {\r\n childList: true,\r\n attributes: true,\r\n subtree: true\r\n }\r\n );\r\n return Report.fit('body');\r\n },\r\n\r\n fit(selector) {\r\n let el;\r\n if (!((el = $(selector, doc)) && (getComputedStyle(el).visibility !== 'hidden'))) { return; }\r\n const dy = (el.getBoundingClientRect().bottom - doc.clientHeight) + 8;\r\n if (dy > 0) { return window.resizeBy(0, dy); }\r\n },\r\n\r\n archive() {\r\n let match, urls;\r\n if (!(urls = Redirect.report(g.BOARD.ID)).length) { return; }\r\n\r\n const form = $('form');\r\n const types = $.id('reportTypes');\r\n const message = $('h3');\r\n\r\n const fieldset = $.el('fieldset', {\r\n id: 'archive-report',\r\n hidden: true\r\n }\r\n ,\r\n { innerHTML: ReportPage });\r\n const enabled = $('#archive-report-enabled', fieldset);\r\n const reason = $('#archive-report-reason', fieldset);\r\n const submit = $('#archive-report-submit', fieldset);\r\n\r\n $.on(enabled, 'change', function() {\r\n return reason.disabled = !this.checked;\r\n });\r\n\r\n if (form && types) {\r\n fieldset.hidden = !$('[value=\"31\"]', types).checked;\r\n $.on(types, 'change', function(e) {\r\n fieldset.hidden = (e.target.value !== '31');\r\n return Report.fit('body');\r\n });\r\n $.after(types, fieldset);\r\n Report.fit('body');\r\n $.one(form, 'submit', function(e) {\r\n if (!fieldset.hidden && enabled.checked) {\r\n e.preventDefault();\r\n return Report.archiveSubmit(urls, reason.value, results => {\r\n this.action = '#archiveresults=' + encodeURIComponent(JSON.stringify(results));\r\n return this.submit();\r\n });\r\n }\r\n });\r\n } else if (message) {\r\n fieldset.hidden = /Report submitted!/.test(message.textContent);\r\n $.on(enabled, 'change', function() {\r\n return submit.hidden = !this.checked;\r\n });\r\n $.after(message, fieldset);\r\n $.on(submit, 'click', () => Report.archiveSubmit(urls, reason.value, Report.archiveResults));\r\n }\r\n\r\n if (match = location.hash.match(/^#archiveresults=(.*)$/)) {\r\n try {\r\n return Report.archiveResults(JSON.parse(decodeURIComponent(match[1])));\r\n } catch (error) {}\r\n }\r\n },\r\n\r\n archiveSubmit(urls, reason, cb) {\r\n const form = $.formData({\r\n board: g.BOARD.ID,\r\n num: Report.postID,\r\n reason\r\n });\r\n const results = [];\r\n for (var [name, url] of urls) {\r\n (function(name, url) {\r\n return $.ajax(url, {\r\n onloadend() {\r\n results.push([name, this.response || {error: ''}]);\r\n if (results.length === urls.length) {\r\n return cb(results);\r\n }\r\n },\r\n form\r\n });\r\n })(name, url);\r\n }\r\n },\r\n\r\n archiveResults(results) {\r\n const fieldset = $.id('archive-report');\r\n for (var [name, response] of results) {\r\n var line = $.el('h3',\r\n {className: 'archive-report-response'});\r\n if ('success' in response) {\r\n $.addClass(line, 'archive-report-success');\r\n line.textContent = `${name}: ${response.success}`;\r\n } else {\r\n $.addClass(line, 'archive-report-error');\r\n line.textContent = `${name}: ${response.error || 'Error reporting post.'}`;\r\n }\r\n if (fieldset) {\r\n $.before(fieldset, line);\r\n } else {\r\n $.add(d.body, line);\r\n }\r\n }\r\n }\r\n};\r\nexport default Report;\r\n","import DataBoard from \"../classes/DataBoard\";\r\nimport { Conf, d, g } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nconst PostSuccessful = {\r\n init() {\r\n if (!Conf['Remember Your Posts']) { return; }\r\n return $.ready(this.ready);\r\n },\r\n\r\n ready() {\r\n if (d.title !== 'Post successful!') { return; }\r\n\r\n let [_, threadID, postID] = Array.from($('h1').nextSibling.textContent.match(/thread:(\\d+),no:(\\d+)/));\r\n postID = +postID;\r\n threadID = +threadID || postID;\r\n\r\n const db = new DataBoard('yourPosts');\r\n return db.set({\r\n boardID: g.BOARD.ID,\r\n threadID,\r\n postID,\r\n val: true\r\n });\r\n }\r\n};\r\nexport default PostSuccessful;\r\n",null,null,null,null,"import SWTinyboard from \"./SW.tinyboard\";\r\nimport SWYotsuba from \"./SW.yotsuba\";\r\n\r\nconst SW = { tinyboard: SWTinyboard, yotsuba: SWYotsuba };\r\nexport default SW;\r\n",null,"import $ from \"../platform/$\";\r\nimport Callbacks from \"../classes/Callbacks\";\r\nimport { g, Conf } from \"../globals/globals\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar Time = {\r\n init() {\r\n if (!['index', 'thread', 'archive'].includes(g.VIEW) || !Conf['Time Formatting']) { return; }\r\n\r\n return Callbacks.Post.push({\r\n name: 'Time Formatting',\r\n cb: this.node\r\n });\r\n },\r\n\r\n node() {\r\n if (!this.info.date || this.isClone) { return; }\r\n const {textContent} = this.nodes.date;\r\n return this.nodes.date.textContent = textContent.match(/^\\s*/)[0] + Time.format(Conf['time'], this.info.date) + textContent.match(/\\s*$/)[0];\r\n },\r\n\r\n format(formatString, date) {\r\n return formatString.replace(/%(.)/g, function(s, c) {\r\n if ($.hasOwn(Time.formatters, c)) {\r\n return Time.formatters[c].call(date);\r\n } else {\r\n return s;\r\n }\r\n });\r\n },\r\n\r\n day: [\r\n 'Sunday',\r\n 'Monday',\r\n 'Tuesday',\r\n 'Wednesday',\r\n 'Thursday',\r\n 'Friday',\r\n 'Saturday'\r\n ],\r\n\r\n month: [\r\n 'January',\r\n 'February',\r\n 'March',\r\n 'April',\r\n 'May',\r\n 'June',\r\n 'July',\r\n 'August',\r\n 'September',\r\n 'October',\r\n 'November',\r\n 'December'\r\n ],\r\n\r\n localeFormat(date, options, defaultValue) {\r\n if (Conf['timeLocale']) {\r\n try {\r\n return Intl.DateTimeFormat(Conf['timeLocale'], options).format(date);\r\n } catch (error) {}\r\n }\r\n return defaultValue;\r\n },\r\n\r\n localeFormatPart(date, options, part, defaultValue) {\r\n if (Conf['timeLocale']) {\r\n try {\r\n const parts = Intl.DateTimeFormat(Conf['timeLocale'], options).formatToParts(date);\r\n return parts.map(function(x) { if (x.type === part) { return x.value; } else { return ''; } }).join('');\r\n } catch (error) {}\r\n }\r\n return defaultValue;\r\n },\r\n\r\n zeroPad(n) { if (n < 10) { return `0${n}`; } else { return n; } },\r\n\r\n formatters: {\r\n a() { return Time.localeFormat(this, {weekday: 'short'}, Time.day[this.getDay()].slice(0, 3)); },\r\n A() { return Time.localeFormat(this, {weekday: 'long'}, Time.day[this.getDay()]); },\r\n b() { return Time.localeFormat(this, {month: 'short'}, Time.month[this.getMonth()].slice(0, 3)); },\r\n B() { return Time.localeFormat(this, {month: 'long'}, Time.month[this.getMonth()]); },\r\n d() { return Time.zeroPad(this.getDate()); },\r\n e() { return this.getDate(); },\r\n H() { return Time.zeroPad(this.getHours()); },\r\n I() { return Time.zeroPad((this.getHours() % 12) || 12); },\r\n k() { return this.getHours(); },\r\n l() { return (this.getHours() % 12) || 12; },\r\n m() { return Time.zeroPad(this.getMonth() + 1); },\r\n M() { return Time.zeroPad(this.getMinutes()); },\r\n p() { return Time.localeFormatPart(this, {hour: 'numeric', hour12: true}, 'dayperiod', (this.getHours() < 12 ? 'AM' : 'PM')); },\r\n P() { return Time.formatters.p.call(this).toLowerCase(); },\r\n S() { return Time.zeroPad(this.getSeconds()); },\r\n y() { return this.getFullYear().toString().slice(2); },\r\n Y() { return this.getFullYear(); },\r\n '%'() { return '%'; }\r\n }\r\n};\r\nexport default Time;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport Header from \"../General/Header\";\r\nimport UI from \"../General/UI\";\r\nimport { g, Conf, E, d } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\nimport QuoteThreading from \"../Quotelinks/QuoteThreading\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS104: Avoid inline assignments\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar ReplyPruning = {\r\n init() {\r\n if ((g.VIEW !== 'thread') || !Conf['Reply Pruning']) { return; }\r\n\r\n this.container = $.frag();\r\n\r\n this.summary = $.el('span', {\r\n hidden: true,\r\n className: 'summary'\r\n }\r\n );\r\n this.summary.style.cursor = 'pointer';\r\n $.on(this.summary, 'click', () => {\r\n this.inputs.enabled.checked = !this.inputs.enabled.checked;\r\n return $.event('change', null, this.inputs.enabled);\r\n });\r\n\r\n const label = UI.checkbox('Prune Replies', 'Show Last', Conf['Prune All Threads']);\r\n const el = $.el('span',\r\n {title: 'Maximum number of replies to show.'}\r\n ,\r\n {innerHTML: \" \"});\r\n $.prepend(el, label);\r\n\r\n this.inputs = {\r\n enabled: label.firstElementChild,\r\n replies: el.lastElementChild\r\n };\r\n\r\n this.setEnabled.call(this.inputs.enabled);\r\n $.on(this.inputs.enabled, 'change', this.setEnabled);\r\n $.on(this.inputs.replies, 'change', $.cb.value);\r\n\r\n Header.menu.addEntry({\r\n el,\r\n order: 190\r\n });\r\n\r\n return Callbacks.Thread.push({\r\n name: 'Reply Pruning',\r\n cb: this.node\r\n });\r\n },\r\n\r\n position: 0,\r\n hidden: 0,\r\n hiddenFiles: 0,\r\n total: 0,\r\n totalFiles: 0,\r\n\r\n setEnabled() {\r\n const other = QuoteThreading.input;\r\n if (this.checked && other?.checked) {\r\n other.checked = false;\r\n $.event('change', null, other);\r\n }\r\n return ReplyPruning.active = this.checked;\r\n },\r\n\r\n showIfHidden(id) {\r\n if (ReplyPruning.container && $(`#${id}`, ReplyPruning.container)) {\r\n ReplyPruning.inputs.enabled.checked = false;\r\n return $.event('change', null, ReplyPruning.inputs.enabled);\r\n }\r\n },\r\n\r\n node() {\r\n let middle;\r\n ReplyPruning.thread = this;\r\n\r\n if (this.isSticky) {\r\n ReplyPruning.active = (ReplyPruning.inputs.enabled.checked = true);\r\n if (QuoteThreading.input) {\r\n // Disable Quote Threading for this thread but don't save the setting.\r\n Conf['Thread Quotes'] = (QuoteThreading.input.checked = false);\r\n }\r\n }\r\n\r\n this.posts.forEach(function(post) {\r\n if (post.isReply) {\r\n ReplyPruning.total++;\r\n if (post.file) { return ReplyPruning.totalFiles++; }\r\n }\r\n });\r\n\r\n // If we're linked to a post that we would hide, don't hide the posts in the first place.\r\n if (\r\n ReplyPruning.active &&\r\n /^#p\\d+$/.test(location.hash) &&\r\n (1 <= (middle = this.posts.keys.indexOf(location.hash.slice(2))) && middle < 1 + Math.max(ReplyPruning.total - +Conf[\"Max Replies\"], 0))\r\n ) {\r\n ReplyPruning.active = (ReplyPruning.inputs.enabled.checked = false);\r\n }\r\n\r\n $.after(this.OP.nodes.root, ReplyPruning.summary);\r\n\r\n $.on(ReplyPruning.inputs.enabled, 'change', ReplyPruning.update);\r\n $.on(ReplyPruning.inputs.replies, 'change', ReplyPruning.update);\r\n $.on(d, 'ThreadUpdate', ReplyPruning.updateCount);\r\n $.on(d, 'ThreadUpdate', ReplyPruning.update);\r\n\r\n return ReplyPruning.update();\r\n },\r\n\r\n updateCount(e) {\r\n if (e.detail[404]) { return; }\r\n for (var fullID of e.detail.newPosts) {\r\n ReplyPruning.total++;\r\n if (g.posts.get(fullID).file) { ReplyPruning.totalFiles++; }\r\n }\r\n },\r\n\r\n update() {\r\n let boardTop, node, post;\r\n const hidden1 = ReplyPruning.hidden;\r\n const hidden2 = ReplyPruning.active ?\r\n Math.max(ReplyPruning.total - +Conf[\"Max Replies\"], 0)\r\n :\r\n 0;\r\n\r\n // Record position from bottom of document\r\n const oldPos = d.body.clientHeight - window.scrollY;\r\n\r\n const {posts} = ReplyPruning.thread;\r\n\r\n if (ReplyPruning.hidden < hidden2) {\r\n while ((ReplyPruning.hidden < hidden2) && (ReplyPruning.position < posts.keys.length)) {\r\n post = posts.get(posts.keys[ReplyPruning.position++]);\r\n if (post.isReply && !post.isFetchedQuote) {\r\n while ((node = ReplyPruning.summary.nextSibling) && (node !== post.nodes.root)) { $.add(ReplyPruning.container, node); }\r\n $.add(ReplyPruning.container, post.nodes.root);\r\n ReplyPruning.hidden++;\r\n if (post.file) { ReplyPruning.hiddenFiles++; }\r\n }\r\n }\r\n\r\n } else if (ReplyPruning.hidden > hidden2) {\r\n const frag = $.frag();\r\n while ((ReplyPruning.hidden > hidden2) && (ReplyPruning.position > 0)) {\r\n post = posts.get(posts.keys[--ReplyPruning.position]);\r\n if (post.isReply && !post.isFetchedQuote) {\r\n while ((node = ReplyPruning.container.lastChild) && (node !== post.nodes.root)) { $.prepend(frag, node); }\r\n $.prepend(frag, post.nodes.root);\r\n ReplyPruning.hidden--;\r\n if (post.file) { ReplyPruning.hiddenFiles--; }\r\n }\r\n }\r\n $.after(ReplyPruning.summary, frag);\r\n $.event('PostsInserted', null, ReplyPruning.summary.parentNode);\r\n }\r\n\r\n ReplyPruning.summary.textContent = ReplyPruning.active ?\r\n g.SITE.Build.summaryText('+', ReplyPruning.hidden, ReplyPruning.hiddenFiles)\r\n :\r\n g.SITE.Build.summaryText('-', ReplyPruning.total, ReplyPruning.totalFiles);\r\n ReplyPruning.summary.hidden = (ReplyPruning.total <= +Conf[\"Max Replies\"]);\r\n\r\n // Maintain position in thread when posts are added/removed above\r\n if ((hidden1 !== hidden2) && ((boardTop = Header.getTopOf($('.board'))) < 0)) {\r\n return window.scrollBy(0, Math.max(d.body.clientHeight - oldPos, window.scrollY + boardTop) - window.scrollY);\r\n }\r\n }\r\n};\r\nexport default ReplyPruning;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport RandomAccessList from \"../classes/RandomAccessList\";\r\nimport Header from \"../General/Header\";\r\nimport { Conf, d, g } from \"../globals/globals\";\r\nimport ReplyPruning from \"../Monitoring/ReplyPruning\";\r\nimport Unread from \"../Monitoring/Unread\";\r\nimport $ from \"../platform/$\";\r\nimport { dict } from \"../platform/helpers\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\n/*\r\n <3 aeosynth\r\n*/\r\n\r\nvar QuoteThreading = {\r\n init() {\r\n if (!Conf['Quote Threading'] || (g.VIEW !== 'thread')) { return; }\r\n\r\n this.controls = $.el('label',\r\n {innerHTML: \" Threading\"});\r\n\r\n this.threadNewLink = $.el('span', {\r\n className: 'brackets-wrap threadnewlink',\r\n hidden: true\r\n }\r\n );\r\n $.extend(this.threadNewLink, {innerHTML: \"Thread New Posts\"});\r\n\r\n this.input = $('input', this.controls);\r\n this.input.checked = Conf['Thread Quotes'];\r\n\r\n $.on(this.input, 'change', this.setEnabled);\r\n $.on(this.input, 'change', this.rethread);\r\n $.on(this.threadNewLink.firstElementChild, 'click', this.rethread);\r\n $.on(d, '4chanXInitFinished', () => { return this.ready = true; });\r\n\r\n Header.menu.addEntry(this.entry = {\r\n el: this.controls,\r\n order: 99\r\n }\r\n );\r\n\r\n Callbacks.Thread.push({\r\n name: 'Quote Threading',\r\n cb: this.setThread\r\n });\r\n\r\n return Callbacks.Post.push({\r\n name: 'Quote Threading',\r\n cb: this.node\r\n });\r\n },\r\n\r\n parent: dict(),\r\n children: dict(),\r\n inserted: dict(),\r\n\r\n toggleThreading() {\r\n return this.setThreadingState(!Conf['Thread Quotes']);\r\n },\r\n\r\n setThreadingState(enabled) {\r\n this.input.checked = enabled;\r\n this.setEnabled.call(this.input);\r\n return this.rethread.call(this.input);\r\n },\r\n\r\n setEnabled() {\r\n if (this.checked) {\r\n $.set('Prune All Threads', false);\r\n const other = ReplyPruning.inputs?.enabled;\r\n if (other?.checked) {\r\n other.checked = false;\r\n $.event('change', null, other);\r\n }\r\n }\r\n return $.cb.checked.call(this);\r\n },\r\n\r\n setThread() {\r\n QuoteThreading.thread = this;\r\n return $.asap((() => !Conf['Thread Updater'] || $('.navLinksBot > .updatelink')), function() {\r\n let navLinksBot;\r\n if (navLinksBot = $('.navLinksBot')) { return $.add(navLinksBot, [$.tn(' '), QuoteThreading.threadNewLink]); }\r\n });\r\n },\r\n\r\n node() {\r\n let parent;\r\n if (this.isFetchedQuote || this.isClone || !this.isReply) { return; }\r\n\r\n const parents = new Set();\r\n let lastParent = null;\r\n for (var quote of this.quotes) {\r\n if ((parent = g.posts.get(quote))) {\r\n if (!parent.isFetchedQuote && parent.isReply && (parent.ID < this.ID)) {\r\n parents.add(parent.ID);\r\n if (!lastParent || (parent.ID > lastParent.ID)) { lastParent = parent; }\r\n }\r\n }\r\n }\r\n\r\n if (!lastParent) { return; }\r\n\r\n let ancestor = lastParent;\r\n while ((ancestor = QuoteThreading.parent[ancestor.fullID])) {\r\n parents.delete(ancestor.ID);\r\n }\r\n\r\n if (parents.size === 1) {\r\n return QuoteThreading.parent[this.fullID] = lastParent;\r\n }\r\n },\r\n\r\n descendants(post) {\r\n let children;\r\n let posts = [post];\r\n if (children = QuoteThreading.children[post.fullID]) {\r\n for (var child of children) {\r\n posts = posts.concat(QuoteThreading.descendants(child));\r\n }\r\n }\r\n return posts;\r\n },\r\n\r\n insert(post) {\r\n let parent, x;\r\n if (!(\r\n Conf['Thread Quotes'] &&\r\n (parent = QuoteThreading.parent[post.fullID]) &&\r\n !QuoteThreading.inserted[post.fullID]\r\n )) { return false; }\r\n\r\n const descendants = QuoteThreading.descendants(post);\r\n if (!Unread.posts.has(parent.ID)) {\r\n if ((function() { for (var x of descendants) { if (Unread.posts.has(x.ID)) { return true; } } })()) {\r\n QuoteThreading.threadNewLink.hidden = false;\r\n return false;\r\n }\r\n }\r\n\r\n const {order} = Unread;\r\n const children = (QuoteThreading.children[parent.fullID] || (QuoteThreading.children[parent.fullID] = []));\r\n const threadContainer = parent.nodes.threadContainer || $.el('div', {className: 'threadContainer'});\r\n const nodes = [post.nodes.root];\r\n if (post.nodes.threadContainer) { nodes.push(post.nodes.threadContainer); }\r\n\r\n let i = children.length;\r\n for (let j = children.length - 1; j >= 0; j--) { var child = children[j]; if (child.ID >= post.ID) { i--; } }\r\n if (i !== children.length) {\r\n const next = children[i];\r\n for (x of descendants) { order.before(order[next.ID], order[x.ID]); }\r\n children.splice(i, 0, post);\r\n $.before(next.nodes.root, nodes);\r\n } else {\r\n let prev2;\r\n let prev = parent;\r\n while ((prev2 = QuoteThreading.children[prev.fullID]) && prev2.length) {\r\n prev = prev2[prev2.length-1];\r\n }\r\n for (let k = descendants.length - 1; k >= 0; k--) { x = descendants[k]; order.after(order[prev.ID], order[x.ID]); }\r\n children.push(post);\r\n $.add(threadContainer, nodes);\r\n }\r\n\r\n QuoteThreading.inserted[post.fullID] = true;\r\n\r\n if (!parent.nodes.threadContainer) {\r\n parent.nodes.threadContainer = threadContainer;\r\n $.addClass(parent.nodes.root, 'threadOP');\r\n $.after(parent.nodes.root, threadContainer);\r\n }\r\n\r\n return true;\r\n },\r\n\r\n rethread() {\r\n if (!QuoteThreading.ready) { return; }\r\n const {thread} = QuoteThreading;\r\n const {posts} = thread;\r\n\r\n QuoteThreading.threadNewLink.hidden = true;\r\n\r\n if (Conf['Thread Quotes']) {\r\n posts.forEach(QuoteThreading.insert);\r\n } else {\r\n const nodes = [];\r\n Unread.order = new RandomAccessList();\r\n QuoteThreading.inserted = dict();\r\n posts.forEach(function(post) {\r\n if (post.isFetchedQuote) { return; }\r\n Unread.order.push(post);\r\n if (post.isReply) { nodes.push(post.nodes.root); }\r\n if (QuoteThreading.children[post.fullID]) {\r\n delete QuoteThreading.children[post.fullID];\r\n $.rmClass(post.nodes.root, 'threadOP');\r\n $.rm(post.nodes.threadContainer);\r\n return delete post.nodes.threadContainer;\r\n }\r\n });\r\n $.add(thread.nodes.root, nodes);\r\n }\r\n\r\n Unread.position = Unread.order.first;\r\n Unread.updatePosition();\r\n Unread.setLine(true);\r\n Unread.read();\r\n return Unread.update();\r\n }\r\n};\r\nexport default QuoteThreading;\r\n","import Beep from './ThreadUpdater/beep.wav';\r\nimport $ from \"../platform/$\";\r\nimport Callbacks from '../classes/Callbacks';\r\nimport Notice from '../classes/Notice';\r\nimport Post from '../classes/Post';\r\nimport Main from '../main/Main';\r\nimport Config from '../config/Config';\r\nimport Settings from '../General/Settings';\r\nimport QuoteThreading from '../Quotelinks/QuoteThreading';\r\nimport Unread from './Unread';\r\nimport Header from '../General/Header';\r\nimport { g, Conf, d, doc } from '../globals/globals';\r\nimport UI from '../General/UI';\r\nimport { MINUTE, SECOND } from '../platform/helpers';\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS201: Simplify complex destructure assignments\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\n\r\nvar ThreadUpdater = {\r\n init() {\r\n let el, name, sc;\r\n if ((g.VIEW !== 'thread') || !Conf['Thread Updater']) { return; }\r\n this.enabled = true;\r\n\r\n // Chromium won't play audio created in an inactive tab until the tab has been focused, so set it up now.\r\n // XXX Sometimes the loading stalls in Firefox, esp. when opening in private browsing window followed by normal window.\r\n // Don't let it keep the loading icon on indefinitely.\r\n this.audio = $.el('audio');\r\n if ($.engine !== 'gecko') { this.audio.src = this.beep; }\r\n\r\n if (Conf['Updater and Stats in Header']) {\r\n this.dialog = (sc = $.el('span',\r\n {id: 'updater'}));\r\n $.extend(sc, {innerHTML: ''});\r\n Header.addShortcut('updater', sc, 100);\r\n } else {\r\n this.dialog = (sc = UI.dialog('updater',\r\n {innerHTML: '
            '}));\r\n $.addClass(doc, 'float');\r\n $.ready(() => $.add(d.body, sc));\r\n }\r\n\r\n this.checkPostCount = 0;\r\n\r\n this.timer = $('#update-timer', sc);\r\n this.status = $('#update-status', sc);\r\n\r\n $.on(this.timer, 'click', this.update);\r\n $.on(this.status, 'click', this.update);\r\n\r\n const updateLink = $.el('span',\r\n {className: 'brackets-wrap updatelink'});\r\n $.extend(updateLink, {innerHTML: 'Update'});\r\n Main.ready(function() {\r\n let navLinksBot;\r\n if (navLinksBot = $('.navLinksBot')) { return $.add(navLinksBot, [$.tn(' '), updateLink]); }\r\n });\r\n $.on(updateLink.firstElementChild, 'click', this.update);\r\n\r\n const subEntries = [];\r\n for (name in Config.updater.checkbox) {\r\n var conf = Config.updater.checkbox[name];\r\n el = UI.checkbox(name, name);\r\n el.title = conf[1];\r\n var input = el.firstElementChild;\r\n $.on(input, 'change', $.cb.checked);\r\n if (input.name === 'Scroll BG') {\r\n $.on(input, 'change', this.cb.scrollBG);\r\n this.cb.scrollBG();\r\n } else if (input.name === 'Auto Update') {\r\n $.on(input, 'change', this.setInterval);\r\n }\r\n subEntries.push({el});\r\n }\r\n\r\n this.settings = $.el('span',\r\n {innerHTML: 'Interval'});\r\n\r\n $.on(this.settings, 'click', this.intervalShortcut);\r\n\r\n subEntries.push({el: this.settings});\r\n\r\n Header.menu.addEntry(this.entry = {\r\n el: $.el('span',\r\n {textContent: 'Updater'}),\r\n order: 110,\r\n subEntries\r\n }\r\n );\r\n\r\n return Callbacks.Thread.push({\r\n name: 'Thread Updater',\r\n cb: this.node\r\n });\r\n },\r\n\r\n node() {\r\n ThreadUpdater.thread = this;\r\n ThreadUpdater.root = this.nodes.root;\r\n ThreadUpdater.outdateCount = 0;\r\n\r\n // We must keep track of our own list of live posts/files\r\n // to provide an accurate deletedPosts/deletedFiles on update\r\n // as posts may be `kill`ed elsewhere.\r\n ThreadUpdater.postIDs = [];\r\n ThreadUpdater.fileIDs = [];\r\n this.posts.forEach(function(post) {\r\n ThreadUpdater.postIDs.push(post.ID);\r\n if (post.file) { return ThreadUpdater.fileIDs.push(post.ID); }\r\n });\r\n\r\n ThreadUpdater.cb.interval.call($.el('input', {value: Conf['Interval']}));\r\n\r\n $.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost);\r\n $.on(d, 'visibilitychange', ThreadUpdater.cb.visibility);\r\n\r\n return ThreadUpdater.setInterval();\r\n },\r\n\r\n /*\r\n http://freesound.org/people/pierrecartoons1979/sounds/90112/\r\n cc-by-nc-3.0\r\n */\r\n beep: `data:audio/wav;base64,${Beep}`,\r\n\r\n playBeep() {\r\n const {audio} = ThreadUpdater;\r\n if (!audio.src) { audio.src = ThreadUpdater.beep; }\r\n if (audio.paused) {\r\n return audio.play();\r\n } else {\r\n return $.one(audio, 'ended', ThreadUpdater.playBeep);\r\n }\r\n },\r\n\r\n cb: {\r\n checkpost(e) {\r\n if (e.detail.threadID !== ThreadUpdater.thread.ID) { return; }\r\n ThreadUpdater.postID = e.detail.postID;\r\n ThreadUpdater.checkPostCount = 0;\r\n ThreadUpdater.outdateCount = 0;\r\n return ThreadUpdater.setInterval();\r\n },\r\n\r\n visibility() {\r\n if (d.hidden) { return; }\r\n // Reset the counter when we focus this tab.\r\n ThreadUpdater.outdateCount = 0;\r\n if (ThreadUpdater.seconds > ThreadUpdater.interval) {\r\n return ThreadUpdater.setInterval();\r\n }\r\n },\r\n\r\n scrollBG() {\r\n return ThreadUpdater.scrollBG = Conf['Scroll BG'] ?\r\n () => true\r\n :\r\n () => !d.hidden;\r\n },\r\n\r\n interval(e) {\r\n let val = parseInt(this.value, 10);\r\n if (val < 1) { val = 1; }\r\n ThreadUpdater.interval = (this.value = val);\r\n if (e) { return $.cb.value.call(this); }\r\n },\r\n\r\n load() {\r\n if (this !== ThreadUpdater.req) { return; } // aborted\r\n switch (this.status) {\r\n case 200:\r\n ThreadUpdater.parse(this);\r\n if (ThreadUpdater.thread.isArchived) {\r\n return ThreadUpdater.kill();\r\n } else {\r\n return ThreadUpdater.setInterval();\r\n }\r\n case 404:\r\n // XXX workaround for 4chan sending false 404s\r\n return $.ajax(g.SITE.urls.catalogJSON({boardID: ThreadUpdater.thread.board.ID}), { onloadend() {\r\n let confirmed;\r\n if (this.status === 200) {\r\n confirmed = true;\r\n for (var page of this.response) {\r\n for (var thread of page.threads) {\r\n if (thread.no === ThreadUpdater.thread.ID) {\r\n confirmed = false;\r\n break;\r\n }\r\n }\r\n }\r\n } else {\r\n confirmed = false;\r\n }\r\n if (confirmed) {\r\n return ThreadUpdater.kill();\r\n } else {\r\n return ThreadUpdater.error(this);\r\n }\r\n }\r\n }\r\n );\r\n default:\r\n return ThreadUpdater.error(this);\r\n }\r\n }\r\n },\r\n\r\n kill() {\r\n ThreadUpdater.thread.kill();\r\n ThreadUpdater.setInterval();\r\n return $.event('ThreadUpdate', {\r\n 404: true,\r\n threadID: ThreadUpdater.thread.fullID\r\n }\r\n );\r\n },\r\n\r\n error(req) {\r\n if (req.status === 304) {\r\n ThreadUpdater.set('status', '');\r\n }\r\n ThreadUpdater.setInterval();\r\n if (!req.status) {\r\n return ThreadUpdater.set('status', 'Connection Error', 'warning');\r\n } else if (req.status !== 304) {\r\n return ThreadUpdater.set('status', `${req.statusText} (${req.status})`, 'warning');\r\n }\r\n },\r\n\r\n setInterval() {\r\n clearTimeout(ThreadUpdater.timeoutID);\r\n\r\n if (ThreadUpdater.thread.isDead) {\r\n ThreadUpdater.set('status', (ThreadUpdater.thread.isArchived ? 'Archived' : '404'), 'warning');\r\n ThreadUpdater.set('timer', '');\r\n return;\r\n }\r\n\r\n // Fetching your own posts after posting\r\n if (ThreadUpdater.postID && (ThreadUpdater.checkPostCount < 5)) {\r\n ThreadUpdater.set('timer', '...', 'loading');\r\n ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * SECOND);\r\n return;\r\n }\r\n\r\n if (!Conf['Auto Update']) {\r\n ThreadUpdater.set('timer', 'Update');\r\n return;\r\n }\r\n\r\n const {interval} = ThreadUpdater;\r\n if (Conf['Optional Increase']) {\r\n // Lower the max refresh rate limit on visible tabs.\r\n const limit = d.hidden ? 10 : 5;\r\n const j = Math.min(ThreadUpdater.outdateCount, limit);\r\n\r\n // 1 second to 100, 30 to 300.\r\n const cur = (Math.floor(interval * 0.1) || 1) * j * j;\r\n ThreadUpdater.seconds = $.minmax(cur, interval, 300);\r\n } else {\r\n ThreadUpdater.seconds = interval;\r\n }\r\n\r\n return ThreadUpdater.timeout();\r\n },\r\n\r\n intervalShortcut() {\r\n Settings.open('Advanced');\r\n const settings = $.id('fourchanx-settings');\r\n return $('input[name=Interval]', settings).focus();\r\n },\r\n\r\n set(name, text, klass) {\r\n let node;\r\n const el = ThreadUpdater[name];\r\n if ((node = el.firstChild)) {\r\n // Prevent the creation of a new DOM Node\r\n // by setting the text node's data.\r\n node.data = text;\r\n } else {\r\n el.textContent = text;\r\n }\r\n return el.className = klass ?? (text === '' ? 'empty' : '');\r\n },\r\n\r\n timeout() {\r\n if (ThreadUpdater.seconds) {\r\n ThreadUpdater.set('timer', ThreadUpdater.seconds);\r\n ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000);\r\n } else {\r\n ThreadUpdater.outdateCount++;\r\n ThreadUpdater.update();\r\n }\r\n return ThreadUpdater.seconds--;\r\n },\r\n\r\n update() {\r\n let oldReq;\r\n clearTimeout(ThreadUpdater.timeoutID);\r\n ThreadUpdater.set('timer', '...', 'loading');\r\n if (oldReq = ThreadUpdater.req) {\r\n delete ThreadUpdater.req;\r\n oldReq.abort();\r\n }\r\n return ThreadUpdater.req = $.whenModified(\r\n g.SITE.urls.threadJSON({boardID: ThreadUpdater.thread.board.ID, threadID: ThreadUpdater.thread.ID}),\r\n 'ThreadUpdater',\r\n ThreadUpdater.cb.load,\r\n { timeout: MINUTE }\r\n );\r\n },\r\n\r\n updateThreadStatus(type, status) {\r\n let hasChanged;\r\n if (!(hasChanged = ThreadUpdater.thread[`is${type}`] !== status)) { return; }\r\n ThreadUpdater.thread.setStatus(type, status);\r\n if ((type === 'Closed') && ThreadUpdater.thread.isArchived) { return; }\r\n const change = type === 'Sticky' ?\r\n status ?\r\n 'now a sticky'\r\n :\r\n 'not a sticky anymore'\r\n :\r\n status ?\r\n 'now closed'\r\n :\r\n 'not closed anymore';\r\n return new Notice('info', `The thread is ${change}.`, 30);\r\n },\r\n\r\n parse(req) {\r\n let ID, ipCountEl, post;\r\n const postObjects = req.response.posts;\r\n const OP = postObjects[0];\r\n const {thread} = ThreadUpdater;\r\n const {board} = thread;\r\n const lastPost = ThreadUpdater.postIDs[ThreadUpdater.postIDs.length - 1];\r\n\r\n // XXX Reject updates that falsely delete the last post.\r\n if ((postObjects[postObjects.length-1].no < lastPost) &&\r\n ((new Date(req.getResponseHeader('Last-Modified')) - thread.posts.get(lastPost).info.date) < (30 * SECOND))) { return; }\r\n\r\n g.SITE.Build.spoilerRange[board] = OP.custom_spoiler;\r\n thread.setStatus('Archived', !!OP.archived);\r\n ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky);\r\n ThreadUpdater.updateThreadStatus('Closed', !!OP.closed);\r\n thread.postLimit = !!OP.bumplimit;\r\n thread.fileLimit = !!OP.imagelimit;\r\n if (OP.unique_ips != null) { thread.ipCount = OP.unique_ips; }\r\n\r\n const posts = []; // new post objects\r\n const index = []; // existing posts\r\n const files = []; // existing files\r\n const newPosts = []; // new post fullID list for API\r\n\r\n // Build the index, create posts.\r\n for (var postObject of postObjects) {\r\n ID = postObject.no;\r\n index.push(ID);\r\n if (postObject.fsize) { files.push(ID); }\r\n\r\n // Insert new posts, not older ones.\r\n if (ID <= lastPost) { continue; }\r\n\r\n // XXX Resurrect wrongly deleted posts.\r\n if ((post = thread.posts.get(ID)) && !post.isFetchedQuote) {\r\n post.resurrect();\r\n continue;\r\n }\r\n\r\n newPosts.push(`${board}.${ID}`);\r\n var node = g.SITE.Build.postFromObject(postObject, board.ID);\r\n posts.push(new Post(node, thread, board));\r\n // Fetching your own posts after posting\r\n if (ThreadUpdater.postID === ID) { delete ThreadUpdater.postID; }\r\n }\r\n\r\n // Check for deleted posts.\r\n const deletedPosts = [];\r\n for (ID of ThreadUpdater.postIDs) {\r\n if (!index.includes(ID)) {\r\n thread.posts.get(ID).kill();\r\n deletedPosts.push(`${board}.${ID}`);\r\n }\r\n }\r\n ThreadUpdater.postIDs = index;\r\n\r\n // Check for deleted files.\r\n const deletedFiles = [];\r\n for (ID of ThreadUpdater.fileIDs) {\r\n if (!(files.includes(ID) || deletedPosts.includes(`${board}.${ID}`))) {\r\n thread.posts.get(ID).kill(true);\r\n deletedFiles.push(`${board}.${ID}`);\r\n }\r\n }\r\n ThreadUpdater.fileIDs = files;\r\n\r\n if (!posts.length) {\r\n ThreadUpdater.set('status', '');\r\n } else {\r\n ThreadUpdater.set('status', `+${posts.length}`, 'new');\r\n ThreadUpdater.outdateCount = 0;\r\n\r\n const unreadCount = Unread.posts?.size;\r\n const unreadQYCount = Unread.postsQuotingYou?.size;\r\n\r\n Main.callbackNodes('Post', posts);\r\n\r\n if (d.hidden || !d.hasFocus()) {\r\n if (Conf['Beep Quoting You'] && (Unread.postsQuotingYou?.size > unreadQYCount)) {\r\n ThreadUpdater.playBeep();\r\n if (Conf['Beep']) { ThreadUpdater.playBeep(); }\r\n } else if (Conf['Beep'] && (Unread.posts?.size > 0) && (unreadCount === 0)) {\r\n ThreadUpdater.playBeep();\r\n }\r\n }\r\n\r\n const scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() &&\r\n ((ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight) < 25);\r\n\r\n let firstPost = null;\r\n for (post of posts) {\r\n if (!QuoteThreading.insert(post)) {\r\n if (!firstPost) { firstPost = post.nodes.root; }\r\n $.add(ThreadUpdater.root, post.nodes.root);\r\n }\r\n }\r\n $.event('PostsInserted', null, ThreadUpdater.root);\r\n\r\n if (scroll) {\r\n if (Conf['Bottom Scroll']) {\r\n window.scrollTo(0, d.body.clientHeight);\r\n } else {\r\n if (firstPost) { Header.scrollTo(firstPost); }\r\n }\r\n }\r\n }\r\n\r\n // Update IP count in original post form.\r\n if ((OP.unique_ips != null) && (ipCountEl = $.id('unique-ips'))) {\r\n ipCountEl.textContent = OP.unique_ips;\r\n ipCountEl.previousSibling.textContent = ipCountEl.previousSibling.textContent.replace(/\\b(?:is|are)\\b/, OP.unique_ips === 1 ? 'is' : 'are');\r\n ipCountEl.nextSibling.textContent = ipCountEl.nextSibling.textContent.replace(/\\bposters?\\b/, OP.unique_ips === 1 ? 'poster' : 'posters');\r\n }\r\n\r\n return $.event('ThreadUpdate', {\r\n 404: false,\r\n threadID: thread.fullID,\r\n newPosts,\r\n deletedPosts,\r\n deletedFiles,\r\n postCount: OP.replies + 1,\r\n fileCount: OP.images + !!OP.fsize,\r\n ipCount: OP.unique_ips\r\n }\r\n );\r\n }\r\n};\r\nexport default ThreadUpdater;\r\n",null,"import Callbacks from \"../classes/Callbacks\";\r\nimport Header from \"../General/Header\";\r\nimport UI from \"../General/UI\";\r\nimport { Conf, doc, g } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar FappeTyme = {\r\n init() {\r\n if ((!Conf['Fappe Tyme'] && !Conf['Werk Tyme']) || !['index', 'thread', 'archive'].includes(g.VIEW)) { return; }\r\n\r\n this.nodes = {};\r\n this.enabled = {\r\n fappe: false,\r\n werk: Conf['werk']\r\n };\r\n\r\n for (var type of [\"Fappe\", \"Werk\"]) {\r\n if (Conf[`${type} Tyme`]) {\r\n var lc = type.toLowerCase();\r\n var el = UI.checkbox(lc, `${type} Tyme`, false);\r\n el.title = `${type} Tyme`;\r\n\r\n this.nodes[lc] = el.firstElementChild;\r\n if (Conf[lc]) { this.set(lc, true); }\r\n $.on(this.nodes[lc], 'change', this.toggle.bind(this, lc));\r\n\r\n Header.menu.addEntry({\r\n el,\r\n order: 97\r\n });\r\n\r\n var indicator = $.el('span', {\r\n className: 'indicator',\r\n textContent: type[0],\r\n title: `${type} Tyme active`\r\n }\r\n );\r\n $.on(indicator, 'click', function() {\r\n const check = $.getOwn(FappeTyme.nodes, this.parentNode.id.replace('shortcut-', ''));\r\n check.checked = !check.checked;\r\n return $.event('change', null, check);\r\n });\r\n Header.addShortcut(lc, indicator, 410);\r\n }\r\n }\r\n\r\n if (Conf['Werk Tyme']) {\r\n $.sync('werk', this.set.bind(this, 'werk'));\r\n }\r\n\r\n Callbacks.Post.push({\r\n name: 'Fappe Tyme',\r\n cb: this.node\r\n });\r\n\r\n return Callbacks.CatalogThread.push({\r\n name: 'Werk Tyme',\r\n cb: this.catalogNode\r\n });\r\n },\r\n\r\n node() {\r\n return this.nodes.root.classList.toggle('noFile', !this.files.length);\r\n },\r\n\r\n catalogNode() {\r\n const file = this.thread.OP.files[0];\r\n if (!file) { return; }\r\n const filename = $.el('div', {\r\n textContent: file.name,\r\n className: 'werkTyme-filename'\r\n }\r\n );\r\n return $.add(this.nodes.thumb.parentNode, filename);\r\n },\r\n\r\n set(type, enabled) {\r\n this.enabled[type] = (this.nodes[type].checked = enabled);\r\n return $[`${enabled ? 'add' : 'rm'}Class`](doc, `${type}Tyme`);\r\n },\r\n\r\n toggle(type) {\r\n this.set(type, !this.enabled[type]);\r\n if (type === 'werk') { return $.cb.checked.call(this.nodes[type]); }\r\n }\r\n};\r\nexport default FappeTyme;\r\n","import Callbacks from \"../classes/Callbacks\";\r\nimport Notice from \"../classes/Notice\";\r\nimport Filter from \"../Filtering/Filter\";\r\nimport { g, Conf, doc } from \"../globals/globals\";\r\nimport $ from \"../platform/$\";\r\nimport { dict } from \"../platform/helpers\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS104: Avoid inline assignments\r\n * DS204: Change includes calls to have a more natural evaluation order\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar Sauce = {\r\n init() {\r\n let link;\r\n if (!['index', 'thread'].includes(g.VIEW) || !Conf['Sauce']) { return; }\r\n $.addClass(doc, 'show-sauce');\r\n\r\n const links = [];\r\n for (link of Conf['sauces'].split('\\n')) {\r\n var linkData;\r\n if ((link[0] !== '#') && (linkData = this.parseLink(link))) {\r\n links.push(linkData);\r\n }\r\n }\r\n if (!links.length) { return; }\r\n\r\n this.links = links;\r\n this.link = $.el('a', {\r\n target: '_blank',\r\n className: 'sauce'\r\n }\r\n );\r\n return Callbacks.Post.push({\r\n name: 'Sauce',\r\n cb: this.node\r\n });\r\n },\r\n\r\n parseLink(link) {\r\n if (!(link = link.trim())) { return null; }\r\n const parts = dict();\r\n const iterable = link.split(/;(?=(?:text|boards|types|regexp|sandbox):?)/);\r\n for (let i = 0; i < iterable.length; i++) {\r\n var part = iterable[i];\r\n if (i === 0) {\r\n parts['url'] = part;\r\n } else {\r\n var m = part.match(/^(\\w*):?(.*)$/);\r\n parts[m[1]] = m[2];\r\n }\r\n }\r\n if (!parts['text']) { parts['text'] = parts['url'].match(/(\\w+)\\.\\w+\\//)?.[1] || '?'; }\r\n if ('boards' in parts) {\r\n parts['boards'] = Filter.parseBoards(parts['boards']);\r\n }\r\n if ('regexp' in parts) {\r\n try {\r\n let regexp;\r\n if (regexp = parts['regexp'].match(/^\\/(.*)\\/(\\w*)$/)) {\r\n parts['regexp'] = RegExp(regexp[1], regexp[2]);\r\n } else {\r\n parts['regexp'] = RegExp(parts['regexp']);\r\n }\r\n } catch (err) {\r\n new Notice('warning', [\r\n $.tn(\"Invalid regexp for Sauce link:\"),\r\n $.el('br'),\r\n $.tn(link),\r\n $.el('br'),\r\n $.tn(err.message)\r\n ], 60);\r\n return null;\r\n }\r\n }\r\n return parts;\r\n },\r\n\r\n createSauceLink(link, post, file) {\r\n let a, matches, needle;\r\n const ext = file.url.match(/[^.]*$/)[0];\r\n const parts = dict();\r\n $.extend(parts, link);\r\n\r\n if (!!parts['boards'] && !parts['boards'][`${post.siteID}/${post.boardID}`] && !parts['boards'][`${post.siteID}/*`]) { return null; }\r\n if (!!parts['types'] && (needle = ext, !parts['types'].split(',').includes(needle))) { return null; }\r\n if (!!parts['regexp'] && (!(matches = file.name.match(parts['regexp'])))) { return null; }\r\n\r\n const missing = [];\r\n for (var key of ['url', 'text']) {\r\n parts[key] = parts[key].replace(/%(T?URL|IMG|[sh]?MD5|board|name|%|semi|\\$\\d+)/g, function(orig, parameter) {\r\n let type;\r\n if (parameter[0] === '$') {\r\n if (!matches) { return orig; }\r\n type = matches[parameter.slice(1)] || '';\r\n } else {\r\n type = Sauce.formatters[parameter](post, file, ext);\r\n if ((type == null)) {\r\n missing.push(parameter);\r\n return '';\r\n }\r\n }\r\n\r\n if ((key === 'url') && !['%', 'semi'].includes(parameter)) {\r\n if (/^javascript:/i.test(parts['url'])) { type = JSON.stringify(type); }\r\n type = encodeURIComponent(type);\r\n }\r\n return type;\r\n });\r\n }\r\n\r\n if (g.SITE.areMD5sDeferred?.(post.board) && missing.length && !missing.filter(x => !/^.?MD5$/.test(x)).length) {\r\n a = Sauce.link.cloneNode(false);\r\n a.dataset.skip = '1';\r\n return a;\r\n }\r\n\r\n if (missing.length) { return null; }\r\n\r\n a = Sauce.link.cloneNode(false);\r\n a.href = parts['url'];\r\n a.textContent = parts['text'];\r\n if (/^javascript:/i.test(parts['url'])) { a.removeAttribute('target'); }\r\n return a;\r\n },\r\n\r\n node() {\r\n if (this.isClone) { return; }\r\n for (var file of this.files) {\r\n Sauce.file(this, file);\r\n }\r\n },\r\n\r\n file(post, file) {\r\n let link, node;\r\n const nodes = [];\r\n const skipped = [];\r\n for (link of Sauce.links) {\r\n if (node = Sauce.createSauceLink(link, post, file)) {\r\n nodes.push($.tn(' '), node);\r\n if (node.dataset.skip) { skipped.push([link, node]); }\r\n }\r\n }\r\n $.add(file.text, nodes);\r\n\r\n if (skipped.length) {\r\n var observer = new MutationObserver(function() {\r\n if (file.text.dataset.md5) {\r\n for ([link, node] of skipped) {\r\n var node2;\r\n if (node2 = Sauce.createSauceLink(link, post, file)) {\r\n $.replace(node, node2);\r\n }\r\n }\r\n return observer.disconnect();\r\n }\r\n });\r\n return observer.observe(file.text, {attributes: true});\r\n }\r\n },\r\n\r\n formatters: {\r\n TURL(post, file) { return file.thumbURL; },\r\n URL(post, file) { return file.url; },\r\n IMG(post, file, ext) { if (['gif', 'jpg', 'jpeg', 'png'].includes(ext)) { return file.url; } else { return file.thumbURL; } },\r\n MD5(post, file) { return file.MD5; },\r\n sMD5(post, file) { return file.MD5?.replace(/[+/=]/g, c => ({'+': '-', '/': '_', '=': ''})[c]); },\r\n hMD5(post, file) { if (file.MD5) { return (atob(file.MD5).map((c) => `0${c.charCodeAt(0).toString(16)}`.slice(-2))).join(''); } },\r\n board(post) { return post.board.ID; },\r\n name(post, file) { return file.name; },\r\n '%'() { return '%'; },\r\n semi() { return ';'; }\r\n }\r\n};\r\nexport default Sauce;\r\n","/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS205: Consider reworking code to avoid use of IIFEs\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nimport galleryPage from './Gallery/Gallery.html';\r\nimport $ from '../platform/$';\r\nimport Callbacks from '../classes/Callbacks';\r\nimport Notice from '../classes/Notice';\r\nimport Main from '../main/Main';\r\nimport Keybinds from '../Miscellaneous/Keybinds';\r\nimport $$ from '../platform/$$';\r\nimport ImageCommon from './ImageCommon';\r\nimport Sauce from './Sauce';\r\nimport Volume from './Volume';\r\nimport Header from '../General/Header';\r\nimport { Conf, d, doc, g } from '../globals/globals';\r\nimport UI from '../General/UI';\r\nimport Get from '../General/Get';\r\nimport { debounce, dict, SECOND } from '../platform/helpers';\r\n\r\nvar Gallery = {\r\n init() {\r\n if (!(this.enabled = Conf['Gallery'] && ['index', 'thread'].includes(g.VIEW))) { return; }\r\n\r\n this.delay = Conf['Slide Delay'];\r\n\r\n const el = $.el('a', {\r\n href: 'javascript:;',\r\n title: 'Gallery',\r\n textContent: '🖼︎',\r\n });\r\n\r\n $.on(el, 'click', this.cb.toggle);\r\n\r\n Header.addShortcut('gallery', el, 530);\r\n\r\n return Callbacks.Post.push({\r\n name: 'Gallery',\r\n cb: this.node\r\n });\r\n },\r\n\r\n node() {\r\n return (() => {\r\n const result = [];\r\n for (var file of this.files) {\r\n if (file.thumb) {\r\n if (Gallery.nodes) {\r\n Gallery.generateThumb(this, file);\r\n Gallery.nodes.total.textContent = Gallery.images.length;\r\n }\r\n\r\n if (!Conf['Image Expansion'] && ((g.SITE.software !== 'tinyboard') || !Main.jsEnabled)) {\r\n result.push($.on(file.thumbLink, 'click', Gallery.cb.image));\r\n } else {\r\n result.push(undefined);\r\n }\r\n }\r\n }\r\n return result;\r\n })();\r\n },\r\n\r\n build(image) {\r\n let dialog, thumb;\r\n const {cb} = Gallery;\r\n\r\n if (Conf['Fullscreen Gallery']) {\r\n $.one(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', () => $.on(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', cb.close));\r\n doc.mozRequestFullScreen?.();\r\n doc.webkitRequestFullScreen?.(Element.ALLOW_KEYBOARD_INPUT);\r\n }\r\n\r\n Gallery.images = [];\r\n const nodes = (Gallery.nodes = {});\r\n Gallery.fileIDs = dict();\r\n Gallery.slideshow = false;\r\n\r\n nodes.el = (dialog = $.el('div',\r\n {id: 'a-gallery'}));\r\n $.extend(dialog, {innerHTML: galleryPage });\r\n\r\n const object = {\r\n buttons: '.gal-buttons',\r\n frame: '.gal-image',\r\n name: '.gal-name',\r\n count: '.count',\r\n total: '.total',\r\n sauce: '.gal-sauce',\r\n thumbs: '.gal-thumbnails',\r\n next: '.gal-image a',\r\n current: '.gal-image img'\r\n };\r\n for (var key in object) { var value = object[key]; nodes[key] = $(value, dialog); }\r\n\r\n const menuButton = $('.menu-button', dialog);\r\n nodes.menu = new UI.Menu('gallery');\r\n\r\n $.on(nodes.frame, 'click', cb.blank);\r\n if (Conf['Mouse Wheel Volume']) { $.on(nodes.frame, 'wheel', Volume.wheel); }\r\n $.on(nodes.next, 'click', cb.click);\r\n $.on(nodes.name, 'click', ImageCommon.download);\r\n\r\n $.on($('.gal-prev', dialog), 'click', cb.prev);\r\n $.on($('.gal-next', dialog), 'click', cb.next);\r\n $.on($('.gal-start', dialog), 'click', cb.start);\r\n $.on($('.gal-stop', dialog), 'click', cb.stop);\r\n $.on($('.gal-close', dialog), 'click', cb.close);\r\n\r\n $.on(menuButton, 'click', function(e) {\r\n return nodes.menu.toggle(e, this, g);\r\n });\r\n\r\n for (var entry of Gallery.menu.createSubEntries()) {\r\n entry.order = 0;\r\n nodes.menu.addEntry(entry);\r\n }\r\n\r\n $.on(d, 'keydown', cb.keybinds);\r\n if (Conf['Keybinds']) { $.off(d, 'keydown', Keybinds.keydown); }\r\n\r\n $.on(window, 'resize', Gallery.cb.setHeight);\r\n\r\n for (var postThumb of $$(g.SITE.selectors.file.thumb)) {\r\n var post;\r\n if (!(post = Get.postFromNode(postThumb))) { continue; }\r\n for (var file of post.files) {\r\n if (file.thumb) {\r\n Gallery.generateThumb(post, file);\r\n // If no image to open is given, pick image we have scrolled to.\r\n if (!image && Gallery.fileIDs[`${post.fullID}.${file.index}`]) {\r\n var candidate = file.thumbLink;\r\n if ((Header.getTopOf(candidate) + candidate.getBoundingClientRect().height) >= 0) {\r\n image = candidate;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n $.addClass(doc, 'gallery-open');\r\n\r\n $.add(d.body, dialog);\r\n\r\n nodes.thumbs.scrollTop = 0;\r\n nodes.current.parentElement.scrollTop = 0;\r\n\r\n if (image) { thumb = $(`[href='${image.href}']`, nodes.thumbs); }\r\n if (!thumb) { thumb = Gallery.images[Gallery.images.length-1]; }\r\n if (thumb) { Gallery.open(thumb); }\r\n\r\n doc.style.overflow = 'hidden';\r\n return nodes.total.textContent = Gallery.images.length;\r\n },\r\n\r\n generateThumb(post, file) {\r\n if (post.isClone || post.isHidden) { return; }\r\n if (!file || !file.thumb || (!file.isImage && !file.isVideo && !Conf['PDF in Gallery'])) { return; }\r\n if (Gallery.fileIDs[`${post.fullID}.${file.index}`]) { return; }\r\n\r\n Gallery.fileIDs[`${post.fullID}.${file.index}`] = true;\r\n\r\n const thumb = $.el('a', {\r\n className: 'gal-thumb',\r\n href: file.url,\r\n target: '_blank',\r\n title: file.name\r\n }\r\n );\r\n\r\n thumb.dataset.id = Gallery.images.length;\r\n thumb.dataset.post = post.fullID;\r\n thumb.dataset.file = file.index;\r\n\r\n const thumbImg = file.thumb.cloneNode(false);\r\n thumbImg.style.cssText = '';\r\n $.add(thumb, thumbImg);\r\n\r\n $.on(thumb, 'click', Gallery.cb.open);\r\n\r\n Gallery.images.push(thumb);\r\n return $.add(Gallery.nodes.thumbs, thumb);\r\n },\r\n\r\n load(thumb, errorCB) {\r\n const ext = thumb.href.match(/\\w*$/);\r\n const elType = $.getOwn({'webm': 'video', 'mp4': 'video', 'ogv': 'video', 'pdf': 'iframe'}, ext) || 'img';\r\n const file = $.el(elType);\r\n $.extend(file.dataset, thumb.dataset);\r\n $.on(file, 'error', errorCB);\r\n file.src = thumb.href;\r\n return file;\r\n },\r\n\r\n open(thumb) {\r\n let el, file, post;\r\n const {nodes} = Gallery;\r\n const oldID = +nodes.current.dataset.id;\r\n const newID = +thumb.dataset.id;\r\n\r\n // Highlight, center selected thumbnail\r\n if (el = Gallery.images[oldID]) { $.rmClass(el, 'gal-highlight'); }\r\n $.addClass(thumb, 'gal-highlight');\r\n nodes.thumbs.scrollTop = (thumb.offsetTop + (thumb.offsetHeight/2)) - (nodes.thumbs.clientHeight/2);\r\n\r\n // Load image or use preloaded image\r\n if (Gallery.cache?.dataset.id === (''+newID)) {\r\n file = Gallery.cache;\r\n $.off(file, 'error', Gallery.cacheError);\r\n $.on(file, 'error', Gallery.error);\r\n } else {\r\n file = Gallery.load(thumb, Gallery.error);\r\n }\r\n\r\n // Replace old image with new one\r\n $.off(nodes.current, 'error', Gallery.error);\r\n ImageCommon.pause(nodes.current);\r\n $.replace(nodes.current, file);\r\n nodes.current = file;\r\n\r\n if (file.nodeName === 'VIDEO') {\r\n file.loop = true;\r\n Volume.setup(file);\r\n if (Conf['Autoplay']) { file.play(); }\r\n if (Conf['Show Controls']) { ImageCommon.addControls(file); }\r\n }\r\n\r\n doc.classList.toggle('gal-pdf', file.nodeName === 'IFRAME');\r\n Gallery.cb.setHeight();\r\n nodes.count.textContent = +thumb.dataset.id + 1;\r\n nodes.name.download = (nodes.name.textContent = thumb.title);\r\n nodes.name.href = thumb.href;\r\n nodes.frame.scrollTop = 0;\r\n nodes.next.focus();\r\n\r\n // Set sauce links\r\n $.rmAll(nodes.sauce);\r\n if (Conf['Sauce'] && Sauce.links && (post = g.posts.get(file.dataset.post))) {\r\n const sauces = [];\r\n for (var link of Sauce.links) {\r\n var node;\r\n if (node = Sauce.createSauceLink(link, post, post.files[+file.dataset.file])) {\r\n sauces.push($.tn(' '), node);\r\n }\r\n }\r\n $.add(nodes.sauce, sauces);\r\n }\r\n\r\n // Continue slideshow if moving forward, stop otherwise\r\n if (Gallery.slideshow && ((newID > oldID) || ((oldID === (Gallery.images.length-1)) && (newID === 0)))) {\r\n Gallery.setupTimer();\r\n } else {\r\n Gallery.cb.stop();\r\n }\r\n\r\n // Scroll to post\r\n if (Conf['Scroll to Post'] && (post = g.posts.get(file.dataset.post))) {\r\n Header.scrollTo(post.nodes.root);\r\n }\r\n\r\n // Preload next image\r\n if (isNaN(oldID) || (newID === ((oldID + 1) % Gallery.images.length))) {\r\n return Gallery.cache = Gallery.load(Gallery.images[(newID + 1) % Gallery.images.length], Gallery.cacheError);\r\n }\r\n },\r\n\r\n error() {\r\n if (this.error?.code === MediaError.MEDIA_ERR_DECODE) {\r\n return new Notice('error', 'Corrupt or unplayable video', 30);\r\n }\r\n if (ImageCommon.isFromArchive(this)) { return; }\r\n const post = g.posts.get(this.dataset.post);\r\n const file = post.files[+this.dataset.file];\r\n return ImageCommon.error(this, post, file, null, url => {\r\n if (!url) { return; }\r\n Gallery.images[+this.dataset.id].href = url;\r\n if (Gallery.nodes.current === this) { return this.src = url; }\r\n });\r\n },\r\n\r\n cacheError() {\r\n return delete Gallery.cache;\r\n },\r\n\r\n cleanupTimer() {\r\n clearTimeout(Gallery.timeoutID);\r\n const {current} = Gallery.nodes;\r\n $.off(current, 'canplaythrough load', Gallery.startTimer);\r\n return $.off(current, 'ended', Gallery.cb.next);\r\n },\r\n\r\n startTimer() {\r\n return Gallery.timeoutID = setTimeout(Gallery.checkTimer, Gallery.delay * SECOND);\r\n },\r\n\r\n setupTimer() {\r\n Gallery.cleanupTimer();\r\n const {current} = Gallery.nodes;\r\n const isVideo = current.nodeName === 'VIDEO';\r\n if (isVideo) { current.play(); }\r\n if ((isVideo ? current.readyState >= 4 : current.complete) || (current.nodeName === 'IFRAME')) {\r\n return Gallery.startTimer();\r\n } else {\r\n return $.on(current, (isVideo ? 'canplaythrough' : 'load'), Gallery.startTimer);\r\n }\r\n },\r\n\r\n checkTimer() {\r\n const {current} = Gallery.nodes;\r\n if ((current.nodeName === 'VIDEO') && !current.paused) {\r\n $.on(current, 'ended', Gallery.cb.next);\r\n return current.loop = false;\r\n } else {\r\n return Gallery.cb.next();\r\n }\r\n },\r\n\r\n cb: {\r\n keybinds(e) {\r\n let key;\r\n if (!(key = Keybinds.keyCode(e))) { return; }\r\n\r\n const cb = (() => { switch (key) {\r\n case Conf['Close']: case Conf['Open Gallery']:\r\n return Gallery.cb.close;\r\n case Conf['Next Gallery Image']:\r\n return Gallery.cb.next;\r\n case Conf['Advance Gallery']:\r\n return Gallery.cb.advance;\r\n case Conf['Previous Gallery Image']:\r\n return Gallery.cb.prev;\r\n case Conf['Pause']:\r\n return Gallery.cb.pause;\r\n case Conf['Slideshow']:\r\n return Gallery.cb.toggleSlideshow;\r\n case Conf['Rotate image anticlockwise']:\r\n return Gallery.cb.rotateLeft;\r\n case Conf['Rotate image clockwise']:\r\n return Gallery.cb.rotateRight;\r\n case Conf['Download Gallery Image']:\r\n return Gallery.cb.download;\r\n } })();\r\n\r\n if (!cb) { return; }\r\n e.stopPropagation();\r\n e.preventDefault();\r\n return cb();\r\n },\r\n\r\n open(e) {\r\n if (e) { e.preventDefault(); }\r\n if (this) { return Gallery.open(this); }\r\n },\r\n\r\n image(e) {\r\n e.preventDefault();\r\n e.stopPropagation();\r\n return Gallery.build(this);\r\n },\r\n\r\n prev() {\r\n return Gallery.cb.open.call(\r\n Gallery.images[+Gallery.nodes.current.dataset.id - 1] || Gallery.images[Gallery.images.length - 1]\r\n );\r\n },\r\n next() {\r\n return Gallery.cb.open.call(\r\n Gallery.images[+Gallery.nodes.current.dataset.id + 1] || Gallery.images[0]\r\n );\r\n },\r\n\r\n click(e) {\r\n if (ImageCommon.onControls(e)) { return; }\r\n e.preventDefault();\r\n return Gallery.cb.advance();\r\n },\r\n\r\n advance() { if (!Conf['Autoplay'] && Gallery.nodes.current.paused) { return Gallery.nodes.current.play(); } else { return Gallery.cb.next(); } },\r\n toggle() { return (Gallery.nodes ? Gallery.cb.close : Gallery.build)(); },\r\n blank(e) { if (e.target === this) { return Gallery.cb.close(); } },\r\n toggleSlideshow() { return Gallery.cb[Gallery.slideshow ? 'stop' : 'start'](); },\r\n\r\n download() {\r\n const name = $('.gal-name');\r\n return name.click();\r\n },\r\n\r\n pause() {\r\n Gallery.cb.stop();\r\n const {current} = Gallery.nodes;\r\n if (current.nodeName === 'VIDEO') { return current[current.paused ? 'play' : 'pause'](); }\r\n },\r\n\r\n start() {\r\n $.addClass(Gallery.nodes.buttons, 'gal-playing');\r\n Gallery.slideshow = true;\r\n return Gallery.setupTimer();\r\n },\r\n\r\n stop() {\r\n if (!Gallery.slideshow) { return; }\r\n Gallery.cleanupTimer();\r\n const {current} = Gallery.nodes;\r\n if (current.nodeName === 'VIDEO') { current.loop = true; }\r\n $.rmClass(Gallery.nodes.buttons, 'gal-playing');\r\n return Gallery.slideshow = false;\r\n },\r\n\r\n rotateLeft() { return Gallery.cb.rotate(270); },\r\n rotateRight() { return Gallery.cb.rotate(90); },\r\n\r\n rotate: debounce(100, function(delta) {\r\n const {current} = Gallery.nodes;\r\n if (current.nodeName === 'IFRAME') { return; }\r\n current.dataRotate = ((current.dataRotate || 0) + delta) % 360;\r\n current.style.transform = `rotate(${current.dataRotate}deg)`;\r\n return Gallery.cb.setHeight();\r\n }),\r\n\r\n close() {\r\n $.off(Gallery.nodes.current, 'error', Gallery.error);\r\n ImageCommon.pause(Gallery.nodes.current);\r\n $.rm(Gallery.nodes.el);\r\n $.rmClass(doc, 'gallery-open');\r\n if (Conf['Fullscreen Gallery']) {\r\n $.off(d, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', Gallery.cb.close);\r\n d.mozCancelFullScreen?.();\r\n d.webkitExitFullscreen?.();\r\n }\r\n delete Gallery.nodes;\r\n delete Gallery.fileIDs;\r\n doc.style.overflow = '';\r\n\r\n $.off(d, 'keydown', Gallery.cb.keybinds);\r\n if (Conf['Keybinds']) { $.on(d, 'keydown', Keybinds.keydown); }\r\n $.off(window, 'resize', Gallery.cb.setHeight);\r\n return clearTimeout(Gallery.timeoutID);\r\n },\r\n\r\n setFitness() {\r\n return (this.checked ? $.addClass : $.rmClass)(doc, `gal-${this.name.toLowerCase().replace(/\\s+/g, '-')}`);\r\n },\r\n\r\n setHeight: debounce(100, function () {\r\n let dim, margin, minHeight;\r\n const {current, frame} = Gallery.nodes;\r\n const {style} = current;\r\n\r\n if (Conf['Stretch to Fit'] && (dim = g.posts.get(current.dataset.post)?.files[+current.dataset.file].dimensions)) {\r\n const [width, height] = Array.from(dim.split('x'));\r\n let containerWidth = frame.clientWidth;\r\n let containerHeight = doc.clientHeight - 25;\r\n if (((current.dataRotate || 0) % 180) === 90) {\r\n [containerWidth, containerHeight] = Array.from([containerHeight, containerWidth]);\r\n }\r\n minHeight = Math.min(containerHeight, (height / width) * containerWidth);\r\n style.minHeight = minHeight + 'px';\r\n style.minWidth = ((width / height) * minHeight) + 'px';\r\n } else {\r\n style.minHeight = (style.minWidth = '');\r\n }\r\n\r\n if (((current.dataRotate || 0) % 180) === 90) {\r\n style.maxWidth = Conf['Fit Height'] ? `${doc.clientHeight - 25}px` : 'none';\r\n style.maxHeight = Conf['Fit Width'] ? `${frame.clientWidth}px` : 'none';\r\n margin = (current.clientWidth - current.clientHeight)/2;\r\n return style.margin = `${margin}px ${-margin}px`;\r\n } else {\r\n return style.maxWidth = (style.maxHeight = (style.margin = ''));\r\n }\r\n }),\r\n\r\n setDelay() { return Gallery.delay = +this.value; }\r\n },\r\n\r\n menu: {\r\n init() {\r\n if (!Gallery.enabled) { return; }\r\n\r\n const el = $.el('span', {\r\n textContent: 'Gallery',\r\n className: 'gallery-link'\r\n }\r\n );\r\n\r\n return Header.menu.addEntry({\r\n el,\r\n order: 105,\r\n subEntries: Gallery.menu.createSubEntries()\r\n });\r\n },\r\n\r\n createSubEntry(name) {\r\n const label = UI.checkbox(name, name);\r\n const input = label.firstElementChild;\r\n if (['Hide Thumbnails', 'Fit Width', 'Fit Height'].includes(name)) { $.on(input, 'change', Gallery.cb.setFitness); }\r\n $.event('change', null, input);\r\n $.on(input, 'change', $.cb.checked);\r\n if (['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Stretch to Fit'].includes(name)) { $.on(input, 'change', Gallery.cb.setHeight); }\r\n return {el: label};\r\n },\r\n\r\n createSubEntries() {\r\n const subEntries = (['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Stretch to Fit', 'Scroll to Post'].map((item) => Gallery.menu.createSubEntry(item)));\r\n\r\n const delayLabel = $.el('label', {innerHTML: 'Slide Delay: '});\r\n const delayInput = delayLabel.firstElementChild;\r\n delayInput.value = Gallery.delay;\r\n $.on(delayInput, 'change', Gallery.cb.setDelay);\r\n $.on(delayInput, 'change', $.cb.value);\r\n subEntries.push({el: delayLabel});\r\n\r\n return subEntries;\r\n }\r\n }\r\n};\r\nexport default Gallery;\r\n","import Get from '../General/Get';\r\nimport Header from '../General/Header';\r\nimport UI from '../General/UI';\r\nimport { g, Conf, d, doc, E } from '../globals/globals';\r\nimport ImageHost from '../Images/ImageHost';\r\nimport Main from '../main/Main';\r\nimport $ from '../platform/$';\r\nimport $$ from '../platform/$$';\r\nimport CrossOrigin from '../platform/CrossOrigin';\r\nimport { dict } from '../platform/helpers';\r\nimport EmbeddingPage from './Embedding/Embed.html';\r\n/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS205: Consider reworking code to avoid use of IIFEs\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\n\r\nvar Embedding = {\r\n init() {\r\n if (!['index', 'thread', 'archive'].includes(g.VIEW) || !Conf['Linkify'] || (!Conf['Embedding'] && !Conf['Link Title'] && !Conf['Cover Preview'])) { return; }\r\n this.types = dict();\r\n for (var type of this.ordered_types) { this.types[type.key] = type; }\r\n\r\n if (Conf['Embedding'] && (g.VIEW !== 'archive')) {\r\n this.dialog = UI.dialog('embedding',\r\n { innerHTML: EmbeddingPage });\r\n this.media = $('#media-embed', this.dialog);\r\n $.one(d, '4chanXInitFinished', this.ready);\r\n $.on(d, 'IndexRefreshInternal', () => g.posts.forEach(function(post) {\r\n for (post of [post, ...Array.from(post.clones)]) {\r\n for (var embed of post.nodes.embedlinks) {\r\n Embedding.cb.catalogRemove.call(embed);\r\n }\r\n }\r\n }));\r\n }\r\n if (Conf['Link Title']) {\r\n return $.on(d, '4chanXInitFinished PostsInserted', function() {\r\n for (var key in Embedding.types) {\r\n var service = Embedding.types[key];\r\n if (service.title?.batchSize) {\r\n Embedding.flushTitles(service.title);\r\n }\r\n }\r\n });\r\n }\r\n },\r\n\r\n events(post) {\r\n let el, i, items;\r\n if (g.VIEW === 'archive') { return; }\r\n if (Conf['Embedding']) {\r\n i = 0;\r\n items = (post.nodes.embedlinks = $$('.embedder', post.nodes.comment));\r\n while ((el = items[i++])) {\r\n $.on(el, 'click', Embedding.cb.click);\r\n if ($.hasClass(el, 'embedded')) { Embedding.cb.toggle.call(el); }\r\n }\r\n }\r\n if (Conf['Cover Preview']) {\r\n i = 0;\r\n items = $$('.linkify', post.nodes.comment);\r\n while ((el = items[i++])) {\r\n var data;\r\n if (data = Embedding.services(el)) {\r\n Embedding.preview(data);\r\n }\r\n }\r\n return;\r\n }\r\n },\r\n\r\n process(link, post) {\r\n let data;\r\n if (!Conf['Embedding'] && !Conf['Link Title'] && !Conf['Cover Preview']) { return; }\r\n if ($.x('ancestor::pre', link)) { return; }\r\n if (data = Embedding.services(link)) {\r\n data.post = post;\r\n if (Conf['Embedding'] && (g.VIEW !== 'archive')) { Embedding.embed(data); }\r\n if (Conf['Link Title']) { Embedding.title(data); }\r\n if (Conf['Cover Preview'] && (g.VIEW !== 'archive')) { return Embedding.preview(data); }\r\n }\r\n },\r\n\r\n services(link) {\r\n const {href} = link;\r\n for (var type of Embedding.ordered_types) {\r\n var match;\r\n if (match = type.regExp.exec(href)) {\r\n return {key: type.key, uid: match[1], options: match[2], link};\r\n }\r\n }\r\n },\r\n\r\n embed(data) {\r\n const {key, uid, options, link, post} = data;\r\n const {href} = link;\r\n\r\n $.addClass(link, key.toLowerCase());\r\n\r\n const embed = $.el('a', {\r\n className: 'embedder',\r\n href: 'javascript:;'\r\n }\r\n ,\r\n {innerHTML: '(unembed)'});\r\n\r\n const object = {key, uid, options, href};\r\n for (var name in object) { var value = object[name]; embed.dataset[name] = value; }\r\n\r\n $.on(embed, 'click', Embedding.cb.click);\r\n $.after(link, [$.tn(' '), embed]);\r\n post.nodes.embedlinks.push(embed);\r\n\r\n if (Conf['Auto-embed'] && !Conf['Floating Embeds'] && !post.isFetchedQuote) {\r\n if ($.hasClass(doc, 'catalog-mode')) {\r\n return $.addClass(embed, 'embed-removed');\r\n } else {\r\n return Embedding.cb.toggle.call(embed);\r\n }\r\n }\r\n },\r\n\r\n ready() {\r\n if (!Main.isThisPageLegit()) { return; }\r\n $.addClass(Embedding.dialog, 'empty');\r\n $.on($('.close', Embedding.dialog), 'click', Embedding.closeFloat);\r\n $.on($('.move', Embedding.dialog), 'mousedown', Embedding.dragEmbed);\r\n $.on($('.jump', Embedding.dialog), 'click', function() {\r\n if (doc.contains(Embedding.lastEmbed)) { return Header.scrollTo(Embedding.lastEmbed); }\r\n });\r\n return $.add(d.body, Embedding.dialog);\r\n },\r\n\r\n closeFloat() {\r\n delete Embedding.lastEmbed;\r\n $.addClass(Embedding.dialog, 'empty');\r\n return $.replace(Embedding.media.firstChild, $.el('div'));\r\n },\r\n\r\n dragEmbed() {\r\n // only webkit can handle a blocking div\r\n const {style} = Embedding.media;\r\n if (Embedding.dragEmbed.mouseup) {\r\n $.off(d, 'mouseup', Embedding.dragEmbed);\r\n Embedding.dragEmbed.mouseup = false;\r\n style.pointerEvents = '';\r\n return;\r\n }\r\n $.on(d, 'mouseup', Embedding.dragEmbed);\r\n Embedding.dragEmbed.mouseup = true;\r\n return style.pointerEvents = 'none';\r\n },\r\n\r\n title(data) {\r\n let service;\r\n const {key, uid, options, link, post} = data;\r\n if (!(service = Embedding.types[key].title)) { return; }\r\n $.addClass(link, key.toLowerCase());\r\n if (service.batchSize) {\r\n (service.queue || (service.queue = [])).push(data);\r\n if (service.queue.length >= service.batchSize) {\r\n return Embedding.flushTitles(service);\r\n }\r\n } else {\r\n return CrossOrigin.cache(service.api(uid), (function() { return Embedding.cb.title(this, data); }));\r\n }\r\n },\r\n\r\n flushTitles(service) {\r\n let data;\r\n const {queue} = service;\r\n if (!queue?.length) { return; }\r\n service.queue = [];\r\n const cb = function() {\r\n for (data of queue) { Embedding.cb.title(this, data); }\r\n };\r\n return CrossOrigin.cache(service.api((() => {\r\n const result = [];\r\n for (data of queue) { result.push(data.uid);\r\n }\r\n return result;\r\n })()), cb);\r\n },\r\n\r\n preview(data) {\r\n let service;\r\n const {key, uid, link} = data;\r\n if (!(service = Embedding.types[key].preview)) { return; }\r\n return $.on(link, 'mouseover', function(e) {\r\n const src = service.url(uid);\r\n const {height} = service;\r\n const el = $.el('img', {\r\n src,\r\n id: 'ihover'\r\n }\r\n );\r\n $.add(Header.hover, el);\r\n return UI.hover({\r\n root: link,\r\n el,\r\n latestEvent: e,\r\n endEvents: 'mouseout click',\r\n height\r\n });\r\n });\r\n },\r\n\r\n cb: {\r\n click(e) {\r\n e.preventDefault();\r\n if (!$.hasClass(this, 'embedded') && (Conf['Floating Embeds'] || $.hasClass(doc, 'catalog-mode'))) {\r\n let div;\r\n if (!(div = Embedding.media.firstChild)) { return; }\r\n $.replace(div, Embedding.cb.embed(this));\r\n Embedding.lastEmbed = Get.postFromNode(this).nodes.root;\r\n return $.rmClass(Embedding.dialog, 'empty');\r\n } else {\r\n return Embedding.cb.toggle.call(this);\r\n }\r\n },\r\n\r\n toggle() {\r\n if ($.hasClass(this, \"embedded\")) {\r\n $.rm(this.nextElementSibling);\r\n } else {\r\n $.after(this, Embedding.cb.embed(this));\r\n }\r\n return $.toggleClass(this, 'embedded');\r\n },\r\n\r\n embed(a) {\r\n // We create an element to embed\r\n let el, type;\r\n const container = $.el('div', {className: 'media-embed'});\r\n $.add(container, (el = (type = Embedding.types[a.dataset.key]).el(a)));\r\n\r\n // Set style values.\r\n el.style.cssText = (type.style != null) ?\r\n type.style\r\n :\r\n 'border: none; width: 640px; height: 360px;';\r\n\r\n return container;\r\n },\r\n\r\n catalogRemove() {\r\n const isCatalog = $.hasClass(doc, 'catalog-mode');\r\n if ((isCatalog && $.hasClass(this, 'embedded')) || (!isCatalog && $.hasClass(this, 'embed-removed'))) {\r\n Embedding.cb.toggle.call(this);\r\n return $.toggleClass(this, 'embed-removed');\r\n }\r\n },\r\n\r\n title(req, data) {\r\n let text;\r\n const {key, uid, options, link, post} = data;\r\n const service = Embedding.types[key].title;\r\n\r\n let {status} = req;\r\n if ([200, 304].includes(status) && service.status) {\r\n status = service.status(req.response)[0];\r\n }\r\n\r\n if (!status) { return; }\r\n\r\n text = `[${key}] ${(() => { switch (status) {\r\n case 200: case 304:\r\n text = service.text(req.response, uid);\r\n if (typeof text === 'string') {\r\n return text;\r\n } else {\r\n return text = link.textContent;\r\n }\r\n case 404:\r\n return \"Not Found\";\r\n case 403: case 401:\r\n return \"Forbidden or Private\";\r\n default:\r\n return `${status}'d`;\r\n } })()\r\n }`;\r\n\r\n link.dataset.original = link.textContent;\r\n link.textContent = text;\r\n for (var post2 of post.clones) {\r\n for (var link2 of $$('a.linkify', post2.nodes.comment)) {\r\n if (link2.href === link.href) {\r\n if (link2.dataset.original == null) { link2.dataset.original = link2.textContent; }\r\n link2.textContent = text;\r\n }\r\n }\r\n }\r\n }\r\n },\r\n\r\n ordered_types: [{\r\n key: 'audio',\r\n regExp: /^[^?#]+\\.(?:mp3|m4a|oga|wav|flac)(?:[?#]|$)/i,\r\n style: '',\r\n el(a) {\r\n return $.el('audio', {\r\n controls: true,\r\n preload: 'auto',\r\n src: a.dataset.href\r\n }\r\n );\r\n }\r\n }\r\n , {\r\n key: 'image',\r\n regExp: /^[^?#]+\\.(?:gif|png|jpg|jpeg|bmp|webp)(?::\\w+)?(?:[?#]|$)/i,\r\n style: '',\r\n el(a) {\r\n const hrefEsc = E(a.dataset.href);\r\n return $.el('div', { innerHTML: ``});\r\n }\r\n }\r\n , {\r\n key: 'video',\r\n regExp: /^[^?#]+\\.(?:og[gv]|webm|mp4)(?:[?#]|$)/i,\r\n style: 'max-width: 80vw; max-height: 80vh;',\r\n el(a) {\r\n const el = $.el('video', {\r\n hidden: true,\r\n controls: true,\r\n preload: 'auto',\r\n src: a.dataset.href,\r\n loop: ImageHost.test(a.dataset.href.split('/')[2])\r\n });\r\n $.on(el, 'loadedmetadata', function() {\r\n if ((el.videoHeight === 0) && el.parentNode) {\r\n return $.replace(el, Embedding.types.audio.el(a));\r\n } else {\r\n return el.hidden = false;\r\n }\r\n });\r\n return el;\r\n }\r\n }\r\n , {\r\n key: 'PeerTube',\r\n regExp: /^(\\w+:\\/\\/[^\\/]+\\/videos\\/watch\\/\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12})(.*)/,\r\n el(a) {\r\n let start;\r\n const options = (start = a.dataset.options.match(/[?&](start=\\w+)/)) ? `?${start[1]}` : '';\r\n const el = $.el('iframe',\r\n {src: a.dataset.uid.replace('/videos/watch/', '/videos/embed/') + options});\r\n el.setAttribute(\"allowfullscreen\", \"true\");\r\n return el;\r\n }\r\n }\r\n , {\r\n key: 'BitChute',\r\n regExp: /^\\w+:\\/\\/(?:www\\.)?bitchute\\.com\\/video\\/([\\w\\-]+)/,\r\n el(a) {\r\n const el = $.el('iframe',\r\n {src: `https://www.bitchute.com/embed/${a.dataset.uid}/`});\r\n el.setAttribute(\"allowfullscreen\", \"true\");\r\n return el;\r\n }\r\n }\r\n , {\r\n key: 'Clyp',\r\n regExp: /^\\w+:\\/\\/(?:www\\.)?clyp\\.it\\/(\\w{8})/,\r\n style: 'border: 0; width: 640px; height: 160px;',\r\n el(a) {\r\n return $.el('iframe',\r\n {src: `https://clyp.it/${a.dataset.uid}/widget`});\r\n },\r\n title: {\r\n api(uid) { return `https://api.clyp.it/oembed?url=https://clyp.it/${uid}`; },\r\n text(_) { return _.title; }\r\n }\r\n }\r\n , {\r\n key: 'Dailymotion',\r\n regExp: /^\\w+:\\/\\/(?:(?:www\\.)?dailymotion\\.com\\/(?:embed\\/)?video|dai\\.ly)\\/([A-Za-z0-9]+)[^?]*(.*)/,\r\n el(a) {\r\n let start;\r\n const options = (start = a.dataset.options.match(/[?&](start=\\d+)/)) ? `?${start[1]}` : '';\r\n const el = $.el('iframe',\r\n {src: `//www.dailymotion.com/embed/video/${a.dataset.uid}${options}`});\r\n el.setAttribute(\"allowfullscreen\", \"true\");\r\n return el;\r\n },\r\n title: {\r\n api(uid) { return `https://api.dailymotion.com/video/${uid}`; },\r\n text(_) { return _.title; }\r\n },\r\n preview: {\r\n url(uid) { return `https://www.dailymotion.com/thumbnail/video/${uid}`; },\r\n height: 240\r\n }\r\n }\r\n , {\r\n key: 'Gfycat',\r\n regExp: /^\\w+:\\/\\/(?:www\\.)?gfycat\\.com\\/(?:iframe\\/)?(\\w+)/,\r\n el(a) {\r\n const el = $.el('iframe',\r\n {src: `//gfycat.com/ifr/${a.dataset.uid}`});\r\n el.setAttribute(\"allowfullscreen\", \"true\");\r\n return el;\r\n }\r\n }\r\n , {\r\n key: 'Gist',\r\n regExp: /^\\w+:\\/\\/gist\\.github\\.com\\/[\\w\\-]+\\/(\\w+)/,\r\n style: '',\r\n el: (function() {\r\n let counter = 0;\r\n return function(a) {\r\n const el = $.el('pre', {\r\n hidden: true,\r\n id: `gist-embed-${counter++}`\r\n }\r\n );\r\n CrossOrigin.cache(`https://api.github.com/gists/${a.dataset.uid}`, function() {\r\n el.textContent = Object.values(this.response.files)[0].content;\r\n el.className = 'prettyprint';\r\n $.global(() => window.prettyPrint?.((function() {}), document.getElementById(document.currentScript.dataset.id).parentNode)\r\n , {id: el.id});\r\n return el.hidden = false;\r\n });\r\n return el;\r\n };\r\n })(),\r\n title: {\r\n api(uid) { return `https://api.github.com/gists/${uid}`; },\r\n text({files}) {\r\n for (var file in files) { if (files.hasOwnProperty(file)) { return file; } }\r\n }\r\n }\r\n }\r\n , {\r\n key: 'InstallGentoo',\r\n regExp: /^\\w+:\\/\\/paste\\.installgentoo\\.com\\/view\\/(?:raw\\/|download\\/|embed\\/)?(\\w+)/,\r\n el(a) {\r\n return $.el('iframe',\r\n {src: `https://paste.installgentoo.com/view/embed/${a.dataset.uid}`});\r\n }\r\n }\r\n , {\r\n key: 'LiveLeak',\r\n regExp: /^\\w+:\\/\\/(?:\\w+\\.)?liveleak\\.com\\/.*\\?.*[tif]=(\\w+)/,\r\n el(a) {\r\n const el = $.el('iframe',\r\n {src: `https://www.liveleak.com/e/${a.dataset.uid}`,});\r\n el.setAttribute(\"allowfullscreen\", \"true\");\r\n return el;\r\n }\r\n }\r\n , {\r\n key: 'Loopvid',\r\n 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?:\\/\\/.+)/,\r\n style: 'max-width: 80vw; max-height: 80vh;',\r\n el(a) {\r\n const el = $.el('video', {\r\n controls: true,\r\n preload: 'auto',\r\n loop: true\r\n }\r\n );\r\n if (/^http/.test(a.dataset.uid)) {\r\n $.add(el, $.el('source', {src: a.dataset.uid}));\r\n return el;\r\n }\r\n const [_, host, names] = Array.from(a.dataset.uid.match(/(\\w+)\\/(.*)/));\r\n const types = (() => { switch (host) {\r\n case 'gd': case 'wu': case 'fc': return [''];\r\n case 'gc': return ['giant', 'fat', 'zippy'];\r\n default: return ['.webm', '.mp4'];\r\n } })();\r\n for (var name of names.split(',')) {\r\n for (var type of types) {\r\n var base = `${name}${type}`;\r\n var urls = (() => { switch (host) {\r\n // list from src/common.py at http://loopvid.appspot.com/source.html\r\n case 'pf': return [`https://kastden.org/_loopvid_media/pf/${base}`, `https://web.archive.org/web/2/http://a.pomf.se/${base}`];\r\n case 'kd': return [`https://kastden.org/loopvid/${base}`];\r\n case 'lv': return [`https://lv.kastden.org/${base}`];\r\n case 'gd': return [`https://docs.google.com/uc?export=download&id=${base}`];\r\n case 'gh': return [`https://googledrive.com/host/${base}`];\r\n case 'db': return [`https://dl.dropboxusercontent.com/u/${base}`];\r\n case 'dx': return [`https://dl.dropboxusercontent.com/${base}`];\r\n case 'nn': return [`https://kastden.org/_loopvid_media/nn/${base}`];\r\n case 'cp': return [`https://copy.com/${base}`];\r\n case 'wu': return [`http://webmup.com/${base}/vid.webm`];\r\n case 'ig': return [`https://i.imgur.com/${base}`];\r\n case 'ky': return [`https://kastden.org/_loopvid_media/ky/${base}`];\r\n case 'mf': return [`https://kastden.org/_loopvid_media/mf/${base}`, `https://web.archive.org/web/2/https://d.maxfile.ro/${base}`];\r\n case 'm2': return [`https://kastden.org/_loopvid_media/m2/${base}`];\r\n case 'pc': return [`https://kastden.org/_loopvid_media/pc/${base}`, `https://web.archive.org/web/2/http://a.pomf.cat/${base}`];\r\n case '1c': return [`http://b.1339.cf/${base}`];\r\n case 'pi': return [`https://kastden.org/_loopvid_media/pi/${base}`, `https://web.archive.org/web/2/https://u.pomf.is/${base}`];\r\n case 'ni': return [`https://kastden.org/_loopvid_media/ni/${base}`, `https://web.archive.org/web/2/https://u.nya.is/${base}`];\r\n case 'wl': return [`http://webm.land/media/${base}`];\r\n case 'ko': return [`https://kordy.kastden.org/loopvid/${base}`];\r\n case 'mm': return [`https://kastden.org/_loopvid_media/mm/${base}`, `https://web.archive.org/web/2/https://my.mixtape.moe/${base}`];\r\n case 'ic': return [`https://media.8ch.net/file_store/${base}`];\r\n case 'fc': return [`//${ImageHost.host()}/${base}.webm`];\r\n case 'gc': return [`https://${type}.gfycat.com/${name}.webm`];\r\n } })();\r\n\r\n for (var url of urls) {\r\n $.add(el, $.el('source', {src: url}));\r\n }\r\n }\r\n }\r\n return el;\r\n }\r\n }\r\n , {\r\n key: 'Openings.moe',\r\n regExp: /^\\w+:\\/\\/openings.moe\\/\\?video=([^.&=]+)/,\r\n style: 'width: 1280px; height: 720px; max-width: 80vw; max-height: 80vh;',\r\n el(a) {\r\n const el = $.el('iframe',\r\n {src: `https://openings.moe/?video=${a.dataset.uid}`,});\r\n el.setAttribute(\"allowfullscreen\", \"true\");\r\n return el;\r\n }\r\n }\r\n , {\r\n key: 'Pastebin',\r\n regExp: /^\\w+:\\/\\/(?:\\w+\\.)?pastebin\\.com\\/(?!u\\/)(?:[\\w.]+(?:\\/|\\?i\\=))?(\\w+)/,\r\n el(a) {\r\n let div;\r\n return div = $.el('iframe',\r\n {src: `//pastebin.com/embed_iframe.php?i=${a.dataset.uid}`});\r\n }\r\n }\r\n , {\r\n key: 'SoundCloud',\r\n regExp: /^\\w+:\\/\\/(?:www\\.)?(?:soundcloud\\.com\\/|snd\\.sc\\/)([\\w\\-\\/]+)/,\r\n style: 'border: 0; width: 500px; height: 400px;',\r\n el(a) {\r\n return $.el('iframe',\r\n {src: `https://w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F${encodeURIComponent(a.dataset.uid)}`});\r\n },\r\n title: {\r\n api(uid) { return `${location.protocol}//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F${encodeURIComponent(uid)}`; },\r\n text(_) { return _.title; }\r\n }\r\n }\r\n , {\r\n key: 'StrawPoll',\r\n regExp: /^\\w+:\\/\\/(?:www\\.)?strawpoll\\.me\\/(?:embed_\\d+\\/)?(\\d+(?:\\/r)?)/,\r\n style: 'border: 0; width: 600px; height: 406px;',\r\n el(a) {\r\n return $.el('iframe',\r\n {src: `https://www.strawpoll.me/embed_1/${a.dataset.uid}`});\r\n }\r\n }\r\n , {\r\n key: 'Streamable',\r\n regExp: /^\\w+:\\/\\/(?:www\\.)?streamable\\.com\\/(\\w+)/,\r\n el(a) {\r\n const el = $.el('iframe',\r\n {src: `https://streamable.com/o/${a.dataset.uid}`});\r\n el.setAttribute(\"allowfullscreen\", \"true\");\r\n return el;\r\n },\r\n title: {\r\n api(uid) { return `https://api.streamable.com/oembed?url=https://streamable.com/${uid}`; },\r\n text(_) { return _.title; }\r\n }\r\n }\r\n , {\r\n key: 'TwitchTV',\r\n regExp: /^\\w+:\\/\\/(?:www\\.|secure\\.|clips\\.|m\\.)?twitch\\.tv\\/(\\w[^#\\&\\?]*)/,\r\n el(a) {\r\n let url;\r\n let m = a.dataset.href.match(/^\\w+:\\/\\/(?:(clips\\.)|\\w+\\.)?twitch\\.tv\\/(?:\\w+\\/)?(clip\\/)?(\\w[^#\\&\\?]*)/);\r\n if (m[1] || m[2]) {\r\n url = `//clips.twitch.tv/embed?clip=${m[3]}&parent=${location.hostname}`;\r\n } else {\r\n let time;\r\n m = a.dataset.uid.match(/(\\w+)(?:\\/(?:v\\/)?(\\d+))?/);\r\n url = `//player.twitch.tv/?${m[2] ? `video=v${m[2]}` : `channel=${m[1]}`}&autoplay=false&parent=${location.hostname}`;\r\n if (time = a.dataset.href.match(/\\bt=(\\w+)/)) {\r\n url += `&time=${time[1]}`;\r\n }\r\n }\r\n const el = $.el('iframe',\r\n {src: url});\r\n el.setAttribute(\"allowfullscreen\", \"true\");\r\n return el;\r\n }\r\n }\r\n , {\r\n key: 'Twitter',\r\n regExp: /^\\w+:\\/\\/(?:www\\.|mobile\\.)?twitter\\.com\\/(\\w+\\/status\\/\\d+)/,\r\n style: 'border: none; width: 550px; height: 250px; overflow: hidden; resize: both;',\r\n el(a) {\r\n const el = $.el('iframe');\r\n $.on(el, 'load', function() {\r\n return this.contentWindow.postMessage({element: 't', query: 'height'}, 'https://twitframe.com');\r\n });\r\n var onMessage = function(e) {\r\n if ((e.source === el.contentWindow) && (e.origin === 'https://twitframe.com')) {\r\n $.off(window, 'message', onMessage);\r\n return (cont || el).style.height = `${+$.minmax(e.data.height, 250, 0.8 * doc.clientHeight)}px`;\r\n }\r\n };\r\n $.on(window, 'message', onMessage);\r\n el.src = `https://twitframe.com/show?url=https://twitter.com/${a.dataset.uid}`;\r\n if ($.engine === 'gecko') {\r\n // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=680823\r\n el.style.cssText = 'border: none; width: 100%; height: 100%;';\r\n var cont = $.el('div');\r\n $.add(cont, el);\r\n return cont;\r\n } else {\r\n return el;\r\n }\r\n }\r\n }\r\n , {\r\n key: 'VidLii',\r\n regExp: /^\\w+:\\/\\/(?:www\\.)?vidlii\\.com\\/watch\\?v=(\\w{11})/,\r\n style: 'border: none; width: 640px; height: 392px;',\r\n el(a) {\r\n const el = $.el('iframe',\r\n {src: `https://www.vidlii.com/embed?v=${a.dataset.uid}&a=0`});\r\n el.setAttribute(\"allowfullscreen\", \"true\");\r\n return el;\r\n }\r\n }\r\n , {\r\n key: 'Vimeo',\r\n regExp: /^\\w+:\\/\\/(?:www\\.)?vimeo\\.com\\/(\\d+)/,\r\n el(a) {\r\n const el = $.el('iframe',\r\n {src: `//player.vimeo.com/video/${a.dataset.uid}?wmode=opaque`});\r\n el.setAttribute(\"allowfullscreen\", \"true\");\r\n return el;\r\n },\r\n title: {\r\n api(uid) { return `https://vimeo.com/api/oembed.json?url=https://vimeo.com/${uid}`; },\r\n text(_) { return _.title; }\r\n }\r\n }\r\n , {\r\n key: 'Vine',\r\n regExp: /^\\w+:\\/\\/(?:www\\.)?vine\\.co\\/v\\/(\\w+)/,\r\n style: 'border: none; width: 500px; height: 500px;',\r\n el(a) {\r\n return $.el('iframe',\r\n {src: `https://vine.co/v/${a.dataset.uid}/card`});\r\n }\r\n }\r\n , {\r\n key: 'Vocaroo',\r\n regExp: /^\\w+:\\/\\/(?:(?:www\\.|old\\.)?vocaroo\\.com|voca\\.ro)\\/((?:i\\/)?\\w+)/,\r\n style: '',\r\n el(a) {\r\n const el = $.el('iframe');\r\n el.width = 300;\r\n el.height = 60;\r\n el.setAttribute('frameborder', 0);\r\n el.src = `https://vocaroo.com/embed/${a.dataset.uid.replace(/^i\\//, '')}?autoplay=0`;\r\n return el;\r\n }\r\n }\r\n , {\r\n key: 'YouTube',\r\n regExp: /^\\w+:\\/\\/(?:youtu.be\\/|[\\w.]*youtube[\\w.]*\\/.*(?:v=|\\bembed\\/|\\bv\\/|live\\/))([\\w\\-]{11})(.*)/,\r\n el(a) {\r\n let start = a.dataset.options.match(/\\b(?:star)?t\\=(\\w+)/);\r\n if (start) { start = start[1]; }\r\n if (start && !/^\\d+$/.test(start)) {\r\n start += ' 0h0m0s';\r\n start = (3600 * start.match(/(\\d+)h/)[1]) + (60 * start.match(/(\\d+)m/)[1]) + (1 * start.match(/(\\d+)s/)[1]);\r\n }\r\n const el = $.el('iframe',\r\n {src: `//www.youtube.com/embed/${a.dataset.uid}?rel=0&wmode=opaque${start ? '&start=' + start : ''}`});\r\n el.setAttribute(\"allowfullscreen\", \"true\");\r\n return el;\r\n },\r\n title: {\r\n api(uid) { return `https://www.youtube.com/oembed?url=https%3A//www.youtube.com/watch%3Fv%3D${uid}&format=json`; },\r\n text(_) { return _.title; },\r\n status(_) {\r\n if (_.error) {\r\n const m = _.error.match(/^(\\d*)\\s*(.*)/);\r\n return [+m[1], m[2]];\r\n } else {\r\n return [200, 'OK'];\r\n }\r\n }\r\n },\r\n preview: {\r\n url(uid) { return `https://img.youtube.com/vi/${uid}/0.jpg`; },\r\n height: 360\r\n }\r\n }\r\n ]\r\n};\r\nexport default Embedding;\r\n","import Notice from \"../classes/Notice\";\r\nimport Config from \"../config/Config\";\r\nimport Filter from \"../Filtering/Filter\";\r\nimport ThreadHiding from \"../Filtering/ThreadHiding\";\r\nimport BoardConfig from \"../General/BoardConfig\";\r\nimport Get from \"../General/Get\";\r\nimport Header from \"../General/Header\";\r\nimport Index from \"../General/Index\";\r\nimport Settings from \"../General/Settings\";\r\nimport { Conf, d, g } from \"../globals/globals\";\r\nimport FappeTyme from \"../Images/FappeTyme\";\r\nimport Gallery from \"../Images/Gallery\";\r\nimport ImageExpand from \"../Images/ImageExpand\";\r\nimport Embedding from \"../Linkification/Embedding\";\r\nimport ThreadUpdater from \"../Monitoring/ThreadUpdater\";\r\nimport ThreadWatcher from \"../Monitoring/ThreadWatcher\";\r\nimport UnreadIndex from \"../Monitoring/UnreadIndex\";\r\nimport $ from \"../platform/$\";\r\nimport $$ from \"../platform/$$\";\r\nimport QR from \"../Posting/QR\";\r\nimport QuoteThreading from \"../Quotelinks/QuoteThreading\";\r\nimport QuoteYou from \"../Quotelinks/QuoteYou\";\r\nimport CatalogLinks from \"./CatalogLinks\";\r\nimport ExpandThread from \"./ExpandThread\";\r\nimport Nav from \"./Nav\";\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS205: Consider reworking code to avoid use of IIFEs\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\nvar Keybinds = {\r\n init() {\r\n if (!Conf['Keybinds']) { return; }\r\n\r\n for (var hotkey in Config.hotkeys) {\r\n $.sync(hotkey, Keybinds.sync);\r\n }\r\n\r\n var init = function() {\r\n $.off(d, '4chanXInitFinished', init);\r\n $.on(d, 'keydown', Keybinds.keydown);\r\n for (var node of $$('[accesskey]')) {\r\n node.removeAttribute('accesskey');\r\n }\r\n };\r\n return $.on(d, '4chanXInitFinished', init);\r\n },\r\n\r\n sync(key, hotkey) {\r\n return Conf[hotkey] = key;\r\n },\r\n\r\n keydown(e) {\r\n let key, thread, threadRoot;\r\n let catalog, notifications;\r\n if (!(key = Keybinds.keyCode(e))) { return; }\r\n const {target} = e;\r\n if (['INPUT', 'TEXTAREA'].includes(target.nodeName)) {\r\n if (!/(Esc|Alt|Ctrl|Meta|Shift\\+\\w{2,})/.test(key) || !!/^Alt\\+(\\d|Up|Down|Left|Right)$/.test(key)) { return; }\r\n }\r\n if (['index', 'thread'].includes(g.VIEW)) {\r\n threadRoot = Nav.getThread();\r\n thread = Get.threadFromRoot(threadRoot);\r\n }\r\n switch (key) {\r\n // QR & Options\r\n case Conf['Toggle board list']:\r\n if (!Conf['Custom Board Navigation']) { return; }\r\n Header.toggleBoardList();\r\n break;\r\n case Conf['Toggle header']:\r\n Header.toggleBarVisibility();\r\n break;\r\n case Conf['Open empty QR']:\r\n if (!QR.postingIsEnabled) { return; }\r\n Keybinds.qr();\r\n break;\r\n case Conf['Open QR']:\r\n if (!QR.postingIsEnabled || !threadRoot) { return; }\r\n Keybinds.qr(threadRoot);\r\n break;\r\n case Conf['Open settings']:\r\n Settings.open();\r\n break;\r\n case Conf['Close']:\r\n if (Settings.dialog) {\r\n Settings.close();\r\n } else if ((notifications = $$('.notification')).length) {\r\n for (var notification of notifications) {\r\n $('.close', notification).click();\r\n }\r\n } else if (QR.nodes && !(QR.nodes.el.hidden || (window.getComputedStyle(QR.nodes.form).display === 'none'))) {\r\n if (Conf['Persistent QR']) {\r\n QR.hide();\r\n } else {\r\n QR.close();\r\n }\r\n } else if (Embedding.lastEmbed) {\r\n Embedding.closeFloat();\r\n } else {\r\n return;\r\n }\r\n break;\r\n case Conf['Spoiler tags']:\r\n if (target.nodeName !== 'TEXTAREA') { return; }\r\n Keybinds.tags('spoiler', target);\r\n break;\r\n case Conf['Code tags']:\r\n if (target.nodeName !== 'TEXTAREA') { return; }\r\n Keybinds.tags('code', target);\r\n break;\r\n case Conf['Eqn tags']:\r\n if (target.nodeName !== 'TEXTAREA') { return; }\r\n Keybinds.tags('eqn', target);\r\n break;\r\n case Conf['Math tags']:\r\n if (target.nodeName !== 'TEXTAREA') { return; }\r\n Keybinds.tags('math', target);\r\n break;\r\n case Conf['SJIS tags']:\r\n if (target.nodeName !== 'TEXTAREA') { return; }\r\n Keybinds.tags('sjis', target);\r\n break;\r\n case Conf['Toggle sage']:\r\n if (!QR.nodes || !!QR.nodes.el.hidden) { return; }\r\n Keybinds.sage();\r\n break;\r\n case Conf['Toggle Cooldown']:\r\n if (!QR.nodes || !!QR.nodes.el.hidden || !$.hasClass(QR.nodes.fileSubmit, 'custom-cooldown')) { return; }\r\n QR.toggleCustomCooldown();\r\n break;\r\n case Conf['Post from URL']:\r\n if (!QR.postingIsEnabled) { return; }\r\n QR.handleUrl('');\r\n break;\r\n case Conf['Add new post']:\r\n if (!QR.postingIsEnabled) { return; }\r\n QR.addPost();\r\n break;\r\n case Conf['Submit QR']:\r\n if (!QR.nodes || !!QR.nodes.el.hidden) { return; }\r\n if (!QR.status()) { QR.submit(); }\r\n break;\r\n // Index/Thread related\r\n case Conf['Update']:\r\n switch (g.VIEW) {\r\n case 'thread':\r\n if (!ThreadUpdater.enabled) { return; }\r\n ThreadUpdater.update();\r\n break;\r\n case 'index':\r\n if (!Index.enabled) { return; }\r\n Index.update();\r\n break;\r\n default:\r\n return;\r\n }\r\n break;\r\n case Conf['Watch']:\r\n if (!ThreadWatcher.enabled || !thread) { return; }\r\n ThreadWatcher.toggle(thread);\r\n break;\r\n case Conf['Update thread watcher']:\r\n if (!ThreadWatcher.enabled) { return; }\r\n ThreadWatcher.buttonFetchAll();\r\n break;\r\n case Conf['Toggle thread watcher']:\r\n if (!ThreadWatcher.enabled) { return; }\r\n ThreadWatcher.toggleWatcher();\r\n break;\r\n case Conf['Toggle threading']:\r\n if (!QuoteThreading.ready) { return; }\r\n QuoteThreading.toggleThreading();\r\n break;\r\n case Conf['Mark thread read']:\r\n if ((g.VIEW !== 'index') || !thread || !UnreadIndex.enabled) { return; }\r\n UnreadIndex.markRead.call(threadRoot);\r\n break;\r\n // Images\r\n case Conf['Expand image']:\r\n if (!ImageExpand.enabled || !threadRoot) { return; }\r\n var post = Get.postFromNode(Keybinds.post(threadRoot));\r\n if (post.file) { ImageExpand.toggle(post); }\r\n break;\r\n case Conf['Expand images']:\r\n if (!ImageExpand.enabled) { return; }\r\n ImageExpand.cb.toggleAll();\r\n break;\r\n case Conf['Open Gallery']:\r\n if (!Gallery.enabled) { return; }\r\n Gallery.cb.toggle();\r\n break;\r\n case Conf['fappeTyme']:\r\n if (!FappeTyme.nodes?.fappe) { return; }\r\n FappeTyme.toggle('fappe');\r\n break;\r\n case Conf['werkTyme']:\r\n if (!FappeTyme.nodes?.werk) { return; }\r\n FappeTyme.toggle('werk');\r\n break;\r\n // Board Navigation\r\n case Conf['Front page']:\r\n if (Index.enabled) {\r\n Index.userPageNav(1);\r\n } else {\r\n location.href = `/${g.BOARD}/`;\r\n }\r\n break;\r\n case Conf['Open front page']:\r\n $.open(`${location.origin}/${g.BOARD}/`);\r\n break;\r\n case Conf['Next page']:\r\n if ((g.VIEW !== 'index') || !!g.SITE.isOnePage?.(g.BOARD)) { return; }\r\n if (Index.enabled) {\r\n if (!['paged', 'infinite'].includes(Conf['Index Mode'])) { return; }\r\n $('.next button', Index.pagelist).click();\r\n } else {\r\n $(g.SITE.selectors.nav.next)?.click();\r\n }\r\n break;\r\n case Conf['Previous page']:\r\n if ((g.VIEW !== 'index') || !!g.SITE.isOnePage?.(g.BOARD)) { return; }\r\n if (Index.enabled) {\r\n if (!['paged', 'infinite'].includes(Conf['Index Mode'])) { return; }\r\n $('.prev button', Index.pagelist).click();\r\n } else {\r\n $(g.SITE.selectors.nav.prev)?.click();\r\n }\r\n break;\r\n case Conf['Search form']:\r\n if (g.VIEW !== 'index') { return; }\r\n var searchInput = Index.enabled ?\r\n Index.searchInput\r\n : g.SITE.selectors.searchBox ?\r\n $(g.SITE.selectors.searchBox)\r\n :\r\n undefined;\r\n if (!searchInput) { return; }\r\n Header.scrollToIfNeeded(searchInput);\r\n searchInput.focus();\r\n break;\r\n case Conf['Paged mode']:\r\n if (!Index.enabledOn(g.BOARD)) { return; }\r\n location.href = g.VIEW === 'index' ? '#paged' : `/${g.BOARD}/#paged`;\r\n break;\r\n case Conf['Infinite scrolling mode']:\r\n if (!Index.enabledOn(g.BOARD)) { return; }\r\n location.href = g.VIEW === 'index' ? '#infinite' : `/${g.BOARD}/#infinite`;\r\n break;\r\n case Conf['All pages mode']:\r\n if (!Index.enabledOn(g.BOARD)) { return; }\r\n location.href = g.VIEW === 'index' ? '#all-pages' : `/${g.BOARD}/#all-pages`;\r\n break;\r\n case Conf['Open catalog']:\r\n if (!(catalog = CatalogLinks.catalog())) { return; }\r\n location.href = catalog;\r\n break;\r\n case Conf['Cycle sort type']:\r\n if (!Index.enabled) { return; }\r\n Index.cycleSortType();\r\n break;\r\n // Thread Navigation\r\n case Conf['Next thread']:\r\n if ((g.VIEW !== 'index') || !threadRoot) { return; }\r\n Nav.scroll(+1);\r\n break;\r\n case Conf['Previous thread']:\r\n if ((g.VIEW !== 'index') || !threadRoot) { return; }\r\n Nav.scroll(-1);\r\n break;\r\n case Conf['Expand thread']:\r\n if ((g.VIEW !== 'index') || !threadRoot) { return; }\r\n ExpandThread.toggle(thread);\r\n // Keep thread from moving off screen when contracted.\r\n Header.scrollTo(threadRoot);\r\n break;\r\n case Conf['Open thread']:\r\n if ((g.VIEW !== 'index') || !threadRoot) { return; }\r\n Keybinds.open(thread);\r\n break;\r\n case Conf['Open thread tab']:\r\n if ((g.VIEW !== 'index') || !threadRoot) { return; }\r\n Keybinds.open(thread, true);\r\n break;\r\n // Reply Navigation\r\n case Conf['Next reply']:\r\n if (!threadRoot) { return; }\r\n Keybinds.hl(+1, threadRoot);\r\n break;\r\n case Conf['Previous reply']:\r\n if (!threadRoot) { return; }\r\n Keybinds.hl(-1, threadRoot);\r\n break;\r\n case Conf['Deselect reply']:\r\n if (!threadRoot) { return; }\r\n Keybinds.hl(0, threadRoot);\r\n break;\r\n case Conf['Hide']:\r\n if (!thread || !ThreadHiding.db) { return; }\r\n Header.scrollTo(threadRoot);\r\n ThreadHiding.toggle(thread);\r\n break;\r\n case Conf['Quick Filter MD5']:\r\n if (!threadRoot) { return; }\r\n post = Keybinds.post(threadRoot);\r\n Keybinds.hl(+1, threadRoot);\r\n Filter.quickFilterMD5.call(post, e);\r\n break;\r\n case Conf['Previous Post Quoting You']:\r\n if (!threadRoot || !QuoteYou.db) { return; }\r\n QuoteYou.cb.seek('preceding');\r\n break;\r\n case Conf['Next Post Quoting You']:\r\n if (!threadRoot || !QuoteYou.db) { return; }\r\n QuoteYou.cb.seek('following');\r\n break;\r\n default:\r\n return;\r\n }\r\n e.preventDefault();\r\n return e.stopPropagation();\r\n },\r\n\r\n keyCode(e) {\r\n let key = (() => { let kc;\r\n switch ((kc = e.keyCode)) {\r\n case 8: // return\r\n return '';\r\n case 13:\r\n return 'Enter';\r\n case 27:\r\n return 'Esc';\r\n case 32:\r\n return 'Space';\r\n case 37:\r\n return 'Left';\r\n case 38:\r\n return 'Up';\r\n case 39:\r\n return 'Right';\r\n case 40:\r\n return 'Down';\r\n case 188:\r\n return 'Comma';\r\n case 190:\r\n return 'Period';\r\n case 191:\r\n return 'Slash';\r\n case 59: case 186:\r\n return 'Semicolon';\r\n default:\r\n if ((48 <= kc && kc <= 57) || (65 <= kc && kc <= 90)) { // 0-9, A-Z\r\n return String.fromCharCode(kc).toLowerCase();\r\n } else if (96 <= kc && kc <= 105) { // numpad 0-9\r\n return String.fromCharCode(kc - 48).toLowerCase();\r\n } else {\r\n return null;\r\n }\r\n } })();\r\n if (key) {\r\n if (e.altKey) { key = 'Alt+' + key; }\r\n if (e.ctrlKey) { key = 'Ctrl+' + key; }\r\n if (e.metaKey) { key = 'Meta+' + key; }\r\n if (e.shiftKey) { key = 'Shift+' + key; }\r\n }\r\n return key;\r\n },\r\n\r\n post(thread) {\r\n const s = g.SITE.selectors;\r\n return (\r\n $(`${s.postContainer}${s.highlightable.reply}.${g.SITE.classes.highlight}`, thread) ||\r\n $(`${g.SITE.isOPContainerThread ? s.thread : s.postContainer}${s.highlightable.op}`, thread)\r\n );\r\n },\r\n\r\n qr(thread) {\r\n QR.open();\r\n if (thread != null) {\r\n QR.quote.call(Keybinds.post(thread));\r\n }\r\n return QR.nodes.com.focus();\r\n },\r\n\r\n tags(tag, ta) {\r\n BoardConfig.ready(function() {\r\n const {config} = g.BOARD;\r\n const supported = (() => { switch (tag) {\r\n case 'spoiler': return !!config.spoilers;\r\n case 'code': return !!config.code_tags;\r\n case 'math': case 'eqn': return !!config.math_tags;\r\n case 'sjis': return !!config.sjis_tags;\r\n } })();\r\n if (!supported) { return new Notice('warning', `[${tag}] tags are not supported on /${g.BOARD}/.`, 20); }\r\n });\r\n\r\n const {\r\n value\r\n } = ta;\r\n const selStart = ta.selectionStart;\r\n const selEnd = ta.selectionEnd;\r\n\r\n ta.value =\r\n value.slice(0, selStart) +\r\n `[${tag}]` + value.slice(selStart, selEnd) + `[/${tag}]` +\r\n value.slice(selEnd);\r\n\r\n // Move the caret to the end of the selection.\r\n const range = (`[${tag}]`).length + selEnd;\r\n ta.setSelectionRange(range, range);\r\n\r\n // Fire the 'input' event\r\n return $.event('input', null, ta);\r\n },\r\n\r\n sage() {\r\n const isSage = /sage/i.test(QR.nodes.email.value);\r\n return QR.nodes.email.value = isSage ?\r\n \"\"\r\n : \"sage\";\r\n },\r\n\r\n open(thread, tab) {\r\n if (g.VIEW !== 'index') { return; }\r\n const url = Get.url('thread', thread);\r\n if (tab) {\r\n return $.open(url);\r\n } else {\r\n return location.href = url;\r\n }\r\n },\r\n\r\n hl(delta, thread) {\r\n const replySelector = `${g.SITE.selectors.postContainer}${g.SITE.selectors.highlightable.reply}`;\r\n const {highlight} = g.SITE.classes;\r\n\r\n const postEl = $(`${replySelector}.${highlight}`, thread);\r\n\r\n if (!delta) {\r\n if (postEl) { $.rmClass(postEl, highlight); }\r\n return;\r\n }\r\n\r\n if (postEl) {\r\n const {height} = postEl.getBoundingClientRect();\r\n if ((Header.getTopOf(postEl) >= -height) && (Header.getBottomOf(postEl) >= -height)) { // We're at least partially visible\r\n let next;\r\n const {root} = Get.postFromNode(postEl).nodes;\r\n const axis = delta === +1 ?\r\n 'following'\r\n :\r\n 'preceding';\r\n if (!(next = $.x(`${axis}-sibling::${g.SITE.xpath.replyContainer}[not(@hidden) and not(child::div[@class='stub'])][1]`, root))) { return; }\r\n if (!next.matches(replySelector)) { next = $(replySelector, next); }\r\n Header.scrollToIfNeeded(next, delta === +1);\r\n $.addClass(next, highlight);\r\n $.rmClass(postEl, highlight);\r\n return;\r\n }\r\n $.rmClass(postEl, highlight);\r\n }\r\n\r\n const replies = $$(replySelector, thread);\r\n if (delta === -1) { replies.reverse(); }\r\n for (var reply of replies) {\r\n if (((delta === +1) && (Header.getTopOf(reply) > 0)) || ((delta === -1) && (Header.getBottomOf(reply) > 0))) {\r\n $.addClass(reply, highlight);\r\n return;\r\n }\r\n }\r\n }\r\n};\r\nexport default Keybinds;\r\n","import $ from \"../platform/$\";\r\nimport CaptchaReplace from \"./Captcha.replace\";\r\nimport CaptchaT from \"./Captcha.t\";\r\nimport meta from '../../package.json';\r\nimport Main from \"../main/Main\";\r\nimport Keybinds from \"../Miscellaneous/Keybinds\";\r\nimport $$ from \"../platform/$$\";\r\nimport QR from \"./QR\";\r\nimport { Conf, d } from \"../globals/globals\";\r\nimport { MINUTE, SECOND } from \"../platform/helpers\";\r\n\r\nconst Captcha = {\r\n Cache: {\r\n init() {\r\n $.on(d, 'SaveCaptcha', e => {\r\n return this.saveAPI(e.detail);\r\n });\r\n return $.on(d, 'NoCaptcha', e => {\r\n return this.noCaptcha(e.detail);\r\n });\r\n },\r\n\r\n captchas: [],\r\n\r\n getCount() {\r\n return this.captchas.length;\r\n },\r\n\r\n neededRaw() {\r\n return !(\r\n this.haveCookie() || this.captchas.length || QR.req || this.submitCB\r\n ) && (\r\n (QR.posts.length > 1) || Conf['Auto-load captcha'] || !QR.posts[0].isOnlyQuotes() || QR.posts[0].file\r\n );\r\n },\r\n\r\n needed() {\r\n return this.neededRaw() && $.event('LoadCaptcha');\r\n },\r\n\r\n prerequest() {\r\n if (!Conf['Prerequest Captcha']) { return; }\r\n // Post count temporarily off by 1 when called from QR.post.rm, QR.close, or QR.submit\r\n return $.queueTask(() => {\r\n if (\r\n !this.prerequested &&\r\n this.neededRaw() &&\r\n !$.event('LoadCaptcha') &&\r\n !QR.captcha.occupied() &&\r\n (QR.cooldown.seconds <= 60) &&\r\n (QR.selected === QR.posts[QR.posts.length - 1]) &&\r\n !QR.selected.isOnlyQuotes()\r\n ) {\r\n const isReply = (QR.selected.thread !== 'new');\r\n if (!$.event('RequestCaptcha', { isReply })) {\r\n this.prerequested = true;\r\n this.submitCB = captcha => {\r\n if (captcha) { return this.save(captcha); }\r\n };\r\n return this.updateCount();\r\n }\r\n }\r\n });\r\n },\r\n\r\n haveCookie() {\r\n return /\\b_ct=/.test(d.cookie) && (QR.posts[0].thread !== 'new');\r\n },\r\n\r\n getOne() {\r\n let captcha;\r\n delete this.prerequested;\r\n this.clear();\r\n if (captcha = this.captchas.shift()) {\r\n this.count();\r\n return captcha;\r\n } else {\r\n return null;\r\n }\r\n },\r\n\r\n request(isReply) {\r\n if (!this.submitCB) {\r\n if ($.event('RequestCaptcha', { isReply })) { return; }\r\n }\r\n return cb => {\r\n this.submitCB = cb;\r\n return this.updateCount();\r\n };\r\n },\r\n\r\n abort() {\r\n if (this.submitCB) {\r\n delete this.submitCB;\r\n $.event('AbortCaptcha');\r\n return this.updateCount();\r\n }\r\n },\r\n\r\n saveAPI(captcha) {\r\n let cb;\r\n if (cb = this.submitCB) {\r\n delete this.submitCB;\r\n cb(captcha);\r\n return this.updateCount();\r\n } else {\r\n return this.save(captcha);\r\n }\r\n },\r\n\r\n noCaptcha(detail) {\r\n let cb;\r\n if (cb = this.submitCB) {\r\n if (!this.haveCookie() || detail?.error) {\r\n QR.error(detail?.error || 'Failed to retrieve captcha.');\r\n QR.captcha.setup(d.activeElement === QR.nodes.status);\r\n }\r\n delete this.submitCB;\r\n cb();\r\n return this.updateCount();\r\n }\r\n },\r\n\r\n save(captcha) {\r\n let cb;\r\n if (cb = this.submitCB) {\r\n this.abort();\r\n cb(captcha);\r\n return;\r\n }\r\n this.captchas.push(captcha);\r\n this.captchas.sort((a, b) => a.timeout - b.timeout);\r\n return this.count();\r\n },\r\n\r\n clear() {\r\n if (this.captchas.length) {\r\n let i;\r\n const now = Date.now();\r\n for (i = 0; i < this.captchas.length; i++) {\r\n var captcha = this.captchas[i];\r\n if (captcha.timeout > now) { break; }\r\n }\r\n if (i) {\r\n this.captchas = this.captchas.slice(i);\r\n return this.count();\r\n }\r\n }\r\n },\r\n\r\n count() {\r\n clearTimeout(this.timer);\r\n if (this.captchas.length) {\r\n this.timer = setTimeout(this.clear.bind(this), this.captchas[0].timeout - Date.now());\r\n }\r\n return this.updateCount();\r\n },\r\n\r\n updateCount() {\r\n return $.event('CaptchaCount', this.captchas.length);\r\n }\r\n }, Replace: CaptchaReplace, t: CaptchaT, v2: {\r\n lifetime: 2 * MINUTE,\r\n\r\n init() {\r\n if (d.cookie.indexOf('pass_enabled=1') >= 0) { return; }\r\n if (!(this.isEnabled = !!$('#g-recaptcha, #captcha-forced-noscript') || !$.id('postForm'))) { return; }\r\n\r\n if (this.noscript = Conf['Force Noscript Captcha'] || !Main.jsEnabled) {\r\n $.addClass(QR.nodes.el, 'noscript-captcha');\r\n }\r\n\r\n Captcha.cache.init();\r\n $.on(d, 'CaptchaCount', this.count.bind(this));\r\n\r\n const root = $.el('div', { className: 'captcha-root' });\r\n $.extend(root, {\r\n innerHTML:\r\n '
            '\r\n }\r\n );\r\n const counter = $('.captcha-counter > a', root);\r\n this.nodes = { root, counter };\r\n this.count();\r\n $.addClass(QR.nodes.el, 'has-captcha', 'captcha-v2');\r\n $.after(QR.nodes.com.parentNode, root);\r\n\r\n $.on(counter, 'click', this.toggle.bind(this));\r\n $.on(counter, 'keydown', e => {\r\n if (Keybinds.keyCode(e) !== 'Space') { return; }\r\n this.toggle();\r\n e.preventDefault();\r\n return e.stopPropagation();\r\n });\r\n return $.on(window, 'captcha:success', () => {\r\n // XXX Greasemonkey 1.x workaround to gain access to GM_* functions.\r\n return $.queueTask(() => this.save(false));\r\n });\r\n },\r\n\r\n timeouts: {},\r\n prevNeeded: 0,\r\n\r\n noscriptURL() {\r\n let lang;\r\n let url = `https://www.google.com/recaptcha/api/fallback?k=${meta.recaptchaKey}`;\r\n if (lang = Conf['captchaLanguage'].trim()) {\r\n url += `&hl=${encodeURIComponent(lang)}`;\r\n }\r\n return url;\r\n },\r\n\r\n moreNeeded() {\r\n // Post count temporarily off by 1 when called from QR.post.rm, QR.close, or QR.submit\r\n return $.queueTask(() => {\r\n const needed = Captcha.cache.needed();\r\n if (needed && !this.prevNeeded) {\r\n this.setup(QR.cooldown.auto && (d.activeElement === QR.nodes.status));\r\n }\r\n return this.prevNeeded = needed;\r\n });\r\n },\r\n\r\n toggle() {\r\n if (this.nodes.container && !this.timeouts.destroy) {\r\n return this.destroy();\r\n } else {\r\n return this.setup(true, true);\r\n }\r\n },\r\n\r\n setup(focus, force) {\r\n if (!this.isEnabled || (!Captcha.cache.needed() && !force)) { return; }\r\n\r\n if (focus) {\r\n $.addClass(QR.nodes.el, 'focus');\r\n this.nodes.counter.focus();\r\n }\r\n\r\n if (this.timeouts.destroy) {\r\n clearTimeout(this.timeouts.destroy);\r\n delete this.timeouts.destroy;\r\n return this.reload();\r\n }\r\n\r\n if (this.nodes.container) {\r\n // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=1226835\r\n $.queueTask(() => {\r\n let iframe;\r\n if (this.nodes.container && (d.activeElement === this.nodes.counter) && (iframe = $('iframe[src^=\"https://www.google.com/recaptcha/\"]', this.nodes.container))) {\r\n iframe.focus();\r\n return QR.focus();\r\n }\r\n }); // Event handler not fired in Firefox\r\n return;\r\n }\r\n\r\n this.nodes.container = $.el('div', { className: 'captcha-container' });\r\n $.prepend(this.nodes.root, this.nodes.container);\r\n new MutationObserver(this.afterSetup.bind(this)).observe(this.nodes.container, {\r\n childList: true,\r\n subtree: true\r\n }\r\n );\r\n\r\n if (this.noscript) {\r\n return this.setupNoscript();\r\n } else {\r\n return this.setupJS();\r\n }\r\n },\r\n\r\n setupNoscript() {\r\n const iframe = $.el('iframe', {\r\n id: 'qr-captcha-iframe',\r\n scrolling: 'no',\r\n src: this.noscriptURL()\r\n }\r\n );\r\n const div = $.el('div');\r\n const textarea = $.el('textarea');\r\n $.add(div, textarea);\r\n return $.add(this.nodes.container, [iframe, div]);\r\n },\r\n\r\n setupJS() {\r\n return $.global(function () {\r\n const render = function () {\r\n const { classList } = document.documentElement;\r\n const container = document.querySelector('#qr .captcha-container');\r\n return container.dataset.widgetID = window.grecaptcha.render(container, {\r\n sitekey: meta.recaptchaKey,\r\n theme: classList.contains('tomorrow') || classList.contains('spooky') || classList.contains('dark-captcha') ? 'dark' : 'light',\r\n callback(response) {\r\n return window.dispatchEvent(new CustomEvent('captcha:success', { detail: response }));\r\n }\r\n }\r\n );\r\n };\r\n if (window.grecaptcha) {\r\n return render();\r\n } else {\r\n const cbNative = window.onRecaptchaLoaded;\r\n window.onRecaptchaLoaded = function () {\r\n render();\r\n return cbNative();\r\n };\r\n if (!document.head.querySelector('script[src^=\"https://www.google.com/recaptcha/api.js\"]')) {\r\n const script = document.createElement('script');\r\n script.src = 'https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoaded&render=explicit';\r\n return document.head.appendChild(script);\r\n }\r\n }\r\n });\r\n },\r\n\r\n afterSetup(mutations) {\r\n for (var mutation of mutations) {\r\n for (var node of mutation.addedNodes) {\r\n var iframe, textarea;\r\n if (iframe = $.x('./descendant-or-self::iframe[starts-with(@src, \"https://www.google.com/recaptcha/\")]', node)) { this.setupIFrame(iframe); }\r\n if (textarea = $.x('./descendant-or-self::textarea', node)) { this.setupTextArea(textarea); }\r\n }\r\n }\r\n },\r\n\r\n setupIFrame(iframe) {\r\n let needle;\r\n if (!doc.contains(iframe)) { return; }\r\n Captcha.replace.iframe(iframe);\r\n $.addClass(QR.nodes.el, 'captcha-open');\r\n this.fixQRPosition();\r\n $.on(iframe, 'load', this.fixQRPosition);\r\n if (d.activeElement === this.nodes.counter) { iframe.focus(); }\r\n // XXX Make sure scroll on space prevention (see src/css/style.css) doesn't cause scrolling of div\r\n if (['blink', 'edge'].includes($.engine) && (needle = iframe.parentNode, $$('#qr .captcha-container > div > div:first-of-type').includes(needle))) {\r\n return $.on(iframe.parentNode, 'scroll', function () { return this.scrollTop = 0; });\r\n }\r\n },\r\n\r\n fixQRPosition() {\r\n if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) {\r\n QR.nodes.el.style.top = '';\r\n return QR.nodes.el.style.bottom = '0px';\r\n }\r\n },\r\n\r\n setupTextArea(textarea) {\r\n return $.one(textarea, 'input', () => this.save(true));\r\n },\r\n\r\n destroy() {\r\n if (!this.isEnabled) { return; }\r\n delete this.timeouts.destroy;\r\n $.rmClass(QR.nodes.el, 'captcha-open');\r\n if (this.nodes.container) {\r\n $.global(function () {\r\n const container = document.querySelector('#qr .captcha-container');\r\n return window.grecaptcha.reset(container.dataset.widgetID);\r\n });\r\n $.rm(this.nodes.container);\r\n return delete this.nodes.container;\r\n }\r\n },\r\n\r\n getOne(isReply) {\r\n return Captcha.cache.getOne(isReply);\r\n },\r\n\r\n save(pasted, token) {\r\n Captcha.cache.save({\r\n response: token || $('textarea', this.nodes.container).value,\r\n timeout: Date.now() + this.lifetime\r\n });\r\n\r\n const focus = (d.activeElement?.nodeName === 'IFRAME') && /https?:\\/\\/www\\.google\\.com\\/recaptcha\\//.test(d.activeElement.src);\r\n if (Captcha.cache.needed()) {\r\n if (focus) {\r\n if (QR.cooldown.auto || Conf['Post on Captcha Completion']) {\r\n this.nodes.counter.focus();\r\n } else {\r\n QR.nodes.status.focus();\r\n }\r\n }\r\n this.reload();\r\n } else {\r\n if (pasted) {\r\n this.destroy();\r\n } else {\r\n if (this.timeouts.destroy == null) { this.timeouts.destroy = setTimeout(this.destroy.bind(this), 3 * SECOND); }\r\n }\r\n if (focus) { QR.nodes.status.focus(); }\r\n }\r\n\r\n if (Conf['Post on Captcha Completion'] && !QR.cooldown.auto) { return QR.submit(); }\r\n },\r\n\r\n count() {\r\n const count = Captcha.cache.getCount();\r\n const loading = Captcha.cache.submitCB ? '...' : '';\r\n this.nodes.counter.textContent = `Captchas: ${count}${loading}`;\r\n return this.moreNeeded();\r\n },\r\n\r\n reload() {\r\n if ($('iframe[src^=\"https://www.google.com/recaptcha/api/fallback?\"]', this.nodes.container)) {\r\n this.destroy();\r\n return this.setup(false, true);\r\n } else {\r\n return $.global(function () {\r\n const container = document.querySelector('#qr .captcha-container');\r\n return window.grecaptcha.reset(container.dataset.widgetID);\r\n });\r\n }\r\n },\r\n\r\n occupied() {\r\n return !!this.nodes.container && !this.timeouts.destroy;\r\n }\r\n }\r\n};\r\nexport default Captcha;\r\n","import QuickReplyPage from './QR/QuickReply.html';\r\nimport $ from '../platform/$';\r\nimport Callbacks from '../classes/Callbacks';\r\nimport Notice from '../classes/Notice';\r\nimport Main from '../main/Main';\r\nimport Favicon from '../Monitoring/Favicon';\r\nimport $$ from '../platform/$$';\r\nimport CrossOrigin from '../platform/CrossOrigin';\r\nimport Captcha from './Captcha';\r\nimport meta from '../../package.json';\r\nimport Header from '../General/Header';\r\nimport { Conf, E, d, doc, g } from '../globals/globals';\r\nimport Menu from '../Menu/Menu';\r\nimport UI from '../General/UI';\r\nimport BoardConfig from '../General/BoardConfig';\r\nimport Get from '../General/Get';\r\nimport { DAY, dict, SECOND } from '../platform/helpers';\r\n\r\n/*\r\n * decaffeinate suggestions:\r\n * DS101: Remove unnecessary use of Array.from\r\n * DS102: Remove unnecessary code created because of implicit returns\r\n * DS202: Simplify dynamic range loops\r\n * DS207: Consider shorter variations of null checks\r\n * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md\r\n */\r\n\r\nvar QR = {\r\n mimeTypes: ['image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'application/vnd.adobe.flash.movie', 'application/x-shockwave-flash', 'video/webm'],\r\n\r\n validExtension: /\\.(jpe?g|png|gif|pdf|swf|webm)$/i,\r\n\r\n typeFromExtension: {\r\n 'jpg': 'image/jpeg',\r\n 'jpeg': 'image/jpeg',\r\n 'png': 'image/png',\r\n 'gif': 'image/gif',\r\n 'pdf': 'application/pdf',\r\n 'swf': 'application/vnd.adobe.flash.movie',\r\n 'webm': 'video/webm'\r\n },\r\n\r\n extensionFromType: {\r\n 'image/jpeg': 'jpg',\r\n 'image/png': 'png',\r\n 'image/gif': 'gif',\r\n 'application/pdf': 'pdf',\r\n 'application/vnd.adobe.flash.movie': 'swf',\r\n 'application/x-shockwave-flash': 'swf',\r\n 'video/webm': 'webm'\r\n },\r\n\r\n init() {\r\n let sc;\r\n if (!Conf['Quick Reply']) { return; }\r\n\r\n this.posts = [];\r\n\r\n $.on(d, '4chanXInitFinished', () => BoardConfig.ready(QR.initReady));\r\n\r\n Callbacks.Post.push({\r\n name: 'Quick Reply',\r\n cb: this.node\r\n });\r\n\r\n this.shortcut = (sc = $.el('a', {\r\n className: 'disabled',\r\n textContent: '↩',\r\n title: 'Quick Reply',\r\n href: 'javascript:;'\r\n }\r\n ));\r\n $.on(sc, 'click', function() {\r\n if (!QR.postingIsEnabled) { return; }\r\n if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) {\r\n QR.open();\r\n return QR.nodes.com.focus();\r\n } else {\r\n return QR.close();\r\n }\r\n });\r\n\r\n return Header.addShortcut('qr', sc, 540);\r\n },\r\n\r\n initReady() {\r\n let origToggle;\r\n const captchaVersion = $('#g-recaptcha, #captcha-forced-noscript') ? 'v2' : 't';\r\n QR.captcha = Captcha[captchaVersion];\r\n QR.postingIsEnabled = true;\r\n\r\n const {config} = g.BOARD;\r\n const prop = (key, def) => +(config[key] ?? def);\r\n\r\n QR.min_width = prop('min_image_width', 1);\r\n QR.min_height = prop('min_image_height', 1);\r\n QR.max_width = (QR.max_height = 10000);\r\n\r\n QR.max_size = prop('max_filesize', 4194304);\r\n QR.max_size_video = prop('max_webm_filesize', QR.max_size);\r\n QR.max_comment = prop('max_comment_chars', 2000);\r\n\r\n QR.max_width_video = (QR.max_height_video = 2048);\r\n QR.max_duration_video = prop('max_webm_duration', 120);\r\n\r\n QR.forcedAnon = !!config.forced_anon;\r\n QR.spoiler = !!config.spoilers;\r\n\r\n if (origToggle = $.id('togglePostFormLink')) {\r\n const link = $.el('h1',\r\n {className: \"qr-link-container\"});\r\n $.extend(link, {\r\n innerHTML:\r\n `${g.VIEW === \"thread\" ? \"Reply to Thread\" : \"Start a Thread\"}`\r\n });\r\n\r\n QR.link = link.firstElementChild;\r\n $.on(link.firstChild, 'click', function() {\r\n QR.open();\r\n return QR.nodes.com.focus();\r\n });\r\n\r\n $.before(origToggle, link);\r\n origToggle.firstElementChild.textContent = 'Original Form';\r\n }\r\n\r\n if (g.VIEW === 'thread') {\r\n let navLinksBot;\r\n const linkBot = $.el('div',\r\n {className: \"brackets-wrap qr-link-container-bottom\"});\r\n $.extend(linkBot, {innerHTML: 'Reply to Thread'});\r\n\r\n $.on(linkBot.firstElementChild, 'click', function() {\r\n QR.open();\r\n return QR.nodes.com.focus();\r\n });\r\n\r\n if (navLinksBot = $('.navLinksBot')) { $.prepend(navLinksBot, linkBot); }\r\n }\r\n\r\n $.on(d, 'QRGetFile', QR.getFile);\r\n $.on(d, 'QRDrawFile', QR.drawFile);\r\n $.on(d, 'QRSetFile', QR.setFile);\r\n\r\n $.on(d, 'paste', QR.paste);\r\n $.on(d, 'dragover', QR.dragOver);\r\n $.on(d, 'drop', QR.dropFile);\r\n $.on(d, 'dragstart dragend', QR.drag);\r\n\r\n $.on(d, 'IndexRefreshInternal', QR.generatePostableThreadsList);\r\n $.on(d, 'ThreadUpdate', QR.statusCheck);\r\n\r\n if (!Conf['Persistent QR']) { return; }\r\n QR.open();\r\n if (Conf['Auto Hide QR']) { return QR.hide(); }\r\n },\r\n\r\n statusCheck() {\r\n if (!QR.nodes) { return; }\r\n const {thread} = QR.posts[0];\r\n if ((thread !== 'new') && g.threads.get(`${g.BOARD}.${thread}`).isDead) {\r\n return QR.abort();\r\n } else {\r\n return QR.status();\r\n }\r\n },\r\n\r\n node() {\r\n $.on(this.nodes.quote, 'click', QR.quote);\r\n if (this.isFetchedQuote) { return QR.generatePostableThreadsList(); }\r\n },\r\n\r\n open() {\r\n if (QR.nodes) {\r\n if (QR.nodes.el.hidden) { QR.captcha.setup(); }\r\n QR.nodes.el.hidden = false;\r\n QR.unhide();\r\n } else {\r\n try {\r\n QR.dialog();\r\n } catch (err) {\r\n delete QR.nodes;\r\n Main.handleErrors({\r\n message: 'Quick Reply dialog creation crashed.',\r\n error: err\r\n });\r\n return;\r\n }\r\n }\r\n return $.rmClass(QR.shortcut, 'disabled');\r\n },\r\n\r\n close() {\r\n if (QR.req) {\r\n QR.abort();\r\n return;\r\n }\r\n QR.nodes.el.hidden = true;\r\n QR.cleanNotifications();\r\n QR.blur();\r\n $.rmClass(QR.nodes.el, 'dump');\r\n $.addClass(QR.shortcut, 'disabled');\r\n new QR.post(true);\r\n for (var post of QR.posts.splice(0, QR.posts.length - 1)) {\r\n post.delete();\r\n }\r\n QR.cooldown.auto = false;\r\n QR.status();\r\n return QR.captcha.destroy();\r\n },\r\n\r\n focus() {\r\n return $.queueTask(function() {\r\n if (!QR.inBubble()) {\r\n QR.hasFocus = d.activeElement && QR.nodes.el.contains(d.activeElement);\r\n return QR.nodes.el.classList.toggle('focus', QR.hasFocus);\r\n }\r\n });\r\n },\r\n\r\n inBubble() {\r\n const bubbles = $$('iframe[src^=\"https://www.google.com/recaptcha/api2/frame\"]');\r\n return bubbles.includes(d.activeElement) || bubbles.some(el => (getComputedStyle(el).visibility !== 'hidden') && (el.getBoundingClientRect().bottom > 0));\r\n },\r\n\r\n hide() {\r\n QR.blur();\r\n $.addClass(QR.nodes.el, 'autohide');\r\n return QR.nodes.autohide.checked = true;\r\n },\r\n\r\n unhide() {\r\n $.rmClass(QR.nodes.el, 'autohide');\r\n return QR.nodes.autohide.checked = false;\r\n },\r\n\r\n toggleHide() {\r\n if (this.checked) {\r\n return QR.hide();\r\n } else {\r\n return QR.unhide();\r\n }\r\n },\r\n\r\n blur() {\r\n if (QR.nodes.el.contains(d.activeElement)) { return d.activeElement.blur(); }\r\n },\r\n\r\n toggleSJIS(e) {\r\n e.preventDefault();\r\n Conf['sjisPreview'] = !Conf['sjisPreview'];\r\n $.set('sjisPreview', Conf['sjisPreview']);\r\n return QR.nodes.el.classList.toggle('sjis-preview', Conf['sjisPreview']);\r\n },\r\n\r\n texPreviewShow() {\r\n if ($.hasClass(QR.nodes.el, 'tex-preview')) { return QR.texPreviewHide(); }\r\n $.addClass(QR.nodes.el, 'tex-preview');\r\n QR.nodes.texPreview.textContent = QR.nodes.com.value;\r\n return $.event('mathjax', null, QR.nodes.texPreview);\r\n },\r\n\r\n texPreviewHide() {\r\n return $.rmClass(QR.nodes.el, 'tex-preview');\r\n },\r\n\r\n addPost() {\r\n const wasOpen = (QR.nodes && !QR.nodes.el.hidden);\r\n QR.open();\r\n if (wasOpen) {\r\n $.addClass(QR.nodes.el, 'dump');\r\n new QR.post(true);\r\n }\r\n return QR.nodes.com.focus();\r\n },\r\n\r\n setCustomCooldown(enabled) {\r\n Conf['customCooldownEnabled'] = enabled;\r\n QR.cooldown.customCooldown = enabled;\r\n return QR.nodes.customCooldown.classList.toggle('disabled', !enabled);\r\n },\r\n\r\n toggleCustomCooldown() {\r\n const enabled = $.hasClass(QR.nodes.customCooldown, 'disabled');\r\n QR.setCustomCooldown(enabled);\r\n return $.set('customCooldownEnabled', enabled);\r\n },\r\n\r\n error(err, focusOverride) {\r\n let el;\r\n QR.open();\r\n if (typeof err === 'string') {\r\n el = $.tn(err);\r\n } else {\r\n el = err;\r\n el.removeAttribute('style');\r\n }\r\n const notice = new Notice('warning', el);\r\n QR.notifications.push(notice);\r\n if (!Header.areNotificationsEnabled) {\r\n if (d.hidden && !QR.cooldown.auto) { return alert(el.textContent); }\r\n } else if (d.hidden || !(focusOverride || d.hasFocus())) {\r\n const notif = new Notification(el.textContent, {\r\n body: el.textContent,\r\n icon: Favicon.logo\r\n }\r\n );\r\n notif.onclick = () => window.focus();\r\n if ($.engine !== 'gecko') {\r\n // Firefox automatically closes notifications\r\n // so we can't control the onclose properly.\r\n notif.onclose = () => notice.close();\r\n return notif.onshow = () => setTimeout(function() {\r\n notif.onclose = null;\r\n return notif.close();\r\n }\r\n , 7 * SECOND);\r\n }\r\n }\r\n },\r\n\r\n connectionError() {\r\n return $.el('span',\r\n { innerHTML:\r\n 'Connection error while posting. ' +\r\n '[More info]'\r\n }\r\n );\r\n },\r\n\r\n notifications: [],\r\n\r\n cleanNotifications() {\r\n for (var notification of QR.notifications) {\r\n notification.close();\r\n }\r\n return QR.notifications = [];\r\n },\r\n\r\n status() {\r\n let disabled, value;\r\n if (!QR.nodes) { return; }\r\n const {thread} = QR.posts[0];\r\n if ((thread !== 'new') && g.threads.get(`${g.BOARD}.${thread}`).isDead) {\r\n value = 'Dead';\r\n disabled = true;\r\n QR.cooldown.auto = false;\r\n }\r\n\r\n value = QR.req ?\r\n QR.req.progress\r\n :\r\n QR.cooldown.seconds || value;\r\n\r\n const {status} = QR.nodes;\r\n status.value = !value ?\r\n 'Submit'\r\n : QR.cooldown.auto ?\r\n `Auto ${value}`\r\n :\r\n value;\r\n return status.disabled = disabled || false;\r\n },\r\n\r\n openPost() {\r\n QR.open();\r\n if (QR.selected.isLocked) {\r\n const index = QR.posts.indexOf(QR.selected);\r\n (QR.posts[index+1] || new QR.post()).select();\r\n $.addClass(QR.nodes.el, 'dump');\r\n return QR.cooldown.auto = true;\r\n }\r\n },\r\n\r\n quote(e) {\r\n let range;\r\n e?.preventDefault();\r\n if (!QR.postingIsEnabled) { return; }\r\n const sel = d.getSelection();\r\n const post = Get.postFromNode(this);\r\n const {root} = post.nodes;\r\n const postRange = new Range();\r\n postRange.selectNode(root);\r\n let text = post.board.ID === g.BOARD.ID ? `>>${post}\\n` : `>>>/${post.board}/${post}\\n`;\r\n for (let i = 0, end = sel.rangeCount, asc = 0 <= end; asc ? i < end : i > end; asc ? i++ : i--) {\r\n try {\r\n var insideCode, node;\r\n range = sel.getRangeAt(i);\r\n // Trim range to be fully inside post\r\n if (range.compareBoundaryPoints(Range.START_TO_START, postRange) < 0) {\r\n range.setStartBefore(root);\r\n }\r\n if (range.compareBoundaryPoints(Range.END_TO_END, postRange) > 0) {\r\n range.setEndAfter(root);\r\n }\r\n\r\n if (!range.toString().trim()) { continue; }\r\n\r\n var frag = range.cloneContents();\r\n var ancestor = range.commonAncestorContainer;\r\n // Quoting the insides of a spoiler/code tag.\r\n if ($.x('ancestor-or-self::*[self::s or contains(@class,\"removed-spoiler\")]', ancestor)) {\r\n $.prepend(frag, $.tn('[spoiler]'));\r\n $.add(frag, $.tn('[/spoiler]'));\r\n }\r\n if (insideCode = $.x('ancestor-or-self::pre[contains(@class,\"prettyprint\")]', ancestor)) {\r\n $.prepend(frag, $.tn('[code]'));\r\n $.add(frag, $.tn('[/code]'));\r\n }\r\n for (node of $$((insideCode ? 'br' : '.prettyprint br'), frag)) {\r\n $.replace(node, $.tn('\\n'));\r\n }\r\n for (node of $$('br', frag)) {\r\n if (node !== frag.lastChild) { $.replace(node, $.tn('\\n>')); }\r\n }\r\n g.SITE.insertTags?.(frag);\r\n for (node of $$('.linkify[data-original]', frag)) {\r\n $.replace(node, $.tn(node.dataset.original));\r\n }\r\n for (node of $$('.embedder', frag)) {\r\n if (node.previousSibling?.nodeValue === ' ') { $.rm(node.previousSibling); }\r\n $.rm(node);\r\n }\r\n text += `>${frag.textContent.trim()}\\n`;\r\n } catch (error) { }\r\n }\r\n\r\n QR.openPost();\r\n const {com, thread} = QR.nodes;\r\n if (!com.value) { thread.value = Get.threadFromNode(this); }\r\n\r\n const wasOnlyQuotes = QR.selected.isOnlyQuotes();\r\n\r\n const caretPos = com.selectionStart;\r\n // Replace selection for text.\r\n com.value = com.value.slice(0, caretPos) + text + com.value.slice(com.selectionEnd);\r\n // Move the caret to the end of the new quote.\r\n range = caretPos + text.length;\r\n com.setSelectionRange(range, range);\r\n com.focus();\r\n\r\n // This allows us to determine if any text other than quotes has been typed.\r\n if (wasOnlyQuotes) { QR.selected.quotedText = com.value; }\r\n\r\n QR.selected.save(com);\r\n return QR.selected.save(thread);\r\n },\r\n\r\n characterCount() {\r\n const counter = QR.nodes.charCount;\r\n const count = QR.nodes.com.value.replace(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g, '_').length;\r\n counter.textContent = count;\r\n counter.hidden = count < (QR.max_comment/2);\r\n return (count > QR.max_comment ? $.addClass : $.rmClass)(counter, 'warning');\r\n },\r\n\r\n getFile() {\r\n return $.event('QRFile', QR.selected?.file);\r\n },\r\n\r\n drawFile(e) {\r\n const file = QR.selected?.file;\r\n if (!file || !/^(image|video)\\//.test(file.type)) { return; }\r\n const isVideo = /^video\\//.test(file);\r\n const el = $.el((isVideo ? 'video' : 'img'));\r\n $.on(el, 'error', () => QR.openError());\r\n $.on(el, (isVideo ? 'loadeddata' : 'load'), function() {\r\n e.target.getContext('2d').drawImage(el, 0, 0);\r\n URL.revokeObjectURL(el.src);\r\n return $.event('QRImageDrawn', null, e.target);\r\n });\r\n return el.src = URL.createObjectURL(file);\r\n },\r\n\r\n openError() {\r\n const div = $.el('div');\r\n $.extend(div, {\r\n innerHTML:\r\n 'Could not open file. [More info]'\r\n });\r\n return QR.error(div);\r\n },\r\n\r\n setFile(e) {\r\n const {file, name, source} = e.detail;\r\n if (name != null) { file.name = name; }\r\n if (source != null) { file.source = source; }\r\n QR.open();\r\n return QR.handleFiles([file]);\r\n },\r\n\r\n drag(e) {\r\n // Let it drag anything from the page.\r\n const toggle = e.type === 'dragstart' ? $.off : $.on;\r\n toggle(d, 'dragover', QR.dragOver);\r\n return toggle(d, 'drop', QR.dropFile);\r\n },\r\n\r\n dragOver(e) {\r\n e.preventDefault();\r\n return e.dataTransfer.dropEffect = 'copy';\r\n }, // cursor feedback\r\n\r\n dropFile(e) {\r\n // Let it only handle files from the desktop.\r\n if (!e.dataTransfer.files.length) { return; }\r\n e.preventDefault();\r\n QR.open();\r\n return QR.handleFiles(e.dataTransfer.files);\r\n },\r\n\r\n paste(e) {\r\n if (!e.clipboardData.items) { return; }\r\n let file = null;\r\n let score = -1;\r\n for (var item of e.clipboardData.items) {\r\n var file2;\r\n if ((item.kind === 'file') && (file2 = item.getAsFile())) {\r\n var score2 = (2*(file2.size <= QR.max_size)) + (file2.type === 'image/png');\r\n if (score2 > score) {\r\n file = file2;\r\n score = score2;\r\n }\r\n }\r\n }\r\n if (file) {\r\n const {type} = file;\r\n const blob = new Blob([file], {type});\r\n blob.name = `${Conf['pastedname']}.${$.getOwn(QR.extensionFromType, type) || 'jpg'}`;\r\n QR.open();\r\n QR.handleFiles([blob]);\r\n $.addClass(QR.nodes.el, 'dump');\r\n }\r\n },\r\n\r\n pasteFF() {\r\n const {pasteArea} = QR.nodes;\r\n if (!pasteArea.childNodes.length) { return; }\r\n const images = $$('img', pasteArea);\r\n $.rmAll(pasteArea);\r\n for (var img of images) {\r\n var m;\r\n var {src} = img;\r\n if (m = src.match(/data:(image\\/(\\w+));base64,(.+)/)) {\r\n var bstr = atob(m[3]);\r\n var arr = new Uint8Array(bstr.length);\r\n for (var i = 0, end = bstr.length, asc = 0 <= end; asc ? i < end : i > end; asc ? i++ : i--) {\r\n arr[i] = bstr.charCodeAt(i);\r\n }\r\n var blob = new Blob([arr], {type: m[1]});\r\n blob.name = `${Conf['pastedname']}.${m[2]}`;\r\n QR.handleFiles([blob]);\r\n } else if (/^https?:\\/\\//.test(src)) {\r\n QR.handleUrl(src);\r\n }\r\n }\r\n },\r\n\r\n handleUrl(urlDefault) {\r\n QR.open();\r\n QR.selected.preventAutoPost();\r\n return CrossOrigin.permission(function() {\r\n const url = prompt('Enter a URL:', urlDefault);\r\n if (url === null) { return; }\r\n QR.nodes.fileButton.focus();\r\n return CrossOrigin.file(url, function(blob) {\r\n if (blob && !/^text\\//.test(blob.type)) {\r\n return QR.handleFiles([blob]);\r\n } else {\r\n return QR.error(\"Can't load file.\");\r\n }\r\n });\r\n });\r\n },\r\n\r\n handleFiles(files) {\r\n if (this !== QR) { // file input\r\n files = [...Array.from(this.files)];\r\n this.value = null;\r\n }\r\n if (!files.length) { return; }\r\n QR.cleanNotifications();\r\n for (var file of files) {\r\n QR.handleFile(file, files.length);\r\n }\r\n if (files.length !== 1) { $.addClass(QR.nodes.el, 'dump'); }\r\n if ((d.activeElement === QR.nodes.fileButton) && $.hasClass(QR.nodes.fileSubmit, 'has-file')) {\r\n return QR.nodes.filename.focus();\r\n }\r\n },\r\n\r\n handleFile(file, nfiles) {\r\n let post;\r\n const isText = /^text\\//.test(file.type);\r\n if (nfiles === 1) {\r\n post = QR.selected;\r\n } else {\r\n post = QR.posts[QR.posts.length - 1];\r\n if (isText ? post.com || post.pasting : post.file) {\r\n post = new QR.post();\r\n }\r\n }\r\n return post[isText ? 'pasteText' : 'setFile'](file);\r\n },\r\n\r\n openFileInput() {\r\n if (QR.nodes.fileButton.disabled) { return; }\r\n QR.nodes.fileInput.click();\r\n return QR.nodes.fileButton.focus();\r\n },\r\n\r\n generatePostableThreadsList() {\r\n if (!QR.nodes) { return; }\r\n const list = QR.nodes.thread;\r\n const options = [list.firstElementChild];\r\n for (var thread of g.BOARD.threads.keys) {\r\n options.push($.el('option', {\r\n value: thread,\r\n textContent: `Thread ${thread}`\r\n }\r\n )\r\n );\r\n }\r\n const val = list.value;\r\n $.rmAll(list);\r\n $.add(list, options);\r\n list.value = val;\r\n if (list.value === val) { return; }\r\n // Fix the value if the option disappeared.\r\n list.value = g.VIEW === 'thread' ?\r\n g.THREADID\r\n :\r\n 'new';\r\n return (g.VIEW === 'thread' ? $.addClass : $.rmClass)(QR.nodes.el, 'reply-to-thread');\r\n },\r\n\r\n dialog() {\r\n let dialog, event, nodes;\r\n let name;\r\n QR.nodes = (nodes = {\r\n el: (dialog = UI.dialog('qr',\r\n { innerHTML: QuickReplyPage }))\r\n });\r\n\r\n const setNode = (name, query) => nodes[name] = $(query, dialog);\r\n\r\n setNode('move', '.move');\r\n setNode('autohide', '#autohide');\r\n setNode('close', '.close');\r\n setNode('thread', 'select');\r\n setNode('form', 'form');\r\n setNode('sjisToggle', '#sjis-toggle');\r\n setNode('texButton', '#tex-preview-button');\r\n setNode('name', '[data-name=name]');\r\n setNode('email', '[data-name=email]');\r\n setNode('sub', '[data-name=sub]');\r\n setNode('com', '[data-name=com]');\r\n setNode('charCount', '#char-count');\r\n setNode('texPreview', '#tex-preview');\r\n setNode('dumpList', '#dump-list');\r\n setNode('addPost', '#add-post');\r\n setNode('oekaki', '.oekaki');\r\n setNode('drawButton', '#qr-draw-button');\r\n setNode('fileSubmit', '#file-n-submit');\r\n setNode('fileButton', '#qr-file-button');\r\n setNode('noFile', '#qr-no-file');\r\n setNode('filename', '#qr-filename');\r\n setNode('spoiler', '#qr-file-spoiler');\r\n setNode('oekakiButton', '#qr-oekaki-button');\r\n setNode('fileRM', '#qr-filerm');\r\n setNode('urlButton', '#url-button');\r\n setNode('pasteArea', '#paste-area');\r\n setNode('customCooldown', '#custom-cooldown-button');\r\n setNode('dumpButton', '#dump-button');\r\n setNode('status', '[type=submit]');\r\n setNode('flashTag', '[name=filetag]');\r\n setNode('fileInput', '[type=file]');\r\n\r\n const {config} = g.BOARD;\r\n const {classList} = QR.nodes.el;\r\n classList.toggle('forced-anon', QR.forcedAnon);\r\n classList.toggle('has-spoiler', QR.spoiler);\r\n classList.toggle('has-sjis', !!config.sjis_tags);\r\n classList.toggle('has-math', !!config.math_tags);\r\n classList.toggle('sjis-preview', !!config.sjis_tags && Conf['sjisPreview']);\r\n classList.toggle('show-new-thread-option', Conf['Show New Thread Option in Threads']);\r\n\r\n if (parseInt(Conf['customCooldown'], 10) > 0) {\r\n $.addClass(QR.nodes.fileSubmit, 'custom-cooldown');\r\n $.get('customCooldownEnabled', Conf['customCooldownEnabled'], function({customCooldownEnabled}) {\r\n QR.setCustomCooldown(customCooldownEnabled);\r\n return $.sync('customCooldownEnabled', QR.setCustomCooldown);\r\n });\r\n }\r\n\r\n QR.flagsInput();\r\n\r\n $.on(nodes.autohide, 'change', QR.toggleHide);\r\n $.on(nodes.close, 'click', QR.close);\r\n $.on(nodes.status, 'click', QR.submit);\r\n $.on(nodes.form, 'submit', QR.submit);\r\n $.on(nodes.sjisToggle, 'click', QR.toggleSJIS);\r\n $.on(nodes.texButton, 'mousedown', QR.texPreviewShow);\r\n $.on(nodes.texButton, 'mouseup', QR.texPreviewHide);\r\n $.on(nodes.addPost, 'click', () => new QR.post(true));\r\n $.on(nodes.drawButton, 'click', QR.oekaki.draw);\r\n $.on(nodes.fileButton, 'click', QR.openFileInput);\r\n $.on(nodes.noFile, 'click', QR.openFileInput);\r\n $.on(nodes.filename, 'focus', function() { return $.addClass(this.parentNode, 'focus'); });\r\n $.on(nodes.filename, 'blur', function() { return $.rmClass(this.parentNode, 'focus'); });\r\n $.on(nodes.spoiler, 'change', () => QR.selected.nodes.spoiler.click());\r\n $.on(nodes.oekakiButton, 'click', QR.oekaki.button);\r\n $.on(nodes.fileRM, 'click', () => QR.selected.rmFile());\r\n $.on(nodes.urlButton, 'click', () => QR.handleUrl(''));\r\n $.on(nodes.customCooldown, 'click', QR.toggleCustomCooldown);\r\n $.on(nodes.dumpButton, 'click', () => nodes.el.classList.toggle('dump'));\r\n $.on(nodes.fileInput, 'change', QR.handleFiles);\r\n\r\n window.addEventListener('focus', QR.focus, true);\r\n window.addEventListener('blur', QR.focus, true);\r\n // We don't receive blur events from captcha iframe.\r\n $.on(d, 'click', QR.focus);\r\n\r\n // XXX Workaround for image pasting in Firefox, obsolete as of v50.\r\n // https://bugzilla.mozilla.org/show_bug.cgi?id=906420\r\n if (($.engine === 'gecko') && !window.DataTransferItemList) {\r\n nodes.pasteArea.hidden = false;\r\n }\r\n new MutationObserver(QR.pasteFF).observe(nodes.pasteArea, {childList: true});\r\n\r\n // save selected post's data\r\n const items = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag'];\r\n let i = 0;\r\n const save = function() { return QR.selected.save(this); };\r\n while ((name = items[i++])) {\r\n var node;\r\n if (!(node = nodes[name])) { continue; }\r\n event = node.nodeName === 'SELECT' ? 'change' : 'input';\r\n $.on(nodes[name], event, save);\r\n }\r\n\r\n // XXX Blink and WebKit treat width and height of + +
            + +
            +
            + + +
            + +
            + + + No selected file + + + ✎︎ + + 🔗︎ + + 🕒︎ + + + + +
            + + + + + + +`; + + var ferongr_unreadDead = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///9zBQC/AADpDAP/gID/q6voCwJJTwpOAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC'; + + var ferongr_unreadDeadY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxUlEQVR42q1TOwrCQBB9s0FRtJI0WoqFtSLYegoP4gVSeJsUHsHSI3iFeIqRXXgwrhlXwYHHhLwPTB7B36abBCV+0pA4DUBQUNZYQptGtW3jtoKyxgoe0yrBCoyZfL/5ioQ3URZOXW9I341l3oo+NXEZiW4CEuIzvPECopED4OaZ3RNmeAm4u+a8Jr5f17VyVoL8fr8qcltzwlyyj2iqcgPOQ9ExkHAITgD75bYBe0A5S4H/P9htuWMF3QXoQpwaKeT+lnsC6JE5I6aq6fEAAAAASUVORK5CYII='; + + var ferongr_unreadSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///8AcH4AtswA2PJ55fKi6fIA1/FtpPADAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC'; + + var ferongr_unreadSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxElEQVQ4y2NgoBq4/vE/HJOsBiRQUIfA2AzBqQYqUfn00/9FLz+BaQxDCKqBmX7jExijKEDSDJPHrnnbGQhGV4RmOFwdVkNwhQMheYwQxhaIi7b9Z9A3gWAQm2BUoQOgRhgA8o7j1ozLC4LCyAZcx6kZI5qg4kLKqggDFFWxJySsUQVzlb4pwgAJaTRvokcVNgOqOv8zcHBCsL07DgNg8YsczzA5MxtUL+DMD8g0slxI/H8GQ/P/DJKyeKIRpglXZsIiBwBhP5O+VbI/JgAAAABJRU5ErkJggg=='; + + var ferongr_unreadNSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEX///8oeQBJ3ABV/wHM/7Lu/+ZU/gAqUP3dAAAAAXRSTlMAQObYZgAAAGJJREFUeF5Fi7ENg0AQBCfa/AFdDh2gdwPIogMK2E2+/xLslwOvdqRJhv+GQQPUCtJM7svankLrq/I+TY5e6Ueh1jyBMX7AFJi9vwfyVO4CbbO6jNYpp9GyVPbdkFhVgAQ2H0NOE5jk9DT8AAAAAElFTkSuQmCC'; + + var ferongr_unreadNSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAx0lEQVQ4y2NgoBYI+cfwH4ZJVgMS0KhEYGyG4FQDkzjzf9P/d/+fgWl0QwiqgSkI/c8IxsgKkDXD5LFq9rwDweiK0A2HqcNqCK5wICSPEcLYAtH+AMN/IXMIBrEJRie6OEgjDAC5x3FqxuUFNiEUA67j1IweTTBxBQ1puAG86jgSEraogskJWSBcwCGF5k30qMJmgMFEhv/MXBAs5oLDAFj8IsczTE7UEeECbhU8+QGZRpaTi2b4L2zF8J9TGk80wjThykzY5AAW/2O1C2mIbgAAAABJRU5ErkJggg=='; + + var xat_unreadDead = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAG1BMVEX+AACLkZFub2yfaF3zZGIAAAD/AAD/iYr/zs8IPcF6AAAABXRSTlMAeprJ7xzg6IEAAABZSURBVAjXY2DABKGBSkqioQwMrGmpxsZhaQEMDGFpIa5pqSCRtPDSNJBIaGh5eShQDYOye0V7iREKAyQFYoiCFAcyILQDGcGmEEZYkGoqiMHKysAQEICwGwAAjBmBqhYlagAAAABJRU5ErkJggg=='; + + var xat_unreadDeadY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAPFBMVEUAAACEgoBva2ilamDxcG7IaWYgFBNOSEf//f0PDQwBAAA7LCwAAAD/AAD+hIX+m5z+zc5HAADPAAAGAADl032uAAAADHRSTlMAzNv0/vz+6v3+7ALrmfyXAAAAaUlEQVQY042PyxKAIAhFAc1eV7T6/3/N8VXOtAgWwBm4ANEPA8AswpySXHvvYZLlpBNrh9pDtcSqAQ1BUTVIjNUQY5icmwfglmXNgE0d6QBF9GigrU0A9LoM53U1kFzk6SBQuWfD/vHqDUCpBmVKTTM4AAAAAElFTkSuQmCC'; + + var xat_unreadSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIVBMVEUAAACRjop4dXVpZ2tdcI9dfKdisfMAAAAumMN9xv+s2/+PADT2AAAAB3RSTlMAepGdv83v3HIc4QAAAFxJREFUCNdjYMAE5YXKRuLlDAzsHe2uIRUdBQwMFR1l6R3tIJGOyukdIJHy8lkry4FqGEwzV62aFozMUAFJOQEZ4iDFhQwI7UBGaTiEUVFs3g5isLMzMBQUIOwGAJRlIu9hk08QAAAAAElFTkSuQmCC'; + + var xat_unreadSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAMFBMVEUAAACAgYVlc4ljsu4AAAAAAAAAAAAumMODyP6b1P6e1f/g8v89msgSIiwNFxwbPU3tQYj5AAAABnRSTlMAxej+9VTmD9ciAAAAZElEQVQI12NgwARpiUKKYmkMDGzlZUpK6eUJDAzp5clm5WUgkfKMtnKQSFpa54o0oBoGJYvZO88+gjJu7wMyhIBS2SCGGFDxaxADpP32NjAjSe0bSFd6epIaWISNjYEhJRVhNwAGlyJpYtcvcAAAAABJRU5ErkJggg=='; + + var xat_unreadNSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAHlBMVEUfJSCRi5Frbm9dn19082KR/30AAABmzDOq/5vZ/9Gt/vt2AAAABnRSTlMAe5rJ7/4vxEp4AAAAWUlEQVQI12NgwARpiUpKYmkMDGzlZcbG6eUJDAzp5Slu5WUgkfLUsHKQSFpaRGsaUA2DsmvnjBAjFAZICsQQAylOZEBoBzKSzSCM9CS1MhCDjY2BISEBYTcAtgAcKSK2vuIAAAAASUVORK5CYII='; + + var xat_unreadNSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAM1BMVEUAAACBj39tfm1qj2RepFlu2VQAAQAAAAAAAABmyzOX/oSr/pus/pzk/98PGgtatC4CBAI1ENblAAAACHRSTlMA09/p9v77ig0SBcQAAABnSURBVBjTjY9LDsAgCEQRsR2xWu9/2hK/adJFYQG8wABEPwyAYzNnSatjjPAiviWLhPCqI1R7HBrQdCmGBrEETTmnUAq/QMm5dODHyAQOXXR1zLUGsIEI7lonMGfeHQTq9xw4P159AIxSBSC53km7AAAAAElFTkSuQmCC'; + + var Mayhem_unreadDead = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABFklEQVR4AZ2R4WqEMBCEFy1yiJQQ14gcIhIuFBFR+qPQ93+v66QMksrlTwMfkZ2ZZbMKTgVqYIDl3YAbeCM31lJP/Zul4MAEPJjBQGNDLGsz8PQ6aqLAP5PTdd1WlmU09mSKtdTDRgrkzspJPKq6RxMahfj9yhOzQEZwZAwfzrk1ox3MXibIN8hO4MAjeV72CemJGWblnRsOYOdoGw0jebB20BPAwKzUQPlrFhrXFw1Wagu9yuzZwINzVAZCURRL+gRr7Wd8Vtqg4Th/lsUmewyk9WQ/A7NiwJz5VV/GmO+MNjMrFvh/NPDMigHTaeJN09a27ZHRJmalBg54CgfvAGYSLpoHjlmpuAwFdzDy7oGS/qIpM9UPFGg1b1kUlssAAAAASUVORK5CYII='; + + var Mayhem_unreadDeadY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABR0lEQVR4AYWSQWq0QBCFCw0SRIK0PQ4hiIhEZBhEySLyewUPEMgqR/JIXiDhzz7kKKYePIZajEzDRxfV9dWU3SO6IiVWUsVxT5R75Y4gTmwNnUh4kCulUiuV8sjChDjmKtaUcHgmHsnNrMPh0IVhiMIjKZGzNXDoyhMzF7C89z2KtFGD+FoNXEUKZdgpaPM8P++cDXTtBDca7EyQK8+bXTufYBccuvLAG26UnqN1LCgI4g/lm7zTgSux4vk0J8rnKw3+m1//pBPbBrVyGZVNmiAITviEtm3t+D+2QcJx7GUxlN4594K4ZY75Xzh0JVWqnad6TdP0H+LRNBjHcYNDV5xS32qwaC4my7Lwn6guu5QoomgbdFmWDYhnM8E8zxscuhLzPWtKA/dGqUizrityX9M0YX+DQ1ciXobnP6vgfmTOM7Znnk70B58pPaEvx+epAAAAAElFTkSuQmCC'; + + var Mayhem_unreadSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/ElEQVR4AZ3RUWqEMBSF4ftQZAhSREQJIiIXpQwi+tSldkFdWPsLhyEE0ocKH2Fyzg1mNJ4KAQ1arTUeeJMH6qwTUJmCHjMcC6KKtbSIylzdXpl18J/k4fdTpUFmPLOOa9bGe+P4+n5RYYfLXuiMsAlXofBxK2QXpvwN/jqg+AY91vR+pStk+apZe0fEhhMXDhUmWXEoO9WNmrWAzvRPq7jnB2jvUGfWTEgPcJzZFTbZk/0Tnh5QI+af6lVGvq/Do2atwVL4VJ+3QrZo1lr4Pw5wzVqDWaV7SUvHrZDNmrWAHq7g0rphkS3LXDMBVqFGhxGT1gGdDFnWaab6BRmXRvbxDmYiAAAAAElFTkSuQmCC'; + + var Mayhem_unreadSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4AY2SQUrEQBBFS9CMNFEkhAQdYmiCIUgcZlYGc4VsBcGVF/AuWXme4F7RtXiVWF9+Y9MYtOHRTdX/NZWaEj2RYpQTJeEdK4fKPuA7DjSGXiQkU0qlUqxySmFMEsYsNSU8zEmK4OwdEbmkKCclYoGmolfWCGyenh1O0EJE2gXNWpFC2S0IGrCQ29EbdPCPAmEHmXIxByf8hDAPD71yzAnXypatbSgoAN8Pyju5h4deMUrqJk1z+0uBN+/XX+gxfoFK2QafUJO2aRq//Q+/QIx2wr+Kwq0rusrP/QKf9MTCtbQLf9U1wNvYnz3qug45S68kSvVXgbPbx3nvYPXNOI7cRPWySukK+DcGCvA+urqZ3RmGAbmSXjFK5rpwW8nhWVJP04TYa9/3uO/goVciDiPlZhW8c8ZAHuRSeqIv32FK/GYGL8YAAAAASUVORK5CYII='; + + var Mayhem_unreadNSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/ElEQVR4AZ3RUWqEMBSF4ftQZAihDCKKiAQJShERQx+6o662e2p/4TCEQF468BEm95yLovFr4PBEq9PjgTd5wBcZp6559AiIWDAq6KXV3aJMUMfDOsTf7Mf/XaFBAvYiE9W16b74/vl8UeBAlKOSmWAzUiXwcavMkrrFE9QXVJ+gx5q9XvUVivmqrr1jxIYLCacCs6y6S8psGNU1hw4Bu4JHuUB3pzJBHZcviLiKV9jkyO4vxHyBx1h+qlcY5b2Wj+raE0vlU33dKrNFXWsR/7EgqmtPBIXuIw+dt8osqGsOPaIGSeeGRbZiFtVxsAYeHSbMOgd0MhSzTp3mD4RaQX4aW3NMAAAAAElFTkSuQmCC'; + + var Mayhem_unreadNSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABP0lEQVR4AYWS0UqFQBCGhziImNRBRImDmUgiIaF0kWSP4AMEXXXTE/QiPpL3UdR19Crb/PAvLEtyFj5mmfn/cdxd0RUokbJXEsZYCZUd4D72NBG8wkKmlEqtVMoFhTFJmKuoKelBTVIkjbNE5IainJTIeZqaXjkg8fp+Z7GCjiLQbWgOihTKsCFowUZtoNef4HgDf4JMuTbe8n/Br8NDr5zxhBul52i3FBQE+xflmzzTA69ESmpPmubunwZfztc/6IncBrXSe7/QkK5tW3f8H7dBjHH8q6Kwt033V6Hb4JeeWPgsq42rugfYZ92psWscRwMPvZIo9bEGD2+F2YUnBizLwpeoXnYpbQM34kAB9peP58aueZ4NPPRKxPusaRoYG6UizbquyH1O04T4RA+8EvAwUr6sgjFnDuReLaUn+ANygUa7+9SCWgAAAABJRU5ErkJggg=='; + + var fourChanJS_unreadDead = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAD/AABnZ2f///8nFk05AAAAAXRSTlMAQObYZgAAAEFJREFUeNqNjgEKACAMAjvX/98cAkkxgmSgO8Bt/Ai4ApJ6KKhzF3OiEMDASrGB/QWgPEHsUpN+Ng9xAETMYhDrWmeHAMcmvycWAAAAAElFTkSuQmCC'; + + var fourChanJS_unreadDeadY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAD1BMVEUAAAAAAAD/AABmZmYA/wBD99DBAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAE9JREFUCNdljcsRACEIQ5MOiNKAdGAJ9N/Uiu7nsMzABHgB4B8ygFoZA2hhVWavhhGeURPJU9q45+17hGbfGxa82Ndex3hEM44SJGD2/b4AzDgGlHbl388AAAAASUVORK5CYII='; + + var fourChanJS_unreadSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAAul8NnZ2f////82iC9AAAAAXRSTlMAQObYZgAAAEFJREFUeNqNjgEKACAMAjvX/98cAkkxgmSgO8Bt/Ai4ApJ6KKhzF3OiEMDASrGB/QWgPEHsUpN+Ng9xAETMYhDrWmeHAMcmvycWAAAAAElFTkSuQmCC'; + + var fourChanJS_unreadSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAD1BMVEUAAAAAAAAul8NnZ2f/AAD7B+mqAAAAAXRSTlMAQObYZgAAAAlwSFlzAAALEgAACxIB0t1+/AAAAE9JREFUCNdljcsRACEIQ5MOiNKAdGAJ9N/Uiu7nsMzABHgB4B8ygFoZA2hhVWavhhGeURPJU9q45+17hGbfGxa82Ndex3hEM44SJGD2/b4AzDgGlHbl388AAAAASUVORK5CYII='; + + var fourChanJS_unreadNSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAElBMVEUBAAAAAABmzDNlyjJnZ2f///+6o7dfAAAAAXRSTlMAQObYZgAAAERJREFUeF6NjkEKADEIA51o///lJZfQxUsHITogWi8AvwZJuxmYa25xDooBLEwOWFTYAsYVhdorLZt9Ng9xCUTCUCQ2H3F4ANrZ2WNiAAAAAElFTkSuQmCC'; + + var fourChanJS_unreadNSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAD1BMVEUAAAAAAABmzDNmZmb/AAC8/wCMAAAAAXRSTlMAQObYZgAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAE9JREFUCNdljcsRACEIQ5MOiNKAdGAJ9N/Uiu7nsMzABHgB4B8ygFoZA2hhVWavhhGeURPJU9q45+17hGbfGxa82Ndex3hEM44SJGD2/b4AzDgGlHbl388AAAAASUVORK5CYII='; + + var Original_unreadDead = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX/////AAD///8AAABBZmS3AAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII='; + + var Original_unreadDeadY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhElEQVR42q1RwQnAMAjMu5M4guAKXa4j5dUROo5tipSDcrFChUONd0di2m/hEGVOHDyIPufgwAFASDkpoSzmBrkJ2UMyR9LsJ3rvrqo3Rt1YMIMhhNnOxLMnoMFBxHyJAr2IOBFzA8U+6pLBdmEJTA0aMVjpDd6Loks0s5HZNwYx8tfZCZ0kll7ORffZAAAAAElFTkSuQmCC'; + + var Original_unreadSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX///8ul8P///8AAACaqgkzAAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII='; + + var Original_unreadSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAABBQcHFx4KISoNLToaVW4oKCgul8M4ODg7OzvBwcH///8uS/CdAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eILZO5/XI0UAgm7H9tOsu0yGWAQSOoFijHOxOANGqm/LczpOaXs4gISrPZ+gc2+hO5w2xdwgOjBFUIF+sEJrhUl9JFr+badFwR+BfqlmGUJAAAAAElFTkSuQmCC'; + + var Original_unreadNSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAADFBMVEX///9mzDP///8AAACT0n1lAAAAAXRSTlMAQObYZgAAAExJREFUeF4tyrENgDAMAMFXKuQswQLBG3mOlBnFS1gwDfIYLpEivvjq2MlqjmYvYg5jWEzCwtDSQlwcXKCVLrpFbvLvvSf9uZJ2HusDtJAY7Tkn1oYAAAAASUVORK5CYII='; + + var Original_unreadNSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAAECAIQIAgWLAsePA8oKCg4ODg6dB07OztmzDPBwcH///+rsf3XAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eIDhbn/cTVSCCTsfmw7ybbLZIBBIKkXKKU0E4M3aKT+tjCn5xiziwuIsNr7BTb7ErrDZV/AAaIHdwgV6AcnuFaU0Eeu5dt2XiUyBjCQ2bIrAAAAAElFTkSuQmCC'; + + var Metro_unreadDead = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAC/AABrZQDiAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg=='; + + var Metro_unreadDeadY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAC/AAD///8dAAApAABsAAAHAAA4AACQAAAsAABMCpCvAAAAA3RSTlMAPse+s4iwAAAAMklEQVQI12NggAFmY2MDECaNAQZCilAzVJyg5oS4GqAxUtygjIp2KGOKJ5SxepcB3BUAcdYRqxAtgFoAAAAASUVORK5CYII='; + + var Metro_unreadSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAAA1/GhpCidAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg=='; + + var Metro_unreadSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAAA1/H///8AISUALzQAeokACAkAQEcAorYAMTcE9WFNAAAAA3RSTlMAPse+s4iwAAAAMklEQVQI12NggAFmY2MDECaNAQZCilAzVJyg5oS4GqAxUtygjIp2KGOKJ5SxepcB3BUAcdYRqxAtgFoAAAAASUVORK5CYII='; + + var Metro_unreadNSFW = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAABV/wErM5hwAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg=='; + + var Metro_unreadNSFWY = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAABV/wH///8NKAASOAAwkQADCgAZTABAwQATOwC5e3VGAAAAA3RSTlMAPse+s4iwAAAAMklEQVQI12NggAFmY2MDECaNAQZCilAzVJyg5oS4GqAxUtygjIp2KGOKJ5SxepcB3BUAcdYRqxAtgFoAAAAASUVORK5CYII='; + + var dead = 'R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw=='; + + var empty = 'R0lGODlhEAAQAJEAAAAAAP///9vb2////yH5BAEAAAMALAAAAAAQABAAAAIvnI+pq+D9DBAUoFkPFnbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw=='; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var Favicon = { + init() { + return $$1.asap((() => d$1.head && (Favicon.el = $$1('link[rel="shortcut icon"]', d$1.head))), Favicon.initAsap); + }, + + set(status) { + Favicon.status = status; + if (Favicon.el) { + Favicon.el.href = Favicon[status]; + // `favicon.href = href` doesn't work on Firefox. + return $$1.add(d$1.head, Favicon.el); + } + }, + + initAsap() { + Favicon.el.type = 'image/x-icon'; + const {href} = Favicon.el; + Favicon.isSFW = /ws\.ico$/.test(href); + Favicon.default = href; + Favicon.switch(); + if (Favicon.status) { + return Favicon.set(Favicon.status); + } + }, + + switch() { + let items = { + ferongr: [ + ferongr_unreadDead, + ferongr_unreadDeadY, + ferongr_unreadSFW, + ferongr_unreadSFWY, + ferongr_unreadNSFW, + ferongr_unreadNSFWY, + ], + 'xat-': [ + xat_unreadDead, + xat_unreadDeadY, + xat_unreadSFW, + xat_unreadSFWY, + xat_unreadNSFW, + xat_unreadNSFWY, + ], + Mayhem: [ + Mayhem_unreadDead, + Mayhem_unreadDeadY, + Mayhem_unreadSFW, + Mayhem_unreadSFWY, + Mayhem_unreadNSFW, + Mayhem_unreadNSFWY, + ], + '4chanJS': [ + fourChanJS_unreadDead, + fourChanJS_unreadDeadY, + fourChanJS_unreadSFW, + fourChanJS_unreadSFWY, + fourChanJS_unreadNSFW, + fourChanJS_unreadNSFWY, + ], + Original: [ + Original_unreadDead, + Original_unreadDeadY, + Original_unreadSFW, + Original_unreadSFWY, + Original_unreadNSFW, + Original_unreadNSFWY, + ], + 'Metro': [ + Metro_unreadDead, + Metro_unreadDeadY, + Metro_unreadSFW, + Metro_unreadSFWY, + Metro_unreadNSFW, + Metro_unreadNSFWY, + ] + }; + items = $$1.getOwn(items, Conf['favicon']); + + const f = Favicon; + const t = 'data:image/png;base64,'; + let i = 0; + while (items[i]) { + items[i] = t + items[i++]; + } + + [f.unreadDead, f.unreadDeadY, f.unreadSFW, f.unreadSFWY, f.unreadNSFW, f.unreadNSFWY] = Array.from(items); + return f.update(); + }, + + update() { + if (this.isSFW) { + this.unread = this.unreadSFW; + return this.unreadY = this.unreadSFWY; + } else { + this.unread = this.unreadNSFW; + return this.unreadY = this.unreadNSFWY; + } + }, + + SFW: '//s.4cdn.org/image/favicon-ws.ico', + NSFW: '//s.4cdn.org/image/favicon.ico', + dead: `data:image/gif;base64,${dead}`, + logo: `data:image/png;base64,${empty}`, + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const $$ = (selector, root = d$1.body) => [...Array.from(root.querySelectorAll(selector))]; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const CaptchaReplace = { + init() { + if ((g.SITE.software !== 'yotsuba') || (d$1.cookie.indexOf('pass_enabled=1') >= 0)) { return; } + + if (Conf['Force Noscript Captcha'] && Main$1.jsEnabled) { + $$1.ready(Captcha.replace.noscript); + return; + } + + if (Conf['captchaLanguage'].trim()) { + if (['boards.4chan.org', 'boards.4channel.org'].includes(location.hostname)) { + return $$1.onExists(doc$1, '#captchaFormPart', node => $$1.onExists(node, 'iframe[src^="https://www.google.com/recaptcha/"]', Captcha.replace.iframe)); + } else { + return $$1.onExists(doc$1, 'iframe[src^="https://www.google.com/recaptcha/"]', Captcha.replace.iframe); + } + } + }, + + noscript() { + let noscript, original, toggle; + if (!((original = $$1('#g-recaptcha')) && (noscript = $$1('noscript', original.parentNode)))) { return; } + const span = $$1.el('span', + {id: 'captcha-forced-noscript'}); + $$1.replace(noscript, span); + $$1.rm(original); + const insert = function() { + span.innerHTML = noscript.textContent; + return Captcha.replace.iframe($$1('iframe[src^="https://www.google.com/recaptcha/"]', span)); + }; + if (toggle = $$1('#togglePostFormLink a, #form-link')) { + return $$1.on(toggle, 'click', insert); + } else { + return insert(); + } + }, + + iframe(iframe) { + let lang; + if (lang = Conf['captchaLanguage'].trim()) { + const src = /[?&]hl=/.test(iframe.src) ? + iframe.src.replace(/([?&]hl=)[^&]*/, '$1' + encodeURIComponent(lang)) + : + iframe.src + `&hl=${encodeURIComponent(lang)}`; + if (iframe.src !== src) { iframe.src = src; } + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const CaptchaT = { + init() { + if (d$1.cookie.indexOf('pass_enabled=1') >= 0) { return; } + if (!(this.isEnabled = !!$$1('#t-root') || !$$1.id('postForm'))) { return; } + + const root = $$1.el('div', {className: 'captcha-root'}); + this.nodes = {root}; + + $$1.addClass(QR.nodes.el, 'has-captcha', 'captcha-t'); + return $$1.after(QR.nodes.com.parentNode, root); + }, + + moreNeeded() { + }, + + getThread() { + let threadID; + const boardID = g.BOARD.ID; + if (QR.posts[0].thread === 'new') { + threadID = '0'; + } else { + threadID = '' + QR.posts[0].thread; + } + return {boardID, threadID}; + }, + + setup(focus) { + if (!this.isEnabled) { return; } + + if (!this.nodes.container) { + this.nodes.container = $$1.el('div', {className: 'captcha-container'}); + $$1.prepend(this.nodes.root, this.nodes.container); + CaptchaT.currentThread = CaptchaT.getThread(); + $$1.global(function() { + const el = document.querySelector('#qr .captcha-container'); + window.TCaptcha.init(el, this.boardID, +this.threadID); + return window.TCaptcha.setErrorCb(err => window.dispatchEvent(new CustomEvent('CreateNotification', {detail: { + type: 'warning', + content: '' + err + }}) + )); + } + , CaptchaT.currentThread); + } + + if (focus) { + return $$1('#t-resp').focus(); + } + }, + + destroy() { + if (!this.isEnabled || !this.nodes.container) { return; } + $$1.global(() => window.TCaptcha.destroy()); + $$1.rm(this.nodes.container); + return delete this.nodes.container; + }, + + updateThread() { + if (!this.isEnabled) { return; } + const {boardID, threadID} = (CaptchaT.currentThread || {}); + const newThread = CaptchaT.getThread(); + if ((newThread.boardID !== boardID) || (newThread.threadID !== threadID)) { + CaptchaT.destroy(); + return CaptchaT.setup(); + } + }, + + getOne() { + let el; + let response = {}; + if (this.nodes.container) { + for (var key of ['t-response', 't-challenge']) { + response[key] = $$1(`[name='${key}']`, this.nodes.container).value; + } + } + if (!response['t-response'] && !((el = $$1('#t-msg')) && /Verification not required/i.test(el.textContent))) { + response = null; + } + return response; + }, + + setUsed() { + if (!this.isEnabled) { return; } + if (this.nodes.container) { + return $$1.global(() => window.TCaptcha.clearChallenge()); + } + }, + + occupied() { + return !!this.nodes.container; + } + }; + + // This file was created because these functions on $ were sometimes not initialized yet because of circular + // dependencies, so try to keep this file without dependencies, so these functions don't have to wait for something else + const debounce = (wait, fn) => { + let lastCall = 0; + let timeout = null; + let that = null; + let args = null; + const exec = function () { + lastCall = Date.now(); + return fn.apply(that, args); + }; + return function () { + args = arguments; + that = this; + if (lastCall < (Date.now() - wait)) { + return exec(); + } + // stop current reset + clearTimeout(timeout); + // after wait, let next invocation execute immediately + return timeout = setTimeout(exec, wait); + }; + }; + const dict = () => Object.create(null); + dict.clone = function (obj) { + if ((typeof obj !== 'object') || (obj === null)) { + return obj; + } + else if (obj instanceof Array) { + const arr = []; + for (let i = 0, end = obj.length; i < end; i++) { + arr.push(dict.clone(obj[i])); + } + return arr; + } + else { + const map = Object.create(null); + for (var key in obj) { + var val = obj[key]; + map[key] = dict.clone(val); + } + return map; + } + }; + dict.json = (str) => dict.clone(JSON.parse(str)); + const SECOND = 1000; + const MINUTE = SECOND * 60; + const HOUR = MINUTE * 60; + const DAY = HOUR * 24; + const platform = window.GM_xmlhttpRequest ? 'userscript' : 'crx'; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS104: Avoid inline assignments + * DS206: Consider reworking classes to avoid initClass + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class DataBoard { + static initClass() { + this.keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads', 'watcherLastModified', 'customTitles']; + + this.changes = []; + } + + constructor(key, sync, dontClean) { + this.onSync = this.onSync.bind(this); + this.key = key; + this.initData(Conf[this.key]); + $$1.sync(this.key, this.onSync); + if (!dontClean) { this.clean(); } + if (!sync) { return; } + // Chrome also fires the onChanged callback on the current tab, + // so we only start syncing when we're ready. + var init = () => { + $$1.off(d$1, '4chanXInitFinished', init); + return this.sync = sync; + }; + $$1.on(d$1, '4chanXInitFinished', init); + } + + initData(data) { + let boards; + this.data = data; + if (this.data.boards) { + let lastChecked; + ({boards, lastChecked} = this.data); + this.data['4chan.org'] = {boards, lastChecked}; + delete this.data.boards; + delete this.data.lastChecked; + } + return this.data[g.SITE.ID] || (this.data[g.SITE.ID] = { boards: dict() }); + } + + save(change, cb) { + change(); + DataBoard.changes.push(change); + return $$1.get(this.key, { boards: dict() }, items => { + if (!DataBoard.changes.length) { return; } + const needSync = ((items[this.key].version || 0) > (this.data.version || 0)); + if (needSync) { + this.initData(items[this.key]); + for (change of DataBoard.changes) { change(); } + } + DataBoard.changes = []; + this.data.version = (this.data.version || 0) + 1; + return $$1.set(this.key, this.data, () => { + if (needSync) { this.sync?.(); } + return cb?.(); + }); + }); + } + + forceSync(cb) { + return $$1.get(this.key, { boards: dict() }, items => { + if ((items[this.key].version || 0) > (this.data.version || 0)) { + this.initData(items[this.key]); + for (var change of DataBoard.changes) { change(); } + this.sync?.(); + } + return cb?.(); + }); + } + + delete({siteID, boardID, threadID, postID}, cb) { + if (!siteID) { siteID = g.SITE.ID; } + if (!this.data[siteID]) { return; } + return this.save(() => { + if (postID) { + if (!this.data[siteID].boards[boardID]?.[threadID]) { return; } + delete this.data[siteID].boards[boardID][threadID][postID]; + return this.deleteIfEmpty({siteID, boardID, threadID}); + } else if (threadID) { + if (!this.data[siteID].boards[boardID]) { return; } + delete this.data[siteID].boards[boardID][threadID]; + return this.deleteIfEmpty({siteID, boardID}); + } else { + return delete this.data[siteID].boards[boardID]; + } + } + , cb); + } + + deleteIfEmpty({siteID, boardID, threadID}) { + if (!this.data[siteID]) { return; } + if (threadID) { + if (!Object.keys(this.data[siteID].boards[boardID][threadID]).length) { + delete this.data[siteID].boards[boardID][threadID]; + return this.deleteIfEmpty({siteID, boardID}); + } + } else if (!Object.keys(this.data[siteID].boards[boardID]).length) { + return delete this.data[siteID].boards[boardID]; + } + } + + set(data, cb) { + return this.save(() => { + return this.setUnsafe(data); + } + , cb); + } + + setUnsafe({siteID, boardID, threadID, postID, val}) { + if (!siteID) { siteID = g.SITE.ID; } + if (!this.data[siteID]) { this.data[siteID] = { boards: dict() }; } + if (postID !== undefined) { + let base; + return (((base = this.data[siteID].boards[boardID] || (this.data[siteID].boards[boardID] = dict())))[threadID] || (base[threadID] = dict()))[postID] = val; + } else if (threadID !== undefined) { + return (this.data[siteID].boards[boardID] || (this.data[siteID].boards[boardID] = dict()))[threadID] = val; + } else { + return this.data[siteID].boards[boardID] = val; + } + } + + extend({siteID, boardID, threadID, postID, val}, cb) { + return this.save(() => { + const oldVal = this.get({ siteID, boardID, threadID, postID, defaultValue: dict() }); + for (var key in val) { + var subVal = val[key]; + if (typeof subVal === 'undefined') { + delete oldVal[key]; + } else { + oldVal[key] = subVal; + } + } + return this.setUnsafe({siteID, boardID, threadID, postID, val: oldVal}); + } + , cb); + } + + setLastChecked(key='lastChecked') { + return this.save(() => { + return this.data[key] = Date.now(); + }); + } + + get({siteID, boardID, threadID, postID, defaultValue}) { + let board, val; + if (!siteID) { siteID = g.SITE.ID; } + if (board = this.data[siteID]?.boards[boardID]) { + let thread; + if (threadID == null) { + if (postID != null) { + for (thread = 0; thread < board.length; thread++) { + board[thread]; + if (postID in thread) { + val = thread[postID]; + break; + } + } + } else { + val = board; + } + } else if (thread = board[threadID]) { + val = (postID != null) ? + thread[postID] + : + thread; + } + } + return val || defaultValue; + } + + clean() { + let boardID, middle; + const siteID = g.SITE.ID; + for (boardID in this.data[siteID].boards) { + this.data[siteID].boards[boardID]; + this.deleteIfEmpty({siteID, boardID}); + } + const now = Date.now(); + if (now - (2 * HOUR) >= ((middle = this.data[siteID].lastChecked || 0)) || middle > now) { + this.data[siteID].lastChecked = now; + for (boardID in this.data[siteID].boards) { + this.ajaxClean(boardID); + } + } + } + + ajaxClean(boardID) { + const that = this; + const siteID = g.SITE.ID; + const threadsList = g.SITE.urls.threadsListJSON?.({siteID, boardID}); + if (!threadsList) { return; } + return $$1.cache(threadsList, function() { + if (this.status !== 200) { return; } + const archiveList = g.SITE.urls.archiveListJSON?.({siteID, boardID}); + if (!archiveList) { return that.ajaxCleanParse(boardID, this.response); } + const response1 = this.response; + return $$1.cache(archiveList, function() { + if ((this.status !== 200) && (!!g.SITE.archivedBoardsKnown || (this.status !== 404))) { return; } + return that.ajaxCleanParse(boardID, response1, this.response); + }); + }); + } + + ajaxCleanParse(boardID, response1, response2) { + let board, ID; + const siteID = g.SITE.ID; + if (!(board = this.data[siteID].boards[boardID])) { return; } + const threads = dict(); + if (response1) { + for (var page of response1) { + for (var thread of page.threads) { + ID = thread.no; + if (ID in board) { threads[ID] = board[ID]; } + } + } + } + if (response2) { + for (ID of response2) { + if (ID in board) { threads[ID] = board[ID]; } + } + } + this.data[siteID].boards[boardID] = threads; + this.deleteIfEmpty({siteID, boardID}); + return $$1.set(this.key, this.data); + } + + onSync(data) { + if ((data.version || 0) <= (this.data.version || 0)) { return; } + this.initData(data); + return this.sync?.(); + } + } + DataBoard.initClass(); + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class SimpleDict { + constructor() { + this.keys = []; + } + push(key, data) { + key = `${key}`; + if (!this[key]) { + this.keys.push(key); + } + return this[key] = data; + } + rm(key) { + let i; + key = `${key}`; + if ((i = this.keys.indexOf(key)) !== -1) { + this.keys.splice(i, 1); + return delete this[key]; + } + } + forEach(fn) { + for (var key of [...Array.from(this.keys)]) { + fn(this[key]); + } + } + get(key) { + if (key === 'keys') { + return undefined; + } + else { + return $$1.getOwn(this, key); + } + } + } + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class Thread { + toString() { return this.ID; } + + constructor(ID, board) { + this.board = board; + this.ID = +ID; + this.threadID = this.ID; + this.boardID = this.board.ID; + this.siteID = g.SITE.ID; + this.fullID = `${this.board}.${this.ID}`; + this.posts = new SimpleDict(); + this.isDead = false; + this.isHidden = false; + this.isSticky = false; + this.isClosed = false; + this.isArchived = false; + this.postLimit = false; + this.fileLimit = false; + this.lastPost = 0; + this.ipCount = undefined; + this.json = null; + + this.OP = null; + this.catalogView = null; + + this.nodes = + {root: null}; + + this.board.threads.push(this.ID, this); + g.threads.push(this.fullID, this); + } + + setPage(pageNum) { + let icon; + const {info, reply} = this.OP.nodes; + if (!(icon = $$1('.page-num', info))) { + icon = $$1.el('span', {className: 'page-num'}); + $$1.replace(reply.parentNode.previousSibling, [$$1.tn(' '), icon, $$1.tn(' ')]); + } + icon.title = `This thread is on page ${pageNum} in the original index.`; + icon.textContent = `[${pageNum}]`; + if (this.catalogView) { return this.catalogView.nodes.pageCount.textContent = pageNum; } + } + + setCount(type, count, reachedLimit) { + if (!this.catalogView) { return; } + const el = this.catalogView.nodes[`${type}Count`]; + el.textContent = count; + return (reachedLimit ? $$1.addClass : $$1.rmClass)(el, 'warning'); + } + + setStatus(type, status) { + const name = `is${type}`; + if (this[name] === status) { return; } + this[name] = status; + if (!this.OP) { return; } + this.setIcon('Sticky', this.isSticky); + this.setIcon('Closed', this.isClosed && !this.isArchived); + return this.setIcon('Archived', this.isArchived); + } + + setIcon(type, status) { + const typeLC = type.toLowerCase(); + let icon = $$1(`.${typeLC}Icon`, this.OP.nodes.info); + if (!!icon === status) { return; } + + if (!status) { + $$1.rm(icon.previousSibling); + $$1.rm(icon); + if (this.catalogView) { $$1.rm($$1(`.${typeLC}Icon`, this.catalogView.nodes.icons)); } + return; + } + icon = $$1.el('img', { + src: `${g.SITE.Build.staticPath}${typeLC}${g.SITE.Build.gifIcon}`, + alt: type, + title: type, + className: `${typeLC}Icon retina` + } + ); + if (g.BOARD.ID === 'f') { + icon.style.cssText = 'height: 18px; width: 18px;'; + } + + const root = (type !== 'Sticky') && this.isSticky ? + $$1('.stickyIcon', this.OP.nodes.info) + : + $$1('.page-num', this.OP.nodes.info) || this.OP.nodes.quote; + $$1.after(root, [$$1.tn(' '), icon]); + + if (!this.catalogView) { return; } + return ((type === 'Sticky') && this.isClosed ? $$1.prepend : $$1.add)(this.catalogView.nodes.icons, icon.cloneNode()); + } + + kill() { + return this.isDead = true; + } + + collect() { + let n = 0; + this.posts.forEach(function(post) { + if (post.clones.length) { + return n++; + } else { + return post.collect(); + } + }); + if (!n) { + g.threads.rm(this.fullID); + return this.board.threads.rm(this); + } + } + } + + class CatalogThread { + toString() { return this.ID; } + + constructor(root, thread) { + this.thread = thread; + this.ID = this.thread.ID; + this.board = this.thread.board; + const {post} = this.thread.OP.nodes; + this.nodes = { + root, + thumb: $$1('.catalog-thumb', post), + icons: $$1('.catalog-icons', post), + postCount: $$1('.post-count', post), + fileCount: $$1('.file-count', post), + pageCount: $$1('.page-count', post), + replies: null + }; + this.thread.catalogView = this; + } + } + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS206: Consider reworking classes to avoid initClass + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const dialog = function(id, properties) { + const el = $$1.el('div', { + className: 'dialog', + id + } + ); + $$1.extend(el, properties); + el.style.cssText = Conf[`${id}.position`]; + + const move = $$1('.move', el); + $$1.on(move, 'touchstart mousedown', dragstart); + for (var child of move.children) { + if (!child.tagName) { continue; } + $$1.on(child, 'touchstart mousedown', e => e.stopPropagation()); + } + + return el; + }; + + var Menu$1 = (function() { + let currentMenu = undefined; + let lastToggledButton = undefined; + Menu$1 = class Menu { + static initClass() { + currentMenu = null; + lastToggledButton = null; + } + + constructor(type) { + // XXX AddMenuEntry event is deprecated + 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 = type; + $$1.on(d$1, 'AddMenuEntry', ({detail}) => { + if (detail.type !== this.type) { return; } + delete detail.open; + return this.addEntry(detail); + }); + this.entries = []; + } + + makeMenu() { + const menu = $$1.el('div', { + className: 'dialog', + id: 'menu', + tabIndex: 0 + } + ); + menu.dataset.type = this.type; + $$1.on(menu, 'click', e => e.stopPropagation()); + $$1.on(menu, 'keydown', this.keybinds); + return menu; + } + + toggle(e, button, data) { + e.preventDefault(); + e.stopPropagation(); + + if (currentMenu) { + // Close if it's already opened. + // Reopen if we clicked on another button. + const previousButton = lastToggledButton; + currentMenu.close(); + if (previousButton === button) { return; } + } + + if (!this.entries.length) { return; } + return this.open(button, data); + } + + open(button, data) { + let entry; + const menu = (this.menu = this.makeMenu()); + currentMenu = this; + lastToggledButton = button; + + this.entries.sort((first, second) => first.order - second.order); + + for (entry of this.entries) { + this.insertEntry(entry, menu, data); + } + + $$1.addClass(lastToggledButton, 'active'); + + $$1.on(d$1, 'click CloseMenu', this.close); + $$1.on(d$1, 'scroll', this.setPosition); + $$1.on(window, 'resize', this.setPosition); + $$1.after(button, menu); + + this.setPosition(); + + entry = $$1('.entry', menu); + // We've removed flexbox, so we don't use order anymore. + // while prevEntry = @findNextEntry entry, -1 + // entry = prevEntry + this.focus(entry); + + return menu.focus(); + } + + setPosition() { + const mRect = this.menu.getBoundingClientRect(); + const bRect = lastToggledButton.getBoundingClientRect(); + window.scrollY + bRect.top; + window.scrollX + bRect.left; + const cHeight = doc$1.clientHeight; + const cWidth = doc$1.clientWidth; + const [top, bottom] = Array.from((bRect.top + bRect.height + mRect.height) < cHeight ? + [`${bRect.bottom}px`, ''] + : + ['', `${cHeight - bRect.top}px`]); + const [left, right] = Array.from((bRect.left + mRect.width) < cWidth ? + [`${bRect.left}px`, ''] + : + ['', `${cWidth - bRect.right}px`]); + $$1.extend(this.menu.style, {top, right, bottom, left}); + return this.menu.classList.toggle('left', right); + } + + insertEntry(entry, parent, data) { + let submenu; + if (typeof entry.open === 'function') { + try { + if (!entry.open(data)) { return; } + } catch (err) { + Main$1.handleErrors({ + message: `Error in building the ${this.type} menu.`, + error: err + }); + return; + } + } + $$1.add(parent, entry.el); + + if (!entry.subEntries) { return; } + if (submenu = $$1('.submenu', entry.el)) { + // Reset sub menu, remove irrelevant entries. + $$1.rm(submenu); + } + submenu = $$1.el('div', + {className: 'dialog submenu'}); + for (var subEntry of entry.subEntries) { + this.insertEntry(subEntry, submenu, data); + } + $$1.add(entry.el, submenu); + } + + close() { + $$1.rm(this.menu); + delete this.menu; + $$1.rmClass(lastToggledButton, 'active'); + currentMenu = null; + lastToggledButton = null; + $$1.off(d$1, 'click scroll CloseMenu', this.close); + $$1.off(d$1, 'scroll', this.setPosition); + return $$1.off(window, 'resize', this.setPosition); + } + + findNextEntry(entry, direction) { + const entries = [...Array.from(entry.parentNode.children)]; + entries.sort((first, second) => first.style.order - second.style.order); + return entries[entries.indexOf(entry) + direction]; + } + + keybinds(e) { + let subEntry; + let next, submenu; + let entry = $$1('.focused', this.menu); + while ((subEntry = $$1('.focused', entry))) { + entry = subEntry; + } + + switch (e.keyCode) { + case 27: // Esc + lastToggledButton.focus(); + this.close(); + break; + case 13: case 32: // Enter, Space + entry.click(); + break; + case 38: // Up + if (next = this.findNextEntry(entry, -1)) { + this.focus(next); + } + break; + case 40: // Down + if (next = this.findNextEntry(entry, +1)) { + this.focus(next); + } + break; + case 39: // Right + if ((submenu = $$1('.submenu', entry)) && (next = submenu.firstElementChild)) { + let nextPrev; + while ((nextPrev = this.findNextEntry(next, -1))) { + next = nextPrev; + } + this.focus(next); + } + break; + case 37: // Left + if (next = $$1.x('parent::*[contains(@class,"submenu")]/parent::*', entry)) { + this.focus(next); + } + break; + default: + return; + } + + e.preventDefault(); + return e.stopPropagation(); + } + + onFocus(e) { + e.stopPropagation(); + return this.focus(e.target); + } + + focus(entry) { + let focused, submenu; + while ((focused = $$1.x('parent::*/child::*[contains(@class,"focused")]', entry))) { + $$1.rmClass(focused, 'focused'); + } + for (focused of $$('.focused', entry)) { + $$1.rmClass(focused, 'focused'); + } + $$1.addClass(entry, 'focused'); + + // Submenu positioning. + if (!(submenu = $$1('.submenu', entry))) { return; } + const sRect = submenu.getBoundingClientRect(); + const eRect = entry.getBoundingClientRect(); + const cHeight = doc$1.clientHeight; + const cWidth = doc$1.clientWidth; + const [top, bottom] = Array.from((eRect.top + sRect.height) < cHeight ? + ['0px', 'auto'] + : + ['auto', '0px']); + const [left, right] = Array.from((eRect.right + sRect.width) < (cWidth - 150) ? + ['100%', 'auto'] + : + ['auto', '100%']); + const {style} = submenu; + style.top = top; + style.bottom = bottom; + style.left = left; + return style.right = right; + } + + addEntry(entry) { + this.parseEntry(entry); + return this.entries.push(entry); + } + + parseEntry(entry) { + const {el, subEntries} = entry; + $$1.addClass(el, 'entry'); + $$1.on(el, 'focus mouseover', this.onFocus); + el.style.order = entry.order || 100; + if (!subEntries) { return; } + $$1.addClass(el, 'has-submenu'); + for (var subEntry of subEntries) { + this.parseEntry(subEntry); + } + } + }; + Menu$1.initClass(); + return Menu$1; + })(); + + var dragstart = function (e) { + let isTouching; + if ((e.type === 'mousedown') && (e.button !== 0)) { return; } // not LMB + // prevent text selection + e.preventDefault(); + if (isTouching = e.type === 'touchstart') { + e = e.changedTouches[e.changedTouches.length - 1]; + } + // distance from pointer to el edge is constant; calculate it here. + const el = $$1.x('ancestor::div[contains(@class,"dialog")][1]', this); + const rect = el.getBoundingClientRect(); + const screenHeight = doc$1.clientHeight; + const screenWidth = doc$1.clientWidth; + const o = { + id: el.id, + style: el.style, + dx: e.clientX - rect.left, + dy: e.clientY - rect.top, + height: screenHeight - rect.height, + width: screenWidth - rect.width, + screenHeight, + screenWidth, + isTouching + }; + + [o.topBorder, o.bottomBorder] = Array.from(Conf['Header auto-hide'] || !Conf['Fixed Header'] ? + [0, 0] + : Conf['Bottom Header'] ? + [0, Header$1.bar.getBoundingClientRect().height] + : + [Header$1.bar.getBoundingClientRect().height, 0]); + + if (isTouching) { + o.identifier = e.identifier; + o.move = touchmove.bind(o); + o.up = touchend.bind(o); + $$1.on(d$1, 'touchmove', o.move); + return $$1.on(d$1, 'touchend touchcancel', o.up); + } else { // mousedown + o.move = drag.bind(o); + o.up = dragend.bind(o); + $$1.on(d$1, 'mousemove', o.move); + return $$1.on(d$1, 'mouseup', o.up); + } + }; + + var touchmove = function (e) { + for (var touch of e.changedTouches) { + if (touch.identifier === this.identifier) { + drag.call(this, touch); + return; + } + } + }; + + var drag = function (e) { + const {clientX, clientY} = e; + + let left = clientX - this.dx; + left = left < 10 ? + 0 + : (this.width - left) < 10 ? + '' + : + ((left / this.screenWidth) * 100) + '%'; + + let top = clientY - this.dy; + top = top < (10 + this.topBorder) ? + this.topBorder + 'px' + : (this.height - top) < (10 + this.bottomBorder) ? + '' + : + ((top / this.screenHeight) * 100) + '%'; + + const right = left === '' ? + 0 + : + ''; + + const bottom = top === '' ? + this.bottomBorder + 'px' + : + ''; + + const {style} = this; + style.left = left; + style.right = right; + style.top = top; + return style.bottom = bottom; + }; + + var touchend = function (e) { + for (var touch of e.changedTouches) { + if (touch.identifier === this.identifier) { + dragend.call(this); + return; + } + } + }; + + var dragend = function () { + if (this.isTouching) { + $$1.off(d$1, 'touchmove', this.move); + $$1.off(d$1, 'touchend touchcancel', this.up); + } else { // mouseup + $$1.off(d$1, 'mousemove', this.move); + $$1.off(d$1, 'mouseup', this.up); + } + return $$1.set(`${this.id}.position`, this.style.cssText); + }; + + const hoverstart = function ({ root, el, latestEvent, endEvents, height, width, cb, noRemove }) { + const rect = root.getBoundingClientRect(); + const o = { + root, + el, + style: el.style, + isImage: ['IMG', 'VIDEO'].includes(el.nodeName), + cb, + endEvents, + latestEvent, + clientHeight: doc$1.clientHeight, + clientWidth: doc$1.clientWidth, + height, + width, + noRemove, + clientX: (rect.left + rect.right) / 2, + clientY: (rect.top + rect.bottom) / 2 + }; + o.hover = hover.bind(o); + o.hoverend = hoverend.bind(o); + + o.hover(o.latestEvent); + new MutationObserver(function() { + if (el.parentNode) { return o.hover(o.latestEvent); } + }).observe(el, {childList: true}); + + $$1.on(root, endEvents, o.hoverend); + if ($$1.x('ancestor::div[contains(@class,"inline")][1]', root)) { + $$1.on(d$1, 'keydown', o.hoverend); + } + $$1.on(root, 'mousemove', o.hover); + + // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=674955 + o.workaround = function(e) { if (!root.contains(e.target)) { return o.hoverend(e); } }; + return $$1.on(doc$1, 'mousemove', o.workaround); + }; + + hoverstart.padding = 25; + + var hover = function (e) { + this.latestEvent = e; + const height = (this.height || this.el.offsetHeight) + hoverstart.padding; + const width = (this.width || this.el.offsetWidth); + const {clientX, clientY} = Conf['Follow Cursor'] ? e : this; + + const top = this.isImage ? + Math.max(0, (clientY * (this.clientHeight - height)) / this.clientHeight) + : + Math.max(0, Math.min(this.clientHeight - height, clientY - 120)); + + let threshold = this.clientWidth / 2; + if (!this.isImage) { threshold = Math.max(threshold, this.clientWidth - 400); } + let marginX = (clientX <= threshold ? clientX : this.clientWidth - clientX) + 45; + if (this.isImage) { marginX = Math.min(marginX, this.clientWidth - width); } + marginX += 'px'; + const [left, right] = Array.from(clientX <= threshold ? [marginX, ''] : ['', marginX]); + + const {style} = this; + style.top = top + 'px'; + style.left = left; + return style.right = right; + }; + + var hoverend = function (e) { + if (((e.type === 'keydown') && (e.keyCode !== 13)) || (e.target.nodeName === "TEXTAREA")) { return; } + if (!this.noRemove) { $$1.rm(this.el); } + $$1.off(this.root, this.endEvents, this.hoverend); + $$1.off(d$1, 'keydown', this.hoverend); + $$1.off(this.root, 'mousemove', this.hover); + // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=674955 + $$1.off(doc$1, 'mousemove', this.workaround); + if (this.cb) { return this.cb.call(this); } + }; + + const checkbox = function (name, text, checked) { + if (checked == null) { checked = Conf[name]; } + const label = $$1.el('label'); + const input = $$1.el('input', {type: 'checkbox', name, checked}); + $$1.add(label, [input, $$1.tn(` ${text}`)]); + return label; + }; + + const UI = { + dialog, + Menu: Menu$1, + hover: hoverstart, + checkbox + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Nav = { + init() { + switch (g.VIEW) { + case 'index': + if (!Conf['Index Navigation']) { return; } + break; + case 'thread': + if (!Conf['Reply Navigation']) { return; } + break; + default: + return; + } + + const span = $$1.el('span', + {id: 'navlinks'}); + const prev = $$1.el('a', { + textContent: '▲', + href: 'javascript:;' + } + ); + const next = $$1.el('a', { + textContent: '▼', + href: 'javascript:;' + } + ); + + $$1.on(prev, 'click', this.prev); + $$1.on(next, 'click', this.next); + + $$1.add(span, [prev, $$1.tn(' '), next]); + var append = function() { + $$1.off(d$1, '4chanXInitFinished', append); + return $$1.add(d$1.body, span); + }; + return $$1.on(d$1, '4chanXInitFinished', append); + }, + + prev() { + if (g.VIEW === 'thread') { + return window.scrollTo(0, 0); + } else { + return Nav.scroll(-1); + } + }, + + next() { + if (g.VIEW === 'thread') { + return window.scrollTo(0, d$1.body.scrollHeight); + } else { + return Nav.scroll(+1); + } + }, + + getThread() { + if (g.VIEW === 'thread') { return g.threads.get(`${g.BOARD}.${g.THREADID}`).nodes.root; } + if ($$1.hasClass(doc$1, 'catalog-mode')) { return; } + for (var threadRoot of $$(g.SITE.selectors.thread)) { + var thread = Get$1.threadFromRoot(threadRoot); + if (thread.isHidden && !thread.stub) { continue; } + if (Header$1.getTopOf(threadRoot) >= -threadRoot.getBoundingClientRect().height) { // not scrolled past + return threadRoot; + } + } + }, + + scroll(delta) { + let next; + d$1.activeElement?.blur(); + let thread = Nav.getThread(); + if (!thread) { return; } + const axis = delta === +1 ? + 'following' + : + 'preceding'; + if (next = $$1.x(`${axis}-sibling::${g.SITE.xpath.thread}[not(@hidden)][1]`, thread)) { + // Unless we're not at the beginning of the current thread, + // and thus wanting to move to beginning, + // or we're above the first thread and don't want to skip it. + const top = Header$1.getTopOf(thread); + if (((delta === +1) && (top < 5)) || ((delta === -1) && (top > -5))) { thread = next; } + } + // Add extra space to the end of the page if necessary so that all threads can be selected by keybinds. + const extra = (Header$1.getTopOf(thread) + doc$1.clientHeight) - d$1.body.getBoundingClientRect().bottom; + if (extra > 0) { d$1.body.style.marginBottom = `${extra}px`; } + + Header$1.scrollTo(thread); + + if ((extra > 0) && !Nav.haveExtra) { + Nav.haveExtra = true; + return $$1.on(d$1, 'scroll', Nav.removeExtra); + } + }, + + removeExtra() { + const extra = doc$1.clientHeight - d$1.body.getBoundingClientRect().bottom; + if (extra > 0) { + return d$1.body.style.marginBottom = `${extra}px`; + } else { + d$1.body.style.marginBottom = ''; + delete Nav.haveExtra; + return $$1.off(d$1, 'scroll', Nav.removeExtra); + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ImageHost = { + init() { + if ((!(this.useFaster = /\S/.test(Conf['fourchanImageHost']))) || (g.SITE.software !== 'yotsuba') || !['index', 'thread'].includes(g.VIEW)) { return; } + return Callbacks.Post.push({ + name: 'Image Host Rewriting', + cb: this.node + }); + }, + + suggestions: ['i.4cdn.org', 'is2.4chan.org'], + + host() { + return Conf['fourchanImageHost'].trim() || 'i.4cdn.org'; + }, + flashHost() { + return 'i.4cdn.org'; + }, + thumbHost() { + return 'i.4cdn.org'; + }, + test(hostname) { + return (hostname === 'i.4cdn.org') || ImageHost.regex.test(hostname); + }, + + regex: /^is\d*\.4chan(?:nel)?\.org$/, + + node() { + if (this.isClone) { return; } + const host = ImageHost.host(); + if (this.file && ImageHost.test(this.file.url.split('/')[2]) && !/\.swf$/.test(this.file.url)) { + this.file.link.hostname = host; + if (this.file.thumbLink) { this.file.thumbLink.hostname = host; } + this.file.url = this.file.link.href; + } + return ImageHost.fixLinks($$('a', this.nodes.comment)); + }, + + fixLinks(links) { + for (var link of links) { + if (ImageHost.test(link.hostname) && !/\.swf$/.test(link.pathname)) { + var host = ImageHost.host(); + if (link.hostname !== host) { link.hostname = host; } + } + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Volume = { + init() { + if (!['index', 'thread'].includes(g.VIEW) || + (!Conf['Image Expansion'] && !Conf['Image Hover'] && !Conf['Image Hover in Catalog'] && !Conf['Gallery'])) { return; } + + $$1.sync('Allow Sound', function(x) { + Conf['Allow Sound'] = x; + if (Volume.inputs) Volume.inputs.unmute.checked = x; + }); + + $$1.sync('Default Volume', function(x) { + Conf['Default Volume'] = x; + if (Volume.inputs) Volume.inputs.volume.value = x; + }); + + if (Conf['Mouse Wheel Volume']) { + Callbacks.Post.push({ + name: 'Mouse Wheel Volume', + cb: this.node + }); + } + + if (g.SITE.noAudio?.(g.BOARD)) { return; } + + if (Conf['Mouse Wheel Volume']) { + Callbacks.CatalogThread.push({ + name: 'Mouse Wheel Volume', + cb: this.catalogNode + }); + } + + const unmuteEntry = UI.checkbox('Allow Sound', 'Allow Sound'); + unmuteEntry.title = Config.main['Images and Videos']['Allow Sound'][1]; + + const volumeEntry = $$1.el('label', + {title: 'Default volume for videos.'}); + $$1.extend(volumeEntry, + {innerHTML: " Volume"}); + + this.inputs = { + unmute: unmuteEntry.firstElementChild, + volume: volumeEntry.firstElementChild + }; + + $$1.on(this.inputs.unmute, 'change', $$1.cb.checked); + $$1.on(this.inputs.volume, 'change', $$1.cb.value); + + Header$1.menu.addEntry({el: unmuteEntry, order: 200}); + return Header$1.menu.addEntry({el: volumeEntry, order: 201}); + }, + + setup(video) { + video.muted = !Conf['Allow Sound']; + video.volume = Conf['Default Volume']; + return $$1.on(video, 'volumechange', Volume.change); + }, + + change() { + const {muted, volume} = this; + const items = { + 'Allow Sound': !muted, + 'Default Volume': volume + }; + for (var key in items) { + var val = items[key]; + if (Conf[key] === val) { + delete items[key]; + } + } + $$1.set(items); + $$1.extend(Conf, items); + if (Volume.inputs) { + Volume.inputs.unmute.checked = !muted; + return Volume.inputs.volume.value = volume; + } + }, + + node() { + if (g.SITE.noAudio?.(this.board)) { return; } + for (var file of this.files) { + if (file.isVideo) { + if (file.thumb) { $$1.on(file.thumb, 'wheel', Volume.wheel.bind(Header$1.hover)); } + $$1.on(($$1('.file-info', file.text) || file.link), 'wheel', Volume.wheel.bind(file.thumbLink)); + } + } + }, + + catalogNode() { + const file = this.thread.OP.files[0]; + if (!file?.isVideo) { return; } + return $$1.on(this.nodes.thumb, 'wheel', Volume.wheel.bind(Header$1.hover)); + }, + + wheel(e) { + let el; + if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) { return; } + if (!(el = $$1('video:not([data-md5])', this))) { return; } + if (el.muted || !$$1.hasAudio(el)) { return; } + let volume = el.volume + 0.1; + if (e.deltaY < 0) { volume *= 1.1; } + if (e.deltaY > 0) { volume /= 1.1; } + el.volume = $$1.minmax(volume - 0.1, 0, 1); + return e.preventDefault(); + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS104: Avoid inline assignments + * DS204: Change includes calls to have a more natural evaluation order + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ImageCommon = { + // Pause and mute video in preparation for removing the element from the document. + pause(video) { + if (video.nodeName !== 'VIDEO') { return; } + video.pause(); + $$1.off(video, 'volumechange', Volume.change); + return video.muted = true; + }, + + rewind(el) { + if (el.nodeName === 'VIDEO') { + if (el.readyState >= el.HAVE_METADATA) { return el.currentTime = 0; } + } else if (/\.gif$/.test(el.src)) { + return $$1.queueTask(() => el.src = el.src); + } + }, + + pushCache(el) { + ImageCommon.cache = el; + return $$1.on(el, 'error', ImageCommon.cacheError); + }, + + popCache() { + const el = ImageCommon.cache; + $$1.off(el, 'error', ImageCommon.cacheError); + delete ImageCommon.cache; + return el; + }, + + cacheError() { + if (ImageCommon.cache === this) { return delete ImageCommon.cache; } + }, + + decodeError(file, fileObj) { + let message; + if (file.error?.code !== MediaError.MEDIA_ERR_DECODE) { return false; } + if (!(message = $$1('.warning', fileObj.thumb.parentNode))) { + message = $$1.el('div', {className: 'warning'}); + $$1.after(fileObj.thumb, message); + } + message.textContent = 'Error: Corrupt or unplayable video'; + return true; + }, + + isFromArchive(file) { + return (g.SITE.software === 'yotsuba') && !ImageHost.test(file.src.split('/')[2]); + }, + + error(file, post, fileObj, delay, cb) { + let timeoutID; + const src = fileObj.url.split('/'); + let url = null; + if ((g.SITE.software === 'yotsuba') && Conf['404 Redirect']) { + url = Redirect$1.to('file', { + boardID: post.board.ID, + filename: src[src.length - 1] + }); + } + if (!url || !Redirect$1.securityCheck(url)) { url = null; } + + if ((post.isDead || fileObj.isDead) && !ImageCommon.isFromArchive(file)) { return cb(url); } + + if (delay != null) { timeoutID = setTimeout((() => cb(url)), delay); } + if (post.isDead || fileObj.isDead) { return; } + const redirect = function() { + if (!ImageCommon.isFromArchive(file)) { + if (delay != null) { clearTimeout(timeoutID); } + return cb(url); + } + }; + + const threadJSON = g.SITE.urls.threadJSON?.(post); + if (!threadJSON) { return; } + var parseJSON = function(isArchiveURL) { + let needle, postObj; + if (this.status === 404) { + let archivedThreadJSON; + if (!isArchiveURL && (archivedThreadJSON = g.SITE.urls.archivedThreadJSON?.(post))) { + $$1.ajax(archivedThreadJSON, {onloadend() { return parseJSON.call(this, true); }}); + } else { + post.kill(!post.isClone, fileObj.index); + } + } + if (this.status !== 200) { return redirect(); } + for (postObj of this.response.posts) { + if (postObj.no === post.ID) { break; } + } + if (postObj.no !== post.ID) { + post.kill(); + return redirect(); + } else if ((needle = fileObj.docIndex, g.SITE.Build.parseJSON(postObj, post.board).filesDeleted.includes(needle))) { + post.kill(true); + return redirect(); + } else { + return url = fileObj.url; + } + }; + return $$1.ajax(threadJSON, {onloadend() { return parseJSON.call(this); }}); + }, + + // Add controls, but not until the mouse is moved over the video. + addControls(video) { + var handler = function() { + $$1.off(video, 'mouseover', handler); + // Hacky workaround for Firefox forever-loading bug for very short videos + const t = new Date().getTime(); + return $$1.asap((() => ($$1.engine !== 'gecko') || ((video.readyState >= 3) && (video.currentTime <= Math.max(0.1, (video.duration - 0.5)))) || (new Date().getTime() >= (t + 1000))), () => video.controls = true); + }; + return $$1.on(video, 'mouseover', handler); + }, + + // XXX Estimate whether clicks are on the video controls and should be ignored. + onControls(e) { + return (Conf['Show Controls'] && Conf['Click Passthrough'] && (e.target.nodeName === 'VIDEO')) || + (e.target.controls && ((e.target.getBoundingClientRect().bottom - e.clientY) < 35)); + }, + + download(e) { + if (this.protocol === 'blob:') { return true; } + e.preventDefault(); + const {href, download} = this; + return CrossOrigin$1.file(href, function(blob) { + if (blob) { + const a = $$1.el('a', { + href: URL.createObjectURL(blob), + download, + hidden: true + } + ); + $$1.add(d$1.body, a); + a.click(); + return $$1.rm(a); + } else { + return new Notice('warning', `Could not download ${href}`, 20); + } + }); + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ImageExpand = { + init() { + if (!(this.enabled = Conf['Image Expansion'] && ['index', 'thread'].includes(g.VIEW))) { return; } + + this.EAI = $$1.el('a', { + className: 'expand-all-shortcut', + textContent: '➕︎', + title: 'Expand All Images', + href: 'javascript:;' + } + ); + + $$1.on(this.EAI, 'click', this.cb.toggleAll); + Header$1.addShortcut('expand-all', this.EAI, 520); + $$1.on(d$1, 'scroll visibilitychange', this.cb.playVideos); + this.videoControls = $$1.el('span', {className: 'video-controls'}); + $$1.extend(this.videoControls, {innerHTML: " contract"}); + + return Callbacks.Post.push({ + name: 'Image Expansion', + cb: this.node + }); + }, + + node() { + if (!this.file || (!this.file.isImage && !this.file.isVideo)) { return; } + $$1.on(this.file.thumbLink, 'click', ImageExpand.cb.toggle); + + if (this.isClone) { + if (this.file.isExpanding) { + // If we clone a post where the image is still loading, + // make it loading in the clone too. + ImageExpand.contract(this); + return ImageExpand.expand(this); + + } else if (this.file.isExpanded && this.file.isVideo) { + Volume.setup(this.file.fullImage); + ImageExpand.setupVideoCB(this); + return ImageExpand.setupVideo(this, !this.origin.file.fullImage?.paused || this.origin.file.wasPlaying, this.file.fullImage.controls); + } + + } else if (ImageExpand.on && !this.isHidden && !this.isFetchedQuote && + (Conf['Expand spoilers'] || !this.file.isSpoiler) && + (Conf['Expand videos'] || !this.file.isVideo)) { + return ImageExpand.expand(this); + } + }, + + cb: { + toggle(e) { + if ($$1.modifiedClick(e)) { return; } + const post = Get$1.postFromNode(this); + const {file} = post; + if (file.isExpanded && ImageCommon.onControls(e)) { return; } + e.preventDefault(); + if (!Conf['Autoplay'] && file.fullImage?.paused) { + return file.fullImage.play(); + } else { + return ImageExpand.toggle(post); + } + }, + + toggleAll() { + let func; + $$1.event('CloseMenu'); + const threadRoot = Nav.getThread(); + const toggle = function(post) { + const {file} = post; + if (!file || (!file.isImage && !file.isVideo) || !doc$1.contains(post.nodes.root)) { return; } + if (ImageExpand.on && + ((!Conf['Expand spoilers'] && file.isSpoiler) || + (!Conf['Expand videos'] && file.isVideo) || + (Conf['Expand from here'] && (Header$1.getTopOf(file.thumb) < 0)) || + (Conf['Expand thread only'] && (g.VIEW === 'index') && !threadRoot?.contains(file.thumb)))) { + return; + } + return $$1.queueTask(func, post); + }; + + if (ImageExpand.on = $$1.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) { + ImageExpand.EAI.className = 'contract-all-shortcut'; + ImageExpand.EAI.title = 'Contract All Images'; + ImageExpand.EAI.textContent = '➖︎'; + func = ImageExpand.expand; + } else { + ImageExpand.EAI.className = 'expand-all-shortcut'; + ImageExpand.EAI.title = 'Expand All Images'; + ImageExpand.EAI.textContent = '➕︎'; + func = ImageExpand.contract; + } + + return g.posts.forEach(function(post) { + for (post of [post, ...Array.from(post.clones)]) { toggle(post); } + }); + }, + + playVideos() { + return g.posts.forEach(function(post) { + for (post of [post, ...Array.from(post.clones)]) { + var {file} = post; + if (!file || !file.isVideo || !file.isExpanded) { continue; } + + var video = file.fullImage; + var visible = ($$1.hasAudio(video) && !video.muted) || Header$1.isNodeVisible(video); + if (visible && file.wasPlaying) { + delete file.wasPlaying; + video.play(); + } else if (!visible && !video.paused) { + file.wasPlaying = true; + video.pause(); + } + } + }); + }, + + setFitness() { + return $$1[this.checked ? 'addClass' : 'rmClass'](doc$1, this.name.toLowerCase().replace(/\s+/g, '-')); + } + }, + + toggle(post) { + if (!post.file.isExpanding && !post.file.isExpanded) { + post.file.scrollIntoView = Conf['Scroll into view']; + ImageExpand.expand(post); + return; + } + + ImageExpand.contract(post); + + if (Conf['Advance on contract']) { + let next = post.nodes.root; + while ((next = $$1.x("following::div[contains(@class,'postContainer')][1]", next))) { + if (!$$1('.stub', next) && (next.offsetHeight !== 0)) { break; } + } + if (next) { + return Header$1.scrollTo(next); + } + } + }, + + contract(post) { + let bottom, el, oldHeight, scrollY; + const {file} = post; + + if (el = file.fullImage) { + const top = Header$1.getTopOf(el); + bottom = top + el.getBoundingClientRect().height; + oldHeight = d$1.body.clientHeight; + ({scrollY} = window); + } + + $$1.rmClass(post.nodes.root, 'expanded-image'); + $$1.rmClass(file.thumb, 'expanding'); + $$1.rm(file.videoControls); + file.thumbLink.href = file.url; + file.thumbLink.target = '_blank'; + for (var x of ['isExpanding', 'isExpanded', 'videoControls', 'wasPlaying', 'scrollIntoView']) { + delete file[x]; + } + + if (!el) { return; } + + if (doc$1.contains(el)) { + if (bottom <= 0) { + // For images entirely above us, scroll to remain in place. + window.scrollBy(0, ((scrollY - window.scrollY) + d$1.body.clientHeight) - oldHeight); + } else { + // For images not above us that would be moved above us, scroll to the thumbnail. + Header$1.scrollToIfNeeded(post.nodes.root); + } + if (window.scrollX > 0) { + // If we have scrolled right viewing an expanded image, return to the left. + window.scrollBy(-window.scrollX, 0); + } + } + + $$1.off(el, 'error', ImageExpand.error); + ImageCommon.pushCache(el); + if (file.isVideo) { + ImageCommon.pause(el); + for (var eventName in ImageExpand.videoCB) { + var cb = ImageExpand.videoCB[eventName]; + $$1.off(el, eventName, cb); + } + } + if (Conf['Restart when Opened']) { ImageCommon.rewind(file.thumb); } + delete file.fullImage; + return $$1.queueTask(function() { + // XXX Work around Chrome/Chromium not firing mouseover on the thumbnail. + if (file.isExpanding || file.isExpanded) { return; } + $$1.rmClass(el, 'full-image'); + if (el.id) { return; } + return $$1.rm(el); + }); + }, + + expand(post, src) { + // Do not expand images of hidden/filtered replies, or already expanded pictures. + let el; + const {file} = post; + const {thumb, thumbLink, isVideo} = file; + if (post.isHidden || file.isExpanding || file.isExpanded) { return; } + + $$1.addClass(thumb, 'expanding'); + file.isExpanding = true; + + if (file.fullImage) { + el = file.fullImage; + } else if (ImageCommon.cache?.dataset.fileID === `${post.fullID}.${file.index}`) { + el = (file.fullImage = ImageCommon.popCache()); + $$1.on(el, 'error', ImageExpand.error); + if (Conf['Restart when Opened'] && (el.id !== 'ihover')) { ImageCommon.rewind(el); } + el.removeAttribute('id'); + } else { + el = (file.fullImage = $$1.el((isVideo ? 'video' : 'img'))); + el.dataset.fileID = `${post.fullID}.${file.index}`; + $$1.on(el, 'error', ImageExpand.error); + el.src = src || file.url; + } + + el.className = 'full-image'; + $$1.after(thumb, el); + + if (isVideo) { + // add contract link to file info + if (!file.videoControls) { + file.videoControls = ImageExpand.videoControls.cloneNode(true); + $$1.add(file.text, file.videoControls); + } + + // disable link to file so native controls can work + thumbLink.removeAttribute('href'); + thumbLink.removeAttribute('target'); + + el.loop = true; + Volume.setup(el); + ImageExpand.setupVideoCB(post); + } + + if (!isVideo) { + return $$1.asap((() => el.naturalHeight), () => ImageExpand.completeExpand(post)); + } else if (el.readyState >= el.HAVE_METADATA) { + return ImageExpand.completeExpand(post); + } else { + return $$1.on(el, 'loadedmetadata', () => ImageExpand.completeExpand(post)); + } + }, + + completeExpand(post) { + const {file} = post; + if (!file.isExpanding) { return; } // contracted before the image loaded + + const bottom = Header$1.getTopOf(file.thumb) + file.thumb.getBoundingClientRect().height; + const oldHeight = d$1.body.clientHeight; + const {scrollY} = window; + + $$1.addClass(post.nodes.root, 'expanded-image'); + $$1.rmClass(file.thumb, 'expanding'); + file.isExpanded = true; + delete file.isExpanding; + + // Scroll to keep our place in the thread when images are expanded above us. + if (doc$1.contains(post.nodes.root) && (bottom <= 0)) { + window.scrollBy(0, ((scrollY - window.scrollY) + d$1.body.clientHeight) - oldHeight); + } + + // Scroll to display full image. + if (file.scrollIntoView) { + delete file.scrollIntoView; + const imageBottom = Math.min(doc$1.clientHeight - file.fullImage.getBoundingClientRect().bottom - 25, Header$1.getBottomOf(file.fullImage)); + if (imageBottom < 0) { + window.scrollBy(0, Math.min(-imageBottom, Header$1.getTopOf(file.fullImage))); + } + } + + if (file.isVideo) { + return ImageExpand.setupVideo(post, Conf['Autoplay'], Conf['Show Controls']); + } + }, + + setupVideo(post, playing, controls) { + const {fullImage} = post.file; + if (!playing) { + fullImage.controls = controls; + return; + } + fullImage.controls = false; + $$1.asap((() => doc$1.contains(fullImage)), function() { + if (!d$1.hidden && Header$1.isNodeVisible(fullImage)) { + return fullImage.play(); + } else { + return post.file.wasPlaying = true; + } + }); + if (controls) { + return ImageCommon.addControls(fullImage); + } + }, + + videoCB: (function() { + // dragging to the left contracts the video + let mousedown = false; + return { + mouseover() { return mousedown = false; }, + mousedown(e) { if (e.button === 0) { return mousedown = true; } }, + mouseup(e) { if (e.button === 0) { return mousedown = false; } }, + mouseout(e) { if (((e.buttons & 1) || mousedown) && (e.clientX <= this.getBoundingClientRect().left)) { return ImageExpand.toggle(Get$1.postFromNode(this)); } } + }; + })(), + + setupVideoCB(post) { + for (var eventName in ImageExpand.videoCB) { + var cb = ImageExpand.videoCB[eventName]; + $$1.on(post.file.fullImage, eventName, cb); + } + if (post.file.videoControls) { + return $$1.on(post.file.videoControls.firstElementChild, 'click', () => ImageExpand.toggle(post)); + } + }, + + error() { + const post = Get$1.postFromNode(this); + $$1.rm(this); + delete post.file.fullImage; + // Images can error: + // - before the image started loading. + // - after the image started loading. + // Don't try to re-expand if it was already contracted. + if (!post.file.isExpanding && !post.file.isExpanded) { return; } + if (ImageCommon.decodeError(this, post.file)) { + return ImageExpand.contract(post); + } + // Don't autoretry images from the archive. + if (ImageCommon.isFromArchive(this)) { + return ImageExpand.contract(post); + } + return ImageCommon.error(this, post, post.file, 10 * SECOND, function(URL) { + if (post.file.isExpanding || post.file.isExpanded) { + ImageExpand.contract(post); + if (URL) { return ImageExpand.expand(post, URL); } + } + }); + }, + + menu: { + init() { + if (!ImageExpand.enabled) { return; } + + const el = $$1.el('span', { + textContent: 'Image Expansion', + className: 'image-expansion-link' + } + ); + + const {createSubEntry} = ImageExpand.menu; + const subEntries = []; + for (var name in Config.imageExpansion) { + var conf = Config.imageExpansion[name]; + subEntries.push(createSubEntry(name, conf[1])); + } + + return Header$1.menu.addEntry({ + el, + order: 105, + subEntries + }); + }, + + createSubEntry(name, desc) { + const label = UI.checkbox(name, name); + label.title = desc; + const input = label.firstElementChild; + if (['Fit width', 'Fit height'].includes(name)) { + $$1.on(input, 'change', ImageExpand.cb.setFitness); + } + $$1.event('change', null, input); + $$1.on(input, 'change', $$1.cb.checked); + return {el: label}; + } + } + }; + + class Post { + toString() { return this.ID; } + constructor(root, thread, board, flags = {}) { + // <% if (readJSON('/.tests_enabled')) { %> + // @normalizedOriginal = Test.normalize root + // <% } %> + // Skip initialization for PostClone + if (root === undefined && thread === undefined && board === undefined) + return; + this.root = root; + this.thread = thread; + this.board = board; + $$1.extend(this, flags); + this.ID = +root.id.match(/\d*$/)[0]; + this.postID = this.ID; + this.threadID = this.thread.ID; + this.boardID = this.board.ID; + this.siteID = g.SITE.ID; + this.fullID = `${this.board}.${this.ID}`; + this.context = this; + this.isReply = (this.ID !== this.threadID); + root.dataset.fullID = this.fullID; + this.nodes = this.parseNodes(root); + if (!this.isReply) { + this.thread.OP = this; + for (var key of ['isSticky', 'isClosed', 'isArchived']) { + var selector; + if (selector = g.SITE.selectors.icons[key]) { + this.thread[key] = !!$$1(selector, this.nodes.info); + } + } + if (this.thread.isArchived) { + this.thread.isClosed = true; + this.thread.kill(); + } + } + const name = this.nodes.name?.textContent; + const tripcode = this.nodes.tripcode?.textContent; + this.info = { + subject: this.nodes.subject?.textContent || undefined, + name, + email: this.nodes.email ? decodeURIComponent(this.nodes.email.href.replace(/^mailto:/, '')) : undefined, + tripcode, + 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 ? g.SITE.parseDate(this.nodes.date) : undefined, + nameBlock: Conf['Anonymize'] ? 'Anonymous' : `${name || ''} ${tripcode || ''}`.trim(), + }; + if (this.info.capcode) { + this.info.nameBlock += ` ## ${this.info.capcode}`; + } + if (this.info.uniqueID) { + this.info.nameBlock += ` (ID: ${this.info.uniqueID})`; + } + this.parseComment(); + this.parseQuotes(); + this.parseFiles(); + this.isDead = false; + this.isHidden = false; + this.clones = []; + // <% if (readJSON('/.tests_enabled')) { %> + // return if @forBuildTest + // <% } %> + if (g.posts.get(this.fullID)) { + this.isRebuilt = true; + this.clones = g.posts.get(this.fullID).clones; + for (var clone of this.clones) { + clone.origin = this; + } + } + if (!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); + g.posts.push(this.fullID, this); + this.isFetchedQuote = false; + this.isClone = false; + } + parseNodes(root) { + const s = g.SITE.selectors; + const post = $$1(s.post, root) || root; + const info = $$1(s.infoRoot, post); + const nodes = { + root, + bottom: this.isReply || !g.SITE.isOPContainerThread ? root : $$1(s.opBottom, root), + post, + info, + comment: $$1(s.comment, post), + quotelinks: [], + archivelinks: [], + embedlinks: [], + backlinks: post.getElementsByClassName('backlink'), + uniqueIDRoot: undefined, + uniqueID: undefined, + }; + for (var key in s.info) { + var selector = s.info[key]; + nodes[key] = $$1(selector, info); + } + g.SITE.parseNodes?.(this, nodes); + if (!nodes.uniqueIDRoot) { + nodes.uniqueIDRoot = nodes.uniqueID; + } + return nodes; + } + parseComment() { + // Merge text nodes and remove empty ones. + let bq; + this.nodes.comment.normalize(); + // Get the comment's text. + //
            -> \n + // Remove: + // 'Comment too long'... + // EXIF data. (/p/) + this.nodes.commentClean = (bq = this.nodes.comment.cloneNode(true)); + g.SITE.cleanComment?.(bq); + return this.info.comment = this.nodesToText(bq); + } + commentDisplay() { + // Get the comment's text for display purposes (e.g. notifications, excerpts). + // In addition to what's done in generating `@info.comment`, remove: + // Spoilers. (filter to '[spoiler]') + // Rolls. (/tg/, /qst/) + // Fortunes. (/s4s/) + // Preceding and following new lines. + // Trailing spaces. + const bq = this.nodes.commentClean.cloneNode(true); + if (!Conf['Remove Spoilers'] && !Conf['Reveal Spoilers']) { + this.cleanSpoilers(bq); + } + g.SITE.cleanCommentDisplay?.(bq); + return this.nodesToText(bq).trim().replace(/\s+$/gm, ''); + } + commentOrig() { + // Get the comment's text for reposting purposes. + const bq = this.nodes.commentClean.cloneNode(true); + g.SITE.insertTags?.(bq); + return this.nodesToText(bq); + } + nodesToText(bq) { + let node; + let text = ""; + const nodes = $$1.X('.//br|.//text()', bq); + let i = 0; + while ((node = nodes.snapshotItem(i++))) { + text += node.data || '\n'; + } + return text; + } + cleanSpoilers(bq) { + const spoilers = $$(g.SITE.selectors.spoiler, bq); + for (var node of spoilers) { + $$1.replace(node, $$1.tn('[spoiler]')); + } + } + parseQuotes() { + this.quotes = []; + for (var quotelink of $$(g.SITE.selectors.quotelink, this.nodes.comment)) { + this.parseQuote(quotelink); + } + } + parseQuote(quotelink) { + // Only add quotes that link to posts on an imageboard. + // Don't add: + // - board links. (>>>/b/) + // - catalog links. (>>>/b/catalog or >>>/b/search) + // - rules links. (>>>/a/rules) + // - text-board quotelinks. (>>>/img/1234) + const match = quotelink.href.match(g.SITE.regexp.quotelink); + if (!match && (!this.isClone || !quotelink.dataset.postID)) { + return; + } // normal or resurrected quote + this.nodes.quotelinks.push(quotelink); + if (this.isClone) { + return; + } + // ES6 Set when? + const fullID = `${match[1]}.${match[3]}`; + if (!this.quotes.includes(fullID)) + this.quotes.push(fullID); + } + parseFiles() { + let file; + this.files = []; + const fileRoots = this.fileRoots(); + let index = 0; + for (let docIndex = 0; docIndex < fileRoots.length; docIndex++) { + var fileRoot = fileRoots[docIndex]; + if (file = this.parseFile(fileRoot)) { + file.index = (index++); + file.docIndex = docIndex; + this.files.push(file); + } + } + if (this.files.length) { + return this.file = this.files[0]; + } + } + fileRoots() { + if (g.SITE.selectors.multifile) { + const roots = $$(g.SITE.selectors.multifile, this.nodes.root); + if (roots.length) { + return roots; + } + } + return [this.nodes.root]; + } + parseFile(fileRoot) { + const file = { isDead: false }; + for (var key in g.SITE.selectors.file) { + var selector = g.SITE.selectors.file[key]; + file[key] = $$1(selector, fileRoot); + } + file.thumbLink = file.thumb?.parentNode; + if (!(file.text && file.link)) { + return; + } + if (!g.SITE.parseFile(this, file)) { + return; + } + $$1.extend(file, { + url: file.link.href, + isImage: $$1.isImage(file.link.href), + isVideo: $$1.isVideo(file.link.href) + }); + let size = +file.size.match(/[\d.]+/)[0]; + let unit = ['B', 'KB', 'MB', 'GB'].indexOf(file.size.match(/\w+$/)[0]); + while (unit-- > 0) { + size *= 1024; + } + file.sizeInBytes = size; + return file; + } + kill(file, index = 0) { + let strong; + if (file) { + if (this.isDead || this.files[index].isDead) { + return; + } + this.files[index].isDead = true; + $$1.addClass(this.nodes.root, 'deleted-file'); + } + else { + if (this.isDead) { + return; + } + this.isDead = true; + $$1.rmClass(this.nodes.root, 'deleted-file'); + $$1.addClass(this.nodes.root, 'deleted-post'); + } + if (!(strong = $$1('strong.warning', this.nodes.info))) { + strong = $$1.el('strong', { className: 'warning' }); + $$1.after($$1('input', this.nodes.info), strong); + } + strong.textContent = file ? '[File deleted]' : '[Deleted]'; + if (this.isClone) { + return; + } + for (var clone of this.clones) { + clone.kill(file, index); + } + if (file) { + return; + } + // Get quotelinks/backlinks to this post + // and paint them (Dead). + for (var quotelink of Get$1.allQuotelinksLinkingTo(this)) { + if (!$$1.hasClass(quotelink, 'deadlink')) { + $$1.add(quotelink, Post.deadMark.cloneNode(true)); + $$1.addClass(quotelink, 'deadlink'); + } + } + } + // XXX Workaround for 4chan's racing condition + // giving us false-positive dead posts. + resurrect() { + this.isDead = false; + $$1.rmClass(this.nodes.root, 'deleted-post'); + const strong = $$1('strong.warning', this.nodes.info); + // no false-positive files + if (this.files.some(file => file.isDead)) { + $$1.addClass(this.nodes.root, 'deleted-file'); + strong.textContent = '[File deleted]'; + } + else { + $$1.rm(strong); + } + if (this.isClone) { + return; + } + for (var clone of this.clones) { + clone.resurrect(); + } + for (var quotelink of Get$1.allQuotelinksLinkingTo(this)) { + if ($$1.hasClass(quotelink, 'deadlink')) { + $$1.rm($$1('.qmark-dead', quotelink)); + $$1.rmClass(quotelink, 'deadlink'); + } + } + } + collect() { + g.posts.rm(this.fullID); + this.thread.posts.rm(this); + this.board.posts.rm(this); + } + addClone(context, contractThumb) { + // Callbacks may not have been run yet due to anti-browser-lock delay in Main.callbackNodesDB. + Callbacks.Post.execute(this); + return new PostClone(this, context, contractThumb); + } + rmClone(index) { + this.clones.splice(index, 1); + for (var clone of this.clones.slice(index)) { + clone.nodes.root.dataset.clone = index++; + } + } + setCatalogOP(isCatalogOP) { + this.nodes.root.classList.toggle('catalog-container', isCatalogOP); + this.nodes.root.classList.toggle('opContainer', !isCatalogOP); + this.nodes.post.classList.toggle('catalog-post', isCatalogOP); + this.nodes.post.classList.toggle('op', !isCatalogOP); + this.nodes.post.style.left = (this.nodes.post.style.right = null); + } + } + // because of a circular dependency $ might not be initialized, so we can't use $.el + Post.deadMark = (() => { + const el = document.createElement('span'); + // \u00A0 is nbsp + el.textContent = '\u00A0(Dead)'; + el.className = 'qmark-dead'; + return el; + })(); + class PostClone extends Post { + constructor(origin, context, contractThumb) { + super(); + this.isClone = true; + let file, fileRoots, key; + this.origin = origin; + this.context = context; + for (key of ['ID', 'postID', 'threadID', 'boardID', 'siteID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply']) { + // Copy or point to the origin's key value. + this[key] = this.origin[key]; + } + const { nodes } = this.origin; + const root = contractThumb ? this.cloneWithoutVideo(nodes.root) : nodes.root.cloneNode(true); + for (var node of [root, ...$$('[id]', root)]) { + node.id += `_${PostClone.suffix}`; + } + PostClone.suffix++; + // Remove inlined posts inside of this post. + for (var inline of $$('.inline', root)) { + $$1.rm(inline); + } + for (var inlined of $$('.inlined', root)) { + $$1.rmClass(inlined, 'inlined'); + } + this.nodes = this.parseNodes(root); + root.hidden = false; // post hiding + $$1.rmClass(root, 'forwarded'); // quote inlining + $$1.rmClass(this.nodes.post, 'highlight'); // keybind navigation, ID highlighting + // Remove catalog stuff. + if (!this.isReply) { + this.setCatalogOP(false); + $$1.rm($$1('.catalog-link', this.nodes.post)); + $$1.rm($$1('.catalog-stats', this.nodes.post)); + $$1.rm($$1('.catalog-replies', this.nodes.post)); + } + this.parseQuotes(); + this.quotes = [...this.origin.quotes]; + this.files = []; + if (this.origin.files.length) { + fileRoots = this.fileRoots(); + } + for (var originFile of this.origin.files) { + // Copy values, point to relevant elements. + file = { ...originFile }; + var fileRoot = fileRoots[file.docIndex]; + for (key in g.SITE.selectors.file) { + var selector = g.SITE.selectors.file[key]; + file[key] = $$1(selector, fileRoot); + } + file.thumbLink = file.thumb?.parentNode; + if (file.thumbLink) { + file.fullImage = $$1('.full-image', file.thumbLink); + } + file.videoControls = $$1('.video-controls', file.text); + if (file.videoThumb) { + file.thumb.muted = true; + } + this.files.push(file); + } + if (this.files.length) { + this.file = this.files[0]; + // Contract thumbnails in quote preview + if (this.file.thumb && contractThumb) { + ImageExpand.contract(this); + } + } + if (this.origin.isDead) { + this.isDead = true; + } + root.dataset.clone = this.origin.clones.push(this) - 1; + return this; + } + cloneWithoutVideo(node) { + if ((node.tagName === 'VIDEO') && !node.dataset.md5) { // (exception for WebM thumbnails) + return []; + } + else if ((node.nodeType === Node.ELEMENT_NODE) && $$1('video', node)) { + const clone = node.cloneNode(false); + for (var child of node.childNodes) { + $$1.add(clone, this.cloneWithoutVideo(child)); + } + return clone; + } + else { + return node.cloneNode(true); + } + } + } + PostClone.suffix = 0; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Menu = { + init() { + if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu']) { return; } + + this.button = $$1.el('a', { + className: 'menu-button', + href: 'javascript:;' + } + ); + + $$1.extend(this.button, {textContent: "🞃"}); + + this.menu = new UI.Menu('post'); + Callbacks.Post.push({ + name: 'Menu', + cb: this.node + }); + + return Callbacks.CatalogThread.push({ + name: 'Menu', + cb: this.catalogNode + }); + }, + + node() { + if (this.isClone) { + const button = $$1('.menu-button', this.nodes.info); + $$1.rmClass(button, 'active'); + $$1.rm($$1('.dialog', this.nodes.info)); + Menu.makeButton(this, button); + return; + } + return $$1.add(this.nodes.info, Menu.makeButton(this)); + }, + + catalogNode() { + return $$1.after(this.nodes.icons, Menu.makeButton(this.thread.OP)); + }, + + makeButton(post, button) { + if (!button) { button = Menu.button.cloneNode(true); } + $$1.on(button, 'click', function(e) { + return Menu.menu.toggle(e, this, post); + }); + return button; + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Recursive = { + recursives: dict(), + init() { + if (!['index', 'thread'].includes(g.VIEW)) { return; } + return Callbacks.Post.push({ + name: 'Recursive', + cb: this.node + }); + }, + + node() { + if (this.isClone || this.isFetchedQuote) { return; } + for (var quote of this.quotes) { + var obj; + if ((obj = Recursive.recursives[quote])) { + for (var i = 0; i < obj.recursives.length; i++) { + var recursive = obj.recursives[i]; + recursive(this, ...Array.from(obj.args[i])); + } + } + } + }, + + add(recursive, post, ...args) { + const obj = Recursive.recursives[post.fullID] || (Recursive.recursives[post.fullID] = { + recursives: [], + args: [] + }); + obj.recursives.push(recursive); + return obj.args.push(args); + }, + + rm(recursive, post) { + let obj; + if (!(obj = Recursive.recursives[post.fullID])) { return; } + for (let i = 0; i < obj.recursives.length; i++) { + var rec = obj.recursives[i]; + if (rec === recursive) { + obj.recursives.splice(i, 1); + obj.args.splice(i, 1); + } + } + }, + + apply(recursive, post, ...args) { + const {fullID} = post; + return g.posts.forEach(function(post) { + if (post.quotes.includes(fullID)) { + return recursive(post, ...Array.from(args)); + } + }); + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var PostHiding = { + init() { + if (!['index', 'thread'].includes(g.VIEW) || (!Conf['Reply Hiding Buttons'] && !(Conf['Menu'] && Conf['Reply Hiding Link']))) { return; } + + if (Conf['Reply Hiding Buttons']) { + $$1.addClass(doc$1, "reply-hide"); + } + + this.db = new DataBoard('hiddenPosts'); + return Callbacks.Post.push({ + name: 'Reply Hiding', + cb: this.node + }); + }, + + isHidden(boardID, threadID, postID) { + return !!(PostHiding.db && PostHiding.db.get({boardID, threadID, postID})); + }, + + node() { + let data, sa; + if (!this.isReply || this.isClone || this.isFetchedQuote) { return; } + + if (data = PostHiding.db.get({boardID: this.board.ID, threadID: this.thread.ID, postID: this.ID})) { + if (data.thisPost) { + PostHiding.hide(this, data.makeStub, data.hideRecursively); + } else { + Recursive.apply(PostHiding.hide, this, data.makeStub, true); + Recursive.add(PostHiding.hide, this, data.makeStub, true); + } + } + + if (!Conf['Reply Hiding Buttons']) { return; } + + const button = PostHiding.makeButton(this, 'hide'); + if (sa = g.SITE.selectors.sideArrows) { + const sideArrows = $$1(sa, this.nodes.root); + $$1.replace(sideArrows.firstChild, button); + return sideArrows.className = 'replacedSideArrows'; + } else { + return $$1.prepend(this.nodes.info, button); + } + }, + + menu: { + init() { + if (!['index', 'thread'].includes(g.VIEW) || !Conf['Menu'] || !Conf['Reply Hiding Link']) { return; } + + // Hide + let div = $$1.el('div', { + className: 'hide-reply-link', + textContent: 'Hide' + } + ); + + let apply = $$1.el('a', { + textContent: 'Apply', + href: 'javascript:;' + } + ); + $$1.on(apply, 'click', PostHiding.menu.hide); + + let thisPost = UI.checkbox('thisPost', 'This post', true); + let replies = UI.checkbox('replies', 'Hide replies', Conf['Recursive Hiding']); + const makeStub = UI.checkbox('makeStub', 'Make stub', Conf['Stubs']); + + Menu.menu.addEntry({ + el: div, + order: 20, + open(post) { + if (!post.isReply || post.isClone || post.isHidden) { + return false; + } + PostHiding.menu.post = post; + return true; + }, + subEntries: [ + {el: apply} + , + {el: thisPost} + , + {el: replies} + , + {el: makeStub} + ]}); + + // Show + div = $$1.el('div', { + className: 'show-reply-link', + textContent: 'Show' + } + ); + + apply = $$1.el('a', { + textContent: 'Apply', + href: 'javascript:;' + } + ); + $$1.on(apply, 'click', PostHiding.menu.show); + + thisPost = UI.checkbox('thisPost', 'This post', false); + replies = UI.checkbox('replies', 'Show replies', false); + const hideStubLink = $$1.el('a', { + textContent: 'Hide stub', + href: 'javascript:;' + } + ); + $$1.on(hideStubLink, 'click', PostHiding.menu.hideStub); + + Menu.menu.addEntry({ + el: div, + order: 20, + open(post) { + let data; + if (!post.isReply || post.isClone || !post.isHidden) { + return false; + } + if (!(data = PostHiding.db.get({boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID}))) { + return false; + } + PostHiding.menu.post = post; + thisPost.firstChild.checked = post.isHidden; + replies.firstChild.checked = (data?.hideRecursively != null) ? data.hideRecursively : Conf['Recursive Hiding']; + return true; + }, + subEntries: [ + {el: apply} + , + {el: thisPost} + , + {el: replies} + ]}); + + return Menu.menu.addEntry({ + el: hideStubLink, + order: 15, + open(post) { + if (!post.isReply || post.isClone || !post.isHidden) { + return false; + } + if (!(PostHiding.db.get({boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID}))) { + return false; + } + return PostHiding.menu.post = post; + } + }); + }, + + hide() { + const parent = this.parentNode; + const thisPost = $$1('input[name=thisPost]', parent).checked; + const replies = $$1('input[name=replies]', parent).checked; + const makeStub = $$1('input[name=makeStub]', parent).checked; + const {post} = PostHiding.menu; + if (thisPost) { + PostHiding.hide(post, makeStub, replies); + } else if (replies) { + Recursive.apply(PostHiding.hide, post, makeStub, true); + Recursive.add(PostHiding.hide, post, makeStub, true); + } else { + return; + } + PostHiding.saveHiddenState(post, true, thisPost, makeStub, replies); + return $$1.event('CloseMenu'); + }, + + show() { + let data; + const parent = this.parentNode; + const thisPost = $$1('input[name=thisPost]', parent).checked; + const replies = $$1('input[name=replies]', parent).checked; + const {post} = PostHiding.menu; + if (thisPost) { + PostHiding.show(post, replies); + } else if (replies) { + Recursive.apply(PostHiding.show, post, true); + Recursive.rm(PostHiding.hide, post, true); + } else { + return; + } + if (data = PostHiding.db.get({boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID})) { + PostHiding.saveHiddenState(post, !(thisPost && replies), !thisPost, data.makeStub, !replies); + } + return $$1.event('CloseMenu'); + }, + hideStub() { + let data; + const {post} = PostHiding.menu; + if (data = PostHiding.db.get({boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID})) { + PostHiding.show(post, data.hideRecursively); + PostHiding.hide(post, false, data.hideRecursively); + PostHiding.saveHiddenState(post, true, true, false, data.hideRecursively); + } + $$1.event('CloseMenu'); + } + }, + + makeButton(post, type) { + const span = $$1.el('span', { + textContent: type === 'hide' ? '➖︎' : '➕︎', + }); + const a = $$1.el('a', { + className: `${type}-reply-button`, + href: 'javascript:;' + } + ); + $$1.add(a, span); + $$1.on(a, 'click', PostHiding.toggle); + return a; + }, + + saveHiddenState(post, isHiding, thisPost, makeStub, hideRecursively) { + const data = { + boardID: post.board.ID, + threadID: post.thread.ID, + postID: post.ID + }; + if (isHiding) { + data.val = { + thisPost: thisPost !== false, // undefined -> true + makeStub, + hideRecursively + }; + return PostHiding.db.set(data); + } else { + return PostHiding.db.delete(data); + } + }, + + toggle() { + const post = Get$1.postFromNode(this); + PostHiding[(post.isHidden ? 'show' : 'hide')](post); + return PostHiding.saveHiddenState(post, post.isHidden); + }, + + hide(post, makeStub=Conf['Stubs'], hideRecursively=Conf['Recursive Hiding']) { + if (post.isHidden) { return; } + post.isHidden = true; + + if (hideRecursively) { + Recursive.apply(PostHiding.hide, post, makeStub, true); + Recursive.add(PostHiding.hide, post, makeStub, true); + } + + for (var quotelink of Get$1.allQuotelinksLinkingTo(post)) { + $$1.addClass(quotelink, 'filtered'); + } + + if (!makeStub) { + post.nodes.root.hidden = true; + return; + } + + const a = PostHiding.makeButton(post, 'show'); + $$1.add(a, $$1.tn(` ${post.info.nameBlock}`)); + post.nodes.stub = $$1.el('div', + {className: 'stub'}); + $$1.add(post.nodes.stub, a); + if (Conf['Menu']) { + $$1.add(post.nodes.stub, Menu.makeButton(post)); + } + return $$1.prepend(post.nodes.root, post.nodes.stub); + }, + + show(post, showRecursively=Conf['Recursive Hiding']) { + if (post.nodes.stub) { + $$1.rm(post.nodes.stub); + delete post.nodes.stub; + } else { + post.nodes.root.hidden = false; + } + post.isHidden = false; + if (showRecursively) { + Recursive.apply(PostHiding.show, post, true); + Recursive.rm(PostHiding.hide, post); + } + for (var quotelink of Get$1.allQuotelinksLinkingTo(post)) { + $$1.rmClass(quotelink, 'filtered'); + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var RelativeDates = { + INTERVAL: 30000, + + init() { + if ( + (['index', 'thread', 'archive'].includes(g.VIEW) && Conf['Relative Post Dates'] && !Conf['Relative Date Title']) || + Index$1.enabled + ) { + this.flush(); + $$1.on(d$1, 'visibilitychange PostsInserted', this.flush); + } + + if (Conf['Relative Post Dates']) { + return Callbacks.Post.push({ + name: 'Relative Post Dates', + cb: this.node + }); + } + }, + + node() { + if (!this.info.date) { return; } + const dateEl = this.nodes.date; + if (Conf['Relative Date Title']) { + $$1.on(dateEl, 'mouseover', () => RelativeDates.hover(this)); + return; + } + if (this.isClone) { return; } + + // Show original absolute time as tooltip so users can still know exact times + // Since "Time Formatting" runs its `node` before us, the title tooltip will + // pick up the user-formatted time instead of 4chan time when enabled. + dateEl.title = dateEl.textContent; + + return RelativeDates.update(this); + }, + + // diff is milliseconds from now. + relative(diff, now, date, abbrev) { + let number; + let unit = (() => { + if ((number = (diff / DAY)) >= 1) { + const years = now.getFullYear() - date.getFullYear(); + let months = now.getMonth() - date.getMonth(); + const days = now.getDate() - date.getDate(); + if (years > 1) { + number = years - ((months < 0) || ((months === 0) && (days < 0))); + return 'year'; + } else if ((years === 1) && ((months > 0) || ((months === 0) && (days >= 0)))) { + number = years; + return 'year'; + } else if ((months = months + (12*years)) > 1) { + number = months - (days < 0); + return 'month'; + } else if ((months === 1) && (days >= 0)) { + number = months; + return 'month'; + } else { + return 'day'; + } + } else if ((number = (diff / HOUR)) >= 1) { + return 'hour'; + } else if ((number = (diff / MINUTE)) >= 1) { + return 'minute'; + } else { + // prevent "-1 seconds ago" + number = Math.max(0, diff) / SECOND; + return 'second'; + } + })(); + + const rounded = Math.round(number); + + if (abbrev) { + unit = unit === 'month' ? 'mo' : unit[0]; + } else { + if (rounded !== 1) { unit += 's'; } // pluralize + } + + if (abbrev) { return `${rounded}${unit}`; } else { return `${rounded} ${unit} ago`; } + }, + + // Changing all relative dates as soon as possible incurs many annoying + // redraws and scroll stuttering. Thus, sacrifice accuracy for UX/CPU economy, + // and perform redraws when the DOM is otherwise being manipulated (and scroll + // stuttering won't be noticed), falling back to INTERVAL while the page + // is visible. + // + // Each individual dateTime element will add its update() function to the stale list + // when it is to be called. + stale: [], + flush() { + // No point in changing the dates until the user sees them. + if (d$1.hidden) { return; } + + const now = new Date(); + for (var data of RelativeDates.stale) { RelativeDates.update(data, now); } + RelativeDates.stale = []; + + // Reset automatic flush. + clearTimeout(RelativeDates.timeout); + return RelativeDates.timeout = setTimeout(RelativeDates.flush, RelativeDates.INTERVAL); + }, + + hover(post) { + const { + date + } = post.info; + const now = new Date(); + const diff = now - date; + return post.nodes.date.title = RelativeDates.relative(diff, now, date); + }, + + // `update()`, when called from `flush()`, updates the elements, + // and re-calls `setOwnTimeout()` to re-add `data` to the stale list later. + update(data, now) { + let abbrev, date; + const isPost = data instanceof Post; + if (isPost) { + ({ + date + } = data.info); + abbrev = false; + } else { + date = new Date(+data.dataset.utc); + abbrev = !!data.dataset.abbrev; + } + if (!now) { now = new Date(); } + const diff = now - date; + const relative = RelativeDates.relative(diff, now, date, abbrev); + if (isPost) { + for (var singlePost of [data].concat(data.clones)) { + singlePost.nodes.date.firstChild.textContent = relative; + } + } else { + data.firstChild.textContent = relative; + } + return RelativeDates.setOwnTimeout(diff, data); + }, + + setOwnTimeout(diff, data) { + const delay = diff < MINUTE ? + SECOND - ((diff + (SECOND / 2)) % SECOND) + : diff < HOUR ? + MINUTE - ((diff + (MINUTE / 2)) % MINUTE) + : diff < DAY ? + HOUR - ((diff + (HOUR / 2)) % HOUR) + : + DAY - ((diff + (DAY / 2)) % DAY); + return setTimeout(RelativeDates.markStale, delay, data); + }, + + markStale(data) { + if (RelativeDates.stale.includes(data)) { return; } // We can call RelativeDates.update() multiple times. + if (data instanceof Post && !g.posts.get(data.fullID)) { return; } // collected post. + if (data instanceof Element && !doc$1.contains(data)) { return; } // removed catalog reply. + return RelativeDates.stale.push(data); + } + }; + + var ThreadWatcherPage = `
            + Thread Watcher 🗘 + + 🞃 + × +
            +
            +`; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS104: Avoid inline assignments + * DS205: Consider reworking code to avoid use of IIFEs + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var BoardConfig = { + cbs: [], + + init() { + let middle; + if (g.SITE.software !== 'yotsuba') { return; } + const now = Date.now(); + if (now - (2 * HOUR) >= ((middle = Conf['boardConfig'].lastChecked || 0)) || middle > now) { + return $$1.ajax(`${location.protocol}//a.4cdn.org/boards.json`, + {onloadend: this.load}); + } else { + const {boards} = Conf['boardConfig']; + return this.set(boards); + } + }, + + load() { + let boards; + if ((this.status === 200) && this.response && this.response.boards) { + boards = dict(); + for (var board of this.response.boards) { + boards[board.board] = board; + } + $$1.set('boardConfig', {boards, lastChecked: Date.now()}); + } else { + ({boards} = Conf['boardConfig']); + const err = (() => { switch (this.status) { + case 0: return 'Connection Error'; + case 200: return 'Invalid Data'; + default: return `Error ${this.statusText} (${this.status})`; + } })(); + new Notice('warning', `Failed to load board configuration. ${err}`, 20); + } + return BoardConfig.set(boards); + }, + + set(boards) { + this.boards = boards; + for (var ID in g.boards) { + var board = g.boards[ID]; + board.config = this.boards[ID] || {}; + } + for (var cb of this.cbs) { + $$1.queueTask(cb); + } + }, + + ready(cb) { + if (this.boards) { + return cb(); + } else { + return this.cbs.push(cb); + } + }, + + sfwBoards(sfw) { + return (() => { + const result = []; + const object = this.boards || Conf['boardConfig'].boards; + for (var board in object) { + var data = object[board]; + if (!!data.ws_board === sfw) { + result.push(board); + } + } + return result; + })(); + }, + + isSFW(board) { + return !!(this.boards || Conf['boardConfig'].boards)[board]?.ws_board; + }, + + domain(board) { + return `boards.${BoardConfig.isSFW(board) ? '4channel' : '4chan'}.org`; + }, + + isArchived(board) { + // assume archive exists if no data available to prevent cleaning of archived threads + const data = (this.boards || Conf['boardConfig'].boards)[board]; + return !data || data.is_archived; + }, + + noAudio(boardID) { + if (g.SITE.software !== 'yotsuba') { return false; } + const boards = this.boards || Conf['boardConfig'].boards; + return boards && boards[boardID] && !boards[boardID].webm_audio; + }, + + title(boardID) { + return (this.boards || Conf['boardConfig'].boards)?.[boardID]?.title || ''; + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class Board { + toString() { return this.ID; } + + constructor(ID) { + this.ID = ID; + this.boardID = this.ID; + this.siteID = g.SITE.ID; + this.threads = new SimpleDict(); + this.posts = new SimpleDict(); + this.config = BoardConfig.boards?.[this.ID] || {}; + + g.boards[this] = this; + } + + cooldowns() { + const c2 = (this.config || {}).cooldowns || {}; + const c = { + thread: c2.threads || 0, + reply: c2.replies || 0, + image: c2.images || 0, + thread_global: 300 // inter-board thread cooldown + }; + // Pass users have reduced cooldowns. + if (d$1.cookie.indexOf('pass_enabled=1') >= 0) { + for (var key of ['reply', 'image']) { + c[key] = Math.ceil(c[key] / 2); + } + } + return c; + } + } + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const PostRedirect = { + init() { + return $$1.on(d$1, 'QRPostSuccessful', e => { + if (!e.detail.redirect) { return; } + this.event = e; + this.delays = 0; + return $$1.queueTask(() => { + if ((e === this.event) && (this.delays === 0)) { + return location.href = e.detail.redirect; + } + }); + }); + }, + + delays: 0, + + delay() { + if (!this.event) { return null; } + const e = this.event; + this.delays++; + return () => { + if (e !== this.event) { return; } + this.delays--; + if (this.delays === 0) { + return location.href = e.detail.redirect; + } + }; + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ExpandComment = { + init() { + if ((g.VIEW !== 'index') || !Conf['Comment Expansion'] || Conf['JSON Index']) { return; } + + return Callbacks.Post.push({ + name: 'Comment Expansion', + cb: this.node + }); + }, + + node() { + let a; + if (a = $$1('.abbr > a:not([onclick])', this.nodes.comment)) { + return $$1.on(a, 'click', ExpandComment.cb); + } + }, + + callbacks: [], + + cb(e) { + e.preventDefault(); + return ExpandComment.expand(Get$1.postFromNode(this)); + }, + + expand(post) { + let a; + if (post.nodes.longComment && !post.nodes.longComment.parentNode) { + $$1.replace(post.nodes.shortComment, post.nodes.longComment); + post.nodes.comment = post.nodes.longComment; + return; + } + if (!(a = $$1('.abbr > a', post.nodes.comment))) { return; } + a.textContent = `Post No.${post} Loading...`; + return $$1.cache(g.SITE.urls.threadJSON({boardID: post.boardID, threadID: post.threadID}), function() { return ExpandComment.parse(this, a, post); }); + }, + + contract(post) { + if (!post.nodes.shortComment) { return; } + const a = $$1('.abbr > a', post.nodes.shortComment); + a.textContent = 'here'; + $$1.replace(post.nodes.longComment, post.nodes.shortComment); + return post.nodes.comment = post.nodes.shortComment; + }, + + parse(req, a, post) { + let postObj, spoilerRange; + const {status} = req; + if (![200, 304].includes(status)) { + a.textContent = status ? `Error ${req.statusText} (${status})` : 'Connection Error'; + return; + } + + const { + posts + } = req.response; + if (spoilerRange = posts[0].custom_spoiler) { + g.SITE.Build.spoilerRange[g.BOARD] = spoilerRange; + } + + for (postObj of posts) { + if (postObj.no === post.ID) { break; } + } + if (postObj.no !== post.ID) { + a.textContent = `Post No.${post} not found.`; + return; + } + + const {comment} = post.nodes; + const clone = comment.cloneNode(false); + clone.innerHTML = postObj.com; + // Fix pathnames + for (var quote of $$('.quotelink', clone)) { + var href = quote.getAttribute('href'); + if (href[0] === '/') { continue; } // Cross-board quote, or board link + if (href[0] === '#') { + quote.href = `${a.pathname.split(/\/+/).splice(0,4).join('/')}${href}`; + } else { + quote.href = `${a.pathname.split(/\/+/).splice(0,3).join('/')}/${href}`; + } + } + post.nodes.shortComment = comment; + $$1.replace(comment, clone); + post.nodes.comment = (post.nodes.longComment = clone); + post.parseComment(); + post.parseQuotes(); + + for (var callback of ExpandComment.callbacks) { + callback.call(post); + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var QuoteYou = { + init() { + if (!Conf['Remember Your Posts']) { return; } + + this.db = new DataBoard('yourPosts'); + $$1.sync('Remember Your Posts', enabled => Conf['Remember Your Posts'] = enabled); + $$1.on(d$1, 'QRPostSuccessful', function(e) { + const cb = PostRedirect.delay(); + return $$1.get('Remember Your Posts', Conf['Remember Your Posts'], function(items) { + if (!items['Remember Your Posts']) { return; } + const {boardID, threadID, postID} = e.detail; + return QuoteYou.db.set({boardID, threadID, postID, val: true}, cb); + }); + }); + + if (!['index', 'thread', 'archive'].includes(g.VIEW)) { return; } + + if (Conf['Highlight Own Posts']) { + $$1.addClass(doc$1, 'highlight-own'); + } + + if (Conf['Highlight Posts Quoting You']) { + $$1.addClass(doc$1, 'highlight-you'); + } + + if (Conf['Comment Expansion']) { + ExpandComment.callbacks.push(this.node); + } + + // \u00A0 is nbsp + this.mark = $$1.el('span', { + textContent: '\u00A0(You)', + className: 'qmark-you' + } + ); + Callbacks.Post.push({ + name: 'Mark Quotes of You', + cb: this.node + }); + + return QuoteYou.menu.init(); + }, + + isYou(post) { + return !!QuoteYou.db?.get({ + boardID: post.boardID, + threadID: post.threadID, + postID: post.ID + }); + }, + + node() { + if (this.isClone) { return; } + + if (QuoteYou.isYou(this)) { + $$1.addClass(this.nodes.root, 'yourPost'); + } + + // Stop there if there's no quotes in that post. + if (!this.quotes.length) { return; } + + for (var quotelink of this.nodes.quotelinks) { + if (QuoteYou.db.get(Get$1.postDataFromLink(quotelink))) { + if (Conf['Mark Quotes of You']) { $$1.add(quotelink, QuoteYou.mark.cloneNode(true)); } + $$1.addClass(quotelink, 'you'); + $$1.addClass(this.nodes.root, 'quotesYou'); + } + } + }, + + menu: { + init() { + const label = $$1.el('label', + {className: 'toggle-you'} + , + {innerHTML: ' You'}); + const input = $$1('input', label); + $$1.on(input, 'change', QuoteYou.menu.toggle); + return Menu.menu?.addEntry({ + el: label, + order: 80, + open(post) { + QuoteYou.menu.post = (post.origin || post); + input.checked = QuoteYou.isYou(post); + return true; + } + }); + }, + + toggle() { + const {post} = QuoteYou.menu; + const data = {boardID: post.board.ID, threadID: post.thread.ID, postID: post.ID, val: true}; + if (this.checked) { + QuoteYou.db.set(data); + } else { + QuoteYou.db.delete(data); + } + for (var clone of [post].concat(post.clones)) { + clone.nodes.root.classList.toggle('yourPost', this.checked); + } + for (var quotelink of Get$1.allQuotelinksLinkingTo(post)) { + if (this.checked) { + if (Conf['Mark Quotes of You']) { $$1.add(quotelink, QuoteYou.mark.cloneNode(true)); } + } else { + $$1.rm($$1('.qmark-you', quotelink)); + } + quotelink.classList.toggle('you', this.checked); + if ($$1.hasClass(quotelink, 'quotelink')) { + var quoter = Get$1.postFromNode(quotelink).nodes.root; + quoter.classList.toggle('quotesYou', !!$$1('.quotelink.you', quoter)); + } + } + } + }, + + cb: { + seek(type) { + let highlighted, post; + let result; + const {highlight} = g.SITE.classes; + if (highlighted = $$1(`.${highlight}`)) { $$1.rmClass(highlighted, highlight); } + + if (!QuoteYou.lastRead || !doc$1.contains(QuoteYou.lastRead) || !$$1.hasClass(QuoteYou.lastRead, 'quotesYou')) { + if (!(post = (QuoteYou.lastRead = $$1('.quotesYou')))) { + new Notice('warning', 'No posts are currently quoting you, loser.', 20); + return; + } + if (QuoteYou.cb.scroll(post)) { return; } + } else { + post = QuoteYou.lastRead; + } + + const str = `${type}::div[contains(@class,'quotesYou')]`; + + while (post = (result = $$1.X(str, post)).snapshotItem(type === 'preceding' ? result.snapshotLength - 1 : 0)) { + if (QuoteYou.cb.scroll(post)) { return; } + } + + const posts = $$('.quotesYou'); + return QuoteYou.cb.scroll(posts[type === 'following' ? 0 : posts.length - 1]); + }, + + scroll(root) { + const post = Get$1.postFromRoot(root); + if (!post.nodes.post.getBoundingClientRect().height) { + return false; + } else { + QuoteYou.lastRead = root; + location.href = Get$1.url('post', post); + Header$1.scrollTo(post.nodes.post); + if (post.isReply) { + const sel = `${g.SITE.selectors.postContainer}${g.SITE.selectors.highlightable.reply}`; + let node = post.nodes.root; + if (!node.matches(sel)) { node = $$1(sel, node); } + $$1.addClass(node, g.SITE.classes.highlight); + } + return true; + } + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class RandomAccessList { + constructor(items) { + this.length = 0; + if (items) { for (var item of items) { this.push(item); } } + } + + push(data) { + let item; + let {ID} = data; + if (!ID) { ID = data.id; } + if (this[ID]) { return; } + const {last} = this; + this[ID] = (item = { + prev: last, + next: null, + data, + ID + }); + item.prev = last; + this.last = last ? + (last.next = item) + : + (this.first = item); + return this.length++; + } + + before(root, item) { + if ((item.next === root) || (item === root)) { return; } + + this.rmi(item); + + const {prev} = root; + root.prev = item; + item.next = root; + item.prev = prev; + if (prev) { + return prev.next = item; + } else { + return this.first = item; + } + } + + after(root, item) { + if ((item.prev === root) || (item === root)) { return; } + + this.rmi(item); + + const {next} = root; + root.next = item; + item.prev = root; + item.next = next; + if (next) { + return next.prev = item; + } else { + return this.last = item; + } + } + + prepend(item) { + const {first} = this; + if ((item === first) || !this[item.ID]) { return; } + this.rmi(item); + item.next = first; + if (first) { + first.prev = item; + } else { + this.last = item; + } + this.first = item; + return delete item.prev; + } + + shift() { + return this.rm(this.first.ID); + } + + order() { + let item; + const order = [(item = this.first)]; + while ((item = item.next)) { order.push(item); } + return order; + } + + rm(ID) { + const item = this[ID]; + if (!item) { return; } + delete this[ID]; + this.length--; + this.rmi(item); + delete item.next; + return delete item.prev; + } + + rmi(item) { + const {prev, next} = item; + if (prev) { + prev.next = next; + } else { + this.first = next; + } + if (next) { + return next.prev = prev; + } else { + return this.last = prev; + } + } + } + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Unread = { + init() { + if ((g.VIEW !== 'thread') || ( + !Conf['Unread Count'] && + !Conf['Unread Favicon'] && + !Conf['Unread Line'] && + !Conf['Remember Last Read Post'] && + !Conf['Desktop Notifications'] && + !Conf['Quote Threading'] + )) { return; } + + if (Conf['Remember Last Read Post']) { + $$1.sync('Remember Last Read Post', enabled => Conf['Remember Last Read Post'] = enabled); + this.db = new DataBoard('lastReadPosts', this.sync); + } + + this.hr = $$1.el('hr', { + id: 'unread-line', + className: 'unread-line' + } + ); + this.posts = new Set(); + this.postsQuotingYou = new Set(); + this.order = new RandomAccessList(); + this.position = null; + + Callbacks.Thread.push({ + name: 'Unread', + cb: this.node + }); + + return Callbacks.Post.push({ + name: 'Unread', + cb: this.addPost + }); + }, + + node() { + Unread.thread = this; + Unread.title = d$1.title; + Unread.lastReadPost = Unread.db?.get({ + boardID: this.board.ID, + threadID: this.ID + }) || 0; + Unread.readCount = 0; + for (var ID of this.posts.keys) { if (+ID <= Unread.lastReadPost) { Unread.readCount++; } } + $$1.one(d$1, '4chanXInitFinished', Unread.ready); + $$1.on(d$1, 'PostsInserted', Unread.onUpdate); + $$1.on(d$1, 'ThreadUpdate', function(e) { if (e.detail[404]) { return Unread.update(); } }); + const resetLink = $$1.el('a', { + href: 'javascript:;', + className: 'unread-reset', + textContent: 'Mark all unread' + } + ); + $$1.on(resetLink, 'click', Unread.reset); + return Header$1.menu.addEntry({ + el: resetLink, + order: 70 + }); + }, + + ready() { + if (Conf['Remember Last Read Post'] && Conf['Scroll to Last Read Post']) { Unread.scroll(); } + Unread.setLine(true); + Unread.read(); + Unread.update(); + $$1.on(d$1, 'scroll visibilitychange', Unread.read); + if (Conf['Unread Line']) { return $$1.on(d$1, 'visibilitychange', Unread.setLine); } + }, + + positionPrev() { + if (Unread.position) { return Unread.position.prev; } else { return Unread.order.last; } + }, + + scroll() { + // Let the header's onload callback handle it. + let hash; + if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) { return; } + + let position = Unread.positionPrev(); + while (position) { + var {bottom} = position.data.nodes; + if (!bottom.getBoundingClientRect().height) { + // Don't try to scroll to posts with display: none + position = position.prev; + } else { + Header$1.scrollToIfNeeded(bottom, true); + break; + } + } + }, + + reset() { + if (Unread.lastReadPost == null) { return; } + + Unread.posts = new Set(); + Unread.postsQuotingYou = new Set(); + Unread.order = new RandomAccessList(); + Unread.position = null; + Unread.lastReadPost = 0; + Unread.readCount = 0; + Unread.thread.posts.forEach(post => Unread.addPost.call(post)); + + $$1.forceSync('Remember Last Read Post'); + if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) { + Unread.db.set({ + boardID: Unread.thread.board.ID, + threadID: Unread.thread.ID, + val: 0 + }); + } + + Unread.updatePosition(); + Unread.setLine(); + return Unread.update(); + }, + + sync() { + if (Unread.lastReadPost == null) { return; } + const lastReadPost = Unread.db.get({ + boardID: Unread.thread.board.ID, + threadID: Unread.thread.ID, + defaultValue: 0 + }); + if (Unread.lastReadPost >= lastReadPost) { return; } + Unread.lastReadPost = lastReadPost; + + const postIDs = Unread.thread.posts.keys; + for (let i = Unread.readCount, end = postIDs.length; i < end; i++) { + var ID = +postIDs[i]; + if (!Unread.thread.posts.get(ID).isFetchedQuote) { + if (ID > Unread.lastReadPost) { break; } + Unread.posts.delete(ID); + Unread.postsQuotingYou.delete(ID); + } + Unread.readCount++; + } + + Unread.updatePosition(); + Unread.setLine(); + return Unread.update(); + }, + + addPost() { + if (this.isFetchedQuote || this.isClone) { return; } + Unread.order.push(this); + if ((this.ID <= Unread.lastReadPost) || this.isHidden || QuoteYou.isYou(this)) { return; } + Unread.posts.add((Unread.posts.last = this.ID)); + Unread.addPostQuotingYou(this); + return Unread.position != null ? Unread.position : (Unread.position = Unread.order[this.ID]); + }, + + addPostQuotingYou(post) { + for (var quotelink of post.nodes.quotelinks) { + if (QuoteYou.db?.get(Get$1.postDataFromLink(quotelink))) { + Unread.postsQuotingYou.add((Unread.postsQuotingYou.last = post.ID)); + Unread.openNotification(post); + return; + } + } + }, + + openNotification(post, predicate=' replied to you') { + if (!Header$1.areNotificationsEnabled) { return; } + const notif = new Notification(`${post.info.nameBlock}${predicate}`, { + body: post.commentDisplay(), + icon: Favicon.logo + } + ); + notif.onclick = function() { + Header$1.scrollToIfNeeded(post.nodes.bottom, true); + return window.focus(); + }; + return notif.onshow = () => setTimeout(() => notif.close() + , 7 * SECOND); + }, + + onUpdate() { + return $$1.queueTask(function() { // ThreadUpdater may scroll immediately after inserting posts + Unread.setLine(); + Unread.read(); + return Unread.update(); + }); + }, + + readSinglePost(post) { + const {ID} = post; + if (!Unread.posts.has(ID)) { return; } + Unread.posts.delete(ID); + Unread.postsQuotingYou.delete(ID); + Unread.updatePosition(); + Unread.saveLastReadPost(); + return Unread.update(); + }, + + read: debounce(100, function(e) { + // Update the lastReadPost when hidden posts are added to the thread. + if (!Unread.posts.size && (Unread.readCount !== Unread.thread.posts.keys.length)) { + Unread.saveLastReadPost(); + } + + if (d$1.hidden || !Unread.posts.size) { return; } + + let count = 0; + while (Unread.position) { + var {ID, data} = Unread.position; + var {bottom} = data.nodes; + if (!!bottom.getBoundingClientRect().height && // post has been hidden + (Header$1.getBottomOf(bottom) <= -1)) { break; } // post is completely read + count++; + Unread.posts.delete(ID); + Unread.postsQuotingYou.delete(ID); + Unread.position = Unread.position.next; + } + + if (!count) { return; } + Unread.updatePosition(); + Unread.saveLastReadPost(); + if (e) { return Unread.update(); } + }), + + updatePosition() { + while (Unread.position && !Unread.posts.has(Unread.position.ID)) { + Unread.position = Unread.position.next; + } + }, + + saveLastReadPost: debounce(2 * SECOND, function() { + let ID; + $$1.forceSync('Remember Last Read Post'); + if (!Conf['Remember Last Read Post'] || !Unread.db) { return; } + const postIDs = Unread.thread.posts.keys; + for (let i = Unread.readCount, end = postIDs.length; i < end; i++) { + ID = +postIDs[i]; + if (!Unread.thread.posts.get(ID).isFetchedQuote) { + if (Unread.posts.has(ID)) { break; } + Unread.lastReadPost = ID; + } + Unread.readCount++; + } + if (Unread.thread.isDead && !Unread.thread.isArchived) { return; } + return Unread.db.set({ + boardID: Unread.thread.board.ID, + threadID: Unread.thread.ID, + val: Unread.lastReadPost + }); + }), + + setLine(force) { + if (!Conf['Unread Line']) { return; } + if (Unread.hr.hidden || d$1.hidden || (force === true)) { + const oldPosition = Unread.linePosition; + if (Unread.linePosition = Unread.positionPrev()) { + if (Unread.linePosition !== oldPosition) { + let node = Unread.linePosition.data.nodes.bottom; + if (node.nextSibling?.tagName === 'BR') { node = node.nextSibling; } + $$1.after(node, Unread.hr); + } + } else { + $$1.rm(Unread.hr); + } + } + return Unread.hr.hidden = Unread.linePosition === Unread.order.last; + }, + + update() { + const count = Unread.posts.size; + const countQuotingYou = Unread.postsQuotingYou.size; + + if (Conf['Unread Count']) { + const titleQuotingYou = Conf['Quoted Title'] && countQuotingYou ? '(!) ' : ''; + const titleCount = count || !Conf['Hide Unread Count at (0)'] ? `(${count}) ` : ''; + const titleDead = Unread.thread.isDead ? + Unread.title.replace('-', (Unread.thread.isArchived ? '- Archived -' : '- 404 -')) + : + Unread.title; + d$1.title = `${titleQuotingYou}${titleCount}${titleDead}`; + } + + Unread.saveThreadWatcherCount(); + + if (Conf['Unread Favicon'] && (g.SITE.software === 'yotsuba')) { + const {isDead} = Unread.thread; + return Favicon.set(( + countQuotingYou ? + (isDead ? 'unreadDeadY' : 'unreadY') + : count ? + (isDead ? 'unreadDead' : 'unread') + : + (isDead ? 'dead' : 'default') + ) + ); + } + }, + + saveThreadWatcherCount: debounce(2 * SECOND, function() { + $$1.forceSync('Remember Last Read Post'); + if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) { + let posts; + const quotingYou = !Conf['Require OP Quote Link'] && QuoteYou.isYou(Unread.thread.OP) ? Unread.posts : Unread.postsQuotingYou; + if (!quotingYou.size) { + quotingYou.last = 0; + } else if (!quotingYou.has(quotingYou.last)) { + quotingYou.last = 0; + posts = Unread.thread.posts.keys; + for (let i = posts.length - 1; i >= 0; i--) { + if (quotingYou.has(+posts[i])) { + quotingYou.last = posts[i]; + break; + } + } + } + return ThreadWatcher$1.update(g.SITE.ID, Unread.thread.board.ID, Unread.thread.ID, { + last: Unread.thread.lastPost, + isDead: Unread.thread.isDead, + isArchived: Unread.thread.isArchived, + unread: Unread.posts.size, + quotingYou: (quotingYou.last || 0) + } + ); + } + }) + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ExpandThread = { + statuses: dict(), + init() { + if (!((g.VIEW === 'index') && Conf['Thread Expansion'])) { return; } + if (Conf['JSON Index']) { + return $$1.on(d$1, 'IndexRefreshInternal', this.onIndexRefresh); + } else { + return Callbacks.Thread.push({ + name: 'Expand Thread', + cb() { return ExpandThread.setButton(this); } + }); + } + }, + + setButton(thread) { + let a; + if (!(thread.nodes.root && (a = $$1('.summary', thread.nodes.root)))) { return; } + a.textContent = g.SITE.Build.summaryText('+', ...Array.from(a.textContent.match(/\d+/g))); + a.style.cursor = 'pointer'; + return $$1.on(a, 'click', ExpandThread.cbToggle); + }, + + disconnect(refresh) { + if ((g.VIEW === 'thread') || !Conf['Thread Expansion']) { return; } + for (var threadID in ExpandThread.statuses) { + var oldReq; + var status = ExpandThread.statuses[threadID]; + if (oldReq = status.req) { + delete status.req; + oldReq.abort(); + } + delete ExpandThread.statuses[threadID]; + } + + if (!refresh) { return $$1.off(d$1, 'IndexRefreshInternal', this.onIndexRefresh); } + }, + + onIndexRefresh() { + ExpandThread.disconnect(true); + return g.BOARD.threads.forEach(thread => ExpandThread.setButton(thread)); + }, + + cbToggle(e) { + if ($$1.modifiedClick(e)) { return; } + e.preventDefault(); + return ExpandThread.toggle(Get$1.threadFromNode(this)); + }, + + cbToggleBottom(e) { + if ($$1.modifiedClick(e)) { return; } + e.preventDefault(); + const thread = Get$1.threadFromNode(this); + $$1.rm(this); // remove before fixing bottom of thread position + const {bottom} = thread.nodes.root.getBoundingClientRect(); + ExpandThread.toggle(thread); + return window.scrollBy(0, (thread.nodes.root.getBoundingClientRect().bottom - bottom)); + }, + + toggle(thread) { + let a; + if (!(thread.nodes.root && (a = $$1('.summary', thread.nodes.root)))) { return; } + if (thread.ID in ExpandThread.statuses) { + return ExpandThread.contract(thread, a, thread.nodes.root); + } else { + return ExpandThread.expand(thread, a); + } + }, + + expand(thread, a) { + let status; + ExpandThread.statuses[thread] = (status = {}); + a.textContent = g.SITE.Build.summaryText('...', ...Array.from(a.textContent.match(/\d+/g))); + status.req = $$1.cache(g.SITE.urls.threadJSON({boardID: thread.board.ID, threadID: thread.ID}), function() { + if (this !== status.req) { return; } // aborted + delete status.req; + return ExpandThread.parse(this, thread, a); + }); + return status.numReplies = $$(g.SITE.selectors.replyOriginal, thread.nodes.root).length; + }, + + contract(thread, a, threadRoot) { + let oldReq; + const status = ExpandThread.statuses[thread]; + delete ExpandThread.statuses[thread]; + if (oldReq = status.req) { + delete status.req; + oldReq.abort(); + if (a) { a.textContent = g.SITE.Build.summaryText('+', ...Array.from(a.textContent.match(/\d+/g))); } + return; + } + + let replies = $$('.thread > .replyContainer', threadRoot); + if (status.numReplies) { replies = replies.slice(0, (-status.numReplies)); } + let postsCount = 0; + let filesCount = 0; + for (var reply of replies) { + // rm clones + if (Conf['Quote Inlining']) { var inlined; + while ((inlined = $$1('.inlined', reply))) { inlined.click(); } } + postsCount++; + if ('file' in Get$1.postFromRoot(reply)) { filesCount++; } + $$1.rm(reply); + } + if (Index$1.enabled) { // otherwise handled by Main.addPosts + $$1.event('PostsRemoved', null, a.parentNode); + } + a.textContent = g.SITE.Build.summaryText('+', postsCount, filesCount); + return $$1.rm($$1('.summary-bottom', threadRoot)); + }, + + parse(req, thread, a) { + let root; + if (![200, 304].includes(req.status)) { + a.textContent = req.status ? `Error ${req.statusText} (${req.status})` : 'Connection Error'; + return; + } + + g.SITE.Build.spoilerRange[thread.board] = req.response.posts[0].custom_spoiler; + + const posts = []; + const postsRoot = []; + let filesCount = 0; + for (var postData of req.response.posts) { + var post; + if (postData.no === thread.ID) { continue; } + if ((post = thread.posts.get(postData.no)) && !post.isFetchedQuote) { + if ('file' in post) { filesCount++; } + ({root} = post.nodes); + postsRoot.push(root); + continue; + } + root = g.SITE.Build.postFromObject(postData, thread.board.ID); + post = new Post(root, thread, thread.board); + if ('file' in post) { filesCount++; } + posts.push(post); + postsRoot.push(root); + } + Main$1.callbackNodes('Post', posts); + $$1.after(a, postsRoot); + $$1.event('PostsInserted', null, a.parentNode); + + const postsCount = postsRoot.length; + a.textContent = g.SITE.Build.summaryText('-', postsCount, filesCount); + + if (root) { + const a2 = a.cloneNode(true); + a2.classList.add('summary-bottom'); + $$1.on(a2, 'click', ExpandThread.cbToggleBottom); + return $$1.after(root, a2); + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var UnreadIndex = { + lastReadPost: dict(), + hr: dict(), + markReadLink: dict(), + + init() { + if ((g.VIEW !== 'index') || !Conf['Remember Last Read Post'] || !Conf['Unread Line in Index']) { return; } + + this.enabled = true; + this.db = new DataBoard('lastReadPosts', this.sync); + + Callbacks.Thread.push({ + name: 'Unread Line in Index', + cb: this.node + }); + + $$1.on(d$1, 'IndexRefreshInternal', this.onIndexRefresh); + return $$1.on(d$1, 'PostsInserted PostsRemoved', this.onPostsInserted); + }, + + node() { + UnreadIndex.lastReadPost[this.fullID] = UnreadIndex.db.get({ + boardID: this.board.ID, + threadID: this.ID + }) || 0; + if (!Index$1.enabled) { // let onIndexRefresh handle JSON Index + return UnreadIndex.update(this); + } + }, + + onIndexRefresh(e) { + if (e.detail.isCatalog) { return; } + return (() => { + const result = []; + for (var threadID of e.detail.threadIDs) { + var thread = g.threads.get(threadID); + result.push(UnreadIndex.update(thread)); + } + return result; + })(); + }, + + onPostsInserted(e) { + if (e.target === Index$1.root) { return; } // onIndexRefresh handles this case + const thread = Get$1.threadFromNode(e.target); + if (!thread || (thread.nodes.root !== e.target)) { return; } + const wasVisible = !!UnreadIndex.hr[thread.fullID]?.parentNode; + UnreadIndex.update(thread); + if (Conf['Scroll to Last Read Post'] && (e.type === 'PostsInserted') && !wasVisible && !!UnreadIndex.hr[thread.fullID]?.parentNode) { + return Header$1.scrollToIfNeeded(UnreadIndex.hr[thread.fullID], true); + } + }, + + sync() { + return g.threads.forEach(function(thread) { + const lastReadPost = UnreadIndex.db.get({ + boardID: thread.board.ID, + threadID: thread.ID + }) || 0; + if (lastReadPost !== UnreadIndex.lastReadPost[thread.fullID]) { + UnreadIndex.lastReadPost[thread.fullID] = lastReadPost; + if (thread.nodes.root?.parentNode) { + return UnreadIndex.update(thread); + } + } + }); + }, + + update(thread) { + let divider; + const lastReadPost = UnreadIndex.lastReadPost[thread.fullID]; + let repliesShown = 0; + let repliesRead = 0; + let firstUnread = null; + thread.posts.forEach(function(post) { + if (post.isReply && thread.nodes.root.contains(post.nodes.root)) { + repliesShown++; + if (post.ID <= lastReadPost) { + return repliesRead++; + } else if ((!firstUnread || (post.ID < firstUnread.ID)) && !post.isHidden && !QuoteYou.isYou(post)) { + return firstUnread = post; + } + } + }); + + let hr = UnreadIndex.hr[thread.fullID]; + if (firstUnread && (repliesRead || ((lastReadPost === thread.OP.ID) && (!$$1(g.SITE.selectors.summary, thread.nodes.root) || thread.ID in ExpandThread.statuses)))) { + if (!hr) { + hr = (UnreadIndex.hr[thread.fullID] = $$1.el('hr', + {className: 'unread-line'})); + } + $$1.before(firstUnread.nodes.root, hr); + } else { + $$1.rm(hr); + } + + const hasUnread = repliesShown ? + firstUnread || !repliesRead + : Index$1.enabled ? + thread.lastPost > lastReadPost + : + thread.OP.ID > lastReadPost; + thread.nodes.root.classList.toggle('unread-thread', hasUnread); + + let link = UnreadIndex.markReadLink[thread.fullID]; + if (!link) { + link = (UnreadIndex.markReadLink[thread.fullID] = $$1.el('a', { + className: 'unread-mark-read brackets-wrap', + href: 'javascript:;', + textContent: 'Mark Read' + } + )); + $$1.on(link, 'click', UnreadIndex.markRead); + } + if (divider = $$1(g.SITE.selectors.threadDivider, thread.nodes.root)) { // divider inside thread as in Tinyboard + return $$1.before(divider, link); + } else { + return $$1.add(thread.nodes.root, link); + } + }, + + markRead() { + const thread = Get$1.threadFromNode(this); + UnreadIndex.lastReadPost[thread.fullID] = thread.lastPost; + UnreadIndex.db.set({ + boardID: thread.board.ID, + threadID: thread.ID, + val: thread.lastPost + }); + $$1.rm(UnreadIndex.hr[thread.fullID]); + thread.nodes.root.classList.remove('unread-thread'); + return ThreadWatcher$1.update(g.SITE.ID, thread.board.ID, thread.ID, { + last: thread.lastPost, + unread: 0, + quotingYou: 0 + } + ); + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS104: Avoid inline assignments + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var ThreadWatcher = { + init() { + let sc; + if (!(this.enabled = Conf['Thread Watcher'])) { return; } + + this.shortcut = (sc = $$1.el('a', { + id: 'watcher-link', + textContent: '👁︎', + title: 'Thread Watcher', + href: 'javascript:;', + } + )); + + this.db = new DataBoard('watchedThreads', this.refresh, true); + this.dbLM = new DataBoard('watcherLastModified', null, true); + this.dialog = UI.dialog('thread-watcher', { innerHTML: ThreadWatcherPage }); + this.status = $$1('#watcher-status', this.dialog); + this.list = this.dialog.lastElementChild; + this.refreshButton = $$1('.refresh', this.dialog); + this.closeButton = $$1('.move > .close', this.dialog); + this.unreaddb = Unread.db || UnreadIndex.db || new DataBoard('lastReadPosts'); + this.unreadEnabled = Conf['Remember Last Read Post']; + + $$1.on(d$1, 'QRPostSuccessful', this.cb.post); + $$1.on(sc, 'click', this.toggleWatcher); + $$1.on(this.refreshButton, 'click', this.buttonFetchAll); + $$1.on(this.closeButton, 'click', this.toggleWatcher); + + this.menu.addHeaderMenuEntry(); + $$1.onExists(doc$1, 'body', this.addDialog); + + switch (g.VIEW) { + case 'index': + $$1.on(d$1, 'IndexUpdate', this.cb.onIndexUpdate); + break; + case 'thread': + $$1.on(d$1, 'ThreadUpdate', this.cb.onThreadRefresh); + break; + } + + if (Conf['Fixed Thread Watcher']) { + $$1.addClass(doc$1, 'fixed-watcher'); + } + if (!Conf['Persistent Thread Watcher']) { + $$1.addClass(ThreadWatcher.shortcut, 'disabled'); + this.dialog.hidden = true; + } + + Header$1.addShortcut('watcher', sc, 510); + + ThreadWatcher.initLastModified(); + ThreadWatcher.fetchAuto(); + $$1.on(window, 'visibilitychange focus', () => $$1.queueTask(ThreadWatcher.fetchAuto)); + + if (Conf['Menu'] && Index$1.enabled) { + Menu.menu.addEntry({ + el: $$1.el('a', { + href: 'javascript:;', + className: 'has-shortcut-text' + } + , {innerHTML: 'Alt+click'}), + order: 6, + open({thread}) { + if (Conf['Index Mode'] !== 'catalog') { return false; } + this.el.firstElementChild.textContent = ThreadWatcher.isWatched(thread) ? + 'Unwatch' + : + 'Watch'; + if (this.cb) { $$1.off(this.el, 'click', this.cb); } + this.cb = function() { + $$1.event('CloseMenu'); + return ThreadWatcher.toggle(thread); + }; + $$1.on(this.el, 'click', this.cb); + return true; + } + }); + } + + if (!['index', 'thread'].includes(g.VIEW)) { return; } + + Callbacks.Post.push({ + name: 'Thread Watcher', + cb: this.node + }); + return Callbacks.CatalogThread.push({ + name: 'Thread Watcher', + cb: this.catalogNode + }); + }, + + isWatched(thread) { + return !!ThreadWatcher.db?.get({boardID: thread.board.ID, threadID: thread.ID}); + }, + + isWatchedRaw(boardID, threadID) { + return !!ThreadWatcher.db?.get({boardID, threadID}); + }, + + setToggler(toggler, isWatched) { + toggler.classList.toggle('watched', isWatched); + return toggler.title = `${isWatched ? 'Unwatch' : 'Watch'} Thread`; + }, + + node() { + let toggler; + if (this.isReply) { return; } + if (this.isClone) { + toggler = $$1('.watch-thread-link', this.nodes.info); + } else { + toggler = $$1.el('a', { + href: 'javascript:;', + className: 'watch-thread-link' + } + ); + $$1.before($$1('input', this.nodes.info), toggler); + } + const siteID = g.SITE.ID; + const boardID = this.board.ID; + const threadID = this.thread.ID; + const data = ThreadWatcher.db.get({siteID, boardID, threadID}); + ThreadWatcher.setToggler(toggler, !!data); + $$1.on(toggler, 'click', ThreadWatcher.cb.toggle); + // Add missing excerpt for threads added by Auto Watch + if (data && (data.excerpt == null)) { + return $$1.queueTask(() => { + return ThreadWatcher.update(siteID, boardID, threadID, {excerpt: Get$1.threadExcerpt(this.thread)}); + }); + } + }, + + catalogNode() { + if (ThreadWatcher.isWatched(this.thread)) { $$1.addClass(this.nodes.root, 'watched'); } + return $$1.on(this.nodes.root, 'mousedown click', e => { + if ((e.button !== 0) || !e.altKey) { return; } + if (e.type === 'click') { ThreadWatcher.toggle(this.thread); } + return e.preventDefault(); + }); + }, // Also on mousedown to prevent highlighting thumbnail in Firefox. + + addDialog() { + if (!Main$1.isThisPageLegit()) { return; } + ThreadWatcher.build(); + return $$1.prepend(d$1.body, ThreadWatcher.dialog); + }, + + toggleWatcher() { + $$1.toggleClass(ThreadWatcher.shortcut, 'disabled'); + return ThreadWatcher.dialog.hidden = !ThreadWatcher.dialog.hidden; + }, + + cb: { + openAll() { + if ($$1.hasClass(this, 'disabled')) { return; } + for (var a of $$('a.watcher-link', ThreadWatcher.list)) { + $$1.open(a.href); + } + return $$1.event('CloseMenu'); + }, + openUnread() { + if ($$1.hasClass(this, 'disabled')) { return; } + for (var a of $$('.replies-unread > a.watcher-link', ThreadWatcher.list)) { + $$1.open(a.href); + } + return $$1.event('CloseMenu'); + }, + openDeads() { + if ($$1.hasClass(this, 'disabled')) { return; } + for (var a of $$('.dead-thread > a.watcher-link', ThreadWatcher.list)) { + $$1.open(a.href); + } + return $$1.event('CloseMenu'); + }, + pruneDeads() { + if ($$1.hasClass(this, 'disabled')) { return; } + for (var {siteID, boardID, threadID, data} of ThreadWatcher.getAll()) { + if (data.isDead) { + ThreadWatcher.db.delete({siteID, boardID, threadID}); + } + } + ThreadWatcher.refresh(); + return $$1.event('CloseMenu'); + }, + dismiss() { + for (var {siteID, boardID, threadID, data} of ThreadWatcher.getAll()) { + if (data.quotingYou) { + ThreadWatcher.update(siteID, boardID, threadID, {dismiss: data.quotingYou || 0}); + } + } + return $$1.event('CloseMenu'); + }, + toggle() { + const {thread} = Get$1.postFromNode(this); + return ThreadWatcher.toggle(thread); + }, + rm() { + const {siteID} = this.parentNode.dataset; + const [boardID, threadID] = Array.from(this.parentNode.dataset.fullID.split('.')); + return ThreadWatcher.rm(siteID, boardID, +threadID); + }, + post(e) { + const {boardID, threadID, postID} = e.detail; + const cb = PostRedirect.delay(); + if (postID === threadID) { + if (Conf['Auto Watch']) { + return ThreadWatcher.addRaw(boardID, threadID, {}, cb); + } + } else if (Conf['Auto Watch Reply']) { + return ThreadWatcher.add((g.threads.get(boardID + '.' + threadID) || new Thread(threadID, g.boards[boardID] || new Board(boardID))), cb); + } + }, + onIndexUpdate(e) { + const {db} = ThreadWatcher; + const siteID = g.SITE.ID; + const boardID = g.BOARD.ID; + let nKilled = 0; + for (var threadID in db.data[siteID].boards[boardID]) { + // Don't prune threads that have yet to appear in index. + var data = db.data[siteID].boards[boardID][threadID]; + if (!data?.isDead && !e.detail.threads.includes(`${boardID}.${threadID}`)) { + if (!e.detail.threads.some(fullID => +fullID.split('.')[1] > threadID)) { continue; } + if (Conf['Auto Prune'] || !(data && (typeof data === 'object'))) { // corrupt data + db.delete({boardID, threadID}); + nKilled++; + } else { + ThreadWatcher.fetchStatus({siteID, boardID, threadID, data}); + } + } + } + if (nKilled) { return ThreadWatcher.refresh(); } + }, + onThreadRefresh(e) { + const thread = g.threads.get(e.detail.threadID); + if (!e.detail[404] || !ThreadWatcher.isWatched(thread)) { return; } + // Update dead status. + return ThreadWatcher.add(thread); + } + }, + + requests: [], + fetched: 0, + + fetch(url, {siteID, force}, args, cb) { + if (ThreadWatcher.requests.length === 0) { + ThreadWatcher.status.textContent = '...'; + $$1.addClass(ThreadWatcher.refreshButton, 'spin'); + } + const onloadend = function() { + if (this.finished) { return; } + this.finished = true; + ThreadWatcher.fetched++; + if (ThreadWatcher.fetched === ThreadWatcher.requests.length) { + ThreadWatcher.clearRequests(); + } else { + ThreadWatcher.status.textContent = `${Math.round((ThreadWatcher.fetched / ThreadWatcher.requests.length) * 100)}%`; + } + return cb.apply(this, args); + }; + const ajax = siteID === g.SITE.ID ? $$1.ajax : CrossOrigin$1.ajax; + if (force) { + delete $$1.lastModified.ThreadWatcher?.[url]; + } + const req = $$1.whenModified( + url, + 'ThreadWatcher', + onloadend, + { timeout: MINUTE, ajax } + ); + return ThreadWatcher.requests.push(req); + }, + + clearRequests() { + ThreadWatcher.requests = []; + ThreadWatcher.fetched = 0; + ThreadWatcher.status.textContent = ''; + return $$1.rmClass(ThreadWatcher.refreshButton, 'spin'); + }, + + abort() { + delete ThreadWatcher.syncing; + for (var req of ThreadWatcher.requests) { + if (!req.finished) { + req.finished = true; + req.abort(); + } + } + return ThreadWatcher.clearRequests(); + }, + + initLastModified() { + const lm = ($$1.lastModified['ThreadWatcher'] || ($$1.lastModified['ThreadWatcher'] = dict())); + for (var siteID in ThreadWatcher.dbLM.data) { + var boards = ThreadWatcher.dbLM.data[siteID]; + for (var boardID in boards.boards) { + var data = boards.boards[boardID]; + if (ThreadWatcher.db.get({siteID, boardID})) { + for (var url in data) { + var date = data[url]; + lm[url] = date; + } + } else { + ThreadWatcher.dbLM.delete({siteID, boardID}); + } + } + } + }, + + fetchAuto() { + let middle; + clearTimeout(ThreadWatcher.timeout); + if (!Conf['Auto Update Thread Watcher']) { return; } + const {db} = ThreadWatcher; + const interval = Conf['Show Page'] || (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) ? 5 * MINUTE : 2 * HOUR; + const now = Date.now(); + if ((now - interval >= ((middle = db.data.lastChecked || 0)) || middle > now) && !d$1.hidden && !!d$1.hasFocus()) { + ThreadWatcher.fetchAllStatus(interval); + } + return ThreadWatcher.timeout = setTimeout(ThreadWatcher.fetchAuto, interval); + }, + + buttonFetchAll() { + if (ThreadWatcher.syncing || ThreadWatcher.requests.length) { + return ThreadWatcher.abort(); + } else { + return ThreadWatcher.fetchAllStatus(); + } + }, + + fetchAllStatus(interval=0) { + ThreadWatcher.status.textContent = '...'; + $$1.addClass(ThreadWatcher.refreshButton, 'spin'); + ThreadWatcher.syncing = true; + const dbs = [ThreadWatcher.db, ThreadWatcher.unreaddb, QuoteYou.db].filter(x => x); + let n = 0; + return dbs.map((dbi) => + dbi.forceSync(function() { + if ((++n) === dbs.length) { + let middle; + if (!ThreadWatcher.syncing) { return; } // aborted + delete ThreadWatcher.syncing; + if (0 > (middle = Date.now() - (ThreadWatcher.db.data.lastChecked || 0)) || middle >= interval) { // not checked in another tab + // XXX On vichan boards, last_modified field of threads.json does not account for sage posts. + // Occasionally check replies field of catalog.json to find these posts. + let middle1; + const {db} = ThreadWatcher; + const now = Date.now(); + const deep = !(now - (2 * HOUR) < ((middle1 = db.data.lastChecked2 || 0)) && middle1 <= now); + const boards = ThreadWatcher.getAll(true); + for (var board of boards) { + ThreadWatcher.fetchBoard(board, deep); + } + db.setLastChecked(); + if (deep) { db.setLastChecked('lastChecked2'); } + } + if (ThreadWatcher.fetched === ThreadWatcher.requests.length) { + return ThreadWatcher.clearRequests(); + } + } + })); + }, + + fetchBoard(board, deep) { + if (!board.some(thread => !thread.data.isDead)) { return; } + let force = false; + for (var thread of board) { + var {data} = thread; + if (!data.isDead && (data.last !== -1)) { + if (Conf['Show Page'] && (data.page == null)) { force = true; } + if ((data.modified == null)) { force = (thread.force = true); } + } + } + const {siteID, boardID} = board[0]; + const site = g.sites[siteID]; + if (!site) { return; } + const urlF = deep && site.threadModTimeIgnoresSage ? 'catalogJSON' : 'threadsListJSON'; + const url = site.urls[urlF]?.({siteID, boardID}); + if (!url) { return; } + return ThreadWatcher.fetch(url, {siteID, force}, [board, url], ThreadWatcher.parseBoard); + }, + + parseBoard(board, url) { + let page, thread; + if (this.status !== 200) { return; } + const {siteID, boardID} = board[0]; + const lmDate = this.getResponseHeader('Last-Modified'); + ThreadWatcher.dbLM.extend({siteID, boardID, val: $$1.item(url, lmDate)}); + const threads = dict(); + let pageLength = 0; + let nThreads = 0; + let oldest = null; + try { + pageLength = this.response[0]?.threads.length || 0; + for (let i = 0; i < this.response.length; i++) { + page = this.response[i]; + for (var item of page.threads) { + threads[item.no] = { + page: i + 1, + index: nThreads, + modified: item.last_modified, + replies: item.replies + }; + nThreads++; + if ((oldest == null) || (item.no < oldest)) { + oldest = item.no; + } + } + } + } catch (error) { + for (thread of board) { + ThreadWatcher.fetchStatus(thread); + } + } + for (thread of board) { + var {threadID, data} = thread; + if (threads[threadID]) { + var index, modified, replies; + ({page, index, modified, replies} = threads[threadID]); + if (Conf['Show Page']) { + var lastPage = g.sites[siteID].isPrunedByAge?.({siteID, boardID}) ? + threadID === oldest + : + index >= (nThreads - pageLength); + ThreadWatcher.update(siteID, boardID, threadID, {page, lastPage}); + } + if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { + if ((modified !== data.modified) || ((replies != null) && (replies !== data.replies))) { + (thread.newData || (thread.newData = {})).modified = modified; + ThreadWatcher.fetchStatus(thread); + } + } + } else { + ThreadWatcher.fetchStatus(thread); + } + } + }, + + fetchStatus(thread) { + const {siteID, boardID, threadID, data, force} = thread; + const url = g.sites[siteID]?.urls.threadJSON?.({siteID, boardID, threadID}); + if (!url) { return; } + if (data.isDead && !force) { return; } + if (data.last === -1) { return; } // 404 or no JSON API + return ThreadWatcher.fetch(url, {siteID, force}, [thread], ThreadWatcher.parseStatus); + }, + + parseStatus(thread, isArchiveURL) { + let isDead, last; + let {siteID, boardID, threadID, data, newData, force} = thread; + const site = g.sites[siteID]; + if ((this.status === 200) && this.response) { + let isArchived; + last = this.response.posts[this.response.posts.length-1].no; + const replies = this.response.posts.length-1; + isDead = (isArchived = !!(this.response.posts[0].archived || isArchiveURL)); + if (isDead && Conf['Auto Prune']) { + ThreadWatcher.rm(siteID, boardID, threadID); + return; + } + + if ((last === data.last) && (isDead === data.isDead) && (isArchived === data.isArchived)) { return; } + + const lastReadPost = ThreadWatcher.unreaddb.get({siteID, boardID, threadID, defaultValue: 0}); + let unread = data.unread || 0; + let quotingYou = data.quotingYou || 0; + const youOP = !!QuoteYou.db?.get({siteID, boardID, threadID, postID: threadID}); + + for (var postObj of this.response.posts) { + if ((postObj.no <= (data.last || 0)) || (postObj.no <= lastReadPost)) { continue; } + if (QuoteYou.db?.get({siteID, boardID, threadID, postID: postObj.no})) { continue; } + + var quotesYou = false; + if (!Conf['Require OP Quote Link'] && youOP) { + quotesYou = true; + } else if (QuoteYou.db && postObj.com) { + var match; + var regexp = site.regexp.quotelinkHTML; + regexp.lastIndex = 0; + while (match = regexp.exec(postObj.com)) { + if (QuoteYou.db.get({ + siteID, + boardID: match[1] ? encodeURIComponent(match[1]) : boardID, + threadID: match[2] || threadID, + postID: match[3] || match[2] || threadID + })) { + quotesYou = true; + break; + } + } + } + + if (!unread || (!quotingYou && quotesYou)) { + if (Filter.isHidden(site.Build.parseJSON(postObj, {siteID, boardID}))) { continue; } + } + + unread++; + if (quotesYou) { quotingYou = postObj.no; } + } + + if (!newData) { newData = {}; } + $$1.extend(newData, {last, replies, isDead, isArchived, unread, quotingYou}); + return ThreadWatcher.update(siteID, boardID, threadID, newData); + + } else if (this.status === 404) { + const archiveURL = g.sites[siteID]?.urls.archivedThreadJSON?.({siteID, boardID, threadID}); + if (!isArchiveURL && archiveURL) { + return ThreadWatcher.fetch(archiveURL, {siteID, force}, [thread, true], ThreadWatcher.parseStatus); + } else if (site.mayLackJSON && (data.last == null)) { + return ThreadWatcher.update(siteID, boardID, threadID, {last: -1}); + } else { + return ThreadWatcher.update(siteID, boardID, threadID, {isDead: true}); + } + } + }, + + getAll(groupByBoard) { + const all = []; + for (var siteID in ThreadWatcher.db.data) { + var boards = ThreadWatcher.db.data[siteID]; + for (var boardID in boards.boards) { + var cont; + var threads = boards.boards[boardID]; + if (Conf['Current Board'] && ((siteID !== g.SITE.ID) || (boardID !== g.BOARD.ID))) { + continue; + } + if (groupByBoard) { + all.push((cont = [])); + } + for (var threadID in threads) { + var data = threads[threadID]; + if (data && (typeof data === 'object')) { + (groupByBoard ? cont : all).push({siteID, boardID, threadID, data}); + } + } + } + } + return all; + }, + + makeLine(siteID, boardID, threadID, data) { + let page; + const x = $$1.el('a', { + textContent: '✕', + href: 'javascript:;' + } + ); + $$1.on(x, 'click', ThreadWatcher.cb.rm); + + let {excerpt, isArchived} = data; + if (!excerpt) { excerpt = `/${boardID}/ - No.${threadID}`; } + if (Conf['Show Site Prefix']) { excerpt = ThreadWatcher.prefixes[siteID] + excerpt; } + + const link = $$1.el('a', { + href: g.sites[siteID]?.urls.thread({siteID, boardID, threadID}, isArchived) || '', + title: excerpt, + className: 'watcher-link' + } + ); + + if (Conf['Show Page'] && (data.page != null)) { + page = $$1.el('span', { + textContent: `[${data.page}]`, + className: 'watcher-page' + } + ); + $$1.add(link, page); + } + + if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count'] && (data.unread != null)) { + const count = $$1.el('span', { + textContent: `(${data.unread})`, + className: 'watcher-unread' + } + ); + $$1.add(link, count); + } + + const title = $$1.el('span', { + textContent: excerpt, + className: 'watcher-title' + } + ); + $$1.add(link, title); + + const div = $$1.el('div'); + const fullID = `${boardID}.${threadID}`; + div.dataset.fullID = fullID; + div.dataset.siteID = siteID; + if ((g.VIEW === 'thread') && (fullID === `${g.BOARD}.${g.THREADID}`)) { $$1.addClass(div, 'current'); } + if (data.isDead) { $$1.addClass(div, 'dead-thread'); } + if (Conf['Show Page']) { + if (data.lastPage) { $$1.addClass(div, 'last-page'); } + if (data.page != null) { div.dataset.page = data.page; } + } + if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { + if (data.unread === 0) { $$1.addClass(div, 'replies-read'); } + if (data.unread) { $$1.addClass(div, 'replies-unread'); } + if ((data.quotingYou || 0) > (data.dismiss || 0)) { $$1.addClass(div, 'replies-quoting-you'); } + } + $$1.add(div, [x, $$1.tn(' '), link]); + return div; + }, + + setPrefixes(threads) { + const prefixes = dict(); + for (var {siteID} of threads) { + if (siteID in prefixes) { continue; } + var len = 0; + var prefix = ''; + var conflicts = Object.keys(prefixes); + while (conflicts.length > 0) { + len++; + prefix = siteID.slice(0, len); + var conflicts2 = []; + for (var siteID2 of conflicts) { + if (siteID2.slice(0, len) === prefix) { + conflicts2.push(siteID2); + } else if (prefixes[siteID2].length < len) { + prefixes[siteID2] = siteID2.slice(0, len); + } + } + conflicts = conflicts2; + } + prefixes[siteID] = prefix; + } + return ThreadWatcher.prefixes = prefixes; + }, + + build() { + const nodes = []; + const threads = ThreadWatcher.getAll(); + ThreadWatcher.setPrefixes(threads); + for (var {siteID, boardID, threadID, data} of threads) { + // Add missing excerpt for threads added by Auto Watch + var thread; + if ((data.excerpt == null) && (siteID === g.SITE.ID) && (thread = g.threads.get(`${boardID}.${threadID}`)) && thread.OP) { + ThreadWatcher.db.extend({boardID, threadID, val: {excerpt: Get$1.threadExcerpt(thread)}}); + } + nodes.push(ThreadWatcher.makeLine(siteID, boardID, threadID, data)); + } + const {list} = ThreadWatcher; + $$1.rmAll(list); + $$1.add(list, nodes); + + return ThreadWatcher.refreshIcon(); + }, + + refresh() { + ThreadWatcher.build(); + + g.threads.forEach(function(thread) { + const isWatched = ThreadWatcher.isWatched(thread); + if (thread.OP) { + for (var post of [thread.OP, ...Array.from(thread.OP.clones)]) { + var toggler; + if (toggler = $$1('.watch-thread-link', post.nodes.info)) { + ThreadWatcher.setToggler(toggler, isWatched); + } + } + } + if (thread.catalogView) { return thread.catalogView.nodes.root.classList.toggle('watched', isWatched); } + }); + + if (Conf['Pin Watched Threads']) { + return $$1.event('SortIndex', {deferred: Conf['Index Mode'] !== 'catalog'}); + } + }, + + refreshIcon() { + for (var className of ['replies-unread', 'replies-quoting-you']) { + ThreadWatcher.shortcut.classList.toggle(className, !!$$1(`.${className}`, ThreadWatcher.dialog)); + } + }, + + update(siteID, boardID, threadID, newData) { + let data, key, line, val; + if (!(data = ThreadWatcher.db?.get({siteID, boardID, threadID}))) { return; } + if (newData.isDead && Conf['Auto Prune']) { + ThreadWatcher.rm(siteID, boardID, threadID); + return; + } + if (newData.isDead || (newData.last === -1)) { + for (key of ['isArchived', 'page', 'lastPage', 'unread', 'quotingyou']) { + if (!(key in newData)) { + newData[key] = undefined; + } + } + } + if ((newData.last != null) && (newData.last < data.last)) { + newData.modified = undefined; + } + let n = 0; + for (key in newData) { val = newData[key]; if (data[key] !== val) { n++; } } + if (!n) { return; } + ThreadWatcher.db.extend({siteID, boardID, threadID, val: newData}); + if (line = $$1(`#watched-threads > [data-site-i-d='${siteID}'][data-full-i-d='${boardID}.${threadID}']`, ThreadWatcher.dialog)) { + const newLine = ThreadWatcher.makeLine(siteID, boardID, threadID, data); + $$1.replace(line, newLine); + return ThreadWatcher.refreshIcon(); + } else { + return ThreadWatcher.refresh(); + } + }, + + set404(boardID, threadID, cb) { + let data; + if (!(data = ThreadWatcher.db?.get({boardID, threadID}))) { return cb(); } + if (Conf['Auto Prune']) { + ThreadWatcher.db.delete({boardID, threadID}); + return cb(); + } + if (data.isDead && !((data.isArchived != null) || (data.page != null) || (data.lastPage != null) || (data.unread != null) || (data.quotingYou != null))) { return cb(); } + return ThreadWatcher.db.extend({boardID, threadID, val: {isDead: true, isArchived: undefined, page: undefined, lastPage: undefined, unread: undefined, quotingYou: undefined}}, cb); + }, + + toggle(thread) { + const siteID = g.SITE.ID; + const boardID = thread.board.ID; + const threadID = thread.ID; + if (ThreadWatcher.db.get({boardID, threadID})) { + return ThreadWatcher.rm(siteID, boardID, threadID); + } else { + return ThreadWatcher.add(thread); + } + }, + + add(thread, cb) { + const data = {}; + const siteID = g.SITE.ID; + const boardID = thread.board.ID; + const threadID = thread.ID; + if (thread.isDead) { + if (Conf['Auto Prune'] && ThreadWatcher.db.get({boardID, threadID})) { + ThreadWatcher.rm(siteID, boardID, threadID, cb); + return; + } + data.isDead = true; + } + if (thread.OP) { data.excerpt = Get$1.threadExcerpt(thread); } + return ThreadWatcher.addRaw(boardID, threadID, data, cb); + }, + + addRaw(boardID, threadID, data, cb) { + const oldData = ThreadWatcher.db.get({ boardID, threadID, defaultValue: dict() }); + delete oldData.last; + delete oldData.modified; + $$1.extend(oldData, data); + ThreadWatcher.db.set({boardID, threadID, val: oldData}, cb); + ThreadWatcher.refresh(); + const thread = {siteID: g.SITE.ID, boardID, threadID, data, force: true}; + if (Conf['Show Page'] && !data.isDead) { + return ThreadWatcher.fetchBoard([thread]); + } else if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) { + return ThreadWatcher.fetchStatus(thread); + } + }, + + rm(siteID, boardID, threadID, cb) { + ThreadWatcher.db.delete({siteID, boardID, threadID}, cb); + return ThreadWatcher.refresh(); + }, + + menu: { + init() { + if (!Conf['Thread Watcher']) { return; } + const menu = (this.menu = new UI.Menu('thread watcher')); + $$1.on($$1('.menu-button', ThreadWatcher.dialog), 'click', function(e) { + return menu.toggle(e, this, ThreadWatcher); + }); + return this.addMenuEntries(); + }, + + addHeaderMenuEntry() { + if (g.VIEW !== 'thread') { return; } + const entryEl = $$1.el('a', + {href: 'javascript:;'}); + Header$1.menu.addEntry({ + el: entryEl, + order: 60, + open() { + const [addClass, rmClass, text] = Array.from(!!ThreadWatcher.db.get({boardID: g.BOARD.ID, threadID: g.THREADID}) ? + ['unwatch-thread', 'watch-thread', 'Unwatch thread'] + : + ['watch-thread', 'unwatch-thread', 'Watch thread']); + $$1.addClass(entryEl, addClass); + $$1.rmClass(entryEl, rmClass); + entryEl.textContent = text; + return true; + } + }); + return $$1.on(entryEl, 'click', () => ThreadWatcher.toggle(g.threads.get(`${g.BOARD}.${g.THREADID}`))); + }, + + addMenuEntries() { + const entries = []; + + // `Open all` entry + entries.push({ + text: 'Open all threads', + cb: ThreadWatcher.cb.openAll, + open() { + this.el.classList.toggle('disabled', !ThreadWatcher.list.firstElementChild); + return true; + } + }); + + // `Open Unread` entry + entries.push({ + text: 'Open unread threads', + cb: ThreadWatcher.cb.openUnread, + open() { + this.el.classList.toggle('disabled', !$$1('.replies-unread', ThreadWatcher.list)); + return true; + } + }); + + // `Open dead threads` entry + entries.push({ + text: 'Open dead threads', + cb: ThreadWatcher.cb.openDeads, + open() { + this.el.classList.toggle('disabled', !$$1('.dead-thread', ThreadWatcher.list)); + return true; + } + }); + + // `Prune dead threads` entry + entries.push({ + text: 'Prune dead threads', + cb: ThreadWatcher.cb.pruneDeads, + open() { + this.el.classList.toggle('disabled', !$$1('.dead-thread', ThreadWatcher.list)); + return true; + } + }); + + // `Dismiss posts quoting you` entry + entries.push({ + text: 'Dismiss posts quoting you', + title: 'Unhighlight the thread watcher icon and threads until there are new replies quoting you.', + cb: ThreadWatcher.cb.dismiss, + open() { + this.el.classList.toggle('disabled', !$$1.hasClass(ThreadWatcher.shortcut, 'replies-quoting-you')); + return true; + } + }); + + for (var {text, title, cb, open} of entries) { + var entry = { + el: $$1.el('a', { + textContent: text, + href: 'javascript:;' + } + ) + }; + if (title) { entry.el.title = title; } + $$1.on(entry.el, 'click', cb); + entry.open = open.bind(entry); + this.menu.addEntry(entry); + } + + // Settings checkbox entries: + for (var name in Config.threadWatcher) { + var conf = Config.threadWatcher[name]; + this.addCheckbox(name, conf[1]); + } + + }, + + addCheckbox(name, desc) { + const entry = { + type: 'thread watcher', + el: UI.checkbox(name, name.replace(' Thread Watcher', '')) + }; + entry.el.title = desc; + const input = entry.el.firstElementChild; + if ((name === 'Show Unread Count') && !ThreadWatcher.unreadEnabled) { + input.disabled = true; + $$1.addClass(entry.el, 'disabled'); + entry.el.title += '\n[Remember Last Read Post is disabled.]'; + } + $$1.on(input, 'change', $$1.cb.checked); + if (['Current Board', 'Show Page', 'Show Unread Count', 'Show Site Prefix'].includes(name)) { $$1.on(input, 'change', ThreadWatcher.refresh); } + if (['Show Page', 'Show Unread Count', 'Auto Update Thread Watcher'].includes(name)) { $$1.on(input, 'change', ThreadWatcher.fetchAuto); } + return this.menu.addEntry(entry); + } + } + }; + var ThreadWatcher$1 = ThreadWatcher; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * DS206: Consider reworking classes to avoid initClass + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + class Fetcher { + static initClass() { + + this.prototype.archiveTags = { + '\n': {innerHTML: "
            "}, + '[b]': {innerHTML: ""}, + '[/b]': {innerHTML: ""}, + '[spoiler]': {innerHTML: ""}, + '[/spoiler]': {innerHTML: ""}, + '[code]': {innerHTML: "
            "},
            +        '[/code]':    {innerHTML: "
            "}, + '[moot]': {innerHTML: "
            "}, + '[/moot]': {innerHTML: "
            "}, + '[banned]': {innerHTML: ""}, + '[/banned]': {innerHTML: ""}, + '[fortune]'(text) { return {innerHTML: ""}; }, + '[/fortune]': {innerHTML: ""}, + '[i]': {innerHTML: ""}, + '[/i]': {innerHTML: ""}, + '[red]': {innerHTML: ""}, + '[/red]': {innerHTML: ""}, + '[green]': {innerHTML: ""}, + '[/green]': {innerHTML: ""}, + '[blue]': {innerHTML: ""}, + '[/blue]': {innerHTML: ""} + }; + } + constructor(boardID, threadID, postID, root, quoter) { + let post, thread; + this.boardID = boardID; + this.threadID = threadID; + this.postID = postID; + this.root = root; + this.quoter = quoter; + if (post = g.posts.get(`${this.boardID}.${this.postID}`)) { + this.insert(post); + return; + } + + // 4chan X catalog data + if ((post = Index$1.replyData?.[`${this.boardID}.${this.postID}`]) && (thread = g.threads.get(`${this.boardID}.${this.threadID}`))) { + const board = g.boards[this.boardID]; + post = new Post(g.SITE.Build.postFromObject(post, this.boardID), thread, board, {isFetchedQuote: true}); + Main$1.callbackNodes('Post', [post]); + this.insert(post); + return; + } + + this.root.textContent = `Loading post No.${this.postID}...`; + if (this.threadID) { + const that = this; + $$1.cache(g.SITE.urls.threadJSON({boardID: this.boardID, threadID: this.threadID}), function({isCached}) { + return that.fetchedPost(this, isCached); + }); + } else { + this.archivedPost(); + } + } + + insert(post) { + // Stop here if the container has been removed while loading. + if (!this.root.parentNode) { return; } + if (!this.quoter) { this.quoter = post; } + const clone = post.addClone(this.quoter.context, ($$1.hasClass(this.root, 'dialog'))); + Main$1.callbackNodes('Post', [clone]); + + // Get rid of the side arrows/stubs. + const {nodes} = clone; + $$1.rmAll(nodes.root); + $$1.add(nodes.root, nodes.post); + + // Indicate links to the containing post. + const quotes = [...clone.nodes.quotelinks, ...clone.nodes.backlinks]; + for (var quote of quotes) { + var {boardID, postID} = Get$1.postDataFromLink(quote); + if ((postID === this.quoter.ID) && (boardID === this.quoter.board.ID)) { + $$1.addClass(quote, 'forwardlink'); + } + } + + // Set up flag CSS for cross-board links to boards with flags + if (clone.nodes.flag && !(Fetcher.flagCSS || (Fetcher.flagCSS = $$1('link[href^="//s.4cdn.org/css/flags."]')))) { + const cssVersion = $$1('link[href^="//s.4cdn.org/css/"]')?.href.match(/\d+(?=\.css$)|$/)[0] || Date.now(); + Fetcher.flagCSS = $$1.el('link', { + rel: 'stylesheet', + href: `//s.4cdn.org/css/flags.${cssVersion}.css` + } + ); + $$1.add(d$1.head, Fetcher.flagCSS); + } + + $$1.rmAll(this.root); + $$1.add(this.root, nodes.root); + return $$1.event('PostsInserted', null, this.root); + } + + fetchedPost(req, isCached) { + // In case of multiple callbacks for the same request, + // don't parse the same original post more than once. + let post; + if (post = g.posts.get(`${this.boardID}.${this.postID}`)) { + this.insert(post); + return; + } + + const {status} = req; + if (status !== 200) { + // The thread can die by the time we check a quote. + if (status && this.archivedPost()) { return; } + + $$1.addClass(this.root, 'warning'); + this.root.textContent = + status === 404 ? + `Thread No.${this.threadID} 404'd.` + : !status ? + 'Connection Error' + : + `Error ${req.statusText} (${req.status}).`; + return; + } + + const {posts} = req.response; + g.SITE.Build.spoilerRange[this.boardID] = posts[0].custom_spoiler; + for (post of posts) { + if (post.no === this.postID) { break; } + } // we found it! + + if (post.no !== this.postID) { + // Cached requests can be stale and must be rechecked. + if (isCached) { + const api = g.SITE.urls.threadJSON({boardID: this.boardID, threadID: this.threadID}); + $$1.cleanCache(url => url === api); + const that = this; + $$1.cache(api, function() { + return that.fetchedPost(this, false); + }); + return; + } + + // The post can be deleted by the time we check a quote. + if (this.archivedPost()) { return; } + + $$1.addClass(this.root, 'warning'); + this.root.textContent = `Post No.${this.postID} was not found.`; + return; + } + + const board = g.boards[this.boardID] || + new Board(this.boardID); + const thread = g.threads.get(`${this.boardID}.${this.threadID}`) || + new Thread(this.threadID, board); + post = new Post(g.SITE.Build.postFromObject(post, this.boardID), thread, board, {isFetchedQuote: true}); + Main$1.callbackNodes('Post', [post]); + return this.insert(post); + } + + archivedPost() { + let url; + if (!Conf['Resurrect Quotes']) { return false; } + if (!(url = Redirect$1.to('post', {boardID: this.boardID, postID: this.postID}))) { return false; } + const archive = Redirect$1.data.post[this.boardID]; + const encryptionOK = /^https:\/\//.test(url) || (location.protocol === 'http:'); + if (encryptionOK || Conf['Exempt Archives from Encryption']) { + const that = this; + CrossOrigin$1.cache(url, function() { + if (!encryptionOK && this.response?.media) { + const {media} = this.response; + for (var key in media) { + // Image/thumbnail URLs loaded over HTTP can be modified in transit. + // Require them to be from an HTTP host so that no referrer is sent to them from an HTTPS page. + if (/_link$/.test(key)) { + if (!$$1.getOwn(media, key)?.match(/^http:\/\//)) { delete media[key]; } + } + } + } + return that.parseArchivedPost(this.response, url, archive); + }); + return true; + } + return false; + } + + parseArchivedPost(data, url, archive) { + // In case of multiple callbacks for the same request, + // don't parse the same original post more than once. + let post; + if (post = g.posts.get(`${this.boardID}.${this.postID}`)) { + this.insert(post); + return; + } + + if (data == null) { + $$1.addClass(this.root, 'warning'); + this.root.textContent = `Error fetching Post No.${this.postID} from ${archive.name}.`; + return; + } + + if (data.error) { + $$1.addClass(this.root, 'warning'); + this.root.textContent = data.error; + return; + } + + // https://github.com/eksopl/asagi/blob/v0.4.0b74/src/main/java/net/easymodo/asagi/YotsubaAbstract.java#L82-L129 + // https://github.com/FoolCode/FoolFuuka/blob/800bd090835489e7e24371186db6e336f04b85c0/src/Model/Comment.php#L368-L428 + // https://github.com/bstats/b-stats/blob/6abe7bffaf6e5f523498d760e54b110df5331fbb/inc/classes/Yotsuba.php#L157-L168 + let comment = (data.comment || '').split(/(\n|\[\/?(?:b|spoiler|code|moot|banned|fortune(?: color="#\w+")?|i|red|green|blue)\])/); + comment = (() => { + const result = []; + for (let i = 0; i < comment.length; i++) { + var text = comment[i]; + if ((i % 2) === 1) { + var tag = Fetcher.archiveTags[text.replace(/\ .*\]/, ']')]; + if (typeof tag === 'function') { result.push(tag(text)); } else { result.push(tag); } + } else { + var greentext = text[0] === '>'; + text = text.replace(/(\[\/?[a-z]+):lit(\])/g, '$1$2'); + text = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g).map((text2, j) => + {((j % 2) ? "" + E(text2) + "" : E(text2));}); + text = {innerHTML: ((greentext) ? "" + E.cat(text) + "" : E.cat(text))}; + result.push(text); + } + } + return result; + })(); + comment = {innerHTML: E.cat(comment)}; + + this.threadID = +data.thread_num; + const o = { + ID: this.postID, + threadID: this.threadID, + boardID: this.boardID, + isReply: this.postID !== this.threadID + }; + o.info = { + subject: data.title, + email: data.email, + name: data.name || '', + tripcode: data.trip, + capcode: (() => { switch (data.capcode) { + // https://github.com/pleebe/FoolFuuka/blob/bf4224eed04637a4d0bd4411c2bf5f9945dfec0b/assets/themes/foolz/foolfuuka-theme-fuuka/src/Partial/Board.php#L77 + 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: data.poster_hash, + flagCode: data.poster_country, + flagCodeTroll: data.troll_country_code, + flag: data.poster_country_name || data.troll_country_name, + dateUTC: data.timestamp, + dateText: data.fourchan_date, + commentHTML: comment + }; + if (o.info.capcode) { delete o.info.uniqueID; } + if (data.media && !!+data.media.banned) { + o.fileDeleted = true; + } else if (data.media?.media_filename) { + let {thumb_link} = data.media; + // Fix URLs missing origin + if (thumb_link?.[0] === '/') { thumb_link = url.split('/', 3).join('/') + thumb_link; } + if (!Redirect$1.securityCheck(thumb_link)) { thumb_link = ''; } + let media_link = Redirect$1.to('file', {boardID: this.boardID, filename: data.media.media_orig}); + if (!Redirect$1.securityCheck(media_link)) { media_link = ''; } + o.file = { + name: data.media.media_filename, + url: media_link || + (this.boardID === 'f' ? + `${location.protocol}//${ImageHost.flashHost()}/${this.boardID}/${encodeURIComponent(E(data.media.media_filename))}` + : + `${location.protocol}//${ImageHost.host()}/${this.boardID}/${data.media.media_orig}`), + height: data.media.media_h, + width: data.media.media_w, + MD5: data.media.media_hash, + size: $$1.bytesToString(data.media.media_size), + thumbURL: thumb_link || `${location.protocol}//${ImageHost.thumbHost()}/${this.boardID}/${data.media.preview_orig}`, + theight: data.media.preview_h, + twidth: data.media.preview_w, + isSpoiler: data.media.spoiler === '1' + }; + if (!/\.pdf$/.test(o.file.url)) { o.file.dimensions = `${o.file.width}x${o.file.height}`; } + if ((this.boardID === 'f') && data.media.exif) { o.file.tag = JSON.parse(data.media.exif).Tag; } + } + o.extra = dict(); + + const board = g.boards[this.boardID] || + new Board(this.boardID); + const thread = g.threads.get(`${this.boardID}.${this.threadID}`) || + new Thread(this.threadID, board); + post = new Post(g.SITE.Build.post(o), thread, board, {isFetchedQuote: true}); + post.kill(); + if (post.file) { post.file.thumbURL = o.file.thumbURL; } + Main$1.callbackNodes('Post', [post]); + return this.insert(post); + } + } + Fetcher.initClass(); + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var QuotePreview = { + init() { + if (!Conf['Quote Previewing']) { return; } + + if (g.VIEW === 'archive') { + $$1.on(d$1, 'mouseover', function(e) { + if ((e.target.nodeName === 'A') && $$1.hasClass(e.target, 'quotelink')) { + return QuotePreview.mouseover.call(e.target, e); + } + }); + } + + if (!['index', 'thread'].includes(g.VIEW)) { return; } + + if (Conf['Comment Expansion']) { + ExpandComment.callbacks.push(this.node); + } + + return Callbacks.Post.push({ + name: 'Quote Previewing', + cb: this.node + }); + }, + + node() { + for (var link of this.nodes.quotelinks.concat([...Array.from(this.nodes.backlinks)], this.nodes.archivelinks)) { + $$1.on(link, 'mouseover', QuotePreview.mouseover); + } + }, + + mouseover(e) { + let origin; + if (($$1.hasClass(this, 'inlined') && !$$1.hasClass(doc, 'catalog-mode')) || !d$1.contains(this)) { return; } + + const {boardID, threadID, postID} = Get$1.postDataFromLink(this); + + const qp = $$1.el('div', { + id: 'qp', + className: 'dialog' + } + ); + + $$1.add(Header$1.hover, qp); + new Fetcher(boardID, threadID, postID, qp, Get$1.postFromNode(this)); + + UI.hover({ + root: this, + el: qp, + latestEvent: e, + endEvents: 'mouseout click', + cb: QuotePreview.mouseout + }); + + if (Conf['Quote Highlighting'] && (origin = g.posts.get(`${boardID}.${postID}`))) { + const posts = [origin].concat(origin.clones); + // Remove the clone that's in the qp from the array. + posts.pop(); + for (var post of posts) { + $$1.addClass(post.nodes.post, 'qphl'); + } + } + }, + + mouseout() { + // Stop if it only contains text. + let root; + if (!(root = this.el.firstElementChild)) { return; } + + $$1.event('PostsRemoved', null, Header$1.hover); + + const clone = Get$1.postFromRoot(root); + let post = clone.origin; + post.rmClone(root.dataset.clone); + + if (!Conf['Quote Highlighting']) { return; } + for (post of [post].concat(post.clones)) { + $$1.rmClass(post.nodes.post, 'qphl'); + } + } + }; + + var NavLinksPage = `Index +Catalog +Archive +Bottom + + +× + + + + + + + + +`; + + var PageList = ` +
            + + +`; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var Index = { + showHiddenThreads: false, + changed: {}, + + enabledOn({siteID, boardID}) { + return Conf['JSON Index'] && (g.sites[siteID].software === 'yotsuba') && (boardID !== 'f'); + }, + + init() { + let input, inputs, name; + if (g.VIEW !== 'index') { return; } + + // For IndexRefresh events + $$1.one(d$1, '4chanXInitFinished', this.cb.initFinished); + $$1.on(d$1, 'PostsInserted', this.cb.postsInserted); + + if (!this.enabledOn(g.BOARD)) { return; } + + this.enabled = true; + + Callbacks.Post.push({ + name: 'Index Page Numbers', + cb: this.node + }); + Callbacks.CatalogThread.push({ + name: 'Catalog Features', + cb: this.catalogNode + }); + + this.search = history.state?.searched || ''; + if (history.state?.mode) { + Conf['Index Mode'] = history.state?.mode; + } + this.currentSort = history.state?.sort; + if (!this.currentSort) { this.currentSort = typeof Conf['Index Sort'] === 'object' ? ( + Conf['Index Sort'][g.BOARD.ID] || 'bump' + ) : ( + Conf['Index Sort'] + ); } + this.currentPage = this.getCurrentPage(); + this.processHash(); + + $$1.addClass(doc$1, 'index-loading', `${Conf['Index Mode'].replace(/\ /g, '-')}-mode`); + $$1.on(window, 'popstate', this.cb.popstate); + $$1.on(d$1, 'scroll', this.scroll); + $$1.on(d$1, 'SortIndex', this.cb.resort); + + // Header refresh button + this.button = $$1.el('a', { + title: 'Refresh', + href: 'javascript:;', + textContent: '🗘' + } + ); + $$1.on(this.button, 'click', () => Index.update()); + Header$1.addShortcut('index-refresh', this.button, 590); + + // Header "Index Navigation" submenu + const entries = []; + this.inputs = (inputs = dict()); + for (name in Config.Index) { + var arr = Config.Index[name]; + if (arr instanceof Array) { + var label = UI.checkbox(name, `${name[0]}${name.slice(1).toLowerCase()}`); + label.title = arr[1]; + entries.push({el: label}); + input = label.firstChild; + $$1.on(input, 'change', $$1.cb.checked); + inputs[name] = input; + } + } + $$1.on(inputs['Show Replies'], 'change', this.cb.replies); + $$1.on(inputs['Catalog Hover Expand'], 'change', this.cb.hover); + $$1.on(inputs['Pin Watched Threads'], 'change', this.cb.resort); + $$1.on(inputs['Anchor Hidden Threads'], 'change', this.cb.resort); + + const watchSettings = function(e) { + if (input = $$1.getOwn(inputs, e.target.name)) { + input.checked = e.target.checked; + return $$1.event('change', null, input); + } + }; + $$1.on(d$1, 'OpenSettings', () => $$1.on($$1.id('fourchanx-settings'), 'change', watchSettings)); + + const sortEntry = UI.checkbox('Per-Board Sort Type', 'Per-board sort type', (typeof Conf['Index Sort'] === 'object')); + sortEntry.title = 'Set the sorting order of each board independently.'; + $$1.on(sortEntry.firstChild, 'change', this.cb.perBoardSort); + entries.splice(3, 0, {el: sortEntry}); + + Header$1.menu.addEntry({ + el: $$1.el('span', + {textContent: 'Index Navigation'}), + order: 100, + subEntries: entries + }); + + // Navigation links at top of index + this.navLinks = $$1.el('div', {className: 'navLinks json-index'}); + $$1.extend(this.navLinks, {innerHTML: NavLinksPage}); + $$1('.cataloglink a', this.navLinks).href = CatalogLinks.catalog(); + if (!BoardConfig.isArchived(g.BOARD.ID)) { $$1('.archlistlink', this.navLinks).hidden = true; } + $$1.on($$1('#index-last-refresh a', this.navLinks), 'click', this.cb.refreshFront); + + // Search field + this.searchInput = $$1('#index-search', this.navLinks); + this.setupSearch(); + $$1.on(this.searchInput, 'input', this.onSearchInput); + $$1.on($$1('#index-search-clear', this.navLinks), 'click', this.clearSearch); + + // Hidden threads toggle + this.hideLabel = $$1('#hidden-label', this.navLinks); + $$1.on($$1('#hidden-toggle a', this.navLinks), 'click', this.cb.toggleHiddenThreads); + + // Drop-down menus and reverse sort toggle + this.selectRev = $$1('#index-rev', this.navLinks); + this.selectMode = $$1('#index-mode', this.navLinks); + this.selectSort = $$1('#index-sort', this.navLinks); + this.selectSize = $$1('#index-size', this.navLinks); + $$1.on(this.selectRev, 'change', this.cb.sort); + $$1.on(this.selectMode, 'change', this.cb.mode); + $$1.on(this.selectSort, 'change', this.cb.sort); + $$1.on(this.selectSize, 'change', $$1.cb.value); + $$1.on(this.selectSize, 'change', this.cb.size); + for (var select of [this.selectMode, this.selectSize]) { + select.value = Conf[select.name]; + } + this.selectRev.checked = /-rev$/.test(Index.currentSort); + this.selectSort.value = Index.currentSort.replace(/-rev$/, ''); + + // Last Long Reply options + this.lastLongOptions = $$1('#lastlong-options', this.navLinks); + this.lastLongInputs = $$('input', this.lastLongOptions); + this.lastLongThresholds = [0, 0]; + this.lastLongOptions.hidden = (this.selectSort.value !== 'lastlong'); + for (let i = 0; i < this.lastLongInputs.length; i++) { + input = this.lastLongInputs[i]; + $$1.on(input, 'change', this.cb.lastLongThresholds); + var tRaw = Conf[`Last Long Reply Thresholds ${i}`]; + input.value = (this.lastLongThresholds[i] = + typeof tRaw === 'object' ? (tRaw[g.BOARD.ID] ?? 100) : tRaw); + } + + // Thread container + this.root = $$1.el('div', {className: 'board json-index'}); + $$1.on(this.root, 'click', this.cb.hoverToggle); + this.cb.size(); + this.cb.hover(); + + // Page list + this.pagelist = $$1.el('div', {className: 'pagelist json-index'}); + $$1.extend(this.pagelist, {innerHTML: PageList}); + $$1('.cataloglink a', this.pagelist).href = CatalogLinks.catalog(); + $$1.on(this.pagelist, 'click', this.cb.pageNav); + + this.update(true); + + $$1.onExists(doc$1, 'title + *', () => d$1.title = d$1.title.replace(/\ -\ Page\ \d+/, '')); + + $$1.onExists(doc$1, '.board > .thread > .postContainer, .board + *', function() { + let el; + g.SITE.Build.hat = $$1('.board > .thread > img:first-child'); + if (g.SITE.Build.hat) { + g.BOARD.threads.forEach(function(thread) { + if (thread.nodes.root) { + return $$1.prepend(thread.nodes.root, g.SITE.Build.hat.cloneNode(false)); + } + }); + $$1.addClass(doc$1, 'hats-enabled'); + $$1.addStyle(`.catalog-thread::after {background-image: url(${g.SITE.Build.hat.src});}`); + } + + const board = $$1('.board'); + $$1.replace(board, Index.root); + if (Index.loaded) { + $$1.event('PostsInserted', null, Index.root); + } + // Hacks: + // - When removing an element from the document during page load, + // its ancestors will still be correctly created inside of it. + // - Creating loadable elements inside of an origin-less document + // will not download them. + // - Combine the two and you get a download canceller! + // Does not work on Firefox unfortunately. bugzil.la/939713 + try { + d$1.implementation.createDocument(null, null, null).appendChild(board); + } catch (error) {} + + for (el of $$('.navLinks')) { $$1.rm(el); } + $$1.rm($$1.id('ctrl-top')); + const topNavPos = $$1.id('delform').previousElementSibling; + $$1.before(topNavPos, $$1.el('hr')); + $$1.before(topNavPos, Index.navLinks); + const timeEl = $$1('#index-last-refresh time', Index.navLinks); + if (timeEl.dataset.utc) { return RelativeDates.update(timeEl); } + }); + + return Main$1.ready(function() { + let pagelist; + if (pagelist = $$1('.pagelist')) { + $$1.replace(pagelist, Index.pagelist); + } + return $$1.rmClass(doc$1, 'index-loading'); + }); + }, + + scroll() { + if (Index.req || !Index.liveThreadData || (Conf['Index Mode'] !== 'infinite') || (window.scrollY <= (doc$1.scrollHeight - (300 + window.innerHeight)))) { return; } + if (Index.pageNum == null) { Index.pageNum = Index.currentPage; } // Avoid having to pushState to keep track of the current page + + const pageNum = ++Index.pageNum; + if (pageNum > Index.pagesNum) { return Index.endNotice(); } + + const threadIDs = Index.threadsOnPage(pageNum); + return Index.buildStructure(threadIDs); + }, + + endNotice: (function() { + let notify = false; + const reset = () => notify = false; + return function() { + if (notify) { return; } + notify = true; + new Notice('info', "Last page reached.", 2); + return setTimeout(reset, 3 * SECOND); + }; + })(), + + menu: { + init() { + if ((g.VIEW !== 'index') || !Conf['Menu'] || !Conf['Thread Hiding Link'] || !Index.enabledOn(g.BOARD)) { return; } + + return Menu.menu.addEntry({ + el: $$1.el('a', { + href: 'javascript:;', + className: 'has-shortcut-text' + } + , {innerHTML: "Shift+click"}), + order: 20, + open({thread}) { + if (Conf['Index Mode'] !== 'catalog') { return false; } + this.el.firstElementChild.textContent = thread.isHidden ? + 'Unhide' + : + 'Hide'; + if (this.cb) { $$1.off(this.el, 'click', this.cb); } + this.cb = function() { + $$1.event('CloseMenu'); + return Index.toggleHide(thread); + }; + $$1.on(this.el, 'click', this.cb); + return true; + } + }); + } + }, + + node() { + if (this.isReply || this.isClone || (Index.threadPosition[this.ID] == null)) { return; } + return this.thread.setPage(Math.floor(Index.threadPosition[this.ID] / Index.threadsNumPerPage) + 1); + }, + + catalogNode() { + return $$1.on(this.nodes.root, 'mousedown click', e => { + if ((e.button !== 0) || !e.shiftKey) { return; } + if (e.type === 'click') { Index.toggleHide(this.thread); } + return e.preventDefault(); + }); + }, // Also on mousedown to prevent highlighting text. + + toggleHide(thread) { + if (Index.showHiddenThreads) { + ThreadHiding.show(thread); + if (!ThreadHiding.db.get({boardID: thread.board.ID, threadID: thread.ID})) { return; } + // Don't save when un-hiding filtered threads. + } else { + ThreadHiding.hide(thread); + } + return ThreadHiding.saveHiddenState(thread); + }, + + cycleSortType() { + let i; + const types = [...Array.from(Index.selectSort.options)].filter(option => !option.disabled); + for (i = 0; i < types.length; i++) { + var type = types[i]; + if (type.selected) { break; } + } + types[(i + 1) % types.length].selected = true; + return $$1.event('change', null, Index.selectSort); + }, + + cb: { + initFinished() { + Index.initFinishedFired = true; + return $$1.queueTask(() => Index.cb.postsInserted()); + }, + + postsInserted() { + if (!Index.initFinishedFired) { return; } + let n = 0; + g.posts.forEach(function(post) { + if (!post.isFetchedQuote && !post.indexRefreshSeen && doc$1.contains(post.nodes.root)) { + post.indexRefreshSeen = true; + return n++; + } + }); + if (n) { return $$1.event('IndexRefresh'); } + }, + + toggleHiddenThreads() { + $$1('#hidden-toggle a', Index.navLinks).textContent = (Index.showHiddenThreads = !Index.showHiddenThreads) ? + 'Hide' + : + 'Show'; + Index.sort(); + return Index.buildIndex(); + }, + + mode() { + Index.pushState({mode: this.value}); + return Index.pageLoad(false); + }, + + sort() { + const value = Index.selectRev.checked ? Index.selectSort.value + "-rev" : Index.selectSort.value; + Index.pushState({sort: value}); + return Index.pageLoad(false); + }, + + resort(e) { + Index.changed.order = true; + if (!e?.detail?.deferred) { return Index.pageLoad(false); } + }, + + perBoardSort() { + Conf['Index Sort'] = this.checked ? dict() : ''; + Index.saveSort(); + for (let i = 0; i < 2; i++) { + Conf[`Last Long Reply Thresholds ${i}`] = this.checked ? dict() : ''; + Index.saveLastLongThresholds(i); + } + }, + + lastLongThresholds() { + const i = [...Array.from(this.parentNode.children)].indexOf(this); + const value = +this.value; + if (!Number.isFinite(value)) { + this.value = Index.lastLongThresholds[i]; + return; + } + Index.lastLongThresholds[i] = value; + Index.saveLastLongThresholds(i); + Index.changed.order = true; + return Index.pageLoad(false); + }, + + size(e) { + if (Conf['Index Mode'] !== 'catalog') { + $$1.rmClass(Index.root, 'catalog-small'); + $$1.rmClass(Index.root, 'catalog-large'); + } else if (Conf['Index Size'] === 'small') { + $$1.addClass(Index.root, 'catalog-small'); + $$1.rmClass(Index.root, 'catalog-large'); + } else { + $$1.addClass(Index.root, 'catalog-large'); + $$1.rmClass(Index.root, 'catalog-small'); + } + if (e) { return Index.buildIndex(); } + }, + + replies() { + return Index.buildIndex(); + }, + + hover() { + return doc$1.classList.toggle('catalog-hover-expand', Conf['Catalog Hover Expand']); + }, + + hoverToggle(e) { + if (Conf['Catalog Hover Toggle'] && $$1.hasClass(doc$1, 'catalog-mode') && !$$1.modifiedClick(e) && !$$1.x('ancestor-or-self::a', e.target)) { + let thread; + const input = Index.inputs['Catalog Hover Expand']; + input.checked = !input.checked; + $$1.event('change', null, input); + if (thread = Get$1.threadFromNode(e.target)) { + Index.cb.catalogReplies.call(thread); + return Index.cb.hoverAdjust.call(thread.OP.nodes); + } + } + }, + + popstate(e) { + if (e?.state) { + const {searched, mode, sort} = e.state; + const page = Index.getCurrentPage(); + Index.setState({search: searched, mode, sort, page}); + return Index.pageLoad(false); + } else { + // page load or hash change + const nCommands = Index.processHash(); + if (Conf['Refreshed Navigation'] && nCommands) { + return Index.update(); + } else { + return Index.pageLoad(); + } + } + }, + + pageNav(e) { + let a; + if ($$1.modifiedClick(e)) { return; } + switch (e.target.nodeName) { + case 'BUTTON': + e.target.blur(); + a = e.target.parentNode; + break; + case 'A': + a = e.target; + break; + default: + return; + } + if (a.textContent === 'Catalog') { return; } + e.preventDefault(); + return Index.userPageNav(+a.pathname.split(/\/+/)[2] || 1); + }, + + refreshFront() { + Index.pushState({page: 1}); + return Index.update(); + }, + + catalogReplies() { + if (Conf['Show Replies'] && $$1.hasClass(doc$1, 'catalog-hover-expand') && !this.catalogView.nodes.replies) { + return Index.buildCatalogReplies(this); + } + }, + + hoverAdjust() { + // Prevent hovered catalog threads from going offscreen. + let x; + if (!$$1.hasClass(doc$1, 'catalog-hover-expand')) { return; } + const rect = this.post.getBoundingClientRect(); + if (x = $$1.minmax(0, -rect.left, doc$1.clientWidth - rect.right)) { + const {style} = this.post; + style.left = `${x}px`; + style.right = `${-x}px`; + return $$1.one(this.root, 'mouseleave', () => style.left = (style.right = null)); + } + } + }, + + scrollToIndex() { + // Scroll to navlinks, or top of board if navlinks are hidden. + return Header$1.scrollToIfNeeded((Index.navLinks.getBoundingClientRect().height ? Index.navLinks : Index.root)); + }, + + getCurrentPage() { + return +window.location.pathname.split(/\/+/)[2] || 1; + }, + + userPageNav(page) { + Index.pushState({page}); + if (Conf['Refreshed Navigation']) { + return Index.update(); + } else { + return Index.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() { + // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=483304 + let hash = location.href.match(/#.*/)?.[0] || ''; + const state = + {replace: true}; + const commands = hash.slice(1).split('/'); + const leftover = []; + for (var command of commands) { + var mode, sort; + if (mode = $$1.getOwn(Index.hashCommands.mode, command)) { + state.mode = mode; + } else if (command === 'index') { + state.mode = Conf['Previous Index Mode']; + state.page = 1; + } else if (sort = $$1.getOwn(Index.hashCommands.sort, command.replace(/-rev$/, ''))) { + state.sort = sort; + if (/-rev$/.test(command)) { state.sort += '-rev'; } + } else if (/^s=/.test(command)) { + state.search = decodeURIComponent(command.slice(2)).replace(/\+/g, ' ').trim(); + } else { + leftover.push(command); + } + } + hash = leftover.join('/'); + if (hash) { state.hash = `#${hash}`; } + Index.pushState(state); + return commands.length - leftover.length; + }, + + pushState(state) { + let {search, hash, replace} = state; + let pageBeforeSearch = history.state?.oldpage; + if ((search != null) && (search !== Index.search)) { + state.page = search ? 1 : (pageBeforeSearch || 1); + if (!search) { + pageBeforeSearch = undefined; + } else if (!Index.search) { + pageBeforeSearch = Index.currentPage; + } + } + Index.setState(state); + const pathname = Index.currentPage === 1 ? `/${g.BOARD}/` : `/${g.BOARD}/${Index.currentPage}`; + if (!hash) { hash = ''; } + return history[replace ? 'replaceState' : 'pushState']({ + mode: Conf['Index Mode'], + sort: Index.currentSort, + searched: Index.search, + oldpage: pageBeforeSearch + } + , '', `${location.protocol}//${location.host}${pathname}${hash}`); + }, + + setState({search, mode, sort, page, hash}) { + if ((search != null) && (search !== Index.search)) { + Index.changed.search = true; + Index.search = search; + } + if ((mode != null) && (mode !== Conf['Index Mode'])) { + Index.changed.mode = true; + Conf['Index Mode'] = mode; + $$1.set('Index Mode', mode); + if ((mode !== 'catalog') && (Conf['Previous Index Mode'] !== mode)) { + Conf['Previous Index Mode'] = mode; + $$1.set('Previous Index Mode', mode); + } + } + if ((sort != null) && (sort !== Index.currentSort)) { + Index.changed.sort = true; + Index.currentSort = sort; + Index.saveSort(); + } + if (['all pages', 'catalog'].includes(Conf['Index Mode'])) { page = 1; } + if ((page != null) && (page !== Index.currentPage)) { + Index.changed.page = true; + Index.currentPage = page; + } + if (hash != null) { + return Index.changed.hash = true; + } + }, + + savePerBoard(key, value) { + if (typeof Conf[key] === 'object') { + Conf[key][g.BOARD.ID] = value; + } else { + Conf[key] = value; + } + return $$1.set(key, Conf[key]); + }, + + saveSort() { + return Index.savePerBoard('Index Sort', Index.currentSort); + }, + + saveLastLongThresholds(i) { + return Index.savePerBoard(`Last Long Reply Thresholds ${i}`, Index.lastLongThresholds[i]); + }, + + pageLoad(scroll=true) { + if (!Index.liveThreadData) { return; } + let {threads, order, search, mode, sort, page, hash} = Index.changed; + if (!threads) { threads = search; } + if (!order) { order = sort; } + if (threads || order) { Index.sort(); } + if (threads) { Index.buildPagelist(); } + if (search) { Index.setupSearch(); } + if (mode) { Index.setupMode(); } + if (sort) { Index.setupSort(); } + if (threads || mode || page || order) { Index.buildIndex(); } + if (threads || page) { Index.setPage(); } + if (scroll && !hash) { Index.scrollToIndex(); } + if (hash) { Header$1.hashScroll(); } + return Index.changed = {}; + }, + + setupMode() { + for (var mode of ['paged', 'infinite', 'all pages', 'catalog']) { + $$1[mode === Conf['Index Mode'] ? 'addClass' : 'rmClass'](doc$1, `${mode.replace(/\ /g, '-')}-mode`); + } + Index.selectMode.value = Conf['Index Mode']; + Index.cb.size(); + Index.showHiddenThreads = false; + return $$1('#hidden-toggle a', Index.navLinks).textContent = 'Show'; + }, + + setupSort() { + Index.selectRev.checked = /-rev$/.test(Index.currentSort); + Index.selectSort.value = Index.currentSort.replace(/-rev$/, ''); + return Index.lastLongOptions.hidden = (Index.selectSort.value !== 'lastlong'); + }, + + getPagesNum() { + if (Index.search) { + return Math.ceil(Index.sortedThreadIDs.length / Index.threadsNumPerPage); + } else { + return Index.pagesNum; + } + }, + + getMaxPageNum() { + return Math.max(1, Index.getPagesNum()); + }, + + buildPagelist() { + const pagesRoot = $$1('.pages', Index.pagelist); + const maxPageNum = Index.getMaxPageNum(); + if (pagesRoot.childElementCount !== maxPageNum) { + const nodes = []; + for (let i = 1, end = maxPageNum; i <= end; i++) { + var a = $$1.el('a', { + textContent: i, + href: i === 1 ? './' : i + } + ); + nodes.push($$1.tn('['), a, $$1.tn('] ')); + } + $$1.rmAll(pagesRoot); + return $$1.add(pagesRoot, nodes); + } + }, + + setPage() { + let a, strong; + const pageNum = Index.currentPage; + const maxPageNum = Index.getMaxPageNum(); + const pagesRoot = $$1('.pages', Index.pagelist); + + // Previous/Next buttons + const prev = pagesRoot.previousElementSibling.firstElementChild; + const next = pagesRoot.nextElementSibling.firstElementChild; + let href = Math.max(pageNum - 1, 1); + prev.href = href === 1 ? './' : href; + prev.firstElementChild.disabled = href === pageNum; + href = Math.min(pageNum + 1, maxPageNum); + next.href = href === 1 ? './' : href; + next.firstElementChild.disabled = href === pageNum; + + // current page + if (strong = $$1('strong', pagesRoot)) { + if (+strong.textContent === pageNum) { return; } + $$1.replace(strong, strong.firstChild); + } else { + strong = $$1.el('strong'); + } + + if (a = pagesRoot.children[pageNum - 1]) { + $$1.before(a, strong); + return $$1.add(strong, a); + } + }, + + updateHideLabel() { + if (!Index.hideLabel) { return; } + let hiddenCount = 0; + for (var threadID of Index.liveThreadIDs) { + if (Index.isHidden(threadID)) { + hiddenCount++; + } + } + if (!hiddenCount) { + Index.hideLabel.hidden = true; + if (Index.showHiddenThreads) { Index.cb.toggleHiddenThreads(); } + return; + } + Index.hideLabel.hidden = false; + return $$1('#hidden-count', Index.navLinks).textContent = hiddenCount === 1 ? + '1 hidden thread' + : + `${hiddenCount} hidden threads`; + }, + + update(firstTime) { + let oldReq; + if (oldReq = Index.req) { + delete Index.req; + oldReq.abort(); + } + + if (Conf['Index Refresh Notifications']) { + // Optional notification for manual refreshes + if (!Index.notice) { Index.notice = new Notice('info', 'Refreshing index...'); } + if (!Index.nTimeout) { Index.nTimeout = setTimeout(() => { + if (Index.notice) { + Index.notice.el.lastElementChild.textContent += ' (disable JSON Index if this takes too long)'; + } + } + , 3 * SECOND); } + } else { + // Also display notice if Index Refresh is taking too long + if (!Index.nTimeout) { Index.nTimeout = setTimeout(() => Index.notice || (Index.notice = new Notice('info', 'Refreshing index... (disable JSON Index if this takes too long)')) + , 3 * SECOND); } + } + + // Hard refresh in case of incomplete page load. + if (!firstTime && (d$1.readyState !== 'loading') && !$$1('.board + *')) { + location.reload(); + return; + } + + Index.req = $$1.whenModified( + g.SITE.urls.catalogJSON({boardID: g.BOARD.ID}), + 'Index', + Index.load + ); + return $$1.addClass(Index.button, 'spin'); + }, + + load() { + let err; + if (this !== Index.req) { return; } // aborted + + $$1.rmClass(Index.button, 'spin'); + const {notice, nTimeout} = Index; + if (nTimeout) { clearTimeout(nTimeout); } + delete Index.nTimeout; + delete Index.req; + delete Index.notice; + + if (![200, 304].includes(this.status)) { + err = `Index refresh failed. ${this.status ? `Error ${this.statusText} (${this.status})` : 'Connection Error'}`; + if (notice) { + notice.setType('warning'); + notice.el.lastElementChild.textContent = err; + setTimeout(notice.close, SECOND); + } else { + new Notice('warning', err, 1); + } + return; + } + + try { + if (this.status === 200) { + Index.parse(this.response); + } else if (this.status === 304) { + Index.pageLoad(); + } + } catch (error) { + err = error; + c.error(`Index failure: ${err.message}`, err.stack); + if (notice) { + notice.setType('error'); + notice.el.lastElementChild.textContent = 'Index refresh failed.'; + setTimeout(notice.close, SECOND); + } else { + new Notice('error', 'Index refresh failed.', 1); + } + return; + } + + if (notice) { + if (Conf['Index Refresh Notifications']) { + notice.setType('success'); + notice.el.lastElementChild.textContent = 'Index refreshed!'; + setTimeout(notice.close, SECOND); + } else { + notice.close(); + } + } + + const timeEl = $$1('#index-last-refresh time', Index.navLinks); + timeEl.dataset.utc = Date.parse(this.getResponseHeader('Last-Modified')); + return RelativeDates.update(timeEl); + }, + + parse(pages) { + $$1.cleanCache(url => /^https?:\/\/a\.4cdn\.org\//.test(url)); + Index.parseThreadList(pages); + Index.changed.threads = true; + return Index.pageLoad(); + }, + + parseThreadList(pages) { + Index.pagesNum = pages.length; + Index.threadsNumPerPage = pages[0]?.threads.length || 1; + Index.liveThreadData = pages.reduce(((arr, next) => arr.concat(next.threads)), []); + Index.liveThreadIDs = Index.liveThreadData.map(data => data.no); + Index.liveThreadDict = dict(); + Index.threadPosition = dict(); + Index.parsedThreads = dict(); + Index.replyData = dict(); + for (let i = 0; i < Index.liveThreadData.length; i++) { + var obj, results; + var data = Index.liveThreadData[i]; + Index.liveThreadDict[data.no] = data; + Index.threadPosition[data.no] = i; + Index.parsedThreads[data.no] = (obj = g.SITE.Build.parseJSON(data, g.BOARD)); + obj.filterResults = (results = Filter.test(obj)); + obj.isOnTop = results.top; + obj.isHidden = results.hide || ThreadHiding.isHidden(obj.boardID, obj.threadID); + if (data.last_replies) { + for (var reply of data.last_replies) { + Index.replyData[`${g.BOARD}.${reply.no}`] = reply; + } + } + } + if (Index.liveThreadData[0]) { + g.SITE.Build.spoilerRange[g.BOARD.ID] = Index.liveThreadData[0].custom_spoiler; + } + g.BOARD.threads.forEach(function(thread) { + if (!Index.liveThreadIDs.includes(thread.ID)) { return thread.collect(); } + }); + $$1.event('IndexUpdate', + {threads: ((Index.liveThreadIDs.map((ID) => `${g.BOARD}.${ID}`)))}); + }, + + isHidden(threadID) { + let thread; + if ((thread = g.BOARD.threads.get(threadID)) && thread.OP && !thread.OP.isFetchedQuote) { + return thread.isHidden; + } else { + return Index.parsedThreads[threadID].isHidden; + } + }, + + isHiddenReply(threadID, replyData) { + return PostHiding.isHidden(g.BOARD.ID, threadID, replyData.no) || Filter.isHidden(g.SITE.Build.parseJSON(replyData, g.BOARD)); + }, + + buildThreads(threadIDs, isCatalog, withReplies) { + let errors; + const threads = []; + const newThreads = []; + let newPosts = []; + for (var ID of threadIDs) { + var opRoot, thread; + try { + var OP; + var threadData = Index.liveThreadDict[ID]; + + if (thread = g.BOARD.threads.get(ID)) { + var isStale = (thread.json !== threadData) && (JSON.stringify(thread.json) !== JSON.stringify(threadData)); + if (isStale) { + thread.setCount('post', threadData.replies + 1, threadData.bumplimit); + thread.setCount('file', threadData.images + !!threadData.ext, threadData.imagelimit); + thread.setStatus('Sticky', !!threadData.sticky); + thread.setStatus('Closed', !!threadData.closed); + } + if (thread.catalogView) { + $$1.rm(thread.catalogView.nodes.replies); + thread.catalogView.nodes.replies = null; + } + } else { + thread = new Thread(ID, g.BOARD); + newThreads.push(thread); + } + var lastPost = threadData.last_replies && threadData.last_replies.length ? threadData.last_replies[threadData.last_replies.length - 1].no : ID; + if (lastPost > thread.lastPost) { thread.lastPost = lastPost; } + thread.json = threadData; + threads.push(thread); + + if ((OP = thread.OP) && !OP.isFetchedQuote) { + OP.setCatalogOP(isCatalog); + thread.setPage(Math.floor(Index.threadPosition[ID] / Index.threadsNumPerPage) + 1); + } else { + var obj = Index.parsedThreads[ID]; + opRoot = g.SITE.Build.post(obj); + OP = new Post(opRoot, thread, g.BOARD); + OP.filterResults = obj.filterResults; + newPosts.push(OP); + } + + if (!isCatalog || !thread.nodes.root) { + g.SITE.Build.thread(thread, threadData, withReplies); + } + } catch (err) { + // Skip posts that we failed to parse. + if (!errors) { errors = []; } + errors.push({ + message: `Parsing of Thread No.${thread} failed. Thread will be skipped.`, + error: err, + html: opRoot?.outerHTML + }); + } + } + if (errors) { Main$1.handleErrors(errors); } + + if (withReplies) { + newPosts = newPosts.concat(Index.buildReplies(threads)); + } + + Main$1.callbackNodes('Thread', newThreads); + Main$1.callbackNodes('Post', newPosts); + Index.updateHideLabel(); + $$1.event('IndexRefreshInternal', {threadIDs: (threads.map((t) => t.fullID)), isCatalog}); + + return threads; + }, + + buildReplies(threads) { + let errors; + const posts = []; + for (var thread of threads) { + var lastReplies; + if (!(lastReplies = Index.liveThreadDict[thread.ID].last_replies)) { continue; } + var nodes = []; + for (var data of lastReplies) { + var node, post; + if ((post = thread.posts.get(data.no)) && !post.isFetchedQuote) { + nodes.push(post.nodes.root); + continue; + } + nodes.push(node = g.SITE.Build.postFromObject(data, thread.board.ID)); + try { + posts.push(new Post(node, thread, thread.board)); + } catch (err) { + // Skip posts that we failed to parse. + if (!errors) { errors = []; } + errors.push({ + message: `Parsing of Post No.${data.no} failed. Post will be skipped.`, + error: err, + html: node?.outerHTML + }); + } + } + $$1.add(thread.nodes.root, nodes); + } + + if (errors) { Main$1.handleErrors(errors); } + return posts; + }, + + buildCatalogViews(threads) { + const catalogThreads = []; + for (var thread of threads) { + if (!thread.catalogView) { + var {ID} = thread; + var page = Math.floor(Index.threadPosition[ID] / Index.threadsNumPerPage) + 1; + var root = g.SITE.Build.catalogThread(thread, Index.liveThreadDict[ID], page); + catalogThreads.push(new CatalogThread(root, thread)); + } + } + Main$1.callbackNodes('CatalogThread', catalogThreads); + }, + + sizeCatalogViews(threads) { + // XXX When browsers support CSS3 attr(), use it instead. + const size = Conf['Index Size'] === 'small' ? 150 : 250; + for (var thread of threads) { + var {thumb} = thread.catalogView.nodes; + var {width, height} = thumb.dataset; + if (!width) { continue; } + var ratio = size / Math.max(width, height); + thumb.style.width = (width * ratio) + 'px'; + thumb.style.height = (height * ratio) + 'px'; + } + }, + + buildCatalogReplies(thread) { + let lastReplies; + const {nodes} = thread.catalogView; + if (!(lastReplies = Index.liveThreadDict[thread.ID].last_replies)) { return; } + + const replies = []; + for (var data of lastReplies) { + if (Index.isHiddenReply(thread.ID, data)) { continue; } + var reply = g.SITE.Build.catalogReply(thread, data); + RelativeDates.update($$1('time', reply)); + $$1.on($$1('.catalog-reply-preview', reply), 'mouseover', QuotePreview.mouseover); + replies.push(reply); + } + + nodes.replies = $$1.el('div', {className: 'catalog-replies'}); + $$1.add(nodes.replies, replies); + $$1.add(thread.OP.nodes.post, nodes.replies); + }, + + sort() { + let threadIDs; + const {liveThreadIDs, liveThreadData} = Index; + if (!liveThreadData) { return; } + const tmp_time = new Date().getTime()/1000; + const sortType = Index.currentSort.replace(/-rev$/, ''); + Index.sortedThreadIDs = (() => { switch (sortType) { + case 'lastreply': case 'lastlong': + var repliesAvailable = liveThreadData.some(thread => thread.last_replies?.length); + var lastlong = function(thread) { + if (!repliesAvailable) { + return thread.last_modified; + } + const iterable = thread.last_replies || []; + for (let i = iterable.length - 1; i >= 0; i--) { + var r = iterable[i]; + if (Index.isHiddenReply(thread.no, r)) { continue; } + if (sortType === 'lastreply') { + return r; + } + var len = r.com ? g.SITE.Build.parseComment(r.com).replace(/[^a-z]/ig, '').length : 0; + if (len >= Index.lastLongThresholds[+!!r.ext]) { + return r; + } + } + if (thread.omitted_posts && thread.last_replies?.length) { return thread.last_replies[0]; } else { return thread; } + }; + var lastlongD = dict(); + for (var thread of liveThreadData) { + lastlongD[thread.no] = lastlong(thread).no; + } + return [...Array.from(liveThreadData)].sort((a, b) => lastlongD[b.no] - lastlongD[a.no]).map(post => post.no); + case 'bump': return liveThreadIDs; + case 'birth': return [...Array.from(liveThreadIDs) ].sort((a, b) => b - a); + case 'replycount': return [...Array.from(liveThreadData)].sort((a, b) => b.replies - a.replies).map(post => post.no); + case 'filecount': return [...Array.from(liveThreadData)].sort((a, b) => b.images - a.images).map(post => post.no); + case 'activity': return [...Array.from(liveThreadData)].sort((a, b) => ((tmp_time-a.time)/(a.replies+1)) - ((tmp_time-b.time)/(b.replies+1))).map(post => post.no); + default: return liveThreadIDs; + } })(); + if (/-rev$/.test(Index.currentSort)) { + Index.sortedThreadIDs = [...Array.from(Index.sortedThreadIDs)].reverse(); + } + if (Index.search && (threadIDs = Index.querySearch(Index.search))) { + Index.sortedThreadIDs = threadIDs; + } + // Sticky threads + Index.sortOnTop(obj => obj.isSticky); + // Highlighted threads + Index.sortOnTop(obj => obj.isOnTop || (Conf['Pin Watched Threads'] && ThreadWatcher$1.isWatchedRaw(obj.boardID, obj.threadID))); + // Non-hidden threads + if (Conf['Anchor Hidden Threads']) { return Index.sortOnTop(obj => !Index.isHidden(obj.threadID)); } + }, + + sortOnTop(match) { + const topThreads = []; + const bottomThreads = []; + for (var ID of Index.sortedThreadIDs) { + (match(Index.parsedThreads[ID]) ? topThreads : bottomThreads).push(ID); + } + return Index.sortedThreadIDs = topThreads.concat(bottomThreads); + }, + + buildIndex() { + let threadIDs; + if (!Index.liveThreadData) { return; } + switch (Conf['Index Mode']) { + case 'all pages': + threadIDs = Index.sortedThreadIDs; + break; + case 'catalog': + threadIDs = Index.sortedThreadIDs.filter(ID => !Index.isHidden(ID) !== Index.showHiddenThreads); + break; + default: + threadIDs = Index.threadsOnPage(Index.currentPage); + } + delete Index.pageNum; + $$1.rmAll(Index.root); + $$1.rmAll(Header$1.hover); + if (Index.loaded && Index.root.parentNode) { + $$1.event('PostsRemoved', null, Index.root); + } + if (Conf['Index Mode'] === 'catalog') { + Index.buildCatalog(threadIDs); + } else { + Index.buildStructure(threadIDs); + } + }, + + threadsOnPage(pageNum) { + const nodesPerPage = Index.threadsNumPerPage; + const offset = nodesPerPage * (pageNum - 1); + return Index.sortedThreadIDs.slice(offset , offset + nodesPerPage); + }, + + buildStructure(threadIDs) { + const threads = Index.buildThreads(threadIDs, false, Conf['Show Replies']); + const nodes = []; + for (var thread of threads) { + nodes.push(thread.nodes.root, $$1.el('hr')); + } + $$1.add(Index.root, nodes); + if (Index.root.parentNode) { + $$1.event('PostsInserted', null, Index.root); + } + Index.loaded = true; + }, + + buildCatalog(threadIDs) { + let i = 0; + const n = threadIDs.length; + let node0 = null; + var fn = function() { + if (node0 && !node0.parentNode) { return; } // Index.root cleared + const j = (i > 0) && Index.root.parentNode ? n : i + 30; + node0 = Index.buildCatalogPart(threadIDs.slice(i, j))[0]; + i = j; + if (i < n) { + return $$1.queueTask(fn); + } else { + if (Index.root.parentNode) { + $$1.event('PostsInserted', null, Index.root); + } + return Index.loaded = true; + } + }; + fn(); + }, + + buildCatalogPart(threadIDs) { + const threads = Index.buildThreads(threadIDs, true); + Index.buildCatalogViews(threads); + Index.sizeCatalogViews(threads); + const nodes = []; + for (var thread of threads) { + thread.OP.setCatalogOP(true); + $$1.add(thread.catalogView.nodes.root, thread.OP.nodes.root); + nodes.push(thread.catalogView.nodes.root); + $$1.on(thread.catalogView.nodes.root, 'mouseenter', Index.cb.catalogReplies.bind(thread)); + $$1.on(thread.OP.nodes.root, 'mouseenter', Index.cb.hoverAdjust.bind(thread.OP.nodes)); + } + $$1.add(Index.root, nodes); + return nodes; + }, + + clearSearch() { + Index.searchInput.value = ''; + Index.onSearchInput(); + return Index.searchInput.focus(); + }, + + setupSearch() { + Index.searchInput.value = Index.search; + if (Index.search) { + return Index.searchInput.dataset.searching = 1; + } else { + // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=1021289 + return Index.searchInput.removeAttribute('data-searching'); + } + }, + + onSearchInput() { + const search = Index.searchInput.value.trim(); + if (search === Index.search) { return; } + Index.pushState({ + search, + replace: !!search === !!Index.search + }); + return Index.pageLoad(false); + }, + + querySearch(query) { + let keywords, match; + if (match = query.match(/^([\w+]+):\/(.*)\/(\w*)$/)) { + let regexp; + try { + regexp = RegExp(match[2], match[3]); + } catch (error) { + return []; + } + return Index.sortedThreadIDs.filter(ID => regexp.test(Filter.values(match[1], Index.parsedThreads[ID]).join('\n'))); + } + if (!(keywords = query.toLowerCase().match(/\S+/g))) { return; } + return Index.sortedThreadIDs.filter(ID => Index.searchMatch(Index.parsedThreads[ID], keywords)); + }, + + searchMatch(obj, keywords) { + const {info, file} = obj; + if (info.comment == null) { info.comment = g.SITE.Build.parseComment(info.commentHTML.innerHTML); } + let text = []; + for (var key of ['comment', 'subject', 'name', 'tripcode']) { + if (key in info) { text.push(info[key]); } + } + if (file) { text.push(file.name); } + text = text.join(' ').toLowerCase(); + for (var keyword of keywords) { + if (-1 === text.indexOf(keyword)) { return false; } + } + return true; + } + }; + var Index$1 = Index; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ThreadHiding = { + init() { + if (!['index', 'catalog'].includes(g.VIEW) || (!Conf['Thread Hiding Buttons'] && !(Conf['Menu'] && Conf['Thread Hiding Link']) && !Conf['JSON Index'])) { return; } + this.db = new DataBoard('hiddenThreads'); + if (g.VIEW === 'catalog') { return this.catalogWatch(); } + this.catalogSet(g.BOARD); + $$1.on(d$1, 'IndexRefreshInternal', this.onIndexRefresh); + if (Conf['Thread Hiding Buttons']) { + $$1.addClass(doc$1, 'thread-hide'); + } + return Callbacks.Post.push({ + name: 'Thread Hiding', + cb: this.node + }); + }, + + catalogSet(board) { + if (!$$1.hasStorage || (g.SITE.software !== 'yotsuba')) { return; } + const hiddenThreads = ThreadHiding.db.get({ + boardID: board.ID, + defaultValue: dict() + }); + for (var threadID in hiddenThreads) { hiddenThreads[threadID] = true; } + return localStorage.setItem(`4chan-hide-t-${board}`, JSON.stringify(hiddenThreads)); + }, + + catalogWatch() { + if (!$$1.hasStorage || (g.SITE.software !== 'yotsuba')) { return; } + this.hiddenThreads = JSON.parse(localStorage.getItem(`4chan-hide-t-${g.BOARD}`)) || {}; + return Main$1.ready(() => // 4chan's catalog sets the style to "display: none;" when hiding or unhiding a thread. + new MutationObserver(ThreadHiding.catalogSave).observe($$1.id('threads'), { + attributes: true, + subtree: true, + attributeFilter: ['style'] + })); + }, + + catalogSave() { + let threadID; + const hiddenThreads2 = JSON.parse(localStorage.getItem(`4chan-hide-t-${g.BOARD}`)) || {}; + for (threadID in hiddenThreads2) { + if (!$$1.hasOwn(ThreadHiding.hiddenThreads, threadID)) { + ThreadHiding.db.set({ + boardID: g.BOARD.ID, + threadID, + val: {makeStub: Conf['Stubs']}}); + } + } + for (threadID in ThreadHiding.hiddenThreads) { + if (!$$1.hasOwn(hiddenThreads2, threadID)) { + ThreadHiding.db.delete({ + boardID: g.BOARD.ID, + threadID + }); + } + } + return ThreadHiding.hiddenThreads = hiddenThreads2; + }, + + isHidden(boardID, threadID) { + return !!(ThreadHiding.db && ThreadHiding.db.get({boardID, threadID})); + }, + + node() { + let data; + if (this.isReply || this.isClone || this.isFetchedQuote) { return; } + + if (Conf['Thread Hiding Buttons']) { + $$1.prepend(this.nodes.root, ThreadHiding.makeButton(this.thread, 'hide')); + } + + if (data = ThreadHiding.db.get({boardID: this.board.ID, threadID: this.ID})) { + return ThreadHiding.hide(this.thread, data.makeStub); + } + }, + + onIndexRefresh() { + return g.BOARD.threads.forEach(function(thread) { + const {root} = thread.nodes; + if (thread.isHidden && thread.stub && !root.contains(thread.stub)) { + return ThreadHiding.makeStub(thread, root); + } + }); + }, + + menu: { + init() { + if ((g.VIEW !== 'index') || !Conf['Menu'] || !Conf['Thread Hiding Link']) { return; } + + let div = $$1.el('div', { + className: 'hide-thread-link', + textContent: 'Hide' + } + ); + + const apply = $$1.el('a', { + textContent: 'Apply', + href: 'javascript:;' + } + ); + $$1.on(apply, 'click', ThreadHiding.menu.hide); + + const makeStub = UI.checkbox('Stubs', 'Make stub'); + + Menu.menu.addEntry({ + el: div, + order: 20, + open({thread, isReply}) { + if (isReply || thread.isHidden || (Conf['JSON Index'] && (Conf['Index Mode'] === 'catalog'))) { + return false; + } + ThreadHiding.menu.thread = thread; + return true; + }, + subEntries: [{el: apply}, {el: makeStub}]}); + + div = $$1.el('a', { + className: 'show-thread-link', + textContent: 'Show', + href: 'javascript:;' + } + ); + $$1.on(div, 'click', ThreadHiding.menu.show); + + Menu.menu.addEntry({ + el: div, + order: 20, + open({thread, isReply}) { + if (isReply || !thread.isHidden || (Conf['JSON Index'] && (Conf['Index Mode'] === 'catalog'))) { + return false; + } + ThreadHiding.menu.thread = thread; + return true; + } + }); + + const hideStubLink = $$1.el('a', { + textContent: 'Hide stub', + href: 'javascript:;' + } + ); + $$1.on(hideStubLink, 'click', ThreadHiding.menu.hideStub); + + return Menu.menu.addEntry({ + el: hideStubLink, + order: 15, + open({thread, isReply}) { + if (isReply || !thread.isHidden || (Conf['JSON Index'] && (Conf['Index Mode'] === 'catalog'))) { + return false; + } + return ThreadHiding.menu.thread = thread; + } + }); + }, + + hide() { + const makeStub = $$1('input', this.parentNode).checked; + const {thread} = ThreadHiding.menu; + ThreadHiding.hide(thread, makeStub); + ThreadHiding.saveHiddenState(thread, makeStub); + return $$1.event('CloseMenu'); + }, + + show() { + const {thread} = ThreadHiding.menu; + ThreadHiding.show(thread); + ThreadHiding.saveHiddenState(thread); + return $$1.event('CloseMenu'); + }, + + hideStub() { + const {thread} = ThreadHiding.menu; + ThreadHiding.show(thread); + ThreadHiding.hide(thread, false); + ThreadHiding.saveHiddenState(thread, false); + $$1.event('CloseMenu'); + } + }, + + makeButton(thread, type) { + const a = $$1.el('a', { + className: `${type}-thread-button`, + href: 'javascript:;' + } + ); + $$1.extend(a, {textContent: type === "hide" ? '➖︎' : '➕︎' }); + a.dataset.fullID = thread.fullID; + $$1.on(a, 'click', ThreadHiding.toggle); + return a; + }, + + makeStub(thread, root) { + let summary, threadDivider; + let numReplies = $$(g.SITE.selectors.replyOriginal, root).length; + if (summary = $$1(g.SITE.selectors.summary, root)) { numReplies += +summary.textContent.match(/\d+/); } + + const a = ThreadHiding.makeButton(thread, 'show'); + $$1.add(a, $$1.tn(` ${thread.OP.info.nameBlock} (${numReplies === 1 ? '1 reply' : `${numReplies} replies`})`)); + thread.stub = $$1.el('div', + {className: 'stub'}); + if (Conf['Menu']) { + $$1.add(thread.stub, [a, Menu.makeButton(thread.OP)]); + } else { + $$1.add(thread.stub, a); + } + $$1.prepend(root, thread.stub); + + // Prevent hiding of thread divider on sites that put it inside the thread + if (threadDivider = $$1(g.SITE.selectors.threadDivider, root)) { + return $$1.addClass(threadDivider, 'threadDivider'); + } + }, + + saveHiddenState(thread, makeStub) { + if (thread.isHidden) { + ThreadHiding.db.set({ + boardID: thread.board.ID, + threadID: thread.ID, + val: {makeStub}}); + } else { + ThreadHiding.db.delete({ + boardID: thread.board.ID, + threadID: thread.ID + }); + } + return ThreadHiding.catalogSet(thread.board); + }, + + toggle(thread) { + if (!(thread instanceof Thread)) { + thread = g.threads.get(this.dataset.fullID); + } + if (thread.isHidden) { + ThreadHiding.show(thread); + } else { + ThreadHiding.hide(thread); + } + return ThreadHiding.saveHiddenState(thread); + }, + + hide(thread, makeStub=Conf['Stubs']) { + if (thread.isHidden) { return; } + const threadRoot = thread.nodes.root; + thread.isHidden = true; + Index$1.updateHideLabel(); + if (thread.catalogView && !Index$1.showHiddenThreads) { + $$1.rm(thread.catalogView.nodes.root); + $$1.event('PostsRemoved', null, Index$1.root); + } + + if (!makeStub) { return threadRoot.hidden = true; } + + return ThreadHiding.makeStub(thread, threadRoot); + }, + + show(thread) { + if (thread.stub) { + $$1.rm(thread.stub); + delete thread.stub; + } + const threadRoot = thread.nodes.root; + threadRoot.hidden = (thread.isHidden = false); + Index$1.updateHideLabel(); + if (thread.catalogView && Index$1.showHiddenThreads) { + $$1.rm(thread.catalogView.nodes.root); + return $$1.event('PostsRemoved', null, Index$1.root); + } + } + }; + + /* + * This file has the code for the jsx to { innerHTML: "safe string" } + * + * Usage: import h from this file. + * Attributes are stringified raw, so the names must be like html text: eg class and not className. + * Boolean values are stringified as followed: true will mean the attribute is there, false means it will be omitted. + * Strings bound to attributes and children will be escaped automatically. + * It returns interface EscapedHtml { innerHTML: "safe string", [isEscaped]: true } + * + * For strings that don't have a parent element you can use fragments: <>. + * Note that you need to import hFragment, which for some reason isn't auto imported on "add all missing imports" + */ + /** + * The symbol indicating that a string is safely escaped. + * This is a symbol so it can't be faked by a json blob from the internet. + */ + const isEscaped = Symbol('isEscaped'); + const voidElements = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'source', 'track', 'wbr',]); + const hFragment = Symbol('hFragment'); + /** Function that jsx/tsx will be compiled to. */ + function h(tag, attributes, ...children) { + let innerHTML = tag === hFragment ? '' : `<${tag}`; + if (attributes) { + for (const [attribute, value] of Object.entries(attributes)) { + if (!value && value !== 0) + continue; + innerHTML += ` ${attribute}`; + if (value === true) + continue; + innerHTML += `="${E(value.toString())}"`; + } + } + if (tag !== hFragment) + innerHTML += '>'; + const isVoid = tag !== hFragment && voidElements.has(tag); + if (isVoid) { + if (children.length) + throw new TypeError(`${tag} is a void html element and can't have child elements`); + } + else { + for (const child of children) { + if (child === null || child === undefined || child === '') + continue; + if (child instanceof Object && "innerHTML" in child && child[isEscaped]) { + innerHTML += child.innerHTML; + continue; + } + innerHTML += E(child.toString()); + } + } + if (!isVoid && tag !== hFragment) + innerHTML += ``; + return { innerHTML, [isEscaped]: true }; + } + + // \u00A0 is non breaking space + const separator = '\u00A0|\u00A0'; + const settingsHtml = h("div", { id: "fourchanx-settings", class: "dialog" }, + h("nav", null, + h("div", { class: "sections-list" }), + h("p", { class: "imp-exp-result warning" }), + h("div", { class: "credits" }, + h("a", { class: "export" }, "Export"), + separator, + h("a", { class: "import" }, "Import"), + separator, + h("a", { class: "reset" }, "Reset Settings"), + separator, + h("input", { type: "file", hidden: true }), + h("a", { href: meta.page, target: "_blank" }, meta.name), + separator, + h("a", { href: meta.changelog, target: "_blank" }, g.VERSION), + separator, + h("a", { href: meta.issues, target: "_blank" }, "Issues"), + separator, + h("a", { href: "javascript:;", class: "close", title: "Close" }, "\u2715"))), + h("div", { class: "section-container" }, + h("section", null))); + + var FilterGuidePage = `
            Filter is disabled.
            +

            + Use regular expressions, one per line.
            + Lines starting with a # will be ignored.
            + For example, /weeaboo/i will filter posts containing the string \`weeaboo\`, case-insensitive.
            + MD5 and Unique ID filtering use exact string matching, not regular expressions. +

            +
              You can use these settings with each regular expression, separate them with semicolons: +
            • + Per boards, separate them with commas. It is global if not specified. Use sfw and nsfw to reference all worksafe or not-worksafe boards.
              + For example: boards:a,jp;.
              + To specify boards on a particular site, put the beginning of the domain and a slash character before the list.
              + Any initial www. should not be included, and all 4chan domains are considered 4chan.org.
              + For example: boards:4:a,jp,sama:a,z;.
              + An asterisk can be used to specify all boards on a site.
              + For example: boards:4:*;.
              +
            • +
            • + Select boards to be excluded from the filter. The syntax is the same as for the boards: option above.
              + For example: exclude:vg,v;. +
            • +
            • + Filter OPs only along with their threads (\`only\`) or replies only (\`no\`).
              + For example: op:only; or op:no;. +
            • +
            • + Filter only posts with files (\`only\`) or only posts without files (\`no\`).
              + For example: file:only; or file:no;. +
            • +
            • + Overrule the \`Show Stubs\` setting if specified: create a stub (\`yes\`) or not (\`no\`).
              + For example: stub:yes; or stub:no;. +
            • +
            • + Highlight instead of hiding. You can specify a class name to use with a userstyle.
              + For example: highlight; or highlight:wallpaper;. +
            • +
            • + Highlighted OPs will have their threads put on top of the board index by default.
              + For example: top:yes; or top:no;. +
            • +
            • + Show a desktop notification instead of hiding.
              + For example: notify;. +
            • +
            • + Filters in the "General" section apply to multiple fields, by default subject,name,filename,comment.
              + The fields can be specified with the type option, separated by commas.
              + For example: type:@{filterTypes};.
              + Types can also be combined with a + sign; this indicates the filter applies to the given fields joined by newlines.
              + For example: type:filename+filesize+dimensions;.
              +
            • +
            +`; + + var SaucePage = `
            Sauce is disabled.
            + +
            + +
            These parameters will be replaced by their corresponding values in the URL and displayed text:
            +
              +
            • %IMG: Full image URL for GIF, JPG, and PNG; thumbnail URL for other types.
            • +
            • %URL: Full image URL.
            • +
            • %TURL: Thumbnail URL.
            • +
            • %name: Original file name.
            • +
            • %board: Current board.
            • +
            • %MD5: MD5 hash in base64.
            • +
            • %sMD5: MD5 hash in base64 using - and _.
            • +
            • %hMD5: MD5 hash in hexadecimal.
            • +
            • %$0: Matched regular expression within the filename.
            • +
            • %$1, %$2, %$3, ... : Subexpressions within the matched regular expression.
            • +
            • %%, %semi: Literal % and ;.
            • +
            +
            Lines starting with a # will be ignored.
            +
            You can specify a display text by appending ;text:[text] to the URL.
            +
            You can specify the applicable boards/sites by appending ;boards:[board1],[board2]. See the Filter guide for details.
            +
            You can specify the applicable file types by appending ;types:[extension1],[extension2].
            +
            You can specify a regular expression the filename must match by appending ;regexp:[regular expression].
            +
            + +`; + + var AdvancedPage = `
            + Archives +
            404 Redirect is disabled.
            + + + + + + + + +
            Thread redirectionPost fetchingFile redirection
            +
            +
            + Archive Lists: Each line below should be an archive list in this format or a URL to load an archive list from.
            + Archive properties can be overriden by another item with the same uid (or if absent, its name). +
            + + Last updated: +
            + +
            + External Catalog +
            External Catalog is disabled. This will be used only as a fallback.
            +
            + URLs of external catalog sites, where %board is to be replaced by the board name.
            + Each URL should be followed by ;boards: and optionally ;exclude: and a list of supported/excluded boards in the format explained in the Filter guide. +
            + +
            + +
            + Override 4chan Image Host +
            Change 4chan image links to this domain. Leave blank for no change.
            +
            + +
            + +
            + Captcha Language +
            Choose from list of language codes. Leave blank to autoselect.
            +
            +
            + +
            + Custom Board Navigation +
            + New lines will be converted into spaces.

            +
            In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
            +
            Board link: g
            +
            Archive link: g-archive
            +
            Internal archive link: g-expired
            +
            Title link: g-title
            +
            Board link (Replace with title when on that board): g-replace
            +
            Full text link: g-full
            +
            Custom text link: g-text:"Install Gentoo"
            +
            Index-only link: g-index
            +
            Catalog-only link: g-catalog
            +
            Index mode: g-mode:"infinite scrolling"
            +
            Index sort: g-sort:"creation date rev"
            +
            External link: external-text:"Google","http://www.google.com"
            +
            Open in new tab: g-nt
            +
            Combinations are possible: g-index-text:"Technology Index"
            +
            Full board list toggle: toggle-all
            +
            +
            + [ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:"Piracy"]
            + will give you
            + [ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]
            + if you are on /g/. +
            +
            + +
            + Time Formatting is disabled. +
            :
            + +
            Day: %a, %A, %d, %e
            +
            Month: %m, %b, %B
            +
            Year: %y, %Y
            +
            Hour: %k, %H, %l, %I, %p, %P
            +
            Minute: %M
            +
            Second: %S
            +
            Literal %: %%
            + +
            + +
            + Quote Backlinks formatting is disabled. +
            :
            +
            + +
            + Default pasted content filename +
            .png
            +
            + +
            + File Info Formatting is disabled. +
            :
            +
            Link: %l (truncated), %L (untruncated), %T (4chan filename)
            +
            Filename: %n (truncated), %N (untruncated), %t (4chan filename)
            +
            Download button: %d
            +
            Quick filter MD5: %f
            +
            Spoiler indicator: %p
            +
            Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
            +
            Resolution: %r (Displays 'PDF' for PDF files)
            +
            Tag: %g +
            Literal %: %%
            +
            + +
            + Quick Reply Personas + +

            + One item per line.
            + Items will be added in the relevant input's auto-completion list.
            + Password items will always be used, since there is no password input.
            + Lines starting with a # will be ignored. +

            +
              You can use these settings with each item, separate them with semicolons: +
            • Possible items are: name, options (or equivalently email), subject and password.
            • +
            • Wrap values of items with quotes, like this: options:"sage".
            • +
            • Force values as defaults with the always keyword, for example: options:"sage";always.
            • +
            • Select specific boards for an item, separated with commas, for example: options:"sage";boards:jp;always.
            • +
            +
            + +
            + Unread Favicon is disabled. + + +
            + +
            + Thread Updater is disabled. +
            + Interval: seconds +
            +
            + +
            + Custom Cooldown Time +
            + Seconds: +
            +
            + +
            + + + +
            For more information about customizing 4chan X's CSS, see the styling guide.
            + + +
            + +
            + Javascript Whitelist +
            + Sources from which Javascript is allowed to be loaded by Content Security Policy.
            + Lines starting with a # will be ignored. +
            + +
            + +
            + Known Banners +
            List of known banners, used for click-to-change feature.
            + +
            +`; + + var KeybindsPage = `
            Keybinds are disabled.
            +
            Allowed keys: a-z, 0-9, Ctrl, Shift, Alt, Meta, Enter, Esc, Up, Down, Right, Left.
            +
            Press Backspace to disable a keybind.
            + + +
            ActionsKeybinds
            +`; + + var FilterSelectPage = ` +
            +`; + + var burichan = `/* General */ +:root.burichan .dialog { + background-color: #D6DAF0; + border-color: #B7C5D9; +} +:root.burichan .field:focus, +:root.burichan .field.focus { + border-color: #98E; +} + +/* Header */ +:root.burichan #header-bar.dialog { + background-color: rgba(214,218,240,0.98); +} +:root.burichan:not(.fixed) #header-bar, :root.burichan #header-bar #notifications { + font-size: 11pt; +} +:root.burichan #header-bar, :root.burichan #header-bar #notifications { + color: #89A; +} +:root.burichan #header-bar a, :root.burichan #header-bar #notifications a { + color: #34345C; +} + +/* Settings */ +:root.burichan #fourchanx-settings fieldset, :root.burichan .section-main div::before { + border-color: #B7C5D9; +} +:root.burichan .suboption-list > div:last-of-type { + background-color: #D6DAF0; +} + +/* Catalog */ +:root.burichan.catalog-hover-expand .catalog-container:hover > .post { + background-color: #D6DAF0; +} +:root.burichan.werkTyme .catalog-thread:not(:hover), +:root.burichan.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.burichan.catalog-hover-expand .catalog-container:hover > .post, +:root.burichan.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #B7C5D9; +} + +/* Quote */ +:root.burichan .backlink.deadlink { + color: #34345C !important; +} +:root.burichan .inline { + border-color: #B7C5D9; + background-color: rgba(255, 255, 255, .14); +} + +/* Fappe and Werk Tyme */ +:root.burichan .indicator { + color: #D6DAF0; +} + +/* Anonymize */ +:root.burichan.anonymize $site$info$name::before { + font-size: 12pt; +} + +/* QR */ +.burichan #dump-list::-webkit-scrollbar-thumb { + background-color: #D6DAF0; + border-color: #B7C5D9; +} +:root.burichan .qr-preview { + background-color: rgba(0, 0, 0, .15); +} +:root.burichan .qr-link { + border-color: rgb(199, 203, 225) rgb(199, 203, 225) rgb(184, 188, 210); + background: linear-gradient(#E5E9FF, #D6DAF0) repeat scroll 0% 0% transparent; +} +:root.burichan .qr-link:hover { + background: #D9DDF3; +} + +/* Menu */ +:root.burichan #menu { + color: #000000; +} +:root.burichan .entry { + font-size: 12pt; +} +:root.burichan .focused.entry { + background: rgba(255, 255, 255, .33); +} + +/* Unread */ +:root.burichan .unread-mark-read { + background-color: rgba(214,218,240,0.5); +} + +/* Thread Watcher */ +:root.burichan .replies-quoting-you > a, :root.burichan #watcher-link.replies-quoting-you, :root.burichan .last-page > a > .watcher-page { + color: #F00; +} + +/* Watcher Favicon */ +:root.burichan .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + var futaba = `/* General */ +:root.futaba .dialog { + background-color: #F0E0D6; + border-color: #D9BFB7; +} +:root.futaba .field:focus, +:root.futaba .field.focus { + border-color: #EA8; +} + +/* Header */ +:root.futaba #header-bar.dialog { + background-color: rgba(240,224,214,0.98); +} +:root.futaba:not(.fixed) #header-bar, :root.futaba #notifications { + font-size: 11pt; +} +:root.futaba #header-bar, :root.futaba #notifications { + color: #B86; +} +:root.futaba #header-bar a, :root.futaba #notifications a { + color: #800000; +} + +/* Settings */ +:root.futaba #fourchanx-settings fieldset, :root.futaba .section-main div::before { + border-color: #D9BFB7; +} +:root.futaba .suboption-list > div:last-of-type { + background-color: #F0E0D6; +} + +/* Catalog */ +:root.futaba.catalog-hover-expand .catalog-container:hover > .post { + background-color: #F0E0D6; +} +:root.futaba.werkTyme .catalog-thread:not(:hover), +:root.futaba.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.futaba.catalog-hover-expand .catalog-container:hover > .post, +:root.futaba.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #D9BFB7; +} + +/* Quote */ +:root.futaba .backlink.deadlink { + color: #00E !important; +} +:root.futaba .inline { + border-color: #D9BFB7; + background-color: rgba(255, 255, 255, .14); +} + +/* Fappe and Werk Tyme */ +:root.futaba .indicator { + color: #F0E0D6; +} + +/* Anonymize */ +:root.futaba.anonymize $site$info$name::before { + font-size: 12pt; +} + +/* QR */ +.futaba #dump-list::-webkit-scrollbar-thumb { + background-color: #F0E0D6; + border-color: #D9BFB7; +} +:root.futaba .qr-preview { + background-color: rgba(0, 0, 0, .15); +} +:root.futaba .qr-link { + border-color: rgb(225, 209, 199) rgb(225, 209, 199) rgb(210, 194, 184); + background: linear-gradient(#FFEFE5, #F0E0D6) repeat scroll 0% 0% transparent; +} +:root.futaba .qr-link:hover { + background: #F0E0D6; +} + +/* Menu */ +:root.futaba #menu { + color: #800000; +} +:root.futaba .entry { + font-size: 12pt; +} +:root.futaba .focused.entry { + background: rgba(255, 255, 255, .33); +} + +/* Unread */ +:root.futaba .unread-mark-read { + background-color: rgba(240,224,214,0.5); +} + +/* Thread Watcher */ +:root.futaba .replies-quoting-you > a, :root.futaba #watcher-link.replies-quoting-you, :root.futaba .last-page > a > .watcher-page { + color: #F00; +} + +/* Watcher Favicon */ +:root.futaba .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + var linkifyAudio = '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=='; + + var linkifyBitchute = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAadQTFRFAAAAwzw8xDs7cY6O0iws0ysrtF9f0Sws1CwsyzU1zTIy1igoyzQ01icnY7i4t0hI0S4u0ysr1Soq1ikp1ikp1Soq0ysr0S4uu0VFzjEx1Csr1ygo2Ccn2Ccn1ygo1CoqzjExzjAw1Skp2Ccn2Ccn1ikp0TAwxzY21Soq1SoqyzQ00iws1ygo1ygo0yws1Soq1Skp1igo1igo1igo1igo1igo1igo1Coq1Soq0C0t1ygo1ygo0S4unV5e1Csr1ygo1ygo1CsruUdHxzg41Skp1ygo1CsryTU10C4u1igo1ycn1ygo0i0txjo60S0t1ikp1ygo1ikp1Cws1Coq1Coq0yws0S0tyzQ00iws1Soq0ysr0i0txDs72Ccn2CUl2CYm2CQk3EFB2S8v2zw82jY24FZW3D0931FR3EBA3UND8LS04FVV7qys4V9f4WBg+erq766u9t7e7qqq2Ckp54KC9+Pj6pSU+Ojo5XNz9NHR6YqK8bu765ub5G5u9M3N6ImJ88vL5XV165eX3UVF6pWV3UhI2Soq2jU12Coq2jQ02Cgo2Sws////FaxLuAAAAF10Uk5TAAAAAAAAAAAAAAAAAAAAASJnoLy9oWolAhBz1vr72XgTGKf8/a4cCpuiDVvz9mS6xOvy9vzg6aGsPOToRAFv9fh2Awm07XgIMd765UEDOsfemVhhY00nBommbCkEI8horgAAAL5JREFUKBUFwbFKA0EUQNF7387sMq4EmzRpLSSdIBYKFv6Af2prnSYkRT4gWFgkCBJQ0EIFdcZzBCeqqh4qdk7VW2ChPusw02sAYKU7z7wEAAA2piQKFbrWSHazc1J0XWs5pdxPDykcVX+7Y9UxUsSo+s7PibqPFBRV/C5qi4i/UkrJrc7L47Bt4ZWnUaMCAE9GSrtKBQD2fR+bnAEAeOn7dUTOwApe35bDsPz0zsniQlV98IN0tJ3f6P0XAMA/kxou7OXCdnoAAAAASUVORK5CYII='; + + var linkifyClyp = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAwUExURTSY22ey5E2l4KbS75rM7Y3F64C/6f///8zl9nS45r/f9PL5/UGe3bPY8Vqr4v///wNjrzUAAAABYktHRA8YugDZAAAAB3RJTUUH4AINEi85AIH95AAAAE9JREFUCNdjYMAGGBWgDGYHCM2a3hkAZmi0dzSBaKaO9o5moCqmLiCjYzNQyw4QowIodQzI6E0AKcpo72gE6+Jyb1kAMehUA9RktgdYbQYAjGIVNGGXBJkAAAAASUVORK5CYII='; + + var linkifyDailymotion = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAnUExURQBk3ff6/trp+kKO5wZt3xx54q7P9Ozz/IS17zOG5WKh653E8sbc9/GbbcoAAABZSURBVAjXY2BAASyhDhAGc9oECMOjyAAiESEEYrBYpLWBGcwHxcvBjDDxHelghpF0yDQwY3kVgweEUeEQDWbMEepqAjO8FMsLIeYsU8o+BrbCdWboTAe4AwALXxWGjW41FwAAAABJRU5ErkJggg=='; + + var linkifyGfycat = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAjVBMVEWn3gCo3gSr3w2t4BSu4Bav4Ri35C+45DK45DO55DXA50rA50vB50zC6E/D6FTF6VjG6VvL62vN7G/P7XbQ7XfW74vY8JDa8ZTe8qDe8qLf86Pi9Kzj9K7k9LHp9sDp98Lq98Ps+Mr0++L5/O75/fD6/fH6/fL6/fP7/fT7/fb8/ff8/vj8/vn+/v7///91X4cfAAAAcklEQVR42o3M2xKBUACF4aVQckrIuRJK6H//x2sme4/MuPDfre9i6c/Cc3U5Dj87BuAxsXvGu6JvIIXEHRWwNHCHQNrCzkAFkbSBg4EM8i+Yw7PXBa3zRfuxVyf/Bis7nKwGKAcWxgC8prI5Sc315OlnDfzpDar2S9/oAAAAAElFTkSuQmCC'; + + var linkifyGist = '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=='; + + var linkifyImage = '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='; + + var linkifyInstallgentoo = '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'; + + var linkifyLiveleak = '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='; + + var linkifyPastebin = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB1FBMVEUAAAAAAAAAAABWYWwAAABbY3BbYm5dZnFdZXJeZnMEBAQHCAhYYGpdZnFdZnBgaHIlJyomKCooKi09QkdESU5eZGtdYmhdYmleY2lrcXdqb3Rqb3Rqb3SSmJ+SlJeWmJutr7GtrrCWm6ChpKhbW1tmZmZvb290dHR3d3d4eHh5eXl6enp8fHx+gIJ/f3+CgoKDg4OEhISFhYWHh4eKioqKjI2Li4uMjIyOjo6Pj4+QkJCRkZGSkpKUlJSVl5mWlpaYmZqZm52ampqbm5ucnJydnZ2enp6fn5+hoaGioqKkpKSkpaalpaWmp6mmp6qnqauoqKioqquoqq2qqqqrrK2srKysra6srrCsrrGurq6vr6+wsLCxsbGysrKztLa0tLS1t7m2tra3t7e4uLi5ubm6urq7u7u8vLy9vb2+vr7AwMDAwsTBwcHExcfFxcXFxsnGxsbHx8fIyMjJycnMzMzNzc3Ozs7O0NLPz8/Q0NDR0dHR09XT09PV1dXV1dbV1tfV19rW1tbX19fX19jY2tzZ2dnZ2tva2tra3N3a3N7c3Nze3t7f39/f4OHg4ODi4uLl5+jm5ubs7Ozs7e3u7u7v7+/v8PDw8PDx8fHy8vLz8/P29vYSoLMZAAAAJHRSTlMABAUGCwsNHCAiLzMzMzZEYGJwgIuOnJycnqmqq9bc3+/w8fkZ0N/uAAAA/klEQVQoU2NgYGDl5YMDdgYGBmZZ3964CYFtIR3e9Q7K/AwMHI55KfaFmcHWMy3K3MwlGRg4wz0zdYpcorRbNbL0LaWAAp3ts2umV8wo6MupTauQBgqUG03VL7W3sfZSb1erAgm02M+yzYrVCXUy6zapAQlUx/dEdyX3J3ZHVUYVywAF8o2rDNN1Go2jzGLMokAC2QbuSc42mXmaOXop9iAtCXrJ5qXWjT59Abl2ESJAAX/tSIMMiyrrqQ3T6uS5gQK6kSqpqkUermGTexQFmYACflqR+hlWZSamzQpCLEDPsSmVVDT1TJw0JUhOAMRnYOARFRMTE5cQF+ZiBPIAII5B3EVG0b4AAAAASUVORK5CYII='; + + var linkifyPeertube = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABIFBMVEUhHyAAAABzPBnxaA3CWBEnJSYbGRptbW16enpzc3PTayWhb04hHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyAhHyApIh+0UhMfHiBWMhvsZg7zaQ0hHyAhHyAXHCHzaQ3xaA3xaA3xaA3xaA0hHyAhHyDxaA3xaA3xaA3xaA3xaA3xaA0oJickIiMdGxwUEhPxaA3xaA3xaA1sbGxwcHB3d3eFhYXxaA3xaA3xaA1zc3Nzc3Nzc3Nzc3Nzc3PxaA3xaA3xaA1zc3Nzc3NtdHjxaA3xaA1yc3STcFnvaA/yaAxzc3N4c2/FbDFzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3MhHyDxaA1zc3MAAAAfljyVAAAAXHRSTlMAAAAAAAAAAAAAAAAZkjMBHOLXYArj8p0u2VsJ1XaGL/OhKyXc1WEN2gwk2/SjKgEYiS4B/tYFGosqAdleAxzj12ML9Z8s850rJWbYeYMs1F8Koiri1V0MGZY0AYbIBFIAAAABYktHRAH/Ai3eAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4wYXFBUVX81QWQAAAKxJREFUGNNVz9UWgkAQANDBtdbu7lZsxe7ubpH//wxBPKDzNvdMAmi0Oj0QQgAYjCazBX7BStvsDqHoAzTtdLklf+Dx+vwICRAIhsKRaCyOvpAwJ6Up8pXOZHOIAFm+UCzJEQuvMhWrIFBUa/WGkodmq40Ad7q9/kDFwnA05lpYYCbT2ZykFvxQDhhmuVpvcvxaHra7vfp72KflcMSYEOB0vlyx+By+3R9PMSfe+P0enM1454kAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDYtMjRUMDM6MjE6MjEtMDc6MDDse6MAAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTA2LTI0VDAzOjIxOjIxLTA3OjAwnSYbvAAAAABJRU5ErkJggg=='; + + var linkifySoundcloud = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABsklEQVQ4y5WTy2pUQRCGv2rbzDjJeAlIBmOyipGIIJqFEBDElwh4yULGeRFXPoEIBl/AvQ/gC2RnxCAoxijiwks852S6+3dxzslcHJCpTXVX11/Xv0097gLPgVNMJxnQNfX4zsqleWbnpoMf/oa9d988MM9MC/rp+E0a+A0dsVobMNMCOO8B6McRoABJI+A6gJmN3D2A8jgEBCEkSEMBrcrsDAzDWWn3AjgKFaDMmgRqniGFgsaDp1jrLOngDf1XT1D+A1dFc4MKAkkiCVKjjVu7g9+4Rzx4i1u6hjXbuMWr0O5QPNvCu7IaCZwEKQukLGDrm5x8uI0tr6MkiGlkiv7yLfzN+6S5i6QsIMABkEfcxhbWWYMkVAOjxvYAjc3HNHrbKI9VBQBFwF25XQKSBjqIf1YBuAurEMrczgDygD6/x2LCpFLXLUyQ+PoldphhBhYfIX09XU1+Flaukz7uYqs3SHs7cG4BmTsmkBUF9mmXEwa28BNLPaQPLepuNcbGSWQquQC2/Kdcox1FUGkcB0ykck1nA2+wTzMs8stGnP4rbWGw74EuS/GFQWfK7/wF6P4F7fzIAYkdmdEAAAAASUVORK5CYII='; + + var linkifyStreamable = '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'; + + var linkifyTwitchtv = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAYUExURf///2RBpWRBpWRBpWRBpWRBpWRBpf///+zQyUYAAAAGdFJOUwFdZX0lTzs4r5oAAAABYktHRAcWYYjrAAAAB3RJTUUH4AINEi42iSXRNAAAAD1JREFUCNdjYEiDAAZGGIMtjQEEUBlMCWoEGci6mGEMsxQgIy0BiB3AjLS0FAYQIw0kwABipoI1AhkBQBIAFCIXxiHgq80AAAAASUVORK5CYII='; + + var linkifyTwitter = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAEsUExURf///1Cf21Gg3FGi31Gh3VKj4FGh3lKj4VKk4lKl41Ol5FOn51Sp6VSo6FOn5lCf21Gg3FGh3VGi31Gi31Gh3lGg3FGg3FGg3FGg3FGh3lGg3FGi31Kk4lKj4FGh3lGi31Kk4lGh3lGg3FGh3lOm5FOm5VGi31Kj4VSo6FGi31Gh3VGg3FKj4FOn51Gi31So6FWr7VOl5FGi31On51Sq6lKk4lOo51Sp6VOm5FSq61Ws7VOn51Oo51Sq61Ol5FOm5FSq61Wr7VOo51On51Sr7FWs7VSp6lGg3FGh3VOm5FWr7VSp6lKj4VOm5FSo6FSr7FWs7VWs7VWr7VSq6lOo51Om5FOo51So6FOm5VOl5FSq61Ws7VSr7FSp6lSp6VWs7lWr7VKk4lSq6v///6E3MNsAAABVdFJOUwAAAAAAAAAAAAAAAAAAAB0Ii+3xnBVTJhfsMKb+qTEp9GwBF/7lLAbo0m4pLkUTdvk2Ev3+EZnOBo/3Z8ffCRzH/D0OqPxiLnvx3UI8m9n1++GwXQZNS29BAAAAAWJLR0QAiAUdSAAAAAd0SU1FB+ACDRIwBwy67tEAAADKSURBVBjTY2BAB4xogIGRH8IQEBQSFhEVE2eQkJQC8ZmkQ8PCI2Rk5RjkIxUUlRgZlVWioqNjYlXVGNQ14iI1tbR14qLj4+MTdJkZ9PQNosJCE0OjgPz4KEMWBiPjhPiEmKQokIJ4E1MmBmazhHg4MGdlYmCzsLSC8ROsmRkZmFht4Eps7ViADmOzd4DyHZ2YmYACTOzOLmATXd04mIBOd/eQ9owFCXh5c7KB/MLi4+vnHxAYFBzCwcYEEmBi5uLm4eHl42RmAnsSAMZBLgZiFUQ5AAAAAElFTkSuQmCC'; + + var linkifyVideo = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAxgDGAP8nNqN7AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gMZBjQQLEEqGwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAA5SURBVDjLY2AYaMDIwMDwn1JD/lPCZhpwL+B1wf///ykzgBhDiAoDfIYQZQAjIyP5BuDTPJqQqAQAvW0ZAMk8+EEAAAAASUVORK5CYII='; + + var linkifyVidlii = '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='; + + var linkifyCimeo = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAYFBMVEUAAAAIdZUKh6sLlLkLmr4LmsAMp88NrdYVW3MZj7Acstkrt9s1e5E7vN5EfI9JvdtKwuBijp5kpbl30eiDt8aG1uqRr7qTyNehxM+k4PCy3enB3OTg6Ovv9PXw+fz////L9U5WAAAAAXRSTlMAQObYZgAAAIFJREFUeNplz90OwiAMBWAQpAoyxclkP3je/y0H2AQXz0WT8100rRD6kNI9/cRroemQL3hXhoujZYj4OHoAmBvYGcBISwbWBvfXCrytnIDUQMkbsBpagMA7zhtQdyTFQAmIG7IkYniiZuh3XGsPqoOZkMOJOpAcLqUzNFGGu/57fwc1hgtp0mVSyQAAAABJRU5ErkJggg=='; + + var linkifyVine = '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'; + + var linkifyVocaroo = '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=='; + + var linkifyYoutube = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAYAAABr5z2BAAABIklEQVQoz53LvUrDUBjG8bOoOammSf1IoBSvoCB4JeIqOHgBLt6AIMRBBQelWurQ2kERnMRBsBUcIp5FJSBI5oQsJVkkUHh8W0o5nhaFHvjBgef/Mq+Q46RJBMkI/vE+aOus956tnEswIZe1LV0QyJ5sE2GzgZfVMtRNIdiDpccEssdlB1mW4bvTwdvWJtRdErM7U+8S/FJykCRJX5qm+KpVce8UMNLRLbulz4iSjTAMh6Iowsd5BeNadp3nUF0VlxAEwZBotXC0Usa4ll3meZdA1iguwvf9vpvDA2wvmKgYGtSud8suDB4TyGr2PF49D/vra9jRZ1BVdknMzgwuCGSnZEObwu6sBnVTCHZiaC7BhFx2PKdxUidiAH/4lLo9Mv0DELVs9qsOHXwAAAAASUVORK5CYII='; + + var photon = `/* General */ +:root.photon .dialog { + background-color: #DDD; + border-color: #CCC; +} +:root.photon .field:focus, +:root.photon .field.focus { + border-color: #EA8; +} + +/* 4chan style fixes */ +:root.photon #arc-list tr:nth-of-type(odd) span.quote { + color: #C0E17A; +} +:root.photon.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(221, 0, 0, .8) !important; +} +:root.photon.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(221, 0, 0, .8) !important; +} + +/* Header */ +:root.photon #header-bar.dialog { + background-color: rgba(221,221,221,0.98); +} +:root.photon:not(.fixed) #header-bar, :root.photon #notifications { + font-size: 9pt; +} +:root.photon #header-bar, :root.photon #notifications { + color: #333; +} +:root.photon #header-bar a, :root.photon #notifications a { + color: #FF6600; +} + +/* Settings */ +:root.photon #fourchanx-settings fieldset, :root.photon .section-main div::before { + border-color: #CCC; +} +:root.photon .suboption-list > div:last-of-type { + background-color: #DDD; +} + +/* Catalog */ +:root.photon.catalog-hover-expand .catalog-container:hover > .post { + background-color: #DDD; +} +:root.photon.werkTyme .catalog-thread:not(:hover), +:root.photon.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.photon.catalog-hover-expand .catalog-container:hover > .post, +:root.photon.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #CCC; +} + +/* Quote */ +:root.photon .backlink.deadlink { + color: #F60 !important; +} +:root.photon .inline { + border-color: #CCC; + background-color: rgba(255, 255, 255, .14); +} + +/* Fappe and Werk Tyme */ +:root.photon .indicator { + color: #DDD; +} + +/* QR */ +.photon #dump-list::-webkit-scrollbar-thumb { + background-color: #DDD; + border-color: #CCC; +} +:root.photon .qr-preview { + background-color: rgba(0, 0, 0, .15); +} +:root.photon .qr-link { + border-color: rgb(206, 206, 206) rgb(206, 206, 206) rgb(191, 191, 191); + background: linear-gradient(#ECECEC, #DDD) repeat scroll 0% 0% transparent; +} +:root.photon .qr-link:hover { + background: #DDDDDD; +} + +/* Menu */ +:root.photon #menu { + color: #333; +} +:root.photon .entry { + font-size: 10pt; +} +:root.photon .focused.entry { + background: rgba(255, 255, 255, .33); +} + +/* Unread */ +:root.photon .unread-mark-read { + background-color: rgba(221,221,221,0.5); +} + +/* Thread Watcher */ +:root.photon .replies-quoting-you > a, :root.photon #watcher-link.replies-quoting-you, :root.photon .last-page > a > .watcher-page { + color: #00F !important; +} + +/* Watcher Favicon */ +:root.photon .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + var report = `#g-recaptcha, +:root:not(.js-enabled) #captchaContainerAlt { + height: auto; +} +#captchaContainerAlt td:nth-child(2) { + display: table-cell !important; +} + +/* Archive reports */ +#archive-report { + padding: 3px; +} +#archive-report-enabled { + vertical-align: middle; +} +#archive-report > label { + display: block; +} +#archive-report-reason { + display: block; + width: 98%; +} +.archive-report-success { + color: green; +} +.archive-report-error { + color: red; +}`; + + var spooky = `/* General */ +:root.spooky .dialog { + background-color: #171526; + border-color: #707070; +} +:root.spooky .field:focus, +:root.spooky .field.focus { + border-color: #98E; +} + +/* 4chan style fixes */ +:root.spooky #arc-list span.quote { + color: #634C2C; +} +:root.spooky.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(145, 182, 214, .8) !important; +} +:root.spooky.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(145, 182, 214, .8) !important; +} + +/* Header */ +:root.spooky #header-bar.dialog { + background-color: rgba(23,21,38,0.98); +} +:root.spooky:not(.fixed) #header-bar, :root.spooky #notifications { + font-size: 9pt; +} +:root.spooky #header-bar, :root.spooky #notifications { + color: #C49756; +} +:root.spooky #board-list a, :root.spooky #shortcuts a { + color: #FE9600; +} +:root.spooky.shortcut-icons .native-settings { + background-image: url('//s.4cdn.org/image/favicon-ws.ico'); +} + +/* Settings */ +:root.spooky #fourchanx-settings fieldset, :root.spooky .section-main div::before { + border-color: #707070; +} +:root.spooky .suboption-list > div:last-of-type { + background-color: #171526; +} + +/* Catalog */ +:root.spooky.catalog-hover-expand .catalog-container:hover > .post { + background-color: #171526; +} +:root.spooky.werkTyme .catalog-thread:not(:hover), +:root.spooky.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.spooky.catalog-hover-expand .catalog-container:hover > .post, +:root.spooky.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #707070; +} + +/* Quote */ +:root.spooky .backlink.deadlink { + color: #FE9600 !important; +} +:root.spooky .inline { + border-color: #707070; + background-color: rgba(255, 255, 255, .14); +} + +/* Fappe and Werk Tyme */ +:root.spooky .indicator { + color: #171526; +} + +/* Highlighting */ +:root.spooky .qphl { + outline: 2px solid rgba(145, 182, 214, .8); +} +:root.spooky.highlight-you .quotesYou$site$highlightable$op, +:root.spooky.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(145, 182, 214, .8); +} +:root.spooky.highlight-own .yourPost$site$highlightable$op, +:root.spooky.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(145, 182, 214, .8); +} +:root.spooky .filter-highlight$site$highlightable$op, +:root.spooky .filter-highlight$site$highlightable$reply { + box-shadow: inset 5px 0 rgba(145, 182, 214, .5); +} +:root.spooky.highlight-own .yourPost > $site$sideArrows, +:root.spooky.highlight-you .quotesYou > $site$sideArrows, +:root.spooky .filter-highlight > $site$sideArrows { + color: rgb(155, 185, 210); +} + +/* QR */ +.spooky #dump-list::-webkit-scrollbar-thumb { + background-color: #171526; + border-color: #707070; +} +:root.spooky .qr-preview { + background-color: rgba(0, 0, 0, .15); +} +:root.spooky #qr .field { + background-color: rgb(26, 27, 29); + color: rgb(197,200,198); + border-color: rgb(40, 41, 42); +} +:root.spooky #qr .field:focus, +:root.spooky #qr .field.focus { + border-color: rgb(254, 150, 0) !important; + background-color: rgb(30,32,36); +} +:root.spooky .persona button { + background: linear-gradient(to bottom, #2E3035, #222427) no-repeat; + color: rgb(197,200,198); + border-color: rgb(40, 41, 42); + outline: none; +} +:root.spooky .persona button::-moz-focus-inner { + border: none; +} +:root.spooky .persona button:focus { + border-color: rgb(254, 150, 0); +} +:root.spooky #qr.sjis-preview #sjis-toggle, +:root.spooky #qr.tex-preview #tex-preview-button { + background: rgb(26, 27, 29); +} +:root.spooky #qr select, +:root.spooky #file-n-submit > input, +:root.spooky #qr-draw-button { + border-color: rgb(40, 41, 42); +} +:root.spooky #qr-filename { + color: rgb(197,200,198); +} + +:root.spooky .qr-link { + border-color: rgb(8, 6, 23) rgb(8, 6, 23) rgb(0, 0, 8); + background: linear-gradient(#262435, #171526) repeat scroll 0% 0% transparent; +} +:root.spooky .qr-link:hover { + background: #1A1829; +} + + +/* Menu */ +:root.spooky #menu { + color: #FE9600; +} +:root.spooky .entry { + font-size: 10pt; +} +:root.spooky .focused.entry { + background: rgba(255, 255, 255, .33); +} + +/* Unread */ +:root.spooky .unread-line { + border-color: rgb(197, 200, 198); + visibility: visible; + opacity: 1; +} +:root.spooky .unread-mark-read { + background-color: rgba(23,21,38,0.5); +} + +/* Thread Watcher */ +:root.spooky .replies-quoting-you > a, :root.spooky #watcher-link.replies-quoting-you, :root.spooky .last-page > a > .watcher-page { + color: #F00 !important; +} + +/* Watcher Favicon */ +:root.spooky .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + var style = `/* General */ +.dialog { + border: 1px solid; + display: block; + background-color: inherit; +} +.dialog:not(#qr):not(#thread-watcher):not(#header-bar) { + box-shadow: 0 1px 2px rgba(0, 0, 0, .15); +} +#qr, +#thread-watcher { + box-shadow: -1px 2px 2px rgba(0, 0, 0, 0.25); +} +.captcha-img, +.field { + background-color: #FFF; + border: 1px solid #CCC; + -moz-box-sizing: border-box; + box-sizing: border-box; + color: #333; + font: 13px sans-serif; + outline: none; + transition: color .25s, border-color .25s; +} +.field::-moz-placeholder { + color: #AAA; + font-size: 13px; + opacity: 1; +} +.captch-img:hover, +.field:hover { + border-color: #999; +} +.field:hover, .field:focus, .field.focus { + color: #000; +} +.field[disabled] { + background-color: #F2F2F2; + color: #888; +} +.field::-webkit-search-decoration { + display: none; +} +.move { + cursor: move; + overflow: hidden; +} +label { + cursor: pointer; +} +a[href="javascript:;"] { + text-decoration: none; +} +.warning { + color: red; +} +:root.sw-yotsuba #boardNavDesktop, :root.sw-yotsuba #boardNavMobile { + display: none !important; +} +:root.hide-bottom-board-list $site$boardListBottom { + display: none; +} +body.hasDropDownNav{ + margin-top: 5px; +} +:root:not(.keyboard-focus) a { + outline: none; +} +.painted { + border-radius: 3px; + padding: 0px 2px; +} +[hidden] { + display: none !important; +} + +/* 4chan style fixes */ +/* overrides 4chan CSS on div.opContainer, div.op */ +:root.sw-yotsuba .opContainer, :root.sw-yotsuba .op { + display: block; + overflow: visible; +} +:root.sw-yotsuba .reply > .file > .fileText { + margin: 0 20px; +} +:root.sw-yotsuba #arc-list span.quote { + color: #789922; +} +:root.sw-yotsuba .fileText a { + unicode-bidi: -moz-isolate; + unicode-bidi: -webkit-isolate; +} +:root.sw-yotsuba #g-recaptcha { + min-height: 78px; + height: auto; +} +:root.sw-yotsuba:not(.js-enabled) #postForm { + display: table; +} +:root.sw-yotsuba #captchaContainerAlt td:nth-child(2) { + display: table-cell !important; +} +:root.sw-yotsuba canvas#tegaki-canvas { + background: none; +} +/* Disable obnoxious captcha fade-in. */ +:root.sw-yotsuba > body > div:last-of-type { + transition: none !important; +} +/* Fix captcha scrolling to top of page. */ +:root.sw-yotsuba > body > div[style*=" top: -10000px;"] { + visibility: hidden !important; +} +/* Make long filenames wrap properly: https://github.com/ccd0/4chan-x/issues/1082 */ +:root.sw-yotsuba .post > .file { + /* 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 */ + word-break: break-word; +} +:root.sw-yotsuba:not(.ua-webkit):not(.ua-blink) .fileText { + word-wrap: break-word; + max-width: calc(100vw - 90px); +} +:root.sw-yotsuba > body.is_catalog .thread > a > img { + display: inline-block; +} +/* Links to NSFW boards */ +:root.sw-yotsuba .nwsb { + display: inline; +} +:root.sw-yotsuba .fileText { + max-width: auto; + white-space: normal; +} + +/* Ads */ +:root.sw-yotsuba .ad-cnt > *, :root.sw-yotsuba .adg-rects > *, :root.sw-yotsuba .bsa-cnt { + height: auto !important; +} +:root.sw-yotsuba:not(.ads-loaded) hr.abovePostForm, +:root.sw-yotsuba:not(.ads-loaded) .adg-rects > hr, +:root.sw-yotsuba #adg-ol + hr, +:root.sw-yotsuba .danbo-slot:empty { + display: none; +} +:root.sw-yotsuba .adg-rects { + margin: 0; + font-size: 0; +} +:root.sw-yotsuba div.center[style] { + display: none !important; +} + +/* Tinyboard / vichan conflicts */ +#menu > .hide-thread-link { + width: auto; + height: auto; + overflow: visible; + background-image: none; +} +#menu label.entry { + display: block; +} +#fourchanx-settings label { + display: inline; +} +.intro a[href="javascript:;"], +#menu a { + margin: 0; +} +.gal-buttons.gal-buttons a { + font-size: inherit; +} +:root.sw-tinyboard.fixed.top-header:not(.autohide) .boardlist, +:root.sw-tinyboard.fixed.top-header:not(.autohide) .bar.top { + position: static; +} +:root.sw-tinyboard.fixed.top-header:not(.autohide) div.pages.top { + top: auto; + bottom: 0; +} +:root.sw-tinyboard.fixed.top-header.autohide .boardlist, +:root.sw-tinyboard.fixed.top-header.autohide .bar.top { + z-index: 3; +} + +/* Tinyboard site style conflicts */ +:root[data-host="fufufu.moe"].fixed.top-header:not(.autohide) div.pages.top { + top: 26px; + bottom: auto; +} +:root[data-host="merorin.com"].fixed.top-header:not(.autohide) span.settings { + top: 26px; +} +:root[data-host="fufufu.moe"]:not(.fixed) #header-bar { + margin-top: 38px; +} +:root[data-host="lainchan.org"]:not(.fixed) #header-bar { + margin-top: 17px; +} +:root[data-host="smuglo.li"]:not(.fixed) #header-bar { + margin-top: 8px; +} + +/* Anti-autoplay */ +audio.controls-added { + display: block; + margin: auto; + white-space: normal; +} +:root.anti-autoplay div.embed { + position: static; + width: auto; + height: auto; + text-align: center; +} +:root.anti-autoplay .autoplay-removed { + visibility: visible !important; + min-width: 640px; + min-height: 360px; +} + +/* fixed, z-index */ +#overlay, +#qp, #ihover, +#navlinks, .fixed #header-bar, +:root.float #updater, +:root.float #thread-stats, +#qr { + position: fixed; +} +#overlay { + z-index: 999; +} +#qp, #ihover { + z-index: 60; +} +#menu, .gal-buttons { + z-index: 50; +} +#updater, #thread-stats { + z-index: 40; +} +:root.fixed #header-bar, #notifications { + z-index: 35; +} +#a-gallery { + z-index: 30; +} +#navlinks { + z-index: 25; +} +#qr { + z-index: 20; +} +#embedding { + z-index: 11; +} +:root.fixed-watcher #thread-watcher { + z-index: 10; +} +:root.fixed:not(.gallery-open) #header-bar:not(:hover) { + z-index: 8; +} +#thread-watcher { + z-index: 5; +} + +/* Header */ +.fixed.top-header body { + padding-top: 2em; +} +.fixed.bottom-header body { + padding-bottom: 2em; +} +.fixed #header-bar { + right: 0; + left: 0; + padding: 3px 4px 4px; + font-size: 12px; +} +.fixed.top-header #header-bar { + top: 0; +} +.fixed.bottom-header #header-bar { + bottom: 0; +} +#header-bar { + border-width: 0; + transition: all .1s .05s ease-in-out; +} +:root.fixed #header-bar { + box-shadow: -5px 1px 10px rgba(0, 0, 0, 0.20); +} +:root.centered-links #shortcuts { + width: 300px; + text-align: right; +} +:root.centered-links #header-bar { + text-align: center; +} +#custom-board-list { + font-size: 13px; + vertical-align: middle; +} +#full-board-list { + vertical-align: middle; +} +:root.centered-links #custom-board-list { + position: relative; + left: 150px; +} +.fixed.top-header #header-bar { + border-bottom-width: 1px; +} +.fixed.bottom-header #header-bar { + box-shadow: 0 -1px 2px rgba(0, 0, 0, .15); + border-top-width: 1px; +} +.fixed.bottom-header #header-bar .menu-button i { + border-top: none; + border-bottom: 6px solid; +} +.fixed #header-bar.autohide:not(:hover) { + box-shadow: none; + transition: all .8s .6s cubic-bezier(.55, .055, .675, .19); +} +.fixed.top-header #header-bar.autohide:not(:hover) { + margin-bottom: -1em; + -webkit-transform: translateY(-100%); + transform: translateY(-100%); +} +.fixed.bottom-header #header-bar.autohide:not(:hover) { + -webkit-transform: translateY(100%); + transform: translateY(100%); +} +#scroll-marker { + left: 0; + right: 0; + height: 10px; + position: absolute; +} +#header-bar:not(.autohide) #scroll-marker { + pointer-events: none; +} +#header-bar #scroll-marker { + display: none; +} +.fixed #header-bar #scroll-marker { + display: block; +} +.fixed.top-header #header-bar #scroll-marker { + top: 100%; +} +.fixed.bottom-header #header-bar #scroll-marker { + bottom: 100%; +} +#board-list a, #shortcuts a:not(.entry) { + text-decoration: none; + padding: 1px; +} +#shortcuts:empty { + display: none; +} +.brackets-wrap::before { + content: "\\00a0["; +} +.brackets-wrap::after { + content: "]\\00a0"; +} +.dead-thread, +.disabled:not(.replies-quoting-you) { + opacity: .45; +} +#shortcuts { + float: right; +} +:root.autohiding-scrollbar #shortcuts { + margin-right: 12px; +} +.shortcut { + margin-left: 3px; + vertical-align: middle; +} +:root.shortcut-icons .native-settings { + font-size: 0; + color: transparent; + display: inline-block; + vertical-align: top; + height: 12px; + width: 14px; + background: url('//s.4cdn.org/image/favicon.ico') 0px -1px no-repeat; +} +#navbotright, +#navtopright { + display: none; +} +#toggleMsgBtn { + display: none !important; +} +.current, +:root.sw-yotsuba div#boardNavDesktopFoot a.current { + font-weight: bold; +} +@media (min-width: 1300px) { + :root.sw-yotsuba.fixed:not(.centered-links) #header-bar { + white-space: nowrap; + display: -webkit-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + } + :root.sw-yotsuba.fixed:not(.centered-links) #board-list { + -webkit-flex: auto; + flex: auto; + } + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list { + display: -webkit-flex; + display: flex; + } + :root.sw-yotsuba.fixed:not(.centered-links) .hide-board-list-container { + -webkit-flex: none; + flex: none; + margin-right: 5px; + } + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList { + -webkit-flex: auto; + flex: auto; + display: -webkit-flex; + display: flex; + width: 0px; /* XXX Fixes Edge not shrinking the board list below default size when needed */ + } + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > a, + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > span:not(.space):not(.spacer) { + -webkit-flex: none; + flex: none; + padding: .17em; + margin: -.17em -.32em; + } + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > span { + pointer-events: none; + } + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > span.space { + -webkit-flex: 0 .63 .63em; + flex: 0 .63 .63em; + } + :root.sw-yotsuba.fixed:not(.centered-links) #full-board-list > .boardList > span.spacer { + -webkit-flex: 0 .38 .38em; + flex: 0 .38 .38em; + } + :root.sw-yotsuba.fixed:not(.centered-links) #shortcuts { + float: initial; + -webkit-flex: none; + flex: none; + display: -webkit-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + } +} +/* 4chan X link brackets */ +.brackets-wrap::before { + content: "["; +} +.brackets-wrap::after { + content: "]"; +} +/* Notifications */ +#notifications { + position: fixed; + top: 0; + height: 0; + text-align: center; + right: 0; + left: 0; + visibility: visible; +} +#notifications:empty { + display: none; +} +:root.fixed.top-header:not(.gallery-open) #header-bar #notifications, +:root.fixed.top-header #header-bar.autohide #notifications { + position: absolute; + top: 100%; +} +.notification { + color: #FFF; + font-weight: 700; + text-shadow: 0 1px 2px rgba(0, 0, 0, .5); + box-shadow: 0 1px 2px rgba(0, 0, 0, .15); + border-radius: 2px; + margin: 1px auto; + width: 550px; + max-width: 100%; + position: relative; + transition: all .25s ease-in-out; +} +.notification.error { + background-color: hsla(0, 100%, 38%, .9); +} +.notification.warning { + background-color: hsla(36, 100%, 38%, .9); +} +.notification.info { + background-color: hsla(200, 100%, 38%, .9); +} +.notification.success { + background-color: hsla(104, 100%, 38%, .9); +} +.notification a { + color: white; +} +.notification > .close { + padding: 7px; + top: 0px; + right: 5px; + position: absolute; +} +.notification > .fa-times::before { + font-size: 11px !important; +} +.message { + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 6px 20px; + max-height: 200px; + width: 100%; + overflow: auto; + white-space: pre-line; +} +.message a { + text-decoration: underline; +} +:root.tainted .report-error { + display: none; +} + +/* Settings */ +:root.fourchan-x body { + -moz-box-sizing: border-box; + box-sizing: border-box; +} +#overlay { + background-color: rgba(0, 0, 0, .5); + display: -webkit-flex; + display: flex; + top: 0; + left: 0; + height: 100%; + width: 100%; +} +#fourchanx-settings { + -moz-box-sizing: border-box; + box-sizing: border-box; + box-shadow: 0 0 15px rgba(0, 0, 0, .15); + height: 600px; + max-height: 100%; + width: 900px; + max-width: 100%; + margin: auto; + padding: 5px; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: column; + flex-direction: column; +} +#fourchanx-settings > nav { + padding: 2px 2px 8px; + display: -webkit-flex; + display: flex; +} +#fourchanx-settings > nav a { + text-decoration: underline; +} +#fourchanx-settings > nav a.close { + text-decoration: none; + padding: 0 2px; + margin: 0; +} +.section-container { + -webkit-flex: 1; + flex: 1; + position: relative; + overflow: auto; + padding-right: 5px; + overscroll-behavior: contain; +} +.sections-list { + -webkit-flex: 1; + flex: 1; +} +.export, .import, .reset { + cursor: pointer; + text-decoration: none !important; +} +.tab-selected { + font-weight: 700; +} +.section-sauce ul, +.section-advanced ul { + list-style: none; + margin: 0; +} +.section-sauce ul { + padding: 8px; +} +.section-advanced ul { + padding: 0px; +} +.section-sauce li, +.section-advanced li { + padding-left: 4px; +} +.section-main ul { + margin: 0; + padding: 0 0 0 16px; +} +.section-main li { + white-space: pre-line; + list-style: disc; +} +.section-main li:not(:first-of-type) { + margin-top: 4px; +} +.section-main label { + text-decoration: underline; +} +div[data-checked="false"] > .suboption-list { + display: none; +} +.suboption-list { + position: relative; +} +.suboption-list::before { + content: ""; + display: inline-block; + position: absolute; + left: .7em; + width: 0; + height: 100%; + border-left: 1px solid; +} +.suboption-list > div { + position: relative; + padding-left: 1.4em; +} +.suboption-list > div::before { + content: ""; + display: inline-block; + position: absolute; + left: .7em; + width: .7em; + height: .6em; + border-left: 1px solid; + border-bottom: 1px solid; +} +#fourchanx-settings .section-main p { + margin: .5em 0 0; +} +.section-filter ul { + padding: 0; +} +.section-filter li { + margin: 10px 40px; + list-style: disc; +} +.section-filter textarea { + height: 500px; +} +.section-main a, .section-filter a, .section-advanced a { + text-decoration: underline; +} +#sauce-doc-expand:not(:checked) ~ #sauce-doc { + max-height: 130px; + overflow: auto; +} +#sauce-doc > label { + float: right; + margin: 0 5px; +} +/* XXX for OneeChan */ +#sauce-doc-expand + .riceCheck { + display: none; +} +.section-sauce textarea { + height: 430px; +} +.section-advanced .field[name="boardnav"] { + width: 100%; +} +.section-advanced textarea { + height: 150px; +} +.section-advanced textarea[name="archiveLists"], +.section-advanced textarea[name="externalCatalogURLs"], +.section-advanced textarea[name="knownBanners"] { + height: 75px; +} +.section-advanced .archive-cell { + min-width: 160px; + text-align: center; +} +.section-advanced #archive-board-select { + position: absolute; +} +.section-advanced .note { + font-size: 0.8em; + font-style: italic; + margin-left: 10px; +} +.section-advanced .note code { + font-style: normal; + font-size: 11px; +} +.favicon-preview > img { + vertical-align: middle; +} +.favicon-preview > img:nth-of-type(3n+1) { + margin-left: 4px; +} +.section-keybinds .field { + font-family: monospace; +} +#fourchanx-settings fieldset { + border: 1px solid; + border-radius: 3px; + padding: 0.35em 0.625em 0.75em; + margin: 0px 2px; +} +#fourchanx-settings legend { + font-weight: 700; + color: inherit; +} +#fourchanx-settings textarea { + font-family: monospace; + width: 100%; + resize: vertical; +} +#fourchanx-settings code { + color: #000; + background-color: #FFF; + padding: 0 2px; +} +#fourchanx-settings th { + text-align: center; + font-weight: bold; +} +#fourchanx-settings p { + margin: 1em 0px; +} +#fourchanx-settings table { + margin: auto; +} + +/* Index */ +:root.index-loading .navLinks:not(.json-index), +:root.index-loading .board:not(.json-index), +:root.index-loading .pagelist:not(.json-index), +:root.infinite-mode .pagelist, +:root.all-pages-mode .pagelist, +:root.catalog-mode .pagelist, +:root:not(.catalog-mode) .indexlink, +:root.catalog-mode .cataloglink, +:root:not(.catalog-mode) #hidden-label, +:root:not(.catalog-mode) #index-size { + display: none; +} +#index-search { + padding-right: 1.5em; + width: 100px; + transition: color .25s, border-color .25s, width .25s; +} +#index-search:focus, +#index-search[data-searching] { + width: 200px; +} +#index-search-clear { + color: gray; + display: inline-block; + position: relative; + left: -1em; + width: 0; +} +/* \`\`::-webkit-*'' selectors break selector lists on Firefox. */ +#index-search::-webkit-search-cancel-button { + display: none; +} +#index-search:not([data-searching]) + #index-search-clear { + display: none; +} +#index-options { + float: right; +} +#lastlong-options { + display: inline-block; + vertical-align: middle; + height: 28px; + margin: -14px 0; +} +#lastlong-options > input { + padding: 0; + border: 0 !important; + text-align: center; + background: transparent; + display: block; + font-size: 12px; + height: 12px; + width: 30px; + margin: 1px 0; +} +.summary { + text-decoration: none; +} + +/* Catalog */ +:root.catalog-mode .board { + text-align: center; +} +.catalog-thread { + display: inline-block; + -moz-box-sizing: border-box; + box-sizing: border-box; + border: 1px solid transparent; + word-wrap: break-word; + vertical-align: top; + position: relative; +} +/* overrides 4chan CSS on div.thread */ +.catalog-thread.catalog-thread { + margin: 2px; +} +.catalog-small > .catalog-thread { + width: 165px; + height: 320px; +} +.catalog-large > .catalog-thread { + width: 270px; + height: 410px; +} +:root.catalog-hover-expand .catalog-thread:hover { + z-index: 1; +} +.catalog-container { + position: absolute; + top: -4px; + left: 0; + right: 0; + bottom: 0; +} +.catalog-container:not(:hover), +:root:not(.catalog-hover-expand) .catalog-container { + overflow: hidden; +} +.catalog-post { + position: absolute; + top: 4px; + left: 0; + right: 0; + border: 1px solid transparent; + padding-top: 20px; +} +/* overrides inline CSS from Index.cb.hoverAdjust */ +:root:not(.catalog-hover-expand) .catalog-post { + left: 0 !important; + right: 0 !important; +} +/* overrides 4chan CSS on div.post */ +.catalog-post.catalog-post { + margin: -21px -1px -1px; + overflow: visible; +} +.catalog-thread.noFile > * > .catalog-post { + margin-top: -7px; + padding-top: 6px; +} +:root.catalog-hover-expand .catalog-container:hover > .catalog-post { + margin-left: -61px; + margin-right: -61px; +} +:root.catalog-hover-expand .catalog-container:hover > * > :not(.catalog-replies) { + padding-left: 2px; + padding-right: 2px; +} +.catalog-link { + display: block; + position: relative; +} +.catalog-thumb { + border-radius: 2px; + box-shadow: 0 0 5px rgba(0, 0, 0, .25); + vertical-align: top; +} +.catalog-thumb.spoiler-file { + width: 100px; + height: 100px; +} +.catalog-thumb.deleted-file { + width: 127px; + height: 13px; + padding: 20px 11px; +} +.catalog-thumb.no-file { + width: 77px; + height: 13px; + padding: 20px 36px; +} +.catalog-icons > img, +.catalog-stats > .menu-button { + width: 1em; + height: 1em; + margin: 0; + vertical-align: text-top; + padding-left: 2px; +} +.catalog-stats > .menu-button { + font-weight: normal; +} +.catalog-stats > .menu-button > i::before { + line-height: 11px; +} +.catalog-stats { + font-size: 10px; + font-weight: 700; + padding-top: 2px; +} +.catalog-stats > [title] { + cursor: help; +} +.catalog-post > .postMessage { + margin: 0; + padding-bottom: .3em; +} +.catalog-container:not(:hover) > * > .file, +.catalog-container:not(:hover) > * > .postInfo > :not(.subject), +.catalog-container:not(:hover) > * > .catalog-replies, +.catalog-container:not(:hover) .extra-linebreak, +.catalog-container:not(:hover) .abbr, +:root:not(.catalog-hover-expand) .catalog-container > * > .file, +:root:not(.catalog-hover-expand) .catalog-container > * > .postInfo > :not(.subject), +:root:not(.catalog-hover-expand) .catalog-container > * > .catalog-replies, +:root:not(.catalog-hover-expand) .catalog-container .extra-linebreak, +:root:not(.catalog-hover-expand) .catalog-container .abbr, +.catalog-thread > .catalog-container > :not(.catalog-post), +.catalog-post > .file > :not(.fileText), +.catalog-post > * > .fileText > :not(:first-child), +.catalog-post > .postInfo > :not(.subject):not(.nameBlock):not(.dateTime), +.catalog-post > .postInfo > .nameBlock > .contact-links, +.catalog-post > * > * > .posteruid, +.catalog-post > * > * > .postJumper, +:root.bottom-backlinks .catalog-post > .container, +.post:not(.catalog-post) > .catalog-link, +.post:not(.catalog-post) > .catalog-stats, +.post:not(.catalog-post) > .catalog-replies { + display: none; +} +.catalog-post > .file { + position: absolute; + left: 0; + right: 0; + top: 0; + min-height: 20px; + background-color: inherit; +} +.catalog-post > * > .fileText { + position: relative; + padding: 2px; + background-color: inherit; +} +.catalog-small .catalog-post > * .fileText { + font-size: 10px; +} +.catalog-post > * > .fileText:not(:hover) { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.catalog-post > * > .fileText:hover { + z-index: 1; +} +/* overrides 4chan CSS on div.post div.postInfo */ +.catalog-post > .postInfo.postInfo { + width: auto; +} +.catalog-post > * > .subject { + display: block; +} +.catalog-post > * > .dateTime { + display: inline-block; + font-style: italic; +} +:root.catalog-hover-expand .catalog-container:hover > * > * > .nameBlock, +:root.catalog-hover-expand .catalog-container:hover > * > * > .dateTime, +:root.catalog-hover-expand .catalog-container:hover > * > .postMessage:not(:empty) { + padding-top: .3em; +} +.catalog-post .extra-linebreak { + content: ''; /* makes this work in Blink/WebKit */ + display: block; + margin-top: .3em; +} +.catalog-reply { + text-align: left; + white-space: nowrap; + border-top: 1px solid transparent; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: row; + flex-direction: row; + -webkit-align-items: stretch; + align-items: stretch; +} +.catalog-reply > * { + padding: 3px; + overflow: hidden; + -webkit-flex: none; + flex: none; +} +.catalog-reply > span { + font-style: italic; + font-weight: bold; +} +.catalog-reply-excerpt { + -webkit-flex: 1 1 auto; + flex: 1 1 auto; +} +.catalog-post .prettyprinted { + max-width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.catalog-post .MathJax_Display { + text-align: center !important; +} +.catalog-container:not(:hover) .exif, +:root:not(.catalog-hover-expand) .catalog-container .exif { + display: none !important; +} +.catalog-post > * > .exif { + border-collapse: collapse; +} +:root.catalog-hover-expand .catalog-container:hover .exif[style*="display: block;"] { + display: inline-block !important; +} +.catalog-post > * > .exif, +.catalog-post > * > .exif > tbody { + background-color: inherit; +} +.catalog-post > * > .exif, +.catalog-post > * > .exif td { + min-width: 0; +} +.catalog-post > * > .exif td { + padding-top: 1px; +} +:root.hats-enabled .catalog-thread::after { + content: ''; + pointer-events: none; + position: absolute; + background-size: contain; +} +:root.hats-enabled .catalog-small > .catalog-thread::after { + left: -8px; + top: -59px; + width: 96px; + height: 96px; +} +:root.hats-enabled:not(.werkTyme) .catalog-small > .catalog-thread:not(.noFile)::after { + left: calc(67px - .3px * var(--tn-w)); +} +:root.hats-enabled .catalog-large > .catalog-thread::after { + left: -15px; + top: -98px; + width: 160px; + height: 160px; +} +:root.hats-enabled:not(.werkTyme) .catalog-large > .catalog-thread:not(.noFile)::after { + left: calc(110px - .5px * var(--tn-w)); +} + +/* Copy Text Link's textarea element */ +textarea.copy-text-element { + height: 0; + width: 0; + position: absolute; + top: -10000px; +} + +/* Announcement Hiding */ +:root.hide-announcement $site$psa { + display: none; +} +.hide-announcement-button { + opacity: 0.4; + float: left; +} + +/* Unread */ +.unread-line { + margin: 0; + border-color: rgb(255,0,0); +} +.unread-line + br { + display: none; +} +.unread-mark-read { + float: right; + clear: both; + width: 100%; + text-align: right; +} +:not(.unread-thread) > .unread-mark-read { + display: none; +} + +/* Thread Updater */ +#updater { + background: none; + border: none; + box-shadow: none; +} +#updater > .move { + position: absolute; + top: -5px; + bottom: -5px; + left: -5px; + right: -5px; + z-index: -1; +} +#updater > div:last-child { + text-align: center; +} +#updater input[type="number"] { + width: 4em; +} +:root.float #updater { + padding: 0px 3px; +} +:root:not(.float).shortcut-icons #updater { + display: inline-block; + min-width: 12pt; + text-align: right; +} +.new { + color: limegreen; +} +#update-status:not(.empty) + #update-timer:not(.empty):not(.loading) { + margin-left: 5px; +} +#update-timer { + cursor: pointer; +} + +/* Thread Watcher */ +#thread-watcher { + position: absolute; +} +#thread-watcher { + padding-bottom: 3px; + padding-left: 3px; + white-space: nowrap; + min-width: 146px; +} +#watched-threads { + overflow-x: hidden; + overflow-y: auto; +} +#thread-watcher .refresh { + padding: 0px 3px; +} +:root.fixed-watcher #thread-watcher { + position: fixed; +} +:root.fixed-watcher #watched-threads { + /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */ + max-height: 85vh; + max-height: calc(100vh - 75px); +} +:root:not(.fixed-watcher) #watched-threads:not(:hover) { + max-height: 210px; + overflow-y: hidden; +} +#thread-watcher > .move { + padding-top: 3px; +} +#watched-threads > div { + padding-left: 3px; + padding-right: 3px; +} +#watched-threads .watcher-link { + max-width: 250px; + display: -webkit-inline-flex; + display: inline-flex; + -webkit-flex-direction: row; + flex-direction: row; +} +#watched-threads .watcher-page, +#watched-threads .watcher-unread { + -webkit-flex: 0 0 auto; + flex: 0 0 auto; + margin-right: 2px; +} +#watched-threads .watcher-title { + overflow: hidden; + text-overflow: ellipsis; + -webkit-flex: 0 1 auto; + flex: 0 1 auto; +} +#watched-threads .watcher-title:not(:first-child) { + margin-left: 2px; +} +.replies-quoting-you > a, #watcher-link.replies-quoting-you, .last-page > a > .watcher-page { + color: #F00; +} +#thread-watcher a { + text-decoration: none; +} +#thread-watcher .move > .close { + position: absolute; + right: 0px; + top: 0px; + padding: 0px 4px; +} +.watch-thread-link { + padding-top: 18px; + width: 18px; + height: 0px; + display: inline-block; + background-repeat: no-repeat; + opacity: 0.2; + position: relative; + top: 1px; + background-image: url("data:image/svg+xml,"); +} +.watch-thread-link.watched { + opacity: 1; +} + + +/* Thread Stats */ +#thread-stats { + background: none; + border: none; + box-shadow: none; +} +:root.float #thread-stats > .move > :not(#page-count) { + pointer-events: none; +} +:root.float #thread-stats { + padding: 0px 3px; +} +#page-count { + cursor: pointer; +} + +/* Quote */ +.hashlink::before { + content: ' '; + visibility: hidden; +} +.inline + .hashlink { + display: none !important; +} +:root.resurrect-quotes .deadlink { + text-decoration: none !important; +} +.catalog-post .qmark-ct { + display: none; +} +.backlink.deadlink:not(.forwardlink), +.quotelink.deadlink:not(.forwardlink) { + text-decoration: underline !important; +} +:root:not(.catalog-mode) .inlined { + opacity: .5; +} +#qp input, .forwarded { + display: none; +} +.quotelink.forwardlink, +.backlink.forwardlink { + text-decoration: none; + border-bottom: 1px dashed; +} +.filtered { + text-decoration: underline line-through; +} +:root.hide-backlinks .backlink.filtered, +:root.hide-backlinks .backlink.filtered + .hashlink.filtered { + display: none; +} +.postNum + .container::before { + content: " "; +} +:root.bottom-backlinks .container { + display: block; + clear: both; + margin: 0 4px; +} +:root.bottom-backlinks .backlink { + font-size: 90%; +} +.inline { + border: 1px solid; + display: table; + margin: 2px 0; +} +.container ~ .inline { + margin-left: 20px; +} +:root.catalog-mode .inline { + display: none; +} +.inline .post { + border: 0 !important; + background-color: transparent !important; + display: table !important; + margin: 0 !important; + padding: 1px 2px !important; +} +#qp > .opContainer::after { + content: ''; + clear: both; + display: table; +} +#qp .post { + border: none; + margin: 0; + padding: 2px 2px 5px; +} +#qp img { + max-height: 80vh; + max-width: 50vw; +} + +/* Quote Threading */ +.threadContainer { + margin-left: 20px; + border-left: 1px solid rgba(128,128,128,.3); +} +.threadOP { + clear: both; +} + +/* File */ +.fileText-original, +.fnswitch:hover > .fntrunc, +.fnswitch:not(:hover) > .fnfull, +.expanded-image > .post > .file > .fileThumb > video[data-md5], +.expanded-image > .post > .file > .fileThumb > img[data-md5] { + display: none; +} +.full-image[data-file-i-d] { + display: none; + cursor: pointer; +} +.expanded-image > .post > .file > .fileThumb > .full-image { + display: inline; +} +.expanded-image { + clear: left; +} +.expanding { + opacity: .5; +} +:root.fit-height .full-image { + max-height: 100vh; +} +:root.fit-height.fixed .full-image { + /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */ + max-height: 93vh; + max-height: calc(100vh - 35px); +} +:root.fit-width .full-image { + max-width: 100%; +} +:root.ua-gecko.fit-width .full-image { + width: 100%; +} +.fileThumb > .warning { + clear: both; +} +#ihover { + pointer-events: none; + /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */ + max-height: 95vh; + max-height: calc(100vh - 25px); + max-width: 100vw; +} +/* WEBM Metadata */ +.webm-title > a::before { + content: "title"; + text-decoration: underline; +} +.webm-title.loading > a::after { + content: "..."; +} +.webm-title.error > a:hover::before, +.webm-title.error > a:focus::before { + content: "error"; + text-decoration: none; +} +.webm-title > span { + cursor: text; +} +.webm-title.not-found > span::before { + content: "not found"; +} +.webm-title:not(:hover):not(:focus) > span, +.webm-title:hover > span + a, +.webm-title:focus > span + a { + display: none; +} +/* Volume control */ +input[name="Default Volume"] { + width: 4em; + height: 1ex; + vertical-align: middle; + margin: 0px; +} +/* Fappe and Werk Tyme */ +:root.fappeTyme $site$replyOriginal.noFile, +:root.fappeTyme $site$replyOriginal.noFile + br { + display: none; +} +:root.werkTyme $site$thumbLink, +:root.werkTyme $site$file$thumb, +:root.werkTyme .catalog-thumb:not(.deleted-file):not(.no-file), +:root:not(.werkTyme) .werkTyme-filename { + display: none; +} +.werkTyme-filename { + font-weight: bold; + font-size: 110%; +} +:root.werkTyme .catalog-link { + box-shadow: 0 0 5px rgba(0, 0, 0, .25); + padding: 8px; + text-align: center; +} +:root.werkTyme .catalog-thumb { + box-shadow: none; + padding: 0; + vertical-align: middle; +} +.indicator { + background: rgba(255,0,0,0.8); + font-weight: bold; + display: inline-block; + min-width: 9px; + padding: 0px 2px; + margin: 0 1px; + text-align: center; + color: white; + border-radius: 2px; + cursor: pointer; +} +:root:not(.fappeTyme) #shortcut-fappe, +:root:not(.werkTyme) #shortcut-werk { + display: none; +} + +/* Index/Reply Navigation */ +#navlinks { + font-size: 16px; + top: 25px; + right: 10px; +} +:root.catalog-mode #navlinks { + display: none; +} + +/* Highlighting */ +.qphl { + outline: 2px solid rgba(216, 94, 49, .8); +} +:root.highlight-you .quotesYou$site$highlightable$op, +:root.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(221, 0, 0, .8); +} +:root.highlight-own .yourPost$site$highlightable$op, +:root.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(221, 0, 0, .8); +} +.filter-highlight$site$highlightable$op, +.filter-highlight$site$highlightable$reply { + box-shadow: inset 5px 0 rgba(221, 0, 0, .5); +} +:root.highlight-own .yourPost > $site$sideArrows, +:root.highlight-you .quotesYou > $site$sideArrows, +.filter-highlight > $site$sideArrows { + color: rgba(221, 0, 0, .8); +} +:root.highlight-own .yourPost$site$highlightable$op::after, +:root.highlight-you .quotesYou$site$highlightable$op::after, +.filter-highlight$site$highlightable$op::after { + content: ""; + display: block; + clear: both; +} +:root:not(.werkTyme) .catalog-thread.filter-highlight .catalog-thumb, +:root.werkTyme .catalog-thread.filter-highlight:not(:hover), +:root.werkTyme:not(.catalog-hover-expand) .catalog-thread.filter-highlight, +:root.werkTyme.catalog-hover-expand .catalog-thread.filter-highlight > .catalog-container:hover > .catalog-post, +:root.catalog $site$catalog$thread.filter-highlight$site$highlightable$catalog { + box-shadow: 0 0 3px 3px rgba(255, 0, 0, .5); +} +:root:not(.werkTyme) .catalog-thread.watched .catalog-thumb, +:root:root.werkTyme .catalog-thread.watched:not(:hover), +:root:root.werkTyme:not(.catalog-hover-expand) .catalog-thread.watched, +:root.werkTyme.catalog-hover-expand .catalog-thread.watched > .catalog-container:hover > .catalog-post { + border: 2px solid rgba(255, 0, 0, .75); +} + +/* Spoiler text */ +:root.reveal-spoilers $site$spoiler, +:root.reveal-spoilers $site$spoiler > a { + color: white !important; +} +:root.reveal-spoilers .removed-spoiler::before { + content: "[spoiler]"; +} +:root.reveal-spoilers .removed-spoiler::after { + content: "[/spoiler]"; +} + +/* Thread & Reply Hiding */ +.hide-thread-button, +.hide-reply-button { + float: left; + margin-right: 4px; + padding: 2px; +} +$site$infoRoot a.hide-reply-button { + margin-right: 6px; + padding: 0; +} +.replacedSideArrows { + float: left; +} +.hide-thread-button:not(:hover), +.hide-reply-button:not(:hover) { + opacity: 0.4; +} +.threadContainer .hide-reply-button { + margin-left: 2px !important; + position: relative; + left: 1px; +} +.hide-thread-button { + margin-top: -1px; + width: 11px; +} +.stub ~ :not(.threadDivider) { + display: none !important; +} +.stub input { + display: inline-block; +} +$site$thread[hidden] + hr { + display: none; +} +:root.reply-hide $site$sideArrows { + display: none; +} +:root.sw-yotsuba.thread-hide .party-hat { + left: 19px; +} + +/* Anonymize */ +:root.anonymize $site$info$name, +:root.sw-yotsuba.anonymize .post-author:not([class*=capcode]) { + font-size: 0; +} +:root.anonymize $site$info$tripcode, +:root.sw-yotsuba.anonymize .n-pu { + display: none; +} +:root.anonymize $site$info$name::before, +:root.sw-yotsuba.anonymize .post-author:not([class*=capcode])::before { + content: "Anonymous"; + font-size: 10pt; +} +:root.sw-yotsuba.anonymize .flashListing .name::before, +:root.sw-yotsuba.anonymize .post-last > .post-author:not([class*=capcode])::before { + font-size: 9pt; +} + +/* QR */ +:root.hide-original-post-form #togglePostFormLink, +#qr.autohide:not(.focus):not(:hover):not(:active) > form, +:root.thread-view #qr:not(.show-new-thread-option) select[data-name="thread"], +#file-n-submit:not(.has-file) #qr-filerm { + display: none; +} +:root.hide-original-post-form #postForm { + display: none !important; +} +#qr select, +#qr-filename-container > a, +.remove, +.captcha-img { + cursor: pointer; +} +#qr { + position: fixed; + padding: 1px; + border: 1px solid transparent; + min-width: 300px; + border-radius: 3px 3px 0 0; +} +#qr > form { + /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */ + max-height: 85vh; + max-height: calc(100vh - 75px); + overflow-y: auto; + overflow-x: hidden; +} +#qrtab { + border-radius: 3px 3px 0 0; +} +#qrtab { + margin-bottom: 1px; +} +#qr .close { + float: right; + padding: 0 3px; +} +.qr-link-container { + text-align: center; + margin: 16px 0; +} +.qr-link-container-bottom { + width: 200px; + position: absolute; + left: -100px; + margin-left: 50%; + text-align: center; +} +.qr-link { + border-radius: 3px; + padding: 6px 10px 5px; + font-weight: bold; + vertical-align: middle; + border-style: solid; + border-width: 1px; + font-size: 10pt; +} +.qr-link-container + #togglePostFormLink { + font-size: 10pt; + font-weight: normal; + margin: -8px 0 3.5px; +} +.persona { + width: 100%; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: row; + flex-direction: row; +} +.persona .field { + -webkit-flex: 1; + flex: 1; + width: 0; +} +#qr.forced-anon input[data-name="name"]:not(.force-show), +#qr.forced-anon input[data-name="sub"]:not(.force-show), +#qr.reply-to-thread input[data-name="sub"]:not(.force-show), +body:not(.board_f) #qr select[name="filetag"], +#qr.reply-to-thread select[name="filetag"], +#qr:not(.has-sjis) #sjis-toggle, +#qr:not(.has-math) #tex-preview-button, +#qr.tex-preview .textarea > :not(#tex-preview), +#qr:not(.tex-preview) #tex-preview { + display: none; +} +.persona button { + -webkit-flex: 0 0 23px; + flex: 0 0 23px; + -webkit-align-self: stretch; + align-self: stretch; + border: 1px solid #BBB; + padding: 0; + background: linear-gradient(to bottom, #F8F8F8, #DCDCDC) no-repeat; + color: #000; +} +#qr.sjis-preview #sjis-toggle, #qr.tex-preview #tex-preview-button { + background: #DCDCDC; +} +#sjis-toggle, #qr.sjis-preview textarea.field { + font-family: "IPAMonaPGothic","Mona","MS PGothic",monospace; + font-size: 16px; + line-height: 17px; +} +#tex-preview-button { + font-size: 10px; +} +#tex-preview { + white-space: pre-line; +} +#qr textarea.field { + height: 14.8em; + min-height: 9em; +} +#qr.has-captcha textarea.field { + height: 9em; +} +input.field.tripped:not(:hover):not(:focus) { + color: transparent !important; + text-shadow: none !important; +} +#qr textarea { + min-width: 300px; + resize: both; +} +.field { + -moz-box-sizing: border-box; + box-sizing: border-box; + margin: 0px; + padding: 2px 4px 3px; +} +#qr label input[type="checkbox"] { + position: relative; + top: 2px; +} + +/* Recaptcha v2 */ +#qr .captcha-root { + position: relative; +} +#qr .captcha-container > div { + margin: auto; + width: 304px; +} +/* XXX scrollable with scroll bar hidden; prevents scroll on space press */ +:root.ua-blink #qr .captcha-container > div, +:root.ua-edge #qr .captcha-container > div { + overflow: hidden; +} +:root.ua-blink #qr .captcha-container > div > div:first-of-type, +:root.ua-edge #qr .captcha-container > div > div:first-of-type { + overflow-y: scroll; + overflow-x: hidden; + padding-right: 30px; + height: 99%; + width: 100%; +} +#qr .captcha-counter { + display: block; + width: 100%; + text-align: center; + pointer-events: none; +} +#qr.captcha-open .captcha-counter { + position: absolute; + bottom: 3px; +} +#qr .captcha-counter > a { + pointer-events: auto; + display: inline-block; /* XXX https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8851747/ */ +} +#qr:not(.captcha-open) .captcha-counter > a { + display: block; + width: 100%; +} +#qr.captcha-v2 #qr-captcha-iframe { + width: 302px; + height: 423px; + border: 0; + display: block; + margin: auto; +} +.goog-bubble-content { + max-width: 100vw; + max-height: 100vh; + overflow: auto; +} +.goog-bubble-content iframe { + position: static !important; +} + +/* File Input, Submit Button, Oekaki */ +#file-n-submit, #qr .oekaki { + display: -webkit-flex; + display: flex; + -webkit-align-items: stretch; + align-items: stretch; + height: 25px; + margin-top: 1px; +} +#file-n-submit > input, #qr-draw-button { + background: linear-gradient(to bottom, #F8F8F8, #DCDCDC) no-repeat; + border: 1px solid #BBB; + border-radius: 2px; + height: 100%; +} +#qr-file-button, #qr-draw-button { + width: 15%; +} +#file-n-submit input[type="submit"] { + width: 25%; +} +#qr-filename-container { + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + width: 0; + display: -webkit-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + position: relative; + padding: 1px; +} +input#qr-filename { + border: none !important; + background: none !important; + outline: none; +} +#qr-filename, +.has-file #qr-no-file { + display: none; +} +#qr-no-file, +.has-file #qr-filename { + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + width: 0px; /* XXX Fixes filename not shrinking to allow space for buttons in Edge */ + display: inline-block; + padding: 0; + padding-left: 3px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +#qr-no-file { + color: #AAA; +} +#qr .oekaki.has-file { + display: none; +} +#qr .oekaki > label { + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + width: 0; + display: -webkit-flex; + display: flex; + -webkit-align-items: center; + align-items: center; + height: 100%; +} +#qr .oekaki > label > span { + margin: 0 3px; +} +#qr .oekaki > label > input { + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + width: 0; + height: 100%; +} +#qr .oekaki-bg { + position: relative; + display: inline-block; + height: 100%; + width: 10%; + margin-left: 3px; +} +#qr .oekaki-bg > * { + position: absolute; + top: 0; + left: 0; + margin: 0; +} +#qr .oekaki-bg > :not([name="oekaki-bgcolor"]) { + z-index: 1; +} +#qr [name="oekaki-bgcolor"] { + height: 100%; + width: 100%; + border: none; + padding: 0; +} +#qr [name="oekaki-bg"]:not(:checked) ~ [name="oekaki-bgcolor"] { + visibility: hidden; +} +#qr input[type="file"] { + visibility: hidden; + position: absolute; +} + +/* Spoiler Checkbox, QR Icons */ +#qr-filename-container > label, #qr-filename-container > a { + -webkit-flex: none; + flex: none; + margin: 0; + margin-right: 3px; +} +#qr:not(.has-spoiler) #qr-spoiler-label, +#file-n-submit:not(.has-file) #qr-spoiler-label, +.has-file #paste-area, +.has-file #url-button, +#file-n-submit:not(.custom-cooldown) #custom-cooldown-button { + display: none; +} +#qr-filename-container > label { + position: relative; +} +#qr-filename-container input[type="checkbox"] { + margin: 0; +} +.checkbox-letter { + font-size: 13px; + font-weight: bold; +} +#qr-filename-container label:not(:hover) > input[type="checkbox"]:not(:focus):not(:checked), +#qr-filename-container label:not(:hover) > input[type="checkbox"]:not(:focus):not(:checked) ~ :not(.checkbox-letter), +#qr-filename-container label:hover > .checkbox-letter, +input[type="checkbox"]:focus ~ .checkbox-letter, +input[type="checkbox"]:checked ~ .checkbox-letter { + /* not displayed but still focusable */ + position: absolute; + opacity: 0; + pointer-events: none; +} +.checkbox-letter, #paste-area, #url-button, #custom-cooldown-button, #dump-button { + opacity: 0.6; +} +#paste-area { + font-size: 0; +} +#paste-area:focus { + opacity: 1; +} +#custom-cooldown-button.disabled { + opacity: 0.27; +} + +/* Thread and Flash Tag Select */ +#qr select { + background: white; + border: 1px solid #CCC; +} +#qr select[data-name="thread"] { + float: right; +} +#qr > form > select { + margin-top: 1px; +} + +/* Dumping UI */ +.dump #dump-list-container { + display: block; +} +#dump-list-container { + display: none; + position: relative; + overflow-y: hidden; + margin-top: 1px; +} +#dump-list { + overflow-x: auto; + overflow-y: auto; + white-space: nowrap; + width: 248px; + max-height: 248px; + min-height: 90px; + max-width: 100%; + min-width: 100%; + display: -webkit-flex; + display: flex; + -webkit-flex-wrap: wrap; + flex-wrap: wrap; +} +#dump-list:hover { + overflow-x: auto; +} +.qr-preview { + -moz-box-sizing: border-box; + box-sizing: border-box; + counter-increment: thumbnails; + cursor: move; + display: inline-block; + height: 90px; + width: 90px; + padding: 2px; + opacity: .5; + overflow: hidden; + position: relative; + text-shadow: 0 0 2px #000; + -webkit-transition: opacity .25s ease-in-out, -webkit-transform .25s ease-in-out; + transition: opacity .25s ease-in-out, transform .25s ease-in-out, -webkit-transform .25s ease-in-out; + vertical-align: top; + background-size: cover; + -webkit-flex: none; + flex: none; +} +.qr-preview:hover, +.qr-preview:focus { + opacity: .9; +} +.qr-preview::before { + content: counter(thumbnails); + color: #fff; + position: absolute; + top: 3px; + right: 3px; + text-shadow: 0 0 3px #000, 0 0 8px #000; +} +.qr-preview#selected { + opacity: 1; +} +.qr-preview.drag { + box-shadow: 0 0 10px rgba(0,0,0,.5); + -webkit-transform: scale(.8); + transform: scale(.8); +} +.qr-preview.over { + border-color: #fff; + -webkit-transform: scale(1.1); + transform: scale(1.1); + opacity: 0.9; + z-index: 10; +} +.qr-preview > span { + color: #fff; +} +.remove { + background: none; + color: #e00; + padding: 1px; +} +a:only-of-type > .remove { + display: none; +} +.remove:hover::after { + content: " Remove"; +} +.qr-preview:not(.has-file) label, +#qr:not(.has-spoiler) .qr-preview-spoiler { + display: none; +} +.qr-preview > label { + background: rgba(0,0,0,.5); + color: #fff; + right: 0; + bottom: 0; + left: 0; + position: absolute; + text-align: center; +} +.qr-preview > label > input { + margin: 0; +} +#add-post { + cursor: pointer; + font-size: 2em; + position: absolute; + bottom: 20px; + right: 10px; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); +} +.textarea { + position: relative; + display: -webkit-flex; + display: flex; +} +#char-count { + color: #000; + background: hsla(0, 0%, 100%, .5); + font-size: 8pt; + position: absolute; + bottom: 1px; + right: 1px; + pointer-events: none; +} +#char-count.warning { + color: red; +} + +/* Menu */ +.menu-button:not(.fa-bars) { + display: inline-block; + position: relative; + cursor: pointer; +} +#header-bar .menu-button i { + border-top: 6px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + display: inline-block; + margin: 2px; + vertical-align: middle; +} +.postInfo > .menu-button, +#thread-watcher .menu-button { + width: 18px; + height: 15px; + text-align: center; +} +#menu { + position: fixed; + outline: none; + font-weight: normal; +} +#menu, .submenu { + border-radius: 3px; + padding-top: 1px; + padding-bottom: 3px; +} +.entry { + cursor: pointer; + display: block; + outline: none; + padding: 2px 10px; + position: relative; + text-decoration: none; + white-space: nowrap; + min-width: 70px; + text-align: left; + text-shadow: none; + font-size: 10pt; +} +.left>.entry.has-submenu { + padding-right: 17px !important; +} +.entry input[type="checkbox"], +.entry input[type="radio"] { + margin: 0px; + position: relative; + top: 2px; +} +.entry input[type="number"] { + width: 4.5em; +} +.entry.has-shortcut-text { + display: flex; + justify-content: space-between; + align-items: center; +} +.entry .shortcut-text { + opacity: 0.5; + font-size: 70%; + margin-left: 5px; +} +.has-submenu::after { + content: ""; + border-left: .5em solid; + border-top: .3em solid transparent; + border-bottom: .3em solid transparent; + display: inline-block; + margin: .3em; + position: absolute; + right: 3px; +} +.left .has-submenu::after { + border-left: 0; + border-right: .5em solid; +} +.submenu { + display: none; + position: absolute; + left: 100%; + top: -1px; + margin-left: 0px; + margin-top: -2px; +} +.focused > .submenu { + display: block; +} +.imp-exp-result { + position: absolute; + text-align: center; + margin: auto; + right: 0px; + left: 0px; + width: 200px; +} + +/* Custom Board Titles */ +.boardTitle, .boardSubtitle { + white-space: pre-line; +} +.boardTitle[contenteditable="true"], +.boardSubtitle[contenteditable="true"] { + cursor: text !important; +} + +/* Embedding */ +.embedder:not(.embedded) > span { + display: none; +} +#embedding { + padding: 1px 4px 1px 4px; + position: fixed; +} +#embedding.empty { + display: none; +} +#embedding > div:first-child { + display: -webkit-flex; + display: flex; +} +#embedding .move { + -webkit-flex: 1; + flex: 1; +} +#embedding .jump { + margin: -1px 4px; + text-decoration: none; +} + +/* Gallery */ +#a-gallery { + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: row; + flex-direction: row; + background: rgba(0,0,0,0.7); +} +.gal-viewport { + display: -webkit-flex; + display: flex; + -webkit-align-items: stretch; + align-items: stretch; + -webkit-flex-direction: row; + flex-direction: row; + -webkit-flex: 1 1 auto; + flex: 1 1 auto; + overflow: hidden; +} +.gal-thumbnails { + -webkit-flex: 0 0 150px; + flex: 0 0 150px; + overflow-y: auto; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: column; + flex-direction: column; + -webkit-align-items: stretch; + align-items: stretch; + text-align: center; + background: rgba(0,0,0,.5); + border-left: 1px solid #222; +} +.gal-hide-thumbnails .gal-thumbnails { + display: none; +} +.gal-thumb img, +.gal-thumb video { + max-width: 125px; + max-height: 125px; + height: auto; + width: auto; +} +.gal-thumb { + -webkit-flex: 0 0 auto; + flex: 0 0 auto; + padding: 3px; + line-height: 0; + transition: background .2s linear; +} +.gal-highlight { + background: rgba(0, 190, 255,.8); +} +.gal-prev { + border-right: 1px solid #222; +} +.gal-next { + border-left: 1px solid #222; +} +.gal-prev, +.gal-next { + -webkit-flex: 0 0 20px; + flex: 0 0 20px; + position: relative; + cursor: pointer; + opacity: 0.7; + background-color: rgba(0, 0, 0, 0.3); +} +.gal-prev:hover, +.gal-next:hover { + opacity: 1; +} +.gal-prev::after, +.gal-next::after { + position: absolute; + top: 48.6%; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); + display: inline-block; + border-top: 11px solid transparent; + border-bottom: 11px solid transparent; + content: ""; +} +.gal-prev::after { + border-right: 12px solid #fff; + right: 5px; +} +.gal-next::after { + border-left: 12px solid #fff; + right: 3px; +} +.gal-image { + -webkit-flex: 1 0 auto; + flex: 1 0 auto; + display: -webkit-flex; + display: flex; + -webkit-align-items: flex-start; + align-items: flex-start; + -webkit-justify-content: space-around; + justify-content: space-around; + overflow: hidden; + /* Flex > Non-Flex child max-width and overflow fix (Firefox only?) */ + width: 1%; +} +:root:not(.gal-fit-height):not(.gal-pdf) .gal-image { + overflow-y: scroll !important; +} +:root:not(.gal-fit-width):not(.gal-pdf) .gal-image { + overflow-x: scroll !important; +} +.gal-image a { + display: -webkit-flex; + display: flex; + -webkit-align-items: flex-start; + align-items: flex-start; + margin: auto; + line-height: 0; + max-width: 100%; +} +:root.gal-pdf .gal-image a { + width: 100%; + height: 100%; +} +.gal-image img, +.gal-image video { + -webkit-flex: none; + flex: none; +} +.gal-fit-width .gal-image img, +.gal-fit-width .gal-image video { + max-width: 100%; +} +.gal-fit-height .gal-image img, +.gal-fit-height .gal-image video { + /* XXX https://code.google.com/p/chromium/issues/detail?id=168840, https://bugs.webkit.org/show_bug.cgi?id=94158 */ + max-height: 95vh; + max-height: calc(100vh - 25px); +} +.gal-image iframe { + width: 100%; + height: 100%; +} +.gal-buttons { + font-size: 2em; + margin-right: 3px; + padding-left: 7px; + padding-right: 7px; + top: 5px; +} +:root.gal-pdf .gal-buttons { + top: 40px; + background: rgba(0,0,0,0.6) !important; + border-radius: 3px; +} +.gal-buttons a { + color: #ffffff; + text-shadow: 0px 0px 1px #000000; +} +.gal-buttons i { + display: inline-block; + margin: 2px; + position: relative; +} +.gal-start i { + border-left: 10px solid; + border-top: 6px solid transparent; + border-bottom: 6px solid transparent; + bottom: 1px; +} +.gal-stop i { + border: 5px solid; + bottom: 2px; +} +.gal-buttons.gal-playing > .gal-start, +.gal-buttons:not(.gal-playing) > .gal-stop { + display: none; +} +.gal-buttons .menu-button i { + border-top: 10px solid; + border-right: 6px solid transparent; + border-left: 6px solid transparent; + bottom: 2px; + vertical-align: baseline; +} +.gal-labels { + position: fixed; + bottom: 6px; + display: -webkit-flex; + display: flex; + -webkit-flex-direction: column; + flex-direction: column; + -webkit-align-items: flex-end; + align-items: flex-end; + +} +:root:not(.show-sauce) .gal-sauce { + display: none; +} +.gal-name, +.gal-count, +.gal-sauce { + background: rgba(0,0,0,0.6) !important; + border-radius: 3px; + padding: 1px 5px 2px 5px; + margin-top: 3px; + color: #ffffff !important; + text-decoration: none !important; +} +.gal-sauce a { + color: #ffffff !important; +} +.gal-name:hover, +.gal-buttons a:hover, +.gal-sauce a:hover { + color: rgb(95, 95, 101) !important; +} +:root.gal-pdf .gal-buttons a:hover { + color: rgb(204, 204, 204) !important; +} +.gal-buttons, +.gal-labels { + position: fixed; + right: 195px; +} +.gal-hide-thumbnails .gal-buttons, +.gal-hide-thumbnails .gal-labels { + right: 44px; +} +:root:not(.gal-fit-width):not(.gal-pdf) .gal-labels { + bottom: 23px !important; +} +:root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-buttons, +:root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-labels { + right: 178px !important; +} +:root.gal-hide-thumbnails.gal-fit-height:not(.gal-pdf) .gal-buttons, +:root.gal-hide-thumbnails.gal-fit-height:not(.gal-pdf) .gal-labels { + right: 28px !important; +} +:root.gallery-open.fixed #header-bar:not(.autohide), +:root.gallery-open.fixed #header-bar:not(.autohide) #shortcuts .fa::before { + visibility: hidden; +} + +/* Mod Contact Links */ +.contact-links { + margin-left: 2px; +} +.move-note > a { + text-decoration: underline; +} +.invisible { + font-size: 0; +} + +/* PostJumper */ +.postJumper > .prev, +.postJumper > .next { + font-size: 120%; +} + +/* PSA */ +.fcx-announcement { + text-align: center; +} +.fcx-announcement a { + text-decoration: underline; +} + +@keyframes spin { + 0% {transform:rotate(0deg);} + 100% {transform:rotate(359deg);} +} + +.spin { + animation:spin 2s infinite linear; +} +`; + + var supports = `/* XXX Moved to end of stylesheet to avoid breaking whole stylesheet in Maxthon. */ +@supports (text-decoration-style: dashed) or (-moz-text-decoration-style: dashed) { + .quotelink.forwardlink, + .backlink.forwardlink { + text-decoration: underline; + -moz-text-decoration-style: dashed; + text-decoration-style: dashed; + border-bottom: none; + } +} +`; + + var tomorrow = `/* General */ +:root.tomorrow .dialog { + background-color: #282A2E; + border-color: #111; +} + +/* 4chan style fixes */ +:root.tomorrow #arc-list span.quote { + color: #B5BD68; +} +:root.tomorrow.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(145, 182, 214, .8) !important; +} +:root.tomorrow.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(145, 182, 214, .8) !important; +} + +/* Header */ +:root.tomorrow #header-bar.dialog { + background-color: rgba(40,42,46,0.9); +} +:root.tomorrow:not(.fixed) #header-bar, :root.tomorrow #notifications { + font-size: 9pt; +} +:root.tomorrow #header-bar, :root.tomorrow #notifications { + color: #C5C8C6; +} +:root.tomorrow #header-bar a, :root.tomorrow #notifications a { + color: #81A2BE; +} +:root.tomorrow.shortcut-icons .native-settings { + background-image: url('//s.4cdn.org/image/favicon-ws.ico'); +} + +/* Settings */ +:root.tomorrow #fourchanx-settings fieldset, :root.tomorrow .section-main div::before { + border-color: #111; +} +:root.tomorrow .suboption-list > div:last-of-type { + background-color: #282A2E; +} + +/* Catalog */ +:root.tomorrow.catalog-hover-expand .catalog-container:hover > .post { + background-color: #282A2E; +} +:root.tomorrow.werkTyme .catalog-thread:not(:hover), +:root.tomorrow.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.tomorrow.catalog-hover-expand .catalog-container:hover > .post, +:root.tomorrow.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #111; +} + +/* Quote */ +:root.tomorrow .backlink.deadlink { + color: #81A2BE !important; +} +:root.tomorrow .inline { + border-color: #111; + background-color: rgba(0, 0, 0, .14); +} + +/* Fappe and Werk Tyme */ +:root.tomorrow .indicator { + color: #282A2E; +} + +/* Highlighting */ +:root.tomorrow .qphl { + outline: 2px solid rgba(145, 182, 214, .8); +} +:root.tomorrow.highlight-you .quotesYou$site$highlightable$op, +:root.tomorrow.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(145, 182, 214, .8); +} +:root.tomorrow.highlight-own .yourPost$site$highlightable$op, +:root.tomorrow.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(145, 182, 214, .8); +} +:root.tomorrow .filter-highlight$site$highlightable$op, +:root.tomorrow .filter-highlight$site$highlightable$reply { + box-shadow: inset 5px 0 rgba(145, 182, 214, .5); +} +:root.tomorrow.highlight-own .yourPost > $site$sideArrows, +:root.tomorrow.highlight-you .quotesYou > $site$sideArrows, +:root.tomorrow .filter-highlight > $site$sideArrows { + color: rgb(155, 185, 210); +} +:root.tomorrow .catalog-thread.filter-highlight .catalog-thumb, +:root.tomorrow.werkTyme .catalog-thread.filter-highlight:not(:hover), +:root.tomorrow.werkTyme:not(.catalog-hover-expand) .catalog-thread.filter-highlight, +:root.tomorrow.werkTyme.catalog-hover-expand .catalog-thread.filter-highlight > .catalog-container:hover > .catalog-post { + box-shadow: 0 0 3px 3px rgba(64, 192, 255, .7); +} +:root.tomorrow .catalog-thread.watched .catalog-thumb, +:root.tomorrow.werkTyme .catalog-thread.watched:not(:hover), +:root.tomorrow.werkTyme:not(.catalog-hover-expand) .catalog-thread.watched, +:root.tomorrow.werkTyme.catalog-hover-expand .catalog-thread.watched > .catalog-container:hover > .catalog-post { + border: 2px solid rgb(64, 192, 255); +} + + +/* QR */ +.tomorrow #dump-list::-webkit-scrollbar-thumb { + background-color: #282A2E; + border-color: #111; +} +:root.tomorrow .qr-preview { + background-color: rgba(255, 255, 255, .15); +} +:root.tomorrow #qr .field { + background-color: rgb(26, 27, 29); + color: rgb(197,200,198); + border-color: rgb(40, 41, 42); +} +:root.tomorrow #qr .field:focus, +:root.tomorrow #qr .field.focus { + border-color: rgb(129, 162, 190) !important; + background-color: rgb(30,32,36); +} +:root.tomorrow .persona button { + background: linear-gradient(to bottom, #2E3035, #222427) no-repeat; + color: rgb(197,200,198); + border-color: rgb(40, 41, 42); + outline: none; +} +:root.tomorrow .persona button::-moz-focus-inner { + border: none; +} +:root.tomorrow .persona button:focus { + border-color: rgb(129, 162, 190); +} +:root.tomorrow #qr.sjis-preview #sjis-toggle, +:root.tomorrow #qr.tex-preview #tex-preview-button { + background: rgb(26, 27, 29); +} +:root.tomorrow #qr select, +:root.tomorrow #file-n-submit > input, +:root.tomorrow #qr-draw-button { + border-color: rgb(40, 41, 42); +} +:root.tomorrow #qr-filename { + color: rgb(197,200,198); +} +:root.tomorrow .qr-link { + border-color: rgb(25, 27, 31) rgb(25, 27, 31) rgb(10, 12, 16); + background: linear-gradient(#37393D, #282A2E) repeat scroll 0% 0% transparent; +} +:root.tomorrow .qr-link:hover { + background: #282A2E; +} + +/* Menu */ +:root.tomorrow #menu { + color: #C5C8C6; +} +:root.tomorrow .entry { + font-size: 10pt; +} +:root.tomorrow .focused.entry { + background: rgba(0, 0, 0, .33); +} + +/* Unread */ +:root.tomorrow .unread-line { + border-color: rgb(197, 200, 198); +} +:root.tomorrow .unread-mark-read { + background-color: rgba(40,42,46,0.5); +} + +/* Thread Watcher */ +:root.tomorrow .replies-quoting-you > a, :root.tomorrow #watcher-link.replies-quoting-you, :root.tomorrow .last-page > a > .watcher-page { + color: #F00 !important; +} + +/* Watcher Favicon */ +:root.tomorrow .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + var www = `#captcha-cnt { + height: auto; +} +:root:not(.js-enabled) #form { + display: block; +} +#bd > div[style], #bd > div[style] > * { + height: auto !important; + margin: 0 !important; + font-size: 0; +} +`; + + var yotsubaB = `/* General */ +:root.yotsuba-b .dialog { + background-color: #D6DAF0; + border-color: #B7C5D9; +} +:root.yotsuba-b .field:focus, +:root.yotsuba-b .field.focus { + border-color: #98E; +} + +/* 4chan style fixes */ +:root.yotsuba-b.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(221, 0, 0, .8) !important; +} +:root.yotsuba-b.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(221, 0, 0, .8) !important; +} + +/* Header */ +:root.yotsuba-b #header-bar.dialog { + background-color: rgba(214,218,240,0.98); +} +:root.yotsuba-b:not(.fixed) #header-bar, :root.yotsuba-b #notifications { + font-size: 9pt; +} +:root.yotsuba-b #header-bar, :root.yotsuba-b #notifications { + color: #89A; +} +:root.yotsuba-b #board-list a, :root.yotsuba-b #shortcuts a { + color: #34345C; +} + +/* Settings */ +:root.yotsuba-b #fourchanx-settings fieldset, :root.yotsuba-b .section-main div::before { + border-color: #B7C5D9; +} +:root.yotsuba-b .suboption-list > div:last-of-type { + background-color: #D6DAF0; +} + +/* Catalog */ +:root.yotsuba-b.catalog-hover-expand .catalog-container:hover > .post { + background-color: #D6DAF0; +} +:root.yotsuba-b.werkTyme .catalog-thread:not(:hover), +:root.yotsuba-b.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.yotsuba-b.catalog-hover-expand .catalog-container:hover > .post, +:root.yotsuba-b.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #B7C5D9; +} + +/* Quote */ +:root.yotsuba-b .backlink.deadlink { + color: #34345C !important; +} +:root.yotsuba-b .inline { + border-color: #B7C5D9; + background-color: rgba(255, 255, 255, .14); +} + +/* Fappe and Werk Tyme */ +:root.yotsuba-b .indicator { + color: #D6DAF0; +} + +/* QR */ +.yotsuba-b #dump-list::-webkit-scrollbar-thumb { + background-color: #D6DAF0; + border-color: #B7C5D9; +} +:root.yotsuba-b .qr-preview { + background-color: rgba(0, 0, 0, .15); +} +:root.yotsuba-b .qr-link { + border-color: rgb(199, 203, 225) rgb(199, 203, 225) rgb(184, 188, 210); + background: linear-gradient(#E5E9FF, #D6DAF0) repeat scroll 0% 0% transparent; +} +:root.yotsuba-b .qr-link:hover { + background: #D9DDF3; +} + + +/* Menu */ +:root.yotsuba-b #menu { + color: #000; +} +:root.yotsuba-b .entry { + font-size: 10pt; +} +:root.yotsuba-b .focused.entry { + background: rgba(255, 255, 255, .33); +} + +/* Unread */ +:root.yotsuba-b .unread-mark-read { + background-color: rgba(214,218,240,0.5); +} + +/* Thread Watcher */ +:root.yotsuba-b .replies-quoting-you > a, :root.yotsuba-b #watcher-link.replies-quoting-you { + color: #F00; +} + +/* Watcher Favicon */ +:root.yotsuba-b .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + var yotsuba = `/* General */ +:root.yotsuba .dialog { + background-color: #F0E0D6; + border-color: #D9BFB7; +} +:root.yotsuba .field:focus, +:root.yotsuba .field.focus { + border-color: #EA8; +} + +/* 4chan style fixes */ +:root.yotsuba.highlight-you .quotesYou$site$highlightable$reply { + border-left: 3px solid rgba(221, 0, 0, .8) !important; +} +:root.yotsuba.highlight-own .yourPost$site$highlightable$reply { + border-left: 3px dashed rgba(221, 0, 0, .8) !important; +} + +/* Header */ +:root.yotsuba #header-bar.dialog { + background-color: rgba(240,224,214,0.98); +} +:root.yotsuba:not(.fixed) #header-bar, :root.yotsuba #notifications { + font-size: 9pt; +} +:root.yotsuba #header-bar, :root.yotsuba #notifications { + color: #B86; +} +:root.yotsuba #board-list a, :root.yotsuba #shortcuts a { + color: #800000; +} + +/* Settings */ +:root.yotsuba #fourchanx-settings fieldset, :root.yotsuba .section-main div::before { + border-color: #D9BFB7; +} +:root.yotsuba .suboption-list > div:last-of-type { + background-color: #F0E0D6; +} + +/* Catalog */ +:root.yotsuba.catalog-hover-expand .catalog-container:hover > .post { + background-color: #F0E0D6; +} +:root.yotsuba.werkTyme .catalog-thread:not(:hover), +:root.yotsuba.werkTyme:not(.catalog-hover-expand) .catalog-thread, +:root.yotsuba.catalog-hover-expand .catalog-container:hover > .post, +:root.yotsuba.catalog-hover-expand .catalog-container:hover .catalog-reply { + border-color: #D9BFB7; +} + +/* Quote */ +:root.yotsuba .backlink.deadlink { + color: #00E !important; +} +:root.yotsuba .inline { + border-color: #D9BFB7; + background-color: rgba(255, 255, 255, .14); +} + +/* Fappe and Werk Tyme */ +:root.yotsuba .indicator { + color: #F0E0D6; +} + +/* QR */ +.yotsuba #dump-list::-webkit-scrollbar-thumb { + background-color: #F0E0D6; + border-color: #D9BFB7; +} +:root.yotsuba .qr-preview { + background-color: rgba(0, 0, 0, .15); +} +:root.yotsuba .qr-link { + border-color: rgb(225, 209, 199) rgb(225, 209, 199) rgb(210, 194, 184); + background: linear-gradient(#FFEFE5, #F0E0D6) repeat scroll 0% 0% transparent; +} +:root.yotsuba .qr-link:hover { + background: #F0E0D6; +} + +/* Menu */ +:root.yotsuba #menu { + color: #800000; +} +:root.yotsuba .entry { + font-size: 10pt; +} +:root.yotsuba .focused.entry { + background: rgba(255, 255, 255, .33); +} + +/* Unread */ +:root.yotsuba .unread-mark-read { + background-color: rgba(240,224,214,0.5); +} + +/* Thread Watcher */ +:root.yotsuba .replies-quoting-you > a, :root.yotsuba #watcher-link.replies-quoting-you, :root.yotsuba .last-page > a > .watcher-page { + color: #F00; +} + +/* Watcher Favicon */ +:root.yotsuba .watch-thread-link +{ + background-image: url("data:image/svg+xml,"); +} +`; + + // == Create CSS for Link Title Favicons == // + const icons = (data) => ('/* Link Title Favicons */\n' + + data.map(({ name, data }) => `.linkify.${name}::before { + content: ""; + background: transparent url('data:image/png;base64,${data}') center left no-repeat!important; + padding-left: 18px; +} +`).join('')); + + // cSpell:ignore installGentoo, webfont + // <% + // var inc = require['style']; + // var faCSS = read('/node_modules/font-awesome/css/font-awesome.css'); + // var mainCSS = ['font-awesome', 'style', 'yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon', 'spooky'].map(x => read(`${x}.css`)).join(''); + // var iconNames = files.filter(f => /^linkify\.[^.]+\.png$/.test(f)); + // var icons = iconNames.map(readBase64); + // %> + const mainCSS = style + yotsuba + yotsubaB + futaba + burichan + tomorrow + photon + spooky; + const faIcons = [ + { name: "Audio", data: linkifyAudio }, + { name: "Bitchute", data: linkifyBitchute }, + { name: "Clyp", data: linkifyClyp }, + { name: "Dailymotion", data: linkifyDailymotion }, + { name: "Gfycat", data: linkifyGfycat }, + { name: "Gist", data: linkifyGist }, + { name: "Image", data: linkifyImage }, + { name: "Installgentoo", data: linkifyInstallgentoo }, + { name: "Liveleak", data: linkifyLiveleak }, + { name: "Pastebin", data: linkifyPastebin }, + { name: "Peertube", data: linkifyPeertube }, + { name: "Soundcloud", data: linkifySoundcloud }, + { name: "Streamable", data: linkifyStreamable }, + { name: "Twitchtv", data: linkifyTwitchtv }, + { name: "Twitter", data: linkifyTwitter }, + { name: "Video", data: linkifyVideo }, + { name: "Vidlii", data: linkifyVidlii }, + { name: "Cimeo", data: linkifyCimeo }, + { name: "Vine", data: linkifyVine }, + { name: "Vocaroo", data: linkifyVocaroo }, + { name: "Youtube", data: linkifyYoutube }, + ]; + const CSS = { + boards: mainCSS + icons(faIcons) + supports, + report, + www, + sub: function (css) { + var variables = { + site: g.SITE.selectors + }; + return css.replace(/\$[\w\$]+/g, function (name) { + var words = name.slice(1).split('$'); + var sel = variables; + for (var i = 0; i < words.length; i++) { + if (typeof sel !== 'object') + return ':not(*)'; + sel = $$1.getOwn(sel, words[i]); + } + if (typeof sel !== 'string') + return ':not(*)'; + return sel; + }); + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const CustomCSS = { + init() { + if (!Conf['Custom CSS']) { return; } + return this.addStyle(); + }, + + addStyle() { + return this.style = $$1.addStyle(CSS.sub(Conf['usercss']), 'custom-css', '#fourchanx-css'); + }, + + rmStyle() { + if (this.style) { + $$1.rm(this.style); + return delete this.style; + } + }, + + update() { + if (!this.style) { + return this.addStyle(); + } + return this.style.textContent = CSS.sub(Conf['usercss']); + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const SWTinyboard = { + isOPContainerThread: true, + mayLackJSON: true, + threadModTimeIgnoresSage: true, + + 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 script of $$('script:not([src])', d$1.head)) { + var m; + if (m = script.textContent.match(/\bvar configRoot=(".*?")/)) { + var properties = dict(); + try { + var root = JSON.parse(m[1]); + if (root[0] === '/') { + properties.root = location.origin + root; + } else if (/^https?:/.test(root)) { + properties.root = root; + } + } catch (error) {} + return properties; + } + } + return false; + }, + + awaitBoard(cb) { + if ($$1.id('react-ui')) { + const s = (this.selectors = Object.create(this.selectors)); + s.boardFor = {index: '.page-container'}; + s.thread = 'div[id^="thread_"]'; + return Main$1.mounted(cb); + } else { + return cb(); + } + }, + + urls: { + thread({siteID, boardID, threadID}, isArchived) { + return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/${isArchived ? 'archive/' : ''}res/${threadID}.html`; + }, + post({postID}) { return `#${postID}`; }, + index({siteID, boardID}) { return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/`; }, + catalog({siteID, boardID}) { return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/catalog.html`; }, + threadJSON({siteID, boardID, threadID}, isArchived) { + const root = Conf['siteProperties'][siteID]?.root; + if (root) { return `${root}${boardID}/${isArchived ? 'archive/' : ''}res/${threadID}.json`; } else { return ''; } + }, + archivedThreadJSON(thread) { + return SWTinyboard.urls.threadJSON(thread, true); + }, + threadsListJSON({siteID, boardID}) { + const root = Conf['siteProperties'][siteID]?.root; + if (root) { return `${root}${boardID}/threads.json`; } else { return ''; } + }, + archiveListJSON({siteID, boardID}) { + const root = Conf['siteProperties'][siteID]?.root; + if (root) { return `${root}${boardID}/archive/archive.json`; } else { return ''; } + }, + catalogJSON({siteID, boardID}) { + const root = Conf['siteProperties'][siteID]?.root; + if (root) { return `${root}${boardID}/catalog.json`; } else { return ''; } + }, + file({siteID, boardID}, filename) { + return `${Conf['siteProperties'][siteID]?.root || `http://${siteID}/`}${boardID}/${filename}`; + }, + thumb(board, filename) { + return SWTinyboard.urls.file(board, filename); + } + }, + + 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)', // postContainer is thread for OP + 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: + /]*\bhref="[^"]*\/([^\/]+)\/res\/(\d+)(?:\.\w+)?#(\d+)"/g + }, + + Build: { + parseJSON(data, board) { + const o = this.parseJSON(data, board); + if (data.ext === 'deleted') { + delete o.file; + $$1.extend(o, { + files: [], + fileDeleted: true, + filesDeleted: [0] + }); + } + if (data.extra_files) { + let file; + for (let i = 0; i < data.extra_files.length; i++) { + var extra_file = data.extra_files[i]; + if (extra_file.ext === 'deleted') { + o.filesDeleted.push(i); + } else { + file = this.parseJSONFile(data, board); + o.files.push(file); + } + } + if (o.files.length) { + o.file = o.files[0]; + } + } + return o; + }, + + parseComment(html) { + html = html + .replace(//gi, '\n') + .replace(/<[^>]*>/g, ''); + return $$1.unescape(html); + } + }, + + bgColoredEl() { + return $$1.el('div', {className: 'post reply'}); + }, + + isFileURL(url) { + return /\/src\/[^\/]+/.test(url.pathname); + }, + + preParsingFixes(board) { + // fixes effects of unclosed link in announcement + let broken; + if (broken = $$1('a > input[name="board"]', board)) { + return $$1.before(broken.parentNode, broken); + } + }, + + parseNodes(post, nodes) { + // Add vichan's span.poster_id around the ID if not already present. + let m; + if (nodes.uniqueID) { return; } + let text = ''; + let node = nodes.nameBlock.nextSibling; + while (node && (node.nodeType === 3)) { + text += node.textContent; + node = node.nextSibling; + } + if (m = text.match(/(\s*ID:\s*)(\S+)/)) { + let uniqueID; + nodes.info.normalize(); + let {nextSibling} = nodes.nameBlock; + nextSibling = nextSibling.splitText(m[1].length); + nextSibling.splitText(m[2].length); + nodes.uniqueID = (uniqueID = $$1.el('span', {className: 'poster_id'})); + $$1.replace(nextSibling, uniqueID); + return $$1.add(uniqueID, nextSibling); + } + }, + + parseDate(node) { + let date = Date.parse(node.getAttribute('datetime')?.trim()); + if (!isNaN(date)) { return new Date(date); } + date = Date.parse(node.textContent.trim() + ' UTC'); // e.g. onesixtwo.club + if (!isNaN(date)) { return new Date(date); } + return undefined; + }, + + parseFile(post, file) { + let info, infoNode; + const {text, link, thumb} = file; + if ($$1.x(`ancestor::${this.xpath.postContainer}[1]`, text) !== post.nodes.root) { return false; } // file belongs to a reply + if (!(infoNode = link.nextSibling?.textContent.includes('(') ? link.nextSibling : link.nextElementSibling)) { return false; } + if (!(info = infoNode.textContent.match(/\((.*,\s*)?([\d.]+ ?[KMG]?B).*\)/))) { return false; } + const nameNode = $$1('.postfilename', text); + $$1.extend(file, { + name: nameNode ? (nameNode.title || nameNode.textContent) : link.pathname.match(/[^/]*$/)[0], + size: info[2], + dimensions: info[0].match(/\d+x\d+/)?.[0] + }); + if (thumb) { + $$1.extend(file, { + thumbURL: /\/static\//.test(thumb.src) && $$1.isImage(link.href) ? link.href : thumb.src, + isSpoiler: /^Spoiler/i.test(info[1] || '') || (link.textContent === 'Spoiler Image') + } + ); + } + return true; + }, + + isThumbExpanded(file) { + // Detect old Tinyboard image expansion that changes src attribute on thumbnail. + return $$1.hasClass(file.thumb.parentNode, 'expanded') || (file.thumb.parentNode.dataset.expanded === 'true'); + }, + + isLinkified(link) { + return /\bnofollow\b/.test(link.rel); + }, + + catalogPin(threadRoot) { + return threadRoot.dataset.sticky = 'true'; + } + }; + + const passMessagePage = h("div", { class: "box-inner" }, + h("div", { class: "boxbar" }, + h("h2", null, + "Trouble buying a 4chan Pass? (a message from 4chan X)", + h("a", { href: "javascript:;", style: "text-decoration: none; float: right; margin-right: 4px;", title: "Close" }, "\u00D7"))), + h("div", { class: "boxcontent" }, + "Check the 4chan X wiki for ", + h("a", { href: `${meta.captchaFAQ}#alternatives`, target: "_blank", rel: "noopener" }, "alternative solutions"), + ".")); + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + const PassMessage = { + init() { + if (Conf['passMessageClosed']) { return; } + const msg = $$1.el('div', + {className: 'box-outer top-box'} + , + passMessagePage); + msg.style.cssText = 'padding-bottom: 0;'; + const close = $$1('a', msg); + $$1.on(close, 'click', function() { + $$1.rm(msg); + return $$1.set('passMessageClosed', true); + }); + return $$1.ready(function() { + let hd; + if (hd = $$1.id('hd')) { + return $$1.after(hd, msg); + } else { + return $$1.prepend(d$1.body, msg); + } + }); + } + }; + + var ReportPage = ` + + + +`; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var Report = { + init() { + let match; + if (!(match = location.search.match(/\bno=(\d+)/))) { return; } + Captcha.replace.init(); + this.postID = +match[1]; + return $$1.ready(this.ready); + }, + + ready() { + $$1.addStyle(CSS.report); + + if (Conf['Archive Report']) { Report.archive(); } + + new MutationObserver(function() { + Report.fit('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); + return Report.fit('body'); + }).observe(d$1.body, { + childList: true, + attributes: true, + subtree: true + } + ); + return Report.fit('body'); + }, + + fit(selector) { + let el; + if (!((el = $$1(selector, doc)) && (getComputedStyle(el).visibility !== 'hidden'))) { return; } + const dy = (el.getBoundingClientRect().bottom - doc.clientHeight) + 8; + if (dy > 0) { return window.resizeBy(0, dy); } + }, + + archive() { + let match, urls; + if (!(urls = Redirect$1.report(g.BOARD.ID)).length) { return; } + + const form = $$1('form'); + const types = $$1.id('reportTypes'); + const message = $$1('h3'); + + const fieldset = $$1.el('fieldset', { + id: 'archive-report', + hidden: true + } + , + { innerHTML: ReportPage }); + const enabled = $$1('#archive-report-enabled', fieldset); + const reason = $$1('#archive-report-reason', fieldset); + const submit = $$1('#archive-report-submit', fieldset); + + $$1.on(enabled, 'change', function() { + return reason.disabled = !this.checked; + }); + + if (form && types) { + fieldset.hidden = !$$1('[value="31"]', types).checked; + $$1.on(types, 'change', function(e) { + fieldset.hidden = (e.target.value !== '31'); + return Report.fit('body'); + }); + $$1.after(types, fieldset); + Report.fit('body'); + $$1.one(form, 'submit', function(e) { + if (!fieldset.hidden && enabled.checked) { + e.preventDefault(); + return Report.archiveSubmit(urls, reason.value, results => { + this.action = '#archiveresults=' + encodeURIComponent(JSON.stringify(results)); + return this.submit(); + }); + } + }); + } else if (message) { + fieldset.hidden = /Report submitted!/.test(message.textContent); + $$1.on(enabled, 'change', function() { + return submit.hidden = !this.checked; + }); + $$1.after(message, fieldset); + $$1.on(submit, 'click', () => Report.archiveSubmit(urls, reason.value, Report.archiveResults)); + } + + if (match = location.hash.match(/^#archiveresults=(.*)$/)) { + try { + return Report.archiveResults(JSON.parse(decodeURIComponent(match[1]))); + } catch (error) {} + } + }, + + archiveSubmit(urls, reason, cb) { + const form = $$1.formData({ + board: g.BOARD.ID, + num: Report.postID, + reason + }); + const results = []; + for (var [name, url] of urls) { + (function(name, url) { + return $$1.ajax(url, { + onloadend() { + results.push([name, this.response || {error: ''}]); + if (results.length === urls.length) { + return cb(results); + } + }, + form + }); + })(name, url); + } + }, + + archiveResults(results) { + const fieldset = $$1.id('archive-report'); + for (var [name, response] of results) { + var line = $$1.el('h3', + {className: 'archive-report-response'}); + if ('success' in response) { + $$1.addClass(line, 'archive-report-success'); + line.textContent = `${name}: ${response.success}`; + } else { + $$1.addClass(line, 'archive-report-error'); + line.textContent = `${name}: ${response.error || 'Error reporting post.'}`; + } + if (fieldset) { + $$1.before(fieldset, line); + } else { + $$1.add(d$1.body, line); + } + } + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const PostSuccessful = { + init() { + if (!Conf['Remember Your Posts']) { return; } + return $$1.ready(this.ready); + }, + + ready() { + if (d$1.title !== 'Post successful!') { return; } + + let [_, threadID, postID] = Array.from($$1('h1').nextSibling.textContent.match(/thread:(\d+),no:(\d+)/)); + postID = +postID; + threadID = +threadID || postID; + + const db = new DataBoard('yourPosts'); + return db.set({ + boardID: g.BOARD.ID, + threadID, + postID, + val: true + }); + } + }; + + function generatePostInfoHtml(ID, o, subject, capcode, email, name, tripcode, pass, capcodeLC, capcodePlural, staticPath, gifIcon, capcodeDescription, uniqueID, flag, flagCode, flagCodeTroll, dateUTC, dateText, postLink, quoteLink, boardID, threadID) { + const nameHtml = [h("span", { class: `name${capcode ? ' ' + capcode : ''}` }, name)]; + if (tripcode) + nameHtml.push(' ', h("span", { class: "postertrip" }, tripcode)); + if (pass) + nameHtml.push(' ', h("span", { title: `Pass user since ${pass}`, class: "n-pu" })); + if (capcode) { + nameHtml.push(' ', h("strong", { class: `capcode hand id_${capcodeLC}`, title: `Highlight posts by ${capcodePlural}` }, + "## ", + capcode)); + } + const nameBlockContent = email ? [' ', h("a", { href: `mailto:${email}`, class: "useremail" }, ...nameHtml)] : nameHtml; + if (!(boardID === "f" && !o.isReply || capcodeDescription)) + nameBlockContent.push(' '); + if (capcodeDescription) { + nameBlockContent.push(h("img", { src: `${staticPath}${capcodeLC}icon${gifIcon}`, alt: `${capcode} Icon}`, title: `This user is ${capcodeDescription}.`, class: "identityIcon retina" })); + if (uniqueID && !capcode) { + nameBlockContent.push(h("span", { class: `posteruid id_${uniqueID}` }, + "(ID: ", + h("span", { class: "hand", title: "Highlight posts by this ID" }, + "$", + uniqueID), + ")")); + } + } + if (flagCode) + nameBlockContent.push(' ', h("span", { title: flag, class: `flag flag-${flagCode.toLowerCase()}` })); + if (flagCodeTroll) + nameBlockContent.push(' ', h("span", { title: flag, class: `bfl bfl-${flagCodeTroll.toLowerCase()}` })); + const postNumContent = [ + h("a", { href: postLink, title: "Link to this post" }, "No."), + h("a", { href: quoteLink, title: "Reply to this post" }, ID), + ]; + if (o.isSticky) { + const src = `${staticPath}sticky${gifIcon}`; + postNumContent.push(' '); + if (boardID === "f") { + postNumContent.push(h("img", { src: src, alt: "Sticky", title: "Sticky", style: "height: 18px; width: 18px;" })); + } + else { + postNumContent.push(h("img", { src: src, alt: "Sticky", title: "Sticky", class: "stickyIcon retina" })); + } + } + if (o.isClosed && !o.isArchived) { + postNumContent.push(' '); + const src = `${staticPath}closed${gifIcon}`; + if (boardID === "f") { + postNumContent.push(h("img", { src: src, alt: "Closed", title: "Closed", style: "height: 18px; width: 18px;" })); + } + else { + postNumContent.push(h("img", { src: src, alt: "Closed", title: "Closed", class: "closedIcon retina" })); + } + } + if (o.isArchived) { + postNumContent.push(' ', h("img", { src: `${staticPath}archived${gifIcon}`, alt: "Archived", title: "Archived", class: "archivedIcon retina" })); + } + if (!o.isReply && g.VIEW === "index") { + // \u00A0 is nbsp + postNumContent.push(' \u00A0 '); + postNumContent.push(h("span", null, + "[", + h("a", { href: `/${boardID}/thread/${threadID}`, class: "replylink" }, "Reply"), + "]")); + } + return h("div", { class: "postInfo desktop", id: `pi${ID}` }, + h("input", { type: "checkbox", name: ID, value: "delete" }), + ' ', + ...((!o.isReply || boardID === "f" || subject) ? [h("span", { class: "subject" }, subject), ' '] : []), + h("span", { class: `nameBlock${capcode || ''}` }, ...nameBlockContent), + ' ', + h("span", { class: "dateTime", "data-utc": dateUTC }, dateText), + ' ', + h("span", { class: `postNum${!(boardID === " f" && !o.isReply) ? ' desktop' : ''}` }, ...postNumContent)); + } + + function generateFileHtml(file, ID, boardID, fileURL, shortFilename, fileThumb, o, staticPath, gifIcon) { + if (file) { + const fileContent = []; + if (boardID === "f") { + fileContent.push(h("div", { class: "fileInfo", "data-md5": file.MD5 }, + h("span", { class: "fileText", id: `fT${ID}` }, + 'File: ', + h("a", { "data-width": file.width, "data-height": file.height, href: fileURL, target: "_blank" }, file.name), + "-(", + file.size, + ", ", + file.dimensions, + file.tag ? ', ' + file.tag : '', + ")"))); + } + else { + fileContent.push(h("div", { class: "fileText", id: `fT${ID}`, title: file.isSpoiler ? file.name : null }, + 'File: ', + h("a", { title: file.name === shortFilename || file.isSpoiler ? null : file.name, href: fileURL, target: "_blank" }, file.isSpoiler ? 'Spoiler Image' : shortFilename), + ` (${file.size}, ${file.dimensions || "PDF"})`), h("a", { class: `fileThumb${file.isSpoiler ? ' imgspoiler' : ''}`, href: fileURL, target: "_blank", "data-m": file.hasDownscale ? '' : null }, + h("img", { src: fileThumb, alt: file.size, "data-md5": file.MD5, style: `height: ${file.isSpoiler ? '100' : file.theight}px; width: ${file.isSpoiler ? '100' : file.twidth}px;`, loading: "lazy" }))); + } + return h("div", { class: "file", id: `f${ID}` }, ...fileContent); + } + else if (o.fileDeleted) { + return h("div", { class: "file", id: `f${ID}` }, + h("span", { class: "fileThumb" }, + h("img", { src: `${staticPath}filedeleted-res${gifIcon}`, alt: "File deleted.", class: "fileDeletedRes retina" }))); + } + return { innerHTML: '', [isEscaped]: true }; + } + + function generateCatalogThreadHtml(thread, src, imgClass, data, postCount, fileCount, pageCount, staticPath, gifIcon) { + return h(hFragment, null, + h("a", { class: "catalog-link", href: `/${thread.board}/thread/${thread.ID}` }, imgClass ? + h("img", { src: src, class: `catalog-thumb ${imgClass}` }) : + h("img", { src: src, class: "catalog-thumb", "data-width": data.tn_w, "data-height": data.tn_h })), + h("div", { class: "catalog-stats" }, + h("span", { title: "Posts / Files / Page" }, + h("span", { class: `post-count${data.bumplimit ? ' warning' : ''}` }, postCount), + ' / ', + h("span", { class: `file-count${data.imagelimit ? ' warning' : ''}` }, fileCount), + ' / ', + h("span", { class: "page-count" }, pageCount)), + h("span", { class: "catalog-icons" }, + thread.isSticky ? h("img", { src: `${staticPath}sticky${gifIcon}`, class: "stickyIcon", title: "Sticky" }) : '', + thread.isClosed ? h("img", { src: `${staticPath}closed${gifIcon}`, class: "closedIcon", title: "Closed" }) : ''))); + } + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + const SWYotsuba = { + isOPContainerThread: false, + hasIPCount: true, + archivedBoardsKnown: true, + urls: { + thread({ boardID, threadID }) { return `${location.protocol}//${BoardConfig.domain(boardID)}/${boardID}/thread/${threadID}`; }, + post({ postID }) { return `#p${postID}`; }, + index({ boardID }) { return `${location.protocol}//${BoardConfig.domain(boardID)}/${boardID}/`; }, + catalog({ boardID }) { if (boardID === 'f') { + return undefined; + } + else { + return `${location.protocol}//${BoardConfig.domain(boardID)}/${boardID}/catalog`; + } }, + archive({ boardID }) { if (BoardConfig.isArchived(boardID)) { + return `${location.protocol}//${BoardConfig.domain(boardID)}/${boardID}/archive`; + } + else { + return undefined; + } }, + threadJSON({ boardID, threadID }) { return `${location.protocol}//a.4cdn.org/${boardID}/thread/${threadID}.json`; }, + threadsListJSON({ boardID }) { return `${location.protocol}//a.4cdn.org/${boardID}/threads.json`; }, + archiveListJSON({ boardID }) { if (BoardConfig.isArchived(boardID)) { + return `${location.protocol}//a.4cdn.org/${boardID}/archive.json`; + } + else { + return ''; + } }, + catalogJSON({ boardID }) { return `${location.protocol}//a.4cdn.org/${boardID}/catalog.json`; }, + file({ boardID }, filename) { + const hostname = boardID === 'f' ? ImageHost.flashHost() : ImageHost.host(); + return `${location.protocol}//${hostname}/${boardID}/${filename}`; + }, + thumb({ boardID }, filename) { + return `${location.protocol}//${ImageHost.thumbHost()}/${boardID}/${filename}`; + } + }, + isPrunedByAge({ boardID }) { return boardID === 'f'; }, + areMD5sDeferred({ boardID }) { return boardID === 'f'; }, + isOnePage({ boardID }) { return boardID === 'f'; }, + noAudio({ boardID }) { return BoardConfig.noAudio(boardID); }, + 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: /]*\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() { + return $$1.el('div', { className: 'reply' }); + }, + isThisPageLegit() { + // not 404 error page or similar. + return ['boards.4chan.org', 'boards.4channel.org'].includes(location.hostname) && + d$1.doctype && + !$$1('link[href*="favicon-status.ico"]', d$1.head) && + !['4chan - Temporarily Offline', '4chan - Error', '504 Gateway Time-out', 'MathJax Equation Source'].includes(d$1.title); + }, + is404() { + // XXX Sometimes threads don't 404 but are left over as stubs containing one garbage reply post. + return ['4chan - Temporarily Offline', '4chan - 404 Not Found'].includes(d$1.title) || ((g.VIEW === 'thread') && $$1('.board') && !$$1('.opContainer')); + }, + isIncomplete() { + return ['index', 'thread'].includes(g.VIEW) && !$$1('.board + *'); + }, + isBoardlessPage(url) { + return ['www.4chan.org', 'www.4channel.org'].includes(url.hostname); + }, + isAuxiliaryPage(url) { + return !['boards.4chan.org', 'boards.4channel.org'].includes(url.hostname); + }, + isFileURL(url) { + return ImageHost.test(url.hostname); + }, + initAuxiliary() { + switch (location.hostname) { + case 'www.4chan.org': + case 'www.4channel.org': + if (SWYotsuba.regexp.pass.test(location.href)) { + PassMessage.init(); + } + else { + $$1.onExists(doc$1, 'body', () => $$1.addStyle(CSS.www)); + Captcha.replace.init(); + } + return; + case 'sys.4chan.org': + case 'sys.4channel.org': + var pathname = location.pathname.split(/\/+/); + if (pathname[2] === 'imgboard.php') { + let match; + if (/\bmode=report\b/.test(location.search)) { + Report.init(); + } + else if (match = location.search.match(/\bres=(\d+)/)) { + $$1.ready(function () { + if (Conf['404 Redirect'] && ($$1.id('errmsg')?.textContent === 'Error: Specified thread does not exist.')) { + return Redirect$1.navigate('thread', { + boardID: g.BOARD.ID, + postID: +match[1] + }); + } + }); + } + } + else if (pathname[2] === 'post') { + PostSuccessful.init(); + } + return; + } + }, + scriptData() { + for (var script of $$('script:not([src])', d$1.head)) { + if (/\bcooldowns *=/.test(script.textContent)) { + return script.textContent; + } + } + return ''; + }, + parseThreadMetadata(thread) { + let m; + const scriptData = this.scriptData(); + thread.postLimit = /\bbumplimit *= *1\b/.test(scriptData); + thread.fileLimit = /\bimagelimit *= *1\b/.test(scriptData); + thread.ipCount = (m = scriptData.match(/\bunique_ips *= *(\d+)\b/)) ? +m[1] : undefined; + if ((g.BOARD.ID === 'f') && thread.OP.file) { + const { file } = thread.OP; + return $$1.ajax(this.urls.threadJSON({ boardID: 'f', threadID: thread.ID }), { + timeout: MINUTE, + onloadend() { + if (this.response) { + return file.text.dataset.md5 = (file.MD5 = this.response.posts[0].md5); + } + } + }); + } + }, + parseNodes(post, nodes) { + // Add CSS classes to sticky/closed icons on /f/ to match other boards. + if (post.boardID === 'f') { + return (() => { + const result = []; + for (var type of ['Sticky', 'Closed']) { + var icon; + if (icon = $$1(`img[alt=${type}]`, nodes.info)) { + result.push($$1.addClass(icon, `${type.toLowerCase()}Icon`, 'retina')); + } + } + return result; + })(); + } + }, + parseDate(node) { + return new Date(node.dataset.utc * 1000); + }, + parseFile(post, file) { + let info; + const { text, link, thumb } = file; + if (!(info = link.nextSibling?.textContent.match(/\(([\d.]+ [KMG]?B).*\)/))) { + return false; + } + $$1.extend(file, { + name: text.title || link.title || link.textContent, + size: info[1], + dimensions: info[0].match(/\d+x\d+/)?.[0], + tag: info[0].match(/,[^,]*, ([a-z]+)\)/i)?.[1], + MD5: text.dataset.md5 + }); + if (thumb) { + $$1.extend(file, { + thumbURL: thumb.src, + MD5: thumb.dataset.md5, + isSpoiler: $$1.hasClass(thumb.parentNode, 'imgspoiler') + }); + if (file.isSpoiler) { + let m; + file.thumbURL = (m = link.href.match(/\d+(?=\.\w+$)/)) ? `${location.protocol}//${ImageHost.thumbHost()}/${post.board}/${m[0]}s.jpg` : undefined; + } + } + return true; + }, + cleanComment(bq) { + let abbr; + if (abbr = $$1('.abbr', bq)) { // 'Comment too long' or 'EXIF data available' + for (var node of $$('.abbr + br, .exif', bq)) { + $$1.rm(node); + } + for (let i = 0; i < 2; i++) { + var br; + if ((br = abbr.previousSibling) && (br.nodeName === 'BR')) { + $$1.rm(br); + } + } + return $$1.rm(abbr); + } + }, + cleanCommentDisplay(bq) { + let b; + if ((b = $$1('b', bq)) && /^Rolled /.test(b.textContent)) { + $$1.rm(b); + } + return $$1.rm($$1('.fortune', bq)); + }, + insertTags(bq) { + let node; + for (node of $$('s, .removed-spoiler', bq)) { + $$1.replace(node, [$$1.tn('[spoiler]'), ...Array.from(node.childNodes), $$1.tn('[/spoiler]')]); + } + for (node of $$('.prettyprint', bq)) { + $$1.replace(node, [$$1.tn('[code]'), ...Array.from(node.childNodes), $$1.tn('[/code]')]); + } + }, + hasCORS(url) { + return url.split('/').slice(0, 3).join('/') === (location.protocol + '//a.4cdn.org'); + }, + sfwBoards(sfw) { + return BoardConfig.sfwBoards(sfw); + }, + uidColor(uid) { + let msg = 0; + let i = 0; + while (i < 8) { + msg = ((msg << 5) - msg) + uid.charCodeAt(i++); + } + return (msg >> 8) & 0xFFFFFF; + }, + isLinkified(link) { + return ImageHost.test(link.hostname); + }, + testNativeExtension() { + return $$1.global(function () { + if (window.Parser?.postMenuIcon) { + return this.enabled = 'true'; + } + }); + }, + transformBoardList() { + let node; + const nodes = []; + const spacer = () => $$1.el('span', { className: 'spacer' }); + const items = $$1.X('.//a|.//text()[not(ancestor::a)]', $$1(SWYotsuba.selectors.boardList)); + let i = 0; + while ((node = items.snapshotItem(i++))) { + switch (node.nodeName) { + case '#text': + for (var chr of node.nodeValue) { + var span = $$1.el('span', { textContent: chr }); + if (chr === ' ') { + span.className = 'space'; + } + if (chr === ']') { + nodes.push(spacer()); + } + nodes.push(span); + if (chr === '[') { + nodes.push(spacer()); + } + } + break; + case 'A': + var a = node.cloneNode(true); + nodes.push(a); + break; + } + } + return nodes; + }, + Build: { + staticPath: '//s.4cdn.org/image/', + gifIcon: window.devicePixelRatio >= 2 ? '@2x.gif' : '.gif', + spoilerRange: Object.create(null), + shortFilename(filename) { + const ext = filename.match(/\.?[^\.]*$/)[0]; + if ((filename.length - ext.length) > 30) { + return `${filename.match(/(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[^]){0,25}/)[0]}(...)${ext}`; + } + else { + return filename; + } + }, + spoilerThumb(boardID) { + let spoilerRange; + if ((spoilerRange = this.spoilerRange[boardID])) { + // Randomize the spoiler image. + return `${this.staticPath}spoiler-${boardID}${Math.floor(1 + (spoilerRange * Math.random()))}.png`; + } + else { + return `${this.staticPath}spoiler.png`; + } + }, + sameThread(boardID, threadID) { + return (g.VIEW === 'thread') && (g.BOARD.ID === boardID) && (g.THREADID === +threadID); + }, + threadURL(boardID, threadID) { + if (boardID !== g.BOARD.ID) { + return `//${BoardConfig.domain(boardID)}/${boardID}/thread/${threadID}`; + } + else if ((g.VIEW !== 'thread') || (+threadID !== g.THREADID)) { + return `/${boardID}/thread/${threadID}`; + } + else { + return ''; + } + }, + postURL(boardID, threadID, postID) { + return `${this.threadURL(boardID, threadID)}#p${postID}`; + }, + parseJSON(data, { siteID, boardID }) { + const o = { + // id + ID: data.no, + postID: data.no, + threadID: data.resto || data.no, + boardID, + siteID, + isReply: !!data.resto, + // thread status + isSticky: !!data.sticky, + isClosed: !!data.closed, + isArchived: !!data.archived, + // file status + fileDeleted: !!data.filedeleted, + filesDeleted: data.filedeleted ? [0] : [] + }; + o.info = { + subject: $$1.unescape(data.sub), + email: $$1.unescape(data.email), + name: $$1.unescape(data.name) || '', + tripcode: data.trip, + pass: (data.since4pass != null) ? `${data.since4pass}` : undefined, + uniqueID: data.id, + flagCode: data.country, + flagCodeTroll: data.board_flag, + flag: $$1.unescape((data.country_name || data.flag_name)), + dateUTC: data.time, + dateText: data.now, + // Yes, we use the raw string here + commentHTML: { innerHTML: data.com || '', [isEscaped]: true } + }; + if (data.capcode) { + o.info.capcode = data.capcode.replace(/_highlight$/, '').replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase()); + o.capcodeHighlight = /_highlight$/.test(data.capcode); + delete o.info.uniqueID; + } + o.files = []; + if (data.ext) { + o.file = this.parseJSONFile(data, { siteID, boardID }); + o.files.push(o.file); + } + // Temporary JSON properties for events such as April 1 / Halloween + o.extra = dict(); + for (var key in data) { + if (key[0] === 'x') { + o.extra[key] = data[key]; + } + } + return o; + }, + parseJSONFile(data, { siteID, boardID }) { + const site = g.sites[siteID]; + const filename = (site.software === 'yotsuba') && (boardID === 'f') ? + `${encodeURIComponent(data.filename)}${data.ext}` + : + `${data.tim}${data.ext}`; + const o = { + name: ($$1.unescape(data.filename)) + data.ext, + url: site.urls.file({ siteID, boardID }, filename), + height: data.h, + width: data.w, + MD5: data.md5, + size: $$1.bytesToString(data.fsize), + thumbURL: site.urls.thumb({ siteID, boardID }, `${data.tim}s.jpg`), + theight: data.tn_h, + twidth: data.tn_w, + isSpoiler: !!data.spoiler, + tag: data.tag, + hasDownscale: !!data.m_img + }; + if ((data.h != null) && !/\.pdf$/.test(o.url)) { + o.dimensions = `${o.width}x${o.height}`; + } + return o; + }, + parseComment(html) { + html = html + .replace(//gi, '\n') + .replace(/\n\n]*>/g, ''); + return $$1.unescape(html); + }, + parseCommentDisplay(html) { + // Hide spoilers. + if (!Conf['Remove Spoilers'] && !Conf['Reveal Spoilers']) { + let html2; + while ((html2 = html.replace(/(?:(?!<\/?s>).)*<\/s>/g, '[spoiler]')) !== html) { + html = html2; + } + } + html = html + .replace(/^Rolled [^<]*<\/b>/i, '') // Rolls (/tg/, /qst/) + .replace(/>") : ''), + h("div", { id: `p${ID}`, class: `post ${postClass}${o.capcodeHighlight ? ' highlightPost' : ''}` }, + (o.isReply ? h(hFragment, null, + postInfo, + fileBlock) : h(hFragment, null, + fileBlock, + postInfo)), + h("blockquote", { class: "postMessage", id: `m${ID}` }, commentHTML))); + const container = $$1.el('div', { + className: `postContainer ${postClass}Container`, + id: `pc${ID}` + }); + $$1.extend(container, wholePost); + // Fix quotelinks + for (var quote of $$('.quotelink', container)) { + var href = quote.getAttribute('href'); + if (href[0] === '#') { + if (!this.sameThread(boardID, threadID)) { + quote.href = this.threadURL(boardID, threadID) + href; + } + } + else { + var match; + if ((match = quote.href.match(SWYotsuba.regexp.quotelink)) && (this.sameThread(match[1], match[2]))) { + quote.href = href.match(/(#[^#]*)?$/)[0] || '#'; + } + } + } + return container; + }, + summaryText(status, posts, files) { + let text = ''; + if (status) { + text += `${status} `; + } + text += `${posts} post${posts > 1 ? 's' : ''}`; + if (+files) { + text += ` and ${files} image repl${files > 1 ? 'ies' : 'y'}`; + } + return text += ` ${status === '-' ? 'shown' : 'omitted'}.`; + }, + summary(boardID, threadID, posts, files) { + return $$1.el('a', { + className: 'summary', + textContent: this.summaryText('', posts, files), + href: `/${boardID}/thread/${threadID}` + }); + }, + thread(thread, data, withReplies) { + let root; + if (root = thread.nodes.root) { + $$1.rmAll(root); + } + else { + thread.nodes.root = (root = $$1.el('div', { + className: 'thread', + id: `t${data.no}` + })); + } + if (this.hat) { + $$1.add(root, this.hat.cloneNode(false)); + } + $$1.add(root, thread.OP.nodes.root); + if (data.omitted_posts || (!withReplies && data.replies)) { + const [posts, files] = Array.from(withReplies ? + // XXX data.omitted_images is not accurate. + [data.omitted_posts, data.images - data.last_replies.filter(data => !!data.ext).length] + : + [data.replies, data.images]); + const summary = this.summary(thread.board.ID, data.no, posts, files); + $$1.add(root, summary); + } + return root; + }, + catalogThread(thread, data, pageCount) { + let cssText, imgClass, src; + const { staticPath, gifIcon } = this; + const { tn_w, tn_h } = data; + if (data.spoiler && !Conf['Reveal Spoiler Thumbnails']) { + let spoilerRange; + src = `${staticPath}spoiler`; + if (spoilerRange = this.spoilerRange[thread.board]) { + // Randomize the spoiler image. + src += (`-${thread.board}`) + Math.floor(1 + (spoilerRange * Math.random())); + } + src += '.png'; + imgClass = 'spoiler-file'; + cssText = "--tn-w: 100; --tn-h: 100;"; + } + else if (data.filedeleted) { + src = `${staticPath}filedeleted-res${gifIcon}`; + imgClass = 'deleted-file'; + } + else if (thread.OP.file) { + src = thread.OP.file.thumbURL; + const ratio = 250 / Math.max(tn_w, tn_h); + cssText = `--tn-w: ${tn_w * ratio}; --tn-h: ${tn_h * ratio};`; + } + else { + src = `${staticPath}nofile.png`; + imgClass = 'no-file'; + } + const postCount = data.replies + 1; + const fileCount = data.images + !!data.ext; + const container = $$1.el('div', generateCatalogThreadHtml(thread, src, imgClass, data, postCount, fileCount, pageCount, staticPath, gifIcon)); + $$1.before(thread.OP.nodes.info, [...Array.from(container.childNodes)]); + for (var br of $$('br', thread.OP.nodes.comment)) { + if (br.previousSibling && (br.previousSibling.nodeName === 'BR')) { + $$1.addClass(br, 'extra-linebreak'); + } + } + const root = $$1.el('div', { + className: 'thread catalog-thread', + id: `t${thread}` + }); + if (thread.OP.highlights) { + $$1.addClass(root, ...Array.from(thread.OP.highlights)); + } + if (!thread.OP.file) { + $$1.addClass(root, 'noFile'); + } + root.style.cssText = cssText || ''; + return root; + }, + catalogReply(thread, data) { + let excerpt = ''; + if (data.com) { + excerpt = this.parseCommentDisplay(data.com).replace(/>>\d+/g, '').trim().replace(/\n+/g, ' // '); + } + if (data.ext) { + if (!excerpt) { + excerpt = `${$$1.unescape(data.filename)}${data.ext}`; + } + } + if (data.com) { + if (!excerpt) { + excerpt = $$1.unescape(data.com.replace(//gi, ' // ')); + } + } + if (!excerpt) { + excerpt = '\xA0'; + } + if (excerpt.length > 73) { + excerpt = `${excerpt.slice(0, 70)}...`; + } + const link = this.postURL(thread.board.ID, thread.ID, data.no); + return $$1.el('div', { className: 'catalog-reply' }, h(hFragment, null, + h("span", null, + h("time", { "data-utc": data.time * 1000, "data-abbrev": "1" }, "..."), + ": "), + h("a", { class: "catalog-reply-excerpt", href: link }, excerpt), + h("a", { class: "catalog-reply-preview", href: link }, "..."))); + } + } + }; + + const SW = { tinyboard: SWTinyboard, yotsuba: SWYotsuba }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var FileInfo = { + init() { + if (!['index', 'thread', 'archive'].includes(g.VIEW) || !Conf['File Info Formatting']) { + return; + } + return Callbacks.Post.push({ + name: 'File Info Formatting', + cb: this.node + }); + }, + node() { + if (!this.file) { + return; + } + if (this.isClone) { + let a; + for (a of $$('.file-info .download-button', this.file.text)) { + $$1.on(a, 'click', ImageCommon.download); + } + for (a of $$('.file-info .quick-filter-md5', this.file.text)) { + $$1.on(a, 'click', Filter.quickFilterMD5); + } + return; + } + const oldInfo = $$1.el('span', { className: 'fileText-original' }); + $$1.prepend(this.file.link.parentNode, oldInfo); + $$1.add(oldInfo, [this.file.link.previousSibling, this.file.link, this.file.link.nextSibling]); + const info = $$1.el('span', { className: 'file-info' }); + FileInfo.format(Conf['fileInfo'], this, info); + return $$1.prepend(this.file.text, info); + }, + format(formatString, post, outputNode) { + let a; + const output = []; + formatString.replace(/%(.)|[^%]+/g, function (s, c) { + output.push($$1.hasOwn(FileInfo.formatters, c) ? + FileInfo.formatters[c].call(post) + : + { innerHTML: E(s) }); + return ''; + }); + $$1.extend(outputNode, { innerHTML: E.cat(output) }); + for (a of $$('.download-button', outputNode)) { + $$1.on(a, 'click', ImageCommon.download); + } + for (a of $$('.quick-filter-md5', outputNode)) { + $$1.on(a, 'click', Filter.quickFilterMD5); + } + }, + formatters: { + t() { return { innerHTML: E(this.file.url.match(/[^/]*$/)[0]), [isEscaped]: true }; }, + T() { return h("a", { href: this.file.url, target: "_blank" }, FileInfo.formatters.t.call(this)); }, + l() { return h("a", { href: this.file.url, target: "_blank" }, FileInfo.formatters.n.call(this)); }, + L() { return h("a", { href: this.file.url, target: "_blank" }, FileInfo.formatters.N.call(this)); }, + n() { + const fullname = this.file.name; + const shortname = SW.yotsuba.Build.shortFilename(this.file.name, this.isReply); + if (fullname === shortname) { + return { innerHTML: E(fullname), [isEscaped]: true }; + } + else { + return h("span", { class: "fnswitch" }, + h("span", { class: "fntrunc" }, shortname), + h("span", { class: "fnfull" }, fullname)); + } + }, + N() { return { innerHTML: E(this.file.name), [isEscaped]: true }; }, + d() { return h("a", { href: this.file.url, download: this.file.name, class: "download-button" }, "\uD83D\uDCE5\uFE0E"); }, + f() { + return { innerHTML: "", [isEscaped]: true }; + }, + p() { return { innerHTML: ((this.file.isSpoiler) ? "Spoiler, " : ""), [isEscaped]: true }; }, + s() { return { innerHTML: E(this.file.size), [isEscaped]: true }; }, + B() { return { innerHTML: Math.round(this.file.sizeInBytes) + " Bytes", [isEscaped]: true }; }, + K() { return { innerHTML: (Math.round(this.file.sizeInBytes / 1024)) + " KB", [isEscaped]: true }; }, + M() { return { innerHTML: (Math.round(this.file.sizeInBytes / 1048576 * 100) / 100) + " MB", [isEscaped]: true }; }, + r() { return { innerHTML: E(this.file.dimensions || "PDF"), [isEscaped]: true }; }, + g() { return { innerHTML: ((this.file.tag) ? ", " + E(this.file.tag) : ""), [isEscaped]: true }; }, + '%'() { return { innerHTML: "%", [isEscaped]: true }; } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Time = { + init() { + if (!['index', 'thread', 'archive'].includes(g.VIEW) || !Conf['Time Formatting']) { return; } + + return Callbacks.Post.push({ + name: 'Time Formatting', + cb: this.node + }); + }, + + node() { + if (!this.info.date || this.isClone) { return; } + const {textContent} = this.nodes.date; + return this.nodes.date.textContent = textContent.match(/^\s*/)[0] + Time.format(Conf['time'], this.info.date) + textContent.match(/\s*$/)[0]; + }, + + format(formatString, date) { + return formatString.replace(/%(.)/g, function(s, c) { + if ($$1.hasOwn(Time.formatters, c)) { + return Time.formatters[c].call(date); + } else { + return s; + } + }); + }, + + day: [ + 'Sunday', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday' + ], + + month: [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December' + ], + + localeFormat(date, options, defaultValue) { + if (Conf['timeLocale']) { + try { + return Intl.DateTimeFormat(Conf['timeLocale'], options).format(date); + } catch (error) {} + } + return defaultValue; + }, + + localeFormatPart(date, options, part, defaultValue) { + if (Conf['timeLocale']) { + try { + const parts = Intl.DateTimeFormat(Conf['timeLocale'], options).formatToParts(date); + return parts.map(function(x) { if (x.type === part) { return x.value; } else { return ''; } }).join(''); + } catch (error) {} + } + return defaultValue; + }, + + zeroPad(n) { if (n < 10) { return `0${n}`; } else { return n; } }, + + formatters: { + a() { return Time.localeFormat(this, {weekday: 'short'}, Time.day[this.getDay()].slice(0, 3)); }, + A() { return Time.localeFormat(this, {weekday: 'long'}, Time.day[this.getDay()]); }, + b() { return Time.localeFormat(this, {month: 'short'}, Time.month[this.getMonth()].slice(0, 3)); }, + B() { return Time.localeFormat(this, {month: 'long'}, Time.month[this.getMonth()]); }, + d() { return Time.zeroPad(this.getDate()); }, + e() { return this.getDate(); }, + H() { return Time.zeroPad(this.getHours()); }, + I() { return Time.zeroPad((this.getHours() % 12) || 12); }, + k() { return this.getHours(); }, + l() { return (this.getHours() % 12) || 12; }, + m() { return Time.zeroPad(this.getMonth() + 1); }, + M() { return Time.zeroPad(this.getMinutes()); }, + p() { return Time.localeFormatPart(this, {hour: 'numeric', hour12: true}, 'dayperiod', (this.getHours() < 12 ? 'AM' : 'PM')); }, + P() { return Time.formatters.p.call(this).toLowerCase(); }, + S() { return Time.zeroPad(this.getSeconds()); }, + y() { return this.getFullYear().toString().slice(2); }, + Y() { return this.getFullYear(); }, + '%'() { return '%'; } + } + }; + + var Beep = 'UklGRjQDAABXQVZFZm10IBAAAAABAAEAgD4AAIA+AAABAAgAc21wbDwAAABBAAADAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkYXRhzAIAAGMms8em0tleMV4zIpLVo8nhfSlcPR102Ki+5JspVEkdVtKzs+K1NEhUIT7DwKrcy0g6WygsrM2k1NpiLl0zIY/WpMrjgCdbPhxw2Kq+5Z4qUkkdU9K1s+K5NkVTITzBwqnczko3WikrqM+l1NxlLF0zIIvXpsnjgydZPhxs2ay95aIrUEkdUdC3suK8N0NUIjq+xKrcz002WioppdGm091pK1w0IIjYp8jkhydXPxxq2K295aUrTkoeTs65suK+OUFUIzi7xqrb0VA0WSoootKm0t5tKlo1H4TYqMfkiydWQBxm16+85actTEseS8y7seHAPD9TIza5yKra01QyWSson9On0d5wKVk2H4DYqcfkjidUQB1j1rG75KsvSkseScu8seDCPz1TJDW2yara1FYxWSwnm9Sn0N9zKVg2H33ZqsXkkihSQR1g1bK65K0wSEsfR8i+seDEQTxUJTOzy6rY1VowWC0mmNWoz993KVc3H3rYq8TklSlRQh1d1LS647AyR0wgRMbAsN/GRDpTJTKwzKrX1l4vVy4lldWpzt97KVY4IXbUr8LZljVPRCxhw7W3z6ZISkw1VK+4sMWvXEhSPk6buay9sm5JVkZNiLWqtrJ+TldNTnquqbCwilZXU1BwpKirrpNgWFhTaZmnpquZbFlbVmWOpaOonHZcXlljhaGhpZ1+YWBdYn2cn6GdhmdhYGN3lp2enIttY2Jjco+bnJuOdGZlZXCImJqakHpoZ2Zug5WYmZJ/bGlobX6RlpeSg3BqaW16jZSVkoZ0bGtteImSk5KIeG5tbnaFkJKRinxxbm91gY2QkIt/c3BwdH6Kj4+LgnZxcXR8iI2OjIR5c3J0e4WLjYuFe3VzdHmCioyLhn52dHR5gIiKioeAeHV1eH+GiYqHgXp2dnh9hIiJh4J8eHd4fIKHiIeDfXl4eHyBhoeHhH96eHmA'; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS104: Avoid inline assignments + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var ReplyPruning = { + init() { + if ((g.VIEW !== 'thread') || !Conf['Reply Pruning']) { return; } + + this.container = $$1.frag(); + + this.summary = $$1.el('span', { + hidden: true, + className: 'summary' + } + ); + this.summary.style.cursor = 'pointer'; + $$1.on(this.summary, 'click', () => { + this.inputs.enabled.checked = !this.inputs.enabled.checked; + return $$1.event('change', null, this.inputs.enabled); + }); + + const label = UI.checkbox('Prune Replies', 'Show Last', Conf['Prune All Threads']); + const el = $$1.el('span', + {title: 'Maximum number of replies to show.'} + , + {innerHTML: " "}); + $$1.prepend(el, label); + + this.inputs = { + enabled: label.firstElementChild, + replies: el.lastElementChild + }; + + this.setEnabled.call(this.inputs.enabled); + $$1.on(this.inputs.enabled, 'change', this.setEnabled); + $$1.on(this.inputs.replies, 'change', $$1.cb.value); + + Header$1.menu.addEntry({ + el, + order: 190 + }); + + return Callbacks.Thread.push({ + name: 'Reply Pruning', + cb: this.node + }); + }, + + position: 0, + hidden: 0, + hiddenFiles: 0, + total: 0, + totalFiles: 0, + + setEnabled() { + const other = QuoteThreading.input; + if (this.checked && other?.checked) { + other.checked = false; + $$1.event('change', null, other); + } + return ReplyPruning.active = this.checked; + }, + + showIfHidden(id) { + if (ReplyPruning.container && $$1(`#${id}`, ReplyPruning.container)) { + ReplyPruning.inputs.enabled.checked = false; + return $$1.event('change', null, ReplyPruning.inputs.enabled); + } + }, + + node() { + let middle; + ReplyPruning.thread = this; + + if (this.isSticky) { + ReplyPruning.active = (ReplyPruning.inputs.enabled.checked = true); + if (QuoteThreading.input) { + // Disable Quote Threading for this thread but don't save the setting. + Conf['Thread Quotes'] = (QuoteThreading.input.checked = false); + } + } + + this.posts.forEach(function(post) { + if (post.isReply) { + ReplyPruning.total++; + if (post.file) { return ReplyPruning.totalFiles++; } + } + }); + + // If we're linked to a post that we would hide, don't hide the posts in the first place. + if ( + ReplyPruning.active && + /^#p\d+$/.test(location.hash) && + (1 <= (middle = this.posts.keys.indexOf(location.hash.slice(2))) && middle < 1 + Math.max(ReplyPruning.total - +Conf["Max Replies"], 0)) + ) { + ReplyPruning.active = (ReplyPruning.inputs.enabled.checked = false); + } + + $$1.after(this.OP.nodes.root, ReplyPruning.summary); + + $$1.on(ReplyPruning.inputs.enabled, 'change', ReplyPruning.update); + $$1.on(ReplyPruning.inputs.replies, 'change', ReplyPruning.update); + $$1.on(d$1, 'ThreadUpdate', ReplyPruning.updateCount); + $$1.on(d$1, 'ThreadUpdate', ReplyPruning.update); + + return ReplyPruning.update(); + }, + + updateCount(e) { + if (e.detail[404]) { return; } + for (var fullID of e.detail.newPosts) { + ReplyPruning.total++; + if (g.posts.get(fullID).file) { ReplyPruning.totalFiles++; } + } + }, + + update() { + let boardTop, node, post; + const hidden1 = ReplyPruning.hidden; + const hidden2 = ReplyPruning.active ? + Math.max(ReplyPruning.total - +Conf["Max Replies"], 0) + : + 0; + + // Record position from bottom of document + const oldPos = d$1.body.clientHeight - window.scrollY; + + const {posts} = ReplyPruning.thread; + + if (ReplyPruning.hidden < hidden2) { + while ((ReplyPruning.hidden < hidden2) && (ReplyPruning.position < posts.keys.length)) { + post = posts.get(posts.keys[ReplyPruning.position++]); + if (post.isReply && !post.isFetchedQuote) { + while ((node = ReplyPruning.summary.nextSibling) && (node !== post.nodes.root)) { $$1.add(ReplyPruning.container, node); } + $$1.add(ReplyPruning.container, post.nodes.root); + ReplyPruning.hidden++; + if (post.file) { ReplyPruning.hiddenFiles++; } + } + } + + } else if (ReplyPruning.hidden > hidden2) { + const frag = $$1.frag(); + while ((ReplyPruning.hidden > hidden2) && (ReplyPruning.position > 0)) { + post = posts.get(posts.keys[--ReplyPruning.position]); + if (post.isReply && !post.isFetchedQuote) { + while ((node = ReplyPruning.container.lastChild) && (node !== post.nodes.root)) { $$1.prepend(frag, node); } + $$1.prepend(frag, post.nodes.root); + ReplyPruning.hidden--; + if (post.file) { ReplyPruning.hiddenFiles--; } + } + } + $$1.after(ReplyPruning.summary, frag); + $$1.event('PostsInserted', null, ReplyPruning.summary.parentNode); + } + + ReplyPruning.summary.textContent = ReplyPruning.active ? + g.SITE.Build.summaryText('+', ReplyPruning.hidden, ReplyPruning.hiddenFiles) + : + g.SITE.Build.summaryText('-', ReplyPruning.total, ReplyPruning.totalFiles); + ReplyPruning.summary.hidden = (ReplyPruning.total <= +Conf["Max Replies"]); + + // Maintain position in thread when posts are added/removed above + if ((hidden1 !== hidden2) && ((boardTop = Header$1.getTopOf($$1('.board'))) < 0)) { + return window.scrollBy(0, Math.max(d$1.body.clientHeight - oldPos, window.scrollY + boardTop) - window.scrollY); + } + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + /* + <3 aeosynth + */ + + var QuoteThreading = { + init() { + if (!Conf['Quote Threading'] || (g.VIEW !== 'thread')) { return; } + + this.controls = $$1.el('label', + {innerHTML: " Threading"}); + + this.threadNewLink = $$1.el('span', { + className: 'brackets-wrap threadnewlink', + hidden: true + } + ); + $$1.extend(this.threadNewLink, {innerHTML: "Thread New Posts"}); + + this.input = $$1('input', this.controls); + this.input.checked = Conf['Thread Quotes']; + + $$1.on(this.input, 'change', this.setEnabled); + $$1.on(this.input, 'change', this.rethread); + $$1.on(this.threadNewLink.firstElementChild, 'click', this.rethread); + $$1.on(d$1, '4chanXInitFinished', () => { return this.ready = true; }); + + Header$1.menu.addEntry(this.entry = { + el: this.controls, + order: 99 + } + ); + + Callbacks.Thread.push({ + name: 'Quote Threading', + cb: this.setThread + }); + + return Callbacks.Post.push({ + name: 'Quote Threading', + cb: this.node + }); + }, + + parent: dict(), + children: dict(), + inserted: dict(), + + toggleThreading() { + return this.setThreadingState(!Conf['Thread Quotes']); + }, + + setThreadingState(enabled) { + this.input.checked = enabled; + this.setEnabled.call(this.input); + return this.rethread.call(this.input); + }, + + setEnabled() { + if (this.checked) { + $$1.set('Prune All Threads', false); + const other = ReplyPruning.inputs?.enabled; + if (other?.checked) { + other.checked = false; + $$1.event('change', null, other); + } + } + return $$1.cb.checked.call(this); + }, + + setThread() { + QuoteThreading.thread = this; + return $$1.asap((() => !Conf['Thread Updater'] || $$1('.navLinksBot > .updatelink')), function() { + let navLinksBot; + if (navLinksBot = $$1('.navLinksBot')) { return $$1.add(navLinksBot, [$$1.tn(' '), QuoteThreading.threadNewLink]); } + }); + }, + + node() { + let parent; + if (this.isFetchedQuote || this.isClone || !this.isReply) { return; } + + const parents = new Set(); + let lastParent = null; + for (var quote of this.quotes) { + if ((parent = g.posts.get(quote))) { + if (!parent.isFetchedQuote && parent.isReply && (parent.ID < this.ID)) { + parents.add(parent.ID); + if (!lastParent || (parent.ID > lastParent.ID)) { lastParent = parent; } + } + } + } + + if (!lastParent) { return; } + + let ancestor = lastParent; + while ((ancestor = QuoteThreading.parent[ancestor.fullID])) { + parents.delete(ancestor.ID); + } + + if (parents.size === 1) { + return QuoteThreading.parent[this.fullID] = lastParent; + } + }, + + descendants(post) { + let children; + let posts = [post]; + if (children = QuoteThreading.children[post.fullID]) { + for (var child of children) { + posts = posts.concat(QuoteThreading.descendants(child)); + } + } + return posts; + }, + + insert(post) { + let parent, x; + if (!( + Conf['Thread Quotes'] && + (parent = QuoteThreading.parent[post.fullID]) && + !QuoteThreading.inserted[post.fullID] + )) { return false; } + + const descendants = QuoteThreading.descendants(post); + if (!Unread.posts.has(parent.ID)) { + if ((function() { for (var x of descendants) { if (Unread.posts.has(x.ID)) { return true; } } })()) { + QuoteThreading.threadNewLink.hidden = false; + return false; + } + } + + const {order} = Unread; + const children = (QuoteThreading.children[parent.fullID] || (QuoteThreading.children[parent.fullID] = [])); + const threadContainer = parent.nodes.threadContainer || $$1.el('div', {className: 'threadContainer'}); + const nodes = [post.nodes.root]; + if (post.nodes.threadContainer) { nodes.push(post.nodes.threadContainer); } + + let i = children.length; + for (let j = children.length - 1; j >= 0; j--) { var child = children[j]; if (child.ID >= post.ID) { i--; } } + if (i !== children.length) { + const next = children[i]; + for (x of descendants) { order.before(order[next.ID], order[x.ID]); } + children.splice(i, 0, post); + $$1.before(next.nodes.root, nodes); + } else { + let prev2; + let prev = parent; + while ((prev2 = QuoteThreading.children[prev.fullID]) && prev2.length) { + prev = prev2[prev2.length-1]; + } + for (let k = descendants.length - 1; k >= 0; k--) { x = descendants[k]; order.after(order[prev.ID], order[x.ID]); } + children.push(post); + $$1.add(threadContainer, nodes); + } + + QuoteThreading.inserted[post.fullID] = true; + + if (!parent.nodes.threadContainer) { + parent.nodes.threadContainer = threadContainer; + $$1.addClass(parent.nodes.root, 'threadOP'); + $$1.after(parent.nodes.root, threadContainer); + } + + return true; + }, + + rethread() { + if (!QuoteThreading.ready) { return; } + const {thread} = QuoteThreading; + const {posts} = thread; + + QuoteThreading.threadNewLink.hidden = true; + + if (Conf['Thread Quotes']) { + posts.forEach(QuoteThreading.insert); + } else { + const nodes = []; + Unread.order = new RandomAccessList(); + QuoteThreading.inserted = dict(); + posts.forEach(function(post) { + if (post.isFetchedQuote) { return; } + Unread.order.push(post); + if (post.isReply) { nodes.push(post.nodes.root); } + if (QuoteThreading.children[post.fullID]) { + delete QuoteThreading.children[post.fullID]; + $$1.rmClass(post.nodes.root, 'threadOP'); + $$1.rm(post.nodes.threadContainer); + return delete post.nodes.threadContainer; + } + }); + $$1.add(thread.nodes.root, nodes); + } + + Unread.position = Unread.order.first; + Unread.updatePosition(); + Unread.setLine(true); + Unread.read(); + return Unread.update(); + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS201: Simplify complex destructure assignments + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var ThreadUpdater = { + init() { + let el, name, sc; + if ((g.VIEW !== 'thread') || !Conf['Thread Updater']) { return; } + this.enabled = true; + + // Chromium won't play audio created in an inactive tab until the tab has been focused, so set it up now. + // XXX Sometimes the loading stalls in Firefox, esp. when opening in private browsing window followed by normal window. + // Don't let it keep the loading icon on indefinitely. + this.audio = $$1.el('audio'); + if ($$1.engine !== 'gecko') { this.audio.src = this.beep; } + + if (Conf['Updater and Stats in Header']) { + this.dialog = (sc = $$1.el('span', + {id: 'updater'})); + $$1.extend(sc, {innerHTML: ''}); + Header$1.addShortcut('updater', sc, 100); + } else { + this.dialog = (sc = UI.dialog('updater', + {innerHTML: '
            '})); + $$1.addClass(doc$1, 'float'); + $$1.ready(() => $$1.add(d$1.body, sc)); + } + + this.checkPostCount = 0; + + this.timer = $$1('#update-timer', sc); + this.status = $$1('#update-status', sc); + + $$1.on(this.timer, 'click', this.update); + $$1.on(this.status, 'click', this.update); + + const updateLink = $$1.el('span', + {className: 'brackets-wrap updatelink'}); + $$1.extend(updateLink, {innerHTML: 'Update'}); + Main$1.ready(function() { + let navLinksBot; + if (navLinksBot = $$1('.navLinksBot')) { return $$1.add(navLinksBot, [$$1.tn(' '), updateLink]); } + }); + $$1.on(updateLink.firstElementChild, 'click', this.update); + + const subEntries = []; + for (name in Config.updater.checkbox) { + var conf = Config.updater.checkbox[name]; + el = UI.checkbox(name, name); + el.title = conf[1]; + var input = el.firstElementChild; + $$1.on(input, 'change', $$1.cb.checked); + if (input.name === 'Scroll BG') { + $$1.on(input, 'change', this.cb.scrollBG); + this.cb.scrollBG(); + } else if (input.name === 'Auto Update') { + $$1.on(input, 'change', this.setInterval); + } + subEntries.push({el}); + } + + this.settings = $$1.el('span', + {innerHTML: 'Interval'}); + + $$1.on(this.settings, 'click', this.intervalShortcut); + + subEntries.push({el: this.settings}); + + Header$1.menu.addEntry(this.entry = { + el: $$1.el('span', + {textContent: 'Updater'}), + order: 110, + subEntries + } + ); + + return Callbacks.Thread.push({ + name: 'Thread Updater', + cb: this.node + }); + }, + + node() { + ThreadUpdater.thread = this; + ThreadUpdater.root = this.nodes.root; + ThreadUpdater.outdateCount = 0; + + // We must keep track of our own list of live posts/files + // to provide an accurate deletedPosts/deletedFiles on update + // as posts may be `kill`ed elsewhere. + ThreadUpdater.postIDs = []; + ThreadUpdater.fileIDs = []; + this.posts.forEach(function(post) { + ThreadUpdater.postIDs.push(post.ID); + if (post.file) { return ThreadUpdater.fileIDs.push(post.ID); } + }); + + ThreadUpdater.cb.interval.call($$1.el('input', {value: Conf['Interval']})); + + $$1.on(d$1, 'QRPostSuccessful', ThreadUpdater.cb.checkpost); + $$1.on(d$1, 'visibilitychange', ThreadUpdater.cb.visibility); + + return ThreadUpdater.setInterval(); + }, + + /* + http://freesound.org/people/pierrecartoons1979/sounds/90112/ + cc-by-nc-3.0 + */ + beep: `data:audio/wav;base64,${Beep}`, + + playBeep() { + const {audio} = ThreadUpdater; + if (!audio.src) { audio.src = ThreadUpdater.beep; } + if (audio.paused) { + return audio.play(); + } else { + return $$1.one(audio, 'ended', ThreadUpdater.playBeep); + } + }, + + cb: { + checkpost(e) { + if (e.detail.threadID !== ThreadUpdater.thread.ID) { return; } + ThreadUpdater.postID = e.detail.postID; + ThreadUpdater.checkPostCount = 0; + ThreadUpdater.outdateCount = 0; + return ThreadUpdater.setInterval(); + }, + + visibility() { + if (d$1.hidden) { return; } + // Reset the counter when we focus this tab. + ThreadUpdater.outdateCount = 0; + if (ThreadUpdater.seconds > ThreadUpdater.interval) { + return ThreadUpdater.setInterval(); + } + }, + + scrollBG() { + return ThreadUpdater.scrollBG = Conf['Scroll BG'] ? + () => true + : + () => !d$1.hidden; + }, + + interval(e) { + let val = parseInt(this.value, 10); + if (val < 1) { val = 1; } + ThreadUpdater.interval = (this.value = val); + if (e) { return $$1.cb.value.call(this); } + }, + + load() { + if (this !== ThreadUpdater.req) { return; } // aborted + switch (this.status) { + case 200: + ThreadUpdater.parse(this); + if (ThreadUpdater.thread.isArchived) { + return ThreadUpdater.kill(); + } else { + return ThreadUpdater.setInterval(); + } + case 404: + // XXX workaround for 4chan sending false 404s + return $$1.ajax(g.SITE.urls.catalogJSON({boardID: ThreadUpdater.thread.board.ID}), { onloadend() { + let confirmed; + if (this.status === 200) { + confirmed = true; + for (var page of this.response) { + for (var thread of page.threads) { + if (thread.no === ThreadUpdater.thread.ID) { + confirmed = false; + break; + } + } + } + } else { + confirmed = false; + } + if (confirmed) { + return ThreadUpdater.kill(); + } else { + return ThreadUpdater.error(this); + } + } + } + ); + default: + return ThreadUpdater.error(this); + } + } + }, + + kill() { + ThreadUpdater.thread.kill(); + ThreadUpdater.setInterval(); + return $$1.event('ThreadUpdate', { + 404: true, + threadID: ThreadUpdater.thread.fullID + } + ); + }, + + error(req) { + if (req.status === 304) { + ThreadUpdater.set('status', ''); + } + ThreadUpdater.setInterval(); + if (!req.status) { + return ThreadUpdater.set('status', 'Connection Error', 'warning'); + } else if (req.status !== 304) { + return ThreadUpdater.set('status', `${req.statusText} (${req.status})`, 'warning'); + } + }, + + setInterval() { + clearTimeout(ThreadUpdater.timeoutID); + + if (ThreadUpdater.thread.isDead) { + ThreadUpdater.set('status', (ThreadUpdater.thread.isArchived ? 'Archived' : '404'), 'warning'); + ThreadUpdater.set('timer', ''); + return; + } + + // Fetching your own posts after posting + if (ThreadUpdater.postID && (ThreadUpdater.checkPostCount < 5)) { + ThreadUpdater.set('timer', '...', 'loading'); + ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * SECOND); + return; + } + + if (!Conf['Auto Update']) { + ThreadUpdater.set('timer', 'Update'); + return; + } + + const {interval} = ThreadUpdater; + if (Conf['Optional Increase']) { + // Lower the max refresh rate limit on visible tabs. + const limit = d$1.hidden ? 10 : 5; + const j = Math.min(ThreadUpdater.outdateCount, limit); + + // 1 second to 100, 30 to 300. + const cur = (Math.floor(interval * 0.1) || 1) * j * j; + ThreadUpdater.seconds = $$1.minmax(cur, interval, 300); + } else { + ThreadUpdater.seconds = interval; + } + + return ThreadUpdater.timeout(); + }, + + intervalShortcut() { + Settings.open('Advanced'); + const settings = $$1.id('fourchanx-settings'); + return $$1('input[name=Interval]', settings).focus(); + }, + + set(name, text, klass) { + let node; + const el = ThreadUpdater[name]; + if ((node = el.firstChild)) { + // Prevent the creation of a new DOM Node + // by setting the text node's data. + node.data = text; + } else { + el.textContent = text; + } + return el.className = klass ?? (text === '' ? 'empty' : ''); + }, + + timeout() { + if (ThreadUpdater.seconds) { + ThreadUpdater.set('timer', ThreadUpdater.seconds); + ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000); + } else { + ThreadUpdater.outdateCount++; + ThreadUpdater.update(); + } + return ThreadUpdater.seconds--; + }, + + update() { + let oldReq; + clearTimeout(ThreadUpdater.timeoutID); + ThreadUpdater.set('timer', '...', 'loading'); + if (oldReq = ThreadUpdater.req) { + delete ThreadUpdater.req; + oldReq.abort(); + } + return ThreadUpdater.req = $$1.whenModified( + g.SITE.urls.threadJSON({boardID: ThreadUpdater.thread.board.ID, threadID: ThreadUpdater.thread.ID}), + 'ThreadUpdater', + ThreadUpdater.cb.load, + { timeout: MINUTE } + ); + }, + + updateThreadStatus(type, status) { + if (!(ThreadUpdater.thread[`is${type}`] !== status)) { return; } + ThreadUpdater.thread.setStatus(type, status); + if ((type === 'Closed') && ThreadUpdater.thread.isArchived) { return; } + const change = type === 'Sticky' ? + status ? + 'now a sticky' + : + 'not a sticky anymore' + : + status ? + 'now closed' + : + 'not closed anymore'; + return new Notice('info', `The thread is ${change}.`, 30); + }, + + parse(req) { + let ID, ipCountEl, post; + const postObjects = req.response.posts; + const OP = postObjects[0]; + const {thread} = ThreadUpdater; + const {board} = thread; + const lastPost = ThreadUpdater.postIDs[ThreadUpdater.postIDs.length - 1]; + + // XXX Reject updates that falsely delete the last post. + if ((postObjects[postObjects.length-1].no < lastPost) && + ((new Date(req.getResponseHeader('Last-Modified')) - thread.posts.get(lastPost).info.date) < (30 * SECOND))) { return; } + + g.SITE.Build.spoilerRange[board] = OP.custom_spoiler; + thread.setStatus('Archived', !!OP.archived); + ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky); + ThreadUpdater.updateThreadStatus('Closed', !!OP.closed); + thread.postLimit = !!OP.bumplimit; + thread.fileLimit = !!OP.imagelimit; + if (OP.unique_ips != null) { thread.ipCount = OP.unique_ips; } + + const posts = []; // new post objects + const index = []; // existing posts + const files = []; // existing files + const newPosts = []; // new post fullID list for API + + // Build the index, create posts. + for (var postObject of postObjects) { + ID = postObject.no; + index.push(ID); + if (postObject.fsize) { files.push(ID); } + + // Insert new posts, not older ones. + if (ID <= lastPost) { continue; } + + // XXX Resurrect wrongly deleted posts. + if ((post = thread.posts.get(ID)) && !post.isFetchedQuote) { + post.resurrect(); + continue; + } + + newPosts.push(`${board}.${ID}`); + var node = g.SITE.Build.postFromObject(postObject, board.ID); + posts.push(new Post(node, thread, board)); + // Fetching your own posts after posting + if (ThreadUpdater.postID === ID) { delete ThreadUpdater.postID; } + } + + // Check for deleted posts. + const deletedPosts = []; + for (ID of ThreadUpdater.postIDs) { + if (!index.includes(ID)) { + thread.posts.get(ID).kill(); + deletedPosts.push(`${board}.${ID}`); + } + } + ThreadUpdater.postIDs = index; + + // Check for deleted files. + const deletedFiles = []; + for (ID of ThreadUpdater.fileIDs) { + if (!(files.includes(ID) || deletedPosts.includes(`${board}.${ID}`))) { + thread.posts.get(ID).kill(true); + deletedFiles.push(`${board}.${ID}`); + } + } + ThreadUpdater.fileIDs = files; + + if (!posts.length) { + ThreadUpdater.set('status', ''); + } else { + ThreadUpdater.set('status', `+${posts.length}`, 'new'); + ThreadUpdater.outdateCount = 0; + + const unreadCount = Unread.posts?.size; + const unreadQYCount = Unread.postsQuotingYou?.size; + + Main$1.callbackNodes('Post', posts); + + if (d$1.hidden || !d$1.hasFocus()) { + if (Conf['Beep Quoting You'] && (Unread.postsQuotingYou?.size > unreadQYCount)) { + ThreadUpdater.playBeep(); + if (Conf['Beep']) { ThreadUpdater.playBeep(); } + } else if (Conf['Beep'] && (Unread.posts?.size > 0) && (unreadCount === 0)) { + ThreadUpdater.playBeep(); + } + } + + const scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && + ((ThreadUpdater.root.getBoundingClientRect().bottom - doc$1.clientHeight) < 25); + + let firstPost = null; + for (post of posts) { + if (!QuoteThreading.insert(post)) { + if (!firstPost) { firstPost = post.nodes.root; } + $$1.add(ThreadUpdater.root, post.nodes.root); + } + } + $$1.event('PostsInserted', null, ThreadUpdater.root); + + if (scroll) { + if (Conf['Bottom Scroll']) { + window.scrollTo(0, d$1.body.clientHeight); + } else { + if (firstPost) { Header$1.scrollTo(firstPost); } + } + } + } + + // Update IP count in original post form. + if ((OP.unique_ips != null) && (ipCountEl = $$1.id('unique-ips'))) { + ipCountEl.textContent = OP.unique_ips; + ipCountEl.previousSibling.textContent = ipCountEl.previousSibling.textContent.replace(/\b(?:is|are)\b/, OP.unique_ips === 1 ? 'is' : 'are'); + ipCountEl.nextSibling.textContent = ipCountEl.nextSibling.textContent.replace(/\bposters?\b/, OP.unique_ips === 1 ? 'poster' : 'posters'); + } + + return $$1.event('ThreadUpdate', { + 404: false, + threadID: thread.fullID, + newPosts, + deletedPosts, + deletedFiles, + postCount: OP.replies + 1, + fileCount: OP.images + !!OP.fsize, + ipCount: OP.unique_ips + } + ); + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Settings = { + dialog: undefined, + init() { + // 4chan X settings link + const link = $$1.el('a', { + className: 'settings-link', + textContent: '🔧︎', + title: `${meta.name} Settings`, + href: 'javascript:;' + }); + $$1.on(link, 'click', Settings.open); + Header$1.addShortcut('settings', link, 820); + const add = this.addSection; + add('Main', this.main); + add('Filter', this.filter); + add('Sauce', this.sauce); + add('Advanced', this.advanced); + add('Keybinds', this.keybinds); + $$1.on(d$1, 'AddSettingsSection', Settings.addSection); + $$1.on(d$1, 'OpenSettings', e => Settings.open(e.detail)); + if ((g.SITE.software === 'yotsuba') && Conf['Disable Native Extension']) { + if ($$1.hasStorage) { + // Run in page context to handle case where 4chan X has localStorage access but not the page. + // (e.g. Pale Moon 26.2.2, GM 3.8, cookies disabled for 4chan only) + return $$1.global(function () { + try { + const settings = JSON.parse(localStorage.getItem('4chan-settings')) || {}; + if (settings.disableAll) { + return; + } + settings.disableAll = true; + return localStorage.setItem('4chan-settings', JSON.stringify(settings)); + } + catch (error) { + return Object.defineProperty(window, 'Config', { value: { disableAll: true } }); + } + }); + } + else { + return $$1.global(() => Object.defineProperty(window, 'Config', { value: { disableAll: true } })); + } + } + }, + open(openSection) { + let dialog, sectionToOpen; + if (Settings.dialog) { + return; + } + $$1.event('CloseMenu'); + Settings.dialog = (dialog = $$1.el('div', { id: 'overlay' }, settingsHtml)); + $$1.on($$1('.export', dialog), 'click', Settings.export); + $$1.on($$1('.import', dialog), 'click', Settings.import); + $$1.on($$1('.reset', dialog), 'click', Settings.reset); + $$1.on($$1('input', dialog), 'change', Settings.onImport); + const links = []; + for (var section of Settings.sections) { + var link = $$1.el('a', { + className: `tab-${section.hyphenatedTitle}`, + textContent: section.title, + href: 'javascript:;' + }); + $$1.on(link, 'click', Settings.openSection.bind(section)); + links.push(link, $$1.tn(' | ')); + if (section.title === openSection) { + sectionToOpen = link; + } + } + links.pop(); + $$1.add($$1('.sections-list', dialog), links); + if (openSection !== 'none') { + (sectionToOpen ? sectionToOpen : links[0]).click(); + } + $$1.on($$1('.close', dialog), 'click', Settings.close); + $$1.on(window, 'beforeunload', Settings.close); + $$1.on(dialog, 'click', Settings.close); + $$1.on(dialog.firstElementChild, 'click', e => e.stopPropagation()); + $$1.add(d$1.body, dialog); + return $$1.event('OpenSettings', null, dialog); + }, + close() { + if (!Settings.dialog) { + return; + } + // Unfocus current field to trigger change event. + d$1.activeElement?.blur(); + $$1.rm(Settings.dialog); + return delete Settings.dialog; + }, + sections: [], + addSection(title, open) { + if (typeof title !== 'string') { + ({ title, open } = title.detail); + } + const hyphenatedTitle = title.toLowerCase().replace(/\s+/g, '-'); + return Settings.sections.push({ title, hyphenatedTitle, open }); + }, + openSection() { + let selected; + if (selected = $$1('.tab-selected', Settings.dialog)) { + $$1.rmClass(selected, 'tab-selected'); + } + $$1.addClass($$1(`.tab-${this.hyphenatedTitle}`, Settings.dialog), 'tab-selected'); + const section = $$1('section', Settings.dialog); + $$1.rmAll(section); + section.className = `section-${this.hyphenatedTitle}`; + this.open(section, g); + section.scrollTop = 0; + return $$1.event('OpenSettings', null, section); + }, + warnings: { + localStorage(cb) { + if ($$1.cantSync) { + const why = $$1.cantSet ? 'save your settings' : 'synchronize settings between tabs'; + return cb($$1.el('li', { + textContent: `\ +${meta.name} needs local storage to ${why}. +Enable 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(cb) { + return $$1.onExists(doc$1, '.adg-rects > .desktop', ad => $$1.onExists(ad, 'iframe', function () { + const url = Redirect$1.to('thread', { boardID: 'qa', threadID: 362590 }); + return cb($$1.el('li', h(hFragment, null, + "To protect yourself from ", + h("a", { href: url, target: "_blank" }, "malicious ads"), + ", you should ", + h("a", { href: "https://github.com/gorhill/uBlock#ublock-origin", target: "_blank" }, "block ads"), + " on 4chan."))); + })); + } + }, + main(section) { + let key; + const warnings = $$1.el('fieldset', { hidden: true }, { innerHTML: 'Warnings
              ' }); + const addWarning = function (item) { + $$1.add($$1('ul', warnings), item); + return warnings.hidden = false; + }; + for (key in Settings.warnings) { + var warning = Settings.warnings[key]; + warning(addWarning); + } + $$1.add(section, warnings); + const items = dict(); + const inputs = dict(); + const addCheckboxes = function (root, obj) { + const containers = [root]; + return (() => { + const result = []; + for (key in obj) { + var arr = obj[key]; + if (arr instanceof Array) { + var description = arr[1]; + var div = $$1.el('div', { innerHTML: `: ${description}` }); + div.dataset.name = key; + var input = $$1('input', div); + $$1.on(input, 'change', $$1.cb.checked); + $$1.on(input, 'change', function () { return this.parentNode.parentNode.dataset.checked = this.checked; }); + items[key] = Conf[key]; + inputs[key] = input; + var level = arr[2] || 0; + if (containers.length <= level) { + var container = $$1.el('div', { className: 'suboption-list' }); + $$1.add(containers[containers.length - 1].lastElementChild, container); + containers[level] = container; + } + else if (containers.length > (level + 1)) { + containers.splice(level + 1, containers.length - (level + 1)); + } + result.push($$1.add(containers[level], div)); + } + } + return result; + })(); + }; + for (var keyFS in Config.main) { + var obj = Config.main[keyFS]; + var fs = $$1.el('fieldset', { innerHTML: `${keyFS}` }); + addCheckboxes(fs, obj); + if (keyFS === 'Posting and Captchas') { + $$1.add(fs, $$1.el('p', { innerHTML: 'For more info on captcha options and issues, see the captcha FAQ.' })); + } + $$1.add(section, fs); + } + addCheckboxes($$1('div[data-name="JSON Index"] > .suboption-list', section), Config.Index); + // Unsupported options + if ($$1.engine !== 'gecko') { + $$1('div[data-name="Remember QR Size"]', section).hidden = true; + } + if ($$1.perProtocolSettings || (location.protocol !== 'https:')) { + $$1('div[data-name="Redirect to HTTPS"]', section).hidden = true; + } + if (platform !== 'crx') { + $$1('div[data-name="Work around CORB Bug"]', section).hidden = true; + } + $$1.get(items, function (items) { + for (key in items) { + var val = items[key]; + inputs[key].checked = val; + inputs[key].parentNode.parentNode.dataset.checked = val; + } + }); + const div = $$1.el('div', { innerHTML: ': Clear manually-hidden threads and posts on all boards. Reload the page to apply.' }); + const button = $$1('button', div); + $$1.get({ hiddenThreads: dict(), hiddenPosts: dict() }, function ({ hiddenThreads, hiddenPosts }) { + let board, ID, site, thread; + let hiddenNum = 0; + for (ID in hiddenThreads) { + site = hiddenThreads[ID]; + if (ID !== 'boards') { + for (ID in site.boards) { + board = site.boards[ID]; + hiddenNum += Object.keys(board).length; + } + } + } + for (ID in hiddenThreads.boards) { + board = hiddenThreads.boards[ID]; + hiddenNum += Object.keys(board).length; + } + for (ID in hiddenPosts) { + site = hiddenPosts[ID]; + if (ID !== 'boards') { + for (ID in site.boards) { + board = site.boards[ID]; + for (ID in board) { + thread = board[ID]; + hiddenNum += Object.keys(thread).length; + } + } + } + } + for (ID in hiddenPosts.boards) { + board = hiddenPosts.boards[ID]; + for (ID in board) { + thread = board[ID]; + hiddenNum += Object.keys(thread).length; + } + } + return button.textContent = `Hidden: ${hiddenNum}`; + }); + $$1.on(button, 'click', function () { + this.textContent = 'Hidden: 0'; + return $$1.get('hiddenThreads', dict(), function ({ hiddenThreads }) { + if ($$1.hasStorage && (g.SITE.software === 'yotsuba')) { + let boardID; + for (boardID in hiddenThreads['4chan.org']?.boards) { + localStorage.removeItem(`4chan-hide-t-${boardID}`); + } + for (boardID in hiddenThreads.boards) { + localStorage.removeItem(`4chan-hide-t-${boardID}`); + } + } + return ($$1.delete(['hiddenThreads', 'hiddenPosts'])); + }); + }); + return $$1.after($$1('input[name="Stubs"]', section).parentNode.parentNode, div); + }, + export() { + // Make sure to export the most recent data, but don't overwrite existing `Conf` object. + const Conf2 = dict(); + $$1.extend(Conf2, Conf); + return $$1.get(Conf2, function (Conf2) { + // Don't export cached JSON data. + delete Conf2['boardConfig']; + return (Settings.downloadExport({ version: g.VERSION, date: Date.now(), Conf: Conf2 })); + }); + }, + downloadExport(data) { + const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); + const url = URL.createObjectURL(blob); + const a = $$1.el('a', { + download: `${meta.name} v${g.VERSION}-${data.date}.json`, + href: url + }); + const p = $$1('.imp-exp-result', Settings.dialog); + $$1.rmAll(p); + $$1.add(p, a); + return a.click(); + }, + import() { + return $$1('input[type=file]', this.parentNode).click(); + }, + onImport() { + let file; + if (!(file = this.files[0])) { + return; + } + this.value = null; + const output = $$1('.imp-exp-result'); + if (!confirm('Your current settings will be entirely overwritten, are you sure?')) { + output.textContent = 'Import aborted.'; + return; + } + const reader = new FileReader(); + reader.onload = function (e) { + try { + return Settings.loadSettings(dict.json(e.target.result), function (err) { + if (err) { + return output.textContent = 'Import failed due to an error.'; + } + else if (confirm('Import successful. Reload now?')) { + return window.location.reload(); + } + }); + } + catch (error) { + const err = error; + output.textContent = 'Import failed due to an error.'; + return c.error(err.stack); + } + }; + return reader.readAsText(file); + }, + convertFrom: { + loadletter(data) { + const convertSettings = function (data, map) { + for (var prevKey in map) { + var newKey = map[prevKey]; + if (newKey) { + data.Conf[newKey] = data.Conf[prevKey]; + } + delete data.Conf[prevKey]; + } + return data; + }; + data = convertSettings(data, { + // General confs + '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', + // filter + 'uniqueid': 'uniqueID', + 'mod': 'capcode', + 'email': '', + 'country': 'flag', + 'md5': 'MD5', + // keybinds + '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', + // updater + 'Scrolling': 'Auto Scroll', + 'Verbose': '' + }); + if ('Always CDN' in data.Conf) { + data.Conf['fourchanImageHost'] = data.Conf['Always CDN'] ? 'i.4cdn.org' : ''; + delete data.Conf['Always CDN']; + } + data.Conf.sauces = data.Conf.sauces.replace(/\$\d/g, function (c) { + switch (c) { + case '$1': + return '%TURL'; + case '$2': + return '%URL'; + case '$3': + return '%MD5'; + case '$4': + return '%board'; + default: + return c; + } + }); + for (var key in Config.hotkeys) { + Config.hotkeys[key]; + if (key in data.Conf) { + data.Conf[key] = data.Conf[key].replace(/ctrl|alt|meta/g, s => `${s[0].toUpperCase()}${s.slice(1)}`).replace(/(^|.+\+)[A-Z]$/g, s => `Shift+${s.slice(0, -1)}${s.slice(-1).toLowerCase()}`); + } + } + if (data.WatchedThreads) { + data.Conf['watchedThreads'] = dict.clone({ '4chan.org': { boards: {} } }); + for (var boardID in data.WatchedThreads) { + var threads = data.WatchedThreads[boardID]; + for (var threadID in threads) { + var threadData = threads[threadID]; + (data.Conf['watchedThreads']['4chan.org'].boards[boardID] || (data.Conf['watchedThreads']['4chan.org'].boards[boardID] = dict()))[threadID] = { excerpt: threadData.textContent }; + } + } + } + return data; + } + }, + upgrade(data, version) { + let corrupted, key, val; + const changes = dict(); + const set = (key, value) => data[key] = (changes[key] = value); + const setD = function (key, value) { + if (data[key] == null) { + return set(key, value); + } + }; + const addSauces = function (sauces) { + if (data['sauces'] != null) { + sauces = sauces.filter(s => data['sauces'].indexOf(s.match(/[^#;\s]+|$/)[0]) < 0); + if (sauces.length) { + return set('sauces', data['sauces'] + '\n\n' + sauces.join('\n')); + } + } + }; + const addCSS = function (css) { + if (data['usercss'] == null) { + set('usercss', Config['usercss']); + } + if (data['usercss'].indexOf(css) < 0) { + return set('usercss', css + '\n\n' + data['usercss']); + } + }; + // XXX https://github.com/greasemonkey/greasemonkey/issues/2600 + if (corrupted = (version[0] === '"')) { + try { + version = JSON.parse(version); + } + catch (error) { } + } + const compareString = version.replace(/\d+/g, x => ('0000' + x).slice(-5)); + if (compareString < '00001.00013.00014.00008') { + for (key in data) { + val = data[key]; + if ((typeof val === 'string') && (typeof Conf[key] !== 'string') && !['Index Sort', 'Last Long Reply Thresholds 0', 'Last Long Reply Thresholds 1'].includes(key)) { + corrupted = true; + break; + } + } + } + if (corrupted) { + for (key in data) { + val = data[key]; + if (typeof val === 'string') { + try { + var val2 = JSON.parse(val); + set(key, val2); + } + catch (error1) { } + } + } + } + if (compareString < '00001.00011.00008.00000') { + if (data['Fixed Thread Watcher'] == null) { + set('Fixed Thread Watcher', data['Toggleable Thread Watcher'] ?? true); + } + if (data['Exempt Archives from Encryption'] == null) { + set('Exempt Archives from Encryption', data['Except Archives from Encryption'] ?? false); + } + } + if (compareString < '00001.00011.00010.00001') { + if (data['selectedArchives'] != null) { + const uids = { "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 boardID in data['selectedArchives']) { + var record = data['selectedArchives'][boardID]; + for (var type in record) { + var name = record[type]; + if ($$1.hasOwn(uids, name)) { + record[type] = uids[name]; + } + } + } + set('selectedArchives', data['selectedArchives']); + } + } + if (compareString < '00001.00011.00016.00000') { + let rice; + if (rice = Config['usercss'].match(/\/\* Board title rice \*\/(?:\n.+)*/)[0]) { + if ((data['usercss'] != null) && (data['usercss'].indexOf(rice) < 0)) { + set('usercss', rice + '\n\n' + data['usercss']); + } + } + } + if (compareString < '00001.00011.00017.00000') { + for (key of ['Persistent QR', 'Color User IDs', 'Fappe Tyme', 'Werk Tyme', 'Highlight Posts Quoting You', 'Highlight Own Posts']) { + if (data[key] == null) { + set(key, (key === 'Persistent QR')); + } + } + } + if (compareString < '00001.00011.00017.00006') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/iqdb\.org\//mg, '$1//iqdb.org/')); + } + } + if ((compareString < '00001.00011.00019.00003') && !Settings.dialog) { + $$1.queueTask(() => Settings.warnings.ads(item => new Notice('warning', [...Array.from(item.childNodes)]))); + } + if (compareString < '00001.00011.00020.00003') { + const object = { 'Inline Cross-thread Quotes Only': false, 'Pass Link': true }; + for (key in object) { + var value = object[key]; + if (data[key] == null) { + set(key, value); + } + } + } + if (compareString < '00001.00011.00021.00003') { + if (data['Remember Your Posts'] == null) { + set('Remember Your Posts', data['Mark Quotes of You'] ?? true); + } + } + if (compareString < '00001.00011.00022.00000') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(?:IMG|URL))%3Fs\.jpg/mg, '$1')); + set('sauces', data['sauces'].replace(/^#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(?:IMG|T?URL)(?=$|;)/mg, '$&&safe=off')); + } + } + if (compareString < '00001.00011.00022.00002') { + if ((data['Use Recaptcha v1 in Reports'] == null) && data['Use Recaptcha v1'] && !data['Use Recaptcha v2 in Reports']) { + set('Use Recaptcha v1 in Reports', true); + } + } + if (compareString < '00001.00011.00024.00000') { + if ((data['JSON Navigation'] != null) && (data['JSON Index'] == null)) { + set('JSON Index', data['JSON Navigation']); + } + } + if (compareString < '00001.00011.00026.00000') { + if ((data['Oekaki Links'] != null) && (data['Edit Link'] == null)) { + set('Edit Link', data['Oekaki Links']); + } + if (data['Inline Cross-thread Quotes Only'] == null) { + set('Inline Cross-thread Quotes Only', true); + } + } + if (compareString < '00001.00011.00030.00000') { + if (data['Quote Threading'] && (data['Thread Quotes'] == null)) { + set('Thread Quotes', true); + } + } + if (compareString < '00001.00011.00032.00000') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/3d\.iqdb\.org\//mg, '$1//3d.iqdb.org/')); + } + addSauces([ + '#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' + ]); + } + if (compareString < '00001.00011.00035.00000') { + addSauces(['https://whatanime.ga/?auto&url=%IMG;text:wait']); + } + if (compareString < '00001.00012.00000.00000') { + if (data['Exempt Archives from Encryption'] == null) { + set('Exempt Archives from Encryption', false); + } + if (data['Show New Thread Option in Threads'] == null) { + set('Show New Thread Option in Threads', false); + } + if (data['Show Name and Subject']) { + addCSS('#qr .persona .field {display: block !important;}'); + } + if (data['QR Shortcut'] === false) { + addCSS('#shortcut-qr {display: none;}'); + } + if (data['Bottom QR Link'] === false) { + addCSS('.qr-link-container-bottom {display: none;}'); + } + } + if (compareString < '00001.00012.00000.00006') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*)https:\/\/(?:desustorage|cuckchan)\.org\//mg, '$1https://desuarchive.org/')); + } + } + if (compareString < '00001.00012.00001.00000') { + if ((data['Persistent Thread Watcher'] == null) && (data['Toggleable Thread Watcher'] != null)) { + set('Persistent Thread Watcher', !data['Toggleable Thread Watcher']); + } + } + if (compareString < '00001.00012.00003.00000') { + for (key of ['Image Hover in Catalog', 'Auto Watch', 'Auto Watch Reply']) { + setD(key, false); + } + } + if (compareString < '00001.00013.00001.00002') { + addSauces(['#//www.bing.com/images/search?q=imgurl:%IMG&view=detailv2&iss=sbi#enterInsights']); + } + if (compareString < '00001.00013.00005.00000') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*)http:\/\/regex\.info\/exif\.cgi/mg, '$1http://exif.regex.info/exif.cgi')); + } + addSauces(Config['sauces'].match(/# Known filename formats:(?:\n.+)*|$/)[0].split('\n')); + } + if (compareString < '00001.00013.00007.00002') { + setD('Require OP Quote Link', true); + } + if (compareString < '00001.00013.00008.00000') { + setD('Download Link', true); + } + if (compareString < '00001.00013.00009.00003') { + if (data['jsWhitelist'] != null) { + const list = data['jsWhitelist'].split('\n'); + if (!list.includes('https://cdnjs.cloudflare.com') && list.includes('https://cdn.mathjax.org')) { + set('jsWhitelist', data['jsWhitelist'] + '\n\nhttps://cdnjs.cloudflare.com'); + } + } + } + if (compareString < '00001.00014.00000.00006') { + if (data['siteSoftware'] != null) { + set('siteSoftware', data['siteSoftware'] + '\n4cdn.org yotsuba'); + } + } + if (compareString < '00001.00014.00003.00002') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*)https:\/\/whatanime\.ga\//mg, '$1https://trace.moe/')); + } + } + if (compareString < '00001.00014.00004.00004') { + if ((data['siteSoftware'] != null) && !/^4channel\.org yotsuba$/m.test(data['siteSoftware'])) { + set('siteSoftware', data['siteSoftware'] + '\n4channel.org yotsuba'); + } + } + if (compareString < '00001.00014.00005.00000') { + for (var db of DataBoard.keys) { + if (data[db]?.boards) { + var { boards, lastChecked } = data[db]; + data[db]['4chan.org'] = { boards, lastChecked }; + delete data[db].boards; + delete data[db].lastChecked; + set(db, data[db]); + } + } + if ((data['siteSoftware'] != null) && (data['siteProperties'] == null)) { + const siteProperties = dict(); + for (var line of data['siteSoftware'].split('\n')) { + var [hostname, software] = Array.from(line.split(' ')); + siteProperties[hostname] = { software }; + } + set('siteProperties', siteProperties); + } + } + if (compareString < '00001.00014.00006.00006') { + if (data['sauces'] != null) { + set('sauces', data['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}-/')); + } + } + if (compareString < '00001.00014.00008.00000') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/https:\/\/www\.yandex\.com\/images\/search/g, 'https://yandex.com/images/search')); + } + } + if (compareString < '00001.00014.00009.00000') { + if (data['sauces'] != null) { + set('sauces', data['sauces'].replace(/^(#?\s*)(?:http:)?\/\/(www\.pixiv\.net|www\.deviantart\.com|imgur\.com|flickr\.com)\//mg, '$1https://$2/')); + set('sauces', data['sauces'].replace(/https:\/\/yandex\.com\/images\/search\?rpt=imageview&img_url=%IMG/g, 'https://yandex.com/images/search?rpt=imageview&url=%IMG')); + } + } + if (compareString < '00001.00014.00009.00001') { + if ((data['Use Faster Image Host'] != null) && (data['fourchanImageHost'] == null)) { + set('fourchanImageHost', (data['Use Faster Image Host'] ? 'i.4cdn.org' : '')); + } + } + if (compareString < '00001.00014.00010.00001') { + if (data['Filter in Native Catalog'] == null) { + set('Filter in Native Catalog', false); + } + } + if (compareString < '00001.00014.00012.00008') { + if (data['boardnav'] == null) { + set('boardnav', `\ +[ toggle-all ] +a-replace +c-replace +g-replace +k-replace +v-replace +vg-replace +vr-replace +ck-replace +co-replace +fit-replace +jp-replace +mu-replace +sp-replace +tv-replace +vp-replace +[external-text:"FAQ","${meta.faq}"]\ +`); + } + } + if (compareString < '00001.00014.00016.00001') { + if (data['archiveLists'] != null) { + set('archiveLists', data['archiveLists'].replace('https://mayhemydg.github.io/archives.json/archives.json', 'https://nstepien.github.io/archives.json/archives.json')); + } + } + if (compareString < '00001.00014.00016.00007') { + if (data['sauces'] != null) { + set('sauces', data['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')); + } + } + if (compareString < '00001.00014.00017.00002') { + if (data['jsWhitelist'] != null) { + set('jsWhitelist', data['jsWhitelist'] + '\n\nhttps://hcaptcha.com\nhttps://*.hcaptcha.com'); + } + } + if (compareString < '00001.00014.00020.00004') { + if (data['archiveLists'] != null) { + set('archiveLists', data['archiveLists'].replace('https://nstepien.github.io/archives.json/archives.json', 'https://4chenz.github.io/archives.json/archives.json')); + } + } + if (compareString < '00001.00014.00022.00003') { + if (data['sauces']) { + set('sauces', data['sauces'].replace(/^#?\s*https:\/\/www\.google\.com\/searchbyimage\?image_url=%(IMG|T?URL)&safe=off(?=$|;)/mg, 'https://www.google.com/searchbyimage?sbisrc=4chanx&image_url=%$1&safe=off')); + if (compareString === '00001.00014.00022.00002' && !/\bsbisrc=/.test(data['sauces'])) { + set('sauces', data['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')); + } + } + } + return changes; + }, + loadSettings(data, cb) { + if (data.version.split('.')[0] === '2') { // https://github.com/loadletter/4chan-x + data = Settings.convertFrom.loadletter(data); + } + else if (data.version !== g.VERSION) { + Settings.upgrade(data.Conf, data.version); + } + return $$1.clear(function (err) { + if (err) { + return cb(err); + } + return $$1.set(data.Conf, cb); + }); + }, + reset() { + if (confirm('Your current settings will be entirely wiped, are you sure?')) { + return $$1.clear(function (err) { + if (err) { + return $$1('.imp-exp-result').textContent = 'Import failed due to an error.'; + } + else if (confirm('Reset successful. Reload now?')) { + return window.location.reload(); + } + }); + } + }, + filter(section) { + $$1.extend(section, { innerHTML: FilterSelectPage }); + const select = $$1('select', section); + $$1.on(select, 'change', Settings.selectFilter); + return Settings.selectFilter.call(select); + }, + selectFilter() { + let name; + const div = this.nextElementSibling; + if ((name = this.value) !== 'guide') { + if (!$$1.hasOwn(Config.filter, name)) { + return; + } + $$1.rmAll(div); + const ta = $$1.el('textarea', { + name, + className: 'field', + spellcheck: false + }); + $$1.on(ta, 'change', $$1.cb.value); + $$1.get(name, Conf[name], function (item) { + ta.value = item[name]; + return $$1.add(div, ta); + }); + return; + } + Object.keys(Config.filter).filter(x => x !== 'general').map((x, i) => ({ + innerHTML: (i ? "," : "") + `${E(x)}` + })); + $$1.extend(div, { innerHTML: FilterGuidePage }); + return $$1('.warning', div).hidden = Conf['Filter']; + }, + sauce(section) { + $$1.extend(section, { innerHTML: SaucePage }); + $$1('.warning', section).hidden = Conf['Sauce']; + const ta = $$1('textarea', section); + $$1.get('sauces', Conf['sauces'], function (item) { + ta.value = item['sauces']; + return (ta.hidden = false); + }); // XXX prevent Firefox from adding initialization to undo queue + return $$1.on(ta, 'change', $$1.cb.value); + }, + advanced(section) { + let input, name; + $$1.extend(section, { innerHTML: AdvancedPage }); + for (var warning of $$('.warning', section)) { + warning.hidden = Conf[warning.dataset.feature]; + } + const inputs = dict(); + for (input of $$('[name]', section)) { + inputs[input.name] = input; + } + $$1.on(inputs['archiveLists'], 'change', function () { + $$1.set('lastarchivecheck', 0); + Conf['lastarchivecheck'] = 0; + return $$1.id('lastarchivecheck').textContent = 'never'; + }); + const items = dict(); + for (name in inputs) { + input = inputs[name]; + if (!['Interval', 'Custom CSS'].includes(name)) { + items[name] = Conf[name]; + var event = ((input.nodeName === 'SELECT') || + ['checkbox', 'radio'].includes(input.type) || + ((input.nodeName === 'TEXTAREA') && !(name in Settings))) ? 'change' : 'input'; + $$1.on(input, event, $$1.cb[input.type === 'checkbox' ? 'checked' : 'value']); + if (name in Settings) { + $$1.on(input, event, Settings[name]); + } + } + } + $$1.get(items, function (items) { + for (var key in items) { + var val = items[key]; + input = inputs[key]; + input[input.type === 'checkbox' ? 'checked' : 'value'] = val; + input.hidden = false; // XXX prevent Firefox from adding initialization to undo queue + if (key in Settings) { + Settings[key].call(input); + } + } + }); + const listImageHost = $$1.id('list-fourchanImageHost'); + for (var textContent of ImageHost.suggestions) { + $$1.add(listImageHost, $$1.el('option', { textContent })); + } + const interval = inputs['Interval']; + const customCSS = inputs['Custom CSS']; + const applyCSS = $$1('#apply-css', section); + interval.value = Conf['Interval']; + customCSS.checked = Conf['Custom CSS']; + inputs['usercss'].disabled = !Conf['Custom CSS']; + applyCSS.disabled = !Conf['Custom CSS']; + $$1.on(interval, 'change', ThreadUpdater.cb.interval); + $$1.on(customCSS, 'change', Settings.togglecss); + $$1.on(applyCSS, 'click', () => CustomCSS.update()); + const itemsArchive = dict(); + for (name of ['archives', 'selectedArchives', 'lastarchivecheck']) { + itemsArchive[name] = Conf[name]; + } + $$1.get(itemsArchive, function (itemsArchive) { + $$1.extend(Conf, itemsArchive); + Redirect$1.selectArchives(); + return Settings.addArchiveTable(section); + }); + const boardSelect = $$1('#archive-board-select', section); + const table = $$1('#archive-table', section); + const updateArchives = $$1('#update-archives', section); + $$1.on(boardSelect, 'change', function () { + $$1('tbody > :not([hidden])', table).hidden = true; + return $$1(`tbody > .${this.value}`, table).hidden = false; + }); + return $$1.on(updateArchives, 'click', () => Redirect$1.update(() => Settings.addArchiveTable(section))); + }, + addArchiveTable(section) { + let boardID, o; + $$1('#lastarchivecheck', section).textContent = Conf['lastarchivecheck'] === 0 ? + 'never' + : + new Date(Conf['lastarchivecheck']).toLocaleString(); + const boardSelect = $$1('#archive-board-select', section); + const table = $$1('#archive-table', section); + const tbody = $$1('tbody', section); + $$1.rmAll(boardSelect); + $$1.rmAll(tbody); + const archBoards = dict(); + for (var { uid, name, boards, files, software } of Conf['archives']) { + if (!['fuuka', 'foolfuuka'].includes(software)) { + continue; + } + for (boardID of boards) { + o = archBoards[boardID] || (archBoards[boardID] = { + thread: [], + post: [], + file: [] + }); + var archive = [uid ?? name, name]; + o.thread.push(archive); + if (software === 'foolfuuka') { + o.post.push(archive); + } + if (files.includes(boardID)) { + o.file.push(archive); + } + } + } + const rows = []; + const boardOptions = []; + for (boardID of Object.keys(archBoards).sort()) { // Alphabetical order + var row = $$1.el('tr', { className: `board-${boardID}` }); + row.hidden = boardID !== g.BOARD.ID; + boardOptions.push($$1.el('option', { + textContent: `/${boardID}/`, + value: `board-${boardID}`, + selected: boardID === g.BOARD.ID + })); + o = archBoards[boardID]; + for (var item of ['thread', 'post', 'file']) { + $$1.add(row, Settings.addArchiveCell(boardID, o, item)); + } + rows.push(row); + } + if (rows.length === 0) { + boardSelect.hidden = (table.hidden = true); + return; + } + boardSelect.hidden = (table.hidden = false); + if (!(g.BOARD.ID in archBoards)) { + rows[0].hidden = false; + } + $$1.add(boardSelect, boardOptions); + $$1.add(tbody, rows); + for (boardID in Conf['selectedArchives']) { + var data = Conf['selectedArchives'][boardID]; + for (var type in data) { + var select; + var id = data[type]; + if (select = $$1(`select[data-boardid='${boardID}'][data-type='${type}']`, tbody)) { + select.value = JSON.stringify(id); + if (!select.value) { + select.value = select.firstChild.value; + } + } + } + } + }, + addArchiveCell(boardID, data, type) { + const { length } = data[type]; + const td = $$1.el('td', { className: 'archive-cell' }); + if (!length) { + td.textContent = '--'; + return td; + } + const options = []; + let i = 0; + while (i < length) { + var archive = data[type][i++]; + options.push($$1.el('option', { + value: JSON.stringify(archive[0]), + textContent: archive[1] + })); + } + $$1.extend(td, { innerHTML: '' }); + const select = td.firstElementChild; + if (!(select.disabled = length === 1)) { + // XXX GM can't into datasets + select.setAttribute('data-boardid', boardID); + select.setAttribute('data-type', type); + $$1.on(select, 'change', Settings.saveSelectedArchive); + } + $$1.add(select, options); + return td; + }, + saveSelectedArchive() { + return $$1.get('selectedArchives', Conf['selectedArchives'], ({ selectedArchives }) => { + (selectedArchives[this.dataset.boardid] || (selectedArchives[this.dataset.boardid] = dict()))[this.dataset.type] = JSON.parse(this.value); + $$1.set('selectedArchives', selectedArchives); + Conf['selectedArchives'] = selectedArchives; + return Redirect$1.selectArchives(); + }); + }, + boardnav() { + return Header$1.generateBoardList(this.value); + }, + time() { + return this.nextElementSibling.textContent = Time.format(this.value, new Date()); + }, + timeLocale() { + return Settings.time.call($$1('[name=time]', Settings.dialog)); + }, + backlink() { + return this.nextElementSibling.textContent = this.value.replace(/%(?:id|%)/g, x => ({ '%id': '123456789', '%%': '%' })[x]); + }, + fileInfo() { + const data = { + isReply: true, + file: { + url: `//${ImageHost.host()}/g/1334437723720.jpg`, + name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg', + size: '276 KB', + sizeInBytes: 276 * 1024, + dimensions: '1280x720', + isImage: true, + isVideo: false, + isSpoiler: true, + tag: 'Loop' + } + }; + return FileInfo.format(this.value, data, this.nextElementSibling); + }, + favicon() { + Favicon.switch(); + if ((g.VIEW === 'thread') && Conf['Unread Favicon']) { + Unread.update(); + } + const img = this.nextElementSibling.children; + const f = Favicon; + const iterable = [f.SFW, f.unreadSFW, f.unreadSFWY, f.NSFW, f.unreadNSFW, f.unreadNSFWY, f.dead, f.unreadDead, f.unreadDeadY]; + for (let i = 0; i < iterable.length; i++) { + var icon = iterable[i]; + if (!img[i]) { + $$1.add(this.nextElementSibling, $$1.el('img')); + } + img[i].src = icon; + } + }, + togglecss() { + if (($$1('textarea[name=usercss]', $$1.x('ancestor::fieldset[1]', this)).disabled = ($$1.id('apply-css').disabled = !this.checked))) { + CustomCSS.rmStyle(); + } + else { + CustomCSS.addStyle(); + } + return $$1.cb.checked.call(this); + }, + keybinds(section) { + let key; + $$1.extend(section, { innerHTML: KeybindsPage }); + $$1('.warning', section).hidden = Conf['Keybinds']; + const tbody = $$1('tbody', section); + const items = dict(); + const inputs = dict(); + for (key in Config.hotkeys) { + var arr = Config.hotkeys[key]; + var tr = $$1.el('tr', { innerHTML: `${arr[1]}` }); + var input = $$1('input', tr); + input.name = key; + input.spellcheck = false; + items[key] = Conf[key]; + inputs[key] = input; + $$1.on(input, 'keydown', Settings.keybind); + $$1.add(tbody, tr); + } + return $$1.get(items, function (items) { + for (key in items) { + var val = items[key]; + inputs[key].value = val; + } + }); + }, + keybind(e) { + let key; + if (e.keyCode === 9) { + return; + } // tab + e.preventDefault(); + e.stopPropagation(); + if ((key = Keybinds.keyCode(e)) == null) { + return; + } + this.value = key; + return $$1.cb.value.call(this); + } + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var FappeTyme = { + init() { + if ((!Conf['Fappe Tyme'] && !Conf['Werk Tyme']) || !['index', 'thread', 'archive'].includes(g.VIEW)) { return; } + + this.nodes = {}; + this.enabled = { + fappe: false, + werk: Conf['werk'] + }; + + for (var type of ["Fappe", "Werk"]) { + if (Conf[`${type} Tyme`]) { + var lc = type.toLowerCase(); + var el = UI.checkbox(lc, `${type} Tyme`, false); + el.title = `${type} Tyme`; + + this.nodes[lc] = el.firstElementChild; + if (Conf[lc]) { this.set(lc, true); } + $$1.on(this.nodes[lc], 'change', this.toggle.bind(this, lc)); + + Header$1.menu.addEntry({ + el, + order: 97 + }); + + var indicator = $$1.el('span', { + className: 'indicator', + textContent: type[0], + title: `${type} Tyme active` + } + ); + $$1.on(indicator, 'click', function() { + const check = $$1.getOwn(FappeTyme.nodes, this.parentNode.id.replace('shortcut-', '')); + check.checked = !check.checked; + return $$1.event('change', null, check); + }); + Header$1.addShortcut(lc, indicator, 410); + } + } + + if (Conf['Werk Tyme']) { + $$1.sync('werk', this.set.bind(this, 'werk')); + } + + Callbacks.Post.push({ + name: 'Fappe Tyme', + cb: this.node + }); + + return Callbacks.CatalogThread.push({ + name: 'Werk Tyme', + cb: this.catalogNode + }); + }, + + node() { + return this.nodes.root.classList.toggle('noFile', !this.files.length); + }, + + catalogNode() { + const file = this.thread.OP.files[0]; + if (!file) { return; } + const filename = $$1.el('div', { + textContent: file.name, + className: 'werkTyme-filename' + } + ); + return $$1.add(this.nodes.thumb.parentNode, filename); + }, + + set(type, enabled) { + this.enabled[type] = (this.nodes[type].checked = enabled); + return $$1[`${enabled ? 'add' : 'rm'}Class`](doc$1, `${type}Tyme`); + }, + + toggle(type) { + this.set(type, !this.enabled[type]); + if (type === 'werk') { return $$1.cb.checked.call(this.nodes[type]); } + } + }; + + var galleryPage = `
              + + + + + × + +
              + + / + + + +
              +
              +
              + +
              +
              +
              +
              +`; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS104: Avoid inline assignments + * DS204: Change includes calls to have a more natural evaluation order + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Sauce = { + init() { + let link; + if (!['index', 'thread'].includes(g.VIEW) || !Conf['Sauce']) { return; } + $$1.addClass(doc$1, 'show-sauce'); + + const links = []; + for (link of Conf['sauces'].split('\n')) { + var linkData; + if ((link[0] !== '#') && (linkData = this.parseLink(link))) { + links.push(linkData); + } + } + if (!links.length) { return; } + + this.links = links; + this.link = $$1.el('a', { + target: '_blank', + className: 'sauce' + } + ); + return Callbacks.Post.push({ + name: 'Sauce', + cb: this.node + }); + }, + + parseLink(link) { + if (!(link = link.trim())) { return null; } + const parts = dict(); + const iterable = link.split(/;(?=(?:text|boards|types|regexp|sandbox):?)/); + for (let i = 0; i < iterable.length; i++) { + var part = iterable[i]; + if (i === 0) { + parts['url'] = part; + } else { + var m = part.match(/^(\w*):?(.*)$/); + parts[m[1]] = m[2]; + } + } + if (!parts['text']) { parts['text'] = parts['url'].match(/(\w+)\.\w+\//)?.[1] || '?'; } + if ('boards' in parts) { + parts['boards'] = Filter.parseBoards(parts['boards']); + } + if ('regexp' in parts) { + try { + let regexp; + if (regexp = parts['regexp'].match(/^\/(.*)\/(\w*)$/)) { + parts['regexp'] = RegExp(regexp[1], regexp[2]); + } else { + parts['regexp'] = RegExp(parts['regexp']); + } + } catch (err) { + new Notice('warning', [ + $$1.tn("Invalid regexp for Sauce link:"), + $$1.el('br'), + $$1.tn(link), + $$1.el('br'), + $$1.tn(err.message) + ], 60); + return null; + } + } + return parts; + }, + + createSauceLink(link, post, file) { + let a, matches, needle; + const ext = file.url.match(/[^.]*$/)[0]; + const parts = dict(); + $$1.extend(parts, link); + + if (!!parts['boards'] && !parts['boards'][`${post.siteID}/${post.boardID}`] && !parts['boards'][`${post.siteID}/*`]) { return null; } + if (!!parts['types'] && (needle = ext, !parts['types'].split(',').includes(needle))) { return null; } + if (!!parts['regexp'] && (!(matches = file.name.match(parts['regexp'])))) { return null; } + + const missing = []; + for (var key of ['url', 'text']) { + parts[key] = parts[key].replace(/%(T?URL|IMG|[sh]?MD5|board|name|%|semi|\$\d+)/g, function(orig, parameter) { + let type; + if (parameter[0] === '$') { + if (!matches) { return orig; } + type = matches[parameter.slice(1)] || ''; + } else { + type = Sauce.formatters[parameter](post, file, ext); + if ((type == null)) { + missing.push(parameter); + return ''; + } + } + + if ((key === 'url') && !['%', 'semi'].includes(parameter)) { + if (/^javascript:/i.test(parts['url'])) { type = JSON.stringify(type); } + type = encodeURIComponent(type); + } + return type; + }); + } + + if (g.SITE.areMD5sDeferred?.(post.board) && missing.length && !missing.filter(x => !/^.?MD5$/.test(x)).length) { + a = Sauce.link.cloneNode(false); + a.dataset.skip = '1'; + return a; + } + + if (missing.length) { return null; } + + a = Sauce.link.cloneNode(false); + a.href = parts['url']; + a.textContent = parts['text']; + if (/^javascript:/i.test(parts['url'])) { a.removeAttribute('target'); } + return a; + }, + + node() { + if (this.isClone) { return; } + for (var file of this.files) { + Sauce.file(this, file); + } + }, + + file(post, file) { + let link, node; + const nodes = []; + const skipped = []; + for (link of Sauce.links) { + if (node = Sauce.createSauceLink(link, post, file)) { + nodes.push($$1.tn(' '), node); + if (node.dataset.skip) { skipped.push([link, node]); } + } + } + $$1.add(file.text, nodes); + + if (skipped.length) { + var observer = new MutationObserver(function() { + if (file.text.dataset.md5) { + for ([link, node] of skipped) { + var node2; + if (node2 = Sauce.createSauceLink(link, post, file)) { + $$1.replace(node, node2); + } + } + return observer.disconnect(); + } + }); + return observer.observe(file.text, {attributes: true}); + } + }, + + formatters: { + TURL(post, file) { return file.thumbURL; }, + URL(post, file) { return file.url; }, + IMG(post, file, ext) { if (['gif', 'jpg', 'jpeg', 'png'].includes(ext)) { return file.url; } else { return file.thumbURL; } }, + MD5(post, file) { return file.MD5; }, + sMD5(post, file) { return file.MD5?.replace(/[+/=]/g, c => ({'+': '-', '/': '_', '=': ''})[c]); }, + hMD5(post, file) { if (file.MD5) { return (atob(file.MD5).map((c) => `0${c.charCodeAt(0).toString(16)}`.slice(-2))).join(''); } }, + board(post) { return post.board.ID; }, + name(post, file) { return file.name; }, + '%'() { return '%'; }, + semi() { return ';'; } + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var Gallery = { + init() { + if (!(this.enabled = Conf['Gallery'] && ['index', 'thread'].includes(g.VIEW))) { return; } + + this.delay = Conf['Slide Delay']; + + const el = $$1.el('a', { + href: 'javascript:;', + title: 'Gallery', + textContent: '🖼︎', + }); + + $$1.on(el, 'click', this.cb.toggle); + + Header$1.addShortcut('gallery', el, 530); + + return Callbacks.Post.push({ + name: 'Gallery', + cb: this.node + }); + }, + + node() { + return (() => { + const result = []; + for (var file of this.files) { + if (file.thumb) { + if (Gallery.nodes) { + Gallery.generateThumb(this, file); + Gallery.nodes.total.textContent = Gallery.images.length; + } + + if (!Conf['Image Expansion'] && ((g.SITE.software !== 'tinyboard') || !Main$1.jsEnabled)) { + result.push($$1.on(file.thumbLink, 'click', Gallery.cb.image)); + } else { + result.push(undefined); + } + } + } + return result; + })(); + }, + + build(image) { + let dialog, thumb; + const {cb} = Gallery; + + if (Conf['Fullscreen Gallery']) { + $$1.one(d$1, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', () => $$1.on(d$1, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', cb.close)); + doc$1.mozRequestFullScreen?.(); + doc$1.webkitRequestFullScreen?.(Element.ALLOW_KEYBOARD_INPUT); + } + + Gallery.images = []; + const nodes = (Gallery.nodes = {}); + Gallery.fileIDs = dict(); + Gallery.slideshow = false; + + nodes.el = (dialog = $$1.el('div', + {id: 'a-gallery'})); + $$1.extend(dialog, {innerHTML: galleryPage }); + + const object = { + 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 key in object) { var value = object[key]; nodes[key] = $$1(value, dialog); } + + const menuButton = $$1('.menu-button', dialog); + nodes.menu = new UI.Menu('gallery'); + + $$1.on(nodes.frame, 'click', cb.blank); + if (Conf['Mouse Wheel Volume']) { $$1.on(nodes.frame, 'wheel', Volume.wheel); } + $$1.on(nodes.next, 'click', cb.click); + $$1.on(nodes.name, 'click', ImageCommon.download); + + $$1.on($$1('.gal-prev', dialog), 'click', cb.prev); + $$1.on($$1('.gal-next', dialog), 'click', cb.next); + $$1.on($$1('.gal-start', dialog), 'click', cb.start); + $$1.on($$1('.gal-stop', dialog), 'click', cb.stop); + $$1.on($$1('.gal-close', dialog), 'click', cb.close); + + $$1.on(menuButton, 'click', function(e) { + return nodes.menu.toggle(e, this, g); + }); + + for (var entry of Gallery.menu.createSubEntries()) { + entry.order = 0; + nodes.menu.addEntry(entry); + } + + $$1.on(d$1, 'keydown', cb.keybinds); + if (Conf['Keybinds']) { $$1.off(d$1, 'keydown', Keybinds.keydown); } + + $$1.on(window, 'resize', Gallery.cb.setHeight); + + for (var postThumb of $$(g.SITE.selectors.file.thumb)) { + var post; + if (!(post = Get$1.postFromNode(postThumb))) { continue; } + for (var file of post.files) { + if (file.thumb) { + Gallery.generateThumb(post, file); + // If no image to open is given, pick image we have scrolled to. + if (!image && Gallery.fileIDs[`${post.fullID}.${file.index}`]) { + var candidate = file.thumbLink; + if ((Header$1.getTopOf(candidate) + candidate.getBoundingClientRect().height) >= 0) { + image = candidate; + } + } + } + } + } + $$1.addClass(doc$1, 'gallery-open'); + + $$1.add(d$1.body, dialog); + + nodes.thumbs.scrollTop = 0; + nodes.current.parentElement.scrollTop = 0; + + if (image) { thumb = $$1(`[href='${image.href}']`, nodes.thumbs); } + if (!thumb) { thumb = Gallery.images[Gallery.images.length-1]; } + if (thumb) { Gallery.open(thumb); } + + doc$1.style.overflow = 'hidden'; + return nodes.total.textContent = Gallery.images.length; + }, + + generateThumb(post, file) { + if (post.isClone || post.isHidden) { return; } + if (!file || !file.thumb || (!file.isImage && !file.isVideo && !Conf['PDF in Gallery'])) { return; } + if (Gallery.fileIDs[`${post.fullID}.${file.index}`]) { return; } + + Gallery.fileIDs[`${post.fullID}.${file.index}`] = true; + + const thumb = $$1.el('a', { + className: 'gal-thumb', + href: file.url, + target: '_blank', + title: file.name + } + ); + + thumb.dataset.id = Gallery.images.length; + thumb.dataset.post = post.fullID; + thumb.dataset.file = file.index; + + const thumbImg = file.thumb.cloneNode(false); + thumbImg.style.cssText = ''; + $$1.add(thumb, thumbImg); + + $$1.on(thumb, 'click', Gallery.cb.open); + + Gallery.images.push(thumb); + return $$1.add(Gallery.nodes.thumbs, thumb); + }, + + load(thumb, errorCB) { + const ext = thumb.href.match(/\w*$/); + const elType = $$1.getOwn({'webm': 'video', 'mp4': 'video', 'ogv': 'video', 'pdf': 'iframe'}, ext) || 'img'; + const file = $$1.el(elType); + $$1.extend(file.dataset, thumb.dataset); + $$1.on(file, 'error', errorCB); + file.src = thumb.href; + return file; + }, + + open(thumb) { + let el, file, post; + const {nodes} = Gallery; + const oldID = +nodes.current.dataset.id; + const newID = +thumb.dataset.id; + + // Highlight, center selected thumbnail + if (el = Gallery.images[oldID]) { $$1.rmClass(el, 'gal-highlight'); } + $$1.addClass(thumb, 'gal-highlight'); + nodes.thumbs.scrollTop = (thumb.offsetTop + (thumb.offsetHeight/2)) - (nodes.thumbs.clientHeight/2); + + // Load image or use preloaded image + if (Gallery.cache?.dataset.id === (''+newID)) { + file = Gallery.cache; + $$1.off(file, 'error', Gallery.cacheError); + $$1.on(file, 'error', Gallery.error); + } else { + file = Gallery.load(thumb, Gallery.error); + } + + // Replace old image with new one + $$1.off(nodes.current, 'error', Gallery.error); + ImageCommon.pause(nodes.current); + $$1.replace(nodes.current, file); + nodes.current = file; + + if (file.nodeName === 'VIDEO') { + file.loop = true; + Volume.setup(file); + if (Conf['Autoplay']) { file.play(); } + if (Conf['Show Controls']) { ImageCommon.addControls(file); } + } + + doc$1.classList.toggle('gal-pdf', file.nodeName === 'IFRAME'); + Gallery.cb.setHeight(); + nodes.count.textContent = +thumb.dataset.id + 1; + nodes.name.download = (nodes.name.textContent = thumb.title); + nodes.name.href = thumb.href; + nodes.frame.scrollTop = 0; + nodes.next.focus(); + + // Set sauce links + $$1.rmAll(nodes.sauce); + if (Conf['Sauce'] && Sauce.links && (post = g.posts.get(file.dataset.post))) { + const sauces = []; + for (var link of Sauce.links) { + var node; + if (node = Sauce.createSauceLink(link, post, post.files[+file.dataset.file])) { + sauces.push($$1.tn(' '), node); + } + } + $$1.add(nodes.sauce, sauces); + } + + // Continue slideshow if moving forward, stop otherwise + if (Gallery.slideshow && ((newID > oldID) || ((oldID === (Gallery.images.length-1)) && (newID === 0)))) { + Gallery.setupTimer(); + } else { + Gallery.cb.stop(); + } + + // Scroll to post + if (Conf['Scroll to Post'] && (post = g.posts.get(file.dataset.post))) { + Header$1.scrollTo(post.nodes.root); + } + + // Preload next image + if (isNaN(oldID) || (newID === ((oldID + 1) % Gallery.images.length))) { + return Gallery.cache = Gallery.load(Gallery.images[(newID + 1) % Gallery.images.length], Gallery.cacheError); + } + }, + + error() { + if (this.error?.code === MediaError.MEDIA_ERR_DECODE) { + return new Notice('error', 'Corrupt or unplayable video', 30); + } + if (ImageCommon.isFromArchive(this)) { return; } + const post = g.posts.get(this.dataset.post); + const file = post.files[+this.dataset.file]; + return ImageCommon.error(this, post, file, null, url => { + if (!url) { return; } + Gallery.images[+this.dataset.id].href = url; + if (Gallery.nodes.current === this) { return this.src = url; } + }); + }, + + cacheError() { + return delete Gallery.cache; + }, + + cleanupTimer() { + clearTimeout(Gallery.timeoutID); + const {current} = Gallery.nodes; + $$1.off(current, 'canplaythrough load', Gallery.startTimer); + return $$1.off(current, 'ended', Gallery.cb.next); + }, + + startTimer() { + return Gallery.timeoutID = setTimeout(Gallery.checkTimer, Gallery.delay * SECOND); + }, + + setupTimer() { + Gallery.cleanupTimer(); + const {current} = Gallery.nodes; + const isVideo = current.nodeName === 'VIDEO'; + if (isVideo) { current.play(); } + if ((isVideo ? current.readyState >= 4 : current.complete) || (current.nodeName === 'IFRAME')) { + return Gallery.startTimer(); + } else { + return $$1.on(current, (isVideo ? 'canplaythrough' : 'load'), Gallery.startTimer); + } + }, + + checkTimer() { + const {current} = Gallery.nodes; + if ((current.nodeName === 'VIDEO') && !current.paused) { + $$1.on(current, 'ended', Gallery.cb.next); + return current.loop = false; + } else { + return Gallery.cb.next(); + } + }, + + cb: { + keybinds(e) { + let key; + if (!(key = Keybinds.keyCode(e))) { return; } + + const cb = (() => { switch (key) { + case Conf['Close']: case Conf['Open Gallery']: + return Gallery.cb.close; + case Conf['Next Gallery Image']: + return Gallery.cb.next; + case Conf['Advance Gallery']: + return Gallery.cb.advance; + case Conf['Previous Gallery Image']: + return Gallery.cb.prev; + case Conf['Pause']: + return Gallery.cb.pause; + case Conf['Slideshow']: + return Gallery.cb.toggleSlideshow; + case Conf['Rotate image anticlockwise']: + return Gallery.cb.rotateLeft; + case Conf['Rotate image clockwise']: + return Gallery.cb.rotateRight; + case Conf['Download Gallery Image']: + return Gallery.cb.download; + } })(); + + if (!cb) { return; } + e.stopPropagation(); + e.preventDefault(); + return cb(); + }, + + open(e) { + if (e) { e.preventDefault(); } + if (this) { return Gallery.open(this); } + }, + + image(e) { + e.preventDefault(); + e.stopPropagation(); + return Gallery.build(this); + }, + + prev() { + return Gallery.cb.open.call( + Gallery.images[+Gallery.nodes.current.dataset.id - 1] || Gallery.images[Gallery.images.length - 1] + ); + }, + next() { + return Gallery.cb.open.call( + Gallery.images[+Gallery.nodes.current.dataset.id + 1] || Gallery.images[0] + ); + }, + + click(e) { + if (ImageCommon.onControls(e)) { return; } + e.preventDefault(); + return Gallery.cb.advance(); + }, + + advance() { if (!Conf['Autoplay'] && Gallery.nodes.current.paused) { return Gallery.nodes.current.play(); } else { return Gallery.cb.next(); } }, + toggle() { return (Gallery.nodes ? Gallery.cb.close : Gallery.build)(); }, + blank(e) { if (e.target === this) { return Gallery.cb.close(); } }, + toggleSlideshow() { return Gallery.cb[Gallery.slideshow ? 'stop' : 'start'](); }, + + download() { + const name = $$1('.gal-name'); + return name.click(); + }, + + pause() { + Gallery.cb.stop(); + const {current} = Gallery.nodes; + if (current.nodeName === 'VIDEO') { return current[current.paused ? 'play' : 'pause'](); } + }, + + start() { + $$1.addClass(Gallery.nodes.buttons, 'gal-playing'); + Gallery.slideshow = true; + return Gallery.setupTimer(); + }, + + stop() { + if (!Gallery.slideshow) { return; } + Gallery.cleanupTimer(); + const {current} = Gallery.nodes; + if (current.nodeName === 'VIDEO') { current.loop = true; } + $$1.rmClass(Gallery.nodes.buttons, 'gal-playing'); + return Gallery.slideshow = false; + }, + + rotateLeft() { return Gallery.cb.rotate(270); }, + rotateRight() { return Gallery.cb.rotate(90); }, + + rotate: debounce(100, function(delta) { + const {current} = Gallery.nodes; + if (current.nodeName === 'IFRAME') { return; } + current.dataRotate = ((current.dataRotate || 0) + delta) % 360; + current.style.transform = `rotate(${current.dataRotate}deg)`; + return Gallery.cb.setHeight(); + }), + + close() { + $$1.off(Gallery.nodes.current, 'error', Gallery.error); + ImageCommon.pause(Gallery.nodes.current); + $$1.rm(Gallery.nodes.el); + $$1.rmClass(doc$1, 'gallery-open'); + if (Conf['Fullscreen Gallery']) { + $$1.off(d$1, 'fullscreenchange mozfullscreenchange webkitfullscreenchange', Gallery.cb.close); + d$1.mozCancelFullScreen?.(); + d$1.webkitExitFullscreen?.(); + } + delete Gallery.nodes; + delete Gallery.fileIDs; + doc$1.style.overflow = ''; + + $$1.off(d$1, 'keydown', Gallery.cb.keybinds); + if (Conf['Keybinds']) { $$1.on(d$1, 'keydown', Keybinds.keydown); } + $$1.off(window, 'resize', Gallery.cb.setHeight); + return clearTimeout(Gallery.timeoutID); + }, + + setFitness() { + return (this.checked ? $$1.addClass : $$1.rmClass)(doc$1, `gal-${this.name.toLowerCase().replace(/\s+/g, '-')}`); + }, + + setHeight: debounce(100, function () { + let dim, margin, minHeight; + const {current, frame} = Gallery.nodes; + const {style} = current; + + if (Conf['Stretch to Fit'] && (dim = g.posts.get(current.dataset.post)?.files[+current.dataset.file].dimensions)) { + const [width, height] = Array.from(dim.split('x')); + let containerWidth = frame.clientWidth; + let containerHeight = doc$1.clientHeight - 25; + if (((current.dataRotate || 0) % 180) === 90) { + [containerWidth, containerHeight] = Array.from([containerHeight, containerWidth]); + } + minHeight = Math.min(containerHeight, (height / width) * containerWidth); + style.minHeight = minHeight + 'px'; + style.minWidth = ((width / height) * minHeight) + 'px'; + } else { + style.minHeight = (style.minWidth = ''); + } + + if (((current.dataRotate || 0) % 180) === 90) { + style.maxWidth = Conf['Fit Height'] ? `${doc$1.clientHeight - 25}px` : 'none'; + style.maxHeight = Conf['Fit Width'] ? `${frame.clientWidth}px` : 'none'; + margin = (current.clientWidth - current.clientHeight)/2; + return style.margin = `${margin}px ${-margin}px`; + } else { + return style.maxWidth = (style.maxHeight = (style.margin = '')); + } + }), + + setDelay() { return Gallery.delay = +this.value; } + }, + + menu: { + init() { + if (!Gallery.enabled) { return; } + + const el = $$1.el('span', { + textContent: 'Gallery', + className: 'gallery-link' + } + ); + + return Header$1.menu.addEntry({ + el, + order: 105, + subEntries: Gallery.menu.createSubEntries() + }); + }, + + createSubEntry(name) { + const label = UI.checkbox(name, name); + const input = label.firstElementChild; + if (['Hide Thumbnails', 'Fit Width', 'Fit Height'].includes(name)) { $$1.on(input, 'change', Gallery.cb.setFitness); } + $$1.event('change', null, input); + $$1.on(input, 'change', $$1.cb.checked); + if (['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Stretch to Fit'].includes(name)) { $$1.on(input, 'change', Gallery.cb.setHeight); } + return {el: label}; + }, + + createSubEntries() { + const subEntries = (['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Stretch to Fit', 'Scroll to Post'].map((item) => Gallery.menu.createSubEntry(item))); + + const delayLabel = $$1.el('label', {innerHTML: 'Slide Delay: '}); + const delayInput = delayLabel.firstElementChild; + delayInput.value = Gallery.delay; + $$1.on(delayInput, 'change', Gallery.cb.setDelay); + $$1.on(delayInput, 'change', $$1.cb.value); + subEntries.push({el: delayLabel}); + + return subEntries; + } + } + }; + + var EmbeddingPage = `
              +
              + + × +
              +
              +`; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var Embedding = { + init() { + if (!['index', 'thread', 'archive'].includes(g.VIEW) || !Conf['Linkify'] || (!Conf['Embedding'] && !Conf['Link Title'] && !Conf['Cover Preview'])) { return; } + this.types = dict(); + for (var type of this.ordered_types) { this.types[type.key] = type; } + + if (Conf['Embedding'] && (g.VIEW !== 'archive')) { + this.dialog = UI.dialog('embedding', + { innerHTML: EmbeddingPage }); + this.media = $$1('#media-embed', this.dialog); + $$1.one(d$1, '4chanXInitFinished', this.ready); + $$1.on(d$1, 'IndexRefreshInternal', () => g.posts.forEach(function(post) { + for (post of [post, ...Array.from(post.clones)]) { + for (var embed of post.nodes.embedlinks) { + Embedding.cb.catalogRemove.call(embed); + } + } + })); + } + if (Conf['Link Title']) { + return $$1.on(d$1, '4chanXInitFinished PostsInserted', function() { + for (var key in Embedding.types) { + var service = Embedding.types[key]; + if (service.title?.batchSize) { + Embedding.flushTitles(service.title); + } + } + }); + } + }, + + events(post) { + let el, i, items; + if (g.VIEW === 'archive') { return; } + if (Conf['Embedding']) { + i = 0; + items = (post.nodes.embedlinks = $$('.embedder', post.nodes.comment)); + while ((el = items[i++])) { + $$1.on(el, 'click', Embedding.cb.click); + if ($$1.hasClass(el, 'embedded')) { Embedding.cb.toggle.call(el); } + } + } + if (Conf['Cover Preview']) { + i = 0; + items = $$('.linkify', post.nodes.comment); + while ((el = items[i++])) { + var data; + if (data = Embedding.services(el)) { + Embedding.preview(data); + } + } + return; + } + }, + + process(link, post) { + let data; + if (!Conf['Embedding'] && !Conf['Link Title'] && !Conf['Cover Preview']) { return; } + if ($$1.x('ancestor::pre', link)) { return; } + if (data = Embedding.services(link)) { + data.post = post; + if (Conf['Embedding'] && (g.VIEW !== 'archive')) { Embedding.embed(data); } + if (Conf['Link Title']) { Embedding.title(data); } + if (Conf['Cover Preview'] && (g.VIEW !== 'archive')) { return Embedding.preview(data); } + } + }, + + services(link) { + const {href} = link; + for (var type of Embedding.ordered_types) { + var match; + if (match = type.regExp.exec(href)) { + return {key: type.key, uid: match[1], options: match[2], link}; + } + } + }, + + embed(data) { + const {key, uid, options, link, post} = data; + const {href} = link; + + $$1.addClass(link, key.toLowerCase()); + + const embed = $$1.el('a', { + className: 'embedder', + href: 'javascript:;' + } + , + {innerHTML: '(unembed)'}); + + const object = {key, uid, options, href}; + for (var name in object) { var value = object[name]; embed.dataset[name] = value; } + + $$1.on(embed, 'click', Embedding.cb.click); + $$1.after(link, [$$1.tn(' '), embed]); + post.nodes.embedlinks.push(embed); + + if (Conf['Auto-embed'] && !Conf['Floating Embeds'] && !post.isFetchedQuote) { + if ($$1.hasClass(doc$1, 'catalog-mode')) { + return $$1.addClass(embed, 'embed-removed'); + } else { + return Embedding.cb.toggle.call(embed); + } + } + }, + + ready() { + if (!Main$1.isThisPageLegit()) { return; } + $$1.addClass(Embedding.dialog, 'empty'); + $$1.on($$1('.close', Embedding.dialog), 'click', Embedding.closeFloat); + $$1.on($$1('.move', Embedding.dialog), 'mousedown', Embedding.dragEmbed); + $$1.on($$1('.jump', Embedding.dialog), 'click', function() { + if (doc$1.contains(Embedding.lastEmbed)) { return Header$1.scrollTo(Embedding.lastEmbed); } + }); + return $$1.add(d$1.body, Embedding.dialog); + }, + + closeFloat() { + delete Embedding.lastEmbed; + $$1.addClass(Embedding.dialog, 'empty'); + return $$1.replace(Embedding.media.firstChild, $$1.el('div')); + }, + + dragEmbed() { + // only webkit can handle a blocking div + const {style} = Embedding.media; + if (Embedding.dragEmbed.mouseup) { + $$1.off(d$1, 'mouseup', Embedding.dragEmbed); + Embedding.dragEmbed.mouseup = false; + style.pointerEvents = ''; + return; + } + $$1.on(d$1, 'mouseup', Embedding.dragEmbed); + Embedding.dragEmbed.mouseup = true; + return style.pointerEvents = 'none'; + }, + + title(data) { + let service; + const {key, uid, options, link, post} = data; + if (!(service = Embedding.types[key].title)) { return; } + $$1.addClass(link, key.toLowerCase()); + if (service.batchSize) { + (service.queue || (service.queue = [])).push(data); + if (service.queue.length >= service.batchSize) { + return Embedding.flushTitles(service); + } + } else { + return CrossOrigin$1.cache(service.api(uid), (function() { return Embedding.cb.title(this, data); })); + } + }, + + flushTitles(service) { + let data; + const {queue} = service; + if (!queue?.length) { return; } + service.queue = []; + const cb = function() { + for (data of queue) { Embedding.cb.title(this, data); } + }; + return CrossOrigin$1.cache(service.api((() => { + const result = []; + for (data of queue) { result.push(data.uid); + } + return result; + })()), cb); + }, + + preview(data) { + let service; + const {key, uid, link} = data; + if (!(service = Embedding.types[key].preview)) { return; } + return $$1.on(link, 'mouseover', function(e) { + const src = service.url(uid); + const {height} = service; + const el = $$1.el('img', { + src, + id: 'ihover' + } + ); + $$1.add(Header$1.hover, el); + return UI.hover({ + root: link, + el, + latestEvent: e, + endEvents: 'mouseout click', + height + }); + }); + }, + + cb: { + click(e) { + e.preventDefault(); + if (!$$1.hasClass(this, 'embedded') && (Conf['Floating Embeds'] || $$1.hasClass(doc$1, 'catalog-mode'))) { + let div; + if (!(div = Embedding.media.firstChild)) { return; } + $$1.replace(div, Embedding.cb.embed(this)); + Embedding.lastEmbed = Get$1.postFromNode(this).nodes.root; + return $$1.rmClass(Embedding.dialog, 'empty'); + } else { + return Embedding.cb.toggle.call(this); + } + }, + + toggle() { + if ($$1.hasClass(this, "embedded")) { + $$1.rm(this.nextElementSibling); + } else { + $$1.after(this, Embedding.cb.embed(this)); + } + return $$1.toggleClass(this, 'embedded'); + }, + + embed(a) { + // We create an element to embed + let el, type; + const container = $$1.el('div', {className: 'media-embed'}); + $$1.add(container, (el = (type = Embedding.types[a.dataset.key]).el(a))); + + // Set style values. + el.style.cssText = (type.style != null) ? + type.style + : + 'border: none; width: 640px; height: 360px;'; + + return container; + }, + + catalogRemove() { + const isCatalog = $$1.hasClass(doc$1, 'catalog-mode'); + if ((isCatalog && $$1.hasClass(this, 'embedded')) || (!isCatalog && $$1.hasClass(this, 'embed-removed'))) { + Embedding.cb.toggle.call(this); + return $$1.toggleClass(this, 'embed-removed'); + } + }, + + title(req, data) { + let text; + const {key, uid, options, link, post} = data; + const service = Embedding.types[key].title; + + let {status} = req; + if ([200, 304].includes(status) && service.status) { + status = service.status(req.response)[0]; + } + + if (!status) { return; } + + text = `[${key}] ${(() => { switch (status) { + case 200: case 304: + text = service.text(req.response, uid); + if (typeof text === 'string') { + return text; + } else { + return text = link.textContent; + } + case 404: + return "Not Found"; + case 403: case 401: + return "Forbidden or Private"; + default: + return `${status}'d`; + } })() + }`; + + link.dataset.original = link.textContent; + link.textContent = text; + for (var post2 of post.clones) { + for (var link2 of $$('a.linkify', post2.nodes.comment)) { + if (link2.href === link.href) { + if (link2.dataset.original == null) { link2.dataset.original = link2.textContent; } + link2.textContent = text; + } + } + } + } + }, + + ordered_types: [{ + key: 'audio', + regExp: /^[^?#]+\.(?:mp3|m4a|oga|wav|flac)(?:[?#]|$)/i, + style: '', + el(a) { + return $$1.el('audio', { + controls: true, + preload: 'auto', + src: a.dataset.href + } + ); + } + } + , { + key: 'image', + regExp: /^[^?#]+\.(?:gif|png|jpg|jpeg|bmp|webp)(?::\w+)?(?:[?#]|$)/i, + style: '', + el(a) { + const hrefEsc = E(a.dataset.href); + return $$1.el('div', { innerHTML: ``}); + } + } + , { + key: 'video', + regExp: /^[^?#]+\.(?:og[gv]|webm|mp4)(?:[?#]|$)/i, + style: 'max-width: 80vw; max-height: 80vh;', + el(a) { + const el = $$1.el('video', { + hidden: true, + controls: true, + preload: 'auto', + src: a.dataset.href, + loop: ImageHost.test(a.dataset.href.split('/')[2]) + }); + $$1.on(el, 'loadedmetadata', function() { + if ((el.videoHeight === 0) && el.parentNode) { + return $$1.replace(el, Embedding.types.audio.el(a)); + } else { + return el.hidden = false; + } + }); + return el; + } + } + , { + key: 'PeerTube', + regExp: /^(\w+:\/\/[^\/]+\/videos\/watch\/\w{8}-\w{4}-\w{4}-\w{4}-\w{12})(.*)/, + el(a) { + let start; + const options = (start = a.dataset.options.match(/[?&](start=\w+)/)) ? `?${start[1]}` : ''; + const el = $$1.el('iframe', + {src: a.dataset.uid.replace('/videos/watch/', '/videos/embed/') + options}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + key: 'BitChute', + regExp: /^\w+:\/\/(?:www\.)?bitchute\.com\/video\/([\w\-]+)/, + el(a) { + const el = $$1.el('iframe', + {src: `https://www.bitchute.com/embed/${a.dataset.uid}/`}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + key: 'Clyp', + regExp: /^\w+:\/\/(?:www\.)?clyp\.it\/(\w{8})/, + style: 'border: 0; width: 640px; height: 160px;', + el(a) { + return $$1.el('iframe', + {src: `https://clyp.it/${a.dataset.uid}/widget`}); + }, + title: { + api(uid) { return `https://api.clyp.it/oembed?url=https://clyp.it/${uid}`; }, + text(_) { return _.title; } + } + } + , { + key: 'Dailymotion', + regExp: /^\w+:\/\/(?:(?:www\.)?dailymotion\.com\/(?:embed\/)?video|dai\.ly)\/([A-Za-z0-9]+)[^?]*(.*)/, + el(a) { + let start; + const options = (start = a.dataset.options.match(/[?&](start=\d+)/)) ? `?${start[1]}` : ''; + const el = $$1.el('iframe', + {src: `//www.dailymotion.com/embed/video/${a.dataset.uid}${options}`}); + el.setAttribute("allowfullscreen", "true"); + return el; + }, + title: { + api(uid) { return `https://api.dailymotion.com/video/${uid}`; }, + text(_) { return _.title; } + }, + preview: { + url(uid) { return `https://www.dailymotion.com/thumbnail/video/${uid}`; }, + height: 240 + } + } + , { + key: 'Gfycat', + regExp: /^\w+:\/\/(?:www\.)?gfycat\.com\/(?:iframe\/)?(\w+)/, + el(a) { + const el = $$1.el('iframe', + {src: `//gfycat.com/ifr/${a.dataset.uid}`}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + key: 'Gist', + regExp: /^\w+:\/\/gist\.github\.com\/[\w\-]+\/(\w+)/, + style: '', + el: (function() { + let counter = 0; + return function(a) { + const el = $$1.el('pre', { + hidden: true, + id: `gist-embed-${counter++}` + } + ); + CrossOrigin$1.cache(`https://api.github.com/gists/${a.dataset.uid}`, function() { + el.textContent = Object.values(this.response.files)[0].content; + el.className = 'prettyprint'; + $$1.global(() => window.prettyPrint?.((function() {}), document.getElementById(document.currentScript.dataset.id).parentNode) + , {id: el.id}); + return el.hidden = false; + }); + return el; + }; + })(), + title: { + api(uid) { return `https://api.github.com/gists/${uid}`; }, + text({files}) { + for (var file in files) { if (files.hasOwnProperty(file)) { return file; } } + } + } + } + , { + key: 'InstallGentoo', + regExp: /^\w+:\/\/paste\.installgentoo\.com\/view\/(?:raw\/|download\/|embed\/)?(\w+)/, + el(a) { + return $$1.el('iframe', + {src: `https://paste.installgentoo.com/view/embed/${a.dataset.uid}`}); + } + } + , { + key: 'LiveLeak', + regExp: /^\w+:\/\/(?:\w+\.)?liveleak\.com\/.*\?.*[tif]=(\w+)/, + el(a) { + const el = $$1.el('iframe', + {src: `https://www.liveleak.com/e/${a.dataset.uid}`,}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + 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(a) { + const el = $$1.el('video', { + controls: true, + preload: 'auto', + loop: true + } + ); + if (/^http/.test(a.dataset.uid)) { + $$1.add(el, $$1.el('source', {src: a.dataset.uid})); + return el; + } + const [_, host, names] = Array.from(a.dataset.uid.match(/(\w+)\/(.*)/)); + const types = (() => { switch (host) { + case 'gd': case 'wu': case 'fc': return ['']; + case 'gc': return ['giant', 'fat', 'zippy']; + default: return ['.webm', '.mp4']; + } })(); + for (var name of names.split(',')) { + for (var type of types) { + var base = `${name}${type}`; + var urls = (() => { switch (host) { + // list from src/common.py at http://loopvid.appspot.com/source.html + case 'pf': return [`https://kastden.org/_loopvid_media/pf/${base}`, `https://web.archive.org/web/2/http://a.pomf.se/${base}`]; + case 'kd': return [`https://kastden.org/loopvid/${base}`]; + case 'lv': return [`https://lv.kastden.org/${base}`]; + case 'gd': return [`https://docs.google.com/uc?export=download&id=${base}`]; + case 'gh': return [`https://googledrive.com/host/${base}`]; + case 'db': return [`https://dl.dropboxusercontent.com/u/${base}`]; + case 'dx': return [`https://dl.dropboxusercontent.com/${base}`]; + case 'nn': return [`https://kastden.org/_loopvid_media/nn/${base}`]; + case 'cp': return [`https://copy.com/${base}`]; + case 'wu': return [`http://webmup.com/${base}/vid.webm`]; + case 'ig': return [`https://i.imgur.com/${base}`]; + case 'ky': return [`https://kastden.org/_loopvid_media/ky/${base}`]; + case 'mf': return [`https://kastden.org/_loopvid_media/mf/${base}`, `https://web.archive.org/web/2/https://d.maxfile.ro/${base}`]; + case 'm2': return [`https://kastden.org/_loopvid_media/m2/${base}`]; + case 'pc': return [`https://kastden.org/_loopvid_media/pc/${base}`, `https://web.archive.org/web/2/http://a.pomf.cat/${base}`]; + case '1c': return [`http://b.1339.cf/${base}`]; + case 'pi': return [`https://kastden.org/_loopvid_media/pi/${base}`, `https://web.archive.org/web/2/https://u.pomf.is/${base}`]; + case 'ni': return [`https://kastden.org/_loopvid_media/ni/${base}`, `https://web.archive.org/web/2/https://u.nya.is/${base}`]; + case 'wl': return [`http://webm.land/media/${base}`]; + case 'ko': return [`https://kordy.kastden.org/loopvid/${base}`]; + case 'mm': return [`https://kastden.org/_loopvid_media/mm/${base}`, `https://web.archive.org/web/2/https://my.mixtape.moe/${base}`]; + case 'ic': return [`https://media.8ch.net/file_store/${base}`]; + case 'fc': return [`//${ImageHost.host()}/${base}.webm`]; + case 'gc': return [`https://${type}.gfycat.com/${name}.webm`]; + } })(); + + for (var url of urls) { + $$1.add(el, $$1.el('source', {src: url})); + } + } + } + return el; + } + } + , { + key: 'Openings.moe', + regExp: /^\w+:\/\/openings.moe\/\?video=([^.&=]+)/, + style: 'width: 1280px; height: 720px; max-width: 80vw; max-height: 80vh;', + el(a) { + const el = $$1.el('iframe', + {src: `https://openings.moe/?video=${a.dataset.uid}`,}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + key: 'Pastebin', + regExp: /^\w+:\/\/(?:\w+\.)?pastebin\.com\/(?!u\/)(?:[\w.]+(?:\/|\?i\=))?(\w+)/, + el(a) { + return $$1.el('iframe', + {src: `//pastebin.com/embed_iframe.php?i=${a.dataset.uid}`}); + } + } + , { + key: 'SoundCloud', + regExp: /^\w+:\/\/(?:www\.)?(?:soundcloud\.com\/|snd\.sc\/)([\w\-\/]+)/, + style: 'border: 0; width: 500px; height: 400px;', + el(a) { + return $$1.el('iframe', + {src: `https://w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F${encodeURIComponent(a.dataset.uid)}`}); + }, + title: { + api(uid) { return `${location.protocol}//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F${encodeURIComponent(uid)}`; }, + text(_) { return _.title; } + } + } + , { + key: 'StrawPoll', + regExp: /^\w+:\/\/(?:www\.)?strawpoll\.me\/(?:embed_\d+\/)?(\d+(?:\/r)?)/, + style: 'border: 0; width: 600px; height: 406px;', + el(a) { + return $$1.el('iframe', + {src: `https://www.strawpoll.me/embed_1/${a.dataset.uid}`}); + } + } + , { + key: 'Streamable', + regExp: /^\w+:\/\/(?:www\.)?streamable\.com\/(\w+)/, + el(a) { + const el = $$1.el('iframe', + {src: `https://streamable.com/o/${a.dataset.uid}`}); + el.setAttribute("allowfullscreen", "true"); + return el; + }, + title: { + api(uid) { return `https://api.streamable.com/oembed?url=https://streamable.com/${uid}`; }, + text(_) { return _.title; } + } + } + , { + key: 'TwitchTV', + regExp: /^\w+:\/\/(?:www\.|secure\.|clips\.|m\.)?twitch\.tv\/(\w[^#\&\?]*)/, + el(a) { + let url; + let m = a.dataset.href.match(/^\w+:\/\/(?:(clips\.)|\w+\.)?twitch\.tv\/(?:\w+\/)?(clip\/)?(\w[^#\&\?]*)/); + if (m[1] || m[2]) { + url = `//clips.twitch.tv/embed?clip=${m[3]}&parent=${location.hostname}`; + } else { + let time; + m = a.dataset.uid.match(/(\w+)(?:\/(?:v\/)?(\d+))?/); + url = `//player.twitch.tv/?${m[2] ? `video=v${m[2]}` : `channel=${m[1]}`}&autoplay=false&parent=${location.hostname}`; + if (time = a.dataset.href.match(/\bt=(\w+)/)) { + url += `&time=${time[1]}`; + } + } + const el = $$1.el('iframe', + {src: url}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + key: 'Twitter', + regExp: /^\w+:\/\/(?:www\.|mobile\.)?twitter\.com\/(\w+\/status\/\d+)/, + style: 'border: none; width: 550px; height: 250px; overflow: hidden; resize: both;', + el(a) { + const el = $$1.el('iframe'); + $$1.on(el, 'load', function() { + return this.contentWindow.postMessage({element: 't', query: 'height'}, 'https://twitframe.com'); + }); + var onMessage = function(e) { + if ((e.source === el.contentWindow) && (e.origin === 'https://twitframe.com')) { + $$1.off(window, 'message', onMessage); + return (cont || el).style.height = `${+$$1.minmax(e.data.height, 250, 0.8 * doc$1.clientHeight)}px`; + } + }; + $$1.on(window, 'message', onMessage); + el.src = `https://twitframe.com/show?url=https://twitter.com/${a.dataset.uid}`; + if ($$1.engine === 'gecko') { + // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=680823 + el.style.cssText = 'border: none; width: 100%; height: 100%;'; + var cont = $$1.el('div'); + $$1.add(cont, el); + return cont; + } else { + return el; + } + } + } + , { + key: 'VidLii', + regExp: /^\w+:\/\/(?:www\.)?vidlii\.com\/watch\?v=(\w{11})/, + style: 'border: none; width: 640px; height: 392px;', + el(a) { + const el = $$1.el('iframe', + {src: `https://www.vidlii.com/embed?v=${a.dataset.uid}&a=0`}); + el.setAttribute("allowfullscreen", "true"); + return el; + } + } + , { + key: 'Vimeo', + regExp: /^\w+:\/\/(?:www\.)?vimeo\.com\/(\d+)/, + el(a) { + const el = $$1.el('iframe', + {src: `//player.vimeo.com/video/${a.dataset.uid}?wmode=opaque`}); + el.setAttribute("allowfullscreen", "true"); + return el; + }, + title: { + api(uid) { return `https://vimeo.com/api/oembed.json?url=https://vimeo.com/${uid}`; }, + text(_) { return _.title; } + } + } + , { + key: 'Vine', + regExp: /^\w+:\/\/(?:www\.)?vine\.co\/v\/(\w+)/, + style: 'border: none; width: 500px; height: 500px;', + el(a) { + return $$1.el('iframe', + {src: `https://vine.co/v/${a.dataset.uid}/card`}); + } + } + , { + key: 'Vocaroo', + regExp: /^\w+:\/\/(?:(?:www\.|old\.)?vocaroo\.com|voca\.ro)\/((?:i\/)?\w+)/, + style: '', + el(a) { + const el = $$1.el('iframe'); + el.width = 300; + el.height = 60; + el.setAttribute('frameborder', 0); + el.src = `https://vocaroo.com/embed/${a.dataset.uid.replace(/^i\//, '')}?autoplay=0`; + return el; + } + } + , { + key: 'YouTube', + regExp: /^\w+:\/\/(?:youtu.be\/|[\w.]*youtube[\w.]*\/.*(?:v=|\bembed\/|\bv\/|live\/))([\w\-]{11})(.*)/, + el(a) { + let start = a.dataset.options.match(/\b(?:star)?t\=(\w+)/); + if (start) { start = start[1]; } + if (start && !/^\d+$/.test(start)) { + start += ' 0h0m0s'; + start = (3600 * start.match(/(\d+)h/)[1]) + (60 * start.match(/(\d+)m/)[1]) + (1 * start.match(/(\d+)s/)[1]); + } + const el = $$1.el('iframe', + {src: `//www.youtube.com/embed/${a.dataset.uid}?rel=0&wmode=opaque${start ? '&start=' + start : ''}`}); + el.setAttribute("allowfullscreen", "true"); + return el; + }, + title: { + api(uid) { return `https://www.youtube.com/oembed?url=https%3A//www.youtube.com/watch%3Fv%3D${uid}&format=json`; }, + text(_) { return _.title; }, + status(_) { + if (_.error) { + const m = _.error.match(/^(\d*)\s*(.*)/); + return [+m[1], m[2]]; + } else { + return [200, 'OK']; + } + } + }, + preview: { + url(uid) { return `https://img.youtube.com/vi/${uid}/0.jpg`; }, + height: 360 + } + } + ] + }; + + /* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + var Keybinds = { + init() { + if (!Conf['Keybinds']) { return; } + + for (var hotkey in Config.hotkeys) { + $$1.sync(hotkey, Keybinds.sync); + } + + var init = function() { + $$1.off(d$1, '4chanXInitFinished', init); + $$1.on(d$1, 'keydown', Keybinds.keydown); + for (var node of $$('[accesskey]')) { + node.removeAttribute('accesskey'); + } + }; + return $$1.on(d$1, '4chanXInitFinished', init); + }, + + sync(key, hotkey) { + return Conf[hotkey] = key; + }, + + keydown(e) { + let key, thread, threadRoot; + let catalog, notifications; + if (!(key = Keybinds.keyCode(e))) { return; } + const {target} = e; + if (['INPUT', 'TEXTAREA'].includes(target.nodeName)) { + if (!/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(key) || !!/^Alt\+(\d|Up|Down|Left|Right)$/.test(key)) { return; } + } + if (['index', 'thread'].includes(g.VIEW)) { + threadRoot = Nav.getThread(); + thread = Get$1.threadFromRoot(threadRoot); + } + switch (key) { + // QR & Options + case Conf['Toggle board list']: + if (!Conf['Custom Board Navigation']) { return; } + Header$1.toggleBoardList(); + break; + case Conf['Toggle header']: + Header$1.toggleBarVisibility(); + break; + case Conf['Open empty QR']: + if (!QR.postingIsEnabled) { return; } + Keybinds.qr(); + break; + case Conf['Open QR']: + if (!QR.postingIsEnabled || !threadRoot) { return; } + Keybinds.qr(threadRoot); + break; + case Conf['Open settings']: + Settings.open(); + break; + case Conf['Close']: + if (Settings.dialog) { + Settings.close(); + } else if ((notifications = $$('.notification')).length) { + for (var notification of notifications) { + $$1('.close', notification).click(); + } + } else if (QR.nodes && !(QR.nodes.el.hidden || (window.getComputedStyle(QR.nodes.form).display === 'none'))) { + if (Conf['Persistent QR']) { + QR.hide(); + } else { + QR.close(); + } + } else if (Embedding.lastEmbed) { + Embedding.closeFloat(); + } else { + return; + } + break; + case Conf['Spoiler tags']: + if (target.nodeName !== 'TEXTAREA') { return; } + Keybinds.tags('spoiler', target); + break; + case Conf['Code tags']: + if (target.nodeName !== 'TEXTAREA') { return; } + Keybinds.tags('code', target); + break; + case Conf['Eqn tags']: + if (target.nodeName !== 'TEXTAREA') { return; } + Keybinds.tags('eqn', target); + break; + case Conf['Math tags']: + if (target.nodeName !== 'TEXTAREA') { return; } + Keybinds.tags('math', target); + break; + case Conf['SJIS tags']: + if (target.nodeName !== 'TEXTAREA') { return; } + Keybinds.tags('sjis', target); + break; + case Conf['Toggle sage']: + if (!QR.nodes || !!QR.nodes.el.hidden) { return; } + Keybinds.sage(); + break; + case Conf['Toggle Cooldown']: + if (!QR.nodes || !!QR.nodes.el.hidden || !$$1.hasClass(QR.nodes.fileSubmit, 'custom-cooldown')) { return; } + QR.toggleCustomCooldown(); + break; + case Conf['Post from URL']: + if (!QR.postingIsEnabled) { return; } + QR.handleUrl(''); + break; + case Conf['Add new post']: + if (!QR.postingIsEnabled) { return; } + QR.addPost(); + break; + case Conf['Submit QR']: + if (!QR.nodes || !!QR.nodes.el.hidden) { return; } + if (!QR.status()) { QR.submit(); } + break; + // Index/Thread related + case Conf['Update']: + switch (g.VIEW) { + case 'thread': + if (!ThreadUpdater.enabled) { return; } + ThreadUpdater.update(); + break; + case 'index': + if (!Index$1.enabled) { return; } + Index$1.update(); + break; + default: + return; + } + break; + case Conf['Watch']: + if (!ThreadWatcher$1.enabled || !thread) { return; } + ThreadWatcher$1.toggle(thread); + break; + case Conf['Update thread watcher']: + if (!ThreadWatcher$1.enabled) { return; } + ThreadWatcher$1.buttonFetchAll(); + break; + case Conf['Toggle thread watcher']: + if (!ThreadWatcher$1.enabled) { return; } + ThreadWatcher$1.toggleWatcher(); + break; + case Conf['Toggle threading']: + if (!QuoteThreading.ready) { return; } + QuoteThreading.toggleThreading(); + break; + case Conf['Mark thread read']: + if ((g.VIEW !== 'index') || !thread || !UnreadIndex.enabled) { return; } + UnreadIndex.markRead.call(threadRoot); + break; + // Images + case Conf['Expand image']: + if (!ImageExpand.enabled || !threadRoot) { return; } + var post = Get$1.postFromNode(Keybinds.post(threadRoot)); + if (post.file) { ImageExpand.toggle(post); } + break; + case Conf['Expand images']: + if (!ImageExpand.enabled) { return; } + ImageExpand.cb.toggleAll(); + break; + case Conf['Open Gallery']: + if (!Gallery.enabled) { return; } + Gallery.cb.toggle(); + break; + case Conf['fappeTyme']: + if (!FappeTyme.nodes?.fappe) { return; } + FappeTyme.toggle('fappe'); + break; + case Conf['werkTyme']: + if (!FappeTyme.nodes?.werk) { return; } + FappeTyme.toggle('werk'); + break; + // Board Navigation + case Conf['Front page']: + if (Index$1.enabled) { + Index$1.userPageNav(1); + } else { + location.href = `/${g.BOARD}/`; + } + break; + case Conf['Open front page']: + $$1.open(`${location.origin}/${g.BOARD}/`); + break; + case Conf['Next page']: + if ((g.VIEW !== 'index') || !!g.SITE.isOnePage?.(g.BOARD)) { return; } + if (Index$1.enabled) { + if (!['paged', 'infinite'].includes(Conf['Index Mode'])) { return; } + $$1('.next button', Index$1.pagelist).click(); + } else { + $$1(g.SITE.selectors.nav.next)?.click(); + } + break; + case Conf['Previous page']: + if ((g.VIEW !== 'index') || !!g.SITE.isOnePage?.(g.BOARD)) { return; } + if (Index$1.enabled) { + if (!['paged', 'infinite'].includes(Conf['Index Mode'])) { return; } + $$1('.prev button', Index$1.pagelist).click(); + } else { + $$1(g.SITE.selectors.nav.prev)?.click(); + } + break; + case Conf['Search form']: + if (g.VIEW !== 'index') { return; } + var searchInput = Index$1.enabled ? + Index$1.searchInput + : g.SITE.selectors.searchBox ? + $$1(g.SITE.selectors.searchBox) + : + undefined; + if (!searchInput) { return; } + Header$1.scrollToIfNeeded(searchInput); + searchInput.focus(); + break; + case Conf['Paged mode']: + if (!Index$1.enabledOn(g.BOARD)) { return; } + location.href = g.VIEW === 'index' ? '#paged' : `/${g.BOARD}/#paged`; + break; + case Conf['Infinite scrolling mode']: + if (!Index$1.enabledOn(g.BOARD)) { return; } + location.href = g.VIEW === 'index' ? '#infinite' : `/${g.BOARD}/#infinite`; + break; + case Conf['All pages mode']: + if (!Index$1.enabledOn(g.BOARD)) { return; } + location.href = g.VIEW === 'index' ? '#all-pages' : `/${g.BOARD}/#all-pages`; + break; + case Conf['Open catalog']: + if (!(catalog = CatalogLinks.catalog())) { return; } + location.href = catalog; + break; + case Conf['Cycle sort type']: + if (!Index$1.enabled) { return; } + Index$1.cycleSortType(); + break; + // Thread Navigation + case Conf['Next thread']: + if ((g.VIEW !== 'index') || !threadRoot) { return; } + Nav.scroll(+1); + break; + case Conf['Previous thread']: + if ((g.VIEW !== 'index') || !threadRoot) { return; } + Nav.scroll(-1); + break; + case Conf['Expand thread']: + if ((g.VIEW !== 'index') || !threadRoot) { return; } + ExpandThread.toggle(thread); + // Keep thread from moving off screen when contracted. + Header$1.scrollTo(threadRoot); + break; + case Conf['Open thread']: + if ((g.VIEW !== 'index') || !threadRoot) { return; } + Keybinds.open(thread); + break; + case Conf['Open thread tab']: + if ((g.VIEW !== 'index') || !threadRoot) { return; } + Keybinds.open(thread, true); + break; + // Reply Navigation + case Conf['Next reply']: + if (!threadRoot) { return; } + Keybinds.hl(+1, threadRoot); + break; + case Conf['Previous reply']: + if (!threadRoot) { return; } + Keybinds.hl(-1, threadRoot); + break; + case Conf['Deselect reply']: + if (!threadRoot) { return; } + Keybinds.hl(0, threadRoot); + break; + case Conf['Hide']: + if (!thread || !ThreadHiding.db) { return; } + Header$1.scrollTo(threadRoot); + ThreadHiding.toggle(thread); + break; + case Conf['Quick Filter MD5']: + if (!threadRoot) { return; } + post = Keybinds.post(threadRoot); + Keybinds.hl(+1, threadRoot); + Filter.quickFilterMD5.call(post, e); + break; + case Conf['Previous Post Quoting You']: + if (!threadRoot || !QuoteYou.db) { return; } + QuoteYou.cb.seek('preceding'); + break; + case Conf['Next Post Quoting You']: + if (!threadRoot || !QuoteYou.db) { return; } + QuoteYou.cb.seek('following'); + break; + default: + return; + } + e.preventDefault(); + return e.stopPropagation(); + }, + + keyCode(e) { + let key = (() => { let kc; + switch ((kc = e.keyCode)) { + case 8: // return + 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: + if ((48 <= kc && kc <= 57) || (65 <= kc && kc <= 90)) { // 0-9, A-Z + return String.fromCharCode(kc).toLowerCase(); + } else if (96 <= kc && kc <= 105) { // numpad 0-9 + return String.fromCharCode(kc - 48).toLowerCase(); + } else { + return null; + } + } })(); + if (key) { + if (e.altKey) { key = 'Alt+' + key; } + if (e.ctrlKey) { key = 'Ctrl+' + key; } + if (e.metaKey) { key = 'Meta+' + key; } + if (e.shiftKey) { key = 'Shift+' + key; } + } + return key; + }, + + post(thread) { + const s = g.SITE.selectors; + return ( + $$1(`${s.postContainer}${s.highlightable.reply}.${g.SITE.classes.highlight}`, thread) || + $$1(`${g.SITE.isOPContainerThread ? s.thread : s.postContainer}${s.highlightable.op}`, thread) + ); + }, + + qr(thread) { + QR.open(); + if (thread != null) { + QR.quote.call(Keybinds.post(thread)); + } + return QR.nodes.com.focus(); + }, + + tags(tag, ta) { + BoardConfig.ready(function() { + const {config} = g.BOARD; + const supported = (() => { switch (tag) { + case 'spoiler': return !!config.spoilers; + case 'code': return !!config.code_tags; + case 'math': case 'eqn': return !!config.math_tags; + case 'sjis': return !!config.sjis_tags; + } })(); + if (!supported) { return new Notice('warning', `[${tag}] tags are not supported on /${g.BOARD}/.`, 20); } + }); + + const { + value + } = ta; + const selStart = ta.selectionStart; + const selEnd = ta.selectionEnd; + + ta.value = + value.slice(0, selStart) + + `[${tag}]` + value.slice(selStart, selEnd) + `[/${tag}]` + + value.slice(selEnd); + + // Move the caret to the end of the selection. + const range = (`[${tag}]`).length + selEnd; + ta.setSelectionRange(range, range); + + // Fire the 'input' event + return $$1.event('input', null, ta); + }, + + sage() { + const isSage = /sage/i.test(QR.nodes.email.value); + return QR.nodes.email.value = isSage ? + "" + : "sage"; + }, + + open(thread, tab) { + if (g.VIEW !== 'index') { return; } + const url = Get$1.url('thread', thread); + if (tab) { + return $$1.open(url); + } else { + return location.href = url; + } + }, + + hl(delta, thread) { + const replySelector = `${g.SITE.selectors.postContainer}${g.SITE.selectors.highlightable.reply}`; + const {highlight} = g.SITE.classes; + + const postEl = $$1(`${replySelector}.${highlight}`, thread); + + if (!delta) { + if (postEl) { $$1.rmClass(postEl, highlight); } + return; + } + + if (postEl) { + const {height} = postEl.getBoundingClientRect(); + if ((Header$1.getTopOf(postEl) >= -height) && (Header$1.getBottomOf(postEl) >= -height)) { // We're at least partially visible + let next; + const {root} = Get$1.postFromNode(postEl).nodes; + const axis = delta === +1 ? + 'following' + : + 'preceding'; + if (!(next = $$1.x(`${axis}-sibling::${g.SITE.xpath.replyContainer}[not(@hidden) and not(child::div[@class='stub'])][1]`, root))) { return; } + if (!next.matches(replySelector)) { next = $$1(replySelector, next); } + Header$1.scrollToIfNeeded(next, delta === +1); + $$1.addClass(next, highlight); + $$1.rmClass(postEl, highlight); + return; + } + $$1.rmClass(postEl, highlight); + } + + const replies = $$(replySelector, thread); + if (delta === -1) { replies.reverse(); } + for (var reply of replies) { + if (((delta === +1) && (Header$1.getTopOf(reply) > 0)) || ((delta === -1) && (Header$1.getBottomOf(reply) > 0))) { + $$1.addClass(reply, highlight); + return; + } + } + } + }; + + const Captcha = { + Cache: { + init() { + $$1.on(d$1, 'SaveCaptcha', e => { + return this.saveAPI(e.detail); + }); + return $$1.on(d$1, 'NoCaptcha', e => { + return this.noCaptcha(e.detail); + }); + }, + + captchas: [], + + getCount() { + return this.captchas.length; + }, + + neededRaw() { + return !( + this.haveCookie() || this.captchas.length || QR.req || this.submitCB + ) && ( + (QR.posts.length > 1) || Conf['Auto-load captcha'] || !QR.posts[0].isOnlyQuotes() || QR.posts[0].file + ); + }, + + needed() { + return this.neededRaw() && $$1.event('LoadCaptcha'); + }, + + prerequest() { + if (!Conf['Prerequest Captcha']) { return; } + // Post count temporarily off by 1 when called from QR.post.rm, QR.close, or QR.submit + return $$1.queueTask(() => { + if ( + !this.prerequested && + this.neededRaw() && + !$$1.event('LoadCaptcha') && + !QR.captcha.occupied() && + (QR.cooldown.seconds <= 60) && + (QR.selected === QR.posts[QR.posts.length - 1]) && + !QR.selected.isOnlyQuotes() + ) { + const isReply = (QR.selected.thread !== 'new'); + if (!$$1.event('RequestCaptcha', { isReply })) { + this.prerequested = true; + this.submitCB = captcha => { + if (captcha) { return this.save(captcha); } + }; + return this.updateCount(); + } + } + }); + }, + + haveCookie() { + return /\b_ct=/.test(d$1.cookie) && (QR.posts[0].thread !== 'new'); + }, + + getOne() { + let captcha; + delete this.prerequested; + this.clear(); + if (captcha = this.captchas.shift()) { + this.count(); + return captcha; + } else { + return null; + } + }, + + request(isReply) { + if (!this.submitCB) { + if ($$1.event('RequestCaptcha', { isReply })) { return; } + } + return cb => { + this.submitCB = cb; + return this.updateCount(); + }; + }, + + abort() { + if (this.submitCB) { + delete this.submitCB; + $$1.event('AbortCaptcha'); + return this.updateCount(); + } + }, + + saveAPI(captcha) { + let cb; + if (cb = this.submitCB) { + delete this.submitCB; + cb(captcha); + return this.updateCount(); + } else { + return this.save(captcha); + } + }, + + noCaptcha(detail) { + let cb; + if (cb = this.submitCB) { + if (!this.haveCookie() || detail?.error) { + QR.error(detail?.error || 'Failed to retrieve captcha.'); + QR.captcha.setup(d$1.activeElement === QR.nodes.status); + } + delete this.submitCB; + cb(); + return this.updateCount(); + } + }, + + save(captcha) { + let cb; + if (cb = this.submitCB) { + this.abort(); + cb(captcha); + return; + } + this.captchas.push(captcha); + this.captchas.sort((a, b) => a.timeout - b.timeout); + return this.count(); + }, + + clear() { + if (this.captchas.length) { + let i; + const now = Date.now(); + for (i = 0; i < this.captchas.length; i++) { + var captcha = this.captchas[i]; + if (captcha.timeout > now) { break; } + } + if (i) { + this.captchas = this.captchas.slice(i); + return this.count(); + } + } + }, + + count() { + clearTimeout(this.timer); + if (this.captchas.length) { + this.timer = setTimeout(this.clear.bind(this), this.captchas[0].timeout - Date.now()); + } + return this.updateCount(); + }, + + updateCount() { + return $$1.event('CaptchaCount', this.captchas.length); + } + }, Replace: CaptchaReplace, t: CaptchaT, v2: { + lifetime: 2 * MINUTE, + + init() { + if (d$1.cookie.indexOf('pass_enabled=1') >= 0) { return; } + if (!(this.isEnabled = !!$$1('#g-recaptcha, #captcha-forced-noscript') || !$$1.id('postForm'))) { return; } + + if (this.noscript = Conf['Force Noscript Captcha'] || !Main$1.jsEnabled) { + $$1.addClass(QR.nodes.el, 'noscript-captcha'); + } + + Captcha.cache.init(); + $$1.on(d$1, 'CaptchaCount', this.count.bind(this)); + + const root = $$1.el('div', { className: 'captcha-root' }); + $$1.extend(root, { + innerHTML: + '
              ' + } + ); + const counter = $$1('.captcha-counter > a', root); + this.nodes = { root, counter }; + this.count(); + $$1.addClass(QR.nodes.el, 'has-captcha', 'captcha-v2'); + $$1.after(QR.nodes.com.parentNode, root); + + $$1.on(counter, 'click', this.toggle.bind(this)); + $$1.on(counter, 'keydown', e => { + if (Keybinds.keyCode(e) !== 'Space') { return; } + this.toggle(); + e.preventDefault(); + return e.stopPropagation(); + }); + return $$1.on(window, 'captcha:success', () => { + // XXX Greasemonkey 1.x workaround to gain access to GM_* functions. + return $$1.queueTask(() => this.save(false)); + }); + }, + + timeouts: {}, + prevNeeded: 0, + + noscriptURL() { + let lang; + let url = `https://www.google.com/recaptcha/api/fallback?k=${meta.recaptchaKey}`; + if (lang = Conf['captchaLanguage'].trim()) { + url += `&hl=${encodeURIComponent(lang)}`; + } + return url; + }, + + moreNeeded() { + // Post count temporarily off by 1 when called from QR.post.rm, QR.close, or QR.submit + return $$1.queueTask(() => { + const needed = Captcha.cache.needed(); + if (needed && !this.prevNeeded) { + this.setup(QR.cooldown.auto && (d$1.activeElement === QR.nodes.status)); + } + return this.prevNeeded = needed; + }); + }, + + toggle() { + if (this.nodes.container && !this.timeouts.destroy) { + return this.destroy(); + } else { + return this.setup(true, true); + } + }, + + setup(focus, force) { + if (!this.isEnabled || (!Captcha.cache.needed() && !force)) { return; } + + if (focus) { + $$1.addClass(QR.nodes.el, 'focus'); + this.nodes.counter.focus(); + } + + if (this.timeouts.destroy) { + clearTimeout(this.timeouts.destroy); + delete this.timeouts.destroy; + return this.reload(); + } + + if (this.nodes.container) { + // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=1226835 + $$1.queueTask(() => { + let iframe; + if (this.nodes.container && (d$1.activeElement === this.nodes.counter) && (iframe = $$1('iframe[src^="https://www.google.com/recaptcha/"]', this.nodes.container))) { + iframe.focus(); + return QR.focus(); + } + }); // Event handler not fired in Firefox + return; + } + + this.nodes.container = $$1.el('div', { className: 'captcha-container' }); + $$1.prepend(this.nodes.root, this.nodes.container); + new MutationObserver(this.afterSetup.bind(this)).observe(this.nodes.container, { + childList: true, + subtree: true + } + ); + + if (this.noscript) { + return this.setupNoscript(); + } else { + return this.setupJS(); + } + }, + + setupNoscript() { + const iframe = $$1.el('iframe', { + id: 'qr-captcha-iframe', + scrolling: 'no', + src: this.noscriptURL() + } + ); + const div = $$1.el('div'); + const textarea = $$1.el('textarea'); + $$1.add(div, textarea); + return $$1.add(this.nodes.container, [iframe, div]); + }, + + setupJS() { + return $$1.global(function () { + const render = function () { + const { classList } = document.documentElement; + const container = document.querySelector('#qr .captcha-container'); + return container.dataset.widgetID = window.grecaptcha.render(container, { + sitekey: meta.recaptchaKey, + theme: classList.contains('tomorrow') || classList.contains('spooky') || classList.contains('dark-captcha') ? 'dark' : 'light', + callback(response) { + return window.dispatchEvent(new CustomEvent('captcha:success', { detail: response })); + } + } + ); + }; + if (window.grecaptcha) { + return render(); + } else { + const cbNative = window.onRecaptchaLoaded; + window.onRecaptchaLoaded = function () { + render(); + return cbNative(); + }; + if (!document.head.querySelector('script[src^="https://www.google.com/recaptcha/api.js"]')) { + const script = document.createElement('script'); + script.src = 'https://www.google.com/recaptcha/api.js?onload=onRecaptchaLoaded&render=explicit'; + return document.head.appendChild(script); + } + } + }); + }, + + afterSetup(mutations) { + for (var mutation of mutations) { + for (var node of mutation.addedNodes) { + var iframe, textarea; + if (iframe = $$1.x('./descendant-or-self::iframe[starts-with(@src, "https://www.google.com/recaptcha/")]', node)) { this.setupIFrame(iframe); } + if (textarea = $$1.x('./descendant-or-self::textarea', node)) { this.setupTextArea(textarea); } + } + } + }, + + setupIFrame(iframe) { + let needle; + if (!doc.contains(iframe)) { return; } + Captcha.replace.iframe(iframe); + $$1.addClass(QR.nodes.el, 'captcha-open'); + this.fixQRPosition(); + $$1.on(iframe, 'load', this.fixQRPosition); + if (d$1.activeElement === this.nodes.counter) { iframe.focus(); } + // XXX Make sure scroll on space prevention (see src/css/style.css) doesn't cause scrolling of div + if (['blink', 'edge'].includes($$1.engine) && (needle = iframe.parentNode, $$('#qr .captcha-container > div > div:first-of-type').includes(needle))) { + return $$1.on(iframe.parentNode, 'scroll', function () { return this.scrollTop = 0; }); + } + }, + + fixQRPosition() { + if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) { + QR.nodes.el.style.top = ''; + return QR.nodes.el.style.bottom = '0px'; + } + }, + + setupTextArea(textarea) { + return $$1.one(textarea, 'input', () => this.save(true)); + }, + + destroy() { + if (!this.isEnabled) { return; } + delete this.timeouts.destroy; + $$1.rmClass(QR.nodes.el, 'captcha-open'); + if (this.nodes.container) { + $$1.global(function () { + const container = document.querySelector('#qr .captcha-container'); + return window.grecaptcha.reset(container.dataset.widgetID); + }); + $$1.rm(this.nodes.container); + return delete this.nodes.container; + } + }, + + getOne(isReply) { + return Captcha.cache.getOne(isReply); + }, + + save(pasted, token) { + Captcha.cache.save({ + response: token || $$1('textarea', this.nodes.container).value, + timeout: Date.now() + this.lifetime + }); + + const focus = (d$1.activeElement?.nodeName === 'IFRAME') && /https?:\/\/www\.google\.com\/recaptcha\//.test(d$1.activeElement.src); + if (Captcha.cache.needed()) { + if (focus) { + if (QR.cooldown.auto || Conf['Post on Captcha Completion']) { + this.nodes.counter.focus(); + } else { + QR.nodes.status.focus(); + } + } + this.reload(); + } else { + if (pasted) { + this.destroy(); + } else { + if (this.timeouts.destroy == null) { this.timeouts.destroy = setTimeout(this.destroy.bind(this), 3 * SECOND); } + } + if (focus) { QR.nodes.status.focus(); } + } + + if (Conf['Post on Captcha Completion'] && !QR.cooldown.auto) { return QR.submit(); } + }, + + count() { + const count = Captcha.cache.getCount(); + const loading = Captcha.cache.submitCB ? '...' : ''; + this.nodes.counter.textContent = `Captchas: ${count}${loading}`; + return this.moreNeeded(); + }, + + reload() { + if ($$1('iframe[src^="https://www.google.com/recaptcha/api/fallback?"]', this.nodes.container)) { + this.destroy(); + return this.setup(false, true); + } else { + return $$1.global(function () { + const container = document.querySelector('#qr .captcha-container'); + return window.grecaptcha.reset(container.dataset.widgetID); + }); + } + }, + + occupied() { + return !!this.nodes.container && !this.timeouts.destroy; + } + } + }; + + /* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS202: Simplify dynamic range loops + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md + */ + + var QR = { + 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 sc; + if (!Conf['Quick Reply']) { return; } + + this.posts = []; + + $$1.on(d$1, '4chanXInitFinished', () => BoardConfig.ready(QR.initReady)); + + Callbacks.Post.push({ + name: 'Quick Reply', + cb: this.node + }); + + this.shortcut = (sc = $$1.el('a', { + className: 'disabled', + textContent: '↩', + title: 'Quick Reply', + href: 'javascript:;' + } + )); + $$1.on(sc, 'click', function() { + if (!QR.postingIsEnabled) { return; } + if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) { + QR.open(); + return QR.nodes.com.focus(); + } else { + return QR.close(); + } + }); + + return Header$1.addShortcut('qr', sc, 540); + }, + + initReady() { + let origToggle; + const captchaVersion = $$1('#g-recaptcha, #captcha-forced-noscript') ? 'v2' : 't'; + QR.captcha = Captcha[captchaVersion]; + QR.postingIsEnabled = true; + + const {config} = g.BOARD; + const prop = (key, def) => +(config[key] ?? def); + + QR.min_width = prop('min_image_width', 1); + QR.min_height = prop('min_image_height', 1); + QR.max_width = (QR.max_height = 10000); + + QR.max_size = prop('max_filesize', 4194304); + QR.max_size_video = prop('max_webm_filesize', QR.max_size); + QR.max_comment = prop('max_comment_chars', 2000); + + QR.max_width_video = (QR.max_height_video = 2048); + QR.max_duration_video = prop('max_webm_duration', 120); + + QR.forcedAnon = !!config.forced_anon; + QR.spoiler = !!config.spoilers; + + if (origToggle = $$1.id('togglePostFormLink')) { + const link = $$1.el('h1', + {className: "qr-link-container"}); + $$1.extend(link, { + innerHTML: + `${g.VIEW === "thread" ? "Reply to Thread" : "Start a Thread"}` + }); + + QR.link = link.firstElementChild; + $$1.on(link.firstChild, 'click', function() { + QR.open(); + return QR.nodes.com.focus(); + }); + + $$1.before(origToggle, link); + origToggle.firstElementChild.textContent = 'Original Form'; + } + + if (g.VIEW === 'thread') { + let navLinksBot; + const linkBot = $$1.el('div', + {className: "brackets-wrap qr-link-container-bottom"}); + $$1.extend(linkBot, {innerHTML: 'Reply to Thread'}); + + $$1.on(linkBot.firstElementChild, 'click', function() { + QR.open(); + return QR.nodes.com.focus(); + }); + + if (navLinksBot = $$1('.navLinksBot')) { $$1.prepend(navLinksBot, linkBot); } + } + + $$1.on(d$1, 'QRGetFile', QR.getFile); + $$1.on(d$1, 'QRDrawFile', QR.drawFile); + $$1.on(d$1, 'QRSetFile', QR.setFile); + + $$1.on(d$1, 'paste', QR.paste); + $$1.on(d$1, 'dragover', QR.dragOver); + $$1.on(d$1, 'drop', QR.dropFile); + $$1.on(d$1, 'dragstart dragend', QR.drag); + + $$1.on(d$1, 'IndexRefreshInternal', QR.generatePostableThreadsList); + $$1.on(d$1, 'ThreadUpdate', QR.statusCheck); + + if (!Conf['Persistent QR']) { return; } + QR.open(); + if (Conf['Auto Hide QR']) { return QR.hide(); } + }, + + statusCheck() { + if (!QR.nodes) { return; } + const {thread} = QR.posts[0]; + if ((thread !== 'new') && g.threads.get(`${g.BOARD}.${thread}`).isDead) { + return QR.abort(); + } else { + return QR.status(); + } + }, + + node() { + $$1.on(this.nodes.quote, 'click', QR.quote); + if (this.isFetchedQuote) { return QR.generatePostableThreadsList(); } + }, + + open() { + if (QR.nodes) { + if (QR.nodes.el.hidden) { QR.captcha.setup(); } + QR.nodes.el.hidden = false; + QR.unhide(); + } else { + try { + QR.dialog(); + } catch (err) { + delete QR.nodes; + Main$1.handleErrors({ + message: 'Quick Reply dialog creation crashed.', + error: err + }); + return; + } + } + return $$1.rmClass(QR.shortcut, 'disabled'); + }, + + close() { + if (QR.req) { + QR.abort(); + return; + } + QR.nodes.el.hidden = true; + QR.cleanNotifications(); + QR.blur(); + $$1.rmClass(QR.nodes.el, 'dump'); + $$1.addClass(QR.shortcut, 'disabled'); + new QR.post(true); + for (var post of QR.posts.splice(0, QR.posts.length - 1)) { + post.delete(); + } + QR.cooldown.auto = false; + QR.status(); + return QR.captcha.destroy(); + }, + + focus() { + return $$1.queueTask(function() { + if (!QR.inBubble()) { + QR.hasFocus = d$1.activeElement && QR.nodes.el.contains(d$1.activeElement); + return QR.nodes.el.classList.toggle('focus', QR.hasFocus); + } + }); + }, + + inBubble() { + const bubbles = $$('iframe[src^="https://www.google.com/recaptcha/api2/frame"]'); + return bubbles.includes(d$1.activeElement) || bubbles.some(el => (getComputedStyle(el).visibility !== 'hidden') && (el.getBoundingClientRect().bottom > 0)); + }, + + hide() { + QR.blur(); + $$1.addClass(QR.nodes.el, 'autohide'); + return QR.nodes.autohide.checked = true; + }, + + unhide() { + $$1.rmClass(QR.nodes.el, 'autohide'); + return QR.nodes.autohide.checked = false; + }, + + toggleHide() { + if (this.checked) { + return QR.hide(); + } else { + return QR.unhide(); + } + }, + + blur() { + if (QR.nodes.el.contains(d$1.activeElement)) { return d$1.activeElement.blur(); } + }, + + toggleSJIS(e) { + e.preventDefault(); + Conf['sjisPreview'] = !Conf['sjisPreview']; + $$1.set('sjisPreview', Conf['sjisPreview']); + return QR.nodes.el.classList.toggle('sjis-preview', Conf['sjisPreview']); + }, + + texPreviewShow() { + if ($$1.hasClass(QR.nodes.el, 'tex-preview')) { return QR.texPreviewHide(); } + $$1.addClass(QR.nodes.el, 'tex-preview'); + QR.nodes.texPreview.textContent = QR.nodes.com.value; + return $$1.event('mathjax', null, QR.nodes.texPreview); + }, + + texPreviewHide() { + return $$1.rmClass(QR.nodes.el, 'tex-preview'); + }, + + addPost() { + const wasOpen = (QR.nodes && !QR.nodes.el.hidden); + QR.open(); + if (wasOpen) { + $$1.addClass(QR.nodes.el, 'dump'); + new QR.post(true); + } + return QR.nodes.com.focus(); + }, + + setCustomCooldown(enabled) { + Conf['customCooldownEnabled'] = enabled; + QR.cooldown.customCooldown = enabled; + return QR.nodes.customCooldown.classList.toggle('disabled', !enabled); + }, + + toggleCustomCooldown() { + const enabled = $$1.hasClass(QR.nodes.customCooldown, 'disabled'); + QR.setCustomCooldown(enabled); + return $$1.set('customCooldownEnabled', enabled); + }, + + error(err, focusOverride) { + let el; + QR.open(); + if (typeof err === 'string') { + el = $$1.tn(err); + } else { + el = err; + el.removeAttribute('style'); + } + const notice = new Notice('warning', el); + QR.notifications.push(notice); + if (!Header$1.areNotificationsEnabled) { + if (d$1.hidden && !QR.cooldown.auto) { return alert(el.textContent); } + } else if (d$1.hidden || !(focusOverride || d$1.hasFocus())) { + const notif = new Notification(el.textContent, { + body: el.textContent, + icon: Favicon.logo + } + ); + notif.onclick = () => window.focus(); + if ($$1.engine !== 'gecko') { + // Firefox automatically closes notifications + // so we can't control the onclose properly. + notif.onclose = () => notice.close(); + return notif.onshow = () => setTimeout(function() { + notif.onclose = null; + return notif.close(); + } + , 7 * SECOND); + } + } + }, + + connectionError() { + return $$1.el('span', + { innerHTML: + 'Connection error while posting. ' + + '[More info]' + } + ); + }, + + notifications: [], + + cleanNotifications() { + for (var notification of QR.notifications) { + notification.close(); + } + return QR.notifications = []; + }, + + status() { + let disabled, value; + if (!QR.nodes) { return; } + const {thread} = QR.posts[0]; + if ((thread !== 'new') && g.threads.get(`${g.BOARD}.${thread}`).isDead) { + value = 'Dead'; + disabled = true; + QR.cooldown.auto = false; + } + + value = QR.req ? + QR.req.progress + : + QR.cooldown.seconds || value; + + const {status} = QR.nodes; + status.value = !value ? + 'Submit' + : QR.cooldown.auto ? + `Auto ${value}` + : + value; + return status.disabled = disabled || false; + }, + + openPost() { + QR.open(); + if (QR.selected.isLocked) { + const index = QR.posts.indexOf(QR.selected); + (QR.posts[index+1] || new QR.post()).select(); + $$1.addClass(QR.nodes.el, 'dump'); + return QR.cooldown.auto = true; + } + }, + + quote(e) { + let range; + e?.preventDefault(); + if (!QR.postingIsEnabled) { return; } + const sel = d$1.getSelection(); + const post = Get$1.postFromNode(this); + const {root} = post.nodes; + const postRange = new Range(); + postRange.selectNode(root); + let text = post.board.ID === g.BOARD.ID ? `>>${post}\n` : `>>>/${post.board}/${post}\n`; + for (let i = 0, end = sel.rangeCount, asc = 0 <= end; asc ? i < end : i > end; asc ? i++ : i--) { + try { + var insideCode, node; + range = sel.getRangeAt(i); + // Trim range to be fully inside post + if (range.compareBoundaryPoints(Range.START_TO_START, postRange) < 0) { + range.setStartBefore(root); + } + if (range.compareBoundaryPoints(Range.END_TO_END, postRange) > 0) { + range.setEndAfter(root); + } + + if (!range.toString().trim()) { continue; } + + var frag = range.cloneContents(); + var ancestor = range.commonAncestorContainer; + // Quoting the insides of a spoiler/code tag. + if ($$1.x('ancestor-or-self::*[self::s or contains(@class,"removed-spoiler")]', ancestor)) { + $$1.prepend(frag, $$1.tn('[spoiler]')); + $$1.add(frag, $$1.tn('[/spoiler]')); + } + if (insideCode = $$1.x('ancestor-or-self::pre[contains(@class,"prettyprint")]', ancestor)) { + $$1.prepend(frag, $$1.tn('[code]')); + $$1.add(frag, $$1.tn('[/code]')); + } + for (node of $$((insideCode ? 'br' : '.prettyprint br'), frag)) { + $$1.replace(node, $$1.tn('\n')); + } + for (node of $$('br', frag)) { + if (node !== frag.lastChild) { $$1.replace(node, $$1.tn('\n>')); } + } + g.SITE.insertTags?.(frag); + for (node of $$('.linkify[data-original]', frag)) { + $$1.replace(node, $$1.tn(node.dataset.original)); + } + for (node of $$('.embedder', frag)) { + if (node.previousSibling?.nodeValue === ' ') { $$1.rm(node.previousSibling); } + $$1.rm(node); + } + text += `>${frag.textContent.trim()}\n`; + } catch (error) { } + } + + QR.openPost(); + const {com, thread} = QR.nodes; + if (!com.value) { thread.value = Get$1.threadFromNode(this); } + + const wasOnlyQuotes = QR.selected.isOnlyQuotes(); + + const caretPos = com.selectionStart; + // Replace selection for text. + com.value = com.value.slice(0, caretPos) + text + com.value.slice(com.selectionEnd); + // Move the caret to the end of the new quote. + range = caretPos + text.length; + com.setSelectionRange(range, range); + com.focus(); + + // This allows us to determine if any text other than quotes has been typed. + if (wasOnlyQuotes) { QR.selected.quotedText = com.value; } + + QR.selected.save(com); + return QR.selected.save(thread); + }, + + characterCount() { + const counter = QR.nodes.charCount; + const count = QR.nodes.com.value.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '_').length; + counter.textContent = count; + counter.hidden = count < (QR.max_comment/2); + return (count > QR.max_comment ? $$1.addClass : $$1.rmClass)(counter, 'warning'); + }, + + getFile() { + return $$1.event('QRFile', QR.selected?.file); + }, + + drawFile(e) { + const file = QR.selected?.file; + if (!file || !/^(image|video)\//.test(file.type)) { return; } + const isVideo = /^video\//.test(file); + const el = $$1.el((isVideo ? 'video' : 'img')); + $$1.on(el, 'error', () => QR.openError()); + $$1.on(el, (isVideo ? 'loadeddata' : 'load'), function() { + e.target.getContext('2d').drawImage(el, 0, 0); + URL.revokeObjectURL(el.src); + return $$1.event('QRImageDrawn', null, e.target); + }); + return el.src = URL.createObjectURL(file); + }, + + openError() { + const div = $$1.el('div'); + $$1.extend(div, { + innerHTML: + 'Could not open file. [More info]' + }); + return QR.error(div); + }, + + setFile(e) { + const {file, name, source} = e.detail; + if (name != null) { file.name = name; } + if (source != null) { file.source = source; } + QR.open(); + return QR.handleFiles([file]); + }, + + drag(e) { + // Let it drag anything from the page. + const toggle = e.type === 'dragstart' ? $$1.off : $$1.on; + toggle(d$1, 'dragover', QR.dragOver); + return toggle(d$1, 'drop', QR.dropFile); + }, + + dragOver(e) { + e.preventDefault(); + return e.dataTransfer.dropEffect = 'copy'; + }, // cursor feedback + + dropFile(e) { + // Let it only handle files from the desktop. + if (!e.dataTransfer.files.length) { return; } + e.preventDefault(); + QR.open(); + return QR.handleFiles(e.dataTransfer.files); + }, + + paste(e) { + if (!e.clipboardData.items) { return; } + let file = null; + let score = -1; + for (var item of e.clipboardData.items) { + var file2; + if ((item.kind === 'file') && (file2 = item.getAsFile())) { + var score2 = (2*(file2.size <= QR.max_size)) + (file2.type === 'image/png'); + if (score2 > score) { + file = file2; + score = score2; + } + } + } + if (file) { + const {type} = file; + const blob = new Blob([file], {type}); + blob.name = `${Conf['pastedname']}.${$$1.getOwn(QR.extensionFromType, type) || 'jpg'}`; + QR.open(); + QR.handleFiles([blob]); + $$1.addClass(QR.nodes.el, 'dump'); + } + }, + + pasteFF() { + const {pasteArea} = QR.nodes; + if (!pasteArea.childNodes.length) { return; } + const images = $$('img', pasteArea); + $$1.rmAll(pasteArea); + for (var img of images) { + var m; + var {src} = img; + if (m = src.match(/data:(image\/(\w+));base64,(.+)/)) { + var bstr = atob(m[3]); + var arr = new Uint8Array(bstr.length); + for (var i = 0, end = bstr.length, asc = 0 <= end; asc ? i < end : i > end; asc ? i++ : i--) { + arr[i] = bstr.charCodeAt(i); + } + var blob = new Blob([arr], {type: m[1]}); + blob.name = `${Conf['pastedname']}.${m[2]}`; + QR.handleFiles([blob]); + } else if (/^https?:\/\//.test(src)) { + QR.handleUrl(src); + } + } + }, + + handleUrl(urlDefault) { + QR.open(); + QR.selected.preventAutoPost(); + return CrossOrigin$1.permission(function() { + const url = prompt('Enter a URL:', urlDefault); + if (url === null) { return; } + QR.nodes.fileButton.focus(); + return CrossOrigin$1.file(url, function(blob) { + if (blob && !/^text\//.test(blob.type)) { + return QR.handleFiles([blob]); + } else { + return QR.error("Can't load file."); + } + }); + }); + }, + + handleFiles(files) { + if (this !== QR) { // file input + files = [...Array.from(this.files)]; + this.value = null; + } + if (!files.length) { return; } + QR.cleanNotifications(); + for (var file of files) { + QR.handleFile(file, files.length); + } + if (files.length !== 1) { $$1.addClass(QR.nodes.el, 'dump'); } + if ((d$1.activeElement === QR.nodes.fileButton) && $$1.hasClass(QR.nodes.fileSubmit, 'has-file')) { + return QR.nodes.filename.focus(); + } + }, + + handleFile(file, nfiles) { + let post; + const isText = /^text\//.test(file.type); + if (nfiles === 1) { + post = QR.selected; + } else { + post = QR.posts[QR.posts.length - 1]; + if (isText ? post.com || post.pasting : post.file) { + post = new QR.post(); + } + } + return post[isText ? 'pasteText' : 'setFile'](file); + }, + + openFileInput() { + if (QR.nodes.fileButton.disabled) { return; } + QR.nodes.fileInput.click(); + return QR.nodes.fileButton.focus(); + }, + + generatePostableThreadsList() { + if (!QR.nodes) { return; } + const list = QR.nodes.thread; + const options = [list.firstElementChild]; + for (var thread of g.BOARD.threads.keys) { + options.push($$1.el('option', { + value: thread, + textContent: `Thread ${thread}` + } + ) + ); + } + const val = list.value; + $$1.rmAll(list); + $$1.add(list, options); + list.value = val; + if (list.value === val) { return; } + // Fix the value if the option disappeared. + list.value = g.VIEW === 'thread' ? + g.THREADID + : + 'new'; + return (g.VIEW === 'thread' ? $$1.addClass : $$1.rmClass)(QR.nodes.el, 'reply-to-thread'); + }, + + dialog() { + let dialog, event, nodes; + let name; + QR.nodes = (nodes = { + el: (dialog = UI.dialog('qr', + { innerHTML: QuickReplyPage })) + }); + + const setNode = (name, query) => nodes[name] = $$1(query, dialog); + + setNode('move', '.move'); + setNode('autohide', '#autohide'); + setNode('close', '.close'); + setNode('thread', 'select'); + setNode('form', 'form'); + setNode('sjisToggle', '#sjis-toggle'); + setNode('texButton', '#tex-preview-button'); + setNode('name', '[data-name=name]'); + setNode('email', '[data-name=email]'); + setNode('sub', '[data-name=sub]'); + setNode('com', '[data-name=com]'); + setNode('charCount', '#char-count'); + setNode('texPreview', '#tex-preview'); + setNode('dumpList', '#dump-list'); + setNode('addPost', '#add-post'); + setNode('oekaki', '.oekaki'); + setNode('drawButton', '#qr-draw-button'); + setNode('fileSubmit', '#file-n-submit'); + setNode('fileButton', '#qr-file-button'); + setNode('noFile', '#qr-no-file'); + setNode('filename', '#qr-filename'); + setNode('spoiler', '#qr-file-spoiler'); + setNode('oekakiButton', '#qr-oekaki-button'); + setNode('fileRM', '#qr-filerm'); + setNode('urlButton', '#url-button'); + setNode('pasteArea', '#paste-area'); + setNode('customCooldown', '#custom-cooldown-button'); + setNode('dumpButton', '#dump-button'); + setNode('status', '[type=submit]'); + setNode('flashTag', '[name=filetag]'); + setNode('fileInput', '[type=file]'); + + const {config} = g.BOARD; + const {classList} = QR.nodes.el; + classList.toggle('forced-anon', QR.forcedAnon); + classList.toggle('has-spoiler', QR.spoiler); + classList.toggle('has-sjis', !!config.sjis_tags); + classList.toggle('has-math', !!config.math_tags); + classList.toggle('sjis-preview', !!config.sjis_tags && Conf['sjisPreview']); + classList.toggle('show-new-thread-option', Conf['Show New Thread Option in Threads']); + + if (parseInt(Conf['customCooldown'], 10) > 0) { + $$1.addClass(QR.nodes.fileSubmit, 'custom-cooldown'); + $$1.get('customCooldownEnabled', Conf['customCooldownEnabled'], function({customCooldownEnabled}) { + QR.setCustomCooldown(customCooldownEnabled); + return $$1.sync('customCooldownEnabled', QR.setCustomCooldown); + }); + } + + QR.flagsInput(); + + $$1.on(nodes.autohide, 'change', QR.toggleHide); + $$1.on(nodes.close, 'click', QR.close); + $$1.on(nodes.status, 'click', QR.submit); + $$1.on(nodes.form, 'submit', QR.submit); + $$1.on(nodes.sjisToggle, 'click', QR.toggleSJIS); + $$1.on(nodes.texButton, 'mousedown', QR.texPreviewShow); + $$1.on(nodes.texButton, 'mouseup', QR.texPreviewHide); + $$1.on(nodes.addPost, 'click', () => new QR.post(true)); + $$1.on(nodes.drawButton, 'click', QR.oekaki.draw); + $$1.on(nodes.fileButton, 'click', QR.openFileInput); + $$1.on(nodes.noFile, 'click', QR.openFileInput); + $$1.on(nodes.filename, 'focus', function() { return $$1.addClass(this.parentNode, 'focus'); }); + $$1.on(nodes.filename, 'blur', function() { return $$1.rmClass(this.parentNode, 'focus'); }); + $$1.on(nodes.spoiler, 'change', () => QR.selected.nodes.spoiler.click()); + $$1.on(nodes.oekakiButton, 'click', QR.oekaki.button); + $$1.on(nodes.fileRM, 'click', () => QR.selected.rmFile()); + $$1.on(nodes.urlButton, 'click', () => QR.handleUrl('')); + $$1.on(nodes.customCooldown, 'click', QR.toggleCustomCooldown); + $$1.on(nodes.dumpButton, 'click', () => nodes.el.classList.toggle('dump')); + $$1.on(nodes.fileInput, 'change', QR.handleFiles); + + window.addEventListener('focus', QR.focus, true); + window.addEventListener('blur', QR.focus, true); + // We don't receive blur events from captcha iframe. + $$1.on(d$1, 'click', QR.focus); + + // XXX Workaround for image pasting in Firefox, obsolete as of v50. + // https://bugzilla.mozilla.org/show_bug.cgi?id=906420 + if (($$1.engine === 'gecko') && !window.DataTransferItemList) { + nodes.pasteArea.hidden = false; + } + new MutationObserver(QR.pasteFF).observe(nodes.pasteArea, {childList: true}); + + // save selected post's data + const items = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag']; + let i = 0; + const save = function() { return QR.selected.save(this); }; + while ((name = items[i++])) { + var node; + if (!(node = nodes[name])) { continue; } + event = node.nodeName === 'SELECT' ? 'change' : 'input'; + $$1.on(nodes[name], event, save); + } + + // XXX Blink and WebKit treat width and height of

              $U#Zdf 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%0D`<@i>TMxuj4Lxe$5@<- z(j9BDsM{+GlViJ~GS6D*wpPXxlF2f!K^L{Bv!ob*g3hHI>Tmk>@D57Dq1L~>zyca` z+~;E(s|;pX5|s`%H8j-aO$K(9`aBJ6jt0MA|NA04SZ&lFP2OxI znSw&cil?-=UaVR~pKB3)Rg0*G;#MvNNAPTGG)){1JsH+zM;k>~7$8<%QfR99 zshsV?q#k_(o5r4}?!%}ak_jMQqQiq&zFE);TZcHj5ok#d$UzZ}s&Y0~Lu5^rLI)#D zE^4Lr9ZyBc6)mrEH{{Wv*%{RN?_nJrm0-ALB4_tzS)$=M&0_&~lQ}&N8C#$lRHJlC znh5-imD4Yo%DihGptR&9 zooZ%so)2COAyzP1k-xfMrU8FyC5Qc#5HrcS2Bede1iv_u1~NK`vII)*eRif?2 zqt|RxUuIc~CKPCuK)M+Ao}_#Wa(MM%K<>RkBpU?amg_3{cn)S(WTuY>yQd`UG;s%s zd8KbYM07H0 zm-_)RfxQ19-qwsjKgHQGc#e&!x17_9yq?z_1tB4z$9=*-Je6#xHog^U!l2E^VST`I z60>~Ckg}ktgUwVoENZcw(kANi)yv?N=gyw-w%qUtoO|-pNfU$hFU7}7+mY;x|iiYHdo{rhaiyp{uLM3G=iCIWYe35cmN(=>U5 zWS%ksCa2KsOj@;q)f}V1ZW9dQZ5%qf3LE^wF^^u+>IKB0SzJ`O_-P(EZ>8|B3h=A7)x5HFW=?&F z8jLfE>Q>me>{Nz!Hf#;Jm7f{3o-TE#)~|*87YZmB9h~K8hREgXM>9EWqA98~WOP>H z92LzuWpZ3{CPl%Ml=~Fohd}zEE0Cht8%%7B6&g{O%3U5v@%8Q*}Je;L2&1Lg`zNF*BVDl_7id}?nQ}c z-01tG^))2W3gn|Afd8DEk7FZ1P>R`JKu{2CmIh9k;+3u|H-wBk9Q2-$s*C72~EkiXqElo6&jVg8b~rmeg#O&9>?26Fyteq$s{>lz!F|-s?q_#^|M{X}1&g zS;_b=Mm9-Dcka)|kLKvpT$upCsL%pHBQ-eK39Mk>^Jjra4+jYrA#{PXaNx!^DoT%L z&#Q;3lAkX$_r?);GwS;7k!D;(OXzFKQ&gw}a#4%2yg+m0)sYqhUJZ9?$XjI$vmFuV z@pvv~3ofkT!WZB_Idr!5JT)7uZ(at=2E?jfOpPE+aXhmvrVLN~yUe+;Wv)W&+C8LS zVb)*xO!}xDK<&m`&#FF+EtND=MsWSYMB`JT zQ$nn9NjS=sNM0BQq05zvU?}`v$XXq`%5RYm)WM0YN$3;!;25E-#%+@>WWrvJhXg&= z$x=LcECL#y5VK3}b=%*ni?F^jfu z$?f8}s;v<;noe#F_m%s?VT&-yu=tW)i>pEU@7T32CP-*tQM|cI>I9KS5&#1ZH}sMX_&2oHgB?vw4F>@ zIOzb`!td1woiS!%DU(~KUodV$rXq~v^blej%yO8eIm)u4GDZd~2Vn;TT4ELb>%i+_ z0juBy#4($XKB40at)N-T<^RFPN7ku-R1cL{hH#TPR69~T)Mh>Jw?i`8>nLpg=cnoJ zXf%vg=H@1oNx2gQot_6CxpSe%dYhZRAsy+fOPf#?n8n1%Jg!;&9fNtcQ$|dj?lhJ~ z3xbj;Sjq*V-|+|aUMUw1>jR!{TRkZSUWjI){zqq4j5bdLHWhe-v;_Z^kK31&$;B)& zF<~@9?EpW_(2#5hvuNAfniZYeq`}OnJf1f+sfvsFNMpQ=i{)~2h6V^`75G!CQgV9>Gy$j$u>Hw@Tg$e+MTvQ#LAWk_vOzU;g8!+vCCn z+F_Y|1Iy|7mw=SH0;^EG{?Gro`R5#2fw%Md+)U0JGzko!pVZca{xBH86$fKNpM$s^ zQm`=nAEY{X85Ep#v{=YeeUN70=v1d9@%@v$G6p($;YB*ic!dVRXjSoLPQ4((^g7!G zImN@bYzlKz$Qe$6cNY51BY!mYw(Pe^Hw=>VSuhFOh;dBP@*fmLA}cUCKEdwnkz|pZ zQsRG7B!xGgA4v_F@3A@$Oa|NMyV3CQ( z(lDy6N{Hd7{fs?7~4t%sLxRD%Cy4Oqoat12xM%6^k%&g&&CTw2YJeBw|sJ8lj@tu7lGCM z`ZyW|{Y}Ovk?u!I&>D+Mf{Kn-EaHEb9)Ykj0|-1`G72<>K?Po8VfZFVBk){wQ@$k^ z5Littv{MsfH;UW6XqYb=acAUXNFZ?(22Tm@5!%gx7H}3IPCuQ=FzNsXHok&2h$A5^ z6Au(?Q#CRvb=X?2K7(qfxibnEu5WjB22udE_upcs2Eq4gidJOulX%$P8tP z>l{`J_OynITM07q?G#G4Iz7&d)YW z=}Z>Nk-=*4e}>zVWILtYKU^Y~S2JT&HbH?wNQ_csqtKNm995;G4nB+bAeb$KJW=f0 zD0OH$5L)He@I#Wg$JhDqVKznHaY~Z^myk29Izz8*ePJjNRj^?%G zn`~YSALi=hKT`SgblefEN0DY(Yc2OV2OO%zWoBT5OKN;BNHV}4bOza`TzM(e{IHOh z>t<$`+5U>dCd6Bm6+oevZGW{|3C+v?Amvu#8;HQc-2^=O=qk+)hQB<4_P0rh_UHQ%w<1{Y^%Z)WA{Rb^1nPFDUA#uhrv#x!q`Spe==MAKQ2x<`}RcUmzPr z)*-nYY7<{#pP`;;1)k#}pzpmp!!$@nq>yaKq|2RP@d0k=2yq+$NFD+glcA1B?5lQQ9w<%Cc zuUbuf^kR17p3nn3?S!!<@E;jZZ`%1~6hCS_Oe@|WE>N`{vmfT-BUI4FDedzL_1h1- zkjb>oWojF3zqMr`@MA6TY)@os+`ow?Pg!NjnIy?Fnff{@GRQvn$0MXJ4jYjdJ`l2v z8g~H&cM6AHroPGnEo6l~W&DtL6DE5(Kw% zT1Y@_2WfhHvQH%jMl?G!p=#^#=s6hUp39w&m83`@{6qoy%SpP-J zACplsH9TDR!@Jb=H^roz!^Z7U#AocO^_FJ)oNNHak4g+F!Qg~93r$O)_IKfI51YGR>QMd4a z2+)*r8K~DHkgo%3il;$sOtRFr&@|0v2C0u%x#XQA7B_!--)E#~l@u))1c3trja#3N zKE=e$nyU@4LwrTBYU%u;!?I6XJ}1M-FK0-rlUJp!ZU6E3#7qr9lfkpYlZWHa#g|Hj zqN+nMxg(P~QjLLayo(~vXSTwGyc={Nw<$9MM#DnIF4!Y<1obE7p{iKxvXGW(H>fh` z?OPY^lKYG_C;nZ*fF83!dlrl!@HprI8X?U%doq4 zbLgSsUi#CW)65}V@@3`Exj%t4`IFHme*$sxXH1>^IVb$Rl^)SnTM40P zmFen^EQZKdU|Ll|FQQanP^Un^Kn^q=1kAu3@5V~7BnovMj8aY){afoqj^FN(X`qAk%|l7F9NS5p`C z+36IOwB;iDg$ym0TMB|upv$U5&gXUyloC_Gwo17`=m0_~U*AWWnFfg6X`ip-?lPjt0e`SlHp5pDvPyuO{WnCy{4&sBx zNz_G?;b-z_<}-Y99{(YmOeu#HI0pgM+Ew|4{1#YWDQ`2GU=8Dyb9mRuS|BBeAJ#>W zv1F|fGhT|Pr5Z4~ER@h;6n7SEm8P{|?!2`!a(j#_Kq-}EzLUXj8))pp^xRzZ6qV7a z!EkadN5dXLW=R21o$oTpLu({iO!qWKL!EqthyM&z<+ z)Wc7ee9;*OK!gcYb`Z7uelU($nx<0jI$p)M<3)aqpK6rlv$B_mBhAI}^dTcn6<8nNgKRM=@w>@#{meH!qU-yI5fuim+tDpKkMY z(|G`AR?HHlD3=rTBvw+BN#HQzSivt33uMBHhh}s??8D3oCUju4v$~u%eIsA9jnAne ziHxJJ9#-3NkB?r$fsYG`Bd^rUa?xrzNiKsiZ995VP`qEcOn;Petp-o?nc(=sQ-MwK z`1-j>Om-@t)enZyuHE^3QBJKV)6wNVDE$g^bO0-bKU*`!(jcG@bL0Z~!L$IC8{IpG zTs?di?8So66o}U>Nv9gjlztJClDm6H5B*Y3Mh7kbZRhHvFg$LF z4Vrh8`hz!%#h?HLHV)<{UZbC9@k+@a`mIf%`y!NZ&;400kO6+_{6z-#7a7lAWB`9f zllEUwtN3=#XBLTMP7sAys>&fPe>?2tS8~d1<4>OR8?3~NvMl@yEX#_rMxss&zZeU~ zzmtLM-yN&RYvAInC`%>dFptj{CVz&$n_}M5q*mxEl+;gbhRWRHNv+U{iZA-4R_JuC z-|drHp$lNGVZw)AT3Ue>wk}FAh$L^AsA)+$dpst@eh#IvS#A|-HOtb<#o2uXaf)om z_Zk_-78y&_#k5XIj0B=g7>eIvH`Vb8dXJn)ca=x6E(Ew8Ox0V?@~*sjcQl)X2j?r)| zA1FP5Y$Rk9g*?1LG)~`>?VT@b6{wKGQiFals?;AvAMB@SVZK8Cr{ zAGB(%afmmUYtZ~VtmT5zDFxr^0HJ(pitajl`=dUHvyX!^U>K0ehjKyoDpH(s;!`C= zdS zNhNnjPC}vPEHv#){*cF9L*H7P;f9u@(vJuuNalsb*Wh;3qw-~uvM1?XfgO6qj(nlwF@IujJ=kP(Y+mOlyLtZ8r z+IxfAXxo^BC$eI3qnUHO;`$Ictd9_z0(C$E3eCXHX6VOr46(u%19i#kU9Wjpv@jwX zU75~`7=RbksE{2aw@t1jM^jLj(59Ztk0c&x#&kfOyhdn$LC#KhBra;Nqz2=siSFfW zr;H9mt;#gop#B&Ru z^xj)Or0!L@r6!0=a|H~It`3*H0?9dikg+zi0pr7zKcQNdu=cHa^8AOEMy=EtBgj087E)x!9J`4F-uRf3im`Uf5d~Wo{VWF623fUU>hk1v+bi(RT zr$UCCR8vsOqluI=pxkYGg-R)B$wE_9Tno};ooj~uLz+2MH|vMj*V7bKr*BL%YQq{$ zJ7N~RCP@+OVaT}QF;FmBo$V9FF#cd|+-N{Z2?LLG>(Lgo7t}4xX|5IlI>N4Aw5NLg(NPora%P3r+S8$h+5ADlN=m4R8_CHJet`O3egb9ubf5 z^VeT|P~|A-dr}O-p5+EYgR%Z_Jn~wnU~2%S$`6n_+VAaT&GkFWF(_*|txe4TsCh_5c@&?YKxG>MFI+o6<5@TW8)q5Q6pSF>S z(sR>0#>FcS1y($hvw`ziT1Kba<*M8IY%ay=PVLm5ZQdP^hSJ2*tsfnMK@1@zA)MTl z<#h~Cprus4m2Ay8H`j_~pz7=}LwkJ2-Xr@0$!6UakASmmFi7f)?uvHMh`ZRf?0mw( zQrceC@AbG@O%kCn#7clZJ<~(KKI-1qAHlzC-0PKWZM#;>d0cEnQu3U*7h(%@mO3&0 zq#hj-Dx1%R{gmd*Eq^t#XElkHW36Ng5uy@03G~bJn~VaA*g1##7Oyj!LOy)D3WY@j zQpz(yIvzPzVbwyZsFlpJ#(0(Tmcte+qHt zJ1?lil)x2{k$qW9IqT#YM><2r z35r#Vw}lgy7KhJ8>s*!MHUd!eX(eP!wI&!OvbHHR#l zIa>R-3>KqkzjwO5q~@9$3_Kj(riL_ZX_zDvZ&@tAE*hbzCpYQ(Juk=9spZ^tEVt)u zPRAd0#|>n0n$1>a4lO5UALl0ioj$}z_zc@Eg+w~przztTNDDP*^Io8Hwb+6zf#U&;rHT^z zi!+JPiZhTKnv7khkBdcCQ%x|DkXb9SXiX`ph<9DKnOPK=G!F1 z$cQW}Sl09j6&Kb!81$X6*n|dH$7llt9f7Tl67_`qUBJJK1WobKCjl4d!rznnpabDh z*grgg1^!*Yzl->H3I8tR-*+_hEjjm?`+|@O@zDp4MP%8Qch%#DEDDL}WZ0kIWH;J! zWc;G(J^&X`Zx|)o1(U3P^+wn(@cHxSIsTefhL3YvNh7cgyKm^t6ak?P zBSint)m#NKt;44;c>PdwqubnPywj-Ra$I6&=9YY&omKL3>ROqQEl)&cfVdphk(L`1 zwipWnApr3+P*hkCpN;~5Fp3Iv5l_#mCucv-4u9Z-1iUnBqE3LZg&(0s$QrezP!``7 zcqV-mn+F>(2J(+Gg3k#f*c`N~7)Ls_`zcyy6r3V6RVZ4LDRO5|f1qZ8m)ipL0JH&} zO)nUDjEvVD!a0_S%Le^^FsQQE>o!MIN`*fb^1N~!kLRD)^xr5K2rt#B@PCjmFHKX9 zt~JZ7mT1f%-iR^9*sy`(I_j!+%_>85tW~W%1oTtN&N&L}s~+P}9&X5-8X3&BF(dMF zMA%@mRioF<24Wv)n~JTZ8qgQR-@JWWkf-wn+%3@?w&pwRL!L?03fo zOT^trIUUZLd$X->M^4cABi_`BkCU}++Bz{nS(B#5ZXZsLLnv7Kj&dbdJAkQXE1>Y) zmg?EVP9t)jM}A6?qOlR!uNb6Mig);Sc*dS!Yg$rRi^3z=)Oj#i-pJllBTF`L<>~by zdUE%5u*&1)aL>$eZ}aHgGs8XO;ogQ{O~ZZfaMp%4@TYMvH$gO;x^!Q634O%I<04Hn zmFdJiZqt3!iHbXM4}LXu;{IV3p&2sV{hESyjtk%C)-&P#nnZ~|X_;H1n`E6Rl}+<# zv1u9;xsu~X!Uuw}vza9kyL2?uTaPP9L~JT<;xlxYVSp{Z9ipcdjTOQdrl;&)|IPur$198C8;%MLR{ zba)xRW$87z#ku(+%t0_jkTP;v=B8Q5xNllJbv~RAA<2Bd4d#gg9|;4JSlv97#}coH zixS>U+3>B0N6RPQZf^GB&*Nv$j`4AyAD_YF2JF?Hcb#r9A2A@5QBXG|F*Y#Vm+=76n-Dz zrriqUpBstsf`6fMoMOysP&XyT1jIL$<9p@jM&esJJ?nTeV@MG}EO>=;nPSJJ*o}u2 zRHezPCj|D2n=oS+BN${iQ4fp;sa_dKXoj?&ceWut*$6+!F{JW=18$1l=;t>tV0FE( zE{aztzrrLT4md&v3RJEbnNfLYiaayd!ny%zYz!_J#uzJQ)LdJsmwJ za%06#NaUWXd^s6Y;5e*`$o8}9$B8cb$Vp+5_ou~Th*NnRCAlOYDh+!PTnjg^RbHnv z!V@LMQe7?Qqr%mWYv_WWUc7pFa!&Pv3*r3gm0K7I?wCHJWTN3!h0R3t2dQFGMW=F` zn%!EHX4t~;hU`Ugpz8b(%Q_BN-dTDG`GVT$i?m-4Ga!~3jbVF-IDd6|N=)B652@Sm z76$biyGmwASk{ZyV-dGC$1$OykS^bXWKy3ZrWDli^z@VwVLGGg^19>I#%+k#reR!U ziR3V*Hs#gaI^Euu6CA7E9We5ANYD4lq&m?X9R9oABWHgLX3gtp1dCSvffPs!yY3*2 zCgmk51rd>9fJL;pc~J{cUO!S5@UFk*ui8irpLVf@MMN&NcvHrYgNt&eVt`{y>Bfhc zH=ai+0kF15HO>THgS#iGP-S)_f>q!+qH|yNl`3&Sj*AcW95+KcCec^B`mF!F=g6Z9 zeaNM|jZp(lWy#~29&OIsj5J8QmOKejlQJWn*xX1{N<;k^ekv~H-uZK|XZ$yMmybng z4$1~Tj0TCXI>+XQEx$|HrdKn(F9`q%m{7^slrRWfk38Rh%4eO}gyY*^&fElx@7c5D zu0BKy8D4@X^2!5EC<=lV^m{0OlVO~0m)w~^0uo*&x zZ_Tl|b=s16iY70nJjXKr(PWZ`U&58j1+HGK(=(IUS*|Q*!RLV(4elwfZg{B?Y>-p# zu!w!Mksn>HgMf>=tZ(l3@&RJmxN8O{1PT}~fP$xo_l{jfHu-WOh5ua67T-Ra&xhAJ z=FkHfD1z`Z<3iqrh}6zS$c4EGxkz4wT+l_xg|EATRuN(gm(8cnad`b9l`_Fvg))x) z*d4rBr-xg|Nmr4U3wA0XfZ8lNVUo1*i-6x%XBw2eq<$2FYC5X+2+4XxHT ze!)YVnMNWWKHBtqD*y zuQ1+7W7z&vY^GM;obZ9PO-ixQIZmi%@Z)m~_psU(MX*k7 zw$y3`+T2vpfQ(r4q^n1YLmRzn(qDI_ap8nQyj7RP1|0N3GPCsQMZ<#8umn2Xy-0#))J|uu+_&mysOD z$1qedXk{W_7ORUyyf#8hG_tSqy^z$6tQ%Xt0O?YBW$$G_Ki7Wa41nb#ji7Q@ql%#U z3WmL(3{Q&5!v_>_hGcR0M!t6^)rX_CtQ^C$cI-oyE8?5MD-=ij{O+Of4}Y+s%3B3$ zLdLwJynTLt`2YOhsJVT>+d@W{`8Z0Df+s^}A<-#)09Cl8-OXW-9YZ1Fs=Y6$TU zlpse{y}~sIPxz;=UeQhAc{RcKct>kL@k>1Y((hzt z`khD#tpYAy+34Y*K_~c>RXj@8YP)6-j=M7j9rVYQ_5{7EgkH>u!Y@o66 zrEFNicnph>lRjLh6!kq2s zv2jR(>+BN{nkeP|<|ekDYo09;h-w^oOlS=8J$exsGBu?r z`^`SR4aUIVa`h;vTwrFLHd8YYl#ek{>i(#lkNCT-he}+| zCy}iX4{fJ&IOzTS=0&Vfg}^5p%?2t|CY{&%%*^dDvjnoJSOu-L!;-cbCstn^(RK6* z`DDPy{uZWW!5qgF&q>I!=S%LC?GQV`_O+`;*f}LYaJo#V6AjTv!C1#Z%o<(vtH?kS z;}0r(0&g?D9r%S^PL_4Q{%r{(B@1-cj3Q^d(wP%Td2Y-)MdXK2vsg@v;aNm*1C|NQ z7T2~F*}Np*K$6$he3ndry!5|@(9EJPl8Lq<(W4oVUoyo#Nb$q4A;H&>;6+tkCKF(f zHOG1QYH?o7BXX!SlDtl`DU4WoIVm8S5>R0%>D)`RDFinha`i2mN=aO+l98+=6J={R zT_2}aol~UmD4%I4R#PnI1s-1xG0idI0a7}BLJDzURrz@bSq37j59miX_-?>SAkCK{ zQi(}N#||ope}yU3nGeIA(sV?U-~?a-`Wt@6a{w<|YK=G+#HuSku&Ra9h5~;i3*CA^ z>O;F3(SSyh(p-CK>0K-_%(#~n-oz4uWa}k_H_?RJG?6-Ih1vKxSX>fkAR>v8ci|D6 zk{Ss%Miz{6!BnB-*+??p4T&t&&q$phdy1KIWz-mv7#%L9cO;-ha<_OP1jUG;QWlDo zR!KC8ay7wxDP)=0{Ig);)UV&A#>{Q9BUL0C^X8?jAi98Hj~C_I9Y2!PTmn;4yOGC; z(LtMFij3~P34#+%5_@NC9LdL&RtWKMp7YrHpnw2xhZLEDnBtz=29Fbi_gsYqRwa|^ zL#Nvk%iCzCq^eZH`UD9DniwIIBZxEGPg$(zZaNpJ|AAUq|M{=T-SU0Hd%@8~ZK}lN2fPyt?YofPwQ)(l-iSE(U>*GE_q;Wi6{ZNakjJ zvnZScmCkFJ_eCCqqUjv>vaQX)VJ~)L<=iQGgx_&2QO=sMSsDRx#2xK$ein)K7|Z6w zeT*eQJBj((U}feg0!=hmHyX68zMhTJ9gmgX5G9fk(I-Gbv}V1y^e$c+PRKdBGjKH) zAuX1PxlmzRFl)SxLjpk*Y)G}KhAY%3VJBf*;?eU6T{+3>w=@=7q4k$3)EX42a}Nv(_w z*)#%zfpB;j*i&b;519g*2SwC}0C+2_)9_^*f1kDwXeWhGj&!Baex38toa0MlqD45qpm#Zw2P)q#iFv+z)4 z;iPJPBCNBYFN!I_wmaZDj-6%#p!!At1ixG^$U^7UNnOm}Lq9Z{{j+D?LB%g~uUIFJ z5?-gXAwVQx9a}}yMZ7p>>(hxjtEzLTI%UcO4DP2E(z2A{NAcb?1!0x;&XdlRW=aX? zDOcu()Z)W(ef>B9{mqpdt5HfPZ}Glb(=B;Tk?ik9 zc@TA*`(^A~)G8@OPhL>UKfcKhFe=TlD^ikJsK3Ev$hE7&0>%)=v;!g`-VH{zwjaVQ zho-#aRMZg5fY7a0?E6jOZwtkP$(C#Lb}>y|h(g<6jwL2Lu}b=Dg=>!sjIWmmXgQd# z#_NutUAw4D4p_ZFz{a>&9>8!u9w0tmpnyw*-`j1@`w;rJJ)tu96;izMZ*!{BFx)68 zrw!T1<7X4Zk6^oWTEo4}LHu(8rdZi*0(i3?Px2`hQ;zsaFCGOBKAE`T0UuK>k_?Ah z;It|wSLM0~s||j*(3HK8c!(PMc&*Jlo9NN%DhCFnkegq>qbWd^^FvXc&4-ugZ}t@#sdWfp^SgnMn0f zRGKp43xi9cHalJr@iYj~Pxm%!sJRDH+V$iNRhMkANB8oW>GatR)k0^^v{RXhn>RY? zWsCyLN;8Cmog>^U)_}5+Ff=p)AFR1yEa>q^qIyxi=tm~}vWr1|UY;)gySR>eW`9bs ziMy?)fsF7aK;XO9gcCVYtg8Vz6JY2 zuTHaqNF5vpps+BJsUk(UT+mhGSa&>@f&SLzym(i$0Tdl9Xf)tOEVfL?+RoLP%A5@| zm3`2O`qkVC>qQp+u9{7*ja7EU3|m)Ov8BI}+dGZG!i^I)C~Gn@bWEmIJ%6p1z*lBR zokcd+!PUr_Leau-c0H};g{|J{Vqj(-bjWr`!&+4A#Styhlwqle9$%EGj0=l>IsA}K z@LN`$vYi6;qJ-V+d{}2EMS&adaC9yQ@TP%&=igoMK~qQY)IIcpCzSKs;jsU={_#fH zwLlntGht|Q)m#(0PmhHnCTLvr*dj$(6UCHTCqtp`nP8}c_uGVcadh%-wAfSr31ehR z7bWmJu`;_{47Lk@Fhi6rw}DngBhV>yRsdlKyufd-*DCLDsM6rb1OZ*41eh*bqu6>; zS2q>Q_l_zgwU8(Txvo_%q=>j5FmcA^Zg6U0w%*_>vBD9Ec3)>6+^w+@pf<6w7}qQb z*xux*{@4D zoY9rG^?bP+@5u8Z(A{e|pj=gRI41T)cj`s8V`#eP9dhotky({f3<-RCvDz%8gHg^g z^xJ*{KEK0DPLu{zVb_u>8WKiIhPA$9*ob|-ygVguB*XH0{sy^Y#5>y**4C7RzIJBSqCp_Ex&aHRRpxEd{y#KmM>m5XyY%8ubJoL_6!Z`seVpCQJ~jAu+2 zC)xzWvBQEJ5lOCp1ST~$GcG){xW z?6(ZQv&ZYV21{;Al*O;stFT^%k$AEPi1|@1h7-RGA5j`w^>Vm4ACP6M&A*}ZXJ28U zX2x~Z(%5jw;N?mUFy6**ANN&f(8|%Zw{Voa1)XmAcJmV8bzX5b?4fc$p2bxdn zy;;E4Zy-xv3;oCB+G$#GH<5rXl72gSL3KRYf&1fld8#UQxCW_VqciwUIu^#Q7Eb2L zbHM>Wgt}B?K^(#lopBQjB%)f9H?orz?WS7*r={m`VBRN*IRtE$i0H<+ud((c=HPxU&q7vPKy${-NGyAHXd$Xp^s;vb|G%0cBArs-oo^xhA^Ghw zsKKyCOwh&K>a9}MX^5I>*&~-}iTM9qL6_J2449d~{8u`#xY|$PCiq&p_+cSByJ;;| zbjHb5osVbglucJmme$;(Hq5&^cs;&;4to;hoYokjDk_gr;TlFe@1S`k9)h~@J)6Wk z2Gc{P%V>Jds+L^MAyTN*Zax!;7X$Jw;Ls-Is8KIRBjCNK%gLQiL`y@C1 zaH_5V|yO!nN2YlIGi^6TFarP(I z!`Ze&f}uYaKi9>$kuej@wo2Fpa9|1D9U|}8?rpeq>fTo{w7L5N$YT>lge`YYH&pX~ ze_zaveqf_y z)8Ryqs;iN75rv8mm#EabWh>qyE7CQ=&smjCDv*cgN`G?#g6I;fSdeZ{RgylIsP!Ty z;Nf2Ob>!H!Lcx+gP(`#Rp}NjaSi^=l9zQ82!|R-x`*vyrvt#UyDM9E>IsBdj{;kxM zN8|OQdOiPsXIjpdi{f|Q6S^B`WtTO98{;KLzaGN3^J+P7H+8W+djrKMs0&rE@Mns_ zg;S+Dka;R((w-|}gs2nKm6#KxSwa(;se?EnYgyl;)q-Q88#gUckMqqY>?&Jb#1CAb zmSXrey0EJ?hM(AI>}w<4jmIxBHln_*x*hGgv=c4kmKRyx0&q@9uC_GDjC7c*un&I7 z;F#JJmj@@`!whJW(d~Xt<)&rhmJ#SQ=SoI6-_lktfn=@XESzr*W-yrwus^oKSh(8B zfmFJ^S;ap#x*+=Lm@3xM$D5u|SJE9Z4U*}(uE4+2{Tiw41;f}>hlC4x4 z+_K$7!ej;IlLI53I5rt{!~Xoqj)-Q|3vS+GYFMspNBxZ$EGBAy_fM(bip~**ci-;P zkp&{M0>P`HHlQ$`5RY6jPlM83=n!9*9G*)OGzG*kP2Pc-5h$gU3}j*zDKcZsT3jcx>*VHJdXT;8-kq)1Ki?un8+8U!!f~*fAz7 znpCWD0UH+giExn|mM0LCV6g_P(^!F0ly5qwL0#mgG(71Xe|mG^{g;N?lg!!SjrJ#eJ?#^@b%c+v1^?kQOFb~gfH@MG$8&kjc-OtGhn>^X$x+&3aW zag@-EiQD-R7HlV`x$}%}sX^X^r}fx4!@!*0Sj`nFboiCH{!WD2yM|KpoX-KNs`-~m3mkt7%O7eoYKh!pU2)3xBP zknjs%+!8%7_aW+}w4?9p$9Rf@$G^*yLx~~MzuA=Jg~sGbz{)$!vjr}kyWOTjCBy0+ zvjv56Gc~r2$Gb8SdqogX_+VU)77;7-+B1&S2K?|ki2Jd;Oh-n+;n0So0*Bs2Ly=U$ zW7iW#(W-VK_{sFs;RiajN`7i${dlE1=G26aA6iq7RbgmHjY&LQRLXTn0wSU*l=t%8 z*`zudPC98FhiElj&BJpZ``+XBtS|}Exyt$gC&IglkAxzo;2<8aqj%{!1d=lLqD)@S z_=?YL&&R}PeXKQC^4qEyq_+)BDyk`0quV>T%b4Bm2J7ICX-=|6Mi?j+oWE^H1{J;=q;p5za1U5h$9UV zngrciDR(q9Gttn5^OJ3lV|m@44v2>cVqnD{vlK5-9vAe96d-m+XHft_oWWV=Zw0kL zU~NeDjFgXmQ-mRuHiE=@rj)oR*GG;VYEk8yb%*RDho^0i+z>7x!=gS|$hKpiR{9f= z`X~2(jfK25k8V81q3)oyE3?_Ads#W|IWe^~4zjp~r>%jq zSd=WqOS>*=KAfIG1Ta-OX3LhA&G*A{?Bk^SG_0?NVe>Md0?wn}3|Nt1(rG=dP8B)! zI`rdoS`9o_-sXTCr4b{}kv#jvh^-BT5G4U)C=hNdd9dLbwTW0tkpu8%6M^`J9)|Sb z@1`{Wyk*^r1SreDk_znoRw&^P^id=0vtW5Tsj7LNTkZlMs0ZC_BYxsm!)?S;GnbpI z>1xvr(rVa#l7ftvZ6#;;N(}|HwkD1<&(?3I4iNn9{Pa2_0 zZU{;e(9sETfE`M7890Gc>1Xd+$`ER7_Z;a{7sZ4cfb@$ z`6|uG`7bgKH($h|73B1Y+M8AJk@1OWff`~gkymS!Y$Lt#%WYTtDn+6EzPyC0iirN| zw`H*`-VW=F{O+NaYL5vO#dG&n{o;a>>#;%Rh0XV}F2)p>f(Eryd(+R#vz}^YQo6R7%d zb??;T5NGIA6vG6Ho5Xu!dD7P=lJ>!#9*{8kM|G#ML#|P~Opr^-M9`%mri%Mlq(yx4gd%?&wOt4pT)FN&airS8l0Hhk2r>JWi?Jw7SP*ts`bb z3(dd7p7OTHA(0~!EvL8>bh&}zBcw#VTURw6H!OnNQcZJ9TA|gpU6D5lxl?TO>wC`C ziQQ%Nj@TG=nvl{`dUW^}Mf2H@s#{R3)b;_gm<7K}+#{>6NDFOhNXfN*n6G{t8-AMey$YDeQ7xXbi*fj|JF`h z=H5v;`B=c)ppojjy~PDPgQJ=2^=UC%+ROChrMWV@A=%mw7OyclIHFxw1!~7QBOPTo z>~S%plza)5^X(-+Q*f6T7-);6h zW2~fNP=Ja-3xeafg3qHSD3>uAVAX;j=&OOS6ics{Y~%Rc!9}^Fv12$YYgs=hOc)>* z_57!DTvV(519gw}U^bAhGO0lphR%Fcfk55bjf8Xc$HC!{gyqDGjqxfNb5!2IWx5_Y zPP%hKQ)63}DU1Ur!zsuYG(Nt=oy=%_?8tp-b-Zd@{Hn;+IC$^f7ORCHroDa4X)BuR zN%yH#4Ir;&dg^$)GA*$8JfR)NUziq)A)X04y|m$;m$5F23&K%v$e{7vX22N2BM84Y zZRN*KFH#Dkbzo39?%ja?r7&^5NKy{c=A`A&Zb90cZmLo2lsiMlm3Ov*2NUWyQI#Hm zP4^PQH%8=Q7S&^zbi1q6GZ2%`t3@~3N&R&o?-7X#$SEH$0fwU@-#8i^U9I2UK*&~f zyz2}uXJ?(=NP&JJbX~!5H^$%^jaA_^v!0LG7OjF1d7);59UV z6c9`U@8%dMC^Ipc5&-7X#m3Qz<7Or3*|&0^^^^rVsPVy`D&)E@O3gzv??y3V79^)5?6Cw4^+uAHHIrAj1s7S|c% zNi}mA)c#}V$Tb65cZ6#pxuv@`oSac0Tx^euPwP6#%fgksxZcEuI6#+-DSQkpDM0Af z@?`t6I7hTF)rXy|bzvtMJ8YoB`NB!&78xn3uW1J9nK8HoM`P)%zFK9>{iIWX48P#- z)hoo8lu3+Dufl@F7aA7Uw9srZ1i|0z%G9(bgH>rjs;fC07WN{7!|fL=Z{}!ps%O_n zhjAkP@r2&uKw!k9Wcgk=Ljxop_KrF)S^6kM$Nvc7iNXpL(xvnBNm0r|>uNZkm9w)> zC?t)vc1rySQ%uU!0+qWv+4knGged1;_M`#MQ683i1|T_dwHY3Kl#@S(QuU(N{PE38 zd$dQ=B|)q4n#aV?ZlD&OrW3h(y_1^~tp3F?3QbpZosmSIG}Oad5d#~&sA%mEIx8=# z?ri*$laldwI@@)RHWY4fv?VPXu*fjrIF{I^_MjHt6INBDCo7v_eeZ#sQ3=?h!bE+n zNJb`zbRW6D(%HgzN3AF)h7lTTUP2gY7D&RP0>LCaTc@OvHWEoospQs@Ng$m_2_=}h ztC(WT2qB4y_R||VBfjOwR3SzkXI4FHLDa%G3c6@EZZ#@*_;EIb@flA3tllPi87)au zu2CVKUV3{?@MY zg|=Af=Kgg!xng%_J?5}`3-4yui5(uBn=Zybw=W3w{P4Jy=QDM*M-5e$l;Y+~dX_p@ zu4GRazps75clvx|+wHcoe?B$7({?cG&ap=5JrbdQqn3m#4GFP#+P3)Eb)8o*^=twH z$%qUFi+MTCyYYjWNxG8?C1)HxYqU!RmJ|W_WQ$CJlTCDl;pH}&bUI&l+C^%*lT#fk zI-Lf!qELXpE7aoOi9~)^QBQuqRDk^5owa=MRd;QpY(Gz`Ke|dBQbNZvwx$G(rO}^H z1t^x91Zt!{)v3}%98Vs%OaQyfUh&tR{P36EB`fGiJDN z2`elP!Yqt)A)&@^8r1L})C?j3Ys>RVX`^)ci`rOgI}K<9i!dZ)%?Kz0R!7)(YhU6| zx&-2S&7N6Ix=ps%P;?8^YhJ>T*0Z}-o>IQ7!m4B*i-r(^fvF4>)hKT@yDEw3BFV{` zdWKhWNkt5lL!yC%5pOQS?9>5zG=I8}4i@ilG4E*}6=SX0xER4q{ru+nel@)WSrG)( zDWcG?(j9g>yNO{)Tp78}MYdBoEjP`6MJlDRf-zzWq?UWNwCS~yrTUl>Bwa5v*BI%a z-fCY0lY*8BJtNPb@o+89`M{6KDmsxInp?=TC%_h^rtK7+V2bYFb-gx=eKo@);N&_- zl`f119SxxZsME@c|8`QcA{RtZA`56p*WXQ&?Y zwZSoS#288^az2_AM{5~@ zphKEBl;&vd;e(Cg!w1xFli#+xuYww3I*R*D`w}Ffi=C6|1ANF1IL(6%D&^q=IJ3{7 zSo*Ve({&J&bSzVWQx4~xLd18%_(a8Ia9Ymm1?e>+@s{r9ok7^hj3ZN{Cs|i!8qTOh z#2Tameeg26U&ZlsO*a*FIjL+P1{gflWU#dQj)*K|^C|UtF{l^SyFOpAp!6CURO`SZ_{&aH&BfuK zTi=SHN1RqgNkyDc1Zr$IW-Qj-1lsRMBkRF;RyDrhp^eVblZz zNDNdYqi94hiH~LQboxdI5NDeSm!Y6-Zz)lgM(Y9`x|p882gP3r{S=d!96NzOuL#kX z-(rbt;U%)rbwp;m!Br0A?pcpL%iMQ5t{?SCwOYSY34O&US4SsUdz5WoA!qa*mK5_? zp6JtU`vN(9pj(_eZo~s=+xk=lYT0>uWjjxgFw@R6G%X!X8w-+&qXB@zrrKN4J;h2B z_ubrbQtz%ZTMBrmy~%T<0GmxTkFQN1+fv|5W0c#UiehY|g4}#Te^~Ux*j$SWWf9mE z<91rs+ni)xxgM<}yKv#bL=xXyNy_eO*5^&h2ykS#WXJKILM6&k#B)r!=2Mnk#mOF- zC@|u;H}{yM5*EZ1|DdVEW3s){PdbCzu;?`~FHc;!wP2<8Bwwx~uSghD5z3sg z%UqU+A8=yXPstsv&^^&=JAh@la4wsX~8hz>n7csd!&)m@xmeI#nxX`eeIv? zP*;6kks$@egpQ$Io)70kSPgS0=3|;~C{P@uVnoeMFXM>aF&T|114U)$@)WZP7!Iv< z>V$HpIYe=uKp7F=XMk#HIK$*SXYrtj|bE2Ey}2`O1wg*0dqhJP&m|swLiGON4{y}i)t zADki*Z0ay}0-rB-z45^5-}%Bbv*Pmht0~#8IR!=wF%+}oyY2ExG~$ca93Gul6D;3n zs${njqLJ|g(N=mbR82>!-iZW(S7b;5vVf!`x+Uf1Zpz>dp+`-9KHf(0U^p@4ccdG9k-)=DbGY=8My5_r zUyIhpC79?z53h`zc%EU;8dX)d2+kf2D-KjUFMeAVx8Ou&{c1M3{v)DQ)Qtzg+)OjUX?^6e8G35}m2}lyoD-IN>2ex2)`TM1N{?(`ut<3wGFW&0+0sa481- z%Caen76`2BA-Z(JUpN`{xBTdG32w!0)PC^%RW{y&XDA2ey8=etY^d z;^AHhb?ID5_)6=xmlD*Cf6gWSXXvHBN^j9am_yM?RkdZzk;6QDZP649VJa=D|&+w8v4(%Qm?V7h>xv<96^2p%JRu6|_b( z9Ej_ga}zbXwTsk4*wqpRe_Vm8+rqL_Gh}~H<90-L6q0XMWNh4EVjGpzG?J-JwXBs_ zl@7g3RF`)@X)~!Ae8e$)gXb-8CO^26f*~Z#hsi^H<2S?ExSE!KD>8jlWv2#f{;kw2 zp*qP>=w7zw0ZC+EWm}t@n{IFj`Z=fiD8;>RzNTo5PageMrSE!20~D|JY-J3U#3rY( zLP4M|$4_xXt6@C6>G9Uk9*zz0^A^Eu{l2-?MxD5m9>>(DF(r4NES$oF* z=T$aAftHaNdCzs1H*Cd(xX<5mf30I>BMPYwP`cLjTvWy zvAANiLknG<_4`Z#3*sGZIX&w*>_DeN;7V9hqv7oJWO$7$p=mzjx;bskCTeEDLh?(; z>Iub1XESg^A1!BtD0q6Bi{T95fn*v3N~gxU8=6ef>UaXIfHokI8YYoMh!uRkoSw{v z<-|{6Oyvvht1JBSQQ+!n1GCV-B@lV-Kxske-)E%6THCMY^X27&S5SiL5I>d{QdTMP zG{bd*fiX3j6I9r2j7H;4c1P)d*tjY$%8h5FCYmiK*ZoKJ zMKSLG5tT+bVP8_weN}Yd0A)HIi0z`do6JX%ex~p0v0w!r)cMELKzy?_-uDJIBCzg` z&$l)HPEED8z@0PzE!xYLHoJ~pSB}xZo!D4vEp64j}K7aXxBm0_BgoL^xjgU}GeDH%6GvUJ<#FOjdy|S^js-%Z{gH+GI z|E}6(KG0)AMpjFcB_gp8(n{pbPL&I5@&i6{;qY|%LF|Zb8+2OP0M61~i(-?B{yd;u z(Ue>>hM=iWZAS|GqSG8!V%Rrt)6u6)UvsK?>@@{QY!zleuiKUMXt%K z+t~aLH-7@hz1l7uy~V>xVSWw#V!Hf*@vG#HEY4ykn_;5*jUunM)KP)pB8Sfu485*H z{^{02i5f=cG1|ZHvn~9rdbAvuRW9S2fUJIZa6YX03v8fmm}ZAkGgQ@NQeC-lVC|Jw zM)Ymk#7FP#_HB+hwZAo+vyHz&|LOUYr>~4CgW|$>o7q>{HvCWF@r{f3<*0aFekdky zaAbF*M@DNxMH>W2m9EmO&c52q?nOQIL%jC$ID@xicopOEN!`iqgbrsTt>xxfM`#vg zGcE;0x4?{LrTS!TIiKX_sElRd0eEe zzQs{63}x_6kVz{9b?4TmJq5i>kx=S-C#_YPrgWWClx9Jbt_xkZZQHhO+xAzstuEVk zcb9G3wr%Uw{OeqtIcw%3ZuV8g+8LR-G9sSWmD+q32lP0l6593HQghILuTvHAeY=?7 zc2Fx}BOZ^f4p6GBRy{GR9NDH#Vy)+-Zc~J#+Iz`1Tgwo+$@Icc9&`hJxdToen%*G= z;|R_#hh+`HT2qbFmn~X17ej`f9D;5pjRw?hnUIuJzV;-rI0L(m*m`75-o~b^xI;Z~ zVb_>;w@1iNx%X7uqU>nj>OEKpYYDq|xjQ>FJ9|5X1uM0!Ca?u%@5_5hj=PTSdbyhuXGbac}*m4u;_Rkh!pCz!0kcP#Wu`eoshrnE$&xnl#Xfp#x&- zu3UcYpR{{iB+YMxSh_bATPnQ^?*7<5>$wNw6_KR=2`g3M^QKPOs9V|Lk130#sllx9 zUJNt0TiEoY0L9dz43GrUz0;P$DZOszD8U5UAqxwx&jNqHp zLA1@T?g9+Ipx)sPA5@|_t{_u+^xE_=2U1?K^dVhiOOu6<9HzJr{`&4&Lfa;BdNtLP zxVPC@s4!`EFN*NmP<5R{_5L7#{6$V3Pn?o}z>b!TeWGa$a8~MiZ8{u{Y`eirMcL-w zL&AjJ@EmqB#sa0y5o_Mid;v0iTLrvp z%9GlHV1mF(De+iLAPvS@(934dA&{as3v583du!u=AU5sp27|hp6Yz2G=^_;!%cHrP zwsw(m1k+r6qVJ9EGoN~zLU5bpF@8w_+#Qtz91UC^|25M!GhyJh0P_s%=ot+kP}Gb5 z9bLG&23E*N0}+jXfcNm`2zn78dX3)|jbe{O@?p`1lE)qrxd(iH!q|QC(OL|4Y%wWa z>*RxY&y^9(KE_3yyb*j0W%c7x6w)A0>pG`UOxTvCgC{zv>W@b)+Q@=2E zx=UYj6PFlO?_2+>${jz=OMeK2Y(zi_$U6rfqp&5uY@@q0)i+RF@Qn37O$D;U$+@r` zbgrcjJ@DMtxzsF$v`hDkn>)Jgl80+PK+RfkY?OwM{ zj;{Q89W)S9tyzt&S-QeGU_cHWK^ZIetS4MUHOM8cYcFStYW_~U5MI6a*Q z`M|Z?p3nVC0$S*=aE5D`(UZgmoD>=1dE$#Crg8X{sXDCQdK3Qfo&)%JCul1-utY2u zNq7_KW8ZY={=t{wy1OMi!r;O4e*<^9eeHnRa(*~w_pEbpPaCok-KJ~7rvnXXv9m;v zf{X67Kw~M*ORSW;2GrUb1$2%T@u_n|`O%z&XfRdqEtGMwwGf zgA}YT+eST^W)Nyu0>{Rph`E$7XO{6ni4!?73qc@mg1LMAM^6pDRg_J=-{W(_9vCo6oj097k%ES;fjl9i1&y{$ zi_9*C{!Ma0vZ~Pke3+s96lQPJvY1au9`#jIOrh4U=v{SW$-a6D-YcQXYEQ~W+d>36 zJ&D0z+qeQ#k^X@92b^Q+-4Rg4CPv;Y_^Y4{0}bMIi0>Kzi1j8!IH+2dx|N_53~nrr zqb~)1`#^@%*g|#hxfrn1L1U1u?Et4AAw~n|_eX9Yj&x<=9b zF%hdDuSSeb$PbFit4N&GA^|zZaBAgj+C4Q3aK4{4r*EIXeAwHW*R=OD6{OFa36bp7cf9TO{4i{<9&Sc!kmAb z9-e3XKv!vuqzwM$%2g*WrpL2{a+X7ZTGhNH>}ZhFeh?M8vGDTR zC!vo!C2@S{O~0eUGy|srNKZV=MZRSNjTk=KD>g3YnjbmDYUYkc9L63@hqwCc{P)Ab zU-GoH1~~S?Bf38o8+7ehKrRu;^F!2<>=CYJ~7W1Po zwsudN$-wQS9D}rZe>xQjIywR}Fe_y>%c-g#qXGFS?iW%L)>WU8mu_zAphq6>TJ%!y zeBnDalZS(h+-14B$YQK|-7C?9wT2HragrG%aIxNo$RBTB?=v7<<^E!w*4pZ@mOVn) zEb!i%O0c%!Ma)tthsM3x-}4;?)p$#Lpx)T>mG%4+g0oipx)~ic2czgoK`4DXO$+bT z#DOl^LNYGxx9XKNLy1Ga7fp(_+M(QZq+0&waK5F}X}ZthK5#{^OVQR{^(^$;1YZoy zsJ%&m?u+N26%UJv|r2tnBUQB%R2qFHLmgT2+eVLTF#C1 zf(x_Z-)F`E>T_TF_Z| z?{`A`!IXzqu`PT`0CAtHu73+d-$_Q?+KyRDm2E%MaB}$D_I{dXtd!mB$wHiYfgG zrj1o`c+U-2Pca5c|E@aIVE6Q87=W7%GvF9O1INZ#mObk__EYM88-L@j=-5bG&5h95 zIbrqBowbSwFK(nN9}D@$6@(xMTWy9CtJJQ#KOLrDM1&G@5_8DGo=5VZOccEzg?Zjz zj@KlzDMRy8E-3Sy91$dFw(DKfx?h^I(2H!?#3cY(DYI}F)}SzD`S~9KKJhVp>&E)>yjvWstumn zfC$Ep+)srusIVU2hBBC1eHfyfauY-3esnkaaWRM4YshMa>4l2ELzZS(9@%E$-2} zb%&$z9=7j!=y!HB1`I$x(=?NYVu>@EoS3yJ{&D`9^iR}zr7?SH+GAYl^dYedhwGGA z9O4B4iOt;YihR8O9_no*%LFi$ysGSc48cNZVnV;GS?6J9II`58OAU9qNnax4)Y4)W zGEcr^RidW&S3KU`_lJYwd_M=O%$?_=o}qgNEQh0e2j_hnp7fJmq$D(a$o=*T{L-Ow z)sTs%_ScyUjh)2?b2Y7ARQO`-X-65+)JBr8N$UL@QYc#I9>SV=M8rmdUy(RM#7E+) zbSPvAJ;^N*h)ozLLuz!>Q&}P66a{F=pC1H7)Zmo?d_)gDQ-TC|1rQlQaiDQc zE!C>yoL$zNMpX(WG?eCJ>tu<$U|f+dHFVc3ZOalgTT5d%>WK*P$Xk;0jGy~)`+!Do z3#Vy$MpxU;l-BJU+edqw%440g&!TDfG0dB%&`9s`>KsV+hkO@oMN?Hs7-!Eo0Hid^~9`MHnk5AIZ9woLGMz zAJ@X79a)4k?p2%~g$<}`8fXMEK+`DEUB9jQJ5&>KAw6?>aCGo45wk_P;}llF{eLMN zxu}*AX^7*nfzRLa3>Qhf`Mg!&kw5H6D8p>P<-Ro6a+7p7Ae9yGne+FAM~yd3e&mv3CxENJ1aA(6uH*aoUE0Gg zofsrfn^46YO4X{~t9nzWm8)IsZay`q#YV7ydeeRlLR^o7J#Dmav{idi?tT^2?GNt1 zGZZz~UdqgJ`_aQTC3r%hkAYd;>pxw}RSLyZWgL+eC$bj|HpJh7qK9U$6Rdl8Q;QxN zU3bX9mog@1&O#$y&Pi#4iYr$aC~CZ}s%EK7T7iB%*2MUmRW(@er#X}6vLlyaS2Q57 z*@M(t^*mDZLbO$rQM!^g{I_8EE8_t?TjSGh?7|-pOt3a7-P}o`X>-MWoVG0T2r(*o zkuZ&0t_bEPrXakWlf9fyK5_b4Dn|}G=aju)e$8Lnk2lQIMH|v3PN&ZneSYcn`LP@@ z^}F7te;@auky6pvLu_Q6<}U|diEs`xKXMhxWw!3m&s_HNo2s>upuFR7tX*su=zqj_ zvUMc))}Vv;IpJ;0AS(v}k3If2kqC$h!&;v#=HQkIK)gLbhrd_)MgnQndQ>1n8Q~k@ zCZDn`%O-1gyGuzwRI?>cvA?R0cYG_(<2^mz-#&P<*9b^mek~Kc6kBZnoUJ_ph#t_s zY^<%boQP(&PDe+pTANOVd) z=|#rFrlB&_m!Ar~fmq$B%DyNLLz-4Kg&CLk1sEyi*gXjym$a}#Vo6DiqQyT5uxG3z zFKN8PrVNW{pY0P7i5ZJc&cYr}H>wUwK!23^jmAOGxq3ydiI%7XMv{YZ{c5oP(&FH| zEN~$nSDXtgK1SN_y=Qtng}-I#aoVtRQW}#3S)6ZZ6gEj1BKMo+;H47cDa&J&xFzj+ zK8Zq}gp((8N8o~8{2tBD3T^H=IEw;%p5vq!qWcyufeZ)Jg5w$5YV8ri=ORuD@HY}B z4LpIY&(zuBWVXDO&U*xIMLk==1tCQyF;jfd$ltL*(odtH0svm^vCjcKscjN29q7!R_DW=W$6S0H8 zc~rk#5!Fuam;3)cO#msT5g~1x=-ED0t!-d&RT2krKsLQWYLyyg;JW=T-NfkP`N(1x z1>ar@fr2+$3_)YvUbv2;B9deH`2`Z4H^7g?}%_dw~iMdfG} z^z04Y$K25iyI3>r)Cw!_t1Y&g($Q9WlW1DQnu2LYv-14)D8JhY5s{sJgx%rnVbth& z%u%!J+G_D^0*)&YD(3L`08`D+{gKXDgrc8R$*!)q48Ps?tt^W1}FV+l^Bj4sxj7ULUT4;@P-e_HMCmbk+jSoOXTI zHzUJr0__tLGLEm%Ab>$Q&hBwhY`TcsicZyN*}kc-CbT@w7iZz|Y5CeOLbe-a377G* zgJs<>Yc?pWD~j>$(N9lb@r0+>Wln2@mCqATk4d4iWdFT_j|m1 zMJF^R6}-)UKdBy>N=rSB@d(f|A60Q^^=>mV-C)N+JC0|gkb>OA8UUs>_?swMq#mmq zMy}+bMLLH-i%W7ylt=AHT+x^stWzr~$aNqh0(<6>7Z0QeKaC4)r49Qb$qH+dhpJ%O zGR7+Af^MzHRobo?)Z>QJDfEef~78}Z%GG>Y96d0Vw@;UOcUONmY5TP9BuoK z6GfAK6o3dAC4szSl=gpw~#%sB`N z5fkvmm){G7WNn3)&O%|YMXMV6jmsq`*s*;R> z?(~4|5bs)@bSdP#mWOOGOnm@`jiZ+=XvFFgwAWg!X&mdKeJI~=LMvR^;Q`Hwb{fRn zoKKWc!_AjAO8Q^l`-XA!2&@t@xu21O2umn&y7f%eS`1Yf!d0e;^Hj0M#)=q5uoD#1 z`BDpl?IbvHVO@xRup;dcOMGba%BP^r+*8Q_Xt;FpTH