diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5643a279e..797d180de 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,20 @@
-### v2.8.9
-*2014-02-09*
+**Spittie**
+- Add Twitter embedding
+- Add .xpi for Firefox Mobile
+- Add /biz/
+- Add gfycat.com embedding
+- Replace some icons with fontawesome
+- Add Metro favicons (lel)
+- Fix Chrome (aka copy from Appchan)
+- Add option to load the captcha when you open a thread
+- Add OpenSUSE emoji
+- Fix Chrome (Maybe? Hopefully I haven't fucked everything)
+- Add fgst.eu
+- Add mawa.re
+- Fix new captcha
+- Add archive.installgentoo.com
+- Upload images directly from urls
+
### v2.8.8
*2014-01-30*
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3478e5082..c6a99fd0a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,16 +1,16 @@
## Reporting bugs and suggestions
-Reporting bugs:
+Reporting bugs: (note that some of these links refer to Mayhem's 4chan X repo to avoid duplication of information resources. Bugs MUST be filed on [our issue tracker](https://github.com/zixaphir/appchan-x/issues), not Mayhem's)
-1. Make sure both your **browser** and **4chan X** are up to date.
+1. Make sure both your **browser** and **Appchan X** are up to date.
Only **Chrome**, **Firefox** and **Opera** are supported.
- **SRWare Iron**, **Firefox ESR**, **Pale Moon**, **Waterfox**, and other derivatives are not supported, use them at your own risk.
+ **SRWare Iron**, **Firefox ESR**, **Pale Moon**, **Waterfox**, and other derivatives are not supported, use them at your own risk. This means that issue reports made with these browsers will be ignored unless you're able to duplicate it on a supported browser.
2. Look at the list of [known problems and solutions](https://github.com/MayhemYDG/4chan-x/wiki/FAQ#known-problems).
3. Disable your other extensions & scripts to identify conflicts.
-4. If your issue persists, open a [new issue](https://github.com/MayhemYDG/4chan-x/issues) with the following information:
+4. If your issue persists, open a [new issue](https://github.com/zixaphir/appchan-x/issues) with the following information:
1. Precise steps to reproduce the problem, with the expected and actual results.
2. [Console errors](https://github.com/MayhemYDG/4chan-x/wiki/FAQ#console-errors), if any.
- 3. 4chan X version, browser variant, browser version, and Greasemonkey version if you are using it.
+ 3. Appchan X version, browser variant, browser version, and Greasemonkey version if you are using it.
4. Your exported settings. If your settings contains sensible information (e.g. personas), edit the text file manually.
Respect these guidelines:
@@ -25,9 +25,9 @@ Respect these guidelines:
- Install [node.js](http://nodejs.org/).
- Install [Grunt's CLI](http://gruntjs.com/) with `npm install -g grunt-cli`.
-- Clone 4chan X.
+- Clone Appchan X.
- `cd` into it.
-- Install/Update 4chan X dependencies with `npm install`.
+- Install/Update Appchan X dependencies with `npm install`.
### Build
@@ -39,7 +39,7 @@ Respect these guidelines:
- Update the version with `grunt patch`, `grunt minor` or `grunt major`.
- Release with `grunt release`.
-Note: this is only used to release new 4chan X versions, and is **not** needed or wanted in pull requests.
+Note: this is only used to release new versions, and is **not** needed or wanted in pull requests.
### Contribute
diff --git a/LICENSE b/LICENSE
index f5a9a1617..4d229a004 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,5 @@
/*
-* appchan x - Version 2.8.9 - 2014-02-09
+* appchan x - Version 2.8.9 - 2014-02-16
*
* Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
diff --git a/README.md b/README.md
index 1782855be..0b1188f60 100755
--- a/README.md
+++ b/README.md
@@ -1,7 +1,5 @@
# Get Appchan X [HERE](http://zixaphir.github.io/appchan-x/).
-## Reporting bugs and suggestions
-
1. Make sure both your **browser** and **Appchan X** are up to date.
2. Disable your other extensions & scripts to identify conflicts.
3. If your issue persists, open a [new issue](https://github.com/zixaphir/appchan-x/issues) with the following information:
@@ -9,16 +7,14 @@
2. Console errors, if any.
3. Browser version.
4. Your exported settings. If your settings contains sensitive information (e.g. personas), edit the text file manually.
+## If you have any problems, try resetting your 4chan X settings before calling me a faggot (but feel free to do so)
-Open your console with:
-- `Ctrl + Shift + J` on Chrome.
-- `Ctrl + Shift + K` on Firefox.
-- `Ctrl + Shift + O` on Opera.
-
-## Development & Contribution
+## Forking
### Get started
+- Get started by reading through the [Help link](https://help.github.com/) on how to fork a Github project.
+- Click the "Fork" button on this page.
- Install [node.js](http://nodejs.org/).
- Install [Grunt's CLI](http://gruntjs.com/) with `npm install -g grunt-cli`.
- Clone Appchan X.
@@ -32,6 +28,6 @@ Open your console with:
### Contribute
-- Edit the CoffeeScript sources.
-- If the edits affect regular users, edit the changelog.
-- Open a pull request.
+- See (https://github.com/zixaphir/CONTRIBUTING.md).
+
+Note: this is only used to release new versions, ignore as you see fit.
diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js
index d74b232cc..c72846c5e 100755
--- a/builds/4chan-X.meta.js
+++ b/builds/4chan-X.meta.js
@@ -1,11 +1,11 @@
// ==UserScript==
// @name 4chan X
-// @version 1.3.2
+// @version 1.3.7
// @minGMVer 1.14
// @minFFVer 26
// @namespace 4chan-X
// @description Cross-browser userscript for maximum lurking on 4chan.
-// @license MIT; https://github.com/seaweedchan/4chan-x/blob/master/LICENSE
+// @license MIT; https://github.com/Spittie/4chan-x/blob/master/LICENSE
// @match *://boards.4chan.org/*
// @match *://sys.4chan.org/*
// @match *://a.4cdn.org/*
@@ -15,8 +15,9 @@
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM_openInTab
+// @grant GM_xmlhttpRequest
// @run-at document-start
-// @updateURL https://github.com/seaweedchan/4chan-x/raw/stable/builds/4chan-X.meta.js
-// @downloadURL https://github.com/seaweedchan/4chan-x/raw/stable/builds/4chan-X.user.js
-// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAgMAAAAqbBEUAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAHFJREFUKFOt0LENACEIBdBv4Qju4wgWanEj3D6OcIVMKaitYHEU/jwTCQj8W75kiVCSBvdQ5/AvfVHBin11BgdRq3ysBgfwBDRrj3MCIA+oAQaku/Q1cNctrAmyDl577tOThYt/Y1RBM4DgOHzM0HFTAyLukH/cmRnqAAAAAElFTkSuQmCC
+// @updateURL https://github.com/Spittie/4chan-x/raw/stable/builds/4chan-X.meta.js
+// @downloadURL https://github.com/Spittie/4chan-x/raw/stable/builds/4chan-X.user.js
+// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAF5JREFUeNrtkTESABAQxPD/R6tsE2dUGYUtFJvLDKf93KevHJAjpBorAQWSBIKqFASC4G0pCAkm4GfaEvgYXl0T6HBaE97f0vmnfYHbZOMLZCx9ISdKWwjOWZSC8GYm4SUGwfYgqI4AAAAASUVORK5CYII=
// ==/UserScript==
diff --git a/builds/appchan-x.meta.js b/builds/appchan-x.meta.js
index e9df813c2..b1a76e6ec 100644
--- a/builds/appchan-x.meta.js
+++ b/builds/appchan-x.meta.js
@@ -15,6 +15,7 @@
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM_openInTab
+// @grant GM_xmlhttpRequest
// @run-at document-start
// @updateURL https://github.com/zixaphir/appchan-x/raw/stable/builds/appchan-x.meta.js
// @downloadURL https://github.com/zixaphir/appchan-x/raw/stable/builds/appchan-x.user.js
diff --git a/builds/appchan-x.user.js b/builds/appchan-x.user.js
index dce699b9a..6961c52b1 100644
--- a/builds/appchan-x.user.js
+++ b/builds/appchan-x.user.js
@@ -16,6 +16,7 @@
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM_openInTab
+// @grant GM_xmlhttpRequest
// @run-at document-start
// @updateURL https://github.com/zixaphir/appchan-x/raw/stable/builds/appchan-x.meta.js
// @downloadURL https://github.com/zixaphir/appchan-x/raw/stable/builds/appchan-x.user.js
@@ -23,7 +24,7 @@
// ==/UserScript==
/*
-* appchan x - Version 2.8.9 - 2014-02-09
+* appchan x - Version 2.8.9 - 2014-02-16
*
* Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
@@ -216,7 +217,8 @@
'Cooldown Prediction': [true, 'Decrease the cooldown time by taking into account upload speed. Disable it if it\'s inaccurate for you.'],
'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.'],
'Captcha Warning Notifications': [true, 'When disabled, shows a red border on the CAPTCHA input until a key is pressed instead of a notification.'],
- 'Dump List Before Comment': [false, 'Position of the QR\'s Dump List.']
+ 'Dump List Before Comment': [false, 'Position of the QR\'s Dump List.'],
+ 'Auto-load captcha': [false, 'Automatically load the captcha when you open a thread']
},
'Quote Links': {
'Quote Backlinks': [true, 'Add quote backlinks.'],
@@ -7994,6 +7996,14 @@
});
}
},
+ Twitter: {
+ regExp: /.*twitter.com\/(.+\/status\/\d+)/,
+ el: function(a) {
+ return $.el('iframe', {
+ src: "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid
+ });
+ }
+ },
LiveLeak: {
regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/,
el: function(a) {
@@ -8069,6 +8079,15 @@
});
}
},
+ gfycat: {
+ regExp: /.*gfycat.com\/(?:iframe\/)?(\S*)/,
+ el: function(a) {
+ var div;
+ return div = $.el('iframe', {
+ src: "http://gfycat.com/iframe/" + a.dataset.uid
+ });
+ }
+ },
SoundCloud: {
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/,
style: 'height: auto; width: 500px; display: inline-block;',
@@ -8500,6 +8519,56 @@
QR.handleFiles(files);
return $.addClass(QR.nodes.el, 'dump');
},
+ handleBlob: function(blob) {
+ var _ref;
+ if (blob.type === null) {
+ return QR.error("Unsupported file type.");
+ }
+ if (_ref = blob.type, __indexOf.call(QR.mimeTypes, _ref) < 0) {
+ return QR.error("Unsupported file type.");
+ }
+ return QR.handleFiles([blob]);
+ },
+ handleUrl: function() {
+ var url;
+ url = prompt("Insert an url:");
+ if (url === null) {
+ return;
+ }
+ GM_xmlhttpRequest({
+ method: "GET",
+ url: url,
+ overrideMimeType: "text/plain; charset=x-user-defined",
+ onload: function(xhr) {
+ var data, end, header, i, mime, r, start, urlBlob;
+ r = xhr.responseText;
+ data = new Uint8Array(r.length);
+ i = 0;
+ while (i < r.length) {
+ data[i] = r.charCodeAt(i);
+ i++;
+ }
+ header = xhr.responseHeaders;
+ start = header.indexOf("Content-Type: ") + 14;
+ end = header.substr(start, header.length).indexOf("\n") - 1;
+ mime = header.substr(start, end);
+ if (mime === null) {
+ return;
+ }
+ urlBlob = new Blob([data], {
+ type: mime
+ });
+ urlBlob.name = url.substr(url.lastIndexOf('/') + 1, url.length);
+ QR.handleBlob(urlBlob);
+ return;
+ return {
+ onerror: function(xhr) {
+ return QR.error("Can't load image.");
+ }
+ };
+ }
+ });
+ },
handleFiles: function(files) {
var file, isSingle, max, _i, _len;
if (this !== QR) {
@@ -8592,7 +8661,7 @@
dialog: function() {
var check, dialog, elm, event, i, items, key, mimeTypes, name, node, nodes, save, value, _ref;
QR.nodes = nodes = {
- el: dialog = UI.dialog('qr', 'top:0;right:0;', "
")
+ el: dialog = UI.dialog('qr', 'top:0;right:0;', "
No selected file
")
};
_ref = {
move: '.move',
@@ -8602,6 +8671,7 @@
close: '.close',
form: 'form',
dumpButton: '#dump-button',
+ urlButton: '#url-button',
name: '[data-name=name]',
email: '[data-name=email]',
sub: '[data-name=sub]',
@@ -8665,6 +8735,7 @@
$.on(nodes.dumpButton, 'click', function() {
return nodes.el.classList.toggle('dump');
});
+ $.on(nodes.urlButton, 'click', QR.handleUrl);
$.on(nodes.addPost, 'click', function() {
return new QR.post(true);
});
@@ -9039,7 +9110,7 @@
imgContainer = $.el('div', {
className: 'captcha-img',
title: 'Reload reCAPTCHA',
- innerHTML: ' ',
+ innerHTML: '',
hidden: true
});
input = $.el('input', {
@@ -9047,10 +9118,11 @@
title: 'Verification',
placeholder: 'Focus to load reCAPTCHA',
autocomplete: 'off',
- spellcheck: false
+ spellcheck: false,
+ tabIndex: 45
});
this.nodes = {
- img: imgContainer.firstChild,
+ img: $('img', imgContainer),
input: input
};
$.on(input, 'focus', this.setup);
@@ -9062,6 +9134,9 @@
this.setupObserver.observe(container, {
childList: true
});
+ if (Conf['Auto-load captcha']) {
+ this.setup();
+ }
return this.afterSetup();
},
setup: function() {
@@ -9081,7 +9156,7 @@
$.globalEval('window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: RecaptchaState.timeout}))');
$.off(window, 'captcha:timeout', setLifetime);
_ref = QR.captcha.nodes, img = _ref.img, input = _ref.input;
- img.parentNode.hidden = false;
+ img.parentNode.parentNode.hidden = false;
$.off(input, 'focus', QR.captcha.setup);
$.on(input, 'keydown', QR.captcha.keydown.bind(QR.captcha));
$.on(img.parentNode, 'click', QR.captcha.reload.bind(QR.captcha));
@@ -9141,6 +9216,9 @@
},
clear: function() {
var captcha, i, now, _i, _len, _ref;
+ if (!this.captchas.length) {
+ return;
+ }
now = Date.now();
_ref = this.captchas;
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
@@ -9170,7 +9248,7 @@
},
count: function() {
var count;
- count = this.captchas.length;
+ count = this.captchas ? this.captchas.length : 0;
this.nodes.input.placeholder = (function() {
switch (count) {
case 0:
@@ -10952,7 +11030,8 @@
'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']
+ 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,';
@@ -12336,8 +12415,8 @@
archives: [
{
name: "Foolz",
- boards: ["a", "co", "gd", "jp", "m", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"],
- files: ["a", "gd", "jp", "m", "tg", "vg", "vp", "vr", "wsg"],
+ boards: ["a", "biz", "co", "gd", "jp", "m", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"],
+ files: ["a", "biz", "gd", "jp", "m", "tg", "vg", "vp", "vr", "wsg"],
data: {
domain: "archive.foolz.us",
http: false,
@@ -12434,10 +12513,10 @@
}
}, {
name: "fgts",
- boards: ["soc"],
- files: ["soc"],
+ boards: ["r", "soc"],
+ files: ["r", "soc"],
data: {
- domain: "fgts.eu",
+ domain: "fgst.eu",
http: true,
https: true,
software: "foolfuuka"
@@ -12462,8 +12541,8 @@
}
}, {
name: "Foolz Beta",
- boards: ["a", "co", "d", "gd", "h", "jp", "m", "mlp", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
- files: ["a", "d", "gd", "h", "jp", "m", "tg", "u", "vg", "vp", "vr", "wsg"],
+ boards: ["a", "co", "gd", "jp", "m", "s4s", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
+ files: ["a", "gd", "jp", "m", "s4s", "tg", "u", "vg", "vp", "vr", "wsg"],
data: {
domain: "beta.foolz.us",
http: true,
@@ -12656,7 +12735,7 @@
css.push(".emoji-position-after:not(.emoji-disable):not(.emoji-" + (pony = key === "pony" ? 'disable-ponies' : 'only-ponies') + ") a.useremail[href*='" + name + "']:last-of-type::after, .emoji-position-after:not(.emoji-disable):not(.emoji-" + pony + ") a.useremail[href*='" + (name.toLowerCase()) + "']:last-of-type::after, .emoji-position-after:not(.emoji-disable):not(.emoji-" + pony + ") a.useremail[href*='" + (name.toUpperCase()) + "']:last-of-type::after, .emoji-position-before:not(.emoji-disable):not(.emoji-" + pony + ") a.useremail[href*='" + name + "']:last-of-type::before, .emoji-position-before:not(.emoji-disable):not(.emoji-" + pony + ") a.useremail[href*='" + (name.toLowerCase()) + "']:last-of-type::before, .emoji-position-before:not(.emoji-disable):not(.emoji-" + pony + ") a.useremail[href*='" + (name.toUpperCase()) + "']:last-of-type::before { content: url('data:image/png;base64," + icon + "'); }");
}
}
- css.push(".sage-highlighting-image.sage-image-appchan.sage-highlight-position-after a.useremail[href*='sage']:last-of-type::after, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-after a.useremail[href*='SAGE']:last-of-type::after, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-after a.useremail[href*='Sage']:last-of-type::after, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-before a.useremail[href*='sage']:last-of-type::before, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-before a.useremail[href*='SAGE']:last-of-type::before, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-before a.useremail[href*='Sage']:last-of-type::before { content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAABa1BMVEUAAACqrKiCgYIAAAAAAAAAAACHmX5pgl5NUEx/hnx4hXRSUVMiIyKwrbFzn19SbkZ1d3OvtqtpaWhcX1ooMyRsd2aWkZddkEV8vWGcpZl+kHd7jHNdYFuRmI4bHRthaV5WhUFsfGZReUBFZjdJazpGVUBnamYfHB9TeUMzSSpHgS1cY1k1NDUyOC8yWiFywVBoh1lDSEAZHBpucW0ICQgUHhBjfFhCRUA+QTtEQUUBAQFyo1praWspKigWFRZHU0F6j3E9Oz5VWFN0j2hncWONk4sAAABASDxJWkJKTUgAAAAvNC0fJR0DAwMAAAA9QzoWGhQAAAA8YytvrFOJsnlqyT9oqExqtkdrsExpsUsqQx9rpVJDbzBBbi5utk9jiFRuk11iqUR64k5Wf0JIZTpadk5om1BkyjmF1GRNY0FheFdXpjVXhz86XSp2yFJwslR3w1NbxitbtDWW5nNnilhFXTtYqDRwp1dSijiJ7H99AAAAUnRSTlMAJTgNGQml71ypu3cPEN/RDh8HBbOwQN7wVg4CAQZ28vs9EDluXjo58Ge8xwMy0P3+rV8cT73sawEdTv63NAa3rQwo4cUdAl3hWQSWvS8qqYsjEDiCzAAAAIVJREFUeNpFx7GKAQAYAOD/A7GbZVAWZTBZFGQw6LyCF/MIkiTdcOmWSzYbJVE2u1KX0J1v+8QDv/EkyS0yXF/NgeEILiHfyc74mICTQltqYXBeAWU9HGxU09YqqEvAElGjyZYjPyLqitjzHSEiGkrsfMWr0VLe+oy/djGP//YwfbeP8bN3Or0bkqEVblAAAAAASUVORK5CYII='); } .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-after a.useremail[href*='sage']:last-of-type::after, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-after a.useremail[href*='SAGE']:last-of-type::after, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-after a.useremail[href*='Sage']:last-of-type::after, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-before a.useremail[href*='sage']:last-of-type::before, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-before a.useremail[href*='SAGE']:last-of-type::before, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-before a.useremail[href*='Sage']:last-of-type::before { content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAYAAACZ3F9/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAa9JREFUKFOdkt0rg2EUwM95b2zlL0CRRLngksznXrJsNtYW1tjYhM3mY6+IXZAbikhTKJp8XZAp81UmWYhIRHHhUi60e7s6ntdCa2449es8PfU7z+k5B6AbyuE/wQlc4BcO2d06unAUBCgFE0hianOd3NHIcy8NPwrUf9NBPZcOEi7ayXZiea/1V7+ljaXeYAfOgg2So2TOwQWGnwQafOgi962TnMFmatozUeNu4yetASspVvgXiUvii5K5Nm6z56ol3Hdtpy+cwSYy+HRUt1nLsoEato0kXyh6wTac+24brThWv6MNOYNW9prlG/uxmbRrFaT0VrCspZoNPSUNJNyCBcoiLZuhLH0o9U6UrAfGKCz7RlLM81Q8XUwqr4oKPLIQmnA8IupBigacVy7yrya/2JouhryJHJJNykg+UxLGOtz6+SQNpEiMcduls4Wvoli9WklVKz+ol5SU4U6ngql8Qj2eRI+GyajBhSRH4r3cUxhSeRVhsYBmWUWiyM+UMDmDUI2nsfuSC1I27nLgYZJlP8jhjJ3PY8iE+L8tWx4kQC6MQA5b1D9HNiRCFhx8AF/e2qh92VnKAAAAAElFTkSuQmCC'); }");
+ css.push(".sage-highlighting-image.sage-image-appchan.sage-highlight-position-after a.useremail[href*='sage']:last-of-type::after, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-after a.useremail[href*='SAGE']:last-of-type::after, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-after a.useremail[href*='Sage']:last-of-type::after, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-before a.useremail[href*='sage']:last-of-type::before, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-before a.useremail[href*='SAGE']:last-of-type::before, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-before a.useremail[href*='Sage']:last-of-type::before { content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAABa1BMVEUAAACqrKiCgYIAAAAAAAAAAACHmX5pgl5NUEx/hnx4hXRSUVMiIyKwrbFzn19SbkZ1d3OvtqtpaWhcX1ooMyRsd2aWkZddkEV8vWGcpZl+kHd7jHNdYFuRmI4bHRthaV5WhUFsfGZReUBFZjdJazpGVUBnamYfHB9TeUMzSSpHgS1cY1k1NDUyOC8yWiFywVBoh1lDSEAZHBpucW0ICQgUHhBjfFhCRUA+QTtEQUUBAQFyo1praWspKigWFRZHU0F6j3E9Oz5VWFN0j2hncWONk4sAAABASDxJWkJKTUgAAAAvNC0fJR0DAwMAAAA9QzoWGhQAAAA8YytvrFOJsnlqyT9oqExqtkdrsExpsUsqQx9rpVJDbzBBbi5utk9jiFRuk11iqUR64k5Wf0JIZTpadk5om1BkyjmF1GRNY0FheFdXpjVXhz86XSp2yFJwslR3w1NbxitbtDWW5nNnilhFXTtYqDRwp1dSijiJ7H99AAAAUnRSTlMAJTgNGQml71ypu3cPEN/RDh8HBbOwQN7wVg4CAQZ28vs9EDluXjo58Ge8xwMy0P3+rV8cT73sawEdTv63NAa3rQwo4cUdAl3hWQSWvS8qqYsjEDiCzAAAAIVJREFUeNpFx7GKAQAYAOD/A7GbZVAWZTBZFGQw6LyCF/MIkiTdcOmWSzYbJVE2u1KX0J1v+8QDv/EkyS0yXF/NgeEILiHfyc74mICTQltqYXBeAWU9HGxU09YqqEvAElGjyZYjPyLqitjzHSEiGkrsfMWr0VLe+oy/djGP//YwfbeP8bN3Or0bkqEVblAAAAAASUVORK5CYII='); } .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-after a.useremail[href*='sage']:last-of-type::after, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-after a.useremail[href*='SAGE']:last-of-type::after, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-after a.useremail[href*='Sage']:last-of-type::after, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-before a.useremail[href*='sage']:last-of-type::before, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-before a.useremail[href*='SAGE']:last-of-type::before, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-before a.useremail[href*='Sage']:last-of-type::before { content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAMAAACuAq9NAAABIFBMVEUAAAAAXwAAOAAAVQAAKgAAOgAALwAAagAATwAAdAAAYAAAYwAARAAAcgAANwAAOAABcwEBZAEBXwEAQwABbwEBaQEBWgEBTwECdAICaQIIcwgBWQEIXAcARAAALgACdAICbQICdAICcAIBVQEBTgEAQgAAQwAkjCIcexomgSIcbRtCnj9IpUNEmT5LoUNYtFE9lDtClD5dtVJqwmNCmEFMoEh1zGcnfCYnfCc6jzc7kDs9kjxAlUBDmEFInUNLoEpMoExOo0tPpExQpU1Rpk1Sp0pSp1JXrFVZrlhar1Rar1pes1xftFhhtmFit19juFxkuVxovWRrwGBuw2Juw2Nuw2Ruw2V0yWx1ym14zWt6z2980W6A1XGD2HSD2XSI3XdgUJhRAAAAN3RSTlMACAkJDBobHyBERUVHR3KIiYyNkJmanZ6rrq+ws7S5vL29vsLFxsfP0dLU5eXn5+vt7e34+fn5LB88GQAAAI1JREFUGFdNzjsSwjAMRdGn2PngmZAUVHQshP0vArYQYCYDlmxLos3tTncx4xjdAMCEhR1ApLup+bPxtgsQzZ2Mr4iPYROEU129g6it0jJCv6xqFJlpKbl2kr21Zsl/Mo0IBpmrqg7ZnPfgSnKuqhrKwO+AVrSUOjmo5VcEuHzH9CEAXaTDYZ88HGh++QNCDFZ4bvbHSQAAAABJRU5ErkJggg=='); }");
return css.join("");
},
icons: {
@@ -12672,29 +12751,29 @@
not: {
'Plan9': 'iVBORw0KGgoAAAANSUhEUgAAAAwAAAAPCAYAAAGn5h7fAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAzE15J1s7QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACAElEQVQoz3WSz4sSARTHvzMjygpqYg3+KIhkE83DKtKlf0C9SrTRuZNEx0VowU6CuSeJNlwwpEO2kJ6SQBiIUAzFjRDF4wrjKosnGx3HmdehFDfpe/2+z/s++D5gU7IsEwRByICIiAEAIiIAYAFAXsjYVr/fLxMRNVvN+prJ5/OA3+/XERFNf02JyeVyDx0OxyvLNQsnimLKfcf9KRQKXQAAnE6nlf5qMpnQycnbP/kAoKoqsSwLAJhOp+AAwOv1otvtpqxWq73dbt/r9XqvEQ6HUalUEvF4XLd5IpvNZqlerzd5nlf6/f6tTCZjBACk0+nb+XxeW4UrikLJZPImAGA0Gq0NIqJyuSyyANDr9Q5Wu1utFvR6/SULAI1G4+vK8Pv90DTtGwsAJpPpaGUYDAZ0Op3PHAAEg8H3tVqtbrtu21sqyxuRSOQJk0ql9IvF4r7b7f7pcrlejkaj57IsH58Pzp8dvjhc/lsBk0gkbLFYrFqtVvd27+4qOk733ePxPDCbzVBVFfP5fCiK4rvhxfDN/qP9wSasGwwGMv1HiqJQsVg8ZlfTHMepkiR1t05gGJBGmM/nMBqNj9nN9kql0lNN064ARISzH2cQBAGz2ewLu2na7XYLwzBbvxYIBBCNRrFj3BmsAZ/PZ+J5/kOhUIAkSVeA8XiMZqt5efrx9OA3GfcgvyVno9cAAAAASUVORK5CYII=',
'Neko': 'iVBORw0KGgoAAAANSUhEUgAAABMAAAARCAMAAAAIRmf1AAACoFBMVEUAAABnUFZoUVddU1T6+PvFwLzn4eFXVlT/+vZpZGCgm5dKU1Cfnpz//flbWljr5uLp5OCalpNZWFb//f3r6+n28ff9+PRaVVH59Pr//vr38vj57/Dp7eyjn5zq8O5aVVJbYV9nVFhjUFRiWFlZVlFgZGOboJzm5uZhamfz9/bt8fDw6+drb26bl5j/8/lkX1z06uldWFS5r61UT0tfWlbDwr3Ew76moqNRTU7Mx8P75OpeY19pWl1XW1qzr6x5eHaLiojv7+1UT0xIU0uzqadVS0nV0MxkZGT5+PPk497///ra29Xq5eFtY2H28e2hnJignJlUUE1dXV2vrqxkY2FkYF/m3d5vZmfDuruhl5aZlJHx8O75+PZWVVP29vT/9fTj3trv6ubh5eRdXFqTkpBOTUtqZmX88/RMQ0T78vPEvr7HwcHDwsDq6ef///3Gx8H++fXEv7tZWVedmZZXXVudnJp0c3FZU1f79fnb1dlXUVVjXWFrZmy8t7359/qLj455e3q4s69vamZjX1zy4+avpaReWFz/+f1NR0vu6Ozp4+f48/lnYmi8ur3Iw7/69fHz7+xbV1SZmJZVUk1ZV1zq5ez++f/c196uqbDn4uj9+P7z7vRVVVXt6ORiXl/OycXHw8CPi4ihoJ5aWF3/+v/k3+axrLOsp67LzMZYU1m2sq9dWF5WUU1WUk/Au7eYlJGqpqObmphYVV749f7p5Or38fPu6OpiXFz38fH79vLz7urv6+hhYF5cWWKal6D//f/Z09Xg29exraqbl5RqaW6kpKTq5uPv7Of/+PDj29D//vP18Ozs5+OloJymoZ1ZVVJZWVlkYF2hnpmblIyspJmVjYKQi4enop5STUlRTUpcWUhqY1BgWT9ZUjhcV1NiXVkkhke3AAAABHRSTlMA5vjapJ+a9wAAAP9JREFUGBk9wA1EAwEAhuHv3dTQAkLiUlJFJWF0QDLFYDRXIMkomBgxNIYxhOk4wwCqQhQjxgxSGIsALFA5BiYbMZHajz1oJlx51sBJpf6Gd3zONcrqm/r1W8ByK0r+XV1LXyOLLnjW6hMGpu0u1IzPSdO17DgrGC6AadrVodGcDQYbhguP6wAvAaC0BRZQalkUQ8UQDz5tAof0XbejOFcV5xiUoCfjj3O/nf0ZbqAMPYmzU18KSDaRQ08qnfw+B2JNdAEQt2O5vctUGjhoIBU4ygPsj2Vh5zYopDK73hsirdkPTwGCbSHpiYFwYVVC/17pCFSBeUmoqwYQuZtWxx+BVEz0LeVKIQAAAABJRU5ErkJggg==',
- 'Madotsuki': 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAMAAADTRh9nAAAALVBMVEUAAAC3iopWLTtWPkHnvqUcBxx5GCZyAAARERGbdXJrRUyGRUyYbY23coZFGDRFGEYfAAAAAXRSTlMAQObYZgAAAGhJREFUeF5Vy1kOQyEMQ1Fshzd12P9y61AixLX4yJFo1cvVUfT23GaflF0HPLln6bhnZVKCcrIWGqpCUcKYSP3JSIRySKTtULPNwMaD8/NC8tsyqsd1hR+6qeqIDHc3LD0B3KdtV1f2A+LJBBIHSgcEAAAAAElFTkSuQmCC',
+ 'Madotsuki': 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAMAAADTRh9nAAAALVBMVEUAAAC3iopWLTtWPkHnvqUcBxx5GCZyAAARERGbdXJrRUyGRUyYbY23coZFGDRFGEYfAAAAAXRSTlMAQObYZgAAAGdJREFUeNpVywkOwCAQAkAXtPb+/3PLWklTiIlMtDiH4rvpVM22K+WvY+7Z/dOxZ2xkLmYpNWo6RoKMUQJ8SYiozEYiZAuLbCZQsGB+/hC4SwZsdV2rTjSR0+J9tzXL0B4RW5f9VbE94skEEpHbpw8AAAAASUVORK5CYII=',
'Sega': 'iVBORw0KGgoAAAANSUhEUgAAACwAAAALBAMAAAD2A3K8AAAAMFBMVEUAAACMjpOChImytLmdnqMrKzDIyM55dnkODQ94foQ7PkXm5Olsb3VUUVVhZmw8Sl6klHLxAAAAAXRSTlMAQObYZgAAANFJREFUGJVjYIACRiUlJUUGDHBk4syTkxQwhO3/rQ/4ZYsuymi3YEFUqAhC4LCJZJGIi1uimKKjk3KysbOxsaMnAwNLyqoopaXhttf2it1anrJqke1pr1DlBAZhicLnM5YXZ4RWlIYoezx0zrjYqG6czCDsYRzxIko6Q/qFaKy0690Ij0MxN8K2MIhJXF+hsfxJxuwdpYGVaUU3Mm5bqgKFOZOFit3Vp23J3pgsqLxFUXpLtlD5bgcGBs45794dn6mkOVFQUOjNmXPPz8ysOcAAANw6SHLtrqolAAAAAElFTkSuQmCC',
'Sakamoto': 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAQCAYAAADwMZRfAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAxVJREFUOE+Nk19IU1EYwK+GQQTVQ39egh6ibKlzw91z7rn3bvfOmddNszl1bjKXc5rJJGmBUr7Yg9qTD0IalFgRBEYg6EDQQB+GovQyQgiaUZsoLcgHMcr069w7MgcGXfi453zn+37fv3MYZt/n99e76tzVj4JN/hP79fvXnV3hnNabwUBjoOHcgTYOu/JQspgTzsqKgn9BfD4vkWTzur287PqLVy+zM+yePB7KsRXLywTjnSpnZctBkPCdW8ccDuU55vBO8RXbkC/oP5ph19V5+7LIky0OY1BKbZEbLcFSt7u6pN7jLmltCVrr3DV5jY3+KovFEsccB1KJNVpefe10BqS2tqqO4/AuphBB4L/LkrRqNgtJs1lMypLls1kU38mytMLz/E8VIlutqVqX6/weZG52OttRXjbE0cP/FYLRlpVjDXuQ/r77x2XZPKkCHA4HBAIBkCQpAygIAvh8Pu2MZgO0Lz+QSa/sQfwN9RfpVN66XC6Ynp6GhYUFGBwczAC1t7fD0tISxONx6O7upgHILmsqvLcHodOggfiV/v5+SCaT4HQ6IRaLgdfr1bIRRREmJyfBZrNBNBqF+fl5sNsdgE2GiAbp6bmbdbXC7qWQbxMTE7C2tgY6nQ5SqRSEw2ENopaoZpCXlwdTU1NaoECgCbgiU6y8QH+ECYWaTymK7TWdys7MzIwGaWtrg42NDejo6AB1WjU1NZo+FArB2NgYrK6uQrAlCASxn2z6wkuMp87VIAhkE2MEAwMDkEgkYHx8HBYXF0HtkQpRy1BLiEQisLy8rPVNKSsFjEzrXH4+z1hlS4xDhKadNu7t7YPR0VHweDzAEVWfHru6HxkZgeHhYVAURYNjkylVWKArZjjMzqmdVi+QCsLUkQiEjvDvncEkvU7/qQ0Vgukeo48Go87IiCJnZNmipxiz7wXEbVDnbUxQOgM12h9n6qTq6NvapRdtkwaP0XK8RmPuYSbxYfaQ/sJJhjfknuFRURUi7AMOozcCwl94hLZp5F+EioDQVwqYI6jomZU1NFtM+rOSxZjVazcyvwHr/p/Kws1jegAAAABJRU5ErkJggg==',
'Baka': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAA0pJREFUOE91k3tI01EUx39JOpA0H4jNx0pbD3XTalISWf8YFlEgldqDsBLLyqjEKBCiLLWiggh6/KEV1WZ7OaelLZvDdDafNW1JFraWe/32+01FrUZ9uy4ylLpw4Z5z7/nc77n3HIqaMRIjZJyEcNX+uFCFeGmI/GZciEIsCFJUTvoAzDz+1y7K76MSwhX5hXl6z+WSbrzU2KB8YEGDwgrTaxZ3b7xHcaHhR3xw7Z5/UviB1ReP5XSg3+TAqYJOxMzWISFIC0GQDomhTVA9skCnsaAwp/vnMq66dBokNuBR9uFd7T9Z1zCunjci0qcRJUVdoJ3DYOhRnC/qBZ+jQbfeCc+37yjY2UEg0iwvJE0k9l8Z+8xqHmTgot0QLdQgTaQFQ2AsOzlHvOu1S5pwOLsHHo8HjHMCq2MazNvTlByKHyrJLDvdR25jMWRxYx5HjeMH2r1BDOOeguRua4OI14jx8a8YH5tA+al3EHKlW6mYOapb2oZBOOwMbEMseAE12L+jjUh3w+VipyAZ65oxn1NP/GMYGR6Ftn4Qsf7qa9S82Y/l/X122G0uL2TbxmZEz1WhXW8mUol8moXu+SCi/OoQ6VsDh3UUwyQ1k9GOaI5MTkX4yWTGHutvgI1F28sviAlRgxeoRm62HvsyW8En9pZ1TYgi6TntoyQtFm86rVgUoJZRvDnKMmXVAGxWmkAYOBwudBqGcHCvHulrGpGT2Uy+z4yT+QYsCXtCUpp8GxbKhx8gDK0ro+KjJGvzdjfDZnN6VdisLD5/JjArQ2zW66PJOj2lEZtStaBphkwah7K6kMJ/GEulp1bMWhAmMbTozOQRaWRtfoZVgjo4iRra4SYgGi26TwjxVeDKhR7Y7U606ixICq9tr7hd7+OthRWL7yUnJ1WPmXotqLhpRICPHCePtuFV6xdUPTAhcWEtRHEqfHpPyto4hPXLXnzflSEJnFaN3OCKDcsFsrEntR9RUmxARLAUgT5iBPuJsXWDBj0dZjRU9yNV+PTbpjTp9OA/pOSk24nRkXf1J462oPxcJ65f6ULlHSMulepRerYDgvj7A0cKpNz/tyTZqbzXO4t0ZZGQJ34RH11lFHIlA8LIqreCCMUZRY3cd2bwL/5/RmjNSXqtAAAAAElFTkSuQmCC',
- 'Ponyo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAuNJREFUOE+Nk3tI01EUx39BTytConQTt1am07m5abi5KT5S8z2dj1yOEMUC7aUgIoimlmUEWX9kBZGWaamEmE6U1BI1XNPNGTrnHs33IwuSXrL4NgcJ0mNdOHDh3PPhnPP9XoKwcroJYvMQiRSicHCQKCgUyZC9/T5rNet5KUFs0zCZbZMsFmZ9fTEjEEBDp4/KSSSb/4JoGIyWaTYbiykpWEhOxhSHAzWD0aqkUGhWAcVkW58xlvuPhfh4zItEmOHxYDR3MhcdDaNAsKJydAz5IySKRNjEUmy88vjOVaU8F0iPCqCNjEBHkC/UYaGYFwqxmJoKLYOhkxPElg0QsbNtTlmox9yjRD9UCbnoOR+J/lwRWtOCcdXfDc2BPpg0d7CQlIQZPh9KKlVkAQjJ2x2zmOSsQu7hpzUJfBhLjsNQmADjxcT10Bcl4rE4EHc5LjBEhEPn7f1WTqXSLQB/s1Tp7vslsoIkyPPiMJAbi86McBguiaHKjoEqR4jJy2K0nAxApzMN5iUGrclrKVaz2fUvuF4tRbxDKA90w5VjTFyLZKHpTBSq4/1QnxGB2qxoVIZx0JopRCPHFSNOThfWZzfrXDcZEowH4iA05ATg68hDtBaL0HAuCm3lJ9Bfcx2fFNUoi/DCjRgfNHHd1wCZA2TyXjNkE6F0cBDpPFiojeNi8EkJdFoN3vXch0nbBJOhDd907dANv8JITxNqziag3ZsJbUDAwLin50Q9QWwl1qSYoNOVvUcOoqOqAAa9Fu9H2/F9+B5WZLcwOyxFX18flLI+VASyMGVeoJHD+Tzq5BS1PoaKRrNT8127P74swsq4FCa9FKvqBqwaOiz3hdEuLKueYSyECT2LNW0eIfo3E/WmEbvnG1MUJnWdpWhDGDvxQXZHo+RR0uW2tnv+auPX+TvtJm7zKpaen/4y2yjBUlcxlvtvmvT16ZWDpQeoVv3/60F/NrHjTf4ugazIXtJ8ivjnz/sJ+yGQRjcqUdIAAAAASUVORK5CYII=',
- 'Rabite': 'iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAD/0lEQVR4Xl2MXUxbdQDFz/9+9Lb3tkBLCxTKhzgoOOZAsokbJmZxDFHnd+LL4hKVzBgfNCY++ODbjDEaZowvErOM6HRu6hKZY2rIAOkCY4OSDTpFaAsrlJa2t5+39+NvjT7tnJzknIfzI98Nf/C6TuXdguWBd1q9rcb8/CwsZiu2Ywm4nDVo3VWLZCKDaDwJq9mCg31PgjAMKKUwmcyYvTbek9iJRDm6M/XswEDjwNz6plWW6wdZhjUAintFCEEhn0N04zYskljaDLaj8ar49oUrsYR6mrFJNj322w46H8y+mitM/ZJKZmyE4XAvjJSsazpyuSzslVZIkgWKOvvRgQ6Xrdlhqmds7o7bFZoLkctreKxf7GtuCE7IyUQjBQcQ8j/lvxCGQJZz0IoCVpamTtzfIh9nwiaIrCQyjNg8mq11oDLUhNXRJfT1Ozr3tS/PqpnQ80qRgjAmKIqBfK4ItbSLKoOZqR/6neLkENlSUAIhlktvEf+sD2rkm8nWTHtvZCGMVON1ePuaoBER31/MXGly1wSqq9Uug6FluYyWXJiPqFXmjd4Dh9oF9ZKKimYXRtYCx8lmMIDIxlIPGz591av0mtanF7FcCEN6iMXeox2wOJ0QJAmUAoRQaIqCnWAQY1/ewKNGNeQuYXkm0d2NC2e+wvmRr/Hx+6+8PHayrbDyyQBNDb9As3PHKDWG6MTM23RoeJAWsqeoWvyUUv0UHf7pBB0fe4OeeXe3/vmHbx3+8dwIGJ4IsFpMMFe0fbtAn+nwZePr1u4MBK8XIALG/Rt479wYrs2vgeNNAMNgMbiNzybuoKVvn+Gs9kbr6qpBfJfGYHFIkJUCoGwfqcoMX/b27EGhwgOjoCADDlP+CA51ugFFRzoB8FYNaQ1oqKD44+eNL+wNj7zJGQSIhe8+jgQ9thk+27v/KRY6L4FSCkVOwtlQj6P73Qgt/o1ERoKt4iUkE7+jrZMHyzIoK9cOBFfT4LbWAk+0a7ZLnvqHcTNdACgFScfAcjxEdy00VQclHGo7dqGeYxHbvIo6hwhSghCehb3G5p6eW7VxXC5/xGWToMgrKKoaCnIalI9CIARasQAqloMI/x4BWrLLYwE1AEPTwCGHaGjz7pw/leZUNV8wNm9BLy6CxsvxZ1kMbaY4TKIIXlNBsynoVjvAC4CuAoYOVi+CMfLYCUfg95tPHuzZB0YtKzsb58RMucWE/fZmhCbdOP9rNnLnxko6GVoB8lFwyVVw8b/AyeulHoJyN4Rb19dTFyeqBlu6njvfsWcvOJvLs7DMmw/7bvpeE4pU2OIcgcqmp4fGAgt2Txwvqr7lTp5V7LquZxXC6+BqEvGcY5pyjaM1tffJbk89NE3FP5VQ6y7a+paZAAAAAElFTkSuQmCC',
- 'Arch': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABCFBMVEUAAAAA//8rqtVAqtUQj88tpdIYks46otwVldUbktEaldMjldM2qNcXk9IWktQZkdIYlc8mnNUXlNEZktEZlNIYktIWlNMXktE7o9klmdMXktFHqdkXk9EWk9EYk9IlmtQXlNEXktAWk9AWlNEYlNFDptkZldMYk9E4otg/p9kXktEXk9AXlNA4otclmdQXk9IYktEXlNEwn9YXk9IXk9FFp9o3otgXk9FPrdwXk9E2otdCptkXk9E/ptkcldIXk9Edl9IXk9EjmdUXk9EXk9EXk9EbldIcldIjmdMmmtQsndUvntYyn9YyoNYzoNc0odc1odc2odc6pNg7pNg9pdlDp9pJqttOrdzlYlFbAAAARXRSTlMAAQYMEBEVFhgcHR0mLS8zNTY3PT4/RU1kdXp6e3+Cg4WIiYqMjZGXl5mbnqSnrbS3zMzV3OPk7Ozv8fT29vf4+fz8/f7SyXIjAAAAmUlEQVR4XlXI1WLCUBQF0YM3SHB3a1B3l7Bx1///E6ANkDtva0jKbCW2XIH1z2hiZEZ4uUgxo7JedTQye/KN/Sb5tbJ+7V9OXd1n+O+38257TL+tah3mADAwSMM7wzQWF4Hff6ubQIZIAIb6vxEF4CZyATXhZa4HwEnEA+2QgoiyQDnIEWkjVSBBZBqXbCRlKYo8+Rwkyx54AOYfFe7HhFa7AAAAAElFTkSuQmCC',
- 'CentOS': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB5lBMVEUAAADy8tng4Ovs9tnk5O3c7bX44LLduNO1tdDh7r/eutj43q2kocX23az07N+qqsvUqcmXl7331ZXJj7r40o/Pn8T42qP63KjNw9n21p3Y387Ml7732JzR55z05MSxtMLGn8TC4Hx8eqt8e62Af6/B4HnG4oPC4HzH44fBf7LCgbOkoMTcsrmtn8PWqcfFtKrj4Jvs2ZOz2FnMqLXT3KfY5p60Z6NUU5XRuqHzwWSywqDn3JaiiLWahrWhkry5zJjRmqm1Z6P1wmb1y319fK632mK5cKi5nH+73Gu73Gy73W283W+9eK17e6y1yZS3aqRZWJdcW5ldXJplXZppaKBwb6VwcKV5eKswL306OYNPTpGkfK+m0kGpUJWq1EnEqIuXK3+Xh7ahP4qhkryMfK6BgK+CdpGMaKKMa6O9ea2+eq6+oYW/eq+NbqWVlL2Wlr7AjanA4HnA4HrBkqbBlafB33rCgbLCmKjCxIzC1mSs1UytV5mtxIWt1lCuz2evWpuvXJywxYzHjrvH4oXIjrrN2HXO5pTO5pXUlYnUlYvVl5Hb0G7e0XTg03rhr5fpzHPpzXTp0Hvtz3/wrDHytknyt0zyuE3yuVHzvVr0wGP1x3T1yHf1yXe0ZaL2zYP30o730pD31ZeRIcF5AAAAQ3RSTlMAFBkbHEhJS0xMTk5UWWBsd4SEiIiPkJCVlZaam6CjpK29wMPDxMTFxcnK193e3+Dg4uTn5+fo6e/v8/P4+fn7/P7+J4XBAAAAAOBJREFUeF5Vj1OvAwEYBb/yGlu717atLW0b17Zt2/6nze42TTpvMw8nOZCAmwUpiIY6c5IiLi9tPX64GairqszHQ4X2VB64v1Cs6PxMPJSdHM777s6/jyaMRGiRLyyrb88OpjZ3CzAXrm1sqzSNNeN7kVBPNgB7cG51abE5l9cXDces7emQ1uadHhutFUg6gpPKkSIqQGavwz7r7O/+/3t/rSdjI9XDM3qz4fr3B/3iA0aJTG9x71+9oR/PLDwUe2wm19bly+fTIxHyEETatbPewGEw6Mk/tKZCEqSQQUlIHB/QNBEjjVN1AAAAAElFTkSuQmCC',
+ 'Ponyo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACAVBMVEUAAAAAAAA/AAC/AADMAACqAAC2AADGcQBMGQCyZgDMGRnEYgDMERHJGhrOGBjHeQvSISFPGgjNgyDQHh7MHx9QHgqBGhHLeQzQHh7OGRnSHR3WJCTTJCTQGxvQHx9jLBbKfxjPGxvPHh7QOB7TJCRrLRrTJCRZJhHbljjeqmN3OibaLS1+NyXYMDC8NzPaKyvYKyvaLS3YOincQEDorFvbKCjdNjbaKCjuypjZMjLcKyveLi6GRi/hOzvhMTHrs2ftxpHXLix/OCODOCeGSjOHRy2IPyqJQSqKSy6PTjmQQS6XSDGZMSefWUKgTzehUz2jVT2kVDqkbVSlWUGmUTema02qZUqrbkyrckCsMSmwNyywbEyyQTm0XkC1YkS1ak+1gVK2Qzu3iVq5Ni26Qjy6oHy9JiG9ZUnCb0vENCLFxcXGdVLGpIzJdVDKfFbMd1HNqILQysXScU7Sck/TwrDXRS3YSEbcS0rdLy7d0cHd3Nref1XfSknfflTfhFnf3tzgwp3hLi7hgFXhglfiLi7iRUTiTU3ihVnjMTHjSknkMDDlODjlOjrlOzvmPDzmrFzm0bbnTU3oT0/oUlLpU1PpVlbpWFjp1r7qW1vqYGDrvoHs1rnt0q7vwH/yz6HzypLz2bb306L43bn50Zr62Kv637r82Kf83LD83rb837f84b0dlQysAAAAQnRSTlMAAQQEBQYHCQoKCg0PExUXFx0fISgzOTtCRUVMTVJSXFxcXGNqa3BykJegp6mqtLS1t7/Jz9DU1trb3eTn8/X2/P3IgXZJAAAA30lEQVQoz2NggAJmSUUlPgYEYDNs6es150II6HfNmNZhIAznizlOmdzdONFWCsLlENVyTixPKZs004oFxFe3CfDLyI5zi2mb2iPHwCCoqhPYXNvU1FQd7FNjJsLAwCSfl5+bXldU3B6bJsHMwKCr5+Tu6hHtHxbqHR+pBjRAu9U3YmFCeFLOPBfPKBVeRgbZipCCqoblKxdVlgQlG1uyMrCYZqbWz148f0JWoVennTRQj4DR3AUrlixdMX1OqbUM2FncJstWAMEqC2UeqLv5Nez7ZzloCiH5lV1cgRPKBAApxz0bK1ScOQAAAABJRU5ErkJggg==',
+ 'Rabite': 'iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAD7klEQVQYGQXBW2xTZQDA8f93zmlPe7qOrVvXyzY2B6ybTLksIAImanTiDGimb/pAohISEx980TffTHwjPviiDxiNokajMSAQIwEGIwzYTWAFcZdudOt9bdfbuXz+fuLHrz9935bFnbr3yY/6Y/3O9PQkXk8T6UyeYHuY/u1RCvkyqWyBJo+XQyOvIRQFKSVut4fJG5cO5HPJlCZz42+MjvaM3l5ZayoWu0+oiuqABAAAAEAIQa1aIbV6D6/PQAiFdCrbkU3/cjGTN08rfp/fzvyVY/fTm+9WauN/bhTKfqFogAQAAEAgsC2bSmWT1rYmfD4vdXPy84NDQX9fwN2t+CND91qsIMnzizx/xBjp27p0pVjI90g0EAIABCBAKIJisYLV0Hl0f/zkth3F40rCjaH6DEUx+s5uRgO0LfeycPY+I0cCu/cNzk+a5eWxekMiFDf1ukO10sBsSBqmws3xX4+0G1dPifU6SsJNplJaF7OTE5jJ76/2lwcPJ2cSbPTcIjbSiyUMfv69fLE3Eo6HQuYeR5HNlbJVmJlOmh2e1cMHXxzUzXMmLX1Bvl2MHxdrS3GSq/cPqInTl2P1w+6V63PM1xL49qrsOjaEt70d3edDShBCYtXr5JaWuPDVHZ5zQhT36PM388PD6rN795LLOyu37q7+W639cTTQoWsD/X6697fiHxhkYibJb+cfs2egA3DQNDdnrqXpjUWZW5h2HlpPvR3eOhhXXEKnyevG0zJwZka+PjSxmV1pGi6jx2IgdC7NrvLxTxe4Mb2I5nKDojC3lOaLKw/YMbLPaQ/FUp2dIbRgWzvegA8j2Ar19LaO8q0uJTRITfFQz+c4OTbM0PYou3aGKaSKlPLwyZu7KFmwtUVqldTsCc32faA4AjKJxy814tlvlq/+8GVvp4rt8iGlpF4s0N7i5dj+CLn4fzz6J0N18wXSCYXekI7LMGjeYh1cWiihrS/GXx20/Oe6up9hqlQDKRGlDKrmwohEsUwbKTSiQ9vp1lQya5fpDBgIVUG4VFrD/sj12wt+TatUXwn6fdSLj2iYFrViCelKoQuB1aghjS0I3UCoIJEEu7xIBxzLQqNCannt8e3ZjZJmmtWas3YXuzGHzG7hYXOGAXcWt2Hgskzk5gZ2Uyu4dLBNcGxUu4HiVMklkszOej47dGAf6tjYsXRzw3onpOGOqC1MzVSZym8kvdYGml3SPR6JapZQagWURhmlkqeWzfFgPr/x953wh31Do99FoxE0f7BrZt7leXliauI9vSH1dS0Qb+s9eupCfKa1K8tb5sT8bpdab7Vte7MuXDZaOJ+tBK5LredsOPpEMdLVjWWZ/A+8EtJREuofIwAAAABJRU5ErkJggg==',
+ 'Arch': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABCFBMVEUAAAAA//8rqtVAqtUQj88tpdIYks46otwVldUbktEaldMjldM2qNcXk9IWktQZkdIYlc8mnNUXlNEZktEZlNIYktIWlNMXktE7o9klmdMXktFHqdkXk9EWk9EYk9IlmtQXlNEXktAWk9AWlNEYlNFDptkZldMYk9E4otg/p9kXktEXk9AXlNA4otclmdQXk9IYktEXlNEwn9YXk9IXk9FFp9o3otgXk9FPrdwXk9E2otdCptkXk9E/ptkcldIXk9Edl9IXk9EjmdUXk9EXk9EXk9EbldIcldIjmdMmmtQsndUvntYyn9YyoNYzoNc0odc1odc2odc6pNg7pNg9pdlDp9pJqttOrdzlYlFbAAAARXRSTlMAAQYMEBEVFhgcHR0mLS8zNTY3PT4/RU1kdXp6e3+Cg4WIiYqMjZGXl5mbnqSnrbS3zMzV3OPk7Ozv8fT29vf4+fz8/f7SyXIjAAAAlUlEQVQYV1XNQwIDAQBD0dS2bdvmNLV5/5t0UU52728CvGayQLx8UWz1eKoXhdBqmRaF6mbdVfzZXWgetomfpY3b4Hruqb7B97hf9rtT5mNZ+7ggyaHuHTxzzqIxgUy+LG+RWSBFjrQAgAhJF+Ak6ykA0PRJOgAj2QlKAOTISkADKMM1Mg4YJmXr585cEozw2vE3m/8J5h8V7jsI1XAAAAAASUVORK5CYII=',
+ 'CentOS': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB5lBMVEUAAADy8tng4Ovs9tnk5O3c7bX44LLduNO1tdDh7r/eutj43q2kocX23az07N+qqsvUqcmXl7331ZXJj7r40o/Pn8T42qP63KjNw9n21p3Y387Ml7732JzR55z05MSxtMLGn8TC4Hx8eqt8e62Af6/B4HnG4oPC4HzH44fBf7LCgbOkoMTcsrmtn8PWqcfFtKrj4Jvs2ZOz2FnMqLXT3KfY5p60Z6NUU5XRuqHzwWSywqDn3JaiiLWahrWhkry5zJjRmqm1Z6P1wmb1y319fK632mK5cKi5nH+73Gu73Gy73W283W+9eK17e6y1yZS3aqRZWJdcW5ldXJplXZppaKBwb6VwcKV5eKswL306OYNPTpGkfK+m0kGpUJWq1EnEqIuXK3+Xh7ahP4qhkryMfK6BgK+CdpGMaKKMa6O9ea2+eq6+oYW/eq+NbqWVlL2Wlr7AjanA4HnA4HrBkqbBlafB33rCgbLCmKjCxIzC1mSs1UytV5mtxIWt1lCuz2evWpuvXJywxYzHjrvH4oXIjrrN2HXO5pTO5pXUlYnUlYvVl5Hb0G7e0XTg03rhr5fpzHPpzXTp0Hvtz3/wrDHytknyt0zyuE3yuVHzvVr0wGP1x3T1yHf1yXe0ZaL2zYP30o730pD31ZeRIcF5AAAAQ3RSTlMAFBkbHEhJS0xMTk5UWWBsd4SEiIiPkJCVlZaam6CjpK29wMPDxMTFxcnK193e3+Dg4uTn5+fo6e/v8/P4+fn7/P7+J4XBAAAAANNJREFUGFdjYIAAcW4oA0rJOFnywkVk1VVNWyf1OehpaQqABTW8213jJna5lfnECoMF1NqaC2MmdM5tyfKHCJi4FpV69nc05VTXK4D40hVVtR5ehjqZDUkJNjwMDKKOBeUlxcZ8EnbJiSnB5hwM7GbRuRnpulJyFvHZ7mlKLAwMXLZhofnh9tYLF8ycrs8EMkQ7Nc830K93/jznOZJgW1RcfIMiG3tmOM+aKgIWUI4KCYio6Z42e8pkiAC/oKC8VV2lgZiQEBvcP6xGioyo3uVkhvIBH9A0EWEgTIIAAAAASUVORK5CYII=',
'Debian': 'iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAZ5JREFUOE+Nkk0oBHEYxv8fu5GQj3JwcaDkIAc5IpR87M7MKnIVJVKclaIQ5Sy5OLkgR7n5OigcSNpmd2c2Vyfl4KT8/muWiVU79TTv+7zv837NCBF6PG1X+NpZyEYSD9mIc+tHnBPe23B9xKrCuTmbQA/JKfABrhBswa1hH4A38IwfOxPdX1qcjiCQxO5NyrjKV70TnSbeRPwJvGN3i4yyqnEucPY8ZZX9GSEgGK+RvFfyjk2VKZxzBNG8wJWWgh/xtDOeUXZ7Slr6TrSLYL9N4SMgYTTcwdc2ArvJcElhSVcM6mCNSV8n9hA59yTU5UWMG6HIbLhIWlglgWiC2L4Z79qTdo40D6ISuOWwKCWHyk9Fv8ldpUHOuGTuynwSBUynddPdlbEosVpP9Eu4FnOsRzUYNTsdmZN/d5LDiqM0w+2CMdAFFsFGWgfXxZnheqe/z+0puwEM0HHYV3Z9Sgz8TEz7GkQvpuJ/36ggj2AaHLrSlkULWV5x+h2E8xkZL16YVjGNaAUscfZ/f6c/k9ywLKI2MMcRWl0RLy007idmRbQJ7RIfDAAAAABJRU5ErkJggg==',
- 'Elementary': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAAAEgAAABIAEbJaz4AAAGcSURBVCjPfZE7aFRhFIS/+TchRAtRlBQqiMpiEILsf/cBoviqxC42hliktsgKK4gKkS2sUkRUUFCwCGoqZclFiIUQWN1k790gKFHBxkdhYSMIgeT+x+KqpTPdzMBwzsjIUS2GMfN4IFXqHi19zHUHIPl61rFt1tIM09Zie7bs6xKADMnPM2Tn3VG7okVzHLHJsOIe6ld6xgyjVPeJ7/cN/7N8yDD8cf9l/8DIZr9YqhuqFLOOHS640GE0Wch7o2/hdO9NbWhjtVBzYYzZdDXcVvzP3sRgYQ0635nbOOfM25IcVZ79OQebYLn7ASR2KXJ4euU9DGavc3tkqy6qAeAvcwrvoG8tCHQAINoysGBPum/Bn6BJExyp7Us+WVcVqJR5aQ/Sa1DZrcfcsM+kTmkYBc1yKbofYmskd6F8NvR4nl5X1RJVillbc3aMg0BbrbBXETvsQjrvh9Uu1Apff9xb5yp3wgSpdnJSfbxYH195F/UrtlvdGAP52L/Pv/iXpWGf+BgZMkAqTWpKT+2VOiGjpCrj1uzdNCMP/G/u39MktJ21xpKNAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDEzLTEwLTE1VDIyOjIzOjU0KzA4OjAwkOuuIAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxMy0xMC0xNVQyMjoyMzo1NCswODowMOG2FpwAAAAASUVORK5CYII=',
- 'Fedora': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABPlBMVEUAAAApQXIpQXIpQXIqQ3UpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIqQ3QpQXIpQXIqRHYpQXIpQXIqQ3QqRHYpQXI8brT///8uTYMpQnM5Zqg5ZqnS1+I4ZaY4ZactSn8uRnYrQ3MrRXgsRHUsR3s8bbM8brMtSX4wUosxVI01XZw2X50vUIguToQvR3c6X5o6aKs6aq08Un8qQnM9VIFDWINJXohKcKlXapEqQ3UvUIc2X55bhcBdcJVgcpdhfapmd5tuk8dxgqJ1hKR5jbB6iah/m8Shudq3v9C4wNG/x9bFy9nFzNnFzNrIz9zK0NzK0t/O2+3P1eA2YaDU2eTb3+jb4Oje4urj6fHm6e/s7/Tz9fj3+fz7/P38/f3+/v83YaEa/NNxAAAAHnRSTlMABAoVGyY1SVlpeIuQsLfDzdHW4+3y8/b39/n6+vr4+ns8AAAAyklEQVR4XiWN5XrDMAxF75KOknYdZJS0klNmHjMzMzO9/wvMcH7I37mSJShsJ+5NjMT6umDoHyXDcI/2qJadh++P3cle1de+9yPe3/bTY92wzfzr7wGtP3JrAI72BZGVtcAdQlwHy+JS1pDbBE9qamZF3BYrjQxPEXwKc6dC8bXFm0QIpmt8kn0Rn093q82UCtK8oXZckwFJzuulV8bHkajPyXdbnJnARfDHs0trz+JQ+5AFvzp/L0+cL2qPAINUPrq5OC6p/64F/AMnrST+Dq/r7QAAAABJRU5ErkJggg==',
- 'FreeBSD': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAABIAAAASABGyWs+AAAABmJLR0QA/wD/AP+gvaeTAAADXklEQVQYGQXBS2wUZQDA8f83j33M9rF9d7u4loaWklaDpkSo9KDGaIKUaGxshD2YSPRiuDVeTDyhBxosJCoa40ktpAkPDcUqAYVIpUSUPrAulEdD2bbb7e7ObGcfM/P5+4kwKDvq6yJ1FYYcvb+YAkqAHo/HQ7FYrFIoCiurq9ZXJ06YSOkA+kBzfX06bys3zHxS9EL0tXDVyZfefacqV+X/ZSJx5+qLbx98LhaL9RiGEZWlEsWC/Thd9q6Pf3vs2u6Orc83rFsvTwwfLf5obgywT1Vjh2Hh+rbNsnTssJdNLedK5aIrpSuldKVXKsnH4+Pyn6FDXn5tMef9O+3NvdkvP1V4+EYw2AoQ+KSx8dRYS6NXXnwovaItXduSrrkinWxGOmZWJi9OyOK9m1LmsjIz9IH8QUMOd3WfAQwNKCy2tJwbHB5+XasPaxIHmc4g7WWEZ1MquBiRFlJTf1E7+Tl/H/8asavPzTY1nWd2ZkMDRPeBeHPz5ojwsilEQCBvTSKunCF3M8FSNkBGVTHDYYrLj8jVNhDZ2SMa2zo3MTamaIC/u6Ojr3DtrOrvP0BpdATnyBeIhTxpR5ABUlKSUlXS1dWstbVxdz6hPL0l1quGqkLaKwNvVcjEXNRd/4mit4Z19DjefBEPyCKxgQJQcF28dBrHNDGTSZSezsjeff0hraa2Vs2vrvit81O4vj9xLJcC4ADrQA7YAGqBGsAql/EtLdFQE/L7dF1XZmdnSrbPMJfXoLDmolQK8gJyQBowgQhQDRQBD+hsraVhd4e5MH+/oExfvWLJ9q3/3S7qMpNH2hsS40kFS4EUUAMA2IANRIBXv4uzuO67c2PykqkA5YmZ6bN18YPi0Yoknxc4AsJPCMLVAk2BLKDosCWqs/PZaulkuxk9fekcUBAAQGDks5FT0W++3NuYuC0DVUL4DIEdlIQDAj0IRkigaMjArkFx0tf523sffrQHyKsAgHPhwoXLL+yP9/kePNhk5ExUTyKFkJVAUAiCFZrQup4Rv9ftuLV/6ONBYBVABQAArMvJ5MXW7duD6P62sD8UrPAFRU1TpeCpCnGvPZr7WW///v0jpw+VC9ZdAAABAAAAAMLo7drWrmQyPWG/r8tnaGIjaM05ujr16x/ZBFh5AACA/wGZnIuw4Z4A3AAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxMi0wNy0wNFQxMDowOTo0OS0wNDowMOPVpFwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTItMDctMDRUMTA6MDk6NDktMDQ6MDCSiBzgAAAAAElFTkSuQmCC',
- 'Gentoo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB9VBMVEUAAAD///+AgICqqv+AgIC/v9+Ojqqii9GAgKptYZKQkOmPj/ddUYBgW4eVjeCTgfiWjO5wbJaZkvPBvepkXomYkNldV4Bzbpl6dJ+Uj7ynoO6Vi+1qZI63se2mnudjXYjOy+GCfaqZjvWlm/Pc2e+Oh7NeWIOWjfeXjeW1sd+gl+diXIfp5/KHgKnn5/F2cZx6c6ZgWoXc2e6dltrAvNu0scrX1eTOyujCvup4c5qpovVpY43///+6uPPJyPXq6fvm5vrz8/z8/P7+/v/d3PixqvmxrPSyrfe0sPO0sfS3tMve2/3r6vy6ufPz8/3d3fi3tM63tPO4tsu5tsu5tvO6tfe6t/Vva5KRjKy7tvW7t/W9vPO/vM+/vvPCwfPEw/TFwvTFxOfGxfTGxvTHxvTIx/TJx/aTiOrNzPXNzfXQzfnRzuHS0fbS0vbT0uHU0e/U0uTU0/bW0+zW1ffX1vfY1/jZ2Pjb2/jc2uSTiemVkLSlnvbe3PTe3vng3fzg3f3g4Pnh4Pnh4fri4enj4/nk5Prl5Prm4/ymn/bn5vro5/rp6O/p6funoPWsqs3t7Pvt7fXv7vzv7v3w7/nx7/3y8f3y8v3z8vytqPWuqPX09P319P319P719f339v739/34+P35+f37+/+uqev9/f6vqvSwrPQAR0dcAAAAPHRSTlMAAQIDBAgJCwwVFyAsNUFHSVBneH+Bh4mVmZmanKCxsrK2tr3ExtDW19rb4ODl5u3t7u/w8/T6+/z9/f4MkNJ1AAAA8ElEQVR4XjXNw5aDURSE0YrRtm3b54+dtm3btm3bz9k3Wek9+2pSYFwT8ibzE93hwAtdJqK3nZo4J9hFXbP+vFHOthV6gnGzstZq94wdCs4UCCDymQ2v7X0LdYoSQ0MIENRYzJbRlPTTHu73ZNAL8vivmVui98PpzuqffX0mIPHJGtOQenukteJ+aS3b9htNpDnT9TeZH1bHAwBRMhGpd6e6uNrLoRgxBKmsX47nBlp678ojpEA40fejcmW4e/No0V8IIPfj6eKgbEJ3ZUnzgE1OqWp9Q3VeWRAsg51f1dZ8c31RmAsc+N5JGbG+zvj3BzDCPrzMDC9SAAAAAElFTkSuQmCC',
- 'Mint': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACVVBMVEUAAADh4eEAAAAAAAAAAAAAAAAAAAAsLCyXl5dgYGCnp6eTk5N3d3fBwcGqqqq8vLzNzc3Ozs7Ozs7Pz8/Pz9DQ0NHR0dLS0tLS0tPT09Pf3t/Pz8/i4eLb29vZ2drZ2tna2dra2trf3t/u7O/u7e/u7O/r6+vt7O/w7/Lw8PDy8fTz8fXz8fbx8fHz8/P19fb49/j49/n6+vuPxlmWyGOx437h9NDr9eD6/fj////+/v75/vTA5Jv6/fb7/fnL5bDL5q+AxjeDxUCEzTyGxUaGzjyHxkiHzz6J0D+Kxk6K0kCLyE2M00WNy06P00mSz1OUyF+W2FGX1FiY0F6Z02CZ21ac0Wiez2yfz2+f2mOh4GCi4GOi4WKi4mOk12+k3Wul32um1Hin0nun4G6n5Gin5Wmo23Op2Huq1n+q43Cr526s4Hit23+v6XSw34Cw34Gw6nWx4IKy4IOy44Cy63ez146z34az4IWz4YW03Y217nu38H2625e645G74pK83pu98Iq984W+4ZjA4px0tzDA5ZrB8ZDC5p7D55/E947F6KHF+JHH4qvH6qTI46/K5LLL5LN1tzLL5bN1uTDL57DM5bPM6qzM66/N5rTP6LbP6bTR6rfS573T67vT7LrV7r3X68XX7MHX773Y77/Y9rvZ8cHa7cjd88bi88/j8tTk8djk9tHm8trn89vo89zo9N3p9N3p9d7p9tvq9d/s+93s/dzy+erz+O73+vT4/PX5/fT5/fX5/vN1uzB3vTD6/ff6/fh5uTj8/fv9/vr9/vx8wjV/xDmrMRH0AAAAOXRSTlMAAAECAwQJDzk/RUlNU3F0kpSVlpeYmpucnaKjpKWqqqqtu8LExMTEzdTU1NXY4evy8vP+/v7+/v6LaR1mAAABD0lEQVR4XiXI03bEABAA0KltW9kaW3eSZW3btm3btm3b/q4mp/fxgqKOtpamhrqaqoqykrQYABh+PVMU9fjE5Xp8o54kgPHN0EBHU2N5YXZykiua0HHd2759VF2Sk5IYE5GGsmCEWLV1kVWwt5O+3x/qpgsy8k4ja+cJl2/v5C22tlgCAHtw9TQSa4s+AzfPSm0BRNl9SydhWJzLC567KrNhgrNwHIJ5qTz/2f9w7Jw/DNqIjVr04exW0AEOXcN3Ab7enr9eDW2VTJgehONyc2Z8XP5YdD0Tcuhcc4/r45OjGX51TEjYPbh8THRPvbz+CHusgSZlT7rP8PkCwfQKaQUi9Igr6JsRBMFiWZgb/AHKElRzKopZJQAAAABJRU5ErkJggg==',
+ 'Elementary': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAACXBIWXMAAABIAAAASABGyWs+AAAAAmJLR0QA/4ePzL8AAAFuSURBVCiRfVG/S8NQEH4VimAHcXKS+otIsNb2vpc4W0QXF8FBqKOiIEgQKTgEK/gXBKEOIoIIgmMo6KSIkxYXHRxcqhjQQpQKOojES9K0mxwc7919d/fdd8IToemKLMKGw2bLoq5E8dDFyIALixZlAWvsd/BBhog1ACKGMiqkyiVU5SGO8EQzmV66QNmHMICrK4hjHXUt49dgHM+D7ekELslggK7AJVUbxicmo7l4yY56Yqwbrq4IpmZx6FweN9MdcOVQ8CrRpoBNedGGLzkXAWgFpyF13soWcHhAP7xsMkyPdOFRpoL6DXzDYYDehwF4NBUEO+UNbQd9cvhhCANsbYK/1zA9oWm4xbKf1nrwii3K8wgmWeLKVdSxhzfK+Wk5ixoOmIPFJHnNGit3D4/tShZol1Wp0jR3VYM1A6F+YWaTNI8T3OEMZjrBPeOsrtGS+iFUsbmqyn0iqRvHepf7WJApUpmaxeq2jvX/uf8A9h7IjHC1AQkAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTMtMTAtMTVUMjI6MjM6NTQrMDg6MDCQ664gAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDEzLTEwLTE1VDIyOjIzOjU0KzA4OjAw4bYWnAAAAABJRU5ErkJggg==',
+ 'Fedora': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABPlBMVEUAAAApQXIpQXIpQXIqQ3UpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIqQ3QpQXIpQXIqRHYpQXIpQXIqQ3QqRHYpQXI8brT///8uTYMpQnM5Zqg5ZqnS1+I4ZaY4ZactSn8uRnYrQ3MrRXgsRHUsR3s8bbM8brMtSX4wUosxVI01XZw2X50vUIguToQvR3c6X5o6aKs6aq08Un8qQnM9VIFDWINJXohKcKlXapEqQ3UvUIc2X55bhcBdcJVgcpdhfapmd5tuk8dxgqJ1hKR5jbB6iah/m8Shudq3v9C4wNG/x9bFy9nFzNnFzNrIz9zK0NzK0t/O2+3P1eA2YaDU2eTb3+jb4Oje4urj6fHm6e/s7/Tz9fj3+fz7/P38/f3+/v83YaEa/NNxAAAAHnRSTlMABAoVGyY1SVlpeIuQsLfDzdHW4+3y8/b39/n6+vr4+ns8AAAAxklEQVQYGSXBhUJCQRRF0SNYgIooiPJ0zwXE7k6wu7s7//8HdGAteeFoPNne2lhfpYpIioqWWnkNeNv3X+87HXWSIni73/b2updvq1E4hffys8/ag5toUhRv0QpAn5tCcbyiXQBZN4mSQG62ZDf9Q2PdbhplyPacmPe56TZAwcyIOy4828fj7cp4DhTk3ToU7YoKdbleoGiXlKXVOToPbNkpZTEFv25uefXJDvASIWWGF+7M7GyJf4lqqZnBw+vzowEgHQtJfyetJP7BfFOIAAAAAElFTkSuQmCC',
+ 'FreeBSD': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADXklEQVQ4EQXBS2wUZQDA8f83j33M9rF9d7u4loaWklaDpkSo9KDGaIKUaGxshD2YSPRiuDVeTDyhBxosJCoa40ktpAkPDcUqAYVIpUSUPrAulEdD2bbb7e7ObGcfM/P5+4kwKDvq6yJ1FYYcvb+YAkqAHo/HQ7FYrFIoCiurq9ZXJ06YSOkA+kBzfX06bys3zHxS9EL0tXDVyZfefacqV+X/ZSJx5+qLbx98LhaL9RiGEZWlEsWC/Thd9q6Pf3vs2u6Orc83rFsvTwwfLf5obgywT1Vjh2Hh+rbNsnTssJdNLedK5aIrpSuldKVXKsnH4+Pyn6FDXn5tMef9O+3NvdkvP1V4+EYw2AoQ+KSx8dRYS6NXXnwovaItXduSrrkinWxGOmZWJi9OyOK9m1LmsjIz9IH8QUMOd3WfAQwNKCy2tJwbHB5+XasPaxIHmc4g7WWEZ1MquBiRFlJTf1E7+Tl/H/8asavPzTY1nWd2ZkMDRPeBeHPz5ojwsilEQCBvTSKunCF3M8FSNkBGVTHDYYrLj8jVNhDZ2SMa2zo3MTamaIC/u6Ojr3DtrOrvP0BpdATnyBeIhTxpR5ABUlKSUlXS1dWstbVxdz6hPL0l1quGqkLaKwNvVcjEXNRd/4mit4Z19DjefBEPyCKxgQJQcF28dBrHNDGTSZSezsjeff0hraa2Vs2vrvit81O4vj9xLJcC4ADrQA7YAGqBGsAql/EtLdFQE/L7dF1XZmdnSrbPMJfXoLDmolQK8gJyQBowgQhQDRQBD+hsraVhd4e5MH+/oExfvWLJ9q3/3S7qMpNH2hsS40kFS4EUUAMA2IANRIBXv4uzuO67c2PykqkA5YmZ6bN18YPi0Yoknxc4AsJPCMLVAk2BLKDosCWqs/PZaulkuxk9fekcUBAAQGDks5FT0W++3NuYuC0DVUL4DIEdlIQDAj0IRkigaMjArkFx0tf523sffrQHyKsAgHPhwoXLL+yP9/kePNhk5ExUTyKFkJVAUAiCFZrQup4Rv9ftuLV/6ONBYBVABQAArMvJ5MXW7duD6P62sD8UrPAFRU1TpeCpCnGvPZr7WW///v0jpw+VC9ZdAAABAAAAAMLo7drWrmQyPWG/r8tnaGIjaM05ujr16x/ZBFh5AACA/wGZnIuwraa4ZgAAAABJRU5ErkJggg==',
+ 'Gentoo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB9VBMVEUAAAD///+AgICqqv+AgIC/v9+Ojqqii9GAgKptYZKQkOmPj/ddUYBgW4eVjeCTgfiWjO5wbJaZkvPBvepkXomYkNldV4Bzbpl6dJ+Uj7ynoO6Vi+1qZI63se2mnudjXYjOy+GCfaqZjvWlm/Pc2e+Oh7NeWIOWjfeXjeW1sd+gl+diXIfp5/KHgKnn5/F2cZx6c6ZgWoXc2e6dltrAvNu0scrX1eTOyujCvup4c5qpovVpY43///+6uPPJyPXq6fvm5vrz8/z8/P7+/v/d3PixqvmxrPSyrfe0sPO0sfS3tMve2/3r6vy6ufPz8/3d3fi3tM63tPO4tsu5tsu5tvO6tfe6t/Vva5KRjKy7tvW7t/W9vPO/vM+/vvPCwfPEw/TFwvTFxOfGxfTGxvTHxvTIx/TJx/aTiOrNzPXNzfXQzfnRzuHS0fbS0vbT0uHU0e/U0uTU0/bW0+zW1ffX1vfY1/jZ2Pjb2/jc2uSTiemVkLSlnvbe3PTe3vng3fzg3f3g4Pnh4Pnh4fri4enj4/nk5Prl5Prm4/ymn/bn5vro5/rp6O/p6funoPWsqs3t7Pvt7fXv7vzv7v3w7/nx7/3y8f3y8v3z8vytqPWuqPX09P319P319P719f339v739/34+P35+f37+/+uqev9/f6vqvSwrPQAR0dcAAAAPHRSTlMAAQIDBAgJCwwVFyAsNUFHSVBneH+Bh4mVmZmanKCxsrK2tr3ExtDW19rb4ODl5u3t7u/w8/T6+/z9/f4MkNJ1AAAA7UlEQVQYGQXBA2IDABAAwU1t27aNi1Pbtm0rtW277+wMgEN05nRWjBMAgCJgVUTed+sibQEg9EZEvm7V8x05LgCOJSKi1+8XdKmUhT5AyIuIvHUOLDWoyvKb/MG3uVRExuOTzvqUf6fDrthEfc/diXwczXbX/h7kpYCle+qETrQ7Y+1VDysbaYAiTER3bhhsKXpcn/QG8zgR0e7N9Cjrr0bCLTBNEJHXk4Whtv77ymArCBL5eVKvjfZuHS97mQEZn8+XhxVThuviRGcA0ss1xk3NRXW2nzUAeNZsL7Y25gbaAwCYuMUmR3jYAQDwDzDCPrxVMnjZAAAAAElFTkSuQmCC',
+ 'Mint': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACVVBMVEUAAADh4eEAAAAAAAAAAAAAAAAAAAAsLCyXl5dgYGCnp6eTk5N3d3fBwcGqqqq8vLzNzc3Ozs7Ozs7Pz8/Pz9DQ0NHR0dLS0tLS0tPT09Pf3t/Pz8/i4eLb29vZ2drZ2tna2dra2trf3t/u7O/u7e/u7O/r6+vt7O/w7/Lw8PDy8fTz8fXz8fbx8fHz8/P19fb49/j49/n6+vuPxlmWyGOx437h9NDr9eD6/fj////+/v75/vTA5Jv6/fb7/fnL5bDL5q+AxjeDxUCEzTyGxUaGzjyHxkiHzz6J0D+Kxk6K0kCLyE2M00WNy06P00mSz1OUyF+W2FGX1FiY0F6Z02CZ21ac0Wiez2yfz2+f2mOh4GCi4GOi4WKi4mOk12+k3Wul32um1Hin0nun4G6n5Gin5Wmo23Op2Huq1n+q43Cr526s4Hit23+v6XSw34Cw34Gw6nWx4IKy4IOy44Cy63ez146z34az4IWz4YW03Y217nu38H2625e645G74pK83pu98Iq984W+4ZjA4px0tzDA5ZrB8ZDC5p7D55/E947F6KHF+JHH4qvH6qTI46/K5LLL5LN1tzLL5bN1uTDL57DM5bPM6qzM66/N5rTP6LbP6bTR6rfS573T67vT7LrV7r3X68XX7MHX773Y77/Y9rvZ8cHa7cjd88bi88/j8tTk8djk9tHm8trn89vo89zo9N3p9N3p9d7p9tvq9d/s+93s/dzy+erz+O73+vT4/PX5/fT5/fX5/vN1uzB3vTD6/ff6/fh5uTj8/fv9/vr9/vx8wjV/xDmrMRH0AAAAOXRSTlMAAAECAwQJDzk/RUlNU3F0kpSVlpeYmpucnaKjpKWqqqqtu8LExMTEzdTU1NXY4evy8vP+/v7+/v6LaR1mAAABDUlEQVQYGWPgk5QQFxMVERYSFODnYGZgYJA7vMfa2nrXbltbiyOW0mwMDApbuzsbq6sKslJiok0tFYECW9oalqwuyU2NjQoNjLfkYpC3tCxevDE5c/nShBUdfmZSDJw8Rr3zN0Ru2n/AaptlXa0G0FiDrnnrgizLsg95LVqfp8PAwGTQPnutv2VOmp3P9M352iABm5lrfC3T4+w8pkEEDJtmrPJeGBY8y9VmWSFQBYN+c892TzcXp2POlfVFIAGllQGWc2qSIsIz+kMqQALclsalOywXTJjUl+heDhJg1d1pcnBiy+S9+446tmoBBRjY9azMp9rbOzhMmWulycAIFGHhlVFWUVFRVVVXkwUAyhJUc5MwaMIAAAAASUVORK5CYII=',
'Osx': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABrVBMVEUAAAD///////+qqqr///+ZmZn///+qqqqAgID///////+tra339/eAgICoqKjx8fGMjIzm5ubh4eGPj4/g4ODIyMiAgICSkpKLi4vS1tbPz8+Xl5eMjIypqanIyMjW1tZ2dnbR0dGamprFxcV3d3d+fn60tbV3d3dcXFx3d3epqal7fHxxcXF+foCnp6hYWFhyc3Ojo6SMjI5fX196enp+fn6Li4xERERqamqgoKFpaWmFhoeen6A/Pz9QUFCWlpeSk5SUlZWUlZaOjo+Tk5RHR0cuLi5YWFgwMDAeHh40NDQ3Nzc6OjpcXF1rbG0XFxdSU1NVVVVXV1dZWVlbW1tnZ2lwcHABAQEEBAQXFxchISI+P0BISUpaW1xHR0kNDg4qKyszNDU1NTY9Pj8NDQ1cXF4XFxhSU1QSEhIDAwMrKywtLS4uLi4wMDFHSElISEggISE0NDVJSktNTU1FRUVWVlhGRkYEBAVBQUE0NTZQUVJQUVMFBQUqKitWV1lXV1daWlpaWlw+Pj8bGxtcXV9dXV1fX19fYGFgYGBkZGRlZmhpaWlsbGxwcHB2dna844Y9AAAAV3RSTlMAAQIDAwUFBggMDhkeICMkKCgqMDIzPj9ERFBib4CCg4iMjZCcnp+jqamrw83W1tvb3ePl6Ojp6+vs7u7v8PHy9PT09PT3+vr7/f39/f39/v7+/v7+/v50ou7NAAAA30lEQVR4XkXIY3vDYABG4SepMdq2bRSz/capzdm2fvOuDO397Rw0Ly4tz2QAQPbcxuZ2E/STJwfxPhWgG355fRrVAIVb1zeP9UDLfiSwkAcADe8fn7tFxWuEXFRDoer/OgoMTRBCumj8yJwPBo8Zhpk14U856/HI8n0ZUtpZ1udrSzfVneA4roNKjdrwpcMRilb8d8G60+lKnrpWcn9bO+B23w2O8Tzfq4aiNSZJqzn5O4Kw16h06fPZ+VUlUHfo97+VAEb7rSh2UgDd4/U+TBlQY7FMj5gBIGvcarVVfQPVPTG94D0j9QAAAABJRU5ErkJggg==',
'Rhel': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABj1BMVEUAAAD///////8AAAD///////8AAAD///8AAAD///////8AAAD///8AAAD+/v4AAAAAAAAAAAArKysAAAD///////8AAAAAAAAAAAAAAAD///8AAAAAAAAAAAD///8AAAD///8AAAAAAAAAAAAAAAB5eXn+/v5JSUnKysrS0tJ5eXmqqqqxsrL+/v4ZCgknJyeHh4eIiIjo6OgZCAdOTk7t7e3///8GCwwPAAArKyv19fX29vb9/f0EAAD////+/v4AAAAGBgYHAAAJAAAMAAANAQAPAQAVAQFyCQV9fX2pIRzmEQjn5+cBAAAFAAAAAADnEQjvEgn////uEQjyEgnsEQjzEgnxEgljBwPaEAj9EwnwEglHBQJHBQNNBQIBAAB3CQR5CQSHCgWLCgWRCgWTCwadDAWmDAapDAa/DgfKDwjWEAgGAADh4eHiEQjmEQjmEQkKAADoEQgLAQDtEQgMAQDuEQnvEQjvEQkPAQAfAgEuAwEvAwE8BAL1Egn3Egn4Egn6Egk+BAL+/v5CBQJrB0muAAAAT3RSTlMAAAMEBAkYGhsbMTRLUmpvcHeIjLe6vcHCxM3P0NbW3Ojp6u/w9ff5+fn6+vr6+/v7+/v8/Pz9/f39/f39/f7+/v7+/v7+/v7+/v7+/v7+Q8UoNAAAAO5JREFUeF4tiwVPA0EYRL9SXIsWl+LuxfcOd2Z3764quLu788NZNrxkksmbDP2R7vH6GioLs+iffEzNXd4+TqPErUUpVqMOvwgdzMPn1rv5vPsVeufBTaBK/bH2FPvkEUuIG5jIIc+sHYn/HJ3dC/Hxuo4y8s44dzwBbFkisHN8bVIdXs6jb+H97aCwbHEIqgcml64CD7YllNkAVQC940MLYe5YzvIeQAXNrd19Roc5MdzfdQLUUKaUYyuG9I8y1g4gj6hIak4X5cBIT2MquZJrJdOqpY11ZpAiqVwbY/C7KY1cRCrZxX4pWXVuiuq/hs49kg4OyP4AAAAASUVORK5CYII=',
- 'Sabayon': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABvFBMVEUAAAAcUaYdVKwAAAAAAAUABAwWRY4YSZYhZtIhaNYHDx0KCgoFDBcKCgoRMmYSNm0fXL0fXb8AAAAYS5gaTp8fXLwgXsEGBgYFBQUZSpgZTZ4JFSgODg4IEiIOJkwOKVIkW7EnXbQLGzUTExMKGC8LHjwMIkITExMiIiIPEBEPJ00QEhMXOXAaPncOJEgoXbApXbEcHBwwMDAEAgAfHRgQDgo3NC8AAAAHBwcKCgoLCwsJCQkaGhofHx8lJSUwMDA0NDQ4ODiRkZEICQocHBweHh4GBgYHCg8mJiYnJycpKSkrKystLS0uLi4ICAgODg43NzcRERF1dXUUFBSjo6O1tbUbGxsEBAMLGS8MDA0iIiIjIyMkJCQNDQ0NHTYKCQkoKCgPDw8QEBArMDkKCgkRERIREhMxMTEyMjISIz00Njk1NTU2NjYCAgIVFRU5OTo5P0c8PD0+Pj4/QURAQEBHR0dKSkpMTExSUlJiYmJlZWVnZ2cWFhZ2dnZ4eHh8fHx9fX2FhYUXFxeVlZWXl5eYmJiZmZmcnJwZGRmlpaWrq6usrKyvr68KFiq/v7/FxcXY2Nji4uLn5+ft7e0yif9uAAAAN3RSTlMAAAApKSkqKioqg4OEhISEhoa1tra3t7y9vr7S09PT09TU+Pj5+fn5+/v7+/v7+/v7/v7+/v7+70RY/wAAAPpJREFUeF4dyWNjw2AUBeC7dfYyorM6rx1exKltzLZt2/rDa/J8OgBVVlFDX39jcTZoUqCse251a2dvu6ccUtWlanLQ4Vpel+ThlWq1l3wEz58tx4dOt1dMlAJk9A5gMjG75LHwo46hzkwosGOMbejumoRvubC9EOrMviT0E0Us9fvN9dA6zxJCNv6+ECGsb6oNWsgmpZT9/UTUZo3Em6AW34guTL4jiAudiCM1kLcw8/SmHERfT1/eueBiDqR1GK1n9w+K8nglxYxd6QAML4ztXoQuj8YFgWcgqdJp8qzty26vaboCNIxBCshyQDKov0aXr29v1ufq1PwPx5Q7bCoh6eoAAAAASUVORK5CYII=',
+ 'Sabayon': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABvFBMVEUAAAAcUaYdVKwAAAAAAAUABAwWRY4YSZYhZtIhaNYHDx0KCgoFDBcKCgoRMmYSNm0fXL0fXb8AAAAYS5gaTp8fXLwgXsEGBgYFBQUZSpgZTZ4JFSgODg4IEiIOJkwOKVIkW7EnXbQLGzUTExMKGC8LHjwMIkITExMiIiIPEBEPJ00QEhMXOXAaPncOJEgoXbApXbEcHBwwMDAEAgAfHRgQDgo3NC8AAAAHBwcKCgoLCwsJCQkaGhofHx8lJSUwMDA0NDQ4ODiRkZEICQocHBweHh4GBgYHCg8mJiYnJycpKSkrKystLS0uLi4ICAgODg43NzcRERF1dXUUFBSjo6O1tbUbGxsEBAMLGS8MDA0iIiIjIyMkJCQNDQ0NHTYKCQkoKCgPDw8QEBArMDkKCgkRERIREhMxMTEyMjISIz00Njk1NTU2NjYCAgIVFRU5OTo5P0c8PD0+Pj4/QURAQEBHR0dKSkpMTExSUlJiYmJlZWVnZ2cWFhZ2dnZ4eHh8fHx9fX2FhYUXFxeVlZWXl5eYmJiZmZmcnJwZGRmlpaWrq6usrKyvr68KFiq/v7/FxcXY2Nji4uLn5+ft7e0yif9uAAAAN3RSTlMAAAApKSkqKioqg4OEhISEhoa1tra3t7y9vr7S09PT09TU+Pj5+fn5+/v7+/v7+/v7/v7+/v7+70RY/wAAAPlJREFUGBktwQNbQ2EYANC3lt3NtazltvDh+s52tm1z2f7Dfe3pHPiTllfT1V2bnw5xCVDUPruyub271VEMicCUTfQ6XEtritq/XA5MwVvw7NFydOB0e+WhQoCUzh5MxmcWPRZxxNHXmgo5doyxDd3ESPhaCNtzocrsY9BXFPHU7zdXQ+McTwhZ//lAhPC+ySZoIBuUUv77HVGbNTJYB5X4SnZh8hlBQuhYHq6ArPnphxdtP/p88vQqBBcyIKnFaD29vdO0+0tlwNiWDMCJ0ujOeejicEySRA6YUqfJs7qnur2mqRKI4wxKQFUDioGDf7psfXO9PlMHzC/HlDtslvM8zQAAAABJRU5ErkJggg==',
'Slackware': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AcEDi0qZWWDgAAAAx1JREFUOMt9kktoXHUchb/ffc1M7rySSdJMOknFPMRitLgoNKKI8ZHGKkgrjU8SitidimSh2UkXoQmoO1dGQSxJjdvOtqSaqlR0USEGSjVJGxuSmWR6M3fu4/93YX0g4rc9HA6cc4Q7DI+fpzz7PA8++2mxvZAeBZ4xhHtFcJRmXWsWvb36/OLcyxf5B/KHeYHy7DmGx1+YSDjmWTdlobTGMAStQGkNoLXS4tXDq7u7tUcWz49tA8jR8QUuzB5n5NTCV13F9JEo1JJwTLKuzU61QiOMcd0UDb+BncwQK3Rl15eNja3ui/Njq8aF2eMcO/XlBz0H8oO2ZUkum6A13WB99TtyzXlaCi24SaFa+ZFCzsG2DNnfkdbFjsI1APPhk+d6ujqznycdCxFozadYWvyMpx47wa+bPkGksKwUNnsk3TaCGASRXDZh5LpHXPPg4Rcni+3uYBxrtBbQghlscOVKmYHeEm0ZIZ9xyLffw41ND6VAa43SmjiMByzHYtjzwr9arfshxf5jOKlvKZfn8es77N2uks24PPfSFD/9Uvt7AtPKWmEU9d645eHYJo5tcKi/FX/zG+zmQxQH+rANk862DOW5N/hhaY64cJSa5xNFCgDDILZACMKYWAmh73HmzFsMlBQJ06LeiMinE1S3KzRCm5rXIIoUIoKIYCVM36urZFbEoiBLNMIhAE6/NsSB7h6SKZdL8xsUOnpx9j1KbTdARACIowArYe1ergfNT2i0mIbJys0GI6PT3N1/hJvrPxOFdRJNBQIy/FapI4Bpgohgcjuw+jq8jy8tV55MNBWI4ohS802CpizKv8q+FgALZAfYgSyAZtNro1oLaU1VvxCA029Oraxs7u/tKnXiNjn8HyKwur6lI++6vPK4V7IA7u+1Dyu1tr183ddNbkHuXP8/zEIYeFqiLRl6YO/p0bHJdflT/PD9qZa1W+ry99fcvlAlcZwUpuUAglIRYVgnDEIOlna4q0M/NPnuO1/PzMwg/045O/XeibUt5/Xangx6viSVFpK2jtMpvdyWCz+5ryf10clX3/amp6eZmJjgd441URWWJY8BAAAAAElFTkSuQmCC',
- 'Trisquel': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABjFBMVEX///8AAAAAAAAAAAAAADMAAGYAAAAAHFUAGWYAF10AImYAIGAAHloAHGMAKGsAGmYAJmYAJGEAKnUAJ1gAMXYAJnEAJGQAI2EAK28AK3cAGTEAMHgALXEALXgALG0AFUAAI2oAK3EAMngANoYALXMANIAAM4IANIIAL3gANIcANokANoQANYQAOY0ANIYANooAN4kAN40AOY0APZMANIUAOY0AO5AAPZUAPJAAP5MAPpQAQJUAOYsAPpYANoUAPpoAPpUAM4AAQJkAPZIAPJEAQpgAN4cAPpQAPZUAPJEAO4oAOosAOo8AQJoAOYsAO44AQpsAO48AQp0AP5UAQpoARJwAQ58ARaAAQZgAQ54AQ50AQpgARaIARqMARaMARaIAR6QARaIARaEASakARKEAR6MASqsARKEASKcAR6MARqYAR6UATbEATa8ARqUARKAAR6oARqMASKgATK8AR6QATbIATbAASq0AR6cASKgASqwAR6UASKcATa8ASqoASqwAS6wASKoAS60ATbHn4CTpAAAAhHRSTlMAAQIFBQUGCQoLDxAREhMUFBUYGhobHB0eHh8gIiIjJCQkJCYoLC0xMTE0NDo6Oz1BQUNHSUxOVFVVVldaWl5iY2RkZWZoamtsb3FycnR1ent9f4KDhIiJioyNkJGYm5+foqOkpqamqKmqrKytsLKzs7e4uLy8v8TFxcXGx8rO0NXY2eZc4XYcAAAA00lEQVR4XkWN1VoCUQAG/3NWtwh7CTsQJOyk7BaDxuxA6bbrxf32gt25m7kZqDRYxziooDV7+1AalMUavQh2AsEZoWvzigLun+T17/c8QiJZ7qu2QKiNmyZthdcR1/as353jIeU1GxMHo5XHdqPFeX8IaDMdHPYN6dRN7LR4qQewdTa35HWkyh+fbxERAMjwlAWJv3CPSKDQ+H7XvHdkV4Pua3Gtm4sPKIF/WV8dop4VKBw/NU33B3x1JbTt+XwhkJQoqRfWvHOy28uqH8JIdomR/R+s9yR3Cso77AAAAABJRU5ErkJggg==',
- 'Ubuntu': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABKVBMVEX////ojFzplGf1zbnqnHLvs5P10b3yuZv1xKrytZXvtJXys5LysI32waT0n3HxiVHwg0jxhk31kFn0h0zxf0P0hUrveTv2iU3yfkD1hEfyejv5eDLybSX0aR7zZxvyayH6ZxnxZBj4YhH7XAb5WALlUQLeTwHgUAHeTgHfTwD65NzdTQDdTQHdTgD31MfcTgLcTADcTQD////xt5/31Mf54dfmfE/dUAbeVQ/jcUDcTgHeWBnnflHohFvpjGbqkGztnX342Mz53dLgXiP65d399PHdUgrtoYLyu6Xzvaf76eLfXB/rkm/fWhvupojwrpTeVhTgYSfgYynzwa30xbL1ybnngFT31snngljhZS3539XhZzDiajbibDn77OX88Ovrl3X99vTjbz1fisGCAAAAMHRSTlMABgYGBwcHJiorMDA1NXGHjY2Nl5mZmZyfn6O5u8XHzc3X193j9fj4+vr6/f39/f08OUojAAAAx0lEQVR4Xi3HZVbDYBhGwQctWqzFPXiQ+36pu+LubvtfBKcN82/UEhld2vWXxyL6F92gbTPabse8hU/uHMx1SZoyyJWPTwq1Rs7GpYE9+Cg+OJcs1MHvU9y4fnrN31yUm18vMCIPjtw3QMndw4rs8ieVzAAcBlewpe1KM3uaBuD3Dda1BhWXAsi6AFY1a2SqifxZ+rnxWYcJDRkUS3fO1R5vwe+XZgw4D4L3RAJiknoXCVX3WeiUpJ5pIxTvVmg45pl5k4Ot/AGV2iqZBWgJJAAAAABJRU5ErkJggg==',
+ 'Trisquel': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABjFBMVEX///8AAAAAAAAAAAAAADMAAGYAAAAAHFUAGWYAF10AImYAIGAAHloAHGMAKGsAGmYAJmYAJGEAKnUAJ1gAMXYAJnEAJGQAI2EAK28AK3cAGTEAMHgALXEALXgALG0AFUAAI2oAK3EAMngANoYALXMANIAAM4IANIIAL3gANIcANokANoQANYQAOY0ANIYANooAN4kAN40AOY0APZMANIUAOY0AO5AAPZUAPJAAP5MAPpQAQJUAOYsAPpYANoUAPpoAPpUAM4AAQJkAPZIAPJEAQpgAN4cAPpQAPZUAPJEAO4oAOosAOo8AQJoAOYsAO44AQpsAO48AQp0AP5UAQpoARJwAQ58ARaAAQZgAQ54AQ50AQpgARaIARqMARaMARaIAR6QARaIARaEASakARKEAR6MASqsARKEASKcAR6MARqYAR6UATbEATa8ARqUARKAAR6oARqMASKgATK8AR6QATbIATbAASq0AR6cASKgASqwAR6UASKcATa8ASqoASqwAS6wASKoAS60ATbHn4CTpAAAAhHRSTlMAAQIFBQUGCQoLDxAREhMUFBUYGhobHB0eHh8gIiIjJCQkJCYoLC0xMTE0NDo6Oz1BQUNHSUxOVFVVVldaWl5iY2RkZWZoamtsb3FycnR1ent9f4KDhIiJioyNkJGYm5+foqOkpqamqKmqrKytsLKzs7e4uLy8v8TFxcXGx8rO0NXY2eZc4XYcAAAAzUlEQVQYV2NggAMWdX12BiQglJ+SXqIMYqmHxQdJMzAEmXLKuCcyMTBYNWYmNTVYMARzMToqlAsycFYYSBppFFVp6nqa2VkVcDCIFXK7GfrrlWWISKjqpAUwMPDkibIz+Inn5iSHxxQn8AHN9Ig1d7DRzimtrasO5QJZwqhmrMoQ2Rwix8WIcANrTaqAT6AWQoC33t5Flj1CCS7AUenqrMJk7YRQEpXFb6LoawvjMjIJZ8dZ+maKMcHMZWST8or2lmdD2MPILKYlxgziAwCs9yR3GXo0vAAAAABJRU5ErkJggg==',
+ 'Ubuntu': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABKVBMVEX////ojFzplGf1zbnqnHLvs5P10b3yuZv1xKrytZXvtJXys5LysI32waT0n3HxiVHwg0jxhk31kFn0h0zxf0P0hUrveTv2iU3yfkD1hEfyejv5eDLybSX0aR7zZxvyayH6ZxnxZBj4YhH7XAb5WALlUQLeTwHgUAHeTgHfTwD65NzdTQDdTQHdTgD31MfcTgLcTADcTQD////xt5/31Mf54dfmfE/dUAbeVQ/jcUDcTgHeWBnnflHohFvpjGbqkGztnX342Mz53dLgXiP65d399PHdUgrtoYLyu6Xzvaf76eLfXB/rkm/fWhvupojwrpTeVhTgYSfgYynzwa30xbL1ybnngFT31snngljhZS3539XhZzDiajbibDn77OX88Ovrl3X99vTjbz1fisGCAAAAMHRSTlMABgYGBwcHJiorMDA1NXGHjY2Nl5mZmZyfn6O5u8XHzc3X193j9fj4+vr6/f39/f08OUojAAAAxklEQVQYGS3BBULDQABFwY8WLdbiHjzI201Sd8Hd3e5/CJKWGUVio0u77vJYTP/iG7RsxhXpmDe0BDsHc12SpgzkyscnhVojZ8algT34KD5YGxTq4PYpabh+es3fXJSbXy8wIgeO7Dehkr2HFZnLn1SQIXToXcGWtivN7GmayO8brGsNKjZFKGs9WNWsIVP182fp58ZnHSY0ZKBYurO29ngLbr80Y4Bzz3v3fUhI6l2krbrPQqdCPdOGtmS32oYTjjHO5KBCf5XaKpkxFPzRAAAAAElFTkSuQmCC',
'Windows': 'iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAA+pJREFUOE+F0n84FHYcB3CWSsL9ojo/6ik64c6PnTjmSS0limmrpBm2G002y++xzXRz6zE0R4nbw+RnTj/WD4sbanLkkAe55ccYlyNme4SrO9u9d13PI3/saZ+/vs/3831ez+f9eb5aWsuqy2mjRYeNUa7YmtjfTico7jNJ8z0eG24NB9vvnDrvufzpq89Npnr8VjMddNmuRh9rDfp36mFg91oM7qPIc5JdbDJq3An/JfCu7Hl53W2lpS220pP2OuniN299jAYbYizSENIoAgbCTdrTKtxOJVdvGo8psUwKy7Vxe4ez1YEVudGP8YEZzyveInFJ6mZRHHqYazDspw/pJwTIuERM5JIwmUdGdyo9K7/BszGzzg6fXzZHGJ8KvzQqXKOpoIeZLjofWR++BPWyCEnPY4xFGEKWQcLjMjKmr1MwfcMYwmz/Y4KOgNki0V5k1dkjUWCK93Kp2PMFFawos8cm1gZ2GqjLXktL4mbQPHLQ4B9ZDFE5+S356fQlyuJMqzH++HnTo6ui2OO1ko9Ul+4fxfd3d4F7k4YTReqpuFS88bGZUE2QNNDobuIq8Q5CduHb7lFJaTnvnym9ergjMWD/FG8zf+aKS3G9JO5C01Asah6wUXrvALKEDoitMMHhDKrKJdg8RU2s0EB2EWWur8dd7PDPFv6dUC0Gv3kAN36VPRGP/5k5NS6lljWxG0TDiSr1VKhoPwhevRMSqkwRxDObc/DavGtpP6zoi8XOyZfhnyNEvKANBU0P8VPfI/wyNCGXSn7wlEmyA9KrgmOKGth3eDVvPfyywq2dnUEv2R9qG2rLsH7xJXziKnWcI8tlTvEC7Mu8hROlImTU9aKqcwQ1vWOihWFu+sJknmph5CvxQh87c7bNh/NXo03hrMCosyvLmMNgMF7TQL6J1dsZIUVwjKqEO+cajp5vxPN439U/gKBt8PTcYHzL/BgHCyOf4unAISj6mFC2bYC82kB5Ls460NHRUVsDeYSXpGw7UgC7sAtwShDgzdM38W7BbURXtqpqhfmB8sEQuXwoCM/6faGQuGCxyxyKWhIm+PrSD495WL3cT0hhi8Whc3NbAs9KaOyCTvrJ8qkdX19XBeTUDU00+55USFzVU2yHstcaix0mUAjJkJeuRU868Ucmk0lcguiBnMAVxjbbdHV1yeq8+u4Hgo22huSG+iQXp83ftaxW3lsPZcs6KG5T8OwaAfJiPcxlrVRVRhvF02i0F/t5VbHZ7JWDfErKTLnhE3mFPuRFepg/uxqz6TqLv6euGj3ut87t/4ylvre3t3ZehOWWO1zjSFEqMVP4GfGb/DBykJcjmaZOoLsc+hcVY/LaAgcTQAAAAABJRU5ErkJggg==',
'OpenBSD': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAykIPu64pQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAADTklEQVQ4y32RXUxTdxjGn3N6eujoKT3SUkuk3VoBGfVjgFXAsZ7WkipyYXQbuu3CzUXZmGRbssnFEseFkWzgcGzGXky9MWL8TsC4IeFgtK4oAqOnG5vMVl1pCMVWQD7b/y5M6jLdflfvxfPked/nBQA0NDSChqnGVrLuGkES742NhJAdhAKAuk9yyUs5Gry7RQMZAARCWgivpQiPe71P5DUfH0xaqTL7m/iiLkJmphawa+e4SM2PvUyC4yUIBu8CnAQKAK53rCA5OUtQtStVpJ4Gw/FOBddZVKhCfq4MP4n6+at+DUsJm/e0G9JZzYEvI2tHwlEYjDxomkZ+3nG8WroRtHihZVOhVlorDQzh0okhcByDP4ZGcf+X9XAsvY5/RsBa7Kq5H/CqLctKyl/g08S2i6fq8W/MS3P34T9wNDVYSeDX1eTD9xhiLXbtB/Akwmmv6Kr+ICFkLpGhtNSM3qsSstS3oX8lSsmsxS6ZVn3j6PvVVqhUcvC8AtPxVPxwygVKvngN89WOjgVprggGA4eenjB4nsXsTASpC63I0wVTZYPR11FoKRB8Ax54PCFk6BhMTk5CPR3GSbHouGzknr/bYFq9EAvfc9Tu1sLjHcXNKxLuTOTgzOlOe7IHBc/beAXWpWmXlz8a84nhcLQ+ecVzsAEQrMWuMX+f9HZF2YPZ28FVSNfoPWqOzMUmqYMAJm7+/OOzXQFwHGpyEV+vi+yvtxBC9pDmpgJC4tvI3mo9GTitIxvW24nT7ug67HY/3eDs2bbyrVsrY2day70rV6kRfDAHk5lDLJqAmmeRiD9GJDKHvwb74R8G0mkTPjrQTTG122xkTTbwaV2b1H4u16JQKXGr7yG2b8/H1MQ09IsTSEmRwzf4CCwzD+dmE1re8CI7wwi5XNlFf9vaTXX4dWJg4LLl7h05fpNGwNAMWpp9CIVYNO/tRCzGwpDFQaVMQTS2CKY0BWr3GVGWNSXKACDDaA4Mh976pq9f5Sy09GgKlmeAMIBKzUKpU+BFoxJecRhUfAbMxDi4eADfHVmE79v7q575gvvYeVvjZ58LD5mwsKUyX0hnf0feslnQCWD4zxnc6reKisxsfH2oscqcmTmK/+Ow252cna7K52r+Bky6PqmoT5HBAAAAAElFTkSuQmCC',
- 'Gnu': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAywUV5gQrwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAADcElEQVQ4y43Tb0jjBRzH8c9v+7nNMebcUW21Cc78g/wcuhByIScoMRwoTBmFlZCmIJ14axqkgoYIkXIqKIVBEuJNUBEUPRlpqDC3Q2Ex0nTezun2YOaPLXNIv7Vvj7zgiOj1+PPk/eADjuNEuHN6ekqMw+H4IzMz8xChUCjV1NT0JbO7uxtfXFy8NZvNr21tbd0AAEQikY6I0m1tbQbx2NjYZiqV+vn29jY+PDw8xhYWFj45PDzcb25uhlQqfSTief6X0dFRpqKigvF4PPPipaWlY7lcXhCLxXJnZmY+ZTY2NnzX19ePGxsbHw0MDLivrq5mc3Jy2pPJZLVWq/2cdbvdDSzLholoNJ1OMy6Xq0Ymk5HNZktOTU29qMgA8HYqlaKDgwNKp9M0PT09BgAM/iGuqqoimUx2yPP8U5/P9wEAMB0dHRUKheJHiUTyeGhoqAUAnE7nR0qlsjcQCLwjlsvlz+bm5mQWi0VSWlr6bXV1tU6hUMj6+/vfN5lMN0xxcfG1zWZ7SETTSqWSGhoamPHxcajV6s+8Xu9Xou7u7t9VKtW00+mkSCTC6PV6aDQa8Dw/Wl9fP8UAQCgUosvLSyovL2eWl5dRUFBw7Ha7v9vc3By5K3g1EAg8FQSBiIguLi4IgBwA2LtEjuPuJxKJ62AwKFpdXf0eQBIvYVmW/cLlchEAWK1WAADT09NzX6PR/OTz+eKVlZUzKpVqTyqVvsnzfLCkpGSrtrb2t97eXnFeXl5ZKpWyZ2RkPPP7/UUnJyefGI3GU+zt7aU4jotOTk7mAUBfX1+b1Wq9kcvlBIAcDgctLCyQxWKhoqIi6uzs/BoAVlZW3qqpqbllZmdnf1hfX//Q4/HEzWbzX+3t7fcMBgMFg0EYjUYmEolAEAREo1Hk5+fT+fk5Mzg4GD86OpJ0dXXJGQBoaWl5Ra/XP6yrq3tQVlam2N7ehslkAsuySCaTUKvVSCQS2NnZSXAcJxYEQTEyMvKeIAhLDADY7fZ7BoPhm6ysLFpbWzuan5//WKvVvsHzPEWjUSYSiSA3N5d0Oh0TjUaf+/1+S2Nj46/4FwYAr7e2tnbF4/E/iYjC4TCFw+F0LBaj/f19mpiYeID/IAagAyABYLXb7cLZ2Rml02nyer3POY6rwv8hEr34u0IkEk1mZ2cTgGMA7768/RtL5JKsGzrLIgAAAABJRU5ErkJggg==',
+ 'Gnu': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAHC/Qd8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAywUV5gQrwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAAmJLR0QA/4ePzL8AAAHHSURBVBgZZcFPSJNxAAbgt28uanSRapCsy0KK2CWCUYecB5HBolNsglZEsmAwaUvHaIu2YYty1bKGMKmgHIRbGEhURIEY/VHUQ+uwZcxEJSL5Ft+W5ubv7TMkip4HJglrPhHeUmAchWprBK+Kni9pukoAJAOF04j4y6Z9dZtu3sIT32lxXwxeRepwidP0mAF0p5JKPfBsLOMBQs/dJ3pehzcnQ+jc6SfFKlN8KMgEodLiQJWTFOyPY52mUbLmzANY4zro+xG8DVXn8UjOvg2WFSB69Oxo8Hx3F3CM2KsE2wO8LKbp5gWvtYK78zHKooM/eZFu9t0AUOCYIIf4IRfvOrIBKn12vEJyjtDhtx3QfV+dYPgO/qipOfeAgA0qn+UaW+TE9ZQjE0g63uhrpZh2yJyOPXKFe9uWrmTxtmpaSOwCgk5bWUfQywyt3MOOHmB4f9MyBu610ii3fRvlvBgRMrOc4mPmxQs2yPpylABObQ9FJxVyhAqXuEiyyOFiQcnT6TipBWDf6k9fGjwUWZgjF8V7PmVOlPmxkNmNvxhR136muELOclZ85QR73fiHBgZshM1e+UzBdzOmRvxPgmqLlKgl8mjGul/jG/ctzIC/LwAAAABJRU5ErkJggg==',
'CrunchBang': 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAQCAQAAAC45EetAAAA8ElEQVR4XnWOsUpCYQBGz1TIHYu2Qix6g0DEtSeQu/UIISJtUS8gJq61F1wcdMohcBDxKUR8hsz1xA/y44/cs3znbB+RJ0Skl3pSkeFQbUs79VAPzrwPFRmN1Ja0Ug/16I93+1oi4lKte+zMXv32WuoAm43lXMrqzbFncgWw21lORf4+/PREKpAhYqZuPXZ+T/3yXbZEajV1JavUQ104sRcq0myqc5mnHurWqc/7yhExVwuPncl+C4Bu13L60ueAwcByOtLhgAIRCzU38fRGTmSxUBvSSD3Ui1NvQkXWa7Uq1dRD9R17HiqyRUSy1NP6B7e1Yu2GtlUKAAAAAElFTkSuQmCC',
'Yuno': 'iVBORw0KGgoAAAANSUhEUgAAABgAAAAPCAYAAAD+pA/bAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAABDtJREFUOE+FlHtMm1UYxrtsi8aEgCb+oTFmZur+WNS5RaPERU10C2qGaBgb6hgwLwMmHTIKlIKlQIHSQrmU24BSSmnpBVooUmihtEC5yKWDjVu5uOkcEca4lG5E93j6EQmELX7Jky/fOed9fu973vMdGu0xT3Cgz57yXMZLDdXcy821PFWLKmuA6HqLMqtLX5POl4iYb2ukWW8IOOFe/qfe3/M4n0eOjwyZD8//bldODOk37N1yDJgl+LVdjEGLFKO9KkzZm8hbje7mIrTXZ7sMtTydrJh15H8hHW11XvN/jGS7VudcD5w34ZZzeQYb67fwYO03LN4exo1+LWzNxbA05O5QuzbHqRYn+++CHDx4YK9WLfaedfQzV5em54g5Zbi8OIml+VFMDLWQ7GXoaSmFWZsDZVGCO2u0EbkhHTrhFqi9PmelSsQ8tAtSVch60dpUeGe4kxgZxegzVkBzlQ2NKBG2+iJIMqMok9r8OLRIMqApToSqmAWTmk9B2+o2YW79oshU7ABcuvAFrVGWXkVKpBYoSaBSxIS2mINpiwbjZiUMZRloVfJQyaXDKObBpimBScpHFe8KmmXpaKhK3arGrBVuVBclHN2CiPNin1OVs1tVJYlQlyZBxA6DviQVo6ZaOKd7sTplw53BVugruBBzfsRslw7rZPxaczWutSpQV/gzJPxo1JexyfaxKBBpuiEx+tw+CpKdEvGWTprGlhcwqbIzL5/DYKMYndpK3L1hxf3ZfkrzwybUZjPhnOqmvlcmutFF1jis9QSShOrcWNSXJ1MA0ou/NZWc8Ddfe4VGO3bk0JON1dyMMlK+gmxNrZCFhZF2Kng7YNO0awt4b7wLNp2EqtAsF6ImP56SG0B6siovTYpIjg15gapCVhAfJRUyIBFEo6k8AyuTtkcC/qvG/XbDexulWJvqgYH0o0nKhVHFJ40XwFQnWM5OCX+XMg86c3KvVMSMapCmPpSTIygTxGKZZOcOXhrr3Mp4uzkFuG6B3ajE3TELDDU8qEmsmvRATxquKkxAnSTFjwKEfv3JU9JC5unG6rQ1bTkbQ4Yq/DVgxOqwBWt2K9Yne3ZCZvrgHO2k5paHzOhSiVCZSkdNTgzy40JRlPgDhDHBCxUZdCs91G8fLeK87zOl6XSOICZYXMGNhDqX9fDP/mbK2DXVi/szm03eLpejl5pzOfqwOt4JBT8OeYwQt/4R/BR0OzXiLCM5LOCji/4nXt46rpywgG+zor5RxgSdupBzJdglSY+5ZZbl3XNY6mbn7W0Lcx06zBg1WBjtcC6OmG+OmRTrFrnIUZESZeVeCpwh8TpiPsQ47/tloM97T+/6m8mg55mT3tStyL54mhlwwtszNvjzD8/6HH8i7PvvPPRioZdRWuDBZUR6pEWG7I8P9Xs1Jsj36MfvvO5J/+rTw58dP7afJPfBgeef3XGz/gskFVpJc4HwGwAAAABJRU5ErkJggg=='
}
@@ -16357,7 +16436,7 @@
},
advanced: function(section) {
var archBoards, boardID, boardOptions, boardSelect, boards, data, event, files, input, inputs, item, items, name, o, row, rows, ta, table, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4;
- section.innerHTML = "Archiver 404 Redirect is disabled.
Thread redirection Post fetching File redirection
Disabled selections indicate that only one archive is available for that board and redirection type. Custom Board Navigation
New lines will be converted into spaces. In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
Board link: g
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:\"Install Gentoo\"
Index-only link: g-index
Catalog-only link: g-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: g-index-text:\"Technology Index\"
Full board list toggle: toggle-all
[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"] will give you[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy] if you are on /g/.
Time Formatting is disabled. :
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled. :
File Info Formatting is disabled. :
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas One item per line. Items will be added in the relevant input's auto-completion list. Password items will always be used, since there is no password input. Lines starting with a # will be ignored.
You can use these settings with each item, separate them with semicolons:Possible items are: name, email, subject and password. Wrap values of items with quotes, like this: email:\"sage\". Force values as defaults with the always keyword, for example: email:\"sage\";always. Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always. Unread Favicon is disabled. ferongr xat- Mayhem 4chanJS Original Emoji is disabled. Sage Icon: 4chan SS appchan
Thread Updater is disabled. Interval:
Custom CSSApply CSS
";
+ section.innerHTML = "Archiver 404 Redirect is disabled.
Thread redirection Post fetching File redirection
Disabled selections indicate that only one archive is available for that board and redirection type. Custom Board Navigation
New lines will be converted into spaces. In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
Board link: g
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:\"Install Gentoo\"
Index-only link: g-index
Catalog-only link: g-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: g-index-text:\"Technology Index\"
Full board list toggle: toggle-all
[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"] will give you[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy] if you are on /g/.
Time Formatting is disabled. :
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled. :
File Info Formatting is disabled. :
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas One item per line. Items will be added in the relevant input's auto-completion list. Password items will always be used, since there is no password input. Lines starting with a # will be ignored.
You can use these settings with each item, separate them with semicolons:Possible items are: name, email, subject and password. Wrap values of items with quotes, like this: email:\"sage\". Force values as defaults with the always keyword, for example: email:\"sage\";always. Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always. Unread Favicon is disabled. ferongr xat- Mayhem 4chanJS Original Metro Emoji is disabled. Sage Icon: 4chan SS appchan
Thread Updater is disabled. Interval:
Custom CSSApply CSS
";
items = {};
inputs = {};
_ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss'];
diff --git a/builds/crx.crx b/builds/crx.crx
new file mode 100644
index 000000000..85cd36e95
Binary files /dev/null and b/builds/crx.crx differ
diff --git a/builds/crx/manifest.json b/builds/crx/manifest.json
index c92bf53a3..95e253485 100644
--- a/builds/crx/manifest.json
+++ b/builds/crx/manifest.json
@@ -17,6 +17,8 @@
"homepage_url": "http://zixaphir.github.com/appchan-x/",
"minimum_chrome_version": "31",
"permissions": [
- "storage"
+ "storage",
+ "http://*/",
+ "https://*/"
]
}
diff --git a/builds/crx/script.js b/builds/crx/script.js
index 2cc6073cf..252d9542a 100644
--- a/builds/crx/script.js
+++ b/builds/crx/script.js
@@ -1,6 +1,6 @@
// Generated by CoffeeScript
/*
-* appchan x - Version 2.8.9 - 2014-02-09
+* appchan x - Version 2.8.9 - 2014-02-16
*
* Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
@@ -194,7 +194,8 @@
'Cooldown Prediction': [true, 'Decrease the cooldown time by taking into account upload speed. Disable it if it\'s inaccurate for you.'],
'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.'],
'Captcha Warning Notifications': [true, 'When disabled, shows a red border on the CAPTCHA input until a key is pressed instead of a notification.'],
- 'Dump List Before Comment': [false, 'Position of the QR\'s Dump List.']
+ 'Dump List Before Comment': [false, 'Position of the QR\'s Dump List.'],
+ 'Auto-load captcha': [false, 'Automatically load the captcha when you open a thread']
},
'Quote Links': {
'Quote Backlinks': [true, 'Add quote backlinks.'],
@@ -8029,6 +8030,14 @@
});
}
},
+ Twitter: {
+ regExp: /.*twitter.com\/(.+\/status\/\d+)/,
+ el: function(a) {
+ return $.el('iframe', {
+ src: "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid
+ });
+ }
+ },
LiveLeak: {
regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/,
el: function(a) {
@@ -8104,6 +8113,15 @@
});
}
},
+ gfycat: {
+ regExp: /.*gfycat.com\/(?:iframe\/)?(\S*)/,
+ el: function(a) {
+ var div;
+ return div = $.el('iframe', {
+ src: "http://gfycat.com/iframe/" + a.dataset.uid
+ });
+ }
+ },
SoundCloud: {
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/,
style: 'height: auto; width: 500px; display: inline-block;',
@@ -8545,6 +8563,42 @@
QR.handleFiles(files);
return $.addClass(QR.nodes.el, 'dump');
},
+ handleBlob: function(blob) {
+ var _ref;
+ if (blob.type === null) {
+ return QR.error("Unsupported file type.");
+ }
+ if (_ref = blob.type, __indexOf.call(QR.mimeTypes, _ref) < 0) {
+ return QR.error("Unsupported file type.");
+ }
+ return QR.handleFiles([blob]);
+ },
+ handleUrl: function() {
+ var url, xhr;
+ url = prompt("Insert an url:");
+ if (url === null) {
+ return;
+ }
+ xhr = new XMLHttpRequest();
+ xhr.open('GET', url, true);
+ xhr.responseType = 'blob';
+ xhr.onload = function(e) {
+ var urlBlob;
+ if (this.readyState === this.DONE && xhr.status === 200) {
+ urlBlob = new Blob([this.response], {
+ type: this.getResponseHeader('content-type')
+ });
+ urlBlob.name = url.substr(url.lastIndexOf('/') + 1, url.length);
+ QR.handleBlob(urlBlob);
+ } else {
+ QR.error("Can't load image.");
+ }
+ };
+ xhr.onerror = function(e) {
+ QR.error("Can't load image.");
+ };
+ xhr.send();
+ },
handleFiles: function(files) {
var file, isSingle, max, _i, _len;
if (this !== QR) {
@@ -8637,7 +8691,7 @@
dialog: function() {
var check, dialog, elm, event, i, items, key, mimeTypes, name, node, nodes, save, value, _ref;
QR.nodes = nodes = {
- el: dialog = UI.dialog('qr', 'top:0;right:0;', "
No selected file
")
+ el: dialog = UI.dialog('qr', 'top:0;right:0;', "
No selected file
")
};
_ref = {
move: '.move',
@@ -8647,6 +8701,7 @@
close: '.close',
form: 'form',
dumpButton: '#dump-button',
+ urlButton: '#url-button',
name: '[data-name=name]',
email: '[data-name=email]',
sub: '[data-name=sub]',
@@ -8710,6 +8765,7 @@
$.on(nodes.dumpButton, 'click', function() {
return nodes.el.classList.toggle('dump');
});
+ $.on(nodes.urlButton, 'click', QR.handleUrl);
$.on(nodes.addPost, 'click', function() {
return new QR.post(true);
});
@@ -9073,7 +9129,7 @@
imgContainer = $.el('div', {
className: 'captcha-img',
title: 'Reload reCAPTCHA',
- innerHTML: ' ',
+ innerHTML: '',
hidden: true
});
input = $.el('input', {
@@ -9081,10 +9137,11 @@
title: 'Verification',
placeholder: 'Focus to load reCAPTCHA',
autocomplete: 'off',
- spellcheck: false
+ spellcheck: false,
+ tabIndex: 45
});
this.nodes = {
- img: imgContainer.firstChild,
+ img: $('img', imgContainer),
input: input
};
$.on(input, 'focus', this.setup);
@@ -9096,6 +9153,9 @@
this.setupObserver.observe(container, {
childList: true
});
+ if (Conf['Auto-load captcha']) {
+ this.setup();
+ }
return this.afterSetup();
},
setup: function() {
@@ -9115,7 +9175,7 @@
$.globalEval('window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: RecaptchaState.timeout}))');
$.off(window, 'captcha:timeout', setLifetime);
_ref = QR.captcha.nodes, img = _ref.img, input = _ref.input;
- img.parentNode.hidden = false;
+ img.parentNode.parentNode.hidden = false;
$.off(input, 'focus', QR.captcha.setup);
$.on(input, 'keydown', QR.captcha.keydown.bind(QR.captcha));
$.on(img.parentNode, 'click', QR.captcha.reload.bind(QR.captcha));
@@ -9175,6 +9235,9 @@
},
clear: function() {
var captcha, i, now, _i, _len, _ref;
+ if (!this.captchas.length) {
+ return;
+ }
now = Date.now();
_ref = this.captchas;
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
@@ -9204,7 +9267,7 @@
},
count: function() {
var count;
- count = this.captchas.length;
+ count = this.captchas ? this.captchas.length : 0;
this.nodes.input.placeholder = (function() {
switch (count) {
case 0:
@@ -10958,7 +11021,8 @@
'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']
+ 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,';
@@ -12348,8 +12412,8 @@
archives: [
{
name: "Foolz",
- boards: ["a", "co", "gd", "jp", "m", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"],
- files: ["a", "gd", "jp", "m", "tg", "vg", "vp", "vr", "wsg"],
+ boards: ["a", "biz", "co", "gd", "jp", "m", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"],
+ files: ["a", "biz", "gd", "jp", "m", "tg", "vg", "vp", "vr", "wsg"],
data: {
domain: "archive.foolz.us",
http: false,
@@ -12446,10 +12510,10 @@
}
}, {
name: "fgts",
- boards: ["soc"],
- files: ["soc"],
+ boards: ["r", "soc"],
+ files: ["r", "soc"],
data: {
- domain: "fgts.eu",
+ domain: "fgst.eu",
http: true,
https: true,
software: "foolfuuka"
@@ -12474,8 +12538,8 @@
}
}, {
name: "Foolz Beta",
- boards: ["a", "co", "d", "gd", "h", "jp", "m", "mlp", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
- files: ["a", "d", "gd", "h", "jp", "m", "tg", "u", "vg", "vp", "vr", "wsg"],
+ boards: ["a", "co", "gd", "jp", "m", "s4s", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
+ files: ["a", "gd", "jp", "m", "s4s", "tg", "u", "vg", "vp", "vr", "wsg"],
data: {
domain: "beta.foolz.us",
http: true,
@@ -12668,7 +12732,7 @@
css.push(".emoji-position-after:not(.emoji-disable):not(.emoji-" + (pony = key === "pony" ? 'disable-ponies' : 'only-ponies') + ") a.useremail[href*='" + name + "']:last-of-type::after, .emoji-position-after:not(.emoji-disable):not(.emoji-" + pony + ") a.useremail[href*='" + (name.toLowerCase()) + "']:last-of-type::after, .emoji-position-after:not(.emoji-disable):not(.emoji-" + pony + ") a.useremail[href*='" + (name.toUpperCase()) + "']:last-of-type::after, .emoji-position-before:not(.emoji-disable):not(.emoji-" + pony + ") a.useremail[href*='" + name + "']:last-of-type::before, .emoji-position-before:not(.emoji-disable):not(.emoji-" + pony + ") a.useremail[href*='" + (name.toLowerCase()) + "']:last-of-type::before, .emoji-position-before:not(.emoji-disable):not(.emoji-" + pony + ") a.useremail[href*='" + (name.toUpperCase()) + "']:last-of-type::before { content: url('data:image/png;base64," + icon + "'); }");
}
}
- css.push(".sage-highlighting-image.sage-image-appchan.sage-highlight-position-after a.useremail[href*='sage']:last-of-type::after, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-after a.useremail[href*='SAGE']:last-of-type::after, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-after a.useremail[href*='Sage']:last-of-type::after, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-before a.useremail[href*='sage']:last-of-type::before, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-before a.useremail[href*='SAGE']:last-of-type::before, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-before a.useremail[href*='Sage']:last-of-type::before { content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAABa1BMVEUAAACqrKiCgYIAAAAAAAAAAACHmX5pgl5NUEx/hnx4hXRSUVMiIyKwrbFzn19SbkZ1d3OvtqtpaWhcX1ooMyRsd2aWkZddkEV8vWGcpZl+kHd7jHNdYFuRmI4bHRthaV5WhUFsfGZReUBFZjdJazpGVUBnamYfHB9TeUMzSSpHgS1cY1k1NDUyOC8yWiFywVBoh1lDSEAZHBpucW0ICQgUHhBjfFhCRUA+QTtEQUUBAQFyo1praWspKigWFRZHU0F6j3E9Oz5VWFN0j2hncWONk4sAAABASDxJWkJKTUgAAAAvNC0fJR0DAwMAAAA9QzoWGhQAAAA8YytvrFOJsnlqyT9oqExqtkdrsExpsUsqQx9rpVJDbzBBbi5utk9jiFRuk11iqUR64k5Wf0JIZTpadk5om1BkyjmF1GRNY0FheFdXpjVXhz86XSp2yFJwslR3w1NbxitbtDWW5nNnilhFXTtYqDRwp1dSijiJ7H99AAAAUnRSTlMAJTgNGQml71ypu3cPEN/RDh8HBbOwQN7wVg4CAQZ28vs9EDluXjo58Ge8xwMy0P3+rV8cT73sawEdTv63NAa3rQwo4cUdAl3hWQSWvS8qqYsjEDiCzAAAAIVJREFUeNpFx7GKAQAYAOD/A7GbZVAWZTBZFGQw6LyCF/MIkiTdcOmWSzYbJVE2u1KX0J1v+8QDv/EkyS0yXF/NgeEILiHfyc74mICTQltqYXBeAWU9HGxU09YqqEvAElGjyZYjPyLqitjzHSEiGkrsfMWr0VLe+oy/djGP//YwfbeP8bN3Or0bkqEVblAAAAAASUVORK5CYII='); } .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-after a.useremail[href*='sage']:last-of-type::after, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-after a.useremail[href*='SAGE']:last-of-type::after, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-after a.useremail[href*='Sage']:last-of-type::after, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-before a.useremail[href*='sage']:last-of-type::before, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-before a.useremail[href*='SAGE']:last-of-type::before, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-before a.useremail[href*='Sage']:last-of-type::before { content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAYAAACZ3F9/AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAa9JREFUKFOdkt0rg2EUwM95b2zlL0CRRLngksznXrJsNtYW1tjYhM3mY6+IXZAbikhTKJp8XZAp81UmWYhIRHHhUi60e7s6ntdCa2449es8PfU7z+k5B6AbyuE/wQlc4BcO2d06unAUBCgFE0hianOd3NHIcy8NPwrUf9NBPZcOEi7ayXZiea/1V7+ljaXeYAfOgg2So2TOwQWGnwQafOgi962TnMFmatozUeNu4yetASspVvgXiUvii5K5Nm6z56ol3Hdtpy+cwSYy+HRUt1nLsoEato0kXyh6wTac+24brThWv6MNOYNW9prlG/uxmbRrFaT0VrCspZoNPSUNJNyCBcoiLZuhLH0o9U6UrAfGKCz7RlLM81Q8XUwqr4oKPLIQmnA8IupBigacVy7yrya/2JouhryJHJJNykg+UxLGOtz6+SQNpEiMcduls4Wvoli9WklVKz+ol5SU4U6ngql8Qj2eRI+GyajBhSRH4r3cUxhSeRVhsYBmWUWiyM+UMDmDUI2nsfuSC1I27nLgYZJlP8jhjJ3PY8iE+L8tWx4kQC6MQA5b1D9HNiRCFhx8AF/e2qh92VnKAAAAAElFTkSuQmCC'); }");
+ css.push(".sage-highlighting-image.sage-image-appchan.sage-highlight-position-after a.useremail[href*='sage']:last-of-type::after, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-after a.useremail[href*='SAGE']:last-of-type::after, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-after a.useremail[href*='Sage']:last-of-type::after, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-before a.useremail[href*='sage']:last-of-type::before, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-before a.useremail[href*='SAGE']:last-of-type::before, .sage-highlighting-image.sage-image-appchan.sage-highlight-position-before a.useremail[href*='Sage']:last-of-type::before { content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAABa1BMVEUAAACqrKiCgYIAAAAAAAAAAACHmX5pgl5NUEx/hnx4hXRSUVMiIyKwrbFzn19SbkZ1d3OvtqtpaWhcX1ooMyRsd2aWkZddkEV8vWGcpZl+kHd7jHNdYFuRmI4bHRthaV5WhUFsfGZReUBFZjdJazpGVUBnamYfHB9TeUMzSSpHgS1cY1k1NDUyOC8yWiFywVBoh1lDSEAZHBpucW0ICQgUHhBjfFhCRUA+QTtEQUUBAQFyo1praWspKigWFRZHU0F6j3E9Oz5VWFN0j2hncWONk4sAAABASDxJWkJKTUgAAAAvNC0fJR0DAwMAAAA9QzoWGhQAAAA8YytvrFOJsnlqyT9oqExqtkdrsExpsUsqQx9rpVJDbzBBbi5utk9jiFRuk11iqUR64k5Wf0JIZTpadk5om1BkyjmF1GRNY0FheFdXpjVXhz86XSp2yFJwslR3w1NbxitbtDWW5nNnilhFXTtYqDRwp1dSijiJ7H99AAAAUnRSTlMAJTgNGQml71ypu3cPEN/RDh8HBbOwQN7wVg4CAQZ28vs9EDluXjo58Ge8xwMy0P3+rV8cT73sawEdTv63NAa3rQwo4cUdAl3hWQSWvS8qqYsjEDiCzAAAAIVJREFUeNpFx7GKAQAYAOD/A7GbZVAWZTBZFGQw6LyCF/MIkiTdcOmWSzYbJVE2u1KX0J1v+8QDv/EkyS0yXF/NgeEILiHfyc74mICTQltqYXBeAWU9HGxU09YqqEvAElGjyZYjPyLqitjzHSEiGkrsfMWr0VLe+oy/djGP//YwfbeP8bN3Or0bkqEVblAAAAAASUVORK5CYII='); } .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-after a.useremail[href*='sage']:last-of-type::after, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-after a.useremail[href*='SAGE']:last-of-type::after, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-after a.useremail[href*='Sage']:last-of-type::after, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-before a.useremail[href*='sage']:last-of-type::before, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-before a.useremail[href*='SAGE']:last-of-type::before, .sage-highlighting-image.sage-image-4chan-ss.sage-highlight-position-before a.useremail[href*='Sage']:last-of-type::before { content: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAMAAACuAq9NAAABIFBMVEUAAAAAXwAAOAAAVQAAKgAAOgAALwAAagAATwAAdAAAYAAAYwAARAAAcgAANwAAOAABcwEBZAEBXwEAQwABbwEBaQEBWgEBTwECdAICaQIIcwgBWQEIXAcARAAALgACdAICbQICdAICcAIBVQEBTgEAQgAAQwAkjCIcexomgSIcbRtCnj9IpUNEmT5LoUNYtFE9lDtClD5dtVJqwmNCmEFMoEh1zGcnfCYnfCc6jzc7kDs9kjxAlUBDmEFInUNLoEpMoExOo0tPpExQpU1Rpk1Sp0pSp1JXrFVZrlhar1Rar1pes1xftFhhtmFit19juFxkuVxovWRrwGBuw2Juw2Nuw2Ruw2V0yWx1ym14zWt6z2980W6A1XGD2HSD2XSI3XdgUJhRAAAAN3RSTlMACAkJDBobHyBERUVHR3KIiYyNkJmanZ6rrq+ws7S5vL29vsLFxsfP0dLU5eXn5+vt7e34+fn5LB88GQAAAI1JREFUGFdNzjsSwjAMRdGn2PngmZAUVHQshP0vArYQYCYDlmxLos3tTncx4xjdAMCEhR1ApLup+bPxtgsQzZ2Mr4iPYROEU129g6it0jJCv6xqFJlpKbl2kr21Zsl/Mo0IBpmrqg7ZnPfgSnKuqhrKwO+AVrSUOjmo5VcEuHzH9CEAXaTDYZ88HGh++QNCDFZ4bvbHSQAAAABJRU5ErkJggg=='); }");
return css.join("");
},
icons: {
@@ -12684,29 +12748,29 @@
not: {
'Plan9': 'iVBORw0KGgoAAAANSUhEUgAAAAwAAAAPCAYAAAGn5h7fAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAzE15J1s7QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACAElEQVQoz3WSz4sSARTHvzMjygpqYg3+KIhkE83DKtKlf0C9SrTRuZNEx0VowU6CuSeJNlwwpEO2kJ6SQBiIUAzFjRDF4wrjKosnGx3HmdehFDfpe/2+z/s++D5gU7IsEwRByICIiAEAIiIAYAFAXsjYVr/fLxMRNVvN+prJ5/OA3+/XERFNf02JyeVyDx0OxyvLNQsnimLKfcf9KRQKXQAAnE6nlf5qMpnQycnbP/kAoKoqsSwLAJhOp+AAwOv1otvtpqxWq73dbt/r9XqvEQ6HUalUEvF4XLd5IpvNZqlerzd5nlf6/f6tTCZjBACk0+nb+XxeW4UrikLJZPImAGA0Gq0NIqJyuSyyANDr9Q5Wu1utFvR6/SULAI1G4+vK8Pv90DTtGwsAJpPpaGUYDAZ0Op3PHAAEg8H3tVqtbrtu21sqyxuRSOQJk0ql9IvF4r7b7f7pcrlejkaj57IsH58Pzp8dvjhc/lsBk0gkbLFYrFqtVvd27+4qOk733ePxPDCbzVBVFfP5fCiK4rvhxfDN/qP9wSasGwwGMv1HiqJQsVg8ZlfTHMepkiR1t05gGJBGmM/nMBqNj9nN9kql0lNN064ARISzH2cQBAGz2ewLu2na7XYLwzBbvxYIBBCNRrFj3BmsAZ/PZ+J5/kOhUIAkSVeA8XiMZqt5efrx9OA3GfcgvyVno9cAAAAASUVORK5CYII=',
'Neko': 'iVBORw0KGgoAAAANSUhEUgAAABMAAAARCAMAAAAIRmf1AAACoFBMVEUAAABnUFZoUVddU1T6+PvFwLzn4eFXVlT/+vZpZGCgm5dKU1Cfnpz//flbWljr5uLp5OCalpNZWFb//f3r6+n28ff9+PRaVVH59Pr//vr38vj57/Dp7eyjn5zq8O5aVVJbYV9nVFhjUFRiWFlZVlFgZGOboJzm5uZhamfz9/bt8fDw6+drb26bl5j/8/lkX1z06uldWFS5r61UT0tfWlbDwr3Ew76moqNRTU7Mx8P75OpeY19pWl1XW1qzr6x5eHaLiojv7+1UT0xIU0uzqadVS0nV0MxkZGT5+PPk497///ra29Xq5eFtY2H28e2hnJignJlUUE1dXV2vrqxkY2FkYF/m3d5vZmfDuruhl5aZlJHx8O75+PZWVVP29vT/9fTj3trv6ubh5eRdXFqTkpBOTUtqZmX88/RMQ0T78vPEvr7HwcHDwsDq6ef///3Gx8H++fXEv7tZWVedmZZXXVudnJp0c3FZU1f79fnb1dlXUVVjXWFrZmy8t7359/qLj455e3q4s69vamZjX1zy4+avpaReWFz/+f1NR0vu6Ozp4+f48/lnYmi8ur3Iw7/69fHz7+xbV1SZmJZVUk1ZV1zq5ez++f/c196uqbDn4uj9+P7z7vRVVVXt6ORiXl/OycXHw8CPi4ihoJ5aWF3/+v/k3+axrLOsp67LzMZYU1m2sq9dWF5WUU1WUk/Au7eYlJGqpqObmphYVV749f7p5Or38fPu6OpiXFz38fH79vLz7urv6+hhYF5cWWKal6D//f/Z09Xg29exraqbl5RqaW6kpKTq5uPv7Of/+PDj29D//vP18Ozs5+OloJymoZ1ZVVJZWVlkYF2hnpmblIyspJmVjYKQi4enop5STUlRTUpcWUhqY1BgWT9ZUjhcV1NiXVkkhke3AAAABHRSTlMA5vjapJ+a9wAAAP9JREFUGBk9wA1EAwEAhuHv3dTQAkLiUlJFJWF0QDLFYDRXIMkomBgxNIYxhOk4wwCqQhQjxgxSGIsALFA5BiYbMZHajz1oJlx51sBJpf6Gd3zONcrqm/r1W8ByK0r+XV1LXyOLLnjW6hMGpu0u1IzPSdO17DgrGC6AadrVodGcDQYbhguP6wAvAaC0BRZQalkUQ8UQDz5tAof0XbejOFcV5xiUoCfjj3O/nf0ZbqAMPYmzU18KSDaRQ08qnfw+B2JNdAEQt2O5vctUGjhoIBU4ygPsj2Vh5zYopDK73hsirdkPTwGCbSHpiYFwYVVC/17pCFSBeUmoqwYQuZtWxx+BVEz0LeVKIQAAAABJRU5ErkJggg==',
- 'Madotsuki': 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAMAAADTRh9nAAAALVBMVEUAAAC3iopWLTtWPkHnvqUcBxx5GCZyAAARERGbdXJrRUyGRUyYbY23coZFGDRFGEYfAAAAAXRSTlMAQObYZgAAAGhJREFUeF5Vy1kOQyEMQ1Fshzd12P9y61AixLX4yJFo1cvVUfT23GaflF0HPLln6bhnZVKCcrIWGqpCUcKYSP3JSIRySKTtULPNwMaD8/NC8tsyqsd1hR+6qeqIDHc3LD0B3KdtV1f2A+LJBBIHSgcEAAAAAElFTkSuQmCC',
+ 'Madotsuki': 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAMAAADTRh9nAAAALVBMVEUAAAC3iopWLTtWPkHnvqUcBxx5GCZyAAARERGbdXJrRUyGRUyYbY23coZFGDRFGEYfAAAAAXRSTlMAQObYZgAAAGdJREFUeNpVywkOwCAQAkAXtPb+/3PLWklTiIlMtDiH4rvpVM22K+WvY+7Z/dOxZ2xkLmYpNWo6RoKMUQJ8SYiozEYiZAuLbCZQsGB+/hC4SwZsdV2rTjSR0+J9tzXL0B4RW5f9VbE94skEEpHbpw8AAAAASUVORK5CYII=',
'Sega': 'iVBORw0KGgoAAAANSUhEUgAAACwAAAALBAMAAAD2A3K8AAAAMFBMVEUAAACMjpOChImytLmdnqMrKzDIyM55dnkODQ94foQ7PkXm5Olsb3VUUVVhZmw8Sl6klHLxAAAAAXRSTlMAQObYZgAAANFJREFUGJVjYIACRiUlJUUGDHBk4syTkxQwhO3/rQ/4ZYsuymi3YEFUqAhC4LCJZJGIi1uimKKjk3KysbOxsaMnAwNLyqoopaXhttf2it1anrJqke1pr1DlBAZhicLnM5YXZ4RWlIYoezx0zrjYqG6czCDsYRzxIko6Q/qFaKy0690Ij0MxN8K2MIhJXF+hsfxJxuwdpYGVaUU3Mm5bqgKFOZOFit3Vp23J3pgsqLxFUXpLtlD5bgcGBs45794dn6mkOVFQUOjNmXPPz8ysOcAAANw6SHLtrqolAAAAAElFTkSuQmCC',
'Sakamoto': 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAQCAYAAADwMZRfAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAxVJREFUOE+Nk19IU1EYwK+GQQTVQ39egh6ibKlzw91z7rn3bvfOmddNszl1bjKXc5rJJGmBUr7Yg9qTD0IalFgRBEYg6EDQQB+GovQyQgiaUZsoLcgHMcr069w7MgcGXfi453zn+37fv3MYZt/n99e76tzVj4JN/hP79fvXnV3hnNabwUBjoOHcgTYOu/JQspgTzsqKgn9BfD4vkWTzur287PqLVy+zM+yePB7KsRXLywTjnSpnZctBkPCdW8ccDuU55vBO8RXbkC/oP5ph19V5+7LIky0OY1BKbZEbLcFSt7u6pN7jLmltCVrr3DV5jY3+KovFEsccB1KJNVpefe10BqS2tqqO4/AuphBB4L/LkrRqNgtJs1lMypLls1kU38mytMLz/E8VIlutqVqX6/weZG52OttRXjbE0cP/FYLRlpVjDXuQ/r77x2XZPKkCHA4HBAIBkCQpAygIAvh8Pu2MZgO0Lz+QSa/sQfwN9RfpVN66XC6Ynp6GhYUFGBwczAC1t7fD0tISxONx6O7upgHILmsqvLcHodOggfiV/v5+SCaT4HQ6IRaLgdfr1bIRRREmJyfBZrNBNBqF+fl5sNsdgE2GiAbp6bmbdbXC7qWQbxMTE7C2tgY6nQ5SqRSEw2ENopaoZpCXlwdTU1NaoECgCbgiU6y8QH+ECYWaTymK7TWdys7MzIwGaWtrg42NDejo6AB1WjU1NZo+FArB2NgYrK6uQrAlCASxn2z6wkuMp87VIAhkE2MEAwMDkEgkYHx8HBYXF0HtkQpRy1BLiEQisLy8rPVNKSsFjEzrXH4+z1hlS4xDhKadNu7t7YPR0VHweDzAEVWfHru6HxkZgeHhYVAURYNjkylVWKArZjjMzqmdVi+QCsLUkQiEjvDvncEkvU7/qQ0Vgukeo48Go87IiCJnZNmipxiz7wXEbVDnbUxQOgM12h9n6qTq6NvapRdtkwaP0XK8RmPuYSbxYfaQ/sJJhjfknuFRURUi7AMOozcCwl94hLZp5F+EioDQVwqYI6jomZU1NFtM+rOSxZjVazcyvwHr/p/Kws1jegAAAABJRU5ErkJggg==',
'Baka': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAA0pJREFUOE91k3tI01EUx39JOpA0H4jNx0pbD3XTalISWf8YFlEgldqDsBLLyqjEKBCiLLWiggh6/KEV1WZ7OaelLZvDdDafNW1JFraWe/32+01FrUZ9uy4ylLpw4Z5z7/nc77n3HIqaMRIjZJyEcNX+uFCFeGmI/GZciEIsCFJUTvoAzDz+1y7K76MSwhX5hXl6z+WSbrzU2KB8YEGDwgrTaxZ3b7xHcaHhR3xw7Z5/UviB1ReP5XSg3+TAqYJOxMzWISFIC0GQDomhTVA9skCnsaAwp/vnMq66dBokNuBR9uFd7T9Z1zCunjci0qcRJUVdoJ3DYOhRnC/qBZ+jQbfeCc+37yjY2UEg0iwvJE0k9l8Z+8xqHmTgot0QLdQgTaQFQ2AsOzlHvOu1S5pwOLsHHo8HjHMCq2MazNvTlByKHyrJLDvdR25jMWRxYx5HjeMH2r1BDOOeguRua4OI14jx8a8YH5tA+al3EHKlW6mYOapb2oZBOOwMbEMseAE12L+jjUh3w+VipyAZ65oxn1NP/GMYGR6Ftn4Qsf7qa9S82Y/l/X122G0uL2TbxmZEz1WhXW8mUol8moXu+SCi/OoQ6VsDh3UUwyQ1k9GOaI5MTkX4yWTGHutvgI1F28sviAlRgxeoRm62HvsyW8En9pZ1TYgi6TntoyQtFm86rVgUoJZRvDnKMmXVAGxWmkAYOBwudBqGcHCvHulrGpGT2Uy+z4yT+QYsCXtCUpp8GxbKhx8gDK0ro+KjJGvzdjfDZnN6VdisLD5/JjArQ2zW66PJOj2lEZtStaBphkwah7K6kMJ/GEulp1bMWhAmMbTozOQRaWRtfoZVgjo4iRra4SYgGi26TwjxVeDKhR7Y7U606ixICq9tr7hd7+OthRWL7yUnJ1WPmXotqLhpRICPHCePtuFV6xdUPTAhcWEtRHEqfHpPyto4hPXLXnzflSEJnFaN3OCKDcsFsrEntR9RUmxARLAUgT5iBPuJsXWDBj0dZjRU9yNV+PTbpjTp9OA/pOSk24nRkXf1J462oPxcJ65f6ULlHSMulepRerYDgvj7A0cKpNz/tyTZqbzXO4t0ZZGQJ34RH11lFHIlA8LIqreCCMUZRY3cd2bwL/5/RmjNSXqtAAAAAElFTkSuQmCC',
- 'Ponyo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAuNJREFUOE+Nk3tI01EUx39BTytConQTt1am07m5abi5KT5S8z2dj1yOEMUC7aUgIoimlmUEWX9kBZGWaamEmE6U1BI1XNPNGTrnHs33IwuSXrL4NgcJ0mNdOHDh3PPhnPP9XoKwcroJYvMQiRSicHCQKCgUyZC9/T5rNet5KUFs0zCZbZMsFmZ9fTEjEEBDp4/KSSSb/4JoGIyWaTYbiykpWEhOxhSHAzWD0aqkUGhWAcVkW58xlvuPhfh4zItEmOHxYDR3MhcdDaNAsKJydAz5IySKRNjEUmy88vjOVaU8F0iPCqCNjEBHkC/UYaGYFwqxmJoKLYOhkxPElg0QsbNtTlmox9yjRD9UCbnoOR+J/lwRWtOCcdXfDc2BPpg0d7CQlIQZPh9KKlVkAQjJ2x2zmOSsQu7hpzUJfBhLjsNQmADjxcT10Bcl4rE4EHc5LjBEhEPn7f1WTqXSLQB/s1Tp7vslsoIkyPPiMJAbi86McBguiaHKjoEqR4jJy2K0nAxApzMN5iUGrclrKVaz2fUvuF4tRbxDKA90w5VjTFyLZKHpTBSq4/1QnxGB2qxoVIZx0JopRCPHFSNOThfWZzfrXDcZEowH4iA05ATg68hDtBaL0HAuCm3lJ9Bfcx2fFNUoi/DCjRgfNHHd1wCZA2TyXjNkE6F0cBDpPFiojeNi8EkJdFoN3vXch0nbBJOhDd907dANv8JITxNqziag3ZsJbUDAwLin50Q9QWwl1qSYoNOVvUcOoqOqAAa9Fu9H2/F9+B5WZLcwOyxFX18flLI+VASyMGVeoJHD+Tzq5BS1PoaKRrNT8127P74swsq4FCa9FKvqBqwaOiz3hdEuLKueYSyECT2LNW0eIfo3E/WmEbvnG1MUJnWdpWhDGDvxQXZHo+RR0uW2tnv+auPX+TvtJm7zKpaen/4y2yjBUlcxlvtvmvT16ZWDpQeoVv3/60F/NrHjTf4ugazIXtJ8ivjnz/sJ+yGQRjcqUdIAAAAASUVORK5CYII=',
- 'Rabite': 'iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAD/0lEQVR4Xl2MXUxbdQDFz/9+9Lb3tkBLCxTKhzgoOOZAsokbJmZxDFHnd+LL4hKVzBgfNCY++ODbjDEaZowvErOM6HRu6hKZY2rIAOkCY4OSDTpFaAsrlJa2t5+39+NvjT7tnJzknIfzI98Nf/C6TuXdguWBd1q9rcb8/CwsZiu2Ywm4nDVo3VWLZCKDaDwJq9mCg31PgjAMKKUwmcyYvTbek9iJRDm6M/XswEDjwNz6plWW6wdZhjUAintFCEEhn0N04zYskljaDLaj8ar49oUrsYR6mrFJNj322w46H8y+mitM/ZJKZmyE4XAvjJSsazpyuSzslVZIkgWKOvvRgQ6Xrdlhqmds7o7bFZoLkctreKxf7GtuCE7IyUQjBQcQ8j/lvxCGQJZz0IoCVpamTtzfIh9nwiaIrCQyjNg8mq11oDLUhNXRJfT1Ozr3tS/PqpnQ80qRgjAmKIqBfK4ItbSLKoOZqR/6neLkENlSUAIhlktvEf+sD2rkm8nWTHtvZCGMVON1ePuaoBER31/MXGly1wSqq9Uug6FluYyWXJiPqFXmjd4Dh9oF9ZKKimYXRtYCx8lmMIDIxlIPGz591av0mtanF7FcCEN6iMXeox2wOJ0QJAmUAoRQaIqCnWAQY1/ewKNGNeQuYXkm0d2NC2e+wvmRr/Hx+6+8PHayrbDyyQBNDb9As3PHKDWG6MTM23RoeJAWsqeoWvyUUv0UHf7pBB0fe4OeeXe3/vmHbx3+8dwIGJ4IsFpMMFe0fbtAn+nwZePr1u4MBK8XIALG/Rt479wYrs2vgeNNAMNgMbiNzybuoKVvn+Gs9kbr6qpBfJfGYHFIkJUCoGwfqcoMX/b27EGhwgOjoCADDlP+CA51ugFFRzoB8FYNaQ1oqKD44+eNL+wNj7zJGQSIhe8+jgQ9thk+27v/KRY6L4FSCkVOwtlQj6P73Qgt/o1ERoKt4iUkE7+jrZMHyzIoK9cOBFfT4LbWAk+0a7ZLnvqHcTNdACgFScfAcjxEdy00VQclHGo7dqGeYxHbvIo6hwhSghCehb3G5p6eW7VxXC5/xGWToMgrKKoaCnIalI9CIARasQAqloMI/x4BWrLLYwE1AEPTwCGHaGjz7pw/leZUNV8wNm9BLy6CxsvxZ1kMbaY4TKIIXlNBsynoVjvAC4CuAoYOVi+CMfLYCUfg95tPHuzZB0YtKzsb58RMucWE/fZmhCbdOP9rNnLnxko6GVoB8lFwyVVw8b/AyeulHoJyN4Rb19dTFyeqBlu6njvfsWcvOJvLs7DMmw/7bvpeE4pU2OIcgcqmp4fGAgt2Txwvqr7lTp5V7LquZxXC6+BqEvGcY5pyjaM1tffJbk89NE3FP5VQ6y7a+paZAAAAAElFTkSuQmCC',
- 'Arch': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABCFBMVEUAAAAA//8rqtVAqtUQj88tpdIYks46otwVldUbktEaldMjldM2qNcXk9IWktQZkdIYlc8mnNUXlNEZktEZlNIYktIWlNMXktE7o9klmdMXktFHqdkXk9EWk9EYk9IlmtQXlNEXktAWk9AWlNEYlNFDptkZldMYk9E4otg/p9kXktEXk9AXlNA4otclmdQXk9IYktEXlNEwn9YXk9IXk9FFp9o3otgXk9FPrdwXk9E2otdCptkXk9E/ptkcldIXk9Edl9IXk9EjmdUXk9EXk9EXk9EbldIcldIjmdMmmtQsndUvntYyn9YyoNYzoNc0odc1odc2odc6pNg7pNg9pdlDp9pJqttOrdzlYlFbAAAARXRSTlMAAQYMEBEVFhgcHR0mLS8zNTY3PT4/RU1kdXp6e3+Cg4WIiYqMjZGXl5mbnqSnrbS3zMzV3OPk7Ozv8fT29vf4+fz8/f7SyXIjAAAAmUlEQVR4XlXI1WLCUBQF0YM3SHB3a1B3l7Bx1///E6ANkDtva0jKbCW2XIH1z2hiZEZ4uUgxo7JedTQye/KN/Sb5tbJ+7V9OXd1n+O+38257TL+tah3mADAwSMM7wzQWF4Hff6ubQIZIAIb6vxEF4CZyATXhZa4HwEnEA+2QgoiyQDnIEWkjVSBBZBqXbCRlKYo8+Rwkyx54AOYfFe7HhFa7AAAAAElFTkSuQmCC',
- 'CentOS': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB5lBMVEUAAADy8tng4Ovs9tnk5O3c7bX44LLduNO1tdDh7r/eutj43q2kocX23az07N+qqsvUqcmXl7331ZXJj7r40o/Pn8T42qP63KjNw9n21p3Y387Ml7732JzR55z05MSxtMLGn8TC4Hx8eqt8e62Af6/B4HnG4oPC4HzH44fBf7LCgbOkoMTcsrmtn8PWqcfFtKrj4Jvs2ZOz2FnMqLXT3KfY5p60Z6NUU5XRuqHzwWSywqDn3JaiiLWahrWhkry5zJjRmqm1Z6P1wmb1y319fK632mK5cKi5nH+73Gu73Gy73W283W+9eK17e6y1yZS3aqRZWJdcW5ldXJplXZppaKBwb6VwcKV5eKswL306OYNPTpGkfK+m0kGpUJWq1EnEqIuXK3+Xh7ahP4qhkryMfK6BgK+CdpGMaKKMa6O9ea2+eq6+oYW/eq+NbqWVlL2Wlr7AjanA4HnA4HrBkqbBlafB33rCgbLCmKjCxIzC1mSs1UytV5mtxIWt1lCuz2evWpuvXJywxYzHjrvH4oXIjrrN2HXO5pTO5pXUlYnUlYvVl5Hb0G7e0XTg03rhr5fpzHPpzXTp0Hvtz3/wrDHytknyt0zyuE3yuVHzvVr0wGP1x3T1yHf1yXe0ZaL2zYP30o730pD31ZeRIcF5AAAAQ3RSTlMAFBkbHEhJS0xMTk5UWWBsd4SEiIiPkJCVlZaam6CjpK29wMPDxMTFxcnK193e3+Dg4uTn5+fo6e/v8/P4+fn7/P7+J4XBAAAAAOBJREFUeF5Vj1OvAwEYBb/yGlu717atLW0b17Zt2/6nze42TTpvMw8nOZCAmwUpiIY6c5IiLi9tPX64GairqszHQ4X2VB64v1Cs6PxMPJSdHM777s6/jyaMRGiRLyyrb88OpjZ3CzAXrm1sqzSNNeN7kVBPNgB7cG51abE5l9cXDces7emQ1uadHhutFUg6gpPKkSIqQGavwz7r7O/+/3t/rSdjI9XDM3qz4fr3B/3iA0aJTG9x71+9oR/PLDwUe2wm19bly+fTIxHyEETatbPewGEw6Mk/tKZCEqSQQUlIHB/QNBEjjVN1AAAAAElFTkSuQmCC',
+ 'Ponyo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACAVBMVEUAAAAAAAA/AAC/AADMAACqAAC2AADGcQBMGQCyZgDMGRnEYgDMERHJGhrOGBjHeQvSISFPGgjNgyDQHh7MHx9QHgqBGhHLeQzQHh7OGRnSHR3WJCTTJCTQGxvQHx9jLBbKfxjPGxvPHh7QOB7TJCRrLRrTJCRZJhHbljjeqmN3OibaLS1+NyXYMDC8NzPaKyvYKyvaLS3YOincQEDorFvbKCjdNjbaKCjuypjZMjLcKyveLi6GRi/hOzvhMTHrs2ftxpHXLix/OCODOCeGSjOHRy2IPyqJQSqKSy6PTjmQQS6XSDGZMSefWUKgTzehUz2jVT2kVDqkbVSlWUGmUTema02qZUqrbkyrckCsMSmwNyywbEyyQTm0XkC1YkS1ak+1gVK2Qzu3iVq5Ni26Qjy6oHy9JiG9ZUnCb0vENCLFxcXGdVLGpIzJdVDKfFbMd1HNqILQysXScU7Sck/TwrDXRS3YSEbcS0rdLy7d0cHd3Nref1XfSknfflTfhFnf3tzgwp3hLi7hgFXhglfiLi7iRUTiTU3ihVnjMTHjSknkMDDlODjlOjrlOzvmPDzmrFzm0bbnTU3oT0/oUlLpU1PpVlbpWFjp1r7qW1vqYGDrvoHs1rnt0q7vwH/yz6HzypLz2bb306L43bn50Zr62Kv637r82Kf83LD83rb837f84b0dlQysAAAAQnRSTlMAAQQEBQYHCQoKCg0PExUXFx0fISgzOTtCRUVMTVJSXFxcXGNqa3BykJegp6mqtLS1t7/Jz9DU1trb3eTn8/X2/P3IgXZJAAAA30lEQVQoz2NggAJmSUUlPgYEYDNs6es150II6HfNmNZhIAznizlOmdzdONFWCsLlENVyTixPKZs004oFxFe3CfDLyI5zi2mb2iPHwCCoqhPYXNvU1FQd7FNjJsLAwCSfl5+bXldU3B6bJsHMwKCr5+Tu6hHtHxbqHR+pBjRAu9U3YmFCeFLOPBfPKBVeRgbZipCCqoblKxdVlgQlG1uyMrCYZqbWz148f0JWoVennTRQj4DR3AUrlixdMX1OqbUM2FncJstWAMEqC2UeqLv5Nez7ZzloCiH5lV1cgRPKBAApxz0bK1ScOQAAAABJRU5ErkJggg==',
+ 'Rabite': 'iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAD7klEQVQYGQXBW2xTZQDA8f93zmlPe7qOrVvXyzY2B6ybTLksIAImanTiDGimb/pAohISEx980TffTHwjPviiDxiNokajMSAQIwEGIwzYTWAFcZdudOt9bdfbuXz+fuLHrz9935bFnbr3yY/6Y/3O9PQkXk8T6UyeYHuY/u1RCvkyqWyBJo+XQyOvIRQFKSVut4fJG5cO5HPJlCZz42+MjvaM3l5ZayoWu0+oiuqABAAAAEAIQa1aIbV6D6/PQAiFdCrbkU3/cjGTN08rfp/fzvyVY/fTm+9WauN/bhTKfqFogAQAAEAgsC2bSmWT1rYmfD4vdXPy84NDQX9fwN2t+CND91qsIMnzizx/xBjp27p0pVjI90g0EAIABCBAKIJisYLV0Hl0f/zkth3F40rCjaH6DEUx+s5uRgO0LfeycPY+I0cCu/cNzk+a5eWxekMiFDf1ukO10sBsSBqmws3xX4+0G1dPifU6SsJNplJaF7OTE5jJ76/2lwcPJ2cSbPTcIjbSiyUMfv69fLE3Eo6HQuYeR5HNlbJVmJlOmh2e1cMHXxzUzXMmLX1Bvl2MHxdrS3GSq/cPqInTl2P1w+6V63PM1xL49qrsOjaEt70d3edDShBCYtXr5JaWuPDVHZ5zQhT36PM388PD6rN795LLOyu37q7+W639cTTQoWsD/X6697fiHxhkYibJb+cfs2egA3DQNDdnrqXpjUWZW5h2HlpPvR3eOhhXXEKnyevG0zJwZka+PjSxmV1pGi6jx2IgdC7NrvLxTxe4Mb2I5nKDojC3lOaLKw/YMbLPaQ/FUp2dIbRgWzvegA8j2Ar19LaO8q0uJTRITfFQz+c4OTbM0PYou3aGKaSKlPLwyZu7KFmwtUVqldTsCc32faA4AjKJxy814tlvlq/+8GVvp4rt8iGlpF4s0N7i5dj+CLn4fzz6J0N18wXSCYXekI7LMGjeYh1cWiihrS/GXx20/Oe6up9hqlQDKRGlDKrmwohEsUwbKTSiQ9vp1lQya5fpDBgIVUG4VFrD/sj12wt+TatUXwn6fdSLj2iYFrViCelKoQuB1aghjS0I3UCoIJEEu7xIBxzLQqNCannt8e3ZjZJmmtWas3YXuzGHzG7hYXOGAXcWt2Hgskzk5gZ2Uyu4dLBNcGxUu4HiVMklkszOej47dGAf6tjYsXRzw3onpOGOqC1MzVSZym8kvdYGml3SPR6JapZQagWURhmlkqeWzfFgPr/x953wh31Do99FoxE0f7BrZt7leXliauI9vSH1dS0Qb+s9eupCfKa1K8tb5sT8bpdab7Vte7MuXDZaOJ+tBK5LredsOPpEMdLVjWWZ/A+8EtJREuofIwAAAABJRU5ErkJggg==',
+ 'Arch': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABCFBMVEUAAAAA//8rqtVAqtUQj88tpdIYks46otwVldUbktEaldMjldM2qNcXk9IWktQZkdIYlc8mnNUXlNEZktEZlNIYktIWlNMXktE7o9klmdMXktFHqdkXk9EWk9EYk9IlmtQXlNEXktAWk9AWlNEYlNFDptkZldMYk9E4otg/p9kXktEXk9AXlNA4otclmdQXk9IYktEXlNEwn9YXk9IXk9FFp9o3otgXk9FPrdwXk9E2otdCptkXk9E/ptkcldIXk9Edl9IXk9EjmdUXk9EXk9EXk9EbldIcldIjmdMmmtQsndUvntYyn9YyoNYzoNc0odc1odc2odc6pNg7pNg9pdlDp9pJqttOrdzlYlFbAAAARXRSTlMAAQYMEBEVFhgcHR0mLS8zNTY3PT4/RU1kdXp6e3+Cg4WIiYqMjZGXl5mbnqSnrbS3zMzV3OPk7Ozv8fT29vf4+fz8/f7SyXIjAAAAlUlEQVQYV1XNQwIDAQBD0dS2bdvmNLV5/5t0UU52728CvGayQLx8UWz1eKoXhdBqmRaF6mbdVfzZXWgetomfpY3b4Hruqb7B97hf9rtT5mNZ+7ggyaHuHTxzzqIxgUy+LG+RWSBFjrQAgAhJF+Ak6ykA0PRJOgAj2QlKAOTISkADKMM1Mg4YJmXr585cEozw2vE3m/8J5h8V7jsI1XAAAAAASUVORK5CYII=',
+ 'CentOS': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB5lBMVEUAAADy8tng4Ovs9tnk5O3c7bX44LLduNO1tdDh7r/eutj43q2kocX23az07N+qqsvUqcmXl7331ZXJj7r40o/Pn8T42qP63KjNw9n21p3Y387Ml7732JzR55z05MSxtMLGn8TC4Hx8eqt8e62Af6/B4HnG4oPC4HzH44fBf7LCgbOkoMTcsrmtn8PWqcfFtKrj4Jvs2ZOz2FnMqLXT3KfY5p60Z6NUU5XRuqHzwWSywqDn3JaiiLWahrWhkry5zJjRmqm1Z6P1wmb1y319fK632mK5cKi5nH+73Gu73Gy73W283W+9eK17e6y1yZS3aqRZWJdcW5ldXJplXZppaKBwb6VwcKV5eKswL306OYNPTpGkfK+m0kGpUJWq1EnEqIuXK3+Xh7ahP4qhkryMfK6BgK+CdpGMaKKMa6O9ea2+eq6+oYW/eq+NbqWVlL2Wlr7AjanA4HnA4HrBkqbBlafB33rCgbLCmKjCxIzC1mSs1UytV5mtxIWt1lCuz2evWpuvXJywxYzHjrvH4oXIjrrN2HXO5pTO5pXUlYnUlYvVl5Hb0G7e0XTg03rhr5fpzHPpzXTp0Hvtz3/wrDHytknyt0zyuE3yuVHzvVr0wGP1x3T1yHf1yXe0ZaL2zYP30o730pD31ZeRIcF5AAAAQ3RSTlMAFBkbHEhJS0xMTk5UWWBsd4SEiIiPkJCVlZaam6CjpK29wMPDxMTFxcnK193e3+Dg4uTn5+fo6e/v8/P4+fn7/P7+J4XBAAAAANNJREFUGFdjYIAAcW4oA0rJOFnywkVk1VVNWyf1OehpaQqABTW8213jJna5lfnECoMF1NqaC2MmdM5tyfKHCJi4FpV69nc05VTXK4D40hVVtR5ehjqZDUkJNjwMDKKOBeUlxcZ8EnbJiSnB5hwM7GbRuRnpulJyFvHZ7mlKLAwMXLZhofnh9tYLF8ycrs8EMkQ7Nc830K93/jznOZJgW1RcfIMiG3tmOM+aKgIWUI4KCYio6Z42e8pkiAC/oKC8VV2lgZiQEBvcP6xGioyo3uVkhvIBH9A0EWEgTIIAAAAASUVORK5CYII=',
'Debian': 'iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAZ5JREFUOE+Nkk0oBHEYxv8fu5GQj3JwcaDkIAc5IpR87M7MKnIVJVKclaIQ5Sy5OLkgR7n5OigcSNpmd2c2Vyfl4KT8/muWiVU79TTv+7zv837NCBF6PG1X+NpZyEYSD9mIc+tHnBPe23B9xKrCuTmbQA/JKfABrhBswa1hH4A38IwfOxPdX1qcjiCQxO5NyrjKV70TnSbeRPwJvGN3i4yyqnEucPY8ZZX9GSEgGK+RvFfyjk2VKZxzBNG8wJWWgh/xtDOeUXZ7Slr6TrSLYL9N4SMgYTTcwdc2ArvJcElhSVcM6mCNSV8n9hA59yTU5UWMG6HIbLhIWlglgWiC2L4Z79qTdo40D6ISuOWwKCWHyk9Fv8ldpUHOuGTuynwSBUynddPdlbEosVpP9Eu4FnOsRzUYNTsdmZN/d5LDiqM0w+2CMdAFFsFGWgfXxZnheqe/z+0puwEM0HHYV3Z9Sgz8TEz7GkQvpuJ/36ggj2AaHLrSlkULWV5x+h2E8xkZL16YVjGNaAUscfZ/f6c/k9ywLKI2MMcRWl0RLy007idmRbQJ7RIfDAAAAABJRU5ErkJggg==',
- 'Elementary': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAAAEgAAABIAEbJaz4AAAGcSURBVCjPfZE7aFRhFIS/+TchRAtRlBQqiMpiEILsf/cBoviqxC42hliktsgKK4gKkS2sUkRUUFCwCGoqZclFiIUQWN1k790gKFHBxkdhYSMIgeT+x+KqpTPdzMBwzsjIUS2GMfN4IFXqHi19zHUHIPl61rFt1tIM09Zie7bs6xKADMnPM2Tn3VG7okVzHLHJsOIe6ld6xgyjVPeJ7/cN/7N8yDD8cf9l/8DIZr9YqhuqFLOOHS640GE0Wch7o2/hdO9NbWhjtVBzYYzZdDXcVvzP3sRgYQ0635nbOOfM25IcVZ79OQebYLn7ASR2KXJ4euU9DGavc3tkqy6qAeAvcwrvoG8tCHQAINoysGBPum/Bn6BJExyp7Us+WVcVqJR5aQ/Sa1DZrcfcsM+kTmkYBc1yKbofYmskd6F8NvR4nl5X1RJVillbc3aMg0BbrbBXETvsQjrvh9Uu1Apff9xb5yp3wgSpdnJSfbxYH195F/UrtlvdGAP52L/Pv/iXpWGf+BgZMkAqTWpKT+2VOiGjpCrj1uzdNCMP/G/u39MktJ21xpKNAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDEzLTEwLTE1VDIyOjIzOjU0KzA4OjAwkOuuIAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxMy0xMC0xNVQyMjoyMzo1NCswODowMOG2FpwAAAAASUVORK5CYII=',
- 'Fedora': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABPlBMVEUAAAApQXIpQXIpQXIqQ3UpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIqQ3QpQXIpQXIqRHYpQXIpQXIqQ3QqRHYpQXI8brT///8uTYMpQnM5Zqg5ZqnS1+I4ZaY4ZactSn8uRnYrQ3MrRXgsRHUsR3s8bbM8brMtSX4wUosxVI01XZw2X50vUIguToQvR3c6X5o6aKs6aq08Un8qQnM9VIFDWINJXohKcKlXapEqQ3UvUIc2X55bhcBdcJVgcpdhfapmd5tuk8dxgqJ1hKR5jbB6iah/m8Shudq3v9C4wNG/x9bFy9nFzNnFzNrIz9zK0NzK0t/O2+3P1eA2YaDU2eTb3+jb4Oje4urj6fHm6e/s7/Tz9fj3+fz7/P38/f3+/v83YaEa/NNxAAAAHnRSTlMABAoVGyY1SVlpeIuQsLfDzdHW4+3y8/b39/n6+vr4+ns8AAAAyklEQVR4XiWN5XrDMAxF75KOknYdZJS0klNmHjMzMzO9/wvMcH7I37mSJShsJ+5NjMT6umDoHyXDcI/2qJadh++P3cle1de+9yPe3/bTY92wzfzr7wGtP3JrAI72BZGVtcAdQlwHy+JS1pDbBE9qamZF3BYrjQxPEXwKc6dC8bXFm0QIpmt8kn0Rn093q82UCtK8oXZckwFJzuulV8bHkajPyXdbnJnARfDHs0trz+JQ+5AFvzp/L0+cL2qPAINUPrq5OC6p/64F/AMnrST+Dq/r7QAAAABJRU5ErkJggg==',
- 'FreeBSD': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAABIAAAASABGyWs+AAAABmJLR0QA/wD/AP+gvaeTAAADXklEQVQYGQXBS2wUZQDA8f83j33M9rF9d7u4loaWklaDpkSo9KDGaIKUaGxshD2YSPRiuDVeTDyhBxosJCoa40ktpAkPDcUqAYVIpUSUPrAulEdD2bbb7e7ObGcfM/P5+4kwKDvq6yJ1FYYcvb+YAkqAHo/HQ7FYrFIoCiurq9ZXJ06YSOkA+kBzfX06bys3zHxS9EL0tXDVyZfefacqV+X/ZSJx5+qLbx98LhaL9RiGEZWlEsWC/Thd9q6Pf3vs2u6Orc83rFsvTwwfLf5obgywT1Vjh2Hh+rbNsnTssJdNLedK5aIrpSuldKVXKsnH4+Pyn6FDXn5tMef9O+3NvdkvP1V4+EYw2AoQ+KSx8dRYS6NXXnwovaItXduSrrkinWxGOmZWJi9OyOK9m1LmsjIz9IH8QUMOd3WfAQwNKCy2tJwbHB5+XasPaxIHmc4g7WWEZ1MquBiRFlJTf1E7+Tl/H/8asavPzTY1nWd2ZkMDRPeBeHPz5ojwsilEQCBvTSKunCF3M8FSNkBGVTHDYYrLj8jVNhDZ2SMa2zo3MTamaIC/u6Ojr3DtrOrvP0BpdATnyBeIhTxpR5ABUlKSUlXS1dWstbVxdz6hPL0l1quGqkLaKwNvVcjEXNRd/4mit4Z19DjefBEPyCKxgQJQcF28dBrHNDGTSZSezsjeff0hraa2Vs2vrvit81O4vj9xLJcC4ADrQA7YAGqBGsAql/EtLdFQE/L7dF1XZmdnSrbPMJfXoLDmolQK8gJyQBowgQhQDRQBD+hsraVhd4e5MH+/oExfvWLJ9q3/3S7qMpNH2hsS40kFS4EUUAMA2IANRIBXv4uzuO67c2PykqkA5YmZ6bN18YPi0Yoknxc4AsJPCMLVAk2BLKDosCWqs/PZaulkuxk9fekcUBAAQGDks5FT0W++3NuYuC0DVUL4DIEdlIQDAj0IRkigaMjArkFx0tf523sffrQHyKsAgHPhwoXLL+yP9/kePNhk5ExUTyKFkJVAUAiCFZrQup4Rv9ftuLV/6ONBYBVABQAArMvJ5MXW7duD6P62sD8UrPAFRU1TpeCpCnGvPZr7WW///v0jpw+VC9ZdAAABAAAAAMLo7drWrmQyPWG/r8tnaGIjaM05ujr16x/ZBFh5AACA/wGZnIuw4Z4A3AAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxMi0wNy0wNFQxMDowOTo0OS0wNDowMOPVpFwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTItMDctMDRUMTA6MDk6NDktMDQ6MDCSiBzgAAAAAElFTkSuQmCC',
- 'Gentoo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB9VBMVEUAAAD///+AgICqqv+AgIC/v9+Ojqqii9GAgKptYZKQkOmPj/ddUYBgW4eVjeCTgfiWjO5wbJaZkvPBvepkXomYkNldV4Bzbpl6dJ+Uj7ynoO6Vi+1qZI63se2mnudjXYjOy+GCfaqZjvWlm/Pc2e+Oh7NeWIOWjfeXjeW1sd+gl+diXIfp5/KHgKnn5/F2cZx6c6ZgWoXc2e6dltrAvNu0scrX1eTOyujCvup4c5qpovVpY43///+6uPPJyPXq6fvm5vrz8/z8/P7+/v/d3PixqvmxrPSyrfe0sPO0sfS3tMve2/3r6vy6ufPz8/3d3fi3tM63tPO4tsu5tsu5tvO6tfe6t/Vva5KRjKy7tvW7t/W9vPO/vM+/vvPCwfPEw/TFwvTFxOfGxfTGxvTHxvTIx/TJx/aTiOrNzPXNzfXQzfnRzuHS0fbS0vbT0uHU0e/U0uTU0/bW0+zW1ffX1vfY1/jZ2Pjb2/jc2uSTiemVkLSlnvbe3PTe3vng3fzg3f3g4Pnh4Pnh4fri4enj4/nk5Prl5Prm4/ymn/bn5vro5/rp6O/p6funoPWsqs3t7Pvt7fXv7vzv7v3w7/nx7/3y8f3y8v3z8vytqPWuqPX09P319P319P719f339v739/34+P35+f37+/+uqev9/f6vqvSwrPQAR0dcAAAAPHRSTlMAAQIDBAgJCwwVFyAsNUFHSVBneH+Bh4mVmZmanKCxsrK2tr3ExtDW19rb4ODl5u3t7u/w8/T6+/z9/f4MkNJ1AAAA8ElEQVR4XjXNw5aDURSE0YrRtm3b54+dtm3btm3bz9k3Wek9+2pSYFwT8ibzE93hwAtdJqK3nZo4J9hFXbP+vFHOthV6gnGzstZq94wdCs4UCCDymQ2v7X0LdYoSQ0MIENRYzJbRlPTTHu73ZNAL8vivmVui98PpzuqffX0mIPHJGtOQenukteJ+aS3b9htNpDnT9TeZH1bHAwBRMhGpd6e6uNrLoRgxBKmsX47nBlp678ojpEA40fejcmW4e/No0V8IIPfj6eKgbEJ3ZUnzgE1OqWp9Q3VeWRAsg51f1dZ8c31RmAsc+N5JGbG+zvj3BzDCPrzMDC9SAAAAAElFTkSuQmCC',
- 'Mint': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACVVBMVEUAAADh4eEAAAAAAAAAAAAAAAAAAAAsLCyXl5dgYGCnp6eTk5N3d3fBwcGqqqq8vLzNzc3Ozs7Ozs7Pz8/Pz9DQ0NHR0dLS0tLS0tPT09Pf3t/Pz8/i4eLb29vZ2drZ2tna2dra2trf3t/u7O/u7e/u7O/r6+vt7O/w7/Lw8PDy8fTz8fXz8fbx8fHz8/P19fb49/j49/n6+vuPxlmWyGOx437h9NDr9eD6/fj////+/v75/vTA5Jv6/fb7/fnL5bDL5q+AxjeDxUCEzTyGxUaGzjyHxkiHzz6J0D+Kxk6K0kCLyE2M00WNy06P00mSz1OUyF+W2FGX1FiY0F6Z02CZ21ac0Wiez2yfz2+f2mOh4GCi4GOi4WKi4mOk12+k3Wul32um1Hin0nun4G6n5Gin5Wmo23Op2Huq1n+q43Cr526s4Hit23+v6XSw34Cw34Gw6nWx4IKy4IOy44Cy63ez146z34az4IWz4YW03Y217nu38H2625e645G74pK83pu98Iq984W+4ZjA4px0tzDA5ZrB8ZDC5p7D55/E947F6KHF+JHH4qvH6qTI46/K5LLL5LN1tzLL5bN1uTDL57DM5bPM6qzM66/N5rTP6LbP6bTR6rfS573T67vT7LrV7r3X68XX7MHX773Y77/Y9rvZ8cHa7cjd88bi88/j8tTk8djk9tHm8trn89vo89zo9N3p9N3p9d7p9tvq9d/s+93s/dzy+erz+O73+vT4/PX5/fT5/fX5/vN1uzB3vTD6/ff6/fh5uTj8/fv9/vr9/vx8wjV/xDmrMRH0AAAAOXRSTlMAAAECAwQJDzk/RUlNU3F0kpSVlpeYmpucnaKjpKWqqqqtu8LExMTEzdTU1NXY4evy8vP+/v7+/v6LaR1mAAABD0lEQVR4XiXI03bEABAA0KltW9kaW3eSZW3btm3btm3b/q4mp/fxgqKOtpamhrqaqoqykrQYABh+PVMU9fjE5Xp8o54kgPHN0EBHU2N5YXZykiua0HHd2759VF2Sk5IYE5GGsmCEWLV1kVWwt5O+3x/qpgsy8k4ja+cJl2/v5C22tlgCAHtw9TQSa4s+AzfPSm0BRNl9SydhWJzLC567KrNhgrNwHIJ5qTz/2f9w7Jw/DNqIjVr04exW0AEOXcN3Ab7enr9eDW2VTJgehONyc2Z8XP5YdD0Tcuhcc4/r45OjGX51TEjYPbh8THRPvbz+CHusgSZlT7rP8PkCwfQKaQUi9Igr6JsRBMFiWZgb/AHKElRzKopZJQAAAABJRU5ErkJggg==',
+ 'Elementary': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAACXBIWXMAAABIAAAASABGyWs+AAAAAmJLR0QA/4ePzL8AAAFuSURBVCiRfVG/S8NQEH4VimAHcXKS+otIsNb2vpc4W0QXF8FBqKOiIEgQKTgEK/gXBKEOIoIIgmMo6KSIkxYXHRxcqhjQQpQKOojES9K0mxwc7919d/fdd8IToemKLMKGw2bLoq5E8dDFyIALixZlAWvsd/BBhog1ACKGMiqkyiVU5SGO8EQzmV66QNmHMICrK4hjHXUt49dgHM+D7ekELslggK7AJVUbxicmo7l4yY56Yqwbrq4IpmZx6FweN9MdcOVQ8CrRpoBNedGGLzkXAWgFpyF13soWcHhAP7xsMkyPdOFRpoL6DXzDYYDehwF4NBUEO+UNbQd9cvhhCANsbYK/1zA9oWm4xbKf1nrwii3K8wgmWeLKVdSxhzfK+Wk5ixoOmIPFJHnNGit3D4/tShZol1Wp0jR3VYM1A6F+YWaTNI8T3OEMZjrBPeOsrtGS+iFUsbmqyn0iqRvHepf7WJApUpmaxeq2jvX/uf8A9h7IjHC1AQkAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTMtMTAtMTVUMjI6MjM6NTQrMDg6MDCQ664gAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDEzLTEwLTE1VDIyOjIzOjU0KzA4OjAw4bYWnAAAAABJRU5ErkJggg==',
+ 'Fedora': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABPlBMVEUAAAApQXIpQXIpQXIqQ3UpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIqQ3QpQXIpQXIqRHYpQXIpQXIqQ3QqRHYpQXI8brT///8uTYMpQnM5Zqg5ZqnS1+I4ZaY4ZactSn8uRnYrQ3MrRXgsRHUsR3s8bbM8brMtSX4wUosxVI01XZw2X50vUIguToQvR3c6X5o6aKs6aq08Un8qQnM9VIFDWINJXohKcKlXapEqQ3UvUIc2X55bhcBdcJVgcpdhfapmd5tuk8dxgqJ1hKR5jbB6iah/m8Shudq3v9C4wNG/x9bFy9nFzNnFzNrIz9zK0NzK0t/O2+3P1eA2YaDU2eTb3+jb4Oje4urj6fHm6e/s7/Tz9fj3+fz7/P38/f3+/v83YaEa/NNxAAAAHnRSTlMABAoVGyY1SVlpeIuQsLfDzdHW4+3y8/b39/n6+vr4+ns8AAAAxklEQVQYGSXBhUJCQRRF0SNYgIooiPJ0zwXE7k6wu7s7//8HdGAteeFoPNne2lhfpYpIioqWWnkNeNv3X+87HXWSIni73/b2updvq1E4hffys8/ag5toUhRv0QpAn5tCcbyiXQBZN4mSQG62ZDf9Q2PdbhplyPacmPe56TZAwcyIOy4828fj7cp4DhTk3ToU7YoKdbleoGiXlKXVOToPbNkpZTEFv25uefXJDvASIWWGF+7M7GyJf4lqqZnBw+vzowEgHQtJfyetJP7BfFOIAAAAAElFTkSuQmCC',
+ 'FreeBSD': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADXklEQVQ4EQXBS2wUZQDA8f83j33M9rF9d7u4loaWklaDpkSo9KDGaIKUaGxshD2YSPRiuDVeTDyhBxosJCoa40ktpAkPDcUqAYVIpUSUPrAulEdD2bbb7e7ObGcfM/P5+4kwKDvq6yJ1FYYcvb+YAkqAHo/HQ7FYrFIoCiurq9ZXJ06YSOkA+kBzfX06bys3zHxS9EL0tXDVyZfefacqV+X/ZSJx5+qLbx98LhaL9RiGEZWlEsWC/Thd9q6Pf3vs2u6Orc83rFsvTwwfLf5obgywT1Vjh2Hh+rbNsnTssJdNLedK5aIrpSuldKVXKsnH4+Pyn6FDXn5tMef9O+3NvdkvP1V4+EYw2AoQ+KSx8dRYS6NXXnwovaItXduSrrkinWxGOmZWJi9OyOK9m1LmsjIz9IH8QUMOd3WfAQwNKCy2tJwbHB5+XasPaxIHmc4g7WWEZ1MquBiRFlJTf1E7+Tl/H/8asavPzTY1nWd2ZkMDRPeBeHPz5ojwsilEQCBvTSKunCF3M8FSNkBGVTHDYYrLj8jVNhDZ2SMa2zo3MTamaIC/u6Ojr3DtrOrvP0BpdATnyBeIhTxpR5ABUlKSUlXS1dWstbVxdz6hPL0l1quGqkLaKwNvVcjEXNRd/4mit4Z19DjefBEPyCKxgQJQcF28dBrHNDGTSZSezsjeff0hraa2Vs2vrvit81O4vj9xLJcC4ADrQA7YAGqBGsAql/EtLdFQE/L7dF1XZmdnSrbPMJfXoLDmolQK8gJyQBowgQhQDRQBD+hsraVhd4e5MH+/oExfvWLJ9q3/3S7qMpNH2hsS40kFS4EUUAMA2IANRIBXv4uzuO67c2PykqkA5YmZ6bN18YPi0Yoknxc4AsJPCMLVAk2BLKDosCWqs/PZaulkuxk9fekcUBAAQGDks5FT0W++3NuYuC0DVUL4DIEdlIQDAj0IRkigaMjArkFx0tf523sffrQHyKsAgHPhwoXLL+yP9/kePNhk5ExUTyKFkJVAUAiCFZrQup4Rv9ftuLV/6ONBYBVABQAArMvJ5MXW7duD6P62sD8UrPAFRU1TpeCpCnGvPZr7WW///v0jpw+VC9ZdAAABAAAAAMLo7drWrmQyPWG/r8tnaGIjaM05ujr16x/ZBFh5AACA/wGZnIuwraa4ZgAAAABJRU5ErkJggg==',
+ 'Gentoo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB9VBMVEUAAAD///+AgICqqv+AgIC/v9+Ojqqii9GAgKptYZKQkOmPj/ddUYBgW4eVjeCTgfiWjO5wbJaZkvPBvepkXomYkNldV4Bzbpl6dJ+Uj7ynoO6Vi+1qZI63se2mnudjXYjOy+GCfaqZjvWlm/Pc2e+Oh7NeWIOWjfeXjeW1sd+gl+diXIfp5/KHgKnn5/F2cZx6c6ZgWoXc2e6dltrAvNu0scrX1eTOyujCvup4c5qpovVpY43///+6uPPJyPXq6fvm5vrz8/z8/P7+/v/d3PixqvmxrPSyrfe0sPO0sfS3tMve2/3r6vy6ufPz8/3d3fi3tM63tPO4tsu5tsu5tvO6tfe6t/Vva5KRjKy7tvW7t/W9vPO/vM+/vvPCwfPEw/TFwvTFxOfGxfTGxvTHxvTIx/TJx/aTiOrNzPXNzfXQzfnRzuHS0fbS0vbT0uHU0e/U0uTU0/bW0+zW1ffX1vfY1/jZ2Pjb2/jc2uSTiemVkLSlnvbe3PTe3vng3fzg3f3g4Pnh4Pnh4fri4enj4/nk5Prl5Prm4/ymn/bn5vro5/rp6O/p6funoPWsqs3t7Pvt7fXv7vzv7v3w7/nx7/3y8f3y8v3z8vytqPWuqPX09P319P319P719f339v739/34+P35+f37+/+uqev9/f6vqvSwrPQAR0dcAAAAPHRSTlMAAQIDBAgJCwwVFyAsNUFHSVBneH+Bh4mVmZmanKCxsrK2tr3ExtDW19rb4ODl5u3t7u/w8/T6+/z9/f4MkNJ1AAAA7UlEQVQYGQXBA2IDABAAwU1t27aNi1Pbtm0rtW277+wMgEN05nRWjBMAgCJgVUTed+sibQEg9EZEvm7V8x05LgCOJSKi1+8XdKmUhT5AyIuIvHUOLDWoyvKb/MG3uVRExuOTzvqUf6fDrthEfc/diXwczXbX/h7kpYCle+qETrQ7Y+1VDysbaYAiTER3bhhsKXpcn/QG8zgR0e7N9Cjrr0bCLTBNEJHXk4Whtv77ymArCBL5eVKvjfZuHS97mQEZn8+XhxVThuviRGcA0ss1xk3NRXW2nzUAeNZsL7Y25gbaAwCYuMUmR3jYAQDwDzDCPrxVMnjZAAAAAElFTkSuQmCC',
+ 'Mint': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACVVBMVEUAAADh4eEAAAAAAAAAAAAAAAAAAAAsLCyXl5dgYGCnp6eTk5N3d3fBwcGqqqq8vLzNzc3Ozs7Ozs7Pz8/Pz9DQ0NHR0dLS0tLS0tPT09Pf3t/Pz8/i4eLb29vZ2drZ2tna2dra2trf3t/u7O/u7e/u7O/r6+vt7O/w7/Lw8PDy8fTz8fXz8fbx8fHz8/P19fb49/j49/n6+vuPxlmWyGOx437h9NDr9eD6/fj////+/v75/vTA5Jv6/fb7/fnL5bDL5q+AxjeDxUCEzTyGxUaGzjyHxkiHzz6J0D+Kxk6K0kCLyE2M00WNy06P00mSz1OUyF+W2FGX1FiY0F6Z02CZ21ac0Wiez2yfz2+f2mOh4GCi4GOi4WKi4mOk12+k3Wul32um1Hin0nun4G6n5Gin5Wmo23Op2Huq1n+q43Cr526s4Hit23+v6XSw34Cw34Gw6nWx4IKy4IOy44Cy63ez146z34az4IWz4YW03Y217nu38H2625e645G74pK83pu98Iq984W+4ZjA4px0tzDA5ZrB8ZDC5p7D55/E947F6KHF+JHH4qvH6qTI46/K5LLL5LN1tzLL5bN1uTDL57DM5bPM6qzM66/N5rTP6LbP6bTR6rfS573T67vT7LrV7r3X68XX7MHX773Y77/Y9rvZ8cHa7cjd88bi88/j8tTk8djk9tHm8trn89vo89zo9N3p9N3p9d7p9tvq9d/s+93s/dzy+erz+O73+vT4/PX5/fT5/fX5/vN1uzB3vTD6/ff6/fh5uTj8/fv9/vr9/vx8wjV/xDmrMRH0AAAAOXRSTlMAAAECAwQJDzk/RUlNU3F0kpSVlpeYmpucnaKjpKWqqqqtu8LExMTEzdTU1NXY4evy8vP+/v7+/v6LaR1mAAABDUlEQVQYGWPgk5QQFxMVERYSFODnYGZgYJA7vMfa2nrXbltbiyOW0mwMDApbuzsbq6sKslJiok0tFYECW9oalqwuyU2NjQoNjLfkYpC3tCxevDE5c/nShBUdfmZSDJw8Rr3zN0Ru2n/AaptlXa0G0FiDrnnrgizLsg95LVqfp8PAwGTQPnutv2VOmp3P9M352iABm5lrfC3T4+w8pkEEDJtmrPJeGBY8y9VmWSFQBYN+c892TzcXp2POlfVFIAGllQGWc2qSIsIz+kMqQALclsalOywXTJjUl+heDhJg1d1pcnBiy+S9+446tmoBBRjY9azMp9rbOzhMmWulycAIFGHhlVFWUVFRVVVXkwUAyhJUc5MwaMIAAAAASUVORK5CYII=',
'Osx': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABrVBMVEUAAAD///////+qqqr///+ZmZn///+qqqqAgID///////+tra339/eAgICoqKjx8fGMjIzm5ubh4eGPj4/g4ODIyMiAgICSkpKLi4vS1tbPz8+Xl5eMjIypqanIyMjW1tZ2dnbR0dGamprFxcV3d3d+fn60tbV3d3dcXFx3d3epqal7fHxxcXF+foCnp6hYWFhyc3Ojo6SMjI5fX196enp+fn6Li4xERERqamqgoKFpaWmFhoeen6A/Pz9QUFCWlpeSk5SUlZWUlZaOjo+Tk5RHR0cuLi5YWFgwMDAeHh40NDQ3Nzc6OjpcXF1rbG0XFxdSU1NVVVVXV1dZWVlbW1tnZ2lwcHABAQEEBAQXFxchISI+P0BISUpaW1xHR0kNDg4qKyszNDU1NTY9Pj8NDQ1cXF4XFxhSU1QSEhIDAwMrKywtLS4uLi4wMDFHSElISEggISE0NDVJSktNTU1FRUVWVlhGRkYEBAVBQUE0NTZQUVJQUVMFBQUqKitWV1lXV1daWlpaWlw+Pj8bGxtcXV9dXV1fX19fYGFgYGBkZGRlZmhpaWlsbGxwcHB2dna844Y9AAAAV3RSTlMAAQIDAwUFBggMDhkeICMkKCgqMDIzPj9ERFBib4CCg4iMjZCcnp+jqamrw83W1tvb3ePl6Ojp6+vs7u7v8PHy9PT09PT3+vr7/f39/f39/v7+/v7+/v50ou7NAAAA30lEQVR4XkXIY3vDYABG4SepMdq2bRSz/capzdm2fvOuDO397Rw0Ly4tz2QAQPbcxuZ2E/STJwfxPhWgG355fRrVAIVb1zeP9UDLfiSwkAcADe8fn7tFxWuEXFRDoer/OgoMTRBCumj8yJwPBo8Zhpk14U856/HI8n0ZUtpZ1udrSzfVneA4roNKjdrwpcMRilb8d8G60+lKnrpWcn9bO+B23w2O8Tzfq4aiNSZJqzn5O4Kw16h06fPZ+VUlUHfo97+VAEb7rSh2UgDd4/U+TBlQY7FMj5gBIGvcarVVfQPVPTG94D0j9QAAAABJRU5ErkJggg==',
'Rhel': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABj1BMVEUAAAD///////8AAAD///////8AAAD///8AAAD///////8AAAD///8AAAD+/v4AAAAAAAAAAAArKysAAAD///////8AAAAAAAAAAAAAAAD///8AAAAAAAAAAAD///8AAAD///8AAAAAAAAAAAAAAAB5eXn+/v5JSUnKysrS0tJ5eXmqqqqxsrL+/v4ZCgknJyeHh4eIiIjo6OgZCAdOTk7t7e3///8GCwwPAAArKyv19fX29vb9/f0EAAD////+/v4AAAAGBgYHAAAJAAAMAAANAQAPAQAVAQFyCQV9fX2pIRzmEQjn5+cBAAAFAAAAAADnEQjvEgn////uEQjyEgnsEQjzEgnxEgljBwPaEAj9EwnwEglHBQJHBQNNBQIBAAB3CQR5CQSHCgWLCgWRCgWTCwadDAWmDAapDAa/DgfKDwjWEAgGAADh4eHiEQjmEQjmEQkKAADoEQgLAQDtEQgMAQDuEQnvEQjvEQkPAQAfAgEuAwEvAwE8BAL1Egn3Egn4Egn6Egk+BAL+/v5CBQJrB0muAAAAT3RSTlMAAAMEBAkYGhsbMTRLUmpvcHeIjLe6vcHCxM3P0NbW3Ojp6u/w9ff5+fn6+vr6+/v7+/v8/Pz9/f39/f39/f7+/v7+/v7+/v7+/v7+/v7+Q8UoNAAAAO5JREFUeF4tiwVPA0EYRL9SXIsWl+LuxfcOd2Z3764quLu788NZNrxkksmbDP2R7vH6GioLs+iffEzNXd4+TqPErUUpVqMOvwgdzMPn1rv5vPsVeufBTaBK/bH2FPvkEUuIG5jIIc+sHYn/HJ3dC/Hxuo4y8s44dzwBbFkisHN8bVIdXs6jb+H97aCwbHEIqgcml64CD7YllNkAVQC940MLYe5YzvIeQAXNrd19Roc5MdzfdQLUUKaUYyuG9I8y1g4gj6hIak4X5cBIT2MquZJrJdOqpY11ZpAiqVwbY/C7KY1cRCrZxX4pWXVuiuq/hs49kg4OyP4AAAAASUVORK5CYII=',
- 'Sabayon': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABvFBMVEUAAAAcUaYdVKwAAAAAAAUABAwWRY4YSZYhZtIhaNYHDx0KCgoFDBcKCgoRMmYSNm0fXL0fXb8AAAAYS5gaTp8fXLwgXsEGBgYFBQUZSpgZTZ4JFSgODg4IEiIOJkwOKVIkW7EnXbQLGzUTExMKGC8LHjwMIkITExMiIiIPEBEPJ00QEhMXOXAaPncOJEgoXbApXbEcHBwwMDAEAgAfHRgQDgo3NC8AAAAHBwcKCgoLCwsJCQkaGhofHx8lJSUwMDA0NDQ4ODiRkZEICQocHBweHh4GBgYHCg8mJiYnJycpKSkrKystLS0uLi4ICAgODg43NzcRERF1dXUUFBSjo6O1tbUbGxsEBAMLGS8MDA0iIiIjIyMkJCQNDQ0NHTYKCQkoKCgPDw8QEBArMDkKCgkRERIREhMxMTEyMjISIz00Njk1NTU2NjYCAgIVFRU5OTo5P0c8PD0+Pj4/QURAQEBHR0dKSkpMTExSUlJiYmJlZWVnZ2cWFhZ2dnZ4eHh8fHx9fX2FhYUXFxeVlZWXl5eYmJiZmZmcnJwZGRmlpaWrq6usrKyvr68KFiq/v7/FxcXY2Nji4uLn5+ft7e0yif9uAAAAN3RSTlMAAAApKSkqKioqg4OEhISEhoa1tra3t7y9vr7S09PT09TU+Pj5+fn5+/v7+/v7+/v7/v7+/v7+70RY/wAAAPpJREFUeF4dyWNjw2AUBeC7dfYyorM6rx1exKltzLZt2/rDa/J8OgBVVlFDX39jcTZoUqCse251a2dvu6ccUtWlanLQ4Vpel+ThlWq1l3wEz58tx4dOt1dMlAJk9A5gMjG75LHwo46hzkwosGOMbejumoRvubC9EOrMviT0E0Us9fvN9dA6zxJCNv6+ECGsb6oNWsgmpZT9/UTUZo3Em6AW34guTL4jiAudiCM1kLcw8/SmHERfT1/eueBiDqR1GK1n9w+K8nglxYxd6QAML4ztXoQuj8YFgWcgqdJp8qzty26vaboCNIxBCshyQDKov0aXr29v1ufq1PwPx5Q7bCoh6eoAAAAASUVORK5CYII=',
+ 'Sabayon': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABvFBMVEUAAAAcUaYdVKwAAAAAAAUABAwWRY4YSZYhZtIhaNYHDx0KCgoFDBcKCgoRMmYSNm0fXL0fXb8AAAAYS5gaTp8fXLwgXsEGBgYFBQUZSpgZTZ4JFSgODg4IEiIOJkwOKVIkW7EnXbQLGzUTExMKGC8LHjwMIkITExMiIiIPEBEPJ00QEhMXOXAaPncOJEgoXbApXbEcHBwwMDAEAgAfHRgQDgo3NC8AAAAHBwcKCgoLCwsJCQkaGhofHx8lJSUwMDA0NDQ4ODiRkZEICQocHBweHh4GBgYHCg8mJiYnJycpKSkrKystLS0uLi4ICAgODg43NzcRERF1dXUUFBSjo6O1tbUbGxsEBAMLGS8MDA0iIiIjIyMkJCQNDQ0NHTYKCQkoKCgPDw8QEBArMDkKCgkRERIREhMxMTEyMjISIz00Njk1NTU2NjYCAgIVFRU5OTo5P0c8PD0+Pj4/QURAQEBHR0dKSkpMTExSUlJiYmJlZWVnZ2cWFhZ2dnZ4eHh8fHx9fX2FhYUXFxeVlZWXl5eYmJiZmZmcnJwZGRmlpaWrq6usrKyvr68KFiq/v7/FxcXY2Nji4uLn5+ft7e0yif9uAAAAN3RSTlMAAAApKSkqKioqg4OEhISEhoa1tra3t7y9vr7S09PT09TU+Pj5+fn5+/v7+/v7+/v7/v7+/v7+70RY/wAAAPlJREFUGBktwQNbQ2EYANC3lt3NtazltvDh+s52tm1z2f7Dfe3pHPiTllfT1V2bnw5xCVDUPruyub271VEMicCUTfQ6XEtritq/XA5MwVvw7NFydOB0e+WhQoCUzh5MxmcWPRZxxNHXmgo5doyxDd3ESPhaCNtzocrsY9BXFPHU7zdXQ+McTwhZ//lAhPC+ySZoIBuUUv77HVGbNTJYB5X4SnZh8hlBQuhYHq6ArPnphxdtP/p88vQqBBcyIKnFaD29vdO0+0tlwNiWDMCJ0ujOeejicEySRA6YUqfJs7qnur2mqRKI4wxKQFUDioGDf7psfXO9PlMHzC/HlDtslvM8zQAAAABJRU5ErkJggg==',
'Slackware': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AcEDi0qZWWDgAAAAx1JREFUOMt9kktoXHUchb/ffc1M7rySSdJMOknFPMRitLgoNKKI8ZHGKkgrjU8SitidimSh2UkXoQmoO1dGQSxJjdvOtqSaqlR0USEGSjVJGxuSmWR6M3fu4/93YX0g4rc9HA6cc4Q7DI+fpzz7PA8++2mxvZAeBZ4xhHtFcJRmXWsWvb36/OLcyxf5B/KHeYHy7DmGx1+YSDjmWTdlobTGMAStQGkNoLXS4tXDq7u7tUcWz49tA8jR8QUuzB5n5NTCV13F9JEo1JJwTLKuzU61QiOMcd0UDb+BncwQK3Rl15eNja3ui/Njq8aF2eMcO/XlBz0H8oO2ZUkum6A13WB99TtyzXlaCi24SaFa+ZFCzsG2DNnfkdbFjsI1APPhk+d6ujqznycdCxFozadYWvyMpx47wa+bPkGksKwUNnsk3TaCGASRXDZh5LpHXPPg4Rcni+3uYBxrtBbQghlscOVKmYHeEm0ZIZ9xyLffw41ND6VAa43SmjiMByzHYtjzwr9arfshxf5jOKlvKZfn8es77N2uks24PPfSFD/9Uvt7AtPKWmEU9d645eHYJo5tcKi/FX/zG+zmQxQH+rANk862DOW5N/hhaY64cJSa5xNFCgDDILZACMKYWAmh73HmzFsMlBQJ06LeiMinE1S3KzRCm5rXIIoUIoKIYCVM36urZFbEoiBLNMIhAE6/NsSB7h6SKZdL8xsUOnpx9j1KbTdARACIowArYe1ergfNT2i0mIbJys0GI6PT3N1/hJvrPxOFdRJNBQIy/FapI4Bpgohgcjuw+jq8jy8tV55MNBWI4ohS802CpizKv8q+FgALZAfYgSyAZtNro1oLaU1VvxCA029Oraxs7u/tKnXiNjn8HyKwur6lI++6vPK4V7IA7u+1Dyu1tr183ddNbkHuXP8/zEIYeFqiLRl6YO/p0bHJdflT/PD9qZa1W+ry99fcvlAlcZwUpuUAglIRYVgnDEIOlna4q0M/NPnuO1/PzMwg/045O/XeibUt5/Xangx6viSVFpK2jtMpvdyWCz+5ryf10clX3/amp6eZmJjgd441URWWJY8BAAAAAElFTkSuQmCC',
- 'Trisquel': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABjFBMVEX///8AAAAAAAAAAAAAADMAAGYAAAAAHFUAGWYAF10AImYAIGAAHloAHGMAKGsAGmYAJmYAJGEAKnUAJ1gAMXYAJnEAJGQAI2EAK28AK3cAGTEAMHgALXEALXgALG0AFUAAI2oAK3EAMngANoYALXMANIAAM4IANIIAL3gANIcANokANoQANYQAOY0ANIYANooAN4kAN40AOY0APZMANIUAOY0AO5AAPZUAPJAAP5MAPpQAQJUAOYsAPpYANoUAPpoAPpUAM4AAQJkAPZIAPJEAQpgAN4cAPpQAPZUAPJEAO4oAOosAOo8AQJoAOYsAO44AQpsAO48AQp0AP5UAQpoARJwAQ58ARaAAQZgAQ54AQ50AQpgARaIARqMARaMARaIAR6QARaIARaEASakARKEAR6MASqsARKEASKcAR6MARqYAR6UATbEATa8ARqUARKAAR6oARqMASKgATK8AR6QATbIATbAASq0AR6cASKgASqwAR6UASKcATa8ASqoASqwAS6wASKoAS60ATbHn4CTpAAAAhHRSTlMAAQIFBQUGCQoLDxAREhMUFBUYGhobHB0eHh8gIiIjJCQkJCYoLC0xMTE0NDo6Oz1BQUNHSUxOVFVVVldaWl5iY2RkZWZoamtsb3FycnR1ent9f4KDhIiJioyNkJGYm5+foqOkpqamqKmqrKytsLKzs7e4uLy8v8TFxcXGx8rO0NXY2eZc4XYcAAAA00lEQVR4XkWN1VoCUQAG/3NWtwh7CTsQJOyk7BaDxuxA6bbrxf32gt25m7kZqDRYxziooDV7+1AalMUavQh2AsEZoWvzigLun+T17/c8QiJZ7qu2QKiNmyZthdcR1/as353jIeU1GxMHo5XHdqPFeX8IaDMdHPYN6dRN7LR4qQewdTa35HWkyh+fbxERAMjwlAWJv3CPSKDQ+H7XvHdkV4Pua3Gtm4sPKIF/WV8dop4VKBw/NU33B3x1JbTt+XwhkJQoqRfWvHOy28uqH8JIdomR/R+s9yR3Cso77AAAAABJRU5ErkJggg==',
- 'Ubuntu': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABKVBMVEX////ojFzplGf1zbnqnHLvs5P10b3yuZv1xKrytZXvtJXys5LysI32waT0n3HxiVHwg0jxhk31kFn0h0zxf0P0hUrveTv2iU3yfkD1hEfyejv5eDLybSX0aR7zZxvyayH6ZxnxZBj4YhH7XAb5WALlUQLeTwHgUAHeTgHfTwD65NzdTQDdTQHdTgD31MfcTgLcTADcTQD////xt5/31Mf54dfmfE/dUAbeVQ/jcUDcTgHeWBnnflHohFvpjGbqkGztnX342Mz53dLgXiP65d399PHdUgrtoYLyu6Xzvaf76eLfXB/rkm/fWhvupojwrpTeVhTgYSfgYynzwa30xbL1ybnngFT31snngljhZS3539XhZzDiajbibDn77OX88Ovrl3X99vTjbz1fisGCAAAAMHRSTlMABgYGBwcHJiorMDA1NXGHjY2Nl5mZmZyfn6O5u8XHzc3X193j9fj4+vr6/f39/f08OUojAAAAx0lEQVR4Xi3HZVbDYBhGwQctWqzFPXiQ+36pu+LubvtfBKcN82/UEhld2vWXxyL6F92gbTPabse8hU/uHMx1SZoyyJWPTwq1Rs7GpYE9+Cg+OJcs1MHvU9y4fnrN31yUm18vMCIPjtw3QMndw4rs8ieVzAAcBlewpe1KM3uaBuD3Dda1BhWXAsi6AFY1a2SqifxZ+rnxWYcJDRkUS3fO1R5vwe+XZgw4D4L3RAJiknoXCVX3WeiUpJ5pIxTvVmg45pl5k4Ot/AGV2iqZBWgJJAAAAABJRU5ErkJggg==',
+ 'Trisquel': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABjFBMVEX///8AAAAAAAAAAAAAADMAAGYAAAAAHFUAGWYAF10AImYAIGAAHloAHGMAKGsAGmYAJmYAJGEAKnUAJ1gAMXYAJnEAJGQAI2EAK28AK3cAGTEAMHgALXEALXgALG0AFUAAI2oAK3EAMngANoYALXMANIAAM4IANIIAL3gANIcANokANoQANYQAOY0ANIYANooAN4kAN40AOY0APZMANIUAOY0AO5AAPZUAPJAAP5MAPpQAQJUAOYsAPpYANoUAPpoAPpUAM4AAQJkAPZIAPJEAQpgAN4cAPpQAPZUAPJEAO4oAOosAOo8AQJoAOYsAO44AQpsAO48AQp0AP5UAQpoARJwAQ58ARaAAQZgAQ54AQ50AQpgARaIARqMARaMARaIAR6QARaIARaEASakARKEAR6MASqsARKEASKcAR6MARqYAR6UATbEATa8ARqUARKAAR6oARqMASKgATK8AR6QATbIATbAASq0AR6cASKgASqwAR6UASKcATa8ASqoASqwAS6wASKoAS60ATbHn4CTpAAAAhHRSTlMAAQIFBQUGCQoLDxAREhMUFBUYGhobHB0eHh8gIiIjJCQkJCYoLC0xMTE0NDo6Oz1BQUNHSUxOVFVVVldaWl5iY2RkZWZoamtsb3FycnR1ent9f4KDhIiJioyNkJGYm5+foqOkpqamqKmqrKytsLKzs7e4uLy8v8TFxcXGx8rO0NXY2eZc4XYcAAAAzUlEQVQYV2NggAMWdX12BiQglJ+SXqIMYqmHxQdJMzAEmXLKuCcyMTBYNWYmNTVYMARzMToqlAsycFYYSBppFFVp6nqa2VkVcDCIFXK7GfrrlWWISKjqpAUwMPDkibIz+Inn5iSHxxQn8AHN9Ig1d7DRzimtrasO5QJZwqhmrMoQ2Rwix8WIcANrTaqAT6AWQoC33t5Flj1CCS7AUenqrMJk7YRQEpXFb6LoawvjMjIJZ8dZ+maKMcHMZWST8or2lmdD2MPILKYlxgziAwCs9yR3GXo0vAAAAABJRU5ErkJggg==',
+ 'Ubuntu': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABKVBMVEX////ojFzplGf1zbnqnHLvs5P10b3yuZv1xKrytZXvtJXys5LysI32waT0n3HxiVHwg0jxhk31kFn0h0zxf0P0hUrveTv2iU3yfkD1hEfyejv5eDLybSX0aR7zZxvyayH6ZxnxZBj4YhH7XAb5WALlUQLeTwHgUAHeTgHfTwD65NzdTQDdTQHdTgD31MfcTgLcTADcTQD////xt5/31Mf54dfmfE/dUAbeVQ/jcUDcTgHeWBnnflHohFvpjGbqkGztnX342Mz53dLgXiP65d399PHdUgrtoYLyu6Xzvaf76eLfXB/rkm/fWhvupojwrpTeVhTgYSfgYynzwa30xbL1ybnngFT31snngljhZS3539XhZzDiajbibDn77OX88Ovrl3X99vTjbz1fisGCAAAAMHRSTlMABgYGBwcHJiorMDA1NXGHjY2Nl5mZmZyfn6O5u8XHzc3X193j9fj4+vr6/f39/f08OUojAAAAxklEQVQYGS3BBULDQABFwY8WLdbiHjzI201Sd8Hd3e5/CJKWGUVio0u77vJYTP/iG7RsxhXpmDe0BDsHc12SpgzkyscnhVojZ8algT34KD5YGxTq4PYpabh+es3fXJSbXy8wIgeO7Dehkr2HFZnLn1SQIXToXcGWtivN7GmayO8brGsNKjZFKGs9WNWsIVP182fp58ZnHSY0ZKBYurO29ngLbr80Y4Bzz3v3fUhI6l2krbrPQqdCPdOGtmS32oYTjjHO5KBCf5XaKpkxFPzRAAAAAElFTkSuQmCC',
'Windows': 'iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAA+pJREFUOE+F0n84FHYcB3CWSsL9ojo/6ik64c6PnTjmSS0limmrpBm2G002y++xzXRz6zE0R4nbw+RnTj/WD4sbanLkkAe55ccYlyNme4SrO9u9d13PI3/saZ+/vs/3831ez+f9eb5aWsuqy2mjRYeNUa7YmtjfTico7jNJ8z0eG24NB9vvnDrvufzpq89Npnr8VjMddNmuRh9rDfp36mFg91oM7qPIc5JdbDJq3An/JfCu7Hl53W2lpS220pP2OuniN299jAYbYizSENIoAgbCTdrTKtxOJVdvGo8psUwKy7Vxe4ez1YEVudGP8YEZzyveInFJ6mZRHHqYazDspw/pJwTIuERM5JIwmUdGdyo9K7/BszGzzg6fXzZHGJ8KvzQqXKOpoIeZLjofWR++BPWyCEnPY4xFGEKWQcLjMjKmr1MwfcMYwmz/Y4KOgNki0V5k1dkjUWCK93Kp2PMFFawos8cm1gZ2GqjLXktL4mbQPHLQ4B9ZDFE5+S356fQlyuJMqzH++HnTo6ui2OO1ko9Ul+4fxfd3d4F7k4YTReqpuFS88bGZUE2QNNDobuIq8Q5CduHb7lFJaTnvnym9ergjMWD/FG8zf+aKS3G9JO5C01Asah6wUXrvALKEDoitMMHhDKrKJdg8RU2s0EB2EWWur8dd7PDPFv6dUC0Gv3kAN36VPRGP/5k5NS6lljWxG0TDiSr1VKhoPwhevRMSqkwRxDObc/DavGtpP6zoi8XOyZfhnyNEvKANBU0P8VPfI/wyNCGXSn7wlEmyA9KrgmOKGth3eDVvPfyywq2dnUEv2R9qG2rLsH7xJXziKnWcI8tlTvEC7Mu8hROlImTU9aKqcwQ1vWOihWFu+sJknmph5CvxQh87c7bNh/NXo03hrMCosyvLmMNgMF7TQL6J1dsZIUVwjKqEO+cajp5vxPN439U/gKBt8PTcYHzL/BgHCyOf4unAISj6mFC2bYC82kB5Ls460NHRUVsDeYSXpGw7UgC7sAtwShDgzdM38W7BbURXtqpqhfmB8sEQuXwoCM/6faGQuGCxyxyKWhIm+PrSD495WL3cT0hhi8Whc3NbAs9KaOyCTvrJ8qkdX19XBeTUDU00+55USFzVU2yHstcaix0mUAjJkJeuRU868Ucmk0lcguiBnMAVxjbbdHV1yeq8+u4Hgo22huSG+iQXp83ftaxW3lsPZcs6KG5T8OwaAfJiPcxlrVRVRhvF02i0F/t5VbHZ7JWDfErKTLnhE3mFPuRFepg/uxqz6TqLv6euGj3ut87t/4ylvre3t3ZehOWWO1zjSFEqMVP4GfGb/DBykJcjmaZOoLsc+hcVY/LaAgcTQAAAAABJRU5ErkJggg==',
'OpenBSD': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAykIPu64pQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAADTklEQVQ4y32RXUxTdxjGn3N6eujoKT3SUkuk3VoBGfVjgFXAsZ7WkipyYXQbuu3CzUXZmGRbssnFEseFkWzgcGzGXky9MWL8TsC4IeFgtK4oAqOnG5vMVl1pCMVWQD7b/y5M6jLdflfvxfPked/nBQA0NDSChqnGVrLuGkES742NhJAdhAKAuk9yyUs5Gry7RQMZAARCWgivpQiPe71P5DUfH0xaqTL7m/iiLkJmphawa+e4SM2PvUyC4yUIBu8CnAQKAK53rCA5OUtQtStVpJ4Gw/FOBddZVKhCfq4MP4n6+at+DUsJm/e0G9JZzYEvI2tHwlEYjDxomkZ+3nG8WroRtHihZVOhVlorDQzh0okhcByDP4ZGcf+X9XAsvY5/RsBa7Kq5H/CqLctKyl/g08S2i6fq8W/MS3P34T9wNDVYSeDX1eTD9xhiLXbtB/Akwmmv6Kr+ICFkLpGhtNSM3qsSstS3oX8lSsmsxS6ZVn3j6PvVVqhUcvC8AtPxVPxwygVKvngN89WOjgVprggGA4eenjB4nsXsTASpC63I0wVTZYPR11FoKRB8Ax54PCFk6BhMTk5CPR3GSbHouGzknr/bYFq9EAvfc9Tu1sLjHcXNKxLuTOTgzOlOe7IHBc/beAXWpWmXlz8a84nhcLQ+ecVzsAEQrMWuMX+f9HZF2YPZ28FVSNfoPWqOzMUmqYMAJm7+/OOzXQFwHGpyEV+vi+yvtxBC9pDmpgJC4tvI3mo9GTitIxvW24nT7ug67HY/3eDs2bbyrVsrY2day70rV6kRfDAHk5lDLJqAmmeRiD9GJDKHvwb74R8G0mkTPjrQTTG122xkTTbwaV2b1H4u16JQKXGr7yG2b8/H1MQ09IsTSEmRwzf4CCwzD+dmE1re8CI7wwi5XNlFf9vaTXX4dWJg4LLl7h05fpNGwNAMWpp9CIVYNO/tRCzGwpDFQaVMQTS2CKY0BWr3GVGWNSXKACDDaA4Mh976pq9f5Sy09GgKlmeAMIBKzUKpU+BFoxJecRhUfAbMxDi4eADfHVmE79v7q575gvvYeVvjZ58LD5mwsKUyX0hnf0feslnQCWD4zxnc6reKisxsfH2oscqcmTmK/+Ow252cna7K52r+Bky6PqmoT5HBAAAAAElFTkSuQmCC',
- 'Gnu': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAywUV5gQrwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAADcElEQVQ4y43Tb0jjBRzH8c9v+7nNMebcUW21Cc78g/wcuhByIScoMRwoTBmFlZCmIJ14axqkgoYIkXIqKIVBEuJNUBEUPRlpqDC3Q2Ex0nTezun2YOaPLXNIv7Vvj7zgiOj1+PPk/eADjuNEuHN6ekqMw+H4IzMz8xChUCjV1NT0JbO7uxtfXFy8NZvNr21tbd0AAEQikY6I0m1tbQbx2NjYZiqV+vn29jY+PDw8xhYWFj45PDzcb25uhlQqfSTief6X0dFRpqKigvF4PPPipaWlY7lcXhCLxXJnZmY+ZTY2NnzX19ePGxsbHw0MDLivrq5mc3Jy2pPJZLVWq/2cdbvdDSzLholoNJ1OMy6Xq0Ymk5HNZktOTU29qMgA8HYqlaKDgwNKp9M0PT09BgAM/iGuqqoimUx2yPP8U5/P9wEAMB0dHRUKheJHiUTyeGhoqAUAnE7nR0qlsjcQCLwjlsvlz+bm5mQWi0VSWlr6bXV1tU6hUMj6+/vfN5lMN0xxcfG1zWZ7SETTSqWSGhoamPHxcajV6s+8Xu9Xou7u7t9VKtW00+mkSCTC6PV6aDQa8Dw/Wl9fP8UAQCgUosvLSyovL2eWl5dRUFBw7Ha7v9vc3By5K3g1EAg8FQSBiIguLi4IgBwA2LtEjuPuJxKJ62AwKFpdXf0eQBIvYVmW/cLlchEAWK1WAADT09NzX6PR/OTz+eKVlZUzKpVqTyqVvsnzfLCkpGSrtrb2t97eXnFeXl5ZKpWyZ2RkPPP7/UUnJyefGI3GU+zt7aU4jotOTk7mAUBfX1+b1Wq9kcvlBIAcDgctLCyQxWKhoqIi6uzs/BoAVlZW3qqpqbllZmdnf1hfX//Q4/HEzWbzX+3t7fcMBgMFg0EYjUYmEolAEAREo1Hk5+fT+fk5Mzg4GD86OpJ0dXXJGQBoaWl5Ra/XP6yrq3tQVlam2N7ehslkAsuySCaTUKvVSCQS2NnZSXAcJxYEQTEyMvKeIAhLDADY7fZ7BoPhm6ysLFpbWzuan5//WKvVvsHzPEWjUSYSiSA3N5d0Oh0TjUaf+/1+S2Nj46/4FwYAr7e2tnbF4/E/iYjC4TCFw+F0LBaj/f19mpiYeID/IAagAyABYLXb7cLZ2Rml02nyer3POY6rwv8hEr34u0IkEk1mZ2cTgGMA7768/RtL5JKsGzrLIgAAAABJRU5ErkJggg==',
+ 'Gnu': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAHC/Qd8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAywUV5gQrwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAAmJLR0QA/4ePzL8AAAHHSURBVBgZZcFPSJNxAAbgt28uanSRapCsy0KK2CWCUYecB5HBolNsglZEsmAwaUvHaIu2YYty1bKGMKmgHIRbGEhURIEY/VHUQ+uwZcxEJSL5Ft+W5ubv7TMkip4HJglrPhHeUmAchWprBK+Kni9pukoAJAOF04j4y6Z9dZtu3sIT32lxXwxeRepwidP0mAF0p5JKPfBsLOMBQs/dJ3pehzcnQ+jc6SfFKlN8KMgEodLiQJWTFOyPY52mUbLmzANY4zro+xG8DVXn8UjOvg2WFSB69Oxo8Hx3F3CM2KsE2wO8LKbp5gWvtYK78zHKooM/eZFu9t0AUOCYIIf4IRfvOrIBKn12vEJyjtDhtx3QfV+dYPgO/qipOfeAgA0qn+UaW+TE9ZQjE0g63uhrpZh2yJyOPXKFe9uWrmTxtmpaSOwCgk5bWUfQywyt3MOOHmB4f9MyBu610ii3fRvlvBgRMrOc4mPmxQs2yPpylABObQ9FJxVyhAqXuEiyyOFiQcnT6TipBWDf6k9fGjwUWZgjF8V7PmVOlPmxkNmNvxhR136muELOclZ85QR73fiHBgZshM1e+UzBdzOmRvxPgmqLlKgl8mjGul/jG/ctzIC/LwAAAABJRU5ErkJggg==',
'CrunchBang': 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAQCAQAAAC45EetAAAA8ElEQVR4XnWOsUpCYQBGz1TIHYu2Qix6g0DEtSeQu/UIISJtUS8gJq61F1wcdMohcBDxKUR8hsz1xA/y44/cs3znbB+RJ0Skl3pSkeFQbUs79VAPzrwPFRmN1Ja0Ug/16I93+1oi4lKte+zMXv32WuoAm43lXMrqzbFncgWw21lORf4+/PREKpAhYqZuPXZ+T/3yXbZEajV1JavUQ104sRcq0myqc5mnHurWqc/7yhExVwuPncl+C4Bu13L60ueAwcByOtLhgAIRCzU38fRGTmSxUBvSSD3Ui1NvQkXWa7Uq1dRD9R17HiqyRUSy1NP6B7e1Yu2GtlUKAAAAAElFTkSuQmCC',
'Yuno': 'iVBORw0KGgoAAAANSUhEUgAAABgAAAAPCAYAAAD+pA/bAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAABDtJREFUOE+FlHtMm1UYxrtsi8aEgCb+oTFmZur+WNS5RaPERU10C2qGaBgb6hgwLwMmHTIKlIKlQIHSQrmU24BSSmnpBVooUmihtEC5yKWDjVu5uOkcEca4lG5E93j6EQmELX7Jky/fOed9fu973vMdGu0xT3Cgz57yXMZLDdXcy821PFWLKmuA6HqLMqtLX5POl4iYb2ukWW8IOOFe/qfe3/M4n0eOjwyZD8//bldODOk37N1yDJgl+LVdjEGLFKO9KkzZm8hbje7mIrTXZ7sMtTydrJh15H8hHW11XvN/jGS7VudcD5w34ZZzeQYb67fwYO03LN4exo1+LWzNxbA05O5QuzbHqRYn+++CHDx4YK9WLfaedfQzV5em54g5Zbi8OIml+VFMDLWQ7GXoaSmFWZsDZVGCO2u0EbkhHTrhFqi9PmelSsQ8tAtSVch60dpUeGe4kxgZxegzVkBzlQ2NKBG2+iJIMqMok9r8OLRIMqApToSqmAWTmk9B2+o2YW79oshU7ABcuvAFrVGWXkVKpBYoSaBSxIS2mINpiwbjZiUMZRloVfJQyaXDKObBpimBScpHFe8KmmXpaKhK3arGrBVuVBclHN2CiPNin1OVs1tVJYlQlyZBxA6DviQVo6ZaOKd7sTplw53BVugruBBzfsRslw7rZPxaczWutSpQV/gzJPxo1JexyfaxKBBpuiEx+tw+CpKdEvGWTprGlhcwqbIzL5/DYKMYndpK3L1hxf3ZfkrzwybUZjPhnOqmvlcmutFF1jis9QSShOrcWNSXJ1MA0ou/NZWc8Ddfe4VGO3bk0JON1dyMMlK+gmxNrZCFhZF2Kng7YNO0awt4b7wLNp2EqtAsF6ImP56SG0B6siovTYpIjg15gapCVhAfJRUyIBFEo6k8AyuTtkcC/qvG/XbDexulWJvqgYH0o0nKhVHFJ40XwFQnWM5OCX+XMg86c3KvVMSMapCmPpSTIygTxGKZZOcOXhrr3Mp4uzkFuG6B3ajE3TELDDU8qEmsmvRATxquKkxAnSTFjwKEfv3JU9JC5unG6rQ1bTkbQ4Yq/DVgxOqwBWt2K9Yne3ZCZvrgHO2k5paHzOhSiVCZSkdNTgzy40JRlPgDhDHBCxUZdCs91G8fLeK87zOl6XSOICZYXMGNhDqX9fDP/mbK2DXVi/szm03eLpejl5pzOfqwOt4JBT8OeYwQt/4R/BR0OzXiLCM5LOCji/4nXt46rpywgG+zor5RxgSdupBzJdglSY+5ZZbl3XNY6mbn7W0Lcx06zBg1WBjtcC6OmG+OmRTrFrnIUZESZeVeCpwh8TpiPsQ47/tloM97T+/6m8mg55mT3tStyL54mhlwwtszNvjzD8/6HH8i7PvvPPRioZdRWuDBZUR6pEWG7I8P9Xs1Jsj36MfvvO5J/+rTw58dP7afJPfBgeef3XGz/gskFVpJc4HwGwAAAABJRU5ErkJggg=='
}
@@ -16372,7 +16436,7 @@
},
advanced: function(section) {
var archBoards, boardID, boardOptions, boardSelect, boards, data, event, files, input, inputs, item, items, name, o, row, rows, ta, table, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4;
- section.innerHTML = "Archiver 404 Redirect is disabled.
Thread redirection Post fetching File redirection
Disabled selections indicate that only one archive is available for that board and redirection type. Custom Board Navigation
New lines will be converted into spaces. In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
Board link: g
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:\"Install Gentoo\"
Index-only link: g-index
Catalog-only link: g-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: g-index-text:\"Technology Index\"
Full board list toggle: toggle-all
[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"] will give you[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy] if you are on /g/.
Time Formatting is disabled. :
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled. :
File Info Formatting is disabled. :
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas One item per line. Items will be added in the relevant input's auto-completion list. Password items will always be used, since there is no password input. Lines starting with a # will be ignored.
You can use these settings with each item, separate them with semicolons:Possible items are: name, email, subject and password. Wrap values of items with quotes, like this: email:\"sage\". Force values as defaults with the always keyword, for example: email:\"sage\";always. Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always. Unread Favicon is disabled. ferongr xat- Mayhem 4chanJS Original Emoji is disabled. Sage Icon: 4chan SS appchan
Thread Updater is disabled. Interval:
Custom CSSApply CSS
";
+ section.innerHTML = "Archiver 404 Redirect is disabled.
Thread redirection Post fetching File redirection
Disabled selections indicate that only one archive is available for that board and redirection type. Custom Board Navigation
New lines will be converted into spaces. In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
Board link: g
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:\"Install Gentoo\"
Index-only link: g-index
Catalog-only link: g-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: g-index-text:\"Technology Index\"
Full board list toggle: toggle-all
[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"] will give you[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy] if you are on /g/.
Time Formatting is disabled. :
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled. :
File Info Formatting is disabled. :
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas One item per line. Items will be added in the relevant input's auto-completion list. Password items will always be used, since there is no password input. Lines starting with a # will be ignored.
You can use these settings with each item, separate them with semicolons:Possible items are: name, email, subject and password. Wrap values of items with quotes, like this: email:\"sage\". Force values as defaults with the always keyword, for example: email:\"sage\";always. Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always. Unread Favicon is disabled. ferongr xat- Mayhem 4chanJS Original Metro Emoji is disabled. Sage Icon: 4chan SS appchan
Thread Updater is disabled. Interval:
Custom CSSApply CSS
";
items = {};
inputs = {};
_ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss'];
diff --git a/builds/xpi/4chanx.xpi b/builds/xpi/4chanx.xpi
new file mode 100644
index 000000000..4e84eb064
Binary files /dev/null and b/builds/xpi/4chanx.xpi differ
diff --git a/builds/xpi/data/4chan-X.user.js b/builds/xpi/data/4chan-X.user.js
new file mode 100644
index 000000000..5456ed885
--- /dev/null
+++ b/builds/xpi/data/4chan-X.user.js
@@ -0,0 +1,12838 @@
+// Generated by CoffeeScript
+// ==UserScript==
+// @name 4chan X
+// @version 1.3.7
+// @minGMVer 1.13
+// @minFFVer 26
+// @namespace 4chan-X
+// @description Cross-browser userscript for maximum lurking on 4chan.
+// @license MIT; https://github.com/Spittie/4chan-x/blob/master/LICENSE
+// @match *://boards.4chan.org/*
+// @match *://sys.4chan.org/*
+// @match *://a.4cdn.org/*
+// @match *://i.4cdn.org/*
+// @grant GM_getValue
+// @grant GM_setValue
+// @grant GM_deleteValue
+// @grant GM_openInTab
+// @grant GM_xmlhttpRequest
+// @run-at document-start
+// @updateURL https://github.com/Spittie/4chan-x/raw/stable/builds/4chan-X.meta.js
+// @downloadURL https://github.com/Spittie/4chan-x/raw/stable/builds/4chan-X.user.js
+// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAF5JREFUeNrtkTESABAQxPD/R6tsE2dUGYUtFJvLDKf93KevHJAjpBorAQWSBIKqFASC4G0pCAkm4GfaEvgYXl0T6HBaE97f0vmnfYHbZOMLZCx9ISdKWwjOWZSC8GYm4SUGwfYgqI4AAAAASUVORK5CYII=
+// ==/UserScript==
+
+/*
+* 4chan X - Version 1.3.7 - 2014-02-15
+*
+* Licensed under the MIT license.
+* https://github.com/Spittie/4chan-x/blob/master/LICENSE
+*
+* Appchan X Copyright © 2013-2013 Zixaphir
+* http://zixaphir.github.io/appchan-x/
+* 4chan x Copyright © 2009-2011 James Campos
+* https://github.com/aeosynth/4chan-x
+* 4chan x Copyright © 2012-2014 Nicolas Stepien
+* https://4chan-x.just-believe.in/
+* 4chan x Copyright © 2013-2014 Jordan Bates
+* http://seaweedchan.github.io/4chan-x/
+* 4chan x Copyright © 2012-2014 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
+*
+* 4chan/4chan-JS (https://github.com/4chan/4chan-JS)
+* Copyright (c) 2012-2013, 4chan LLC
+* All rights reserved.
+*
+* license: https://github.com/4chan/4chan-JS/blob/master/LICENSE
+*/
+'use strict';
+
+(function() {
+ var $, $$, Anonymize, ArchiveLink, AutoGIF, Banner, Board, Build, Callbacks, CatalogLinks, Clone, Conf, Config, CustomCSS, DataBoard, DeleteLink, Dice, DownloadLink, Emoji, ExpandComment, ExpandThread, FappeTyme, Favicon, FileInfo, Filter, Fourchan, Gallery, Get, Header, IDColor, ImageExpand, ImageHover, ImageLoader, Index, InfiniScroll, Keybinds, Linkify, Main, Menu, Nav, Notice, PSAHiding, Polyfill, Post, PostHiding, QR, QuoteBacklink, QuoteCT, QuoteInline, QuoteOP, QuotePreview, QuoteStrikeThrough, QuoteThreading, QuoteYou, Quotify, RandomAccessList, Recursive, Redirect, RelativeDates, RemoveSpoilers, Report, ReportLink, RevealSpoilers, Sauce, Settings, Thread, ThreadExcerpt, ThreadHiding, ThreadStats, ThreadUpdater, ThreadWatcher, Time, UI, Unread, c, d, doc, g,
+ __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
+ __slice = [].slice,
+ __hasProp = {}.hasOwnProperty,
+ __extends = 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; },
+ __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
+
+ Array.prototype.indexOf = function(val) {
+ var i;
+ i = this.length;
+ while (i--) {
+ if (this[i] === val) {
+ return i;
+ }
+ }
+ return i;
+ };
+
+ __indexOf = [].indexOf;
+
+ Config = {
+ main: {
+ 'Miscellaneous': {
+ 'Catalog Links': [true, 'Add toggle link in header menu to turn Navigation links into links to each board\'s catalog.'],
+ 'External Catalog': [false, 'Link to external catalog instead of the internal one.'],
+ 'QR Shortcut': [false, 'Adds a small [QR] link in the header.'],
+ 'Announcement Hiding': [true, 'Add button to hide 4chan announcements.'],
+ 'Desktop Notifications': [false, 'Enables desktop notifications across various 4chan X features.'],
+ '404 Redirect': [true, 'Redirect dead threads and images.'],
+ '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.'],
+ '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.'],
+ 'Show Dice Roll': [true, 'Show dice that were entered into the email field.'],
+ 'Custom Board Titles': [true, 'Allow editing of the board title and subtitle by ctrl+clicking them'],
+ 'Persistent Custom Board Titles': [false, 'Force custom board titles to be persistent, even if moot updates the board titles.'],
+ 'Show Updated Notifications': [true, 'Show notifications when 4chan X is successfully updated.'],
+ 'Emoji': [false, 'Adds icons next to names for different emails'],
+ 'Color User IDs': [false, '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.']
+ },
+ 'Linkification': {
+ 'Linkify': [true, 'Convert text into links where applicable.'],
+ 'Embedding': [true, 'Embed supported services.'],
+ 'Auto-embed': [false, 'Auto-embed Linkify Embeds.'],
+ 'Link Title': [true, 'Replace the link of a supported site with its actual title. Currently Supported: YouTube, Vimeo, SoundCloud, and Github gists']
+ },
+ 'Filtering': {
+ 'Anonymize': [false, 'Make everyone Anonymous.'],
+ 'Filter': [true, 'Self-moderation placebo.'],
+ 'Recursive Hiding': [true, 'Hide replies of hidden posts, recursively.'],
+ 'Thread Hiding Buttons': [false, 'Add buttons to hide entire threads.'],
+ 'Reply Hiding Buttons': [false, 'Add buttons to hide single replies.'],
+ 'Filtered Backlinks': [true, 'When enabled, shows backlinks to filtered posts with a line-through decoration. Otherwise, hides the backlinks.'],
+ 'Stubs': [true, 'Show stubs of hidden threads / replies.']
+ },
+ 'Images': {
+ 'Image Expansion': [true, 'Expand images.'],
+ 'Image Hover': [true, 'Show full image on mouseover.'],
+ 'Gallery': [true, 'Adds a simple and cute image gallery.'],
+ 'Sauce': [true, 'Add sauce links to images.'],
+ 'Reveal Spoiler Thumbnails': [false, 'Replace spoiler thumbnails with the original image.'],
+ 'Replace GIF': [false, 'Replace thumbnail of gifs with its actual image.'],
+ 'Replace PNG': [false, 'Replace pngs.'],
+ 'Replace JPG': [false, 'Replace jpgs.'],
+ 'Image Prefetching': [false, 'Preload images'],
+ 'Fappe Tyme': [false, 'Hide posts without images. *hint* *hint*'],
+ 'Werk Tyme': [false, 'Hide all post images.']
+ },
+ 'Menu': {
+ 'Menu': [true, 'Add a drop-down menu to posts.'],
+ 'Report Link': [true, 'Add a report link to the menu.'],
+ 'Thread Hiding Link': [true, 'Add a link to hide entire threads.'],
+ 'Reply Hiding Link': [true, 'Add a link to hide single replies.'],
+ 'Delete Link': [true, 'Add post and image deletion links to the menu.'],
+ 'Archive Link': [true, 'Add an archive link to the menu.']
+ },
+ 'Monitoring': {
+ 'Thread Updater': [true, 'Fetch and insert new replies. Has more options in its own dialog.'],
+ 'Unread Count': [true, 'Show the unread posts count in the tab title.'],
+ 'Hide Unread Count at (0)': [false, 'Hide the unread posts count in the tab title when it reaches 0.'],
+ '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.'],
+ 'Scroll to Last Read Post': [true, 'Scroll back to the last read post when reopening a thread.'],
+ 'Thread Excerpt': [true, 'Show an excerpt of the thread in the tab title.'],
+ 'Thread Stats': [true, 'Display reply and image count.'],
+ 'Page Count in Stats': [false, 'Display the page count in the thread stats as well.'],
+ '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.'],
+ 'Toggleable Thread Watcher': [true, 'Adds a shortcut for the thread watcher, hides the watcher by default, and makes it scroll with the page.']
+ },
+ 'Posting': {
+ 'Quick Reply': [true, 'All-in-one form to reply, create threads, automate dumping and more.'],
+ 'Persistent QR': [true, 'The Quick reply won\'t disappear after posting.'],
+ 'Auto Hide QR': [true, 'Automatically hide the quick reply when posting.'],
+ 'Open Post in New Tab': [true, 'Open new threads or replies to a thread from the index in a new tab.'],
+ 'Remember Subject': [false, 'Remember the subject field, instead of resetting after posting.'],
+ 'Remember QR Size': [false, 'Remember the size of the Quick reply.'],
+ 'Remember Spoiler': [false, 'Remember the spoiler state, instead of resetting after posting.'],
+ 'Hide Original Post Form': [true, 'Hide the normal post form.'],
+ 'Cooldown': [true, 'Indicate the remaining time before posting again.'],
+ 'Cooldown Prediction': [true, 'Decrease the cooldown time by taking into account upload speed. Disable it if it\'s inaccurate for you.'],
+ 'Posting Success Notifications': [true, 'Show notifications on successful post creation or file uploading.'],
+ 'Captcha Warning Notifications': [true, 'When disabled, shows a red border on the CAPTCHA input until a key is pressed instead of a notification.'],
+ 'Auto-load captcha': [false, 'Automatically load the captcha when you open a thread']
+ },
+ 'Quote Links': {
+ 'Quote Backlinks': [true, 'Add quote backlinks.'],
+ 'OP Backlinks': [true, 'Add backlinks to the OP.'],
+ 'Quote Inlining': [true, 'Inline quoted post on click.'],
+ 'Quote Hash Navigation': [false, 'Include an extra link after quotes for autoscrolling to quoted posts.'],
+ 'Forward Hiding': [true, 'Hide original posts of inlined backlinks.'],
+ 'Quote Previewing': [true, 'Show quoted post on hover.'],
+ 'Quote Highlighting': [true, 'Highlight the previewed post.'],
+ 'Resurrect Quotes': [true, 'Link dead quotes to the archives.'],
+ 'Mark Quotes of You': [true, 'Add \'(You)\' to quotes linking to your posts.'],
+ 'Quoted Title': [false, 'Change the page title to reflect you\'ve been quoted.'],
+ 'Highlight Posts Quoting You': [false, 'Highlights any posts that contain a quote to your post.'],
+ 'Highlight Own Posts': [false, 'Highlights own posts if Mark Quotes of You is enabled.'],
+ 'Mark OP Quotes': [true, 'Add \'(OP)\' to OP quotes.'],
+ 'Mark Cross-thread Quotes': [true, 'Add \'(Cross-thread)\' to cross-threads quotes.'],
+ 'Quote Threading': [true, 'Thread conversations']
+ }
+ },
+ imageExpansion: {
+ 'Fit width': [false, ''],
+ 'Fit height': [false, ''],
+ 'Expand spoilers': [true, 'Expand all images along with spoilers.'],
+ '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]
+ },
+ threadWatcher: {
+ 'Current Board': [false, 'Only show watched threads from the current board.'],
+ 'Auto Watch': [true, 'Automatically watch threads you start.'],
+ 'Auto Watch Reply': [false, 'Automatically watch threads you reply to.'],
+ 'Auto Prune': [false, 'Automatically prune 404\'d threads.']
+ },
+ filter: {
+ 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 moot:\n#/Admin$/;highlight:moot;op:yes",
+ email: "",
+ subject: "# Filter Generals on /v/:\n#/general/i;boards:v;op:only",
+ comment: "# Filter Stallman copypasta on /g/:\n#/what you\'re refer+ing to as linux/i;boards:g",
+ 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=%TURL\nhttp://iqdb.org/?url=%TURL\n#//tineye.com/search?url=%TURL\n#http://saucenao.com/search.php?url=%TURL\n#http://3d.iqdb.org/?url=%TURL\n#http://regex.info/exif.cgi?imgurl=%URL\n# uploaders:\n#http://imgur.com/upload?url=%URL;text:Upload to imgur\n#http://ompldr.org/upload?url1=%URL;text:Upload to ompldr\n# \"View Same\" in archives:\n#//archive.foolz.us/_/search/image/%MD5/;text:View same on foolz\n#//archive.foolz.us/%board/search/image/%MD5/;text:View same on foolz /%board/\n#//archive.installgentoo.net/%board/image/%MD5;text:View same on installgentoo /%board/",
+ FappeT: {
+ fappe: false,
+ werk: false
+ },
+ 'sageEmoji': '4chan SS',
+ 'emojiPos': 'before',
+ 'Custom CSS': false,
+ Index: {
+ 'Index Mode': 'paged',
+ 'Index Sort': 'bump',
+ 'Show Replies': true,
+ '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/seaweedchan/4chan-x/wiki/Frequently-Asked-Questions\"]",
+ QR: {
+ 'QR.personas': "#email:\"sage\";boards:jp;always"
+ },
+ time: '%m/%d/%y(%a)%H:%M:%S',
+ backlink: '>>%id',
+ fileInfo: '%L (%p%s, %r)',
+ favicon: 'ferongr',
+ usercss: '',
+ 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': ['i', 'Open QR without post number inserted.'],
+ 'Open QR': ['Shift+i', 'Open QR with post number inserted.'],
+ 'Open settings': ['Alt+o', 'Open Settings.'],
+ 'Close': ['Esc', 'Close Settings, Notifications or QR.'],
+ '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.'],
+ 'Toggle sage': ['Alt+s', 'Toggle sage in email field'],
+ 'Submit QR': ['Ctrl+Enter', 'Submit post.'],
+ 'Watch': ['w', 'Watch thread.'],
+ 'Update': ['r', 'Update the thread now.'],
+ 'Expand image': ['Shift+e', 'Expand selected image.'],
+ 'Expand images': ['e', 'Expand all images.'],
+ 'Open Gallery': ['g', 'Opens the gallery.'],
+ 'fappeTyme': ['f', 'Fappe Tyme.'],
+ 'werkTyme': ['Shift+w', 'Werk Tyme'],
+ 'Front page': ['0', 'Jump to page 0.'],
+ 'Open front page': ['Shift+0', 'Open page 0 in a new tab.'],
+ 'Next page': ['Shift+Right', 'Jump to the next page.'],
+ 'Previous page': ['Shift+Left', 'Jump to the previous page.'],
+ 'Open catalog': ['Shift+c', 'Open the catalog of the current board'],
+ 'Search form': ['Ctrl+Alt+s', 'Focus the search field on the board index.'],
+ 'Next thread': ['Shift+Down', 'See next thread.'],
+ 'Previous thread': ['Shift+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.'],
+ '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
+ }
+ };
+
+ Conf = {};
+
+ c = console;
+
+ d = document;
+
+ doc = d.documentElement;
+
+ g = {
+ VERSION: '1.3.7',
+ NAMESPACE: '4chan X.',
+ boards: {},
+ threads: {},
+ posts: {}
+ };
+
+ $ = function(selector, root) {
+ if (root == null) {
+ root = d.body;
+ }
+ return root.querySelector(selector);
+ };
+
+ $.extend = function(obj, prop) {
+ var key, val;
+ for (key in prop) {
+ val = prop[key];
+ if (prop.hasOwnProperty(key)) {
+ obj[key] = val;
+ }
+ }
+ };
+
+ $.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 lastModified;
+ lastModified = {};
+ return function(url, options, extra) {
+ var form, r, sync, type, upCallbacks, whenModified;
+ if (extra == null) {
+ extra = {};
+ }
+ type = extra.type, whenModified = extra.whenModified, upCallbacks = extra.upCallbacks, form = extra.form, sync = extra.sync;
+ r = new XMLHttpRequest();
+ type || (type = form && 'post' || 'get');
+ r.open(type, url, !sync);
+ if (whenModified) {
+ if (url in lastModified) {
+ r.setRequestHeader('If-Modified-Since', lastModified[url]);
+ }
+ $.on(r, 'load', function() {
+ return lastModified[url] = r.getResponseHeader('Last-Modified');
+ });
+ }
+ $.extend(r, options);
+ $.extend(r.upload, upCallbacks);
+ r.send(form);
+ return r;
+ };
+ })();
+
+ $.cache = (function() {
+ var reqs;
+ reqs = {};
+ return function(url, cb, options) {
+ var err, req, rm;
+ if (req = reqs[url]) {
+ if (req.readyState === 4) {
+ cb.call(req, req.evt);
+ } else {
+ req.callbacks.push(cb);
+ }
+ return;
+ }
+ rm = function() {
+ return delete reqs[url];
+ };
+ try {
+ req = $.ajax(url, options);
+ } catch (_error) {
+ err = _error;
+ return;
+ }
+ $.on(req, 'load', function(e) {
+ var _i, _len, _ref;
+ _ref = this.callbacks;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ cb = _ref[_i];
+ cb.call(this, e);
+ }
+ this.evt = e;
+ return delete this.callbacks;
+ });
+ $.on(req, 'abort error', rm);
+ req.callbacks = [cb];
+ return reqs[url] = req;
+ };
+ })();
+
+ $.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);
+ }
+ };
+
+ $.addStyle = function(css, id) {
+ var style;
+ style = $.el('style', {
+ id: id,
+ textContent: css
+ });
+ $.asap((function() {
+ return d.head;
+ }), 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(el, className) {
+ return el.classList.add(className);
+ };
+
+ $.rmClass = function(el, className) {
+ return 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() {
+ if ('remove' in Element.prototype) {
+ return function(el) {
+ return el.remove();
+ };
+ } else {
+ return function(el) {
+ var _ref;
+ return (_ref = el.parentNode) != null ? _ref.removeChild(el) : void 0;
+ };
+ }
+ })();
+
+ $.rmAll = function(root) {
+ var node, _i, _len, _ref;
+ _ref = __slice.call(root.childNodes);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ node = _ref[_i];
+ root.removeChild(node);
+ }
+ };
+
+ $.tn = function(s) {
+ return d.createTextNode(s);
+ };
+
+ $.frag = function() {
+ return d.createDocumentFragment();
+ };
+
+ $.nodes = function(nodes) {
+ var frag, node, _i, _len;
+ if (!(nodes instanceof Array)) {
+ return nodes;
+ }
+ frag = $.frag();
+ for (_i = 0, _len = nodes.length; _i < _len; _i++) {
+ node = nodes[_i];
+ 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) {
+ var el;
+ el = d.createElement(tag);
+ if (properties) {
+ $.extend(el, properties);
+ }
+ return el;
+ };
+
+ $.on = function(el, events, handler) {
+ var event, _i, _len, _ref;
+ _ref = events.split(' ');
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ event = _ref[_i];
+ el.addEventListener(event, handler, false);
+ }
+ };
+
+ $.off = function(el, events, handler) {
+ var event, _i, _len, _ref;
+ _ref = events.split(' ');
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ event = _ref[_i];
+ el.removeEventListener(event, handler, false);
+ }
+ };
+
+ $.event = function(event, detail, root) {
+ if (root == null) {
+ root = d;
+ }
+ return root.dispatchEvent(new CustomEvent(event, {
+ bubbles: true,
+ detail: detail
+ }));
+ };
+
+ $.open = GM_openInTab;
+
+ $.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);
+ };
+
+ $.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);
+ };
+
+ $.item = function(key, val) {
+ var item;
+ item = {};
+ item[key] = val;
+ return item;
+ };
+
+ $.syncing = {};
+
+ $.sync = (function() {
+ $.on(window, 'storage', function(_arg) {
+ var cb, key, newValue;
+ key = _arg.key, newValue = _arg.newValue;
+ if (cb = $.syncing[key]) {
+ return cb(JSON.parse(newValue), key);
+ }
+ });
+ return function(key, cb) {
+ return $.syncing[g.NAMESPACE + key] = cb;
+ };
+ })();
+
+ $["delete"] = function(keys) {
+ var key, _i, _len;
+ if (!(keys instanceof Array)) {
+ keys = [keys];
+ }
+ for (_i = 0, _len = keys.length; _i < _len; _i++) {
+ key = keys[_i];
+ key = g.NAMESPACE + key;
+ localStorage.removeItem(key);
+ GM_deleteValue(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 = GM_getValue(g.NAMESPACE + key)) {
+ items[key] = JSON.parse(val);
+ }
+ }
+ return cb(items);
+ });
+ };
+
+ $.set = (function() {
+ var set;
+ set = function(key, val) {
+ key = g.NAMESPACE + key;
+ val = JSON.stringify(val);
+ if (key in $.syncing) {
+ localStorage.setItem(key, val);
+ }
+ return GM_setValue(key, val);
+ };
+ return function(keys, val) {
+ var key;
+ if (typeof keys === 'string') {
+ set(keys, val);
+ return;
+ }
+ for (key in keys) {
+ val = keys[key];
+ set(key, val);
+ }
+ };
+ })();
+
+ $$ = function(selector, root) {
+ if (root == null) {
+ root = d.body;
+ }
+ return __slice.call(root.querySelectorAll(selector));
+ };
+
+ Callbacks = (function() {
+ function Callbacks() {}
+
+ Callbacks.prototype.push = function(_arg) {
+ var cb, name;
+ name = _arg.name, cb = _arg.cb;
+ return this[name] = cb;
+ };
+
+ Callbacks.prototype.clean = function() {
+ var name;
+ for (name in this) {
+ if (this.hasOwnProperty(name)) {
+ this.rm(name);
+ }
+ }
+ };
+
+ Callbacks.prototype.rm = function(name) {
+ return delete this[name];
+ };
+
+ Callbacks.prototype.execute = function(node) {
+ var err, errors, name;
+ for (name in this) {
+ if (this.hasOwnProperty(name)) {
+ try {
+ this[name].call(node);
+ } catch (_error) {
+ err = _error;
+ if (!errors) {
+ errors = [];
+ }
+ errors.push({
+ message: ['"', name, '" crashed on node No.', node, ' (', node.board, ').'].join(''),
+ error: err
+ });
+ }
+ }
+ }
+ if (errors) {
+ return Main.handleErrors(errors);
+ }
+ };
+
+ return Callbacks;
+
+ })();
+
+ Board = (function() {
+ Board.prototype.toString = function() {
+ return this.ID;
+ };
+
+ function Board(ID) {
+ this.ID = ID;
+ this.threads = {};
+ this.posts = {};
+ g.boards[this] = this;
+ }
+
+ return Board;
+
+ })();
+
+ Thread = (function() {
+ Thread.callbacks = new Callbacks();
+
+ Thread.prototype.toString = function() {
+ return this.ID;
+ };
+
+ function Thread(ID, board) {
+ this.ID = ID;
+ this.board = board;
+ this.fullID = "" + this.board + "." + this.ID;
+ this.posts = {};
+ this.isSticky = false;
+ this.isClosed = false;
+ this.postLimit = false;
+ this.fileLimit = false;
+ g.threads[this.fullID] = board.threads[this] = this;
+ }
+
+ Thread.prototype.setPage = function(pageNum) {
+ var icon, key, _i, _len, _ref;
+ icon = $('.page-num', this.OP.nodes.post);
+ _ref = ['title', 'textContent'];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ key = _ref[_i];
+ icon[key] = icon[key].replace(/\d+/, pageNum);
+ }
+ };
+
+ Thread.prototype.setStatus = function(type, status) {
+ var icon, name, root, typeLC;
+ name = "is" + type;
+ if (this[name] === status) {
+ return;
+ }
+ this[name] = status;
+ if (!this.OP) {
+ return;
+ }
+ typeLC = type.toLowerCase();
+ if (!status) {
+ $.rm($("." + typeLC + "Icon", this.OP.nodes.info));
+ return;
+ }
+ icon = $.el('img', {
+ src: "//s.4cdn.org/image/" + typeLC + (window.devicePixelRatio >= 2 ? '@2x' : '') + ".gif",
+ alt: type,
+ title: type,
+ className: "" + typeLC + "Icon"
+ });
+ root = type === 'Closed' && this.isSticky ? $('.stickyIcon', this.OP.nodes.info) : g.VIEW === 'index' ? $('.page-num', this.OP.nodes.info) : $('[title="Quote this post"]', this.OP.nodes.info);
+ return $.after(root, [$.tn(' '), icon]);
+ };
+
+ Thread.prototype.kill = function() {
+ this.isDead = true;
+ return this.timeOfDeath = Date.now();
+ };
+
+ Thread.prototype.collect = function() {
+ var post, postID, _i, _len, _ref;
+ _ref = this.posts;
+ for (post = _i = 0, _len = _ref.length; _i < _len; post = ++_i) {
+ postID = _ref[post];
+ post.collect();
+ }
+ delete g.threads[this.fullID];
+ return delete this.board.threads[this];
+ };
+
+ return Thread;
+
+ })();
+
+ Post = (function() {
+ Post.callbacks = new Callbacks();
+
+ Post.prototype.toString = function() {
+ return this.ID;
+ };
+
+ function Post(root, thread, board, that) {
+ var capcode, date, email, flag, info, name, post, subject, tripcode, uniqueID;
+ this.thread = thread;
+ this.board = board;
+ if (that == null) {
+ that = {};
+ }
+ this.ID = +root.id.slice(2);
+ this.fullID = "" + this.board + "." + this.ID;
+ if (that.isOriginalMarkup) {
+ this.cleanup(root);
+ }
+ post = $('.post', root);
+ info = $('.postInfo', post);
+ this.nodes = {
+ root: root,
+ post: post,
+ info: info,
+ comment: $('.postMessage', post),
+ links: [],
+ quotelinks: [],
+ backlinks: info.getElementsByClassName('backlink')
+ };
+ if (!(this.isReply = $.hasClass(post, 'reply'))) {
+ this.thread.OP = this;
+ this.thread.isSticky = !!$('.stickyIcon', info);
+ this.thread.isClosed = !!$('.closedIcon', info);
+ }
+ this.info = {};
+ if (subject = $('.subject', info)) {
+ this.nodes.subject = subject;
+ this.info.subject = subject.textContent;
+ }
+ 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);
+ }
+ if (Conf['Quick Reply']) {
+ this.info.yours = QR.db.get({
+ boardID: this.board,
+ threadID: this.thread,
+ postID: this.ID
+ });
+ }
+ this.parseComment();
+ this.parseQuotes();
+ this.parseFile(that);
+ this.clones = [];
+ g.posts[this.fullID] = thread.posts[this] = board.posts[this] = this;
+ if (that.isArchived) {
+ this.kill();
+ }
+ }
+
+ Post.prototype.parseComment = function() {
+ var bq, i, node, nodes, text;
+ this.nodes.comment.normalize();
+ bq = this.nodes.comment.cloneNode(true);
+ nodes = $$('.abbr, .exif, b', bq);
+ i = 0;
+ while (node = nodes[i++]) {
+ $.rm(node);
+ }
+ text = "";
+ nodes = $.X('.//br|.//text()', bq);
+ i = 0;
+ while (node = nodes.snapshotItem(i++)) {
+ text += node.data || '\n';
+ }
+ return this.info.comment = text.trim().replace(/\s+$/gm, '');
+ };
+
+ Post.prototype.parseQuotes = function() {
+ var quotelink, _i, _len, _ref;
+ this.quotes = [];
+ _ref = $$('.quotelink', this.nodes.comment);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ quotelink = _ref[_i];
+ this.parseQuote(quotelink);
+ }
+ };
+
+ Post.prototype.parseQuote = function(quotelink) {
+ var fullID, match;
+ if (!(match = quotelink.href.match(/boards\.4chan\.org\/([^\/]+)\/res\/\d+#p(\d+)$/))) {
+ 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(that) {
+ var anchor, fileEl, fileText, nameNode, size, thumb, unit;
+ if (!((fileEl = $('.file', this.nodes.post)) && (thumb = $('img[data-md5]', fileEl)))) {
+ return;
+ }
+ anchor = thumb.parentNode;
+ fileText = fileEl.firstElementChild;
+ this.file = {
+ text: fileText,
+ thumb: thumb,
+ URL: anchor.href,
+ size: thumb.alt.match(/[\d.]+\s\w+/)[0],
+ MD5: thumb.dataset.md5,
+ isSpoiler: $.hasClass(anchor, 'imgspoiler')
+ };
+ 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;
+ this.file.thumbURL = that.isArchived ? thumb.src : "" + location.protocol + "//t.4cdn.org/" + this.board + "/thumb/" + (this.file.URL.match(/(\d+)\./)[1]) + "s.jpg";
+ this.file.name = (nameNode = $('span', fileText)) ? nameNode.title || nameNode.textContent : fileText.title;
+ if (this.file.isImage = /(jpg|png|gif)$/i.test(this.file.name)) {
+ return this.file.dimensions = fileText.textContent.match(/\d+x\d+/)[0];
+ }
+ };
+
+ Post.prototype.cleanup = function(root) {
+ var node, _i, _j, _len, _len1, _ref, _ref1;
+ _ref = $$('.mobile', root);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ node = _ref[_i];
+ $.rm(node);
+ }
+ _ref1 = $$('.desktop', root);
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ node = _ref1[_j];
+ $.rmClass(node, 'desktop');
+ }
+ };
+
+ Post.prototype.kill = function(file, now) {
+ var clone, quotelink, strong, _i, _j, _len, _len1, _ref, _ref1;
+ now || (now = new Date());
+ if (file) {
+ if (this.file.isDead) {
+ return;
+ }
+ this.file.isDead = true;
+ this.file.timeOfDeath = now;
+ $.addClass(this.nodes.root, 'deleted-file');
+ } else {
+ if (this.isDead) {
+ return;
+ }
+ this.isDead = true;
+ this.timeOfDeath = now;
+ $.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 (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ clone = _ref[_i];
+ clone.kill(file, now);
+ }
+ if (file) {
+ return;
+ }
+ _ref1 = Get.allQuotelinksLinkingTo(this);
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ quotelink = _ref1[_j];
+ if (!(!$.hasClass(quotelink, 'deadlink'))) {
+ continue;
+ }
+ $.add(quotelink, $.tn('\u00A0(Dead)'));
+ $.addClass(quotelink, 'deadlink');
+ }
+ };
+
+ Post.prototype.resurrect = function() {
+ var clone, quotelink, strong, _i, _j, _len, _len1, _ref, _ref1;
+ delete this.isDead;
+ delete this.timeOfDeath;
+ $.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 (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ clone = _ref[_i];
+ clone.resurrect();
+ }
+ _ref1 = Get.allQuotelinksLinkingTo(this);
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ quotelink = _ref1[_j];
+ if ($.hasClass(quotelink, 'deadlink')) {
+ quotelink.textContent = quotelink.textContent.replace('\u00A0(Dead)', '');
+ $.rmClass(quotelink, 'deadlink');
+ }
+ }
+ };
+
+ Post.prototype.collect = function() {
+ this.kill();
+ delete g.posts[this.fullID];
+ delete this.thread.posts[this];
+ return delete this.board.posts[this];
+ };
+
+ Post.prototype.addClone = function(context) {
+ return new Clone(this, context);
+ };
+
+ Post.prototype.rmClone = function(index) {
+ var clone, _i, _len, _ref;
+ this.clones.splice(index, 1);
+ _ref = this.clones.slice(index);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ clone = _ref[_i];
+ clone.nodes.root.dataset.clone = index++;
+ }
+ };
+
+ return Post;
+
+ })();
+
+ Clone = (function(_super) {
+ __extends(Clone, _super);
+
+ function Clone(origin, context) {
+ var file, info, inline, inlined, key, nodes, post, root, val, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3;
+ this.origin = origin;
+ this.context = context;
+ _ref = ['ID', 'fullID', 'board', 'thread', 'info', 'quotes', 'isReply'];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ key = _ref[_i];
+ this[key] = origin[key];
+ }
+ nodes = origin.nodes;
+ root = nodes.root.cloneNode(true);
+ post = $('.post', root);
+ info = $('.postInfo', post);
+ this.nodes = {
+ root: root,
+ post: post,
+ info: info,
+ comment: $('.postMessage', post),
+ quotelinks: [],
+ backlinks: info.getElementsByClassName('backlink')
+ };
+ _ref1 = $$('.inline', post);
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ inline = _ref1[_j];
+ $.rm(inline);
+ }
+ _ref2 = $$('.inlined', post);
+ for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
+ inlined = _ref2[_k];
+ $.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', info);
+ }
+ if (nodes.flag) {
+ this.nodes.flag = $('.countryFlag', info);
+ }
+ if (nodes.date) {
+ this.nodes.date = $('.dateTime', info);
+ }
+ this.parseQuotes();
+ if (origin.file) {
+ this.file = {};
+ _ref3 = origin.file;
+ for (key in _ref3) {
+ val = _ref3[key];
+ this.file[key] = val;
+ }
+ file = $('.file', post);
+ this.file.text = file.firstElementChild;
+ this.file.thumb = $('img[data-md5]', file);
+ this.file.fullImage = $('.full-image', file);
+ }
+ if (origin.isDead) {
+ this.isDead = true;
+ }
+ this.isClone = true;
+ root.dataset.clone = origin.clones.push(this) - 1;
+ }
+
+ return Clone;
+
+ })(Post);
+
+ DataBoard = (function() {
+ DataBoard.keys = ['hiddenThreads', 'hiddenPosts', 'lastReadPosts', 'yourPosts', 'watchedThreads'];
+
+ function DataBoard(key, sync, dontClean) {
+ var init,
+ _this = this;
+ this.key = key;
+ this.onSync = __bind(this.onSync, this);
+ this.data = Conf[key];
+ $.sync(key, this.onSync);
+ if (!dontClean) {
+ this.clean();
+ }
+ if (!sync) {
+ return;
+ }
+ init = function() {
+ $.off(d, '4chanXInitFinished', init);
+ return _this.sync = sync;
+ };
+ $.on(d, '4chanXInitFinished', init);
+ }
+
+ DataBoard.prototype.save = function() {
+ return $.set(this.key, this.data);
+ };
+
+ DataBoard.prototype["delete"] = function(_arg) {
+ var boardID, postID, threadID;
+ boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID;
+ if (postID) {
+ delete this.data.boards[boardID][threadID][postID];
+ this.deleteIfEmpty({
+ boardID: boardID,
+ threadID: threadID
+ });
+ } else if (threadID) {
+ 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;
+ 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) {
+ var boardID, postID, threadID, val, _base, _base1, _base2;
+ boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID, val = _arg.val;
+ if (postID !== void 0) {
+ ((_base = ((_base1 = this.data.boards)[boardID] || (_base1[boardID] = {})))[threadID] || (_base[threadID] = {}))[postID] = val;
+ } else if (threadID !== void 0) {
+ ((_base2 = this.data.boards)[boardID] || (_base2[boardID] = {}))[threadID] = val;
+ } else {
+ this.data.boards[boardID] = val;
+ }
+ return this.save();
+ };
+
+ DataBoard.prototype.get = function(_arg) {
+ var ID, board, boardID, defaultValue, postID, thread, threadID, val, _i, _len;
+ boardID = _arg.boardID, threadID = _arg.threadID, postID = _arg.postID, defaultValue = _arg.defaultValue;
+ if (board = this.data.boards[boardID]) {
+ if (!threadID) {
+ if (postID) {
+ for (thread = _i = 0, _len = board.length; _i < _len; thread = ++_i) {
+ ID = board[thread];
+ if (postID in thread) {
+ val = thread[postID];
+ break;
+ }
+ }
+ } else {
+ val = board;
+ }
+ } else if (thread = board[threadID]) {
+ val = postID ? thread[postID] : thread;
+ }
+ }
+ return val || defaultValue;
+ };
+
+ DataBoard.prototype.clean = function() {
+ var boardID, now, val, _ref;
+ _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);
+ }
+ }
+ return this.save();
+ };
+
+ DataBoard.prototype.ajaxClean = function(boardID) {
+ var _this = this;
+ return $.cache("//a.4cdn.org/" + boardID + "/threads.json", function(e) {
+ var board, page, thread, threads, _i, _j, _len, _len1, _ref, _ref1;
+ if (e.target.status !== 200) {
+ if (e.target.status === 404) {
+ _this["delete"](boardID);
+ }
+ return;
+ }
+ board = _this.data.boards[boardID];
+ threads = {};
+ _ref = JSON.parse(e.target.response);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ page = _ref[_i];
+ _ref1 = page.threads;
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ thread = _ref1[_j];
+ if (thread.no in board) {
+ threads[thread.no] = board[thread.no];
+ }
+ }
+ }
+ _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, timeout) {
+ this.timeout = timeout;
+ this.close = __bind(this.close, this);
+ this.add = __bind(this.add, this);
+ this.el = $.el('div', {
+ innerHTML: '
'
+ });
+ this.el.style.opacity = 0;
+ this.setType(type);
+ $.on(this.el.firstElementChild, 'click', this.close);
+ if (typeof content === 'string') {
+ content = $.tn(content);
+ }
+ $.add(this.el.lastElementChild, content);
+ $.ready(this.add);
+ }
+
+ Notice.prototype.setType = function(type) {
+ return this.el.className = "notification " + type;
+ };
+
+ Notice.prototype.add = function() {
+ if (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);
+ return $.rm(this.el);
+ };
+
+ return Notice;
+
+ })();
+
+ RandomAccessList = (function() {
+ function RandomAccessList() {
+ this.length = 0;
+ }
+
+ RandomAccessList.prototype.push = function(item) {
+ var ID, last;
+ ID = item.ID;
+ if (this[ID]) {
+ return;
+ }
+ last = this.last;
+ item.prev = last;
+ this[ID] = item;
+ this.last = last ? last.next = item : this.first = item;
+ return this.length++;
+ };
+
+ RandomAccessList.prototype.after = function(root, item) {
+ var next;
+ if (item.prev === root) {
+ return;
+ }
+ this.rmi(item);
+ next = root.next;
+ root.next = item;
+ item.prev = root;
+ item.next = next;
+ return next.prev = item;
+ };
+
+ RandomAccessList.prototype.prepend = function(item) {
+ var first;
+ first = this.first;
+ if (item === first || !this[item.ID]) {
+ return;
+ }
+ this.rmi(item);
+ item.next = first;
+ first.prev = item;
+ this.first = item;
+ return delete item.prev;
+ };
+
+ RandomAccessList.prototype.shift = function() {
+ return this.rm(this.first.ID);
+ };
+
+ 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;
+
+ })();
+
+ Polyfill = {
+ init: function() {},
+ notificationPermission: function() {
+ if (!window.Notification || 'permission' in Notification || !window.webkitNotifications) {
+ return;
+ }
+ return Object.defineProperty(Notification, 'permission', {
+ get: function() {
+ switch (webkitNotifications.checkPermission()) {
+ case 0:
+ return 'granted';
+ case 1:
+ return 'default';
+ case 2:
+ return 'denied';
+ }
+ }
+ });
+ },
+ toBlob: function() {
+ var _base;
+ return (_base = HTMLCanvasElement.prototype).toBlob || (_base.toBlob = function(cb) {
+ var data, i, l, ui8a, _i;
+ data = atob(this.toDataURL().slice(22));
+ l = data.length;
+ ui8a = new Uint8Array(l);
+ for (i = _i = 0; _i < l; i = _i += 1) {
+ ui8a[i] = data.charCodeAt(i);
+ }
+ return cb(new Blob([ui8a], {
+ type: 'image/png'
+ }));
+ });
+ },
+ visibility: function() {
+ if ('visibilityState' in d) {
+ return;
+ }
+ Object.defineProperties(HTMLDocument.prototype, {
+ visibilityState: {
+ get: function() {
+ return this.webkitVisibilityState;
+ }
+ },
+ hidden: {
+ get: function() {
+ return this.webkitHidden;
+ }
+ }
+ });
+ return $.on(d, 'webkitvisibilitychange', function() {
+ return $.event('visibilitychange');
+ });
+ }
+ };
+
+ Header = {
+ init: function() {
+ var barFixedToggler, barPositionToggler, customNavToggler, editCustomNav, footerToggler, headerToggler, linkJustifyToggler, menuButton, scrollHeaderToggler, shortcutToggler,
+ _this = this;
+ this.menu = new UI.Menu('header');
+ menuButton = $.el('span', {
+ className: 'menu-button',
+ innerHTML: ' '
+ });
+ barFixedToggler = $.el('label', {
+ innerHTML: ' Fixed Header'
+ });
+ headerToggler = $.el('label', {
+ innerHTML: ' Auto-hide header'
+ });
+ scrollHeaderToggler = $.el('label', {
+ innerHTML: ' Auto-hide header on scroll'
+ });
+ barPositionToggler = $.el('label', {
+ innerHTML: ' Bottom header'
+ });
+ linkJustifyToggler = $.el('label', {
+ innerHTML: " Centered links"
+ });
+ customNavToggler = $.el('label', {
+ innerHTML: ' Custom board navigation'
+ });
+ footerToggler = $.el('label', {
+ innerHTML: " Hide bottom board list"
+ });
+ shortcutToggler = $.el('label', {
+ innerHTML: " 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.headerToggler, 'change', this.toggleBarVisibility);
+ $.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']);
+ $.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);
+ this.addShortcut(menuButton);
+ $.event('AddMenuEntry', {
+ type: 'header',
+ 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 hashchange', Header.hashScroll);
+ $.on(d, 'CreateNotification', this.createNotification);
+ $.asap((function() {
+ return d.body;
+ }), function() {
+ if (!Main.isThisPageLegit()) {
+ return;
+ }
+ $.asap((function() {
+ return $.id('boardNavMobile') || d.readyState !== 'loading';
+ }), Header.setBoardList);
+ $.prepend(d.body, _this.bar);
+ $.add(d.body, Header.hover);
+ _this.setBarPosition(Conf['Bottom Header']);
+ return _this;
+ });
+ $.ready(function() {
+ var a, cs, footer;
+ _this.footer = footer = $.id('boardNavDesktopFoot');
+ if (a = $("a[href*='/" + g.BOARD + "/']", footer)) {
+ a.className = 'current';
+ $.on(a, 'click', Index.cb.link);
+ }
+ cs = $.el('a', {
+ id: 'settingsWindowLink',
+ href: 'javascript:;',
+ textContent: 'Catalog Settings'
+ });
+ if (g.VIEW === 'catalog') {
+ _this.addShortcut(cs);
+ }
+ Header.setFooterVisibility(Conf['Bottom Board List']);
+ return $.sync('Bottom Board List', Header.setFooterVisibility);
+ });
+ 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, fourchannav, fullBoardList;
+ fourchannav = $.id('boardNavDesktop');
+ boardList = $.el('span', {
+ id: 'board-list',
+ innerHTML: " - " + fourchannav.innerHTML + " "
+ });
+ if (a = $("a[href*='/" + g.BOARD + "/']", boardList)) {
+ a.className = 'current';
+ $.on(a, 'click', Index.cb.link);
+ }
+ fullBoardList = $('#full-board-list', boardList);
+ btn = $('.hide-board-list-button', fullBoardList);
+ $.on(btn, 'click', Header.toggleBoardList);
+ $.rm($('#navtopright', fullBoardList));
+ $.add(boardList, fullBoardList);
+ $.add(Header.bar, [boardList, Header.shortcuts, Header.noticesRoot, Header.toggle]);
+ Header.setCustomNav(Conf['Custom Board Navigation']);
+ Header.generateBoardList(Conf['boardnav'].replace(/(\r\n|\n|\r)/g, ' '));
+ $.sync('Custom Board Navigation', Header.setCustomNav);
+ return $.sync('boardnav', Header.generateBoardList);
+ },
+ generateBoardList: function(text) {
+ var as, list, nodes;
+ list = $('#custom-board-list', Header.bar);
+ $.rmAll(list);
+ if (!text) {
+ return;
+ }
+ as = $$('#full-board-list a[title]', Header.bar);
+ nodes = text.match(/[\w@]+((-(all|title|replace|full|index|catalog|url:"[^"]+[^"]"|text:"[^"]+")|\,"[^"]+[^"]"))*|[^\w@]+/g).map(function(t) {
+ var a, board, current, m, _i, _len;
+ if (/^[^\w@]/.test(t)) {
+ return $.tn(t);
+ }
+ if (/^toggle-all/.test(t)) {
+ a = $.el('a', {
+ className: 'show-board-list-button',
+ textContent: (t.match(/-text:"(.+)"/) || [null, '+'])[1],
+ href: 'javascript:;'
+ });
+ $.on(a, 'click', Header.toggleBoardList);
+ return a;
+ }
+ if (/^external/.test(t)) {
+ a = $.el('a', {
+ href: (t.match(/\,"(.+)"/) || [null, '+'])[1],
+ textContent: (t.match(/-text:"(.+)"\,/) || [null, '+'])[1],
+ className: 'external'
+ });
+ return a;
+ }
+ board = /^current/.test(t) ? g.BOARD.ID : t.match(/^[^-]+/)[0];
+ for (_i = 0, _len = as.length; _i < _len; _i++) {
+ a = as[_i];
+ if (a.textContent === board) {
+ a = a.cloneNode(true);
+ current = $.hasClass(a, 'current');
+ if (current) {
+ $.on(a, 'click', Index.cb.link);
+ }
+ a.textContent = /-title/.test(t) || /-replace/.test(t) && current ? a.title : /-full/.test(t) ? "/" + board + "/ - " + a.title : (m = t.match(/-text:"(.+)"/)) ? m[1] : a.textContent;
+ if (m = t.match(/-(index|catalog)/)) {
+ a.dataset.only = m[1];
+ a.href = "//boards.4chan.org/" + board + "/";
+ if (m[1] === 'catalog') {
+ if (Conf['External Catalog']) {
+ a.href = CatalogLinks.external(board);
+ } else {
+ a.href += 'catalog';
+ }
+ $.addClass(a, 'catalog');
+ }
+ }
+ if (board === '@') {
+ $.addClass(a, 'navSmall');
+ }
+ return a;
+ }
+ }
+ return $.tn(t);
+ });
+ return $.add(list, nodes);
+ },
+ 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');
+ this.checked = hide;
+ $.set('Header auto-hide', Conf['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(e) {
+ var hide;
+ hide = this.checked;
+ $.set('Header auto-hide on scroll', hide);
+ return Header.setHideBarOnScroll(hide);
+ },
+ hideBarOnScroll: function() {
+ var offsetY;
+ offsetY = window.pageYOffset;
+ if (offsetY > (Header.previousOffset || 0)) {
+ $.addClass(Header.bar, 'autohide');
+ $.addClass(Header.bar, 'scroll');
+ } else {
+ $.rmClass(Header.bar, 'autohide');
+ $.rmClass(Header.bar, 'scroll');
+ }
+ return Header.previousOffset = offsetY;
+ },
+ setBarPosition: function(bottom) {
+ var args;
+ Header.barPositionToggler.checked = bottom;
+ $.event('CloseMenu');
+ args = bottom ? ['bottom-header', 'top-header', 'bottom', 'after'] : ['top-header', 'bottom-header', 'top', 'add'];
+ $.addClass(doc, args[0]);
+ $.rmClass(doc, args[1]);
+ Header.bar.parentNode.className = args[2];
+ return $[args[3]](Header.bar, Header.noticesRoot);
+ },
+ toggleBarPosition: function() {
+ $.cb.checked.call(this);
+ return Header.setBarPosition(this.checked);
+ },
+ setFooterVisibility: function(hide) {
+ Header.footerToggler.checked = hide;
+ return Header.footer.hidden = hide;
+ },
+ toggleFooterVisibility: function() {
+ var hide, message;
+ $.event('CloseMenu');
+ hide = this.nodeName === 'INPUT' ? this.checked : !!Header.footer.hidden;
+ 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-button', full);
+ return _ref = show ? [false, true] : [true, false], cust.hidden = _ref[0], full.hidden = _ref[1], _ref;
+ },
+ toggleCustomNav: function() {
+ $.cb.checked.call(this);
+ return Header.setCustomNav(this.checked);
+ },
+ editCustomNav: function() {
+ var settings;
+ Settings.open('Advanced');
+ settings = $.id('fourchanx-settings');
+ return $('input[name=boardnav]', settings).focus();
+ },
+ hashScroll: function() {
+ var hash, post;
+ hash = this.location.hash.slice(1);
+ if (!(/^p\d+$/.test(hash) && (post = $.id(hash)))) {
+ return;
+ }
+ if ((Get.postFromRoot(post)).isHidden) {
+ return;
+ }
+ return Header.scrollTo(post);
+ },
+ scrollTo: function(root, down, needed) {
+ var x;
+ if (down) {
+ x = Header.getBottomOf(root);
+ if (!(needed && x >= 0)) {
+ return window.scrollBy(0, -x);
+ }
+ } else {
+ x = Header.getTopOf(root);
+ 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['Bottom Header']) {
+ headRect = Header.toggle.getBoundingClientRect();
+ bottom -= clientHeight - headRect.bottom + headRect.height;
+ }
+ return bottom;
+ },
+ addShortcut: function(el) {
+ var shortcut;
+ shortcut = $.el('span', {
+ className: 'shortcut brackets-wrap'
+ });
+ $.add(shortcut, el);
+ return $.prepend(Header.shortcuts, shortcut);
+ },
+ menuToggle: function(e) {
+ return Header.menu.toggle(e, this, g);
+ },
+ createNotification: function(e) {
+ var cb, content, lifetime, notice, type, _ref;
+ _ref = e.detail, type = _ref.type, content = _ref.content, lifetime = _ref.lifetime, cb = _ref.cb;
+ notice = new Notice(type, content, lifetime);
+ if (cb) {
+ return cb(notice);
+ }
+ },
+ 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: "Desktop notification permissions are not granted.\n[FAQ ] \nAuthorize or Disable "
+ });
+ _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 = {
+ init: function() {
+ var anchorEntry, input, label, modeEntry, name, refNavEntry, repliesEntry, sortEntry, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2;
+ if (g.VIEW !== 'index' || g.BOARD.ID === 'f') {
+ return;
+ }
+ this.button = $.el('a', {
+ className: 'index-refresh-shortcut fa fa-refresh',
+ title: 'Refresh Index',
+ href: 'javascript:;',
+ textContent: 'Refresh Index'
+ });
+ $.on(this.button, 'click', this.update);
+ Header.addShortcut(this.button, 1);
+ modeEntry = {
+ el: $.el('span', {
+ textContent: 'Index mode'
+ }),
+ subEntries: [
+ {
+ el: $.el('label', {
+ innerHTML: ' Paged'
+ })
+ }, {
+ el: $.el('label', {
+ innerHTML: ' Infinite scrolling'
+ })
+ }, {
+ el: $.el('label', {
+ innerHTML: ' All threads'
+ })
+ }
+ ]
+ };
+ _ref = modeEntry.subEntries;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ label = _ref[_i];
+ input = label.el.firstChild;
+ input.checked = Conf['Index Mode'] === input.value;
+ $.on(input, 'change', $.cb.value);
+ $.on(input, 'change', this.cb.mode);
+ }
+ sortEntry = {
+ el: $.el('span', {
+ textContent: 'Sort by'
+ }),
+ subEntries: [
+ {
+ el: $.el('label', {
+ innerHTML: ' Bump order'
+ })
+ }, {
+ el: $.el('label', {
+ innerHTML: ' Last reply'
+ })
+ }, {
+ el: $.el('label', {
+ innerHTML: ' Creation date'
+ })
+ }, {
+ el: $.el('label', {
+ innerHTML: ' Reply count'
+ })
+ }, {
+ el: $.el('label', {
+ innerHTML: ' File count'
+ })
+ }
+ ]
+ };
+ _ref1 = sortEntry.subEntries;
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ label = _ref1[_j];
+ input = label.el.firstChild;
+ input.checked = Conf['Index Sort'] === input.value;
+ $.on(input, 'change', $.cb.value);
+ $.on(input, 'change', this.cb.sort);
+ }
+ repliesEntry = {
+ el: $.el('label', {
+ innerHTML: ' Show replies'
+ })
+ };
+ anchorEntry = {
+ el: $.el('label', {
+ innerHTML: ' Anchor hidden threads',
+ title: 'Move hidden threads at the end of the index.'
+ })
+ };
+ refNavEntry = {
+ el: $.el('label', {
+ innerHTML: ' Refreshed navigation',
+ title: 'Refresh index when navigating through pages.'
+ })
+ };
+ _ref2 = [repliesEntry, anchorEntry, refNavEntry];
+ for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
+ label = _ref2[_k];
+ input = label.el.firstChild;
+ name = input.name;
+ input.checked = Conf[name];
+ $.on(input, 'change', $.cb.checked);
+ switch (name) {
+ case 'Show Replies':
+ $.on(input, 'change', this.cb.replies);
+ break;
+ case 'Anchor Hidden Threads':
+ $.on(input, 'change', this.cb.sort);
+ }
+ }
+ $.event('AddMenuEntry', {
+ type: 'header',
+ el: $.el('span', {
+ textContent: 'Index Navigation'
+ }),
+ order: 98,
+ subEntries: [repliesEntry, anchorEntry, refNavEntry, modeEntry, sortEntry]
+ });
+ $.addClass(doc, 'index-loading');
+ this.update();
+ this.root = $.el('div', {
+ className: 'board'
+ });
+ this.pagelist = $.el('div', {
+ className: 'pagelist',
+ hidden: true,
+ innerHTML: "
"
+ });
+ this.navLinks = $.el('div', {
+ className: 'navLinks',
+ innerHTML: "[Catalog ] [... ] × "
+ });
+ this.searchInput = $('#index-search', this.navLinks);
+ this.currentPage = this.getCurrentPage();
+ $.on(window, 'popstate', this.cb.popstate);
+ $.on(d, 'scroll', Index.scroll);
+ $.on(this.pagelist, 'click', this.cb.pageNav);
+ $.on(this.searchInput, 'input', this.onSearchInput);
+ $.on($('#index-search-clear', this.navLinks), 'click', this.clearSearch);
+ return $.asap((function() {
+ return $('.board', doc) || d.readyState !== 'loading';
+ }), function() {
+ var board, navLink, _l, _len3, _ref3;
+ board = $('.board');
+ $.replace(board, Index.root);
+ d.implementation.createDocument(null, null, null).appendChild(board);
+ _ref3 = $$('.navLinks');
+ for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
+ navLink = _ref3[_l];
+ $.rm(navLink);
+ }
+ $.after($.x('child::form/preceding-sibling::hr[1]'), Index.navLinks);
+ $.rmClass(doc, 'index-loading');
+ return $.asap((function() {
+ return $('.pagelist') || d.readyState !== 'loading';
+ }), function() {
+ return $.replace($('.pagelist'), Index.pagelist);
+ });
+ });
+ },
+ scroll: $.debounce(100, function() {
+ var nodes, nodesPerPage, pageNum;
+ if (Index.req || Conf['Index Mode'] !== 'infinite' || ((d.body.scrollTop || doc.scrollTop) <= doc.scrollHeight - (300 + window.innerHeight))) {
+ return;
+ }
+ pageNum = Index.getCurrentPage() + 1;
+ if (pageNum >= Index.pagesNum) {
+ return Index.endNotice();
+ }
+ nodesPerPage = Index.threadsNumPerPage * 2;
+ history.pushState(null, '', "/" + g.BOARD + "/" + pageNum);
+ nodes = Index.sortedNodes.slice(nodesPerPage * pageNum, nodesPerPage * (pageNum + 1));
+ if (Conf['Show Replies']) {
+ Index.buildReplies(nodes);
+ }
+ $.add(Index.root, nodes);
+ return Index.setPage();
+ }),
+ 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);
+ };
+ })(),
+ cb: {
+ mode: function() {
+ Index.togglePagelist();
+ return Index.buildIndex();
+ },
+ sort: function() {
+ Index.sort();
+ return Index.buildIndex();
+ },
+ replies: function() {
+ Index.buildThreads();
+ Index.sort();
+ return Index.buildIndex();
+ },
+ popstate: function(e) {
+ var pageNum;
+ pageNum = Index.getCurrentPage();
+ if (Index.currentPage !== pageNum) {
+ return Index.pageLoad(pageNum);
+ }
+ },
+ pageNav: function(e) {
+ var a;
+ if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
+ return;
+ }
+ switch (e.target.nodeName) {
+ case 'BUTTON':
+ 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]);
+ },
+ link: function(e) {
+ if (g.VIEW !== 'index' || /catalog/.test(this.href)) {
+ return;
+ }
+ e.preventDefault();
+ history.pushState(null, '', this.pathname);
+ return Index.update();
+ }
+ },
+ scrollToIndex: function() {
+ return Header.scrollToIfNeeded(Index.root);
+ },
+ getCurrentPage: function() {
+ return +window.location.pathname.split('/')[2];
+ },
+ userPageNav: function(pageNum) {
+ if (Conf['Refreshed Navigation'] && Conf['Index Mode'] !== 'all pages') {
+ return Index.update(pageNum);
+ } else {
+ return Index.pageNav(pageNum);
+ }
+ },
+ pageNav: function(pageNum) {
+ if (Index.currentPage === pageNum) {
+ return;
+ }
+ history.pushState(null, '', pageNum === 0 ? './' : pageNum);
+ return Index.pageLoad(pageNum);
+ },
+ pageLoad: function(pageNum) {
+ Index.currentPage = pageNum;
+ if (Conf['Index Mode'] === 'all pages') {
+ return;
+ }
+ Index.buildIndex();
+ Index.setPage();
+ return Index.scrollToIndex();
+ },
+ getPagesNum: function() {
+ if (Index.isSearching) {
+ return Math.ceil((Index.sortedNodes.length / 2) / Index.threadsNumPerPage);
+ } else {
+ return Index.pagesNum;
+ }
+ },
+ getMaxPageNum: function() {
+ return Math.max(0, Index.getPagesNum() - 1);
+ },
+ togglePagelist: function() {
+ return Index.pagelist.hidden = Conf['Index Mode'] === 'all pages';
+ },
+ buildPagelist: function() {
+ var a, i, maxPageNum, nodes, pagesRoot, _i;
+ pagesRoot = $('.pages', Index.pagelist);
+ maxPageNum = Index.getMaxPageNum();
+ if (pagesRoot.childElementCount !== maxPageNum + 1) {
+ nodes = [];
+ for (i = _i = 0; _i <= maxPageNum; i = _i += 1) {
+ a = $.el('a', {
+ textContent: i,
+ href: i ? i : './'
+ });
+ nodes.push($.tn('['), a, $.tn('] '));
+ }
+ $.rmAll(pagesRoot);
+ $.add(pagesRoot, nodes);
+ }
+ return Index.togglePagelist();
+ },
+ setPage: function() {
+ var a, href, maxPageNum, next, pageNum, pagesRoot, prev, strong;
+ pageNum = Index.getCurrentPage();
+ maxPageNum = Index.getMaxPageNum();
+ pagesRoot = $('.pages', Index.pagelist);
+ prev = pagesRoot.previousSibling.firstChild;
+ next = pagesRoot.nextSibling.firstChild;
+ href = Math.max(pageNum - 1, 0);
+ prev.href = href === 0 ? './' : href;
+ prev.firstChild.disabled = href === pageNum;
+ href = Math.min(pageNum + 1, maxPageNum);
+ next.href = href === 0 ? './' : 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];
+ $.before(a, strong);
+ return $.add(strong, a);
+ },
+ update: function(pageNum) {
+ var onload, _ref, _ref1;
+ if (!navigator.onLine) {
+ return;
+ }
+ if ((_ref = Index.req) != null) {
+ _ref.abort();
+ }
+ if ((_ref1 = Index.notice) != null) {
+ _ref1.close();
+ }
+ if (typeof pageNum !== 'number') {
+ pageNum = null;
+ }
+ onload = function(e) {
+ return Index.load(e, pageNum);
+ };
+ Index.req = $.ajax("//a.4cdn.org/" + g.BOARD + "/catalog.json", {
+ onabort: onload,
+ onloadend: onload
+ }, {
+ whenModified: true
+ });
+ return $.addClass(Index.button, 'fa-spin');
+ },
+ load: function(e, pageNum) {
+ var err, notice, req, timeEl;
+ $.rmClass(Index.button, 'fa-spin');
+ req = Index.req, notice = Index.notice;
+ delete Index.req;
+ delete Index.notice;
+ if (e.type === 'abort') {
+ req.onloadend = null;
+ notice.close();
+ return;
+ }
+ try {
+ if (req.status === 200) {
+ Index.parse(JSON.parse(req.response), pageNum);
+ } else if (req.status === 304 && (pageNum != null)) {
+ Index.pageNav(pageNum);
+ }
+ } catch (_error) {
+ err = _error;
+ c.error('Index failure:', err.stack);
+ if (notice) {
+ notice.setType('error');
+ notice.el.lastElementChild.textContent = 'Index refresh failed.';
+ setTimeout(notice.close, 2 * $.SECOND);
+ } else {
+ new Notice('error', 'Index refresh failed.', 2);
+ }
+ return;
+ }
+ timeEl = $('#index-last-refresh', Index.navLinks);
+ timeEl.dataset.utc = Date.parse(req.getResponseHeader('Last-Modified'));
+ RelativeDates.update(timeEl);
+ return Index.scrollToIndex();
+ },
+ parse: function(pages, pageNum) {
+ Index.parseThreadList(pages);
+ Index.buildThreads();
+ Index.sort();
+ Index.buildPagelist();
+ if (pageNum != null) {
+ Index.pageNav(pageNum);
+ return;
+ }
+ Index.buildIndex();
+ return Index.setPage();
+ },
+ parseThreadList: function(pages) {
+ var thread, threadID, _ref, _ref1;
+ Index.pagesNum = pages.length;
+ Index.threadsNumPerPage = pages[0].threads.length;
+ Index.liveThreadData = pages.reduce((function(arr, next) {
+ return arr.concat(next.threads);
+ }), []);
+ Index.liveThreadIDs = Index.liveThreadData.map(function(data) {
+ return data.no;
+ });
+ _ref = g.BOARD.threads;
+ for (threadID in _ref) {
+ thread = _ref[threadID];
+ if (_ref1 = thread.ID, __indexOf.call(Index.liveThreadIDs, _ref1) < 0) {
+ thread.collect();
+ }
+ }
+ },
+ buildThreads: function() {
+ var err, errors, i, posts, thread, threadData, threadRoot, threads, _i, _len, _ref;
+ Index.nodes = [];
+ threads = [];
+ posts = [];
+ _ref = Index.liveThreadData;
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+ threadData = _ref[i];
+ threadRoot = Build.thread(g.BOARD, threadData);
+ Index.nodes.push(threadRoot, $.el('hr'));
+ if (thread = g.BOARD.threads[threadData.no]) {
+ thread.setPage(Math.floor(i / Index.threadsNumPerPage));
+ thread.setStatus('Sticky', !!threadData.sticky);
+ thread.setStatus('Closed', !!threadData.closed);
+ } else {
+ thread = new Thread(threadData.no, g.BOARD);
+ threads.push(thread);
+ }
+ if (thread.ID in thread.posts) {
+ continue;
+ }
+ try {
+ posts.push(new Post($('.opContainer', threadRoot), thread, g.BOARD));
+ } catch (_error) {
+ err = _error;
+ if (!errors) {
+ errors = [];
+ }
+ errors.push({
+ message: "Parsing of Post No." + thread + " failed. Post will be skipped.",
+ error: err
+ });
+ }
+ }
+ if (errors) {
+ Main.handleErrors(errors);
+ }
+ $.nodes(Index.nodes);
+ Main.callbackNodes(Thread, threads);
+ Main.callbackNodes(Post, posts);
+ return $.event('IndexRefresh');
+ },
+ buildReplies: function(threadRoots) {
+ var data, err, errors, i, lastReplies, node, nodes, post, posts, thread, threadRoot, _i, _j, _len, _len1;
+ posts = [];
+ for (_i = 0, _len = threadRoots.length; _i < _len; _i += 2) {
+ threadRoot = threadRoots[_i];
+ thread = Get.threadFromRoot(threadRoot);
+ i = Index.liveThreadIDs.indexOf(thread.ID);
+ if (!(lastReplies = Index.liveThreadData[i].last_replies)) {
+ continue;
+ }
+ nodes = [];
+ for (_j = 0, _len1 = lastReplies.length; _j < _len1; _j++) {
+ data = lastReplies[_j];
+ if (post = thread.posts[data.no]) {
+ 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);
+ },
+ sort: function() {
+ var i, sortedThreadIDs, threadID, _i, _len;
+ switch (Conf['Index Sort']) {
+ case 'bump':
+ sortedThreadIDs = Index.liveThreadIDs;
+ break;
+ case 'lastreply':
+ sortedThreadIDs = __slice.call(Index.liveThreadData).sort(function(a, b) {
+ if ('last_replies' in a) {
+ a = a.last_replies[a.last_replies.length - 1];
+ }
+ if ('last_replies' in b) {
+ b = b.last_replies[b.last_replies.length - 1];
+ }
+ return b.no - a.no;
+ }).map(function(data) {
+ return data.no;
+ });
+ break;
+ case 'birth':
+ sortedThreadIDs = __slice.call(Index.liveThreadIDs).sort(function(a, b) {
+ return b - a;
+ });
+ break;
+ case 'replycount':
+ sortedThreadIDs = __slice.call(Index.liveThreadData).sort(function(a, b) {
+ return b.replies - a.replies;
+ }).map(function(data) {
+ return data.no;
+ });
+ break;
+ case 'filecount':
+ sortedThreadIDs = __slice.call(Index.liveThreadData).sort(function(a, b) {
+ return b.images - a.images;
+ }).map(function(data) {
+ return data.no;
+ });
+ }
+ Index.sortedNodes = [];
+ for (_i = 0, _len = sortedThreadIDs.length; _i < _len; _i++) {
+ threadID = sortedThreadIDs[_i];
+ i = Index.liveThreadIDs.indexOf(threadID) * 2;
+ Index.sortedNodes.push(Index.nodes[i], Index.nodes[i + 1]);
+ }
+ if (Index.isSearching) {
+ Index.sortedNodes = Index.querySearch(Index.searchInput.value) || Index.sortedNodes;
+ }
+ Index.sortOnTop(function(thread) {
+ return thread.isSticky;
+ });
+ if (Conf['Filter']) {
+ Index.sortOnTop(function(thread) {
+ return thread.isOnTop;
+ });
+ }
+ if (Conf['Anchor Hidden Threads']) {
+ return Index.sortOnTop(function(thread) {
+ return !thread.isHidden;
+ });
+ }
+ },
+ sortOnTop: function(match) {
+ var i, offset, threadRoot, _i, _len, _ref, _ref1;
+ offset = 0;
+ _ref = Index.sortedNodes;
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = _i += 2) {
+ threadRoot = _ref[i];
+ if (match(Get.threadFromRoot(threadRoot))) {
+ (_ref1 = Index.sortedNodes).splice.apply(_ref1, [offset++ * 2, 0].concat(__slice.call(Index.sortedNodes.splice(i, 2))));
+ }
+ }
+ },
+ buildIndex: function() {
+ var nodes, nodesPerPage, pageNum;
+ if (Conf['Index Mode'] !== 'all pages') {
+ pageNum = Index.getCurrentPage();
+ nodesPerPage = Index.threadsNumPerPage * 2;
+ nodes = Index.sortedNodes.slice(nodesPerPage * pageNum, nodesPerPage * (pageNum + 1));
+ } else {
+ nodes = Index.sortedNodes;
+ }
+ $.rmAll(Index.root);
+ $.rmAll(Header.hover);
+ if (Conf['Show Replies']) {
+ Index.buildReplies(nodes);
+ }
+ $.event('IndexBuild', nodes);
+ return $.add(Index.root, nodes);
+ },
+ isSearching: false,
+ clearSearch: function() {
+ Index.searchInput.value = null;
+ Index.onSearchInput();
+ return Index.searchInput.focus();
+ },
+ onSearchInput: function() {
+ var pageNum;
+ if (Index.isSearching = !!Index.searchInput.value.trim()) {
+ if (!Index.searchInput.dataset.searching) {
+ Index.searchInput.dataset.searching = 1;
+ Index.pageBeforeSearch = Index.getCurrentPage();
+ pageNum = 0;
+ } else {
+ pageNum = Index.getCurrentPage();
+ }
+ } else {
+ pageNum = Index.pageBeforeSearch;
+ delete Index.pageBeforeSearch;
+ Index.searchInput.removeAttribute('data-searching');
+ }
+ Index.sort();
+ if (Conf['Index Mode'] !== 'all pages') {
+ pageNum = Math.min(pageNum, Index.getMaxPageNum());
+ }
+ Index.buildPagelist();
+ if (Index.currentPage === pageNum) {
+ Index.buildIndex();
+ return Index.setPage();
+ } else {
+ return Index.pageNav(pageNum);
+ }
+ },
+ querySearch: function(query) {
+ var keywords;
+ if (!(keywords = query.toLowerCase().match(/\S+/g))) {
+ return;
+ }
+ return Index.search(keywords);
+ },
+ search: function(keywords) {
+ var found, i, threadRoot, _i, _len, _ref;
+ found = [];
+ _ref = Index.sortedNodes;
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = _i += 2) {
+ threadRoot = _ref[i];
+ if (Index.searchMatch(Get.threadFromRoot(threadRoot), keywords)) {
+ found.push(Index.sortedNodes[i], Index.sortedNodes[i + 1]);
+ }
+ }
+ return found;
+ },
+ searchMatch: function(thread, keywords) {
+ var file, info, key, keyword, text, _i, _j, _len, _len1, _ref, _ref1;
+ _ref = thread.OP, info = _ref.info, file = _ref.file;
+ text = [];
+ _ref1 = ['comment', 'subject', 'name', 'tripcode', 'email'];
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ key = _ref1[_i];
+ if (key in info) {
+ text.push(info[key]);
+ }
+ }
+ if (file) {
+ text.push(file.name);
+ }
+ text = text.join(' ').toLowerCase();
+ for (_j = 0, _len1 = keywords.length; _j < _len1; _j++) {
+ keyword = keywords[_j];
+ if (-1 === text.indexOf(keyword)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ };
+
+ Build = {
+ staticPath: '//s.4cdn.org/image/',
+ gifIcon: window.devicePixelRatio >= 2 ? '@2x.gif' : '.gif',
+ spoilerRange: {},
+ shortFilename: function(filename, isReply) {
+ var threshold;
+ threshold = isReply ? 30 : 40;
+ if (filename.length - 4 > threshold) {
+ return "" + filename.slice(0, threshold - 5) + "(...)." + filename.slice(-3);
+ } else {
+ return filename;
+ }
+ },
+ thumbRotate: (function() {
+ var n;
+ n = 0;
+ return function() {
+ return n = (n + 1) % 3;
+ };
+ })(),
+ postFromObject: function(data, boardID) {
+ var o;
+ o = {
+ postID: data.no,
+ threadID: data.resto || data.no,
+ boardID: boardID,
+ name: data.name,
+ capcode: data.capcode,
+ tripcode: data.trip,
+ uniqueID: data.id,
+ email: data.email ? encodeURI(data.email.replace(/"/g, '"')) : '',
+ subject: data.sub,
+ flagCode: data.country,
+ flagName: data.country_name,
+ date: data.now,
+ dateUTC: data.time,
+ comment: data.com,
+ isSticky: !!data.sticky,
+ isClosed: !!data.closed
+ };
+ if (data.ext || data.filedeleted) {
+ o.file = {
+ name: data.filename + data.ext,
+ timestamp: "" + data.tim + data.ext,
+ url: boardID === 'f' ? "//i.4cdn.org/" + boardID + "/src/" + data.filename + data.ext : "//i.4cdn.org/" + boardID + "/src/" + data.tim + data.ext,
+ height: data.h,
+ width: data.w,
+ MD5: data.md5,
+ size: data.fsize,
+ turl: "//" + (Build.thumbRotate()) + ".t.4cdn.org/" + boardID + "/thumb/" + data.tim + "s.jpg",
+ theight: data.tn_h,
+ twidth: data.tn_w,
+ isSpoiler: !!data.spoiler,
+ isDeleted: !!data.filedeleted
+ };
+ }
+ return Build.post(o);
+ },
+ post: function(o, isArchived) {
+ /*
+ This function contains code from 4chan-JS (https://github.com/4chan/4chan-JS).
+ @license: https://github.com/4chan/4chan-JS/blob/master/LICENSE
+ */
+
+ var a, boardID, capcode, capcodeClass, capcodeIcon, capcodeStart, closed, comment, container, date, dateUTC, email, emailEnd, emailStart, file, fileDims, fileHTML, fileInfo, fileSize, fileThumb, filename, flag, flagCode, flagName, gifIcon, href, imgSrc, isClosed, isOP, isSticky, name, pageIcon, pageNum, postID, quote, replyLink, shortFilename, spoilerRange, staticPath, sticky, subject, threadID, tripcode, uniqueID, userID, _i, _len, _ref;
+ postID = o.postID, threadID = o.threadID, boardID = o.boardID, name = o.name, capcode = o.capcode, tripcode = o.tripcode, uniqueID = o.uniqueID, email = o.email, subject = o.subject, flagCode = o.flagCode, flagName = o.flagName, date = o.date, dateUTC = o.dateUTC, isSticky = o.isSticky, isClosed = o.isClosed, comment = o.comment, file = o.file;
+ isOP = postID === threadID;
+ staticPath = Build.staticPath, gifIcon = Build.gifIcon;
+ tripcode = tripcode ? " " + tripcode + " " : '';
+ if (email) {
+ emailStart = '';
+ emailEnd = ' ';
+ } else {
+ emailStart = '';
+ emailEnd = '';
+ }
+ switch (capcode) {
+ case 'admin':
+ case 'admin_highlight':
+ capcodeClass = " capcodeAdmin";
+ capcodeStart = " ## Admin ";
+ capcodeIcon = (" ";
+ break;
+ case 'mod':
+ capcodeClass = " capcodeMod";
+ capcodeStart = " ## Mod ";
+ capcodeIcon = (" ";
+ break;
+ case 'developer':
+ capcodeClass = " capcodeDeveloper";
+ capcodeStart = " ## Developer ";
+ capcodeIcon = (" ";
+ break;
+ default:
+ capcodeClass = '';
+ capcodeStart = '';
+ capcodeIcon = '';
+ }
+ userID = !capcode && uniqueID ? (" (ID: ") + ("" + uniqueID + " ) ") : '';
+ flag = !flagCode ? '' : boardID === 'pol' ? " " : " ";
+ if (file != null ? file.isDeleted : void 0) {
+ fileHTML = isOP ? ("") + (" ") + " " : ("") + (" ") + " ";
+ } else if (file) {
+ fileSize = $.bytesToString(file.size);
+ fileThumb = file.turl;
+ if (file.isSpoiler) {
+ fileSize = "Spoiler Image, " + fileSize;
+ if (!isArchived) {
+ fileThumb = "" + staticPath + "spoiler";
+ if (spoilerRange = Build.spoilerRange[boardID]) {
+ fileThumb += ("-" + boardID) + Math.floor(1 + spoilerRange * Math.random());
+ }
+ fileThumb += '.png';
+ file.twidth = file.theight = 100;
+ }
+ }
+ imgSrc = boardID === 'f' ? '' : ("") + (" ") + " ";
+ a = $.el('a', {
+ innerHTML: file.name
+ });
+ filename = a.textContent.replace(/%22/g, '"');
+ a.textContent = Build.shortFilename(filename);
+ shortFilename = a.innerHTML;
+ a.textContent = filename;
+ filename = a.innerHTML.replace(/'/g, ''');
+ fileDims = file.name.slice(-3) === 'pdf' ? 'PDF' : "" + file.width + "x" + file.height;
+ fileInfo = ("File:
" + file.timestamp + " ") + ("-(" + fileSize + ", " + fileDims + (file.isSpoiler ? '' : ",
" + shortFilename + " ")) + ")
";
+ fileHTML = "" + fileInfo + imgSrc + "
";
+ } else {
+ fileHTML = '';
+ }
+ sticky = isSticky ? " " : '';
+ closed = isClosed ? " " : '';
+ if (isOP && g.VIEW === 'index') {
+ pageNum = Math.floor(Index.liveThreadIDs.indexOf(postID) / Index.threadsNumPerPage);
+ pageIcon = " [" + pageNum + "] ";
+ replyLink = " [Reply ] ";
+ } else {
+ pageIcon = replyLink = '';
+ }
+ container = $.el('div', {
+ id: "pc" + postID,
+ className: "postContainer " + (isOP ? 'op' : 'reply') + "Container",
+ innerHTML: "" + (isOP ? '' : ">>
") + "" + (isOP ? fileHTML : '') + "
" + ' ' + "
" + (subject || '') + " " + ' ' + "
" + emailStart + "" + (name || '') + " " + (tripcode + capcodeStart + emailEnd + capcodeIcon + userID + flag) + " " + " " + "
" + date + " " + ' ' + "
No. " + postID + " " + (pageIcon + sticky + closed + replyLink) + "" + (isOP ? '' : fileHTML) + "
" + (comment || '') + " " + ' ' + "
"
+ });
+ _ref = $$('.quotelink', container);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ quote = _ref[_i];
+ href = quote.getAttribute('href');
+ if (href[0] === '/') {
+ continue;
+ }
+ quote.href = "/" + boardID + "/res/" + 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 + "/res/" + threadID
+ });
+ },
+ thread: function(board, data) {
+ var OP, files, nodes, posts, root, _ref;
+ Build.spoilerRange[board] = data.custom_spoiler;
+ if ((OP = board.posts[data.no]) && (root = OP.nodes.root.parentNode)) {
+ $.rmAll(root);
+ } else {
+ root = $.el('div', {
+ className: 'thread',
+ id: "t" + data.no
+ });
+ }
+ nodes = [OP ? OP.nodes.root : Build.postFromObject(data, board.ID)];
+ if (data.omitted_posts || !Conf['Show Replies'] && data.replies) {
+ _ref = Conf['Show Replies'] ? [data.omitted_posts, data.omitted_images] : [
+ data.replies, data.omitted_images + data.last_replies.filter(function(data) {
+ return !!data.ext;
+ }).length
+ ], posts = _ref[0], files = _ref[1];
+ nodes.push(Build.summary(board.ID, data.no, posts, files));
+ }
+ $.add(root, nodes);
+ return root;
+ }
+ };
+
+ Get = {
+ threadExcerpt: function(thread) {
+ var OP, excerpt, _ref;
+ OP = thread.OP;
+ excerpt = ((_ref = OP.info.subject) != null ? _ref.trim() : void 0) || OP.info.comment.replace(/\n+/g, ' // ') || Conf['Anonymize'] && 'Anonymous' || $('.nameBlock', OP.nodes.info).textContent.trim();
+ if (excerpt.length > 70) {
+ excerpt = "" + excerpt.slice(0, 67) + "...";
+ }
+ return "/" + thread.board + "/ - " + 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 boardID, index, link, post, postID;
+ link = $('a[title="Highlight this post"]', root);
+ boardID = link.pathname.split('/')[1];
+ postID = link.hash.slice(2);
+ index = root.dataset.clone;
+ post = g.posts["" + boardID + "." + postID];
+ 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));
+ },
+ contextFromNode: function(node) {
+ return Get.postFromRoot($.x('ancestor::div[parent::div[@class="thread"]][1]', node));
+ },
+ postDataFromLink: function(link) {
+ var boardID, path, postID, threadID, _ref;
+ 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 ID, quote, quotedPost, quotelinks, quoterPost, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4;
+ quotelinks = [];
+ _ref = g.posts;
+ for (ID in _ref) {
+ quoterPost = _ref[ID];
+ if (_ref1 = post.fullID, __indexOf.call(quoterPost.quotes, _ref1) >= 0) {
+ _ref2 = [quoterPost].concat(quoterPost.clones);
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ quoterPost = _ref2[_i];
+ quotelinks.push.apply(quotelinks, quoterPost.nodes.quotelinks);
+ }
+ }
+ }
+ if (Conf['Quote Backlinks']) {
+ _ref3 = post.quotes;
+ for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
+ quote = _ref3[_j];
+ if (!(quotedPost = g.posts[quote])) {
+ continue;
+ }
+ _ref4 = [quotedPost].concat(quotedPost.clones);
+ for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
+ quotedPost = _ref4[_k];
+ quotelinks.push.apply(quotelinks, __slice.call(quotedPost.nodes.backlinks));
+ }
+ }
+ }
+ return quotelinks.filter(function(quotelink) {
+ var boardID, postID, _ref5;
+ _ref5 = Get.postDataFromLink(quotelink), boardID = _ref5.boardID, postID = _ref5.postID;
+ return boardID === post.board.ID && postID === post.ID;
+ });
+ },
+ postClone: function(boardID, threadID, postID, root, context) {
+ var post, url;
+ if (post = g.posts["" + boardID + "." + postID]) {
+ Get.insert(post, root, context);
+ return;
+ }
+ root.textContent = "Loading post No." + postID + "...";
+ if (threadID) {
+ return $.cache("//a.4cdn.org/" + boardID + "/res/" + threadID + ".json", function() {
+ return Get.fetchedPost(this, boardID, threadID, postID, root, context);
+ });
+ } else if (url = Redirect.to('post', {
+ boardID: boardID,
+ postID: postID
+ })) {
+ return $.cache(url, function() {
+ return Get.archivedPost(this, boardID, postID, root, context);
+ }, {
+ withCredentials: url.archive.withCredentials
+ });
+ }
+ },
+ insert: function(post, root, context) {
+ var clone, nodes;
+ if (!root.parentNode) {
+ return;
+ }
+ clone = post.addClone(context);
+ Main.callbackNodes(Clone, [clone]);
+ nodes = clone.nodes;
+ $.rmAll(nodes.root);
+ $.add(nodes.root, nodes.post);
+ $.rmAll(root);
+ return $.add(root, nodes.root);
+ },
+ fetchedPost: function(req, boardID, threadID, postID, root, context) {
+ var board, post, posts, status, thread, url, _i, _len;
+ if (post = g.posts["" + boardID + "." + postID]) {
+ Get.insert(post, root, context);
+ return;
+ }
+ status = req.status;
+ if (status !== 200 && status !== 304) {
+ if (url = Redirect.to('post', {
+ boardID: boardID,
+ postID: postID
+ })) {
+ $.cache(url, function() {
+ return Get.archivedPost(this, boardID, postID, root, context);
+ }, {
+ withCredentials: url.archive.withCredentials
+ });
+ } else {
+ $.addClass(root, 'warning');
+ root.textContent = status === 404 ? "Thread No." + threadID + " 404'd." : "Error " + req.statusText + " (" + req.status + ").";
+ }
+ return;
+ }
+ posts = JSON.parse(req.response).posts;
+ Build.spoilerRange[boardID] = posts[0].custom_spoiler;
+ for (_i = 0, _len = posts.length; _i < _len; _i++) {
+ post = posts[_i];
+ if (post.no === postID) {
+ break;
+ }
+ }
+ if (post.no !== postID) {
+ if (url = Redirect.to('post', {
+ boardID: boardID,
+ postID: postID
+ })) {
+ $.cache(url, function() {
+ return Get.archivedPost(this, boardID, postID, root, context);
+ }, {
+ withCredentials: url.archive.withCredentials
+ });
+ } else {
+ $.addClass(root, 'warning');
+ root.textContent = "Post No." + postID + " was not found.";
+ }
+ return;
+ }
+ board = g.boards[boardID] || new Board(boardID);
+ thread = g.threads["" + boardID + "." + threadID] || new Thread(threadID, board);
+ post = new Post(Build.postFromObject(post, boardID), thread, board);
+ Main.callbackNodes(Post, [post]);
+ return Get.insert(post, root, context);
+ },
+ archivedPost: function(req, boardID, postID, root, context) {
+ var board, bq, comment, data, o, post, thread, threadID, _ref;
+ if (post = g.posts["" + boardID + "." + postID]) {
+ Get.insert(post, root, context);
+ return;
+ }
+ data = JSON.parse(req.response);
+ if (data.error) {
+ $.addClass(root, 'warning');
+ root.textContent = data.error;
+ return;
+ }
+ bq = $.el('blockquote', {
+ textContent: data.comment
+ });
+ bq.innerHTML = bq.innerHTML.replace(/\n|\[\/?[a-z]+(:lit)?\]/g, Get.parseMarkup);
+ comment = bq.innerHTML.replace(/(^|>)(>[^<$]*)(<|$)/g, '$1$2 $3').replace(/((>){2}(>\/[a-z\d]+\/)?\d+)/g, '$1 ');
+ threadID = +data.thread_num;
+ o = {
+ postID: postID,
+ threadID: threadID,
+ boardID: boardID,
+ name: data.name_processed,
+ capcode: (function() {
+ switch (data.capcode) {
+ case 'M':
+ return 'mod';
+ case 'A':
+ return 'admin';
+ case 'D':
+ return 'developer';
+ }
+ })(),
+ tripcode: data.trip,
+ uniqueID: data.poster_hash,
+ email: data.email ? encodeURI(data.email) : '',
+ subject: data.title_processed,
+ flagCode: data.poster_country,
+ flagName: data.poster_country_name_processed,
+ date: data.fourchan_date,
+ dateUTC: data.timestamp,
+ comment: comment
+ };
+ if ((_ref = data.media) != null ? _ref.media_filename : void 0) {
+ o.file = {
+ name: data.media.media_filename_processed,
+ timestamp: data.media.media_orig,
+ url: data.media.media_link || data.media.remote_media_link,
+ height: data.media.media_h,
+ width: data.media.media_w,
+ MD5: data.media.media_hash,
+ size: data.media.media_size,
+ turl: data.media.thumb_link || ("//t.4cdn.org/" + boardID + "/thumb/" + data.media.preview_orig),
+ theight: data.media.preview_h,
+ twidth: data.media.preview_w,
+ isSpoiler: data.media.spoiler === '1'
+ };
+ }
+ board = g.boards[boardID] || new Board(boardID);
+ thread = g.threads["" + boardID + "." + threadID] || new Thread(threadID, board);
+ post = new Post(Build.post(o, true), thread, board, {
+ isArchived: true
+ });
+ Main.callbackNodes(Post, [post]);
+ return Get.insert(post, root, context);
+ },
+ parseMarkup: function(text) {
+ switch (text) {
+ case '\n':
+ return ' ';
+ case '[b]':
+ return '';
+ case '[/b]':
+ return ' ';
+ case '[spoiler]':
+ return '';
+ case '[/spoiler]':
+ return ' ';
+ case '[code]':
+ return '';
+ case '[/code]':
+ return ' ';
+ case '[moot]':
+ return '';
+ case '[/moot]':
+ return '
';
+ case '[banned]':
+ return '';
+ case '[/banned]':
+ return ' ';
+ default:
+ return text.replace(':lit', '');
+ }
+ }
+ };
+
+ UI = (function() {
+ var Menu, dialog, drag, dragend, dragstart, hover, hoverend, hoverstart, touchend, touchmove;
+ dialog = function(id, position, html) {
+ var child, el, move, _i, _len, _ref;
+ el = $.el('div', {
+ className: 'dialog',
+ innerHTML: html,
+ id: id
+ });
+ 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 (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ child = _ref[_i];
+ if (!child.tagName) {
+ continue;
+ }
+ $.on(child, 'touchstart mousedown', function(e) {
+ return e.stopPropagation();
+ });
+ }
+ return el;
+ };
+ Menu = (function() {
+ var currentMenu, lastToggledButton;
+
+ currentMenu = null;
+
+ lastToggledButton = null;
+
+ function Menu(type) {
+ this.type = type;
+ this.addEntry = __bind(this.addEntry, this);
+ this.keybinds = __bind(this.keybinds, this);
+ this.close = __bind(this.close, this);
+ $.on(d, 'AddMenuEntry', this.addEntry);
+ 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;
+ this.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, left, mRect, menu, right, style, top, _i, _len, _ref, _ref1, _ref2;
+ menu = this.makeMenu();
+ currentMenu = menu;
+ lastToggledButton = button;
+ this.entries.sort(function(first, second) {
+ return first.order - second.order;
+ });
+ _ref = this.entries;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ entry = _ref[_i];
+ this.insertEntry(entry, menu, data);
+ }
+ $.addClass(lastToggledButton, 'active');
+ $.on(d, 'click', this.close);
+ $.on(d, 'CloseMenu', this.close);
+ $.add(Header.hover, 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 subEntry, submenu, _i, _len, _ref;
+ if (typeof entry.open === 'function') {
+ if (!entry.open(data)) {
+ return;
+ }
+ }
+ $.add(parent, entry.el);
+ if (!entry.subEntries) {
+ return;
+ }
+ if (submenu = $('.submenu', entry.el)) {
+ $.rm(submenu);
+ }
+ submenu = $.el('div', {
+ className: 'dialog submenu'
+ });
+ _ref = entry.subEntries;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ subEntry = _ref[_i];
+ this.insertEntry(subEntry, submenu, data);
+ }
+ $.add(entry.el, submenu);
+ };
+
+ Menu.prototype.close = function() {
+ $.rm(currentMenu);
+ $.rmClass(lastToggledButton, 'active');
+ currentMenu = null;
+ lastToggledButton = null;
+ return $.off(d, 'click 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', currentMenu);
+ 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.focus = function(entry) {
+ var bottom, cHeight, cWidth, eRect, focused, left, right, sRect, style, submenu, top, _i, _len, _ref, _ref1, _ref2;
+ while (focused = $.x('parent::*/child::*[contains(@class,"focused")]', entry)) {
+ $.rmClass(focused, 'focused');
+ }
+ _ref = $$('.focused', entry);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ focused = _ref[_i];
+ $.rmClass(focused, 'focused');
+ }
+ $.addClass(entry, 'focused');
+ if (!(submenu = $('.submenu', entry))) {
+ return;
+ }
+ sRect = submenu.getBoundingClientRect();
+ eRect = entry.getBoundingClientRect();
+ cHeight = doc.clientHeight;
+ cWidth = doc.clientWidth;
+ _ref1 = eRect.top + sRect.height < cHeight ? ['0px', 'auto'] : ['auto', '0px'], top = _ref1[0], bottom = _ref1[1];
+ _ref2 = eRect.right + sRect.width < cWidth - 150 ? ['100%', 'auto'] : ['auto', '100%'], left = _ref2[0], right = _ref2[1];
+ style = submenu.style;
+ style.top = top;
+ style.bottom = bottom;
+ style.left = left;
+ return style.right = right;
+ };
+
+ Menu.prototype.addEntry = function(e) {
+ var entry;
+ entry = e.detail;
+ if (entry.type !== this.type) {
+ return;
+ }
+ this.parseEntry(entry);
+ return this.entries.push(entry);
+ };
+
+ Menu.prototype.parseEntry = function(entry) {
+ var el, subEntries, subEntry, _i, _len;
+ el = entry.el, subEntries = entry.subEntries;
+ $.addClass(el, 'entry');
+ $.on(el, 'focus mouseover', (function(e) {
+ e.stopPropagation();
+ return this.focus(el);
+ }).bind(this));
+ el.style.order = entry.order || 100;
+ if (!subEntries) {
+ return;
+ }
+ $.addClass(el, 'has-submenu');
+ for (_i = 0, _len = subEntries.length; _i < _len; _i++) {
+ subEntry = subEntries[_i];
+ this.parseEntry(subEntry);
+ }
+ };
+
+ return Menu;
+
+ })();
+ dragstart = function(e) {
+ var el, isTouching, o, rect, screenHeight, screenWidth, _ref;
+ 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 touch, _i, _len, _ref;
+ _ref = e.changedTouches;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ touch = _ref[_i];
+ if (touch.identifier === this.identifier) {
+ drag.call(this, touch);
+ return;
+ }
+ }
+ };
+ drag = function(e) {
+ var bottom, clientX, clientY, left, right, style, top;
+ clientX = e.clientX, clientY = e.clientY;
+ left = clientX - this.dx;
+ left = left < 10 ? 0 : this.width - left < 10 ? 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 touch, _i, _len, _ref;
+ _ref = e.changedTouches;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ touch = _ref[_i];
+ if (touch.identifier === this.identifier) {
+ dragend.call(this);
+ return;
+ }
+ }
+ };
+ dragend = function() {
+ if (this.isTouching) {
+ $.off(d, 'touchmove', this.move);
+ $.off(d, 'touchend touchcancel', this.up);
+ } else {
+ $.off(d, 'mousemove', this.move);
+ $.off(d, 'mouseup', this.up);
+ }
+ return $.set("" + this.id + ".position", this.style.cssText);
+ };
+ hoverstart = function(_arg) {
+ var asapTest, cb, el, endEvents, latestEvent, o, root;
+ root = _arg.root, el = _arg.el, latestEvent = _arg.latestEvent, endEvents = _arg.endEvents, asapTest = _arg.asapTest, cb = _arg.cb;
+ o = {
+ root: root,
+ el: el,
+ style: el.style,
+ cb: cb,
+ endEvents: endEvents,
+ latestEvent: latestEvent,
+ clientHeight: doc.clientHeight,
+ clientWidth: doc.clientWidth
+ };
+ o.hover = hover.bind(o);
+ o.hoverend = hoverend.bind(o);
+ $.asap(function() {
+ return !el.parentNode || asapTest();
+ }, function() {
+ if (el.parentNode) {
+ return o.hover(o.latestEvent);
+ }
+ });
+ $.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();
+ }
+ };
+ return $.on(doc, 'mousemove', o.workaround);
+ };
+ hover = function(e) {
+ var clientX, clientY, height, left, right, style, top, _ref;
+ this.latestEvent = e;
+ height = this.el.offsetHeight;
+ clientX = e.clientX, clientY = e.clientY;
+ top = clientY - 120;
+ top = this.clientHeight <= height || top <= 0 ? 0 : top + height >= this.clientHeight ? this.clientHeight - height : top;
+ _ref = clientX <= this.clientWidth - 400 ? [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;
+ }
+ $.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);
+ }
+ };
+ return {
+ dialog: dialog,
+ Menu: Menu,
+ hover: hoverstart
+ };
+ })();
+
+ Anonymize = {
+ init: function() {
+ if (g.VIEW === 'catalog' || !Conf['Anonymize']) {
+ return;
+ }
+ return Post.callbacks.push({
+ name: 'Anonymize',
+ cb: this.node
+ });
+ },
+ node: function() {
+ var email, name, tripcode, _ref;
+ 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;
+ }
+ }
+ };
+
+ Filter = {
+ filters: {},
+ init: function() {
+ var boards, err, filter, hl, key, op, regexp, stub, top, _i, _len, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
+ if (g.VIEW === 'catalog' || !Conf['Filter']) {
+ return;
+ }
+ if (!Conf['Filtered Backlinks']) {
+ $.addClass(doc, 'hide-backlinks');
+ }
+ for (key in Config.filter) {
+ this.filters[key] = [];
+ _ref = Conf[key].split('\n');
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ filter = _ref[_i];
+ if (filter[0] === '#') {
+ continue;
+ }
+ if (!(regexp = filter.match(/\/(.+)\/(\w*)/))) {
+ continue;
+ }
+ filter = filter.replace(regexp[0], '');
+ boards = ((_ref1 = filter.match(/boards:([^;]+)/)) != null ? _ref1[1].toLowerCase() : void 0) || 'global';
+ if (boards !== 'global' && (_ref2 = g.BOARD.ID, __indexOf.call(boards.split(','), _ref2) < 0)) {
+ continue;
+ }
+ if (key === 'uniqueID' || key === 'MD5') {
+ regexp = regexp[1];
+ } else {
+ try {
+ regexp = RegExp(regexp[1], regexp[2]);
+ } catch (_error) {
+ err = _error;
+ new Notice('warning', err.message, 60);
+ continue;
+ }
+ }
+ op = ((_ref3 = filter.match(/[^t]op:(yes|no|only)/)) != null ? _ref3[1] : void 0) || 'yes';
+ stub = (function() {
+ var _ref4;
+ switch ((_ref4 = filter.match(/stub:(yes|no)/)) != null ? _ref4[1] : void 0) {
+ case 'yes':
+ return true;
+ case 'no':
+ return false;
+ default:
+ return Conf['Stubs'];
+ }
+ })();
+ if (hl = /highlight/.test(filter)) {
+ hl = ((_ref4 = filter.match(/highlight:(\w+)/)) != null ? _ref4[1] : void 0) || 'filter-highlight';
+ top = ((_ref5 = filter.match(/top:(yes|no)/)) != null ? _ref5[1] : void 0) || 'yes';
+ top = top === 'yes';
+ }
+ this.filters[key].push(this.createFilter(regexp, 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, 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, isReply) {
+ if (isReply && op === 'only' || !isReply && op === 'no') {
+ return false;
+ }
+ if (!test(value)) {
+ return false;
+ }
+ return settings;
+ };
+ },
+ node: function() {
+ var filter, key, result, value, _i, _len, _ref;
+ if (this.isClone) {
+ return;
+ }
+ for (key in Filter.filters) {
+ value = Filter[key](this);
+ if (value === false) {
+ continue;
+ }
+ _ref = Filter.filters[key];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ filter = _ref[_i];
+ if (!(result = filter(value, this.isReply))) {
+ continue;
+ }
+ if (result.hide) {
+ 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.isReply && result.top) {
+ this.thread.isOnTop = true;
+ }
+ }
+ }
+ },
+ name: function(post) {
+ if ('name' in post.info) {
+ return post.info.name;
+ }
+ return false;
+ },
+ uniqueID: function(post) {
+ if ('uniqueID' in post.info) {
+ return post.info.uniqueID;
+ }
+ return false;
+ },
+ tripcode: function(post) {
+ if ('tripcode' in post.info) {
+ return post.info.tripcode;
+ }
+ return false;
+ },
+ capcode: function(post) {
+ if ('capcode' in post.info) {
+ return post.info.capcode;
+ }
+ return false;
+ },
+ email: function(post) {
+ if ('email' in post.info) {
+ return post.info.email;
+ }
+ return false;
+ },
+ subject: function(post) {
+ if ('subject' in post.info) {
+ return post.info.subject || false;
+ }
+ return false;
+ },
+ comment: function(post) {
+ if ('comment' in post.info) {
+ return post.info.comment;
+ }
+ return false;
+ },
+ flag: function(post) {
+ if ('flag' in post.info) {
+ return post.info.flag;
+ }
+ return false;
+ },
+ filename: function(post) {
+ if (post.file) {
+ return post.file.name;
+ }
+ return false;
+ },
+ dimensions: function(post) {
+ if (post.file && post.file.isImage) {
+ return post.file.dimensions;
+ }
+ return false;
+ },
+ filesize: function(post) {
+ if (post.file) {
+ return post.file.size;
+ }
+ return false;
+ },
+ MD5: function(post) {
+ if (post.file) {
+ return post.file.MD5;
+ }
+ return false;
+ },
+ menu: {
+ init: function() {
+ var div, entry, type, _i, _len, _ref;
+ if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Filter']) {
+ return;
+ }
+ div = $.el('div', {
+ textContent: 'Filter'
+ });
+ entry = {
+ type: 'post',
+ el: div,
+ order: 50,
+ open: function(post) {
+ Filter.menu.post = post;
+ return true;
+ },
+ subEntries: []
+ };
+ _ref = [['Name', 'name'], ['Unique ID', 'uniqueID'], ['Tripcode', 'tripcode'], ['Capcode', 'capcode'], ['E-mail', 'email'], ['Subject', 'subject'], ['Comment', 'comment'], ['Flag', 'flag'], ['Filename', 'filename'], ['Image dimensions', 'dimensions'], ['Filesize', 'filesize'], ['Image MD5', 'MD5']];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ type = _ref[_i];
+ entry.subEntries.push(Filter.menu.createSubEntry(type[0], type[1]));
+ }
+ return $.event('AddMenuEntry', 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 !== false;
+ }
+ };
+ },
+ 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() {
+ if (g.VIEW === 'catalog' || !Conf['Reply Hiding Buttons'] && !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;
+ if (!this.isReply || this.isClone) {
+ 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;
+ }
+ return $.replace($('.sideArrows', this.nodes.root), PostHiding.makeButton(this, 'hide'));
+ },
+ menu: {
+ init: function() {
+ var apply, div, hideStubLink, makeStub, replies, thisPost;
+ if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Reply Hiding Link']) {
+ return;
+ }
+ div = $.el('div', {
+ className: 'hide-reply-link',
+ textContent: 'Hide reply'
+ });
+ apply = $.el('a', {
+ textContent: 'Apply',
+ href: 'javascript:;'
+ });
+ $.on(apply, 'click', PostHiding.menu.hide);
+ thisPost = $.el('label', {
+ innerHTML: ' This post'
+ });
+ replies = $.el('label', {
+ innerHTML: " Hide replies"
+ });
+ makeStub = $.el('label', {
+ innerHTML: " Make stub"
+ });
+ $.event('AddMenuEntry', {
+ type: 'post',
+ 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 reply'
+ });
+ apply = $.el('a', {
+ textContent: 'Apply',
+ href: 'javascript:;'
+ });
+ $.on(apply, 'click', PostHiding.menu.show);
+ thisPost = $.el('label', {
+ innerHTML: ' This post'
+ });
+ replies = $.el('label', {
+ innerHTML: " Show replies"
+ });
+ hideStubLink = $.el('a', {
+ textContent: 'Hide stub',
+ href: 'javascript:;'
+ });
+ $.on(hideStubLink, 'click', PostHiding.menu.hideStub);
+ $.event('AddMenuEntry', {
+ type: 'post',
+ 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 $.event('AddMenuEntry', {
+ type: 'post',
+ 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 post;
+ post = PostHiding.menu.post;
+ post.nodes.root.hidden = true;
+ $.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, postInfo, quotelink, _i, _len, _ref;
+ if (makeStub == null) {
+ makeStub = Conf['Stubs'];
+ }
+ if (hideRecursively == null) {
+ hideRecursively = Conf['Recursive Hiding'];
+ }
+ if (post.isHidden) {
+ return;
+ }
+ post.isHidden = true;
+ if (hideRecursively) {
+ Recursive.apply(PostHiding.hide, post, makeStub, true);
+ Recursive.add(PostHiding.hide, post, makeStub, true);
+ }
+ _ref = Get.allQuotelinksLinkingTo(post);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ quotelink = _ref[_i];
+ $.addClass(quotelink, 'filtered');
+ }
+ if (!makeStub) {
+ post.nodes.root.hidden = true;
+ return;
+ }
+ a = PostHiding.makeButton(post, 'show');
+ postInfo = Conf['Anonymize'] ? 'Anonymous' : $('.nameBlock', post.nodes.info).textContent;
+ $.add(a, $.tn(" " + postInfo));
+ post.nodes.stub = $.el('div', {
+ className: 'stub'
+ });
+ $.add(post.nodes.stub, a);
+ if (Conf['Menu']) {
+ $.add(post.nodes.stub, Menu.makeButton());
+ }
+ return $.prepend(post.nodes.root, post.nodes.stub);
+ },
+ show: function(post, showRecursively) {
+ var quotelink, _i, _len, _ref;
+ if (showRecursively == null) {
+ showRecursively = Conf['Recursive Hiding'];
+ }
+ if (post.nodes.stub) {
+ $.rm(post.nodes.stub);
+ delete post.nodes.stub;
+ } else {
+ post.nodes.root.hidden = false;
+ }
+ post.isHidden = false;
+ if (showRecursively) {
+ Recursive.apply(PostHiding.show, post, true);
+ Recursive.rm(PostHiding.hide, post);
+ }
+ _ref = Get.allQuotelinksLinkingTo(post);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ quotelink = _ref[_i];
+ $.rmClass(quotelink, 'filtered');
+ }
+ }
+ };
+
+ Recursive = {
+ recursives: {},
+ init: function() {
+ if (g.VIEW === 'catalog') {
+ return;
+ }
+ return Post.callbacks.push({
+ name: 'Recursive',
+ cb: this.node
+ });
+ },
+ node: function() {
+ var i, obj, quote, recursive, _i, _j, _len, _len1, _ref, _ref1;
+ if (this.isClone) {
+ return;
+ }
+ _ref = this.quotes;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ quote = _ref[_i];
+ if (obj = Recursive.recursives[quote]) {
+ _ref1 = obj.recursives;
+ for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {
+ recursive = _ref1[i];
+ recursive.apply(null, [this].concat(__slice.call(obj.args[i])));
+ }
+ }
+ }
+ },
+ add: function() {
+ var args, obj, post, recursive, _base, _name;
+ recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
+ obj = (_base = Recursive.recursives)[_name = post.fullID] || (_base[_name] = {
+ recursives: [],
+ args: []
+ });
+ obj.recursives.push(recursive);
+ return obj.args.push(args);
+ },
+ rm: function(recursive, post) {
+ var i, obj, rec, _i, _len, _ref;
+ if (!(obj = Recursive.recursives[post.fullID])) {
+ return;
+ }
+ _ref = obj.recursives;
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+ rec = _ref[i];
+ if (rec === recursive) {
+ obj.recursives.splice(i, 1);
+ obj.args.splice(i, 1);
+ }
+ }
+ },
+ apply: function() {
+ var ID, args, fullID, post, recursive, _ref;
+ recursive = arguments[0], post = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];
+ fullID = post.fullID;
+ _ref = g.posts;
+ for (ID in _ref) {
+ post = _ref[ID];
+ if (__indexOf.call(post.quotes, fullID) >= 0) {
+ recursive.apply(null, [post].concat(__slice.call(args)));
+ }
+ }
+ }
+ };
+
+ ThreadHiding = {
+ init: function() {
+ if (g.VIEW !== 'index' || !Conf['Thread Hiding Buttons'] && !Conf['Thread Hiding Link']) {
+ return;
+ }
+ this.db = new DataBoard('hiddenThreads');
+ this.syncCatalog();
+ $.on(d, 'IndexBuild', this.onIndexBuild);
+ return Thread.callbacks.push({
+ name: 'Thread Hiding',
+ cb: this.node
+ });
+ },
+ node: function() {
+ var data;
+ if (data = ThreadHiding.db.get({
+ boardID: this.board.ID,
+ threadID: this.ID
+ })) {
+ ThreadHiding.hide(this, data.makeStub);
+ }
+ if (!Conf['Thread Hiding Buttons']) {
+ return;
+ }
+ return $.prepend(this.OP.nodes.root, ThreadHiding.makeButton(this, 'hide'));
+ },
+ onIndexBuild: function(_arg) {
+ var i, nodes, root, thread, _i, _len;
+ nodes = _arg.detail;
+ for (i = _i = 0, _len = nodes.length; _i < _len; i = _i += 2) {
+ root = nodes[i];
+ thread = Get.threadFromRoot(root);
+ if (!thread.isHidden) {
+ continue;
+ }
+ if (!thread.stub) {
+ nodes[i + 1].hidden = true;
+ } else if (!root.contains(thread.stub)) {
+ ThreadHiding.makeStub(thread, root);
+ }
+ }
+ },
+ syncCatalog: function() {
+ var hiddenThreads, hiddenThreadsOnCatalog, threadID;
+ hiddenThreads = ThreadHiding.db.get({
+ boardID: g.BOARD.ID,
+ defaultValue: {}
+ });
+ hiddenThreadsOnCatalog = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {};
+ for (threadID in hiddenThreadsOnCatalog) {
+ if (!(threadID in hiddenThreads)) {
+ hiddenThreads[threadID] = {};
+ }
+ }
+ for (threadID in hiddenThreads) {
+ if (!(threadID in hiddenThreadsOnCatalog)) {
+ delete hiddenThreads[threadID];
+ }
+ }
+ if ((ThreadHiding.db.data.lastChecked || 0) > Date.now() - $.MINUTE) {
+ ThreadHiding.cleanCatalog(hiddenThreadsOnCatalog);
+ }
+ return ThreadHiding.db.set({
+ boardID: g.BOARD.ID,
+ val: hiddenThreads
+ });
+ },
+ cleanCatalog: function(hiddenThreadsOnCatalog) {
+ return $.cache("//a.4cdn.org/" + g.BOARD + "/threads.json", function() {
+ var page, thread, threads, _i, _j, _len, _len1, _ref, _ref1;
+ if (this.status !== 200) {
+ return;
+ }
+ threads = {};
+ _ref = JSON.parse(this.response);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ page = _ref[_i];
+ _ref1 = page.threads;
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ thread = _ref1[_j];
+ if (thread.no in hiddenThreadsOnCatalog) {
+ threads[thread.no] = hiddenThreadsOnCatalog[thread.no];
+ }
+ }
+ }
+ if (Object.keys(threads).length) {
+ return localStorage.setItem("4chan-hide-t-" + g.BOARD, JSON.stringify(threads));
+ } else {
+ return localStorage.removeItem("4chan-hide-t-" + g.BOARD);
+ }
+ });
+ },
+ 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 thread'
+ });
+ apply = $.el('a', {
+ textContent: 'Apply',
+ href: 'javascript:;'
+ });
+ $.on(apply, 'click', ThreadHiding.menu.hide);
+ makeStub = $.el('label', {
+ innerHTML: " Make stub"
+ });
+ $.event('AddMenuEntry', {
+ type: 'post',
+ el: div,
+ order: 20,
+ open: function(_arg) {
+ var isReply, thread;
+ thread = _arg.thread, isReply = _arg.isReply;
+ if (isReply || thread.isHidden) {
+ return false;
+ }
+ ThreadHiding.menu.thread = thread;
+ return true;
+ },
+ subEntries: [
+ {
+ el: apply
+ }, {
+ el: makeStub
+ }
+ ]
+ });
+ div = $.el('a', {
+ className: 'show-thread-link',
+ textContent: 'Show thread',
+ href: 'javascript:;'
+ });
+ $.on(div, 'click', ThreadHiding.menu.show);
+ $.event('AddMenuEntry', {
+ type: 'post',
+ el: div,
+ order: 20,
+ open: function(_arg) {
+ var isReply, thread;
+ thread = _arg.thread, isReply = _arg.isReply;
+ if (isReply || !thread.isHidden) {
+ return false;
+ }
+ ThreadHiding.menu.thread = thread;
+ return true;
+ }
+ });
+ hideStubLink = $.el('a', {
+ textContent: 'Hide stub',
+ href: 'javascript:;'
+ });
+ $.on(hideStubLink, 'click', ThreadHiding.menu.hideStub);
+ return $.event('AddMenuEntry', {
+ type: 'post',
+ el: hideStubLink,
+ order: 15,
+ open: function(_arg) {
+ var isReply, thread;
+ thread = _arg.thread, isReply = _arg.isReply;
+ if (isReply || !thread.isHidden) {
+ 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.hide(thread, false);
+ $.event('CloseMenu');
+ }
+ },
+ makeButton: function(thread, type) {
+ var a;
+ a = $.el('a', {
+ className: "" + type + "-thread-button",
+ innerHTML: " ",
+ href: 'javascript:;'
+ });
+ a.dataset.fullID = thread.fullID;
+ $.on(a, 'click', ThreadHiding.toggle);
+ return a;
+ },
+ makeStub: function(thread, root) {
+ var a, numReplies, opInfo, summary;
+ numReplies = $$('.thread > .replyContainer', root).length;
+ if (summary = $('.summary', root)) {
+ numReplies += +summary.textContent.match(/\d+/);
+ }
+ opInfo = Conf['Anonymize'] ? 'Anonymous' : $('.nameBlock', thread.OP.nodes.info).textContent;
+ a = ThreadHiding.makeButton(thread, 'show');
+ $.add(a, $.tn(" " + opInfo + " (" + (numReplies === 1 ? '1 reply' : "" + numReplies + " replies") + ")"));
+ thread.stub = $.el('div', {
+ className: 'stub'
+ });
+ if (Conf['Menu']) {
+ $.add(thread.stub, [a, Menu.makeButton()]);
+ } else {
+ $.add(thread.stub, a);
+ }
+ return $.prepend(root, thread.stub);
+ },
+ saveHiddenState: function(thread, makeStub) {
+ var hiddenThreadsOnCatalog;
+ hiddenThreadsOnCatalog = JSON.parse(localStorage.getItem("4chan-hide-t-" + g.BOARD)) || {};
+ if (thread.isHidden) {
+ ThreadHiding.db.set({
+ boardID: thread.board.ID,
+ threadID: thread.ID,
+ val: {
+ makeStub: makeStub
+ }
+ });
+ hiddenThreadsOnCatalog[thread] = true;
+ } else {
+ ThreadHiding.db["delete"]({
+ boardID: thread.board.ID,
+ threadID: thread.ID
+ });
+ delete hiddenThreadsOnCatalog[thread];
+ }
+ return localStorage.setItem("4chan-hide-t-" + g.BOARD, JSON.stringify(hiddenThreadsOnCatalog));
+ },
+ 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 (!makeStub) {
+ return threadRoot.hidden = threadRoot.nextElementSibling.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;
+ return threadRoot.nextElementSibling.hidden = threadRoot.hidden = thread.isHidden = false;
+ }
+ };
+
+ QuoteBacklink = {
+ init: function() {
+ var format;
+ if (g.VIEW === 'catalog' || !Conf['Quote Backlinks']) {
+ return;
+ }
+ format = Conf['backlink'].replace(/%id/g, "' + id + '");
+ this.funk = Function('id', "return '" + format + "'");
+ this.containers = {};
+ 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, frag, link, post, quote, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
+ if (this.isClone || !this.quotes.length) {
+ return;
+ }
+ a = $.el('a', {
+ href: "/" + this.board + "/res/" + this.thread + "#p" + this,
+ className: this.isHidden ? 'filtered backlink' : 'backlink',
+ textContent: (QuoteBacklink.funk(this.ID)) + (Conf['Mark Quotes of You'] && this.info.yours ? '\u00A0(You)' : '')
+ });
+ _ref = this.quotes;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ quote = _ref[_i];
+ containers = [QuoteBacklink.getContainer(quote)];
+ if ((post = g.posts[quote]) && post.nodes.backlinkContainer) {
+ _ref1 = post.clones;
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ clone = _ref1[_j];
+ containers.push(clone.nodes.backlinkContainer);
+ }
+ }
+ for (_k = 0, _len2 = containers.length; _k < _len2; _k++) {
+ container = containers[_k];
+ frag = [$.tn(' '), link = a.cloneNode(true)];
+ if (Conf['Quote Previewing']) {
+ $.on(link, 'mouseover', QuotePreview.mouseover);
+ }
+ if (Conf['Quote Inlining']) {
+ $.on(link, 'click', QuoteInline.toggle);
+ if (Conf['Quote Hash Navigation']) {
+ frag.push.apply(frag, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
+ }
+ }
+ $.add(container, frag);
+ }
+ }
+ },
+ 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 _base;
+ return (_base = this.containers)[id] || (_base[id] = $.el('span', {
+ className: 'container'
+ }));
+ }
+ };
+
+ QuoteCT = {
+ init: function() {
+ if (g.VIEW === 'catalog' || !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, quotelink, thread, threadID, _i, _len, _ref, _ref1, _ref2;
+ if (this.isClone && this.thread === this.context.thread) {
+ return;
+ }
+ _ref = this.isClone ? this.context : this, board = _ref.board, thread = _ref.thread;
+ _ref1 = this.nodes.quotelinks;
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ quotelink = _ref1[_i];
+ _ref2 = Get.postDataFromLink(quotelink), boardID = _ref2.boardID, threadID = _ref2.threadID;
+ if (!threadID) {
+ continue;
+ }
+ if (this.isClone) {
+ quotelink.textContent = quotelink.textContent.replace(QuoteCT.text, '');
+ }
+ if (boardID === board.ID && threadID !== thread.ID) {
+ $.add(quotelink, $.tn(QuoteCT.text));
+ }
+ }
+ }
+ };
+
+ QuoteInline = {
+ init: function() {
+ if (g.VIEW === 'catalog' || !Conf['Quote Inlining']) {
+ return;
+ }
+ if (Conf['Quote Hash Navigation']) {
+ this.node = function() {
+ var link, _i, _len, _ref;
+ _ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks));
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ link = _ref[_i];
+ if (!this.isClone) {
+ $.after(link, QuoteInline.qiQuote(link, $.hasClass(link, 'filtered')));
+ }
+ $.on(link, 'click', QuoteInline.toggle);
+ }
+ };
+ } else {
+ this.node = function() {
+ var link, _i, _len, _ref;
+ _ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks));
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ link = _ref[_i];
+ $.on(link, 'click', QuoteInline.toggle);
+ }
+ };
+ }
+ if (Conf['Comment Expansion']) {
+ ExpandComment.callbacks.push(this.node);
+ }
+ return Post.callbacks.push({
+ name: 'Quote Inlining',
+ cb: this.node
+ });
+ },
+ qiQuote: function(link, hidden) {
+ return [
+ $.tn(' '), $.el('a', {
+ className: hidden ? 'hashlink filtered' : 'hashlink',
+ textContent: '#',
+ href: link.href
+ })
+ ];
+ },
+ toggle: function(e) {
+ var boardID, context, postID, threadID, _ref;
+ 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;
+ context = Get.contextFromNode(this);
+ if ($.hasClass(this, 'inlined')) {
+ QuoteInline.rm(this, boardID, threadID, postID, context);
+ } else {
+ if ($.x("ancestor::div[@id='p" + postID + "']", this)) {
+ return;
+ }
+ QuoteInline.add(this, boardID, threadID, postID, context);
+ }
+ 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) {
+ var inline, isBacklink, post, qroot, root;
+ isBacklink = $.hasClass(quotelink, 'backlink');
+ inline = $.el('div', {
+ id: "i" + postID,
+ className: 'inline'
+ });
+ root = QuoteInline.findRoot(quotelink, isBacklink);
+ $.after(root, inline);
+ qroot = $.x('ancestor::*[contains(@class,"postContainer")][1]', root);
+ $.addClass(qroot, 'hasInline');
+ Get.postClone(boardID, threadID, postID, inline, context);
+ 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, root, _ref;
+ isBacklink = $.hasClass(quotelink, 'backlink');
+ root = QuoteInline.findRoot(quotelink, isBacklink);
+ root = $.x("following-sibling::div[@id='i" + 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() {
+ if (g.VIEW === 'catalog' || !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.isClone ? this.context : this).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() {
+ if (g.VIEW === 'catalog' || !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 link, _i, _len, _ref;
+ _ref = this.nodes.quotelinks.concat(__slice.call(this.nodes.backlinks));
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ link = _ref[_i];
+ $.on(link, 'mouseover', QuotePreview.mouseover);
+ }
+ },
+ mouseover: function(e) {
+ var boardID, clone, origin, post, postID, posts, qp, quote, quoterID, threadID, _i, _j, _len, _len1, _ref, _ref1;
+ if ($.hasClass(this, 'inlined')) {
+ 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);
+ Get.postClone(boardID, threadID, postID, qp, Get.contextFromNode(this));
+ UI.hover({
+ root: this,
+ el: qp,
+ latestEvent: e,
+ endEvents: 'mouseout click',
+ cb: QuotePreview.mouseout,
+ asapTest: function() {
+ return qp.firstElementChild;
+ }
+ });
+ if (!(origin = g.posts["" + boardID + "." + postID])) {
+ return;
+ }
+ if (Conf['Quote Highlighting']) {
+ posts = [origin].concat(origin.clones);
+ posts.pop();
+ for (_i = 0, _len = posts.length; _i < _len; _i++) {
+ post = posts[_i];
+ $.addClass(post.nodes.post, 'qphl');
+ }
+ }
+ quoterID = $.x('ancestor::*[@id][1]', this).id.match(/\d+$/)[0];
+ clone = Get.postFromRoot(qp.firstChild);
+ _ref1 = clone.nodes.quotelinks.concat(__slice.call(clone.nodes.backlinks));
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ quote = _ref1[_j];
+ if (quote.hash.slice(2) === quoterID) {
+ $.addClass(quote, 'forwardlink');
+ }
+ }
+ },
+ mouseout: function() {
+ var clone, post, root, _i, _len, _ref;
+ 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 (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ post = _ref[_i];
+ $.rmClass(post.nodes.post, 'qphl');
+ }
+ }
+ };
+
+ QuoteStrikeThrough = {
+ init: function() {
+ if (g.VIEW === 'catalog' || !Conf['Reply Hiding Buttons'] && !Conf['Reply Hiding Link'] && !Conf['Filter']) {
+ return;
+ }
+ return Post.callbacks.push({
+ name: 'Strike-through Quotes',
+ cb: this.node
+ });
+ },
+ node: function() {
+ var boardID, postID, quotelink, _i, _len, _ref, _ref1, _ref2;
+ if (this.isClone) {
+ return;
+ }
+ _ref = this.nodes.quotelinks;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ quotelink = _ref[_i];
+ _ref1 = Get.postDataFromLink(quotelink), boardID = _ref1.boardID, postID = _ref1.postID;
+ if ((_ref2 = g.posts["" + boardID + "." + postID]) != null ? _ref2.isHidden : void 0) {
+ $.addClass(quotelink, 'filtered');
+ }
+ }
+ }
+ };
+
+ /*
+ <3 aeosynth
+ */
+
+
+ QuoteThreading = {
+ init: function() {
+ var input;
+ if (!(Conf['Quote Threading'] && g.VIEW === 'thread')) {
+ return;
+ }
+ this.enabled = true;
+ this.controls = $.el('span', {
+ innerHTML: ' Threading '
+ });
+ input = $('input', this.controls);
+ $.on(input, 'change', this.toggle);
+ $.event('AddMenuEntry', {
+ type: 'header',
+ el: this.controls,
+ order: 98
+ });
+ if (!Conf['Unread Count']) {
+ $.on(d, '4chanXInitFinished', this.setup);
+ }
+ return Post.callbacks.push({
+ name: 'Quote Threading',
+ cb: this.node
+ });
+ },
+ setup: function() {
+ $.off(d, '4chanXInitFinished', QuoteThreading.setup);
+ return QuoteThreading.force();
+ },
+ force: function() {
+ var ID, post, _ref;
+ _ref = g.posts;
+ for (ID in _ref) {
+ post = _ref[ID];
+ if (post.cb) {
+ post.cb(true);
+ }
+ }
+ },
+ node: function() {
+ var keys, len, post, posts, quote, _i, _len, _ref;
+ posts = g.posts;
+ if (this.isClone || !QuoteThreading.enabled) {
+ return;
+ }
+ if (Conf['Unread Count']) {
+ Unread.posts.push(this);
+ }
+ if (this.thread.OP === this || !(post = posts[this.fullID]) || post.isHidden) {
+ return;
+ }
+ keys = [];
+ len = g.BOARD.ID.length + 1;
+ _ref = this.quotes;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ quote = _ref[_i];
+ if ((quote.slice(len) < this.ID) && quote in posts) {
+ keys.push(quote);
+ }
+ }
+ if (keys.length !== 1) {
+ return;
+ }
+ this.threaded = keys[0];
+ return this.cb = QuoteThreading.nodeinsert;
+ },
+ nodeinsert: function(force) {
+ var bottom, height, post, posts, root, threadContainer, top, _ref;
+ post = g.posts[this.threaded];
+ if (this.thread.OP === post) {
+ return false;
+ }
+ posts = Unread.posts;
+ root = post.nodes.root;
+ if (!force) {
+ height = doc.clientHeight;
+ _ref = root.getBoundingClientRect(), bottom = _ref.bottom, top = _ref.top;
+ if (!((Conf['Unread Count'] && posts[post.ID]) || ((bottom < height) && (top > 0)))) {
+ return false;
+ }
+ }
+ if ($.hasClass(root, 'threadOP')) {
+ threadContainer = root.nextElementSibling;
+ post = Get.postFromRoot($.x('descendant::div[contains(@class,"postContainer")][last()]', threadContainer));
+ $.add(threadContainer, this.nodes.root);
+ } else {
+ threadContainer = $.el('div', {
+ className: 'threadContainer'
+ });
+ $.add(threadContainer, this.nodes.root);
+ $.after(root, threadContainer);
+ $.addClass(root, 'threadOP');
+ }
+ if (!Conf['Unread Count']) {
+ return true;
+ }
+ if (posts[post.ID]) {
+ posts.after(post, this);
+ } else {
+ posts.prepend(this);
+ }
+ return true;
+ },
+ toggle: function() {
+ var ID, container, containers, nodes, post, posts, thread, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
+ if (QuoteThreading.enabled = this.checked) {
+ QuoteThreading.force();
+ } else {
+ thread = $('.thread');
+ posts = [];
+ nodes = [];
+ _ref = g.posts;
+ for (ID in _ref) {
+ post = _ref[ID];
+ if (!(post === post.thread.OP || post.isClone)) {
+ posts.push(post);
+ }
+ }
+ posts.sort(function(a, b) {
+ return a.ID - b.ID;
+ });
+ for (_i = 0, _len = posts.length; _i < _len; _i++) {
+ post = posts[_i];
+ nodes.push(post.nodes.root);
+ }
+ $.add(thread, nodes);
+ containers = $$('.threadContainer', thread);
+ for (_j = 0, _len1 = containers.length; _j < _len1; _j++) {
+ container = containers[_j];
+ $.rm(container);
+ }
+ _ref1 = $$('.threadOP');
+ for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
+ post = _ref1[_k];
+ $.rmClass(post, 'threadOP');
+ }
+ }
+ },
+ kb: function() {
+ var control;
+ control = $.id('threadingControl');
+ control.checked = !control.checked;
+ return QuoteThreading.toggle.call(control);
+ }
+ };
+
+ QuoteYou = {
+ init: function() {
+ if (!(g.VIEW !== 'catalog' && Conf['Mark Quotes of You'] && Conf['Quick Reply'])) {
+ 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 quotelink, _i, _len, _ref;
+ if (this.isClone) {
+ return;
+ }
+ if (this.info.yours) {
+ $.addClass(this.nodes.root, 'yourPost');
+ }
+ if (!this.quotes.length) {
+ return;
+ }
+ _ref = this.nodes.quotelinks;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ quotelink = _ref[_i];
+ if (!(QR.db.get(Get.postDataFromLink(quotelink)))) {
+ continue;
+ }
+ $.add(quotelink, $.tn(QuoteYou.text));
+ $.addClass(quotelink, 'you');
+ $.addClass(this.nodes.root, 'quotesYou');
+ }
+ },
+ cb: {
+ seek: function(type) {
+ var highlight, post, posts, result, str;
+ if (!(Conf['Mark Quotes of You'] && Conf['Quick Reply'])) {
+ return;
+ }
+ if (highlight = $('.highlight')) {
+ $.rmClass(highlight, 'highlight');
+ }
+ if (!QuoteYou.lastRead) {
+ 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(post) {
+ if (Get.postFromRoot(post).isHidden) {
+ return false;
+ } else {
+ QuoteYou.lastRead = post;
+ window.location = "#" + post.id;
+ Header.scrollToPost(post);
+ $.addClass($('.post', post), 'highlight');
+ return true;
+ }
+ }
+ }
+ };
+
+ Quotify = {
+ init: function() {
+ if (g.VIEW === 'catalog' || !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, _i, _len, _ref;
+ _ref = $$('.deadlink', this.nodes.comment);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ deadlink = _ref[_i];
+ if (this.isClone) {
+ if ($.hasClass(deadlink, 'quotelink')) {
+ this.nodes.quotelinks.push(deadlink);
+ }
+ } else {
+ Quotify.parseDeadlink.call(this, deadlink);
+ }
+ }
+ },
+ parseDeadlink: function(deadlink) {
+ var a, boardID, 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: "/" + boardID + "/res/" + post.thread + "#p" + postID,
+ className: 'quotelink',
+ textContent: quote
+ });
+ } else {
+ a = $.el('a', {
+ href: "/" + boardID + "/res/" + post.thread + "#p" + postID,
+ className: 'quotelink deadlink',
+ target: '_blank',
+ textContent: "" + quote + "\u00A0(Dead)"
+ });
+ $.extend(a.dataset, {
+ boardID: boardID,
+ threadID: post.thread.ID,
+ postID: postID
+ });
+ }
+ } else if (redirect = Redirect.to('thread', {
+ boardID: boardID,
+ threadID: 0,
+ postID: postID
+ })) {
+ a = $.el('a', {
+ href: redirect,
+ className: 'deadlink',
+ target: '_blank',
+ textContent: "" + quote + "\u00A0(Dead)"
+ });
+ if (Redirect.to('post', {
+ boardID: boardID,
+ postID: postID
+ })) {
+ $.addClass(a, 'quotelink');
+ $.extend(a.dataset, {
+ boardID: boardID,
+ postID: postID
+ });
+ }
+ }
+ if (__indexOf.call(this.quotes, quoteID) < 0) {
+ this.quotes.push(quoteID);
+ }
+ if (!a) {
+ return deadlink.textContent = "" + quote + "\u00A0(Dead)";
+ }
+ $.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));
+ }
+ };
+
+ QR = {
+ init: function() {
+ var sc;
+ if (!Conf['Quick Reply']) {
+ return;
+ }
+ this.db = new DataBoard('yourPosts');
+ this.posts = [];
+ if (Conf['QR Shortcut']) {
+ sc = $.el('a', {
+ className: "qr-shortcut fa fa-comment-o " + (!Conf['Persistent QR'] ? 'disabled' : ''),
+ textContent: 'QR',
+ title: 'Quick Reply',
+ href: 'javascript:;'
+ });
+ $.on(sc, 'click', function() {
+ if (Conf['Persistent QR'] || !QR.nodes || QR.nodes.el.hidden) {
+ $.event('CloseMenu');
+ QR.open();
+ QR.nodes.com.focus();
+ return $.rmClass(this, 'disabled');
+ } else {
+ QR.close();
+ return $.addClass(this, 'disabled');
+ }
+ });
+ Header.addShortcut(sc);
+ }
+ if (Conf['Hide Original Post Form']) {
+ $.asap((function() {
+ return doc;
+ }), function() {
+ return $.addClass(doc, 'hide-original-post-form');
+ });
+ }
+ $.ready(this.initReady);
+ if (Conf['Persistent QR']) {
+ if (!(g.BOARD.ID === 'f' && g.VIEW === 'index')) {
+ $.on(d, '4chanXInitFinished', this.persist);
+ } else {
+ $.ready(this.persist);
+ }
+ }
+ return Post.callbacks.push({
+ name: 'Quick Reply',
+ cb: this.node
+ });
+ },
+ initReady: function() {
+ var link;
+ QR.postingIsEnabled = !!$.id('postForm');
+ if (!QR.postingIsEnabled) {
+ return;
+ }
+ link = $.el('h1', {
+ innerHTML: "" + (g.VIEW === 'thread' ? 'Reply to Thread' : 'Start a Thread') + " ",
+ className: "qr-link-container"
+ });
+ $.on(link.firstChild, 'click', function() {
+ $.event('CloseMenu');
+ QR.open();
+ QR.nodes.com.focus();
+ if (Conf['QR Shortcut']) {
+ return $.rmClass($('.qr-shortcut'), 'disabled');
+ }
+ });
+ $.before($.id('postForm'), link);
+ $.on(d, 'QRGetSelectedPost', function(_arg) {
+ var cb;
+ cb = _arg.detail;
+ return cb(QR.selected);
+ });
+ $.on(d, 'QRAddPreSubmitHook', function(_arg) {
+ var cb;
+ cb = _arg.detail;
+ return QR.preSubmitHooks.push(cb);
+ });
+ $.on(d, 'dragover', QR.dragOver);
+ $.on(d, 'drop', QR.dropFile);
+ $.on(d, 'dragstart dragend', QR.drag);
+ switch (g.VIEW) {
+ case 'index':
+ return $.on(d, 'IndexRefresh', QR.generatePostableThreadsList);
+ case 'thread':
+ return $.on(d, 'ThreadUpdate', function() {
+ if (g.DEAD) {
+ return QR.abort();
+ } else {
+ return QR.status();
+ }
+ });
+ }
+ },
+ node: function() {
+ return $.on($('a[title="Quote this post"]', this.nodes.info), 'click', QR.quote);
+ },
+ persist: function() {
+ if (!QR.postingIsEnabled) {
+ return;
+ }
+ QR.open();
+ if (Conf['Auto Hide QR'] || g.VIEW === 'catalog') {
+ return QR.hide();
+ }
+ },
+ open: function() {
+ var err;
+ if (QR.nodes) {
+ QR.nodes.el.hidden = false;
+ QR.unhide();
+ return;
+ }
+ try {
+ return QR.dialog();
+ } catch (_error) {
+ err = _error;
+ delete QR.nodes;
+ return Main.handleErrors({
+ message: 'Quick Reply dialog creation crashed.',
+ error: err
+ });
+ }
+ },
+ close: function() {
+ var post, _i, _len, _ref;
+ if (QR.req) {
+ QR.abort();
+ return;
+ }
+ QR.nodes.el.hidden = true;
+ QR.cleanNotifications();
+ d.activeElement.blur();
+ $.rmClass(QR.nodes.el, 'dump');
+ if (!Conf['Captcha Warning Notifications']) {
+ if (QR.captcha.isEnabled) {
+ $.rmClass(QR.captcha.nodes.input, 'error');
+ }
+ }
+ if (Conf['QR Shortcut']) {
+ $.toggleClass($('.qr-shortcut'), 'disabled');
+ }
+ new QR.post(true);
+ _ref = QR.posts.splice(0, QR.posts.length - 1);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ post = _ref[_i];
+ post["delete"]();
+ }
+ QR.cooldown.auto = false;
+ return QR.status();
+ },
+ focusin: function() {
+ return $.addClass(QR.nodes.el, 'focus');
+ },
+ focusout: function() {
+ return $.rmClass(QR.nodes.el, 'focus');
+ },
+ 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();
+ }
+ },
+ error: function(err) {
+ var el;
+ QR.open();
+ if (typeof err === 'string') {
+ el = $.tn(err);
+ } else {
+ el = err;
+ el.removeAttribute('style');
+ }
+ if (QR.captcha.isEnabled && /captcha|verification/i.test(el.textContent)) {
+ QR.captcha.nodes.input.focus();
+ if (Conf['Captcha Warning Notifications'] && !d.hidden) {
+ QR.notify(el);
+ } else {
+ $.addClass(QR.captcha.nodes.input, 'error');
+ $.on(QR.captcha.nodes.input, 'keydown', function() {
+ return $.rmClass(QR.captcha.nodes.input, 'error');
+ });
+ }
+ } else {
+ QR.notify(el);
+ }
+ if (d.hidden) {
+ return alert(el.textContent);
+ }
+ },
+ notify: function(el) {
+ var notice, notif;
+ notice = new Notice('warning', el);
+ if (!(Header.areNotificationsEnabled && d.hidden)) {
+ return QR.notifications.push(notice);
+ } else {
+ notif = new Notification(el.textContent, {
+ body: el.textContent,
+ icon: Favicon.logo
+ });
+ return notif.onclick = function() {
+ return window.focus();
+ };
+ }
+ },
+ notifications: [],
+ cleanNotifications: function() {
+ var notification, _i, _len, _ref;
+ _ref = QR.notifications;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ notification = _ref[_i];
+ 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 = 404;
+ 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;
+ },
+ quote: function(e) {
+ var caretPos, com, index, post, range, s, sel, text, thread, _ref;
+ if (e != null) {
+ e.preventDefault();
+ }
+ if (!QR.postingIsEnabled) {
+ return;
+ }
+ sel = d.getSelection();
+ post = Get.postFromNode(this);
+ text = ">>" + post + "\n";
+ if ((s = sel.toString().trim()) && post === Get.postFromNode(sel.anchorNode)) {
+ s = s.replace(/\n/g, '\n>');
+ text += ">" + s + "\n";
+ }
+ 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');
+ QR.cooldown.auto = true;
+ }
+ _ref = QR.nodes, com = _ref.com, thread = _ref.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);
+ QR.selected.save(thread);
+ if (Conf['QR Shortcut']) {
+ return $.rmClass($('.qr-shortcut'), 'disabled');
+ }
+ },
+ characterCount: function() {
+ var count, counter;
+ counter = QR.nodes.charCount;
+ count = QR.nodes.com.textLength;
+ counter.textContent = count;
+ counter.hidden = count < 1000;
+ return (count > 1500 ? $.addClass : $.rmClass)(counter, 'warning');
+ },
+ 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, _i, _len, _ref;
+ files = [];
+ _ref = e.clipboardData.items;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ item = _ref[_i];
+ 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');
+ },
+ handleBlob: function(blob) {
+ var _ref;
+ if (blob.type === null) {
+ return QR.error("Unsupported file type.");
+ }
+ if (_ref = blob.type, __indexOf.call(QR.mimeTypes, _ref) < 0) {
+ return QR.error("Unsupported file type.");
+ }
+ return QR.handleFiles([blob]);
+ },
+ handleUrl: function() {
+ var url;
+ url = prompt("Insert an url:");
+ if (url === null) {
+ return;
+ }
+ GM_xmlhttpRequest({
+ method: "GET",
+ url: url,
+ overrideMimeType: "text/plain; charset=x-user-defined",
+ onload: function(xhr) {
+ var data, end, header, i, mime, r, start, urlBlob;
+ r = xhr.responseText;
+ data = new Uint8Array(r.length);
+ i = 0;
+ while (i < r.length) {
+ data[i] = r.charCodeAt(i);
+ i++;
+ }
+ header = xhr.responseHeaders;
+ start = header.indexOf("Content-Type: ") + 14;
+ end = header.substr(start, header.length).indexOf("\n") - 1;
+ mime = header.substr(start, end);
+ if (mime === null) {
+ return;
+ }
+ urlBlob = new Blob([data], {
+ type: mime
+ });
+ urlBlob.name = url.substr(url.lastIndexOf('/') + 1, url.length);
+ QR.handleBlob(urlBlob);
+ return;
+ return {
+ onerror: function(xhr) {
+ return QR.error("Can't load image.");
+ }
+ };
+ }
+ });
+ },
+ handleFiles: function(files) {
+ var file, isSingle, max, _i, _len;
+ if (this !== QR) {
+ files = __slice.call(this.files);
+ this.value = null;
+ }
+ if (!files.length) {
+ return;
+ }
+ max = QR.nodes.fileInput.max;
+ isSingle = files.length === 1;
+ QR.cleanNotifications();
+ for (_i = 0, _len = files.length; _i < _len; _i++) {
+ file = files[_i];
+ QR.handleFile(file, isSingle, max);
+ }
+ if (!isSingle) {
+ return $.addClass(QR.nodes.el, 'dump');
+ }
+ },
+ handleFile: function(file, isSingle, max) {
+ var post, _ref;
+ if (file.size > max) {
+ QR.error("" + file.name + ": File too large (file: " + ($.bytesToString(file.size)) + ", max: " + ($.bytesToString(max)) + ").");
+ return;
+ } else if (_ref = file.type, __indexOf.call(QR.mimeTypes, _ref) < 0) {
+ if (!/^text/.test(file.type)) {
+ QR.error("" + file.name + ": Unsupported file type.");
+ return;
+ }
+ if (isSingle) {
+ post = QR.selected;
+ } else if ((post = QR.posts[QR.posts.length - 1]).com) {
+ post = new QR.post();
+ }
+ post.pasteText(file);
+ return;
+ }
+ if (isSingle) {
+ post = QR.selected;
+ } else if ((post = QR.posts[QR.posts.length - 1]).file) {
+ post = new QR.post();
+ }
+ return post.setFile(file);
+ },
+ openFileInput: function(e) {
+ var _ref;
+ e.stopPropagation();
+ if (e.shiftKey && e.type === 'click') {
+ return QR.selected.rmFile();
+ }
+ if (e.ctrlKey && e.type === 'click') {
+ $.addClass(QR.nodes.filename, 'edit');
+ QR.nodes.filename.focus();
+ return $.on(QR.nodes.filename, 'blur', function() {
+ return $.rmClass(QR.nodes.filename, 'edit');
+ });
+ }
+ if (e.target.nodeName === 'INPUT' || (e.keyCode && ((_ref = e.keyCode) !== 32 && _ref !== 13)) || e.ctrlKey) {
+ return;
+ }
+ e.preventDefault();
+ return QR.nodes.fileInput.click();
+ },
+ generatePostableThreadsList: function() {
+ var list, options, thread, val;
+ if (!QR.nodes) {
+ return;
+ }
+ list = QR.nodes.thread;
+ options = [list.firstChild];
+ for (thread in g.BOARD.threads) {
+ options.push($.el('option', {
+ value: thread,
+ textContent: "Thread No." + thread
+ }));
+ }
+ val = list.value;
+ $.rmAll(list);
+ $.add(list, options);
+ list.value = val;
+ if (!list.value) {
+ return;
+ }
+ return list.value = g.VIEW === 'thread' ? g.THREADID : 'new';
+ },
+ dialog: function() {
+ var check, dialog, elm, event, flagSelector, i, items, key, mimeTypes, name, node, nodes, save, value, _ref;
+ QR.nodes = nodes = {
+ el: dialog = UI.dialog('qr', 'top:0;right:0;', "
No selected file
")
+ };
+ _ref = {
+ move: '.move',
+ autohide: '#autohide',
+ thread: 'select',
+ threadPar: '#qr-thread-select',
+ close: '.close',
+ form: 'form',
+ dumpButton: '#dump-button',
+ urlButton: '#url-button',
+ name: '[data-name=name]',
+ email: '[data-name=email]',
+ sub: '[data-name=sub]',
+ com: '[data-name=com]',
+ dumpList: '#dump-list',
+ addPost: '#add-post',
+ charCount: '#char-count',
+ fileSubmit: '#file-n-submit',
+ filename: '#qr-filename',
+ fileContainer: '#qr-filename-container',
+ fileRM: '#qr-filerm',
+ fileExtras: '#qr-extras-container',
+ spoiler: '#qr-file-spoiler',
+ spoilerPar: '#qr-spoiler-label',
+ status: '[type=submit]',
+ fileInput: '[type=file]'
+ };
+ for (key in _ref) {
+ value = _ref[key];
+ nodes[key] = $(value, dialog);
+ }
+ check = {
+ jpg: 'image/jpeg',
+ pdf: 'application/pdf',
+ swf: 'application/x-shockwave-flash'
+ };
+ mimeTypes = $('ul.rules > li').textContent.trim().match(/: (.+)/)[1].toLowerCase().replace(/\w+/g, function(type) {
+ return check[type] || ("image/" + type);
+ });
+ QR.mimeTypes = mimeTypes.split(', ');
+ QR.mimeTypes.push('');
+ nodes.fileInput.max = $('input[name=MAX_FILE_SIZE]').value;
+ QR.spoiler = !!$('input[name=spoiler]');
+ if (QR.spoiler) {
+ $.addClass(QR.nodes.el, 'has-spoiler');
+ } else {
+ nodes.spoiler.parentElement.hidden = true;
+ }
+ if (g.BOARD.ID === 'f') {
+ nodes.flashTag = $.el('select', {
+ name: 'filetag',
+ innerHTML: "Hentai \nPorn \nJapanese \nAnime \nGame \nLoop \nOther "
+ });
+ nodes.flashTag.dataset["default"] = '4';
+ $.add(nodes.form, nodes.flashTag);
+ }
+ if (flagSelector = $('.flagSelector')) {
+ nodes.flag = flagSelector.cloneNode(true);
+ nodes.flag.dataset.name = 'flag';
+ nodes.flag.dataset["default"] = '0';
+ $.add(nodes.form, nodes.flag);
+ }
+ $.on(nodes.filename.parentNode, 'click keydown', QR.openFileInput);
+ items = $$('*', QR.nodes.el);
+ i = 0;
+ while (elm = items[i++]) {
+ $.on(elm, 'blur', QR.focusout);
+ $.on(elm, 'focus', QR.focusin);
+ }
+ $.on(nodes.autohide, 'change', QR.toggleHide);
+ $.on(nodes.close, 'click', QR.close);
+ $.on(nodes.dumpButton, 'click', function() {
+ return nodes.el.classList.toggle('dump');
+ });
+ $.on(nodes.urlButton, 'click', QR.handleUrl);
+ $.on(nodes.addPost, 'click', function() {
+ return new QR.post(true);
+ });
+ $.on(nodes.form, 'submit', QR.submit);
+ $.on(nodes.fileRM, 'click', function() {
+ return QR.selected.rmFile();
+ });
+ $.on(nodes.fileExtras, 'click', function(e) {
+ return e.stopPropagation();
+ });
+ $.on(nodes.spoiler, 'change', function() {
+ return QR.selected.nodes.spoiler.click();
+ });
+ $.on(nodes.fileInput, 'change', QR.handleFiles);
+ items = ['name', 'email', 'sub', 'com', 'filename', 'flag'];
+ i = 0;
+ save = function() {
+ return QR.selected.save(this);
+ };
+ while (name = items[i++]) {
+ if (!(node = nodes[name])) {
+ continue;
+ }
+ event = node.nodeName === 'SELECT' ? 'change' : 'input';
+ $.on(nodes[name], event, save);
+ }
+ if (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.init();
+ QR.captcha.init();
+ $.add(d.body, dialog);
+ return $.event('QRDialogCreation', null, dialog);
+ },
+ preSubmitHooks: [],
+ submit: function(e) {
+ var challenge, err, extra, filetag, formData, hook, options, post, response, textOnly, thread, threadID, _i, _len, _ref, _ref1;
+ 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();
+ if (g.BOARD.ID === 'f') {
+ filetag = QR.nodes.flashTag.value;
+ }
+ threadID = post.thread;
+ thread = g.BOARD.threads[threadID];
+ if (threadID === 'new') {
+ threadID = null;
+ if (g.BOARD.ID === 'vg' && !post.sub) {
+ err = 'New threads require a subject.';
+ } else if (!(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 file selected.';
+ } else if (post.file && thread.fileLimit) {
+ err = 'Max limit of image replies has been reached.';
+ } else {
+ _ref = QR.preSubmitHooks;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ hook = _ref[_i];
+ if (err = hook(post, thread)) {
+ break;
+ }
+ }
+ }
+ if (QR.captcha.isEnabled && !err) {
+ _ref1 = QR.captcha.getOne(), challenge = _ref1.challenge, response = _ref1.response;
+ if (!response) {
+ err = 'No valid captcha.';
+ }
+ }
+ 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: post.name,
+ email: post.email,
+ sub: post.sub,
+ com: post.com,
+ upfile: post.file,
+ filetag: filetag,
+ spoiler: post.spoiler,
+ flag: post.flag,
+ textonly: textOnly,
+ mode: 'regist',
+ pwd: QR.persona.pwd,
+ recaptcha_challenge_field: challenge,
+ recaptcha_response_field: response
+ };
+ 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. \n[Banned? ] [More info ]"
+ }));
+ }
+ };
+ extra = {
+ form: $.formData(formData),
+ upCallbacks: {
+ onload: function() {
+ QR.req.isUploadFinished = true;
+ QR.req.uploadEndTime = Date.now();
+ QR.req.progress = '...';
+ return QR.status();
+ },
+ onprogress: function(e) {
+ QR.req.progress = "" + (Math.round(e.loaded / e.total * 100)) + "%";
+ return QR.status();
+ }
+ }
+ };
+ QR.req = $.ajax($.id('postForm').parentNode.action, options, extra);
+ QR.req.uploadStartTime = Date.now();
+ QR.req.progress = '...';
+ return QR.status();
+ },
+ response: function() {
+ var URL, ban, board, captchasCount, err, h1, isReply, m, notif, post, postID, postsCount, req, resDoc, threadID, _, _ref, _ref1;
+ req = QR.req;
+ delete QR.req;
+ post = QR.posts[0];
+ post.unlock();
+ resDoc = req.response;
+ if (ban = $('.banType', resDoc)) {
+ board = $('.board', resDoc).innerHTML;
+ err = $.el('span', {
+ innerHTML: ban.textContent.toLowerCase() === 'banned' ? "You are banned on " + board + "! ;_; \nClick here to see the reason." : "You were issued a warning on " + board + " as " + ($('.nameBlock', resDoc).innerHTML) + ". \nReason: " + ($('.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 = 'You seem to have mistyped the CAPTCHA.';
+ }
+ QR.cooldown.auto = QR.captcha.isEnabled ? !!QR.captcha.captchas.length : err === 'Connection error with sys.4chan.org.' ? true : false;
+ QR.cooldown.set({
+ delay: 2
+ });
+ } else if (err.textContent && (m = err.textContent.match(/wait\s(\d+)\ssecond/i))) {
+ QR.cooldown.auto = QR.captcha.isEnabled ? !!QR.captcha.captchas.length : true;
+ QR.cooldown.set({
+ delay: m[1]
+ });
+ } else {
+ 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));
+ }
+ QR.persona.set(post);
+ _ref1 = h1.nextSibling.textContent.match(/thread:(\d+),no:(\d+)/), _ = _ref1[0], threadID = _ref1[1], postID = _ref1[2];
+ postID = +postID;
+ threadID = +threadID || postID;
+ isReply = threadID !== postID;
+ QR.db.set({
+ boardID: g.BOARD.ID,
+ threadID: threadID,
+ postID: postID,
+ val: true
+ });
+ ThreadUpdater.postID = postID;
+ $.event('QRPostSuccessful', {
+ board: g.BOARD,
+ threadID: threadID,
+ postID: postID
+ });
+ $.event('QRPostSuccessful_', {
+ threadID: threadID,
+ postID: postID
+ });
+ postsCount = QR.posts.length - 1;
+ QR.cooldown.auto = postsCount && isReply;
+ if (QR.cooldown.auto && QR.captcha.isEnabled && (captchasCount = QR.captcha.captchas.length) < 3 && captchasCount < postsCount) {
+ notif = new Notification('Quick reply warning', {
+ body: "You are running low on cached captchas. Cache count: " + captchasCount + ".",
+ icon: Favicon.logo
+ });
+ notif.onclick = function() {
+ QR.open();
+ QR.captcha.nodes.input.focus();
+ return window.focus();
+ };
+ notif.onshow = function() {
+ return setTimeout(function() {
+ return notif.close();
+ }, 7 * $.SECOND);
+ };
+ }
+ if (!(Conf['Persistent QR'] || QR.cooldown.auto)) {
+ QR.close();
+ } else {
+ post.rm();
+ }
+ QR.cooldown.set({
+ req: req,
+ post: post,
+ isReply: isReply,
+ threadID: threadID
+ });
+ URL = threadID === postID ? "/" + g.BOARD + "/res/" + threadID : g.VIEW === 'index' && !QR.cooldown.auto && Conf['Open Post in New Tab'] ? "/" + g.BOARD + "/res/" + threadID + "#p" + postID : void 0;
+ if (URL) {
+ if (Conf['Open Post in New Tab']) {
+ $.open(URL);
+ } else {
+ window.location = URL;
+ }
+ }
+ return QR.status();
+ },
+ 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();
+ }
+ };
+
+ QR.captcha = {
+ init: function() {
+ var container, imgContainer, input;
+ if (d.cookie.indexOf('pass_enabled=1') >= 0) {
+ return;
+ }
+ container = $.id('captchaContainer');
+ if (!(this.isEnabled = !!container)) {
+ return;
+ }
+ if (Conf['Auto-load captcha']) {
+ $.globalEval('loadRecaptcha()');
+ }
+ imgContainer = $.el('div', {
+ className: 'captcha-img',
+ title: 'Reload reCAPTCHA',
+ innerHTML: ' ',
+ hidden: true
+ });
+ input = $.el('input', {
+ className: 'captcha-input field',
+ title: 'Verification',
+ placeholder: 'Focus to load reCAPTCHA',
+ autocomplete: 'off',
+ spellcheck: false,
+ tabIndex: 45
+ });
+ this.nodes = {
+ img: imgContainer.firstChild,
+ input: input
+ };
+ $.on(input, 'focus', this.setup);
+ $.on(input, 'blur', QR.focusout);
+ $.on(input, 'focus', QR.focusin);
+ $.addClass(QR.nodes.el, 'has-captcha');
+ $.after(QR.nodes.com.parentNode, [imgContainer, input]);
+ this.setupObserver = new MutationObserver(this.afterSetup);
+ this.setupObserver.observe(container, {
+ childList: true
+ });
+ return this.afterSetup();
+ },
+ setup: function() {
+ return $.globalEval('loadRecaptcha()');
+ },
+ afterSetup: function() {
+ var challenge, img, input, setLifetime, _ref;
+ if (!(challenge = $.id('recaptcha_challenge_field_holder'))) {
+ return;
+ }
+ QR.captcha.setupObserver.disconnect();
+ delete QR.captcha.setupObserver;
+ setLifetime = function(e) {
+ return QR.captcha.lifetime = e.detail;
+ };
+ $.on(window, 'captcha:timeout', setLifetime);
+ $.globalEval('window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: RecaptchaState.timeout}))');
+ $.off(window, 'captcha:timeout', setLifetime);
+ _ref = QR.captcha.nodes, img = _ref.img, input = _ref.input;
+ img.parentNode.hidden = false;
+ $.off(input, 'focus', QR.captcha.setup);
+ $.on(input, 'keydown', QR.captcha.keydown.bind(QR.captcha));
+ $.on(img.parentNode, 'click', QR.captcha.reload.bind(QR.captcha));
+ $.get('captchas', [], function(_arg) {
+ var captchas;
+ captchas = _arg.captchas;
+ return QR.captcha.sync(captchas);
+ });
+ $.sync('captchas', QR.captcha.sync);
+ QR.captcha.nodes.challenge = challenge;
+ new MutationObserver(QR.captcha.load.bind(QR.captcha)).observe(challenge, {
+ childList: true
+ });
+ return QR.captcha.load();
+ },
+ sync: function(captchas) {
+ QR.captcha.captchas = captchas;
+ return QR.captcha.count();
+ },
+ getOne: function() {
+ var captcha, challenge, response;
+ this.clear();
+ if (captcha = this.captchas.shift()) {
+ challenge = captcha.challenge, response = captcha.response;
+ this.count();
+ $.set('captchas', this.captchas);
+ } else {
+ challenge = this.nodes.img.alt;
+ if (response = this.nodes.input.value) {
+ this.reload();
+ }
+ }
+ if (response) {
+ response = response.trim();
+ if (!/\s/.test(response)) {
+ response = "" + response + " " + response;
+ }
+ }
+ return {
+ challenge: challenge,
+ response: response
+ };
+ },
+ save: function() {
+ var response;
+ if (!(response = this.nodes.input.value.trim())) {
+ return;
+ }
+ this.captchas.push({
+ challenge: this.nodes.img.alt,
+ response: response,
+ timeout: this.timeout
+ });
+ this.count();
+ this.reload();
+ return $.set('captchas', this.captchas);
+ },
+ clear: function() {
+ var captcha, i, now, _i, _len, _ref;
+ if (!this.captchas.length) {
+ return;
+ }
+ now = Date.now();
+ _ref = this.captchas;
+ for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
+ 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;
+ if (!this.nodes.challenge.firstChild) {
+ return;
+ }
+ this.timeout = Date.now() + this.lifetime * $.SECOND - $.MINUTE;
+ challenge = this.nodes.challenge.firstChild.value;
+ this.nodes.img.alt = challenge;
+ this.nodes.img.src = "//www.google.com/recaptcha/api/image?c=" + challenge;
+ this.nodes.input.value = null;
+ return this.clear();
+ },
+ count: function() {
+ var count;
+ count = this.captchas ? this.captchas.length : 0;
+ this.nodes.input.placeholder = (function() {
+ switch (count) {
+ case 0:
+ return 'Verification (Shift + Enter to cache)';
+ case 1:
+ return 'Verification (1 cached captcha)';
+ default:
+ return "Verification (" + count + " cached captchas)";
+ }
+ })();
+ return this.nodes.input.alt = count;
+ },
+ reload: function(focus) {
+ $.globalEval('Recaptcha.reload("t")');
+ 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();
+ }
+ };
+
+ QR.cooldown = {
+ init: function() {
+ var key, setTimers, type,
+ _this = this;
+ if (!Conf['Cooldown']) {
+ return;
+ }
+ setTimers = function(e) {
+ return QR.cooldown.types = e.detail;
+ };
+ $.on(window, 'cooldown:timers', setTimers);
+ $.globalEval('window.dispatchEvent(new CustomEvent("cooldown:timers", {detail: cooldowns}))');
+ $.off(window, 'cooldown:timers', setTimers);
+ for (type in QR.cooldown.types) {
+ QR.cooldown.types[type] = +QR.cooldown.types[type];
+ }
+ QR.cooldown.upSpd = 0;
+ QR.cooldown.upSpdAccuracy = .5;
+ key = "cooldown." + g.BOARD;
+ $.get(key, {}, function(item) {
+ QR.cooldown.cooldowns = item[key];
+ return QR.cooldown.start();
+ });
+ return $.sync(key, QR.cooldown.sync);
+ },
+ start: function() {
+ if (!Conf['Cooldown']) {
+ return;
+ }
+ if (QR.cooldown.isCounting) {
+ return;
+ }
+ QR.cooldown.isCounting = true;
+ return QR.cooldown.count();
+ },
+ sync: function(cooldowns) {
+ var id;
+ for (id in cooldowns) {
+ QR.cooldown.cooldowns[id] = cooldowns[id];
+ }
+ return QR.cooldown.start();
+ },
+ set: function(data) {
+ var cooldown, delay, isReply, post, req, start, threadID, upSpd;
+ if (!Conf['Cooldown']) {
+ return;
+ }
+ req = data.req, post = data.post, isReply = data.isReply, threadID = data.threadID, delay = data.delay;
+ start = req ? req.uploadEndTime : Date.now();
+ if (delay) {
+ cooldown = {
+ delay: delay
+ };
+ } else {
+ if (post.file) {
+ upSpd = post.file.size / ((start - req.uploadStartTime) / $.SECOND);
+ QR.cooldown.upSpdAccuracy = ((upSpd > QR.cooldown.upSpd * .9) + QR.cooldown.upSpdAccuracy) / 2;
+ QR.cooldown.upSpd = upSpd;
+ }
+ cooldown = {
+ isReply: isReply,
+ threadID: threadID
+ };
+ }
+ QR.cooldown.cooldowns[start] = cooldown;
+ $.set("cooldown." + g.BOARD, QR.cooldown.cooldowns);
+ return QR.cooldown.start();
+ },
+ unset: function(id) {
+ delete QR.cooldown.cooldowns[id];
+ if (Object.keys(QR.cooldown.cooldowns).length) {
+ return $.set("cooldown." + g.BOARD, QR.cooldown.cooldowns);
+ } else {
+ return $["delete"]("cooldown." + g.BOARD);
+ }
+ },
+ count: function() {
+ var cooldown, cooldowns, elapsed, hasFile, isReply, maxTimer, now, post, seconds, start, type, types, upSpd, upSpdAccuracy, update, _ref;
+ if (!Object.keys(QR.cooldown.cooldowns).length) {
+ $["delete"]("" + g.BOARD + ".cooldown");
+ delete QR.cooldown.isCounting;
+ delete QR.cooldown.seconds;
+ QR.status();
+ return;
+ }
+ clearTimeout(QR.cooldown.timeout);
+ QR.cooldown.timeout = setTimeout(QR.cooldown.count, $.SECOND);
+ now = Date.now();
+ post = QR.posts[0];
+ isReply = post.thread !== 'new';
+ hasFile = !!post.file;
+ seconds = null;
+ _ref = QR.cooldown, types = _ref.types, cooldowns = _ref.cooldowns, upSpd = _ref.upSpd, upSpdAccuracy = _ref.upSpdAccuracy;
+ for (start in cooldowns) {
+ cooldown = cooldowns[start];
+ if ('delay' in cooldown) {
+ if (cooldown.delay) {
+ seconds = Math.max(seconds, cooldown.delay--);
+ } else {
+ seconds = Math.max(seconds, 0);
+ QR.cooldown.unset(start);
+ }
+ continue;
+ }
+ if (isReply === cooldown.isReply) {
+ elapsed = Math.floor((now - start) / $.SECOND);
+ if (elapsed < 0) {
+ continue;
+ }
+ type = !isReply ? 'thread' : hasFile ? 'image' : 'reply';
+ maxTimer = Math.max(types[type] || 0, types[type + '_intra'] || 0);
+ if (!((start <= now && now <= start + maxTimer * $.SECOND))) {
+ QR.cooldown.unset(start);
+ }
+ if (isReply && +post.thread === cooldown.threadID) {
+ type += '_intra';
+ }
+ seconds = Math.max(seconds, types[type] - elapsed);
+ }
+ }
+ if (seconds && Conf['Cooldown Prediction'] && hasFile && upSpd) {
+ seconds -= Math.floor(post.file.size / upSpd * upSpdAccuracy);
+ seconds = seconds > 0 ? seconds : 0;
+ }
+ update = seconds !== null || !!QR.cooldown.seconds;
+ QR.cooldown.seconds = seconds;
+ if (update) {
+ QR.status();
+ }
+ if (seconds === 0 && QR.cooldown.auto && !QR.req) {
+ return QR.submit();
+ }
+ }
+ };
+
+ QR.persona = {
+ pwd: '',
+ always: {},
+ init: function() {
+ QR.persona.getPassword();
+ return $.get('QR.personas', Conf['QR.personas'], function(_arg) {
+ var arr, item, personas, type, types, _i, _len, _ref;
+ personas = _arg['QR.personas'];
+ types = {
+ name: [],
+ email: [],
+ sub: []
+ };
+ _ref = personas.split('\n');
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ item = _ref[_i];
+ 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, type, val, _ref, _ref1, _ref2;
+ if (item[0] === '#') {
+ return;
+ }
+ if (!(match = item.match(/(name|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 === '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 list, val, _i, _len;
+ list = $("#list-" + type, QR.nodes.el);
+ for (_i = 0, _len = arr.length; _i < _len; _i++) {
+ val = arr[_i];
+ if (val) {
+ $.add(list, $.el('option', {
+ textContent: val
+ }));
+ }
+ }
+ },
+ getPassword: function() {
+ var input, m;
+ if (!QR.persona.pwd) {
+ QR.persona.pwd = (m = d.cookie.match(/4chan_pass=([^;]+)/)) ? decodeURIComponent(m[1]) : (input = $.id('postPassword')) ? input.value : $.id('delPassword').value;
+ }
+ 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,
+ email: /^sage$/.test(post.email) ? persona.email : post.email,
+ sub: Conf['Remember Subject'] ? post.sub : void 0,
+ flag: post.flag
+ };
+ return $.set('QR.persona', persona);
+ });
+ }
+ };
+
+ QR.post = (function() {
+ function _Class(select) {
+ this.select = __bind(this.select, this);
+ var el, elm, event, prev, _i, _j, _len, _len1, _ref, _ref1,
+ _this = this;
+ el = $.el('a', {
+ className: 'qr-preview',
+ draggable: true,
+ href: 'javascript:;',
+ innerHTML: ' Spoiler '
+ });
+ this.nodes = {
+ el: el,
+ rm: el.firstChild,
+ label: $('label', el),
+ spoiler: $('input', el),
+ span: el.lastChild
+ };
+ _ref = $$('*', el);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ elm = _ref[_i];
+ $.on(elm, 'blur', QR.focusout);
+ $.on(elm, 'focus', QR.focusin);
+ }
+ $.on(el, 'click', this.select);
+ $.on(this.nodes.rm, 'click', function(e) {
+ e.stopPropagation();
+ return _this.rm();
+ });
+ $.on(this.nodes.label, 'click', function(e) {
+ return e.stopPropagation();
+ });
+ $.on(this.nodes.spoiler, 'change', function(e) {
+ _this.spoiler = e.target.checked;
+ if (_this === QR.selected) {
+ return QR.nodes.spoiler.checked = _this.spoiler;
+ }
+ });
+ $.add(QR.nodes.dumpList, el);
+ _ref1 = ['dragStart', 'dragEnter', 'dragLeave', 'dragOver', 'dragEnd', 'drop'];
+ for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
+ event = _ref1[_j];
+ $.on(el, event.toLowerCase(), this[event]);
+ }
+ this.thread = g.VIEW === 'thread' ? g.THREADID : 'new';
+ prev = QR.posts[QR.posts.length - 1];
+ QR.posts.push(this);
+ this.nodes.spoiler.checked = this.spoiler = prev && Conf['Remember Spoiler'] ? prev.spoiler : false;
+ QR.persona.get(function(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 : prev && !/^sage$/.test(prev.email) ? prev.email : persona.email;
+ _this.sub = 'sub' in QR.persona.always ? QR.persona.always.sub : Conf['Remember Subject'] ? prev ? prev.sub : persona.sub : '';
+ if (QR.nodes.flag) {
+ _this.flag = prev ? prev.flag : persona.flag;
+ }
+ if (QR.selected === _this) {
+ return _this.load();
+ }
+ });
+ if (select) {
+ this.select();
+ }
+ this.unlock();
+ }
+
+ _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);
+ return URL.revokeObjectURL(this.URL);
+ };
+
+ _Class.prototype.lock = function(lock) {
+ var name, node, _i, _len, _ref;
+ if (lock == null) {
+ lock = true;
+ }
+ this.isLocked = lock;
+ if (this !== QR.selected) {
+ return;
+ }
+ _ref = ['thread', 'name', 'email', 'sub', 'com', 'fileButton', 'filename', 'spoiler', 'flag'];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ name = _ref[_i];
+ if (node = QR.nodes[name]) {
+ node.disabled = lock;
+ }
+ }
+ this.nodes.rm.style.visibility = lock ? 'hidden' : '';
+ (lock ? $.off : $.on)(QR.nodes.filename.previousElementSibling, 'click', QR.openFileInput);
+ 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.id = null;
+ 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;
+ this.load();
+ return $.event('QRPostSelection', this);
+ };
+
+ _Class.prototype.load = function() {
+ var name, node, _i, _len, _ref;
+ _ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'flag'];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ name = _ref[_i];
+ if (!(node = QR.nodes[name])) {
+ continue;
+ }
+ node.value = this[name] || node.dataset["default"] || null;
+ }
+ 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':
+ return QR.status();
+ case 'com':
+ this.nodes.span.textContent = this.com;
+ QR.characterCount();
+ 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.file.newName = this.filename.replace(/[/\\]/g, '-');
+ if (!/\.(jpe?g|png|gif|pdf|swf)$/i.test(this.filename)) {
+ this.file.newName += '.jpg';
+ }
+ return this.updateFilename();
+ }
+ };
+
+ _Class.prototype.forceSave = function() {
+ var name, node, _i, _len, _ref;
+ if (this !== QR.selected) {
+ return;
+ }
+ _ref = ['thread', 'name', 'email', 'sub', 'com', 'filename', 'spoiler', 'flag'];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ name = _ref[_i];
+ if (!(node = QR.nodes[name])) {
+ continue;
+ }
+ this.save(node);
+ }
+ };
+
+ _Class.prototype.setFile = function(file) {
+ this.file = file;
+ this.filename = file.name;
+ this.filesize = $.bytesToString(file.size);
+ if (QR.spoiler) {
+ this.nodes.label.hidden = false;
+ }
+ URL.revokeObjectURL(this.URL);
+ if (this === QR.selected) {
+ this.showFileData();
+ }
+ if (!/^image/.test(file.type)) {
+ this.nodes.el.style.backgroundImage = null;
+ return;
+ }
+ return this.setThumbnail();
+ };
+
+ _Class.prototype.setThumbnail = function() {
+ var fileURL, img,
+ _this = this;
+ img = $.el('img');
+ img.onload = function() {
+ var cv, height, s, width;
+ s = 90 * 2 * window.devicePixelRatio;
+ if (_this.file.type === 'image/gif') {
+ s *= 3;
+ }
+ height = img.height, width = img.width;
+ if (height < s || width < s) {
+ _this.URL = fileURL;
+ _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 = img.height = height;
+ cv.width = img.width = width;
+ cv.getContext('2d').drawImage(img, 0, 0, width, height);
+ URL.revokeObjectURL(fileURL);
+ return cv.toBlob(function(blob) {
+ _this.URL = URL.createObjectURL(blob);
+ return _this.nodes.el.style.backgroundImage = "url(" + _this.URL + ")";
+ });
+ };
+ fileURL = URL.createObjectURL(this.file);
+ return img.src = fileURL;
+ };
+
+ _Class.prototype.rmFile = function() {
+ if (this.isLocked) {
+ return;
+ }
+ delete this.file;
+ delete this.filename;
+ delete this.filesize;
+ this.nodes.el.title = null;
+ QR.nodes.fileContainer.title = '';
+ this.nodes.el.style.backgroundImage = null;
+ if (QR.spoiler) {
+ this.nodes.label.hidden = true;
+ }
+ this.showFileData();
+ return URL.revokeObjectURL(this.URL);
+ };
+
+ _Class.prototype.updateFilename = function() {
+ var long;
+ long = "" + this.filename + " (" + this.filesize + ")\nCtrl+click to edit filename. Shift+click to clear.";
+ this.nodes.el.title = long;
+ if (this !== QR.selected) {
+ return;
+ }
+ return QR.nodes.fileContainer.title = long;
+ };
+
+ _Class.prototype.showFileData = function() {
+ if (this.file) {
+ this.updateFilename();
+ QR.nodes.filename.value = this.filename;
+ QR.nodes.spoiler.checked = this.spoiler;
+ return $.addClass(QR.nodes.fileSubmit, 'has-file');
+ } else {
+ return $.rmClass(QR.nodes.fileSubmit, 'has-file');
+ }
+ };
+
+ _Class.prototype.pasteText = function(file) {
+ var reader,
+ _this = this;
+ reader = new FileReader();
+ reader.onload = function(e) {
+ var text;
+ text = e.target.result;
+ if (_this.com) {
+ _this.com += "\n" + text;
+ } else {
+ _this.com = text;
+ }
+ if (QR.selected === _this) {
+ QR.nodes.com.value = _this.com;
+ }
+ return _this.nodes.span.textContent = _this.com;
+ };
+ return reader.readAsText(file);
+ };
+
+ _Class.prototype.dragStart = function(e) {
+ e.dataTransfer.setDragImage(this, e.layerX, e.layerY);
+ 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;
+
+ })();
+
+ AutoGIF = {
+ init: function() {
+ var _ref;
+ if (g.VIEW === 'catalog' || !Conf['Auto-GIF'] || ((_ref = g.BOARD.ID) === 'gif' || _ref === 'wsg')) {
+ return;
+ }
+ return Post.callbacks.push({
+ name: 'Auto-GIF',
+ cb: this.node
+ });
+ },
+ node: function() {
+ var URL, gif, style, thumb, _ref, _ref1;
+ if (this.isClone || this.isHidden || this.thread.isHidden || !((_ref = this.file) != null ? _ref.isImage : void 0)) {
+ return;
+ }
+ _ref1 = this.file, thumb = _ref1.thumb, URL = _ref1.URL;
+ if (!(/gif$/.test(URL) && !/spoiler/.test(thumb.src))) {
+ return;
+ }
+ if (this.file.isSpoiler) {
+ style = thumb.style;
+ style.maxHeight = style.maxWidth = this.isReply ? '125px' : '250px';
+ }
+ gif = $.el('img');
+ $.on(gif, 'load', function() {
+ return thumb.src = URL;
+ });
+ return gif.src = URL;
+ }
+ };
+
+ FappeTyme = {
+ init: function() {
+ var el, input, lc, type, _i, _len, _ref;
+ if (!(Conf['Fappe Tyme'] || Conf['Werk Tyme']) || g.VIEW === 'catalog' || g.BOARD === 'f') {
+ return;
+ }
+ _ref = ["Fappe", "Werk"];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ type = _ref[_i];
+ if (!Conf["" + type + " Tyme"]) {
+ continue;
+ }
+ lc = type.toLowerCase();
+ el = $.el('label', {
+ innerHTML: " " + type + " Tyme",
+ title: "" + type + " Tyme"
+ });
+ FappeTyme[lc] = input = el.firstElementChild;
+ $.on(input, 'change', FappeTyme.cb.toggle.bind(input));
+ $.event('AddMenuEntry', {
+ type: 'header',
+ el: el,
+ order: 97
+ });
+ if (Conf[lc]) {
+ FappeTyme.cb.set(lc);
+ }
+ }
+ return Post.callbacks.push({
+ name: 'Fappe Tyme',
+ cb: this.node
+ });
+ },
+ node: function() {
+ if (this.file) {
+ return;
+ }
+ return $.addClass(this.nodes.root, "noFile");
+ },
+ cb: {
+ set: function(type) {
+ FappeTyme[type].checked = Conf[type];
+ return $["" + (Conf[type] ? 'add' : 'rm') + "Class"](doc, "" + type + "Tyme");
+ },
+ toggle: function() {
+ Conf[this.name] = !Conf[this.name];
+ FappeTyme.cb.set(this.name);
+ return $.cb.checked.call(FappeTyme[this.name]);
+ }
+ }
+ };
+
+ Gallery = {
+ init: function() {
+ var el;
+ if (g.VIEW === 'catalog' || g.BOARD === 'f' || !Conf['Gallery']) {
+ return;
+ }
+ 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.isImage : void 0)) {
+ return;
+ }
+ if (Gallery.nodes) {
+ Gallery.generateThumb($('.file', this.nodes.root));
+ 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 cb, createSubEntry, dialog, el, file, files, i, key, menuButton, name, nodes, value, _ref;
+ Gallery.images = [];
+ nodes = Gallery.nodes = {};
+ nodes.el = dialog = $.el('div', {
+ id: 'a-gallery',
+ innerHTML: "\n
\n \n × \n \n
\n
/ \n
\n
\n
\n
\n
\n
\n
"
+ });
+ _ref = {
+ 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');
+ cb = Gallery.cb;
+ $.on(nodes.frame, 'click', cb.blank);
+ $.on(nodes.current, 'click', cb.download);
+ $.on(nodes.next, 'click', cb.next);
+ $.on($('.gal-prev', dialog), 'click', cb.prev);
+ $.on($('.gal-next', dialog), 'click', cb.next);
+ $.on($('.gal-close', dialog), 'click', cb.close);
+ $.on(menuButton, 'click', function(e) {
+ return nodes.menu.toggle(e, this, g);
+ });
+ createSubEntry = Gallery.menu.createSubEntry;
+ for (name in Config.gallery) {
+ el = createSubEntry(name).el;
+ $.event('AddMenuEntry', {
+ type: 'gallery',
+ el: el,
+ order: 0
+ });
+ }
+ $.on(d, 'keydown', cb.keybinds);
+ $.off(d, 'keydown', Keybinds.keydown);
+ i = 0;
+ files = $$('.post .file');
+ while (file = files[i++]) {
+ if ($('.fileDeletedRes, .fileDeleted', file)) {
+ continue;
+ }
+ Gallery.generateThumb(file);
+ }
+ $.add(d.body, dialog);
+ nodes.thumbs.scrollTop = 0;
+ nodes.current.parentElement.scrollTop = 0;
+ Gallery.cb.open.call(image ? $("[href='" + (image.href.replace(/https?:/, '')) + "']", nodes.thumbs) : Gallery.images[0]);
+ d.body.style.overflow = 'hidden';
+ return nodes.total.textContent = --i;
+ },
+ generateThumb: function(file) {
+ var double, post, thumb, title;
+ post = Get.postFromNode(file);
+ title = ($('.fileText a', file)).textContent;
+ thumb = post.file.thumb.parentNode.cloneNode(true);
+ if (double = $('img + img', thumb)) {
+ $.rm(double);
+ }
+ thumb.className = 'gal-thumb';
+ thumb.title = title;
+ thumb.dataset.id = Gallery.images.length;
+ thumb.dataset.post = $('a[title="Highlight this post"]', post.nodes.info).href;
+ thumb.firstElementChild.style.cssText = '';
+ $.on(thumb, 'click', Gallery.cb.open);
+ Gallery.images.push(thumb);
+ return $.add(Gallery.nodes.thumbs, thumb);
+ },
+ cb: {
+ keybinds: function(e) {
+ var cb, key;
+ if (!(key = Keybinds.keyCode(e))) {
+ return;
+ }
+ cb = (function() {
+ switch (key) {
+ case 'Esc':
+ case Conf['Open Gallery']:
+ return Gallery.cb.close;
+ case 'Right':
+ case 'Enter':
+ return Gallery.cb.next;
+ case 'Left':
+ case '':
+ return Gallery.cb.prev;
+ }
+ })();
+ if (!cb) {
+ return;
+ }
+ e.stopPropagation();
+ e.preventDefault();
+ return cb();
+ },
+ open: function(e) {
+ var el, img, name, nodes, rect, top;
+ if (e) {
+ e.preventDefault();
+ }
+ if (!this) {
+ return;
+ }
+ nodes = Gallery.nodes;
+ name = nodes.name;
+ if (el = $('.gal-highlight', Gallery.thumbs)) {
+ $.rmClass(el, 'gal-highlight');
+ }
+ $.addClass(this, 'gal-highlight');
+ img = $.el('img', {
+ src: name.href = this.href,
+ title: name.download = name.textContent = this.title
+ });
+ $.extend(img.dataset, this.dataset);
+ $.replace(nodes.current, img);
+ nodes.count.textContent = +this.dataset.id + 1;
+ nodes.current = img;
+ nodes.frame.scrollTop = 0;
+ nodes.next.focus();
+ rect = this.getBoundingClientRect();
+ top = rect.top;
+ if (top > 0) {
+ top += rect.height - doc.clientHeight;
+ if (top < 0) {
+ return;
+ }
+ }
+ nodes.thumbs.scrollTop += top;
+ return $.on(img, 'error', function() {
+ return Gallery.cb.error(img, thumb);
+ });
+ },
+ image: function(e) {
+ e.preventDefault();
+ e.stopPropagation();
+ return Gallery.build(this);
+ },
+ error: function(img, thumb) {
+ var URL, post, revived, src;
+ post = Get.postFromLink($.el('a', {
+ href: img.dataset.post
+ }));
+ delete post.file.fullImage;
+ src = this.src.split('/');
+ if (src[2] === 'images.4chan.org') {
+ URL = Redirect.to('file', {
+ boardID: src[3],
+ filename: src[5]
+ });
+ if (URL) {
+ thumb.href = URL;
+ if (Gallery.nodes.current !== img) {
+ return;
+ }
+ revived = $.el('img', {
+ src: URL,
+ title: img.title
+ });
+ $.extend(revived.dataset, img.dataset);
+ $.replace(img, revived);
+ return;
+ }
+ if (g.DEAD || post.isDead || post.file.isDead) {
+ return;
+ }
+ }
+ return $.ajax("//api.4chan.org/" + post.board + "/res/" + post.thread + ".json", {
+ onload: function() {
+ var i, postObj;
+ if (this.status !== 200) {
+ return;
+ }
+ i = 0;
+ while (postObj = JSON.parse(this.response).posts[i++]) {
+ if (postObj.no === post.ID) {
+ break;
+ }
+ }
+ if (!postObj.no) {
+ return post.kill();
+ }
+ if (postObj.filedeleted) {
+ return post.kill(true);
+ }
+ }
+ });
+ },
+ prev: function() {
+ return Gallery.cb.open.call(Gallery.images[+Gallery.nodes.current.dataset.id - 1]);
+ },
+ next: function() {
+ return Gallery.cb.open.call(Gallery.images[+Gallery.nodes.current.dataset.id + 1]);
+ },
+ toggle: function() {
+ return (Gallery.nodes ? Gallery.cb.close : Gallery.build)();
+ },
+ blank: function(e) {
+ if (e.target === this) {
+ return Gallery.cb.close();
+ }
+ },
+ close: function() {
+ $.rm(Gallery.nodes.el);
+ delete Gallery.nodes;
+ d.body.style.overflow = '';
+ $.off(d, 'keydown', Gallery.cb.keybinds);
+ return $.on(d, 'keydown', Keybinds.keydown);
+ },
+ setFitness: function() {
+ return (this.checked ? $.addClass : $.rmClass)(doc, "gal-" + (this.name.toLowerCase().replace(/\s+/g, '-')));
+ }
+ },
+ menu: {
+ init: function() {
+ var createSubEntry, el, name, subEntries;
+ if (g.VIEW === 'catalog' || !Conf['Gallery']) {
+ return;
+ }
+ el = $.el('span', {
+ textContent: 'Gallery',
+ className: 'gallery-link'
+ });
+ createSubEntry = Gallery.menu.createSubEntry;
+ subEntries = [];
+ for (name in Config.gallery) {
+ subEntries.push(createSubEntry(name));
+ }
+ return $.event('AddMenuEntry', {
+ type: 'header',
+ el: el,
+ order: 105,
+ subEntries: subEntries
+ });
+ },
+ createSubEntry: function(name) {
+ var input, label;
+ label = $.el('label', {
+ innerHTML: " " + name
+ });
+ input = label.firstElementChild;
+ if (name === 'Fit Width' || name === 'Fit Height' || name === 'Hide Thumbnails') {
+ $.on(input, 'change', Gallery.cb.setFitness);
+ }
+ input.checked = Conf[name];
+ $.event('change', null, input);
+ $.on(input, 'change', $.cb.checked);
+ return {
+ el: label
+ };
+ }
+ }
+ };
+
+ ImageExpand = {
+ init: function() {
+ if (g.VIEW === 'catalog' || !Conf['Image Expansion']) {
+ return;
+ }
+ this.EAI = $.el('a', {
+ className: 'expand-all-shortcut fa fa-expand',
+ textContent: 'EAI',
+ title: 'Expand All Images',
+ href: 'javascript:;'
+ });
+ $.on(this.EAI, 'click', ImageExpand.cb.toggleAll);
+ Header.addShortcut(this.EAI, 3);
+ return Post.callbacks.push({
+ name: 'Image Expansion',
+ cb: this.node
+ });
+ },
+ node: function() {
+ var thumb, _ref;
+ if (!((_ref = this.file) != null ? _ref.isImage : void 0)) {
+ return;
+ }
+ thumb = this.file.thumb;
+ $.on(thumb.parentNode, 'click', ImageExpand.cb.toggle);
+ if (this.isClone && $.hasClass(thumb, 'expanding')) {
+ ImageExpand.contract(this);
+ ImageExpand.expand(this);
+ return;
+ }
+ if (ImageExpand.on && !this.isHidden && (Conf['Expand spoilers'] || !this.file.isSpoiler)) {
+ return ImageExpand.expand(this);
+ }
+ },
+ cb: {
+ toggle: function(e) {
+ if (e.shiftKey || e.altKey || e.ctrlKey || e.metaKey || e.button !== 0) {
+ return;
+ }
+ e.preventDefault();
+ return ImageExpand.toggle(Get.postFromNode(this));
+ },
+ toggleAll: function() {
+ var ID, file, func, post, _i, _len, _ref, _ref1;
+ $.event('CloseMenu');
+ 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;
+ }
+ _ref = g.posts;
+ for (ID in _ref) {
+ post = _ref[ID];
+ _ref1 = [post].concat(post.clones);
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ post = _ref1[_i];
+ file = post.file;
+ if (!(file && file.isImage && doc.contains(post.nodes.root))) {
+ continue;
+ }
+ if (ImageExpand.on && (!Conf['Expand spoilers'] && file.isSpoiler || Conf['Expand from here'] && Header.getTopOf(file.thumb) < 0)) {
+ continue;
+ }
+ $.queueTask(func, post);
+ }
+ }
+ },
+ setFitness: function() {
+ return (this.checked ? $.addClass : $.rmClass)(doc, this.name.toLowerCase().replace(/\s+/g, '-'));
+ }
+ },
+ toggle: function(post) {
+ var headRect, left, root, thumb, top, x, y, _ref;
+ thumb = post.file.thumb;
+ if (!(post.file.isExpanded || $.hasClass(thumb, 'expanding'))) {
+ ImageExpand.expand(post);
+ return;
+ }
+ root = post.nodes.root;
+ _ref = (Conf['Advance on contract'] ? (function() {
+ var next;
+ next = root;
+ while (next = $.x("following::div[contains(@class,'postContainer')][1]", next)) {
+ if ($('.stub', next) || next.offsetHeight === 0) {
+ continue;
+ }
+ return next;
+ }
+ return root;
+ })() : root).getBoundingClientRect(), top = _ref.top, left = _ref.left;
+ if (top < 0) {
+ y = top;
+ if (Conf['Fixed Header'] && !Conf['Bottom Header']) {
+ headRect = Header.bar.getBoundingClientRect();
+ y -= headRect.top + headRect.height;
+ }
+ }
+ if (left < 0) {
+ x = -window.scrollX;
+ }
+ if (x || y) {
+ window.scrollBy(x, y);
+ }
+ return ImageExpand.contract(post);
+ },
+ contract: function(post) {
+ $.rmClass(post.nodes.root, 'expanded-image');
+ $.rmClass(post.file.thumb, 'expanding');
+ return post.file.isExpanded = false;
+ },
+ expand: function(post, src) {
+ var img, thumb;
+ thumb = post.file.thumb;
+ if (post.isHidden || post.file.isExpanded || $.hasClass(thumb, 'expanding')) {
+ return;
+ }
+ $.addClass(thumb, 'expanding');
+ if (post.file.fullImage) {
+ $.asap((function() {
+ return post.file.fullImage.naturalHeight;
+ }), function() {
+ return ImageExpand.completeExpand(post);
+ });
+ return;
+ }
+ post.file.fullImage = img = $.el('img', {
+ className: 'full-image',
+ src: src || post.file.URL
+ });
+ $.on(img, 'error', ImageExpand.error);
+ $.asap((function() {
+ return post.file.fullImage.naturalHeight;
+ }), function() {
+ return ImageExpand.completeExpand(post);
+ });
+ return $.after(thumb, img);
+ },
+ completeExpand: function(post) {
+ var bottom, thumb;
+ thumb = post.file.thumb;
+ if (!$.hasClass(thumb, 'expanding')) {
+ return;
+ }
+ post.file.isExpanded = true;
+ if (!post.nodes.root.parentNode) {
+ $.addClass(post.nodes.root, 'expanded-image');
+ $.rmClass(post.file.thumb, 'expanding');
+ return;
+ }
+ bottom = post.nodes.root.getBoundingClientRect().bottom;
+ return $.queueTask(function() {
+ $.addClass(post.nodes.root, 'expanded-image');
+ $.rmClass(post.file.thumb, 'expanding');
+ if (!(bottom <= 0)) {
+ return;
+ }
+ return window.scrollBy(0, post.nodes.root.getBoundingClientRect().bottom - bottom);
+ });
+ },
+ error: function() {
+ var URL, post, src, timeoutID;
+ post = Get.postFromNode(this);
+ $.rm(this);
+ delete post.file.fullImage;
+ if (!($.hasClass(post.file.thumb, 'expanding') || $.hasClass(post.nodes.root, 'expanded-image'))) {
+ return;
+ }
+ ImageExpand.contract(post);
+ src = this.src.split('/');
+ if (src[2] === 'i.4cdn.org') {
+ URL = Redirect.to('file', {
+ boardID: src[3],
+ filename: src[5]
+ });
+ if (URL) {
+ setTimeout(ImageExpand.expand, 10000, post, URL);
+ return;
+ }
+ if (g.DEAD || post.isDead || post.file.isDead) {
+ return;
+ }
+ }
+ timeoutID = setTimeout(ImageExpand.expand, 10000, post);
+ return $.ajax("//a.4cdn.org/" + post.board + "/res/" + post.thread + ".json", {
+ onload: function() {
+ var postObj, _i, _len, _ref;
+ if (this.status !== 200) {
+ return;
+ }
+ _ref = JSON.parse(this.response).posts;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ postObj = _ref[_i];
+ if (postObj.no === post.ID) {
+ break;
+ }
+ }
+ if (postObj.no !== post.ID) {
+ clearTimeout(timeoutID);
+ return post.kill();
+ } else if (postObj.filedeleted) {
+ clearTimeout(timeoutID);
+ return post.kill(true);
+ }
+ }
+ });
+ },
+ menu: {
+ init: function() {
+ var conf, createSubEntry, el, name, subEntries, _ref;
+ if (g.VIEW === 'catalog' || !Conf['Image Expansion']) {
+ 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 $.event('AddMenuEntry', {
+ type: 'header',
+ el: el,
+ order: 105,
+ subEntries: subEntries
+ });
+ },
+ createSubEntry: function(name, desc) {
+ var input, label;
+ label = $.el('label', {
+ innerHTML: " " + name,
+ title: desc
+ });
+ input = label.firstElementChild;
+ if (name === 'Fit width' || name === 'Fit height') {
+ $.on(input, 'change', ImageExpand.cb.setFitness);
+ }
+ input.checked = Conf[name];
+ $.event('change', null, input);
+ $.on(input, 'change', $.cb.checked);
+ return {
+ el: label
+ };
+ }
+ }
+ };
+
+ ImageHover = {
+ init: function() {
+ if (g.VIEW === 'catalog' || !Conf['Image Hover']) {
+ return;
+ }
+ return Post.callbacks.push({
+ name: 'Image Hover',
+ cb: this.node
+ });
+ },
+ node: function() {
+ var _ref;
+ if (!((_ref = this.file) != null ? _ref.isImage : void 0)) {
+ return;
+ }
+ return $.on(this.file.thumb, 'mouseover', ImageHover.mouseover);
+ },
+ mouseover: function(e) {
+ var el, post;
+ post = Get.postFromNode(this);
+ el = $.el('img', {
+ id: 'ihover',
+ src: post.file.URL
+ });
+ el.dataset.fullID = post.fullID;
+ $.add(Header.hover, el);
+ UI.hover({
+ root: this,
+ el: el,
+ latestEvent: e,
+ endEvents: 'mouseout click',
+ asapTest: function() {
+ return el.naturalHeight;
+ }
+ });
+ return $.on(el, 'error', ImageHover.error);
+ },
+ error: function() {
+ var URL, post, src, timeoutID,
+ _this = this;
+ if (!doc.contains(this)) {
+ return;
+ }
+ post = g.posts[this.dataset.fullID];
+ src = this.src.split('/');
+ if (src[2] === 'i.4cdn.org') {
+ URL = Redirect.to('file', {
+ boardID: src[3],
+ filename: src[5].replace(/\?.+$/, '')
+ });
+ if (URL) {
+ this.src = URL;
+ return;
+ }
+ if (g.DEAD || post.isDead || post.file.isDead) {
+ return;
+ }
+ }
+ timeoutID = setTimeout((function() {
+ return _this.src = post.file.URL + '?' + Date.now();
+ }), 3000);
+ return $.ajax("//a.4cdn.org/" + post.board + "/res/" + post.thread + ".json", {
+ onload: function() {
+ var postObj, _i, _len, _ref;
+ if (this.status !== 200) {
+ return;
+ }
+ _ref = JSON.parse(this.response).posts;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ postObj = _ref[_i];
+ if (postObj.no === post.ID) {
+ break;
+ }
+ }
+ if (postObj.no !== post.ID) {
+ clearTimeout(timeoutID);
+ return post.kill();
+ } else if (postObj.filedeleted) {
+ clearTimeout(timeoutID);
+ return post.kill(true);
+ }
+ }
+ });
+ }
+ };
+
+ ImageLoader = {
+ init: function() {
+ var prefetch;
+ if (g.VIEW === 'catalog') {
+ return;
+ }
+ if (!(Conf["Image Prefetching"] || Conf["Replace JPG"] || Conf["Replace PNG"] || Conf["Replace GIF"])) {
+ return;
+ }
+ Post.callbacks.push({
+ name: 'Image Replace',
+ cb: this.node
+ });
+ if (!(Conf['Image Prefetching'] && g.VIEW === 'thread')) {
+ return;
+ }
+ prefetch = $.el('label', {
+ innerHTML: ' Prefetch Images'
+ });
+ this.el = prefetch.firstElementChild;
+ $.on(this.el, 'change', this.toggle);
+ return $.event('AddMenuEntry', {
+ type: 'header',
+ el: prefetch,
+ order: 104
+ });
+ },
+ node: function() {
+ var URL, img, string, style, thumb, type, _ref, _ref1;
+ if (this.isClone || this.isHidden || this.thread.isHidden || !((_ref = this.file) != null ? _ref.isImage : void 0)) {
+ return;
+ }
+ _ref1 = this.file, thumb = _ref1.thumb, URL = _ref1.URL;
+ if (!((Conf[string = "Replace " + ((type = (URL.match(/\w{3}$/))[0].toUpperCase()) === 'PEG' ? 'JPG' : type)] && !/spoiler/.test(thumb.src)) || Conf['prefetch'])) {
+ return;
+ }
+ if (this.file.isSpoiler) {
+ style = thumb.style;
+ style.maxHeight = style.maxWidth = this.isReply ? '125px' : '250px';
+ }
+ img = $.el('img');
+ if (Conf[string]) {
+ $.on(img, 'load', function() {
+ return thumb.src = URL;
+ });
+ }
+ return img.src = URL;
+ },
+ toggle: function() {
+ var enabled, id, post, _ref;
+ enabled = Conf['prefetch'] = this.checked;
+ if (enabled) {
+ _ref = g.threads["" + g.BOARD.ID + "." + g.THREADID].posts;
+ for (id in _ref) {
+ post = _ref[id];
+ ImageLoader.node.call(post);
+ }
+ }
+ }
+ };
+
+ RevealSpoilers = {
+ init: function() {
+ if (g.VIEW === 'catalog' || !Conf['Reveal Spoiler Thumbnails']) {
+ return;
+ }
+ return Post.callbacks.push({
+ cb: this.node
+ });
+ },
+ node: function() {
+ var thumb, _ref;
+ if (this.isClone || !((_ref = this.file) != null ? _ref.isSpoiler : void 0)) {
+ return;
+ }
+ thumb = this.file.thumb;
+ thumb.removeAttribute('style');
+ return thumb.src = this.file.thumbURL;
+ }
+ };
+
+ Sauce = {
+ init: function() {
+ var err, link, links, _i, _len, _ref;
+ if (g.VIEW === 'catalog' || !Conf['Sauce']) {
+ return;
+ }
+ links = [];
+ _ref = Conf['sauces'].split('\n');
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ link = _ref[_i];
+ try {
+ if (link[0] !== '#') {
+ links.push(this.createSauceLink(link.trim()));
+ }
+ } catch (_error) {
+ err = _error;
+ }
+ }
+ if (!links.length) {
+ return;
+ }
+ this.links = links;
+ this.link = $.el('a', {
+ target: '_blank'
+ });
+ return Post.callbacks.push({
+ name: 'Sauce',
+ cb: this.node
+ });
+ },
+ createSauceLink: function(link) {
+ var m, text;
+ link = link.replace(/%(T?URL|MD5|board)/ig, function(parameter) {
+ switch (parameter) {
+ case '%TURL':
+ return "' + encodeURIComponent(post.file.thumbURL) + '";
+ case '%URL':
+ return "' + encodeURIComponent(post.file.URL) + '";
+ case '%MD5':
+ return "' + encodeURIComponent(post.file.MD5) + '";
+ case '%board':
+ return "' + encodeURIComponent(post.board) + '";
+ default:
+ return parameter;
+ }
+ });
+ text = (m = link.match(/;text:(.+)$/)) ? m[1] : link.match(/(\w+)\.\w+\//)[1];
+ link = link.replace(/;text:.+$/, '');
+ return Function('post', 'a', "a.href = '" + link + "';\na.textContent = '" + text + "';\nreturn a;");
+ },
+ node: function() {
+ var link, nodes, _i, _len, _ref;
+ if (this.isClone || !this.file) {
+ return;
+ }
+ nodes = [];
+ _ref = Sauce.links;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ link = _ref[_i];
+ nodes.push($.tn('\u00A0'), link(this, Sauce.link.cloneNode(true)));
+ }
+ return $.add(this.file.text, nodes);
+ }
+ };
+
+ Linkify = {
+ init: function() {
+ if (g.VIEW === 'catalog' || !Conf['Linkify']) {
+ return;
+ }
+ this.regString = /((https?|mailto|git|magnet|ftp|irc):([a-z\d%\/])|[-a-z\d]+[.](aero|asia|biz|cat|com|coop|info|int|jobs|mobi|museum|name|net|org|post|pro|tel|travel|xxx|edu|gov|mil|[a-z]{2})(\/|(?!.))|[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}|[-\w\d.@]+@[a-z\d.-]+\.[a-z\d])/i;
+ if (Conf['Comment Expansion']) {
+ ExpandComment.callbacks.push(this.node);
+ }
+ if (Conf['Title Link']) {
+ $.sync('CachedTitles', Linkify.titleSync);
+ }
+ return Post.callbacks.push({
+ name: 'Linkify',
+ cb: this.node
+ });
+ },
+ node: function() {
+ var data, el, end, endNode, i, index, items, length, link, links, node, result, saved, snapshot, space, test, word, _i, _len, _ref;
+ if (this.isClone) {
+ if (Conf['Embedding']) {
+ i = 0;
+ items = $$('.embed', this.nodes.comment);
+ while (el = items[i++]) {
+ $.on(el, 'click', Linkify.cb.toggle);
+ if ($.hasClass(el, 'embedded')) {
+ Linkify.cb.toggle.call(el);
+ }
+ }
+ }
+ return;
+ }
+ test = /[^\s'"]+/g;
+ space = /[\s'"]/;
+ snapshot = $.X('.//br|.//text()', this.nodes.comment);
+ i = 0;
+ links = [];
+ while (node = snapshot.snapshotItem(i++)) {
+ data = node.data;
+ if (node.parentElement.nodeName === "A" || !data) {
+ 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') {
+ break;
+ }
+ endNode = saved;
+ data = saved.data;
+ word += data;
+ length = data.length;
+ if (end = space.exec(data)) {
+ test.lastIndex = length = end.index;
+ i--;
+ break;
+ }
+ }
+ }
+ if (Linkify.regString.exec(word)) {
+ links.push(Linkify.makeRange(node, endNode, index, length));
+ }
+ if (!(test.lastIndex && node === endNode)) {
+ break;
+ }
+ }
+ }
+ _ref = links.reverse();
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ link = _ref[_i];
+ this.nodes.links.push(Linkify.makeLink(link, this));
+ link.detach();
+ }
+ if (!(Conf['Embedding'] || Conf['Link Title'])) {
+ return;
+ }
+ links = this.nodes.links;
+ i = 0;
+ while (link = links[i++]) {
+ if (data = Linkify.services(link)) {
+ if (Conf['Embedding']) {
+ Linkify.embed(data);
+ }
+ if (Conf['Link Title']) {
+ Linkify.title(data);
+ }
+ }
+ }
+ },
+ 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, char, i, text;
+ text = range.toString();
+ i = 0;
+ while (/[(\[{<>]/.test(text.charAt(i))) {
+ i++;
+ }
+ if (i) {
+ 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(char = text.charAt(text.length - (1 + i)))) {
+ if (!(/[.,]/.test(char) || (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 (!/(https?|mailto|git|magnet|ftp|irc):/.test(text)) {
+ text = (/@/.test(text) ? 'mailto:' : 'http://') + text;
+ }
+ a = $.el('a', {
+ className: 'linkify',
+ rel: 'nofollow noreferrer',
+ target: '_blank',
+ href: text
+ });
+ $.add(a, range.extractContents());
+ range.insertNode(a);
+ return a;
+ },
+ services: function(link) {
+ var href, key, match, type, _ref;
+ href = link.href;
+ _ref = Linkify.types;
+ for (key in _ref) {
+ type = _ref[key];
+ if (!(match = type.regExp.exec(href))) {
+ continue;
+ }
+ return [key, match[1], match[2], link];
+ }
+ },
+ embed: function(data) {
+ var embed, href, key, link, name, options, uid, value, _ref;
+ key = data[0], uid = data[1], options = data[2], link = data[3];
+ href = link.href;
+ embed = $.el('a', {
+ className: 'embedder',
+ href: 'javascript:;',
+ textContent: '(embed)'
+ });
+ _ref = {
+ key: key,
+ href: href,
+ uid: uid,
+ options: options
+ };
+ for (name in _ref) {
+ value = _ref[name];
+ embed.dataset[name] = value;
+ }
+ embed.dataset.nodedata = link.innerHTML;
+ $.addClass(link, "" + embed.dataset.key);
+ $.on(embed, 'click', Linkify.cb.toggle);
+ $.after(link, [$.tn(' '), embed]);
+ if (Conf['Auto-embed']) {
+ Linkify.cb.toggle.call(embed);
+ }
+ data.push(embed);
+ },
+ title: function(data) {
+ var embed, err, key, link, options, service, title, titles, uid;
+ key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4];
+ if (!(service = Linkify.types[key].title)) {
+ return;
+ }
+ titles = Conf['CachedTitles'];
+ if (title = titles[uid]) {
+ if (link) {
+ link.textContent = title[0];
+ }
+ if (Conf['Embedding']) {
+ return embed.dataset.title = title[0];
+ }
+ } else {
+ try {
+ $.cache(service.api(uid), function() {
+ return title = Linkify.cb.title(this, data);
+ });
+ } catch (_error) {
+ err = _error;
+ if (link) {
+ link.innerHTML = "[" + key + "] Title Link Blocked (are you using NoScript?)";
+ }
+ return;
+ }
+ if (title) {
+ titles[uid] = [title, Date.now()];
+ return $.set('CachedTitles', titles);
+ }
+ }
+ },
+ titleSync: function(value) {
+ return Conf['CachedTitles'] = value;
+ },
+ cb: {
+ toggle: function() {
+ var string, _ref;
+ _ref = $.hasClass(this, "embedded") ? ['unembed', '(embed)'] : ['embed', '(unembed)'], string = _ref[0], this.textContent = _ref[1];
+ $.replace(this.previousElementSibling, Linkify.cb[string](this));
+ return $.toggleClass(this, 'embedded');
+ },
+ embed: function(a) {
+ var el, style, type;
+ el = (type = Linkify.types[a.dataset.key]).el(a);
+ el.style.cssText = (style = type.style) ? style : "border: 0; width: 640px; height: 390px";
+ return el;
+ },
+ unembed: function(a) {
+ var el;
+ el = $.el('a', {
+ rel: 'nofollow noreferrer',
+ target: 'blank',
+ className: 'linkify',
+ href: a.dataset.href,
+ innerHTML: a.dataset.title || a.dataset.nodedata
+ });
+ $.addClass(el, a.dataset.key);
+ return el;
+ },
+ title: function(response, data) {
+ var embed, key, link, options, service, text, uid;
+ key = data[0], uid = data[1], options = data[2], link = data[3], embed = data[4];
+ service = Linkify.types[key].title;
+ switch (response.status) {
+ case 200:
+ case 304:
+ text = "" + (service.text(JSON.parse(response.responseText)));
+ if (Conf['Embedding']) {
+ embed.dataset.title = text;
+ }
+ break;
+ case 404:
+ text = "[" + key + "] Not Found";
+ break;
+ case 403:
+ text = "[" + key + "] Forbidden or Private";
+ break;
+ default:
+ text = "[" + key + "] " + this.status + "'d";
+ }
+ if (link) {
+ return link.textContent = text;
+ }
+ }
+ },
+ types: {
+ audio: {
+ regExp: /(.*\.(mp3|ogg|wav))$/,
+ el: function(a) {
+ return $.el('audio', {
+ controls: 'controls',
+ preload: 'auto',
+ src: a.dataset.uid
+ });
+ }
+ },
+ gist: {
+ regExp: /.*(?:gist.github.com.*\/)([^\/][^\/]*)$/,
+ el: function(a) {
+ var div;
+ return div = $.el('iframe', {
+ src: "http://www.purplegene.com/script?url=https://gist.github.com/" + a.dataset.uid + ".js"
+ });
+ },
+ 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;
+ }
+ }
+ }
+ }
+ },
+ image: {
+ regExp: /(http|www).*\.(gif|png|jpg|jpeg|bmp)$/,
+ style: 'border: 0; width: auto; height: auto;',
+ el: function(a) {
+ return $.el('div', {
+ innerHTML: " "
+ });
+ }
+ },
+ InstallGentoo: {
+ regExp: /.*(?:paste.installgentoo.com\/view\/)([0-9a-z_]+)/,
+ el: function(a) {
+ return $.el('iframe', {
+ src: "http://paste.installgentoo.com/view/embed/" + a.dataset.uid
+ });
+ }
+ },
+ Twitter: {
+ regExp: /.*twitter.com\/(.+\/status\/\d+)/,
+ el: function(a) {
+ return $.el('iframe', {
+ src: "https://twitframe.com/show?url=https://twitter.com/" + a.dataset.uid
+ });
+ }
+ },
+ LiveLeak: {
+ regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/,
+ el: function(a) {
+ var el;
+ el = $.el('iframe', {
+ width: "640",
+ height: "360",
+ src: "http://www.liveleak.com/ll_embed?i=" + a.dataset.uid,
+ frameborder: "0"
+ });
+ el.setAttribute("allowfullscreen", "true");
+ return el;
+ }
+ },
+ MediaCrush: {
+ regExp: /.*(?:mediacru.sh\/)([0-9a-z_]+)/i,
+ style: 'border: 0;',
+ el: function(a) {
+ var el;
+ el = $.el('div');
+ $.cache("https://mediacru.sh/" + a.dataset.uid + ".json", function() {
+ var embed, file, files, status, type, _i, _j, _len, _len1, _ref;
+ status = this.status;
+ if (status !== 200 && status !== 304) {
+ return div.innerHTML = "ERROR " + status;
+ }
+ files = JSON.parse(this.response).files;
+ _ref = ['video/mp4', 'video/ogv', 'image/svg+xml', 'image/png', 'image/gif', 'image/jpeg', 'image/svg', 'audio/mpeg'];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ type = _ref[_i];
+ for (_j = 0, _len1 = files.length; _j < _len1; _j++) {
+ file = files[_j];
+ if (file.type === type) {
+ embed = file;
+ break;
+ }
+ }
+ if (embed) {
+ break;
+ }
+ }
+ if (!embed) {
+ return div.innerHTML = "ERROR: Not a valid filetype";
+ }
+ return el.innerHTML = (function() {
+ switch (embed.type) {
+ case 'video/mp4':
+ case 'video/ogv':
+ return "\n \n \n ";
+ case 'image/png':
+ case 'image/gif':
+ case 'image/jpeg':
+ return " ";
+ case 'image/svg':
+ case 'image/svg+xml':
+ return " ";
+ case 'audio/mpeg':
+ return " ";
+ default:
+ return "ERROR: No valid filetype.";
+ }
+ })();
+ });
+ return el;
+ }
+ },
+ pastebin: {
+ regExp: /.*(?:pastebin.com\/(?!u\/))([^#\&\?]*).*/,
+ el: function(a) {
+ var div;
+ return div = $.el('iframe', {
+ src: "http://pastebin.com/embed_iframe.php?i=" + a.dataset.uid
+ });
+ }
+ },
+ gfycat: {
+ regExp: /.*gfycat.com\/(?:iframe\/)?(\S*)/,
+ el: function(a) {
+ var div;
+ return div = $.el('iframe', {
+ src: "http://gfycat.com/iframe/" + a.dataset.uid
+ });
+ }
+ },
+ SoundCloud: {
+ regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/,
+ style: 'height: auto; width: 500px; display: inline-block;',
+ el: function(a) {
+ var div;
+ div = $.el('div', {
+ className: "soundcloud",
+ name: "soundcloud"
+ });
+ $.ajax("//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + a.dataset.uid, {
+ onloadend: function() {
+ return div.innerHTML = JSON.parse(this.responseText).html;
+ }
+ }, false);
+ return div;
+ },
+ title: {
+ api: function(uid) {
+ return "//soundcloud.com/oembed?show_artwork=false&&maxwidth=500px&show_comments=false&format=json&url=https://www.soundcloud.com/" + uid;
+ },
+ text: function(_) {
+ return _.title;
+ }
+ }
+ },
+ StrawPoll: {
+ regExp: /strawpoll\.me\/(?:embed_\d+\/)?(\d+)/,
+ style: 'border: 0; width: 600px; height: 406px;',
+ el: function(a) {
+ return $.el('iframe', {
+ src: "http://strawpoll.me/embed_1/" + a.dataset.uid
+ });
+ }
+ },
+ TwitchTV: {
+ regExp: /.*(?:twitch.tv\/)([^#\&\?]*).*/,
+ style: "border: none; width: 640px; height: 360px;",
+ el: function(a) {
+ var channel, chapter, result, _;
+ if (result = /(\w+)\/(?:[a-z]\/)?(\d+)/i.exec(a.dataset.uid)) {
+ _ = result[0], channel = result[1], chapter = result[2];
+ return $.el('object', {
+ data: 'http://www.twitch.tv/widgets/archive_embed_player.swf',
+ innerHTML: " \n "
+ });
+ } else {
+ channel = (/(\w+)/.exec(a.dataset.uid))[0];
+ return $.el('object', {
+ data: "http://www.twitch.tv/widgets/live_embed_player.swf?channel=" + channel,
+ innerHTML: " \n \n "
+ });
+ }
+ }
+ },
+ Vocaroo: {
+ regExp: /.*(?:vocaroo.com\/)([^#\&\?]*).*/,
+ style: 'border: 0; width: 150px; height: 45px;',
+ el: function(a) {
+ return $.el('object', {
+ innerHTML: " "
+ });
+ }
+ },
+ Vimeo: {
+ regExp: /.*(?:vimeo.com\/)([^#\&\?]*).*/,
+ 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=http://vimeo.com/" + uid;
+ },
+ text: function(_) {
+ return _.title;
+ }
+ }
+ },
+ Vine: {
+ regExp: /.*(?:vine.co\/)([^#\&\?]*).*/,
+ style: 'border: none; width: 500px; height: 500px;',
+ el: function(a) {
+ return $.el('iframe', {
+ src: "https://vine.co/" + a.dataset.uid + "/card"
+ });
+ }
+ },
+ YouTube: {
+ regExp: /.*(?:youtu.be\/|youtube.*v=|youtube.*\/embed\/|youtube.*\/v\/|youtube.*videos\/)([^#\&\?]*)\??(t\=.*)?/,
+ el: function(a) {
+ var el;
+ el = $.el('iframe', {
+ src: "//www.youtube.com/embed/" + a.dataset.uid + (a.dataset.option ? '#' + a.dataset.option : '') + "?wmode=opaque"
+ });
+ el.setAttribute("allowfullscreen", "true");
+ return el;
+ },
+ title: {
+ api: function(uid) {
+ return "https://gdata.youtube.com/feeds/api/videos/" + uid + "?alt=json&fields=title/text(),yt:noembed,app:control/yt:state/@reasonCode";
+ },
+ text: function(data) {
+ return data.entry.title.$t;
+ }
+ }
+ }
+ }
+ };
+
+ ArchiveLink = {
+ init: function() {
+ var div, entry, type, _i, _len, _ref;
+ if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Archive Link']) {
+ return;
+ }
+ div = $.el('div', {
+ textContent: 'Archive'
+ });
+ entry = {
+ type: 'post',
+ 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: []
+ };
+ _ref = [['Post', 'post'], ['Name', 'name'], ['Tripcode', 'tripcode'], ['E-mail', 'email'], ['Subject', 'subject'], ['Filename', 'filename'], ['Image MD5', 'MD5']];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ type = _ref[_i];
+ entry.subEntries.push(this.createSubEntry(type[0], type[1]));
+ }
+ return $.event('AddMenuEntry', 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 = {
+ init: function() {
+ var div, fileEl, fileEntry, postEl, postEntry;
+ if (g.VIEW === 'catalog' || !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:;'
+ });
+ postEntry = {
+ el: postEl,
+ open: function() {
+ postEl.textContent = 'Post';
+ $.on(postEl, 'click', DeleteLink["delete"]);
+ return true;
+ }
+ };
+ fileEntry = {
+ el: fileEl,
+ open: function(_arg) {
+ var file;
+ file = _arg.file;
+ if (!file || file.isDead) {
+ return false;
+ }
+ fileEl.textContent = 'File';
+ $.on(fileEl, 'click', DeleteLink["delete"]);
+ return true;
+ }
+ };
+ return $.event('AddMenuEntry', {
+ type: 'post',
+ el: div,
+ order: 40,
+ open: function(post) {
+ var node;
+ if (post.isDead) {
+ return false;
+ }
+ DeleteLink.post = post;
+ node = div.firstChild;
+ node.textContent = 'Delete';
+ DeleteLink.cooldown.start(post, node);
+ return true;
+ },
+ subEntries: [postEntry, fileEntry]
+ });
+ },
+ "delete": function() {
+ var fileOnly, form, link, post;
+ post = DeleteLink.post;
+ if (DeleteLink.cooldown.counting === post) {
+ return;
+ }
+ $.off(this, 'click', DeleteLink["delete"]);
+ fileOnly = $.hasClass(this, 'delete-file');
+ this.textContent = "Deleting " + (fileOnly ? 'file' : 'post') + "...";
+ form = {
+ mode: 'usrdel',
+ onlyimgdel: fileOnly,
+ pwd: QR.persona.getPassword()
+ };
+ form[post.ID] = 'delete';
+ link = this;
+ 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);
+ }
+ }, {
+ form: $.formData(form)
+ });
+ },
+ load: function(link, post, fileOnly, resDoc) {
+ var msg, s;
+ if (resDoc.title === '4chan - Banned') {
+ s = 'Banned!';
+ } else if (msg = resDoc.getElementById('errmsg')) {
+ s = msg.textContent;
+ $.on(link, 'click', DeleteLink["delete"]);
+ } else {
+ if (resDoc.title === 'Updating index...') {
+ (post.origin || post).kill(fileOnly);
+ }
+ s = 'Deleted';
+ }
+ return link.textContent = s;
+ },
+ error: function(link) {
+ link.textContent = 'Connection error, please retry.';
+ return $.on(link, 'click', DeleteLink["delete"]);
+ },
+ cooldown: {
+ start: function(post, node) {
+ var length, seconds, _ref;
+ if (!((_ref = QR.db) != null ? _ref.get({
+ boardID: post.board.ID,
+ threadID: post.thread.ID,
+ postID: post.ID
+ }) : void 0)) {
+ delete DeleteLink.cooldown.counting;
+ return;
+ }
+ DeleteLink.cooldown.counting = post;
+ length = 60;
+ seconds = Math.ceil((length * $.SECOND - (Date.now() - post.info.date)) / $.SECOND);
+ return DeleteLink.cooldown.count(post, seconds, length, node);
+ },
+ count: function(post, seconds, length, node) {
+ if (DeleteLink.cooldown.counting !== post) {
+ return;
+ }
+ if (!((0 <= seconds && seconds <= length))) {
+ if (DeleteLink.cooldown.counting === post) {
+ node.textContent = 'Delete';
+ delete DeleteLink.cooldown.counting;
+ }
+ return;
+ }
+ setTimeout(DeleteLink.cooldown.count, 1000, post, seconds - 1, length, node);
+ return node.textContent = "Delete (" + seconds + ")";
+ }
+ }
+ };
+
+ DownloadLink = {
+ init: function() {
+ var a;
+ if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Download Link']) {
+ return;
+ }
+ a = $.el('a', {
+ className: 'download-link',
+ textContent: 'Download file'
+ });
+ return $.event('AddMenuEntry', {
+ type: 'post',
+ 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() {
+ if (g.VIEW === 'catalog' || !Conf['Menu']) {
+ return;
+ }
+ this.menu = new UI.Menu('post');
+ return Post.callbacks.push({
+ name: 'Menu',
+ cb: this.node
+ });
+ },
+ node: function() {
+ if (this.isClone) {
+ $.on($('.menu-button', this.nodes.info), 'click', Menu.toggle);
+ return;
+ }
+ return $.add(this.nodes.info, Menu.makeButton());
+ },
+ makeButton: (function() {
+ var a;
+ a = $.el('a', {
+ className: 'menu-button',
+ innerHTML: ' ',
+ href: 'javascript:;'
+ });
+ return function() {
+ var button;
+ button = a.cloneNode(true);
+ $.on(button, 'click', Menu.toggle);
+ return button;
+ };
+ })(),
+ toggle: function(e) {
+ var post;
+ post = Get.postFromNode(this);
+ return Menu.menu.toggle(e, this, post);
+ }
+ };
+
+ ReportLink = {
+ init: function() {
+ var a;
+ if (g.VIEW === 'catalog' || !Conf['Menu'] || !Conf['Report Link']) {
+ return;
+ }
+ a = $.el('a', {
+ className: 'report-link',
+ href: 'javascript:;',
+ textContent: 'Report this post'
+ });
+ $.on(a, 'click', ReportLink.report);
+ return $.event('AddMenuEntry', {
+ type: 'post',
+ el: a,
+ order: 10,
+ open: function(post) {
+ ReportLink.post = post;
+ return !post.isDead;
+ }
+ });
+ },
+ report: function() {
+ var id, post, set, url;
+ post = ReportLink.post;
+ url = "//sys.4chan.org/" + post.board + "/imgboard.php?mode=report&no=" + post;
+ id = Date.now();
+ set = "toolbar=0,scrollbars=0,location=0,status=1,menubar=0,resizable=1,width=685,height=200";
+ return window.open(url, id, set);
+ }
+ };
+
+ Favicon = {
+ init: function() {
+ return $.ready(function() {
+ var href;
+ Favicon.el = $('link[rel="shortcut icon"]', d.head);
+ Favicon.el.type = 'image/x-icon';
+ href = Favicon.el.href;
+ Favicon.SFW = /ws\.ico$/.test(href);
+ Favicon["default"] = href;
+ return Favicon["switch"]();
+ });
+ },
+ "switch": function() {
+ if (Favicon.SFW) {
+ Favicon["default"] = 'https://s.4cdn.org/image/favicon-ws.ico';
+ } else {
+ Favicon["default"] = 'https://s.4cdn.org/image/favicon.ico';
+ }
+ switch (Conf['favicon']) {
+ case 'ferongr':
+ Favicon.unreadDead = 'data:image/gif;base64,R0lGODlhEAAQAPIGAOgLAnMFAL8AAOkMA/+AgP+rqwAAAAAAACH5BAUKAAYALAAAAAAQABAAQANKaLrcDYDBF8YgAQZiswJVp1mDZ4CB+aUmmkYnq4IFphGFGoMwr0MwySSGs62KGZBAIAJZli2gcLhA9V6STTNkjAkCX803LDmVgwkAOw==';
+ Favicon.unreadDeadY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxUlEQVR42q1TOwrCQBB9s0FRtJI0WoqFtSLYegoP4gVSeJsUHsHSI3iFeIqRXXgwrhlXwYHHhLwPTB7B36abBCV+0pA4DUBQUNZYQptGtW3jtoKyxgoe0yrBCoyZfL/5ioQ3URZOXW9I341l3oo+NXEZiW4CEuIzvPECopED4OaZ3RNmeAm4u+a8Jr5f17VyVoL8fr8qcltzwlyyj2iqcgPOQ9ExkHAITgD75bYBe0A5S4H/P9htuWMF3QXoQpwaKeT+lnsC6JE5I6aq6fEAAAAASUVORK5CYII=';
+ Favicon.unreadSFW = 'data:image/gif;base64,R0lGODlhEAAQAPIGAADX8QBwfgC2zADY8nnl8qLp8gAAAAAAACH5BAUKAAYALAAAAAAQABAAQANKaLrcDYDBF8YgAQZiswJVp1mDZ4CB+aUmmkYnq4IFphGFGoMwr0MwySSGs62KGZBAIAJZli2gcLhA9V6STTNkjAkCX803LDmVgwkAOw==';
+ Favicon.unreadSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxElEQVQ4y2NgoBq4/vE/HJOsBiRQUIfA2AzBqQYqUfn00/9FLz+BaQxDCKqBmX7jExijKEDSDJPHrnnbGQhGV4RmOFwdVkNwhQMheYwQxhaIi7b9Z9A3gWAQm2BUoQOgRhgA8o7j1ozLC4LCyAZcx6kZI5qg4kLKqggDFFWxJySsUQVzlb4pwgAJaTRvokcVNgOqOv8zcHBCsL07DgNg8YsczzA5MxtUL+DMD8g0slxI/H8GQ/P/DJKyeKIRpglXZsIiBwBhP5O+VbI/JgAAAABJRU5ErkJggg==';
+ Favicon.unreadNSFW = 'data:image/gif;base64,R0lGODlhEAAQAPIGAFT+ACh5AEncAFX/Acz/su7/5gAAAAAAACH5BAUKAAYALAAAAAAQABAAQANKaLrcDYDBF8YgAQZiswJVp1mDZ4CB+aUmmkYnq4IFphGFGoMwr0MwySSGs62KGZBAIAJZli2gcLhA9V6STTNkjAkCX803LDmVgwkAOw==';
+ Favicon.unreadNSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAx0lEQVQ4y2NgoBYI+cfwH4ZJVgMS0KhEYGyG4FQDkzjzf9P/d/+fgWl0QwiqgSkI/c8IxsgKkDXD5LFq9rwDweiK0A2HqcNqCK5wICSPEcLYAtH+AMN/IXMIBrEJRie6OEgjDAC5x3FqxuUFNiEUA67j1IweTTBxBQ1puAG86jgSEraogskJWSBcwCGF5k30qMJmgMFEhv/MXBAs5oLDAFj8IsczTE7UEeECbhU8+QGZRpaTi2b4L2zF8J9TGk80wjThykzY5AAW/2O1C2mIbgAAAABJRU5ErkJggg==';
+ break;
+ case 'xat-':
+ Favicon.unreadDead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAxUlEQVR42s1SQQrCMBDsQ8WDIEV6LTT2A4og2Hi0veo7fIAH04e06L1jphIJRtoVLw4MmWZnh2aT6K8Ax82uyFOV6SSJK5Kae74naIZHfhfx5HxaTC8kdeCRhNzms8ayFTaHJuTLzvKpJSE+sVoDhxIoK2qv5vgGDutoz8vfhlJd33w1gDGg5h5r9NArCzA1UNevgPtQQJplmtMeOwI99AYBW73PI8EQqXsvIbjGduAaxwPcQ/oqwF/dUw5r5GfArcLa73gAGxUeHPIycrIAAAAASUVORK5CYII=';
+ Favicon.unreadDeadY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA80lEQVQ4y2NgGEzgPwx3TZhYVVJRPik7O30uCIPYIDFkNRia/yNhEH9ieszB5ZlxZ0EYxMamhqAhn1KT3gPxB5I1wxT9r6r8B8T/ccnjDAOwhvaO//9nz/n/f85cMBtdHiMEQYG1DOhfkLP/V1T8A2u+eOn//0uXwAYdiIr6ZyQi8ltOWPCLm5vzVuIMuHT5///Ll8EGWEhJ/YcBfn7+lxgGlJSXT4KFNi4vwAA3N/c7DAN6J02uYsATiBqoBrzCmpCwROMHWDRaIBmANRCxGQBLSOCEBcRcUIzXAGQalpRBbB8iXMCAJPEfh9wRKG1HtRwIAJCmKOzjRex1AAAAAElFTkSuQmCC';
+ Favicon.unreadSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAzUlEQVQ4y2NgGEzgPwxP7OuqqigtmZSZnj0XhEFskBiyGgzNetMPwzGIH5M/8WBczfKzIAxiY1ND0JCkDZ/eA/EHkjXDFFUe+f8PiP/jkscZBiDcfvr//9lX/v+fA8QgNro8RgiCAiuuetlZkLMrgDaDNF988///pdcQg0BiIDmQGpBaogy4BDTg8htkAz7jNqAcGFWw0MbnBZAakFoMAyZP6K1CDixcgQhiQ9UyEBONH4iNRqwGwBISSQYg07CkjE0OX35gwKEAnxz5AADUHTv3RAHZ7QAAAABJRU5ErkJggg==';
+ Favicon.unreadSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/klEQVQ4y2NgGEzgPwxP7OuqqigtmZSZnj0XhEFskBiyGgzNetMPwzGIH5M/8WBczfKzIAxiY1ND0JCkDZ/eA/EHkjXDFFUe+f8PiP/jkscZBiDcfvr//9lX/v+fA8QgNro8RgiCAiuuetlZkLMrgDaDNF988///pdcQg6KmHPgnomL0W1BM7ours9tWogy4BDTg8huIAVLaFv9hgJ+f/yWGAeXAqIKFNi4vwAA3N/c7DAMmT+itQg4s9EBkF5dDNuAV1oSEJRo/wKKRS1ELbgDWQMRmACwhgdhSoXn/GVnZwRivAcg0LCmD2Ly6VgRdwIAk8R+H3BEobUe1HAgA7g5BI+Q2tn8AAAAASUVORK5CYII=';
+ Favicon.unreadNSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAzklEQVQ4y2NgGEzgPwxP7JpYVVZSMSk9O2suCIPYIDFkNRia084YwzGIHzMx/mDc8vizIAxiY1ND0JCST0nvgfgDyZphinr+V/4D4v+45HGGAQjP+t/+f/X/2UA8B8xGl8cIQVBgxS2LPwtyds//in8gzTf/XwTiS2CDQGIgOZAakFqiDLgF1Hzr/2WEAZ/xGFBWUj4JFtr4vABSA1KLYcDk3slVyIGFKxBBbKhaBmKi8QOx0YjVAFhCIskAZBqWlLHJ4csPDDgU4JMjHwAAAfUvfvahyqUAAAAASUVORK5CYII=';
+ Favicon.unreadNSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/klEQVQ4y2NgGEzgPwxP7JpYVVZSMSk9O2suCIPYIDFkNRia084YwzGIHzMx/mDc8vizIAxiY1ND0JCST0nvgfgDyZphinr+V/4D4v+45HGGAQjP+t/+f/X/2UA8B8xGl8cIQVBgxS2LPwtyds//in8gzTf/XwTiS2CDMg9E/ZMwEvktKCf4xdnNdStRBtwCar71/zLYADkLqf8wwM/P/xLDgLKS8kmw0MblBRjg5uZ+h2HA5N7JVciBhR6IAgocyAa8wpqQsETjB1g0iulwww3AGojYDIAlJBDbqkT2PwsHExjjNQCZhiVlEFvOhp+gCxiQJP7jkDsCpe2olgMB9UE2wvseYUsAAAAASUVORK5CYII=';
+ break;
+ case 'Mayhem':
+ Favicon.unreadDead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABFklEQVR4AZ2R4WqEMBCEFy1yiJQQ14gcIhIuFBFR+qPQ93+v66QMksrlTwMfkZ2ZZbMKTgVqYIDl3YAbeCM31lJP/Zul4MAEPJjBQGNDLGsz8PQ6aqLAP5PTdd1WlmU09mSKtdTDRgrkzspJPKq6RxMahfj9yhOzQEZwZAwfzrk1ox3MXibIN8hO4MAjeV72CemJGWblnRsOYOdoGw0jebB20BPAwKzUQPlrFhrXFw1Wagu9yuzZwINzVAZCURRL+gRr7Wd8Vtqg4Th/lsUmewyk9WQ/A7NiwJz5VV/GmO+MNjMrFvh/NPDMigHTaeJN09a27ZHRJmalBg54CgfvAGYSLpoHjlmpuAwFdzDy7oGS/qIpM9UPFGg1b1kUlssAAAAASUVORK5CYII=';
+ Favicon.unreadDeadY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABR0lEQVR4AYWSQWq0QBCFCw0SRIK0PQ4hiIhEZBhEySLyewUPEMgqR/JIXiDhzz7kKKYePIZajEzDRxfV9dWU3SO6IiVWUsVxT5R75Y4gTmwNnUh4kCulUiuV8sjChDjmKtaUcHgmHsnNrMPh0IVhiMIjKZGzNXDoyhMzF7C89z2KtFGD+FoNXEUKZdgpaPM8P++cDXTtBDca7EyQK8+bXTufYBccuvLAG26UnqN1LCgI4g/lm7zTgSux4vk0J8rnKw3+m1//pBPbBrVyGZVNmiAITviEtm3t+D+2QcJx7GUxlN4594K4ZY75Xzh0JVWqnad6TdP0H+LRNBjHcYNDV5xS32qwaC4my7Lwn6guu5QoomgbdFmWDYhnM8E8zxscuhLzPWtKA/dGqUizrityX9M0YX+DQ1ciXobnP6vgfmTOM7Znnk70B58pPaEvx+epAAAAAElFTkSuQmCC';
+ Favicon.unreadSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/ElEQVR4AZ3RUWqEMBSF4ftQZAhSREQJIiIXpQwi+tSldkFdWPsLhyEE0ocKH2Fyzg1mNJ4KAQ1arTUeeJMH6qwTUJmCHjMcC6KKtbSIylzdXpl18J/k4fdTpUFmPLOOa9bGe+P4+n5RYYfLXuiMsAlXofBxK2QXpvwN/jqg+AY91vR+pStk+apZe0fEhhMXDhUmWXEoO9WNmrWAzvRPq7jnB2jvUGfWTEgPcJzZFTbZk/0Tnh5QI+af6lVGvq/Do2atwVL4VJ+3QrZo1lr4Pw5wzVqDWaV7SUvHrZDNmrWAHq7g0rphkS3LXDMBVqFGhxGT1gGdDFnWaab6BRmXRvbxDmYiAAAAAElFTkSuQmCC';
+ Favicon.unreadSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4AY2SQUrEQBBFS9CMNFEkhAQdYmiCIUgcZlYGc4VsBcGVF/AuWXme4F7RtXiVWF9+Y9MYtOHRTdX/NZWaEj2RYpQTJeEdK4fKPuA7DjSGXiQkU0qlUqxySmFMEsYsNSU8zEmK4OwdEbmkKCclYoGmolfWCGyenh1O0EJE2gXNWpFC2S0IGrCQ29EbdPCPAmEHmXIxByf8hDAPD71yzAnXypatbSgoAN8Pyju5h4deMUrqJk1z+0uBN+/XX+gxfoFK2QafUJO2aRq//Q+/QIx2wr+Kwq0rusrP/QKf9MTCtbQLf9U1wNvYnz3qug45S68kSvVXgbPbx3nvYPXNOI7cRPWySukK+DcGCvA+urqZ3RmGAbmSXjFK5rpwW8nhWVJP04TYa9/3uO/goVciDiPlZhW8c8ZAHuRSeqIv32FK/GYGL8YAAAAASUVORK5CYII=';
+ Favicon.unreadNSFW = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA/ElEQVR4AZ3RUWqEMBSF4ftQZAihDCKKiAQJShERQx+6o662e2p/4TCEQF468BEm95yLovFr4PBEq9PjgTd5wBcZp6559AiIWDAq6KXV3aJMUMfDOsTf7Mf/XaFBAvYiE9W16b74/vl8UeBAlKOSmWAzUiXwcavMkrrFE9QXVJ+gx5q9XvUVivmqrr1jxIYLCacCs6y6S8psGNU1hw4Bu4JHuUB3pzJBHZcviLiKV9jkyO4vxHyBx1h+qlcY5b2Wj+raE0vlU33dKrNFXWsR/7EgqmtPBIXuIw+dt8osqGsOPaIGSeeGRbZiFtVxsAYeHSbMOgd0MhSzTp3mD4RaQX4aW3NMAAAAAElFTkSuQmCC';
+ Favicon.unreadNSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABP0lEQVR4AYWS0UqFQBCGhziImNRBRImDmUgiIaF0kWSP4AMEXXXTE/QiPpL3UdR19Crb/PAvLEtyFj5mmfn/cdxd0RUokbJXEsZYCZUd4D72NBG8wkKmlEqtVMoFhTFJmKuoKelBTVIkjbNE5IainJTIeZqaXjkg8fp+Z7GCjiLQbWgOihTKsCFowUZtoNef4HgDf4JMuTbe8n/Br8NDr5zxhBul52i3FBQE+xflmzzTA69ESmpPmubunwZfztc/6IncBrXSe7/QkK5tW3f8H7dBjHH8q6Kwt033V6Hb4JeeWPgsq42rugfYZ92psWscRwMPvZIo9bEGD2+F2YUnBizLwpeoXnYpbQM34kAB9peP58aueZ4NPPRKxPusaRoYG6UizbquyH1O04T4RA+8EvAwUr6sgjFnDuReLaUn+ANygUa7+9SCWgAAAABJRU5ErkJggg==';
+ break;
+ case 'Original':
+ Favicon.unreadDead = 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAMALAAAAAAQABAAAAI/nI95wsqygIRxDgGCBhTrwF3Zxowg5H1cSopS6FrGQ82PU1951ckRmYKJVCXizLRC9kAnT0aIiR6lCFT1cigAADs=';
+ Favicon.unreadDeadY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAhElEQVR42q1RwQnAMAjMu5M4guAKXa4j5dUROo5tipSDcrFChUONd0di2m/hEGVOHDyIPufgwAFASDkpoSzmBrkJ2UMyR9LsJ3rvrqo3Rt1YMIMhhNnOxLMnoMFBxHyJAr2IOBFzA8U+6pLBdmEJTA0aMVjpDd6Loks0s5HZNwYx8tfZCZ0kll7ORffZAAAAAElFTkSuQmCC';
+ Favicon.unreadSFW = 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAC6Xw////////yH5BAEKAAMALAAAAAAQABAAAAI/nI95wsqygIRxDgGCBhTrwF3Zxowg5H1cSopS6FrGQ82PU1951ckRmYKJVCXizLRC9kAnT0aIiR6lCFT1cigAADs=';
+ Favicon.unreadSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAABBQcHFx4KISoNLToaVW4oKCgul8M4ODg7OzvBwcH///8uS/CdAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eILZO5/XI0UAgm7H9tOsu0yGWAQSOoFijHOxOANGqm/LczpOaXs4gISrPZ+gc2+hO5w2xdwgOjBFUIF+sEJrhUl9JFr+badFwR+BfqlmGUJAAAAAElFTkSuQmCC';
+ Favicon.unreadNSFW = 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAGbMM////////yH5BAEKAAMALAAAAAAQABAAAAI/nI95wsqygIRxDgGCBhTrwF3Zxowg5H1cSopS6FrGQ82PU1951ckRmYKJVCXizLRC9kAnT0aIiR6lCFT1cigAADs=';
+ Favicon.unreadNSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAALVBMVEUAAAAAAAAAAAAAAAAECAIQIAgWLAsePA8oKCg4ODg6dB07OztmzDPBwcH///+rsf3XAAAAA3RSTlMAx9dmesIgAAAAV0lEQVR42m2NWw6AIBAD1eIDhbn/cTVSCCTsfmw7ybbLZIBBIKkXKKU0E4M3aKT+tjCn5xiziwuIsNr7BTb7ErrDZV/AAaIHdwgV6AcnuFaU0Eeu5dt2XiUyBjCQ2bIrAAAAAElFTkSuQmCC';
+ break;
+ case 'Metro':
+ Favicon.unreadDead = 'data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAC/AABrZQDiAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==';
+ Favicon.unreadDeadY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAAHAAAdAAApAAAsAAA4AABsAACQAAC/AAD///9SVhtjAAAAA3RSTlMAPse+s4iwAAAAM0lEQVQIW2NggAGuVasWgDBpDDAQUoSaob0Jao73lgVojOitUEazBZRRvR3KmJa5AO4KAGBtLuMAuhIIAAAAAElFTkSuQmCC';
+ Favicon.unreadSFW = 'data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAAA1/GhpCidAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==';
+ Favicon.unreadSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAAACAkAISUALzQAMTcAQEcAeokAorYA1/H///8BrzTFAAAAA3RSTlMAPse+s4iwAAAAM0lEQVQIW2NggAGuVasWgDBpDDAQUoSaob0Jao73lgVojOitUEazBZRRvR3KmJa5AO4KAGBtLuMAuhIIAAAAAElFTkSuQmCC';
+ Favicon.unreadNSFW = 'data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAABV/wErM5hwAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==';
+ Favicon.unreadNSFWY = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAJFBMVEUAAAAAAAAAAAADCgANKAASOAATOwAZTAAwkQBAwQBV/wH////+Fmy4AAAAA3RSTlMAPse+s4iwAAAAM0lEQVQIW2NggAGuVasWgDBpDDAQUoSaob0Jao73lgVojOitUEazBZRRvR3KmJa5AO4KAGBtLuMAuhIIAAAAAElFTkSuQmCC';
+ if (Favicon.SFW) {
+ Favicon["default"] = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAAul8Or2V3yAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==';
+ } else {
+ Favicon["default"] = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAABmzDMxovcJAAAAAXRSTlMAQObYZgAAABJJREFUCB1jZGBgrMNAQEEc4gCSfAX5bRw/NQAAAABJRU5ErkJggg==';
+ }
+ }
+ if (Favicon.SFW) {
+ Favicon.unread = Favicon.unreadSFW;
+ return Favicon.unreadY = Favicon.unreadSFWY;
+ } else {
+ Favicon.unread = Favicon.unreadNSFW;
+ return Favicon.unreadY = Favicon.unreadNSFWY;
+ }
+ },
+ dead: 'data:image/gif;base64,R0lGODlhEAAQAKECAAAAAP8AAP///////yH5BAEKAAIALAAAAAAQABAAAAIvlI+pq+D9DAgUoFkPDlbs7lFZKIJOJJ3MyraoB14jFpOcVMpzrnF3OKlZYsMWowAAOw==',
+ logo: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAgMAAAC+UIlYAAAACVBMVEUAAGcAAABmzDNZt9VtAAAAAXRSTlMAQObYZgAAAGlJREFUWMPtlkEKADEIA/tJP9lXLttQto2yHxgDHozTi0ToGK2WKZZ+HAQQMZc+xBwI4EZ+wAC2IfPuSIDOZJrSZQEAX9eVJhhwIuUYAnQe8rhAEMAZlTI2MID9f5Clyh0JeE1V1ZEAvB4qDfwuJTSGRAAAAABJRU5ErkJggg=='
+ };
+
+ ThreadExcerpt = {
+ init: function() {
+ if (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,
+ _this = this;
+ if (g.VIEW !== 'thread' || !Conf['Thread Stats']) {
+ return;
+ }
+ if (Conf['Updater and Stats in Header']) {
+ this.dialog = sc = $.el('span', {
+ innerHTML: "0 / 0 " + (Conf["Page Count in Stats"] ? " / 0 " : ""),
+ id: 'thread-stats',
+ title: 'Post Count / File Count' + (Conf["Page Count in Stats"] ? " / Page Count" : "")
+ });
+ $.ready(function() {
+ return Header.addShortcut(sc);
+ });
+ } else {
+ this.dialog = sc = UI.dialog('thread-stats', 'bottom: 0px; right: 0px;', "0 / 0 " + (Conf["Page Count in Stats"] ? " / 0 " : "") + "
");
+ $.ready(function() {
+ return $.add(d.body, sc);
+ });
+ }
+ this.postCountEl = $('#post-count', sc);
+ this.fileCountEl = $('#file-count', sc);
+ this.pageCountEl = $('#page-count', sc);
+ return Thread.callbacks.push({
+ name: 'Thread Stats',
+ cb: this.node
+ });
+ },
+ node: function() {
+ var ID, fileCount, post, postCount, _ref;
+ postCount = 0;
+ fileCount = 0;
+ _ref = this.posts;
+ for (ID in _ref) {
+ post = _ref[ID];
+ postCount++;
+ if (post.file) {
+ fileCount++;
+ }
+ }
+ ThreadStats.thread = this;
+ ThreadStats.fetchPage();
+ ThreadStats.update(postCount, fileCount);
+ return $.on(d, 'ThreadUpdate', ThreadStats.onUpdate);
+ },
+ onUpdate: function(e) {
+ var fileCount, postCount, _ref;
+ if (e.detail[404]) {
+ return;
+ }
+ _ref = e.detail, postCount = _ref.postCount, fileCount = _ref.fileCount;
+ return ThreadStats.update(postCount, fileCount);
+ },
+ update: function(postCount, fileCount) {
+ var fileCountEl, postCountEl, thread;
+ thread = ThreadStats.thread, postCountEl = ThreadStats.postCountEl, fileCountEl = ThreadStats.fileCountEl;
+ postCountEl.textContent = postCount;
+ fileCountEl.textContent = fileCount;
+ (thread.postLimit && !thread.isSticky ? $.addClass : $.rmClass)(postCountEl, 'warning');
+ return (thread.fileLimit && !thread.isSticky ? $.addClass : $.rmClass)(fileCountEl, 'warning');
+ },
+ fetchPage: function() {
+ if (!Conf["Page Count in Stats"]) {
+ return;
+ }
+ if (ThreadStats.thread.isDead) {
+ ThreadStats.pageCountEl.textContent = 'Dead';
+ $.addClass(ThreadStats.pageCountEl, 'warning');
+ return;
+ }
+ setTimeout(ThreadStats.fetchPage, 2 * $.MINUTE);
+ return $.ajax("//a.4cdn.org/" + ThreadStats.thread.board + "/threads.json", {
+ onload: ThreadStats.onThreadsLoad
+ }, {
+ whenModified: true
+ });
+ },
+ onThreadsLoad: function() {
+ var page, pages, thread, _i, _j, _len, _len1, _ref;
+ if (!(Conf["Page Count in Stats"] && this.status === 200)) {
+ return;
+ }
+ pages = JSON.parse(this.response);
+ for (_i = 0, _len = pages.length; _i < _len; _i++) {
+ page = pages[_i];
+ _ref = page.threads;
+ for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
+ thread = _ref[_j];
+ if (thread.no === ThreadStats.thread.ID) {
+ ThreadStats.pageCountEl.textContent = page.page;
+ (page.page === pages.length - 1 ? $.addClass : $.rmClass)(ThreadStats.pageCountEl, 'warning');
+ return;
+ }
+ }
+ }
+ }
+ };
+
+ ThreadUpdater = {
+ init: function() {
+ var checked, conf, el, input, name, sc, settings, subEntries, _ref,
+ _this = this;
+ if (g.VIEW !== 'thread' || !Conf['Thread Updater']) {
+ return;
+ }
+ if (Conf['Updater and Stats in Header']) {
+ this.dialog = sc = $.el('span', {
+ innerHTML: " ",
+ id: 'updater'
+ });
+ $.ready(function() {
+ return Header.addShortcut(sc);
+ });
+ } else {
+ this.dialog = sc = UI.dialog('updater', 'bottom: 0px; left: 0px;', "
");
+ $.addClass(doc, 'float');
+ $.ready(function() {
+ $.addClass(doc, 'float');
+ return $.add(d.body, sc);
+ });
+ }
+ this.checkPostCount = 0;
+ this.timer = $('#update-timer', sc);
+ this.status = $('#update-status', sc);
+ this.isUpdating = Conf['Auto Update'];
+ $.on(this.timer, 'click', ThreadUpdater.update);
+ $.on(this.status, 'click', ThreadUpdater.update);
+ subEntries = [];
+ _ref = Config.updater.checkbox;
+ for (name in _ref) {
+ conf = _ref[name];
+ checked = Conf[name] ? 'checked' : '';
+ el = $.el('label', {
+ title: "" + conf[1],
+ innerHTML: " " + name
+ });
+ input = el.firstElementChild;
+ $.on(input, 'change', $.cb.checked);
+ if (input.name === 'Scroll BG') {
+ $.on(input, 'change', ThreadUpdater.cb.scrollBG);
+ ThreadUpdater.cb.scrollBG();
+ } else if (input.name === 'Auto Update') {
+ $.on(input, 'change', ThreadUpdater.cb.update);
+ }
+ subEntries.push({
+ el: el
+ });
+ }
+ settings = $.el('span', {
+ innerHTML: 'Interval '
+ });
+ $.on(settings, 'click', this.intervalShortcut);
+ subEntries.push({
+ el: settings
+ });
+ $.event('AddMenuEntry', {
+ type: 'header',
+ 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.lastPost = +ThreadUpdater.root.lastElementChild.id.match(/\d+/)[0];
+ ThreadUpdater.outdateCount = 0;
+ ThreadUpdater.cb.interval.call($.el('input', {
+ value: Conf['Interval']
+ }));
+ $.on(window, 'online offline', ThreadUpdater.cb.online);
+ $.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost);
+ $.on(d, 'visibilitychange', ThreadUpdater.cb.visibility);
+ return ThreadUpdater.cb.online();
+ },
+ /*
+ 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',
+ cb: {
+ online: function() {
+ if (ThreadUpdater.online = navigator.onLine) {
+ ThreadUpdater.outdateCount = 0;
+ ThreadUpdater.setInterval();
+ ThreadUpdater.set('status', null, null);
+ return;
+ }
+ ThreadUpdater.set('timer', null);
+ return ThreadUpdater.set('status', 'Offline', 'warning');
+ },
+ post: function(e) {
+ if (!(ThreadUpdater.isUpdating && e.detail.threadID === ThreadUpdater.thread.ID)) {
+ return;
+ }
+ ThreadUpdater.outdateCount = 0;
+ if (ThreadUpdater.seconds > 2) {
+ return setTimeout(ThreadUpdater.update, 1000);
+ }
+ },
+ checkpost: function(e) {
+ if (!ThreadUpdater.checkPostCount) {
+ if (e.detail.threadID !== ThreadUpdater.thread.ID) {
+ return;
+ }
+ ThreadUpdater.seconds = 0;
+ ThreadUpdater.outdateCount = 0;
+ ThreadUpdater.set('timer', '...');
+ }
+ if (!(g.DEAD || ThreadUpdater.foundPost || ThreadUpdater.checkPostCount >= 5)) {
+ return setTimeout(ThreadUpdater.update, ++ThreadUpdater.checkPostCount * $.SECOND);
+ }
+ ThreadUpdater.setInterval();
+ ThreadUpdater.checkPostCount = 0;
+ delete ThreadUpdater.foundPost;
+ return delete ThreadUpdater.postID;
+ },
+ 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() {
+ var val;
+ val = parseInt(this.value, 10);
+ if (val < 1) {
+ val = 1;
+ }
+ ThreadUpdater.interval = this.value = val;
+ return $.cb.value.call(this);
+ },
+ load: function(e) {
+ var klass, req, text, _ref;
+ req = ThreadUpdater.req;
+ switch (req.status) {
+ case 200:
+ g.DEAD = false;
+ ThreadUpdater.parse(JSON.parse(req.response).posts);
+ ThreadUpdater.setInterval();
+ break;
+ case 404:
+ g.DEAD = true;
+ ThreadUpdater.set('timer', null);
+ ThreadUpdater.set('status', '404', 'warning');
+ clearTimeout(ThreadUpdater.timeoutID);
+ ThreadUpdater.thread.kill();
+ $.event('ThreadUpdate', {
+ 404: true,
+ thread: ThreadUpdater.thread
+ });
+ break;
+ default:
+ ThreadUpdater.outdateCount++;
+ ThreadUpdater.setInterval();
+ _ref = req.status === 304 ? [null, null] : ["" + req.statusText + " (" + req.status + ")", 'warning'], text = _ref[0], klass = _ref[1];
+ ThreadUpdater.set('status', text, klass);
+ }
+ if (ThreadUpdater.postID) {
+ return ThreadUpdater.cb.checkpost();
+ }
+ }
+ },
+ setInterval: function() {
+ var cur, i, j, limit;
+ i = ThreadUpdater.interval + 1;
+ if (Conf['Optional Increase']) {
+ cur = ThreadUpdater.outdateCount || 1;
+ limit = d.hidden ? 7 : 10;
+ j = cur <= limit ? cur : limit;
+ cur = (Math.floor(i * 0.1) || 1) * j * j;
+ ThreadUpdater.seconds = cur > i ? cur <= 300 ? cur : 300 : i;
+ } else {
+ ThreadUpdater.seconds = i;
+ }
+ ThreadUpdater.set('timer', ThreadUpdater.seconds);
+ return ThreadUpdater.count(true);
+ },
+ 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;
+ }
+ if (klass !== void 0) {
+ return el.className = klass;
+ }
+ },
+ count: function(start) {
+ clearTimeout(ThreadUpdater.timeoutID);
+ if (start && ThreadUpdater.isUpdating && navigator.onLine) {
+ return ThreadUpdater.timeout();
+ }
+ },
+ timeout: function() {
+ var n;
+ ThreadUpdater.timeoutID = setTimeout(ThreadUpdater.timeout, 1000);
+ if (!(n = --ThreadUpdater.seconds)) {
+ return ThreadUpdater.update();
+ } else if (n <= -60) {
+ ThreadUpdater.set('status', 'Retrying', null);
+ return ThreadUpdater.update();
+ } else if (n > 0) {
+ return ThreadUpdater.set('timer', n);
+ }
+ },
+ update: function() {
+ var url, _ref;
+ if (!navigator.onLine) {
+ return;
+ }
+ ThreadUpdater.count();
+ if (Conf['Auto Update']) {
+ ThreadUpdater.set('timer', '...');
+ } else {
+ ThreadUpdater.set('timer', 'Update');
+ }
+ if ((_ref = ThreadUpdater.req) != null) {
+ _ref.abort();
+ }
+ url = "//a.4cdn.org/" + ThreadUpdater.thread.board + "/res/" + ThreadUpdater.thread + ".json";
+ return ThreadUpdater.req = $.ajax(url, {
+ onloadend: ThreadUpdater.cb.load
+ }, {
+ whenModified: true
+ });
+ },
+ updateThreadStatus: function(type, status) {
+ var change, hasChanged;
+ if (!(hasChanged = ThreadUpdater.thread["is" + type] !== status)) {
+ return;
+ }
+ ThreadUpdater.thread.setStatus(type, status);
+ 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(postObjects) {
+ var ID, OP, count, deletedFiles, deletedPosts, files, index, key, node, num, post, postObject, posts, root, scroll, _i, _len, _ref;
+ OP = postObjects[0];
+ Build.spoilerRange[ThreadUpdater.thread.board] = OP.custom_spoiler;
+ ThreadUpdater.updateThreadStatus('Sticky', !!OP.sticky);
+ ThreadUpdater.updateThreadStatus('Closed', !!OP.closed);
+ ThreadUpdater.thread.postLimit = !!OP.bumplimit;
+ ThreadUpdater.thread.fileLimit = !!OP.imagelimit;
+ posts = [];
+ index = [];
+ files = [];
+ count = 0;
+ for (_i = 0, _len = postObjects.length; _i < _len; _i++) {
+ postObject = postObjects[_i];
+ num = postObject.no;
+ index.push(num);
+ if (postObject.fsize) {
+ files.push(num);
+ }
+ if (num <= ThreadUpdater.lastPost) {
+ continue;
+ }
+ count++;
+ node = Build.postFromObject(postObject, ThreadUpdater.thread.board.ID);
+ posts.push(new Post(node, ThreadUpdater.thread, ThreadUpdater.thread.board));
+ }
+ deletedPosts = [];
+ deletedFiles = [];
+ _ref = ThreadUpdater.thread.posts;
+ for (ID in _ref) {
+ post = _ref[ID];
+ ID = +ID;
+ if (__indexOf.call(index, ID) < 0) {
+ post.kill();
+ deletedPosts.push(post);
+ } else if (post.isDead) {
+ post.resurrect();
+ } else if (post.file && !(post.file.isDead || __indexOf.call(files, ID) >= 0)) {
+ post.kill(true);
+ deletedFiles.push(post);
+ }
+ if (ThreadUpdater.postID && ThreadUpdater.postID === ID) {
+ ThreadUpdater.foundPost = true;
+ }
+ }
+ if (!count) {
+ ThreadUpdater.set('status', null, null);
+ ThreadUpdater.outdateCount++;
+ } else {
+ ThreadUpdater.set('status', "+" + count, 'new');
+ ThreadUpdater.outdateCount = 0;
+ if (Conf['Beep'] && d.hidden && Unread.posts && !Unread.posts.length) {
+ if (!ThreadUpdater.audio) {
+ ThreadUpdater.audio = $.el('audio', {
+ src: ThreadUpdater.beep
+ });
+ }
+ ThreadUpdater.audio.play();
+ }
+ ThreadUpdater.lastPost = posts[count - 1].ID;
+ Main.callbackNodes(Post, posts);
+ scroll = Conf['Auto Scroll'] && ThreadUpdater.scrollBG() && ThreadUpdater.root.getBoundingClientRect().bottom - doc.clientHeight < 25;
+ for (key in posts) {
+ post = posts[key];
+ if (!posts.hasOwnProperty(key)) {
+ continue;
+ }
+ root = post.nodes.root;
+ if (post.cb) {
+ if (!post.cb()) {
+ $.add(ThreadUpdater.root, root);
+ }
+ } else {
+ $.add(ThreadUpdater.root, root);
+ }
+ }
+ if (scroll) {
+ if (Conf['Bottom Scroll']) {
+ window.scrollTo(0, d.body.clientHeight);
+ } else {
+ if (root) {
+ Header.scrollTo(root);
+ }
+ }
+ }
+ $.queueTask(function() {
+ var length, threadID;
+ threadID = ThreadUpdater.thread.ID;
+ length = $$('.thread > .postContainer', ThreadUpdater.root).length;
+ return Fourchan.parseThread(threadID, length - count, length);
+ });
+ }
+ return $.event('ThreadUpdate', {
+ 404: false,
+ thread: ThreadUpdater.thread,
+ newPosts: posts,
+ deletedPosts: deletedPosts,
+ deletedFiles: deletedFiles,
+ postCount: OP.replies + 1,
+ fileCount: OP.images + (!!ThreadUpdater.thread.OP.file && !ThreadUpdater.thread.OP.file.isDead)
+ });
+ }
+ };
+
+ ThreadWatcher = {
+ init: function() {
+ var now, sc;
+ if (!Conf['Thread Watcher']) {
+ return;
+ }
+ this.shortcut = sc = $.el('a', {
+ id: 'watcher-link',
+ textContent: '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;', "
");
+ this.status = $('#watcher-status', this.dialog);
+ this.list = this.dialog.lastElementChild;
+ $.on(d, 'QRPostSuccessful', this.cb.post);
+ if (g.VIEW === 'thread') {
+ $.on(d, 'ThreadUpdate', this.cb.threadUpdate);
+ }
+ $.on(sc, 'click', this.toggleWatcher);
+ $.on($('.move>.close', ThreadWatcher.dialog), '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['Toggleable Thread Watcher']) {
+ Header.addShortcut(sc);
+ $.addClass(doc, 'fixed-watcher');
+ }
+ now = Date.now();
+ if ((this.db.data.lastChecked || 0) < now - 2 * $.HOUR) {
+ this.db.data.lastChecked = now;
+ ThreadWatcher.fetchAllStatus();
+ this.db.save();
+ }
+ return Thread.callbacks.push({
+ name: 'Thread Watcher',
+ cb: this.node
+ });
+ },
+ node: function() {
+ var toggler;
+ toggler = $.el('img', {
+ className: 'watch-thread-link'
+ });
+ $.on(toggler, 'click', ThreadWatcher.cb.toggle);
+ return $.before($('input', this.OP.nodes.post), toggler);
+ },
+ ready: function() {
+ $.off(d, '4chanXInitFinished', ThreadWatcher.ready);
+ if (!Main.isThisPageLegit()) {
+ return;
+ }
+ ThreadWatcher.refresh();
+ $.add(d.body, ThreadWatcher.dialog);
+ if (Conf['Toggleable Thread Watcher']) {
+ ThreadWatcher.dialog.hidden = true;
+ }
+ 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, _i, _len, _ref;
+ if ($.hasClass(this, 'disabled')) {
+ return;
+ }
+ _ref = $$('a[title]', ThreadWatcher.list);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ a = _ref[_i];
+ $.open(a.href);
+ }
+ return $.event('CloseMenu');
+ },
+ checkThreads: function() {
+ if ($.hasClass(this, 'disabled')) {
+ return;
+ }
+ return ThreadWatcher.fetchAllStatus();
+ },
+ pruneDeads: function() {
+ var boardID, data, threadID, _i, _len, _ref, _ref1;
+ if ($.hasClass(this, 'disabled')) {
+ return;
+ }
+ _ref = ThreadWatcher.getAll();
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ _ref1 = _ref[_i], 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() {
+ return ThreadWatcher.toggle(Get.postFromNode(this).thread);
+ },
+ rm: function() {
+ var boardID, threadID, _ref;
+ _ref = this.parentNode.dataset.fullID.split('.'), boardID = _ref[0], threadID = _ref[1];
+ return ThreadWatcher.rm(boardID, +threadID);
+ },
+ post: function(e) {
+ var board, postID, threadID, _ref;
+ _ref = e.detail, board = _ref.board, postID = _ref.postID, threadID = _ref.threadID;
+ if (postID === threadID) {
+ if (Conf['Auto Watch']) {
+ return $.set('AutoWatch', threadID);
+ }
+ } else if (Conf['Auto Watch Reply']) {
+ return ThreadWatcher.add(board.threads[threadID]);
+ }
+ },
+ onIndexRefresh: function() {
+ var boardID, data, db, threadID, _ref;
+ db = ThreadWatcher.db;
+ boardID = g.BOARD.ID;
+ _ref = db.data.boards[boardID];
+ for (threadID in _ref) {
+ data = _ref[threadID];
+ if (!data.isDead && !(threadID in g.BOARD.threads)) {
+ if (Conf['Auto Prune']) {
+ ThreadWatcher.db["delete"]({
+ boardID: boardID,
+ threadID: threadID
+ });
+ } else {
+ data.isDead = true;
+ ThreadWatcher.db.set({
+ boardID: boardID,
+ threadID: threadID,
+ val: data
+ });
+ }
+ }
+ }
+ return ThreadWatcher.refresh();
+ },
+ onThreadRefresh: function(e) {
+ var thread;
+ thread = e.detail.thread;
+ if (!(e.detail[404] && ThreadWatcher.db.get({
+ boardID: thread.board.ID,
+ threadID: thread.ID
+ }))) {
+ return;
+ }
+ return ThreadWatcher.add(thread);
+ }
+ },
+ fetchCount: {
+ fetched: 0,
+ fetching: 0
+ },
+ fetchAllStatus: function() {
+ var thread, threads, _i, _len;
+ if (!(threads = ThreadWatcher.getAll()).length) {
+ return;
+ }
+ ThreadWatcher.status.textContent = '...';
+ for (_i = 0, _len = threads.length; _i < _len; _i++) {
+ thread = threads[_i];
+ ThreadWatcher.fetchStatus(thread);
+ }
+ },
+ fetchStatus: function(_arg) {
+ var boardID, data, fetchCount, threadID;
+ boardID = _arg.boardID, threadID = _arg.threadID, data = _arg.data;
+ if (data.isDead) {
+ return;
+ }
+ fetchCount = ThreadWatcher.fetchCount;
+ fetchCount.fetching++;
+ return $.ajax("//a.4cdn.org/" + boardID + "/res/" + threadID + ".json", {
+ onloadend: function() {
+ var status;
+ fetchCount.fetched++;
+ if (fetchCount.fetched === fetchCount.fetching) {
+ fetchCount.fetched = 0;
+ fetchCount.fetching = 0;
+ status = '';
+ } else {
+ status = "" + (Math.round(fetchCount.fetched / fetchCount.fetching * 100)) + "%";
+ }
+ ThreadWatcher.status.textContent = status;
+ if (this.status !== 404) {
+ return;
+ }
+ if (Conf['Auto Prune']) {
+ ThreadWatcher.db["delete"]({
+ boardID: boardID,
+ threadID: threadID
+ });
+ } else {
+ data.isDead = true;
+ ThreadWatcher.db.set({
+ boardID: boardID,
+ threadID: threadID,
+ val: data
+ });
+ }
+ return ThreadWatcher.refresh();
+ }
+ }, {
+ type: 'head'
+ });
+ },
+ getAll: function() {
+ var all, boardID, data, threadID, threads, _ref;
+ 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];
+ all.push({
+ boardID: boardID,
+ threadID: threadID,
+ data: data
+ });
+ }
+ }
+ return all;
+ },
+ makeLine: function(boardID, threadID, data) {
+ var div, fullID, href, link, x;
+ x = $.el('a', {
+ className: 'fa fa-times',
+ href: 'javascript:;'
+ });
+ $.on(x, 'click', ThreadWatcher.cb.rm);
+ if (data.isDead) {
+ href = Redirect.to('thread', {
+ boardID: boardID,
+ threadID: threadID
+ });
+ }
+ link = $.el('a', {
+ href: href || ("/" + boardID + "/res/" + threadID),
+ textContent: data.excerpt,
+ title: data.excerpt
+ });
+ 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');
+ }
+ $.add(div, [x, $.tn(' '), link]);
+ return div;
+ },
+ refresh: function() {
+ var boardID, data, helper, list, nodes, refresher, thread, threadID, toggler, watched, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3;
+ nodes = [];
+ _ref = ThreadWatcher.getAll();
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ _ref1 = _ref[_i], boardID = _ref1.boardID, threadID = _ref1.threadID, data = _ref1.data;
+ nodes.push(ThreadWatcher.makeLine(boardID, threadID, data));
+ }
+ list = ThreadWatcher.list;
+ $.rmAll(list);
+ $.add(list, nodes);
+ _ref2 = g.BOARD.threads;
+ for (threadID in _ref2) {
+ thread = _ref2[threadID];
+ toggler = $('.watch-thread-link', thread.OP.nodes.post);
+ watched = ThreadWatcher.db.get({
+ boardID: thread.board.ID,
+ threadID: threadID
+ });
+ helper = watched ? ['addClass', 'Unwatch'] : ['rmClass', 'Watch'];
+ $[helper[0]](toggler, 'watched');
+ toggler.title = "" + helper[1] + " Thread";
+ }
+ _ref3 = ThreadWatcher.menu.refreshers;
+ for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
+ refresher = _ref3[_j];
+ refresher();
+ }
+ },
+ 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
+ });
+ return ThreadWatcher.refresh();
+ },
+ rm: function(boardID, threadID) {
+ ThreadWatcher.db["delete"]({
+ boardID: boardID,
+ threadID: threadID
+ });
+ return ThreadWatcher.refresh();
+ },
+ convert: function(oldFormat) {
+ var boardID, data, newFormat, threadID, threads;
+ newFormat = {};
+ for (boardID in oldFormat) {
+ threads = oldFormat[boardID];
+ for (threadID in threads) {
+ data = threads[threadID];
+ (newFormat[boardID] || (newFormat[boardID] = {}))[threadID] = {
+ excerpt: data.textContent
+ };
+ }
+ }
+ return newFormat;
+ },
+ menu: {
+ refreshers: [],
+ init: function() {
+ var menu;
+ if (!Conf['Thread Watcher']) {
+ return;
+ }
+ 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:;'
+ });
+ $.event('AddMenuEntry', {
+ type: 'header',
+ el: entryEl,
+ order: 60
+ });
+ $.on(entryEl, 'click', function() {
+ return ThreadWatcher.toggle(g.threads["" + g.BOARD + "." + g.THREADID]);
+ });
+ return this.refreshers.push(function() {
+ var addClass, rmClass, text, _ref;
+ _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, name, refresh, subEntries, _i, _len, _ref, _ref1;
+ entries = [];
+ entries.push({
+ cb: ThreadWatcher.cb.openAll,
+ entry: {
+ type: 'thread watcher',
+ el: $.el('a', {
+ textContent: 'Open all threads'
+ })
+ },
+ refresh: function() {
+ return (ThreadWatcher.list.firstElementChild ? $.rmClass : $.addClass)(this.el, 'disabled');
+ }
+ });
+ entries.push({
+ cb: ThreadWatcher.cb.checkThreads,
+ entry: {
+ type: 'thread watcher',
+ el: $.el('a', {
+ textContent: 'Check 404\'d threads'
+ })
+ },
+ refresh: function() {
+ return ($('div:not(.dead-thread)', ThreadWatcher.list) ? $.rmClass : $.addClass)(this.el, 'disabled');
+ }
+ });
+ entries.push({
+ cb: ThreadWatcher.cb.pruneDeads,
+ entry: {
+ type: 'thread watcher',
+ el: $.el('a', {
+ textContent: 'Prune 404\'d 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: {
+ type: 'thread watcher',
+ el: $.el('span', {
+ textContent: 'Settings'
+ }),
+ subEntries: subEntries
+ }
+ });
+ for (_i = 0, _len = entries.length; _i < _len; _i++) {
+ _ref1 = entries[_i], 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));
+ }
+ $.event('AddMenuEntry', entry);
+ }
+ },
+ createSubEntry: function(name, desc) {
+ var entry, input;
+ entry = {
+ type: 'thread watcher',
+ el: $.el('label', {
+ innerHTML: " " + name,
+ title: desc
+ })
+ };
+ input = entry.el.firstElementChild;
+ input.checked = Conf[name];
+ $.on(input, 'change', $.cb.checked);
+ if (name === 'Current Board') {
+ $.on(input, 'change', ThreadWatcher.refresh);
+ }
+ return entry;
+ }
+ }
+ };
+
+ Unread = {
+ init: function() {
+ if (g.VIEW !== 'thread' || !Conf['Unread Count'] && !Conf['Unread Favicon'] && !Conf['Desktop Notifications']) {
+ return;
+ }
+ this.db = new DataBoard('lastReadPosts', this.sync);
+ this.hr = $.el('hr', {
+ id: 'unread-line'
+ });
+ this.posts = new RandomAccessList;
+ this.postsQuotingYou = [];
+ return Thread.callbacks.push({
+ name: 'Unread',
+ cb: this.node
+ });
+ },
+ node: function() {
+ Unread.thread = this;
+ Unread.title = d.title;
+ Unread.lastReadPost = Unread.db.get({
+ boardID: this.board.ID,
+ threadID: this.ID,
+ defaultValue: 0
+ });
+ $.on(d, '4chanXInitFinished', Unread.ready);
+ $.on(d, 'ThreadUpdate', Unread.onUpdate);
+ $.on(d, 'scroll visibilitychange', Unread.read);
+ if (Conf['Unread Line']) {
+ return $.on(d, 'visibilitychange', Unread.setLine);
+ }
+ },
+ ready: function() {
+ var ID, post, posts, _ref;
+ $.off(d, '4chanXInitFinished', Unread.ready);
+ posts = [];
+ _ref = Unread.thread.posts;
+ for (ID in _ref) {
+ post = _ref[ID];
+ if (post.isReply) {
+ posts.push(post);
+ }
+ }
+ Unread.addPosts(posts);
+ if (Conf['Quote Threading']) {
+ QuoteThreading.force();
+ }
+ if (Conf['Scroll to Last Read Post']) {
+ return Unread.scroll();
+ }
+ },
+ scroll: function() {
+ var down, hash, post, posts, root;
+ if ((hash = location.hash.match(/\d+/)) && hash[0] in Unread.thread.posts) {
+ return;
+ }
+ if (post = Unread.posts.first) {
+ while (root = $.x('preceding-sibling::div[contains(@class,"replyContainer")][1]', post.nodes.root)) {
+ if (!(post = Get.postFromRoot(root)).isHidden) {
+ break;
+ }
+ }
+ if (!root) {
+ return;
+ }
+ down = true;
+ } else {
+ posts = Object.keys(Unread.thread.posts);
+ root = Unread.thread.posts[posts[posts.length - 1]].nodes.root;
+ }
+ if (Header.getBottomOf(root) < 0) {
+ return Header.scrollTo(root, down);
+ }
+ },
+ sync: function() {
+ var ID, lastReadPost, post;
+ lastReadPost = Unread.db.get({
+ boardID: Unread.thread.board.ID,
+ threadID: Unread.thread.ID,
+ defaultValue: 0
+ });
+ if (!(Unread.lastReadPost < lastReadPost)) {
+ return;
+ }
+ Unread.lastReadPost = lastReadPost;
+ post = Unread.posts.first;
+ while (post) {
+ if ((ID = post.ID, post) > Unread.lastReadPost) {
+ break;
+ }
+ post = post.next;
+ Unread.posts.rm(ID);
+ }
+ Unread.readArray(Unread.postsQuotingYou);
+ if (Conf['Unread Line']) {
+ Unread.setLine();
+ }
+ return Unread.update();
+ },
+ addPosts: function(posts) {
+ var ID, post, _i, _len, _ref;
+ for (_i = 0, _len = posts.length; _i < _len; _i++) {
+ post = posts[_i];
+ ID = post.ID;
+ if (ID <= Unread.lastReadPost || post.isHidden || QR.db.get({
+ boardID: post.board.ID,
+ threadID: post.thread.ID,
+ postID: ID
+ })) {
+ continue;
+ }
+ if (!(post.prev || post.next)) {
+ Unread.posts.push(post);
+ }
+ Unread.addPostQuotingYou(post);
+ }
+ if (Conf['Unread Line']) {
+ Unread.setLine((_ref = Unread.posts.first, __indexOf.call(posts, _ref) >= 0));
+ }
+ Unread.read();
+ return Unread.update();
+ },
+ addPostQuotingYou: function(post) {
+ var quotelink, _i, _len, _ref;
+ if (!QR.db) {
+ return;
+ }
+ _ref = post.nodes.quotelinks;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ quotelink = _ref[_i];
+ if (!(QR.db.get(Get.postDataFromLink(quotelink)))) {
+ continue;
+ }
+ Unread.postsQuotingYou.push(post);
+ Unread.openNotification(post);
+ return;
+ }
+ },
+ openNotification: function(post) {
+ var name, notif;
+ if (!Header.areNotificationsEnabled) {
+ return;
+ }
+ name = Conf['Anonymize'] ? 'Anonymous' : $('.nameBlock', post.nodes.info).textContent.trim();
+ notif = new Notification("" + name + " replied to you", {
+ body: post.info.comment,
+ icon: Favicon.logo
+ });
+ notif.onclick = function() {
+ Header.scrollToIfNeeded(post.nodes.root, true);
+ return window.focus();
+ };
+ return notif.onshow = function() {
+ return setTimeout(function() {
+ return notif.close();
+ }, 7 * $.SECOND);
+ };
+ },
+ onUpdate: function(e) {
+ if (e.detail[404]) {
+ return Unread.update();
+ } else {
+ return Unread.addPosts(e.detail.newPosts);
+ }
+ },
+ readSinglePost: function(post) {
+ var ID, i;
+ ID = post.ID;
+ if (!Unread.posts[ID]) {
+ return;
+ }
+ if (post === Unread.posts.first) {
+ Unread.lastReadPost = ID;
+ Unread.saveLastReadPost();
+ }
+ Unread.posts.rm(ID);
+ if ((i = Unread.postsQuotingYou.indexOf(post)) !== -1) {
+ Unread.postsQuotingYou.splice(i, 1);
+ }
+ return Unread.update();
+ },
+ readArray: function(arr) {
+ var i, post, _i, _len;
+ for (i = _i = 0, _len = arr.length; _i < _len; i = ++_i) {
+ post = arr[i];
+ if (post.ID > Unread.lastReadPost) {
+ break;
+ }
+ }
+ return arr.splice(0, i);
+ },
+ read: $.debounce(100, function(e) {
+ var ID, height, post, posts;
+ if (d.hidden || !Unread.posts.length) {
+ return;
+ }
+ height = doc.clientHeight;
+ posts = Unread.posts;
+ while (post = posts.first) {
+ if (!(Header.getBottomOf(post.nodes.root) > -1)) {
+ break;
+ }
+ ID = post.ID;
+ posts.rm(ID);
+ if (Conf['Mark Quotes of You'] && post.info.yours) {
+ QuoteYou.lastRead = post.nodes.root;
+ }
+ }
+ if (!ID) {
+ return;
+ }
+ if (Unread.lastReadPost < ID || !Unread.lastReadPost) {
+ Unread.lastReadPost = ID;
+ }
+ Unread.saveLastReadPost();
+ Unread.readArray(Unread.postsQuotingYou);
+ if (e) {
+ return Unread.update();
+ }
+ }),
+ saveLastReadPost: $.debounce(2 * $.SECOND, function() {
+ if (Unread.thread.isDead) {
+ return;
+ }
+ return Unread.db.set({
+ boardID: Unread.thread.board.ID,
+ threadID: Unread.thread.ID,
+ val: Unread.lastReadPost
+ });
+ }),
+ setLine: function(force) {
+ var post;
+ if (!(d.hidden || force === true)) {
+ return;
+ }
+ if (!(post = Unread.posts.first)) {
+ return $.rm(Unread.hr);
+ }
+ if ($.x('preceding-sibling::div[contains(@class,"replyContainer")]', post.nodes.root)) {
+ return $.before(post.nodes.root, Unread.hr);
+ }
+ },
+ update: function() {
+ var count;
+ count = Unread.posts.length;
+ if (Conf['Unread Count']) {
+ d.title = "" + (Conf['Quoted Title'] && Unread.postsQuotingYou.length ? '(!) ' : '') + (count || !Conf['Hide Unread Count at (0)'] ? "(" + count + ") " : '') + (g.DEAD ? "/" + g.BOARD + "/ - 404" : "" + Unread.title);
+ }
+ if (!Conf['Unread Favicon']) {
+ return;
+ }
+ Favicon.el.href = g.DEAD ? Unread.postsQuotingYou[0] ? Favicon.unreadDeadY : count ? Favicon.unreadDead : Favicon.dead : count ? Unread.postsQuotingYou[0] ? Favicon.unreadY : Favicon.unread : Favicon["default"];
+ return $.add(d.head, Favicon.el);
+ }
+ };
+
+ Redirect = {
+ init: function() {
+ var archive, archives, boardID, boards, data, files, id, name, o, record, software, type, _i, _len, _ref, _ref1;
+ o = {
+ thread: {},
+ post: {},
+ file: {}
+ };
+ archives = Redirect.archives;
+ _ref = Conf['selectedArchives'];
+ for (boardID in _ref) {
+ record = _ref[boardID];
+ for (type in record) {
+ id = record[type];
+ if (!((archive = archives[id]))) {
+ continue;
+ }
+ boards = type === 'file' ? archive.files : archive.boards;
+ if (__indexOf.call(boards, boardID) < 0) {
+ continue;
+ }
+ o[type][boardID] = archive.data;
+ }
+ }
+ for (name in archives) {
+ _ref1 = archives[name], data = _ref1.data, boards = _ref1.boards, files = _ref1.files;
+ software = data.software;
+ for (_i = 0, _len = boards.length; _i < _len; _i++) {
+ boardID = boards[_i];
+ 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;
+ }
+ }
+ }
+ return Redirect.data = o;
+ },
+ archives: {
+ "Foolz": {
+ boards: ["a", "biz", "co", "gd", "jp", "m", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"],
+ files: ["a", "biz", "gd", "jp", "m", "tg", "vg", "vp", "vr", "wsg"],
+ data: {
+ domain: "archive.foolz.us",
+ http: false,
+ https: true,
+ software: "foolfuuka"
+ }
+ },
+ "NSFW Foolz": {
+ boards: ["u"],
+ files: ["u"],
+ data: {
+ domain: "nsfw.foolz.us",
+ http: false,
+ https: true,
+ software: "foolfuuka"
+ }
+ },
+ "The Dark Cave": {
+ boards: ["c", "int", "out", "po"],
+ files: ["c", "po"],
+ data: {
+ domain: "archive.thedarkcave.org",
+ http: true,
+ https: true,
+ software: "foolfuuka"
+ }
+ },
+ "4plebs": {
+ boards: ["adv", "hr", "o", "pol", "s4s", "tg", "tv", "x"],
+ files: ["adv", "hr", "o", "pol", "s4s", "tg", "tv", "x"],
+ data: {
+ domain: "archive.4plebs.org",
+ http: true,
+ https: true,
+ software: "foolfuuka"
+ }
+ },
+ "Nyafuu": {
+ boards: ["c", "e", "w", "wg"],
+ files: ["c", "e", "w", "wg"],
+ data: {
+ domain: "archive.nyafuu.org",
+ http: true,
+ https: true,
+ software: "foolfuuka"
+ }
+ },
+ "Love is Over": {
+ boards: ["d", "i"],
+ files: ["d", "i"],
+ data: {
+ domain: "loveisover.me",
+ http: true,
+ https: true,
+ software: "foolfuuka"
+ }
+ },
+ "Install Gentoo (.net)": {
+ boards: ["diy", "g", "sci"],
+ files: [],
+ data: {
+ domain: "archive.installgentoo.net",
+ http: false,
+ https: true,
+ software: "fuuka"
+ }
+ },
+ "Install Gentoo (.com)": {
+ boards: ["t", "g"],
+ files: ["t", "g"],
+ data: {
+ domain: "archive.installgentoo.com/",
+ http: true,
+ https: true,
+ software: "foolfuuka"
+ }
+ },
+ "Rebecca Black Tech": {
+ boards: ["cgl", "g", "mu", "w"],
+ files: ["cgl", "g", "mu", "w"],
+ data: {
+ domain: "rbt.asia",
+ http: true,
+ https: true,
+ software: "fuuka"
+ }
+ },
+ "Heinessen": {
+ boards: ["an", "fit", "k", "mlp", "r9k", "toy"],
+ files: ["an", "fit", "k", "r9k", "toy"],
+ data: {
+ domain: "archive.heinessen.com",
+ http: true,
+ software: "fuuka"
+ }
+ },
+ "warosu": {
+ boards: ["3", "cgl", "ck", "fa", "ic", "jp", "lit", "tg", "vr"],
+ files: ["3", "cgl", "ck", "fa", "ic", "jp", "lit", "tg", "vr"],
+ data: {
+ domain: "fuuka.warosu.org",
+ http: true,
+ https: true,
+ software: "fuuka"
+ }
+ },
+ "fgst": {
+ boards: ["r", "soc"],
+ files: ["r", "soc"],
+ data: {
+ domain: "fgst.eu",
+ http: true,
+ https: true,
+ software: "foolfuuka"
+ }
+ },
+ "maware": {
+ boards: ["t"],
+ files: ["t"],
+ data: {
+ domain: "archive.mawa.re",
+ http: true,
+ https: false,
+ software: "foolfuuka"
+ }
+ },
+ "Foolz Beta": {
+ boards: ["a", "co", "gd", "jp", "m", "s4s", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
+ files: ["a", "gd", "jp", "m", "s4s", "tg", "u", "vg", "vp", "vr", "wsg"],
+ data: {
+ domain: "beta.foolz.us",
+ http: true,
+ https: true,
+ withCredentials: true,
+ software: "foolfuuka"
+ }
+ }
+ },
+ to: function(dest, data) {
+ var archive;
+ archive = (dest === 'search' ? 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 URL, boardID, postID;
+ boardID = _arg.boardID, postID = _arg.postID;
+ URL = new String("" + (Redirect.protocol(archive)) + archive.domain + "/_/api/chan/post/?board=" + boardID + "&num=" + postID);
+ URL.archive = archive;
+ 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;
+ },
+ 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;
+ value = encodeURIComponent(value);
+ path = archive.software === 'foolfuuka' ? "" + boardID + "/search/" + type + "/" + value : "" + boardID + "/?task=search2&search_" + (type === 'image' ? 'media_hash' : type) + "=" + value;
+ return "" + (Redirect.protocol(archive)) + archive.domain + "/" + path;
+ }
+ };
+
+ PSAHiding = {
+ init: function() {
+ if (!Conf['Announcement Hiding']) {
+ return;
+ }
+ $.addClass(doc, 'hide-announcement');
+ return $.on(d, '4chanXInitFinished', this.setup);
+ },
+ setup: function() {
+ var btn, entry, psa;
+ $.off(d, '4chanXInitFinished', PSAHiding.setup);
+ if (!(psa = $.id('globalMessage'))) {
+ $.rmClass(doc, 'hide-announcement');
+ return;
+ }
+ entry = {
+ type: 'header',
+ el: $.el('a', {
+ textContent: 'Show announcement',
+ className: 'show-announcement',
+ href: 'javascript:;'
+ }),
+ order: 50,
+ open: function() {
+ return psa.hidden;
+ }
+ };
+ $.event('AddMenuEntry', entry);
+ $.on(entry.el, 'click', PSAHiding.toggle);
+ PSAHiding.btn = btn = $.el('span', {
+ innerHTML: '[Dismiss ]',
+ title: 'Mark announcement as read and hide.',
+ className: 'hide-announcement',
+ href: 'javascript:;'
+ });
+ $.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(e) {
+ 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 hr, psa;
+ psa = $.id('globalMessage');
+ psa.hidden = PSAHiding.btn.hidden = UTC && UTC >= +psa.dataset.utc ? true : false;
+ if ((hr = psa.nextElementSibling) && hr.nodeName === 'HR') {
+ return hr.hidden = psa.hidden;
+ }
+ }
+ };
+
+ Banner = {
+ init: function() {
+ return $.asap((function() {
+ return d.body;
+ }), function() {
+ return $.asap((function() {
+ return $('.abovePostForm');
+ }), Banner.ready);
+ });
+ },
+ ready: function() {
+ var banner, child, children, i;
+ banner = $(".boardBanner");
+ children = banner.children;
+ i = 0;
+ while (child = children[i++]) {
+ if (i === 1) {
+ child.id = "Banner";
+ child.title = "Click to change";
+ $.on(child, 'click', Banner.cb.toggle);
+ continue;
+ }
+ if (Conf['Custom Board Titles']) {
+ Banner.custom(child).title = "Ctrl+click to edit board " + (i === 3 ? 'sub' : '') + "title";
+ child.spellcheck = false;
+ }
+ }
+ },
+ cb: {
+ toggle: (function() {
+ var types;
+ types = {
+ jpg: 227,
+ png: 270,
+ gif: 253
+ };
+ return function() {
+ var num, type;
+ type = Object.keys(types)[Math.floor(3 * Math.random())];
+ num = Math.floor(types[type] * Math.random());
+ return this.src = "//static.4chan.org/image/title/" + num + "." + type;
+ };
+ })(),
+ click: function(e) {
+ if (e.ctrlKey) {
+ this.contentEditable = true;
+ return this.focus();
+ }
+ },
+ keydown: function(e) {
+ e.stopPropagation();
+ if (!e.shiftKey && e.keyCode === 13) {
+ return this.blur();
+ }
+ },
+ focus: function() {
+ var items, string, string2;
+ this.textContent = this.innerHTML;
+ string = "" + g.BOARD + "." + this.className;
+ string2 = "" + string + ".orig";
+ items = {
+ title: this.innerHTML
+ };
+ items[string] = '';
+ items[string2] = false;
+ $.get(items, function(items) {
+ if (!(items[string2] && items.title === items[string])) {
+ return $.set(string2, items.title);
+ }
+ });
+ },
+ blur: function() {
+ this.innerHTML = this.textContent;
+ this.contentEditable = false;
+ return $.set("" + g.BOARD + "." + this.className, this.textContent);
+ }
+ },
+ custom: function(child) {
+ var cachedTest, string;
+ cachedTest = child.innerHTML;
+ string = "" + g.BOARD + "." + child.className;
+ $.on(child, 'click keydown focus blur', function(e) {
+ return Banner.cb[e.type].apply(this, [e]);
+ });
+ $.get(string, cachedTest, function(item) {
+ var string2, title;
+ if (!(title = item[string])) {
+ return;
+ }
+ if (Conf['Persistent Custom Board Titles']) {
+ return child.innerHTML = title;
+ }
+ string2 = "" + string + ".orig";
+ return $.get(string2, cachedTest, function(itemb) {
+ if (cachedTest === itemb[string2]) {
+ return child.innerHTML = title;
+ } else {
+ $.set(string, cachedTest);
+ return $.set(string2, cachedTest);
+ }
+ });
+ });
+ return child;
+ }
+ };
+
+ CatalogLinks = {
+ init: function() {
+ var el, input;
+ if (!Conf['Catalog Links']) {
+ return;
+ }
+ CatalogLinks.el = el = $.el('label', {
+ id: 'toggleCatalog',
+ href: 'javascript:;',
+ innerHTML: " Catalog Links"
+ });
+ input = $('input', el);
+ $.on(input, 'change', this.toggle);
+ $.sync('Header catalog links', CatalogLinks.set);
+ $.event('AddMenuEntry', {
+ type: 'header',
+ el: el,
+ order: 95
+ });
+ return $.on(d, '4chanXInitFinished', function() {
+ 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, generateURL, path, _i, _len, _ref, _ref1;
+ path = useCatalog ? 'catalog' : '';
+ generateURL = useCatalog && Conf['External Catalog'] ? CatalogLinks.external : function(board) {
+ return a.href = "/" + board + "/" + path;
+ };
+ _ref = $$("#board-list a:not(.catalog), #boardNavDesktopFoot a");
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ a = _ref[_i];
+ if (((_ref1 = a.hostname) !== 'boards.4chan.org' && _ref1 !== 'catalog.neet.tv' && _ref1 !== '4index.gropes.us') || !(board = a.pathname.split('/')[1]) || (board === 'f' || board === 'status' || board === '4chan')) {
+ continue;
+ }
+ a.href = generateURL(board);
+ }
+ return CatalogLinks.el.title = "Turn catalog links " + (useCatalog ? 'off' : 'on') + ".";
+ },
+ external: function(board) {
+ switch (board) {
+ case 'a':
+ case 'c':
+ case 'g':
+ case 'co':
+ case 'k':
+ case 'm':
+ case 'o':
+ case 'p':
+ case 'v':
+ case 'vg':
+ case 'w':
+ case 'cm':
+ case '3':
+ case 'adv':
+ case 'an':
+ case 'cgl':
+ case 'ck':
+ case 'diy':
+ case 'fa':
+ case 'fit':
+ case 'int':
+ case 'jp':
+ case 'mlp':
+ case 'lit':
+ case 'mu':
+ case 'n':
+ case 'po':
+ case 'sci':
+ case 'toy':
+ case 'trv':
+ case 'tv':
+ case 'vp':
+ case 'x':
+ case 'q':
+ return "http://catalog.neet.tv/" + board;
+ case 'd':
+ case 'e':
+ case 'gif':
+ case 'h':
+ case 'hr':
+ case 'hc':
+ case 'r9k':
+ case 's':
+ case 'pol':
+ case 'soc':
+ case 'u':
+ case 'i':
+ case 'ic':
+ case 'hm':
+ case 'r':
+ case 'w':
+ case 'wg':
+ case 'wsg':
+ case 't':
+ case 'y':
+ return "http://4index.gropes.us/" + board;
+ default:
+ return "/" + board + "/catalog";
+ }
+ }
+ };
+
+ CustomCSS = {
+ init: function() {
+ if (!Conf['Custom CSS']) {
+ return;
+ }
+ return this.addStyle();
+ },
+ addStyle: function() {
+ return this.style = $.addStyle(Conf['usercss']);
+ },
+ rmStyle: function() {
+ if (this.style) {
+ $.rm(this.style);
+ return delete this.style;
+ }
+ },
+ update: function() {
+ if (!this.style) {
+ this.addStyle();
+ }
+ return this.style.textContent = Conf['usercss'];
+ }
+ };
+
+ Dice = {
+ init: function() {
+ if (g.BOARD.ID !== 'tg' || g.VIEW === 'catalog' || !Conf['Show Dice Roll']) {
+ return;
+ }
+ return Post.callbacks.push({
+ name: 'Show Dice Roll',
+ cb: this.node
+ });
+ },
+ node: function() {
+ var dicestats, roll, _ref;
+ if (this.isClone || !(dicestats = (_ref = this.info.email) != null ? _ref.match(/dice[+\s](\d+)d(\d+)/) : void 0)) {
+ return;
+ }
+ roll = $('b', this.nodes.comment).firstChild;
+ return roll.data = "Rolled " + dicestats[1] + "d" + dicestats[2] + ": " + (roll.data.slice(7));
+ }
+ };
+
+ Emoji = {
+ init: function() {
+ var css, icon, name, pos, _ref;
+ if (!Conf['Emoji']) {
+ return;
+ }
+ pos = Conf['emojiPos'];
+ css = ["a.useremail[href]:last-of-type::" + pos + " {\n vertical-align: top;\n margin-" + (pos === "before" ? "right" : "left") + ": 5px;\n}\n"];
+ this.icons["PlanNine"] = Emoji.icons["Plan9"];
+ this.icons['Sage'] = Emoji.sage[Conf['sageEmoji']];
+ _ref = this.icons;
+ for (name in _ref) {
+ icon = _ref[name];
+ if (!this.icons.hasOwnProperty(name)) {
+ continue;
+ }
+ css.push("a.useremail[href*='" + name + "']:last-of-type::" + pos + ",\na.useremail[href*='" + (name.toLowerCase()) + "']:last-of-type::" + pos + ",\na.useremail[href*='" + (name.toUpperCase()) + "']:last-of-type::" + pos + " {\n content: url('data:image/png;base64," + icon + "');\n}\n");
+ }
+ return $.addStyle(css.join(""), 'emoji');
+ },
+ sage: {
+ '4chan SS': 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAMAAACuAq9NAAABIFBMVEUAAAAAXwAAOAAAVQAAKgAAOgAALwAAagAATwAAdAAAYAAAYwAARAAAcgAANwAAOAABcwEBZAEBXwEAQwABbwEBaQEBWgEBTwECdAICaQIIcwgBWQEIXAcARAAALgACdAICbQICdAICcAIBVQEBTgEAQgAAQwAkjCIcexomgSIcbRtCnj9IpUNEmT5LoUNYtFE9lDtClD5dtVJqwmNCmEFMoEh1zGcnfCYnfCc6jzc7kDs9kjxAlUBDmEFInUNLoEpMoExOo0tPpExQpU1Rpk1Sp0pSp1JXrFVZrlhar1Rar1pes1xftFhhtmFit19juFxkuVxovWRrwGBuw2Juw2Nuw2Ruw2V0yWx1ym14zWt6z2980W6A1XGD2HSD2XSI3XdgUJhRAAAAN3RSTlMACAkJDBobHyBERUVHR3KIiYyNkJmanZ6rrq+ws7S5vL29vsLFxsfP0dLU5eXn5+vt7e34+fn5LB88GQAAAI1JREFUGFdNzjsSwjAMRdGn2PngmZAUVHQshP0vArYQYCYDlmxLos3tTncx4xjdAMCEhR1ApLup+bPxtgsQzZ2Mr4iPYROEU129g6it0jJCv6xqFJlpKbl2kr21Zsl/Mo0IBpmrqg7ZnPfgSnKuqhrKwO+AVrSUOjmo5VcEuHzH9CEAXaTDYZ88HGh++QNCDFZ4bvbHSQAAAABJRU5ErkJggg==',
+ 'appchan': 'iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAABa1BMVEUAAACqrKiCgYIAAAAAAAAAAACHmX5pgl5NUEx/hnx4hXRSUVMiIyKwrbFzn19SbkZ1d3OvtqtpaWhcX1ooMyRsd2aWkZddkEV8vWGcpZl+kHd7jHNdYFuRmI4bHRthaV5WhUFsfGZReUBFZjdJazpGVUBnamYfHB9TeUMzSSpHgS1cY1k1NDUyOC8yWiFywVBoh1lDSEAZHBpucW0ICQgUHhBjfFhCRUA+QTtEQUUBAQFyo1praWspKigWFRZHU0F6j3E9Oz5VWFN0j2hncWONk4sAAABASDxJWkJKTUgAAAAvNC0fJR0DAwMAAAA9QzoWGhQAAAA8YytvrFOJsnlqyT9oqExqtkdrsExpsUsqQx9rpVJDbzBBbi5utk9jiFRuk11iqUR64k5Wf0JIZTpadk5om1BkyjmF1GRNY0FheFdXpjVXhz86XSp2yFJwslR3w1NbxitbtDWW5nNnilhFXTtYqDRwp1dSijiJ7H99AAAAUnRSTlMAJTgNGQml71ypu3cPEN/RDh8HBbOwQN7wVg4CAQZ28vs9EDluXjo58Ge8xwMy0P3+rV8cT73sawEdTv63NAa3rQwo4cUdAl3hWQSWvS8qqYsjEDiCzAAAAIVJREFUeNpFx7GKAQAYAOD/A7GbZVAWZTBZFGQw6LyCF/MIkiTdcOmWSzYbJVE2u1KX0J1v+8QDv/EkyS0yXF/NgeEILiHfyc74mICTQltqYXBeAWU9HGxU09YqqEvAElGjyZYjPyLqitjzHSEiGkrsfMWr0VLe+oy/djGP//YwfbeP8bN3Or0bkqEVblAAAAAASUVORK5CYII='
+ },
+ icons: {
+ 'Plan9': 'iVBORw0KGgoAAAANSUhEUgAAAAwAAAAPCAYAAAGn5h7fAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAzE15J1s7QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAACAElEQVQoz3WSz4sSARTHvzMjygpqYg3+KIhkE83DKtKlf0C9SrTRuZNEx0VowU6CuSeJNlwwpEO2kJ6SQBiIUAzFjRDF4wrjKosnGx3HmdehFDfpe/2+z/s++D5gU7IsEwRByICIiAEAIiIAYAFAXsjYVr/fLxMRNVvN+prJ5/OA3+/XERFNf02JyeVyDx0OxyvLNQsnimLKfcf9KRQKXQAAnE6nlf5qMpnQycnbP/kAoKoqsSwLAJhOp+AAwOv1otvtpqxWq73dbt/r9XqvEQ6HUalUEvF4XLd5IpvNZqlerzd5nlf6/f6tTCZjBACk0+nb+XxeW4UrikLJZPImAGA0Gq0NIqJyuSyyANDr9Q5Wu1utFvR6/SULAI1G4+vK8Pv90DTtGwsAJpPpaGUYDAZ0Op3PHAAEg8H3tVqtbrtu21sqyxuRSOQJk0ql9IvF4r7b7f7pcrlejkaj57IsH58Pzp8dvjhc/lsBk0gkbLFYrFqtVvd27+4qOk733ePxPDCbzVBVFfP5fCiK4rvhxfDN/qP9wSasGwwGMv1HiqJQsVg8ZlfTHMepkiR1t05gGJBGmM/nMBqNj9nN9kql0lNN064ARISzH2cQBAGz2ewLu2na7XYLwzBbvxYIBBCNRrFj3BmsAZ/PZ+J5/kOhUIAkSVeA8XiMZqt5efrx9OA3GfcgvyVno9cAAAAASUVORK5CYII=',
+ 'Neko': 'iVBORw0KGgoAAAANSUhEUgAAABMAAAARCAMAAAAIRmf1AAACoFBMVEUAAABnUFZoUVddU1T6+PvFwLzn4eFXVlT/+vZpZGCgm5dKU1Cfnpz//flbWljr5uLp5OCalpNZWFb//f3r6+n28ff9+PRaVVH59Pr//vr38vj57/Dp7eyjn5zq8O5aVVJbYV9nVFhjUFRiWFlZVlFgZGOboJzm5uZhamfz9/bt8fDw6+drb26bl5j/8/lkX1z06uldWFS5r61UT0tfWlbDwr3Ew76moqNRTU7Mx8P75OpeY19pWl1XW1qzr6x5eHaLiojv7+1UT0xIU0uzqadVS0nV0MxkZGT5+PPk497///ra29Xq5eFtY2H28e2hnJignJlUUE1dXV2vrqxkY2FkYF/m3d5vZmfDuruhl5aZlJHx8O75+PZWVVP29vT/9fTj3trv6ubh5eRdXFqTkpBOTUtqZmX88/RMQ0T78vPEvr7HwcHDwsDq6ef///3Gx8H++fXEv7tZWVedmZZXXVudnJp0c3FZU1f79fnb1dlXUVVjXWFrZmy8t7359/qLj455e3q4s69vamZjX1zy4+avpaReWFz/+f1NR0vu6Ozp4+f48/lnYmi8ur3Iw7/69fHz7+xbV1SZmJZVUk1ZV1zq5ez++f/c196uqbDn4uj9+P7z7vRVVVXt6ORiXl/OycXHw8CPi4ihoJ5aWF3/+v/k3+axrLOsp67LzMZYU1m2sq9dWF5WUU1WUk/Au7eYlJGqpqObmphYVV749f7p5Or38fPu6OpiXFz38fH79vLz7urv6+hhYF5cWWKal6D//f/Z09Xg29exraqbl5RqaW6kpKTq5uPv7Of/+PDj29D//vP18Ozs5+OloJymoZ1ZVVJZWVlkYF2hnpmblIyspJmVjYKQi4enop5STUlRTUpcWUhqY1BgWT9ZUjhcV1NiXVkkhke3AAAABHRSTlMA5vjapJ+a9wAAAP9JREFUGBk9wA1EAwEAhuHv3dTQAkLiUlJFJWF0QDLFYDRXIMkomBgxNIYxhOk4wwCqQhQjxgxSGIsALFA5BiYbMZHajz1oJlx51sBJpf6Gd3zONcrqm/r1W8ByK0r+XV1LXyOLLnjW6hMGpu0u1IzPSdO17DgrGC6AadrVodGcDQYbhguP6wAvAaC0BRZQalkUQ8UQDz5tAof0XbejOFcV5xiUoCfjj3O/nf0ZbqAMPYmzU18KSDaRQ08qnfw+B2JNdAEQt2O5vctUGjhoIBU4ygPsj2Vh5zYopDK73hsirdkPTwGCbSHpiYFwYVVC/17pCFSBeUmoqwYQuZtWxx+BVEz0LeVKIQAAAABJRU5ErkJggg==',
+ 'Madotsuki': 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAMAAADTRh9nAAAALVBMVEUAAAC3iopWLTtWPkHnvqUcBxx5GCZyAAARERGbdXJrRUyGRUyYbY23coZFGDRFGEYfAAAAAXRSTlMAQObYZgAAAGdJREFUeNpVywkOwCAQAkAXtPb+/3PLWklTiIlMtDiH4rvpVM22K+WvY+7Z/dOxZ2xkLmYpNWo6RoKMUQJ8SYiozEYiZAuLbCZQsGB+/hC4SwZsdV2rTjSR0+J9tzXL0B4RW5f9VbE94skEEpHbpw8AAAAASUVORK5CYII=',
+ 'Sega': 'iVBORw0KGgoAAAANSUhEUgAAACwAAAALBAMAAAD2A3K8AAAAMFBMVEUAAACMjpOChImytLmdnqMrKzDIyM55dnkODQ94foQ7PkXm5Olsb3VUUVVhZmw8Sl6klHLxAAAAAXRSTlMAQObYZgAAANFJREFUGJVjYIACRiUlJUUGDHBk4syTkxQwhO3/rQ/4ZYsuymi3YEFUqAhC4LCJZJGIi1uimKKjk3KysbOxsaMnAwNLyqoopaXhttf2it1anrJqke1pr1DlBAZhicLnM5YXZ4RWlIYoezx0zrjYqG6czCDsYRzxIko6Q/qFaKy0690Ij0MxN8K2MIhJXF+hsfxJxuwdpYGVaUU3Mm5bqgKFOZOFit3Vp23J3pgsqLxFUXpLtlD5bgcGBs45794dn6mkOVFQUOjNmXPPz8ysOcAAANw6SHLtrqolAAAAAElFTkSuQmCC',
+ 'Sakamoto': 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAQCAYAAADwMZRfAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAxVJREFUOE+Nk19IU1EYwK+GQQTVQ39egh6ibKlzw91z7rn3bvfOmddNszl1bjKXc5rJJGmBUr7Yg9qTD0IalFgRBEYg6EDQQB+GovQyQgiaUZsoLcgHMcr069w7MgcGXfi453zn+37fv3MYZt/n99e76tzVj4JN/hP79fvXnV3hnNabwUBjoOHcgTYOu/JQspgTzsqKgn9BfD4vkWTzur287PqLVy+zM+yePB7KsRXLywTjnSpnZctBkPCdW8ccDuU55vBO8RXbkC/oP5ph19V5+7LIky0OY1BKbZEbLcFSt7u6pN7jLmltCVrr3DV5jY3+KovFEsccB1KJNVpefe10BqS2tqqO4/AuphBB4L/LkrRqNgtJs1lMypLls1kU38mytMLz/E8VIlutqVqX6/weZG52OttRXjbE0cP/FYLRlpVjDXuQ/r77x2XZPKkCHA4HBAIBkCQpAygIAvh8Pu2MZgO0Lz+QSa/sQfwN9RfpVN66XC6Ynp6GhYUFGBwczAC1t7fD0tISxONx6O7upgHILmsqvLcHodOggfiV/v5+SCaT4HQ6IRaLgdfr1bIRRREmJyfBZrNBNBqF+fl5sNsdgE2GiAbp6bmbdbXC7qWQbxMTE7C2tgY6nQ5SqRSEw2ENopaoZpCXlwdTU1NaoECgCbgiU6y8QH+ECYWaTymK7TWdys7MzIwGaWtrg42NDejo6AB1WjU1NZo+FArB2NgYrK6uQrAlCASxn2z6wkuMp87VIAhkE2MEAwMDkEgkYHx8HBYXF0HtkQpRy1BLiEQisLy8rPVNKSsFjEzrXH4+z1hlS4xDhKadNu7t7YPR0VHweDzAEVWfHru6HxkZgeHhYVAURYNjkylVWKArZjjMzqmdVi+QCsLUkQiEjvDvncEkvU7/qQ0Vgukeo48Go87IiCJnZNmipxiz7wXEbVDnbUxQOgM12h9n6qTq6NvapRdtkwaP0XK8RmPuYSbxYfaQ/sJJhjfknuFRURUi7AMOozcCwl94hLZp5F+EioDQVwqYI6jomZU1NFtM+rOSxZjVazcyvwHr/p/Kws1jegAAAABJRU5ErkJggg==',
+ 'Baka': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAA0pJREFUOE91k3tI01EUx39JOpA0H4jNx0pbD3XTalISWf8YFlEgldqDsBLLyqjEKBCiLLWiggh6/KEV1WZ7OaelLZvDdDafNW1JFraWe/32+01FrUZ9uy4ylLpw4Z5z7/nc77n3HIqaMRIjZJyEcNX+uFCFeGmI/GZciEIsCFJUTvoAzDz+1y7K76MSwhX5hXl6z+WSbrzU2KB8YEGDwgrTaxZ3b7xHcaHhR3xw7Z5/UviB1ReP5XSg3+TAqYJOxMzWISFIC0GQDomhTVA9skCnsaAwp/vnMq66dBokNuBR9uFd7T9Z1zCunjci0qcRJUVdoJ3DYOhRnC/qBZ+jQbfeCc+37yjY2UEg0iwvJE0k9l8Z+8xqHmTgot0QLdQgTaQFQ2AsOzlHvOu1S5pwOLsHHo8HjHMCq2MazNvTlByKHyrJLDvdR25jMWRxYx5HjeMH2r1BDOOeguRua4OI14jx8a8YH5tA+al3EHKlW6mYOapb2oZBOOwMbEMseAE12L+jjUh3w+VipyAZ65oxn1NP/GMYGR6Ftn4Qsf7qa9S82Y/l/X122G0uL2TbxmZEz1WhXW8mUol8moXu+SCi/OoQ6VsDh3UUwyQ1k9GOaI5MTkX4yWTGHutvgI1F28sviAlRgxeoRm62HvsyW8En9pZ1TYgi6TntoyQtFm86rVgUoJZRvDnKMmXVAGxWmkAYOBwudBqGcHCvHulrGpGT2Uy+z4yT+QYsCXtCUpp8GxbKhx8gDK0ro+KjJGvzdjfDZnN6VdisLD5/JjArQ2zW66PJOj2lEZtStaBphkwah7K6kMJ/GEulp1bMWhAmMbTozOQRaWRtfoZVgjo4iRra4SYgGi26TwjxVeDKhR7Y7U606ixICq9tr7hd7+OthRWL7yUnJ1WPmXotqLhpRICPHCePtuFV6xdUPTAhcWEtRHEqfHpPyto4hPXLXnzflSEJnFaN3OCKDcsFsrEntR9RUmxARLAUgT5iBPuJsXWDBj0dZjRU9yNV+PTbpjTp9OA/pOSk24nRkXf1J462oPxcJ65f6ULlHSMulepRerYDgvj7A0cKpNz/tyTZqbzXO4t0ZZGQJ34RH11lFHIlA8LIqreCCMUZRY3cd2bwL/5/RmjNSXqtAAAAAElFTkSuQmCC',
+ 'Ponyo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACAVBMVEUAAAAAAAA/AAC/AADMAACqAAC2AADGcQBMGQCyZgDMGRnEYgDMERHJGhrOGBjHeQvSISFPGgjNgyDQHh7MHx9QHgqBGhHLeQzQHh7OGRnSHR3WJCTTJCTQGxvQHx9jLBbKfxjPGxvPHh7QOB7TJCRrLRrTJCRZJhHbljjeqmN3OibaLS1+NyXYMDC8NzPaKyvYKyvaLS3YOincQEDorFvbKCjdNjbaKCjuypjZMjLcKyveLi6GRi/hOzvhMTHrs2ftxpHXLix/OCODOCeGSjOHRy2IPyqJQSqKSy6PTjmQQS6XSDGZMSefWUKgTzehUz2jVT2kVDqkbVSlWUGmUTema02qZUqrbkyrckCsMSmwNyywbEyyQTm0XkC1YkS1ak+1gVK2Qzu3iVq5Ni26Qjy6oHy9JiG9ZUnCb0vENCLFxcXGdVLGpIzJdVDKfFbMd1HNqILQysXScU7Sck/TwrDXRS3YSEbcS0rdLy7d0cHd3Nref1XfSknfflTfhFnf3tzgwp3hLi7hgFXhglfiLi7iRUTiTU3ihVnjMTHjSknkMDDlODjlOjrlOzvmPDzmrFzm0bbnTU3oT0/oUlLpU1PpVlbpWFjp1r7qW1vqYGDrvoHs1rnt0q7vwH/yz6HzypLz2bb306L43bn50Zr62Kv637r82Kf83LD83rb837f84b0dlQysAAAAQnRSTlMAAQQEBQYHCQoKCg0PExUXFx0fISgzOTtCRUVMTVJSXFxcXGNqa3BykJegp6mqtLS1t7/Jz9DU1trb3eTn8/X2/P3IgXZJAAAA30lEQVQoz2NggAJmSUUlPgYEYDNs6es150II6HfNmNZhIAznizlOmdzdONFWCsLlENVyTixPKZs004oFxFe3CfDLyI5zi2mb2iPHwCCoqhPYXNvU1FQd7FNjJsLAwCSfl5+bXldU3B6bJsHMwKCr5+Tu6hHtHxbqHR+pBjRAu9U3YmFCeFLOPBfPKBVeRgbZipCCqoblKxdVlgQlG1uyMrCYZqbWz148f0JWoVennTRQj4DR3AUrlixdMX1OqbUM2FncJstWAMEqC2UeqLv5Nez7ZzloCiH5lV1cgRPKBAApxz0bK1ScOQAAAABJRU5ErkJggg==',
+ 'Rabite': 'iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAD7klEQVQYGQXBW2xTZQDA8f93zmlPe7qOrVvXyzY2B6ybTLksIAImanTiDGimb/pAohISEx980TffTHwjPviiDxiNokajMSAQIwEGIwzYTWAFcZdudOt9bdfbuXz+fuLHrz9935bFnbr3yY/6Y/3O9PQkXk8T6UyeYHuY/u1RCvkyqWyBJo+XQyOvIRQFKSVut4fJG5cO5HPJlCZz42+MjvaM3l5ZayoWu0+oiuqABAAAAEAIQa1aIbV6D6/PQAiFdCrbkU3/cjGTN08rfp/fzvyVY/fTm+9WauN/bhTKfqFogAQAAEAgsC2bSmWT1rYmfD4vdXPy84NDQX9fwN2t+CND91qsIMnzizx/xBjp27p0pVjI90g0EAIABCBAKIJisYLV0Hl0f/zkth3F40rCjaH6DEUx+s5uRgO0LfeycPY+I0cCu/cNzk+a5eWxekMiFDf1ukO10sBsSBqmws3xX4+0G1dPifU6SsJNplJaF7OTE5jJ76/2lwcPJ2cSbPTcIjbSiyUMfv69fLE3Eo6HQuYeR5HNlbJVmJlOmh2e1cMHXxzUzXMmLX1Bvl2MHxdrS3GSq/cPqInTl2P1w+6V63PM1xL49qrsOjaEt70d3edDShBCYtXr5JaWuPDVHZ5zQhT36PM388PD6rN795LLOyu37q7+W639cTTQoWsD/X6697fiHxhkYibJb+cfs2egA3DQNDdnrqXpjUWZW5h2HlpPvR3eOhhXXEKnyevG0zJwZka+PjSxmV1pGi6jx2IgdC7NrvLxTxe4Mb2I5nKDojC3lOaLKw/YMbLPaQ/FUp2dIbRgWzvegA8j2Ar19LaO8q0uJTRITfFQz+c4OTbM0PYou3aGKaSKlPLwyZu7KFmwtUVqldTsCc32faA4AjKJxy814tlvlq/+8GVvp4rt8iGlpF4s0N7i5dj+CLn4fzz6J0N18wXSCYXekI7LMGjeYh1cWiihrS/GXx20/Oe6up9hqlQDKRGlDKrmwohEsUwbKTSiQ9vp1lQya5fpDBgIVUG4VFrD/sj12wt+TatUXwn6fdSLj2iYFrViCelKoQuB1aghjS0I3UCoIJEEu7xIBxzLQqNCannt8e3ZjZJmmtWas3YXuzGHzG7hYXOGAXcWt2Hgskzk5gZ2Uyu4dLBNcGxUu4HiVMklkszOej47dGAf6tjYsXRzw3onpOGOqC1MzVSZym8kvdYGml3SPR6JapZQagWURhmlkqeWzfFgPr/x953wh31Do99FoxE0f7BrZt7leXliauI9vSH1dS0Qb+s9eupCfKa1K8tb5sT8bpdab7Vte7MuXDZaOJ+tBK5LredsOPpEMdLVjWWZ/A+8EtJREuofIwAAAABJRU5ErkJggg==',
+ 'Arch': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABCFBMVEUAAAAA//8rqtVAqtUQj88tpdIYks46otwVldUbktEaldMjldM2qNcXk9IWktQZkdIYlc8mnNUXlNEZktEZlNIYktIWlNMXktE7o9klmdMXktFHqdkXk9EWk9EYk9IlmtQXlNEXktAWk9AWlNEYlNFDptkZldMYk9E4otg/p9kXktEXk9AXlNA4otclmdQXk9IYktEXlNEwn9YXk9IXk9FFp9o3otgXk9FPrdwXk9E2otdCptkXk9E/ptkcldIXk9Edl9IXk9EjmdUXk9EXk9EXk9EbldIcldIjmdMmmtQsndUvntYyn9YyoNYzoNc0odc1odc2odc6pNg7pNg9pdlDp9pJqttOrdzlYlFbAAAARXRSTlMAAQYMEBEVFhgcHR0mLS8zNTY3PT4/RU1kdXp6e3+Cg4WIiYqMjZGXl5mbnqSnrbS3zMzV3OPk7Ozv8fT29vf4+fz8/f7SyXIjAAAAlUlEQVQYV1XNQwIDAQBD0dS2bdvmNLV5/5t0UU52728CvGayQLx8UWz1eKoXhdBqmRaF6mbdVfzZXWgetomfpY3b4Hruqb7B97hf9rtT5mNZ+7ggyaHuHTxzzqIxgUy+LG+RWSBFjrQAgAhJF+Ak6ykA0PRJOgAj2QlKAOTISkADKMM1Mg4YJmXr585cEozw2vE3m/8J5h8V7jsI1XAAAAAASUVORK5CYII=',
+ 'CentOS': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB5lBMVEUAAADy8tng4Ovs9tnk5O3c7bX44LLduNO1tdDh7r/eutj43q2kocX23az07N+qqsvUqcmXl7331ZXJj7r40o/Pn8T42qP63KjNw9n21p3Y387Ml7732JzR55z05MSxtMLGn8TC4Hx8eqt8e62Af6/B4HnG4oPC4HzH44fBf7LCgbOkoMTcsrmtn8PWqcfFtKrj4Jvs2ZOz2FnMqLXT3KfY5p60Z6NUU5XRuqHzwWSywqDn3JaiiLWahrWhkry5zJjRmqm1Z6P1wmb1y319fK632mK5cKi5nH+73Gu73Gy73W283W+9eK17e6y1yZS3aqRZWJdcW5ldXJplXZppaKBwb6VwcKV5eKswL306OYNPTpGkfK+m0kGpUJWq1EnEqIuXK3+Xh7ahP4qhkryMfK6BgK+CdpGMaKKMa6O9ea2+eq6+oYW/eq+NbqWVlL2Wlr7AjanA4HnA4HrBkqbBlafB33rCgbLCmKjCxIzC1mSs1UytV5mtxIWt1lCuz2evWpuvXJywxYzHjrvH4oXIjrrN2HXO5pTO5pXUlYnUlYvVl5Hb0G7e0XTg03rhr5fpzHPpzXTp0Hvtz3/wrDHytknyt0zyuE3yuVHzvVr0wGP1x3T1yHf1yXe0ZaL2zYP30o730pD31ZeRIcF5AAAAQ3RSTlMAFBkbHEhJS0xMTk5UWWBsd4SEiIiPkJCVlZaam6CjpK29wMPDxMTFxcnK193e3+Dg4uTn5+fo6e/v8/P4+fn7/P7+J4XBAAAAANNJREFUGFdjYIAAcW4oA0rJOFnywkVk1VVNWyf1OehpaQqABTW8213jJna5lfnECoMF1NqaC2MmdM5tyfKHCJi4FpV69nc05VTXK4D40hVVtR5ehjqZDUkJNjwMDKKOBeUlxcZ8EnbJiSnB5hwM7GbRuRnpulJyFvHZ7mlKLAwMXLZhofnh9tYLF8ycrs8EMkQ7Nc830K93/jznOZJgW1RcfIMiG3tmOM+aKgIWUI4KCYio6Z42e8pkiAC/oKC8VV2lgZiQEBvcP6xGioyo3uVkhvIBH9A0EWEgTIIAAAAASUVORK5CYII=',
+ 'Debian': 'iVBORw0KGgoAAAANSUhEUgAAAA0AAAAQCAYAAADNo/U5AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAZ5JREFUOE+Nkk0oBHEYxv8fu5GQj3JwcaDkIAc5IpR87M7MKnIVJVKclaIQ5Sy5OLkgR7n5OigcSNpmd2c2Vyfl4KT8/muWiVU79TTv+7zv837NCBF6PG1X+NpZyEYSD9mIc+tHnBPe23B9xKrCuTmbQA/JKfABrhBswa1hH4A38IwfOxPdX1qcjiCQxO5NyrjKV70TnSbeRPwJvGN3i4yyqnEucPY8ZZX9GSEgGK+RvFfyjk2VKZxzBNG8wJWWgh/xtDOeUXZ7Slr6TrSLYL9N4SMgYTTcwdc2ArvJcElhSVcM6mCNSV8n9hA59yTU5UWMG6HIbLhIWlglgWiC2L4Z79qTdo40D6ISuOWwKCWHyk9Fv8ldpUHOuGTuynwSBUynddPdlbEosVpP9Eu4FnOsRzUYNTsdmZN/d5LDiqM0w+2CMdAFFsFGWgfXxZnheqe/z+0puwEM0HHYV3Z9Sgz8TEz7GkQvpuJ/36ggj2AaHLrSlkULWV5x+h2E8xkZL16YVjGNaAUscfZ/f6c/k9ywLKI2MMcRWl0RLy007idmRbQJ7RIfDAAAAABJRU5ErkJggg==',
+ 'Elementary': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAACXBIWXMAAABIAAAASABGyWs+AAAAAmJLR0QA/4ePzL8AAAFuSURBVCiRfVG/S8NQEH4VimAHcXKS+otIsNb2vpc4W0QXF8FBqKOiIEgQKTgEK/gXBKEOIoIIgmMo6KSIkxYXHRxcqhjQQpQKOojES9K0mxwc7919d/fdd8IToemKLMKGw2bLoq5E8dDFyIALixZlAWvsd/BBhog1ACKGMiqkyiVU5SGO8EQzmV66QNmHMICrK4hjHXUt49dgHM+D7ekELslggK7AJVUbxicmo7l4yY56Yqwbrq4IpmZx6FweN9MdcOVQ8CrRpoBNedGGLzkXAWgFpyF13soWcHhAP7xsMkyPdOFRpoL6DXzDYYDehwF4NBUEO+UNbQd9cvhhCANsbYK/1zA9oWm4xbKf1nrwii3K8wgmWeLKVdSxhzfK+Wk5ixoOmIPFJHnNGit3D4/tShZol1Wp0jR3VYM1A6F+YWaTNI8T3OEMZjrBPeOsrtGS+iFUsbmqyn0iqRvHepf7WJApUpmaxeq2jvX/uf8A9h7IjHC1AQkAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTMtMTAtMTVUMjI6MjM6NTQrMDg6MDCQ664gAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDEzLTEwLTE1VDIyOjIzOjU0KzA4OjAw4bYWnAAAAABJRU5ErkJggg==',
+ 'Fedora': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABPlBMVEUAAAApQXIpQXIpQXIqQ3UpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIpQXIqQ3QpQXIpQXIqRHYpQXIpQXIqQ3QqRHYpQXI8brT///8uTYMpQnM5Zqg5ZqnS1+I4ZaY4ZactSn8uRnYrQ3MrRXgsRHUsR3s8bbM8brMtSX4wUosxVI01XZw2X50vUIguToQvR3c6X5o6aKs6aq08Un8qQnM9VIFDWINJXohKcKlXapEqQ3UvUIc2X55bhcBdcJVgcpdhfapmd5tuk8dxgqJ1hKR5jbB6iah/m8Shudq3v9C4wNG/x9bFy9nFzNnFzNrIz9zK0NzK0t/O2+3P1eA2YaDU2eTb3+jb4Oje4urj6fHm6e/s7/Tz9fj3+fz7/P38/f3+/v83YaEa/NNxAAAAHnRSTlMABAoVGyY1SVlpeIuQsLfDzdHW4+3y8/b39/n6+vr4+ns8AAAAxklEQVQYGSXBhUJCQRRF0SNYgIooiPJ0zwXE7k6wu7s7//8HdGAteeFoPNne2lhfpYpIioqWWnkNeNv3X+87HXWSIni73/b2updvq1E4hffys8/ag5toUhRv0QpAn5tCcbyiXQBZN4mSQG62ZDf9Q2PdbhplyPacmPe56TZAwcyIOy4828fj7cp4DhTk3ToU7YoKdbleoGiXlKXVOToPbNkpZTEFv25uefXJDvASIWWGF+7M7GyJf4lqqZnBw+vzowEgHQtJfyetJP7BfFOIAAAAAElFTkSuQmCC',
+ 'FreeBSD': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADXklEQVQ4EQXBS2wUZQDA8f83j33M9rF9d7u4loaWklaDpkSo9KDGaIKUaGxshD2YSPRiuDVeTDyhBxosJCoa40ktpAkPDcUqAYVIpUSUPrAulEdD2bbb7e7ObGcfM/P5+4kwKDvq6yJ1FYYcvb+YAkqAHo/HQ7FYrFIoCiurq9ZXJ06YSOkA+kBzfX06bys3zHxS9EL0tXDVyZfefacqV+X/ZSJx5+qLbx98LhaL9RiGEZWlEsWC/Thd9q6Pf3vs2u6Orc83rFsvTwwfLf5obgywT1Vjh2Hh+rbNsnTssJdNLedK5aIrpSuldKVXKsnH4+Pyn6FDXn5tMef9O+3NvdkvP1V4+EYw2AoQ+KSx8dRYS6NXXnwovaItXduSrrkinWxGOmZWJi9OyOK9m1LmsjIz9IH8QUMOd3WfAQwNKCy2tJwbHB5+XasPaxIHmc4g7WWEZ1MquBiRFlJTf1E7+Tl/H/8asavPzTY1nWd2ZkMDRPeBeHPz5ojwsilEQCBvTSKunCF3M8FSNkBGVTHDYYrLj8jVNhDZ2SMa2zo3MTamaIC/u6Ojr3DtrOrvP0BpdATnyBeIhTxpR5ABUlKSUlXS1dWstbVxdz6hPL0l1quGqkLaKwNvVcjEXNRd/4mit4Z19DjefBEPyCKxgQJQcF28dBrHNDGTSZSezsjeff0hraa2Vs2vrvit81O4vj9xLJcC4ADrQA7YAGqBGsAql/EtLdFQE/L7dF1XZmdnSrbPMJfXoLDmolQK8gJyQBowgQhQDRQBD+hsraVhd4e5MH+/oExfvWLJ9q3/3S7qMpNH2hsS40kFS4EUUAMA2IANRIBXv4uzuO67c2PykqkA5YmZ6bN18YPi0Yoknxc4AsJPCMLVAk2BLKDosCWqs/PZaulkuxk9fekcUBAAQGDks5FT0W++3NuYuC0DVUL4DIEdlIQDAj0IRkigaMjArkFx0tf523sffrQHyKsAgHPhwoXLL+yP9/kePNhk5ExUTyKFkJVAUAiCFZrQup4Rv9ftuLV/6ONBYBVABQAArMvJ5MXW7duD6P62sD8UrPAFRU1TpeCpCnGvPZr7WW///v0jpw+VC9ZdAAABAAAAAMLo7drWrmQyPWG/r8tnaGIjaM05ujr16x/ZBFh5AACA/wGZnIuwraa4ZgAAAABJRU5ErkJggg==',
+ 'Gentoo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB9VBMVEUAAAD///+AgICqqv+AgIC/v9+Ojqqii9GAgKptYZKQkOmPj/ddUYBgW4eVjeCTgfiWjO5wbJaZkvPBvepkXomYkNldV4Bzbpl6dJ+Uj7ynoO6Vi+1qZI63se2mnudjXYjOy+GCfaqZjvWlm/Pc2e+Oh7NeWIOWjfeXjeW1sd+gl+diXIfp5/KHgKnn5/F2cZx6c6ZgWoXc2e6dltrAvNu0scrX1eTOyujCvup4c5qpovVpY43///+6uPPJyPXq6fvm5vrz8/z8/P7+/v/d3PixqvmxrPSyrfe0sPO0sfS3tMve2/3r6vy6ufPz8/3d3fi3tM63tPO4tsu5tsu5tvO6tfe6t/Vva5KRjKy7tvW7t/W9vPO/vM+/vvPCwfPEw/TFwvTFxOfGxfTGxvTHxvTIx/TJx/aTiOrNzPXNzfXQzfnRzuHS0fbS0vbT0uHU0e/U0uTU0/bW0+zW1ffX1vfY1/jZ2Pjb2/jc2uSTiemVkLSlnvbe3PTe3vng3fzg3f3g4Pnh4Pnh4fri4enj4/nk5Prl5Prm4/ymn/bn5vro5/rp6O/p6funoPWsqs3t7Pvt7fXv7vzv7v3w7/nx7/3y8f3y8v3z8vytqPWuqPX09P319P319P719f339v739/34+P35+f37+/+uqev9/f6vqvSwrPQAR0dcAAAAPHRSTlMAAQIDBAgJCwwVFyAsNUFHSVBneH+Bh4mVmZmanKCxsrK2tr3ExtDW19rb4ODl5u3t7u/w8/T6+/z9/f4MkNJ1AAAA7UlEQVQYGQXBA2IDABAAwU1t27aNi1Pbtm0rtW277+wMgEN05nRWjBMAgCJgVUTed+sibQEg9EZEvm7V8x05LgCOJSKi1+8XdKmUhT5AyIuIvHUOLDWoyvKb/MG3uVRExuOTzvqUf6fDrthEfc/diXwczXbX/h7kpYCle+qETrQ7Y+1VDysbaYAiTER3bhhsKXpcn/QG8zgR0e7N9Cjrr0bCLTBNEJHXk4Whtv77ymArCBL5eVKvjfZuHS97mQEZn8+XhxVThuviRGcA0ss1xk3NRXW2nzUAeNZsL7Y25gbaAwCYuMUmR3jYAQDwDzDCPrxVMnjZAAAAAElFTkSuQmCC',
+ 'Mint': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACVVBMVEUAAADh4eEAAAAAAAAAAAAAAAAAAAAsLCyXl5dgYGCnp6eTk5N3d3fBwcGqqqq8vLzNzc3Ozs7Ozs7Pz8/Pz9DQ0NHR0dLS0tLS0tPT09Pf3t/Pz8/i4eLb29vZ2drZ2tna2dra2trf3t/u7O/u7e/u7O/r6+vt7O/w7/Lw8PDy8fTz8fXz8fbx8fHz8/P19fb49/j49/n6+vuPxlmWyGOx437h9NDr9eD6/fj////+/v75/vTA5Jv6/fb7/fnL5bDL5q+AxjeDxUCEzTyGxUaGzjyHxkiHzz6J0D+Kxk6K0kCLyE2M00WNy06P00mSz1OUyF+W2FGX1FiY0F6Z02CZ21ac0Wiez2yfz2+f2mOh4GCi4GOi4WKi4mOk12+k3Wul32um1Hin0nun4G6n5Gin5Wmo23Op2Huq1n+q43Cr526s4Hit23+v6XSw34Cw34Gw6nWx4IKy4IOy44Cy63ez146z34az4IWz4YW03Y217nu38H2625e645G74pK83pu98Iq984W+4ZjA4px0tzDA5ZrB8ZDC5p7D55/E947F6KHF+JHH4qvH6qTI46/K5LLL5LN1tzLL5bN1uTDL57DM5bPM6qzM66/N5rTP6LbP6bTR6rfS573T67vT7LrV7r3X68XX7MHX773Y77/Y9rvZ8cHa7cjd88bi88/j8tTk8djk9tHm8trn89vo89zo9N3p9N3p9d7p9tvq9d/s+93s/dzy+erz+O73+vT4/PX5/fT5/fX5/vN1uzB3vTD6/ff6/fh5uTj8/fv9/vr9/vx8wjV/xDmrMRH0AAAAOXRSTlMAAAECAwQJDzk/RUlNU3F0kpSVlpeYmpucnaKjpKWqqqqtu8LExMTEzdTU1NXY4evy8vP+/v7+/v6LaR1mAAABDUlEQVQYGWPgk5QQFxMVERYSFODnYGZgYJA7vMfa2nrXbltbiyOW0mwMDApbuzsbq6sKslJiok0tFYECW9oalqwuyU2NjQoNjLfkYpC3tCxevDE5c/nShBUdfmZSDJw8Rr3zN0Ru2n/AaptlXa0G0FiDrnnrgizLsg95LVqfp8PAwGTQPnutv2VOmp3P9M352iABm5lrfC3T4+w8pkEEDJtmrPJeGBY8y9VmWSFQBYN+c892TzcXp2POlfVFIAGllQGWc2qSIsIz+kMqQALclsalOywXTJjUl+heDhJg1d1pcnBiy+S9+446tmoBBRjY9azMp9rbOzhMmWulycAIFGHhlVFWUVFRVVVXkwUAyhJUc5MwaMIAAAAASUVORK5CYII=',
+ 'OpenSUSE': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3gIKDigueojqlAAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAADEklEQVQ4y5WTTWxUZRSGn/PdO9PpdKYjbRmmrWmm/00ptlS02FqjEgpRNCxo3Eg0auJCrJqYmGA0hEiC7ghroy40Rk0wppYiIbEBjQSlFEJFWksTqv21vwydmTv3Oy5GFho2PvvzvHnf5MA/XP5jqPPMtU8fWFr6q5P/MDT+uTM1PybcBZlbmD0dL9u0c2j8Cx2YPEqkoBzR7G9V0Y61RyueW0+Eq38NRt2XAX6c+Lqos2Zv6qcb/Wyv3pMXvNgfT9fGHioImcLcjbWLbtAEyPheNmtX1bMeG4IVwZayHmku6Z6LBst7Nld2jNxJPz/Zj/QNNqnFs1bVuOKiRgCLWBcRyNoUgqvhQETAob1sz8i+pkM7bq6Mpms3bUm5CAgB46IggBVEDKIWS44d9x6gK/6MpHLLCA7vXXysJuCEFnq3vC2fXTpkXMjfIfmNREBV8cjQXvo0YSfGwQttVIab8TTDW+2D0cMXunKTc+NfJeN1+8xdlxUH3+boLn+B01PHqSraxpttA4SdUlYyMySLt+pHV19qBMgLVFEFweD56yAWEWFm/TqJwnrm02O8+3MH4ytniQbiZHO3AxinZXhy8GEDoAgGy7pdpbfuKBFTguBwYuIw+xuP0VKyk0RBLW+0DnBl8Ttu+7dYSU+xnFvYbe70tgKFJsrVxZO88+AP7K0+SNau88HwEySKGmgt28XZ6Y85N/0hjjgE3Cglwcpl6TvVpCiIKJYcaqHAjdBbe4Sme7q5tPgtv8yeYCkzjxEl6ERoiHVmHql4/lpiY2WbvDrYqAiIku+uDhYla1PEguVUFNbzeNUrJEI1qCqz6d859+cn3Exfp654a6f0napXUSdvEIO1ihGLIICDMYbl7AxqBas59TUjyeJtNMa2Dz973/v75cDJWn/NW8w6xsVXD9cUEDAhsKDGx/dz+GTElbBJRlsDDRu6ZkNOZNdTza+NALgVRZu/fzL5ejTslup8eoLp1BhTq5fxxCNkwsTD1SSj9/vVxW23NpZW9sAAX145UgTwzegxUNUg/4P+0eP/euu/AVF+N0gj+MWXAAAAAElFTkSuQmCC',
+ 'Osx': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABrVBMVEUAAAD///////+qqqr///+ZmZn///+qqqqAgID///////+tra339/eAgICoqKjx8fGMjIzm5ubh4eGPj4/g4ODIyMiAgICSkpKLi4vS1tbPz8+Xl5eMjIypqanIyMjW1tZ2dnbR0dGamprFxcV3d3d+fn60tbV3d3dcXFx3d3epqal7fHxxcXF+foCnp6hYWFhyc3Ojo6SMjI5fX196enp+fn6Li4xERERqamqgoKFpaWmFhoeen6A/Pz9QUFCWlpeSk5SUlZWUlZaOjo+Tk5RHR0cuLi5YWFgwMDAeHh40NDQ3Nzc6OjpcXF1rbG0XFxdSU1NVVVVXV1dZWVlbW1tnZ2lwcHABAQEEBAQXFxchISI+P0BISUpaW1xHR0kNDg4qKyszNDU1NTY9Pj8NDQ1cXF4XFxhSU1QSEhIDAwMrKywtLS4uLi4wMDFHSElISEggISE0NDVJSktNTU1FRUVWVlhGRkYEBAVBQUE0NTZQUVJQUVMFBQUqKitWV1lXV1daWlpaWlw+Pj8bGxtcXV9dXV1fX19fYGFgYGBkZGRlZmhpaWlsbGxwcHB2dna844Y9AAAAV3RSTlMAAQIDAwUFBggMDhkeICMkKCgqMDIzPj9ERFBib4CCg4iMjZCcnp+jqamrw83W1tvb3ePl6Ojp6+vs7u7v8PHy9PT09PT3+vr7/f39/f39/v7+/v7+/v50ou7NAAAA30lEQVR4XkXIY3vDYABG4SepMdq2bRSz/capzdm2fvOuDO397Rw0Ly4tz2QAQPbcxuZ2E/STJwfxPhWgG355fRrVAIVb1zeP9UDLfiSwkAcADe8fn7tFxWuEXFRDoer/OgoMTRBCumj8yJwPBo8Zhpk14U856/HI8n0ZUtpZ1udrSzfVneA4roNKjdrwpcMRilb8d8G60+lKnrpWcn9bO+B23w2O8Tzfq4aiNSZJqzn5O4Kw16h06fPZ+VUlUHfo97+VAEb7rSh2UgDd4/U+TBlQY7FMj5gBIGvcarVVfQPVPTG94D0j9QAAAABJRU5ErkJggg==',
+ 'Rhel': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABj1BMVEUAAAD///////8AAAD///////8AAAD///8AAAD///////8AAAD///8AAAD+/v4AAAAAAAAAAAArKysAAAD///////8AAAAAAAAAAAAAAAD///8AAAAAAAAAAAD///8AAAD///8AAAAAAAAAAAAAAAB5eXn+/v5JSUnKysrS0tJ5eXmqqqqxsrL+/v4ZCgknJyeHh4eIiIjo6OgZCAdOTk7t7e3///8GCwwPAAArKyv19fX29vb9/f0EAAD////+/v4AAAAGBgYHAAAJAAAMAAANAQAPAQAVAQFyCQV9fX2pIRzmEQjn5+cBAAAFAAAAAADnEQjvEgn////uEQjyEgnsEQjzEgnxEgljBwPaEAj9EwnwEglHBQJHBQNNBQIBAAB3CQR5CQSHCgWLCgWRCgWTCwadDAWmDAapDAa/DgfKDwjWEAgGAADh4eHiEQjmEQjmEQkKAADoEQgLAQDtEQgMAQDuEQnvEQjvEQkPAQAfAgEuAwEvAwE8BAL1Egn3Egn4Egn6Egk+BAL+/v5CBQJrB0muAAAAT3RSTlMAAAMEBAkYGhsbMTRLUmpvcHeIjLe6vcHCxM3P0NbW3Ojp6u/w9ff5+fn6+vr6+/v7+/v8/Pz9/f39/f39/f7+/v7+/v7+/v7+/v7+/v7+Q8UoNAAAAO5JREFUeF4tiwVPA0EYRL9SXIsWl+LuxfcOd2Z3764quLu788NZNrxkksmbDP2R7vH6GioLs+iffEzNXd4+TqPErUUpVqMOvwgdzMPn1rv5vPsVeufBTaBK/bH2FPvkEUuIG5jIIc+sHYn/HJ3dC/Hxuo4y8s44dzwBbFkisHN8bVIdXs6jb+H97aCwbHEIqgcml64CD7YllNkAVQC940MLYe5YzvIeQAXNrd19Roc5MdzfdQLUUKaUYyuG9I8y1g4gj6hIak4X5cBIT2MquZJrJdOqpY11ZpAiqVwbY/C7KY1cRCrZxX4pWXVuiuq/hs49kg4OyP4AAAAASUVORK5CYII=',
+ 'Sabayon': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABvFBMVEUAAAAcUaYdVKwAAAAAAAUABAwWRY4YSZYhZtIhaNYHDx0KCgoFDBcKCgoRMmYSNm0fXL0fXb8AAAAYS5gaTp8fXLwgXsEGBgYFBQUZSpgZTZ4JFSgODg4IEiIOJkwOKVIkW7EnXbQLGzUTExMKGC8LHjwMIkITExMiIiIPEBEPJ00QEhMXOXAaPncOJEgoXbApXbEcHBwwMDAEAgAfHRgQDgo3NC8AAAAHBwcKCgoLCwsJCQkaGhofHx8lJSUwMDA0NDQ4ODiRkZEICQocHBweHh4GBgYHCg8mJiYnJycpKSkrKystLS0uLi4ICAgODg43NzcRERF1dXUUFBSjo6O1tbUbGxsEBAMLGS8MDA0iIiIjIyMkJCQNDQ0NHTYKCQkoKCgPDw8QEBArMDkKCgkRERIREhMxMTEyMjISIz00Njk1NTU2NjYCAgIVFRU5OTo5P0c8PD0+Pj4/QURAQEBHR0dKSkpMTExSUlJiYmJlZWVnZ2cWFhZ2dnZ4eHh8fHx9fX2FhYUXFxeVlZWXl5eYmJiZmZmcnJwZGRmlpaWrq6usrKyvr68KFiq/v7/FxcXY2Nji4uLn5+ft7e0yif9uAAAAN3RSTlMAAAApKSkqKioqg4OEhISEhoa1tra3t7y9vr7S09PT09TU+Pj5+fn5+/v7+/v7+/v7/v7+/v7+70RY/wAAAPlJREFUGBktwQNbQ2EYANC3lt3NtazltvDh+s52tm1z2f7Dfe3pHPiTllfT1V2bnw5xCVDUPruyub271VEMicCUTfQ6XEtritq/XA5MwVvw7NFydOB0e+WhQoCUzh5MxmcWPRZxxNHXmgo5doyxDd3ESPhaCNtzocrsY9BXFPHU7zdXQ+McTwhZ//lAhPC+ySZoIBuUUv77HVGbNTJYB5X4SnZh8hlBQuhYHq6ArPnphxdtP/p88vQqBBcyIKnFaD29vdO0+0tlwNiWDMCJ0ujOeejicEySRA6YUqfJs7qnur2mqRKI4wxKQFUDioGDf7psfXO9PlMHzC/HlDtslvM8zQAAAABJRU5ErkJggg==',
+ 'Slackware': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AcEDi0qZWWDgAAAAx1JREFUOMt9kktoXHUchb/ffc1M7rySSdJMOknFPMRitLgoNKKI8ZHGKkgrjU8SitidimSh2UkXoQmoO1dGQSxJjdvOtqSaqlR0USEGSjVJGxuSmWR6M3fu4/93YX0g4rc9HA6cc4Q7DI+fpzz7PA8++2mxvZAeBZ4xhHtFcJRmXWsWvb36/OLcyxf5B/KHeYHy7DmGx1+YSDjmWTdlobTGMAStQGkNoLXS4tXDq7u7tUcWz49tA8jR8QUuzB5n5NTCV13F9JEo1JJwTLKuzU61QiOMcd0UDb+BncwQK3Rl15eNja3ui/Njq8aF2eMcO/XlBz0H8oO2ZUkum6A13WB99TtyzXlaCi24SaFa+ZFCzsG2DNnfkdbFjsI1APPhk+d6ujqznycdCxFozadYWvyMpx47wa+bPkGksKwUNnsk3TaCGASRXDZh5LpHXPPg4Rcni+3uYBxrtBbQghlscOVKmYHeEm0ZIZ9xyLffw41ND6VAa43SmjiMByzHYtjzwr9arfshxf5jOKlvKZfn8es77N2uks24PPfSFD/9Uvt7AtPKWmEU9d645eHYJo5tcKi/FX/zG+zmQxQH+rANk862DOW5N/hhaY64cJSa5xNFCgDDILZACMKYWAmh73HmzFsMlBQJ06LeiMinE1S3KzRCm5rXIIoUIoKIYCVM36urZFbEoiBLNMIhAE6/NsSB7h6SKZdL8xsUOnpx9j1KbTdARACIowArYe1ergfNT2i0mIbJys0GI6PT3N1/hJvrPxOFdRJNBQIy/FapI4Bpgohgcjuw+jq8jy8tV55MNBWI4ohS802CpizKv8q+FgALZAfYgSyAZtNro1oLaU1VvxCA029Oraxs7u/tKnXiNjn8HyKwur6lI++6vPK4V7IA7u+1Dyu1tr183ddNbkHuXP8/zEIYeFqiLRl6YO/p0bHJdflT/PD9qZa1W+ry99fcvlAlcZwUpuUAglIRYVgnDEIOlna4q0M/NPnuO1/PzMwg/045O/XeibUt5/Xangx6viSVFpK2jtMpvdyWCz+5ryf10clX3/amp6eZmJjgd441URWWJY8BAAAAAElFTkSuQmCC',
+ 'Trisquel': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABjFBMVEX///8AAAAAAAAAAAAAADMAAGYAAAAAHFUAGWYAF10AImYAIGAAHloAHGMAKGsAGmYAJmYAJGEAKnUAJ1gAMXYAJnEAJGQAI2EAK28AK3cAGTEAMHgALXEALXgALG0AFUAAI2oAK3EAMngANoYALXMANIAAM4IANIIAL3gANIcANokANoQANYQAOY0ANIYANooAN4kAN40AOY0APZMANIUAOY0AO5AAPZUAPJAAP5MAPpQAQJUAOYsAPpYANoUAPpoAPpUAM4AAQJkAPZIAPJEAQpgAN4cAPpQAPZUAPJEAO4oAOosAOo8AQJoAOYsAO44AQpsAO48AQp0AP5UAQpoARJwAQ58ARaAAQZgAQ54AQ50AQpgARaIARqMARaMARaIAR6QARaIARaEASakARKEAR6MASqsARKEASKcAR6MARqYAR6UATbEATa8ARqUARKAAR6oARqMASKgATK8AR6QATbIATbAASq0AR6cASKgASqwAR6UASKcATa8ASqoASqwAS6wASKoAS60ATbHn4CTpAAAAhHRSTlMAAQIFBQUGCQoLDxAREhMUFBUYGhobHB0eHh8gIiIjJCQkJCYoLC0xMTE0NDo6Oz1BQUNHSUxOVFVVVldaWl5iY2RkZWZoamtsb3FycnR1ent9f4KDhIiJioyNkJGYm5+foqOkpqamqKmqrKytsLKzs7e4uLy8v8TFxcXGx8rO0NXY2eZc4XYcAAAAzUlEQVQYV2NggAMWdX12BiQglJ+SXqIMYqmHxQdJMzAEmXLKuCcyMTBYNWYmNTVYMARzMToqlAsycFYYSBppFFVp6nqa2VkVcDCIFXK7GfrrlWWISKjqpAUwMPDkibIz+Inn5iSHxxQn8AHN9Ig1d7DRzimtrasO5QJZwqhmrMoQ2Rwix8WIcANrTaqAT6AWQoC33t5Flj1CCS7AUenqrMJk7YRQEpXFb6LoawvjMjIJZ8dZ+maKMcHMZWST8or2lmdD2MPILKYlxgziAwCs9yR3GXo0vAAAAABJRU5ErkJggg==',
+ 'Ubuntu': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAABKVBMVEX////ojFzplGf1zbnqnHLvs5P10b3yuZv1xKrytZXvtJXys5LysI32waT0n3HxiVHwg0jxhk31kFn0h0zxf0P0hUrveTv2iU3yfkD1hEfyejv5eDLybSX0aR7zZxvyayH6ZxnxZBj4YhH7XAb5WALlUQLeTwHgUAHeTgHfTwD65NzdTQDdTQHdTgD31MfcTgLcTADcTQD////xt5/31Mf54dfmfE/dUAbeVQ/jcUDcTgHeWBnnflHohFvpjGbqkGztnX342Mz53dLgXiP65d399PHdUgrtoYLyu6Xzvaf76eLfXB/rkm/fWhvupojwrpTeVhTgYSfgYynzwa30xbL1ybnngFT31snngljhZS3539XhZzDiajbibDn77OX88Ovrl3X99vTjbz1fisGCAAAAMHRSTlMABgYGBwcHJiorMDA1NXGHjY2Nl5mZmZyfn6O5u8XHzc3X193j9fj4+vr6/f39/f08OUojAAAAxklEQVQYGS3BBULDQABFwY8WLdbiHjzI201Sd8Hd3e5/CJKWGUVio0u77vJYTP/iG7RsxhXpmDe0BDsHc12SpgzkyscnhVojZ8algT34KD5YGxTq4PYpabh+es3fXJSbXy8wIgeO7Dehkr2HFZnLn1SQIXToXcGWtivN7GmayO8brGsNKjZFKGs9WNWsIVP182fp58ZnHSY0ZKBYurO29ngLbr80Y4Bzz3v3fUhI6l2krbrPQqdCPdOGtmS32oYTjjHO5KBCf5XaKpkxFPzRAAAAAElFTkSuQmCC',
+ 'Windows': 'iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAA+pJREFUOE+F0n84FHYcB3CWSsL9ojo/6ik64c6PnTjmSS0limmrpBm2G002y++xzXRz6zE0R4nbw+RnTj/WD4sbanLkkAe55ccYlyNme4SrO9u9d13PI3/saZ+/vs/3831ez+f9eb5aWsuqy2mjRYeNUa7YmtjfTico7jNJ8z0eG24NB9vvnDrvufzpq89Npnr8VjMddNmuRh9rDfp36mFg91oM7qPIc5JdbDJq3An/JfCu7Hl53W2lpS220pP2OuniN299jAYbYizSENIoAgbCTdrTKtxOJVdvGo8psUwKy7Vxe4ez1YEVudGP8YEZzyveInFJ6mZRHHqYazDspw/pJwTIuERM5JIwmUdGdyo9K7/BszGzzg6fXzZHGJ8KvzQqXKOpoIeZLjofWR++BPWyCEnPY4xFGEKWQcLjMjKmr1MwfcMYwmz/Y4KOgNki0V5k1dkjUWCK93Kp2PMFFawos8cm1gZ2GqjLXktL4mbQPHLQ4B9ZDFE5+S356fQlyuJMqzH++HnTo6ui2OO1ko9Ul+4fxfd3d4F7k4YTReqpuFS88bGZUE2QNNDobuIq8Q5CduHb7lFJaTnvnym9ergjMWD/FG8zf+aKS3G9JO5C01Asah6wUXrvALKEDoitMMHhDKrKJdg8RU2s0EB2EWWur8dd7PDPFv6dUC0Gv3kAN36VPRGP/5k5NS6lljWxG0TDiSr1VKhoPwhevRMSqkwRxDObc/DavGtpP6zoi8XOyZfhnyNEvKANBU0P8VPfI/wyNCGXSn7wlEmyA9KrgmOKGth3eDVvPfyywq2dnUEv2R9qG2rLsH7xJXziKnWcI8tlTvEC7Mu8hROlImTU9aKqcwQ1vWOihWFu+sJknmph5CvxQh87c7bNh/NXo03hrMCosyvLmMNgMF7TQL6J1dsZIUVwjKqEO+cajp5vxPN439U/gKBt8PTcYHzL/BgHCyOf4unAISj6mFC2bYC82kB5Ls460NHRUVsDeYSXpGw7UgC7sAtwShDgzdM38W7BbURXtqpqhfmB8sEQuXwoCM/6faGQuGCxyxyKWhIm+PrSD495WL3cT0hhi8Whc3NbAs9KaOyCTvrJ8qkdX19XBeTUDU00+55USFzVU2yHstcaix0mUAjJkJeuRU868Ucmk0lcguiBnMAVxjbbdHV1yeq8+u4Hgo22huSG+iQXp83ftaxW3lsPZcs6KG5T8OwaAfJiPcxlrVRVRhvF02i0F/t5VbHZ7JWDfErKTLnhE3mFPuRFepg/uxqz6TqLv6euGj3ut87t/4ylvre3t3ZehOWWO1zjSFEqMVP4GfGb/DBykJcjmaZOoLsc+hcVY/LaAgcTQAAAAABJRU5ErkJggg==',
+ 'OpenBSD': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAykIPu64pQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAADTklEQVQ4y32RXUxTdxjGn3N6eujoKT3SUkuk3VoBGfVjgFXAsZ7WkipyYXQbuu3CzUXZmGRbssnFEseFkWzgcGzGXky9MWL8TsC4IeFgtK4oAqOnG5vMVl1pCMVWQD7b/y5M6jLdflfvxfPked/nBQA0NDSChqnGVrLuGkES742NhJAdhAKAuk9yyUs5Gry7RQMZAARCWgivpQiPe71P5DUfH0xaqTL7m/iiLkJmphawa+e4SM2PvUyC4yUIBu8CnAQKAK53rCA5OUtQtStVpJ4Gw/FOBddZVKhCfq4MP4n6+at+DUsJm/e0G9JZzYEvI2tHwlEYjDxomkZ+3nG8WroRtHihZVOhVlorDQzh0okhcByDP4ZGcf+X9XAsvY5/RsBa7Kq5H/CqLctKyl/g08S2i6fq8W/MS3P34T9wNDVYSeDX1eTD9xhiLXbtB/Akwmmv6Kr+ICFkLpGhtNSM3qsSstS3oX8lSsmsxS6ZVn3j6PvVVqhUcvC8AtPxVPxwygVKvngN89WOjgVprggGA4eenjB4nsXsTASpC63I0wVTZYPR11FoKRB8Ax54PCFk6BhMTk5CPR3GSbHouGzknr/bYFq9EAvfc9Tu1sLjHcXNKxLuTOTgzOlOe7IHBc/beAXWpWmXlz8a84nhcLQ+ecVzsAEQrMWuMX+f9HZF2YPZ28FVSNfoPWqOzMUmqYMAJm7+/OOzXQFwHGpyEV+vi+yvtxBC9pDmpgJC4tvI3mo9GTitIxvW24nT7ug67HY/3eDs2bbyrVsrY2day70rV6kRfDAHk5lDLJqAmmeRiD9GJDKHvwb74R8G0mkTPjrQTTG122xkTTbwaV2b1H4u16JQKXGr7yG2b8/H1MQ09IsTSEmRwzf4CCwzD+dmE1re8CI7wwi5XNlFf9vaTXX4dWJg4LLl7h05fpNGwNAMWpp9CIVYNO/tRCzGwpDFQaVMQTS2CKY0BWr3GVGWNSXKACDDaA4Mh976pq9f5Sy09GgKlmeAMIBKzUKpU+BFoxJecRhUfAbMxDi4eADfHVmE79v7q575gvvYeVvjZ58LD5mwsKUyX0hnf0feslnQCWD4zxnc6reKisxsfH2oscqcmTmK/+Ow252cna7K52r+Bky6PqmoT5HBAAAAAElFTkSuQmCC',
+ 'Gnu': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAHC/Qd8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AoYAywUV5gQrwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAAmJLR0QA/4ePzL8AAAHHSURBVBgZZcFPSJNxAAbgt28uanSRapCsy0KK2CWCUYecB5HBolNsglZEsmAwaUvHaIu2YYty1bKGMKmgHIRbGEhURIEY/VHUQ+uwZcxEJSL5Ft+W5ubv7TMkip4HJglrPhHeUmAchWprBK+Kni9pukoAJAOF04j4y6Z9dZtu3sIT32lxXwxeRepwidP0mAF0p5JKPfBsLOMBQs/dJ3pehzcnQ+jc6SfFKlN8KMgEodLiQJWTFOyPY52mUbLmzANY4zro+xG8DVXn8UjOvg2WFSB69Oxo8Hx3F3CM2KsE2wO8LKbp5gWvtYK78zHKooM/eZFu9t0AUOCYIIf4IRfvOrIBKn12vEJyjtDhtx3QfV+dYPgO/qipOfeAgA0qn+UaW+TE9ZQjE0g63uhrpZh2yJyOPXKFe9uWrmTxtmpaSOwCgk5bWUfQywyt3MOOHmB4f9MyBu610ii3fRvlvBgRMrOc4mPmxQs2yPpylABObQ9FJxVyhAqXuEiyyOFiQcnT6TipBWDf6k9fGjwUWZgjF8V7PmVOlPmxkNmNvxhR136muELOclZ85QR73fiHBgZshM1e+UzBdzOmRvxPgmqLlKgl8mjGul/jG/ctzIC/LwAAAABJRU5ErkJggg==',
+ 'CrunchBang': 'iVBORw0KGgoAAAANSUhEUgAAABYAAAAQCAQAAAC45EetAAAA8ElEQVR4XnWOsUpCYQBGz1TIHYu2Qix6g0DEtSeQu/UIISJtUS8gJq61F1wcdMohcBDxKUR8hsz1xA/y44/cs3znbB+RJ0Skl3pSkeFQbUs79VAPzrwPFRmN1Ja0Ug/16I93+1oi4lKte+zMXv32WuoAm43lXMrqzbFncgWw21lORf4+/PREKpAhYqZuPXZ+T/3yXbZEajV1JavUQ104sRcq0myqc5mnHurWqc/7yhExVwuPncl+C4Bu13L60ueAwcByOtLhgAIRCzU38fRGTmSxUBvSSD3Ui1NvQkXWa7Uq1dRD9R17HiqyRUSy1NP6B7e1Yu2GtlUKAAAAAElFTkSuQmCC',
+ 'Yuno': 'iVBORw0KGgoAAAANSUhEUgAAABgAAAAPCAYAAAD+pA/bAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAABDtJREFUOE+FlHtMm1UYxrtsi8aEgCb+oTFmZur+WNS5RaPERU10C2qGaBgb6hgwLwMmHTIKlIKlQIHSQrmU24BSSmnpBVooUmihtEC5yKWDjVu5uOkcEca4lG5E93j6EQmELX7Jky/fOed9fu973vMdGu0xT3Cgz57yXMZLDdXcy821PFWLKmuA6HqLMqtLX5POl4iYb2ukWW8IOOFe/qfe3/M4n0eOjwyZD8//bldODOk37N1yDJgl+LVdjEGLFKO9KkzZm8hbje7mIrTXZ7sMtTydrJh15H8hHW11XvN/jGS7VudcD5w34ZZzeQYb67fwYO03LN4exo1+LWzNxbA05O5QuzbHqRYn+++CHDx4YK9WLfaedfQzV5em54g5Zbi8OIml+VFMDLWQ7GXoaSmFWZsDZVGCO2u0EbkhHTrhFqi9PmelSsQ8tAtSVch60dpUeGe4kxgZxegzVkBzlQ2NKBG2+iJIMqMok9r8OLRIMqApToSqmAWTmk9B2+o2YW79oshU7ABcuvAFrVGWXkVKpBYoSaBSxIS2mINpiwbjZiUMZRloVfJQyaXDKObBpimBScpHFe8KmmXpaKhK3arGrBVuVBclHN2CiPNin1OVs1tVJYlQlyZBxA6DviQVo6ZaOKd7sTplw53BVugruBBzfsRslw7rZPxaczWutSpQV/gzJPxo1JexyfaxKBBpuiEx+tw+CpKdEvGWTprGlhcwqbIzL5/DYKMYndpK3L1hxf3ZfkrzwybUZjPhnOqmvlcmutFF1jis9QSShOrcWNSXJ1MA0ou/NZWc8Ddfe4VGO3bk0JON1dyMMlK+gmxNrZCFhZF2Kng7YNO0awt4b7wLNp2EqtAsF6ImP56SG0B6siovTYpIjg15gapCVhAfJRUyIBFEo6k8AyuTtkcC/qvG/XbDexulWJvqgYH0o0nKhVHFJ40XwFQnWM5OCX+XMg86c3KvVMSMapCmPpSTIygTxGKZZOcOXhrr3Mp4uzkFuG6B3ajE3TELDDU8qEmsmvRATxquKkxAnSTFjwKEfv3JU9JC5unG6rQ1bTkbQ4Yq/DVgxOqwBWt2K9Yne3ZCZvrgHO2k5paHzOhSiVCZSkdNTgzy40JRlPgDhDHBCxUZdCs91G8fLeK87zOl6XSOICZYXMGNhDqX9fDP/mbK2DXVi/szm03eLpejl5pzOfqwOt4JBT8OeYwQt/4R/BR0OzXiLCM5LOCji/4nXt46rpywgG+zor5RxgSdupBzJdglSY+5ZZbl3XNY6mbn7W0Lcx06zBg1WBjtcC6OmG+OmRTrFrnIUZESZeVeCpwh8TpiPsQ47/tloM97T+/6m8mg55mT3tStyL54mhlwwtszNvjzD8/6HH8i7PvvPPRioZdRWuDBZUR6pEWG7I8P9Xs1Jsj36MfvvO5J/+rTw58dP7afJPfBgeef3XGz/gskFVpJc4HwGwAAAABJRU5ErkJggg=='
+ }
+ };
+
+ ExpandComment = {
+ init: function() {
+ if (g.VIEW !== 'index' || !Conf['Comment Expansion']) {
+ 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("//api.4chan.org" + a.pathname + ".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, postObj, posts, quote, spoilerRange, status, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
+ status = req.status;
+ if (status !== 200 && status !== 304) {
+ a.textContent = "Error " + req.statusText + " (" + status + ")";
+ return;
+ }
+ posts = JSON.parse(req.response).posts;
+ if (spoilerRange = posts[0].custom_spoiler) {
+ Build.spoilerRange[g.BOARD] = spoilerRange;
+ }
+ for (_i = 0, _len = posts.length; _i < _len; _i++) {
+ postObj = posts[_i];
+ if (postObj.no === post.ID) {
+ break;
+ }
+ }
+ if (postObj.no !== post.ID) {
+ a.textContent = "Post No." + post + " not found.";
+ return;
+ }
+ comment = post.nodes.comment;
+ clone = comment.cloneNode(false);
+ clone.innerHTML = postObj.com;
+ _ref = $$('.quotelink', clone);
+ for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
+ quote = _ref[_j];
+ href = quote.getAttribute('href');
+ if (href[0] === '/') {
+ continue;
+ }
+ quote.href = "/" + post.board + "/res/" + href;
+ }
+ post.nodes.shortComment = comment;
+ $.replace(comment, clone);
+ post.nodes.comment = post.nodes.longComment = clone;
+ post.parseComment();
+ post.parseQuotes();
+ _ref1 = ExpandComment.callbacks;
+ for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
+ callback = _ref1[_k];
+ callback.call(post);
+ }
+ }
+ };
+
+ ExpandThread = {
+ init: function() {
+ if (g.VIEW !== 'index' || !Conf['Thread Expansion']) {
+ return;
+ }
+ this.statuses = {};
+ return $.on(d, 'IndexRefresh', this.onIndexRefresh);
+ },
+ setButton: function(thread) {
+ var a;
+ if (!(a = $.x('following-sibling::a[contains(@class,"summary")][1]', thread.OP.nodes.root))) {
+ return;
+ }
+ a.textContent = ExpandThread.text.apply(ExpandThread, ['+'].concat(__slice.call(a.textContent.match(/\d+/g))));
+ return $.on(a, 'click', ExpandThread.cbToggle);
+ },
+ onIndexRefresh: function() {
+ var status, thread, threadID, _ref, _ref1, _ref2;
+ _ref = ExpandThread.statuses;
+ for (threadID in _ref) {
+ status = _ref[threadID];
+ if ((_ref1 = status.req) != null) {
+ _ref1.abort();
+ }
+ delete ExpandThread.statuses[threadID];
+ }
+ _ref2 = g.BOARD.threads;
+ for (threadID in _ref2) {
+ thread = _ref2[threadID];
+ 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, threadRoot);
+ }
+ },
+ expand: function(thread, a, threadRoot) {
+ 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 + "/res/" + thread + ".json", function() {
+ delete status.req;
+ return ExpandThread.parse(this, thread, a);
+ });
+ },
+ contract: function(thread, a, threadRoot) {
+ var filesCount, inlined, num, postsCount, replies, reply, status, _i, _len;
+ 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['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 (_i = 0, _len = replies.length; _i < _len; _i++) {
+ reply = replies[_i];
+ if (Conf['Quote Inlining']) {
+ while (inlined = $('.inlined', reply)) {
+ inlined.click();
+ }
+ }
+ postsCount++;
+ if ('file' in Get.postFromRoot(reply)) {
+ filesCount++;
+ }
+ $.rm(reply);
+ }
+ return a.textContent = ExpandThread.text('+', postsCount, filesCount);
+ },
+ parse: function(req, thread, a) {
+ var data, filesCount, post, postData, posts, postsCount, postsRoot, root, _i, _len, _ref;
+ if ((_ref = req.status) !== 200 && _ref !== 304) {
+ a.textContent = "Error " + req.statusText + " (" + req.status + ")";
+ return;
+ }
+ data = JSON.parse(req.response).posts;
+ Build.spoilerRange[thread.board] = data.shift().custom_spoiler;
+ posts = [];
+ postsRoot = [];
+ filesCount = 0;
+ for (_i = 0, _len = data.length; _i < _len; _i++) {
+ postData = data[_i];
+ if (post = thread.posts[postData.no]) {
+ 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);
+ postsCount = postsRoot.length;
+ a.textContent = ExpandThread.text('-', postsCount, filesCount);
+ return Fourchan.parseThread(thread.ID, 1, postsCount);
+ }
+ };
+
+ FileInfo = {
+ init: function() {
+ if (g.VIEW === 'catalog' || !Conf['File Info Formatting']) {
+ return;
+ }
+ this.funk = this.createFunc(Conf['fileInfo']);
+ return Post.callbacks.push({
+ name: 'File Info Formatting',
+ cb: this.node
+ });
+ },
+ node: function() {
+ if (!this.file || this.isClone) {
+ return;
+ }
+ return this.file.text.innerHTML = "" + (FileInfo.funk(FileInfo, this)) + " ";
+ },
+ createFunc: function(format) {
+ var code;
+ code = format.replace(/%(.)/g, function(s, c) {
+ if (c in FileInfo.formatters) {
+ return "' + FileInfo.formatters." + c + ".call(post) + '";
+ } else {
+ return s;
+ }
+ });
+ return Function('FileInfo', 'post', "return '" + code + "'");
+ },
+ convertUnit: function(size, unit) {
+ var i;
+ if (unit === 'B') {
+ return "" + (size.toFixed()) + " Bytes";
+ }
+ i = 1 + ['KB', 'MB'].indexOf(unit);
+ while (i--) {
+ size /= 1024;
+ }
+ size = unit === 'MB' ? Math.round(size * 100) / 100 : size.toFixed();
+ return "" + size + " " + unit;
+ },
+ escape: function(name) {
+ return name.replace(/<|>/g, function(c) {
+ return c === '<' && '<' || '>';
+ });
+ },
+ formatters: {
+ t: function() {
+ return this.file.URL.match(/\d+\..+$/)[0];
+ },
+ T: function() {
+ return "" + (FileInfo.formatters.t.call(this)) + " ";
+ },
+ l: function() {
+ return "" + (FileInfo.formatters.n.call(this)) + " ";
+ },
+ L: function() {
+ return "" + (FileInfo.formatters.N.call(this)) + " ";
+ },
+ n: function() {
+ var fullname, shortname;
+ fullname = this.file.name;
+ shortname = Build.shortFilename(this.file.name, this.isReply);
+ if (fullname === shortname) {
+ return FileInfo.escape(fullname);
+ } else {
+ return "" + (FileInfo.escape(shortname)) + " " + (FileInfo.escape(fullname)) + " ";
+ }
+ },
+ N: function() {
+ return FileInfo.escape(this.file.name);
+ },
+ p: function() {
+ if (this.file.isSpoiler) {
+ return 'Spoiler, ';
+ } else {
+ return '';
+ }
+ },
+ s: function() {
+ return this.file.size;
+ },
+ B: function() {
+ return FileInfo.convertUnit(this.file.sizeInBytes, 'B');
+ },
+ K: function() {
+ return FileInfo.convertUnit(this.file.sizeInBytes, 'KB');
+ },
+ M: function() {
+ return FileInfo.convertUnit(this.file.sizeInBytes, 'MB');
+ },
+ r: function() {
+ if (this.file.isImage) {
+ return this.file.dimensions;
+ } else {
+ return 'PDF';
+ }
+ }
+ }
+ };
+
+ Fourchan = {
+ init: function() {
+ var board;
+ if (g.VIEW === 'catalog') {
+ return;
+ }
+ board = g.BOARD.ID;
+ if (board === 'g') {
+ $.globalEval("window.addEventListener('prettyprint', function(e) {\n window.dispatchEvent(new CustomEvent('prettyprint:cb', {\n detail: prettyPrintOne(e.detail)\n }));\n}, false);");
+ Post.callbacks.push({
+ name: 'Parse /g/ code',
+ cb: this.code
+ });
+ }
+ if (board === 'sci') {
+ $.globalEval("window.addEventListener('jsmath', function(e) {\n if (jsMath.loaded) {\n // process one post\n jsMath.ProcessBeforeShowing(e.detail);\n } else {\n // load jsMath and process whole document\n jsMath.Autoload.Script.Push('ProcessBeforeShowing', [null]);\n jsMath.Autoload.LoadJsMath();\n }\n}, false);");
+ return Post.callbacks.push({
+ name: 'Parse /sci/ math',
+ cb: this.math
+ });
+ }
+ },
+ code: function() {
+ var apply, pre, _i, _len, _ref;
+ if (this.isClone) {
+ return;
+ }
+ apply = function(e) {
+ return pre.innerHTML = e.detail;
+ };
+ $.on(window, 'prettyprint:cb', apply);
+ _ref = $$('.prettyprint:not(.prettyprinted)', this.nodes.comment);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ pre = _ref[_i];
+ $.event('prettyprint', pre.innerHTML, window);
+ }
+ $.off(window, 'prettyprint:cb', apply);
+ },
+ math: function() {
+ if (this.isClone || !$('.math', this.nodes.comment)) {
+ return;
+ }
+ return $.event('jsmath', this.nodes.post, window);
+ },
+ parseThread: function(threadID, offset, limit) {
+ return $.event('4chanParsingDone', {
+ threadId: threadID,
+ offset: offset,
+ limit: limit
+ });
+ }
+ };
+
+ IDColor = {
+ init: function() {
+ if (g.VIEW === 'catalog' || !Conf['Color User IDs']) {
+ return;
+ }
+ this.ids = {};
+ 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)) {
+ return;
+ }
+ span = $('.hand', this.nodes.uniqueID);
+ if (!(span && span.nodeName === 'SPAN')) {
+ return;
+ }
+ rgb = IDColor.compute(uid);
+ style = span.style;
+ style.color = rgb[3];
+ style.backgroundColor = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")";
+ $.addClass(span, 'painted');
+ return span.title = 'Highlight posts by this ID';
+ },
+ compute: function(uid) {
+ var hash, rgb;
+ if (IDColor.ids[uid]) {
+ return IDColor.ids[uid];
+ }
+ hash = IDColor.hash(uid);
+ rgb = [(hash >> 24) & 0xFF, (hash >> 16) & 0xFF, (hash >> 8) & 0xFF];
+ rgb[3] = (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;
+ }
+ };
+
+ InfiniScroll = {
+ init: function() {
+ if (!(Conf['Infinite Scrolling'] && g.VIEW === 'index' && g.BOARD !== 'f')) {
+ return;
+ }
+ this.threads = g.threads;
+ return $.on(d, '4chanXInitFinished', this.ready);
+ },
+ ready: function() {
+ $.off(d, '4chanXInitFinished', InfiniScroll.ready);
+ $.on(d, 'scroll', InfiniScroll.scroll);
+ return InfiniScroll.scroll();
+ },
+ scroll: $.debounce(100, function() {
+ var url;
+ if (InfiniScroll.isFetching || ((d.body.scrollTop || doc.scrollTop) <= doc.scrollHeight - (300 + window.innerHeight))) {
+ return;
+ }
+ if (InfiniScroll.isDead) {
+ return InfiniScroll.notice();
+ }
+ if (InfiniScroll.cache && InfiniScroll.cache.time > Date.now() - $.MINUTE) {
+ return InfiniScroll.parse(InfiniScroll.cache);
+ }
+ new Notice('info', "Fetching next page.", 2);
+ InfiniScroll.isFetching = true;
+ url = "//api.4chan.org/" + g.BOARD + "/catalog.json";
+ return $.ajax(url, {
+ onloadend: InfiniScroll.cb.load
+ }, {
+ whenModified: true
+ });
+ }),
+ parse: function(response) {
+ var botPostForm, el, nodes, omitted_images, omitted_posts, op, post, postlink, posts, replylink, thread, threadID, threadNodes, threads, _i, _j, _len, _len1, _ref;
+ threads = InfiniScroll.parsePages(response);
+ threadNodes = [];
+ nodes = [];
+ if (!threads.length) {
+ InfiniScroll.notice();
+ return InfiniScroll.isDead = true;
+ }
+ for (_i = 0, _len = threads.length; _i < _len; _i++) {
+ thread = threads[_i];
+ posts = [];
+ omitted_posts = thread.omitted_posts, omitted_images = thread.omitted_images;
+ threadID = thread.no;
+ el = $.el('div', {
+ className: 'thread',
+ id: "t" + threadID
+ });
+ op = Build.postFromObject(thread, g.BOARD);
+ posts.push(op);
+ replylink = $.el('a', {
+ href: "res/" + threadID,
+ className: 'replylink',
+ textContent: 'Reply'
+ });
+ postlink = $.el('div', {
+ className: "postLink mobile",
+ innerHTML: "View Thread "
+ });
+ if (omitted_posts) {
+ posts.push($.el('span', {
+ className: 'summary desktop',
+ innerHTML: "" + omitted_posts + " posts " + (omitted_images ? "and " + omitted_images + " image replies" : void 0) + " omitted. Click here to view."
+ }));
+ $.prepend(postlink, $.el('span', {
+ className: 'info',
+ innerHTML: "" + omitted_posts + " posts omitted " + (omitted_images ? "(" + omitted_images + " have images) " : "")
+ }));
+ }
+ $.add($('.postInfo', op), [$.tn('\u00A0\u00A0\u00A0['), replylink, $.tn(']\u00A0')]);
+ $.add(op, postlink);
+ if (thread.last_replies) {
+ _ref = thread.last_replies;
+ for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
+ post = _ref[_j];
+ posts.push(Build.postFromObject(post, g.BOARD));
+ }
+ }
+ $.add(el, posts);
+ threadNodes.push(el);
+ nodes.push(el);
+ nodes.push($.el('hr'));
+ }
+ InfiniScroll.features(threadNodes);
+ if (botPostForm = $('.board > .mobile.center')) {
+ return $.before(botPostForm, nodes);
+ }
+ },
+ parsePages: function(response) {
+ var newThreads, number, page, pages, thread, threads, _i, _len;
+ pages = JSON.parse(response);
+ newThreads = [];
+ for (number in pages) {
+ page = pages[number];
+ if (!(pages.hasOwnProperty(number))) {
+ continue;
+ }
+ threads = page.threads;
+ for (_i = 0, _len = threads.length; _i < _len; _i++) {
+ thread = threads[_i];
+ if (g.threads["" + g.BOARD + "." + thread.no]) {
+ continue;
+ }
+ newThreads.push(thread);
+ if (newThreads.length === 15) {
+ return newThreads;
+ }
+ }
+ }
+ return newThreads;
+ },
+ features: function(threadNodes) {
+ var err, errors, post, posts, thread, threadRoot, threads, _i, _j, _len, _len1, _ref;
+ posts = [];
+ threads = [];
+ for (_i = 0, _len = threadNodes.length; _i < _len; _i++) {
+ threadRoot = threadNodes[_i];
+ thread = new Thread(+threadRoot.id.slice(1), g.BOARD);
+ threads.push(thread);
+ _ref = $$('.thread > .postContainer', threadRoot);
+ for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
+ post = _ref[_j];
+ try {
+ posts.push(new Post(post, 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);
+ }
+ Main.callbackNodes(Thread, threads);
+ return Main.callbackNodes(Post, posts);
+ },
+ notice: (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);
+ };
+ })(),
+ cb: {
+ load: function() {
+ InfiniScroll.isFetching = false;
+ if (this.status !== 200) {
+ return;
+ }
+ InfiniScroll.cache = new String(this.response);
+ InfiniScroll.cache.time = Date.now();
+ return InfiniScroll.parse(this.response);
+ }
+ }
+ };
+
+ Keybinds = {
+ init: function() {
+ var hotkey, init;
+ if (g.VIEW === 'catalog' || !Conf['Keybinds']) {
+ return;
+ }
+ for (hotkey in Conf.hotkeys) {
+ $.sync(hotkey, Keybinds.sync);
+ }
+ init = function() {
+ var node, _i, _len, _ref;
+ $.off(d, '4chanXInitFinished', init);
+ $.on(d, 'keydown', Keybinds.keydown);
+ _ref = $$('[accesskey]');
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ node = _ref[_i];
+ node.removeAttribute('accesskey');
+ }
+ };
+ return $.on(d, '4chanXInitFinished', init);
+ },
+ sync: function(key, hotkey) {
+ return Conf[hotkey] = key;
+ },
+ keydown: function(e) {
+ var key, notification, notifications, op, target, thread, threadRoot, _i, _len, _ref;
+ 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)) {
+ return;
+ }
+ }
+ threadRoot = Nav.getThread();
+ if (op = $('.op', threadRoot)) {
+ thread = Get.postFromNode(op).thread;
+ }
+ switch (key) {
+ case Conf['Toggle board list']:
+ if (Conf['Custom Board Navigation']) {
+ Header.toggleBoardList();
+ }
+ break;
+ case Conf['Toggle header']:
+ Header.toggleBarVisibility();
+ break;
+ case Conf['Open empty QR']:
+ Keybinds.qr(threadRoot);
+ break;
+ case Conf['Open QR']:
+ Keybinds.qr(threadRoot, true);
+ break;
+ case Conf['Open settings']:
+ Settings.open();
+ break;
+ case Conf['Close']:
+ if (Settings.dialog) {
+ Settings.close();
+ } else if ((notifications = $$('.notification')).length) {
+ for (_i = 0, _len = notifications.length; _i < _len; _i++) {
+ notification = notifications[_i];
+ $('.close', notification).click();
+ }
+ } else if (QR.nodes) {
+ if (Conf['Persistent QR']) {
+ QR.hide();
+ } else {
+ QR.close();
+ }
+ }
+ 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['Toggle sage']:
+ if (QR.nodes) {
+ Keybinds.sage();
+ }
+ break;
+ case Conf['Submit QR']:
+ if (QR.nodes && !QR.status()) {
+ QR.submit();
+ }
+ break;
+ case Conf['Update']:
+ switch (g.VIEW) {
+ case 'thread':
+ ThreadUpdater.update();
+ break;
+ case 'index':
+ Index.update();
+ }
+ break;
+ case Conf['Watch']:
+ ThreadWatcher.toggle(thread);
+ break;
+ case Conf['Expand image']:
+ Keybinds.img(threadRoot);
+ break;
+ case Conf['Expand images']:
+ Keybinds.img(threadRoot, true);
+ break;
+ case Conf['Open Gallery']:
+ Gallery.cb.toggle();
+ break;
+ case Conf['fappeTyme']:
+ FappeTyme.cb.toggle.call({
+ name: 'fappe'
+ });
+ break;
+ case Conf['werkTyme']:
+ FappeTyme.cb.toggle.call({
+ name: 'werk'
+ });
+ break;
+ case Conf['Front page']:
+ if (g.VIEW === 'index') {
+ Index.userPageNav(0);
+ } else {
+ window.location = "/" + g.BOARD + "/";
+ }
+ break;
+ case Conf['Open front page']:
+ $.open("/" + g.BOARD + "/");
+ break;
+ case Conf['Next page']:
+ if (!(g.VIEW === 'index' && Conf['Index Mode'] !== 'all pages')) {
+ return;
+ }
+ $('.next button', Index.pagelist).click();
+ break;
+ case Conf['Previous page']:
+ if (!(g.VIEW === 'index' && Conf['Index Mode'] !== 'all pages')) {
+ return;
+ }
+ $('.prev button', Index.pagelist).click();
+ break;
+ case Conf['Search form']:
+ Index.searchInput.focus();
+ break;
+ case Conf['Open catalog']:
+ if (Conf['External Catalog']) {
+ window.location = CatalogLinks.external(g.BOARD.ID);
+ } else {
+ window.location = "/" + g.BOARD + "/catalog";
+ }
+ break;
+ case Conf['Next thread']:
+ if (g.VIEW !== 'index') {
+ return;
+ }
+ Nav.scroll(+1);
+ break;
+ case Conf['Previous thread']:
+ if (g.VIEW !== 'index') {
+ return;
+ }
+ Nav.scroll(-1);
+ break;
+ case Conf['Expand thread']:
+ ExpandThread.toggle(thread);
+ break;
+ case Conf['Open thread']:
+ Keybinds.open(thread);
+ break;
+ case Conf['Open thread tab']:
+ Keybinds.open(thread, true);
+ break;
+ case Conf['Next reply']:
+ Keybinds.hl(+1, threadRoot);
+ break;
+ case Conf['Previous reply']:
+ Keybinds.hl(-1, threadRoot);
+ break;
+ case Conf['Deselect reply']:
+ Keybinds.hl(0, threadRoot);
+ break;
+ case Conf['Hide']:
+ if (ThreadHiding.db) {
+ ThreadHiding.toggle(thread);
+ }
+ break;
+ case Conf['Previous Post Quoting You']:
+ QuoteYou.cb.seek('preceding');
+ break;
+ case Conf['Next Post Quoting You']:
+ 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 37:
+ return 'Left';
+ case 38:
+ return 'Up';
+ case 39:
+ return 'Right';
+ case 40:
+ return 'Down';
+ default:
+ if ((48 <= kc && kc <= 57) || (65 <= kc && kc <= 90)) {
+ return String.fromCharCode(kc).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, quote) {
+ if (!(Conf['Quick Reply'] && QR.postingIsEnabled)) {
+ return;
+ }
+ QR.open();
+ if (quote) {
+ QR.quote.call($('input', $('.post.highlight', thread) || thread));
+ }
+ QR.nodes.com.focus();
+ if (Conf['QR Shortcut']) {
+ return $.rmClass($('.qr-shortcut'), 'disabled');
+ }
+ },
+ tags: function(tag, ta) {
+ var range, selEnd, selStart, value;
+ 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 + "/res/" + thread;
+ if (tab) {
+ return $.open(url);
+ } else {
+ return location.href = url;
+ }
+ },
+ hl: function(delta, thread) {
+ var axis, height, next, postEl, replies, reply, root, _i, _len;
+ 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 (_i = 0, _len = replies.length; _i < _len; _i++) {
+ reply = replies[_i];
+ 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 thread, threadRoot, _i, _len, _ref;
+ _ref = $$('.thread');
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ threadRoot = _ref[_i];
+ thread = Get.threadFromRoot(threadRoot);
+ if (thread.isHidden && !thread.stub) {
+ continue;
+ }
+ if (Header.getTopOf(threadRoot) >= -threadRoot.getBoundingClientRect().height) {
+ return threadRoot;
+ }
+ }
+ return $('.board');
+ },
+ scroll: function(delta) {
+ var axis, next, thread, top;
+ 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;
+ }
+ }
+ return Header.scrollTo(thread);
+ }
+ };
+
+ RelativeDates = {
+ INTERVAL: $.MINUTE / 2,
+ init: function() {
+ switch (g.VIEW) {
+ case 'index':
+ this.flush();
+ $.on(d, 'visibilitychange', this.flush);
+ if (!Conf['Relative Post Dates']) {
+ return;
+ }
+ break;
+ case 'thread':
+ if (!Conf['Relative Post Dates']) {
+ return;
+ }
+ this.flush();
+ if (g.VIEW === 'thread') {
+ $.on(d, 'visibilitychange ThreadUpdate', this.flush);
+ }
+ break;
+ default:
+ return;
+ }
+ return Post.callbacks.push({
+ name: 'Relative Post Dates',
+ cb: this.node
+ });
+ },
+ node: function() {
+ var dateEl;
+ if (this.isClone) {
+ return;
+ }
+ dateEl = this.nodes.date;
+ 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) % 12) > 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, now, _i, _len, _ref;
+ if (d.hidden) {
+ return;
+ }
+ now = new Date();
+ _ref = RelativeDates.stale;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ data = _ref[_i];
+ RelativeDates.update(data, now);
+ }
+ RelativeDates.stale = [];
+ clearTimeout(RelativeDates.timeout);
+ return RelativeDates.timeout = setTimeout(RelativeDates.flush, RelativeDates.INTERVAL);
+ },
+ update: function(data, now) {
+ var date, diff, isPost, relative, singlePost, _i, _len, _ref;
+ 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 (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ singlePost = _ref[_i];
+ singlePost.nodes.date.firstChild.textContent = relative;
+ }
+ } else {
+ data.firstChild.textContent = relative;
+ }
+ return RelativeDates.setOwnTimeout(diff, data);
+ },
+ setOwnTimeout: function(diff, data) {
+ var delay;
+ delay = diff < $.MINUTE ? $.SECOND - (diff + $.SECOND / 2) % $.SECOND : diff < $.HOUR ? $.MINUTE - (diff + $.MINUTE / 2) % $.MINUTE : diff < $.DAY ? $.HOUR - (diff + $.HOUR / 2) % $.HOUR : $.DAY - (diff + $.DAY / 2) % $.DAY;
+ return setTimeout(RelativeDates.markStale, delay, data);
+ },
+ markStale: function(data) {
+ if (__indexOf.call(RelativeDates.stale, data) >= 0) {
+ return;
+ }
+ if (data instanceof Post && !g.posts[data.fullID]) {
+ return;
+ }
+ return RelativeDates.stale.push(data);
+ }
+ };
+
+ RemoveSpoilers = {
+ init: function() {
+ if (Conf['Reveal Spoilers'] && !Conf['Remove Spoilers']) {
+ $.addClass(doc, 'reveal-spoilers');
+ }
+ if (!Conf['Remove Spoilers']) {
+ return;
+ }
+ if (Conf['Reveal Spoilers']) {
+ this.wrapper = function(text) {
+ return "[spoiler]" + text + "[/spoiler]";
+ };
+ }
+ return Post.callbacks.push({
+ name: 'Reveal Spoilers',
+ cb: this.node
+ });
+ },
+ wrapper: function(text) {
+ return text;
+ },
+ node: function(post) {
+ var spoiler, spoilers, _i, _len;
+ spoilers = $$('s', this.nodes.comment);
+ for (_i = 0, _len = spoilers.length; _i < _len; _i++) {
+ spoiler = spoilers[_i];
+ $.replace(spoiler, $.tn(RemoveSpoilers.wrapper(spoiler.textContent)));
+ }
+ }
+ };
+
+ Report = {
+ init: function() {
+ if (!/report/.test(location.search)) {
+ return;
+ }
+ return $.asap((function() {
+ return $.id('recaptcha_response_field');
+ }), Report.ready);
+ },
+ ready: function() {
+ var field;
+ field = $.id('recaptcha_response_field');
+ $.on(field, 'keydown', function(e) {
+ if (e.keyCode === 8 && !field.value) {
+ return $.globalEval('Recaptcha.reload("t")');
+ }
+ });
+ return $.on($('form'), 'submit', function(e) {
+ var response;
+ e.preventDefault();
+ response = field.value.trim();
+ if (!/\s/.test(response)) {
+ field.value = "" + response + " " + response;
+ }
+ return this.submit();
+ });
+ }
+ };
+
+ Time = {
+ init: function() {
+ if (g.VIEW === 'catalog' || !Conf['Time Formatting']) {
+ return;
+ }
+ this.funk = this.createFunc(Conf['time']);
+ return Post.callbacks.push({
+ name: 'Time Formatting',
+ cb: this.node
+ });
+ },
+ node: function() {
+ if (this.isClone) {
+ return;
+ }
+ return this.nodes.date.textContent = Time.funk(Time, this.info.date);
+ },
+ createFunc: function(format) {
+ var code;
+ code = format.replace(/%([A-Za-z])/g, function(s, c) {
+ if (c in Time.formatters) {
+ return "' + Time.formatters." + c + ".call(date) + '";
+ } else {
+ return s;
+ }
+ });
+ return Function('Time', 'date', "return '" + code + "'");
+ },
+ 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();
+ }
+ }
+ };
+
+ Settings = {
+ init: function() {
+ var link, settings;
+ link = $.el('a', {
+ className: 'settings-link fa fa-wrench',
+ textContent: 'Settings',
+ href: 'javascript:;'
+ });
+ $.on(link, 'click', Settings.open);
+ Header.addShortcut(link);
+ $.get('previousversion', null, function(item) {
+ var changelog, el, previous;
+ if (previous = item['previousversion']) {
+ if (previous === g.VERSION) {
+ return;
+ }
+ changelog = 'https://github.com/Spittie/4chan-x/blob/master/CHANGELOG.md';
+ el = $.el('span', {
+ innerHTML: "4chan X has been updated to version " + g.VERSION + " ."
+ });
+ if (Conf['Show Updated Notifications']) {
+ new Notice('info', el, 30);
+ }
+ } else {
+ $.on(d, '4chanXInitFinished', Settings.open);
+ }
+ return $.set('previousversion', g.VERSION);
+ });
+ Settings.addSection('Main', Settings.main);
+ Settings.addSection('Filter', Settings.filter);
+ Settings.addSection('Sauce', Settings.sauce);
+ Settings.addSection('Advanced', Settings.advanced);
+ Settings.addSection('Keybinds', Settings.keybinds);
+ $.on(d, 'AddSettingsSection', Settings.addSection);
+ $.on(d, 'OpenSettings', function(e) {
+ return Settings.open(e.detail);
+ });
+ settings = JSON.parse(localStorage.getItem('4chan-settings')) || {};
+ if (settings.disableAll) {
+ return;
+ }
+ settings.disableAll = true;
+ return localStorage.setItem('4chan-settings', JSON.stringify(settings));
+ },
+ open: function(openSection) {
+ var dialog, html, link, links, overlay, section, sectionToOpen, _i, _len, _ref;
+ $.off(d, '4chanXInitFinished', Settings.open);
+ if (Settings.dialog) {
+ return;
+ }
+ $.event('CloseMenu');
+ html = "
";
+ Settings.overlay = overlay = $.el('div', {
+ id: 'overlay'
+ });
+ Settings.dialog = dialog = $.el('div', {
+ id: 'fourchanx-settings',
+ className: 'dialog',
+ innerHTML: html
+ });
+ $.on($('.export', Settings.dialog), 'click', Settings["export"]);
+ $.on($('.import', Settings.dialog), 'click', Settings["import"]);
+ $.on($('input', Settings.dialog), 'change', Settings.onImport);
+ links = [];
+ _ref = Settings.sections;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ section = _ref[_i];
+ 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);
+ (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() {
+ if (!Settings.dialog) {
+ return;
+ }
+ $.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);
+ },
+ main: function(section) {
+ var arr, button, description, div, fs, hiddenNum, input, inputs, items, key, obj, _ref;
+ items = {};
+ inputs = {};
+ _ref = Config.main;
+ for (key in _ref) {
+ obj = _ref[key];
+ fs = $.el('fieldset', {
+ innerHTML: "" + key + " "
+ });
+ for (key in obj) {
+ arr = obj[key];
+ description = arr[1];
+ div = $.el('div', {
+ innerHTML: " " + key + ": " + description + " "
+ });
+ input = $('input', div);
+ $.on(input, 'change', $.cb.checked);
+ items[key] = Conf[key];
+ inputs[key] = input;
+ $.add(fs, div);
+ }
+ $.add(section, fs);
+ }
+ $.get(items, function(items) {
+ var val;
+ for (key in items) {
+ val = items[key];
+ inputs[key].checked = val;
+ }
+ });
+ div = $.el('div', {
+ innerHTML: ": Clear manually-hidden threads and posts on all boards. Reload the page to apply."
+ });
+ button = $('button', div);
+ hiddenNum = 0;
+ $.get('hiddenThreads', {
+ boards: {}
+ }, function(item) {
+ var ID, board, thread, _ref1;
+ _ref1 = item.hiddenThreads.boards;
+ for (ID in _ref1) {
+ board = _ref1[ID];
+ for (ID in board) {
+ thread = board[ID];
+ hiddenNum++;
+ }
+ }
+ return button.textContent = "Hidden: " + hiddenNum;
+ });
+ $.get('hiddenPosts', {
+ boards: {}
+ }, function(item) {
+ var ID, board, post, thread, _ref1;
+ _ref1 = item.hiddenPosts.boards;
+ for (ID in _ref1) {
+ board = _ref1[ID];
+ for (ID in board) {
+ thread = board[ID];
+ for (ID in thread) {
+ post = thread[ID];
+ hiddenNum++;
+ }
+ }
+ }
+ return button.textContent = "Hidden: " + hiddenNum;
+ });
+ $.on(button, 'click', function() {
+ this.textContent = 'Hidden: 0';
+ return $.get('hiddenThreads', {
+ boards: {}
+ }, function(item) {
+ var boardID;
+ for (boardID in item.hiddenThreads.boards) {
+ localStorage.removeItem("4chan-hide-t-" + boardID);
+ }
+ return $["delete"](['hiddenThreads', 'hiddenPosts']);
+ });
+ });
+ return $.after($('input[name="Stubs"]', section).parentNode.parentNode, div);
+ },
+ "export": function(now, data) {
+ var a, db, p, _i, _len, _ref;
+ if (typeof now !== 'number') {
+ now = Date.now();
+ data = {
+ version: g.VERSION,
+ date: now
+ };
+ _ref = DataBoard.keys;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ db = _ref[_i];
+ Conf[db] = {
+ boards: {}
+ };
+ }
+ $.get(Conf, function(Conf) {
+ delete Conf['archives'];
+ data.Conf = Conf;
+ return Settings["export"](now, data);
+ });
+ return;
+ }
+ a = $.el('a', {
+ className: 'warning',
+ textContent: 'Save me!',
+ download: "4chan X v" + g.VERSION + "-" + now + ".json",
+ href: "data:application/json;base64," + (btoa(unescape(encodeURIComponent(JSON.stringify(data, null, 2))))),
+ target: '_blank'
+ });
+ p = $('.imp-exp-result', Settings.dialog);
+ $.rmAll(p);
+ return $.add(p, a);
+ },
+ "import": function() {
+ return this.nextElementSibling.click();
+ },
+ onImport: function() {
+ var file, output, reader;
+ if (!(file = this.files[0])) {
+ return;
+ }
+ 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 data, err;
+ try {
+ data = JSON.parse(e.target.result);
+ Settings.loadSettings(data);
+ 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);
+ },
+ loadSettings: function(data) {
+ var key, val, version, _ref;
+ version = data.version.split('.');
+ if (version[0] === '2') {
+ data = Settings.convertSettings(data, {
+ 'Disable 4chan\'s extension': '',
+ 'Catalog Links': '',
+ 'Reply Navigation': '',
+ 'Show Stubs': 'Stubs',
+ 'Image Auto-Gif': 'Auto-GIF',
+ 'Expand From Current': '',
+ 'Unread Tab Icon': 'Unread Favicon',
+ 'Post in Title': 'Thread Excerpt',
+ 'Auto Hide QR': '',
+ 'Open Reply in New Tab': '',
+ 'Remember QR size': '',
+ 'Quote Inline': 'Quote Inlining',
+ 'Quote Preview': 'Quote Previewing',
+ 'Indicate OP quote': 'Mark OP Quotes',
+ 'Indicate Cross-thread Quotes': 'Mark Cross-thread Quotes',
+ 'Reply Hiding': 'Reply Hiding Buttons',
+ 'Thread Hiding': 'Thread Hiding Buttons',
+ 'uniqueid': 'uniqueID',
+ 'mod': 'capcode',
+ 'country': 'flag',
+ 'md5': 'MD5',
+ 'openEmptyQR': 'Open empty QR',
+ 'openQR': 'Open QR',
+ 'openOptions': 'Open settings',
+ 'close': 'Close',
+ 'spoiler': 'Spoiler tags',
+ '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());
+ });
+ }
+ }
+ data.Conf['WatchedThreads'] = data.WatchedThreads;
+ }
+ if (data.Conf['WatchedThreads']) {
+ data.Conf['watchedThreads'] = {
+ boards: ThreadWatcher.convert(data.Conf['WatchedThreads'])
+ };
+ delete data.Conf['WatchedThreads'];
+ }
+ return $.set(data.Conf);
+ },
+ 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;
+ },
+ filter: function(section) {
+ var select;
+ section.innerHTML = "Guide Name Unique ID Tripcode Capcode E-mail Subject Comment Flag Filename Image dimensions Filesize Image MD5
";
+ 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;
+ }
+ return div.innerHTML = "Filter is disabled.
Use regular expressions , one per line. Lines starting with a # will be ignored. For example, /weeaboo/i will filter posts containing the string `weeaboo`, case-insensitive. MD5 filtering uses exact string matching, not regular expressions.
You can use these settings with each regular expression, separate them with semicolons:Per boards, separate them with commas. It is global if not specified. For example: boards:a,jp;. Filter OPs only along with their threads (`only`), replies only (`no`), or both (`yes`, this is default). For example: op:only;, op:no; or op:yes;. Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`). For example: stub:yes; or stub:no;. Highlight instead of hiding. You can specify a class name to use with a userstyle. For example: highlight; or highlight:wallpaper;. Highlighted OPs will have their threads put on top of the board index by default. For example: top:yes; or top:no;. ";
+ },
+ sauce: function(section) {
+ var ta;
+ section.innerHTML = "Sauce is disabled.
Lines starting with a # will be ignored.
You can specify a display text by appending ;text:[text] to the URL.
These parameters will be replaced by their corresponding values:%TURL: Thumbnail URL.%URL: Full image URL.%MD5: MD5 hash.%board: Current board. ";
+ ta = $('textarea', section);
+ $.get('sauces', Conf['sauces'], function(item) {
+ return ta.value = item['sauces'];
+ });
+ return $.on(ta, 'change', $.cb.value);
+ },
+ advanced: function(section) {
+ var archive, boardID, boardOptions, boardSelect, boards, data, event, input, inputs, item, items, name, row, rows, ta, table, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _ref4;
+ section.innerHTML = "Archiver 404 Redirect is disabled.
Thread redirection Post fetching File redirection
Disabled selections indicate that only one archive is available for that board and redirection type. Custom Board Navigation
New lines will be converted into spaces. In the following examples for /g/, g can be changed to a different board ID (a, b, etc...), the current board (current), or the Twitter link (@).
Board link: g
Title link: g-title
Board link (Replace with title when on that board): g-replace
Full text link: g-full
Custom text link: g-text:\"Install Gentoo\"
Index-only link: g-index
Catalog-only link: g-catalog
External link: external-text:\"Google\",\"http://www.google.com\"
Combinations are possible: g-index-text:\"Technology Index\"
Full board list toggle: toggle-all
[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:\"Piracy\"] will give you[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy] if you are on /g/.
Time Formatting is disabled. :
Day: %a, %A, %d, %e
Month: %m, %b, %B
Year: %y, %Y
Hour: %k, %H, %l, %I, %p, %P
Minute: %M
Second: %S
Quote Backlinks formatting is disabled. :
File Info Formatting is disabled. :
Link: %l (truncated), %L (untruncated), %T (Unix timestamp)
Original file name: %n (truncated), %N (untruncated), %t (Unix timestamp)
Spoiler indicator: %p
Size: %B (Bytes), %K (KB), %M (MB), %s (4chan default)
Resolution: %r (Displays 'PDF' for PDF files)
Quick Reply Personas is disabled. One item per line. Items will be added in the relevant input's auto-completion list. Password items will always be used, since there is no password input. Lines starting with a # will be ignored.
You can use these settings with each item, separate them with semicolons:Possible items are: name, email, subject and password. Wrap values of items with quotes, like this: email:\"sage\". Force values as defaults with the always keyword, for example: email:\"sage\";always. Select specific boards for an item, separated with commas, for example: email:\"sage\";boards:jp;always. Unread Favicon is disabled. ferongr xat- Mayhem Original Metro Emoji is disabled. Sage Icon: 4chan SS appchan
Position: Before After
Thread Updater is disabled. Interval:
Custom CSSApply CSS ";
+ items = {};
+ inputs = {};
+ _ref = ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'sageEmoji', 'emojiPos', 'usercss'];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ name = _ref[_i];
+ input = $("[name=" + name + "]", section);
+ items[name] = Conf[name];
+ inputs[name] = input;
+ event = name === 'favicon' || name === 'usercss' || name === 'sageEmoji' || name === 'emojiPos' ? 'change' : 'input';
+ $.on(input, event, $.cb.value);
+ }
+ 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];
+ if (key === 'emojiPos') {
+ continue;
+ }
+ input = inputs[key];
+ input.value = val;
+ if (key === 'usercss') {
+ continue;
+ }
+ $.on(input, event, Settings[key]);
+ Settings[key].call(input);
+ }
+ });
+ $.on($('input[name=Interval]', section), 'change', ThreadUpdater.cb.interval);
+ $.on($('input[name="Custom CSS"]', section), 'change', Settings.togglecss);
+ $.on($.id('apply-css'), 'click', Settings.usercss);
+ boards = {};
+ _ref1 = Redirect.archives;
+ for (name in _ref1) {
+ archive = _ref1[name];
+ _ref2 = archive.boards;
+ for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
+ boardID = _ref2[_j];
+ data = boards[boardID] || (boards[boardID] = {
+ thread: [],
+ post: [],
+ file: []
+ });
+ data.thread.push(name);
+ if (archive.software === 'foolfuuka') {
+ data.post.push(name);
+ }
+ if (__indexOf.call(archive.files, boardID) >= 0) {
+ data.file.push(name);
+ }
+ }
+ }
+ rows = [];
+ boardOptions = [];
+ _ref3 = Object.keys(boards).sort();
+ for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) {
+ boardID = _ref3[_k];
+ 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
+ }));
+ data = boards[boardID];
+ _ref4 = ['thread', 'post', 'file'];
+ for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) {
+ item = _ref4[_l];
+ $.add(row, Settings.addArchiveCell(boardID, data, item));
+ }
+ rows.push(row);
+ }
+ $.add($('tbody', section), rows);
+ boardSelect = $('#archive-board-select', section);
+ $.add(boardSelect, boardOptions);
+ table = $.id('archive-table');
+ $.on(boardSelect, 'change', function() {
+ $('tbody > :not([hidden])', table).hidden = true;
+ return $("tbody > ." + this.value, table).hidden = false;
+ });
+ $.get('selectedArchives', Conf['selectedArchives'], function(_arg) {
+ var option, selectedArchives, type;
+ selectedArchives = _arg.selectedArchives;
+ for (boardID in selectedArchives) {
+ data = selectedArchives[boardID];
+ for (type in data) {
+ name = data[type];
+ if (option = $("select[data-boardid='" + boardID + "'][data-type='" + type + "'] > option[value='" + name + "']", section)) {
+ option.selected = true;
+ }
+ }
+ }
+ });
+ },
+ 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', {
+ textContent: archive,
+ value: archive
+ }));
+ }
+ td.innerHTML = ' ';
+ select = td.firstElementChild;
+ if (!(select.disabled = length === 1)) {
+ select.setAttribute('data-boardid', boardID);
+ select.setAttribute('data-type', type);
+ $.on(select, 'change', Settings.saveSelectedArchive);
+ }
+ $.add(select, options);
+ return td;
+ },
+ saveSelectedArchive: function() {
+ var _this = this;
+ return $.get('selectedArchives', Conf['selectedArchives'], function(_arg) {
+ var selectedArchives, _name;
+ selectedArchives = _arg.selectedArchives;
+ (selectedArchives[_name = _this.dataset.boardid] || (selectedArchives[_name] = {}))[_this.dataset.type] = _this.value;
+ return $.set('selectedArchives', selectedArchives);
+ });
+ },
+ boardnav: function() {
+ return Header.generateBoardList(this.value);
+ },
+ time: function() {
+ var funk;
+ funk = Time.createFunc(this.value);
+ return this.nextElementSibling.textContent = funk(Time, new Date());
+ },
+ backlink: function() {
+ return this.nextElementSibling.textContent = this.value.replace(/%id/, '123456789');
+ },
+ fileInfo: function() {
+ var data, funk;
+ data = {
+ isReply: true,
+ file: {
+ URL: '//i.4cdn.org/g/src/1334437723720.jpg',
+ name: 'd9bb2efc98dd0df141a94399ff5880b7.jpg',
+ size: '276 KB',
+ sizeInBytes: 276 * 1024,
+ dimensions: '1280x720',
+ isImage: true,
+ isSpoiler: true
+ }
+ };
+ funk = FileInfo.createFunc(this.value);
+ return this.nextElementSibling.innerHTML = funk(FileInfo, data);
+ },
+ favicon: function() {
+ Favicon["switch"]();
+ if (g.VIEW === 'thread' && Conf['Unread Favicon']) {
+ Unread.update();
+ }
+ return this.nextElementSibling.innerHTML = " \n \n \n ";
+ },
+ sageEmoji: function() {
+ return this.nextElementSibling.innerHTML = " ";
+ },
+ togglecss: function() {
+ if ($('textarea[name=usercss]', $.x('ancestor::fieldset[1]', this)).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, tbody, tr, _ref;
+ section.innerHTML = "Keybinds are disabled.
Allowed keys: a-z , 0-9 , Ctrl , Shift , Alt , Meta , Enter , Esc , Up , Down , Right , Left .
Press Backspace to disable a keybind.
";
+ tbody = $('tbody', section);
+ items = {};
+ inputs = {};
+ _ref = Config.hotkeys;
+ for (key in _ref) {
+ arr = _ref[key];
+ tr = $.el('tr', {
+ innerHTML: "" + arr[1] + " "
+ });
+ input = $('input', tr);
+ input.name = key;
+ input.spellcheck = false;
+ items[key] = Conf[key];
+ inputs[key] = input;
+ $.on(input, 'keydown', Settings.keybind);
+ $.add(tbody, tr);
+ }
+ return $.get(items, function(items) {
+ var val;
+ for (key in items) {
+ val = items[key];
+ inputs[key].value = val;
+ }
+ });
+ },
+ keybind: function(e) {
+ var key;
+ if (e.keyCode === 9) {
+ return;
+ }
+ e.preventDefault();
+ e.stopPropagation();
+ if ((key = Keybinds.keyCode(e)) == null) {
+ return;
+ }
+ this.value = key;
+ return $.cb.value.call(this);
+ }
+ };
+
+ Main = {
+ init: function() {
+ var db, flatten, pathname, _i, _len, _ref, _ref1;
+ pathname = location.pathname.split('/');
+ g.BOARD = new Board(pathname[1]);
+ if ((_ref = g.BOARD.ID) === 'z' || _ref === 'fk') {
+ return;
+ }
+ g.VIEW = (function() {
+ switch (pathname[2]) {
+ case 'res':
+ return 'thread';
+ case 'catalog':
+ return 'catalog';
+ default:
+ return 'index';
+ }
+ })();
+ if (g.VIEW === 'thread') {
+ g.THREADID = +pathname[3];
+ }
+ 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);
+ _ref1 = DataBoard.keys;
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ db = _ref1[_i];
+ Conf[db] = {
+ boards: {}
+ };
+ }
+ Conf['selectedArchives'] = {};
+ Conf['CachedTitles'] = [];
+ $.get(Conf, function(items) {
+ $.extend(Conf, items);
+ return Main.initFeatures();
+ });
+ return $.on(d, '4chanMainInit', Main.initStyle);
+ },
+ initFeatures: function() {
+ var init;
+ switch (location.hostname) {
+ case 'a.4cdn.org':
+ return;
+ case 'sys.4chan.org':
+ Report.init();
+ return;
+ case 'i.4cdn.org':
+ $.ready(function() {
+ var URL, pathname, _ref;
+ if (Conf['404 Redirect'] && ((_ref = d.title) === '4chan - Temporarily Offline' || _ref === '4chan - 404 Not Found')) {
+ Redirect.init();
+ pathname = location.pathname.split('/');
+ URL = Redirect.to('file', {
+ boardID: g.BOARD.ID,
+ filename: pathname[pathname.length - 1]
+ });
+ if (URL) {
+ return location.replace(URL);
+ }
+ }
+ });
+ return;
+ }
+ init = function(features) {
+ var err, module, name;
+ for (name in features) {
+ module = features[name];
+ try {
+ module.init();
+ } catch (_error) {
+ err = _error;
+ Main.handleErrors({
+ message: "\"" + name + "\" initialization crashed.",
+ error: err
+ });
+ }
+ }
+ };
+ init({
+ 'Polyfill': Polyfill,
+ 'Redirect': Redirect,
+ 'Header': Header,
+ 'Catalog Links': CatalogLinks,
+ 'Settings': Settings,
+ 'Index Generator': Index,
+ 'Announcement Hiding': PSAHiding,
+ 'Fourchan thingies': Fourchan,
+ 'Emoji': Emoji,
+ 'Color User IDs': IDColor,
+ 'Custom CSS': CustomCSS,
+ '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,
+ 'Menu': Menu,
+ 'Report Link': ReportLink,
+ 'Thread Hiding (Menu)': ThreadHiding.menu,
+ 'Reply Hiding (Menu)': PostHiding.menu,
+ 'Delete Link': DeleteLink,
+ 'Filter (Menu)': Filter.menu,
+ 'Download Link': DownloadLink,
+ 'Archive Link': ArchiveLink,
+ 'Quote Inlining': QuoteInline,
+ 'Quote Previewing': QuotePreview,
+ 'Quote Backlinks': QuoteBacklink,
+ 'Mark Quotes of You': QuoteYou,
+ 'Mark OP Quotes': QuoteOP,
+ 'Mark Cross-thread Quotes': QuoteCT,
+ 'Anonymize': Anonymize,
+ 'Time Formatting': Time,
+ 'Relative Post Dates': RelativeDates,
+ 'File Info Formatting': FileInfo,
+ 'Fappe Tyme': FappeTyme,
+ 'Gallery': Gallery,
+ 'Gallery (menu)': Gallery.menu,
+ 'Sauce': Sauce,
+ 'Image Expansion': ImageExpand,
+ 'Image Expansion (Menu)': ImageExpand.menu,
+ 'Reveal Spoiler Thumbnails': RevealSpoilers,
+ 'Image Loading': ImageLoader,
+ 'Image Hover': ImageHover,
+ '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,
+ 'Index Navigation': Nav,
+ 'Keybinds': Keybinds,
+ 'Show Dice Roll': Dice,
+ 'Banner': Banner
+ });
+ $.on(d, 'AddCallback', Main.addCallback);
+ return $.ready(Main.initReady);
+ },
+ initStyle: function() {
+ var mainStyleSheet, setStyle, style, styleSheets, _ref;
+ $.off(d, '4chanMainInit', Main.initStyle);
+ if (!Main.isThisPageLegit() || $.hasClass(doc, 'fourchan-x')) {
+ return;
+ }
+ if ((_ref = $('link[href*=mobile]', d.head)) != null) {
+ _ref.disabled = true;
+ }
+ $.addClass(doc, 'gecko');
+ $.addClass(doc, 'fourchan-x');
+ $.addClass(doc, 'seaweedchan');
+ $.addClass(doc, g.VIEW);
+ $.addStyle(Main.css);
+ 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 styleSheet, _i, _len;
+ $.rmClass(doc, style);
+ for (_i = 0, _len = styleSheets.length; _i < _len; _i++) {
+ styleSheet = styleSheets[_i];
+ if (styleSheet.href === mainStyleSheet.href) {
+ style = styleSheet.title.toLowerCase().replace('new', '').trim().replace(/\s+/g, '-');
+ break;
+ }
+ }
+ return $.addClass(doc, style);
+ };
+ setStyle();
+ if (!mainStyleSheet) {
+ return;
+ }
+ return new MutationObserver(setStyle).observe(mainStyleSheet, {
+ attributes: true,
+ attributeFilter: ['href']
+ });
+ },
+ initReady: function() {
+ var GMver, err, href, i, passLink, styleSelector, v, _i, _len, _ref, _ref1;
+ if ((_ref = d.title) === '4chan - Temporarily Offline' || _ref === '4chan - 404 Not Found') {
+ if (Conf['404 Redirect'] && g.VIEW === 'thread') {
+ href = Redirect.to('thread', {
+ boardID: g.BOARD.ID,
+ threadID: g.THREADID,
+ postID: +location.hash.match(/\d+/)
+ });
+ location.replace(href || ("/" + g.BOARD + "/"));
+ }
+ return;
+ }
+ Main.initStyle();
+ if (g.VIEW === 'thread') {
+ Main.initThread();
+ } else {
+ $.event('4chanXInitFinished');
+ }
+ if (styleSelector = $.id('styleSelector')) {
+ passLink = $.el('a', {
+ textContent: '4chan Pass',
+ href: 'javascript:;'
+ });
+ $.on(passLink, 'click', function() {
+ return window.open('//sys.4chan.org/auth', 'This will steal your data.', 'left=0,top=0,width=500,height=255,toolbar=0,resizable=0');
+ });
+ $.before(styleSelector.previousSibling, [$.tn('['), passLink, $.tn(']\u00A0\u00A0')]);
+ }
+ GMver = GM_info.version.split('.');
+ _ref1 = "1.13".split('.');
+ for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) {
+ v = _ref1[i];
+ if (v === GMver[i]) {
+ continue;
+ }
+ (v < GMver[i]) || new Notice('warning', "Your version of Greasemonkey is outdated (v" + GM_info.version + " instead of v1.13 minimum) and 4chan X may not operate correctly.", 30);
+ break;
+ }
+ try {
+ return localStorage.getItem('4chan-settings');
+ } catch (_error) {
+ err = _error;
+ return new Notice('warning', 'Cookies need to be enabled on 4chan for 4chan X to operate properly.', 30);
+ }
+ },
+ initThread: function() {
+ var err, errors, postRoot, posts, thread, threadRoot, _i, _len, _ref;
+ if (!(threadRoot = $('.thread'))) {
+ return;
+ }
+ thread = new Thread(+threadRoot.id.slice(1), g.BOARD);
+ posts = [];
+ _ref = $$('.thread > .postContainer', threadRoot);
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ postRoot = _ref[_i];
+ try {
+ posts.push(new Post(postRoot, thread, g.BOARD, {
+ isOriginalMarkup: true
+ }));
+ } 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);
+ }
+ Main.callbackNodes(Thread, [thread]);
+ return Main.callbackNodesDB(Post, posts, function() {
+ 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, errors, fn, i, len, softTask;
+ errors = null;
+ len = 0;
+ i = 0;
+ cbs = klass.callbacks;
+ fn = function() {
+ var node;
+ node = nodes[i++];
+ cbs.execute(node);
+ return i % 25;
+ };
+ softTask = function() {
+ while (fn()) {
+ if (len === i) {
+ if (cb) {
+ cb();
+ }
+ return;
+ }
+ }
+ return setTimeout(softTask, 0);
+ };
+ len = nodes.length;
+ return softTask();
+ },
+ addCallback: function(e) {
+ var Klass, obj;
+ obj = e.detail;
+ if (typeof obj.callback.name !== 'string') {
+ throw new Error("Invalid callback name: " + obj.callback.name);
+ }
+ switch (obj.type) {
+ case 'Post':
+ Klass = Post;
+ break;
+ case 'Thread':
+ Klass = Thread;
+ break;
+ default:
+ return;
+ }
+ obj.callback.isAddon = true;
+ return Klass.callbacks.push(obj.callback);
+ },
+ handleErrors: function(errors) {
+ var div, error, logs, _i, _len;
+ if (!(errors instanceof Array)) {
+ error = errors;
+ } else if (errors.length === 1) {
+ error = errors[0];
+ }
+ if (error) {
+ new Notice('error', Main.parseError(error), 15);
+ return;
+ }
+ div = $.el('div', {
+ innerHTML: "" + errors.length + " errors occurred. [show ]"
+ });
+ $.on(div.lastElementChild, 'click', function() {
+ var _ref;
+ return _ref = this.textContent === 'show' ? ['hide', false] : ['show', true], this.textContent = _ref[0], logs.hidden = _ref[1], _ref;
+ });
+ logs = $.el('div', {
+ hidden: true
+ });
+ for (_i = 0, _len = errors.length; _i < _len; _i++) {
+ error = errors[_i];
+ $.add(logs, Main.parseError(error));
+ }
+ return new Notice('error', [div, logs], 30);
+ },
+ parseError: function(data) {
+ var error, message;
+ c.error(data.message, data.error.stack);
+ message = $.el('div', {
+ textContent: data.message
+ });
+ error = $.el('div', {
+ textContent: data.error
+ });
+ return [message, error];
+ },
+ 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;
+ },
+ css: "/*! * Font Awesome 4.0.3 * the iconic font designed for Bootstrap * ------------------------------------------------------------------------------ * The full suite of pictographic icons, examples, and documentation can be * found at http://fontawesome.io. Stay up to date on Twitter at * http://twitter.com/fontawesome. * * License * ------------------------------------------------------------------------------ * - The Font Awesome font is licensed under SIL OFL 1.1 - * http://scripts.sil.org/OFL * - Font Awesome CSS, LESS, and SASS files are licensed under MIT License - * http://opensource.org/licenses/mit-license.html * - Font Awesome documentation licensed under CC BY 3.0 - * http://creativecommons.org/licenses/by/3.0/ * - Attribution is no longer required in Font Awesome 3.0, but much appreciated: * \"Font Awesome by Dave Gandy - http://fontawesome.io\" * * Author - Dave Gandy * ------------------------------------------------------------------------------ * Email: dave@fontawesome.io * Twitter: http://twitter.com/davegandy * Work: Lead Product Designer @ Kyruus - http://kyruus.com */ @font-face{font-family:FontAwesome;src:url('data:application/font-woff;base64,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') format('woff');font-weight:400;font-style:normal}.fa::before{font-family:FontAwesome;font-weight:400;font-style:normal;-webkit-font-smoothing:antialiased;*margin-right:.3em;text-decoration:inherit;display:none;speak:none} :root.shortcut-icons .fa::before, .menu-button .fa::before, .hide-reply-button .fa::before, .hide-thread-button .fa::before {display:inline-block;font-size:13px;visibility:visible} :root.shortcut-icons #shortcuts .fa::before{font-size:15px!important;margin-top:-3px!important;position:relative;top:1px} :root.shortcut-icons .fa, .menu-button .fa{font-size:0;visibility:hidden} :root.shortcut-icons .shortcut.brackets-wrap::after,:root.shortcut-icons .shortcut.brackets-wrap::before{display:none} :root.shortcut-icons a .fa, .menu-button .fa, .hide-reply-button .fa, .hide-thread-button .fa {display:inline} /* Update this line only */ .fa-glass:before{content:\"\\f000\"}.fa-music:before{content:\"\\f001\"}.fa-search:before{content:\"\\f002\"}.fa-envelope-o:before{content:\"\\f003\"}.fa-heart:before{content:\"\\f004\"}.fa-star:before{content:\"\\f005\"}.fa-star-o:before{content:\"\\f006\"}.fa-user:before{content:\"\\f007\"}.fa-film:before{content:\"\\f008\"}.fa-th-large:before{content:\"\\f009\"}.fa-th:before{content:\"\\f00a\"}.fa-th-list:before{content:\"\\f00b\"}.fa-check:before{content:\"\\f00c\"}.fa-times:before{content:\"\\f00d\"}.fa-search-plus:before{content:\"\\f00e\"}.fa-search-minus:before{content:\"\\f010\"}.fa-power-off:before{content:\"\\f011\"}.fa-signal:before{content:\"\\f012\"}.fa-gear:before,.fa-cog:before{content:\"\\f013\"}.fa-trash-o:before{content:\"\\f014\"}.fa-home:before{content:\"\\f015\"}.fa-file-o:before{content:\"\\f016\"}.fa-clock-o:before{content:\"\\f017\"}.fa-road:before{content:\"\\f018\"}.fa-download:before{content:\"\\f019\"}.fa-arrow-circle-o-down:before{content:\"\\f01a\"}.fa-arrow-circle-o-up:before{content:\"\\f01b\"}.fa-inbox:before{content:\"\\f01c\"}.fa-play-circle-o:before{content:\"\\f01d\"}.fa-rotate-right:before,.fa-repeat:before{content:\"\\f01e\"}.fa-refresh:before{content:\"\\f021\"}.fa-list-alt:before{content:\"\\f022\"}.fa-lock:before{content:\"\\f023\"}.fa-flag:before{content:\"\\f024\"}.fa-headphones:before{content:\"\\f025\"}.fa-volume-off:before{content:\"\\f026\"}.fa-volume-down:before{content:\"\\f027\"}.fa-volume-up:before{content:\"\\f028\"}.fa-qrcode:before{content:\"\\f029\"}.fa-barcode:before{content:\"\\f02a\"}.fa-tag:before{content:\"\\f02b\"}.fa-tags:before{content:\"\\f02c\"}.fa-book:before{content:\"\\f02d\"}.fa-bookmark:before{content:\"\\f02e\"}.fa-print:before{content:\"\\f02f\"}.fa-camera:before{content:\"\\f030\"}.fa-font:before{content:\"\\f031\"}.fa-bold:before{content:\"\\f032\"}.fa-italic:before{content:\"\\f033\"}.fa-text-height:before{content:\"\\f034\"}.fa-text-width:before{content:\"\\f035\"}.fa-align-left:before{content:\"\\f036\"}.fa-align-center:before{content:\"\\f037\"}.fa-align-right:before{content:\"\\f038\"}.fa-align-justify:before{content:\"\\f039\"}.fa-list:before{content:\"\\f03a\"}.fa-dedent:before,.fa-outdent:before{content:\"\\f03b\"}.fa-indent:before{content:\"\\f03c\"}.fa-video-camera:before{content:\"\\f03d\"}.fa-picture-o:before{content:\"\\f03e\"}.fa-pencil:before{content:\"\\f040\"}.fa-map-marker:before{content:\"\\f041\"}.fa-adjust:before{content:\"\\f042\"}.fa-tint:before{content:\"\\f043\"}.fa-edit:before,.fa-pencil-square-o:before{content:\"\\f044\"}.fa-share-square-o:before{content:\"\\f045\"}.fa-check-square-o:before{content:\"\\f046\"}.fa-arrows:before{content:\"\\f047\"}.fa-step-backward:before{content:\"\\f048\"}.fa-fast-backward:before{content:\"\\f049\"}.fa-backward:before{content:\"\\f04a\"}.fa-play:before{content:\"\\f04b\"}.fa-pause:before{content:\"\\f04c\"}.fa-stop:before{content:\"\\f04d\"}.fa-forward:before{content:\"\\f04e\"}.fa-fast-forward:before{content:\"\\f050\"}.fa-step-forward:before{content:\"\\f051\"}.fa-eject:before{content:\"\\f052\"}.fa-chevron-left:before{content:\"\\f053\"}.fa-chevron-right:before{content:\"\\f054\"}.fa-plus-circle:before{content:\"\\f055\"}.fa-minus-circle:before{content:\"\\f056\"}.fa-times-circle:before{content:\"\\f057\"}.fa-check-circle:before{content:\"\\f058\"}.fa-question-circle:before{content:\"\\f059\"}.fa-info-circle:before{content:\"\\f05a\"}.fa-crosshairs:before{content:\"\\f05b\"}.fa-times-circle-o:before{content:\"\\f05c\"}.fa-check-circle-o:before{content:\"\\f05d\"}.fa-ban:before{content:\"\\f05e\"}.fa-arrow-left:before{content:\"\\f060\"}.fa-arrow-right:before{content:\"\\f061\"}.fa-arrow-up:before{content:\"\\f062\"}.fa-arrow-down:before{content:\"\\f063\"}.fa-mail-forward:before,.fa-share:before{content:\"\\f064\"}.fa-expand:before{content:\"\\f065\"}.fa-compress:before{content:\"\\f066\"}.fa-plus:before{content:\"\\f067\"}.fa-minus:before{content:\"\\f068\"}.fa-asterisk:before{content:\"\\f069\"}.fa-exclamation-circle:before{content:\"\\f06a\"}.fa-gift:before{content:\"\\f06b\"}.fa-leaf:before{content:\"\\f06c\"}.fa-fire:before{content:\"\\f06d\"}.fa-eye:before{content:\"\\f06e\"}.fa-eye-slash:before{content:\"\\f070\"}.fa-warning:before,.fa-exclamation-triangle:before{content:\"\\f071\"}.fa-plane:before{content:\"\\f072\"}.fa-calendar:before{content:\"\\f073\"}.fa-random:before{content:\"\\f074\"}.fa-comment:before{content:\"\\f075\"}.fa-magnet:before{content:\"\\f076\"}.fa-chevron-up:before{content:\"\\f077\"}.fa-chevron-down:before{content:\"\\f078\"}.fa-retweet:before{content:\"\\f079\"}.fa-shopping-cart:before{content:\"\\f07a\"}.fa-folder:before{content:\"\\f07b\"}.fa-folder-open:before{content:\"\\f07c\"}.fa-arrows-v:before{content:\"\\f07d\"}.fa-arrows-h:before{content:\"\\f07e\"}.fa-bar-chart-o:before{content:\"\\f080\"}.fa-twitter-square:before{content:\"\\f081\"}.fa-facebook-square:before{content:\"\\f082\"}.fa-camera-retro:before{content:\"\\f083\"}.fa-key:before{content:\"\\f084\"}.fa-gears:before,.fa-cogs:before{content:\"\\f085\"}.fa-comments:before{content:\"\\f086\"}.fa-thumbs-o-up:before{content:\"\\f087\"}.fa-thumbs-o-down:before{content:\"\\f088\"}.fa-star-half:before{content:\"\\f089\"}.fa-heart-o:before{content:\"\\f08a\"}.fa-sign-out:before{content:\"\\f08b\"}.fa-linkedin-square:before{content:\"\\f08c\"}.fa-thumb-tack:before{content:\"\\f08d\"}.fa-external-link:before{content:\"\\f08e\"}.fa-sign-in:before{content:\"\\f090\"}.fa-trophy:before{content:\"\\f091\"}.fa-github-square:before{content:\"\\f092\"}.fa-upload:before{content:\"\\f093\"}.fa-lemon-o:before{content:\"\\f094\"}.fa-phone:before{content:\"\\f095\"}.fa-square-o:before{content:\"\\f096\"}.fa-bookmark-o:before{content:\"\\f097\"}.fa-phone-square:before{content:\"\\f098\"}.fa-twitter:before{content:\"\\f099\"}.fa-facebook:before{content:\"\\f09a\"}.fa-github:before{content:\"\\f09b\"}.fa-unlock:before{content:\"\\f09c\"}.fa-credit-card:before{content:\"\\f09d\"}.fa-rss:before{content:\"\\f09e\"}.fa-hdd-o:before{content:\"\\f0a0\"}.fa-bullhorn:before{content:\"\\f0a1\"}.fa-bell:before{content:\"\\f0f3\"}.fa-certificate:before{content:\"\\f0a3\"}.fa-hand-o-right:before{content:\"\\f0a4\"}.fa-hand-o-left:before{content:\"\\f0a5\"}.fa-hand-o-up:before{content:\"\\f0a6\"}.fa-hand-o-down:before{content:\"\\f0a7\"}.fa-arrow-circle-left:before{content:\"\\f0a8\"}.fa-arrow-circle-right:before{content:\"\\f0a9\"}.fa-arrow-circle-up:before{content:\"\\f0aa\"}.fa-arrow-circle-down:before{content:\"\\f0ab\"}.fa-globe:before{content:\"\\f0ac\"}.fa-wrench:before{content:\"\\f0ad\"}.fa-tasks:before{content:\"\\f0ae\"}.fa-filter:before{content:\"\\f0b0\"}.fa-briefcase:before{content:\"\\f0b1\"}.fa-arrows-alt:before{content:\"\\f0b2\"}.fa-group:before,.fa-users:before{content:\"\\f0c0\"}.fa-chain:before,.fa-link:before{content:\"\\f0c1\"}.fa-cloud:before{content:\"\\f0c2\"}.fa-flask:before{content:\"\\f0c3\"}.fa-cut:before,.fa-scissors:before{content:\"\\f0c4\"}.fa-copy:before,.fa-files-o:before{content:\"\\f0c5\"}.fa-paperclip:before{content:\"\\f0c6\"}.fa-save:before,.fa-floppy-o:before{content:\"\\f0c7\"}.fa-square:before{content:\"\\f0c8\"}.fa-bars:before{content:\"\\f0c9\"}.fa-list-ul:before{content:\"\\f0ca\"}.fa-list-ol:before{content:\"\\f0cb\"}.fa-strikethrough:before{content:\"\\f0cc\"}.fa-underline:before{content:\"\\f0cd\"}.fa-table:before{content:\"\\f0ce\"}.fa-magic:before{content:\"\\f0d0\"}.fa-truck:before{content:\"\\f0d1\"}.fa-pinterest:before{content:\"\\f0d2\"}.fa-pinterest-square:before{content:\"\\f0d3\"}.fa-google-plus-square:before{content:\"\\f0d4\"}.fa-google-plus:before{content:\"\\f0d5\"}.fa-money:before{content:\"\\f0d6\"}.fa-caret-down:before{content:\"\\f0d7\"}.fa-caret-up:before{content:\"\\f0d8\"}.fa-caret-left:before{content:\"\\f0d9\"}.fa-caret-right:before{content:\"\\f0da\"}.fa-columns:before{content:\"\\f0db\"}.fa-unsorted:before,.fa-sort:before{content:\"\\f0dc\"}.fa-sort-down:before,.fa-sort-asc:before{content:\"\\f0dd\"}.fa-sort-up:before,.fa-sort-desc:before{content:\"\\f0de\"}.fa-envelope:before{content:\"\\f0e0\"}.fa-linkedin:before{content:\"\\f0e1\"}.fa-rotate-left:before,.fa-undo:before{content:\"\\f0e2\"}.fa-legal:before,.fa-gavel:before{content:\"\\f0e3\"}.fa-dashboard:before,.fa-tachometer:before{content:\"\\f0e4\"}.fa-comment-o:before{content:\"\\f0e5\"}.fa-comments-o:before{content:\"\\f0e6\"}.fa-flash:before,.fa-bolt:before{content:\"\\f0e7\"}.fa-sitemap:before{content:\"\\f0e8\"}.fa-umbrella:before{content:\"\\f0e9\"}.fa-paste:before,.fa-clipboard:before{content:\"\\f0ea\"}.fa-lightbulb-o:before{content:\"\\f0eb\"}.fa-exchange:before{content:\"\\f0ec\"}.fa-cloud-download:before{content:\"\\f0ed\"}.fa-cloud-upload:before{content:\"\\f0ee\"}.fa-user-md:before{content:\"\\f0f0\"}.fa-stethoscope:before{content:\"\\f0f1\"}.fa-suitcase:before{content:\"\\f0f2\"}.fa-bell-o:before{content:\"\\f0a2\"}.fa-coffee:before{content:\"\\f0f4\"}.fa-cutlery:before{content:\"\\f0f5\"}.fa-file-text-o:before{content:\"\\f0f6\"}.fa-building-o:before{content:\"\\f0f7\"}.fa-hospital-o:before{content:\"\\f0f8\"}.fa-ambulance:before{content:\"\\f0f9\"}.fa-medkit:before{content:\"\\f0fa\"}.fa-fighter-jet:before{content:\"\\f0fb\"}.fa-beer:before{content:\"\\f0fc\"}.fa-h-square:before{content:\"\\f0fd\"}.fa-plus-square:before{content:\"\\f0fe\"}.fa-angle-double-left:before{content:\"\\f100\"}.fa-angle-double-right:before{content:\"\\f101\"}.fa-angle-double-up:before{content:\"\\f102\"}.fa-angle-double-down:before{content:\"\\f103\"}.fa-angle-left:before{content:\"\\f104\"}.fa-angle-right:before{content:\"\\f105\"}.fa-angle-up:before{content:\"\\f106\"}.fa-angle-down:before{content:\"\\f107\"}.fa-desktop:before{content:\"\\f108\"}.fa-laptop:before{content:\"\\f109\"}.fa-tablet:before{content:\"\\f10a\"}.fa-mobile-phone:before,.fa-mobile:before{content:\"\\f10b\"}.fa-circle-o:before{content:\"\\f10c\"}.fa-quote-left:before{content:\"\\f10d\"}.fa-quote-right:before{content:\"\\f10e\"}.fa-spinner:before{content:\"\\f110\"}.fa-circle:before{content:\"\\f111\"}.fa-mail-reply:before,.fa-reply:before{content:\"\\f112\"}.fa-github-alt:before{content:\"\\f113\"}.fa-folder-o:before{content:\"\\f114\"}.fa-folder-open-o:before{content:\"\\f115\"}.fa-smile-o:before{content:\"\\f118\"}.fa-frown-o:before{content:\"\\f119\"}.fa-meh-o:before{content:\"\\f11a\"}.fa-gamepad:before{content:\"\\f11b\"}.fa-keyboard-o:before{content:\"\\f11c\"}.fa-flag-o:before{content:\"\\f11d\"}.fa-flag-checkered:before{content:\"\\f11e\"}.fa-terminal:before{content:\"\\f120\"}.fa-code:before{content:\"\\f121\"}.fa-reply-all:before{content:\"\\f122\"}.fa-mail-reply-all:before{content:\"\\f122\"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:\"\\f123\"}.fa-location-arrow:before{content:\"\\f124\"}.fa-crop:before{content:\"\\f125\"}.fa-code-fork:before{content:\"\\f126\"}.fa-unlink:before,.fa-chain-broken:before{content:\"\\f127\"}.fa-question:before{content:\"\\f128\"}.fa-info:before{content:\"\\f129\"}.fa-exclamation:before{content:\"\\f12a\"}.fa-superscript:before{content:\"\\f12b\"}.fa-subscript:before{content:\"\\f12c\"}.fa-eraser:before{content:\"\\f12d\"}.fa-puzzle-piece:before{content:\"\\f12e\"}.fa-microphone:before{content:\"\\f130\"}.fa-microphone-slash:before{content:\"\\f131\"}.fa-shield:before{content:\"\\f132\"}.fa-calendar-o:before{content:\"\\f133\"}.fa-fire-extinguisher:before{content:\"\\f134\"}.fa-rocket:before{content:\"\\f135\"}.fa-maxcdn:before{content:\"\\f136\"}.fa-chevron-circle-left:before{content:\"\\f137\"}.fa-chevron-circle-right:before{content:\"\\f138\"}.fa-chevron-circle-up:before{content:\"\\f139\"}.fa-chevron-circle-down:before{content:\"\\f13a\"}.fa-html5:before{content:\"\\f13b\"}.fa-css3:before{content:\"\\f13c\"}.fa-anchor:before{content:\"\\f13d\"}.fa-unlock-alt:before{content:\"\\f13e\"}.fa-bullseye:before{content:\"\\f140\"}.fa-ellipsis-h:before{content:\"\\f141\"}.fa-ellipsis-v:before{content:\"\\f142\"}.fa-rss-square:before{content:\"\\f143\"}.fa-play-circle:before{content:\"\\f144\"}.fa-ticket:before{content:\"\\f145\"}.fa-minus-square:before{content:\"\\f146\"}.fa-minus-square-o:before{content:\"\\f147\"}.fa-level-up:before{content:\"\\f148\"}.fa-level-down:before{content:\"\\f149\"}.fa-check-square:before{content:\"\\f14a\"}.fa-pencil-square:before{content:\"\\f14b\"}.fa-external-link-square:before{content:\"\\f14c\"}.fa-share-square:before{content:\"\\f14d\"}.fa-compass:before{content:\"\\f14e\"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:\"\\f150\"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:\"\\f151\"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:\"\\f152\"}.fa-euro:before,.fa-eur:before{content:\"\\f153\"}.fa-gbp:before{content:\"\\f154\"}.fa-dollar:before,.fa-usd:before{content:\"\\f155\"}.fa-rupee:before,.fa-inr:before{content:\"\\f156\"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:\"\\f157\"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:\"\\f158\"}.fa-won:before,.fa-krw:before{content:\"\\f159\"}.fa-bitcoin:before,.fa-btc:before{content:\"\\f15a\"}.fa-file:before{content:\"\\f15b\"}.fa-file-text:before{content:\"\\f15c\"}.fa-sort-alpha-asc:before{content:\"\\f15d\"}.fa-sort-alpha-desc:before{content:\"\\f15e\"}.fa-sort-amount-asc:before{content:\"\\f160\"}.fa-sort-amount-desc:before{content:\"\\f161\"}.fa-sort-numeric-asc:before{content:\"\\f162\"}.fa-sort-numeric-desc:before{content:\"\\f163\"}.fa-thumbs-up:before{content:\"\\f164\"}.fa-thumbs-down:before{content:\"\\f165\"}.fa-youtube-square:before{content:\"\\f166\"}.fa-youtube:before{content:\"\\f167\"}.fa-xing:before{content:\"\\f168\"}.fa-xing-square:before{content:\"\\f169\"}.fa-youtube-play:before{content:\"\\f16a\"}.fa-dropbox:before{content:\"\\f16b\"}.fa-stack-overflow:before{content:\"\\f16c\"}.fa-instagram:before{content:\"\\f16d\"}.fa-flickr:before{content:\"\\f16e\"}.fa-adn:before{content:\"\\f170\"}.fa-bitbucket:before{content:\"\\f171\"}.fa-bitbucket-square:before{content:\"\\f172\"}.fa-tumblr:before{content:\"\\f173\"}.fa-tumblr-square:before{content:\"\\f174\"}.fa-long-arrow-down:before{content:\"\\f175\"}.fa-long-arrow-up:before{content:\"\\f176\"}.fa-long-arrow-left:before{content:\"\\f177\"}.fa-long-arrow-right:before{content:\"\\f178\"}.fa-apple:before{content:\"\\f179\"}.fa-windows:before{content:\"\\f17a\"}.fa-android:before{content:\"\\f17b\"}.fa-linux:before{content:\"\\f17c\"}.fa-dribbble:before{content:\"\\f17d\"}.fa-skype:before{content:\"\\f17e\"}.fa-foursquare:before{content:\"\\f180\"}.fa-trello:before{content:\"\\f181\"}.fa-female:before{content:\"\\f182\"}.fa-male:before{content:\"\\f183\"}.fa-gittip:before{content:\"\\f184\"}.fa-sun-o:before{content:\"\\f185\"}.fa-moon-o:before{content:\"\\f186\"}.fa-archive:before{content:\"\\f187\"}.fa-bug:before{content:\"\\f188\"}.fa-vk:before{content:\"\\f189\"}.fa-weibo:before{content:\"\\f18a\"}.fa-renren:before{content:\"\\f18b\"}.fa-pagelines:before{content:\"\\f18c\"}.fa-stack-exchange:before{content:\"\\f18d\"}.fa-arrow-circle-o-right:before{content:\"\\f18e\"}.fa-arrow-circle-o-left:before{content:\"\\f190\"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:\"\\f191\"}.fa-dot-circle-o:before{content:\"\\f192\"}.fa-wheelchair:before{content:\"\\f193\"}.fa-vimeo-square:before{content:\"\\f194\"}.fa-turkish-lira:before,.fa-try:before{content:\"\\f195\"}.fa-plus-square-o:before{content:\"\\f196\"} /* */ .fa-spin::before{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}}\n/* General */ .dialog { border: 1px solid; display: block; } .dialog:not(#qr):not(#thread-watcher):not(#header-bar) { box-shadow: 0 1px 2px rgba(0, 0, 0, .15); } #qr, #thread-watcher { box-shadow: -1px 2px 2px rgba(0, 0, 0, 0.25); } .captcha-img, .field { background-color: #FFF; border: 1px solid #CCC; -moz-box-sizing: border-box; box-sizing: border-box; color: #333; font: 13px sans-serif; outline: none; transition: color .25s, border-color .25s; transition: color .25s, border-color .25s; } .field::-moz-placeholder, .field:hover::-moz-placeholder { color: #AAA !important; font-size: 13px !important; opacity: 1.0 !important; } .captch-img:hover, .field:hover { border-color: #999; } .field:hover, .field:focus { color: #000; } .field[disabled] { background-color: #F2F2F2; color: #888; } .field::-webkit-search-decoration { display: none; } .move { cursor: move; overflow: hidden; } label, .watch-thread-link { cursor: pointer; } a[href=\"javascript:;\"] { text-decoration: none; } .warning { color: red; } #boardNavDesktop { display: none !important; } a { outline: none !important; } .painted { border-radius: 3px; padding: 0px 2px; } body>hr, .ad-plea-bottom + hr { display: none; } .board > hr:last-of-type { border-top-color: transparent !important; } div.navLinks { margin-bottom: -10px !important; } .ad-plea { display: none; } .ad-cnt { margin: 10px !important; } /* 4chan style fixes */ .opContainer, .op { display: block !important; overflow: visible !important; } .reply > .file > .fileText { margin: 0 20px; } [hidden] { display: none !important; } div.center:not(.ad-cnt) { display: none !important; } .page-num { margin-right: -8px; } /* fixed, z-index */ #overlay, #fourchanx-settings, #qp, #ihover, #navlinks, .fixed #header-bar, :root.float #updater, :root.float #thread-stats, #qr { position: fixed; } #fourchanx-settings { z-index: 999; } #overlay { z-index: 900; } #notifications { z-index: 70; } #qp, #ihover { z-index: 60; } #menu { z-index: 50; } #navlinks, #updater, #thread-stats { z-index: 40; } .fixed #header-bar.autohide { z-index: 35; } #qr { z-index: 30; } #thread-watcher { z-index: 8; } :root.fixed-watcher #thread-watcher { z-index: 20; } .fixed #header-bar { z-index: 10; } /* Header */ .fixed.top-header body { padding-top: 2em; } .fixed.bottom-header body { padding-bottom: 2em; } .fixed #header-bar { right: 0; left: 0; padding: 3px 4px 4px; } .fixed.top-header #header-bar { top: 0; } .fixed.bottom-header #header-bar { bottom: 0; } #header-bar { border-width: 0; transition: all .1s .05s ease-in-out; } :root.fixed #header-bar { box-shadow: -5px 1px 10px rgba(0, 0, 0, 0.20); } #custom-board-list .current { padding: 1px 1px 4px 1px; } :root.centered-links #shortcuts { width: 300px; text-align: right; } :root.centered-links #header-bar { text-align: center; } #board-list { font-size: 13px; } :root.centered-links #custom-board-list { position: relative; left: 150px; } .fixed.top-header #header-bar { border-bottom-width: 1px; } .fixed.bottom-header #header-bar { box-shadow: 0 -1px 2px rgba(0, 0, 0, .15); border-top-width: 1px; } .fixed.bottom-header #header-bar .menu-button i { border-top: none; border-bottom: 6px solid; } #board-list { text-align: center; } .fixed #header-bar.autohide:not(:hover) { box-shadow: none; transition: all .8s .6s cubic-bezier(.55, .055, .675, .19); } .fixed.top-header #header-bar.autohide:not(:hover) { margin-bottom: -1em; -webkit-transform: translateY(-100%); transform: translateY(-100%); } .fixed.bottom-header #header-bar.autohide:not(:hover) { -webkit-transform: translateY(100%); transform: translateY(100%); } #scroll-marker { left: 0; right: 0; height: 10px; position: absolute; } :root:not(.autohide) #scroll-marker { pointer-events: none; } #header-bar #scroll-marker { display: none; } .fixed #header-bar #scroll-marker { display: block; } .fixed.top-header #header-bar #scroll-marker { top: 100%; } .fixed.bottom-header #header-bar #scroll-marker { bottom: 100%; } #header-bar a:not(.entry):not(.close) { text-decoration: none; } #header-bar a:not(.entry):not(.close):not(.current) { padding: 1px; } #header-bar input { margin: 0; vertical-align: bottom; } #shortcuts:empty { display: none; } .brackets-wrap::before { content: \"\\00a0[\"; } .brackets-wrap::after { content: \"]\\00a0\"; } .dead-thread, .disabled { opacity: .45; } #shortcuts { float: right; } .shortcut { margin-left: 3px; } #navbotright, #navtopright { display: none; } #toggleMsgBtn { display: none !important; } .current { font-weight: bold; } /* 4chan X link brackets */ .brackets-wrap::after { content: \"]\"; } .brackets-wrap::before { content: \"[\"; } /* Notifications */ #notifications { position: fixed; top: 0; height: 0; text-align: center; right: 0; left: 0; transition: all .8s .6s cubic-bezier(.55, .055, .675, .19); } .fixed.top-header #header-bar #notifications { position: absolute; top: 100%; } .notification { color: #FFF; font-weight: 700; text-shadow: 0 1px 2px rgba(0, 0, 0, .5); box-shadow: 0 1px 2px rgba(0, 0, 0, .15); border-radius: 2px; margin: 1px auto; width: 500px; max-width: 100%; position: relative; transition: all .25s ease-in-out; } .notification.error { background-color: hsla(0, 100%, 38%, .9); } .notification.warning { background-color: hsla(36, 100%, 38%, .9); } .notification.info { background-color: hsla(200, 100%, 38%, .9); } .notification.success { background-color: hsla(104, 100%, 38%, .9); } .notification a { color: white; } .notification > .close { padding: 7px; top: 0px; right: 5px; position: absolute; } .notification > .fa-times::before { font-size: 11px !important; } .message { -moz-box-sizing: border-box; box-sizing: border-box; padding: 6px 20px; max-height: 200px; width: 100%; overflow: auto; } /* Settings */ :root.fourchan-x body { -moz-box-sizing: border-box; box-sizing: border-box; } #overlay { background-color: rgba(0, 0, 0, .5); top: 0; left: 0; height: 100%; width: 100%; } #fourchanx-settings { -moz-box-sizing: border-box; box-sizing: border-box; box-shadow: 0 0 15px rgba(0, 0, 0, .15); height: 600px; max-height: 100%; width: 900px; max-width: 100%; margin: auto; padding: 3px; top: 50%; left: 50%; -moz-transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); } #fourchanx-settings > nav { padding: 2px 2px 0; height: 15px; } #fourchanx-settings > nav a { text-decoration: underline; } #fourchanx-settings > nav a.close { text-decoration: none; padding: 0 2px; } .section-container { overflow: auto; position: absolute; top: 2.1em; right: 5px; bottom: 5px; left: 5px; padding-right: 5px; } .sections-list { padding: 0 3px; float: left; } .credits { float: right; } .tab-selected { font-weight: 700; } .section-sauce ul, .section-advanced ul { list-style: none; margin: 0; } .section-sauce ul { padding: 8px; } .section-advanced ul { padding: 0px; } .section-sauce li, .section-advanced li { padding-left: 4px; } .section-main label { text-decoration: underline; } .section-filter ul { padding: 0; } .section-filter li { margin: 10px 40px; } .section-filter textarea { height: 500px; } .section-sauce textarea { height: 350px; } .section-advanced .field[name=\"boardnav\"] { width: 100%; } .section-advanced textarea { height: 150px; } .section-advanced .archive-cell { min-width: 160px; text-align: center; } .section-advanced #archive-board-select { position: absolute; } .section-advanced .note { font-size: 0.8em; font-style: italic; margin-left: 10px; } .section-advanced .note code { font-style: normal; font-size: 11px; } .section-keybinds .field { font-family: monospace; } #fourchanx-settings fieldset { border: 1px solid; border-radius: 3px; } #fourchanx-settings legend { font-weight: 700; } #fourchanx-settings textarea { font-family: monospace; min-width: 100%; max-width: 100%; } #fourchanx-settings code { color: #000; background-color: #FFF; padding: 0 2px; } .unscroll { overflow: hidden; } /* Index */ :root.index-loading .navLinks, :root.index-loading .board, :root.index-loading .pagelist { display: none; } #index-search { padding-right: 1.5em; width: 100px; transition: color .25s, border-color .25s, width .25s; } #index-search:focus, #index-search[data-searching] { width: 200px; } #index-search-clear { color: gray; margin-left: -1em; } #index-search:not([data-searching]) + #index-search-clear { display: none; } .summary { text-decoration: none; } /* Announcement Hiding */ :root.hide-announcement #globalMessage { display: none; } span.hide-announcement { font-size: 11px; position: relative; bottom: 5px; } .globalMessage, h2, h3 { color: inherit !important; font-size: 13px; font-weight: 100; } /* Unread */ #unread-line { margin: 0; border-color: rgb(255,0,0); } /* Thread Updater */ #updater { background: none; border: none; box-shadow: none; } #updater > .move { padding: 5px 3px 0px; margin-bottom: -3px; } #updater > div:last-child { text-align: center; } #updater input[type=number] { width: 4em; } :root.float #updater { padding: 0px 3px; } .new { color: limegreen; } #update-status.new { margin-right: 5px; } #update-timer { cursor: pointer; } /* Thread Watcher */ #thread-watcher { position: absolute; } #thread-watcher { padding-bottom: 3px; padding-left: 3px; overflow: hidden; white-space: nowrap; min-width: 136px; max-height: 92%; overflow-y: auto; } #thread-watcher .menu-button { bottom: 1px; } :root.fixed-watcher #thread-watcher { position: fixed; } :root:not(.fixed-watcher) #thread-watcher:not(:hover) { max-height: 210px; overflow-y: hidden; } #thread-watcher > .move { padding-top: 3px; } #watched-threads > div { max-width: 250px; overflow: hidden; padding-left: 3px; padding-right: 3px; text-overflow: ellipsis; } #thread-watcher a { text-decoration: none; } #thread-watcher .move>.close { position: absolute; right: 0px; top: 0px; padding: 0px 4px; } .watch-thread-link { padding-top: 18px; width: 18px; height: 0px; display: inline-block; background-repeat: no-repeat; opacity: 0.2; position: relative; top: 1px; } .watch-thread-link.watched { opacity: 1; } /* Thread Stats */ #thread-stats { background: none; border: none; box-shadow: none; } :root.float #post-count, :root.float #file-count { pointer-events: none; } :root.float #thread-stats { padding: 0px 3px; } /* Quote */ .deadlink { text-decoration: none !important; } .backlink.deadlink:not(.forwardlink), .quotelink.deadlink:not(.forwardlink) { text-decoration: underline !important; } .inlined { opacity: .5; } #qp input, .forwarded { display: none; } .quotelink.forwardlink, .backlink.forwardlink { text-decoration: none; border-bottom: 1px dashed; } .filtered { text-decoration: underline line-through; } :root.hide-backlinks .backlink.filtered { display: none; } .inline { border: 1px solid; display: table; margin: 2px 0; } .inline .post { border: 0 !important; background-color: transparent !important; display: table !important; margin: 0 !important; padding: 1px 2px !important; } #qp > .opContainer::after { content: ''; clear: both; display: table; } #qp .post { border: none; margin: 0; padding: 2px 2px 5px; } #qp img { max-height: 80vh; max-width: 50vw; } .qphl { outline: 2px solid rgba(216, 94, 49, .7); } :root.highlight-own .yourPost > .reply, :root.highlight-you .quotesYou > .reply { border-left: 2px solid rgba(221,0,0,.5); } /* Quote Threading */ .threadContainer { margin-left: 20px; border-left: 1px solid rgba(128,128,128,.3); } .threadOP { clear: both; } /* File */ .fileText:hover .fntrunc, .fileText:not(:hover) .fnfull, .expanded-image > .post > .file > .fileThumb > img[data-md5], :not(.expanded-image) > .post > .file > .fileThumb > .full-image { display: none; } .expanding { opacity: .5; } :root.fit-height .full-image { max-height: 100vh; } :root.fit-width .full-image { max-width: 100%; } :root.gecko.fit-width .full-image { width: 100%; } #ihover { -moz-box-sizing: border-box; box-sizing: border-box; max-height: 100%; max-width: 75%; padding-bottom: 16px; } /* Fappe Tyme */ .fappeTyme .thread > .noFile, .fappeTyme .threadContainer > .noFile { display: none; } /* Werk Tyme */ .werkTyme .post .file { display: none; } /* Index/Reply Navigation */ #navlinks { font-size: 16px; top: 25px; right: 10px; } /* Filter */ .opContainer.filter-highlight { box-shadow: inset 5px 0 rgba(255, 0, 0, .5); } .filter-highlight > .reply { box-shadow: -5px 0 rgba(255, 0, 0, .5); } /* Spoiler text */ :root.reveal-spoilers s { color: white !important; } /* Thread & Reply Hiding */ .hide-thread-button, .hide-reply-button { float: left; margin-right: 4px; padding: 2px; } .hide-thread-button:not(:hover), .hide-reply-button:not(:hover) { opacity: 0.4; } .threadContainer .hide-reply-button { margin-left: 2px !important; position: relative; left: 1px; } .hide-thread-button { margin-top: -1px; } .stub ~ * { display: none !important; } .stub input { display: inline-block; } /* QR */ :root.hide-original-post-form #postForm, :root.hide-original-post-form .postingMode, :root.hide-original-post-form #togglePostForm, #qr.autohide:not(.has-focus):not(:hover) > form, .postingMode ~ #qr select[data-name=thread], #file-n-submit:not(.has-file) #qr-filerm { display: none; } #qr select, #dump-button, #url-button, .remove, .captcha-img { cursor: pointer; } #qr { z-index: 20; position: fixed; padding: 1px; border: 1px solid transparent; min-width: 300px; border-radius: 3px 3px 0 0; } #qrtab { border-radius: 3px 3px 0 0; } #qrtab { margin-bottom: 1px; } #qr .close { float: right; padding: 0 3px; } #qr .warning { min-height: 1.6em; vertical-align: middle; padding: 0 1px; border-width: 1px; border-style: solid; } .qr-link-container { text-align: center; } .qr-link { border-radius: 3px; padding: 6px 10px 5px; font-weight: bold; vertical-align: middle; border-style: solid; border-width: 1px; font-size: 10pt; } .persona { width: 248px; max-width: 100%; min-width: 100%; } #dump-button { width: 10%; margin: 0; margin-right: 4px; font: 13px sans-serif; padding: 1px 0px 2px; opacity: 0.6; } #url-button { width: 10%; margin: 0; margin-right: 4px; font: 13px sans-serif; padding: 1px 0px 2px; opacity: 0.6; } .persona .field:not(#dump) { width: 95px; min-width: 33.3%; max-width: 33.3%; } #qr textarea.field { height: 14.8em; min-height: 9em; } #qr.has-captcha textarea.field { height: 9em; } input.field.tripped:not(:hover):not(:focus) { color: transparent !important; text-shadow: none !important; } #qr textarea { resize: both; } .captcha-img { margin: 0px; text-align: center; background-image: #fff; font-size: 0px; min-height: 59px; min-width: 302px; } .captcha-input{ width: 100%; margin: 1px 0 0; } .captcha-input.error:focus { border-color: rgb(255,0,0) !important; } .field { -moz-box-sizing: border-box; margin: 0px; padding: 2px 4px 3px; } #qr textarea { min-width: 100%; } #qr [type='submit'] { width: 25%; vertical-align: top; } :root.webkit #qr [type='submit'] { height: 24px; } #qr label input[type=\"checkbox\"] { position: relative; top: 2px; } /* Fake File Input */ input#qr-filename { border: none !important; width: 80%; padding: 0px 4px; position: relative; bottom: 1px; background: none !important; } input#qr-filename:not(.edit) { pointer-events: none; } #qr-filename, #qr-filesize, .has-file #qr-no-file { display: none; } #qr-no-file, .has-file #qr-filename, .has-file #qr-filesize { display: inline-block; margin: 0 0 2px; overflow: hidden; text-overflow: ellipsis; vertical-align: top; } #qr-no-file { color: #AAA; padding: 1px 4px; } #qr-filename-container { -moz-box-sizing: border-box; display: inline-block; position: relative; width: 100px; min-width: 74.6%; max-width: 74.6%; margin-right: 0.4%; margin-top: 1px; overflow: hidden; padding: 2px 1px 0; height: 22px; } #qr-filename-container:hover { cursor: text; } #qr-extras-container { position: absolute; right: 0px; } #qr-filerm { margin-right: 3px; z-index: 2; } #file-n-submit { height: 23px; } #qr input[type=file] { visibility: hidden; position: absolute; } /* Thread Select / Spoiler Label */ #qr select[data-name=thread] { float: right; } #qr.has-spoiler .has-file #qr-spoiler-label { width: 6.7%; min-width: 6.7%; max-width: 6.7%; display: inline-block; text-align: center; vertical-align: top; } #qr.has-spoiler #file-n-submit:not(.has-file) #qr-spoiler-label { display: none; } #qr.has-spoiler .has-file #qr-filename-container { max-width: 67.9%; min-width: 67.9%; } #qr-spoiler-label input { position: relative; top: 3px; } /* Dumping UI */ .dump #dump-list-container { display: block; } #dump-list-container { display: none; position: relative; overflow-y: hidden; margin-top: 1px; } #dump-list { overflow-x: auto; overflow-y: hidden; white-space: nowrap; width: 248px; max-width: 100%; min-width: 100%; } #dump-list:hover { overflow-x: auto; } .qr-preview { -moz-box-sizing: border-box; counter-increment: thumbnails; cursor: move; display: inline-block; height: 90px; width: 90px; padding: 2px; opacity: .5; overflow: hidden; position: relative; text-shadow: 0 0 2px #000; -moz-transition: opacity .25s ease-in-out; vertical-align: top; background-size: cover; } .qr-preview:hover, .qr-preview:focus { opacity: .9; } .qr-preview::before { content: counter(thumbnails); color: #fff; position: absolute; top: 3px; right: 3px; text-shadow: 0 0 3px #000, 0 0 8px #000; } .qr-preview#selected { opacity: 1; } .qr-preview.drag { box-shadow: 0 0 10px rgba(0,0,0,.5); } .qr-preview.over { border-color: #fff; } .qr-preview > span { color: #fff; } .remove { background: none; color: #e00; padding: 1px; } a:only-of-type > .remove { display: none; } .remove:hover::after { content: \" Remove\"; } .qr-preview > label { background: rgba(0,0,0,.5); color: #fff; right: 0; bottom: 0; left: 0; position: absolute; text-align: center; } .qr-preview > label > input { margin: 0; } #add-post { cursor: pointer; font-size: 2em; position: absolute; top: 50%; right: 10px; -moz-transform: translateY(-50%); } .textarea { position: relative; } :root.webkit .textarea { margin-bottom: -2px; } #char-count { color: #000; background: hsla(0, 0%, 100%, .5); font-size: 8pt; position: absolute; bottom: 1px; right: 1px; pointer-events: none; } /* Menu */ .menu-button:not(.fa-bars) { display: inline-block; position: relative; cursor: pointer; } .menu-button i { border-top: 6px solid; border-right: 4px solid transparent; border-left: 4px solid transparent; display: inline-block; margin: 2px; vertical-align: middle; } .reply .menu-button, .op .menu-button, #thread-watcher .menu-button { margin-left: -1px !important; position: relative; } .op .menu-button, #thread-watcher .menu-button { top: 1px; } :root.blink .reply .menu-button { position: relative; top: 2px; } :root.blink .op .menu-button, :root.blink #thread-watcher .menu-button { top: 3px; } .menu-button + .container:not(:empty) { margin-left: -5px !important; } #menu { position: fixed; outline: none; } #menu, .submenu { border-radius: 3px; padding-top: 1px; padding-bottom: 3px; } .entry { cursor: pointer; display: block; outline: none; padding: 2px 10px; position: relative; text-decoration: none; white-space: nowrap; min-width: 70px; } .left>.entry.has-submenu { padding-right: 17px !important; } .entry input[type=\"checkbox\"], .entry input[type=\"radio\"] { margin: 0px; position: relative; top: 2px; } .has-submenu::after { content: \"\"; border-left: .5em solid; border-top: .3em solid transparent; border-bottom: .3em solid transparent; display: inline-block; margin: .3em; position: absolute; right: 3px; } .left .has-submenu::after { border-left: 0; border-right: .5em solid; } .submenu { display: none; position: absolute; left: 100%; top: -1px; margin-left: 0px; margin-top: -2px; } .focused > .submenu { display: block; } .imp-exp-result { position: absolute; text-align: center; margin: auto; right: 0px; left: 0px; width: 200px; } .export, .import { cursor: pointer; text-decoration: none !important; } /* Custom Board Titles */ .boardTitle[contenteditable=\"true\"], .boardSubtitle[contenteditable=\"true\"] { cursor: text !important; } div.boardTitle { font-weight: 400 !important; } /* Link Title Favicons */ .linkify.YouTube { background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAMCAYAAABr5z2BAAABIklEQVQoz53LvUrDUBjG8bOoOammSf1IoBSvoCB4JeIqOHgBLt6AIMRBBQelWurQ2kERnMRBsBUcIp5FJSBI5oQsJVkkUHh8W0o5nhaFHvjBgef/Mq+Q46RJBMkI/vE+aOus956tnEswIZe1LV0QyJ5sE2GzgZfVMtRNIdiDpccEssdlB1mW4bvTwdvWJtRdErM7U+8S/FJykCRJX5qm+KpVce8UMNLRLbulz4iSjTAMh6Iowsd5BeNadp3nUF0VlxAEwZBotXC0Usa4ll3meZdA1iguwvf9vpvDA2wvmKgYGtSud8suDB4TyGr2PF49D/vra9jRZ1BVdknMzgwuCGSnZEObwu6sBnVTCHZiaC7BhFx2PKdxUidiAH/4lLo9Mv0DELVs9qsOHXwAAAAASUVORK5CYII=') center left no-repeat!important; padding-left: 18px; } .linkify.Vimeo { background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAYFBMVEUAAAAIdZUKh6sLlLkLmr4LmsAMp88NrdYVW3MZj7Acstkrt9s1e5E7vN5EfI9JvdtKwuBijp5kpbl30eiDt8aG1uqRr7qTyNehxM+k4PCy3enB3OTg6Ovv9PXw+fz////L9U5WAAAAAXRSTlMAQObYZgAAAIFJREFUeNplz90OwiAMBWAQpAoyxclkP3je/y0H2AQXz0WT8100rRD6kNI9/cRroemQL3hXhoujZYj4OHoAmBvYGcBISwbWBvfXCrytnIDUQMkbsBpagMA7zhtQdyTFQAmIG7IkYniiZuh3XGsPqoOZkMOJOpAcLqUzNFGGu/57fwc1hgtp0mVSyQAAAABJRU5ErkJggg==') center left no-repeat!important; padding-left: 18px; } .linkify.SoundCloud { 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; padding-left: 18px; } .linkify.audio { 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; padding-left: 18px; } .linkify.LiveLeak { 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; padding-left: 18px; } .linkify.Vocaroo { 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; padding-left: 18px; } .linkify.pastebin { 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; padding-left: 18px; } .linkify.gist { 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; padding-left: 18px; } .linkify.image { 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; padding-left: 18px; } .linkify.InstallGentoo { 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; padding-left: 18px; } /* Gallery */ #a-gallery { position: fixed; top: 0; bottom: 0; left: 0; right: 0; z-index: 30; display: flex; flex-direction: row; background: rgba(0,0,0,0.7); } .gal-viewport { display: flex; align-items: stretch; flex-direction: row; flex: 1 1 auto; } .gal-thumbnails { flex: 0 0 150px; overflow-y: auto; display: flex; flex-direction: column; align-items: stretch; text-align: center; background: rgba(0,0,0,.5); border-left: 1px solid #222; } .gal-hide-thumbnails .gal-thumbnails { display: none; } .gal-thumb img { max-width: 125px; max-height: 125px; height: auto; width: auto; } .gal-thumb { flex: 0 0 auto; padding: 3px; line-height: 0; transition: background .2s linear; } .gal-highlight { background: rgba(0, 190, 255,.8); } .gal-prev { order: 0; border-right: 1px solid #222; } .gal-next { order: 2; border-left: 1px solid #222; } .gal-prev, .gal-next { flex: 0 0 20px; position: relative; cursor: pointer; opacity: 0.7; background-color: rgba(0, 0, 0, 0.3); } .gal-prev:hover, .gal-next:hover { opacity: 1; } .gal-prev::after, .gal-next::after { position: absolute; top: 48.6%; transform: translateY(-50%) display: inline-block; border-top: 11px solid transparent; border-bottom: 11px solid transparent; content: \"\"; } .gal-prev::after { border-right: 12px solid #fff; right: 5px; } .gal-next::after { border-left: 12px solid #fff; right: 3px; } .gal-image { order: 1; flex: 1 0 auto; display: flex; align-items: flex-start; justify-content: space-around; overflow: hidden; /* Flex > Non-Flex child max-width and overflow fix (Firefox only?) */ width: 1%; } :root:not(.gal-fit-height) .gal-image { overflow-y: scroll !important; } :root:not(.gal-fit-width) .gal-image { overflow-x: scroll !important; } .gal-image a { margin: auto; line-height: 0; } .gal-fit-width .gal-image img { max-width: 100%; } .gal-fit-height .gal-image img { /* Chrome doesn't support viewpoint units in calc() http://bugs.chromium.org/168840 \"It looks like the original author of viewport units in WebKit is not coming back to fix this stuff.\" Well, fuck. */ max-height: 95vh; max-height: calc(100vh - 25px); } .gal-buttons { font-size: 2em; margin-right: 10px; top: 5px; } .gal-buttons i { vertical-align: baseline; border-top-width: .4em; border-right-width: .25em; border-left-width: .25em; } .gal-buttons .menu-button { bottom: 2px; color: #ffffff; text-shadow: 0px 0px 1px #000000; } .gal-close { color: #ffffff; text-shadow: 0px 0px 1px #000000; } .gal-buttons, .gal-name, .gal-count { position: fixed; right: 178px; } .gal-hide-thumbnails .gal-buttons, .gal-hide-thumbnails .gal-count, .gal-hide-thumbnails .gal-name { right: 28px; } .gal-name { bottom: 6px; background: rgba(0,0,0,0.6) !important; border-radius: 3px; padding: 1px 5px 2px 5px; text-decoration: none !important; color: white !important; } .gal-name:hover, .gal-close:hover, .gal-buttons .menu-button:hover { color: rgb(95, 95, 101) !important; } .gal-count { bottom: 27px; background: rgba(0,0,0,0.6) !important; border-radius: 3px; padding: 1px 5px 2px 5px; color: #ffffff !important; } :root:not(.gal-fit-width) .gal-name { bottom: 23px !important; } :root:not(.gal-fit-width) .gal-count { bottom: 44px !important; } :root:not(.gal-fit-height):not(.gal-hide-thumbnails) .gal-buttons, :root:not(.gal-fit-height):not(.gal-hide-thumbnails) .gal-name, :root:not(.gal-fit-height):not(.gal-hide-thumbnails) .gal-count { right: 195px !important; } :root.gal-hide-thumbnails:not(.gal-fit-height) .gal-buttons, :root.gal-hide-thumbnails:not(.gal-fit-height) .gal-name, :root.gal-hide-thumbnails:not(.gal-fit-height) .gal-count { right: 44px !important; } @media screen and (resolution: 1dppx) { .fa-bars { font-size: 14px; } #shortcuts .fa-bars { vertical-align: -1px; } }\n/* General */ :root.yotsuba .dialog { background-color: #F0E0D6; border-color: #D9BFB7; } :root.yotsuba .field:focus { border-color: #EA8; } /* Header */ :root.yotsuba #header-bar.dialog { background-color: rgba(240,224,214,0.98); } :root.yotsuba #header-bar, :root.yotsuba #notifications { font-size: 9pt; color: #B86; } :root.yotsuba #board-list a, :root.yotsuba #shortcuts a { color: #800000; } :root.yotsuba.fixed #custom-board-list a.current { border-bottom: 1px solid rgba(178,0,0,0.2); } :root.yotsuba.fixed #custom-board-list .current:hover { border-bottom-color: rgba(255,0,0,0.2); } /* Settings */ :root.yotsuba #fourchanx-settings fieldset { border-color: #D9BFB7; } /* Quote */ :root.yotsuba .backlink.deadlink { color: #00E !important; } :root.yotsuba .inline { border-color: #D9BFB7; background-color: rgba(255, 255, 255, .14); } /* QR */ .yotsuba #dump-list::-webkit-scrollbar-thumb { background-color: #F0E0D6; border-color: #D9BFB7; } :root.yotsuba .qr-preview { background-color: rgba(0, 0, 0, .15); } :root.yotsuba .qr-link { border-color: rgb(225, 209, 199) rgb(225, 209, 199) rgb(210, 194, 184); background: linear-gradient(#FFEFE5, #F0E0D6) repeat scroll 0% 0% transparent; } :root.yotsuba .qr-link:hover { background: #F0E0D6; } /* Menu */ :root.yotsuba #menu { color: #800000; } :root.yotsuba .entry { font-size: 10pt; } :root.yotsuba .focused.entry { background: rgba(255, 255, 255, .33); } /* Watcher Favicon */ :root.yotsuba .watch-thread-link { background-image: url(\"data:image/svg+xml, \"); } /* Board Title */ :root.yotsuba div.boardTitle { font-family: sans-serif !important; text-shadow: 1px 1px 1px rgba(100,0,0,0.6); }\n/* General */ :root.yotsuba-b .dialog { background-color: #D6DAF0; border-color: #B7C5D9; } :root.yotsuba-b .field:focus { border-color: #98E; } /* Header */ :root.yotsuba-b #header-bar.dialog { background-color: rgba(214,218,240,0.98); } :root.yotsuba-b #header-bar, :root.yotsuba-b #notifications { font-size: 9pt; color: #89A; } :root.yotsuba-b #board-list a, :root.yotsuba-b #shortcuts a { color: #34345C; } :root.yotsuba-b.fixed #custom-board-list .current { border-bottom: 1px solid rgba(30, 30, 255, 0.2); } :root.yotsuba-b.fixed #custom-board-list .current:hover { border-bottom-color: rgba(255,0,0,0.2); } /* Settings */ :root.yotsuba-b #fourchanx-settings fieldset { border-color: #B7C5D9; } /* Quote */ :root.yotsuba-b .backlink.deadlink { color: #34345C !important; } :root.yotsuba-b .inline { border-color: #B7C5D9; background-color: rgba(255, 255, 255, .14); } /* QR */ .yotsuba-b #dump-list::-webkit-scrollbar-thumb { background-color: #D6DAF0; border-color: #B7C5D9; } :root.yotsuba-b .qr-preview { background-color: rgba(0, 0, 0, .15); } :root.yotsuba-b .qr-link { border-color: rgb(199, 203, 225) rgb(199, 203, 225) rgb(184, 188, 210); background: linear-gradient(#E5E9FF, #D6DAF0) repeat scroll 0% 0% transparent; } :root.yotsuba-b .qr-link:hover { background: #D9DDF3; } /* Menu */ :root.yotsuba-b #menu { color: #000; } :root.yotsuba-b .entry { font-size: 10pt; } :root.yotsuba-b .focused.entry { background: rgba(255, 255, 255, .33); } /* Watcher Favicon */ :root.yotsuba-b .watch-thread-link { background-image: url(\"data:image/svg+xml, \"); } /* Board Title */ :root.yotsuba-b div.boardTitle { font-family: sans-serif !important; text-shadow: 1px 1px 1px rgba(105,10,15,0.6); }\n/* General */ :root.futaba .dialog { background-color: #F0E0D6; border-color: #D9BFB7; } :root.futaba .field:focus { border-color: #EA8; } /* Header */ :root.futaba #header-bar.dialog { background-color: rgba(240,224,214,0.98); } :root.futaba #header-bar, :root.futaba #notifications { font-size: 11pt; color: #B86; } :root.futaba #header-bar a, :root.futaba #notifications a { color: #800000; } :root.futaba.fixed #custom-board-list a.current { border-bottom: 1px solid rgba(178,0,0,0.2); } :root.futaba.fixed #custom-board-list .current:hover { border-bottom-color: rgba(255,0,0,0.2); } /* Settings */ :root.futaba #fourchanx-settings fieldset { border-color: #D9BFB7; } /* Quote */ :root.futaba .backlink.deadlink { color: #00E !important; } :root.futaba .inline { border-color: #D9BFB7; background-color: rgba(255, 255, 255, .14); } /* QR */ .futaba #dump-list::-webkit-scrollbar-thumb { background-color: #F0E0D6; border-color: #D9BFB7; } :root.futaba .qr-preview { background-color: rgba(0, 0, 0, .15); } :root.futaba .qr-link { border-color: rgb(225, 209, 199) rgb(225, 209, 199) rgb(210, 194, 184); background: linear-gradient(#FFEFE5, #F0E0D6) repeat scroll 0% 0% transparent; } :root.futaba .qr-link:hover { background: #F0E0D6; } /* Menu */ :root.futaba #menu { color: #800000; } :root.futaba .entry { font-size: 12pt; } :root.futaba .focused.entry { background: rgba(255, 255, 255, .33); } /* Watcher Favicon */ :root.futaba .watch-thread-link { background-image: url(\"data:image/svg+xml, \"); }\n/* General */ :root.burichan .dialog { background-color: #D6DAF0; border-color: #B7C5D9; } :root.burichan .field:focus { border-color: #98E; } /* Header */ :root.burichan #header-bar.dialog { background-color: rgba(214,218,240,0.98); } :root.burichan #header-bar, :root.burichan #header-bar #notifications { font-size: 11pt; color: #89A; } :root.burichan #header-bar a, :root.burichan #header-bar #notifications a { color: #34345C; } :root.burichan.fixed #custom-board-list .current { border-bottom: 1px solid rgba(30, 30, 255, 0.2); } :root.burichan.fixed #custom-board-list .current:hover { border-bottom-color: rgba(255,0,0,0.2); } /* Settings */ :root.burichan #fourchanx-settings fieldset { border-color: #B7C5D9; } /* Quote */ :root.burichan .backlink.deadlink { color: #34345C !important; } :root.burichan .inline { border-color: #B7C5D9; background-color: rgba(255, 255, 255, .14); } /* QR */ .burichan #dump-list::-webkit-scrollbar-thumb { background-color: #D6DAF0; border-color: #B7C5D9; } :root.burichan .qr-preview { background-color: rgba(0, 0, 0, .15); } :root.burichan .qr-link { border-color: rgb(199, 203, 225) rgb(199, 203, 225) rgb(184, 188, 210); background: linear-gradient(#E5E9FF, #D6DAF0) repeat scroll 0% 0% transparent; } :root.burichan .qr-link:hover { background: #D9DDF3; } /* Menu */ :root.burichan #menu { color: #000000; } :root.burichan .entry { font-size: 12pt; } :root.burichan .focused.entry { background: rgba(255, 255, 255, .33); } /* Watcher Favicon */ :root.burichan .watch-thread-link { background-image: url(\"data:image/svg+xml, \"); }\n/* General */ :root.tomorrow .dialog { background-color: #282A2E; border-color: #111; } /* Header */ :root.tomorrow #header-bar.dialog { background-color: rgba(40,42,46,0.9); } :root.tomorrow #header-bar, :root.tomorrow #notifications { font-size: 9pt; color: #C5C8C6; } :root.tomorrow #header-bar a, :root.tomorrow #notifications a { color: #81A2BE; } :root.tomorrow.fixed #custom-board-list a.current { border-bottom: 1px solid rgba(83,124,160,0.4); } :root.tomorrow.fixed #custom-board-list .current:hover { border-bottom-color: rgba(95,137,172,0.4); } /* Settings */ :root.tomorrow #fourchanx-settings fieldset { border-color: #111; } /* Quote */ :root.tomorrow .backlink.deadlink { color: #81A2BE !important; } :root.tomorrow .inline { border-color: #111; background-color: rgba(0, 0, 0, .14); } /* QR */ .tomorrow #dump-list::-webkit-scrollbar-thumb { background-color: #282A2E; border-color: #111; } :root.tomorrow .qr-preview { background-color: rgba(255, 255, 255, .15); } :root.tomorrow #qr .field { background-color: rgb(26, 27, 29); color: rgb(197,200,198); border-color: rgb(40, 41, 42); } :root.tomorrow #qr .field:focus { border-color: rgb(129, 162, 190) !important; background-color: rgb(30,32,36); } :root.tomorrow .qr-link { border-color: rgb(25, 27, 31) rgb(25, 27, 31) rgb(10, 12, 16); background: linear-gradient(#37393D, #282A2E) repeat scroll 0% 0% transparent; } :root.tomorrow .qr-link:hover { background: #282A2E; } /* Menu */ :root.tomorrow #menu { color: #C5C8C6; } :root.tomorrow .entry { font-size: 10pt; } :root.tomorrow .focused.entry { background: rgba(0, 0, 0, .33); } /* Watcher Favicon */ :root.tomorrow .watch-thread-link { background-image: url(\"data:image/svg+xml, \"); } /* Board Title */ :root.tomorrow div.boardTitle { font-family: sans-serif !important; text-shadow: 1px 1px 1px rgba(167,170,168,0.6); }\n/* General */ :root.photon .dialog { background-color: #DDD; border-color: #CCC; } :root.photon .field:focus { border-color: #EA8; } /* Header */ :root.photon #header-bar.dialog { background-color: rgba(221,221,221,0.98); } :root.photon #header-bar, :root.photon #notifications { font-size: 9pt; color: #333; } :root.photon #header-bar a, :root.photon #notifications a { color: #FF6600; } :root.photon.fixed #custom-board-list a.current { border-bottom: 1px solid rgba(0,74,153,0.2); } :root.photon.fixed #custom-board-list .current:hover { border-bottom-color: rgba(255,51,0,0.2); } /* Settings */ :root.photon #fourchanx-settings fieldset { border-color: #CCC; } /* Quote */ :root.photon .backlink.deadlink { color: #F60 !important; } :root.photon .inline { border-color: #CCC; background-color: rgba(255, 255, 255, .14); } /* QR */ .photon #dump-list::-webkit-scrollbar-thumb { background-color: #DDD; border-color: #CCC; } :root.photon .qr-preview { background-color: rgba(0, 0, 0, .15); } :root.photon .qr-link { border-color: rgb(206, 206, 206) rgb(206, 206, 206) rgb(191, 191, 191); background: linear-gradient(#ECECEC, #DDD) repeat scroll 0% 0% transparent; } :root.photon .qr-link:hover { background: #DDDDDD; } /* Menu */ :root.photon #menu { color: #333; } :root.photon .entry { font-size: 10pt; } :root.photon .focused.entry { background: rgba(255, 255, 255, .33); } /* Watcher Favicon */ :root.photon .watch-thread-link { background-image: url(\"data:image/svg+xml, \"); } /* Board Title */ :root.photon div.boardTitle { font-family: sans-serif !important; text-shadow: 1px 1px 1px rgba(0,74,153,0.6); }"
+ };
+
+ Main.init();
+
+}).call(this);
diff --git a/builds/xpi/data/greaseshim.js b/builds/xpi/data/greaseshim.js
new file mode 100644
index 000000000..0d89a981f
--- /dev/null
+++ b/builds/xpi/data/greaseshim.js
@@ -0,0 +1,62 @@
+function GM_openInTab(_url) {
+ self.port.emit("GM_openInTab", _url);
+ return; // Should return the Window object
+};
+
+function GM_setValue(_name, _value) {
+ localStorage[_name] = _value;
+ return;
+};
+
+function GM_getValue(_name, _default) {
+ if (localStorage[_name] === null && _default === null) return null;
+ return (localStorage[_name] || _default);
+};
+
+function GM_deleteValue(_name) {
+ localStorage.removeItem(_name);
+ return;
+};
+
+function GM_listValues() {
+ return Object.keys(localStorage);
+};
+
+function GM_setClipboard(_text) {
+ self.port.emit("GM_setClipboard", _text);
+};
+
+//Deprecated
+function GM_log(_message) {
+ console.log(_message);
+ return;
+};
+
+function GM_xmlhttpRequest(_details) {
+ //Ugly hack? Race condition? Memory leak?
+ _onload = _details.onload;
+ _context = _details.context;
+ self.port.emit("GM_xmlhttpRequest", _details);
+};
+
+self.port.on("callback_GM_xmlhttpRequest", function(_response) {
+ _response.context = _context;
+ _onload(_response);
+});
+
+function GM_addStyle(_css) {
+ self.port.emit("GM_addStyle", _css);
+}
+
+var GM_info = new Object();
+GM_info.version = '1.15';
+GM_info.scriptWillUpdate = true;
+
+//To do
+function GM_registerMenuCommand(_caption, _commandFunc, _accessKey) {
+ return;
+}
+
+self.port.on("load-userscript", function(_script) {
+ eval(_script);
+});
diff --git a/builds/xpi/doc/main.md b/builds/xpi/doc/main.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/builds/xpi/icon.png b/builds/xpi/icon.png
new file mode 100755
index 000000000..6b9265ec9
Binary files /dev/null and b/builds/xpi/icon.png differ
diff --git a/builds/xpi/icon64.png b/builds/xpi/icon64.png
new file mode 100755
index 000000000..80b72bf13
Binary files /dev/null and b/builds/xpi/icon64.png differ
diff --git a/builds/xpi/lib/main.js b/builds/xpi/lib/main.js
new file mode 100644
index 000000000..43db1bef7
--- /dev/null
+++ b/builds/xpi/lib/main.js
@@ -0,0 +1,82 @@
+var data = require("sdk/self").data;
+var Request = require("sdk/request").Request;
+var tabs = require("sdk/tabs");
+var system = require("sdk/system");
+if (system.platform !== 'android') {
+ // Clipboard is not supported on Android
+ var clipboard = require("sdk/clipboard");
+}
+var pageMod = require("sdk/page-mod");
+pageMod.PageMod({
+ include: ["*.4chan.org", "*.4cdn.org"],
+ contentScriptFile: data.url("greaseshim.js"),
+ contentScriptWhen: "start",
+ onAttach: function(worker) {
+ worker.port.emit("load-userscript", data.load("4chan-X.user.js"));
+
+ //GM_openInTab
+ worker.port.on("GM_openInTab", function(url) {
+ tabs.open(url);
+ });
+
+ //GM_setClipboard
+ worker.port.on("GM_setClipboard", function(text) {
+ if (system.platform !== 'android') {
+ // Clipboard is not supported on Android
+ clipboard.set(text);
+ }
+ });
+
+ //GM_xmlhttpRequest
+ worker.port.on("GM_xmlhttpRequest", function(details) {
+ request = new Object();
+ request.url = details.url;
+ if (details.headers) {
+ request.headers = details.headers;
+ if (details.headers["Content-Type"]) {request.contentType = details.headers["Content-Type"]};
+ };
+ if (details.data) {request.content = encodeURIComponent(details.data)};
+ if (details.overrideMimeType) {request.overrideMimeType = details.overrideMimeType};
+
+ request.onComplete = function(response) {
+ response.finalUrl = details.url;
+ response.responseText = response.text;
+ for (var headerName in response.headers) {
+ _string = headerName + ": " + response.headers[headerName] + " \n";
+ response.responseHeaders += _string;
+ }
+ response.readyState = 4;
+ worker.port.emit("callback_GM_xmlhttpRequest", response);
+ }
+
+ xhr = Request(request);
+
+ switch(details.method){
+ case "GET":
+ xhr.get();
+ break;
+ case "POST":
+ xhr.post();
+ break;
+ case "HEAD":
+ xhr.head();
+ break;
+ case "PUT":
+ xhr.put();
+ break;
+ default: xhr.get();
+ }
+ });
+
+ //GM_addStyle
+ worker.port.on("GM_addStyle", function(css) {
+ tabs.activeTab.attach({
+ contentScript: "var style = document.createElement('style');" +
+ "style.type = 'text/css';" +
+ "style.innerHTML = '" + css + "';" +
+ "document.head.appendChild(style);"
+ });
+ });
+
+ }
+});
\ No newline at end of file
diff --git a/builds/xpi/package.json b/builds/xpi/package.json
new file mode 100644
index 000000000..00bd4cdce
--- /dev/null
+++ b/builds/xpi/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "4chanx",
+ "title": "4chan X",
+ "id": "72DAF86E-9689-11E3-8BA3-F4B66188709B",
+ "description": "Adds various features to 4chan.",
+ "author": "Spittie",
+ "license": "MIT",
+ "version": "1.3.7"
+}
diff --git a/builds/xpi/test/test-main.js b/builds/xpi/test/test-main.js
new file mode 100644
index 000000000..147f98adf
--- /dev/null
+++ b/builds/xpi/test/test-main.js
@@ -0,0 +1,12 @@
+var main = require("./main");
+
+exports["test main"] = function(assert) {
+ assert.pass("Unit test running!");
+};
+
+exports["test main async"] = function(assert, done) {
+ assert.pass("async Unit test running!");
+ done();
+};
+
+require("sdk/test").run(exports);
diff --git a/src/Archive/Redirect.coffee b/src/Archive/Redirect.coffee
index bc42c6cff..77cb63abf 100755
--- a/src/Archive/Redirect.coffee
+++ b/src/Archive/Redirect.coffee
@@ -24,8 +24,8 @@ Redirect =
archives: [
name: "Foolz"
- boards: ["a", "co", "gd", "jp", "m", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"]
- files: ["a", "gd", "jp", "m", "tg", "vg", "vp", "vr", "wsg"]
+ boards: ["a", "biz","co", "gd", "jp", "m", "sp", "tg", "tv", "v", "vg", "vp", "vr", "wsg"]
+ files: ["a", "biz","gd", "jp", "m", "tg", "vg", "vp", "vr", "wsg"]
data:
domain: "archive.foolz.us"
http: false
@@ -69,7 +69,7 @@ Redirect =
software: "foolfuuka"
,
name: "Love is Over"
- boards: ["d", "i"],
+ boards: ["d", "i"]
files: ["d", "i"]
data:
domain: "loveisover.me"
@@ -112,15 +112,15 @@ Redirect =
software: "fuuka"
,
name: "fgts"
- boards: ["soc"]
- files: ["soc"]
+ boards: ["r", "soc"]
+ files: ["r", "soc"]
data:
- domain: "fgts.eu"
+ domain: "fgst.eu"
http: true
https: true
software: "foolfuuka"
,
- name: "maware"
+ name: "maware"
boards: ["t"]
files: ["t"]
data:
@@ -137,8 +137,8 @@ Redirect =
software: "foolfuuka"
,
name: "Foolz Beta"
- boards: ["a", "co", "d", "gd", "h", "jp", "m", "mlp", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
- files: ["a", "d", "gd", "h", "jp", "m", "tg", "u", "vg", "vp", "vr", "wsg"]
+ boards: ["a", "co", "gd", "jp", "m", "s4s", "sp", "tg", "tv", "u", "v", "vg", "vp", "vr", "wsg"],
+ files: ["a", "gd", "jp", "m", "s4s", "tg", "u", "vg", "vp", "vr", "wsg"]
data:
domain: "beta.foolz.us"
http: true
diff --git a/src/General/Config.coffee b/src/General/Config.coffee
index 2b325ce71..3b89daf0c 100755
--- a/src/General/Config.coffee
+++ b/src/General/Config.coffee
@@ -295,6 +295,10 @@ Config =
false
'Position of the QR\'s Dump List.'
]
+ 'Auto-load captcha': [
+ false
+ 'Automatically load the captcha when you open a thread'
+ ]
'Quote Links':
'Quote Backlinks': [
diff --git a/src/General/css/style.css b/src/General/css/style.css
index 223768bbe..7e37887ef 100755
--- a/src/General/css/style.css
+++ b/src/General/css/style.css
@@ -803,6 +803,7 @@ span.hide-announcement {
}
#qr select,
#dump-button,
+#url-button,
.remove,
.captcha-img {
cursor: pointer;
@@ -857,6 +858,14 @@ span.hide-announcement {
padding: 1px 0px 2px;
opacity: 0.6;
}
+#url-button {
+ width: 10%;
+ margin: 0;
+ margin-right: 4px;
+ font: 13px sans-serif;
+ padding: 1px 0px 2px;
+ opacity: 0.6;
+}
.persona .field:not(#dump) {
width: 95px;
min-width: 33.3%;
@@ -884,7 +893,7 @@ input.field.tripped:not(:hover):not(:focus) {
min-height: 59px;
min-width: 302px;
}
-.captcha-input {
+.captcha-input{
width: 100%;
margin: 1px 0 0;
}
@@ -961,7 +970,7 @@ input#qr-filename:not(.edit) {
right: 0px;
}
#qr-filerm {
- margin-right: 2px;
+ margin-right: 3px;
z-index: 2;
}
#file-n-submit {
diff --git a/src/General/html/Features/QuickReply.html b/src/General/html/Features/QuickReply.html
index 231700e89..a885db216 100755
--- a/src/General/html/Features/QuickReply.html
+++ b/src/General/html/Features/QuickReply.html
@@ -30,6 +30,8 @@
Spoiler
+ \uf0c1
+ Post from URL
+
Dump
\uf00d
@@ -43,4 +45,3 @@
-
diff --git a/src/General/html/Settings/Advanced.html b/src/General/html/Settings/Advanced.html
index 165781d5d..e54e95680 100755
--- a/src/General/html/Settings/Advanced.html
+++ b/src/General/html/Settings/Advanced.html
@@ -89,6 +89,7 @@
Mayhem
4chanJS
Original
+ Metro
diff --git a/src/General/img/changelog/1.1.18.png b/src/General/img/changelog/1.1.18.png
old mode 100755
new mode 100644
index f0660b621..1c122516d
Binary files a/src/General/img/changelog/1.1.18.png and b/src/General/img/changelog/1.1.18.png differ
diff --git a/src/General/img/changelog/1.2.0.png b/src/General/img/changelog/1.2.0.png
old mode 100755
new mode 100644
index 25a6a3de3..df5fb1cef
Binary files a/src/General/img/changelog/1.2.0.png and b/src/General/img/changelog/1.2.0.png differ
diff --git a/src/General/img/changelog/1.2.28-2.png b/src/General/img/changelog/1.2.28-2.png
index ba53d5e10..b72994a64 100644
Binary files a/src/General/img/changelog/1.2.28-2.png and b/src/General/img/changelog/1.2.28-2.png differ
diff --git a/src/General/img/changelog/1.2.28.png b/src/General/img/changelog/1.2.28.png
index a368c0298..66d626daf 100644
Binary files a/src/General/img/changelog/1.2.28.png and b/src/General/img/changelog/1.2.28.png differ
diff --git a/src/General/img/changelog/1.2.31.png b/src/General/img/changelog/1.2.31.png
index 57ae022b9..da7a95a4b 100644
Binary files a/src/General/img/changelog/1.2.31.png and b/src/General/img/changelog/1.2.31.png differ
diff --git a/src/General/img/changelog/1.3.6.gif b/src/General/img/changelog/1.3.6.gif
new file mode 100644
index 000000000..3b663b752
Binary files /dev/null and b/src/General/img/changelog/1.3.6.gif differ
diff --git a/src/General/img/emoji/SS-sage.png b/src/General/img/emoji/SS-sage.png
old mode 100755
new mode 100644
index 942c87624..5a2df3ff6
Binary files a/src/General/img/emoji/SS-sage.png and b/src/General/img/emoji/SS-sage.png differ
diff --git a/src/General/img/emoji/arch.png b/src/General/img/emoji/arch.png
old mode 100755
new mode 100644
index ba61a4a62..74e4d5fea
Binary files a/src/General/img/emoji/arch.png and b/src/General/img/emoji/arch.png differ
diff --git a/src/General/img/emoji/centos.png b/src/General/img/emoji/centos.png
old mode 100755
new mode 100644
index 00e0070f2..390bd83a0
Binary files a/src/General/img/emoji/centos.png and b/src/General/img/emoji/centos.png differ
diff --git a/src/General/img/emoji/elementary.png b/src/General/img/emoji/elementary.png
index ad249d03a..9174e3cd1 100644
Binary files a/src/General/img/emoji/elementary.png and b/src/General/img/emoji/elementary.png differ
diff --git a/src/General/img/emoji/fedora.png b/src/General/img/emoji/fedora.png
old mode 100755
new mode 100644
index f09c82325..4a8652c3a
Binary files a/src/General/img/emoji/fedora.png and b/src/General/img/emoji/fedora.png differ
diff --git a/src/General/img/emoji/freebsd.png b/src/General/img/emoji/freebsd.png
old mode 100755
new mode 100644
index b4a16f12e..ac56b271f
Binary files a/src/General/img/emoji/freebsd.png and b/src/General/img/emoji/freebsd.png differ
diff --git a/src/General/img/emoji/gentoo.png b/src/General/img/emoji/gentoo.png
old mode 100755
new mode 100644
index ffed8d875..4a4830171
Binary files a/src/General/img/emoji/gentoo.png and b/src/General/img/emoji/gentoo.png differ
diff --git a/src/General/img/emoji/gnu.png b/src/General/img/emoji/gnu.png
old mode 100755
new mode 100644
index f5cae1d67..110380a65
Binary files a/src/General/img/emoji/gnu.png and b/src/General/img/emoji/gnu.png differ
diff --git a/src/General/img/emoji/madotsuki.png b/src/General/img/emoji/madotsuki.png
old mode 100755
new mode 100644
index cbee19fd8..c558c56ad
Binary files a/src/General/img/emoji/madotsuki.png and b/src/General/img/emoji/madotsuki.png differ
diff --git a/src/General/img/emoji/mint.png b/src/General/img/emoji/mint.png
old mode 100755
new mode 100644
index 26306ee2c..16306bac6
Binary files a/src/General/img/emoji/mint.png and b/src/General/img/emoji/mint.png differ
diff --git a/src/General/img/emoji/opensuse.png b/src/General/img/emoji/opensuse.png
new file mode 100644
index 000000000..848cbac9d
Binary files /dev/null and b/src/General/img/emoji/opensuse.png differ
diff --git a/src/General/img/emoji/ponyo.png b/src/General/img/emoji/ponyo.png
old mode 100755
new mode 100644
index 0144270cc..1844d882f
Binary files a/src/General/img/emoji/ponyo.png and b/src/General/img/emoji/ponyo.png differ
diff --git a/src/General/img/emoji/rabite.png b/src/General/img/emoji/rabite.png
old mode 100755
new mode 100644
index 5485cbcf0..5b45efa1f
Binary files a/src/General/img/emoji/rabite.png and b/src/General/img/emoji/rabite.png differ
diff --git a/src/General/img/emoji/sabayon.png b/src/General/img/emoji/sabayon.png
old mode 100755
new mode 100644
index 92cd7860e..a940aaf83
Binary files a/src/General/img/emoji/sabayon.png and b/src/General/img/emoji/sabayon.png differ
diff --git a/src/General/img/emoji/trisquel.png b/src/General/img/emoji/trisquel.png
old mode 100755
new mode 100644
index 0eecdeb67..582aa1254
Binary files a/src/General/img/emoji/trisquel.png and b/src/General/img/emoji/trisquel.png differ
diff --git a/src/General/img/emoji/ubuntu.png b/src/General/img/emoji/ubuntu.png
old mode 100755
new mode 100644
index 6873d9d93..579057086
Binary files a/src/General/img/emoji/ubuntu.png and b/src/General/img/emoji/ubuntu.png differ
diff --git a/src/General/img/favicons/Metro/readNSFW.png b/src/General/img/favicons/Metro/readNSFW.png
new file mode 100644
index 000000000..caf76752b
Binary files /dev/null and b/src/General/img/favicons/Metro/readNSFW.png differ
diff --git a/src/General/img/favicons/Metro/readSFW.png b/src/General/img/favicons/Metro/readSFW.png
new file mode 100644
index 000000000..ffa080694
Binary files /dev/null and b/src/General/img/favicons/Metro/readSFW.png differ
diff --git a/src/General/img/favicons/Metro/unreadDead.png b/src/General/img/favicons/Metro/unreadDead.png
new file mode 100644
index 000000000..8e5e671fa
Binary files /dev/null and b/src/General/img/favicons/Metro/unreadDead.png differ
diff --git a/src/General/img/favicons/Metro/unreadDeadY.png b/src/General/img/favicons/Metro/unreadDeadY.png
new file mode 100644
index 000000000..458ec9cdf
Binary files /dev/null and b/src/General/img/favicons/Metro/unreadDeadY.png differ
diff --git a/src/General/img/favicons/Metro/unreadNSFW.png b/src/General/img/favicons/Metro/unreadNSFW.png
new file mode 100644
index 000000000..1e5727586
Binary files /dev/null and b/src/General/img/favicons/Metro/unreadNSFW.png differ
diff --git a/src/General/img/favicons/Metro/unreadNSFWY.png b/src/General/img/favicons/Metro/unreadNSFWY.png
new file mode 100644
index 000000000..5c34ec8a0
Binary files /dev/null and b/src/General/img/favicons/Metro/unreadNSFWY.png differ
diff --git a/src/General/img/favicons/Metro/unreadSFW.png b/src/General/img/favicons/Metro/unreadSFW.png
new file mode 100644
index 000000000..4aef3cd06
Binary files /dev/null and b/src/General/img/favicons/Metro/unreadSFW.png differ
diff --git a/src/General/img/favicons/Metro/unreadSFWY.png b/src/General/img/favicons/Metro/unreadSFWY.png
new file mode 100644
index 000000000..66ed2c844
Binary files /dev/null and b/src/General/img/favicons/Metro/unreadSFWY.png differ
diff --git a/src/General/img/links/gfycat.png b/src/General/img/links/gfycat.png
new file mode 100644
index 000000000..b4c16243d
Binary files /dev/null and b/src/General/img/links/gfycat.png differ
diff --git a/src/General/img/links/gist.png b/src/General/img/links/gist.png
old mode 100755
new mode 100644
index 9abe604d0..3cd5abffd
Binary files a/src/General/img/links/gist.png and b/src/General/img/links/gist.png differ
diff --git a/src/General/img/links/installgentoo.png b/src/General/img/links/installgentoo.png
old mode 100755
new mode 100644
index 2f10394a4..793076742
Binary files a/src/General/img/links/installgentoo.png and b/src/General/img/links/installgentoo.png differ
diff --git a/src/General/img/links/liveleak.png b/src/General/img/links/liveleak.png
old mode 100755
new mode 100644
index f5b2461d9..122650ba3
Binary files a/src/General/img/links/liveleak.png and b/src/General/img/links/liveleak.png differ
diff --git a/src/General/img/links/pastebin.png b/src/General/img/links/pastebin.png
old mode 100755
new mode 100644
index cd1996440..caf3725cd
Binary files a/src/General/img/links/pastebin.png and b/src/General/img/links/pastebin.png differ
diff --git a/src/General/img/links/vimeo.png b/src/General/img/links/vimeo.png
old mode 100755
new mode 100644
index 8eb9413f8..d5f096abe
Binary files a/src/General/img/links/vimeo.png and b/src/General/img/links/vimeo.png differ
diff --git a/src/General/meta/manifest.json b/src/General/meta/manifest.json
index d1c79c7a7..cb022ecea 100755
--- a/src/General/meta/manifest.json
+++ b/src/General/meta/manifest.json
@@ -17,6 +17,8 @@
"homepage_url": "<%= meta.page %>",
"minimum_chrome_version": "<%= meta.min.chrome %>",
"permissions": [
- "storage"
+ "storage",
+ "http://*/",
+ "https://*/"
]
}
diff --git a/src/General/meta/metadata.js b/src/General/meta/metadata.js
index 9dac93a7e..ef89cbc37 100755
--- a/src/General/meta/metadata.js
+++ b/src/General/meta/metadata.js
@@ -16,6 +16,7 @@
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM_openInTab
+// @grant GM_xmlhttpRequest
// @run-at document-start
// @updateURL <%= meta.repo %>raw/stable/builds/<%= meta.files.metajs %>
// @downloadURL <%= meta.repo %>raw/stable/builds/<%= meta.files.userjs %>
diff --git a/src/Linkification/Linkify.coffee b/src/Linkification/Linkify.coffee
index 52d241cdb..fc29bc4b6 100755
--- a/src/Linkification/Linkify.coffee
+++ b/src/Linkification/Linkify.coffee
@@ -284,6 +284,12 @@ Linkify =
el: (a) ->
$.el 'iframe',
src: "http://paste.installgentoo.com/view/embed/#{a.dataset.uid}"
+
+ Twitter:
+ regExp: /.*twitter.com\/(.+\/status\/\d+)/
+ el: (a) ->
+ $.el 'iframe',
+ src: "https://twitframe.com/show?url=https://twitter.com/#{a.dataset.uid}"
LiveLeak:
regExp: /.*(?:liveleak.com\/view.+i=)([0-9a-z_]+)/
@@ -334,6 +340,12 @@ Linkify =
div = $.el 'iframe',
src: "http://pastebin.com/embed_iframe.php?i=#{a.dataset.uid}"
+ gfycat:
+ regExp: /.*gfycat.com\/(?:iframe\/)?(\S*)/
+ el: (a) ->
+ div = $.el 'iframe',
+ src: "http://gfycat.com/iframe/#{a.dataset.uid}"
+
SoundCloud:
regExp: /.*(?:soundcloud.com\/|snd.sc\/)([^#\&\?]*).*/
style: 'height: auto; width: 500px; display: inline-block;'
diff --git a/src/Monitoring/Favicon.coffee b/src/Monitoring/Favicon.coffee
index 126a7a9a5..ff25eab64 100755
--- a/src/Monitoring/Favicon.coffee
+++ b/src/Monitoring/Favicon.coffee
@@ -41,6 +41,14 @@ Favicon =
'<%= grunt.file.read("src/General/img/favicons/Original/unreadNSFW.png", {encoding: "base64"}) %>'
'<%= grunt.file.read("src/General/img/favicons/Original/unreadNSFWY.png", {encoding: "base64"}) %>'
]
+ 'Metro': [
+ '<%= grunt.file.read("src/General/img/favicons/Metro/unreadDead.png", {encoding: "base64"}) %>'
+ '<%= grunt.file.read("src/General/img/favicons/Metro/unreadDeadY.png", {encoding: "base64"}) %>'
+ '<%= grunt.file.read("src/General/img/favicons/Metro/unreadSFW.png", {encoding: "base64"}) %>'
+ '<%= grunt.file.read("src/General/img/favicons/Metro/unreadSFWY.png", {encoding: "base64"}) %>'
+ '<%= grunt.file.read("src/General/img/favicons/Metro/unreadNSFW.png", {encoding: "base64"}) %>'
+ '<%= grunt.file.read("src/General/img/favicons/Metro/unreadNSFWY.png", {encoding: "base64"}) %>'
+ ]
}[Conf['favicon']]
f = Favicon
@@ -48,9 +56,10 @@ Favicon =
i = 0
while items[i]
items[i] = t + items[i++]
+
[f.unreadDead, funreadDeadY, f.unreadSFW, f.unreadSFWY, f.unreadNSFW, f.unreadNSFWY] = items
f.update()
-
+
update: ->
if @SFW
@unread = @unreadSFW
diff --git a/src/Posting/QR.captcha.coffee b/src/Posting/QR.captcha.coffee
index 24ad74f48..2e152b730 100644
--- a/src/Posting/QR.captcha.coffee
+++ b/src/Posting/QR.captcha.coffee
@@ -7,16 +7,19 @@ QR.captcha =
imgContainer = $.el 'div',
className: 'captcha-img'
title: 'Reload reCAPTCHA'
- innerHTML: ' '
+ innerHTML: ' '
hidden: true
+
input = $.el 'input',
className: 'captcha-input field'
title: 'Verification'
placeholder: 'Focus to load reCAPTCHA'
autocomplete: 'off'
spellcheck: false
+ tabIndex: 45
+
@nodes =
- img: imgContainer.firstChild
+ img: $ 'img', imgContainer
input: input
$.on input, 'focus', @setup
@@ -26,13 +29,14 @@ QR.captcha =
$.addClass QR.nodes.el, 'has-captcha'
$.after QR.nodes.com.parentNode, [imgContainer, input]
-
+
@setupObserver = new MutationObserver @afterSetup
@setupObserver.observe container, childList: true
+
+ @setup() if Conf['Auto-load captcha']
@afterSetup() # reCAPTCHA might have loaded before the QR.
- setup: ->
- $.globalEval 'loadRecaptcha()'
+ setup: -> $.globalEval 'loadRecaptcha()'
afterSetup: ->
return unless challenge = $.id 'recaptcha_challenge_field_holder'
@@ -45,7 +49,7 @@ QR.captcha =
$.off window, 'captcha:timeout', setLifetime
{img, input} = QR.captcha.nodes
- img.parentNode.hidden = false
+ img.parentNode.parentNode.hidden = false
$.off input, 'focus', QR.captcha.setup
$.on input, 'keydown', QR.captcha.keydown.bind QR.captcha
$.on img.parentNode, 'click', QR.captcha.reload.bind QR.captcha
@@ -90,6 +94,7 @@ QR.captcha =
$.set 'captchas', @captchas
clear: ->
+ return unless @captchas.length
now = Date.now()
for captcha, i in @captchas
break if captcha.timeout > now
@@ -109,7 +114,7 @@ QR.captcha =
@clear()
count: ->
- count = @captchas.length
+ count = if @captchas then @captchas.length else 0
@nodes.input.placeholder = switch count
when 0
'Verification (Shift + Enter to cache)'
diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee
index 7f4ddc753..3753fd1e4 100644
--- a/src/Posting/QR.coffee
+++ b/src/Posting/QR.coffee
@@ -112,11 +112,8 @@ QR =
QR.cooldown.auto = false
QR.status()
- focusin: ->
- $.addClass QR.nodes.el, 'focus'
-
- focusout: ->
- $.rmClass QR.nodes.el, 'focus'
+ focusin: -> $.addClass QR.nodes.el, 'focus'
+ focusout: -> $.rmClass QR.nodes.el, 'focus'
hide: ->
d.activeElement.blur()
@@ -271,6 +268,69 @@ QR =
QR.open()
QR.handleFiles files
$.addClass QR.nodes.el, 'dump'
+
+ handleBlob: (blob) ->
+ return if blob.type is null
+ QR.error "Unsupported file type."
+ return unless blob.type in QR.mimeTypes
+ QR.error "Unsupported file type."
+ QR.handleFiles([blob])
+
+ handleUrl: ->
+ url = prompt("Insert an url:")
+ return if url is null
+ <% if (type === 'crx') { %>
+ xhr = new XMLHttpRequest();
+ xhr.open('GET', url, true)
+ xhr.responseType = 'blob'
+ xhr.onload = (e) ->
+ if @readyState is @DONE && xhr.status is 200
+ urlBlob = new Blob([@response], {type : @getResponseHeader('content-type')})
+ urlBlob.name = url.substr(url.lastIndexOf('/')+1, url.length)
+ QR.handleBlob(urlBlob)
+ return
+ else
+ QR.error "Can't load image."
+ return
+
+ xhr.onerror = (e) ->
+ QR.error "Can't load image."
+ return
+
+ xhr.send()
+ return
+ <% } %>
+
+ <% if (type === 'userscript') { %>
+ GM_xmlhttpRequest {
+ method: "GET",
+ url: url,
+ overrideMimeType: "text/plain; charset=x-user-defined",
+ onload: (xhr) ->
+ r = xhr.responseText
+ data = new Uint8Array(r.length)
+ i = 0
+ while i < r.length
+ data[i] = r.charCodeAt(i)
+ i++
+ #QUALITY coding at work
+ header = xhr.responseHeaders
+ start = header.indexOf("Content-Type: ") + 14
+ end = header.substr(start, header.length).indexOf("\n") - 1
+ mime = header.substr(start, end)
+ return if mime is null
+
+ urlBlob = new Blob([data], {type: mime})
+
+ urlBlob.name = url.substr(url.lastIndexOf('/')+1, url.length)
+ QR.handleBlob(urlBlob)
+ return
+
+ onerror: (xhr) ->
+ QR.error "Can't load image."
+ }
+ return
+ <% } %>
handleFiles: (files) ->
if @ isnt QR # file input
@@ -349,6 +409,7 @@ QR =
close: '.close'
form: 'form'
dumpButton: '#dump-button'
+ urlButton: '#url-button'
name: '[data-name=name]'
email: '[data-name=email]'
sub: '[data-name=sub]'
@@ -419,6 +480,7 @@ QR =
$.on nodes.autohide, 'change', QR.toggleHide
$.on nodes.close, 'click', QR.close
$.on nodes.dumpButton, 'click', -> nodes.el.classList.toggle 'dump'
+ $.on nodes.urlButton, 'click', QR.handleUrl
$.on nodes.addPost, 'click', -> new QR.post true
$.on nodes.form, 'submit', QR.submit
$.on nodes.filename, 'blur', -> $.rmClass @, 'edit'
diff --git a/src/Posting/QR.post.coffee b/src/Posting/QR.post.coffee
index bf7fe7bf3..272a144e3 100644
--- a/src/Posting/QR.post.coffee
+++ b/src/Posting/QR.post.coffee
@@ -266,4 +266,4 @@ QR.post = class
(if oldIndex < newIndex then $.after else $.before) @, el
post = QR.posts.splice(oldIndex, 1)[0]
QR.posts.splice newIndex, 0, post
- QR.status()
\ No newline at end of file
+ QR.status()