Browse Source

Merge branch 'master' of https://github.com/vichan-devel/vichan

pull/40/head
czaks 8 years ago
parent
commit
c53f13bf90
  1. 6
      .gitignore
  2. 19
      README.md
  3. 1
      banned.php
  4. 35
      inc/api.php
  5. 27
      inc/cache.php
  6. 63
      inc/config.php
  7. 7
      inc/display.php
  8. 698
      inc/functions.php
  9. 5
      inc/image.php
  10. BIN
      inc/lib/geoip/GeoIPv6.dat
  11. 7
      inc/lib/webm/README.md
  12. 55
      inc/lib/webm/ffmpeg.php
  13. 19
      inc/lib/webm/posthandler.php
  14. 25
      inc/mod/pages.php
  15. 16
      js/ajax.js
  16. 82
      js/catalog-search.js
  17. 4
      js/expand-video.js
  18. 1
      js/favorites.js
  19. 191
      js/file-selector.js
  20. 2
      js/forced-anon.js
  21. 165
      js/gallery-view.js
  22. 4
      js/hide-images.js
  23. 182
      js/image-hover.js
  24. 2
      js/live-index.js
  25. 2
      js/no-animated-gif.js
  26. 116
      js/own-board.js
  27. 11
      js/quick-reply.js
  28. 116
      js/thread-stats.js
  29. 2
      js/toggle-images.js
  30. 48
      js/treeview.js
  31. 2
      js/upload-selection.js
  32. 2
      js/wPaint
  33. 9
      js/watch.js
  34. 9
      js/wpaint.js
  35. 7
      mod.php
  36. 81
      post.php
  37. 216
      smart_build.php
  38. 2
      stylesheets/burichan.css
  39. 2
      stylesheets/caffe.css
  40. 8
      stylesheets/confraria.css
  41. 18
      stylesheets/dark.css
  42. 24
      stylesheets/dark_roach.css
  43. 4
      stylesheets/favela.css
  44. 10
      stylesheets/ferus.css
  45. 542
      stylesheets/font-awesome/css/font-awesome.css
  46. 4
      stylesheets/font-awesome/css/font-awesome.min.css
  47. BIN
      stylesheets/font-awesome/fonts/FontAwesome.otf
  48. BIN
      stylesheets/font-awesome/fonts/fontawesome-webfont.eot
  49. 1064
      stylesheets/font-awesome/fonts/fontawesome-webfont.svg
  50. BIN
      stylesheets/font-awesome/fonts/fontawesome-webfont.ttf
  51. BIN
      stylesheets/font-awesome/fonts/fontawesome-webfont.woff
  52. BIN
      stylesheets/font-awesome/fonts/fontawesome-webfont.woff2
  53. 34
      stylesheets/font-awesome/less/animated.less
  54. 9
      stylesheets/font-awesome/less/bordered-pulled.less
  55. 8
      stylesheets/font-awesome/less/core.less
  56. 4
      stylesheets/font-awesome/less/font-awesome.less
  57. 177
      stylesheets/font-awesome/less/icons.less
  58. 2
      stylesheets/font-awesome/less/list.less
  59. 14
      stylesheets/font-awesome/less/mixins.less
  60. 11
      stylesheets/font-awesome/less/path.less
  61. 11
      stylesheets/font-awesome/less/rotated-flipped.less
  62. 179
      stylesheets/font-awesome/less/variables.less
  63. 34
      stylesheets/font-awesome/scss/_animated.scss
  64. 9
      stylesheets/font-awesome/scss/_bordered-pulled.scss
  65. 8
      stylesheets/font-awesome/scss/_core.scss
  66. 177
      stylesheets/font-awesome/scss/_icons.scss
  67. 14
      stylesheets/font-awesome/scss/_mixins.scss
  68. 3
      stylesheets/font-awesome/scss/_path.scss
  69. 11
      stylesheets/font-awesome/scss/_rotated-flipped.scss
  70. 179
      stylesheets/font-awesome/scss/_variables.scss
  71. 4
      stylesheets/font-awesome/scss/font-awesome.scss
  72. 19
      stylesheets/futaba+vichan.css
  73. 4
      stylesheets/futaba-light.css
  74. 4
      stylesheets/futaba.css
  75. 4
      stylesheets/gentoochan.css
  76. 4
      stylesheets/jungle.css
  77. 22
      stylesheets/luna.css
  78. 8
      stylesheets/miku.css
  79. 8
      stylesheets/nigrachan.css
  80. 8
      stylesheets/notsuba.css
  81. 6
      stylesheets/novo_jungle.css
  82. 2
      stylesheets/photon.css
  83. 4
      stylesheets/piwnichan.css
  84. 2
      stylesheets/ricechan.css
  85. 188
      stylesheets/style.css
  86. 4
      stylesheets/szalet.css
  87. 10
      stylesheets/terminal2.css
  88. 2
      stylesheets/testorange.css
  89. 2
      stylesheets/v8ch.css
  90. 18
      stylesheets/wasabi.css
  91. 4
      stylesheets/yotsuba.css
  92. 15
      templates/fileboard.html
  93. 2
      templates/generic_page.html
  94. 2
      templates/index.html
  95. 2
      templates/main.js
  96. 4
      templates/mod/dashboard.html
  97. 2
      templates/mod/recent_posts.html
  98. 2
      templates/page.html
  99. 6
      templates/post/image.html
  100. 2
      templates/post/image_identification.html

6
.gitignore

