├── .ruby-version ├── test ├── empty_config.yml ├── database │ ├── funky_ids │ │ ├── funky_ids.fa.nsi │ │ ├── funky_ids.fa.nhr │ │ ├── funky_ids.fa.nin │ │ ├── funky_ids.fa.nog │ │ ├── funky_ids.fa.nsq │ │ ├── funky_ids.fa.nsd │ │ └── funky_ids.fa │ ├── without_parse_seqids │ │ ├── without_parse_seqids.fa.phr │ │ ├── without_parse_seqids.fa.pin │ │ ├── without_parse_seqids.fa.psq │ │ └── without_parse_seqids.fa │ └── sample │ │ ├── proteins │ │ └── Solenopsis_invicta │ │ │ ├── Sinvicta2-2-3.prot.subset.fasta.phr │ │ │ ├── Sinvicta2-2-3.prot.subset.fasta.pin │ │ │ ├── Sinvicta2-2-3.prot.subset.fasta.pog │ │ │ └── Sinvicta2-2-3.prot.subset.fasta.psi │ │ └── transcripts │ │ └── Solenopsis_invicta │ │ ├── Sinvicta2-2-3.cdna.subset.fasta.nhr │ │ ├── Sinvicta2-2-3.cdna.subset.fasta.nin │ │ ├── Sinvicta2-2-3.cdna.subset.fasta.nog │ │ ├── Sinvicta2-2-3.cdna.subset.fasta.nsi │ │ ├── Sinvicta2-2-3.cdna.subset.fasta.nsq │ │ └── Sinvicta2-2-3.cdna.subset.fasta.nsd └── test_route_spec.rb ├── public ├── web_files │ ├── json │ │ └── .gitkeep │ ├── img │ │ └── gene.png │ └── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ └── fontawesome-webfont.woff ├── src │ ├── js │ │ ├── jquery.cookie.min.js │ │ ├── bionode-seq.min.js │ │ ├── genevalidator.js │ │ ├── jquery.validate.min.js │ │ ├── bootstrap.min.js │ │ └── jquery.tablesorter.min.js │ └── css │ │ ├── custom.css │ │ └── font-awesome.min.css └── GeneValidator │ └── loading.html ├── config.ru ├── lib ├── genevalidatorapp │ ├── version.rb │ ├── logger.rb │ ├── server.rb │ ├── config.rb │ ├── database.rb │ ├── routes.rb │ ├── exceptions.rb │ └── genevalidator.rb └── genevalidatorapp.rb ├── Gemfile ├── views ├── 500.slim ├── results.slim ├── layout.slim └── index.slim ├── .gitignore ├── .travis.yml ├── README.md ├── genevalidatorapp.gemspec └── Rakefile /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.2 -------------------------------------------------------------------------------- /test/empty_config.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/web_files/json/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | require 'genevalidatorapp' 2 | GeneValidatorApp.init 3 | run GeneValidatorApp 4 | -------------------------------------------------------------------------------- /lib/genevalidatorapp/version.rb: -------------------------------------------------------------------------------- 1 | module GeneValidatorApp 2 | VERSION = '2.1.8'.freeze 3 | end 4 | -------------------------------------------------------------------------------- /test/database/funky_ids/funky_ids.fa.nsi: -------------------------------------------------------------------------------- 1 | m @m4>123#4562 -------------------------------------------------------------------------------- /public/web_files/img/gene.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/public/web_files/img/gene.png -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | 5 | gem 'passenger', '~>5.3.4' 6 | gem 'genevalidator', '2.1.5' 7 | -------------------------------------------------------------------------------- /public/web_files/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/public/web_files/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /test/database/funky_ids/funky_ids.fa.nhr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/funky_ids/funky_ids.fa.nhr -------------------------------------------------------------------------------- /test/database/funky_ids/funky_ids.fa.nin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/funky_ids/funky_ids.fa.nin -------------------------------------------------------------------------------- /test/database/funky_ids/funky_ids.fa.nog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/funky_ids/funky_ids.fa.nog -------------------------------------------------------------------------------- /test/database/funky_ids/funky_ids.fa.nsq: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/funky_ids/funky_ids.fa.nsq -------------------------------------------------------------------------------- /public/web_files/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/public/web_files/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /public/web_files/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/public/web_files/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /public/web_files/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/public/web_files/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /test/database/without_parse_seqids/without_parse_seqids.fa.phr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/without_parse_seqids/without_parse_seqids.fa.phr -------------------------------------------------------------------------------- /test/database/without_parse_seqids/without_parse_seqids.fa.pin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/without_parse_seqids/without_parse_seqids.fa.pin -------------------------------------------------------------------------------- /test/database/funky_ids/funky_ids.fa.nsd: -------------------------------------------------------------------------------- 1 | 123#4562 2 | 123456#3 3 | abc#def1 4 | abcdef#0 5 | lcl|123#4562 6 | lcl|1234564 7 | lcl|123456#3 8 | lcl|abc#def1 9 | lcl|abcdef#0 10 | -------------------------------------------------------------------------------- /test/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.phr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.phr -------------------------------------------------------------------------------- /test/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pin -------------------------------------------------------------------------------- /test/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pog -------------------------------------------------------------------------------- /test/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.psi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.psi -------------------------------------------------------------------------------- /test/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nhr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nhr -------------------------------------------------------------------------------- /test/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nin -------------------------------------------------------------------------------- /test/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nog -------------------------------------------------------------------------------- /test/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nsi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nsi -------------------------------------------------------------------------------- /test/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nsq: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wurmlab/genevalidatorapp/HEAD/test/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nsq -------------------------------------------------------------------------------- /views/500.slim: -------------------------------------------------------------------------------- 1 | .alert.alert-danger role="alert" 2 | h3.error_header Oops! Something went Wonky! 3 | p Apologies, there was an error with your request. Please try again. 4 | p Error Message: #{request.env['sinatra.error'].message} 5 | p If the error persists, please contact the administrator. -------------------------------------------------------------------------------- /test/database/funky_ids/funky_ids.fa: -------------------------------------------------------------------------------- 1 | >abcdef# 2 | GATGAACGCTGGCGGCGTGCCTAATACATGCAAGTCGAG 3 | >abc#def 4 | GATGAACGCTGGCGGCGTGCCTAATACATGCAAGTCGAG 5 | >123#456 6 | GATGAACGCTGGCGGCGTGCCTAATACATGCAAGTCGAG 7 | >123456# 8 | GATGAACGCTGGCGGCGTGCCTAATACATGCAAGTCGAG 9 | >123456 10 | GATGAACGCTGGCGGCGTGCCTAATACATGCAAGTCGAG 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | .DS_Store 7 | Gemfile.lock 8 | InstalledFiles 9 | _yardoc 10 | coverage 11 | doc/ 12 | lib/bundler/man 13 | pkg 14 | rdoc 15 | spec/reports 16 | test/tmp 17 | test/version_tmp 18 | tmp 19 | *.bundle 20 | *.so 21 | *.o 22 | *.a 23 | mkmf.log 24 | .DS_Store 25 | passenger* -------------------------------------------------------------------------------- /test/database/without_parse_seqids/without_parse_seqids.fa.psq: -------------------------------------------------------------------------------- 1 |     2 |    3 |           4 |   5 | 6 |    7 |        8 | 9 |    10 |  11 |          12 |  13 | 14 |  15 |            16 |  17 |  18 | 19 |       20 | 21 |  22 |     23 |               -------------------------------------------------------------------------------- /test/database/without_parse_seqids/without_parse_seqids.fa: -------------------------------------------------------------------------------- 1 | >SI2.2.0_06267 locus=Si_gnF.scaffold02592[1282609..1284114].pep_2 quality=100.00 2 | MNTLWLSLWDYPGKLPLNFMVFDTKDDLQAAYWRDPYSIPLAVIFEDPQPISQRLIYEIR 3 | TNPSYTLPPPPTKLYSAPISCRKNKTGHWMDDILSIKTGESCPVNNYLHSGFLALQMITD 4 | ITKIKLENSDVTIPDIKLIMFPKEPYTADWMLAFRVVIPLYMVLALSQFITYLLILIVGE 5 | KENKIKEGMKMMGLNDSVF 6 | >SI2.2.0_13722 locus=Si_gnF.scaffold06207[1925625..1928536].pep_1 quality=100.00 7 | MSANRLNVLVTLMLAVALLVTESGNAQVDGYLQFNPKRSAVSSPQKYCGKKLSNALQIIC 8 | DGVYNSMFKKSGQDFPPQNKRHIAHRINGNEEESFTTLKSNFLNWCVEVYHRHYRFVFVS 9 | EMEMADYPLAYDISPYLPPFLSRARARGMLDGRFAGRRYRRESRGIHEECCINGCTINEL 10 | TSYCGP 11 | -------------------------------------------------------------------------------- /lib/genevalidatorapp/logger.rb: -------------------------------------------------------------------------------- 1 | require 'logger' 2 | 3 | module GeneValidatorApp 4 | class Logger < Logger 5 | def initialize(dev, verbose = false) 6 | super dev 7 | self.level = verbose ? DEBUG : INFO 8 | self.formatter = Formatter.new 9 | end 10 | 11 | # We change Logging format so that it is consistent with Sinatra's 12 | class Formatter < Formatter 13 | Format = "[%s] %s %s\n".freeze 14 | 15 | def initialize 16 | self.datetime_format = '%Y-%m-%d %H:%M:%S' 17 | end 18 | 19 | def call(severity, time, _progname, msg) 20 | format(Format, format_datetime(time), severity, msg2str(msg)) 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - "2.2.10" 4 | - "2.3.7" 5 | - "2.4.4" 6 | - "2.5.1" 7 | before_install: 8 | # Install MAFFT 9 | - mkdir dependencies 10 | - mkdir dependencies/mafft 11 | - curl -L --fail https://mafft.cbrc.jp/alignment/software/mafft-7.397-linux.tgz | tar -xzf - --strip-components=1 -C dependencies/mafft 12 | - MAFFT_DIR="$PWD/dependencies/mafft/mafftdir" 13 | - MAFFT_BINARIES="${MAFFT_DIR}/libexec"; export MAFFT_BINARIES; 14 | # BLAST 15 | - mkdir dependencies/blast 16 | - curl -L --fail https://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/2.7.1/ncbi-blast-2.7.1+-x64-linux.tar.gz | tar -xzf - --strip-components=1 -C dependencies/blast 17 | - BLAST_BIN="$PWD/dependencies/blast/bin" 18 | - export PATH=${MAFFT_DIR}/bin:${BLAST_BIN}:$PATH 19 | script: bundle exec rake test 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GeneValidatorApp 2 | [![Build Status](https://travis-ci.org/wurmlab/genevalidatorapp.svg?branch=master)](https://travis-ci.org/wurmlab/genevalidatorapp) 3 | [![Gem Version](https://badge.fury.io/rb/genevalidatorapp.svg)](http://badge.fury.io/rb/genevalidatorapp) 4 | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/wurmlab/genevalidatorapp/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/wurmlab/genevalidatorapp/?branch=master) 5 | 6 | 7 | ## Introduction 8 | 9 | This repository is part of the GeneValidator Package and is used internally by GeneValidator - Please see [https://github.com/wurmlab/genevalidator](https://github.com/wurmlab/genevalidator) for more information. 10 | 11 | 12 |
13 | 14 | This program was developed at [Wurm Lab](https://wurmlab.github.io), [QMUL](http://sbcs.qmul.ac.uk) with the support of a BBSRC grant. 15 | -------------------------------------------------------------------------------- /public/src/js/jquery.cookie.min.js: -------------------------------------------------------------------------------- 1 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?a(require("jquery")):a(jQuery)}(function(a){function c(a){return h.raw?a:encodeURIComponent(a)}function d(a){return h.raw?a:decodeURIComponent(a)}function e(a){return c(h.json?JSON.stringify(a):String(a))}function f(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(b," ")),h.json?JSON.parse(a):a}catch(c){}}function g(b,c){var d=h.raw?b:f(b);return a.isFunction(c)?c(d):d}var b=/\+/g,h=a.cookie=function(b,f,i){if(void 0!==f&&!a.isFunction(f)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[c(b),"=",e(f),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=b?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){var p=m[n].split("="),q=d(p.shift()),r=p.join("=");if(b&&b===q){l=g(r,f);break}b||void 0===(r=g(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0===a.cookie(b)?!1:(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}}); -------------------------------------------------------------------------------- /genevalidatorapp.gemspec: -------------------------------------------------------------------------------- 1 | lib = File.expand_path('lib', __dir__) 2 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 3 | require 'genevalidatorapp/version' 4 | 5 | Gem::Specification.new do |s| 6 | s.name = 'genevalidatorapp' 7 | s.version = GeneValidatorApp::VERSION 8 | s.authors = ['Monica Dragan', 'Ismail Moghul', 'Anurag Priyam', 9 | 'Yannick Wurm'] 10 | s.email = 'y.wurm@qmul.ac.uk' 11 | s.summary = 'A Web App wrapper for GeneValidator.' 12 | s.description = 'A Web App wrapper for GeneValidator, a program for' \ 13 | ' validating gene predictions.' 14 | s.homepage = 'https://wurmlab.github.io/tools/genevalidator/' 15 | s.license = 'AGPL' 16 | 17 | s.files = `git ls-files -z`.split("\x0") 18 | s.test_files = s.files.grep(%r{^(test|spec|features)/}) 19 | s.require_paths = ['lib'] 20 | 21 | s.required_ruby_version = '>= 2.2.0' 22 | 23 | s.add_development_dependency 'capybara', '~> 2.4', '>= 2.4.4' 24 | s.add_development_dependency 'minitest', '~> 5.10' 25 | s.add_development_dependency 'rake', '~> 12.3' 26 | # s.add_development_dependency 'w3c_validators', '~>1.1' 27 | 28 | s.add_dependency 'bio', '~>1.4' 29 | s.add_dependency 'sinatra', '~> 2.0' 30 | s.add_dependency 'sinatra-cross_origin', '~> 0.3' 31 | s.add_dependency 'slim', '~>3.0' 32 | end 33 | -------------------------------------------------------------------------------- /lib/genevalidatorapp/server.rb: -------------------------------------------------------------------------------- 1 | require 'rack/handler/webrick' 2 | 3 | module GeneValidatorApp 4 | # Simple wrapper around WEBrick and Rack::Handler::WEBrick to host 5 | # GeneValidatorApp standalone. 6 | class Server 7 | class << self 8 | def run(*args) 9 | new(*args).start 10 | end 11 | end 12 | 13 | def initialize(app) 14 | @app = app 15 | end 16 | 17 | attr_reader :app 18 | 19 | # Start server. Raises Errno::EADDRINUSE if port is in use by another 20 | # process. Raises Errno::EACCES if binding to the port requires root 21 | # privilege. 22 | def start 23 | setup_signal_handlers 24 | @server = WEBrick::HTTPServer.new(options) 25 | @server.mount '/', Rack::Handler::WEBrick, app 26 | @server.start 27 | end 28 | 29 | # Stop server. 30 | def stop 31 | @server.shutdown 32 | end 33 | 34 | # Options Hash passed to WEBrick::HTTPServer. 35 | # rubocop:disable Metrics/AbcSize 36 | def options 37 | @options ||= { 38 | BindAddress: app.config[:host], 39 | Port: app.config[:port], 40 | StartCallback: proc { app.on_start }, 41 | StopCallback: proc { app.on_stop }, 42 | OutputBufferSize: 5, 43 | AccessLog: [[logdev, WEBrick::AccessLog::COMMON_LOG_FORMAT]], 44 | Logger: WEBrick::Log.new(logdev) 45 | } 46 | end 47 | # rubocop:enable Metrics/AbcSize 48 | 49 | private 50 | 51 | def setup_signal_handlers 52 | %i[INT TERM].each do |sig| 53 | trap sig do 54 | stop 55 | end 56 | end 57 | end 58 | 59 | def logdev 60 | @logdev ||= app.verbose? ? STDERR : '/dev/null' 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake/testtask' 2 | GEMSPEC = Gem::Specification.load('genevalidatorapp.gemspec') 3 | 4 | task default: [:build] 5 | 6 | desc 'Builds and installs' 7 | task install: [:build] do 8 | sh "gem install #{Rake.original_dir}/genevalidatorapp-#{GEMSPEC.version}.gem" 9 | end 10 | 11 | desc 'Runs tests and builds gem (default)' 12 | task build: [:test] do 13 | sh "gem build #{Rake.original_dir}/genevalidatorapp.gemspec" 14 | end 15 | 16 | desc 'Runs tests' 17 | task :test do 18 | Rake::TestTask.new do |t| 19 | t.libs.push 'lib' 20 | t.test_files = FileList['test/test_*.rb'] 21 | t.verbose = false 22 | t.warning = false 23 | end 24 | end 25 | 26 | desc 'Build Assets' 27 | task :assets do 28 | # Requires uglifycss and uglifyjs 29 | # npm install uglifycss -g 30 | # npm install uglify-js -g 31 | src_assets_dir = File.expand_path('public/src', __dir__) 32 | assets_dir = File.expand_path('public/web_files', __dir__) 33 | `rm #{assets_dir}/css/gv.compiled.min.css` 34 | `rm #{assets_dir}/js/gv.compiled.min.js` 35 | sh "uglifycss --output '#{assets_dir}/css/gv.compiled.min.css'" \ 36 | " '#{src_assets_dir}/css/bootstrap1.min.css'" \ 37 | " '#{src_assets_dir}/css/font-awesome.min.css'" \ 38 | " '#{src_assets_dir}/css/custom.css'" 39 | 40 | sh "uglifyjs '#{src_assets_dir}/js/jquery.min.js'" \ 41 | " '#{src_assets_dir}/js/bootstrap.min.js'" \ 42 | " '#{src_assets_dir}/js/jquery.tablesorter.min.js'" \ 43 | " '#{src_assets_dir}/js/jquery.validate.min.js'" \ 44 | " '#{src_assets_dir}/js/jquery.cookie.min.js'" \ 45 | " '#{src_assets_dir}/js/d3.v3.min.js'" \ 46 | " '#{src_assets_dir}/js/plots.js'" \ 47 | " '#{src_assets_dir}/js/genevalidator.js'" \ 48 | " -m -c -o '#{assets_dir}/js/gv.compiled.min.js'" 49 | end 50 | -------------------------------------------------------------------------------- /public/GeneValidator/loading.html: -------------------------------------------------------------------------------- 1 | GeneValidator: identify problems with gene predictions 2 | 4 | 5 |
6 |

GeneValidator

7 |

Identify Problems with Protein-Coding Gene Predictions

8 | 9 |

Calculating...

10 | 11 |
12 | 13 | -------------------------------------------------------------------------------- /test/test_route_spec.rb: -------------------------------------------------------------------------------- 1 | require 'minitest/autorun' 2 | require 'capybara/minitest' 3 | 4 | require 'genevalidatorapp' 5 | 6 | # Basic unit tests for HTTP / Rack interface. 7 | module GeneValidatorApp 8 | # include W3CValidators 9 | describe 'Routes' do 10 | ENV['RACK_ENV'] = 'production' 11 | include Rack::Test::Methods 12 | 13 | let 'root' do 14 | GeneValidatorApp.root 15 | end 16 | 17 | let 'empty_config' do 18 | File.join(root, 'test', 'empty_config.yml') 19 | end 20 | 21 | let 'database_dir' do 22 | File.join(root, 'test', 'database') 23 | end 24 | 25 | before :each do 26 | GeneValidatorApp.init(config_file: empty_config, 27 | database_dir: database_dir) 28 | 29 | validations = %w[lenc lenr dup merge align frame orf] 30 | sequence = 'AGCTAGCTAGCT' 31 | database = Database.first.name 32 | 33 | @params = { 34 | 'validations' => validations, 35 | 'seq' => sequence, 36 | 'database' => database 37 | } 38 | end 39 | 40 | let 'app' do 41 | GeneValidatorApp 42 | end 43 | 44 | it 'should start the app' do 45 | get '/' 46 | assert_equal(true, last_response.ok?) 47 | end 48 | 49 | it 'returns Bad Request (400) if no sequence is provided' do 50 | @params.delete('seq') 51 | post '/', @params 52 | assert_equal(400, last_response.status) 53 | end 54 | 55 | it 'returns Bad Request (400) if no validations is provided' do 56 | @params.delete('validations') 57 | post '/', @params 58 | assert_equal(400, last_response.status) 59 | end 60 | 61 | it 'returns Bad Request (400) if no database is provided' do 62 | @params.delete('database') 63 | post '/', @params 64 | assert_equal(400, last_response.status) 65 | end 66 | 67 | # W3C_Validator Gem is broken - https://github.com/alexdunae/w3c_validators/issues/16 68 | # it 'validate the html' do 69 | # get '/' 70 | # html = last_response.body 71 | 72 | # validator = MarkupValidator.new 73 | # results = validator.validate_text(html.to_s) 74 | # results.errors.each { |err| puts err.to_s } if results.errors.length > 0 75 | # puts results.errors 76 | # results.errors.length.should == 0 77 | # end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /lib/genevalidatorapp/config.rb: -------------------------------------------------------------------------------- 1 | require 'forwardable' 2 | 3 | # Define Config class. 4 | module GeneValidatorApp 5 | # Capture our configuration system. 6 | class Config 7 | extend Forwardable 8 | 9 | def_delegators GeneValidatorApp, :logger 10 | 11 | def initialize(data = {}) 12 | @data = symbolise data 13 | @config_file = @data.delete(:config_file) || default_config_file 14 | @config_file = File.expand_path(@config_file) 15 | @data = parse_config_file.update @data 16 | @data = defaults.update @data 17 | end 18 | 19 | attr_reader :data, :config_file 20 | 21 | # Get. 22 | def [](key) 23 | data[key] 24 | end 25 | 26 | # Set. 27 | def []=(key, value) 28 | data[key] = value 29 | end 30 | 31 | # Exists? 32 | def include?(key) 33 | data.include? key 34 | end 35 | 36 | # Write config data to config file. 37 | def write_config_file 38 | return unless config_file 39 | 40 | File.open(config_file, 'w') do |f| 41 | f.puts(data.delete_if { |_, v| v.nil? }.to_yaml) 42 | end 43 | end 44 | 45 | private 46 | 47 | # Symbolizes keys. Changes `database` key to `database_dir`. 48 | def symbolise(data) 49 | return {} unless data 50 | # Symbolize keys. 51 | Hash[data.map { |k, v| [k.to_sym, v] }] 52 | end 53 | 54 | # Parses and returns data from config_file if it exists. Returns {} 55 | # otherwise. 56 | def parse_config_file 57 | unless file? config_file 58 | logger.debug "Configuration file not found: #{config_file}" 59 | return {} 60 | end 61 | 62 | logger.debug "Reading configuration file: #{config_file}." 63 | symbolise YAML.load_file(config_file) 64 | rescue StandardError => error 65 | raise CONFIG_FILE_ERROR.new(config_file, error) 66 | end 67 | 68 | def file?(file) 69 | file && File.exist?(file) && File.file?(file) 70 | end 71 | 72 | # Default configuration data. 73 | def defaults 74 | { 75 | num_threads: 1, 76 | mafft_threads: 1, 77 | port: 5678, 78 | ssl: false, 79 | host: '0.0.0.0', 80 | serve_public_dir: File.join(Dir.home, '.genevalidatorapp/'), 81 | max_characters: 'undefined' 82 | } 83 | end 84 | 85 | def default_config_file 86 | '~/.genevalidatorapp.conf' 87 | end 88 | end 89 | end 90 | -------------------------------------------------------------------------------- /lib/genevalidatorapp/database.rb: -------------------------------------------------------------------------------- 1 | require 'find' 2 | require 'digest/md5' 3 | require 'forwardable' 4 | 5 | module GeneValidatorApp 6 | # class on the BLAST databases 7 | class Database < Struct.new(:name, :title, :type) 8 | class << self 9 | extend Forwardable 10 | 11 | def_delegators GeneValidatorApp, :config, :logger 12 | 13 | def collection 14 | @collection ||= {} 15 | end 16 | 17 | private :collection 18 | 19 | def <<(database) 20 | collection[database.id] = database 21 | end 22 | 23 | def [](ids) 24 | ids = Array ids 25 | collection.values_at(*ids) 26 | end 27 | 28 | def ids 29 | collection.keys 30 | end 31 | 32 | def all 33 | collection.values 34 | end 35 | 36 | def each(&block) 37 | all.each(&block) 38 | end 39 | 40 | def include?(path) 41 | collection.include? Digest::MD5.hexdigest path 42 | end 43 | 44 | def group_by(&block) 45 | all.group_by(&block) 46 | end 47 | 48 | def first 49 | all.first 50 | end 51 | 52 | def default_db 53 | if config[:default_db] && Database.include?(config[:default_db]) 54 | all.find { |a| a.name == config[:default_db] } 55 | else 56 | all.first 57 | end 58 | end 59 | 60 | def non_default_dbs 61 | all.find_all { |a| a != Database.default_db } 62 | end 63 | 64 | # Returns the original structure that the title is within. 65 | def obtain_original_structure(db_title) 66 | all.find_all { |a| a.title.chomp == db_title } 67 | end 68 | 69 | # Recurisvely scan `database_dir` for blast databases. 70 | def scan_databases_dir 71 | database_dir = config[:database_dir] 72 | cmd = "blastdbcmd -recursive -list #{database_dir} -list_outfmt" \ 73 | ' "%p::%f::%t"' 74 | list = `#{cmd} 2>&1` 75 | list.each_line do |line| 76 | type, name, title = line.split('::', 3) 77 | next if multipart_database_name?(name) 78 | next unless type.casecmp('protein').zero? 79 | self << Database.new(name, title, type) 80 | end 81 | end 82 | 83 | # Returns true if the database name appears to be a multi-part database 84 | # name. 85 | # 86 | # e.g. 87 | # /home/ben/pd.ben/sequenceserver/db/nr.00 => yes 88 | # /home/ben/pd.ben/sequenceserver/db/nr => no 89 | # /home/ben/pd.ben/sequenceserver/db/img3.5.finished.faa.01 => yes 90 | def multipart_database_name?(db_name) 91 | !db_name.match(%r{.+\/\S+\d{2}$}).nil? 92 | end 93 | end 94 | 95 | def initialize(*args) 96 | args.last.downcase! 97 | args.each(&:freeze) 98 | super 99 | 100 | @id = Digest::MD5.hexdigest args.first 101 | end 102 | 103 | attr_reader :id 104 | 105 | def to_s 106 | "#{type}: #{title} #{name}" 107 | end 108 | end 109 | end 110 | -------------------------------------------------------------------------------- /views/results.slim: -------------------------------------------------------------------------------- 1 | h3 Overview 2 | #overview.text-left 3 | span 4 | strong BLAST Database Used: 5 | = @params[:database] 6 | br 7 | strong BLAST E-Value Used: 8 | | 10-5 9 | br 10 | #overview_text 11 | button#overview_btn.btn.btn-primary.btn-sm style="margin-bottom:10px" data-toggle="button" onclick="GV.toggleOverviewBtn();" data-overviewjson="/GeneValidator/#{@gv_results[:unique_id]}/output/html_files/json/overview.json" 12 | br 13 | 14 | - output_dir = "/GeneValidator/#{@gv_results[:unique_id]}/output/" 15 | - csv_file = File.join(output_dir, 'input_file_results.csv') 16 | - json_file = File.join(output_dir, 'input_file_results.json') 17 | - summary_file = File.join(output_dir, 'input_file_summary.csv') 18 | a.btn.btn-primary.btn-sm target="_blank" download="" style="margin-right:10px;" href="#{csv_file}" CSV Output File 19 | a.btn.btn-primary.btn-sm target="_blank" download="" style="margin-right:10px;" href="#{json_file}" JSON Output File 20 | a.btn.btn-primary.btn-sm target="_blank" download="" style="margin-right:10px;" href="#{summary_file}" Summary CSV Output File 21 | 22 | br/ 23 | hr/ 24 | h3#results_header GeneValidator Results Table 25 | table#sortable_table.table.table-striped.table-collapsed.table-bordered.table-condensed.tablesorter 26 | thead 27 | tr#header 28 | th # 29 | th Ranking 30 | th 31 | | Sequence Definition  32 | span data-placement="top" data-toggle="tooltip" title=("Query definition as it apears in the input fasta file.") 33 | i.fa.fa-question-circle 34 | th 35 | | No. Hits  36 | span data-placement="top" data-toggle="tooltip" title=("Number of non-identical hits found by BLAST.") 37 | i.fa.fa-question-circle 38 | - @json_data_section[0][:validations].each do |_short_header, item| 39 | th.sorter-false 40 | strong 41 | = item[:header] 42 | | 43 | - if item[:header] == "Length Cluster" || item[:header] == "Gene Merge" || item[:header] == "Main ORF" || item[:header] == "Missing/Extra Sequences" 44 | span data-placement="top" data-toggle="tooltip" title=("Charts available for this validation") 45 | i.fa.fa-bar-chart-o.chartIcon 46 | | 47 | span data-placement="top" data-toggle="tooltip" title="#{item[:description]}" 48 | i.fa.fa-question-circle 49 | th.sorter-false.chart-column 50 | tbody 51 | - @json_data_section.each do |row| 52 | - json_file = "/GeneValidator/#{@gv_results[:unique_id]}/output/html_files/json/input_file_#{row[:idx]}.json" 53 | tr data-jsonfile="#{json_file}" data-target="toggle#{row[:idx]}" 54 | td title="idx" = row[:idx] 55 | td data-score="#{row[:overall_score]}" 56 | .ratings 57 | .empty-stars 58 | .full-stars style=("width:#{row[:overall_score]}%;") 59 | td title="Definition" = row[:definition] 60 | td title=("No. Hits") = row[:no_hits] 61 | - row[:validations].each do |_short_header, item| 62 | td class="#{item[:status]}" title="#{item[:header]}" 63 | == item[:print].gsub(' ', ' ').gsub('; ', '; ') 64 | - if row[:validations].select { |_short_header, item| item[:graphs] != nil }.map{ |_short_header, item| item[:graphs].length }.inject(0) { |r, e| r + e } != 0 65 | td 66 | button.plot_btn.btn.btn-default title=("Show plots") 67 | i.fa.fa-bar-chart-o 68 | - else 69 | td 70 | -------------------------------------------------------------------------------- /views/layout.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | html lang="en" 3 | head 4 | meta charset="utf-8" 5 | meta content="IE=edge" http-equiv="X-UA-Compatible" 6 | meta content="width=device-width, initial-scale=1" name="viewport" 7 | meta content="GeneValidator | Identify problems with Gene Predictions" name="description" 8 | meta content="Wurmlab" name="author" 9 | title GeneValidator | Identify problems with Gene Predictions 10 | 11 | link href="/web_files/css/gv.compiled.min.css" rel="stylesheet" type="text/css" 12 | 13 | script type="text/javascript" src="/web_files/js/gv.compiled.min.js" 14 | /! HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries 15 | /![if lt IE 9] 16 | script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js" 17 | script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js" 18 | 19 | body#mainbody 20 | .navbar.navbar-default.navbar-fixed-top role="navigation" 21 | .nav-container 22 | .navbar-header 23 | button.navbar-toggle data-target=".navbar-responsive-collapse" data-toggle="collapse" type="button" 24 | span.icon-bar 25 | span.icon-bar 26 | span.icon-bar 27 | span.navbar-brand 28 | a href="#" GeneValidator 29 | .navbar-collapse.collapse.navbar-responsive-collapse 30 | ul.nav.navbar-nav 31 | li 32 | a href="https://wurmlab.github.io/tools/genevalidator/" target="_blank" GeneValidator 33 | li 34 | a href="https://wurmlab.github.io/tools/genevalidator/api" target="_blank" API 35 | li 36 | a href="https://wurmlab.github.io" target="_blank" Wurm Lab 37 | li 38 | a href="http://doi.org/10.1093/bioinformatics/btw015" target="_blank" Publication 39 | 40 | ul.nav.navbar-nav.navbar-right 41 | li 42 | a.nav_github_icon href="https://github.com/wurmlab/genevalidatorapp" target="_blank" 43 | span.i.fa.fa-2x.fa-github 44 | ==yield 45 | #spinner.modal aria-hidden="true" aria-labelledby="spinner" role="dialog" tabindex="-1" 46 | .modal-dialog 47 | .modal-content 48 | .modal-body.text-center 49 | h2 Calculating... 50 | p.results_link This may take some time. Please leave this page open. 51 | i.fa.fa-spinner.fa-5x.fa-spin 52 | footer#footer 53 | p.text-muted.text-center 54 | | Please cite: 55 | Dragan M, Moghul I, Priyam A, Bustos C & Wurm Y. 2016. GeneValidator: identify problematic gene predictions. 56 | Bioinformatics, doi: 10.1093/bioinformatics/btw015. 57 | br 58 | | Developed at 59 | a href="https://wurmlab.github.io" target="_blank" Wurm Lab 60 | | , 61 | a href="http://www.sbcs.qmul.ac.uk" target="_blank" QMUL 62 | | with funding by 63 | a href="http://www.bbsrc.ac.uk/home/home.aspx" target="_blank" BBSRC 64 | | and 65 | a href="https://www.google-melange.com/gsoc/homepage/google/gsoc2013" target="_blank" Google Summer of Code 2013 66 | br 67 | | This page was created by 68 | a href="https://github.com/wurmlab/genevalidatorapp" target="_blank" GeneValidator Web Application 69 | | v#{GeneValidatorApp::VERSION} (using 70 | a href="https://github.com/wurmlab/genevalidator" target="_blank" GeneValidator 71 | | v#{@current_gv_version}) -------------------------------------------------------------------------------- /views/index.slim: -------------------------------------------------------------------------------- 1 | section#search 2 | h1.page-header 3 | span GeneValidator  4 | span.small Identify problems with gene predictions 5 | form#input action="/" method="POST" 6 | .form-group#input_seq_group 7 | label.control-label.input_seq-label for="seq" Input Sequences: 8 | - if @max_characters != 'undefined' 9 | textarea#seq.form-control autofocus="" name="seq" placeholder="Paste your sequence(s) here..." rows="10" spellcheck="false" data-maxCharacters="#{@max_characters}" 10 | - else 11 | textarea#seq.form-control autofocus="" name="seq" placeholder="Paste your sequence(s) here..." rows="10" spellcheck="false" 12 | .clearfix 13 | .form-group 14 | button#input_btn.btn.btn-lg.btn-primary type="submit" value="input" 15 | i.fa.fa-search 16 | |   Analyse Sequences 17 | button#adv_params_btn.btn.btn-primary type="button" onclick="changeAdvParamsBtnText()" 18 | i.fa.fa-pencil-square-o 19 | |   Show Advanced Parameters 20 | .clearfix 21 | #adv_params.collapse 22 | .form-group.form-inline#validations_group 23 | br/ 24 | label.control-label Advanced Parameters: Validations Types 25 | br/ 26 | label.checkbox-inline.no_indent.col-lg-3.col-md-5.col-sm-6.col-xs-12 27 | Length Validation (via clusterization) 28 | label.checkbox-inline.no_indent.col-lg-3.col-md-5.col-sm-6.col-xs-12 29 | Length Validation (via ranking) 30 | label.checkbox-inline.no_indent.col-lg-3.col-md-5.col-sm-6.col-xs-12 31 | Duplication Check 32 | label.checkbox-inline.no_indent.col-lg-3.col-md-5.col-sm-6.col-xs-12 33 | Gene Merge Validation 34 | label.checkbox-inline.no_indent.col-lg-3.col-md-5.col-sm-6.col-xs-12 35 | Multiple Alignment Validation (proteins) 36 | label.checkbox-inline.no_indent.col-lg-3.col-md-5.col-sm-6.col-xs-12 37 | Blast Reading Frame Validation (nucleotides) 38 | label#lastValidation.checkbox-inline.no_indent.col-lg-3.col-md-5.col-sm-6.col-xs-12 39 | Open Reading Frame Validation (nucleotides) 40 | .clearfix 41 | br/ 42 | .form-group.form-inline 43 | label.control-label Advanced Parameters: Database 44 | br/ 45 | label.radio-inline.no_indent.col-xs-12 46 | #{@default_db.title.chomp} 47 | - unless @non_default_dbs.empty? 48 | - @non_default_dbs.each do |db| 49 | label.radio-inline.no_indent.col-xs-12 50 | #{db.title.chomp} 51 | .clearfix 52 | .show_examples_text 53 | span 54 | a#protein_example onclick="examplarSequence('protein')" 55 | | Show a protein example 56 | span 57 | |  |  58 | span 59 | a#dna_example onclick="examplarSequence('dna')" 60 | | Show a DNA example 61 | section#results 62 | #results_box style="display:none;" 63 | h1#output_header.page-header 64 | span Results 65 | #output -------------------------------------------------------------------------------- /lib/genevalidatorapp/routes.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra/base' 2 | require 'sinatra/cross_origin' 3 | require 'genevalidator/version' 4 | require 'genevalidatorapp/version' 5 | require 'slim' 6 | 7 | module GeneValidatorApp 8 | # The Sinatra Routes 9 | class Routes < Sinatra::Base 10 | register Sinatra::CrossOrigin 11 | 12 | configure do 13 | # We don't need Rack::MethodOverride. Let's avoid the overhead. 14 | disable :method_override 15 | 16 | # Ensure exceptions never leak out of the app. Exceptions raised within 17 | # the app must be handled by the app. We do this by attaching error 18 | # blocks to exceptions we know how to handle and attaching to Exception 19 | # as fallback. 20 | disable :show_exceptions, :raise_errors 21 | 22 | # Make it a policy to dump to 'rack.errors' any exception raised by the 23 | # app so that error handlers don't have to do it themselves. But for it 24 | # to always work, Exceptions defined by us should not respond to `code` 25 | # or http_status` methods. Error blocks errors must explicitly set http 26 | # status, if needed, by calling `status` method. 27 | enable :dump_errors 28 | 29 | # We don't want Sinatra do setup any loggers for us. We will use our own. 30 | set :logging, nil 31 | 32 | # This is the app root... 33 | set :root, -> { GeneValidatorApp.root } 34 | 35 | # This is the full path to the public folder... 36 | set :public_folder, -> { GeneValidatorApp.public_dir } 37 | end 38 | 39 | helpers do 40 | # Overide default URI helper method - to hardcode a https:// 41 | # In our setup, we are running passenger on http:// (not secure) and then 42 | # reverse proxying that onto a 443 port (i.e. https://) 43 | # Generates the absolute URI for a given path in the app. 44 | # Takes Rack routers and reverse proxies into account. 45 | def uri(addr = nil, absolute = true, add_script_name = true) 46 | return addr if addr =~ /\A[a-z][a-z0-9\+\.\-]*:/i 47 | uri = [host = ''] 48 | if absolute 49 | host << (GeneValidatorApp.ssl? ? 'https://' : 'http://') 50 | host << if request.forwarded? || request.port != (request.secure? ? 443 : 80) 51 | request.host_with_port 52 | else 53 | request.host 54 | end 55 | end 56 | uri << request.script_name.to_s if add_script_name 57 | uri << (addr || request.path_info).to_s 58 | File.join uri 59 | end 60 | 61 | def host_with_port 62 | forwarded = request.env['HTTP_X_FORWARDED_HOST'] 63 | if forwarded 64 | forwarded.split(/,\s?/).last 65 | else 66 | request.env['HTTP_HOST'] || "#{request.env['SERVER_NAME'] || 67 | request.env['SERVER_ADDR']}:#{request.env['SERVER_PORT']}" 68 | end 69 | end 70 | 71 | # Remove port number. 72 | def host 73 | host_with_port.to_s.sub(/:\d+\z/, '') 74 | end 75 | 76 | def base_url 77 | @base_url ||= "#{GeneValidatorApp.ssl? ? 'https' : 'http'}://#{host}" 78 | end 79 | end 80 | 81 | # Set up global variables for the templates... 82 | before '/' do 83 | @default_db = Database.default_db 84 | @non_default_dbs = Database.non_default_dbs 85 | @max_characters = GeneValidatorApp.config[:max_characters] 86 | @current_gv_version = GeneValidator::VERSION 87 | end 88 | 89 | get '/' do 90 | slim :index 91 | end 92 | 93 | post '/' do 94 | cross_origin # Required for the API to work... 95 | RunGeneValidator.init(request.url, params) 96 | @gv_results = RunGeneValidator.run 97 | @json_data_section = @gv_results[:parsed_json] 98 | if @params[:results_url] 99 | @gv_results[:results_url] 100 | elsif @params[:json_url] 101 | @gv_results[:json_url] 102 | else 103 | slim :results, layout: false 104 | end 105 | end 106 | 107 | # This error block will only ever be hit if the user gives us a funny 108 | # sequence or incorrect advanced parameter. Well, we could hit this block 109 | # if someone is playing around with our HTTP API too. 110 | error RunGeneValidator::ArgumentError do 111 | status 400 112 | slim :"500", layout: false 113 | end 114 | 115 | # This will catch any unhandled error and some very special errors. Ideally 116 | # we will never hit this block. If we do, there's a bug in GeneValidatorApp 117 | # or something really weird going on. 118 | # TODO: If we hit this error block we show the stacktrace to the user 119 | # requesting them to post the same to our Google Group. 120 | error Exception, RunGeneValidator::RuntimeError do 121 | status 500 122 | slim :"500", layout: false 123 | end 124 | 125 | not_found do 126 | status 404 127 | slim :"500" # TODO: Create another Template 128 | end 129 | end 130 | end 131 | -------------------------------------------------------------------------------- /lib/genevalidatorapp/exceptions.rb: -------------------------------------------------------------------------------- 1 | # This file defines all possible exceptions that can be thrown by 2 | # GeneValidatorApp on startup. 3 | # 4 | # Exceptions only ever inform another entity (downstream code or users) of an 5 | # issue. Exceptions may or may not be recoverable. 6 | # 7 | # Error classes should be seen as: the error code (class name), human readable 8 | # message (to_s method), and necessary attributes to act on the error. 9 | # 10 | # We define as many error classes as needed to be precise about the issue, thus 11 | # making it easy for downstream code (bin/genevalidatorapp or config.ru) to act 12 | # on them. 13 | 14 | module GeneValidatorApp 15 | # Error in config file. 16 | class CONFIG_FILE_ERROR < StandardError 17 | def initialize(ent, err) 18 | @ent = ent 19 | @err = err 20 | end 21 | 22 | attr_reader :ent, :err 23 | 24 | def to_s 25 | < at , but 44 | # didn't". 45 | # 46 | # ENOENT is raised if and only if an entity was set, either using CLI or 47 | # config file. For instance, it's compulsory to set database_dir. But ENOENT 48 | # is not raised if database_dir is not set. ENOENT is raised if database_dir 49 | # was set, but does not exist. 50 | class ENOENT < StandardError 51 | def initialize(des, ent) 52 | @des = des 53 | @ent = ent 54 | end 55 | 56 | attr_reader :des, :ent 57 | 58 | def to_s 59 | "Could not find #{des}: #{ent}" 60 | end 61 | end 62 | 63 | # Raised if bin dir set, but does not exist. 64 | class BIN_DIR_NOT_FOUND < ENOENT 65 | def initialize(ent) 66 | super 'bin dir', ent 67 | end 68 | end 69 | 70 | # Raised if extension file set, but does not exist. 71 | class EXTENSION_FILE_NOT_FOUND < ENOENT 72 | def initialize(ent) 73 | super 'extension file', ent 74 | end 75 | end 76 | 77 | # Raised if database dir set, but does not exist. 78 | class DATABASE_DIR_NOT_FOUND < ENOENT 79 | def initialize(ent) 80 | super 'database dir', ent 81 | end 82 | end 83 | 84 | ## MAFFT NOT INSTALLED OR NOT COMPATIBLE ## 85 | 86 | # Raised if GV could not locate MAFFT binaries on 87 | # user's system. 88 | class MAFFT_NOT_INSTALLED < StandardError 89 | def to_s 90 | 'Could not locate MAFFT binaries.' 91 | end 92 | end 93 | 94 | ## BLAST NOT INSTALLED OR NOT COMPATIBLE ## 95 | 96 | # Raised if GV could not locate NCBI BLAST+ installation on 97 | # user's system. 98 | class BLAST_NOT_INSTALLED < StandardError 99 | def to_s 100 | 'Could not locate BLAST+ binaries.' 101 | end 102 | end 103 | 104 | # Raised if GV could not successfully execute 'blastp -version' 105 | # on user's system (see #141). 106 | class BLAST_NOT_EXECUTABLE < StandardError 107 | def to_s 108 | 'Error executing BLAST+ binaries.' 109 | end 110 | end 111 | 112 | # Raised if GV determined NCBI BLAST+ present on the user's 113 | # system but not meeting GV's minimum version requirement. 114 | class BLAST_NOT_COMPATIBLE < StandardError 115 | def initialize(version) 116 | @version = version 117 | end 118 | 119 | attr_reader :version 120 | 121 | def to_s 122 | <Submitted:'\ 140 | "#{Time.now.strftime('%H:%M-%B_%d_%Y')}\n") 141 | end 142 | sequence.gsub!(/^\>(\S+)/) do |s| 143 | if unique_queries.key?(s) 144 | unique_queries[s] += 1 145 | s + '_' + (unique_queries[s] - 1).to_s 146 | else 147 | unique_queries[s] = 1 148 | s 149 | end 150 | end 151 | @params[:seq] = sequence 152 | end 153 | 154 | # Asserts that the input file has been generated and is not empty 155 | def assert_input_file_present 156 | return if File.exist?(@input_file) && !File.zero?(@input_file) 157 | raise 'GeneValidatorApp was unable to create the input file.' 158 | end 159 | 160 | # Runs GeneValidator 161 | def run_genevalidator 162 | create_gv_log_file 163 | run_gv 164 | assert_json_output_file_produced 165 | rescue SystemExit 166 | raise 'GeneValidator failed to run properly' 167 | end 168 | 169 | def run_gv 170 | run_opt = gv_params 171 | GeneValidator.init(run_opt) 172 | GeneValidator.run 173 | end 174 | 175 | def gv_params 176 | { 177 | validations: @params[:validations], 178 | db: @db, 179 | num_threads: config[:num_threads], 180 | mafft_threads: config[:mafft_threads], 181 | min_blast_hits: 5, 182 | input_fasta_file: @input_file, 183 | output_formats: %w[html csv json summary], 184 | output_dir: File.join(@run_dir, 'output') 185 | } 186 | end 187 | 188 | def create_gv_log_file 189 | @gv_log_file = File.join(@run_dir, 'log_file.txt') 190 | logger.debug("Log file: #{@gv_log_file}") 191 | end 192 | 193 | # Assets whether the results file is produced by GeneValidator. 194 | def assert_json_output_file_produced 195 | @json_file = File.join(@run_dir, 'output/input_file_results.json') 196 | return if File.exist?(@json_file) 197 | raise 'GeneValidator did not produce the required output file.' 198 | end 199 | 200 | # Reuturns the URL of the results page. 201 | def produce_result_url_link(url) 202 | url.gsub(/input/, '').gsub(%r{/*$}, '') + 203 | "/GeneValidator/#{@unique_id}/output/results.html" 204 | end 205 | 206 | # Reuturns the URL of the results page. 207 | def produce_json_url_link(url) 208 | url.gsub(/input/, '').gsub(%r{/*$}, '') + 209 | "/GeneValidator/#{@unique_id}/output/input_file_results.json" 210 | end 211 | 212 | def parse_output_json 213 | json_contents = File.read(output_json_file_path) 214 | JSON.parse(json_contents, symbolize_names: true) 215 | end 216 | 217 | def output_json_file_path 218 | File.join(@run_dir, 'output/input_file_results.json') 219 | end 220 | 221 | def individual_json_path 222 | "/GeneValidator/#{@unique_id}/output/html_files/json" 223 | end 224 | end 225 | end 226 | end 227 | -------------------------------------------------------------------------------- /public/src/js/bionode-seq.min.js: -------------------------------------------------------------------------------- 1 | require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o=threshold||acgMatch+uMatch>=threshold){if(tMatch>=uMatch){return"dna"}else if(uMatch>=tMatch){return"rna"}else{return"dna"}}else if(proteinMatch>=threshold){return"protein"}};seq.createComplementBase=function(sequenceType){var complementBasesMatrix=sequenceType==="rna"||sequenceType==="ambiguousRna"?_rnaComplementBasesMatrix:_dnaComplementBasesMatrix;var getComplementBase=function(base){var complement=complementBasesMatrix[base];return complement||base};return getComplementBase};seq.reverse=function(sequence){return sequence.split("").reverse().join("")};seq.complement=function(sequence,reverse){var reverse=reverse||false;var sequenceType=seq.checkType(sequence);var getComplementBase=seq.createComplementBase(sequenceType);if(reverse){return sequence.split("").reverse().map(getComplementBase).join("")}else{return sequence.split("").map(getComplementBase).join("")}};seq.reverseComplement=function(sequence){return seq.complement(sequence,true)};seq.getTranscribedBase=function(base){return _transcribeBasesMatrix[base]||base};seq.getTranslatedAA=function(codon){return _translateCodonsMatrix[codon]};seq.removeIntrons=function(sequence,exonsRanges){var sequenceWithoutIntrons="";var exonsRangesSorted=exonsRanges.sort(function(a,b){return a[0]-b[0]});exonsRangesSorted.forEach(function(exonRange){sequenceWithoutIntrons+=sequence.substring(exonRange[0],exonRange[1])});return sequenceWithoutIntrons};seq.transcribe=function(sequence,exonsRanges){if(exonsRanges){var sequenceWithoutIntrons=seq.removeIntrons(sequence,exonsRanges);sequence=sequenceWithoutIntrons}var sequenceType=seq.checkType(sequence);if(sequenceType==="dna"||sequenceType==="ambiguousDna"){return sequence.replace(/t/g,"u").replace(/T/g,"U")}else if(sequenceType==="rna"||sequenceType==="ambiguousRna"){return sequence.replace(/u/g,"t").replace(/U/g,"T")}};seq.translate=function(sequence,exonsRanges){if(exonsRanges){var sequenceWithoutIntrons=seq.removeIntrons(sequence,exonsRanges);sequence=sequenceWithoutIntrons}var sequenceType=seq.checkType(sequence);var rna;if(sequenceType==="protein"){return sequence}else if(sequenceType==="dna"||sequenceType==="ambiguousDna"){if(sequenceType==="ambiguousDna")sequence.replace(/[wsmkrybdhv]/g,"x").replace(/[WSMKRYBDHV]/g,"X");rna=seq.transcribe(sequence,exonsRanges)}else if(sequenceType==="rna"||sequenceType==="ambiguousRna"){if(sequenceType==="ambiguousRna")sequence.replace(/[wsmkrybdhv]/g,"x").replace(/[WSMKRYBDHV]/g,"X");rna=sequence}return rna.match(/.{1,3}/g).map(seq.getTranslatedAA).join("")};seq.reverseExons=function(exonsRanges,referenceLength){var reversedExonsRanges=[];exonsRanges.forEach(function(exonRange){var start=referenceLength-exonRange[1];var stop=referenceLength-exonRange[0];reversedExonsRanges.push([start,stop])});return reversedExonsRanges};seq.findNonCanonicalSplices=function(sequence,exonsRanges){var nonCanonicalSplices=[];var exonsRangesSorted=exonsRanges.sort(function(a,b){return a[0]-b[0]});exonsRangesSorted.forEach(checkNonCanonicalIntron);function checkNonCanonicalIntron(exonRange,i){var donor=exonRange;var acceptor=exonsRangesSorted[i+1];if(!acceptor)return null;var intronRange=[donor[1],acceptor[0]];var intronStartBases=sequence.slice(intronRange[0],intronRange[0]+2).toLowerCase().replace("t","u");var intronStopBases=sequence.slice(intronRange[1]-2,intronRange[1]).toLowerCase();if(intronStartBases!=="gu")nonCanonicalSplices.push(intronRange[0]);if(intronStopBases!=="ag")nonCanonicalSplices.push(intronRange[1])}return nonCanonicalSplices};seq.checkCanonicalTranslationStartSite=function(sequence){return sequence.substring(0,3).toLowerCase().replace("t","u")==="aug"};seq.getReadingFrames=function(sequence){var reverse=seq.reverseComplement(sequence);return[sequence,sequence.substring(1),sequence.substring(2),reverse,reverse.substring(1),reverse.substring(2)]};seq.getOpenReadingFrames=function(sequence){var sequenceType=seq.checkType(sequence);var stopCodons;if(sequenceType==="dna"||sequenceType==="ambiguousDna"){stopCodons=["TAA","TGA","TAG","taa","tga","tag"]}else if(sequenceType==="rna"||sequenceType==="ambiguousRna"){stopCodons=["UAA","UGA","UAG","uaa","uga","uag"]}var openReadingFrames=[];var openReadingFrame="";sequence.match(/.{1,3}/g).forEach(function(codon){openReadingFrame+=codon;if(stopCodons.indexOf(codon)!==-1&&openReadingFrame.length>0){openReadingFrames.push(openReadingFrame);openReadingFrame=""}});openReadingFrames.push(openReadingFrame);return openReadingFrames};seq.getAllOpenReadingFrames=function(sequence){var readingFrames=seq.getReadingFrames(sequence);var allOpenReadingFrames=readingFrames.map(seq.getOpenReadingFrames);return allOpenReadingFrames};seq.findLongestOpenReadingFrame=function(sequence,frameSymbol){var frameSymbols=["+1","+2","+3","-1","-2","-3"];if(frameSymbol){var framePosition=frameSymbols.indexOf(frameSymbol);var readingFrame=seq.getReadingFrames(sequence)[framePosition];var openReadingFrames=seq.getOpenReadingFrames(readingFrame);var longestOpenReadingFrame=getLongestOpenReadingFrame(openReadingFrames);return longestOpenReadingFrame}else{var longestOpenReadingFrames=seq.getAllOpenReadingFrames(sequence).map(getLongestOpenReadingFrame);var longestOpenReadingFrame=getLongestOpenReadingFrame(longestOpenReadingFrames.slice());var framePosition=longestOpenReadingFrames.indexOf(longestOpenReadingFrame);var frameSymbol=frameSymbols[framePosition];return[longestOpenReadingFrame,frameSymbol]}function sortReadingFrames(a,b){var aSort=a.length;var bSort=b.length;if(bSort-aSort===0){var aStartCodon=a.slice(0,3).toUpperCase().replace("T","U");var bStartCodon=b.slice(0,3).toUpperCase().replace("T","U");if(aStartCodon==="AUG"){aSort++}if(bStartCodon==="AUG"){bSort++}}return bSort-aSort}function getLongestOpenReadingFrame(array){return array.sort(sortReadingFrames)[0]}}},{}],"bionode-seq":[function(require,module,exports){module.exports=require("./lib/bionode-seq")},{"./lib/bionode-seq":1}]},{},["bionode-seq"]); -------------------------------------------------------------------------------- /lib/genevalidatorapp.rb: -------------------------------------------------------------------------------- 1 | require 'yaml' 2 | require 'fileutils' 3 | 4 | require 'genevalidatorapp/config' 5 | require 'genevalidatorapp/database' 6 | require 'genevalidatorapp/exceptions' 7 | require 'genevalidatorapp/genevalidator' 8 | require 'genevalidatorapp/logger' 9 | require 'genevalidatorapp/routes' 10 | require 'genevalidatorapp/server' 11 | require 'genevalidatorapp/version' 12 | 13 | module GeneValidatorApp 14 | # Use a fixed minimum version of BLAST+ 15 | MINIMUM_BLAST_VERSION = '2.11.0+'.freeze 16 | 17 | class << self 18 | def environment 19 | ENV['RACK_ENV'] 20 | end 21 | 22 | def verbose? 23 | @verbose ||= (environment == 'development') 24 | end 25 | 26 | def root 27 | File.dirname(File.dirname(__FILE__)) 28 | end 29 | 30 | def ssl? 31 | @config[:ssl] 32 | end 33 | 34 | def logger 35 | @logger ||= Logger.new(STDERR, verbose?) 36 | end 37 | 38 | # Setting up the environment before running the app... 39 | def init(config = {}) 40 | @config = Config.new(config) 41 | 42 | init_binaries 43 | init_database 44 | 45 | init_dirs 46 | 47 | load_extension 48 | check_num_threads 49 | check_max_characters 50 | self 51 | end 52 | 53 | attr_reader :config, :temp_dir, :public_dir 54 | 55 | # Starting the app manually 56 | def run 57 | check_host 58 | Server.run(self) 59 | rescue Errno::EADDRINUSE 60 | puts "** Could not bind to port #{config[:port]}." 61 | puts " Is GeneValidator already accessible at #{server_url}?" 62 | puts ' No? Try running GeneValidator on another port, like so:' 63 | puts 64 | puts ' genevalidator app -p 4570.' 65 | rescue Errno::EACCES 66 | puts "** Need root privilege to bind to port #{config[:port]}." 67 | puts ' It is not advisable to run GeneValidator as root.' 68 | puts ' Please use Apache/Nginx to bind to a privileged port.' 69 | end 70 | 71 | def on_start 72 | puts '** GeneValidator is ready.' 73 | puts " Go to #{server_url} in your browser and start analysing genes!" 74 | puts ' Press CTRL+C to quit.' 75 | open_in_browser(server_url) 76 | end 77 | 78 | def on_stop 79 | puts 80 | puts '** Thank you for using GeneValidator :).' 81 | puts ' Please cite: ' 82 | puts ' Dragan M, Moghul MI, Priyam A, Bustos C, Wurm Y. 2016.' 83 | puts ' GeneValidator: identify problems with protein-coding gene' 84 | puts ' predictions. Bioinformatics, doi: 10.1093/bioinformatics/btw015.' 85 | end 86 | 87 | # Rack-interface. 88 | # 89 | # Inject our logger in the env and dispatch request to our controller. 90 | def call(env) 91 | env['rack.logger'] = logger 92 | Routes.call(env) 93 | end 94 | 95 | private 96 | 97 | def init_dirs 98 | config[:serve_public_dir] = File.expand_path(config[:serve_public_dir]) 99 | unique_start_id = 'GV_' + Time.now.strftime('%Y%m%d-%H-%M-%S').to_s 100 | @public_dir = File.join(config[:serve_public_dir], unique_start_id) 101 | init_public_dir 102 | end 103 | 104 | # Create the Public Dir and copy files from gem root - this public dir 105 | # is served by the app is accessible at URL/... 106 | def init_public_dir 107 | FileUtils.mkdir_p(File.join(@public_dir, 'GeneValidator')) 108 | root_web_files = File.join(GeneValidatorApp.root, 'public/web_files') 109 | root_gv = File.join(GeneValidatorApp.root, 'public/GeneValidator') 110 | FileUtils.cp_r(root_web_files, @public_dir) 111 | FileUtils.cp_r(root_gv, @public_dir) 112 | end 113 | 114 | def init_binaries 115 | config[:bin] = init_bins if config[:bin] 116 | assert_blast_installed_and_compatible 117 | assert_mafft_installed 118 | end 119 | 120 | def init_database 121 | set_database_from_env unless config[:database_dir] 122 | raise DATABASE_DIR_NOT_SET unless config[:database_dir] 123 | 124 | config[:database_dir] = File.expand_path(config[:database_dir]) 125 | unless File.exist?(config[:database_dir]) && 126 | File.directory?(config[:database_dir]) 127 | raise DATABASE_DIR_NOT_FOUND, config[:database_dir] 128 | end 129 | 130 | assert_blast_databases_present_in_database_dir 131 | logger.debug("Will use BLAST+ databases at: #{config[:database_dir]}") 132 | 133 | Database.scan_databases_dir 134 | Database.each do |database| 135 | logger.debug("Found #{database.type.chomp} database" \ 136 | " '#{database.title.chomp}' at '#{database.name.chomp}'") 137 | end 138 | end 139 | 140 | # attempt to set the database dir to GV_BLAST_DB_DIR if it exists 141 | def set_database_from_env 142 | config[:database_dir] = ENV['GV_BLAST_DB_DIR'] 143 | end 144 | 145 | def load_extension 146 | return unless config[:require] 147 | config[:require] = File.expand_path config[:require] 148 | unless File.exist?(config[:require]) && File.file?(config[:require]) 149 | raise EXTENSION_FILE_NOT_FOUND, config[:require] 150 | end 151 | 152 | logger.debug("Loading extension: #{config[:require]}") 153 | require config[:require] 154 | end 155 | 156 | def assert_blast_databases_present_in_database_dir 157 | cmd = "blastdbcmd -recursive -list '#{config[:database_dir]}'" 158 | out = `#{cmd}` 159 | errpat = /BLAST Database error/ 160 | raise NO_BLAST_DATABASE_FOUND, config[:database_dir] if out.empty? 161 | raise BLAST_DATABASE_ERROR, cmd, out if out.match(errpat) || 162 | !$CHILD_STATUS.success? 163 | type = [] 164 | out.lines.each { |l| type << l.split[1] } 165 | return if type.include? 'Protein' 166 | raise NO_PROTEIN_BLAST_DATABASE_FOUND, config[:database_dir] 167 | end 168 | 169 | def check_num_threads 170 | num_threads = Integer(config[:num_threads]) 171 | raise NUM_THREADS_INCORRECT unless num_threads > 0 172 | 173 | logger.debug "Will use #{num_threads} threads to run BLAST." 174 | if num_threads > 256 175 | logger.warn "Number of threads set at #{num_threads} is unusually high." 176 | end 177 | rescue StandardError 178 | raise NUM_THREADS_INCORRECT 179 | end 180 | 181 | def check_max_characters 182 | if config[:max_characters] != 'undefined' 183 | config[:max_characters] = Integer(config[:max_characters]) 184 | end 185 | rescue StandardError 186 | raise MAX_CHARACTERS_INCORRECT 187 | end 188 | 189 | def init_bins 190 | bins = [] 191 | Array(config[:bin]).each do |bin| 192 | bins << File.expand_path(bin) 193 | unless File.exist?(bin) && File.directory?(bin) 194 | raise BIN_DIR_NOT_FOUND, config[:bin] 195 | end 196 | export_bin_dir(bin) 197 | end 198 | bins 199 | end 200 | 201 | ## Checks if dir is in $PATH and if not, it adds the dir to the $PATH. 202 | def export_bin_dir(bin_dir) 203 | return unless bin_dir 204 | return if ENV['PATH'].split(':').include?(bin_dir) 205 | ENV['PATH'] = "#{bin_dir}:#{ENV['PATH']}" 206 | end 207 | 208 | def assert_blast_installed_and_compatible 209 | raise BLAST_NOT_INSTALLED unless command? 'blastdbcmd' 210 | version = `blastdbcmd -version`.split[1] 211 | return if is_compatible(version, MINIMUM_BLAST_VERSION) 212 | raise BLAST_NOT_COMPATIBLE, version 213 | end 214 | 215 | def assert_mafft_installed 216 | raise MAFFT_NOT_INSTALLED unless command? 'mafft' 217 | end 218 | 219 | # Check and warn user if host is 0.0.0.0 (default). 220 | def check_host 221 | return unless config[:host] == '0.0.0.0' 222 | logger.warn 'Will listen on all interfaces (0.0.0.0).' \ 223 | ' Consider using 127.0.0.1 (--host option).' 224 | end 225 | 226 | def server_url 227 | host = config[:host] 228 | host = 'localhost' if host == '127.0.0.1' || host == '0.0.0.0' 229 | "http://#{host}:#{config[:port]}" 230 | end 231 | 232 | def open_in_browser(server_url) 233 | return if using_ssh? || verbose? 234 | if RUBY_PLATFORM =~ /linux/ && xdg? 235 | `xdg-open #{server_url}` 236 | elsif RUBY_PLATFORM =~ /darwin/ 237 | `open #{server_url}` 238 | end 239 | end 240 | 241 | def using_ssh? 242 | true if ENV['SSH_CLIENT'] || ENV['SSH_TTY'] || ENV['SSH_CONNECTION'] 243 | end 244 | 245 | def xdg? 246 | true if ENV['DISPLAY'] && command?('xdg-open') 247 | end 248 | 249 | # Return `true` if the given command exists and is executable. 250 | def command?(command) 251 | system("which #{command} > /dev/null 2>&1") 252 | end 253 | 254 | # Returns true if the given version is higher than the minimum expected 255 | # version string. 256 | def is_compatible(given, expected) 257 | # The speceship operator (<=>) below returns -1, 0, 1 depending on 258 | # on whether the left operand is lower, same, or higher than the 259 | # right operand. We want the left operand to be the same or higher. 260 | (parse_version(given) <=> parse_version(expected)) >= 0 261 | end 262 | 263 | # Turn version string into an arrary of its component numbers. 264 | def parse_version(version_string) 265 | version_string.split('.').map(&:to_i) 266 | end 267 | end 268 | end 269 | -------------------------------------------------------------------------------- /public/src/css/custom.css: -------------------------------------------------------------------------------- 1 | html { 2 | /* This is required in order to make the footer stick to the bottom..*/ 3 | /* There is a js function that controls the bottom margin...*/ 4 | position: relative; 5 | min-height: 100%; 6 | } 7 | 8 | body { 9 | margin: 0; 10 | margin-top: 60px; 11 | background-color:#F5F5F5; 12 | } 13 | 14 | section { 15 | width: 100%; 16 | padding: 0 5%; 17 | display: table; 18 | margin: 0; 19 | max-width: none; 20 | padding-bottom: 35px; 21 | } 22 | 23 | .nav-container { 24 | width:100%; 25 | padding: 0 5%; 26 | margin: 0; 27 | } 28 | 29 | .navbar-brand { 30 | padding-left: 0; 31 | } 32 | 33 | footer { 34 | bottom: 0; 35 | width: 100%; 36 | margin: 0 auto; 37 | position: absolute; 38 | border-top: 2px solid #DBDBDB; 39 | padding-top:10px; 40 | } 41 | 42 | .alert-danger{ 43 | background-color: #f2dede; 44 | } 45 | 46 | .alert-danger p { 47 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 48 | font-size: 14px; 49 | line-height: 20px; 50 | text-align: left; 51 | font-weight: 400; 52 | color: #ff1c21; 53 | } 54 | 55 | .alert-danger h3 { 56 | color: #ff1c21; 57 | } 58 | 59 | 60 | /* Navbar 61 | -------------------------------------------------- */ 62 | .navbar-nav>li>a, .navbar-brand { 63 | line-height: 27px; 64 | } 65 | 66 | .navbar-brand a { 67 | color:#fff; 68 | } 69 | 70 | .navbar-brand a:hover { 71 | text-decoration: none; 72 | } 73 | 74 | .navbar-nav > li > a.nav_github_icon { 75 | padding-top: 0; 76 | padding-bottom: 0; 77 | } 78 | 79 | .fa-github { 80 | color: #fff; 81 | padding-top: 18px; 82 | padding-bottom: 18px; 83 | } 84 | 85 | h1 .small { 86 | color: #2C3E50; 87 | } 88 | 89 | .input_seq-label { 90 | font-size: 26px; 91 | } 92 | 93 | #protein_example, #dna_example { 94 | cursor: pointer; 95 | } 96 | 97 | #adv_params_btn { 98 | display: block; 99 | margin-left: auto; 100 | margin-right: auto; 101 | margin-top: 20px; 102 | } 103 | 104 | #input_btn { 105 | display: block; 106 | margin-left: auto; 107 | margin-right: auto; 108 | } 109 | 110 | .show_examples_text { 111 | font-size: 17px; 112 | text-align: center; 113 | margin-top: 10px; 114 | } 115 | 116 | .control-label{ 117 | font-size: 1.25em; 118 | font-weight: normal; 119 | } 120 | 121 | label, .radio label, .checkbox label, .help-block { 122 | font-size: 0.9em; 123 | font-weight: inherit; 124 | } 125 | 126 | .checkbox.inline.no_indent+.checkbox.inline.no_indent { 127 | margin-left: 0; 128 | margin-right: 10px; 129 | 130 | } 131 | .checkbox.inline.no_indent:last-child { 132 | margin-right: 0px; 133 | } 134 | 135 | label.checkbox-inline.no_indent { 136 | margin-left: 0; 137 | margin-right: 10px; 138 | } 139 | 140 | label.radio-inline.no_indent { 141 | margin-left: 0; 142 | margin-right: 10px; 143 | } 144 | 145 | #results_header { 146 | margin-top: 0; 147 | margin-bottom: 30px; 148 | } 149 | 150 | #results_link_btn { 151 | margin-top: 0; 152 | margin-right: -15px; 153 | } 154 | 155 | /* Table 156 | -------------------------------------------------- */ 157 | .table { 158 | color: #333; 159 | } 160 | 161 | .table thead tr { 162 | border-bottom: 3px solid #DDD; 163 | } 164 | 165 | .table td { 166 | font-size: 13px !important; 167 | border-color: rgb(221, 221, 221) !important; 168 | } 169 | 170 | table .success, 171 | .table .success, 172 | table .warning, 173 | .table .warning, 174 | table .danger, 175 | .table .danger, 176 | table .info, 177 | .table .info { 178 | color: #333; 179 | } 180 | 181 | .table-bordered { 182 | border: none; 183 | } 184 | 185 | .danger { 186 | background-color: rgb(242, 222, 222) !important; 187 | } 188 | 189 | .danger:hover { 190 | background-color: rgb(242, 203, 203) !important; 191 | } 192 | 193 | .success { 194 | background-color: rgb(223, 240, 216) !important; 195 | } 196 | 197 | .success:hover{ 198 | background-color: rgb(204, 228, 200) !important; 199 | } 200 | 201 | .warning { 202 | background-color: rgb(252, 248, 227) !important; 203 | } 204 | 205 | .alert-info { 206 | background-color: rgb(217, 237, 247); 207 | border-color: rgb(188, 232, 241); 208 | border-style: solid; 209 | border-width: 1px; 210 | border-collapse: collapse; 211 | box-sizing: border-box; 212 | color: rgb(49, 112, 143); 213 | display: block; 214 | margin-bottom: 0px; 215 | padding-bottom: 15px; 216 | padding-left: 15px; 217 | padding-right: 15px; 218 | padding-top: 15px; 219 | } 220 | 221 | .explanation_alert p { 222 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 223 | font-size: 14px; 224 | line-height: 20px; 225 | text-align: left; 226 | font-weight: 400; 227 | } 228 | 229 | .plot_btn { 230 | color: #333; 231 | background-color: #fff; 232 | border-color: #ccc; 233 | } 234 | 235 | .plot_btn:hover { 236 | color: #333; 237 | background-color: #ebebeb; 238 | border-color: #adadad 239 | } 240 | 241 | .table-bordered>thead>tr>th, 242 | .table-bordered>tbody>tr>th, 243 | .table-bordered>tfoot>tr>th, 244 | .table-bordered>thead>tr>td, 245 | .table-bordered>tbody>tr>td, 246 | .table-bordered>tfoot>tr>td { 247 | border:none; 248 | } 249 | 250 | .table-bordered>tbody>tr { 251 | border-bottom: 2px solid #DDD; 252 | } 253 | 254 | .error_header { 255 | margin-top: 10px; 256 | } 257 | 258 | 259 | /* GeneValidator Results... 260 | -------------------------------------------------- */ 261 | .explanation_alert{ 262 | margin-bottom: 0; 263 | } 264 | 265 | /* TABLE 266 | ___________________________*/ 267 | 268 | .table-responsive { 269 | overflow-x: auto; 270 | } 271 | 272 | .table td { 273 | vertical-align: middle !important; 274 | border-collapse: collapse; 275 | background-clip: padding-box; 276 | text-align: left; 277 | } 278 | 279 | .table th, 280 | .table thead td { 281 | background-color: #E8E8E8; 282 | white-space: nowrap; 283 | } 284 | 285 | tr { 286 | height: 39px; 287 | } 288 | 289 | .expanded-child{ 290 | display: block; 291 | text-align: center; 292 | } 293 | 294 | /* table sorter ___________*/ 295 | 296 | 297 | .tablesorter-default .header, 298 | .tablesorter-default .tablesorter-header { 299 | background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); 300 | background-position: center right; 301 | background-repeat: no-repeat; 302 | cursor: pointer; 303 | padding: 4px 20px 4px 4px; 304 | } 305 | .tablesorter-default thead .headerSortUp, 306 | .tablesorter-default thead .tablesorter-headerSortUp, 307 | .tablesorter-default thead .tablesorter-headerAsc { 308 | background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); 309 | border-bottom: #000 3px solid !important; 310 | } 311 | .tablesorter-default thead .headerSortDown, 312 | .tablesorter-default thead .tablesorter-headerSortDown, 313 | .tablesorter-default thead .tablesorter-headerDesc { 314 | background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); 315 | border-bottom: #000 3px solid !important; 316 | } 317 | .tablesorter-default thead .sorter-false { 318 | background-image: none; 319 | cursor: default; 320 | padding: 4px; 321 | } 322 | 323 | /* table processing indicator */ 324 | .tablesorter-default .tablesorter-processing { 325 | background-position: center center !important; 326 | background-repeat: no-repeat !important; 327 | background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important; 328 | } 329 | 330 | /* table icons ___________*/ 331 | 332 | .table tbody td.success, 333 | .table tbody td.danger, 334 | .table tbody td.warning { 335 | padding-left:30px !important; 336 | position:relative; 337 | } 338 | 339 | .table tbody td.success:before, 340 | .table tbody td.danger:before, 341 | .table tbody td.warning:before { 342 | font-family: FontAwesome; 343 | position: absolute; 344 | margin-left:-25px; 345 | font-size: 1.5em; 346 | margin-top: -0.75em; 347 | top:50%; 348 | } 349 | 350 | .table tbody td.success:before { 351 | content: "\f058"; 352 | color:#1AA882; 353 | } 354 | 355 | .table tbody td.danger:before { 356 | content: "\f057"; 357 | color:#FC585A; 358 | } 359 | 360 | .table tbody td.warning:before{ 361 | content: "\f06a"; 362 | color:#FCB83F; 363 | } 364 | 365 | .table tbody td.success, 366 | .table tbody td.danger { 367 | cursor: pointer !important; 368 | } 369 | 370 | /* Tooltips 371 | ___________________________*/ 372 | 373 | .tooltip > .tooltip-inner { 374 | background-color: #fff; 375 | color: #000; 376 | border: 1px solid #CCCCCC; 377 | max-width:275px; 378 | } 379 | 380 | .tooltip.top > .tooltip-arrow { 381 | bottom:0; 382 | left:50%; 383 | margin-left:-5px; 384 | border-left:5px solid transparent; 385 | border-right:5px solid transparent; 386 | border-top:5px solid #CCC 387 | } 388 | 389 | /* D3Js & Axis 390 | ___________________________*/ 391 | .axis path, 392 | .axis line { 393 | fill: none; 394 | stroke: #000; 395 | shape-rendering: crispEdges; 396 | } 397 | 398 | .dot { 399 | stroke: #000; 400 | opacity:0.7; 401 | } 402 | 403 | .line1 { 404 | fill: green; 405 | stroke: black; 406 | stroke-width: 1.5px; 407 | opacity:0.5; 408 | } 409 | 410 | svg:not(:root) { 411 | overflow: visible; 412 | } 413 | 414 | svg { 415 | margin:15px; 416 | } 417 | 418 | /* Ratings... 419 | ___________________________*/ 420 | 421 | .ratings { 422 | position: relative; 423 | vertical-align: middle; 424 | display: inline-block; 425 | color: #b1b1b1; 426 | overflow: hidden; 427 | } 428 | 429 | .full-stars{ 430 | position: absolute; 431 | left: 0; 432 | top: 0; 433 | white-space: nowrap; 434 | overflow: hidden; 435 | color: #fde16d; 436 | } 437 | 438 | .empty-stars:before, 439 | .full-stars:before { 440 | font-family: FontAwesome; 441 | content: "\f005\f005\f005\f005\f005"; 442 | font-size: 14pt; 443 | } 444 | 445 | .empty-stars:before { 446 | -webkit-text-stroke: 1px #848484; 447 | } 448 | 449 | .full-stars:before { 450 | -webkit-text-stroke: 1px orange; 451 | } 452 | 453 | /* Other 454 | ___________________________*/ 455 | 456 | .menu_icon { 457 | padding-left: 10px; 458 | font-weight: bold; 459 | } 460 | 461 | #toggle { 462 | text-align:center; 463 | } 464 | 465 | .tooltip-inner { 466 | white-space: pre-wrap; 467 | min-width: 100px; 468 | } 469 | 470 | #report { 471 | text-align: left; 472 | } 473 | 474 | 475 | /* Responsive CSS 476 | ___________________________*/ 477 | 478 | @media (min-width: 768px) { 479 | #adv_params_btn { 480 | float:left !important; 481 | margin-top:0; 482 | } 483 | 484 | #input_btn { 485 | float:right !important; 486 | } 487 | 488 | .show_examples_text { 489 | text-align: left; 490 | } 491 | 492 | .container{ 493 | width:90%; 494 | } 495 | } 496 | 497 | 498 | /* Browser Specific 499 | ___________________________*/ 500 | 501 | /* Border on Stars ________*/ 502 | /* Webkit-text-stroke not support on firefox or IE */ 503 | /* Firefox */ 504 | @-moz-document url-prefix() { 505 | .full-stars{ 506 | color: #ECBE24; 507 | } 508 | } 509 | /* IE */ 510 | 516 | -------------------------------------------------------------------------------- /public/src/js/genevalidator.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | 'use strict'; 3 | checkCollapseState(); 4 | keepFooterFixedToBottom(); 5 | addSeqValidation(); 6 | inputValidation(); 7 | bindTdClicks(); 8 | 9 | $(document).bind('keydown', function (e) { 10 | if (e.ctrlKey && e.keyCode === 13 ) { 11 | $('#input').trigger('submit'); 12 | } 13 | }); 14 | }); 15 | 16 | // Looks for a cookie (called 'GeneValidator_adv_params_status') to check the state of the adv_params box when it was last closed. 17 | // This function is called upon as soon as the website is loaded; 18 | var checkCollapseState = function () { 19 | 'use strict'; 20 | if ($.cookie('GeneValidator_adv_params_status')){ 21 | var adv_params_status = $.cookie('GeneValidator_adv_params_status'); 22 | if (adv_params_status === 'open') { 23 | var btn = document.getElementById('adv_params_btn'); 24 | btn.innerHTML = '  Hide Advanced Parameters'; 25 | $('#adv_params').addClass('in'); 26 | } 27 | } 28 | }; 29 | 30 | // This function simply ensures that the footer stays to fixed to the bottom of the window 31 | var keepFooterFixedToBottom = function () { 32 | 'use strict'; 33 | $('#mainbody').css({'margin-bottom': (($('#footer').height()) + 15)+'px'}); 34 | $(window).resize(function(){ 35 | $('#mainbody').css({'margin-bottom': (($('#footer').height()) + 15)+'px'}); 36 | }); 37 | }; 38 | 39 | // Creates a custom Validation for Jquery Validation plugin... 40 | // It ensures that sequences are either protein or DNA data... 41 | // If there are multiple sequences, ensures that they are of the same type 42 | // It utilises the checkType function (further below)... 43 | var addSeqValidation = function () { 44 | 'use strict'; 45 | jQuery.validator.addMethod('checkInputType', function(value, element) { 46 | var types = [], 47 | type = ''; 48 | if (value.charAt(0) === '>') { 49 | var seqs_array = value.split('>'); 50 | for (var i = 1; i < seqs_array.length; i++) { 51 | var lines = seqs_array[i].split('\n'); 52 | if (lines.length !== 0) { 53 | var clean_lines = jQuery.grep(lines,function(n){ return(n); }); 54 | if (clean_lines.length !== 0){ 55 | clean_lines.shift(); 56 | var seq = clean_lines.join(''); 57 | type = checkType(seq, 0.9); 58 | types.push(type); 59 | if ((type !== 'protein') && (type !== 'dna') && (type !== 'rna')) { 60 | return false; 61 | } 62 | } 63 | } 64 | } 65 | var firstType = types[0]; 66 | for (var j = 0; j < types.length; j++) { 67 | if (types[j] !== firstType){ 68 | return false; 69 | } 70 | } 71 | return true; 72 | } else { 73 | type = checkType(value, 0.9); 74 | if ((type !== 'protein') && (type !== 'dna') && (type !== 'rna')) { 75 | return false; 76 | } else { 77 | return true; 78 | } 79 | } 80 | }, '* The Input must be either DNA or protein sequence(s). Please ensure that your sequences do not contains any non-letter character(s). If there are multiple sequences, ensure that they are all of one type. '); 81 | }; 82 | 83 | 84 | // A function that validates the input - Utilises Jquery.Validator.js 85 | var inputValidation = function () { 86 | 'use strict'; 87 | var maxCharacters = $('#seq').attr('data-maxCharacters'); // returns a number or undefined 88 | $('#input').validate({ 89 | rules: { 90 | seq: { 91 | minlength: 5, 92 | required: true, 93 | checkInputType: true, 94 | maxlength: maxCharacters // when undefined, maxlength is unlimited 95 | }, 96 | 'validations[]': { 97 | required: true, 98 | }, 99 | }, 100 | highlight: function(element) { 101 | $(element).closest('.form-group').addClass('has-error'); 102 | }, 103 | unhighlight: function(element) { 104 | $(element).closest('.form-group').removeClass('has-error'); 105 | }, 106 | errorElement: 'span', 107 | errorClass: 'help-block', 108 | errorPlacement: function(error, element) { 109 | if (element.parent().parent().attr('id') === 'validations_group') { 110 | var helpText = document.getElementById('lastValidation'); 111 | error.insertAfter(helpText); 112 | } else { 113 | if (element.parent('.input-group').length) { 114 | error.insertAfter(element.parent()); 115 | } else { 116 | error.insertAfter(element); 117 | } 118 | } 119 | }, 120 | submitHandler: function(form) { 121 | $('#spinner').modal({ 122 | backdrop: 'static', 123 | keyboard: 'false' 124 | }); 125 | ajaxFunction(); 126 | } 127 | }); 128 | }; 129 | 130 | var bindTdClicks = function () { 131 | $( document ).on( "click", "td, .plot_btn", function( event ) { 132 | if ($(this).hasClass('success') || $(this).hasClass('danger')){ 133 | var title = $(this).attr('title'); 134 | var val = title.replace(/[ \/]/g, ''); 135 | GV.addData(this, val); 136 | } else if ($(this).hasClass('plot_btn')){ 137 | GV.addData(this, 'all'); 138 | } 139 | }); 140 | }; 141 | 142 | // Sends the data within the form to the Server 143 | var ajaxFunction = function () { 144 | 'use strict'; 145 | $.ajax({ 146 | type: 'POST', 147 | url: $('#input').attr('action'), 148 | data: $('#input').serialize(), 149 | success: function(response){ 150 | $('#results_box').show(); 151 | $('#output').html(response); 152 | GV.toggleOverviewBtn(); // add overview info from JSON 153 | initTableSorter(); // initiate the table sorter 154 | $("[data-toggle='tooltip']").tooltip(); // Initiate the tooltips 155 | 156 | $('#mainbody').css({'background-color': '#fff'}); 157 | $('#search').css({'background-color': '#F5F5F5'}); 158 | $('#results').css({'border-top': '3px solid #DBDBDB'}); 159 | $('#search').css({'margin-bottom': '0'}); 160 | 161 | $('#spinner').modal('hide'); // remove progress notification 162 | }, 163 | error: function (e, status) { 164 | var errorMessage; 165 | if (e.status == 500 || e.status == 400) { 166 | errorMessage = e.responseText; 167 | $('#results_box').show(); 168 | $('#output').html(errorMessage); 169 | $('#spinner').modal('hide'); // remove progress notification 170 | } else { 171 | errorMessage = e.responseText; 172 | $('#results_box').show(); 173 | $('#output').html('There seems to be an unidentified Error.'); 174 | $('#spinner').modal('hide'); // remove progress notification 175 | } 176 | } 177 | }); 178 | }; 179 | 180 | // Table sortert Initialiser 181 | // Contains a custom parser that allows the Stars to be sorted. 182 | var initTableSorter = function () { 183 | 'use strict'; 184 | $.tablesorter.addParser({ 185 | id: 'star_scores', 186 | is: function(s) {return false;}, 187 | format: function(s, table, cell, cellIndex) { 188 | var $cell = $(cell); 189 | if (cellIndex === 1) { 190 | return $cell.attr('data-score') || s; 191 | } 192 | return s; 193 | }, 194 | parsed: false, 195 | type: 'numeric' 196 | }); 197 | 198 | $('table').tablesorter({ 199 | headers: { 200 | 1 : { sorter: 'star_scores' } 201 | }, 202 | sortList: [[0,0]], 203 | }); 204 | }; 205 | 206 | // Function is called each time the Adv. Params button is pressed... 207 | var changeAdvParamsBtnText = function () { 208 | 'use strict'; 209 | var btn = document.getElementById('adv_params_btn'); 210 | if (btn.innerHTML === '  Show Advanced Parameters') { 211 | btn.innerHTML = '  Hide Advanced Parameters'; 212 | $('#adv_params').collapse('show'); 213 | $.cookie('GeneValidator_adv_params_status', 'open'); 214 | } 215 | else { 216 | btn.innerHTML = '  Show Advanced Parameters'; 217 | $('#adv_params').collapse('hide'); 218 | $.cookie('GeneValidator_adv_params_status', 'closed'); 219 | } 220 | }; 221 | 222 | // Changes the input to an examplar dna or protein sequence... 223 | var examplarSequence = function (type){ 224 | 'use strict'; 225 | var dna = '>Insulin\n' + 226 | 'ATGGCTCTCTGGATCCGGTCGCTGCCTCTCCTGGCCCTTCTTGCTCTTTCTGGCCCTGGGATCAGCCACGCAGCTGCCAACCAGCACCTCTGTGGCTCCCACTTGGTTGAGGCTCTCTACCTGGTGTGTGGGGAGCGGGGTTTCTTCTACTCCCCCAAAACACGGCGGGACGTTGAGCAGCCTCTAGTGAACGGTCCCCTGCATGGCGAGGTGGGAGAGCTGCCGTTCCAGCATGAGGAATACCAGAAAGTCAAGCGAGGCATCGTTGAGCAATGCTGTGAAAACCCGTGCTCCCTCTACCAACTGGAAAACTACTGCAACTAG\n' + 227 | '>Insulin (with a duplication)\n' + 228 | 'ATGGCTCTCTGGATCCGGTCGCTGCCTCTCCTGGCCCTTCTTGCTCTTTCTGGCCCTGGGATCAGCCACGCAGCTGCCAACCAGCACCTCTGTGGCTCCCACTTGGTTGAGGCTCTCTACCTGGTGTGTGGGGAGCGGGGTTTCTTCTACTCCCCCAAAACACGGCGGGACGTTGAGCAGCCTCTAGTGAACGGTCCCCTGCATGGCGAGGTGGGAGAGCTGCCGTTCCAGCATGAGGAATACCAGACAGCACCTCTGTGGCTCCCACTTGGTTGAGGCTCTCTACCTGGTGTGTGGGGAGCGGGGTTTCTTCTACTCCCCCAAAACACGGCGGGACGTTGAGCAGCCTCTAGTGAACGGTCCCCTGCATGGCGAGGTGGGAGAGCTGCCGTTCCAGCATGAGGAATACCAGAAAGTCAAGCGAGGCATCGTTGAGCAATGCTGTGAAAACCCGTGCTCCCTCTACCAACTGGAAAACTACTGCAACTAG'; 229 | var protein = '>Methylmalonyl-CoA carboxyltransferase 12S \n' + 230 | 'MAENNNLKLASTMEGRVEQLAEQRQVIEAGGGERRVEKQHSQGKQTARERLNNLLDPHSFDEVGAFRKHRTTLFGMDKAVVPADGVVTGRGTILGRPVHAASQDFTVMGGSAGETQSTKVVETMEQALLTGTPFLFFYDSGGARIQEGIDSLSGYGKMFFANVKLSGVVPQIAIIAGPCAGGASYSPALTDFIIMTKKAHMFITGPQVIKSVTGEDVTADELGGAEAHMAISGNIHFVAEDDDAAELIAKKLLSFLPQNNTEEASFVNPNNDVSPNTELRDIVPIDGKKGYDVRDVIAKIVDWGDYLEVKAGYATNLVTAFARVNGRSVGIVANQPSVMSGCLDINASDKAAEFVNFCDSFNIPLVQLVDVPGFLPGVQQEYGGIIRHGAKMLYAYSEATVPKITVVLRKAYGGSYLAMCNRDLGADAVYAWPSAEIAVMGAEGAANVIFRKEIKAADDPDAMRAEKIEEYQNAFNTPYVAAARGQVDDVIDPADTRRKIASALEMYATKRQTRPAKKPWKLPLLSEEEIMADEEEKDLMIATLNKRVASLESELGSLQSDTQGVTEDVLTAISAVAAYLGNDGSAEVVHFAPSPNWVREGRRALQNHSIR\n' + 231 | '>locus=Si_gnF\n' + 232 | 'MWFPVVLLLLVGVAVAMPDHEHAWEPQNEYQYSVFVRTLTGVDTLKQQYTGIQLKGVLVIQVKSEELLQAKYINPRYAHIHQELSNGPYSKIPEENLEYRDIPMSGKPFEIKLKHGVIRDLLFDRNVPTWEVNMLKGIVGQLQIDTQGENAIDSQSTQIPSNSEPSSATFKAMEDSVGGKCEVLYEITPLPQHVAQTRPDRVPMSSVPSKGHHYEVKKLKNYEKCQERQLYHYGMDVKMTKENMMKRNKVVSELSTTHIVITGTLKSFTIQSTEMKNEITVQPESSDSPIGTVYSITKLTLAKINKISNSWFGPLELSNVESTGNLVYIFNNPFSDSEQRRVGQPSISRNSEQENSLETKKRSFHSHSSSSSSSSSSSSEEENESVMQSKASLRNIFMAPNVPLLPYFIGFKGKTIMKSNEHNVMQLAKDLLLQIAKEIQNPSEGYENTLEKYVNLKNLIRTMDRKQYTELEQYVSQFNKATVEGENAWYTLRDAVVHAGTGPAFVTIENWLKSGQVKGEEAAELLSKIPKSVHQPTPDYIKEFFKLIKSSVVTQQEYVNVSAPLAFAELLRNNYVVPSYYPVHSFGRMTLKGNEEIDNYISYLANQLQQGYLENNTQKIQTFIFALGVTAHPKIISVFEPYLEGKLPTTKYQRMLMVAALYDLSRDIPKLVGPIFYKLYMNENEAHEVRCMAVQQFILTDPPMITLQRVAKYTNYDQSDQVNSAVKSTLNSIINTKRPEWRNLANKARSVRYLVNPKNYDTWYSKGYYIDFENWVFKGLNVKMVASNDAVLPRYVYVGLDSIFNFLRKPTFEVGYAVSSYRQVYDLINELWNSYQFEEMREKSQGSRVEKLAQELKIKSGQKNNLEGHVLFNSVYGSMVYPYDKHRIREAVAALKKLLTSDSKLKTTAFNNFEKIVSFPMEMGVPFVYSFELPVFVKSEINFKKGEPITSRSGVYETLFCNRVQKRFGFIAPFEYQNYIAGIDKNGIMRVPLKYETNIDIKQKNFALKIHPNIPQSGTSTGLTHYSVVPFTTRQNIFNLQPVSNEGNTRPVITSEIHKMTKEKGPFSIKIESDTTKKESVLEDIVTGISKSSNSNNERYMKIDTTFESKQVAKCEIQIDMTFDAVTIHGKNQQPSHKEMQHHSKLDWKPNSKERREEIVNVLSAGLKSGTVFVADVSFSLPRLQDNTYVFTVGSVRSNIDQKLRHYFYVNTNAAQEVKYELCYSQEVQYAYPTPLNFEYAINNEPKDKLKGVLRYGRTCNTGNEIVITGSSSQSPQLRDMIENSSITKQCMEEIQKGKKSVRTCNKATDVAQVRDQLNFHIDASQLSEIRQKYDQVIGLLNYTNLSQYNVQQNSETNTIVVQNPWVMVPTVQEPWYRWAIKPSESQRQSEIDVLLDEVSQPSCTLDNDKILTFDNQLYNVQLGKCKHVLLTTYPQDSHNRRNYIPESSKVAVLAKDTDNDSRNVYVWLGNLEIELKKVGNDLKVAINGQNVEIPEKGHQESNGNEIIFEIVQLPDGSLSVISEKYGITVIFDGKHVRLYANGATYRNAIRGLCGNYDSRRDNDFLTPKNCLLTKPEEFAATYAMTNENCQGPAPENKRKAEGAMCIEVPEQQQMNVISDREAGRMMTEGGNWGYHQSNRKKEHGQDSKRGHGHKKYNQKDSQEGGSNESQYRKKHNIVYRTRVVEMDDKICFTTTPVPGCLQDTRPVERVPKKYDLYCLSKNNESMDLKRRVEEGAKPDFTQKPVNKIQNFQIPVSCSAA'; 233 | 234 | if (type === 'dna'){ 235 | document.getElementById('seq').value = dna; 236 | } else if (type === 'protein') { 237 | document.getElementById('seq').value = protein; 238 | } 239 | }; 240 | 241 | // FROM BIONODE-Seq - See https://github.com/bionode/bionode-seq 242 | // Checks whether a sequence is a protein or dna sequence... 243 | var checkType = function (sequence, threshold, length, index) { 244 | 'use strict'; 245 | if (threshold === undefined) { 246 | threshold = 0.9; 247 | } 248 | if (length === undefined) { 249 | length = 10000; 250 | } 251 | if (index === undefined) { 252 | index = 1; 253 | } 254 | var seq = sequence.slice(index - 1, length); 255 | 256 | var dnaSeq = seq.replace(/N/gi,''); 257 | var dnaTotal = dnaSeq.length; 258 | var acgMatch = ((dnaSeq.match(/[ACG]/gi) || []).length) / dnaTotal; 259 | var tMatch = ((dnaSeq.match(/[T]/gi) || []).length) / dnaTotal; 260 | var uMatch = ((dnaSeq.match(/[U]/gi) || []).length) / dnaTotal; 261 | 262 | var proteinSeq = seq.replace(/X/gi,''); 263 | var proteinTotal = proteinSeq.length; 264 | var proteinMatch = ((seq.match(/[ARNDCQEGHILKMFPSTWYV\*]/gi) || []).length) / proteinTotal; 265 | 266 | if (((acgMatch + tMatch) >= threshold) || ((acgMatch + uMatch) >= threshold)) { 267 | if (tMatch >= uMatch) { 268 | return 'dna'; 269 | } else if (uMatch >= tMatch) { 270 | return 'rna'; 271 | } else { 272 | return 'dna'; 273 | } 274 | } else if (proteinMatch >= threshold) { 275 | return 'protein'; 276 | } 277 | }; 278 | -------------------------------------------------------------------------------- /public/src/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.1.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-square:before,.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"} -------------------------------------------------------------------------------- /public/src/js/jquery.validate.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.13.0 - 7/1/2014 2 | * http://jqueryvalidation.org/ 3 | * Copyright (c) 2014 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.validateDelegate(":submit","click",function(b){c.settings.submitHandler&&(c.submitButton=b.target),a(b.target).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(b.target).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.submit(function(b){function d(){var d;return c.settings.submitHandler?(c.submitButton&&(d=a("").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c;return a(this[0]).is("form")?b=this.validate().form():(b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b})),b},removeAttrs:function(b){var c={},d=this;return a.each(b.split(/\s/),function(a,b){c[b]=d.attr(b),d.removeAttr(b)}),c},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){return!!a.trim(""+a(b).val())},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&!this.blockFocusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(a,b){(9!==b.which||""!==this.elementValue(a))&&(a.name in this.submitted||a===this.lastElement)&&this.element(a)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date ( ISO ).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c=a.data(this[0].form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!this.is(e.ignore)&&e[d].call(c,this[0],b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).validateDelegate(":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'] ,[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox']","focusin focusout keyup",b).validateDelegate("select, option, [type='radio'], [type='checkbox']","click",b),this.settings.invalidHandler&&a(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c=this.clean(b),d=this.validationTargetFor(c),e=!0;return this.lastElement=d,void 0===d?delete this.invalid[c.name]:(this.prepareElement(d),this.currentElements=a(d),e=this.check(d)!==!1,e?delete this.invalid[d.name]:this.invalid[d.name]=!0),a(b).attr("aria-invalid",!e),this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),e},showErrors:function(b){if(b){a.extend(this.errorMap,b),this.errorList=[];for(var c in b)this.errorList.push({message:b[c],element:this.findByName(c)[0]});this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors(),this.elements().removeClass(this.settings.errorClass).removeData("previousValue").removeAttr("aria-invalid")},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){return!this.name&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in c||!b.objectLength(a(this).rules())?!1:(c[this.name]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([]),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d=a(b),e=b.type;return"radio"===e||"checkbox"===e?a("input[name='"+b.name+"']:checked").val():"number"===e&&"undefined"!=typeof b.validity?b.validity.badInput?!1:d.val():(c=d.val(),"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;aWarning: No message defined for "+b.name+"")},formatAndAdd:function(b,c){var d=this.defaultMessage(b,c.method),e=/\$?\{(\d+)\}/g;"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),this.errorList.push({message:d,element:b,method:c.method}),this.errorMap[b.name]=d,this.submitted[b.name]=d},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g=this.errorsFor(b),h=this.idOrName(b),i=a(b).attr("aria-describedby");g.length?(g.removeClass(this.settings.validClass).addClass(this.settings.errorClass),g.html(c)):(g=a("<"+this.settings.errorElement+">").attr("id",h+"-error").addClass(this.settings.errorClass).html(c||""),d=g,this.settings.wrapper&&(d=g.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b),g.is("label")?g.attr("for",h):0===g.parents("label[for='"+h+"']").length&&(f=g.attr("id"),i?i.match(new RegExp("\b"+f+"\b"))||(i+=" "+f):i=f,a(b).attr("aria-describedby",i),e=this.groups[b.name],e&&a.each(this.groups,function(b,c){c===e&&a("[name='"+b+"']",this.currentForm).attr("aria-describedby",g.attr("id"))}))),!c&&this.settings.success&&(g.text(""),"string"==typeof this.settings.success?g.addClass(this.settings.success):this.settings.success(g,b)),this.toShow=this.toShow.add(g)},errorsFor:function(b){var c=this.idOrName(b),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+d.replace(/\s+/g,", #")),this.errors().filter(e)},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(a){return this.checkable(a)&&(a=this.findByName(a.name).not(this.settings.ignore)[0]),a},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+b+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,"remote")})}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),/min|max/.test(c)&&(null===g||/number|range|text/.test(g))&&(d=Number(d)),d||0===d?e[c]=d:g===c&&"range"!==g&&(e[c]=!0);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b);for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),void 0!==d&&(e[c]=d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0!==e.param?e.param:!0:delete b[d]}}),a.each(b,function(d,e){b[d]=a.isFunction(e)?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(b.min&&b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),b.minlength&&b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:a.trim(b).length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||d>=e},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(a.trim(b),c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||c>=a},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d){if(this.optional(c))return"dependency-mismatch";var e,f,g=this.previousValue(c);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),g.originalMessage=this.settings.messages[c.name].remote,this.settings.messages[c.name].remote=g.message,d="string"==typeof d&&{url:d}||d,g.old===b?g.valid:(g.old=b,e=this,this.startRequest(c),f={},f[c.name]=b,a.ajax(a.extend(!0,{url:d,mode:"abort",port:"validate"+c.name,dataType:"json",data:f,context:e.currentForm,success:function(d){var f,h,i,j=d===!0||"true"===d;e.settings.messages[c.name].remote=g.originalMessage,j?(i=e.formSubmitted,e.prepareElement(c),e.formSubmitted=i,e.successList.push(c),delete e.invalid[c.name],e.showErrors()):(f={},h=d||e.defaultMessage(c,"remote"),f[c.name]=g.message=a.isFunction(h)?h(b):h,e.invalid[c.name]=!0,e.showErrors(f)),g.valid=j,e.stopRequest(c,j)}},d)),"pending")}}}),a.format=function(){throw"$.format has been deprecated. Please use $.validator.format instead."};var b,c={};a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a.extend(a.fn,{validateDelegate:function(b,c,d){return this.bind(c,function(c){var e=a(c.target);return e.is(b)?d.apply(e,arguments):void 0})}})}); -------------------------------------------------------------------------------- /test/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nsd: -------------------------------------------------------------------------------- 1 | lcl|si2.2.0_00025131 2 | lcl|si2.2.0_00029402 3 | lcl|si2.2.0_00040213 4 | lcl|si2.2.0_00041194 5 | lcl|si2.2.0_00109260 6 | lcl|si2.2.0_00222376 7 | lcl|si2.2.0_00225277 8 | lcl|si2.2.0_00231230 9 | lcl|si2.2.0_00233226 10 | lcl|si2.2.0_00257382 11 | lcl|si2.2.0_00262156 12 | lcl|si2.2.0_00263354 13 | lcl|si2.2.0_00272222 14 | lcl|si2.2.0_00313290 15 | lcl|si2.2.0_00336338 16 | lcl|si2.2.0_00352340 17 | lcl|si2.2.0_0039883 18 | lcl|si2.2.0_00408422 19 | lcl|si2.2.0_0041737 20 | lcl|si2.2.0_00442323 21 | lcl|si2.2.0_00476267 22 | lcl|si2.2.0_00491426 23 | lcl|si2.2.0_0051241 24 | lcl|si2.2.0_00530448 25 | lcl|si2.2.0_00539396 26 | lcl|si2.2.0_0054894 27 | lcl|si2.2.0_00556361 28 | lcl|si2.2.0_00573452 29 | lcl|si2.2.0_00688241 30 | lcl|si2.2.0_00726163 31 | lcl|si2.2.0_00735424 32 | lcl|si2.2.0_00757233 33 | lcl|si2.2.0_00758469 34 | lcl|si2.2.0_0076791 35 | lcl|si2.2.0_00796104 36 | lcl|si2.2.0_0080276 37 | lcl|si2.2.0_00815455 38 | lcl|si2.2.0_00838401 39 | lcl|si2.2.0_00846117 40 | lcl|si2.2.0_00856188 41 | lcl|si2.2.0_00883239 42 | lcl|si2.2.0_00895155 43 | lcl|si2.2.0_00906336 44 | lcl|si2.2.0_00930128 45 | lcl|si2.2.0_00941256 46 | lcl|si2.2.0_00968431 47 | lcl|si2.2.0_01040462 48 | lcl|si2.2.0_01046116 49 | lcl|si2.2.0_01063373 50 | lcl|si2.2.0_01070101 51 | lcl|si2.2.0_01152371 52 | lcl|si2.2.0_01178203 53 | lcl|si2.2.0_01180414 54 | lcl|si2.2.0_0118940 55 | lcl|si2.2.0_01200291 56 | lcl|si2.2.0_01297333 57 | lcl|si2.2.0_01299199 58 | lcl|si2.2.0_01349436 59 | lcl|si2.2.0_01416348 60 | lcl|si2.2.0_01499107 61 | lcl|si2.2.0_01549384 62 | lcl|si2.2.0_01590228 63 | lcl|si2.2.0_01592249 64 | lcl|si2.2.0_01603440 65 | lcl|si2.2.0_01639130 66 | lcl|si2.2.0_01678437 67 | lcl|si2.2.0_0180190 68 | lcl|si2.2.0_01803183 69 | lcl|si2.2.0_01824111 70 | lcl|si2.2.0_0186055 71 | lcl|si2.2.0_0186352 72 | lcl|si2.2.0_01901197 73 | lcl|si2.2.0_02019389 74 | lcl|si2.2.0_020539 75 | lcl|si2.2.0_02067218 76 | lcl|si2.2.0_0213888 77 | lcl|si2.2.0_02155447 78 | lcl|si2.2.0_02171279 79 | lcl|si2.2.0_02309398 80 | lcl|si2.2.0_02329307 81 | lcl|si2.2.0_02372355 82 | lcl|si2.2.0_02498359 83 | lcl|si2.2.0_0256539 84 | lcl|si2.2.0_02569438 85 | lcl|si2.2.0_02570413 86 | lcl|si2.2.0_02604404 87 | lcl|si2.2.0_02618407 88 | lcl|si2.2.0_02625196 89 | lcl|si2.2.0_0262797 90 | lcl|si2.2.0_0265118 91 | lcl|si2.2.0_02653141 92 | lcl|si2.2.0_0267689 93 | lcl|si2.2.0_02677147 94 | lcl|si2.2.0_02705231 95 | lcl|si2.2.0_02709174 96 | lcl|si2.2.0_02720166 97 | lcl|si2.2.0_02743313 98 | lcl|si2.2.0_0280627 99 | lcl|si2.2.0_0283510 100 | lcl|si2.2.0_02844352 101 | lcl|si2.2.0_02874263 102 | lcl|si2.2.0_0287580 103 | lcl|si2.2.0_02909408 104 | lcl|si2.2.0_02926405 105 | lcl|si2.2.0_02933142 106 | lcl|si2.2.0_02941212 107 | lcl|si2.2.0_03000250 108 | lcl|si2.2.0_03058360 109 | lcl|si2.2.0_03068386 110 | lcl|si2.2.0_03120282 111 | lcl|si2.2.0_03170470 112 | lcl|si2.2.0_0317160 113 | lcl|si2.2.0_03183362 114 | lcl|si2.2.0_03195449 115 | lcl|si2.2.0_032175 116 | lcl|si2.2.0_03294303 117 | lcl|si2.2.0_03319409 118 | lcl|si2.2.0_03338103 119 | lcl|si2.2.0_03352136 120 | lcl|si2.2.0_03357119 121 | lcl|si2.2.0_03392120 122 | lcl|si2.2.0_03412444 123 | lcl|si2.2.0_0343271 124 | lcl|si2.2.0_03440159 125 | lcl|si2.2.0_0345253 126 | lcl|si2.2.0_03509445 127 | lcl|si2.2.0_03529295 128 | lcl|si2.2.0_03608350 129 | lcl|si2.2.0_03631395 130 | lcl|si2.2.0_0363923 131 | lcl|si2.2.0_0364914 132 | lcl|si2.2.0_03658366 133 | lcl|si2.2.0_03671383 134 | lcl|si2.2.0_03683345 135 | lcl|si2.2.0_03693258 136 | lcl|si2.2.0_0374664 137 | lcl|si2.2.0_03791252 138 | lcl|si2.2.0_03801148 139 | lcl|si2.2.0_03829296 140 | lcl|si2.2.0_03842454 141 | lcl|si2.2.0_03843324 142 | lcl|si2.2.0_03849225 143 | lcl|si2.2.0_03854377 144 | lcl|si2.2.0_03876411 145 | lcl|si2.2.0_03895259 146 | lcl|si2.2.0_03921358 147 | lcl|si2.2.0_03922351 148 | lcl|si2.2.0_03948280 149 | lcl|si2.2.0_03954234 150 | lcl|si2.2.0_03956349 151 | lcl|si2.2.0_03969168 152 | lcl|si2.2.0_04057246 153 | lcl|si2.2.0_04064237 154 | lcl|si2.2.0_04077393 155 | lcl|si2.2.0_04131217 156 | lcl|si2.2.0_04169140 157 | lcl|si2.2.0_04198320 158 | lcl|si2.2.0_0428570 159 | lcl|si2.2.0_04298229 160 | lcl|si2.2.0_04313145 161 | lcl|si2.2.0_04406428 162 | lcl|si2.2.0_04432122 163 | lcl|si2.2.0_0443519 164 | lcl|si2.2.0_04483244 165 | lcl|si2.2.0_04539137 166 | lcl|si2.2.0_04550248 167 | lcl|si2.2.0_04587434 168 | lcl|si2.2.0_04614306 169 | lcl|si2.2.0_04640192 170 | lcl|si2.2.0_04699191 171 | lcl|si2.2.0_04756391 172 | lcl|si2.2.0_04757100 173 | lcl|si2.2.0_04814201 174 | lcl|si2.2.0_04854423 175 | lcl|si2.2.0_04895287 176 | lcl|si2.2.0_04910311 177 | lcl|si2.2.0_04911254 178 | lcl|si2.2.0_04970385 179 | lcl|si2.2.0_04982161 180 | lcl|si2.2.0_04990245 181 | lcl|si2.2.0_04999432 182 | lcl|si2.2.0_050006 183 | lcl|si2.2.0_05027435 184 | lcl|si2.2.0_05091453 185 | lcl|si2.2.0_05108309 186 | lcl|si2.2.0_05113304 187 | lcl|si2.2.0_05122209 188 | lcl|si2.2.0_05139276 189 | lcl|si2.2.0_05142315 190 | lcl|si2.2.0_05191467 191 | lcl|si2.2.0_05261356 192 | lcl|si2.2.0_05263265 193 | lcl|si2.2.0_05280162 194 | lcl|si2.2.0_05318328 195 | lcl|si2.2.0_05326417 196 | lcl|si2.2.0_05333465 197 | lcl|si2.2.0_0539054 198 | lcl|si2.2.0_05416124 199 | lcl|si2.2.0_0545173 200 | lcl|si2.2.0_05454357 201 | lcl|si2.2.0_05475152 202 | lcl|si2.2.0_05484207 203 | lcl|si2.2.0_0550236 204 | lcl|si2.2.0_0555620 205 | lcl|si2.2.0_05699461 206 | lcl|si2.2.0_05717425 207 | lcl|si2.2.0_0577895 208 | lcl|si2.2.0_05807108 209 | lcl|si2.2.0_05814301 210 | lcl|si2.2.0_05838326 211 | lcl|si2.2.0_05844261 212 | lcl|si2.2.0_05850332 213 | lcl|si2.2.0_05852430 214 | lcl|si2.2.0_05898190 215 | lcl|si2.2.0_05913399 216 | lcl|si2.2.0_0591825 217 | lcl|si2.2.0_05950308 218 | lcl|si2.2.0_0599850 219 | lcl|si2.2.0_06035160 220 | lcl|si2.2.0_06066236 221 | lcl|si2.2.0_06112433 222 | lcl|si2.2.0_06200421 223 | lcl|si2.2.0_06250173 224 | lcl|si2.2.0_062670 225 | lcl|si2.2.0_06268337 226 | lcl|si2.2.0_0628517 227 | lcl|si2.2.0_06304381 228 | lcl|si2.2.0_0633575 229 | lcl|si2.2.0_06399325 230 | lcl|si2.2.0_06419202 231 | lcl|si2.2.0_06430334 232 | lcl|si2.2.0_06442118 233 | lcl|si2.2.0_06444186 234 | lcl|si2.2.0_06462400 235 | lcl|si2.2.0_0647078 236 | lcl|si2.2.0_06488429 237 | lcl|si2.2.0_0650813 238 | lcl|si2.2.0_06520132 239 | lcl|si2.2.0_06553471 240 | lcl|si2.2.0_06559446 241 | lcl|si2.2.0_0657424 242 | lcl|si2.2.0_06606185 243 | lcl|si2.2.0_06674165 244 | lcl|si2.2.0_0669661 245 | lcl|si2.2.0_06703138 246 | lcl|si2.2.0_0670435 247 | lcl|si2.2.0_0675945 248 | lcl|si2.2.0_06791299 249 | lcl|si2.2.0_06832466 250 | lcl|si2.2.0_068973 251 | lcl|si2.2.0_06904210 252 | lcl|si2.2.0_06947243 253 | lcl|si2.2.0_06968208 254 | lcl|si2.2.0_07040220 255 | lcl|si2.2.0_07045442 256 | lcl|si2.2.0_0705487 257 | lcl|si2.2.0_07075255 258 | lcl|si2.2.0_07142105 259 | lcl|si2.2.0_07189273 260 | lcl|si2.2.0_07195172 261 | lcl|si2.2.0_07213151 262 | lcl|si2.2.0_07221330 263 | lcl|si2.2.0_07273439 264 | lcl|si2.2.0_07299180 265 | lcl|si2.2.0_07302314 266 | lcl|si2.2.0_07307270 267 | lcl|si2.2.0_0731962 268 | lcl|si2.2.0_07340418 269 | lcl|si2.2.0_07378262 270 | lcl|si2.2.0_0741230 271 | lcl|si2.2.0_07495341 272 | lcl|si2.2.0_07528269 273 | lcl|si2.2.0_07649372 274 | lcl|si2.2.0_07659321 275 | lcl|si2.2.0_07663427 276 | lcl|si2.2.0_0769428 277 | lcl|si2.2.0_07710353 278 | lcl|si2.2.0_07739416 279 | lcl|si2.2.0_0775221 280 | lcl|si2.2.0_07781380 281 | lcl|si2.2.0_07810460 282 | lcl|si2.2.0_07818364 283 | lcl|si2.2.0_07850157 284 | lcl|si2.2.0_07860379 285 | lcl|si2.2.0_07938283 286 | lcl|si2.2.0_07944181 287 | lcl|si2.2.0_07987271 288 | lcl|si2.2.0_08070286 289 | lcl|si2.2.0_08109170 290 | lcl|si2.2.0_08121378 291 | lcl|si2.2.0_0820496 292 | lcl|si2.2.0_08214365 293 | lcl|si2.2.0_0822243 294 | lcl|si2.2.0_08227374 295 | lcl|si2.2.0_08256472 296 | lcl|si2.2.0_08266331 297 | lcl|si2.2.0_0827432 298 | lcl|si2.2.0_08297125 299 | lcl|si2.2.0_08322443 300 | lcl|si2.2.0_08326221 301 | lcl|si2.2.0_08331388 302 | lcl|si2.2.0_0835212 303 | lcl|si2.2.0_08362456 304 | lcl|si2.2.0_08371312 305 | lcl|si2.2.0_08388369 306 | lcl|si2.2.0_08434327 307 | lcl|si2.2.0_08473216 308 | lcl|si2.2.0_08498171 309 | lcl|si2.2.0_0852057 310 | lcl|si2.2.0_08521387 311 | lcl|si2.2.0_08538329 312 | lcl|si2.2.0_0859985 313 | lcl|si2.2.0_08637289 314 | lcl|si2.2.0_08643133 315 | lcl|si2.2.0_08660187 316 | lcl|si2.2.0_08703339 317 | lcl|si2.2.0_08773264 318 | lcl|si2.2.0_08813459 319 | lcl|si2.2.0_08869123 320 | lcl|si2.2.0_0887038 321 | lcl|si2.2.0_0888692 322 | lcl|si2.2.0_08900463 323 | lcl|si2.2.0_08904204 324 | lcl|si2.2.0_08927214 325 | lcl|si2.2.0_08934272 326 | lcl|si2.2.0_08938390 327 | lcl|si2.2.0_08940149 328 | lcl|si2.2.0_08981232 329 | lcl|si2.2.0_08994134 330 | lcl|si2.2.0_09019318 331 | lcl|si2.2.0_090854 332 | lcl|si2.2.0_0917116 333 | lcl|si2.2.0_09180189 334 | lcl|si2.2.0_09288144 335 | lcl|si2.2.0_09290143 336 | lcl|si2.2.0_09298375 337 | lcl|si2.2.0_093738 338 | lcl|si2.2.0_09378127 339 | lcl|si2.2.0_09379106 340 | lcl|si2.2.0_09455415 341 | lcl|si2.2.0_0952547 342 | lcl|si2.2.0_0953042 343 | lcl|si2.2.0_09542285 344 | lcl|si2.2.0_09684302 345 | lcl|si2.2.0_0972186 346 | lcl|si2.2.0_0975972 347 | lcl|si2.2.0_0982651 348 | lcl|si2.2.0_09883310 349 | lcl|si2.2.0_09895154 350 | lcl|si2.2.0_09931266 351 | lcl|si2.2.0_09955344 352 | lcl|si2.2.0_0996046 353 | lcl|si2.2.0_09970275 354 | lcl|si2.2.0_10024457 355 | lcl|si2.2.0_10087211 356 | lcl|si2.2.0_10101305 357 | lcl|si2.2.0_10107343 358 | lcl|si2.2.0_1010948 359 | lcl|si2.2.0_10176129 360 | lcl|si2.2.0_10199420 361 | lcl|si2.2.0_10239363 362 | lcl|si2.2.0_10254169 363 | lcl|si2.2.0_10270158 364 | lcl|si2.2.0_10325110 365 | lcl|si2.2.0_1033815 366 | lcl|si2.2.0_10340227 367 | lcl|si2.2.0_1038431 368 | lcl|si2.2.0_10410316 369 | lcl|si2.2.0_10416347 370 | lcl|si2.2.0_10444198 371 | lcl|si2.2.0_1046484 372 | lcl|si2.2.0_10487178 373 | lcl|si2.2.0_10490150 374 | lcl|si2.2.0_10541179 375 | lcl|si2.2.0_10585278 376 | lcl|si2.2.0_10643109 377 | lcl|si2.2.0_1066529 378 | lcl|si2.2.0_10673219 379 | lcl|si2.2.0_10734253 380 | lcl|si2.2.0_1074181 381 | lcl|si2.2.0_10746403 382 | lcl|si2.2.0_10766293 383 | lcl|si2.2.0_1083068 384 | lcl|si2.2.0_10869451 385 | lcl|si2.2.0_1087859 386 | lcl|si2.2.0_10902392 387 | lcl|si2.2.0_10912240 388 | lcl|si2.2.0_10915184 389 | lcl|si2.2.0_10922195 390 | lcl|si2.2.0_10964450 391 | lcl|si2.2.0_10984223 392 | lcl|si2.2.0_10986139 393 | lcl|si2.2.0_10997288 394 | lcl|si2.2.0_1101577 395 | lcl|si2.2.0_11030251 396 | lcl|si2.2.0_1103434 397 | lcl|si2.2.0_11045406 398 | lcl|si2.2.0_11048135 399 | lcl|si2.2.0_11072112 400 | lcl|si2.2.0_1110469 401 | lcl|si2.2.0_11111175 402 | lcl|si2.2.0_11159102 403 | lcl|si2.2.0_11174322 404 | lcl|si2.2.0_11186176 405 | lcl|si2.2.0_1128765 406 | lcl|si2.2.0_11310215 407 | lcl|si2.2.0_11346300 408 | lcl|si2.2.0_11366394 409 | lcl|si2.2.0_11378292 410 | lcl|si2.2.0_11393458 411 | lcl|si2.2.0_11531121 412 | lcl|si2.2.0_11573177 413 | lcl|si2.2.0_11575200 414 | lcl|si2.2.0_1161274 415 | lcl|si2.2.0_11619342 416 | lcl|si2.2.0_11670281 417 | lcl|si2.2.0_11718114 418 | lcl|si2.2.0_1171926 419 | lcl|si2.2.0_11740468 420 | lcl|si2.2.0_1174533 421 | lcl|si2.2.0_1175867 422 | lcl|si2.2.0_11765368 423 | lcl|si2.2.0_11770441 424 | lcl|si2.2.0_1179279 425 | lcl|si2.2.0_11823410 426 | lcl|si2.2.0_11859153 427 | lcl|si2.2.0_11872412 428 | lcl|si2.2.0_11917164 429 | lcl|si2.2.0_11938242 430 | lcl|si2.2.0_1219444 431 | lcl|si2.2.0_12220235 432 | lcl|si2.2.0_12228464 433 | lcl|si2.2.0_12238115 434 | lcl|si2.2.0_1224766 435 | lcl|si2.2.0_12277297 436 | lcl|si2.2.0_12364193 437 | lcl|si2.2.0_12545238 438 | lcl|si2.2.0_13149274 439 | lcl|si2.2.0_1347156 440 | lcl|si2.2.0_13538146 441 | lcl|si2.2.0_137221 442 | lcl|si2.2.0_13865317 443 | lcl|si2.2.0_142667 444 | lcl|si2.2.0_1433611 445 | lcl|si2.2.0_14586370 446 | lcl|si2.2.0_14827205 447 | lcl|si2.2.0_14892397 448 | lcl|si2.2.0_14968113 449 | lcl|si2.2.0_15061335 450 | lcl|si2.2.0_15449224 451 | lcl|si2.2.0_15526298 452 | lcl|si2.2.0_15710319 453 | lcl|si2.2.0_16113346 454 | lcl|si2.2.0_1613558 455 | lcl|si2.2.0_16166268 456 | lcl|si2.2.0_16500182 457 | lcl|si2.2.0_1650582 458 | lcl|si2.2.0_16525294 459 | lcl|si2.2.0_80076247 460 | lcl|si2.2.0_8009363 461 | lcl|si2.2.0_8018193 462 | lcl|si2.2.0_8022722 463 | lcl|si2.2.0_802572 464 | lcl|si2.2.0_80276167 465 | lcl|si2.2.0_80326126 466 | lcl|si2.2.0_80420367 467 | lcl|si2.2.0_80469419 468 | lcl|si2.2.0_80483284 469 | lcl|si2.2.0_8057799 470 | lcl|si2.2.0_8062349 471 | lcl|si2.2.0_80755206 472 | lcl|si2.2.0_80772257 473 | lcl|si2.2.0_8083498 474 | si2.2.0_00025131 475 | si2.2.0_00029402 476 | si2.2.0_00040213 477 | si2.2.0_00041194 478 | si2.2.0_00109260 479 | si2.2.0_00222376 480 | si2.2.0_00225277 481 | si2.2.0_00231230 482 | si2.2.0_00233226 483 | si2.2.0_00257382 484 | si2.2.0_00262156 485 | si2.2.0_00263354 486 | si2.2.0_00272222 487 | si2.2.0_00313290 488 | si2.2.0_00336338 489 | si2.2.0_00352340 490 | si2.2.0_0039883 491 | si2.2.0_00408422 492 | si2.2.0_0041737 493 | si2.2.0_00442323 494 | si2.2.0_00476267 495 | si2.2.0_00491426 496 | si2.2.0_0051241 497 | si2.2.0_00530448 498 | si2.2.0_00539396 499 | si2.2.0_0054894 500 | si2.2.0_00556361 501 | si2.2.0_00573452 502 | si2.2.0_00688241 503 | si2.2.0_00726163 504 | si2.2.0_00735424 505 | si2.2.0_00757233 506 | si2.2.0_00758469 507 | si2.2.0_0076791 508 | si2.2.0_00796104 509 | si2.2.0_0080276 510 | si2.2.0_00815455 511 | si2.2.0_00838401 512 | si2.2.0_00846117 513 | si2.2.0_00856188 514 | si2.2.0_00883239 515 | si2.2.0_00895155 516 | si2.2.0_00906336 517 | si2.2.0_00930128 518 | si2.2.0_00941256 519 | si2.2.0_00968431 520 | si2.2.0_01040462 521 | si2.2.0_01046116 522 | si2.2.0_01063373 523 | si2.2.0_01070101 524 | si2.2.0_01152371 525 | si2.2.0_01178203 526 | si2.2.0_01180414 527 | si2.2.0_0118940 528 | si2.2.0_01200291 529 | si2.2.0_01297333 530 | si2.2.0_01299199 531 | si2.2.0_01349436 532 | si2.2.0_01416348 533 | si2.2.0_01499107 534 | si2.2.0_01549384 535 | si2.2.0_01590228 536 | si2.2.0_01592249 537 | si2.2.0_01603440 538 | si2.2.0_01639130 539 | si2.2.0_01678437 540 | si2.2.0_0180190 541 | si2.2.0_01803183 542 | si2.2.0_01824111 543 | si2.2.0_0186055 544 | si2.2.0_0186352 545 | si2.2.0_01901197 546 | si2.2.0_02019389 547 | si2.2.0_020539 548 | si2.2.0_02067218 549 | si2.2.0_0213888 550 | si2.2.0_02155447 551 | si2.2.0_02171279 552 | si2.2.0_02309398 553 | si2.2.0_02329307 554 | si2.2.0_02372355 555 | si2.2.0_02498359 556 | si2.2.0_0256539 557 | si2.2.0_02569438 558 | si2.2.0_02570413 559 | si2.2.0_02604404 560 | si2.2.0_02618407 561 | si2.2.0_02625196 562 | si2.2.0_0262797 563 | si2.2.0_0265118 564 | si2.2.0_02653141 565 | si2.2.0_0267689 566 | si2.2.0_02677147 567 | si2.2.0_02705231 568 | si2.2.0_02709174 569 | si2.2.0_02720166 570 | si2.2.0_02743313 571 | si2.2.0_0280627 572 | si2.2.0_0283510 573 | si2.2.0_02844352 574 | si2.2.0_02874263 575 | si2.2.0_0287580 576 | si2.2.0_02909408 577 | si2.2.0_02926405 578 | si2.2.0_02933142 579 | si2.2.0_02941212 580 | si2.2.0_03000250 581 | si2.2.0_03058360 582 | si2.2.0_03068386 583 | si2.2.0_03120282 584 | si2.2.0_03170470 585 | si2.2.0_0317160 586 | si2.2.0_03183362 587 | si2.2.0_03195449 588 | si2.2.0_032175 589 | si2.2.0_03294303 590 | si2.2.0_03319409 591 | si2.2.0_03338103 592 | si2.2.0_03352136 593 | si2.2.0_03357119 594 | si2.2.0_03392120 595 | si2.2.0_03412444 596 | si2.2.0_0343271 597 | si2.2.0_03440159 598 | si2.2.0_0345253 599 | si2.2.0_03509445 600 | si2.2.0_03529295 601 | si2.2.0_03608350 602 | si2.2.0_03631395 603 | si2.2.0_0363923 604 | si2.2.0_0364914 605 | si2.2.0_03658366 606 | si2.2.0_03671383 607 | si2.2.0_03683345 608 | si2.2.0_03693258 609 | si2.2.0_0374664 610 | si2.2.0_03791252 611 | si2.2.0_03801148 612 | si2.2.0_03829296 613 | si2.2.0_03842454 614 | si2.2.0_03843324 615 | si2.2.0_03849225 616 | si2.2.0_03854377 617 | si2.2.0_03876411 618 | si2.2.0_03895259 619 | si2.2.0_03921358 620 | si2.2.0_03922351 621 | si2.2.0_03948280 622 | si2.2.0_03954234 623 | si2.2.0_03956349 624 | si2.2.0_03969168 625 | si2.2.0_04057246 626 | si2.2.0_04064237 627 | si2.2.0_04077393 628 | si2.2.0_04131217 629 | si2.2.0_04169140 630 | si2.2.0_04198320 631 | si2.2.0_0428570 632 | si2.2.0_04298229 633 | si2.2.0_04313145 634 | si2.2.0_04406428 635 | si2.2.0_04432122 636 | si2.2.0_0443519 637 | si2.2.0_04483244 638 | si2.2.0_04539137 639 | si2.2.0_04550248 640 | si2.2.0_04587434 641 | si2.2.0_04614306 642 | si2.2.0_04640192 643 | si2.2.0_04699191 644 | si2.2.0_04756391 645 | si2.2.0_04757100 646 | si2.2.0_04814201 647 | si2.2.0_04854423 648 | si2.2.0_04895287 649 | si2.2.0_04910311 650 | si2.2.0_04911254 651 | si2.2.0_04970385 652 | si2.2.0_04982161 653 | si2.2.0_04990245 654 | si2.2.0_04999432 655 | si2.2.0_050006 656 | si2.2.0_05027435 657 | si2.2.0_05091453 658 | si2.2.0_05108309 659 | si2.2.0_05113304 660 | si2.2.0_05122209 661 | si2.2.0_05139276 662 | si2.2.0_05142315 663 | si2.2.0_05191467 664 | si2.2.0_05261356 665 | si2.2.0_05263265 666 | si2.2.0_05280162 667 | si2.2.0_05318328 668 | si2.2.0_05326417 669 | si2.2.0_05333465 670 | si2.2.0_0539054 671 | si2.2.0_05416124 672 | si2.2.0_0545173 673 | si2.2.0_05454357 674 | si2.2.0_05475152 675 | si2.2.0_05484207 676 | si2.2.0_0550236 677 | si2.2.0_0555620 678 | si2.2.0_05699461 679 | si2.2.0_05717425 680 | si2.2.0_0577895 681 | si2.2.0_05807108 682 | si2.2.0_05814301 683 | si2.2.0_05838326 684 | si2.2.0_05844261 685 | si2.2.0_05850332 686 | si2.2.0_05852430 687 | si2.2.0_05898190 688 | si2.2.0_05913399 689 | si2.2.0_0591825 690 | si2.2.0_05950308 691 | si2.2.0_0599850 692 | si2.2.0_06035160 693 | si2.2.0_06066236 694 | si2.2.0_06112433 695 | si2.2.0_06200421 696 | si2.2.0_06250173 697 | si2.2.0_062670 698 | si2.2.0_06268337 699 | si2.2.0_0628517 700 | si2.2.0_06304381 701 | si2.2.0_0633575 702 | si2.2.0_06399325 703 | si2.2.0_06419202 704 | si2.2.0_06430334 705 | si2.2.0_06442118 706 | si2.2.0_06444186 707 | si2.2.0_06462400 708 | si2.2.0_0647078 709 | si2.2.0_06488429 710 | si2.2.0_0650813 711 | si2.2.0_06520132 712 | si2.2.0_06553471 713 | si2.2.0_06559446 714 | si2.2.0_0657424 715 | si2.2.0_06606185 716 | si2.2.0_06674165 717 | si2.2.0_0669661 718 | si2.2.0_06703138 719 | si2.2.0_0670435 720 | si2.2.0_0675945 721 | si2.2.0_06791299 722 | si2.2.0_06832466 723 | si2.2.0_068973 724 | si2.2.0_06904210 725 | si2.2.0_06947243 726 | si2.2.0_06968208 727 | si2.2.0_07040220 728 | si2.2.0_07045442 729 | si2.2.0_0705487 730 | si2.2.0_07075255 731 | si2.2.0_07142105 732 | si2.2.0_07189273 733 | si2.2.0_07195172 734 | si2.2.0_07213151 735 | si2.2.0_07221330 736 | si2.2.0_07273439 737 | si2.2.0_07299180 738 | si2.2.0_07302314 739 | si2.2.0_07307270 740 | si2.2.0_0731962 741 | si2.2.0_07340418 742 | si2.2.0_07378262 743 | si2.2.0_0741230 744 | si2.2.0_07495341 745 | si2.2.0_07528269 746 | si2.2.0_07649372 747 | si2.2.0_07659321 748 | si2.2.0_07663427 749 | si2.2.0_0769428 750 | si2.2.0_07710353 751 | si2.2.0_07739416 752 | si2.2.0_0775221 753 | si2.2.0_07781380 754 | si2.2.0_07810460 755 | si2.2.0_07818364 756 | si2.2.0_07850157 757 | si2.2.0_07860379 758 | si2.2.0_07938283 759 | si2.2.0_07944181 760 | si2.2.0_07987271 761 | si2.2.0_08070286 762 | si2.2.0_08109170 763 | si2.2.0_08121378 764 | si2.2.0_0820496 765 | si2.2.0_08214365 766 | si2.2.0_0822243 767 | si2.2.0_08227374 768 | si2.2.0_08256472 769 | si2.2.0_08266331 770 | si2.2.0_0827432 771 | si2.2.0_08297125 772 | si2.2.0_08322443 773 | si2.2.0_08326221 774 | si2.2.0_08331388 775 | si2.2.0_0835212 776 | si2.2.0_08362456 777 | si2.2.0_08371312 778 | si2.2.0_08388369 779 | si2.2.0_08434327 780 | si2.2.0_08473216 781 | si2.2.0_08498171 782 | si2.2.0_0852057 783 | si2.2.0_08521387 784 | si2.2.0_08538329 785 | si2.2.0_0859985 786 | si2.2.0_08637289 787 | si2.2.0_08643133 788 | si2.2.0_08660187 789 | si2.2.0_08703339 790 | si2.2.0_08773264 791 | si2.2.0_08813459 792 | si2.2.0_08869123 793 | si2.2.0_0887038 794 | si2.2.0_0888692 795 | si2.2.0_08900463 796 | si2.2.0_08904204 797 | si2.2.0_08927214 798 | si2.2.0_08934272 799 | si2.2.0_08938390 800 | si2.2.0_08940149 801 | si2.2.0_08981232 802 | si2.2.0_08994134 803 | si2.2.0_09019318 804 | si2.2.0_090854 805 | si2.2.0_0917116 806 | si2.2.0_09180189 807 | si2.2.0_09288144 808 | si2.2.0_09290143 809 | si2.2.0_09298375 810 | si2.2.0_093738 811 | si2.2.0_09378127 812 | si2.2.0_09379106 813 | si2.2.0_09455415 814 | si2.2.0_0952547 815 | si2.2.0_0953042 816 | si2.2.0_09542285 817 | si2.2.0_09684302 818 | si2.2.0_0972186 819 | si2.2.0_0975972 820 | si2.2.0_0982651 821 | si2.2.0_09883310 822 | si2.2.0_09895154 823 | si2.2.0_09931266 824 | si2.2.0_09955344 825 | si2.2.0_0996046 826 | si2.2.0_09970275 827 | si2.2.0_10024457 828 | si2.2.0_10087211 829 | si2.2.0_10101305 830 | si2.2.0_10107343 831 | si2.2.0_1010948 832 | si2.2.0_10176129 833 | si2.2.0_10199420 834 | si2.2.0_10239363 835 | si2.2.0_10254169 836 | si2.2.0_10270158 837 | si2.2.0_10325110 838 | si2.2.0_1033815 839 | si2.2.0_10340227 840 | si2.2.0_1038431 841 | si2.2.0_10410316 842 | si2.2.0_10416347 843 | si2.2.0_10444198 844 | si2.2.0_1046484 845 | si2.2.0_10487178 846 | si2.2.0_10490150 847 | si2.2.0_10541179 848 | si2.2.0_10585278 849 | si2.2.0_10643109 850 | si2.2.0_1066529 851 | si2.2.0_10673219 852 | si2.2.0_10734253 853 | si2.2.0_1074181 854 | si2.2.0_10746403 855 | si2.2.0_10766293 856 | si2.2.0_1083068 857 | si2.2.0_10869451 858 | si2.2.0_1087859 859 | si2.2.0_10902392 860 | si2.2.0_10912240 861 | si2.2.0_10915184 862 | si2.2.0_10922195 863 | si2.2.0_10964450 864 | si2.2.0_10984223 865 | si2.2.0_10986139 866 | si2.2.0_10997288 867 | si2.2.0_1101577 868 | si2.2.0_11030251 869 | si2.2.0_1103434 870 | si2.2.0_11045406 871 | si2.2.0_11048135 872 | si2.2.0_11072112 873 | si2.2.0_1110469 874 | si2.2.0_11111175 875 | si2.2.0_11159102 876 | si2.2.0_11174322 877 | si2.2.0_11186176 878 | si2.2.0_1128765 879 | si2.2.0_11310215 880 | si2.2.0_11346300 881 | si2.2.0_11366394 882 | si2.2.0_11378292 883 | si2.2.0_11393458 884 | si2.2.0_11531121 885 | si2.2.0_11573177 886 | si2.2.0_11575200 887 | si2.2.0_1161274 888 | si2.2.0_11619342 889 | si2.2.0_11670281 890 | si2.2.0_11718114 891 | si2.2.0_1171926 892 | si2.2.0_11740468 893 | si2.2.0_1174533 894 | si2.2.0_1175867 895 | si2.2.0_11765368 896 | si2.2.0_11770441 897 | si2.2.0_1179279 898 | si2.2.0_11823410 899 | si2.2.0_11859153 900 | si2.2.0_11872412 901 | si2.2.0_11917164 902 | si2.2.0_11938242 903 | si2.2.0_1219444 904 | si2.2.0_12220235 905 | si2.2.0_12228464 906 | si2.2.0_12238115 907 | si2.2.0_1224766 908 | si2.2.0_12277297 909 | si2.2.0_12364193 910 | si2.2.0_12545238 911 | si2.2.0_13149274 912 | si2.2.0_1347156 913 | si2.2.0_13538146 914 | si2.2.0_137221 915 | si2.2.0_13865317 916 | si2.2.0_142667 917 | si2.2.0_1433611 918 | si2.2.0_14586370 919 | si2.2.0_14827205 920 | si2.2.0_14892397 921 | si2.2.0_14968113 922 | si2.2.0_15061335 923 | si2.2.0_15449224 924 | si2.2.0_15526298 925 | si2.2.0_15710319 926 | si2.2.0_16113346 927 | si2.2.0_1613558 928 | si2.2.0_16166268 929 | si2.2.0_16500182 930 | si2.2.0_1650582 931 | si2.2.0_16525294 932 | si2.2.0_80076247 933 | si2.2.0_8009363 934 | si2.2.0_8018193 935 | si2.2.0_8022722 936 | si2.2.0_802572 937 | si2.2.0_80276167 938 | si2.2.0_80326126 939 | si2.2.0_80420367 940 | si2.2.0_80469419 941 | si2.2.0_80483284 942 | si2.2.0_8057799 943 | si2.2.0_8062349 944 | si2.2.0_80755206 945 | si2.2.0_80772257 946 | si2.2.0_8083498 947 | -------------------------------------------------------------------------------- /public/src/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.1.1 (http://getbootstrap.com) 3 | * Copyright 2011-2014 Twitter, Inc. 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.isLoading=!1};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",f.resetText||d.data("resetText",d[e]()),d[e](f[b]||this.options[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},b.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});return this.$element.trigger(j),j.isDefaultPrevented()?void 0:(this.sliding=!0,f&&this.pause(),this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid.bs.carousel",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid.bs.carousel")},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid.bs.carousel")),f&&this.cycle(),this)};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("collapse in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);!e&&f.toggle&&"show"==c&&(c=!c),e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(jQuery),+function(a){"use strict";function b(b){a(d).remove(),a(e).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(''}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(a(c).is("body")?window:c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);{var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})}},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);if(g&&b<=e[0])return g!=(a=f[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parentsUntil(this.options.target,".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(b.RESET).addClass("affix");var a=this.$window.scrollTop(),c=this.$element.offset();return this.pinnedOffset=c.top-a},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"top"==this.affixed&&(e.top+=d),"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top(this.$element)),"function"==typeof h&&(h=f.bottom(this.$element));var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;if(this.affixed!==i){this.unpin&&this.$element.css("top","");var j="affix"+(i?"-"+i:""),k=a.Event(j+".bs.affix");this.$element.trigger(k),k.isDefaultPrevented()||(this.affixed=i,this.unpin="bottom"==i?this.getPinnedOffset():null,this.$element.removeClass(b.RESET).addClass(j).trigger(a.Event(j.replace("affix","affixed"))),"bottom"==i&&this.$element.offset({top:c-h-this.$element.height()}))}}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(jQuery); -------------------------------------------------------------------------------- /public/src/js/jquery.tablesorter.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * TableSorter 2.17.7 min - Client-side table sorting with ease! 3 | * Copyright (c) 2007 Christian Bach 4 | */ 5 | !function(h){h.extend({tablesorter:new function(){function d(){var a=arguments[0],b=1':"";p.$headers=h(a).find(p.selectorHeaders).each(function(k){c=h(this);b=f.getColumnData(a,p.headers,k,!0);p.headerContent[k]=h(this).html();l=p.headerTemplate.replace(/\{content\}/g,h(this).html()).replace(/\{icon\}/g,e);p.onRenderTemplate&&(g=p.onRenderTemplate.apply(c, [k,l]))&&"string"===typeof g&&(l=g);h(this).html('
'+l+"
");p.onRenderHeader&&p.onRenderHeader.apply(c,[k]);this.column=parseInt(h(this).attr("data-column"),10);this.order=D(f.getData(c,b,"sortInitialOrder")||p.sortInitialOrder)?[1,0,2]:[0,1,2];this.count=-1;this.lockedOrder=!1;x=f.getData(c,b,"lockedOrder")||!1;"undefined"!==typeof x&&!1!==x&&(this.order=this.lockedOrder=D(x)?[1,1,1]:[0,0,0]);c.addClass(f.css.header+" "+p.cssHeader);p.headerList[k]=this;c.parent().addClass(f.css.headerRow+ " "+p.cssHeaderRow).attr("role","row");p.tabIndex&&c.attr("tabindex",0)}).attr({scope:"col",role:"columnheader"});C(a);p.debug&&(q("Built headers:",k),d(p.$headers))}function F(a,b,c){var g=a.config;g.$table.find(g.selectorRemove).remove();v(a);w(a);I(g.$table,b,c)}function C(a){var b,c,g,e=a.config;e.$headers.each(function(l,d){c=h(d);g=f.getColumnData(a,e.headers,l,!0);b="false"===f.getData(d,g,"sorter")||"false"===f.getData(d,g,"parser");d.sortDisabled=b;c[b?"addClass":"removeClass"]("sorter-false").attr("aria-disabled", ""+b);a.id&&(b?c.removeAttr("aria-controls"):c.attr("aria-controls",a.id))})}function G(a){var b,c,g=a.config,e=g.sortList,l=e.length,d=f.css.sortNone+" "+g.cssNone,k=[f.css.sortAsc+" "+g.cssAsc,f.css.sortDesc+" "+g.cssDesc],p=["ascending","descending"],m=h(a).find("tfoot tr").children().add(g.$extraHeaders).removeClass(k.join(" "));g.$headers.removeClass(k.join(" ")).addClass(d).attr("aria-sort","none");for(b=0;b"),c=h(a).width();h(a.tBodies[0]).find("tr:first").children(":visible").each(function(){b.append(h("").css("width",parseInt(h(this).width()/c*1E3,10)/10+"%"))});h(a).prepend(b)}}function P(a,b){var c,g,e,l,f,k=a.config,d=b||k.sortList;k.sortList=[];h.each(d,function(a,b){l=parseInt(b[0],10);if(e=k.$headers.filter('[data-column="'+l+'"]:last')[0]){g=(g=(""+b[1]).match(/^(1|d|s|o|n)/))? g[0]:"";switch(g){case "1":case "d":g=1;break;case "s":g=f||0;break;case "o":c=e.order[(f||0)%(k.sortReset?3:2)];g=0===c?1:1===c?0:2;break;case "n":e.count+=1;g=e.order[e.count%(k.sortReset?3:2)];break;default:g=0}f=0===a?g:f;c=[l,parseInt(g,10)||0];k.sortList.push(c);g=h.inArray(c[1],e.order);e.count=0<=g?g:c[1]%(k.sortReset?3:2)}})}function Q(a,b){return a&&a[b]?a[b].type||"":""}function L(a,b,c){if(a.isUpdating)return setTimeout(function(){L(a,b,c)},50);var g,e,l,d,k=a.config,p=!c[k.sortMultiSortKey], m=k.$table;m.trigger("sortStart",a);b.count=c[k.sortResetKey]?2:(b.count+1)%(k.sortReset?3:2);k.sortRestart&&(e=b,k.$headers.each(function(){this===e||!p&&h(this).is("."+f.css.sortDesc+",."+f.css.sortAsc)||(this.count=-1)}));e=b.column;if(p){k.sortList=[];if(null!==k.sortForce)for(g=k.sortForce,l=0;lg&&(k.sortList.push([e,g]),1g&&(k.sortList.push([e,g]),1 thead th, > thead td",selectorSort:"th, td",selectorRemove:".remove-me", debug:!1,headerList:[],empties:{},strings:{},parsers:[]};f.css={table:"tablesorter",cssHasChild:"tablesorter-hasChildRow",childRow:"tablesorter-childRow",header:"tablesorter-header",headerRow:"tablesorter-headerRow",headerIn:"tablesorter-header-inner",icon:"tablesorter-icon",info:"tablesorter-infoOnly",processing:"tablesorter-processing",sortAsc:"tablesorter-headerAsc",sortDesc:"tablesorter-headerDesc",sortNone:"tablesorter-headerUnSorted"};f.language={sortAsc:"Ascending sort applied, ",sortDesc:"Descending sort applied, ", sortNone:"No sort applied, ",nextAsc:"activate to apply an ascending sort",nextDesc:"activate to apply a descending sort",nextNone:"activate to remove the sort"};f.log=d;f.benchmark=q;f.construct=function(a){return this.each(function(){var b=h.extend(!0,{},f.defaults,a);b.originalSettings=a;!this.hasInitialized&&f.buildTable&&"TABLE"!==this.tagName?f.buildTable(this,b):f.setup(this,b)})};f.setup=function(a,b){if(!a||!a.tHead||0===a.tBodies.length||!0===a.hasInitialized)return b.debug?d("ERROR: stopping initialization! No table, thead, tbody or tablesorter has already been initialized"): "";var c="",g=h(a),e=h.metadata;a.hasInitialized=!1;a.isProcessing=!0;a.config=b;h.data(a,"tablesorter",b);b.debug&&h.data(a,"startoveralltimer",new Date);b.supportsDataObject=function(a){a[0]=parseInt(a[0],10);return 1'),c=h.fn.detach?b.detach():b.remove();c=h(a).find("span.tablesorter-savemyplace");b.insertAfter(c);c.remove();a.isProcessing=!1};f.clearTableBody=function(a){h(a)[0].config.$tbodies.children().detach()};f.bindEvents=function(a,b,c){a=h(a)[0];var g,e=a.config;!0!==c&&(e.$extraHeaders=e.$extraHeaders?e.$extraHeaders.add(b):b);b.find(e.selectorSort).add(b.filter(e.selectorSort)).unbind(["mousedown","mouseup", "sort","keyup",""].join(e.namespace+" ")).bind(["mousedown","mouseup","sort","keyup",""].join(e.namespace+" "),function(c,d){var f;f=c.type;if(!(1!==(c.which||c.button)&&!/sort|keyup/.test(f)||"keyup"===f&&13!==c.which||"mouseup"===f&&!0!==d&&250<(new Date).getTime()-g)){if("mousedown"===f)return g=(new Date).getTime(),/(input|select|button|textarea)/i.test(c.target.tagName)?"":!e.cancelSelection;e.delayInit&&n(e.cache)&&w(a);f=h.fn.closest?h(this).closest("th, td")[0]:/TH|TD/.test(this.tagName)? this:h(this).parents("th, td")[0];f=e.$headers[b.index(f)];f.sortDisabled||L(a,f,c)}});e.cancelSelection&&b.attr("unselectable","on").bind("selectstart",!1).css({"user-select":"none",MozUserSelect:"none"})};f.restoreHeaders=function(a){var b=h(a)[0].config;b.$table.find(b.selectorHeaders).each(function(a){h(this).find("."+f.css.headerIn).length&&h(this).html(b.headerContent[a])})};f.destroy=function(a,b,c){a=h(a)[0];if(a.hasInitialized){f.refreshWidgets(a,!0,!0);var g=h(a),e=a.config,d=g.find("thead:first"), q=d.find("tr."+f.css.headerRow).removeClass(f.css.headerRow+" "+e.cssHeaderRow),k=g.find("tfoot:first > tr").children("th, td");!1===b&&0<=h.inArray("uitheme",e.widgets)&&(g.trigger("applyWidgetId",["uitheme"]),g.trigger("applyWidgetId",["zebra"]));d.find("tr").not(q).remove();g.removeData("tablesorter").unbind("sortReset update updateAll updateRows updateCell addRows updateComplete sorton appendCache updateCache applyWidgetId applyWidgets refreshWidgets destroy mouseup mouseleave keypress sortBegin sortEnd resetToLoadState ".split(" ").join(e.namespace+ " "));e.$headers.add(k).removeClass([f.css.header,e.cssHeader,e.cssAsc,e.cssDesc,f.css.sortAsc,f.css.sortDesc,f.css.sortNone].join(" ")).removeAttr("data-column").removeAttr("aria-label").attr("aria-disabled","true");q.find(e.selectorSort).unbind(["mousedown","mouseup","keypress",""].join(e.namespace+" "));f.restoreHeaders(a);g.toggleClass(f.css.table+" "+e.tableClass+" tablesorter-"+e.theme,!1===b);a.hasInitialized=!1;delete a.config.cache;"function"===typeof c&&c(a)}};f.regex={chunk:/(^([+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?)?$|^0x[0-9a-f]+$|\d+)/gi, chunks:/(^\\0|\\0$)/,hex:/^0x[0-9a-f]+$/i};f.sortNatural=function(a,b){if(a===b)return 0;var c,g,e,d,h,k;g=f.regex;if(g.hex.test(b)){c=parseInt(a.match(g.hex),16);e=parseInt(b.match(g.hex),16);if(ce)return 1}c=a.replace(g.chunk,"\\0$1\\0").replace(g.chunks,"").split("\\0");g=b.replace(g.chunk,"\\0$1\\0").replace(g.chunks,"").split("\\0");k=Math.max(c.length,g.length);for(h=0;hd)return 1}return 0};f.sortNaturalAsc=function(a,b,c,g,e){if(a===b)return 0;c=e.string[e.empties[c]||e.emptyTo];return""===a&&0!==c?"boolean"===typeof c?c?-1:1:-c||-1:""===b&&0!==c?"boolean"===typeof c?c?1:-1:c||1:f.sortNatural(a,b)};f.sortNaturalDesc=function(a,b,c,g,e){if(a===b)return 0;c=e.string[e.empties[c]||e.emptyTo];return""===a&&0!==c?"boolean"===typeof c?c?-1:1:c||1:""===b&&0!==c?"boolean"===typeof c?c? 1:-1:-c||-1:f.sortNatural(b,a)};f.sortText=function(a,b){return a>b?1:ah.inArray(q[g].id,l))&&(e.debug&&d('Refeshing widgets: Removing "'+q[g].id+'"'),q[g].hasOwnProperty("remove")&&e.widgetInit[q[g].id]&&(q[g].remove(a, e,e.widgetOptions),e.widgetInit[q[g].id]=!1));!0!==c&&f.applyWidget(a,b)};f.getData=function(a,b,c){var d="";a=h(a);var e,f;if(!a.length)return"";e=h.metadata?a.metadata():!1;f=" "+(a.attr("class")||"");"undefined"!==typeof a.data(c)||"undefined"!==typeof a.data(c.toLowerCase())?d+=a.data(c)||a.data(c.toLowerCase()):e&&"undefined"!==typeof e[c]?d+=e[c]:b&&"undefined"!==typeof b[c]?d+=b[c]:" "!==f&&f.match(" "+c+"-")&&(d=f.match(new RegExp("\\s"+c+"-([\\w-]+)"))[1]||"");return h.trim(d)};f.formatFloat= function(a,b){if("string"!==typeof a||""===a)return a;var c;a=(b&&b.config?!1!==b.config.usNumberFormat:"undefined"!==typeof b?b:1)?a.replace(/,/g,""):a.replace(/[\s|\.]/g,"").replace(/,/g,".");/^\s*\([.\d]+\)/.test(a)&&(a=a.replace(/^\s*\(([.\d]+)\)/,"-$1"));c=parseFloat(a);return isNaN(c)?h.trim(a):c};f.isDigit=function(a){return isNaN(a)?/^[\-+(]?\d+[)]?$/.test(a.toString().replace(/[,.'"\s]/g,"")):!0}}});var r=h.tablesorter;h.fn.extend({tablesorter:r.construct});r.addParser({id:"no-parser",is:function(){return!1}, format:function(){return""},type:"text"});r.addParser({id:"text",is:function(){return!0},format:function(d,q){var n=q.config;d&&(d=h.trim(n.ignoreCase?d.toLocaleLowerCase():d),d=n.sortLocaleCompare?r.replaceAccents(d):d);return d},type:"text"});r.addParser({id:"digit",is:function(d){return r.isDigit(d)},format:function(d,q){var n=r.formatFloat((d||"").replace(/[^\w,. \-()]/g,""),q);return d&&"number"===typeof n?n:d?h.trim(d&&q.config.ignoreCase?d.toLocaleLowerCase():d):d},type:"numeric"});r.addParser({id:"currency", is:function(d){return/^\(?\d+[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]|[\u00a3$\u20ac\u00a4\u00a5\u00a2?.]\d+\)?$/.test((d||"").replace(/[+\-,. ]/g,""))},format:function(d,q){var n=r.formatFloat((d||"").replace(/[^\w,. \-()]/g,""),q);return d&&"number"===typeof n?n:d?h.trim(d&&q.config.ignoreCase?d.toLocaleLowerCase():d):d},type:"numeric"});r.addParser({id:"ipAddress",is:function(d){return/^\d{1,3}[\.]\d{1,3}[\.]\d{1,3}[\.]\d{1,3}$/.test(d)},format:function(d,h){var n,y=d?d.split("."):"",v="",w=y.length; for(n=0;nd.length},format:function(d,h){return d?r.formatFloat(d.replace(/%/g,""),h):d},type:"numeric"});r.addParser({id:"usLongDate",is:function(d){return/^[A-Z]{3,10}\.?\s+\d{1,2},?\s+(\d{4})(\s+\d{1,2}:\d{2}(:\d{2})?(\s+[AP]M)?)?$/i.test(d)||/^\d{1,2}\s+[A-Z]{3,10}\s+\d{4}/i.test(d)},format:function(d,h){return d?r.formatFloat((new Date(d.replace(/(\S)([AP]M)$/i,"$1 $2"))).getTime()||d,h):d},type:"numeric"});r.addParser({id:"shortDate",is:function(d){return/(^\d{1,2}[\/\s]\d{1,2}[\/\s]\d{4})|(^\d{4}[\/\s]\d{1,2}[\/\s]\d{1,2})/.test((d|| "").replace(/\s+/g," ").replace(/[\-.,]/g,"/"))},format:function(d,h,n,y){if(d){n=h.config;var v=n.$headers.filter("[data-column="+y+"]:last");y=v.length&&v[0].dateFormat||r.getData(v,r.getColumnData(h,n.headers,y),"dateFormat")||n.dateFormat;d=d.replace(/\s+/g," ").replace(/[\-.,]/g,"/");"mmddyyyy"===y?d=d.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$1/$2"):"ddmmyyyy"===y?d=d.replace(/(\d{1,2})[\/\s](\d{1,2})[\/\s](\d{4})/,"$3/$2/$1"):"yyyymmdd"===y&&(d=d.replace(/(\d{4})[\/\s](\d{1,2})[\/\s](\d{1,2})/, "$1/$2/$3"))}return d?r.formatFloat((new Date(d)).getTime()||d,h):d},type:"numeric"});r.addParser({id:"time",is:function(d){return/^(([0-2]?\d:[0-5]\d)|([0-1]?\d:[0-5]\d\s?([AP]M)))$/i.test(d)},format:function(d,h){return d?r.formatFloat((new Date("2000/01/01 "+d.replace(/(\S)([AP]M)$/i,"$1 $2"))).getTime()||d,h):d},type:"numeric"});r.addParser({id:"metadata",is:function(){return!1},format:function(d,q,n){d=q.config;d=d.parserMetadataName?d.parserMetadataName:"sortValue";return h(n).metadata()[d]}, type:"numeric"});r.addWidget({id:"zebra",priority:90,format:function(d,q,n){var y,v,w,z,D,E,F=new RegExp(q.cssChildRow,"i"),C=q.$tbodies;q.debug&&(D=new Date);for(d=0;d