merge master with paypalrecurring

This commit is contained in:
Kyle Drake 2016-01-19 11:29:12 -08:00
commit b878417ee0
206 changed files with 8067 additions and 1860 deletions

19
.gitignore vendored
View file

@ -1,20 +1,4 @@
*.gem
*.rbc
.bundle
.config .config
coverage
InstalledFiles
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
# YARD artifacts
.yardoc
_yardoc
doc/
tests/coverage tests/coverage
config.yml config.yml
.DS_Store .DS_Store
@ -30,8 +14,7 @@ files/map.txt
.sass-cache/* .sass-cache/*
files/sslsites.zip files/sslsites.zip
.tm_properties .tm_properties
./black_box.rb
.vagrant .vagrant
public/banned_sites public/banned_sites
public/deleted_sites public/deleted_sites
tests/stat_logs/* Gemfile.lock

View file

@ -1,7 +1,10 @@
language: ruby language: ruby
rvm: rvm:
- "2.1.1" - "2.3.0"
- "2.2.3"
addons: addons:
postgresql: "9.3" postgresql: "9.3"
before_script: before_script:
- psql -c 'create database travis_ci_test;' -U postgres - psql -c 'create database travis_ci_test;' -U postgres
sudo: false
bundler_args: --jobs=1

13
Gemfile
View file

@ -15,8 +15,8 @@ gem 'mail'
gem 'google-api-client', require: 'google/api_client' gem 'google-api-client', require: 'google/api_client'
gem 'tilt' gem 'tilt'
gem 'erubis' gem 'erubis'
gem 'stripe' #, source: 'https://code.stripe.com/' gem 'stripe', '1.15.0' #, source: 'https://code.stripe.com/'
gem 'screencap' #gem 'screencap', '~> 0.1.4'
gem 'cocaine' gem 'cocaine'
gem 'zipruby' gem 'zipruby'
gem 'sass', require: nil gem 'sass', require: nil
@ -32,13 +32,17 @@ gem 'geoip'
gem 'io-extra', require: 'io/extra' gem 'io-extra', require: 'io/extra'
gem 'rye' gem 'rye'
gem 'dnsruby' gem 'dnsruby'
gem 'base32'
gem 'coveralls', require: false
gem 'sanitize'
gem 'will_paginate'
platform :mri, :rbx do platform :mri, :rbx do
gem 'magic' # sudo apt-get install file, For OSX: brew install libmagic gem 'magic' # sudo apt-get install file, For OSX: brew install libmagic
gem 'pg' gem 'pg'
gem 'sequel_pg', require: nil gem 'sequel_pg', require: nil
gem 'hiredis' gem 'hiredis'
gem 'rainbows', require: nil gem 'posix-spawn'
group :development, :test do group :development, :test do
gem 'pry' gem 'pry'
@ -77,10 +81,11 @@ group :test do
gem 'capybara_minitest_spec' gem 'capybara_minitest_spec'
gem 'rack_session_access', require: nil gem 'rack_session_access', require: nil
gem 'webmock', require: nil gem 'webmock', require: nil
gem 'stripe-ruby-mock', '~> 2.0.1', require: 'stripe_mock' gem 'stripe-ruby-mock', '2.0.1', require: 'stripe_mock'
gem 'timecop' gem 'timecop'
platform :mri, :rbx do platform :mri, :rbx do
gem 'simplecov', require: nil gem 'simplecov', require: nil
gem 'm'
end end
end end

View file

@ -1,324 +0,0 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (4.2.3)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.3.8)
ago (0.1.5)
annoy (0.5.6)
highline (>= 1.5.0)
ansi (1.5.0)
autoparse (0.3.3)
addressable (>= 2.3.1)
extlib (>= 0.9.15)
multi_json (>= 1.0.0)
bcrypt (3.1.10)
blankslate (3.1.3)
builder (3.2.2)
byebug (4.0.5)
columnize (= 0.9.0)
capybara (2.4.4)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
capybara_minitest_spec (1.0.5)
capybara (>= 2)
minitest (>= 4)
celluloid (0.16.0)
timers (~> 4.0.0)
climate_control (0.0.3)
activesupport (>= 3.0)
cliver (0.3.2)
cocaine (0.5.7)
climate_control (>= 0.0.3, < 1.0)
coderay (1.1.0)
columnize (0.9.0)
connection_pool (2.2.0)
crack (0.4.2)
safe_yaml (~> 1.0.0)
dante (0.2.0)
dav4rack (0.3.0)
nokogiri (>= 1.4.2)
rack (>= 1.1.0)
uuidtools (~> 2.1.1)
dnsruby (1.58.0)
docile (1.1.5)
domain_name (0.5.24)
unf (>= 0.0.5, < 1.0.0)
drydock (0.6.9)
erubis (2.7.0)
extlib (0.9.16)
fabrication (2.13.2)
faker (1.4.3)
i18n (~> 0.5)
faraday (0.9.1)
multipart-post (>= 1.2, < 3)
ffi (1.9.10)
ffi-compiler (0.1.3)
ffi (>= 1.0.0)
rake
filesize (0.1.0)
geoip (1.6.1)
google-api-client (0.8.6)
activesupport (>= 3.2)
addressable (~> 2.3)
autoparse (~> 0.3)
extlib (~> 0.9)
faraday (~> 0.9)
googleauth (~> 0.3)
launchy (~> 2.4)
multi_json (~> 1.10)
retriable (~> 1.4)
signet (~> 0.6)
googleauth (0.4.1)
faraday (~> 0.9)
jwt (~> 1.4)
logging (~> 2.0)
memoist (~> 0.12)
multi_json (= 1.11)
signet (~> 0.6)
highline (1.7.2)
hiredis (0.6.0)
hitimes (1.2.2)
http-cookie (1.0.2)
domain_name (~> 0.5)
i18n (0.7.0)
io-extra (1.2.8)
jimson-temp (0.9.5)
blankslate (>= 3.1.2)
multi_json (~> 1.0)
rack (~> 1.4)
rest-client (~> 1.0)
json (1.8.3)
jwt (1.5.1)
kgio (2.9.3)
launchy (2.4.3)
addressable (~> 2.3)
little-plugger (1.1.3)
logging (2.0.0)
little-plugger (~> 1.1)
multi_json (~> 1.10)
magic (0.2.9)
ffi (>= 0.6.3)
mail (2.6.3)
mime-types (>= 1.16, < 3)
memoist (0.12.0)
metaclass (0.0.4)
method_source (0.8.2)
mime-types (2.6.1)
mini_portile (0.6.2)
minitest (5.7.0)
minitest-reporters (1.0.18)
ansi
builder
minitest (>= 5.0)
ruby-progressbar
mocha (1.1.0)
metaclass (~> 0.0.1)
multi_json (1.11.0)
multipart-post (2.0.0)
net-scp (1.2.1)
net-ssh (>= 2.6.5)
net-ssh (2.9.2)
netrc (0.10.3)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
paypal-recurring (1.1.0)
pg (0.18.2)
phantomjs (1.9.8.0)
poltergeist (1.6.0)
capybara (~> 2.1)
cliver (~> 0.3.1)
multi_json (~> 1.0)
websocket-driver (>= 0.2.0)
pry (0.10.1)
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
pry-byebug (3.1.0)
byebug (~> 4.0)
pry (~> 0.10)
puma (2.11.3)
rack (>= 1.1, < 2.0)
rack (1.6.4)
rack-cache (1.2)
rack (>= 0.4)
rack-protection (1.5.3)
rack
rack-recaptcha (0.6.6)
json
rack-test (0.6.3)
rack (>= 1.0)
rack_session_access (0.1.1)
builder (>= 2.0.0)
rack (>= 1.0.0)
rainbows (4.6.2)
kgio (~> 2.5)
rack (~> 1.1)
unicorn (~> 4.8)
raindrops (0.14.0)
rake (10.4.2)
redis (3.2.1)
redis-namespace (1.5.2)
redis (~> 3.0, >= 3.0.4)
rest-client (1.8.0)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 3.0)
netrc (~> 0.7)
retriable (1.4.1)
rmagick (2.15.2)
ruby-progressbar (1.7.5)
rye (0.9.13)
annoy
docile (>= 1.0.1)
highline (>= 1.5.1)
net-scp (>= 1.0.2)
net-ssh (>= 2.0.13)
sysinfo (>= 0.8.1)
safe_yaml (1.0.4)
sass (3.4.16)
screencap (0.1.2)
phantomjs
scrypt (2.0.2)
ffi-compiler (>= 0.0.2)
rake
sequel (4.8.0)
sequel_pg (1.6.13)
pg (>= 0.8.0)
sequel (>= 3.39.0)
shotgun (0.9.1)
rack (>= 1.0)
sidekiq (3.4.1)
celluloid (~> 0.16.0)
connection_pool (>= 2.1.1)
json
redis (>= 3.0.6)
redis-namespace (>= 1.3.1)
signet (0.6.1)
addressable (~> 2.3)
extlib (~> 0.9)
faraday (~> 0.9)
jwt (~> 1.5)
multi_json (~> 1.10)
simplecov (0.10.0)
docile (~> 1.1.0)
json (~> 1.8)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
sinatra (1.4.6)
rack (~> 1.4)
rack-protection (~> 1.4)
tilt (>= 1.3, < 3)
sinatra-flash (0.3.0)
sinatra (>= 1.0.0)
sinatra-xsendfile (0.4.2)
sinatra (>= 0.9.1)
slop (3.6.0)
storable (0.8.9)
stripe (1.23.0)
json (~> 1.8.1)
rest-client (~> 1.4)
stripe-ruby-mock (2.0.5)
dante (>= 0.2.0)
jimson-temp
stripe (>= 1.15.0)
sysinfo (0.8.1)
drydock
storable
thread (0.2.1)
thread_safe (0.3.5)
tilt (2.0.1)
timecop (0.7.4)
timers (4.0.1)
hitimes
tzinfo (1.2.2)
thread_safe (~> 0.1)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.1)
unicorn (4.9.0)
kgio (~> 2.6)
rack
raindrops (~> 0.7)
uuidtools (2.1.5)
webmock (1.21.0)
addressable (>= 2.3.6)
crack (>= 0.3.2)
websocket-driver (0.6.1)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
xpath (2.0.0)
nokogiri (~> 1.3)
zipruby (0.3.6)
PLATFORMS
ruby
DEPENDENCIES
addressable
ago
bcrypt
capybara_minitest_spec
cocaine
dav4rack
dnsruby
erubis
fabrication
faker
filesize
geoip
google-api-client
hiredis
io-extra
jdbc-postgres
jruby-openssl
json
magic
mail
minitest
minitest-reporters
mocha
paypal-recurring
pg
poltergeist
pry
pry-byebug
puma
rack-cache
rack-recaptcha
rack-test
rack_session_access
rainbows
rake
redis
rest-client
rmagick
ruby-debug
rye
sass
screencap
scrypt
sequel (= 4.8.0)
sequel_pg
shotgun
sidekiq
simplecov
sinatra
sinatra-flash
sinatra-xsendfile
stripe
stripe-ruby-mock (~> 2.0.1)
thread
tilt
timecop
webmock
zipruby
BUNDLED WITH
1.10.2

View file

@ -1,6 +1,7 @@
# Neocities.org # Neocities.org
[![Build Status](https://travis-ci.org/neocities/neocities.png?branch=master)](https://travis-ci.org/neocities/neocities) [![Build Status](https://travis-ci.org/neocities/neocities.png?branch=master)](https://travis-ci.org/neocities/neocities)
[![Coverage Status](https://coveralls.io/repos/neocities/neocities/badge.svg?branch=master&service=github)](https://coveralls.io/github/neocities/neocities?branch=master)
The web site for Neocities! It's open source. Want a feature on the site? Send a pull request! The web site for Neocities! It's open source. Want a feature on the site? Send a pull request!

View file

@ -41,7 +41,7 @@ end
desc 'Update banned IPs list' desc 'Update banned IPs list'
task :update_blocked_ips => [:environment] do task :update_blocked_ips => [:environment] do
uri = URI.parse('http://www.stopforumspam.com/downloads/listed_ip_90.zip') uri = URI.parse('http://www.stopforumspam.com/downloads/listed_ip_90.zip')
blocked_ips_zip = Tempfile.new('blockedipszip', Dir.tmpdir, 'wb') blocked_ips_zip = Tempfile.new('blockedipszip', Dir.tmpdir)
blocked_ips_zip.binmode blocked_ips_zip.binmode
Net::HTTP.start(uri.host, uri.port) do |http| Net::HTTP.start(uri.host, uri.port) do |http|
@ -216,6 +216,73 @@ task :hash_ips => [:environment] do
end end
end end
desc 'prime_site_files'
task :prime_site_files => [:environment] do
Site.where(is_banned: false).where(is_deleted: false).select(:id, :username).all.each do |site|
Dir.glob(File.join(site.files_path, '**/*')).each do |file|
path = file.gsub(site.base_files_path, '').sub(/^\//, '')
site_file = site.site_files_dataset[path: path]
if site_file.nil?
mtime = File.mtime file
site_file_opts = {
path: path,
updated_at: mtime,
created_at: mtime
}
if File.directory? file
site_file_opts.merge! is_directory: true
else
site_file_opts.merge!(
size: File.size(file),
sha1_hash: Digest::SHA1.file(file).hexdigest
)
end
site.add_site_file site_file_opts
end
end
end
end
desc 'dedupe_follows'
task :dedupe_follows => [:environment] do
follows = Follow.all
deduped_follows = Follow.all.uniq {|f| "#{f.site_id}_#{f.actioning_site_id}"}
follows.each do |follow|
unless deduped_follows.include?(follow)
puts "deleting dedupe: #{follow.inspect}"
follow.delete
end
end
end
desc 'flush_empty_index_sites'
task :flush_empty_index_sites => [:environment] do
sites = Site.select(:id).all
counter = 0
sites.each do |site|
if site.empty_index?
counter += 1
site.site_changed = false
site.save_changes validate: false
end
end
puts "#{counter} sites set to not changed."
end
desc 'compute_scores'
task :compute_scores => [:environment] do
Site.compute_scores
end
=begin =begin
desc 'Update screenshots' desc 'Update screenshots'
task :update_screenshots => [:environment] do task :update_screenshots => [:environment] do
@ -224,3 +291,33 @@ task :update_screenshots => [:environment] do
} }
end end
=end =end
desc 'prime_classifier'
task :prime_classifier => [:environment] do
Site.select(:id, :username).where(is_banned: false, is_deleted: false).all.each do |site|
next if site.site_files_dataset.where(classifier: 'spam').count > 0
html_files = site.site_files_dataset.where(path: /\.html$/).all
html_files.each do |html_file|
print "training #{site.username}/#{html_file.path}..."
site.train html_file.path
print "done.\n"
end
end
end
desc 'train_spam'
task :train_spam => [:environment] do
paths = File.read('./spam.txt')
paths.split("\n").each do |path|
username, site_file_path = path.match(/^([a-zA-Z0-9_\-]+)\/(.+)$/i).captures
site = Site[username: username]
next if site.nil?
site_file = site.site_files_dataset.where(path: site_file_path).first
next if site_file.nil?
site.train site_file_path, :spam
site.ban!
puts "Deleted #{site_file_path}, banned #{site.username}"
end
end

