Merge branch 'v3' into Av2

Conflicts:
	builds/4chan-X.js
	builds/4chan-X.meta.js
	builds/4chan-X.user.js
	builds/crx.crx
	builds/crx/manifest.json
	builds/crx/script.js
	package.json
	src/General/Config.coffee
	src/General/Main.coffee
	src/General/Settings.coffee
	src/General/css/burichan.css
	src/General/css/futaba.css
	src/General/css/photon.css
	src/General/css/style.css
	src/General/css/tomorrow.css
	src/General/css/yotsuba-b.css
	src/General/css/yotsuba.css
	src/General/img/favicons/Original/unreadDead.gif
	src/General/img/favicons/Original/unreadNSFW.gif
	src/General/img/favicons/Original/unreadSFW.gif
	src/General/img/favicons/dead.gif
	src/General/img/favicons/empty.gif
	src/General/img/favicons/ferongr/unreadDead.gif
	src/General/img/favicons/ferongr/unreadNSFW.gif
	src/General/img/favicons/ferongr/unreadSFW.gif
	src/General/meta/metadata.js
	src/Miscellaneous/AnnouncementHiding.coffee
	src/Miscellaneous/Keybinds.coffee
	src/Monitoring/ThreadStats.coffee
	src/Monitoring/ThreadUpdater.coffee
	src/Posting/QuickReply.coffee
	src/features/misc/header.coffee
	src/features/monitoring/favicon.coffee
This commit is contained in:
Zixaphir 2013-04-28 21:20:07 -07:00
commit 77433f5da8
199 changed files with 16645 additions and 16119 deletions

2
.gitignore vendored
View File

@ -4,3 +4,5 @@ node_modules/
tmp-crx/
tmp-userjs/
tmp-userscript/
builds/4chan-X.zip
Gruntfile.js

View File

@ -1,125 +1,106 @@
- Added the option `Hide Unread Count at (0)`, disabled by default.
### 1.1.3 - 2013-04-28
seaweedchan:
- Chrome doesn't get .null, so don't style it
- Fix count when auto update is disabled and set updater text to "Update"
- Remove /v/ and /vg/ redirection. See https://archive.foolz.us/foolz/thread/509388/ for news and how you can donate to bring /v/ and /vg/ archiving back.
- Toggle keybind for header auto-hiding
### 3.1.4 - *2013-04-17*
MayhemYDG:
- Fix Unread Count taking into account hidden posts.
- Fix QR remembering the file spoiler state when it shouldn't, for real this time.
- Fix inputs in the `Rice` tab being empty when `Custom Board Navigation` is disabled.
### 1.1.2 - 2013-04-26
seaweedchan:
- Fix emoji and favicon previews not updating on change.
- Fix issue with dragging thread watcher
- Fix some settings not importing when coming from Mayhem's v3
- Fix menu z-index
### 3.1.3 - *2013-04-16*
MayhemYDG:
- Fix bug where a thread would freeze on load.
- Fix Chrome freezing when switching from the `Filter` tab to another tab in the settings.
zixaphir:
- Fix preview with favicons and emoji
- Fix NaN error on Thread Updater Interval
- Draggable UI can no longer overlap the Header.
-- Setting the header to Autohide also increases its z-index to overlap other UI
### 3.1.2 - *2013-04-16*
- Fix error with successful posting.
### 3.1.1 - *2013-04-16*
- Styling adjustments for the announcement toggler.
## 3.1.0 - *2013-04-16*
- **New feature**: `Announcement Hiding`, enabled by default.
- Fix support for www.4chan.org/frames on Chrome.
- Fix quote features not working on dead quotelinks in inlined posts.
- Fix resurrecting dead quotelinks on HTTP.
### 3.0.6 - *2013-04-14*
- Fix regression concerning thread selection when quoting on the index.
### 3.0.5 - *2013-04-14*
- `Scroll to Last Read Post` is now optional, enabled by default.
- The QR won't auto-hide when auto-hide is enabled and one of its input is focused. Doesn't work on Firefox.
- Added the `Remember QR Size` setting back in, disabled by default. Only on Firefox.
- Fix QR remembering the file spoiler state when it shouldn't.
- Fix QR cooldown in Opera.
### 3.0.4 - *2013-04-11*
- More minor fixes.
### 3.0.3 - *2013-04-10*
### 1.1.1 - 2013-04-26
zixaphir:
- Fix script on Opera
MayhemYDG:
- Minor fixes.
- Chrome only: Due to technical limitations, Filter lists and Custom CSS will not by synchronized across devices anymore.
### 3.0.2 - *2013-04-09*
seaweedchan:
- Allow thread watcher to load on catalog
- Added a setting in the Header's menu to move it at the bottom of the screen.
- Added the `Cooldown` setting back in.
- Fixed the Header going above posts when following quotelinks for example.
- Fixed a bug where dead quotelinks would disappear.
### 1.0.10:
- Add message pertaining to rewrite
### 3.0.1 - *2013-04-08*
### 1.0.9:
ihavenoface:
- Implement Announcement Hiding
seaweedchan:
- Change #options back to inheriting colors from replies
- Fix script breaking when disabling image expansion
- Added the possibility to combine board-list toggle and custom text.
- Added Reply Navigation back in, disabled by default.
- Fixed Thread Hiding initialization error.
### 1.0.8:
seaweedchan:
- Redo settings menu styling
- Move Export/Import buttons and dialog
- Update license and use banner.js for license
# 3.0.0 - *2013-04-07*
### 1.0.7:
qqueue:
- Relative post dates
MayhemYDG:
- Exporting/importing settings
**Major rewrite of 4chan X.**
### 1.0.6
seaweedchan:
- Update supported boards for archive redirection and custom navigation
- Point to github.io instead of github.com for pages
- Fix post archive link for InstallGentoo and Foolz
- Make InstallGentoo default for /g/
- Fix embedding issues
Header:
- Easily access features and the boards list directly from the Header.
- The board list can be customized.
- The Header can be automatically hidden.
### 1.0.5:
seaweedchan:
- Added keybind to toggle Fappe Tyme
- Fix code tag keybind
Zixaphir:
- Add 'yourPost' class to own replies
Extension-related changes for Chrome and Opera:
- Installing and updating is now pain-free on Chrome.
- Settings will persist on different subdomains and protocols (HTTP/HTTPS).
- Settings will persist in Incognito on Chrome.
- Clearing your cookies won't erase your settings anymore.
- Fixed Chrome's install warning saying that 4chan X would run on all web sites.
### 1.0.4:
seaweedchan:
- Fix Fappe Tyme
- Re- add label for image expanding
- Move restore button to left side as per RiDeag
Egocentrism:
- `(You)` will be added to quotes linking to your posts.
- The Unread tab icon will indicate new unread posts quoting you with an exclamation mark.
### 1.0.3
seaweedchan:
- Add ad- blocking CSS into Custom CSS examples
Zixaphir:
- Fix ctrl+s bringing up save dialog
- Fix issues with soundcloud embedding
Quick Reply changes:
- Opening text files will insert their content in the comment field.
- Pasting files/images (e.g. from another website) in Chrome will open them in the QR.
- Cooldown start time is now more accurate, which means shorter cooldown period and faster auto-posting.
- Cooldown remaining time will adjust to your upload speed and file size for faster auto-posting.
- Clicking the submit button while uploading will abort the upload and won't start re-uploading automatically anymore.
- Closing the QR while uploading will abort the upload and won't close the QR anymore.
- Creating threads outside of the index is now possible.
- Selection-to-quote also applies to selected text inside the post, not just inside the comment.
- Added support for thread creation in the catalog.
- Added thumbnailing support for Opera.
### 1.0.2:
seaweedchan:
- New Rice option: Emoji Position
- New layout for Rice tab
- No more Yotsuba / Yotsuba B in options
Image Expansion changes:
- The toggle and settings are now located in the Header's shortcuts and menu.
- Expanding spoilers along with all non-spoiler images is now optional, and disabled by default.
- Expanding OP images won't squish replies anymore.
### 1.0.1:
- New option: Emoji
- New Rice option: Sage Emoji
seaweedchan:
- Prettier error messages
Thread Updater changes:
- The Thread Updater will now notify of sticky/closed status change and update the icons.
- The Thread Updater will pause when offline, and resume when online.
- Added a setting to always auto-scroll to the bottom instead of the first new post.
Unread posts changes:
- Added a line to distinguish read posts from unread ones.
- Read posts won't be marked as unread after reloading a thread.
- The page will scroll to the last read post after reloading a thread.
- Visible posts will not be taken into account towards the unread count.
Thread Stats changes:
- Post and file count will now adjust with deleted posts.
- The post count will now become red past the bump limit.
- The file count will not become red anymore inside sticky threads.
Thread/Post Hiding changes:
- Added Thread & Post Hiding in the Menu, with individual settings.
- Thread & Post Hiding Buttons can now be disabled in the settings.
- Recursive Hiding will be automatically applied when manually showing/hiding a post.
Other:
- Added touch and multi-touch support for dragging windows.
- Added [eqn] and [math] tags keybind.
- Fix Chrome's install warning saying that 4chan X would execute on all domains.
- Fix Quote Backlinks and Quote Highlighting not affecting inlined quotes.
- Fix unreadable inlined posts with the Tomorrow theme.
- Fix user ID highlighting on fetched posts.
- More fixes and improvements.
### 1.0.0
- Initial release
zixaphir:
- Fix unread post count for filtered posts
- Fix issues when switching from ihavenoface's fork
- Fix backlinks not receiving filtered class
- Fix QR position not saving on refresh

