diff --git a/.gitignore b/.gitignore index 0abd85ad..eaa4a86e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,20 +1,4 @@ -*.gem -*.rbc -.bundle .config -coverage -InstalledFiles -lib/bundler/man -pkg -rdoc -spec/reports -test/tmp -test/version_tmp -tmp -# YARD artifacts -.yardoc -_yardoc -doc/ tests/coverage config.yml .DS_Store @@ -30,8 +14,7 @@ files/map.txt .sass-cache/* files/sslsites.zip .tm_properties -./black_box.rb .vagrant public/banned_sites public/deleted_sites -tests/stat_logs/* +Gemfile.lock diff --git a/.travis.yml b/.travis.yml index e029b7a2..07848556 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,10 @@ language: ruby rvm: - - "2.1.1" + - "2.3.0" + - "2.2.3" addons: postgresql: "9.3" before_script: - psql -c 'create database travis_ci_test;' -U postgres +sudo: false +bundler_args: --jobs=1 diff --git a/Gemfile b/Gemfile index c92b40d4..a98cc309 100644 --- a/Gemfile +++ b/Gemfile @@ -15,8 +15,8 @@ gem 'mail' gem 'google-api-client', require: 'google/api_client' gem 'tilt' gem 'erubis' -gem 'stripe' #, source: 'https://code.stripe.com/' -gem 'screencap' +gem 'stripe', '1.15.0' #, source: 'https://code.stripe.com/' +#gem 'screencap', '~> 0.1.4' gem 'cocaine' gem 'zipruby' gem 'sass', require: nil @@ -32,13 +32,17 @@ gem 'geoip' gem 'io-extra', require: 'io/extra' gem 'rye' gem 'dnsruby' +gem 'base32' +gem 'coveralls', require: false +gem 'sanitize' +gem 'will_paginate' platform :mri, :rbx do gem 'magic' # sudo apt-get install file, For OSX: brew install libmagic gem 'pg' gem 'sequel_pg', require: nil gem 'hiredis' - gem 'rainbows', require: nil + gem 'posix-spawn' group :development, :test do gem 'pry' @@ -77,10 +81,11 @@ group :test do gem 'capybara_minitest_spec' gem 'rack_session_access', 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' platform :mri, :rbx do gem 'simplecov', require: nil + gem 'm' end end diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 98f8ed2f..00000000 --- a/Gemfile.lock +++ /dev/null @@ -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 diff --git a/README.md b/README.md index d69f7d66..e5fc7bbf 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Neocities.org [![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! diff --git a/Rakefile b/Rakefile index 4ac5badd..49f89cfe 100644 --- a/Rakefile +++ b/Rakefile @@ -41,7 +41,7 @@ end desc 'Update banned IPs list' task :update_blocked_ips => [:environment] do 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 Net::HTTP.start(uri.host, uri.port) do |http| @@ -216,6 +216,73 @@ task :hash_ips => [:environment] do 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 desc 'Update screenshots' task :update_screenshots => [:environment] do @@ -224,3 +291,33 @@ task :update_screenshots => [:environment] do } 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 diff --git a/app/admin.rb b/app/admin.rb index 5f2303af..80f751d8 100644 --- a/app/admin.rb +++ b/app/admin.rb @@ -11,6 +11,65 @@ get '/admin/reports' do erb :'admin/reports' 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 require_admin erb :'admin/email' @@ -79,6 +138,11 @@ post '/admin/banhammer' do site = Site[username: params[:username]] + if !params[:classifier].empty? + site.untrain 'index.html' + site.train 'index.html', params[:classifier] + end + if site.nil? flash[:error] = 'User not found' redirect '/admin' @@ -105,6 +169,7 @@ post '/admin/mark_nsfw' do end site.is_nsfw = true + site.admin_nsfw = true site.save_changes validate: false flash[:success] = 'MISSION ACCOMPLISHED' diff --git a/app/blog.rb b/app/blog.rb index 6fa8e715..c2e4df8e 100644 --- a/app/blog.rb +++ b/app/blog.rb @@ -1,22 +1,7 @@ -require 'net/http' -require 'uri' - get '/blog/?' do - expires 60, :public, :must_revalidate - return Net::HTTP.get_response(URI('http://blog.neocities.org')).body + redirect 'https://blog.neocities.org', 301 end get '/blog/:article' do |article| - expires 60, :public, :must_revalidate - - 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 + redirect "https://blog.neocities.org/#{article}.html", 301 end diff --git a/app/browse.rb b/app/browse.rb index 744e67e7..3d4717ef 100644 --- a/app/browse.rb +++ b/app/browse.rb @@ -1,7 +1,7 @@ get '/browse/?' do - @current_page = params[:current_page] - @current_page = @current_page.to_i - @current_page = 1 if @current_page == 0 + + @page = params[:page].to_i + @page = 1 if @page == 0 params.delete 'tag' if params[:tag].nil? || params[:tag].strip.empty? @@ -11,12 +11,14 @@ get '/browse/?' do site_dataset = browse_sites_dataset end - site_dataset = site_dataset.paginate @current_page, Site::BROWSE_PAGINATION_LENGTH - @page_count = site_dataset.page_count || 1 + site_dataset = site_dataset.paginate @page, Site::BROWSE_PAGINATION_LENGTH + @pagination_dataset = site_dataset @sites = site_dataset.all + if params[:tag] @title = "Sites tagged #{params[:tag]}" end + erb :browse end @@ -28,9 +30,12 @@ def education_sites_dataset end 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 + site_dataset.or! sites__id: current_site.id + if !current_site.blocking_site_ids.empty? site_dataset.where!(Sequel.~(Sequel.qualify(:sites, :id) => current_site.blocking_site_ids)) end @@ -43,6 +48,9 @@ def browse_sites_dataset end case params[:sort_by] + when 'special_sauce' + site_dataset.exclude! score: nil + site_dataset.order! :score.desc when 'followers' site_dataset = site_dataset.association_left_join :follows 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)] - if params[:tag] && params[:sort_by] != 'followers' - site_dataset = site_dataset.association_join(:tags).select_all(:sites) + if params[:tag] + 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.is_nsfw = ?', (params[:is_nsfw] == 'true' ? true : false)] end diff --git a/app/create.rb b/app/create.rb index a9df8649..b3f0d3d8 100644 --- a/app/create.rb +++ b/app/create.rb @@ -1,5 +1,5 @@ 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( 'https://www.google.com/recaptcha/api/siteverify?'+ Rack::Utils.build_query( @@ -54,7 +54,15 @@ end post '/create' do content_type :json - require_unbanned_ip + + if banned?(true) + signout + session[:banned] = true if !session[:banned] + + flash[:error] = 'There was an error, please contact support to log in.' + redirect '/' + end + dashboard_if_signed_in @site = Site.new( diff --git a/app/dmca.rb b/app/dmca.rb index ae838708..de118f0a 100644 --- a/app/dmca.rb +++ b/app/dmca.rb @@ -30,7 +30,7 @@ post '/dmca/contact' do no_footer: true }) - flash[:success] = 'Your DCMA notification has been sent.' + flash[:success] = 'Your DMCA notification has been sent.' redirect '/' end end diff --git a/app/index.rb b/app/index.rb index 17e2ee85..e905414c 100644 --- a/app/index.rb +++ b/app/index.rb @@ -6,23 +6,23 @@ get '/?' do @suggestions = current_site.suggestions - @current_page = params[:current_page].to_i - @current_page = 1 if @current_page == 0 + @page = params[:page].to_i + @page = 1 if @page == 0 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] event = Event.select(:id).where(id: params[:event_id]).first not_found if event.nil? not_found if event.is_deleted events_dataset = Event.where(id: params[:event_id]).paginate(1, 1) elsif params[:activity] == 'global' - events_dataset = Event.global_dataset @current_page + events_dataset = Event.global_dataset @page else - events_dataset = current_site.news_feed(@current_page, 10) + events_dataset = current_site.news_feed(@page, 10) end - @page_count = events_dataset.page_count || 1 + @pagination_dataset = events_dataset @events = events_dataset.all current_site.events_dataset.update notification_seen: true @@ -50,10 +50,6 @@ get '/education' do erb :education, layout: :index_layout end -get '/tutorials' do - erb :'tutorials' -end - get '/donate' do erb :'donate' end @@ -82,3 +78,7 @@ end get '/permanent-web' do erb :'permanent_web' end + +get '/thankyou' do + erb :'thankyou' +end diff --git a/app/mockup.rb b/app/mockup.rb index 3017a565..5aab40b2 100644 --- a/app/mockup.rb +++ b/app/mockup.rb @@ -29,4 +29,9 @@ get '/stats_mockup' do require_login erb :'stats_mockup', locals: {site: current_site} end + +get '/tutorial_mockup_c1p2' do + require_login + erb :'tutorial_mockup_c1p2', locals: {site: current_site} +end # :nocov: \ No newline at end of file diff --git a/app/search.rb b/app/search.rb deleted file mode 100644 index 8e76e5ad..00000000 --- a/app/search.rb +++ /dev/null @@ -1,4 +0,0 @@ - -get '/search' do - erb :'search' -end diff --git a/app/settings.rb b/app/settings.rb index fb35e541..8b18ae3b 100644 --- a/app/settings.rb +++ b/app/settings.rb @@ -185,7 +185,7 @@ post '/settings/:username/change_name' do end 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] @@ -195,11 +195,11 @@ post '/settings/:username/change_name' do @site.move_files_from old_username } - old_file_paths.each do |file_path| - @site.purge_cache file_path + old_site_file_paths.each do |site_file_path| + @site.delete_cache site_file_path end - flash[:success] = "Site/user name has been changed. You will need to use this name to login, don't forget it." + flash[:success] = "Site/user name has been changed. You will need to use this name to login, don't forget it!" redirect "/settings/#{@site.username}#username" else flash[:error] = @site.errors.first.last.first @@ -211,6 +211,8 @@ post '/settings/:username/change_nsfw' do require_login require_ownership_for_settings + redirect "/settings/#{@site.username}" if @site.admin_nsfw == true + @site.is_nsfw = params[:is_nsfw] @site.save_changes validate: false flash[:success] = @site.is_nsfw ? 'Marked 18+' : 'Unmarked 18+' @@ -260,7 +262,7 @@ end post '/settings/change_email' do require_login - + if params[:email] == parent_site.email flash[:error] = 'You are already using this email address for this account.' redirect '/settings#email' @@ -331,4 +333,30 @@ get '/settings/unsubscribe_email/?' do @message = 'There was an error unsubscribing your email address. Please contact support.' end erb :'settings/account/unsubscribe' -end \ No newline at end of file +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 diff --git a/app/site.rb b/app/site.rb index d716ec56..eceaffe5 100644 --- a/app/site.rb +++ b/app/site.rb @@ -13,9 +13,9 @@ get '/site/:username/?' do |username| @title = site.title - @current_page = params[:current_page] - @current_page = @current_page.to_i - @current_page = 1 if @current_page == 0 + @page = params[:page] + @page = @page.to_i + @page = 1 if @page == 0 if params[:event_id] not_found unless params[:event_id].is_integer? @@ -23,10 +23,11 @@ get '/site/:username/?' do |username| not_found if event.nil? events_dataset = Event.where(id: params[:event_id]).paginate(1, 1) else - events_dataset = site.latest_events(@current_page, 10) + events_dataset = site.latest_events(@page, 10) end @page_count = events_dataset.page_count || 1 + @pagination_dataset = events_dataset @latest_events = events_dataset.all erb :'site', locals: {site: site, is_current_site: site == current_site} @@ -161,7 +162,6 @@ post '/site/create_directory' do require_login path = "#{params[:dir] || ''}/#{params[:name]}" - result = current_site.create_directory path if result != true diff --git a/app/site_files.rb b/app/site_files.rb index aa7107dc..8fd9789e 100644 --- a/app/site_files.rb +++ b/app/site_files.rb @@ -207,6 +207,10 @@ get '/site_files/allowed_types' do erb :'site_files/allowed_types' end +get '/site_files/hotlinking' do + erb :'site_files/hotlinking' +end + get '/site_files/mount_info' do erb :'site_files/mount_info' end diff --git a/app/surf.rb b/app/surf.rb index 95d819db..a96b8995 100644 --- a/app/surf.rb +++ b/app/surf.rb @@ -1,8 +1,8 @@ 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? 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 @site = site_dataset.first redirect "/browse?#{Rack::Utils.build_query params}" if @site.nil? diff --git a/app/tutorial.rb b/app/tutorial.rb new file mode 100644 index 00000000..cdba092f --- /dev/null +++ b/app/tutorial.rb @@ -0,0 +1,45 @@ +def default_tutorial_html + <<-EOT.strip + + + + + + My web site + + + + + Hello World! + + + +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 diff --git a/app_helpers.rb b/app_helpers.rb index 27a0e116..5590c189 100644 --- a/app_helpers.rb +++ b/app_helpers.rb @@ -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 redirect '/dashboard' if signed_in? end def require_login_ajax 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 def csrf_safe? @@ -31,11 +21,7 @@ end def require_login redirect '/' unless signed_in? - if session[:banned] || current_site.is_banned || parent_site.is_banned - signout - session[:banned] = true - redirect '/' - end + enforce_ban if banned? end def signed_in? @@ -52,15 +38,18 @@ def parent_site current_site.parent? ? current_site : current_site.parent end -def require_unbanned_ip - if session[:banned] || (is_banned_ip = Site.banned_ip?(request.ip)) - signout - session[:banned] = request.ip if !session[:banned] +def banned?(ip_check=false) + return true if session[:banned] + return true if current_site && (current_site.is_banned || parent_site.is_banned) - flash[:error] = 'Site creation has been banned due to a Terms of Service violation from your location. '+ - 'If you believe this to be in error, contact the site admin.' - return {result: 'error'}.to_json - end + return true if ip_check && Site.banned_ip?(request.ip) + false +end + +def enforce_ban + signout + session[:banned] = true + redirect '/' end def title diff --git a/config.ru b/config.ru index f664a028..16e3721c 100644 --- a/config.ru +++ b/config.ru @@ -1,11 +1,6 @@ require 'rubygems' require './app.rb' require 'sidekiq/web' -require 'unicorn/preread_input' - -if defined?(Unicorn) - use Unicorn::PrereadInput -end map('/') do use(Rack::Cache, @@ -35,13 +30,18 @@ map '/webdav' do end if Site.valid_file_type?(filename: path, tempfile: tmpfile) - site.store_file path, tmpfile + site.store_files [{filename: path, tempfile: tmpfile}] return [201, {}, ['']] else return [415, {}, ['']] end end + if env['REQUEST_METHOD'] == 'MKCOL' + site.create_directory env['PATH_INFO'] + return [201, {}, ['']] + end + if env['REQUEST_METHOD'] == 'MOVE' tmpfile = Tempfile.new 'moved_file' tmpfile.close @@ -51,7 +51,7 @@ map '/webdav' do FileUtils.cp site.files_path(env['PATH_INFO']), tmpfile.path DB.transaction do - site.store_file destination, tmpfile + site.store_files [{filename: destination, tempfile: tmpfile}] site.delete_file env['PATH_INFO'] end diff --git a/environment.rb b/environment.rb index a5eb50a1..d8a6cb9d 100644 --- a/environment.rb +++ b/environment.rb @@ -11,6 +11,8 @@ require 'logger' Bundler.require Bundler.require :development if ENV['RACK_ENV'] == 'development' +require 'tilt/erubis' + Dir['./ext/**/*.rb'].each {|f| require f} # :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.extension :pagination +require 'will_paginate/sequel' + # :nocov: =begin if defined?(Pry) @@ -61,6 +65,7 @@ end # :nocov: if ENV['RACK_ENV'] == 'development' # Run async jobs immediately in development. +=begin module Sidekiq module Worker module ClassMethods @@ -72,6 +77,7 @@ if ENV['RACK_ENV'] == 'development' end end end +=end end # :nocov: diff --git a/ext/base58.rb b/ext/base58.rb new file mode 100644 index 00000000..048f7cb8 --- /dev/null +++ b/ext/base58.rb @@ -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 diff --git a/files/phantomjs_screenshot.js b/files/phantomjs_screenshot.js new file mode 100644 index 00000000..0ac8e24b --- /dev/null +++ b/files/phantomjs_screenshot.js @@ -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: '); + 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() +}) + diff --git a/migrations/070_add_admin_nsfw.rb b/migrations/070_add_admin_nsfw.rb new file mode 100644 index 00000000..e03921d0 --- /dev/null +++ b/migrations/070_add_admin_nsfw.rb @@ -0,0 +1,9 @@ +Sequel.migration do + up { + DB.add_column :sites, :admin_nsfw, :boolean + } + + down { + DB.drop_column :sites, :admin_nsfw + } +end diff --git a/migrations/071_banned_referrers.rb b/migrations/071_banned_referrers.rb new file mode 100644 index 00000000..c23d728a --- /dev/null +++ b/migrations/071_banned_referrers.rb @@ -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 diff --git a/migrations/072_banned_commenting.rb b/migrations/072_banned_commenting.rb new file mode 100644 index 00000000..88176fd2 --- /dev/null +++ b/migrations/072_banned_commenting.rb @@ -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 diff --git a/migrations/073_add_follow_uniqueness.rb b/migrations/073_add_follow_uniqueness.rb new file mode 100644 index 00000000..4e80ff28 --- /dev/null +++ b/migrations/073_add_follow_uniqueness.rb @@ -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 diff --git a/migrations/074_add_custom_max_space.rb b/migrations/074_add_custom_max_space.rb new file mode 100644 index 00000000..1bc09b18 --- /dev/null +++ b/migrations/074_add_custom_max_space.rb @@ -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 diff --git a/migrations/075_special_sauce.rb b/migrations/075_special_sauce.rb new file mode 100644 index 00000000..394f2ded --- /dev/null +++ b/migrations/075_special_sauce.rb @@ -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 diff --git a/migrations/076_decimal_sauce.rb b/migrations/076_decimal_sauce.rb new file mode 100644 index 00000000..dcef090c --- /dev/null +++ b/migrations/076_decimal_sauce.rb @@ -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 diff --git a/migrations/077_decimal_sauce_index.rb b/migrations/077_decimal_sauce_index.rb new file mode 100644 index 00000000..fa242b45 --- /dev/null +++ b/migrations/077_decimal_sauce_index.rb @@ -0,0 +1,9 @@ +Sequel.migration do + up { + DB.add_index :sites, :score + } + + down { + DB.drop_index :sites, :score + } +end diff --git a/migrations/078_total_stat.rb b/migrations/078_total_stat.rb new file mode 100644 index 00000000..6698e2a9 --- /dev/null +++ b/migrations/078_total_stat.rb @@ -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 diff --git a/migrations/079_add_total_stat_bandwidth.rb b/migrations/079_add_total_stat_bandwidth.rb new file mode 100644 index 00000000..a3d30feb --- /dev/null +++ b/migrations/079_add_total_stat_bandwidth.rb @@ -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 diff --git a/migrations/080_fix_total_stat_bandwidth.rb b/migrations/080_fix_total_stat_bandwidth.rb new file mode 100644 index 00000000..3c87e95a --- /dev/null +++ b/migrations/080_fix_total_stat_bandwidth.rb @@ -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 diff --git a/migrations/081_stats_bigint.rb b/migrations/081_stats_bigint.rb new file mode 100644 index 00000000..f8f0081b --- /dev/null +++ b/migrations/081_stats_bigint.rb @@ -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 diff --git a/migrations/082_daily_stats_bigint.rb b/migrations/082_daily_stats_bigint.rb new file mode 100644 index 00000000..5cefebed --- /dev/null +++ b/migrations/082_daily_stats_bigint.rb @@ -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 diff --git a/migrations/083_add_classifiers.rb b/migrations/083_add_classifiers.rb new file mode 100644 index 00000000..9292780b --- /dev/null +++ b/migrations/083_add_classifiers.rb @@ -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 diff --git a/models/archive.rb b/models/archive.rb index 53731056..93b30b03 100644 --- a/models/archive.rb +++ b/models/archive.rb @@ -1,9 +1,19 @@ +require 'base32' + class Archive < Sequel::Model many_to_one :site set_primary_key [:site_id, :ipfs_hash] 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 - "https://#{ipfs_hash}.ipfs.neocities.org" + "http://#{hshca_hash}.ipfs.neocitiesops.net" end end diff --git a/models/daily_site_stat.rb b/models/daily_site_stat.rb new file mode 100644 index 00000000..cdcc3622 --- /dev/null +++ b/models/daily_site_stat.rb @@ -0,0 +1,2 @@ +class DailySiteStat < Sequel::Model +end diff --git a/models/site.rb b/models/site.rb index 3da82121..54920fa3 100644 --- a/models/site.rb +++ b/models/site.rb @@ -33,11 +33,11 @@ class Site < Sequel::Model } 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{ - html htm txt js css md manifest + html htm txt js css md manifest less } MINIMUM_PASSWORD_LENGTH = 5 @@ -74,6 +74,8 @@ class Site < Sequel::Model /PHP\.Hide/ ] + EMPTY_FILE_HASH = Digest::SHA1.hexdigest '' + 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 EMAIL_SANITY_REGEX = /.+@.+\..+/i @@ -103,7 +105,7 @@ class Site < Sequel::Model custom_ssl_certificates: true, no_file_restrictions: true, custom_domains: true, - maximum_site_files: 25000 + maximum_site_files: 50000 } PLAN_FEATURES[:free] = PLAN_FEATURES[:supporter].merge( @@ -115,7 +117,7 @@ class Site < Sequel::Model custom_ssl_certificates: false, no_file_restrictions: false, custom_domains: false, - maximum_site_files: 1000 + maximum_site_files: 2000 ) def self.newsletter_sites @@ -294,6 +296,7 @@ class Site < Sequel::Model end def banned_ip?(ip) + return false if ENV['RACK_ENV'] == 'production' && ip == '127.0.0.1' return true if Site.where(is_banned: true). where(ip: hash_ip(ip)). where(['updated_at > ?', Time.now-BANNED_TIME]). @@ -318,7 +321,7 @@ class Site < Sequel::Model end 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 def toggle_follow(site) @@ -417,7 +420,7 @@ class Site < Sequel::Model end def get_file(path) - File.read files_path(path) + File.read current_files_path(path) end def before_destroy @@ -456,8 +459,8 @@ class Site < Sequel::Model FileUtils.mv files_path, File.join(BANNED_SITES_ROOT, username) } - file_list.each do |path| - purge_cache path + site_files.each do |site_file| + delete_cache site_file.path end end @@ -467,6 +470,16 @@ class Site < Sequel::Model } 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 def follows_dataset super.where(Sequel.~(site_id: blocking_site_ids)) @@ -485,6 +498,7 @@ class Site < Sequel::Model =end def commenting_allowed? + return false if owner.commenting_banned == true return true if owner.commenting_allowed if owner.supporter? @@ -579,12 +593,32 @@ class Site < Sequel::Model # We gotta flush the dirname too if it's an index file. if relative_path != '' && relative_path.match(/\/$|index\.html?$/i) 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 PurgeCacheOrderWorker.perform_async username, relative_path 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 def add_to_ipfs @@ -637,6 +671,32 @@ class Site < Sequel::Model return 'Directory (or file) already exists.' 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 true end @@ -870,6 +930,12 @@ class Site < Sequel::Model File.join TEMPLATE_ROOT, name 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) raise 'username missing' if name.nil? || name.empty? File.join SITE_FILES_ROOT, name @@ -880,7 +946,7 @@ class Site < Sequel::Model path ||= '' clean = [] - parts = path.split '/' + parts = path.to_s.split '/' parts.each do |part| next if part.empty? || part == '.' @@ -890,6 +956,10 @@ class Site < Sequel::Model clean.join '/' end + def current_files_path(path='') + File.join current_base_files_path, scrubbed_path(path) + end + def files_path(path='') File.join base_files_path, scrubbed_path(path) end @@ -904,9 +974,17 @@ class Site < Sequel::Model 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_image] = !(file[:ext].match IMAGE_REGEX).nil? file[:is_editable] = !(file[:ext].match EDITABLE_FILE_EXT).nil? + file end @@ -920,8 +998,16 @@ class Site < Sequel::Model end def actual_space_used - space = Dir.glob(File.join(files_path, '*')).collect {|p| File.size(p)}.inject {|sum,x| sum += x} - space.nil? ? 0 : space + space = 0 + + files = Dir.glob File.join(files_path, '**', '*') + + files.each do |file| + next if File.directory? file + space += File.size file + end + + space end def total_space_used @@ -936,7 +1022,11 @@ class Site < Sequel::Model end 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 def space_percentage_used @@ -956,6 +1046,10 @@ class Site < Sequel::Model PLAN_FEATURES[plan_type.to_sym][:name] end + def stripe_paying_supporter? + stripe_customer_id && !plan_ended && values[:plan_type].match(/free|special/).nil? + end + def unconverted_legacy_supporter? stripe_customer_id && !plan_ended && values[:plan_type].nil? && stripe_subscription_id.nil? end @@ -1028,13 +1122,70 @@ class Site < Sequel::Model 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) 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 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 def screenshot_path(path, resolution) @@ -1090,11 +1241,53 @@ class Site < Sequel::Model 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. def store_files(files, opts={}) results = [] new_size = 0 - html_uploaded = false if too_many_files?(files.length) results << false @@ -1102,35 +1295,53 @@ class Site < Sequel::Model end files.each do |file| - html_uploaded = true if file[:filename].match HTML_REGEX - existing_size = 0 + site_file = site_files_dataset.where(path: scrubbed_path(file[:filename])).first + if site_file existing_size = site_file.size end res = store_file(file[:filename], file[:tempfile], file[:opts] || opts) + if res == true new_size -= existing_size new_size += file[:tempfile].size end + results << res end - if results.include? true && opts[:new_install] != 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=?", - true, - time, - time, - self.id - ] - sql.first + if results.include? true + + DB["update sites set space_used=space_used#{new_size < 0 ? new_size.to_s : '+'+new_size.to_s} where id=?", self.id].first + + if opts[:new_install] != true + if files.select {|f| f[:filename] =~ /^\/?index.html$/}.length > 0 || site_changed == true + index_changed = true + else + 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 #SiteChange.record self, relative_path unless opts[:new_install] - ArchiveWorker.perform_async self.id end results @@ -1138,36 +1349,9 @@ class Site < Sequel::Model def delete_file(path) return false if files_path(path) == files_path - begin - FileUtils.rm files_path(path) - rescue Errno::EISDIR - 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 - + path = scrubbed_path path + site_file = site_files_dataset.where(path: path).first + site_file.destroy if site_file true end @@ -1186,6 +1370,15 @@ class Site < Sequel::Model return false 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' begin new_title = Nokogiri::HTML(File.read(uploaded.path)).css('title').first.text @@ -1198,18 +1391,6 @@ class Site < Sequel::Model 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 File.chmod 0640, path @@ -1227,11 +1408,11 @@ class Site < Sequel::Model purge_cache path 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 ThumbnailWorker.perform_async values[:username], relative_path end + true end - end diff --git a/models/site_file.rb b/models/site_file.rb index fa5db8d6..bf81c5e3 100644 --- a/models/site_file.rb +++ b/models/site_file.rb @@ -1,5 +1,53 @@ +require 'sanitize' + class SiteFile < Sequel::Model + CLASSIFIER_LIMIT = 1_000_000.freeze + CLASSIFIER_WORD_LIMIT = 25.freeze unrestrict_primary_key plugin :update_primary_key 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 + diff --git a/models/stat.rb b/models/stat.rb index 687997ee..fe2ea15c 100644 --- a/models/stat.rb +++ b/models/stat.rb @@ -15,8 +15,11 @@ class Stat < Sequel::Model end def parse_logfiles(path) + total_site_stats = {} + Dir["#{path}/*.log"].each do |log_path| site_logs = {} + logfile = File.open log_path, 'r' while hit = logfile.gets @@ -26,9 +29,13 @@ class Stat < Sequel::Model time, username, size, path, ip, referrer = hit_array + log_time = Time.parse time + 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, views: 0, bandwidth: 0, @@ -36,78 +43,111 @@ class Stat < Sequel::Model ips: [], referrers: {}, paths: {} - } unless site_logs[username] + } unless site_logs[log_time][username] - site_logs[username][:hits] += 1 - site_logs[username][:bandwidth] += size.to_i + total_site_stats[log_time] = { + hits: 0, + views: 0, + bandwidth: 0 + } unless total_site_stats[log_time] - unless site_logs[username][:view_ips].include?(ip) - site_logs[username][:views] += 1 - site_logs[username][:view_ips] << ip + site_logs[log_time][username][:hits] += 1 + site_logs[log_time][username][:bandwidth] += size.to_i + + 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? - site_logs[username][:referrers][referrer] ||= 0 - site_logs[username][:referrers][referrer] += 1 + site_logs[log_time][username][:referrers][referrer] ||= 0 + site_logs[log_time][username][:referrers][referrer] += 1 end end - site_logs[username][:paths][path] ||= 0 - site_logs[username][:paths][path] += 1 + site_logs[log_time][username][:paths][path] ||= 0 + site_logs[log_time][username][:paths][path] += 1 end 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 - site_logs.each do |username, site_log| - DB['update sites set hits=hits+?, views=views+? where username=?', - site_log[:hits], - site_log[:views], - username + site_logs.each do |log_time, usernames| + Site.select(:id, :username).where(username: usernames.keys).all.each do |site| + site_logs[log_time][site.username][:id] = site.id + end + + usernames.each do |username, site_log| + DB['update sites set hits=hits+?, views=views+? where username=?', + site_log[:hits], + site_log[:views], + username ].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 - DB[:stats].lock('EXCLUSIVE') { stat = Stat.create opts } if stat.nil? + stat = nil - DB[ - 'update stats set hits=hits+?, views=views+?, bandwidth=bandwidth+? where id=?', - site_log[:hits], - site_log[:views], - site_log[:bandwidth], - stat.id - ].first + DB[:stats].lock('EXCLUSIVE') { + stat = Stat.select(:id).where(opts).first + stat = Stat.create opts if stat.nil? + } + + DB[ + 'update stats set hits=hits+?, views=views+?, bandwidth=bandwidth+? where id=?', + site_log[:hits], + site_log[:views], + site_log[:bandwidth], + stat.id + ].first =begin - site_log[:referrers].each do |referrer, views| - 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 - end + site_log[:referrers].each do |referrer, views| + 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 + end - site_log[:view_ips].each do |ip| - site_location = StatLocation.create_or_get site_log[:id], ip - next if site_location.nil? - DB['update stat_locations set views=views+1 where id=?', site_location.id].first - end + site_log[:view_ips].each do |ip| + site_location = StatLocation.create_or_get site_log[:id], ip + next if site_location.nil? + DB['update stat_locations set views=views+1 where id=?', site_location.id].first + end - site_log[:paths].each do |path, views| - site_path = StatPath.create_or_get site_log[:id], path - next if site_path.nil? - DB['update stat_paths set views=views+? where id=?', views, site_path.id].first - end + site_log[:paths].each do |path, views| + site_path = StatPath.create_or_get site_log[:id], path + next if site_path.nil? + DB['update stat_paths set views=views+? where id=?', views, site_path.id].first + end =end + end end end FileUtils.rm log_path 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 diff --git a/public/cat.png b/public/cat.png new file mode 100644 index 00000000..7d8eeadb Binary files /dev/null and b/public/cat.png differ diff --git a/public/css/highlight/styles/agate.css b/public/css/highlight/styles/agate.css new file mode 100644 index 00000000..8d64547c --- /dev/null +++ b/public/css/highlight/styles/agate.css @@ -0,0 +1,108 @@ +/*! + * Agate by Taufik Nurrohman + * ---------------------------------------------------- + * + * #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; +} diff --git a/public/css/highlight/styles/androidstudio.css b/public/css/highlight/styles/androidstudio.css new file mode 100644 index 00000000..bc8e473b --- /dev/null +++ b/public/css/highlight/styles/androidstudio.css @@ -0,0 +1,66 @@ +/* +Date: 24 Fev 2015 +Author: Pedro Oliveira +*/ + +.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; +} diff --git a/public/css/highlight/styles/arta.css b/public/css/highlight/styles/arta.css new file mode 100644 index 00000000..75ef3a9e --- /dev/null +++ b/public/css/highlight/styles/arta.css @@ -0,0 +1,73 @@ +/* +Date: 17.V.2011 +Author: pumbur +*/ + +.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; +} diff --git a/public/css/highlight/styles/ascetic.css b/public/css/highlight/styles/ascetic.css new file mode 100644 index 00000000..48397e88 --- /dev/null +++ b/public/css/highlight/styles/ascetic.css @@ -0,0 +1,45 @@ +/* + +Original style from softwaremaniacs.org (c) Ivan Sagalaev + +*/ + +.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; +} diff --git a/public/css/highlight/styles/atelier-cave-dark.css b/public/css/highlight/styles/atelier-cave-dark.css new file mode 100644 index 00000000..65428f3b --- /dev/null +++ b/public/css/highlight/styles/atelier-cave-dark.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-cave-light.css b/public/css/highlight/styles/atelier-cave-light.css new file mode 100644 index 00000000..b419f9fd --- /dev/null +++ b/public/css/highlight/styles/atelier-cave-light.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-dune-dark.css b/public/css/highlight/styles/atelier-dune-dark.css new file mode 100644 index 00000000..1684f522 --- /dev/null +++ b/public/css/highlight/styles/atelier-dune-dark.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-dune-light.css b/public/css/highlight/styles/atelier-dune-light.css new file mode 100644 index 00000000..547719de --- /dev/null +++ b/public/css/highlight/styles/atelier-dune-light.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-estuary-dark.css b/public/css/highlight/styles/atelier-estuary-dark.css new file mode 100644 index 00000000..a5e50718 --- /dev/null +++ b/public/css/highlight/styles/atelier-estuary-dark.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-estuary-light.css b/public/css/highlight/styles/atelier-estuary-light.css new file mode 100644 index 00000000..1daee5d9 --- /dev/null +++ b/public/css/highlight/styles/atelier-estuary-light.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-forest-dark.css b/public/css/highlight/styles/atelier-forest-dark.css new file mode 100644 index 00000000..0ef4fae3 --- /dev/null +++ b/public/css/highlight/styles/atelier-forest-dark.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-forest-light.css b/public/css/highlight/styles/atelier-forest-light.css new file mode 100644 index 00000000..bbedde18 --- /dev/null +++ b/public/css/highlight/styles/atelier-forest-light.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-heath-dark.css b/public/css/highlight/styles/atelier-heath-dark.css new file mode 100644 index 00000000..fe01ff72 --- /dev/null +++ b/public/css/highlight/styles/atelier-heath-dark.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-heath-light.css b/public/css/highlight/styles/atelier-heath-light.css new file mode 100644 index 00000000..ee43786d --- /dev/null +++ b/public/css/highlight/styles/atelier-heath-light.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-lakeside-dark.css b/public/css/highlight/styles/atelier-lakeside-dark.css new file mode 100644 index 00000000..a937d3bf --- /dev/null +++ b/public/css/highlight/styles/atelier-lakeside-dark.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-lakeside-light.css b/public/css/highlight/styles/atelier-lakeside-light.css new file mode 100644 index 00000000..6c7e8f9e --- /dev/null +++ b/public/css/highlight/styles/atelier-lakeside-light.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-plateau-dark.css b/public/css/highlight/styles/atelier-plateau-dark.css new file mode 100644 index 00000000..3bb05269 --- /dev/null +++ b/public/css/highlight/styles/atelier-plateau-dark.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-plateau-light.css b/public/css/highlight/styles/atelier-plateau-light.css new file mode 100644 index 00000000..5f0222be --- /dev/null +++ b/public/css/highlight/styles/atelier-plateau-light.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-savanna-dark.css b/public/css/highlight/styles/atelier-savanna-dark.css new file mode 100644 index 00000000..38f83143 --- /dev/null +++ b/public/css/highlight/styles/atelier-savanna-dark.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-savanna-light.css b/public/css/highlight/styles/atelier-savanna-light.css new file mode 100644 index 00000000..1ccd7c68 --- /dev/null +++ b/public/css/highlight/styles/atelier-savanna-light.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-seaside-dark.css b/public/css/highlight/styles/atelier-seaside-dark.css new file mode 100644 index 00000000..df29949c --- /dev/null +++ b/public/css/highlight/styles/atelier-seaside-dark.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-seaside-light.css b/public/css/highlight/styles/atelier-seaside-light.css new file mode 100644 index 00000000..9d960f29 --- /dev/null +++ b/public/css/highlight/styles/atelier-seaside-light.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-sulphurpool-dark.css b/public/css/highlight/styles/atelier-sulphurpool-dark.css new file mode 100644 index 00000000..c2ab7938 --- /dev/null +++ b/public/css/highlight/styles/atelier-sulphurpool-dark.css @@ -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; +} diff --git a/public/css/highlight/styles/atelier-sulphurpool-light.css b/public/css/highlight/styles/atelier-sulphurpool-light.css new file mode 100644 index 00000000..96c47d08 --- /dev/null +++ b/public/css/highlight/styles/atelier-sulphurpool-light.css @@ -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; +} diff --git a/public/css/highlight/styles/brown-paper.css b/public/css/highlight/styles/brown-paper.css new file mode 100644 index 00000000..f0197b92 --- /dev/null +++ b/public/css/highlight/styles/brown-paper.css @@ -0,0 +1,64 @@ +/* + +Brown Paper style from goldblog.com.ua (c) Zaripov Yura + +*/ + +.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; +} diff --git a/public/css/highlight/styles/brown-papersq.png b/public/css/highlight/styles/brown-papersq.png new file mode 100644 index 00000000..3813903d Binary files /dev/null and b/public/css/highlight/styles/brown-papersq.png differ diff --git a/public/css/highlight/styles/codepen-embed.css b/public/css/highlight/styles/codepen-embed.css new file mode 100644 index 00000000..195c4a07 --- /dev/null +++ b/public/css/highlight/styles/codepen-embed.css @@ -0,0 +1,60 @@ +/* + codepen.io Embed Theme + Author: Justin Perry + 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; +} diff --git a/public/css/highlight/styles/color-brewer.css b/public/css/highlight/styles/color-brewer.css new file mode 100644 index 00000000..7934d986 --- /dev/null +++ b/public/css/highlight/styles/color-brewer.css @@ -0,0 +1,71 @@ +/* + +Colorbrewer theme +Original: https://github.com/mbostock/colorbrewer-theme (c) Mike Bostock +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; +} diff --git a/public/css/highlight/styles/dark.css b/public/css/highlight/styles/dark.css new file mode 100644 index 00000000..b4724f5f --- /dev/null +++ b/public/css/highlight/styles/dark.css @@ -0,0 +1,63 @@ +/* + +Dark style from softwaremaniacs.org (c) Ivan Sagalaev + +*/ + +.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; +} diff --git a/public/css/highlight/styles/darkula.css b/public/css/highlight/styles/darkula.css new file mode 100644 index 00000000..c01f9a7f --- /dev/null +++ b/public/css/highlight/styles/darkula.css @@ -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; +} diff --git a/public/css/highlight/styles/default.css b/public/css/highlight/styles/default.css new file mode 100644 index 00000000..aee40746 --- /dev/null +++ b/public/css/highlight/styles/default.css @@ -0,0 +1,77 @@ +/* + +Original highlight.js style (c) Ivan Sagalaev + +*/ + +.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; +} diff --git a/public/css/highlight/styles/docco.css b/public/css/highlight/styles/docco.css new file mode 100644 index 00000000..db366be3 --- /dev/null +++ b/public/css/highlight/styles/docco.css @@ -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; +} diff --git a/public/css/highlight/styles/far.css b/public/css/highlight/styles/far.css new file mode 100644 index 00000000..2b3f87b5 --- /dev/null +++ b/public/css/highlight/styles/far.css @@ -0,0 +1,71 @@ +/* + +FAR Style (c) MajestiC + +*/ + +.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; +} diff --git a/public/css/highlight/styles/foundation.css b/public/css/highlight/styles/foundation.css new file mode 100644 index 00000000..f1fe64b3 --- /dev/null +++ b/public/css/highlight/styles/foundation.css @@ -0,0 +1,88 @@ +/* +Description: Foundation 4 docs style for highlight.js +Author: Dan Allen +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; +} diff --git a/public/css/highlight/styles/github-gist.css b/public/css/highlight/styles/github-gist.css new file mode 100644 index 00000000..155f0b91 --- /dev/null +++ b/public/css/highlight/styles/github-gist.css @@ -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; +} diff --git a/public/css/highlight/styles/github.css b/public/css/highlight/styles/github.css new file mode 100644 index 00000000..791932b8 --- /dev/null +++ b/public/css/highlight/styles/github.css @@ -0,0 +1,99 @@ +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.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; +} diff --git a/public/css/highlight/styles/googlecode.css b/public/css/highlight/styles/googlecode.css new file mode 100644 index 00000000..884ad635 --- /dev/null +++ b/public/css/highlight/styles/googlecode.css @@ -0,0 +1,89 @@ +/* + +Google Code style (c) Aahan Krish + +*/ + +.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; +} diff --git a/public/css/highlight/styles/grayscale.css b/public/css/highlight/styles/grayscale.css new file mode 100644 index 00000000..5376f340 --- /dev/null +++ b/public/css/highlight/styles/grayscale.css @@ -0,0 +1,101 @@ +/* + +grayscale style (c) MY Sun + +*/ + +.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; +} diff --git a/public/css/highlight/styles/hopscotch.css b/public/css/highlight/styles/hopscotch.css new file mode 100644 index 00000000..32e60d23 --- /dev/null +++ b/public/css/highlight/styles/hopscotch.css @@ -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; +} diff --git a/public/css/highlight/styles/hybrid.css b/public/css/highlight/styles/hybrid.css new file mode 100644 index 00000000..29735a18 --- /dev/null +++ b/public/css/highlight/styles/hybrid.css @@ -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; +} diff --git a/public/css/highlight/styles/idea.css b/public/css/highlight/styles/idea.css new file mode 100644 index 00000000..3bf1892b --- /dev/null +++ b/public/css/highlight/styles/idea.css @@ -0,0 +1,97 @@ +/* + +Intellij Idea-like styling (c) Vasily Polovnyov + +*/ + +.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; +} diff --git a/public/css/highlight/styles/ir-black.css b/public/css/highlight/styles/ir-black.css new file mode 100644 index 00000000..bd4c755e --- /dev/null +++ b/public/css/highlight/styles/ir-black.css @@ -0,0 +1,73 @@ +/* + IR_Black style (c) Vasily Mikhailitchenko +*/ + +.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; +} diff --git a/public/css/highlight/styles/kimbie.dark.css b/public/css/highlight/styles/kimbie.dark.css new file mode 100644 index 00000000..d139cb5d --- /dev/null +++ b/public/css/highlight/styles/kimbie.dark.css @@ -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; +} diff --git a/public/css/highlight/styles/kimbie.light.css b/public/css/highlight/styles/kimbie.light.css new file mode 100644 index 00000000..04ff6ed3 --- /dev/null +++ b/public/css/highlight/styles/kimbie.light.css @@ -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; +} diff --git a/public/css/highlight/styles/magula.css b/public/css/highlight/styles/magula.css new file mode 100644 index 00000000..44dee5e8 --- /dev/null +++ b/public/css/highlight/styles/magula.css @@ -0,0 +1,70 @@ +/* +Description: Magula style for highligh.js +Author: Ruslan Keba +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; +} diff --git a/public/css/highlight/styles/mono-blue.css b/public/css/highlight/styles/mono-blue.css new file mode 100644 index 00000000..884c97c7 --- /dev/null +++ b/public/css/highlight/styles/mono-blue.css @@ -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; +} diff --git a/public/css/highlight/styles/monokai-sublime.css b/public/css/highlight/styles/monokai-sublime.css new file mode 100644 index 00000000..2864170d --- /dev/null +++ b/public/css/highlight/styles/monokai-sublime.css @@ -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; +} diff --git a/public/css/highlight/styles/monokai.css b/public/css/highlight/styles/monokai.css new file mode 100644 index 00000000..775d53f9 --- /dev/null +++ b/public/css/highlight/styles/monokai.css @@ -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; +} diff --git a/public/css/highlight/styles/obsidian.css b/public/css/highlight/styles/obsidian.css new file mode 100644 index 00000000..356630fa --- /dev/null +++ b/public/css/highlight/styles/obsidian.css @@ -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; +} diff --git a/public/css/highlight/styles/paraiso-dark.css b/public/css/highlight/styles/paraiso-dark.css new file mode 100644 index 00000000..e7292401 --- /dev/null +++ b/public/css/highlight/styles/paraiso-dark.css @@ -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; +} diff --git a/public/css/highlight/styles/paraiso-light.css b/public/css/highlight/styles/paraiso-light.css new file mode 100644 index 00000000..944857cd --- /dev/null +++ b/public/css/highlight/styles/paraiso-light.css @@ -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; +} diff --git a/public/css/highlight/styles/pojoaque.css b/public/css/highlight/styles/pojoaque.css new file mode 100644 index 00000000..2e07847b --- /dev/null +++ b/public/css/highlight/styles/pojoaque.css @@ -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; +} diff --git a/public/css/highlight/styles/pojoaque.jpg b/public/css/highlight/styles/pojoaque.jpg new file mode 100644 index 00000000..9c07d4ab Binary files /dev/null and b/public/css/highlight/styles/pojoaque.jpg differ diff --git a/public/css/highlight/styles/railscasts.css b/public/css/highlight/styles/railscasts.css new file mode 100644 index 00000000..008cdc5b --- /dev/null +++ b/public/css/highlight/styles/railscasts.css @@ -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; +} diff --git a/public/css/highlight/styles/rainbow.css b/public/css/highlight/styles/rainbow.css new file mode 100644 index 00000000..905eb8ef --- /dev/null +++ b/public/css/highlight/styles/rainbow.css @@ -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; +} diff --git a/public/css/highlight/styles/school-book.css b/public/css/highlight/styles/school-book.css new file mode 100644 index 00000000..964b51d8 --- /dev/null +++ b/public/css/highlight/styles/school-book.css @@ -0,0 +1,72 @@ +/* + +School Book style from goldblog.com.ua (c) Zaripov Yura + +*/ + +.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; +} diff --git a/public/css/highlight/styles/school-book.png b/public/css/highlight/styles/school-book.png new file mode 100644 index 00000000..956e9790 Binary files /dev/null and b/public/css/highlight/styles/school-book.png differ diff --git a/public/css/highlight/styles/solarized-dark.css b/public/css/highlight/styles/solarized-dark.css new file mode 100644 index 00000000..b4c0da1f --- /dev/null +++ b/public/css/highlight/styles/solarized-dark.css @@ -0,0 +1,84 @@ +/* + +Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #002b36; + color: #839496; +} + +.hljs-comment, +.hljs-quote { + color: #586e75; +} + +/* Solarized Green */ +.hljs-keyword, +.hljs-selector-tag, +.hljs-addition { + color: #859900; +} + +/* Solarized Cyan */ +.hljs-number, +.hljs-string, +.hljs-meta .hljs-meta-string, +.hljs-literal, +.hljs-doctag, +.hljs-regexp { + color: #2aa198; +} + +/* Solarized Blue */ +.hljs-title, +.hljs-section, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #268bd2; +} + +/* Solarized Yellow */ +.hljs-attribute, +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-class .hljs-title, +.hljs-type { + color: #b58900; +} + +/* Solarized Orange */ +.hljs-symbol, +.hljs-bullet, +.hljs-subst, +.hljs-meta, +.hljs-meta .hljs-keyword, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-link { + color: #cb4b16; +} + +/* Solarized Red */ +.hljs-built_in, +.hljs-deletion { + color: #dc322f; +} + +.hljs-formula { + background: #073642; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/public/css/highlight/styles/solarized-light.css b/public/css/highlight/styles/solarized-light.css new file mode 100644 index 00000000..fdcfcc72 --- /dev/null +++ b/public/css/highlight/styles/solarized-light.css @@ -0,0 +1,84 @@ +/* + +Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #fdf6e3; + color: #657b83; +} + +.hljs-comment, +.hljs-quote { + color: #93a1a1; +} + +/* Solarized Green */ +.hljs-keyword, +.hljs-selector-tag, +.hljs-addition { + color: #859900; +} + +/* Solarized Cyan */ +.hljs-number, +.hljs-string, +.hljs-meta .hljs-meta-string, +.hljs-literal, +.hljs-doctag, +.hljs-regexp { + color: #2aa198; +} + +/* Solarized Blue */ +.hljs-title, +.hljs-section, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #268bd2; +} + +/* Solarized Yellow */ +.hljs-attribute, +.hljs-attr, +.hljs-variable, +.hljs-template-variable, +.hljs-class .hljs-title, +.hljs-type { + color: #b58900; +} + +/* Solarized Orange */ +.hljs-symbol, +.hljs-bullet, +.hljs-subst, +.hljs-meta, +.hljs-meta .hljs-keyword, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-link { + color: #cb4b16; +} + +/* Solarized Red */ +.hljs-built_in, +.hljs-deletion { + color: #dc322f; +} + +.hljs-formula { + background: #eee8d5; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/public/css/highlight/styles/sunburst.css b/public/css/highlight/styles/sunburst.css new file mode 100644 index 00000000..f56dd5e9 --- /dev/null +++ b/public/css/highlight/styles/sunburst.css @@ -0,0 +1,102 @@ +/* + +Sunburst-like style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #000; + color: #f8f8f8; +} + +.hljs-comment, +.hljs-quote { + color: #aeaeae; + font-style: italic; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-type { + color: #e28964; +} + +.hljs-string { + color: #65b042; +} + +.hljs-subst { + color: #daefa3; +} + +.hljs-regexp, +.hljs-link { + color: #e9c062; +} + +.hljs-title, +.hljs-section, +.hljs-tag, +.hljs-name { + color: #89bdff; +} + +.hljs-class .hljs-title, +.hljs-doctag { + text-decoration: underline; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-number { + color: #3387cc; +} + +.hljs-params, +.hljs-variable, +.hljs-template-variable { + color: #3e87e3; +} + +.hljs-attribute { + color: #cda869; +} + +.hljs-meta { + color: #8996a8; +} + +.hljs-formula { + background-color: #0e2231; + color: #f8f8f8; + font-style: italic; +} + +.hljs-addition { + background-color: #253b22; + color: #f8f8f8; +} + +.hljs-deletion { + background-color: #420e09; + color: #f8f8f8; +} + +.hljs-selector-class { + color: #9b703f; +} + +.hljs-selector-id { + color: #8b98ab; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/public/css/highlight/styles/tomorrow-night-blue.css b/public/css/highlight/styles/tomorrow-night-blue.css new file mode 100644 index 00000000..78e59cc8 --- /dev/null +++ b/public/css/highlight/styles/tomorrow-night-blue.css @@ -0,0 +1,75 @@ +/* Tomorrow Night Blue Theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment, +.hljs-quote { + color: #7285b7; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #ff9da4; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #ffc58f; +} + +/* Tomorrow Yellow */ +.hljs-attribute { + color: #ffeead; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #d1f1a9; +} + +/* Tomorrow Blue */ +.hljs-title, +.hljs-section { + color: #bbdaff; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #ebbbff; +} + +.hljs { + display: block; + overflow-x: auto; + background: #002451; + color: white; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/public/css/highlight/styles/tomorrow-night-bright.css b/public/css/highlight/styles/tomorrow-night-bright.css new file mode 100644 index 00000000..e05af8ae --- /dev/null +++ b/public/css/highlight/styles/tomorrow-night-bright.css @@ -0,0 +1,74 @@ +/* Tomorrow Night Bright Theme */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment, +.hljs-quote { + color: #969896; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #d54e53; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #e78c45; +} + +/* Tomorrow Yellow */ +.hljs-attribute { + color: #e7c547; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #b9ca4a; +} + +/* Tomorrow Blue */ +.hljs-title, +.hljs-section { + color: #7aa6da; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #c397d8; +} + +.hljs { + display: block; + overflow-x: auto; + background: black; + color: #eaeaea; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/public/css/highlight/styles/tomorrow-night-eighties.css b/public/css/highlight/styles/tomorrow-night-eighties.css new file mode 100644 index 00000000..08fd51c7 --- /dev/null +++ b/public/css/highlight/styles/tomorrow-night-eighties.css @@ -0,0 +1,74 @@ +/* Tomorrow Night Eighties Theme */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment, +.hljs-quote { + color: #999999; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #f2777a; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #f99157; +} + +/* Tomorrow Yellow */ +.hljs-attribute { + color: #ffcc66; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #99cc99; +} + +/* Tomorrow Blue */ +.hljs-title, +.hljs-section { + color: #6699cc; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #cc99cc; +} + +.hljs { + display: block; + overflow-x: auto; + background: #2d2d2d; + color: #cccccc; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/public/css/highlight/styles/tomorrow-night.css b/public/css/highlight/styles/tomorrow-night.css new file mode 100644 index 00000000..ddd270a4 --- /dev/null +++ b/public/css/highlight/styles/tomorrow-night.css @@ -0,0 +1,75 @@ +/* Tomorrow Night Theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment, +.hljs-quote { + color: #969896; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #cc6666; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #de935f; +} + +/* Tomorrow Yellow */ +.hljs-attribute { + color: #f0c674; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #b5bd68; +} + +/* Tomorrow Blue */ +.hljs-title, +.hljs-section { + color: #81a2be; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #b294bb; +} + +.hljs { + display: block; + overflow-x: auto; + background: #1d1f21; + color: #c5c8c6; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/public/css/highlight/styles/tomorrow.css b/public/css/highlight/styles/tomorrow.css new file mode 100644 index 00000000..026a62fe --- /dev/null +++ b/public/css/highlight/styles/tomorrow.css @@ -0,0 +1,72 @@ +/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment, +.hljs-quote { + color: #8e908c; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-tag, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-regexp, +.hljs-deletion { + color: #c82829; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params, +.hljs-meta, +.hljs-link { + color: #f5871f; +} + +/* Tomorrow Yellow */ +.hljs-attribute { + color: #eab700; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet, +.hljs-addition { + color: #718c00; +} + +/* Tomorrow Blue */ +.hljs-title, +.hljs-section { + color: #4271ae; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #8959a8; +} + +.hljs { + display: block; + overflow-x: auto; + background: white; + color: #4d4d4c; + padding: 0.5em; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/public/css/highlight/styles/vs.css b/public/css/highlight/styles/vs.css new file mode 100644 index 00000000..c5d07d31 --- /dev/null +++ b/public/css/highlight/styles/vs.css @@ -0,0 +1,68 @@ +/* + +Visual Studio-like style based on original C# coloring by Jason Diamond + +*/ +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: white; + color: black; +} + +.hljs-comment, +.hljs-quote, +.hljs-variable { + color: #008000; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-built_in, +.hljs-name, +.hljs-tag { + color: #00f; +} + +.hljs-string, +.hljs-title, +.hljs-section, +.hljs-attribute, +.hljs-literal, +.hljs-template-tag, +.hljs-template-variable, +.hljs-type, +.hljs-addition { + color: #a31515; +} + +.hljs-deletion, +.hljs-selector-attr, +.hljs-selector-pseudo, +.hljs-meta { + color: #2b91af; +} + +.hljs-doctag { + color: #808080; +} + +.hljs-attr { + color: #f00; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link { + color: #00b0e8; +} + + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/public/css/highlight/styles/xcode.css b/public/css/highlight/styles/xcode.css new file mode 100644 index 00000000..43dddad8 --- /dev/null +++ b/public/css/highlight/styles/xcode.css @@ -0,0 +1,93 @@ +/* + +XCode style (c) Angel Garcia + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #fff; + color: black; +} + +.hljs-comment, +.hljs-quote { + color: #006a00; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-literal { + color: #aa0d91; +} + +.hljs-name { + color: #008; +} + +.hljs-variable, +.hljs-template-variable { + color: #660; +} + +.hljs-string { + color: #c41a16; +} + +.hljs-regexp, +.hljs-link { + color: #080; +} + +.hljs-title, +.hljs-tag, +.hljs-symbol, +.hljs-bullet, +.hljs-number, +.hljs-meta { + color: #1c00cf; +} + +.hljs-section, +.hljs-class .hljs-title, +.hljs-type, +.hljs-attr, +.hljs-built_in, +.hljs-builtin-name, +.hljs-params { + color: #5c2699; +} + +.hljs-attribute, +.hljs-subst { + color: #000; +} + +.hljs-formula { + background-color: #eee; + font-style: italic; +} + +.hljs-addition { + background-color: #baeeba; +} + +.hljs-deletion { + background-color: #ffc8bd; +} + +.hljs-selector-id, +.hljs-selector-class { + color: #9b703f; +} + +.hljs-doctag, +.hljs-strong { + font-weight: bold; +} + +.hljs-emphasis { + font-style: italic; +} diff --git a/public/css/highlight/styles/zenburn.css b/public/css/highlight/styles/zenburn.css new file mode 100644 index 00000000..07be5020 --- /dev/null +++ b/public/css/highlight/styles/zenburn.css @@ -0,0 +1,80 @@ +/* + +Zenburn style from voldmar.ru (c) Vladimir Epifanov +based on dark.css by Ivan Sagalaev + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + background: #3f3f3f; + color: #dcdcdc; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-tag { + color: #e3ceab; +} + +.hljs-template-tag { + color: #dcdcdc; +} + +.hljs-number { + color: #8cd0d3; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-attribute { + color: #efdcbc; +} + +.hljs-literal { + color: #efefaf; +} + +.hljs-subst { + color: #8f8f8f; +} + +.hljs-title, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class, +.hljs-section, +.hljs-type { + color: #efef8f; +} + +.hljs-symbol, +.hljs-bullet, +.hljs-link { + color: #dca3a3; +} + +.hljs-deletion, +.hljs-string, +.hljs-built_in, +.hljs-builtin-name { + color: #cc9393; +} + +.hljs-addition, +.hljs-comment, +.hljs-quote, +.hljs-meta { + color: #7f9f7f; +} + + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/public/css/neo.css.map b/public/css/neo.css.map new file mode 100644 index 00000000..c77f028a --- /dev/null +++ b/public/css/neo.css.map @@ -0,0 +1,7 @@ +{ +"version": 3, +"mappings": "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", +"sources": ["../../sass/neo.scss","../../sass/_base-sass/_basic.scss","../../sass/_helper-sass/_mixins.scss","../../sass/_base-sass/_base-HTML5.scss","../../sass/_base-sass/_base-Media.scss","../../sass/_project-sass/_project-Vars.scss","../../sass/_base-sass/_typography.scss","../../sass/_base-sass/_type-Code.scss","../../sass/_base-sass/_type-Lists.scss","../../sass/_base-sass/_base-Form.scss","../../sass/_base-sass/_tables.scss","../../sass/_helper-sass/_layout.scss","../../sass/_base-sass/_navs.scss","../../sass/_base-sass/_forms.scss","../../sass/_helper-sass/_buttons.scss","../../sass/_helper-sass/_navs.scss","../../sass/_helper-sass/_helper.scss","../../sass/_helper-sass/_type.scss","../../sass/_project-sass/_project-Type.scss","../../sass/_project-sass/_project-Base.scss","../../sass/_project-sass/_project-Header.scss","../../sass/_project-sass/_project-Main.scss","../../sass/_project-sass/_project-Footer.scss","../../sass/_project-sass/_project-Website-Gallery.scss","../../sass/_project-sass/_project-Tutorial.scss","../../sass/_tidy.scss"], +"names": [], +"file": "neo.css" +} \ No newline at end of file diff --git a/public/img/discourse-logo.png b/public/img/discourse-logo.png new file mode 100644 index 00000000..a0e952f1 Binary files /dev/null and b/public/img/discourse-logo.png differ diff --git a/public/img/front-browse-screenshot.jpg b/public/img/front-browse-screenshot.jpg new file mode 100644 index 00000000..5df8119c Binary files /dev/null and b/public/img/front-browse-screenshot.jpg differ diff --git a/public/img/front-follow-screenshot.jpg b/public/img/front-follow-screenshot.jpg new file mode 100644 index 00000000..231dd63f Binary files /dev/null and b/public/img/front-follow-screenshot.jpg differ diff --git a/public/img/kickstarterendpenelope.png b/public/img/kickstarterendpenelope.png new file mode 100644 index 00000000..c2f61c64 Binary files /dev/null and b/public/img/kickstarterendpenelope.png differ diff --git a/public/img/tutorial/ch1pg1.png b/public/img/tutorial/ch1pg1.png new file mode 100644 index 00000000..09be5c38 Binary files /dev/null and b/public/img/tutorial/ch1pg1.png differ diff --git a/public/img/tutorial/ch1pg10.png b/public/img/tutorial/ch1pg10.png new file mode 100644 index 00000000..485fb02f Binary files /dev/null and b/public/img/tutorial/ch1pg10.png differ diff --git a/public/img/tutorial/ch1pg1_2.png b/public/img/tutorial/ch1pg1_2.png new file mode 100644 index 00000000..62404533 Binary files /dev/null and b/public/img/tutorial/ch1pg1_2.png differ diff --git a/public/img/tutorial/ch1pg2.png b/public/img/tutorial/ch1pg2.png new file mode 100644 index 00000000..64b0e3a1 Binary files /dev/null and b/public/img/tutorial/ch1pg2.png differ diff --git a/public/img/tutorial/ch1pg2_2.png b/public/img/tutorial/ch1pg2_2.png new file mode 100644 index 00000000..3fbaa935 Binary files /dev/null and b/public/img/tutorial/ch1pg2_2.png differ diff --git a/public/img/tutorial/ch1pg3.png b/public/img/tutorial/ch1pg3.png new file mode 100644 index 00000000..5df04e0a Binary files /dev/null and b/public/img/tutorial/ch1pg3.png differ diff --git a/public/img/tutorial/ch1pg4.png b/public/img/tutorial/ch1pg4.png new file mode 100644 index 00000000..dfe9fa81 Binary files /dev/null and b/public/img/tutorial/ch1pg4.png differ diff --git a/public/img/tutorial/ch1pg5.png b/public/img/tutorial/ch1pg5.png new file mode 100644 index 00000000..0f369db2 Binary files /dev/null and b/public/img/tutorial/ch1pg5.png differ diff --git a/public/img/tutorial/ch1pg6.png b/public/img/tutorial/ch1pg6.png new file mode 100644 index 00000000..71ef3165 Binary files /dev/null and b/public/img/tutorial/ch1pg6.png differ diff --git a/public/img/tutorial/ch1pg7.png b/public/img/tutorial/ch1pg7.png new file mode 100644 index 00000000..6620a4e3 Binary files /dev/null and b/public/img/tutorial/ch1pg7.png differ diff --git a/public/img/tutorial/ch1pg8.png b/public/img/tutorial/ch1pg8.png new file mode 100644 index 00000000..c20fd57a Binary files /dev/null and b/public/img/tutorial/ch1pg8.png differ diff --git a/public/img/tutorial/ch1pg9.png b/public/img/tutorial/ch1pg9.png new file mode 100644 index 00000000..54d661a3 Binary files /dev/null and b/public/img/tutorial/ch1pg9.png differ diff --git a/public/js/highlight.pack.js b/public/js/highlight.pack.js new file mode 100644 index 00000000..6daf8698 --- /dev/null +++ b/public/js/highlight.pack.js @@ -0,0 +1,2 @@ +/*! highlight.js v9.0.0 | BSD3 License | git.io/hljslicense */ +!function(e){"undefined"!=typeof exports?e(exports):(self.hljs=e({}),"function"==typeof define&&define.amd&&define("hljs",[],function(){return self.hljs}))}(function(e){function n(e){return e.replace(/&/gm,"&").replace(//gm,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0==t.index}function a(e){return/^(no-?highlight|plain|text)$/i.test(e)}function i(e){var n,t,r,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=/\blang(?:uage)?-([\w-]+)\b/i.exec(i))return E(t[1])?t[1]:"no-highlight";for(i=i.split(/\s+/),n=0,r=i.length;r>n;n++)if(E(i[n])||a(i[n]))return i[n]}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3==i.nodeType?a+=i.nodeValue.length:1==i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!=r[0].offset?e[0].offset"}function u(e){l+=""}function c(e){("start"==e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substr(s,g[0].offset-s)),s=g[0].offset,g==e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g==e&&g.length&&g[0].offset==s);f.reverse().forEach(o)}else"start"==g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?c("keyword",a.k):Object.keys(a.k).forEach(function(e){c(e,a.k[e])}),a.k=u}a.lR=t(a.l||/\b\w+\b/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),void 0===a.r&&(a.r=1),a.c||(a.c=[]);var s=[];a.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"==e?a:e)}),a.c=s,a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var l=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,a,i){function o(e,n){for(var t=0;t";return i+=e+'">',i+n+o}function p(){if(!L.k)return n(M);var e="",t=0;L.lR.lastIndex=0;for(var r=L.lR.exec(M);r;){e+=n(M.substr(t,r.index-t));var a=g(L,r);a?(B+=a[1],e+=h(a[0],n(r[0]))):e+=n(r[0]),t=L.lR.lastIndex,r=L.lR.exec(M)}return e+n(M.substr(t))}function d(){var e="string"==typeof L.sL;if(e&&!R[L.sL])return n(M);var t=e?l(L.sL,M,!0,y[L.sL]):f(M,L.sL.length?L.sL:void 0);return L.r>0&&(B+=t.r),e&&(y[L.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){return void 0!==L.sL?d():p()}function v(e,t){var r=e.cN?h(e.cN,"",!0):"";e.rB?(k+=r,M=""):e.eB?(k+=n(t)+r,M=""):(k+=r,M=t),L=Object.create(e,{parent:{value:L}})}function m(e,t){if(M+=e,void 0===t)return k+=b(),0;var r=o(t,L);if(r)return k+=b(),v(r,t),r.rB?0:t.length;var a=u(L,t);if(a){var i=L;i.rE||i.eE||(M+=t),k+=b();do L.cN&&(k+=""),B+=L.r,L=L.parent;while(L!=a.parent);return i.eE&&(k+=n(t)),M="",a.starts&&v(a.starts,""),i.rE?0:t.length}if(c(t,L))throw new Error('Illegal lexeme "'+t+'" for mode "'+(L.cN||"")+'"');return M+=t,t.length||1}var N=E(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var w,L=i||N,y={},k="";for(w=L;w!=N;w=w.parent)w.cN&&(k=h(w.cN,"",!0)+k);var M="",B=0;try{for(var C,j,I=0;;){if(L.t.lastIndex=I,C=L.t.exec(t),!C)break;j=m(t.substr(I,C.index-I),C[0]),I=C.index+j}for(m(t.substr(I)),w=L;w.parent;w=w.parent)w.cN&&(k+="");return{r:B,value:k,language:e,top:L}}catch(O){if(-1!=O.message.indexOf("Illegal"))return{r:0,value:n(t)};throw O}}function f(e,t){t=t||x.languages||Object.keys(R);var r={r:0,value:n(e)},a=r;return t.forEach(function(n){if(E(n)){var t=l(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}}),a.language&&(r.second_best=a),r}function g(e){return x.tabReplace&&(e=e.replace(/^((<[^>]+>|\t)+)/gm,function(e,n){return n.replace(/\t/g,x.tabReplace)})),x.useBR&&(e=e.replace(/\n/g,"
")),e}function h(e,n,t){var r=n?w[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function p(e){var n=i(e);if(!a(n)){var t;x.useBR?(t=document.createElementNS("http://www.w3.org/1999/xhtml","div"),t.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):t=e;var r=t.textContent,o=n?l(n,r,!0):f(r),s=u(t);if(s.length){var p=document.createElementNS("http://www.w3.org/1999/xhtml","div");p.innerHTML=o.value,o.value=c(s,u(p),r)}o.value=g(o.value),e.innerHTML=o.value,e.className=h(e.className,n,o.language),e.result={language:o.language,re:o.r},o.second_best&&(e.second_best={language:o.second_best.language,re:o.second_best.r})}}function d(e){x=o(x,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");Array.prototype.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=R[n]=t(e);r.aliases&&r.aliases.forEach(function(e){w[e]=n})}function N(){return Object.keys(R)}function E(e){return e=(e||"").toLowerCase(),R[e]||R[w[e]]}var x={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},R={},w={};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=E,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e});hljs.registerLanguage("xml",function(s){var t="[A-Za-z0-9\\._:-]+",e={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php"},r={eW:!0,i:/]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[r],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[r],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},e,{cN:"meta",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},r]}]}});hljs.registerLanguage("php",function(e){var c={b:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},a={cN:"meta",b:/<\?(php)?|\?>/},i={cN:"string",c:[e.BE,a],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},e.inherit(e.ASM,{i:null}),e.inherit(e.QSM,{i:null})]},t={v:[e.BNM,e.CNM]};return{aliases:["php3","php4","php5","php6"],cI:!0,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[e.CLCM,e.HCM,e.C("/\\*","\\*/",{c:[{cN:"doctag",b:"@[A-Za-z]+"},a]}),e.C("__halt_compiler.+?;",!1,{eW:!0,k:"__halt_compiler",l:e.UIR}),{cN:"string",b:/<<<['"]?\w+['"]?$/,e:/^\w+;?$/,c:[e.BE,{cN:"subst",v:[{b:/\$\w+/},{b:/\{\$/,e:/\}/}]}]},a,c,{b:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{cN:"function",bK:"function",e:/[;{]/,eE:!0,i:"\\$|\\[|%",c:[e.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",c,e.CBCM,i,t]}]},{cN:"class",bK:"class interface",e:"{",eE:!0,i:/[:\(\$"]/,c:[{bK:"extends implements"},e.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[e.UTM]},{bK:"use",e:";",c:[e.UTM]},{b:"=>"},i,t]}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\s*\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"']+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("python",function(e){var r={cN:"meta",b:/^(>>>|\.\.\.) /},b={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[r],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[r],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},e.ASM,e.QSM]},a={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},l={cN:"params",b:/\(/,e:/\)/,c:["self",r,a,b]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:[r,a,b,e.HCM,{v:[{cN:"function",bK:"def",r:10},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,l]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("json",function(e){var t={literal:"true false null"},i=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:i,k:t},s={b:"{",e:"}",c:[{cN:"attr",b:'\\s*"',e:'"\\s*:\\s*',eB:!0,eE:!0,c:[e.BE],i:"\\n",starts:r}],i:"\\S"},n={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return i.splice(i.length,0,s,n),{c:i,k:t,i:"\\S"}});hljs.registerLanguage("javascript",function(e){return{aliases:["js"],k:{keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{b:/\s*[);\]]/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:[e.CLCM,e.CBCM]}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#/}});hljs.registerLanguage("ruby",function(e){var b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",c="and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",r={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[r]}),e.C("^\\=begin","^\\=end",{c:[r],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:c},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:c},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d,i.c=d;var o="[>?]>",l="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",w=[{b:/^\s*=>/,starts:{e:"$",c:d}},{cN:"meta",b:"^("+o+"|"+l+"|"+u+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:c,i:/\/\*/,c:s.concat(w).concat(d)}}); \ No newline at end of file diff --git a/public/js/keyboard.js b/public/js/keyboard.js deleted file mode 100644 index 5a518d7d..00000000 --- a/public/js/keyboard.js +++ /dev/null @@ -1,961 +0,0 @@ -/** - * Title: KeyboardJS - * Version: v0.4.1 - * Description: KeyboardJS is a flexible and easy to use keyboard binding - * library. - * Author: Robert Hurst. - * - * Copyright 2011, Robert William Hurst - * Licenced under the BSD License. - * See https://raw.github.com/RobertWHurst/KeyboardJS/master/license.txt - */ -(function(context, factory) { - - //INDEXOF POLLYFILL - [].indexOf||(Array.prototype.indexOf=function(a,b,c){for(c=this.length,b=(c+~~b)%c;b"]], - ['shift + /', ["questionmark", "?"]] - ] - }; - //a-z and A-Z - for (aI = 65; aI <= 90; aI += 1) { - usLocale.map[aI] = String.fromCharCode(aI + 32); - usLocale.macros.push(['shift + ' + String.fromCharCode(aI + 32) + ', capslock + ' + String.fromCharCode(aI + 32), [String.fromCharCode(aI)]]); - } - registerLocale('us', usLocale); - getSetLocale('us'); - - - ////////// - // INIT // - ////////// - - //enable the library - enable(); - - - ///////// - // API // - ///////// - - //assemble the library and return it - KeyboardJS.enable = enable; - KeyboardJS.disable = disable; - KeyboardJS.activeKeys = getActiveKeys; - KeyboardJS.releaseKey = removeActiveKey; - KeyboardJS.pressKey = addActiveKey; - KeyboardJS.on = createBinding; - KeyboardJS.clear = removeBindingByKeyCombo; - KeyboardJS.clear.key = removeBindingByKeyName; - KeyboardJS.locale = getSetLocale; - KeyboardJS.locale.register = registerLocale; - KeyboardJS.macro = createMacro; - KeyboardJS.macro.remove = removeMacro; - KeyboardJS.key = {}; - KeyboardJS.key.name = getKeyName; - KeyboardJS.key.code = getKeyCode; - KeyboardJS.combo = {}; - KeyboardJS.combo.active = isSatisfiedCombo; - KeyboardJS.combo.parse = parseKeyCombo; - KeyboardJS.combo.stringify = stringifyKeyCombo; - return KeyboardJS; - - - ////////////////////// - // INSTANCE METHODS // - ////////////////////// - - /** - * Enables KeyboardJS - */ - function enable() { - if(targetWindow.addEventListener) { - targetWindow.document.addEventListener('keydown', keydown, false); - targetWindow.document.addEventListener('keyup', keyup, false); - targetWindow.addEventListener('blur', reset, false); - targetWindow.addEventListener('webkitfullscreenchange', reset, false); - targetWindow.addEventListener('mozfullscreenchange', reset, false); - } else if(targetWindow.attachEvent) { - targetWindow.document.attachEvent('onkeydown', keydown); - targetWindow.document.attachEvent('onkeyup', keyup); - targetWindow.attachEvent('onblur', reset); - } - } - - /** - * Exits all active bindings and disables KeyboardJS - */ - function disable() { - reset(); - if(targetWindow.removeEventListener) { - targetWindow.document.removeEventListener('keydown', keydown, false); - targetWindow.document.removeEventListener('keyup', keyup, false); - targetWindow.removeEventListener('blur', reset, false); - targetWindow.removeEventListener('webkitfullscreenchange', reset, false); - targetWindow.removeEventListener('mozfullscreenchange', reset, false); - } else if(targetWindow.detachEvent) { - targetWindow.document.detachEvent('onkeydown', keydown); - targetWindow.document.detachEvent('onkeyup', keyup); - targetWindow.detachEvent('onblur', reset); - } - } - - - //////////////////// - // EVENT HANDLERS // - //////////////////// - - /** - * Exits all active bindings. Optionally passes an event to all binding - * handlers. - * @param {KeyboardEvent} event [Optional] - */ - function reset(event) { - activeKeys = []; - pruneMacros(); - pruneBindings(event); - } - - /** - * Key down event handler. - * @param {KeyboardEvent} event - */ - function keydown(event) { - var keyNames, keyName, kI; - keyNames = getKeyName(event.keyCode); - if(keyNames.length < 1) { return; } - event.isRepeat = false; - for(kI = 0; kI < keyNames.length; kI += 1) { - keyName = keyNames[kI]; - if (getActiveKeys().indexOf(keyName) != -1) - event.isRepeat = true; - addActiveKey(keyName); - } - executeMacros(); - executeBindings(event); - } - - /** - * Key up event handler. - * @param {KeyboardEvent} event - */ - function keyup(event) { - var keyNames, kI; - keyNames = getKeyName(event.keyCode); - if(keyNames.length < 1) { return; } - for(kI = 0; kI < keyNames.length; kI += 1) { - removeActiveKey(keyNames[kI]); - } - pruneMacros(); - pruneBindings(event); - } - - /** - * Accepts a key code and returns the key names defined by the current - * locale. - * @param {Number} keyCode - * @return {Array} keyNames An array of key names defined for the key - * code as defined by the current locale. - */ - function getKeyName(keyCode) { - return map[keyCode] || []; - } - - /** - * Accepts a key name and returns the key code defined by the current - * locale. - * @param {Number} keyName - * @return {Number|false} - */ - function getKeyCode(keyName) { - var keyCode; - for(keyCode in map) { - if(!map.hasOwnProperty(keyCode)) { continue; } - if(map[keyCode].indexOf(keyName) > -1) { return keyCode; } - } - return false; - } - - - //////////// - // MACROS // - //////////// - - /** - * Accepts a key combo and an array of key names to inject once the key - * combo is satisfied. - * @param {String} combo - * @param {Array} injectedKeys - */ - function createMacro(combo, injectedKeys) { - if(typeof combo !== 'string' && (typeof combo !== 'object' || typeof combo.push !== 'function')) { - throw new Error("Cannot create macro. The combo must be a string or array."); - } - if(typeof injectedKeys !== 'object' || typeof injectedKeys.push !== 'function') { - throw new Error("Cannot create macro. The injectedKeys must be an array."); - } - macros.push([combo, injectedKeys]); - } - - /** - * Accepts a key combo and clears any and all macros bound to that key - * combo. - * @param {String} combo - */ - function removeMacro(combo) { - var macro; - if(typeof combo !== 'string' && (typeof combo !== 'object' || typeof combo.push !== 'function')) { throw new Error("Cannot remove macro. The combo must be a string or array."); } - for(mI = 0; mI < macros.length; mI += 1) { - macro = macros[mI]; - if(compareCombos(combo, macro[0])) { - removeActiveKey(macro[1]); - macros.splice(mI, 1); - break; - } - } - } - - /** - * Executes macros against the active keys. Each macro's key combo is - * checked and if found to be satisfied, the macro's key names are injected - * into active keys. - */ - function executeMacros() { - var mI, combo, kI; - for(mI = 0; mI < macros.length; mI += 1) { - combo = parseKeyCombo(macros[mI][0]); - if(activeMacros.indexOf(macros[mI]) === -1 && isSatisfiedCombo(combo)) { - activeMacros.push(macros[mI]); - for(kI = 0; kI < macros[mI][1].length; kI += 1) { - addActiveKey(macros[mI][1][kI]); - } - } - } - } - - /** - * Prunes active macros. Checks each active macro's key combo and if found - * to no longer to be satisfied, each of the macro's key names are removed - * from active keys. - */ - function pruneMacros() { - var mI, combo, kI; - for(mI = 0; mI < activeMacros.length; mI += 1) { - combo = parseKeyCombo(activeMacros[mI][0]); - if(isSatisfiedCombo(combo) === false) { - for(kI = 0; kI < activeMacros[mI][1].length; kI += 1) { - removeActiveKey(activeMacros[mI][1][kI]); - } - activeMacros.splice(mI, 1); - mI -= 1; - } - } - } - - - ////////////// - // BINDINGS // - ////////////// - - /** - * Creates a binding object, and, if provided, binds a key down hander and - * a key up handler. Returns a binding object that emits keyup and - * keydown events. - * @param {String} keyCombo - * @param {Function} keyDownCallback [Optional] - * @param {Function} keyUpCallback [Optional] - * @return {Object} binding - */ - function createBinding(keyCombo, keyDownCallback, keyUpCallback) { - var api = {}, binding, subBindings = [], bindingApi = {}, kI, - subCombo; - - //break the combo down into a combo array - if(typeof keyCombo === 'string') { - keyCombo = parseKeyCombo(keyCombo); - } - - //bind each sub combo contained within the combo string - for(kI = 0; kI < keyCombo.length; kI += 1) { - binding = {}; - - //stringify the combo again - subCombo = stringifyKeyCombo([keyCombo[kI]]); - - //validate the sub combo - if(typeof subCombo !== 'string') { throw new Error('Failed to bind key combo. The key combo must be string.'); } - - //create the binding - binding.keyCombo = subCombo; - binding.keyDownCallback = []; - binding.keyUpCallback = []; - - //inject the key down and key up callbacks if given - if(keyDownCallback) { binding.keyDownCallback.push(keyDownCallback); } - if(keyUpCallback) { binding.keyUpCallback.push(keyUpCallback); } - - //stash the new binding - bindings.push(binding); - subBindings.push(binding); - } - - //build the binding api - api.clear = clear; - api.on = on; - return api; - - /** - * Clears the binding - */ - function clear() { - var bI; - for(bI = 0; bI < subBindings.length; bI += 1) { - bindings.splice(bindings.indexOf(subBindings[bI]), 1); - } - } - - /** - * Accepts an event name. and any number of callbacks. When the event is - * emitted, all callbacks are executed. Available events are key up and - * key down. - * @param {String} eventName - * @return {Object} subBinding - */ - function on(eventName ) { - var api = {}, callbacks, cI, bI; - - //validate event name - if(typeof eventName !== 'string') { throw new Error('Cannot bind callback. The event name must be a string.'); } - if(eventName !== 'keyup' && eventName !== 'keydown') { throw new Error('Cannot bind callback. The event name must be a "keyup" or "keydown".'); } - - //gather the callbacks - callbacks = Array.prototype.slice.apply(arguments, [1]); - - //stash each the new binding - for(cI = 0; cI < callbacks.length; cI += 1) { - if(typeof callbacks[cI] === 'function') { - if(eventName === 'keyup') { - for(bI = 0; bI < subBindings.length; bI += 1) { - subBindings[bI].keyUpCallback.push(callbacks[cI]); - } - } else if(eventName === 'keydown') { - for(bI = 0; bI < subBindings.length; bI += 1) { - subBindings[bI].keyDownCallback.push(callbacks[cI]); - } - } - } - } - - //construct and return the sub binding api - api.clear = clear; - return api; - - /** - * Clears the binding - */ - function clear() { - var cI, bI; - for(cI = 0; cI < callbacks.length; cI += 1) { - if(typeof callbacks[cI] === 'function') { - if(eventName === 'keyup') { - for(bI = 0; bI < subBindings.length; bI += 1) { - subBindings[bI].keyUpCallback.splice(subBindings[bI].keyUpCallback.indexOf(callbacks[cI]), 1); - } - } else { - for(bI = 0; bI < subBindings.length; bI += 1) { - subBindings[bI].keyDownCallback.splice(subBindings[bI].keyDownCallback.indexOf(callbacks[cI]), 1); - } - } - } - } - } - } - } - - /** - * Clears all binding attached to a given key combo. Key name order does not - * matter as long as the key combos equate. - * @param {String} keyCombo - */ - function removeBindingByKeyCombo(keyCombo) { - var bI, binding, keyName; - for(bI = 0; bI < bindings.length; bI += 1) { - binding = bindings[bI]; - if(compareCombos(keyCombo, binding.keyCombo)) { - bindings.splice(bI, 1); bI -= 1; - } - } - } - - /** - * Clears all binding attached to key combos containing a given key name. - * @param {String} keyName - */ - function removeBindingByKeyName(keyName) { - var bI, kI, binding; - if(keyName) { - for(bI = 0; bI < bindings.length; bI += 1) { - binding = bindings[bI]; - for(kI = 0; kI < binding.keyCombo.length; kI += 1) { - if(binding.keyCombo[kI].indexOf(keyName) > -1) { - bindings.splice(bI, 1); bI -= 1; - break; - } - } - } - } else { - bindings = []; - } - } - - /** - * Executes bindings that are active. Only allows the keys to be used once - * as to prevent binding overlap. - * @param {KeyboardEvent} event The keyboard event. - */ - function executeBindings(event) { - var bI, sBI, binding, bindingKeys, remainingKeys, cI, killEventBubble, kI, bindingKeysSatisfied, - index, sortedBindings = [], bindingWeight; - - remainingKeys = [].concat(activeKeys); - for(bI = 0; bI < bindings.length; bI += 1) { - bindingWeight = extractComboKeys(bindings[bI].keyCombo).length; - if(!sortedBindings[bindingWeight]) { sortedBindings[bindingWeight] = []; } - sortedBindings[bindingWeight].push(bindings[bI]); - } - for(sBI = sortedBindings.length - 1; sBI >= 0; sBI -= 1) { - if(!sortedBindings[sBI]) { continue; } - for(bI = 0; bI < sortedBindings[sBI].length; bI += 1) { - binding = sortedBindings[sBI][bI]; - bindingKeys = extractComboKeys(binding.keyCombo); - bindingKeysSatisfied = true; - for(kI = 0; kI < bindingKeys.length; kI += 1) { - if(remainingKeys.indexOf(bindingKeys[kI]) === -1) { - bindingKeysSatisfied = false; - break; - } - } - if(bindingKeysSatisfied && isSatisfiedCombo(binding.keyCombo)) { - activeBindings.push(binding); - for(kI = 0; kI < bindingKeys.length; kI += 1) { - index = remainingKeys.indexOf(bindingKeys[kI]); - if(index > -1) { - remainingKeys.splice(index, 1); - kI -= 1; - } - } - for(cI = 0; cI < binding.keyDownCallback.length; cI += 1) { - if (binding.keyDownCallback[cI](event, getActiveKeys(), binding.keyCombo) === false) { - killEventBubble = true; - } - } - if(killEventBubble === true) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - /** - * Removes bindings that are no longer satisfied by the active keys. Also - * fires the key up callbacks. - * @param {KeyboardEvent} event - */ - function pruneBindings(event) { - var bI, cI, binding, killEventBubble; - for(bI = 0; bI < activeBindings.length; bI += 1) { - binding = activeBindings[bI]; - if(isSatisfiedCombo(binding.keyCombo) === false) { - for(cI = 0; cI < binding.keyUpCallback.length; cI += 1) { - if (binding.keyUpCallback[cI](event, getActiveKeys(), binding.keyCombo) === false) { - killEventBubble = true; - } - } - if(killEventBubble === true) { - event.preventDefault(); - event.stopPropagation(); - } - activeBindings.splice(bI, 1); - bI -= 1; - } - } - } - - - /////////////////// - // COMBO STRINGS // - /////////////////// - - /** - * Compares two key combos returning true when they are functionally - * equivalent. - * @param {String} keyComboArrayA keyCombo A key combo string or array. - * @param {String} keyComboArrayB keyCombo A key combo string or array. - * @return {Boolean} - */ - function compareCombos(keyComboArrayA, keyComboArrayB) { - var cI, sI, kI; - keyComboArrayA = parseKeyCombo(keyComboArrayA); - keyComboArrayB = parseKeyCombo(keyComboArrayB); - if(keyComboArrayA.length !== keyComboArrayB.length) { return false; } - for(cI = 0; cI < keyComboArrayA.length; cI += 1) { - if(keyComboArrayA[cI].length !== keyComboArrayB[cI].length) { return false; } - for(sI = 0; sI < keyComboArrayA[cI].length; sI += 1) { - if(keyComboArrayA[cI][sI].length !== keyComboArrayB[cI][sI].length) { return false; } - for(kI = 0; kI < keyComboArrayA[cI][sI].length; kI += 1) { - if(keyComboArrayB[cI][sI].indexOf(keyComboArrayA[cI][sI][kI]) === -1) { return false; } - } - } - } - return true; - } - - /** - * Checks to see if a key combo string or key array is satisfied by the - * currently active keys. It does not take into account spent keys. - * @param {String} keyCombo A key combo string or array. - * @return {Boolean} - */ - function isSatisfiedCombo(keyCombo) { - var cI, sI, stage, kI, stageOffset = 0, index, comboMatches; - keyCombo = parseKeyCombo(keyCombo); - for(cI = 0; cI < keyCombo.length; cI += 1) { - comboMatches = true; - stageOffset = 0; - for(sI = 0; sI < keyCombo[cI].length; sI += 1) { - stage = [].concat(keyCombo[cI][sI]); - for(kI = stageOffset; kI < activeKeys.length; kI += 1) { - index = stage.indexOf(activeKeys[kI]); - if(index > -1) { - stage.splice(index, 1); - stageOffset = kI; - } - } - if(stage.length !== 0) { comboMatches = false; break; } - } - if(comboMatches) { return true; } - } - return false; - } - - /** - * Accepts a key combo array or string and returns a flat array containing all keys referenced by - * the key combo. - * @param {String} keyCombo A key combo string or array. - * @return {Array} - */ - function extractComboKeys(keyCombo) { - var cI, sI, kI, keys = []; - keyCombo = parseKeyCombo(keyCombo); - for(cI = 0; cI < keyCombo.length; cI += 1) { - for(sI = 0; sI < keyCombo[cI].length; sI += 1) { - keys = keys.concat(keyCombo[cI][sI]); - } - } - return keys; - } - - /** - * Parses a key combo string into a 3 dimensional array. - * - Level 1 - sub combos. - * - Level 2 - combo stages. A stage is a set of key name pairs that must - * be satisfied in the order they are defined. - * - Level 3 - each key name to the stage. - * @param {String|Array} keyCombo A key combo string. - * @return {Array} - */ - function parseKeyCombo(keyCombo) { - var s = keyCombo, i = 0, op = 0, ws = false, nc = false, combos = [], combo = [], stage = [], key = ''; - - if(typeof keyCombo === 'object' && typeof keyCombo.push === 'function') { return keyCombo; } - if(typeof keyCombo !== 'string') { throw new Error('Cannot parse "keyCombo" because its type is "' + (typeof keyCombo) + '". It must be a "string".'); } - - //remove leading whitespace - while(s.charAt(i) === ' ') { i += 1; } - while(true) { - if(s.charAt(i) === ' ') { - //white space & next combo op - while(s.charAt(i) === ' ') { i += 1; } - ws = true; - } else if(s.charAt(i) === ',') { - if(op || nc) { throw new Error('Failed to parse key combo. Unexpected , at character index ' + i + '.'); } - nc = true; - i += 1; - } else if(s.charAt(i) === '+') { - //next key - if(key.length) { stage.push(key); key = ''; } - if(op || nc) { throw new Error('Failed to parse key combo. Unexpected + at character index ' + i + '.'); } - op = true; - i += 1; - } else if(s.charAt(i) === '>') { - //next stage op - if(key.length) { stage.push(key); key = ''; } - if(stage.length) { combo.push(stage); stage = []; } - if(op || nc) { throw new Error('Failed to parse key combo. Unexpected > at character index ' + i + '.'); } - op = true; - i += 1; - } else if(i < s.length - 1 && s.charAt(i) === '!' && (s.charAt(i + 1) === '>' || s.charAt(i + 1) === ',' || s.charAt(i + 1) === '+')) { - key += s.charAt(i + 1); - op = false; - ws = false; - nc = false; - i += 2; - } else if(i < s.length && s.charAt(i) !== '+' && s.charAt(i) !== '>' && s.charAt(i) !== ',' && s.charAt(i) !== ' ') { - //end combo - if(op === false && ws === true || nc === true) { - if(key.length) { stage.push(key); key = ''; } - if(stage.length) { combo.push(stage); stage = []; } - if(combo.length) { combos.push(combo); combo = []; } - } - op = false; - ws = false; - nc = false; - //key - while(i < s.length && s.charAt(i) !== '+' && s.charAt(i) !== '>' && s.charAt(i) !== ',' && s.charAt(i) !== ' ') { - key += s.charAt(i); - i += 1; - } - } else { - //unknown char - i += 1; - continue; - } - //end of combos string - if(i >= s.length) { - if(key.length) { stage.push(key); key = ''; } - if(stage.length) { combo.push(stage); stage = []; } - if(combo.length) { combos.push(combo); combo = []; } - break; - } - } - return combos; - } - - /** - * Stringifys a key combo. - * @param {Array|String} keyComboArray A key combo array. If a key - * combo string is given it will be returned. - * @return {String} - */ - function stringifyKeyCombo(keyComboArray) { - var cI, ccI, output = []; - if(typeof keyComboArray === 'string') { return keyComboArray; } - if(typeof keyComboArray !== 'object' || typeof keyComboArray.push !== 'function') { throw new Error('Cannot stringify key combo.'); } - for(cI = 0; cI < keyComboArray.length; cI += 1) { - output[cI] = []; - for(ccI = 0; ccI < keyComboArray[cI].length; ccI += 1) { - output[cI][ccI] = keyComboArray[cI][ccI].join(' + '); - } - output[cI] = output[cI].join(' > '); - } - return output.join(' '); - } - - - ///////////////// - // ACTIVE KEYS // - ///////////////// - - /** - * Returns the a copy of the active keys array. - * @return {Array} - */ - function getActiveKeys() { - return [].concat(activeKeys); - } - - /** - * Adds a key to the active keys array, but only if it has not already been - * added. - * @param {String} keyName The key name string. - */ - function addActiveKey(keyName) { - if(keyName.match(/\s/)) { throw new Error('Cannot add key name ' + keyName + ' to active keys because it contains whitespace.'); } - if(activeKeys.indexOf(keyName) > -1) { return; } - activeKeys.push(keyName); - } - - /** - * Removes a key from the active keys array. - * @param {String} keyNames The key name string. - */ - function removeActiveKey(keyName) { - var keyCode = getKeyCode(keyName); - if(keyCode === '91' || keyCode === '92') { activeKeys = []; } //remove all key on release of super. - else { activeKeys.splice(activeKeys.indexOf(keyName), 1); } - } - - - ///////////// - // LOCALES // - ///////////// - - /** - * Registers a new locale. This is useful if you would like to add support for a new keyboard layout. It could also be useful for - * alternative key names. For example if you program games you could create a locale for your key mappings. Instead of key 65 mapped - * to 'a' you could map it to 'jump'. - * @param {String} localeName The name of the new locale. - * @param {Object} localeMap The locale map. - */ - function registerLocale(localeName, localeMap) { - - //validate arguments - if(typeof localeName !== 'string') { throw new Error('Cannot register new locale. The locale name must be a string.'); } - if(typeof localeMap !== 'object') { throw new Error('Cannot register ' + localeName + ' locale. The locale map must be an object.'); } - if(typeof localeMap.map !== 'object') { throw new Error('Cannot register ' + localeName + ' locale. The locale map is invalid.'); } - - //stash the locale - if(!localeMap.macros) { localeMap.macros = []; } - locales[localeName] = localeMap; - } - - /** - * Swaps the current locale. - * @param {String} localeName The locale to activate. - * @return {Object} - */ - function getSetLocale(localeName) { - - //if a new locale is given then set it - if(localeName) { - if(typeof localeName !== 'string') { throw new Error('Cannot set locale. The locale name must be a string.'); } - if(!locales[localeName]) { throw new Error('Cannot set locale to ' + localeName + ' because it does not exist. If you would like to submit a ' + localeName + ' locale map for KeyboardJS please submit it at https://github.com/RobertWHurst/KeyboardJS/issues.'); } - - //set the current map and macros - map = locales[localeName].map; - macros = locales[localeName].macros; - - //set the current locale - locale = localeName; - } - - //return the current locale - return locale; - } -}); diff --git a/public/js/xregexp-min.js b/public/js/xregexp-min.js new file mode 100644 index 00000000..ade6f9a3 --- /dev/null +++ b/public/js/xregexp-min.js @@ -0,0 +1,2 @@ +//XRegExp 3.0.0 MIT License +var XRegExp=function(a){"use strict";function u(a,d,e,f,g){var h;if(a[c]={captureNames:d},g)return a;if(a.__proto__)a.__proto__=b.prototype;else for(h in b.prototype)a[h]=b.prototype[h];return a[c].source=e,a[c].flags=f?f.split("").sort().join(""):f,a}function v(a){return e.replace.call(a,/([\s\S])(?=[\s\S]*\1)/g,"")}function w(d,f){if(!b.isRegExp(d))throw new TypeError("Type RegExp expected");var g=d[c]||{},h=y(d),i="",j="",k=null,l=null;return f=f||{},f.removeG&&(j+="g"),f.removeY&&(j+="y"),j&&(h=e.replace.call(h,new RegExp("["+j+"]+","g"),"")),f.addG&&(i+="g"),f.addY&&(i+="y"),i&&(h=v(h+i)),f.isInternalOnly||(g.source!==a&&(k=g.source),null!=g.flags&&(l=i?v(g.flags+i):g.flags)),d=u(new RegExp(d.source,h),z(d)?g.captureNames.slice(0):null,k,l,f.isInternalOnly)}function x(a){return parseInt(a,16)}function y(a){return q?a.flags:e.exec.call(/\/([a-z]*)$/i,RegExp.prototype.toString.call(a))[1]}function z(a){return!(!a[c]||!a[c].captureNames)}function A(a){return parseInt(a,10).toString(16)}function B(a,b){var d,c=a.length;for(d=0;c>d;++d)if(a[d]===b)return d;return-1}function C(a,b){return s.call(a)==="[object "+b+"]"}function D(a,b,c){return e.test.call(c.indexOf("x")>-1?/^(?:\s+|#.*|\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/:/^(?:\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/,a.slice(b))}function E(a){for(;a.length<4;)a="0"+a;return a}function F(a,b){var c;if(v(b)!==b)throw new SyntaxError("Invalid duplicate regex flag "+b);for(a=e.replace.call(a,/^\(\?([\w$]+)\)/,function(a,c){if(e.test.call(/[gy]/,c))throw new SyntaxError("Cannot use flag g or y in mode modifier "+a);return b=v(b+c),""}),c=0;c"}else if(c)return"\\"+(+c+i);return a};if(!C(a,"Array")||!a.length)throw new TypeError("Must provide a nonempty array of patterns to merge");for(m=0;m1&&B(f,"")>-1&&(h=w(this,{removeG:!0,isInternalOnly:!0}),e.replace.call(String(b).slice(f.index),h,function(){var c,b=arguments.length;for(c=1;b-2>c;++c)arguments[c]===a&&(f[c]=a)})),this[c]&&this[c].captureNames)for(i=1;if.index&&(this.lastIndex=f.index)}return this.global||(this.lastIndex=d),f},f.test=function(a){return!!f.exec.call(this,a)},f.match=function(a){var c;if(b.isRegExp(a)){if(a.global)return c=e.match.apply(this,arguments),a.lastIndex=0,c}else a=new RegExp(a);return f.exec.call(a,L(this))},f.replace=function(d,f){var h,i,j,g=b.isRegExp(d);return g?(d[c]&&(i=d[c].captureNames),h=d.lastIndex):d+="",j=C(f,"Function")?e.replace.call(String(this),d,function(){var c,b=arguments;if(i)for(b[0]=new String(b[0]),c=0;ce)throw new SyntaxError("Backreference to undefined group "+b);return a[e+1]||""}if("$"===d)return"$";if("&"===d||0===+d)return a[0];if("`"===d)return a[a.length-1].slice(0,a[a.length-2]);if("'"===d)return a[a.length-1].slice(a[a.length-2]+a[0].length);if(d=+d,!isNaN(d)){if(d>a.length-3)throw new SyntaxError("Backreference to undefined group "+b);return a[d]||""}throw new SyntaxError("Invalid token "+b)})}),g&&(d.global?d.lastIndex=0:d.lastIndex=h),j},f.split=function(c,d){if(!b.isRegExp(c))return e.split.apply(this,arguments);var j,f=String(this),g=[],h=c.lastIndex,i=0;return d=(d===a?-1:d)>>>0,b.forEach(f,c,function(a){a.index+a[0].length>i&&(g.push(f.slice(i,a.index)),a.length>1&&a.indexd?g.slice(0,d):g},t=b.addToken,t(/\\([ABCE-RTUVXYZaeg-mopqyz]|c(?![A-Za-z])|u(?![\dA-Fa-f]{4}|{[\dA-Fa-f]+})|x(?![\dA-Fa-f]{2}))/,function(a,b){if("B"===a[1]&&b===j)return a[0];throw new SyntaxError("Invalid escape "+a[0])},{scope:"all",leadChar:"\\"}),t(/\\u{([\dA-Fa-f]+)}/,function(a,b,c){var d=x(a[1]);if(d>1114111)throw new SyntaxError("Invalid Unicode code point "+a[0]);if(65535>=d)return"\\u"+E(A(d));if(o&&c.indexOf("u")>-1)return a[0];throw new SyntaxError("Cannot use Unicode code point above \\u{FFFF} without flag u")},{scope:"all",leadChar:"\\"}),t(/\[(\^?)]/,function(a){return a[1]?"[\\s\\S]":"\\b\\B"},{leadChar:"["}),t(/\(\?#[^)]*\)/,function(a,b,c){return D(a.input,a.index+a[0].length,c)?"":"(?:)"},{leadChar:"("}),t(/\s+|#.*/,function(a,b,c){return D(a.input,a.index+a[0].length,c)?"":"(?:)"},{flag:"x"}),t(/\./,function(){return"[\\s\\S]"},{flag:"s",leadChar:"."}),t(/\\k<([\w$]+)>/,function(a){var b=isNaN(a[1])?B(this.captureNames,a[1])+1:+a[1],c=a.index+a[0].length;if(!b||b>this.captureNames.length)throw new SyntaxError("Backreference to undefined group "+a[0]);return"\\"+b+(c===a.input.length||isNaN(a.input.charAt(c))?"":"(?:)")},{leadChar:"\\"}),t(/\\(\d+)/,function(a,b){if(!(b===j&&/^[1-9]/.test(a[1])&&+a[1]<=this.captureNames.length)&&"0"!==a[1])throw new SyntaxError("Cannot use octal escape or backreference to undefined group "+a[0]);return a[0]},{scope:"all",leadChar:"\\"}),t(/\(\?P?<([\w$]+)>/,function(a){if(!isNaN(a[1]))throw new SyntaxError("Cannot use integer as capture name "+a[0]);if("length"===a[1]||"__proto__"===a[1])throw new SyntaxError("Cannot use reserved word as capture name "+a[0]);if(B(this.captureNames,a[1])>-1)throw new SyntaxError("Cannot use same name for multiple groups "+a[0]);return this.captureNames.push(a[1]),this.hasNamedCapture=!0,"("},{leadChar:"("}),t(/\((?!\?)/,function(a,b,c){return c.indexOf("n")>-1?"(?:":(this.captureNames.push(null),"(")},{optionalFlags:"n",leadChar:"("}),b}(); \ No newline at end of file diff --git a/puma_config.rb b/puma_config.rb new file mode 100644 index 00000000..5fb01d68 --- /dev/null +++ b/puma_config.rb @@ -0,0 +1,28 @@ +def processor_count + case RbConfig::CONFIG['host_os'] + when /darwin9/ + `hwprefs cpu_count`.to_i + when /darwin/ + ((`which hwprefs` != '') ? `hwprefs thread_count` : `sysctl -n hw.ncpu`).to_i + when /linux/ + `cat /proc/cpuinfo | grep processor | wc -l`.to_i + when /freebsd/ + `sysctl -n hw.ncpu`.to_i + when /mswin|mingw/ + require 'win32ole' + wmi = WIN32OLE.connect("winmgmts://") + cpu = wmi.ExecQuery("select NumberOfCores from Win32_Processor") # TODO count hyper-threaded in this + cpu.to_enum.first.NumberOfCores + end +end + +environment 'production' +daemonize +pidfile '/var/run/neocities/neocities.pid' +stdout_redirect '/var/log/neocities/neocities.log', '/var/log/neocities/neocities-errors.log', true +quiet +workers processor_count +worker_timeout 600 +preload_app! +on_worker_boot { DB.disconnect } +bind 'unix:/var/run/neocities/neocities.sock?backlog=2048' diff --git a/sass/_project-sass/_project-Main.scss b/sass/_project-sass/_project-Main.scss index 9054be9a..8bc6a24f 100644 --- a/sass/_project-sass/_project-Main.scss +++ b/sass/_project-sass/_project-Main.scss @@ -42,6 +42,10 @@ .interior .header-Outro h1 { font-size: 2.5em; margin-top: 15px; + + a { + color: white; + } } .news-site-info { @media (max-device-width:480px), screen and (max-width:800px) { @@ -127,15 +131,30 @@ font-weight: normal; font-size: 12px; padding: 7px 15px; - - @media (max-device-width:480px), screen and (max-width:800px) { - margin: 6px 0px 8px; - } } .row.content { margin-left: 6%; margin-right: 6%; } + @media (max-device-width:480px), screen and (max-width:800px) { + .signup-Area { + display: none; + } + ul { + display: none; + } + .row.content.wide { + margin: 0; + padding-top: 13px; + padding-bottom: 10px; + } + .btn-Action { + margin: 6px 4px 8px; + } + .site-url { + margin-top: -13px; + } + } } .interior .header-Outro a {color:#E93250} .interior .header-Outro .btn-Action {color:#fff} @@ -168,7 +187,7 @@ @media (max-device-width:480px), screen and (max-width:800px) { width: 100%; - height: 300px; + height: 200px; } } .interior .header-Outro .screenshot.dashboard { @@ -205,8 +224,8 @@ float: left; @media (max-device-width: 480px), screen and (max-width: 800px) { - margin-left: 22px; - margin-top: 18px; + margin-left: 0px; + margin-top: 16px; } } .welcome { @@ -237,6 +256,48 @@ width: 100%; position: relative; margin-top: 7px; + + .column, input[type='checkbox'] { + display: none; + } + + .btn-group { + float: left; + margin-right: 15px; + margin-left: -3px; + + >.btn+.btn { + margin-left: 0px; + border-left: 1px solid rgba(0, 0, 0, 0.1); + } + .btn { + padding: 7px 11px; + margin-top: 1px; + background: #77ABB8; + @include box-shadow(0 0 5px rgba(0, 0, 0, 0.2)); + + &:focus, &.active { + outline: 0; + background: #4F727B; + } + } + } +} +.files { + .btn.iconview-button { + background: #4F727B; + } + .btn.listview-button { + background: #77ABB8; + } +} +.files.list-view { + .btn.listview-button { + background: #4F727B; + } + .btn.iconview-button { + background: #77ABB8; + } } .files .header { background: #5E95A1; @@ -259,12 +320,22 @@ } .files .actions { float: right; + + @media (max-device-width:480px), screen and (max-width:800px) { + float: left; + margin-top: 7px; + + .fa { + display: none; + } + } } .files .btn-Action { margin-left: 8px; @media (max-device-width:480px), screen and (max-width:800px) { - margin: 4px 8px 4px 0; + margin: 4px 3px 4px 0; + padding: 8px 17px; } } .files .list { @@ -360,6 +431,7 @@ white-space: nowrap; overflow: hidden; display: block; + text-overflow: ellipsis; } .html-thumbnail { font-size: 11px; @@ -448,6 +520,112 @@ .html-thumbnail.misc.fileimagehover .overlay { margin: 1px 0 0 2px; } +@mixin dashboard-list-view { + padding: 0; + + .upload-Boundary { + padding: 0; + border: 0; + margin: 0; + } + .file { + padding: 10px 20px; + margin: 0; + width: 100%; + + &:nth-child(even) { + background: #EFE8DC; + } + .title { + margin: 0; + margin-left: 9px; + margin-top: 2px; + float: left; + font-size: 14px; + text-align: left; + width: 30%; + text-overflow: ellipsis; + + @media (max-device-width:480px), screen and (max-width:800px) { + width: 33%; + } + } + input[type='checkbox'] { + display: block; + float: left; + margin-top: 5px; + margin-right: 6px; + } + } + .html-thumbnail, .misc-icon { + margin: 0; + float: left; + width: 23px; + height: 23px; + background-size: 23px; + padding: 0; + font-size: 8px; + + img { + max-width: 23px; + max-height: 23px; + } + } + .misc-icon { + padding-top: 8px; + } + .folder-icon { + background-position: 0 4px; + background-size: 23px; + height: 23px; + } + .file > .overlay { + padding-top: 11px; + margin-left: 20px; + text-align: right; + background-color: transparent; + display: block; + width: 94%; + + a { + color: #e93250; + display: inline; + margin-right: 5px; + } + .link-overlay { + width: 30%; + } + + @media (max-device-width:480px), screen and (max-width:800px) { + width: 84%; + } + } + .html-thumbnail > .overlay { + display: none; + } + .column { + float: left; + width: 13%; + font-size: 13px; + display: block; + padding-top: 4px; + + @media (max-device-width:480px), screen and (max-width:800px) { + display: none; + } + } +} +@media (max-device-width:480px), screen and (max-width:800px) { + .files .list { + @include dashboard-list-view; + } + .files .btn-group { + display: none; + } +} +.files.list-view .list { + @include dashboard-list-view; +} .site-actions { float: left; margin-top: 20px; @@ -574,10 +752,9 @@ } } @media (max-device-width:480px), screen and (max-width:800px) { - width: 10em!important; - float: right; - padding: 0 0 18px 0; - margin-top: -77px; + position: absolute; + top: 46px; + right: -8px; } } .interior .header-Outro.with-columns .col-66 { @@ -638,6 +815,7 @@ @media (max-device-width:480px), screen and (max-width:800px) { width: 60%; + height: 160px; } } .site-portrait { @@ -1664,7 +1842,7 @@ a.tag:hover { padding-top: 0; background: #4F7E89; - padding-bottom: 7em; + padding-bottom: 5em; a { color: white; @@ -1730,8 +1908,20 @@ a.tag:hover { .browse-page h1 { margin-top: 0; } -.browse-page .tags { - padding: 0 30px 40px 30px; +.browse-page .row.content.misc { + form { + padding: 0; + } + input { + margin-top: 0; + margin-bottom: 0; + } + &:last-child { + padding-bottom: 68px; + } + p { + margin-top: 1em; + } } .misc-page .pagination { width: 100%; @@ -1781,6 +1971,12 @@ a.tag:hover { .filename { font-weight: bold; } + @media (max-device-width:480px), screen and (max-width:800px) { + width: 70%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } } .row.content { padding: 15px 20px; @@ -1916,39 +2112,33 @@ table#latest-visitors { width: 100%; } } -.intro-List.kickstarter .col { - padding-top: 1em; - padding-bottom: .8em; - margin-left: 0; - - &:first-child{ - padding-left: 2px; +.section.thankyou { + text-align: center; + color: #4F7E89; + padding: 6.5em 8% 7em; + + a { + color: #4F7E89; + text-decoration: underline; } - - .title { - margin-top: 1%; - } - .title a { - color: white; - font-weight: bold; - text-decoration: none; + img { + margin-bottom: 1em; } p { - margin-top: 15px; + font-size: 1em; + } + p:first-child { + font-size: 120%; + margin-bottom: .2em; } } -.welcome.kickstarter { - background: #daeea5 url(/img/tutorialthumbnail.png) no-repeat; - background-position: right center; - background-size: auto 100%; - padding: 15px 100px 4px 23px; - margin-bottom: 13px; - font-size: 95%; +ul.thankyou { + list-style: none; + margin-top: 1.5em; + clear: both; - h4 { - margin-bottom: .2em; - a { - color: #2c3e50!important; - } + li { + display: inline-block; + width: 32%; } } \ No newline at end of file diff --git a/sass/_project-sass/_project-Tutorial.scss b/sass/_project-sass/_project-Tutorial.scss new file mode 100644 index 00000000..4b68c506 --- /dev/null +++ b/sass/_project-sass/_project-Tutorial.scss @@ -0,0 +1,73 @@ +// ---------------------------------------------------------------- +// Project Specific: Tutorial +// ---------------------------------------------------------------- + +.tutorial { + p { + font-size: 1em; + } + .interact { + textarea.editor { + height: 350px!important; + width: 100%; + background-color: #1D1F21; + color: white; + font: 16px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace; + margin-bottom: 0; + border: 0; + } + h3 { + margin-top: 10px; + } + .preview { + height: 300px; + width: 100%; + background-color: gray; + } + .btn { + float: right; + } + .error { + background: #93771b; + color: #fff; + padding: 5px 10px; + font-size: 14px; + } + } + .lesson { + h1, .subtitle { + color: #5e95a1; + } + .subtitle { + font-size: 14px; + margin-top: 0; + text-align: left; + } + .comic { + position: relative; + background-repeat: no-repeat; + } + .dialogue { + width: 180px; + position: absolute; + text-align: center; + + &:nth-child(1) { + left: 30px; + top: 30px; + } + &:nth-child(2) { + left: 250px; + top: 30px; + } + &:nth-child(3) { + left: 30px; + top: 250px; + } + &:nth-child(4) { + left: 250px; + top: 250px; + } + } + } +} \ No newline at end of file diff --git a/sass/_project-sass/_project-Website-Gallery.scss b/sass/_project-sass/_project-Website-Gallery.scss index 45306414..8653cb88 100644 --- a/sass/_project-sass/_project-Website-Gallery.scss +++ b/sass/_project-sass/_project-Website-Gallery.scss @@ -11,7 +11,7 @@ float:left; margin-bottom:$spacing*2; color: #666; - @include box-shadow(1px 1px 2px 0px rgba(0, 0, 0, 0.18)); + @include box-shadow(0px 1px 3px 0px rgba(0, 0, 0, 0.18)); @media (max-device-width:480px), screen and (max-width:800px){ width:50% diff --git a/sass/neo.scss b/sass/neo.scss index fd821dc3..b0ab7f7e 100644 --- a/sass/neo.scss +++ b/sass/neo.scss @@ -29,6 +29,7 @@ // Specific Modules @import '_project-sass/project-Website-Gallery'; // Browse website specific styling + @import '_project-sass/project-Tutorial'; // Tutorial specific styling // FIXITFIXITFIXITFIXIT // Only import tidyUp if you actually need to make some quick fix hacks that you don't diff --git a/tests/acceptance/browse_tests.rb b/tests/acceptance/browse_tests.rb new file mode 100644 index 00000000..af8c390a --- /dev/null +++ b/tests/acceptance/browse_tests.rb @@ -0,0 +1,46 @@ +require_relative './environment.rb' + +describe '/browse' do + include Capybara::DSL + + describe 'as admin' do + before do + DB[:sites_tags].delete + DB[:sites].delete + Capybara.reset_sessions! + @admin = Fabricate :site, is_admin: true + @site = Fabricate :site, site_changed: true + page.set_rack_session id: @admin.id + end + + it 'bans from browse for admin' do + visit '/browse?sort_by=newest' + within(".website-Gallery li#username_#{@site.username}") do + click_button 'Ban' + end + + @site.reload.is_banned.must_equal true + @admin.reload.is_banned.must_equal false + end + + it 'bans for spam' do + visit '/browse?sort_by=newest' + within(".website-Gallery li#username_#{@site.username}") do + click_button 'Spam' + end + + @site.reload.is_banned.must_equal true + @site.site_files_dataset.where(path: 'index.html').first.classifier.must_equal 'spam' + end + + it 'bans for phishing' do + visit '/browse?sort_by=newest' + within(".website-Gallery li#username_#{@site.username}") do + click_button 'Phishing' + end + + @site.reload.is_banned.must_equal true + @site.site_files_dataset.where(path: 'index.html').first.classifier.must_equal 'phishing' + end + end +end diff --git a/tests/acceptance/settings/site_tests.rb b/tests/acceptance/settings/site_tests.rb index 968037ff..dbb4d999 100644 --- a/tests/acceptance/settings/site_tests.rb +++ b/tests/acceptance/settings/site_tests.rb @@ -320,6 +320,12 @@ describe 'delete' do someone_elses_site.is_deleted.must_equal false end + it 'should not show NSFW tab for admin NSFW flag' do + owned_site = Fabricate :site, parent_site_id: @site.id, admin_nsfw: true + visit "/settings/#{owned_site.username}" + page.body.wont_match /18\+/ + end + it 'should succeed if you own the site' do owned_site = Fabricate :site, parent_site_id: @site.id visit "/settings/#{owned_site.username}#delete" @@ -341,4 +347,4 @@ describe 'delete' do visit "/settings/#{@site.username}#delete" page.body.must_match /You cannot delete the parent site without deleting the children sites first/i end -end \ No newline at end of file +end diff --git a/tests/acceptance/signup_tests.rb b/tests/acceptance/signup_tests.rb index d5018b26..08cb5176 100644 --- a/tests/acceptance/signup_tests.rb +++ b/tests/acceptance/signup_tests.rb @@ -9,9 +9,19 @@ describe 'signup' do def fill_in_valid @site = Fabricate.attributes_for(:site) - fill_in 'username', with: @site[:username] - fill_in 'password', with: @site[:password] - fill_in 'email', with: @site[:email] + + time = Time.now + begin + fill_in 'username', with: @site[:username] + fill_in 'password', with: @site[:password] + fill_in 'email', with: @site[:email] + rescue Capybara::ElementNotFound + puts "Waiting on fill_in #{Time.now - time} seconds" + raise if Time.now - time > 30 + visit_signup + sleep 0.5 + retry + end end def click_signup_button @@ -35,12 +45,14 @@ describe 'signup' do after do Capybara.default_driver = :rack_test + BlockedIp.where(ip: '127.0.0.1').delete + DB[:sites].where(is_banned: true).delete end it 'succeeds with valid data' do fill_in_valid click_signup_button - site_created?.must_equal true + site_created? index_file_path = File.join Site::SITE_FILES_ROOT, @site[:username], 'index.html' File.exist?(index_file_path).must_equal true @@ -54,6 +66,27 @@ describe 'signup' do site.ip.must_equal Site.hash_ip('127.0.0.1') end + it 'fails if site with same ip has been banned' do + @banned_site = Fabricate :site + @banned_site.is_banned = true + @banned_site.save_changes + + fill_in_valid + click_signup_button + Site[username: @site[:username]].must_be_nil + current_path.must_equal '/' + page.wont_have_content 'Welcome to Neocities' + end + + it 'fails if IP is banned from blocked ips list' do + DB[:blocked_ips].insert(ip: '127.0.0.1', created_at: Time.now) + fill_in_valid + click_signup_button + Site[username: @site[:username]].must_be_nil + current_path.must_equal '/' + page.wont_have_content 'Welcome to Neocities' + end + it 'fails to create for existing site' do @existing_site = Fabricate :site fill_in_valid diff --git a/tests/environment.rb b/tests/environment.rb index 3247bc9f..d8d148bb 100644 --- a/tests/environment.rb +++ b/tests/environment.rb @@ -1,10 +1,17 @@ ENV['RACK_ENV'] = 'test' raise 'Forget it.' if ENV['RACK_ENV'] == 'production' +require 'coveralls' require 'simplecov' + +SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ + SimpleCov::Formatter::HTMLFormatter, + Coveralls::SimpleCov::Formatter +] SimpleCov.coverage_dir File.join('tests', 'coverage') SimpleCov.start do add_filter "/migrations/" + add_filter "/tests/" end SimpleCov.command_name 'minitest' diff --git a/tests/files/blankindex/index.html b/tests/files/blankindex/index.html new file mode 100644 index 00000000..e69de29b diff --git a/tests/files/classifier/ham.html b/tests/files/classifier/ham.html new file mode 100644 index 00000000..fb2e3f75 --- /dev/null +++ b/tests/files/classifier/ham.html @@ -0,0 +1 @@ +I am a piece of ham. diff --git a/tests/files/classifier/phishing.html b/tests/files/classifier/phishing.html new file mode 100644 index 00000000..b7a57acd --- /dev/null +++ b/tests/files/classifier/phishing.html @@ -0,0 +1 @@ +Facebook login enter your password derrp diff --git a/tests/files/classifier/spam.html b/tests/files/classifier/spam.html new file mode 100644 index 00000000..bea343a8 --- /dev/null +++ b/tests/files/classifier/spam.html @@ -0,0 +1 @@ +Ham sucks. How would you like to buy some spam? diff --git a/tests/site_file_tests.rb b/tests/site_file_tests.rb index f2aee5ee..fbf6ccff 100644 --- a/tests/site_file_tests.rb +++ b/tests/site_file_tests.rb @@ -24,16 +24,43 @@ describe 'site_files' do end describe 'delete' do + before do + DeleteCacheWorker.jobs.clear + DeleteCacheOrderWorker.jobs.clear + end + it 'works' do + initial_space_used = @site.space_used uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') upload 'files[]' => uploaded_file - @site.reload.space_used.must_equal uploaded_file.size + + PurgeCacheOrderWorker.jobs.clear + + @site.reload.space_used.must_equal initial_space_used + uploaded_file.size + @site.actual_space_used.must_equal @site.space_used file_path = @site.files_path 'test.jpg' File.exists?(file_path).must_equal true delete_file filename: 'test.jpg' + File.exists?(file_path).must_equal false SiteFile[site_id: @site.id, path: 'test.jpg'].must_be_nil - @site.reload.space_used.must_equal 0 + @site.reload.space_used.must_equal initial_space_used + @site.actual_space_used.must_equal @site.space_used + + PurgeCacheOrderWorker.jobs.length.must_equal 0 + DeleteCacheOrderWorker.jobs.length.must_equal 1 + args = DeleteCacheOrderWorker.jobs.first['args'] + args[0].must_equal @site.username + args[1].must_equal '/test.jpg' + end + + it 'flushes surf for index.html' do + uploaded_file = Rack::Test::UploadedFile.new('./tests/files/index.html', 'text/html') + upload 'files[]' => uploaded_file + delete_file filename: '/index.html' + + DeleteCacheOrderWorker.jobs.length.must_equal 3 + DeleteCacheOrderWorker.jobs.collect {|j| j['args'].last}.must_equal ['/index.html', '/?surf=1', '/'] end it 'deletes a directory and all files in it' do @@ -45,9 +72,36 @@ describe 'site_files' do 'dir' => '', 'files[]' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') ) + + space_used = @site.reload.space_used delete_file filename: 'test' + + @site.reload.space_used.must_equal(space_used - File.size('./tests/files/test.jpg')) + + @site.site_files.select {|f| f.path == 'test'}.length.must_equal 0 @site.site_files.select {|f| f.path =~ /^test\//}.length.must_equal 0 - @site.site_files.select {|f| f.path =~ /^test/}.length.must_equal 1 + @site.site_files.select {|f| f.path =~ /^test.jpg/}.length.must_equal 1 + end + + it 'deletes records for nested directories' do + upload( + 'dir' => 'derp/ing/tons', + 'files[]' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') + ) + + expected_site_file_paths = ['derp', 'derp/ing', 'derp/ing/tons', 'derp/ing/tons/test.jpg'] + + expected_site_file_paths.each do |path| + @site.site_files.select {|f| f.path == path}.length.must_equal 1 + end + + delete_file filename: 'derp' + + @site.reload + + expected_site_file_paths.each do |path| + @site.site_files.select {|f| f.path == path}.length.must_equal 0 + end end it 'goes back to deleting directory' do @@ -107,25 +161,35 @@ describe 'site_files' do @site.title.must_equal 'Hello?' # Purge cache needs to flush / and index.html for either scenario. - PurgeCacheOrderWorker.jobs.length.must_equal 2 + PurgeCacheOrderWorker.jobs.length.must_equal 3 first_purge = PurgeCacheOrderWorker.jobs.first + surf_purge = PurgeCacheOrderWorker.jobs[1] dirname_purge = PurgeCacheOrderWorker.jobs.last username, pathname = first_purge['args'] username.must_equal @site.username pathname.must_equal '/index.html' + + surf_purge['args'].last.must_equal '/?surf=1' + username, pathame = nil username, pathname = dirname_purge['args'] username.must_equal @site.username pathname.must_equal '/' + + @site.space_used.must_equal @site.actual_space_used + + (@site.space_used > 0).must_equal true end it 'provides the correct space used after overwriting an existing file' do + initial_space_used = @site.space_used uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') upload 'files[]' => uploaded_file second_uploaded_file = Rack::Test::UploadedFile.new('./tests/files/img/test.jpg', 'image/jpeg') upload 'files[]' => second_uploaded_file - @site.reload.space_used.must_equal second_uploaded_file.size + @site.reload.space_used.must_equal initial_space_used + second_uploaded_file.size + @site.space_used.must_equal @site.actual_space_used end it 'does not change title for subdir index.html' do @@ -138,6 +202,7 @@ describe 'site_files' do end it 'succeeds with valid file' do + initial_space_used = @site.space_used uploaded_file = Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') upload 'files[]' => uploaded_file last_response.body.must_match /successfully uploaded/i @@ -149,7 +214,8 @@ describe 'site_files' do @site.reload @site.space_used.wont_equal 0 - @site.space_used.must_equal uploaded_file.size + @site.space_used.must_equal initial_space_used + uploaded_file.size + @site.space_used.must_equal @site.actual_space_used ThumbnailWorker.jobs.length.must_equal 1 ThumbnailWorker.drain @@ -158,7 +224,15 @@ describe 'site_files' do File.exists?(@site.thumbnail_path('test.jpg', resolution)).must_equal true end - @site.site_changed.must_equal true + @site.site_changed.must_equal false + end + + it 'sets site changed to false if index is empty' do + uploaded_file = Rack::Test::UploadedFile.new('./tests/files/blankindex/index.html', 'text/html') + upload 'files[]' => uploaded_file + last_response.body.must_match /successfully uploaded/i + @site.empty_index?.must_equal true + @site.site_changed.must_equal false end it 'fails with unsupported file' do @@ -213,6 +287,10 @@ describe 'site_files' do ThumbnailWorker.jobs.length.must_equal 1 ThumbnailWorker.drain + @site.site_files_dataset.where(path: 'derpie').count.must_equal 1 + @site.site_files_dataset.where(path: 'derpie/derptest').count.must_equal 1 + @site.site_files_dataset.where(path: 'derpie/derptest/test.jpg').count.must_equal 1 + Site::THUMBNAIL_RESOLUTIONS.each do |resolution| File.exists?(@site.thumbnail_path('derpie/derptest/test.jpg', resolution)).must_equal true @site.thumbnail_url('derpie/derptest/test.jpg', resolution).must_equal( @@ -221,6 +299,20 @@ describe 'site_files' do end end + it 'does not register site changing until root index.html is changed' do + upload( + 'dir' => 'derpie/derptest', + 'files[]' => Rack::Test::UploadedFile.new('./tests/files/test.jpg', 'image/jpeg') + ) + @site.reload.site_changed.must_equal false + + upload 'files[]' => Rack::Test::UploadedFile.new('./tests/files/index.html', 'text/html') + @site.reload.site_changed.must_equal true + + upload 'files[]' => Rack::Test::UploadedFile.new('./tests/files/chunkfive.otf', 'application/vnd.ms-opentype') + @site.reload.site_changed.must_equal true + end + it 'does not store new file if hash matches' do upload( 'dir' => 'derpie/derptest', @@ -237,5 +329,27 @@ describe 'site_files' do upload 'files[]' => Rack::Test::UploadedFile.new('./tests/files/index.html', 'text/html') @site.reload.changed_count.must_equal 2 end + + describe 'classification' do + before do + puts "TODO FINISH CLASSIFIER" + #$trainer.instance_variable_get('@db').redis.flushall + end +=begin + it 'trains files' do + upload 'files[]' => Rack::Test::UploadedFile.new('./tests/files/classifier/ham.html', 'text/html') + upload 'files[]' => Rack::Test::UploadedFile.new('./tests/files/classifier/spam.html', 'text/html') + upload 'files[]' => Rack::Test::UploadedFile.new('./tests/files/classifier/phishing.html', 'text/html') + + @site.train 'ham.html' + @site.train 'spam.html', 'spam' + @site.train 'phishing.html', 'phishing' + + @site.classify('ham.html').must_equal 'ham' + @site.classify('spam.html').must_equal 'spam' + @site.classify('phishing.html').must_equal 'phishing' + end +=end + end end end diff --git a/tests/site_tests.rb b/tests/site_tests.rb index e72a685e..5cf387cb 100644 --- a/tests/site_tests.rb +++ b/tests/site_tests.rb @@ -5,6 +5,38 @@ def app end describe Site do + describe 'banning' do + it 'still makes files available' do + site = Fabricate :site + site.ban! + File.exist?(site.current_files_path('index.html')).must_equal true + site.current_files_path('index.html').must_equal File.join(Site::BANNED_SITES_ROOT, site.username, 'index.html') + end + end + + describe 'directory create' do + it 'handles wacky pathnames' do + ['/derp', '/derp/'].each do |path| + site = Fabricate :site + site_file_count = site.site_files_dataset.count + site.create_directory path + site.site_files.select {|s| s.path == '' || s.path == '.'}.length.must_equal 0 + site.site_files.select {|s| s.path == path.gsub('/', '')}.first.wont_be_nil + site.site_files_dataset.count.must_equal site_file_count+1 + end + end + end + + describe 'custom_max_space' do + it 'should use the custom max space if it is more' do + site = Fabricate :site + site.maximum_space.must_equal Site::PLAN_FEATURES[:free][:space] + site.custom_max_space = 10**9 + site.save_changes + site.maximum_space.must_equal 10**9 + end + end + describe 'can_email' do it 'should fail if send_emails is false' do site = Fabricate :site @@ -76,7 +108,7 @@ describe Site do Fabricate :site, new_tags_string: 'gardening', views: Site::SUGGESTIONS_VIEWS_MIN } - site.suggestions.length.must_equal Site::SUGGESTIONS_LIMIT + site.suggestions.length.must_equal(Site::SUGGESTIONS_LIMIT - 5) end end end diff --git a/tests/stat_logs/.gitignore b/tests/stat_logs/.gitignore new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/tests/stat_logs/.gitignore @@ -0,0 +1 @@ +* diff --git a/tests/stat_tests.rb b/tests/stat_tests.rb index 4216d39e..3c22fdeb 100644 --- a/tests/stat_tests.rb +++ b/tests/stat_tests.rb @@ -35,11 +35,34 @@ describe 'stats' do end Stat.parse_logfiles STAT_LOGS_PATH + @site.stats.first.bandwidth.must_equal 612917*2 #@site.stat_referrers.first.url.must_equal 'http://derp.com' #@site.stat_locations.first.city_name.must_equal 'Menlo Park' end + it 'takes accout for log hit time' do + @site = Fabricate :site + File.open("tests/stat_logs/#{SecureRandom.uuid}.log", 'w') do |file| + file.write "2015-05-01T21:16:35+00:00\t#{@site.username}\t612917\t/images/derpie space.png\t67.180.75.140\thttp://derp.com\n" + file.write "2015-05-02T21:16:35+00:00\t#{@site.username}\t612917\t/images/derpie space.png\t67.180.75.140\thttp://derp.com\n" + end + + Stat.parse_logfiles STAT_LOGS_PATH + + @site.stats.length.must_equal 2 + + [Date.new(2015, 5, 2), Date.new(2015, 5, 1)].each do |date| + stats = @site.stats.select {|stat| stat.created_at == date} + stats.length.must_equal 1 + stat = stats.first + stat.hits.must_equal 1 + stat.views.must_equal 1 + stat.bandwidth.must_equal 612917 + end + + end + it 'deals with spaces in referrer' do @site = Fabricate :site File.open("tests/stat_logs/#{SecureRandom.uuid}.log", 'w') do |file| @@ -103,6 +126,7 @@ describe 'stats' do end it 'parses logfile' do + DB[:daily_site_stats].delete Stat.parse_logfiles STAT_LOGS_PATH @site_one.reload @@ -149,5 +173,14 @@ describe 'stats' do #stat_paths.last.name.must_equal '/derp.html' # [geoip.city('67.180.75.140'), geoip.city('172.56.16.152')] + + # Saves to daily_site_stats + + DailySiteStat.count.must_equal 1 + d = DailySiteStat.first + d.created_at.must_equal Date.new(@time.year, @time.month, @time.day) + d.hits.must_equal 7 + d.views.must_equal 5 + d.bandwidth.must_equal 35000 end end diff --git a/tests/workers/delete_cache_order_worker_tests.rb b/tests/workers/delete_cache_order_worker_tests.rb new file mode 100644 index 00000000..9810fcd8 --- /dev/null +++ b/tests/workers/delete_cache_order_worker_tests.rb @@ -0,0 +1,21 @@ +require_relative '../environment.rb' + +describe DeleteCacheWorker do + before do + PurgeCacheOrderWorker.jobs.clear + PurgeCacheWorker.jobs.clear + end + + it 'queues up purges' do + DeleteCacheOrderWorker.new.perform('kyledrake', '/test.jpg') + + job_one_args = DeleteCacheWorker.jobs.first['args'] + job_two_args = DeleteCacheWorker.jobs.last['args'] + job_one_args[0].must_equal '10.0.0.1' + job_one_args[1].must_equal 'kyledrake' + job_one_args[2].must_equal '/test.jpg' + job_two_args[0].must_equal '10.0.0.2' + job_two_args[1].must_equal 'kyledrake' + job_two_args[2].must_equal '/test.jpg' + end +end diff --git a/tests/workers/delete_cache_worker_tests.rb b/tests/workers/delete_cache_worker_tests.rb new file mode 100644 index 00000000..70f6f690 --- /dev/null +++ b/tests/workers/delete_cache_worker_tests.rb @@ -0,0 +1,64 @@ +require_relative '../environment.rb' + +describe DeleteCacheWorker do + before do + @test_ip = '10.0.0.1' + end + + it 'throws exception without 200 or 404 http status' do + stub_request(:get, "http://#{@test_ip}/:cache/purge/test.jpg"). + with(headers: {'Host' => 'kyledrake.neocities.org'}) + .to_return(status: 503) + + worker = DeleteCacheWorker.new + + proc { + worker.perform @test_ip, 'kyledrake', '/test.jpg' + }.must_raise RestClient::ServiceUnavailable + end + + it 'handles 404 without exception' do + stub_request(:get, "http://#{@test_ip}/:cache/purge/test.jpg"). + with(headers: {'Host' => 'kyledrake.neocities.org'}) + .to_return(status: 404) + + worker = DeleteCacheWorker.new + worker.perform @test_ip, 'kyledrake', '/test.jpg' + end + + it 'sends a purge request' do + stub_request(:get, "http://#{@test_ip}/:cache/purge/test.jpg"). + with(headers: {'Host' => 'kyledrake.neocities.org'}) + .to_return(status: 200) + + worker = DeleteCacheWorker.new + worker.perform @test_ip, 'kyledrake', '/test.jpg' + + assert_requested :get, "http://#{@test_ip}/:cache/purge/test.jpg" + end + + it 'handles spaces correctly' do + stub_request(:get, "http://#{@test_ip}/:cache/purge/te st.jpg"). + with(headers: {'Host' => 'kyledrake.neocities.org'}) + .to_return(status: 200) + + url = Addressable::URI.encode_component( + "http://#{@test_ip}/:cache/purge/te st.jpg", + Addressable::URI::CharacterClasses::QUERY + ) + + worker = DeleteCacheWorker.new + worker.perform @test_ip, 'kyledrake', '/te st.jpg' + + assert_requested :get, url + end + + it 'works without forward slash' do + stub_request(:get, "http://#{@test_ip}/:cache/purge/test.jpg"). + with(headers: {'Host' => 'kyledrake.neocities.org'}) + .to_return(status: 200) + + worker = DeleteCacheWorker.new + worker.perform @test_ip, 'kyledrake', 'test.jpg' + end +end diff --git a/tests/workers/purge_cache_worker_tests.rb b/tests/workers/purge_cache_worker_tests.rb index 90be0da8..b07bc3c7 100644 --- a/tests/workers/purge_cache_worker_tests.rb +++ b/tests/workers/purge_cache_worker_tests.rb @@ -6,8 +6,8 @@ describe PurgeCacheWorker do end it 'throws exception without 200 or 404 http status' do - stub_request(:get, "http://#{@test_ip}/:cache/purge/test.jpg"). - with(headers: {'Host' => 'kyledrake.neocities.org'}) + stub_request(:head, "http://#{@test_ip}/test.jpg"). + with(headers: {'Host' => 'kyledrake.neocities.org', 'Cache-Purge' => '1'}) .to_return(status: 503) worker = PurgeCacheWorker.new @@ -18,8 +18,8 @@ describe PurgeCacheWorker do end it 'handles 404 without exception' do - stub_request(:get, "http://#{@test_ip}/:cache/purge/test.jpg"). - with(headers: {'Host' => 'kyledrake.neocities.org'}) + stub_request(:head, "http://#{@test_ip}/test.jpg"). + with(headers: {'Host' => 'kyledrake.neocities.org', 'Cache-Purge' => '1'}) .to_return(status: 404) worker = PurgeCacheWorker.new @@ -27,35 +27,35 @@ describe PurgeCacheWorker do end it 'sends a purge request' do - stub_request(:get, "http://#{@test_ip}/:cache/purge/test.jpg"). - with(headers: {'Host' => 'kyledrake.neocities.org'}) + stub_request(:head, "http://#{@test_ip}/test.jpg"). + with(headers: {'Host' => 'kyledrake.neocities.org', 'Cache-Purge' => '1'}) .to_return(status: 200) worker = PurgeCacheWorker.new worker.perform @test_ip, 'kyledrake', '/test.jpg' - assert_requested :get, "http://#{@test_ip}/:cache/purge/test.jpg" + assert_requested :head, "http://#{@test_ip}/test.jpg" end it 'handles spaces correctly' do - stub_request(:get, "http://#{@test_ip}/:cache/purge/te st.jpg"). - with(headers: {'Host' => 'kyledrake.neocities.org'}) + stub_request(:head, "http://#{@test_ip}/te st.jpg"). + with(headers: {'Host' => 'kyledrake.neocities.org', 'Cache-Purge' => '1'}) .to_return(status: 200) url = Addressable::URI.encode_component( - "http://#{@test_ip}/:cache/purge/te st.jpg", + "http://#{@test_ip}/te st.jpg", Addressable::URI::CharacterClasses::QUERY ) worker = PurgeCacheWorker.new worker.perform @test_ip, 'kyledrake', '/te st.jpg' - assert_requested :get, url + assert_requested :head, url end it 'works without forward slash' do - stub_request(:get, "http://#{@test_ip}/:cache/purge/test.jpg"). - with(headers: {'Host' => 'kyledrake.neocities.org'}) + stub_request(:head, "http://#{@test_ip}/test.jpg"). + with(headers: {'Host' => 'kyledrake.neocities.org', 'Cache-Purge' => '1'}) .to_return(status: 200) worker = PurgeCacheWorker.new diff --git a/views/_footer.erb b/views/_footer.erb index cd67fe04..e1ab4b83 100644 --- a/views/_footer.erb +++ b/views/_footer.erb @@ -11,7 +11,7 @@
  • About
  • Donate
  • <% unless is_education? %> -
  • Blog
  • +
  • Blog
  • API
  • Press
  • <% end %> diff --git a/views/_header_links.erb b/views/_header_links.erb index 265f3616..ec317af4 100644 --- a/views/_header_links.erb +++ b/views/_header_links.erb @@ -7,9 +7,6 @@ Websites <% unless is_education? %> -
  • - Search -
  • Activity
  • @@ -17,8 +14,6 @@
  • Learn
  • - <% unless is_education? %>
  • - Support Our Kickstarter -
  • - <% end %> + Support Us + \ No newline at end of file diff --git a/views/_news.erb b/views/_news.erb index 2641c68d..7ca1b3c5 100644 --- a/views/_news.erb +++ b/views/_news.erb @@ -126,26 +126,7 @@ <% if params[:activity] != 'global' %>
    - <% if @page_count > 1 %> - - <% end %> + <%== erb :_pagination, layout: false %>
    <% end %> diff --git a/views/_news_profile_comment.erb b/views/_news_profile_comment.erb index f2ccde95..9d9716a9 100644 --- a/views/_news_profile_comment.erb +++ b/views/_news_profile_comment.erb @@ -10,13 +10,11 @@ <% if actioning_site.supporter? %><% end %><%= actioning_site.username %> <% end %> - + <% if actioning_site.id != profile_comment.site_id %> + + <% if profile_comment.site.supporter? %><% end %><%= profile_comment.site.username %> + <% end %> - <% if current_site && current_site.id == profile_comment.site_id %> - You - <% else %> - <% if profile_comment.site.supporter? %><% end %><%= profile_comment.site.username %> - <% end %> <%= profile_comment.created_at.ago %> diff --git a/views/_pagination.erb b/views/_pagination.erb new file mode 100644 index 00000000..b568d5f9 --- /dev/null +++ b/views/_pagination.erb @@ -0,0 +1,5 @@ +<% if @pagination_dataset.total_pages > 1 %> + +<% end %> diff --git a/views/admin.erb b/views/admin.erb index f2ac59b1..394e617a 100644 --- a/views/admin.erb +++ b/views/admin.erb @@ -9,7 +9,8 @@ @@ -28,6 +29,13 @@ <%== csrf_token_input_html %>

    Site Name:

    +
    + +

    diff --git a/views/admin/reports.erb b/views/admin/reports.erb index 3b6c0801..2de772a6 100644 --- a/views/admin/reports.erb +++ b/views/admin/reports.erb @@ -5,7 +5,8 @@
    -
    + + <%== csrf_token_input_html %> diff --git a/views/admin/site.erb b/views/admin/site.erb new file mode 100644 index 00000000..957d376a --- /dev/null +++ b/views/admin/site.erb @@ -0,0 +1,80 @@ +
    +
    +

    Site Inspector

    +

    <%= @site.username %>

    +
    +
    + +
    + +
    + + <%== csrf_token_input_html %> + +

    + + +
    + <%== csrf_token_input_html %> + +

    + +
    + +
    +
    +
    + + +
    + +
    + +

    Site Pages

    + +
    Site
    + <% @site.site_files_dataset.where(path: /\.html/).all.each do |site_file| %> + + + + + <% end %> +
    +

    <%= site_file.path %>

    + <% if !site_file.classifier.blank? %> +

    + <% if site_file.classifier == 'ham' %> + <%= site_file.classifier %> + <% else %> + <%= site_file.classifier %> + <% end %> +

    + <% else %> +

    Not Classified

    + <% end %> + +
    + <%== csrf_token_input_html %> + + + + +
    + +
    + <%== csrf_token_input_html %> + + + + +
    + +
    + <%== csrf_token_input_html %> + + + + +
    +
    +
    diff --git a/views/admin/usage.erb b/views/admin/usage.erb new file mode 100644 index 00000000..5a1b23f1 --- /dev/null +++ b/views/admin/usage.erb @@ -0,0 +1,54 @@ +
    +
    +

    Bandwidth Stats

    +

    John James Cowperthwaite cares that I care about this

    +
    +
    + +
    +
    +
    + + + + + + + + + <% @monthly_stats.each do |monthly_stat| %> + + + + + + + <% end %> +
    ViewsHitsBandwidthDate
    <%= monthly_stat[:views].to_comma_separated %><%= monthly_stat[:hits].to_comma_separated %><%= monthly_stat[:bandwidth].to_bytes_pretty %><%= monthly_stat[:date].strftime('%Y %B') %>
    +
    +
    + +
    +
    +

    Popular Sites

    + <% @monthly_stats.each do |monthly_stat| %> +

    <%= monthly_stat[:date].strftime('%Y %B') %>

    + + + + + + + <% monthly_stat[:popular_sites].each do |s| %> + + + + + + <% end %> +
    UsernameProfileBandwidth
    <%= s[:username] %>link<%= s[:bandwidth].to_bytes_pretty %>
    + <% end %> +
    +
    + +
    diff --git a/views/browse.erb b/views/browse.erb index 6fe5da75..b7f9c542 100644 --- a/views/browse.erb +++ b/views/browse.erb @@ -1,10 +1,10 @@ @@ -12,7 +12,7 @@
    <% if params[:tag] %> -

    Sites tagged <%= params[:tag] %>

    +

    Websites > <%= params[:tag] %>

    <% else %>

    Sites on Neocities

    <% end %> @@ -26,6 +26,7 @@
    - + + <% else %> + <% if params[:tag] %> + + <% end %> <% end %>
    @@ -70,8 +75,8 @@ <% else %>
    <% end %> -
    +
    +
    +
    + + +