View file

@ -11,6 +11,65 @@ get '/admin/reports' do
erb :'admin/reports' erb :'admin/reports'
end end
get '/admin/site/:username' do |username|
require_admin
@site = Site[username: username]
not_found if @site.nil?
@title = "Site Inspector - #{@site.username}"
erb :'admin/site'
end
post '/admin/reports' do
end
post '/admin/site_files/train' do
require_admin
site = Site[params[:site_id]]
site_file = site.site_files_dataset.where(path: params[:path]).first
not_found if site_file.nil?
site.untrain site_file.path
site.train site_file.path, params[:classifier]
'ok'
end
get '/admin/usage' do
require_admin
today = Date.today
current_month = Date.new today.year, today.month, 1
@monthly_stats = []
month = current_month
until month.year == 2015 && month.month == 1 do
stats = DB[
'select sum(views) as views, sum(hits) as hits, sum(bandwidth) as bandwidth from stats where created_at >= ? and created_at < ?',
month,
month.next_month].first
stats.keys.each do |key|
stats[key] ||= 0
end
stats.collect {|s| s == 0}.uniq
if stats[:views] != 0 && stats[:hits] != 0 && stats[:bandwidth] != 0
popular_sites = DB[
'select sum(bandwidth) as bandwidth,username from stats left join sites on sites.id=stats.site_id where stats.created_at >= ? and stats.created_at < ? group by username order by bandwidth desc limit 50',
month,
month.next_month
].all
@monthly_stats.push stats.merge(date: month).merge(popular_sites: popular_sites)
end
month = month.prev_month
end
erb :'admin/usage'
end
get '/admin/email' do get '/admin/email' do
require_admin require_admin
erb :'admin/email' erb :'admin/email'
@ -79,6 +138,11 @@ post '/admin/banhammer' do
site = Site[username: params[:username]] site = Site[username: params[:username]]
if !params[:classifier].empty?
site.untrain 'index.html'
site.train 'index.html', params[:classifier]
end
if site.nil? if site.nil?
flash[:error] = 'User not found' flash[:error] = 'User not found'
redirect '/admin' redirect '/admin'
@ -105,6 +169,7 @@ post '/admin/mark_nsfw' do
end end
site.is_nsfw = true site.is_nsfw = true
site.admin_nsfw = true
site.save_changes validate: false site.save_changes validate: false
flash[:success] = 'MISSION ACCOMPLISHED' flash[:success] = 'MISSION ACCOMPLISHED'

View file

@ -1,22 +1,7 @@
require 'net/http'
require 'uri'
get '/blog/?' do get '/blog/?' do
expires 60, :public, :must_revalidate redirect 'https://blog.neocities.org', 301
return Net::HTTP.get_response(URI('http://blog.neocities.org')).body
end end
get '/blog/:article' do |article| get '/blog/:article' do |article|
expires 60, :public, :must_revalidate redirect "https://blog.neocities.org/#{article}.html", 301
attempted = false
begin
return Net::HTTP.get_response(URI("http://blog.neocities.org/#{article}.html")).body
rescue => e
raise e if attempted
attempted = true
article = article.match(/^[a-zA-Z0-9-]+/).to_s
retry
end
end end

View file

@ -1,7 +1,7 @@
get '/browse/?' do get '/browse/?' do
@current_page = params[:current_page]
@current_page = @current_page.to_i @page = params[:page].to_i
@current_page = 1 if @current_page == 0 @page = 1 if @page == 0
params.delete 'tag' if params[:tag].nil? || params[:tag].strip.empty? params.delete 'tag' if params[:tag].nil? || params[:tag].strip.empty?
@ -11,12 +11,14 @@ get '/browse/?' do
site_dataset = browse_sites_dataset site_dataset = browse_sites_dataset
end end
site_dataset = site_dataset.paginate @current_page, Site::BROWSE_PAGINATION_LENGTH site_dataset = site_dataset.paginate @page, Site::BROWSE_PAGINATION_LENGTH
@page_count = site_dataset.page_count || 1 @pagination_dataset = site_dataset
@sites = site_dataset.all @sites = site_dataset.all
if params[:tag] if params[:tag]
@title = "Sites tagged #{params[:tag]}" @title = "Sites tagged #{params[:tag]}"
end end
erb :browse erb :browse
end end
@ -28,9 +30,12 @@ def education_sites_dataset
end end
def browse_sites_dataset def browse_sites_dataset
site_dataset = Site.filter(is_deleted: false, is_banned: false, is_crashing: false).filter(site_changed: true)
site_dataset = Site.browse_dataset
if current_site if current_site
site_dataset.or! sites__id: current_site.id
if !current_site.blocking_site_ids.empty? if !current_site.blocking_site_ids.empty?
site_dataset.where!(Sequel.~(Sequel.qualify(:sites, :id) => current_site.blocking_site_ids)) site_dataset.where!(Sequel.~(Sequel.qualify(:sites, :id) => current_site.blocking_site_ids))
end end
@ -43,6 +48,9 @@ def browse_sites_dataset
end end
case params[:sort_by] case params[:sort_by]
when 'special_sauce'
site_dataset.exclude! score: nil
site_dataset.order! :score.desc
when 'followers' when 'followers'
site_dataset = site_dataset.association_left_join :follows site_dataset = site_dataset.association_left_join :follows
site_dataset.select_all! :sites site_dataset.select_all! :sites
@ -89,8 +97,9 @@ def browse_sites_dataset
site_dataset.where! ['sites.is_nsfw = ?', (params[:is_nsfw] == 'true' ? true : false)] site_dataset.where! ['sites.is_nsfw = ?', (params[:is_nsfw] == 'true' ? true : false)]
if params[:tag] && params[:sort_by] != 'followers' if params[:tag]
site_dataset = site_dataset.association_join(:tags).select_all(:sites) site_dataset.inner_join! :sites_tags, :site_id => :id
site_dataset.inner_join! :tags, :id => :sites_tags__tag_id
site_dataset.where! ['tags.name = ?', params[:tag]] site_dataset.where! ['tags.name = ?', params[:tag]]
site_dataset.where! ['tags.is_nsfw = ?', (params[:is_nsfw] == 'true' ? true : false)] site_dataset.where! ['tags.is_nsfw = ?', (params[:is_nsfw] == 'true' ? true : false)]
end end

View file

@ -1,5 +1,5 @@
def new_recaptcha_valid? def new_recaptcha_valid?
return session[:captcha_valid] = true if ENV['RACK_ENV'] == 'test' return session[:captcha_valid] = true if ENV['RACK_ENV'] == 'test' || ENV['TRAVIS']
resp = Net::HTTP.get URI( resp = Net::HTTP.get URI(
'https://www.google.com/recaptcha/api/siteverify?'+ 'https://www.google.com/recaptcha/api/siteverify?'+
Rack::Utils.build_query( Rack::Utils.build_query(
@ -54,7 +54,15 @@ end
post '/create' do post '/create' do
content_type :json content_type :json
require_unbanned_ip
if banned?(true)
signout
session[:banned] = true if !session[:banned]
flash[:error] = 'There was an error, please <a href="/contact">contact support</a> to log in.'
redirect '/'
end
dashboard_if_signed_in dashboard_if_signed_in
@site = Site.new( @site = Site.new(

View file

@ -30,7 +30,7 @@ post '/dmca/contact' do
no_footer: true no_footer: true
}) })
flash[:success] = 'Your DCMA notification has been sent.' flash[:success] = 'Your DMCA notification has been sent.'
redirect '/' redirect '/'
end end
end end

View file

@ -6,23 +6,23 @@ get '/?' do
@suggestions = current_site.suggestions @suggestions = current_site.suggestions
@current_page = params[:current_page].to_i @page = params[:page].to_i
@current_page = 1 if @current_page == 0 @page = 1 if @page == 0
if params[:activity] == 'mine' if params[:activity] == 'mine'
events_dataset = current_site.latest_events(@current_page, 10) events_dataset = current_site.latest_events(@page, 10)
elsif params[:event_id] elsif params[:event_id]
event = Event.select(:id).where(id: params[:event_id]).first event = Event.select(:id).where(id: params[:event_id]).first
not_found if event.nil? not_found if event.nil?
not_found if event.is_deleted not_found if event.is_deleted
events_dataset = Event.where(id: params[:event_id]).paginate(1, 1) events_dataset = Event.where(id: params[:event_id]).paginate(1, 1)
elsif params[:activity] == 'global' elsif params[:activity] == 'global'
events_dataset = Event.global_dataset @current_page events_dataset = Event.global_dataset @page
else else
events_dataset = current_site.news_feed(@current_page, 10) events_dataset = current_site.news_feed(@page, 10)
end end
@page_count = events_dataset.page_count || 1 @pagination_dataset = events_dataset
@events = events_dataset.all @events = events_dataset.all
current_site.events_dataset.update notification_seen: true current_site.events_dataset.update notification_seen: true
@ -50,10 +50,6 @@ get '/education' do
erb :education, layout: :index_layout erb :education, layout: :index_layout
end end
get '/tutorials' do
erb :'tutorials'
end
get '/donate' do get '/donate' do
erb :'donate' erb :'donate'
end end
@ -82,3 +78,7 @@ end
get '/permanent-web' do get '/permanent-web' do
erb :'permanent_web' erb :'permanent_web'
end end
get '/thankyou' do
erb :'thankyou'
end

View file

@ -29,4 +29,9 @@ get '/stats_mockup' do
require_login require_login
erb :'stats_mockup', locals: {site: current_site} erb :'stats_mockup', locals: {site: current_site}
end end
get '/tutorial_mockup_c1p2' do
require_login
erb :'tutorial_mockup_c1p2', locals: {site: current_site}
end
# :nocov: # :nocov:

View file

@ -1,4 +0,0 @@
get '/search' do
erb :'search'
end

View file

@ -185,7 +185,7 @@ post '/settings/:username/change_name' do
end end
old_host = @site.host old_host = @site.host
old_file_paths = @site.file_list.collect {|f| f[:path]} old_site_file_paths = @site.site_files.collect {|site_file| site_file.path}
@site.username = params[:name] @site.username = params[:name]
@ -195,11 +195,11 @@ post '/settings/:username/change_name' do
@site.move_files_from old_username @site.move_files_from old_username
} }
old_file_paths.each do |file_path| old_site_file_paths.each do |site_file_path|
@site.purge_cache file_path @site.delete_cache site_file_path
end end
flash[:success] = "Site/user name has been changed. You will need to use this name to login, <b>don't forget it</b>." flash[:success] = "Site/user name has been changed. You will need to use this name to login, <b>don't forget it!</b>"
redirect "/settings/#{@site.username}#username" redirect "/settings/#{@site.username}#username"
else else
flash[:error] = @site.errors.first.last.first flash[:error] = @site.errors.first.last.first
@ -211,6 +211,8 @@ post '/settings/:username/change_nsfw' do
require_login require_login
require_ownership_for_settings require_ownership_for_settings
redirect "/settings/#{@site.username}" if @site.admin_nsfw == true
@site.is_nsfw = params[:is_nsfw] @site.is_nsfw = params[:is_nsfw]
@site.save_changes validate: false @site.save_changes validate: false
flash[:success] = @site.is_nsfw ? 'Marked 18+' : 'Unmarked 18+' flash[:success] = @site.is_nsfw ? 'Marked 18+' : 'Unmarked 18+'
@ -260,7 +262,7 @@ end
post '/settings/change_email' do post '/settings/change_email' do
require_login require_login
if params[:email] == parent_site.email if params[:email] == parent_site.email
flash[:error] = 'You are already using this email address for this account.' flash[:error] = 'You are already using this email address for this account.'
redirect '/settings#email' redirect '/settings#email'
@ -331,4 +333,30 @@ get '/settings/unsubscribe_email/?' do
@message = 'There was an error unsubscribing your email address. Please contact support.' @message = 'There was an error unsubscribing your email address. Please contact support.'
end end
erb :'settings/account/unsubscribe' erb :'settings/account/unsubscribe'
end end
post '/settings/update_card' do
require_login
customer = Stripe::Customer.retrieve current_site.stripe_customer_id
old_card_ids = customer.sources.collect {|s| s.id}
begin
customer.sources.create source: params[:stripe_token]
rescue Stripe::InvalidRequestError => e
if e.message.match /cannot use a.+token more than once/
flash[:error] = 'Card is already being used.'
redirect '/settings#billing'
else
raise e
end
end
old_card_ids.each do |card_id|
customer.sources.retrieve(card_id).delete
end
flash[:success] = 'Card information updated.'
redirect '/settings#billing'
end

View file

@ -13,9 +13,9 @@ get '/site/:username/?' do |username|
@title = site.title @title = site.title
@current_page = params[:current_page] @page = params[:page]
@current_page = @current_page.to_i @page = @page.to_i
@current_page = 1 if @current_page == 0 @page = 1 if @page == 0
if params[:event_id] if params[:event_id]
not_found unless params[:event_id].is_integer? not_found unless params[:event_id].is_integer?
@ -23,10 +23,11 @@ get '/site/:username/?' do |username|
not_found if event.nil? not_found if event.nil?
events_dataset = Event.where(id: params[:event_id]).paginate(1, 1) events_dataset = Event.where(id: params[:event_id]).paginate(1, 1)
else else
events_dataset = site.latest_events(@current_page, 10) events_dataset = site.latest_events(@page, 10)
end end
@page_count = events_dataset.page_count || 1 @page_count = events_dataset.page_count || 1
@pagination_dataset = events_dataset
@latest_events = events_dataset.all @latest_events = events_dataset.all
erb :'site', locals: {site: site, is_current_site: site == current_site} erb :'site', locals: {site: site, is_current_site: site == current_site}
@ -161,7 +162,6 @@ post '/site/create_directory' do
require_login require_login
path = "#{params[:dir] || ''}/#{params[:name]}" path = "#{params[:dir] || ''}/#{params[:name]}"
result = current_site.create_directory path result = current_site.create_directory path
if result != true if result != true