@ -38,6 +38,12 @@ Thumbs.db
*.orig
*~
# tmp filesystem
/tmp/cache/*
/tmp/locks/*
!/tmp/cache/.gitkeep
!/tmp/locks/.gitkeep
#vichan custom
favicon.ico
/static/spoiler.png

19
README.md

@ -6,14 +6,16 @@ About
vichan is a free light-weight, fast, highly configurable and user-friendly
imageboard software package. It is written in PHP and has few dependencies.
vichan is a fork of [Tinyboard](http://tinyboard.org/), a great imageboard package, actively
building on it and adding a lot of features and other improvements.
vichan is a fork of (now defunc'd) [Tinyboard](http://github.com/savetheinternet/Tinyboard),
a great imageboard package, actively building on it and adding a lot of features and other
improvements.
Support and announcements: https://int.vichan.net/devel/
Support and announcements: https://engine.vichan.net/
Requirements
------------
1. PHP >= 5.4 (we still try to keep compatibility with php 5.3 as much as possible)
PHP 7.0 is explicitly supported.
2. MySQL/MariaDB server
3. [mbstring](http://www.php.net/manual/en/mbstring.installation.php)
4. [PHP GD](http://www.php.net/manual/en/intro.image.php)
@ -41,7 +43,7 @@ If you need help developing a patch, please join our IRC channel.
Installation
-------------
1. Download and extract Tinyboard to your web directory or get the latest
1. Download and extract vichan to your web directory or get the latest
development version with:
git clone git://github.com/vichan-devel/vichan.git
@ -64,7 +66,7 @@ backup your ```inc/instance-config.php```, replace all your files in place
(don't remove boards etc.), then put ```inc/instance-config.php``` back and
finally run ```install.php```.
To migrate from a Kusaba X board:
To migrate from a Kusaba X board, use http://github.com/vichan-devel/Tinyboard-Migration
Support
--------
@ -84,15 +86,12 @@ find support from a variety of sources:
vichan is based on a Tinyboard, so both engines have very much in common. These
links may be helpful for you as well:
* Tinyboard documentation can be found [here](http://tinyboard.org/docs/).
* You can join Tinyboard's IRC channel for support and general queries:
[irc.datnode.net #tinyboard](irc://irc.datnode.net/tinyboard).
* You may find help at [tinyboard.org](http://tinyboard.org/#help).
* Tinyboard documentation can be found [here](https://web.archive.org/web/20121016074303/http://tinyboard.org/docs/?p=Main_Page).
Donations
---------
Do you like our work? You can motivate us financially to do better ;)
* Bitcoin: [![tip for next commit](http://tip4commit.com/projects/708.svg)](http://tip4commit.com/projects/708)
* Bitcoin: 1GjZEdLaTQ8JWVFGZW921Yv4x59f9oiZME
You can also ask us to develop some feature specially for you <3. Join our IRC
channel and ask for a quote (there are a few of us, who work with the codebase

1
banned.php

@ -1,5 +1,6 @@
<?php
require_once 'inc/functions.php';
require_once 'inc/bans.php';
checkBan();
print "<!doctype html><html><head><meta charset='utf-8'><title>"._("Banned?")."</title></head><body>";
print "<h1>"._("You are not banned.")."</h1>";

35
inc/api.php

@ -33,6 +33,7 @@ class Api {
'sticky' => 'sticky',
'locked' => 'locked',
'bump' => 'last_modified',
'embed' => 'embed',
);
$this->threadsPageFields = array(
@ -85,11 +86,22 @@ class Api {
}
}
private function translateFile($file, $post, &$apiPost) {
$this->translateFields($this->fileFields, $file, $apiPost);
$apiPost['filename'] = @substr($file->name, 0, strrpos($file->name, '.'));
$dotPos = strrpos($file->file, '.');
$apiPost['ext'] = substr($file->file, $dotPos);
$apiPost['tim'] = substr($file->file, 0, $dotPos);
$apiPost['md5'] = base64_encode(hex2bin($post->filehash));
}
private function translatePost($post, $threadsPage = false) {
global $config, $board;
$apiPost = array();
$fields = $threadsPage ? $this->threadsPageFields : $this->postFields;
$this->translateFields($fields, $post, $apiPost);
if (isset($config['poster_ids']) && $config['poster_ids']) $apiPost['id'] = poster_id($post->ip, $post->thread, $board['uri']);
if ($threadsPage) return $apiPost;
// Handle country field
@ -104,16 +116,27 @@ class Api {
}
}
if ($config['slugify'] && !$post->thread) {
$apiPost['semantic_url'] = $post->slug;
}
// Handle files
// Note: 4chan only supports one file, so only the first file is taken into account for 4chan-compatible API.
if (isset($post->files) && $post->files && !$threadsPage) {
$file = $post->files[0];
$this->translateFields($this->fileFields, $file, $apiPost);
$apiPost['filename'] = substr($file->name, 0, strrpos($file->name, '.'));
$dotPos = strrpos($file->file, '.');
$apiPost['ext'] = substr($file->file, $dotPos);
$apiPost['tim'] = substr($file->file, 0, $dotPos);
$apiPost['md5'] = base64_encode(hex2bin($post->filehash));
$this->translateFile($file, $post, $apiPost);
if (sizeof($post->files) > 1) {
$extra_files = array();
foreach ($post->files as $i => $f) {
if ($i == 0) continue;
$extra_file = array();
$this->translateFile($f, $post, $extra_file);
$extra_files[] = $extra_file;
}
$apiPost['extra_files'] = $extra_files;
}
}
return $apiPost;

27
inc/cache.php

@ -50,6 +50,17 @@ class Cache {
case 'php':
$data = isset(self::$cache[$key]) ? self::$cache[$key] : false;
break;
case 'fs':
$key = str_replace('/', '::', $key);
$key = str_replace("\0", '', $key);
if (!file_exists('tmp/cache/'.$key)) {
$data = false;
}
else {
$data = file_get_contents('tmp/cache/'.$key);
$data = json_decode($data, true);
}
break;
case 'redis':
if (!self::$cache)
self::init();
@ -87,6 +98,11 @@ class Cache {
case 'xcache':
xcache_set($key, $value, $expires);
break;
case 'fs':
$key = str_replace('/', '::', $key);
$key = str_replace("\0", '', $key);
file_put_contents('tmp/cache/'.$key, json_encode($value));
break;
case 'php':
self::$cache[$key] = $value;
break;
@ -113,6 +129,11 @@ class Cache {
case 'xcache':
xcache_unset($key);
break;
case 'fs':
$key = str_replace('/', '::', $key);
$key = str_replace("\0", '', $key);
@unlink('tmp/cache/'.$key);
break;
case 'php':
unset(self::$cache[$key]);
break;
@ -134,6 +155,12 @@ class Cache {
case 'php':
self::$cache = array();
break;
case 'fs':
$files = glob('tmp/cache/*');
foreach ($files as $file) {
unlink($file);
}
break;
case 'redis':
if (!self::$cache)
self::init();

63
inc/config.php

@ -115,7 +115,7 @@
* http://tinyboard.org/docs/index.php?p=Config/Cache
*/
$config['cache']['enabled'] = false;
$config['cache']['enabled'] = 'php';
// $config['cache']['enabled'] = 'xcache';
// $config['cache']['enabled'] = 'apc';
// $config['cache']['enabled'] = 'memcached';
@ -137,6 +137,11 @@
// Tinyboard to use.
$config['cache']['redis'] = array('localhost', 6379, '', 1);
// EXPERIMENTAL: Should we cache configs? Warning: this changes board behaviour, i'd say, a lot.
// If you have any lambdas/includes present in your config, you should move them to instance-functions.php
// (this file will be explicitly loaded during cache hit, but not during cache miss).
$config['cache_config'] = false;
/*
* ====================
* Cookie settings
@ -277,7 +282,8 @@
'file_url',
'json_response',
'user_flag',
'no_country'
'no_country',
'tag'
);
// Enable reCaptcha to make spam even harder. Rarely necessary.
@ -290,6 +296,12 @@
// Ability to lock a board for normal users and still allow mods to post. Could also be useful for making an archive board
$config['board_locked'] = false;
// If poster's proxy supplies X-Forwarded-For header, check if poster's real IP is banned.
$config['proxy_check'] = false;
// If poster's proxy supplies X-Forwarded-For header, save it for further inspection and/or filtering.
$config['proxy_save'] = false;
/*
* Custom filters detect certain posts and reject/ban accordingly. They are made up of a condition and an
* action (for when ALL conditions are met). As every single post has to be put through each filter,
@ -538,6 +550,9 @@
// When true, the sage won't be displayed
$config['hide_sage'] = false;
// Don't display user's email when it's not "sage"
$config['hide_email'] = false;
// Attach country flags to posts.
$config['country_flags'] = false;
@ -570,6 +585,9 @@
// Use semantic URLs for threads, like /b/res/12345/daily-programming-thread.html
$config['slugify'] = false;
// Max size for slugs
$config['slug_max_size'] = 80;
/*
* ====================
* Ban settings
@ -610,13 +628,10 @@
$config['markup'][] = array("/\*\*(.+?)\*\*/", "<span class=\"spoiler\">\$1</span>");
$config['markup'][] = array("/^[ |\t]*==(.+?)==[ |\t]*$/m", "<span class=\"heading\">\$1</span>");
// Highlight PHP code wrapped in <code> tags (PHP 5.3+)
// $config['markup'][] = array(
// '/^&lt;code&gt;(.+)&lt;\/code&gt;/ms',
// function($matches) {
// return highlight_string(html_entity_decode($matches[1]), true);
// }
// );
// Code markup. This should be set to a regular expression, using tags you want to use. Examples:
// "/\[code\](.*?)\[\/code\]/is"
// "/```([a-z0-9-]{0,20})\n(.*?)\n?```\n?/s"
$config['markup_code'] = false;
// Repair markup with HTML Tidy. This may be slower, but it solves nesting mistakes. Tinyboad, at the
// time of writing this, can not prevent out-of-order markup tags (eg. "**''test**'') without help from
@ -724,6 +739,11 @@
$config['allowed_ext'][] = 'png';
// $config['allowed_ext'][] = 'svg';
// Allowed extensions for OP. Inherits from the above setting if set to false. Otherwise, it overrides both allowed_ext and
// allowed_ext_files (filetypes for downloadable files should be set in allowed_ext_files as well). This setting is useful
// for creating fileboards.
$config['allowed_ext_op'] = false;
// Allowed additional file extensions (not images; downloadable files).
// $config['allowed_ext_files'][] = 'txt';
// $config['allowed_ext_files'][] = 'zip';
@ -737,6 +757,7 @@
$config['file_icons']['default'] = 'file.png';
$config['file_icons']['zip'] = 'zip.png';
$config['file_icons']['webm'] = 'video.png';
$config['file_icons']['mp4'] = 'video.png';
// Example: Custom thumbnail for certain file extension.
// $config['file_icons']['extension'] = 'some_file.png';
@ -1005,7 +1026,7 @@
'<object style="float: left;margin: 10px 20px;" width="%%tb_width%%" height="%%tb_height%%"><param name="movie" value="http://www.dailymotion.com/swf/video/$2"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><param name="wmode" value="transparent"><embed type="application/x-shockwave-flash" src="http://www.dailymotion.com/swf/video/$2" width="%%tb_width%%" height="%%tb_height%%" wmode="transparent" allowfullscreen="true" allowscriptaccess="always"></object>'
),
array(
'/^https?:\/\/(\w+\.)?metacafe\.com\/watch\/(\d+)\/([a-zA-Z0-9_\-.]+)\/(\?.+)?$/i',
'/^https?:\/\/(\w+\.)?metacafe\.com\/watch\/(\d+)\/([a-zA-Z0-9_\-.]+)\/(\?[^\'"<>]+)?$/i',
'<div style="float:left;margin:10px 20px;width:%%tb_width%%px;height:%%tb_height%%px"><embed flashVars="playerVars=showStats=no|autoPlay=no" src="http://www.metacafe.com/fplayer/$2/$3.swf" width="%%tb_width%%" height="%%tb_height%%" wmode="transparent" allowFullScreen="true" allowScriptAccess="always" name="Metacafe_$2" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash"></div>'
),
array(
@ -1172,9 +1193,20 @@
// Website favicon.
// $config['url_favicon'] = '/favicon.gif';
// EXPERIMENTAL: Try not to build pages when we shouldn't have to.
// Try not to build pages when we shouldn't have to.
$config['try_smarter'] = true;
// EXPERIMENTAL: Defer static HTML building to a moment, when a given file is actually accessed.
// Warning: This option won't run out of the box. You need to tell your webserver, that a file
// for serving 403 and 404 pages is /smart_build.php. Also, you need to turn off indexes.
$config['smart_build'] = false;
// Smart build related: when a file doesn't exist, where should we redirect?
$config['page_404'] = '/404.html';
// Smart build related: extra entrypoints.
$config['smart_build_entrypoints'] = array();
/*
* ====================
* Mod settings
@ -1496,6 +1528,13 @@
// Allow OP to remove arbitrary posts in his thread
$config['user_moderation'] = false;
// File board. Like 4chan /f/
$config['file_board'] = false;
// Thread tags. Set to false to disable
// Example: array('A' => 'Chinese cartoons', 'M' => 'Music', 'P' => 'Pornography');
$config['allowed_tags'] = false;
/*
* ====================
* Public post search
@ -1630,6 +1669,6 @@
// Youtube.js embed HTML code
$config['youtube_js_html'] = '<div class="video-container" data-video="$2">'.
'<a href="$0" target="_blank" class="file">'.
'<a href="https://youtu.be/$2" target="_blank" class="file">'.
'<img style="width:360px;height:270px;" src="//img.youtube.com/vi/$2/0.jpg" class="post-image"/>'.
'</a></div>';

7
inc/display.php

@ -354,7 +354,7 @@ class Post {
}
if (isset($this->files) && $this->files)
$this->files = json_decode($this->files);
$this->files = @json_decode($this->files);
$this->subject = utf8tohtml($this->subject);
$this->name = utf8tohtml($this->name);
@ -404,7 +404,7 @@ class Thread {
}
if (isset($this->files))
$this->files = json_decode($this->files);
$this->files = @json_decode($this->files);
$this->subject = utf8tohtml($this->subject);
$this->name = utf8tohtml($this->name);
@ -453,7 +453,8 @@ class Thread {
event('show-thread', $this);
$built = Element('post_thread.html', array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index, 'hasnoko50' => $hasnoko50, 'isnoko50' => $isnoko50, 'mod' => $this->mod));
$file = ($index && $config['file_board']) ? 'post_thread_fileboard.html' : 'post_thread.html';
$built = Element($file, array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index, 'hasnoko50' => $hasnoko50, 'isnoko50' => $isnoko50, 'mod' => $this->mod));
return $built;
}

698
inc/functions.php

@ -18,8 +18,9 @@ require_once 'inc/template.php';
require_once 'inc/database.php';
require_once 'inc/events.php';
require_once 'inc/api.php';
require_once 'inc/bans.php';
require_once 'inc/lib/gettext/gettext.inc';
if (!extension_loaded('gettext')) {
require_once 'inc/lib/gettext/gettext.inc';
}
// the user is not currently logged in as a moderator
$mod = false;
@ -29,14 +30,17 @@ mb_internal_encoding('UTF-8');
loadConfig();
function init_locale($locale, $error='error') {
if (_setlocale(LC_ALL, $locale) === false) {
$error('The specified locale (' . $locale . ') does not exist on your platform!');
}
if (extension_loaded('gettext')) {
if (setlocale(LC_ALL, $locale) === false) {
//$error('The specified locale (' . $locale . ') does not exist on your platform!');
}
bindtextdomain('tinyboard', './inc/locale');
bind_textdomain_codeset('tinyboard', 'UTF-8');
textdomain('tinyboard');
} else {
if (_setlocale(LC_ALL, $locale) === false) {
$error('The specified locale (' . $locale . ') does not exist on your platform!');
}
_bindtextdomain('tinyboard', './inc/locale');
_bind_textdomain_codeset('tinyboard', 'UTF-8');
_textdomain('tinyboard');
@ -46,167 +50,213 @@ $current_locale = 'en';
function loadConfig() {
global $board, $config, $__ip, $debug, $__version, $microtime_start, $current_locale;
global $board, $config, $__ip, $debug, $__version, $microtime_start, $current_locale, $events;
$error = function_exists('error') ? 'error' : 'basic_error_function_because_the_other_isnt_loaded_yet';
reset_events();
$boardsuffix = isset($board['uri']) ? $board['uri'] : '';
if (!isset($_SERVER['REMOTE_ADDR']))
$_SERVER['REMOTE_ADDR'] = '0.0.0.0';
$arrays = array(
'db',
'api',
'cache',
'cookies',
'error',
'dir',
'mod',
'spam',
'filters',
'wordfilters',
'custom_capcode',
'custom_tripcode',
'dnsbl',
'dnsbl_exceptions',
'remote',
'allowed_ext',
'allowed_ext_files',
'file_icons',
'footer',
'stylesheets',
'additional_javascript',
'markup',
'custom_pages',
'dashboard_links'
);
if (file_exists('tmp/cache/cache_config.php')) {
require_once('tmp/cache/cache_config.php');
}
if (isset($config['cache_config']) &&
$config['cache_config'] &&
$config = Cache::get('config_' . $boardsuffix ) ) {
$events = Cache::get('events_' . $boardsuffix );
define_groups();
if (file_exists('inc/instance-functions.php')) {
require_once('inc/instance-functions.php');
}
$config = array();
foreach ($arrays as $key) {
$config[$key] = array();
if ($config['locale'] != $current_locale) {
$current_locale = $config['locale'];
init_locale($config['locale'], $error);
}
}
else {
$config = array();
reset_events();
$arrays = array(
'db',
'api',
'cache',
'cookies',
'error',
'dir',
'mod',
'spam',
'filters',
'wordfilters',
'custom_capcode',
'custom_tripcode',
'dnsbl',
'dnsbl_exceptions',
'remote',
'allowed_ext',
'allowed_ext_files',
'file_icons',
'footer',
'stylesheets',
'additional_javascript',
'markup',
'custom_pages',
'dashboard_links'
);
if (!file_exists('inc/instance-config.php'))
$error('Tinyboard is not configured! Create inc/instance-config.php.');
foreach ($arrays as $key) {
$config[$key] = array();
}
// Initialize locale as early as possible
if (!file_exists('inc/instance-config.php'))
$error('Tinyboard is not configured! Create inc/instance-config.php.');
$config['locale'] = 'en';
// Initialize locale as early as possible
$configstr = file_get_contents('inc/instance-config.php');
// Those calls are expensive. Unfortunately, our cache system is not initialized at this point.
// So, we may store the locale in a tmp/ filesystem.
if (isset($board['dir']) && file_exists($board['dir'] . '/config.php')) {
$configstr .= file_get_contents($board['dir'] . '/config.php');
if (file_exists($fn = 'tmp/cache/locale_' . $boardsuffix ) ) {
$config['locale'] = file_get_contents($fn);
}
$matches = array();
preg_match_all('/[^\/*#]\$config\s*\[\s*[\'"]locale[\'"]\s*\]\s*=\s*([\'"])(.*?)\1/', $configstr, $matches);
if ($matches && isset ($matches[2]) && $matches[2]) {
$matches = $matches[2];
$config['locale'] = $matches[count($matches)-1];
}
else {
$config['locale'] = 'en';
if ($config['locale'] != $current_locale) {
$current_locale = $config['locale'];
init_locale($config['locale'], $error);
}
$configstr = file_get_contents('inc/instance-config.php');
if (isset($board['dir']) && file_exists($board['dir'] . '/config.php')) {
$configstr .= file_get_contents($board['dir'] . '/config.php');
}
$matches = array();
preg_match_all('/[^\/*#]\$config\s*\[\s*[\'"]locale[\'"]\s*\]\s*=\s*([\'"])(.*?)\1/', $configstr, $matches);
if ($matches && isset ($matches[2]) && $matches[2]) {
$matches = $matches[2];
$config['locale'] = $matches[count($matches)-1];
}
require 'inc/config.php';
file_put_contents($fn, $config['locale']);
}
require 'inc/instance-config.php';
if ($config['locale'] != $current_locale) {
$current_locale = $config['locale'];
init_locale($config['locale'], $error);
}
if (isset($board['dir']) && file_exists($board['dir'] . '/config.php')) {
require $board['dir'] . '/config.php';
}
require 'inc/config.php';
if ($config['locale'] != $current_locale) {
$current_locale = $config['locale'];
init_locale($config['locale'], $error);
}
require 'inc/instance-config.php';
date_default_timezone_set($config['timezone']);
if (isset($board['dir']) && file_exists($board['dir'] . '/config.php')) {
require $board['dir'] . '/config.php';
}
if (!isset($config['global_message']))
$config['global_message'] = false;
if (!isset($config['post_url']))
$config['post_url'] = $config['root'] . $config['file_post'];
if (!isset($config['referer_match']))
if (isset($_SERVER['HTTP_HOST'])) {
$config['referer_match'] = '/^' .
(preg_match('@^https?://@', $config['root']) ? '' :
'https?:\/\/' . $_SERVER['HTTP_HOST']) .
preg_quote($config['root'], '/') .
'(' .
str_replace('%s', $config['board_regex'], preg_quote($config['board_path'], '/')) .
'(' .
preg_quote($config['file_index'], '/') . '|' .
str_replace('%d', '\d+', preg_quote($config['file_page'])) .
')?' .
'|' .
str_replace('%s', $config['board_regex'], preg_quote($config['board_path'], '/')) .
preg_quote($config['dir']['res'], '/') .
'(' .
str_replace('%d', '\d+', preg_quote($config['file_page'], '/')) . '|' .
str_replace('%d', '\d+', preg_quote($config['file_page50'], '/')) . '|' .
str_replace(array('%d', '%s'), array('\d+', '[a-z0-9-]+'), preg_quote($config['file_page_slug'], '/')) . '|' .
str_replace(array('%d', '%s'), array('\d+', '[a-z0-9-]+'), preg_quote($config['file_page50_slug'], '/')) .
')' .
'|' .
preg_quote($config['file_mod'], '/') . '\?\/.+' .
')([#?](.+)?)?$/ui';
} else {
// CLI mode
$config['referer_match'] = '//';
}
if (!isset($config['cookies']['path']))
$config['cookies']['path'] = &$config['root'];
if (!isset($config['dir']['static']))
$config['dir']['static'] = $config['root'] . 'static/';
if (!isset($config['image_blank']))
$config['image_blank'] = $config['dir']['static'] . 'blank.gif';
if (!isset($config['image_sticky']))
$config['image_sticky'] = $config['dir']['static'] . 'sticky.gif';
if (!isset($config['image_locked']))
$config['image_locked'] = $config['dir']['static'] . 'locked.gif';
if (!isset($config['image_bumplocked']))
$config['image_bumplocked'] = $config['dir']['static'] . 'sage.gif';
if (!isset($config['image_deleted']))
$config['image_deleted'] = $config['dir']['static'] . 'deleted.png';
if (!isset($config['uri_thumb']))
$config['uri_thumb'] = $config['root'] . $board['dir'] . $config['dir']['thumb'];
elseif (isset($board['dir']))
$config['uri_thumb'] = sprintf($config['uri_thumb'], $board['dir']);
if (!isset($config['uri_img']))
$config['uri_img'] = $config['root'] . $board['dir'] . $config['dir']['img'];
elseif (isset($board['dir']))
$config['uri_img'] = sprintf($config['uri_img'], $board['dir']);
if (!isset($config['uri_stylesheets']))
$config['uri_stylesheets'] = $config['root'] . 'stylesheets/';
if (!isset($config['url_stylesheet']))
$config['url_stylesheet'] = $config['uri_stylesheets'] . 'style.css';
if (!isset($config['url_javascript']))
$config['url_javascript'] = $config['root'] . $config['file_script'];
if (!isset($config['additional_javascript_url']))
$config['additional_javascript_url'] = $config['root'];
if (!isset($config['uri_flags']))
$config['uri_flags'] = $config['root'] . 'static/flags/%s.png';
if (!isset($config['user_flag']))
$config['user_flag'] = false;
if (!isset($config['user_flags']))
$config['user_flags'] = array();
if ($config['locale'] != $current_locale) {
$current_locale = $config['locale'];
init_locale($config['locale'], $error);
}
if (!isset($config['global_message']))
$config['global_message'] = false;
if (!isset($config['post_url']))
$config['post_url'] = $config['root'] . $config['file_post'];
if (!isset($config['referer_match']))
if (isset($_SERVER['HTTP_HOST'])) {
$config['referer_match'] = '/^' .
(preg_match('@^https?://@', $config['root']) ? '' :
'https?:\/\/' . $_SERVER['HTTP_HOST']) .
preg_quote($config['root'], '/') .
'(' .
str_replace('%s', $config['board_regex'], preg_quote($config['board_path'], '/')) .
'(' .
preg_quote($config['file_index'], '/') . '|' .
str_replace('%d', '\d+', preg_quote($config['file_page'])) .
')?' .
'|' .
str_replace('%s', $config['board_regex'], preg_quote($config['board_path'], '/')) .
preg_quote($config['dir']['res'], '/') .
'(' .
str_replace('%d', '\d+', preg_quote($config['file_page'], '/')) . '|' .
str_replace('%d', '\d+', preg_quote($config['file_page50'], '/')) . '|' .
str_replace(array('%d', '%s'), array('\d+', '[a-z0-9-]+'), preg_quote($config['file_page_slug'], '/')) . '|' .
str_replace(array('%d', '%s'), array('\d+', '[a-z0-9-]+'), preg_quote($config['file_page50_slug'], '/')) .
')' .
'|' .
preg_quote($config['file_mod'], '/') . '\?\/.+' .
')([#?](.+)?)?$/ui';
} else {
// CLI mode
$config['referer_match'] = '//';
}
if (!isset($config['cookies']['path']))
$config['cookies']['path'] = &$config['root'];
if (!isset($config['dir']['static']))
$config['dir']['static'] = $config['root'] . 'static/';
if (!isset($config['image_blank']))
$config['image_blank'] = $config['dir']['static'] . 'blank.gif';
if (!isset($config['image_sticky']))
$config['image_sticky'] = $config['dir']['static'] . 'sticky.gif';
if (!isset($config['image_locked']))
$config['image_locked'] = $config['dir']['static'] . 'locked.gif';
if (!isset($config['image_bumplocked']))
$config['image_bumplocked'] = $config['dir']['static'] . 'sage.gif';
if (!isset($config['image_deleted']))
$config['image_deleted'] = $config['dir']['static'] . 'deleted.png';
if (!isset($config['uri_thumb']))
$config['uri_thumb'] = $config['root'] . $board['dir'] . $config['dir']['thumb'];
elseif (isset($board['dir']))
$config['uri_thumb'] = sprintf($config['uri_thumb'], $board['dir']);
if (!isset($config['uri_img']))
$config['uri_img'] = $config['root'] . $board['dir'] . $config['dir']['img'];
elseif (isset($board['dir']))
$config['uri_img'] = sprintf($config['uri_img'], $board['dir']);
if (!isset($config['uri_stylesheets']))
$config['uri_stylesheets'] = $config['root'] . 'stylesheets/';
if (!isset($config['url_stylesheet']))
$config['url_stylesheet'] = $config['uri_stylesheets'] . 'style.css';
if (!isset($config['url_javascript']))
$config['url_javascript'] = $config['root'] . $config['file_script'];
if (!isset($config['additional_javascript_url']))
$config['additional_javascript_url'] = $config['root'];
if (!isset($config['uri_flags']))
$config['uri_flags'] = $config['root'] . 'static/flags/%s.png';
if (!isset($config['user_flag']))
$config['user_flag'] = false;
if (!isset($config['user_flags']))
$config['user_flags'] = array();
if (!isset($__version))
$__version = file_exists('.installed') ? trim(file_get_contents('.installed')) : false;
$config['version'] = $__version;
if ($config['allow_roll'])
event_handler('post', 'diceRoller');
if (in_array('webm', $config['allowed_ext_files']) ||
in_array('mp4', $config['allowed_ext_files']))
event_handler('post', 'postHandler');
}
// Effectful config processing below:
date_default_timezone_set($config['timezone']);
if ($config['root_file']) {
chdir($config['root_file']);
}
@ -219,10 +269,6 @@ function loadConfig() {
if (preg_match('/^\:\:(ffff\:)?(\d+\.\d+\.\d+\.\d+)$/', $__ip, $m))
$_SERVER['REMOTE_ADDR'] = $m[2];
if (!isset($__version))
$__version = file_exists('.installed') ? trim(file_get_contents('.installed')) : false;
$config['version'] = $__version;
if ($config['verbose_errors']) {
set_error_handler('verbose_error_handler');
error_reporting(E_ALL);
@ -241,18 +287,29 @@ function loadConfig() {
if ($config['cache']['enabled'])
require_once 'inc/cache.php';
if (in_array('webm', $config['allowed_ext_files'])) {
if (in_array('webm', $config['allowed_ext_files']) ||
in_array('mp4', $config['allowed_ext_files']))
require_once 'inc/lib/webm/posthandler.php';
event_handler('post', 'postHandler');
event('load-config');
if ($config['cache_config'] && !isset ($config['cache_config_loaded'])) {
file_put_contents('tmp/cache/cache_config.php', '<?php '.
'$config = array();'.
'$config[\'cache\'] = '.var_export($config['cache'], true).';'.
'$config[\'cache_config\'] = true;'.
'$config[\'debug\'] = '.var_export($config['debug'], true).';'.
'require_once(\'inc/cache.php\');'
);
$config['cache_config_loaded'] = true;
Cache::set('config_'.$boardsuffix, $config);
Cache::set('events_'.$boardsuffix, $events);
}
if (is_array($config['anonymous']))
$config['anonymous'] = $config['anonymous'][array_rand($config['anonymous'])];
if ($config['allow_roll'])
event_handler('post', 'diceRoller');
event('load-config');
if ($config['debug']) {
if (!isset($debug)) {
@ -328,8 +385,12 @@ function verbose_error_handler($errno, $errstr, $errfile, $errline) {
function define_groups() {
global $config;
foreach ($config['mod']['groups'] as $group_value => $group_name)
defined($group_name) or define($group_name, $group_value, true);
foreach ($config['mod']['groups'] as $group_value => $group_name) {
$group_name = strtoupper($group_name);
if(!defined($group_name)) {
define($group_name, $group_value, true);
}
}
ksort($config['mod']['groups']);
}
@ -348,9 +409,22 @@ function rebuildThemes($action, $boardname = false) {
$_board = $board;
// List themes
$query = query("SELECT `theme` FROM ``theme_settings`` WHERE `name` IS NULL AND `value` IS NULL") or error(db_error());
if ($themes = Cache::get("themes")) {
// OK, we already have themes loaded
}
else {
$query = query("SELECT `theme` FROM ``theme_settings`` WHERE `name` IS NULL AND `value` IS NULL") or error(db_error());
while ($theme = $query->fetch(PDO::FETCH_ASSOC)) {
$themes = array();
while ($theme = $query->fetch(PDO::FETCH_ASSOC)) {
$themes[] = $theme;
}
Cache::set("themes", $themes);
}
foreach ($themes as $theme) {
// Restore them
$config = $_config;
$board = $_board;
@ -379,7 +453,7 @@ function rebuildThemes($action, $boardname = false) {
// Reload the locale
if ($config['locale'] != $current_locale) {
$current_locale = $config['locale'];
init_locale($config['locale'], $error);
init_locale($config['locale']);
}
}
@ -411,6 +485,10 @@ function rebuildTheme($theme, $action, $board = false) {
function themeSettings($theme) {
if ($settings = Cache::get("theme_settings_".$theme)) {
return $settings;
}
$query = prepare("SELECT `name`, `value` FROM ``theme_settings`` WHERE `theme` = :theme AND `name` IS NOT NULL");
$query->bindValue(':theme', $theme);
$query->execute() or error(db_error($query));
@ -420,6 +498,8 @@ function themeSettings($theme) {
$settings[$s['name']] = $s['value'];
}
Cache::set("theme_settings_".$theme, $settings);
return $settings;
}
@ -475,6 +555,11 @@ function openBoard($uri) {
$board = getBoardInfo($uri);
if ($board) {
setupBoard($board);
if (function_exists('after_open_board')) {
after_open_board();
}
return true;
}
return false;
@ -636,6 +721,13 @@ function file_unlink($path) {
}
$ret = @unlink($path);
if ($config['gzip_static']) {
$gzpath = "$path.gz";
@unlink($gzpath);
}
if (isset($config['purge']) && $path[0] != '/' && isset($_SERVER['HTTP_HOST'])) {
// Purge cache
if (basename($path) == $config['file_index']) {
@ -810,12 +902,29 @@ function checkBan($board = false) {
if (event('check-ban', $board))
return true;
$bans = Bans::find($_SERVER['REMOTE_ADDR'], $board, $config['show_modname']);
$ips = array();
$ips[] = $_SERVER['REMOTE_ADDR'];
if ($config['proxy_check'] && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ips = array_merge($ips, explode(", ", $_SERVER['HTTP_X_FORWARDED_FOR']));
}
foreach ($ips as $ip) {
$bans = Bans::find($_SERVER['REMOTE_ADDR'], $board, $config['show_modname']);
foreach ($bans as &$ban) {
if ($ban['expires'] && $ban['expires'] < time()) {
Bans::delete($ban['id']);
if ($config['require_ban_view'] && !$ban['seen']) {
foreach ($bans as &$ban) {
if ($ban['expires'] && $ban['expires'] < time()) {
Bans::delete($ban['id']);
if ($config['require_ban_view'] && !$ban['seen']) {
if (!isset($_POST['json_response'])) {
displayBan($ban);
} else {
header('Content-Type: text/json');
die(json_encode(array('error' => true, 'banned' => true)));
}
}
} else {
if (!isset($_POST['json_response'])) {
displayBan($ban);
} else {
@ -823,13 +932,6 @@ function checkBan($board = false) {
die(json_encode(array('error' => true, 'banned' => true)));
}
}
} else {
if (!isset($_POST['json_response'])) {
displayBan($ban);
} else {
header('Content-Type: text/json');
die(json_encode(array('error' => true, 'banned' => true)));
}
}
}
@ -1004,8 +1106,9 @@ function bumpThread($id) {
if (event('bump', $id))
return true;
if ($config['try_smarter'])
$build_pages[] = thread_find_page($id);
if ($config['try_smarter']) {
$build_pages = array_merge(range(1, thread_find_page($id)), $build_pages);
}
$query = prepare(sprintf("UPDATE ``posts_%s`` SET `bump` = :time WHERE `id` = :id AND `thread` IS NULL", $board['uri']));
$query->bindValue(':time', time(), PDO::PARAM_INT);
@ -1085,7 +1188,7 @@ function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) {
global $board, $config;
// Select post and replies (if thread) in one query
$query = prepare(sprintf("SELECT `id`,`thread`,`files` FROM ``posts_%s`` WHERE `id` = :id OR `thread` = :id", $board['uri']));
$query = prepare(sprintf("SELECT `id`,`thread`,`files`,`slug` FROM ``posts_%s`` WHERE `id` = :id OR `thread` = :id", $board['uri']));
$query->bindValue(':id', $id, PDO::PARAM_INT);
$query->execute() or error(db_error($query));
@ -1257,6 +1360,10 @@ function index($page, $mod=false) {
$body .= $thread->build(true);
}
if ($config['file_board']) {
$body = Element('fileboard.html', array('body' => $body, 'mod' => $mod));
}
return array(
'board' => $board,
'body' => $body,
@ -1468,56 +1575,65 @@ function checkMute() {
}
}
function buildIndex() {
function buildIndex($global_api = "yes") {
global $board, $config, $build_pages;
$pages = getPages();
if (!$config['try_smarter'])
$antibot = create_antibot($board['uri']);
if (!$config['smart_build']) {
$pages = getPages();
if (!$config['try_smarter'])
$antibot = create_antibot($board['uri']);
if ($config['api']['enabled']) {
$api = new Api();
$catalog = array();
if ($config['api']['enabled']) {
$api = new Api();
$catalog = array();
}
}
for ($page = 1; $page <= $config['max_pages']; $page++) {
$filename = $board['dir'] . ($page == 1 ? $config['file_index'] : sprintf($config['file_page'], $page));
$jsonFilename = $board['dir'] . ($page - 1) . '.json'; // pages should start from 0
if (!$config['api']['enabled'] && $config['try_smarter'] && isset($build_pages) && !empty($build_pages)
&& !in_array($page, $build_pages) && is_file($filename))
if ((!$config['api']['enabled'] || $global_api == "skip" || $config['smart_build']) && $config['try_smarter']
&& isset($build_pages) && !empty($build_pages) && !in_array($page, $build_pages) )
continue;
$content = index($page);
if (!$content)
break;
// json api
if ($config['api']['enabled']) {
$threads = $content['threads'];
$json = json_encode($api->translatePage($threads));
$jsonFilename = $board['dir'] . ($page - 1) . '.json'; // pages should start from 0
file_write($jsonFilename, $json);
if (!$config['smart_build']) {
$content = index($page);
if (!$content)
break;
$catalog[$page-1] = $threads;
}
// json api
if ($config['api']['enabled']) {
$threads = $content['threads'];
$json = json_encode($api->translatePage($threads));
file_write($jsonFilename, $json);
if ($config['api']['enabled'] && $config['try_smarter'] && isset($build_pages) && !empty($build_pages)
&& !in_array($page, $build_pages) && is_file($filename))
continue;
$catalog[$page-1] = $threads;
}
if ($config['try_smarter']) {
$antibot = create_antibot($board['uri'], 0 - $page);
$content['current_page'] = $page;
}
$antibot->reset();
$content['pages'] = $pages;
$content['pages'][$page-1]['selected'] = true;
$content['btn'] = getPageButtons($content['pages']);
$content['antibot'] = $antibot;
if ($config['api']['enabled'] && $global_api != "skip" && $config['try_smarter'] && isset($build_pages)
&& !empty($build_pages) && !in_array($page, $build_pages) )
continue;
file_write($filename, Element('index.html', $content));
if ($config['try_smarter']) {
$antibot = create_antibot($board['uri'], 0 - $page);
$content['current_page'] = $page;
}
$antibot->reset();
$content['pages'] = $pages;
$content['pages'][$page-1]['selected'] = true;
$content['btn'] = getPageButtons($content['pages']);
$content['antibot'] = $antibot;
file_write($filename, Element('index.html', $content));
}
else {
file_unlink($filename);
file_unlink($jsonFilename);
}
}
if ($page < $config['max_pages']) {
if (!$config['smart_build'] && $page < $config['max_pages']) {
for (;$page<=$config['max_pages'];$page++) {
$filename = $board['dir'] . ($page==1 ? $config['file_index'] : sprintf($config['file_page'], $page));
file_unlink($filename);
@ -1530,14 +1646,22 @@ function buildIndex() {
}
// json api catalog
if ($config['api']['enabled']) {
$json = json_encode($api->translateCatalog($catalog));
$jsonFilename = $board['dir'] . 'catalog.json';
file_write($jsonFilename, $json);
if ($config['api']['enabled'] && $global_api != "skip") {
if ($config['smart_build']) {
$jsonFilename = $board['dir'] . 'catalog.json';
file_unlink($jsonFilename);
$jsonFilename = $board['dir'] . 'threads.json';
file_unlink($jsonFilename);
}
else {
$json = json_encode($api->translateCatalog($catalog));
$jsonFilename = $board['dir'] . 'catalog.json';
file_write($jsonFilename, $json);
$json = json_encode($api->translateCatalog($catalog, true));
$jsonFilename = $board['dir'] . 'threads.json';
file_write($jsonFilename, $json);
$json = json_encode($api->translateCatalog($catalog, true));
$jsonFilename = $board['dir'] . 'threads.json';
file_write($jsonFilename, $json);
}
}
if ($config['try_smarter'])
@ -1739,6 +1863,15 @@ function markup(&$body, $track_cites = false) {
if (mysql_version() < 50503)
$body = mb_encode_numericentity($body, array(0x010000, 0xffffff, 0, 0xffffff), 'UTF-8');
if ($config['markup_code']) {
$code_markup = array();
$body = preg_replace_callback($config['markup_code'], function($matches) use (&$code_markup) {
$d = count($code_markup);
$code_markup[] = $matches;
return "<code $d>";
}, $body);
}
foreach ($config['markup'] as $markup) {
if (is_string($markup[1])) {
$body = preg_replace($markup[0], $markup[1], $body);
@ -1810,7 +1943,7 @@ function markup(&$body, $track_cites = false) {
if (isset($cited_posts[$cite])) {
$replacement = '<a onclick="highlightReply(\''.$cite.'\');" href="' .
$config['root'] . $board['dir'] . $config['dir']['res'] .
($cited_posts[$cite] ? $cited_posts[$cite] : $cite) . '.html#' . $cite . '">' .
link_for(array('id' => $cite, 'thread' => $cited_posts[$cite])) . '#' . $cite . '">' .
'&gt;&gt;' . $cite .
'</a>';
@ -1876,12 +2009,12 @@ function markup(&$body, $track_cites = false) {
if (!empty($clauses)) {
$cited_posts[$_board] = array();
$query = query(sprintf('SELECT `thread`, `id` FROM ``posts_%s`` WHERE ' .
$query = query(sprintf('SELECT `thread`, `id`, `slug` FROM ``posts_%s`` WHERE ' .
implode(' OR ', $clauses), $board['uri'])) or error(db_error());
while ($cite = $query->fetch(PDO::FETCH_ASSOC)) {
$cited_posts[$_board][$cite['id']] = $config['root'] . $board['dir'] . $config['dir']['res'] .
($cite['thread'] ? $cite['thread'] : $cite['id']) . '.html#' . $cite['id'];
link_for($cite) . '#' . $cite['id'];
}
}
@ -1936,7 +2069,19 @@ function markup(&$body, $track_cites = false) {
$body = preg_replace('/\s+$/', '', $body);
$body = preg_replace("/\n/", '<br/>', $body);
// Fix code markup
if ($config['markup_code']) {
foreach ($code_markup as $id => $val) {
$code = isset($val[2]) ? $val[2] : $val[1];
$code_lang = isset($val[2]) ? $val[1] : "";
$code = "<pre class='code lang-$code_lang'>".str_replace(array("\n","\t"), array("&#10;","&#9;"), htmlspecialchars($code))."</pre>";
$body = str_replace("<code $id>", $code, $body);
}
}
if ($config['markup_repair_tidy']) {
$tidy = new tidy();
$body = str_replace("\t", '&#09;', $body);
@ -1954,10 +2099,10 @@ function markup(&$body, $track_cites = false) {
), 'utf8');
$body = str_replace("\n", '', $body);
}
// replace tabs with 8 spaces
$body = str_replace("\t", ' ', $body);
return $tracked_cites;
}
@ -2029,51 +2174,62 @@ function buildThread($id, $return = false, $mod = false) {
cache::delete("thread_{$board['uri']}_{$id}");
}
$query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE (`thread` IS NULL AND `id` = :id) OR `thread` = :id ORDER BY `thread`,`id`", $board['uri']));
$query->bindValue(':id', $id, PDO::PARAM_INT);
$query->execute() or error(db_error($query));
if ($config['try_smarter'] && !$mod)
$build_pages[] = thread_find_page($id);
while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
if (!isset($thread)) {
$thread = new Thread($post, $mod ? '?/' : $config['root'], $mod);
} else {
$thread->add(new Post($post, $mod ? '?/' : $config['root'], $mod));
if (!$config['smart_build'] || $return || $mod) {
$query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE (`thread` IS NULL AND `id` = :id) OR `thread` = :id ORDER BY `thread`,`id`", $board['uri']));
$query->bindValue(':id', $id, PDO::PARAM_INT);
$query->execute() or error(db_error($query));
while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
if (!isset($thread)) {
$thread = new Thread($post, $mod ? '?/' : $config['root'], $mod);
} else {
$thread->add(new Post($post, $mod ? '?/' : $config['root'], $mod));
}
}
}
// Check if any posts were found
if (!isset($thread))
error($config['error']['nonexistant']);
// Check if any posts were found
if (!isset($thread))
error($config['error']['nonexistant']);
$hasnoko50 = $thread->postCount() >= $config['noko50_min'];
$antibot = $mod || $return ? false : create_antibot($board['uri'], $id);
$hasnoko50 = $thread->postCount() >= $config['noko50_min'];
$antibot = $mod || $return ? false : create_antibot($board['uri'], $id);
$body = Element('thread.html', array(
'board' => $board,
'thread' => $thread,
'body' => $thread->build(),
'config' => $config,
'id' => $id,
'mod' => $mod,
'hasnoko50' => $hasnoko50,
'isnoko50' => false,
'antibot' => $antibot,
'boardlist' => createBoardlist($mod),
'return' => ($mod ? '?' . $board['url'] . $config['file_index'] : $config['root'] . $board['dir'] . $config['file_index'])
));
if ($config['try_smarter'] && !$mod)
$build_pages[] = thread_find_page($id);
$body = Element('thread.html', array(
'board' => $board,
'thread' => $thread,
'body' => $thread->build(),
'config' => $config,
'id' => $id,
'mod' => $mod,
'hasnoko50' => $hasnoko50,
'isnoko50' => false,
'antibot' => $antibot,
'boardlist' => createBoardlist($mod),
'return' => ($mod ? '?' . $board['url'] . $config['file_index'] : $config['root'] . $board['dir'] . $config['file_index'])
));
// json api
if ($config['api']['enabled']) {
$api = new Api();
$json = json_encode($api->translateThread($thread));
// json api
if ($config['api']['enabled']) {
$api = new Api();
$json = json_encode($api->translateThread($thread));
$jsonFilename = $board['dir'] . $config['dir']['res'] . $id . '.json';
file_write($jsonFilename, $json);
}
}
else {
$jsonFilename = $board['dir'] . $config['dir']['res'] . $id . '.json';
file_write($jsonFilename, $json);
file_unlink($jsonFilename);
}
if ($return) {
if ($config['smart_build'] && !$return && !$mod) {
$noko50fn = $board['dir'] . $config['dir']['res'] . link_for(array('id' => $id), true);
file_unlink($noko50fn);
file_unlink($board['dir'] . $config['dir']['res'] . link_for(array('id' => $id)));
} else if ($return) {
return $body;
} else {
$noko50fn = $board['dir'] . $config['dir']['res'] . link_for($thread, true);
@ -2432,6 +2588,8 @@ function diceRoller($post) {
}
function slugify($post) {
global $config;
$slug = "";
if (isset($post['subject']) && $post['subject'])
@ -2447,6 +2605,9 @@ function slugify($post) {
// Transliterate local characters like ü, I wonder how would it work for weird alphabets :^)
$slug = iconv("UTF-8", "ASCII//TRANSLIT//IGNORE", $slug);
// Remove Tinyboard custom markup
$slug = preg_replace("/<tinyboard [^>]+>.*?<\/tinyboard>/s", '', $slug);
// Downcase everything
$slug = strtolower($slug);
@ -2459,8 +2620,8 @@ function slugify($post) {
// Strip dashes at the beginning and at the end
$slug = preg_replace('/^-|-$/', '', $slug);
// Slug should be 200 characters long, at max
$slug = substr($slug, 0, 200);
// Slug should be X characters long, at max (80?)
$slug = substr($slug, 0, $config['slug_max_size']);
// Slug is now ready
return $slug;
@ -2478,17 +2639,26 @@ function link_for($post, $page50 = false, $foreignlink = false, $thread = false)
$slug = false;
if ($config['slugify'] && isset($post['thread']) && $post['thread']) {
if ($config['slugify'] && ( (isset($post['thread']) && $post['thread']) || !isset ($post['slug']) ) ) {
$cvar = "slug_".$b['uri']."_".$id;
if (!$thread) {
// Oh fuck, we'd better optimize it ASAP
$slug = Cache::get($cvar);
$query = prepare(sprintf("SELECT `slug` FROM ``posts_%s`` WHERE `id` = :id", $b['uri']));
$query->bindValue(':id', $id, PDO::PARAM_INT);
$query->execute() or error(db_error($query));
if ($slug === false) {
$query = prepare(sprintf("SELECT `slug` FROM ``posts_%s`` WHERE `id` = :id", $b['uri']));
$query->bindValue(':id', $id, PDO::PARAM_INT);
$query->execute() or error(db_error($query));
$thread = $query->fetch(PDO::FETCH_ASSOC);
$thread = $query->fetch(PDO::FETCH_ASSOC);
$slug = $thread['slug'];
Cache::set($cvar, $slug);
}
}
else {
$slug = $thread['slug'];
}
$slug = $thread['slug'];
}
elseif ($config['slugify']) {
$slug = $post['slug'];

5
inc/image.php

@ -363,9 +363,10 @@ class ImageConvert extends ImageBase {
$this->height,
escapeshellarg($this->temp)))) || !file_exists($this->temp)) {
if (strpos($error, "known incorrect sRGB profile") === false) {
if (strpos($error, "known incorrect sRGB profile") === false &&
strpos($error, "iCCP: Not recognizing known sRGB profile that has been edited") === false) {
$this->destroy();
error('Failed to resize image!', null, array('convert_error' => $error));
error(_('Failed to resize image!')." "._('Details: ').nl2br(htmlspecialchars($error)), null, array('convert_error' => $error));
}
if (!file_exists($this->temp)) {
$this->destroy();

BIN
inc/lib/geoip/GeoIPv6.dat

Binary file not shown.

7
inc/lib/webm/README.md

@ -30,6 +30,13 @@ If you have an [FFmpeg](https://www.ffmpeg.org/) binary on your server and you w
$config['webm']['ffmpeg_path'] = '/path/to/ffmeg';
$config['webm']['ffprobe_path'] = '/path/to/ffprobe';
MP4 support
-----------
MP4 support is available only if you use FFmpeg thumbnailing (see above).
$config['allowed_ext_files'][] = 'mp4';
License
-------

55
inc/lib/webm/ffmpeg.php

@ -3,60 +3,63 @@
* ffmpeg.php
* A barebones ffmpeg based webm implementation for vichan.
*/
function get_webm_info($filename) {
global $board, $config;
$filename = escapeshellarg($filename);
$ffprobe = $config['webm']['ffprobe_path'];
$ffprobe_out = array();
$webminfo = array();
exec("$ffprobe -v quiet -print_format json -show_format -show_streams $filename", $ffprobe_out);
$ffprobe_out = json_decode(implode("\n", $ffprobe_out), 1);
$webminfo['error'] = is_valid_webm($ffprobe_out);
if(empty($webminfo['error'])) {
$webminfo['width'] = $ffprobe_out['streams'][0]['width'];
$webminfo['height'] = $ffprobe_out['streams'][0]['height'];
$webminfo['duration'] = $ffprobe_out['format']['duration'];
}
return $webminfo;
}
function is_valid_webm($ffprobe_out) {
global $board, $config;
if (empty($ffprobe_out))
return array('code' => 1, 'msg' => $config['error']['genwebmerror']);
if ($ffprobe_out['format']['format_name'] != 'matroska,webm')
return array('code' => 2, 'msg' => $config['error']['invalidwebm']);
$extension = pathinfo($ffprobe_out['format']['filename'], PATHINFO_EXTENSION);
if ($extension === 'webm') {
if ($ffprobe_out['format']['format_name'] != 'matroska,webm')
return array('code' => 2, 'msg' => $config['error']['invalidwebm']);
} elseif ($extension === 'mp4') {
if ($ffprobe_out['streams'][0]['codec_name'] != 'h264' && $ffprobe_out['streams'][1]['codec_name'] != 'aac')
return array('code' => 2, 'msg' => $config['error']['invalidwebm']);
} else {
return array('code' => 1, 'msg' => $config['error']['genwebmerror']);
}
if ((count($ffprobe_out['streams']) > 1) && (!$config['webm']['allow_audio']))
return array('code' => 3, 'msg' => $config['error']['webmhasaudio']);
if ($ffprobe_out['streams'][0]['codec_name'] != 'vp8')
return array('code' => 2, 'msg' => $config['error']['invalidwebm']);
if (empty($ffprobe_out['streams'][0]['width']) || (empty($ffprobe_out['streams'][0]['height'])))
return array('code' => 2, 'msg' => $config['error']['invalidwebm']);
if ($ffprobe_out['format']['duration'] > $config['webm']['max_length'])
return array('code' => 4, 'msg' => $config['error']['webmtoolong']);
return array('code' => 4, 'msg' => sprintf($config['error']['webmtoolong'], $config['webm']['max_length']));
}
function make_webm_thumbnail($filename, $thumbnail, $width, $height) {
function make_webm_thumbnail($filename, $thumbnail, $width, $height, $duration) {
global $board, $config;
$filename = escapeshellarg($filename);
$thumbnail = escapeshellarg($thumbnail); // Should be safe by default but you
$thumbnailfc = escapeshellarg($thumbnail); // Should be safe by default but you
// can never be too safe.
$width = escapeshellarg($width);
$height = escapeshellarg($height); // Same as above.
$ffmpeg = $config['webm']['ffmpeg_path'];
$ret = 0;
$ffmpeg_out = array();
exec("$ffmpeg -i $filename -v quiet -ss 00:00:00 -an -vframes 1 -f mjpeg -vf scale=$width:$height $thumbnail 2>&1");
return count($ffmpeg_out);
exec("$ffmpeg -strict -2 -ss " . floor($duration / 2) . " -i $filename -v quiet -an -vframes 1 -f mjpeg -vf scale=$width:$height $thumbnailfc 2>&1", $ffmpeg_out, $ret);
// Work around for https://trac.ffmpeg.org/ticket/4362
if (filesize($thumbnail) === 0) {
// try again with first frame
exec("$ffmpeg -y -strict -2 -ss 0 -i $filename -v quiet -an -vframes 1 -f mjpeg -vf scale=$width:$height $thumbnailfc 2>&1", $ffmpeg_out, $ret);
clearstatcache();
// failed if no thumbnail size even if ret code 0, ffmpeg is buggy
if (filesize($thumbnail) === 0) {
$ret = 1;
}
}
return $ret;
}

19
inc/lib/webm/posthandler.php

@ -1,27 +1,22 @@
<?php
// Glue code for handling a Tinyboard post.
// Portions of this file are derived from Tinyboard code.
function postHandler($post) {
global $board, $config;
if ($post->has_file) foreach ($post->files as &$file) if ($file->extension == 'webm') {
if ($post->has_file) foreach ($post->files as &$file) if ($file->extension == 'webm' || $file->extension == 'mp4') {
if ($config['webm']['use_ffmpeg']) {
require_once dirname(__FILE__) . '/ffmpeg.php';
$webminfo = get_webm_info($file->file_path);
if (empty($webminfo['error'])) {
$file->width = $webminfo['width'];
$file->height = $webminfo['height'];
if ($config['spoiler_images'] && isset($_POST['spoiler'])) {
$file = webm_set_spoiler($file);
}
else {
$file = set_thumbnail_dimensions($post, $file);
$tn_path = $board['dir'] . $config['dir']['thumb'] . $file->file_id . '.jpg';
if(false == make_webm_thumbnail($file->file_path, $tn_path, $file->thumbwidth, $file->thumbheight)) {
if(0 == make_webm_thumbnail($file->file_path, $tn_path, $file->thumbwidth, $file->thumbheight, $webminfo['duration'])) {
$file->thumb = $file->file_id . '.jpg';
}
else {
@ -37,7 +32,6 @@ function postHandler($post) {
require_once dirname(__FILE__) . '/videodata.php';
$videoDetails = videoData($file->file_path);
if (!isset($videoDetails['container']) || $videoDetails['container'] != 'webm') return "not a WebM file";
// Set thumbnail
$thumbName = $board['dir'] . $config['dir']['thumb'] . $file->file_id . '.webm';
if ($config['spoiler_images'] && isset($_POST['spoiler'])) {
@ -53,12 +47,10 @@ function postHandler($post) {
$file->thumb = 'file';
}
unset($videoDetails['frame']);
// Set width and height
if (isset($videoDetails['width']) && isset($videoDetails['height'])) {
$file->width = $videoDetails['width'];
$file->height = $videoDetails['height'];
if ($file->thumb != 'file' && $file->thumb != 'spoiler') {
$file = set_thumbnail_dimensions($post, $file);
}
@ -66,14 +58,11 @@ function postHandler($post) {
}
}
}
function set_thumbnail_dimensions($post,$file) {
global $board, $config;
$tn_dimensions = array();
$tn_maxw = $post->op ? $config['thumb_op_width'] : $config['thumb_width'];
$tn_maxh = $post->op ? $config['thumb_op_height'] : $config['thumb_height'];
if ($file->width > $tn_maxw || $file->height > $tn_maxh) {
$file->thumbwidth = min($tn_maxw, intval(round($file->width * $tn_maxh / $file->height)));
$file->thumbheight = min($tn_maxh, intval(round($file->height * $tn_maxw / $file->width)));
@ -81,17 +70,13 @@ function set_thumbnail_dimensions($post,$file) {
$file->thumbwidth = $file->width;
$file->thumbheight = $file->height;
}
return $file;
}
function webm_set_spoiler($file) {
global $board, $config;
$file->thumb = 'spoiler';
$size = @getimagesize($config['spoiler_image']);
$file->thumbwidth = $size[0];
$file->thumbheight = $size[1];
return $file;
}

25
inc/mod/pages.php

@ -111,7 +111,7 @@ function mod_dashboard() {
$latest = unserialize($_COOKIE['update']);
} else {
$ctx = stream_context_create(array('http' => array('timeout' => 5)));
if ($code = @file_get_contents('http://tinyboard.org/version.txt', 0, $ctx)) {
if ($code = @file_get_contents('http://engine.vichan.net/version.txt', 0, $ctx)) {
$ver = strtok($code, "\n");
if (preg_match('@^// v(\d+)\.(\d+)\.(\d+)\s*?$@', $ver, $matches)) {
@ -120,7 +120,7 @@ function mod_dashboard() {
'major' => $matches[2],
'minor' => $matches[3]
);
if (preg_match('/v(\d+)\.(\d)\.(\d+)(-dev.+)?$/', $config['version'], $matches)) {
if (preg_match('/(\d+)\.(\d)\.(\d+)(-dev.+)?$/', $config['version'], $matches)) {
$current = array(
'massive' => (int) $matches[1],
'major' => (int) $matches[2],
@ -1224,7 +1224,10 @@ function mod_move($originBoard, $postID) {
// create the new thread
$newID = post($post);
$op = $post;
$op['id'] = $newID;
if ($post['has_file']) {
// copy image
foreach ($post['files'] as $i => &$file) {
@ -1357,14 +1360,14 @@ function mod_move($originBoard, $postID) {
buildIndex();
header('Location: ?/' . sprintf($config['board_path'], $originBoard) . $config['dir']['res'] . link_for($post, false, $newboard) .
header('Location: ?/' . sprintf($config['board_path'], $newboard['uri']) . $config['dir']['res'] . link_for($op, false, $newboard) .
'#' . $botID, true, $config['redirect_http']);
} else {
deletePost($postID);
buildIndex();
openBoard($targetBoard);
header('Location: ?/' . sprintf($config['board_path'], $board['uri']) . $config['dir']['res'] . link_for($post, false, $newboard), true, $config['redirect_http']);
header('Location: ?/' . sprintf($config['board_path'], $newboard['uri']) . $config['dir']['res'] . link_for($op, false, $newboard), true, $config['redirect_http']);
}
}
@ -2498,10 +2501,14 @@ function mod_theme_configure($theme_name) {
$query->bindValue(':value', $_POST[$conf['name']]);
$query->execute() or error(db_error($query));
}
$query = prepare("INSERT INTO ``theme_settings`` VALUES(:theme, NULL, NULL)");
$query->bindValue(':theme', $theme_name);
$query->execute() or error(db_error($query));
// Clean cache
Cache::delete("themes");
Cache::delete("theme_settings_".$theme_name);
$result = true;
$message = false;
@ -2549,11 +2556,15 @@ function mod_theme_uninstall($theme_name) {
if (!hasPermission($config['mod']['themes']))
error($config['error']['noaccess']);
$query = prepare("DELETE FROM ``theme_settings`` WHERE `theme` = :theme");
$query->bindValue(':theme', $theme_name);
$query->execute() or error(db_error($query));
// Clean cache
Cache::delete("themes");
Cache::delete("theme_settings_".$theme);
header('Location: ?/themes', true, $config['redirect_http']);
}

16
js/ajax.js

@ -115,17 +115,10 @@ $(window).ready(function() {
}
},
error: function(xhr, status, er) {
// An error occured
do_not_ajax = true;
$(form).find('input[type="submit"]').each(function() {
var $replacement = $('<input type="hidden">');
$replacement.attr('name', $(this).attr('name'));
$replacement.val(submit_txt);
$(this)
.after($replacement)
.replaceWith($('<input type="button">').val(submit_txt));
});
$(form).submit();
console.log(xhr);
alert(_('The server took too long to submit your post. Your post was probably still submitted. If it wasn\'t, we might be experiencing issues right now -- please try your post again later. Error information: ') + "<div><textarea>" + JSON.stringify(xhr) + "</textarea></div>");
$(form).find('input[type="submit"]').val(submit_txt);
$(form).find('input[type="submit"]').removeAttr('disabled');
},
data: formData,
cache: false,
@ -141,6 +134,7 @@ $(window).ready(function() {
};
setup_form($('form[name="post"]'));
$(window).on('quick-reply', function() {
$('form#quick-reply').off('submit');
setup_form($('form#quick-reply'));
});
});

82
js/catalog-search.js

@ -0,0 +1,82 @@
/*
* catalog-search.js
* - Search and filters threads when on catalog view
* - Optional shortcuts 's' and 'esc' to open and close the search.
*
* Usage:
* $config['additional_javascript'][] = 'js/jquery.min.js';
* $config['additional_javascript'][] = 'js/comment-toolbar.js';
*/
if (active_page == 'catalog') {
onready(function () {
'use strict';
// 'true' = enable shortcuts
var useKeybinds = true;
// trigger the search 400ms after last keystroke
var delay = 400;
var timeoutHandle;
//search and hide none matching threads
function filter(search_term) {
$('.replies').each(function () {
var subject = $(this).children('.intro').text().toLowerCase();
var comment = $(this).clone().children().remove(':lt(2)').end().text().trim().toLowerCase();
search_term = search_term.toLowerCase();
if (subject.indexOf(search_term) == -1 && comment.indexOf(search_term) == -1) {
$(this).parents('div[id="Grid"]>.mix').css('display', 'none');
} else {
$(this).parents('div[id="Grid"]>.mix').css('display', 'inline-block');
}
});
}
function searchToggle() {
var button = $('#catalog_search_button')[0];
if (!button.dataset.expanded) {
button.dataset.expanded = '1';
button.innerText = 'Close';
$('.catalog_search').append(' <input id="search_field" style="border: inset 1px;">');
$('#search_field').focus();
} else {
delete button.dataset.expanded;
button.innerText = 'Search';
$('.catalog_search').children().last().remove();
$('div[id="Grid"]>.mix').each(function () { $(this).css('display', 'inline-block'); });
}
}
$('.threads').before('<span class="catalog_search">[<a id="catalog_search_button" style="text-decoration:none; cursor:pointer;"></a>]</span>');
$('#catalog_search_button').text('Search');
$('#catalog_search_button').on('click', searchToggle);
$('.catalog_search').on('keyup', 'input#search_field', function (e) {
window.clearTimeout(timeoutHandle);
timeoutHandle = window.setTimeout(filter, 400, e.target.value);
});
if (useKeybinds) {
// 's'
$('body').on('keydown', function (e) {
if (e.which === 83 && e.target.tagName === 'BODY' && !(e.ctrlKey || e.altKey || e.shiftKey)) {
e.preventDefault();
if ($('#search_field').length !== 0) {
$('#search_field').focus();
} else {
searchToggle();
}
}
});
// 'esc'
$('.catalog_search').on('keydown', 'input#search_field', function (e) {
if (e.which === 27 && !(e.ctrlKey || e.altKey || e.shiftKey)) {
window.clearTimeout(timeoutHandle);
searchToggle();
}
});
}
});
}

4
js/expand-video.js

@ -204,13 +204,13 @@ function setupVideo(thumb, url) {
function setupVideosIn(element) {
var thumbs = element.querySelectorAll("a.file");
for (var i = 0; i < thumbs.length; i++) {
if (/\.webm$/.test(thumbs[i].pathname)) {
if (/\.webm$|\.mp4$/.test(thumbs[i].pathname)) {
setupVideo(thumbs[i], thumbs[i].href);
} else {
var m = thumbs[i].search.match(/\bv=([^&]*)/);
if (m != null) {
var url = decodeURIComponent(m[1]);
if (/\.webm$/.test(url)) setupVideo(thumbs[i], url);
if (/\.webm$|\.mp4$/.test(url)) setupVideo(thumbs[i], url);
}
}
}

1
js/favorites.js

@ -54,7 +54,6 @@ if (active_page == 'thread' || active_page == 'index') {
$(document).ready(function(){
var favorites = JSON.parse(localStorage.favorites);
var is_board_favorite = ~$.inArray(board_name, favorites);
console.log(is_board_favorite);
$('header>h1').append('<a id="favorite-star" href="#" data-active="'+(is_board_favorite ? 'true' : 'false')+'" style="color: '+(is_board_favorite ? 'yellow' : 'grey')+'; text-decoration:none">\u2605</span>');
add_favorites();

191
js/file-selector.js

@ -0,0 +1,191 @@
/*
* file-selector.js - Add support for drag and drop file selection, and paste from clipbboard on supported browsers.
*
* Usage:
* $config['additional_javascript'][] = 'js/jquery.min.js';
* $config['additional_javascript'][] = 'js/file-selector.js';
*/
function init_file_selector(max_images) {
$(document).ready(function () {
// add options panel item
if (window.Options && Options.get_tab('general')) {
Options.extend_tab('general', '<label id="file-drag-drop"><input type="checkbox">' + _('Drag and drop file selection') + '</label>');
$('#file-drag-drop>input').on('click', function() {
if ($('#file-drag-drop>input').is(':checked')) {
localStorage.file_dragdrop = 'true';
} else {
localStorage.file_dragdrop = 'false';
}
});
if (typeof localStorage.file_dragdrop === 'undefined') localStorage.file_dragdrop = 'true';
if (localStorage.file_dragdrop === 'true') $('#file-drag-drop>input').prop('checked', true);
}
});
// disabled by user, or incompatible browser.
if (localStorage.file_dragdrop == 'false' || !(window.URL.createObjectURL && window.File))
return;
// multipost not enabled
if (typeof max_images == 'undefined') {
var max_images = 1;
}
$('<div class="dropzone-wrap" style="display: none;">'+
'<div class="dropzone" tabindex="0">'+
'<div class="file-hint">'+_('Select/drop/paste files here')+'</div>'+
'<div class="file-thumbs"></div>'+
'</div>'+
'</div>'+
'</div>').prependTo('#upload td');
var files = [];
$('#upload_file').remove(); // remove the original file selector
$('.dropzone-wrap').css('user-select', 'none').show(); // let jquery add browser specific prefix
function addFile(file) {
if (files.length == max_images)
return;
files.push(file);
addThumb(file);
}
function removeFile(file) {
files.splice(files.indexOf(file), 1);
}
function getThumbElement(file) {
return $('.tmb-container').filter(function(){return($(this).data('file-ref')==file);});
}
function addThumb(file) {
var fileName = (file.name.length < 24) ? file.name : file.name.substr(0, 22) + '…';
var fileType = file.type.split('/')[0];
var fileExt = file.type.split('/')[1];
var $container = $('<div>')
.addClass('tmb-container')
.data('file-ref', file)
.append(
$('<div>').addClass('remove-btn').html('✖'),
$('<div>').addClass('file-tmb'),
$('<div>').addClass('tmb-filename').html(fileName)
)
.appendTo('.file-thumbs');
var $fileThumb = $container.find('.file-tmb');
if (fileType == 'image') {
// if image file, generate thumbnail
var objURL = window.URL.createObjectURL(file);
$fileThumb.css('background-image', 'url('+ objURL +')');
} else {
$fileThumb.html('<span>' + fileExt.toUpperCase() + '</span>');
}
}
$(document).on('ajax_before_post', function (e, formData) {
for (var i=0; i<max_images; i++) {
var key = 'file';
if (i > 0) key += i + 1;
if (typeof files[i] === 'undefined') break;
formData.append(key, files[i]);
}
});
// clear file queue and UI on success
$(document).on('ajax_after_post', function () {
files = [];
$('.file-thumbs').empty();
});
var dragCounter = 0;
var dropHandlers = {
dragenter: function (e) {
e.stopPropagation();
e.preventDefault();
if (dragCounter === 0) $('.dropzone').addClass('dragover');
dragCounter++;
},
dragover: function (e) {
// needed for webkit to work
e.stopPropagation();
e.preventDefault();
},
dragleave: function (e) {
e.stopPropagation();
e.preventDefault();
dragCounter--;
if (dragCounter === 0) $('.dropzone').removeClass('dragover');
},
drop: function (e) {
e.stopPropagation();
e.preventDefault();
$('.dropzone').removeClass('dragover');
dragCounter = 0;
var fileList = e.originalEvent.dataTransfer.files;
for (var i=0; i<fileList.length; i++) {
addFile(fileList[i]);
}
}
};
// attach handlers
$(document).on(dropHandlers);
$(document).on('click', '.dropzone .remove-btn', function (e) {
e.stopPropagation();
var file = $(e.target).parent().data('file-ref');
getThumbElement(file).remove();
removeFile(file);
});
$(document).on('keypress click', '.dropzone', function (e) {
e.stopPropagation();
// accept mouse click or Enter
if ((e.which != 1 || e.target.className != 'file-hint') &&
e.which != 13)
return;
var $fileSelector = $('<input type="file" multiple>');
$fileSelector.on('change', function (e) {
if (this.files.length > 0) {
for (var i=0; i<this.files.length; i++) {
addFile(this.files[i]);
}
}
$(this).remove();
});
$fileSelector.click();
});
$(document).on('paste', function (e) {
var clipboard = e.originalEvent.clipboardData;
if (typeof clipboard.items != 'undefined' && clipboard.items.length != 0) {
//Webkit
for (var i=0; i<clipboard.items.length; i++) {
if (clipboard.items[i].kind != 'file')
continue;
//convert blob to file
var file = new File([clipboard.items[i].getAsFile()], 'ClipboardImage.png', {type: 'image/png'});
addFile(file);
}
}
});
}

2
js/forced-anon.js

@ -64,7 +64,7 @@ $(document).ready(function() {
if (window.Options && Options.get_tab('general')) {
selector = '#forced-anon';
event = 'change';
Options.extend_tab("general", "<label id='forced-anon'><input type='checkbox' /> "+_('Forced anonymity')+"</label>");
Options.extend_tab("general", "<label id='forced-anon'><input type='checkbox' />"+_('Forced anonymity')+"</label>");
}
else {
selector = '#forced-anon';

165
js/gallery-view.js

@ -0,0 +1,165 @@
if (active_page == 'index' || active_page == 'thread')
$(function(){
var gallery_view = false;
$('hr:first').before('<div id="gallery-view" style="text-align:right"><a class="unimportant" href="javascript:void(0)">-</a></div>');
$('#gallery-view a').html(gallery_view ? _("Disable gallery mode") : _("Enable gallery mode")).click(function() {
gallery_view = !gallery_view;
$(this).html(gallery_view ? _("Disable gallery mode") : _("Enable gallery mode"));
toggle_gview(document);
});
var toggle_gview = function(elem) {
if (gallery_view) {
$(elem).find('img.post-image').parent().each(function() {
this.oldonclick = this.onclick;
this.onclick = handle_click;
$(this).attr('data-galid', Math.random());
});
}
else {
$(elem).find('img.post-image').parent().each(function() {
if (this.onclick == handle_click) this.onclick = this.oldonclick;
});
}
};
$(document).on('new_post', toggle_gview);
var gallery_opened = false;
var handle_click = function(e) {
e.stopPropagation();
e.preventDefault();
if (!gallery_opened) open_gallery();
gallery_setimage($(this).attr('data-galid'));
};
var handler, images, active, toolbar;
var open_gallery = function() {
$('body').css('overflow', 'hidden');
gallery_opened = true;
handler = $("<div id='alert_handler'></div>").hide().appendTo('body').css('text-align', 'left');
$("<div id='alert_background'></div>").click(close_gallery).appendTo(handler);
images = $("<div id='gallery_images'></div>").appendTo(handler);
toolbar = $("<div id='gallery_toolbar'></div>").appendTo(handler);
active = $("<div id='gallery_main'></div>").appendTo(handler);
active.on('click', function() {
close_gallery();
});
$('img.post-image').parent().each(function() {
var thumb = $(this).find('img').attr('src');
var i = $('<img>').appendTo(images);
i.attr('src', thumb);
i.attr('data-galid-th', $(this).attr('data-galid'));
i.on('click', function(e) {
gallery_setimage($(this).attr('data-galid-th'));
});
});
$("<a href='javascript:void(0)'><i class='fa fa-times'></i></div>")
.click(close_gallery).appendTo(toolbar);
$('body').on('keydown.gview', function(e) {
if (e.which == 39 || e.which == 40) { // right or down arrow
gallery_setimage(+1);
e.preventDefault();
}
else if (e.which == 37 || e.which == 38) { // left or up arrow
gallery_setimage(-1);
e.preventDefault();
}
});
handler.fadeIn(400);
};
var gallery_setimage = function(a) {
if (a == +1 || a == -1) {
var meth = (a == -1) ? 'prev' : 'next';
a = $('#gallery_images img.active')[meth]().attr('data-galid-th');
if (!a) return;
}
$('#gallery_images img.active').removeClass('active');
var thumb = $('#gallery_images [data-galid-th="'+a+'"]');
var elem = $('a[data-galid="'+a+'"]');
thumb.addClass('active');
var topscroll = thumb.position().top + images.scrollTop();
topscroll -= images.height() / 2;
topscroll += thumb.height() / 2;
images.animate({'scrollTop': topscroll}, 300);
var img = elem.attr('href');
active.find('img, video').fadeOut(200, function() { $(this).remove(); });
var i;
if (img.match(/player\.php/)) {
img = img.replace(/.*player\.php\?v=|&t=.*/g, '');
}
if (img.match(/\.webm$|\.mp4$|\.ogv$/i)) { // We are handling video nao
i = $('<video>');
i.attr('src', img);
i.attr('autoplay', true);
i.attr('controls', true);
i.appendTo(active);
i.hide();
}
else { // Just a plain image
i = $('<img>');
i.attr('src', img);
i.appendTo(active);
i.hide();
}
// Let's actually preload the next few images
var nextimg = $('#gallery_images active');
for (var j = 0; j < 3; j++) {
nextimg = nextimg.next();
var attr;
if (attr = nextimg.attr('data-gaild-th')) {
var href = $('a[data-galid="'+attr+'"]').attr('href');
if (href.match(/\.webm|\.mp4|\.ogv/i)) { j--; continue; }
if ($('[data-galid-preload="'+attr+'"]').length) continue;
var img = $('<img>').attr('src', href).attr('data-galid-preload', attr).hide().appendTo('body').on('load', function() { $(this).remove(); });
}
else break;
}
i.one('load canplay', function() {
i.css('left', 'calc(50% - '+i.width()+'px / 2)');
i.css('top', 'calc(50% - '+i.height()+'px / 2)');
i.fadeIn(200);
}).on('click', function(e) {
e.stopPropagation();
gallery_setimage(+1);
});
};
var close_gallery = function() {
$('body').css('overflow', 'auto');
gallery_opened = false;
$('body').off('keydown.gview');
handler.fadeOut(400, function() { handler.remove(); });
};
});

4
js/hide-images.js

@ -93,9 +93,9 @@ $(document).ready(function(){
$(this).parent().prev().find('.hide-image-link').click();
};
$('div.post > a > img.post-image, div > a > img.post-image').each(handle_images);
$('div.post > a > img.post-image, div.post > a > video.post-image, div > a > img.post-image, div > a > video.post-image').each(handle_images);
$(document).on('new_post', function(e, post) {
$(post).find('a > img.post-image').each(handle_images);
$(post).find('a > img.post-image, a > video.post-image').each(handle_images);
});
});

182
js/image-hover.js

@ -0,0 +1,182 @@
/* image-hover.js
* This script is copied almost verbatim from https://github.com/Pashe/8chanX/blob/2-0/8chan-x.user.js
* All I did was remove the sprintf dependency and integrate it into 8chan's Options as opposed to Pashe's.
* I also changed initHover() to also bind on new_post.
* Thanks Pashe for using WTFPL.
*/
if (active_page === "catalog" || active_page === "thread" || active_page === "index") {
$(document).on('ready', function(){
if (window.Options && Options.get_tab('general')) {
Options.extend_tab("general",
"<fieldset><legend>Image hover</legend>"
+ ("<label class='image-hover' id='imageHover'><input type='checkbox' /> "+_('Image hover')+"</label>")
+ ("<label class='image-hover' id='catalogImageHover'><input type='checkbox' /> "+_('Image hover on catalog')+"</label>")
+ ("<label class='image-hover' id='imageHoverFollowCursor'><input type='checkbox' /> "+_('Image hover should follow cursor')+"</label>")
+ "</fieldset>");
}
$('.image-hover').on('change', function(){
var setting = $(this).attr('id');
localStorage[setting] = $(this).children('input').is(':checked');
});
if (!localStorage.imageHover || !localStorage.catalogImageHover || !localStorage.imageHoverFollowCursor) {
localStorage.imageHover = 'false';
localStorage.catalogImageHover = 'false';
localStorage.imageHoverFollowCursor = 'false';
}
if (getSetting('imageHover')) $('#imageHover>input').prop('checked', 'checked');
if (getSetting('catalogImageHover')) $('#catalogImageHover>input').prop('checked', 'checked');
if (getSetting('imageHoverFollowCursor')) $('#imageHoverFollowCursor>input').prop('checked', 'checked');
function getFileExtension(filename) { //Pashe, WTFPL
if (filename.match(/\.([a-z0-9]+)(&loop.*)?$/i) !== null) {
return filename.match(/\.([a-z0-9]+)(&loop.*)?$/i)[1];
} else if (filename.match(/https?:\/\/(www\.)?youtube.com/)) {
return 'Youtube';
} else {
return "unknown: " + filename;
}
}
function isImage(fileExtension) { //Pashe, WTFPL
return ($.inArray(fileExtension, ["jpg", "jpeg", "gif", "png"]) !== -1);
}
function isVideo(fileExtension) { //Pashe, WTFPL
return ($.inArray(fileExtension, ["webm", "mp4"]) !== -1);
}
function isOnCatalog() {
return window.active_page === "catalog";
}
function isOnThread() {
return window.active_page === "thread";
}
function getSetting(key) {
return (localStorage[key] == 'true');
}
function initImageHover() { //Pashe, influenced by tux, et al, WTFPL
if (!getSetting("imageHover") && !getSetting("catalogImageHover")) {return;}
var selectors = [];
if (getSetting("imageHover")) {selectors.push("img.post-image", "canvas.post-image");}
if (getSetting("catalogImageHover") && isOnCatalog()) {
selectors.push(".thread-image");
$(".theme-catalog div.thread").css("position", "inherit");
}
function bindEvents(el) {
$(el).find(selectors.join(", ")).each(function () {
if ($(this).parent().data("expanded")) {return;}
var $this = $(this);
$this.on("mousemove", imageHoverStart);
$this.on("mouseout", imageHoverEnd);
$this.on("click", imageHoverEnd);
});
}
bindEvents(document.body);
$(document).on('new_post', function(e, post) {
bindEvents(post);
});
}
function imageHoverStart(e) { //Pashe, anonish, WTFPL
var hoverImage = $("#chx_hoverImage");
if (hoverImage.length) {
if (getSetting("imageHoverFollowCursor")) {
var scrollTop = $(window).scrollTop();
var imgY = e.pageY;
var imgTop = imgY;
var windowWidth = $(window).width();
var imgWidth = hoverImage.width() + e.pageX;
if (imgY < scrollTop + 15) {
imgTop = scrollTop;
} else if (imgY > scrollTop + $(window).height() - hoverImage.height() - 15) {
imgTop = scrollTop + $(window).height() - hoverImage.height() - 15;
}
if (imgWidth > windowWidth) {
hoverImage.css({
'left': (e.pageX + (windowWidth - imgWidth)),
'top' : imgTop,
});
} else {
hoverImage.css({
'left': e.pageX,
'top' : imgTop,
});
}
hoverImage.appendTo($("body"));
}
return;
}
var $this = $(this);
var fullUrl;
if ($this.parent().attr("href").match("src")) {
fullUrl = $this.parent().attr("href");
} else if (isOnCatalog()) {
fullUrl = $this.attr("data-fullimage");
if (!isImage(getFileExtension(fullUrl))) {fullUrl = $this.attr("src");}
}
if (isVideo(getFileExtension(fullUrl))) {return;}
hoverImage = $('<img id="chx_hoverImage" src="'+fullUrl+'" />');
if (getSetting("imageHoverFollowCursor")) {
var size = $this.parents('.file').find('.unimportant').text().match(/\b(\d+)x(\d+)\b/),
maxWidth = $(window).width(),
maxHeight = $(window).height();
var scale = Math.min(1, maxWidth / size[1], maxHeight / size[2]);
hoverImage.css({
"position" : "absolute",
"z-index" : 101,
"pointer-events": "none",
"width" : size[1] + "px",
"height" : size[2] + "px",
"max-width" : (size[1] * scale) + "px",
"max-height" : (size[2] * scale) + "px",
'left' : e.pageX,
'top' : imgTop,
});
} else {
hoverImage.css({
"position" : "fixed",
"top" : 0,
"right" : 0,
"z-index" : 101,
"pointer-events": "none",
"max-width" : "100%",
"max-height" : "100%",
});
}
hoverImage.appendTo($("body"));
if (isOnThread()) {$this.css("cursor", "none");}
}
function imageHoverEnd() { //Pashe, WTFPL
$("#chx_hoverImage").remove();
}
initImageHover();
});
}

2
js/live-index.js

@ -58,7 +58,7 @@ if (active_page == 'index' && (""+document.location).match(/\/(index\.html)?(\?|
update_new_threads(new_threads);
});
}, 1000);
}, 20000);
});
$(document).on("new_post", function(e, post) {

2
js/no-animated-gif.js

@ -57,7 +57,7 @@ if (active_page == 'thread' || active_page == 'index' || active_page == 'ukko' |
if (window.Options && Options.get_tab('general')) {
selector = '#no-animated-gif>input';
event = 'change';
Options.extend_tab("general", "<label id='no-animated-gif'><input type='checkbox' /> "+_('Unanimate GIFs')+"</label>");
Options.extend_tab("general", "<label id='no-animated-gif'><input type='checkbox' />"+_('Unanimate GIFs')+"</label>");
}
else {
selector = '#no-animated-gif';

116
js/own-board.js

@ -0,0 +1,116 @@
/*****************************************************************
* ------- WARNING! --------- *
*****************************************************************
* This script is at the current time undocumented and *
* unsupported. It is still a work in progress and will likely *
* change. You are on your own. *
*****************************************************************/
+function() {
var uniq = function(a) {
var b = {};
var c = [];
a.forEach(function(i) {
if (!b[i]) {
c.push(i);
b[i] = true;
}
});
return c;
};
if (active_page == 'thread' || active_page == 'index') {
var board = null;
$(function() {
board = $('input[name="board"]').first().val();
});
$(document).on('ajax_after_post', function(e, r) {
var threads = JSON.parse(localStorage.obthreads || '[]');
var thread = null;
if (active_page == 'index') {
thread = r.id|0;
}
else {
thread = $('[id^="thread_"]').first().attr('id').replace("thread_", "")|0;
}
threads.push([board, thread]);
threads = uniq(threads);
localStorage.obthreads = JSON.stringify(threads);
});
}
var loaded = false;
$(function() {
loaded = true;
});
var activate = function() {
if (document.location.hash != '#own') return false;
if (loaded) late_activate();
else $(function() { late_activate(); });
return true;
};
var late_activate = function() {
$('[id^="thread_"]').remove();
var threads = JSON.parse(localStorage.obthreads || '[]');
threads.forEach(function(v) {
var board = v[0];
var thread = v[1];
var url = "/"+board+"/res/"+thread+".html";
$.get(url, function(html) {
var s = $(html).find('[id^="thread_"]');
s[0].bumptime = (new Date(s.find("time").last().attr("datetime"))).getTime();
var added = false;
$('[id^="thread_"]').each(function() {
if (added) return;
if (s[0].bumptime > this.bumptime) {
added = true;
s.insertBefore(this);
}
});
if (!added) {
s.appendTo('[name="postcontrols"]');
}
s.find('.post.reply').addClass('hidden').hide().slice(-3).removeClass('hidden').show();
s.find('.post.reply.hidden').next().addClass('hidden').hide(); // Hide <br> elements
var posts_omitted = s.find('.post.reply.hidden').length;
var images_omitted = s.find('.post.reply.hidden img').length;
if (posts_omitted > 0) {
var omitted = $(fmt('<span class="omitted">'+_('{0} posts and {1} images omitted.')+' '+_('Click reply to view.')+'</span>',
[posts_omitted, images_omitted]));
omitted.appendTo(s.find('.post.op'));
}
var reply = $('<a href="'+url+'">['+_('Reply')+']</a>').appendTo(s.find('.intro').first());
$(document).trigger('new_post', s[0]);
});
});
};
$(window).on("hashchange", function() {
return !activate();
});
activate();
}();

11
js/quick-reply.js

@ -83,11 +83,12 @@
}\
#quick-reply textarea {\
width: 100%;\
min-width: 100%;\
box-sizing: border-box;\
-webkit-box-sizing:border-box;\
-moz-box-sizing: border-box;\
font-size: 10pt;\
resize: vertical;\
resize: vertical horizontal;\
}\
#quick-reply input, #quick-reply select, #quick-reply textarea {\
margin: 0 0 1px 0;\
@ -115,7 +116,7 @@
#quick-reply td.recaptcha-response {\
padding: 0 0 1px 0;\
}\
@media screen and (max-width: 800px) {\
@media screen and (max-width: 400px) {\
#quick-reply {\
display: none !important;\
}\
@ -363,7 +364,7 @@
$(window).ready(function() {
if (settings.get('hide_at_top', true)) {
$(window).scroll(function() {
if ($(this).width() <= 800)
if ($(this).width() <= 400)
return;
if ($(this).scrollTop() < $origPostForm.offset().top + $origPostForm.height() - 100)
$postForm.fadeOut(100);
@ -384,7 +385,7 @@
};
$(window).on('cite', function(e, id, with_link) {
if ($(this).width() <= 800)
if ($(this).width() <= 400)
return;
show_quick_reply();
if (with_link) {
@ -439,7 +440,7 @@
$('.quick-reply-btn').hide();
$(window).scroll(function() {
if ($(this).width() <= 800)
if ($(this).width() <= 400)
return;
if ($(this).scrollTop() < $('form[name="post"]:first').offset().top + $('form[name="post"]:first').height() - 100)
$('.quick-reply-btn').fadeOut(100);

116
js/thread-stats.js

@ -0,0 +1,116 @@
/*
* thread-stats.js
* - Adds statistics of the thread below the posts area
* - Shows ID post count beside each postID on hover
*
* Usage:
* $config['additional_javascript'][] = 'js/jquery.min.js';
* $config['additional_javascript'][] = 'js/thread-stats.js';
*/
if (active_page == 'thread') {
$(document).ready(function(){
//check if page uses unique ID
var IDsupport = ($('.poster_id').length > 0);
var thread_id = (document.location.pathname + document.location.search).split('/');
thread_id = thread_id[thread_id.length -1].split('+')[0].split('-')[0].split('.')[0];
$('.boardlist.bottom, footer')
.first()
.before('<div id="thread_stats"></div>');
var el = $('#thread_stats');
el.prepend(_('Page')+' <span id="thread_stats_page">?</span>');
if (IDsupport){
el.prepend('<span id="thread_stats_uids">0</span> UIDs |&nbsp;');
}
el.prepend('<span id="thread_stats_images">0</span> '+_('images')+' |&nbsp;');
el.prepend('<span id="thread_stats_posts">0</span> '+_('replies')+' |&nbsp;');
delete el;
function update_thread_stats(){
var op = $('#thread_'+ thread_id +' > div.post.op:not(.post-hover):not(.inline)').first();
var replies = $('#thread_'+ thread_id +' > div.post.reply:not(.post-hover):not(.inline)');
// post count
$('#thread_stats_posts').text(replies.length);
// image count
$('#thread_stats_images').text(replies.filter(function(){
return $(this).find('> .files').text().trim() != false;
}).length);
// unique ID count
if (IDsupport) {
var opID = op.find('> .intro > .poster_id').text();
var ids = {};
replies.each(function(){
var cur = $(this).find('> .intro > .poster_id');
var curID = cur.text();
if (ids[curID] === undefined) {
ids[curID] = 0;
}
ids[curID]++;
});
if (ids[opID] === undefined) {
ids[opID] = 0;
}
ids[opID]++;
var cur = op.find('>.intro >.poster_id');
cur.find('+.posts_by_id').remove();
cur.after('<span class="posts_by_id"> ('+ ids[cur.text()] +')</span>');
replies.each(function(){
cur = $(this).find('>.intro >.poster_id');
cur.find('+.posts_by_id').remove();
cur.after('<span class="posts_by_id"> ('+ ids[cur.text()] +')</span>');
});
var size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
$('#thread_stats_uids').text(size(ids));
}
var board_name = $('input[name="board"]').val();
$.getJSON('//'+ document.location.host +'/'+ board_name +'/threads.json').success(function(data){
var found, page = '???';
for (var i=0;data[i];i++){
var threads = data[i].threads;
for (var j=0; threads[j]; j++){
if (parseInt(threads[j].no) == parseInt(thread_id)) {
page = data[i].page +1;
found = true;
break;
}
}
if (found) break;
}
$('#thread_stats_page').text(page);
if (!found) $('#thread_stats_page').css('color','red');
else $('#thread_stats_page').css('color','');
});
}
// load the current page the thread is on.
// uses ajax call so it gets loaded on a delay (depending on network resources available)
var thread_stats_page_timer = setInterval(function(){
var board_name = $('input[name="board"]').val();
$.getJSON('//'+ document.location.host +'/'+ board_name +'/threads.json').success(function(data){
var found, page = '???';
for (var i=0;data[i];i++){
var threads = data[i].threads;
for (var j=0; threads[j]; j++){
if (parseInt(threads[j].no) == parseInt(thread_id)) {
page = data[i].page +1;
found = true;
break;
}
}
if (found) break;
}
$('#thread_stats_page').text(page);
if (!found) $('#thread_stats_page').css('color','red');
else $('#thread_stats_page').css('color','');
});
},30000);
$('body').append('<style>.posts_by_id{display:none;}.poster_id:hover+.posts_by_id{display:initial}</style>');
update_thread_stats();
$('#update_thread').click(update_thread_stats);
$(document).on('new_post',update_thread_stats);
});
}

2
js/toggle-images.js

@ -60,7 +60,7 @@ $(document).ready(function(){
if (window.Options && Options.get_tab('general')) {
selector = '#toggle-images>input';
event = 'change';
Options.extend_tab("general", "<label id='toggle-images'><input type='checkbox' /> "+_('Hide images')+"</label>");
Options.extend_tab("general", "<label id='toggle-images'><input type='checkbox' />"+_('Hide images')+"</label>");
}
else {
selector = '#toggle-images a';

48
js/treeview.js

@ -11,14 +11,28 @@
*
*/
if (active_page == 'thread')
if (active_page == 'thread' || active_page == 'ukko' || active_page == 'index')
$(function() {
$('hr:first').before('<div id="treeview" style="text-align:right"><a class="unimportant" href="javascript:void(0)"></a></div>');
$('div#treeview a')
.text(_('Tree view'))
.click(function(e) {
e.preventDefault();
if (window.Options && Options.get_tab('general')) {
var selector = '#treeview-global>input';
Options.extend_tab("general", "<label id='treeview-global'><input type='checkbox' /> "+_('Use tree view by default')+"</label>");
$(selector).on('change', function() {
if (localStorage.treeview === 'true') {
localStorage.treeview = 'false';
} else {
localStorage.treeview = 'true';
}
});
if (localStorage.treeview === 'true') {
$(selector).attr('checked', 'checked');
}
}
});
if (active_page == 'thread')
$(function() {
var treeview = function(enable) {
if (enable === true) {
$('.post.reply').each(function(){
var references = [];
$(this).find('.body a').each(function(){
@ -26,7 +40,6 @@ $(function() {
references.push(parseInt($(this).html().replace('&gt;&gt;', '')));
}
});
var maxref = references.reduce(function(a,b) { return a > b ? a : b; }, 0);
var parent_post = $("#reply_"+maxref);
@ -39,7 +52,24 @@ $(function() {
post.detach().css("margin-left", margin).insertAfter(parent_post.next());
br.detach().insertAfter(post);
});
});
} else {
$('.post.reply').sort(function(a,b) {
return parseInt(a.id.replace('reply_', '')) - parseInt(b.id.replace('reply_', ''));
}).each(function () {
var post = $(this);
var br = post.next();
post.detach().css('margin-left', '').appendTo('.thread');
br.detach().insertAfter(post);
});
}
}
$('hr:first').before('<div class="unimportant" style="text-align:right"><label for="treeview"><input type="checkbox" id="treeview"> '+_('Tree view')+'</label></div>');
$('input#treeview').on('change', function(e) { treeview($(this).is(':checked')); });
if (localStorage.treeview === 'true') {
treeview(true);
$('input#treeview').attr('checked', true);
}
});

2
js/upload-selection.js

@ -25,6 +25,7 @@ $(function(){
$("#upload_url").hide();
$("#upload_embed").hide();
$(".add_image").hide();
$(".dropzone-wrap").hide();
$('[id^=upload_file]').each(function(i, v) {
$(v).val('');
@ -40,6 +41,7 @@ $(function(){
enable_file = function() {
disable_all();
$("#upload").show();
$(".dropzone-wrap").show();
$(".file_separator").show();
$("[id^=upload_file]").show();
$(".add_image").show();

2
js/wPaint

@ -1 +1 @@
Subproject commit 2c272dffca0f3d7b7163bd82ba15629f54409278
Subproject commit f11220032e7edb8349516d3751d3aaee0fd0de68

9
js/watch.js

@ -98,6 +98,9 @@ $(function(){
else {
bc.threads = bc.threads || {};
bc.threads[thread] = Date.now();
bc.slugs = bc.slugs || {};
bc.slugs[thread] = document.location.pathname + document.location.search;
}
st[board] = bc;
storage_save(st);
@ -121,7 +124,7 @@ $(function(){
var tag;
if (variant == 'desktop') {
tag = $("<a href='"+modRoot+board+"/res/"+tid+".html'><span>#"+tid+"</span><span class='cb-uri watch-remove'>"+newposts+"</span>");
tag = $("<a href='"+((storage()[board].slugs && storage()[board].slugs[tid]) || (modRoot+board+"/res/"+tid+".html"))+"'><span>#"+tid+"</span><span class='cb-uri watch-remove'>"+newposts+"</span>");
tag.find(".watch-remove").mouseenter(function() {
this.oldval = $(this).html();
$(this).css("min-width", $(this).width());
@ -132,7 +135,7 @@ $(function(){
})
}
else if (variant == 'mobile') {
tag = $("<a href='"+modRoot+board+"/res/"+tid+".html'><span>#"+tid+"</span><span class='cb-uri'>"+newposts+"</span>"
tag = $("<a href='"+((storage()[board].slugs && storage()[board].slugs[tid]) || (modRoot+board+"/res/"+tid+".html"))+"'><span>#"+tid+"</span><span class='cb-uri'>"+newposts+"</span>"
+"<span class='cb-uri watch-remove'><i class='fa fa-minus'></i></span>");
}
@ -245,7 +248,7 @@ $(function(){
var st = storage();
var sched = 0;
var sched_diff = 300;
var sched_diff = 2000;
for (var i in st) {
if (st[i].watched) {

9
js/wpaint.js

@ -13,12 +13,7 @@
* $config['additional_javascript'][] = 'js/jquery.min.js';
* $config['additional_javascript'][] = 'js/jquery-ui.custom.min.js';
* $config['additional_javascript'][] = 'js/ajax.js';
* $config['additional_javascript'][] = 'js/wPaint/lib/wColorPicker.min.js';
* $config['additional_javascript'][] = 'js/wPaint/wPaint.min.js';
* $config['additional_javascript'][] = 'js/wPaint/plugins/main/wPaint.menu.main.min.js';
* $config['additional_javascript'][] = 'js/wPaint/plugins/text/wPaint.menu.text.min.js';
* $config['additional_javascript'][] = 'js/wPaint/plugins/shapes/wPaint.menu.main.shapes.min.js';
* $config['additional_javascript'][] = 'js/wPaint/plugins/file/wPaint.menu.main.file.min.js';
* $config['additional_javascript'][] = 'js/wPaint/8ch.js';
* $config['additional_javascript'][] = 'js/wpaint.js';
* $config['additional_javascript'][] = 'js/upload-selection.js';
*
@ -49,7 +44,7 @@ oekaki.init = function() {
var oekaki_form = '<tr id="oekaki"><th>Oekaki</th><td><div id="wpaintctr"><div id="wpaintdiv"></div></div></td></tr>';
// Add oekaki after the file input
$('form[name="post"]:not(#quick-reply) input[type="file"]').parent().parent().after(oekaki_form);
$('form[name="post"]:not(#quick-reply) [id="upload"]').after(oekaki_form);
$('<link class="wpaintcss" rel="stylesheet" href="'+configRoot+'js/wPaint/wPaint.min.css" />').appendTo($("head"));
$('<link class="wpaintcss" rel="stylesheet" href="'+configRoot+'js/wPaint/lib/wColorPicker.min.css" />').appendTo($("head"));

7
mod.php

@ -4,9 +4,10 @@
* Copyright (c) 2010-2014 Tinyboard Development Group
*/
require 'inc/functions.php';
require 'inc/mod/pages.php';
require 'inc/mod/auth.php';
require_once 'inc/functions.php';
require_once 'inc/bans.php';
require_once 'inc/mod/pages.php';
require_once 'inc/mod/auth.php';
if ($config['debug'])
$parse_start_time = microtime(true);

81
post.php

@ -3,8 +3,9 @@
* Copyright (c) 2010-2014 Tinyboard Development Group
*/
require 'inc/functions.php';
require 'inc/anti-bot.php';
require_once 'inc/functions.php';
require_once 'inc/anti-bot.php';
require_once 'inc/bans.php';
// Fix for magic quotes
if (get_magic_quotes_gpc()) {
@ -92,18 +93,22 @@ if (isset($_POST['delete'])) {
buildIndex();
rebuildThemes('post-delete', $board['uri']);
$is_mod = isset($_POST['mod']) && $_POST['mod'];
$root = $is_mod ? $config['root'] . $config['file_mod'] . '?/' : $config['root'];
if (!isset($_POST['json_response'])) {
header('Location: ' . $root . $board['dir'] . $config['file_index'], true, $config['redirect_http']);
} else {
header('Content-Type: text/json');
echo json_encode(array('success' => true));
}
// We are already done, let's continue our heavy-lifting work in the background (if we run off FastCGI)
if (function_exists('fastcgi_finish_request'))
@fastcgi_finish_request();
rebuildThemes('post-delete', $board['uri']);
} elseif (isset($_POST['report'])) {
if (!isset($_POST['board'], $_POST['reason']))
error($config['error']['bot']);
@ -307,7 +312,12 @@ if (isset($_POST['delete'])) {
$url_without_params = $post['file_url'];
$post['extension'] = strtolower(mb_substr($url_without_params, mb_strrpos($url_without_params, '.') + 1));
if (!in_array($post['extension'], $config['allowed_ext']) && !in_array($post['extension'], $config['allowed_ext_files']))
if ($post['op'] && $config['allowed_ext_op']) {
if (!in_array($post['extension'], $config['allowed_ext_op']))
error($config['error']['unknownext']);
}
else if (!in_array($post['extension'], $config['allowed_ext']) && !in_array($post['extension'], $config['allowed_ext_files']))
error($config['error']['unknownext']);
$post['file_tmp'] = tempnam($config['tmp'], 'url');
@ -516,7 +526,7 @@ if (isset($_POST['delete'])) {
"\n<tinyboard flag alt>".geoip\geoip_country_name_by_addr_v6($gi, ipv4to6($_SERVER['REMOTE_ADDR']))."</tinyboard>";
}
}
if ($config['user_flag'] && isset($_POST['user_flag']))
if (!empty($_POST['user_flag']) ){
@ -530,6 +540,15 @@ if (isset($_POST['delete'])) {
$post['body'] .= "\n<tinyboard flag>" . strtolower($user_flag) . "</tinyboard>" .
"\n<tinyboard flag alt>" . $flag_alt . "</tinyboard>";
}
if ($config['allowed_tags'] && $post['op'] && isset($_POST['tag']) && isset($config['allowed_tags'][$_POST['tag']])) {
$post['body'] .= "\n<tinyboard tag>" . $_POST['tag'] . "</tinyboard>";
}
if ($config['proxy_save'] && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$proxy = preg_replace("/[^0-9a-fA-F.,: ]/", '', $_SERVER['HTTP_X_FORWARDED_FOR']);
$post['body'] .= "\n<tinyboard proxy>".$proxy."</tinyboard>";
}
if (mysql_version() >= 50503) {
$post['body_nomarkup'] = $post['body']; // Assume we're using the utf8mb4 charset
@ -555,7 +574,11 @@ if (isset($_POST['delete'])) {
if ($post['has_file']) {
$fnarray = array();
foreach ($post['files'] as $key => &$file) {
if (!in_array($file['extension'], $config['allowed_ext']) && !in_array($file['extension'], $config['allowed_ext_files']))
if ($post['op'] && $config['allowed_ext_op']) {
if (!in_array($file['extension'], $config['allowed_ext_op']))
error($config['error']['unknownext']);
}
elseif (!in_array($file['extension'], $config['allowed_ext']) && !in_array($file['extension'], $config['allowed_ext_files']))
error($config['error']['unknownext']);
$file['is_an_image'] = !in_array($file['extension'], $config['allowed_ext_files']);
@ -800,6 +823,7 @@ if (isset($_POST['delete'])) {
$post['num_files'] = sizeof($post['files']);
$post['id'] = $id = post($post);
$post['slug'] = slugify($post);
insertFloodPost($post);
@ -821,18 +845,6 @@ if (isset($_POST['delete'])) {
bumpThread($post['thread']);
}
buildThread($post['op'] ? $id : $post['thread']);
if ($config['try_smarter'] && $post['op'])
$build_pages = range(1, $config['max_pages']);
if ($post['op'])
clean();
event('post-after', $post);
buildIndex();
if (isset($_SERVER['HTTP_REFERER'])) {
// Tell Javascript that we posted successfully
if (isset($_COOKIE[$config['cookies']['js']]))
@ -869,6 +881,8 @@ if (isset($_POST['delete'])) {
$redirect = $root . $board['dir'] . $config['file_index'];
}
buildThread($post['op'] ? $id : $post['thread']);
if ($config['syslog'])
_syslog(LOG_INFO, 'New post: /' . $board['dir'] . $config['dir']['res'] .
@ -876,11 +890,6 @@ if (isset($_POST['delete'])) {
if (!$post['mod']) header('X-Associated-Content: "' . $redirect . '"');
if ($post['op'])
rebuildThemes('post-thread', $board['uri']);
else
rebuildThemes('post', $board['uri']);
if (!isset($_POST['json_response'])) {
header('Location: ' . $redirect, true, $config['redirect_http']);
} else {
@ -891,6 +900,26 @@ if (isset($_POST['delete'])) {
'id' => $id
));
}
if ($config['try_smarter'] && $post['op'])
$build_pages = range(1, $config['max_pages']);
if ($post['op'])
clean();
event('post-after', $post);
buildIndex();
// We are already done, let's continue our heavy-lifting work in the background (if we run off FastCGI)
if (function_exists('fastcgi_finish_request'))
@fastcgi_finish_request();
if ($post['op'])
rebuildThemes('post-thread', $board['uri']);
else
rebuildThemes('post', $board['uri']);
} elseif (isset($_POST['appeal'])) {
if (!isset($_POST['ban_id']))
error($config['error']['bot']);

216
smart_build.php

@ -0,0 +1,216 @@
<?php
require_once("inc/functions.php");
if (!$config['smart_build']) {
die('You need to enable $config["smart_build"]');
}
$config['smart_build'] = false; // Let's disable it, so we can build the page for real
function after_open_board() { global $config;
$config['smart_build'] = false;
};
function sb_board($b, $page = 1) { global $config, $build_pages; $page = (int)$page;
if ($page < 1) return false;
if (!openBoard($b)) return false;
if ($page > $config['max_pages']) return false;
$config['try_smarter'] = true;
$build_pages = array($page);
buildIndex("skip");
return true;
}
function sb_api_board($b, $page = 0) { $page = (int)$page;
return sb_board($b, $page + 1);
}
function sb_thread($b, $thread, $slugcheck = false) { global $config; $thread = (int)$thread;
if ($thread < 1) return false;
if (!preg_match('/^'.$config['board_regex'].'$/u', $b)) return false;
if (Cache::get("thread_exists_".$b."_".$thread) == "no") return false;
$query = prepare(sprintf("SELECT MAX(`id`) AS `max` FROM ``posts_%s``", $b));
if (!$query->execute()) return false;
$s = $query->fetch(PDO::FETCH_ASSOC);
$max = $s['max'];
if ($thread > $max) return false;
$query = prepare(sprintf("SELECT `id` FROM ``posts_%s`` WHERE `id` = :id AND `thread` IS NULL", $b));
$query->bindValue(':id', $thread);
if (!$query->execute() || !$query->fetch(PDO::FETCH_ASSOC) ) {
Cache::set("thread_exists_".$b."_".$thread, "no");
return false;
}
if ($slugcheck && $config['slugify']) {
global $request;
$link = link_for(array("id" => $thread), $slugcheck === 50, array("uri" => $b));
$link = "/".$b."/".$config['dir']['res'].$link;
if ($link != $request) {
header("Location: $link", true, 301);
die();
}
}
if ($slugcheck == 50) { // Should we really generate +50 page? Maybe there are not enough posts anyway
global $request;
$r = str_replace("+50", "", $request);
$r = substr($r, 1); // Cut the slash
if (file_exists($r)) return false;
}
if (!openBoard($b)) return false;
buildThread($thread);
return true;
}
function sb_thread_slugcheck($b, $thread) {
return sb_thread($b, $thread, true);
}
function sb_thread_slugcheck50($b, $thread) {
return sb_thread($b, $thread, 50);
}
function sb_api($b) { global $config, $build_pages;
if (!openBoard($b)) return false;
$config['try_smarter'] = true;
$build_pages = array(-1);
buildIndex();
return true;
}
function sb_ukko() {
rebuildTheme("ukko", "post-thread");
return true;
}
function sb_catalog($b) {
if (!openBoard($b)) return false;
rebuildTheme("catalog", "post-thread", $b);
return true;
}
function sb_recent() {
rebuildTheme("recent", "post-thread");
return true;
}
function sb_sitemap() {
rebuildTheme("sitemap", "all");
return true;
}
$entrypoints = array();
$entrypoints['/%b/'] = 'sb_board';
$entrypoints['/%b/'.$config['file_index']] = 'sb_board';
$entrypoints['/%b/'.$config['file_page']] = 'sb_board';
$entrypoints['/%b/%d.json'] = 'sb_api_board';
if ($config['api']['enabled']) {
$entrypoints['/%b/threads.json'] = 'sb_api';
$entrypoints['/%b/catalog.json'] = 'sb_api';
}
$entrypoints['/%b/'.$config['dir']['res'].$config['file_page']] = 'sb_thread_slugcheck';
$entrypoints['/%b/'.$config['dir']['res'].$config['file_page50']] = 'sb_thread_slugcheck50';
if ($config['slugify']) {
$entrypoints['/%b/'.$config['dir']['res'].$config['file_page_slug']] = 'sb_thread_slugcheck';
$entrypoints['/%b/'.$config['dir']['res'].$config['file_page50_slug']] = 'sb_thread_slugcheck50';
}
if ($config['api']['enabled']) {
$entrypoints['/%b/'.$config['dir']['res'].'%d.json'] = 'sb_thread';
}
$entrypoints['/*/'] = 'sb_ukko';
$entrypoints['/*/index.html'] = 'sb_ukko';
$entrypoints['/recent.html'] = 'sb_recent';
$entrypoints['/%b/catalog.html'] = 'sb_catalog';
$entrypoints['/sitemap.xml'] = 'sb_sitemap';
$reached = false;
$request = $_SERVER['REQUEST_URI'];
list($request) = explode('?', $request);
foreach ($entrypoints as $id => $fun) {
$id = '@^' . preg_quote($id, '@') . '$@u';
$id = str_replace('%b', '('.$config['board_regex'].')', $id);
$id = str_replace('%d', '([0-9]+)', $id);
$id = str_replace('%s', '[a-zA-Z0-9-]+', $id);
$matches = null;
if (preg_match ($id, $request, $matches)) {
array_shift($matches);
$reached = call_user_func_array($fun, $matches);
break;
}
}
function die_404() { global $config;
if (!$config['page_404']) {
header("HTTP/1.1 404 Not Found");
header("Status: 404 Not Found");
echo "<h1>404 Not Found</h1><p>Page doesn't exist<hr><address>vichan</address>";
}
else {
header("Location: ".$config['page_404']);
}
header("X-Accel-Expires: 120");
die();
}
if ($reached) {
if ($request[strlen($request)-1] == '/') {
$request .= 'index.html';
}
$request = '.'.$request;
if (!file_exists($request)) {
die_404();
}
header("HTTP/1.1 200 OK");
header("Status: 200 OK");
if (preg_match('/\.json$/', $request)) {
header("Content-Type", "application/json");
}
elseif (preg_match('/\.js$/', $request)) {
header("Content-Type", "text/javascript; charset=utf-8");
}
elseif (preg_match('/\.xml$/', $request)) {
header("Content-Type", "application/xml");
}
else {
header("Content-Type", "text/html; charset=utf-8");
}
header("Cache-Control: public, nocache, no-cache, max-age=0, must-revalidate");
header("Expires: Fri, 22 Feb 1991 06:00:00 GMT");
header("Last-Modified: ".date('r', filemtime($request)));
//if (isset ($_SERVER['HTTP_ACCEPT_ENCODING']) && preg_match('/gzip/', $_SERVER['HTTP_ACCEPT_ENCODING']) && file_exists($request.".gz")) {
// header("Content-Encoding: gzip");
// $file = fopen($request.".gz", 'r');
//}
//else {
$file = fopen($request, 'r');
//}
fpassthru($file);
fclose($file);
}
else {
die_404();
}

2
stylesheets/burichan.css

@ -36,7 +36,7 @@ div.banner {
font-weight: normal;
}
p.intro span.name {
.intro span.name {
font-family: serif;
font-size: 12px;
}

2
stylesheets/caffe.css

@ -353,7 +353,7 @@ width: 100%;
#attention_bar:hover {
background-color: rgba(88, 53, 41, 0.3);
}
p.intro a.email span.name {
.intro a.email span.name {
color: #8e6152;
}
a.post_no:hover {

8
stylesheets/confraria.css

@ -55,11 +55,11 @@ form table tr th {
padding: 0px 5px;
}
p.intro span.name {
.intro span.name {
color: #C5C8C6;
}
p.intro span.subject {
.intro span.subject {
color: #CC1105;
font-weight: bold;
}
@ -90,11 +90,11 @@ div.post.reply.highlighted {
background: #4A4C4F;
}
p.intro a.email span.name {
.intro a.email span.name {
color: rgb(129, 162, 190);
}
p.intro a.email:hover span.name {
.intro a.email:hover span.name {
color: rgb(95, 137, 172);
}

18
stylesheets/dark.css

@ -23,7 +23,7 @@ div.title, h1 {
div.title p {
font-size: 10px;
}
a:link, a:visited, p.intro a.email span.name {
a:link, a:visited, .intro a.email span.name {
color: #CCCCCC;
text-decoration: none;
font-family: sans-serif;
@ -61,21 +61,21 @@ div.post.reply div.body a:link, div.post.reply div.body a:visited {
div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover {
color: #32DD72;
}
p.intro span.subject {
.intro span.subject {
font-size: 12px;
font-family: sans-serif;
color: #446655;
font-weight: 800;
}
p.intro span.name {
.intro span.name {
color: #32DD72;
font-weight: 800;
}
p.intro a.capcode, p.intro a.nametag {
.intro a.capcode, p.intro a.nametag {
color: magenta;
margin-left: 0;
}
p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name {
.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name {
color: #32ddaf;
}
input[type="text"], textarea, select {
@ -166,13 +166,13 @@ table.modlog tr th {
color: #AAAAAA;
}
.desktop-style div.boardlist:nth-child(1) {
.desktop-style div.boardlist:not(.bottom) {
text-shadow: black 1px 1px 1px, black -1px -1px 1px, black -1px 1px 1px, black 1px -1px 1px;
background-color: #666666;
}
.desktop-style div.boardlist:nth-child(1):hover, .desktop-style div.boardlist:nth-child(1).cb-menu {
.desktop-style div.boardlist:not(.bottom):hover, .desktop-style div.boardlist:not(.bottom).cb-menu {
background-color: rgba(30%, 30%, 30%, 0.65);
}
@ -190,3 +190,7 @@ div.report {
.options_tab_icon.active {
color: #FFFFFF;
}
#quick-reply table {
background: none repeat scroll 0% 0% #333 !important;
}

24
stylesheets/dark_roach.css

@ -20,7 +20,7 @@ a, a:visited {
text-decoration: none;
color: #9999CC;
}
a:hover, p.intro a.post_no:hover {
a:hover, .intro a.post_no:hover {
color: #996699
}
a.post_no {
@ -28,19 +28,19 @@ a.post_no {
margin: 0;
padding: 0;
}
p.intro a.post_no {
.intro a.post_no {
color: inherit;
}
p.intro a.post_no, p.intro a.email {
.intro a.post_no, p.intro a.email {
margin: 0;
}
p.intro a.email span.name {
.intro a.email span.name {
color: #666699;
}
p.intro a.email:hover span.name {
.intro a.email:hover span.name {
color: #663366;
}
p.intro label {
.intro label {
display: inline;
}
h2 {
@ -163,7 +163,7 @@ div.post.op {
div.post.op hr {
border-color: #000000;
}
p.intro {
.intro {
margin: 0.5em 0;
padding: 0;
padding-bottom: 0.2em;
@ -172,19 +172,19 @@ input.delete {
float: left;
margin: 1px 6px 0 0;
}
p.intro span.subject {
.intro span.subject {
color: #336699;
font-weight: bold;
}
p.intro span.name {
.intro span.name {
color: #336600;
font-weight: bold;
}
p.intro span.capcode, p.intro a.capcode, p.intro a.nametag {
.intro span.capcode, p.intro a.capcode, p.intro a.nametag {
color: #CC0000;
margin-left: 0;
}
p.intro a {
.intro a {
margin-left: 8px;
}
div.delete {
@ -456,7 +456,7 @@ table.mod.config-editor input[type="text"] {
background-color: #333333;
opacity: 0.8;
}
p.intro.thread-hidden {
.intro.thread-hidden {
margin: 0px;
padding: 0px;
}

4
stylesheets/favela.css

@ -46,7 +46,7 @@ form table tr th {
color: #FFF;
}
p.intro span.name {
.intro span.name {
font-family: serif;
}
@ -81,7 +81,7 @@ div[id^="thread_"].highlighted {
background: #B5FFDD;
}
p.intro a.email span.name {
.intro a.email span.name {
color: #345456;
}

10
stylesheets/ferus.css

@ -16,7 +16,7 @@ div.title, h1 {
div.title p {
font-size: 13px;
}
a:link, a:visited, p.intro a.email span.name {
a:link, a:visited, .intro a.email span.name {
color: #16C816;
text-decoration: underline;
font-family: monospace;
@ -51,21 +51,21 @@ div.post.reply div.body a:link, div.post.reply div.body a:visited {
div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover {
color: #00FF00;
}
p.intro span.subject {
.intro span.subject {
font-size: 12px;
font-family: monospace;
color: #446655;
font-weight: 800;
}
p.intro span.name {
.intro span.name {
color: #008200;
font-weight: 900;
}
p.intro a.capcode, p.intro a.nametag {
.intro a.capcode, p.intro a.nametag {
color: magenta;
margin-left: 0;
}
p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name {
.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name {
color: #00CC64;
font-family: monospace;
}

542
stylesheets/font-awesome/css/font-awesome.css

@ -1,22 +1,21 @@
/*!
* Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
* Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
*/
/* FONT PATH
* -------------------------- */
@font-face {
font-family: 'FontAwesome';
src: url('../fonts/fontawesome-webfont.eot?v=4.1.0');
src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');
src: url('../fonts/fontawesome-webfont.eot?v=4.4.0');
src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.4.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.4.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.4.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.4.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular') format('svg');
font-weight: normal;
font-style: normal;
}
.fa {
display: inline-block;
font-family: FontAwesome;
font-style: normal;
font-weight: normal;
line-height: 1;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@ -65,6 +64,19 @@
border: solid 0.08em #eeeeee;
border-radius: .1em;
}
.fa-pull-left {
float: left;
}
.fa-pull-right {
float: right;
}
.fa.fa-pull-left {
margin-right: .3em;
}
.fa.fa-pull-right {
margin-left: .3em;
}
/* Deprecated as of 4.4.0 */
.pull-right {
float: right;
}
@ -78,36 +90,24 @@
margin-left: .3em;
}
.fa-spin {
-webkit-animation: spin 2s infinite linear;
-moz-animation: spin 2s infinite linear;
-o-animation: spin 2s infinite linear;
animation: spin 2s infinite linear;
-webkit-animation: fa-spin 2s infinite linear;
animation: fa-spin 2s infinite linear;
}
@-moz-keyframes spin {
0% {
-moz-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(359deg);
}
.fa-pulse {
-webkit-animation: fa-spin 1s infinite steps(8);
animation: fa-spin 1s infinite steps(8);
}
@-webkit-keyframes spin {
@-webkit-keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@-o-keyframes spin {
0% {
-o-transform: rotate(0deg);
}
100% {
-o-transform: rotate(359deg);
}
}
@keyframes spin {
@keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
@ -120,43 +120,40 @@
.fa-rotate-90 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-ms-transform: rotate(90deg);
-o-transform: rotate(90deg);
transform: rotate(90deg);
}
.fa-rotate-180 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-ms-transform: rotate(180deg);
-o-transform: rotate(180deg);
transform: rotate(180deg);
}
.fa-rotate-270 {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
-webkit-transform: rotate(270deg);
-moz-transform: rotate(270deg);
-ms-transform: rotate(270deg);
-o-transform: rotate(270deg);
transform: rotate(270deg);
}
.fa-flip-horizontal {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);
-webkit-transform: scale(-1, 1);
-moz-transform: scale(-1, 1);
-ms-transform: scale(-1, 1);
-o-transform: scale(-1, 1);
transform: scale(-1, 1);
}
.fa-flip-vertical {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);
-webkit-transform: scale(1, -1);
-moz-transform: scale(1, -1);
-ms-transform: scale(1, -1);
-o-transform: scale(1, -1);
transform: scale(1, -1);
}
:root .fa-rotate-90,
:root .fa-rotate-180,
:root .fa-rotate-270,
:root .fa-flip-horizontal,
:root .fa-flip-vertical {
filter: none;
}
.fa-stack {
position: relative;
display: inline-block;
@ -222,6 +219,8 @@
.fa-check:before {
content: "\f00c";
}
.fa-remove:before,
.fa-close:before,
.fa-times:before {
content: "\f00d";
}
@ -551,7 +550,8 @@
.fa-arrows-h:before {
content: "\f07e";
}
.fa-bar-chart-o:before {
.fa-bar-chart-o:before,
.fa-bar-chart:before {
content: "\f080";
}
.fa-twitter-square:before {
@ -627,6 +627,7 @@
.fa-twitter:before {
content: "\f099";
}
.fa-facebook-f:before,
.fa-facebook:before {
content: "\f09a";
}
@ -639,6 +640,7 @@
.fa-credit-card:before {
content: "\f09d";
}
.fa-feed:before,
.fa-rss:before {
content: "\f09e";
}
@ -1276,7 +1278,8 @@
.fa-male:before {
content: "\f183";
}
.fa-gittip:before {
.fa-gittip:before,
.fa-gratipay:before {
content: "\f184";
}
.fa-sun-o:before {
@ -1380,7 +1383,6 @@
.fa-digg:before {
content: "\f1a6";
}
.fa-pied-piper-square:before,
.fa-pied-piper:before {
content: "\f1a7";
}
@ -1497,6 +1499,7 @@
content: "\f1cc";
}
.fa-life-bouy:before,
.fa-life-buoy:before,
.fa-life-saver:before,
.fa-support:before,
.fa-life-ring:before {
@ -1519,6 +1522,8 @@
.fa-git:before {
content: "\f1d3";
}
.fa-y-combinator-square:before,
.fa-yc-square:before,
.fa-hacker-news:before {
content: "\f1d4";
}
@ -1564,3 +1569,458 @@
.fa-bomb:before {
content: "\f1e2";
}
.fa-soccer-ball-o:before,
.fa-futbol-o:before {
content: "\f1e3";
}
.fa-tty:before {
content: "\f1e4";
}
.fa-binoculars:before {
content: "\f1e5";
}
.fa-plug:before {
content: "\f1e6";
}
.fa-slideshare:before {
content: "\f1e7";
}
.fa-twitch:before {
content: "\f1e8";
}
.fa-yelp:before {
content: "\f1e9";
}
.fa-newspaper-o:before {
content: "\f1ea";
}
.fa-wifi:before {
content: "\f1eb";
}
.fa-calculator:before {
content: "\f1ec";
}
.fa-paypal:before {
content: "\f1ed";
}
.fa-google-wallet:before {
content: "\f1ee";
}
.fa-cc-visa:before {
content: "\f1f0";
}
.fa-cc-mastercard:before {
content: "\f1f1";
}
.fa-cc-discover:before {
content: "\f1f2";
}
.fa-cc-amex:before {
content: "\f1f3";
}
.fa-cc-paypal:before {
content: "\f1f4";
}
.fa-cc-stripe:before {
content: "\f1f5";
}
.fa-bell-slash:before {
content: "\f1f6";
}
.fa-bell-slash-o:before {
content: "\f1f7";
}
.fa-trash:before {
content: "\f1f8";
}
.fa-copyright:before {
content: "\f1f9";
}
.fa-at:before {
content: "\f1fa";
}
.fa-eyedropper:before {
content: "\f1fb";
}
.fa-paint-brush:before {
content: "\f1fc";
}
.fa-birthday-cake:before {
content: "\f1fd";
}
.fa-area-chart:before {
content: "\f1fe";
}
.fa-pie-chart:before {
content: "\f200";
}
.fa-line-chart:before {
content: "\f201";
}
.fa-lastfm:before {
content: "\f202";
}
.fa-lastfm-square:before {
content: "\f203";
}
.fa-toggle-off:before {
content: "\f204";
}
.fa-toggle-on:before {
content: "\f205";
}
.fa-bicycle:before {
content: "\f206";
}
.fa-bus:before {
content: "\f207";
}
.fa-ioxhost:before {
content: "\f208";
}
.fa-angellist:before {
content: "\f209";
}
.fa-cc:before {
content: "\f20a";
}
.fa-shekel:before,
.fa-sheqel:before,
.fa-ils:before {
content: "\f20b";
}
.fa-meanpath:before {
content: "\f20c";
}
.fa-buysellads:before {
content: "\f20d";
}
.fa-connectdevelop:before {
content: "\f20e";
}
.fa-dashcube:before {
content: "\f210";
}
.fa-forumbee:before {
content: "\f211";
}
.fa-leanpub:before {
content: "\f212";
}
.fa-sellsy:before {
content: "\f213";
}
.fa-shirtsinbulk:before {
content: "\f214";
}
.fa-simplybuilt:before {
content: "\f215";
}
.fa-skyatlas:before {
content: "\f216";
}
.fa-cart-plus:before {
content: "\f217";
}
.fa-cart-arrow-down:before {
content: "\f218";
}
.fa-diamond:before {
content: "\f219";
}
.fa-ship:before {
content: "\f21a";
}
.fa-user-secret:before {
content: "\f21b";
}
.fa-motorcycle:before {
content: "\f21c";
}
.fa-street-view:before {
content: "\f21d";
}
.fa-heartbeat:before {
content: "\f21e";
}
.fa-venus:before {
content: "\f221";
}
.fa-mars:before {
content: "\f222";
}
.fa-mercury:before {
content: "\f223";
}
.fa-intersex:before,
.fa-transgender:before {
content: "\f224";
}
.fa-transgender-alt:before {
content: "\f225";
}
.fa-venus-double:before {
content: "\f226";
}
.fa-mars-double:before {
content: "\f227";
}
.fa-venus-mars:before {
content: "\f228";
}
.fa-mars-stroke:before {
content: "\f229";
}
.fa-mars-stroke-v:before {
content: "\f22a";
}
.fa-mars-stroke-h:before {
content: "\f22b";
}
.fa-neuter:before {
content: "\f22c";
}
.fa-genderless:before {
content: "\f22d";
}
.fa-facebook-official:before {
content: "\f230";
}
.fa-pinterest-p:before {
content: "\f231";
}
.fa-whatsapp:before {
content: "\f232";
}
.fa-server:before {
content: "\f233";
}
.fa-user-plus:before {
content: "\f234";
}
.fa-user-times:before {
content: "\f235";
}
.fa-hotel:before,
.fa-bed:before {
content: "\f236";
}
.fa-viacoin:before {
content: "\f237";
}
.fa-train:before {
content: "\f238";
}
.fa-subway:before {
content: "\f239";
}
.fa-medium:before {
content: "\f23a";
}
.fa-yc:before,
.fa-y-combinator:before {
content: "\f23b";
}
.fa-optin-monster:before {
content: "\f23c";
}
.fa-opencart:before {
content: "\f23d";
}
.fa-expeditedssl:before {
content: "\f23e";
}
.fa-battery-4:before,
.fa-battery-full:before {
content: "\f240";
}
.fa-battery-3:before,
.fa-battery-three-quarters:before {
content: "\f241";
}
.fa-battery-2:before,
.fa-battery-half:before {
content: "\f242";
}
.fa-battery-1:before,
.fa-battery-quarter:before {
content: "\f243";
}
.fa-battery-0:before,
.fa-battery-empty:before {
content: "\f244";
}
.fa-mouse-pointer:before {
content: "\f245";
}
.fa-i-cursor:before {
content: "\f246";
}
.fa-object-group:before {
content: "\f247";
}
.fa-object-ungroup:before {
content: "\f248";
}
.fa-sticky-note:before {
content: "\f249";
}
.fa-sticky-note-o:before {
content: "\f24a";
}
.fa-cc-jcb:before {
content: "\f24b";
}
.fa-cc-diners-club:before {
content: "\f24c";
}
.fa-clone:before {
content: "\f24d";
}
.fa-balance-scale:before {
content: "\f24e";
}
.fa-hourglass-o:before {
content: "\f250";
}
.fa-hourglass-1:before,
.fa-hourglass-start:before {
content: "\f251";
}
.fa-hourglass-2:before,
.fa-hourglass-half:before {
content: "\f252";
}
.fa-hourglass-3:before,
.fa-hourglass-end:before {
content: "\f253";
}
.fa-hourglass:before {
content: "\f254";
}
.fa-hand-grab-o:before,
.fa-hand-rock-o:before {
content: "\f255";
}
.fa-hand-stop-o:before,
.fa-hand-paper-o:before {
content: "\f256";
}
.fa-hand-scissors-o:before {
content: "\f257";
}
.fa-hand-lizard-o:before {
content: "\f258";
}
.fa-hand-spock-o:before {
content: "\f259";
}
.fa-hand-pointer-o:before {
content: "\f25a";
}
.fa-hand-peace-o:before {
content: "\f25b";
}
.fa-trademark:before {
content: "\f25c";
}
.fa-registered:before {
content: "\f25d";
}
.fa-creative-commons:before {
content: "\f25e";
}
.fa-gg:before {
content: "\f260";
}
.fa-gg-circle:before {
content: "\f261";
}
.fa-tripadvisor:before {
content: "\f262";
}
.fa-odnoklassniki:before {
content: "\f263";
}
.fa-odnoklassniki-square:before {
content: "\f264";
}
.fa-get-pocket:before {
content: "\f265";
}
.fa-wikipedia-w:before {
content: "\f266";
}
.fa-safari:before {
content: "\f267";
}
.fa-chrome:before {
content: "\f268";
}
.fa-firefox:before {
content: "\f269";
}
.fa-opera:before {
content: "\f26a";
}
.fa-internet-explorer:before {
content: "\f26b";
}
.fa-tv:before,
.fa-television:before {
content: "\f26c";
}
.fa-contao:before {
content: "\f26d";
}
.fa-500px:before {
content: "\f26e";
}
.fa-amazon:before {
content: "\f270";
}
.fa-calendar-plus-o:before {
content: "\f271";
}
.fa-calendar-minus-o:before {
content: "\f272";
}
.fa-calendar-times-o:before {
content: "\f273";
}
.fa-calendar-check-o:before {
content: "\f274";
}
.fa-industry:before {
content: "\f275";
}
.fa-map-pin:before {
content: "\f276";
}
.fa-map-signs:before {
content: "\f277";
}
.fa-map-o:before {
content: "\f278";
}
.fa-map:before {
content: "\f279";
}
.fa-commenting:before {
content: "\f27a";
}
.fa-commenting-o:before {
content: "\f27b";
}
.fa-houzz:before {
content: "\f27c";
}
.fa-vimeo:before {
content: "\f27d";
}
.fa-black-tie:before {
content: "\f27e";
}
.fa-fonticons:before {
content: "\f280";
}

4
stylesheets/font-awesome/css/font-awesome.min.css

File diff suppressed because one or more lines are too long

BIN
stylesheets/font-awesome/fonts/FontAwesome.otf

Binary file not shown.

BIN
stylesheets/font-awesome/fonts/fontawesome-webfont.eot

Binary file not shown.

1064
stylesheets/font-awesome/fonts/fontawesome-webfont.svg

File diff suppressed because it is too large

Before

Width:  |  Height:  |  Size: 248 KiB

After

Width:  |  Height:  |  Size: 348 KiB

BIN
stylesheets/font-awesome/fonts/fontawesome-webfont.ttf

Binary file not shown.

BIN
stylesheets/font-awesome/fonts/fontawesome-webfont.woff

Binary file not shown.

BIN
stylesheets/font-awesome/fonts/fontawesome-webfont.woff2

Binary file not shown.

34
stylesheets/font-awesome/less/animated.less

@ -0,0 +1,34 @@
// Animated Icons
// --------------------------
.@{fa-css-prefix}-spin {
-webkit-animation: fa-spin 2s infinite linear;
animation: fa-spin 2s infinite linear;
}
.@{fa-css-prefix}-pulse {
-webkit-animation: fa-spin 1s infinite steps(8);
animation: fa-spin 1s infinite steps(8);
}
@-webkit-keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}

9
stylesheets/font-awesome/less/bordered-pulled.less

@ -7,6 +7,15 @@
border-radius: .1em;
}
.@{fa-css-prefix}-pull-left { float: left; }
.@{fa-css-prefix}-pull-right { float: right; }
.@{fa-css-prefix} {
&.@{fa-css-prefix}-pull-left { margin-right: .3em; }
&.@{fa-css-prefix}-pull-right { margin-left: .3em; }
}
/* Deprecated as of 4.4.0 */
.pull-right { float: right; }
.pull-left { float: left; }

8
stylesheets/font-awesome/less/core.less

@ -3,10 +3,10 @@
.@{fa-css-prefix} {
display: inline-block;
font-family: FontAwesome;
font-style: normal;
font-weight: normal;
line-height: 1;
font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
font-size: inherit; // can't have font-size inherit on line above, so need to override
text-rendering: auto; // optimizelegibility throws things off #1094
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

4
stylesheets/font-awesome/less/font-awesome.less

@ -1,5 +1,5 @@
/*!
* Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
* Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
*/
@ -11,7 +11,7 @@
@import "fixed-width.less";
@import "list.less";
@import "bordered-pulled.less";
@import "spinning.less";
@import "animated.less";
@import "rotated-flipped.less";
@import "stacked.less";
@import "icons.less";

177
stylesheets/font-awesome/less/icons.less

@ -14,6 +14,8 @@
.@{fa-css-prefix}-th:before { content: @fa-var-th; }
.@{fa-css-prefix}-th-list:before { content: @fa-var-th-list; }
.@{fa-css-prefix}-check:before { content: @fa-var-check; }
.@{fa-css-prefix}-remove:before,
.@{fa-css-prefix}-close:before,
.@{fa-css-prefix}-times:before { content: @fa-var-times; }
.@{fa-css-prefix}-search-plus:before { content: @fa-var-search-plus; }
.@{fa-css-prefix}-search-minus:before { content: @fa-var-search-minus; }
@ -129,7 +131,8 @@
.@{fa-css-prefix}-folder-open:before { content: @fa-var-folder-open; }
.@{fa-css-prefix}-arrows-v:before { content: @fa-var-arrows-v; }
.@{fa-css-prefix}-arrows-h:before { content: @fa-var-arrows-h; }
.@{fa-css-prefix}-bar-chart-o:before { content: @fa-var-bar-chart-o; }
.@{fa-css-prefix}-bar-chart-o:before,
.@{fa-css-prefix}-bar-chart:before { content: @fa-var-bar-chart; }
.@{fa-css-prefix}-twitter-square:before { content: @fa-var-twitter-square; }
.@{fa-css-prefix}-facebook-square:before { content: @fa-var-facebook-square; }
.@{fa-css-prefix}-camera-retro:before { content: @fa-var-camera-retro; }
@ -155,10 +158,12 @@
.@{fa-css-prefix}-bookmark-o:before { content: @fa-var-bookmark-o; }
.@{fa-css-prefix}-phone-square:before { content: @fa-var-phone-square; }
.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; }
.@{fa-css-prefix}-facebook-f:before,
.@{fa-css-prefix}-facebook:before { content: @fa-var-facebook; }
.@{fa-css-prefix}-github:before { content: @fa-var-github; }
.@{fa-css-prefix}-unlock:before { content: @fa-var-unlock; }
.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; }
.@{fa-css-prefix}-feed:before,
.@{fa-css-prefix}-rss:before { content: @fa-var-rss; }
.@{fa-css-prefix}-hdd-o:before { content: @fa-var-hdd-o; }
.@{fa-css-prefix}-bullhorn:before { content: @fa-var-bullhorn; }
@ -394,7 +399,8 @@
.@{fa-css-prefix}-trello:before { content: @fa-var-trello; }
.@{fa-css-prefix}-female:before { content: @fa-var-female; }
.@{fa-css-prefix}-male:before { content: @fa-var-male; }
.@{fa-css-prefix}-gittip:before { content: @fa-var-gittip; }
.@{fa-css-prefix}-gittip:before,
.@{fa-css-prefix}-gratipay:before { content: @fa-var-gratipay; }
.@{fa-css-prefix}-sun-o:before { content: @fa-var-sun-o; }
.@{fa-css-prefix}-moon-o:before { content: @fa-var-moon-o; }
.@{fa-css-prefix}-archive:before { content: @fa-var-archive; }
@ -432,7 +438,6 @@
.@{fa-css-prefix}-stumbleupon:before { content: @fa-var-stumbleupon; }
.@{fa-css-prefix}-delicious:before { content: @fa-var-delicious; }
.@{fa-css-prefix}-digg:before { content: @fa-var-digg; }
.@{fa-css-prefix}-pied-piper-square:before,
.@{fa-css-prefix}-pied-piper:before { content: @fa-var-pied-piper; }
.@{fa-css-prefix}-pied-piper-alt:before { content: @fa-var-pied-piper-alt; }
.@{fa-css-prefix}-drupal:before { content: @fa-var-drupal; }
@ -477,6 +482,7 @@
.@{fa-css-prefix}-codepen:before { content: @fa-var-codepen; }
.@{fa-css-prefix}-jsfiddle:before { content: @fa-var-jsfiddle; }
.@{fa-css-prefix}-life-bouy:before,
.@{fa-css-prefix}-life-buoy:before,
.@{fa-css-prefix}-life-saver:before,
.@{fa-css-prefix}-support:before,
.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; }
@ -487,6 +493,8 @@
.@{fa-css-prefix}-empire:before { content: @fa-var-empire; }
.@{fa-css-prefix}-git-square:before { content: @fa-var-git-square; }
.@{fa-css-prefix}-git:before { content: @fa-var-git; }
.@{fa-css-prefix}-y-combinator-square:before,
.@{fa-css-prefix}-yc-square:before,
.@{fa-css-prefix}-hacker-news:before { content: @fa-var-hacker-news; }
.@{fa-css-prefix}-tencent-weibo:before { content: @fa-var-tencent-weibo; }
.@{fa-css-prefix}-qq:before { content: @fa-var-qq; }
@ -504,3 +512,166 @@
.@{fa-css-prefix}-share-alt:before { content: @fa-var-share-alt; }
.@{fa-css-prefix}-share-alt-square:before { content: @fa-var-share-alt-square; }
.@{fa-css-prefix}-bomb:before { content: @fa-var-bomb; }
.@{fa-css-prefix}-soccer-ball-o:before,
.@{fa-css-prefix}-futbol-o:before { content: @fa-var-futbol-o; }
.@{fa-css-prefix}-tty:before { content: @fa-var-tty; }
.@{fa-css-prefix}-binoculars:before { content: @fa-var-binoculars; }
.@{fa-css-prefix}-plug:before { content: @fa-var-plug; }
.@{fa-css-prefix}-slideshare:before { content: @fa-var-slideshare; }
.@{fa-css-prefix}-twitch:before { content: @fa-var-twitch; }
.@{fa-css-prefix}-yelp:before { content: @fa-var-yelp; }
.@{fa-css-prefix}-newspaper-o:before { content: @fa-var-newspaper-o; }
.@{fa-css-prefix}-wifi:before { content: @fa-var-wifi; }
.@{fa-css-prefix}-calculator:before { content: @fa-var-calculator; }
.@{fa-css-prefix}-paypal:before { content: @fa-var-paypal; }
.@{fa-css-prefix}-google-wallet:before { content: @fa-var-google-wallet; }
.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; }
.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; }
.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; }
.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; }
.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; }
.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; }
.@{fa-css-prefix}-bell-slash:before { content: @fa-var-bell-slash; }
.@{fa-css-prefix}-bell-slash-o:before { content: @fa-var-bell-slash-o; }
.@{fa-css-prefix}-trash:before { content: @fa-var-trash; }
.@{fa-css-prefix}-copyright:before { content: @fa-var-copyright; }
.@{fa-css-prefix}-at:before { content: @fa-var-at; }
.@{fa-css-prefix}-eyedropper:before { content: @fa-var-eyedropper; }
.@{fa-css-prefix}-paint-brush:before { content: @fa-var-paint-brush; }
.@{fa-css-prefix}-birthday-cake:before { content: @fa-var-birthday-cake; }
.@{fa-css-prefix}-area-chart:before { content: @fa-var-area-chart; }
.@{fa-css-prefix}-pie-chart:before { content: @fa-var-pie-chart; }
.@{fa-css-prefix}-line-chart:before { content: @fa-var-line-chart; }
.@{fa-css-prefix}-lastfm:before { content: @fa-var-lastfm; }
.@{fa-css-prefix}-lastfm-square:before { content: @fa-var-lastfm-square; }
.@{fa-css-prefix}-toggle-off:before { content: @fa-var-toggle-off; }
.@{fa-css-prefix}-toggle-on:before { content: @fa-var-toggle-on; }
.@{fa-css-prefix}-bicycle:before { content: @fa-var-bicycle; }
.@{fa-css-prefix}-bus:before { content: @fa-var-bus; }
.@{fa-css-prefix}-ioxhost:before { content: @fa-var-ioxhost; }
.@{fa-css-prefix}-angellist:before { content: @fa-var-angellist; }
.@{fa-css-prefix}-cc:before { content: @fa-var-cc; }
.@{fa-css-prefix}-shekel:before,
.@{fa-css-prefix}-sheqel:before,
.@{fa-css-prefix}-ils:before { content: @fa-var-ils; }
.@{fa-css-prefix}-meanpath:before { content: @fa-var-meanpath; }
.@{fa-css-prefix}-buysellads:before { content: @fa-var-buysellads; }
.@{fa-css-prefix}-connectdevelop:before { content: @fa-var-connectdevelop; }
.@{fa-css-prefix}-dashcube:before { content: @fa-var-dashcube; }
.@{fa-css-prefix}-forumbee:before { content: @fa-var-forumbee; }
.@{fa-css-prefix}-leanpub:before { content: @fa-var-leanpub; }
.@{fa-css-prefix}-sellsy:before { content: @fa-var-sellsy; }
.@{fa-css-prefix}-shirtsinbulk:before { content: @fa-var-shirtsinbulk; }
.@{fa-css-prefix}-simplybuilt:before { content: @fa-var-simplybuilt; }
.@{fa-css-prefix}-skyatlas:before { content: @fa-var-skyatlas; }
.@{fa-css-prefix}-cart-plus:before { content: @fa-var-cart-plus; }
.@{fa-css-prefix}-cart-arrow-down:before { content: @fa-var-cart-arrow-down; }
.@{fa-css-prefix}-diamond:before { content: @fa-var-diamond; }
.@{fa-css-prefix}-ship:before { content: @fa-var-ship; }
.@{fa-css-prefix}-user-secret:before { content: @fa-var-user-secret; }
.@{fa-css-prefix}-motorcycle:before { content: @fa-var-motorcycle; }
.@{fa-css-prefix}-street-view:before { content: @fa-var-street-view; }
.@{fa-css-prefix}-heartbeat:before { content: @fa-var-heartbeat; }
.@{fa-css-prefix}-venus:before { content: @fa-var-venus; }
.@{fa-css-prefix}-mars:before { content: @fa-var-mars; }
.@{fa-css-prefix}-mercury:before { content: @fa-var-mercury; }
.@{fa-css-prefix}-intersex:before,
.@{fa-css-prefix}-transgender:before { content: @fa-var-transgender; }
.@{fa-css-prefix}-transgender-alt:before { content: @fa-var-transgender-alt; }
.@{fa-css-prefix}-venus-double:before { content: @fa-var-venus-double; }
.@{fa-css-prefix}-mars-double:before { content: @fa-var-mars-double; }
.@{fa-css-prefix}-venus-mars:before { content: @fa-var-venus-mars; }
.@{fa-css-prefix}-mars-stroke:before { content: @fa-var-mars-stroke; }
.@{fa-css-prefix}-mars-stroke-v:before { content: @fa-var-mars-stroke-v; }
.@{fa-css-prefix}-mars-stroke-h:before { content: @fa-var-mars-stroke-h; }
.@{fa-css-prefix}-neuter:before { content: @fa-var-neuter; }
.@{fa-css-prefix}-genderless:before { content: @fa-var-genderless; }
.@{fa-css-prefix}-facebook-official:before { content: @fa-var-facebook-official; }
.@{fa-css-prefix}-pinterest-p:before { content: @fa-var-pinterest-p; }
.@{fa-css-prefix}-whatsapp:before { content: @fa-var-whatsapp; }
.@{fa-css-prefix}-server:before { content: @fa-var-server; }
.@{fa-css-prefix}-user-plus:before { content: @fa-var-user-plus; }
.@{fa-css-prefix}-user-times:before { content: @fa-var-user-times; }
.@{fa-css-prefix}-hotel:before,
.@{fa-css-prefix}-bed:before { content: @fa-var-bed; }
.@{fa-css-prefix}-viacoin:before { content: @fa-var-viacoin; }
.@{fa-css-prefix}-train:before { content: @fa-var-train; }
.@{fa-css-prefix}-subway:before { content: @fa-var-subway; }
.@{fa-css-prefix}-medium:before { content: @fa-var-medium; }
.@{fa-css-prefix}-yc:before,
.@{fa-css-prefix}-y-combinator:before { content: @fa-var-y-combinator; }
.@{fa-css-prefix}-optin-monster:before { content: @fa-var-optin-monster; }
.@{fa-css-prefix}-opencart:before { content: @fa-var-opencart; }
.@{fa-css-prefix}-expeditedssl:before { content: @fa-var-expeditedssl; }
.@{fa-css-prefix}-battery-4:before,
.@{fa-css-prefix}-battery-full:before { content: @fa-var-battery-full; }
.@{fa-css-prefix}-battery-3:before,
.@{fa-css-prefix}-battery-three-quarters:before { content: @fa-var-battery-three-quarters; }
.@{fa-css-prefix}-battery-2:before,
.@{fa-css-prefix}-battery-half:before { content: @fa-var-battery-half; }
.@{fa-css-prefix}-battery-1:before,
.@{fa-css-prefix}-battery-quarter:before { content: @fa-var-battery-quarter; }
.@{fa-css-prefix}-battery-0:before,
.@{fa-css-prefix}-battery-empty:before { content: @fa-var-battery-empty; }
.@{fa-css-prefix}-mouse-pointer:before { content: @fa-var-mouse-pointer; }
.@{fa-css-prefix}-i-cursor:before { content: @fa-var-i-cursor; }
.@{fa-css-prefix}-object-group:before { content: @fa-var-object-group; }
.@{fa-css-prefix}-object-ungroup:before { content: @fa-var-object-ungroup; }
.@{fa-css-prefix}-sticky-note:before { content: @fa-var-sticky-note; }
.@{fa-css-prefix}-sticky-note-o:before { content: @fa-var-sticky-note-o; }
.@{fa-css-prefix}-cc-jcb:before { content: @fa-var-cc-jcb; }
.@{fa-css-prefix}-cc-diners-club:before { content: @fa-var-cc-diners-club; }
.@{fa-css-prefix}-clone:before { content: @fa-var-clone; }
.@{fa-css-prefix}-balance-scale:before { content: @fa-var-balance-scale; }
.@{fa-css-prefix}-hourglass-o:before { content: @fa-var-hourglass-o; }
.@{fa-css-prefix}-hourglass-1:before,
.@{fa-css-prefix}-hourglass-start:before { content: @fa-var-hourglass-start; }
.@{fa-css-prefix}-hourglass-2:before,
.@{fa-css-prefix}-hourglass-half:before { content: @fa-var-hourglass-half; }
.@{fa-css-prefix}-hourglass-3:before,
.@{fa-css-prefix}-hourglass-end:before { content: @fa-var-hourglass-end; }
.@{fa-css-prefix}-hourglass:before { content: @fa-var-hourglass; }
.@{fa-css-prefix}-hand-grab-o:before,
.@{fa-css-prefix}-hand-rock-o:before { content: @fa-var-hand-rock-o; }
.@{fa-css-prefix}-hand-stop-o:before,
.@{fa-css-prefix}-hand-paper-o:before { content: @fa-var-hand-paper-o; }
.@{fa-css-prefix}-hand-scissors-o:before { content: @fa-var-hand-scissors-o; }
.@{fa-css-prefix}-hand-lizard-o:before { content: @fa-var-hand-lizard-o; }
.@{fa-css-prefix}-hand-spock-o:before { content: @fa-var-hand-spock-o; }
.@{fa-css-prefix}-hand-pointer-o:before { content: @fa-var-hand-pointer-o; }
.@{fa-css-prefix}-hand-peace-o:before { content: @fa-var-hand-peace-o; }
.@{fa-css-prefix}-trademark:before { content: @fa-var-trademark; }
.@{fa-css-prefix}-registered:before { content: @fa-var-registered; }
.@{fa-css-prefix}-creative-commons:before { content: @fa-var-creative-commons; }
.@{fa-css-prefix}-gg:before { content: @fa-var-gg; }
.@{fa-css-prefix}-gg-circle:before { content: @fa-var-gg-circle; }
.@{fa-css-prefix}-tripadvisor:before { content: @fa-var-tripadvisor; }
.@{fa-css-prefix}-odnoklassniki:before { content: @fa-var-odnoklassniki; }
.@{fa-css-prefix}-odnoklassniki-square:before { content: @fa-var-odnoklassniki-square; }
.@{fa-css-prefix}-get-pocket:before { content: @fa-var-get-pocket; }
.@{fa-css-prefix}-wikipedia-w:before { content: @fa-var-wikipedia-w; }
.@{fa-css-prefix}-safari:before { content: @fa-var-safari; }
.@{fa-css-prefix}-chrome:before { content: @fa-var-chrome; }
.@{fa-css-prefix}-firefox:before { content: @fa-var-firefox; }
.@{fa-css-prefix}-opera:before { content: @fa-var-opera; }
.@{fa-css-prefix}-internet-explorer:before { content: @fa-var-internet-explorer; }
.@{fa-css-prefix}-tv:before,
.@{fa-css-prefix}-television:before { content: @fa-var-television; }
.@{fa-css-prefix}-contao:before { content: @fa-var-contao; }
.@{fa-css-prefix}-500px:before { content: @fa-var-500px; }
.@{fa-css-prefix}-amazon:before { content: @fa-var-amazon; }
.@{fa-css-prefix}-calendar-plus-o:before { content: @fa-var-calendar-plus-o; }
.@{fa-css-prefix}-calendar-minus-o:before { content: @fa-var-calendar-minus-o; }
.@{fa-css-prefix}-calendar-times-o:before { content: @fa-var-calendar-times-o; }
.@{fa-css-prefix}-calendar-check-o:before { content: @fa-var-calendar-check-o; }
.@{fa-css-prefix}-industry:before { content: @fa-var-industry; }
.@{fa-css-prefix}-map-pin:before { content: @fa-var-map-pin; }
.@{fa-css-prefix}-map-signs:before { content: @fa-var-map-signs; }
.@{fa-css-prefix}-map-o:before { content: @fa-var-map-o; }
.@{fa-css-prefix}-map:before { content: @fa-var-map; }
.@{fa-css-prefix}-commenting:before { content: @fa-var-commenting; }
.@{fa-css-prefix}-commenting-o:before { content: @fa-var-commenting-o; }
.@{fa-css-prefix}-houzz:before { content: @fa-var-houzz; }
.@{fa-css-prefix}-vimeo:before { content: @fa-var-vimeo; }
.@{fa-css-prefix}-black-tie:before { content: @fa-var-black-tie; }
.@{fa-css-prefix}-fonticons:before { content: @fa-var-fonticons; }

2
stylesheets/font-awesome/less/list.less

@ -14,6 +14,6 @@
top: (2em / 14);
text-align: center;
&.@{fa-css-prefix}-lg {
left: -@fa-li-width + (4em / 14);
left: (-@fa-li-width + (4em / 14));
}
}

14
stylesheets/font-awesome/less/mixins.less

@ -1,20 +1,26 @@
// Mixins
// --------------------------
.fa-icon() {
display: inline-block;
font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
font-size: inherit; // can't have font-size inherit on line above, so need to override
text-rendering: auto; // optimizelegibility throws things off #1094
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.fa-icon-rotate(@degrees, @rotation) {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation);
-webkit-transform: rotate(@degrees);
-moz-transform: rotate(@degrees);
-ms-transform: rotate(@degrees);
-o-transform: rotate(@degrees);
transform: rotate(@degrees);
}
.fa-icon-flip(@horiz, @vert, @rotation) {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=@rotation, mirror=1);
-webkit-transform: scale(@horiz, @vert);
-moz-transform: scale(@horiz, @vert);
-ms-transform: scale(@horiz, @vert);
-o-transform: scale(@horiz, @vert);
transform: scale(@horiz, @vert);
}

11
stylesheets/font-awesome/less/path.less

@ -3,11 +3,12 @@
@font-face {
font-family: 'FontAwesome';
src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}')";
src: ~"url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype')",
~"url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff')",
~"url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype')",
~"url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg')";
src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
// src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
font-weight: normal;
font-style: normal;

11
stylesheets/font-awesome/less/rotated-flipped.less

@ -7,3 +7,14 @@
.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
// Hook for IE8-9
// -------------------------
:root .@{fa-css-prefix}-rotate-90,
:root .@{fa-css-prefix}-rotate-180,
:root .@{fa-css-prefix}-rotate-270,
:root .@{fa-css-prefix}-flip-horizontal,
:root .@{fa-css-prefix}-flip-vertical {
filter: none;
}

179
stylesheets/font-awesome/less/variables.less

@ -2,22 +2,27 @@
// --------------------------
@fa-font-path: "../fonts";
//@fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.1.0/fonts"; // for referencing Bootstrap CDN font files directly
@fa-font-size-base: 14px;
@fa-line-height-base: 1;
//@fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.4.0/fonts"; // for referencing Bootstrap CDN font files directly
@fa-css-prefix: fa;
@fa-version: "4.1.0";
@fa-version: "4.4.0";
@fa-border-color: #eee;
@fa-inverse: #fff;
@fa-li-width: (30em / 14);
@fa-var-500px: "\f26e";
@fa-var-adjust: "\f042";
@fa-var-adn: "\f170";
@fa-var-align-center: "\f037";
@fa-var-align-justify: "\f039";
@fa-var-align-left: "\f036";
@fa-var-align-right: "\f038";
@fa-var-amazon: "\f270";
@fa-var-ambulance: "\f0f9";
@fa-var-anchor: "\f13d";
@fa-var-android: "\f17b";
@fa-var-angellist: "\f209";
@fa-var-angle-double-down: "\f103";
@fa-var-angle-double-left: "\f100";
@fa-var-angle-double-right: "\f101";
@ -28,6 +33,7 @@
@fa-var-angle-up: "\f106";
@fa-var-apple: "\f179";
@fa-var-archive: "\f187";
@fa-var-area-chart: "\f1fe";
@fa-var-arrow-circle-down: "\f0ab";
@fa-var-arrow-circle-left: "\f0a8";
@fa-var-arrow-circle-o-down: "\f01a";
@ -45,21 +51,41 @@
@fa-var-arrows-h: "\f07e";
@fa-var-arrows-v: "\f07d";
@fa-var-asterisk: "\f069";
@fa-var-at: "\f1fa";
@fa-var-automobile: "\f1b9";
@fa-var-backward: "\f04a";
@fa-var-balance-scale: "\f24e";
@fa-var-ban: "\f05e";
@fa-var-bank: "\f19c";
@fa-var-bar-chart: "\f080";
@fa-var-bar-chart-o: "\f080";
@fa-var-barcode: "\f02a";
@fa-var-bars: "\f0c9";
@fa-var-battery-0: "\f244";
@fa-var-battery-1: "\f243";
@fa-var-battery-2: "\f242";
@fa-var-battery-3: "\f241";
@fa-var-battery-4: "\f240";
@fa-var-battery-empty: "\f244";
@fa-var-battery-full: "\f240";
@fa-var-battery-half: "\f242";
@fa-var-battery-quarter: "\f243";
@fa-var-battery-three-quarters: "\f241";
@fa-var-bed: "\f236";
@fa-var-beer: "\f0fc";
@fa-var-behance: "\f1b4";
@fa-var-behance-square: "\f1b5";
@fa-var-bell: "\f0f3";
@fa-var-bell-o: "\f0a2";
@fa-var-bell-slash: "\f1f6";
@fa-var-bell-slash-o: "\f1f7";
@fa-var-bicycle: "\f206";
@fa-var-binoculars: "\f1e5";
@fa-var-birthday-cake: "\f1fd";
@fa-var-bitbucket: "\f171";
@fa-var-bitbucket-square: "\f172";
@fa-var-bitcoin: "\f15a";
@fa-var-black-tie: "\f27e";
@fa-var-bold: "\f032";
@fa-var-bolt: "\f0e7";
@fa-var-bomb: "\f1e2";
@ -73,9 +99,16 @@
@fa-var-building-o: "\f0f7";
@fa-var-bullhorn: "\f0a1";
@fa-var-bullseye: "\f140";
@fa-var-bus: "\f207";
@fa-var-buysellads: "\f20d";
@fa-var-cab: "\f1ba";
@fa-var-calculator: "\f1ec";
@fa-var-calendar: "\f073";
@fa-var-calendar-check-o: "\f274";
@fa-var-calendar-minus-o: "\f272";
@fa-var-calendar-o: "\f133";
@fa-var-calendar-plus-o: "\f271";
@fa-var-calendar-times-o: "\f273";
@fa-var-camera: "\f030";
@fa-var-camera-retro: "\f083";
@fa-var-car: "\f1b9";
@ -87,6 +120,17 @@
@fa-var-caret-square-o-right: "\f152";
@fa-var-caret-square-o-up: "\f151";
@fa-var-caret-up: "\f0d8";
@fa-var-cart-arrow-down: "\f218";
@fa-var-cart-plus: "\f217";
@fa-var-cc: "\f20a";
@fa-var-cc-amex: "\f1f3";
@fa-var-cc-diners-club: "\f24c";
@fa-var-cc-discover: "\f1f2";
@fa-var-cc-jcb: "\f24b";
@fa-var-cc-mastercard: "\f1f1";
@fa-var-cc-paypal: "\f1f4";
@fa-var-cc-stripe: "\f1f5";
@fa-var-cc-visa: "\f1f0";
@fa-var-certificate: "\f0a3";
@fa-var-chain: "\f0c1";
@fa-var-chain-broken: "\f127";
@ -104,12 +148,15 @@
@fa-var-chevron-right: "\f054";
@fa-var-chevron-up: "\f077";
@fa-var-child: "\f1ae";
@fa-var-chrome: "\f268";
@fa-var-circle: "\f111";
@fa-var-circle-o: "\f10c";
@fa-var-circle-o-notch: "\f1ce";
@fa-var-circle-thin: "\f1db";
@fa-var-clipboard: "\f0ea";
@fa-var-clock-o: "\f017";
@fa-var-clone: "\f24d";
@fa-var-close: "\f00d";
@fa-var-cloud: "\f0c2";
@fa-var-cloud-download: "\f0ed";
@fa-var-cloud-upload: "\f0ee";
@ -123,11 +170,17 @@
@fa-var-columns: "\f0db";
@fa-var-comment: "\f075";
@fa-var-comment-o: "\f0e5";
@fa-var-commenting: "\f27a";
@fa-var-commenting-o: "\f27b";
@fa-var-comments: "\f086";
@fa-var-comments-o: "\f0e6";
@fa-var-compass: "\f14e";
@fa-var-compress: "\f066";
@fa-var-connectdevelop: "\f20e";
@fa-var-contao: "\f26d";
@fa-var-copy: "\f0c5";
@fa-var-copyright: "\f1f9";
@fa-var-creative-commons: "\f25e";
@fa-var-credit-card: "\f09d";
@fa-var-crop: "\f125";
@fa-var-crosshairs: "\f05b";
@ -137,11 +190,13 @@
@fa-var-cut: "\f0c4";
@fa-var-cutlery: "\f0f5";
@fa-var-dashboard: "\f0e4";
@fa-var-dashcube: "\f210";
@fa-var-database: "\f1c0";
@fa-var-dedent: "\f03b";
@fa-var-delicious: "\f1a5";
@fa-var-desktop: "\f108";
@fa-var-deviantart: "\f1bd";
@fa-var-diamond: "\f219";
@fa-var-digg: "\f1a6";
@fa-var-dollar: "\f155";
@fa-var-dot-circle-o: "\f192";
@ -165,15 +220,20 @@
@fa-var-exclamation-circle: "\f06a";
@fa-var-exclamation-triangle: "\f071";
@fa-var-expand: "\f065";
@fa-var-expeditedssl: "\f23e";
@fa-var-external-link: "\f08e";
@fa-var-external-link-square: "\f14c";
@fa-var-eye: "\f06e";
@fa-var-eye-slash: "\f070";
@fa-var-eyedropper: "\f1fb";
@fa-var-facebook: "\f09a";
@fa-var-facebook-f: "\f09a";
@fa-var-facebook-official: "\f230";
@fa-var-facebook-square: "\f082";
@fa-var-fast-backward: "\f049";
@fa-var-fast-forward: "\f050";
@fa-var-fax: "\f1ac";
@fa-var-feed: "\f09e";
@fa-var-female: "\f182";
@fa-var-fighter-jet: "\f0fb";
@fa-var-file: "\f15b";
@ -199,6 +259,7 @@
@fa-var-filter: "\f0b0";
@fa-var-fire: "\f06d";
@fa-var-fire-extinguisher: "\f134";
@fa-var-firefox: "\f269";
@fa-var-flag: "\f024";
@fa-var-flag-checkered: "\f11e";
@fa-var-flag-o: "\f11d";
@ -211,15 +272,22 @@
@fa-var-folder-open: "\f07c";
@fa-var-folder-open-o: "\f115";
@fa-var-font: "\f031";
@fa-var-fonticons: "\f280";
@fa-var-forumbee: "\f211";
@fa-var-forward: "\f04e";
@fa-var-foursquare: "\f180";
@fa-var-frown-o: "\f119";
@fa-var-futbol-o: "\f1e3";
@fa-var-gamepad: "\f11b";
@fa-var-gavel: "\f0e3";
@fa-var-gbp: "\f154";
@fa-var-ge: "\f1d1";
@fa-var-gear: "\f013";
@fa-var-gears: "\f085";
@fa-var-genderless: "\f22d";
@fa-var-get-pocket: "\f265";
@fa-var-gg: "\f260";
@fa-var-gg-circle: "\f261";
@fa-var-gift: "\f06b";
@fa-var-git: "\f1d3";
@fa-var-git-square: "\f1d2";
@ -232,31 +300,59 @@
@fa-var-google: "\f1a0";
@fa-var-google-plus: "\f0d5";
@fa-var-google-plus-square: "\f0d4";
@fa-var-google-wallet: "\f1ee";
@fa-var-graduation-cap: "\f19d";
@fa-var-gratipay: "\f184";
@fa-var-group: "\f0c0";
@fa-var-h-square: "\f0fd";
@fa-var-hacker-news: "\f1d4";
@fa-var-hand-grab-o: "\f255";
@fa-var-hand-lizard-o: "\f258";
@fa-var-hand-o-down: "\f0a7";
@fa-var-hand-o-left: "\f0a5";
@fa-var-hand-o-right: "\f0a4";
@fa-var-hand-o-up: "\f0a6";
@fa-var-hand-paper-o: "\f256";
@fa-var-hand-peace-o: "\f25b";
@fa-var-hand-pointer-o: "\f25a";
@fa-var-hand-rock-o: "\f255";
@fa-var-hand-scissors-o: "\f257";
@fa-var-hand-spock-o: "\f259";
@fa-var-hand-stop-o: "\f256";
@fa-var-hdd-o: "\f0a0";
@fa-var-header: "\f1dc";
@fa-var-headphones: "\f025";
@fa-var-heart: "\f004";
@fa-var-heart-o: "\f08a";
@fa-var-heartbeat: "\f21e";
@fa-var-history: "\f1da";
@fa-var-home: "\f015";
@fa-var-hospital-o: "\f0f8";
@fa-var-hotel: "\f236";
@fa-var-hourglass: "\f254";
@fa-var-hourglass-1: "\f251";
@fa-var-hourglass-2: "\f252";
@fa-var-hourglass-3: "\f253";
@fa-var-hourglass-end: "\f253";
@fa-var-hourglass-half: "\f252";
@fa-var-hourglass-o: "\f250";
@fa-var-hourglass-start: "\f251";
@fa-var-houzz: "\f27c";
@fa-var-html5: "\f13b";
@fa-var-i-cursor: "\f246";
@fa-var-ils: "\f20b";
@fa-var-image: "\f03e";
@fa-var-inbox: "\f01c";
@fa-var-indent: "\f03c";
@fa-var-industry: "\f275";
@fa-var-info: "\f129";
@fa-var-info-circle: "\f05a";
@fa-var-inr: "\f156";
@fa-var-instagram: "\f16d";
@fa-var-institution: "\f19c";
@fa-var-internet-explorer: "\f26b";
@fa-var-intersex: "\f224";
@fa-var-ioxhost: "\f208";
@fa-var-italic: "\f033";
@fa-var-joomla: "\f1aa";
@fa-var-jpy: "\f157";
@ -266,15 +362,20 @@
@fa-var-krw: "\f159";
@fa-var-language: "\f1ab";
@fa-var-laptop: "\f109";
@fa-var-lastfm: "\f202";
@fa-var-lastfm-square: "\f203";
@fa-var-leaf: "\f06c";
@fa-var-leanpub: "\f212";
@fa-var-legal: "\f0e3";
@fa-var-lemon-o: "\f094";
@fa-var-level-down: "\f149";
@fa-var-level-up: "\f148";
@fa-var-life-bouy: "\f1cd";
@fa-var-life-buoy: "\f1cd";
@fa-var-life-ring: "\f1cd";
@fa-var-life-saver: "\f1cd";
@fa-var-lightbulb-o: "\f0eb";
@fa-var-line-chart: "\f201";
@fa-var-link: "\f0c1";
@fa-var-linkedin: "\f0e1";
@fa-var-linkedin-square: "\f08c";
@ -295,10 +396,22 @@
@fa-var-mail-reply: "\f112";
@fa-var-mail-reply-all: "\f122";
@fa-var-male: "\f183";
@fa-var-map: "\f279";
@fa-var-map-marker: "\f041";
@fa-var-map-o: "\f278";
@fa-var-map-pin: "\f276";
@fa-var-map-signs: "\f277";
@fa-var-mars: "\f222";
@fa-var-mars-double: "\f227";
@fa-var-mars-stroke: "\f229";
@fa-var-mars-stroke-h: "\f22b";
@fa-var-mars-stroke-v: "\f22a";
@fa-var-maxcdn: "\f136";
@fa-var-meanpath: "\f20c";
@fa-var-medium: "\f23a";
@fa-var-medkit: "\f0fa";
@fa-var-meh-o: "\f11a";
@fa-var-mercury: "\f223";
@fa-var-microphone: "\f130";
@fa-var-microphone-slash: "\f131";
@fa-var-minus: "\f068";
@ -310,11 +423,23 @@
@fa-var-money: "\f0d6";
@fa-var-moon-o: "\f186";
@fa-var-mortar-board: "\f19d";
@fa-var-motorcycle: "\f21c";
@fa-var-mouse-pointer: "\f245";
@fa-var-music: "\f001";
@fa-var-navicon: "\f0c9";
@fa-var-neuter: "\f22c";
@fa-var-newspaper-o: "\f1ea";
@fa-var-object-group: "\f247";
@fa-var-object-ungroup: "\f248";
@fa-var-odnoklassniki: "\f263";
@fa-var-odnoklassniki-square: "\f264";
@fa-var-opencart: "\f23d";
@fa-var-openid: "\f19b";
@fa-var-opera: "\f26a";
@fa-var-optin-monster: "\f23c";
@fa-var-outdent: "\f03b";
@fa-var-pagelines: "\f18c";
@fa-var-paint-brush: "\f1fc";
@fa-var-paper-plane: "\f1d8";
@fa-var-paper-plane-o: "\f1d9";
@fa-var-paperclip: "\f0c6";
@ -322,6 +447,7 @@
@fa-var-paste: "\f0ea";
@fa-var-pause: "\f04c";
@fa-var-paw: "\f1b0";
@fa-var-paypal: "\f1ed";
@fa-var-pencil: "\f040";
@fa-var-pencil-square: "\f14b";
@fa-var-pencil-square-o: "\f044";
@ -329,15 +455,17 @@
@fa-var-phone-square: "\f098";
@fa-var-photo: "\f03e";
@fa-var-picture-o: "\f03e";
@fa-var-pie-chart: "\f200";
@fa-var-pied-piper: "\f1a7";
@fa-var-pied-piper-alt: "\f1a8";
@fa-var-pied-piper-square: "\f1a7";
@fa-var-pinterest: "\f0d2";
@fa-var-pinterest-p: "\f231";
@fa-var-pinterest-square: "\f0d3";
@fa-var-plane: "\f072";
@fa-var-play: "\f04b";
@fa-var-play-circle: "\f144";
@fa-var-play-circle-o: "\f01d";
@fa-var-plug: "\f1e6";
@fa-var-plus: "\f067";
@fa-var-plus-circle: "\f055";
@fa-var-plus-square: "\f0fe";
@ -358,6 +486,8 @@
@fa-var-reddit: "\f1a1";
@fa-var-reddit-square: "\f1a2";
@fa-var-refresh: "\f021";
@fa-var-registered: "\f25d";
@fa-var-remove: "\f00d";
@fa-var-renren: "\f18b";
@fa-var-reorder: "\f0c9";
@fa-var-repeat: "\f01e";
@ -375,28 +505,39 @@
@fa-var-rub: "\f158";
@fa-var-ruble: "\f158";
@fa-var-rupee: "\f156";
@fa-var-safari: "\f267";
@fa-var-save: "\f0c7";
@fa-var-scissors: "\f0c4";
@fa-var-search: "\f002";
@fa-var-search-minus: "\f010";
@fa-var-search-plus: "\f00e";
@fa-var-sellsy: "\f213";
@fa-var-send: "\f1d8";
@fa-var-send-o: "\f1d9";
@fa-var-server: "\f233";
@fa-var-share: "\f064";
@fa-var-share-alt: "\f1e0";
@fa-var-share-alt-square: "\f1e1";
@fa-var-share-square: "\f14d";
@fa-var-share-square-o: "\f045";
@fa-var-shekel: "\f20b";
@fa-var-sheqel: "\f20b";
@fa-var-shield: "\f132";
@fa-var-ship: "\f21a";
@fa-var-shirtsinbulk: "\f214";
@fa-var-shopping-cart: "\f07a";
@fa-var-sign-in: "\f090";
@fa-var-sign-out: "\f08b";
@fa-var-signal: "\f012";
@fa-var-simplybuilt: "\f215";
@fa-var-sitemap: "\f0e8";
@fa-var-skyatlas: "\f216";
@fa-var-skype: "\f17e";
@fa-var-slack: "\f198";
@fa-var-sliders: "\f1de";
@fa-var-slideshare: "\f1e7";
@fa-var-smile-o: "\f118";
@fa-var-soccer-ball-o: "\f1e3";
@fa-var-sort: "\f0dc";
@fa-var-sort-alpha-asc: "\f15d";
@fa-var-sort-alpha-desc: "\f15e";
@ -428,11 +569,15 @@
@fa-var-step-backward: "\f048";
@fa-var-step-forward: "\f051";
@fa-var-stethoscope: "\f0f1";
@fa-var-sticky-note: "\f249";
@fa-var-sticky-note-o: "\f24a";
@fa-var-stop: "\f04d";
@fa-var-street-view: "\f21d";
@fa-var-strikethrough: "\f0cc";
@fa-var-stumbleupon: "\f1a4";
@fa-var-stumbleupon-circle: "\f1a3";
@fa-var-subscript: "\f12c";
@fa-var-subway: "\f239";
@fa-var-suitcase: "\f0f2";
@fa-var-sun-o: "\f185";
@fa-var-superscript: "\f12b";
@ -444,6 +589,7 @@
@fa-var-tags: "\f02c";
@fa-var-tasks: "\f0ae";
@fa-var-taxi: "\f1ba";
@fa-var-television: "\f26c";
@fa-var-tencent-weibo: "\f1d5";
@fa-var-terminal: "\f120";
@fa-var-text-height: "\f034";
@ -463,17 +609,28 @@
@fa-var-tint: "\f043";
@fa-var-toggle-down: "\f150";
@fa-var-toggle-left: "\f191";
@fa-var-toggle-off: "\f204";
@fa-var-toggle-on: "\f205";
@fa-var-toggle-right: "\f152";
@fa-var-toggle-up: "\f151";
@fa-var-trademark: "\f25c";
@fa-var-train: "\f238";
@fa-var-transgender: "\f224";
@fa-var-transgender-alt: "\f225";
@fa-var-trash: "\f1f8";
@fa-var-trash-o: "\f014";
@fa-var-tree: "\f1bb";
@fa-var-trello: "\f181";
@fa-var-tripadvisor: "\f262";
@fa-var-trophy: "\f091";
@fa-var-truck: "\f0d1";
@fa-var-try: "\f195";
@fa-var-tty: "\f1e4";
@fa-var-tumblr: "\f173";
@fa-var-tumblr-square: "\f174";
@fa-var-turkish-lira: "\f195";
@fa-var-tv: "\f26c";
@fa-var-twitch: "\f1e8";
@fa-var-twitter: "\f099";
@fa-var-twitter-square: "\f081";
@fa-var-umbrella: "\f0e9";
@ -488,8 +645,16 @@
@fa-var-usd: "\f155";
@fa-var-user: "\f007";
@fa-var-user-md: "\f0f0";
@fa-var-user-plus: "\f234";
@fa-var-user-secret: "\f21b";
@fa-var-user-times: "\f235";
@fa-var-users: "\f0c0";
@fa-var-venus: "\f221";
@fa-var-venus-double: "\f226";
@fa-var-venus-mars: "\f228";
@fa-var-viacoin: "\f237";
@fa-var-video-camera: "\f03d";
@fa-var-vimeo: "\f27d";
@fa-var-vimeo-square: "\f194";
@fa-var-vine: "\f1ca";
@fa-var-vk: "\f189";
@ -500,14 +665,22 @@
@fa-var-wechat: "\f1d7";
@fa-var-weibo: "\f18a";
@fa-var-weixin: "\f1d7";
@fa-var-whatsapp: "\f232";
@fa-var-wheelchair: "\f193";
@fa-var-wifi: "\f1eb";
@fa-var-wikipedia-w: "\f266";
@fa-var-windows: "\f17a";
@fa-var-won: "\f159";
@fa-var-wordpress: "\f19a";
@fa-var-wrench: "\f0ad";
@fa-var-xing: "\f168";
@fa-var-xing-square: "\f169";
@fa-var-y-combinator: "\f23b";
@fa-var-y-combinator-square: "\f1d4";
@fa-var-yahoo: "\f19e";
@fa-var-yc: "\f23b";
@fa-var-yc-square: "\f1d4";
@fa-var-yelp: "\f1e9";
@fa-var-yen: "\f157";
@fa-var-youtube: "\f167";
@fa-var-youtube-play: "\f16a";

34
stylesheets/font-awesome/scss/_animated.scss

@ -0,0 +1,34 @@
// Spinning Icons
// --------------------------
.#{$fa-css-prefix}-spin {
-webkit-animation: fa-spin 2s infinite linear;
animation: fa-spin 2s infinite linear;
}
.#{$fa-css-prefix}-pulse {
-webkit-animation: fa-spin 1s infinite steps(8);
animation: fa-spin 1s infinite steps(8);
}
@-webkit-keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes fa-spin {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}

9
stylesheets/font-awesome/scss/_bordered-pulled.scss

@ -7,6 +7,15 @@
border-radius: .1em;
}
.#{$fa-css-prefix}-pull-left { float: left; }
.#{$fa-css-prefix}-pull-right { float: right; }
.#{$fa-css-prefix} {
&.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
&.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
}
/* Deprecated as of 4.4.0 */
.pull-right { float: right; }
.pull-left { float: left; }

8
stylesheets/font-awesome/scss/_core.scss

@ -3,10 +3,10 @@
.#{$fa-css-prefix} {
display: inline-block;
font-family: FontAwesome;
font-style: normal;
font-weight: normal;
line-height: 1;
font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
font-size: inherit; // can't have font-size inherit on line above, so need to override
text-rendering: auto; // optimizelegibility throws things off #1094
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

177
stylesheets/font-awesome/scss/_icons.scss

@ -14,6 +14,8 @@
.#{$fa-css-prefix}-th:before { content: $fa-var-th; }
.#{$fa-css-prefix}-th-list:before { content: $fa-var-th-list; }
.#{$fa-css-prefix}-check:before { content: $fa-var-check; }
.#{$fa-css-prefix}-remove:before,
.#{$fa-css-prefix}-close:before,
.#{$fa-css-prefix}-times:before { content: $fa-var-times; }
.#{$fa-css-prefix}-search-plus:before { content: $fa-var-search-plus; }
.#{$fa-css-prefix}-search-minus:before { content: $fa-var-search-minus; }
@ -129,7 +131,8 @@
.#{$fa-css-prefix}-folder-open:before { content: $fa-var-folder-open; }
.#{$fa-css-prefix}-arrows-v:before { content: $fa-var-arrows-v; }
.#{$fa-css-prefix}-arrows-h:before { content: $fa-var-arrows-h; }
.#{$fa-css-prefix}-bar-chart-o:before { content: $fa-var-bar-chart-o; }
.#{$fa-css-prefix}-bar-chart-o:before,
.#{$fa-css-prefix}-bar-chart:before { content: $fa-var-bar-chart; }
.#{$fa-css-prefix}-twitter-square:before { content: $fa-var-twitter-square; }
.#{$fa-css-prefix}-facebook-square:before { content: $fa-var-facebook-square; }
.#{$fa-css-prefix}-camera-retro:before { content: $fa-var-camera-retro; }
@ -155,10 +158,12 @@
.#{$fa-css-prefix}-bookmark-o:before { content: $fa-var-bookmark-o; }
.#{$fa-css-prefix}-phone-square:before { content: $fa-var-phone-square; }
.#{$fa-css-prefix}-twitter:before { content: $fa-var-twitter; }
.#{$fa-css-prefix}-facebook-f:before,
.#{$fa-css-prefix}-facebook:before { content: $fa-var-facebook; }
.#{$fa-css-prefix}-github:before { content: $fa-var-github; }
.#{$fa-css-prefix}-unlock:before { content: $fa-var-unlock; }
.#{$fa-css-prefix}-credit-card:before { content: $fa-var-credit-card; }
.#{$fa-css-prefix}-feed:before,
.#{$fa-css-prefix}-rss:before { content: $fa-var-rss; }
.#{$fa-css-prefix}-hdd-o:before { content: $fa-var-hdd-o; }
.#{$fa-css-prefix}-bullhorn:before { content: $fa-var-bullhorn; }
@ -394,7 +399,8 @@
.#{$fa-css-prefix}-trello:before { content: $fa-var-trello; }
.#{$fa-css-prefix}-female:before { content: $fa-var-female; }
.#{$fa-css-prefix}-male:before { content: $fa-var-male; }
.#{$fa-css-prefix}-gittip:before { content: $fa-var-gittip; }
.#{$fa-css-prefix}-gittip:before,
.#{$fa-css-prefix}-gratipay:before { content: $fa-var-gratipay; }
.#{$fa-css-prefix}-sun-o:before { content: $fa-var-sun-o; }
.#{$fa-css-prefix}-moon-o:before { content: $fa-var-moon-o; }
.#{$fa-css-prefix}-archive:before { content: $fa-var-archive; }
@ -432,7 +438,6 @@
.#{$fa-css-prefix}-stumbleupon:before { content: $fa-var-stumbleupon; }
.#{$fa-css-prefix}-delicious:before { content: $fa-var-delicious; }
.#{$fa-css-prefix}-digg:before { content: $fa-var-digg; }
.#{$fa-css-prefix}-pied-piper-square:before,
.#{$fa-css-prefix}-pied-piper:before { content: $fa-var-pied-piper; }
.#{$fa-css-prefix}-pied-piper-alt:before { content: $fa-var-pied-piper-alt; }
.#{$fa-css-prefix}-drupal:before { content: $fa-var-drupal; }
@ -477,6 +482,7 @@
.#{$fa-css-prefix}-codepen:before { content: $fa-var-codepen; }
.#{$fa-css-prefix}-jsfiddle:before { content: $fa-var-jsfiddle; }
.#{$fa-css-prefix}-life-bouy:before,
.#{$fa-css-prefix}-life-buoy:before,
.#{$fa-css-prefix}-life-saver:before,
.#{$fa-css-prefix}-support:before,
.#{$fa-css-prefix}-life-ring:before { content: $fa-var-life-ring; }
@ -487,6 +493,8 @@
.#{$fa-css-prefix}-empire:before { content: $fa-var-empire; }
.#{$fa-css-prefix}-git-square:before { content: $fa-var-git-square; }
.#{$fa-css-prefix}-git:before { content: $fa-var-git; }
.#{$fa-css-prefix}-y-combinator-square:before,
.#{$fa-css-prefix}-yc-square:before,
.#{$fa-css-prefix}-hacker-news:before { content: $fa-var-hacker-news; }
.#{$fa-css-prefix}-tencent-weibo:before { content: $fa-var-tencent-weibo; }
.#{$fa-css-prefix}-qq:before { content: $fa-var-qq; }
@ -504,3 +512,166 @@
.#{$fa-css-prefix}-share-alt:before { content: $fa-var-share-alt; }
.#{$fa-css-prefix}-share-alt-square:before { content: $fa-var-share-alt-square; }
.#{$fa-css-prefix}-bomb:before { content: $fa-var-bomb; }
.#{$fa-css-prefix}-soccer-ball-o:before,
.#{$fa-css-prefix}-futbol-o:before { content: $fa-var-futbol-o; }
.#{$fa-css-prefix}-tty:before { content: $fa-var-tty; }
.#{$fa-css-prefix}-binoculars:before { content: $fa-var-binoculars; }
.#{$fa-css-prefix}-plug:before { content: $fa-var-plug; }
.#{$fa-css-prefix}-slideshare:before { content: $fa-var-slideshare; }
.#{$fa-css-prefix}-twitch:before { content: $fa-var-twitch; }
.#{$fa-css-prefix}-yelp:before { content: $fa-var-yelp; }
.#{$fa-css-prefix}-newspaper-o:before { content: $fa-var-newspaper-o; }
.#{$fa-css-prefix}-wifi:before { content: $fa-var-wifi; }
.#{$fa-css-prefix}-calculator:before { content: $fa-var-calculator; }
.#{$fa-css-prefix}-paypal:before { content: $fa-var-paypal; }
.#{$fa-css-prefix}-google-wallet:before { content: $fa-var-google-wallet; }
.#{$fa-css-prefix}-cc-visa:before { content: $fa-var-cc-visa; }
.#{$fa-css-prefix}-cc-mastercard:before { content: $fa-var-cc-mastercard; }
.#{$fa-css-prefix}-cc-discover:before { content: $fa-var-cc-discover; }
.#{$fa-css-prefix}-cc-amex:before { content: $fa-var-cc-amex; }
.#{$fa-css-prefix}-cc-paypal:before { content: $fa-var-cc-paypal; }
.#{$fa-css-prefix}-cc-stripe:before { content: $fa-var-cc-stripe; }
.#{$fa-css-prefix}-bell-slash:before { content: $fa-var-bell-slash; }
.#{$fa-css-prefix}-bell-slash-o:before { content: $fa-var-bell-slash-o; }
.#{$fa-css-prefix}-trash:before { content: $fa-var-trash; }
.#{$fa-css-prefix}-copyright:before { content: $fa-var-copyright; }
.#{$fa-css-prefix}-at:before { content: $fa-var-at; }
.#{$fa-css-prefix}-eyedropper:before { content: $fa-var-eyedropper; }
.#{$fa-css-prefix}-paint-brush:before { content: $fa-var-paint-brush; }
.#{$fa-css-prefix}-birthday-cake:before { content: $fa-var-birthday-cake; }
.#{$fa-css-prefix}-area-chart:before { content: $fa-var-area-chart; }
.#{$fa-css-prefix}-pie-chart:before { content: $fa-var-pie-chart; }
.#{$fa-css-prefix}-line-chart:before { content: $fa-var-line-chart; }
.#{$fa-css-prefix}-lastfm:before { content: $fa-var-lastfm; }
.#{$fa-css-prefix}-lastfm-square:before { content: $fa-var-lastfm-square; }
.#{$fa-css-prefix}-toggle-off:before { content: $fa-var-toggle-off; }
.#{$fa-css-prefix}-toggle-on:before { content: $fa-var-toggle-on; }
.#{$fa-css-prefix}-bicycle:before { content: $fa-var-bicycle; }
.#{$fa-css-prefix}-bus:before { content: $fa-var-bus; }
.#{$fa-css-prefix}-ioxhost:before { content: $fa-var-ioxhost; }
.#{$fa-css-prefix}-angellist:before { content: $fa-var-angellist; }
.#{$fa-css-prefix}-cc:before { content: $fa-var-cc; }
.#{$fa-css-prefix}-shekel:before,
.#{$fa-css-prefix}-sheqel:before,
.#{$fa-css-prefix}-ils:before { content: $fa-var-ils; }
.#{$fa-css-prefix}-meanpath:before { content: $fa-var-meanpath; }
.#{$fa-css-prefix}-buysellads:before { content: $fa-var-buysellads; }
.#{$fa-css-prefix}-connectdevelop:before { content: $fa-var-connectdevelop; }
.#{$fa-css-prefix}-dashcube:before { content: $fa-var-dashcube; }
.#{$fa-css-prefix}-forumbee:before { content: $fa-var-forumbee; }
.#{$fa-css-prefix}-leanpub:before { content: $fa-var-leanpub; }
.#{$fa-css-prefix}-sellsy:before { content: $fa-var-sellsy; }
.#{$fa-css-prefix}-shirtsinbulk:before { content: $fa-var-shirtsinbulk; }
.#{$fa-css-prefix}-simplybuilt:before { content: $fa-var-simplybuilt; }
.#{$fa-css-prefix}-skyatlas:before { content: $fa-var-skyatlas; }
.#{$fa-css-prefix}-cart-plus:before { content: $fa-var-cart-plus; }
.#{$fa-css-prefix}-cart-arrow-down:before { content: $fa-var-cart-arrow-down; }
.#{$fa-css-prefix}-diamond:before { content: $fa-var-diamond; }
.#{$fa-css-prefix}-ship:before { content: $fa-var-ship; }
.#{$fa-css-prefix}-user-secret:before { content: $fa-var-user-secret; }
.#{$fa-css-prefix}-motorcycle:before { content: $fa-var-motorcycle; }
.#{$fa-css-prefix}-street-view:before { content: $fa-var-street-view; }
.#{$fa-css-prefix}-heartbeat:before { content: $fa-var-heartbeat; }
.#{$fa-css-prefix}-venus:before { content: $fa-var-venus; }
.#{$fa-css-prefix}-mars:before { content: $fa-var-mars; }
.#{$fa-css-prefix}-mercury:before { content: $fa-var-mercury; }
.#{$fa-css-prefix}-intersex:before,
.#{$fa-css-prefix}-transgender:before { content: $fa-var-transgender; }
.#{$fa-css-prefix}-transgender-alt:before { content: $fa-var-transgender-alt; }
.#{$fa-css-prefix}-venus-double:before { content: $fa-var-venus-double; }
.#{$fa-css-prefix}-mars-double:before { content: $fa-var-mars-double; }
.#{$fa-css-prefix}-venus-mars:before { content: $fa-var-venus-mars; }
.#{$fa-css-prefix}-mars-stroke:before { content: $fa-var-mars-stroke; }
.#{$fa-css-prefix}-mars-stroke-v:before { content: $fa-var-mars-stroke-v; }
.#{$fa-css-prefix}-mars-stroke-h:before { content: $fa-var-mars-stroke-h; }
.#{$fa-css-prefix}-neuter:before { content: $fa-var-neuter; }
.#{$fa-css-prefix}-genderless:before { content: $fa-var-genderless; }
.#{$fa-css-prefix}-facebook-official:before { content: $fa-var-facebook-official; }
.#{$fa-css-prefix}-pinterest-p:before { content: $fa-var-pinterest-p; }
.#{$fa-css-prefix}-whatsapp:before { content: $fa-var-whatsapp; }
.#{$fa-css-prefix}-server:before { content: $fa-var-server; }
.#{$fa-css-prefix}-user-plus:before { content: $fa-var-user-plus; }
.#{$fa-css-prefix}-user-times:before { content: $fa-var-user-times; }
.#{$fa-css-prefix}-hotel:before,
.#{$fa-css-prefix}-bed:before { content: $fa-var-bed; }
.#{$fa-css-prefix}-viacoin:before { content: $fa-var-viacoin; }
.#{$fa-css-prefix}-train:before { content: $fa-var-train; }
.#{$fa-css-prefix}-subway:before { content: $fa-var-subway; }
.#{$fa-css-prefix}-medium:before { content: $fa-var-medium; }
.#{$fa-css-prefix}-yc:before,
.#{$fa-css-prefix}-y-combinator:before { content: $fa-var-y-combinator; }
.#{$fa-css-prefix}-optin-monster:before { content: $fa-var-optin-monster; }
.#{$fa-css-prefix}-opencart:before { content: $fa-var-opencart; }
.#{$fa-css-prefix}-expeditedssl:before { content: $fa-var-expeditedssl; }
.#{$fa-css-prefix}-battery-4:before,
.#{$fa-css-prefix}-battery-full:before { content: $fa-var-battery-full; }
.#{$fa-css-prefix}-battery-3:before,
.#{$fa-css-prefix}-battery-three-quarters:before { content: $fa-var-battery-three-quarters; }
.#{$fa-css-prefix}-battery-2:before,
.#{$fa-css-prefix}-battery-half:before { content: $fa-var-battery-half; }
.#{$fa-css-prefix}-battery-1:before,
.#{$fa-css-prefix}-battery-quarter:before { content: $fa-var-battery-quarter; }
.#{$fa-css-prefix}-battery-0:before,
.#{$fa-css-prefix}-battery-empty:before { content: $fa-var-battery-empty; }
.#{$fa-css-prefix}-mouse-pointer:before { content: $fa-var-mouse-pointer; }
.#{$fa-css-prefix}-i-cursor:before { content: $fa-var-i-cursor; }
.#{$fa-css-prefix}-object-group:before { content: $fa-var-object-group; }
.#{$fa-css-prefix}-object-ungroup:before { content: $fa-var-object-ungroup; }
.#{$fa-css-prefix}-sticky-note:before { content: $fa-var-sticky-note; }
.#{$fa-css-prefix}-sticky-note-o:before { content: $fa-var-sticky-note-o; }
.#{$fa-css-prefix}-cc-jcb:before { content: $fa-var-cc-jcb; }
.#{$fa-css-prefix}-cc-diners-club:before { content: $fa-var-cc-diners-club; }
.#{$fa-css-prefix}-clone:before { content: $fa-var-clone; }
.#{$fa-css-prefix}-balance-scale:before { content: $fa-var-balance-scale; }
.#{$fa-css-prefix}-hourglass-o:before { content: $fa-var-hourglass-o; }
.#{$fa-css-prefix}-hourglass-1:before,
.#{$fa-css-prefix}-hourglass-start:before { content: $fa-var-hourglass-start; }
.#{$fa-css-prefix}-hourglass-2:before,
.#{$fa-css-prefix}-hourglass-half:before { content: $fa-var-hourglass-half; }
.#{$fa-css-prefix}-hourglass-3:before,
.#{$fa-css-prefix}-hourglass-end:before { content: $fa-var-hourglass-end; }
.#{$fa-css-prefix}-hourglass:before { content: $fa-var-hourglass; }
.#{$fa-css-prefix}-hand-grab-o:before,
.#{$fa-css-prefix}-hand-rock-o:before { content: $fa-var-hand-rock-o; }
.#{$fa-css-prefix}-hand-stop-o:before,
.#{$fa-css-prefix}-hand-paper-o:before { content: $fa-var-hand-paper-o; }
.#{$fa-css-prefix}-hand-scissors-o:before { content: $fa-var-hand-scissors-o; }
.#{$fa-css-prefix}-hand-lizard-o:before { content: $fa-var-hand-lizard-o; }
.#{$fa-css-prefix}-hand-spock-o:before { content: $fa-var-hand-spock-o; }
.#{$fa-css-prefix}-hand-pointer-o:before { content: $fa-var-hand-pointer-o; }
.#{$fa-css-prefix}-hand-peace-o:before { content: $fa-var-hand-peace-o; }
.#{$fa-css-prefix}-trademark:before { content: $fa-var-trademark; }
.#{$fa-css-prefix}-registered:before { content: $fa-var-registered; }
.#{$fa-css-prefix}-creative-commons:before { content: $fa-var-creative-commons; }
.#{$fa-css-prefix}-gg:before { content: $fa-var-gg; }
.#{$fa-css-prefix}-gg-circle:before { content: $fa-var-gg-circle; }
.#{$fa-css-prefix}-tripadvisor:before { content: $fa-var-tripadvisor; }
.#{$fa-css-prefix}-odnoklassniki:before { content: $fa-var-odnoklassniki; }
.#{$fa-css-prefix}-odnoklassniki-square:before { content: $fa-var-odnoklassniki-square; }
.#{$fa-css-prefix}-get-pocket:before { content: $fa-var-get-pocket; }
.#{$fa-css-prefix}-wikipedia-w:before { content: $fa-var-wikipedia-w; }
.#{$fa-css-prefix}-safari:before { content: $fa-var-safari; }
.#{$fa-css-prefix}-chrome:before { content: $fa-var-chrome; }
.#{$fa-css-prefix}-firefox:before { content: $fa-var-firefox; }
.#{$fa-css-prefix}-opera:before { content: $fa-var-opera; }
.#{$fa-css-prefix}-internet-explorer:before { content: $fa-var-internet-explorer; }
.#{$fa-css-prefix}-tv:before,
.#{$fa-css-prefix}-television:before { content: $fa-var-television; }
.#{$fa-css-prefix}-contao:before { content: $fa-var-contao; }
.#{$fa-css-prefix}-500px:before { content: $fa-var-500px; }
.#{$fa-css-prefix}-amazon:before { content: $fa-var-amazon; }
.#{$fa-css-prefix}-calendar-plus-o:before { content: $fa-var-calendar-plus-o; }
.#{$fa-css-prefix}-calendar-minus-o:before { content: $fa-var-calendar-minus-o; }
.#{$fa-css-prefix}-calendar-times-o:before { content: $fa-var-calendar-times-o; }
.#{$fa-css-prefix}-calendar-check-o:before { content: $fa-var-calendar-check-o; }
.#{$fa-css-prefix}-industry:before { content: $fa-var-industry; }
.#{$fa-css-prefix}-map-pin:before { content: $fa-var-map-pin; }
.#{$fa-css-prefix}-map-signs:before { content: $fa-var-map-signs; }
.#{$fa-css-prefix}-map-o:before { content: $fa-var-map-o; }
.#{$fa-css-prefix}-map:before { content: $fa-var-map; }
.#{$fa-css-prefix}-commenting:before { content: $fa-var-commenting; }
.#{$fa-css-prefix}-commenting-o:before { content: $fa-var-commenting-o; }
.#{$fa-css-prefix}-houzz:before { content: $fa-var-houzz; }
.#{$fa-css-prefix}-vimeo:before { content: $fa-var-vimeo; }
.#{$fa-css-prefix}-black-tie:before { content: $fa-var-black-tie; }
.#{$fa-css-prefix}-fonticons:before { content: $fa-var-fonticons; }

14
stylesheets/font-awesome/scss/_mixins.scss

@ -1,20 +1,26 @@
// Mixins
// --------------------------
@mixin fa-icon() {
display: inline-block;
font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
font-size: inherit; // can't have font-size inherit on line above, so need to override
text-rendering: auto; // optimizelegibility throws things off #1094
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@mixin fa-icon-rotate($degrees, $rotation) {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation});
-webkit-transform: rotate($degrees);
-moz-transform: rotate($degrees);
-ms-transform: rotate($degrees);
-o-transform: rotate($degrees);
transform: rotate($degrees);
}
@mixin fa-icon-flip($horiz, $vert, $rotation) {
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation});
-webkit-transform: scale($horiz, $vert);
-moz-transform: scale($horiz, $vert);
-ms-transform: scale($horiz, $vert);
-o-transform: scale($horiz, $vert);
transform: scale($horiz, $vert);
}

3
stylesheets/font-awesome/scss/_path.scss

@ -5,10 +5,11 @@
font-family: 'FontAwesome';
src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
//src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
// src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
font-weight: normal;
font-style: normal;
}

11
stylesheets/font-awesome/scss/_rotated-flipped.scss

@ -7,3 +7,14 @@
.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
// Hook for IE8-9
// -------------------------
:root .#{$fa-css-prefix}-rotate-90,
:root .#{$fa-css-prefix}-rotate-180,
:root .#{$fa-css-prefix}-rotate-270,
:root .#{$fa-css-prefix}-flip-horizontal,
:root .#{$fa-css-prefix}-flip-vertical {
filter: none;
}

179
stylesheets/font-awesome/scss/_variables.scss

@ -2,22 +2,27 @@
// --------------------------
$fa-font-path: "../fonts" !default;
//$fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.1.0/fonts" !default; // for referencing Bootstrap CDN font files directly
$fa-font-size-base: 14px !default;
$fa-line-height-base: 1 !default;
//$fa-font-path: "//netdna.bootstrapcdn.com/font-awesome/4.4.0/fonts" !default; // for referencing Bootstrap CDN font files directly
$fa-css-prefix: fa !default;
$fa-version: "4.1.0" !default;
$fa-version: "4.4.0" !default;
$fa-border-color: #eee !default;
$fa-inverse: #fff !default;
$fa-li-width: (30em / 14) !default;
$fa-var-500px: "\f26e";
$fa-var-adjust: "\f042";
$fa-var-adn: "\f170";
$fa-var-align-center: "\f037";
$fa-var-align-justify: "\f039";
$fa-var-align-left: "\f036";
$fa-var-align-right: "\f038";
$fa-var-amazon: "\f270";
$fa-var-ambulance: "\f0f9";
$fa-var-anchor: "\f13d";
$fa-var-android: "\f17b";
$fa-var-angellist: "\f209";
$fa-var-angle-double-down: "\f103";
$fa-var-angle-double-left: "\f100";
$fa-var-angle-double-right: "\f101";
@ -28,6 +33,7 @@ $fa-var-angle-right: "\f105";
$fa-var-angle-up: "\f106";
$fa-var-apple: "\f179";
$fa-var-archive: "\f187";
$fa-var-area-chart: "\f1fe";
$fa-var-arrow-circle-down: "\f0ab";
$fa-var-arrow-circle-left: "\f0a8";
$fa-var-arrow-circle-o-down: "\f01a";
@ -45,21 +51,41 @@ $fa-var-arrows-alt: "\f0b2";
$fa-var-arrows-h: "\f07e";
$fa-var-arrows-v: "\f07d";
$fa-var-asterisk: "\f069";
$fa-var-at: "\f1fa";
$fa-var-automobile: "\f1b9";
$fa-var-backward: "\f04a";
$fa-var-balance-scale: "\f24e";
$fa-var-ban: "\f05e";
$fa-var-bank: "\f19c";
$fa-var-bar-chart: "\f080";
$fa-var-bar-chart-o: "\f080";
$fa-var-barcode: "\f02a";
$fa-var-bars: "\f0c9";
$fa-var-battery-0: "\f244";
$fa-var-battery-1: "\f243";
$fa-var-battery-2: "\f242";
$fa-var-battery-3: "\f241";
$fa-var-battery-4: "\f240";
$fa-var-battery-empty: "\f244";
$fa-var-battery-full: "\f240";
$fa-var-battery-half: "\f242";
$fa-var-battery-quarter: "\f243";
$fa-var-battery-three-quarters: "\f241";
$fa-var-bed: "\f236";
$fa-var-beer: "\f0fc";
$fa-var-behance: "\f1b4";
$fa-var-behance-square: "\f1b5";
$fa-var-bell: "\f0f3";
$fa-var-bell-o: "\f0a2";
$fa-var-bell-slash: "\f1f6";
$fa-var-bell-slash-o: "\f1f7";
$fa-var-bicycle: "\f206";
$fa-var-binoculars: "\f1e5";
$fa-var-birthday-cake: "\f1fd";
$fa-var-bitbucket: "\f171";
$fa-var-bitbucket-square: "\f172";
$fa-var-bitcoin: "\f15a";
$fa-var-black-tie: "\f27e";
$fa-var-bold: "\f032";
$fa-var-bolt: "\f0e7";
$fa-var-bomb: "\f1e2";
@ -73,9 +99,16 @@ $fa-var-building: "\f1ad";
$fa-var-building-o: "\f0f7";
$fa-var-bullhorn: "\f0a1";
$fa-var-bullseye: "\f140";
$fa-var-bus: "\f207";
$fa-var-buysellads: "\f20d";
$fa-var-cab: "\f1ba";
$fa-var-calculator: "\f1ec";
$fa-var-calendar: "\f073";
$fa-var-calendar-check-o: "\f274";
$fa-var-calendar-minus-o: "\f272";
$fa-var-calendar-o: "\f133";
$fa-var-calendar-plus-o: "\f271";
$fa-var-calendar-times-o: "\f273";
$fa-var-camera: "\f030";
$fa-var-camera-retro: "\f083";
$fa-var-car: "\f1b9";
@ -87,6 +120,17 @@ $fa-var-caret-square-o-left: "\f191";
$fa-var-caret-square-o-right: "\f152";
$fa-var-caret-square-o-up: "\f151";
$fa-var-caret-up: "\f0d8";
$fa-var-cart-arrow-down: "\f218";
$fa-var-cart-plus: "\f217";
$fa-var-cc: "\f20a";
$fa-var-cc-amex: "\f1f3";
$fa-var-cc-diners-club: "\f24c";
$fa-var-cc-discover: "\f1f2";
$fa-var-cc-jcb: "\f24b";
$fa-var-cc-mastercard: "\f1f1";
$fa-var-cc-paypal: "\f1f4";
$fa-var-cc-stripe: "\f1f5";
$fa-var-cc-visa: "\f1f0";
$fa-var-certificate: "\f0a3";
$fa-var-chain: "\f0c1";
$fa-var-chain-broken: "\f127";
@ -104,12 +148,15 @@ $fa-var-chevron-left: "\f053";
$fa-var-chevron-right: "\f054";
$fa-var-chevron-up: "\f077";
$fa-var-child: "\f1ae";
$fa-var-chrome: "\f268";
$fa-var-circle: "\f111";
$fa-var-circle-o: "\f10c";
$fa-var-circle-o-notch: "\f1ce";
$fa-var-circle-thin: "\f1db";
$fa-var-clipboard: "\f0ea";
$fa-var-clock-o: "\f017";
$fa-var-clone: "\f24d";
$fa-var-close: "\f00d";
$fa-var-cloud: "\f0c2";
$fa-var-cloud-download: "\f0ed";
$fa-var-cloud-upload: "\f0ee";
@ -123,11 +170,17 @@ $fa-var-cogs: "\f085";
$fa-var-columns: "\f0db";
$fa-var-comment: "\f075";
$fa-var-comment-o: "\f0e5";
$fa-var-commenting: "\f27a";
$fa-var-commenting-o: "\f27b";
$fa-var-comments: "\f086";
$fa-var-comments-o: "\f0e6";
$fa-var-compass: "\f14e";
$fa-var-compress: "\f066";
$fa-var-connectdevelop: "\f20e";
$fa-var-contao: "\f26d";
$fa-var-copy: "\f0c5";
$fa-var-copyright: "\f1f9";
$fa-var-creative-commons: "\f25e";
$fa-var-credit-card: "\f09d";
$fa-var-crop: "\f125";
$fa-var-crosshairs: "\f05b";
@ -137,11 +190,13 @@ $fa-var-cubes: "\f1b3";
$fa-var-cut: "\f0c4";
$fa-var-cutlery: "\f0f5";
$fa-var-dashboard: "\f0e4";
$fa-var-dashcube: "\f210";
$fa-var-database: "\f1c0";
$fa-var-dedent: "\f03b";
$fa-var-delicious: "\f1a5";
$fa-var-desktop: "\f108";
$fa-var-deviantart: "\f1bd";
$fa-var-diamond: "\f219";
$fa-var-digg: "\f1a6";
$fa-var-dollar: "\f155";
$fa-var-dot-circle-o: "\f192";
@ -165,15 +220,20 @@ $fa-var-exclamation: "\f12a";
$fa-var-exclamation-circle: "\f06a";
$fa-var-exclamation-triangle: "\f071";
$fa-var-expand: "\f065";
$fa-var-expeditedssl: "\f23e";
$fa-var-external-link: "\f08e";
$fa-var-external-link-square: "\f14c";
$fa-var-eye: "\f06e";
$fa-var-eye-slash: "\f070";
$fa-var-eyedropper: "\f1fb";
$fa-var-facebook: "\f09a";
$fa-var-facebook-f: "\f09a";
$fa-var-facebook-official: "\f230";
$fa-var-facebook-square: "\f082";
$fa-var-fast-backward: "\f049";
$fa-var-fast-forward: "\f050";
$fa-var-fax: "\f1ac";
$fa-var-feed: "\f09e";
$fa-var-female: "\f182";
$fa-var-fighter-jet: "\f0fb";
$fa-var-file: "\f15b";
@ -199,6 +259,7 @@ $fa-var-film: "\f008";
$fa-var-filter: "\f0b0";
$fa-var-fire: "\f06d";
$fa-var-fire-extinguisher: "\f134";
$fa-var-firefox: "\f269";
$fa-var-flag: "\f024";
$fa-var-flag-checkered: "\f11e";
$fa-var-flag-o: "\f11d";
@ -211,15 +272,22 @@ $fa-var-folder-o: "\f114";
$fa-var-folder-open: "\f07c";
$fa-var-folder-open-o: "\f115";
$fa-var-font: "\f031";
$fa-var-fonticons: "\f280";
$fa-var-forumbee: "\f211";
$fa-var-forward: "\f04e";
$fa-var-foursquare: "\f180";
$fa-var-frown-o: "\f119";
$fa-var-futbol-o: "\f1e3";
$fa-var-gamepad: "\f11b";
$fa-var-gavel: "\f0e3";
$fa-var-gbp: "\f154";
$fa-var-ge: "\f1d1";
$fa-var-gear: "\f013";
$fa-var-gears: "\f085";
$fa-var-genderless: "\f22d";
$fa-var-get-pocket: "\f265";
$fa-var-gg: "\f260";
$fa-var-gg-circle: "\f261";
$fa-var-gift: "\f06b";
$fa-var-git: "\f1d3";
$fa-var-git-square: "\f1d2";
@ -232,31 +300,59 @@ $fa-var-globe: "\f0ac";
$fa-var-google: "\f1a0";
$fa-var-google-plus: "\f0d5";
$fa-var-google-plus-square: "\f0d4";
$fa-var-google-wallet: "\f1ee";
$fa-var-graduation-cap: "\f19d";
$fa-var-gratipay: "\f184";
$fa-var-group: "\f0c0";
$fa-var-h-square: "\f0fd";
$fa-var-hacker-news: "\f1d4";
$fa-var-hand-grab-o: "\f255";
$fa-var-hand-lizard-o: "\f258";
$fa-var-hand-o-down: "\f0a7";
$fa-var-hand-o-left: "\f0a5";
$fa-var-hand-o-right: "\f0a4";
$fa-var-hand-o-up: "\f0a6";
$fa-var-hand-paper-o: "\f256";
$fa-var-hand-peace-o: "\f25b";
$fa-var-hand-pointer-o: "\f25a";
$fa-var-hand-rock-o: "\f255";
$fa-var-hand-scissors-o: "\f257";
$fa-var-hand-spock-o: "\f259";
$fa-var-hand-stop-o: "\f256";
$fa-var-hdd-o: "\f0a0";
$fa-var-header: "\f1dc";
$fa-var-headphones: "\f025";
$fa-var-heart: "\f004";
$fa-var-heart-o: "\f08a";
$fa-var-heartbeat: "\f21e";
$fa-var-history: "\f1da";
$fa-var-home: "\f015";
$fa-var-hospital-o: "\f0f8";
$fa-var-hotel: "\f236";
$fa-var-hourglass: "\f254";
$fa-var-hourglass-1: "\f251";
$fa-var-hourglass-2: "\f252";
$fa-var-hourglass-3: "\f253";
$fa-var-hourglass-end: "\f253";
$fa-var-hourglass-half: "\f252";
$fa-var-hourglass-o: "\f250";
$fa-var-hourglass-start: "\f251";
$fa-var-houzz: "\f27c";
$fa-var-html5: "\f13b";
$fa-var-i-cursor: "\f246";
$fa-var-ils: "\f20b";
$fa-var-image: "\f03e";
$fa-var-inbox: "\f01c";
$fa-var-indent: "\f03c";
$fa-var-industry: "\f275";
$fa-var-info: "\f129";
$fa-var-info-circle: "\f05a";
$fa-var-inr: "\f156";
$fa-var-instagram: "\f16d";
$fa-var-institution: "\f19c";
$fa-var-internet-explorer: "\f26b";
$fa-var-intersex: "\f224";
$fa-var-ioxhost: "\f208";
$fa-var-italic: "\f033";
$fa-var-joomla: "\f1aa";
$fa-var-jpy: "\f157";
@ -266,15 +362,20 @@ $fa-var-keyboard-o: "\f11c";
$fa-var-krw: "\f159";
$fa-var-language: "\f1ab";
$fa-var-laptop: "\f109";
$fa-var-lastfm: "\f202";
$fa-var-lastfm-square: "\f203";
$fa-var-leaf: "\f06c";
$fa-var-leanpub: "\f212";
$fa-var-legal: "\f0e3";
$fa-var-lemon-o: "\f094";
$fa-var-level-down: "\f149";
$fa-var-level-up: "\f148";
$fa-var-life-bouy: "\f1cd";
$fa-var-life-buoy: "\f1cd";
$fa-var-life-ring: "\f1cd";
$fa-var-life-saver: "\f1cd";
$fa-var-lightbulb-o: "\f0eb";
$fa-var-line-chart: "\f201";
$fa-var-link: "\f0c1";
$fa-var-linkedin: "\f0e1";
$fa-var-linkedin-square: "\f08c";
@ -295,10 +396,22 @@ $fa-var-mail-forward: "\f064";
$fa-var-mail-reply: "\f112";
$fa-var-mail-reply-all: "\f122";
$fa-var-male: "\f183";
$fa-var-map: "\f279";
$fa-var-map-marker: "\f041";
$fa-var-map-o: "\f278";
$fa-var-map-pin: "\f276";
$fa-var-map-signs: "\f277";
$fa-var-mars: "\f222";
$fa-var-mars-double: "\f227";
$fa-var-mars-stroke: "\f229";
$fa-var-mars-stroke-h: "\f22b";
$fa-var-mars-stroke-v: "\f22a";
$fa-var-maxcdn: "\f136";
$fa-var-meanpath: "\f20c";
$fa-var-medium: "\f23a";
$fa-var-medkit: "\f0fa";
$fa-var-meh-o: "\f11a";
$fa-var-mercury: "\f223";
$fa-var-microphone: "\f130";
$fa-var-microphone-slash: "\f131";
$fa-var-minus: "\f068";
@ -310,11 +423,23 @@ $fa-var-mobile-phone: "\f10b";
$fa-var-money: "\f0d6";
$fa-var-moon-o: "\f186";
$fa-var-mortar-board: "\f19d";
$fa-var-motorcycle: "\f21c";
$fa-var-mouse-pointer: "\f245";
$fa-var-music: "\f001";
$fa-var-navicon: "\f0c9";
$fa-var-neuter: "\f22c";
$fa-var-newspaper-o: "\f1ea";
$fa-var-object-group: "\f247";
$fa-var-object-ungroup: "\f248";
$fa-var-odnoklassniki: "\f263";
$fa-var-odnoklassniki-square: "\f264";
$fa-var-opencart: "\f23d";
$fa-var-openid: "\f19b";
$fa-var-opera: "\f26a";
$fa-var-optin-monster: "\f23c";
$fa-var-outdent: "\f03b";
$fa-var-pagelines: "\f18c";
$fa-var-paint-brush: "\f1fc";
$fa-var-paper-plane: "\f1d8";
$fa-var-paper-plane-o: "\f1d9";
$fa-var-paperclip: "\f0c6";
@ -322,6 +447,7 @@ $fa-var-paragraph: "\f1dd";
$fa-var-paste: "\f0ea";
$fa-var-pause: "\f04c";
$fa-var-paw: "\f1b0";
$fa-var-paypal: "\f1ed";
$fa-var-pencil: "\f040";
$fa-var-pencil-square: "\f14b";
$fa-var-pencil-square-o: "\f044";
@ -329,15 +455,17 @@ $fa-var-phone: "\f095";
$fa-var-phone-square: "\f098";
$fa-var-photo: "\f03e";
$fa-var-picture-o: "\f03e";
$fa-var-pie-chart: "\f200";
$fa-var-pied-piper: "\f1a7";
$fa-var-pied-piper-alt: "\f1a8";
$fa-var-pied-piper-square: "\f1a7";
$fa-var-pinterest: "\f0d2";
$fa-var-pinterest-p: "\f231";
$fa-var-pinterest-square: "\f0d3";
$fa-var-plane: "\f072";
$fa-var-play: "\f04b";
$fa-var-play-circle: "\f144";
$fa-var-play-circle-o: "\f01d";
$fa-var-plug: "\f1e6";
$fa-var-plus: "\f067";
$fa-var-plus-circle: "\f055";
$fa-var-plus-square: "\f0fe";
@ -358,6 +486,8 @@ $fa-var-recycle: "\f1b8";
$fa-var-reddit: "\f1a1";
$fa-var-reddit-square: "\f1a2";
$fa-var-refresh: "\f021";
$fa-var-registered: "\f25d";
$fa-var-remove: "\f00d";
$fa-var-renren: "\f18b";
$fa-var-reorder: "\f0c9";
$fa-var-repeat: "\f01e";
@ -375,28 +505,39 @@ $fa-var-rss-square: "\f143";
$fa-var-rub: "\f158";
$fa-var-ruble: "\f158";
$fa-var-rupee: "\f156";
$fa-var-safari: "\f267";
$fa-var-save: "\f0c7";
$fa-var-scissors: "\f0c4";
$fa-var-search: "\f002";
$fa-var-search-minus: "\f010";
$fa-var-search-plus: "\f00e";
$fa-var-sellsy: "\f213";
$fa-var-send: "\f1d8";
$fa-var-send-o: "\f1d9";
$fa-var-server: "\f233";
$fa-var-share: "\f064";
$fa-var-share-alt: "\f1e0";
$fa-var-share-alt-square: "\f1e1";
$fa-var-share-square: "\f14d";
$fa-var-share-square-o: "\f045";
$fa-var-shekel: "\f20b";
$fa-var-sheqel: "\f20b";
$fa-var-shield: "\f132";
$fa-var-ship: "\f21a";
$fa-var-shirtsinbulk: "\f214";
$fa-var-shopping-cart: "\f07a";
$fa-var-sign-in: "\f090";
$fa-var-sign-out: "\f08b";
$fa-var-signal: "\f012";
$fa-var-simplybuilt: "\f215";
$fa-var-sitemap: "\f0e8";
$fa-var-skyatlas: "\f216";
$fa-var-skype: "\f17e";
$fa-var-slack: "\f198";
$fa-var-sliders: "\f1de";
$fa-var-slideshare: "\f1e7";
$fa-var-smile-o: "\f118";
$fa-var-soccer-ball-o: "\f1e3";
$fa-var-sort: "\f0dc";
$fa-var-sort-alpha-asc: "\f15d";
$fa-var-sort-alpha-desc: "\f15e";
@ -428,11 +569,15 @@ $fa-var-steam-square: "\f1b7";
$fa-var-step-backward: "\f048";
$fa-var-step-forward: "\f051";
$fa-var-stethoscope: "\f0f1";
$fa-var-sticky-note: "\f249";
$fa-var-sticky-note-o: "\f24a";
$fa-var-stop: "\f04d";
$fa-var-street-view: "\f21d";
$fa-var-strikethrough: "\f0cc";
$fa-var-stumbleupon: "\f1a4";
$fa-var-stumbleupon-circle: "\f1a3";
$fa-var-subscript: "\f12c";
$fa-var-subway: "\f239";
$fa-var-suitcase: "\f0f2";
$fa-var-sun-o: "\f185";
$fa-var-superscript: "\f12b";
@ -444,6 +589,7 @@ $fa-var-tag: "\f02b";
$fa-var-tags: "\f02c";
$fa-var-tasks: "\f0ae";
$fa-var-taxi: "\f1ba";
$fa-var-television: "\f26c";
$fa-var-tencent-weibo: "\f1d5";
$fa-var-terminal: "\f120";
$fa-var-text-height: "\f034";
@ -463,17 +609,28 @@ $fa-var-times-circle-o: "\f05c";
$fa-var-tint: "\f043";
$fa-var-toggle-down: "\f150";
$fa-var-toggle-left: "\f191";
$fa-var-toggle-off: "\f204";
$fa-var-toggle-on: "\f205";
$fa-var-toggle-right: "\f152";
$fa-var-toggle-up: "\f151";
$fa-var-trademark: "\f25c";
$fa-var-train: "\f238";
$fa-var-transgender: "\f224";
$fa-var-transgender-alt: "\f225";
$fa-var-trash: "\f1f8";
$fa-var-trash-o: "\f014";
$fa-var-tree: "\f1bb";
$fa-var-trello: "\f181";
$fa-var-tripadvisor: "\f262";
$fa-var-trophy: "\f091";
$fa-var-truck: "\f0d1";
$fa-var-try: "\f195";
$fa-var-tty: "\f1e4";
$fa-var-tumblr: "\f173";
$fa-var-tumblr-square: "\f174";
$fa-var-turkish-lira: "\f195";
$fa-var-tv: "\f26c";
$fa-var-twitch: "\f1e8";
$fa-var-twitter: "\f099";
$fa-var-twitter-square: "\f081";
$fa-var-umbrella: "\f0e9";
@ -488,8 +645,16 @@ $fa-var-upload: "\f093";
$fa-var-usd: "\f155";
$fa-var-user: "\f007";
$fa-var-user-md: "\f0f0";
$fa-var-user-plus: "\f234";
$fa-var-user-secret: "\f21b";
$fa-var-user-times: "\f235";
$fa-var-users: "\f0c0";
$fa-var-venus: "\f221";
$fa-var-venus-double: "\f226";
$fa-var-venus-mars: "\f228";
$fa-var-viacoin: "\f237";
$fa-var-video-camera: "\f03d";
$fa-var-vimeo: "\f27d";
$fa-var-vimeo-square: "\f194";
$fa-var-vine: "\f1ca";
$fa-var-vk: "\f189";
@ -500,14 +665,22 @@ $fa-var-warning: "\f071";
$fa-var-wechat: "\f1d7";
$fa-var-weibo: "\f18a";
$fa-var-weixin: "\f1d7";
$fa-var-whatsapp: "\f232";
$fa-var-wheelchair: "\f193";
$fa-var-wifi: "\f1eb";
$fa-var-wikipedia-w: "\f266";
$fa-var-windows: "\f17a";
$fa-var-won: "\f159";
$fa-var-wordpress: "\f19a";
$fa-var-wrench: "\f0ad";
$fa-var-xing: "\f168";
$fa-var-xing-square: "\f169";
$fa-var-y-combinator: "\f23b";
$fa-var-y-combinator-square: "\f1d4";
$fa-var-yahoo: "\f19e";
$fa-var-yc: "\f23b";
$fa-var-yc-square: "\f1d4";
$fa-var-yelp: "\f1e9";
$fa-var-yen: "\f157";
$fa-var-youtube: "\f167";
$fa-var-youtube-play: "\f16a";

4
stylesheets/font-awesome/scss/font-awesome.scss

@ -1,5 +1,5 @@
/*!
* Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome
* Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
*/
@ -11,7 +11,7 @@
@import "fixed-width";
@import "list";
@import "bordered-pulled";
@import "spinning";
@import "animated";
@import "rotated-flipped";
@import "stacked";
@import "icons";

19
stylesheets/futaba+vichan.css

@ -15,7 +15,7 @@ div.title p {
div.pages {
font-size: 13px !important;
}
a:link, a:visited, p.intro a.email span.name {
a:link, a:visited, .intro a.email span.name {
color: #0000ff;
font-size: inherit;
text-decoration: inherit;
@ -41,7 +41,7 @@ div.post.reply.highlighted {
div.post.reply div.body a {
color: navy;
}
p.intro span.subject {
.intro span.subject {
color: #d00;
}
form table tr th {
@ -83,22 +83,16 @@ div.boardlist a {
table.modlog tr th {
background: #EA8;
}
div.boardlist {
background-color: rgba(90%,90%,90%,0.2);
.desktop-style div.boardlist:nth-child(1), .desktop-style div.boardlist:nth-child(1):hover {
background-color: #f0e0d6;
}
div.boardlist .sub {
background: none;
}
div.boardlist.bottom {
background-color:transparent;
}
.desktop-style div.boardlist:nth-child(1) {
text-shadow: #fff 1px 1px 1px, #fff -1px -1px 1px;
}
.desktop-style div.boardlist:nth-child(1):hover, .desktop-style div.boardlist:nth-child(1).cb-menu {
background-color: rgba(90%, 90%, 90%, 0.55);
}
/* options.js */
#options_div, #alert_div {
@ -116,3 +110,8 @@ div.boardlist.bottom {
border-color: #d9bfb7;
border-width: 1px 0px 0px 1px;
}
.dropzone {
background-color: white;
border: 1px solid #a9a9a9;
}

4
stylesheets/futaba-light.css

@ -15,7 +15,7 @@ div.title p {
div.pages {
font-size: 13px !important;
}
a:link, a:visited, p.intro a.email span.name {
a:link, a:visited, .intro a.email span.name {
color: #A32615;
font-size: inherit;
text-decoration: inherit;
@ -42,7 +42,7 @@ div.post.reply.highlighted {
div.post.reply div.body a {
color: rgb(190, 79, 43);
}
p.intro span.subject {
.intro span.subject {
color: #AA4848;
}
form table tr th {

4
stylesheets/futaba.css

@ -10,7 +10,7 @@ div.title h1 {
div.title p {
font-size: 10px;
}
a:link, a:visited, p.intro a.email span.name {
a:link, a:visited, .intro a.email span.name {
color: #0000ff;
}
a:link:hover {
@ -30,7 +30,7 @@ div.post.reply.highlighted {
div.post.reply div.body a {
color: navy;
}
p.intro span.subject {
.intro span.subject {
color: #d00;
}
form table tr th {

4
stylesheets/gentoochan.css

@ -2,7 +2,7 @@ body {
background: #0E0E0E url(data:image/gif;base64,R0lGODlhGAAMAKEEAOXl5ebm5vDw8PHx8SH+EUNyZWF0ZWQgd2l0aCBHSU1QACwAAAAAGAAMAAACRpQiY6cLa146MyY1EJQKjG81lNGRUPOIkgMJHtquBgIO7xwvpbrpduUSuXq8ntEC0bBEylYitdDAdM1ViaobkgKgZwyDLAAAOw==) repeat 0 0!important;
color: #000;
}
a:link, a:visited, p.intro a.email span.name {
a:link, a:visited, .intro a.email span.name {
-webkit-transition: all ease-in 0.3s;
-moz-transition: all ease-in 0.3s;
color: rgba(0, 0, 0, 0.6);
@ -33,7 +33,7 @@ div.post.reply.highlighted {
div.post.reply p.body a {
color: navy;
}
p.intro span.subject {
.intro span.subject {
color: #000;
}
form table tr th {

4
stylesheets/jungle.css

@ -66,7 +66,7 @@ box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.35);
div.post.reply div.body a {
color: #00E;
}
p.intro span.subject {
.intro span.subject {
color: #d00;
}
form table tr th {
@ -118,7 +118,7 @@ table.modlog tr th {
background: #EA8;
}
p.intro span.name {
.intro span.name {
color: maroon;
font-weight: 600;
}

22
stylesheets/luna.css

@ -22,7 +22,7 @@ a, a:selected {
text-decoration: bold;
color: #ffffff;
}
a:hover, p.intro a.post_no:hover {
a:hover, .intro a.post_no:hover {
color: #ffffff;
}
a.post_no {
@ -30,19 +30,19 @@ a.post_no {
margin: 0;
padding: 0;
}
p.intro a.post_no {
.intro a.post_no {
color: inherit;
}
p.intro a.post_no, p.intro a.email {
.intro a.post_no, p.intro a.email {
margin: 0;
}
p.intro a.email span.name {
.intro a.email span.name {
color: #0091ff;
}
p.intro a.email:hover span.name {
.intro a.email:hover span.name {
color: #ffffff;
}
p.intro label {
.intro label {
display: inline;
}
h2 {
@ -165,7 +165,7 @@ div.post.op {
div.post.op hr {
border-color: #040934;
}
p.intro {
.intro {
margin: 0.5em 0;
padding: 0;
padding-bottom: 0.2em;
@ -174,19 +174,19 @@ input.delete {
float: left;
margin: 1px 6px 0 0;
}
p.intro span.subject {
.intro span.subject {
color: #CCCCEE;
font-weight: bold;
}
p.intro span.name {
.intro span.name {
color: #BBBBDD;
font-weight: bold;
}
p.intro span.capcode, p.intro a.capcode, p.intro a.nametag {
.intro span.capcode, p.intro a.capcode, p.intro a.nametag {
color: #CCCCEE;
margin-left: 0;
}
p.intro a {
.intro a {
margin-left: 8px;
}
div.delete {

8
stylesheets/miku.css

@ -19,11 +19,11 @@ a.post_no {
color: #000033;
}
p.intro a.email span.name {
.intro a.email span.name {
color: #0093AB;
}
p.intro a.email:hover span.name {
.intro a.email:hover span.name {
color: #DD0000;
}
@ -43,12 +43,12 @@ div.post.op hr {
border-color: #B7C9D5;
}
p.intro span.subject {
.intro span.subject {
color: #117743;
font-weight: 800;
}
p.intro span.name {
.intro span.name {
color: #117743;
font-weight: 800;
}

8
stylesheets/nigrachan.css

@ -52,7 +52,7 @@ input[type="text"], input[type="password"], textarea, input[type="submit"], inpu
border: 1px solid #202020;
}
p.intro span.name {
.intro span.name {
font-size: 11pt;
color: #505050;
font-weight: bold;
@ -88,16 +88,16 @@ div.post.reply.highlighted {
background: #111111;
}
p.intro a.email span.name {
.intro a.email span.name {
color: #FFFFFF;
}
p.intro a.email:hover span.name {
.intro a.email:hover span.name {
color: #A0A0A0;
text-decoration: underline;
}
p.intro span.subject {
.intro span.subject {
color: #606060;
}

8
stylesheets/notsuba.css

@ -20,11 +20,11 @@ a.post_no {
color: #000033;
}
p.intro a.email span.name {
.intro a.email span.name {
color: #608673;
}
p.intro a.email:hover span.name {
.intro a.email:hover span.name {
color: #DD0000;
}
@ -44,12 +44,12 @@ div.post.op hr {
border-color: #608673;
}
p.intro span.subject {
.intro span.subject {
color: #8a2e2e;
font-weight: 800;
}
p.intro span.name {
.intro span.name {
color: #117743;
font-weight: 800;
}

6
stylesheets/novo_jungle.css

@ -65,7 +65,7 @@ form[name="postcontrols"] {
margin: 20px auto;
}
p.intro span.name {
.intro span.name {
color: #800000;
font-weight: 800;
}
@ -104,11 +104,11 @@ div.post.reply.highlighted {
background-image: url('img/jungle_td_dark.png');;
}
p.intro a.email span.name {
.intro a.email span.name {
color: #0000EE;
}
p.intro a.email:hover span.name {
.intro a.email:hover span.name {
color: #00990B;
}

2
stylesheets/photon.css

@ -326,6 +326,6 @@ form table tr td div {
padding: 0px !important;
}
.desktop-style div.boardlist:nth-child(1) {
.desktop-style div.boardlist:not(.bottom) {
background-color: #DDDDDD;
}

4
stylesheets/piwnichan.css

@ -41,7 +41,7 @@ a.email span.name {
color: #5A8C99 !important;
}
p.intro span.capcode, p.intro a.capcode, p.intro a.nametag {
.intro span.capcode, p.intro a.capcode, p.intro a.nametag {
color: #6E0877;
}
@ -157,7 +157,7 @@ div.banner, .replymode, .catalogmode {
font-weight:800;
}
p.intro span.subject {
.intro span.subject {
color: #4D2C80;
font-weight: bold;
}

2
stylesheets/ricechan.css

@ -190,7 +190,7 @@ blockquote {
.de-refmap {
color: #4C505E !important;
}
p.intro a.email span.name {
.intro a.email span.name {
text-decoration: underline;
}
.quote {

188
stylesheets/style.css

@ -13,7 +13,7 @@ a,a:visited {
color: #34345C;
}
a:hover,p.intro a.post_no:hover {
a:hover,.intro a.post_no:hover {
color: #ff0000;
}
@ -23,27 +23,27 @@ a.post_no {
padding: 0;
}
p.intro a.post_no {
.intro a.post_no {
color: inherit;
}
p.intro a.post_no,p.intro a.email,p.intro a.post_anchor {
.intro a.post_no,p.intro a.email,p.intro a.post_anchor {
margin: 0;
}
p.intro a.email span.name {
.intro a.email span.name {
color: #34345C;
}
p.intro a.email:hover span.name {
.intro a.email:hover span.name {
color: #ff0000;
}
p.intro label {
.intro label {
display: inline;
}
p.intro time,p.intro a.ip-link,p.intro a.capcode {
.intro time,p.intro a.ip-link,p.intro a.capcode {
direction: ltr;
unicode-bidi: embed;
}
@ -93,13 +93,17 @@ input[type="text"],input[type="password"],textarea {
text-shadow: none;
text-transform: none;
word-spacing: normal;
max-width: 75%;
max-width: 100%;
}
#quick-reply input[type="text"], input[type="password"], #quick-reply textarea {
max-width: 100%;
}
textarea {
width: 100%;
}
form table tr td {
text-align: left;
margin: 0;
@ -215,7 +219,7 @@ div.post.op hr {
border-color: #D9BFB7;
}
p.intro {
.intro {
margin: 0.5em 0;
padding: 0;
padding-bottom: 0.2em;
@ -226,22 +230,22 @@ input.delete {
margin: 1px 6px 0 0;
}
p.intro span.subject {
.intro span.subject {
color: #0F0C5D;
font-weight: bold;
}
p.intro span.name {
.intro span.name {
color: #117743;
font-weight: bold;
}
p.intro span.capcode,p.intro a.capcode,p.intro a.nametag {
.intro span.capcode,p.intro a.capcode,p.intro a.nametag {
color: #F00000;
margin-left: 0;
}
p.intro a {
.intro a {
margin-left: 8px;
}
@ -600,7 +604,7 @@ table.mod.config-editor input[type="text"] {
background-color: rgba(100%,100%,100%,0.2);
}
p.intro.thread-hidden {
.intro.thread-hidden {
margin: 0;
padding: 0;
}
@ -821,7 +825,7 @@ div.thread:hover {
#options_div {
width: 600px;
height: 300px;
height: 320px;
}
#alert_div {
@ -888,6 +892,7 @@ div.thread:hover {
right: 0px;
text-align: left;
font-size: 12px;
overflow-y: auto;
}
.options_tab h2 {
@ -926,7 +931,7 @@ span.pln {
@media screen and (min-width: 768px) {
p.intro {
.intro {
clear: none;
}
@ -959,3 +964,154 @@ span.pln {
cursor: pointer;
}
#youtube-size input {
width: 50px;
}
/* File selector */
.dropzone {
color: #000;
cursor: default;
margin: auto;
padding: 0px 4px;
text-align: center;
min-height: 50px;
max-height: 140px;
transition: 0.2s;
background-color: rgba(200, 200, 200, 0.5);
overflow-y: auto;
}
.dropzone-wrap {
width: 100%;
}
.dropzone .file-hint {
color: rgba(0, 0, 0, 0.5);
cursor: pointer;
position: relative;
margin-bottom: 5px;
padding: 10px 0px;
top: 5px;
transition: 0.2s;
border: 2px dashed rgba(125, 125, 125, 0.4);
}
.file-hint:hover, .dropzone.dragover .file-hint {
color: rgba(0, 0, 0, 1);
border-color: rgba(125, 125, 125, 0.8);
}
.dropzone.dragover {
background-color: rgba(200, 200, 200, 1);
}
.dropzone .file-thumbs {
text-align: left;
width: 100%;
}
.dropzone .tmb-container {
padding: 3px;
overflow-x: hidden;
white-space: nowrap;
}
.dropzone .file-tmb {
height: 40px;
width: 70px;
cursor: pointer;
display: inline-block;
text-align: center;
background-color: rgba(187, 187, 187, 0.5);
background-size: cover;
background-position: center;
}
.dropzone .file-tmb span {
font-weight: 600;
position: relative;
top: 13px;
}
.dropzone .tmb-filename {
display: inline-block;
vertical-align: bottom;
bottom: 12px;
position: relative;
margin-left: 5px;
}
.dropzone .remove-btn {
cursor: pointer;
color: rgba(125, 125, 125, 0.5);
display: inline-block;
vertical-align: bottom;
bottom: 10px;
position: relative;
margin-right: 5px;
font-size: 20px
}
.dropzone .remove-btn:hover {
color: rgba(125, 125, 125, 1);
}
#thread_stats {
display: inline;
margin-left: 10px;
margin-right: 10px;
}
/* Fileboard */
table.fileboard th, table.fileboard td {
padding: 2px;
text-align: center;
}
table.fileboard .intro a {
margin-left: 0px;
}
/* Gallery view */
#gallery_images {
position: absolute;
right: 0px;
bottom: 0px;
top: 0px;
width: 12%;
background-color: rgba(0, 0, 0, 0.4);
overflow: auto;
}
#gallery_toolbar {
position: absolute;
right: 12%;
left: 0px;
bottom: 0px;
height: 32px;
background-color: rgba(0, 0, 0, 0.4);
text-align: right;
}
#gallery_images img {
width: 100%;
}
#gallery_toolbar a {
font-size: 28px;
padding-right: 5px;
}
#gallery_main {
position: absolute;
left: 0px;
right: 12%;
bottom: 32px;
top: 0px;
padding: 10px;
}
#gallery_images img {
opacity: 0.6;
-webkit-transition: all 0.5s;
transition: all 0.5s;
}
#gallery_images img:hover, #gallery_images img.active {
opacity: 1;
}
#gallery_images img.active {
-webkit-box-shadow: 0px 0px 29px 2px rgba(255,255,255,1);
-moz-box-shadow: 0px 0px 29px 2px rgba(255,255,255,1);
box-shadow: 0px 0px 29px 2px rgba(255,255,255,1);
z-index: 1;
}
#gallery_main img, #gallery_main video {
max-width: 100%;
max-height: 100%;
position: absolute;
}

4
stylesheets/szalet.css

@ -20,7 +20,7 @@ background-repeat: repeat;
background-color: #200000;
}
p.intro span.capcode, p.intro a.capcode, p.intro a.nametag {
.intro span.capcode, p.intro a.capcode, p.intro a.nametag {
color: #26899C;
}
@ -154,7 +154,7 @@ div.banner, .replymode, .catalogmode {
font-weight:800;
}
p.intro span.subject {
.intro span.subject {
color: #771018;
font-weight: bold;
}

10
stylesheets/terminal2.css

@ -16,7 +16,7 @@ div.title, h1 {
div.title p {
font-size: 10px;
}
a:link, a:visited, p.intro a.email span.name {
a:link, a:visited, .intro a.email span.name {
color: #00FF00;
text-decoration: underline;
font-family: sans-serif;
@ -50,21 +50,21 @@ div.post.reply div.body a:link, div.post.reply div.body a:visited {
div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover {
color: #00FF00;
}
p.intro span.subject {
.intro span.subject {
font-size: 12px;
font-family: sans-serif;
color: #446655;
font-weight: 800;
}
p.intro span.name {
.intro span.name {
color: #00FF00;
font-weight: 800;
}
p.intro a.capcode, p.intro a.nametag {
.intro a.capcode, p.intro a.nametag {
color: #00FF00;
margin-left: 0;
}
p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name {
.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name {
color: #00FF00;
}
input[type="text"], textarea, select {

2
stylesheets/testorange.css

@ -202,7 +202,7 @@ div.boardlist.bottom {
background-color: rgba(0%, 0%, 0%, 0.45);
}
p.intro span.subject {
.intro span.subject {
color:#ee8100;
}

2
stylesheets/v8ch.css

@ -136,7 +136,7 @@ form table tr th{
background: #fec !important;
}
p.intro.thread-hidden{
.intro.thread-hidden{
padding-bottom: 1em !important;
}

18
stylesheets/wasabi.css

@ -27,16 +27,16 @@ a.post_no {
margin: 0;
padding: 0;
}
p.intro a.post_no, p.intro a.email {
.intro a.post_no, p.intro a.email {
margin: 0;
}
p.intro a.email span.name {
.intro a.email span.name {
color: #34345C;
}
p.intro a.email:hover span.name {
.intro a.email:hover span.name {
color: #ff0000;
}
p.intro label {
.intro label {
display: inline;
}
h2 {
@ -155,7 +155,7 @@ div.post.op {
div.post.op hr {
border-color: #D9BFB7;
}
p.intro {
.intro {
margin: 0.5em 0;
padding: 0;
padding-bottom: 0.2em;
@ -164,19 +164,19 @@ input.delete {
float: left;
margin: 1px 6px 0 0;
}
p.intro span.subject {
.intro span.subject {
color: #0F0C5D;
font-weight: bold;
}
p.intro span.name {
.intro span.name {
color: #117743;
font-weight: bold;
}
p.intro a.capcode, p.intro a.nametag {
.intro a.capcode, p.intro a.nametag {
color: #F00000;
margin-left: 0;
}
p.intro a {
.intro a {
margin-left: 8px;
}
div.delete {

4
stylesheets/yotsuba.css

@ -2,7 +2,7 @@ body {
background: #ffe url('img/fade-yotsuba.png') repeat-x 50% 0%;
color: #800000;
}
a:link, a:visited, p.intro a.email span.name {
a:link, a:visited, .intro a.email span.name {
color: #0000ff;
}
a:link:hover {
@ -22,7 +22,7 @@ div.post.reply.highlighted {
div.post.reply div.body a {
color: navy;
}
p.intro span.subject {
.intro span.subject {
color: #d00;
}
form table tr th {

15
templates/fileboard.html

@ -0,0 +1,15 @@
<table class='fileboard'>
<tr>
<th>&nbsp; <!-- checkbox -->
<th>{% trans %}No.{% endtrans %}
<th>{% trans %}Name{% endtrans %}
<th>{% trans %}File{% endtrans %}
<th>{% trans %}Tag{% endtrans %}
<th>{% trans %}Subject{% endtrans %}
<th>{% trans %}Size{% endtrans %}
<th>{% trans %}Date{% endtrans %}
<th>{% trans %}Replies{% endtrans %}
<th>&nbsp; <!-- reply -->
</tr>
{{ body }}
</table>

2
templates/generic_page.html

@ -39,7 +39,7 @@
<p class="unimportant" style="margin-top:20px;text-align:center;">- <a href="http://tinyboard.org/">Tinyboard</a> +
<a href='https://int.vichan.net/devel/'>vichan</a> {{ config.version }} -
<br><a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2014 Tinyboard Development Group
<br><a href="https://int.vichan.net/devel/">vichan</a> Copyright &copy; 2012-2014 vichan-devel</p>
<br><a href="https://engine.vichan.net/">vichan</a> Copyright &copy; 2012-2015 vichan-devel</p>
{% for footer in config.footer %}<p class="unimportant" style="text-align:center;">{{ footer }}</p>{% endfor %}
</footer>
<script type="text/javascript">{% raw %}

2
templates/index.html

@ -79,7 +79,7 @@
<p class="unimportant" style="margin-top:20px;text-align:center;">- <a href="http://tinyboard.org/">Tinyboard</a> +
<a href='https://int.vichan.net/devel/'>vichan</a> {{ config.version }} -
<br><a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2014 Tinyboard Development Group
<br><a href="https://int.vichan.net/devel/">vichan</a> Copyright &copy; 2012-2014 vichan-devel</p>
<br><a href="https://engine.vichan.net/">vichan</a> Copyright &copy; 2012-2015 vichan-devel</p>
{% for footer in config.footer %}<p class="unimportant" style="text-align:center;">{{ footer }}</p>{% endfor %}
</footer>

2
templates/main.js

@ -254,7 +254,7 @@ function dopost(form) {
saved[document.location] = form.elements['body'].value;
sessionStorage.body = JSON.stringify(saved);
return form.elements['body'].value != "" || form.elements['file'].value != "" || (form.elements.file_url && form.elements['file_url'].value != "");
return form.elements['body'].value != "" || (form.elements['file'] && form.elements['file'].value != "") || (form.elements.file_url && form.elements['file_url'].value != "");
}
function citeReply(id, with_link) {

4
templates/mod/dashboard.html

@ -155,9 +155,9 @@
<legend>Update</legend>
<ul>
<li>
A newer version of Tinyboard
A newer version of vichan
(<strong>v{{ newer_release.massive }}.{{ newer_release.major }}.{{ newer_release.minor }}</strong>) is available!
See <a href="http://tinyboard.org">http://tinyboard.org/</a> for upgrade instructions.
See <a href="https://engine.vichan.net">https://engine.vichan.net/</a> for upgrade instructions.
</li>
</ul>
</fieldset>

2
templates/mod/recent_posts.html

@ -11,7 +11,7 @@
{% else %}
{% set thread = post.thread %}
{% endif %}
<div class="post-wrapper" data-board="{{ post.board }}"><hr/><a class="eita-link" id="eita-{{ post.board }}-{{ thread }}" href="?/{{ post.board }}/res/{{ thread }}.html#{{ post.id }}">/{{ post.board }}/{{ post.id }}</a><br>
<div class="post-wrapper" data-board="{{ post.board }}"><hr/><a class="eita-link" id="eita-{{ post.board }}-{{ thread }}" href="?/{{ post.board }}/{{ config.dir.res }}{{ thread }}.html#{{ post.id }}">/{{ post.board }}/{{ post.id }}</a><br>
{{ post.built }}
</div>
{% endfor %}

2
templates/page.html

@ -25,7 +25,7 @@
<p class="unimportant" style="margin-top:20px;text-align:center;">- <a href="http://tinyboard.org/">Tinyboard</a> +
<a href='https://int.vichan.net/devel/'>vichan</a> {{ config.version }} -
<br><a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2014 Tinyboard Development Group
<br><a href="https://int.vichan.net/devel/">vichan</a> Copyright &copy; 2012-2014 vichan-devel</p>
<br><a href="https://engine.vichan.net/">vichan</a> Copyright &copy; 2012-2015 vichan-devel</p>
</footer>
</body>
</html>

6
templates/post/image.html

@ -1,16 +1,16 @@
<a href="
{% if post.file|extension == 'webm' %}
{% if post.file|extension == 'webm' or post.file|extension == 'mp4' %}
{{ config.root }}player.php?v={{ config.uri_img }}{{ post.file }}&amp;t={{ post.filename|e('url') }}&amp;loop=1
{% else %}
{{ config.uri_img }}{{ post.file }}
{% endif %}
"
target="_blank"
{% if post.thumb == 'file' or post.modifiers['is_file'] == '1' or post.filename|extension == 'webm' %}
{% if post.thumb == 'file' or post.modifiers['is_file'] == '1' or post.filename|extension == 'webm' or post.file|extension == 'mp4' %}
class="file"
{% endif %}
>
{% if post.thumb|extension == 'webm' %}
{% if post.thumb|extension == 'webm' or post.thumb|extension == 'mp4' %}
<video autoplay class="post-image" src="{{ config.uri_thumb }}{{ post.thumb }}"
poster="
{{ config.root }}

2
templates/post/image_identification.html

@ -8,7 +8,7 @@
<a href="http://regex.info/exif.cgi?url={{ config.domain }}{{ config.uri_img }}{{ file.file }}" target="_blank">Exif</a>
{% endif %}
{% if config.image_identification_google %}
<a href="https://www.google.com/searchbyimage?image_url={{ config.domain }}{{ config.uri_img }}{{ file.file }}" target="_blank">Google</a>
<a href="https://www.google.com/searchbyimage?image_url={{ config.domain|url_encode }}{{ config.uri_img|url_encode }}{{ file.file|url_encode }}" target="_blank">Google</a>
{% endif %}
{% if config.image_identification_iqdb %}
<a href="http://iqdb.org/?url={{ config.domain }}{{ config.uri_img }}{{ file.file }}" target="_blank">iqdb</a>

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

Loading…
Cancel
Save