diff --git a/CHANGELOG.md b/CHANGELOG.md index e629c4723..6006f63ec 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### v1.9.2.4 +*2014-09-08* + +**ccd0** +- Fix thumbnail replacement / preloading loading images which are not actually on the page. + ### v1.9.2.3 *2014-09-07* diff --git a/LICENSE b/LICENSE index 3e0e1b6ee..7bda8883f 100755 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ /* -* 4chan X - Version 1.9.2.3 +* 4chan X - Version 1.9.2.4 * * 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 ed8e9e1e8..d60706d24 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 67e3f7517..6edb8bfdf 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.9.2.3 +// @version 1.9.2.4 // @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 2336e9409..49655a367 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.9.2.3 +// @version 1.9.2.4 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -24,7 +24,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.9.2.3 +* 4chan X - Version 1.9.2.4 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -376,7 +376,7 @@ doc = d.documentElement; g = { - VERSION: '1.9.2.3', + VERSION: '1.9.2.4', NAMESPACE: '4chan X.', NAME: '4chan X', FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions', @@ -2478,6 +2478,7 @@ var board, el, topNavPos, _l, _len3, _ref3, _ref4; board = $('.board'); $.replace(board, Index.root); + $.event('PostsInserted'); d.implementation.createDocument(null, null, null).appendChild(board); _ref3 = $$('.navLinks'); for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { @@ -2960,6 +2961,9 @@ node = nodes[_i]; $.add(Index.root, [node, $.el('hr')]); } + if (doc.contains(Index.root)) { + $.event('PostsInserted'); + } return ThreadHiding.onIndexBuild(nodes); }, isSearching: false, @@ -3455,7 +3459,8 @@ $.rmAll(nodes.root); $.add(nodes.root, nodes.post); $.rmAll(root); - return $.add(root, nodes.root); + $.add(root, nodes.root); + return $.event('PostsInserted'); }, fetchedPost: function(req, boardID, threadID, postID, root, context) { var board, post, posts, status, thread, _i, _len; @@ -8667,6 +8672,16 @@ }); }); } + $.on(d, 'PostsInserted', function() { + var thumb, thumbsToPlay, _i, _len; + thumbsToPlay = ImageLoader.thumbsToPlay; + ImageLoader.thumbsToPlay = []; + for (_i = 0, _len = thumbsToPlay.length; _i < _len; _i++) { + thumb = thumbsToPlay[_i]; + ImageLoader.play(thumb); + } + return g.posts.forEach(ImageLoader.prefetch); + }); if (!Conf['Image Prefetching']) { return; } @@ -8674,45 +8689,59 @@ innerHTML: " Prefetch Images" }); this.el = prefetch.firstElementChild; - $.on(this.el, 'change', this.toggle); + $.on(this.el, 'change', function() { + if (Conf['prefetch'] = this.checked) { + return g.posts.forEach(ImageLoader.prefetch); + } + }); return Header.menu.addEntry({ el: prefetch, order: 104 }); }, - node: function(force) { - var URL, el, isImage, isVideo, match, prefetch, replace, thumb, type, _ref; - if (!this.file) { + node: function() { + var _ref; + if (this.isClone) { + if ((_ref = this.file) != null ? _ref.videoThumb : void 0) { + return ImageLoader.play(this.file.thumb); + } + } else { + return ImageLoader.prefetch(this); + } + }, + prefetch: function(post) { + var URL, el, file, isImage, isVideo, match, replace, thumb, type; + file = post.file; + if (!file) { return; } - _ref = this.file, isImage = _ref.isImage, isVideo = _ref.isVideo, thumb = _ref.thumb, URL = _ref.URL; - if (this.isClone && this.file.videoThumb) { - ImageLoader.play(thumb); - } - if (this.isClone || this.isHidden || this.thread.isHidden || !(isImage || isVideo)) { + isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, URL = file.URL; + if (!(isImage || isVideo) || post.isHidden || post.thread.isHidden || file.isPrefetched) { return; } type = (match = URL.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src); - prefetch = (Conf['prefetch'] && g.VIEW === 'thread') || force; - if (!(replace || prefetch)) { + if (!(replace || Conf['prefetch'])) { return; } + if (![post].concat(__slice.call(post.clones)).some(function(clone) { + return doc.contains(clone.nodes.root); + })) { + return; + } + file.isPrefetched = true; el = $.el(isImage ? 'img' : 'video'); if (replace) { - if (this.file.isSpoiler) { - thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; - } if (isImage) { $.on(el, 'load', (function(_this) { return function() { - return ImageLoader.replaceImage(_this); + return ImageLoader.replaceImage(post); }; })(this)); } else { $.one(el, 'loadeddata', (function(_this) { return function() { - return ImageLoader.replaceVideo(_this, el); + return ImageLoader.replaceVideo(post, el); }; })(this)); } @@ -8786,28 +8815,22 @@ $.replace(thumb, video); file.thumb = video; file.videoThumb = true; - if (!post.isFetchedQuote) { + if (doc.contains(video) || post.isClone) { return ImageLoader.play(video); } }, - play: function(video) { - if (Conf['Autoplay']) { - return $.asap((function() { - return doc.contains(video); - }), function() { - if (Header.isNodeVisible(video)) { - return video.play(); - } - }); + thumbsToPlay: [], + play: function(thumb) { + var _ref; + if (!Conf['Autoplay']) { + return; } - }, - toggle: function() { - var enabled; - enabled = Conf['prefetch'] = this.checked; - if (enabled) { - g.BOARD.posts.forEach(function(post) { - return ImageLoader.node.call(post, true); - }); + if (doc.contains(thumb)) { + if (Header.isNodeVisible(thumb) || ((_ref = $.id('qp')) != null ? _ref.contains(thumb) : void 0)) { + return thumb.play(); + } + } else { + return ImageLoader.thumbsToPlay.push(thumb); } } }; @@ -8828,6 +8851,7 @@ } thumb = this.file.thumb; thumb.removeAttribute('style'); + thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; return thumb.src = this.file.thumbURL; } }; @@ -10462,6 +10486,7 @@ $.add(ThreadUpdater.root, root); } } + $.event('PostsInserted'); if (scroll) { if (Conf['Bottom Scroll']) { window.scrollTo(0, d.body.clientHeight); @@ -11896,6 +11921,7 @@ } Main.callbackNodes(Post, posts); $.after(a, postsRoot); + $.event('PostsInserted'); postsCount = postsRoot.length; a.textContent = ExpandThread.text('-', postsCount, filesCount); return Fourchan.parseThread(thread.ID, 1, postsCount); @@ -12922,7 +12948,7 @@ className: 'dialog' }); $.extend(dialog, { - innerHTML: "
" + innerHTML: "
" }); $.on($('.export', Settings.dialog), 'click', Settings["export"]); $.on($('.import', Settings.dialog), 'click', Settings["import"]); diff --git a/builds/4chan-X-noupdate.crx b/builds/4chan-X-noupdate.crx index 17e92735c..854309a80 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 6be2bf7e0..f419bfed6 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.9.2.3 +// @version 1.9.2.4 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -23,7 +23,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.9.2.3 +* 4chan X - Version 1.9.2.4 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -375,7 +375,7 @@ doc = d.documentElement; g = { - VERSION: '1.9.2.3', + VERSION: '1.9.2.4', NAMESPACE: '4chan X.', NAME: '4chan X', FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions', @@ -2477,6 +2477,7 @@ var board, el, topNavPos, _l, _len3, _ref3, _ref4; board = $('.board'); $.replace(board, Index.root); + $.event('PostsInserted'); d.implementation.createDocument(null, null, null).appendChild(board); _ref3 = $$('.navLinks'); for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { @@ -2959,6 +2960,9 @@ node = nodes[_i]; $.add(Index.root, [node, $.el('hr')]); } + if (doc.contains(Index.root)) { + $.event('PostsInserted'); + } return ThreadHiding.onIndexBuild(nodes); }, isSearching: false, @@ -3454,7 +3458,8 @@ $.rmAll(nodes.root); $.add(nodes.root, nodes.post); $.rmAll(root); - return $.add(root, nodes.root); + $.add(root, nodes.root); + return $.event('PostsInserted'); }, fetchedPost: function(req, boardID, threadID, postID, root, context) { var board, post, posts, status, thread, _i, _len; @@ -8666,6 +8671,16 @@ }); }); } + $.on(d, 'PostsInserted', function() { + var thumb, thumbsToPlay, _i, _len; + thumbsToPlay = ImageLoader.thumbsToPlay; + ImageLoader.thumbsToPlay = []; + for (_i = 0, _len = thumbsToPlay.length; _i < _len; _i++) { + thumb = thumbsToPlay[_i]; + ImageLoader.play(thumb); + } + return g.posts.forEach(ImageLoader.prefetch); + }); if (!Conf['Image Prefetching']) { return; } @@ -8673,45 +8688,59 @@ innerHTML: " Prefetch Images" }); this.el = prefetch.firstElementChild; - $.on(this.el, 'change', this.toggle); + $.on(this.el, 'change', function() { + if (Conf['prefetch'] = this.checked) { + return g.posts.forEach(ImageLoader.prefetch); + } + }); return Header.menu.addEntry({ el: prefetch, order: 104 }); }, - node: function(force) { - var URL, el, isImage, isVideo, match, prefetch, replace, thumb, type, _ref; - if (!this.file) { + node: function() { + var _ref; + if (this.isClone) { + if ((_ref = this.file) != null ? _ref.videoThumb : void 0) { + return ImageLoader.play(this.file.thumb); + } + } else { + return ImageLoader.prefetch(this); + } + }, + prefetch: function(post) { + var URL, el, file, isImage, isVideo, match, replace, thumb, type; + file = post.file; + if (!file) { return; } - _ref = this.file, isImage = _ref.isImage, isVideo = _ref.isVideo, thumb = _ref.thumb, URL = _ref.URL; - if (this.isClone && this.file.videoThumb) { - ImageLoader.play(thumb); - } - if (this.isClone || this.isHidden || this.thread.isHidden || !(isImage || isVideo)) { + isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, URL = file.URL; + if (!(isImage || isVideo) || post.isHidden || post.thread.isHidden || file.isPrefetched) { return; } type = (match = URL.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src); - prefetch = (Conf['prefetch'] && g.VIEW === 'thread') || force; - if (!(replace || prefetch)) { + if (!(replace || Conf['prefetch'])) { return; } + if (![post].concat(__slice.call(post.clones)).some(function(clone) { + return doc.contains(clone.nodes.root); + })) { + return; + } + file.isPrefetched = true; el = $.el(isImage ? 'img' : 'video'); if (replace) { - if (this.file.isSpoiler) { - thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; - } if (isImage) { $.on(el, 'load', (function(_this) { return function() { - return ImageLoader.replaceImage(_this); + return ImageLoader.replaceImage(post); }; })(this)); } else { $.one(el, 'loadeddata', (function(_this) { return function() { - return ImageLoader.replaceVideo(_this, el); + return ImageLoader.replaceVideo(post, el); }; })(this)); } @@ -8785,28 +8814,22 @@ $.replace(thumb, video); file.thumb = video; file.videoThumb = true; - if (!post.isFetchedQuote) { + if (doc.contains(video) || post.isClone) { return ImageLoader.play(video); } }, - play: function(video) { - if (Conf['Autoplay']) { - return $.asap((function() { - return doc.contains(video); - }), function() { - if (Header.isNodeVisible(video)) { - return video.play(); - } - }); + thumbsToPlay: [], + play: function(thumb) { + var _ref; + if (!Conf['Autoplay']) { + return; } - }, - toggle: function() { - var enabled; - enabled = Conf['prefetch'] = this.checked; - if (enabled) { - g.BOARD.posts.forEach(function(post) { - return ImageLoader.node.call(post, true); - }); + if (doc.contains(thumb)) { + if (Header.isNodeVisible(thumb) || ((_ref = $.id('qp')) != null ? _ref.contains(thumb) : void 0)) { + return thumb.play(); + } + } else { + return ImageLoader.thumbsToPlay.push(thumb); } } }; @@ -8827,6 +8850,7 @@ } thumb = this.file.thumb; thumb.removeAttribute('style'); + thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; return thumb.src = this.file.thumbURL; } }; @@ -10461,6 +10485,7 @@ $.add(ThreadUpdater.root, root); } } + $.event('PostsInserted'); if (scroll) { if (Conf['Bottom Scroll']) { window.scrollTo(0, d.body.clientHeight); @@ -11895,6 +11920,7 @@ } Main.callbackNodes(Post, posts); $.after(a, postsRoot); + $.event('PostsInserted'); postsCount = postsRoot.length; a.textContent = ExpandThread.text('-', postsCount, filesCount); return Fourchan.parseThread(thread.ID, 1, postsCount); @@ -12921,7 +12947,7 @@ className: 'dialog' }); $.extend(dialog, { - innerHTML: "
" + innerHTML: "
" }); $.on($('.export', Settings.dialog), 'click', Settings["export"]); $.on($('.import', Settings.dialog), 'click', Settings["import"]); diff --git a/builds/4chan-X.crx b/builds/4chan-X.crx index 515803262..43dd7f558 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 641ee69b3..1c0e7493a 100644 --- a/builds/4chan-X.meta.js +++ b/builds/4chan-X.meta.js @@ -1,6 +1,6 @@ // ==UserScript== // @name 4chan X -// @version 1.9.2.3 +// @version 1.9.2.4 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X diff --git a/builds/4chan-X.user.js b/builds/4chan-X.user.js index 52f88fe2c..dc1e86500 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.9.2.3 +// @version 1.9.2.4 // @minGMVer 1.14 // @minFFVer 26 // @namespace 4chan-X @@ -24,7 +24,7 @@ // ==/UserScript== /* -* 4chan X - Version 1.9.2.3 +* 4chan X - Version 1.9.2.4 * * Licensed under the MIT license. * https://github.com/ccd0/4chan-x/blob/master/LICENSE @@ -376,7 +376,7 @@ doc = d.documentElement; g = { - VERSION: '1.9.2.3', + VERSION: '1.9.2.4', NAMESPACE: '4chan X.', NAME: '4chan X', FAQ: 'https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions', @@ -2478,6 +2478,7 @@ var board, el, topNavPos, _l, _len3, _ref3, _ref4; board = $('.board'); $.replace(board, Index.root); + $.event('PostsInserted'); d.implementation.createDocument(null, null, null).appendChild(board); _ref3 = $$('.navLinks'); for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { @@ -2960,6 +2961,9 @@ node = nodes[_i]; $.add(Index.root, [node, $.el('hr')]); } + if (doc.contains(Index.root)) { + $.event('PostsInserted'); + } return ThreadHiding.onIndexBuild(nodes); }, isSearching: false, @@ -3455,7 +3459,8 @@ $.rmAll(nodes.root); $.add(nodes.root, nodes.post); $.rmAll(root); - return $.add(root, nodes.root); + $.add(root, nodes.root); + return $.event('PostsInserted'); }, fetchedPost: function(req, boardID, threadID, postID, root, context) { var board, post, posts, status, thread, _i, _len; @@ -8667,6 +8672,16 @@ }); }); } + $.on(d, 'PostsInserted', function() { + var thumb, thumbsToPlay, _i, _len; + thumbsToPlay = ImageLoader.thumbsToPlay; + ImageLoader.thumbsToPlay = []; + for (_i = 0, _len = thumbsToPlay.length; _i < _len; _i++) { + thumb = thumbsToPlay[_i]; + ImageLoader.play(thumb); + } + return g.posts.forEach(ImageLoader.prefetch); + }); if (!Conf['Image Prefetching']) { return; } @@ -8674,45 +8689,59 @@ innerHTML: " Prefetch Images" }); this.el = prefetch.firstElementChild; - $.on(this.el, 'change', this.toggle); + $.on(this.el, 'change', function() { + if (Conf['prefetch'] = this.checked) { + return g.posts.forEach(ImageLoader.prefetch); + } + }); return Header.menu.addEntry({ el: prefetch, order: 104 }); }, - node: function(force) { - var URL, el, isImage, isVideo, match, prefetch, replace, thumb, type, _ref; - if (!this.file) { + node: function() { + var _ref; + if (this.isClone) { + if ((_ref = this.file) != null ? _ref.videoThumb : void 0) { + return ImageLoader.play(this.file.thumb); + } + } else { + return ImageLoader.prefetch(this); + } + }, + prefetch: function(post) { + var URL, el, file, isImage, isVideo, match, replace, thumb, type; + file = post.file; + if (!file) { return; } - _ref = this.file, isImage = _ref.isImage, isVideo = _ref.isVideo, thumb = _ref.thumb, URL = _ref.URL; - if (this.isClone && this.file.videoThumb) { - ImageLoader.play(thumb); - } - if (this.isClone || this.isHidden || this.thread.isHidden || !(isImage || isVideo)) { + isImage = file.isImage, isVideo = file.isVideo, thumb = file.thumb, URL = file.URL; + if (!(isImage || isVideo) || post.isHidden || post.thread.isHidden || file.isPrefetched) { return; } type = (match = URL.match(/\.([^.]+)$/)[1].toUpperCase()) === 'JPEG' ? 'JPG' : match; replace = Conf["Replace " + type] && !/spoiler/.test(thumb.src); - prefetch = (Conf['prefetch'] && g.VIEW === 'thread') || force; - if (!(replace || prefetch)) { + if (!(replace || Conf['prefetch'])) { return; } + if (![post].concat(__slice.call(post.clones)).some(function(clone) { + return doc.contains(clone.nodes.root); + })) { + return; + } + file.isPrefetched = true; el = $.el(isImage ? 'img' : 'video'); if (replace) { - if (this.file.isSpoiler) { - thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; - } if (isImage) { $.on(el, 'load', (function(_this) { return function() { - return ImageLoader.replaceImage(_this); + return ImageLoader.replaceImage(post); }; })(this)); } else { $.one(el, 'loadeddata', (function(_this) { return function() { - return ImageLoader.replaceVideo(_this, el); + return ImageLoader.replaceVideo(post, el); }; })(this)); } @@ -8786,28 +8815,22 @@ $.replace(thumb, video); file.thumb = video; file.videoThumb = true; - if (!post.isFetchedQuote) { + if (doc.contains(video) || post.isClone) { return ImageLoader.play(video); } }, - play: function(video) { - if (Conf['Autoplay']) { - return $.asap((function() { - return doc.contains(video); - }), function() { - if (Header.isNodeVisible(video)) { - return video.play(); - } - }); + thumbsToPlay: [], + play: function(thumb) { + var _ref; + if (!Conf['Autoplay']) { + return; } - }, - toggle: function() { - var enabled; - enabled = Conf['prefetch'] = this.checked; - if (enabled) { - g.BOARD.posts.forEach(function(post) { - return ImageLoader.node.call(post, true); - }); + if (doc.contains(thumb)) { + if (Header.isNodeVisible(thumb) || ((_ref = $.id('qp')) != null ? _ref.contains(thumb) : void 0)) { + return thumb.play(); + } + } else { + return ImageLoader.thumbsToPlay.push(thumb); } } }; @@ -8828,6 +8851,7 @@ } thumb = this.file.thumb; thumb.removeAttribute('style'); + thumb.style.maxHeight = thumb.style.maxWidth = this.isReply ? '125px' : '250px'; return thumb.src = this.file.thumbURL; } }; @@ -10462,6 +10486,7 @@ $.add(ThreadUpdater.root, root); } } + $.event('PostsInserted'); if (scroll) { if (Conf['Bottom Scroll']) { window.scrollTo(0, d.body.clientHeight); @@ -11896,6 +11921,7 @@ } Main.callbackNodes(Post, posts); $.after(a, postsRoot); + $.event('PostsInserted'); postsCount = postsRoot.length; a.textContent = ExpandThread.text('-', postsCount, filesCount); return Fourchan.parseThread(thread.ID, 1, postsCount); @@ -12922,7 +12948,7 @@ className: 'dialog' }); $.extend(dialog, { - innerHTML: "
" + innerHTML: "
" }); $.on($('.export', Settings.dialog), 'click', Settings["export"]); $.on($('.import', Settings.dialog), 'click', Settings["import"]); diff --git a/builds/4chan-X.zip b/builds/4chan-X.zip index aba6aff1d..1143b6db0 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 0a47d7c95..73105e269 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 d5d055a2f..412c1f90c 100644 --- a/builds/updates.xml +++ b/builds/updates.xml @@ -1,7 +1,7 @@ - + diff --git a/package.json b/package.json index 61bde0ab1..f49aa1a40 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.9.2.3", + "version": "1.9.2.4", "repo": "https://github.com/ccd0/4chan-x/", "page": "https://github.com/ccd0/4chan-x", "downloads": "https://ccd0.github.io/4chan-x/builds/",