View File

@ -1,50 +0,0 @@
## Reporting bugs and suggestions
Reporting bugs:
1. Make sure both your **browser** and **4chan 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/MayhemYDG/4chan-x/issues) with the following information:
1. Precise steps to reproduce the problem, with the expected and actual results.
2. Console errors, if any.
3. Browser version.
4. Your exported settings.
Open your console with:
- `Ctrl + Shift + J` on Chrome.
- `Ctrl + Shift + K` on Firefox.
- `Ctrl + Shift + O` on Opera.
Respect these guidelines:
- Describe the issue clearly, put some effort into it. A one-liner isn't a good enough description.
- If you want to get your suggestion implemented sooner, make it convincing.
- If you want to criticize, make it convincing and constructive.
- Be mature. Act like an idiot and you will be blocked without warning.
## Development & Contribution
### Get started
- Install [node.js](http://nodejs.org/).
- Install [Grunt's CLI](http://gruntjs.com/) with `npm install -g grunt-cli`.
- Clone 4chan X.
- `cd` into it.
- Install/Update 4chan X dependencies with `npm install`.
### Build
- Build with `grunt`.
- Continuously build with `grunt watch`.
### Release
- 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.
### Contribute
- Edit the CoffeeScript sources.
- If the edits affect regular users, edit the changelog.
- Open a pull request.

View File

@ -17,29 +17,47 @@ module.exports = (grunt) ->
coffee:
options: concatOptions
src: [
'src/config.coffee'
'src/globals.coffee'
'src/lib/*.coffee'
'src/features/*/*.coffee'
'src/settings.coffee'
'src/main.coffee'
'src/General/Config.coffee'
'src/General/Globals.coffee'
'src/General/lib/*.coffee'
'src/General/Header.coffee'
'src/General/Build.coffee'
'src/General/Get.coffee'
'src/General/UI.coffee'
'src/Filtering/*'
'src/Quotelinks/*'
'src/Linkification/*'
'src/Posting/*'
'src/Images/*'
'src/Menu/*'
'src/Monitoring/*'
'src/Archive/*'
'src/Theming/*'
'src/Miscellaneous/*'
'src/General/Settings.coffee'
'src/General/Main.coffee'
]
dest: 'tmp-<%= pkg.type %>/script.coffee'
license:
options: concatOptions
files:
'LICENSE': 'src/General/meta/banner.js'
crx:
options: concatOptions
files:
'builds/crx/manifest.json': 'src/meta/manifest.json'
'builds/crx/manifest.json': 'src/General/meta/manifest.json'
'builds/crx/script.js': [
'src/banner.js'
'src/General/meta/banner.js'
'tmp-<%= pkg.type %>/script.js'
]
userjs:
options: concatOptions
src: [
'src/meta/metadata.js'
'src/meta/banner.js'
'src/General/meta/metadata.js'
'src/General/meta/banner.js'
'tmp-<%= pkg.type %>/script.js'
]
dest: 'builds/<%= pkg.name %>.js'
@ -47,16 +65,16 @@ module.exports = (grunt) ->
userscript:
options: concatOptions
files:
'builds/<%= pkg.name %>.meta.js': 'src/metadata.js'
'builds/<%= pkg.name %>.meta.js': 'src/General/meta/metadata.js'
'builds/<%= pkg.name %>.user.js': [
'src/meta/metadata.js'
'src/meta/banner.js'
'src/General/meta/metadata.js'
'src/General/meta/banner.js'
'tmp-<%= pkg.type %>/script.js'
]
copy:
crx:
src: 'src/img/*.png'
src: 'src/General/img/*.png'
dest: 'builds/crx/'
expand: true
flatten: true
@ -80,7 +98,7 @@ module.exports = (grunt) ->
'git checkout <%= pkg.meta.mainBranch %>',
'git commit -am "Release <%= pkg.meta.name %> v<%= pkg.version %>."',
'git tag -a <%= pkg.version %> -m "<%= pkg.meta.name %> v<%= pkg.version %>."',
'git tag -af stable-v3 -m "<%= pkg.meta.name %> v<%= pkg.version %>."'
'git tag -af stable -m "<%= pkg.meta.name %> v<%= pkg.version %>."'
].join(' && ')
stdout: true
@ -135,6 +153,7 @@ module.exports = (grunt) ->
grunt.registerTask 'build', [
'concurrent:build'
'concat:license'
]
grunt.registerTask 'build-crx', [
@ -164,38 +183,39 @@ module.exports = (grunt) ->
grunt.registerTask 'release', [
'default'
'compress:crx'
'shell:commit'
'shell:push'
]
grunt.registerTask 'patch', [
'bump'
'reloadPkh'
'reloadPkg'
'updcl:3'
]
grunt.registerTask 'minor', [
'bump:minor'
'reloadPkh'
'reloadPkg'
'updcl:2'
]
grunt.registerTask 'major', [
'bump:major'
'reloadPkh'
'reloadPkg'
'updcl:1'
]
grunt.registerTask 'reloadPkg', 'Reload the package', ->
# Update the `pkg` object with the new version.
pkg = grunt.file.readJSON('package.json')
concatOptions.process.data = pkg
grunt.config.data.pkg = concatOptions.process.data = pkg
grunt.log.ok('pkg reloaded.')
grunt.registerTask 'updcl', 'Update the changelog', (i) ->
# i is the number of #s for markdown.
version = []
version.length = +i + 1
version = version.join('#') + ' ' + pkg.version + ' *(' + grunt.template.today('yyyy-mm-dd') + ')*'
version = version.join('#') + ' ' + pkg.version + ' - ' + grunt.template.today('yyyy-mm-dd')
grunt.file.write 'CHANGELOG.md', version + '\n' + grunt.file.read('CHANGELOG.md')
grunt.log.ok 'Changelog updated for v' + pkg.version + '.'

109
LICENSE
View File

@ -1,22 +1,89 @@
Copyright (c) 2009-2011 James Campos <james.r.campos@gmail.com>
Copyright (c) 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
/*
* appchan x - Version 2.0.0 - 2013-04-28
*
* Licensed under the MIT license.
* https://github.com/zixaphir/appchan-x/blob/master/LICENSE
*
* Appchan X Copyright © 2013-2013 Zixaphir <zixaphirmoxphar@gmail.com>
* http://zixaphir.github.io/appchan-x/
* 4chan x Copyright © 2009-2011 James Campos <james.r.campos@gmail.com>
* https://github.com/aeosynth/4chan-x
* 4chan x Copyright © 2012-2013 Nicolas Stepien <stepien.nicolas@gmail.com>
* https://4chan-x.just-believe.in/
* 4chan x Copyright © 2013-2013 Jordan Bates <saudrapsmann@gmail.com>
* http://seaweedchan.github.io/4chan-x/
* 4chan x Copyright © 2012-2013 ihavenoface
* http://ihavenoface.github.io/4chan-x/
* 4chan SS Copyright © 2011-2013 Ahodesuka
* https://github.com/ahodesuka/4chan-Style-Script/
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Contributors:
* aeosynth
* mayhemydg
* noface
* !K.WeEabo0o
* blaise
* that4chanwolf
* desuwa
* seaweed
* e000
* ahodesuka
* Shou
* ferongr
* xat
* Ongpot
* thisisanon
* Anonymous
* Seiba
* herpaderpderp
* WakiMiko
* btmcsweeney
* AppleBloom
*
* All the people who've taken the time to write bug reports.
*
* Thank you.
*/
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.
/*
* 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
*
* Linkify: (http://userscripts.org/scripts/show/1352)
* Copyright (c) 2011, Anthony Lieuallen
* All rights reserved.
* Originally written by Anthony Lieuallen of http://arantius.com/
* Licensed for unlimited modification and redistribution as long as
* this notice is kept intact.
*
* license: http://userscripts.org/scripts/review/1352
*
*/

View File

@ -1,8 +1,44 @@
# 4chan X
# Get 4chan X [HERE](http://seaweedchan.github.io/4chan-x/).
Get it [here](https://4chan-x.just-believe.in/).
## Reporting bugs and suggestions
***
1. Make sure both your **browser** and **4chan 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/seaweedchan/4chan-x/issues) with the following information:
1. Precise steps to reproduce the problem, with the expected and actual results.
2. Console errors, if any.
3. Browser version.
4. Your exported settings.
### [MIT License](/LICENSE)
### [Contribute](/CONTRIBUTING.md)
Open your console with:
- `Ctrl + Shift + J` on Chrome.
- `Ctrl + Shift + K` on Firefox.
- `Ctrl + Shift + O` on Opera.
## Development & Contribution
### Get started
- Install [node.js](http://nodejs.org/).
- Install [Grunt's CLI](http://gruntjs.com/) with `npm install -g grunt-cli`.
- Clone 4chan X.
- `cd` into it.
- Install/Update 4chan X dependencies with `npm install`.
### Build
- Build with `grunt`.
- Continuously build with `grunt watch`.
### Release
- 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.
### Contribute
- Edit the CoffeeScript sources.
- If the edits affect regular users, edit the changelog.
- Open a pull request.

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,19 @@
// ==UserScript==
// @name appchan x
// @version 2.0.0
// @namespace zixaphir
// @description The most comprehensive 4chan userscript.
// @license MIT; https://github.com/zixaphir/appchan-x/blob/Av2/LICENSE
// @match *://api.4chan.org/*
// @match *://boards.4chan.org/*
// @match *://images.4chan.org/*
// @match *://sys.4chan.org/*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM_openInTab
// @run-at document-start
// @updateURL https://github.com/zixaphir/appchan-x/raw/stable/builds/4chan_X.meta.js
// @downloadURL https://github.com/zixaphir/appchan-x/raw/stable/builds/4chan_X.user.js
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAElBMVEX///8EZgR8ulSk0oT///8EAgQ1A88mAAAAAXRSTlMAQObYZgAAAIpJREFUeF6t0sENwjAMhWF84N4H6gAYMUBkdQMYwfuvwmstEeD4kl892P0OaaWcpga2/K0SGII1HNBXARgu7veoY3ANd+esgMHZIz85u0EABrbms3pl/bkC1Tn5ihGOfQwqHeZ/FdYdirEMgCG2ZAQWDTL0m9FvjAhcvoGNAK2gZhGYYX9+ZgFm9gaiNmNkMENY4QAAAABJRU5ErkJggg==
// ==/UserScript==

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -14,16 +14,20 @@
"*://boards.4chan.org/*",
"*://images.4chan.org/*",
"*://sys.4chan.org/*"
]
],
"files": {
"metajs": "4chan_X.meta.js",
"userjs": "4chan_X.user.js"
}
},
"devDependencies": {
"grunt": "~0.4.1",
"grunt-bump": "~0.0.2",
"grunt-concurrent": "~0.2.0",
"grunt-contrib-clean": "~0.4.1",
"grunt-contrib-coffee": "~0.6.7",
"grunt-contrib-compress": "~0.4.10",
"grunt-contrib-concat": "~0.2.0",
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-compress": "~0.5.0",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-watch": "~0.3.1",
"grunt-shell": "~0.2.2"

View File

@ -9,7 +9,7 @@ Redirect =
image: (boardID, filename) ->
# Do not use g.BOARD, the image url can originate from a cross-quote.
switch boardID
when 'a', 'gd', 'jp', 'm', 'q', 'tg', 'vg', 'vp', 'vr', 'wsg'
when 'a', 'gd', 'jp', 'm', 'q', 'tg', 'vp', 'vr', 'wsg'
"//archive.foolz.us/#{boardID}/full_image/#{filename}"
when 'u'
"//nsfw.foolz.us/#{boardID}/full_image/#{filename}"
@ -61,7 +61,7 @@ Redirect =
archiver:
'Foolz':
base: 'https://archive.foolz.us'
boards: ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'v', 'vg', 'vp', 'vr', 'wsg']
boards: ['a', 'co', 'gd', 'jp', 'm', 'q', 'sp', 'tg', 'tv', 'vp', 'vr', 'wsg']
type: 'foolfuuka'
'NSFWFoolz':
base: 'https://nsfw.foolz.us'
@ -130,4 +130,4 @@ Redirect =
"##{postID}"
else
"#p#{postID}"
"#{base}/#{path}"
"#{base}/#{path}"

View File

@ -9,10 +9,6 @@ Config =
false
'Link to external catalog instead of the internal one.'
]
'Custom Board Navigation': [
false
'Show custom links instead of the full board list.'
]
'QR Shortcut': [
false,
'Adds a small [QR] link in the header.'
@ -61,6 +57,22 @@ Config =
true
'Check for updated versions of <%= meta.name %>.'
]
'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.'
]
'Indicate Spoilers': [
false
'Indicate spoilers if Remove Spoilers is enabled.'
]
'Linkification':
'Linkify': [
@ -183,7 +195,7 @@ Config =
]
'Hide Unread Count at (0)': [
false
'Hide the unread posts count when it reaches 0.'
'Hide the unread posts count in the tab title when it reaches 0.'
]
'Unread Favicon': [
true
@ -259,7 +271,11 @@ Config =
]
'Cooldown': [
true
'Prevent "flood detected" errors.'
'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.'
]
'Quote Links':
@ -295,6 +311,10 @@ Config =
true
'Add \'(You)\' to quotes linking to your posts.'
]
'Highlight Own Posts': [
false
'Highlights own posts if Mark Quotes of You is enabled.'
]
'Mark OP Quotes': [
true
'Add \'(OP)\' to OP quotes.'
@ -410,11 +430,6 @@ Config =
true
'Adds an icon you can hover over to show the watcher, as opposed to having the watcher always visible.'
]
'Updater Position': [
'top'
'The position of 4chan thread updater and stats'
['top', 'bottom', 'moveable']
]
Posts:
'Alternate Post Colors': [
@ -734,14 +749,20 @@ http://iqdb.org/?url=%TURL
#//archive.foolz.us/%board/search/image/%MD5/;text:View same on foolz /%board/
#//archive.installgentoo.net/%board/image/%MD5;text:View same on installgentoo /%board/
"""
'sageEmoji': 'appchan'
'emojiPos': 'before'
'Custom CSS': false
'Boards Navigation': 'Sticky top'
'Header auto-hide': false
'Header catalog links': false
Header:
'Fixed Header': true
'Header auto-hide': false
'Bottom Header': false
'Hide Header': false
'Header catalog links': false
'Bottom Board List': true
'Custom Board Navigation': true
boardnav: '[ toggle-all ] [current-title]'
@ -784,12 +805,16 @@ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
'Ctrl+b'
'Toggle the full board list.'
]
'Toggle header': [
'Shift+h'
'Toggle the auto-hide option of the header.'
]
'Open empty QR': [
'l'
'i'
'Open QR without post number inserted.'
]
'Open QR': [
'Shift+l'
'Shift+i'
'Open QR with post number inserted.'
]
'Open settings': [
@ -816,8 +841,12 @@ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
'Alt+m'
'Insert math tags.'
]
'Submit QR': [
'Toggle sage': [
'Alt+s'
'Toggle sage in email field'
]
'Submit QR': [
'Ctrl+Enter'
'Submit post.'
]
# Thread related
@ -859,6 +888,10 @@ box-shadow: inset 2px 2px 2px rgba(0,0,0,0.2);
'Left'
'Jump to the previous page.'
]
'Open catalog': [
'Shift+c'
'Open the catalog of the current board'
]
# Thread Navigation
'Next thread': [
'Down'

View File

@ -2810,5 +2810,5 @@ textarea,
}"""
Icons =
oneechan: '<%= grunt.file.read("src/img/icons/oneechan.png", {encoding: "base64"}) %>'
"4chan SS": '<%= grunt.file.read("src/img/icons/4chanSS.png", {encoding: "base64"}) %>'
oneechan: '<%= grunt.file.read("src/General/img/icons/oneechan.png", {encoding: "base64"}) %>'
"4chan SS": '<%= grunt.file.read("src/General/img/icons/4chanSS.png", {encoding: "base64"}) %>'

267
src/General/Header.coffee Normal file
View File

@ -0,0 +1,267 @@
Header =
init: ->
@menu = new UI.Menu 'header'
@menuButton = $.el 'span',
className: 'menu-button'
id: 'main-menu'
barFixedToggler = $.el 'label',
innerHTML: '<input type=checkbox name="Fixed Header"> Fixed Header'
headerToggler = $.el 'label',
innerHTML: '<input type=checkbox name="Header auto-hide"> Auto-hide header'
barPositionToggler = $.el 'label',
innerHTML: '<input type=checkbox name="Bottom header"> Bottom header'
customNavToggler = $.el 'label',
innerHTML: '<input type=checkbox name="Custom Board Navigation"> Custom board navigation'
footerToggler = $.el 'label',
innerHTML: "<input type=checkbox #{unless Conf['Bottom Board List'] then 'checked' else ''}> Hide bottom board list"
editCustomNav = $.el 'a',
textContent: 'Edit custom board navigation'
href: 'javascript:;'
@barFixedToggler = barFixedToggler.firstElementChild
@barPositionToggler = barPositionToggler.firstElementChild
@headerToggler = headerToggler.firstElementChild
@footerToggler = footerToggler.firstElementChild
@customNavToggler = customNavToggler.firstElementChild
$.on @menuButton, 'click', @menuToggle
$.on @barFixedToggler, 'change', @toggleBarFixed
$.on @barPositionToggler, 'change', @toggleBarPosition
$.on @headerToggler, 'change', @toggleBarVisibility
$.on @footerToggler, 'change', @toggleFooterVisibility
$.on @customNavToggler, 'change', @toggleCustomNav
$.on editCustomNav, 'click', @editCustomNav
@setBarFixed Conf['Fixed Header']
@setBarVisibility Conf['Header auto-hide']
$.sync 'Fixed Header', Header.setBarFixed
$.sync 'Bottom Header', Header.setBarPosition
$.sync 'Header auto-hide', Header.setBarVisibility
$.event 'AddMenuEntry',
type: 'header'
el: $.el 'span',
textContent: 'Header'
order: 107
subEntries: [
{el: barFixedToggler}
{el: headerToggler}
{el: barPositionToggler}
{el: footerToggler}
{el: customNavToggler}
{el: editCustomNav}
]
$.on window, 'load hashchange', Header.hashScroll
$.on d, 'CreateNotification', @createNotification
$.asap (-> d.body), =>
return unless Main.isThisPageLegit()
# Wait for #boardNavMobile instead of #boardNavDesktop,
# it might be incomplete otherwise.
$.asap (-> $.id('boardNavMobile') or d.readyState is 'complete'), Header.setBoardList
$.prepend d.body, @bar
$.add d.body, Header.hover
@setBarPosition Conf['Bottom Header']
$.ready =>
cs = $.id('settingsWindowLink')
cs.textContent = 'Catalog Settings'
@addShortcut cs if g.VIEW is 'catalog'
bar: $.el 'div',
id: 'header-bar'
notify: $.el 'div',
id: 'notifications'
shortcuts: $.el 'span',
id: 'shortcuts'
hover: $.el 'div',
id: 'hoverUI'
toggle: $.el 'div',
id: 'scroll-marker'
setBoardList: ->
fourchannav = $.id 'boardNavDesktop'
if a = $ "a[href*='/#{g.BOARD}/']", fourchannav
a.className = 'current'
boardList = $.el 'span',
id: 'board-list'
innerHTML: "<span id=custom-board-list></span><span id=full-board-list hidden>[<a href=javascript:; class='hide-board-list-button'> - </a>] #{fourchannav.innerHTML}</span>"
fullBoardList = $ '#full-board-list', boardList
btn = $ '.hide-board-list-button', fullBoardList
$.on btn, 'click', Header.toggleBoardList
$.rm $ '#navtopright', fullBoardList
settings = $.id('navtopright')
$.prepend d.body, settings
$.add settings, Header.menuButton
$.add boardList, fullBoardList
$.add Header.bar, [boardList, Header.shortcuts, Header.notify, Header.toggle]
Header.setCustomNav Conf['Custom Board Navigation']
Header.generateBoardList Conf['boardnav']
$.sync 'Custom Board Navigation', Header.setCustomNav
$.sync 'boardnav', Header.generateBoardList
generateBoardList: (text) ->
list = $ '#custom-board-list', Header.bar
$.rmAll list
return unless text
as = $$('#full-board-list a', Header.bar)
nodes = text.match(/[\w@]+(-(all|title|replace|full|index|catalog|text:"[^"]+"))*|[^\w@]+/g).map (t) ->
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
board = if /^current/.test t
g.BOARD.ID
else
t.match(/^[^-]+/)[0]
for a in as
if a.textContent is board
a = a.cloneNode true
if /-title/.test t
a.textContent = a.title
else if /-replace/.test t
if $.hasClass a, 'current'
a.textContent = a.title
else if /-full/.test t
a.textContent = "/#{board}/ - #{a.title}"
else if /-(index|catalog|text)/.test t
if m = t.match /-(index|catalog)/
a.setAttribute 'data-only', m[1]
a.href = "//boards.4chan.org/#{board}/"
a.href += 'catalog' if m[1] is 'catalog'
if m = t.match /-text:"(.+)"/
a.textContent = m[1]
else if board is '@'
$.addClass a, 'navSmall'
return a
$.tn t
$.add list, nodes
toggleBoardList: ->
{bar} = Header
custom = $ '#custom-board-list', bar
full = $ '#full-board-list', bar
showBoardList = !full.hidden
custom.hidden = !showBoardList
full.hidden = showBoardList
setBarPosition: (bottom) ->
Header.barPositionToggler.checked = bottom
if bottom
$.rmClass doc, 'top'
$.addClass doc, 'bottom'
$.after Header.bar, Header.notify
else
$.rmClass doc, 'bottom'
$.addClass doc, 'top'
$.add Header.bar, Header.notify
Style.padding()
toggleBarPosition: ->
$.event 'CloseMenu'
Header.setBarPosition @checked
Conf['Bottom Header'] = @checked
$.set 'Bottom Header', @checked
setBarFixed: (fixed) ->
Header.barFixedToggler.checked = fixed
if fixed
$.addClass doc, 'fixed'
$.addClass Header.bar, 'dialog'
else
$.rmClass doc, 'fixed'
$.rmClass Header.bar, 'dialog'
toggleBarFixed: ->
$.event 'CloseMenu'
Header.setBarFixed @checked
Conf['Fixed Header'] = @checked
$.set 'Fixed Header', @checked
setBarVisibility: (hide) ->
Header.headerToggler.checked = hide
$.event 'CloseMenu'
(if hide then $.addClass else $.rmClass) Header.bar, 'autohide'
(if hide then $.addClass else $.rmClass) doc, 'autohide'
toggleBarVisibility: (e) ->
return if e.type is 'mousedown' and e.button isnt 0 # not LMB
hide = if @nodeName is 'INPUT'
@checked
else
!$.hasClass Header.bar, 'autohide'
Conf['Header auto-hide'] = hide
$.set 'Header auto-hide', hide
Header.setBarVisibility hide
message = if hide
'The header bar will automatically hide itself.'
else
'The header bar will remain visible.'
new Notification 'info', message, 2
setCustomNav: (show) ->
Header.customNavToggler.checked = show
cust = $ '#custom-board-list', Header.bar
full = $ '#full-board-list', Header.bar
btn = $ '.hide-board-list-button', full
[cust.hidden, full.hidden] = if show
[false, true]
else
[true, false]
toggleCustomNav: ->
$.cb.checked.call @
Header.setCustomNav @checked
editCustomNav: ->
Settings.open 'Advanced'
settings = $.id 'fourchanx-settings'
$('input[name=boardnav]', settings).focus()
hashScroll: ->
return unless (hash = @location.hash) and post = $.id hash[1..]
return if (Get.postFromRoot post).isHidden
Header.scrollToPost post
scrollToPost: (post) ->
{top} = post.getBoundingClientRect()
if Conf['Fixed Header'] and not Conf['Bottom Header']
headRect = Header.bar.getBoundingClientRect()
top += - headRect.top - headRect.height
(if $.engine is 'webkit' then d.body else doc).scrollTop += top
addShortcut: (el) ->
shortcut = $.el 'span',
className: 'shortcut'
$.add shortcut, [$.tn(' ['), el, $.tn(']')]
$.prepend Header.shortcuts, shortcut
menuToggle: (e) ->
Header.menu.toggle e, @, g
createNotification: (e) ->
{type, content, lifetime, cb} = e.detail
notif = new Notification type, content, lifetime
cb notif if cb

View File

@ -75,7 +75,7 @@ Main =
for name, module of features
# c.time "#{name} initialization"
try
do module.init
module.init()
catch err
Main.handleErrors
message: "\"#{name}\" initialization crashed."
@ -99,6 +99,9 @@ Main =
'Settings': Settings
'Announcement Hiding': PSAHiding
'Fourchan thingies': Fourchan
'Emoji': Emoji
'Color User IDs': IDColor
'Remove Spoilers': RemoveSpoilers
'Custom CSS': CustomCSS
'Linkify': Linkify
'Resurrect Quotes': Quotify
@ -183,7 +186,11 @@ Main =
Main.handleErrors errors if errors
Main.callbackNodes Thread, threads
Main.callbackNodes Post, posts
Main.callbackNodesDB Post, posts, ->
$.event '4chanXInitFinished'
Main.checkUpdate()
return
$.event '4chanXInitFinished'
Main.checkUpdate()
@ -206,6 +213,45 @@ Main =
# c.profileEnd callback.name
Main.handleErrors errors if errors
callbackNodesDB: (klass, nodes, cb) ->
queue = []
softTask = ->
task = queue.shift()
func = task[0]
args = Array::slice.call task, 1
func.apply func, args
return unless queue.length
if (queue.length % 7) is 0
setTimeout softTask, 0
else
softTask()
# get the nodes' length only once
len = nodes.length
i = 0
errors = null
func = (node, i) ->
for callback in klass::callbacks
try
callback.cb.call node
catch err
unless errors
errors = []
errors.push
message: "\"#{callback.name}\" crashed on #{klass.name} No.#{node} (/#{node.board}/)."
error: err
# finish
if i is len
Main.handleErrors errors if errors
cb() if cb
while i < len
node = nodes[i]
queue.push [func, node, ++i]
softTask()
addCallback: (e) ->
obj = e.detail
unless typeof obj.callback.name is 'string'

View File

@ -40,7 +40,7 @@ Settings =
Settings.addSection 'Script', Settings.main
Settings.addSection 'Filter', Settings.filter
Settings.addSection 'Sauce', Settings.sauce
Settings.addSection 'Rice', Settings.rice
Settings.addSection 'Advanced', Settings.advanced
Settings.addSection 'Keybinds', Settings.keybinds
$.on d, 'AddSettingsSection', Settings.addSection
@ -68,22 +68,7 @@ Settings =
Settings.dialog = dialog = $.el 'div',
id: 'appchanx-settings'
class: 'dialog'
innerHTML: """
<nav>
<div class=sections-list></div>
<span class='imp-exp-result warning'></span>
<div class=credits>
<a class=export>Export</a> |
<a class=import>Import</a> |
<input type=file style='display: none;'>
<a href='<%= meta.page %>' target=_blank><%= meta.name %></a> |
<a href='<%= meta.repo %>blob/<%= meta.mainBranch %>/CHANGELOG.md' target=_blank>#{g.VERSION}</a> |
<a href='<%= meta.repo %>blob/<%= meta.mainBranch %>/CONTRIBUTING.md#reporting-bugs-and-suggestions' target=_blank>Issues</a> |
<a href=javascript:; class=close title=Close>×</a>
</div>
</nav>
<hr>
<div class=section-container><section></section></div>"""
innerHTML: """<%= grunt.file.read('src/General/html/Settings/Settings.html').replace(/>\s+</g, '><').trim() %>"""
Settings.overlay = overlay = $.el 'div',
id: 'overlay'
@ -306,6 +291,12 @@ Settings =
data.Conf[key] = data.Conf[key].replace(/ctrl|alt|meta/g, (s) -> "#{s[0].toUpperCase()}#{s[1..]}").replace /(^|.+\+)[A-Z]$/g, (s) ->
"Shift+#{s[0...-1]}#{s[-1..].toLowerCase()}"
data.Conf.WatchedThreads = data.WatchedThreads
else if version[0] is '3'
data = Settings.convertSettings data,
'Reply Hiding': 'Reply Hiding Buttons'
'Thread Hiding': 'Thread Hiding Buttons'
'Bottom header': 'Bottom Header'
'Unread Tab Icon': 'Unread Favicon'
$.set data.Conf
convertSettings: (data, map) ->
@ -316,22 +307,7 @@ Settings =
filter: (section) ->
section.innerHTML = """
<select name=filter>
<option value=guide>Guide</option>
<option value=name>Name</option>
<option value=uniqueID>Unique ID</option>
<option value=tripcode>Tripcode</option>
<option value=capcode>Capcode</option>
<option value=email>E-mail</option>
<option value=subject>Subject</option>
<option value=comment>Comment</option>
<option value=flag>Flag</option>
<option value=filename>Filename</option>
<option value=dimensions>Image dimensions</option>
<option value=filesize>Filesize</option>
<option value=MD5>Image MD5</option>
</select>
<div></div>
<%= grunt.file.read('src/General/html/Settings/Filter-select.html').replace(/>\s+</g, '><').trim() %>
"""
select = $ 'select', section
$.on select, 'change', Settings.selectFilter
@ -351,135 +327,27 @@ Settings =
$.add div, ta
return
div.innerHTML = """
<div class=warning #{if Conf['Filter'] then 'hidden' else ''}><code>Filter</code> is disabled.</div>
<p>
Use <a href=https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions>regular expressions</a>, one per line.<br>
Lines starting with a <code>#</code> will be ignored.<br>
For example, <code>/weeaboo/i</code> will filter posts containing the string `<code>weeaboo</code>`, case-insensitive.<br>
MD5 filtering uses exact string matching, not regular expressions.
</p>
<ul>You can use these settings with each regular expression, separate them with semicolons:
<li>
Per boards, separate them with commas. It is global if not specified.<br>
For example: <code>boards:a,jp;</code>.
</li>
<li>
Filter OPs only along with their threads (`only`), replies only (`no`), or both (`yes`, this is default).<br>
For example: <code>op:only;</code>, <code>op:no;</code> or <code>op:yes;</code>.
</li>
<li>
Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`).<br>
For example: <code>stub:yes;</code> or <code>stub:no;</code>.
</li>
<li>
Highlight instead of hiding. You can specify a class name to use with a userstyle.<br>
For example: <code>highlight;</code> or <code>highlight:wallpaper;</code>.
</li>
<li>
Highlighted OPs will have their threads put on top of board pages by default.<br>
For example: <code>top:yes;</code> or <code>top:no;</code>.
</li>
</ul>
<%= grunt.file.read('src/General/html/Settings/Filter-guide.html').replace(/>\s+</g, '><').trim() %>
"""
sauce: (section) ->
section.innerHTML = """
<div class=warning #{if Conf['Sauce'] then 'hidden' else ''}><code>Sauce</code> is disabled.</div>
<div>Lines starting with a <code>#</code> will be ignored.</div>
<div>You can specify a display text by appending <code>;text:[text]</code> to the URL.</div>
<ul>These parameters will be replaced by their corresponding values:
<li><code>%TURL</code>: Thumbnail URL.</li>
<li><code>%URL</code>: Full image URL.</li>
<li><code>%MD5</code>: MD5 hash.</li>
<li><code>%board</code>: Current board.</li>
</ul>
<textarea name=sauces class=field spellcheck=false></textarea>
<%= grunt.file.read('src/General/html/Settings/Sauce.html').replace(/>\s+</g, '><').trim() %>
"""
sauce = $ 'textarea', section
$.get 'sauces', Conf['sauces'], (item) ->
sauce.value = item['sauces']
$.on sauce, 'change', $.cb.value
rice: (section) ->
section.innerHTML = """
<fieldset>
<legend>Archiver</legend>
Select an Archiver for this board:
<select name=archiver></select>
</fieldset>
<fieldset>
<legend>Custom Board Navigation <span class=warning #{if Conf['Custom Board Navigation'] then 'hidden' else ''}>is disabled.</span></legend>
<div><input name=boardnav class=field spellcheck=false></div>
<div>In the following, <code>board</code> can translate to a board ID (<code>a</code>, <code>b</code>, etc...), the current board (<code>current</code>), or the Status/Twitter link (<code>status</code>, <code>@</code>).</div>
<div>
For example:<br>
<code>[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:"Piracy"]</code><br>
will give you<br>
<code>[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]</code><br>
if you are on /g/.
</div>
<div>Board link: <code>board</code></div>
<div>Title link: <code>board-title</code></div>
<div>Board link (Replace with title when on that board): <code>board-replace</code></div>
<div>Full text link: <code>board-full</code></div>
<div>Custom text link: <code>board-text:"VIP Board"</code></div>
<div>Index-only link: <code>board-index</code></div>
<div>Catalog-only link: <code>board-catalog</code></div>
<div>Combinations are possible: <code>board-index-text:"VIP Index"</code></div>
<div>Full board list toggle: <code>toggle-all</code></div>
</fieldset>
<fieldset>
<legend>Time Formatting <span class=warning #{if Conf['Time Formatting'] then 'hidden' else ''}>is disabled.</span></legend>
<div><input name=time class=field spellcheck=false>: <span class=time-preview></span></div>
<div>Supported <a href=//en.wikipedia.org/wiki/Date_%28Unix%29#Formatting>format specifiers</a>:</div>
<div>Day: <code>%a</code>, <code>%A</code>, <code>%d</code>, <code>%e</code></div>
<div>Month: <code>%m</code>, <code>%b</code>, <code>%B</code></div>
<div>Year: <code>%y</code></div>
<div>Hour: <code>%k</code>, <code>%H</code>, <code>%l</code>, <code>%I</code>, <code>%p</code>, <code>%P</code></div>
<div>Minute: <code>%M</code></div>
<div>Second: <code>%S</code></div>
</fieldset>
<fieldset>
<legend>Quote Backlinks formatting <span class=warning #{if Conf['Quote Backlinks'] then 'hidden' else ''}>is disabled.</span></legend>
<div><input name=backlink class=field spellcheck=false>: <span class=backlink-preview></span></div>
</fieldset>
<fieldset>
<legend>File Info Formatting <span class=warning #{if Conf['File Info Formatting'] then 'hidden' else ''}>is disabled.</span></legend>
<div><input name=fileInfo class=field spellcheck=false>: <span class='fileText file-info-preview'></span></div>
<div>Link: <code>%l</code> (truncated), <code>%L</code> (untruncated), <code>%T</code> (Unix timestamp)</div>
<div>Original file name: <code>%n</code> (truncated), <code>%N</code> (untruncated), <code>%t</code> (Unix timestamp)</div>
<div>Spoiler indicator: <code>%p</code></div>
<div>Size: <code>%B</code> (Bytes), <code>%K</code> (KB), <code>%M</code> (MB), <code>%s</code> (4chan default)</div>
<div>Resolution: <code>%r</code> (Displays 'PDF' for PDF files)</div>
</fieldset>
<fieldset>
<legend>Unread Favicon <span class=warning #{if Conf['Unread Favicon'] then 'hidden' else ''}>is disabled.</span></legend>
<select name=favicon>
<option value=ferongr>ferongr</option>
<option value=xat->xat-</option>
<option value=Mayhem>Mayhem</option>
<option value=Original>Original</option>
</select>
<span class=favicon-preview></span>
</fieldset>
<fieldset>
<legend><input type=checkbox name='Custom CSS' #{if Conf['Custom CSS'] then 'checked' else ''}> Custom CSS</legend>
<button id=apply-css>Apply CSS</button>
<textarea name=usercss class=field spellcheck=false #{if Conf['Custom CSS'] then '' else 'disabled'}></textarea>
</fieldset>
"""
advanced: (section) ->
section.innerHTML = """<%= grunt.file.read('src/General/html/Settings/Advanced.html').replace(/>\s+</g, '><').trim() %>"""
items = {}
inputs = {}
for name in ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'usercss']
for name in ['boardnav', 'time', 'backlink', 'fileInfo', 'favicon', 'emojiPos', 'sageEmoji', 'usercss']
input = $ "[name='#{name}']", section
items[name] = Conf[name]
inputs[name] = input
event = if ['favicon', 'usercss'].contains name
event = if ['favicon', 'usercss', 'sageEmoji', 'emojiPos'].contains name
'change'
else
'input'
@ -501,13 +369,14 @@ Settings =
$.get items, (items) ->
for key, val of items
continue if ['usercss', 'emojiPos', 'archiver'].contains key
input = inputs[key]
input.value = val
unless 'usercss' is name
$.on input, event, Settings[key]
Settings[key].call input
return
Rice.nodes section
$.on input, event, Settings[key]
Settings[key].call input
Rice.nodes sectionreturn
$.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
@ -519,7 +388,7 @@ Settings =
@nextElementSibling.textContent = funk Time, new Date()
backlink: ->
@nextElementSibling.textContent = Conf['backlink'].replace /%id/, '123456789'
@nextElementSibling.textContent = @value.replace /%id/, '123456789'
fileInfo: ->
data =
@ -538,13 +407,18 @@ Settings =
favicon: ->
Favicon.switch()
Unread.update() if g.VIEW is 'thread' and Conf['Unread Favicon']
@nextElementSibling.innerHTML = """
$.id('favicon-preview').innerHTML = """
<img src=#{Favicon.default}>
<img src=#{Favicon.unreadSFW}>
<img src=#{Favicon.unreadNSFW}>
<img src=#{Favicon.unreadDead}>
"""
sageEmoji: ->
$.id('sageicon-preview').innerHTML = """
<img src=data:image/png;base64,#{Emoji.sage[@value]}>
"""
togglecss: ->
if $('textarea', @parentNode.parentNode).disabled = !@checked
CustomCSS.rmStyle()
@ -557,12 +431,7 @@ Settings =
keybinds: (section) ->
section.innerHTML = """
<div class=warning #{if Conf['Keybinds'] then 'hidden' else ''}><code>Keybinds</code> are disabled.</div>
<div>Allowed keys: <kbd>a-z</kbd>, <kbd>0-9</kbd>, <kbd>Ctrl</kbd>, <kbd>Shift</kbd>, <kbd>Alt</kbd>, <kbd>Meta</kbd>, <kbd>Enter</kbd>, <kbd>Esc</kbd>, <kbd>Up</kbd>, <kbd>Down</kbd>, <kbd>Right</kbd>, <kbd>Left</kbd>.</div>
<div>Press <kbd>Backspace</kbd> to disable a keybind.</div>
<table><tbody>
<tr><th>Actions</th><th>Keybinds</th></tr>
</tbody></table>
<%= grunt.file.read('src/General/html/Settings/Keybinds.html').replace(/>\s+</g, '><').trim() %>
"""
tbody = $ 'tbody', section
items = {}
@ -1116,4 +985,4 @@ Settings =
userThemes = item["userThemes"]
userThemes[@id] = Themes[@id]
$.set 'userThemes', userThemes
$.rm @
$.rm @

View File

@ -54,7 +54,7 @@ UI = do ->
menu = @makeMenu()
currentMenu = menu
lastToggledButton = button
@entries.sort (first, second) ->
first.order - second.order
@ -226,6 +226,14 @@ UI = do ->
screenWidth: screenWidth
isTouching: isTouching
}
[o.topBorder, o.bottomBorder] = if Conf['Header auto-hide']
[0, 0]
else if Conf['Bottom Header']
[0, Header.bar.getBoundingClientRect().height]
else
[Header.bar.getBoundingClientRect().height, 0]
if isTouching
o.identifier = e.identifier
o.move = touchmove.bind o
@ -256,9 +264,9 @@ UI = do ->
left / @screenWidth * 100 + '%'
top = clientY - @dy
top = if top < 10
0
else if @height - top < 10
top = if top < (10 + @topBorder)
@topBorder + 'px'
else if @height - top < (10 + @bottomBorder)
null
else
top / @screenHeight * 100 + '%'
@ -267,8 +275,9 @@ UI = do ->
0
else
null
bottom = if top is null
0
@bottomBorder + 'px'
else
null

View File

@ -78,7 +78,7 @@ body > a[style="cursor: pointer; float: right;"]::after {
#boardNavDesktopFoot {
top: 16px !important;
}
#{if _conf['Boards Navigation'] is 'Top' or _conf['Boards Navigation'] is 'Sticky top' then '#header-bar' else if _conf['Pagination'] is 'top' or _conf['Pagination'] is 'sticky top' then '.pagelist'} {
.fixed.top #header-bar#{if _conf['Pagination'] is 'top' or _conf['Pagination'] is 'sticky top' then ',\n.pagelist' else ''} {
#{if _conf['4chan SS Navigation']
"padding-#{align}: #{iconOffset}px;"
else

View File

@ -78,7 +78,7 @@ div.navLinks > a:first-of-type::after {
width: #{233 + Style.sidebarOffset.W}px !important;
#{align}: 18px !important;
}
#{if _conf['Boards Navigation'] is 'Top' or _conf['Boards Navigation'] is 'Sticky top' then '#header-bar' else if _conf['Pagination'] is 'top' or _conf['Pagination'] is 'sticky top' then '.pagelist'} {
.fixed.top #header-bar#{if _conf['Pagination'] is 'top' or _conf['Pagination'] is 'sticky top' then ',\n.pagelist' else ''} {
#{if _conf['4chan SS Navigation']
"padding-#{align}: #{iconOffset}px;"
else

View File

@ -1,5 +1,6 @@
/* Cleanup */
#absbot,
#boardNavDesktop,
#delPassword,
#delform > hr:last-of-type,
#navbotright,
@ -168,6 +169,9 @@ else "
" else ""}
text-align: #{_conf["Navigation Alignment"]};
}
.fixed #header-bar.autohide {
z-index: 24;
}
.fixed #header-bar {
position: fixed;
}
@ -500,31 +504,6 @@ else "
outline: none;
z-index: 22;
}
/* Updater */
#updater {
position: fixed;
z-index: 10;
padding: 0 1px 1px;
#{if _conf["Rounded Edges"] then "border-radius: 3px;" else ""}
}
#updater:hover {
z-index: 30;
}
#updater:not(:hover) > div:not(.move) {
display: none;
}
#updater input {
text-align: right;
}
#updater .field {
width: 50px;
}
/* Stats */
#thread-stats {
position: fixed;
#{if _conf["Rounded Edges"] then "border-radius: 3px;" else ""}
z-index: 10;
}
/* Image Expansion */
.fit-width .full-image {
max-width: 100%;
@ -1297,6 +1276,9 @@ input:not([type=radio]) {
vertical-align: bottom;
padding: 0 1px;
}
.selectrice {
padding-right: 1.6em;
}
#qr textarea {
min-width: 100%;
}
@ -1521,6 +1503,14 @@ a:only-of-type > .remove {
#{if _conf["Single Column Mode"] then "margin: 0 auto 6px;" else "margin: 0 3px 6px;\n display: inline-block;"}
border: 0;
}
#appchanx-settings .section-advanced fieldset {
display: block;
margin: 0 auto 6px;
}
.section-advanced .selectrice {
display: inline-block;
clear: both;
}
.section-container {
overflow: auto;
position: absolute;
@ -1554,13 +1544,13 @@ a:only-of-type > .remove {
}
.section-script fieldset > div,
.section-style fieldset > div,
.section-rice fieldset > div {
.section-advanced fieldset > div {
overflow: visible;
padding: 0 5px 0 7px;
}
#appchanx-settings tr:nth-of-type(2n+1),
.section-script fieldset > div:nth-of-type(2n+1),
.section-rice fieldset > div:nth-of-type(2n+1),
.section-advanced fieldset > div:nth-of-type(2n+1),
.section-style fieldset > div:nth-of-type(2n+1),
.section-keybinds tr:nth-of-type(2n+1),
#selectrice li:nth-of-type(2n+1) {
@ -1820,10 +1810,6 @@ opacity: 0;
#info .btn-wrap {
display: inline-block;
}
#settings .selectrice {
width: 100px;
display: inline-block;
}
#post-preview {
position: absolute;
z-index: 22;

View File

@ -103,7 +103,6 @@ s:not(:hover) {
#appchanx-settings,
#qrtab,
#{if _conf["Post Form Decorations"] then "#qr," else ""}
#updater,
input[type="submit"],
input[value="Report"],
span[style="left: 5px; position: absolute;"] a {
@ -227,9 +226,8 @@ a[style="cursor: pointer; float: right;"] ~ div[style^="width: 100%;"] > table {
color: #{theme["Timestamps"]} !important;
}
#fs_status a,
#updater #count:not(.new)::after,
#updater #update-status:not(.new)::after,
#showQR,
#updater,
.abbr,
.boxbar,
.boxcontent,
@ -280,7 +278,6 @@ textarea {
.selectrice::after {
border-top: .45em solid #{theme["Inputs"]};
}
#updater input,
.bd {
background: #{theme["Buttons Background"]};
border: 1px solid #{theme["Buttons Border"]};

View File

@ -116,7 +116,7 @@ a.useremail[href*="SAGE"]:last-of-type::#{_conf["Sage Highlight Position"]} {
a.useremail[href*="sage"]:last-of-type::#{_conf["Sage Highlight Position"]},
a.useremail[href*="Sage"]:last-of-type::#{_conf["Sage Highlight Position"]},
a.useremail[href*="SAGE"]:last-of-type::#{_conf["Sage Highlight Position"]} {
content: url("data:image/png;base64,<%= grunt.file.read("src/img/emoji/sage.png", {encoding: "base64"}) %>");
content: url("data:image/png;base64,<%= grunt.file.read("src/General/img/emoji/sage.png", {encoding: "base64"}) %>");
vertical-align: top;
margin-#{if _conf["Sage Highlight Position"] is "before" then "right" else "left"}: #{parseInt _conf['Emoji Spacing']}px;
}\n

View File

@ -0,0 +1,37 @@
<div id=qrtab class=move>
<input type=checkbox id=autohide title=Auto-hide> Post Form
<a href=javascript:; class=close title=Close>×</a>
</div>
<form>
<div class=persona>
<input id=dump-button type=button title='Dump list' value=+ tabindex=0>
<input name=name data-name=name title=Name placeholder=Name class=field size=1 tabindex=10>
<input name=email data-name=email title=E-mail placeholder=E-mail class=field size=1 tabindex=20>
<input name=sub data-name=sub title=Subject placeholder=Subject class=field size=1 tabindex=30>
</div>
<div class=textarea>
<textarea data-name=com title=Comment placeholder=Comment class=field tabindex=40></textarea>
<span id=char-count></span>
</div>
<div id=dump-list-container>
<div id=dump-list></div>
<a id=add-post href=javascript:; title="Add a post" tabindex=50>+</a>
</div>
<div id=file-n-submit>
<span id=qr-filename-container class=field tabindex=60>
<span id=qr-no-file>No selected file</span>
<span id=qr-filename></span>
<a id=qr-filerm href=javascript:; title='Remove file' tabindex=80>×</a>
</span>
<input type=submit tabindex=70>
</div>
<input type=file multiple>
<div id=qr-thread-select>
<select title='Create a new thread / Reply'>
<option value=new>New thread</option>
</select>
</div>
<label id=qr-spoiler-label>
<input type=checkbox id=qr-file-spoiler title='Spoiler image' tabindex=90>Spoiler?
</label>
</form>

View File

@ -0,0 +1,101 @@
<fieldset>
<legend>Archiver</legend>
<div>
Select an Archiver for this board:
<select name=archiver></select>
</div>
</fieldset>
<fieldset>
<legend>Custom Board Navigation <span class=warning #{if Conf['Custom Board Navigation'] then 'hidden' else ''}>is disabled.</span></legend>
<div><input name=boardnav class=field spellcheck=false></div>
<div>In the following, <code>board</code> can translate to a board ID (<code>a</code>, <code>b</code>, etc...), the current board (<code>current</code>), or the Status/Twitter link (<code>status</code>, <code>@</code>).</div>
<div>
For example:<br>
<code>[ toggle-all ] [current-title] [g-title / a-title / jp-title] [x / wsg / h] [t-text:"Piracy"]</code><br>
will give you<br>
<code>[ + ] [Technology] [Technology / Anime & Manga / Otaku Culture] [x / wsg / h] [Piracy]</code><br>
if you are on /g/.
</div>
<div>Board link: <code>board</code></div>
<div>Title link: <code>board-title</code></div>
<div>Board link (Replace with title when on that board): <code>board-replace</code></div>
<div>Full text link: <code>board-full</code></div>
<div>Custom text link: <code>board-text:"VIP Board"</code></div>
<div>Index-only link: <code>board-index</code></div>
<div>Catalog-only link: <code>board-catalog</code></div>
<div>Combinations are possible: <code>board-index-text:"VIP Index"</code></div>
<div>Full board list toggle: <code>toggle-all</code></div>
</fieldset>
<fieldset>
<legend>Time Formatting <span class=warning #{if Conf['Time Formatting'] then 'hidden' else ''}>is disabled.</span></legend>
<div><input name=time class=field spellcheck=false>: <span class=time-preview></span></div>
<div>Supported <a href=//en.wikipedia.org/wiki/Date_%28Unix%29#Formatting>format specifiers</a>:</div>
<div>Day: <code>%a</code>, <code>%A</code>, <code>%d</code>, <code>%e</code></div>
<div>Month: <code>%m</code>, <code>%b</code>, <code>%B</code></div>
<div>Year: <code>%y</code></div>
<div>Hour: <code>%k</code>, <code>%H</code>, <code>%l</code>, <code>%I</code>, <code>%p</code>, <code>%P</code></div>
<div>Minute: <code>%M</code></div>
<div>Second: <code>%S</code></div>
</fieldset>
<fieldset>
<legend>Quote Backlinks formatting <span class=warning #{if Conf['Quote Backlinks'] then 'hidden' else ''}>is disabled.</span></legend>
<div><input name=backlink class=field spellcheck=false>: <span class=backlink-preview></span></div>
</fieldset>
<fieldset>
<legend>File Info Formatting <span class=warning #{if Conf['File Info Formatting'] then 'hidden' else ''}>is disabled.</span></legend>
<div><input name=fileInfo class=field spellcheck=false>: <span class='fileText file-info-preview'></span></div>
<div>Link: <code>%l</code> (truncated), <code>%L</code> (untruncated), <code>%T</code> (Unix timestamp)</div>
<div>Original file name: <code>%n</code> (truncated), <code>%N</code> (untruncated), <code>%t</code> (Unix timestamp)</div>
<div>Spoiler indicator: <code>%p</code></div>
<div>Size: <code>%B</code> (Bytes), <code>%K</code> (KB), <code>%M</code> (MB), <code>%s</code> (4chan default)</div>
<div>Resolution: <code>%r</code> (Displays 'PDF' for PDF files)</div>
</fieldset>
<fieldset>
<legend>Unread Favicon <span class=warning #{if Conf['Unread Favicon'] then 'hidden' else ''}>is disabled.</span></legend>
<div>
<select name=favicon>
<option value=ferongr>ferongr</option>
<option value=xat->xat-</option>
<option value=Mayhem>Mayhem</option>
<option value=4chanJS>4chanJS</option>
<option value=Original>Original</option>
</select>
<span id=favicon-preview></span>
</div>
</fieldset>
<fieldset>
<legend>Emoji <span class=warning #{if Conf['Emoji'] then 'hidden' else ''}>is disabled.</span></legend>
<div>
Sage Icon: <select name=sageEmoji>
<option value="4chan SS">4chan SS</option>
<option value="appchan">appchan</option>
</select>
<span id=sageicon-preview></span>
</div>
<div>
Position: <select name=emojiPos>
<option value="before">Before</option>
<option value="after">After</option>
</select>
</div>
</fieldset>
<fieldset>
<legend>Thread Updater <span class=warning #{if Conf['Thread Updater'] then 'hidden' else ''}>is disabled.</span></legend>
<div>
Interval: <input type=number name=Interval class=field min=1 value=#{Conf['Interval']}>
</div>
</fieldset>
<fieldset>
<legend><input type=checkbox name='Custom CSS' #{if Conf['Custom CSS'] then 'checked' else ''}> Custom CSS</legend>
<div>
<button id=apply-css>Apply CSS</button>
<textarea name=usercss class=field spellcheck=false #{if Conf['Custom CSS'] then '' else 'disabled'}></textarea>
</div>
</fieldset>

View File

@ -0,0 +1,29 @@
<div class=warning #{if Conf['Filter'] then 'hidden' else ''}><code>Filter</code> is disabled.</div>
<p>
Use <a href=https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions>regular expressions</a>, one per line.<br>
Lines starting with a <code>#</code> will be ignored.<br>
For example, <code>/weeaboo/i</code> will filter posts containing the string `<code>weeaboo</code>`, case-insensitive.<br>
MD5 filtering uses exact string matching, not regular expressions.
</p>
<ul>You can use these settings with each regular expression, separate them with semicolons:
<li>
Per boards, separate them with commas. It is global if not specified.<br>
For example: <code>boards:a,jp;</code>.
</li>
<li>
Filter OPs only along with their threads (`only`), replies only (`no`), or both (`yes`, this is default).<br>
For example: <code>op:only;</code>, <code>op:no;</code> or <code>op:yes;</code>.
</li>
<li>
Overrule the `Show Stubs` setting if specified: create a stub (`yes`) or not (`no`).<br>
For example: <code>stub:yes;</code> or <code>stub:no;</code>.
</li>
<li>
Highlight instead of hiding. You can specify a class name to use with a userstyle.<br>
For example: <code>highlight;</code> or <code>highlight:wallpaper;</code>.
</li>
<li>
Highlighted OPs will have their threads put on top of board pages by default.<br>
For example: <code>top:yes;</code> or <code>top:no;</code>.
</li>
</ul>

View File

@ -0,0 +1,16 @@
<select name=filter>
<option value=guide>Guide</option>
<option value=name>Name</option>
<option value=uniqueID>Unique ID</option>
<option value=tripcode>Tripcode</option>
<option value=capcode>Capcode</option>
<option value=email>E-mail</option>
<option value=subject>Subject</option>
<option value=comment>Comment</option>
<option value=flag>Flag</option>
<option value=filename>Filename</option>
<option value=dimensions>Image dimensions</option>
<option value=filesize>Filesize</option>
<option value=MD5>Image MD5</option>
</select>
<div></div>

View File

@ -0,0 +1,6 @@
<div class=warning #{if Conf['Keybinds'] then 'hidden' else ''}><code>Keybinds</code> are disabled.</div>
<div>Allowed keys: <kbd>a-z</kbd>, <kbd>0-9</kbd>, <kbd>Ctrl</kbd>, <kbd>Shift</kbd>, <kbd>Alt</kbd>, <kbd>Meta</kbd>, <kbd>Enter</kbd>, <kbd>Esc</kbd>, <kbd>Up</kbd>, <kbd>Down</kbd>, <kbd>Right</kbd>, <kbd>Left</kbd>.</div>
<div>Press <kbd>Backspace</kbd> to disable a keybind.</div>
<table><tbody>
<tr><th>Actions</th><th>Keybinds</th></tr>
</tbody></table>

View File

@ -0,0 +1,10 @@
<div class=warning #{if Conf['Sauce'] then 'hidden' else ''}><code>Sauce</code> is disabled.</div>
<div>Lines starting with a <code>#</code> will be ignored.</div>
<div>You can specify a display text by appending <code>;text:[text]</code> to the URL.</div>
<ul>These parameters will be replaced by their corresponding values:
<li><code>%TURL</code>: Thumbnail URL.</li>
<li><code>%URL</code>: Full image URL.</li>
<li><code>%MD5</code>: MD5 hash.</li>
<li><code>%board</code>: Current board.</li>
</ul>
<textarea name=sauces class=field spellcheck=false></textarea>

View File

@ -0,0 +1,15 @@
<nav>
<div class=sections-list></div>
<span class='imp-exp-result warning'></span>
<div class=credits>
<a class=export>Export</a> |
<a class=import>Import</a> |
<input type=file style='display: none;'>
<a href='<%= meta.page %>' target=_blank><%= meta.name %></a> |
<a href='<%= meta.repo %>blob/<%= meta.mainBranch %>/CHANGELOG.md' target=_blank>#{g.VERSION}</a> |
<a href='<%= meta.repo %>blob/<%= meta.mainBranch %>/CONTRIBUTING.md#reporting-bugs-and-suggestions' target=_blank>Issues</a> |
<a href=javascript:; class=close title=Close>×</a>
</div>
</nav>
<hr>
<div class=section-container><section></section></div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

View File

Before

Width:  |  Height:  |  Size: 659 B

After

Width:  |  Height:  |  Size: 659 B

View File

Before

Width:  |  Height:  |  Size: 912 B

After

Width:  |  Height:  |  Size: 912 B

View File

Before

Width:  |  Height:  |  Size: 567 B

After

Width:  |  Height:  |  Size: 567 B

View File

Before

Width:  |  Height:  |  Size: 987 B

After

Width:  |  Height:  |  Size: 987 B

View File

Before

Width:  |  Height:  |  Size: 858 B

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 B

View File

Before

Width:  |  Height:  |  Size: 559 B

After

Width:  |  Height:  |  Size: 559 B

View File

Before

Width:  |  Height:  |  Size: 631 B

After

Width:  |  Height:  |  Size: 631 B

View File

Before

Width:  |  Height:  |  Size: 1021 B

After

Width:  |  Height:  |  Size: 1021 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 882 B

After

Width:  |  Height:  |  Size: 882 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 231 B

After

Width:  |  Height:  |  Size: 231 B

View File

Before

Width:  |  Height:  |  Size: 1006 B

After

Width:  |  Height:  |  Size: 1006 B

View File

Before

Width:  |  Height:  |  Size: 1012 B

After

Width:  |  Height:  |  Size: 1012 B

View File

Before

Width:  |  Height:  |  Size: 1002 B

After

Width:  |  Height:  |  Size: 1002 B

View File

Before

Width:  |  Height:  |  Size: 820 B

After

Width:  |  Height:  |  Size: 820 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 668 B

After

Width:  |  Height:  |  Size: 668 B

View File

Before

Width:  |  Height:  |  Size: 884 B

After

Width:  |  Height:  |  Size: 884 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 797 B

After

Width:  |  Height:  |  Size: 797 B

View File

Before

Width:  |  Height:  |  Size: 830 B

After

Width:  |  Height:  |  Size: 830 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 659 B

View File

Before

Width:  |  Height:  |  Size: 934 B

After

Width:  |  Height:  |  Size: 934 B

View File

Before

Width:  |  Height:  |  Size: 339 B

After

Width:  |  Height:  |  Size: 339 B

View File

Before

Width:  |  Height:  |  Size: 912 B

After

Width:  |  Height:  |  Size: 912 B

View File

Before

Width:  |  Height:  |  Size: 850 B

After

Width:  |  Height:  |  Size: 850 B

View File

Before

Width:  |  Height:  |  Size: 820 B

After

Width:  |  Height:  |  Size: 820 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 625 B

After

Width:  |  Height:  |  Size: 625 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

View File

Before

Width:  |  Height:  |  Size: 346 B

After

Width:  |  Height:  |  Size: 346 B

View File

Before

Width:  |  Height:  |  Size: 456 B

After

Width:  |  Height:  |  Size: 456 B

View File

Before

Width:  |  Height:  |  Size: 323 B

After

Width:  |  Height:  |  Size: 323 B

View File

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 450 B

View File

Before

Width:  |  Height:  |  Size: 321 B

After

Width:  |  Height:  |  Size: 321 B

View File

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

View File

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 170 B

View File

Before

Width:  |  Height:  |  Size: 232 B

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

View File

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 170 B

View File

Before

Width:  |  Height:  |  Size: 232 B

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

View File

Before

Width:  |  Height:  |  Size: 170 B

After

Width:  |  Height:  |  Size: 170 B

Some files were not shown because too many files have changed in this diff Show More