summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore19
-rwxr-xr-x403.php17
-rwxr-xr-x404.php32
-rw-r--r--README.md49
-rwxr-xr-xb.php47
-rw-r--r--banned.php19
-rw-r--r--banners.php22
-rw-r--r--banners/lain-bottom.pngbin0 -> 118244 bytes
-rwxr-xr-xbg.php20
-rwxr-xr-xc.php20
-rw-r--r--favicon.pngbin0 -> 18511 bytes
-rw-r--r--inc/bans.php12
-rw-r--r--inc/config.php5
-rw-r--r--inc/error.php91
-rwxr-xr-xinc/functions.php74
-rw-r--r--inc/instance-config.php23
-rw-r--r--inc/mod/pages.php33
-rw-r--r--install.php5
-rw-r--r--js/ajax.js2
-rw-r--r--js/auto-reload.js376
-rw-r--r--js/catalog-link.js72
-rw-r--r--js/catalog-search.js93
-rw-r--r--js/hilight.js12
-rw-r--r--js/mute-images.js48
-rw-r--r--js/options.js10
-rwxr-xr-xjs/piwik.js12
-rw-r--r--js/post-hover.js6
-rw-r--r--js/prettify.js1655
-rw-r--r--js/quick-post-controls.js16
-rw-r--r--js/quick-reply.js3
-rw-r--r--js/rules-popup.js44
-rw-r--r--js/style-select.js10
-rw-r--r--js/thread-stats.js17
m---------js/wPaint0
l---------lam1
l---------layer031
-rw-r--r--mod.php6
-rw-r--r--post.php52
-rw-r--r--robots.txt2
-rw-r--r--static/.gitignore33
-rw-r--r--static/403.jpgbin0 -> 44607 bytes
-rw-r--r--static/btc.jpgbin0 -> 37349 bytes
-rw-r--r--static/congrats.swfbin0 -> 213269 bytes
-rw-r--r--static/cyberia.oggbin0 -> 9368298 bytes
-rw-r--r--static/duvet.mp3bin0 -> 8168104 bytes
-rw-r--r--static/duvet.oggbin0 -> 8393856 bytes
-rwxr-xr-xstatic/html.pngbin0 -> 867 bytes
-rw-r--r--static/lain.mp3.m3u1
-rw-r--r--static/lain.ogg.m3u1
-rw-r--r--static/lain_2_090.jpgbin0 -> 44217 bytes
-rw-r--r--static/lain_epup.jpgbin0 -> 13403 bytes
-rw-r--r--static/lain_is_cute_datass_small.pngbin0 -> 129614 bytes
-rw-r--r--static/lain_is_cute_datass_small_teal.pngbin0 -> 129614 bytes
-rwxr-xr-xstatic/nginx.pngbin0 -> 604 bytes
-rw-r--r--static/partyhat.gifbin0 -> 895 bytes
-rw-r--r--static/pdf.jpgbin0 -> 13001 bytes
-rw-r--r--static/slack_for_ios_upload.jpgbin0 -> 1829277 bytes
-rwxr-xr-xstatic/ssl.pngbin0 -> 589 bytes
-rw-r--r--static/system.gifbin0 -> 490484 bytes
-rwxr-xr-xstatic/ubuntu.pngbin0 -> 1007 bytes
-rw-r--r--static/warning.pngbin673 -> 0 bytes
-rw-r--r--static/zine_ipad.pngbin0 -> 404306 bytes
-rw-r--r--stylesheets/500px.css372
-rw-r--r--stylesheets/8ch.cyber.css469
-rw-r--r--stylesheets/beta.css381
-rw-r--r--stylesheets/birthday.css21
-rwxr-xr-xstylesheets/code/dark.css141
-rwxr-xr-xstylesheets/code/light.css141
-rw-r--r--stylesheets/cupcake.css96
-rw-r--r--stylesheets/cyberpunk.css264
-rw-r--r--stylesheets/cyberpunk2.css241
-rw-r--r--stylesheets/dark.css76
-rw-r--r--stylesheets/dark_irc.css16
-rw-r--r--stylesheets/dark_purple.css21
-rw-r--r--stylesheets/dark_red.css21
-rw-r--r--stylesheets/darkroot_garden.css259
-rw-r--r--stylesheets/dicksinmyass.css80
-rw-r--r--stylesheets/fauux.css215
-rw-r--r--stylesheets/ferus.css46
-rw-r--r--stylesheets/fonts/DejaVuSans-Bold.ttfbin0 -> 693876 bytes
-rw-r--r--stylesheets/fonts/DejaVuSans-BoldOblique.ttfbin0 -> 632168 bytes
-rw-r--r--stylesheets/fonts/DejaVuSans-ExtraLight.ttfbin0 -> 352492 bytes
-rw-r--r--stylesheets/fonts/DejaVuSans-Oblique.ttfbin0 -> 632416 bytes
-rw-r--r--stylesheets/fonts/DejaVuSans.ttfbin0 -> 741536 bytes
-rw-r--r--stylesheets/fonts/DejaVuSansCondensed-Bold.ttfbin0 -> 653336 bytes
-rw-r--r--stylesheets/fonts/DejaVuSansCondensed-BoldOblique.ttfbin0 -> 600936 bytes
-rw-r--r--stylesheets/fonts/DejaVuSansCondensed-Oblique.ttfbin0 -> 596596 bytes
-rw-r--r--stylesheets/fonts/DejaVuSansCondensed.ttfbin0 -> 664972 bytes
-rw-r--r--stylesheets/fonts/DejaVuSansMono-Bold.ttfbin0 -> 318392 bytes
-rw-r--r--stylesheets/fonts/DejaVuSansMono-BoldOblique.ttfbin0 -> 239876 bytes
-rw-r--r--stylesheets/fonts/DejaVuSansMono-Oblique.ttfbin0 -> 245948 bytes
-rw-r--r--stylesheets/fonts/DejaVuSansMono.ttfbin0 -> 335068 bytes
-rw-r--r--stylesheets/fonts/DejaVuSerif-Bold.ttfbin0 -> 345364 bytes
-rw-r--r--stylesheets/fonts/DejaVuSerif-BoldItalic.ttfbin0 -> 336884 bytes
-rw-r--r--stylesheets/fonts/DejaVuSerif-Italic.ttfbin0 -> 343388 bytes
-rw-r--r--stylesheets/fonts/DejaVuSerif.ttfbin0 -> 367260 bytes
-rw-r--r--stylesheets/fonts/DejaVuSerifCondensed-Bold.ttfbin0 -> 320720 bytes
-rw-r--r--stylesheets/fonts/DejaVuSerifCondensed-BoldItalic.ttfbin0 -> 335940 bytes
-rw-r--r--stylesheets/fonts/DejaVuSerifCondensed-Italic.ttfbin0 -> 342736 bytes
-rw-r--r--stylesheets/fonts/DejaVuSerifCondensed.ttfbin0 -> 334040 bytes
-rw-r--r--stylesheets/fonts/DroidSans-Bold.ttfbin0 -> 191032 bytes
-rw-r--r--stylesheets/fonts/DroidSans.ttfbin0 -> 190044 bytes
-rwxr-xr-xstylesheets/fonts/Fujiyama.rarbin0 -> 206077 bytes
-rwxr-xr-xstylesheets/fonts/Fujiyama.ttfbin0 -> 27840 bytes
-rwxr-xr-xstylesheets/fonts/Fujiyama2.ttfbin0 -> 36416 bytes
-rwxr-xr-xstylesheets/fonts/Fujiyama2_Plain.ttfbin0 -> 34232 bytes
-rwxr-xr-xstylesheets/fonts/FujiyamaExtraBold_Italic.ttfbin0 -> 37596 bytes
-rwxr-xr-xstylesheets/fonts/FujiyamaExtraBold_Plain.ttfbin0 -> 33640 bytes
-rwxr-xr-xstylesheets/fonts/FujiyamaLight_Plain.ttfbin0 -> 34692 bytes
-rwxr-xr-xstylesheets/fonts/Fujiyama_Bold_Italic.ttfbin0 -> 28500 bytes
-rwxr-xr-xstylesheets/fonts/Fujiyama_ExtraBold-Normal.ttfbin0 -> 29384 bytes
-rwxr-xr-xstylesheets/fonts/Fujiyama_Plain.ttfbin0 -> 34764 bytes
-rwxr-xr-xstylesheets/fonts/Futura_PT.rar1
-rw-r--r--stylesheets/fonts/OpenSans-Light-webfont.eotbin0 -> 19084 bytes
-rw-r--r--stylesheets/fonts/OpenSans-Light-webfont.svg252
-rw-r--r--stylesheets/fonts/OpenSans-Light-webfont.ttfbin0 -> 41540 bytes
-rw-r--r--stylesheets/fonts/OpenSans-Light-webfont.woffbin0 -> 22604 bytes
-rwxr-xr-xstylesheets/fonts/TR_Fujiyama_Bold.ttfbin0 -> 49764 bytes
-rwxr-xr-xstylesheets/fonts/lain.TTFbin0 -> 57604 bytes
-rwxr-xr-xstylesheets/fonts/nrdyyh.woffbin0 -> 37536 bytes
-rwxr-xr-xstylesheets/fonts/vt220.ttfbin0 -> 88228 bytes
-rw-r--r--stylesheets/forest.css259
-rw-r--r--stylesheets/heavy_ice.css384
-rwxr-xr-xstylesheets/img/7.gifbin0 -> 939026 bytes
-rwxr-xr-xstylesheets/img/banner_terminal_mask.pngbin0 -> 466 bytes
-rwxr-xr-xstylesheets/img/idx2.gifbin0 -> 4224 bytes
-rw-r--r--stylesheets/img/matrix.jpgbin0 -> 26527 bytes
-rw-r--r--stylesheets/img/matrix_yellow.gifbin0 -> 135452 bytes
-rw-r--r--stylesheets/jungle.css11
-rw-r--r--stylesheets/kalyx_theme.css303
-rw-r--r--stylesheets/miku.css13
-rw-r--r--stylesheets/mono.e.lain.css364
-rw-r--r--stylesheets/new_test.css559
-rw-r--r--stylesheets/poison.css97
-rw-r--r--stylesheets/recent.css190
-rw-r--r--stylesheets/style.css985
-rwxr-xr-xstylesheets/svg/bannermaks.svg12
-rwxr-xr-xstylesheets/svg/blur.svg73
-rwxr-xr-xstylesheets/svg/shadow.svg11
-rwxr-xr-xstylesheets/svg/terminal.svg10
-rw-r--r--stylesheets/terminal2.css16
-rw-r--r--stylesheets/terminal_common.css153
-rw-r--r--stylesheets/terminal_green.css49
-rw-r--r--stylesheets/terminal_purple.css65
-rw-r--r--stylesheets/volafile.css96
-rw-r--r--stylesheets/yotsuba.css12
-rw-r--r--templates/badges.html4
-rw-r--r--templates/banned.html1
-rw-r--r--templates/boardlist.html1
-rw-r--r--templates/generic_page.html2
-rw-r--r--templates/header.html1
-rw-r--r--templates/index.html43
-rwxr-xr-x[-rw-r--r--]templates/main.js22
-rw-r--r--templates/mod/ban_form.html3
-rw-r--r--templates/mod/config-editor-php.html6
-rw-r--r--templates/mod/confirm.html2
-rw-r--r--templates/mod/dashboard.html131
-rw-r--r--templates/notbanned.html7
-rw-r--r--templates/page.html2
-rw-r--r--templates/post/fileinfo.html2
-rw-r--r--templates/post/image_identification.html2
-rw-r--r--templates/post/post_controls.html10
-rw-r--r--templates/post_form.html15
-rw-r--r--templates/post_reply.html45
-rwxr-xr-x[-rw-r--r--]templates/posts.sql0
-rw-r--r--templates/rules.html33
-rw-r--r--templates/themes/basic/index.html11
-rw-r--r--templates/themes/catalog/catalog.html51
-rw-r--r--templates/themes/catalog/info.php45
-rw-r--r--templates/themes/catalog/theme.php224
-rw-r--r--templates/themes/categories-uboachan/info.php42
-rw-r--r--templates/themes/categories-uboachan/theme.php223
-rw-r--r--templates/themes/categories-uboachan/thumb.pngbin0 -> 9965 bytes
-rw-r--r--templates/themes/donate/donate.html208
-rw-r--r--templates/themes/donate/info.php23
-rw-r--r--templates/themes/donate/theme.php28
-rw-r--r--templates/themes/donate/thumb.pngbin0 -> 9098 bytes
-rw-r--r--templates/themes/irc/info.php23
-rw-r--r--templates/themes/irc/irc.html30
-rw-r--r--templates/themes/irc/radio.html29
-rw-r--r--templates/themes/irc/theme.php27
-rw-r--r--templates/themes/irc/thumb.pngbin0 -> 10730 bytes
-rw-r--r--templates/themes/public_banlist/theme.php2
-rw-r--r--templates/themes/radio/info.php23
-rw-r--r--templates/themes/radio/radio.html76
-rw-r--r--templates/themes/radio/theme.php27
-rw-r--r--templates/themes/radio/thumb.pngbin0 -> 10730 bytes
-rw-r--r--templates/themes/rand/info.php54
-rw-r--r--templates/themes/rand/rand.js116
-rw-r--r--templates/themes/rand/theme.php105
-rw-r--r--templates/themes/rand/thumb.pngbin0 -> 13085 bytes
-rw-r--r--templates/themes/recent/cyberpunk_recent.css124
-rw-r--r--templates/themes/recent/recent.css154
-rw-r--r--templates/themes/recent/recent.html40
-rw-r--r--templates/themes/recent/recent_dark.css72
-rwxr-xr-xtemplates/themes/rules/info.php23
-rwxr-xr-xtemplates/themes/rules/rules.html38
-rwxr-xr-xtemplates/themes/rules/theme.php28
-rwxr-xr-xtemplates/themes/rules/thumb.pngbin0 -> 19899 bytes
-rw-r--r--templates/themes/semirand/info.php70
-rw-r--r--templates/themes/semirand/semirand.js158
-rw-r--r--templates/themes/semirand/theme.php255
-rw-r--r--templates/themes/semirand/thumb.pngbin0 -> 13085 bytes
-rw-r--r--templates/themes/ukko/theme.php2
-rw-r--r--templates/themes/zine/info.php23
-rw-r--r--templates/themes/zine/theme.php28
-rw-r--r--templates/themes/zine/thumb.pngbin0 -> 9098 bytes
-rwxr-xr-xtemplates/themes/zine/zine.html69
-rw-r--r--templates/thread.html35
-rw-r--r--walls/1426962866730.pngbin0 -> 2725061 bytes
-rw-r--r--walls/1426963001770-1.jpgbin0 -> 840771 bytes
-rw-r--r--walls/1426966616071-1.jpgbin0 -> 387702 bytes
-rw-r--r--walls/1426966728834-1.jpgbin0 -> 535648 bytes
-rw-r--r--walls/1427001458818-1.jpgbin0 -> 346652 bytes
-rw-r--r--walls/1427003079773-1.jpgbin0 -> 271017 bytes
-rw-r--r--walls/1427003222547-1.jpgbin0 -> 616651 bytes
-rw-r--r--walls/1427007090570.jpgbin0 -> 329484 bytes
-rw-r--r--walls/1427010911673-1.jpgbin0 -> 366257 bytes
-rw-r--r--walls/1427029908812-0.jpgbin0 -> 357359 bytes
-rw-r--r--walls/1427029908812-1.jpgbin0 -> 868436 bytes
-rw-r--r--walls/1427029908812-2.jpgbin0 -> 1172057 bytes
-rw-r--r--walls/1427030144598-1.jpgbin0 -> 255016 bytes
-rw-r--r--walls/1427030144598-2.jpgbin0 -> 470444 bytes
-rw-r--r--walls/1427032003105-0.jpgbin0 -> 2374599 bytes
-rw-r--r--walls/1427032212051-2.jpgbin0 -> 765691 bytes
-rw-r--r--walls/1427067866355.jpgbin0 -> 765660 bytes
l---------weeb1
227 files changed, 11717 insertions, 838 deletions
diff --git a/.gitignore b/.gitignore
index 281515e9..f03e1a4a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@
/*/thumb
/*/config.php
/*.html
+/*.xml
# include some files though
!/templates/*.html
@@ -37,6 +38,7 @@ Thumbs.db
*.rej
*.orig
*~
+~*/
# tmp filesystem
/tmp/cache/*
@@ -47,3 +49,20 @@ Thumbs.db
#vichan custom
favicon.ico
/static/spoiler.png
+
+piwik/
+jwplayer/
+tf/
+
+# vim swapfiles
+[._]*.s[a-w][a-z]
+[._]s[a-w][a-z]
+
+# special boards
+all/
+mod/
+random/
+
+# Banners
+banners/*
+!banners/lain-bottom.png
diff --git a/403.php b/403.php
new file mode 100755
index 00000000..db92b593
--- /dev/null
+++ b/403.php
@@ -0,0 +1,17 @@
+<title>403</title>
+</head>
+<!-- <body style="background: black"> -->
+<body style="background-image:url(/static/system.gif)">
+<center><img height=480 width=640 src="/static/403.jpg"/>
+<marquee scrollamount="40"><h1><p style="font-family: sans-serif; font-size:30px; color: black;">WHOOPS</p></h1></marquee>
+<p style="color: blue;background:black">this isn't for you</p>
+<p style="color: red;background:black">it's a 403</p>
+<br /> <br />
+<param name="movie" value="/static/congrats.swf">
+</center>
+<audio autoplay loop>
+<source src="/static/cyberia.ogg" />
+</audio>
+</body>
+</html>
+
diff --git a/404.php b/404.php
new file mode 100755
index 00000000..45f12e2f
--- /dev/null
+++ b/404.php
@@ -0,0 +1,32 @@
+<title>404</title>
+<style type="text/css">
+body {
+ margin: 0 !important;
+ padding: 0px !important;
+ overflow-x:hidden!important;
+ background-size: cover !important;
+ background-color: #222 !important;
+ background-image:
+ url(https://gs1.wac.edgecastcdn.net/8019B6/data.tumblr.com/tumblr_mc0xu6C22f1qbj9bko1_500.gif);
+ background-repeat: no-repeat !important;
+ background-position: 0!important;
+ background-attachment: fixed !important;
+ background-size: cover !important;
+}
+</style>
+</head>
+
+<body>
+<center><!--<img src="/static/lain_2_090.jpg"/>-->
+<marquee scrollamount="40"><h1><p style="font-family: sans-serif; font-size:30px; color: white;">WHOOPS</p></h1></marquee>
+<p style="color: blue;background:black">There's nothing here</p>
+<p style="color: red;background:black">it's a 404</p>
+<br /> <br />
+<audio autoplay loop>
+<source src="/static/duvet.ogg" type="audio/ogg" />
+<source src="/static/duvet.mp3" type="audio/mpeg" />
+</audio>
+</center>
+</body>
+</html>
+
diff --git a/README.md b/README.md
index 6e153ab7..768714c5 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,12 @@
-vichan - A lightweight and full featured PHP imageboard.
+Lainchan - A fork of vichan
========================================================
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 (now defunc'd) [Tinyboard](http://github.com/savetheinternet/Tinyboard),
+Lainchan is a fork of [vichan](http://github.com/vichan-devel/vichan),
a great imageboard package, actively building on it and adding a lot of features and other
improvements.
-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)
@@ -21,8 +16,8 @@ Requirements
4. [PHP GD](http://www.php.net/manual/en/intro.image.php)
5. [PHP PDO](http://www.php.net/manual/en/intro.pdo.php)
-We try to make sure vichan is compatible with all major web servers and
-operating systems. vichan does not include an Apache ```.htaccess``` file nor does
+We try to make sure lainchan is compatible with all major web servers and
+operating systems. lainchan does not include an Apache ```.htaccess``` file nor does
it need one.
### Recommended
@@ -34,23 +29,25 @@ it need one.
Contributing
------------
-You can contribute to vichan by:
+You can contribute to lainchan by:
* Developing patches/improvements/translations and using GitHub to submit pull requests
* Providing feedback and suggestions
* Writing/editing documentation
-If you need help developing a patch, please join our IRC channel.
+If you need help developing a patch, please join our IRC channel.
+
+> irc.freenode.net @ #lainchan-dev
Installation
-------------
-1. Download and extract vichan to your web directory or get the latest
+1. Download and extract lainchan to your web directory or get the latest
development version with:
- git clone git://github.com/vichan-devel/vichan.git
+ git clone git://github.com/lainchan/lainchan.git
2. Navigate to ```install.php``` in your web browser and follow the
prompts.
-3. vichan should now be installed. Log in to ```mod.php``` with the
+3. lainchan should now be installed. Log in to ```mod.php``` with the
default username and password combination: **admin / password**.
Please remember to change the administrator account password.
@@ -70,20 +67,18 @@ To migrate from a Kusaba X board, use http://github.com/vichan-devel/Tinyboard-M
Support
--------
-vichan is still beta software -- there are bound to be bugs. If you find a
-bug, please report it.
+If you find a bug, please report it.
-If you need assistance with installing, configuring, or using vichan, you may
+If you need assistance with installing, configuring, or using lainchan, you may
find support from a variety of sources:
* If you're unsure about how to enable or configure certain features, make
sure you have read the comments in ```inc/config.php```.
-* Check out an [official vichan board](http://int.vichan.net/devel/).
-* You can join vichan's IRC channel for support
- [irc.6irc.net #vichan-devel](irc://irc.6irc.net/vichan-devel)
+* You can join lainchan's IRC channel for support
+ [irc.freenode.net #lainchan](irc://irc.freenode.net/lainchan)
### Tinyboard support
-vichan is based on a Tinyboard, so both engines have very much in common. These
+vichan, and by extension lainchan, 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](https://web.archive.org/web/20121016074303/http://tinyboard.org/docs/?p=Main_Page).
@@ -91,7 +86,7 @@ links may be helpful for you as well:
Donations
---------
Do you like our work? You can motivate us financially to do better ;)
-* Bitcoin: 1GjZEdLaTQ8JWVFGZW921Yv4x59f9oiZME
+* Bitcoin: 18CshTkxW6HRFoBhXo9mLJcjkReMmjvuq9
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
@@ -109,13 +104,13 @@ at the power users. You won't be able to run these from shared hosting accounts
Localisation
------------
-Wanting to have vichan in your language? You can contribute your translations at this URL:
+Wanting to have lainchan in your language? You can contribute your translations to vichan at this URL:
https://www.transifex.com/projects/p/tinyboard-vichan-devel/
Oekaki
------
-vichan makes use of [wPaint](https://github.com/websanova/wPaint) for oekaki. After you pull the repository, however, you will need to download wPaint separately using git's `submodule` feature. Use the following commands:
+lainchan makes use of [wPaint](https://github.com/websanova/wPaint) for oekaki. After you pull the repository, however, you will need to download wPaint separately using git's `submodule` feature. Use the following commands:
```
git submodule init
@@ -128,12 +123,12 @@ WebM support
------------
Read `inc/lib/webm/README.md` for information about enabling webm.
-vichan API
+lainchan API
----------
-vichan provides by default a 4chan-compatible JSON API. For documentation on this, see:
+lainchan provides by default a 4chan-compatible JSON API, just like vichan. For documentation on this, see:
https://github.com/vichan-devel/vichan-API/ .
License
--------
-See [LICENSE.md](http://github.com/vichan-devel/vichan/blob/master/LICENSE.md).
+See [LICENSE.md](http://github.com/lainchan/lainchan/blob/master/LICENSE.md).
diff --git a/b.php b/b.php
new file mode 100755
index 00000000..a0638ec3
--- /dev/null
+++ b/b.php
@@ -0,0 +1,47 @@
+<?php
+// This script assumes there is at least one normal (non-priority)
+// banner!
+
+// Get the files in a directory, returns null if the directory does
+// not exist.
+function getFilesInDirectory($dir) {
+ if (! is_dir($dir)) {
+ return null;
+ }
+
+ return array_diff(scandir($dir), array('.', '..'));
+}
+
+// Serve a random banner and exit.
+function serveRandomBanner($dir, $files) {
+ $name = $files[array_rand($files)];
+
+ // snags the extension
+ $ext = pathinfo($name, PATHINFO_EXTENSION);
+
+ // send the right headers
+ header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1
+ header('Pragma: no-cache'); // HTTP 1.0
+ header('Expires: 0'); // Proxies
+ header("Content-type: image/" . $ext);
+ header("Content-Disposition: inline; filename=" . $name);
+
+ // readfile displays the image, passthru seems to spits stream.
+ readfile($dir.$name);
+ exit;
+}
+
+// Get all the banners
+$bannerDir = "banners/";
+$priorityDir = "banners_priority/";
+
+$banners = getFilesInDirectory($bannerDir);
+$priority = getFilesInDirectory($priorityDir);
+
+// If there are priority banners, serve 1/3rd of the time.
+if($priority !== null && count($priority) !== 0 && rand(0,2) === 0) {
+ serveRandomBanner($priorityDir, $priority);
+}
+
+serveRandomBanner($bannerDir, $banners);
+?>
diff --git a/banned.php b/banned.php
index 1bee9115..a38b87c4 100644
--- a/banned.php
+++ b/banned.php
@@ -1,8 +1,15 @@
<?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>";
- print "</body></html>";
+ require_once 'inc/functions.php';
+ require_once 'inc/bans.php';
+ checkBan();
+
+ //If the user is not banned, show the "not banned" page.
+ die(
+ Element('page.html', array(
+ 'title' => _('Not banned!'),
+ 'config' => $config,
+ 'nojavascript' => true,
+ 'body' => Element('notbanned.html', array()
+ ))
+ ));
?>
diff --git a/banners.php b/banners.php
new file mode 100644
index 00000000..48e312f2
--- /dev/null
+++ b/banners.php
@@ -0,0 +1,22 @@
+<html>
+<head>
+<title>Lainchan Banners</title>
+</head>
+<body>
+<?php
+function listBannersInDir($dir) {
+ if ($handle = opendir($dir)) {
+ while (false !== ($entry = readdir($handle))) {
+ if ($entry != "." && $entry != "..") {
+ echo "<a href=\"$dir/$entry\"><img src=\"$dir/$entry\" alt=\"$entry\" style=\"width:348px;height:128px\"></a> ";
+ }
+ }
+ closedir($handle);
+ }
+}
+
+listBannersInDir("banners_priority");
+listBannersInDir("banners");
+?>
+</body>
+</html>
diff --git a/banners/lain-bottom.png b/banners/lain-bottom.png
new file mode 100644
index 00000000..2f271c54
--- /dev/null
+++ b/banners/lain-bottom.png
Binary files differ
diff --git a/bg.php b/bg.php
new file mode 100755
index 00000000..bb0b9d88
--- /dev/null
+++ b/bg.php
@@ -0,0 +1,20 @@
+<?php
+//renaming to bg.php
+$dir = "walls/";
+$files = scandir($dir);
+$images = array_diff($files, array('.', '..'));
+$name = $images[array_rand($images)];
+// open the file in a binary mode
+$fp = fopen($dir . $name, 'rb');
+
+// send the right headers
+header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1
+header('Pragma: no-cache'); // HTTP 1.0
+header('Expires: 0'); // Proxies
+header('Content-Type: ' . $fp['type']);
+header('Content-Length: ' . $fp['bytes']);
+
+// dump the picture and stop the script
+fpassthru($fp);
+exit;
+?>
diff --git a/c.php b/c.php
new file mode 100755
index 00000000..00c23180
--- /dev/null
+++ b/c.php
@@ -0,0 +1,20 @@
+<?php
+$dir = "banners/";
+$files = scandir($dir);
+$images = array_diff($files, array('.', '..'));
+$name = $images[array_rand($images)];
+$fp = fopen($dir . $name, 'rb');
+
+// send the right headers
+header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1
+header('Pragma: no-cache'); // HTTP 1.0
+header('Expires: 0'); // Proxies
+header('Content-Type: ' . $fp['type']);
+header('Content-Length: ' . $fp['bytes']);
+
+// dump the picture and stop the script
+//fpassthru($fp);
+print($fp['type']);
+print('dicks');
+exit;
+?>
diff --git a/favicon.png b/favicon.png
new file mode 100644
index 00000000..8028966e
--- /dev/null
+++ b/favicon.png
Binary files differ
diff --git a/inc/bans.php b/inc/bans.php
index c468eb64..7a514f04 100644
--- a/inc/bans.php
+++ b/inc/bans.php
@@ -149,7 +149,7 @@ class Bans {
return $ban_list;
}
- static public function stream_json($out = false, $filter_ips = false, $filter_staff = false, $board_access = false) {
+ static public function stream_json($out = false, $filter_ips = false, $filter_staff = false, $board_access = false, $hide_regexes = []) {
$query = query("SELECT ``bans``.*, `username` FROM ``bans``
LEFT JOIN ``mods`` ON ``mods``.`id` = `creator`
ORDER BY `created` DESC") or error(db_error());
@@ -164,7 +164,15 @@ class Bans {
foreach ($bans as &$ban) {
$ban['mask'] = self::range_to_string(array($ban['ipstart'], $ban['ipend']));
- if ($ban['post']) {
+ $hide_message = false;
+ foreach ($hide_regexes as $regex) {
+ if(preg_match($regex, $ban['reason'])) {
+ $hide_message = true;
+ break;
+ }
+ }
+
+ if ($ban['post'] && !$hide_message) {
$post = json_decode($ban['post']);
$ban['message'] = isset($post->body) ? $post->body : 0;
}
diff --git a/inc/config.php b/inc/config.php
index bfb774a8..dc65068f 100644
--- a/inc/config.php
+++ b/inc/config.php
@@ -1810,6 +1810,11 @@
'<img style="width:360px;height:270px;" src="//img.youtube.com/vi/$2/0.jpg" class="post-image"/>'.
'</a></div>';
+ // Slack Report Notification
+ $config['slack'] = true;
+ $config['slack_channel'] = "reports";
+ $config['slack_incoming_webhook_endpoint'] = "https://hooks.slack.com/services/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";
+
// Password hashing function
//
// $5$ <- SHA256
diff --git a/inc/error.php b/inc/error.php
new file mode 100644
index 00000000..da707911
--- /dev/null
+++ b/inc/error.php
@@ -0,0 +1,91 @@
+<?PHP
+
+function error_handler($errno,$errstr,$errfile, $errline, $errcontext){
+ if(error_reporting() & $errno){
+ $config['debug']=true;
+ error($errstr . ' in ' . $errfile . ' at line ' . $errline);
+ }
+ return false;
+}
+
+function exception_handler(Exception $e){
+ error($e->getMessage());
+}
+
+set_exception_handler('exception_handler');
+
+function fatal_error_handler(){
+ if (($error = error_get_last()) && $error['type'] == E_ERROR) {
+ error('Caught fatal error: ' . $error['message'] . ' in ' . $error['file'] . ' at line ' . $error['line']);
+ }
+}
+
+register_shutdown_function('fatal_error_handler');
+
+$error_recursion=false;
+
+function error($message, $priority = true, $debug_stuff = false) {
+ global $board, $mod, $config, $db_error, $error_recursion;
+
+ if($error_recursion!==false){
+ die("Error recursion detected with " . $message . "<br>Original error:".$error_recursion);
+ }
+
+ $error_recursion=$message;
+
+ if (defined('STDIN')) {
+ // Running from CLI
+ echo('Error: ' . $message . "\n");
+ debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
+ die();
+ }
+
+ if(!empty($config)){
+
+ if ($config['syslog'] && $priority !== false) {
+ // Use LOG_NOTICE instead of LOG_ERR or LOG_WARNING because most error message are not significant.
+ _syslog($priority !== true ? $priority : LOG_NOTICE, $message);
+ }
+
+ if ($config['debug']) {
+ $debug_stuff=array();
+ if(isset($db_error)){
+ $debug_stuff = array_combine(array('SQLSTATE', 'Error code', 'Error message'), $db_error);
+ }
+ $debug_stuff['backtrace'] = debug_backtrace();
+ $pw = $config['db']['password'];
+ $debug_callback = function(&$item) use (&$debug_callback, $pw) {
+ if (is_array($item)) {
+ return array_map($debug_callback, $item);
+ }
+ return ($item == $pw ? 'hunter2' : $item);
+ };
+ $debug_stuff = array_map($debug_callback, $debug_stuff);
+ }
+ }
+
+ if (isset($_POST['json_response'])) {
+ header('Content-Type: text/json; charset=utf-8');
+ $data=array('error'=>$message);
+ if(!empty($config) && $config['debug']){
+ $data['debug']=$debug_stuff;
+ }
+ print json_encode($data);
+ exit();
+ }
+
+ header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error');
+
+ die(Element('page.html', array(
+ 'config' => $config,
+ 'title' => _('Error'),
+ 'subtitle' => _('An error has occured.'),
+ 'body' => Element('error.html', array(
+ 'config' => $config,
+ 'message' => $message,
+ 'mod' => $mod,
+ 'board' => isset($board) ? $board : false,
+ 'debug' => str_replace("\n", '&#10;', utf8tohtml(print_r($debug_stuff, true)))
+ ))
+ )));
+}
diff --git a/inc/functions.php b/inc/functions.php
index 1b336e12..86efe789 100755
--- a/inc/functions.php
+++ b/inc/functions.php
@@ -12,7 +12,8 @@ if (realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) {
define('TINYBOARD', null);
$microtime_start = microtime(true);
-
+require_once 'inc/error.php';
+require_once 'inc/cache.php';
require_once 'inc/display.php';
require_once 'inc/template.php';
require_once 'inc/database.php';
@@ -31,11 +32,10 @@ if (!extension_loaded('gettext')) {
// the user is not currently logged in as a moderator
$mod = false;
-register_shutdown_function('fatal_error_handler');
mb_internal_encoding('UTF-8');
loadConfig();
-function init_locale($locale, $error='error') {
+function init_locale($locale) {
if (extension_loaded('gettext')) {
if (setlocale(LC_ALL, $locale) === false) {
//$error('The specified locale (' . $locale . ') does not exist on your platform!');
@@ -45,7 +45,7 @@ function init_locale($locale, $error='error') {
textdomain('tinyboard');
} else {
if (_setlocale(LC_ALL, $locale) === false) {
- $error('The specified locale (' . $locale . ') does not exist on your platform!');
+ error('The specified locale (' . $locale . ') does not exist on your platform!');
}
_bindtextdomain('tinyboard', './inc/locale');
_bind_textdomain_codeset('tinyboard', 'UTF-8');
@@ -58,8 +58,6 @@ $current_locale = 'en';
function loadConfig() {
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';
-
$boardsuffix = isset($board['uri']) ? $board['uri'] : '';
if (!isset($_SERVER['REMOTE_ADDR']))
@@ -69,7 +67,6 @@ function loadConfig() {
require_once('tmp/cache/cache_config.php');
}
-
if (isset($config['cache_config']) &&
$config['cache_config'] &&
$config = Cache::get('config_' . $boardsuffix ) ) {
@@ -83,7 +80,7 @@ function loadConfig() {
if ($config['locale'] != $current_locale) {
$current_locale = $config['locale'];
- init_locale($config['locale'], $error);
+ init_locale($config['locale']);
}
}
else {
@@ -114,6 +111,7 @@ function loadConfig() {
'file_icons',
'footer',
'stylesheets',
+ 'code_stylesheets',
'additional_javascript',
'markup',
'custom_pages',
@@ -125,7 +123,7 @@ function loadConfig() {
}
if (!file_exists('inc/instance-config.php'))
- $error('Tinyboard is not configured! Create inc/instance-config.php.');
+ error('Tinyboard is not configured! Create inc/instance-config.php.');
// Initialize locale as early as possible
@@ -155,7 +153,7 @@ function loadConfig() {
if ($config['locale'] != $current_locale) {
$current_locale = $config['locale'];
- init_locale($config['locale'], $error);
+ init_locale($config['locale']);
}
require 'inc/config.php';
@@ -168,7 +166,7 @@ function loadConfig() {
if ($config['locale'] != $current_locale) {
$current_locale = $config['locale'];
- init_locale($config['locale'], $error);
+ init_locale($config['locale']);
}
if (!isset($config['global_message']))
@@ -278,7 +276,7 @@ function loadConfig() {
$_SERVER['REMOTE_ADDR'] = $m[2];
if ($config['verbose_errors']) {
- set_error_handler('verbose_error_handler');
+ set_error_handler('error_handler');
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('html_errors', false);
@@ -339,36 +337,6 @@ function loadConfig() {
}
}
-function basic_error_function_because_the_other_isnt_loaded_yet($message, $priority = true) {
- global $config;
-
- if ($config['syslog'] && $priority !== false) {
- // Use LOG_NOTICE instead of LOG_ERR or LOG_WARNING because most error message are not significant.
- _syslog($priority !== true ? $priority : LOG_NOTICE, $message);
- }
-
- // Yes, this is horrible.
- die('<!DOCTYPE html><html><head><title>Error</title>' .
- '<style type="text/css">' .
- 'body{text-align:center;font-family:arial, helvetica, sans-serif;font-size:10pt;}' .
- 'p{padding:0;margin:20px 0;}' .
- 'p.c{font-size:11px;}' .
- '</style></head>' .
- '<body><h2>Error</h2>' . $message . '<hr/>' .
- '<p class="c">This alternative error page is being displayed because the other couldn\'t be found or hasn\'t loaded yet.</p></body></html>');
-}
-
-function fatal_error_handler() {
- if ($error = error_get_last()) {
- if ($error['type'] == E_ERROR) {
- if (function_exists('error')) {
- error('Caught fatal error: ' . $error['message'] . ' in <strong>' . $error['file'] . '</strong> on line ' . $error['line'], LOG_ERR);
- } else {
- basic_error_function_because_the_other_isnt_loaded_yet('Caught fatal error: ' . $error['message'] . ' in ' . $error['file'] . ' on line ' . $error['line'], LOG_ERR);
- }
- }
- }
-}
function _syslog($priority, $message) {
if (isset($_SERVER['REMOTE_ADDR'], $_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI'])) {
@@ -379,16 +347,6 @@ function _syslog($priority, $message) {
}
}
-function verbose_error_handler($errno, $errstr, $errfile, $errline) {
- if (error_reporting() == 0)
- return false; // Looks like this warning was suppressed by the @ operator.
- error(utf8tohtml($errstr), true, array(
- 'file' => $errfile . ':' . $errline,
- 'errno' => $errno,
- 'error' => $errstr,
- 'backtrace' => array_slice(debug_backtrace(), 1)
- ));
-}
function define_groups() {
global $config;
@@ -1732,9 +1690,17 @@ function buildJavascript() {
'uri' => addslashes((!empty($uri) ? $config['uri_stylesheets'] : '') . $uri));
}
+ $code_stylesheets = array();
+ foreach ($config['code_stylesheets'] as $name => $uri) {
+ $code_stylesheets[] = array(
+ 'name' => addslashes($name),
+ 'uri' => addslashes((!empty($uri) ? $config['uri_stylesheets'] : '') . $uri));
+ }
+
$script = Element('main.js', array(
'config' => $config,
- 'stylesheets' => $stylesheets
+ 'stylesheets' => $stylesheets,
+ 'code_stylesheets' => $code_stylesheets
));
// Check if we have translation for the javascripts; if yes, we add it to additional javascripts
@@ -2136,6 +2102,8 @@ function markup(&$body, $track_cites = false, $op = false) {
$code = isset($val[2]) ? $val[2] : $val[1];
$code_lang = isset($val[2]) ? $val[1] : "";
+ $code = rtrim(ltrim($code, "\r\n"));
+
$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);
diff --git a/inc/instance-config.php b/inc/instance-config.php
deleted file mode 100644
index f2dafe6f..00000000
--- a/inc/instance-config.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-/*
- * Instance Configuration
- * ----------------------
- * Edit this file and not config.php for imageboard configuration.
- *
- * You can copy values from config.php (defaults) and paste them here.
- */
-
-
-
- // Database stuff
- $config['db']['type'] = 'mysql';
- $config['db']['server'] = 'localhost';
- $config['db']['user'] = '';
- $config['db']['password'] = '';
- $config['db']['database'] = '';
-
- //$config['root'] = '/';
-
-
-?> \ No newline at end of file
diff --git a/inc/mod/pages.php b/inc/mod/pages.php
index c3e98af5..491432b3 100644
--- a/inc/mod/pages.php
+++ b/inc/mod/pages.php
@@ -61,7 +61,11 @@ function mod_login($redirect = false) {
}
function mod_confirm($request) {
- mod_page(_('Confirm action'), 'mod/confirm.html', array('request' => $request, 'token' => make_secure_link_token($request)));
+ $args = array('request' => $request, 'token' => make_secure_link_token($request));
+ if(isset($_GET['thread'])) {
+ $args['rest'] = 'thread=' . $_GET['thread'];
+ }
+ mod_page(_('Confirm action'), 'mod/confirm.html', $args);
}
function mod_logout() {
@@ -1194,8 +1198,9 @@ function mod_move_reply($originBoard, $postID) {
// build index
buildIndex();
+
// build new thread
- buildThread($newID);
+ buildThread($post['op'] ? $newID : $post['thread']);
// trigger themes
rebuildThemes('post', $targetBoard);
@@ -1213,7 +1218,7 @@ function mod_move_reply($originBoard, $postID) {
openBoard($targetBoard);
// Find new thread on our target board
- $query = prepare(sprintf('SELECT thread FROM ``posts_%s`` WHERE `id` = :id', $targetBoard));
+ $query = prepare(sprintf('SELECT thread, id FROM ``posts_%s`` WHERE `id` = :id', $targetBoard));
$query->bindValue(':id', $newID);
$query->execute() or error(db_error($query));
$post = $query->fetch(PDO::FETCH_ASSOC);
@@ -1331,7 +1336,7 @@ function mod_move($originBoard, $postID) {
$query = prepare('SELECT `target` FROM ``cites`` WHERE `target_board` = :board AND `board` = :board AND `post` = :post');
$query->bindValue(':board', $originBoard);
$query->bindValue(':post', $post['id'], PDO::PARAM_INT);
- $query->execute() or error(db_error($qurey));
+ $query->execute() or error(db_error($query));
// correct >>X links
while ($cite = $query->fetch(PDO::FETCH_ASSOC)) {
@@ -1492,8 +1497,14 @@ function mod_ban_post($board, $delete, $post, $token = false) {
// Rebuild themes
rebuildThemes('post-delete', $board);
}
-
- header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']);
+
+ if(isset($_POST['thread'])) {
+ // Redirect to thread
+ header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . str_replace('%d', $_POST['thread'], $config['file_page']), true, $config['redirect_http']);
+ } else {
+ // Redirect to board index.
+ header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']);
+ }
}
$args = array(
@@ -1505,6 +1516,10 @@ function mod_ban_post($board, $delete, $post, $token = false) {
'boards' => listBoards(),
'token' => $security_token
);
+
+ if($_GET['thread']) {
+ $args['thread'] = $_GET['thread'];
+ }
mod_page(_('New ban'), 'mod/ban_form.html', $args);
}
@@ -1604,7 +1619,11 @@ function mod_delete($board, $post) {
// Rebuild themes
rebuildThemes('post-delete', $board);
// Redirect
- header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']);
+ if(isset($_GET['thread'])) {
+ header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . str_replace('%d', $_GET['thread'], $config['file_page']), true, $config['redirect_http']);
+ } else {
+ header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']);
+ }
}
function mod_deletefile($board, $post, $file) {
diff --git a/install.php b/install.php
index 6f1617a8..ef2d7aa0 100644
--- a/install.php
+++ b/install.php
@@ -3,6 +3,11 @@
// Installation/upgrade file
define('VERSION', '5.1.3');
+if (fopen('inc/instance-config.php' , 'a') === false) {
+ print('install.php does not have permission to write to /inc/, without permission the installer cannot continue');
+ exit();
+}
+
require 'inc/functions.php';
loadConfig();
diff --git a/js/ajax.js b/js/ajax.js
index 56f0df5c..1072031d 100644
--- a/js/ajax.js
+++ b/js/ajax.js
@@ -94,7 +94,7 @@ $(window).ready(function() {
highlightReply(post_response.id);
window.location.hash = post_response.id;
- $(window).scrollTop($('div.post#reply_' + post_response.id).offset().top);
+ $(window).scrollTop($(document).height());
$(form).find('input[type="submit"]').val(submit_txt);
$(form).find('input[type="submit"]').removeAttr('disabled');
diff --git a/js/auto-reload.js b/js/auto-reload.js
index d015dfc1..bccc0ec2 100644
--- a/js/auto-reload.js
+++ b/js/auto-reload.js
@@ -17,221 +17,227 @@
*
*/
-
+au = false;
auto_reload_enabled = true; // for watch.js to interop
+function makeIcon(){
+ if(au) return;
+ au = true;
+ $("link[rel='icon']").attr("href", "../static/favicon_au.png");
+}
+
$(document).ready(function(){
- if($('div.banner').length == 0)
- return; // not index
-
- if($(".post.op").size() != 1)
- return; //not thread page
-
- var countdown_interval;
+ if($('div.banner').length == 0)
+ return; // not index
- // Add an update link
- $('.boardlist.bottom').prev().after("<span id='updater'><a href='#' id='update_thread' style='padding-left:10px'>["+_("Update")+"]</a> (<input type='checkbox' id='auto_update_status' checked> "+_("Auto")+") <span id='update_secs'></span></span>");
+ if($(".post.op").size() != 1)
+ return; //not thread page
- // Grab the settings
- var settings = new script_settings('auto-reload');
- var poll_interval_mindelay = settings.get('min_delay_bottom', 5000);
- var poll_interval_maxdelay = settings.get('max_delay', 600000);
- var poll_interval_errordelay = settings.get('error_delay', 30000);
+ var countdown_interval;
- // number of ms to wait before reloading
- var poll_interval_delay = poll_interval_mindelay;
- var poll_current_time = poll_interval_delay;
+ // Add an update link
+ $(".threadlinks span:last-child").after("<span id='updater'><a href='#' id='update_thread' style='padding-left:10px'>"+_("Update")+"</a> ] (<input type='checkbox' id='auto_update_status' checked> "+_("Auto")+") <span id='update_secs'></span></span>");
- var end_of_page = false;
+ // Grab the settings
+ var settings = new script_settings('auto-reload');
+ var poll_interval_mindelay = settings.get('min_delay_bottom', 5000);
+ var poll_interval_maxdelay = settings.get('max_delay', 600000);
+ var poll_interval_errordelay = settings.get('error_delay', 30000);
- var new_posts = 0;
- var first_new_post = null;
-
- var title = document.title;
+ // number of ms to wait before reloading
+ var poll_interval_delay = poll_interval_mindelay;
+ var poll_current_time = poll_interval_delay;
- if (typeof update_title == "undefined") {
- var update_title = function() {
- if (new_posts) {
- document.title = "("+new_posts+") "+title;
- } else {
- document.title = title;
- }
- };
- }
+ var end_of_page = false;
- if (typeof add_title_collector != "undefined")
- add_title_collector(function(){
- return new_posts;
- });
+ var new_posts = 0;
+ var first_new_post = null;
- var window_active = true;
- $(window).focus(function() {
- window_active = true;
- recheck_activated();
+ var title = document.title;
- // Reset the delay if needed
- if(settings.get('reset_focus', true)) {
- poll_interval_delay = poll_interval_mindelay;
- }
- });
- $(window).blur(function() {
- window_active = false;
+ if (typeof update_title == "undefined") {
+ var update_title = function() {
+ if (new_posts) {
+ document.title = "("+new_posts+") "+title;
+ } else {
+ document.title = title;
+ }
+ };
+ }
+
+ if (typeof add_title_collector != "undefined")
+ add_title_collector(function(){
+ return new_posts;
});
-
- $('#auto_update_status').click(function() {
- if($("#auto_update_status").is(':checked')) {
- auto_update(poll_interval_mindelay);
- } else {
- stop_auto_update();
- $('#update_secs').text("");
- }
+ var window_active = true;
+ $(window).focus(function() {
+ window_active = true;
+ recheck_activated();
- });
-
+ // Reset the delay if needed
+ if(settings.get('reset_focus', true)) {
+ poll_interval_delay = poll_interval_mindelay;
+ }
+ });
+ $(window).blur(function() {
+ window_active = false;
+ });
- var decrement_timer = function() {
- poll_current_time = poll_current_time - 1000;
- $('#update_secs').text(poll_current_time/1000);
-
- if (poll_current_time <= 0) {
- poll(manualUpdate = false);
- }
+
+ $('#auto_update_status').click(function() {
+ if($("#auto_update_status").is(':checked')) {
+ auto_update(poll_interval_mindelay);
+ } else {
+ stop_auto_update();
+ $('#update_secs').text("");
}
- var recheck_activated = function() {
- if (new_posts && window_active &&
- $(window).scrollTop() + $(window).height() >=
- $('div.boardlist.bottom').position().top) {
+ });
- new_posts = 0;
- }
- update_title();
- first_new_post = null;
- };
-
- // automatically updates the thread after a specified delay
- var auto_update = function(delay) {
- clearInterval(countdown_interval);
- poll_current_time = delay;
- countdown_interval = setInterval(decrement_timer, 1000);
- $('#update_secs').text(poll_current_time/1000);
+ var decrement_timer = function() {
+ poll_current_time = poll_current_time - 1000;
+ $('#update_secs').text(poll_current_time/1000);
+
+ if (poll_current_time <= 0) {
+ poll(manualUpdate = false);
}
-
- var stop_auto_update = function() {
- clearInterval(countdown_interval);
+ }
+
+ var recheck_activated = function() {
+ if (new_posts && window_active &&
+ $(window).scrollTop() + $(window).height() >=
+ $('footer').position().top) {
+
+ new_posts = 0;
}
-
- var epoch = (new Date).getTime();
- var epochold = epoch;
-
- var timeDiff = function (delay) {
- if((epoch-epochold) > delay) {
- epochold = epoch = (new Date).getTime();
- return true;
- }else{
- epoch = (new Date).getTime();
- return;
- }
+ update_title();
+ first_new_post = null;
+ };
+
+ // automatically updates the thread after a specified delay
+ var auto_update = function(delay) {
+ clearInterval(countdown_interval);
+
+ poll_current_time = delay;
+ countdown_interval = setInterval(decrement_timer, 1000);
+ $('#update_secs').text(poll_current_time/1000);
+ }
+
+ var stop_auto_update = function() {
+ clearInterval(countdown_interval);
+ }
+
+ var epoch = (new Date).getTime();
+ var epochold = epoch;
+
+ var timeDiff = function (delay) {
+ if((epoch-epochold) > delay) {
+ epochold = epoch = (new Date).getTime();
+ return true;
+ }else{
+ epoch = (new Date).getTime();
+ return;
}
-
- var poll = function(manualUpdate) {
- stop_auto_update();
- $('#update_secs').text(_("Updating..."));
-
- $.ajax({
- url: document.location,
- success: function(data) {
- var loaded_posts = 0; // the number of new posts loaded in this update
- $(data).find('div.post.reply').each(function() {
- var id = $(this).attr('id');
- if($('#' + id).length == 0) {
- if (!new_posts) {
- first_new_post = this;
- }
- $(this).insertAfter($('div.post:last').next()).after('<br class="clear">');
- new_posts++;
- loaded_posts++;
- $(document).trigger('new_post', this);
- recheck_activated();
- }
- });
- time_loaded = Date.now(); // interop with watch.js
-
-
- if ($('#auto_update_status').is(':checked')) {
- // If there are no new posts, double the delay. Otherwise set it to the min.
- if(loaded_posts == 0) {
- // if the update was manual, don't increase the delay
- if (manualUpdate == false) {
- poll_interval_delay *= 2;
-
- // Don't increase the delay beyond the maximum
- if(poll_interval_delay > poll_interval_maxdelay) {
- poll_interval_delay = poll_interval_maxdelay;
- }
- }
- } else {
- poll_interval_delay = poll_interval_mindelay;
- }
-
- auto_update(poll_interval_delay);
- } else {
- // Decide the message to show if auto update is disabled
- if (loaded_posts > 0)
- $('#update_secs').text(fmt(_("Thread updated with {0} new post(s)"), [loaded_posts]));
- else
- $('#update_secs').text(_("No new posts found"));
- }
- },
- error: function(xhr, status_text, error_text) {
- if (status_text == "error") {
- if (error_text == "Not Found") {
- $('#update_secs').text(_("Thread deleted or pruned"));
- $('#auto_update_status').prop('checked', false);
- $('#auto_update_status').prop('disabled', true); // disable updates if thread is deleted
- return;
- } else {
- $('#update_secs').text("Error: "+error_text);
- }
- } else if (status_text) {
- $('#update_secs').text(_("Error: ")+status_text);
- } else {
- $('#update_secs').text(_("Unknown error"));
- }
-
- // Keep trying to update
- if ($('#auto_update_status').is(':checked')) {
- poll_interval_delay = poll_interval_errordelay;
- auto_update(poll_interval_delay);
- }
+ }
+
+ var poll = function(manualUpdate) {
+ stop_auto_update();
+ $('#update_secs').text(_("Updating..."));
+
+ $.ajax({
+ url: document.location,
+ success: function(data) {
+ var loaded_posts = 0; // the number of new posts loaded in this update
+ $(data).find('div.postcontainer').each(function() {
+ var id = $(this).attr('id').substring(2);
+ if($('#' + id).length == 0) {
+ if (!new_posts) {
+ first_new_post = this;
+ makeIcon();
}
+ $(this).insertAfter($('div.postcontainer:last').next()).after('<br class="clear">');
+ new_posts++;
+ loaded_posts++;
+ $(document).trigger('new_post', this);
+ recheck_activated();
+ }
});
-
- return false;
- };
-
- $(window).scroll(function() {
- recheck_activated();
-
- // if the newest post is not visible
- if($(this).scrollTop() + $(this).height() <
- $('div.post:last').position().top + $('div.post:last').height()) {
- end_of_page = false;
+ time_loaded = Date.now(); // interop with watch.js
+
+
+ if ($('#auto_update_status').is(':checked')) {
+ // If there are no new posts, double the delay. Otherwise set it to the min.
+ if(loaded_posts == 0) {
+ // if the update was manual, don't increase the delay
+ if (manualUpdate == false) {
+ poll_interval_delay *= 2;
+
+ // Don't increase the delay beyond the maximum
+ if(poll_interval_delay > poll_interval_maxdelay) {
+ poll_interval_delay = poll_interval_maxdelay;
+ }
+ }
+ } else {
+ poll_interval_delay = poll_interval_mindelay;
+ }
+
+ auto_update(poll_interval_delay);
+ } else {
+ // Decide the message to show if auto update is disabled
+ if (loaded_posts > 0)
+ $('#update_secs').text(fmt(_("Thread updated with {0} new post(s)"), [loaded_posts]));
+ else
+ $('#update_secs').text(_("No new posts found"));
+ }
+ },
+ error: function(xhr, status_text, error_text) {
+ if (status_text == "error") {
+ if (error_text == "Not Found") {
+ $('#update_secs').text(_("Thread deleted or pruned"));
+ $('#auto_update_status').prop('checked', false);
+ $('#auto_update_status').prop('disabled', true); // disable updates if thread is deleted
return;
+ } else {
+ $('#update_secs').text("Error: "+error_text);
+ }
+ } else if (status_text) {
+ $('#update_secs').text(_("Error: ")+status_text);
} else {
- if($("#auto_update_status").is(':checked') && timeDiff(poll_interval_mindelay)) {
- poll(manualUpdate = true);
- }
- end_of_page = true;
+ $('#update_secs').text(_("Unknown error"));
+ }
+
+ // Keep trying to update
+ if ($('#auto_update_status').is(':checked')) {
+ poll_interval_delay = poll_interval_errordelay;
+ auto_update(poll_interval_delay);
}
+ }
});
- $('#update_thread').on('click', function() { poll(manualUpdate = true); return false; });
+ return false;
+ };
- if($("#auto_update_status").is(':checked')) {
- auto_update(poll_interval_delay);
+ $(window).scroll(function() {
+ recheck_activated();
+
+ // if the newest post is not visible
+ if($(this).scrollTop() + $(this).height() <
+ $('div.post:last').position().top + $('div.post:last').height()) {
+ end_of_page = false;
+ return;
+ } else {
+ if($("#auto_update_status").is(':checked') && timeDiff(poll_interval_mindelay)) {
+ poll(manualUpdate = true);
+ }
+ end_of_page = true;
}
-});
+ });
+
+ $('#update_thread').on('click', function() { poll(manualUpdate = true); return false; });
+ if($("#auto_update_status").is(':checked')) {
+ auto_update(poll_interval_delay);
+ }
+});
diff --git a/js/catalog-link.js b/js/catalog-link.js
index 05ee9efb..a98078f7 100644
--- a/js/catalog-link.js
+++ b/js/catalog-link.js
@@ -12,47 +12,51 @@
* $config['additional_javascript'][] = 'js/catalog-link.js';
*/
-function catalog() {
-var board = $("input[name='board']");
+(function($) {
+var catalog = function() {
+ var board = $('input[name="board"]');
-var catalog_url = configRoot + board.first().val() + "/catalog.html";
+ if (!board.length) {
+ return;
+ }
-var pages = document.getElementsByClassName('pages')[0];
-var bottom = document.getElementsByClassName('boardlist bottom')[0]
-var subtitle = document.getElementsByClassName('subtitle')[0];
+ var catalog_url = configRoot + board.first().val() + '/catalog.html';
-var link = document.createElement('a');
-link.href = catalog_url;
+ var pages = $('.pages');
+ var bottom = $('.boardlist.bottom');
+ var subtitle = $('.subtitle');
-if (pages) {
- link.textContent = _('Catalog');
- link.style.color = '#F10000';
- link.style.padding = '4px';
- link.style.paddingLeft = '9px';
- link.style.borderLeft = '1px solid'
- link.style.borderLeftColor = '#A8A8A8';
- link.style.textDecoration = "underline";
+ var link = $('<a class="catalog" />')
+ .attr('href', catalog_url);
- pages.appendChild(link)
-}
-else {
- link.textContent = '['+_('Catalog')+']';
- link.style.paddingLeft = '10px';
- link.style.textDecoration = "underline";
- document.body.insertBefore(link, bottom);
-}
+ if (pages.length) {
+ link.text(_('Catalog'))
+ .css({
+ color: '#F10000',
+ padding: '4px',
+ textDecoration: 'underline',
+ display: 'table-cell'
+ });
+ link.insertAfter(pages);
+ } else if (bottom.length) {
+ link.text('['+_('Catalog')+']')
+ .css({
+ paddingLeft: '10px',
+ textDecoration: 'underline'
+ });
+ link.insertBefore(bottom);
+ }
-if (subtitle) {
- var link2 = document.createElement('a');
- link2.textContent = _('Catalog');
- link2.href = catalog_url;
-
- var br = document.createElement('br');
- subtitle.appendChild(br);
- subtitle.appendChild(link2);
-}
+ if (subtitle.length) {
+ subtitle.append('<br />');
+ $('<a class="catalog" />')
+ .text(_('Catalog'))
+ .attr('href', catalog_url)
+ .appendTo(subtitle);
+ }
}
-if (active_page == 'thread' || active_page == 'index') {
+if (active_page == 'thread' || active_page == 'index' || active_page == 'ukko') {
$(document).ready(catalog);
}
+})(jQuery);
diff --git a/js/catalog-search.js b/js/catalog-search.js
index ff9af785..fc39b1ce 100644
--- a/js/catalog-search.js
+++ b/js/catalog-search.js
@@ -1,38 +1,22 @@
/*
* catalog-search.js
- * - Search and filters threads when on catalog view
- * - Optional shortcuts 's' and 'esc' to open and close the search.
- *
+ * https://github.com/mgrabovsky/lainchan/blob/catalog-search/js/catalog-search.js
+ *
+ * Released under the MIT license
+ * Copyright (c) 2015 Matěj Grabovský <matej.grabovsky@gmail.com>
+ *
* Usage:
* $config['additional_javascript'][] = 'js/jquery.min.js';
- * $config['additional_javascript'][] = 'js/comment-toolbar.js';
+ * $config['additional_javascript'][] = 'js/catalog-search.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() {
+var catalogSearch = function() {
+ var $controls = $('.controls'),
+ $threads = $('.threads .thread'),
+ $searchLabel = $('<label for="catalog_search">Search: </label>'),
+ $searchBox = $('<input id="catalog_search" type="text" placeholder="Search" />');
function searchToggle() {
var button = $('#catalog_search_button');
@@ -49,34 +33,33 @@ if (active_page == 'catalog') {
}
}
- $('.threads').before('<span class="catalog_search">[<a id="catalog_search_button" style="text-decoration:none; cursor:pointer;"></a>]</span>');
- $('#catalog_search_button').text('Search');
+ $controls.append($searchLabel)
+ .append($searchBox);
- $('#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);
- });
+ $searchBox.keyup(function() {
+ var $found = searchThreads($threads, this.value);
+ $threads.hide();
+ $found.show();
+ });
- 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();
- }
- });
- }
+ var m = location.hash.match(/[#&]s=([^&]+)/);
+ if(m) {
+ $searchBox.val(decodeURIComponent(m[1])).keyup();
+ }
+};
+
+// Filter threads by their content, given a regex. Can be extended to load data
+// remotely and filter by multiple fields
+var searchThreads = function($threads, query) {
+ var re = new RegExp(query, 'mi');
+ return $threads.filter(function() {
+ return re.test($('.replies', this).text());
});
+};
+
+// Only load in the catalog
+if (active_page == 'catalog') {
+ onready(catalogSearch);
}
+
+}());
diff --git a/js/hilight.js b/js/hilight.js
new file mode 100644
index 00000000..0e1612bf
--- /dev/null
+++ b/js/hilight.js
@@ -0,0 +1,12 @@
+function styleCode() {
+ $('pre').each(function() {
+ if (!$(this).hasClass('prettyprint')) {
+ $(this).addClass('prettyprint');
+ }
+ });
+
+ prettyPrint();
+}
+
+$(function() {styleCode();});
+
diff --git a/js/mute-images.js b/js/mute-images.js
new file mode 100644
index 00000000..04dd3466
--- /dev/null
+++ b/js/mute-images.js
@@ -0,0 +1,48 @@
+/*
+ * mute-images.js
+ *
+ * Hide all images.
+ *
+ * Released under the MIT license
+ * Copyright (c) 2015 boku
+ *
+ * Usage:
+ * $config['additional_javascript'][] = 'js/jquery.min.js';
+ * $config['additional_javascript'][] = 'js/mute-images.js';
+ *
+ */
+
+$(document).ready(function(){
+ $('head').append('<style type="text/css"> .muteimages .post-image:not(:hover) { opacity: 0.03; } </style>');
+ $('hr:first').before('<div style="text-align:right"><a class="unimportant" href="javascript:void(0)" id="mute_images">'+_('Mute all images')+'</a></div>');
+
+ if (!localStorage.imagesmuted){
+ localStorage.imagesmuted = 'false';
+ }
+
+ // Load data from HTML5 localStorage
+ var isMuted = JSON.parse(localStorage.imagesmuted),
+ store_data = function() {
+ localStorage.imagesmuted = JSON.stringify(isMuted);
+ };
+
+ if(isMuted){
+ $('body').addClass('muteimages');
+ $('#mute_images').text(_('Unmute all images'));
+ }
+
+ $('#mute_images').on('click', function(){
+ if(isMuted){
+ $('body').removeClass('muteimages');
+ isMuted = false;
+ $('#mute_images').text(_('Mute all images'));
+ }else{
+ $('body').addClass('muteimages');
+ isMuted = true;
+ $('#mute_images').text(_('Unmute all images'));
+ }
+
+ store_data();
+ return false;
+ });
+});
diff --git a/js/options.js b/js/options.js
index 4a7f3ce9..5e51d428 100644
--- a/js/options.js
+++ b/js/options.js
@@ -103,17 +103,19 @@ options_tablist = $("<div id='options_tablist'></div>").appendTo(options_div);
$(function(){
- options_button = $("<a href='javascript:void(0)' title='"+_("Options")+"'>["+_("Options")+"]</a>").css("float", "right");
+ options_button = $("<a href='javascript:void(0)' title='"+_("Options")+"'>["+_("Options")+"]</a>");
if ($(".boardlist.compact-boardlist").length) {
options_button.addClass("cb-item cb-fa").html("<i class='fa fa-gear'></i>");
}
if ($(".boardlist:first").length) {
- options_button.appendTo($(".boardlist:first"));
+ options_button.css('float', 'right').appendTo($(".boardlist:first"));
}
else {
- options_button.prependTo($(document.body));
+ var optsdiv = $('<div style="text-align: right"></div>');
+ options_button.appendTo(optsdiv);
+ optsdiv.prependTo($(document.body));
}
options_button.on("click", Options.show);
@@ -123,4 +125,4 @@ $(function(){
-}();
+}(); \ No newline at end of file
diff --git a/js/piwik.js b/js/piwik.js
new file mode 100755
index 00000000..fd5cce24
--- /dev/null
+++ b/js/piwik.js
@@ -0,0 +1,12 @@
+
+ var _paq = _paq || [];
+ _paq.push(['trackPageView']);
+ _paq.push(['enableLinkTracking']);
+ (function() {
+ var u="//lainchan.org/analytics/piwik/";
+ _paq.push(['setTrackerUrl', u+'piwik.php']);
+ _paq.push(['setSiteId', 1]);
+ var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
+ g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
+ })();
+
diff --git a/js/post-hover.js b/js/post-hover.js
index 780f8cff..e78b57e8 100644
--- a/js/post-hover.js
+++ b/js/post-hover.js
@@ -70,11 +70,11 @@ onready(function(){
.attr('data-board', board)
.addClass('post-hover')
.css('border-style', 'solid')
- .css('box-shadow', '1px 1px 1px #999')
- .css('display', 'block')
+ .css('display', 'inline-block')
.css('position', 'absolute')
.css('font-style', 'normal')
.css('z-index', '100')
+ .css('margin-left', '1em')
.addClass('reply').addClass('post')
.insertAfter($link.parent())
@@ -156,7 +156,7 @@ onready(function(){
}
- $hover.css('left', (e.pageX ? e.pageX : hovered_at['x'])).css('top', top);
+ $hover.css('left', (e.pageX ? e.pageX : hovered_at['x']) + 1).css('top', top);
});
};
diff --git a/js/prettify.js b/js/prettify.js
new file mode 100644
index 00000000..fccf4f52
--- /dev/null
+++ b/js/prettify.js
@@ -0,0 +1,1655 @@
+// Copyright (C) 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/**
+ * @fileoverview
+ * some functions for browser-side pretty printing of code contained in html.
+ *
+ * <p>
+ * For a fairly comprehensive set of languages see the
+ * <a href="http://google-code-prettify.googlecode.com/svn/trunk/README.html#langs">README</a>
+ * file that came with this source. At a minimum, the lexer should work on a
+ * number of languages including C and friends, Java, Python, Bash, SQL, HTML,
+ * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk
+ * and a subset of Perl, but, because of commenting conventions, doesn't work on
+ * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.
+ * <p>
+ * Usage: <ol>
+ * <li> include this source file in an html page via
+ * {@code <script type="text/javascript" src="/path/to/prettify.js"></script>}
+ * <li> define style rules. See the example page for examples.
+ * <li> mark the {@code <pre>} and {@code <code>} tags in your source with
+ * {@code class=prettyprint.}
+ * You can also use the (html deprecated) {@code <xmp>} tag, but the pretty
+ * printer needs to do more substantial DOM manipulations to support that, so
+ * some css styles may not be preserved.
+ * </ol>
+ * That's it. I wanted to keep the API as simple as possible, so there's no
+ * need to specify which language the code is in, but if you wish, you can add
+ * another class to the {@code <pre>} or {@code <code>} element to specify the
+ * language, as in {@code <pre class="prettyprint lang-java">}. Any class that
+ * starts with "lang-" followed by a file extension, specifies the file type.
+ * See the "lang-*.js" files in this directory for code that implements
+ * per-language file handlers.
+ * <p>
+ * Change log:<br>
+ * cbeust, 2006/08/22
+ * <blockquote>
+ * Java annotations (start with "@") are now captured as literals ("lit")
+ * </blockquote>
+ * @requires console
+ */
+
+// JSLint declarations
+/*global console, document, navigator, setTimeout, window, define */
+
+/** @define {boolean} */
+var IN_GLOBAL_SCOPE = true;
+
+/**
+ * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
+ * UI events.
+ * If set to {@code false}, {@code prettyPrint()} is synchronous.
+ */
+window['PR_SHOULD_USE_CONTINUATION'] = true;
+
+/**
+ * Pretty print a chunk of code.
+ * @param {string} sourceCodeHtml The HTML to pretty print.
+ * @param {string} opt_langExtension The language name to use.
+ * Typically, a filename extension like 'cpp' or 'java'.
+ * @param {number|boolean} opt_numberLines True to number lines,
+ * or the 1-indexed number of the first line in sourceCodeHtml.
+ * @return {string} code as html, but prettier
+ */
+var prettyPrintOne;
+/**
+ * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
+ * {@code class=prettyprint} and prettify them.
+ *
+ * @param {Function} opt_whenDone called when prettifying is done.
+ * @param {HTMLElement|HTMLDocument} opt_root an element or document
+ * containing all the elements to pretty print.
+ * Defaults to {@code document.body}.
+ */
+var prettyPrint;
+
+
+(function () {
+ var win = window;
+ // Keyword lists for various languages.
+ // We use things that coerce to strings to make them compact when minified
+ // and to defeat aggressive optimizers that fold large string constants.
+ var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
+ var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," +
+ "double,enum,extern,float,goto,inline,int,long,register,short,signed," +
+ "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];
+ var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
+ "new,operator,private,protected,public,this,throw,true,try,typeof"];
+ var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
+ "concept,concept_map,const_cast,constexpr,decltype,delegate," +
+ "dynamic_cast,explicit,export,friend,generic,late_check," +
+ "mutable,namespace,nullptr,property,reinterpret_cast,static_assert," +
+ "static_cast,template,typeid,typename,using,virtual,where"];
+ var JAVA_KEYWORDS = [COMMON_KEYWORDS,
+ "abstract,assert,boolean,byte,extends,final,finally,implements,import," +
+ "instanceof,interface,null,native,package,strictfp,super,synchronized," +
+ "throws,transient"];
+ var CSHARP_KEYWORDS = [COMMON_KEYWORDS,
+ "abstract,as,base,bool,by,byte,checked,decimal,delegate,descending," +
+ "dynamic,event,finally,fixed,foreach,from,group,implicit,in,interface," +
+ "internal,into,is,let,lock,null,object,out,override,orderby,params," +
+ "partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong," +
+ "unchecked,unsafe,ushort,var,virtual,where"];
+ var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
+ "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
+ "throw,true,try,unless,until,when,while,yes";
+ var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
+ "debugger,eval,export,function,get,null,set,undefined,var,with," +
+ "Infinity,NaN"];
+ var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
+ "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
+ "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
+ var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
+ "elif,except,exec,finally,from,global,import,in,is,lambda," +
+ "nonlocal,not,or,pass,print,raise,try,with,yield," +
+ "False,True,None"];
+ var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
+ "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
+ "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
+ "BEGIN,END"];
+ var RUST_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "as,assert,const,copy,drop," +
+ "enum,extern,fail,false,fn,impl,let,log,loop,match,mod,move,mut,priv," +
+ "pub,pure,ref,self,static,struct,true,trait,type,unsafe,use"];
+ var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
+ "function,in,local,set,then,until"];
+ var ALL_KEYWORDS = [
+ CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS,
+ PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
+ var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)\b/;
+
+ // token style names. correspond to css classes
+ /**
+ * token style for a string literal
+ * @const
+ */
+ var PR_STRING = 'str';
+ /**
+ * token style for a keyword
+ * @const
+ */
+ var PR_KEYWORD = 'kwd';
+ /**
+ * token style for a comment
+ * @const
+ */
+ var PR_COMMENT = 'com';
+ /**
+ * token style for a type
+ * @const
+ */
+ var PR_TYPE = 'typ';
+ /**
+ * token style for a literal value. e.g. 1, null, true.
+ * @const
+ */
+ var PR_LITERAL = 'lit';
+ /**
+ * token style for a punctuation string.
+ * @const
+ */
+ var PR_PUNCTUATION = 'pun';
+ /**
+ * token style for plain text.
+ * @const
+ */
+ var PR_PLAIN = 'pln';
+
+ /**
+ * token style for an sgml tag.
+ * @const
+ */
+ var PR_TAG = 'tag';
+ /**
+ * token style for a markup declaration such as a DOCTYPE.
+ * @const
+ */
+ var PR_DECLARATION = 'dec';
+ /**
+ * token style for embedded source.
+ * @const
+ */
+ var PR_SOURCE = 'src';
+ /**
+ * token style for an sgml attribute name.
+ * @const
+ */
+ var PR_ATTRIB_NAME = 'atn';
+ /**
+ * token style for an sgml attribute value.
+ * @const
+ */
+ var PR_ATTRIB_VALUE = 'atv';
+
+ /**
+ * A class that indicates a section of markup that is not code, e.g. to allow
+ * embedding of line numbers within code listings.
+ * @const
+ */
+ var PR_NOCODE = 'nocode';
+
+
+
+ /**
+ * A set of tokens that can precede a regular expression literal in
+ * javascript
+ * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
+ * has the full list, but I've removed ones that might be problematic when
+ * seen in languages that don't support regular expression literals.
+ *
+ * <p>Specifically, I've removed any keywords that can't precede a regexp
+ * literal in a syntactically legal javascript program, and I've removed the
+ * "in" keyword since it's not a keyword in many languages, and might be used
+ * as a count of inches.
+ *
+ * <p>The link above does not accurately describe EcmaScript rules since
+ * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
+ * very well in practice.
+ *
+ * @private
+ * @const
+ */
+ var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
+
+ // CAVEAT: this does not properly handle the case where a regular
+ // expression immediately follows another since a regular expression may
+ // have flags for case-sensitivity and the like. Having regexp tokens
+ // adjacent is not valid in any language I'm aware of, so I'm punting.
+ // TODO: maybe style special characters inside a regexp as punctuation.
+
+ /**
+ * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
+ * matches the union of the sets of strings matched by the input RegExp.
+ * Since it matches globally, if the input strings have a start-of-input
+ * anchor (/^.../), it is ignored for the purposes of unioning.
+ * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
+ * @return {RegExp} a global regex.
+ */
+ function combinePrefixPatterns(regexs) {
+ var capturedGroupIndex = 0;
+
+ var needToFoldCase = false;
+ var ignoreCase = false;
+ for (var i = 0, n = regexs.length; i < n; ++i) {
+ var regex = regexs[i];
+ if (regex.ignoreCase) {
+ ignoreCase = true;
+ } else if (/[a-z]/i.test(regex.source.replace(
+ /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
+ needToFoldCase = true;
+ ignoreCase = false;
+ break;
+ }
+ }
+
+ var escapeCharToCodeUnit = {
+ 'b': 8,
+ 't': 9,
+ 'n': 0xa,
+ 'v': 0xb,
+ 'f': 0xc,
+ 'r': 0xd
+ };
+
+ function decodeEscape(charsetPart) {
+ var cc0 = charsetPart.charCodeAt(0);
+ if (cc0 !== 92 /* \\ */) {
+ return cc0;
+ }
+ var c1 = charsetPart.charAt(1);
+ cc0 = escapeCharToCodeUnit[c1];
+ if (cc0) {
+ return cc0;
+ } else if ('0' <= c1 && c1 <= '7') {
+ return parseInt(charsetPart.substring(1), 8);
+ } else if (c1 === 'u' || c1 === 'x') {
+ return parseInt(charsetPart.substring(2), 16);
+ } else {
+ return charsetPart.charCodeAt(1);
+ }
+ }
+
+ function encodeEscape(charCode) {
+ if (charCode < 0x20) {
+ return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
+ }
+ var ch = String.fromCharCode(charCode);
+ return (ch === '\\' || ch === '-' || ch === ']' || ch === '^')
+ ? "\\" + ch : ch;
+ }
+
+ function caseFoldCharset(charSet) {
+ var charsetParts = charSet.substring(1, charSet.length - 1).match(
+ new RegExp(
+ '\\\\u[0-9A-Fa-f]{4}'
+ + '|\\\\x[0-9A-Fa-f]{2}'
+ + '|\\\\[0-3][0-7]{0,2}'
+ + '|\\\\[0-7]{1,2}'
+ + '|\\\\[\\s\\S]'
+ + '|-'
+ + '|[^-\\\\]',
+ 'g'));
+ var ranges = [];
+ var inverse = charsetParts[0] === '^';
+
+ var out = ['['];
+ if (inverse) { out.push('^'); }
+
+ for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
+ var p = charsetParts[i];
+ if (/\\[bdsw]/i.test(p)) { // Don't muck with named groups.
+ out.push(p);
+ } else {
+ var start = decodeEscape(p);
+ var end;
+ if (i + 2 < n && '-' === charsetParts[i + 1]) {
+ end = decodeEscape(charsetParts[i + 2]);
+ i += 2;
+ } else {
+ end = start;
+ }
+ ranges.push([start, end]);
+ // If the range might intersect letters, then expand it.
+ // This case handling is too simplistic.
+ // It does not deal with non-latin case folding.
+ // It works for latin source code identifiers though.
+ if (!(end < 65 || start > 122)) {
+ if (!(end < 65 || start > 90)) {
+ ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
+ }
+ if (!(end < 97 || start > 122)) {
+ ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
+ }
+ }
+ }
+ }
+
+ // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
+ // -> [[1, 12], [14, 14], [16, 17]]
+ ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1] - a[1]); });
+ var consolidatedRanges = [];
+ var lastRange = [];
+ for (var i = 0; i < ranges.length; ++i) {
+ var range = ranges[i];
+ if (range[0] <= lastRange[1] + 1) {
+ lastRange[1] = Math.max(lastRange[1], range[1]);
+ } else {
+ consolidatedRanges.push(lastRange = range);
+ }
+ }
+
+ for (var i = 0; i < consolidatedRanges.length; ++i) {
+ var range = consolidatedRanges[i];
+ out.push(encodeEscape(range[0]));
+ if (range[1] > range[0]) {
+ if (range[1] + 1 > range[0]) { out.push('-'); }
+ out.push(encodeEscape(range[1]));
+ }
+ }
+ out.push(']');
+ return out.join('');
+ }
+
+ function allowAnywhereFoldCaseAndRenumberGroups(regex) {
+ // Split into character sets, escape sequences, punctuation strings
+ // like ('(', '(?:', ')', '^'), and runs of characters that do not
+ // include any of the above.
+ var parts = regex.source.match(
+ new RegExp(
+ '(?:'
+ + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]' // a character set
+ + '|\\\\u[A-Fa-f0-9]{4}' // a unicode escape
+ + '|\\\\x[A-Fa-f0-9]{2}' // a hex escape
+ + '|\\\\[0-9]+' // a back-reference or octal escape
+ + '|\\\\[^ux0-9]' // other escape sequence
+ + '|\\(\\?[:!=]' // start of a non-capturing group
+ + '|[\\(\\)\\^]' // start/end of a group, or line start
+ + '|[^\\x5B\\x5C\\(\\)\\^]+' // run of other characters
+ + ')',
+ 'g'));
+ var n = parts.length;
+
+ // Maps captured group numbers to the number they will occupy in
+ // the output or to -1 if that has not been determined, or to
+ // undefined if they need not be capturing in the output.
+ var capturedGroups = [];
+
+ // Walk over and identify back references to build the capturedGroups
+ // mapping.
+ for (var i = 0, groupIndex = 0; i < n; ++i) {
+ var p = parts[i];
+ if (p === '(') {
+ // groups are 1-indexed, so max group index is count of '('
+ ++groupIndex;
+ } else if ('\\' === p.charAt(0)) {
+ var decimalValue = +p.substring(1);
+ if (decimalValue) {
+ if (decimalValue <= groupIndex) {
+ capturedGroups[decimalValue] = -1;
+ } else {
+ // Replace with an unambiguous escape sequence so that
+ // an octal escape sequence does not turn into a backreference
+ // to a capturing group from an earlier regex.
+ parts[i] = encodeEscape(decimalValue);
+ }
+ }
+ }
+ }
+
+ // Renumber groups and reduce capturing groups to non-capturing groups
+ // where possible.
+ for (var i = 1; i < capturedGroups.length; ++i) {
+ if (-1 === capturedGroups[i]) {
+ capturedGroups[i] = ++capturedGroupIndex;
+ }
+ }
+ for (var i = 0, groupIndex = 0; i < n; ++i) {
+ var p = parts[i];
+ if (p === '(') {
+ ++groupIndex;
+ if (!capturedGroups[groupIndex]) {
+ parts[i] = '(?:';
+ }
+ } else if ('\\' === p.charAt(0)) {
+ var decimalValue = +p.substring(1);
+ if (decimalValue && decimalValue <= groupIndex) {
+ parts[i] = '\\' + capturedGroups[decimalValue];
+ }
+ }
+ }
+
+ // Remove any prefix anchors so that the output will match anywhere.
+ // ^^ really does mean an anchored match though.
+ for (var i = 0; i < n; ++i) {
+ if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
+ }
+
+ // Expand letters to groups to handle mixing of case-sensitive and
+ // case-insensitive patterns if necessary.
+ if (regex.ignoreCase && needToFoldCase) {
+ for (var i = 0; i < n; ++i) {
+ var p = parts[i];
+ var ch0 = p.charAt(0);
+ if (p.length >= 2 && ch0 === '[') {
+ parts[i] = caseFoldCharset(p);
+ } else if (ch0 !== '\\') {
+ // TODO: handle letters in numeric escapes.
+ parts[i] = p.replace(
+ /[a-zA-Z]/g,
+ function (ch) {
+ var cc = ch.charCodeAt(0);
+ return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
+ });
+ }
+ }
+ }
+
+ return parts.join('');
+ }
+
+ var rewritten = [];
+ for (var i = 0, n = regexs.length; i < n; ++i) {
+ var regex = regexs[i];
+ if (regex.global || regex.multiline) { throw new Error('' + regex); }
+ rewritten.push(
+ '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
+ }
+
+ return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
+ }
+
+ /**
+ * Split markup into a string of source code and an array mapping ranges in
+ * that string to the text nodes in which they appear.
+ *
+ * <p>
+ * The HTML DOM structure:</p>
+ * <pre>
+ * (Element "p"
+ * (Element "b"
+ * (Text "print ")) ; #1
+ * (Text "'Hello '") ; #2
+ * (Element "br") ; #3
+ * (Text " + 'World';")) ; #4
+ * </pre>
+ * <p>
+ * corresponds to the HTML
+ * {@code <p><b>print </b>'Hello '<br> + 'World';</p>}.</p>
+ *
+ * <p>
+ * It will produce the output:</p>
+ * <pre>
+ * {
+ * sourceCode: "print 'Hello '\n + 'World';",
+ * // 1 2
+ * // 012345678901234 5678901234567
+ * spans: [0, #1, 6, #2, 14, #3, 15, #4]
+ * }
+ * </pre>
+ * <p>
+ * where #1 is a reference to the {@code "print "} text node above, and so
+ * on for the other text nodes.
+ * </p>
+ *
+ * <p>
+ * The {@code} spans array is an array of pairs. Even elements are the start
+ * indices of substrings, and odd elements are the text nodes (or BR elements)
+ * that contain the text for those substrings.
+ * Substrings continue until the next index or the end of the source.
+ * </p>
+ *
+ * @param {Node} node an HTML DOM subtree containing source-code.
+ * @param {boolean} isPreformatted true if white-space in text nodes should
+ * be considered significant.
+ * @return {Object} source code and the text nodes in which they occur.
+ */
+ function extractSourceSpans(node, isPreformatted) {
+ var nocode = /(?:^|\s)nocode(?:\s|$)/;
+
+ var chunks = [];
+ var length = 0;
+ var spans = [];
+ var k = 0;
+
+ function walk(node) {
+ var type = node.nodeType;
+ if (type == 1) { // Element
+ if (nocode.test(node.className)) { return; }
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ walk(child);
+ }
+ var nodeName = node.nodeName.toLowerCase();
+ if ('br' === nodeName || 'li' === nodeName) {
+ chunks[k] = '\n';
+ spans[k << 1] = length++;
+ spans[(k++ << 1) | 1] = node;
+ }
+ } else if (type == 3 || type == 4) { // Text
+ var text = node.nodeValue;
+ if (text.length) {
+ if (!isPreformatted) {
+ text = text.replace(/[ \t\r\n]+/g, ' ');
+ } else {
+ text = text.replace(/\r\n?/g, '\n'); // Normalize newlines.
+ }
+ // TODO: handle tabs here?
+ chunks[k] = text;
+ spans[k << 1] = length;
+ length += text.length;
+ spans[(k++ << 1) | 1] = node;
+ }
+ }
+ }
+
+ walk(node);
+
+ return {
+ sourceCode: chunks.join('').replace(/\n$/, ''),
+ spans: spans
+ };
+ }
+
+ /**
+ * Apply the given language handler to sourceCode and add the resulting
+ * decorations to out.
+ * @param {number} basePos the index of sourceCode within the chunk of source
+ * whose decorations are already present on out.
+ */
+ function appendDecorations(basePos, sourceCode, langHandler, out) {
+ if (!sourceCode) { return; }
+ var job = {
+ sourceCode: sourceCode,
+ basePos: basePos
+ };
+ langHandler(job);
+ out.push.apply(out, job.decorations);
+ }
+
+ var notWs = /\S/;
+
+ /**
+ * Given an element, if it contains only one child element and any text nodes
+ * it contains contain only space characters, return the sole child element.
+ * Otherwise returns undefined.
+ * <p>
+ * This is meant to return the CODE element in {@code <pre><code ...>} when
+ * there is a single child element that contains all the non-space textual
+ * content, but not to return anything where there are multiple child elements
+ * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
+ * is textual content.
+ */
+ function childContentWrapper(element) {
+ var wrapper = undefined;
+ for (var c = element.firstChild; c; c = c.nextSibling) {
+ var type = c.nodeType;
+ wrapper = (type === 1) // Element Node
+ ? (wrapper ? element : c)
+ : (type === 3) // Text Node
+ ? (notWs.test(c.nodeValue) ? element : wrapper)
+ : wrapper;
+ }
+ return wrapper === element ? undefined : wrapper;
+ }
+
+ /** Given triples of [style, pattern, context] returns a lexing function,
+ * The lexing function interprets the patterns to find token boundaries and
+ * returns a decoration list of the form
+ * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
+ * where index_n is an index into the sourceCode, and style_n is a style
+ * constant like PR_PLAIN. index_n-1 <= index_n, and style_n-1 applies to
+ * all characters in sourceCode[index_n-1:index_n].
+ *
+ * The stylePatterns is a list whose elements have the form
+ * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
+ *
+ * Style is a style constant like PR_PLAIN, or can be a string of the
+ * form 'lang-FOO', where FOO is a language extension describing the
+ * language of the portion of the token in $1 after pattern executes.
+ * E.g., if style is 'lang-lisp', and group 1 contains the text
+ * '(hello (world))', then that portion of the token will be passed to the
+ * registered lisp handler for formatting.
+ * The text before and after group 1 will be restyled using this decorator
+ * so decorators should take care that this doesn't result in infinite
+ * recursion. For example, the HTML lexer rule for SCRIPT elements looks
+ * something like ['lang-js', /<[s]cript>(.+?)<\/script>/]. This may match
+ * '<script>foo()<\/script>', which would cause the current decorator to
+ * be called with '<script>' which would not match the same rule since
+ * group 1 must not be empty, so it would be instead styled as PR_TAG by
+ * the generic tag rule. The handler registered for the 'js' extension would
+ * then be called with 'foo()', and finally, the current decorator would
+ * be called with '<\/script>' which would not match the original rule and
+ * so the generic tag rule would identify it as a tag.
+ *
+ * Pattern must only match prefixes, and if it matches a prefix, then that
+ * match is considered a token with the same style.
+ *
+ * Context is applied to the last non-whitespace, non-comment token
+ * recognized.
+ *
+ * Shortcut is an optional string of characters, any of which, if the first
+ * character, gurantee that this pattern and only this pattern matches.
+ *
+ * @param {Array} shortcutStylePatterns patterns that always start with
+ * a known character. Must have a shortcut string.
+ * @param {Array} fallthroughStylePatterns patterns that will be tried in
+ * order if the shortcut ones fail. May have shortcuts.
+ *
+ * @return {function (Object)} a
+ * function that takes source code and returns a list of decorations.
+ */
+ function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
+ var shortcuts = {};
+ var tokenizer;
+ (function () {
+ var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
+ var allRegexs = [];
+ var regexKeys = {};
+ for (var i = 0, n = allPatterns.length; i < n; ++i) {
+ var patternParts = allPatterns[i];
+ var shortcutChars = patternParts[3];
+ if (shortcutChars) {
+ for (var c = shortcutChars.length; --c >= 0;) {
+ shortcuts[shortcutChars.charAt(c)] = patternParts;
+ }
+ }
+ var regex = patternParts[1];
+ var k = '' + regex;
+ if (!regexKeys.hasOwnProperty(k)) {
+ allRegexs.push(regex);
+ regexKeys[k] = null;
+ }
+ }
+ allRegexs.push(/[\0-\uffff]/);
+ tokenizer = combinePrefixPatterns(allRegexs);
+ })();
+
+ var nPatterns = fallthroughStylePatterns.length;
+
+ /**
+ * Lexes job.sourceCode and produces an output array job.decorations of
+ * style classes preceded by the position at which they start in
+ * job.sourceCode in order.
+ *
+ * @param {Object} job an object like <pre>{
+ * sourceCode: {string} sourceText plain text,
+ * basePos: {int} position of job.sourceCode in the larger chunk of
+ * sourceCode.
+ * }</pre>
+ */
+ var decorate = function (job) {
+ var sourceCode = job.sourceCode, basePos = job.basePos;
+ /** Even entries are positions in source in ascending order. Odd enties
+ * are style markers (e.g., PR_COMMENT) that run from that position until
+ * the end.
+ * @type {Array.<number|string>}
+ */
+ var decorations = [basePos, PR_PLAIN];
+ var pos = 0; // index into sourceCode
+ var tokens = sourceCode.match(tokenizer) || [];
+ var styleCache = {};
+
+ for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
+ var token = tokens[ti];
+ var style = styleCache[token];
+ var match = void 0;
+
+ var isEmbedded;
+ if (typeof style === 'string') {
+ isEmbedded = false;
+ } else {
+ var patternParts = shortcuts[token.charAt(0)];
+ if (patternParts) {
+ match = token.match(patternParts[1]);
+ style = patternParts[0];
+ } else {
+ for (var i = 0; i < nPatterns; ++i) {
+ patternParts = fallthroughStylePatterns[i];
+ match = token.match(patternParts[1]);
+ if (match) {
+ style = patternParts[0];
+ break;
+ }
+ }
+
+ if (!match) { // make sure that we make progress
+ style = PR_PLAIN;
+ }
+ }
+
+ isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
+ if (isEmbedded && !(match && typeof match[1] === 'string')) {
+ isEmbedded = false;
+ style = PR_SOURCE;
+ }
+
+ if (!isEmbedded) { styleCache[token] = style; }
+ }
+
+ var tokenStart = pos;
+ pos += token.length;
+
+ if (!isEmbedded) {
+ decorations.push(basePos + tokenStart, style);
+ } else { // Treat group 1 as an embedded block of source code.
+ var embeddedSource = match[1];
+ var embeddedSourceStart = token.indexOf(embeddedSource);
+ var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
+ if (match[2]) {
+ // If embeddedSource can be blank, then it would match at the
+ // beginning which would cause us to infinitely recurse on the
+ // entire token, so we catch the right context in match[2].
+ embeddedSourceEnd = token.length - match[2].length;
+ embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
+ }
+ var lang = style.substring(5);
+ // Decorate the left of the embedded source
+ appendDecorations(
+ basePos + tokenStart,
+ token.substring(0, embeddedSourceStart),
+ decorate, decorations);
+ // Decorate the embedded source
+ appendDecorations(
+ basePos + tokenStart + embeddedSourceStart,
+ embeddedSource,
+ langHandlerForExtension(lang, embeddedSource),
+ decorations);
+ // Decorate the right of the embedded section
+ appendDecorations(
+ basePos + tokenStart + embeddedSourceEnd,
+ token.substring(embeddedSourceEnd),
+ decorate, decorations);
+ }
+ }
+ job.decorations = decorations;
+ };
+ return decorate;
+ }
+
+ /** returns a function that produces a list of decorations from source text.
+ *
+ * This code treats ", ', and ` as string delimiters, and \ as a string
+ * escape. It does not recognize perl's qq() style strings.
+ * It has no special handling for double delimiter escapes as in basic, or
+ * the tripled delimiters used in python, but should work on those regardless
+ * although in those cases a single string literal may be broken up into
+ * multiple adjacent string literals.
+ *
+ * It recognizes C, C++, and shell style comments.
+ *
+ * @param {Object} options a set of optional parameters.
+ * @return {function (Object)} a function that examines the source code
+ * in the input job and builds the decoration list.
+ */
+ function sourceDecorator(options) {
+ var shortcutStylePatterns = [], fallthroughStylePatterns = [];
+ if (options['tripleQuotedStrings']) {
+ // '''multi-line-string''', 'single-line-string', and double-quoted
+ shortcutStylePatterns.push(
+ [PR_STRING, /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
+ null, '\'"']);
+ } else if (options['multiLineStrings']) {
+ // 'multi-line-string', "multi-line-string"
+ shortcutStylePatterns.push(
+ [PR_STRING, /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
+ null, '\'"`']);
+ } else {
+ // 'single-line-string', "single-line-string"
+ shortcutStylePatterns.push(
+ [PR_STRING,
+ /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
+ null, '"\'']);
+ }
+ if (options['verbatimStrings']) {
+ // verbatim-string-literal production from the C# grammar. See issue 93.
+ fallthroughStylePatterns.push(
+ [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
+ }
+ var hc = options['hashComments'];
+ if (hc) {
+ if (options['cStyleComments']) {
+ if (hc > 1) { // multiline hash comments
+ shortcutStylePatterns.push(
+ [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
+ } else {
+ // Stop C preprocessor declarations at an unclosed open comment
+ shortcutStylePatterns.push(
+ [PR_COMMENT, /^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,
+ null, '#']);
+ }
+ // #include <stdio.h>
+ fallthroughStylePatterns.push(
+ [PR_STRING,
+ /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,
+ null]);
+ } else {
+ shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
+ }
+ }
+ if (options['cStyleComments']) {
+ fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
+ fallthroughStylePatterns.push(
+ [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
+ }
+ var regexLiterals = options['regexLiterals'];
+ if (regexLiterals) {
+ /**
+ * @const
+ */
+ var regexExcls = regexLiterals > 1
+ ? '' // Multiline regex literals
+ : '\n\r';
+ /**
+ * @const
+ */
+ var regexAny = regexExcls ? '.' : '[\\S\\s]';
+ /**
+ * @const
+ */
+ var REGEX_LITERAL = (
+ // A regular expression literal starts with a slash that is
+ // not followed by * or / so that it is not confused with
+ // comments.
+ '/(?=[^/*' + regexExcls + '])'
+ // and then contains any number of raw characters,
+ + '(?:[^/\\x5B\\x5C' + regexExcls + ']'
+ // escape sequences (\x5C),
+ + '|\\x5C' + regexAny
+ // or non-nesting character sets (\x5B\x5D);
+ + '|\\x5B(?:[^\\x5C\\x5D' + regexExcls + ']'
+ + '|\\x5C' + regexAny + ')*(?:\\x5D|$))+'
+ // finally closed by a /.
+ + '/');
+ fallthroughStylePatterns.push(
+ ['lang-regex',
+ RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
+ ]);
+ }
+
+ var types = options['types'];
+ if (types) {
+ fallthroughStylePatterns.push([PR_TYPE, types]);
+ }
+
+ var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
+ if (keywords.length) {
+ fallthroughStylePatterns.push(
+ [PR_KEYWORD,
+ new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
+ null]);
+ }
+
+ shortcutStylePatterns.push([PR_PLAIN, /^\s+/, null, ' \r\n\t\xA0']);
+
+ var punctuation =
+ // The Bash man page says
+
+ // A word is a sequence of characters considered as a single
+ // unit by GRUB. Words are separated by metacharacters,
+ // which are the following plus space, tab, and newline: { }
+ // | & $ ; < >
+ // ...
+
+ // A word beginning with # causes that word and all remaining
+ // characters on that line to be ignored.
+
+ // which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
+ // comment but empirically
+ // $ echo {#}
+ // {#}
+ // $ echo \$#
+ // $#
+ // $ echo }#
+ // }#
+
+ // so /(?:^|[|&;<>\s])/ is more appropriate.
+
+ // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
+ // suggests that this definition is compatible with a
+ // default mode that tries to use a single token definition
+ // to recognize both bash/python style comments and C
+ // preprocessor directives.
+
+ // This definition of punctuation does not include # in the list of
+ // follow-on exclusions, so # will not be broken before if preceeded
+ // by a punctuation character. We could try to exclude # after
+ // [|&;<>] but that doesn't seem to cause many major problems.
+ // If that does turn out to be a problem, we should change the below
+ // when hc is truthy to include # in the run of punctuation characters
+ // only when not followint [|&;<>].
+ '^.[^\\s\\w.$@\'"`/\\\\]*';
+ if (options['regexLiterals']) {
+ punctuation += '(?!\s*\/)';
+ }
+
+ fallthroughStylePatterns.push(
+ // TODO(mikesamuel): recognize non-latin letters and numerals in idents
+ [PR_LITERAL, /^@[a-z_$][a-z_$@0-9]*/i, null],
+ [PR_TYPE, /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
+ [PR_PLAIN, /^[a-z_$][a-z_$@0-9]*/i, null],
+ [PR_LITERAL,
+ new RegExp(
+ '^(?:'
+ // A hex number
+ + '0x[a-f0-9]+'
+ // or an octal or decimal number,
+ + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
+ // possibly in scientific notation
+ + '(?:e[+\\-]?\\d+)?'
+ + ')'
+ // with an optional modifier like UL for unsigned long
+ + '[a-z]*', 'i'),
+ null, '0123456789'],
+ // Don't treat escaped quotes in bash as starting strings.
+ // See issue 144.
+ [PR_PLAIN, /^\\[\s\S]?/, null],
+ [PR_PUNCTUATION, new RegExp(punctuation), null]);
+
+ return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
+ }
+
+ var decorateSource = sourceDecorator({
+ 'keywords': ALL_KEYWORDS,
+ 'hashComments': true,
+ 'cStyleComments': true,
+ 'multiLineStrings': true,
+ 'regexLiterals': true
+ });
+
+ /**
+ * Given a DOM subtree, wraps it in a list, and puts each line into its own
+ * list item.
+ *
+ * @param {Node} node modified in place. Its content is pulled into an
+ * HTMLOListElement, and each line is moved into a separate list item.
+ * This requires cloning elements, so the input might not have unique
+ * IDs after numbering.
+ * @param {boolean} isPreformatted true iff white-space in text nodes should
+ * be treated as significant.
+ */
+ function numberLines(node, opt_startLineNum, isPreformatted) {
+ var nocode = /(?:^|\s)nocode(?:\s|$)/;
+ var lineBreak = /\r\n?|\n/;
+
+ var document = node.ownerDocument;
+
+ var li = document.createElement('li');
+ while (node.firstChild) {
+ li.appendChild(node.firstChild);
+ }
+ // An array of lines. We split below, so this is initialized to one
+ // un-split line.
+ var listItems = [li];
+
+ function walk(node) {
+ var type = node.nodeType;
+ if (type == 1 && !nocode.test(node.className)) { // Element
+ if ('br' === node.nodeName) {
+ breakAfter(node);
+ // Discard the <BR> since it is now flush against a </LI>.
+ if (node.parentNode) {
+ node.parentNode.removeChild(node);
+ }
+ } else {
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ walk(child);
+ }
+ }
+ } else if ((type == 3 || type == 4) && isPreformatted) { // Text
+ var text = node.nodeValue;
+ var match = text.match(lineBreak);
+ if (match) {
+ var firstLine = text.substring(0, match.index);
+ node.nodeValue = firstLine;
+ var tail = text.substring(match.index + match[0].length);
+ if (tail) {
+ var parent = node.parentNode;
+ parent.insertBefore(
+ document.createTextNode(tail), node.nextSibling);
+ }
+ breakAfter(node);
+ if (!firstLine) {
+ // Don't leave blank text nodes in the DOM.
+ node.parentNode.removeChild(node);
+ }
+ }
+ }
+ }
+
+ // Split a line after the given node.
+ function breakAfter(lineEndNode) {
+ // If there's nothing to the right, then we can skip ending the line
+ // here, and move root-wards since splitting just before an end-tag
+ // would require us to create a bunch of empty copies.
+ while (!lineEndNode.nextSibling) {
+ lineEndNode = lineEndNode.parentNode;
+ if (!lineEndNode) { return; }
+ }
+
+ function breakLeftOf(limit, copy) {
+ // Clone shallowly if this node needs to be on both sides of the break.
+ var rightSide = copy ? limit.cloneNode(false) : limit;
+ var parent = limit.parentNode;
+ if (parent) {
+ // We clone the parent chain.
+ // This helps us resurrect important styling elements that cross lines.
+ // E.g. in <i>Foo<br>Bar</i>
+ // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
+ var parentClone = breakLeftOf(parent, 1);
+ // Move the clone and everything to the right of the original
+ // onto the cloned parent.
+ var next = limit.nextSibling;
+ parentClone.appendChild(rightSide);
+ for (var sibling = next; sibling; sibling = next) {
+ next = sibling.nextSibling;
+ parentClone.appendChild(sibling);
+ }
+ }
+ return rightSide;
+ }
+
+ var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
+
+ // Walk the parent chain until we reach an unattached LI.
+ for (var parent;
+ // Check nodeType since IE invents document fragments.
+ (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
+ copiedListItem = parent;
+ }
+ // Put it on the list of lines for later processing.
+ listItems.push(copiedListItem);
+ }
+
+ // Split lines while there are lines left to split.
+ for (var i = 0; // Number of lines that have been split so far.
+ i < listItems.length; // length updated by breakAfter calls.
+ ++i) {
+ walk(listItems[i]);
+ }
+
+ // Make sure numeric indices show correctly.
+ if (opt_startLineNum === (opt_startLineNum|0)) {
+ listItems[0].setAttribute('value', opt_startLineNum);
+ }
+
+ var ol = document.createElement('ol');
+ ol.className = 'linenums';
+ var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
+ for (var i = 0, n = listItems.length; i < n; ++i) {
+ li = listItems[i];
+ // Stick a class on the LIs so that stylesheets can
+ // color odd/even rows, or any other row pattern that
+ // is co-prime with 10.
+ li.className = 'L' + ((i + offset) % 10);
+ if (!li.firstChild) {
+ li.appendChild(document.createTextNode('\xA0'));
+ }
+ ol.appendChild(li);
+ }
+
+ node.appendChild(ol);
+ }
+ /**
+ * Breaks {@code job.sourceCode} around style boundaries in
+ * {@code job.decorations} and modifies {@code job.sourceNode} in place.
+ * @param {Object} job like <pre>{
+ * sourceCode: {string} source as plain text,
+ * sourceNode: {HTMLElement} the element containing the source,
+ * spans: {Array.<number|Node>} alternating span start indices into source
+ * and the text node or element (e.g. {@code <BR>}) corresponding to that
+ * span.
+ * decorations: {Array.<number|string} an array of style classes preceded
+ * by the position at which they start in job.sourceCode in order
+ * }</pre>
+ * @private
+ */
+ function recombineTagsAndDecorations(job) {
+ var isIE8OrEarlier = /\bMSIE\s(\d+)/.exec(navigator.userAgent);
+ isIE8OrEarlier = isIE8OrEarlier && +isIE8OrEarlier[1] <= 8;
+ var newlineRe = /\n/g;
+
+ var source = job.sourceCode;
+ var sourceLength = source.length;
+ // Index into source after the last code-unit recombined.
+ var sourceIndex = 0;
+
+ var spans = job.spans;
+ var nSpans = spans.length;
+ // Index into spans after the last span which ends at or before sourceIndex.
+ var spanIndex = 0;
+
+ var decorations = job.decorations;
+ var nDecorations = decorations.length;
+ // Index into decorations after the last decoration which ends at or before
+ // sourceIndex.
+ var decorationIndex = 0;
+
+ // Remove all zero-length decorations.
+ decorations[nDecorations] = sourceLength;
+ var decPos, i;
+ for (i = decPos = 0; i < nDecorations;) {
+ if (decorations[i] !== decorations[i + 2]) {
+ decorations[decPos++] = decorations[i++];
+ decorations[decPos++] = decorations[i++];
+ } else {
+ i += 2;
+ }
+ }
+ nDecorations = decPos;
+
+ // Simplify decorations.
+ for (i = decPos = 0; i < nDecorations;) {
+ var startPos = decorations[i];
+ // Conflate all adjacent decorations that use the same style.
+ var startDec = decorations[i + 1];
+ var end = i + 2;
+ while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
+ end += 2;
+ }
+ decorations[decPos++] = startPos;
+ decorations[decPos++] = startDec;
+ i = end;
+ }
+
+ nDecorations = decorations.length = decPos;
+
+ var sourceNode = job.sourceNode;
+ var oldDisplay;
+ if (sourceNode) {
+ oldDisplay = sourceNode.style.display;
+ sourceNode.style.display = 'none';
+ }
+ try {
+ var decoration = null;
+ while (spanIndex < nSpans) {
+ var spanStart = spans[spanIndex];
+ var spanEnd = spans[spanIndex + 2] || sourceLength;
+
+ var decEnd = decorations[decorationIndex + 2] || sourceLength;
+
+ var end = Math.min(spanEnd, decEnd);
+
+ var textNode = spans[spanIndex + 1];
+ var styledText;
+ if (textNode.nodeType !== 1 // Don't muck with <BR>s or <LI>s
+ // Don't introduce spans around empty text nodes.
+ && (styledText = source.substring(sourceIndex, end))) {
+ // This may seem bizarre, and it is. Emitting LF on IE causes the
+ // code to display with spaces instead of line breaks.
+ // Emitting Windows standard issue linebreaks (CRLF) causes a blank
+ // space to appear at the beginning of every line but the first.
+ // Emitting an old Mac OS 9 line separator makes everything spiffy.
+ if (isIE8OrEarlier) {
+ styledText = styledText.replace(newlineRe, '\r');
+ }
+ textNode.nodeValue = styledText;
+ var document = textNode.ownerDocument;
+ var span = document.createElement('span');
+ span.className = decorations[decorationIndex + 1];
+ var parentNode = textNode.parentNode;
+ parentNode.replaceChild(span, textNode);
+ span.appendChild(textNode);
+ if (sourceIndex < spanEnd) { // Split off a text node.
+ spans[spanIndex + 1] = textNode
+ // TODO: Possibly optimize by using '' if there's no flicker.
+ = document.createTextNode(source.substring(end, spanEnd));
+ parentNode.insertBefore(textNode, span.nextSibling);
+ }
+ }
+
+ sourceIndex = end;
+
+ if (sourceIndex >= spanEnd) {
+ spanIndex += 2;
+ }
+ if (sourceIndex >= decEnd) {
+ decorationIndex += 2;
+ }
+ }
+ } finally {
+ if (sourceNode) {
+ sourceNode.style.display = oldDisplay;
+ }
+ }
+ }
+
+ /** Maps language-specific file extensions to handlers. */
+ var langHandlerRegistry = {};
+ /** Register a language handler for the given file extensions.
+ * @param {function (Object)} handler a function from source code to a list
+ * of decorations. Takes a single argument job which describes the
+ * state of the computation. The single parameter has the form
+ * {@code {
+ * sourceCode: {string} as plain text.
+ * decorations: {Array.<number|string>} an array of style classes
+ * preceded by the position at which they start in
+ * job.sourceCode in order.
+ * The language handler should assigned this field.
+ * basePos: {int} the position of source in the larger source chunk.
+ * All positions in the output decorations array are relative
+ * to the larger source chunk.
+ * } }
+ * @param {Array.<string>} fileExtensions
+ */
+ function registerLangHandler(handler, fileExtensions) {
+ for (var i = fileExtensions.length; --i >= 0;) {
+ var ext = fileExtensions[i];
+ if (!langHandlerRegistry.hasOwnProperty(ext)) {
+ langHandlerRegistry[ext] = handler;
+ } else if (win['console']) {
+ console['warn']('cannot override language handler %s', ext);
+ }
+ }
+ }
+ function langHandlerForExtension(extension, source) {
+ if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
+ // Treat it as markup if the first non whitespace character is a < and
+ // the last non-whitespace character is a >.
+ extension = /^\s*</.test(source)
+ ? 'default-markup'
+ : 'default-code';
+ }
+ return langHandlerRegistry[extension];
+ }
+ registerLangHandler(decorateSource, ['default-code']);
+ registerLangHandler(
+ createSimpleLexer(
+ [],
+ [
+ [PR_PLAIN, /^[^<?]+/],
+ [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
+ [PR_COMMENT, /^<\!--[\s\S]*?(?:-\->|$)/],
+ // Unescaped content in an unknown language
+ ['lang-', /^<\?([\s\S]+?)(?:\?>|$)/],
+ ['lang-', /^<%([\s\S]+?)(?:%>|$)/],
+ [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
+ ['lang-', /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
+ // Unescaped content in javascript. (Or possibly vbscript).
+ ['lang-js', /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
+ // Contains unescaped stylesheet content
+ ['lang-css', /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
+ ['lang-in.tag', /^(<\/?[a-z][^<>]*>)/i]
+ ]),
+ ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
+ registerLangHandler(
+ createSimpleLexer(
+ [
+ [PR_PLAIN, /^[\s]+/, null, ' \t\r\n'],
+ [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
+ ],
+ [
+ [PR_TAG, /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
+ [PR_ATTRIB_NAME, /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
+ ['lang-uq.val', /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
+ [PR_PUNCTUATION, /^[=<>\/]+/],
+ ['lang-js', /^on\w+\s*=\s*\"([^\"]+)\"/i],
+ ['lang-js', /^on\w+\s*=\s*\'([^\']+)\'/i],
+ ['lang-js', /^on\w+\s*=\s*([^\"\'>\s]+)/i],
+ ['lang-css', /^style\s*=\s*\"([^\"]+)\"/i],
+ ['lang-css', /^style\s*=\s*\'([^\']+)\'/i],
+ ['lang-css', /^style\s*=\s*([^\"\'>\s]+)/i]
+ ]),
+ ['in.tag']);
+ registerLangHandler(
+ createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': CPP_KEYWORDS,
+ 'hashComments': true,
+ 'cStyleComments': true,
+ 'types': C_TYPES
+ }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': 'null,true,false'
+ }), ['json']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': CSHARP_KEYWORDS,
+ 'hashComments': true,
+ 'cStyleComments': true,
+ 'verbatimStrings': true,
+ 'types': C_TYPES
+ }), ['cs']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': JAVA_KEYWORDS,
+ 'cStyleComments': true
+ }), ['java']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': SH_KEYWORDS,
+ 'hashComments': true,
+ 'multiLineStrings': true
+ }), ['bash', 'bsh', 'csh', 'sh']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': PYTHON_KEYWORDS,
+ 'hashComments': true,
+ 'multiLineStrings': true,
+ 'tripleQuotedStrings': true
+ }), ['cv', 'py', 'python']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': PERL_KEYWORDS,
+ 'hashComments': true,
+ 'multiLineStrings': true,
+ 'regexLiterals': 2 // multiline regex literals
+ }), ['perl', 'pl', 'pm']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': RUBY_KEYWORDS,
+ 'hashComments': true,
+ 'multiLineStrings': true,
+ 'regexLiterals': true
+ }), ['rb', 'ruby']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': JSCRIPT_KEYWORDS,
+ 'cStyleComments': true,
+ 'regexLiterals': true
+ }), ['javascript', 'js']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': COFFEE_KEYWORDS,
+ 'hashComments': 3, // ### style block comments
+ 'cStyleComments': true,
+ 'multilineStrings': true,
+ 'tripleQuotedStrings': true,
+ 'regexLiterals': true
+ }), ['coffee']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': RUST_KEYWORDS,
+ 'cStyleComments': true,
+ 'multilineStrings': true
+ }), ['rc', 'rs', 'rust']);
+ registerLangHandler(
+ createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
+
+ function applyDecorator(job) {
+ var opt_langExtension = job.langExtension;
+
+ try {
+ // Extract tags, and convert the source code to plain text.
+ var sourceAndSpans = extractSourceSpans(job.sourceNode, job.pre);
+ /** Plain text. @type {string} */
+ var source = sourceAndSpans.sourceCode;
+ job.sourceCode = source;
+ job.spans = sourceAndSpans.spans;
+ job.basePos = 0;
+
+ // Apply the appropriate language handler
+ langHandlerForExtension(opt_langExtension, source)(job);
+
+ // Integrate the decorations and tags back into the source code,
+ // modifying the sourceNode in place.
+ recombineTagsAndDecorations(job);
+ } catch (e) {
+ if (win['console']) {
+ console['log'](e && e['stack'] || e);
+ }
+ }
+ }
+
+ /**
+ * Pretty print a chunk of code.
+ * @param sourceCodeHtml {string} The HTML to pretty print.
+ * @param opt_langExtension {string} The language name to use.
+ * Typically, a filename extension like 'cpp' or 'java'.
+ * @param opt_numberLines {number|boolean} True to number lines,
+ * or the 1-indexed number of the first line in sourceCodeHtml.
+ */
+ function $prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
+ var container = document.createElement('div');
+ // This could cause images to load and onload listeners to fire.
+ // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
+ // We assume that the inner HTML is from a trusted source.
+ // The pre-tag is required for IE8 which strips newlines from innerHTML
+ // when it is injected into a <pre> tag.
+ // http://stackoverflow.com/questions/451486/pre-tag-loses-line-breaks-when-setting-innerhtml-in-ie
+ // http://stackoverflow.com/questions/195363/inserting-a-newline-into-a-pre-tag-ie-javascript
+ container.innerHTML = '<pre>' + sourceCodeHtml + '</pre>';
+ container = container.firstChild;
+ if (opt_numberLines) {
+ numberLines(container, opt_numberLines, true);
+ }
+
+ var job = {
+ langExtension: opt_langExtension,
+ numberLines: opt_numberLines,
+ sourceNode: container,
+ pre: 1
+ };
+ applyDecorator(job);
+ return container.innerHTML;
+ }
+
+ /**
+ * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
+ * {@code class=prettyprint} and prettify them.
+ *
+ * @param {Function} opt_whenDone called when prettifying is done.
+ * @param {HTMLElement|HTMLDocument} opt_root an element or document
+ * containing all the elements to pretty print.
+ * Defaults to {@code document.body}.
+ */
+ function $prettyPrint(opt_whenDone, opt_root) {
+ var root = opt_root || document.body;
+ var doc = root.ownerDocument || document;
+ function byTagName(tn) { return root.getElementsByTagName(tn); }
+ // fetch a list of nodes to rewrite
+ var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
+ var elements = [];
+ for (var i = 0; i < codeSegments.length; ++i) {
+ for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
+ elements.push(codeSegments[i][j]);
+ }
+ }
+ codeSegments = null;
+
+ var clock = Date;
+ if (!clock['now']) {
+ clock = { 'now': function () { return +(new Date); } };
+ }
+
+ // The loop is broken into a series of continuations to make sure that we
+ // don't make the browser unresponsive when rewriting a large page.
+ var k = 0;
+ var prettyPrintingJob;
+
+ var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
+ var prettyPrintRe = /\bprettyprint\b/;
+ var prettyPrintedRe = /\bprettyprinted\b/;
+ var preformattedTagNameRe = /pre|xmp/i;
+ var codeRe = /^code$/i;
+ var preCodeXmpRe = /^(?:pre|code|xmp)$/i;
+ var EMPTY = {};
+
+ function doWork() {
+ var endTime = (win['PR_SHOULD_USE_CONTINUATION'] ?
+ clock['now']() + 250 /* ms */ :
+ Infinity);
+ for (; k < elements.length && clock['now']() < endTime; k++) {
+ var cs = elements[k];
+
+ // Look for a preceding comment like
+ // <?prettify lang="..." linenums="..."?>
+ var attrs = EMPTY;
+ {
+ for (var preceder = cs; (preceder = preceder.previousSibling);) {
+ var nt = preceder.nodeType;
+ // <?foo?> is parsed by HTML 5 to a comment node (8)
+ // like <!--?foo?-->, but in XML is a processing instruction
+ var value = (nt === 7 || nt === 8) && preceder.nodeValue;
+ if (value
+ ? !/^\??prettify\b/.test(value)
+ : (nt !== 3 || /\S/.test(preceder.nodeValue))) {
+ // Skip over white-space text nodes but not others.
+ break;
+ }
+ if (value) {
+ attrs = {};
+ value.replace(
+ /\b(\w+)=([\w:.%+-]+)/g,
+ function (_, name, value) { attrs[name] = value; });
+ break;
+ }
+ }
+ }
+
+ var className = cs.className;
+ if ((attrs !== EMPTY || prettyPrintRe.test(className))
+ // Don't redo this if we've already done it.
+ // This allows recalling pretty print to just prettyprint elements
+ // that have been added to the page since last call.
+ && !prettyPrintedRe.test(className)) {
+
+ // make sure this is not nested in an already prettified element
+ var nested = false;
+ for (var p = cs.parentNode; p; p = p.parentNode) {
+ var tn = p.tagName;
+ if (preCodeXmpRe.test(tn)
+ && p.className && prettyPrintRe.test(p.className)) {
+ nested = true;
+ break;
+ }
+ }
+ if (!nested) {
+ // Mark done. If we fail to prettyprint for whatever reason,
+ // we shouldn't try again.
+ cs.className += ' prettyprinted';
+
+ // If the classes includes a language extensions, use it.
+ // Language extensions can be specified like
+ // <pre class="prettyprint lang-cpp">
+ // the language extension "cpp" is used to find a language handler
+ // as passed to PR.registerLangHandler.
+ // HTML5 recommends that a language be specified using "language-"
+ // as the prefix instead. Google Code Prettify supports both.
+ // http://dev.w3.org/html5/spec-author-view/the-code-element.html
+ var langExtension = attrs['lang'];
+ if (!langExtension) {
+ langExtension = className.match(langExtensionRe);
+ // Support <pre class="prettyprint"><code class="language-c">
+ var wrapper;
+ if (!langExtension && (wrapper = childContentWrapper(cs))
+ && codeRe.test(wrapper.tagName)) {
+ langExtension = wrapper.className.match(langExtensionRe);
+ }
+
+ if (langExtension) { langExtension = langExtension[1]; }
+ }
+
+ var preformatted;
+ if (preformattedTagNameRe.test(cs.tagName)) {
+ preformatted = 1;
+ } else {
+ var currentStyle = cs['currentStyle'];
+ var defaultView = doc.defaultView;
+ var whitespace = (
+ currentStyle
+ ? currentStyle['whiteSpace']
+ : (defaultView
+ && defaultView.getComputedStyle)
+ ? defaultView.getComputedStyle(cs, null)
+ .getPropertyValue('white-space')
+ : 0);
+ preformatted = whitespace
+ && 'pre' === whitespace.substring(0, 3);
+ }
+
+ // Look for a class like linenums or linenums:<n> where <n> is the
+ // 1-indexed number of the first line.
+ var lineNums = attrs['linenums'];
+ if (!(lineNums = lineNums === 'true' || +lineNums)) {
+ lineNums = className.match(/\blinenums\b(?::(\d+))?/);
+ lineNums =
+ lineNums
+ ? lineNums[1] && lineNums[1].length
+ ? +lineNums[1] : true
+ : false;
+ }
+ if (lineNums) { numberLines(cs, lineNums, preformatted); }
+
+ // do the pretty printing
+ prettyPrintingJob = {
+ langExtension: langExtension,
+ sourceNode: cs,
+ numberLines: lineNums,
+ pre: preformatted
+ };
+ applyDecorator(prettyPrintingJob);
+ }
+ }
+ }
+ if (k < elements.length) {
+ // finish up in a continuation
+ setTimeout(doWork, 250);
+ } else if ('function' === typeof opt_whenDone) {
+ opt_whenDone();
+ }
+ }
+
+ doWork();
+ }
+
+ /**
+ * Contains functions for creating and registering new language handlers.
+ * @type {Object}
+ */
+ var PR = win['PR'] = {
+ 'createSimpleLexer': createSimpleLexer,
+ 'registerLangHandler': registerLangHandler,
+ 'sourceDecorator': sourceDecorator,
+ 'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
+ 'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
+ 'PR_COMMENT': PR_COMMENT,
+ 'PR_DECLARATION': PR_DECLARATION,
+ 'PR_KEYWORD': PR_KEYWORD,
+ 'PR_LITERAL': PR_LITERAL,
+ 'PR_NOCODE': PR_NOCODE,
+ 'PR_PLAIN': PR_PLAIN,
+ 'PR_PUNCTUATION': PR_PUNCTUATION,
+ 'PR_SOURCE': PR_SOURCE,
+ 'PR_STRING': PR_STRING,
+ 'PR_TAG': PR_TAG,
+ 'PR_TYPE': PR_TYPE,
+ 'prettyPrintOne':
+ IN_GLOBAL_SCOPE
+ ? (win['prettyPrintOne'] = $prettyPrintOne)
+ : (prettyPrintOne = $prettyPrintOne),
+ 'prettyPrint': prettyPrint =
+ IN_GLOBAL_SCOPE
+ ? (win['prettyPrint'] = $prettyPrint)
+ : (prettyPrint = $prettyPrint)
+ };
+
+ // Make PR available via the Asynchronous Module Definition (AMD) API.
+ // Per https://github.com/amdjs/amdjs-api/wiki/AMD:
+ // The Asynchronous Module Definition (AMD) API specifies a
+ // mechanism for defining modules such that the module and its
+ // dependencies can be asynchronously loaded.
+ // ...
+ // To allow a clear indicator that a global define function (as
+ // needed for script src browser loading) conforms to the AMD API,
+ // any global define function SHOULD have a property called "amd"
+ // whose value is an object. This helps avoid conflict with any
+ // other existing JavaScript code that could have defined a define()
+ // function that does not conform to the AMD API.
+ if (typeof define === "function" && define['amd']) {
+ define("google-code-prettify", [], function () {
+ return PR;
+ });
+ }
+})();
diff --git a/js/quick-post-controls.js b/js/quick-post-controls.js
index 10d74f98..62dfa1e0 100644
--- a/js/quick-post-controls.js
+++ b/js/quick-post-controls.js
@@ -39,10 +39,20 @@ $(document).ready(function(){
' <input type="submit" name="report" value="'+_('Report')+'">' +
'</div>' +
'</form>');
- post_form
+ if($('form[name="post"]:first').size()){
+ post_form
.attr('action', $('form[name="post"]:first').attr('action'))
- .append($('input[name=board]:first').clone())
- .find('input:not([type="checkbox"]):not([type="submit"]):not([type="hidden"])').keypress(function(e) {
+ .append($('input[name=board]:first').clone());
+ }else{
+ var board=$(this).parent().parent().parent().attr("data-board");
+ if(board){
+ post_form.attr('action', '/post.php'); //doesn't respect $config["root"] but...
+ post_form.append('<input type="hidden" value="'+board+'" name="board" />');
+ }else{
+ return;//better not to show a form if it isn't going to work
+ }
+ }
+ post_form.find('input:not([type="checkbox"]):not([type="submit"]):not([type="hidden"])').keypress(function(e) {
if(e.which == 13) {
e.preventDefault();
if($(this).attr('name') == 'password') {
diff --git a/js/quick-reply.js b/js/quick-reply.js
index 408de410..f31af6af 100644
--- a/js/quick-reply.js
+++ b/js/quick-reply.js
@@ -99,9 +99,6 @@
#quick-reply .nonsense {\
display: none;\
}\
- #quick-reply td.submit {\
- width: 1%;\
- }\
#quick-reply td.recaptcha {\
text-align: center;\
padding: 0 0 1px 0;\
diff --git a/js/rules-popup.js b/js/rules-popup.js
new file mode 100644
index 00000000..36261b45
--- /dev/null
+++ b/js/rules-popup.js
@@ -0,0 +1,44 @@
+/*
+ * rules-popup.js
+ * https://github.com/mkwia/lainchan/js/rules-popup.js
+ *
+ * Forces user to accept rules from /templates/rules.html on first welcome
+ *
+ * 2016 mkwia <github.com/mkwia>
+ *
+ * Usage:
+ * $config['additional_javascript'][] = 'js/jquery.min.js';
+ * $config['additional_javascript'][] = 'js/rules-popup.js';
+ *
+ */
+
+$(window).ready(function() {
+ if (typeof localStorage.rulesAccepted === "undefined") {
+
+ // generate a 7-character long random string
+ captcha = Math.random().toString(36).substring(2, 9)
+
+ $("body")
+ .prepend("<div id='rules-popup'>");
+
+ $("#rules-popup")
+ .append("<div class='rules-popup-top'>lainchan rule agreement</div>")
+ .append("<div class='rules-popup-content-wrapper'></div>")
+ .append("<div class='rules-popup-bottom'></div>");
+
+ $(".rules-popup-content-wrapper")
+ .append("<div id='rules-popup-content'></div>");
+ $("#rules-popup-content")
+ .load("/templates/rules.html");
+
+ $(".rules-popup-bottom")
+ .append("<div class='rules-popup-bottom-instructions'>If you accept the rules, retype the captcha and press ACCEPT.</div>")
+ .append("<div class='rules-popup-captcha-wrapper'></div>");
+ $(".rules-popup-captcha-wrapper")
+ .append("<div class='rules-popup-captcha'>" + captcha + "</div>")
+ .append("<form class='rules-popup-form' onsubmit=\"if ($('#captcha').val() == '" + captcha + "') { localStorage.rulesAccepted = 1; $('#rules-popup').remove(); } return false;\"></form>");
+ $(".rules-popup-form")
+ .append("<input class='rules-popup-form-input' type='text' id='captcha' />")
+ .append("<input type='submit' value='ACCEPT' />");
+ }
+})
diff --git a/js/style-select.js b/js/style-select.js
index f0fe3c16..e9d395f0 100644
--- a/js/style-select.js
+++ b/js/style-select.js
@@ -16,6 +16,7 @@
onready(function(){
var stylesDiv = $('div.styles');
+ var pages = $('div.pages');
var stylesSelect = $('<select></select>');
var i = 1;
@@ -34,11 +35,10 @@ onready(function(){
$('#style-select-' + $(this).val()).click();
});
- stylesDiv.hide();
-
- stylesDiv.after(
- $('<div id="style-select" style="float:right;margin-bottom:10px"></div>')
- .text(_('Style: '))
+ stylesDiv.hide()
+ pages.after(
+ $('<div id="style-select"></div>')
+ /*.text(_('Style: '))*/
.append(stylesSelect)
);
});
diff --git a/js/thread-stats.js b/js/thread-stats.js
index 8873dbdb..5785c9f3 100644
--- a/js/thread-stats.js
+++ b/js/thread-stats.js
@@ -12,18 +12,17 @@ $(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];
+ thread_id = thread_id[thread_id.length -1].split('+')[0].split('.')[0];
- $('.boardlist.bottom, footer')
- .first()
- .before('<div id="thread_stats"></div>');
+ $('#thread-links')
+ .after('<div id="thread_stats"></div>');
var el = $('#thread_stats');
- el.prepend(_('Page')+' <span id="thread_stats_page">?</span>');
+ 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;');
+ 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();
@@ -67,7 +66,6 @@ $(document).ready(function(){
};
$('#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++){
@@ -89,7 +87,6 @@ $(document).ready(function(){
// 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++){
@@ -113,4 +110,4 @@ $(document).ready(function(){
$('#update_thread').click(update_thread_stats);
$(document).on('new_post',update_thread_stats);
});
-}
+} \ No newline at end of file
diff --git a/js/wPaint b/js/wPaint
-Subproject f11220032e7edb8349516d3751d3aaee0fd0de6
+Subproject 2c272dffca0f3d7b7163bd82ba15629f5440927
diff --git a/lam b/lam
new file mode 120000
index 00000000..b2d15950
--- /dev/null
+++ b/lam
@@ -0,0 +1 @@
+λ \ No newline at end of file
diff --git a/layer03 b/layer03
new file mode 120000
index 00000000..f1c32abd
--- /dev/null
+++ b/layer03
@@ -0,0 +1 @@
+layer \ No newline at end of file
diff --git a/mod.php b/mod.php
index 0378d55c..b282b8ca 100644
--- a/mod.php
+++ b/mod.php
@@ -16,6 +16,12 @@ check_login(true);
$query = isset($_SERVER['QUERY_STRING']) ? rawurldecode($_SERVER['QUERY_STRING']) : '';
+// If there's a thread parameter (eg, for returning to after enacting a ban)
+// drop it from the $query.
+if(isset($_GET['thread'])) {
+ $query = explode("&thread=", $query)[0];
+}
+
$pages = array(
'' => ':?/', // redirect to dashboard
'/' => 'dashboard', // dashboard
diff --git a/post.php b/post.php
index 47c5f0ef..070cbd88 100644
--- a/post.php
+++ b/post.php
@@ -7,7 +7,19 @@ require_once 'inc/functions.php';
require_once 'inc/anti-bot.php';
require_once 'inc/bans.php';
-if ((!isset($_POST['mod']) || !$_POST['mod']) && $config['board_locked']) {
+// Fix for magic quotes
+if (get_magic_quotes_gpc()) {
+ function strip_array($var) {
+ return is_array($var) ? array_map('strip_array', $var) : stripslashes($var);
+ }
+
+ $_GET = strip_array($_GET);
+ $_POST = strip_array($_POST);
+}
+
+if ((!isset($_POST['mod']) || !$_POST['mod'])
+ && ($config['board_locked']===true
+ || (is_array($config['board_locked']) && in_array(strtolower($_POST['board']), $config['board_locked'])))){
error("Board is locked");
}
@@ -312,15 +324,15 @@ if (isset($_POST['delete'])) {
markup($reason);
foreach ($report as &$id) {
- $query = prepare(sprintf("SELECT `id`, `thread` FROM ``posts_%s`` WHERE `id` = :id", $board['uri']));
+ $query = prepare(sprintf("SELECT `id`,`thread` , `body_nomarkup` FROM ``posts_%s`` WHERE `id` = :id", $board['uri']));
$query->bindValue(':id', $id, PDO::PARAM_INT);
$query->execute() or error(db_error($query));
- $post = $query->fetch(PDO::FETCH_ASSOC);
+ $thread = $query->fetch(PDO::FETCH_ASSOC);
if ($config['syslog'])
_syslog(LOG_INFO, 'Reported post: ' .
- '/' . $board['dir'] . $config['dir']['res'] . link_for($post) . ($post['thread'] ? '#' . $id : '') .
+ '/' . $board['dir'] . $config['dir']['res'] . link_for($post) . ($thread['thread'] ? '#' . $id : '') .
' for "' . $reason . '"'
);
$query = prepare("INSERT INTO ``reports`` VALUES (NULL, :time, :ip, :board, :post, :reason)");
@@ -330,6 +342,38 @@ if (isset($_POST['delete'])) {
$query->bindValue(':post', $id, PDO::PARAM_INT);
$query->bindValue(':reason', $reason, PDO::PARAM_STR);
$query->execute() or error(db_error($query));
+ if ($config['slack'])
+ {
+ function slack($message, $room = "reports", $icon = ":no_entry_sign:")
+ {
+ $room = ($room) ? $room : "reports";
+ $data = "payload=" . json_encode(array(
+ "channel" => "#{$room}",
+ "text" => urlencode($message),
+ "icon_emoji" => $icon
+ ));
+
+ // You can get your webhook endpoint from your Slack settings
+ // For some reason using the configuration key doesn't work
+ //$ch = curl_init($config['slack_incoming_webhook_endpoint']);
+ $ch = curl_init("https://hooks.slack.com/services/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");
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ $result = curl_exec($ch);
+ curl_close($ch);
+
+ return $result;
+ }
+
+ $postcontent = mb_substr($thread['body_nomarkup'], 0, 120) . '... _*(POST TRIMMED)*_';
+ $slackmessage = '<' .$config['domain'] . "/mod.php?/" . $board['dir'] . $config['dir']['res'] . ( $thread['thread'] ? $thread['thread'] : $id ) . ".html" . ($thread['thread'] ? '#' . $id : '') . '> \n ' . $reason . '\n ' . $postcontent . '\n';
+
+ $slackresult = slack($slackmessage, $config['slack_channel']);
+ }
+
+
}
$is_mod = isset($_POST['mod']) && $_POST['mod'];
diff --git a/robots.txt b/robots.txt
new file mode 100644
index 00000000..1f53798b
--- /dev/null
+++ b/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
diff --git a/static/.gitignore b/static/.gitignore
new file mode 100644
index 00000000..449752e3
--- /dev/null
+++ b/static/.gitignore
@@ -0,0 +1,33 @@
+*
+!.gitignore
+!403.jpg
+!blank.gif
+!btc.jpg
+!collapse.gif
+!congrats.swf
+!cyberia.ogg
+!d10.svg
+!deleted.png
+!duvet.mp3
+!duvet.ogg
+!file.png
+!flags/
+!html.png
+!lain.mp3.m3u
+!lain.ogg.m3u
+!lain_2_090.jpg
+!lain_epup.jpg
+!lain_is_cute_datass_small.png
+!lain_is_cute_datass_small_teal.png
+!locked.gif
+!nginx.png
+!partyhat.gif
+!pdf.jpg
+!slack_for_ios_upload.jpg
+!spoiler.png
+!ssl.png
+!system.gif
+!ubuntu.png
+!video.png
+!zine_ipad.png
+!zip.png
diff --git a/static/403.jpg b/static/403.jpg
new file mode 100644
index 00000000..424a82c3
--- /dev/null
+++ b/static/403.jpg
Binary files differ
diff --git a/static/btc.jpg b/static/btc.jpg
new file mode 100644
index 00000000..dd76df27
--- /dev/null
+++ b/static/btc.jpg
Binary files differ
diff --git a/static/congrats.swf b/static/congrats.swf
new file mode 100644
index 00000000..da2bbc86
--- /dev/null
+++ b/static/congrats.swf
Binary files differ
diff --git a/static/cyberia.ogg b/static/cyberia.ogg
new file mode 100644
index 00000000..731fd5e3
--- /dev/null
+++ b/static/cyberia.ogg
Binary files differ
diff --git a/static/duvet.mp3 b/static/duvet.mp3
new file mode 100644
index 00000000..6932c97d
--- /dev/null
+++ b/static/duvet.mp3
Binary files differ
diff --git a/static/duvet.ogg b/static/duvet.ogg
new file mode 100644
index 00000000..23ef6ca4
--- /dev/null
+++ b/static/duvet.ogg
Binary files differ
diff --git a/static/html.png b/static/html.png
new file mode 100755
index 00000000..a2744d42
--- /dev/null
+++ b/static/html.png
Binary files differ
diff --git a/static/lain.mp3.m3u b/static/lain.mp3.m3u
new file mode 100644
index 00000000..bd7a7bb3
--- /dev/null
+++ b/static/lain.mp3.m3u
@@ -0,0 +1 @@
+http://lainchan.org:8000/lain.mp3
diff --git a/static/lain.ogg.m3u b/static/lain.ogg.m3u
new file mode 100644
index 00000000..cc310268
--- /dev/null
+++ b/static/lain.ogg.m3u
@@ -0,0 +1 @@
+http://lainchan.org:8000/lain.ogg
diff --git a/static/lain_2_090.jpg b/static/lain_2_090.jpg
new file mode 100644
index 00000000..81b97e19
--- /dev/null
+++ b/static/lain_2_090.jpg
Binary files differ
diff --git a/static/lain_epup.jpg b/static/lain_epup.jpg
new file mode 100644
index 00000000..9a504e78
--- /dev/null
+++ b/static/lain_epup.jpg
Binary files differ
diff --git a/static/lain_is_cute_datass_small.png b/static/lain_is_cute_datass_small.png
new file mode 100644
index 00000000..ed1d7e84
--- /dev/null
+++ b/static/lain_is_cute_datass_small.png
Binary files differ
diff --git a/static/lain_is_cute_datass_small_teal.png b/static/lain_is_cute_datass_small_teal.png
new file mode 100644
index 00000000..ed1d7e84
--- /dev/null
+++ b/static/lain_is_cute_datass_small_teal.png
Binary files differ
diff --git a/static/nginx.png b/static/nginx.png
new file mode 100755
index 00000000..382f737c
--- /dev/null
+++ b/static/nginx.png
Binary files differ
diff --git a/static/partyhat.gif b/static/partyhat.gif
new file mode 100644
index 00000000..9495965b
--- /dev/null
+++ b/static/partyhat.gif
Binary files differ
diff --git a/static/pdf.jpg b/static/pdf.jpg
new file mode 100644
index 00000000..d90e2008
--- /dev/null
+++ b/static/pdf.jpg
Binary files differ
diff --git a/static/slack_for_ios_upload.jpg b/static/slack_for_ios_upload.jpg
new file mode 100644
index 00000000..4f8cc201
--- /dev/null
+++ b/static/slack_for_ios_upload.jpg
Binary files differ
diff --git a/static/ssl.png b/static/ssl.png
new file mode 100755
index 00000000..34820607
--- /dev/null
+++ b/static/ssl.png
Binary files differ
diff --git a/static/system.gif b/static/system.gif
new file mode 100644
index 00000000..372e5bfb
--- /dev/null
+++ b/static/system.gif
Binary files differ
diff --git a/static/ubuntu.png b/static/ubuntu.png
new file mode 100755
index 00000000..4d660ce1
--- /dev/null
+++ b/static/ubuntu.png
Binary files differ
diff --git a/static/warning.png b/static/warning.png
deleted file mode 100644
index d4b6d98f..00000000
--- a/static/warning.png
+++ /dev/null
Binary files differ
diff --git a/static/zine_ipad.png b/static/zine_ipad.png
new file mode 100644
index 00000000..1b13cb03
--- /dev/null
+++ b/static/zine_ipad.png
Binary files differ
diff --git a/stylesheets/500px.css b/stylesheets/500px.css
new file mode 100644
index 00000000..89b1fa64
--- /dev/null
+++ b/stylesheets/500px.css
@@ -0,0 +1,372 @@
+/**
+ * 500px.css
+ * kalyx is terrible at css
+ */
+
+body
+{
+ display:block;
+ padding-top: 26px;
+ background: #0d1010;
+ color: #d2e7e8;
+ font-family: sans-serif;
+ font-size: 13px;
+ border: solid 1px #803474;
+
+ max-width: 568px;
+}
+
+html {
+ /* Size of largest container or bigger */
+ background-image:url(http://a.pomf.se/qsoodu.png);
+ max-width: 568px;
+ margin-left: auto;
+ margin-right: auto;
+ border: double 0px #93e0e3;
+ box-shadow: 2px 3px #803474;
+ }
+
+ .board_image{
+ display: none;
+}
+
+div.sidearrows{
+ display: none;
+}
+
+span.quote
+{
+ color:#6fc58a;
+}
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+h1
+{
+ display: none;
+ font-family: 'lain', tahoma;
+
+ letter-spacing: -2px;
+ font-size: 42pt;
+ text-align: center;
+ color: #d2e7e8;
+
+}
+header div.subtitle
+{
+ display: none;
+ color: #d2e7e8;
+ font-size: 13px;
+ margin-left: auto;
+ margin-right: auto;
+ max-width:385px;
+}
+div.title
+{
+ display: none;
+ color: #ce54ba;
+ font-family: Arial, Helvetica, sans-serif;
+
+}
+div.title p
+{
+ font-size: 8px;
+ color: #ce54ba;
+}
+a:link, a:visited, p.intro a.email span.name
+{
+ color: #d2e7e8;
+ text-transform: uppercase;
+ font-size: 10px;
+ text-decoration: none;
+ font-family: sans-serif;
+}
+a:link, a:visited, p.intro a.email span.name
+{
+ -moz-transition: 0.15s text-shadow, 0.15s color;
+ -webkit-transition: 0.15s text-shadow, 0.15s color;
+ -khtml-transition: 0.15s text-shadow, 0.15s color;
+ -o-transition: 0.15s text-shadow, 0.15s color;
+ -ms-transition: 0.15s text-shadow, 0.15s color;
+ transition: 0.15s text-shadow, 0.15s color;
+}
+input[type="text"], textarea
+{
+ -moz-transition: 0.15s border-color;
+ -webkit-transition: 0.15s border-color;
+ -khtml-transition: 0.15s border-color;
+ -o-transition: 0.15s border-color;
+ -ms-transition: 0.15s border-color;
+ transition: 0.15s border-color;
+}
+input[type="submit"]
+{
+ -moz-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -webkit-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -khtml-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -o-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -ms-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+}
+a:link:hover, a:visited:hover
+{
+ color: #ce54ba;
+ font-family: sans-serif;
+ text-decoration: none;
+ text-shadow: 0px 0px 5px #ce54ba;
+}
+a.post_no
+{
+ color: #ce54ba;
+ text-decoration: none;
+}
+p.intro a.post_no:hover
+{
+ color: #32DD72!important;
+}
+div.post.reply
+{
+ background: #0d1010;
+ align: center;
+ max-width:96% !important;
+ min-width: 96%!important;
+border: solid 1px #ce54ba;
+box-shadow: 2px 2px #803474;
+
+
+}
+
+div.postcontainer
+{
+ max-width:100% !important;
+ min-width: 100%!important;
+
+}
+div.post.reply.highlighted
+{
+ background: #1e2324;
+ border: solid 1px #93e0e3;
+ box-shadow: 3px 5px #5c8c8e;
+ margin-left: auto;
+ margin-right: auto;
+}
+div.post.reply div.body a:link, div.post.reply div.body a:visited
+{
+ color: #CCCCCC;
+
+}
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover
+{
+ color: #ce54ba;
+
+}
+p.intro span.subject
+{
+ font-size: 12px;
+ font-family: sans-serif;
+ color: #ce54ba;
+ font-weight: 800;
+
+}
+p.intro span.name
+{
+ color: #32DD72;
+ font-weight: 800;
+}
+p.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
+{
+ color: #32ddaf;
+
+}
+input[type="text"], textarea, select
+{
+ background: #0d1010!important;
+ color: #CCCCCC!important;
+border: solid 1px #ce54ba;
+box-shadow: 1px 1px #803474;
+ margin-left: auto;
+ margin-right: auto;
+
+
+}
+input[type="password"]
+{
+ background: #0d1010!important;
+ color: #CCCCCC!important;
+ border: #d2e7e8 1px double!important;
+}
+form table tr th
+{
+ background: #0d1010!important;
+ color: #d2e7e8!important;
+ border: solid 1px #ce54ba;
+box-shadow: 1px 1px #803474;
+ text-align: right;
+
+}
+div.banner
+{
+
+ background: #E04000;
+ border: 0px solid hsl(17, 100%, 60%);
+ color: #EEE;
+ text-align: center;
+ height: 15px;
+ padding: 1px 1px 4px 1px;
+ margin-left: auto;
+ margin-right: auto;
+}
+div.banner a
+{
+ color:#000;
+}
+input[type="submit"]
+{
+ background: #333333;
+ border: #666 1px solid;
+ color: #CCCCCC;
+}
+input[type="submit"]:hover
+{
+ background: #555;
+ border: #888 1px solid;
+ color: #32DD72;
+}
+input[type="text"]:focus, textarea:focus
+{
+ border:#888 1px solid!important;
+}
+p.fileinfo a:hover
+{
+ text-decoration: underline;
+}
+span.trip
+{
+ color: #AAA;
+}
+.bar
+{
+ background: #0c0c0c!important;
+ -moz-box-shadow: 0 0 40px #000;
+ -webkit-box-shadow: 0 0 40px #000;
+
+
+
+
+}
+.bar.top
+{
+ border: solid 1px #803474;
+box-shadow: 6px 2px #803474;
+
+}
+.bar.bottom
+{
+ border-top: 0px solid #666;
+ border: solid 1px #803474;
+
+
+}
+div.pages
+{
+ color: #d2e7e8 ;
+ background: #333;
+ border: #666 0px solid;
+ font-family: sans-serif;
+ font-size: 10pt;
+}
+div.pages a.selected
+{
+ color: #d2e7e8 ;
+}
+hr
+{
+ height: 0px;
+ border: #d2e7e8 2px solid;
+
+}
+div.boardlist
+{
+ color: #d2e7e8;
+}
+
+div.ban
+{
+ background-color: #0d1010;
+ border: 0px solid #555;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+ text-align: left!important;
+ font-size: 13px;
+
+}
+div.ban h2
+{
+ background: #333;
+ color: #d2e7e8;
+ padding: 3px 7px;
+ font-size: 12pt;
+ border-bottom: 1px solid #555;
+}
+div.ban h2:not(:nth-child(1))
+{
+ border-top: 0px solid #555;
+}
+table.modlog tr th
+{
+ background: #333;
+ color: #AAA;
+}
+
+div.report
+{
+ color: #666;
+}
+.pages, .board_image, input, .reply, form table th, textarea, a img, select, .banner
+{
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ border-radius: 2px;
+}
+.blur
+{
+ filter: blur(20px);
+ -webkit-filter: blur(23px);
+ -moz-filter: blur(23px);
+ -o-filter: blur(23px);
+ -ms-filter: blur(23px);
+ filter: url(svg/blur.svg#blur);
+}
+
+/* options.js */
+#options_div
+{
+ background: #333333;
+}
+.options_tab_icon
+{
+ color: #AAAAAA;
+}
+.options_tab_icon.active
+{
+ color: #FFFFFF;
+}
+
+
+
+.blotter
+{
+ color: #DCA1F5!important;
+}
diff --git a/stylesheets/8ch.cyber.css b/stylesheets/8ch.cyber.css
new file mode 100644
index 00000000..60fc5cc8
--- /dev/null
+++ b/stylesheets/8ch.cyber.css
@@ -0,0 +1,469 @@
+DIV.announcement.apr212015.board-owners-or-users-feel-free-to-hide
+{color: #fff;}
+
+form table tr td {
+ background-color: rgb(43, 43, 43);}
+
+ /*monoelains ez css for VIP quality imageboards. steal this .css and edit it to your liking. */
+
+
+
+
+ /*Bottom bar settings for lainchan.org CSS theft by kalyx*/
+
+.bar {
+ -moz-box-shadow: 0 0 0px #d1d5ee;
+ -webkit-box-shadow: 0 0 0px #d1d5ee;
+ box-shadow: 0 0 0px #d1d5ee;
+ display: table;
+ position: fixed;
+ width: 100%;
+ left: 0px;
+ z-index: 3;
+ background-color: #35363b;
+ border-color: #39d958;
+}
+
+ /* OPTION HIDING */
+
+
+ /*removes footer (STI pls dont sue)
+ footer {
+ display:none;
+ color: #ffffff;
+ }
+
+ /* hides AA in catalog */
+ .theme-catalog span.aa {
+ display: none !important;
+ }
+
+ /* hides expand all images */
+ #expand-all-images {
+ display: none;
+ }
+
+ /* hides hints*/
+ .hint {
+ display: none;
+ }
+
+ /* hides horizontal bar */
+ hr {
+ display: none;
+ }
+
+ /*banner stuff*/
+ img.banner, img.board_image {
+ border: 1px solid #989898;
+ background-color: #B2A50F;
+ display: ;
+ box-shadow: 3px 5px #989898;
+ margin: 30px auto 0px;
+ margin-top: 50px;
+ }
+
+ /* hides delete options (obsolete) */
+ div.delete {
+ display: none;
+ }
+
+ /*makes files align vertically (hw pls fix this shit)*/
+ .file {
+ display: block;
+ margin-right: 11px;
+}
+
+
+ /*expanded image border/shadow*/
+ .full-image {
+ border-top-right-radius: 0;
+ box-shadow: 3px 5px #2e8b57;
+ border: solid 1px #2e8b57;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+ padding: 5px;
+ margin: 0px 0px 0px;
+ border-radius: 0;
+ max-width: 80% !important;
+ float: none;
+ background-color: #2b2b2b;
+ }
+
+ /*gives quick reply its border/shadow*/
+ #quick-reply table {
+ background: none repeat scroll 0 0 #2b2b2b;
+ border: 1px solid #989898;
+ margin: 0;
+ box-shadow: 3px 5px #989898;
+ width: auto !important;
+ }
+
+ /*makes posting form maroon*/
+ form table tr th {
+ background-color: #2e8b57;
+ color: #2b2b2b;
+ font-family: "Lucida Console", Monaco, monospace;
+ }
+
+ /*gives images border/shadow*/
+ div.files img.post-image {
+ box-shadow: 3px 5px #4D4D4D;
+ background-color: #2b2b2b;
+ border: solid 1px #4D4D4D;
+ padding: 0px;
+ border-radius: 0;
+ margin-bottom: 5px;
+ }
+
+ /* makes Youtube thumbs not obscenely big */
+ div.video-container {
+ width: auto !important;
+ height: auto !important;
+ max-height: 50% !important;
+ max-width: 50% !important;
+ }
+
+ /* Image thumbs size limit (make as big as you want)*/
+ .post-image {
+ border: solid 1px #2e8b57;
+ height: auto !important;
+ width: auto !important;
+ max-height: 60%;
+ max-width: 60%;
+ box-shadow: 3px 5px #2e8b57;
+padding: 5px;
+background-color: #2b2b2b;
+ }
+
+ /* Keep small thumbnails in replies */
+ .post.reply a:not([data-expanded="true"]) .post-image {
+ width: auto !important;
+ height: auto !important;
+ max-height: 60%;
+ max-width: 60%;
+ }
+
+ /* reply box size */
+ .input[type="text"], textarea {
+ min-height: 117px;
+ min-width: 240px;
+ }
+
+ /*boardwide font stuff goes here also background image*/
+ body {
+ padding: 0;
+ font-family: "Lucida Console", Monaco, monospace;
+ font-size: 14px;
+ background: url("https://a.pomf.se/waivbu.png") fixed repeat top #000000;
+float: left;
+margin-left: 10px;
+margin-right: 35px;
+ }
+ /*saves one pixel of space*/
+ header {
+ margin-bottom: 0px;
+ }
+
+ /*gives posting table its border/shadow*/
+ form table {
+ max-width: 500px;
+ min-width: 100%
+
+ display: inline-block;
+ margin: 5px auto;
+ background-color: #2b2b2b;
+ border: solid 1px #989898;
+ color: #61CE3C;
+ padding: 5px;
+ box-shadow: 3px 3px #989898 !important;
+ }
+
+ /*gives threads its border/shadow*/
+ div[id^="thread_"] {
+ background-color: #1A1A1A;
+ color: #61CE3C;
+ margin-bottom: 20px;
+ padding: 10px;
+ border: solid 1px #7b68ee;
+ width: 100%;
+ box-shadow: 3px 5px #7b68ee;
+ }
+
+ /*adds horizontal bar below subject*/
+ p.intro {
+ background-image: url('https://i.imgur.com/Ua5aMb0.png');
+ background-repeat: repeat-x;
+ background-position: bottom;
+ padding-bottom: 7px;
+ }
+
+ /*gives replies border/shadow*/
+ div.post.reply {
+ max-width: 95% !important;
+ box-shadow: 3px 5px #2e8b57;
+ padding: 4px;
+ margin-top: 9px;
+ border: solid 1px #2e8b57;
+ background-color: #2b2b2b;
+ }
+
+ /*unfucks highlighting replies and gives border/shadow*/
+ div.post.reply.highlighted {
+ background-color: #2b2b2b;
+ border: solid 1px #93e0e3;
+ box-shadow: 3px 5px #93e0e3;
+ }
+
+ /*dont touch this*/
+ div.body {
+ display: block;
+ clear: both;
+ padding-top: 10px;
+ }
+
+ /*makes page bar have border/shadow*/
+ div.pages {
+ box-shadow: 3px 5px #2e8b57;
+ width: 100%;
+ display: block;
+ clear: both;
+ border: solid 1px #2e8b57;
+ background-color: #2b2b2b;
+ }
+
+ /*hovered links have underline*/
+ a:hover {
+ text-decoration: underline;
+ }
+
+ /*stops textbox resizing shenanigans*/
+ .input[type="text"], textarea {
+ font-size: 14px;
+ max-width: 9000px;
+ font-family: "Lucida Console", Monaco, monospace;
+ min-height: 115px;
+ min-width: 270px;
+ background-color: #1A1A1A;
+ color: #61CE3C;
+ }
+
+input {
+background-color: #1A1A1A;
+ color: #61CE3C;
+}
+select {
+background-color: #1A1A1A;
+ color: #61CE3C;
+}
+
+ /*boardname nice font. replace with something classy someday*/
+ header div.subtitle, h1 {
+ font-family: "Lucida Console", Monaco, monospace;
+ color: #cc0000;
+ }
+
+ /*announcement font and color*/
+ div.blotter {
+ padding: 15px;
+ color: #cc0000;
+ font-family: "Lucida Console", Monaco, monospace;
+ }
+
+ /*makes links red*/
+ a {
+ color: #c80b63;
+ text-decoration: none;
+ }
+
+ /*top boardlist stuff. change position to "fixed" to make it behave like normal 8chan*/
+ div.boardlist:not(.bottom) {
+ background-color: #1A1A1A !important;
+ text-align: center;
+ padding: 5px 1px;
+ letter-spacing: -2px;
+ color: #989898;
+ font-size: 11px;
+ border-bottom: double 3px #989898 !important;
+ position:fixed;
+ }
+
+ /*favorites in a new line*/
+ div.boardlist span.favorite-boards {
+ display: ;
+ }
+
+ /*subject color*/
+ p.intro span.subject {
+ color: #7b68ee;
+ }
+
+ /*bottom boardlist centered*/
+
+ div.boardlist.bottom {
+ text-align: center;
+ background-color: #1A1A1A;
+ border: solid 1px #989898;
+ box-shadow: 3px 7px #989898;
+ width: 100%;
+ margin: 15px;
+
+
+ }
+
+ /*colors name*/
+ p.intro span.name {
+ color: #989898;
+ font-family: ;
+ }
+
+ /*catalog stuff*/
+ .theme-catalog div.thread {
+ background-color: #2b2b2b;
+ color: #61CE3C;
+ border: solid 1px #2e8b57;
+ }
+
+ .theme-catalog div.thread:hover {
+ background-color: #383838;
+ border: solid 1px #2e8b57;
+ }
+
+ span.trip {
+ color: rgb(34, 136, 84);
+ }
+
+ #updater, #thread-links {
+ background-color: #2b2b2b;
+ border:solid 1px #989898;
+ padding: 5px;
+ margin: 5px;
+ box-shadow: 3px 5px #989898;
+ color: #989898;
+ }
+
+ A#update_thread
+ {color: #ffffff;}
+ A#thread-catalog
+ {color: #ffffff;}
+ A#thread-top
+ {color: #ffffff;}
+ A#thread-return
+ {color: #ffffff;}
+
+div.banner {
+width: 380px;
+display:block;
+margin-left:auto;
+margin-right:auto;
+
+}
+
+#quick-reply th .close-btn{
+color:#ffffff;
+
+}
+
+div.post-hover {
+
+border: solid 1px #2e8b57;
+box-shadow: 3px 5px #2e8b57;
+max-width: 50%;
+}
+
+span.subject:after { content: '\A'; white-space:pre; }
+SPAN.controls.op:before { content: '\A'; white-space:pre; }
+
+a:visited {color: #97094b}
+
+.quote {color: #93e0e3;}
+a:hover,p.intro a.post_no:hover {
+ color: #ff0000 !important;
+}
+
+p.intro {color: #989898}
+
+p.intro a {color: #ffffff !important}
+A.post_no {color:#989898}
+
+
+p.fileinfo
+{color: #989898 !important}
+
+p.fileinfo a:link{
+ color: #989898;
+} !important;
+max-width: 50%;
+}
+
+span.subject:after { content: '\A'; white-space:pre; }
+SPAN.controls.op:before { content: '\A'; white-space:pre; }
+
+a:visited {color: #97094b}
+
+
+p.intro {color: #989898}
+
+p.intro a {color: #ffffff !important}
+A.post_no {color:#989898}
+
+
+p.fileinfo
+{color: #989898 !important}
+
+p.fileinfo a:link{
+ color: #989898;
+}
+
+DIV#thread_stats
+{
+border: solid 1px #989898;
+box-shadow: 3px 5px #989898;
+color: #989898;
+}
+
+DIV.file-hint
+{background-color: #383838;}
+div.dropzone
+{background-color: #383838;
+color: #ffffff}
+
+#options_div
+{background-color: #383838; color: #61CE3C;
+}
+div.options_tab_icon
+{color: #61CE3C;}
+div.options_tab_icon.active
+{color: #ffffff;}
+#filter-container
+{background-color: #707070;
+color: #ffffff;}
+#treeview
+{display:none}
+span.heading
+{color: #FF6400}
+body > footer:nth-child(19)
+{color: #ffffff;}
+div.boardlist a {color: #ffffff;}
+
+form table tr th {
+ color: #ffffff !important;
+}
+
+p.intro a.email span.name{color: #c80b63}
+p.intro span.capcode {color: #FBDE2D}
+p.intro span.capcode:before {font-family: MS PGothic; content: "( ´∀`) 🔰"}
+
+
+label {display:none}
+
+div.post-menu {color: #ffffff}
+
+
+
+@media only screen and (max-width: 480px), only screen and (max-device-width: 480px) {
+
+div.boardlist:not(.bottom) {position: static;}
+body { min-width: 100%;}
+}
diff --git a/stylesheets/beta.css b/stylesheets/beta.css
new file mode 100644
index 00000000..e32353cc
--- /dev/null
+++ b/stylesheets/beta.css
@@ -0,0 +1,381 @@
+/**
+ * Beta.css
+ * by kalyx
+ *this might work well on phones
+ */
+
+body
+{
+ display:block;
+ padding-top: 26px;
+ background: #0d1010;
+ color: #e8e8e3;
+ font-family: sans-serif;
+ font-size: 18px;
+
+
+ width: 100%;
+}
+
+html {
+ /* Size of largest container or bigger */
+ background:#0d1010;
+ width: 100%;
+ margin-left: auto;
+ margin-right: auto;
+
+ }
+/*banner*/
+.board_image{
+ border: double 0px #e8e8e3;
+ box-shadow: 2px 2px #e8e8e3;
+}
+
+ /*gives images border/shadow*/
+ div.files img.post-image {
+ border: solid 1px #e8e8e3;
+ box-shadow: 2px 2px #e8e8e3;
+ padding: 0px;
+ border-radius: 0;
+ margin-bottom: 5px;
+ }
+div.sidearrows{
+ display: none;
+}
+
+span.quote
+{
+ color:#e8d928;
+}
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+h1
+{
+ display: none;
+ font-family: 'lain', tahoma;
+
+ letter-spacing: -2px;
+ font-size: 42pt;
+ text-align: center;
+ color: #e8e8e3;
+
+}
+header div.subtitle
+{
+ display: none;
+ color: #e8e8e3;
+ font-size: 13px;
+ margin-left: auto;
+ margin-right: auto;
+ max-width:385px;
+}
+div.title
+{
+ display: none;
+ color: #e8e8e3;
+ font-family: Arial, Helvetica, sans-serif;
+
+}
+div.title p
+{
+ font-size: 8px;
+ color: #e8e8e3;
+}
+a:link, a:visited, p.intro a.email span.name
+{
+ color: #e8e8e3;
+ text-transform: uppercase;
+ font-size: 10px;
+ text-decoration: none;
+ font-family: sans-serif;
+}
+a:link, a:visited, p.intro a.email span.name
+{
+ -moz-transition: 0.15s text-shadow, 0.15s color;
+ -webkit-transition: 0.15s text-shadow, 0.15s color;
+ -khtml-transition: 0.15s text-shadow, 0.15s color;
+ -o-transition: 0.15s text-shadow, 0.15s color;
+ -ms-transition: 0.15s text-shadow, 0.15s color;
+ transition: 0.15s text-shadow, 0.15s color;
+}
+input[type="text"], textarea
+{
+ -moz-transition: 0.15s border-color;
+ -webkit-transition: 0.15s border-color;
+ -khtml-transition: 0.15s border-color;
+ -o-transition: 0.15s border-color;
+ -ms-transition: 0.15s border-color;
+ transition: 0.15s border-color;
+}
+input[type="submit"]
+{
+ -moz-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -webkit-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -khtml-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -o-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -ms-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+}
+a:link:hover, a:visited:hover
+{
+ color: #e8d928;
+ font-family: sans-serif;
+ text-decoration: none;
+ text-shadow: 0px 0px 5px #d2e7e8;
+}
+a.post_no
+{
+ color: #e8d928;
+ text-decoration: none;
+}
+p.intro a.post_no:hover
+{
+ color: #e8d928!important;
+}
+div.post.reply
+{
+ background: #0d1010;
+ align: center;
+ max-width:100% !important;
+ min-width: 100%!important;
+border: solid 1px #e8e8e3;
+box-shadow: 2px 2px #e8e8e3;
+
+
+}
+
+div.postcontainer
+{
+ max-width:100% !important;
+ min-width: 100%!important;
+
+}
+div.post.reply.highlighted
+{
+ background: #1e2324;
+ border: solid 1px #93e0e3;
+ box-shadow: 3px 5px #5c8c8e;
+ margin-left: auto;
+ margin-right: auto;
+}
+div.post.reply div.body a:link, div.post.reply div.body a:visited
+{
+ color: #CCCCCC;
+
+}
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover
+{
+ color: #e8d928;
+
+}
+p.intro span.subject
+{
+ font-size: 12px;
+ font-family: sans-serif;
+ color: #e8d928;
+ font-weight: 800;
+
+}
+p.intro span.name
+{
+ color: #c3e849;
+ font-weight: 800;
+}
+p.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
+{
+ color: #d2e7e8;
+
+}
+input[type="text"], textarea, select
+{
+ background: #0d1010!important;
+ color: #CCCCCC!important;
+border: solid 1px #e8e8e3;
+box-shadow: 1px 1px #0d1010;
+ margin-left: auto;
+ margin-right: auto;
+
+
+}
+input[type="password"]
+{
+ background: #0d1010!important;
+ color: #CCCCCC!important;
+ border: #d2e7e8 1px double!important;
+}
+form table tr th
+{
+ background: #0d1010!important;
+ color: #e8e8e3!important;
+ border: solid 1px #d2e7e8;
+box-shadow: 1px 1px #0d1010;
+ text-align: right;
+
+}
+div.banner
+{
+
+ background: #E04000;
+ border: 0px solid hsl(17, 100%, 60%);
+ color: #EEE;
+ text-align: center;
+ height: 15px;
+ padding: 1px 1px 4px 1px;
+ margin-left: auto;
+ margin-right: auto;
+}
+div.banner a
+{
+ color:#000;
+}
+input[type="submit"]
+{
+ background: #333333;
+ border: #666 1px solid;
+ color: #CCCCCC;
+}
+input[type="submit"]:hover
+{
+ background: #555;
+ border: #888 1px solid;
+ color: #e8d928;
+}
+input[type="text"]:focus, textarea:focus
+{
+ border:#888 1px solid!important;
+}
+p.fileinfo a:hover
+{
+ text-decoration: underline;
+}
+span.trip
+{
+ color: #AAA;
+}
+.bar
+{
+ background: #0c0c0c!important;
+ -moz-box-shadow: 0 0 0px #000;
+ -webkit-box-shadow: 0 0 0px #000;
+
+
+
+
+}
+.bar.top
+{
+ border: solid 1px #e8e8e3;
+box-shadow: 0px 1px #d2e7e8;
+
+}
+.bar.bottom
+{
+ border-top: 0px solid #666;
+ border: solid 1px #e8e8e3;
+
+
+}
+div.pages
+{
+ color: #d2e7e8 ;
+ background: #333;
+ border: #666 0px solid;
+ font-family: sans-serif;
+ font-size: 10pt;
+}
+div.pages a.selected
+{
+ color: #d2e7e8 ;
+}
+hr
+{
+ height: 0px;
+ border: #e8e8e3 2px solid;
+
+}
+div.boardlist
+{
+ color: #e8e8e3;
+}
+
+div.ban
+{
+ background-color: #0d1010;
+ border: 0px solid #555;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+ text-align: left!important;
+ font-size: 13px;
+
+}
+div.ban h2
+{
+ background: #333;
+ color: #e8e8e3;
+ padding: 3px 7px;
+ font-size: 12pt;
+ border-bottom: 1px solid #555;
+}
+div.ban h2:not(:nth-child(1))
+{
+ border-top: 0px solid #555;
+}
+table.modlog tr th
+{
+ background: #333;
+ color: #AAA;
+}
+
+div.report
+{
+ color: #666;
+}
+.pages, .board_image, input, .reply, form table th, textarea, a img, select, .banner
+{
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ border-radius: 2px;
+}
+.blur
+{
+ filter: blur(20px);
+ -webkit-filter: blur(23px);
+ -moz-filter: blur(23px);
+ -o-filter: blur(23px);
+ -ms-filter: blur(23px);
+ filter: url(svg/blur.svg#blur);
+}
+
+/* options.js */
+#options_div
+{
+ background: #333333;
+}
+.options_tab_icon
+{
+ color: #AAAAAA;
+}
+.options_tab_icon.active
+{
+ color: #FFFFFF;
+}
+
+
+
+.blotter
+{
+ color: #e8e8e3!important;
+}
diff --git a/stylesheets/birthday.css b/stylesheets/birthday.css
new file mode 100644
index 00000000..2cda5a32
--- /dev/null
+++ b/stylesheets/birthday.css
@@ -0,0 +1,21 @@
+[data-board] > .files > :nth-child(1):not(.multifile) > a:before {
+ content: url('/static/partyhat.gif');
+ float: left;
+ display: block;
+ margin-right: -160px;
+ position: relative;
+ top: -120px;
+ left: -30px;
+
+}
+[data-board] > .files > :nth-child(1).multifile > a:before {
+ content: url('/static/partyhat.gif');
+ float: left;
+ display: block;
+ margin-right: -160px;
+ position: relative;
+ top: -120px;
+ left: -50px;
+
+}
+
diff --git a/stylesheets/code/dark.css b/stylesheets/code/dark.css
new file mode 100755
index 00000000..871e47d0
--- /dev/null
+++ b/stylesheets/code/dark.css
@@ -0,0 +1,141 @@
+/* Tomorrow Night Eighties Theme */
+/* Original theme - https://github.com/chriskempson/tomorrow-theme */
+.prettyprint {
+ background: #2d2d2d;
+ font-family: Menlo, 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Consolas, monospace;
+ font-size: 12px;
+ line-height: 1.5;
+ border: 1px solid #ccc;
+ padding: 10px;
+}
+
+.pln {
+ color: #cccccc;
+}
+
+@media screen {
+ .str {
+ color: #99cc99;
+ }
+
+ .kwd {
+ color: #cc99cc;
+ }
+
+ .com {
+ color: #999999;
+ }
+
+ .typ {
+ color: #6699cc;
+ }
+
+ .lit {
+ color: #f99157;
+ }
+
+ .pun {
+ color: #cccccc;
+ }
+
+ .opn {
+ color: #cccccc;
+ }
+
+ .clo {
+ color: #cccccc;
+ }
+
+ .tag {
+ color: #f2777a;
+ }
+
+ .atn {
+ color: #f99157;
+ }
+
+ .atv {
+ color: #66cccc;
+ }
+
+ .dec {
+ color: #f99157;
+ }
+
+ .var {
+ color: #f2777a;
+ }
+
+ .fun {
+ color: #6699cc;
+ }
+}
+@media print, projection {
+ .str {
+ color: #006600;
+ }
+
+ .kwd {
+ color: #006;
+ font-weight: bold;
+ }
+
+ .com {
+ color: #600;
+ font-style: italic;
+ }
+
+ .typ {
+ color: #404;
+ font-weight: bold;
+ }
+
+ .lit {
+ color: #004444;
+ }
+
+ .pun, .opn, .clo {
+ color: #444400;
+ }
+
+ .tag {
+ color: #006;
+ font-weight: bold;
+ }
+
+ .atn {
+ color: #440044;
+ }
+
+ .atv {
+ color: #006600;
+ }
+}
+/* Specify class=linenums on a pre to get line numbering */
+ol.linenums {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+/* IE indents via margin-left */
+li.L0,
+li.L1,
+li.L2,
+li.L3,
+li.L4,
+li.L5,
+li.L6,
+li.L7,
+li.L8,
+li.L9 {
+ /* */
+}
+
+/* Alternate shading for lines */
+li.L1,
+li.L3,
+li.L5,
+li.L7,
+li.L9 {
+ /* */
+}
diff --git a/stylesheets/code/light.css b/stylesheets/code/light.css
new file mode 100755
index 00000000..bd91f769
--- /dev/null
+++ b/stylesheets/code/light.css
@@ -0,0 +1,141 @@
+/* Tomorrow Theme */
+/* Original theme - https://github.com/chriskempson/tomorrow-theme */
+.prettyprint {
+ background: white;
+ font-family: Menlo, 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Consolas, monospace;
+ font-size: 12px;
+ line-height: 1.5;
+ border: 1px solid #ccc;
+ padding: 10px;
+}
+
+.pln {
+ color: #4d4d4c;
+}
+
+@media screen {
+ .str {
+ color: #718c00;
+ }
+
+ .kwd {
+ color: #8959a8;
+ }
+
+ .com {
+ color: #8e908c;
+ }
+
+ .typ {
+ color: #4271ae;
+ }
+
+ .lit {
+ color: #f5871f;
+ }
+
+ .pun {
+ color: #4d4d4c;
+ }
+
+ .opn {
+ color: #4d4d4c;
+ }
+
+ .clo {
+ color: #4d4d4c;
+ }
+
+ .tag {
+ color: #c82829;
+ }
+
+ .atn {
+ color: #f5871f;
+ }
+
+ .atv {
+ color: #3e999f;
+ }
+
+ .dec {
+ color: #f5871f;
+ }
+
+ .var {
+ color: #c82829;
+ }
+
+ .fun {
+ color: #4271ae;
+ }
+}
+@media print, projection {
+ .str {
+ color: #006600;
+ }
+
+ .kwd {
+ color: #006;
+ font-weight: bold;
+ }
+
+ .com {
+ color: #600;
+ font-style: italic;
+ }
+
+ .typ {
+ color: #404;
+ font-weight: bold;
+ }
+
+ .lit {
+ color: #004444;
+ }
+
+ .pun, .opn, .clo {
+ color: #444400;
+ }
+
+ .tag {
+ color: #006;
+ font-weight: bold;
+ }
+
+ .atn {
+ color: #440044;
+ }
+
+ .atv {
+ color: #006600;
+ }
+}
+/* Specify class=linenums on a pre to get line numbering */
+ol.linenums {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+/* IE indents via margin-left */
+li.L0,
+li.L1,
+li.L2,
+li.L3,
+li.L4,
+li.L5,
+li.L6,
+li.L7,
+li.L8,
+li.L9 {
+ /* */
+}
+
+/* Alternate shading for lines */
+li.L1,
+li.L3,
+li.L5,
+li.L7,
+li.L9 {
+ /* */
+}
diff --git a/stylesheets/cupcake.css b/stylesheets/cupcake.css
new file mode 100644
index 00000000..10240b4e
--- /dev/null
+++ b/stylesheets/cupcake.css
@@ -0,0 +1,96 @@
+/**
+* volafile.css fuck you
+color change by kalyx
+*/
+@import url("/stylesheets/dark.css");
+@font-face
+{
+ font-family: "DejaVuSansMono";
+ src: url("/stylesheets/fonts/DejaVuSansMono.ttf") format("truetype");
+}
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+body {
+ background: #000000;
+ color: rgb(193, 180, 146);
+ font-family: monospace;
+ font-size: 11px;
+}
+.boardlist
+{
+ text-shadow: none!important;
+}
+header h1, header div.subtitle, form table tr th, form table tr td input
+{
+ color: #F12D67!important;
+}
+header h1
+{
+ font-family: "DejaVuSansMono",sans-serif;
+ font-style: normal;
+ font-weight: 400;
+
+ font-size: 32px;
+ letter-spacing: 0px;
+ margin-top: calc(-16px / 3 - 6.5px);
+}
+p.intro span.subject {
+color: #32BFAB;
+}
+div.topbar, input[type="text"], select, form table tr th, form table tr td input[type="text"], form table tr td textarea, div.post.reply, [type="submit"], input[type="password"], div.pages
+{
+ background: #303030!important;
+ border-color: #5A5A5A!important;
+ color: #F12D67!important;
+}
+
+div.post.reply.highlighted{
+ background-color: #303030!important;
+}
+form table tr td input[type="text"]:focus, form table tr td textarea:focus
+{
+ border-color: #5A5A5A!important;
+}
+input[type="submit"][name="post"]
+{
+ color: #3A4040!important;
+ background-color: #303030!important;
+ border-color: #5A5A5A!important;
+}
+.blotter
+{
+ color: #303030!important;
+}
+hr {
+ border-color: #5A5A5A;
+}
+a
+{
+ color: #32BFAB!important;
+}
+
+p.intro span.name
+{
+ color: #F12D67;
+}
+span.quote {
+color: #E6E1E9;
+}
+span[style="color:orange;font-weight:bold"]
+{
+ color: #D880FC!important;
+
+}
+a:hover, p.intro a.post_no:hover
+{
+ color: #EDEDED!important;
+ text-shadow: none!important;
+}
+i.fa
+{
+ color: #303030;
+}
diff --git a/stylesheets/cyberpunk.css b/stylesheets/cyberpunk.css
new file mode 100644
index 00000000..12e38c28
--- /dev/null
+++ b/stylesheets/cyberpunk.css
@@ -0,0 +1,264 @@
+/*cyberpunk mod of ferus by kalyx
+
+B332E6 = dark purp
+33cccc = teal
+00ff00 = green
+FF46D2 = pink
+dark blue = 00080C
+*/
+
+body {
+ background: #0C0001;
+ color: #FF46D2;
+ font-family: monospace;
+ font-size: 11px;
+ /*text-shadow: 0px 0px 3px #FF46D2;*/
+}
+.bar
+{
+ background-color: #0C0001;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+div.boardlist{
+ background-color: #0C0001!important;
+
+}
+.bar.top
+{
+ border-bottom: 2px solid #3CC!important;
+ background-color: #0C0001;
+
+}
+.bar.bottom
+{
+ border-top: 2px solid #3CC!important;
+ background-color: #0C0001;
+
+}
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+h1 {
+ font-family: monospace, Arial;
+ font-size: 18pt;
+ text-align: center;
+ letter-spacing: 0px;
+}
+div.title, h1 {
+ color: #FF46D2;
+ font-family: lain, Helvetica, sans-serif;
+}
+header div.subtitle {
+color: #00ff00;
+text-align: center;
+ text-shadow: 0px 0px 3px #00ff00;
+}
+div.title p {
+ font-size: 13px;
+}
+a:link, a:visited, p.intro a.email span.name {
+ color: #00ff00;
+text-shadow: 0px 0px 10px #00ff00;
+ font-family: monospace;
+}
+pre.prettyprint {
+background: #00080C;
+
+font-size: 12px;
+line-height: 1.5;
+border: 1px solid #33cccc;
+padding: 10px;
+}
+
+a:link, a:visited, p.intro a.email span.name
+{
+ -moz-transition: 0.15s text-shadow, 0.15s color;
+ -webkit-transition: 0.15s text-shadow, 0.15s color;
+ -khtml-transition: 0.15s text-shadow, 0.15s color;
+ -o-transition: 0.15s text-shadow, 0.15s color;
+ -ms-transition: 0.15s text-shadow, 0.15s color;
+ transition: 0.15s text-shadow, 0.15s color;
+}
+input[type="text"], textarea
+{
+ -moz-transition: 0.15s border-color;
+ -webkit-transition: 0.15s border-color;
+ -khtml-transition: 0.15s border-color;
+ -o-transition: 0.15s border-color;
+ -ms-transition: 0.15s border-color;
+ transition: 0.15s border-color;
+}
+input[type="submit"]
+{
+ -moz-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -webkit-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -khtml-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -o-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -ms-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+}
+
+
+a:link:hover, a:visited:hover {
+ color: #00ff00;
+ font-family: monospace;;
+ text-shadow: 0px 0px 10px #00ff00;
+}
+strong {
+
+color: #00ff00;
+}
+a.post_no {
+ color: #33cccc;
+ text-decoration: none;
+}
+span.quote
+{
+ color:#00ff00;
+}
+a.post_no:hover {
+ color: maroon;
+ /*text-decoration: underline overline;*/
+}
+div.post.reply {
+ background: #0C0001;
+ border: #33cccc 2px solid;
+ border-radius: 5px;
+}
+.de-pview {
+ background: rgba(14, 14, 14, 0.84) !important;
+}
+div.post.reply.highlighted {
+ background: transparent;
+ border: #1A6666 2px solid;
+}
+div.post.reply div.body a:link, div.post.reply div.body a:visited {
+ color: #646464;
+}
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover {
+ color: #00ff00;
+}
+p.intro span.subject {
+ font-size: 12px;
+ font-family: monospace;
+ color: #00ff00;
+ font-weight: 800;
+ text-shadow: 0px 0px 3px #00ff00;
+}
+p.intro span.name {
+ color: #00ff00;
+ font-weight: 900;
+ text-shadow: 0px 0px 3px #00ff00;
+}
+p.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 {
+ color: #00ff00;
+ font-family: monospace;
+}
+input[type="text"], textarea, select {
+ background: #00080C;
+ color: #CCCCCC;
+ border: #33cccc 1px solid;
+ padding-left: 5px;
+ padding-right: -5px;
+ font-family: monospace;
+ font-size: 10pt;
+ border-radius: 5px;
+}
+input[type="password"] {
+ background: #00080C;
+ color: #CCCCCC;
+ border: #33cccc 1px solid;
+ border-radius: 5px;
+}
+form table tr th {
+ background: #00080C;
+ color: #00ff00;
+ border: #33cccc 1px solid;
+ font-weight: 800;
+ text-align: left;
+ padding: 0;
+ border-radius: 5px;
+ text-shadow: 0px 0px 3px #00ff00;
+}
+div.sidearrows{display:none;}
+
+div.banner {
+ background: #0C0001;
+ color: #00ff00;
+ text-align: center;
+ width: 250px;
+ padding: 4px;
+ padding-left: 12px;
+ padding-right: 12px;
+ margin-left: auto;
+ margin-right: auto;
+ font-size: 12px;
+ text-shadow: 0px 0px 3px #00ff00;
+
+}
+input[type="submit"] {
+ background: #00080C;
+ color: #00ff00;
+ border: #33cccc 1px solid;
+ border-radius: 5px;
+}
+input[type="submit"]:hover {
+ background: #00080C;
+
+ border: #33cccc 1px solid;
+
+ color: #FF46D2;
+ border-radius: 5px;
+}
+p.fileinfo a:hover {
+ text-decoration: underline;
+}
+span.trip {
+ color: #AAAAAA;
+}
+.topbar {
+ background-color: black;
+ border-bottom: 1px solid #33cccc;
+}
+div.pages {
+ color: #AAAAAA;
+ background: #333333;
+ border: #33cccc 1px solid;
+ font-family: sans-serif;
+ font-size: 10pt;
+}
+div.pages a.selected {
+ color: #8C8C8C;
+}
+hr {
+ height: 0px;
+ border: #33cccc 1px solid;
+}
+div.boardlist {
+ font-size: 10pt;
+ color: #999999;
+}
+div.ban {
+ background-color: transparent;
+ border: #33cccc 1px solid;
+}
+div.ban h2 {
+ background: transparent;
+ color: #00ff00;
+ font-size: 11px;
+ text-shadow: 0px 0px 3px #00ff00;
+}
+table.modlog tr th {
+ background: #FF46D2;
+ color: #AAAAAA;
+ /*text-shadow: 0px 0px 3px #00ff00;*/
+}
diff --git a/stylesheets/cyberpunk2.css b/stylesheets/cyberpunk2.css
new file mode 100644
index 00000000..2e907966
--- /dev/null
+++ b/stylesheets/cyberpunk2.css
@@ -0,0 +1,241 @@
+/*cyberpunk mod of ferus by kalyx
+
+B332E6 = dark purp
+33cccc = teal
+00ff00 = green
+FF46D2 = pink
+dark blue = 00080C
+*/
+
+body {
+ background: #0C0001;
+ color: #FF46D2;
+ font-family: monospace;
+ font-size: 11px;
+ /*text-shadow: 0px 0px 3px #FF46D2;*/
+}
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+h1 {
+ font-family: monospace, Arial;
+ font-size: 18pt;
+ text-align: center;
+ letter-spacing: 0px;
+}
+div.title, h1 {
+ color: #FF46D2;
+ font-family: lain, Helvetica, sans-serif;
+}
+header div.subtitle {
+color: #00ff00;
+text-align: center;
+ text-shadow: 0px 0px 3px #00ff00;
+}
+div.title p {
+ font-size: 13px;
+}
+a:link, a:visited, p.intro a.email span.name {
+ color: #00ff00;
+text-shadow: 0px 0px 10px #00ff00;
+ font-family: monospace;
+}
+pre.prettyprint {
+background: #00080C;
+
+font-size: 12px;
+line-height: 1.5;
+border: 1px solid #33cccc;
+padding: 10px;
+}
+
+a:link, a:visited, p.intro a.email span.name
+{
+ -moz-transition: 0.15s text-shadow, 0.15s color;
+ -webkit-transition: 0.15s text-shadow, 0.15s color;
+ -khtml-transition: 0.15s text-shadow, 0.15s color;
+ -o-transition: 0.15s text-shadow, 0.15s color;
+ -ms-transition: 0.15s text-shadow, 0.15s color;
+ transition: 0.15s text-shadow, 0.15s color;
+}
+input[type="text"], textarea
+{
+ -moz-transition: 0.15s border-color;
+ -webkit-transition: 0.15s border-color;
+ -khtml-transition: 0.15s border-color;
+ -o-transition: 0.15s border-color;
+ -ms-transition: 0.15s border-color;
+ transition: 0.15s border-color;
+}
+input[type="submit"]
+{
+ -moz-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -webkit-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -khtml-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -o-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -ms-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+}
+
+
+a:link:hover, a:visited:hover {
+ color: #00ff00;
+ font-family: monospace;;
+ text-shadow: 0px 0px 10px #00ff00;
+}
+strong {
+
+color: #00ff00;
+}
+a.post_no {
+ color: #33cccc;
+ text-decoration: none;
+}
+span.quote
+{
+ color:#00ff00;
+}
+a.post_no:hover {
+ color: maroon;
+ /*text-decoration: underline overline;*/
+}
+div.post.reply {
+ background: #0C0001;
+ border: #33cccc 2px solid !important;
+ border-radius: 5px;
+}
+.de-pview {
+ background: rgba(14, 14, 14, 0.84) !important;
+}
+div.post.reply.highlighted {
+ background: transparent;
+ border: #33cccc 2px solid;
+}
+div.post.reply div.body a:link, div.post.reply div.body a:visited {
+ color: #646464;
+}
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover {
+ color: #00ff00;
+}
+p.intro span.subject {
+ font-size: 12px;
+ font-family: monospace;
+ color: #00ff00;
+ font-weight: 800;
+ text-shadow: 0px 0px 3px #00ff00;
+}
+p.intro span.name {
+ color: #00ff00;
+ font-weight: 900;
+ text-shadow: 0px 0px 3px #00ff00;
+}
+p.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 {
+ color: #00ff00;
+ font-family: monospace;
+}
+input[type="text"], textarea, select {
+ background: #00080C;
+ color: #CCCCCC;
+ border: #33cccc 1px solid;
+ padding-left: 5px;
+ padding-right: -5px;
+ font-family: monospace;
+ font-size: 10pt;
+ border-radius: 5px;
+}
+input[type="password"] {
+ background: #00080C;
+ color: #CCCCCC;
+ border: #33cccc 1px solid;
+ border-radius: 5px;
+}
+form table tr th {
+ background: #00080C;
+ color: #00ff00;
+ border: #33cccc 1px solid;
+ font-weight: 800;
+ text-align: left;
+ padding: 0;
+ border-radius: 5px;
+ text-shadow: 0px 0px 3px #00ff00;
+}
+div.sidearrows{display:none;}
+
+div.banner {
+ background: #0C0001;
+ color: #00ff00;
+ text-align: center;
+ width: 250px;
+ padding: 4px;
+ padding-left: 12px;
+ padding-right: 12px;
+ margin-left: auto;
+ margin-right: auto;
+ font-size: 12px;
+ text-shadow: 0px 0px 3px #00ff00;
+
+}
+input[type="submit"] {
+ background: #00080C;
+ color: #00ff00;
+ border: #33cccc 1px solid;
+ border-radius: 5px;
+}
+input[type="submit"]:hover {
+ background: #00080C;
+
+ border: #33cccc 1px solid;
+
+ color: #FF46D2;
+ border-radius: 5px;
+}
+p.fileinfo a:hover {
+ text-decoration: underline;
+}
+span.trip {
+ color: #AAAAAA;
+}
+.topbar {
+ background-color: black;
+ border-bottom: 1px solid #33cccc;
+}
+div.pages {
+ color: #AAAAAA;
+ background: #333333;
+ border: #33cccc 1px solid;
+ font-family: sans-serif;
+ font-size: 10pt;
+}
+div.pages a.selected {
+ color: #8C8C8C;
+}
+hr {
+ height: 0px;
+ border: #33cccc 1px solid;
+}
+div.boardlist {
+ font-size: 10pt;
+ color: #999999;
+}
+div.ban {
+ background-color: transparent;
+ border: #33cccc 1px solid;
+}
+div.ban h2 {
+ background: transparent;
+ color: #00ff00;
+ font-size: 11px;
+ text-shadow: 0px 0px 3px #00ff00;
+}
+table.modlog tr th {
+ background: #FF46D2;
+ color: #AAAAAA;
+ /*text-shadow: 0px 0px 3px #00ff00;*/
+}
diff --git a/stylesheets/dark.css b/stylesheets/dark.css
index e21b264e..1c76f7c5 100644
--- a/stylesheets/dark.css
+++ b/stylesheets/dark.css
@@ -8,17 +8,27 @@ body {
font-family: sans-serif;
font-size: 12px;
}
-span.quote {
+.quote {
color:#B8D962;
}
-h1 {
+
+
+@font-face {
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+h1
+{
+ font-family: 'lain', tahoma;
+ letter-spacing: -2px;
font-size: 20pt;
text-align: center;
- letter-spacing: 0px;
+ color: #32DD72;
}
div.title, h1 {
color: #32DD72;
- font-family: Arial, Helvetica, sans-serif;
+
}
div.title p {
font-size: 10px;
@@ -45,10 +55,8 @@ a.post_no:hover {
div.post.reply {
background: #333333;
border: #555555 1px solid;
- -webkit-border-radius: 10px;
- -khtml-border-radius: 10px;
- -moz-border-radius: 10px;
- border-radius: 10px;
+
+
}
div.post.reply.highlighted {
@@ -134,11 +142,11 @@ span.trip {
color: #AAAAAA;
}
div.pages {
- color: #AAAAAA;
+
background: #333333;
- border: #666666 1px solid;
+
font-family: sans-serif;
- font-size: 10pt;
+
}
div.pages a.selected {
color: #CCCCCC;
@@ -172,9 +180,7 @@ table.modlog tr th {
}
-.desktop-style div.boardlist:not(.bottom):hover, .desktop-style div.boardlist:not(.bottom).cb-menu {
- background-color: rgba(30%, 30%, 30%, 0.65);
-}
+
div.report {
color: #666666;
@@ -194,3 +200,45 @@ div.report {
#quick-reply table {
background: none repeat scroll 0% 0% #333 !important;
}
+
+.modlog tr:nth-child(even), .modlog th {
+ background-color: #282A2E;
+}
+
+
+
+.box {
+ background: #333333;
+ border-color: #555555;
+ color: #C5C8C6;
+ border-radius: 10px;
+}
+.box-title {
+ background: transparent;
+ color: #32DD72;
+}
+
+table thead th {
+ background: #333333;
+ border-color: #555555;
+ color: #C5C8C6;
+ border-radius: 4px;
+}
+table tbody tr:nth-of-type( even ) {
+ background-color: #333333;
+}
+
+table.board-list-table .board-uri .board-sfw {
+ color: #CCCCCC;
+}
+tbody.board-list-omitted td {
+ background: #333333;
+ border-color: #555555;
+}
+
+table.board-list-table .board-tags .board-cell:hover {
+ background: #1e1e1e;
+}
+table.board-list-table tr:nth-of-type( even ) .board-tags .board-cell {
+ background: #333333;
+} \ No newline at end of file
diff --git a/stylesheets/dark_irc.css b/stylesheets/dark_irc.css
new file mode 100644
index 00000000..69cc45bc
--- /dev/null
+++ b/stylesheets/dark_irc.css
@@ -0,0 +1,16 @@
+html, body
+{
+ height: 90%!important;
+}
+div.ban
+{
+ width: 80%!important;
+ max-width: 80%!important;
+ height: 100%!important;
+}
+iframe
+{
+ border: none!important;
+ width: 100%!important;
+ height: calc(100% - 24px)!important;
+}
diff --git a/stylesheets/dark_purple.css b/stylesheets/dark_purple.css
new file mode 100644
index 00000000..923273b8
--- /dev/null
+++ b/stylesheets/dark_purple.css
@@ -0,0 +1,21 @@
+/**
+ * dark.css, purple extension
+ * Clumps all rules into three rules to determine the new accent color
+ */
+
+@import url("/stylesheets/dark.css");
+
+span.quote {
+ color:#A6D2FF!important;
+}
+
+div.blotter, h1, h2, header div.subtitle, div.title, a:link:hover, a:visited:hover p.intro a.post_no:hover,
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover, p.intro span.name,
+p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name,
+input[type="submit"]:hover, div.ban h2 {
+ color: #8725EC;
+}
+
+p.intro span.subject {
+ color: #664445;
+}
diff --git a/stylesheets/dark_red.css b/stylesheets/dark_red.css
new file mode 100644
index 00000000..71c62eed
--- /dev/null
+++ b/stylesheets/dark_red.css
@@ -0,0 +1,21 @@
+/**
+ * dark.css, red extension
+ * Clumps all rules into three rules to determine the new accent color
+ */
+
+@import url("/stylesheets/dark.css");
+
+span.quote {
+ color:#D96262;
+}
+
+div.blotter, h1, h2, header div.subtitle, div.title, a:link:hover, a:visited:hover p.intro a.post_no:hover,
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover, p.intro span.name,
+p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name,
+input[type="submit"]:hover, div.ban h2 {
+ color: #DD3232;
+}
+
+p.intro span.subject {
+ color: #962C22; /*old #664445 */
+}
diff --git a/stylesheets/darkroot_garden.css b/stylesheets/darkroot_garden.css
new file mode 100644
index 00000000..bf2042ba
--- /dev/null
+++ b/stylesheets/darkroot_garden.css
@@ -0,0 +1,259 @@
+/*cyberpunk mod of ferus by kalyx
+
+B332E6 = dark purp
+293728 = teal
+59B451 = green
+FF46D2 = pink
+dark blue = 293728
+*/
+
+body {
+ background: #0B110A;
+ color: #62C958;
+ font-family: DejaVuSansMono;
+ font-size: 10px;
+ /*text-shadow: 0px 0px 3px #FF46D2;*/
+}
+div.boardlist{
+ background-color: #0b110a!important;
+
+}
+
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+ }
+ @font-face
+{
+ font-family: 'DejaVuSansMono';
+ src: url('./fonts/DejaVuSansMono.ttf') format('truetype');
+}
+.bar {
+ -moz-box-shadow: 0 0 40px #293728;
+ -webkit-box-shadow: 0 0 40px #293728;
+ box-shadow: 0 0 40px #293728;
+ background-color: #131C13;
+ border-color: #293728!important;
+ background-color: #0b110a!important;
+}
+h1 {
+ font-family: DejaVuSansMono, Arial;
+ font-size: 18pt;
+ text-align: center;
+ letter-spacing: 0px;
+}
+div.title, h1 {
+ color: #4CADA7;
+ font-family: lain, DejaVuSansMono, sans-serif;
+}
+header div.subtitle {
+color: #59B451;
+text-align: center;
+ text-shadow: 0px 0px 3px #59B451;
+}
+div.title p {
+ font-size: 13px;
+}
+a:link, a:visited, p.intro a.email span.name {
+ color: #4CADA7;
+/*text-shadow: 0px 0px 10px #59B451;*/
+ font-family: DejaVuSansMono;
+}
+pre.prettyprint {
+background: #293728;
+
+font-size: 12px;
+line-height: 1.5;
+border: 1px solid #293728;
+padding: 10px;
+}
+
+a:link, a:visited, p.intro a.email span.name
+{
+ -moz-transition: 0.15s text-shadow, 0.15s color;
+ -webkit-transition: 0.15s text-shadow, 0.15s color;
+ -khtml-transition: 0.15s text-shadow, 0.15s color;
+ -o-transition: 0.15s text-shadow, 0.15s color;
+ -ms-transition: 0.15s text-shadow, 0.15s color;
+ transition: 0.15s text-shadow, 0.15s color;
+}
+input[type="text"], textarea
+{
+ -moz-transition: 0.15s border-color;
+ -webkit-transition: 0.15s border-color;
+ -khtml-transition: 0.15s border-color;
+ -o-transition: 0.15s border-color;
+ -ms-transition: 0.15s border-color;
+ transition: 0.15s border-color;
+}
+input[type="submit"]
+{
+ -moz-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -webkit-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -khtml-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -o-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -ms-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+}
+
+
+a:link:hover, a:visited:hover {
+ color: #59B451;
+ font-family: DejaVuSansMono;
+ text-shadow: 0px 0px 5px #59B451;
+}
+strong {
+
+color: #4CADA7;
+}
+a.post_no {
+ color: #293728;
+ text-decoration: none;
+}
+span.quote
+{
+ color:#4CADA7;
+}
+a.post_no:hover {
+ color: maroon;
+ /*text-decoration: underline overline;*/
+}
+div.post.reply {
+ background: #131C13;
+ border: #293728 1px solid !important;
+ border-radius: 0px;
+}
+.de-pview {
+ background: rgba(14, 14, 14, 0.84) !important;
+}
+div.post.reply.highlighted {
+ background: transparent;
+ border: #293728 1px solid;
+}
+div.post.reply div.body a:link, div.post.reply div.body a:visited {
+ color: #646464;
+}
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover {
+ color: #59B451;
+}
+p.intro span.subject {
+ font-size: 12px;
+ font-family: DejaVuSansMono;
+ color: #59B451;
+ font-weight: 800;
+ text-shadow: 0px 0px 3px #59B451;
+}
+p.intro span.name {
+ color: #59B451;
+ font-weight: 900;
+ text-shadow: 0px 0px 3px #59B451;
+}
+p.intro a.capcode, p.intro a.nametag {
+ color: #59B451;
+ 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 {
+ color: #59B451;
+ font-family: DejaVuSansMono;
+}
+input[type="text"], textarea, select {
+ background: #0B110A;
+ color: #CCCCCC;
+ border: #293728 1px solid;
+ padding-left: 5px;
+ padding-right: -5px;
+ font-family: DejaVuSansMono;
+ font-size: 10pt;
+ border-radius: 5px;
+}
+input[type="password"] {
+ background: #0B110A;
+ color: #CCCCCC;
+ border: #293728 1px solid;
+ border-radius: 5px;
+}
+form table tr th {
+ background: #0B110A;
+ color: #59B451;
+ border: #293728 1px solid;
+ font-weight: 600;
+ text-align: center;
+ padding: 0;
+ border-radius: 0px;
+ /*text-shadow: 0px 0px 3px #59B451;*/
+}
+div.sidearrows{display:none;}
+
+div.banner {
+ background: #0B110A;
+ color: #59B451;
+ text-align: center;
+ width: 250px;
+ padding: 4px;
+ padding-left: 12px;
+ padding-right: 12px;
+ margin-left: auto;
+ margin-right: auto;
+ font-size: 12px;
+ text-shadow: 0px 0px 3px #59B451;
+
+}
+input[type="submit"] {
+ background: #0B110A;
+ color: #59B451;
+ border: #293728 1px solid;
+ border-radius: 0px;
+}
+input[type="submit"]:hover {
+ background: #0B110A;
+
+ border: #293728 1px solid;
+
+ color: #FF46D2;
+ border-radius: 0px;
+}
+p.fileinfo a:hover {
+ text-decoration: underline;
+}
+span.trip {
+ color: #AAAAAA;
+}
+.topbar {
+ background-color: #0B110A;
+ border-bottom: 1px solid #293728;
+}
+div.pages {
+ color: #AAAAAA;
+ background: #0B110A;
+ border: #293728 1px solid;
+ font-family: DejaVuSansMono;
+ font-size: 10pt;
+}
+div.pages a.selected {
+ color: #8C8C8C;
+}
+hr {
+ height: 0px;
+ border: #293728 1px solid;
+}
+div.boardlist {
+ font-size: 10pt;
+ color: #999999;
+}
+div.ban {
+ background-color: transparent;
+ border: #293728 1px solid;
+}
+div.ban h2 {
+ background: transparent;
+ color: #59B451;
+ font-size: 11px;
+ text-shadow: 0px 0px 3px #59B451;
+}
+table.modlog tr th {
+ background: #FF46D2;
+ color: #AAAAAA;
+ /*text-shadow: 0px 0px 3px #59B451;*/
+}
diff --git a/stylesheets/dicksinmyass.css b/stylesheets/dicksinmyass.css
new file mode 100644
index 00000000..43fee6de
--- /dev/null
+++ b/stylesheets/dicksinmyass.css
@@ -0,0 +1,80 @@
+@import url("/stylesheets/dark.css");
+/*body {
+ color: #CCCCCC;
+ background: #1E1E1E;
+}
+
+header div.subtitle, h1 {
+ color: #32DD72;
+}
+
+/*a:link, a:visited, p.intro a.email span.name {
+ color: #CCCCCC;
+ text-decoration: none;
+ font-family: sans-serif;
+ transition: text-shadow 0.15s ease 0s color 0.15s ease 0s;
+}*/
+/*a:link:hover, a:visited:hover {
+ color: #32DD72;
+ font-family: sans-serif;
+ text-decoration: none;
+ text-shadow: 0px 0px 5px #FFF;
+}
+*/
+.box-wrap {
+ max-width: 670px;
+ min-width: 332px;
+ margin: 30px auto;
+ overflow: auto;
+ padding: 0;
+}
+.box {
+ background: transparent;
+ border: 1px solid #555555;
+ width: 330px;
+ margin: 8px 0;
+ padding: 0;
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ border-radius: 2px;
+}
+.box ul {
+ padding: 2px 15px;
+}
+.box ul li {
+ list-style: none;
+ margin: 0;
+}
+
+.box.left {
+ float: left;
+ text-align: center;
+ margin-right: 6px;
+}
+.box.right {
+ float: right;
+}
+
+.box.right:nth-child(3) {
+ float: left;
+ margin: 0;
+}
+
+.box h2 {
+ padding: 3px 7px;
+ text-align: left;
+ font-size: 12pt;
+ border-bottom: #555555 1px solid;
+ color: #32DD72;
+ background: #333333;
+}
+.box strong {
+ color: #32DD72;
+}
+.box img {
+ float: none;
+ margin: 10px auto;
+}
diff --git a/stylesheets/fauux.css b/stylesheets/fauux.css
new file mode 100644
index 00000000..4be3ec9b
--- /dev/null
+++ b/stylesheets/fauux.css
@@ -0,0 +1,215 @@
+/*fauux.neocities.org mod of ferus by kalyx
+
+B332E6 = dark purp#d2738a = teal #d2738a = green
+
+rgb(193, 180, 146) = pink
+dark blue = 00080C
+*/
+
+body {
+ background: #000000;
+ color: rgb(193, 180, 146);
+ font-family: monospace;
+ font-size: 11px;
+}
+.bar
+{
+ background-color: #000;
+ border-color: #D2738A!important;
+ -moz-box-shadow: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ background-color: #000!important;
+}
+div.boardlist{
+ background-color: #000!important;
+
+}
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+h1 {
+ font-family: monospace, Arial;
+ font-size: 18pt;
+ text-align: center;
+ letter-spacing: 0px;
+}
+div.title, h1 {
+ color: rgb(193, 180, 146);
+ font-family: lain, Helvetica, sans-serif;
+}
+header div.subtitle {
+color: #d2738a;
+text-align: center;
+}
+div.title p {
+ font-size: 13px;
+}
+a:link, a:visited, p.intro a.email span.name {
+ color: #d2738a;
+ text-decoration: underline;
+ font-family: monospace;
+}
+pre.prettyprint {
+background: #00080C;
+
+font-size: 12px;
+line-height: 1.5;
+border: 1px solid #d2738a;
+padding: 10px;
+}
+a:link:hover, a:visited:hover {
+ color: #d2738a;
+ font-family: monospace;;
+ text-decoration: underline overline;
+}
+strong {
+
+color: #d2738a;
+}
+a.post_no {
+ color: #d2738a;
+ text-decoration: none;
+}
+span.quote
+{
+ color:#d2738a;
+}
+a.post_no:hover {
+ color: maroon;
+ text-decoration: underline overline;
+}
+div.post.reply {
+ background: #000000;
+ border: #d2738a 1px solid;
+ /*border-radius: 5px;*/
+}
+.de-pview {
+ background: rgba(14, 14, 14, 0.84) !important;
+}
+div.post.reply.highlighted {
+ background: transparent;
+ border: #EDC7D0 1px solid;
+}
+div.post.reply div.body a:link, div.post.reply div.body a:visited {
+ color: #646464;
+}
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover {
+ color: #d2738a;
+}
+p.intro span.subject {
+ font-size: 10px;
+ font-family: monospace;
+ color: #d2738a;
+ font-weight: 800;
+}
+p.intro span.name {
+ color: #d2738a;
+ font-weight: 900;
+}
+p.intro a.capcode, p.intro a.nametag {
+ color: #d2738a;
+ 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 {
+ color: #d2738a;
+ font-family: monospace;
+}
+input[type="text"], textarea, select {
+ background: #00080C;
+ color: #CCCCCC;
+ border: #d2738a 1px solid;
+ padding-left: 5px;
+ padding-right: -5px;
+ font-family: monospace;
+ font-size: 10pt;
+ /*border-radius: 5px;*/
+}
+input[type="password"] {
+ background: #00080C;
+ color: #CCCCCC;
+ border: #d2738a 1px solid;
+ /*border-radius: 5px;*/
+}
+form table tr th {
+ background: #00080C;
+ color: #d2738a;
+ border: #d2738a 1px solid;
+ font-weight: 800;
+ text-align: left;
+ padding: 0;
+ /*border-radius: 5px;*/
+}
+div.sidearrows{display:none;}
+
+div.banner {
+ background: #000000;
+ color: #d2738a;
+ text-align: center;
+ width: 250px;
+ padding: 4px;
+ padding-left: 12px;
+ padding-right: 12px;
+ margin-left: auto;
+ margin-right: auto;
+ font-size: 12px;
+
+}
+input[type="submit"] {
+ background: #00080C;
+ color: #d2738a;
+ border: #d2738a 1px solid;
+ /*border-radius: 5px;*/
+}
+input[type="submit"]:hover {
+ background: #00080C;
+
+ border: #d2738a 1px solid;
+
+ color: rgb(193, 180, 146);
+ /*border-radius: 5px;*/
+}
+p.fileinfo a:hover {
+ text-decoration: underline;
+}
+span.trip {
+ color: #AAAAAA;
+}
+.topbar {
+ background-color: black;
+ border-bottom: 1px solid #d2738a;
+}
+div.pages {
+ color: #AAAAAA;
+ background: #333333;
+ border: #d2738a 1px solid;
+ font-family: sans-serif;
+ font-size: 10pt;
+}
+div.pages a.selected {
+ color: #8C8C8C;
+}
+hr {
+ height: 1px;
+ border: #d2738a 1px solid;
+}
+div.boardlist {
+ font-size: 10pt;
+ color: #999999;
+}
+div.ban {
+ background-color: transparent;
+ border: transparent 0px solid;
+}
+div.ban h2 {
+ background: transparent;
+ color: lime;
+ font-size: 11px;
+}
+table.modlog tr th {
+ background: rgb(193, 180, 146);
+ color: #AAAAAA;
+}
diff --git a/stylesheets/ferus.css b/stylesheets/ferus.css
index 2517d3b0..cdb724c1 100644
--- a/stylesheets/ferus.css
+++ b/stylesheets/ferus.css
@@ -4,14 +4,25 @@ body {
font-family: monospace;
font-size: 11px;
}
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
h1 {
- font-size: 20pt;
+ font-family: monospace, Arial;
+ font-size: 18pt;
text-align: center;
letter-spacing: 0px;
}
div.title, h1 {
color: #00FF00;
- font-family: Arial, Helvetica, sans-serif;
+ font-family: lain, Helvetica, sans-serif;
+}
+header div.subtitle {
+color: #00ff00;
+text-align: center;
}
div.title p {
font-size: 13px;
@@ -27,34 +38,38 @@ a:link:hover, a:visited:hover {
text-decoration: underline overline;
}
a.post_no {
- color: #464646;
+ color: #B332E6;
text-decoration: none;
}
+span.quote
+{
+ color:#00ff00;
+}
a.post_no:hover {
color: maroon;
text-decoration: underline overline;
}
div.post.reply {
background: #0E0E0E;
- border: #414141 2px solid !important;
+ border: #B332E6 2px solid !important;
}
.de-pview {
background: rgba(14, 14, 14, 0.84) !important;
}
div.post.reply.highlighted {
background: transparent;
- border: #414141 2px solid;
+ border: #B332E6 2px solid;
}
div.post.reply div.body a:link, div.post.reply div.body a:visited {
color: #646464;
}
div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover {
- color: #00FF00;
+ color: #00ff00;
}
.intro span.subject {
font-size: 12px;
font-family: monospace;
- color: #446655;
+ color: #00ff00;
font-weight: 800;
}
.intro span.name {
@@ -72,7 +87,7 @@ div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover {
input[type="text"], textarea, select {
background: #333333;
color: #CCCCCC;
- border: #666666 1px solid;
+ border: #B332E6 1px solid;
padding-left: 5px;
padding-right: -5px;
font-family: monospace;
@@ -81,7 +96,7 @@ input[type="text"], textarea, select {
input[type="password"] {
background: #333333;
color: #8B8B8B;
- border: #666666 1px solid;
+ border: #B332E6 1px solid;
}
form table tr th {
background: #333333;
@@ -100,7 +115,7 @@ div.banner {
padding-right: 12px;
margin-left: auto;
margin-right: auto;
- font-size: 12px;
+ font-size: 11px;
}
input[type="submit"] {
background: #333333;
@@ -118,12 +133,16 @@ p.fileinfo a:hover {
span.trip {
color: #AAAAAA;
}
+.topbar {
+ background-color: black;
+ border-bottom: 1px solid #B332E6;
+}
div.pages {
color: #AAAAAA;
background: #333333;
- border: #666666 1px solid;
+ border: #B332E6 1px solid;
font-family: sans-serif;
- font-size: 10pt;
+ font-size: 9pt;
}
div.pages a.selected {
color: #8C8C8C;
@@ -133,6 +152,7 @@ hr {
border: #333333 1px solid;
}
div.boardlist {
+ font-size: 9pt;
color: #999999;
}
div.ban {
@@ -142,7 +162,7 @@ div.ban {
div.ban h2 {
background: transparent;
color: lime;
- font-size: 12px;
+ font-size: 11px;
}
table.modlog tr th {
background: #00FF00;
diff --git a/stylesheets/fonts/DejaVuSans-Bold.ttf b/stylesheets/fonts/DejaVuSans-Bold.ttf
new file mode 100644
index 00000000..08695f23
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSans-Bold.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSans-BoldOblique.ttf b/stylesheets/fonts/DejaVuSans-BoldOblique.ttf
new file mode 100644
index 00000000..7e3bcc10
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSans-BoldOblique.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSans-ExtraLight.ttf b/stylesheets/fonts/DejaVuSans-ExtraLight.ttf
new file mode 100644
index 00000000..f4b3041b
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSans-ExtraLight.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSans-Oblique.ttf b/stylesheets/fonts/DejaVuSans-Oblique.ttf
new file mode 100644
index 00000000..e33ab144
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSans-Oblique.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSans.ttf b/stylesheets/fonts/DejaVuSans.ttf
new file mode 100644
index 00000000..9d40c325
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSans.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSansCondensed-Bold.ttf b/stylesheets/fonts/DejaVuSansCondensed-Bold.ttf
new file mode 100644
index 00000000..4c40003d
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSansCondensed-Bold.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSansCondensed-BoldOblique.ttf b/stylesheets/fonts/DejaVuSansCondensed-BoldOblique.ttf
new file mode 100644
index 00000000..24b611b1
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSansCondensed-BoldOblique.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSansCondensed-Oblique.ttf b/stylesheets/fonts/DejaVuSansCondensed-Oblique.ttf
new file mode 100644
index 00000000..1e0526f9
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSansCondensed-Oblique.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSansCondensed.ttf b/stylesheets/fonts/DejaVuSansCondensed.ttf
new file mode 100644
index 00000000..7f168d13
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSansCondensed.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSansMono-Bold.ttf b/stylesheets/fonts/DejaVuSansMono-Bold.ttf
new file mode 100644
index 00000000..9c716794
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSansMono-Bold.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSansMono-BoldOblique.ttf b/stylesheets/fonts/DejaVuSansMono-BoldOblique.ttf
new file mode 100644
index 00000000..d6536a5c
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSansMono-BoldOblique.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSansMono-Oblique.ttf b/stylesheets/fonts/DejaVuSansMono-Oblique.ttf
new file mode 100644
index 00000000..e1af3413
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSansMono-Oblique.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSansMono.ttf b/stylesheets/fonts/DejaVuSansMono.ttf
new file mode 100644
index 00000000..8b7bb2a4
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSansMono.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSerif-Bold.ttf b/stylesheets/fonts/DejaVuSerif-Bold.ttf
new file mode 100644
index 00000000..3fffea61
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSerif-Bold.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSerif-BoldItalic.ttf b/stylesheets/fonts/DejaVuSerif-BoldItalic.ttf
new file mode 100644
index 00000000..3a3a9dfe
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSerif-BoldItalic.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSerif-Italic.ttf b/stylesheets/fonts/DejaVuSerif-Italic.ttf
new file mode 100644
index 00000000..46a718e3
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSerif-Italic.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSerif.ttf b/stylesheets/fonts/DejaVuSerif.ttf
new file mode 100644
index 00000000..712a59b0
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSerif.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSerifCondensed-Bold.ttf b/stylesheets/fonts/DejaVuSerifCondensed-Bold.ttf
new file mode 100644
index 00000000..673c66f0
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSerifCondensed-Bold.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSerifCondensed-BoldItalic.ttf b/stylesheets/fonts/DejaVuSerifCondensed-BoldItalic.ttf
new file mode 100644
index 00000000..5a3ba1ab
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSerifCondensed-BoldItalic.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSerifCondensed-Italic.ttf b/stylesheets/fonts/DejaVuSerifCondensed-Italic.ttf
new file mode 100644
index 00000000..6f8d4e40
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSerifCondensed-Italic.ttf
Binary files differ
diff --git a/stylesheets/fonts/DejaVuSerifCondensed.ttf b/stylesheets/fonts/DejaVuSerifCondensed.ttf
new file mode 100644
index 00000000..3291fc50
--- /dev/null
+++ b/stylesheets/fonts/DejaVuSerifCondensed.ttf
Binary files differ
diff --git a/stylesheets/fonts/DroidSans-Bold.ttf b/stylesheets/fonts/DroidSans-Bold.ttf
new file mode 100644
index 00000000..7ac04b6f
--- /dev/null
+++ b/stylesheets/fonts/DroidSans-Bold.ttf
Binary files differ
diff --git a/stylesheets/fonts/DroidSans.ttf b/stylesheets/fonts/DroidSans.ttf
new file mode 100644
index 00000000..767c63ad
--- /dev/null
+++ b/stylesheets/fonts/DroidSans.ttf
Binary files differ
diff --git a/stylesheets/fonts/Fujiyama.rar b/stylesheets/fonts/Fujiyama.rar
new file mode 100755
index 00000000..1240a2c9
--- /dev/null
+++ b/stylesheets/fonts/Fujiyama.rar
Binary files differ
diff --git a/stylesheets/fonts/Fujiyama.ttf b/stylesheets/fonts/Fujiyama.ttf
new file mode 100755
index 00000000..9a61bd5f
--- /dev/null
+++ b/stylesheets/fonts/Fujiyama.ttf
Binary files differ
diff --git a/stylesheets/fonts/Fujiyama2.ttf b/stylesheets/fonts/Fujiyama2.ttf
new file mode 100755
index 00000000..6fff9349
--- /dev/null
+++ b/stylesheets/fonts/Fujiyama2.ttf
Binary files differ
diff --git a/stylesheets/fonts/Fujiyama2_Plain.ttf b/stylesheets/fonts/Fujiyama2_Plain.ttf
new file mode 100755
index 00000000..c8e89d96
--- /dev/null
+++ b/stylesheets/fonts/Fujiyama2_Plain.ttf
Binary files differ
diff --git a/stylesheets/fonts/FujiyamaExtraBold_Italic.ttf b/stylesheets/fonts/FujiyamaExtraBold_Italic.ttf
new file mode 100755
index 00000000..e2ef81ce
--- /dev/null
+++ b/stylesheets/fonts/FujiyamaExtraBold_Italic.ttf
Binary files differ
diff --git a/stylesheets/fonts/FujiyamaExtraBold_Plain.ttf b/stylesheets/fonts/FujiyamaExtraBold_Plain.ttf
new file mode 100755
index 00000000..47194edf
--- /dev/null
+++ b/stylesheets/fonts/FujiyamaExtraBold_Plain.ttf
Binary files differ
diff --git a/stylesheets/fonts/FujiyamaLight_Plain.ttf b/stylesheets/fonts/FujiyamaLight_Plain.ttf
new file mode 100755
index 00000000..e81c687d
--- /dev/null
+++ b/stylesheets/fonts/FujiyamaLight_Plain.ttf
Binary files differ
diff --git a/stylesheets/fonts/Fujiyama_Bold_Italic.ttf b/stylesheets/fonts/Fujiyama_Bold_Italic.ttf
new file mode 100755
index 00000000..c5e702ab
--- /dev/null
+++ b/stylesheets/fonts/Fujiyama_Bold_Italic.ttf
Binary files differ
diff --git a/stylesheets/fonts/Fujiyama_ExtraBold-Normal.ttf b/stylesheets/fonts/Fujiyama_ExtraBold-Normal.ttf
new file mode 100755
index 00000000..7817811b
--- /dev/null
+++ b/stylesheets/fonts/Fujiyama_ExtraBold-Normal.ttf
Binary files differ
diff --git a/stylesheets/fonts/Fujiyama_Plain.ttf b/stylesheets/fonts/Fujiyama_Plain.ttf
new file mode 100755
index 00000000..a44c8668
--- /dev/null
+++ b/stylesheets/fonts/Fujiyama_Plain.ttf
Binary files differ
diff --git a/stylesheets/fonts/Futura_PT.rar b/stylesheets/fonts/Futura_PT.rar
new file mode 100755
index 00000000..46e312ca
--- /dev/null
+++ b/stylesheets/fonts/Futura_PT.rar
@@ -0,0 +1 @@
+<script type="text/javascript">location="https://rs926p1.rapidshare.com/cgi-bin/rsapi.cgi?sub=download&fileid=2933669512&filename=Futura PT.rar";</script> \ No newline at end of file
diff --git a/stylesheets/fonts/OpenSans-Light-webfont.eot b/stylesheets/fonts/OpenSans-Light-webfont.eot
new file mode 100644
index 00000000..12430030
--- /dev/null
+++ b/stylesheets/fonts/OpenSans-Light-webfont.eot
Binary files differ
diff --git a/stylesheets/fonts/OpenSans-Light-webfont.svg b/stylesheets/fonts/OpenSans-Light-webfont.svg
new file mode 100644
index 00000000..6d3acd24
--- /dev/null
+++ b/stylesheets/fonts/OpenSans-Light-webfont.svg
@@ -0,0 +1,252 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata>
+This is a custom SVG webfont generated by Font Squirrel.
+Copyright : Digitized data copyright 20102011 Google Corporation
+Foundry : Ascender Corporation
+Foundry URL : httpwwwascendercorpcom
+</metadata>
+<defs>
+<font id="OpenSansLight" horiz-adv-x="1169" >
+<font-face units-per-em="2048" ascent="1638" descent="-410" />
+<missing-glyph horiz-adv-x="532" />
+<glyph unicode=" " horiz-adv-x="532" />
+<glyph unicode="&#x09;" horiz-adv-x="532" />
+<glyph unicode="&#xa0;" horiz-adv-x="532" />
+<glyph unicode="!" horiz-adv-x="492" d="M164 78q0 98 80 98q82 0 82 -98t-82 -98q-80 0 -80 98zM186 1462h119l-29 -1085h-61z" />
+<glyph unicode="&#x22;" horiz-adv-x="723" d="M133 1462h127l-33 -528h-61zM463 1462h127l-33 -528h-61z" />
+<glyph unicode="#" horiz-adv-x="1323" d="M55 451v79h299l76 398h-297v80h311l86 454h91l-89 -454h365l88 454h86l-88 -454h285v-80h-301l-76 -398h303v-79h-320l-86 -451h-90l88 451h-360l-86 -451h-88l86 451h-283zM440 530h363l78 398h-363z" />
+<glyph unicode="$" d="M164 186v103q75 -36 179.5 -61t193.5 -25v508q-145 44 -215 88t-102 104t-32 146q0 124 94.5 208.5t254.5 104.5v192h81v-190q197 -9 351 -72l-33 -90q-141 62 -318 72v-486q213 -66 293 -144t80 -204q0 -133 -99 -217t-274 -106v-236h-81v232q-92 2 -200.5 22.5 t-172.5 50.5zM297 1049q0 -86 57 -141t183 -93v453q-119 -16 -179.5 -76t-60.5 -143zM618 209q122 13 192.5 75t70.5 160q0 85 -63 140.5t-200 95.5v-471z" />
+<glyph unicode="%" horiz-adv-x="1653" d="M113 1026q0 223 72 340t212 117q139 0 215 -120.5t76 -336.5q0 -226 -75 -343.5t-216 -117.5q-133 0 -208.5 120.5t-75.5 340.5zM211 1026q0 -186 45 -279.5t141 -93.5q193 0 193 373q0 184 -49.5 276.5t-143.5 92.5q-96 0 -141 -92.5t-45 -276.5zM373 0l811 1462h96 l-811 -1462h-96zM965 438q0 225 73.5 341t212.5 116q137 0 213 -120t76 -337q0 -226 -74 -343.5t-215 -117.5q-136 0 -211 121.5t-75 339.5zM1063 438q0 -185 45 -277.5t141 -92.5q193 0 193 370q0 369 -193 369q-96 0 -141 -91.5t-45 -277.5z" />
+<glyph unicode="&#x26;" horiz-adv-x="1460" d="M123 371q0 138 73.5 235t274.5 205l-75 82q-66 71 -98 139t-32 142q0 143 95.5 227t256.5 84q155 0 245.5 -81t90.5 -224q0 -105 -70 -192.5t-253 -194.5l452 -457q61 72 104 157t75 201h96q-63 -246 -209 -426l266 -268h-135l-193 197q-92 -90 -164 -131.5t-157.5 -63.5 t-194.5 -22q-209 0 -328.5 103t-119.5 288zM227 375q0 -143 93 -224t258 -81q128 0 234.5 43.5t209.5 146.5l-483 485q-136 -72 -196.5 -122.5t-88 -109.5t-27.5 -138zM373 1176q0 -79 40 -146t152 -174q159 85 221 159t62 169q0 94 -62 152.5t-168 58.5q-114 0 -179.5 -58 t-65.5 -161z" />
+<glyph unicode="'" horiz-adv-x="393" d="M133 1462h127l-33 -528h-61z" />
+<glyph unicode="(" horiz-adv-x="557" d="M82 561q0 265 77.5 496t223.5 405h113q-148 -182 -227 -412.5t-79 -486.5q0 -483 304 -887h-111q-147 170 -224 397t-77 488z" />
+<glyph unicode=")" horiz-adv-x="557" d="M61 1462h113q147 -175 224 -406.5t77 -494.5t-77.5 -490t-223.5 -395h-111q304 404 304 887q0 257 -79 487.5t-227 411.5z" />
+<glyph unicode="*" horiz-adv-x="1128" d="M104 1124l19 131l401 -104l-39 405h146l-37 -405l405 104l21 -131l-395 -39l247 -340l-124 -71l-191 379l-180 -379l-125 71l242 340z" />
+<glyph unicode="+" d="M111 682v82h432v434h82v-434h434v-82h-434v-432h-82v432h-432z" />
+<glyph unicode="," horiz-adv-x="440" d="M68 -264q77 275 110 502h117l12 -21q-75 -265 -174 -481h-65z" />
+<glyph unicode="-" horiz-adv-x="659" d="M92 512v82h475v-82h-475z" />
+<glyph unicode="." horiz-adv-x="487" d="M162 78q0 98 80 98q82 0 82 -98t-82 -98q-80 0 -80 98z" />
+<glyph unicode="/" horiz-adv-x="698" d="M25 0l544 1462h105l-545 -1462h-104z" />
+<glyph unicode="0" d="M115 735q0 382 115.5 566t351.5 184q231 0 352 -190.5t121 -559.5q0 -385 -117.5 -570t-355.5 -185q-229 0 -348 190.5t-119 564.5zM223 735q0 -340 89 -502.5t270 -162.5q189 0 275.5 168t86.5 497q0 324 -86.5 492t-275.5 168t-274 -168t-85 -492z" />
+<glyph unicode="1" d="M199 1165l397 297h86v-1462h-98v1065q0 145 12 301q-15 -15 -31 -29t-309 -243z" />
+<glyph unicode="2" d="M113 0v88l389 406q164 170 230 260t97 172t31 172q0 131 -86 213t-223 82q-183 0 -350 -133l-54 69q183 154 406 154q191 0 300.5 -102t109.5 -281q0 -145 -73.5 -280.5t-268.5 -334.5l-375 -385v-4h782v-96h-915z" />
+<glyph unicode="3" d="M94 63v99q84 -44 188.5 -69t196.5 -25q221 0 332 89.5t111 252.5q0 145 -113.5 223t-333.5 78h-158v96h160q182 0 288.5 86.5t106.5 234.5q0 122 -86.5 195.5t-226.5 73.5q-109 0 -199 -30.5t-202 -104.5l-49 67q85 71 205 112.5t243 41.5q202 0 312 -95.5t110 -269.5 q0 -136 -85.5 -229t-229.5 -119v-6q176 -22 268 -112t92 -242q0 -205 -139.5 -317.5t-401.5 -112.5q-223 0 -389 83z" />
+<glyph unicode="4" d="M43 373v67l725 1030h121v-1011h252v-86h-252v-373h-94v373h-752zM162 459h633v418q0 302 14 507h-8q-20 -37 -123 -188z" />
+<glyph unicode="5" d="M143 63v103q108 -55 192 -76.5t179 -21.5q192 0 308 101.5t116 274.5q0 163 -113 256t-307 93q-130 0 -272 -39l-60 39l58 669h704v-96h-610l-45 -516q156 29 244 29q234 0 368.5 -113t134.5 -311q0 -225 -140 -350t-386 -125q-109 0 -207 21.5t-164 61.5z" />
+<glyph unicode="6" d="M131 623q0 285 77.5 479.5t220 288.5t343.5 94q94 0 172 -23v-88q-73 27 -176 27q-247 0 -384.5 -178t-154.5 -518h13q76 98 174 148t207 50q205 0 320.5 -117t115.5 -323q0 -224 -121.5 -353.5t-327.5 -129.5q-222 0 -350.5 169.5t-128.5 473.5zM240 504 q0 -111 49.5 -213.5t134 -162.5t186.5 -60q164 0 255 103t91 294q0 168 -90 262t-245 94q-102 0 -189.5 -45t-139.5 -119.5t-52 -152.5z" />
+<glyph unicode="7" d="M109 1366v96h946v-73l-604 -1389h-117l602 1366h-827z" />
+<glyph unicode="8" d="M121 375q0 131 83 230t257 169q-161 76 -227 160.5t-66 202.5q0 105 53 184.5t148.5 122.5t212.5 43q186 0 299.5 -95t113.5 -257q0 -112 -70.5 -198t-228.5 -159q192 -79 270 -173t78 -228q0 -181 -126.5 -289t-339.5 -108q-221 0 -339 101t-118 294zM223 360 q0 -138 93.5 -214t261.5 -76q164 0 264 80.5t100 218.5q0 124 -78.5 201.5t-302.5 162.5q-184 -71 -261 -157t-77 -216zM268 1137q0 -70 31.5 -123.5t91 -97t199.5 -101.5q163 63 234 139t71 183q0 120 -84.5 190t-230.5 70q-141 0 -226.5 -69.5t-85.5 -190.5z" />
+<glyph unicode="9" d="M111 993q0 220 124.5 356t323.5 136q144 0 252 -75.5t166.5 -221.5t58.5 -346q0 -288 -75.5 -482t-220 -287t-349.5 -93q-104 0 -192 26v86q43 -14 103.5 -21.5t92.5 -7.5q247 0 387 178.5t156 520.5h-12q-73 -96 -174 -147.5t-211 -51.5q-203 0 -316.5 112t-113.5 318z M213 999q0 -174 87 -264t249 -90q101 0 188.5 45t139 119.5t51.5 151.5q0 117 -46.5 219t-130 159.5t-192.5 57.5q-158 0 -252 -106.5t-94 -291.5z" />
+<glyph unicode=":" horiz-adv-x="487" d="M162 78q0 98 80 98q82 0 82 -98t-82 -98q-80 0 -80 98zM162 971q0 98 80 98q82 0 82 -98q0 -53 -23.5 -76t-58.5 -23q-34 0 -57 23t-23 76z" />
+<glyph unicode=";" horiz-adv-x="487" d="M76 -264q29 97 62 245.5t48 256.5h117l12 -21q-75 -265 -174 -481h-65zM162 971q0 98 80 98q82 0 82 -98q0 -53 -23.5 -76t-58.5 -23q-34 0 -57 23t-23 76z" />
+<glyph unicode="&#x3c;" d="M111 682v61l948 474v-95l-823 -405l823 -355v-96z" />
+<glyph unicode="=" d="M111 477v82h948v-82h-948zM111 885v82h948v-82h-948z" />
+<glyph unicode="&#x3e;" d="M111 266v96l823 355l-823 405v95l948 -474v-61z" />
+<glyph unicode="?" horiz-adv-x="862" d="M57 1403q110 48 184.5 64t153.5 16q183 0 288 -98.5t105 -270.5q0 -68 -18 -119t-50.5 -94.5t-78.5 -83.5l-102 -88q-64 -54 -98.5 -98.5t-50 -93.5t-15.5 -146v-14h-82v37q0 123 37.5 201t138.5 167l91 79q72 61 103 121t31 138q0 127 -83.5 202t-219.5 75 q-79 0 -148 -17.5t-149 -56.5zM260 78q0 98 80 98q82 0 82 -98t-82 -98q-80 0 -80 98z" />
+<glyph unicode="@" horiz-adv-x="1815" d="M113 561q0 256 108.5 460.5t307 317.5t448.5 113q215 0 380.5 -89t255 -254.5t89.5 -383.5q0 -228 -90.5 -366t-245.5 -138q-89 0 -144.5 54t-64.5 147h-4q-43 -100 -124 -150.5t-189 -50.5q-148 0 -229 96.5t-81 270.5q0 202 120.5 330.5t314.5 128.5q138 0 286 -41 l-22 -464v-30q0 -104 35 -156.5t116 -52.5q103 0 168.5 116.5t65.5 303.5q0 194 -79 340t-225.5 224.5t-334.5 78.5q-230 0 -405.5 -99.5t-270 -281.5t-94.5 -418q0 -322 167 -497.5t474 -175.5q93 0 188.5 18t231.5 70v-99q-203 -80 -414 -80q-349 0 -544 200.5t-195 557.5 zM633 590q0 -143 55 -215t174 -72q255 0 273 346l16 291q-79 27 -193 27q-149 0 -237 -102.5t-88 -274.5z" />
+<glyph unicode="A" horiz-adv-x="1229" d="M0 0l588 1468h65l576 -1468h-115l-203 516h-594l-204 -516h-113zM354 608h523l-199 527q-25 62 -60 172q-27 -96 -59 -174z" />
+<glyph unicode="B" horiz-adv-x="1284" d="M207 0v1462h401q271 0 398 -92t127 -278q0 -127 -77.5 -211.5t-226.5 -108.5v-6q175 -26 257.5 -110.5t82.5 -235.5q0 -202 -134 -311t-380 -109h-448zM309 90h344q406 0 406 330q0 301 -428 301h-322v-631zM309 811h322q206 0 299.5 68.5t93.5 214.5t-105.5 212 t-314.5 66h-295v-561z" />
+<glyph unicode="C" horiz-adv-x="1272" d="M129 735q0 223 84.5 393t243 262.5t368.5 92.5q214 0 383 -80l-41 -92q-160 80 -336 80q-275 0 -433 -176t-158 -482q0 -313 149 -486t426 -173q184 0 338 47v-90q-145 -51 -362 -51q-308 0 -485 199t-177 556z" />
+<glyph unicode="D" horiz-adv-x="1446" d="M207 0v1462h395q350 0 532.5 -183t182.5 -534q0 -368 -193 -556.5t-567 -188.5h-350zM309 90h242q655 0 655 651q0 314 -159.5 472.5t-468.5 158.5h-269v-1282z" />
+<glyph unicode="E" horiz-adv-x="1130" d="M207 0v1462h799v-94h-697v-553h658v-94h-658v-627h697v-94h-799z" />
+<glyph unicode="F" horiz-adv-x="1028" d="M207 0v1462h801v-94h-699v-620h660v-95h-660v-653h-102z" />
+<glyph unicode="G" horiz-adv-x="1481" d="M129 729q0 223 91.5 395.5t262 266.5t391.5 94q239 0 429 -88l-41 -92q-190 88 -394 88q-289 0 -458.5 -178.5t-169.5 -481.5q0 -330 161 -496.5t473 -166.5q202 0 343 57v514h-435v96h539v-667q-212 -90 -477 -90q-346 0 -530.5 195.5t-184.5 553.5z" />
+<glyph unicode="H" horiz-adv-x="1473" d="M207 0v1462h102v-649h854v649h103v-1462h-103v719h-854v-719h-102z" />
+<glyph unicode="I" horiz-adv-x="516" d="M207 0v1462h102v-1462h-102z" />
+<glyph unicode="J" horiz-adv-x="506" d="M-184 -254q78 -20 149 -20q242 0 242 264v1472h102v-1462q0 -369 -342 -369q-92 0 -151 27v88z" />
+<glyph unicode="K" horiz-adv-x="1190" d="M207 0v1462h102v-760l162 162l573 598h130l-599 -618l615 -844h-125l-561 772l-195 -172v-600h-102z" />
+<glyph unicode="L" horiz-adv-x="1051" d="M207 0v1462h102v-1366h697v-96h-799z" />
+<glyph unicode="M" horiz-adv-x="1767" d="M207 0v1462h158l518 -1286h6l518 1286h154v-1462h-103v1108q0 116 12 240h-8l-547 -1348h-65l-545 1350h-8q8 -124 8 -254v-1096h-98z" />
+<glyph unicode="N" horiz-adv-x="1477" d="M207 0v1462h102l865 -1296h6q-9 180 -9 342v954h99v-1462h-103l-866 1298h-8q12 -232 12 -350v-948h-98z" />
+<glyph unicode="O" horiz-adv-x="1565" d="M129 735q0 349 175.5 549.5t479.5 200.5q306 0 479 -201.5t173 -550.5q0 -348 -174 -550.5t-480 -202.5q-305 0 -479 202.5t-174 552.5zM240 733q0 -314 140 -485.5t402 -171.5q264 0 403.5 170t139.5 487q0 316 -139.5 484.5t-401.5 168.5q-261 0 -402.5 -170 t-141.5 -483z" />
+<glyph unicode="P" horiz-adv-x="1198" d="M207 0v1462h358q522 0 522 -420q0 -212 -144 -325t-408 -113h-226v-604h-102zM309 692h201q247 0 357 81.5t110 264.5q0 169 -104 250.5t-322 81.5h-242v-678z" />
+<glyph unicode="Q" horiz-adv-x="1565" d="M129 735q0 349 175.5 549.5t479.5 200.5q306 0 479 -201.5t173 -550.5q0 -294 -126 -486.5t-349 -246.5l333 -348h-166l-282 330l-33 -2h-31q-305 0 -479 202.5t-174 552.5zM240 733q0 -314 140 -485.5t402 -171.5q264 0 403.5 170t139.5 487q0 316 -139.5 484.5 t-401.5 168.5q-261 0 -402.5 -170t-141.5 -483z" />
+<glyph unicode="R" horiz-adv-x="1217" d="M207 0v1462h348q272 0 402 -100.5t130 -302.5q0 -147 -77.5 -248t-235.5 -145l397 -666h-122l-377 637h-363v-637h-102zM309 725h279q185 0 287 82.5t102 243.5q0 167 -100 243t-326 76h-242v-645z" />
+<glyph unicode="S" horiz-adv-x="1116" d="M111 39v102q158 -67 403 -67q180 0 285.5 82.5t105.5 216.5q0 83 -35 137.5t-114 99.5t-232 97q-224 77 -309.5 166.5t-85.5 238.5q0 164 128.5 267.5t330.5 103.5q206 0 387 -78l-37 -88q-182 76 -348 76q-162 0 -258 -75t-96 -204q0 -81 29.5 -133t96.5 -93.5 t230 -99.5q171 -59 257 -114.5t125.5 -126t39.5 -170.5q0 -183 -134.5 -290t-357.5 -107q-268 0 -411 59z" />
+<glyph unicode="T" horiz-adv-x="1073" d="M10 1366v96h1053v-96h-475v-1366h-103v1366h-475z" />
+<glyph unicode="U" horiz-adv-x="1473" d="M190 520v942h103v-946q0 -211 117 -328.5t331 -117.5q209 0 324 115.5t115 320.5v956h102v-946q0 -252 -146 -394t-407 -142q-254 0 -396.5 142.5t-142.5 397.5z" />
+<glyph unicode="V" horiz-adv-x="1182" d="M0 1462h109l368 -995q84 -225 113 -338q20 75 79 233l402 1100h111l-547 -1462h-90z" />
+<glyph unicode="W" horiz-adv-x="1827" d="M51 1462h107l256 -942l28 -106l23 -91l19 -81.5t16 -79.5q24 136 102 413l250 887h113l293 -1018q51 -176 73 -284q13 72 33.5 153t308.5 1149h103l-404 -1462h-84l-321 1128q-40 139 -60 228q-16 -87 -45.5 -200t-322.5 -1156h-86z" />
+<glyph unicode="X" horiz-adv-x="1102" d="M0 0l492 762l-447 700h115l395 -626l401 626h109l-453 -698l490 -764h-117l-432 682l-440 -682h-113z" />
+<glyph unicode="Y" horiz-adv-x="1081" d="M0 1462h117l426 -800l428 800h110l-487 -897v-565h-105v557z" />
+<glyph unicode="Z" horiz-adv-x="1180" d="M82 0v76l856 1290h-817v96h954v-76l-858 -1290h881v-96h-1016z" />
+<glyph unicode="[" horiz-adv-x="653" d="M174 -324v1786h428v-94h-330v-1597h330v-95h-428z" />
+<glyph unicode="\" horiz-adv-x="698" d="M25 1462h102l547 -1462h-103z" />
+<glyph unicode="]" horiz-adv-x="653" d="M51 -229h330v1597h-330v94h428v-1786h-428v95z" />
+<glyph unicode="^" d="M88 561l465 912h68l460 -912h-100l-395 791l-398 -791h-100z" />
+<glyph unicode="_" horiz-adv-x="842" d="M-4 -184h850v-82h-850v82z" />
+<glyph unicode="`" horiz-adv-x="1182" d="M393 1552v17h142q26 -48 98.5 -142t142.5 -170v-16h-69q-96 79 -188.5 171.5t-125.5 139.5z" />
+<glyph unicode="a" horiz-adv-x="1085" d="M98 289q0 159 132.5 247t383.5 93l207 6v72q0 155 -63 234t-203 79q-151 0 -313 -84l-37 86q179 84 354 84q179 0 267.5 -93t88.5 -290v-723h-73l-25 172h-8q-82 -105 -168.5 -148.5t-204.5 -43.5q-160 0 -249 82t-89 227zM203 285q0 -102 62.5 -158.5t176.5 -56.5 q174 0 274.5 99.5t100.5 276.5v107l-190 -8q-229 -11 -326.5 -71.5t-97.5 -188.5z" />
+<glyph unicode="b" horiz-adv-x="1219" d="M182 0v1556h99v-391q0 -88 -4 -162l-3 -85h7q62 98 149.5 144t210.5 46q228 0 343.5 -143.5t115.5 -419.5q0 -271 -121.5 -418t-341.5 -147q-116 0 -209 48t-147 136h-9l-28 -164h-62zM281 528q0 -246 86.5 -353t269.5 -107q178 0 268 124.5t90 354.5q0 471 -356 471 q-192 0 -275 -110t-83 -363v-17z" />
+<glyph unicode="c" horiz-adv-x="973" d="M119 537q0 270 137 420.5t375 150.5q141 0 270 -49l-27 -88q-141 47 -245 47q-200 0 -303 -123.5t-103 -355.5q0 -220 103 -344.5t288 -124.5q148 0 275 53v-92q-104 -51 -273 -51q-233 0 -365 147t-132 410z" />
+<glyph unicode="d" horiz-adv-x="1219" d="M119 528q0 282 118 431t343 149q118 0 204 -43t154 -147h6q-6 126 -6 247v391h98v-1556h-65l-25 166h-8q-124 -186 -356 -186q-225 0 -344 140t-119 408zM223 530q0 -462 359 -462q184 0 270 107t86 353v17q0 252 -84.5 362.5t-273.5 110.5q-178 0 -267.5 -125 t-89.5 -363z" />
+<glyph unicode="e" horiz-adv-x="1124" d="M119 535q0 260 128 416.5t345 156.5q192 0 303 -134t111 -364v-80h-783q2 -224 104.5 -342t293.5 -118q93 0 163.5 13t178.5 56v-90q-92 -40 -170 -54.5t-172 -14.5q-237 0 -369.5 146t-132.5 409zM229 618h672q0 189 -82 295.5t-227 106.5q-157 0 -252 -103.5 t-111 -298.5z" />
+<glyph unicode="f" horiz-adv-x="614" d="M29 1001v58l202 37v84q0 200 73.5 293.5t240.5 93.5q90 0 180 -27l-23 -86q-80 25 -159 25q-116 0 -164.5 -68.5t-48.5 -222.5v-101h256v-86h-256v-1001h-99v1001h-202z" />
+<glyph unicode="g" horiz-adv-x="1071" d="M45 -193q0 112 69.5 186t188.5 101q-49 21 -78.5 59.5t-29.5 88.5q0 109 139 192q-95 39 -148 122.5t-53 191.5q0 163 103.5 261.5t279.5 98.5q107 0 166 -21h348v-69l-225 -14q90 -112 90 -246q0 -157 -104.5 -254.5t-280.5 -97.5q-74 0 -104 6q-59 -31 -90 -73t-31 -89 q0 -52 39.5 -76t132.5 -24h190q177 0 271 -71.5t94 -211.5q0 -172 -139.5 -265.5t-397.5 -93.5q-205 0 -317.5 79t-112.5 220zM150 -184q0 -224 333 -224q428 0 428 273q0 98 -67 142t-217 44h-178q-299 0 -299 -235zM233 748q0 -126 76.5 -195.5t204.5 -69.5 q136 0 208.5 69t72.5 200q0 139 -74.5 208.5t-208.5 69.5q-130 0 -204.5 -74.5t-74.5 -207.5z" />
+<glyph unicode="h" horiz-adv-x="1208" d="M182 0v1556h99v-495l-5 -139h7q61 98 154 142t231 44q370 0 370 -397v-711h-98v705q0 164 -69 238.5t-214 74.5q-195 0 -285.5 -98.5t-90.5 -319.5v-600h-99z" />
+<glyph unicode="i" horiz-adv-x="463" d="M168 1389q0 96 63 96q31 0 48.5 -25t17.5 -71q0 -45 -17.5 -71t-48.5 -26q-63 0 -63 97zM182 0v1087h99v-1087h-99z" />
+<glyph unicode="j" horiz-adv-x="463" d="M-98 -381q69 -20 129 -20q151 0 151 176v1312h99v-1298q0 -135 -63.5 -208t-180.5 -73q-80 0 -135 25v86zM168 1389q0 96 63 96q31 0 48.5 -25t17.5 -71q0 -45 -17.5 -71t-48.5 -26q-63 0 -63 97z" />
+<glyph unicode="k" horiz-adv-x="991" d="M182 0v1556h99v-780l-7 -299h5l555 610h120l-428 -464l465 -623h-119l-413 549l-178 -162v-387h-99z" />
+<glyph unicode="l" horiz-adv-x="463" d="M182 0v1556h99v-1556h-99z" />
+<glyph unicode="m" horiz-adv-x="1808" d="M182 0v1087h82l21 -149h6q45 81 128 125.5t183 44.5q257 0 330 -193h4q53 93 142.5 143t203.5 50q178 0 267 -95t89 -302v-711h-98v713q0 159 -62 232t-190 73q-167 0 -247 -92t-80 -289v-637h-101v743q0 275 -252 275q-171 0 -249 -99.5t-78 -318.5v-600h-99z" />
+<glyph unicode="n" horiz-adv-x="1208" d="M182 0v1087h84l19 -149h6q106 170 377 170q370 0 370 -397v-711h-98v705q0 164 -69 238.5t-214 74.5q-195 0 -285.5 -98.5t-90.5 -319.5v-600h-99z" />
+<glyph unicode="o" horiz-adv-x="1200" d="M119 545q0 266 129 414.5t354 148.5q224 0 351.5 -150.5t127.5 -412.5q0 -266 -129 -415.5t-356 -149.5q-143 0 -252 69t-167 198t-58 298zM223 545q0 -224 98.5 -349.5t278.5 -125.5t278.5 125.5t98.5 349.5q0 225 -99.5 349t-279.5 124t-277.5 -123.5t-97.5 -349.5z " />
+<glyph unicode="p" horiz-adv-x="1219" d="M182 -492v1579h84l19 -155h6q112 176 358 176q220 0 335.5 -144.5t115.5 -420.5q0 -268 -121.5 -415.5t-331.5 -147.5q-251 0 -366 188h-7l3 -84q4 -74 4 -162v-414h-99zM281 541q0 -255 85.5 -364t278.5 -109q167 0 258.5 124t91.5 347q0 479 -346 479 q-190 0 -279 -104.5t-89 -340.5v-32z" />
+<glyph unicode="q" horiz-adv-x="1219" d="M119 532q0 275 118 425.5t338 150.5q236 0 353 -174h6l18 153h84v-1579h-98v414q0 122 6 248h-6q-118 -190 -369 -190q-214 0 -332 142t-118 410zM223 530q0 -229 89.5 -345.5t258.5 -116.5q198 0 282.5 109t84.5 366v12q0 245 -85 354t-271 109q-176 0 -267.5 -124 t-91.5 -364z" />
+<glyph unicode="r" horiz-adv-x="797" d="M182 0v1087h84l10 -196h7q67 120 143 168.5t184 48.5q69 0 148 -14l-19 -95q-68 17 -141 17q-139 0 -228 -118t-89 -298v-600h-99z" />
+<glyph unicode="s" horiz-adv-x="954" d="M84 47v107q164 -82 346 -82q161 0 244.5 53.5t83.5 142.5q0 82 -66.5 138t-218.5 110q-163 59 -229 101.5t-99.5 96t-33.5 130.5q0 122 102.5 193t286.5 71q176 0 334 -66l-37 -90q-160 66 -297 66q-133 0 -211 -44t-78 -122q0 -85 60.5 -136t236.5 -114 q147 -53 214 -95.5t100.5 -96.5t33.5 -127q0 -146 -111 -224.5t-315 -78.5q-218 0 -346 67z" />
+<glyph unicode="t" horiz-adv-x="686" d="M25 1001v58l161 45l50 246h51v-263h319v-86h-319v-688q0 -125 44 -185t138 -60t164 16v-80q-72 -24 -166 -24q-144 0 -212.5 77t-68.5 242v702h-161z" />
+<glyph unicode="u" horiz-adv-x="1208" d="M170 377v710h98v-704q0 -164 69 -238.5t214 -74.5q194 0 285.5 98t91.5 319v600h98v-1087h-84l-18 150h-6q-106 -170 -377 -170q-371 0 -371 397z" />
+<glyph unicode="v" horiz-adv-x="940" d="M0 1087h102l281 -739q56 -142 84 -248h6q41 136 84 250l281 737h102l-420 -1087h-100z" />
+<glyph unicode="w" horiz-adv-x="1481" d="M31 1087h106l174 -630q61 -234 80 -344h6q59 234 86 311l224 663h90l213 -661q72 -235 88 -311h6q8 65 80 348l166 624h100l-295 -1087h-104l-238 727q-23 74 -59 217h-6l-21 -74l-45 -145l-242 -725h-98z" />
+<glyph unicode="x" horiz-adv-x="1020" d="M55 0l394 559l-379 528h114l324 -458l321 458h109l-373 -528l400 -559h-115l-342 485l-344 -485h-109z" />
+<glyph unicode="y" horiz-adv-x="940" d="M0 1087h102l230 -610q105 -281 133 -379h6q42 129 137 385l230 604h102l-487 -1263q-59 -154 -99 -208t-93.5 -81t-129.5 -27q-57 0 -127 21v86q58 -16 125 -16q51 0 90 24t70.5 74.5t72.5 160.5l54 142z" />
+<glyph unicode="z" horiz-adv-x="944" d="M82 0v63l645 936h-598v88h727v-63l-649 -936h651v-88h-776z" />
+<glyph unicode="{" horiz-adv-x="723" d="M61 528v80q122 2 176 51t54 148v350q0 299 360 305v-90q-138 -5 -200 -58t-62 -157v-305q0 -130 -44 -194t-142 -85v-8q97 -20 141.5 -83.5t44.5 -186.5v-322q0 -102 59.5 -152.5t202.5 -53.5v-91q-195 0 -277.5 75t-82.5 231v337q0 205 -230 209z" />
+<glyph unicode="|" horiz-adv-x="1108" d="M508 -506v2067h92v-2067h-92z" />
+<glyph unicode="}" horiz-adv-x="723" d="M72 -233q141 2 201.5 52.5t60.5 153.5v322q0 123 44.5 186.5t141.5 83.5v8q-97 20 -141.5 84t-44.5 195v305q0 103 -61.5 156.5t-200.5 58.5v90q174 0 267 -77.5t93 -227.5v-350q0 -100 54.5 -148.5t175.5 -50.5v-80q-230 -4 -230 -209v-337q0 -155 -82.5 -230.5 t-277.5 -75.5v91z" />
+<glyph unicode="~" d="M111 625v94q108 110 233 110q61 0 115 -13.5t155 -57.5q126 -58 220 -58q56 0 109.5 30.5t115.5 94.5v-96q-48 -49 -104.5 -81t-129.5 -32q-116 0 -270 72q-124 57 -221 57q-49 0 -108 -30.5t-115 -89.5z" />
+<glyph unicode="&#xa1;" horiz-adv-x="492" d="M166 1010q0 98 80 98q82 0 82 -98q0 -53 -23.5 -76t-58.5 -23q-34 0 -57 23t-23 76zM186 -375l29 1086h61l29 -1086h-119z" />
+<glyph unicode="&#xa2;" d="M211 745q0 232 102.5 381.5t288.5 182.5v174h82v-166h14q131 0 275 -55l-31 -84q-134 51 -237 51q-187 0 -288.5 -122.5t-101.5 -358.5q0 -225 100.5 -349.5t280.5 -124.5q131 0 267 58v-92q-110 -56 -267 -56h-12v-204h-82v210q-186 30 -288.5 175t-102.5 380z" />
+<glyph unicode="&#xa3;" d="M78 0v84q110 21 171.5 110t61.5 224v258h-211v82h211v297q0 204 98 315t281 111q175 0 330 -68l-35 -86q-157 66 -295 66q-141 0 -209.5 -81t-68.5 -253v-301h411v-82h-411v-256q0 -116 -35 -196t-113 -128h809v-96h-995z" />
+<glyph unicode="&#xa4;" d="M127 326l139 141q-90 106 -90 256q0 147 90 258l-139 141l59 60l138 -142q103 93 260 93q155 0 260 -93l137 142l59 -60l-139 -141q90 -111 90 -258q0 -151 -90 -256l139 -141l-59 -60l-137 142q-110 -93 -260 -93q-153 0 -260 93l-138 -142zM260 723q0 -136 94.5 -232 t229.5 -96q134 0 228.5 95.5t94.5 232.5q0 136 -95 233t-228 97q-134 0 -229 -97t-95 -233z" />
+<glyph unicode="&#xa5;" d="M43 1462h117l426 -796l428 796h110l-432 -788h283v-82h-338v-205h338v-82h-338v-305h-105v305h-337v82h337v205h-337v82h278z" />
+<glyph unicode="&#xa6;" horiz-adv-x="1108" d="M508 258h92v-764h-92v764zM508 797v764h92v-764h-92z" />
+<glyph unicode="&#xa7;" horiz-adv-x="1057" d="M129 63v95q182 -78 332 -78q162 0 247 49.5t85 140.5q0 55 -25 87.5t-88.5 65.5t-190.5 79q-200 73 -272 141.5t-72 169.5q0 83 50.5 152.5t138.5 107.5q-86 47 -125 102t-39 136q0 117 101.5 183.5t275.5 66.5q175 0 336 -64l-35 -80q-91 34 -158.5 47t-144.5 13 q-134 0 -205.5 -44.5t-71.5 -119.5q0 -54 25.5 -88.5t85.5 -65.5t188 -74q192 -64 264 -132.5t72 -170.5q0 -173 -186 -274q86 -42 129 -96t43 -136q0 -135 -113 -207.5t-311 -72.5q-92 0 -171 15t-165 52zM246 825q0 -65 31.5 -104t105.5 -75t250 -99q82 41 126 98t44 121 q0 62 -32 102t-108.5 77t-236.5 87q-81 -23 -130.5 -79t-49.5 -128z" />
+<glyph unicode="&#xa8;" horiz-adv-x="1182" d="M336 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86zM717 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86z" />
+<glyph unicode="&#xa9;" horiz-adv-x="1704" d="M100 731q0 200 100 375t275 276t377 101q200 0 375 -100t276 -275t101 -377q0 -197 -97 -370t-272 -277t-383 -104q-207 0 -382 103.5t-272.5 276.5t-97.5 371zM193 731q0 -178 88.5 -329.5t240.5 -240.5t330 -89t329.5 88.5t240.5 240.5t89 330q0 174 -85.5 325 t-239 243t-334.5 92q-176 0 -328.5 -88.5t-241.5 -242.5t-89 -329zM489 725q0 208 111 332.5t297 124.5q119 0 227 -52l-37 -83q-98 45 -190 45q-142 0 -222.5 -94.5t-80.5 -264.5q0 -186 74.5 -275t220.5 -89q84 0 198 43v-88q-102 -45 -208 -45q-187 0 -288.5 115 t-101.5 331z" />
+<glyph unicode="&#xaa;" horiz-adv-x="686" d="M78 989q0 100 80 151.5t241 59.5l95 4v43q0 77 -38 114.5t-106 37.5q-87 0 -196 -49l-33 73q117 56 231 56q228 0 228 -215v-451h-68l-25 72q-84 -84 -202 -84q-95 0 -151 49t-56 139zM168 993q0 -54 35 -85t96 -31q90 0 142.5 50t52.5 142v64l-88 -5q-116 -6 -177 -36.5 t-61 -98.5z" />
+<glyph unicode="&#xab;" horiz-adv-x="885" d="M82 516v27l309 393l62 -43l-254 -363l254 -362l-62 -43zM442 516v27l310 393l61 -43l-254 -363l254 -362l-61 -43z" />
+<glyph unicode="&#xac;" d="M111 682v82h927v-494h-82v412h-845z" />
+<glyph unicode="&#xad;" horiz-adv-x="659" d="M92 512v82h475v-82h-475z" />
+<glyph unicode="&#xae;" horiz-adv-x="1704" d="M100 731q0 200 100 375t275 276t377 101q200 0 375 -100t276 -275t101 -377q0 -197 -97 -370t-272 -277t-383 -104q-207 0 -382 103.5t-272.5 276.5t-97.5 371zM193 731q0 -178 88.5 -329.5t240.5 -240.5t330 -89t329.5 88.5t240.5 240.5t89 330q0 174 -85.5 325 t-239 243t-334.5 92q-176 0 -328.5 -88.5t-241.5 -242.5t-89 -329zM608 291v880h211q143 0 222 -62t79 -191q0 -79 -38.5 -139.5t-110.5 -94.5l237 -393h-121l-210 360h-168v-360h-101zM709 731h112q91 0 143 46.5t52 135.5q0 172 -197 172h-110v-354z" />
+<glyph unicode="&#xaf;" horiz-adv-x="1024" d="M-6 1556v82h1036v-82h-1036z" />
+<glyph unicode="&#xb0;" horiz-adv-x="877" d="M139 1184q0 132 86.5 215.5t212.5 83.5t212.5 -83.5t86.5 -215.5t-86.5 -215.5t-212.5 -83.5q-130 0 -214.5 83t-84.5 216zM229 1184q0 -91 61 -154t148 -63q86 0 147.5 62t61.5 155q0 92 -60 154.5t-149 62.5q-90 0 -149.5 -64t-59.5 -153z" />
+<glyph unicode="&#xb1;" d="M111 1v82h948v-82h-948zM111 682v82h432v434h82v-434h434v-82h-434v-432h-82v432h-432z" />
+<glyph unicode="&#xb2;" horiz-adv-x="688" d="M53 586v78l242 237q125 121 172 193t47 149q0 71 -46.5 112.5t-123.5 41.5q-108 0 -217 -82l-49 65q119 103 270 103q124 0 194 -63.5t70 -174.5q0 -47 -13 -89t-40 -85.5t-68.5 -90t-308.5 -306.5h447v-88h-576z" />
+<glyph unicode="&#xb3;" horiz-adv-x="688" d="M41 629v88q136 -62 266 -62q115 0 174.5 49t59.5 136q0 83 -59.5 122t-178.5 39h-131v84h135q105 0 158 43.5t53 120.5q0 67 -47 107.5t-127 40.5q-128 0 -246 -78l-47 70q130 94 293 94q127 0 199.5 -60t72.5 -163q0 -78 -44 -131.5t-117 -75.5q186 -45 186 -211 q0 -130 -88.5 -201.5t-247.5 -71.5q-144 0 -264 60z" />
+<glyph unicode="&#xb4;" horiz-adv-x="1182" d="M393 1241v16q73 79 144.5 171.5t97.5 140.5h141v-17q-36 -52 -122.5 -138t-190.5 -173h-70z" />
+<glyph unicode="&#xb5;" horiz-adv-x="1221" d="M182 -492v1579h99v-704q0 -164 69 -238.5t213 -74.5q194 0 285.5 98t91.5 319v600h98v-1087h-84l-18 150h-6q-50 -77 -150 -123.5t-217 -46.5q-99 0 -167.5 27.5t-119.5 84.5q5 -92 5 -170v-414h-99z" />
+<glyph unicode="&#xb6;" horiz-adv-x="1341" d="M113 1042q0 260 109 387t341 127h543v-1816h-100v1722h-228v-1722h-100v819q-64 -18 -146 -18q-216 0 -317.5 125t-101.5 376z" />
+<glyph unicode="&#xb7;" horiz-adv-x="487" d="M162 721q0 98 80 98q82 0 82 -98t-82 -98q-80 0 -80 98z" />
+<glyph unicode="&#xb8;" horiz-adv-x="420" d="M43 -393q30 -10 92 -10q78 0 119 28t41 80q0 94 -193 121l93 174h96l-66 -117q168 -37 168 -174q0 -100 -67.5 -150.5t-188.5 -50.5q-68 0 -94 11v88z" />
+<glyph unicode="&#xb9;" horiz-adv-x="688" d="M76 1298l274 164h92v-876h-98v547q0 99 12 233q-26 -23 -233 -145z" />
+<glyph unicode="&#xba;" horiz-adv-x="739" d="M70 1141q0 162 78 250t223 88q142 0 220.5 -87t78.5 -251q0 -161 -80 -250.5t-223 -89.5t-220 86t-77 254zM160 1141q0 -264 209 -264t209 264q0 131 -50 194.5t-159 63.5t-159 -63.5t-50 -194.5z" />
+<glyph unicode="&#xbb;" horiz-adv-x="885" d="M72 168l254 362l-254 363l61 43l309 -391v-27l-309 -393zM432 168l254 362l-254 363l62 43l309 -391v-27l-309 -393z" />
+<glyph unicode="&#xbc;" horiz-adv-x="1516" d="M59 1298l274 164h92v-876h-98v547q0 99 12 233q-26 -23 -233 -145zM243 0l811 1462h94l-811 -1462h-94zM760 242v60l407 581h96v-563h129v-78h-129v-241h-90v241h-413zM864 320h309v221q0 132 8 232q-6 -12 -21.5 -35.5t-295.5 -417.5z" />
+<glyph unicode="&#xbd;" horiz-adv-x="1516" d="M11 1298l274 164h92v-876h-98v547q0 99 12 233q-26 -23 -233 -145zM168 0l811 1462h94l-811 -1462h-94zM827 1v78l242 237q125 121 172 193t47 149q0 71 -46.5 112.5t-123.5 41.5q-108 0 -217 -82l-49 65q119 103 270 103q124 0 194 -63.5t70 -174.5q0 -47 -13 -89 t-40 -85.5t-68.5 -90t-308.5 -306.5h447v-88h-576z" />
+<glyph unicode="&#xbe;" horiz-adv-x="1516" d="M41 629v88q136 -62 266 -62q115 0 174.5 49t59.5 136q0 83 -59.5 122t-178.5 39h-131v84h135q105 0 158 43.5t53 120.5q0 67 -47 107.5t-127 40.5q-128 0 -246 -78l-47 70q130 94 293 94q127 0 199.5 -60t72.5 -163q0 -78 -44 -131.5t-117 -75.5q186 -45 186 -211 q0 -130 -88.5 -201.5t-247.5 -71.5q-144 0 -264 60zM395 0l811 1462h94l-811 -1462h-94zM863 242v60l407 581h96v-563h129v-78h-129v-241h-90v241h-413zM967 320h309v221q0 132 8 232q-6 -12 -21.5 -35.5t-295.5 -417.5z" />
+<glyph unicode="&#xbf;" horiz-adv-x="862" d="M74 -27q0 70 20 124t58.5 102t171.5 159q64 53 98.5 98.5t49.5 94t15 145.5v15h82v-37q0 -125 -39.5 -204.5t-136.5 -164.5l-90 -79q-73 -61 -104 -120.5t-31 -138.5q0 -124 82 -200t221 -76q125 0 233 46l64 27l37 -79q-111 -48 -185.5 -64t-152.5 -16q-184 0 -288.5 99 t-104.5 269zM440 1010q0 98 80 98q82 0 82 -98q0 -53 -23.5 -76t-58.5 -23q-34 0 -57 23t-23 76z" />
+<glyph unicode="&#xc0;" horiz-adv-x="1229" d="M0 0l588 1468h65l576 -1468h-115l-203 516h-594l-204 -516h-113zM337 1890v17h142q26 -48 98.5 -142t142.5 -170v-16h-69q-96 79 -188.5 171.5t-125.5 139.5zM354 608h523l-199 527q-25 62 -60 172q-27 -96 -59 -174z" />
+<glyph unicode="&#xc1;" horiz-adv-x="1229" d="M0 0l588 1468h65l576 -1468h-115l-203 516h-594l-204 -516h-113zM354 608h523l-199 527q-25 62 -60 172q-27 -96 -59 -174zM504 1579v16q73 79 144.5 171.5t97.5 140.5h141v-17q-36 -52 -122.5 -138t-190.5 -173h-70z" />
+<glyph unicode="&#xc2;" horiz-adv-x="1229" d="M0 0l588 1468h65l576 -1468h-115l-203 516h-594l-204 -516h-113zM328 1579v16q62 67 131.5 156t110.5 156h98q68 -120 242 -312v-16h-70q-122 101 -221 207q-108 -114 -221 -207h-70zM354 608h523l-199 527q-25 62 -60 172q-27 -96 -59 -174z" />
+<glyph unicode="&#xc3;" horiz-adv-x="1229" d="M0 0l588 1468h65l576 -1468h-115l-203 516h-594l-204 -516h-113zM287 1581q10 111 63 174.5t137 63.5q48 0 88 -25t82 -59q34 -28 66 -50t61 -22q46 0 77 36.5t48 119.5h76q-16 -116 -69 -177t-132 -61q-36 0 -75 18.5t-101 71.5q-32 26 -62.5 46t-62.5 20 q-45 0 -75 -34.5t-48 -121.5h-73zM354 608h523l-199 527q-25 62 -60 172q-27 -96 -59 -174z" />
+<glyph unicode="&#xc4;" horiz-adv-x="1229" d="M0 0l588 1468h65l576 -1468h-115l-203 516h-594l-204 -516h-113zM354 608h523l-199 527q-25 62 -60 172q-27 -96 -59 -174zM367 1727q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86zM748 1727q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86z" />
+<glyph unicode="&#xc5;" horiz-adv-x="1229" d="M0 0l588 1468h65l576 -1468h-115l-203 516h-594l-204 -516h-113zM354 608h523l-199 527q-25 62 -60 172q-27 -96 -59 -174zM402 1610q0 94 60 152.5t157 58.5t157 -59t60 -152q0 -97 -60 -155t-157 -58t-157 58t-60 155zM482 1610q0 -66 37.5 -103.5t99.5 -37.5 t99.5 37.5t37.5 103.5q0 64 -39 101.5t-98 37.5q-62 0 -99.5 -38t-37.5 -101z" />
+<glyph unicode="&#xc6;" horiz-adv-x="1653" d="M-2 0l653 1462h877v-94h-615v-553h576v-94h-576v-627h615v-94h-717v516h-475l-227 -516h-111zM377 608h434v760h-100z" />
+<glyph unicode="&#xc7;" horiz-adv-x="1272" d="M129 735q0 223 84.5 393t243 262.5t368.5 92.5q214 0 383 -80l-41 -92q-160 80 -336 80q-275 0 -433 -176t-158 -482q0 -313 149 -486t426 -173q184 0 338 47v-90q-145 -51 -362 -51q-308 0 -485 199t-177 556zM561 -393q30 -10 92 -10q78 0 119 28t41 80q0 94 -193 121 l93 174h96l-66 -117q168 -37 168 -174q0 -100 -67.5 -150.5t-188.5 -50.5q-68 0 -94 11v88z" />
+<glyph unicode="&#xc8;" horiz-adv-x="1130" d="M207 0v1462h799v-94h-697v-553h658v-94h-658v-627h697v-94h-799zM314 1890v17h142q26 -48 98.5 -142t142.5 -170v-16h-69q-96 79 -188.5 171.5t-125.5 139.5z" />
+<glyph unicode="&#xc9;" horiz-adv-x="1130" d="M207 0v1462h799v-94h-697v-553h658v-94h-658v-627h697v-94h-799zM463 1579v16q73 79 144.5 171.5t97.5 140.5h141v-17q-36 -52 -122.5 -138t-190.5 -173h-70z" />
+<glyph unicode="&#xca;" horiz-adv-x="1130" d="M207 0v1462h799v-94h-697v-553h658v-94h-658v-627h697v-94h-799zM315 1579v16q62 67 131.5 156t110.5 156h98q68 -120 242 -312v-16h-70q-122 101 -221 207q-108 -114 -221 -207h-70z" />
+<glyph unicode="&#xcb;" horiz-adv-x="1130" d="M207 0v1462h799v-94h-697v-553h658v-94h-658v-627h697v-94h-799zM354 1727q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86zM735 1727q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86z" />
+<glyph unicode="&#xcc;" horiz-adv-x="516" d="M-63 1890v17h142q26 -48 98.5 -142t142.5 -170v-16h-69q-96 79 -188.5 171.5t-125.5 139.5zM207 0v1462h102v-1462h-102z" />
+<glyph unicode="&#xcd;" horiz-adv-x="516" d="M191 1579v16q73 79 144.5 171.5t97.5 140.5h141v-17q-36 -52 -122.5 -138t-190.5 -173h-70zM207 0v1462h102v-1462h-102z" />
+<glyph unicode="&#xce;" horiz-adv-x="516" d="M-32 1579v16q62 67 131.5 156t110.5 156h98q68 -120 242 -312v-16h-70q-122 101 -221 207q-108 -114 -221 -207h-70zM207 0v1462h102v-1462h-102z" />
+<glyph unicode="&#xcf;" horiz-adv-x="516" d="M5 1727q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86zM207 0v1462h102v-1462h-102zM386 1727q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86z" />
+<glyph unicode="&#xd0;" horiz-adv-x="1466" d="M47 678v94h160v690h395q350 0 532.5 -183t182.5 -534q0 -368 -193 -556.5t-567 -188.5h-350v678h-160zM309 90h242q655 0 655 651q0 314 -159.5 472.5t-468.5 158.5h-269v-600h406v-94h-406v-588z" />
+<glyph unicode="&#xd1;" horiz-adv-x="1477" d="M207 0v1462h102l865 -1296h6q-9 180 -9 342v954h99v-1462h-103l-866 1298h-8q12 -232 12 -350v-948h-98zM400 1581q10 111 63 174.5t137 63.5q48 0 88 -25t82 -59q34 -28 66 -50t61 -22q46 0 77 36.5t48 119.5h76q-16 -116 -69 -177t-132 -61q-36 0 -75 18.5t-101 71.5 q-32 26 -62.5 46t-62.5 20q-45 0 -75 -34.5t-48 -121.5h-73z" />
+<glyph unicode="&#xd2;" horiz-adv-x="1565" d="M129 735q0 349 175.5 549.5t479.5 200.5q306 0 479 -201.5t173 -550.5q0 -348 -174 -550.5t-480 -202.5q-305 0 -479 202.5t-174 552.5zM240 733q0 -314 140 -485.5t402 -171.5q264 0 403.5 170t139.5 487q0 316 -139.5 484.5t-401.5 168.5q-261 0 -402.5 -170 t-141.5 -483zM502 1890v17h142q26 -48 98.5 -142t142.5 -170v-16h-69q-96 79 -188.5 171.5t-125.5 139.5z" />
+<glyph unicode="&#xd3;" horiz-adv-x="1565" d="M129 735q0 349 175.5 549.5t479.5 200.5q306 0 479 -201.5t173 -550.5q0 -348 -174 -550.5t-480 -202.5q-305 0 -479 202.5t-174 552.5zM240 733q0 -314 140 -485.5t402 -171.5q264 0 403.5 170t139.5 487q0 316 -139.5 484.5t-401.5 168.5q-261 0 -402.5 -170 t-141.5 -483zM686 1579v16q73 79 144.5 171.5t97.5 140.5h141v-17q-36 -52 -122.5 -138t-190.5 -173h-70z" />
+<glyph unicode="&#xd4;" horiz-adv-x="1565" d="M129 735q0 349 175.5 549.5t479.5 200.5q306 0 479 -201.5t173 -550.5q0 -348 -174 -550.5t-480 -202.5q-305 0 -479 202.5t-174 552.5zM240 733q0 -314 140 -485.5t402 -171.5q264 0 403.5 170t139.5 487q0 316 -139.5 484.5t-401.5 168.5q-261 0 -402.5 -170 t-141.5 -483zM492 1579v16q62 67 131.5 156t110.5 156h98q68 -120 242 -312v-16h-70q-122 101 -221 207q-108 -114 -221 -207h-70z" />
+<glyph unicode="&#xd5;" horiz-adv-x="1565" d="M129 735q0 349 175.5 549.5t479.5 200.5q306 0 479 -201.5t173 -550.5q0 -348 -174 -550.5t-480 -202.5q-305 0 -479 202.5t-174 552.5zM240 733q0 -314 140 -485.5t402 -171.5q264 0 403.5 170t139.5 487q0 316 -139.5 484.5t-401.5 168.5q-261 0 -402.5 -170 t-141.5 -483zM443 1581q10 111 63 174.5t137 63.5q48 0 88 -25t82 -59q34 -28 66 -50t61 -22q46 0 77 36.5t48 119.5h76q-16 -116 -69 -177t-132 -61q-36 0 -75 18.5t-101 71.5q-32 26 -62.5 46t-62.5 20q-45 0 -75 -34.5t-48 -121.5h-73z" />
+<glyph unicode="&#xd6;" horiz-adv-x="1565" d="M129 735q0 349 175.5 549.5t479.5 200.5q306 0 479 -201.5t173 -550.5q0 -348 -174 -550.5t-480 -202.5q-305 0 -479 202.5t-174 552.5zM240 733q0 -314 140 -485.5t402 -171.5q264 0 403.5 170t139.5 487q0 316 -139.5 484.5t-401.5 168.5q-261 0 -402.5 -170 t-141.5 -483zM529 1727q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86zM910 1727q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86z" />
+<glyph unicode="&#xd7;" d="M119 1130l57 58l408 -408l409 408l58 -58l-408 -407l406 -408l-58 -57l-407 408l-406 -408l-57 57l405 408z" />
+<glyph unicode="&#xd8;" horiz-adv-x="1565" d="M129 735q0 349 175.5 549.5t479.5 200.5q232 0 392 -121l108 152l72 -60l-111 -153q191 -207 191 -570q0 -348 -174 -550.5t-480 -202.5q-236 0 -395 120l-86 -120l-74 59l90 127q-188 200 -188 569zM240 733q0 -312 139 -483l739 1034q-133 102 -334 102 q-261 0 -402.5 -170t-141.5 -483zM444 182q133 -106 338 -106q264 0 403.5 170t139.5 487q0 315 -139 486z" />
+<glyph unicode="&#xd9;" horiz-adv-x="1473" d="M190 520v942h103v-946q0 -211 117 -328.5t331 -117.5q209 0 324 115.5t115 320.5v956h102v-946q0 -252 -146 -394t-407 -142q-254 0 -396.5 142.5t-142.5 397.5zM450 1890v17h142q26 -48 98.5 -142t142.5 -170v-16h-69q-96 79 -188.5 171.5t-125.5 139.5z" />
+<glyph unicode="&#xda;" horiz-adv-x="1473" d="M190 520v942h103v-946q0 -211 117 -328.5t331 -117.5q209 0 324 115.5t115 320.5v956h102v-946q0 -252 -146 -394t-407 -142q-254 0 -396.5 142.5t-142.5 397.5zM633 1579v16q73 79 144.5 171.5t97.5 140.5h141v-17q-36 -52 -122.5 -138t-190.5 -173h-70z" />
+<glyph unicode="&#xdb;" horiz-adv-x="1473" d="M190 520v942h103v-946q0 -211 117 -328.5t331 -117.5q209 0 324 115.5t115 320.5v956h102v-946q0 -252 -146 -394t-407 -142q-254 0 -396.5 142.5t-142.5 397.5zM444 1579v16q62 67 131.5 156t110.5 156h98q68 -120 242 -312v-16h-70q-122 101 -221 207 q-108 -114 -221 -207h-70z" />
+<glyph unicode="&#xdc;" horiz-adv-x="1473" d="M190 520v942h103v-946q0 -211 117 -328.5t331 -117.5q209 0 324 115.5t115 320.5v956h102v-946q0 -252 -146 -394t-407 -142q-254 0 -396.5 142.5t-142.5 397.5zM481 1727q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86zM862 1727q0 46 15.5 66t47.5 20 q64 0 64 -86t-64 -86q-63 0 -63 86z" />
+<glyph unicode="&#xdd;" horiz-adv-x="1081" d="M0 1462h117l426 -800l428 800h110l-487 -897v-565h-105v557zM434 1579v16q73 79 144.5 171.5t97.5 140.5h141v-17q-36 -52 -122.5 -138t-190.5 -173h-70z" />
+<glyph unicode="&#xde;" horiz-adv-x="1198" d="M207 0v1462h102v-264h256q522 0 522 -420q0 -212 -144 -325t-408 -113h-226v-340h-102zM309 428h201q247 0 357 81.5t110 264.5q0 169 -104 250.5t-322 81.5h-242v-678z" />
+<glyph unicode="&#xdf;" horiz-adv-x="1194" d="M182 0v1206q0 173 103.5 267t292.5 94q188 0 285.5 -72.5t97.5 -210.5q0 -139 -139 -250q-81 -64 -110.5 -100.5t-29.5 -75.5q0 -44 14.5 -68t51.5 -57t102 -78q106 -75 151.5 -124.5t68 -103t22.5 -120.5q0 -156 -88 -241.5t-246 -85.5q-95 0 -174.5 18.5t-126.5 48.5 v107q65 -38 148.5 -62t152.5 -24q114 0 174.5 54.5t60.5 160.5q0 83 -39 144t-149 136q-127 87 -175 147t-48 146q0 60 32.5 110t106.5 108q74 57 106.5 105.5t32.5 106.5q0 93 -70 143t-202 50q-145 0 -226 -69t-81 -196v-1214h-99z" />
+<glyph unicode="&#xe0;" horiz-adv-x="1085" d="M98 289q0 159 132.5 247t383.5 93l207 6v72q0 155 -63 234t-203 79q-151 0 -313 -84l-37 86q179 84 354 84q179 0 267.5 -93t88.5 -290v-723h-73l-25 172h-8q-82 -105 -168.5 -148.5t-204.5 -43.5q-160 0 -249 82t-89 227zM203 285q0 -102 62.5 -158.5t176.5 -56.5 q174 0 274.5 99.5t100.5 276.5v107l-190 -8q-229 -11 -326.5 -71.5t-97.5 -188.5zM255 1552v17h142q26 -48 98.5 -142t142.5 -170v-16h-69q-96 79 -188.5 171.5t-125.5 139.5z" />
+<glyph unicode="&#xe1;" horiz-adv-x="1085" d="M98 289q0 159 132.5 247t383.5 93l207 6v72q0 155 -63 234t-203 79q-151 0 -313 -84l-37 86q179 84 354 84q179 0 267.5 -93t88.5 -290v-723h-73l-25 172h-8q-82 -105 -168.5 -148.5t-204.5 -43.5q-160 0 -249 82t-89 227zM203 285q0 -102 62.5 -158.5t176.5 -56.5 q174 0 274.5 99.5t100.5 276.5v107l-190 -8q-229 -11 -326.5 -71.5t-97.5 -188.5zM422 1241v16q73 79 144.5 171.5t97.5 140.5h141v-17q-36 -52 -122.5 -138t-190.5 -173h-70z" />
+<glyph unicode="&#xe2;" horiz-adv-x="1085" d="M98 289q0 159 132.5 247t383.5 93l207 6v72q0 155 -63 234t-203 79q-151 0 -313 -84l-37 86q179 84 354 84q179 0 267.5 -93t88.5 -290v-723h-73l-25 172h-8q-82 -105 -168.5 -148.5t-204.5 -43.5q-160 0 -249 82t-89 227zM203 285q0 -102 62.5 -158.5t176.5 -56.5 q174 0 274.5 99.5t100.5 276.5v107l-190 -8q-229 -11 -326.5 -71.5t-97.5 -188.5zM251 1241v16q62 67 131.5 156t110.5 156h98q68 -120 242 -312v-16h-70q-122 101 -221 207q-108 -114 -221 -207h-70z" />
+<glyph unicode="&#xe3;" horiz-adv-x="1085" d="M98 289q0 159 132.5 247t383.5 93l207 6v72q0 155 -63 234t-203 79q-151 0 -313 -84l-37 86q179 84 354 84q179 0 267.5 -93t88.5 -290v-723h-73l-25 172h-8q-82 -105 -168.5 -148.5t-204.5 -43.5q-160 0 -249 82t-89 227zM200 1243q10 111 63 174.5t137 63.5 q48 0 88 -25t82 -59q34 -28 66 -50t61 -22q46 0 77 36.5t48 119.5h76q-16 -116 -69 -177t-132 -61q-36 0 -75 18.5t-101 71.5q-32 26 -62.5 46t-62.5 20q-45 0 -75 -34.5t-48 -121.5h-73zM203 285q0 -102 62.5 -158.5t176.5 -56.5q174 0 274.5 99.5t100.5 276.5v107l-190 -8 q-229 -11 -326.5 -71.5t-97.5 -188.5z" />
+<glyph unicode="&#xe4;" horiz-adv-x="1085" d="M98 289q0 159 132.5 247t383.5 93l207 6v72q0 155 -63 234t-203 79q-151 0 -313 -84l-37 86q179 84 354 84q179 0 267.5 -93t88.5 -290v-723h-73l-25 172h-8q-82 -105 -168.5 -148.5t-204.5 -43.5q-160 0 -249 82t-89 227zM203 285q0 -102 62.5 -158.5t176.5 -56.5 q174 0 274.5 99.5t100.5 276.5v107l-190 -8q-229 -11 -326.5 -71.5t-97.5 -188.5zM282 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86zM663 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86z" />
+<glyph unicode="&#xe5;" horiz-adv-x="1085" d="M98 289q0 159 132.5 247t383.5 93l207 6v72q0 155 -63 234t-203 79q-151 0 -313 -84l-37 86q179 84 354 84q179 0 267.5 -93t88.5 -290v-723h-73l-25 172h-8q-82 -105 -168.5 -148.5t-204.5 -43.5q-160 0 -249 82t-89 227zM203 285q0 -102 62.5 -158.5t176.5 -56.5 q174 0 274.5 99.5t100.5 276.5v107l-190 -8q-229 -11 -326.5 -71.5t-97.5 -188.5zM325 1456q0 94 60 152.5t157 58.5t157 -59t60 -152q0 -97 -60 -155t-157 -58t-157 58t-60 155zM405 1456q0 -66 37.5 -103.5t99.5 -37.5t99.5 37.5t37.5 103.5q0 64 -39 101.5t-98 37.5 q-62 0 -99.5 -38t-37.5 -101z" />
+<glyph unicode="&#xe6;" horiz-adv-x="1731" d="M98 289q0 154 125 243t377 97l201 6v72q0 155 -61.5 234t-198.5 79q-148 0 -305 -84l-37 86q173 84 346 84q261 0 325 -211q111 213 347 213q184 0 289.5 -134.5t105.5 -363.5v-80h-715q0 -460 348 -460q85 0 150 12t174 57v-90q-92 -41 -165 -55t-161 -14 q-295 0 -397 256q-68 -133 -168 -194.5t-252 -61.5q-156 0 -242 82.5t-86 226.5zM203 285q0 -102 61 -158.5t170 -56.5q169 0 266 99.5t97 276.5v107l-187 -8q-219 -11 -313 -71.5t-94 -188.5zM903 618h604q0 188 -77.5 295t-212.5 107q-284 0 -314 -402z" />
+<glyph unicode="&#xe7;" horiz-adv-x="973" d="M119 537q0 270 137 420.5t375 150.5q141 0 270 -49l-27 -88q-141 47 -245 47q-200 0 -303 -123.5t-103 -355.5q0 -220 103 -344.5t288 -124.5q148 0 275 53v-92q-104 -51 -273 -51q-233 0 -365 147t-132 410zM373 -393q30 -10 92 -10q78 0 119 28t41 80q0 94 -193 121 l93 174h96l-66 -117q168 -37 168 -174q0 -100 -67.5 -150.5t-188.5 -50.5q-68 0 -94 11v88z" />
+<glyph unicode="&#xe8;" horiz-adv-x="1124" d="M119 535q0 260 128 416.5t345 156.5q192 0 303 -134t111 -364v-80h-783q2 -224 104.5 -342t293.5 -118q93 0 163.5 13t178.5 56v-90q-92 -40 -170 -54.5t-172 -14.5q-237 0 -369.5 146t-132.5 409zM229 618h672q0 189 -82 295.5t-227 106.5q-157 0 -252 -103.5 t-111 -298.5zM302 1552v17h142q26 -48 98.5 -142t142.5 -170v-16h-69q-96 79 -188.5 171.5t-125.5 139.5z" />
+<glyph unicode="&#xe9;" horiz-adv-x="1124" d="M119 535q0 260 128 416.5t345 156.5q192 0 303 -134t111 -364v-80h-783q2 -224 104.5 -342t293.5 -118q93 0 163.5 13t178.5 56v-90q-92 -40 -170 -54.5t-172 -14.5q-237 0 -369.5 146t-132.5 409zM229 618h672q0 189 -82 295.5t-227 106.5q-157 0 -252 -103.5 t-111 -298.5zM452 1241v16q73 79 144.5 171.5t97.5 140.5h141v-17q-36 -52 -122.5 -138t-190.5 -173h-70z" />
+<glyph unicode="&#xea;" horiz-adv-x="1124" d="M119 535q0 260 128 416.5t345 156.5q192 0 303 -134t111 -364v-80h-783q2 -224 104.5 -342t293.5 -118q93 0 163.5 13t178.5 56v-90q-92 -40 -170 -54.5t-172 -14.5q-237 0 -369.5 146t-132.5 409zM229 618h672q0 189 -82 295.5t-227 106.5q-157 0 -252 -103.5 t-111 -298.5zM290 1241v16q62 67 131.5 156t110.5 156h98q68 -120 242 -312v-16h-70q-122 101 -221 207q-108 -114 -221 -207h-70z" />
+<glyph unicode="&#xeb;" horiz-adv-x="1124" d="M119 535q0 260 128 416.5t345 156.5q192 0 303 -134t111 -364v-80h-783q2 -224 104.5 -342t293.5 -118q93 0 163.5 13t178.5 56v-90q-92 -40 -170 -54.5t-172 -14.5q-237 0 -369.5 146t-132.5 409zM229 618h672q0 189 -82 295.5t-227 106.5q-157 0 -252 -103.5 t-111 -298.5zM331 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86zM712 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86z" />
+<glyph unicode="&#xec;" horiz-adv-x="463" d="M-34 1552v17h142q26 -48 98.5 -142t142.5 -170v-16h-69q-96 79 -188.5 171.5t-125.5 139.5zM182 0v1087h99v-1087h-99z" />
+<glyph unicode="&#xed;" horiz-adv-x="463" d="M107 1241v16q73 79 144.5 171.5t97.5 140.5h141v-17q-36 -52 -122.5 -138t-190.5 -173h-70zM182 0v1087h99v-1087h-99z" />
+<glyph unicode="&#xee;" horiz-adv-x="463" d="M-58 1241v16q62 67 131.5 156t110.5 156h98q68 -120 242 -312v-16h-70q-122 101 -221 207q-108 -114 -221 -207h-70zM182 0v1087h99v-1087h-99z" />
+<glyph unicode="&#xef;" horiz-adv-x="463" d="M-21 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86zM182 0v1087h99v-1087h-99zM360 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86z" />
+<glyph unicode="&#xf0;" horiz-adv-x="1174" d="M117 471q0 228 126.5 357.5t342.5 129.5q108 0 187.5 -33t148.5 -96l4 2q-64 270 -269 459l-270 -157l-49 77l244 146q-86 62 -199 119l45 81q147 -69 248 -145l225 137l49 -84l-202 -121q154 -151 230.5 -353t76.5 -431q0 -276 -124 -427.5t-349 -151.5 q-214 0 -339.5 130t-125.5 361zM221 463q0 -186 94.5 -289.5t268.5 -103.5q179 0 272.5 123t93.5 364q0 146 -97 228.5t-267 82.5q-185 0 -275 -100.5t-90 -304.5z" />
+<glyph unicode="&#xf1;" horiz-adv-x="1208" d="M182 0v1087h84l19 -149h6q106 170 377 170q370 0 370 -397v-711h-98v705q0 164 -69 238.5t-214 74.5q-195 0 -285.5 -98.5t-90.5 -319.5v-600h-99zM282 1243q10 111 63 174.5t137 63.5q48 0 88 -25t82 -59q34 -28 66 -50t61 -22q46 0 77 36.5t48 119.5h76 q-16 -116 -69 -177t-132 -61q-36 0 -75 18.5t-101 71.5q-32 26 -62.5 46t-62.5 20q-45 0 -75 -34.5t-48 -121.5h-73z" />
+<glyph unicode="&#xf2;" horiz-adv-x="1200" d="M119 545q0 266 129 414.5t354 148.5q224 0 351.5 -150.5t127.5 -412.5q0 -266 -129 -415.5t-356 -149.5q-143 0 -252 69t-167 198t-58 298zM223 545q0 -224 98.5 -349.5t278.5 -125.5t278.5 125.5t98.5 349.5q0 225 -99.5 349t-279.5 124t-277.5 -123.5t-97.5 -349.5z M335 1552v17h142q26 -48 98.5 -142t142.5 -170v-16h-69q-96 79 -188.5 171.5t-125.5 139.5z" />
+<glyph unicode="&#xf3;" horiz-adv-x="1200" d="M119 545q0 266 129 414.5t354 148.5q224 0 351.5 -150.5t127.5 -412.5q0 -266 -129 -415.5t-356 -149.5q-143 0 -252 69t-167 198t-58 298zM223 545q0 -224 98.5 -349.5t278.5 -125.5t278.5 125.5t98.5 349.5q0 225 -99.5 349t-279.5 124t-277.5 -123.5t-97.5 -349.5z M499 1241v16q73 79 144.5 171.5t97.5 140.5h141v-17q-36 -52 -122.5 -138t-190.5 -173h-70z" />
+<glyph unicode="&#xf4;" horiz-adv-x="1200" d="M119 545q0 266 129 414.5t354 148.5q224 0 351.5 -150.5t127.5 -412.5q0 -266 -129 -415.5t-356 -149.5q-143 0 -252 69t-167 198t-58 298zM223 545q0 -224 98.5 -349.5t278.5 -125.5t278.5 125.5t98.5 349.5q0 225 -99.5 349t-279.5 124t-277.5 -123.5t-97.5 -349.5z M309 1241v16q62 67 131.5 156t110.5 156h98q68 -120 242 -312v-16h-70q-122 101 -221 207q-108 -114 -221 -207h-70z" />
+<glyph unicode="&#xf5;" horiz-adv-x="1200" d="M119 545q0 266 129 414.5t354 148.5q224 0 351.5 -150.5t127.5 -412.5q0 -266 -129 -415.5t-356 -149.5q-143 0 -252 69t-167 198t-58 298zM223 545q0 -224 98.5 -349.5t278.5 -125.5t278.5 125.5t98.5 349.5q0 225 -99.5 349t-279.5 124t-277.5 -123.5t-97.5 -349.5z M264 1243q10 111 63 174.5t137 63.5q48 0 88 -25t82 -59q34 -28 66 -50t61 -22q46 0 77 36.5t48 119.5h76q-16 -116 -69 -177t-132 -61q-36 0 -75 18.5t-101 71.5q-32 26 -62.5 46t-62.5 20q-45 0 -75 -34.5t-48 -121.5h-73z" />
+<glyph unicode="&#xf6;" horiz-adv-x="1200" d="M119 545q0 266 129 414.5t354 148.5q224 0 351.5 -150.5t127.5 -412.5q0 -266 -129 -415.5t-356 -149.5q-143 0 -252 69t-167 198t-58 298zM223 545q0 -224 98.5 -349.5t278.5 -125.5t278.5 125.5t98.5 349.5q0 225 -99.5 349t-279.5 124t-277.5 -123.5t-97.5 -349.5z M346 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86zM727 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86z" />
+<glyph unicode="&#xf7;" d="M111 682v82h948v-82h-948zM504 371q0 98 80 98q82 0 82 -98q0 -53 -23.5 -76t-58.5 -23q-34 0 -57 23t-23 76zM504 1075q0 99 80 99q82 0 82 -99q0 -52 -23.5 -75t-58.5 -23q-34 0 -57 23t-23 75z" />
+<glyph unicode="&#xf8;" horiz-adv-x="1200" d="M119 545q0 266 129 414.5t354 148.5q179 0 301 -104l96 124l74 -55l-104 -137q112 -147 112 -391q0 -266 -129 -415.5t-356 -149.5q-173 0 -291 98l-86 -113l-72 58l93 120q-121 153 -121 402zM223 545q0 -200 78 -322l543 705q-98 90 -246 90q-180 0 -277.5 -123.5 t-97.5 -349.5zM362 152q94 -82 238 -82q180 0 278.5 125.5t98.5 349.5q0 190 -72 309z" />
+<glyph unicode="&#xf9;" horiz-adv-x="1208" d="M170 377v710h98v-704q0 -164 69 -238.5t214 -74.5q194 0 285.5 98t91.5 319v600h98v-1087h-84l-18 150h-6q-106 -170 -377 -170q-371 0 -371 397zM304 1552v17h142q26 -48 98.5 -142t142.5 -170v-16h-69q-96 79 -188.5 171.5t-125.5 139.5z" />
+<glyph unicode="&#xfa;" horiz-adv-x="1208" d="M170 377v710h98v-704q0 -164 69 -238.5t214 -74.5q194 0 285.5 98t91.5 319v600h98v-1087h-84l-18 150h-6q-106 -170 -377 -170q-371 0 -371 397zM495 1241v16q73 79 144.5 171.5t97.5 140.5h141v-17q-36 -52 -122.5 -138t-190.5 -173h-70z" />
+<glyph unicode="&#xfb;" horiz-adv-x="1208" d="M170 377v710h98v-704q0 -164 69 -238.5t214 -74.5q194 0 285.5 98t91.5 319v600h98v-1087h-84l-18 150h-6q-106 -170 -377 -170q-371 0 -371 397zM313 1241v16q62 67 131.5 156t110.5 156h98q68 -120 242 -312v-16h-70q-122 101 -221 207q-108 -114 -221 -207h-70z" />
+<glyph unicode="&#xfc;" horiz-adv-x="1208" d="M170 377v710h98v-704q0 -164 69 -238.5t214 -74.5q194 0 285.5 98t91.5 319v600h98v-1087h-84l-18 150h-6q-106 -170 -377 -170q-371 0 -371 397zM350 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86zM731 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86 q-63 0 -63 86z" />
+<glyph unicode="&#xfd;" horiz-adv-x="940" d="M0 1087h102l230 -610q105 -281 133 -379h6q42 129 137 385l230 604h102l-487 -1263q-59 -154 -99 -208t-93.5 -81t-129.5 -27q-57 0 -127 21v86q58 -16 125 -16q51 0 90 24t70.5 74.5t72.5 160.5l54 142zM361 1241v16q73 79 144.5 171.5t97.5 140.5h141v-17 q-36 -52 -122.5 -138t-190.5 -173h-70z" />
+<glyph unicode="&#xfe;" horiz-adv-x="1219" d="M182 -492v2048h99v-391l-7 -247h7q114 190 368 190q220 0 335.5 -144.5t115.5 -420.5q0 -268 -121.5 -415.5t-331.5 -147.5q-251 0 -366 188h-7l3 -84q4 -74 4 -162v-414h-99zM281 541q0 -255 85.5 -364t278.5 -109q167 0 258.5 124t91.5 347q0 479 -348 479 q-193 0 -279.5 -105t-86.5 -354v-18z" />
+<glyph unicode="&#xff;" horiz-adv-x="940" d="M0 1087h102l230 -610q105 -281 133 -379h6q42 129 137 385l230 604h102l-487 -1263q-59 -154 -99 -208t-93.5 -81t-129.5 -27q-57 0 -127 21v86q58 -16 125 -16q51 0 90 24t70.5 74.5t72.5 160.5l54 142zM214 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86 q-63 0 -63 86zM595 1389q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86z" />
+<glyph unicode="&#x131;" horiz-adv-x="463" d="M182 0v1087h99v-1087h-99z" />
+<glyph unicode="&#x152;" horiz-adv-x="1839" d="M129 735q0 347 174.5 545.5t480.5 198.5q78 0 183 -17h747v-94h-655v-553h616v-94h-616v-627h655v-94h-756q-76 -16 -176 -16q-305 0 -479 200t-174 551zM240 733q0 -315 140.5 -484t401.5 -169q109 0 174 18v1266q-62 16 -172 16q-262 0 -403 -167.5t-141 -479.5z" />
+<glyph unicode="&#x153;" horiz-adv-x="1942" d="M119 545q0 266 129 414.5t354 148.5q151 0 251 -70t157 -209q110 279 399 279q192 0 303 -134t111 -364v-80h-762q2 -230 100.5 -345t276.5 -115q93 0 163.5 13t178.5 56v-90q-92 -40 -170 -54.5t-172 -14.5q-156 0 -266.5 67.5t-165.5 198.5q-59 -128 -158 -197 t-252 -69q-143 0 -252 69t-167 198t-58 298zM223 545q0 -224 98.5 -349.5t278.5 -125.5q174 0 265 122.5t91 352.5q0 224 -93 348.5t-265 124.5q-180 0 -277.5 -123.5t-97.5 -349.5zM1065 618h653q0 189 -82 295.5t-227 106.5q-155 0 -242 -104t-102 -298z" />
+<glyph unicode="&#x178;" horiz-adv-x="1081" d="M0 1462h117l426 -800l428 800h110l-487 -897v-565h-105v557zM288 1727q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86zM669 1727q0 46 15.5 66t47.5 20q64 0 64 -86t-64 -86q-63 0 -63 86z" />
+<glyph unicode="&#x2c6;" horiz-adv-x="1182" d="M299 1241v16q62 67 131.5 156t110.5 156h98q68 -120 242 -312v-16h-70q-122 101 -221 207q-108 -114 -221 -207h-70z" />
+<glyph unicode="&#x2da;" horiz-adv-x="1182" d="M371 1456q0 94 60 152.5t157 58.5t157 -59t60 -152q0 -97 -60 -155t-157 -58t-157 58t-60 155zM451 1456q0 -66 37.5 -103.5t99.5 -37.5t99.5 37.5t37.5 103.5q0 64 -39 101.5t-98 37.5q-62 0 -99.5 -38t-37.5 -101z" />
+<glyph unicode="&#x2dc;" horiz-adv-x="1182" d="M283 1243q10 111 63 174.5t137 63.5q48 0 88 -25t82 -59q34 -28 66 -50t61 -22q46 0 77 36.5t48 119.5h76q-16 -116 -69 -177t-132 -61q-36 0 -75 18.5t-101 71.5q-32 26 -62.5 46t-62.5 20q-45 0 -75 -34.5t-48 -121.5h-73z" />
+<glyph unicode="&#x2000;" horiz-adv-x="953" />
+<glyph unicode="&#x2001;" horiz-adv-x="1907" />
+<glyph unicode="&#x2002;" horiz-adv-x="953" />
+<glyph unicode="&#x2003;" horiz-adv-x="1907" />
+<glyph unicode="&#x2004;" horiz-adv-x="635" />
+<glyph unicode="&#x2005;" horiz-adv-x="476" />
+<glyph unicode="&#x2006;" horiz-adv-x="317" />
+<glyph unicode="&#x2007;" horiz-adv-x="317" />
+<glyph unicode="&#x2008;" horiz-adv-x="238" />
+<glyph unicode="&#x2009;" horiz-adv-x="381" />
+<glyph unicode="&#x200a;" horiz-adv-x="105" />
+<glyph unicode="&#x2010;" horiz-adv-x="659" d="M92 512v82h475v-82h-475z" />
+<glyph unicode="&#x2011;" horiz-adv-x="659" d="M92 512v82h475v-82h-475z" />
+<glyph unicode="&#x2012;" horiz-adv-x="659" d="M92 512v82h475v-82h-475z" />
+<glyph unicode="&#x2013;" horiz-adv-x="1024" d="M82 512v82h860v-82h-860z" />
+<glyph unicode="&#x2014;" horiz-adv-x="2048" d="M82 512v82h1884v-82h-1884z" />
+<glyph unicode="&#x2018;" horiz-adv-x="297" d="M29 981q32 112 81.5 251t92.5 230h65q-30 -101 -64.5 -257t-45.5 -244h-117z" />
+<glyph unicode="&#x2019;" horiz-adv-x="297" d="M29 961q29 96 61 241.5t49 259.5h117l12 -20q-75 -265 -174 -481h-65z" />
+<glyph unicode="&#x201a;" horiz-adv-x="451" d="M68 -263q29 96 61 241.5t49 259.5h117l12 -20q-75 -265 -174 -481h-65z" />
+<glyph unicode="&#x201c;" horiz-adv-x="614" d="M29 981q32 112 81.5 251t92.5 230h65q-30 -101 -64.5 -257t-45.5 -244h-117zM346 981q34 120 83 255t91 226h66q-30 -98 -63 -248.5t-48 -252.5h-117z" />
+<glyph unicode="&#x201d;" horiz-adv-x="614" d="M29 961q29 96 61 241.5t49 259.5h117l12 -20q-75 -265 -174 -481h-65zM346 961q30 98 63 248.5t48 252.5h116l13 -20q-36 -128 -85 -261t-89 -220h-66z" />
+<glyph unicode="&#x201e;" horiz-adv-x="768" d="M68 -263q29 96 61 241.5t49 259.5h117l12 -20q-75 -265 -174 -481h-65zM385 -263q30 98 63 248.5t48 252.5h116l13 -20q-36 -128 -85 -261t-89 -220h-66z" />
+<glyph unicode="&#x2022;" horiz-adv-x="770" d="M231 748q0 89 40.5 134.5t113.5 45.5t113.5 -47t40.5 -133q0 -85 -41 -133t-113 -48t-113 47t-41 134z" />
+<glyph unicode="&#x2026;" horiz-adv-x="1466" d="M162 78q0 98 80 98q82 0 82 -98t-82 -98q-80 0 -80 98zM651 78q0 98 80 98q82 0 82 -98t-82 -98q-80 0 -80 98zM1141 78q0 98 80 98q82 0 82 -98t-82 -98q-80 0 -80 98z" />
+<glyph unicode="&#x202f;" horiz-adv-x="381" />
+<glyph unicode="&#x2039;" horiz-adv-x="524" d="M82 516v27l309 393l62 -43l-254 -363l254 -362l-62 -43z" />
+<glyph unicode="&#x203a;" horiz-adv-x="524" d="M72 168l254 362l-254 363l61 43l309 -391v-27l-309 -393z" />
+<glyph unicode="&#x2044;" horiz-adv-x="246" d="M-332 0l811 1462h94l-811 -1462h-94z" />
+<glyph unicode="&#x205f;" horiz-adv-x="476" />
+<glyph unicode="&#x2074;" horiz-adv-x="688" d="M25 827v60l407 581h96v-563h129v-78h-129v-241h-90v241h-413zM129 905h309v221q0 132 8 232q-6 -12 -21.5 -35.5t-295.5 -417.5z" />
+<glyph unicode="&#x20ac;" d="M74 528v82h172q-4 38 -4 113l4 102h-172v82h184q39 272 183 425t362 153q88 0 161 -17t148 -57l-39 -86q-132 72 -270 72q-174 0 -288 -125.5t-155 -364.5h502v-82h-510l-4 -104v-24q0 -65 4 -87h449v-82h-443q30 -217 147.5 -338.5t301.5 -121.5q148 0 287 65v-94 q-81 -34 -150.5 -46.5t-140.5 -12.5q-228 0 -367.5 140t-181.5 408h-180z" />
+<glyph unicode="&#x2122;" horiz-adv-x="1485" d="M10 1384v78h522v-78h-219v-643h-86v643h-217zM608 741v721h125l221 -606l224 606h125v-721h-86v398l4 207h-7l-227 -605h-74l-221 609h-6l4 -201v-408h-82z" />
+<glyph unicode="&#x2212;" d="M111 682v82h948v-82h-948z" />
+<glyph unicode="&#xe000;" horiz-adv-x="1085" d="M0 1085h1085v-1085h-1085v1085z" />
+<glyph unicode="&#xfb01;" horiz-adv-x="1077" d="M29 1001v58l202 37v84q0 200 73.5 293.5t240.5 93.5q90 0 180 -27l-23 -86q-80 25 -159 25q-116 0 -164.5 -68.5t-48.5 -222.5v-101h256v-86h-256v-1001h-99v1001h-202zM782 1389q0 96 63 96q31 0 48.5 -25t17.5 -71q0 -45 -17.5 -71t-48.5 -26q-63 0 -63 97zM796 0v1087 h99v-1087h-99z" />
+<glyph unicode="&#xfb02;" horiz-adv-x="1077" d="M29 1001v58l202 37v84q0 200 73.5 293.5t240.5 93.5q90 0 180 -27l-23 -86q-80 25 -159 25q-116 0 -164.5 -68.5t-48.5 -222.5v-101h256v-86h-256v-1001h-99v1001h-202zM796 0v1556h99v-1556h-99z" />
+<glyph unicode="&#xfb03;" horiz-adv-x="1692" d="M29 1001v58l202 37v84q0 200 73.5 293.5t240.5 93.5q90 0 180 -27l-23 -86q-80 25 -159 25q-116 0 -164.5 -68.5t-48.5 -222.5v-101h256v-86h-256v-1001h-99v1001h-202zM643 1001v58l202 37v84q0 200 73.5 293.5t240.5 93.5q90 0 180 -27l-23 -86q-80 25 -159 25 q-116 0 -164.5 -68.5t-48.5 -222.5v-101h256v-86h-256v-1001h-99v1001h-202zM1397 1389q0 96 63 96q31 0 48.5 -25t17.5 -71q0 -45 -17.5 -71t-48.5 -26q-63 0 -63 97zM1411 0v1087h99v-1087h-99z" />
+<glyph unicode="&#xfb04;" horiz-adv-x="1692" d="M29 1001v58l202 37v84q0 200 73.5 293.5t240.5 93.5q90 0 180 -27l-23 -86q-80 25 -159 25q-116 0 -164.5 -68.5t-48.5 -222.5v-101h256v-86h-256v-1001h-99v1001h-202zM643 1001v58l202 37v84q0 200 73.5 293.5t240.5 93.5q90 0 180 -27l-23 -86q-80 25 -159 25 q-116 0 -164.5 -68.5t-48.5 -222.5v-101h256v-86h-256v-1001h-99v1001h-202zM1411 0v1556h99v-1556h-99z" />
+</font>
+</defs></svg> \ No newline at end of file
diff --git a/stylesheets/fonts/OpenSans-Light-webfont.ttf b/stylesheets/fonts/OpenSans-Light-webfont.ttf
new file mode 100644
index 00000000..6972e2b1
--- /dev/null
+++ b/stylesheets/fonts/OpenSans-Light-webfont.ttf
Binary files differ
diff --git a/stylesheets/fonts/OpenSans-Light-webfont.woff b/stylesheets/fonts/OpenSans-Light-webfont.woff
new file mode 100644
index 00000000..27afaf12
--- /dev/null
+++ b/stylesheets/fonts/OpenSans-Light-webfont.woff
Binary files differ
diff --git a/stylesheets/fonts/TR_Fujiyama_Bold.ttf b/stylesheets/fonts/TR_Fujiyama_Bold.ttf
new file mode 100755
index 00000000..72722960
--- /dev/null
+++ b/stylesheets/fonts/TR_Fujiyama_Bold.ttf
Binary files differ
diff --git a/stylesheets/fonts/lain.TTF b/stylesheets/fonts/lain.TTF
new file mode 100755
index 00000000..c8774306
--- /dev/null
+++ b/stylesheets/fonts/lain.TTF
Binary files differ
diff --git a/stylesheets/fonts/nrdyyh.woff b/stylesheets/fonts/nrdyyh.woff
new file mode 100755
index 00000000..6391b270
--- /dev/null
+++ b/stylesheets/fonts/nrdyyh.woff
Binary files differ
diff --git a/stylesheets/fonts/vt220.ttf b/stylesheets/fonts/vt220.ttf
new file mode 100755
index 00000000..ed8fd850
--- /dev/null
+++ b/stylesheets/fonts/vt220.ttf
Binary files differ
diff --git a/stylesheets/forest.css b/stylesheets/forest.css
new file mode 100644
index 00000000..bf2042ba
--- /dev/null
+++ b/stylesheets/forest.css
@@ -0,0 +1,259 @@
+/*cyberpunk mod of ferus by kalyx
+
+B332E6 = dark purp
+293728 = teal
+59B451 = green
+FF46D2 = pink
+dark blue = 293728
+*/
+
+body {
+ background: #0B110A;
+ color: #62C958;
+ font-family: DejaVuSansMono;
+ font-size: 10px;
+ /*text-shadow: 0px 0px 3px #FF46D2;*/
+}
+div.boardlist{
+ background-color: #0b110a!important;
+
+}
+
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+ }
+ @font-face
+{
+ font-family: 'DejaVuSansMono';
+ src: url('./fonts/DejaVuSansMono.ttf') format('truetype');
+}
+.bar {
+ -moz-box-shadow: 0 0 40px #293728;
+ -webkit-box-shadow: 0 0 40px #293728;
+ box-shadow: 0 0 40px #293728;
+ background-color: #131C13;
+ border-color: #293728!important;
+ background-color: #0b110a!important;
+}
+h1 {
+ font-family: DejaVuSansMono, Arial;
+ font-size: 18pt;
+ text-align: center;
+ letter-spacing: 0px;
+}
+div.title, h1 {
+ color: #4CADA7;
+ font-family: lain, DejaVuSansMono, sans-serif;
+}
+header div.subtitle {
+color: #59B451;
+text-align: center;
+ text-shadow: 0px 0px 3px #59B451;
+}
+div.title p {
+ font-size: 13px;
+}
+a:link, a:visited, p.intro a.email span.name {
+ color: #4CADA7;
+/*text-shadow: 0px 0px 10px #59B451;*/
+ font-family: DejaVuSansMono;
+}
+pre.prettyprint {
+background: #293728;
+
+font-size: 12px;
+line-height: 1.5;
+border: 1px solid #293728;
+padding: 10px;
+}
+
+a:link, a:visited, p.intro a.email span.name
+{
+ -moz-transition: 0.15s text-shadow, 0.15s color;
+ -webkit-transition: 0.15s text-shadow, 0.15s color;
+ -khtml-transition: 0.15s text-shadow, 0.15s color;
+ -o-transition: 0.15s text-shadow, 0.15s color;
+ -ms-transition: 0.15s text-shadow, 0.15s color;
+ transition: 0.15s text-shadow, 0.15s color;
+}
+input[type="text"], textarea
+{
+ -moz-transition: 0.15s border-color;
+ -webkit-transition: 0.15s border-color;
+ -khtml-transition: 0.15s border-color;
+ -o-transition: 0.15s border-color;
+ -ms-transition: 0.15s border-color;
+ transition: 0.15s border-color;
+}
+input[type="submit"]
+{
+ -moz-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -webkit-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -khtml-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -o-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -ms-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+}
+
+
+a:link:hover, a:visited:hover {
+ color: #59B451;
+ font-family: DejaVuSansMono;
+ text-shadow: 0px 0px 5px #59B451;
+}
+strong {
+
+color: #4CADA7;
+}
+a.post_no {
+ color: #293728;
+ text-decoration: none;
+}
+span.quote
+{
+ color:#4CADA7;
+}
+a.post_no:hover {
+ color: maroon;
+ /*text-decoration: underline overline;*/
+}
+div.post.reply {
+ background: #131C13;
+ border: #293728 1px solid !important;
+ border-radius: 0px;
+}
+.de-pview {
+ background: rgba(14, 14, 14, 0.84) !important;
+}
+div.post.reply.highlighted {
+ background: transparent;
+ border: #293728 1px solid;
+}
+div.post.reply div.body a:link, div.post.reply div.body a:visited {
+ color: #646464;
+}
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover {
+ color: #59B451;
+}
+p.intro span.subject {
+ font-size: 12px;
+ font-family: DejaVuSansMono;
+ color: #59B451;
+ font-weight: 800;
+ text-shadow: 0px 0px 3px #59B451;
+}
+p.intro span.name {
+ color: #59B451;
+ font-weight: 900;
+ text-shadow: 0px 0px 3px #59B451;
+}
+p.intro a.capcode, p.intro a.nametag {
+ color: #59B451;
+ 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 {
+ color: #59B451;
+ font-family: DejaVuSansMono;
+}
+input[type="text"], textarea, select {
+ background: #0B110A;
+ color: #CCCCCC;
+ border: #293728 1px solid;
+ padding-left: 5px;
+ padding-right: -5px;
+ font-family: DejaVuSansMono;
+ font-size: 10pt;
+ border-radius: 5px;
+}
+input[type="password"] {
+ background: #0B110A;
+ color: #CCCCCC;
+ border: #293728 1px solid;
+ border-radius: 5px;
+}
+form table tr th {
+ background: #0B110A;
+ color: #59B451;
+ border: #293728 1px solid;
+ font-weight: 600;
+ text-align: center;
+ padding: 0;
+ border-radius: 0px;
+ /*text-shadow: 0px 0px 3px #59B451;*/
+}
+div.sidearrows{display:none;}
+
+div.banner {
+ background: #0B110A;
+ color: #59B451;
+ text-align: center;
+ width: 250px;
+ padding: 4px;
+ padding-left: 12px;
+ padding-right: 12px;
+ margin-left: auto;
+ margin-right: auto;
+ font-size: 12px;
+ text-shadow: 0px 0px 3px #59B451;
+
+}
+input[type="submit"] {
+ background: #0B110A;
+ color: #59B451;
+ border: #293728 1px solid;
+ border-radius: 0px;
+}
+input[type="submit"]:hover {
+ background: #0B110A;
+
+ border: #293728 1px solid;
+
+ color: #FF46D2;
+ border-radius: 0px;
+}
+p.fileinfo a:hover {
+ text-decoration: underline;
+}
+span.trip {
+ color: #AAAAAA;
+}
+.topbar {
+ background-color: #0B110A;
+ border-bottom: 1px solid #293728;
+}
+div.pages {
+ color: #AAAAAA;
+ background: #0B110A;
+ border: #293728 1px solid;
+ font-family: DejaVuSansMono;
+ font-size: 10pt;
+}
+div.pages a.selected {
+ color: #8C8C8C;
+}
+hr {
+ height: 0px;
+ border: #293728 1px solid;
+}
+div.boardlist {
+ font-size: 10pt;
+ color: #999999;
+}
+div.ban {
+ background-color: transparent;
+ border: #293728 1px solid;
+}
+div.ban h2 {
+ background: transparent;
+ color: #59B451;
+ font-size: 11px;
+ text-shadow: 0px 0px 3px #59B451;
+}
+table.modlog tr th {
+ background: #FF46D2;
+ color: #AAAAAA;
+ /*text-shadow: 0px 0px 3px #59B451;*/
+}
diff --git a/stylesheets/heavy_ice.css b/stylesheets/heavy_ice.css
new file mode 100644
index 00000000..cbdc9994
--- /dev/null
+++ b/stylesheets/heavy_ice.css
@@ -0,0 +1,384 @@
+/**
+ * heavy_ice.css
+ * by kalyx
+ *stole some shit from monoelain thnx
+ */
+
+body
+{
+ display:block;
+ padding-top: 26px;
+ background: #0d1010;
+ color: #d2e7e8;
+ font-family: sans-serif;
+ font-size: 13px;
+
+
+ max-width: 568px;
+}
+div.boardlist{
+ background-color: #000!important;
+
+}
+html {
+ /* Size of largest container or bigger */
+ background:#0d1010;
+ max-width: 568px;
+ margin-left: auto;
+ margin-right: auto;
+
+ }
+/*banner*/
+.board_image{
+ border: double 0px #d2e7e8;
+ box-shadow: 2px 2px #d2e7e8;
+}
+
+ /*gives images border/shadow*/
+ div.files img.post-image {
+ border: solid 1px #d2e7e8;
+ box-shadow: 2px 2px #d2e7e8;
+ padding: 0px;
+ border-radius: 0;
+ margin-bottom: 5px;
+ }
+div.sidearrows{
+ display: none;
+}
+
+span.quote
+{
+ color:#e8d928;
+}
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+h1
+{
+ display: none;
+ font-family: 'lain', tahoma;
+
+ letter-spacing: -2px;
+ font-size: 42px;
+ text-align: center;
+ color: #d2e7e8;
+
+}
+header div.subtitle
+{
+ display: none;
+ color: #d2e7e8;
+ font-size: 13px;
+ margin-left: auto;
+ margin-right: auto;
+ max-width:385px;
+}
+div.title
+{
+ display: none;
+ color: #e8d928;
+ font-family: Arial, Helvetica, sans-serif;
+
+}
+div.title p
+{
+ font-size: 8px;
+ color: #e8d928;
+}
+a:link, a:visited, p.intro a.email span.name
+{
+ color: #d2e7e8;
+ text-transform: uppercase;
+ font-size: 10px;
+ text-decoration: none;
+ font-family: sans-serif;
+}
+a:link, a:visited, p.intro a.email span.name
+{
+ -moz-transition: 0.15s text-shadow, 0.15s color;
+ -webkit-transition: 0.15s text-shadow, 0.15s color;
+ -khtml-transition: 0.15s text-shadow, 0.15s color;
+ -o-transition: 0.15s text-shadow, 0.15s color;
+ -ms-transition: 0.15s text-shadow, 0.15s color;
+ transition: 0.15s text-shadow, 0.15s color;
+}
+input[type="text"], textarea
+{
+ -moz-transition: 0.15s border-color;
+ -webkit-transition: 0.15s border-color;
+ -khtml-transition: 0.15s border-color;
+ -o-transition: 0.15s border-color;
+ -ms-transition: 0.15s border-color;
+ transition: 0.15s border-color;
+}
+input[type="submit"]
+{
+ -moz-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -webkit-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -khtml-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -o-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -ms-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+}
+a:link:hover, a:visited:hover
+{
+ color: #e8d928;
+ font-family: sans-serif;
+ text-decoration: none;
+ text-shadow: 0px 0px 5px #d2e7e8;
+}
+a.post_no
+{
+ color: #e8d928;
+ text-decoration: none;
+}
+p.intro a.post_no:hover
+{
+ color: #e8d928!important;
+}
+div.post.reply
+{
+ background: #0d1010;
+ align: center;
+ max-width:96% !important;
+ min-width: 96%!important;
+border: solid 1px #d2e7e8;
+box-shadow: 2px 2px #d2e7e8;
+
+
+}
+
+div.postcontainer
+{
+ max-width:100% !important;
+ min-width: 100%!important;
+
+}
+div.post.reply.highlighted
+{
+ background: #1e2324;
+ border: solid 1px #93e0e3;
+ box-shadow: 3px 5px #5c8c8e;
+ margin-left: auto;
+ margin-right: auto;
+}
+div.post.reply div.body a:link, div.post.reply div.body a:visited
+{
+ color: #CCCCCC;
+
+}
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover
+{
+ color: #e8d928;
+
+}
+p.intro span.subject
+{
+ font-size: 12px;
+ font-family: sans-serif;
+ color: #e8d928;
+ font-weight: 800;
+
+}
+p.intro span.name
+{
+ color: #d2e7e8;
+ font-weight: 800;
+}
+p.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
+{
+ color: #d2e7e8;
+
+}
+input[type="text"], textarea, select
+{
+ background: #0d1010!important;
+ color: #CCCCCC!important;
+border: solid 1px #d2e7e8;
+box-shadow: 1px 1px #0d1010;
+ margin-left: auto;
+ margin-right: auto;
+
+
+}
+input[type="password"]
+{
+ background: #0d1010!important;
+ color: #CCCCCC!important;
+ border: #d2e7e8 1px double!important;
+}
+form table tr th
+{
+ background: #0d1010!important;
+ color: #d2e7e8!important;
+ border: solid 1px #d2e7e8;
+box-shadow: 1px 1px #0d1010;
+ text-align: right;
+
+}
+div.banner
+{
+
+ background: #E04000;
+ border: 0px solid hsl(17, 100%, 60%);
+ color: #EEE;
+ text-align: center;
+ height: 15px;
+ padding: 1px 1px 4px 1px;
+ margin-left: auto;
+ margin-right: auto;
+}
+div.banner a
+{
+ color:#000;
+}
+input[type="submit"]
+{
+ background: #333333;
+ border: #666 1px solid;
+ color: #CCCCCC;
+}
+input[type="submit"]:hover
+{
+ background: #555;
+ border: #888 1px solid;
+ color: #e8d928;
+}
+input[type="text"]:focus, textarea:focus
+{
+ border:#888 1px solid!important;
+}
+p.fileinfo a:hover
+{
+ text-decoration: underline;
+}
+span.trip
+{
+ color: #AAA;
+}
+.bar
+{
+ background: #0c0c0c!important;
+ -moz-box-shadow: 0 0 0px #000;
+ -webkit-box-shadow: 0 0 0px #000;
+
+
+
+
+}
+.bar.top
+{
+ border: solid 1px #d2e7e8;
+box-shadow: 0px 1px #d2e7e8;
+
+}
+.bar.bottom
+{
+ border-top: 0px solid #666;
+ border: solid 1px #d2e7e8;
+
+
+}
+div.pages
+{
+ color: #d2e7e8 ;
+ background: #333;
+ border: #666 0px solid;
+ font-family: sans-serif;
+ font-size: 10px;
+}
+div.pages a.selected
+{
+ color: #d2e7e8 ;
+}
+hr
+{
+ height: 0px;
+ border: #d2e7e8 2px solid;
+
+}
+div.boardlist
+{
+ color: #d2e7e8;
+}
+
+div.ban
+{
+ background-color: #0d1010;
+ border: 0px solid #555;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+ text-align: left!important;
+ font-size: 13px;
+
+}
+div.ban h2
+{
+ background: #333;
+ color: #d2e7e8;
+ padding: 3px 7px;
+ font-size: 12px;
+ border-bottom: 1px solid #555;
+}
+div.ban h2:not(:nth-child(1))
+{
+ border-top: 0px solid #555;
+}
+table.modlog tr th
+{
+ background: #333;
+ color: #AAA;
+}
+
+div.report
+{
+ color: #666;
+}
+.pages, .board_image, input, .reply, form table th, textarea, a img, select, .banner
+{
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ border-radius: 2px;
+}
+.blur
+{
+ filter: blur(20px);
+ -webkit-filter: blur(23px);
+ -moz-filter: blur(23px);
+ -o-filter: blur(23px);
+ -ms-filter: blur(23px);
+ filter: url(svg/blur.svg#blur);
+}
+
+/* options.js */
+#options_div
+{
+ background: #333333;
+}
+.options_tab_icon
+{
+ color: #AAAAAA;
+}
+.options_tab_icon.active
+{
+ color: #FFFFFF;
+}
+
+
+
+.blotter
+{
+ color: #e8d928!important;
+}
diff --git a/stylesheets/img/7.gif b/stylesheets/img/7.gif
new file mode 100755
index 00000000..643f8b8f
--- /dev/null
+++ b/stylesheets/img/7.gif
Binary files differ
diff --git a/stylesheets/img/banner_terminal_mask.png b/stylesheets/img/banner_terminal_mask.png
new file mode 100755
index 00000000..63e6e02a
--- /dev/null
+++ b/stylesheets/img/banner_terminal_mask.png
Binary files differ
diff --git a/stylesheets/img/idx2.gif b/stylesheets/img/idx2.gif
new file mode 100755
index 00000000..baa8ecd3
--- /dev/null
+++ b/stylesheets/img/idx2.gif
Binary files differ
diff --git a/stylesheets/img/matrix.jpg b/stylesheets/img/matrix.jpg
new file mode 100644
index 00000000..39294780
--- /dev/null
+++ b/stylesheets/img/matrix.jpg
Binary files differ
diff --git a/stylesheets/img/matrix_yellow.gif b/stylesheets/img/matrix_yellow.gif
new file mode 100644
index 00000000..daa47649
--- /dev/null
+++ b/stylesheets/img/matrix_yellow.gif
Binary files differ
diff --git a/stylesheets/jungle.css b/stylesheets/jungle.css
index 86cb13b8..7691a680 100644
--- a/stylesheets/jungle.css
+++ b/stylesheets/jungle.css
@@ -10,6 +10,14 @@ background-attachment: scroll, scroll;
font-family: serif;
font-size: 16px;
}
+.bar
+{
+ border-color: #E5D959!important;
+ background-image: url('img/jungle_td.png');
+ -moz-box-shadow: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
div.title h1 {
font-size: 24px;
}
@@ -84,6 +92,9 @@ div.ban {
div.ban p {
color: black;
}
+.topbar {
+ background-image: url('img/jungle_td.png');
+}
div.pages {
padding: 7px 5px;
color: #054500;
diff --git a/stylesheets/kalyx_theme.css b/stylesheets/kalyx_theme.css
new file mode 100644
index 00000000..71210cff
--- /dev/null
+++ b/stylesheets/kalyx_theme.css
@@ -0,0 +1,303 @@
+/**
+ * dark.css
+ * Stolen from circlepuller who stole it from derpcat
+ */
+body
+{
+ background: #1E1E1E;
+ color: #999999;
+ font-family: sans-serif;
+ font-size: 11px;
+
+
+}
+
+span.quote
+{
+ color:#B8D962;
+}
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+h1
+{
+ font-family: 'lain', tahoma;
+ letter-spacing: -2px;
+ font-size: 20pt;
+ text-align: center;
+ color: #32DD72;
+}
+header div.subtitle
+{
+ color: #32DD72;
+}
+div.title
+{
+ color: #32DD72;
+ font-family: Arial, Helvetica, sans-serif;
+}
+div.title p
+{
+ font-size: 10px;
+}
+a:link, a:visited, p.intro a.email span.name
+{
+ color: #CCCCCC;
+ text-decoration: none;
+ font-family: sans-serif;
+}
+a:link, a:visited, p.intro a.email span.name
+{
+ -moz-transition: 0.15s text-shadow, 0.15s color;
+ -webkit-transition: 0.15s text-shadow, 0.15s color;
+ -khtml-transition: 0.15s text-shadow, 0.15s color;
+ -o-transition: 0.15s text-shadow, 0.15s color;
+ -ms-transition: 0.15s text-shadow, 0.15s color;
+ transition: 0.15s text-shadow, 0.15s color;
+}
+input[type="text"], textarea
+{
+ -moz-transition: 0.15s border-color;
+ -webkit-transition: 0.15s border-color;
+ -khtml-transition: 0.15s border-color;
+ -o-transition: 0.15s border-color;
+ -ms-transition: 0.15s border-color;
+ transition: 0.15s border-color;
+}
+input[type="submit"]
+{
+ -moz-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -webkit-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -khtml-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -o-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ -ms-transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+ transition: 0.15s border-color, 0.15s background-color, 0.15s color;
+}
+a:link:hover, a:visited:hover
+{
+ color: #32DD72;
+ font-family: sans-serif;
+ text-decoration: none;
+ text-shadow: 0px 0px 5px #fff;
+}
+a.post_no
+{
+ color: #AAA;
+ text-decoration: none;
+}
+p.intro a.post_no:hover
+{
+ color: #32DD72!important;
+}
+div.post.reply
+{
+ background: #181818;
+ border: #555555 0px solid;
+ width:100%;
+
+}
+div.postcontainer
+{
+
+ width:100%;
+
+}
+div.body
+{
+
+ width:100%;
+
+}
+div.sidearrows
+{
+
+ display:none;
+
+}
+div.post.reply.highlighted
+{
+ background: #555;
+ border: transparent 1px solid;
+}
+div.post.reply div.body a:link, div.post.reply div.body a:visited
+{
+ color: #CCCCCC;
+}
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover
+{
+ color: #32DD72;
+}
+p.intro span.subject
+{
+ font-size: 12px;
+ font-family: sans-serif;
+ color: #446655;
+ font-weight: 800;
+}
+p.intro span.name
+{
+ color: #32DD72;
+ font-weight: 800;
+}
+p.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
+{
+ color: #32ddaf;
+}
+input[type="text"], textarea, select
+{
+ background: #333333!important;
+ color: #CCCCCC!important;
+ border: #666666 1px solid!important;
+}
+input[type="password"]
+{
+ background: #333333!important;
+ color: #CCCCCC!important;
+ border: #666666 1px solid!important;
+}
+form table tr th
+{
+ background: #333333!important;
+ color: #AAAAAA!important;
+ border: #333333 1px solid!important;;
+}
+div.banner
+{
+ background: #E04000;
+ border: 1px solid hsl(17, 100%, 60%);
+ color: #EEE;
+ text-align: center;
+ height: 15px;
+ padding: 1px 1px 4px 1px;
+ margin-left: auto;
+ margin-right: auto;
+}
+div.banner a
+{
+ color:#000;
+}
+input[type="submit"]
+{
+ background: #333333;
+ border: #666 1px solid;
+ color: #CCCCCC;
+}
+input[type="submit"]:hover
+{
+ background: #555;
+ border: #888 1px solid;
+ color: #32DD72;
+}
+input[type="text"]:focus, textarea:focus
+{
+ border:#888 1px solid!important;
+}
+p.fileinfo a:hover
+{
+ text-decoration: underline;
+}
+span.trip
+{
+ color: #AAA;
+}
+.topbar
+{
+ background: #333;
+ border-bottom: 0px solid #666;
+ widh:100%;
+}
+div.pages
+{
+ color: #AAA;
+ background: #333;
+ border: #666 1px solid;
+ font-family: sans-serif;
+ font-size: 10pt;
+}
+div.pages a.selected
+{
+ color: #CCC;
+}
+hr
+{
+ height: 0px;
+ border: #333 1px solid;
+}
+div.boardlist
+{
+ color: #999;
+}
+
+div.ban
+{
+ background-color: #1e1e1e;
+ border: 1px solid #555;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+ text-align: left!important;
+}
+div.ban h2
+{
+ background: #333;
+ color: #32DD72;
+ padding: 3px 7px;
+ font-size: 12pt;
+ border-bottom: 1px solid #555;
+}
+div.ban h2:not(:nth-child(1))
+{
+ border-top: 1px solid #555;
+}
+table.modlog tr th
+{
+ background: #333;
+ color: #AAA;
+}
+
+div.report
+{
+ color: #666;
+}
+.pages, .board_image, input, .reply, form table th, textarea, a img, select, .banner
+{
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ border-radius: 2px;
+}
+.blur
+{
+ filter: blur(20px);
+ -webkit-filter: blur(23px);
+ -moz-filter: blur(23px);
+ -o-filter: blur(23px);
+ -ms-filter: blur(23px);
+ filter: url(svg/blur.svg#blur);
+}
+
+/* options.js */
+#options_div
+{
+ background: #333333;
+}
+.options_tab_icon
+{
+ color: #AAAAAA;
+}
+.options_tab_icon.active
+{
+ color: #FFFFFF;
+}
+
+
diff --git a/stylesheets/miku.css b/stylesheets/miku.css
index 7a8fb87e..fc723406 100644
--- a/stylesheets/miku.css
+++ b/stylesheets/miku.css
@@ -5,7 +5,13 @@
body {
background: #D2FFEE url('img/fade-miku.png') top repeat-x;
}
-
+.bar {
+ -moz-box-shadow: 0 0 40px #95d9e1;
+ -webkit-box-shadow: 0 0 40px #95d9e1;
+ box-shadow: 0 0 40px #95d9e1;
+ background: #B6DDDE;
+ border-color: #8FCCCD;
+}
a:link, a:visited {
text-decoration: none;
color: #00637B;
@@ -70,7 +76,10 @@ div.ban h2 {
background: #B6DDDE;
color: #0093AB;
}
-
+.topbar {
+ background: #B6DDDE;
+ border-bottom: 1px solid #8FCCCD;
+}
div.pages {
color: #8899AA;
background: #B6DDDE;
diff --git a/stylesheets/mono.e.lain.css b/stylesheets/mono.e.lain.css
new file mode 100644
index 00000000..9ba0e5b0
--- /dev/null
+++ b/stylesheets/mono.e.lain.css
@@ -0,0 +1,364 @@
+/*monoelains ez css for VIP quality imageboards. steal this .css and edit it to your liking. */
+
+ /* OPTION HIDING */
+
+
+ /*lainchan bottom bar fix*/
+ .bar{
+ background-color: #CDCDCD!important;
+ }
+
+ /*removes footer (STI pls dont sue)
+ footer {
+ display:none;
+ color: #ffffff;
+ }
+
+ /* hides AA in catalog */
+ .theme-catalog span.aa {
+ display: none !important;
+ }
+
+ /* hides expand all images */
+ #expand-all-images {
+ display: none;
+ }
+
+ /* hides hints*/
+ .hint {
+ }
+
+ /* hides horizontal bar */
+ hr {
+ display: none;
+ }
+
+ /*banner stuff*/
+ img.banner, img.board_image {
+ border: 8px ridge #B18108;
+ background-color: #B2A50F;
+ display: ;
+ -webkit-box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5);
+ box-shadow: 7px 7px rgba(0, 0, 0, 0.5);
+ margin: 30px auto 0px;
+ }
+
+ /* hides delete options (obsolete) */
+ div.delete {
+ display: none;
+ }
+
+ /*makes files align vertically (hw pls fix this shit)*/
+ .file {
+ display: block;
+ margin-right: 11px;
+}
+ }
+
+ div.boardlist a {
+ color: rgb(187, 51, 0);
+ }
+
+ /*expanded image border/shadow*/
+ .full-image {
+ border-top-right-radius: 0;
+ -webkit-box-shadow: 7px 7px 0px 0px #000;
+ -moz-box-shadow: 7px 7px 0px 0px #000;
+ -webkit-box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5);
+ box-shadow: 7px 7px rgba(0, 0, 0, 0.5);
+ border: double black;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+ padding: 5px;
+ margin: 0px 0px 0px;
+ /*+border-radius: 0;*/
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+ -khtml-border-radius: 0;
+ border-radius: 0;
+ max-width: 80% !important;
+ float: none;
+ background-color: rgb(194, 194, 194);
+ }
+
+ /*gives quick reply its border/shadow*/
+ #quick-reply table {
+ background: none repeat scroll 0 0 #CBCBCB;
+ border: 4px double;
+ margin: 0;
+ -webkit-box-shadow: 7px 7px 0px 0px #000;
+ -moz-box-shadow: 7px 7px 0px 0px #000;
+ -webkit-box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5);
+ box-shadow: 7px 7px rgba(0, 0, 0, 0.5);
+ width: auto !important;
+ }
+
+ /*makes posting form maroon*/
+ form table tr th {
+ background-color: rgb(187, 51, 0);
+ color: #FFFFFF;
+ font-family: Palatino Linotype, Book Antiqua, Palatino, serif;
+ }
+
+ /*gives images border/shadow*/
+ div.files img.post-image {
+ -webkit-box-shadow: 7px 7px 0px 0px #000;
+ -moz-box-shadow: 7px 7px 0px 0px #000;
+ -webkit-box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5);
+ box-shadow: 7px 7px rgba(0, 0, 0, 0.5);
+ background-color: #CBCBCB;
+ border: double black;
+ padding: 5px;
+ /*+border-radius: 0;*/
+ -moz-border-radius: 0;
+ -webkit-border-radius: 0;
+ -khtml-border-radius: 0;
+ border-radius: 0;
+ margin-bottom: 5px;
+ }
+
+ /* makes Youtube thumbs not obscenely big */
+ div.video-container {
+ width: auto !important;
+ height: auto !important;
+ max-height: 20% !important;
+ max-width: 20% !important;
+ }
+
+ /* Image thumbs size limit (make as big as you want)*/
+ .post-image {
+ border: double black;
+ height: auto !important;
+ width: auto !important;
+ max-height: 60%;
+ max-width: 60%;
+ box-shadow: 7px 7px rgba(0, 0, 0, 0.5);
+padding: 5px;
+background-color: #cdcdcd;
+ }
+
+ /* Keep small thumbnails in replies */
+ .post.reply a:not([data-expanded="true"]) .post-image {
+ width: auto !important;
+ height: auto !important;
+ max-height: 60%;
+ max-width: 60%;
+ }
+
+ /* reply box size */
+ .input[type="text"], textarea {
+ min-height: 117px;
+ min-width: 240px;
+ }
+
+ /*boardwide font stuff goes here also background image*/
+ body {
+ padding: 0;
+ font-family: arial, sans-serif;
+ font-size: 14px;
+ background: url("https://i.imgur.com/OUHu2ki.jpg") fixed repeat top #000000;
+min-width: 395px;
+margin-left: 10px;
+margin-right: 35px;
+
+margin-left: 10px;
+ }
+ /*saves one pixel of space*/
+ header {
+ margin-bottom: 0px;
+ }
+
+ /*gives posting table its border/shadow*/
+ form table {
+ width: 100%;
+ minimum-width: 960px;
+ min-height: 250px;
+ display: inline-block;
+ margin: 5px auto;
+ background-color: #CDCDCD;
+ border: double black;
+ padding: 5px;
+ -webkit-box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5);
+ box-shadow: 7px 5px rgba(0, 0, 0, 0.5);
+ }
+
+ /*gives threads its border/shadow*/
+ div[id^="thread_"] {
+ -webkit-box-shadow: 11px 11px 0px 0px #000;
+ -moz-box-shadow: 11px 11px 0px 0px #000;
+ background-color: rgb(221, 221, 221);
+ margin-bottom: 20px;
+ padding: 10px;
+ border: 3px double #000000;
+ width: 100%;
+ -webkit-box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5);
+ box-shadow: 7px 7px rgba(0, 0, 0, 0.5);
+ }
+
+ /*adds horizontal bar below subject*/
+ p.intro {
+ background-image: url('https://i.imgur.com/UebGaj5.png');
+ background-repeat: repeat-x;
+ background-position: bottom;
+ min-height: 25px;
+ }
+
+ /*gives replies border/shadow*/
+ div.post.reply {
+ max-width: 95% !important;
+ -webkit-box-shadow: 7px 7px 0px 0px #000;
+ -moz-box-shadow: 7px 7px 0px 0px #000;
+ -webkit-box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5);
+ box-shadow: 7px 7px rgba(0, 0, 0, 0.5);
+ padding: 10px;
+ margin-top: 20px;
+ border: double 3px #000;
+ background-color: rgb(194, 194, 194);
+ }
+
+ /*unfucks highlighting replies and gives border/shadow*/
+ div.post.reply.highlighted {
+ background-color: #D6BDB0;
+ }
+
+ /*dont touch this*/
+ div.body {
+ display: block;
+ clear: both;
+ padding-top: 10px;
+ }
+
+ /*makes page bar have border/shadow*/
+ div.pages {
+ -webkit-box-shadow: 7px 7px 0px 0px #000;
+ -moz-box-shadow: 7px 7px 0px 0px #000;
+ -webkit-box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5);
+ box-shadow: 7px 7px rgba(0, 0, 0, 0.5);
+ width: 100%;
+ display: block;
+ clear: both;
+ border: double black;
+ background-color: rgb(221, 221, 221);
+ }
+
+ /*hovered links have underline*/
+ a:hover {
+ text-decoration: underline;
+ }
+
+ /*stops textbox resizing shenanigans*/
+ .input[type="text"], textarea {
+ font-size: 14px;
+ max-width: 9000px;
+ min-height: 115px;
+ min-width: 270px;
+ }
+
+ /*boardname nice font. replace with something classy someday*/
+ header div.subtitle, h1 {
+ font-family: Palatino Linotype, Book Antiqua, Palatino, serif;
+ color: rgb(187, 51, 0);
+ }
+
+ /*announcement font and color*/
+ div.blotter {
+ padding: 15px;
+ color: #000000;
+ font-family: Palatino Linotype, Book Antiqua, Palatino, serif;
+ }
+
+ /*makes links red*/
+ a {
+ color: rgb(187, 51, 0) !important;
+ text-decoration: none;
+ }
+
+ /*top boardlist stuff. change position to "fixed" to make it behave like normal 8chan*/
+ div.boardlist:not(.bottom) {
+ background-color: rgba(221, 221, 221, 1) !important;
+ text-align: center;
+ padding: 5px 75px;
+ box-shadow: 7px 7px rgba(0, 0, 0, 0.5); !important;
+ color: rgba(0, 0, 0, 0.33);
+ font-size: 10px;
+ border: double #000 !important;
+ position:static !important;
+ }
+
+ /*favorites in a new line*/
+ div.boardlist span.favorite-boards {
+ display: block;
+ }
+
+ /*subject color*/
+ p.intro span.subject {
+ color: rgb(117, 8, 8);
+ }
+
+ /*bottom boardlist centered*/
+
+ div.boardlist.bottom {
+ text-align: center;
+ background-color: rgba(228,228,228,1);
+ border: double #000000;
+ width: 101%;
+ }
+
+ /*colors name*/
+ p.intro span.name {
+ color: rgb(122, 77, 77);
+ font-family: ;
+ }
+
+ /*catalog stuff*/
+ .theme-catalog div.thread {
+ background-color: rgb(221, 221, 221);
+ border: double;
+ }
+
+ .theme-catalog div.thread:hover {
+ background-color: #D6BDB0;
+ border: double;
+ }
+
+ span.trip {
+ color: rgb(34, 136, 84);
+ }
+
+ #updater, #thread-links {
+ background-color: rgba(228,228,228,1);
+ border:double;
+ padding: 5px;
+ margin: 5px;
+ -webkit-box-shadow: 10px 10px 10px rgba(0, 0, 0, 0.5);
+ box-shadow: 7px 7px rgba(0, 0, 0, 0.5);
+ }
+
+div.banner {
+width: 380px;
+display:block;
+margin-left:auto;
+margin-right:auto;
+
+}
+
+#quick-reply th .close-btn{
+color:#ffffff;
+
+}
+
+div.post-hover {
+
+background-color: #D6BDB0 !important;
+border: double #000 !important;
+box-shadow: 7px 7px rgba(0, 0, 0, 0.5) !important;
+max-width: 50%;
+}
+
+span.subject:after { content: '\A'; white-space:pre; }
+SPAN.controls.op:before { content: '\A'; white-space:pre; }
+
+div.post-menu
+{
+color: #ffffff;} \ No newline at end of file
diff --git a/stylesheets/new_test.css b/stylesheets/new_test.css
new file mode 100644
index 00000000..d633b9ac
--- /dev/null
+++ b/stylesheets/new_test.css
@@ -0,0 +1,559 @@
+/**
+ * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
+ * http://cssreset.com
+ */
+html, body, div, span, applet, object, iframe,
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code,
+del, dfn, em, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,
+b, u, i, center,
+dl, dt, dd, ol, ul, li,
+fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td,
+article, aside, canvas, details, embed,
+figure, figcaption, footer, header, hgroup,
+menu, nav, output, ruby, section, summary,
+time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+
+/* HTML5 display-role reset for older browsers */
+article, aside, details, figcaption, figure,
+footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+
+body {
+ line-height: 1;
+}
+
+ol, ul {
+ list-style: none;
+}
+
+blockquote, q {
+ quotes: none;
+}
+
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: '';
+ content: none;
+}
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+html, body {
+ max-width: 100%;
+}
+
+body {
+ font-size: 12px;
+ font-family: arial, helvetica, sans-serif;
+ margin: 22px 5px;
+ background: #1e1e1e;
+ color: #999999;
+}
+
+.bar {
+ z-index: 1;
+ font-size: 13px;
+ width: 100%;
+ height: 20px;
+ position: fixed;
+ display: block;
+ margin-left: -5px;
+ background: #333333;
+ border: solid #666666;
+}
+ .bar.top {
+ top: 0;
+ border-width: 0 0 1px 0;
+ }
+ .bar.top .boardlist {
+ overflow: scroll;
+ display: table;
+ border-collapse: separate;
+ border-spacing: calc(1em / 3) 2.5px;
+ text-align: center;
+ margin: 0 auto;
+ height: 100%;
+ }
+ .bar.top .boardlist .sub {
+ white-space: nowrap;
+ display: table-cell;
+ }
+ .bar.bottom {
+ bottom: 0;
+ border-width: 1px 0 0 0;
+ }
+ .bar.bottom .pages {
+ margin-top: -1px;
+ }
+ .bar.bottom .pages > * {
+ display: inline-block;
+ }
+
+@media (max-width: 480px) {
+ body, .bar {
+ margin-left: 0;
+ margin-right: 0;
+ } }
+
+a, a:visited, a:active, a:focus {
+ color: #cccccc;
+ -webkit-transition: 0.15s color;
+ -khtml-transition: 0.15s color;
+ -moz-transition: 0.15s color;
+ -ms-transition: 0.15s color;
+ -o-transition: 0.15s color;
+ transition: 0.15s color;
+ -webkit-transition: 0.15s text-shadow;
+ -khtml-transition: 0.15s text-shadow;
+ -moz-transition: 0.15s text-shadow;
+ -ms-transition: 0.15s text-shadow;
+ -o-transition: 0.15s text-shadow;
+ transition: 0.15s text-shadow;
+ text-decoration: none;
+}
+ a.post_no, a:visited.post_no, a:active.post_no, a:focus.post_no {
+ color: #999999;
+ }
+ a:hover, a:visited:hover, a:active:hover, a:focus:hover {
+ text-shadow: 0px 0px 5px white;
+ color: #32dd72;
+ }
+
+.board_image, header, body > form[name="post"] {
+ display: block;
+ max-width: 100%;
+}
+
+.board_image, header {
+ width: 384px;
+ margin: 0 auto;
+}
+
+.board_image {
+ border: 1px solid #666666;
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -o-border-radius: 2px;
+ border-radius: 2px;
+ width: auto !important;
+ height: auto !important;
+ margin-top: 32px;
+}
+ @media (max-width: 480px) {
+ .board_image {
+ width: 100% !important;
+ border-top: 0;
+ border-right: 0;
+ border-left: 0;
+ margin-top: 0;
+ -webkit-border-radius: 0;
+ -khtml-border-radius: 0;
+ -moz-border-radius: 0;
+ -ms-border-radius: 0;
+ -o-border-radius: 0;
+ border-radius: 0;
+ } }
+
+header {
+ text-align: center;
+ color: #32dd72;
+ margin: 1em auto;
+}
+ header h1 {
+ font: 26px "lain", tahoma;
+ font-weight: bold;
+ letter-spacing: -2px;
+ margin-bottom: 6px;
+ }
+ header .subtitle {
+ font-size: 8pt;
+ }
+
+.unimportant {
+ font-size: 10px;
+}
+
+input, textarea {
+ color: #cccccc;
+ -webkit-appearance: none;
+ -khtml-appearance: none;
+ -moz-appearance: none;
+ -ms-appearance: none;
+ -o-appearance: none;
+ appearance: none;
+}
+ input[type="checkbox"]:after, textarea[type="checkbox"]:after {
+ opacity: 1;
+ display: inline-block;
+ content: " ";
+ box-sizing: border-box;
+ width: 12px;
+ height: 12px;
+ background: transparent;
+ border: 1px solid #666666;
+ position: relative;
+ top: 1px;
+ right: calc(1em + 4px);
+ margin-right: calc(1px - 1em);
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -o-border-radius: 2px;
+ border-radius: 2px;
+ }
+ input:not([type="file"]), textarea:not([type="file"]) {
+ background: #333333;
+ border: 1px solid #666666;
+ }
+ input[type="text"], input[type="button"], input[type="password"], input[type="submit"], input#body, textarea[type="text"], textarea[type="button"], textarea[type="password"], textarea[type="submit"], textarea#body {
+ padding: 2px 4px;
+ }
+ input[type="text"], input[type="button"], input[type="password"], input[type="submit"], textarea[type="text"], textarea[type="button"], textarea[type="password"], textarea[type="submit"] {
+ height: 16px;
+ }
+ input[type="text"], input[type="submit"], input#body, textarea[type="text"], textarea[type="submit"], textarea#body {
+ box-sizing: content-box;
+ -webkit-transition: 0.15s border-color;
+ -khtml-transition: 0.15s border-color;
+ -moz-transition: 0.15s border-color;
+ -ms-transition: 0.15s border-color;
+ -o-transition: 0.15s border-color;
+ transition: 0.15s border-color;
+ }
+ @media (max-width: 480px) {
+ input[type="text"]:last-of-type, input[type="submit"]:last-of-type, input#body:last-of-type, textarea[type="text"]:last-of-type, textarea[type="submit"]:last-of-type, textarea#body:last-of-type {
+ border-right: 0;
+ -webkit-border-radius: 2px 0 0 2px;
+ -khtml-border-radius: 2px 0 0 2px;
+ -moz-border-radius: 2px 0 0 2px;
+ -ms-border-radius: 2px 0 0 2px;
+ -o-border-radius: 2px 0 0 2px;
+ border-radius: 2px 0 0 2px;
+ } }
+ input[type="text"]:focus, input[type="submit"]:hover, input#body:focus, textarea[type="text"]:focus, textarea[type="submit"]:hover, textarea#body:focus {
+ border-color: #888888;
+ }
+ input[type="submit"]:hover, textarea[type="submit"]:hover {
+ color: #32dd72;
+ background: #555555;
+ }
+ input[type="submit"], textarea[type="submit"] {
+ -webkit-transition: 0.15s background;
+ -khtml-transition: 0.15s background;
+ -moz-transition: 0.15s background;
+ -ms-transition: 0.15s background;
+ -o-transition: 0.15s background;
+ transition: 0.15s background;
+ -webkit-transition: 0.15s color;
+ -khtml-transition: 0.15s color;
+ -moz-transition: 0.15s color;
+ -ms-transition: 0.15s color;
+ -o-transition: 0.15s color;
+ transition: 0.15s color;
+ width: 64px;
+ padding: 2px 5px;
+ margin-right: -8px;
+ }
+ input[type="text"], input#body, textarea[type="text"], textarea#body {
+ width: calc(100% - 2px);
+ }
+ input[type="text"][name="subject"], input#body[name="subject"], textarea[type="text"][name="subject"], textarea#body[name="subject"] {
+ width: calc(100% - 76px - 4px);
+ }
+ input#body, textarea#body {
+ min-width: calc(100% - 2px);
+ margin: 0;
+ }
+
+/*[for^="delete"], [for="spoiler"] {
+ &:before {
+ display: inline-block;
+ content: " ";
+ box-sizing: border-box;
+ width: $body_size;
+ height: $body_size;
+ background: transparent;
+ border: $nav_border $nav_border_look;
+ position: relative;
+ top: 1px;
+ right: calc(1em + 4px);
+ margin-right: calc(1px - 1em);
+ @include border-radius($div_radius);
+ }
+}*/
+form[name="post"] {
+ display: block;
+}
+ @media (max-width: 480px) {
+ form[name="post"] table, form[name="post"] tbody, form[name="post"] tr, form[name="post"] td {
+ margin: 0;
+ width: 100% !important;
+ } }
+ form[name="post"] table, form[name="post"] tbody {
+ max-width: 100%;
+ }
+ form[name="post"] table {
+ border-collapse: separate;
+ border-spacing: 2px;
+ margin: 0 auto;
+ }
+ form[name="post"] tbody {
+ width: 100%;
+ display: block;
+ position: relative;
+ left: -4px;
+ }
+ form[name="post"] [id|="upload"] td {
+ display: table-row;
+ }
+ form[name="post"] [id|="upload"] td > * {
+ display: table-cell;
+ height: 20px;
+ }
+ form[name="post"] [id|="upload"] td > *#upload_file {
+ width: 100%;
+ }
+ form[name="post"] [id|="upload"] td > *#spoilercontainer {
+ width: 74px;
+ }
+ form[name="post"] th, form[name="post"] input, form[name="post"] textarea {
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -o-border-radius: 2px;
+ border-radius: 2px;
+ }
+ form[name="post"] th {
+ text-align: left;
+ min-height: 20px;
+ vertical-align: middle;
+ width: 64px;
+ min-width: 64px !important;
+ padding: 0 5px;
+ font-weight: bold;
+ border: 1px solid #333333;
+ background: #333333;
+ }
+ @media (max-width: 480px) {
+ form[name="post"] th {
+ -webkit-border-radius: 0 2px 2px 0;
+ -khtml-border-radius: 0 2px 2px 0;
+ -moz-border-radius: 0 2px 2px 0;
+ -ms-border-radius: 0 2px 2px 0;
+ -o-border-radius: 0 2px 2px 0;
+ border-radius: 0 2px 2px 0;
+ } }
+
+hr {
+ border: 1px solid #333333;
+ margin: 6px 0px;
+ clear: left;
+}
+
+.blotter {
+ color: red;
+ font-weight: bold;
+ text-align: center;
+}
+ .blotter p {
+ margin: 12px 0;
+ }
+
+[id^="thread"] > .files, .op {
+ margin-left: 19px;
+}
+ @media (max-width: 480px) {
+ [id^="thread"] > .files, .op {
+ margin-left: 0;
+ } }
+
+[id^="thread"] > br {
+ display: none;
+}
+
+.fileinfo {
+ margin: 5px 0 5px 0;
+}
+
+.post-image {
+ margin: 0 10px 10px 0;
+ float: left;
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -o-border-radius: 2px;
+ border-radius: 2px;
+}
+ @media (max-width: 480px) {
+ .post-image {
+ float: none;
+ width: 100% !important;
+ height: auto !important;
+ margin-right: 0;
+ -webkit-border-radius: 0;
+ -khtml-border-radius: 0;
+ -moz-border-radius: 0;
+ -ms-border-radius: 0;
+ -o-border-radius: 0;
+ border-radius: 0;
+ margin-bottom: 5px;
+ } }
+
+@media (max-width: 480px) {
+ .post .intro {
+ clear: left;
+ } }
+.post .intro [type="checkbox"] {
+ display: table-cell;
+ vertical-align: middle;
+ box-sizing: border-box;
+ width: 14px;
+ margin: 0 4px 2px 0;
+}
+.post.op .intro {
+ line-height: 1.5em;
+ margin-top: -.25em;
+}
+ @media (max-width: 480px) {
+ .post.op .intro {
+ display: block;
+ margin-top: calc(-.5em - 1px);
+ padding: 0.25em 18px;
+ background-color: #333333;
+ border-bottom: 1px solid #666666;
+ } }
+ .post.op .intro > :last-child:before {
+ content: " ";
+ }
+@media (max-width: 480px) {
+ .post.op .body {
+ margin: 0.7em 23px;
+ } }
+.post .body {
+ margin: 0.7em 0 0.7em 18px;
+}
+
+.postcontainer {
+ border-top: 3px solid transparent;
+}
+ .postcontainer .sidearrows {
+ float: left;
+ width: 14px;
+ margin-right: 5px;
+ }
+ @media (max-width: 480px) {
+ .postcontainer .sidearrows {
+ display: none;
+ } }
+ .postcontainer .op .body {
+ margin-bottom: 1em;
+ }
+ .postcontainer .reply {
+ display: table;
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -o-border-radius: 2px;
+ border-radius: 2px;
+ background-color: #333333;
+ border: 1px solid #666666;
+ padding: 8px 19px 6px 8px;
+ }
+ .postcontainer .reply .files, .postcontainer .reply .body {
+ margin-left: 18px;
+ }
+ @media (max-width: 480px) {
+ .postcontainer .reply .files {
+ position: relative;
+ left: -7px;
+ margin-right: -7px;
+ } }
+ @media (max-width: 480px) {
+ .postcontainer .reply {
+ box-sizing: border-box;
+ width: 100%;
+ border-left: 0;
+ border-right: 0;
+ -webkit-border-radius: 0;
+ -khtml-border-radius: 0;
+ -moz-border-radius: 0;
+ -ms-border-radius: 0;
+ -o-border-radius: 0;
+ border-radius: 0;
+ } }
+
+.name {
+ font-weight: 800;
+ color: #32dd72;
+}
+
+.subject {
+ font-weight: 800;
+ color: rgba(50, 221, 114, 0.6);
+}
+
+.spoiler {
+ background: black;
+ color: black;
+}
+ .spoiler:hover {
+ color: white;
+ }
+
+.quote {
+ color: #b8d962;
+}
+
+.omitted {
+ opacity: 0.6;
+}
+
+div.delete {
+ float: right;
+ white-space: nowrap;
+ position: relative;
+ right: 15px;
+ margin-right: -7px;
+}
+ div.delete input {
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -ms-border-radius: 2px;
+ -o-border-radius: 2px;
+ border-radius: 2px;
+ }
+ div.delete input:last-child {
+ margin-left: 2px;
+ }
+ div.delete [type="text"] {
+ width: 256px !important;
+ }
+ div.delete:last-child {
+ margin-top: 2px;
+ }
+
+footer {
+ clear: both;
+ margin-bottom: 32px;
+}
diff --git a/stylesheets/poison.css b/stylesheets/poison.css
new file mode 100644
index 00000000..772e58b9
--- /dev/null
+++ b/stylesheets/poison.css
@@ -0,0 +1,97 @@
+/**
+* volafile.css fuck you
+color change by kalyx
+*/
+@import url("/stylesheets/dark.css");
+@font-face
+{
+ font-family: "DejaVuSansMono";
+ src: url("/stylesheets/fonts/DejaVuSansMono.ttf") format("truetype");
+}
+
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+body
+{
+ background: #140f16;
+ color: #D794F2;
+ font-size: 12px;
+}
+.bar
+{
+ background-color: #29202D!important;
+ border-color: #29202D!important;
+}
+.boardlist
+{
+ text-shadow: none!important;
+}
+header h1, header div.subtitle, form table tr th, form table tr td input
+{
+ color: #D794F2!important;
+}
+header h1
+{
+ font-family: "lain",sans-serif;
+ font-style: normal;
+ font-weight: 400;
+
+ font-size: 28px;
+ letter-spacing: 0px;
+ margin-top: calc(-16px / 3 - 6.5px);
+}
+p.intro span.subject {
+color: #32BFAB;
+}
+div.topbar, input[type="text"], select, form table tr th, form table tr td input[type="text"], form table tr td textarea, div.post.reply, [type="submit"], input[type="password"], div.pages
+{
+ background: #29202D!important;
+ border-color: #29202D!important;
+ color: #D794F2!important;
+}
+
+div.post.reply.highlighted{
+ background-color: #211A24!important;
+}
+form table tr td input[type="text"]:focus, form table tr td textarea:focus
+{
+ border-color: #5E7F9F!important;
+}
+input[type="submit"][name="post"]
+{
+ color: #3A4040!important;
+ background-color: #29202D!important;
+ border-color: #29202D!important;
+}
+.blotter
+{
+ color: #00ff00!important;
+}
+hr {
+ border-color: #29202D;
+}
+a
+{
+ color: #32BFAB!important;
+}
+
+p.intro span.name
+{
+ color: #D794F2;
+}
+span.quote {
+color: #E6E1E9;
+}
+a:hover, p.intro a.post_no:hover
+{
+ color: #EDEDED!important;
+ text-shadow: none!important;
+}
+:not(a) > i.fa
+{
+ color: #29202D;
+}
diff --git a/stylesheets/recent.css b/stylesheets/recent.css
new file mode 100644
index 00000000..417e65b8
--- /dev/null
+++ b/stylesheets/recent.css
@@ -0,0 +1,190 @@
+/**
+ * dark.css
+ * Stolen from circlepuller who stole it from derpcat
+ */
+body
+{
+ background: #0b000f;
+ color: #7fdd57;
+ font-family: sans-serif;
+ font-size: 12px;
+ margin:auto:
+ }
+.lain_banner{
+margin-left: auto;
+ margin-right: auto;
+ display: block;
+
+}
+@font-face {
+ font-family: 'FontAwesome';
+ 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
+}
+
+
+.box-wrap {
+ max-width: 670px;
+
+ margin: 30px auto;
+ overflow: auto;
+ padding: 0;
+}
+.box {
+ background: #0b000f;
+ border: 0px solid #98E;
+ width: 768px;
+ margin: 0px 0;
+ padding: 0;
+
+}
+
+div#global.ban{
+ max-width: 768px
+}
+
+.box ul {
+ padding: 2px 15px;
+}
+.box ul li {
+ list-style: none;
+ margin: 0;
+}
+.box.left {
+ background: #0b000f;
+ color: #7fdd57;
+ border: 0px solid #060;
+ float: left;
+ width: 50%;
+}
+.box.right {
+ background: #0b000f;
+ color: #7fdd57;
+ border: 0px solid #006;
+ float: right;
+ width: 50%;
+}
+
+.box h2 {
+ padding: 3px 7px;
+ font-size: 12pt;
+
+}
+.box.left h2 {
+ background: #7fdd57;
+ color: #677965;
+}
+.box.right h2 {
+ background: #7fdd57;
+ color: #0b000f;
+}
+.box img {
+ float: none;
+ margin: 0px auto;
+}
+
+span.quote
+{
+ color:#677965;
+}
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+h1
+{
+ font-family: 'arial black', arial;
+ letter-spacing: -20px;
+ font-size: 116pt;
+ text-align: center;
+ color: #7fdd57;
+}
+header div.subtitle
+{
+ color: #677965;
+}
+div.title
+{
+ color: #677965;
+ font-family: Arial, Helvetica, sans-serif;
+}
+div.title p
+{
+ font-size: 10px;
+}
+a:link, a:visited, .intro a.email span.name {
+ color: #677965;
+ text-decoration: none;
+ font-family: sans-serif;
+ font-size: 11pt;
+}
+
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover
+{
+ color: #7fdd57;
+}
+p.intro span.subject {
+ font-size: 12px;
+ font-family: sans-serif;
+ color: #7fdd57;
+ font-weight: 800;
+}
+p.intro span.name {
+ color: #7fdd57;
+ font-weight: 800;
+}
+
+p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name {
+ color: #7fdd57;
+}
+.bar
+{
+ background: #0b000f!important;
+ -moz-box-shadow: 0 0 40px #000;
+ -webkit-box-shadow: 0 0 40px #000;
+ box-shadow: 0 0 40px #000;
+
+}
+.bar.top
+{
+ border-bottom: 0px solid #0b000f;
+}
+.bar.bottom
+{
+ border-top: 1px solid #666;
+}
+
+div.boardlist
+{
+ color: #0b000f;
+}
+
+div.ban
+{
+ background-color: rgba(11, 0, 15, 0);
+ border: 0px solid #555;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+ text-align: left!important;
+}
+div.ban h2
+{
+ background: #0b000f;
+ color: #7fdd57;
+ padding: 5px 5px;
+ font-size: 16pt;
+ border-bottom: 0px solid #555;
+}
+
+div.ban h2:not(:nth-child(1))
+{
+ border-top: 0px solid #0b000f;
+}
+
+
+
diff --git a/stylesheets/style.css b/stylesheets/style.css
index 23d3ad7d..5eaa3c88 100644
--- a/stylesheets/style.css
+++ b/stylesheets/style.css
@@ -1,3 +1,87 @@
+/*Lainchan*/
+
+div.sidearrows{
+ display:none;
+}
+
+
+td{
+
+}
+
+
+
+html, body {
+ max-width: 100%!important;
+ overflow-x: hidden!important;
+}
+
+.post-image{
+ max-width: 94%!important;
+}
+select{
+ float:right;
+}
+
+div.pages{
+
+ margin:0!important;
+ padding: 0!important;
+}
+
+div.boardlist.bottom {
+
+ text-align: center!important;
+ display: none!important;
+}
+
+img.banner, img.board_image {
+
+ max-width: 100%!important;
+
+}
+
+.pintro{
+ width: 98%!important;
+}
+
+.bar {
+
+ display: table!important;
+ position: fixed;
+ width: 100%;
+ left: 0px;
+ z-index: 3;
+ background-color: #333333;
+ border-color: #B7C5D9;
+}
+.bar > :not(script) {
+ display: table-cell;
+ vertical-align: middle;
+}
+.bar.top {
+ text-align: center;
+ top: 0px;
+ border-bottom: 1px solid #B7C5D9;
+}
+
+.bar.bottom {
+ bottom: 0px;
+ border-top: 1px solid #333333;
+ background-color: #333333 ;
+}
+
+
+/*homepage banner*/
+div.lain_banner{
+ margin:auto;
+ position: absolute;
+}
+
+
+/* === GENERAL TAG SETTINGS === */
+
+/* Page Layouts */
body {
background: #EEF2FF url('img/fade-blue.png') repeat-x 50% 0%;
color: black;
@@ -8,6 +92,106 @@ body {
padding-right: 4px;
}
+main,
+aside,
+section {
+ display: block;
+ margin: 0 auto;
+ width: 100%;
+}
+
+main {
+ max-width: 1110px;
+}
+
+/* Tables */
+table {
+ margin: auto;
+
+}
+table.board-list-table {
+ width: 100%;
+}
+table tbody td {
+ margin: 0;
+ padding: 4px 15px 4px 4px;
+
+ text-align: left;
+}
+table thead th {
+ border: 1px solid #000333;
+ padding: 4px 15px 5px 5px;
+
+ background: #98E;
+ color: #000333;
+ text-align: left;
+ white-space: nowrap;
+}
+table tbody tr:nth-of-type( even ) {
+ background-color: transparent!important;
+}
+
+tr{
+
+}
+
+td.minimal,th.minimal {
+ width: 1%;
+ white-space: nowrap;
+}
+
+table.mod.config-editor {
+ font-size: 9pt;
+ width: 100%;
+}
+
+table.mod.config-editor td {
+ text-align: left;
+ padding: 5px;
+ border-bottom: 1px solid #98e;
+}
+
+table.mod.config-editor input[type="text"] {
+ width: 98%;
+}
+
+.longtable p {
+ margin: 0;
+}
+
+/* Uncategorized */
+#post-form-outer {
+ text-align: center;
+}
+
+#post-form-inner {
+ display: inline-block;
+}
+
+.post-table, .post-table-options, textarea {
+ width: 100%;
+}
+
+#post-form-inner .post-table tr {
+ background-color: transparent;
+}
+
+.post-table th, .post-table-options th {
+ width: 85px;
+}
+
+.post-table-options {
+ display: none;
+}
+
+.required-field-cell {
+ vertical-align: top;
+}
+
+.show-options-cell {
+ text-align: right;
+}
+
.hidden {
display:none;
}
@@ -60,7 +244,7 @@ h2 {
}
header {
- margin: 1em 0;
+ margin: 2em 0;
}
h1 {
@@ -79,10 +263,6 @@ header div.subtitle {
font-size: 8pt;
}
-form {
- margin-bottom: 4em;
-}
-
form table {
margin: auto;
}
@@ -97,15 +277,16 @@ input[type="text"],input[type="password"],textarea {
text-shadow: none;
text-transform: none;
word-spacing: normal;
- max-width: 100%;
-}
+ font-size: inherit;
+ font-family: sans-serif;
-#quick-reply input[type="text"], input[type="password"], #quick-reply textarea {
- max-width: 100%;
+ padding:0px!important;
}
-textarea {
- width: 100%;
+
+
+#upload input[type="file"] {
+ max-width: 230px;
}
form table tr td {
@@ -130,17 +311,19 @@ form table tr th {
form table tr td div.center {
text-align: center;
float: left;
- padding-left: 3px;
+ padding: 3px;
+ padding-top: 0px;
+ border: 1px dashed black;
+ margin: 2px
}
-form table tr td div input {
+/*form table tr td div input {
display: block;
margin: 2px auto 0 auto;
}
-
form table tr td div label {
font-size: 10px;
-}
+}*/
.unimportant,.unimportant * {
font-size: 10px;
@@ -199,6 +382,9 @@ img.banner,img.board_image {
}
.full-image {
+ float: left;
+ padding: 5px;
+ margin: 0 20px 0 0;
max-width: 98%;
}
@@ -213,7 +399,7 @@ div.post img.icon {
padding: 0;
}
-div.post i.fa {
+div.post i.fa, div.thread i.fa {
margin: 0 4px;
font-size: 16px;
}
@@ -254,24 +440,37 @@ input.delete {
}
.intro a {
- margin-left: 8px;
+ margin-left: 5px;
}
-div.delete {
- float: right;
+.sage {
+ color: red;
+ font-weight: bold;
}
-div.post.reply p {
- margin: 0.3em 0 0 0;
+.required-star {
+ color: maroon;
}
-div.post.reply div.body {
- margin-left: 1.8em;
+div.post p {
+ display: block;
+ margin: 0;
+
+ line-height: 1.16em;
+ font-size: 13px;
+ min-height: 1.16em;
+}
+
+div.post div.body {
margin-top: 0.8em;
padding-right: 3em;
padding-bottom: 0.3em;
}
+div.post.reply div.body {
+ margin-left: 1.8em;
+}
+
div.post.reply.highlighted {
background: #D6BAD0;
}
@@ -280,10 +479,6 @@ div.post.reply div.body a {
color: #D00;
}
-div.post {
- padding-left: 20px;
-}
-
div.post div.body {
word-wrap: break-word;
white-space: pre-wrap;
@@ -292,7 +487,7 @@ div.post div.body {
div.post.reply {
background: #D6DAF0;
margin: 0.2em 4px;
- padding: 0.2em 0.3em 0.5em 0.6em;
+ padding: 0.5em 0.3em 0.5em 0.6em;
border-width: 1px;
border-style: none solid solid none;
border-color: #B7C5D9;
@@ -300,11 +495,36 @@ div.post.reply {
max-width: 94%!important;
}
+div.post.reply.has-file.body-not-empty {
+ min-width: 33%;
+}
+
+div.post_modified {
+ margin-left: 1.8em;
+}
+div.post_modified div.content-status {
+ margin-top: 0.5em;
+ padding-bottom: 0em;
+ font-size: 72%;
+}
+div.post_modified div.content-status:first-child {
+ margin-top: 1.3em;
+}
+
+div.post_modified div.content-status:first-child {
+ margin-top: 1.3em;
+}
+
+a.dashed-underline {
+ text-decoration: none;
+ border-bottom: 1px dashed;
+}
+
span.trip {
color: #228854;
}
-span.quote {
+.quote {
color: #789922;
}
@@ -339,6 +559,7 @@ div#wrap {
margin: 0 auto;
}
+div.module,
div.ban {
background: white;
border: 1px solid #98E;
@@ -346,7 +567,8 @@ div.ban {
margin: 30px auto;
}
-div.ban p,div.ban h2 {
+div.ban p,
+div.ban h2 {
padding: 3px 7px;
}
@@ -420,13 +642,13 @@ fieldset label {
}
div.pages {
- color: #89A;
- background: #D6DAF0;
- display: inline-block;
- padding: 8px;
- margin: 8px 0 4px 0;
- border-right: 1px solid #B7C5D9;
- border-bottom: 1px solid #B7C5D9;
+ /*! color: #89A; */
+ /*! background: #D6DAF0; */
+ display: inline-block;
+ padding: 8px;
+ /*! margin: 8px 0 4px 0; */
+ /*! border-right: 1px solid #B7C5D9; */
+ /*! border-bottom: 1px solid #B7C5D9; */
}
div.pages.top {
@@ -476,32 +698,6 @@ div.report {
color: #333;
}
-table.modlog {
- margin: auto;
- width: 100%;
-}
-
-table.modlog tr td {
- text-align: left;
- margin: 0;
- padding: 4px 15px 0 0;
-}
-
-table.modlog tr th {
- text-align: left;
- padding: 4px 15px 5px 5px;
- white-space: nowrap;
-}
-
-table.modlog tr th {
- background: #98E;
-}
-
-td.minimal,th.minimal {
- width: 1%;
- white-space: nowrap;
-}
-
div.top_notice {
text-align: center;
margin: 5px auto;
@@ -525,22 +721,7 @@ div.blotter {
text-align: center;
}
-table.mod.config-editor {
- font-size: 9pt;
- width: 100%;
-}
-
-table.mod.config-editor td {
- text-align: left;
- padding: 5px;
- border-bottom: 1px solid #98e;
-}
-
-table.mod.config-editor input[type="text"] {
- width: 98%;
-}
-
-.desktop-style div.boardlist:nth-child(1) {
+.desktop-style div.boardlist:not(.bottom) {
position: fixed;
top: 0;
left: 0;
@@ -613,11 +794,11 @@ form.ban-appeal textarea {
}
.MathJax_Display {
- display: inline!important;
+ display:inline!important;
}
-
pre {
- margin: 0;
+ margin:0
+ display: inline!important;
}
.theme-catalog div.thread img {
@@ -643,8 +824,9 @@ pre {
position: relative;
font-size: 11px;
max-height: 300px;
- background: rgba(182,182,182,0.12);
- border: 2px solid rgba(111,111,111,0.34);
+ background: rgba(182, 182, 182, 0.12);
+ border: 2px solid rgba(111, 111, 111, 0.34);
+ max-height:300px;
}
.theme-catalog div.thread strong {
@@ -681,6 +863,16 @@ pre {
max-height: 192px;
}
+.theme-catalog div.grid-size-medium img {
+ max-height: 33%;
+ max-width: 95%
+}
+
+.theme-catalog div.grid-size-medium {
+ min-width:200px; max-width: 200px;
+ max-height: 274px;
+}
+
.theme-catalog div.grid-size-large img {
max-height: 40%;
max-width: 95%
@@ -710,6 +902,9 @@ pre {
.theme-catalog div.threads {
overflow: hidden;
}
+ div.post .body {
+ clear: both;
+ }
}
.compact-boardlist {
@@ -781,7 +976,7 @@ pre {
margin-top: 1em;
}
-.new-threads {
+.new-threads, .board-settings {
text-align: center;
}
@@ -819,10 +1014,12 @@ pre {
}
#options_div {
- width: 620px;
+ width: 600px;
+ height: 360px;
+/* width: 620px;
height: 400px;
resize: both;
- overflow: auto;
+ overflow: auto;*/
}
@@ -912,6 +1109,7 @@ pre {
.poster_id {
cursor: pointer;
+ white-space:nowrap;
display: inline-block;
-webkit-user-select: none;
-moz-user-select: none;
@@ -940,7 +1138,6 @@ span.pln {
color:grey;
}
-
@media screen and (min-width: 768px) {
.intro {
clear: none;
@@ -951,39 +1148,131 @@ span.pln {
}
}
+/* === SITE-WIDE ASSETS === */
+#logo {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin: 0 0 0 0;
+ text-align: center;
+}
+#logo-link {
+ display: inline;
+}
+#logo-img {
+ display: inline-block;
+ height: 128px;
+ width: auto;
+}
+
+/* === GENERAL CLASSES === */
+.loading {
+ background: none;
+ background-color: none;
+ background-image: url('/static/infinity.gif');
+ background-position: center center;
+ background-repeat: no-repeat;
+ min-height: 76px;
+ min-width: 128px;
+}
+.loading-small {
+ background: none;
+ background-color: none;
+ background-image: url('/static/infinity-small.gif');
+ background-position: center center;
+ background-repeat: no-repeat;
+ min-height: 24px;
+ min-width: 48px;
+}
+
+/* Text and accessibility */
+.ltr {
+ direction: ltr;
+}
+.rtl {
+ direction: rtl;
+ font-family: Tahoma;
+}
+
+/* Responsive helpers */
+.col {
+ box-sizing: border-box;
+ float: left;
+}
+
+.col-12 { width: 100%; }
+.col-11 { width: 91.66666667%; }
+.col-10 { width: 83.33333333%; }
+.col-9 { width: 75%; }
+.col-8 { width: 66.66666667%; }
+.col-7 { width: 58.33333333%; }
+.col-6 { width: 50%; }
+.col-5 { width: 41.66666667%; }
+.col-4 { width: 33.33333333%; }
+.col-3 { width: 25%; }
+.col-2 { width: 16.66666667%; }
+.col-1 { width: 8.33333333%; }
+
+.left-push {
+ float: left;
+}
+.right-push {
+ float: right;
+}
+
+/* Layout design */
+.box {
+ background: #D6DAF0;
+ border: 1px solid #000333;
+ color: #000333;
+ margin: 0 0 12px 0;
+}
+.box-title {
+ background: #98E;
+ color: #000333;
+ font-size: 120%;
+ font-weight: bold;
+ padding: 4px 8px;
+}
+.box-content {
+ padding: 0 8px;
+ margin: 4px 0;
+}
+
+
.clearfix {
- display: block;
- clear: both;
- visibility: hidden;
- overflow: hidden;
-
- font-size: 0px;
- line-height: 0px;
-
- box-sizing: border-box;
- border: none;
- height: 0;
- margin: 0;
- padding: 0;
- width: 100%;
- zoom: 1;
+ display: block;
+ clear: both;
+ visibility: hidden;
+ overflow: hidden;
+
+ font-size: 0px;
+ line-height: 0px;
+
+ box-sizing: border-box;
+ border: none;
+ height: 0;
+ margin: 0;
+ padding: 0;
+ width: 100%;
+ zoom: 1;
}
/* === SPECIFIC PAGES & FEATURES === */
/* Board List */
div.boardlist {
- margin-top: 3px;
-
- color: #89A;
- font-size: 9pt;
+ margin-top: 3px;
+
+ color: #89A;
+ font-size: 9pt;
}
div.boardlist.bottom {
- margin-top: 12px;
- clear: both;
+ margin-top: 12px;
+ clear: both;
}
div.boardlist a {
- text-decoration: none;
+ text-decoration: none;
}
/* Threads */
@@ -1021,34 +1310,161 @@ div.boardlist a {
#report-fields {
}
-
-
/* threadwatcher */
+#watchlist {
+ display: none;
+ max-height: 250px;
+ overflow: auto;
+ border: 1px solid;
+ border-style: none solid solid none;
+ width: 50%;
+ margin: 0 auto;
+ margin-bottom: 10px;
+}
#watchlist {
- display: none;
- max-height: 250px;
- overflow: auto;
- border: 1px solid;
- border-style: none solid solid none;
- width: 50%;
- margin: 0 auto;
- margin-bottom: 10px;
+ font-size: 8pt;
+ width: 15%;
+ position: fixed;
+ right: 0pt;
+ bottom: 0pt;
+ margin: 0pt;
+ padding: 0pt;
}
.watchlist-inner, .watchlist-controls {
- margin: 0 auto;
- margin-top: 10px;
- margin-bottom: 10px;
- text-align: center;
+ margin: 0pt;
+ text-align: center;
}
#watchlist-toggle, .watchThread, .watchlist-remove, #clearList, #clearGhosts {
- cursor: pointer;
+ cursor: pointer;
+}
+.own_post {
+ font-style: italic;
+ font-weight: normal;
+ opacity: .666;
+}
+li.mix {
+ display: inline-block;
+}
+
+/* Mona Font */
+.aa {
+ font-family: Mona, "MS PGothic", "MS Pゴシック", sans-serif;
+ display: block!important;
+ font-size: 12pt;
+ line-height: 1.1;
+}
+.dx,
+.dy,
+.dz {
+ width: 30px;
+ text-align: right;
+ display: inline-block;
+}
+
+/* Dice */
+.dice-option table {
+ border: 1px dotted black;
+ margin: 0;
+ border-collapse: collapse;
+}
+.dice-option table td {
+ text-align: center;
+ border-left: 1px dotted black;
+ padding-left: 2px;
+ padding-right: 2px;
+ padding-bottom: 2px;
+}
+
+/* Quick reply (why was most of this ever in the script?) */
+#quick-reply {
+ position: fixed;
+ right: 5%;
+ top: 5%;
+ float: right;
+ display: block;
+ padding: 0 0 0 0;
+ width: 300px;
+ z-index: 100;
+}
+#quick-reply #post-form-inner {
+ min-width: 300px;
+}
+#quick-reply .post-table tr td:nth-child(2) {
+ width: 33%;
+ text-align: right;
+ padding-right: 4px;
+}
+#quick-reply tr td:nth-child(2) input[type="submit"] {
+ width: 99%;
+}
+#quick-reply th, #quick-reply td {
+ margin: 0;
+ padding: 0;
+}
+#quick-reply th {
+ text-align: center;
+ padding: 2px 0;
+ border: 1px solid #222;
+}
+#quick-reply th .handle {
+ float: left;
+ width: 100%;
+ display: inline-block;
+}
+#quick-reply th .close-btn {
+ float: right;
+ padding: 0 5px;
+}
+#quick-reply input[type="text"], #quick-reply select {
+ width: 100%;
+ padding: 2px;
+ font-size: 10pt;
+ box-sizing: border-box;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing: border-box;
+}
+#quick-reply textarea {
+ min-width: 100%;
+ box-sizing: border-box;
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing: border-box;
+ font-size: 10pt;
+ resize: both;
+}
+#quick-reply input, #quick-reply select, #quick-reply textarea {
+ margin: 0 0 1px 0;
+}
+#quick-reply input[type="file"] {
+ padding: 5px 2px;
+}
+#quick-reply .nonsense {
+ display: none;
+}
+#quick-reply td.recaptcha {
+ text-align: center;
+ padding: 0 0 1px 0;
+}
+#quick-reply td.recaptcha span {
+ display: inline-block;
+ width: 100%;
+ background: white;
+ border: 1px solid #ccc;
+ cursor: pointer;
+}
+#quick-reply td.recaptcha-response {
+ padding: 0 0 1px 0;
+}
+@media screen and (max-width: 600px) {
+ #quick-reply {
+ display: none !important;
+ }
}
#youtube-size input {
- width: 50px;
+ width: 50px;
}
/* File selector */
@@ -1129,19 +1545,225 @@ div.boardlist a {
color: rgba(125, 125, 125, 1);
}
-#thread_stats {
- display: inline;
- margin-left: 10px;
- margin-right: 10px;
+table.board-list-table {
+ display: table;
+ margin: -2px;
+ margin-bottom: 10px;
+ overflow: hidden;
+ table-layout: fixed;
}
-/* Fileboard */
-table.fileboard th, table.fileboard td {
- padding: 2px;
- text-align: center;
+table.board-list-table .board-cell {
+ position: static;
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
-table.fileboard .intro a {
- margin-left: 0px;
+table.board-list-table .board-cell::after {
+ content: ' ';
+ clear: both;
+}
+
+table.board-list-table .board-meta {
+ padding-right: 4px;
+ width: 70px;
+}
+table.board-list-table .board-uri {
+ max-width: 196px;
+}
+table.board-list-table .board-title {
+ width: auto;
+}
+table.board-list-table .board-pph {
+ width: 55px;
+ padding: 4px;
+}
+table.board-list-table .board-max {
+ width: 90px;
+ padding: 4px;
+}
+table.board-list-table .board-unique {
+ width: 100px;
+ padding: 4px;
+}
+table.board-list-table .board-tags {
+ position: relative;
+ height: 15px;
+ width: auto;
+ padding: 0 15px 0 4px;
+}
+table.board-list-table .board-tags .tag-link {
+ display: inline;
+}
+table.board-list-table .board-tags .board-cell:hover {
+ position: absolute;
+ background: #EEF2FF;
+ line-height: 23px;
+ top: 0;
+ bottom: 0;
+ width: 310px;
+}
+table.board-list-table tr:nth-of-type( even ) .board-tags .board-cell {
+ background: #D6DAF0;
+}
+table.board-list-table .board-uri a {
+ display: inline-block;
+ float: left;
+}
+table.board-list-table .board-uri .board-nsfw {
+ color: rgb(230,0,0);
+ margin: 0 0 0 0.6em;
+ float: right;
+}
+table.board-list-table .board-uri .board-sfw {
+ color: #34345C;
+ margin: 0 0 0 0.6em;
+ float: right;
+}
+
+table.board-list-table div.board-cell {
+ max-width: 100%;
+ overflow: hidden;
+}
+
+tbody.board-list-loading {
+ display: none;
+}
+tbody.board-list-loading .loading {
+ height: 80px;
+}
+
+tbody.board-list-omitted td {
+ background: #98E;
+ border-top: 1px solid #000333;
+ padding: 8px;
+ font-size: 125%;
+ text-align: center;
+}
+tbody.board-list-omitted #board-list-more {
+ cursor: default;
+}
+tbody.board-list-omitted #board-list-more.board-list-hasmore {
+ cursor: pointer;
+}
+tbody.board-list-omitted .board-page-loadmore {
+ display: none;
+}
+tbody.board-list-omitted .board-list-hasmore .board-page-loadmore {
+ display: inline;
+}
+
+aside.search-container {
+ margin-bottom: 12px;
+}
+aside.search-container .box {
+ margin-right: 12px;
+}
+
+.board-search {
+ margin: 8px 0;
+}
+.search-item {
+ margin: 8px 0;
+}
+.search-sfw {
+ display: block;
+ cursor: pointer;
+ font-size: 110%;
+ line-height: 120%;
+}
+#search-sfw-input {
+ margin: 0;
+ padding: 0;
+ transform: scale(1.20);
+}
+#search-lang-input,
+#search-title-input,
+#search-tag-input {
+ box-sizing: border-box;
+ font-size: 110%;
+ line-height: 120%;
+ vertical-align: top;
+ padding: 2px 0 2px 4px;
+ max-width: 100%;
+ min-width: 100%;
+ width: 100%:
+}
+#search-loading {
+ display: inline-block;
+ vertical-align: bottom;
+}
+
+ul.tag-list {
+ display: block;
+ list-style: none;
+ margin: 8px 8px -9px 8px;
+ padding: 8px 0 0 0;
+ border-top: 1px solid #000333;
+}
+ul.tag-list::after {
+ content: ' ';
+ display: block;
+ clear: both;
+}
+li.tag-item {
+ display: inline-block;
+ float: left;
+ font-size: 100%;
+ list-style: none;
+ margin: 0;
+ padding: 0 4px 0 0;
+}
+li.tag-item:last-child {
+ padding-bottom: 17px;
+}
+a.tag-link {
+ overflow: hidden;
+ white-space: nowrap;
+}
+li.tag-item a.tag-link {
+}
+td.board-tags a.tag-link {
+ display: inline-block;
+ margin: 0 0.4em 0 0;
+}
+
+@media screen and (max-width: 1100px) {
+ aside.search-container {
+ width: 100%;
+ margin-bottom: 12px;
+ }
+ aside.search-container .box {
+ margin-right: 0;
+ }
+
+ section.board-list {
+ margin-top: 12px;
+ width: 100%;
+ }
+
+ table.board-list-table .board-meta,
+ table.board-list-table .board-pph,
+ table.board-list-table .board-tags {
+ padding: 0;
+ margin: 0;
+ font-size: 0;
+ width: 0;
+ }
+}
+
+#post-moderation-fields {
+ display: none;
+}
+
+.announcement {
+ font-size: 75%;
+ padding-bottom: 1%;
+ margin-left: 5%;
+ margin-right: 5%;
}
/* Gallery view */
@@ -1198,6 +1820,97 @@ table.fileboard .intro a {
max-height: 100%;
position: absolute;
}
+
+/* Fileboard */
+table.fileboard th, table.fileboard td {
+ padding: 2px;
+ text-align: center;
+}
+table.fileboard .intro a {
+ margin-left: 0px;
+}
+
+/* Rules Popup */
+#rules-popup {
+ width: 80%;
+ height: 80%;
+ position: fixed;
+ z-index: 9999;
+ left: 50%;
+ margin-left: -40%;
+ top: 50%;
+ margin-top: -40vh;
+ background: #000000;
+ text-align: center;
+ font-family: sans-serif;
+ font-size: 14px;
+ color: #FFFFFF;
+}
+#rules-popup .rules-popup-top {
+ font-size: 40px;
+ line-height: 60px;
+ position: absolute;
+ top: 0px;
+ height: 60px;
+ width: 100%;
+}
+#rules-popup .rules-popup-content-wrapper {
+ text-align: left;
+ position: absolute;
+ bottom: 80px;
+ top: 60px;
+ width: 100%;
+ overflow: auto;
+}
+#rules-popup #rules-popup-content {
+ padding: 10px;
+ font-size: 12px;
+}
+#rules-popup .rules-popup-bottom {
+ bottom: 0px;
+ height: 80px;
+ width: 100%;
+ position: absolute;
+}
+#rules-popup .rules-popup-bottom-instructions {
+ line-height: 40px;
+}
+#rules-popup .rules-popup-captcha-wrapper {
+ height: 40px;
+}
+#rules-popup .rules-popup-captcha {
+ display: inline-block;
+ border: 1px solid white;
+ font-family: serif;
+ padding: 3px;
+}
+#rules-popup .rules-popup-form {
+ display: inline-block;
+}
+#rules-popup .rules-popup-form-input {
+ width: 100px;
+}
+
+/* dropdown for boardlist. */
+.dropdown {
+ position: relative;
+ display: inline-block;
+}
+
+/* Alter details as needed, I'm not a designer. */
+.dropdown-content {
+ display: none;
+ position: absolute;
+ background-color: #666666;
+ min-width: 130px;
+ padding: 2px 6px;
+ color: #DCA1F5;
+}
+
+.dropdown:hover .dropdown-content {
+ display: block;
+ }
+
.own_post {
font-style: italic;
font-weight: normal;
diff --git a/stylesheets/svg/bannermaks.svg b/stylesheets/svg/bannermaks.svg
new file mode 100755
index 00000000..66daf771
--- /dev/null
+++ b/stylesheets/svg/bannermaks.svg
@@ -0,0 +1,12 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300px" height="100px">
+ <defs>
+ <pattern id="pattern2"
+ x="0" y="0" width=".0052083333333" height=".015625"
+ patternUnits="userSpaceOnUse" >
+ <rect x="0" y="0" width=".0026041666667" height=".0078125" style="stroke: none; fill: white; " />
+ </pattern>
+ <mask maskContentUnits="objectBoundingBox" maskUnits="objectBoundingBox" id="masking">
+ <rect x="0" y="0" width="1" height="1" style="fill: url(#pattern2);"/>
+ </mask>
+ </defs>
+</svg>
diff --git a/stylesheets/svg/blur.svg b/stylesheets/svg/blur.svg
new file mode 100755
index 00000000..a5c8a850
--- /dev/null
+++ b/stylesheets/svg/blur.svg
@@ -0,0 +1,73 @@
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
+ <filter id="blur_green">
+ <feColorMatrix type="saturate" in="SourceGraphic" values="0" result="cox"/>
+ <feColorMatrix type="matrix" in="cox" values=" 0 0 0 0 0
+ 1 0 0 0 0
+ 0 0 0 0 0
+ 1 1 1 0 0
+ " result="dix"/>
+ <feMorphology in="dix" operator="dilate" radius="0.5" result="wangz" />
+ <feGaussianBlur in="wangz" stdDeviation="10" result="blurred"/>
+ <feMerge>
+ <feMergeNode in="blurred"/>
+ <feMergeNode in="dix"/>
+ </feMerge>
+ </filter>
+ <filter id="blur_red">
+ <feColorMatrix type="saturate" in="SourceGraphic" values="0" result="cox"/>
+ <feColorMatrix type="matrix" in="cox" values=" .925 0 0 0 0
+ .067 0 0 0 0
+ .033 0 0 0 0
+ 1 1 1 0 0
+ " result="dix"/>
+ <feMorphology in="dix" operator="dilate" radius="1" result="wangz" />
+ <feGaussianBlur in="wangz" stdDeviation="10" result="blurred"/>
+ <feMerge>
+ <feMergeNode in="blurred"/>
+ <feMergeNode in="dix"/>
+ </feMerge>
+ </filter>
+ <filter id="blur_amber">
+ <feColorMatrix type="saturate" in="SourceGraphic" values="0" result="cox"/>
+ <feColorMatrix type="matrix" in="cox" values=" 0 1 0 0 0
+ 0 .556 0 0 0
+ 0 0 0 0 0
+ 1 1 0 0 0
+ " result="dix"/>
+ <feMorphology in="dix" operator="dilate" radius="1" result="wangz" />
+ <feGaussianBlur in="wangz" stdDeviation="10" result="blurred"/>
+ <feMerge>
+ <feMergeNode in="blurred"/>
+ <feMergeNode in="dix"/>
+ </feMerge>
+ </filter>
+ <filter id="blur_purple">
+ <feColorMatrix type="saturate" in="SourceGraphic" values="0" result="cox"/>
+ <feColorMatrix type="matrix" in="cox" values=" 0 .1 .7 0 0
+ 0 0 0 0 0
+ 0 .1 2 0 0
+ 0 .1 1 0 0
+ " result="dix"/>
+ <feMorphology in="dix" operator="dilate" radius="1" result="wangz" />
+ <feGaussianBlur in="wangz" stdDeviation="10" result="blurred"/>
+ <feMerge>
+ <feMergeNode in="blurred"/>
+ <feMergeNode in="dix"/>
+ </feMerge>
+ </filter>
+<filter id="blur_amber_g">
+ <feColorMatrix type="saturate" in="SourceGraphic" values="0" result="cox"/>
+ <feColorMatrix type="matrix" in="cox" values=" 0 1 0 0 0
+ 0 .556 0 0 0
+ 0 0 0 0 0
+ 1 1 0 0 0
+ " result="dix"/>
+ <feMorphology in="dix" operator="dilate" radius="0" result="wangz" />
+ <feGaussianBlur in="wangz" stdDeviation="10" result="blurred"/>
+ <feMerge>
+ <feMergeNode in="blurred"/>
+ <feMergeNode in="dix"/>
+ </feMerge>
+ </filter>
+
+</svg>
diff --git a/stylesheets/svg/shadow.svg b/stylesheets/svg/shadow.svg
new file mode 100755
index 00000000..a23d15e5
--- /dev/null
+++ b/stylesheets/svg/shadow.svg
@@ -0,0 +1,11 @@
+<svg height="0" xmlns="http://www.w3.org/2000/svg">
+ <filter id="drop-shadow">
+ <feGaussianBlur in="SourceGraphic" stdDeviation="4"/>
+ <feOffset dx="0" dy="0" result="offsetblur"/>
+ <feComposite in2="offsetblur" operator="in"/>
+ <feMerge>
+ <feMergeNode/>
+ <feMergeNode in="SourceGraphic"/>
+ </feMerge>
+ </filter>
+</svg>
diff --git a/stylesheets/svg/terminal.svg b/stylesheets/svg/terminal.svg
new file mode 100755
index 00000000..17ddfad7
--- /dev/null
+++ b/stylesheets/svg/terminal.svg
@@ -0,0 +1,10 @@
+<svg>
+ <filter id="sepia">
+ <feColorMatrix
+ type="matrix"
+ values=".343 .669 .119 0 0
+ .249 .626 .130 0 0
+ .172 .334 .111 0 0
+ .000 .000 .000 1 0 "/>
+ </filter>
+</svg>
diff --git a/stylesheets/terminal2.css b/stylesheets/terminal2.css
index a951bc16..f878e857 100644
--- a/stylesheets/terminal2.css
+++ b/stylesheets/terminal2.css
@@ -168,3 +168,19 @@ table.modlog tr th {
background: none;
}
+.bar
+{
+ background: #333!important;
+ -moz-box-shadow: 0 0 40px #000;
+ -webkit-box-shadow: 0 0 40px #000;
+ box-shadow: 0 0 40px #000;
+
+}
+.bar.top
+{
+ border-bottom: 1px solid #666;
+}
+.bar.bottom
+{
+ border-top: 1px solid #666;
+} \ No newline at end of file
diff --git a/stylesheets/terminal_common.css b/stylesheets/terminal_common.css
new file mode 100644
index 00000000..0c92d4af
--- /dev/null
+++ b/stylesheets/terminal_common.css
@@ -0,0 +1,153 @@
+body {
+ background: #111111;
+ font-family: sans-serif;
+ font-size: 12px;
+}
+@font-face {
+ font-family: 'vt220';
+ src: url('./fonts/vt220.ttf') format('truetype');
+}
+h1 {
+ font-family: 'vt220', tahoma;
+ letter-spacing: -2px;
+ font-size: 18pt;
+ margin: 0;
+}
+div.title, h1 {
+ font-family: 'vt220';
+}
+div.title p {
+ font-size: 10px;
+}
+
+
+div.blotter {
+ font-weight: bold;
+ text-align: center;
+}
+header div.subtitle, h1 {
+ text-align: center;
+}
+header div.subtitle {
+ font-size: 8pt;
+}
+img.board_image {
+ -moz-mask: url(./svg/bannermaks.svg#masking);
+ mask: url(./svg/bannermaks.svg#masking);
+ -webkit-mask: url(./img/banner_terminal_mask.png);
+ border: none!important;
+ overflow: visible!important;
+
+}
+.bic {
+ padding: 20px!important;
+ overflow: visible!important;
+}
+a:link, a:visited, p.intro a.email span.name {
+ text-decoration: underline;
+ font-family: sans-serif;
+}
+a:link:hover, a:visited:hover {
+ font-family: sans-serif;
+ text-decoration: underline overline;
+}
+a.post_no {
+ text-decoration: none;
+}
+a.post_no:hover {
+ text-decoration: underline overline;
+}
+div.post.reply {
+ background: #111111;
+ border: 1px dotted;
+}
+div.post.reply.highlighted {
+ background: transparent;
+ border: transparent 1px dotted;
+}
+p.intro span.subject {
+ font-size: 12px;
+ font-family: sans-serif;
+ font-weight: 800;
+}
+p.intro span.name {
+ font-weight: 800;
+}
+p.intro a.capcode, p.intro a.nametag {
+ margin-left: 0;
+}
+input[type="text"], textarea, select {
+ background: #111111;
+ border: 1px dotted;
+ padding-left: 5px;
+ padding-right: -5px;
+ font-family: sans-serif;
+ font-size: 10pt;
+}
+input[type="password"] {
+ background: #111111;
+ border: 1px dotted;
+}
+
+form table tr th {
+ background: #111111;
+ font-weight: 800;
+ text-align: left;
+ padding: 0;
+ border: #ffaf2b 1px dotted;
+}
+div.banner {
+ background: #AA6C00;
+ color: #FFFFFF;
+ text-align: center;
+ width: 250px;
+ padding: 4px;
+ padding-left: 12px;
+ padding-right: 12px;
+ margin-left: auto;
+ margin-right: auto;
+ font-size: 12px;
+}
+input[type="submit"] {
+ background: #111111;
+ border: 1px dotted;
+}
+input[type="submit"]:hover {
+ background: #111111;
+ border: 1px dotted;
+}
+p.fileinfo a:hover {
+ text-decoration: underline;
+}
+div.pages {
+ background: #111111;
+ border: 1px dotted;
+ font-family: sans-serif;
+ font-size: 10pt;
+}
+hr {
+ height: 1px;
+ border: 1px dotted;
+}
+div.ban {
+ border: transparent 0px dotted;
+}
+div.ban h2 {
+ background: transparent;
+ color: lime;
+ font-size: 12px;
+}
+table.modlog tr th {
+ background: #111111;
+}
+
+.desktop-style div.boardlist:nth-child(1) {
+ background-color: #111111;
+}
+.desktop-style div.boardlist:nth-child(1):hover, .desktop-style div.boardlist:nth-child(1).cb-menu {
+ background-color: #111111;
+}
+
+.desktop-style .sub {
+ background: none;
+}
diff --git a/stylesheets/terminal_green.css b/stylesheets/terminal_green.css
new file mode 100644
index 00000000..e629cf71
--- /dev/null
+++ b/stylesheets/terminal_green.css
@@ -0,0 +1,49 @@
+@import url(./terminal_common.css);
+
+body, div.title, h1, a:link, a:visited, p.intro a.email span.name,
+a:link:hover, a:visited:hover, a.post_no, a.post_no:hover,
+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,
+table.modlog tr th, p.intro span.name, p.intro a.capcode, p.intro a.nametag,
+div.pages a.selected, p.intro a.email, p.intro a.email span.name,
+p.intro a.email:hover, p.intro a.email:hover span.name,
+div.boardlist input[type="text"], textarea, select, input[type="password"],
+form table tr th, input[type="submit"], input[type="submit"]:hover, div.pages
+{
+ color: #00FF00;
+}
+
+.boardlist, div.blotter, header div.subtitle, h1, span.quote
+{
+ color: #00FF00!important;
+}
+
+p.intro span.subject, span.trip
+{
+ color: #00FF00;
+}
+
+
+div.ban h2 {
+ color: lime;
+}
+
+
+.bic {
+ -moz-filter: url(./svg/blur.svg#blur_green);
+ filter: url(./svg/blur.svg#blur_green);
+ -webkit-filter: url(svg/blur.svg#blur_green);
+}
+
+
+input[type="text"], textarea, select, input[type="password"], form table tr th,
+input[type="submit"], input[type="submit"]:hover, div.pages, hr, div.ban,
+div.post.reply, div.post.reply.highlighted
+{
+ border-color: #00FF00;
+}
+
+.desktop-style div.boardlist:nth-child(1) {
+ border-bottom: #00FF00 1px dashed;
+}
+
diff --git a/stylesheets/terminal_purple.css b/stylesheets/terminal_purple.css
new file mode 100644
index 00000000..432ce6b8
--- /dev/null
+++ b/stylesheets/terminal_purple.css
@@ -0,0 +1,65 @@
+@import url(./terminal_common.css);
+
+body, div.title, h1, a:link, a:visited, p.intro a.email span.name,
+a:link:hover, a:visited:hover, a.post_no, a.post_no:hover,
+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,
+table.modlog tr th, p.intro span.name, p.intro a.capcode, p.intro a.nametag,
+div.pages a.selected, p.intro a.email, p.intro a.email span.name,
+p.intro a.email:hover, p.intro a.email:hover span.name,
+div.boardlist input[type="text"], form table tr td input[type="text"], textarea, select, input[type="password"],
+form table tr th, input[type="submit"], input[type="submit"]:hover, div.pages
+{
+ color: #8725EC!important;
+}
+
+.boardlist, div.blotter, header div.subtitle, h1, span.quote
+{
+ color: #A6D2FF!important;
+}
+
+p.intro span.subject, span.trip
+{
+ color: #8725EC;
+}
+
+
+div.ban h2 {
+ color: lime;
+}
+
+
+.bic {
+ -moz-filter: url(./svg/blur.svg#blur_purple);
+ filter: url(./svg/blur.svg#blur_purple);
+ -webkit-filter: url(svg/blur.svg#blur_purple);
+}
+
+
+input[type="text"], textarea, select, input[type="password"], form table tr th,
+input[type="submit"], input[type="submit"]:hover, div.pages, hr, div.ban,
+div.post.reply, div.post.reply.highlighted
+{
+ border-color: #8725EC;
+}
+
+.desktop-style div.boardlist:nth-child(1) {
+ border-bottom: #8725EC 1px dashed;
+}
+
+.bar
+{
+ border-color: #8725EC !important;
+ background-color: black;
+ -moz-box-shadow: none;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.bar.top
+{
+ border-bottom-style: dotted;
+}
+.bar.bottom
+{
+ border-top-style: dotted;
+}
diff --git a/stylesheets/volafile.css b/stylesheets/volafile.css
new file mode 100644
index 00000000..5d250bf6
--- /dev/null
+++ b/stylesheets/volafile.css
@@ -0,0 +1,96 @@
+/**
+* volafile.css fuck you
+A sexy css for lainchan.org created by petsu / yuuko based off of volafile.io
+
+feel free to steal it.
+
+*/
+@import url("/stylesheets/dark.css");
+@font-face
+{
+ font-family: "Open Sans Light";
+ src: url("/stylesheets/fonts/OpenSans-Light-webfont.eot") format("embedded-opentype"), url("/stylesheets/fonts/OpenSans-Light-webfont.woff") format("woff"), url("/stylesheets/fonts/OpenSans-Light-webfont.ttf") format("truetype"), url("/stylesheets/fonts/OpenSans-Light-webfont.svg#OpenSansLight") format("svg");
+}
+body
+{
+ background: #395168;
+ color: #E0E0E0;
+}
+.bar
+{
+ -moz-box-shadow: 0 0 40px #435D78;
+ -webkit-box-shadow: 0 0 40px #435D78;
+ box-shadow: 0 0 40px #435D78;
+ background-color: #435D78!important;
+ border-color: #486582!important;
+}
+.boardlist
+{
+ text-shadow: none!important;
+}
+header h1, header div.subtitle, form table tr th, form table tr td input
+{
+ color: #E0E0E0!important;
+}
+header h1
+{
+ font-family: "Open Sans Light",sans-serif;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 32px;
+ letter-spacing: 0px;
+ margin-top: calc(-16px / 3 - 6.5px);
+}
+
+div.topbar, input[type="text"], select, form table tr th, form table tr td input[type="text"], form table tr td textarea, div.post.reply, [type="submit"], input[type="password"], div.pages
+{
+ background: #435D78!important;
+ border-color: #486582!important;
+ color: #E0E0E0!important;
+}
+div.post.reply.highlighted{
+ background-color: #486582!important;
+}
+form table tr td input[type="text"]:focus, form table tr td textarea:focus
+{
+ border-color: #5E7F9F!important;
+}
+input[type="submit"][name="post"]
+{
+ color: #3A4040!important;
+ background-color: #DCA1F5!important;
+ border-color: #DCA1F5!important;
+}
+.blotter
+{
+ color: #DCA1F5!important;
+}
+hr {
+ border-color: #486582;
+}
+a
+{
+ color: #D8D8D8!important;
+}
+p.intro span.subject
+{
+ color: #13C15F;
+}
+p.intro span.name
+{
+ color: #E0E0E0;
+}
+span[style="color:orange;font-weight:bold"]
+{
+ color: #D880FC!important;
+
+}
+a:hover, p.intro a.post_no:hover
+{
+ color: #EDEDED!important;
+ text-shadow: none!important;
+}
+:not(a) > i.fa
+{
+ color: #DCA1F5;
+}
diff --git a/stylesheets/yotsuba.css b/stylesheets/yotsuba.css
index 5324d1a7..4ec557b9 100644
--- a/stylesheets/yotsuba.css
+++ b/stylesheets/yotsuba.css
@@ -27,6 +27,11 @@ div.post.reply div.body a {
}
form table tr th {
background: #EA8;
+ color: #800000;
+ border: 1px solid #800000;
+}
+textarea:focus, input:not([type="file"]):not([type="checkbox"]):focus, [type="submit"]:hover {
+ border: 1px solid #EA8;
}
div.ban h2 {
background: #FCA;
@@ -38,6 +43,13 @@ div.ban {
div.ban p {
color: black;
}
+.bar {
+ background-color: #F0E0D6;
+ border-color: #D9BFB7!important;
+ -moz-box-shadow: 0 0 40px #fed6af;
+ -webkit-box-shadow: 0 0 40px #fed6af;
+ box-shadow: 0 0 40px #fed6af;
+}
div.pages {
background: #F0E0D6;
border-color: #D9BFB7;
diff --git a/templates/badges.html b/templates/badges.html
new file mode 100644
index 00000000..0aaf11dc
--- /dev/null
+++ b/templates/badges.html
@@ -0,0 +1,4 @@
+<p class="unimportant badges">
+<!--<a href="http://validator.w3.org/check?uri=http://lainchan.org{{ board.url }}"><img src="/static/html.png" alt="Valid HTML" /></a><a href="http://wiki.nginx.org"><img src="/static/nginx.png" alt="NGIИX" /></a><a href="http://ubuntu.com/"><img src="/static/ubuntu.png" alt="Ubuntu Powered" /></a> !-->
+<a href="https://www.openssl.org"><img src="/static/ssl.png" alt="SSL Secure"></a>
+</p>
diff --git a/templates/banned.html b/templates/banned.html
index b4cdf3f9..65d66281 100644
--- a/templates/banned.html
+++ b/templates/banned.html
@@ -1,6 +1,7 @@
{% filter remove_whitespace %}
{# Automatically removes unnecessary whitespace #}
<div class="ban">
+ <iframe width="420" height="315" src="https://www.youtube.com/embed/FXPKJUE86d0" frameborder="0" allowfullscreen></iframe>
{% if ban.expires and time() >= ban.expires %}
<h2>{% trans %}You were banned! ;_;{% endtrans %}</h2>
{% else %}
diff --git a/templates/boardlist.html b/templates/boardlist.html
index 62646845..e69de29b 100644
--- a/templates/boardlist.html
+++ b/templates/boardlist.html
@@ -1 +0,0 @@
-I'm your overboard boardlist. You can put here anything and I reside in templates/boardlist.html
diff --git a/templates/generic_page.html b/templates/generic_page.html
index fbfc3c50..6d2f28c3 100644
--- a/templates/generic_page.html
+++ b/templates/generic_page.html
@@ -6,6 +6,8 @@
<title>{{ board.url }} - {{ board.name }}</title>
{% endblock %}
</head>
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
+
<body class="8chan vichan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
{{ boardlist.top }}
{% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr />{% endif %}
diff --git a/templates/header.html b/templates/header.html
index dd15eeb8..06bc95d9 100644
--- a/templates/header.html
+++ b/templates/header.html
@@ -4,6 +4,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
{% if config.meta_keywords %}<meta name="keywords" content="{{ config.meta_keywords }}">{% endif %}
{% if config.default_stylesheet.1 != '' %}<link rel="stylesheet" type="text/css" id="stylesheet" href="{{ config.uri_stylesheets }}{{ config.default_stylesheet.1 }}">{% endif %}
+ {% if config.default_code_stylesheet.1 != '' %}<link rel="stylesheet" type="text/css" id="code_stylesheet" href="{{ config.uri_stylesheets }}{{ config.default_code_stylesheet.1 }}">{% endif %}
{% if config.font_awesome %}<link rel="stylesheet" href="{{ config.root }}{{ config.font_awesome_css }}">{% endif %}
{% if config.country_flags_condensed %}<link rel="stylesheet" href="{{ config.root }}{{ config.country_flags_condensed_css }}">{% endif %}
<script type="text/javascript">
diff --git a/templates/index.html b/templates/index.html
index 1be614e3..52c7419b 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -2,6 +2,7 @@
<html>
<head>
<meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
<script type="text/javascript">
var
@@ -17,11 +18,13 @@
<title>{{ board.url }} - {{ board.title|e }}</title>
</head>
<body class="8chan vichan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %} active-{% if not no_post_form %}index{% else %}ukko{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
- {{ boardlist.top }}
+ <div class="bar top">
+ {{ boardlist.top }}
+ </div>
{% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr />{% endif %}
{% if config.url_banner %}<img class="board_image" src="{{ config.url_banner }}" {% if config.banner_width or config.banner_height %}style="{% if config.banner_width %}width:{{ config.banner_width }}px{% endif %};{% if config.banner_width %}height:{{ config.banner_height }}px{% endif %}" {% endif %}alt="" />{% endif %}
-
+
<header>
<h1>{{ board.url }} - {{ board.title|e }}</h1>
<div class="subtitle">
@@ -47,16 +50,21 @@
{% endif %}
{% if config.page_nav_top %}
- <div class="pages top">
+ <!--<div class="pages top">
{% for page in pages %}
[<a {% if page.selected %}class="selected"{% endif %}{% if not page.selected %}href="{{ page.link }}"{% endif %}>{{ page.num }}</a>]{% if loop.last %} {% endif %}
{% endfor %}
{{ btn.next }}
- </div>
+ </div>-->
{% endif %}
-
+
{% if config.global_message %}<hr /><div class="blotter">{{ config.global_message }}</div>{% endif %}
<hr />
+ {% if config.catalog_link %}
+ | <a href="{{ config.root }}{{ board.dir }}{{ config.catalog_link }}">Catalog</a>
+ {% endif %}
+ <hr />
+
<form name="postcontrols" action="{{ config.post_url }}" method="post">
<input type="hidden" name="board" value="{{ board.uri }}" />
{% if mod %}<input type="hidden" name="mod" value="1" />{% endif %}
@@ -78,16 +86,33 @@
{{ config.ad.bottom }}
<footer>
- <p class="unimportant" style="margin-top:20px;text-align:center;">- Tinyboard +
- <a href="https://engine.vichan.net/">vichan</a> {{ config.version }} -
- <br>Tinyboard Copyright &copy; 2010-2014 Tinyboard Development Group
- <br><a href="https://engine.vichan.net/">vichan</a> Copyright &copy; 2012-2016 vichan-devel</p>
+ <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> +
+ <a href='https://github.com/lainchan/lainchan'>lainchan</a> {{ config.version }} -
+ <br><a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2014 Tinyboard Development Group
+ <br><a href="https://engine.vichan.net/">vichan</a> Copyright &copy; 2012-2016 vichan-devel
+ <br><a href="https://github.com/lainchan/lainchan">lainchan</a> Copyright &copy; 2014-2016 lainchan Administration</p>
{% for footer in config.footer %}<p class="unimportant" style="text-align:center;">{{ footer }}</p>{% endfor %}
</footer>
+
+ <div class="bar bottom">
+ <div class="pages">
+ {{ btn.prev }} [ {% for page in pages %}
+ <a {% if page.selected %}class="selected"{% endif %}{% if not page.selected %}href="{{ page.link }}"{% endif %}>{{ page.num }}</a>{% if not loop.last %} /{% endif %}
+ {% endfor %} ] {{ btn.next }}
+ {% if config.catalog_link %}
+ | <a href="{{ config.root }}{{ board.dir }}{{ config.catalog_link }}">Catalog</a>
+ {% endif %}
+ </div>
+ </div>
+
+
+ </div>
<script type="text/javascript">{% raw %}
ready();
{% endraw %}</script>
</body>
</html>
+
diff --git a/templates/main.js b/templates/main.js
index c2a6f6c0..af665987 100644..100755
--- a/templates/main.js
+++ b/templates/main.js
@@ -115,6 +115,11 @@ var styles = {
{% for stylesheet in stylesheets %}{% raw %}'{% endraw %}{{ stylesheet.name|addslashes }}{% raw %}' : '{% endraw %}{{ stylesheet.uri|addslashes }}{% raw %}',
{% endraw %}{% endfor %}{% raw %}
};
+var codestyles = {
+ {% endraw %}
+ {% for stylesheet in code_stylesheets %}{% raw %}'{% endraw %}{{ stylesheet.name|addslashes }}{% raw %}' : '{% endraw %}{{ stylesheet.uri|addslashes }}{% raw %}',
+ {% endraw %}{% endfor %}{% raw %}
+};
if (typeof board_name === 'undefined') {
var board_name = false;
@@ -132,6 +137,7 @@ function changeStyle(styleName, link) {
{% endif %}
{% raw %}
+ // Main stylesheet
if (!document.getElementById('stylesheet')) {
var s = document.createElement('link');
s.rel = 'stylesheet';
@@ -140,9 +146,21 @@ function changeStyle(styleName, link) {
var x = document.getElementsByTagName('head')[0];
x.appendChild(s);
}
-
+
document.getElementById('stylesheet').href = styles[styleName];
- selectedstyle = styleName;
+ selectedstyle = styleName;
+
+ // Code stylesheet
+ if (!document.getElementById('code_stylesheet')) {
+ var s = document.createElement('link');
+ s.rel = 'stylesheet';
+ s.type = 'text/css';
+ s.id = 'code_stylesheet';
+ var x = document.getElementsByTagName('head')[0];
+ x.appendChild(s);
+ }
+
+ document.getElementById('code_stylesheet').href = codestyles[styleName];
if (document.getElementsByClassName('styles').length != 0) {
var styleLinks = document.getElementsByClassName('styles')[0].childNodes;
diff --git a/templates/mod/ban_form.html b/templates/mod/ban_form.html
index 98cc34b2..91281359 100644
--- a/templates/mod/ban_form.html
+++ b/templates/mod/ban_form.html
@@ -12,6 +12,9 @@
{% if post and board %}
<input type="hidden" name="delete" value="{% if delete %}1{% else %}0{% endif %}">
{% endif %}
+ {% if thread %}
+ <input type="hidden" name="thread" value="{{ thread }}">
+ {% endif %}
<table>
diff --git a/templates/mod/config-editor-php.html b/templates/mod/config-editor-php.html
index 0c1a3a09..8610316b 100644
--- a/templates/mod/config-editor-php.html
+++ b/templates/mod/config-editor-php.html
@@ -54,11 +54,11 @@ function resize () {
function delayedResize () {
window.setTimeout(resize, 0);
}
-observe(text, 'change', resize);
+/*observe(text, 'change', resize);
observe(text, 'cut', delayedResize);
observe(text, 'paste', delayedResize);
observe(text, 'drop', delayedResize);
-observe(text, 'keydown', delayedResize);
+observe(text, 'keydown', delayedResize);*/
resize();
-</script> \ No newline at end of file
+</script>
diff --git a/templates/mod/confirm.html b/templates/mod/confirm.html
index 65e43eb3..ab91c9ba 100644
--- a/templates/mod/confirm.html
+++ b/templates/mod/confirm.html
@@ -1,5 +1,5 @@
<p style="text-align:center;font-size:1.1em">
- {% trans 'Are you sure you want to do that?' %} <a href="?/{{ request }}/{{ token }}">{% trans 'Click to proceed to' %} ?/{{ request }}</a>.
+ {% trans 'Are you sure you want to do that?' %} <a href="?/{{ request }}/{{ token }}{% if rest %}&amp;{{ rest }}{% endif %}">{% trans 'Click to proceed to' %} ?/{{ request }}</a>.
</p>
<p class="unimportant" style="text-align:center">
{% trans 'You are probably seeing this message because Javascript being disabled. This is a necessary security measure to prevent CSRF attacks.' %}
diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html
index d13bf7f2..706504ea 100644
--- a/templates/mod/dashboard.html
+++ b/templates/mod/dashboard.html
@@ -1,3 +1,62 @@
+<ul>
+ {% for board in boards %}
+ <li>
+ <a href="?/{{ config.board_path|sprintf(board.uri) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(board.uri) }}</a>
+ -
+ {{ board.title|e }}
+ {% if board.subtitle %}
+ <small>&mdash;
+ {% if config.allow_subtitle_html %}
+ {{ board.subtitle }}
+ {% else %}
+ {{ board.subtitle|e }}
+ {% endif %}
+ </small>
+ {% endif %}
+ {% if mod|hasPermission(config.mod.manageboards) %}
+ <a href="?/edit/{{ board.uri }}"><small>[{% trans 'edit' %}]</small></a>
+ {% endif %}
+ </li>
+ {% endfor %}
+
+ {% if mod|hasPermission(config.mod.newboard) %}
+ <li style="margin-top:15px"><a href="?/new-board"><strong>{% trans 'Create new board' %}</strong></a></li>
+ {% endif %}
+
+ {% if mod|hasPermission(config.mod.reports) %}
+ <li>
+ {% if reports > 0 %}<strong>{% endif %}
+ <a href="?/reports">{% trans 'Report queue' %} ({{ reports }})</a>
+ {% if reports > 0 %}</strong>{% endif %}
+ </li>
+ {% endif %}
+ {% if mod|hasPermission(config.mod.view_banlist) %}
+ <li><a href="?/bans">{% trans 'Ban list' %}</a></li>
+ {% endif %}
+ {% if config.ban_appeals and mod|hasPermission(config.mod.view_ban_appeals) %}
+ <li><a href="?/ban-appeals">{% trans 'Ban appeals' %}</a></li>
+ {% endif %}
+ {% if mod|hasPermission(config.mod.manageusers) %}
+ <li><a href="?/users">{% trans 'Manage users' %}</a></li>
+ {% elseif mod|hasPermission(config.mod.change_password) %}
+ <li><a href="?/users/{{ mod.id }}">{% trans 'Change password' %}</a></li>
+ {% endif %}
+ {% if mod|hasPermission(config.mod.themes) %}
+ <li><a href="?/themes">{% trans 'Manage themes' %}</a></li>
+ {% endif %}
+ {% if mod|hasPermission(config.mod.modlog) %}
+ <li><a href="?/log">{% trans 'Moderation log' %}</a></li>
+ {% endif %}
+ {% if mod|hasPermission(config.mod.recent) %}
+ <li><a href="?/recent/25">{% trans 'Recent posts' %}</a></li>
+ {% endif %}
+ {% if mod|hasPermission(config.mod.rebuild) %}
+ <li><a href="?/rebuild">{% trans 'Rebuild' %}</a></li>
+ {% endif %}
+ {% if mod|hasPermission(config.mod.edit_config) %}
+ <li><a href="?/config">{% trans 'Configuration' %}</a></li>
+ {% endif %}
+=======
<fieldset>
<legend>{% trans 'Boards' %}</legend>
@@ -120,60 +179,40 @@
</fieldset>
{% if mod|hasPermission(config.mod.search) %}
- <fieldset>
- <legend>{% trans 'Search' %}</legend>
-
- <ul>
- <li>
- {% include 'mod/search_form.html' %}
- </li>
- </ul>
- </fieldset>
+
+ <li>
+ {% include 'mod/search_form.html' %}
+ </li>
+
{% endif %}
{% if config.mod.dashboard_links|count %}
- <fieldset>
- <legend>{% trans 'Other' %}</legend>
-
- <ul>
- {% for label,link in config.mod.dashboard_links %}
- <li><a href="{{ link }}">{{ label }}</a></li>
- {% endfor %}
- </ul>
- </fieldset>
+
+ {% for label,link in config.mod.dashboard_links %}
+ <li><a href="{{ link }}">{{ label }}</a></li>
+ {% endfor %}
+
{% endif %}
{% if config.debug %}
- <fieldset>
- <legend>{% trans 'Debug' %}</legend>
- <ul>
- <li><a href="?/debug/antispam">{% trans 'Anti-spam' %}</a></li>
- <li><a href="?/debug/recent">{% trans 'Recent posts' %}</a></li>
- {% if mod|hasPermission(config.mod.debug_sql) %}
- <li><a href="?/debug/sql">{% trans 'SQL' %}</a></li>
- {% endif %}
- </ul>
- </fieldset>
+
+ <li><a href="?/debug/antispam">{% trans 'Anti-spam' %}</a></li>
+ <li><a href="?/debug/recent">{% trans 'Recent posts' %}</a></li>
+ {% if mod|hasPermission(config.mod.debug_sql) %}
+ <li><a href="?/debug/sql">{% trans 'SQL' %}</a></li>
+ {% endif %}
+
{% endif %}
{% if newer_release %}
- <fieldset>
- <legend>Update</legend>
- <ul>
- <li>
- A newer version of vichan
- (<strong>v{{ newer_release.massive }}.{{ newer_release.major }}.{{ newer_release.minor }}</strong>) is available!
- See <a href="https://engine.vichan.net">https://engine.vichan.net/</a> for upgrade instructions.
- </li>
- </ul>
- </fieldset>
-{% endif %}
-<fieldset>
- <legend>{% trans 'User account' %}</legend>
-
- <ul>
- <li><a href="?/logout/{{ logout_token }}">{% trans 'Logout' %}</a></li>
- </ul>
-</fieldset>
+ <li>
+ A newer version of vichan
+ (<strong>v{{ newer_release.massive }}.{{ newer_release.major }}.{{ newer_release.minor }}</strong>) is available!
+ See <a href="https://engine.vichan.net">https://engine.vichan.net/</a> for upgrade instructions.
+ </li>
+
+{% endif %}
+ <li><a href="?/logout/{{ logout_token }}">{% trans 'Logout' %}</a></li>
+</ul>
diff --git a/templates/notbanned.html b/templates/notbanned.html
new file mode 100644
index 00000000..6654b6d6
--- /dev/null
+++ b/templates/notbanned.html
@@ -0,0 +1,7 @@
+{% filter remove_whitespace %}
+{# Automatically removes unnecessary whitespace #}
+<div class="ban">
+ <h2>You are not banned!</h2>
+ <p class="reason">Well done on not being terrible!</p>
+</div>
+{% endfilter %}
diff --git a/templates/page.html b/templates/page.html
index 027ed3b9..a5327cf8 100644
--- a/templates/page.html
+++ b/templates/page.html
@@ -2,6 +2,8 @@
<html>
<head>
<meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
+
<script type="text/javascript">
var active_page = "page";
</script>
diff --git a/templates/post/fileinfo.html b/templates/post/fileinfo.html
index 4a3300a4..0446ba29 100644
--- a/templates/post/fileinfo.html
+++ b/templates/post/fileinfo.html
@@ -7,7 +7,7 @@
{% if file.file == 'deleted' %}
<img class="post-image deleted" src="{{ config.image_deleted }}" alt="" />
{% else %}
- <p class="fileinfo">File: <a href="{{ config.uri_img }}{{ file.file }}">{{ file.file }}</a> <span class="unimportant">
+ <p class="fileinfo">File: <a href="{{ config.uri_img }}{{ file.file }}">{{ file.file }}</a> <span class="details">
(
{% if file.thumb == 'spoiler' %}
{% trans %}Spoiler Image{% endtrans %},
diff --git a/templates/post/image_identification.html b/templates/post/image_identification.html
index e6e14abc..ff25ff95 100644
--- a/templates/post/image_identification.html
+++ b/templates/post/image_identification.html
@@ -1,6 +1,6 @@
{% if file.thumb != 'file' and config.image_identification %}
- <span class='image_id'>
+ <span class='unimportant image_id'>
{% if config.image_identification_imgops %}
<a href="http://imgops.com/{{ config.domain }}{{ config.uri_img }}{{ file.file }}" target="_blank">ImgOps</a>
{% endif %}
diff --git a/templates/post/post_controls.html b/templates/post/post_controls.html
index 60dc6fc4..7e56edd3 100644
--- a/templates/post/post_controls.html
+++ b/templates/post/post_controls.html
@@ -2,19 +2,19 @@
<span class="controls {% if not post.thread %}op{% endif %}">
{% if mod|hasPermission(config.mod.delete, board.uri) %}
- {{ secure_link_confirm(config.mod.link_delete, 'Delete'|trans, 'Are you sure you want to delete this?'|trans, board.dir ~ 'delete/' ~ post.id) }}&nbsp;
+ <a title="{% trans %}Delete{% endtrans %}" onclick="if (event.which==2) return true;if (confirm('{% trans %}Are you sure you want to delete this?{% endtrans %}')) document.location='?/{{ secure_link(board.dir ~ 'delete/' ~ post.id) }}{% if post.thread %}&amp;thread={{ post.thread }}{% endif %}';return false;" href="?/{{ board.dir }}delete/{{ post.id }}{% if post.thread %}&amp;thread={{ post.thread }}{% endif %}">{{ config.mod.link_delete }}</a>&nbsp;
{% endif %}
{% if mod|hasPermission(config.mod.deletebyip, board.uri) %}
- {{ secure_link_confirm(config.mod.link_deletebyip, 'Delete all posts by IP'|trans, 'Are you sure you want to delete all posts by this IP address?'|trans, board.dir ~ 'deletebyip/' ~ post.id) }}&nbsp;
+ <a title="{% trans %}Delete all posts by IP{% endtrans %}" onclick="if (event.which==2) return true;if (confirm('{% trans %}Are you sure you want to delete all posts by this IP address?{% endtrans %}')) document.location='?/{{ secure_link(board.dir ~ 'deletebyip/' ~ post.id) }}{% if post.thread %}&amp;thread={{ post.thread }}{% endif %}';return false;" href="?/{{ board.dir }}deletebyip/{{ post.id }}{% if post.thread %}&amp;thread={{ post.thread }}{% endif %}">{{ config.mod.link_deletebyip }}</a>&nbsp;
{% endif %}
{% if mod|hasPermission(config.mod.deletebyip_global, board.uri) %}
- {{ secure_link_confirm(config.mod.link_deletebyip_global, 'Delete all posts by IP across all boards'|trans, 'Are you sure you want to delete all posts by this IP address, across all boards?'|trans, board.dir ~ 'deletebyip/' ~ post.id ~ '/global') }}&nbsp;
+ <a title="{% trans %}Delete all posts by IP across all boards{% endtrans %}" onclick="if (event.which==2) return true;if (confirm('{% trans %}Are you sure you want to delete all posts by this IP address, across all boards?{% endtrans %}')) document.location='?/{{ secure_link(board.dir ~ 'deletebyip/' ~ post.id ~ '/global') }}{% if post.thread %}&amp;thread={{ post.thread }}{% endif %}';return false;" href="?/{{ board.dir }}deletebyip/{{ post.id }}/global{% if post.thread %}&amp;thread={{ post.thread }}{% endif %}">{{ config.mod.link_deletebyip_global }}</a>&nbsp;
{% endif %}
{% if mod|hasPermission(config.mod.ban, board.uri) %}
- <a title="{% trans %}Ban{% endtrans %}" href="?/{{ board.dir }}ban/{{ post.id }}">{{ config.mod.link_ban }}</a>&nbsp;
+ <a title="{% trans %}Ban{% endtrans %}" href="?/{{ board.dir }}ban/{{ post.id }}{% if post.thread %}&amp;thread={{ post.thread }}{% endif %}">{{ config.mod.link_ban }}</a>&nbsp;
{% endif %}
{% if mod|hasPermission(config.mod.bandelete, board.uri) %}
- <a title="{% trans %}Ban & Delete{% endtrans %}" href="?/{{ board.dir }}ban&amp;delete/{{ post.id }}">{{ config.mod.link_bandelete }}</a>&nbsp;
+ <a title="{% trans %}Ban & Delete{% endtrans %}" href="?/{{ board.dir }}ban&amp;delete/{{ post.id }}{% if post.thread %}&amp;thread={{ post.thread }}{% endif %}">{{ config.mod.link_bandelete }}</a>&nbsp;
{% endif %}
{% if not post.thread %}
diff --git a/templates/post_form.html b/templates/post_form.html
index 0e0d3fed..0b02dab2 100644
--- a/templates/post_form.html
+++ b/templates/post_form.html
@@ -9,6 +9,9 @@
{% endif %}
{% if mod %}<input type="hidden" name="mod" value="1">{% endif %}
<table>
+ {% if id %}<tr>
+ <td colspan="2"><div class="banner">{% trans %}Posting mode: Reply{% endtrans %} <a class="unimportant" href="{{ return }}">[{% trans %}Return{% endtrans %}]</a></div></td>
+ </tr>{% endif %}
{% if not config.field_disable_name or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}<tr>
<th>
{% trans %}Name{% endtrans %}
@@ -36,7 +39,7 @@
{% endif %}
{{ antibot.html() }}
{% if not (not (config.field_disable_subject or (id and config.field_disable_reply_subject)) or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri))) %}
- <input accesskey="s" style="margin-left:2px;" type="submit" name="post" value="{% if id %}{{ config.button_reply }}{% else %}{{ config.button_newtopic }}{% endif %}" />{% if config.spoiler_images %} <input id="spoiler" name="spoiler" type="checkbox"> <label for="spoiler">{% trans %}Spoiler Image{% endtrans %}</label> {% endif %}
+ <input accesskey="s" style="margin-left:2px;" type="submit" name="post" value="{% if id %}{{ config.button_reply }}{% else %}{{ config.button_newtopic }}{% endif %}" />{% if config.spoiler_images %}<div id="spoilercontainer"> <input id="spoiler" name="spoiler" type="checkbox"> <label for="spoiler">{% trans %}Spoiler Image{% endtrans %}</label></div>{% endif %}
{% endif %}
{{ antibot.html() }}
</td>
@@ -48,11 +51,12 @@
</th>
<td>
<input style="float:left;" type="text" name="subject" size="25" maxlength="100" autocomplete="off">
- <input accesskey="s" style="margin-left:2px;" type="submit" name="post" value="{% if id %}{{ config.button_reply }}{% else %}{{ config.button_newtopic }}{% endif %}" />{% if config.spoiler_images %} <input id="spoiler" name="spoiler" type="checkbox"> <label for="spoiler">{% trans %}Spoiler Image{% endtrans %}</label>{% endif %}
+ <input accesskey="s" style="margin-left:2px;" type="submit" name="post" value="{% if id %}{{ config.button_reply }}{% else %}{{ config.button_newtopic }}{% endif %}" />
+ <input id="spoiler" name="spoiler" type="checkbox"><label for="spoiler">Spoiler Image</label>
</td>
</tr>
{% endif %}
- <tr>
+ {% if not config.field_disable_comment or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}<tr>
<th>
{% trans %}Comment{% endtrans %}
{{ antibot.html() }}
@@ -62,11 +66,12 @@
{{ antibot.html() }}
{% if not (not (config.field_disable_subject or (id and config.field_disable_reply_subject)) or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri))) %}
{% if not (not config.field_disable_email or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri))) %}
- <input accesskey="s" style="margin-left:2px;" type="submit" name="post" value="{% if id %}{{ config.button_reply }}{% else %}{{ config.button_newtopic }}{% endif %}" />{% if config.spoiler_images %} <input id="spoiler" name="spoiler" type="checkbox"> <label for="spoiler">{% trans %}Spoiler Image{% endtrans %}</label>{% endif %}
+ <input accesskey="s" style="margin-left:2px;" type="submit" name="post" value="{% if id %}{{ config.button_reply }}{% else %}{{ config.button_newtopic }}{% endif %}" />
+ <input id="spoiler" name="spoiler" type="checkbox"><label for="spoiler">Spoiler Image</label>
{% endif %}
{% endif %}
</td>
- </tr>
+ </tr>{% endif %}
{% if config.recaptcha %}
<tr>
<th>
diff --git a/templates/post_reply.html b/templates/post_reply.html
index 451ff1b9..57f55c45 100644
--- a/templates/post_reply.html
+++ b/templates/post_reply.html
@@ -1,27 +1,30 @@
{% filter remove_whitespace %}
{# tabs and new lines will be ignored #}
-<div class="post reply" id="reply_{{ post.id }}">
-<p class="intro">
- {% if not index %}<a id="{{ post.id }}" class="post_anchor"></a>{% endif %}
- <input type="checkbox" class="delete" name="delete_{{ post.id }}" id="delete_{{ post.id }}" />
- <label for="delete_{{ post.id }}">
- {% include 'post/subject.html' %}
- {% include 'post/name.html' %}
- {% include 'post/ip.html' %}
- {% include 'post/flag.html' %}
- {% include 'post/time.html' %}
- </label>
- {% include 'post/poster_id.html' %}&nbsp;
- <a class="post_no" id="post_no_{{ post.id }}" onclick="highlightReply({{ post.id }})" href="{% if isnoko50 %}{{ post.link('', '50') }}{% else %}{{ post.link }}{% endif %}">No.</a>
- <a class="post_no" onclick="citeReply({{ post.id }})" href="{% if isnoko50 %}{{ post.link('q', '50') }}{% else %}{{ post.link('q') }}{% endif %}">{{ post.id }}</a>
+<div class="postcontainer" id="pc{{ post.id }}">
+ <div class="sidearrows">&gt;&gt;</div>
+ <div class="post reply" id="reply_{{ post.id }}">
+ <p class="intro">
+ {% if not index %}<a id="{{ post.id }}" class="post_anchor"></a>{% endif %}
+ <input type="checkbox" class="delete" name="delete_{{ post.id }}" id="delete_{{ post.id }}" />
+ <label for="delete_{{ post.id }}">
+ {% include 'post/subject.html' %}
+ {% include 'post/name.html' %}
+ {% include 'post/ip.html' %}
+ {% include 'post/flag.html' %}
+ {% include 'post/time.html' %}
+ </label>
+ {% include 'post/poster_id.html' %}&nbsp;
+ <a class="post_no" id="post_no_{{ post.id }}" onclick="highlightReply({{ post.id }})" href="{% if isnoko50 %}{{ post.link('', config.file_page50) }}{% else %}{{ post.link }}{% endif %}">No.</a>
+ <a class="post_no" onclick="citeReply({{ post.id }})" href="{% if isnoko50 %}{{ post.link('q', config.file_page50) }}{% else %}{{ post.link('q') }}{% endif %}">{{ post.id }}</a>
</p>
- {% include 'post/fileinfo.html' %}
- {% include 'post/post_controls.html' %}
- <div class="body" {% if post.files|length > 1 %}style="clear:both"{% endif %}>
- {% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %}
- {% if post.modifiers['ban message'] %}
- {{ config.mod.ban_message|sprintf(post.modifiers['ban message']) }}
- {% endif %}
+ {% include 'post/fileinfo.html' %}
+ {% include 'post/post_controls.html' %}
+ <div class="body" {% if post.files|length > 1 %}style="clear:both"{% endif %}>
+ {% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %}
+ {% if post.modifiers['ban message'] %}
+ {{ config.mod.ban_message|sprintf(post.modifiers['ban message']) }}
+ {% endif %}
+ </div>
</div>
</div>
<br/>
diff --git a/templates/posts.sql b/templates/posts.sql
index 070e687b..070e687b 100644..100755
--- a/templates/posts.sql
+++ b/templates/posts.sql
diff --git a/templates/rules.html b/templates/rules.html
new file mode 100644
index 00000000..76fb6a5f
--- /dev/null
+++ b/templates/rules.html
@@ -0,0 +1,33 @@
+<div class="ban" id="global">
+ <h2>GLOBAL RULES</h2>
+ <ol start="0">
+ <li>Do not post in or view any boards if you are under 18 years of age.</li>
+ <li>If you break the rules we will delete your post. Do it repeatedly and you'll be derezzed.</li>
+ <li>Do not call for mods, or announce reports in a thread.</li>
+ <li>Always argue in good faith and avoid using personal attacks.</li>
+ <li>You should always elaborate on your opinions rather than just spilling the soykaf.</li>
+ <li>Don't respond with aggression to perceived flames or trolls (or at all.)</li>
+ <li>Do not whine and cry about 8chan, "quality", "invasions", "newfags", mods, bans, or kalyx outside of /q/.</li>
+ <li>Do not spam or advertise unrelated content.</li>
+ <li>Do not post child pornography or questionable 2D/3DCG/3DPG sexual depictions of children. This includes "child models".</li>
+ <li>If you must post it, spoiler any NSFW content and make sure it's relevant to the discussion.</li>
+ <li>Do not upload malicious archives.</li>
+ <li>Read the rules again. <code>/* infinite iteration will fix later */</code></li>
+ </ol>
+</div>
+
+<div class="ban" id="tips">
+ <h2>PRO TIPS FOR MAXIMUM FUN:</h2>
+ <ul>
+ <li>The mods are not on powertrips, they are friendly and are trying to ensure the quality of lainchan, not belittle your ideas.</li>
+ <li>Lainchan is a place to have your voice heard but not a place for you to drown out others' voices.</li>
+ <li>Mods usually ask each other for opinions before doing anything. We hate having to ban someone.</li>
+ <li> Just relax and try to have fun. Jokes are always welcome.</li>
+ <li> Visit a board you've never been to. Try out /random/.</li>
+ <li> Max file size is 35 mb.</li>
+ <li> PDF, ePub, and webm are supported across the boards.</li>
+ <li>We ALWAYS need contributors to our board software, located on <a href="https://github.com/lainchan/lainchan/">github</a></li>
+ <li> Dice rolling: posting in the email field with the form "dice XdY+/-Z" will result in X Y-sided dice rolled and summed, with the modifier Z added, the result is displayed at the top of the post body.</li>
+ <li> Be smart when posting about potentially illegal activities.</li>
+ </ul>
+</div>
diff --git a/templates/themes/basic/index.html b/templates/themes/basic/index.html
index 9d7a2c41..ad5b92ca 100644
--- a/templates/themes/basic/index.html
+++ b/templates/themes/basic/index.html
@@ -2,22 +2,25 @@
<!doctype html>
<html>
<head>
+ <link rel="stylesheet" media="screen" href="/stylesheets/style.css">
<meta charset="utf-8">
<title>{{ settings.title }}</title>
{% if config.meta_keywords %}<meta name="keywords" content="{{ config.meta_keywords }}">{% endif %}
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
{% if config.url_favicon %}<link rel="shortcut icon" href="{{ config.url_favicon }}">{% endif %}
- <link rel="stylesheet" media="screen" href="{{ config.url_stylesheet }}">
- {% if config.default_stylesheet.1 != '' %}<link rel="stylesheet" type="text/css" id="stylesheet" href="{{ config.uri_stylesheets }}{{ config.default_stylesheet.1 }}">{% endif %}
+ <link rel="stylesheet" media="screen" href="/stylesheets/dark.css">
+ <!--{% if config.default_stylesheet.1 != '' %}<link rel="stylesheet" type="text/css" id="stylesheet" href="{{ config.uri_stylesheets }}{{ config.default_stylesheet.1 }}">{% endif %}-->
{% if config.font_awesome %}<link rel="stylesheet" href="{{ config.root }}{{ config.font_awesome_css }}">{% endif %}
</head>
<body class="8chan vichan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
- {{ boardlist.top }}
+ <div class="bar top">
+ {{ boardlist.top }}
+ </div>
<header>
<h1>{{ settings.title }}</h1>
<div class="subtitle">{{ settings.subtitle }}</div>
</header>
-
+ <img src="static/lain_is_cute_datass_small_teal.png" alt="mascot"/>
<div class="ban">
{% if news|count == 0 %}
<p style="text-align:center" class="unimportant">(No news to show.)</p>
diff --git a/templates/themes/catalog/catalog.html b/templates/themes/catalog/catalog.html
index 0626b376..e556b4a9 100644
--- a/templates/themes/catalog/catalog.html
+++ b/templates/themes/catalog/catalog.html
@@ -8,29 +8,40 @@
, board_name = "{{ board }}";
</script>
{% include 'header.html' %}
- <title>{{ board }} - Catalog</title>
</head>
<body class="8chan vichan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %} theme-catalog active-catalog" data-stylesheet="{% if config.default_stylesheet.1 != '' %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
- {{ boardlist.top }}
+ <div class="top bar topbar">
+ {{ boardlist.top }}
+ </div>
<header>
<h1>{{ settings.title }} (<a href="{{link}}">/{{ board }}/</a>)</h1>
<div class="subtitle">{{ settings.subtitle }}</div>
</header>
- <span>{% trans 'Sort by' %}: </span>
- <select id="sort_by" style="display: inline-block">
- <option selected value="bump:desc">{% trans 'Bump order' %}</option>
- <option value="time:desc">{% trans 'Creation date' %}</option>
- <option value="reply:desc">{% trans 'Reply count' %}</option>
- <option value="random:desc">{% trans 'Random' %}</option>
- </select>
-
- <span>{% trans 'Image size' %}: </span>
- <select id="image_size" style="display: inline-block">
- <option value="vsmall">{% trans 'Very small' %}</option>
- <option selected value="small">{% trans 'Small' %}</option>
- <option value="large">{% trans 'Large' %}</option>
- </select>
+ <div class="controls">
+ <ul style="display: none">
+ <li id="sort-bump-order" class="sort" data-sort="data-bump" data-order="asc">{% trans 'Bump order' %}</li>
+ <li id="sort-creation-date" class="sort" data-sort="data-time" data-order="asc">{% trans 'Creation date' %}</li>
+ <li id="sort-reply-count" class="sort" data-sort="data-reply" data-order="asc">{% trans 'Reply count' %}</li>
+ <li id="sort-random" class="sort" data-sort="random">{% trans 'Random' %}</li>
+ </ul>
+
+ <span>{% trans 'Sort by' %}: </span>
+ <select id="sort_by" style="display: inline-block">
+ <option selected value="bump-order">{% trans 'Bump order' %}</option>
+ <option value="creation-date">{% trans 'Creation date' %}</option>
+ <option value="reply-count">{% trans 'Reply count' %}</option>
+ <option value="random">{% trans 'Random' %}</option>
+ </select>
+
+ <span>{% trans 'Image size' %}: </span>
+ <select id="image_size" style="display: inline-block">
+ <option value="vsmall">{% trans 'Very small' %}</option>
+ <option selected value="small">{% trans 'Small' %}</option>
+ <option value="large">{% trans 'Large' %}</option>
+ </select>
+ </div>
+
<div class="threads">
<div id="Grid">
{% for post in recent_posts %}
@@ -73,10 +84,10 @@
<hr/>
<footer>
- <p class="unimportant" style="margin-top:20px;text-align:center;">- Tinyboard +
- <a href="https://engine.vichan.net/">vichan</a> {{ config.version }} -
- <br>Tinyboard Copyright &copy; 2010-2014 Tinyboard Development Group
- <br><a href="https://engine.vichan.net/">vichan</a> Copyright &copy; 2012-2016 vichan-devel</p>
+ <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://engine.vichan.net/">vichan</a> Copyright &copy; 2012-2015 vichan-devel</p>
</footer>
<script type="text/javascript">{% raw %}
var styles = {
diff --git a/templates/themes/catalog/info.php b/templates/themes/catalog/info.php
index c20a0ca3..66c45082 100644
--- a/templates/themes/catalog/info.php
+++ b/templates/themes/catalog/info.php
@@ -1,27 +1,27 @@
<?php
$theme = array();
-
+
// Theme name
$theme['name'] = 'Catalog';
// Description (you can use Tinyboard markup here)
$theme['description'] = 'Show a post catalog.';
- $theme['version'] = 'v0.2';
-
- // Theme configuration
+ $theme['version'] = 'v0.2.1';
+
+ // Theme configuration
$theme['config'] = Array();
-
+
$theme['config'][] = Array(
'title' => 'Title',
'name' => 'title',
'type' => 'text',
'default' => 'Catalog'
);
-
+
$__boards = listBoards();
$__default_boards = Array();
foreach ($__boards as $__board)
$__default_boards[] = $__board['uri'];
-
+
$theme['config'][] = Array(
'title' => 'Included boards',
'name' => 'boards',
@@ -29,7 +29,7 @@
'comment' => '(space seperated)',
'default' => implode(' ', $__default_boards)
);
-
+
$theme['config'][] = Array(
'title' => 'Update on new posts',
'name' => 'update_on_posts',
@@ -38,14 +38,29 @@
'comment' => 'Without this checked, the catalog only updates on new threads.'
);
- $theme['config'][] = Array(
- 'title' => 'Use tooltipster',
- 'name' => 'use_tooltipster',
- 'type' => 'checkbox',
- 'default' => true,
- 'comment' => 'Check this if you wish to show a nice tooltip with info about the thread on mouse over.'
- );
+ $theme['config'][] = Array(
+ 'title' => 'Enable Ukko catalog',
+ 'name' => 'enable_ukko',
+ 'type' => 'checkbox',
+ 'default' => false,
+ 'comment' => 'Enable catalog for the Ukko theme. This requires the Ukko theme to be enabled.'
+ );
+ $theme['config'][] = Array(
+ 'title' => 'Enable Rand catalog',
+ 'name' => 'enable_rand',
+ 'type' => 'checkbox',
+ 'default' => false,
+ 'comment' => 'Enable catalog for the Rand theme. This requires the Rand theme to be enabled.'
+ );
+ $theme['config'][] = Array(
+ 'title' => 'Use tooltipster',
+ 'name' => 'use_tooltipster',
+ 'type' => 'checkbox',
+ 'default' => true,
+ 'comment' => 'Check this if you wish to show a nice tooltip with info about the thread on mouse over.'
+ );
// Unique function name for building everything
$theme['build_function'] = 'catalog_build';
+
diff --git a/templates/themes/catalog/theme.php b/templates/themes/catalog/theme.php
index 4f512c03..24cdcbb8 100644
--- a/templates/themes/catalog/theme.php
+++ b/templates/themes/catalog/theme.php
@@ -1,19 +1,19 @@
<?php
require 'info.php';
-
+
function catalog_build($action, $settings, $board) {
global $config;
-
+
+ $b = new Catalog($settings);
+ $boards = explode(' ', $settings['boards']);
+
// Possible values for $action:
// - all (rebuild everything, initialization)
// - news (news has been updated)
// - boards (board list changed)
// - post (a reply has been made)
// - post-thread (a thread has been made)
-
- $boards = explode(' ', $settings['boards']);
-
- if ($action == 'all') {
+ if ($action === 'all') {
foreach ($boards as $board) {
$b = new Catalog();
@@ -36,38 +36,163 @@
}
elseif ($action == 'rebuild') {
$b->build($settings, $board);
- }
+ }
+
+ }
+
+ // FIXME: Check that Ukko is actually enabled
+ if ($settings['enable_ukko'] && (
+ $action === 'all' || $action === 'post' ||
+ $action === 'post-thread' || $action === 'post-delete'))
+ {
+ $b->buildUkko();
+ }
+
+ // FIXME: Check that Rand is actually enabled
+ if ($settings['enable_rand'] && (
+ $action === 'all' || $action === 'post' ||
+ $action === 'post-thread' || $action === 'post-delete'))
+ {
+ $b->buildRand();
}
}
-
+
// Wrap functions in a class so they don't interfere with normal Tinyboard operations
class Catalog {
- public function build($settings, $board_name) {
- global $config, $board;
+ private $settings;
+ // Cache for threads from boards that have already been processed
+ private $threadsCache = array();
+
+ public function __construct($settings) {
+ $this->settings = $settings;
+ }
+
+ /**
+ * Build and save the HTML of the catalog for the Ukko theme
+ */
+ public function buildUkko() {
+ global $config;
- if ($board['uri'] != $board_name) {
- if (!openBoard($board_name)) {
- error(sprintf(_("Board %s doesn't exist"), $board_name));
+ $ukkoSettings = themeSettings('ukko');
+ $queries = array();
+ $threads = array();
+
+ $exclusions = explode(' ', $ukkoSettings['exclude']);
+ $boards = array_diff(listBoards(true), $exclusions);
+
+ foreach ($boards as $b) {
+ if (array_key_exists($b, $this->threadsCache)) {
+ $threads = array_merge($threads, $this->threadsCache[$b]);
+ } else {
+ $queries[] = $this->buildThreadsQuery($b);
+ }
+ }
+
+ // Fetch threads from boards that haven't beenp processed yet
+ if (!empty($queries)) {
+ $sql = implode(' UNION ALL ', $queries);
+ $res = query($sql) or error(db_error());
+ $threads = array_merge($threads, $res->fetchAll(PDO::FETCH_ASSOC));
+ }
+
+ // Sort in bump order
+ usort($threads, function($a, $b) {
+ return strcmp($b['bump'], $a['bump']);
+ });
+ // Generate data for the template
+ $recent_posts = $this->generateRecentPosts($threads);
+
+ $this->saveForBoard($ukkoSettings['uri'], $recent_posts,
+ $config['root'] . $ukkoSettings['uri']);
+ }
+
+ /**
+ * Build and save the HTML of the catalog for the Rand theme
+ */
+ public function buildRand() {
+ global $config;
+
+ $randSettings = themeSettings('rand');
+ $queries = array();
+ $threads = array();
+
+ $exclusions = explode(' ', $randSettings['exclude']);
+ $boards = array_diff(listBoards(true), $exclusions);
+
+ foreach ($boards as $b) {
+ if (array_key_exists($b, $this->threadsCache)) {
+ $threads = array_merge($threads, $this->threadsCache[$b]);
+ } else {
+ $queries[] = $this->buildThreadsQuery($b);
}
}
-
- $recent_images = array();
- $recent_posts = array();
- $stats = array();
-
- $query = query(sprintf("SELECT *, `id` AS `thread_id`,
- (SELECT COUNT(`id`) FROM ``posts_%s`` WHERE `thread` = `thread_id`) AS `reply_count`,
- (SELECT SUM(`num_files`) FROM ``posts_%s`` WHERE `thread` = `thread_id` AND `num_files` IS NOT NULL) AS `image_count`,
- '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL ORDER BY `bump` DESC",
- $board_name, $board_name, $board_name, $board_name, $board_name)) or error(db_error());
-
- while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
+
+ // Fetch threads from boards that haven't beenp processed yet
+ if (!empty($queries)) {
+ $sql = implode(' UNION ALL ', $queries);
+ $res = query($sql) or error(db_error());
+ $threads = array_merge($threads, $res->fetchAll(PDO::FETCH_ASSOC));
+ }
+
+ // Sort in bump order
+ usort($threads, function($a, $b) {
+ return strcmp($b['bump'], $a['bump']);
+ });
+ // Generate data for the template
+ $recent_posts = $this->generateRecentPosts($threads);
+
+ $this->saveForBoard($randSettings['uri'], $recent_posts,
+ $config['root'] . $randSettings['uri']);
+ }
+
+ /**
+ * Build and save the HTML of the catalog for the given board
+ */
+ public function build($board_name) {
+ if (!openBoard($board_name)) {
+ error(sprintf(_("Board %s doesn't exist"), $post['board']));
+ }
+
+ if (array_key_exists($board_name, $this->threadsCache)) {
+ $threads = $this->threadsCache[$board_name];
+ } else {
+ $sql = $this->buildThreadsQuery($board_name);
+ $query = query($sql . ' ORDER BY `bump` DESC') or error(db_error());
+ $threads = $query->fetchAll(PDO::FETCH_ASSOC);
+ // Save for posterity
+ $this->threadsCache[$board_name] = $threads;
+ }
+
+ // Generate data for the template
+ $recent_posts = $this->generateRecentPosts($threads);
+
+ $this->saveForBoard($board_name, $recent_posts);
+ }
+
+ private function buildThreadsQuery($board) {
+ $sql = "SELECT *, `id` AS `thread_id`, " .
+ "(SELECT COUNT(`id`) FROM ``posts_$board`` WHERE `thread` = `thread_id`) AS `reply_count`, " .
+ "(SELECT SUM(`num_files`) FROM ``posts_$board`` WHERE `thread` = `thread_id` AND `num_files` IS NOT NULL) AS `image_count`, " .
+ "'$board' AS `board` FROM ``posts_$board`` WHERE `thread` IS NULL";
+
+ return $sql;
+ }
+
+ private function generateRecentPosts($threads) {
+ global $config, $board;
+
+ $posts = array();
+ foreach ($threads as $post) {
+ if ($board['uri'] !== $post['board']) {
+ openBoard($post['board']);
+ }
+
$post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . link_for($post);
$post['board_name'] = $board['name'];
if ($post['embed'] && preg_match('/^https?:\/\/(\w+\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9\-_]{10,11})(&.+)?$/i', $post['embed'], $matches)) {
$post['youtube'] = $matches[2];
- }
+ }
if (isset($post['files']) && $post['files']) {
$files = json_decode($post['files']);
@@ -76,20 +201,19 @@
if ($files[0]->file == 'deleted') {
if (count($files) > 1) {
foreach ($files as $file) {
- if (($file == $files[0]) || ($file->file == 'deleted')) continue;
+ if (($file == $files[0]) || ($file->file == 'deleted'))
+ continue;
$post['file'] = $config['uri_thumb'] . $file->thumb;
}
- if (empty($post['file'])) $post['file'] = $config['image_deleted'];
- }
- else {
+ if (empty($post['file']))
+ $post['file'] = $config['image_deleted'];
+ } else {
$post['file'] = $config['image_deleted'];
}
- }
- else if($files[0]->thumb == 'spoiler') {
+ } else if($files[0]->thumb == 'spoiler') {
$post['file'] = '/' . $config['spoiler_image'];
- }
- else {
+ } else {
$post['file'] = $config['uri_thumb'] . $files[0]->thumb;
}
}
@@ -97,27 +221,41 @@
$post['file'] = $config['root'] . $config['image_deleted'];
}
- if (empty($post['image_count'])) $post['image_count'] = 0;
+ if (empty($post['image_count']))
+ $post['image_count'] = 0;
$post['pubdate'] = date('r', $post['time']);
- $recent_posts[] = $post;
+
+ $posts[] = $post;
}
-
- $required_scripts = array('js/jquery.min.js', 'js/jquery.mixitup.min.js', 'js/catalog.js');
+ return $posts;
+ }
+
+ private function saveForBoard($board_name, $recent_posts, $board_link = null) {
+ global $board, $config;
+
+ if ($board_link === null) {
+ $board_link = $config['root'] . $board['dir'];
+ }
+
+ $required_scripts = array('js/jquery.min.js', 'js/jquery.mixitup.min.js',
+ 'js/catalog.js');
+
+ // Include scripts that haven't been yet included
foreach($required_scripts as $i => $s) {
if (!in_array($s, $config['additional_javascript']))
$config['additional_javascript'][] = $s;
}
file_write($config['dir']['home'] . $board_name . '/catalog.html', Element('themes/catalog/catalog.html', Array(
- 'settings' => $settings,
+ 'settings' => $this->settings,
'config' => $config,
'boardlist' => createBoardlist(),
- 'recent_images' => $recent_images,
+ 'recent_images' => array(),
'recent_posts' => $recent_posts,
- 'stats' => $stats,
+ 'stats' => array(),
'board' => $board_name,
- 'link' => $config['root'] . $board['dir']
+ 'link' => $board_link
)));
file_write($config['dir']['home'] . $board_name . '/index.rss', Element('themes/catalog/index.rss', Array(
@@ -126,4 +264,4 @@
'board' => $board
)));
}
- };
+ }
diff --git a/templates/themes/categories-uboachan/info.php b/templates/themes/categories-uboachan/info.php
new file mode 100644
index 00000000..3ef9871f
--- /dev/null
+++ b/templates/themes/categories-uboachan/info.php
@@ -0,0 +1,42 @@
+<?php
+ $theme = Array();
+
+ // Theme name
+ $theme['name'] = 'Categories-Uboachan';
+ // Description (you can use Tinyboard markup here)
+ $theme['description'] =
+'Uboachan modification of the Categories theme.
+
+Requires $config[\'boards\'] and $config[\'categories\'].';
+ $theme['version'] = 'v0.2.1';
+
+ // Theme configuration
+ $theme['config'] = Array();
+
+ $theme['config'][] = Array(
+ 'title' => 'Title',
+ 'name' => 'title',
+ 'type' => 'text'
+ );
+
+ $theme['config'][] = Array(
+ 'title' => 'Slogan',
+ 'name' => 'subtitle',
+ 'type' => 'text'
+ );
+
+ // Unique function name for building everything
+ $theme['build_function'] = 'categories_build';
+
+ $theme['install_callback'] = 'categories_install';
+ if(!function_exists('categories_install')) {
+ function categories_install($settings) {
+ global $config;
+
+ if(!isset($config['boards']) || !isset($config['categories'])) {
+ return Array(false, '<h2>Prerequisites not met!</h2>' .
+ 'This theme requires $config[\'boards\'] and $config[\'categories\'] to be set.');
+ }
+ }
+ }
+?>
diff --git a/templates/themes/categories-uboachan/theme.php b/templates/themes/categories-uboachan/theme.php
new file mode 100644
index 00000000..296e0d06
--- /dev/null
+++ b/templates/themes/categories-uboachan/theme.php
@@ -0,0 +1,223 @@
+<?php
+ require 'info.php';
+
+ function categories_build($action, $settings) {
+ // Possible values for $action:
+ // - all (rebuild everything, initialization)
+ // - news (news has been updated)
+ // - boards (board list changed)
+
+ Categories::build($action, $settings);
+ }
+
+ // Wrap functions in a class so they don't interfere with normal Tinyboard operations
+ class Categories {
+ public static function build($action, $settings) {
+ global $config;
+
+ if($action == 'all')
+ file_write($config['dir']['home'] . $config['file_index'], Categories::homepage($settings));
+
+ if($action == 'all' || $action == 'boards')
+ file_write($config['dir']['home'] . 'sidebar.html', Categories::sidebar($settings));
+
+ if($action == 'all' || $action == 'news' || $action == 'post')
+ file_write($config['dir']['home'] . 'news.html', Categories::news($settings));
+ }
+
+ // Build homepage
+ public static function homepage($settings) {
+ global $config;
+
+ // HTML5
+ return '<!DOCTYPE html><html>'
+ . '<head>'
+ . '<meta charset="utf-8">'
+ . '<link rel="stylesheet" media="screen" href="' . $config['url_stylesheet'] . '"/>'
+ . '<style type="text/css">'
+ . 'iframe{border:none;margin:0;padding:0;height:100%;position:absolute}'
+ . 'iframe#sidebar{left:0;top:0;width:15%}'
+ . 'iframe#main{left:15%;top:0;width:85%}'
+ . '</style>'
+ . '<title>' . $settings['title'] . '</title>'
+ . '<script type="text/javascript">'
+ . 'function removeFrames() {'
+ . 'window.location = document.getElementById("main").contentWindow.location.href;'
+ . '}'
+ . 'function globalChangeStyle(x)'
+ . '{'
+ . 'document.getElementById("main").contentWindow.changeStyle(x);'
+ . 'document.getElementById("sidebar").contentWindow.changeStyle(x);'
+ . '}'
+ . 'function goNews() {'
+ . 'window.location = \'/\';'
+ . '}'
+ . 'window.f = true;'
+ . '</script>'
+ . '<meta name="description" content="A fansite and imageboard revolving around the cult classic PC game Yume Nikki." />'
+ . '<meta name="keywords" content="yume nikki, imageboard, boards, forums, uboa, madotsuki, poniko, seccom masada, monoko, monoe, images, discussion, video games" />'
+ . '</head><body>'
+ // Sidebar
+ . '<iframe src="sidebar.html" id="sidebar" name="sidebar"></iframe>'
+ // Main
+ . '<iframe src="news.html" id="main" name="main"></iframe>'
+ // Finish page
+ . '</body></html>';
+ }
+
+ // Build news page
+ public static function news($settings) {
+ global $config, $board;
+
+ // HTML5
+ $body = '<!DOCTYPE html><html>'
+ . '<head>'
+ . '<meta charset="utf-8">'
+ . '<link rel="stylesheet" href="frontpage.css" />'
+ . '<link rel="stylesheet" media="screen" id="stylesheet" href="/stylesheets/style.css">'
+ . '<script type="text/javascript" src="/styleswitch-sidebar.js"></script>'
+ . '<title>' . $settings['title'] . ' - News</title>'
+ . '</head><body>';
+
+ $boardlist = createBoardlist();
+
+ $body .= $boardlist['top']
+ . '<br />';
+
+ $boards = listBoards();
+
+ $body .= '<div id="maintable"><div id="logo"></div><div id="announcement">Don\'t touch the lights!</div><table style="margin-bottom: 4px; width: 100%;"><tr>';
+ // Recent Posts
+
+ $body .= '<td style="width: 100%;"><div class="post_wrap"><div class="post_header"><b>Recent Posts</b></div><div class="post_body"><div class="post_content" style="padding-bottom: 10px;">';
+
+ $query = '';
+ foreach($boards as &$_board) {
+ // Block Board
+ if ($_board['uri'] != "aurora") {
+ $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` UNION ALL ", $_board['uri'], $_board['uri']);
+ }
+ }
+ $query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT 15', $query);
+ $query = query($query) or error(db_error());
+
+ while($post = $query->fetch()) {
+ openBoard($post['board']);
+
+ $body .= '<strong>' . $board['name'] . '</strong>: <a href="' .
+ $config['root'] . $board['dir'] . $config['dir']['res'] . ($post['thread']?$post['thread']:$post['id']) . '.html#' . $post['id'] .
+ '">';
+ $snip = pm_snippet($post['body'], 95);
+ if($snip === "<em></em>")
+ {
+ $body .= '&lt;empty&gt;';
+ }
+ else
+ {
+ $body .= $snip;
+ }
+ $body .= '</a><br />';
+ }
+
+ // News
+
+ $body .= '</div></div></div></td></tr></table>';
+
+ $query = query("SELECT * FROM `news` ORDER BY `time` DESC LIMIT 5") or error(db_error());
+ if($query->rowCount() == 0) {
+ $body .= '<p style="text-align:center" class="unimportant">(No news to show.)</p>';
+ } else {
+ // List news
+ while($news = $query->fetch()) {
+ $body .= '<div class="post_wrap"><div class="post_header">' .
+ // Newer than 5 days?
+ (time() - $news['time'] <= 432000 ?
+ '<em><b><span style="color: #D03030;">*NEW*</span></b></em> '
+ :
+ ''
+ ) .
+ ($news['subject'] ?
+ $news['subject']
+ :
+ '<em>no subject</em>'
+ ) .
+ ' &mdash; by ' .
+ $news['name'] .
+ ' at ' .
+ strftime($config['post_date'], $news['time']) .
+ '</div><div class="post_body"><div class="post_content">' .
+ $news['body'] .
+ '</div></div></div>';
+ }
+ }
+
+ // Finish page
+ $body .= '<br />';
+ $body .= '</div></body></html>';
+
+ return $body;
+ }
+
+ // Build sidebar
+ public static function sidebar($settings) {
+ global $config, $board;
+
+ $body = '<!DOCTYPE html><html>'
+ . '<head>'
+ . '<meta charset="utf-8">'
+ . '<link rel="stylesheet" media="screen" href="' . $config['url_stylesheet'] . '"/>'
+ . '<style type="text/css">'
+ . 'fieldset{margin:10px 0}'
+ . 'legend{width:100%;margin-left:-15px;border:1px solid white;color:white;font-weight:bold;padding:5px 5px}'
+ . 'ul{margin:0;padding:0}'
+ . 'li{list-style:none;padding:0 4px;margin: 0 4px}'
+ . 'li a.system{font-weight:bold}'
+ . '</style>'
+ . '<link rel="stylesheet" type="text/css" id="stylesheet" href="/stylesheets/uboachan.css">'
+ . '<script type="text/javascript" src="/styleswitch-sidebar.js"></script>'
+ . '<base target="main" />'
+ . '<title>' . $settings['title'] . '</title>'
+ . '</head><body>';
+
+ $body .= '<fieldset><legend class="category">' . $settings['title'] . '</legend><ul>' .
+ '<li><a class="system" href="news.html">[News]</a></li>' .
+ '<li><a class="system" href="rules.php">[Rules]</a></li>' .
+ '<li><a class="system" href="faq.php">[FAQ]</a></li>' .
+ '<li><a class="system" href="search.php">[Search]</a></li>' .
+ '<li><a class="system" href="http://archive.uboachan.net/">[Archive]</a></li>' .
+ '<li><a class="system" href="http://archive.uboachan.net/media/src/Yume_Nikki.rar">[Download v0.10]</a></li>' .
+ '<li><a class="system" href="javascript:parent.removeFrames()">[Remove Frames]</a></li>' .
+ '<li><a href="javascript:changeStyleForAll(\'YB\');">[YB]</a> <a href="javascript:changeStyleForAll(\'Y\');">[Y]</a> <a href="javascript:changeStyleForAll(\'U\');">[U]</a> <a href="javascript:changeStyleForAll(\'UG\');">[UG]</a> <a href="javascript:changeStyleForAll(\'RZ\');">[RZ]</a></li>'.
+ '</ul></fieldset>';
+
+ for($cat = 0; $cat < count($config['categories']); $cat++) {
+ $body .= '<fieldset><legend class="category">' . $config['categories'][$cat] . '</legend><ul>';
+
+ foreach($config['boards'][$cat] as &$board) {
+ $body .= '<li><a href="' .
+ sprintf($config['board_path'], $board) .
+ '">' . boardTitle($board) . '</a></li>';
+ }
+
+ $body .= '</ul></fieldset>';
+ }
+
+ foreach($config['custom_categories'] as $name => &$group) {
+ $body .= '<fieldset><legend class="category">' . $name . '</legend><ul>';
+
+ foreach($group as $title => &$url) {
+ $body .= '<li><a href="' . $url .
+ '">' . $title . '</a></li>';
+ }
+
+ $body .= '</ul></fieldset>';
+ }
+
+ // Finish page
+ $body .= '</body></html>';
+
+ return $body;
+ }
+ };
+
+?>
diff --git a/templates/themes/categories-uboachan/thumb.png b/templates/themes/categories-uboachan/thumb.png
new file mode 100644
index 00000000..35d747e2
--- /dev/null
+++ b/templates/themes/categories-uboachan/thumb.png
Binary files differ
diff --git a/templates/themes/donate/donate.html b/templates/themes/donate/donate.html
new file mode 100644
index 00000000..551eea62
--- /dev/null
+++ b/templates/themes/donate/donate.html
@@ -0,0 +1,208 @@
+{% filter remove_whitespace %}
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <title>{{ settings.title }}</title>
+ <link rel="shortcut icon" href="/favicon.png">
+ <link rel="stylesheet" media="screen" href="/stylesheets/style.css"/>
+ <link rel="stylesheet" media="screen" href="/stylesheets/dark.css"/>
+ {% if config.font_awesome %}<link rel="stylesheet" href="{{ config.root }}{{ config.font_awesome_css }}">{% endif %}
+<style>
+ /*---------------------------*/
+ .container {
+ margin: auto;
+ width : 50%;
+ }
+ .progress-bar {
+ background-color: #1a1a1a;
+ height: 25px;
+ padding: 5px;
+ width: 350px;
+ position: relative;
+ margin: 70px 0 20px 0;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ -moz-box-shadow: 0 1px 5px #000 inset, 0 1px 0 #444;
+ -webkit-box-shadow: 0 1px 5px #000 inset, 0 1px 0 #444;
+ box-shadow: 0 1px 5px #000 inset, 0 1px 0 #444;
+ }
+
+ .progress-bar span {
+ display: inline-block;
+ height: 100%;
+ background-color: #777;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+ -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, .5) inset;
+ -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, .5) inset;
+ box-shadow: 0 1px 0 rgba(255, 255, 255, .5) inset;
+ -webkit-transition: width .4s ease-in-out;
+ -moz-transition: width .4s ease-in-out;
+ -ms-transition: width .4s ease-in-out;
+ -o-transition: width .4s ease-in-out;
+ transition: width .4s ease-in-out;
+ }
+
+
+ .blue span {
+ background-color: #34c2e3;
+ }
+
+ .red span {
+ background-color: #f42323;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f42323), to(#ff0000));
+ background-image: -webkit-linear-gradient(top, #f42323, #ff0000);
+ background-image: -moz-linear-gradient(top, #f42323, #ff0000);
+ background-image: -ms-linear-gradient(top, #f42323, #ff0000);
+ background-image: -o-linear-gradient(top, #f42323, #ff0000);
+ background-image: linear-gradient(top, #f42323, #ff0000);
+ }
+
+ .green span {
+ background-color: #a5df41;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#a5df41), to(#4ca916));
+ background-image: -webkit-linear-gradient(top, #a5df41, #4ca916);
+ background-image: -moz-linear-gradient(top, #a5df41, #4ca916);
+ background-image: -ms-linear-gradient(top, #a5df41, #4ca916);
+ background-image: -o-linear-gradient(top, #a5df41, #4ca916);
+ background-image: linear-gradient(top, #a5df41, #4ca916);
+ }
+
+ /*---------------------------*/
+
+ .stripes span {
+ -webkit-background-size: 30px 30px;
+ -moz-background-size: 30px 30px;
+ background-size: 30px 30px;
+ background-image: -webkit-gradient(linear, left top, right bottom,
+ color-stop(.25, rgba(255, 255, 255, .15)), color-stop(.25, transparent),
+ color-stop(.5, transparent), color-stop(.5, rgba(255, 255, 255, .15)),
+ color-stop(.75, rgba(255, 255, 255, .15)), color-stop(.75, transparent),
+ to(transparent));
+ background-image: -webkit-linear-gradient(135deg, rgba(255, 255, 255, .15) 25%, transparent 25%,
+ transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%,
+ transparent 75%, transparent);
+ background-image: -moz-linear-gradient(135deg, rgba(255, 255, 255, .15) 25%, transparent 25%,
+ transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%,
+ transparent 75%, transparent);
+ background-image: -ms-linear-gradient(135deg, rgba(255, 255, 255, .15) 25%, transparent 25%,
+ transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%,
+ transparent 75%, transparent);
+ background-image: -o-linear-gradient(135deg, rgba(255, 255, 255, .15) 25%, transparent 25%,
+ transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%,
+ transparent 75%, transparent);
+ background-image: linear-gradient(135deg, rgba(255, 255, 255, .15) 25%, transparent 25%,
+ transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%,
+ transparent 75%, transparent);
+
+ -webkit-animation: animate-stripes 3s linear infinite;
+ -moz-animation: animate-stripes 3s linear infinite;
+ }
+
+ @-webkit-keyframes animate-stripes {
+ 0% {background-position: 0 0;} 100% {background-position: 60px 0;}
+ }
+
+
+ @-moz-keyframes animate-stripes {
+ 0% {background-position: 0 0;} 100% {background-position: 60px 0;}
+ }
+
+ /*---------------------------*/
+
+ .shine span {
+ position: relative;
+ }
+
+ .shine span::after {
+ content: '';
+ opacity: 0;
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background: #fff;
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+
+ -webkit-animation: animate-shine 2s ease-out infinite;
+ -moz-animation: animate-shine 2s ease-out infinite;
+ }
+
+ @-webkit-keyframes animate-shine {
+ 0% {opacity: 0; width: 0;}
+ 50% {opacity: .5;}
+ 100% {opacity: 0; width: 95%;}
+ }
+
+
+ @-moz-keyframes animate-shine {
+ 0% {opacity: 0; width: 0;}
+ 50% {opacity: .5;}
+ 100% {opacity: 0; width: 95%;}
+ }
+ .glow span {
+ -moz-box-shadow: 0 5px 5px rgba(255, 255, 255, .7) inset, 0 -5px 5px rgba(255, 255, 255, .7) inset;
+ -webkit-box-shadow: 0 5px 5px rgba(255, 255, 255, .7) inset, 0 -5px 5px rgba(255, 255, 255, .7) inset;
+ box-shadow: 0 5px 5px rgba(255, 255, 255, .7) inset, 0 -5px 5px rgba(255, 255, 255, .7) inset;
+
+ -webkit-animation: animate-glow 1s ease-out infinite;
+ -moz-animation: animate-glow 1s ease-out infinite;
+ }
+
+ @-webkit-keyframes animate-glow {
+ 0% { -webkit-box-shadow: 0 5px 5px rgba(255, 255, 255, .7) inset, 0 -5px 5px rgba(255, 255, 255, .7) inset;}
+ 50% { -webkit-box-shadow: 0 5px 5px rgba(255, 255, 255, .3) inset, 0 -5px 5px rgba(255, 255, 255, .3) inset;}
+ 100% { -webkit-box-shadow: 0 5px 5px rgba(255, 255, 255, .7) inset, 0 -5px 5px rgba(255, 255, 255, .7) inset;}
+ }
+
+ @-moz-keyframes animate-glow {
+ 0% { -moz-box-shadow: 0 5px 5px rgba(255, 255, 255, .7) inset, 0 -5px 5px rgba(255, 255, 255, .7) inset;}
+ 50% { -moz-box-shadow: 0 5px 5px rgba(255, 255, 255, .3) inset, 0 -5px 5px rgba(255, 255, 255, .3) inset;}
+ 100% { -moz-box-shadow: 0 5px 5px rgba(255, 255, 255, .7) inset, 0 -5px 5px rgba(255, 255, 255, .7) inset;}
+ }
+
+ </style>
+ </head>
+ <body>
+ <div class="bar top">{{ boardlist.top }}</div>
+
+ <header>
+ <h1>{{ settings.title }}</h1>
+ <div class="subtitle">{{ settings.subtitle }}</div>
+ </header>
+<center>
+ <img alt="mascot" src="/static/lain_is_cute_datass_small.png"/>
+</center>
+ <div class="ban">
+ <h2>Thanks for donating</h2>
+ <p>The server costs $55 per month. If you buy stickers we get about 45-55% of whatever you spend. Historical donation records to the former owner are ForeverN2Dust is the top donator, giving about $3000. FOOFDOOF is #2 with $1000 and lots of cheap Chinese shit. Please specify what you'd like your money to go towards. If you don't want to buy stickers, but want to donate something else please either ask in /q/ or contact the Lainchan administration on IRC at #lainchan on Freenode.
+ </p>
+
+ <p><a href="https://www.stickermule.com/marketplace/tags/lainchan"> Buy stickers here</a>
+</p>
+
+<p>Monthly Funding Progress Bar</p>
+
+<p>Cost per month $55</p>
+
+<p>Funds from stickers $37.75</p>
+
+<div class="container">
+<div class="progress-bar red glow">
+ <span style="width:14%;position:relative;left:36%;
+ "> </span>
+</div>
+<div id="value" style="position:relative;left:135px;top:-45px">$-19.25</div>
+</div>
+
+ </div>
+
+ </body>
+</html>
+{% endfilter %}
diff --git a/templates/themes/donate/info.php b/templates/themes/donate/info.php
new file mode 100644
index 00000000..fa3f649b
--- /dev/null
+++ b/templates/themes/donate/info.php
@@ -0,0 +1,23 @@
+<?php
+$theme = array(
+ 'name' => 'Donate',
+ 'description' => 'le wales face',
+ 'version' => 'v9001',
+
+ 'config' => array(
+ array('title' => 'Page title',
+ 'name' => 'title',
+ 'type' => 'text'),
+
+ array('title' => 'Slogan',
+ 'name' => 'subtitle',
+ 'type' => 'text',
+ 'comment' => '(optional)'),
+
+ array('title' => 'File',
+ 'name' => 'file',
+ 'type' => 'text',
+ 'default' => 'donate.html')),
+
+ 'build_function' => 'donate_build');
+?>
diff --git a/templates/themes/donate/theme.php b/templates/themes/donate/theme.php
new file mode 100644
index 00000000..736519a8
--- /dev/null
+++ b/templates/themes/donate/theme.php
@@ -0,0 +1,28 @@
+<?php
+
+require 'info.php';
+
+function donate_build($action, $settings, $board) {
+ donate::build($action, $settings);
+}
+
+class donate {
+ public static function build($action, $settings) {
+ global $config;
+
+ if ($action == 'all') {
+ file_write($config['dir']['home'] . $settings['file'], donate::install($settings));
+ }
+ }
+
+ public static function install($settings) {
+ global $config;
+
+ return Element('themes/donate/donate.html',
+ array('settings' => $settings,
+ 'config' => $config,
+ 'boardlist' => createBoardlist()));
+ }
+}
+
+?>
diff --git a/templates/themes/donate/thumb.png b/templates/themes/donate/thumb.png
new file mode 100644
index 00000000..f3f88e27
--- /dev/null
+++ b/templates/themes/donate/thumb.png
Binary files differ
diff --git a/templates/themes/irc/info.php b/templates/themes/irc/info.php
new file mode 100644
index 00000000..8b31b011
--- /dev/null
+++ b/templates/themes/irc/info.php
@@ -0,0 +1,23 @@
+<?php
+$theme = array(
+ 'name' => 'IRC',
+ 'description' => 'Display a link to the lainchan irc',
+ 'version' => 'v1',
+
+ 'config' => array(
+ array('title' => 'Page title',
+ 'name' => 'title',
+ 'type' => 'text'),
+
+ array('title' => 'Slogan',
+ 'name' => 'subtitle',
+ 'type' => 'text',
+ 'comment' => '(optional)'),
+
+ array('title' => 'File',
+ 'name' => 'file',
+ 'type' => 'text',
+ 'default' => 'irc.html')),
+
+ 'build_function' => 'irc_build');
+?>
diff --git a/templates/themes/irc/irc.html b/templates/themes/irc/irc.html
new file mode 100644
index 00000000..2828b6e0
--- /dev/null
+++ b/templates/themes/irc/irc.html
@@ -0,0 +1,30 @@
+{% filter remove_whitespace %}
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <title>{{ settings.title }}</title>
+ <link rel="shortcut icon" href="/favicon.png">
+ <link rel="stylesheet" media="screen" href="/stylesheets/style.css"/>
+ <link rel="stylesheet" media="screen" href="/stylesheets/dark.css"/>
+ <link rel="stylesheet" media="screen" href="/stylesheets/dark_irc.css"/>
+ <link rel="stylesheet" href="/stylesheets/font-awesome/css/font-awesome.min.css">
+</head>
+ <body>
+ <div class="bar top">
+ {{ boardlist.top }}
+ </div>
+
+ <header>
+ <h1>{{ settings.title }}</h1>
+ <div class="subtitle">{{ settings.subtitle }}</div>
+ </header>
+
+
+ <div class="ban" style="text-align: left!important;">
+ <h2>Web Client - Point your own clients to #lainchan on irc.freenode.net.</h2>
+ <iframe src="https://webchat.freenode.net?channels=%23lainchan&uio=MTE9MTMz98" width="766" height="400"></iframe>
+ </div>
+ </body>
+</html>
+{% endfilter %}
diff --git a/templates/themes/irc/radio.html b/templates/themes/irc/radio.html
new file mode 100644
index 00000000..7f84134b
--- /dev/null
+++ b/templates/themes/irc/radio.html
@@ -0,0 +1,29 @@
+{% filter remove_whitespace %}
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <title>{{ settings.title }}</title>
+ <link rel="shortcut icon" href="/favicon.png">
+ <link rel="stylesheet" media="screen" href="/stylesheets/style.css"/>
+ <link rel="stylesheet" media="screen" href="/stylesheets/dark.css"/>
+ <link rel="stylesheet" media="screen" href="/stylesheets/dark_irc.css"/>
+ </head>
+ <body>
+ <div class="bar top">
+ {{ boardlist.top }}
+ </div>
+
+ <header>
+ <h1>{{ settings.title }}</h1>
+ <div class="subtitle">{{ settings.subtitle }}</div>
+ </header>
+
+
+ <div class="ban" style="text-align: left!important;">
+ <h2>Web Client - Point your own clients to #lainchan on irc.freenode.net.</h2>
+ <iframe src="https://webchat.freenode.net?channels=%23lainchan&uio=MTE9MTMz98" width="766" height="400"></iframe>
+ </div>
+ </body>
+</html>
+{% endfilter %}
diff --git a/templates/themes/irc/theme.php b/templates/themes/irc/theme.php
new file mode 100644
index 00000000..c9b45c33
--- /dev/null
+++ b/templates/themes/irc/theme.php
@@ -0,0 +1,27 @@
+<?php
+require 'info.php';
+
+function irc_build($action, $settings, $board) {
+ irc::build($action, $settings);
+}
+
+class irc {
+ public static function build($action, $settings) {
+ global $config;
+
+ if ($action == 'all') {
+ file_write($config['dir']['home'] . $settings['file'], irc::install($settings));
+ }
+ }
+
+ public static function install($settings) {
+ global $config;
+
+ return Element('themes/irc/irc.html',
+ array('settings' => $settings,
+ 'config' => $config,
+ 'boardlist' => createBoardlist()));
+ }
+}
+
+?>
diff --git a/templates/themes/irc/thumb.png b/templates/themes/irc/thumb.png
new file mode 100644
index 00000000..0988ca68
--- /dev/null
+++ b/templates/themes/irc/thumb.png
Binary files differ
diff --git a/templates/themes/public_banlist/theme.php b/templates/themes/public_banlist/theme.php
index f2b65839..62a794dd 100644
--- a/templates/themes/public_banlist/theme.php
+++ b/templates/themes/public_banlist/theme.php
@@ -25,7 +25,7 @@
public static function gen_json($settings) {
ob_start();
- Bans::stream_json(false, true, true, array());
+ Bans::stream_json(false, true, true, array(), array("/\bcp\b/i", "/porn/i"));
$out = ob_get_contents();
ob_end_clean();
return $out;
diff --git a/templates/themes/radio/info.php b/templates/themes/radio/info.php
new file mode 100644
index 00000000..d6679733
--- /dev/null
+++ b/templates/themes/radio/info.php
@@ -0,0 +1,23 @@
+<?php
+$theme = array(
+ 'name' => 'Radio',
+ 'description' => 'Display a link to the lainchan radio',
+ 'version' => 'v1',
+
+ 'config' => array(
+ array('title' => 'Page title',
+ 'name' => 'title',
+ 'type' => 'text'),
+
+ array('title' => 'Slogan',
+ 'name' => 'subtitle',
+ 'type' => 'text',
+ 'comment' => '(optional)'),
+
+ array('title' => 'File',
+ 'name' => 'file',
+ 'type' => 'text',
+ 'default' => 'radio.html')),
+
+ 'build_function' => 'radio_build');
+?> \ No newline at end of file
diff --git a/templates/themes/radio/radio.html b/templates/themes/radio/radio.html
new file mode 100644
index 00000000..b19d703a
--- /dev/null
+++ b/templates/themes/radio/radio.html
@@ -0,0 +1,76 @@
+{% filter remove_whitespace %}
+<!DOCTYPE html>
+<html style="height:100vh; width:100%;">
+ <head>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <title>{{ settings.title }}</title>
+ <link rel="shortcut icon" href="/favicon.png">
+ <link rel="stylesheet" media="screen" href="/stylesheets/style.css"/>
+ <link rel="stylesheet" media="screen" href="/stylesheets/cyberpunk.css"/>
+ <link rel="stylesheet" href="/stylesheets/font-awesome/css/font-awesome.min.css">
+<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
+<script type="text/javascript">
+$(document).ready(function(){
+ check_status();
+ setInterval(check_status, 15000);
+});
+
+function check_status(){
+$.get("/radio_assets/status.xsl", function(data){
+var el = $( '<div></div>' );
+el.html(data);
+var sd = el.find(".streamdata");
+
+$(".nowplaying").text("Now playing: " + sd[16].textContent);
+
+$(".currentlisteners").text("Current listeners: " + sd[13].textContent); });
+}
+</script>
+ </head>
+ <body style=" background: url(/bg.php) no-repeat center center fixed;
+ -webkit-background-size: cover;
+ -moz-background-size: cover;
+ -o-background-size: cover;
+ background-size: cover;
+ ">
+ <div class="bar top">
+ {{ boardlist.top }}
+ </div>
+
+ {% if config.url_banner %}<img class="board_image" src="{{ config.url_banner }}" {% if config.banner_width or config.banner_height %}style="{% if config.banner_width %}width:{{ config.banner_width }}px{% endif %};{% if config.banner_width %}height:{{ config.banner_height }}px{% endif %}" {% endif %}alt="" />{% endif %}
+ <header>
+ <h1>{{ settings.title }}</h1>
+ <div class="subtitle">{{ settings.subtitle }}</div>
+ </header>
+
+ <img alt="mascot" src="static/lain_is_cute_datass_small.png" style="display: block; margin: 0 auto;"/>
+
+ <div class="ban" style="margin-top: 0px!important; background-color: black; text-align: left!important;">
+ <h2>WELCOME TO CYBERIA</h2>
+
+ <p>Welcome to lainchan's radio stream.
+ </p>
+ <noscript><p>Radio statistics will be not be updated without JavaScript, please visit https://lainchan.org/radio_assets/status.xsl to see them directly.</p></noscript>
+
+ <p class="nowplaying"> Now playing:
+ </p>
+ <p class="currentlisteners"> Current listeners:
+ </p>
+
+ <ul>
+
+ <li><a href="https://lainchan.org/static/lain.ogg.m3u">Vorbis M3U Playlist</a></li>
+ <li><a href="https://lainchan.org/static/lain.mp3.m3u">MP3 M3U Playlist</a></li>
+
+ XSPF considered harmful.
+ </ul>
+
+ <audio controls preload="none" style="margin: 0 5% 20px 5%; width: 90%; box-shadow: 0px 0px 5px black;">
+ <source src="https://lainchan.org/radio_assets/lain.ogg" type="audio/ogg">
+ <source src="https://lainchan.org/radio_assets/lain" type="audio/mpeg">
+ <em>Your browser lacks support for OGG Vorbis files. Please open the M3U file or XSPF file in a multimedia player.</em>
+ </audio>
+ </div>
+ </body>
+</html>
+{% endfilter %}
diff --git a/templates/themes/radio/theme.php b/templates/themes/radio/theme.php
new file mode 100644
index 00000000..e1244e6f
--- /dev/null
+++ b/templates/themes/radio/theme.php
@@ -0,0 +1,27 @@
+<?php
+require 'info.php';
+
+function radio_build($action, $settings, $board) {
+ radio::build($action, $settings);
+}
+
+class radio {
+ public static function build($action, $settings) {
+ global $config;
+
+ if ($action == 'all') {
+ file_write($config['dir']['home'] . $settings['file'], radio::install($settings));
+ }
+ }
+
+ public static function install($settings) {
+ global $config;
+
+ return Element('themes/radio/radio.html',
+ array('settings' => $settings,
+ 'config' => $config,
+ 'boardlist' => createBoardlist()));
+ }
+}
+
+?>
diff --git a/templates/themes/radio/thumb.png b/templates/themes/radio/thumb.png
new file mode 100644
index 00000000..0988ca68
--- /dev/null
+++ b/templates/themes/radio/thumb.png
Binary files differ
diff --git a/templates/themes/rand/info.php b/templates/themes/rand/info.php
new file mode 100644
index 00000000..c226e2e4
--- /dev/null
+++ b/templates/themes/rand/info.php
@@ -0,0 +1,54 @@
+<?php
+ $theme = array();
+
+ // Theme name
+ $theme['name'] = 'Random Overboard';
+ // Description (you can use Tinyboard markup here)
+ $theme['description'] = 'Board with threads and messages from all boards, sorted randomly';
+ $theme['version'] = 'v0.2';
+
+ // Theme configuration
+ $theme['config'] = array();
+
+ $theme['config'][] = array(
+ 'title' => 'Board name',
+ 'name' => 'title',
+ 'type' => 'text',
+ 'default' => 'Random'
+ );
+ $theme['config'][] = array(
+ 'title' => 'Board URI',
+ 'name' => 'uri',
+ 'type' => 'text',
+ 'default' => '.',
+ 'comment' => '(rand for example)'
+ );
+ $theme['config'][] = array(
+ 'title' => 'Subtitle',
+ 'name' => 'subtitle',
+ 'type' => 'text',
+ 'comment' => '(%s = thread limit. for example "%s freshly bumped threads")'
+ );
+ $theme['config'][] = array(
+ 'title' => 'Excluded boards',
+ 'name' => 'exclude',
+ 'type' => 'text',
+ 'comment' => '(space seperated)'
+ );
+ $theme['config'][] = array(
+ 'title' => 'Number of threads',
+ 'name' => 'thread_limit',
+ 'type' => 'text',
+ 'default' => '15',
+ );
+ // Unique function name for building everything
+ $theme['build_function'] = 'rand_build';
+ $theme['install_callback'] = 'rand_install';
+
+ if(!function_exists('rand_install')) {
+ function rand_install($settings) {
+ if (!file_exists($settings['uri']))
+ @mkdir($settings['uri'], 0777) or error("Couldn't create " . $settings['uri'] . ". Check permissions.", true);
+ }
+ }
+
diff --git a/templates/themes/rand/rand.js b/templates/themes/rand/rand.js
new file mode 100644
index 00000000..b2668e0b
--- /dev/null
+++ b/templates/themes/rand/rand.js
@@ -0,0 +1,116 @@
+(function(){
+
+var cache = new Array(),
+ thread = false,
+ loading = false,
+ ukkotimer = false;
+
+if (localStorage.hiddenboards === undefined) {
+ localStorage.hiddenboards = "{}";
+}
+
+// Load data from HTML5 localStorage
+var hiddenboards = JSON.parse(localStorage.hiddenboards);
+
+var storeboards = function() {
+ localStorage.hiddenboards = JSON.stringify(hiddenboards);
+};
+
+$(document).ready(function() {
+ var addukkohide = function() {
+ var ukkohide = $('<a href="javascript:void(0);" class="unimportant ukkohide"></a>');
+ var board = $(this).next().data("board");
+ var hr = $("<hr />");
+
+ $(this).append(ukkohide);
+ $(this).append(hr);
+
+ if (hiddenboards[board] !== true) {
+ ukkohide.html(_("(hide threads from this board)"));
+ hr.hide();
+ }
+ else {
+ ukkohide.html(_("(show threads from this board)"));
+ $(this).next().hide();
+ }
+ ukkohide.click(function() {
+ hiddenboards[board] = (hiddenboards[board] !== true);
+ if (hiddenboards[board] !== true) {
+ $('[data-board="'+board+'"]:not([data-cached="yes"])').show().prev().
+ find('.ukkohide').html(_("(hide threads from this board)")).
+ parent().find('hr').hide();
+ }
+ else {
+ $('[data-board="'+board+'"]:not([data-cached="yes"])').hide().prev().
+ find('.ukkohide').html(_("(show threads from this board)"))
+ .parent().find('hr').show();
+ }
+ storeboards();
+ return false;
+ });
+
+ };
+ $("h2").each(addukkohide);
+
+ $('.pages').hide();
+ var loadnext = function() {
+ if (overflow.length == 0) {
+ $('.pages').show().html(_("No more threads to display"));
+ }
+ while($(window).scrollTop() + $(window).height() + 1000 > $(document).height() && !loading && overflow.length > 0) {
+ var page = modRoot + overflow[0].board + '/' + overflow[0].page;
+ thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]');
+ if (thread.length > 0 && thread.attr("data-cached") !== 'yes') { // already present
+ overflow.shift();
+ continue;
+ }
+
+ var boardheader = $('<h2><a href="/' + overflow[0].board + '/">/' + overflow[0].board + '/</a> </h2>');
+
+ if($.inArray(page, cache) != -1) {
+ if (thread.length > 0) {
+ $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).attr("data-cached", "no").css('display', 'block'));
+ boardheader.insertBefore(thread);
+ addukkohide.call(boardheader);
+ $(document).trigger('new_post', thread);
+ }
+ overflow.shift();
+ } else {
+ loading = true;
+ $('.pages').show().html(_("Loading..."));
+ $.get(page, function(data) {
+ cache.push(page);
+
+ $(data).find('div[id*="thread_"]').each(function() {
+ var checkout = $(this).attr('id').replace('thread_', '');
+ if ($('div#thread_' + checkout + '[data-board="' + overflow[0].board + '"]').length == 0) {
+ $('form[name="postcontrols"]').prepend($(this).css('display', 'none').attr("data-cached", "yes").attr('data-board', overflow[0].board));
+ }
+ });
+
+ thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"][data-cached="yes"]');
+
+ if(thread.length > 0) {
+ $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).attr("data-cached", "no").css('display', 'block'));
+ boardheader.insertBefore(thread);
+ addukkohide.call(boardheader);
+ $(document).trigger('new_post', thread);
+ }
+ overflow.shift();
+
+ loading = false;
+ $('.pages').hide().html("");
+ });
+ break;
+ }
+ }
+ clearTimeout(ukkotimer);
+ ukkotimer = setTimeout(loadnext, 1000);
+ };
+
+ $(window).on('scroll', loadnext);
+
+ ukkotimer = setTimeout(loadnext, 1000);
+});
+
+})();
diff --git a/templates/themes/rand/theme.php b/templates/themes/rand/theme.php
new file mode 100644
index 00000000..e3814c4e
--- /dev/null
+++ b/templates/themes/rand/theme.php
@@ -0,0 +1,105 @@
+<?php
+ require 'info.php';
+
+ function rand_build($action, $settings) {
+ $rand = new rand();
+ $rand->settings = $settings;
+
+ file_write($settings['uri'] . '/index.html', $rand->build());
+ file_write($settings['uri'] . '/rand.js', Element('themes/rand/rand.js', array()));
+ }
+
+ class rand {
+ public $settings;
+ public function build($mod = false) {
+ global $config;
+ $boards = listBoards();
+
+ $body = '';
+ $overflow = array();
+ $board = array(
+ 'dir' => $this->settings['uri'] . "/",
+ 'url' => $this->settings['uri'],
+ 'name' => $this->settings['title'],
+ 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit'])
+ );
+
+ $query = '';
+ foreach($boards as &$_board) {
+ if(in_array($_board['uri'], explode(' ', $this->settings['exclude'])))
+ continue;
+ $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']);
+ }
+ $query = preg_replace('/UNION ALL $/', 'ORDER BY RAND()', $query);
+ $query = query($query) or error(db_error());
+
+ $count = 0;
+ $threads = array();
+ while($post = $query->fetch()) {
+
+ if(!isset($threads[$post['board']])) {
+ $threads[$post['board']] = 1;
+ } else {
+ $threads[$post['board']] += 1;
+ }
+
+ if($count < $this->settings['thread_limit']) {
+ openBoard($post['board']);
+ $thread = new Thread($post, $mod ? '?/' : $config['root'], $mod);
+
+ $posts = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $post['board']));
+ $posts->bindValue(':id', $post['id']);
+ $posts->bindValue(':limit', ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']), PDO::PARAM_INT);
+ $posts->execute() or error(db_error($posts));
+
+ $num_images = 0;
+ while ($po = $posts->fetch()) {
+ if ($po['files'])
+ $num_images++;
+
+ $thread->add(new Post($po, $mod ? '?/' : $config['root'], $mod));
+
+ }
+ if ($posts->rowCount() == ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview'])) {
+ $ct = prepare(sprintf("SELECT COUNT(`id`) as `num` FROM ``posts_%s`` WHERE `thread` = :thread UNION ALL SELECT COUNT(`id`) FROM ``posts_%s`` WHERE `files` IS NOT NULL AND `thread` = :thread", $post['board'], $post['board']));
+ $ct->bindValue(':thread', $post['id'], PDO::PARAM_INT);
+ $ct->execute() or error(db_error($count));
+
+ $c = $ct->fetch();
+ $thread->omitted = $c['num'] - ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']);
+
+ $c = $ct->fetch();
+ $thread->omitted_images = $c['num'] - $num_images;
+ }
+
+
+ $thread->posts = array_reverse($thread->posts);
+ $body .= '<h2><a href="' . $config['root'] . $post['board'] . '">/' . $post['board'] . '/</a></h2>';
+ $body .= $thread->build(true);
+ } else {
+ $page = 'index';
+ if(floor($threads[$post['board']] / $config['threads_per_page']) > 0) {
+ $page = floor($threads[$post['board']] / $config['threads_per_page']) + 1;
+ }
+ $overflow[] = array('id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html');
+ }
+
+ $count += 1;
+ }
+
+ $body .= '<script> var overflow = ' . json_encode($overflow) . '</script>';
+ $body .= '<script type="text/javascript" src="/'.$this->settings['uri'].'/rand.js"></script>';
+
+ return Element('index.html', array(
+ 'config' => $config,
+ 'board' => $board,
+ 'no_post_form' => true,
+ 'body' => $body,
+ 'mod' => $mod,
+ 'boardlist' => createBoardlist($mod),
+ ));
+ }
+
+ };
+
+?>
diff --git a/templates/themes/rand/thumb.png b/templates/themes/rand/thumb.png
new file mode 100644
index 00000000..eb616ef7
--- /dev/null
+++ b/templates/themes/rand/thumb.png
Binary files differ
diff --git a/templates/themes/recent/cyberpunk_recent.css b/templates/themes/recent/cyberpunk_recent.css
new file mode 100644
index 00000000..c8dfd246
--- /dev/null
+++ b/templates/themes/recent/cyberpunk_recent.css
@@ -0,0 +1,124 @@
+body {
+ background: #0C0001;
+ color: #FF36AD;
+ font-family: monospace;
+ font-size: 11px;
+}
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+h1 {
+ font-family: monospace, Arial;
+ font-size: 18pt;
+ text-align: center;
+ letter-spacing: 0px;
+}
+div.title, h1 {
+ color: #FF36AD;
+ font-family: lain, Helvetica, sans-serif;
+}
+header div.subtitle {
+color: #00ff00;
+text-align: center;
+}
+div.title p {
+ font-size: 13px;
+}
+a:link, a:visited, p.intro a.email span.name {
+ color: #00ff00;
+ text-decoration: underline;
+ font-family: monospace;
+}
+a:link:hover, a:visited:hover {
+ color: #00ff00;
+ font-family: monospace;;
+ text-decoration: underline overline;
+}
+/*@import url("/stylesheets/dark.css");
+body {
+ color: #CCCCCC;
+ background: #1E1E1E;
+}
+
+header div.subtitle, h1 {
+ color: #32DD72;
+}
+*/
+
+/*a:link, a:visited, p.intro a.email span.name {
+ color: #CCCCCC;
+ text-decoration: none;
+ font-family: sans-serif;
+ transition: text-shadow 0.15s ease 0s color 0.15s ease 0s;
+}*/
+/*a:link:hover, a:visited:hover {
+ color: #32DD72;
+ font-family: sans-serif;
+ text-decoration: none;
+ text-shadow: 0px 0px 5px #FFF;
+}
+*/
+.box-wrap {
+ max-width: 670px;
+ min-width: 332px;
+ margin: 0px auto 30px auto;
+ overflow: auto;
+ padding: 0;
+}
+.box {
+ background: transparent;
+ border: 1px solid #33cccc;
+ width: 330px;
+ margin: 8px 0 0 0;
+ padding: 0;
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ border-radius: 2px;
+}
+.box ul {
+ padding: 2px 15px;;
+}
+.box ul li {
+ list-style: none;
+ margin: 0;
+}
+
+.box.left {
+ float: left;
+}
+.box.left ul {
+ text-align: center;
+}
+.box.right {
+ float: right;
+}
+.box strong {
+ color: #32DD72;
+}
+.box h2 {
+ padding: 3px 7px;
+ font-size: 10pt;
+ border-bottom: #33cccc 1px solid;
+ color: #00ff00;
+ background: #00080C;
+ border-radius: 10px;
+}
+.box img {
+ float: none;
+ box-sizing: border-box;
+
+}
+.box li:not(:nth-child(1)) img {
+ margin-top: 12px;
+}
+
+.topbar {
+ background-color: black;
+ border-bottom: 1px solid #33cccc;
+} \ No newline at end of file
diff --git a/templates/themes/recent/recent.css b/templates/themes/recent/recent.css
index 7b9f2333..1ec5dc50 100644
--- a/templates/themes/recent/recent.css
+++ b/templates/themes/recent/recent.css
@@ -1,15 +1,35 @@
+/**
+ * dark.css
+ * Stolen from circlepuller who stole it from derpcat
+ */
+body
+{
+ background: #0b000f;
+ color: #7fdd57;
+ font-family: sans-serif;
+ font-size: 12px;
+}
+
+@font-face {
+ font-family: 'FontAwesome';
+ 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
+}
+
.box-wrap {
max-width: 670px;
- min-width: 332px;
+ min-width: 400px;
margin: 30px auto;
overflow: auto;
padding: 0;
}
.box {
- background: white;
- border: 1px solid #98E;
+ background: #0b000f;
+ border: 0px solid #98E;
width: 330px;
- margin: 8px 0;
+ margin: 0px 0;
padding: 0;
}
.box ul {
@@ -20,16 +40,18 @@
margin: 0;
}
.box.left {
- background: #efe;
- color: #060;
- border: 1px solid #060;
+ background: #0b000f;
+ color: #7fdd57;
+ border: 0px solid #060;
float: left;
+ width: 300px;
}
.box.right {
- background: #eef;
- color: #006;
- border: 1px solid #006;
+ background: #0b000f;
+ color: #7fdd57;
+ border: 0px solid #006;
float: right;
+ width: 436px;
}
.box h2 {
@@ -37,14 +59,114 @@
font-size: 12pt;
}
.box.left h2 {
- background: #9C6;
- color: #060;
+ background: #7fdd57;
+ color: #677965;
}
.box.right h2 {
- background: #59A;
- color: white;
+ background: #7fdd57;
+ color: #0b000f;
}
.box img {
float: none;
- margin: 10px auto;
-} \ No newline at end of file
+ margin: 0px auto;
+}
+
+span.quote
+{
+ color:#677965;
+}
+@font-face
+{
+ font-family: 'lain';
+ src: url('./fonts/nrdyyh.woff') format('woff'),
+ url('./fonts/tojcxo.TTF') format('truetype');
+}
+h1
+{
+ font-family: 'arial black', arial;
+ letter-spacing: -20px;
+ font-size: 116pt;
+ text-align: center;
+ color: #7fdd57;
+}
+header div.subtitle
+{
+ color: #677965;
+}
+div.title
+{
+ color: #677965;
+ font-family: Arial, Helvetica, sans-serif;
+}
+div.title p
+{
+ font-size: 10px;
+}
+a:link, a:visited, .intro a.email span.name {
+ color: #677965;
+ text-decoration: none;
+ font-family: sans-serif;
+ font-size: 11pt;
+}
+
+div.post.reply div.body a:link:hover, div.post.reply div.body a:visited:hover
+{
+ color: #7fdd57;
+}
+p.intro span.subject {
+ font-size: 12px;
+ font-family: sans-serif;
+ color: #7fdd57;
+ font-weight: 800;
+}
+p.intro span.name {
+ color: #7fdd57;
+ font-weight: 800;
+}
+
+p.intro a.email, p.intro a.email span.name, p.intro a.email:hover, p.intro a.email:hover span.name {
+ color: #7fdd57;
+}
+.bar
+{
+ background: #0b000f!important;
+ -moz-box-shadow: 0 0 40px #000;
+ -webkit-box-shadow: 0 0 40px #000;
+ box-shadow: 0 0 40px #000;
+}
+.bar.top
+{
+ border-bottom: 0px solid #0b000f;
+}
+.bar.bottom
+{
+ border-top: 1px solid #666;
+}
+
+div.boardlist
+{
+ color: #0b000f;
+}
+
+div.ban
+{
+ background-color: rgba(11, 0, 15, 0);
+ border: 0px solid #555;
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+ text-align: left!important;
+}
+div.ban h2
+{
+ background: #0b000f;
+ color: #7fdd57;
+ padding: 5px 5px;
+ font-size: 16pt;
+ border-bottom: 0px solid #555;
+}
+
+div.ban h2:not(:nth-child(1))
+{
+ border-top: 0px solid #0b000f;
+}
diff --git a/templates/themes/recent/recent.html b/templates/themes/recent/recent.html
index 208c1088..f0276ac7 100644
--- a/templates/themes/recent/recent.html
+++ b/templates/themes/recent/recent.html
@@ -4,20 +4,35 @@
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>{{ settings.title }}</title>
- <link rel="stylesheet" media="screen" href="{{ config.url_stylesheet }}"/>
- <link rel="stylesheet" media="screen" href="{{ config.root }}{{ settings.css }}"/>
+ <link rel="stylesheet" media="screen" href="{{ config.root}}stylesheets/style.css"/>
+ <link rel="stylesheet" media="screen" href="{{ config.root}}stylesheets/recent.css"/>
+ <link rel="stylesheet" media="screen" href="https://lainchan.org/stylesheets/font-awesome/css/font-awesome.min.css"/>
+
{% if config.url_favicon %}<link rel="shortcut icon" href="{{ config.url_favicon }}" />{% endif %}
{% if config.default_stylesheet.1 != '' %}<link rel="stylesheet" type="text/css" id="stylesheet" href="{{ config.uri_stylesheets }}{{ config.default_stylesheet.1 }}">{% endif %}
{% if config.font_awesome %}<link rel="stylesheet" href="{{ config.root }}{{ config.font_awesome_css }}">{% endif %}
</head>
<body>
- {{ boardlist.top }}
+ <div class="bar top">
+ {{ boardlist.top }}
+ </div>
+
<header>
- <h1>{{ settings.title }}</h1>
- <div class="subtitle">{{ settings.subtitle }}</div>
+ <center>
+ <img alt="header" class="lain_banner" src="static/lainchan_header_console.gif"/>
+ </center>
</header>
-
- <div class="box-wrap">
+<br>
+
+ <img alt="mascot" class="lain_banner"src="static/lain_banner1.png"/>
+
+ <br>
+
+ <div class="ban" id="global"> <h2>CYBERPUNK IS DEAD</h2> Pour out the Soykaf, lurk, and read the <a href="https://lainchan.org/rules">rules</a> before posting! </div>
+
+ <br>
+
+ <div class="ban" id="global">
<div class="box left">
<h2>Recent Images</h2>
<ul>
@@ -52,13 +67,12 @@
</ul>
</div>
</div>
-
- <hr/>
+
<footer>
- <p class="unimportant" style="margin-top:20px;text-align:center;">- Tinyboard +
- <a href="https://engine.vichan.net/">vichan</a> {{ config.version }} -
- <br>Tinyboard Copyright &copy; 2010-2014 Tinyboard Development Group
- <br><a href="https://engine.vichan.net/">vichan</a> Copyright &copy; 2012-2016 vichan-devel</p>
+ <center>
+ <a href="mailto:admin@lainchan.org?Subject=Hello" target="_top">admin@lainchan.org</a>
+ </center>
+
</footer>
</body>
</html>
diff --git a/templates/themes/recent/recent_dark.css b/templates/themes/recent/recent_dark.css
index c59214ac..e9c3aed1 100644
--- a/templates/themes/recent/recent_dark.css
+++ b/templates/themes/recent/recent_dark.css
@@ -1,73 +1,79 @@
-body {
+@import url("/stylesheets/dark.css");
+/*body {
color: #CCCCCC;
background: #1E1E1E;
}
header div.subtitle, h1 {
- color: #CCCCCC;
+ color: #32DD72;
}
+*/
-a:link, a:visited, p.intro a.email span.name {
+/*a:link, a:visited, p.intro a.email span.name {
color: #CCCCCC;
- text-decoration: underline;
+ text-decoration: none;
font-family: sans-serif;
-}
-a:link:hover, a:visited:hover {
- color: #FF0000;
+ transition: text-shadow 0.15s ease 0s color 0.15s ease 0s;
+}*/
+/*a:link:hover, a:visited:hover {
+ color: #32DD72;
font-family: sans-serif;
- text-decoration: underline overline;
+ text-decoration: none;
+ text-shadow: 0px 0px 5px #FFF;
}
-
+*/
.box-wrap {
max-width: 670px;
min-width: 332px;
- margin: 30px auto;
+ margin: 0px auto 30px auto;
overflow: auto;
padding: 0;
}
.box {
- background: white;
- border: 1px solid #98E;
+ background: transparent;
+ border: 1px solid #555555;
width: 330px;
- margin: 8px 0;
+ margin: 8px 0 0 0;
padding: 0;
+ -webkit-border-radius: 2px;
+ -khtml-border-radius: 2px;
+ -moz-border-radius: 2px;
+ -o-border-radius: 2px;
+ -ms-border-radius: 2px;
+ border-radius: 2px;
}
.box ul {
- padding: 2px 15px;
+ padding: 2px 15px;;
}
.box ul li {
list-style: none;
margin: 0;
}
+
.box.left {
- background: #333333;
- color: #CCCCCC;
- border: #555555 1px solid;
float: left;
}
+.box.left ul {
+ text-align: center;
+}
.box.right {
- background: #333333;
- color: #CCCCCC;
- border: #555555 1px solid;
float: right;
}
-
+.box strong {
+ color: #32DD72;
+}
.box h2 {
padding: 3px 7px;
font-size: 12pt;
- border: #555555 1px solid;
-}
-.box.left h2 {
- background: #333333;
- color: #CCCCCC;
- border: #555555 1px solid;
-}
-.box.right h2 {
- background: #333333;
- color: #CCCCCC;
- border: #555555 1px solid;
+ border-bottom: #555555 1px solid;
+ color: #32DD72;
+ background: #333333;
}
.box img {
float: none;
- margin: 10px auto;
+ box-sizing: border-box;
+
+}
+.box li:not(:nth-child(1)) img {
+ margin-top: 12px;
}
diff --git a/templates/themes/rules/info.php b/templates/themes/rules/info.php
new file mode 100755
index 00000000..7faaedc6
--- /dev/null
+++ b/templates/themes/rules/info.php
@@ -0,0 +1,23 @@
+<?php
+$theme = array(
+ 'name' => 'Rules',
+ 'description' => 'Display the lainchan rules',
+ 'version' => 'v1',
+
+ 'config' => array(
+ array('title' => 'Page title',
+ 'name' => 'title',
+ 'type' => 'text'),
+
+ array('title' => 'Slogan',
+ 'name' => 'subtitle',
+ 'type' => 'text',
+ 'comment' => '(optional)'),
+
+ array('title' => 'File',
+ 'name' => 'file',
+ 'type' => 'text',
+ 'default' => 'rules.html')),
+
+ 'build_function' => 'rules_build');
+?> \ No newline at end of file
diff --git a/templates/themes/rules/rules.html b/templates/themes/rules/rules.html
new file mode 100755
index 00000000..3f37e573
--- /dev/null
+++ b/templates/themes/rules/rules.html
@@ -0,0 +1,38 @@
+{% filter remove_whitespace %}
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <title>{{ settings.title }}</title>
+ <link rel="shortcut icon" href="/favicon.png">
+ <link rel="stylesheet" media="screen" href="/stylesheets/style.css"/>
+ <link rel="stylesheet" media="screen" href="/stylesheets/dark.css"/>
+ <link rel="stylesheet" href="/stylesheets/font-awesome/css/font-awesome.min.css">
+ </head>
+ <body>
+ <div class="bar top">
+ {{ boardlist.top }}
+ </div>
+
+ <header>
+ <h1>{{ settings.title }}</h1>
+ <div class="subtitle">{{ settings.subtitle }}</div>
+ </header>
+
+ <center>
+ <img alt="mascot" src="static/lain_is_cute_datass_small.png"/>
+ </center>
+
+ {% include 'rules.html' %}
+
+ </body>
+</html>
+{% endfilter %}
+
+
+
+
+
+
+
+
diff --git a/templates/themes/rules/theme.php b/templates/themes/rules/theme.php
new file mode 100755
index 00000000..fc50437f
--- /dev/null
+++ b/templates/themes/rules/theme.php
@@ -0,0 +1,28 @@
+<?php
+
+require 'info.php';
+
+function rules_build($action, $settings, $board) {
+ rules::build($action, $settings);
+}
+
+class rules {
+ public static function build($action, $settings) {
+ global $config;
+
+ if ($action == 'all') {
+ file_write($config['dir']['home'] . $settings['file'], rules::install($settings));
+ }
+ }
+
+ public static function install($settings) {
+ global $config;
+
+ return Element('themes/rules/rules.html',
+ array('settings' => $settings,
+ 'config' => $config,
+ 'boardlist' => createBoardlist()));
+ }
+}
+
+?> \ No newline at end of file
diff --git a/templates/themes/rules/thumb.png b/templates/themes/rules/thumb.png
new file mode 100755
index 00000000..bd6b129f
--- /dev/null
+++ b/templates/themes/rules/thumb.png
Binary files differ
diff --git a/templates/themes/semirand/info.php b/templates/themes/semirand/info.php
new file mode 100644
index 00000000..255935c1
--- /dev/null
+++ b/templates/themes/semirand/info.php
@@ -0,0 +1,70 @@
+<?php
+
+ // Basic theme properties
+ $theme = array(
+ 'name' => 'Mixed All/Random Overboard',
+ // Description (you can use Tinyboard markup here)
+ 'description' => 'Board with threads from all boards with most recently bumped and random ones intermixed',
+ 'version' => 'v0.1',
+ // Unique function name for building and installing whatever's necessary
+ 'build_function' => 'semirand_build',
+ 'install_callback' => 'semirand_install',
+ );
+
+ // Theme configuration
+ $theme['config'] = array(
+ array(
+ 'title' => 'Board name',
+ 'name' => 'title',
+ 'type' => 'text',
+ 'default' => 'Semirandom',
+ ),
+ array(
+ 'title' => 'Board URI',
+ 'name' => 'uri',
+ 'type' => 'text',
+ 'default' => '.',
+ 'comment' => '("mixed", for example)',
+ ),
+ array(
+ 'title' => 'Subtitle',
+ 'name' => 'subtitle',
+ 'type' => 'text',
+ 'comment' => '(%s = thread limit, for example "%s coolest threads")',
+ ),
+ array(
+ 'title' => 'Excluded boards',
+ 'name' => 'exclude',
+ 'type' => 'text',
+ 'comment' => '(space seperated)',
+ ),
+ array(
+ 'title' => 'Number of threads',
+ 'name' => 'thread_limit',
+ 'type' => 'text',
+ 'default' => '15',
+ ),
+ array(
+ 'title' => 'Random threads',
+ 'name' => 'random_count',
+ 'comment' => '(number of consecutive random threads)',
+ 'type' => 'text',
+ 'default' => '1',
+ ),
+ array(
+ 'title' => 'Bumped threads',
+ 'name' => 'bumped_count',
+ 'comment' => '(number of consecutive recent threads)',
+ 'type' => 'text',
+ 'default' => '1',
+ ),
+ );
+
+ if (!function_exists('semirand_install')) {
+ function semirand_install($settings) {
+ if (!file_exists($settings['uri'])) {
+ @mkdir($settings['uri'], 0777) or error("Couldn't create {$settings['uri']}. Check permissions.", true);
+ }
+ }
+ }
+
diff --git a/templates/themes/semirand/semirand.js b/templates/themes/semirand/semirand.js
new file mode 100644
index 00000000..c07e8452
--- /dev/null
+++ b/templates/themes/semirand/semirand.js
@@ -0,0 +1,158 @@
+$(document).ready(function() {
+ var cachedPages = [],
+ loading = false,
+ timer = null;
+
+ // Load data from HTML5 localStorage
+ var hiddenBoards = JSON.parse(localStorage.getItem('hiddenboards'));
+
+ var storeHiddenBoards = function() {
+ localStorage.setItem('hiddenboards', JSON.stringify(hiddenBoards));
+ };
+
+ // No board are hidden by default
+ if (!hiddenBoards) {
+ hiddenBoards = {};
+ storeHiddenBoards();
+ }
+
+ // Hide threads from the same board and remember for next time
+ var onHideClick = function(e) {
+ e.preventDefault();
+ var board = $(this).parent().next().data('board'),
+ threads = $('[data-board="'+board+'"]:not([data-cached="yes"])'),
+ btns = threads.prev().find('.threads-toggle'),
+ hrs = btns.next();
+
+ if (hiddenBoards[board]) {
+ threads.show();
+ btns.find('.threads-toggle').html(_('(hide threads from this board)'));
+ hrs.hide();
+ } else {
+ threads.hide();
+ btns.html(_('(show threads from this board)'));
+ hrs.show();
+ }
+
+ hiddenBoards[board] = !hiddenBoards[board];
+ storeHiddenBoards();
+ };
+
+ // Add a hiding link and horizontal separator to each thread
+ var addHideButton = function() {
+ var board = $(this).next().data('board'),
+ // Create the link and separator
+ button = $('<a href="#" class="unimportant threads-toggle"></a>')
+ .click(onHideClick),
+ myHr = $('<hr />');
+
+ // Insert them after the board name
+ $(this).append(' ').append(button).append(myHr);
+
+ if (hiddenBoards[board]) {
+ button.html(_('(show threads from this board)'));
+ $(this).next().hide();
+ } else {
+ button.html(_('(hide threads from this board)'));
+ myHr.hide();
+ }
+ };
+
+ $('h2').each(addHideButton);
+
+ var appendThread = function(elem, data) {
+ var boardLink = $('<h2><a href="' + modRoot + data.board + '/">/' +
+ data.board + '/</a></h2>');
+
+ // Push the thread after the currently last one
+ $('div[id*="thread_"]').last()
+ .after(elem.data('board', data.board)
+ .data('cached', 'no')
+ .show());
+ // Add the obligatory board link
+ boardLink.insertBefore(elem);
+ // Set up the hiding link
+ addHideButton.call(boardLink);
+ // Trigger an event to let the world know that we have a new thread aboard
+ $(document).trigger('new_post', elem);
+ };
+
+ var attemptLoadNext = function() {
+ if (!ukko_overflow.length) {
+ $('.pages').show().html(_('No more threads to display'));
+ return;
+ }
+
+ var viewHeight = $(window).scrollTop() + $(window).height(),
+ pageHeight = $(document).height();
+ // Keep loading deferred threads as long as we're close to the bottom of the
+ // page and there are threads remaining
+ while(viewHeight + 1000 > pageHeight && !loading && ukko_overflow.length > 0) {
+ // Take the first unloaded post
+ var post = ukko_overflow.shift(),
+ page = modRoot + post.board + '/' + post.page;
+
+ var thread = $('div#thread_' + post.id + '[data-board="' + post.board + '"]');
+ // Check that the thread hasn't been inserted yet
+ if (thread.length && thread.data('cached') !== 'yes') {
+ continue;
+ }
+
+ // Check if we've already downloaded the index page on which this thread
+ // is located
+ if ($.inArray(page, cachedPages) !== -1) {
+ if (thread.length) {
+ appendThread(thread, post);
+ }
+ // Otherwise just load the page and cache its threads
+ } else {
+ // Make sure that no other thread does the job that we're about to do
+ loading = true;
+ $('.pages').show().html(_('Loading…'));
+
+ // Retrieve the page from the server
+ $.get(page, function(data) {
+ cachedPages.push(page);
+
+ // Cache each retrieved thread
+ $(data).find('div[id*="thread_"]').each(function() {
+ var thread_id = $(this).attr('id').replace('thread_', '');
+
+ // Check that this thread hasn't already been loaded somehow
+ if ($('div#thread_' + thread_id + '[data-board="' +
+ post.board + '"]').length)
+ {
+ return;
+ }
+
+ // Hide the freshly loaded threads somewhere at the top
+ // of the page for now
+ $('form[name="postcontrols"]')
+ .prepend($(this).hide()
+ .data('cached', 'yes')
+ .data('data-board', post.board));
+ });
+
+ // Find the current thread in the newly retrieved ones
+ thread = $('div#thread_' + post.id + '[data-board="' +
+ post.board + '"][data-cached="yes"]');
+
+ if (thread.length) {
+ appendThread(thread, post);
+ }
+
+ // Release the lock
+ loading = false;
+ $('.pages').hide().html('');
+ });
+ break;
+ }
+ }
+
+ clearTimeout(timer);
+ // Check again in one second
+ timer = setTimeout(attemptLoadNext, 1000);
+ };
+
+ attemptLoadNext();
+});
diff --git a/templates/themes/semirand/theme.php b/templates/themes/semirand/theme.php
new file mode 100644
index 00000000..e8d3e56c
--- /dev/null
+++ b/templates/themes/semirand/theme.php
@@ -0,0 +1,255 @@
+<?php
+
+ require 'info.php';
+
+ /**
+ * Generate the board's HTML and move it and its JavaScript in place, whence
+ * it's served
+ */
+ function semirand_build($action, $settings) {
+ global $config;
+
+ if ($action !== 'all' && $action !== 'post' && $action !== 'post-thread' &&
+ $action !== 'post-delete')
+ {
+ return;
+ }
+
+ if ($config['smart_build']) {
+ file_unlink($settings['uri'] . '/index.html');
+ } else {
+ $semirand = new semirand($settings);
+
+ // Copy the generated board HTML to its place
+ file_write($settings['uri'] . '/index.html', $semirand->build());
+ file_write($settings['uri'] . '/semirand.js',
+ Element('themes/semirand/semirand.js', array()));
+ }
+ }
+
+ /**
+ * Encapsulation of the theme's internals
+ */
+ class semirand {
+ private $settings;
+
+ function __construct($settings) {
+ $this->settings = $this->parseSettings($settings);
+ }
+
+ /**
+ * Parse and validate configuration parameters passed from the UI
+ */
+ private function parseSettings($settings) {
+ if (!is_numeric($settings['thread_limit']) ||
+ !is_numeric($settings['random_count']) ||
+ !is_numeric($settings['recent_count']))
+ {
+ error('Invalid configuration parameters.', true);
+ }
+
+ $settings['exclude'] = explode(' ', $settings['exclude']);
+ $settings['thread_limit'] = intval($settings['thread_limit']);
+ $settings['random_count'] = intval($settings['random_count']);
+ $settings['recent_count'] = intval($settings['recent_count']);
+
+ if ($settings['thread_limit'] < 1 ||
+ $settings['random_count'] < 1 ||
+ $settings['recent_count'] < 1)
+ {
+ error('Invalid configuration parameters.', true);
+ }
+
+ return $settings;
+ }
+
+ /**
+ * Obtain list of all threads from all non-excluded boards
+ */
+ private function fetchThreads() {
+ $query = '';
+ $boards = listBoards(true);
+
+ foreach ($boards as $b) {
+ if (in_array($b, $this->settings['exclude']))
+ continue;
+ // Threads are those posts that have no parent thread
+ $query .= "SELECT *, '$b' AS `board` FROM ``posts_$b`` " .
+ "WHERE `thread` IS NULL UNION ALL ";
+ }
+
+ $query = preg_replace('/UNION ALL $/', 'ORDER BY `bump` DESC', $query);
+ $result = query($query) or error(db_error());
+
+ return $result->fetchAll(PDO::FETCH_ASSOC);
+ }
+
+ /**
+ * Retrieve all replies to a given thread
+ */
+ private function fetchReplies($board, $thread_id) {
+ $query = prepare("SELECT * FROM ``posts_$board`` WHERE `thread` = :id");
+ $query->bindValue(':id', $thread_id, PDO::PARAM_INT);
+ $query->execute() or error(db_error($query));
+
+ return $query->fetchAll(PDO::FETCH_ASSOC);
+ }
+
+ /**
+ * Intersperse random threads between those in bump order
+ */
+ private function shuffleThreads($threads) {
+ $random_count = $this->settings['random_count'];
+ $recent_count = $this->settings['recent_count'];
+ $total = count($threads);
+
+ // Storage for threads that will be randomly interspersed
+ $shuffled = array();
+
+ // Ratio of bumped / all threads
+ $topRatio = $recent_count / ($recent_count + $random_count);
+ // Shuffle the bottom half of all threads
+ $random = array_splice($threads, floor($total * $topRatio));
+ shuffle($random);
+
+ // Merge the random and sorted threads into one sequence. The pattern
+ // starts at random threads
+ while (!empty($threads)) {
+ $shuffled = array_merge($shuffled,
+ array_splice($random, 0, $random_count),
+ array_splice($threads, 0, $recent_count));
+ }
+
+ return $shuffled;
+ }
+
+ /**
+ * Build the HTML of a single thread in the catalog
+ */
+ private function buildOne($post, $mod = false) {
+ global $config;
+
+ openBoard($post['board']);
+ $thread = new Thread($post, $mod ? '?/' : $config['root'], $mod);
+ $replies = $this->fetchReplies($post['board'], $post['id']);
+ // Number of replies to a thread that are displayed beneath it
+ $preview_count = $post['sticky'] ? $config['threads_preview_sticky'] :
+ $config['threads_preview'];
+
+ // Chomp the last few replies
+ $disp_replies = array_splice($replies, 0, $preview_count);
+ $disp_img_count = 0;
+ foreach ($disp_replies as $reply) {
+ if ($reply['files'] !== '')
+ ++$disp_img_count;
+
+ // Append the reply to the thread as it's being built
+ $thread->add(new Post($reply, $mod ? '?/' : $config['root'], $mod));
+ }
+
+ // Count the number of omitted image replies
+ $omitted_img_count = count(array_filter($replies, function($p) {
+ return $p['files'] !== '';
+ }));
+
+ // Set the corresponding omitted numbers on the thread
+ if (!empty($replies)) {
+ $thread->omitted = count($replies);
+ $thread->omitted_images = $omitted_img_count;
+ }
+
+ // Board name and link
+ $html = '<h2><a href="' . $config['root'] . $post['board'] . '/">/' .
+ $post['board'] . '/</a></h2>';
+ // The thread itself
+ $html .= $thread->build(true);
+
+ return $html;
+ }
+
+ /**
+ * Query the required information and generate the HTML
+ */
+ public function build($mod = false) {
+ if (!isset($this->settings)) {
+ error('Theme is not configured properly.');
+ }
+
+ global $config;
+
+ $html = '';
+ $overflow = array();
+
+ // Fetch threads from all boards and chomp the first 'n' posts, depending
+ // on the setting
+ $threads = $this->shuffleThreads($this->fetchThreads());
+ $total_count = count($threads);
+ // Top threads displayed on load
+ $top_threads = array_splice($threads, 0, $this->settings['thread_limit']);
+ // Number of processed threads by board
+ $counts = array();
+
+ // Output threads up to the specified limit
+ foreach ($top_threads as $post) {
+ if (array_key_exists($post['board'], $counts)) {
+ ++$counts[$post['board']];
+ } else {
+ $counts[$post['board']] = 1;
+ }
+
+ $html .= $this->buildOne($post, $mod);
+ }
+
+ foreach ($threads as $post) {
+ if (array_key_exists($post['board'], $counts)) {
+ ++$counts[$post['board']];
+ } else {
+ $counts[$post['board']] = 1;
+ }
+
+ $page = 'index';
+ $board_page = floor($counts[$post['board']] / $config['threads_per_page']);
+ if ($board_page > 0) {
+ $page = $board_page + 1;
+ }
+ $overflow[] = array(
+ 'id' => $post['id'],
+ 'board' => $post['board'],
+ 'page' => $page . '.html'
+ );
+ }
+
+ $html .= '<script>var ukko_overflow = ' . json_encode($overflow) . '</script>';
+ $html .= '<script type="text/javascript" src="/'.$this->settings['uri'].'/semirand.js"></script>';
+
+ return Element('index.html', array(
+ 'config' => $config,
+ 'board' => array(
+ 'dir' => $this->settings['uri'] . "/",
+ 'url' => $this->settings['uri'],
+ 'title' => $this->settings['title'],
+ 'subtitle' => str_replace('%s', $this->settings['thread_limit'],
+ strval(min($this->settings['subtitle'], $total_count))),
+ ),
+ 'no_post_form' => true,
+ 'body' => $html,
+ 'mod' => $mod,
+ 'boardlist' => createBoardlist($mod),
+ ));
+ }
+
+ };
+
+ if (!function_exists('array_column')) {
+ /**
+ * Pick out values from subarrays by given key
+ */
+ function array_column($array, $key) {
+ $result = [];
+ foreach ($array as $val) {
+ $result[] = $val[$key];
+ }
+ return $result;
+ }
+ }
+
diff --git a/templates/themes/semirand/thumb.png b/templates/themes/semirand/thumb.png
new file mode 100644
index 00000000..eb616ef7
--- /dev/null
+++ b/templates/themes/semirand/thumb.png
Binary files differ
diff --git a/templates/themes/ukko/theme.php b/templates/themes/ukko/theme.php
index e572c467..ee2707bf 100644
--- a/templates/themes/ukko/theme.php
+++ b/templates/themes/ukko/theme.php
@@ -30,7 +30,9 @@
$body = '';
$overflow = array();
$board = array(
+ 'dir' => $this->settings['uri'] . "/",
'url' => $this->settings['uri'],
+ 'uri' => $this->settings['uri'],
'name' => $this->settings['title'],
'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit'])
);
diff --git a/templates/themes/zine/info.php b/templates/themes/zine/info.php
new file mode 100644
index 00000000..d7dabef5
--- /dev/null
+++ b/templates/themes/zine/info.php
@@ -0,0 +1,23 @@
+<?php
+$theme = array(
+ 'name' => 'Zine',
+ 'description' => 'sex on digital paper',
+ 'version' => 'v9001',
+
+ 'config' => array(
+ array('title' => 'Page title',
+ 'name' => 'title',
+ 'type' => 'text'),
+
+ array('title' => 'Slogan',
+ 'name' => 'subtitle',
+ 'type' => 'text',
+ 'comment' => '(optional)'),
+
+ array('title' => 'File',
+ 'name' => 'file',
+ 'type' => 'text',
+ 'default' => 'zine/index.html')),
+
+ 'build_function' => 'zine_build');
+?>
diff --git a/templates/themes/zine/theme.php b/templates/themes/zine/theme.php
new file mode 100644
index 00000000..78cb780c
--- /dev/null
+++ b/templates/themes/zine/theme.php
@@ -0,0 +1,28 @@
+<?php
+
+require 'info.php';
+
+function zine_build($action, $settings, $board) {
+ zine::build($action, $settings);
+}
+
+class zine {
+ public static function build($action, $settings) {
+ global $config;
+
+ if ($action == 'all') {
+ file_write($config['dir']['home'] . $settings['file'], zine::install($settings));
+ }
+ }
+
+ public static function install($settings) {
+ global $config;
+
+ return Element('themes/zine/zine.html',
+ array('settings' => $settings,
+ 'config' => $config,
+ 'boardlist' => createBoardlist()));
+ }
+}
+
+?>
diff --git a/templates/themes/zine/thumb.png b/templates/themes/zine/thumb.png
new file mode 100644
index 00000000..f3f88e27
--- /dev/null
+++ b/templates/themes/zine/thumb.png
Binary files differ
diff --git a/templates/themes/zine/zine.html b/templates/themes/zine/zine.html
new file mode 100755
index 00000000..166c29d0
--- /dev/null
+++ b/templates/themes/zine/zine.html
@@ -0,0 +1,69 @@
+{% filter remove_whitespace %}
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <title>{{ settings.title }}</title>
+ <link rel="shortcut icon" href="/favicon.png">
+ <link rel="stylesheet" media="screen" href="/stylesheets/style.css"/>
+ <link rel="stylesheet" media="screen" href="/stylesheets/dark.css"/>
+ {% if config.font_awesome %}<link rel="stylesheet" href="{{ config.root }}{{ config.font_awesome_css }}">{% endif %}
+ <style type="text/css">
+ [alt="mascot"] {
+ margin: 0px auto -200px auto!important;
+ }
+ [alt="special mascot"] {
+ width: 100%;
+ margin: -3px 0px 0px 0px;
+ }
+ h2 {
+ padding: 3px 0px!important;
+ }
+ h2 span {
+ margin-left: 7px;
+ }
+ .ban {
+ min-width: 208px;
+ }
+ .ban .cont {
+
+ padding: 0px 7px;
+ margin: 7px auto 0px auto;
+ text-align: center;
+ }
+ .ban a {
+ max-width: 192px;
+ display: inline-block;
+ text-align: center;
+ border-radius: 2px;
+ border: 1px solid #555;
+ background: #333;
+ margin: 0px 2px 7px 2px;
+ }
+ a img {
+ max-width: 192px;
+ height: auto;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="bar top">{{ boardlist.top }}</div>
+ <header>
+ <h1>{{ settings.title }}</h1>
+ <div class="subtitle">{{ settings.subtitle }}</div>
+ </header>
+ <img alt="mascot" src="/static/lain_is_cute_datass_small.png"/>
+ <div class="ban">
+ <h2>
+ <img alt="special mascot" src="/static/zine_ipad.png"/>
+ <span>download</span>
+ </h2>
+ <div class="cont">
+ <a href="http://lainzine.neocities.org/all-releases/lainzine01.pdf"><img src="http://lainzine.neocities.org/img/lainzine01.png"/><br/><span>01</span></a>
+ <a href="http://lainzine.neocities.org/all-releases/lainzine02.pdf"><img src="http://lainzine.neocities.org/img/lainzine02.png"/><br/><span>02</span></a>
+ <a href="http://lainzine.neocities.org/all-releases/lainzine03.pdf"><img src="http://lainzine.neocities.org/img/lainzine03.png"/><br/><span>03</span></a>
+ </div>
+ </div>
+ </body>
+</html>
+{% endfilter %}
diff --git a/templates/thread.html b/templates/thread.html
index 88e6ec6d..5ecef649 100644
--- a/templates/thread.html
+++ b/templates/thread.html
@@ -2,6 +2,8 @@
<html>
<head>
<meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
+
<script type="text/javascript">
var active_page = "thread"
@@ -23,8 +25,10 @@
<title>{{ board.url }} - {{ meta_subject }}</title>
</head>
-<body class="8chan vichan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %} active-thread" data-stylesheet="{% if config.default_stylesheet.1 != '' %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
- {{ boardlist.top }}
+<body id="thread" class="8chan vichan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %} active-thread" data-stylesheet="{% if config.default_stylesheet.1 != '' %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
+ <div class="bar top">
+ {{ boardlist.top }}
+ </div>
<a name="top"></a>
{% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr />{% endif %}
{% if config.url_banner %}<img class="board_image" src="{{ config.url_banner }}" {% if config.banner_width or config.banner_height %}style="{% if config.banner_width %}width:{{ config.banner_width }}px{% endif %};{% if config.banner_width %}height:{{ config.banner_height }}px{% endif %}" {% endif %}alt="" />{% endif %}
@@ -44,7 +48,6 @@
{% include 'attention_bar.html' %}
- <div class="banner">{% trans %}Posting mode: Reply{% endtrans %} <a class="unimportant" href="{{ return }}">[{% trans %}Return{% endtrans %}]</a> <a class="unimportant" href="#bottom">[{% trans %}Go to bottom {% endtrans %}]</a></div>
{{ config.ad.top }}
@@ -52,6 +55,11 @@
{% if config.global_message %}<hr /><div class="blotter">{{ config.global_message }}</div>{% endif %}
<hr />
+ <div class="threadlinks-noup">
+ <span class="threadlink">[ <a href="{{ return }}">{% trans %}Return{% endtrans %}</a> /</span>
+ <span class="threadlink"><a href="#bottom" style="padding-left: 10px"> {% trans %}Go to bottom{% endtrans %}</a> ]</span>
+ </div>
+ <hr />
<form name="postcontrols" action="{{ config.post_url }}" method="post">
<input type="hidden" name="board" value="{{ board.uri }}" />
{% if mod %}<input type="hidden" name="mod" value="1" />{% endif %}
@@ -77,19 +85,30 @@
<div class="clearfix"></div>
</form>
- {{ boardlist.bottom }}
+ {{ boardlist.bottom }}
{{ config.ad.bottom }}
<footer>
- <p class="unimportant" style="margin-top:20px;text-align:center;">- Tinyboard +
- <a href="https://engine.vichan.net/">vichan</a> {{ config.version }} -
- <br>Tinyboard Copyright &copy; 2010-2014 Tinyboard Development Group
- <br><a href="https://engine.vichan.net/">vichan</a> Copyright &copy; 2012-2016 vichan-devel</p>
+ {% include 'badges.html' %}
+ <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> +
+ <a href='https://github.com/lainchan/lainchan'>lainchan</a> {{ config.version }} -
+ <br><a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2014 Tinyboard Development Group
+ <br><a href="https://engine.vichan.net/">vichan</a> Copyright &copy; 2012-2016 vichan-devel
+ <br><a href="https://github.com/lainchan/lainchan">lainchan</a> Copyright &copy; 2014-2016 lainchan Administration</p>
{% for footer in config.footer %}<p class="unimportant" style="text-align:center;">{{ footer }}</p>{% endfor %}
</footer>
+ <div class="bar bottom">
+ <div class="threadlinks">
+ <span class="threadlink">[ <a href="{{ return }}">{% trans %}Return{% endtrans %}</a> /</span>
+ <span class="threadlink"><a href="#" style="padding-left: 10px"> {% trans %}Go to top{% endtrans %}</a> /</span>
+ </div>
+ <div class=pages></div>
+ </div>
<script type="text/javascript">{% raw %}
ready();
{% endraw %}</script>
+ <a href="#" id="bottom"></a>
</body>
</html>
diff --git a/walls/1426962866730.png b/walls/1426962866730.png
new file mode 100644
index 00000000..c516c126
--- /dev/null
+++ b/walls/1426962866730.png
Binary files differ
diff --git a/walls/1426963001770-1.jpg b/walls/1426963001770-1.jpg
new file mode 100644
index 00000000..1d80ccc2
--- /dev/null
+++ b/walls/1426963001770-1.jpg
Binary files differ
diff --git a/walls/1426966616071-1.jpg b/walls/1426966616071-1.jpg
new file mode 100644
index 00000000..364a2dc1
--- /dev/null
+++ b/walls/1426966616071-1.jpg
Binary files differ
diff --git a/walls/1426966728834-1.jpg b/walls/1426966728834-1.jpg
new file mode 100644
index 00000000..9d4c1244
--- /dev/null
+++ b/walls/1426966728834-1.jpg
Binary files differ
diff --git a/walls/1427001458818-1.jpg b/walls/1427001458818-1.jpg
new file mode 100644
index 00000000..13d113f4
--- /dev/null
+++ b/walls/1427001458818-1.jpg
Binary files differ
diff --git a/walls/1427003079773-1.jpg b/walls/1427003079773-1.jpg
new file mode 100644
index 00000000..63565e6c
--- /dev/null
+++ b/walls/1427003079773-1.jpg
Binary files differ
diff --git a/walls/1427003222547-1.jpg b/walls/1427003222547-1.jpg
new file mode 100644
index 00000000..486fe6ed
--- /dev/null
+++ b/walls/1427003222547-1.jpg
Binary files differ
diff --git a/walls/1427007090570.jpg b/walls/1427007090570.jpg
new file mode 100644
index 00000000..41d68d24
--- /dev/null
+++ b/walls/1427007090570.jpg
Binary files differ
diff --git a/walls/1427010911673-1.jpg b/walls/1427010911673-1.jpg
new file mode 100644
index 00000000..5b2ca87a
--- /dev/null
+++ b/walls/1427010911673-1.jpg
Binary files differ
diff --git a/walls/1427029908812-0.jpg b/walls/1427029908812-0.jpg
new file mode 100644
index 00000000..b2eb801f
--- /dev/null
+++ b/walls/1427029908812-0.jpg
Binary files differ
diff --git a/walls/1427029908812-1.jpg b/walls/1427029908812-1.jpg
new file mode 100644
index 00000000..0a648f11
--- /dev/null
+++ b/walls/1427029908812-1.jpg
Binary files differ
diff --git a/walls/1427029908812-2.jpg b/walls/1427029908812-2.jpg
new file mode 100644
index 00000000..a2ac7019
--- /dev/null
+++ b/walls/1427029908812-2.jpg
Binary files differ
diff --git a/walls/1427030144598-1.jpg b/walls/1427030144598-1.jpg
new file mode 100644
index 00000000..d7b09991
--- /dev/null
+++ b/walls/1427030144598-1.jpg
Binary files differ
diff --git a/walls/1427030144598-2.jpg b/walls/1427030144598-2.jpg
new file mode 100644
index 00000000..45c0e1ef
--- /dev/null
+++ b/walls/1427030144598-2.jpg
Binary files differ
diff --git a/walls/1427032003105-0.jpg b/walls/1427032003105-0.jpg
new file mode 100644
index 00000000..ba60f89f
--- /dev/null
+++ b/walls/1427032003105-0.jpg
Binary files differ
diff --git a/walls/1427032212051-2.jpg b/walls/1427032212051-2.jpg
new file mode 100644
index 00000000..aea57ca4
--- /dev/null
+++ b/walls/1427032212051-2.jpg
Binary files differ
diff --git a/walls/1427067866355.jpg b/walls/1427067866355.jpg
new file mode 100644
index 00000000..2824bafc
--- /dev/null
+++ b/walls/1427067866355.jpg
Binary files differ
diff --git a/weeb b/weeb
new file mode 120000
index 00000000..6bf0c97a
--- /dev/null
+++ b/weeb
@@ -0,0 +1 @@
+w \ No newline at end of file