4chan X

Cross-browser userscript for maximum lurking on 4chan.

目前为 2016-04-01 提交的版本。查看 最新版本

// Generated by CoffeeScript
// ==UserScript==
// @name         4chan X
// @version      1.11.29.1
// @minGMVer     1.14
// @minFFVer     26
// @namespace    4chan-X
// @description  Cross-browser userscript for maximum lurking on 4chan.
// @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://i.4cdn.org/*
// @include      https://i.4cdn.org/*
// @include      https://www.google.com/recaptcha/api2/anchor?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
// @include      https://www.google.com/recaptcha/api2/frame?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
// @include      http://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
// @include      https://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*
// @exclude      http://www.4chan.org/pass
// @exclude      https://www.4chan.org/pass
// @exclude      http://www.4chan.org/pass?*
// @exclude      https://www.4chan.org/pass?*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_deleteValue
// @grant        GM_listValues
// @grant        GM_addValueChangeListener
// @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 <[email protected]>
* http://zixaphir.github.io/appchan-x/ 
* 4chan x Copyright © 2009-2011 James Campos <[email protected]>
* https://github.com/aeosynth/4chan-x
* 4chan x Copyright © 2012-2014 Nicolas Stepien <[email protected]>
* https://4chan-x.just-believe.in/
* 4chan x Copyright © 2013-2014 Jordan Bates <[email protected]>
* 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:
*
* audio/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.
*/

'use strict';

(function() {
  var $, $$, Anonymize, AntiAutoplay, ArchiveLink, Banner, Board, Build, Callbacks, Captcha, CatalogLinks, CatalogThread, Clone, Conf, Config, Connection, CrossOrigin, CustomCSS, DataBoard, DeleteLink, DownloadLink, E, Embedding, ExpandComment, ExpandThread, FappeTyme, Favicon, Fetcher, FileInfo, Filter, Flash, Fourchan, Gallery, Get, Header, IDColor, IDHighlight, ImageCommon, ImageExpand, ImageHover, ImageLoader, Index, Keybinds, Linkify, Main, MarkNewIPs, Menu, Metadata, Nav, NormalizeURL, Notice, PSAHiding, PassLink, Polyfill, Post, PostHiding, PostSuccessful, PruneReplies, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, ShimSet, SimpleDict, Thread, ThreadExcerpt, ThreadHiding, ThreadLinks, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, Upvotes, Volume, c, d, doc, g,
    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; },
    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,
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  Config = {
    main: {
      'Miscellaneous': {
        '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],
        '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': [false, '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.'],
        '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'],
        '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/.'],
        '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],
        '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],
        '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': [false, 'Show full image / video on mouseover in 4chan X catalog.'],
        'Gallery': [true, 'Adds a simple and cute image gallery.'],
        '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 thumbnails with the actual webm video. Probably will degrade browser performance ;)'],
        'Image Prefetching': [false, 'Add link in header menu 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': [true, '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],
        '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': [true, '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],
        'Thread Excerpt': [true, 'Show an excerpt of the thread in the tab title for threads in /f/.'],
        '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.'],
        'Fixed Thread Watcher': [true, 'Makes the thread watcher scroll with the page.', 1],
        'Toggleable Thread Watcher': [true, 'Adds a shortcut for the thread watcher and hides the watcher by default.', 1],
        'Mark New IPs': [false, 'Label each post from a new IP with the thread\'s current IP count.']
      },
      'Posting and Captchas': {
        'Quick Reply': [true, 'All-in-one form to reply, create threads, automate dumping and more.'],
        'QR Shortcut': [true, 'Add a shortcut to the header to toggle the QR.', 1],
        'Persistent QR': [false, 'The Quick reply won\'t disappear after posting.', 1],
        'Auto Hide QR': [true, 'Automatically hide the quick reply when posting.', 1],
        'Open Post in New Tab': [true, 'Open new threads or replies to a thread from the index in a new tab.', 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': [false, 'Show the option to post a new / different thread from inside a thread.', 1],
        'Show Name and Subject': [false, 'Show the classic name, email, and subject fields in the QR, even when 4chan doesn\'t use them all.', 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],
        'Bottom QR Link': [true, 'Places a link on the bottom of threads to open the QR.', 1],
        'Captcha Fixes': [true, 'Make captcha easier to use, especially with the keyboard.'],
        'Use Recaptcha v1': [false, 'Use the old text version of Recaptcha in the post form.'],
        'Use Recaptcha v1 in Reports': [false, 'Use the text captcha in the report window.'],
        'Force Noscript Captcha': [false, 'Use the non-Javascript fallback captcha even if Javascript is enabled (Recaptcha v2 only).'],
        '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],
        'Quote Inlining': [true, 'Inline quoted post on click.'],
        'Inline Cross-thread Quotes Only': [false, 'Only inline quote links when the posts are on another thread or board, or fetched from the archive.', 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.'],
        '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': [false, 'Thread conversations'],
        'Upvotes': [true, 'Upvote posts.']
      }
    },
    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.'],
      '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': [false, 'Automatically watch threads you start.'],
      'Auto Watch Reply': [false, 'Automatically watch threads you reply to.'],
      'Auto Prune': [false, 'Automatically remove dead threads.'],
      'Show Unread Count': [true, 'Show number of unread posts in watched threads.']
    },
    filter: {
      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",
      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: "https://www.google.com/searchbyimage?image_url=%IMG&safe=off\n//iqdb.org/?url=%IMG\nhttp://eye.swfchan.com/search/?q=%name;types:swf;sandbox\n#//tineye.com/search?url=%IMG\n#https://www.yandex.com/images/search?rpt=imageview&img_url=%IMG\n#//saucenao.com/search.php?url=%IMG\n#http://3d.iqdb.org/?url=%IMG\n# tools:\n#http://regex.info/exif.cgi?imgurl=%URL\n#//imgops.com/%URL;types:gif,jpg,png\n# uploaders:\n#//imgur.com/upload?url=%URL;types:gif,jpg,png,pdf;text:Upload to imgur\n# \"View Same\" in archives:\n#https://archive.4plebs.org/_/search/image/%sMD5/;text:View same on 4plebs\n#https://archive.4plebs.org/%board/search/image/%sMD5/;text:View same on 4plebs /%board/;boards:adv,f,hr,o,pol,s4s,sp,tg,trv,tv,x\n#https://rbt.asia/%board/image/%sMD5;text:View same on RBT /%board/;boards:cgl,g,mu",
    FappeT: {
      werk: false
    },
    'Custom CSS': true,
    Index: {
      'Index Mode': 'paged',
      'Previous Index Mode': 'paged',
      'Index Size': 'small',
      'Show Replies': true,
      'Pin Watched Threads': false,
      'Anchor Hidden Threads': true,
      'Refreshed Navigation': false
    },
    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
    },
    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\"]",
    QR: {
      'QR.personas': "#options:\"sage\";boards:jp;always",
      sjisPreview: false
    },
    captchaLanguage: '',
    time: '%m/%d/%y(%a)%H:%M:%S',
    backlink: '>>%id',
    fileInfo: '%l (%p%s, %r%g)',
    favicon: 'ferongr',
    usercss: "/* Board title rice */\n" +
"div.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" +
"}",
    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.'],
      '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.'],
      'Expand image': ['Shift+e', 'Expand selected image.'],
      'Expand images': ['e', 'Expand all images.'],
      'Open Gallery': ['g', 'Opens the gallery.'],
      'Pause': ['p', 'Pause/play videos in the gallery.'],
      'Slideshow': ['Ctrl+Right', 'Toggle the gallery slideshow mode.'],
      '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.'],
      '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': 30
    },
    customCooldown: 0,
    customCooldownEnabled: true,
    pruneReplies: {
      'Prune Replies': false,
      'Max Replies': 1000
    },
    upvoteText: ''
  };

  Conf = {};

  c = console;

  d = document;

  doc = d.documentElement;

  g = {
    VERSION: '1.11.29.1',
    NAMESPACE: '4chan X.',
    boards: {}
  };

  E = (function() {
    var fn, r, regex, str;
    str = {
      '&': '&amp;',
      "'": '&#039;',
      '"': '&quot;',
      '<': '&lt;',
      '>': '&gt;'
    };
    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, k, len1, x;
    html = '';
    for (k = 0, len1 = templates.length; k < len1; k++) {
      x = templates[k];
      html += x.innerHTML;
    }
    return html;
  };

  E.url = function(content) {
    return "data:text/html;charset=utf-8,<!doctype html>" + (encodeURIComponent(content.innerHTML));
  };

  $ = 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;
    }
  };

  $.ajax = (function() {
    var blockedError, blockedURLs, lastModified;
    lastModified = {};
    blockedURLs = {};
    blockedError = function(url) {
      var message;
      if (blockedURLs[url]) {
        return;
      }
      blockedURLs[url] = true;
      message = $.el('div', {
        innerHTML: "4chan X was blocked from loading the following URL:<br><span></span><br>[<a href=\"https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions#why-was-4chan-x-blocked-from-loading-a-url\" target=\"_blank\">More info</a>]"
      });
      $('span', message).textContent = (/^\/\//.test(url) ? location.protocol : '') + url;
      return new Notice('warning', message, 30, function() {
        return delete blockedURLs[url];
      });
    };
    return function(url, options, extra) {
      var err, event, form, k, len1, r, ref, ref1, type, upCallbacks, whenModified;
      if (options == null) {
        options = {};
      }
      if (extra == null) {
        extra = {};
      }
      type = extra.type, whenModified = extra.whenModified, upCallbacks = extra.upCallbacks, form = extra.form;
      url = url.replace(/^((?:https?:)?\/\/(?:\w+\.)?4c(?:ha|d)n\.org)\/adv\//, '$1//adv/');
      r = new XMLHttpRequest();
      type || (type = form && 'post' || 'get');
      try {
        r.open(type, url, true);
      } catch (_error) {
        err = _error;
        blockedError(url);
        ref = ['error', 'loadend'];
        for (k = 0, len1 = ref.length; k < len1; k++) {
          event = ref[k];
          r["on" + event] = options["on" + event];
          $.queueTask($.event, event, null, r);
        }
        return;
      }
      if (whenModified) {
        if (((ref1 = lastModified[whenModified]) != null ? ref1[url] : void 0) != null) {
          r.setRequestHeader('If-Modified-Since', lastModified[whenModified][url]);
        }
        $.on(r, 'load', function() {
          return (lastModified[whenModified] || (lastModified[whenModified] = {}))[url] = r.getResponseHeader('Last-Modified');
        });
      }
      if (/\.json$/.test(url)) {
        if (options.responseType == null) {
          options.responseType = 'json';
        }
      }
      $.extend(r, options);
      if (options.responseType === 'json' && r.responseType !== 'json' && delete r.response) {
        Object.defineProperty(r, 'response', {
          configurable: true,
          enumerable: true,
          get: function() {
            return JSON.parse(r.responseText);
          }
        });
      }
      $.extend(r.upload, upCallbacks);
      r.send(form);
      return r;
    };
  })();

  (function() {
    var reqs;
    reqs = {};
    $.cache = function(url, cb, options) {
      var err, req, rm;
      if (req = reqs[url]) {
        if (req.readyState === 4) {
          $.queueTask(function() {
            return cb.call(req, req.evt, true);
          });
        } else {
          req.callbacks.push(cb);
        }
        return req;
      }
      rm = function() {
        return delete reqs[url];
      };
      try {
        if (!(req = $.ajax(url, options))) {
          return;
        }
      } catch (_error) {
        err = _error;
        return;
      }
      $.on(req, 'load', function(e) {
        var fn1, k, len1, ref;
        this.evt = e;
        ref = this.callbacks;
        fn1 = (function(_this) {
          return function(cb) {
            return $.queueTask(function() {
              return cb.call(_this, e, false);
            });
          };
        })(this);
        for (k = 0, len1 = ref.length; k < len1; k++) {
          cb = ref[k];
          fn1(cb);
        }
        return delete this.callbacks;
      });
      $.on(req, 'abort error', rm);
      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() {
      $.set(this.name, this.checked);
      return Conf[this.name] = this.checked;
    },
    value: function() {
      $.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);
    }
    if ($.engine === 'edge' && d.readyState === 'loading') {
      $.asap((function() {
        return d.readyState !== 'loading' || $(selector, root);
      }), function() {
        return $.onExists(root, selector, cb);
      });
      return;
    }
    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;
  };

  $.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, k, len1;
    el = arguments[0], classNames = 2 <= arguments.length ? slice.call(arguments, 1) : [];
    for (k = 0, len1 = classNames.length; k < len1; k++) {
      className = classNames[k];
      el.classList.add(className);
    }
  };

  $.rmClass = function() {
    var className, classNames, el, k, len1;
    el = arguments[0], classNames = 2 <= arguments.length ? slice.call(arguments, 1) : [];
    for (k = 0, len1 = classNames.length; k < len1; k++) {
      className = classNames[k];
      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, k, len1, node;
    if (!(nodes instanceof Array)) {
      return nodes;
    }
    frag = $.frag();
    for (k = 0, len1 = nodes.length; k < len1; k++) {
      node = nodes[k];
      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, k, len1, ref;
    ref = events.split(' ');
    for (k = 0, len1 = ref.length; k < len1; k++) {
      event = ref[k];
      el.addEventListener(event, handler, false);
    }
  };

  $.off = function(el, events, handler) {
    var event, k, len1, ref;
    ref = events.split(' ');
    for (k = 0, len1 = ref.length; k < len1; k++) {
      event = ref[k];
      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,
      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,
          detail: clone(detail)
        }));
      };
    }
  })();

  $.open = 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);
      };
    }
  })();

  $.globalEval = function(code) {
    var script;
    script = $.el('script', {
      textContent: code
    });
    $.add(d.head || doc, script);
    return $.rm(script);
  };

  $.global = function(fn) {
    if (doc) {
      return $.globalEval("(" + fn + ")();");
    } else {
      return fn();
    }
  };

  $.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;
  };

  $.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';
    }
  })();

  try {
    localStorage.getItem('x');
    $.hasStorage = true;
  } catch (_error) {
    $.hasStorage = false;
  }

  $.item = function(key, val) {
    var item;
    item = {};
    item[key] = val;
    return item;
  };

  $.syncing = {};

  if (typeof GM_deleteValue !== "undefined" && GM_deleteValue !== null) {
    $.getValue = GM_getValue;
    $.listValues = function() {
      return GM_listValues();
    };
  } else if ($.hasStorage) {
    $.getValue = function(key) {
      return localStorage[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 = {};
    $.setValue = function(key, val) {
      GM_setValue(key, val);
      if (key in $.syncing) {
        $.oldValue[key] = val;
        if ($.hasStorage) {
          return localStorage[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 = {};
    $.setValue = function(key, val) {
      if (key in $.syncing) {
        $.oldValue[key] = val;
      }
      return localStorage[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 = JSON.parse(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(JSON.parse(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 k, key, len1;
    if (!(keys instanceof Array)) {
      keys = [keys];
    }
    for (k = 0, len1 = keys.length; k < len1; k++) {
      key = keys[k];
      $.deleteValue(g.NAMESPACE + key);
    }
  };

  $.get = function(key, val, cb) {
    var items;
    if (typeof cb === 'function') {
      items = $.item(key, val);
    } else {
      items = key;
      cb = val;
    }
    return $.queueTask(function() {
      for (key in items) {
        if (val = $.getValue(g.NAMESPACE + key)) {
          items[key] = JSON.parse(val);
        }
      }
      return cb(items);
    });
  };

  $.set = function(keys, val, cb) {
    var key, value;
    if (typeof keys === 'string') {
      $.setValue(g.NAMESPACE + keys, JSON.stringify(val));
    } else {
      for (key in keys) {
        value = keys[key];
        $.setValue(g.NAMESPACE + key, JSON.stringify(value));
      }
      cb = val;
    }
    return typeof cb === "function" ? cb() : void 0;
  };

  $.clear = function(cb) {
    var id;
    $["delete"](Object.keys(Conf));
    $["delete"](['previousversion', 'AutoWatch', 'QR Size', 'captchas', 'QR.persona', 'hiddenPSA']);
    $["delete"]((function() {
      var k, len1, ref, results;
      ref = ['embedding', 'updater', 'thread-stats', 'thread-watcher', 'qr'];
      results = [];
      for (k = 0, len1 = ref.length; k < len1; k++) {
        id = ref[k];
        results.push(id + ".position");
      }
      return results;
    })());
    try {
      $["delete"]($.listValues().map(function(key) {
        return key.replace(g.NAMESPACE, '');
      }));
    } catch (_error) {}
    return typeof cb === "function" ? cb() : void 0;
  };

  $$ = function(selector, root) {
    if (root == null) {
      root = d.body;
    }
    return slice.call(root.querySelectorAll(selector));
  };

  Callbacks = (function() {
    function Callbacks(type1) {
      this.type = type1;
      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) {
      var err, errors, k, len1, name, ref;
      if (keys == null) {
        keys = this.keys;
      }
      for (k = 0, len1 = keys.length; k < len1; k++) {
        name = keys[k];
        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
          });
        }
      }
      if (errors) {
        return Main.handleErrors(errors);
      }
    };

    return Callbacks;

  })();

  Board = (function() {
    Board.prototype.toString = function() {
      return this.ID;
    };

    function Board(ID1) {
      this.ID = ID1;
      this.threads = new SimpleDict();
      this.posts = new SimpleDict();
      g.boards[this] = this;
    }

    return Board;

  })();

  Thread = (function() {
    Thread.callbacks = new Callbacks('Thread');

    Thread.prototype.toString = function() {
      return this.ID;
    };

    function Thread(ID1, board1) {
      this.ID = ID1;
      this.board = board1;
      this.fullID = this.board + "." + this.ID;
      this.posts = new SimpleDict();
      this.isDead = false;
      this.isHidden = false;
      this.isOnTop = false;
      this.isSticky = false;
      this.isClosed = false;
      this.isArchived = false;
      this.postLimit = false;
      this.fileLimit = false;
      this.ipCount = void 0;
      this.OP = null;
      this.catalogView = null;
      this.board.threads.push(this.ID, this);
      g.threads.push(this.fullID, this);
    }

    Thread.prototype.setPage = function(pageNum) {
      var icon, info, quote, ref;
      ref = this.OP.nodes, info = ref.info, quote = ref.quote;
      if (!(icon = $('.page-num', info))) {
        icon = $.el('span', {
          className: 'page-num'
        });
        $.after(quote, [$.tn(' '), icon]);
      }
      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: "" + Build.staticPath + typeLC + Build.gifIcon,
        alt: type,
        title: type,
        className: typeLC + "Icon retina"
      });
      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() {
      this.posts.forEach(function(post) {
        return post.collect();
      });
      g.threads.rm(this.fullID);
      return this.board.threads.rm(this);
    };

    return Thread;

  })();

  CatalogThread = (function() {
    CatalogThread.callbacks = new Callbacks('Catalog Thread');

    CatalogThread.prototype.toString = function() {
      return this.ID;
    };

    function CatalogThread(root, thread1) {
      this.thread = thread1;
      this.ID = this.thread.ID;
      this.board = this.thread.board;
      this.nodes = {
        root: root,
        thumb: $('.catalog-thumb', root),
        icons: $('.catalog-icons', root),
        postCount: $('.post-count', root),
        fileCount: $('.file-count', root),
        pageCount: $('.page-count', root),
        comment: $('.comment', root)
      };
      this.thread.catalogView = this;
    }

    return CatalogThread;

  })();

  Post = (function() {
    Post.callbacks = new Callbacks('Post');

    Post.prototype.toString = function() {
      return this.ID;
    };

    function Post(root, thread1, board1) {
      var capcode, clone, date, email, flag, info, k, len1, name, post, ref, subject, tripcode, uniqueID;
      this.thread = thread1;
      this.board = board1;
      this.ID = +root.id.slice(2);
      this.fullID = this.board + "." + this.ID;
      this.context = this;
      root.dataset.fullID = this.fullID;
      post = $('.post', root);
      info = $('.postInfo', post);
      this.nodes = {
        root: root,
        post: post,
        info: info,
        nameBlock: $('.nameBlock', info),
        quote: $('.postNum > a:nth-of-type(2)', info),
        comment: $('.postMessage', post),
        links: [],
        quotelinks: []
      };
      if ($.engine === 'edge') {
        Object.defineProperty(this.nodes, 'backlinks', {
          configurable: true,
          enumerable: true,
          get: function() {
            return info.getElementsByClassName('backlink');
          }
        });
      } else {
        this.nodes.backlinks = info.getElementsByClassName('backlink');
      }
      if (!(this.isReply = $.hasClass(post, 'reply'))) {
        this.thread.OP = this;
        this.thread.isArchived = !!$('.archivedIcon', info);
        this.thread.isSticky = !!$('.stickyIcon', info);
        this.thread.isClosed = this.thread.isArchived || !!$('.closedIcon', info);
        if (this.thread.isArchived) {
          this.thread.kill();
        }
      }
      this.info = {};
      this.info.nameBlock = Conf['Anonymize'] ? 'Anonymous' : this.nodes.nameBlock.textContent.trim();
      if (subject = $('.subject', info)) {
        this.nodes.subject = subject;
        this.info.subject = subject.textContent || void 0;
      }
      if (name = $('.name', info)) {
        this.nodes.name = name;
        this.info.name = name.textContent;
      }
      if (email = $('.useremail', info)) {
        this.nodes.email = email;
        this.info.email = decodeURIComponent(email.href.slice(7));
      }
      if (tripcode = $('.postertrip', info)) {
        this.nodes.tripcode = tripcode;
        this.info.tripcode = tripcode.textContent;
      }
      if (uniqueID = $('.posteruid', info)) {
        this.nodes.uniqueID = uniqueID;
        this.info.uniqueID = uniqueID.firstElementChild.textContent;
      }
      if (capcode = $('.capcode.hand', info)) {
        this.nodes.capcode = capcode;
        this.info.capcode = capcode.textContent.replace('## ', '');
      }
      if (flag = $('.flag, .countryFlag', info)) {
        this.nodes.flag = flag;
        this.info.flag = flag.title;
      }
      if (date = $('.dateTime', info)) {
        this.nodes.date = date;
        this.info.date = new Date(date.dataset.utc * 1000);
      }
      this.parseComment();
      this.parseQuotes();
      this.parseFile();
      this.isDead = false;
      this.isHidden = false;
      this.clones = [];
      if (g.posts[this.fullID]) {
        this.isRebuilt = true;
        this.clones = g.posts[this.fullID].clones;
        ref = this.clones;
        for (k = 0, len1 = ref.length; k < len1; k++) {
          clone = ref[k];
          clone.origin = this;
        }
      }
      this.board.posts.push(this.ID, this);
      this.thread.posts.push(this.ID, this);
      g.posts.push(this.fullID, this);
    }

    Post.prototype.parseComment = function() {
      var abbr, bq, commentDisplay, k, len1, len2, node, q, ref, spoilers;
      this.nodes.comment.normalize();
      bq = this.nodes.comment.cloneNode(true);
      ref = $$('.abbr + br, .exif, b, .fortune', bq);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        node = ref[k];
        $.rm(node);
      }
      if (abbr = $('.abbr', bq)) {
        $.rm(abbr);
      }
      this.info.comment = this.nodesToText(bq);
      if (abbr) {
        this.info.comment = this.info.comment.replace(/\n\n$/, '');
      }
      commentDisplay = this.info.comment;
      if (!(Conf['Remove Spoilers'] || Conf['Reveal Spoilers'])) {
        spoilers = $$('s', bq);
        if (spoilers.length) {
          for (q = 0, len2 = spoilers.length; q < len2; q++) {
            node = spoilers[q];
            $.replace(node, $.tn('[spoiler]'));
          }
          commentDisplay = this.nodesToText(bq);
        }
      }
      return this.info.commentDisplay = commentDisplay.trim().replace(/\s+$/gm, '');
    };

    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.parseQuotes = function() {
      var k, len1, quotelink, ref;
      this.quotes = [];
      ref = $$(':not(pre) > .quotelink', this.nodes.comment);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        quotelink = ref[k];
        this.parseQuote(quotelink);
      }
    };

    Post.prototype.parseQuote = function(quotelink) {
      var fullID, match;
      match = quotelink.href.match(/^https?:\/\/boards\.4chan\.org\/+([^\/]+)\/+(?:res|thread)\/+\d+(?:\/[^#]*)?#p(\d+)$/);
      if (!(match || (this.isClone && quotelink.dataset.postID))) {
        return;
      }
      this.nodes.quotelinks.push(quotelink);
      if (this.isClone) {
        return;
      }
      fullID = match[1] + "." + match[2];
      if (indexOf.call(this.quotes, fullID) < 0) {
        return this.quotes.push(fullID);
      }
    };

    Post.prototype.parseFile = function() {
      var fileEl, fileText, info, link, m, ref, ref1, ref2, size, thumb, unit;
      if (!(fileEl = $('.file', this.nodes.post))) {
        return;
      }
      if (!(link = $('.fileText > a, .fileText-original > a', fileEl))) {
        return;
      }
      if (!(info = (ref = link.nextSibling) != null ? ref.textContent.match(/\(([\d.]+ [KMG]?B).*\)/) : void 0)) {
        return;
      }
      fileText = fileEl.firstElementChild;
      this.file = {
        text: fileText,
        link: link,
        url: link.href,
        name: fileText.title || link.title || link.textContent,
        size: info[1],
        isImage: /(jpg|png|gif)$/i.test(link.href),
        isVideo: /webm$/i.test(link.href),
        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
      };
      size = +this.file.size.match(/[\d.]+/)[0];
      unit = ['B', 'KB', 'MB', 'GB'].indexOf(this.file.size.match(/\w+$/)[0]);
      while (unit-- > 0) {
        size *= 1024;
      }
      this.file.sizeInBytes = size;
      if ((thumb = $('.fileThumb > [data-md5]', fileEl))) {
        return $.extend(this.file, {
          thumb: thumb,
          thumbURL: (m = link.href.match(/\d+(?=\.\w+$)/)) ? location.protocol + "//i.4cdn.org/" + this.board + "/" + m[0] + "s.jpg" : void 0,
          MD5: thumb.dataset.md5,
          isSpoiler: $.hasClass(thumb.parentNode, 'imgspoiler')
        });
      }
    };

    Post.prototype.kill = function(file) {
      var clone, k, len1, len2, q, quotelink, ref, ref1, strong;
      if (file) {
        if (this.file.isDead) {
          return;
        }
        this.file.isDead = true;
        $.addClass(this.nodes.root, 'deleted-file');
      } else {
        if (this.isDead) {
          return;
        }
        this.isDead = true;
        $.addClass(this.nodes.root, 'deleted-post');
      }
      if (!(strong = $('strong.warning', this.nodes.info))) {
        strong = $.el('strong', {
          className: 'warning',
          textContent: this.isReply ? '[Deleted]' : '[Dead]'
        });
        $.after($('input', this.nodes.info), strong);
      }
      strong.textContent = file ? '[File deleted]' : '[Deleted]';
      if (this.isClone) {
        return;
      }
      ref = this.clones;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        clone = ref[k];
        clone.kill(file);
      }
      if (file) {
        return;
      }
      ref1 = Get.allQuotelinksLinkingTo(this);
      for (q = 0, len2 = ref1.length; q < len2; q++) {
        quotelink = ref1[q];
        if (!(!$.hasClass(quotelink, 'deadlink'))) {
          continue;
        }
        quotelink.textContent = quotelink.textContent + '\u00A0(Dead)';
        $.addClass(quotelink, 'deadlink');
      }
    };

    Post.prototype.resurrect = function() {
      var clone, k, len1, len2, q, quotelink, ref, ref1, strong;
      this.isDead = false;
      $.rmClass(this.nodes.root, 'deleted-post');
      strong = $('strong.warning', this.nodes.info);
      if (this.file && this.file.isDead) {
        strong.textContent = '[File deleted]';
      } else {
        $.rm(strong);
      }
      if (this.isClone) {
        return;
      }
      ref = this.clones;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        clone = ref[k];
        clone.resurrect();
      }
      ref1 = Get.allQuotelinksLinkingTo(this);
      for (q = 0, len2 = ref1.length; q < len2; q++) {
        quotelink = ref1[q];
        if (!($.hasClass(quotelink, 'deadlink'))) {
          continue;
        }
        quotelink.textContent = quotelink.textContent.replace('\u00A0(Dead)', '');
        $.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) {
      return new Clone(this, context, contractThumb);
    };

    Post.prototype.rmClone = function(index) {
      var clone, k, len1, ref;
      this.clones.splice(index, 1);
      ref = this.clones.slice(index);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        clone = ref[k];
        clone.nodes.root.dataset.clone = index++;
      }
    };

    return Post;

  })();

  Clone = (function(superClass) {
    extend(Clone, superClass);

    Clone.prototype.isClone = true;

    function Clone(origin1, context1, contractThumb) {
      var file, info, inline, inlined, k, key, len1, len2, len3, len4, node, nodes, post, q, ref, ref1, ref2, ref3, ref4, ref5, root, u, v, val;
      this.origin = origin1;
      this.context = context1;
      ref = ['ID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply'];
      for (k = 0, len1 = ref.length; k < len1; k++) {
        key = ref[k];
        this[key] = this.origin[key];
      }
      nodes = this.origin.nodes;
      root = contractThumb ? this.cloneWithoutVideo(nodes.root) : nodes.root.cloneNode(true);
      Clone.prefix || (Clone.prefix = 0);
      ref1 = [root].concat(slice.call($$('[id]', root)));
      for (q = 0, len2 = ref1.length; q < len2; q++) {
        node = ref1[q];
        node.id = Clone.prefix + node.id;
      }
      Clone.prefix++;
      post = $('.post', root);
      info = $('.postInfo', post);
      this.nodes = {
        root: root,
        post: post,
        info: info,
        nameBlock: $('.nameBlock', info),
        quote: $('.postNum > a:nth-of-type(2)', info),
        comment: $('.postMessage', post),
        quotelinks: []
      };
      if ($.engine === 'edge') {
        Object.defineProperty(this.nodes, 'backlinks', {
          configurable: true,
          enumerable: true,
          get: function() {
            return info.getElementsByClassName('backlink');
          }
        });
      } else {
        this.nodes.backlinks = info.getElementsByClassName('backlink');
      }
      ref2 = $$('.inline', post);
      for (u = 0, len3 = ref2.length; u < len3; u++) {
        inline = ref2[u];
        $.rm(inline);
      }
      ref3 = $$('.inlined', post);
      for (v = 0, len4 = ref3.length; v < len4; v++) {
        inlined = ref3[v];
        $.rmClass(inlined, 'inlined');
      }
      root.hidden = false;
      $.rmClass(root, 'forwarded');
      $.rmClass(post, 'highlight');
      if (nodes.subject) {
        this.nodes.subject = $('.subject', info);
      }
      if (nodes.name) {
        this.nodes.name = $('.name', info);
      }
      if (nodes.email) {
        this.nodes.email = $('.useremail', info);
      }
      if (nodes.tripcode) {
        this.nodes.tripcode = $('.postertrip', info);
      }
      if (nodes.uniqueID) {
        this.nodes.uniqueID = $('.posteruid', info);
      }
      if (nodes.capcode) {
        this.nodes.capcode = $('.capcode.hand', info);
      }
      if (nodes.flag) {
        this.nodes.flag = $('.flag, .countryFlag', info);
      }
      if (nodes.date) {
        this.nodes.date = $('.dateTime', info);
      }
      this.parseQuotes();
      this.quotes = slice.call(this.origin.quotes);
      if (this.origin.file) {
        this.file = {};
        ref4 = this.origin.file;
        for (key in ref4) {
          val = ref4[key];
          this.file[key] = val;
        }
        file = $('.file', post);
        this.file.text = file.firstElementChild;
        this.file.link = $('.fileText > a, .fileText-original', file);
        this.file.thumb = $('.fileThumb > [data-md5]', file);
        this.file.fullImage = $('.full-image', file);
        this.file.videoControls = $('.video-controls', this.file.text);
        if (this.file.videoThumb) {
          this.file.thumb.muted = true;
        }
        if ((ref5 = this.file.thumb) != null ? ref5.dataset.src : void 0) {
          this.file.thumb.src = this.file.thumb.dataset.src;
          this.file.thumb.removeAttribute('data-src');
        }
        if (this.file.thumb && contractThumb) {
          ImageExpand.contract(this);
        }
      }
      if (this.origin.isDead) {
        this.isDead = true;
      }
      root.dataset.clone = this.origin.clones.push(this) - 1;
    }

    Clone.prototype.cloneWithoutVideo = function(node) {
      var child, clone, k, len1, 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 (k = 0, len1 = ref.length; k < len1; k++) {
          child = ref[k];
          $.add(clone, this.cloneWithoutVideo(child));
        }
        return clone;
      } else {
        return node.cloneNode(true);
      }
    };

    return Clone;

  })(Post);

  DataBoard = (function() {
    DataBoard.keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads', 'customTitles'];

    function DataBoard(key1, sync, dontClean) {
      var init;
      this.key = key1;
      this.onSync = bind(this.onSync, this);
      this.data = 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.save = function(cb) {
      return $.set(this.key, this.data, cb);
    };

    DataBoard.prototype["delete"] = function(arg) {
      var boardID, postID, ref, threadID;
      boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID;
      $.forceSync(this.key);
      if (postID) {
        if (!((ref = this.data.boards[boardID]) != null ? ref[threadID] : void 0)) {
          return;
        }
        delete this.data.boards[boardID][threadID][postID];
        this.deleteIfEmpty({
          boardID: boardID,
          threadID: threadID
        });
      } else if (threadID) {
        if (!this.data.boards[boardID]) {
          return;
        }
        delete this.data.boards[boardID][threadID];
        this.deleteIfEmpty({
          boardID: boardID
        });
      } else {
        delete this.data.boards[boardID];
      }
      return this.save();
    };

    DataBoard.prototype.deleteIfEmpty = function(arg) {
      var boardID, threadID;
      boardID = arg.boardID, threadID = arg.threadID;
      $.forceSync(this.key);
      if (threadID) {
        if (!Object.keys(this.data.boards[boardID][threadID]).length) {
          delete this.data.boards[boardID][threadID];
          return this.deleteIfEmpty({
            boardID: boardID
          });
        }
      } else if (!Object.keys(this.data.boards[boardID]).length) {
        return delete this.data.boards[boardID];
      }
    };

    DataBoard.prototype.set = function(arg, cb) {
      var base1, base2, base3, boardID, postID, threadID, val;
      boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, val = arg.val;
      $.forceSync(this.key);
      if (postID !== void 0) {
        ((base1 = ((base2 = this.data.boards)[boardID] || (base2[boardID] = {})))[threadID] || (base1[threadID] = {}))[postID] = val;
      } else if (threadID !== void 0) {
        ((base3 = this.data.boards)[boardID] || (base3[boardID] = {}))[threadID] = val;
      } else {
        this.data.boards[boardID] = val;
      }
      return this.save(cb);
    };

    DataBoard.prototype.get = function(arg) {
      var ID, board, boardID, defaultValue, k, len1, postID, thread, threadID, val;
      boardID = arg.boardID, threadID = arg.threadID, postID = arg.postID, defaultValue = arg.defaultValue;
      if (board = this.data.boards[boardID]) {
        if (threadID == null) {
          if (postID != null) {
            for (thread = k = 0, len1 = board.length; k < len1; thread = ++k) {
              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.forceSync = function() {
      return $.forceSync(this.key);
    };

    DataBoard.prototype.clean = function() {
      var boardID, now, ref, val;
      $.forceSync(this.key);
      ref = this.data.boards;
      for (boardID in ref) {
        val = ref[boardID];
        this.deleteIfEmpty({
          boardID: boardID
        });
      }
      now = Date.now();
      if ((this.data.lastChecked || 0) < now - 2 * $.HOUR) {
        this.data.lastChecked = now;
        for (boardID in this.data.boards) {
          this.ajaxClean(boardID);
        }
      }
    };

    DataBoard.prototype.ajaxClean = function(boardID) {
      return $.cache("//a.4cdn.org/" + boardID + "/threads.json", (function(_this) {
        return function(e1) {
          var ref;
          if ((ref = e1.target.status) !== 200 && ref !== 404) {
            return;
          }
          return $.cache("//a.4cdn.org/" + boardID + "/archive.json", function(e2) {
            var ref1;
            if ((ref1 = e2.target.status) !== 200 && ref1 !== 404) {
              return;
            }
            return _this.ajaxCleanParse(boardID, e1.target.response, e2.target.response);
          });
        };
      })(this));
    };

    DataBoard.prototype.ajaxCleanParse = function(boardID, response1, response2) {
      var ID, board, k, len1, len2, len3, page, q, ref, thread, threads, u;
      if (!(board = this.data.boards[boardID])) {
        return;
      }
      threads = {};
      if (response1) {
        for (k = 0, len1 = response1.length; k < len1; k++) {
          page = response1[k];
          ref = page.threads;
          for (q = 0, len2 = ref.length; q < len2; q++) {
            thread = ref[q];
            ID = thread.no;
            if (ID in board) {
              threads[ID] = board[ID];
            }
          }
        }
      }
      if (response2) {
        for (u = 0, len3 = response2.length; u < len3; u++) {
          ID = response2[u];
          if (ID in board) {
            threads[ID] = board[ID];
          }
        }
      }
      this.data.boards[boardID] = threads;
      this.deleteIfEmpty({
        boardID: boardID
      });
      return this.save();
    };

    DataBoard.prototype.onSync = function(data) {
      this.data = data || {
        boards: {}
      };
      return typeof this.sync === "function" ? this.sync() : void 0;
    };

    return DataBoard;

  })();

  Notice = (function() {
    function Notice(type, content, timeout1, onclose) {
      this.timeout = timeout1;
      this.onclose = onclose;
      this.close = bind(this.close, this);
      this.add = bind(this.add, this);
      this.el = $.el('div', {
        innerHTML: "<a href=\"javascript:;\" class=\"close fa fa-times\" title=\"Close\"></a><div class=\"message\"></div>"
      });
      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 (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() {
      $.off(d, 'visibilitychange', this.add);
      $.rm(this.el);
      return typeof this.onclose === "function" ? this.onclose() : void 0;
    };

    return Notice;

  })();

  RandomAccessList = (function() {
    function RandomAccessList(items) {
      var item, k, len1;
      this.length = 0;
      if (items) {
        for (k = 0, len1 = items.length; k < len1; k++) {
          item = items[k];
          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;

  })();

  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 k, key, len1, ref;
      ref = slice.call(this.keys);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        key = ref[k];
        fn(this[key]);
      }
    };

    return SimpleDict;

  })();

  ShimSet = (function() {
    function ShimSet() {
      this.elements = {};
      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;
  }

  Connection = (function() {
    function Connection(target1, origin1, cb1) {
      this.target = target1;
      this.origin = origin1;
      this.cb = cb1 != null ? cb1 : {};
      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 base1, 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 (typeof (base1 = this.cb)[type] === "function") {
          base1[type](value);
        }
      }
    };

    return Connection;

  })();

  Fetcher = (function() {
    function Fetcher(boardID1, threadID1, postID1, root1, quoter1) {
      var post;
      this.boardID = boardID1;
      this.threadID = threadID1;
      this.postID = postID1;
      this.root = root1;
      this.quoter = quoter1;
      if (post = g.posts[this.boardID + "." + this.postID]) {
        this.insert(post);
        return;
      }
      this.root.textContent = "Loading post No." + this.postID + "...";
      if (this.threadID) {
        $.cache("//a.4cdn.org/" + this.boardID + "/thread/" + this.threadID + ".json", (function(_this) {
          return function(e, isCached) {
            return _this.fetchedPost(e.target, isCached);
          };
        })(this));
      } else {
        this.archivedPost();
      }
    }

    Fetcher.prototype.insert = function(post) {
      var boardID, clone, k, len1, nodes, postID, quote, ref, ref1;
      if (!this.root.parentNode) {
        return;
      }
      clone = post.addClone(this.quoter.context, $.hasClass(this.root, 'dialog'));
      Main.callbackNodes(Clone, [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, len1 = ref.length; k < len1; 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');
        }
      }
      $.rmAll(this.root);
      $.add(this.root, nodes.root);
      return $.event('PostsInserted');
    };

    Fetcher.prototype.fetchedPost = function(req, isCached) {
      var api, board, k, len1, post, posts, status, thread;
      if (post = g.posts[this.boardID + "." + this.postID]) {
        this.insert(post);
        return;
      }
      status = req.status;
      if (status !== 200 && status !== 304) {
        if (this.archivedPost()) {
          return;
        }
        $.addClass(this.root, 'warning');
        this.root.textContent = status === 404 ? "Thread No." + this.threadID + " 404'd." : "Error " + req.statusText + " (" + req.status + ").";
        return;
      }
      posts = req.response.posts;
      Build.spoilerRange[this.boardID] = posts[0].custom_spoiler;
      for (k = 0, len1 = posts.length; k < len1; k++) {
        post = posts[k];
        if (post.no === this.postID) {
          break;
        }
      }
      if (post.no !== this.postID) {
        if (isCached) {
          api = "//a.4cdn.org/" + this.boardID + "/thread/" + this.threadID + ".json";
          $.cleanCache(function(url) {
            return url === api;
          });
          $.cache(api, (function(_this) {
            return function(e) {
              return _this.fetchedPost(e.target, false);
            };
          })(this));
          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[this.boardID + "." + this.threadID] || new Thread(this.threadID, board);
      post = new Post(Build.postFromObject(post, this.boardID), thread, board);
      post.isFetchedQuote = true;
      Main.callbackNodes(Post, [post]);
      return this.insert(post);
    };

    Fetcher.prototype.archivedPost = function() {
      var archive, 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];
      if (/^https:\/\//.test(url) || location.protocol === 'http:') {
        $.cache(url, (function(_this) {
          return function(e) {
            return _this.parseArchivedPost(e.target.response, url, archive);
          };
        })(this), {
          responseType: 'json',
          withCredentials: archive.withCredentials
        });
        return true;
      } else if (Conf['Exempt Archives from Encryption']) {
        CrossOrigin.json(url, (function(_this) {
          return function(response) {
            var key, media, ref;
            media = response.media;
            if (media) {
              for (key in media) {
                if (/_link$/.test(key)) {
                  if (!((ref = media[key]) != null ? ref.match(/^http:\/\//) : void 0)) {
                    delete media[key];
                  }
                }
              }
            }
            return _this.parseArchivedPost(response, url, archive);
          };
        })(this));
        return true;
      }
      return false;
    };

    Fetcher.prototype.parseArchivedPost = function(data, url, archive) {
      var board, comment, greentext, i, j, key, o, post, ref, ref1, text, text2, thread, val;
      if (post = g.posts[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)\])/);
      comment = (function() {
        var k, len1, results;
        results = [];
        for (i = k = 0, len1 = comment.length; k < len1; i = ++k) {
          text = comment[i];
          if (i % 2 === 1) {
            results.push(this.archiveTags[text]);
          } else {
            greentext = text[0] === '>';
            text = text.replace(/(\[\/?[a-z]+):lit(\])/, '$1$2');
            text = (function() {
              var len2, q, ref, results1;
              ref = text.split(/(>>(?:>\/[a-z\d]+\/)?\d+)/g);
              results1 = [];
              for (j = q = 0, len2 = ref.length; q < len2; j = ++q) {
                text2 = ref[j];
                results1.push({
                  innerHTML: (j % 2 ? "<span class=\"deadlink\">" + E(text2) + "</span>" : E(text2))
                });
              }
              return results1;
            })();
            text = {
              innerHTML: (greentext ? "<span class=\"quote\">" + E.cat(text) + "</span>" : E.cat(text))
            };
            results.push(text);
          }
        }
        return results;
      }).call(this);
      comment = {
        innerHTML: E.cat(comment)
      };
      this.threadID = +data.thread_num;
      o = {
        postID: 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';
          }
        })(),
        uniqueID: data.poster_hash,
        flagCode: data.poster_country,
        flag: data.poster_country_name,
        dateUTC: data.timestamp,
        dateText: data.fourchan_date,
        commentHTML: comment
      };
      if (o.info.capcode) {
        delete o.info.uniqueID;
      }
      if ((ref = data.media) != null ? ref.media_filename : void 0) {
        ref1 = data.media;
        for (key in ref1) {
          val = ref1[key];
          if (/_link$/.test(key) && (val != null ? val[0] : void 0) === '/') {
            data.media[key] = url.split('/', 3).join('/') + val;
          }
        }
        o.file = {
          name: data.media.media_filename,
          url: data.media.media_link || data.media.remote_media_link || (location.protocol + "//i.4cdn.org/" + this.boardID + "/" + (encodeURIComponent(data.media[this.boardID === 'f' ? 'media_filename' : 'media_orig']))),
          height: data.media.media_h,
          width: data.media.media_w,
          MD5: data.media.media_hash,
          size: $.bytesToString(data.media.media_size),
          thumbURL: data.media.thumb_link || (location.protocol + "//i.4cdn.org/" + 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;
        }
      }
      board = g.boards[this.boardID] || new Board(this.boardID);
      thread = g.threads[this.boardID + "." + this.threadID] || new Thread(this.threadID, board);
      post = new Post(Build.post(o), thread, board);
      post.kill();
      if (post.file) {
        post.file.thumbURL = o.file.thumbURL;
      }
      post.isFetchedQuote = true;
      Main.callbackNodes(Post, [post]);
      return this.insert(post);
    };

    Fetcher.prototype.archiveTags = {
      '\n': {
        innerHTML: "<br>"
      },
      '[b]': {
        innerHTML: "<b>"
      },
      '[/b]': {
        innerHTML: "</b>"
      },
      '[spoiler]': {
        innerHTML: "<s>"
      },
      '[/spoiler]': {
        innerHTML: "</s>"
      },
      '[code]': {
        innerHTML: "<pre class=\"prettyprint\">"
      },
      '[/code]': {
        innerHTML: "</pre>"
      },
      '[moot]': {
        innerHTML: "<div style=\"padding:5px;margin-left:.5em;border-color:#faa;border:2px dashed rgba(255,0,0,.1);border-radius:2px\">"
      },
      '[/moot]': {
        innerHTML: "</div>"
      },
      '[banned]': {
        innerHTML: "<strong style=\"color: red;\">"
      },
      '[/banned]': {
        innerHTML: "</strong>"
      }
    };

    return Fetcher;

  })();

  Polyfill = {
    init: function() {
      return this.toBlob();
    },
    toBlob: function() {
      if (HTMLCanvasElement.prototype.toBlob) {
        return;
      }
      HTMLCanvasElement.prototype.toBlob = function(cb, type, encoderOptions) {
        var data, i, k, l, ref, ui8a, url;
        if (type == null) {
          type = 'image/png';
        }
        url = this.toDataURL(type, encoderOptions);
        data = atob(url.slice(url.indexOf(',') + 1));
        l = data.length;
        ui8a = new Uint8Array(l);
        for (i = k = 0, ref = l; k < ref; i = k += 1) {
          ui8a[i] = data.charCodeAt(i);
        }
        return cb(new Blob([ui8a], {
          type: type
        }));
      };
      return $.globalEval("HTMLCanvasElement.prototype.toBlob = (" + HTMLCanvasElement.prototype.toBlob + ");");
    }
  };

  Header = {
    init: function() {
      var barFixedToggler, barPositionToggler, box, customNavToggler, editCustomNav, footerToggler, headerToggler, linkJustifyToggler, menuButton, scrollHeaderToggler, shortcutToggler;
      this.menu = new UI.Menu('header');
      menuButton = $.el('span', {
        className: 'menu-button'
      });
      $.extend(menuButton, {
        innerHTML: "<i></i>"
      });
      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(menuButton);
      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);
      $.asap((function() {
        return d.body;
      }), (function(_this) {
        return function() {
          if (!Main.isThisPageLegit()) {
            return;
          }
          $.asap((function() {
            return $.id('boardNavMobile') || d.readyState !== 'loading';
          }), function() {
            var a, footer;
            footer = $.id('boardNavDesktop').cloneNode(true);
            footer.id = 'boardNavDesktopFoot';
            $('#navtopright', footer).id = 'navbotright';
            $('#settingsWindowLink', footer).id = 'settingsWindowLinkBot';
            Header.bottomBoardList = $('.boardList', footer);
            if (a = $("a[href*='/" + g.BOARD + "/']", footer)) {
              a.className = 'current';
            }
            Main.ready(function() {
              var absbot, oldFooter;
              if ((oldFooter = $.id('boardNavDesktopFoot'))) {
                return $.replace($('.boardList', oldFooter), Header.bottomBoardList);
              } else if ((absbot = $.id('absbot'))) {
                $.before(absbot, footer);
                return $.globalEval('window.cloneTopNav = function() {};');
              }
            });
            return Header.setBoardList();
          });
          $.prepend(d.body, _this.bar);
          $.add(d.body, Header.hover);
          _this.setBarPosition(Conf['Bottom Header']);
          return _this;
        };
      })(this));
      Main.ready((function(_this) {
        return function() {
          var cs;
          if (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 = 'fa fa-leaf';
            }
            $.on(cs, 'click', function() {
              return $.id('settingsWindowLink').click();
            });
            return _this.addShortcut(cs);
          }
        };
      })(this));
      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 a, boardList, btn, chr, k, len1, len2, node, nodes, q, ref, ref1, spacer, span;
      Header.boardList = boardList = $.el('span', {
        id: 'board-list'
      });
      $.extend(boardList, {
        innerHTML: "<span id=\"custom-board-list\"></span><span id=\"full-board-list\" hidden><span class=\"hide-board-list-container brackets-wrap\"><a href=\"javascript:;\" class=\"hide-board-list-button\">&nbsp;-&nbsp;</a></span> <span class=\"boardList\"></span></span>"
      });
      btn = $('.hide-board-list-button', boardList);
      $.on(btn, 'click', Header.toggleBoardList);
      nodes = [];
      spacer = function() {
        return $.el('span', {
          className: 'spacer'
        });
      };
      ref = $('#boardNavDesktop > .boardList').childNodes;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        node = ref[k];
        switch (node.nodeName) {
          case '#text':
            ref1 = node.nodeValue;
            for (q = 0, len2 = ref1.length; q < len2; q++) {
              chr = ref1[q];
              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);
            if (a.pathname.split('/')[1] === g.BOARD.ID) {
              a.className = 'current';
            }
            nodes.push(a);
        }
      }
      $.add($('.boardList', boardList), nodes);
      $.add(Header.bar, [Header.boardList, Header.shortcuts, Header.noticesRoot, Header.toggle]);
      Header.setCustomNav(Conf['Custom Board Navigation']);
      Header.generateBoardList(Conf['boardnav']);
      $.sync('Custom Board Navigation', Header.setCustomNav);
      return $.sync('boardnav', Header.generateBoardList);
    },
    generateBoardList: function(boardnav) {
      var as, list, nodes, re, t;
      list = $('#custom-board-list', Header.boardList);
      $.rmAll(list);
      if (!boardnav) {
        return;
      }
      boardnav = boardnav.replace(/(\r\n|\n|\r)/g, ' ');
      as = $$('#full-board-list a[title]', Header.boardList);
      re = /[\w@]+(-(all|title|replace|full|index|catalog|archive|expired|(mode|sort|text):"[^"]+"(,"[^"]+")?))*|[^\w@]+/g;
      nodes = (function() {
        var k, len1, ref, results;
        ref = boardnav.match(re);
        results = [];
        for (k = 0, len1 = ref.length; k < len1; k++) {
          t = ref[k];
          results.push(Header.mapCustomNavigation(t, as));
        }
        return results;
      })();
      $.add(list, nodes);
      return $.ready(CatalogLinks.initBoardList);
    },
    mapCustomNavigation: function(t, as) {
      var a, boardID, href, indexOptions, m, text, url;
      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'
        });
        return a;
      }
      boardID = t.split('-')[0];
      if (boardID === 'current') {
        boardID = g.BOARD.ID;
      }
      a = (function() {
        var k, len1, ref;
        if (boardID === '@') {
          return $.el('a', {
            href: 'https://twitter.com/4chan',
            title: '4chan Twitter',
            textContent: '@'
          });
        }
        for (k = 0, len1 = as.length; k < len1; k++) {
          a = as[k];
          if (a.textContent === boardID) {
            return a.cloneNode(true);
          }
        }
        a = $.el('a', {
          href: "/" + boardID + "/",
          textContent: boardID
        });
        if ((ref = g.VIEW) === 'catalog' || ref === 'archive') {
          a.href += g.VIEW;
        }
        if (boardID === g.BOARD.ID) {
          a.className = 'current';
        }
        return a;
      })();
      a.textContent = /-title/.test(t) || /-replace/.test(t) && boardID === g.BOARD.ID ? a.title || a.textContent : /-full/.test(t) ? ("/" + boardID + "/") + (a.title ? " - " + a.title : '') : text || boardID;
      if (m = t.match(/-(index|catalog)/)) {
        if (!(boardID === 'f' && m[1] === 'catalog')) {
          a.dataset.only = m[1];
          a.href = CatalogLinks[m[1]](boardID);
          if (m[1] === 'catalog') {
            $.addClass(a, 'catalog');
          }
        } else {
          return a.firstChild;
        }
      }
      if (Conf['JSON Index'] && indexOptions) {
        a.dataset.indexOptions = indexOptions;
        if (a.hostname === 'boards.4chan.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 (boardID !== 'b' && boardID !== 'f' && boardID !== 'trash') {
          a.href = "/" + boardID + "/archive";
        } else {
          return a.firstChild;
        }
      }
      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');
      if (!Conf['Header auto-hide']) {
        return $.rmClass(Header.bar, 'autohide');
      }
    },
    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;
      Header.barPositionToggler.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)) && (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(el) {
      var shortcut;
      shortcut = $.el('span', {
        className: 'shortcut brackets-wrap'
      });
      $.add(shortcut, el);
      return $.prepend(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. [<a href=\"https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions#why-is-4chan-x-asking-for-permission-to-show-desktop-notifications\" target=\"_blank\">FAQ</a>]<br><button>Authorize</button> or <button>Disable</button>"
      });
      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);
    }
  };

  Index = {
    showHiddenThreads: false,
    changed: {},
    init: function() {
      var anchorEntry, input, k, label, len1, len2, name, pinEntry, q, ref, ref1, ref2, ref3, ref4, ref5, ref6, refNavEntry, repliesEntry, select, sortEntry;
      if (g.BOARD.ID === 'f' || !Conf['JSON Index'] || g.VIEW !== 'index') {
        return;
      }
      CatalogThread.callbacks.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', Index.scroll);
      this.button = $.el('a', {
        className: 'index-refresh-shortcut fa fa-refresh',
        title: 'Refresh',
        href: 'javascript:;',
        textContent: 'Refresh Index'
      });
      $.on(this.button, 'click', function() {
        return Index.update();
      });
      Header.addShortcut(this.button, 1);
      repliesEntry = {
        el: UI.checkbox('Show Replies', 'Show replies')
      };
      sortEntry = {
        el: UI.checkbox('Per-Board Sort Type', 'Per-board sort type', typeof Conf['Index Sort'] === 'object')
      };
      pinEntry = {
        el: UI.checkbox('Pin Watched Threads', 'Pin watched threads')
      };
      anchorEntry = {
        el: UI.checkbox('Anchor Hidden Threads', 'Anchor hidden threads')
      };
      refNavEntry = {
        el: UI.checkbox('Refreshed Navigation', 'Refreshed navigation')
      };
      sortEntry.el.title = 'Set the sorting order of each board independently.';
      pinEntry.el.title = 'Move watched threads to the start of the index.';
      anchorEntry.el.title = 'Move hidden threads to the end of the index.';
      refNavEntry.el.title = 'Refresh index when navigating through pages.';
      ref4 = [repliesEntry, pinEntry, anchorEntry, refNavEntry];
      for (k = 0, len1 = ref4.length; k < len1; k++) {
        label = ref4[k];
        input = label.el.firstChild;
        name = input.name;
        $.on(input, 'change', $.cb.checked);
        switch (name) {
          case 'Show Replies':
            $.on(input, 'change', this.cb.replies);
            break;
          case 'Pin Watched Threads':
          case 'Anchor Hidden Threads':
            $.on(input, 'change', this.cb.resort);
        }
      }
      $.on(sortEntry.el.firstChild, 'change', this.cb.perBoardSort);
      Header.menu.addEntry({
        el: $.el('span', {
          textContent: 'Index Navigation'
        }),
        order: 100,
        subEntries: [repliesEntry, sortEntry, pinEntry, anchorEntry, refNavEntry]
      });
      this.navLinks = $.el('div', {
        className: 'navLinks json-index'
      });
      $.extend(this.navLinks, {
        innerHTML: "<span class=\"brackets-wrap indexlink\"><a href=\"#index\">Index</a></span> <span class=\"brackets-wrap cataloglink\"><a href=\"#catalog\">Catalog</a></span> <span class=\"brackets-wrap archlistlink\"><a href=\"./archive\">Archive</a></span> <span class=\"brackets-wrap bottomlink\"><a href=\"#bottom\">Bottom</a></span> <span class=\"brackets-wrap\" id=\"index-last-refresh\"><a href=\"javascript:;\"><time title=\"Last index refresh\">...</time></a></span> <input type=\"search\" id=\"index-search\" class=\"field\" placeholder=\"Search\"><a id=\"index-search-clear\" href=\"javascript:;\" title=\"Clear search\">×</a><span id=\"hidden-label\" hidden> &mdash; <span id=\"hidden-count\"></span> <span id=\"hidden-toggle\">[<a href=\"javascript:;\">Show</a>]</span></span><select id=\"index-mode\" name=\"Index Mode\"><option disabled>Index Mode</option><option value=\"paged\">Paged</option><option value=\"infinite\">Infinite scrolling</option><option value=\"all pages\">All threads</option><option value=\"catalog\">Catalog</option></select><select id=\"index-sort\" name=\"Index Sort\"><option disabled>Index Sort</option><option value=\"bump\">Bump order</option><option value=\"lastreply\">Last reply</option><option value=\"lastlong\">Last long reply</option><option value=\"birth\">Creation date</option><option value=\"replycount\">Reply count</option><option value=\"filecount\">File count</option></select><select id=\"index-size\" name=\"Index Size\"><option disabled>Image Size</option><option value=\"small\">Small</option><option value=\"large\">Large</option></select>"
      });
      $('.cataloglink a', this.navLinks).href = CatalogLinks.catalog();
      if ((ref5 = g.BOARD.ID) === 'b' || ref5 === 'trash') {
        $('.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.selectMode = $('#index-mode', this.navLinks);
      this.selectSort = $('#index-sort', this.navLinks);
      this.selectSize = $('#index-size', this.navLinks);
      $.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);
      ref6 = [this.selectMode, this.selectSize];
      for (q = 0, len2 = ref6.length; q < len2; q++) {
        select = ref6[q];
        select.value = Conf[select.name];
      }
      this.selectSort.value = Index.currentSort;
      this.root = $.el('div', {
        className: 'board json-index'
      });
      this.cb.size();
      this.pagelist = $.el('div', {
        className: 'pagelist json-index'
      });
      $.extend(this.pagelist, {
        innerHTML: "<div class=\"prev\"><a><button disabled>Previous</button></a></div><div class=\"pages\"></div><div class=\"next\"><a><button disabled>Next</button></a></div><div class=\"pages cataloglink\"><a href=\"./catalog\">Catalog</a></div>"
      });
      $('.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, len4, ref7, ref8, threadRoot, topNavPos, u, v;
        Index.hat = $('.board > .thread > img:first-child');
        if (Index.hat) {
          if (Index.nodes) {
            ref7 = Index.nodes;
            for (u = 0, len3 = ref7.length; u < len3; u++) {
              threadRoot = ref7[u];
              $.prepend(threadRoot, Index.hat.cloneNode(false));
            }
          }
          $.addClass(doc, 'hats-enabled');
          $.addStyle(".catalog-thread::after {background-image: url(" + Index.hat.src + ");}");
        }
        board = $('.board');
        $.replace(board, Index.root);
        $.event('PostsInserted');
        try {
          d.implementation.createDocument(null, null, null).appendChild(board);
        } catch (_error) {}
        ref8 = $$('.navLinks');
        for (v = 0, len4 = ref8.length; v < len4; v++) {
          el = ref8[v];
          $.rm(el);
        }
        $.rm($.id('ctrl-top'));
        topNavPos = $.id('delform').previousElementSibling;
        $.before(topNavPos, $.el('hr'));
        return $.before(topNavPos, Index.navLinks);
      });
      return Main.ready(function() {
        var pagelist;
        if ((pagelist = $('.pagelist'))) {
          $.replace(pagelist, Index.pagelist);
        }
        return $.rmClass(doc, 'index-loading');
      });
    },
    scroll: function() {
      var nodes, pageNum;
      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();
      }
      nodes = Index.buildSinglePage(pageNum);
      if (Conf['Show Replies']) {
        Index.buildReplies(nodes);
      }
      return Index.buildStructure(nodes);
    },
    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['JSON Index'] || !Conf['Menu'] || !Conf['Thread Hiding Link'] || g.BOARD.ID === 'f') {
          return;
        }
        return Menu.menu.addEntry({
          el: $.el('a', {
            href: 'javascript:;',
            className: 'has-shortcut-text'
          }, {
            innerHTML: "<span></span><span class=\"shortcut-text\">Shift+click</span>"
          }),
          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;
          }
        });
      }
    },
    catalogNode: function() {
      return $.on(this.nodes.thumb.parentNode, 'click', Index.onClick);
    },
    onClick: function(e) {
      var thread;
      if (e.button !== 0) {
        return;
      }
      thread = g.threads[this.parentNode.dataset.fullID];
      if (e.shiftKey) {
        Index.toggleHide(thread);
      } else {
        return;
      }
      return e.preventDefault();
    },
    toggleHide: function(thread) {
      $.rm(thread.catalogView.nodes.root);
      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: {
      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() {
        Index.pushState({
          sort: this.value
        });
        return Index.pageLoad(false);
      },
      resort: function() {
        Index.sort();
        return Index.buildIndex();
      },
      perBoardSort: function() {
        Conf['Index Sort'] = this.checked ? {} : '';
        return Index.saveSort();
      },
      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() {
        Index.buildThreads();
        Index.sort();
        return Index.buildIndex();
      },
      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 (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
          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();
      }
    },
    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'
      }
    },
    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 = Index.hashCommands.mode[command])) {
          state.mode = mode;
        } else if (command === 'index') {
          state.mode = Conf['Previous Index Mode'];
          state.page = 1;
        } else if ((sort = Index.hashCommands.sort[command])) {
          state.sort = sort;
        } 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;
      }
    },
    saveSort: function() {
      if (typeof Conf['Index Sort'] === 'object') {
        Conf['Index Sort'][g.BOARD.ID] = Index.currentSort;
      } else {
        Conf['Index Sort'] = Index.currentSort;
      }
      return $.set('Index Sort', Conf['Index Sort']);
    },
    pageLoad: function(scroll) {
      var hash, mode, page, ref, search, sort, threads;
      if (scroll == null) {
        scroll = true;
      }
      if (!Index.liveThreadData) {
        return;
      }
      ref = Index.changed, threads = ref.threads, search = ref.search, mode = ref.mode, sort = ref.sort, page = ref.page, hash = ref.hash;
      if (threads || search || sort) {
        Index.sort();
      }
      if (threads || search) {
        Index.buildPagelist();
      }
      if (search) {
        Index.setupSearch();
      }
      if (mode) {
        Index.setupMode();
      }
      if (sort) {
        Index.setupSort();
      }
      if (threads || search || mode || page || sort) {
        Index.buildIndex();
      }
      if (threads || search || mode || 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() {
      return Index.selectSort.value = Index.currentSort;
    },
    getPagesNum: function() {
      if (Index.search) {
        return Math.ceil(Index.sortedNodes.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');
      }
      a = pagesRoot.children[pageNum - 1];
      $.before(a, strong);
      return $.add(strong, a);
    },
    updateHideLabel: function() {
      var hiddenCount, ref, ref1, thread, threadID;
      hiddenCount = 0;
      ref = g.BOARD.threads;
      for (threadID in ref) {
        thread = ref[threadID];
        if (thread.isHidden) {
          if (ref1 = thread.ID, indexOf.call(Index.liveThreadIDs, ref1) >= 0) {
            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 now, ref, ref1;
      if ((ref = Index.req) != null) {
        ref.abort();
      }
      if ((ref1 = Index.notice) != null) {
        ref1.close();
      }
      if (Conf['Index Refresh Notifications'] && d.readyState !== 'loading') {
        Index.notice = new Notice('info', 'Refreshing index...');
      } else {
        now = Date.now();
        $.ready(function() {
          return Index.nTimeout = setTimeout((function() {
            if (Index.req && !Index.notice) {
              return Index.notice = new Notice('info', 'Refreshing index...');
            }
          }), 3 * $.SECOND - (Date.now() - now));
        });
      }
      if (!firstTime && d.readyState !== 'loading' && !$('.board + *')) {
        location.reload();
        return;
      }
      Index.req = $.ajax("//a.4cdn.org/" + g.BOARD + "/catalog.json", {
        onabort: Index.load,
        onloadend: Index.load
      }, {
        whenModified: 'Index'
      });
      return $.addClass(Index.button, 'fa-spin');
    },
    load: function(e) {
      var err, nTimeout, notice, ref, req, timeEl;
      $.rmClass(Index.button, 'fa-spin');
      req = Index.req, notice = Index.notice, nTimeout = Index.nTimeout;
      if (nTimeout) {
        clearTimeout(nTimeout);
      }
      delete Index.nTimeout;
      delete Index.req;
      delete Index.notice;
      if (e.type === 'abort') {
        req.onloadend = null;
        if (notice != null) {
          notice.close();
        }
        return;
      }
      if ((ref = req.status) !== 200 && ref !== 304) {
        err = "Index refresh failed. Error " + req.statusText + " (" + req.status + ")";
        if (notice) {
          notice.setType('warning');
          notice.el.lastElementChild.textContent = err;
          setTimeout(notice.close, $.SECOND);
        } else {
          new Notice('warning', err, 1);
        }
        return;
      }
      try {
        if (req.status === 200) {
          Index.parse(req.response);
        } else if (req.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(req.getResponseHeader('Last-Modified'));
      return RelativeDates.update(timeEl);
    },
    parse: function(pages) {
      $.cleanCache(function(url) {
        return /^\/\/a\.4cdn\.org\//.test(url);
      });
      Index.parseThreadList(pages);
      Index.buildThreads();
      Index.changed.threads = true;
      return Index.pageLoad();
    },
    parseThreadList: function(pages) {
      var ref;
      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;
      });
      g.BOARD.threads.forEach(function(thread) {
        var ref1;
        if (ref1 = thread.ID, indexOf.call(Index.liveThreadIDs, ref1) < 0) {
          return thread.collect();
        }
      });
    },
    buildThreads: function() {
      var err, errors, i, k, len1, posts, ref, thread, threadData, threadRoot, threads;
      if (!Index.liveThreadData) {
        return;
      }
      Index.nodes = [];
      threads = [];
      posts = [];
      ref = Index.liveThreadData;
      for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
        threadData = ref[i];
        try {
          threadRoot = Build.thread(g.BOARD, threadData);
          if (Index.hat) {
            $.prepend(threadRoot, Index.hat.cloneNode(false));
          }
          if (thread = g.BOARD.threads[threadData.no]) {
            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);
          } else {
            thread = new Thread(threadData.no, g.BOARD);
            threads.push(thread);
          }
          Index.nodes.push(threadRoot);
          if (!(thread.OP && !thread.OP.isFetchedQuote)) {
            posts.push(new Post($('.opContainer', threadRoot), thread, g.BOARD));
          }
          thread.setPage(Math.floor(i / Index.threadsNumPerPage) + 1);
        } catch (_error) {
          err = _error;
          if (!errors) {
            errors = [];
          }
          errors.push({
            message: "Parsing of Thread No." + thread + " failed. Thread will be skipped.",
            error: err
          });
        }
      }
      if (errors) {
        Main.handleErrors(errors);
      }
      $.nodes(Index.nodes);
      Main.callbackNodes(Thread, threads);
      Main.callbackNodes(Post, posts);
      Index.updateHideLabel();
      return $.event('IndexRefresh');
    },
    buildReplies: function(threadRoots) {
      var data, err, errors, i, k, lastReplies, len1, len2, node, nodes, post, posts, q, thread, threadRoot;
      posts = [];
      for (k = 0, len1 = threadRoots.length; k < len1; k++) {
        threadRoot = threadRoots[k];
        thread = Get.threadFromRoot(threadRoot);
        i = Index.liveThreadIDs.indexOf(thread.ID);
        if (!(lastReplies = Index.liveThreadData[i].last_replies)) {
          continue;
        }
        nodes = [];
        for (q = 0, len2 = lastReplies.length; q < len2; q++) {
          data = lastReplies[q];
          if ((post = thread.posts[data.no]) && !post.isFetchedQuote) {
            nodes.push(post.nodes.root);
            continue;
          }
          nodes.push(node = 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
            });
          }
        }
        $.add(threadRoot, nodes);
      }
      if (errors) {
        Main.handleErrors(errors);
      }
      return Main.callbackNodes(Post, posts);
    },
    buildCatalogViews: function() {
      var catalogThreads, k, len1, thread, threads;
      threads = Index.sortedNodes.map(function(threadRoot) {
        return Get.threadFromRoot(threadRoot);
      }).filter(function(thread) {
        return !thread.isHidden !== Index.showHiddenThreads;
      });
      catalogThreads = [];
      for (k = 0, len1 = threads.length; k < len1; k++) {
        thread = threads[k];
        if (!thread.catalogView) {
          catalogThreads.push(new CatalogThread(Build.catalogThread(thread), thread));
        }
      }
      Main.callbackNodes(CatalogThread, catalogThreads);
      return threads.map(function(thread) {
        return thread.catalogView.nodes.root;
      });
    },
    sizeCatalogViews: function(nodes) {
      var height, k, len1, node, ratio, ref, size, thumb, width;
      size = Conf['Index Size'] === 'small' ? 150 : 250;
      for (k = 0, len1 = nodes.length; k < len1; k++) {
        node = nodes[k];
        thumb = $('.catalog-thumb', node);
        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';
      }
    },
    sort: function() {
      var k, lastlong, len1, liveThreadData, liveThreadIDs, nodes, sortedNodes, sortedThreadIDs, threadID;
      liveThreadIDs = Index.liveThreadIDs, liveThreadData = Index.liveThreadData;
      if (!liveThreadData) {
        return;
      }
      sortedThreadIDs = (function() {
        switch (Index.currentSort) {
          case 'lastreply':
            return slice.call(liveThreadData).sort(function(a, b) {
              var num;
              if ((num = a.last_replies)) {
                a = num[num.length - 1];
              }
              if ((num = b.last_replies)) {
                b = num[num.length - 1];
              }
              return b.no - a.no;
            }).map(function(post) {
              return post.no;
            });
          case 'lastlong':
            lastlong = function(thread) {
              var i, k, r, ref;
              ref = thread.last_replies || [];
              for (i = k = ref.length - 1; k >= 0; i = k += -1) {
                r = ref[i];
                if (r.com && Build.parseComment(r.com).replace(/[^a-z]/ig, '').length >= 100) {
                  return r;
                }
              }
              return thread;
            };
            return slice.call(liveThreadData).sort(function(a, b) {
              return lastlong(b).no - lastlong(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;
            });
        }
      })();
      Index.sortedNodes = sortedNodes = [];
      nodes = Index.nodes;
      for (k = 0, len1 = sortedThreadIDs.length; k < len1; k++) {
        threadID = sortedThreadIDs[k];
        sortedNodes.push(nodes[Index.liveThreadIDs.indexOf(threadID)]);
      }
      if (Index.search && (nodes = Index.querySearch(Index.search))) {
        Index.sortedNodes = nodes;
      }
      Index.sortOnTop(function(thread) {
        return thread.isSticky;
      });
      Index.sortOnTop(function(thread) {
        return thread.isOnTop || Conf['Pin Watched Threads'] && ThreadWatcher.isWatched(thread);
      });
      if (Conf['Anchor Hidden Threads']) {
        return Index.sortOnTop(function(thread) {
          return !thread.isHidden;
        });
      }
    },
    sortOnTop: function(match) {
      var bottomNodes, k, len1, ref, threadRoot, topNodes;
      topNodes = [];
      bottomNodes = [];
      ref = Index.sortedNodes;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        threadRoot = ref[k];
        (match(Get.threadFromRoot(threadRoot)) ? topNodes : bottomNodes).push(threadRoot);
      }
      return Index.sortedNodes = topNodes.concat(bottomNodes);
    },
    buildIndex: function() {
      var i, nodes, page, post;
      if (!Index.liveThreadData) {
        return;
      }
      switch (Conf['Index Mode']) {
        case 'all pages':
          nodes = Index.sortedNodes;
          break;
        case 'catalog':
          nodes = Index.buildCatalogViews();
          Index.sizeCatalogViews(nodes);
          break;
        default:
          if (Index.followedThreadID != null) {
            i = 0;
            while (Index.followedThreadID !== Get.threadFromRoot(Index.sortedNodes[i]).ID) {
              i++;
            }
            page = Math.floor(i / Index.threadsNumPerPage) + 1;
            if (page !== Index.currentPage) {
              Index.currentPage = page;
              Index.pushState({
                page: page
              });
              Index.setPage();
            }
          }
          nodes = Index.buildSinglePage(Index.currentPage);
      }
      delete Index.pageNum;
      $.rmAll(Index.root);
      $.rmAll(Header.hover);
      if (Conf['Index Mode'] === 'catalog') {
        return $.add(Index.root, nodes);
      } else {
        if (Conf['Show Replies']) {
          Index.buildReplies(nodes);
        }
        Index.buildStructure(nodes);
        if ((Index.followedThreadID != null) && (post = g.posts[g.BOARD + "." + Index.followedThreadID])) {
          return Header.scrollTo(post.nodes.root);
        }
      }
    },
    buildSinglePage: function(pageNum) {
      var nodesPerPage, offset;
      nodesPerPage = Index.threadsNumPerPage;
      offset = nodesPerPage * (pageNum - 1);
      return Index.sortedNodes.slice(offset, offset + nodesPerPage);
    },
    buildStructure: function(nodes) {
      var k, len1, node, thumb;
      for (k = 0, len1 = nodes.length; k < len1; k++) {
        node = nodes[k];
        if (thumb = $('img[data-src]', node)) {
          thumb.src = thumb.dataset.src;
          thumb.removeAttribute('data-src');
        }
        $.add(Index.root, [node, $.el('hr')]);
      }
      if (doc.contains(Index.root)) {
        $.event('PostsInserted');
      }
      return ThreadHiding.onIndexBuild(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;
      if (!(keywords = query.toLowerCase().match(/\S+/g))) {
        return;
      }
      return Index.sortedNodes.filter(function(threadRoot) {
        return Index.searchMatch(Get.threadFromRoot(threadRoot), keywords);
      });
    },
    searchMatch: function(thread, keywords) {
      var file, info, k, key, keyword, len1, len2, q, ref, ref1, text;
      ref = thread.OP, info = ref.info, file = ref.file;
      text = [];
      ref1 = ['comment', 'subject', 'name', 'tripcode', 'email'];
      for (k = 0, len1 = ref1.length; k < len1; k++) {
        key = ref1[k];
        if (key in info) {
          text.push(info[key]);
        }
      }
      if (file) {
        text.push(file.name);
      }
      text = text.join(' ').toLowerCase();
      for (q = 0, len2 = keywords.length; q < len2; q++) {
        keyword = keywords[q];
        if (-1 === text.indexOf(keyword)) {
          return false;
        }
      }
      return true;
    }
  };

  Build = {
    staticPath: '//s.4cdn.org/image/',
    gifIcon: window.devicePixelRatio >= 2 ? '@2x.gif' : '.gif',
    spoilerRange: {},
    unescape: function(text) {
      if (text == null) {
        return text;
      }
      return text.replace(/<[^>]*>/g, '').replace(/&(amp|#039|quot|lt|gt|#44);/g, function(c) {
        return {
          '&amp;': '&',
          '&#039;': "'",
          '&quot;': '"',
          '&lt;': '<',
          '&gt;': '>',
          '&#44;': ','
        }[c];
      });
    },
    shortFilename: function(filename) {
      var ext, threshold;
      threshold = 30;
      ext = filename.match(/\.?[^\.]*$/)[0];
      if (filename.length - ext.length > threshold) {
        return filename.slice(0, threshold - 5) + "(...)" + 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;
    },
    postURL: function(boardID, threadID, postID) {
      if (Build.sameThread(boardID, threadID)) {
        return "#p" + postID;
      } else {
        return "/" + boardID + "/thread/" + threadID + "#p" + postID;
      }
    },
    parseJSON: function(data, boardID) {
      var o;
      o = {
        postID: data.no,
        threadID: data.resto || data.no,
        boardID: boardID,
        isReply: !!data.resto,
        isSticky: !!data.sticky,
        isClosed: !!data.closed,
        isArchived: !!data.archived,
        fileDeleted: !!data.filedeleted
      };
      o.info = {
        subject: Build.unescape(data.sub),
        email: Build.unescape(data.email),
        name: Build.unescape(data.name) || '',
        tripcode: data.trip,
        uniqueID: data.id,
        flagCode: data.country,
        flag: Build.unescape(data.country_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;
      }
      if (data.ext) {
        o.file = {
          name: (Build.unescape(data.filename)) + data.ext,
          url: boardID === 'f' ? location.protocol + "//i.4cdn.org/" + boardID + "/" + (encodeURIComponent(data.filename)) + data.ext : location.protocol + "//i.4cdn.org/" + boardID + "/" + data.tim + data.ext,
          height: data.h,
          width: data.w,
          MD5: data.md5,
          size: $.bytesToString(data.fsize),
          thumbURL: location.protocol + "//i.4cdn.org/" + boardID + "/" + data.tim + "s.jpg",
          theight: data.tn_h,
          twidth: data.tn_w,
          isSpoiler: !!data.spoiler,
          tag: data.tag
        };
        if (!/\.pdf$/.test(o.file.url)) {
          o.file.dimensions = o.file.width + "x" + o.file.height;
        }
      }
      return o;
    },
    parseComment: function(html) {
      html = html.replace(/<br\b[^<]*>/gi, '\n').replace(/\n\n<span\b[^<]* class="abbr"[^]*$/i, '').replace(/^<b\b[^<]*>Rolled [^<]*<\/b>/i, '').replace(/<span\b[^<]* class="fortune"[^]*$/i, '').replace(/<[^>]*>/g, '');
      return Build.unescape(html);
    },
    postFromObject: function(data, boardID, suppressThumb) {
      var o;
      o = Build.parseJSON(data, boardID);
      return Build.post(o, suppressThumb);
    },
    post: function(o, suppressThumb) {
      var boardID, capcode, capcodeDescription, capcodeLC, capcodeLong, capcodePlural, commentHTML, container, dateText, dateUTC, email, file, fileBlock, fileThumb, fileURL, flag, flagCode, gifIcon, href, k, len1, match, name, postClass, postID, postInfo, postLink, protocol, quote, quoteLink, ref, ref1, shortFilename, staticPath, subject, threadID, tripcode, uniqueID, wholePost;
      postID = o.postID, threadID = o.threadID, boardID = o.boardID, file = o.file;
      ref = o.info, subject = ref.subject, email = ref.email, name = ref.name, tripcode = ref.tripcode, capcode = ref.capcode, uniqueID = ref.uniqueID, flagCode = ref.flagCode, flag = ref.flag, dateUTC = ref.dateUTC, dateText = ref.dateText, commentHTML = ref.commentHTML;
      staticPath = Build.staticPath, gifIcon = Build.gifIcon;

      /* Post Info */
      if (capcode) {
        capcodeLC = capcode.toLowerCase();
        if (capcode === 'Founder') {
          capcodePlural = 'the Founder';
          capcodeDescription = "4chan's Founder";
        } else {
          capcodeLong = {
            'Admin': 'Administrator',
            'Mod': 'Moderator'
          }[capcode] || capcode;
          capcodePlural = capcodeLong + "s";
          capcodeDescription = "a 4chan " + capcodeLong;
        }
      }
      postLink = Build.postURL(boardID, threadID, postID);
      quoteLink = Build.sameThread(boardID, threadID) ? "javascript:quote('" + (+postID) + "');" : "/" + boardID + "/thread/" + threadID + "#q" + postID;
      postInfo = {
        innerHTML: "<div class=\"postInfo desktop\" id=\"pi" + E(postID) + "\"><input type=\"checkbox\" name=\"" + E(postID) + "\" value=\"delete\"> " + (!o.isReply || boardID === "f" || subject ? "<span class=\"subject\">" + E(subject || "") + "</span> " : "") + "<span class=\"nameBlock" + (capcode ? " capcode" + E(capcode) : "") + "\">" + (email ? "<a href=\"mailto:" + E(encodeURIComponent(email).replace(/%40/g, "@")) + "\" class=\"useremail\">" : "") + "<span class=\"name" + (capcode ? " capcode" : "") + "\">" + E(name) + "</span>" + (tripcode ? " <span class=\"postertrip\">" + E(tripcode) + "</span>" : "") + (capcode ? " <strong class=\"capcode hand id_" + E(capcodeLC) + "\" title=\"Highlight posts by " + E(capcodePlural) + "\">## " + E(capcode) + "</strong>" : "") + (email ? "</a>" : "") + (boardID === "f" && !o.isReply || capcode ? "" : " ") + (capcode ? " <img src=\"" + E(staticPath) + E(capcodeLC) + "icon" + E(gifIcon) + "\" alt=\"" + E(capcode) + " Icon\" title=\"This user is " + E(capcodeDescription) + ".\" class=\"identityIcon retina\">" : "") + (uniqueID && !capcode ? " <span class=\"posteruid id_" + E(uniqueID) + "\">(ID: <span class=\"hand\" title=\"Highlight posts by this ID\">" + E(uniqueID) + "</span>)</span>" : "") + (flagCode ? " <span title=\"" + E(flag) + "\" class=\"flag flag-" + E(flagCode.toLowerCase()) + "\"></span>" : "") + "</span> <span class=\"dateTime\" data-utc=\"" + E(dateUTC) + "\">" + E(dateText) + "</span> <span class=\"postNum" + (!(boardID === "f" && !o.isReply) ? " desktop" : "") + "\"><a href=\"" + E(postLink) + "\" title=\"Link to this post\">No.</a><a href=\"" + E(quoteLink) + "\" title=\"Reply to this post\">" + E(postID) + "</a>" + (o.isSticky ? " <img src=\"" + E(staticPath) + "sticky" + E(gifIcon) + "\" alt=\"Sticky\" title=\"Sticky\" class=\"stickyIcon retina\">" : "") + (o.isClosed && !o.isArchived ? " <img src=\"" + E(staticPath) + "closed" + E(gifIcon) + "\" alt=\"Closed\" title=\"Closed\" class=\"closedIcon retina\">" : "") + (o.isArchived ? " <img src=\"" + E(staticPath) + "archived" + E(gifIcon) + "\" alt=\"Archived\" title=\"Archived\" class=\"archivedIcon retina\">" : "") + (!o.isReply && g.VIEW === "index" ? " &nbsp; <span>[<a href=\"/" + E(boardID) + "/thread/" + E(threadID) + "\" class=\"replylink\">Reply</a>]</span>" : "") + "</span></div>"
      };

      /* 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 ? "<div class=\"file\" id=\"f" + E(postID) + "\">" + (boardID === "f" ? "<div class=\"fileInfo\"><span class=\"fileText\" id=\"fT" + E(postID) + "\">File: <a data-width=\"" + E(file.width) + "\" data-height=\"" + E(file.height) + "\" href=\"" + E(fileURL) + "\" target=\"_blank\">" + E(file.name) + "</a>-(" + E(file.size) + ", " + E(file.dimensions) + (file.tag ? ", " + E(file.tag) : "") + ")</span></div>" : "<div class=\"fileText\" id=\"fT" + E(postID) + "\"" + (file.isSpoiler ? " title=\"" + E(file.name) + "\"" : "") + ">File: <a" + (file.name === shortFilename || file.isSpoiler ? "" : " title=\"" + E(file.name) + "\"") + " href=\"" + E(fileURL) + "\" target=\"_blank\">" + (file.isSpoiler ? "Spoiler Image" : E(shortFilename)) + "</a> (" + E(file.size) + ", " + E(file.dimensions || "PDF") + ")</div><a class=\"fileThumb" + (file.isSpoiler ? " imgspoiler" : "") + "\" href=\"" + E(fileURL) + "\" target=\"_blank\"><img" + (suppressThumb ? " data-src=\"" + E(fileThumb) + "\"" : " src=\"" + E(fileThumb) + "\"") + " alt=\"" + E(file.size) + "\" data-md5=\"" + E(file.MD5) + "\" style=\"height: " + E(file.isSpoiler ? 100 : file.theight) + "px; width: " + E(file.isSpoiler ? 100 : file.twidth) + "px;\"></a>") + "</div>" : (o.fileDeleted ? "<div class=\"file\" id=\"f" + E(postID) + "\"><span class=\"fileThumb\"><img src=\"" + E(staticPath) + "filedeleted-res" + E(gifIcon) + "\" alt=\"File deleted.\" class=\"fileDeletedRes retina\"></span></div>" : ""))
      };

      /* Whole Post */
      postClass = o.isReply ? 'reply' : 'op';
      wholePost = {
        innerHTML: (o.isReply ? "<div class=\"sideArrows\" id=\"sa" + E(postID) + "\">&gt;&gt;</div>" : "") + "<div id=\"p" + E(postID) + "\" class=\"post " + E(postClass) + (o.capcodeHighlight ? " highlightPost" : "") + "\">" + (o.isReply ? postInfo.innerHTML + fileBlock.innerHTML : fileBlock.innerHTML + postInfo.innerHTML) + "<blockquote class=\"postMessage\" id=\"m" + E(postID) + "\">" + commentHTML.innerHTML + "</blockquote></div>"
      };
      container = $.el('div', {
        className: "postContainer " + postClass + "Container",
        id: "pc" + postID
      });
      $.extend(container, wholePost);
      ref1 = $$('.quotelink', container);
      for (k = 0, len1 = ref1.length; k < len1; k++) {
        quote = ref1[k];
        href = quote.getAttribute('href');
        if ((href[0] === '#') && !(Build.sameThread(boardID, threadID))) {
          quote.href = ("/" + boardID + "/thread/" + threadID) + href;
        } else if ((match = href.match(/^\/([^\/]+)\/thread\/(\d+)/)) && (Build.sameThread(match[1], match[2]))) {
          quote.href = href.match(/(#[^#]*)?$/)[0] || '#';
        } else if (/^\d+(#|$)/.test(href) && !(g.VIEW === 'thread' && g.BOARD.ID === boardID)) {
          quote.href = "/" + boardID + "/thread/" + href;
        }
      }
      return container;
    },
    summary: function(boardID, threadID, posts, files) {
      var text;
      text = [];
      text.push(posts + " post" + (posts > 1 ? 's' : ''));
      if (files) {
        text.push("and " + files + " image repl" + (files > 1 ? 'ies' : 'y'));
      }
      text.push('omitted.');
      return $.el('a', {
        className: 'summary',
        textContent: text.join(' '),
        href: "/" + boardID + "/thread/" + threadID
      });
    },
    thread: function(board, data, full) {
      var OP, root;
      Build.spoilerRange[board] = data.custom_spoiler;
      if (OP = board.posts[data.no]) {
        if (OP.isFetchedQuote) {
          OP = null;
        }
      }
      if (OP && (root = OP.nodes.root.parentNode)) {
        $.rmAll(root);
      } else {
        root = $.el('div', {
          className: 'thread',
          id: "t" + data.no
        });
      }
      $.add(root, Build[full ? 'fullThread' : 'excerptThread'](board, data, OP));
      return root;
    },
    excerptThread: function(board, data, OP) {
      var files, nodes, posts, ref;
      nodes = [OP ? OP.nodes.root : Build.postFromObject(data, board.ID, true)];
      if (data.omitted_posts || !Conf['Show Replies'] && data.replies) {
        ref = Conf['Show Replies'] ? [
          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];
        nodes.push(Build.summary(board.ID, data.no, posts, files));
      }
      return nodes;
    },
    fullThread: function(board, data) {
      return Build.postFromObject(data, board.ID);
    },
    catalogThread: function(thread) {
      var br, cc, comment, data, exif, fileCount, gifIcon, href, imgClass, k, len1, len2, len3, len4, pageCount, postCount, pp, q, quote, ref, ref1, ref2, ref3, ref4, root, spoilerRange, src, staticPath, u, v;
      staticPath = Build.staticPath, gifIcon = Build.gifIcon;
      data = Index.liveThreadData[Index.liveThreadIDs.indexOf(thread.ID)];
      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';
      } else if (data.filedeleted) {
        src = staticPath + "filedeleted-res" + gifIcon;
        imgClass = 'deleted-file';
      } else if (thread.OP.file) {
        src = thread.OP.file.thumbURL;
      } else {
        src = staticPath + "nofile.png";
        imgClass = 'no-file';
      }
      postCount = data.replies + 1;
      fileCount = data.images + !!data.ext;
      pageCount = Math.floor(Index.liveThreadIDs.indexOf(thread.ID) / Index.threadsNumPerPage) + 1;
      comment = {
        innerHTML: data.com || ''
      };
      root = $.el('div', {
        className: 'catalog-thread'
      });
      $.extend(root, {
        innerHTML: "<a href=\"/" + E(thread.board) + "/thread/" + E(thread.ID) + "\"><img src=\"" + E(src) + "\"" + (imgClass ? " class=\"catalog-thumb " + E(imgClass) + "\"" : " class=\"catalog-thumb\" data-width=\"" + E(data.tn_w) + "\" data-height=\"" + E(data.tn_h) + "\"") + "></a><div class=\"catalog-stats\"><span title=\"Posts / Files / Page\"><span class=\"post-count\">" + E(postCount) + "</span> / <span class=\"file-count\">" + E(fileCount) + "</span> / <span class=\"page-count\">" + E(pageCount) + "</span></span><span class=\"catalog-icons\"></span></div>" + (thread.OP.info.subject ? "<div class=\"subject\">" + E(thread.OP.info.subject) + "</div>" : "") + "<div class=\"comment\">" + comment.innerHTML + "</div>"
      });
      root.dataset.fullID = thread.fullID;
      if (thread.OP.highlights) {
        $.addClass.apply($, [root].concat(slice.call(thread.OP.highlights)));
      }
      ref = $$('.quotelink', root.lastElementChild);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        quote = ref[k];
        href = quote.getAttribute('href');
        if (href[0] === '#') {
          quote.href = ("/" + thread.board + "/thread/" + thread.ID) + href;
        }
      }
      ref1 = $$('.abbr, .exif', root.lastElementChild);
      for (q = 0, len2 = ref1.length; q < len2; q++) {
        exif = ref1[q];
        $.rm(exif);
      }
      ref2 = $$('.prettyprint', root.lastElementChild);
      for (u = 0, len3 = ref2.length; u < len3; u++) {
        pp = ref2[u];
        cc = $.el('span', {
          className: 'catalog-code'
        });
        $.add(cc, slice.call(pp.childNodes));
        $.replace(pp, cc);
      }
      ref3 = $$('br', root.lastElementChild);
      for (v = 0, len4 = ref3.length; v < len4; v++) {
        br = ref3[v];
        if (((ref4 = br.previousSibling) != null ? ref4.nodeName : void 0) === 'BR') {
          $.rm(br);
        }
      }
      if (thread.isSticky) {
        $.add($('.catalog-icons', root), $.el('img', {
          src: staticPath + "sticky" + gifIcon,
          className: 'stickyIcon',
          title: 'Sticky'
        }));
      }
      if (thread.isClosed) {
        $.add($('.catalog-icons', root), $.el('img', {
          src: staticPath + "closed" + gifIcon,
          className: 'closedIcon',
          title: 'Closed'
        }));
      }
      if (data.bumplimit) {
        $.addClass($('.post-count', root), 'warning');
      }
      if (data.imagelimit) {
        $.addClass($('.file-count', root), 'warning');
      }
      return root;
    }
  };

  Get = {
    threadExcerpt: function(thread) {
      var OP, excerpt, ref;
      OP = thread.OP;
      excerpt = ("/" + thread.board + "/ - ") + (((ref = OP.info.subject) != null ? ref.trim() : void 0) || OP.info.commentDisplay.replace(/\n+/g, ' // ') || OP.info.nameBlock);
      if (excerpt.length > 73) {
        return excerpt.slice(0, 70) + "...";
      }
      return excerpt;
    },
    threadFromRoot: function(root) {
      return g.threads[g.BOARD + "." + root.id.slice(1)];
    },
    threadFromNode: function(node) {
      return Get.threadFromRoot($.x('ancestor::div[@class="thread"]', node));
    },
    postFromRoot: function(root) {
      var index, post;
      if (root == null) {
        return null;
      }
      post = g.posts[root.dataset.fullID];
      index = root.dataset.clone;
      if (index) {
        return post.clones[index];
      } else {
        return post;
      }
    },
    postFromNode: function(root) {
      return Get.postFromRoot($.x('(ancestor::div[contains(@class,"postContainer")][1]|following::div[contains(@class,"postContainer")][1])', root));
    },
    postDataFromLink: function(link) {
      var boardID, path, postID, ref, threadID;
      if (link.hostname === 'boards.4chan.org') {
        path = link.pathname.split(/\/+/);
        boardID = path[1];
        threadID = path[3];
        postID = link.hash.slice(2);
      } else {
        ref = link.dataset, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID;
        threadID || (threadID = 0);
      }
      return {
        boardID: boardID,
        threadID: +threadID,
        postID: +postID
      };
    },
    allQuotelinksLinkingTo: function(post) {
      var fullID, handleQuotes, k, len1, posts, qPost, quote, quotelinks, ref;
      quotelinks = [];
      posts = g.posts;
      fullID = post.fullID;
      handleQuotes = function(qPost, type) {
        var clone, k, len1, ref;
        quotelinks.push.apply(quotelinks, qPost.nodes[type]);
        ref = qPost.clones;
        for (k = 0, len1 = ref.length; k < len1; k++) {
          clone = ref[k];
          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 (k = 0, len1 = ref.length; k < len1; k++) {
          quote = ref[k];
          if (qPost = posts[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;
      });
    },
    scriptData: function() {
      var k, len1, ref, script;
      ref = $$('script:not([src])', d.head);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        script = ref[k];
        if (/\bcooldowns *=/.test(script.textContent)) {
          return script.textContent;
        }
      }
      return '';
    }
  };

  UI = (function() {
    var Menu, checkbox, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove;
    dialog = function(id, position, properties) {
      var child, el, k, len1, move, ref;
      el = $.el('div', {
        className: 'dialog',
        id: id
      });
      $.extend(el, properties);
      el.style.cssText = position;
      $.get(id + ".position", position, function(item) {
        return el.style.cssText = item[id + ".position"];
      });
      move = $('.move', el);
      $.on(move, 'touchstart mousedown', dragstart);
      ref = move.children;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        child = ref[k];
        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(type1) {
        this.type = type1;
        this.addEntry = bind(this.addEntry, this);
        this.onFocus = bind(this.onFocus, this);
        this.keybinds = bind(this.keybinds, this);
        this.close = bind(this.close, 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
        });
        $.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 bLeft, bRect, bTop, bottom, cHeight, cWidth, entry, k, left, len1, mRect, menu, ref, ref1, ref2, right, style, top;
        menu = this.menu = this.makeMenu();
        currentMenu = this;
        lastToggledButton = button;
        this.entries.sort(function(first, second) {
          return first.order - second.order;
        });
        ref = this.entries;
        for (k = 0, len1 = ref.length; k < len1; k++) {
          entry = ref[k];
          this.insertEntry(entry, menu, data);
        }
        $.addClass(lastToggledButton, 'active');
        $.on(d, 'click CloseMenu', this.close);
        if (this.type !== 'gallery') {
          $.on(d, 'scroll', this.close);
        }
        $.add(button, menu);
        mRect = menu.getBoundingClientRect();
        bRect = button.getBoundingClientRect();
        bTop = window.scrollY + bRect.top;
        bLeft = window.scrollX + bRect.left;
        cHeight = doc.clientHeight;
        cWidth = doc.clientWidth;
        ref1 = bRect.top + bRect.height + mRect.height < cHeight ? [bRect.bottom, null] : [null, cHeight - bRect.top], top = ref1[0], bottom = ref1[1];
        ref2 = bRect.left + mRect.width < cWidth ? [bRect.left, null] : [null, cWidth - bRect.right], left = ref2[0], right = ref2[1];
        style = menu.style;
        style.top = top + "px";
        style.right = right + "px";
        style.bottom = bottom + "px";
        style.left = left + "px";
        if (right) {
          $.addClass(menu, 'left');
        }
        entry = $('.entry', menu);
        this.focus(entry);
        return menu.focus();
      };

      Menu.prototype.insertEntry = function(entry, parent, data) {
        var err, k, len1, 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 (k = 0, len1 = ref.length; k < len1; k++) {
          subEntry = ref[k];
          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;
        return $.off(d, 'click scroll CloseMenu', this.close);
      };

      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, k, left, len1, ref, ref1, ref2, right, sRect, style, submenu, top;
        while (focused = $.x('parent::*/child::*[contains(@class,"focused")]', entry)) {
          $.rmClass(focused, 'focused');
        }
        ref = $$('.focused', entry);
        for (k = 0, len1 = ref.length; k < len1; k++) {
          focused = ref[k];
          $.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, k, len1, 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 (k = 0, len1 = subEntries.length; k < len1; k++) {
          subEntry = subEntries[k];
          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 k, len1, ref, touch;
      ref = e.changedTouches;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        touch = ref[k];
        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 ? null : left / this.screenWidth * 100 + '%';
      top = clientY - this.dy;
      top = top < (10 + this.topBorder) ? this.topBorder + 'px' : this.height - top < (10 + this.bottomBorder) ? null : top / this.screenHeight * 100 + '%';
      right = left === null ? 0 : null;
      bottom = top === null ? this.bottomBorder + 'px' : null;
      style = this.style;
      style.left = left;
      style.right = right;
      style.top = top;
      return style.bottom = bottom;
    };
    touchend = function(e) {
      var k, len1, ref, touch;
      ref = e.changedTouches;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        touch = ref[k];
        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, ref, root;
      root = arg.root, el = arg.el, latestEvent = arg.latestEvent, endEvents = arg.endEvents, height = arg.height, cb = arg.cb, noRemove = arg.noRemove;
      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,
        noRemove: noRemove
      };
      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, ref, right, style, threshold, top;
      this.latestEvent = e;
      height = (this.height || this.el.offsetHeight) + hoverstart.padding;
      clientX = e.clientX, clientY = e.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);
      }
      ref = clientX <= threshold ? [clientX + 45 + 'px', null] : [null, this.clientWidth - clientX + 45 + 'px'], left = ref[0], right = ref[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;
    };
    return {
      dialog: dialog,
      Menu: Menu,
      hover: hoverstart,
      checkbox: checkbox
    };
  })();

  CrossOrigin = (function() {
    return {
      binary: function(url, cb, headers) {
        var options, ref, workaround;
        if (headers == null) {
          headers = {};
        }
        url = url.replace(/^((?:https?:)?\/\/(?:\w+\.)?4c(?:ha|d)n\.org)\/adv\//, '$1//adv/');
        workaround = $.engine === 'gecko' && (typeof GM_info !== "undefined" && GM_info !== null) && /^[0-2]\.|^3\.[01](?!\d)/.test(GM_info.version);
        workaround || (workaround = /PaleMoon\//.test(navigator.userAgent));
        workaround || (workaround = (typeof GM_info !== "undefined" && GM_info !== null ? (ref = GM_info.script) != null ? ref.includeJSB : void 0 : void 0) != null);
        options = {
          method: "GET",
          url: url,
          headers: headers,
          onload: function(xhr) {
            var contentDisposition, contentType, data, i, r, ref1, ref2;
            if (workaround) {
              r = xhr.responseText;
              data = new Uint8Array(r.length);
              i = 0;
              while (i < r.length) {
                data[i] = r.charCodeAt(i);
                i++;
              }
            } else {
              data = new Uint8Array(xhr.response);
            }
            if (typeof xhr.responseHeaders === 'object') {
              contentType = xhr.responseHeaders['Content-Type'];
              contentDisposition = xhr.responseHeaders['Content-Disposition'];
            } else {
              contentType = (ref1 = xhr.responseHeaders.match(/Content-Type:\s*(.*)/i)) != null ? ref1[1] : void 0;
              contentDisposition = (ref2 = xhr.responseHeaders.match(/Content-Disposition:\s*(.*)/i)) != null ? ref2[1] : void 0;
            }
            return cb(data, contentType, contentDisposition);
          },
          onerror: function() {
            return cb(null);
          },
          onabort: function() {
            return cb(null);
          }
        };
        if (workaround) {
          options.overrideMimeType = options.mimeType = 'text/plain; charset=x-user-defined';
        } else {
          options.responseType = 'arraybuffer';
        }
        return GM_xmlhttpRequest(options);
      },
      file: function(url, cb) {
        return CrossOrigin.binary(url, function(data, contentType, contentDisposition) {
          var blob, match, mime, name, ref, ref1, ref2, ref3;
          if (data == null) {
            return cb(null);
          }
          name = (ref = url.match(/([^\/]+)\/*$/)) != null ? ref[1] : void 0;
          mime = (contentType != null ? contentType.match(/[^;]*/)[0] : void 0) || 'application/octet-stream';
          match = (contentDisposition != null ? (ref1 = contentDisposition.match(/\bfilename\s*=\s*"((\\"|[^"])+)"/i)) != null ? ref1[1] : void 0 : void 0) || (contentType != null ? (ref2 = contentType.match(/\bname\s*=\s*"((\\"|[^"])+)"/i)) != null ? ref2[1] : void 0 : void 0);
          if (match) {
            name = match.replace(/\\"/g, '"');
          }
          if ((typeof GM_info !== "undefined" && GM_info !== null ? (ref3 = GM_info.script) != null ? ref3.includeJSB : void 0 : void 0) != null) {
            mime = QR.typeFromExtension[name.match(/[^.]*$/)[0].toLowerCase()] || 'application/octet-stream';
          }
          blob = new Blob([data], {
            type: mime
          });
          blob.name = name;
          return cb(blob);
        });
      },
      json: (function() {
        var callbacks, responses;
        callbacks = {};
        responses = {};
        return function(url, cb) {
          if (responses[url]) {
            cb(responses[url]);
            return;
          }
          if (callbacks[url]) {
            callbacks[url].push(cb);
            return;
          }
          callbacks[url] = [cb];
          return GM_xmlhttpRequest({
            method: "GET",
            url: url + '',
            onload: function(xhr) {
              var k, len1, ref, response;
              response = JSON.parse(xhr.responseText);
              ref = callbacks[url];
              for (k = 0, len1 = ref.length; k < len1; k++) {
                cb = ref[k];
                cb(response);
              }
              delete callbacks[url];
              return responses[url] = response;
            },
            onerror: function() {
              return delete callbacks[url];
            },
            onabort: function() {
              return delete callbacks[url];
            }
          });
        };
      })()
    };
  })();

  Anonymize = {
    init: function() {
      var ref;
      if (!(((ref = g.VIEW) === 'index' || ref === 'thread' || ref === 'archive') && Conf['Anonymize'])) {
        return;
      }
      if (g.VIEW === 'archive') {
        return this.archive();
      }
      return Post.callbacks.push({
        name: 'Anonymize',
        cb: this.node
      });
    },
    node: function() {
      var email, name, ref, tripcode;
      if (this.info.capcode || this.isClone) {
        return;
      }
      ref = this.nodes, name = ref.name, tripcode = ref.tripcode, email = ref.email;
      if (this.info.name !== 'Anonymous') {
        name.textContent = 'Anonymous';
      }
      if (tripcode) {
        $.rm(tripcode);
        delete this.nodes.tripcode;
      }
      if (this.info.email) {
        $.replace(email, name);
        return delete this.nodes.email;
      }
    },
    archive: function() {
      return $.ready(function() {
        var k, len1, len2, name, q, ref, ref1, trip;
        ref = $$('.name');
        for (k = 0, len1 = ref.length; k < len1; k++) {
          name = ref[k];
          name.textContent = 'Anonymous';
        }
        ref1 = $$('.postertrip');
        for (q = 0, len2 = ref1.length; q < len2; q++) {
          trip = ref1[q];
          $.rm(trip);
        }
      });
    }
  };

  Filter = {
    filters: {},
    init: function() {
      var boards, err, excludes, filter, hl, k, key, len1, line, op, ref, ref1, ref2, ref3, ref4, ref5, ref6, regexp, stub, top;
      if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Filter'])) {
        return;
      }
      if (!Conf['Filtered Backlinks']) {
        $.addClass(doc, 'hide-backlinks');
      }
      for (key in Config.filter) {
        this.filters[key] = [];
        ref1 = Conf[key].split('\n');
        for (k = 0, len1 = ref1.length; k < len1; k++) {
          line = ref1[k];
          if (line[0] === '#') {
            continue;
          }
          if (!(regexp = line.match(/\/(.+)\/(\w*)/))) {
            continue;
          }
          filter = line.replace(regexp[0], '');
          boards = ((ref2 = filter.match(/boards:([^;]+)/)) != null ? ref2[1].toLowerCase() : void 0) || 'global';
          boards = boards === 'global' ? null : boards.split(',');
          if (boards === null) {
            excludes = ((ref3 = filter.match(/exclude:([^;]+)/)) != null ? ref3[1].toLowerCase().split(',') : void 0) || null;
          }
          if (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(/[^t]op:(yes|no|only)/)) != null ? ref4[1] : void 0) || 'yes';
          stub = (function() {
            var ref5;
            switch ((ref5 = filter.match(/stub:(yes|no)/)) != null ? ref5[1] : void 0) {
              case 'yes':
                return true;
              case 'no':
                return false;
              default:
                return Conf['Stubs'];
            }
          })();
          if (hl = /highlight/.test(filter)) {
            hl = ((ref5 = filter.match(/highlight:([\w-]+)/)) != null ? ref5[1] : void 0) || 'filter-highlight';
            top = ((ref6 = filter.match(/top:(yes|no)/)) != null ? ref6[1] : void 0) || 'yes';
            top = top === 'yes';
          }
          this.filters[key].push(this.createFilter(regexp, boards, excludes, op, stub, hl, top));
        }
        if (!this.filters[key].length) {
          delete this.filters[key];
        }
      }
      if (!Object.keys(this.filters).length) {
        return;
      }
      return Post.callbacks.push({
        name: 'Filter',
        cb: this.node
      });
    },
    createFilter: function(regexp, boards, excludes, op, stub, hl, top) {
      var settings, test;
      test = typeof regexp === 'string' ? function(value) {
        return regexp === value;
      } : function(value) {
        return regexp.test(value);
      };
      settings = {
        hide: !hl,
        stub: stub,
        "class": hl,
        top: top
      };
      return function(value, boardID, isReply) {
        if (boards && indexOf.call(boards, boardID) < 0) {
          return false;
        }
        if (excludes && indexOf.call(excludes, boardID) >= 0) {
          return false;
        }
        if (isReply && op === 'only' || !isReply && op === 'no') {
          return false;
        }
        if (!test(value)) {
          return false;
        }
        return settings;
      };
    },
    node: function() {
      var filter, k, key, len1, ref, ref1, result, value;
      if (this.isClone) {
        return;
      }
      for (key in Filter.filters) {
        if ((value = Filter[key](this)) != null) {
          ref = Filter.filters[key];
          for (k = 0, len1 = ref.length; k < len1; k++) {
            filter = ref[k];
            if (!(result = filter(value, this.board.ID, this.isReply))) {
              continue;
            }
            if (result.hide && !this.isFetchedQuote) {
              if (this.isReply) {
                PostHiding.hide(this, result.stub);
              } else if (g.VIEW === 'index') {
                ThreadHiding.hide(this.thread, result.stub);
              } else {
                continue;
              }
              return;
            }
            $.addClass(this.nodes.root, result["class"]);
            if (!(this.highlights && (ref1 = result["class"], indexOf.call(this.highlights, ref1) >= 0))) {
              (this.highlights || (this.highlights = [])).push(result["class"]);
            }
            if (!this.isReply && result.top) {
              this.thread.isOnTop = true;
            }
          }
        }
      }
    },
    isHidden: function(post) {
      var filter, k, key, len1, ref, result, value;
      for (key in Filter.filters) {
        if ((value = Filter[key](post)) != null) {
          ref = Filter.filters[key];
          for (k = 0, len1 = ref.length; k < len1; k++) {
            filter = ref[k];
            if (result = filter(value, post.boardID, post.isReply)) {
              if (result.hide) {
                return true;
              }
            }
          }
        }
      }
      return false;
    },
    postID: function(post) {
      var ref;
      return "" + ((ref = post.ID) != null ? ref : post.postID);
    },
    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;
    },
    subject: function(post) {
      return post.info.subject;
    },
    comment: function(post) {
      var base1;
      return (base1 = post.info).comment != null ? base1.comment : base1.comment = Build.parseComment(post.info.commentHTML.innerHTML);
    },
    flag: function(post) {
      return post.info.flag;
    },
    filename: function(post) {
      var ref;
      return (ref = post.file) != null ? ref.name : void 0;
    },
    dimensions: function(post) {
      var ref;
      return (ref = post.file) != null ? ref.dimensions : void 0;
    },
    filesize: function(post) {
      var ref;
      return (ref = post.file) != null ? ref.size : void 0;
    },
    MD5: function(post) {
      var ref;
      return (ref = post.file) != null ? ref.MD5 : void 0;
    },
    menu: {
      init: function() {
        var div, entry, k, len1, 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'], ['Subject', 'subject'], ['Comment', 'comment'], ['Flag', 'flag'], ['Filename', 'filename'], ['Image dimensions', 'dimensions'], ['Filesize', 'filesize'], ['Image MD5', 'MD5']];
        for (k = 0, len1 = ref1.length; k < len1; k++) {
          type = ref1[k];
          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) {
            var value;
            value = Filter[type](post);
            return value != null;
          }
        };
      },
      makeFilter: function() {
        var re, type, value;
        type = this.dataset.type;
        value = Filter[type](Filter.menu.post);
        re = type === 'uniqueID' || type === 'MD5' ? value : value.replace(/\/|\\|\^|\$|\n|\.|\(|\)|\{|\}|\[|\]|\?|\*|\+|\|/g, function(c) {
          if (c === '\n') {
            return '\\n';
          } else if (c === '\\') {
            return '\\\\';
          } else {
            return "\\" + c;
          }
        });
        re = type === 'uniqueID' || type === 'MD5' ? "/" + re + "/" : "/^" + re + "$/";
        return $.get(type, Conf[type], function(item) {
          var save, section, select, ta, tl;
          save = item[type];
          save = save ? save + "\n" + re : re;
          $.set(type, save);
          Settings.open('Filter');
          section = $('.section-container');
          select = $('select[name=filter]', section);
          select.value = type;
          Settings.selectFilter.call(select);
          ta = $('textarea', section);
          tl = ta.textLength;
          ta.setSelectionRange(tl, tl);
          return ta.focus();
        });
      }
    }
  };

  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 Post.callbacks.push({
        name: 'Reply Hiding',
        cb: this.node
      });
    },
    node: function() {
      var data, 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;
      }
      sideArrows = $('.sideArrows', this.nodes.root);
      $.replace(sideArrows.firstChild, PostHiding.makeButton(this, 'hide'));
      return sideArrows.removeAttribute('class');
    },
    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, k, len1, 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 (k = 0, len1 = ref.length; k < len1; k++) {
        quotelink = ref[k];
        $.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 k, len1, 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 (k = 0, len1 = ref.length; k < len1; k++) {
        quotelink = ref[k];
        $.rmClass(quotelink, 'filtered');
      }
    }
  };

  Recursive = {
    recursives: {},
    init: function() {
      var ref;
      if ((ref = g.VIEW) !== 'index' && ref !== 'thread') {
        return;
      }
      return Post.callbacks.push({
        name: 'Recursive',
        cb: this.node
      });
    },
    node: function() {
      var i, k, len1, len2, obj, q, quote, recursive, ref, ref1;
      if (this.isClone || this.isFetchedQuote) {
        return;
      }
      ref = this.quotes;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        quote = ref[k];
        if (obj = Recursive.recursives[quote]) {
          ref1 = obj.recursives;
          for (i = q = 0, len2 = ref1.length; q < len2; i = ++q) {
            recursive = ref1[i];
            recursive.apply(null, [this].concat(slice.call(obj.args[i])));
          }
        }
      }
    },
    add: function() {
      var args, base1, name1, obj, post, recursive;
      recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
      obj = (base1 = Recursive.recursives)[name1 = post.fullID] || (base1[name1] = {
        recursives: [],
        args: []
      });
      obj.recursives.push(recursive);
      return obj.args.push(args);
    },
    rm: function(recursive, post) {
      var i, k, len1, obj, rec, ref;
      if (!(obj = Recursive.recursives[post.fullID])) {
        return;
      }
      ref = obj.recursives;
      for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
        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)));
        }
      });
    }
  };

  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);
      return Post.callbacks.push({
        name: 'Thread Hiding',
        cb: this.node
      });
    },
    catalogSet: function(board) {
      var hiddenThreads, threadID;
      if (!$.hasStorage) {
        return;
      }
      hiddenThreads = ThreadHiding.db.get({
        boardID: board.ID,
        defaultValue: {}
      });
      for (threadID in hiddenThreads) {
        hiddenThreads[threadID] = true;
      }
      return localStorage.setItem("4chan-hide-t-" + board, JSON.stringify(hiddenThreads));
    },
    catalogWatch: function() {
      if (!$.hasStorage) {
        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 (!(threadID in ThreadHiding.hiddenThreads)) {
          ThreadHiding.db.set({
            boardID: g.BOARD.ID,
            threadID: threadID,
            val: {
              makeStub: Conf['Stubs']
            }
          });
        }
      }
      for (threadID in ThreadHiding.hiddenThreads) {
        if (!(threadID in hiddenThreads2)) {
          ThreadHiding.db["delete"]({
            boardID: g.BOARD.ID,
            threadID: threadID
          });
        }
      }
      return ThreadHiding.hiddenThreads = hiddenThreads2;
    },
    node: function() {
      var data;
      if (this.isReply || this.isClone || this.isFetchedQuote) {
        return;
      }
      if (data = ThreadHiding.db.get({
        boardID: this.board.ID,
        threadID: this.ID
      })) {
        ThreadHiding.hide(this.thread, data.makeStub);
      }
      if (!Conf['Thread Hiding Buttons']) {
        return;
      }
      return $.prepend(this.nodes.root, ThreadHiding.makeButton(this.thread, 'hide'));
    },
    onIndexBuild: function(nodes) {
      var k, len1, root, thread;
      for (k = 0, len1 = nodes.length; k < len1; k++) {
        root = nodes[k];
        thread = Get.threadFromRoot(root);
        if (thread.isHidden && thread.stub && !root.contains(thread.stub)) {
          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: "<span class=\"fa fa-" + (type === "hide" ? "minus" : "plus") + "-square\"></span>"
      });
      a.dataset.fullID = thread.fullID;
      $.on(a, 'click', ThreadHiding.toggle);
      return a;
    },
    makeStub: function(thread, root) {
      var a, numReplies, summary;
      numReplies = $$('.thread > .replyContainer', root).length;
      if (summary = $('.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);
      }
      return $.prepend(root, thread.stub);
    },
    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[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.OP.nodes.root.parentNode;
      thread.isHidden = true;
      if (Conf['JSON Index']) {
        Index.updateHideLabel();
      }
      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.OP.nodes.root.parentNode;
      threadRoot.hidden = thread.isHidden = false;
      if (Conf['JSON Index']) {
        return Index.updateHideLabel();
      }
    }
  };

  QuoteBacklink = {
    containers: {},
    init: function() {
      var ref;
      if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Quote Backlinks']) {
        return;
      }
      Post.callbacks.push({
        name: 'Quote Backlinking Part 1',
        cb: this.firstNode
      });
      return Post.callbacks.push({
        name: 'Quote Backlinking Part 2',
        cb: this.secondNode
      });
    },
    firstNode: function() {
      var a, clone, container, containers, hash, k, len1, len2, len3, link, markYours, nodes, post, q, quote, ref, ref1, ref2, u;
      if (this.isClone || !this.quotes.length || this.isRebuilt) {
        return;
      }
      markYours = Conf['Mark Quotes of You'] && ((ref = QuoteYou.db) != null ? ref.get({
        boardID: this.board.ID,
        threadID: this.thread.ID,
        postID: this.ID
      }) : void 0);
      a = $.el('a', {
        href: 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)) + (markYours ? '\u00A0(You)' : '')
      });
      ref1 = this.quotes;
      for (k = 0, len1 = ref1.length; k < len1; k++) {
        quote = ref1[k];
        containers = [QuoteBacklink.getContainer(quote)];
        if ((post = g.posts[quote]) && post.nodes.backlinkContainer) {
          ref2 = post.clones;
          for (q = 0, len2 = ref2.length; q < len2; q++) {
            clone = ref2[q];
            containers.push(clone.nodes.backlinkContainer);
          }
        }
        for (u = 0, len3 = containers.length; u < len3; u++) {
          container = containers[u];
          link = a.cloneNode(true);
          nodes = container.firstChild ? [$.tn(' '), link] : [link];
          if (Conf['Quote Previewing']) {
            $.on(link, 'mouseover', QuotePreview.mouseover);
          }
          if (Conf['Quote Inlining'] && !(Conf['Inline Cross-thread Quotes Only'] && !QuoteInline.isCrossThread(link))) {
            $.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.info);
        return;
      }
      if (!(this.isReply || Conf['OP Backlinks'])) {
        return;
      }
      container = QuoteBacklink.getContainer(this.fullID);
      this.nodes.backlinkContainer = container;
      return $.add(this.nodes.info, container);
    },
    getContainer: function(id) {
      var base1;
      return (base1 = this.containers)[id] || (base1[id] = $.el('span', {
        className: 'container'
      }));
    }
  };

  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.text = '\u00A0(Cross-thread)';
      return Post.callbacks.push({
        name: 'Mark Cross-thread Quotes',
        cb: this.node
      });
    },
    node: function() {
      var board, boardID, k, len1, 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 (k = 0, len1 = ref1.length; k < len1; k++) {
        quotelink = ref1[k];
        ref2 = Get.postDataFromLink(quotelink), boardID = ref2.boardID, threadID = ref2.threadID;
        if (!threadID) {
          continue;
        }
        if (this.isClone) {
          quotelink.textContent = quotelink.textContent.replace(QuoteCT.text, '');
        }
        if (boardID === board.ID && threadID !== thread.ID) {
          $.add(quotelink, $.tn(QuoteCT.text));
        }
      }
    }
  };

  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 Post.callbacks.push({
        name: 'Quote Inlining',
        cb: this.node
      });
    },
    node: function() {
      var isClone, k, len1, len2, link, process, q, ref, ref1;
      process = QuoteInline.process;
      isClone = this.isClone;
      ref = this.nodes.quotelinks;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        link = ref[k];
        process(link, isClone);
      }
      ref1 = this.nodes.backlinks;
      for (q = 0, len2 = ref1.length; q < len2; q++) {
        link = ref1[q];
        process(link, isClone);
      }
    },
    process: function(link, clone) {
      if (Conf['Inline Cross-thread Quotes Only'] && !QuoteInline.isCrossThread(link)) {
        return;
      }
      if (Conf['Quote Hash Navigation']) {
        if (!clone) {
          $.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
        }
      }
      return $.on(link, 'click', QuoteInline.toggle);
    },
    isCrossThread: function(link) {
      return link.pathname !== location.pathname || link.host !== location.host || link.protocol !== location.protocol;
    },
    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, threadID;
      if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
        return;
      }
      e.preventDefault();
      ref = Get.postDataFromLink(this), boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID;
      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 quotelink.parentNode.parentNode;
      } 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[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, 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);
      $.rm(root);
      if (!$('.inline', qroot)) {
        $.rmClass(qroot, 'hasInline');
      }
      if (!(el = root.firstElementChild)) {
        return;
      }
      post = g.posts[boardID + "." + postID];
      post.rmClone(el.dataset.clone);
      if (Conf['Forward Hiding'] && isBacklink && context.thread === g.threads[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');
      }
    }
  };

  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.text = '\u00A0(OP)';
      return Post.callbacks.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++]) {
          quotelink.textContent = quotelink.textContent.replace(QuoteOP.text, '');
        }
      }
      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, $.tn(QuoteOP.text));
        }
      }
    }
  };

  QuotePreview = {
    init: function() {
      var ref;
      if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Quote Previewing'])) {
        return;
      }
      if (Conf['Comment Expansion']) {
        ExpandComment.callbacks.push(this.node);
      }
      return Post.callbacks.push({
        name: 'Quote Previewing',
        cb: this.node
      });
    },
    node: function() {
      var k, len1, link, ref;
      ref = this.nodes.quotelinks.concat(slice.call(this.nodes.backlinks));
      for (k = 0, len1 = ref.length; k < len1; k++) {
        link = ref[k];
        $.on(link, 'mouseover', QuotePreview.mouseover);
      }
    },
    mouseover: function(e) {
      var boardID, k, len1, origin, post, postID, posts, qp, ref, threadID;
      if ($.hasClass(this, 'inlined') || !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[boardID + "." + postID])) {
        posts = [origin].concat(origin.clones);
        posts.pop();
        for (k = 0, len1 = posts.length; k < len1; k++) {
          post = posts[k];
          $.addClass(post.nodes.post, 'qphl');
        }
      }
    },
    mouseout: function() {
      var clone, k, len1, post, ref, root;
      if (!(root = this.el.firstElementChild)) {
        return;
      }
      clone = Get.postFromRoot(root);
      post = clone.origin;
      post.rmClone(root.dataset.clone);
      if (!Conf['Quote Highlighting']) {
        return;
      }
      ref = [post].concat(post.clones);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        post = ref[k];
        $.rmClass(post.nodes.post, 'qphl');
      }
    }
  };

  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 Post.callbacks.push({
        name: 'Strike-through Quotes',
        cb: this.node
      });
    },
    node: function() {
      var boardID, k, len1, postID, quotelink, ref, ref1, ref2;
      if (this.isClone) {
        return;
      }
      ref = this.nodes.quotelinks;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        quotelink = ref[k];
        ref1 = Get.postDataFromLink(quotelink), boardID = ref1.boardID, postID = ref1.postID;
        if ((ref2 = g.posts[boardID + "." + postID]) != null ? ref2.isHidden : void 0) {
          $.addClass(quotelink, 'filtered');
        }
      }
    }
  };


  /*
    <3 aeosynth
   */

  QuoteThreading = {
    init: function() {
      if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
        return;
      }
      this.enabled = true;
      this.controls = $.el('span', {
        innerHTML: "<label><input id=\"threadingControl\" type=\"checkbox\" checked> Threading</label>"
      });
      this.threadNewLink = $.el('span', {
        className: 'brackets-wrap threadnewlink',
        hidden: true
      });
      $.extend(this.threadNewLink, {
        innerHTML: "<a href=\"javascript:;\">Thread New Posts</a>"
      });
      this.input = $('input', this.controls);
      $.on(this.input, 'change', this.rethread);
      $.on(this.threadNewLink.firstElementChild, 'click', this.rethread);
      Header.menu.addEntry(this.entry = {
        el: this.controls,
        order: 99
      });
      Thread.callbacks.push({
        name: 'Quote Threading',
        cb: this.setThread
      });
      return Post.callbacks.push({
        name: 'Quote Threading',
        cb: this.node
      });
    },
    parent: {},
    children: {},
    inserted: {},
    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, k, lastParent, len1, parent, parents, quote, ref;
      if (this.isFetchedQuote || this.isClone || !this.isReply) {
        return;
      }
      parents = new Set();
      lastParent = null;
      ref = this.quotes;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        quote = ref[k];
        if (parent = g.posts[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, k, len1, posts;
      posts = [post];
      if (children = QuoteThreading.children[post.fullID]) {
        for (k = 0, len1 = children.length; k < len1; k++) {
          child = children[k];
          posts = posts.concat(QuoteThreading.descendants(child));
        }
      }
      return posts;
    },
    insert: function(post) {
      var base1, child, children, descendants, i, k, len1, name1, next, nodes, order, parent, prev, prev2, q, threadContainer, u, x;
      if (!(QuoteThreading.enabled && (parent = QuoteThreading.parent[post.fullID]) && !QuoteThreading.inserted[post.fullID])) {
        return false;
      }
      descendants = QuoteThreading.descendants(post);
      if (!Unread.posts.has(parent.ID)) {
        if ((function() {
          var k, len1, x;
          for (k = 0, len1 = descendants.length; k < len1; k++) {
            x = descendants[k];
            if (Unread.posts.has(x.ID)) {
              return true;
            }
          }
        })()) {
          QuoteThreading.threadNewLink.hidden = false;
          return false;
        }
      }
      order = Unread.order;
      children = ((base1 = QuoteThreading.children)[name1 = parent.fullID] || (base1[name1] = []));
      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 (k = children.length - 1; k >= 0; k += -1) {
        child = children[k];
        if (child.ID >= post.ID) {
          i--;
        }
      }
      if (i !== children.length) {
        next = children[i];
        for (q = 0, len1 = descendants.length; q < len1; q++) {
          x = descendants[q];
          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 (u = descendants.length - 1; u >= 0; u += -1) {
          x = descendants[u];
          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;
      thread = QuoteThreading.thread;
      posts = thread.posts;
      QuoteThreading.threadNewLink.hidden = true;
      if (QuoteThreading.enabled = QuoteThreading.input.checked) {
        posts.forEach(QuoteThreading.insert);
      } else {
        nodes = [];
        Unread.order = new RandomAccessList();
        QuoteThreading.inserted = {};
        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.OP.nodes.root.parentNode, nodes);
      }
      Unread.position = Unread.order.first;
      Unread.updatePosition();
      Unread.setLine(true);
      Unread.read();
      return Unread.update();
    }
  };

  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 boardID, postID, ref, threadID;
        $.forceSync('Remember Your Posts');
        if (Conf['Remember Your Posts']) {
          ref = e.detail, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID;
          return QuoteYou.db.set({
            boardID: boardID,
            threadID: threadID,
            postID: postID,
            val: true
          });
        }
      });
      if ((ref = g.VIEW) !== 'index' && ref !== 'thread') {
        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.text = '\u00A0(You)';
      return Post.callbacks.push({
        name: 'Mark Quotes of You',
        cb: this.node
      });
    },
    node: function() {
      var k, len1, quotelink, ref;
      if (this.isClone) {
        return;
      }
      if (QuoteYou.db.get({
        boardID: this.board.ID,
        threadID: this.thread.ID,
        postID: this.ID
      })) {
        $.addClass(this.nodes.root, 'yourPost');
      }
      if (!this.quotes.length) {
        return;
      }
      ref = this.nodes.quotelinks;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        quotelink = ref[k];
        if (!(QuoteYou.db.get(Get.postDataFromLink(quotelink)))) {
          continue;
        }
        if (Conf['Mark Quotes of You']) {
          $.add(quotelink, $.tn(QuoteYou.text));
        }
        $.addClass(quotelink, 'you');
        $.addClass(this.nodes.root, 'quotesYou');
      }
    },
    cb: {
      seek: function(type) {
        var highlight, post, posts, result, str;
        if (highlight = $('.highlight')) {
          $.rmClass(highlight, '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 post;
        post = $('.post', root);
        if (!post.getBoundingClientRect().height) {
          return false;
        } else {
          QuoteYou.lastRead = root;
          window.location = "#" + post.id;
          Header.scrollTo(post);
          $.addClass(post, 'highlight');
          return true;
        }
      }
    }
  };

  Quotify = {
    init: function() {
      var ref;
      if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Resurrect Quotes']) {
        return;
      }
      if (Conf['Comment Expansion']) {
        ExpandComment.callbacks.push(this.node);
      }
      return Post.callbacks.push({
        name: 'Resurrect Quotes',
        cb: this.node
      });
    },
    node: function() {
      var deadlink, k, len1, ref;
      if (this.isClone) {
        return;
      }
      ref = $$('.deadlink', this.nodes.comment);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        deadlink = ref[k];
        Quotify.parseDeadlink.call(this, deadlink);
      }
    },
    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[quoteID]) {
        if (!post.isDead) {
          a = $.el('a', {
            href: Build.postURL(boardID, post.thread.ID, postID),
            className: 'quotelink',
            textContent: quote
          });
        } else {
          a = $.el('a', {
            href: Build.postURL(boardID, post.thread.ID, postID),
            className: 'quotelink deadlink',
            textContent: quote + "\u00A0(Dead)"
          });
          $.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 + "\u00A0(Dead)"
          });
          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) {
        deadlink.textContent = quote + "\u00A0(Dead)";
        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));
    }
  };

  Upvotes = {
    count: {},
    text: '\u305D\u3046\u3060\u306D',
    regexp: /(?:^>.*\n)+(?:i|top|holy|shit|ay*|oh?|omg|god|jesus|christ|fuck|fukken|fucking?|\s|[.,-])*(?:\u305D\u3046\u3060\u306D|this(?! )|\+1|upvote(?! )d?|under[ -]?rated|\/thread|10\/10|(?:lol|kek|lel|lmao)(?:'?d|[.!]?$)|(?:ha)+[.!]?$|saved|nice(?! )|my sides)(?=\b|\W|$)/gmi,
    init: function() {
      var ref;
      if (!(((ref = g.VIEW) === 'thread' || ref === 'index') && Conf['Upvotes'])) {
        return;
      }
      return Post.callbacks.push({
        name: 'Upvotes',
        cb: this.node
      });
    },
    node: function() {
      var a, context, k, len1, len2, q, quote, quotes, ref, ref1, ref2, results;
      if (this.isFetchedQuote || ((ref = this.origin) != null ? ref.isFetchedQuote : void 0)) {
        return;
      }
      if (this.isClone) {
        this.nodes.vote = $('.upvote', this.nodes.info);
        $.on(this.nodes.vote, 'click', Upvotes.vote);
        return;
      }
      a = $.el('a', {
        className: 'upvote',
        href: 'javascript:;',
        textContent: '+'
      });
      $.add(this.nodes.info, a);
      this.nodes.vote = a;
      $.on(a, 'click', Upvotes.vote);
      if (g.VIEW !== 'thread') {
        return;
      }
      Upvotes.count[this.fullID] = 0;
      quotes = {};
      ref1 = this.info.comment.match(Upvotes.regexp) || [];
      for (k = 0, len1 = ref1.length; k < len1; k++) {
        context = ref1[k];
        ref2 = context.match(/>>\d+/g) || [];
        for (q = 0, len2 = ref2.length; q < len2; q++) {
          quote = ref2[q];
          quotes[quote.slice(2)] = true;
        }
      }
      results = [];
      for (quote in quotes) {
        results.push(Upvotes.increment(g.BOARD + "." + quote));
      }
      return results;
    },
    increment: function(fullID) {
      var count, k, len1, post, ref;
      if (!(fullID in Upvotes.count)) {
        return;
      }
      count = ++Upvotes.count[fullID];
      post = g.posts[fullID];
      ref = [post].concat(slice.call(post.clones));
      for (k = 0, len1 = ref.length; k < len1; k++) {
        post = ref[k];
        post.nodes.vote.textContent = Upvotes.text + "x" + count;
      }
    },
    vote: function() {
      var com, pos, text;
      if (!QR.postingIsEnabled) {
        return;
      }
      if (QR.nodes) {
        $.off(QR.nodes.com, 'input', Upvotes.setText);
      }
      QR.quote.call(this);
      com = QR.nodes.com;
      text = Conf['upvoteText'] + "\n";
      pos = com.selectionStart;
      Upvotes.context = com.value.slice(0, pos);
      com.value = com.value.slice(0, pos) + text + com.value.slice(pos);
      pos += text.length;
      com.setSelectionRange(pos, pos);
      $.event('input', null, com);
      Upvotes.post = $.id('selected');
      return $.on(com, 'input', Upvotes.setText);
    },
    setText: function() {
      var context;
      context = Upvotes.context;
      if ($.id('selected') === Upvotes.post && this.value.slice(0, context.length) === context) {
        Conf['upvoteText'] = this.value.slice(context.length).split('\n')[0];
        return $.set('upvoteText', Conf['upvoteText']);
      } else {
        return $.off(this, 'input', Upvotes.setText);
      }
    }
  };

  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, version;
      if (!Conf['Quick Reply']) {
        return;
      }
      this.posts = [];
      if (g.VIEW === 'archive') {
        return;
      }
      version = Conf['Use Recaptcha v1'] && Main.jsEnabled ? 'v1' : 'v2';
      this.captcha = Captcha[version];
      $.on(d, '4chanXInitFinished', this.initReady);
      Post.callbacks.push({
        name: 'Quick Reply',
        cb: this.node
      });
      if (Conf['QR Shortcut']) {
        this.shortcut = sc = $.el('a', {
          className: 'qr-shortcut 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(sc);
      }
    },
    initReady: function() {
      var link, linkBot, navLinksBot, origToggle;
      $.off(d, '4chanXInitFinished', this.initReady);
      QR.postingIsEnabled = !!$.id('postForm');
      if (!QR.postingIsEnabled) {
        return;
      }
      link = $.el('h1', {
        className: "qr-link-container"
      });
      $.extend(link, {
        innerHTML: "<a href=\"javascript:;\" class=\"qr-link\">" + (g.VIEW === "thread" ? "Reply to Thread" : "Start a Thread") + "</a>"
      });
      QR.link = link.firstElementChild;
      $.on(link.firstChild, 'click', function() {
        QR.open();
        return QR.nodes.com.focus();
      });
      if (Conf['Bottom QR Link'] && g.VIEW === 'thread') {
        linkBot = $.el('div', {
          className: "brackets-wrap qr-link-container-bottom"
        });
        $.extend(linkBot, {
          innerHTML: "<a href=\"javascript:;\" class=\"qr-link-bottom\">Reply to Thread</a>"
        });
        $.on(linkBot.firstElementChild, 'click', function() {
          QR.open();
          return QR.nodes.com.focus();
        });
        if ((navLinksBot = $('.navLinksBot'))) {
          $.prepend(navLinksBot, linkBot);
        }
      }
      origToggle = $.id('togglePostFormLink');
      $.before(origToggle, link);
      origToggle.firstElementChild.textContent = 'Original Form';
      $.on(d, 'QRGetFile', QR.getFile);
      $.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, 'IndexRefresh', 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[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;
        }
      }
      if (Conf['QR Shortcut']) {
        return $.rmClass(QR.shortcut, 'disabled');
      }
    },
    close: function() {
      var k, len1, post, ref;
      if (QR.req) {
        QR.abort();
        return;
      }
      QR.nodes.el.hidden = true;
      QR.cleanNotifications();
      d.activeElement.blur();
      $.rmClass(QR.nodes.el, 'dump');
      if (Conf['QR Shortcut']) {
        $.addClass(QR.shortcut, 'disabled');
      }
      new QR.post(true);
      ref = QR.posts.splice(0, QR.posts.length - 1);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        post = ref[k];
        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() {
      d.activeElement.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();
      }
    },
    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');
    },
    setCustomCooldown: function(enabled) {
      Conf['customCooldownEnabled'] = enabled;
      QR.cooldown.customCooldown = enabled;
      return QR.nodes.customCooldown.classList.toggle('disabled', !enabled);
    },
    toggleCustomCooldown: function() {
      var enabled;
      enabled = $.hasClass(this, '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())) {
        try {
          notif = new Notification(el.textContent, {
            body: el.textContent,
            icon: Favicon.logo
          });
          notif.onclick = function() {
            return $.global(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);
            };
          }
        } catch (_error) {}
      }
    },
    notifications: [],
    cleanNotifications: function() {
      var k, len1, notification, ref;
      ref = QR.notifications;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        notification = ref[k];
        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[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 aa, ancestor, caretPos, com, frag, insideCode, k, len1, len2, len3, len4, len5, len6, node, post, q, range, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, sel, text, thread, u, v, z;
      if (e != null) {
        e.preventDefault();
      }
      if (!QR.postingIsEnabled) {
        return;
      }
      sel = d.getSelection();
      post = Get.postFromNode(this);
      text = post.board.ID === g.BOARD.ID ? ">>" + post + "\n" : ">>>/" + post.board + "/" + post + "\n";
      if (sel.toString().trim() && post === Get.postFromNode(sel.anchorNode)) {
        range = sel.getRangeAt(0);
        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]'));
        }
        ref = $$((insideCode ? 'br' : '.prettyprint br'), frag);
        for (k = 0, len1 = ref.length; k < len1; k++) {
          node = ref[k];
          $.replace(node, $.tn('\n'));
        }
        ref1 = $$('br', frag);
        for (q = 0, len2 = ref1.length; q < len2; q++) {
          node = ref1[q];
          if (node !== frag.lastChild) {
            $.replace(node, $.tn('\n>'));
          }
        }
        ref2 = $$('s, .removed-spoiler', frag);
        for (u = 0, len3 = ref2.length; u < len3; u++) {
          node = ref2[u];
          $.replace(node, [$.tn('[spoiler]')].concat(slice.call(node.childNodes), [$.tn('[/spoiler]')]));
        }
        ref3 = $$('.prettyprint', frag);
        for (v = 0, len4 = ref3.length; v < len4; v++) {
          node = ref3[v];
          $.replace(node, [$.tn('[code]')].concat(slice.call(node.childNodes), [$.tn('[/code]')]));
        }
        ref4 = $$('.linkify[data-original]', frag);
        for (z = 0, len5 = ref4.length; z < len5; z++) {
          node = ref4[z];
          $.replace(node, $.tn(node.dataset.original));
        }
        ref5 = $$('.embedder', frag);
        for (aa = 0, len6 = ref5.length; aa < len6; aa++) {
          node = ref5[aa];
          if (((ref6 = node.previousSibling) != null ? ref6.nodeValue : void 0) === ' ') {
            $.rm(node.previousSibling);
          }
          $.rm(node);
        }
        text += ">" + (frag.textContent.trim()) + "\n";
      }
      QR.openPost();
      ref7 = QR.nodes, com = ref7.com, thread = ref7.thread;
      if (!com.value) {
        thread.value = Get.threadFromNode(this);
      }
      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();
      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);
    },
    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, files, item, k, len1, ref;
      if (!e.clipboardData.items) {
        return;
      }
      files = [];
      ref = e.clipboardData.items;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        item = ref[k];
        if (!(item.kind === 'file')) {
          continue;
        }
        blob = item.getAsFile();
        blob.name = 'file';
        if (blob.type) {
          blob.name += '.' + blob.type.split('/')[1];
        }
        files.push(blob);
      }
      if (!files.length) {
        return;
      }
      QR.open();
      QR.handleFiles(files);
      return $.addClass(QR.nodes.el, 'dump');
    },
    pasteFF: function() {
      var arr, blob, bstr, i, images, img, k, len1, m, pasteArea, q, ref, src;
      pasteArea = QR.nodes.pasteArea;
      if (!pasteArea.childNodes.length) {
        return;
      }
      images = $$('img', pasteArea);
      $.rmAll(pasteArea);
      for (k = 0, len1 = images.length; k < len1; k++) {
        img = images[k];
        src = img.src;
        if (m = src.match(/data:(image\/(\w+));base64,(.+)/)) {
          bstr = atob(m[3]);
          arr = new Uint8Array(bstr.length);
          for (i = q = 0, ref = bstr.length; 0 <= ref ? q < ref : q > ref; i = 0 <= ref ? ++q : --q) {
            arr[i] = bstr.charCodeAt(i);
          }
          blob = new Blob([arr], {
            type: m[1]
          });
          blob.name = "file." + m[2];
          QR.handleFiles([blob]);
        } else if (/^https?:\/\//.test(src)) {
          QR.handleUrl(src);
        }
      }
    },
    handleUrl: function(urlDefault) {
      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, k, len1;
      if (this !== QR) {
        files = slice.call(this.files);
        this.value = null;
      }
      if (!files.length) {
        return;
      }
      QR.cleanNotifications();
      for (k = 0, len1 = files.length; k < len1; k++) {
        file = files[k];
        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 k, len1, list, options, ref, thread, val;
      if (!QR.nodes) {
        return;
      }
      list = QR.nodes.thread;
      options = [list.firstElementChild];
      ref = g.BOARD.threads.keys;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        thread = ref[k];
        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 dialog, event, i, items, m, match_max, match_min, name, node, nodes, ref, rules, save, scriptData, setNode;
      QR.nodes = nodes = {
        el: dialog = UI.dialog('qr', 'top: 50px; right: 0px;', {
          innerHTML: "<div class=\"move\"><label><input type=\"checkbox\" id=\"autohide\" title=\"Auto-hide\">Quick Reply</label><a href=\"javascript:;\" class=\"close\" title=\"Close\">×</a><select data-name=\"thread\" title=\"Create a new thread / Reply\"><option value=\"new\">New thread</option></select></div><form><div class=\"persona\"><button type=\"button\" id=\"sjis-toggle\" title=\"Toggle Mona font\">∀</button><button type=\"button\" id=\"tex-preview-button\" title=\"Preview TeX\">T<sub>E</sub>X</button><input name=\"name\" data-name=\"name\" list=\"list-name\" placeholder=\"Name\" class=\"field\" size=\"1\"><input name=\"email\" data-name=\"email\" list=\"list-email\" placeholder=\"Options\" class=\"field\" size=\"1\"><input name=\"sub\" data-name=\"sub\" list=\"list-sub\" placeholder=\"Subject\" class=\"field\" size=\"1\"></div><div class=\"textarea\"><textarea data-name=\"com\" placeholder=\"Comment\" class=\"field\"></textarea><span id=\"char-count\"></span><div id=\"tex-preview\"></div></div><div id=\"dump-list-container\"><div id=\"dump-list\"></div><a id=\"add-post\" href=\"javascript:;\" title=\"Add a post\">+</a></div><div class=\"oekaki\" hidden><input type=\"button\" id=\"qr-draw-button\" value=\"Draw\"><label><span>Width:</span><input name=\"oekaki-width\" value=\"400\" type=\"number\" class=\"field\" size=\"1\"></label><label><span>Height:</span><input name=\"oekaki-height\" value=\"400\" type=\"number\" class=\"field\" size=\"1\"></label><span class=\"oekaki-bg\" title=\"Background Color\"><input name=\"oekaki-bg\" type=\"checkbox\" checked><input name=\"oekaki-bgcolor\" type=\"color\" value=\"#ffffff\"></span></div><div id=\"file-n-submit\"><input type=\"button\" id=\"qr-file-button\" value=\"Files\"><span id=\"qr-filename-container\" class=\"field\"><span id=\"qr-no-file\">No selected file</span><input id=\"qr-filename\" data-name=\"filename\" spellcheck=\"false\"><label id=\"qr-spoiler-label\"><input type=\"checkbox\" id=\"qr-file-spoiler\" title=\"Spoiler image\"><a class=\"checkbox-letter\">S</a></label><a id=\"qr-oekaki-button\" title=\"Edit in Tegaki\"><i class=\"fa fa-edit\"></i></a><a href=\"javascript:;\" id=\"qr-filerm\" title=\"Remove file\"><i class=\"fa fa-times-circle\"></i></a><a id=\"url-button\" title=\"Post from url\"><i class=\"fa fa-link\"></i></a><a hidden id=\"paste-area\" title=\"Select to paste images\" class=\"fa fa-clipboard\" tabindex=\"-1\" contentEditable=\"true\"></a><a id=\"custom-cooldown-button\" title=\"Toggle custom cooldown\" class=\"disabled\"><i class=\"fa fa-clock-o\"></i></a><a id=\"dump-button\" title=\"Dump list\"><i class=\"fa fa-plus-square\"></i></a></span><input type=\"submit\"></div><select data-default=\"4\" name=\"filetag\"><option value=\"0\">Hentai</option><option value=\"6\">Porn</option><option value=\"1\">Japanese</option><option value=\"2\">Anime</option><option value=\"3\">Game</option><option value=\"5\">Loop</option><option value=\"4\" selected>Other</option></select><input type=\"file\" multiple></form><datalist id=\"list-name\"></datalist><datalist id=\"list-email\"></datalist><datalist id=\"list-sub\"></datalist> "
        })
      };
      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]');
      rules = $('ul.rules').textContent.trim();
      match_min = rules.match(/.+smaller than (\d+)x(\d+).+/);
      match_max = rules.match(/.+greater than (\d+)x(\d+).+/);
      QR.min_width = +(match_min != null ? match_min[1] : void 0) || 1;
      QR.min_height = +(match_min != null ? match_min[2] : void 0) || 1;
      QR.max_width = +(match_max != null ? match_max[1] : void 0) || 10000;
      QR.max_height = +(match_max != null ? match_max[2] : void 0) || 10000;
      scriptData = Get.scriptData();
      QR.max_size = (m = scriptData.match(/\bmaxFilesize *= *(\d+)\b/)) ? +m[1] : 4194304;
      QR.max_size_video = (m = scriptData.match(/\bmaxWebmFilesize *= *(\d+)\b/)) ? +m[1] : QR.max_size;
      QR.max_comment = (m = scriptData.match(/\bcomlen *= *(\d+)\b/)) ? +m[1] : 2000;
      QR.max_width_video = QR.max_height_video = 2048;
      QR.max_duration_video = (ref = g.BOARD.ID) === 'gif' || ref === 'wsg' ? 300 : 120;
      if (Conf['Show New Thread Option in Threads']) {
        $.addClass(QR.nodes.el, 'show-new-thread-option');
      }
      if (Conf['Show Name and Subject']) {
        $.addClass(QR.nodes.name, 'force-show');
        $.addClass(QR.nodes.sub, 'force-show');
        QR.nodes.email.placeholder = 'E-mail';
      }
      QR.forcedAnon = !!$('form[name="post"] input[name="name"][type="hidden"]');
      if (QR.forcedAnon) {
        $.addClass(QR.nodes.el, 'forced-anon');
      }
      QR.spoiler = !!$('.postForm input[name=spoiler]');
      if (QR.spoiler) {
        $.addClass(QR.nodes.el, 'has-spoiler');
      }
      if (g.BOARD.ID === 'jp' && Conf['sjisPreview']) {
        $.addClass(QR.nodes.el, 'sjis-preview');
      }
      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);
        });
      }
      $.on(nodes.autohide, 'change', QR.toggleHide);
      $.on(nodes.close, 'click', QR.close);
      $.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') {
        nodes.pasteArea.hidden = false;
        new MutationObserver(QR.pasteFF).observe(nodes.pasteArea, {
          childList: true
        });
      }
      items = ['thread', 'name', 'email', 'sub', 'com', 'filename'];
      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.init();
      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);
    },
    submit: function(e) {
      var captcha, cb, err, extra, filetag, formData, options, post, ref, textOnly, thread, threadID;
      if (e != null) {
        e.preventDefault();
      }
      if (QR.req) {
        QR.abort();
        return;
      }
      if (QR.cooldown.seconds) {
        QR.cooldown.auto = !QR.cooldown.auto;
        QR.status();
        return;
      }
      post = QR.posts[0];
      post.forceSave();
      threadID = post.thread;
      thread = g.BOARD.threads[threadID];
      if (g.BOARD.ID === 'f' && threadID === 'new') {
        filetag = QR.nodes.flashTag.value;
      }
      if (threadID === 'new') {
        threadID = null;
        if (g.BOARD.ID === 'vg' && !post.sub) {
          err = 'New threads require a subject.';
        } else if (!($.hasClass(d.body, 'text_only') || post.file || (textOnly = !!$('input[name=textonly]', $.id('postForm'))))) {
          err = 'No file selected.';
        }
      } else if (g.BOARD.threads[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 && !err) {
        captcha = QR.captcha.getOne();
        if (!captcha) {
          err = 'No valid captcha.';
          QR.captcha.setup(!QR.cooldown.auto || d.activeElement === QR.nodes.status);
        }
      }
      QR.cleanNotifications();
      if (err) {
        QR.cooldown.auto = false;
        QR.status();
        QR.error(err);
        return;
      }
      QR.cooldown.auto = QR.posts.length > 1;
      if (Conf['Auto Hide QR'] && !QR.cooldown.auto) {
        QR.hide();
      }
      if (!QR.cooldown.auto && $.x('ancestor::div[@id="qr"]', d.activeElement)) {
        d.activeElement.blur();
      }
      post.lock();
      formData = {
        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,
        textonly: textOnly,
        mode: 'regist',
        pwd: QR.persona.pwd
      };
      options = {
        responseType: 'document',
        withCredentials: true,
        onload: QR.response,
        onerror: function() {
          delete QR.req;
          post.unlock();
          QR.cooldown.auto = false;
          QR.status();
          return QR.error($.el('span', {
            innerHTML: "4chan X encountered an error while posting. [<a href=\"//4chan.org/banned\" target=\"_blank\">Banned?</a>] [<a href=\"https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions#what-does-4chan-x-encountered-an-error-while-posting-please-try-again-mean\" target=\"_blank\">More info</a>]"
          }));
        }
      };
      extra = {
        form: $.formData(formData),
        upCallbacks: {
          onload: function() {
            QR.req.isUploadFinished = true;
            QR.req.progress = '...';
            return QR.status();
          },
          onprogress: function(e) {
            QR.req.progress = (Math.round(e.loaded / e.total * 100)) + "%";
            return QR.status();
          }
        }
      };
      cb = function(response) {
        if (response != null) {
          if (response.challenge != null) {
            extra.form.append('recaptcha_challenge_field', response.challenge);
            extra.form.append('recaptcha_response_field', response.response);
          } else {
            extra.form.append('g-recaptcha-response', response.response);
          }
        }
        QR.req = $.ajax("https://sys.4chan.org/" + g.BOARD + "/post", options, extra);
        return QR.req.progress = '...';
      };
      if (typeof captcha === 'function') {
        QR.req = {
          progress: '...',
          abort: function() {
            return cb = null;
          }
        };
        captcha(function(response) {
          if (response) {
            return typeof cb === "function" ? cb(response) : void 0;
          } else {
            delete QR.req;
            post.unlock();
            QR.cooldown.auto = !!QR.captcha.captchas.length;
            return QR.status();
          }
        });
      } else {
        cb(captcha);
      }
      return QR.status();
    },
    response: function() {
      var URL, _, ban, err, h1, isReply, lastPostToThread, m, open, post, postID, postsCount, ref, ref1, ref2, req, resDoc, seconds, threadID;
      req = QR.req;
      delete QR.req;
      post = QR.posts[0];
      post.unlock();
      resDoc = req.response;
      if (ban = $('.banType', resDoc)) {
        err = $.el('span', ban.textContent.toLowerCase() === 'banned' ? {
          innerHTML: "You are banned on " + $(".board", resDoc).innerHTML + "! ;_;<br>Click <a href=\"//www.4chan.org/banned\" target=\"_blank\">here</a> to see the reason."
        } : {
          innerHTML: "You were issued a warning on " + $(".board", resDoc).innerHTML + " as " + $(".nameBlock", resDoc).innerHTML + ".<br>Reason: " + $(".reason", resDoc).innerHTML
        });
      } else if (err = resDoc.getElementById('errmsg')) {
        if ((ref = $('a', err)) != null) {
          ref.target = '_blank';
        }
      } else if (resDoc.title !== 'Post successful!') {
        err = 'Connection error with sys.4chan.org.';
      } else if (req.status !== 200) {
        err = "Error " + req.statusText + " (" + req.status + ")";
      }
      if (err) {
        if (/captcha|verification/i.test(err.textContent) || err === 'Connection error with sys.4chan.org.') {
          if (/mistyped/i.test(err.textContent)) {
            err = $.el('span', {
              innerHTML: "You mistyped the CAPTCHA, or the CAPTCHA malfunctioned [<a href=\"https://www.4chan-x.net/captchas.html\" target=\"_blank\">complain here</a>]."
            });
          } else if (/expired/i.test(err.textContent)) {
            err = 'This CAPTCHA is no longer valid because it has expired.';
          }
          QR.cooldown.auto = QR.captcha.isEnabled || err === 'Connection error with sys.4chan.org.';
          QR.cooldown.addDelay(post, 2);
        } else if (err.textContent && (m = err.textContent.match(/(?:(\d+)\s+minutes?\s+)?(\d+)\s+second/i)) && !/duplicate|hour/i.test(err.textContent)) {
          QR.cooldown.auto = !/have\s+been\s+muted/i.test(err.textContent);
          seconds = 60 * (+(m[1] || 0)) + (+m[2]);
          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 && ((ref1 = d.activeElement) === QR.nodes.status || ref1 === d.body));
        if (QR.captcha.isEnabled && !QR.captcha.captchas.length) {
          QR.cooldown.auto = false;
        }
        QR.status();
        QR.error(err);
        return;
      }
      h1 = $('h1', resDoc);
      QR.cleanNotifications();
      if (Conf['Posting Success Notifications']) {
        QR.notifications.push(new Notice('success', h1.textContent, 5));
      }
      ref2 = h1.nextSibling.textContent.match(/thread:(\d+),no:(\d+)/), _ = ref2[0], threadID = ref2[1], postID = ref2[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, ref3;
        ref3 = QR.posts.slice(1);
        for (k = 0, len1 = ref3.length; k < len1; k++) {
          p = ref3[k];
          if (p.thread === post.thread) {
            return true;
          }
        }
      })());
      if (!(Conf['Persistent QR'] || postsCount)) {
        QR.close();
      } else {
        post.rm();
        QR.captcha.setup(d.activeElement === QR.nodes.status);
      }
      QR.cooldown.add(threadID, postID);
      URL = threadID === postID ? window.location.origin + "/" + g.BOARD + "/thread/" + threadID : g.VIEW === 'index' && 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 window.location = 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);
            }
          }
        }, {
          type: 'HEAD'
        });
      };
      return check();
    },
    abort: function() {
      if (QR.req && !QR.req.isUploadFinished) {
        QR.req.abort();
        delete QR.req;
        QR.posts[0].unlock();
        QR.cooldown.auto = false;
        QR.notifications.push(new Notice('info', 'QR upload aborted.', 5));
      }
      return QR.status();
    }
  };

  Captcha = {};

  Captcha.fixes = {
    imageKeys: '789456123uiojklm'.split('').concat(['Comma', 'Period']),
    imageKeys16: '7890uiopjkl'.split('').concat(['Semicolon', 'm', 'Comma', 'Period', 'Slash']),
    css: '.rc-imageselect-target > div:focus, .rc-image-tile-target:focus {\n  outline: 2px solid #4a90e2;\n}\n.rc-imageselect-target td:focus {\n  box-shadow: inset 0 0 0 2px #4a90e2;\n  outline: none;\n}\n.rc-button-default:focus {\n  box-shadow: inset 0 0 0 2px #0063d6;\n}',
    cssNoscript: '.fbc-payload-imageselect {\n  position: relative;\n}\n.fbc-payload-imageselect > label {\n  position: absolute;\n  display: block;\n  height: 93.3px;\n  width: 93.3px;\n}\nlabel[data-row="0"] {top: 0px;}\nlabel[data-row="1"] {top: 93.3px;}\nlabel[data-row="2"] {top: 186.6px;}\nlabel[data-col="0"] {left: 0px;}\nlabel[data-col="1"] {left: 93.3px;}\nlabel[data-col="2"] {left: 186.6px;}\n.fbc-payload-imageselect > input:focus + label {\n  outline: 2px solid #4a90e2;\n}\n.fbc-button-verify input:focus {\n  box-shadow: inset 0 0 0 2px #0063d6;\n}\nbody.focus .fbc {\n  box-shadow: inset 0 0 0 2px #4a90e2;\n}',
    init: function() {
      switch (location.pathname.split('/')[3]) {
        case 'anchor':
          return this.initMain();
        case 'frame':
          return this.initPopup();
        case 'fallback':
          return this.initNoscript();
      }
    },
    initMain: function() {
      var a, k, len1, ref;
      $.onExists(d.body, '#recaptcha-anchor', function(checkbox) {
        var focus;
        focus = function() {
          var ref;
          if (d.hasFocus() && ((ref = d.activeElement) === d.documentElement || ref === d.body)) {
            return checkbox.focus();
          }
        };
        focus();
        return $.on(window, 'focus', function() {
          return $.queueTask(focus);
        });
      });
      ref = $$('.rc-anchor-pt a');
      for (k = 0, len1 = ref.length; k < len1; k++) {
        a = ref[k];
        a.tabIndex = -1;
      }
    },
    initPopup: function() {
      $.addStyle(this.css);
      this.fixImages();
      new MutationObserver((function(_this) {
        return function() {
          return _this.fixImages();
        };
      })(this)).observe(d.body, {
        childList: true,
        subtree: true
      });
      return $.on(d, 'keydown', this.keybinds.bind(this));
    },
    initNoscript: function() {
      var data, ref, token;
      this.noscript = true;
      data = (token = (ref = $('.fbc-verification-token > textarea')) != null ? ref.value : void 0) ? {
        token: token
      } : {
        working: true
      };
      new Connection(window.parent, '*').send(data);
      d.body.classList.toggle('focus', d.hasFocus());
      $.on(window, 'focus blur', function() {
        return d.body.classList.toggle('focus', d.hasFocus());
      });
      this.images = $$('.fbc-payload-imageselect > input');
      this.width = 3;
      if (this.images.length !== 9) {
        return;
      }
      $.addStyle(this.cssNoscript);
      this.addLabels();
      $.on(d, 'keydown', this.keybinds.bind(this));
      return $.on($('.fbc-imageselect-challenge > form'), 'submit', this.checkForm.bind(this));
    },
    fixImages: function() {
      var img, k, len1, ref;
      this.images = $$('.rc-image-tile-target');
      if (!this.images.length) {
        this.images = $$('.rc-imageselect-target > div, .rc-imageselect-target td');
      }
      this.width = $$('.rc-imageselect-target tr:first-of-type td').length || Math.round(Math.sqrt(this.images.length));
      ref = this.images;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        img = ref[k];
        img.tabIndex = 0;
      }
      if (this.images.length === 9) {
        this.addTooltips(this.images);
      } else {
        this.addTooltips16(this.images);
      }
      return this.complaintLinks();
    },
    complaintLinks: function() {
      var errmsg, k, len1, link, ref;
      ref = $$('.rc-imageselect-incorrect-response, .rc-imageselect-error-select-one, .rc-imageselect-error-select-more, .rc-imageselect-error-dynamic-more');
      for (k = 0, len1 = ref.length; k < len1; k++) {
        errmsg = ref[k];
        if (!$('a', errmsg)) {
          link = $.el('a', {
            href: 'https://www.4chan-x.net/captchas.html',
            target: '_blank',
            textContent: '[complain]'
          });
          $.add(errmsg, [$.tn(' '), link]);
        }
      }
    },
    addLabels: function() {
      var checkbox, i, imageSelect, label, labels;
      imageSelect = $('.fbc-payload-imageselect');
      labels = (function() {
        var k, len1, ref, results;
        ref = this.images;
        results = [];
        for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
          checkbox = ref[i];
          checkbox.id = "checkbox-" + i;
          label = $.el('label', {
            htmlFor: checkbox.id
          });
          label.dataset.row = Math.floor(i / 3);
          label.dataset.col = i % 3;
          $.after(checkbox, label);
          results.push(label);
        }
        return results;
      }).call(this);
      return this.addTooltips(labels);
    },
    addTooltips: function(nodes) {
      var i, k, len1, node;
      for (i = k = 0, len1 = nodes.length; k < len1; i = ++k) {
        node = nodes[i];
        node.title = this.imageKeys[i] + " or " + (this.imageKeys[i + 9][0].toUpperCase()) + this.imageKeys[i + 9].slice(1);
      }
    },
    addTooltips16: function(nodes) {
      var i, k, key, len1, node, ref;
      ref = this.imageKeys16;
      for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
        key = ref[i];
        if (i % 4 < this.width && (node = nodes[nodes.length - (4 - Math.floor(i / 4)) * this.width + (i % 4)])) {
          node.title = "" + (key[0].toUpperCase()) + key.slice(1);
        }
      }
    },
    checkForm: function(e) {
      var checkbox, k, len1, n, ref;
      n = 0;
      ref = this.images;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        checkbox = ref[k];
        if (checkbox.checked) {
          n++;
        }
      }
      if (n === 0) {
        return e.preventDefault();
      }
    },
    keybinds: function(e) {
      var dx, i, img, key, last, n, reload, verify, w, x;
      if (!(this.images && doc.contains(this.images[0]))) {
        return;
      }
      n = this.images.length;
      w = this.width;
      last = n + w - 1;
      reload = $('#recaptcha-reload-button, .fbc-button-reload');
      verify = $('#recaptcha-verify-button, .fbc-button-verify > input');
      x = this.images.indexOf(d.activeElement);
      if (x < 0) {
        x = d.activeElement === verify ? last : n;
      }
      key = Keybinds.keyCode(e);
      if (!this.noscript && key === 'Space' && x < n) {
        this.images[x].click();
      } else if (n === 9 && (i = this.imageKeys.indexOf(key)) >= 0) {
        this.images[i % 9].click();
        verify.focus();
      } else if (n !== 9 && (i = this.imageKeys16.indexOf(key)) >= 0 && i % 4 < w && (img = this.images[n - (4 - Math.floor(i / 4)) * w + (i % 4)])) {
        img.click();
        verify.focus();
      } else if (dx = {
        'Up': n,
        'Down': w,
        'Left': last,
        'Right': 1
      }[key]) {
        x = (x + dx) % (n + w);
        if ((n < x && x < last)) {
          x = dx === last ? n : last;
        }
        (this.images[x] || (x === n ? reload : void 0) || (x === last ? verify : void 0)).focus();
      } else {
        return;
      }
      e.preventDefault();
      return e.stopPropagation();
    }
  };

  Captcha.replace = {
    init: function() {
      if (!(d.cookie.indexOf('pass_enabled=1') < 0)) {
        return;
      }
      if (location.hostname === 'sys.4chan.org' && /[?&]altc\b/.test(location.search) && Main.jsEnabled) {
        $.onExists(doc, 'script[src="//www.google.com/recaptcha/api/js/recaptcha_ajax.js"]', function() {
          $.global(function() {
            return window.el.onload = null;
          });
          return Captcha.v1.create();
        });
        return;
      }
      if (((Conf['Use Recaptcha v1'] && location.hostname === 'boards.4chan.org') || (Conf['Use Recaptcha v1 in Reports'] && location.hostname === 'sys.4chan.org')) && Main.jsEnabled) {
        $.ready(Captcha.replace.v1);
        return;
      }
      if (Conf['Force Noscript Captcha'] && Main.jsEnabled) {
        $.ready(Captcha.replace.noscript);
        return;
      }
      if (Conf['captchaLanguage'].trim() || Conf['Captcha Fixes']) {
        if (location.hostname === 'boards.4chan.org') {
          return $.onExists(doc, '#captchaFormPart', function(node) {
            return $.onExists(node, 'iframe', Captcha.replace.iframe);
          });
        } else {
          return $.onExists(doc, 'iframe', Captcha.replace.iframe);
        }
      }
    },
    noscript: function() {
      var insert, noscript, original, span, toggle;
      if (!((original = $('#g-recaptcha, #captchaContainerAlt')) && (noscript = $('noscript')))) {
        return;
      }
      span = $.el('span', {
        id: 'captcha-forced-noscript'
      });
      $.replace(noscript, span);
      $.rm(original);
      insert = function() {
        span.innerHTML = noscript.textContent;
        return Captcha.replace.iframe($('iframe', span));
      };
      if ((toggle = $('#togglePostFormLink a, #form-link'))) {
        return $.on(toggle, 'click', insert);
      } else {
        return insert();
      }
    },
    v1: function() {
      var form, link;
      if (!$.id('g-recaptcha')) {
        return;
      }
      Captcha.v1.replace();
      if ((link = $.id('form-link'))) {
        return $.on(link, 'click', function() {
          return Captcha.v1.create();
        });
      } else if (location.hostname === 'boards.4chan.org') {
        form = $.id('postForm');
        return form.addEventListener('focus', (function() {
          return Captcha.v1.create();
        }), true);
      } else {
        return Captcha.v1.create();
      }
    },
    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;
        }
      }
      return Captcha.replace.autocopy(iframe);
    },
    autocopy: function(iframe) {
      if (!(Conf['Captcha Fixes'] && /^https:\/\/www\.google\.com\/recaptcha\/api\/fallback\?/.test(iframe.src))) {
        return;
      }
      return new Connection(iframe, 'https://www.google.com', {
        working: function() {
          var ref, ref1;
          if ((ref = $.id('qr')) != null ? ref.contains(iframe) : void 0) {
            return (ref1 = $('#qr .captcha-container textarea')) != null ? ref1.parentNode.hidden = true : void 0;
          }
        },
        token: function(token) {
          var node, textarea;
          node = iframe;
          while ((node = node.parentNode)) {
            if ((textarea = $('textarea', node))) {
              break;
            }
          }
          textarea.value = token;
          return $.event('input', null, textarea);
        }
      });
    }
  };

  Captcha.v1 = {
    blank: "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='300' height='57'/>",
    init: function() {
      var imgContainer, input;
      if (d.cookie.indexOf('pass_enabled=1') >= 0) {
        return;
      }
      if (!(this.isEnabled = !!$('#g-recaptcha, #captchaContainerAlt'))) {
        return;
      }
      imgContainer = $.el('div', {
        className: 'captcha-img',
        title: 'Reload reCAPTCHA'
      });
      $.extend(imgContainer, {
        innerHTML: "<img>"
      });
      input = $.el('input', {
        className: 'captcha-input field',
        title: 'Verification',
        autocomplete: 'off',
        spellcheck: false
      });
      this.nodes = {
        img: imgContainer.firstChild,
        input: input
      };
      $.on(input, 'blur', QR.focusout);
      $.on(input, 'focus', QR.focusin);
      $.on(input, 'keydown', QR.captcha.keydown.bind(QR.captcha));
      $.on(this.nodes.img.parentNode, 'click', QR.captcha.reload.bind(QR.captcha));
      $.addClass(QR.nodes.el, 'has-captcha', 'captcha-v1');
      $.after(QR.nodes.com.parentNode, [imgContainer, input]);
      this.captchas = [];
      $.get('captchas', [], function(arg) {
        var captchas;
        captchas = arg.captchas;
        QR.captcha.sync(captchas);
        return QR.captcha.clear();
      });
      $.sync('captchas', this.sync);
      this.replace();
      this.beforeSetup();
      if (Conf['Auto-load captcha']) {
        this.setup();
      }
      new MutationObserver(this.afterSetup).observe($.id('captchaContainerAlt'), {
        childList: true
      });
      return this.afterSetup();
    },
    replace: function() {
      var container, old;
      if (this.script) {
        return;
      }
      if (!(this.script = $('script[src="//www.google.com/recaptcha/api/js/recaptcha_ajax.js"]', d.head))) {
        this.script = $.el('script', {
          src: '//www.google.com/recaptcha/api/js/recaptcha_ajax.js'
        });
        $.add(d.head, this.script);
      }
      if (old = $.id('g-recaptcha')) {
        container = $.el('div', {
          id: 'captchaContainerAlt'
        });
        return $.replace(old, container);
      }
    },
    create: function() {
      var cont, lang;
      cont = $.id('captchaContainerAlt');
      if (this.occupied) {
        return;
      }
      this.occupied = true;
      if ((lang = Conf['captchaLanguage'].trim())) {
        cont.dataset.lang = lang;
      }
      $.onExists(cont, '#recaptcha_image', function(image) {
        return $.on(image, 'click', function() {
          if ($.id('recaptcha_challenge_image')) {
            return $.global(function() {
              return window.Recaptcha.reload();
            });
          }
        });
      });
      $.onExists(cont, '#recaptcha_response_field', function(field) {
        $.on(field, 'keydown', function(e) {
          if (e.keyCode === 8 && !field.value) {
            return $.global(function() {
              return window.Recaptcha.reload();
            });
          }
        });
        if (location.hostname === 'sys.4chan.org') {
          return field.focus();
        }
      });
      return $.global(function() {
        var container, options, script;
        container = document.getElementById('captchaContainerAlt');
        options = {
          theme: 'clean',
          tabindex: {
            "boards.4chan.org": 5
          }[location.hostname],
          lang: container.dataset.lang
        };
        if (window.Recaptcha) {
          return window.Recaptcha.create('6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc', container, options);
        } else {
          script = document.head.querySelector('script[src="//www.google.com/recaptcha/api/js/recaptcha_ajax.js"]');
          return script.addEventListener('load', function() {
            return window.Recaptcha.create('6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc', container, options);
          }, false);
        }
      });
    },
    cb: {
      focus: function() {
        return QR.captcha.setup(false, true);
      }
    },
    beforeSetup: function() {
      var img, input, ref;
      ref = this.nodes, img = ref.img, input = ref.input;
      img.parentNode.hidden = true;
      img.src = this.blank;
      input.value = '';
      input.placeholder = 'Focus to load reCAPTCHA';
      this.count();
      return $.on(input, 'focus click', this.cb.focus);
    },
    needed: function() {
      var captchaCount, postsCount;
      captchaCount = this.captchas.length;
      if (QR.req) {
        captchaCount++;
      }
      postsCount = QR.posts.length;
      if (postsCount === 1 && !Conf['Auto-load captcha'] && !QR.posts[0].com && !QR.posts[0].file) {
        postsCount = 0;
      }
      return captchaCount < postsCount;
    },
    onNewPost: function() {},
    onPostChange: function() {},
    setup: function(focus, force) {
      if (!(this.isEnabled && (force || this.needed()))) {
        return;
      }
      this.create();
      if (focus) {
        $.addClass(QR.nodes.el, 'focus');
        return this.nodes.input.focus();
      }
    },
    afterSetup: function() {
      var challenge, img, input, ref, setLifetime;
      if (!(challenge = $.id('recaptcha_challenge_field_holder'))) {
        return;
      }
      if (challenge === QR.captcha.nodes.challenge) {
        return;
      }
      setLifetime = function(e) {
        return QR.captcha.lifetime = e.detail;
      };
      $.on(window, 'captcha:timeout', setLifetime);
      $.global(function() {
        return window.dispatchEvent(new CustomEvent('captcha:timeout', {
          detail: window.RecaptchaState.timeout
        }));
      });
      $.off(window, 'captcha:timeout', setLifetime);
      ref = QR.captcha.nodes, img = ref.img, input = ref.input;
      img.parentNode.hidden = false;
      input.placeholder = 'Verification';
      QR.captcha.count();
      $.off(input, 'focus click', QR.captcha.cb.focus);
      QR.captcha.nodes.challenge = challenge;
      new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, {
        childList: true,
        subtree: true,
        attributes: true
      });
      QR.captcha.load();
      if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) {
        QR.nodes.el.style.top = null;
        return QR.nodes.el.style.bottom = '0px';
      }
    },
    destroy: function() {
      if (!this.script) {
        return;
      }
      $.global(function() {
        return window.Recaptcha.destroy();
      });
      delete this.occupied;
      if (this.nodes) {
        return this.beforeSetup();
      }
    },
    sync: function(captchas) {
      if (captchas == null) {
        captchas = [];
      }
      QR.captcha.captchas = captchas;
      return QR.captcha.count();
    },
    getOne: function() {
      var captcha, challenge, response, timeout;
      this.clear();
      if (captcha = this.captchas.shift()) {
        this.count();
        $.set('captchas', this.captchas);
        return captcha;
      } else {
        challenge = this.nodes.img.alt;
        timeout = this.timeout;
        if (/\S/.test(response = this.nodes.input.value)) {
          this.destroy();
          return {
            challenge: challenge,
            response: response,
            timeout: timeout
          };
        } else {
          return null;
        }
      }
    },
    save: function() {
      var response;
      if (!/\S/.test(response = this.nodes.input.value)) {
        return;
      }
      this.nodes.input.value = '';
      this.captchas.push({
        challenge: this.nodes.img.alt,
        response: response,
        timeout: this.timeout
      });
      this.captchas.sort(function(a, b) {
        return a.timeout - b.timeout;
      });
      this.count();
      this.destroy();
      this.setup(false, true);
      return $.set('captchas', this.captchas);
    },
    clear: function() {
      var captcha, i, k, len1, now, ref;
      if (!this.captchas.length) {
        return;
      }
      $.forceSync('captchas');
      now = Date.now();
      ref = this.captchas;
      for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
        captcha = ref[i];
        if (captcha.timeout > now) {
          break;
        }
      }
      if (!i) {
        return;
      }
      this.captchas = this.captchas.slice(i);
      this.count();
      return $.set('captchas', this.captchas);
    },
    load: function() {
      var challenge, challenge_image;
      if ($('#captchaContainerAlt[class~="recaptcha_is_showing_audio"]')) {
        this.nodes.img.src = this.blank;
        return;
      }
      if (!this.nodes.challenge.firstChild) {
        return;
      }
      if (!(challenge_image = $.id('recaptcha_challenge_image'))) {
        return;
      }
      this.timeout = Date.now() + this.lifetime * $.SECOND - $.MINUTE;
      challenge = this.nodes.challenge.firstChild.value;
      this.nodes.img.alt = challenge;
      this.nodes.img.src = challenge_image.src;
      this.nodes.input.value = '';
      return this.clear();
    },
    count: function() {
      var count, placeholder;
      count = this.captchas ? this.captchas.length : 0;
      placeholder = this.nodes.input.placeholder.replace(/\ \(.*\)$/, '');
      placeholder += (function() {
        switch (count) {
          case 0:
            if (placeholder === 'Verification') {
              return ' (Shift + Enter to cache)';
            } else {
              return '';
            }
            break;
          case 1:
            return ' (1 cached captcha)';
          default:
            return " (" + count + " cached captchas)";
        }
      })();
      this.nodes.input.placeholder = placeholder;
      this.nodes.input.alt = count;
      clearTimeout(this.timer);
      if (count) {
        return this.timer = setTimeout(this.clear.bind(this), this.captchas[0].timeout - Date.now());
      }
    },
    reload: function(focus) {
      $.global(function() {
        if (window.Recaptcha.type === 'image') {
          window.Recaptcha.reload();
        } else {
          window.Recaptcha.switch_type('image');
        }
        return window.Recaptcha.should_focus = false;
      });
      if (focus) {
        return this.nodes.input.focus();
      }
    },
    keydown: function(e) {
      if (e.keyCode === 8 && !this.nodes.input.value) {
        this.reload();
      } else if (e.keyCode === 13 && e.shiftKey) {
        this.save();
      } else {
        return;
      }
      return e.preventDefault();
    }
  };

  Captcha.v2 = {
    lifetime: 2 * $.MINUTE,
    init: function() {
      var counter, root;
      if (d.cookie.indexOf('pass_enabled=1') >= 0) {
        return;
      }
      if (!(this.isEnabled = !!$('#g-recaptcha, #captchaContainerAlt, #captcha-forced-noscript'))) {
        return;
      }
      if ((this.noscript = Conf['Force Noscript Captcha'] || !Main.jsEnabled)) {
        $.addClass(QR.nodes.el, 'noscript-captcha');
      }
      this.captchas = [];
      $.get('captchas', [], function(arg) {
        var captchas;
        captchas = arg.captchas;
        return QR.captcha.sync(captchas);
      });
      $.sync('captchas', this.sync.bind(this));
      root = $.el('div', {
        className: 'captcha-root'
      });
      $.extend(root, {
        innerHTML: "<div class=\"captcha-counter\"><a href=\"javascript:;\"></a></div>"
      });
      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: {},
    postsCount: 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;
    },
    needed: function() {
      var captchaCount;
      captchaCount = this.captchas.length;
      if (QR.req) {
        captchaCount++;
      }
      this.postsCount = QR.posts.length;
      if (this.postsCount === 1 && !Conf['Auto-load captcha'] && !QR.posts[0].com && !QR.posts[0].file) {
        this.postsCount = 0;
      }
      return captchaCount < this.postsCount;
    },
    onNewPost: function() {
      return this.setup();
    },
    onPostChange: function() {
      if (this.postsCount === 0) {
        this.setup();
      }
      if (QR.posts.length === 1 && !Conf['Auto-load captcha'] && !QR.posts[0].com && !QR.posts[0].file) {
        return this.postsCount = 0;
      }
    },
    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 && (this.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', _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',
        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;
        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('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;
          return window.onRecaptchaLoaded = function() {
            render();
            return cbNative();
          };
        }
      });
    },
    afterSetup: function(mutations) {
      var iframe, k, len1, len2, mutation, node, q, ref, textarea;
      for (k = 0, len1 = mutations.length; k < len1; k++) {
        mutation = mutations[k];
        ref = mutation.addedNodes;
        for (q = 0, len2 = ref.length; q < len2; q++) {
          node = ref[q];
          if ((iframe = $.x('./descendant-or-self::iframe', node))) {
            this.setupIFrame(iframe);
          }
          if ((textarea = $.x('./descendant-or-self::textarea', node))) {
            this.setupTextArea(textarea);
          }
        }
      }
    },
    setupIFrame: function(iframe) {
      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();
      }
      return $.global(function() {
        var f;
        f = document.querySelector('#qr iframe');
        return f.focus = f.blur = function() {};
      });
    },
    fixQRPosition: function() {
      if (QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight) {
        QR.nodes.el.style.top = null;
        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() {
      var garbage, i, ins, node, ref;
      if (!this.isEnabled) {
        return;
      }
      delete this.timeouts.destroy;
      $.rmClass(QR.nodes.el, 'captcha-open');
      if (this.nodes.container) {
        $.rm(this.nodes.container);
      }
      delete this.nodes.container;
      garbage = $.X('//iframe[starts-with(@src, "https://www.google.com/recaptcha/api2/frame")]/ancestor-or-self::*[parent::body]');
      i = 0;
      while (node = garbage.snapshotItem(i++)) {
        if (((ref = (ins = node.nextSibling)) != null ? ref.nodeName : void 0) === 'INS') {
          $.rm(ins);
        }
        $.rm(node);
      }
    },
    sync: function(captchas) {
      if (captchas == null) {
        captchas = [];
      }
      this.captchas = captchas;
      this.clear();
      return this.count();
    },
    getOne: function() {
      var captcha;
      this.clear();
      if ((captcha = this.captchas.shift())) {
        $.set('captchas', this.captchas);
        this.count();
        return captcha;
      } else {
        return null;
      }
    },
    save: function(pasted, token) {
      var base1, focus, ref;
      $.forceSync('captchas');
      this.captchas.push({
        response: token || $('textarea', this.nodes.container).value,
        timeout: Date.now() + this.lifetime
      });
      this.captchas.sort(function(a, b) {
        return a.timeout - b.timeout;
      });
      $.set('captchas', this.captchas);
      this.count();
      focus = ((ref = d.activeElement) != null ? ref.nodeName : void 0) === 'IFRAME' && /https?:\/\/www\.google\.com\/recaptcha\//.test(d.activeElement.src);
      if (this.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 ((base1 = this.timeouts).destroy == null) {
            base1.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();
      }
    },
    clear: function() {
      var captcha, i, k, len1, now, ref;
      if (!this.captchas.length) {
        return;
      }
      $.forceSync('captchas');
      now = Date.now();
      ref = this.captchas;
      for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
        captcha = ref[i];
        if (captcha.timeout > now) {
          break;
        }
      }
      if (!i) {
        return;
      }
      this.captchas = this.captchas.slice(i);
      this.count();
      $.set('captchas', this.captchas);
      return this.setup(d.activeElement === QR.nodes.status);
    },
    count: function() {
      this.nodes.counter.textContent = "Captchas: " + this.captchas.length;
      clearTimeout(this.timeouts.clear);
      if (this.captchas.length) {
        return this.timeouts.clear = setTimeout(this.clear.bind(this), this.captchas[0].timeout - Date.now());
      }
    },
    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);
        });
      }
    }
  };

  PassLink = {
    init: function() {
      if (!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: "<a href=\"javascript:;\">4chan Pass</a>"
      });
      $.on(passLink.firstElementChild, 'click', function() {
        return window.open('//sys.4chan.org/auth', Date.now(), 'width=500,height=280,toolbar=0');
      });
      return $.before(styleSelector.previousSibling, [passLink, $.tn('\u00A0\u00A0')]);
    }
  };

  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
      });
    }
  };

  QR.cooldown = {
    seconds: 0,
    delays: {
      thread: 0,
      reply: 0,
      image: 0,
      reply_intra: 0,
      image_intra: 0,
      deletion: 60,
      thread_global: 300
    },
    init: function() {
      if (!Conf['Quick Reply']) {
        return;
      }
      this.data = Conf['cooldowns'];
      return $.sync('cooldowns', this.sync);
    },
    setup: function() {
      var delay, m, ref, type;
      if (m = Get.scriptData().match(/\bcooldowns *= *({[^}]+})/)) {
        $.extend(QR.cooldown.delays, JSON.parse(m[1]));
      }
      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 || {};
      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
        });
      }
      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);
      return QR.cooldown.start();
    },
    addMute: function(delay) {
      if (!Conf['Cooldown']) {
        return;
      }
      QR.cooldown.set(g.BOARD.ID, Date.now(), {
        type: 'mute',
        delay: delay
      });
      return QR.cooldown.start();
    },
    "delete": function(post) {
      var base1, cooldown, cooldowns, id, name1;
      if (!QR.cooldown.data) {
        return;
      }
      $.forceSync('cooldowns');
      cooldowns = ((base1 = QR.cooldown.data)[name1 = post.board.ID] || (base1[name1] = {}));
      for (id in cooldowns) {
        cooldown = cooldowns[id];
        if ((cooldown.delay == null) && cooldown.threadID === post.thread.ID && cooldown.postID === post.ID) {
          delete cooldowns[id];
        }
      }
      return QR.cooldown.save([post.board.ID]);
    },
    secondsDeletion: function(post) {
      var cooldown, cooldowns, seconds, start;
      if (!(QR.cooldown.data && Conf['Cooldown'])) {
        return 0;
      }
      cooldowns = QR.cooldown.data[post.board.ID] || {};
      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
        };
      }
    },
    set: function(scope, id, value) {
      var base1, cooldowns;
      $.forceSync('cooldowns');
      cooldowns = ((base1 = QR.cooldown.data)[scope] || (base1[scope] = {}));
      cooldowns[id] = value;
      return $.set('cooldowns', QR.cooldown.data);
    },
    save: function(scopes) {
      var data, k, len1, scope;
      data = QR.cooldown.data;
      for (k = 0, len1 = scopes.length; k < len1; k++) {
        scope = scopes[k];
        if (scope in data && !Object.keys(data[scope]).length) {
          delete data[scope];
        }
      }
      return $.set('cooldowns', data);
    },
    count: function() {
      var base1, cooldown, cooldowns, elapsed, k, len1, maxDelay, nCooldowns, now, ref, ref1, save, scope, seconds, start, suffix, threadID, type, update;
      $.forceSync('cooldowns');
      save = [];
      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 (k = 0, len1 = ref1.length; k < len1; k++) {
          scope = ref1[k];
          cooldowns = ((base1 = QR.cooldown.data)[scope] || (base1[scope] = {}));
          for (start in cooldowns) {
            cooldown = cooldowns[start];
            start = +start;
            elapsed = Math.floor((now - start) / $.SECOND);
            if (elapsed < 0) {
              delete cooldowns[start];
              save.push(scope);
              continue;
            }
            if (cooldown.delay != null) {
              if (cooldown.delay <= elapsed) {
                delete cooldowns[start];
                save.push(scope);
              } 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) {
              delete cooldowns[start];
              save.push(scope);
              continue;
            }
            if ((type === 'thread') === (cooldown.threadID === cooldown.postID) && cooldown.boardID !== g.BOARD.ID) {
              suffix = scope === 'global' ? '_global' : type !== 'thread' && threadID === cooldown.threadID ? '_intra' : '';
              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.length) {
        QR.cooldown.save(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) {
        QR.status();
      }
      if (seconds === 0 && QR.cooldown.auto && !QR.req) {
        return QR.submit();
      }
    }
  };

  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: 95,
          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;
            });
            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/painter"]', d.head)) {
        return cb();
      } else {
        style = $.el('link', {
          rel: 'stylesheet',
          href: "//s.4cdn.org/css/painter." + (Date.now()) + ".css"
        });
        script = $.el('script', {
          src: "//s.4cdn.org/js/painter.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 file, isVideo;
            document.removeEventListener('QRFile', cb, false);
            if (!e.detail) {
              return error('No file to edit.');
            }
            if (!/^(image|video)\//.test(e.detail.type)) {
              return error('Not an image.');
            }
            isVideo = /^video\//.test(e.detail.type);
            file = document.createElement(isVideo ? 'video' : 'img');
            file.addEventListener('error', function() {
              return error('Could not open file.', false);
            });
            file.addEventListener((isVideo ? 'loadeddata' : 'load'), function() {
              if (Tegaki.bg) {
                Tegaki.destroy();
              }
              FCX.oekakiName = name;
              Tegaki.open({
                onDone: FCX.oekakiCB,
                onCancel: function() {
                  return Tegaki.bgColor = '#ffffff';
                },
                width: file.naturalWidth || file.videoWidth,
                height: file.naturalHeight || file.videoHeight,
                bgColor: 'transparent'
              });
              return Tegaki.activeCtx.drawImage(file, 0, 0);
            }, false);
            return file.src = URL.createObjectURL(e.detail);
          };
          if (Tegaki.bg && Tegaki.onDoneCb === FCX.oekakiCB && source === FCX.oekakiLatest) {
            FCX.oekakiName = name;
            return Tegaki.resume();
          } else {
            document.addEventListener('QRFile', cb, false);
            return document.dispatchEvent(new CustomEvent('QRGetFile', {
              bubbles: true
            }));
          }
        });
      });
    },
    toggle: function() {
      return QR.oekaki.load(function() {
        return QR.nodes.oekaki.hidden = !QR.nodes.oekaki.hidden;
      });
    }
  };

  QR.persona = {
    pwd: '',
    always: {},
    init: function() {
      QR.persona.getPassword();
      return $.get('QR.personas', Conf['QR.personas'], function(arg) {
        var arr, item, k, len1, personas, ref, type, types;
        personas = arg['QR.personas'];
        types = {
          name: [],
          email: [],
          sub: []
        };
        ref = personas.split('\n');
        for (k = 0, len1 = ref.length; k < len1; k++) {
          item = ref[k];
          QR.persona.parseItem(item.trim(), types);
        }
        for (type in types) {
          arr = types[type];
          QR.persona.loadPersonas(type, arr);
        }
      });
    },
    parseItem: function(item, types) {
      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(types[type], val) < 0) {
        return types[type].push(val);
      }
    },
    loadPersonas: function(type, arr) {
      var k, len1, list, val;
      list = $("#list-" + type, QR.nodes.el);
      for (k = 0, len1 = arr.length; k < len1; k++) {
        val = arr[k];
        if (val) {
          $.add(list, $.el('option', {
            textContent: val
          }));
        }
      }
    },
    getPassword: function() {
      var input, m, ref;
      if (!QR.persona.pwd) {
        QR.persona.pwd = (m = d.cookie.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : (input = $.id('postPassword')) ? input.value : ((ref = $.id('delPassword')) != null ? ref.value : void 0) || '';
      }
      return QR.persona.pwd;
    },
    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
        };
        return $.set('QR.persona', persona);
      });
    }
  };

  QR.post = (function() {
    function _Class(select) {
      this.select = bind(this.select, this);
      var el, event, k, label, len1, len2, prev, q, ref, ref1;
      el = $.el('a', {
        className: 'qr-preview',
        draggable: true,
        href: 'javascript:;'
      });
      $.extend(el, {
        innerHTML: "<a class=\"remove fa fa-times-circle\" title=\"Remove\"></a><label class=\"qr-preview-spoiler\"><input type=\"checkbox\"> Spoiler</label><span></span>"
      });
      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) {
            return QR.nodes.spoiler.checked = _this.spoiler;
          }
        };
      })(this));
      ref = $$('label', el);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        label = ref[k];
        $.on(label, 'click', function(e) {
          return e.stopPropagation();
        });
      }
      $.add(QR.nodes.dumpList, el);
      ref1 = ['dragStart', 'dragEnter', 'dragLeave', 'dragOver', 'dragEnd', 'drop'];
      for (q = 0, len2 = ref1.length; q < len2; q++) {
        event = ref1[q];
        $.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.selected === _this) {
            return _this.load();
          }
        };
      })(this));
      if (select) {
        this.select();
      }
      this.unlock();
      $.queueTask(function() {
        return QR.captcha.onNewPost();
      });
    }

    _Class.prototype.rm = function() {
      var 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);
      return QR.status();
    };

    _Class.prototype["delete"] = function() {
      $.rm(this.nodes.el);
      URL.revokeObjectURL(this.URL);
      return this.dismissErrors();
    };

    _Class.prototype.lock = function(lock) {
      var k, len1, 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'];
      for (k = 0, len1 = ref.length; k < len1; k++) {
        name = ref[k];
        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 k, len1, name, node, ref;
      ref = ['thread', 'name', 'email', 'sub', 'com', 'filename'];
      for (k = 0, len1 = ref.length; k < len1; k++) {
        name = ref[k];
        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) {
      var name, ref;
      if (input.type === 'checkbox') {
        this.spoiler = input.checked;
        return;
      }
      name = input.dataset.name;
      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();
          return this.updateFlashURL();
        case 'com':
          this.updateComment();
          if (QR.cooldown.auto && this === QR.posts[0] && (0 < (ref = QR.cooldown.seconds) && ref <= 5)) {
            return QR.cooldown.auto = false;
          }
          break;
        case 'filename':
          if (!this.file) {
            return;
          }
          this.saveFilename();
          this.updateFilename();
          return this.updateFlashURL();
        case 'name':
          return QR.persona.set(this);
      }
    };

    _Class.prototype.forceSave = function() {
      var k, len1, name, node, ref;
      if (this !== QR.selected) {
        return;
      }
      ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler'];
      for (k = 0, len1 = ref.length; k < len1; k++) {
        name = ref[k];
        if (!(node = QR.nodes[name])) {
          continue;
        }
        this.save(node);
      }
    };

    _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;
      return $.queueTask(function() {
        return QR.captcha.onPostChange();
      });
    };

    _Class.rmErrored = function(e) {
      var error, errors, k, len1, post, q, ref;
      e.stopPropagation();
      ref = QR.posts;
      for (k = ref.length - 1; k >= 0; k += -1) {
        post = ref[k];
        if (errors = post.errors) {
          for (q = 0, len1 = errors.length; q < len1; q++) {
            error = errors[q];
            if (!(doc.contains(error))) {
              continue;
            }
            post.rm();
            break;
          }
        }
      }
    };

    _Class.prototype.error = function(className, message) {
      var div, ref, rm, rmAll;
      div = $.el('div', {
        className: className
      });
      $.extend(div, {
        innerHTML: E(message) + "<br>[<a href=\"javascript:;\">delete</a>] [<a href=\"javascript:;\">delete all</a>]"
      });
      (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) {
      return this.error('file-error', this.filename + ": " + message);
    };

    _Class.prototype.dismissErrors = function(test) {
      var error, k, len1, ref;
      if (test == null) {
        test = function() {
          return true;
        };
      }
      if (this.errors) {
        ref = this.errors;
        for (k = 0, len1 = ref.length; k < len1; k++) {
          error = ref[k];
          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() - Math.floor(Math.random() * 365 * $.DAY));
        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');
      $.queueTask(function() {
        return QR.captcha.onPostChange();
      });
      URL.revokeObjectURL(this.URL);
      this.saveFilename();
      if (this === QR.selected) {
        this.showFileData();
      } else {
        this.updateFilename();
      }
      this.updateFlashURL();
      this.nodes.el.style.backgroundImage = null;
      if (ref = this.file.type, indexOf.call(QR.mimeTypes, ref) < 0) {
        return this.fileError('Unsupported file type.');
      } else if (/^(image|video)\//.test(this.file.type)) {
        return this.readFile();
      }
    };

    _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);
          return _this.setThumbnail(el);
        };
      })(this);
      onerror = (function(_this) {
        return function() {
          $.off(el, event, onload);
          $.off(el, 'error', onerror);
          _this.fileError((isVideo ? 'Video' : 'Image') + " appears corrupt");
          return URL.revokeObjectURL(el.src);
        };
      })(this);
      $.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, ref, videoHeight, videoWidth, width;
      if (el.tagName === 'IMG') {
        height = el.height, width = el.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;
        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 (((ref = g.BOARD.ID) !== 'gif' && ref !== 'wsg') && $.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.nodes.el.style.backgroundImage = null;
      $.rmClass(this.nodes.el, 'has-file');
      this.showFileData();
      this.updateFlashURL();
      URL.revokeObjectURL(this.URL);
      return this.dismissErrors(function(error) {
        return $.hasClass(error, 'file-error');
      });
    };

    _Class.prototype.saveFilename = function() {
      this.file.newName = (this.filename || '').replace(/[\/\\]/g, '-');
      if (!QR.validExtension.test(this.filename)) {
        return this.file.newName += "." + (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.updateFlashURL = function() {
      var com, oldURL, ref, url;
      if (g.BOARD.ID !== 'f') {
        return;
      }
      if (this.thread === 'new' || !this.file) {
        url = '';
      } else {
        url = this.file.newName;
        if ((ref = $.engine) === 'blink' || ref === 'webkit') {
          url = url.replace(/"/g, '%22');
        }
        url = url.replace(/[\t\n\f\r \xa0\u200B\u2029\u3000]+/g, ' ').replace(/(^ | $)/g, '').replace(/\.[0-9A-Za-z]+$/, '');
        url = "https://i.4cdn.org/f/" + (encodeURIComponent(E(url))) + ".swf\n";
      }
      oldURL = this.flashURL || '';
      if (url !== oldURL) {
        com = this.com || '';
        if (com.slice(0, oldURL.length) === oldURL) {
          this.setComment(url + com.slice(oldURL.length));
        }
        return this.flashURL = url;
      }
    };

    _Class.prototype.pasteText = function(file) {
      var reader;
      this.pasting = true;
      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 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);
      (oldIndex < newIndex ? $.after : $.before)(this, el);
      post = QR.posts.splice(oldIndex, 1)[0];
      QR.posts.splice(newIndex, 0, post);
      return QR.status();
    };

    return _Class;

  })();

  FappeTyme = {
    init: function() {
      var el, k, lc, len1, ref, ref1, type;
      if (!((Conf['Fappe Tyme'] || Conf['Werk Tyme']) && ((ref = g.VIEW) === 'index' || ref === 'thread'))) {
        return;
      }
      this.nodes = {};
      this.enabled = {
        fappe: false,
        werk: Conf['werk']
      };
      ref1 = ["Fappe", "Werk"];
      for (k = 0, len1 = ref1.length; k < len1; k++) {
        type = ref1[k];
        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
        });
      }
      if (Conf['Werk Tyme']) {
        $.sync('werk', this.set.bind(this, 'werk'));
      }
      Post.callbacks.push({
        name: 'Fappe Tyme',
        cb: this.node
      });
      return CatalogThread.callbacks.push({
        name: 'Werk Tyme',
        cb: this.catalogNode
      });
    },
    node: function() {
      return this.nodes.root.classList.toggle('noFile', !this.file);
    },
    catalogNode: function() {
      var file, filename;
      file = this.thread.OP.file;
      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]);
      }
    }
  };

  Gallery = {
    init: function() {
      var el, ref;
      if (!(this.enabled = Conf['Gallery'] && ((ref = g.VIEW) === 'index' || ref === 'thread') && g.BOARD.ID !== 'f')) {
        return;
      }
      this.delay = Conf['Slide Delay'];
      el = $.el('a', {
        href: 'javascript:;',
        id: 'appchan-gal',
        title: 'Gallery',
        className: 'fa fa-picture-o',
        textContent: 'Gallery'
      });
      $.on(el, 'click', this.cb.toggle);
      Header.addShortcut(el);
      return Post.callbacks.push({
        name: 'Gallery',
        cb: this.node
      });
    },
    node: function() {
      var ref;
      if (!((ref = this.file) != null ? ref.thumb : void 0)) {
        return;
      }
      if (Gallery.nodes) {
        Gallery.generateThumb(this);
        Gallery.nodes.total.textContent = Gallery.images.length;
      }
      if (!Conf['Image Expansion']) {
        return $.on(this.file.thumb.parentNode, 'click', Gallery.cb.image);
      }
    },
    build: function(image) {
      var candidate, cb, dialog, entry, file, k, key, len1, len2, menuButton, nodes, post, q, 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.fullIDs = {};
      Gallery.slideshow = false;
      nodes.el = dialog = $.el('div', {
        id: 'a-gallery'
      });
      $.extend(dialog, {
        innerHTML: "<div class=\"gal-viewport\"><span class=\"gal-buttons\"><a href=\"javascript:;\" class=\"gal-start\" title=\"Start slideshow\"><i></i></a><a href=\"javascript:;\" class=\"gal-stop\" title=\"Stop slideshow\"><i></i></a><a href=\"javascript:;\" class=\"menu-button\"><i></i></a><a href=\"javascript:;\" class=\"gal-close\">×</a></span><a class=\"gal-name\" target=\"_blank\"></a><span class=\"gal-count\"><span class=\"count\"></span> / <span class=\"total\"></span></span><div class=\"gal-prev\"></div><div class=\"gal-image\"><a href=\"javascript:;\"><img></a></div><div class=\"gal-next\"></div></div><div class=\"gal-thumbnails\"></div>"
      });
      ref = {
        buttons: '.gal-buttons',
        frame: '.gal-image',
        name: '.gal-name',
        count: '.count',
        total: '.total',
        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 (k = 0, len1 = ref1.length; k < len1; k++) {
        entry = ref1[k];
        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 = $$('.post .file');
      for (q = 0, len2 = ref2.length; q < len2; q++) {
        file = ref2[q];
        post = Get.postFromNode(file);
        if (!((ref3 = post.file) != null ? ref3.thumb : void 0)) {
          continue;
        }
        Gallery.generateThumb(post);
        if (!image && Gallery.fullIDs[post.fullID]) {
          candidate = post.file.thumb.parentNode;
          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) {
      var thumb, thumbImg;
      if (post.isClone || post.isHidden) {
        return;
      }
      if (!(post.file && post.file.thumb && (post.file.isImage || post.file.isVideo || Conf['PDF in Gallery']))) {
        return;
      }
      if (Gallery.fullIDs[post.fullID]) {
        return;
      }
      Gallery.fullIDs[post.fullID] = true;
      thumb = $.el('a', {
        className: 'gal-thumb',
        href: post.file.url,
        target: '_blank',
        title: post.file.name
      });
      thumb.dataset.id = Gallery.images.length;
      thumb.dataset.post = post.fullID;
      thumbImg = post.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 = {
        'webm': 'video',
        'pdf': 'iframe'
      }[ext] || 'img';
      file = $.el(elType, {
        title: thumb.title
      });
      $.extend(file.dataset, thumb.dataset);
      $.on(file, 'error', errorCB);
      file.src = thumb.href;
      return file;
    },
    open: function(thumb) {
      var el, file, newID, nodes, oldID, post, ref;
      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();
      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[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 ref;
      if (((ref = this.error) != null ? ref.code : void 0) === MediaError.MEDIA_ERR_DECODE) {
        return new Notice('error', 'Corrupt or unplayable video', 30);
      }
      if (this.src.split('/')[2] !== 'i.4cdn.org') {
        return;
      }
      return ImageCommon.error(this, g.posts[this.dataset.post], 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 'Right':
              return Gallery.cb.next;
            case 'Enter':
              return Gallery.cb.advance;
            case 'Left':
            case '':
              return Gallery.cb.prev;
            case Conf['Pause']:
              return Gallery.cb.pause;
            case Conf['Slideshow']:
              return Gallery.cb.toggleSlideshow;
          }
        })();
        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']();
      },
      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;
      },
      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.fullIDs;
        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 current, dim, frame, height, minHeight, ref, ref1, ref2, style, width;
        ref = Gallery.nodes, current = ref.current, frame = ref.frame;
        style = current.style;
        if (Conf['Stretch to Fit'] && (dim = (ref1 = g.posts[current.dataset.post]) != null ? ref1.file.dimensions : void 0)) {
          ref2 = dim.split('x'), width = ref2[0], height = ref2[1];
          minHeight = Math.min(doc.clientHeight - 25, height / width * frame.clientWidth);
          style.minHeight = minHeight + 'px';
          return style.minWidth = (width / height * minHeight) + 'px';
        } else {
          return style.minHeight = style.minWidth = null;
        }
      }),
      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 k, len1, ref, results;
          ref = ['Hide Thumbnails', 'Fit Width', 'Fit Height', 'Stretch to Fit', 'Scroll to Post'];
          results = [];
          for (k = 0, len1 = ref.length; k < len1; k++) {
            item = ref[k];
            results.push(Gallery.menu.createSubEntry(item));
          }
          return results;
        })();
        delayLabel = $.el('label', {
          innerHTML: "Slide Delay: <input type=\"number\" name=\"Slide Delay\" min=\"0\" step=\"any\" class=\"field\">"
        });
        delayInput = delayLabel.firstElementChild;
        delayInput.value = Gallery.delay;
        $.on(delayInput, 'change', Gallery.cb.setDelay);
        $.on(delayInput, 'change', $.cb.value);
        subEntries.push({
          el: delayLabel
        });
        return subEntries;
      }
    }
  };

  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, post) {
      var message, ref;
      if (((ref = file.error) != null ? ref.code : void 0) !== MediaError.MEDIA_ERR_DECODE) {
        return false;
      }
      if (!(message = $('.warning', post.file.thumb.parentNode))) {
        message = $.el('div', {
          className: 'warning'
        });
        $.after(post.file.thumb, message);
      }
      message.textContent = 'Error: Corrupt or unplayable video';
      return true;
    },
    error: function(file, post, delay, cb) {
      var URL, redirect, src, timeoutID;
      src = post.file.url.split('/');
      URL = Redirect.to('file', {
        boardID: post.board.ID,
        filename: src[src.length - 1]
      });
      if (!(Conf['404 Redirect'] && URL && Redirect.securityCheck(URL))) {
        URL = null;
      }
      if ((post.isDead || post.file.isDead) && file.src.split('/')[2] === 'i.4cdn.org') {
        return cb(URL);
      }
      if (delay != null) {
        timeoutID = setTimeout((function() {
          return cb(URL);
        }), delay);
      }
      if (post.isDead || post.file.isDead) {
        return;
      }
      redirect = function() {
        if (file.src.split('/')[2] === 'i.4cdn.org') {
          if (delay != null) {
            clearTimeout(timeoutID);
          }
          return cb(URL);
        }
      };
      return $.ajax("//a.4cdn.org/" + post.board + "/thread/" + post.thread + ".json", {
        onload: function() {
          var k, len1, postObj, ref;
          if (this.status === 404) {
            post.kill();
          }
          if (this.status !== 200) {
            return redirect();
          }
          ref = this.response.posts;
          for (k = 0, len1 = ref.length; k < len1; k++) {
            postObj = ref[k];
            if (postObj.no === post.ID) {
              break;
            }
          }
          if (postObj.no !== post.ID) {
            post.kill();
            return redirect();
          } else if (postObj.filedeleted) {
            post.kill(true);
            return redirect();
          } else {
            return URL = post.file.url;
          }
        }
      });
    },
    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) {
      if (this.protocol === 'blob:') {
        return true;
      }
      e.preventDefault();
      return CrossOrigin.file(this.href, (function(_this) {
        return function(blob) {
          if (blob) {
            _this.href = URL.createObjectURL(blob);
            return _this.click();
          } else {
            return new Notice('error', "Could not download " + _this.href, 30);
          }
        };
      })(this));
    }
  };

  ImageExpand = {
    init: function() {
      var ref;
      if (!(this.enabled = Conf['Image Expansion'] && ((ref = g.VIEW) === 'index' || ref === 'thread') && g.BOARD.ID !== 'f')) {
        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(this.EAI, 3);
      $.on(d, 'scroll visibilitychange', this.cb.playVideos);
      this.videoControls = $.el('span', {
        className: 'video-controls'
      });
      $.extend(this.videoControls, {
        innerHTML: " <a href=\"javascript:;\" title=\"You can also contract the video by dragging it to the left.\">contract</a>"
      });
      return Post.callbacks.push({
        name: 'Image Expansion',
        cb: this.node
      });
    },
    node: function() {
      var ref;
      if (!(this.file && (this.file.isImage || this.file.isVideo))) {
        return;
      }
      $.on(this.file.thumb.parentNode, '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 (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
          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, toggle;
        $.event('CloseMenu');
        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)) {
            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 k, len1, ref;
          ref = [post].concat(slice.call(post.clones));
          for (k = 0, len1 = ref.length; k < len1; k++) {
            post = ref[k];
            toggle(post);
          }
        });
      },
      playVideos: function() {
        return g.posts.forEach(function(post) {
          var file, k, len1, ref, video, visible;
          ref = [post].concat(slice.call(post.clones));
          for (k = 0, len1 = ref.length; k < len1; k++) {
            post = ref[k];
            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, k, len1, 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.thumb.parentNode.href = file.url;
      file.thumb.parentNode.target = '_blank';
      ref = ['isExpanding', 'isExpanded', 'videoControls', 'wasPlaying', 'scrollIntoView'];
      for (k = 0, len1 = ref.length; k < len1; k++) {
        x = ref[k];
        delete file[x];
      }
      if (!el) {
        return;
      }
      if (doc.contains(el)) {
        if (bottom <= 0) {
          window.scroll(0, scrollY + d.body.clientHeight - oldHeight);
        } else {
          Header.scrollToIfNeeded(post.nodes.root);
        }
        if (window.scrollX > 0) {
          window.scroll(0, window.scrollY);
        }
      }
      $.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;
      file = post.file;
      thumb = file.thumb, 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.fullID : void 0) === post.fullID) {
        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.fullID = post.fullID;
        $.on(el, 'error', ImageExpand.error);
        el.src = src || file.url;
      }
      el.className = 'full-image';
      $.after(thumb, el);
      if (isVideo) {
        if (Conf['Show Controls'] && Conf['Click Passthrough'] && !file.videoControls) {
          file.videoControls = ImageExpand.videoControls.cloneNode(true);
          $.add(file.text, file.videoControls);
        }
        thumb.parentNode.removeAttribute('href');
        thumb.parentNode.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.scroll(window.scrollX, 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 (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)) {
        return ImageExpand.contract(post);
      }
      if (this.src.split('/')[2] !== 'i.4cdn.org') {
        return ImageExpand.contract(post);
      }
      return ImageCommon.error(this, post, 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
        };
      }
    }
  };

  ImageHover = {
    init: function() {
      var ref;
      if ((ref = g.VIEW) !== 'index' && ref !== 'thread') {
        return;
      }
      if (Conf['Image Hover']) {
        Post.callbacks.push({
          name: 'Image Hover',
          cb: this.node
        });
      }
      if (Conf['Image Hover in Catalog']) {
        return CatalogThread.callbacks.push({
          name: 'Image Hover',
          cb: this.catalogNode
        });
      }
    },
    node: function() {
      if (!(this.file && (this.file.isImage || this.file.isVideo))) {
        return;
      }
      return $.on(this.file.thumb, 'mouseover', ImageHover.mouseover(this));
    },
    catalogNode: function() {
      var file;
      file = this.thread.OP.file;
      if (!(file && (file.isImage || file.isVideo))) {
        return;
      }
      return $.on(this.nodes.thumb, 'mouseover', ImageHover.mouseover(this.thread.OP));
    },
    mouseover: function(post) {
      return function(e) {
        var el, error, file, height, isVideo, left, maxHeight, maxWidth, ref, ref1, ref2, right, scale, width, x;
        if (!doc.contains(this)) {
          return;
        }
        file = post.file;
        isVideo = file.isVideo;
        if (file.isExpanding || file.isExpanded) {
          return;
        }
        error = ImageHover.error(post);
        if (((ref = ImageCommon.cache) != null ? ref.dataset.fullID : void 0) === post.fullID) {
          el = ImageCommon.popCache();
          $.on(el, 'error', error);
        } else {
          el = $.el((isVideo ? 'video' : 'img'));
          el.dataset.fullID = post.fullID;
          $.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();
          }
        }
        ref1 = (function() {
          var k, len1, ref1, results;
          ref1 = file.dimensions.split('x');
          results = [];
          for (k = 0, len1 = ref1.length; k < len1; k++) {
            x = ref1[k];
            results.push(+x);
          }
          return results;
        })(), width = ref1[0], height = ref1[1];
        ref2 = this.getBoundingClientRect(), left = ref2.left, right = ref2.right;
        maxWidth = Math.max(left, doc.clientWidth - right);
        maxHeight = doc.clientHeight - UI.hover.padding;
        scale = Math.min(1, maxWidth / width, maxHeight / height);
        el.style.maxWidth = (scale * width) + "px";
        el.style.maxHeight = (scale * height) + "px";
        return UI.hover({
          root: this,
          el: el,
          latestEvent: e,
          endEvents: 'mouseout click',
          height: scale * height,
          noRemove: true,
          cb: function() {
            $.off(el, 'error', error);
            ImageCommon.pushCache(el);
            ImageCommon.pause(el);
            $.rm(el);
            return el.removeAttribute('style');
          }
        });
      };
    },
    error: function(post) {
      return function() {
        if (ImageCommon.decodeError(this, post)) {
          return;
        }
        return ImageCommon.error(this, post, 3 * $.SECOND, (function(_this) {
          return function(URL) {
            if (URL) {
              return _this.src = URL + (_this.src === URL ? '?' + Date.now() : '');
            } else {
              return $.rm(_this);
            }
          };
        })(this));
      };
    }
  };

  ImageLoader = {
    init: function() {
      var prefetch, ref;
      if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && g.BOARD.ID !== 'f')) {
        return;
      }
      if (!(Conf['Image Prefetching'] || Conf['Replace JPG'] || Conf['Replace PNG'] || Conf['Replace GIF'] || Conf['Replace WEBM'])) {
        return;
      }
      Post.callbacks.push({
        name: 'Image Replace',
        cb: this.node
      });
      $.on(d, 'PostsInserted', function() {
        return g.posts.forEach(ImageLoader.prefetch);
      });
      if (Conf['Replace WEBM']) {
        $.on(d, 'scroll visibilitychange 4chanXInitFinished PostsInserted', this.playVideos);
      }
      if (!Conf['Image Prefetching']) {
        return;
      }
      prefetch = $.el('label', {
        innerHTML: "<input type=\"checkbox\" name=\"prefetch\"> Prefetch Images"
      });
      this.el = prefetch.firstElementChild;
      $.on(this.el, 'change', this.toggle);
      return Header.menu.addEntry({
        el: prefetch,
        order: 98
      });
    },
    node: function() {
      if (this.isClone || !this.file) {
        return;
      }
      if (Conf['Replace WEBM'] && this.file.isVideo) {
        ImageLoader.replaceVideo(this);
      }
      return ImageLoader.prefetch(this);
    },
    replaceVideo: function(post) {
      var attr, file, k, len1, ref, thumb, video;
      file = post.file;
      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 (k = 0, len1 = ref.length; k < len1; k++) {
        attr = ref[k];
        video.style[attr] = thumb.style[attr];
      }
      video.src = file.url;
      $.replace(thumb, video);
      file.thumb = video;
      return file.videoThumb = true;
    },
    prefetch: function(post) {
      var clone, el, file, isImage, isVideo, k, len1, match, ref, replace, thumb, type, url;
      file = post.file;
      if (!file) {
        return;
      }
      isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, url = file.url;
      if (file.isPrefetched || !(isImage || isVideo) || post.isHidden || post.thread.isHidden) {
        return;
      }
      type = (match = url.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match;
      replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src || thumb.dataset.src);
      if (!(replace || Conf['prefetch'])) {
        return;
      }
      if (![post].concat(slice.call(post.clones)).some(function(clone) {
        return doc.contains(clone.nodes.root);
      })) {
        return;
      }
      file.isPrefetched = true;
      if (file.videoThumb) {
        ref = post.clones;
        for (k = 0, len1 = ref.length; k < len1; k++) {
          clone = ref[k];
          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 (replace && isImage) {
        $.on(el, 'load', function() {
          var len2, q, ref1;
          ref1 = post.clones;
          for (q = 0, len2 = ref1.length; q < len2; q++) {
            clone = ref1[q];
            clone.file.thumb.src = url;
          }
          thumb.src = url;
          return thumb.removeAttribute('data-src');
        });
      }
      return el.src = url;
    },
    toggle: function() {
      if (Conf['prefetch'] = this.checked) {
        g.posts.forEach(ImageLoader.prefetch);
      }
    },
    playVideos: function() {
      var qpClone, ref;
      qpClone = (ref = $.id('qp')) != null ? ref.firstElementChild : void 0;
      return g.posts.forEach(function(post) {
        var k, len1, ref1, ref2, thumb;
        ref1 = [post].concat(slice.call(post.clones));
        for (k = 0, len1 = ref1.length; k < len1; k++) {
          post = ref1[k];
          if (!((ref2 = post.file) != null ? ref2.videoThumb : void 0)) {
            continue;
          }
          thumb = post.file.thumb;
          if (Header.isNodeVisible(thumb) || post.nodes.root === qpClone) {
            thumb.play();
          } else {
            thumb.pause();
          }
        }
      });
    }
  };

  Metadata = {
    init: function() {
      var ref;
      if (!(Conf['WEBM Metadata'] && ((ref = g.VIEW) === 'index' || ref === 'thread') && g.BOARD.ID !== 'f')) {
        return;
      }
      return Post.callbacks.push({
        name: 'WEBM Metadata',
        cb: this.node
      });
    },
    node: function() {
      var el;
      if (!(this.file && /webm$/i.test(this.file.url))) {
        return;
      }
      if (this.isClone) {
        el = $('.webm-title', this.file.text);
      } else {
        el = $.el('span', {
          className: 'webm-title'
        });
        $.extend(el, {
          innerHTML: "<a href=\"javascript:;\"></a>"
        });
        $.add(this.file.text, [$.tn('\u00A0'), el]);
      }
      if (el.children.length === 1) {
        return $.one(el.lastElementChild, 'mouseover focus', Metadata.load);
      }
    },
    load: function() {
      $.rmClass(this.parentNode, 'error');
      $.addClass(this.parentNode, 'loading');
      return CrossOrigin.binary(Get.postFromNode(this).file.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;
    }
  };

  RevealSpoilers = {
    init: function() {
      var ref;
      if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Reveal Spoiler Thumbnails'])) {
        return;
      }
      return Post.callbacks.push({
        name: 'Reveal Spoiler Thumbnails',
        cb: this.node
      });
    },
    node: function() {
      var thumb;
      if (!(!this.isClone && this.file && this.file.thumb && this.file.isSpoiler)) {
        return;
      }
      thumb = this.file.thumb;
      thumb.removeAttribute('style');
      thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px';
      if (thumb.src) {
        return thumb.src = this.file.thumbURL;
      } else {
        return thumb.dataset.src = this.file.thumbURL;
      }
    }
  };

  Sauce = {
    init: function() {
      var err, k, len1, link, links, ref, ref1;
      if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Sauce'])) {
        return;
      }
      links = [];
      ref1 = Conf['sauces'].split('\n');
      for (k = 0, len1 = ref1.length; k < len1; k++) {
        link = ref1[k];
        try {
          if (link[0] !== '#') {
            links.push(link.trim());
          }
        } catch (_error) {
          err = _error;
        }
      }
      if (!links.length) {
        return;
      }
      this.links = links;
      this.link = $.el('a', {
        target: '_blank',
        className: 'sauce'
      });
      return Post.callbacks.push({
        name: 'Sauce',
        cb: this.node
      });
    },
    sandbox: function(url) {
      return E.url({
        innerHTML: "<html><head><title>[sb] " + E(url) + "</title><style>iframe {width: 100vw;height: 100vh;border: 0;}body {margin: 0;overflow: hidden;}</style></head><body><iframe sandbox=\"allow-forms\" src=\"" + E(url) + "\"></iframe></body></html>"
      });
    },
    rmOrigin: function(e) {
      if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
        return;
      }
      $.open(this.href);
      return e.preventDefault();
    },
    createSauceLink: function(link, post) {
      var a, ext, i, k, key, len1, m, part, parts, ref, ref1, ref2, skip, url;
      if (!(link = link.trim())) {
        return null;
      }
      parts = {};
      ref = link.split(/;(?=(?:text|boards|types|sandbox):?)/);
      for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
        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) || '?');
      ext = post.file.url.match(/[^.]*$/)[0];
      skip = false;
      for (key in parts) {
        parts[key] = parts[key].replace(/%(T?URL|IMG|[sh]?MD5|board|name|%|semi)/g, function(_, parameter) {
          var type;
          type = Sauce.formatters[parameter](post, ext);
          if (type == null) {
            skip = true;
            return '';
          }
          if (key === 'url' && (parameter !== '%' && parameter !== 'semi')) {
            if (/^javascript:/i.test(parts['url'])) {
              type = JSON.stringify(type);
            }
            type = encodeURIComponent(type);
          }
          return type;
        });
      }
      if (skip) {
        return null;
      }
      if (!(!parts['boards'] || (ref2 = post.board.ID, indexOf.call(parts['boards'].split(','), ref2) >= 0))) {
        return null;
      }
      if (!(!parts['types'] || indexOf.call(parts['types'].split(','), ext) >= 0)) {
        return null;
      }
      url = parts['url'];
      if (parts['sandbox'] != null) {
        url = Sauce.sandbox(url);
      }
      a = Sauce.link.cloneNode(true);
      a.href = url;
      a.textContent = parts['text'];
      if (/^javascript:/i.test(parts['url'])) {
        a.removeAttribute('target');
      }
      if (parts['sandbox'] != null) {
        $.on(a, 'click', Sauce.rmOrigin);
      }
      return a;
    },
    node: function() {
      var k, len1, link, node, nodes, ref;
      if (this.isClone || !this.file) {
        return;
      }
      nodes = [];
      ref = Sauce.links;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        link = ref[k];
        if (node = Sauce.createSauceLink(link, this)) {
          nodes.push($.tn('\u00A0'), node);
        }
      }
      return $.add(this.file.text, nodes);
    },
    formatters: {
      TURL: function(post) {
        return post.file.thumbURL;
      },
      URL: function(post) {
        return post.file.url;
      },
      IMG: function(post, ext) {
        if (ext === 'gif' || ext === 'jpg' || ext === 'png') {
          return post.file.url;
        } else {
          return post.file.thumbURL;
        }
      },
      MD5: function(post) {
        return post.file.MD5;
      },
      sMD5: function(post) {
        var ref;
        return (ref = post.file.MD5) != null ? ref.replace(/[+\/=]/g, function(c) {
          return {
            '+': '-',
            '/': '_',
            '=': ''
          }[c];
        }) : void 0;
      },
      hMD5: function(post) {
        if (post.file.MD5) {
          return ((function() {
            var k, len1, ref, results;
            ref = atob(post.file.MD5);
            results = [];
            for (k = 0, len1 = ref.length; k < len1; k++) {
              c = ref[k];
              results.push(("0" + (c.charCodeAt(0).toString(16))).slice(-2));
            }
            return results;
          })()).join('');
        }
      },
      board: function(post) {
        return post.board.ID;
      },
      name: function(post) {
        return post.file.name;
      },
      '%': function() {
        return '%';
      },
      semi: function() {
        return ';';
      }
    }
  };

  Volume = {
    init: function() {
      var ref, ref1, 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']) {
        Post.callbacks.push({
          name: 'Mouse Wheel Volume',
          cb: this.node
        });
      }
      if ((ref1 = g.BOARD.ID) !== 'gif' && ref1 !== 'wsg') {
        return;
      }
      if (Conf['Mouse Wheel Volume']) {
        CatalogThread.callbacks.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: "<input name=\"Default Volume\" type=\"range\" min=\"0\" max=\"1\" step=\"0.01\" value=\"" + E(Conf["Default Volume"]) + "\"> 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, val, volume;
      muted = this.muted, volume = this.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 ref, ref1;
      if (!(((ref = this.board.ID) === 'gif' || ref === 'wsg') && ((ref1 = this.file) != null ? ref1.isVideo : void 0))) {
        return;
      }
      $.on(this.file.thumb, 'wheel', Volume.wheel.bind(Header.hover));
      return $.on($('a', this.file.text), 'wheel', Volume.wheel.bind(this.file.thumb.parentNode));
    },
    catalogNode: function() {
      var file;
      file = this.thread.OP.file;
      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();
    }
  };

  Embedding = {
    init: function() {
      var k, len1, ref, type;
      if (!(Conf['Embedding'] || Conf['Link Title'])) {
        return;
      }
      this.types = {};
      ref = this.ordered_types;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        type = ref[k];
        this.types[type.key] = type;
      }
      if (Conf['Floating Embeds']) {
        this.dialog = UI.dialog('embedding', 'top: 50px; right: 0px;', {
          innerHTML: "<div><div class=\"move\"></div><a href=\"javascript:;\" class=\"jump\" title=\"Jump to post\">→</a><a href=\"javascript:;\" class=\"close\" title=\"Close\">×</a></div><div id=\"media-embed\"><div></div></div>"
        });
        this.media = $('#media-embed', this.dialog);
        $.one(d, '4chanXInitFinished', this.ready);
      }
      if (Conf['Link Title']) {
        return $.on(d, '4chanXInitFinished PostsInserted', function() {
          var key, ref1, ref2, service;
          ref1 = Embedding.types;
          for (key in ref1) {
            service = ref1[key];
            if ((ref2 = service.title) != null ? ref2.batchSize : void 0) {
              Embedding.flushTitles(service.title);
            }
          }
        });
      }
    },
    events: function(post) {
      var el, i, items;
      if (!Conf['Embedding']) {
        return;
      }
      i = 0;
      items = $$('.embedder', post.nodes.comment);
      while (el = items[i++]) {
        $.on(el, 'click', Embedding.cb.toggle);
        if ($.hasClass(el, 'embedded')) {
          Embedding.cb.toggle.call(el);
        }
      }
    },
    process: function(link, post) {
      var data;
      if (!(Conf['Embedding'] || Conf['Link Title'])) {
        return;
      }
      if ($.x('ancestor::pre', link)) {
        return;
      }
      if (data = Embedding.services(link)) {
        data.post = post;
        if (Conf['Embedding']) {
          Embedding.embed(data);
        }
        if (Conf['Link Title']) {
          return Embedding.title(data);
        }
      }
    },
    services: function(link) {
      var href, k, len1, match, ref, type;
      href = link.href;
      ref = Embedding.ordered_types;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        type = ref[k];
        if (!(match = type.regExp.exec(href))) {
          continue;
        }
        if (type.dummy) {
          return;
        }
        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;
      if (Embedding.types[key].httpOnly && location.protocol !== 'http:') {
        return;
      }
      $.addClass(link, key.toLowerCase());
      embed = $.el('a', {
        className: 'embedder',
        href: 'javascript:;',
        textContent: '(embed)'
      });
      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.toggle);
      $.after(link, [$.tn(' '), embed]);
      if (Conf['Auto-embed'] && !Conf['Floating Embeds'] && !post.isFetchedQuote && key !== 'TwitchTV') {
        return $.asap((function() {
          return doc.contains(embed);
        }), function() {
          return Embedding.cb.toggle.call(embed);
        });
      }
    },
    ready: function() {
      $.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.visibility = '';
        return;
      }
      $.on(d, 'mouseup', Embedding.dragEmbed);
      Embedding.dragEmbed.mouseup = true;
      return style.visibility = 'hidden';
    },
    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 {
        if (!$.cache(service.api(uid), (function() {
          return Embedding.cb.title(this, data);
        }), {
          responseType: 'json'
        })) {
          return $.extend(link, {
            innerHTML: "[" + E(key) + "] <span class=\"warning\">Title Link Blocked</span> (are you using NoScript?)</a>"
          });
        }
      }
    },
    flushTitles: function(service) {
      var cb, data, k, len1, queue;
      queue = service.queue;
      if (!(queue != null ? queue.length : void 0)) {
        return;
      }
      service.queue = [];
      cb = function() {
        var data, k, len1;
        for (k = 0, len1 = queue.length; k < len1; k++) {
          data = queue[k];
          Embedding.cb.title(this, data);
        }
      };
      if (!$.cache(service.api((function() {
        var k, len1, results;
        results = [];
        for (k = 0, len1 = queue.length; k < len1; k++) {
          data = queue[k];
          results.push(data.uid);
        }
        return results;
      })()), cb, {
        responseType: 'json'
      })) {
        for (k = 0, len1 = queue.length; k < len1; k++) {
          data = queue[k];
          $.extend(data.link, {
            innerHTML: "[" + E(data.key) + "] <span class=\"warning\">Title Link Blocked</span> (are you using NoScript?)</a>"
          });
        }
      }
    },
    cb: {
      toggle: function(e) {
        var div;
        if (e != null) {
          e.preventDefault();
        }
        if (Conf['Floating Embeds']) {
          if (!(div = Embedding.media.firstChild)) {
            return;
          }
          $.replace(div, Embedding.cb.embed(this));
          Embedding.lastEmbed = Get.postFromNode(this).nodes.root;
          $.rmClass(Embedding.dialog, 'empty');
          return;
        }
        if ($.hasClass(this, "embedded")) {
          $.rm(this.nextElementSibling);
          this.textContent = '(embed)';
        } else {
          $.after(this, Embedding.cb.embed(this));
          this.textContent = '(unembed)';
        }
        return $.toggleClass(this, 'embedded');
      },
      embed: function(a) {
        var container, el, type;
        container = $.el('div');
        $.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;
      },
      title: function(req, data) {
        var base1, k, key, len1, len2, link, link2, options, post, post2, q, ref, ref1, service, status, text, uid;
        key = data.key, uid = data.uid, options = data.options, link = data.link, post = data.post;
        status = req.status;
        service = Embedding.types[key].title;
        text = "[" + key + "] " + ((function() {
          switch (status) {
            case 200:
            case 304:
              return service.text(req.response, uid);
            case 404:
              return "Not Found";
            case 403:
              return "Forbidden or Private";
            default:
              return status + "'d";
          }
        })());
        link.dataset.original = link.textContent;
        link.textContent = text;
        ref = post.clones;
        for (k = 0, len1 = ref.length; k < len1; k++) {
          post2 = ref[k];
          ref1 = $$('a.linkify', post2.nodes.comment);
          for (q = 0, len2 = ref1.length; q < len2; q++) {
            link2 = ref1[q];
            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|ogg|wav)(?:\?|$)/i,
        style: '',
        el: function(a) {
          return $.el('audio', {
            controls: true,
            preload: 'auto',
            src: a.dataset.href
          });
        }
      }, {
        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;
          }
        }
      }, {
        key: 'Gist',
        regExp: /^\w+:\/\/gist\.github\.com\/(?:[\w\-]+\/)?(\w+)/,
        el: function(a) {
          var content, el;
          el = $.el('iframe');
          el.setAttribute('sandbox', 'allow-scripts');
          content = {
            innerHTML: "<html><head><title>" + E(a.dataset.uid) + "</title></head><body><script src=\"https://gist.github.com/" + E(a.dataset.uid) + ".js\"></script></body></html>"
          };
          el.src = E.url(content);
          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: 'image',
        regExp: /\.(?:gif|png|jpg|jpeg|bmp)(?:\?|$)/i,
        style: '',
        el: function(a) {
          return $.el('div', {
            innerHTML: "<a target=\"_blank\" href=\"" + E(a.dataset.href) + "\"><img src=\"" + E(a.dataset.href) + "\" style=\"max-width: 80vw; max-height: 80vh;\"></a>"
          });
        }
      }, {
        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: 'Twitter',
        regExp: /^\w+:\/\/(?:www\.)?twitter\.com\/(\w+\/status\/\d+)/,
        el: function(a) {
          return $.el('iframe', {
            src: "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid
          });
        }
      }, {
        key: 'LiveLeak',
        regExp: /^\w+:\/\/(?:\w+\.)?liveleak\.com\/.*\?.*i=(\w+)/,
        httpOnly: true,
        el: function(a) {
          var el;
          el = $.el('iframe', {
            src: "http://www.liveleak.com/ll_embed?i=" + a.dataset.uid
          });
          el.setAttribute("allowfullscreen", "true");
          return el;
        }
      }, {
        key: 'Pastebin',
        regExp: /^\w+:\/\/(?:\w+\.)?pastebin\.com\/(?!u\/)(?:[\w\.]+\?i\=)?(\w+)/,
        httpOnly: true,
        el: function(a) {
          var div;
          return div = $.el('iframe', {
            src: "http://pastebin.com/embed_iframe.php?i=" + a.dataset.uid
          });
        }
      }, {
        key: 'Gfycat',
        regExp: /^\w+:\/\/(?:www\.)?gfycat\.com\/(?:iframe\/)?(\w+)/,
        el: function(a) {
          var div;
          return div = $.el('iframe', {
            src: "//gfycat.com/iframe/" + 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 "//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: "//strawpoll.me/embed_1/" + a.dataset.uid
          });
        }
      }, {
        key: 'TwitchTV',
        regExp: /^\w+:\/\/(?:www\.)?twitch\.tv\/(\w[^#\&\?]*)/,
        style: "border: none; width: 620px; height: 378px;",
        el: function(a) {
          var _, channel, flashvars, id, idprefix, k, len1, obj, part, ref, result, seconds, start, type;
          if (result = /(\w+)\/([bcv])\/(\d+)/i.exec(a.dataset.uid)) {
            _ = result[0], channel = result[1], type = result[2], id = result[3];
            idprefix = type === 'b' ? 'a' : type;
            flashvars = "channel=" + channel + "&start_volume=25&auto_play=false&videoId=" + idprefix + id;
            if (start = a.dataset.href.match(/\bt=(\w+)/)) {
              seconds = 0;
              ref = start[1].match(/\d+[hms]/g);
              for (k = 0, len1 = ref.length; k < len1; k++) {
                part = ref[k];
                seconds += +part.slice(0, -1) * {
                  'h': 3600,
                  'm': 60,
                  's': 1
                }[part.slice(-1)];
              }
              flashvars += "&initial_time=" + seconds;
            }
          } else {
            channel = (/(\w+)/.exec(a.dataset.uid))[0];
            flashvars = "channel=" + channel + "&start_volume=25&auto_play=false";
          }
          obj = $.el('object', {
            data: '//www-cdn.jtvnw.net/swflibs/TwitchPlayer.swf'
          });
          $.extend(obj, {
            innerHTML: "<param name=\"allowFullScreen\" value=\"true\"><param name=\"flashvars\">"
          });
          obj.children[1].value = flashvars;
          return obj;
        }
      }, {
        key: 'Vocaroo',
        regExp: /^\w+:\/\/(?:www\.)?vocaroo\.com\/i\/(\w+)/,
        style: '',
        el: function(a) {
          var el, type;
          el = $.el('audio', {
            controls: true,
            preload: 'auto'
          });
          type = el.canPlayType('audio/webm') ? 'webm' : 'mp3';
          el.src = "http://vocaroo.com/media_command.php?media=" + a.dataset.uid + "&command=download_" + type;
          return el;
        }
      }, {
        key: 'Vimeo',
        regExp: /^\w+:\/\/(?:www\.)?vimeo\.com\/(\d+)/,
        el: function(a) {
          return $.el('iframe', {
            src: "//player.vimeo.com/video/" + a.dataset.uid + "?wmode=opaque"
          });
        },
        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: '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 + "?wmode=opaque" + (start ? '&start=' + start : '')
          });
          el.setAttribute("allowfullscreen", "true");
          return el;
        },
        title: {
          batchSize: 50,
          api: function(uids) {
            var ids, key;
            ids = encodeURIComponent(uids.join(','));
            key = 'AIzaSyB5_zaen_-46Uhz1xGR-lz1YoUMHqCD6CE';
            return "https://www.googleapis.com/youtube/v3/videos?part=snippet&id=" + ids + "&fields=items%28id%2Csnippet%28title%29%29&key=" + key;
          },
          text: function(data, uid) {
            var item, k, len1, ref;
            ref = data.items;
            for (k = 0, len1 = ref.length; k < len1; k++) {
              item = ref[k];
              if (item.id === uid) {
                return item.snippet.title;
              }
            }
            return 'Not Found';
          }
        }
      }, {
        key: 'Loopvid',
        regExp: /^\w+:\/\/(?:www\.)?loopvid.appspot.com\/#?((?:pf|kd|lv|gd|gh|db|dx|nn|cp|wu|ig|ky|mf|pc|gc)\/[\w\-\/]+(,[\w\-\/]+)*|fc\/\w+\/\d+)/,
        style: 'max-width: 80vw; max-height: 80vh;',
        el: function(a) {
          var _, base, el, host, k, len1, len2, name, names, q, ref, ref1, type, types, url;
          el = $.el('video', {
            controls: true,
            preload: 'auto',
            loop: true
          });
          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 (k = 0, len1 = ref1.length; k < len1; k++) {
            name = ref1[k];
            for (q = 0, len2 = types.length; q < len2; q++) {
              type = types[q];
              base = "" + name + type;
              url = (function() {
                switch (host) {
                  case 'pf':
                    return "https://web.archive.org/web/2/http://a.pomf.se/" + base;
                  case 'kd':
                    return "http://kastden.org/loopvid/" + base;
                  case 'lv':
                    return "http://kastden.org/_loopvid_media/lv/" + 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 "http://naenara.eu/loopvids/" + 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://kiyo.me/" + base;
                  case 'mf':
                    return "https://d.maxfile.ro/" + base;
                  case 'pc':
                    return "http://a.pomf.cat/" + base;
                  case 'fc':
                    return "//i.4cdn.org/" + base + ".webm";
                  case 'gc':
                    return "https://" + type + ".gfycat.com/" + name + ".webm";
                }
              })();
              $.add(el, $.el('source', {
                src: url
              }));
            }
          }
          return el;
        }
      }, {
        key: 'Clyp',
        regExp: /^\w+:\/\/(?:www\.)?clyp\.it\/(\w+)/,
        style: '',
        el: function(a) {
          var el, type;
          el = $.el('audio', {
            controls: true,
            preload: 'auto'
          });
          type = el.canPlayType('audio/ogg') ? 'ogg' : 'mp3';
          el.src = "https://clyp.it/" + a.dataset.uid + "." + type;
          return el;
        }
      }, {
        key: 'Loopvid-dummy',
        regExp: /^\w+:\/\/(?:www\.)?loopvid.appspot.com\//,
        dummy: true
      }, {
        key: 'MediaFire-dummy',
        regExp: /^\w+:\/\/(?:www\.)?mediafire.com\//,
        dummy: true
      }, {
        key: 'video',
        regExp: /\.(?:ogv|webm|mp4)(?:\?|$)/i,
        style: 'max-width: 80vw; max-height: 80vh;',
        el: function(a) {
          return $.el('video', {
            controls: true,
            preload: 'auto',
            src: a.dataset.href,
            loop: /^https?:\/\/i\.4cdn\.org\//.test(a.dataset.href)
          });
        }
      }
    ]
  };

  Linkify = {
    init: function() {
      var ref;
      if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['Linkify']) {
        return;
      }
      if (Conf['Comment Expansion']) {
        ExpandComment.callbacks.push(this.node);
      }
      Post.callbacks.push({
        name: 'Linkify',
        cb: this.node
      });
      CatalogThread.callbacks.push({
        name: 'Linkify',
        cb: this.catalogNode
      });
      return Embedding.init();
    },
    node: function() {
      var k, len1, len2, link, links, q, ref;
      if (this.isClone) {
        return Embedding.events(this);
      }
      if (!Linkify.regString.test(this.info.comment)) {
        return;
      }
      ref = $$('a[href^="http://i.4cdn.org/"], a[href^="https://i.4cdn.org/"]', this.nodes.comment);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        link = ref[k];
        $.addClass(link, 'linkify');
        Embedding.process(link, this);
      }
      links = Linkify.process(this.nodes.comment);
      for (q = 0, len2 = links.length; q < len2; q++) {
        link = links[q];
        Embedding.process(link, this);
      }
    },
    catalogNode: function() {
      if (!Linkify.regString.test(this.thread.OP.info.comment)) {
        return;
      }
      return Linkify.process(this.nodes.comment);
    },
    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') {
                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;
                }
              }
              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: 'nofollow noreferrer',
        target: '_blank',
        href: text
      });
      $.add(a, range.extractContents());
      range.insertNode(a);
      return a;
    }
  };

  ArchiveLink = {
    init: function() {
      var div, entry, k, len1, ref, ref1, type;
      if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Menu'] && Conf['Archive Link'])) {
        return;
      }
      div = $.el('div', {
        textContent: 'Archive'
      });
      entry = {
        el: div,
        order: 90,
        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'], ['Filename', 'filename'], ['Image MD5', 'MD5']];
      for (k = 0, len1 = ref1.length; k < len1; k++) {
        type = ref1[k];
        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 value;
        value = Filter[type](post);
        if (!value) {
          return false;
        }
        el.href = Redirect.to('search', {
          boardID: post.board.ID,
          type: type,
          value: value,
          isSearch: true
        });
        return true;
      };
      return {
        el: el,
        open: open
      };
    }
  };

  DeleteLink = {
    auto: [{}, {}],
    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,
        onload: function() {
          return DeleteLink.load(link, post, fileOnly, this.response);
        },
        onerror: function() {
          return DeleteLink.error(link, post);
        }
      }, {
        form: $.formData(form)
      });
    },
    load: function(link, post, fileOnly, resDoc) {
      var el, msg;
      link.textContent = DeleteLink.linkText(fileOnly);
      if (resDoc.title === '4chan - Banned') {
        el = $.el('span', {
          innerHTML: "You can&#039;t delete posts because you are <a href=\"//www.4chan.org/banned\" target=\"_blank\">banned</a>."
        });
        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';
        }
      }
    },
    error: function(link, post) {
      new Notice('warning', 'Connection error, please retry.', 20);
      if (post.fullID === DeleteLink.post.fullID) {
        return $.on(link, 'click', DeleteLink.toggle);
      }
    },
    cooldown: {
      seconds: {},
      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, k, len1, 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 (k = 0, len1 = ref.length; k < len1; k++) {
            fileOnly = ref[k];
            if (DeleteLink.auto[+fileOnly][post.fullID]) {
              DeleteLink["delete"](post, fileOnly);
            }
          }
        }
      }
    }
  };

  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;
        }
      });
    }
  };

  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: "<i class=\"fa fa-angle-down\"></i>"
      });
      this.menu = new UI.Menu('post');
      Post.callbacks.push({
        name: 'Menu',
        cb: this.node
      });
      return CatalogThread.callbacks.push({
        name: 'Menu',
        cb: this.catalogNode
      });
    },
    node: function() {
      if (this.isClone) {
        Menu.makeButton(this, $('.menu-button', this.nodes.info));
        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;
    }
  };

  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:;'
      });
      $.on(a, 'click', ReportLink.report);
      return Menu.menu.addEntry({
        el: a,
        order: 10,
        open: function(post) {
          if (!(post.isDead || (post.thread.isDead && !post.thread.isArchived))) {
            a.textContent = 'Report';
            ReportLink.url = "//sys.4chan.org/" + post.board + "/imgboard.php?mode=report&no=" + post;
            if ((Conf['Use Recaptcha v1 in Reports'] && Main.jsEnabled) || d.cookie.indexOf('pass_enabled=1') >= 0) {
              ReportLink.url += '&altc=1';
              ReportLink.dims = 'width=350,height=275';
            } else {
              ReportLink.dims = 'width=400,height=550';
            }
          } else if (Conf['Archive Report']) {
            a.textContent = 'Report to archive';
            ReportLink.url = Redirect.to('report', {
              boardID: post.board.ID,
              postID: post.ID
            });
            ReportLink.dims = 'width=700,height=475';
          } else {
            ReportLink.url = '';
          }
          return !!ReportLink.url;
        }
      });
    },
    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);
    }
  };

  Favicon = {
    init: function() {
      return $.asap((function() {
        return d.head && (Favicon.el = $('link[rel="shortcut icon"]', d.head));
      }), Favicon.initAsap);
    },
    initAsap: function() {
      var href;
      Favicon.el.type = 'image/x-icon';
      href = Favicon.el.href;
      Favicon.SFW = /ws\.ico$/.test(href);
      Favicon["default"] = href;
      return Favicon["switch"]();
    },
    "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-': ['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'],
        Mayhem: ['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'],
        '4chanJS': ['iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAD/AABnZ2f///8nFk05AAAAAXRSTlMAQObYZgAAAEFJREFUeNqNjgEKACAMAjvX/98cAkkxgmSgO8Bt/Ai4ApJ6KKhzF3OiEMDASrGB/QWgPEHsUpN+Ng9xAETMYhDrWmeHAMcmvycWAAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAD/AAD///9nZ2f77Y6hAAAAAXRSTlMAQObYZgAAAEBJREFUeF6NjQEKACAMAnfW/98cAxFiBIngOsTqR8B1IGkeG9p5i7XabgAGZNigXgA8aoCUxvzWAIcBItGiSEwdccYA3BuRAWkAAAAASUVORK5CYII=', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAAul8NnZ2f////82iC9AAAAAXRSTlMAQObYZgAAAEFJREFUeNqNjgEKACAMAjvX/98cAkkxgmSgO8Bt/Ai4ApJ6KKhzF3OiEMDASrGB/QWgPEHsUpN+Ng9xAETMYhDrWmeHAMcmvycWAAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAD1BMVEUBAAAAAAAul8P///9nZ2cgIeMlAAAAAXRSTlMAQObYZgAAAEBJREFUeF6NjQEKACAMAnfW/98cAxFiBIngOsTqR8B1IGkeG9p5i7XabgAGZNigXgA8aoCUxvzWAIcBItGiSEwdccYA3BuRAWkAAAAASUVORK5CYII=', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAElBMVEUBAAAAAABmzDNlyjJnZ2f///+6o7dfAAAAAXRSTlMAQObYZgAAAERJREFUeF6NjkEKADEIA51o///lJZfQxUsHITogWi8AvwZJuxmYa25xDooBLEwOWFTYAsYVhdorLZt9Ng9xCUTCUCQ2H3F4ANrZ2WNiAAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAElBMVEUBAAAAAABmzDP///9lyjJnZ2cIHys9AAAAAXRSTlMAQObYZgAAAENJREFUeF6NjUEKwEAMAjNm9/9fLkEslFwqgjoEUn8EfAqSdrkwzj6ieyyTkQEVGWRvANfO1iEX620AjgBEwqR4Y+sBeGAA6d+vQ4IAAAAASUVORK5CYII='],
        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==', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAAHAAAdAAApAAAsAAA4AABsAACQAAC/AAD///9SVhtjAAAAA3RSTlMAPse+s4iwAAAAM0lEQVQIW2NggAGuVasWgDBpDDAQUoSaob0Jao73lgVojOitUEazBZRRvR3KmJa5AO4KAGBtLuMAuhIIAAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAAA1/GhpCidAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAAACAkAISUALzQAMTcAQEcAeokAorYA1/H///8BrzTFAAAAA3RSTlMAPse+s4iwAAAAM0lEQVQIW2NggAGuVasWgDBpDDAQUoSaob0Jao73lgVojOitUEazBZRRvR3KmJa5AO4KAGBtLuMAuhIIAAAAAElFTkSuQmCC', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAABV/wErM5hwAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==', 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAADCgANKAASOAATOwAZTAAwkQBAwQBV/wH////+Fmy4AAAAA3RSTlMAPse+s4iwAAAAM0lEQVQIW2NggAGuVasWgDBpDDAQUoSaob0Jao73lgVojOitUEazBZRRvR3KmJa5AO4KAGBtLuMAuhIIAAAAAElFTkSuQmCC']
      }[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.SFW) {
        this.unread = this.unreadSFW;
        return this.unreadY = this.unreadSFWY;
      } else {
        this.unread = this.unreadNSFW;
        return this.unreadY = this.unreadNSFWY;
      }
    },
    dead: 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==',
    logo: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAgMAAAC+UIlYAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAGlJREFUWMPtlkEKADEIA/tJP9lXLttQto2yHxgDHozTi0ToGK2WKZZ+HAQQMZc+xBwI4EZ+wAC2IfPuSIDOZJrSZQEAX9eVJhhwIuUYAnQe8rhAEMAZlTI2MID9f5Clyh0JeE1V1ZEAvB4qDfwuJTSGRAAAAABJRU5ErkJggg=='
  };

  MarkNewIPs = {
    init: function() {
      if (g.VIEW !== 'thread' || !Conf['Mark New IPs']) {
        return;
      }
      return Thread.callbacks.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, k, len1, len2, newPosts, postCount, q, 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 (k = 0, len1 = newPosts.length; k < len1; k++) {
            fullID = newPosts[k];
            MarkNewIPs.markNew(g.posts[fullID], ++i);
          }
          break;
        case -deletedPosts.length:
          for (q = 0, len2 = newPosts.length; q < len2; q++) {
            fullID = newPosts[q];
            MarkNewIPs.markOld(g.posts[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');
    }
  };

  PruneReplies = {
    init: function() {
      var el, label;
      if (!(g.VIEW === 'thread' && !Conf['Quote Threading'])) {
        return;
      }
      label = UI.checkbox('Prune Replies', 'Show Last');
      el = $.el('span', {
        title: 'Maximum number of replies to show.'
      }, {
        innerHTML: " <input type=\"number\" name=\"Max Replies\" min=\"0\" step=\"1\" value=\"" + E(Conf["Max Replies"]) + "\" class=\"field\">"
      });
      $.prepend(el, label);
      this.inputs = {
        enabled: label.firstElementChild,
        replies: el.lastElementChild
      };
      $.on(this.inputs.enabled, 'change', $.cb.checked);
      $.on(this.inputs.replies, 'change', $.cb.value);
      Header.menu.addEntry({
        el: el,
        order: 190
      });
      return Thread.callbacks.push({
        name: 'Prune Replies',
        cb: this.node
      });
    },
    position: 0,
    hidden: 0,
    total: 0,
    node: function() {
      PruneReplies.thread = this;
      PruneReplies.total = this.posts.keys.length - 1;
      $.on(PruneReplies.inputs.enabled, 'change', PruneReplies.setEnabled);
      $.on(PruneReplies.inputs.enabled, 'change', PruneReplies.update);
      if (Conf['Prune Replies']) {
        PruneReplies.setEnabled();
        return PruneReplies.update();
      }
    },
    setEnabled: function() {
      var onOff;
      PruneReplies.container || (PruneReplies.container = $.frag());
      onOff = Conf['Prune Replies'] ? $.on : $.off;
      onOff(PruneReplies.inputs.replies, 'change', PruneReplies.update);
      return onOff(d, 'ThreadUpdate', PruneReplies.update);
    },
    update: function(e) {
      var OP, frag, hidden2, post, posts, ref, results;
      if (e && e.type === 'ThreadUpdate' && !e.detail[404]) {
        PruneReplies.total += e.detail.newPosts.length;
      }
      hidden2 = Conf['Prune Replies'] ? Math.max(PruneReplies.total - +Conf["Max Replies"], 0) : 0;
      ref = PruneReplies.thread, posts = ref.posts, OP = ref.OP;
      if (PruneReplies.hidden < hidden2) {
        results = [];
        while (PruneReplies.hidden < hidden2 && PruneReplies.position < posts.keys.length) {
          post = posts[posts.keys[PruneReplies.position++]];
          if (post.isReply && !post.isFetchedQuote) {
            $.add(PruneReplies.container, post.nodes.root);
            results.push(PruneReplies.hidden++);
          } else {
            results.push(void 0);
          }
        }
        return results;
      } else if (PruneReplies.hidden > hidden2) {
        frag = $.frag();
        while (PruneReplies.hidden > hidden2 && PruneReplies.position > 0) {
          post = posts[posts.keys[--PruneReplies.position]];
          if (post.isReply && !post.isFetchedQuote) {
            $.prepend(frag, post.nodes.root);
            PruneReplies.hidden--;
          }
        }
        $.after(OP.nodes.root, frag);
        return $.event('PostsInserted');
      }
    }
  };

  ThreadExcerpt = {
    init: function() {
      if (g.BOARD.ID !== 'f' || g.VIEW !== 'thread' || !Conf['Thread Excerpt']) {
        return;
      }
      return Thread.callbacks.push({
        name: 'Thread Excerpt',
        cb: this.node
      });
    },
    node: function() {
      return d.title = Get.threadExcerpt(this);
    }
  };

  ThreadStats = {
    init: function() {
      var sc, statsHTML, statsTitle;
      if (g.VIEW !== 'thread' || !Conf['Thread Stats']) {
        return;
      }
      statsHTML = {
        innerHTML: "<span id=\"post-count\">?</span> / <span id=\"file-count\">?</span>" + (Conf["IP Count in Stats"] ? " / <span id=\"ip-count\">?</span>" : "") + (Conf["Page Count in Stats"] ? " / <span id=\"page-count\">?</span>" : "")
      };
      statsTitle = 'Posts / Files';
      if (Conf['IP Count in Stats']) {
        statsTitle += ' / IPs';
      }
      if (Conf['Page Count in Stats']) {
        statsTitle += (g.BOARD.ID === 'f' ? ' / Purge Position' : ' / Page');
      }
      if (Conf['Updater and Stats in Header']) {
        this.dialog = sc = $.el('span', {
          id: 'thread-stats',
          title: statsTitle
        });
        $.extend(sc, statsHTML);
        $.ready(function() {
          return Header.addShortcut(sc);
        });
      } else {
        this.dialog = sc = UI.dialog('thread-stats', 'bottom: 0px; right: 0px;', {
          innerHTML: "<div class=\"move\" title=\"" + E(statsTitle) + "\">" + statsHTML.innerHTML + "</div>"
        });
        $.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 Thread.callbacks.push({
        name: 'Thread Stats',
        cb: this.node
      });
    },
    node: function() {
      var fileCount, postCount;
      postCount = 0;
      fileCount = 0;
      this.posts.forEach(function(post) {
        postCount++;
        if (post.file) {
          fileCount++;
        }
        if (ThreadStats.pageCountEl) {
          return ThreadStats.lastPost = post.info.date;
        }
      });
      ThreadStats.thread = this;
      ThreadStats.fetchPage();
      ThreadStats.update(postCount, fileCount, this.ipCount);
      return $.on(d, 'ThreadUpdate', ThreadStats.onUpdate);
    },
    onUpdate: function(e) {
      var fileCount, ipCount, newPosts, postCount, ref, ref1;
      if (e.detail[404]) {
        return;
      }
      ref = e.detail, postCount = ref.postCount, fileCount = ref.fileCount, ipCount = ref.ipCount, newPosts = ref.newPosts;
      ThreadStats.update(postCount, fileCount, ipCount);
      if (!ThreadStats.pageCountEl) {
        return;
      }
      if (newPosts.length) {
        ThreadStats.lastPost = g.posts[newPosts[newPosts.length - 1]].info.date;
      }
      if (g.BOARD.ID !== 'f' && ((ref1 = ThreadStats.pageCountEl) != null ? ref1.textContent : void 0) !== '1') {
        return ThreadStats.fetchPage();
      }
    },
    update: function(postCount, fileCount, ipCount) {
      var fileCountEl, ipCountEl, postCountEl, thread;
      thread = ThreadStats.thread, postCountEl = ThreadStats.postCountEl, fileCountEl = ThreadStats.fileCountEl, ipCountEl = ThreadStats.ipCountEl;
      postCountEl.textContent = postCount;
      fileCountEl.textContent = fileCount;
      if ((ipCount != null) && ipCountEl) {
        ipCountEl.textContent = ipCount;
      }
      (thread.postLimit && !thread.isSticky ? $.addClass : $.rmClass)(postCountEl, 'warning');
      return (thread.fileLimit && !thread.isSticky ? $.addClass : $.rmClass)(fileCountEl, 'warning');
    },
    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 $.ajax("//a.4cdn.org/" + ThreadStats.thread.board + "/threads.json", {
        onload: ThreadStats.onThreadsLoad
      }, {
        whenModified: 'ThreadStats'
      });
    },
    onThreadsLoad: function() {
      var k, len1, len2, len3, page, purgePos, q, ref, ref1, ref2, thread, u;
      if (this.status === 200) {
        ref = this.response;
        for (k = 0, len1 = ref.length; k < len1; k++) {
          page = ref[k];
          if (g.BOARD.ID === 'f') {
            purgePos = 1;
            ref1 = page.threads;
            for (q = 0, len2 = ref1.length; q < len2; q++) {
              thread = ref1[q];
              if (thread.no < ThreadStats.thread.ID) {
                purgePos++;
              }
            }
            ThreadStats.pageCountEl.textContent = purgePos;
          } else {
            ref2 = page.threads;
            for (u = 0, len3 = ref2.length; u < len3; u++) {
              thread = ref2[u];
              if (!(thread.no === ThreadStats.thread.ID)) {
                continue;
              }
              ThreadStats.pageCountEl.textContent = page.page;
              (page.page === this.response.length ? $.addClass : $.rmClass)(ThreadStats.pageCountEl, 'warning');
              ThreadStats.lastPageUpdate = new Date(thread.last_modified * $.SECOND);
              ThreadStats.retry();
              return;
            }
          }
        }
      } else if (this.status === 304) {
        return ThreadStats.retry();
      }
    },
    retry: function() {
      var ref;
      if (g.BOARD.ID !== 'f' && ThreadStats.lastPost > ThreadStats.lastPageUpdate && ((ref = ThreadStats.pageCountEl) != null ? ref.textContent : void 0) !== '1') {
        clearTimeout(ThreadStats.timeout);
        return ThreadStats.timeout = setTimeout(ThreadStats.fetchPage, 5 * $.SECOND);
      }
    }
  };

  ThreadUpdater = {
    init: function() {
      var conf, el, input, name, ref, sc, subEntries, updateLink;
      if (g.VIEW !== 'thread' || !Conf['Thread Updater']) {
        return;
      }
      this.audio = $.el('audio', {
        src: ThreadUpdater.beep
      });
      if (Conf['Updater and Stats in Header']) {
        this.dialog = sc = $.el('span', {
          id: 'updater'
        });
        $.extend(sc, {
          innerHTML: "<span id=\"update-status\" class=\"empty\"></span><span id=\"update-timer\" class=\"empty\" title=\"Update now\"></span>"
        });
        $.ready(function() {
          return Header.addShortcut(sc);
        });
      } else {
        this.dialog = sc = UI.dialog('updater', 'bottom: 0px; left: 0px;', {
          innerHTML: "<div class=\"move\"></div><span id=\"update-status\"></span><span id=\"update-timer\" title=\"Update now\"></span>"
        });
        $.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: "<a href=\"javascript:;\">Update</a>"
      });
      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: "<a href=\"javascript:;\">Interval</a>"
      });
      $.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 Thread.callbacks.push({
        name: 'Thread Updater',
        cb: this.node
      });
    },
    node: function() {
      ThreadUpdater.thread = this;
      ThreadUpdater.root = this.OP.nodes.root.parentNode;
      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);
      ThreadUpdater.setInterval();
      if (this.board.ID === 'f') {
        return ThreadUpdater.update();
      }
    },

    /*
    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;
      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() {
        var req;
        req = ThreadUpdater.req;
        switch (req.status) {
          case 200:
            ThreadUpdater.parse(req);
            if (ThreadUpdater.thread.isArchived) {
              return ThreadUpdater.kill();
            } else {
              return ThreadUpdater.setInterval();
            }
            break;
          case 404:
            return $.ajax("//a.4cdn.org/" + ThreadUpdater.thread.board + "/catalog.json", {
              onloadend: function() {
                var confirmed, k, len1, len2, page, q, ref, ref1, thread;
                if (this.status === 200) {
                  confirmed = true;
                  ref = this.response;
                  for (k = 0, len1 = ref.length; k < len1; k++) {
                    page = ref[k];
                    ref1 = page.threads;
                    for (q = 0, len2 = ref1.length; q < len2; q++) {
                      thread = ref1[q];
                      if (thread.no === ThreadUpdater.thread.ID) {
                        confirmed = false;
                        break;
                      }
                    }
                  }
                } else {
                  confirmed = false;
                }
                if (confirmed) {
                  return ThreadUpdater.kill();
                } else {
                  return ThreadUpdater.error(req);
                }
              }
            });
          default:
            return ThreadUpdater.error(req);
        }
      }
    },
    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 Failed', '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 ref;
      clearTimeout(ThreadUpdater.timeoutID);
      ThreadUpdater.set('timer', '...', 'loading');
      if ((ref = ThreadUpdater.req) != null) {
        ref.abort();
      }
      return ThreadUpdater.req = $.ajax("//a.4cdn.org/" + ThreadUpdater.thread.board + "/thread/" + ThreadUpdater.thread + ".json", {
        onloadend: ThreadUpdater.cb.load,
        timeout: $.MINUTE
      }, {
        whenModified: 'ThreadUpdater'
      });
    },
    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, index, ipCountEl, k, lastPost, len1, len2, len3, len4, newPosts, node, post, postObject, postObjects, posts, q, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, scroll, thread, u, unreadCount, unreadQYCount, v;
      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[lastPost].info.date < 30 * $.SECOND) {
        return;
      }
      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 (k = 0, len1 = postObjects.length; k < len1; k++) {
        postObject = postObjects[k];
        ID = postObject.no;
        index.push(ID);
        if (postObject.fsize) {
          files.push(ID);
        }
        if (board.ID === 'f' && postObject.fsize && (post = thread.posts[ID]) && !post.file) {
          node = Build.postFromObject(postObject, board.ID);
          $.after(post.nodes.info, $('.file', node));
          post.parseFile();
          Post.callbacks.execute(post, ['Filter', 'File Info Formatting', 'Fappe Tyme', 'Sauce']);
        }
        if (ID <= lastPost) {
          continue;
        }
        if ((post = thread.posts[ID]) && !post.isFetchedQuote) {
          post.resurrect();
          continue;
        }
        newPosts.push(board + "." + ID);
        node = Build.postFromObject(postObject, board.ID);
        posts.push(new Post(node, thread, board));
        if (ThreadUpdater.postID === ID) {
          delete ThreadUpdater.postID;
        }
      }
      deletedPosts = [];
      ref1 = ThreadUpdater.postIDs;
      for (q = 0, len2 = ref1.length; q < len2; q++) {
        ID = ref1[q];
        if (!(indexOf.call(index, ID) < 0)) {
          continue;
        }
        thread.posts[ID].kill();
        deletedPosts.push(board + "." + ID);
      }
      ThreadUpdater.postIDs = index;
      deletedFiles = [];
      ref2 = ThreadUpdater.fileIDs;
      for (u = 0, len3 = ref2.length; u < len3; u++) {
        ID = ref2[u];
        if (!(!(indexOf.call(files, ID) >= 0 || (ref3 = board + "." + ID, indexOf.call(deletedPosts, ref3) >= 0)))) {
          continue;
        }
        thread.posts[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 (v = 0, len4 = posts.length; v < len4; v++) {
          post = posts[v];
          if (!QuoteThreading.insert(post)) {
            firstPost || (firstPost = post.nodes.root);
            $.add(ThreadUpdater.root, post.nodes.root);
          }
        }
        $.event('PostsInserted');
        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
      });
    }
  };

  ThreadWatcher = {
    init: function() {
      var sc;
      if (!(this.enabled = Conf['Thread Watcher'])) {
        return;
      }
      this.shortcut = sc = $.el('a', {
        id: 'watcher-link',
        textContent: 'Watcher',
        title: 'Thread Watcher',
        href: 'javascript:;',
        className: 'disabled fa fa-eye'
      });
      this.db = new DataBoard('watchedThreads', this.refresh, true);
      this.dialog = UI.dialog('thread-watcher', 'top: 50px; left: 0px;', {
        innerHTML: "<div class=\"move\">Thread Watcher <a class=\"refresh fa fa-refresh\" title=\"Check threads\" href=\"javascript:;\"></a><span id=\"watcher-status\"></span><a class=\"menu-button\" href=\"javascript:;\"><i class=\"fa fa-angle-down\"></i></a><a class=\"close\" href=\"javascript:;\">×</a></div><div id=\"watched-threads\"></div>"
      });
      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 || 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);
      $.on(d, '4chanXInitFinished', this.ready);
      switch (g.VIEW) {
        case 'index':
          $.on(d, 'IndexRefresh', this.cb.onIndexRefresh);
          break;
        case 'thread':
          $.on(d, 'ThreadUpdate', this.cb.onThreadRefresh);
      }
      if (Conf['Fixed Thread Watcher']) {
        $.addClass(doc, 'fixed-watcher');
      }
      if (Conf['Toggleable Thread Watcher']) {
        this.dialog.hidden = true;
        Header.addShortcut(sc);
        $.addClass(doc, 'toggleable-watcher');
      }
      ThreadWatcher.fetchAuto();
      if (g.VIEW === 'index' && Conf['JSON Index'] && Conf['Menu'] && g.BOARD.ID !== 'f') {
        Menu.menu.addEntry({
          el: $.el('a', {
            href: 'javascript:;',
            className: 'has-shortcut-text'
          }, {
            innerHTML: "<span></span><span class=\"shortcut-text\">Alt+click</span>"
          }),
          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;
          }
        });
      }
      Post.callbacks.push({
        name: 'Thread Watcher',
        cb: this.node
      });
      return CatalogThread.callbacks.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;
    },
    node: function() {
      var toggler;
      if (this.isReply) {
        return;
      }
      if (this.isClone) {
        toggler = $('.watch-thread-link', this.nodes.post);
      } else {
        toggler = $.el('a', {
          href: 'javascript:;',
          className: 'watch-thread-link'
        });
        $.before($('input', this.nodes.post), toggler);
      }
      return $.on(toggler, 'click', ThreadWatcher.cb.toggle);
    },
    catalogNode: function() {
      if (ThreadWatcher.isWatched(this.thread)) {
        $.addClass(this.nodes.root, 'watched');
      }
      $.on(this.nodes.thumb.parentNode, 'click', (function(_this) {
        return function(e) {
          if (!(e.button === 0 && e.altKey)) {
            return;
          }
          ThreadWatcher.toggle(_this.thread);
          return e.preventDefault();
        };
      })(this));
      return $.on(this.nodes.thumb.parentNode, 'mousedown', function(e) {
        if (e.button === 0 && e.altKey) {
          return e.preventDefault();
        }
      });
    },
    ready: function() {
      $.off(d, '4chanXInitFinished', ThreadWatcher.ready);
      if (!Main.isThisPageLegit()) {
        return;
      }
      ThreadWatcher.refresh();
      $.add(d.body, ThreadWatcher.dialog);
      if (!Conf['Auto Watch']) {
        return;
      }
      return $.get('AutoWatch', 0, function(arg) {
        var AutoWatch, thread;
        AutoWatch = arg.AutoWatch;
        if (!(thread = g.BOARD.threads[AutoWatch])) {
          return;
        }
        ThreadWatcher.add(thread);
        return $["delete"]('AutoWatch');
      });
    },
    toggleWatcher: function() {
      $.toggleClass(ThreadWatcher.shortcut, 'disabled');
      return ThreadWatcher.dialog.hidden = !ThreadWatcher.dialog.hidden;
    },
    cb: {
      openAll: function() {
        var a, k, len1, ref;
        if ($.hasClass(this, 'disabled')) {
          return;
        }
        ref = $$('a[title]', ThreadWatcher.list);
        for (k = 0, len1 = ref.length; k < len1; k++) {
          a = ref[k];
          $.open(a.href);
        }
        return $.event('CloseMenu');
      },
      pruneDeads: function() {
        var boardID, data, k, len1, ref, ref1, threadID;
        if ($.hasClass(this, 'disabled')) {
          return;
        }
        ThreadWatcher.db.forceSync();
        ref = ThreadWatcher.getAll();
        for (k = 0, len1 = ref.length; k < len1; k++) {
          ref1 = ref[k], boardID = ref1.boardID, threadID = ref1.threadID, data = ref1.data;
          if (!data.isDead) {
            continue;
          }
          delete ThreadWatcher.db.data.boards[boardID][threadID];
          ThreadWatcher.db.deleteIfEmpty({
            boardID: boardID
          });
        }
        ThreadWatcher.db.save();
        ThreadWatcher.refresh();
        return $.event('CloseMenu');
      },
      toggle: function() {
        var thread;
        thread = Get.postFromNode(this).thread;
        Index.followedThreadID = thread.ID;
        ThreadWatcher.toggle(thread);
        return delete Index.followedThreadID;
      },
      rm: function() {
        var boardID, ref, threadID;
        ref = this.parentNode.dataset.fullID.split('.'), boardID = ref[0], threadID = ref[1];
        return ThreadWatcher.rm(boardID, +threadID);
      },
      post: function(e) {
        var boardID, postID, ref, threadID;
        ref = e.detail, boardID = ref.boardID, threadID = ref.threadID, postID = ref.postID;
        if (postID === threadID) {
          if (Conf['Auto Watch']) {
            return $.set('AutoWatch', threadID);
          }
        } else if (Conf['Auto Watch Reply']) {
          return ThreadWatcher.add(g.threads[boardID + '.' + threadID]);
        }
      },
      onIndexRefresh: function() {
        var boardID, data, db, ref, threadID;
        db = ThreadWatcher.db;
        boardID = g.BOARD.ID;
        db.forceSync();
        ref = db.data.boards[boardID];
        for (threadID in ref) {
          data = ref[threadID];
          if (!(data != null ? data.isDead : void 0) && !(threadID in g.BOARD.threads)) {
            if (Conf['Auto Prune'] || !(data && typeof data === 'object')) {
              db["delete"]({
                boardID: boardID,
                threadID: threadID
              });
            } else {
              if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) {
                ThreadWatcher.fetchStatus({
                  boardID: boardID,
                  threadID: threadID,
                  data: data
                });
              }
              data.isDead = true;
              db.set({
                boardID: boardID,
                threadID: threadID,
                val: data
              });
            }
          }
        }
        return ThreadWatcher.refresh();
      },
      onThreadRefresh: function(e) {
        var thread;
        thread = g.threads[e.detail.threadID];
        if (!(e.detail[404] && ThreadWatcher.db.get({
          boardID: thread.board.ID,
          threadID: thread.ID
        }))) {
          return;
        }
        return ThreadWatcher.add(thread);
      }
    },
    requests: [],
    fetched: 0,
    clearRequests: function() {
      ThreadWatcher.requests = [];
      ThreadWatcher.fetched = 0;
      ThreadWatcher.status.textContent = '';
      return $.rmClass(ThreadWatcher.refreshButton, 'fa-spin');
    },
    abort: function() {
      var k, len1, ref, req;
      ref = ThreadWatcher.requests;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        req = ref[k];
        if (req.readyState !== 4) {
          req.abort();
        }
      }
      return ThreadWatcher.clearRequests();
    },
    fetchAuto: function() {
      var db, interval, now;
      clearTimeout(ThreadWatcher.timeout);
      if (!Conf['Auto Update Thread Watcher']) {
        return;
      }
      db = ThreadWatcher.db;
      interval = ThreadWatcher.unreadEnabled && Conf['Show Unread Count'] ? 5 * $.MINUTE : 2 * $.HOUR;
      now = Date.now();
      if (now >= (db.data.lastChecked || 0) + interval) {
        db.data.lastChecked = now;
        ThreadWatcher.fetchAllStatus();
        db.save();
      }
      return ThreadWatcher.timeout = setTimeout(ThreadWatcher.fetchAuto, interval);
    },
    buttonFetchAll: function() {
      if (ThreadWatcher.requests.length) {
        return ThreadWatcher.abort();
      } else {
        return ThreadWatcher.fetchAllStatus();
      }
    },
    fetchAllStatus: function() {
      var k, len1, ref, thread, threads;
      ThreadWatcher.db.forceSync();
      ThreadWatcher.unreaddb.forceSync();
      if ((ref = QuoteYou.db) != null) {
        ref.forceSync();
      }
      if (!(threads = ThreadWatcher.getAll()).length) {
        return;
      }
      for (k = 0, len1 = threads.length; k < len1; k++) {
        thread = threads[k];
        ThreadWatcher.fetchStatus(thread);
      }
    },
    fetchStatus: function(thread, force) {
      var boardID, data, req, threadID;
      boardID = thread.boardID, threadID = thread.threadID, data = thread.data;
      if (data.isDead && !force) {
        return;
      }
      if (ThreadWatcher.requests.length === 0) {
        ThreadWatcher.status.textContent = '...';
        $.addClass(ThreadWatcher.refreshButton, 'fa-spin');
      }
      req = $.ajax("//a.4cdn.org/" + boardID + "/thread/" + threadID + ".json", {
        onloadend: function() {
          return ThreadWatcher.parseStatus.call(this, thread);
        },
        timeout: $.MINUTE
      }, {
        whenModified: force ? false : 'ThreadWatcher'
      });
      return ThreadWatcher.requests.push(req);
    },
    parseStatus: function(arg) {
      var boardID, data, isDead, k, lastReadPost, len1, match, postObj, quotesYou, quotingYou, ref, ref1, regexp, threadID, unread;
      boardID = arg.boardID, threadID = arg.threadID, data = arg.data;
      ThreadWatcher.fetched++;
      if (ThreadWatcher.fetched === ThreadWatcher.requests.length) {
        ThreadWatcher.clearRequests();
      } else {
        ThreadWatcher.status.textContent = (Math.round(ThreadWatcher.fetched / ThreadWatcher.requests.length * 100)) + "%";
      }
      if (this.status === 200 && this.response) {
        isDead = !!this.response.posts[0].archived;
        if (isDead && Conf['Auto Prune']) {
          ThreadWatcher.db["delete"]({
            boardID: boardID,
            threadID: threadID
          });
          ThreadWatcher.refresh();
          return;
        }
        lastReadPost = ThreadWatcher.unreaddb.get({
          boardID: boardID,
          threadID: threadID,
          defaultValue: 0
        });
        unread = quotingYou = 0;
        ref = this.response.posts;
        for (k = 0, len1 = ref.length; k < len1; k++) {
          postObj = ref[k];
          if (!(postObj.no > lastReadPost)) {
            continue;
          }
          if ((ref1 = QuoteYou.db) != null ? ref1.get({
            boardID: boardID,
            threadID: threadID,
            postID: postObj.no
          }) : void 0) {
            continue;
          }
          unread++;
          if (!(QuoteYou.db && postObj.com)) {
            continue;
          }
          quotesYou = false;
          regexp = /<a [^>]*\bhref="(?:\/([^\/]+)\/thread\/)?(\d+)?(?:#p(\d+))?"/g;
          while (match = regexp.exec(postObj.com)) {
            if (QuoteYou.db.get({
              boardID: match[1] || boardID,
              threadID: match[2] || threadID,
              postID: match[3] || match[2] || threadID
            })) {
              quotesYou = true;
              break;
            }
          }
          if (quotesYou && !Filter.isHidden(Build.parseJSON(postObj, boardID))) {
            quotingYou++;
          }
        }
        if (isDead !== data.isDead || unread !== data.unread || quotingYou !== data.quotingYou) {
          data.isDead = isDead;
          data.unread = unread;
          data.quotingYou = quotingYou;
          ThreadWatcher.db.set({
            boardID: boardID,
            threadID: threadID,
            val: data
          });
          return ThreadWatcher.refresh();
        }
      } else if (this.status === 404) {
        if (Conf['Auto Prune']) {
          ThreadWatcher.db["delete"]({
            boardID: boardID,
            threadID: threadID
          });
        } else {
          data.isDead = true;
          delete data.unread;
          delete data.quotingYou;
          ThreadWatcher.db.set({
            boardID: boardID,
            threadID: threadID,
            val: data
          });
        }
        return ThreadWatcher.refresh();
      }
    },
    getAll: function() {
      var all, boardID, data, ref, threadID, threads;
      all = [];
      ref = ThreadWatcher.db.data.boards;
      for (boardID in ref) {
        threads = ref[boardID];
        if (Conf['Current Board'] && boardID !== g.BOARD.ID) {
          continue;
        }
        for (threadID in threads) {
          data = threads[threadID];
          if (data && typeof data === 'object') {
            all.push({
              boardID: boardID,
              threadID: threadID,
              data: data
            });
          }
        }
      }
      return all;
    },
    makeLine: function(boardID, threadID, data) {
      var count, div, fullID, link, title, x;
      x = $.el('a', {
        className: 'fa fa-times',
        href: 'javascript:;'
      });
      $.on(x, 'click', ThreadWatcher.cb.rm);
      link = $.el('a', {
        href: "/" + boardID + "/thread/" + threadID,
        title: data.excerpt,
        className: 'watcher-link'
      });
      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: data.excerpt,
        className: 'watcher-title'
      });
      $.add(link, title);
      div = $.el('div');
      fullID = boardID + "." + threadID;
      div.dataset.fullID = fullID;
      if (g.VIEW === 'thread' && fullID === (g.BOARD + "." + g.THREADID)) {
        $.addClass(div, 'current');
      }
      if (data.isDead) {
        $.addClass(div, 'dead-thread');
      }
      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) {
          $.addClass(div, 'replies-quoting-you');
        }
      }
      $.add(div, [x, $.tn(' '), link]);
      return div;
    },
    refresh: function() {
      var boardID, data, k, len1, len2, list, nodes, q, ref, ref1, ref2, refresher, threadID;
      nodes = [];
      ref = ThreadWatcher.getAll();
      for (k = 0, len1 = ref.length; k < len1; k++) {
        ref1 = ref[k], boardID = ref1.boardID, threadID = ref1.threadID, data = ref1.data;
        nodes.push(ThreadWatcher.makeLine(boardID, threadID, data));
      }
      list = ThreadWatcher.list;
      $.rmAll(list);
      $.add(list, nodes);
      g.threads.forEach(function(thread) {
        var helper, len2, post, q, ref2, toggler;
        helper = ThreadWatcher.isWatched(thread) ? ['addClass', 'Unwatch'] : ['rmClass', 'Watch'];
        if (thread.OP) {
          ref2 = [thread.OP].concat(slice.call(thread.OP.clones));
          for (q = 0, len2 = ref2.length; q < len2; q++) {
            post = ref2[q];
            toggler = $('.watch-thread-link', post.nodes.post);
            $[helper[0]](toggler, 'watched');
            toggler.title = helper[1] + " Thread";
          }
        }
        if (thread.catalogView) {
          return $[helper[0]](thread.catalogView.nodes.root, 'watched');
        }
      });
      ThreadWatcher.refreshIcon();
      ref2 = ThreadWatcher.menu.refreshers;
      for (q = 0, len2 = ref2.length; q < len2; q++) {
        refresher = ref2[q];
        refresher();
      }
      if (Index.nodes && Conf['Pin Watched Threads']) {
        Index.sort();
        return Index.buildIndex();
      }
    },
    refreshIcon: function() {
      var className, k, len1, ref;
      ref = ['replies-unread', 'replies-quoting-you'];
      for (k = 0, len1 = ref.length; k < len1; k++) {
        className = ref[k];
        ThreadWatcher.shortcut.classList.toggle(className, !!$("." + className, ThreadWatcher.dialog));
      }
    },
    update: function(boardID, threadID, newData) {
      var data, key, line, n, newLine, ref, val;
      if (!(data = (ref = ThreadWatcher.db) != null ? ref.get({
        boardID: boardID,
        threadID: threadID
      }) : void 0)) {
        return;
      }
      if (newData.isDead && Conf['Auto Prune']) {
        ThreadWatcher.db["delete"]({
          boardID: boardID,
          threadID: threadID
        });
        ThreadWatcher.refresh();
        return;
      }
      n = 0;
      for (key in newData) {
        val = newData[key];
        if (data[key] !== val) {
          n++;
        }
      }
      if (!n) {
        return;
      }
      ThreadWatcher.db.forceSync();
      if (!(data = ThreadWatcher.db.get({
        boardID: boardID,
        threadID: threadID
      }))) {
        return;
      }
      $.extend(data, newData);
      ThreadWatcher.db.set({
        boardID: boardID,
        threadID: threadID,
        val: data
      });
      if (line = $("#watched-threads > [data-full-i-d='" + boardID + "." + threadID + "']", ThreadWatcher.dialog)) {
        newLine = ThreadWatcher.makeLine(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.unread != null) || (data.quotingYou != null))) {
        return cb();
      }
      data.isDead = true;
      delete data.unread;
      delete data.quotingYou;
      return ThreadWatcher.db.set({
        boardID: boardID,
        threadID: threadID,
        val: data
      }, cb);
    },
    toggle: function(thread) {
      var boardID, threadID;
      boardID = thread.board.ID;
      threadID = thread.ID;
      if (ThreadWatcher.db.get({
        boardID: boardID,
        threadID: threadID
      })) {
        return ThreadWatcher.rm(boardID, threadID);
      } else {
        return ThreadWatcher.add(thread);
      }
    },
    add: function(thread) {
      var boardID, data, threadID;
      data = {};
      boardID = thread.board.ID;
      threadID = thread.ID;
      if (thread.isDead) {
        if (Conf['Auto Prune'] && ThreadWatcher.db.get({
          boardID: boardID,
          threadID: threadID
        })) {
          ThreadWatcher.rm(boardID, threadID);
          return;
        }
        data.isDead = true;
      }
      data.excerpt = Get.threadExcerpt(thread);
      ThreadWatcher.db.set({
        boardID: boardID,
        threadID: threadID,
        val: data
      });
      ThreadWatcher.refresh();
      if (ThreadWatcher.unreadEnabled && Conf['Show Unread Count']) {
        return ThreadWatcher.fetchStatus({
          boardID: boardID,
          threadID: threadID,
          data: data
        }, true);
      }
    },
    rm: function(boardID, threadID) {
      ThreadWatcher.db["delete"]({
        boardID: boardID,
        threadID: threadID
      });
      return ThreadWatcher.refresh();
    },
    menu: {
      refreshers: [],
      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);
        });
        this.addHeaderMenuEntry();
        return this.addMenuEntries();
      },
      addHeaderMenuEntry: function() {
        var entryEl;
        if (g.VIEW !== 'thread') {
          return;
        }
        entryEl = $.el('a', {
          href: 'javascript:;'
        });
        Header.menu.addEntry({
          el: entryEl,
          order: 60
        });
        $.on(entryEl, 'click', function() {
          return ThreadWatcher.toggle(g.threads[g.BOARD + "." + g.THREADID]);
        });
        return this.refreshers.push(function() {
          var addClass, ref, rmClass, text;
          ref = $('.current', ThreadWatcher.list) ? ['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);
          return entryEl.textContent = text;
        });
      },
      addMenuEntries: function() {
        var cb, conf, entries, entry, k, len1, name, ref, ref1, refresh, subEntries;
        entries = [];
        entries.push({
          cb: ThreadWatcher.cb.openAll,
          entry: {
            el: $.el('a', {
              textContent: 'Open all threads'
            })
          },
          refresh: function() {
            return (ThreadWatcher.list.firstElementChild ? $.rmClass : $.addClass)(this.el, 'disabled');
          }
        });
        entries.push({
          cb: ThreadWatcher.cb.pruneDeads,
          entry: {
            el: $.el('a', {
              textContent: 'Prune dead threads'
            })
          },
          refresh: function() {
            return ($('.dead-thread', ThreadWatcher.list) ? $.rmClass : $.addClass)(this.el, 'disabled');
          }
        });
        subEntries = [];
        ref = Config.threadWatcher;
        for (name in ref) {
          conf = ref[name];
          subEntries.push(this.createSubEntry(name, conf[1]));
        }
        entries.push({
          entry: {
            el: $.el('span', {
              textContent: 'Settings'
            }),
            subEntries: subEntries
          }
        });
        for (k = 0, len1 = entries.length; k < len1; k++) {
          ref1 = entries[k], entry = ref1.entry, cb = ref1.cb, refresh = ref1.refresh;
          if (entry.el.nodeName === 'A') {
            entry.el.href = 'javascript:;';
          }
          if (cb) {
            $.on(entry.el, 'click', cb);
          }
          if (refresh) {
            this.refreshers.push(refresh.bind(entry));
          }
          this.menu.addEntry(entry);
        }
      },
      createSubEntry: 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 Unread Count') {
          $.on(input, 'change', ThreadWatcher.refresh);
        }
        if (name === 'Show Unread Count' || name === 'Auto Update Thread Watcher') {
          $.on(input, 'change', ThreadWatcher.fetchAuto);
        }
        return entry;
      }
    }
  };

  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'
      });
      this.posts = new Set();
      this.postsQuotingYou = new Set();
      this.order = new RandomAccessList();
      this.position = null;
      Thread.callbacks.push({
        name: 'Unread',
        cb: this.node
      });
      return Post.callbacks.push({
        name: 'Unread',
        cb: this.addPost
      });
    },
    node: function() {
      var ID, k, len1, ref, ref1;
      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 (k = 0, len1 = ref1.length; k < len1; k++) {
        ID = ref1[k];
        if (+ID <= Unread.lastReadPost) {
          Unread.readCount++;
        }
      }
      $.one(d, '4chanXInitFinished', Unread.ready);
      return $.on(d, 'ThreadUpdate', Unread.onUpdate);
    },
    ready: function() {
      Unread.setLine(true);
      Unread.read();
      Unread.update();
      if (Conf['Remember Last Read Post'] && Conf['Scroll to Last Read Post']) {
        Unread.scroll();
      }
      $.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 hash, position, root;
      if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) {
        return;
      }
      position = Unread.positionPrev();
      while (position) {
        root = position.data.nodes.root;
        if (!root.getBoundingClientRect().height) {
          position = position.prev;
        } else {
          Header.scrollToIfNeeded(root, true);
          break;
        }
      }
    },
    sync: function() {
      var ID, i, k, 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 = k = ref = Unread.readCount, ref1 = postIDs.length; k < ref1; i = k += 1) {
        ID = +postIDs[i];
        if (!Unread.thread.posts[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() {
      var ref;
      if (this.isFetchedQuote || this.isClone) {
        return;
      }
      Unread.order.push(this);
      if (this.ID <= Unread.lastReadPost || this.isHidden || ((ref = QuoteYou.db) != null ? ref.get({
        boardID: this.board.ID,
        threadID: this.thread.ID,
        postID: this.ID
      }) : void 0)) {
        return;
      }
      Unread.posts.add(this.ID);
      Unread.addPostQuotingYou(this);
      return Unread.position != null ? Unread.position : Unread.position = Unread.order[this.ID];
    },
    addPostQuotingYou: function(post) {
      var k, len1, quotelink, ref, ref1;
      ref = post.nodes.quotelinks;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        quotelink = ref[k];
        if (!((ref1 = QuoteYou.db) != null ? ref1.get(Get.postDataFromLink(quotelink)) : void 0)) {
          continue;
        }
        Unread.postsQuotingYou.add(post.ID);
        Unread.openNotification(post);
        return;
      }
    },
    openNotification: function(post) {
      var notif;
      if (!Header.areNotificationsEnabled) {
        return;
      }
      try {
        notif = new Notification(post.info.nameBlock + " replied to you", {
          body: post.info.commentDisplay,
          icon: Favicon.logo
        });
        notif.onclick = function() {
          Header.scrollToIfNeeded(post.nodes.root, true);
          return $.global(function() {
            return window.focus();
          });
        };
        return notif.onshow = function() {
          return setTimeout(function() {
            return notif.close();
          }, 7 * $.SECOND);
        };
      } catch (_error) {}
    },
    onUpdate: function(e) {
      if (!e.detail[404]) {
        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, count, data, ref, ref1, root;
      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;
        root = data.nodes.root;
        if (!(!root.getBoundingClientRect().height || Header.getBottomOf(root) > -1)) {
          break;
        }
        count++;
        Unread.posts["delete"](ID);
        Unread.postsQuotingYou["delete"](ID);
        if ((ref1 = QuoteYou.db) != null ? ref1.get({
          boardID: data.board.ID,
          threadID: data.thread.ID,
          postID: ID
        }) : void 0) {
          QuoteYou.lastRead = root;
        }
        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, k, postIDs, ref, ref1;
      $.forceSync('Remember Last Read Post');
      if (!(Conf['Remember Last Read Post'] && Unread.db)) {
        return;
      }
      postIDs = Unread.thread.posts.keys;
      for (i = k = ref = Unread.readCount, ref1 = postIDs.length; k < ref1; i = k += 1) {
        ID = +postIDs[i];
        if (!Unread.thread.posts[ID].isFetchedQuote) {
          if (Unread.posts.has(ID)) {
            break;
          }
          Unread.lastReadPost = ID;
        }
        Unread.readCount++;
      }
      if (Unread.thread.isDead && !Unread.thread.isArchived) {
        return;
      }
      Unread.db.forceSync();
      return Unread.db.set({
        boardID: Unread.thread.board.ID,
        threadID: Unread.thread.ID,
        val: Unread.lastReadPost
      });
    }),
    setLine: function(force) {
      if (!Conf['Unread Line']) {
        return;
      }
      if (Unread.hr.hidden || d.hidden || (force === true)) {
        if (Unread.linePosition = Unread.positionPrev()) {
          $.after(Unread.linePosition.data.nodes.root, 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;
      }
      $.forceSync('Remember Last Read Post');
      if (Conf['Remember Last Read Post'] && (!Unread.thread.isDead || Unread.thread.isArchived)) {
        ThreadWatcher.update(Unread.thread.board.ID, Unread.thread.ID, {
          isDead: Unread.thread.isDead,
          unread: count,
          quotingYou: countQuotingYou
        });
      }
      if (Conf['Unread Favicon']) {
        isDead = Unread.thread.isDead;
        Favicon.el.href = countQuotingYou ? Favicon[isDead ? 'unreadDeadY' : 'unreadY'] : count ? Favicon[isDead ? 'unreadDead' : 'unread'] : Favicon[isDead ? 'dead' : 'default'];
        return $.add(d.head, Favicon.el);
      }
    }
  };

  Redirect = {
    init: function() {
      var archive, archives, boardID, boards, data, files, id, k, len1, len2, name, o, q, record, ref, ref1, software, type, uid, withCredentials;
      o = {
        thread: {},
        post: {},
        file: {},
        report: {}
      };
      archives = {};
      ref = Redirect.archives;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        data = ref[k];
        uid = data.uid, name = data.name, boards = data.boards, files = data.files, software = data.software, withCredentials = data.withCredentials;
        archives[JSON.stringify(uid != null ? uid : name)] = data;
        for (q = 0, len2 = boards.length; q < len2; q++) {
          boardID = boards[q];
          if (!withCredentials) {
            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;
            }
          }
          if (name === 'fgts') {
            o.report[boardID] = data;
          }
        }
      }
      ref1 = Conf['selectedArchives'];
      for (boardID in ref1) {
        record = ref1[boardID];
        for (type in record) {
          id = record[type];
          if (id === null) {
            delete o[type][boardID];
          } else if (archive = archives[JSON.stringify(id)]) {
            boards = type === 'file' ? archive.files : archive.boards;
            if (indexOf.call(boards, boardID) >= 0) {
              o[type][boardID] = archive;
            }
          }
        }
      }
      return Redirect.data = o;
    },
    archives: [{"uid":3,"name":"4plebs","domain":"archive.4plebs.org","http":true,"https":true,"software":"foolfuuka","boards":["adv","f","hr","o","pol","s4s","sp","tg","trv","tv","x"],"files":["adv","f","hr","o","pol","s4s","sp","tg","trv","tv","x"]},{"uid":4,"name":"Nyafuu Archive","domain":"archive.nyafuu.org","http":true,"https":true,"software":"foolfuuka","boards":["c","e","w","wg","wsr"],"files":["c","e","w","wg","wsr"]},{"uid":8,"name":"Rebecca Black Tech","domain":"rbt.asia","http":false,"https":true,"software":"fuuka","boards":["cgl","g","mu"],"files":["cgl","g","mu"]},{"uid":10,"name":"warosu","domain":"warosu.org","http":false,"https":true,"software":"fuuka","boards":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"],"files":["3","biz","cgl","ck","diy","fa","g","ic","jp","lit","sci","tg","vr"]},{"uid":15,"name":"fgts","domain":"fgts.jp","http":true,"https":true,"software":"foolfuuka","boards":["asp","b","cm","gd","h","hc","hm","n","out","p","po","qa","r","s","soc","toy","vp","y"],"files":["asp","b","cm","gd","h","hc","hm","n","out","p","po","qa","r","s","soc","toy","vp","y"]},{"uid":23,"name":"Desustorage","domain":"desustorage.org","http":true,"https":true,"software":"foolfuuka","boards":["a","aco","an","c","co","d","fit","gif","his","int","k","m","mlp","qa","r9k","tg","trash","vr","wsg"],"files":["a","aco","an","c","co","d","fit","gif","his","int","k","m","mlp","qa","r9k","tg","trash","vr","wsg"]},{"uid":24,"name":"fireden.net","domain":"boards.fireden.net","http":false,"https":true,"software":"foolfuuka","boards":["a","cm","ic","sci","tg","v","vg","y"],"files":["a","cm","ic","sci","tg","v","vg","y"]},{"uid":25,"name":"arch.b4k.co","domain":"arch.b4k.co","http":true,"https":true,"software":"foolfuuka","boards":["g","jp","mlp","v"],"files":[]},{"uid":5,"name":"Love is Over","domain":"deploy.loveisover.me","http":true,"https":false,"software":"foolfuuka","boards":["c","d","e","i","lgbt","t","u"],"files":["c","d","e","i","lgbt","t","u"],"search":[]}],
    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 (!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;
      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 = {
          'Developer': 'dev'
        }[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(archive, arg) {
      var boardID, postID;
      boardID = arg.boardID, postID = arg.postID;
      return "https://so.fgts.jp/report/?board=" + boardID + "&no=" + postID;
    },
    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);
      }
    }
  };

  PSAHiding = {
    init: function() {
      if (!Conf['Announcement Hiding']) {
        return;
      }
      $.addClass(doc, 'hide-announcement');
      return $.one(d, '4chanXInitFinished', this.setup);
    },
    setup: function() {
      var btn, entry, hr, psa, ref;
      if (!(psa = PSAHiding.psa = $.id('globalMessage'))) {
        $.rmClass(doc, 'hide-announcement');
        return;
      }
      if ((hr = (ref = $.id('globalToggle')) != null ? ref.previousElementSibling : void 0) && hr.nodeName === 'HR') {
        PSAHiding.hr = hr;
      }
      entry = {
        el: $.el('a', {
          textContent: 'Show announcement',
          className: 'show-announcement',
          href: 'javascript:;'
        }),
        order: 50,
        open: function() {
          return PSAHiding.hidden;
        }
      };
      Header.menu.addEntry(entry);
      $.on(entry.el, 'click', PSAHiding.toggle);
      PSAHiding.btn = btn = $.el('span', {
        title: 'Mark announcement as read and hide.',
        className: 'hide-announcement'
      });
      $.extend(btn, {
        innerHTML: "[<a href=\"javascript:;\">Dismiss</a>]"
      });
      $.on(btn, 'click', PSAHiding.toggle);
      $.get('hiddenPSA', 0, function(arg) {
        var hiddenPSA;
        hiddenPSA = arg.hiddenPSA;
        PSAHiding.sync(hiddenPSA);
        $.add(psa, btn);
        return $.rmClass(doc, 'hide-announcement');
      });
      return $.sync('hiddenPSA', PSAHiding.sync);
    },
    toggle: function() {
      var UTC;
      if ($.hasClass(this, 'hide-announcement')) {
        UTC = +$.id('globalMessage').dataset.utc;
        $.set('hiddenPSA', UTC);
      } else {
        $.event('CloseMenu');
        $["delete"]('hiddenPSA');
      }
      return PSAHiding.sync(UTC);
    },
    sync: function(UTC) {
      var psa, ref;
      psa = PSAHiding.psa;
      PSAHiding.hidden = PSAHiding.btn.hidden = (UTC != null) && UTC >= +psa.dataset.utc;
      if (PSAHiding.hidden) {
        $.rm(psa);
      } else {
        $.after($.id('globalToggle'), psa);
      }
      if ((ref = PSAHiding.hr) != null) {
        ref.hidden = PSAHiding.hidden;
      }
    }
  };

  AntiAutoplay = {
    init: function() {
      var audio, k, len1, ref;
      if (!Conf['Disable Autoplaying Sounds']) {
        return;
      }
      $.addClass(doc, 'anti-autoplay');
      ref = $$('audio[autoplay]', doc);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        audio = ref[k];
        this.stop(audio);
      }
      window.addEventListener('loadstart', ((function(_this) {
        return function(e) {
          return _this.stop(e.target);
        };
      })(this)), true);
      Post.callbacks.push({
        name: 'Disable Autoplaying Sounds',
        cb: this.node
      });
      CatalogThread.callbacks.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.root);
    },
    process: function(root) {
      var iframe, k, len1, len2, object, q, ref, ref1;
      ref = $$('iframe[src*="youtube"][src*="autoplay=1"]', root);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        iframe = ref[k];
        iframe.src = iframe.src.replace(/\?autoplay=1&?/, '?').replace('&autoplay=1', '');
        $.addClass(iframe, 'autoplay-removed');
      }
      ref1 = $$('object[data*="youtube"][data*="autoplay=1"]', root);
      for (q = 0, len2 = ref1.length; q < len2; q++) {
        object = ref1[q];
        object.data = object.data.replace(/\?autoplay=1&?/, '?').replace('&autoplay=1', '');
        $.addClass(object, 'autoplay-removed');
      }
    }
  };

  Banner = {
    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"],
    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.BOARD.ID !== 'f' && 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 = Banner.banners.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 base1, br, k, len1, name1, ref;
        if (!(e.ctrlKey || e.metaKey)) {
          return;
        }
        if ((base1 = Banner.original)[name1 = this.className] == null) {
          base1[name1] = this.cloneNode(true);
        }
        this.contentEditable = true;
        ref = $$('br', this);
        for (k = 0, len1 = ref.length; k < len1; k++) {
          br = ref[k];
          $.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, k, len1, ref;
        ref = $$('br', this);
        for (k = 0, len1 = ref.length; k < len1; k++) {
          br = ref[k];
          $.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: {},
    custom: function(child) {
      var className, data, event, items, k, len1, ref, string, string2;
      className = child.className;
      child.title = "Ctrl/\u2318+click to edit board " + (className.slice(5).toLowerCase());
      child.spellcheck = false;
      ref = ['click', 'keydown', 'blur'];
      for (k = 0, len1 = ref.length; k < len1; k++) {
        event = ref[k];
        $.on(child, event, Banner.cb[event]);
      }
      string = g.BOARD + "." + className;
      string2 = string + ".orig";
      items = {};
      items[string] = '';
      items[string2] = child.textContent;
      $.get(items, function(items) {
        if (items[string]) {
          Banner.db.set({
            boardID: g.BOARD.ID,
            threadID: className,
            val: {
              title: items[string],
              orig: items[string2]
            }
          });
        }
        return $["delete"]([string, string2]);
      });
      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
          });
        }
      }
    }
  };

  CatalogLinks = {
    init: function() {
      var el, input, selector;
      if ((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 catalogLink, k, len1, link, ref;
          ref = $$(selector);
          for (k = 0, len1 = ref.length; k < len1; k++) {
            link = ref[k];
            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' && Conf['JSON Index'] && Conf['Use 4chan X Catalog']) {
              catalogLink = link.parentNode.cloneNode(true);
              catalogLink.firstElementChild.textContent = '4chan X Catalog';
              catalogLink.firstElementChild.href = CatalogLinks.catalog();
              $.after(link.parentNode, [$.tn(' '), catalogLink]);
            }
          }
        });
      }
      if (Conf['JSON Index'] && Conf['Use 4chan X Catalog']) {
        Post.callbacks.push({
          name: 'Catalog Link Rewrite',
          cb: this.node
        });
        CatalogThread.callbacks.push({
          name: 'Catalog Link Rewrite',
          cb: this.node
        });
      }
      if (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, k, len1, m, ref;
      ref = $$('a', this.nodes.comment);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        a = ref[k];
        if (m = a.href.match(/^https?:\/\/boards\.4chan\.org\/([^\/]+)\/catalog(#s=.*)?/)) {
          a.href = "//boards.4chan.org/" + m[1] + "/" + (m[2] || '#catalog');
        }
      }
    },
    initBoardList: function() {
      if (!Conf['Catalog Links']) {
        return;
      }
      return CatalogLinks.set(Conf['Header catalog links']);
    },
    toggle: function() {
      $.event('CloseMenu');
      $.set('Header catalog links', this.checked);
      return CatalogLinks.set(this.checked);
    },
    set: function(useCatalog) {
      var a, board, k, len1, ref, ref1;
      ref = $$('a:not([data-only])', Header.boardList).concat($$('a', Header.bottomBoardList));
      for (k = 0, len1 = ref.length; k < len1; k++) {
        a = ref[k];
        if (((ref1 = a.hostname) !== 'boards.4chan.org' && ref1 !== 'catalog.neet.tv') || !(board = a.pathname.split('/')[1]) || (board === 'f' || board === 'status' || board === '4chan') || a.pathname.split('/')[2] === 'archive' || $.hasClass(a, 'external')) {
          continue;
        }
        a.href = useCatalog ? CatalogLinks.catalog(board) : "/" + board + "/";
        if (a.dataset.indexOptions && a.hostname === 'boards.4chan.org' && a.pathname.split('/')[2] === '') {
          a.href += (a.hash ? '/' : '#') + a.dataset.indexOptions;
        }
      }
      CatalogLinks.el.title = "Turn catalog links " + (useCatalog ? 'off' : 'on') + ".";
      return $('input', CatalogLinks.el).checked = useCatalog;
    },
    catalog: function(board) {
      if (board == null) {
        board = g.BOARD.ID;
      }
      if (Conf['External Catalog'] && (board === 'a' || board === 'c' || board === 'g' || board === 'biz' || board === 'k' || board === 'm' || board === 'o' || board === 'p' || board === 'v' || board === 'vg' || board === 'vr' || board === 'w' || board === 'wg' || board === 'cm' || board === '3' || board === 'adv' || board === 'an' || board === 'asp' || board === 'cgl' || board === 'ck' || board === 'co' || board === 'diy' || board === 'fa' || board === 'fit' || board === 'gd' || board === 'int' || board === 'jp' || board === 'lit' || board === 'mlp' || board === 'mu' || board === 'n' || board === 'out' || board === 'po' || board === 'sci' || board === 'sp' || board === 'tg' || board === 'toy' || board === 'trv' || board === 'tv' || board === 'vp' || board === 'wsg' || board === 'x' || board === 'f' || board === 'pol' || board === 's4s' || board === 'lgbt')) {
        return "http://catalog.neet.tv/" + board + "/";
      } else if (Conf['JSON Index'] && Conf['Use 4chan X Catalog']) {
        if (g.BOARD.ID === board && g.VIEW === 'index') {
          return '#catalog';
        } else {
          return "/" + board + "/#catalog";
        }
      } else {
        return "/" + board + "/catalog";
      }
    },
    index: function(board) {
      if (board == null) {
        board = g.BOARD.ID;
      }
      if (Conf['JSON Index'] && board !== 'f') {
        if (g.BOARD.ID === board && g.VIEW === 'index') {
          return '#index';
        } else {
          return "/" + board + "/#index";
        }
      } else {
        return "/" + board + "/";
      }
    }
  };

  CustomCSS = {
    init: function() {
      if (!Conf['Custom CSS']) {
        return;
      }
      return this.addStyle();
    },
    addStyle: function() {
      return this.style = $.addStyle(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 = Conf['usercss'];
    }
  };

  ExpandComment = {
    init: function() {
      if (g.VIEW !== 'index' || !Conf['Comment Expansion'] || Conf['JSON Index']) {
        return;
      }
      if (g.BOARD.ID === 'g') {
        this.callbacks.push(Fourchan.code);
      }
      if (g.BOARD.ID === 'sci') {
        this.callbacks.push(Fourchan.math);
      }
      return Post.callbacks.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("//a.4cdn.org" + (a.pathname.split(/\/+/).splice(0, 4).join('/')) + ".json", 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, k, len1, len2, len3, postObj, posts, q, quote, ref, ref1, spoilerRange, status, u;
      status = req.status;
      if (status !== 200 && status !== 304) {
        a.textContent = "Error " + req.statusText + " (" + status + ")";
        return;
      }
      posts = req.response.posts;
      if (spoilerRange = posts[0].custom_spoiler) {
        Build.spoilerRange[g.BOARD] = spoilerRange;
      }
      for (k = 0, len1 = posts.length; k < len1; k++) {
        postObj = posts[k];
        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 (q = 0, len2 = ref.length; q < len2; q++) {
        quote = ref[q];
        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 (u = 0, len3 = ref1.length; u < len3; u++) {
        callback = ref1[u];
        callback.call(post);
      }
    }
  };

  ExpandThread = {
    statuses: {},
    init: function() {
      if (g.VIEW === 'thread' || !Conf['Thread Expansion']) {
        return;
      }
      if (Conf['JSON Index']) {
        return $.on(d, 'IndexRefresh', this.onIndexRefresh);
      } else {
        return Thread.callbacks.push({
          name: 'Expand Thread',
          cb: function() {
            return ExpandThread.setButton(this);
          }
        });
      }
    },
    setButton: function(thread) {
      var a;
      if (!(a = $.x('following-sibling::*[contains(@class,"summary")][1]', thread.OP.nodes.root))) {
        return;
      }
      a.textContent = ExpandThread.text.apply(ExpandThread, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
      a.style.cursor = 'pointer';
      return $.on(a, 'click', ExpandThread.cbToggle);
    },
    disconnect: function(refresh) {
      var ref, ref1, status, threadID;
      if (g.VIEW === 'thread' || !Conf['Thread Expansion']) {
        return;
      }
      ref = ExpandThread.statuses;
      for (threadID in ref) {
        status = ref[threadID];
        if ((ref1 = status.req) != null) {
          ref1.abort();
        }
        delete ExpandThread.statuses[threadID];
      }
      if (!refresh) {
        return $.off(d, 'IndexRefresh', this.onIndexRefresh);
      }
    },
    onIndexRefresh: function() {
      ExpandThread.disconnect(true);
      return g.BOARD.threads.forEach(function(thread) {
        return ExpandThread.setButton(thread);
      });
    },
    text: function(status, posts, files) {
      return (status + " " + posts + " post" + (posts > 1 ? 's' : '')) + (+files ? " and " + files + " image repl" + (files > 1 ? 'ies' : 'y') : "") + (" " + (status === '-' ? 'shown' : 'omitted') + ".");
    },
    cbToggle: function(e) {
      if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
        return;
      }
      e.preventDefault();
      return ExpandThread.toggle(Get.threadFromNode(this));
    },
    toggle: function(thread) {
      var a, threadRoot;
      threadRoot = thread.OP.nodes.root.parentNode;
      if (!(a = $('.summary', threadRoot))) {
        return;
      }
      if (thread.ID in ExpandThread.statuses) {
        return ExpandThread.contract(thread, a, threadRoot);
      } else {
        return ExpandThread.expand(thread, a);
      }
    },
    expand: function(thread, a) {
      var status;
      ExpandThread.statuses[thread] = status = {};
      a.textContent = ExpandThread.text.apply(ExpandThread, ['...'].concat(slice.call(a.textContent.match(/\d+/g))));
      return status.req = $.cache("//a.4cdn.org/" + thread.board + "/thread/" + thread + ".json", function() {
        delete status.req;
        return ExpandThread.parse(this, thread, a);
      });
    },
    contract: function(thread, a, threadRoot) {
      var filesCount, inlined, k, len1, num, postsCount, replies, reply, status;
      status = ExpandThread.statuses[thread];
      delete ExpandThread.statuses[thread];
      if (status.req) {
        status.req.abort();
        if (a) {
          a.textContent = ExpandThread.text.apply(ExpandThread, ['+'].concat(slice.call(a.textContent.match(/\d+/g))));
        }
        return;
      }
      replies = $$('.thread > .replyContainer', threadRoot);
      if (!Conf['JSON Index'] || Conf['Show Replies']) {
        num = (function() {
          if (thread.isSticky) {
            return 1;
          } else {
            switch (g.BOARD.ID) {
              case 'b':
              case 'vg':
                return 3;
              case 't':
                return 1;
              default:
                return 5;
            }
          }
        })();
        replies = replies.slice(0, -num);
      }
      postsCount = 0;
      filesCount = 0;
      for (k = 0, len1 = replies.length; k < len1; k++) {
        reply = replies[k];
        if (Conf['Quote Inlining']) {
          while (inlined = $('.inlined', reply)) {
            inlined.click();
          }
        }
        postsCount++;
        if ('file' in Get.postFromRoot(reply)) {
          filesCount++;
        }
        $.rm(reply);
      }
      return a.textContent = ExpandThread.text('+', postsCount, filesCount);
    },
    parse: function(req, thread, a) {
      var filesCount, k, len1, post, postData, posts, postsCount, postsRoot, ref, ref1, root;
      if ((ref = req.status) !== 200 && ref !== 304) {
        a.textContent = "Error " + req.statusText + " (" + req.status + ")";
        return;
      }
      Build.spoilerRange[thread.board] = req.response.posts[0].custom_spoiler;
      posts = [];
      postsRoot = [];
      filesCount = 0;
      ref1 = req.response.posts;
      for (k = 0, len1 = ref1.length; k < len1; k++) {
        postData = ref1[k];
        if (postData.no === thread.ID) {
          continue;
        }
        if ((post = thread.posts[postData.no]) && !post.isFetchedQuote) {
          if ('file' in post) {
            filesCount++;
          }
          postsRoot.push(post.nodes.root);
          continue;
        }
        root = 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');
      postsCount = postsRoot.length;
      return a.textContent = ExpandThread.text('-', postsCount, filesCount);
    }
  };

  FileInfo = {
    init: function() {
      var ref;
      if (((ref = g.VIEW) !== 'index' && ref !== 'thread') || !Conf['File Info Formatting']) {
        return;
      }
      return Post.callbacks.push({
        name: 'File Info Formatting',
        cb: this.node
      });
    },
    node: function() {
      var info, oldInfo;
      if (!this.file || this.isClone) {
        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 output;
      output = [];
      formatString.replace(/%(.)|[^%]+/g, function(s, c) {
        output.push(c in FileInfo.formatters ? FileInfo.formatters[c].call(post) : {
          innerHTML: E(s)
        });
        return '';
      });
      return $.extend(outputNode, {
        innerHTML: E.cat(output)
      });
    },
    formatters: {
      t: function() {
        return {
          innerHTML: E(this.file.url.match(/[^/]*$/)[0])
        };
      },
      T: function() {
        return {
          innerHTML: "<a href=\"" + E(this.file.url) + "\" target=\"_blank\">" + FileInfo.formatters.t.call(this).innerHTML + "</a>"
        };
      },
      l: function() {
        return {
          innerHTML: "<a href=\"" + E(this.file.url) + "\" target=\"_blank\">" + FileInfo.formatters.n.call(this).innerHTML + "</a>"
        };
      },
      L: function() {
        return {
          innerHTML: "<a href=\"" + E(this.file.url) + "\" target=\"_blank\">" + FileInfo.formatters.N.call(this).innerHTML + "</a>"
        };
      },
      n: function() {
        var fullname, shortname;
        fullname = this.file.name;
        shortname = Build.shortFilename(this.file.name, this.isReply);
        if (fullname === shortname) {
          return {
            innerHTML: E(fullname)
          };
        } else {
          return {
            innerHTML: "<span class=\"fnswitch\"><span class=\"fntrunc\">" + E(shortname) + "</span><span class=\"fnfull\">" + E(fullname) + "</span></span>"
          };
        }
      },
      N: function() {
        return {
          innerHTML: E(this.file.name)
        };
      },
      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: "%"
        };
      }
    }
  };

  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();
        });
      }
    }
  };

  Fourchan = {
    init: function() {
      var ref;
      if ((ref = g.VIEW) !== 'index' && ref !== 'thread') {
        return;
      }
      if (g.BOARD.ID === 'g') {
        $.on(window, 'prettyprint:cb', function(e) {
          var post, pre;
          if (!(post = g.posts[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');
          }
        });
        $.globalEval('window.addEventListener(\'prettyprint\', function(e) {\n  window.dispatchEvent(new CustomEvent(\'prettyprint:cb\', {\n    detail: {\n      ID:   e.detail.ID,\n      i:    e.detail.i,\n      html: prettyPrintOne(e.detail.html)\n    }\n  }));\n}, false);');
        Post.callbacks.push({
          name: 'Parse /g/ code',
          cb: this.code
        });
      }
      if (g.BOARD.ID === 'sci') {
        $.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);
        });
        Post.callbacks.push({
          name: 'Parse /sci/ math',
          cb: this.math
        });
        CatalogThread.callbacks.push({
          name: 'Parse /sci/ math',
          cb: this.math
        });
      }
      return Main.ready(function() {
        return $.global(function() {
          var k, len1, node, ref1;
          window.clickable_ids = false;
          ref1 = document.querySelectorAll('.posteruid, .capcode');
          for (k = 0, len1 = ref1.length; k < len1; k++) {
            node = ref1[k];
            node.removeEventListener('click', window.idClick, false);
          }
        });
      });
    },
    code: function() {
      if (this.isClone) {
        return;
      }
      return $.ready((function(_this) {
        return function() {
          var i, k, len1, pre, ref;
          ref = $$('.prettyprint', _this.nodes.comment);
          for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
            pre = ref[i];
            if (!$.hasClass(pre, 'prettyprinted')) {
              $.event('prettyprint', {
                ID: _this.fullID,
                i: i,
                html: pre.innerHTML
              }, window);
            }
          }
        };
      })(this));
    },
    math: function() {
      var cb, k, len1, wbr, wbrs;
      if (!/\[(math|eqn)\]/.test(this.nodes.comment.textContent)) {
        return;
      }
      if ((wbrs = $$('wbr', this.nodes.comment)).length) {
        for (k = 0, len1 = wbrs.length; k < len1; k++) {
          wbr = wbrs[k];
          $.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();
    }
  };

  IDColor = {
    init: function() {
      var ref;
      if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Color User IDs'])) {
        return;
      }
      this.ids = {
        Heaven: [0, 0, 0, '#fff']
      };
      return Post.callbacks.push({
        name: 'Color User IDs',
        cb: this.node
      });
    },
    node: function() {
      var rgb, span, style, uid;
      if (this.isClone || !((uid = this.info.uniqueID) && (span = $('span.hand', 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 = IDColor.hash(uid);
      rgb = [(hash >> 24) & 0xFF, (hash >> 16) & 0xFF, (hash >> 8) & 0xFF];
      rgb.push((rgb[0] * 0.299 + rgb[1] * 0.587 + rgb[2] * 0.114) > 125 ? '#000' : '#fff');
      return this.ids[uid] = rgb;
    },
    hash: function(uid) {
      var i, msg;
      msg = 0;
      i = 0;
      while (i < 8) {
        msg = (msg << 5) - msg + uid.charCodeAt(i++);
      }
      return msg;
    }
  };

  IDHighlight = {
    init: function() {
      var ref;
      if ((ref = g.VIEW) !== 'index' && ref !== 'thread') {
        return;
      }
      return Post.callbacks.push({
        name: 'Highlight by User ID',
        cb: this.node
      });
    },
    uniqueID: null,
    node: function() {
      if (this.nodes.uniqueID) {
        $.on(this.nodes.uniqueID, '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);
      };
    }
  };

  Keybinds = {
    init: function() {
      var hotkey, init;
      if (!Conf['Keybinds']) {
        return;
      }
      for (hotkey in Config.hotkeys) {
        $.sync(hotkey, Keybinds.sync);
      }
      init = function() {
        var k, len1, node, ref;
        $.off(d, '4chanXInitFinished', init);
        $.on(d, 'keydown', Keybinds.keydown);
        ref = $$('[accesskey]');
        for (k = 0, len1 = ref.length; k < len1; k++) {
          node = ref[k];
          node.removeAttribute('accesskey');
        }
      };
      return $.on(d, '4chanXInitFinished', init);
    },
    sync: function(key, hotkey) {
      return Conf[hotkey] = key;
    },
    keydown: function(e) {
      var form, k, key, len1, notification, notifications, op, ref, ref1, ref2, ref3, ref4, ref5, 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') || g.VIEW === 'index' && Conf['JSON Index'] && Conf['Index Mode'] === 'catalog' || g.VIEW === 'index' && g.BOARD.ID === 'f')) {
        threadRoot = Nav.getThread();
        if (op = $('.op', threadRoot)) {
          thread = Get.postFromNode(op).thread;
        }
      }
      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 (k = 0, len1 = notifications.length; k < len1; k++) {
              notification = notifications[k];
              $('.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['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 (!Conf['Thread Updater']) {
                return;
              }
              ThreadUpdater.update();
              break;
            case 'index':
              if (!(Conf['JSON Index'] && g.BOARD.ID !== 'f')) {
                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['Expand image']:
          if (!(ImageExpand.enabled && threadRoot)) {
            return;
          }
          Keybinds.img(threadRoot);
          break;
        case Conf['Expand images']:
          if (!(ImageExpand.enabled && threadRoot)) {
            return;
          }
          Keybinds.img(threadRoot, true);
          break;
        case Conf['Open Gallery']:
          if (!Gallery.enabled) {
            return;
          }
          Gallery.cb.toggle();
          break;
        case Conf['fappeTyme']:
          if (!(Conf['Fappe Tyme'] && ((ref2 = g.VIEW) === 'index' || ref2 === 'thread'))) {
            return;
          }
          FappeTyme.toggle('fappe');
          break;
        case Conf['werkTyme']:
          if (!(Conf['Werk Tyme'] && ((ref3 = g.VIEW) === 'index' || ref3 === 'thread'))) {
            return;
          }
          FappeTyme.toggle('werk');
          break;
        case Conf['Front page']:
          if (Conf['JSON Index'] && g.VIEW === 'index' && g.BOARD.ID !== 'f') {
            Index.userPageNav(1);
          } else {
            window.location = "/" + g.BOARD + "/";
          }
          break;
        case Conf['Open front page']:
          $.open("/" + g.BOARD + "/");
          break;
        case Conf['Next page']:
          if (!(g.VIEW === 'index' && g.BOARD.ID !== 'f')) {
            return;
          }
          if (Conf['JSON Index']) {
            if ((ref4 = Conf['Index Mode']) !== 'paged' && ref4 !== 'infinite') {
              return;
            }
            $('.next button', Index.pagelist).click();
          } else {
            if (form = $('.next form')) {
              window.location = form.action;
            }
          }
          break;
        case Conf['Previous page']:
          if (!(g.VIEW === 'index' && g.BOARD.ID !== 'f')) {
            return;
          }
          if (Conf['JSON Index']) {
            if ((ref5 = Conf['Index Mode']) !== 'paged' && ref5 !== 'infinite') {
              return;
            }
            $('.prev button', Index.pagelist).click();
          } else {
            if (form = $('.prev form')) {
              window.location = form.action;
            }
          }
          break;
        case Conf['Search form']:
          if (!(g.VIEW === 'index' && g.BOARD.ID !== 'f')) {
            return;
          }
          searchInput = Conf['JSON Index'] ? Index.searchInput : $.id('search-box');
          Header.scrollToIfNeeded(searchInput);
          searchInput.focus();
          break;
        case Conf['Paged mode']:
          if (!(Conf['JSON Index'] && g.BOARD.ID !== 'f')) {
            return;
          }
          window.location = g.VIEW === 'index' ? '#paged' : "/" + g.BOARD + "/#paged";
          break;
        case Conf['Infinite scrolling mode']:
          if (!(Conf['JSON Index'] && g.BOARD.ID !== 'f')) {
            return;
          }
          window.location = g.VIEW === 'index' ? '#infinite' : "/" + g.BOARD + "/#infinite";
          break;
        case Conf['All pages mode']:
          if (!(Conf['JSON Index'] && g.BOARD.ID !== 'f')) {
            return;
          }
          window.location = g.VIEW === 'index' ? '#all-pages' : "/" + g.BOARD + "/#all-pages";
          break;
        case Conf['Open catalog']:
          if (g.BOARD.ID === 'f') {
            return;
          }
          window.location = CatalogLinks.catalog();
          break;
        case Conf['Cycle sort type']:
          if (!(Conf['JSON Index'] && g.VIEW === 'index' && g.BOARD.ID !== 'f')) {
            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);
          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) {
            return;
          }
          if (ThreadHiding.db) {
            ThreadHiding.toggle(thread);
          }
          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;
    },
    qr: function(thread) {
      QR.open();
      if (thread != null) {
        QR.quote.call($('input', $('.post.highlight', thread) || thread));
      }
      return QR.nodes.com.focus();
    },
    tags: function(tag, ta) {
      var range, selEnd, selStart, supported, value;
      supported = (function() {
        switch (tag) {
          case 'spoiler':
            return !!$('.postForm input[name=spoiler]');
          case 'code':
            return g.BOARD.ID === 'g';
          case 'math':
          case 'eqn':
            return g.BOARD.ID === 'sci';
          case 'sjis':
            return g.BOARD.ID === 'jp';
        }
      })();
      if (!supported) {
        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";
    },
    img: function(thread, all) {
      var post;
      if (all) {
        return ImageExpand.cb.toggleAll();
      } else {
        post = Get.postFromNode($('.post.highlight', thread) || $('.op', thread));
        return ImageExpand.toggle(post);
      }
    },
    open: function(thread, tab) {
      var url;
      if (g.VIEW !== 'index') {
        return;
      }
      url = "/" + thread.board + "/thread/" + thread;
      if (tab) {
        return $.open(url);
      } else {
        return location.href = url;
      }
    },
    hl: function(delta, thread) {
      var axis, height, k, len1, next, postEl, replies, reply, root;
      postEl = $('.reply.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 = postEl.parentNode;
          axis = delta === +1 ? 'following' : 'preceding';
          if (!(next = $.x(axis + "-sibling::div[contains(@class,'replyContainer') and not(@hidden) and not(child::div[@class='stub'])][1]/child::div[contains(@class,'reply')]", root))) {
            return;
          }
          Header.scrollToIfNeeded(next, delta === +1);
          this.focus(next);
          $.rmClass(postEl, 'highlight');
          return;
        }
        $.rmClass(postEl, 'highlight');
      }
      replies = $$('.reply', thread);
      if (delta === -1) {
        replies.reverse();
      }
      for (k = 0, len1 = replies.length; k < len1; k++) {
        reply = replies[k];
        if (delta === +1 && Header.getTopOf(reply) > 0 || delta === -1 && Header.getBottomOf(reply) > 0) {
          this.focus(reply);
          return;
        }
      }
    },
    focus: function(post) {
      return $.addClass(post, 'highlight');
    }
  };

  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 k, len1, ref, thread, threadRoot;
      ref = $$('.thread');
      for (k = 0, len1 = ref.length; k < len1; k++) {
        threadRoot = ref[k];
        thread = Get.threadFromRoot(threadRoot);
        if (thread.isHidden && !thread.stub) {
          continue;
        }
        if (Header.getTopOf(threadRoot) >= -threadRoot.getBoundingClientRect().height) {
          return threadRoot;
        }
      }
      return $('.board');
    },
    scroll: function(delta) {
      var axis, extra, next, ref, thread, top;
      if ((ref = d.activeElement) != null) {
        ref.blur();
      }
      thread = Nav.getThread();
      axis = delta === +1 ? 'following' : 'preceding';
      if (next = $.x(axis + "-sibling::div[contains(@class,'thread') and 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 = null;
        delete Nav.haveExtra;
        return $.off(d, 'scroll', Nav.removeExtra);
      }
    }
  };

  NormalizeURL = {
    init: function() {
      var pathname;
      if (!Conf['Normalize URL']) {
        return;
      }
      pathname = location.pathname.split(/\/+/);
      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);
      }
    }
  };

  RelativeDates = {
    INTERVAL: $.MINUTE / 2,
    init: function() {
      var ref;
      if (((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Relative Post Dates'] && !Conf['Relative Date Title'] || g.VIEW === 'index' && Conf['JSON Index'] && g.BOARD.ID !== 'f') {
        this.flush();
        $.on(d, 'visibilitychange ThreadUpdate', this.flush);
      }
      if (Conf['Relative Post Dates']) {
        return Post.callbacks.push({
          name: 'Relative Post Dates',
          cb: this.node
        });
      }
    },
    node: function() {
      var dateEl;
      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) {
      var days, months, number, rounded, unit, years;
      unit = (number = diff / $.DAY) >= 1 ? (years = now.getYear() - date.getYear(), 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 (rounded !== 1) {
        unit += 's';
      }
      return rounded + " " + unit + " ago";
    },
    stale: [],
    flush: function() {
      var data, k, len1, now, ref;
      if (d.hidden) {
        return;
      }
      now = new Date();
      ref = RelativeDates.stale;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        data = ref[k];
        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 date, diff, isPost, k, len1, ref, relative, singlePost;
      isPost = data instanceof Post;
      date = isPost ? data.info.date : new Date(+data.dataset.utc);
      now || (now = new Date());
      diff = now - date;
      relative = RelativeDates.relative(diff, now, date);
      if (isPost) {
        ref = [data].concat(data.clones);
        for (k = 0, len1 = ref.length; k < len1; k++) {
          singlePost = ref[k];
          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[data.fullID]) {
        return;
      }
      return RelativeDates.stale.push(data);
    }
  };

  RemoveSpoilers = {
    init: function() {
      if (Conf['Reveal Spoilers']) {
        $.addClass(doc, 'reveal-spoilers');
      }
      if (!Conf['Remove Spoilers']) {
        return;
      }
      Post.callbacks.push({
        name: 'Reveal Spoilers',
        cb: this.node
      });
      CatalogThread.callbacks.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 k, len1, span, spoiler, spoilers;
      spoilers = $$('s', el);
      for (k = 0, len1 = spoilers.length; k < len1; k++) {
        spoiler = spoilers[k];
        span = $.el('span', {
          className: 'removed-spoiler'
        });
        $.replace(spoiler, span);
        $.add(span, slice.call(spoiler.childNodes));
      }
    }
  };

  Report = {
    css: "#g-recaptcha,\n" +
":root:not(.js-enabled) #captchaContainerAlt {\n" +
"  height: auto;\n" +
"}\n" +
"#captchaContainerAlt td:nth-child(2) {\n" +
"  display: table-cell !important;\n" +
"}",
    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() {
      var passAd, prev, ref;
      $.addStyle(Report.css);
      if (Conf['Archive Report']) {
        Report.archive();
      }
      if ((passAd = $('a[href="https://www.4chan.org/pass"]'))) {
        $.extend(passAd, {
          textContent: 'Complain',
          href: 'https://www.4chan-x.net/captchas.html',
          tabIndex: -1
        });
        passAd.parentNode.normalize();
        if (((ref = (prev = passAd.previousSibling)) != null ? ref.nodeType : void 0) === Node.TEXT_NODE) {
          prev.nodeValue = prev.nodeValue.replace(/4chan Pass[^\.]*\./i, 'reCAPTCHA malfunctioning?');
        }
        $.after(passAd, [
          $.tn('] ['), $.el('a', {
            href: 'mailto:[email protected]?subject=4chan%20Pass%20-%20Purchase%20Support',
            textContent: 'Email 4chan',
            target: '_blank',
            tabIndex: -1
          })
        ]);
      }
      if (!Conf['Use Recaptcha v1 in Reports'] && !Conf['Force Noscript Captcha'] && Main.jsEnabled) {
        return 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
        });
      } else {
        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 link, message, types, url;
      Redirect.init();
      if (!(url = Redirect.to('report', {
        boardID: g.BOARD.ID,
        postID: Report.postID
      }))) {
        return;
      }
      if ((message = $('h3')) && /Report submitted!/.test(message.textContent)) {
        if (location.hash === '#redirect') {
          $.globalEval('self.close = function(){};');
          window.resizeTo(700, 475);
          location.replace(url);
        }
        return;
      }
      link = $.el('a', {
        href: url,
        textContent: 'Report to archive'
      });
      $.on(link, 'click', function(e) {
        if (!(e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0)) {
          return window.resizeTo(700, 475);
        }
      });
      $.add(d.body, [$.tn(' ['), link, $.tn(']')]);
      if (types = $.id('reportTypes')) {
        return $.on(types, 'change', function(e) {
          return $('form').action = e.target.value === 'illegal' ? '#redirect' : '';
        });
      }
    }
  };

  ThreadLinks = {
    init: function() {
      if (!(g.VIEW === 'index' && Conf['Open Threads in New Tab'])) {
        return;
      }
      Post.callbacks.push({
        name: 'Thread Links',
        cb: this.node
      });
      return CatalogThread.callbacks.push({
        name: 'Thread Links',
        cb: this.catalogNode
      });
    },
    node: function() {
      if (this.isReply || this.isClone) {
        return;
      }
      return ThreadLinks.process($('.replylink', this.nodes.info));
    },
    catalogNode: function() {
      return ThreadLinks.process(this.nodes.thumb.parentNode);
    },
    process: function(link) {
      return link.target = '_blank';
    }
  };

  Time = {
    init: function() {
      var ref;
      if (!(((ref = g.VIEW) === 'index' || ref === 'thread') && Conf['Time Formatting'])) {
        return;
      }
      return Post.callbacks.push({
        name: 'Time Formatting',
        cb: this.node
      });
    },
    node: function() {
      if (this.isClone) {
        return;
      }
      return this.nodes.date.textContent = Time.format(Conf['time'], this.info.date);
    },
    format: function(formatString, date) {
      return formatString.replace(/%(.)/g, function(s, c) {
        if (c in Time.formatters) {
          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'],
    zeroPad: function(n) {
      if (n < 10) {
        return "0" + n;
      } else {
        return n;
      }
    },
    formatters: {
      a: function() {
        return Time.day[this.getDay()].slice(0, 3);
      },
      A: function() {
        return Time.day[this.getDay()];
      },
      b: function() {
        return Time.month[this.getMonth()].slice(0, 3);
      },
      B: function() {
        return 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() {
        if (this.getHours() < 12) {
          return 'AM';
        } else {
          return 'PM';
        }
      },
      P: function() {
        if (this.getHours() < 12) {
          return 'am';
        } else {
          return 'pm';
        }
      },
      S: function() {
        return Time.zeroPad(this.getSeconds());
      },
      y: function() {
        return this.getFullYear().toString().slice(2);
      },
      Y: function() {
        return this.getFullYear();
      },
      '%': function() {
        return '%';
      }
    }
  };

  Settings = {
    init: function() {
      var add, link, settings;
      link = $.el('a', {
        className: 'settings-link fa fa-wrench',
        textContent: 'Settings',
        title: '4chan X Settings',
        href: 'javascript:;'
      });
      $.on(link, 'click', Settings.open);
      Header.addShortcut(link);
      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 (Conf['Disable Native Extension']) {
        if ($.hasStorage) {
          settings = JSON.parse(localStorage.getItem('4chan-settings')) || {};
          if (settings.disableAll) {
            return;
          }
          settings.disableAll = true;
          return localStorage.setItem('4chan-settings', JSON.stringify(settings));
        } else {
          return $.onExists(doc, 'body', function() {
            return $.global(function() {
              return window.Config.disableAll = true;
            });
          });
        }
      }
    },
    open: function(openSection) {
      var dialog, k, len1, link, links, overlay, ref, section, sectionToOpen;
      if (Settings.overlay) {
        return;
      }
      $.event('CloseMenu');
      Settings.dialog = dialog = $.el('div', {
        id: 'fourchanx-settings',
        className: 'dialog'
      });
      $.extend(dialog, {
        innerHTML: "<nav><div class=\"sections-list\"></div><p class=\"imp-exp-result warning\"></p><div class=\"credits\"><a class=\"export\">Export</a>&nbsp|&nbsp<a class=\"import\">Import</a>&nbsp|&nbsp<a class=\"reset\">Reset Settings</a>&nbsp|&nbsp<input type=\"file\" hidden><a href=\"https://www.4chan-x.net/\" target=\"_blank\">4chan X</a>&nbsp|&nbsp<a href=\"https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md\" target=\"_blank\">" + E(g.VERSION) + "</a>&nbsp|&nbsp<a href=\"https://gitreports.com/issue/ccd0/4chan-x\" target=\"_blank\">Issues</a>&nbsp|&nbsp<a href=\"javascript:;\" class=\"close fa fa-times\" title=\"Close\"></a></div></nav><div class=\"section-container\"><section></section></div>"
      });
      Settings.overlay = overlay = $.el('div', {
        id: 'overlay'
      });
      $.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 (k = 0, len1 = ref.length; k < len1; k++) {
        section = ref[k];
        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(overlay, 'click', Settings.close);
      $.add(d.body, [overlay, dialog]);
      return $.event('OpenSettings', null, dialog);
    },
    close: function() {
      var ref;
      if (!Settings.dialog) {
        return;
      }
      if ((ref = d.activeElement) != null) {
        ref.blur();
      }
      $.rm(Settings.overlay);
      $.rm(Settings.dialog);
      delete Settings.overlay;
      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.4chan.org in your browser's privacy settings (may be listed as part of \"local data\" or \"cookies\")."
          }));
        }
      },
      ads: function(cb) {
        return $.onExists(doc, '.ad-cnt', function(ad) {
          return $.onExists(ad, 'img', function() {
            return cb($.el('li', {
              innerHTML: "To protect yourself from <a href=\"https://archive.rebeccablacktech.com/qa/thread/362590\" target=\"_blank\">malicious ads</a>, you should <a href=\"https://github.com/gorhill/uBlock#ublock-origin\" target=\"_blank\">block ads</a> on 4chan."
            }));
          });
        });
      }
    },
    main: function(section) {
      var addWarning, arr, button, container, containers, description, div, fs, input, inputs, items, key, level, obj, ref, ref1, warning, warnings;
      warnings = $.el('fieldset', {
        hidden: true
      }, {
        innerHTML: "<legend>Warnings</legend><ul></ul>"
      });
      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 = {};
      inputs = {};
      ref1 = Config.main;
      for (key in ref1) {
        obj = ref1[key];
        fs = $.el('fieldset', {
          innerHTML: "<legend>" + E(key) + "</legend>"
        });
        containers = [fs];
        for (key in obj) {
          arr = obj[key];
          description = arr[1];
          div = $.el('div', {
            innerHTML: "<label><input type=\"checkbox\" name=\"" + E(key) + "\">" + E(key) + "</label><span class=\"description\">: " + E(description) + "</span>"
          });
          if ($.engine !== 'gecko' && key === 'Remember QR Size') {
            div.hidden = true;
          }
          input = $('input', div);
          $.on(input, 'change', function() {
            this.parentNode.parentNode.dataset.checked = this.checked;
            return $.cb.checked.call(this);
          });
          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));
          }
          $.add(containers[level], div);
        }
        $.add(section, fs);
      }
      $.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: "<button></button><span class=\"description\">: Clear manually-hidden threads and posts on all boards. Reload the page to apply."
      });
      button = $('button', div);
      $.get({
        hiddenThreads: {},
        hiddenPosts: {}
      }, function(arg) {
        var ID, board, hiddenNum, hiddenPosts, hiddenThreads, ref2, ref3, thread;
        hiddenThreads = arg.hiddenThreads, hiddenPosts = arg.hiddenPosts;
        hiddenNum = 0;
        ref2 = hiddenThreads.boards;
        for (ID in ref2) {
          board = ref2[ID];
          hiddenNum += Object.keys(board).length;
        }
        ref3 = hiddenPosts.boards;
        for (ID in ref3) {
          board = ref3[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', {}, function(arg) {
          var boardID, hiddenThreads;
          hiddenThreads = arg.hiddenThreads;
          if ($.hasStorage) {
            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() {
      return $.get(Conf, function(Conf) {
        return Settings.downloadExport({
          version: g.VERSION,
          date: Date.now(),
          Conf: Conf
        });
      });
    },
    downloadExport: function(data) {
      var a, p;
      a = $.el('a', {
        download: "4chan X v" + g.VERSION + "-" + data.date + ".json",
        href: "data:application/json;base64," + (btoa(unescape(encodeURIComponent(JSON.stringify(data, null, 2)))))
      });
      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(JSON.parse(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 base1, 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': '',
          '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',
          'Reveal Spoilers': 'Reveal Spoiler Thumbnails',
          'Expand From Current': 'Expand from here',
          'Post in Title': 'Thread Excerpt',
          'Current Page': 'Page Count in Stats',
          'Current Page Position': '',
          'Alternative captcha': 'Use Recaptcha v1',
          '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',
          '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': ''
        });
        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'] = {
            boards: {}
          };
          ref1 = data.WatchedThreads;
          for (boardID in ref1) {
            threads = ref1[boardID];
            for (threadID in threads) {
              threadData = threads[threadID];
              ((base1 = data.Conf['watchedThreads'].boards)[boardID] || (base1[boardID] = {}))[threadID] = {
                excerpt: threadData.textContent
              };
            }
          }
        }
        return data;
      }
    },
    upgrade: function(data, version) {
      var boardID, changes, compareString, k, key, len1, name, record, ref, ref1, ref2, ref3, ref4, ref5, rice, set, type, uids, value;
      changes = {};
      set = function(key, value) {
        return data[key] = changes[key] = value;
      };
      compareString = version.replace(/\d+/g, function(x) {
        return ('0000' + x).slice(-5);
      });
      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 (name in uids) {
                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 (k = 0, len1 = ref3.length; k < len1; k++) {
          key = ref3[k];
          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.overlay) {
        $.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);
        }
      }
      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 name=\"filter\"><option value=\"guide\">Guide</option><option value=\"postID\">Post number</option><option value=\"name\">Name</option><option value=\"uniqueID\">Unique ID</option><option value=\"tripcode\">Tripcode</option><option value=\"capcode\">Capcode</option><option value=\"subject\">Subject</option><option value=\"comment\">Comment</option><option value=\"flag\">Flag</option><option value=\"filename\">Filename</option><option value=\"dimensions\">Image dimensions</option><option value=\"filesize\">Filesize</option><option value=\"MD5\">Image MD5</option></select><div></div>"
      });
      select = $('select', section);
      $.on(select, 'change', Settings.selectFilter);
      return Settings.selectFilter.call(select);
    },
    selectFilter: function() {
      var div, name, ta;
      div = this.nextElementSibling;
      if ((name = this.value) !== 'guide') {
        $.rmAll(div);
        ta = $.el('textarea', {
          name: name,
          className: 'field',
          spellcheck: false
        });
        $.get(name, Conf[name], function(item) {
          return ta.value = item[name];
        });
        $.on(ta, 'change', $.cb.value);
        $.add(div, ta);
        return;
      }
      $.extend(div, {
        innerHTML: "<div class=\"warning\"><code>Filter</code> is disabled.</div><p>Use <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\" target=\"_blank\">regular expressions</a>, one per line.<br>Lines starting with a <code>#</code> will be ignored.<br>For example, <code>/weeaboo/i</code> will filter posts containing the string \`<code>weeaboo</code>\`, case-insensitive.<br>MD5 filtering uses exact string matching, not regular expressions.</p><ul>You can use these settings with each regular expression, separate them with semicolons:<li>Per boards, separate them with commas. It is global if not specified.<br>For example: <code>boards:a,jp;</code>.</li><li>In case of a global rule, select boards to be excluded from the filter.<br>For example: <code>exclude:vg,v;</code>.</li><li>Filter OPs only along with their threads (\`only\`), replies only (\`no\`), or both (\`yes\`, this is default).<br>For example: <code>op:only;</code>, <code>op:no;</code> or <code>op:yes;</code>.</li><li>Overrule the \`Show Stubs\` setting if specified: create a stub (\`yes\`) or not (\`no\`).<br>For example: <code>stub:yes;</code> or <code>stub:no;</code>.</li><li>Highlight instead of hiding. You can specify a class name to use with a userstyle.<br>For example: <code>highlight;</code> or <code>highlight:wallpaper;</code>.</li><li>Highlighted OPs will have their threads put on top of the board index by default.<br>For example: <code>top:yes;</code> or <code>top:no;</code>.</li></ul><p>Note: If you&#039;re using the native catalog rather than 4chan X&#039;s catalog, 4chan X&#039;s filters do not apply there.<br>The native catalog has its own separate filter list.</p>"
      });
      return $('.warning', div).hidden = Conf['Filter'];
    },
    sauce: function(section) {
      var ta;
      $.extend(section, {
        innerHTML: "<div class=\"warning\"><code>Sauce</code> is disabled.</div><div>Lines starting with a <code>#</code> will be ignored.</div><div>You can specify a display text by appending <code>;text:[text]</code> to the URL.</div><div>You can specify the applicable boards by appending <code>;boards:[board1],[board2]</code>.</div><div>You can specify the applicable file types by appending <code>;types:[extension1],[extension2]</code>.</div><div>You can open links with scripts and popups disabled by appending <code>;sandbox</code>.</div><ul>These parameters will be replaced by their corresponding values:<li><code>%TURL</code>: Thumbnail URL.</li><li><code>%URL</code>: Full image URL.</li><li><code>%IMG</code>: Full image URL for GIF, JPG, and PNG; thumbnail URL for other types.</li><li><code>%MD5</code>: MD5 hash in base64.</li><li><code>%sMD5</code>: MD5 hash in base64 using <code>-</code> and <code>_</code>.</li><li><code>%hMD5</code>: MD5 hash in hexadecimal.</li><li><code>%name</code>: Original file name.</li><li><code>%board</code>: Current board.</li><li><code>%%</code>, <code>%semi</code>: Literal <code>%</code> and <code>;</code>.</li></ul><textarea name=\"sauces\" class=\"field\" spellcheck=\"false\"></textarea>"
      });
      $('.warning', section).hidden = Conf['Sauce'];
      ta = $('textarea', section);
      $.get('sauces', Conf['sauces'], function(item) {
        return ta.value = item['sauces'];
      });
      return $.on(ta, 'change', $.cb.value);
    },
    advanced: function(section) {
      var aa, ab, applyCSS, archBoards, archive, boardID, boardOptions, boardSelect, boards, customCSS, files, i, input, inputs, interval, item, items, k, len1, len2, len3, len4, len5, len6, len7, name, o, q, ref, ref1, ref2, ref3, ref4, ref5, ref6, row, rows, software, ta, table, u, uid, v, warning, withCredentials, z;
      $.extend(section, {
        innerHTML: "<fieldset><legend>Archiver</legend><div class=\"warning\" data-feature=\"404 Redirect\"><code>404 Redirect</code> is disabled.</div><select id=\"archive-board-select\"></select><table id=\"archive-table\"><thead><th>Thread redirection</th><th>Post fetching</th><th>File redirection</th></thead><tbody></tbody></table></fieldset><fieldset><legend>Captcha Language</legend><div>Choose from <a href=\"https://developers.google.com/recaptcha/docs/language\" target=\"_blank\">list of language codes</a>. Leave blank to autoselect.</div><div><input name=\"captchaLanguage\" class=\"field\" spellcheck=\"false\"></div></fieldset><fieldset><legend>Custom Board Navigation</legend><div><textarea name=\"boardnav\" class=\"field\" spellcheck=\"false\"></textarea></div><span class=\"note\">New lines will be converted into spaces.</span><br><br><div class=\"note\">In the following examples for /g/, <code>g</code> can be changed to a different board ID (<code>a</code>, <code>b</code>, etc...), the current board (<code>current</code>), or the Twitter link (<code>@</code>).</div><div>Board link: <code>g</code></div><div>Archive link: <code>g-archive</code></div><div>Internal archive link: <code>g-expired</code></div><div>Title link: <code>g-title</code></div><div>Board link (Replace with title when on that board): <code>g-replace</code></div><div>Full text link: <code>g-full</code></div><div>Custom text link: <code>g-text:&quot;Install Gentoo&quot;</code></div><div>Index-only link: <code>g-index</code></div><div>Catalog-only link: <code>g-catalog</code></div><div>Index mode: <code>g-mode:&quot;infinite scrolling&quot;</code></div><div>Index sort: <code>g-sort:&quot;creation date&quot;</code></div><div>External link: <code>external-text:&quot;Google&quot;,&quot;http://www.google.com&quot;</code></div><div>Combinations are possible: <code>g-index-text:&quot;Technology Index&quot;</code></div><div>Full board list toggle: <code>toggle-all</code></div><br><div class=\"note\"><code>[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:&quot;Piracy&quot;]</code><br>will give you<br><code>[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]</code><br>if you are on /g/.</div></fieldset><fieldset><legend>Time Formatting <span class=\"warning\" data-feature=\"Time Formatting\">is disabled.</span></legend><div><input name=\"time\" class=\"field\" spellcheck=\"false\">: <span class=\"time-preview\"></span></div><div>Supported <a href=\"http://man7.org/linux/man-pages/man1/date.1.html\" target=\"_blank\">format specifiers</a>:</div><div>Day: <code>%a</code>, <code>%A</code>, <code>%d</code>, <code>%e</code></div><div>Month: <code>%m</code>, <code>%b</code>, <code>%B</code></div><div>Year: <code>%y</code>, <code>%Y</code></div><div>Hour: <code>%k</code>, <code>%H</code>, <code>%l</code>, <code>%I</code>, <code>%p</code>, <code>%P</code></div><div>Minute: <code>%M</code></div><div>Second: <code>%S</code></div><div>Literal <code>%</code>: <code>%%</code></div></fieldset><fieldset><legend>Quote Backlinks formatting <span class=\"warning\" data-feature=\"Quote Backlinks\">is disabled.</span></legend><div><input name=\"backlink\" class=\"field\" spellcheck=\"false\">: <span class=\"backlink-preview\"></span></div></fieldset><fieldset><legend>File Info Formatting <span class=\"warning\" data-feature=\"File Info Formatting\">is disabled.</span></legend><div><input name=\"fileInfo\" class=\"field\" spellcheck=\"false\">: <span class=\"file-info file-info-preview\"></span></div><div>Link: <code>%l</code> (truncated), <code>%L</code> (untruncated), <code>%T</code> (4chan filename)</div><div>Filename: <code>%n</code> (truncated), <code>%N</code> (untruncated), <code>%t</code> (4chan filename)</div><div>Spoiler indicator: <code>%p</code></div><div>Size: <code>%B</code> (Bytes), <code>%K</code> (KB), <code>%M</code> (MB), <code>%s</code> (4chan default)</div><div>Resolution: <code>%r</code> (Displays &#039;PDF&#039; for PDF files)</div><div>Tag: <code>%g</code><div>Literal <code>%</code>: <code>%%</code></div></fieldset><fieldset><legend>Quick Reply Personas</legend><textarea class=\"personafield field\" name=\"QR.personas\" spellcheck=\"false\"></textarea><p>One item per line.<br>Items will be added in the relevant input&#039;s auto-completion list.<br>Password items will always be used, since there is no password input.<br>Lines starting with a <code>#</code> will be ignored.</p><ul>You can use these settings with each item, separate them with semicolons:<li>Possible items are: <code>name</code>, <code>options</code> (or equivalently <code>email</code>), <code>subject</code> and <code>password</code>.</li><li>Wrap values of items with quotes, like this: <code>options:&quot;sage&quot;</code>.</li><li>Force values as defaults with the <code>always</code> keyword, for example: <code>options:&quot;sage&quot;;always</code>.</li><li>Select specific boards for an item, separated with commas, for example: <code>options:&quot;sage&quot;;boards:jp;always</code>.</li></ul></fieldset><fieldset><legend>Unread Favicon <span class=\"warning\" data-feature=\"Unread Favicon\">is disabled.</span></legend><select name=\"favicon\"><option value=\"ferongr\">ferongr</option><option value=\"xat-\">xat-</option><option value=\"4chanJS\">4chanJS</option><option value=\"Mayhem\">Mayhem</option><option value=\"Original\">Original</option><option value=\"Metro\">Metro</option></select><span class=\"favicon-preview\"><img src=\"data:image/gif;base64,R0lGODlhEAAQAPAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAIOhI%2Bpy%2B0Po5y02ouzPgUAOw%3D%3D\"><img src=\"data:image/gif;base64,R0lGODlhEAAQAPAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAIOhI%2Bpy%2B0Po5y02ouzPgUAOw%3D%3D\"><img src=\"data:image/gif;base64,R0lGODlhEAAQAPAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAIOhI%2Bpy%2B0Po5y02ouzPgUAOw%3D%3D\"><img src=\"data:image/gif;base64,R0lGODlhEAAQAPAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAIOhI%2Bpy%2B0Po5y02ouzPgUAOw%3D%3D\"></span></fieldset><fieldset><legend>Thread Updater <span class=\"warning\" data-feature=\"Thread Updater\">is disabled.</span></legend><div>Interval: <input type=\"number\" name=\"Interval\" class=\"field\" min=\"1\"> seconds</div></fieldset><fieldset><legend>Custom Cooldown Time</legend><div>Seconds: <input type=\"number\" name=\"customCooldown\" class=\"field\" min=\"0\"></div></fieldset><fieldset><legend><label><input type=\"checkbox\" name=\"Custom CSS\"> Custom CSS</label></legend><button id=\"apply-css\">Apply CSS</button><textarea name=\"usercss\" class=\"field\" spellcheck=\"false\"></textarea></fieldset>"
      });
      ref = $$('.warning', section);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        warning = ref[k];
        warning.hidden = Conf[warning.dataset.feature];
      }
      items = {};
      inputs = {};
      ref1 = ['captchaLanguage', 'boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss', 'customCooldown'];
      for (q = 0, len2 = ref1.length; q < len2; q++) {
        name = ref1[q];
        input = $("[name='" + name + "']", section);
        items[name] = Conf[name];
        inputs[name] = input;
        if (name === 'usercss') {
          $.on(input, 'change', $.cb.value);
        } else if (name === 'favicon') {
          $.on(input, 'change', $.cb.value);
          $.on(input, 'change', Settings[name]);
        } else {
          $.on(input, 'input', $.cb.value);
          if (name in Settings) {
            $.on(input, 'input', Settings[name]);
          }
        }
      }
      ta = $('.personafield', section);
      $.get('QR.personas', Conf['QR.personas'], function(item) {
        return ta.value = item['QR.personas'];
      });
      $.on(ta, 'change', $.cb.value);
      $.get(items, function(items) {
        var key, val;
        for (key in items) {
          val = items[key];
          input = inputs[key];
          input.value = val;
          if (key in Settings && key !== 'usercss') {
            Settings[key].call(input);
          }
        }
      });
      interval = $('input[name="Interval"]', section);
      customCSS = $('input[name="Custom CSS"]', section);
      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', Settings.usercss);
      archBoards = {};
      ref2 = Redirect.archives;
      for (u = 0, len3 = ref2.length; u < len3; u++) {
        ref3 = ref2[u], uid = ref3.uid, name = ref3.name, boards = ref3.boards, files = ref3.files, software = ref3.software, withCredentials = ref3.withCredentials;
        for (v = 0, len4 = boards.length; v < len4; v++) {
          boardID = boards[v];
          o = archBoards[boardID] || (archBoards[boardID] = {
            thread: [[], []],
            post: [[], []],
            file: [[], []]
          });
          i = +(!!withCredentials);
          archive = [uid != null ? uid : name, name];
          o.thread[i].push(archive);
          if (software === 'foolfuuka') {
            o.post[i].push(archive);
          }
          if (indexOf.call(files, boardID) >= 0) {
            o.file[i].push(archive);
          }
        }
      }
      for (boardID in archBoards) {
        o = archBoards[boardID];
        ref4 = ['thread', 'post', 'file'];
        for (z = 0, len5 = ref4.length; z < len5; z++) {
          item = ref4[z];
          i = o[item][0].length ? 1 : 0;
          o[item][i].push([null, 'disabled']);
          o[item] = o[item][0].concat(o[item][1]);
        }
      }
      rows = [];
      boardOptions = [];
      ref5 = Object.keys(archBoards).sort();
      for (aa = 0, len6 = ref5.length; aa < len6; aa++) {
        boardID = ref5[aa];
        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];
        ref6 = ['thread', 'post', 'file'];
        for (ab = 0, len7 = ref6.length; ab < len7; ab++) {
          item = ref6[ab];
          $.add(row, Settings.addArchiveCell(boardID, o, item));
        }
        rows.push(row);
      }
      if (!(g.BOARD.ID in archBoards)) {
        rows[0].hidden = false;
      }
      $.add($('tbody', section), rows);
      boardSelect = $('#archive-board-select', section);
      $.add(boardSelect, boardOptions);
      table = $('#archive-table', section);
      $.on(boardSelect, 'change', function() {
        $('tbody > :not([hidden])', table).hidden = true;
        return $("tbody > ." + this.value, table).hidden = false;
      });
      $.get('selectedArchives', Conf['selectedArchives'], function(arg) {
        var data, id, select, selectedArchives, type;
        selectedArchives = arg.selectedArchives;
        for (boardID in selectedArchives) {
          data = selectedArchives[boardID];
          for (type in data) {
            id = data[type];
            if (select = $("select[data-boardid='" + boardID + "'][data-type='" + type + "']", section)) {
              select.value = JSON.stringify(id);
            }
          }
        }
      });
    },
    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></select>"
      });
      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] = {}))[_this.dataset.type] = JSON.parse(_this.value);
          return $.set('selectedArchives', selectedArchives);
        };
      })(this));
    },
    boardnav: function() {
      return Header.generateBoardList(this.value);
    },
    time: function() {
      return this.nextElementSibling.textContent = Time.format(this.value, new Date());
    },
    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: '//i.4cdn.org/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 img;
      Favicon["switch"]();
      if (g.VIEW === 'thread' && Conf['Unread Favicon']) {
        Unread.update();
      }
      img = this.nextElementSibling.children;
      img[0].src = Favicon["default"];
      img[1].src = Favicon.unreadSFW;
      img[2].src = Favicon.unreadNSFW;
      return img[3].src = Favicon.unreadDead;
    },
    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);
    },
    usercss: function() {
      return CustomCSS.update();
    },
    keybinds: function(section) {
      var arr, input, inputs, items, key, ref, tbody, tr;
      $.extend(section, {
        innerHTML: "<div class=\"warning\"><code>Keybinds</code> are disabled.</div><div>Allowed keys: <kbd>a-z</kbd>, <kbd>0-9</kbd>, <kbd>Ctrl</kbd>, <kbd>Shift</kbd>, <kbd>Alt</kbd>, <kbd>Meta</kbd>, <kbd>Enter</kbd>, <kbd>Esc</kbd>, <kbd>Up</kbd>, <kbd>Down</kbd>, <kbd>Right</kbd>, <kbd>Left</kbd>.</div><div>Press <kbd>Backspace</kbd> to disable a keybind.</div><table><tbody><tr><th>Actions</th><th>Keybinds</th></tr></tbody></table>"
      });
      $('.warning', section).hidden = Conf['Keybinds'];
      tbody = $('tbody', section);
      items = {};
      inputs = {};
      ref = Config.hotkeys;
      for (key in ref) {
        arr = ref[key];
        tr = $.el('tr', {
          innerHTML: "<td>" + E(arr[1]) + "</td><td><input class=\"field\"></td>"
        });
        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);
    }
  };

  Main = {
    init: function() {
      var db, flatten, items, k, key, len1, ref;
      if (d.body && !$('title', d.head)) {
        return;
      }
      if (window['4chan X antidup']) {
        return;
      }
      window['4chan X antidup'] = true;
      if (location.hostname === 'www.google.com') {
        $.get('Captcha Fixes', true, function(arg) {
          var enabled;
          enabled = arg['Captcha Fixes'];
          if (enabled) {
            return $.ready(function() {
              return Captcha.fixes.init();
            });
          }
        });
        return;
      }
      $.global(function() {
        var k, len1, nuke, prop, ref;
        nuke = function(obj, prop) {
          try {
            return Object.defineProperty(obj, prop, {
              configurable: false,
              get: function() {
                throw new Error();
              },
              set: function() {
                throw new Error();
              }
            });
          } catch (_error) {}
        };
        ref = ['atOptions', 'adsterra_key', 'EpmadsConfig', 'epmads_key', 'EpomConfig', 'epom_key', 'exoDocumentProtocol'];
        for (k = 0, len1 = ref.length; k < len1; k++) {
          prop = ref[k];
          nuke(window, prop);
        }
      });
      $.on(window, 'beforescriptexecute', function(e) {
        var host, ref, ref1;
        host = (ref = e.target.src.split('/')[2]) != null ? (ref1 = ref.match(/[^.]+\.[^.]+$/)) != null ? ref1[0] : void 0 : void 0;
        if (host === 'bnhtml.com' || host === 'ecpmrocks.com' || host === 'advertisation.com' || host === 'exoclick.com') {
          return e.preventDefault();
        }
      });
      $.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');
        }
      });
      flatten = function(parent, obj) {
        var key, val;
        if (obj instanceof Array) {
          Conf[parent] = obj[0];
        } else if (typeof obj === 'object') {
          for (key in obj) {
            val = obj[key];
            flatten(key, val);
          }
        } else {
          Conf[parent] = obj;
        }
      };
      flatten(null, Config);
      ref = DataBoard.keys;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        db = ref[k];
        Conf[db] = {
          boards: {}
        };
      }
      Conf['selectedArchives'] = {};
      Conf['cooldowns'] = {};
      Conf['Index Sort'] = {};
      Conf['Except Archives from Encryption'] = false;
      Conf['JSON Navigation'] = true;
      Conf['Oekaki Links'] = true;
      items = {};
      for (key in Conf) {
        items[key] = void 0;
      }
      items['previousversion'] = void 0;
      return $.get(items, function(items) {
        return $.asap((function() {
          return doc = d.documentElement;
        }), function() {
          var ref1, val;
          if ($.cantSet) {

          } else if (items.previousversion == null) {
            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] = (ref1 = items[key]) != null ? ref1 : val;
          }
          return 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 <a href=\"https://github.com/ccd0/4chan-x/blob/master/CHANGELOG.md\" target=\"_blank\">version " + E(g.VERSION) + "</a>."
          });
          return new Notice('info', el, 15);
        }
      });
    },
    initFeatures: function() {
      var err, feature, hostname, k, len1, match, name, pathname, ref, ref1, ref2, ref3, search;
      hostname = location.hostname, search = location.search;
      pathname = location.pathname.split(/\/+/);
      if (hostname !== 'www.4chan.org') {
        g.BOARD = new Board(pathname[1]);
      }
      if (hostname === 'boards.4chan.org' || hostname === 'sys.4chan.org' || hostname === 'www.4chan.org') {
        $.global(function() {
          document.documentElement.classList.add('js-enabled');
          return window.FCX = {};
        });
        Main.jsEnabled = $.hasClass(doc, 'js-enabled');
      }
      switch (hostname) {
        case 'www.4chan.org':
          $.onExists(doc, 'body', function() {
            return $.addStyle(Main.cssWWW);
          });
          Captcha.replace.init();
          return;
        case 'sys.4chan.org':
          if (pathname[2] === 'imgboard.php') {
            if (/\bmode=report\b/.test(search)) {
              Report.init();
            } else if ((match = 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();
          }
          return;
        case 'i.4cdn.org':
          if (!(pathname[2] && !/s\.jpg$/.test(pathname[2]))) {
            return;
          }
          $.asap((function() {
            return d.readyState !== 'loading';
          }), function() {
            var ref, video;
            if (Conf['404 Redirect'] && ((ref = d.title) === '4chan - Temporarily Offline' || ref === '4chan - 404 Not Found')) {
              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;
      }
      if ((ref = pathname[2]) === 'thread' || ref === 'res') {
        g.VIEW = 'thread';
        g.THREADID = +pathname[3];
      } else if ((ref1 = pathname[2]) === 'catalog' || ref1 === 'archive') {
        g.VIEW = pathname[2];
      } else if (pathname[2].match(/^\d*$/)) {
        g.VIEW = 'index';
      } else {
        return;
      }
      g.threads = new SimpleDict();
      g.posts = new SimpleDict();
      $.onExists(doc, 'body', Main.initStyle);
      ref2 = Main.features;
      for (k = 0, len1 = ref2.length; k < len1; k++) {
        ref3 = ref2[k], name = ref3[0], feature = ref3[1];
        try {
          feature.init();
        } catch (_error) {
          err = _error;
          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;
      }
      $.addClass(doc, 'fourchan-x', 'seaweedchan');
      $.addClass(doc, g.VIEW === 'thread' ? 'thread-view' : g.VIEW);
      if ($.engine) {
        $.addClass(doc, $.engine);
      }
      $.onExists(doc, '.ad-cnt', function(ad) {
        return $.onExists(ad, 'img', function() {
          return $.addClass(doc, 'ads-loaded');
        });
      });
      $.addStyle(Main.css, 'fourchanx-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 mainStyleSheet, setStyle, style, styleSheets;
      if (g.VIEW === 'catalog') {
        $.addClass(doc, $.id('base-css').href.match(/catalog_(\w+)/)[1].replace('_new', '').replace(/_+/g, '-'));
        return;
      }
      style = 'yotsuba-b';
      mainStyleSheet = $('link[title=switch]', d.head);
      styleSheets = $$('link[rel="alternate stylesheet"]', d.head);
      setStyle = function() {
        var k, len1, styleSheet;
        $.rmClass(doc, style);
        style = null;
        for (k = 0, len1 = styleSheets.length; k < len1; k++) {
          styleSheet = styleSheets[k];
          if (styleSheet.href === (mainStyleSheet != null ? mainStyleSheet.href : void 0)) {
            style = styleSheet.title.toLowerCase().replace('new', '').trim().replace(/\s+/g, '-');
            break;
          }
        }
        if (style) {
          return $.addClass(doc, style);
        }
      };
      setStyle();
      if (!mainStyleSheet) {
        return;
      }
      return new MutationObserver(setStyle).observe(mainStyleSheet, {
        attributes: true,
        attributeFilter: ['href']
      });
    },
    initReady: function() {
      var msg, ref, ref1, ref2;
      if (g.VIEW === 'thread' && (((ref = d.title) === '4chan - Temporarily Offline' || ref === '4chan - 404 Not Found') || ($('.board') && !$('.opContainer')))) {
        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 ((ref1 = d.title) === '4chan - Temporarily Offline' || ref1 === '4chan - 404 Not Found') {
        return;
      }
      if (((ref2 = g.VIEW) === 'index' || ref2 === 'thread') && !$('.board + *')) {
        msg = $.el('div', {
          innerHTML: "The page didn&#039;t load completely.<br>Some features may not work unless you <a href=\"javascript:;\">reload</a>."
        });
        $.on($('a', msg), 'click', function() {
          return location.reload();
        });
        new Notice('warning', msg);
      }
      if (!(Conf['JSON Index'] && g.VIEW === 'index')) {
        return Main.initThread();
      } else {
        Main.expectInitFinished = true;
        return $.event('4chanXInitFinished');
      }
    },
    initThread: function() {
      var board, err, errors, k, len1, len2, m, postRoot, posts, q, ref, ref1, scriptData, thread, threadRoot, threads;
      if ((board = $('.board'))) {
        threads = [];
        posts = [];
        ref = $$('.board > .thread', board);
        for (k = 0, len1 = ref.length; k < len1; k++) {
          threadRoot = ref[k];
          thread = new Thread(+threadRoot.id.slice(1), g.BOARD);
          threads.push(thread);
          ref1 = $$('.thread > .postContainer', threadRoot);
          for (q = 0, len2 = ref1.length; q < len2; q++) {
            postRoot = ref1[q];
            if ($('.postMessage', postRoot)) {
              try {
                posts.push(new Post(postRoot, thread, g.BOARD));
              } catch (_error) {
                err = _error;
                if (!errors) {
                  errors = [];
                }
                errors.push({
                  message: "Parsing of Post No." + (postRoot.id.match(/\d+/)) + " failed. Post will be skipped.",
                  error: err
                });
              }
            }
          }
        }
        if (errors) {
          Main.handleErrors(errors);
        }
        if (g.VIEW === 'thread') {
          scriptData = Get.scriptData();
          threads[0].postLimit = /\bbumplimit *= *1\b/.test(scriptData);
          threads[0].fileLimit = /\bimagelimit *= *1\b/.test(scriptData);
          threads[0].ipCount = (m = scriptData.match(/\bunique_ips *= *(\d+)\b/)) ? +m[1] : void 0;
        }
        Main.callbackNodes(Thread, threads);
        return Main.callbackNodesDB(Post, posts, function() {
          var len3, post, u;
          for (u = 0, len3 = posts.length; u < len3; u++) {
            post = posts[u];
            QuoteThreading.insert(post);
          }
          Main.expectInitFinished = true;
          return $.event('4chanXInitFinished');
        });
      } else {
        Main.expectInitFinished = true;
        return $.event('4chanXInitFinished');
      }
    },
    callbackNodes: function(klass, nodes) {
      var cb, i, node;
      i = 0;
      cb = klass.callbacks;
      while (node = nodes[i++]) {
        cb.execute(node);
      }
    },
    callbackNodesDB: function(klass, nodes, cb) {
      var cbs, fn, i, softTask;
      i = 0;
      cbs = klass.callbacks;
      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, error, k, len1, logs;
      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 + " [<a href=\"javascript:;\">show</a>]"
      });
      $.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 (k = 0, len1 = errors.length; k < len1; k++) {
        error = errors[k];
        $.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 + " userscript on " + $.engine + lines + ")"
      });
      return [message, error, context];
    },
    reportLink: function(errors) {
      var data, details, ref, title, url;
      data = errors[0];
      title = data.message;
      if (errors.length > 1) {
        title += " (+" + (errors.length - 1) + " other errors)";
      }
      details = "[Please describe the steps needed to reproduce this error.]\n\nScript: 4chan X ccd0 v" + g.VERSION + " userscript\nUser agent: " + navigator.userAgent + "\nURL: " + location.href + "\n\n" + data.error + "\n" + (((ref = data.error.stack) != null ? ref.replace(data.error.toString(), '').trim() : void 0) || '');
      details = details.replace(/file:\/{3}.+\//g, '');
      url = "https://gitreports.com/issue/ccd0/4chan-x?issue_title=" + (encodeURIComponent(title)) + "&details=" + (encodeURIComponent(details));
      return {
        innerHTML: "<span class=\"report-error\"> [<a href=\"" + E(url) + "\" target=\"_blank\">report</a>]</span>"
      };
    },
    isThisPageLegit: function() {
      var ref;
      if (!('thisPageIsLegit' in Main)) {
        Main.thisPageIsLegit = location.hostname === 'boards.4chan.org' && !$('link[href*="favicon-status.ico"]', d.head) && ((ref = d.title) !== '4chan - Temporarily Offline' && ref !== '4chan - Error' && ref !== '504 Gateway Time-out');
      }
      return Main.thisPageIsLegit;
    },
    ready: function(cb) {
      return $.ready(function() {
        if (Main.isThisPageLegit()) {
          return cb();
        }
      });
    },
    css: "/*!\n" +
" *  Font Awesome 4.5.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::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-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: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-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-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-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" +
"  transition: color .25s, border-color .25s;\n" +
"}\n" +
".field::-moz-placeholder,\n" +
".field:hover::-moz-placeholder {\n" +
"  color: #AAA !important;\n" +
"  font-size: 13px !important;\n" +
"  opacity: 1.0 !important;\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" +
"#boardNavDesktop, #boardNavMobile {\n" +
"  display: none !important;\n" +
"}\n" +
":root.hide-bottom-board-list #boardNavDesktopFoot {\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" +
"/* 4chan style fixes */\n" +
".opContainer, .op {\n" +
"  display: block !important;\n" +
"  overflow: visible !important;\n" +
"}\n" +
".reply > .file > .fileText {\n" +
"  margin: 0 20px;\n" +
"}\n" +
".hashlink::before {\n" +
"  content: ' ';\n" +
"  visibility: hidden;\n" +
"}\n" +
".inline + .hashlink,\n" +
"[hidden] {\n" +
"  display: none !important;\n" +
"}\n" +
".page-num {\n" +
"  margin-right: -8px;\n" +
"}\n" +
".fileText a {\n" +
"  unicode-bidi: -moz-isolate;\n" +
"  unicode-bidi: -webkit-isolate;\n" +
"}\n" +
"#g-recaptcha {\n" +
"  min-height: 78px;\n" +
"  height: auto;\n" +
"}\n" +
":root:not(.js-enabled) #postForm {\n" +
"  display: table;\n" +
"}\n" +
"#captchaContainerAlt td:nth-child(2) {\n" +
"  display: table-cell !important;\n" +
"}\n" +
"canvas#tegaki-canvas {\n" +
"  background: none;\n" +
"}\n" +
"/* Disable obnoxious captcha fade-in. */\n" +
"body > div:last-of-type {\n" +
"  transition: none !important;\n" +
"}\n" +
"/* Fix captcha scrolling to top of page. */\n" +
"body > div[style*=\" top: -10000px;\"] {\n" +
"  visibility: hidden !important;\n" +
"}\n" +
"/* Ads */\n" +
":root:not(.ads-loaded) .ad-cnt,\n" +
":root:not(.ads-loaded) .ad-plea,\n" +
":root:not(.ads-loaded) hr.abovePostForm,\n" +
":root:not(.ads-loaded) .ad-plea-bottom + hr {\n" +
"  display: none;\n" +
"}\n" +
"hr + div.center:not(.ad-cnt):not(.topad):not(.middlead):not(.bottomad) {\n" +
"  display: none !important;\n" +
"}\n" +
"/* Anti-autoplay */\n" +
"audio.controls-added {\n" +
"  display: block;\n" +
"  margin: auto;\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" +
"  display: block !important;\n" +
"  min-width: 640px;\n" +
"  min-height: 390px;\n" +
"}\n" +
"/* fixed, z-index */\n" +
"#overlay,\n" +
"#fourchanx-settings,\n" +
"#qp, #ihover,\n" +
"#navlinks, .fixed #header-bar,\n" +
":root.float #updater,\n" +
":root.float #thread-stats,\n" +
"#qr {\n" +
"  position: fixed;\n" +
"}\n" +
"#fourchanx-settings {\n" +
"  z-index: 999;\n" +
"}\n" +
"#overlay {\n" +
"  z-index: 900;\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" +
".shortcut {\n" +
"  margin-left: 3px;\n" +
"  vertical-align: middle;\n" +
"}\n" +
"#navbotright,\n" +
"#navtopright {\n" +
"  display: none;\n" +
"}\n" +
"#toggleMsgBtn {\n" +
"  display: none !important;\n" +
"}\n" +
".current {\n" +
"  font-weight: bold;\n" +
"}\n" +
"@media (min-width: 1300px) {\n" +
"  :root.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.fixed:not(.centered-links) #board-list {\n" +
"    -webkit-flex: auto;\n" +
"    flex: auto;\n" +
"  }\n" +
"  :root.fixed:not(.centered-links) #full-board-list {\n" +
"    display: -webkit-flex;\n" +
"    display: flex;\n" +
"  }\n" +
"  :root.fixed:not(.centered-links) .hide-board-list-container {\n" +
"    -webkit-flex: none;\n" +
"    flex: none;\n" +
"    margin-right: 5px;\n" +
"  }\n" +
"  :root.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.fixed:not(.centered-links) #full-board-list > .boardList > a,\n" +
"  :root.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.fixed:not(.centered-links) #full-board-list > .boardList > span {\n" +
"    pointer-events: none;\n" +
"  }\n" +
"  :root.fixed:not(.centered-links) #full-board-list > .boardList > span.space {\n" +
"    -webkit-flex: 0 .63 .63em;\n" +
"    flex: 0 .63 .63em;\n" +
"  }\n" +
"  :root.fixed:not(.centered-links) #full-board-list > .boardList > span.spacer {\n" +
"    -webkit-flex: 0 .38 .38em;\n" +
"    flex: 0 .38 .38em;\n" +
"  }\n" +
"  :root.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" +
":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: 500px;\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" +
"  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: 3px;\n" +
"  top: 50%;\n" +
"  left: 50%;\n" +
"  -moz-transform: translate(-50%, -50%);\n" +
"  -webkit-transform: translate(-50%, -50%);\n" +
"  transform: translate(-50%, -50%);\n" +
"}\n" +
"#fourchanx-settings > nav {\n" +
"  padding: 2px 2px 0;\n" +
"  height: 15px;\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" +
"  overflow: auto;\n" +
"  position: absolute;\n" +
"  top: 2.1em;\n" +
"  right: 5px;\n" +
"  bottom: 5px;\n" +
"  left: 5px;\n" +
"  padding-right: 5px;\n" +
"}\n" +
".sections-list {\n" +
"  padding: 0 3px;\n" +
"  float: left;\n" +
"}\n" +
".credits {\n" +
"  float: right;\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" +
".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" +
".section-sauce textarea {\n" +
"  height: 350px;\n" +
"}\n" +
".section-advanced .field[name=\"boardnav\"] {\n" +
"  width: 100%;\n" +
"}\n" +
".section-advanced textarea {\n" +
"  height: 150px;\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" +
".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" +
"  min-width: 100%;\n" +
"  max-width: 100%;\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" +
".unscroll {\n" +
"  overflow: hidden;\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-mode, #index-sort, #index-size {\n" +
"  float: right;\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: -webkit-inline-flex;\n" +
"  display: inline-flex;\n" +
"  text-align: left;\n" +
"  -webkit-flex-direction: column;\n" +
"  flex-direction: column;\n" +
"  -webkit-align-items: center;\n" +
"  align-items: center;\n" +
"  margin: 0 2px 5px;\n" +
"  word-wrap: break-word;\n" +
"  vertical-align: top;\n" +
"  position: relative;\n" +
"}\n" +
".catalog-thread > a {\n" +
"  flex-shrink: 0;\n" +
"  -webkit-flex-shrink: 0;\n" +
"  position: relative;\n" +
"}\n" +
".catalog-small .catalog-thread {\n" +
"  width: 165px;\n" +
"  max-height: 320px;\n" +
"}\n" +
".catalog-large .catalog-thread {\n" +
"  width: 270px;\n" +
"  max-height: 410px;\n" +
"}\n" +
".catalog-thumb {\n" +
"  border-radius: 2px;\n" +
"  box-shadow: 0 0 5px rgba(0, 0, 0, .25);\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" +
"  text-align: center;\n" +
"  font-weight: normal;\n" +
"}\n" +
".catalog-stats > .menu-button > i::before {\n" +
"  line-height: 11px;\n" +
"}\n" +
".catalog-stats {\n" +
"  -webkit-flex-shrink: 0;\n" +
"  flex-shrink: 0;\n" +
"  cursor: help;\n" +
"  font-size: 10px;\n" +
"  font-weight: 700;\n" +
"  margin-top: 2px;\n" +
"}\n" +
".catalog-thread > .subject {\n" +
"  -webkit-flex-shrink: 0;\n" +
"  flex-shrink: 0;\n" +
"  -webkit-align-self: stretch;\n" +
"  align-self: stretch;\n" +
"  font-weight: 700;\n" +
"  line-height: 1;\n" +
"  text-align: center;\n" +
"}\n" +
".catalog-thread > .comment {\n" +
"  -webkit-flex-shrink: 1;\n" +
"  flex-shrink: 1;\n" +
"  -webkit-align-self: stretch;\n" +
"  align-self: stretch;\n" +
"  overflow: hidden;\n" +
"  text-align: center;\n" +
"}\n" +
"/* /tg/ dice rolls */\n" +
".board_tg .catalog-thread > .comment > b {\n" +
"  font-weight: normal;\n" +
"}\n" +
".catalog-code {\n" +
"  background-color: #FFF;\n" +
"  display: inline-block;\n" +
"  max-width: 100%;\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: -10px;\n" +
"  top: -65px;\n" +
"  width: 100px;\n" +
"  height: 100px;\n" +
"}\n" +
":root.hats-enabled .catalog-large .catalog-thread::after {\n" +
"  left: -15px;\n" +
"  top: -105px;\n" +
"  width: 160px;\n" +
"  height: 160px;\n" +
"}\n" +
"/* Announcement Hiding */\n" +
":root.hide-announcement #globalMessage {\n" +
"  display: none;\n" +
"}\n" +
"span.hide-announcement {\n" +
"  font-size: 11px;\n" +
"  position: relative;\n" +
"  bottom: 5px;\n" +
"}\n" +
".globalMessage, h2, h3 {\n" +
"  color: inherit !important;\n" +
"  font-size: 13px;\n" +
"  font-weight: 100;\n" +
"}\n" +
"/* Unread */\n" +
"#unread-line {\n" +
"  margin: 0;\n" +
"  border-color: rgb(255,0,0);\n" +
"}\n" +
"/* Thread Updater */\n" +
"#updater {\n" +
"  background: none;\n" +
"  border: none;\n" +
"  box-shadow: none;\n" +
"}\n" +
"#updater > .move {\n" +
"  position: absolute;\n" +
"  left: 0;\n" +
"  top: -5px;\n" +
"  width: 100%;\n" +
"  height: 5px;\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) #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-unread {\n" +
"  -webkit-flex: 0 0 auto;\n" +
"  flex: 0 0 auto;\n" +
"}\n" +
"#watched-threads .watcher-unread::after {\n" +
"  content: \"\\00a0\";\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" +
"#thread-watcher a {\n" +
"  text-decoration: none;\n" +
"}\n" +
":root:not(.toggleable-watcher) #thread-watcher .move > .close {\n" +
"  display: 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" +
"}\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" +
".catalog-thread > .comment > span.quote, #arc-list span.quote {\n" +
"  color: #789922;\n" +
"}\n" +
":root:not(.catalog-mode) .deadlink {\n" +
"  text-decoration: none !important;\n" +
"}\n" +
".backlink.deadlink:not(.forwardlink),\n" +
".quotelink.deadlink:not(.forwardlink) {\n" +
"  text-decoration: underline !important;\n" +
"}\n" +
".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" +
".inline {\n" +
"  border: 1px solid;\n" +
"  display: table;\n" +
"  margin: 2px 0;\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 {\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.gecko.fit-width .full-image {\n" +
"  width: 100%;\n" +
"}\n" +
".fileThumb > .warning {\n" +
"  clear: both;\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 Tyme */\n" +
":root.fappeTyme .thread > .noFile,\n" +
":root.fappeTyme .threadContainer > .noFile {\n" +
"  display: none;\n" +
"}\n" +
"/* Werk Tyme */\n" +
":root.werkTyme .postContainer:not(.noFile) .fileThumb,\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" +
"}\n" +
":root.werkTyme .catalog-thread > a {\n" +
"  text-align: center;\n" +
"  -webkit-align-self: stretch;\n" +
"  align-self: stretch;\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.opContainer,\n" +
":root.highlight-you .quotesYou > .reply {\n" +
"  border-left: 3px solid rgba(221, 0, 0, .8);\n" +
"}\n" +
":root.highlight-own .yourPost.opContainer,\n" +
":root.highlight-own .yourPost > .reply {\n" +
"  border-left: 3px dashed rgba(221, 0, 0, .8);\n" +
"}\n" +
".filter-highlight.opContainer,\n" +
".filter-highlight > .reply {\n" +
"  box-shadow: inset 5px 0 rgba(221, 0, 0, .5);\n" +
"}\n" +
":root.highlight-own .yourPost > div.sideArrows,\n" +
":root.highlight-you .quotesYou > div.sideArrows,\n" +
".filter-highlight > div.sideArrows {\n" +
"  color: rgba(221, 0, 0, .8);\n" +
"}\n" +
":root.highlight-own .yourPost.opContainer::after,\n" +
":root.highlight-you .quotesYou.opContainer::after,\n" +
".filter-highlight.opContainer::after {\n" +
"  content: \"\";\n" +
"  display: block;\n" +
"  clear: both;\n" +
"}\n" +
".filter-highlight .catalog-thumb,\n" +
".filter-highlight .werkTyme-filename {\n" +
"  box-shadow: 0 0 3px 3px rgba(255, 0, 0, .5);\n" +
"}\n" +
".catalog-thread.watched .catalog-thumb,\n" +
".catalog-thread.watched .werkTyme-filename {\n" +
"  border: 2px solid rgba(255, 0, 0, .75);\n" +
"}\n" +
"/* Spoiler text */\n" +
":root.reveal-spoilers s,\n" +
":root.reveal-spoilers s > 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" +
".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" +
"}\n" +
".stub ~ * {\n" +
"  display: none !important;\n" +
"}\n" +
".stub input {\n" +
"  display: inline-block;\n" +
"}\n" +
".thread[hidden] + hr {\n" +
"  display: none;\n" +
"}\n" +
":root.reply-hide div.sideArrows {\n" +
"  display: none;\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" +
"body:not(.board_jp) #sjis-toggle,\n" +
"body:not(.board_sci) #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: 100%;\n" +
"  resize: both;\n" +
"}\n" +
".field {\n" +
"  -moz-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 v1 */\n" +
".captcha-img {\n" +
"  margin: 0px;\n" +
"  text-align: center;\n" +
"  background-image: #fff;\n" +
"  font-size: 0px;\n" +
"  min-height: 59px;\n" +
"  min-width: 302px;\n" +
"}\n" +
".captcha-input {\n" +
"  width: 100%;\n" +
"  margin: 1px 0 0;\n" +
"}\n" +
"#qr.captcha-v1 #qr-captcha-iframe {\n" +
"  display: none;\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" +
"/* scrollable with scroll bar hidden; prevents scroll on space press */\n" +
":root.blink #qr .captcha-container > div {\n" +
"  overflow: hidden;\n" +
"}\n" +
":root.blink #qr .captcha-container > div > div:first-of-type {\n" +
"  overflow-y: scroll;\n" +
"  overflow-x: hidden;\n" +
"  padding-right: 15px;\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" +
"}\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" +
"  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" +
"  -moz-transform: translateY(-50%);\n" +
"}\n" +
".textarea {\n" +
"  position: relative;\n" +
"  display: -webkit-flex;\n" +
"  display: flex;\n" +
"}\n" +
":root.webkit .textarea {\n" +
"  margin-bottom: -2px;\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" +
".post .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" +
"}\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" +
"}\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" +
"/* Link Title Favicons */\n" +
".linkify.audio {\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.clyp {\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 {\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 {\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 {\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 {\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 {\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 {\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 {\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.soundcloud {\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.twitchtv {\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 {\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 {\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.vimeo {\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 {\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 {\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 {\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" +
"/* Embedding */\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" +
"  order: 0;\n" +
"  border-right: 1px solid #222;\n" +
"}\n" +
".gal-next {\n" +
"  order: 2;\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" +
"  order: 1;\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" +
"  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-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-buttons,\n" +
".gal-name,\n" +
".gal-count {\n" +
"  position: fixed;\n" +
"  right: 195px;\n" +
"}\n" +
".gal-hide-thumbnails .gal-buttons,\n" +
".gal-hide-thumbnails .gal-count,\n" +
".gal-hide-thumbnails .gal-name {\n" +
"  right: 44px;\n" +
"}\n" +
".gal-name {\n" +
"  bottom: 6px;\n" +
"  background: rgba(0,0,0,0.6) !important;\n" +
"  border-radius: 3px;\n" +
"  padding: 1px 5px 2px 5px;\n" +
"  text-decoration: none !important;\n" +
"  color: white !important;\n" +
"}\n" +
".gal-name:hover,\n" +
".gal-buttons 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-count {\n" +
"  bottom: 27px;\n" +
"  background: rgba(0,0,0,0.6) !important;\n" +
"  border-radius: 3px;\n" +
"  padding: 1px 5px 2px 5px;\n" +
"  color: #ffffff !important;\n" +
"}\n" +
":root:not(.gal-fit-width):not(.gal-pdf) .gal-name {\n" +
"  bottom: 23px !important;\n" +
"}\n" +
":root:not(.gal-fit-width):not(.gal-pdf) .gal-count {\n" +
"  bottom: 44px !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-name,\n" +
":root.gal-fit-height:not(.gal-pdf):not(.gal-hide-thumbnails) .gal-count {\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-name,\n" +
":root.gal-hide-thumbnails:.gal-fit-height:not(.gal-pdf) .gal-count {\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" +
"/* Upvotes */\n" +
".upvote {\n" +
"  margin: 0 4px;\n" +
"}\n" +
".post .menu-button:not(:last-of-type) {\n" +
"  margin-right: -4px;\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" +
"/* 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" +
"/* 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" +
"/* 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" +
"/* Thread Watcher */\n" +
":root.yotsuba .replies-quoting-you > a, :root.yotsuba #watcher-link.disabled.replies-quoting-you {\n" +
"  color: #F00;\n" +
"}\n" +
"/* Watcher Favicon */\n" +
":root.yotsuba .watch-thread-link\n" +
"{\n" +
"  background-image: url(\"data:image/svg+xml,<svg viewBox='0 0 26 26' preserveAspectRatio='true' xmlns='http://www.w3.org/2000/svg'><path fill='rgb(128,0,0)' d='M24.132,7.971c-2.203-2.205-5.916-2.098-8.25,0.235L15.5,8.588l-0.382-0.382c-2.334-2.333-6.047-2.44-8.25-0.235c-2.204,2.203-2.098,5.916,0.235,8.249l8.396,8.396l8.396-8.396C26.229,13.887,26.336,10.174,24.132,7.971z'/></svg>\");\n" +
"}\n" +
"/* General */\n" +
":root.yotsuba-b .dialog {\n" +
"  background-color: #D6DAF0;\n" +
"  border-color: #B7C5D9;\n" +
"}\n" +
":root.yotsuba-b .field:focus,\n" +
":root.yotsuba-b .field.focus {\n" +
"  border-color: #98E;\n" +
"}\n" +
"/* 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" +
"/* 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" +
"/* 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" +
"/* Thread Watcher */\n" +
":root.yotsuba-b .replies-quoting-you > a, :root.yotsuba-b #watcher-link.disabled.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,<svg viewBox='0 0 26 26' preserveAspectRatio='true' xmlns='http://www.w3.org/2000/svg'><path fill='rgb(0,0,0)' d='M24.132,7.971c-2.203-2.205-5.916-2.098-8.25,0.235L15.5,8.588l-0.382-0.382c-2.334-2.333-6.047-2.44-8.25-0.235c-2.204,2.203-2.098,5.916,0.235,8.249l8.396,8.396l8.396-8.396C26.229,13.887,26.336,10.174,24.132,7.971z'/></svg>\");\n" +
"}\n" +
"/* General */\n" +
":root.futaba .dialog {\n" +
"  background-color: #F0E0D6;\n" +
"  border-color: #D9BFB7;\n" +
"}\n" +
":root.futaba .field:focus,\n" +
":root.futaba .field.focus {\n" +
"  border-color: #EA8;\n" +
"}\n" +
"/* 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" +
"/* 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" +
"/* 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" +
"/* Thread Watcher */\n" +
":root.futaba .replies-quoting-you > a, :root.futaba #watcher-link.disabled.replies-quoting-you {\n" +
"  color: #F00;\n" +
"}\n" +
"/* Watcher Favicon */\n" +
":root.futaba .watch-thread-link\n" +
"{\n" +
"  background-image: url(\"data:image/svg+xml,<svg viewBox='0 0 26 26' preserveAspectRatio='true' xmlns='http://www.w3.org/2000/svg'><path fill='rgb(128,0,0)' d='M24.132,7.971c-2.203-2.205-5.916-2.098-8.25,0.235L15.5,8.588l-0.382-0.382c-2.334-2.333-6.047-2.44-8.25-0.235c-2.204,2.203-2.098,5.916,0.235,8.249l8.396,8.396l8.396-8.396C26.229,13.887,26.336,10.174,24.132,7.971z'/></svg>\");\n" +
"}\n" +
"/* General */\n" +
":root.burichan .dialog {\n" +
"  background-color: #D6DAF0;\n" +
"  border-color: #B7C5D9;\n" +
"}\n" +
":root.burichan .field:focus,\n" +
":root.burichan .field.focus {\n" +
"  border-color: #98E;\n" +
"}\n" +
"/* 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" +
"/* 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" +
"/* 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" +
"/* Thread Watcher */\n" +
":root.burichan .replies-quoting-you > a, :root.burichan #watcher-link.disabled.replies-quoting-you {\n" +
"  color: #F00;\n" +
"}\n" +
"/* Watcher Favicon */\n" +
":root.burichan .watch-thread-link\n" +
"{\n" +
"  background-image: url(\"data:image/svg+xml,<svg viewBox='0 0 26 26' preserveAspectRatio='true' xmlns='http://www.w3.org/2000/svg'><path fill='rgb(0,0,0)' d='M24.132,7.971c-2.203-2.205-5.916-2.098-8.25,0.235L15.5,8.588l-0.382-0.382c-2.334-2.333-6.047-2.44-8.25-0.235c-2.204,2.203-2.098,5.916,0.235,8.249l8.396,8.396l8.396-8.396C26.229,13.887,26.336,10.174,24.132,7.971z'/></svg>\");\n" +
"}\n" +
"/* General */\n" +
":root.tomorrow .dialog {\n" +
"  background-color: #282A2E;\n" +
"  border-color: #111;\n" +
"}\n" +
"/* 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" +
"/* 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-code {\n" +
"  background-color: rgba(255, 255, 255, 0.1);\n" +
"}\n" +
"/* Quote */\n" +
":root.tomorrow .catalog-thread > .comment > span.quote, :root.tomorrow #arc-list span.quote {\n" +
"  color: #B5BD68;\n" +
"}\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" +
"/* Highlighting */\n" +
":root.tomorrow .qphl {\n" +
"  outline: 2px solid rgba(145, 182, 214, .8);\n" +
"}\n" +
":root.tomorrow.highlight-you .quotesYou.opContainer,\n" +
":root.tomorrow.highlight-you .quotesYou > .reply {\n" +
"  border-left: 3px solid rgba(145, 182, 214, .8);\n" +
"}\n" +
":root.tomorrow.highlight-own .yourPost.opContainer,\n" +
":root.tomorrow.highlight-own .yourPost > .reply {\n" +
"  border-left: 3px dashed rgba(145, 182, 214, .8);\n" +
"}\n" +
":root.tomorrow .opContainer.filter-highlight,\n" +
":root.tomorrow .filter-highlight > .reply {\n" +
"  box-shadow: inset 5px 0 rgba(145, 182, 214, .5);\n" +
"}\n" +
":root.tomorrow.highlight-own .yourPost > div.sideArrows,\n" +
":root.tomorrow.highlight-you .quotesYou > div.sideArrows,\n" +
":root.tomorrow .filter-highlight > div.sideArrows {\n" +
"  color: rgb(155, 185, 210);\n" +
"}\n" +
":root.tomorrow .filter-highlight .catalog-thumb,\n" +
":root.tomorrow .filter-highlight .werkTyme-filename {\n" +
"  box-shadow: 0 0 3px 3px rgba(64, 192, 255, .7);\n" +
"}\n" +
":root.tomorrow .catalog-thread.watched .catalog-thumb,\n" +
":root.tomorrow .catalog-thread.watched .werkTyme-filename {\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" +
"/* Thread Watcher */\n" +
":root.tomorrow .replies-quoting-you > a, :root.tomorrow #watcher-link.disabled.replies-quoting-you {\n" +
"  color: #F00 !important;\n" +
"}\n" +
"/* Watcher Favicon */\n" +
":root.tomorrow .watch-thread-link\n" +
"{\n" +
"  background-image: url(\"data:image/svg+xml,<svg viewBox='0 0 26 26' preserveAspectRatio='true' xmlns='http://www.w3.org/2000/svg'><path fill='rgb(197,200,198)' d='M24.132,7.971c-2.203-2.205-5.916-2.098-8.25,0.235L15.5,8.588l-0.382-0.382c-2.334-2.333-6.047-2.44-8.25-0.235c-2.204,2.203-2.098,5.916,0.235,8.249l8.396,8.396l8.396-8.396C26.229,13.887,26.336,10.174,24.132,7.971z'/></svg>\");\n" +
"}\n" +
"/* General */\n" +
":root.photon .dialog {\n" +
"  background-color: #DDD;\n" +
"  border-color: #CCC;\n" +
"}\n" +
":root.photon .field:focus,\n" +
":root.photon .field.focus {\n" +
"  border-color: #EA8;\n" +
"}\n" +
"/* 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-code {\n" +
"  background-color: rgba(150, 150, 150, 0.2);\n" +
"}\n" +
"/* Quote */\n" +
":root.photon #arc-list tr:nth-of-type(odd) span.quote {\n" +
"  color: #C0E17A;\n" +
"}\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" +
"/* 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" +
"/* Thread Watcher */\n" +
":root.photon .replies-quoting-you > a, :root.photon #watcher-link.disabled.replies-quoting-you {\n" +
"  color: #00F !important;\n" +
"}\n" +
"/* Watcher Favicon */\n" +
":root.photon .watch-thread-link\n" +
"{\n" +
"  background-image: url(\"data:image/svg+xml,<svg viewBox='0 0 26 26' preserveAspectRatio='true' xmlns='http://www.w3.org/2000/svg'><path fill='rgb(51,51,51)' d='M24.132,7.971c-2.203-2.205-5.916-2.098-8.25,0.235L15.5,8.588l-0.382-0.382c-2.334-2.333-6.047-2.44-8.25-0.235c-2.204,2.203-2.098,5.916,0.235,8.249l8.396,8.396l8.396-8.396C26.229,13.887,26.336,10.174,24.132,7.971z'/></svg>\");\n" +
"}\n" +
"/* 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" +
"}",
    cssWWW: "#captcha-cnt {\n" +
"  height: auto;\n" +
"}",
    features: [['Polyfill', Polyfill], ['Normalize URL', NormalizeURL], ['Captcha Configuration', Captcha.replace], ['Redirect', Redirect], ['Header', Header], ['Catalog Links', CatalogLinks], ['Settings', Settings], ['Index Generator', Index], ['Disable Autoplay', AntiAutoplay], ['Announcement Hiding', PSAHiding], ['Fourchan thingies', Fourchan], ['Color User IDs', IDColor], ['Highlight by User ID', IDHighlight], ['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', QR], ['Cooldown', QR.cooldown], ['Pass Link', PassLink], ['Menu', Menu], ['Index Generator (Menu)', Index.menu], ['Report Link', ReportLink], ['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], ['Upvotes', Upvotes], ['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], ['Thread Excerpt', ThreadExcerpt], ['Favicon', Favicon], ['Unread', Unread], ['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], ['Flash Features', Flash], ['Prune Replies', PruneReplies]]
  };

  Main.init();

}).call(this);