View file

@ -207,6 +207,10 @@ get '/site_files/allowed_types' do
erb :'site_files/allowed_types' erb :'site_files/allowed_types'
end end
get '/site_files/hotlinking' do
erb :'site_files/hotlinking'
end
get '/site_files/mount_info' do get '/site_files/mount_info' do
erb :'site_files/mount_info' erb :'site_files/mount_info'
end end

View file

@ -1,8 +1,8 @@
get '/surf/?' do get '/surf/?' do
@current_page = params[:current_page].to_i || 1 @page = params[:page].to_i || 1
params.delete 'tag' if params[:tag].nil? || params[:tag].strip.empty? params.delete 'tag' if params[:tag].nil? || params[:tag].strip.empty?
site_dataset = browse_sites_dataset site_dataset = browse_sites_dataset
site_dataset = site_dataset.paginate @current_page, 1 site_dataset = site_dataset.paginate @page, 1
@page_count = site_dataset.page_count || 1 @page_count = site_dataset.page_count || 1
@site = site_dataset.first @site = site_dataset.first
redirect "/browse?#{Rack::Utils.build_query params}" if @site.nil? redirect "/browse?#{Rack::Utils.build_query params}" if @site.nil?

45
app/tutorial.rb Normal file
View file

@ -0,0 +1,45 @@
def default_tutorial_html
<<-EOT.strip
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My web site</title>
</head>
<body>
Hello World!
</body>
</html>
EOT
end
get '/tutorials' do
erb :'tutorials'
end
get '/tutorial/?' do
require_login
erb :'tutorial/index'
end
get '/tutorial/:section/?' do
require_login
redirect "/tutorial/#{params[:section]}/1"
end
get '/tutorial/:section/:page/?' do
require_login
@page = params[:page]
not_found if @page.to_i == 0
not_found unless %w{html css js}.include?(params[:section])
@section = params[:section]
@title = "#{params[:section].upcase} Tutorial - #{@page}/10"
erb "tutorial/layout".to_sym
end

View file

@ -1,20 +1,10 @@
def kickstarter_days_remaining
ending = Time.parse('Sat, Jul 25 2015 3:05 PM PDT')
today = Time.now
remaining = ending - today
return 0 if remaining < 0
((ending - today) / 86400).to_i
end
def dashboard_if_signed_in def dashboard_if_signed_in
redirect '/dashboard' if signed_in? redirect '/dashboard' if signed_in?
end end
def require_login_ajax def require_login_ajax
halt 'You are not logged in!' unless signed_in? halt 'You are not logged in!' unless signed_in?
halt 'You are banned.' if current_site.is_banned? || parent_site.is_banned? halt 'Please contact support.' if banned?
end end
def csrf_safe? def csrf_safe?
@ -31,11 +21,7 @@ end
def require_login def require_login
redirect '/' unless signed_in? redirect '/' unless signed_in?
if session[:banned] || current_site.is_banned || parent_site.is_banned enforce_ban if banned?
signout
session[:banned] = true
redirect '/'
end
end end
def signed_in? def signed_in?
@ -52,15 +38,18 @@ def parent_site
current_site.parent? ? current_site : current_site.parent current_site.parent? ? current_site : current_site.parent
end end
def require_unbanned_ip def banned?(ip_check=false)
if session[:banned] || (is_banned_ip = Site.banned_ip?(request.ip)) return true if session[:banned]
signout return true if current_site && (current_site.is_banned || parent_site.is_banned)
session[:banned] = request.ip if !session[:banned]
flash[:error] = 'Site creation has been banned due to a Terms of Service violation from your location. '+ return true if ip_check && Site.banned_ip?(request.ip)
'If you believe this to be in error, <a href="/contact">contact the site admin</a>.' false
return {result: 'error'}.to_json end
end
def enforce_ban
signout
session[:banned] = true
redirect '/'
end end
def title def title

View file

