diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c4f05711..0b265f2df 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### v1.8.9.6 +*2014-08-12* + **ccd0** - 4chan update: Indicate death of threads with delayed pruning on /a/ and /v/. diff --git a/LICENSE b/LICENSE index 4f8c1674a..e8b226c39 100755 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* 4chan X - Version 1.8.9.5 +* 4chan X - Version 1.8.9.6 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE diff --git a/builds/4chan-X-beta.crx b/builds/4chan-X-beta.crx index 667e77854..bc582e476 100644 Binary files a/builds/4chan-X-beta.crx and b/builds/4chan-X-beta.crx differ diff --git a/builds/4chan-X-beta.meta.js b/builds/4chan-X-beta.meta.js index b13936f7e..421502e92 100644 --- a/builds/4chan-X-beta.meta.js +++ b/builds/4chan-X-beta.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.8.9.5 +// @version 1.8.9.6 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X-beta.user.js b/builds/4chan-X-beta.user.js index d9287a532..bf15acc72 100644 --- a/builds/4chan-X-beta.user.js +++ b/builds/4chan-X-beta.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X -// @version 1.8.9.5 +// @version 1.8.9.6 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -24,7 +24,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.8.9.5 +* 4chan X - Version 1.8.9.6 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -380,7 +380,7 @@ doc = d.documentElement; g = { - VERSION: '1.8.9.5', + VERSION: '1.8.9.6', NAMESPACE: '4chan X.', NAME: '4chan X', FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions', @@ -9995,7 +9995,11 @@ $.on(window, 'online offline', ThreadUpdater.cb.online); $.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost); $.on(d, 'visibilitychange', ThreadUpdater.cb.visibility); - return ThreadUpdater.cb.online(); + if (g.DEAD) { + return ThreadUpdater.set('status', 'Archived', 'warning'); + } else { + return ThreadUpdater.cb.online(); + } }, /* @@ -10005,6 +10009,9 @@ 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 (g.DEAD) { + return; + } if (ThreadUpdater.online = navigator.onLine) { ThreadUpdater.outdateCount = 0; ThreadUpdater.setInterval(); @@ -10070,20 +10077,19 @@ req = ThreadUpdater.req; switch (req.status) { case 200: - g.DEAD = false; + g.DEAD = !!+req.response.posts[0].archived; ThreadUpdater.parse(req.response.posts); - ThreadUpdater.setInterval(); + if (g.DEAD) { + ThreadUpdater.set('status', 'Archived', 'warning'); + ThreadUpdater.kill(); + } else { + 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, - threadID: ThreadUpdater.thread.fullID - }); + ThreadUpdater.kill(); break; default: ThreadUpdater.outdateCount++; @@ -10096,6 +10102,15 @@ } } }, + kill: function() { + ThreadUpdater.set('timer', null); + clearTimeout(ThreadUpdater.timeoutID); + ThreadUpdater.thread.kill(); + return $.event('ThreadUpdate', { + 404: true, + threadID: ThreadUpdater.thread.fullID + }); + }, setInterval: function() { var cur, i, j, limit; i = ThreadUpdater.interval + 1; @@ -12742,7 +12757,7 @@ className: 'dialog' }); $.extend(dialog, { - innerHTML: "
" + innerHTML: "
" }); $.on($('.export', Settings.dialog), 'click', Settings["export"]); $.on($('.import', Settings.dialog), 'click', Settings["import"]); @@ -13549,18 +13564,19 @@ } }, initThread: function() { - var board, err, errors, postRoot, posts, thread, threadRoot, threads, _i, _j, _len, _len1, _ref, _ref1; + var board, err, errors, postRoot, posts, thread, threadRoot, threads, _i, _j, _len, _len1, _ref, _ref1, _ref2; + g.DEAD = !!((_ref = $('.closed')) != null ? _ref.textContent.match(/Thread archived/) : void 0); if (board = $('.board')) { threads = []; posts = []; - _ref = $$('.board > .thread', board); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - threadRoot = _ref[_i]; + _ref1 = $$('.board > .thread', board); + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + threadRoot = _ref1[_i]; thread = new Thread(+threadRoot.id.slice(1), g.BOARD); threads.push(thread); - _ref1 = $$('.thread > .postContainer', threadRoot); - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - postRoot = _ref1[_j]; + _ref2 = $$('.thread > .postContainer', threadRoot); + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + postRoot = _ref2[_j]; try { posts.push(new Post(postRoot, thread, g.BOARD)); } catch (_error) { diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx index b0f06132a..0dec4f2da 100644 Binary files a/builds/4chan-X-noupdate.crx and b/builds/4chan-X-noupdate.crx differ diff --git a/builds/4chan-X-noupdate.user.js b/builds/4chan-X-noupdate.user.js index 52cf6f725..f929f014f 100644 --- a/builds/4chan-X-noupdate.user.js +++ b/builds/4chan-X-noupdate.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X -// @version 1.8.9.5 +// @version 1.8.9.6 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -23,7 +23,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.8.9.5 +* 4chan X - Version 1.8.9.6 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -379,7 +379,7 @@ doc = d.documentElement; g = { - VERSION: '1.8.9.5', + VERSION: '1.8.9.6', NAMESPACE: '4chan X.', NAME: '4chan X', FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions', @@ -9994,7 +9994,11 @@ $.on(window, 'online offline', ThreadUpdater.cb.online); $.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost); $.on(d, 'visibilitychange', ThreadUpdater.cb.visibility); - return ThreadUpdater.cb.online(); + if (g.DEAD) { + return ThreadUpdater.set('status', 'Archived', 'warning'); + } else { + return ThreadUpdater.cb.online(); + } }, /* @@ -10004,6 +10008,9 @@ 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 (g.DEAD) { + return; + } if (ThreadUpdater.online = navigator.onLine) { ThreadUpdater.outdateCount = 0; ThreadUpdater.setInterval(); @@ -10069,20 +10076,19 @@ req = ThreadUpdater.req; switch (req.status) { case 200: - g.DEAD = false; + g.DEAD = !!+req.response.posts[0].archived; ThreadUpdater.parse(req.response.posts); - ThreadUpdater.setInterval(); + if (g.DEAD) { + ThreadUpdater.set('status', 'Archived', 'warning'); + ThreadUpdater.kill(); + } else { + 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, - threadID: ThreadUpdater.thread.fullID - }); + ThreadUpdater.kill(); break; default: ThreadUpdater.outdateCount++; @@ -10095,6 +10101,15 @@ } } }, + kill: function() { + ThreadUpdater.set('timer', null); + clearTimeout(ThreadUpdater.timeoutID); + ThreadUpdater.thread.kill(); + return $.event('ThreadUpdate', { + 404: true, + threadID: ThreadUpdater.thread.fullID + }); + }, setInterval: function() { var cur, i, j, limit; i = ThreadUpdater.interval + 1; @@ -12741,7 +12756,7 @@ className: 'dialog' }); $.extend(dialog, { - innerHTML: "
" + innerHTML: "
" }); $.on($('.export', Settings.dialog), 'click', Settings["export"]); $.on($('.import', Settings.dialog), 'click', Settings["import"]); @@ -13548,18 +13563,19 @@ } }, initThread: function() { - var board, err, errors, postRoot, posts, thread, threadRoot, threads, _i, _j, _len, _len1, _ref, _ref1; + var board, err, errors, postRoot, posts, thread, threadRoot, threads, _i, _j, _len, _len1, _ref, _ref1, _ref2; + g.DEAD = !!((_ref = $('.closed')) != null ? _ref.textContent.match(/Thread archived/) : void 0); if (board = $('.board')) { threads = []; posts = []; - _ref = $$('.board > .thread', board); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - threadRoot = _ref[_i]; + _ref1 = $$('.board > .thread', board); + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + threadRoot = _ref1[_i]; thread = new Thread(+threadRoot.id.slice(1), g.BOARD); threads.push(thread); - _ref1 = $$('.thread > .postContainer', threadRoot); - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - postRoot = _ref1[_j]; + _ref2 = $$('.thread > .postContainer', threadRoot); + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + postRoot = _ref2[_j]; try { posts.push(new Post(postRoot, thread, g.BOARD)); } catch (_error) { diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx index ff1c21d40..4cc72c130 100644 Binary files a/builds/4chan-X.crx and b/builds/4chan-X.crx differ diff --git a/builds/4chan-X.meta.js b/builds/4chan-X.meta.js index 7a6a028d8..d9ac877ed 100644 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.8.9.5 +// @version 1.8.9.6 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 8d75a1ed5..c4670aedb 100644 --- a/builds/4chan-X.user.js +++ b/builds/4chan-X.user.js @@ -1,7 +1,7 @@ // Generated by CoffeeScript // ==UserScript== // @name 4chan X -// @version 1.8.9.5 +// @version 1.8.9.6 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -24,7 +24,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.8.9.5 +* 4chan X - Version 1.8.9.6 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -380,7 +380,7 @@ doc = d.documentElement; g = { - VERSION: '1.8.9.5', + VERSION: '1.8.9.6', NAMESPACE: '4chan X.', NAME: '4chan X', FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions', @@ -9995,7 +9995,11 @@ $.on(window, 'online offline', ThreadUpdater.cb.online); $.on(d, 'QRPostSuccessful', ThreadUpdater.cb.checkpost); $.on(d, 'visibilitychange', ThreadUpdater.cb.visibility); - return ThreadUpdater.cb.online(); + if (g.DEAD) { + return ThreadUpdater.set('status', 'Archived', 'warning'); + } else { + return ThreadUpdater.cb.online(); + } }, /* @@ -10005,6 +10009,9 @@ 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 (g.DEAD) { + return; + } if (ThreadUpdater.online = navigator.onLine) { ThreadUpdater.outdateCount = 0; ThreadUpdater.setInterval(); @@ -10070,20 +10077,19 @@ req = ThreadUpdater.req; switch (req.status) { case 200: - g.DEAD = false; + g.DEAD = !!+req.response.posts[0].archived; ThreadUpdater.parse(req.response.posts); - ThreadUpdater.setInterval(); + if (g.DEAD) { + ThreadUpdater.set('status', 'Archived', 'warning'); + ThreadUpdater.kill(); + } else { + 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, - threadID: ThreadUpdater.thread.fullID - }); + ThreadUpdater.kill(); break; default: ThreadUpdater.outdateCount++; @@ -10096,6 +10102,15 @@ } } }, + kill: function() { + ThreadUpdater.set('timer', null); + clearTimeout(ThreadUpdater.timeoutID); + ThreadUpdater.thread.kill(); + return $.event('ThreadUpdate', { + 404: true, + threadID: ThreadUpdater.thread.fullID + }); + }, setInterval: function() { var cur, i, j, limit; i = ThreadUpdater.interval + 1; @@ -12742,7 +12757,7 @@ className: 'dialog' }); $.extend(dialog, { - innerHTML: "
" + innerHTML: "
" }); $.on($('.export', Settings.dialog), 'click', Settings["export"]); $.on($('.import', Settings.dialog), 'click', Settings["import"]); @@ -13549,18 +13564,19 @@ } }, initThread: function() { - var board, err, errors, postRoot, posts, thread, threadRoot, threads, _i, _j, _len, _len1, _ref, _ref1; + var board, err, errors, postRoot, posts, thread, threadRoot, threads, _i, _j, _len, _len1, _ref, _ref1, _ref2; + g.DEAD = !!((_ref = $('.closed')) != null ? _ref.textContent.match(/Thread archived/) : void 0); if (board = $('.board')) { threads = []; posts = []; - _ref = $$('.board > .thread', board); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - threadRoot = _ref[_i]; + _ref1 = $$('.board > .thread', board); + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + threadRoot = _ref1[_i]; thread = new Thread(+threadRoot.id.slice(1), g.BOARD); threads.push(thread); - _ref1 = $$('.thread > .postContainer', threadRoot); - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - postRoot = _ref1[_j]; + _ref2 = $$('.thread > .postContainer', threadRoot); + for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { + postRoot = _ref2[_j]; try { posts.push(new Post(postRoot, thread, g.BOARD)); } catch (_error) { diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip index d86812d0d..37ff84866 100644 Binary files a/builds/4chan-X.zip and b/builds/4chan-X.zip differ diff --git a/builds/updates-beta.xml b/builds/updates-beta.xml index 65e0f09a1..0ebcc6ddf 100644 --- a/builds/updates-beta.xml +++ b/builds/updates-beta.xml @@ -1,7 +1,7 @@ - + diff --git a/builds/updates.xml b/builds/updates.xml index 773c802b0..7fde32d15 100644 --- a/builds/updates.xml +++ b/builds/updates.xml @@ -1,7 +1,7 @@ - + diff --git a/package.json b/package.json index 33788be44..5ef45a5a9 100755 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "Cross-browser userscript for maximum lurking on 4chan.", "meta": { "name": "4chan X", - "version": "1.8.9.5", + "version": "1.8.9.6", "repo": "https://github.com/ccd0/4chan-x/", "page": "https://github.com/ccd0/4chan-x", "downloads": "https://ccd0.github.io/4chan-x/builds/",