@ -1,11 +1,6 @@
require 'rubygems' require 'rubygems'
require './app.rb' require './app.rb'
require 'sidekiq/web' require 'sidekiq/web'
require 'unicorn/preread_input'
if defined?(Unicorn)
use Unicorn::PrereadInput
end
map('/') do map('/') do
use(Rack::Cache, use(Rack::Cache,
@ -35,13 +30,18 @@ map '/webdav' do
end end
if Site.valid_file_type?(filename: path, tempfile: tmpfile) if Site.valid_file_type?(filename: path, tempfile: tmpfile)
site.store_file path, tmpfile site.store_files [{filename: path, tempfile: tmpfile}]
return [201, {}, ['']] return [201, {}, ['']]
else else
return [415, {}, ['']] return [415, {}, ['']]
end end
end end
if env['REQUEST_METHOD'] == 'MKCOL'
site.create_directory env['PATH_INFO']
return [201, {}, ['']]
end
if env['REQUEST_METHOD'] == 'MOVE' if env['REQUEST_METHOD'] == 'MOVE'
tmpfile = Tempfile.new 'moved_file' tmpfile = Tempfile.new 'moved_file'
tmpfile.close tmpfile.close
@ -51,7 +51,7 @@ map '/webdav' do
FileUtils.cp site.files_path(env['PATH_INFO']), tmpfile.path FileUtils.cp site.files_path(env['PATH_INFO']), tmpfile.path
DB.transaction do DB.transaction do
site.store_file destination, tmpfile site.store_files [{filename: destination, tempfile: tmpfile}]
site.delete_file env['PATH_INFO'] site.delete_file env['PATH_INFO']
end end

View file

@ -11,6 +11,8 @@ require 'logger'
Bundler.require Bundler.require
Bundler.require :development if ENV['RACK_ENV'] == 'development' Bundler.require :development if ENV['RACK_ENV'] == 'development'
require 'tilt/erubis'
Dir['./ext/**/*.rb'].each {|f| require f} Dir['./ext/**/*.rb'].each {|f| require f}
# :nocov: # :nocov:
@ -31,6 +33,8 @@ raise 'hash_ip_salt is required' unless $config['ip_hash_salt']
DB = Sequel.connect $config['database'], sslmode: 'disable', max_connections: $config['database_pool'] DB = Sequel.connect $config['database'], sslmode: 'disable', max_connections: $config['database_pool']
DB.extension :pagination DB.extension :pagination
require 'will_paginate/sequel'
# :nocov: # :nocov:
=begin =begin
if defined?(Pry) if defined?(Pry)
@ -61,6 +65,7 @@ end
# :nocov: # :nocov:
if ENV['RACK_ENV'] == 'development' if ENV['RACK_ENV'] == 'development'
# Run async jobs immediately in development. # Run async jobs immediately in development.
=begin
module Sidekiq module Sidekiq
module Worker module Worker
module ClassMethods module ClassMethods
@ -72,6 +77,7 @@ if ENV['RACK_ENV'] == 'development'
end end
end end
end end
=end
end end
# :nocov: # :nocov:

41
ext/base58.rb Normal file
View file

@ -0,0 +1,41 @@
module Base58
class << self
def int_to_base58(int_val, leading_zero_bytes=0)
alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
base58_val, base = '', alpha.size
while int_val > 0
int_val, remainder = int_val.divmod(base)
base58_val = alpha[remainder] + base58_val
end
base58_val
end
def base58_to_int(base58_val)
alpha = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
int_val, base = 0, alpha.size
base58_val.reverse.each_char.with_index do |char,index|
raise ArgumentError, 'Value not a valid Base58 String.' unless char_index = alpha.index(char)
int_val += char_index*(base**index)
end
int_val
end
def base58_to_bytestring(base58_val)
[Base58.decode_base58(base58_val)].pack('H*')
end
def encode_base58(hex)
leading_zero_bytes = (hex.match(/^([0]+)/) ? $1 : '').size / 2
("1"*leading_zero_bytes) + int_to_base58( hex.to_i(16) )
end
def decode_base58(base58_val)
s = base58_to_int(base58_val).to_s(16); s = (s.bytesize.odd? ? '0'+s : s)
s = '' if s == '00'
leading_zero_bytes = (base58_val.match(/^([1]+)/) ? $1 : '').size
s = ("00"*leading_zero_bytes) + s if leading_zero_bytes > 0
s
end
alias_method :base58_to_hex, :decode_base58
end
end

View file

@ -0,0 +1,56 @@
var page = require('webpage').create()
var system = require('system')
var maxTimeout = 15000
if (system.args.length === 1) {
console.log('required args: <siteURL> <outputFilePath>');
phantom.exit(1)
}
var address = system.args[1]
var outputPath = system.args[2]
page.viewportSize = { width: 1280, height: 960 }
page.clipRect = { top: 0, left: 0, width: 1280, height: 960}
/*
In development, not working yet.
page.settings.scriptTimeout = 1000
page.onLongRunningScript = function() {
page.stopJavaScript()
phantom.exit(4)
}
*/
var t = Date.now()
console.log('Loading ' + address)
setTimeout(function() {
console.log('timeout')
phantom.exit(62)
}, maxTimeout)
page.settings.resourceTimeout = maxTimeout
page.onResourceTimeout = function(e) {
console.log(e.errorCode)
console.log(e.errorString)
console.log(e.url)
phantom.exit(3)
}
page.open(address, function(status) {
if(status !== 'success') {
console.log('failed')
phantom.exit(2)
}
page.render(outputPath)
console.log('Loading time ' + (Date.now() - t) + ' msec');
phantom.exit()
})

View file

@ -0,0 +1,9 @@
Sequel.migration do
up {
DB.add_column :sites, :admin_nsfw, :boolean
}
down {
DB.drop_column :sites, :admin_nsfw
}
end

View file

@ -0,0 +1,12 @@
Sequel.migration do
up {
DB.create_table! :banned_referrers do
primary_key :id
String :name
end
}
down {
DB.drop_table :banned_referrers
}
end

View file

@ -0,0 +1,9 @@
Sequel.migration do
up {
DB.add_column :sites, :commenting_banned, :boolean, default: false
}
down {
DB.drop_column :sites, :commenting_banned
}
end

View file

@ -0,0 +1,9 @@
Sequel.migration do
up {
DB['alter table follows add constraint one_follow_per_site unique (site_id, actioning_site_id)'].first
}
down {
DB['alter table follows drop constraint one_follow_per_site'].first
}
end

View file

@ -0,0 +1,9 @@
Sequel.migration do
up {
DB.add_column :sites, :custom_max_space, :bigint, default: 0
}
down {
DB.drop_column :sites, :custom_max_space
}
end

View file

@ -0,0 +1,11 @@
# IT'S MADE OUT OF FUCKING PEOPLE
Sequel.migration do
up {
DB.add_column :sites, :score, :integer
}
down {
DB.drop_column :sites, :score
}
end

View file

@ -0,0 +1,13 @@
# IT'S MADE OUT OF FUCKING DECIMAL PEOPLE
Sequel.migration do
up {
DB.drop_column :sites, :score
DB.add_column :sites, :score, :decimal, default: 0
}
down {
DB.drop_column :sites, :score
DB.add_column :sites, :score, :integer
}
end

View file

@ -0,0 +1,9 @@
Sequel.migration do
up {
DB.add_index :sites, :score
}
down {
DB.drop_index :sites, :score
}
end

View file

@ -0,0 +1,17 @@
Sequel.migration do
up {
DB.create_table! :daily_site_stats do
primary_key :id
Date :created_at, index: true
Integer :hits, default: 0
Integer :views, default: 0
Integer :comments, default: 0
Integer :follows, default: 0
Integer :site_updates, default: 0
end
}
down {
DB.drop_table :daily_site_stats
}
end

View file

@ -0,0 +1,9 @@
Sequel.migration do
up {
DB.add_column :daily_site_stats, :bandwidth, :integer
}
down {
DB.drop_column :daily_site_stats, :bandwidth
}
end

View file

@ -0,0 +1,11 @@
Sequel.migration do
up {
DB.drop_column :daily_site_stats, :bandwidth
DB.add_column :daily_site_stats, :bandwidth, :integer, default: 0
}
down {
DB.drop_column :daily_site_stats, :bandwidth
DB.add_column :daily_site_stats, :bandwidth, :integer
}
end

View file

@ -0,0 +1,15 @@
Sequel.migration do
up {
alter_table(:stats) do
set_column_type :hits, Bignum
set_column_type :views, Bignum
end
}
down {
alter_table(:stats) do
set_column_type :hits, Integer
set_column_type :views, Integer
end
}
end

View file

@ -0,0 +1,19 @@
Sequel.migration do
up {
alter_table(:daily_site_stats) do
set_column_type :hits, Bignum
set_column_type :views, Bignum
set_column_type :bandwidth, Bignum
set_column_type :site_updates, Bignum
end
}
down {
alter_table(:daily_site_stats) do
set_column_type :hits, Integer
set_column_type :views, Integer
set_column_type :bandwidth, Integer
set_column_type :site_updates, Integer
end
}
end

View file

@ -0,0 +1,9 @@
Sequel.migration do
up {
DB.add_column :site_files, :classifier, :text, default: nil, index: true
}
down {
DB.drop_column :site_files, :classifier
}
end

View file

@ -1,9 +1,19 @@
require 'base32'
class Archive < Sequel::Model class Archive < Sequel::Model
many_to_one :site many_to_one :site
set_primary_key [:site_id, :ipfs_hash] set_primary_key [:site_id, :ipfs_hash]
unrestrict_primary_key unrestrict_primary_key
def self.base58_to_hshca(base58)
Base32.encode(Base58.base58_to_bytestring(base58)).gsub('=', '').downcase
end
def hshca_hash
self.class.base58_to_hshca ipfs_hash
end
def url def url
"https://#{ipfs_hash}.ipfs.neocities.org" "http://#{hshca_hash}.ipfs.neocitiesops.net"
end end
end end

View file

@ -0,0 +1,2 @@
class DailySiteStat < Sequel::Model
end

View file

@ -33,11 +33,11 @@ class Site < Sequel::Model
} }
VALID_EXTENSIONS = %w{ VALID_EXTENSIONS = %w{
html htm txt text css js jpg jpeg png gif svg md markdown eot ttf woff woff2 json geojson csv tsv mf ico pdf asc key pgp xml mid midi manifest otf webapp html htm txt text css js jpg jpeg png gif svg md markdown eot ttf woff woff2 json geojson csv tsv mf ico pdf asc key pgp xml mid midi manifest otf webapp less sass
} }
VALID_EDITABLE_EXTENSIONS = %w{ VALID_EDITABLE_EXTENSIONS = %w{
html htm txt js css md manifest html htm txt js css md manifest less
} }
MINIMUM_PASSWORD_LENGTH = 5 MINIMUM_PASSWORD_LENGTH = 5
@ -74,6 +74,8 @@ class Site < Sequel::Model
/PHP\.Hide/ /PHP\.Hide/
] ]
EMPTY_FILE_HASH = Digest::SHA1.hexdigest ''
PHISHING_FORM_REGEX = /www.formbuddy.com\/cgi-bin\/form.pl/i PHISHING_FORM_REGEX = /www.formbuddy.com\/cgi-bin\/form.pl/i
SPAM_MATCH_REGEX = ENV['RACK_ENV'] == 'test' ? /pillz/ : /#{$config['spam_smart_filter'].join('|')}/i SPAM_MATCH_REGEX = ENV['RACK_ENV'] == 'test' ? /pillz/ : /#{$config['spam_smart_filter'].join('|')}/i
EMAIL_SANITY_REGEX = /.+@.+\..+/i EMAIL_SANITY_REGEX = /.+@.+\..+/i
@ -103,7 +105,7 @@ class Site < Sequel::Model
custom_ssl_certificates: true, custom_ssl_certificates: true,
no_file_restrictions: true, no_file_restrictions: true,
custom_domains: true, custom_domains: true,
maximum_site_files: 25000 maximum_site_files: 50000
} }
PLAN_FEATURES[:free] = PLAN_FEATURES[:supporter].merge( PLAN_FEATURES[:free] = PLAN_FEATURES[:supporter].merge(
@ -115,7 +117,7 @@ class Site < Sequel::Model
custom_ssl_certificates: false, custom_ssl_certificates: false,
no_file_restrictions: false, no_file_restrictions: false,
custom_domains: false, custom_domains: false,
maximum_site_files: 1000 maximum_site_files: 2000
) )
def self.newsletter_sites def self.newsletter_sites
@ -294,6 +296,7 @@ class Site < Sequel::Model
end end
def banned_ip?(ip) def banned_ip?(ip)
return false if ENV['RACK_ENV'] == 'production' && ip == '127.0.0.1'
return true if Site.where(is_banned: true). return true if Site.where(is_banned: true).
where(ip: hash_ip(ip)). where(ip: hash_ip(ip)).
where(['updated_at > ?', Time.now-BANNED_TIME]). where(['updated_at > ?', Time.now-BANNED_TIME]).
@ -318,7 +321,7 @@ class Site < Sequel::Model
end end
def is_following?(site) def is_following?(site)
followings_dataset.select(:id).filter(site_id: site.id).first ? true : false followings_dataset.select(:follows__id).filter(site_id: site.id).first ? true : false
end end
def toggle_follow(site) def toggle_follow(site)
@ -417,7 +420,7 @@ class Site < Sequel::Model
end end
def get_file(path) def get_file(path)
File.read files_path(path) File.read current_files_path(path)
end end
def before_destroy def before_destroy
@ -456,8 +459,8 @@ class Site < Sequel::Model
FileUtils.mv files_path, File.join(BANNED_SITES_ROOT, username) FileUtils.mv files_path, File.join(BANNED_SITES_ROOT, username)
} }
file_list.each do |path| site_files.each do |site_file|
purge_cache path delete_cache site_file.path
end end
end end
@ -467,6 +470,16 @@ class Site < Sequel::Model
} }
end end
# Who this site follows
def followings_dataset
super.select_all(:follows).inner_join(:sites, :id=>:site_id).exclude(:sites__is_deleted => true).exclude(:sites__is_banned => true)
end
# Who this site is following
def follows_dataset
super.select_all(:follows).inner_join(:sites, :id=>:actioning_site_id).exclude(:sites__is_deleted => true).exclude(:sites__is_banned => true)
end
=begin =begin
def follows_dataset def follows_dataset
super.where(Sequel.~(site_id: blocking_site_ids)) super.where(Sequel.~(site_id: blocking_site_ids))
@ -485,6 +498,7 @@ class Site < Sequel::Model
=end =end
def commenting_allowed? def commenting_allowed?
return false if owner.commenting_banned == true
return true if owner.commenting_allowed return true if owner.commenting_allowed
if owner.supporter? if owner.supporter?
@ -579,12 +593,32 @@ class Site < Sequel::Model
# We gotta flush the dirname too if it's an index file. # We gotta flush the dirname too if it's an index file.
if relative_path != '' && relative_path.match(/\/$|index\.html?$/i) if relative_path != '' && relative_path.match(/\/$|index\.html?$/i)
PurgeCacheOrderWorker.perform_async username, relative_path PurgeCacheOrderWorker.perform_async username, relative_path
PurgeCacheOrderWorker.perform_async username, Pathname(relative_path).dirname.to_s
purge_file_path = Pathname(relative_path).dirname.to_s
PurgeCacheOrderWorker.perform_async username, '/?surf=1' if purge_file_path == '/'
PurgeCacheOrderWorker.perform_async username, purge_file_path
else else
PurgeCacheOrderWorker.perform_async username, relative_path PurgeCacheOrderWorker.perform_async username, relative_path
end end
end end
# TODO DRY this up
def delete_cache(path)
relative_path = path.gsub base_files_path, ''
DeleteCacheOrderWorker.perform_async username, relative_path
# We gotta flush the dirname too if it's an index file.
if relative_path != '' && relative_path.match(/\/$|index\.html?$/i)
purge_file_path = Pathname(relative_path).dirname.to_s
DeleteCacheOrderWorker.perform_async username, '/?surf=1' if purge_file_path == '/'
DeleteCacheOrderWorker.perform_async username, purge_file_path
end
end
Rye::Cmd.add_command :ipfs, nil, 'add', :r Rye::Cmd.add_command :ipfs, nil, 'add', :r
def add_to_ipfs def add_to_ipfs
@ -637,6 +671,32 @@ class Site < Sequel::Model
return 'Directory (or file) already exists.' return 'Directory (or file) already exists.'
end end
path_dirs = path.to_s.split('/').select {|p| ![nil, '.', ''].include?(p) }
path_site_file = ''
until path_dirs.empty?
if path_site_file == ''
path_site_file += path_dirs.shift
else
path_site_file += '/' + path_dirs.shift
end
raise ArgumentError, 'directory name cannot be empty' if path_site_file == ''
site_file = SiteFile.where(site_id: self.id, path: path_site_file).first
if site_file.nil?
SiteFile.create(
site_id: self.id,
path: path_site_file,
is_directory: true,
created_at: Time.now,
updated_at: Time.now
)
end
end
FileUtils.mkdir_p relative_path FileUtils.mkdir_p relative_path
true true
end end
@ -870,6 +930,12 @@ class Site < Sequel::Model
File.join TEMPLATE_ROOT, name File.join TEMPLATE_ROOT, name
end end
def current_base_files_path(name=username)
raise 'username missing' if name.nil? || name.empty?
return File.join BANNED_SITES_ROOT, name if is_banned
base_files_path name
end
def base_files_path(name=username) def base_files_path(name=username)
raise 'username missing' if name.nil? || name.empty? raise 'username missing' if name.nil? || name.empty?
File.join SITE_FILES_ROOT, name File.join SITE_FILES_ROOT, name
@ -880,7 +946,7 @@ class Site < Sequel::Model
path ||= '' path ||= ''
clean = [] clean = []
parts = path.split '/' parts = path.to_s.split '/'
parts.each do |part| parts.each do |part|
next if part.empty? || part == '.' next if part.empty? || part == '.'
@ -890,6 +956,10 @@ class Site < Sequel::Model
clean.join '/' clean.join '/'
end end
def current_files_path(path='')
File.join current_base_files_path, scrubbed_path(path)
end
def files_path(path='') def files_path(path='')
File.join base_files_path, scrubbed_path(path) File.join base_files_path, scrubbed_path(path)
end end
@ -904,9 +974,17 @@ class Site < Sequel::Model
is_root_index: file_path == "#{base_files_path}/index.html" is_root_index: file_path == "#{base_files_path}/index.html"
} }
site_file = site_files_dataset.where(path: file_path.gsub(base_files_path, '').sub(/^\//, '')).first
if site_file
file[:size] = site_file.size unless file[:is_directory]
file[:updated_at] = site_file.updated_at
end
file[:is_html] = !(file[:ext].match HTML_REGEX).nil? file[:is_html] = !(file[:ext].match HTML_REGEX).nil?
file[:is_image] = !(file[:ext].match IMAGE_REGEX).nil? file[:is_image] = !(file[:ext].match IMAGE_REGEX).nil?
file[:is_editable] = !(file[:ext].match EDITABLE_FILE_EXT).nil? file[:is_editable] = !(file[:ext].match EDITABLE_FILE_EXT).nil?
file file
end end
@ -920,8 +998,16 @@ class Site < Sequel::Model
end end
def actual_space_used def actual_space_used
space = Dir.glob(File.join(files_path, '*')).collect {|p| File.size(p)}.inject {|sum,x| sum += x} space = 0
space.nil? ? 0 : space
files = Dir.glob File.join(files_path, '**', '*')
files.each do |file|
next if File.directory? file
space += File.size file
end
space
end end
def total_space_used def total_space_used
@ -936,7 +1022,11 @@ class Site < Sequel::Model
end end
def maximum_space def maximum_space
PLAN_FEATURES[(parent? ? self : parent).plan_type.to_sym][:space] plan_space = PLAN_FEATURES[(parent? ? self : parent).plan_type.to_sym][:space]
return custom_max_space if custom_max_space > plan_space
plan_space
end end
def space_percentage_used def space_percentage_used
@ -956,6 +1046,10 @@ class Site < Sequel::Model
PLAN_FEATURES[plan_type.to_sym][:name] PLAN_FEATURES[plan_type.to_sym][:name]
end end
def stripe_paying_supporter?
stripe_customer_id && !plan_ended && values[:plan_type].match(/free|special/).nil?
end
def unconverted_legacy_supporter? def unconverted_legacy_supporter?
stripe_customer_id && !plan_ended && values[:plan_type].nil? && stripe_subscription_id.nil? stripe_customer_id && !plan_ended && values[:plan_type].nil? && stripe_subscription_id.nil?
end end
@ -1028,13 +1122,70 @@ class Site < Sequel::Model
end end
end end
def self.compute_scores
select(:id, :username, :created_at, :updated_at, :views, :featured_at, :changed_count, :api_calls).exclude(is_banned: true).exclude(is_crashing: true).exclude(is_nsfw: true).exclude(updated_at: nil).where(site_changed: true).all.each do |s|
s.score = s.compute_score
s.save_changes validate: false
end
end
SCORE_GRAVITY = 1.8
def compute_score
points = 0
points += follows_dataset.count * 30
points += profile_comments_dataset.count * 1
points += views / 1000
points += 20 if !featured_at.nil?
# penalties
points = 0 if changed_count < 2
points = 0 if api_calls && api_calls > 1000
(points / ((Time.now - updated_at) / 7.days)**SCORE_GRAVITY).round(4)
end
=begin
def compute_score
score = 0
score += (Time.now - created_at) / 1.day
score -= ((Time.now - updated_at) / 1.day) * 2
score += 500 if (updated_at > 1.week.ago)
score -= 1000 if
follow_count = follows_dataset.count
score -= 1000 if follow_count == 0
score += follow_count * 100
score += profile_comments_dataset.count * 5
score += profile_commentings_dataset.count
score.to_i
end
=end
def self.browse_dataset
dataset.where is_deleted: false, is_banned: false, is_crashing: false, site_changed: true
end
def suggestions(limit=SUGGESTIONS_LIMIT, offset=0) def suggestions(limit=SUGGESTIONS_LIMIT, offset=0)
suggestions_dataset = Site.exclude(id: id).exclude(is_banned: true).exclude(is_nsfw: true).order(:views.desc, :updated_at.desc) suggestions_dataset = Site.exclude(id: id).exclude(is_banned: true).exclude(is_nsfw: true).order(:views.desc, :updated_at.desc)
suggestions = suggestions_dataset.where(tags: tags).limit(limit, offset).all suggestions = suggestions_dataset.where(tags: tags).limit(limit, offset).all
return suggestions if suggestions.length == limit return suggestions if suggestions.length == limit
suggestions += suggestions_dataset.where("views >= #{SUGGESTIONS_VIEWS_MIN}").limit(limit-suggestions.length).order(Sequel.lit('RANDOM()')).all # Old.
#suggestions += suggestions_dataset.where("views >= #{SUGGESTIONS_VIEWS_MIN}").limit(limit-suggestions.length).order(Sequel.lit('RANDOM()')).all
# New:
site_dataset = self.class.browse_dataset.association_left_join :follows
site_dataset.select_all! :sites
site_dataset.select_append! Sequel.lit("count(follows.site_id) AS follow_count")
site_dataset.group! :sites__id
site_dataset.order! :follow_count.desc, :updated_at.desc
site_dataset.where! "views >= #{SUGGESTIONS_VIEWS_MIN}"
site_dataset.limit! limit-suggestions.length
#site_dataset.order! Sequel.lit('RANDOM()')
suggestions += site_dataset.all
end end
def screenshot_path(path, resolution) def screenshot_path(path, resolution)
@ -1090,11 +1241,53 @@ class Site < Sequel::Model
end end
end end
def empty_index?
!site_files_dataset.where(path: /^\/?index.html$/).where(sha1_hash: EMPTY_FILE_HASH).first.nil?
end
def classify(path)
return nil unless classification_allowed? path
#$classifier.classify process_for_classification(path)
end
def classification_scores(path)
return nil unless classification_allowed? path
#$classifier.classification_scores process_for_classification(path)
end
def train(path, category='ham')
return nil unless classification_allowed? path
# $trainer.train(category, process_for_classification(path))
site_file = site_files_dataset.where(path: path).first
site_file.classifier = category
site_file.save_changes validate: false
end
def untrain(path, category='ham')
return nil unless classification_allowed? path
# $trainer.untrain(category, process_for_classification(path))
site_file = site_files_dataset.where(path: path).first
site_file.classifier = category
site_file.save_changes validate: false
end
def classification_allowed?(path)
site_file = site_files_dataset.where(path: path).first
return false if site_file.is_directory
return false if site_file.size > SiteFile::CLASSIFIER_LIMIT
return false if !path.match(/\.html$/)
true
end
def process_for_classification(path)
sanitized = Sanitize.fragment get_file(path)
sanitized.gsub(/(http|https):\/\//, '').gsub(/[^\w\s]/, '').downcase.split.uniq.select{|v| v.length < SiteFile::CLASSIFIER_WORD_LIMIT}.join(' ')
end
# array of hashes: filename, tempfile, opts. # array of hashes: filename, tempfile, opts.
def store_files(files, opts={}) def store_files(files, opts={})
results = [] results = []
new_size = 0 new_size = 0
html_uploaded = false
if too_many_files?(files.length) if too_many_files?(files.length)
results << false results << false
@ -1102,35 +1295,53 @@ class Site < Sequel::Model
end end
files.each do |file| files.each do |file|
html_uploaded = true if file[:filename].match HTML_REGEX
existing_size = 0 existing_size = 0
site_file = site_files_dataset.where(path: scrubbed_path(file[:filename])).first site_file = site_files_dataset.where(path: scrubbed_path(file[:filename])).first
if site_file if site_file
existing_size = site_file.size existing_size = site_file.size
end end
res = store_file(file[:filename], file[:tempfile], file[:opts] || opts) res = store_file(file[:filename], file[:tempfile], file[:opts] || opts)
if res == true if res == true
new_size -= existing_size new_size -= existing_size
new_size += file[:tempfile].size new_size += file[:tempfile].size
end end
results << res results << res
end end
if results.include? true && opts[:new_install] != true if results.include? true
time = Time.now
sql = DB["update sites set site_changed=?, site_updated_at=?, updated_at=?, changed_count=changed_count+1, space_used=space_used#{new_size < 0 ? new_size.to_s : '+'+new_size.to_s} where id=?", DB["update sites set space_used=space_used#{new_size < 0 ? new_size.to_s : '+'+new_size.to_s} where id=?", self.id].first
true,
time, if opts[:new_install] != true
time, if files.select {|f| f[:filename] =~ /^\/?index.html$/}.length > 0 || site_changed == true
self.id index_changed = true
] else
sql.first index_changed = false
end
index_changed = false if empty_index?
time = Time.now
sql = DB["update sites set site_changed=?, site_updated_at=?, updated_at=?, changed_count=changed_count+1 where id=?",
index_changed,
time,
time,
self.id
]
sql.first
ArchiveWorker.perform_in 24.hours, self.id
end
reload reload
#SiteChange.record self, relative_path unless opts[:new_install] #SiteChange.record self, relative_path unless opts[:new_install]
ArchiveWorker.perform_async self.id
end end
results results
@ -1138,36 +1349,9 @@ class Site < Sequel::Model
def delete_file(path) def delete_file(path)
return false if files_path(path) == files_path return false if files_path(path) == files_path
begin path = scrubbed_path path
FileUtils.rm files_path(path) site_file = site_files_dataset.where(path: path).first
rescue Errno::EISDIR site_file.destroy if site_file
site_files.each do |site_file|
if site_file.path.match /^#{path}\//
site_file.destroy
end
end
FileUtils.remove_dir files_path(path), true
rescue Errno::ENOENT
end
purge_cache path
ext = File.extname(path).gsub(/^./, '')
screenshots_delete(path) if ext.match HTML_REGEX
thumbnails_delete(path) if ext.match IMAGE_REGEX
path = path[1..path.length] if path[0] == '/'
DB.transaction do
site_file = site_files_dataset.where(path: path).first
if site_file
DB['update sites set space_used=space_used-? where id=?', site_file.size, self.id].first
site_file.delete
end
SiteChangeFile.filter(site_id: self.id, filename: path).delete
end
true true
end end
@ -1186,6 +1370,15 @@ class Site < Sequel::Model
return false return false
end end
if pathname.extname.match HTML_REGEX
# SPAM and phishing checking code goes here
end
relative_path_dir = Pathname(relative_path).dirname
create_directory relative_path_dir unless relative_path_dir == '.'
uploaded_size = uploaded.size
if relative_path == 'index.html' if relative_path == 'index.html'
begin begin
new_title = Nokogiri::HTML(File.read(uploaded.path)).css('title').first.text new_title = Nokogiri::HTML(File.read(uploaded.path)).css('title').first.text
@ -1198,18 +1391,6 @@ class Site < Sequel::Model
end end
end end
if pathname.extname.match HTML_REGEX
# SPAM and phishing checking code goes here
end
dirname = pathname.dirname.to_s
if !File.exists? dirname
FileUtils.mkdir_p dirname
end
uploaded_size = uploaded.size
FileUtils.cp uploaded.path, path FileUtils.cp uploaded.path, path
File.chmod 0640, path File.chmod 0640, path
@ -1227,11 +1408,11 @@ class Site < Sequel::Model
purge_cache path purge_cache path
if pathname.extname.match HTML_REGEX if pathname.extname.match HTML_REGEX
ScreenshotWorker.perform_async values[:username], relative_path ScreenshotWorker.perform_in 1.minute, values[:username], relative_path
elsif pathname.extname.match IMAGE_REGEX elsif pathname.extname.match IMAGE_REGEX
ThumbnailWorker.perform_async values[:username], relative_path ThumbnailWorker.perform_async values[:username], relative_path
end end
true true
end end
end end

View file

@ -1,5 +1,53 @@
require 'sanitize'
class SiteFile < Sequel::Model class SiteFile < Sequel::Model
CLASSIFIER_LIMIT = 1_000_000.freeze
CLASSIFIER_WORD_LIMIT = 25.freeze
unrestrict_primary_key unrestrict_primary_key
plugin :update_primary_key plugin :update_primary_key
many_to_one :site many_to_one :site
def before_destroy
if is_directory
site.site_files_dataset.where(path: /^#{path}\//, is_directory: true).all.each do |site_file|
begin
site_file.destroy
rescue Sequel::NoExistingObject
end
end
site.site_files_dataset.where(path: /^#{path}\//, is_directory: false).all.each do |site_file|
site_file.destroy
end
begin
FileUtils.remove_dir site.files_path(path)
rescue Errno::ENOENT
end
else
begin
FileUtils.rm site.files_path(path)
rescue Errno::ENOENT
end
ext = File.extname(path).gsub(/^./, '')
site.screenshots_delete(path) if ext.match Site::HTML_REGEX
site.thumbnails_delete(path) if ext.match Site::IMAGE_REGEX
end
super
end
def after_destroy
super
unless is_directory
DB['update sites set space_used=space_used-? where id=?', size, site_id].first
end
site.delete_cache site.files_path(path)
SiteChangeFile.filter(site_id: site_id, filename: path).delete
end
end end

View file

@ -15,8 +15,11 @@ class Stat < Sequel::Model
end end
def parse_logfiles(path) def parse_logfiles(path)
total_site_stats = {}
Dir["#{path}/*.log"].each do |log_path| Dir["#{path}/*.log"].each do |log_path|
site_logs = {} site_logs = {}
logfile = File.open log_path, 'r' logfile = File.open log_path, 'r'
while hit = logfile.gets while hit = logfile.gets
@ -26,9 +29,13 @@ class Stat < Sequel::Model
time, username, size, path, ip, referrer = hit_array time, username, size, path, ip, referrer = hit_array
log_time = Time.parse time
next if !referrer.nil? && referrer.match(/bot/i) next if !referrer.nil? && referrer.match(/bot/i)
site_logs[username] = { site_logs[log_time] = {} unless site_logs[log_time]
site_logs[log_time][username] = {
hits: 0, hits: 0,
views: 0, views: 0,
bandwidth: 0, bandwidth: 0,
@ -36,78 +43,111 @@ class Stat < Sequel::Model
ips: [], ips: [],
referrers: {}, referrers: {},
paths: {} paths: {}
} unless site_logs[username] } unless site_logs[log_time][username]
site_logs[username][:hits] += 1 total_site_stats[log_time] = {
site_logs[username][:bandwidth] += size.to_i hits: 0,
views: 0,
bandwidth: 0
} unless total_site_stats[log_time]
unless site_logs[username][:view_ips].include?(ip) site_logs[log_time][username][:hits] += 1
site_logs[username][:views] += 1 site_logs[log_time][username][:bandwidth] += size.to_i
site_logs[username][:view_ips] << ip
total_site_stats[log_time][:hits] += 1
total_site_stats[log_time][:bandwidth] += size.to_i
unless site_logs[log_time][username][:view_ips].include?(ip)
site_logs[log_time][username][:views] += 1
total_site_stats[log_time][:views] += 1
site_logs[log_time][username][:view_ips] << ip
if referrer != '-' && !referrer.nil? if referrer != '-' && !referrer.nil?
site_logs[username][:referrers][referrer] ||= 0 site_logs[log_time][username][:referrers][referrer] ||= 0
site_logs[username][:referrers][referrer] += 1 site_logs[log_time][username][:referrers][referrer] += 1
end end
end end
site_logs[username][:paths][path] ||= 0 site_logs[log_time][username][:paths][path] ||= 0
site_logs[username][:paths][path] += 1 site_logs[log_time][username][:paths][path] += 1
end end
logfile.close logfile.close
current_time = Time.now.utc
current_day_string = current_time.to_date.to_s
Site.select(:id, :username).where(username: site_logs.keys).all.each do |site|
site_logs[site.username][:id] = site.id
end
DB.transaction do DB.transaction do
site_logs.each do |username, site_log| site_logs.each do |log_time, usernames|
DB['update sites set hits=hits+?, views=views+? where username=?', Site.select(:id, :username).where(username: usernames.keys).all.each do |site|
site_log[:hits], site_logs[log_time][site.username][:id] = site.id
site_log[:views], end
username
usernames.each do |username, site_log|
DB['update sites set hits=hits+?, views=views+? where username=?',
site_log[:hits],
site_log[:views],
username
].first ].first
opts = {site_id: site_log[:id], created_at: current_day_string} opts = {site_id: site_log[:id], created_at: log_time.to_date.to_s}
stat = Stat.select(:id).where(opts).first stat = nil
DB[:stats].lock('EXCLUSIVE') { stat = Stat.create opts } if stat.nil?
DB[ DB[:stats].lock('EXCLUSIVE') {
'update stats set hits=hits+?, views=views+?, bandwidth=bandwidth+? where id=?', stat = Stat.select(:id).where(opts).first
site_log[:hits], stat = Stat.create opts if stat.nil?
site_log[:views], }
site_log[:bandwidth],
stat.id DB[
].first 'update stats set hits=hits+?, views=views+?, bandwidth=bandwidth+? where id=?',
site_log[:hits],
site_log[:views],
site_log[:bandwidth],
stat.id
].first
=begin =begin
site_log[:referrers].each do |referrer, views| site_log[:referrers].each do |referrer, views|
stat_referrer = StatReferrer.create_or_get site_log[:id], referrer stat_referrer = StatReferrer.create_or_get site_log[:id], referrer
DB['update stat_referrers set views=views+? where site_id=?', views, site_log[:id]].first DB['update stat_referrers set views=views+? where site_id=?', views, site_log[:id]].first
end end
site_log[:view_ips].each do |ip| site_log[:view_ips].each do |ip|
site_location = StatLocation.create_or_get site_log[:id], ip site_location = StatLocation.create_or_get site_log[:id], ip
next if site_location.nil? next if site_location.nil?
DB['update stat_locations set views=views+1 where id=?', site_location.id].first DB['update stat_locations set views=views+1 where id=?', site_location.id].first
end end
site_log[:paths].each do |path, views| site_log[:paths].each do |path, views|
site_path = StatPath.create_or_get site_log[:id], path site_path = StatPath.create_or_get site_log[:id], path
next if site_path.nil? next if site_path.nil?
DB['update stat_paths set views=views+? where id=?', views, site_path.id].first DB['update stat_paths set views=views+? where id=?', views, site_path.id].first
end end
=end =end
end
end end
end end
FileUtils.rm log_path FileUtils.rm log_path
end end
total_site_stats.each do |time, stats|
opts = {created_at: time.to_date.to_s}
DB[:stats].lock('EXCLUSIVE') {
stat = DailySiteStat.select(:id).where(opts).first
stat = DailySiteStat.create opts if stat.nil?
}
DB[
'update daily_site_stats set hits=hits+?, views=views+?, bandwidth=bandwidth+? where created_at=?',
stats[:hits],
stats[:views],
stats[:bandwidth],
time.to_date
].first
end
end end
end end
end end

BIN
public/cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -0,0 +1,108 @@
/*!
* Agate by Taufik Nurrohman <https://github.com/tovic>
* ----------------------------------------------------
*
* #ade5fc
* #a2fca2
* #c6b4f0
* #d36363
* #fcc28c
* #fc9b9b
* #ffa
* #fff
* #333
* #62c8f3
* #888
*
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #333;
color: white;
}
.hljs-name,
.hljs-strong {
font-weight: bold;
}
.hljs-code,
.hljs-emphasis {
font-style: italic;
}
.hljs-tag {
color: #62c8f3;
}
.hljs-variable,
.hljs-template-variable,
.hljs-selector-id,
.hljs-selector-class {
color: #ade5fc;
}
.hljs-string,
.hljs-bullet {
color: #a2fca2;
}
.hljs-type,
.hljs-title,
.hljs-section,
.hljs-attribute,
.hljs-quote,
.hljs-built_in,
.hljs-builtin-name {
color: #ffa;
}
.hljs-number,
.hljs-symbol,
.hljs-bullet {
color: #d36363;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal {
color: #fcc28c;
}
.hljs-comment,
.hljs-deletion,
.hljs-code {
color: #888;
}
.hljs-regexp,
.hljs-link {
color: #c6b4f0;
}
.hljs-meta {
color: #fc9b9b;
}
.hljs-deletion {
background-color: #fc9b9b;
color: #333;
}
.hljs-addition {
background-color: #a2fca2;
color: #333;
}
.hljs a {
color: inherit;
}
.hljs a:focus,
.hljs a:hover {
color: inherit;
text-decoration: underline;
}

View file

@ -0,0 +1,66 @@
/*
Date: 24 Fev 2015
Author: Pedro Oliveira <kanytu@gmail . com>
*/
.hljs {
color: #a9b7c6;
background: #282b2e;
display: block;
overflow-x: auto;
padding: 0.5em;
}
.hljs-number,
.hljs-literal,
.hljs-symbol,
.hljs-bullet {
color: #6897BB;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-deletion {
color: #cc7832;
}
.hljs-variable,
.hljs-template-variable,
.hljs-link {
color: #629755;
}
.hljs-comment,
.hljs-quote {
color: #808080;
}
.hljs-meta {
color: #bbb529;
}
.hljs-string,
.hljs-attribute,
.hljs-addition {
color: #6A8759;
}
.hljs-section,
.hljs-title,
.hljs-type {
color: #ffc66d;
}
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #e8bf6a;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,73 @@
/*
Date: 17.V.2011
Author: pumbur <pumbur@pumbur.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #222;
}
.hljs,
.hljs-subst {
color: #aaa;
}
.hljs-section {
color: #fff;
}
.hljs-comment,
.hljs-quote,
.hljs-meta {
color: #444;
}
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-regexp {
color: #ffcc33;
}
.hljs-number,
.hljs-addition {
color: #00cc66;
}
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-template-variable,
.hljs-attribute,
.hljs-link {
color: #32aaee;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #6644aa;
}
.hljs-title,
.hljs-variable,
.hljs-deletion,
.hljs-template-tag {
color: #bb1166;
}
.hljs-section,
.hljs-doctag,
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}

View file

@ -0,0 +1,45 @@
/*
Original style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: white;
color: black;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-symbol,
.hljs-bullet,
.hljs-section,
.hljs-addition,
.hljs-attribute,
.hljs-link {
color: #888;
}
.hljs-comment,
.hljs-quote,
.hljs-meta,
.hljs-deletion {
color: #ccc;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-section,
.hljs-name,
.hljs-type,
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}

View file

@ -0,0 +1,83 @@
/* Base16 Atelier Cave Dark - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Cave Comment */
.hljs-comment,
.hljs-quote {
color: #7e7887;
}
/* Atelier-Cave Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-regexp,
.hljs-link,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #be4678;
}
/* Atelier-Cave Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #aa573c;
}
/* Atelier-Cave Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #2a9292;
}
/* Atelier-Cave Blue */
.hljs-title,
.hljs-section {
color: #576ddb;
}
/* Atelier-Cave Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #955ae7;
}
.hljs-deletion,
.hljs-addition {
color: #19171c;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #be4678;
}
.hljs-addition {
background-color: #2a9292;
}
.hljs {
display: block;
overflow-x: auto;
background: #19171c;
color: #8b8792;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,85 @@
/* Base16 Atelier Cave Light - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Cave Comment */
.hljs-comment,
.hljs-quote {
color: #655f6d;
}
/* Atelier-Cave Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #be4678;
}
/* Atelier-Cave Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #aa573c;
}
/* Atelier-Cave Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #2a9292;
}
/* Atelier-Cave Blue */
.hljs-title,
.hljs-section {
color: #576ddb;
}
/* Atelier-Cave Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #955ae7;
}
.hljs-deletion,
.hljs-addition {
color: #19171c;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #be4678;
}
.hljs-addition {
background-color: #2a9292;
}
.hljs {
display: block;
overflow-x: auto;
background: #efecf4;
color: #585260;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,69 @@
/* Base16 Atelier Dune Dark - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Dune Comment */
.hljs-comment,
.hljs-quote {
color: #999580;
}
/* Atelier-Dune Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #d73737;
}
/* Atelier-Dune Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #b65611;
}
/* Atelier-Dune Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #60ac39;
}
/* Atelier-Dune Blue */
.hljs-title,
.hljs-section {
color: #6684e1;
}
/* Atelier-Dune Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #b854d4;
}
.hljs {
display: block;
overflow-x: auto;
background: #20201d;
color: #a6a28c;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,69 @@
/* Base16 Atelier Dune Light - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Dune Comment */
.hljs-comment,
.hljs-quote {
color: #7d7a68;
}
/* Atelier-Dune Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #d73737;
}
/* Atelier-Dune Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #b65611;
}
/* Atelier-Dune Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #60ac39;
}
/* Atelier-Dune Blue */
.hljs-title,
.hljs-section {
color: #6684e1;
}
/* Atelier-Dune Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #b854d4;
}
.hljs {
display: block;
overflow-x: auto;
background: #fefbec;
color: #6e6b5e;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,84 @@
/* Base16 Atelier Estuary Dark - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/estuary) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Estuary Comment */
.hljs-comment,
.hljs-quote {
color: #878573;
}
/* Atelier-Estuary Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #ba6236;
}
/* Atelier-Estuary Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #ae7313;
}
/* Atelier-Estuary Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #7d9726;
}
/* Atelier-Estuary Blue */
.hljs-title,
.hljs-section {
color: #36a166;
}
/* Atelier-Estuary Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #5f9182;
}
.hljs-deletion,
.hljs-addition {
color: #22221b;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #ba6236;
}
.hljs-addition {
background-color: #7d9726;
}
.hljs {
display: block;
overflow-x: auto;
background: #22221b;
color: #929181;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,84 @@
/* Base16 Atelier Estuary Light - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/estuary) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Estuary Comment */
.hljs-comment,
.hljs-quote {
color: #6c6b5a;
}
/* Atelier-Estuary Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #ba6236;
}
/* Atelier-Estuary Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #ae7313;
}
/* Atelier-Estuary Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #7d9726;
}
/* Atelier-Estuary Blue */
.hljs-title,
.hljs-section {
color: #36a166;
}
/* Atelier-Estuary Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #5f9182;
}
.hljs-deletion,
.hljs-addition {
color: #22221b;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #ba6236;
}
.hljs-addition {
background-color: #7d9726;
}
.hljs {
display: block;
overflow-x: auto;
background: #f4f3ec;
color: #5f5e4e;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,69 @@
/* Base16 Atelier Forest Dark - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Forest Comment */
.hljs-comment,
.hljs-quote {
color: #9c9491;
}
/* Atelier-Forest Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #f22c40;
}
/* Atelier-Forest Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #df5320;
}
/* Atelier-Forest Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #7b9726;
}
/* Atelier-Forest Blue */
.hljs-title,
.hljs-section {
color: #407ee7;
}
/* Atelier-Forest Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #6666ea;
}
.hljs {
display: block;
overflow-x: auto;
background: #1b1918;
color: #a8a19f;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,69 @@
/* Base16 Atelier Forest Light - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Forest Comment */
.hljs-comment,
.hljs-quote {
color: #766e6b;
}
/* Atelier-Forest Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #f22c40;
}
/* Atelier-Forest Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #df5320;
}
/* Atelier-Forest Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #7b9726;
}
/* Atelier-Forest Blue */
.hljs-title,
.hljs-section {
color: #407ee7;
}
/* Atelier-Forest Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #6666ea;
}
.hljs {
display: block;
overflow-x: auto;
background: #f1efee;
color: #68615e;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,69 @@
/* Base16 Atelier Heath Dark - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Heath Comment */
.hljs-comment,
.hljs-quote {
color: #9e8f9e;
}
/* Atelier-Heath Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #ca402b;
}
/* Atelier-Heath Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #a65926;
}
/* Atelier-Heath Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #918b3b;
}
/* Atelier-Heath Blue */
.hljs-title,
.hljs-section {
color: #516aec;
}
/* Atelier-Heath Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #7b59c0;
}
.hljs {
display: block;
overflow-x: auto;
background: #1b181b;
color: #ab9bab;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,69 @@
/* Base16 Atelier Heath Light - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Heath Comment */
.hljs-comment,
.hljs-quote {
color: #776977;
}
/* Atelier-Heath Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #ca402b;
}
/* Atelier-Heath Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #a65926;
}
/* Atelier-Heath Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #918b3b;
}
/* Atelier-Heath Blue */
.hljs-title,
.hljs-section {
color: #516aec;
}
/* Atelier-Heath Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #7b59c0;
}
.hljs {
display: block;
overflow-x: auto;
background: #f7f3f7;
color: #695d69;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,69 @@
/* Base16 Atelier Lakeside Dark - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Lakeside Comment */
.hljs-comment,
.hljs-quote {
color: #7195a8;
}
/* Atelier-Lakeside Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #d22d72;
}
/* Atelier-Lakeside Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #935c25;
}
/* Atelier-Lakeside Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #568c3b;
}
/* Atelier-Lakeside Blue */
.hljs-title,
.hljs-section {
color: #257fad;
}
/* Atelier-Lakeside Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #6b6bb8;
}
.hljs {
display: block;
overflow-x: auto;
background: #161b1d;
color: #7ea2b4;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,69 @@
/* Base16 Atelier Lakeside Light - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Lakeside Comment */
.hljs-comment,
.hljs-quote {
color: #5a7b8c;
}
/* Atelier-Lakeside Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #d22d72;
}
/* Atelier-Lakeside Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #935c25;
}
/* Atelier-Lakeside Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #568c3b;
}
/* Atelier-Lakeside Blue */
.hljs-title,
.hljs-section {
color: #257fad;
}
/* Atelier-Lakeside Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #6b6bb8;
}
.hljs {
display: block;
overflow-x: auto;
background: #ebf8ff;
color: #516d7b;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,84 @@
/* Base16 Atelier Plateau Dark - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/plateau) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Plateau Comment */
.hljs-comment,
.hljs-quote {
color: #7e7777;
}
/* Atelier-Plateau Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #ca4949;
}
/* Atelier-Plateau Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #b45a3c;
}
/* Atelier-Plateau Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #4b8b8b;
}
/* Atelier-Plateau Blue */
.hljs-title,
.hljs-section {
color: #7272ca;
}
/* Atelier-Plateau Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #8464c4;
}
.hljs-deletion,
.hljs-addition {
color: #1b1818;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #ca4949;
}
.hljs-addition {
background-color: #4b8b8b;
}
.hljs {
display: block;
overflow-x: auto;
background: #1b1818;
color: #8a8585;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,84 @@
/* Base16 Atelier Plateau Light - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/plateau) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Plateau Comment */
.hljs-comment,
.hljs-quote {
color: #655d5d;
}
/* Atelier-Plateau Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #ca4949;
}
/* Atelier-Plateau Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #b45a3c;
}
/* Atelier-Plateau Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #4b8b8b;
}
/* Atelier-Plateau Blue */
.hljs-title,
.hljs-section {
color: #7272ca;
}
/* Atelier-Plateau Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #8464c4;
}
.hljs-deletion,
.hljs-addition {
color: #1b1818;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #ca4949;
}
.hljs-addition {
background-color: #4b8b8b;
}
.hljs {
display: block;
overflow-x: auto;
background: #f4ecec;
color: #585050;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,84 @@
/* Base16 Atelier Savanna Dark - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/savanna) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Savanna Comment */
.hljs-comment,
.hljs-quote {
color: #78877d;
}
/* Atelier-Savanna Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #b16139;
}
/* Atelier-Savanna Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #9f713c;
}
/* Atelier-Savanna Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #489963;
}
/* Atelier-Savanna Blue */
.hljs-title,
.hljs-section {
color: #478c90;
}
/* Atelier-Savanna Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #55859b;
}
.hljs-deletion,
.hljs-addition {
color: #171c19;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #b16139;
}
.hljs-addition {
background-color: #489963;
}
.hljs {
display: block;
overflow-x: auto;
background: #171c19;
color: #87928a;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,84 @@
/* Base16 Atelier Savanna Light - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/savanna) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Savanna Comment */
.hljs-comment,
.hljs-quote {
color: #5f6d64;
}
/* Atelier-Savanna Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #b16139;
}
/* Atelier-Savanna Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #9f713c;
}
/* Atelier-Savanna Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #489963;
}
/* Atelier-Savanna Blue */
.hljs-title,
.hljs-section {
color: #478c90;
}
/* Atelier-Savanna Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #55859b;
}
.hljs-deletion,
.hljs-addition {
color: #171c19;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #b16139;
}
.hljs-addition {
background-color: #489963;
}
.hljs {
display: block;
overflow-x: auto;
background: #ecf4ee;
color: #526057;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,69 @@
/* Base16 Atelier Seaside Dark - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Seaside Comment */
.hljs-comment,
.hljs-quote {
color: #809980;
}
/* Atelier-Seaside Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #e6193c;
}
/* Atelier-Seaside Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #87711d;
}
/* Atelier-Seaside Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #29a329;
}
/* Atelier-Seaside Blue */
.hljs-title,
.hljs-section {
color: #3d62f5;
}
/* Atelier-Seaside Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #ad2bee;
}
.hljs {
display: block;
overflow-x: auto;
background: #131513;
color: #8ca68c;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,69 @@
/* Base16 Atelier Seaside Light - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Seaside Comment */
.hljs-comment,
.hljs-quote {
color: #687d68;
}
/* Atelier-Seaside Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #e6193c;
}
/* Atelier-Seaside Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #87711d;
}
/* Atelier-Seaside Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #29a329;
}
/* Atelier-Seaside Blue */
.hljs-title,
.hljs-section {
color: #3d62f5;
}
/* Atelier-Seaside Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #ad2bee;
}
.hljs {
display: block;
overflow-x: auto;
background: #f4fbf4;
color: #5e6e5e;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,69 @@
/* Base16 Atelier Sulphurpool Dark - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Sulphurpool Comment */
.hljs-comment,
.hljs-quote {
color: #898ea4;
}
/* Atelier-Sulphurpool Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #c94922;
}
/* Atelier-Sulphurpool Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #c76b29;
}
/* Atelier-Sulphurpool Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #ac9739;
}
/* Atelier-Sulphurpool Blue */
.hljs-title,
.hljs-section {
color: #3d8fd1;
}
/* Atelier-Sulphurpool Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #6679cc;
}
.hljs {
display: block;
overflow-x: auto;
background: #202746;
color: #979db4;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,69 @@
/* Base16 Atelier Sulphurpool Light - Theme */
/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool) */
/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
/* Atelier-Sulphurpool Comment */
.hljs-comment,
.hljs-quote {
color: #6b7394;
}
/* Atelier-Sulphurpool Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #c94922;
}
/* Atelier-Sulphurpool Orange */
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #c76b29;
}
/* Atelier-Sulphurpool Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #ac9739;
}
/* Atelier-Sulphurpool Blue */
.hljs-title,
.hljs-section {
color: #3d8fd1;
}
/* Atelier-Sulphurpool Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #6679cc;
}
.hljs {
display: block;
overflow-x: auto;
background: #f5f7ff;
color: #5e6687;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,64 @@
/*
Brown Paper style from goldblog.com.ua (c) Zaripov Yura <yur4ik7@ukr.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background:#b7a68e url(./brown-papersq.png);
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal {
color:#005599;
font-weight:bold;
}
.hljs,
.hljs-subst {
color: #363c69;
}
.hljs-string,
.hljs-title,
.hljs-section,
.hljs-type,
.hljs-attribute,
.hljs-symbol,
.hljs-bullet,
.hljs-built_in,
.hljs-addition,
.hljs-variable,
.hljs-template-tag,
.hljs-template-variable,
.hljs-link,
.hljs-name {
color: #2c009f;
}
.hljs-comment,
.hljs-quote,
.hljs-meta,
.hljs-deletion {
color: #802022;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-doctag,
.hljs-title,
.hljs-section,
.hljs-type,
.hljs-name,
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -0,0 +1,60 @@
/*
codepen.io Embed Theme
Author: Justin Perry <http://github.com/ourmaninamsterdam>
Original theme - https://github.com/chriskempson/tomorrow-theme
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #222;
color: #fff;
}
.hljs-comment,
.hljs-quote {
color: #777;
}
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-regexp,
.hljs-meta,
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-params,
.hljs-symbol,
.hljs-bullet,
.hljs-link,
.hljs-deletion {
color: #ab875d;
}
.hljs-section,
.hljs-title,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-type,
.hljs-attribute {
color: #9b869b;
}
.hljs-string,
.hljs-keyword,
.hljs-selector-tag,
.hljs-addition {
color: #8f9c6c;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,71 @@
/*
Colorbrewer theme
Original: https://github.com/mbostock/colorbrewer-theme (c) Mike Bostock <mike@ocks.org>
Ported by Fabrício Tavares de Oliveira
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #fff;
}
.hljs,
.hljs-subst {
color: #000;
}
.hljs-string,
.hljs-meta,
.hljs-symbol,
.hljs-template-tag,
.hljs-template-variable,
.hljs-addition {
color: #756bb1;
}
.hljs-comment,
.hljs-quote {
color: #636363;
}
.hljs-number,
.hljs-regexp,
.hljs-literal,
.hljs-bullet,
.hljs-link {
color: #31a354;
}
.hljs-deletion,
.hljs-variable {
color: #88f;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-title,
.hljs-section,
.hljs-built_in,
.hljs-doctag,
.hljs-type,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-strong {
color: #3182bd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-attribute {
color: #e6550d;
}

View file

@ -0,0 +1,63 @@
/*
Dark style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #444;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-section,
.hljs-link {
color: white;
}
.hljs,
.hljs-subst {
color: #ddd;
}
.hljs-string,
.hljs-title,
.hljs-name,
.hljs-type,
.hljs-attribute,
.hljs-symbol,
.hljs-bullet,
.hljs-built_in,
.hljs-addition,
.hljs-variable,
.hljs-template-tag,
.hljs-template-variable {
color: #d88;
}
.hljs-comment,
.hljs-quote,
.hljs-deletion,
.hljs-meta {
color: #777;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-title,
.hljs-section,
.hljs-doctag,
.hljs-type,
.hljs-name,
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}

View file

@ -0,0 +1,74 @@
/*
Darkula color scheme from the JetBrains family of IDEs
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #2b2b2b;
}
.hljs {
color: #bababa;
}
.hljs-strong,
.hljs-emphasis {
color: #a8a8a2;
}
.hljs-bullet,
.hljs-quote,
.hljs-link,
.hljs-number,
.hljs-regexp,
.hljs-literal {
color: #6896ba;
}
.hljs-code,
.hljs-selector-class {
color: #a6e22e;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-section,
.hljs-attribute,
.hljs-name,
.hljs-variable {
color: #cb7832;
}
.hljs-params {
color: #b9b9b9;
}
.hljs-string,
.hljs-subst,
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-symbol,
.hljs-selector-id,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-template-tag,
.hljs-template-variable,
.hljs-addition {
color: #e0c46c;
}
.hljs-comment,
.hljs-deletion,
.hljs-meta {
color: #7f7f7f;
}

View file

@ -0,0 +1,77 @@
/*
Original highlight.js style (c) Ivan Sagalaev <maniac@softwaremaniacs.org>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #F0F0F0;
}
.hljs,
.hljs-subst {
color: #444;
}
.hljs-keyword,
.hljs-attribute,
.hljs-selector-tag,
.hljs-meta-keyword,
.hljs-doctag,
.hljs-name {
font-weight: bold;
}
.hljs-built_in,
.hljs-literal,
.hljs-bullet,
.hljs-code,
.hljs-addition {
color: #1F811F;
}
.hljs-regexp,
.hljs-symbol,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #BC6060;
}
.hljs-type,
.hljs-string,
.hljs-number,
.hljs-selector-id,
.hljs-selector-class,
.hljs-quote,
.hljs-template-tag,
.hljs-deletion {
color: #880000;
}
.hljs-title,
.hljs-section {
color: #880000;
font-weight: bold;
}
.hljs-comment {
color: #888888;
}
.hljs-meta {
color: #2B6EA1;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,97 @@
/*
Docco style used in http://jashkenas.github.com/docco/ converted by Simon Madine (@thingsinjars)
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #000;
background: #f8f8ff;
}
.hljs-comment,
.hljs-quote {
color: #408080;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-subst {
color: #954121;
}
.hljs-number {
color: #40a070;
}
.hljs-string,
.hljs-doctag {
color: #219161;
}
.hljs-selector-id,
.hljs-selector-class,
.hljs-section,
.hljs-type {
color: #19469d;
}
.hljs-params {
color: #00f;
}
.hljs-title {
color: #458;
font-weight: bold;
}
.hljs-tag,
.hljs-name,
.hljs-attribute {
color: #000080;
font-weight: normal;
}
.hljs-variable,
.hljs-template-variable {
color: #008080;
}
.hljs-regexp,
.hljs-link {
color: #b68;
}
.hljs-symbol,
.hljs-bullet {
color: #990073;
}
.hljs-built_in,
.hljs-builtin-name {
color: #0086b3;
}
.hljs-meta {
color: #999;
font-weight: bold;
}
.hljs-deletion {
background: #fdd;
}
.hljs-addition {
background: #dfd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,71 @@
/*
FAR Style (c) MajestiC <majestic2k@gmail.com>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #000080;
}
.hljs,
.hljs-subst {
color: #0ff;
}
.hljs-string,
.hljs-attribute,
.hljs-symbol,
.hljs-bullet,
.hljs-built_in,
.hljs-builtin-name,
.hljs-template-tag,
.hljs-template-variable,
.hljs-addition {
color: #ff0;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-section,
.hljs-type,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-variable {
color: #fff;
}
.hljs-comment,
.hljs-quote,
.hljs-doctag,
.hljs-deletion {
color: #888;
}
.hljs-number,
.hljs-regexp,
.hljs-literal,
.hljs-link {
color: #0f0;
}
.hljs-meta {
color: #008080;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-title,
.hljs-section,
.hljs-name,
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}

View file

@ -0,0 +1,88 @@
/*
Description: Foundation 4 docs style for highlight.js
Author: Dan Allen <dan.j.allen@gmail.com>
Website: http://foundation.zurb.com/docs/
Version: 1.0
Date: 2013-04-02
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #eee; color: black;
}
.hljs-link,
.hljs-emphasis,
.hljs-attribute,
.hljs-addition {
color: #070;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong,
.hljs-string,
.hljs-deletion {
color: #d14;
}
.hljs-strong {
font-weight: bold;
}
.hljs-quote,
.hljs-comment {
color: #998;
font-style: italic;
}
.hljs-section,
.hljs-title {
color: #900;
}
.hljs-class .hljs-title,
.hljs-type {
color: #458;
}
.hljs-variable,
.hljs-template-variable {
color: #336699;
}
.hljs-bullet {
color: #997700;
}
.hljs-meta {
color: #3344bb;
}
.hljs-code,
.hljs-number,
.hljs-literal,
.hljs-keyword,
.hljs-selector-tag {
color: #099;
}
.hljs-regexp {
background-color: #fff0ff;
color: #880088;
}
.hljs-symbol {
color: #990073;
}
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #007700;
}

View file

@ -0,0 +1,71 @@
/**
* GitHub Gist Theme
* Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro
*/
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}

View file

@ -0,0 +1,99 @@
/*
github.com style (c) Vasily Polovnyov <vast@whiteants.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
}
.hljs-comment,
.hljs-quote {
color: #998;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
color: #333;
font-weight: bold;
}
.hljs-number,
.hljs-literal,
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
color: #008080;
}
.hljs-string,
.hljs-doctag {
color: #d14;
}
.hljs-title,
.hljs-section,
.hljs-selector-id {
color: #900;
font-weight: bold;
}
.hljs-subst {
font-weight: normal;
}
.hljs-type,
.hljs-class .hljs-title {
color: #458;
font-weight: bold;
}
.hljs-tag,
.hljs-name,
.hljs-attribute {
color: #000080;
font-weight: normal;
}
.hljs-regexp,
.hljs-link {
color: #009926;
}
.hljs-symbol,
.hljs-bullet {
color: #990073;
}
.hljs-built_in,
.hljs-builtin-name {
color: #0086b3;
}
.hljs-meta {
color: #999;
font-weight: bold;
}
.hljs-deletion {
background: #fdd;
}
.hljs-addition {
background: #dfd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,89 @@
/*
Google Code style (c) Aahan Krish <geekpanth3r@gmail.com>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: white;
color: black;
}
.hljs-comment,
.hljs-quote {
color: #800;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-section,
.hljs-title,
.hljs-name {
color: #008;
}
.hljs-variable,
.hljs-template-variable {
color: #660;
}
.hljs-string,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-regexp {
color: #080;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-meta,
.hljs-number,
.hljs-link {
color: #066;
}
.hljs-title,
.hljs-doctag,
.hljs-type,
.hljs-attr,
.hljs-built_in,
.hljs-builtin-name,
.hljs-params {
color: #606;
}
.hljs-attribute,
.hljs-subst {
color: #000;
}
.hljs-formula {
background-color: #eee;
font-style: italic;
}
.hljs-selector-id,
.hljs-selector-class {
color: #9B703F
}
.hljs-addition {
background-color: #baeeba;
}
.hljs-deletion {
background-color: #ffc8bd;
}
.hljs-doctag,
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}

View file

@ -0,0 +1,101 @@
/*
grayscale style (c) MY Sun <simonmysun@gmail.com>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #fff;
}
.hljs-comment,
.hljs-quote {
color: #777;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
color: #333;
font-weight: bold;
}
.hljs-number,
.hljs-literal {
color: #777;
}
.hljs-string,
.hljs-doctag,
.hljs-formula {
color: #333;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAJ0lEQVQIW2O8e/fufwYGBgZBQUEQxcCIIfDu3Tuwivfv30NUoAsAALHpFMMLqZlPAAAAAElFTkSuQmCC) repeat;
}
.hljs-title,
.hljs-section,
.hljs-selector-id {
color: #000;
font-weight: bold;
}
.hljs-subst {
font-weight: normal;
}
.hljs-class .hljs-title,
.hljs-type,
.hljs-name {
color: #333;
font-weight: bold;
}
.hljs-tag {
color: #333;
}
.hljs-regexp {
color: #333;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAICAYAAADA+m62AAAAPUlEQVQYV2NkQAN37979r6yszIgujiIAU4RNMVwhuiQ6H6wQl3XI4oy4FMHcCJPHcDS6J2A2EqUQpJhohQDexSef15DBCwAAAABJRU5ErkJggg==) repeat;
}
.hljs-symbol,
.hljs-bullet,
.hljs-link {
color: #000;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAKElEQVQIW2NkQAO7d+/+z4gsBhJwdXVlhAvCBECKwIIwAbhKZBUwBQA6hBpm5efZsgAAAABJRU5ErkJggg==) repeat;
}
.hljs-built_in,
.hljs-builtin-name {
color: #000;
text-decoration: underline;
}
.hljs-meta {
color: #999;
font-weight: bold;
}
.hljs-deletion {
color: #fff;
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAYAAABS3WWCAAAAE0lEQVQIW2MMDQ39zzhz5kwIAQAyxweWgUHd1AAAAABJRU5ErkJggg==) repeat;
}
.hljs-addition {
color: #000;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAALUlEQVQYV2N89+7dfwYk8P79ewZBQUFkIQZGOiu6e/cuiptQHAPl0NtNxAQBAM97Oejj3Dg7AAAAAElFTkSuQmCC) repeat;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,83 @@
/*
* Hopscotch
* by Jan T. Sott
* https://github.com/idleberg/Hopscotch
*
* This work is licensed under the Creative Commons CC0 1.0 Universal License
*/
/* Comment */
.hljs-comment,
.hljs-quote {
color: #989498;
}
/* Red */
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-link,
.hljs-deletion {
color: #dd464c;
}
/* Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #fd8b19;
}
/* Yellow */
.hljs-class .hljs-title {
color: #fdcc59;
}
/* Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #8fc13e;
}
/* Aqua */
.hljs-meta {
color: #149b93;
}
/* Blue */
.hljs-function,
.hljs-section,
.hljs-title {
color: #1290bf;
}
/* Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #c85e7c;
}
.hljs {
display: block;
background: #322931;
color: #b9b5b8;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,102 @@
/*
vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid)
*/
/*background color*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #1d1f21;
}
/*selection color*/
.hljs::selection,
.hljs span::selection {
background: #373b41;
}
.hljs::-moz-selection,
.hljs span::-moz-selection {
background: #373b41;
}
/*foreground color*/
.hljs {
color: #c5c8c6;
}
/*color: fg_yellow*/
.hljs-title,
.hljs-name {
color: #f0c674;
}
/*color: fg_comment*/
.hljs-comment,
.hljs-meta,
.hljs-meta .hljs-keyword {
color: #707880;
}
/*color: fg_red*/
.hljs-number,
.hljs-symbol,
.hljs-literal,
.hljs-deletion,
.hljs-link {
color: #cc6666
}
/*color: fg_green*/
.hljs-string,
.hljs-doctag,
.hljs-addition,
.hljs-regexp,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #b5bd68;
}
/*color: fg_purple*/
.hljs-attribute,
.hljs-code,
.hljs-selector-id {
color: #b294bb;
}
/*color: fg_blue*/
.hljs-keyword,
.hljs-selector-tag,
.hljs-bullet,
.hljs-tag {
color: #81a2be;
}
/*color: fg_aqua*/
.hljs-subst,
.hljs-variable,
.hljs-template-tag,
.hljs-template-variable {
color: #8abeb7;
}
/*color: fg_orange*/
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-quote,
.hljs-section,
.hljs-selector-class {
color: #de935f;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,97 @@
/*
Intellij Idea-like styling (c) Vasily Polovnyov <vast@whiteants.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #000;
background: #fff;
}
.hljs-subst,
.hljs-title {
font-weight: normal;
color: #000;
}
.hljs-comment,
.hljs-quote {
color: #808080;
font-style: italic;
}
.hljs-meta {
color: #808000;
}
.hljs-tag {
background: #efefef;
}
.hljs-section,
.hljs-name,
.hljs-literal,
.hljs-keyword,
.hljs-selector-tag,
.hljs-type,
.hljs-selector-id,
.hljs-selector-class {
font-weight: bold;
color: #000080;
}
.hljs-attribute,
.hljs-number,
.hljs-regexp,
.hljs-link {
font-weight: bold;
color: #0000ff;
}
.hljs-number,
.hljs-regexp,
.hljs-link {
font-weight: normal;
}
.hljs-string {
color: #008000;
font-weight: bold;
}
.hljs-symbol,
.hljs-bullet,
.hljs-formula {
color: #000;
background: #d0eded;
font-style: italic;
}
.hljs-doctag {
text-decoration: underline;
}
.hljs-variable,
.hljs-template-variable {
color: #660e7a;
}
.hljs-addition {
background: #baeeba;
}
.hljs-deletion {
background: #ffc8bd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,73 @@
/*
IR_Black style (c) Vasily Mikhailitchenko <vaskas@programica.ru>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #000;
color: #f8f8f8;
}
.hljs-comment,
.hljs-quote,
.hljs-meta {
color: #7c7c7c;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-tag,
.hljs-name {
color: #96cbfe;
}
.hljs-attribute,
.hljs-selector-id {
color: #ffffb6;
}
.hljs-string,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition {
color: #a8ff60;
}
.hljs-subst {
color: #daefa3;
}
.hljs-regexp,
.hljs-link {
color: #e9c062;
}
.hljs-title,
.hljs-section,
.hljs-type,
.hljs-doctag {
color: #ffffb6;
}
.hljs-symbol,
.hljs-bullet,
.hljs-variable,
.hljs-template-variable,
.hljs-literal {
color: #c6c5fe;
}
.hljs-number,
.hljs-deletion {
color:#ff73fd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,74 @@
/*
Name: Kimbie (dark)
Author: Jan T. Sott
License: Creative Commons Attribution-ShareAlike 4.0 Unported License
URL: https://github.com/idleberg/Kimbie-highlight.js
*/
/* Kimbie Comment */
.hljs-comment,
.hljs-quote {
color: #d6baad;
}
/* Kimbie Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-meta {
color: #dc3958;
}
/* Kimbie Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-deletion,
.hljs-link {
color: #f79a32;
}
/* Kimbie Yellow */
.hljs-title,
.hljs-section,
.hljs-attribute {
color: #f06431;
}
/* Kimbie Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #889b4a;
}
/* Kimbie Purple */
.hljs-keyword,
.hljs-selector-tag,
.hljs-function {
color: #98676a;
}
.hljs {
display: block;
overflow-x: auto;
background: #221a0f;
color: #d3af86;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,74 @@
/*
Name: Kimbie (light)
Author: Jan T. Sott
License: Creative Commons Attribution-ShareAlike 4.0 Unported License
URL: https://github.com/idleberg/Kimbie-highlight.js
*/
/* Kimbie Comment */
.hljs-comment,
.hljs-quote {
color: #a57a4c;
}
/* Kimbie Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-meta {
color: #dc3958;
}
/* Kimbie Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-deletion,
.hljs-link {
color: #f79a32;
}
/* Kimbie Yellow */
.hljs-title,
.hljs-section,
.hljs-attribute {
color: #f06431;
}
/* Kimbie Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #889b4a;
}
/* Kimbie Purple */
.hljs-keyword,
.hljs-selector-tag,
.hljs-function {
color: #98676a;
}
.hljs {
display: block;
overflow-x: auto;
background: #fbebd4;
color: #84613d;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,70 @@
/*
Description: Magula style for highligh.js
Author: Ruslan Keba <rukeba@gmail.com>
Website: http://rukeba.com/
Version: 1.0
Date: 2009-01-03
Music: Aphex Twin / Xtal
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background-color: #f4f4f4;
}
.hljs,
.hljs-subst {
color: black;
}
.hljs-string,
.hljs-title,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute,
.hljs-addition,
.hljs-variable,
.hljs-template-tag,
.hljs-template-variable {
color: #050;
}
.hljs-comment,
.hljs-quote {
color: #777;
}
.hljs-number,
.hljs-regexp,
.hljs-literal,
.hljs-type,
.hljs-link {
color: #800;
}
.hljs-deletion,
.hljs-meta {
color: #00e;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-doctag,
.hljs-title,
.hljs-section,
.hljs-built_in,
.hljs-tag,
.hljs-name {
font-weight: bold;
color: navy;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,59 @@
/*
Five-color theme from a single blue hue.
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #eaeef3;
}
.hljs {
color: #00193a;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-title,
.hljs-section,
.hljs-doctag,
.hljs-name,
.hljs-strong {
font-weight: bold;
}
.hljs-comment {
color: #738191;
}
.hljs-string,
.hljs-title,
.hljs-section,
.hljs-built_in,
.hljs-literal,
.hljs-type,
.hljs-addition,
.hljs-tag,
.hljs-quote,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #0048ab;
}
.hljs-meta,
.hljs-subst,
.hljs-symbol,
.hljs-regexp,
.hljs-attribute,
.hljs-deletion,
.hljs-variable,
.hljs-template-variable,
.hljs-link,
.hljs-bullet {
color: #4c81c9;
}
.hljs-emphasis {
font-style: italic;
}

View file

@ -0,0 +1,83 @@
/*
Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #23241f;
}
.hljs,
.hljs-tag,
.hljs-subst {
color: #f8f8f2;
}
.hljs-strong,
.hljs-emphasis {
color: #a8a8a2;
}
.hljs-bullet,
.hljs-quote,
.hljs-number,
.hljs-regexp,
.hljs-literal,
.hljs-link {
color: #ae81ff;
}
.hljs-code,
.hljs-title,
.hljs-section,
.hljs-selector-class {
color: #a6e22e;
}
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-name,
.hljs-attr {
color: #f92672;
}
.hljs-symbol,
.hljs-attribute {
color: #66d9ef;
}
.hljs-params,
.hljs-class .hljs-title {
color: #f8f8f2;
}
.hljs-string,
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-selector-id,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition,
.hljs-variable,
.hljs-template-variable {
color: #e6db74;
}
.hljs-comment,
.hljs-deletion,
.hljs-meta {
color: #75715e;
}

View file

@ -0,0 +1,70 @@
/*
Monokai style - ported by Luigi Maselli - http://grigio.org
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #272822; color: #ddd;
}
.hljs-tag,
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-strong,
.hljs-name {
color: #f92672;
}
.hljs-code {
color: #66d9ef;
}
.hljs-class .hljs-title {
color: white;
}
.hljs-attribute,
.hljs-symbol,
.hljs-regexp,
.hljs-link {
color: #bf79db;
}
.hljs-string,
.hljs-bullet,
.hljs-subst,
.hljs-title,
.hljs-section,
.hljs-emphasis,
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition,
.hljs-variable,
.hljs-template-tag,
.hljs-template-variable {
color: #a6e22e;
}
.hljs-comment,
.hljs-quote,
.hljs-deletion,
.hljs-meta {
color: #75715e;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-doctag,
.hljs-title,
.hljs-section,
.hljs-type,
.hljs-selector-id {
font-weight: bold;
}

View file

@ -0,0 +1,88 @@
/**
* Obsidian style
* ported by Alexander Marenin (http://github.com/ioncreature)
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #282b2e;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-selector-id {
color: #93c763;
}
.hljs-number {
color: #ffcd22;
}
.hljs {
color: #e0e2e4;
}
.hljs-attribute {
color: #668bb0;
}
.hljs-code,
.hljs-class .hljs-title,
.hljs-section {
color: white;
}
.hljs-regexp,
.hljs-link {
color: #d39745;
}
.hljs-meta {
color: #557182;
}
.hljs-tag,
.hljs-name,
.hljs-bullet,
.hljs-subst,
.hljs-emphasis,
.hljs-type,
.hljs-built_in,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition,
.hljs-variable,
.hljs-template-tag,
.hljs-template-variable {
color: #8cbbad;
}
.hljs-string,
.hljs-symbol {
color: #ec7600;
}
.hljs-comment,
.hljs-quote,
.hljs-deletion {
color: #818e96;
}
.hljs-selector-class {
color: #A082BD
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-doctag,
.hljs-title,
.hljs-section,
.hljs-type,
.hljs-name,
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,72 @@
/*
Paraíso (dark)
Created by Jan T. Sott (http://github.com/idleberg)
Inspired by the art of Rubens LP (http://www.rubenslp.com.br)
*/
/* Paraíso Comment */
.hljs-comment,
.hljs-quote {
color: #8d8687;
}
/* Paraíso Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-link,
.hljs-meta {
color: #ef6155;
}
/* Paraíso Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-deletion {
color: #f99b15;
}
/* Paraíso Yellow */
.hljs-title,
.hljs-section,
.hljs-attribute {
color: #fec418;
}
/* Paraíso Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #48b685;
}
/* Paraíso Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #815ba4;
}
.hljs {
display: block;
overflow-x: auto;
background: #2f1e2e;
color: #a39e9b;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,72 @@
/*
Paraíso (light)
Created by Jan T. Sott (http://github.com/idleberg)
Inspired by the art of Rubens LP (http://www.rubenslp.com.br)
*/
/* Paraíso Comment */
.hljs-comment,
.hljs-quote {
color: #776e71;
}
/* Paraíso Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-link,
.hljs-meta {
color: #ef6155;
}
/* Paraíso Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-deletion {
color: #f99b15;
}
/* Paraíso Yellow */
.hljs-title,
.hljs-section,
.hljs-attribute {
color: #fec418;
}
/* Paraíso Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #48b685;
}
/* Paraíso Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #815ba4;
}
.hljs {
display: block;
overflow-x: auto;
background: #e7e9db;
color: #4f424c;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

View file

@ -0,0 +1,83 @@
/*
Pojoaque Style by Jason Tate
http://web-cms-designs.com/ftopict-10-pojoaque-style-for-highlight-js-code-highlighter.html
Based on Solarized Style from http://ethanschoonover.com/solarized
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #dccf8f;
background: url(./pojoaque.jpg) repeat scroll left top #181914;
}
.hljs-comment,
.hljs-quote {
color: #586e75;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-addition {
color: #b64926;
}
.hljs-number,
.hljs-string,
.hljs-doctag,
.hljs-regexp {
color: #468966;
}
.hljs-title,
.hljs-section,
.hljs-built_in,
.hljs-name {
color: #ffb03b;
}
.hljs-variable,
.hljs-template-variable,
.hljs-class .hljs-title,
.hljs-type,
.hljs-tag {
color: #b58900;
}
.hljs-attribute {
color: #b89859;
}
.hljs-symbol,
.hljs-bullet,
.hljs-link,
.hljs-subst,
.hljs-meta {
color: #cb4b16;
}
.hljs-deletion {
color: #dc322f;
}
.hljs-selector-id,
.hljs-selector-class {
color: #d3a60c;
}
.hljs-formula {
background: #073642;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,106 @@
/*
Railscasts-like style (c) Visoft, Inc. (Damien White)
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #232323;
color: #e6e1dc;
}
.hljs-comment,
.hljs-quote {
color: #bc9458;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag {
color: #c26230;
}
.hljs-string,
.hljs-number,
.hljs-regexp,
.hljs-variable,
.hljs-template-variable {
color: #a5c261;
}
.hljs-subst {
color: #519f50;
}
.hljs-tag,
.hljs-name {
color: #e8bf6a;
}
.hljs-type {
color: #da4939;
}
.hljs-symbol,
.hljs-bullet,
.hljs-built_in,
.hljs-builtin-name,
.hljs-attr,
.hljs-link {
color: #6d9cbe;
}
.hljs-params {
color: #d0d0ff;
}
.hljs-attribute {
color: #cda869;
}
.hljs-meta {
color: #9b859d;
}
.hljs-title,
.hljs-section {
color: #ffc66d;
}
.hljs-addition {
background-color: #144212;
color: #e6e1dc;
display: inline-block;
width: 100%;
}
.hljs-deletion {
background-color: #600;
color: #e6e1dc;
display: inline-block;
width: 100%;
}
.hljs-selector-class {
color: #9b703f;
}
.hljs-selector-id {
color: #8b98ab;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-link {
text-decoration: underline;
}

View file

@ -0,0 +1,85 @@
/*
Style with support for rainbow parens
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #474949;
color: #d1d9e1;
}
.hljs-comment,
.hljs-quote {
color: #969896;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-type,
.hljs-addition {
color: #cc99cc;
}
.hljs-number,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #f99157;
}
.hljs-string,
.hljs-doctag,
.hljs-regexp {
color: #8abeb7;
}
.hljs-title,
.hljs-name,
.hljs-section,
.hljs-built_in {
color: #b5bd68;
}
.hljs-variable,
.hljs-template-variable,
.hljs-selector-id,
.hljs-class .hljs-title {
color: #ffcc66;
}
.hljs-section,
.hljs-name,
.hljs-strong {
font-weight: bold;
}
.hljs-symbol,
.hljs-bullet,
.hljs-subst,
.hljs-meta,
.hljs-link {
color: #f99157;
}
.hljs-deletion {
color: #dc322f;
}
.hljs-formula {
background: #eee8d5;
}
.hljs-attr,
.hljs-attribute {
color: #81a2be;
}
.hljs-emphasis {
font-style: italic;
}

View file

@ -0,0 +1,72 @@
/*
School Book style from goldblog.com.ua (c) Zaripov Yura <yur4ik7@ukr.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 15px 0.5em 0.5em 30px;
font-size: 11px;
line-height:16px;
}
pre{
background:#f6f6ae url(./school-book.png);
border-top: solid 2px #d2e8b9;
border-bottom: solid 1px #d2e8b9;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal {
color:#005599;
font-weight:bold;
}
.hljs,
.hljs-subst {
color: #3e5915;
}
.hljs-string,
.hljs-title,
.hljs-section,
.hljs-type,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute,
.hljs-built_in,
.hljs-builtin-name,
.hljs-addition,
.hljs-variable,
.hljs-template-tag,
.hljs-template-variable,
.hljs-link {
color: #2c009f;
}
.hljs-comment,
.hljs-quote,
.hljs-deletion,
.hljs-meta {
color: #e60415;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal,
.hljs-doctag,
.hljs-title,
.hljs-section,
.hljs-type,
.hljs-name,
.hljs-selector-id,
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}

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