summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormr <mr@mrautenberg.de>2010-12-06 12:19:49 +0100
committermr <mr@mrautenberg.de>2010-12-06 12:19:49 +0100
commitf5e96aba9ebf6c97d2f17f79571faf25c201b95f (patch)
treeb15d415ea97a586de3a7a00d5e8590e90e7de7f6
parent04c0b50d08292f2754e1d2a6ac00a644f251f593 (diff)
parent1bcac85620afbccae1164a9a880a2290e360aa62 (diff)
merge with helma/development
-rw-r--r--application.rb354
-rw-r--r--config.ru5
-rw-r--r--helper.rb50
-rw-r--r--model.rb186
-rw-r--r--public/JME.classbin0 -> 26321 bytes
-rw-r--r--public/JME.jarbin0 -> 38760 bytes
-rw-r--r--public/ToxCreate_rgb_72.pngbin0 -> 5978 bytes
-rw-r--r--public/favicon.icobin0 -> 1406 bytes
-rw-r--r--public/hamster_carcinogenicity.csv85
-rw-r--r--public/hamster_carcinogenicity.xlsbin0 -> 57856 bytes
-rwxr-xr-xpublic/javascripts/jquery.js154
-rwxr-xr-xpublic/javascripts/toxcreate.js121
-rw-r--r--public/jme-200606.jarbin0 -> 37255 bytes
-rw-r--r--public/jme.js11
-rw-r--r--public/jme_help.html195
-rw-r--r--public/robots.txt2
-rw-r--r--public/snake_transparent.gifbin0 -> 2209 bytes
-rw-r--r--views/classification.haml11
-rw-r--r--views/classification_validation.haml33
-rw-r--r--views/compound_image.haml2
-rw-r--r--views/confidence.haml7
-rw-r--r--views/create.haml41
-rw-r--r--views/endpoint.haml12
-rw-r--r--views/feature_table.haml28
-rw-r--r--views/fragment.haml9
-rw-r--r--views/help.haml104
-rw-r--r--views/js_link.haml5
-rw-r--r--views/layout.haml43
-rw-r--r--views/lazar.haml58
-rw-r--r--views/lazar_algorithm.haml50
-rw-r--r--views/lazar_description.haml29
-rw-r--r--views/model.haml67
-rw-r--r--views/model_status.haml2
-rw-r--r--views/models.haml21
-rw-r--r--views/neighbors.haml44
-rw-r--r--views/neighbors_navigation.haml22
-rw-r--r--views/predict.haml34
-rw-r--r--views/prediction.haml50
-rw-r--r--views/regression.haml11
-rw-r--r--views/regression_validation.haml9
-rw-r--r--views/significant_fragments.haml10
-rw-r--r--views/similarity.haml19
-rw-r--r--views/style.sass239
-rw-r--r--views/training_data.haml7
-rw-r--r--views/unit.haml10
-rw-r--r--views/validation.haml23
46 files changed, 2163 insertions, 0 deletions
diff --git a/application.rb b/application.rb
new file mode 100644
index 0000000..fe9b8b4
--- /dev/null
+++ b/application.rb
@@ -0,0 +1,354 @@
+['rubygems', "haml", "sass", "rack-flash"].each do |lib|
+ require lib
+end
+gem "opentox-ruby", "~> 0"
+require 'opentox-ruby'
+gem 'sinatra-static-assets'
+require 'sinatra/static_assets'
+require 'ftools'
+require File.join(File.dirname(__FILE__),'model.rb')
+require File.join(File.dirname(__FILE__),'helper.rb')
+#require File.join(File.dirname(__FILE__),'parser.rb')
+
+use Rack::Flash
+set :sessions, true
+
+helpers do
+
+ def error(message)
+ @model.error_messages = message
+ LOGGER.error message
+ @model.status = "Error"
+ @model.save
+ #@dataset.delete
+ flash[:notice] = message
+ redirect url_for('/create')
+ end
+
+end
+
+get '/?' do
+ redirect url_for('/create')
+end
+
+get '/models/?' do
+ @models = ToxCreateModel.all(:order => [ :created_at.desc ])
+ #@models.each { |model| model.process }
+ haml :models
+end
+
+get '/model/:id/status/?' do
+ response['Content-Type'] = 'text/plain'
+ model = ToxCreateModel.get(params[:id])
+ begin
+ haml :model_status, :locals=>{:model=>model}, :layout => false
+ rescue
+ return "unavailable"
+ end
+end
+
+get '/model/:id/:view/?' do
+ response['Content-Type'] = 'text/plain'
+ model = ToxCreateModel.get(params[:id])
+
+ begin
+ #model.process
+ #model.save
+ case params[:view]
+ when "model"
+ haml :model, :locals=>{:model=>model}, :layout => false
+ when /validation/
+ haml :validation, :locals=>{:model=>model}, :layout => false
+ else
+ return "unable to render model: id #{params[:id]}, view #{params[:view]}"
+ end
+ rescue
+ return "unable to render model: id #{params[:id]}, view #{params[:view]}"
+ end
+end
+
+get '/predict/?' do
+ @models = ToxCreateModel.all(:order => [ :created_at.desc ])
+ @models = @models.collect{|m| m if m.status == 'Completed'}.compact
+ haml :predict
+end
+
+get '/create' do
+ haml :create
+end
+
+get '/help' do
+ haml :help
+end
+
+get "/confidence" do
+ haml :confidence
+end
+
+# proxy to get data from compound service
+# (jQuery load does not work with external URIs)
+get %r{/compound/(.*)} do |inchi|
+ inchi = URI.unescape request.env['REQUEST_URI'].sub(/^\//,'').sub(/.*compound\//,'')
+ OpenTox::Compound.from_inchi(inchi).to_names.join(', ')
+end
+
+post '/models' do # create a new model
+
+ unless params[:file] and params[:file][:tempfile] #params[:endpoint] and
+ flash[:notice] = "Please upload a Excel or CSV file."
+ redirect url_for('/create')
+ end
+
+ @model = ToxCreateModel.create(:name => params[:file][:filename].sub(/\..*$/,""))
+ task = OpenTox::Task.create("Uploading dataset and creating lazar model",url_for("/models",:full)) do
+
+ @model.update :status => "Uploading and saving dataset"
+ begin
+ @dataset = OpenTox::Dataset.create
+ # check format by extension - not all browsers provide correct content-type])
+ case File.extname(params[:file][:filename])
+ when ".csv"
+ csv = params[:file][:tempfile].read
+ LOGGER.debug csv
+ @dataset.load_csv(csv)
+ when ".xls", ".xlsx"
+ @dataset.load_spreadsheet(Excel.new params[:file][:tempfile].path)
+ else
+ error "#{params[:file][:filename]} has a unsupported file type."
+ end
+ rescue => e
+ error "Dataset creation failed with #{e.message}"
+ end
+ @dataset.save
+ if @dataset.compounds.size < 10
+ error "Too few compounds to create a prediction model. Did you provide compounds in SMILES format and classification activities as described in the #{link_to "instructions", "/excel_format"}? As a rule of thumb you will need at least 100 training compounds for nongeneric datasets. A lower number could be sufficient for congeneric datasets."
+ end
+ if @dataset.features.keys.size != 1
+ error "More than one feature in dataset #{params[:file][:filename]}. Please delete irrelvant columns and try again."
+ end
+ if @dataset.metadata[OT.Errors]
+ error "Incorrect file format. Please follow the instructions for #{link_to "Excel", "/excel_format"} or #{link_to "CSV", "/csv_format"} formats."
+ end
+ @model.training_dataset = @dataset.uri
+ @model.nr_compounds = @dataset.compounds.size
+ @model.warnings = @dataset.metadata[OT.Warnings] unless @dataset.metadata[OT.Warnings].empty?
+ @model.save
+
+ @model.update :status => "Creating prediction model"
+ begin
+ lazar = OpenTox::Model::Lazar.create(:dataset_uri => @dataset.uri)
+ rescue => e
+ error "Model creation failed with '#{e.message}'. Please check if the input file is in a valid #{link_to "Excel", "/excel_format"} or #{link_to "CSV", "/csv_format"} format."
+ end
+ LOGGER.debug lazar.metadata.to_yaml
+ @model.feature_dataset = lazar.metadata[OT.featureDataset]
+ @model.uri = lazar.uri
+ case lazar.metadata[OT.isA]
+ when /Classification/
+ @model.type = "classification"
+ when /Regression/
+ @model.type = "regression"
+ else
+ @model.type = "unknown"
+ end
+ @model.save
+
+ unless url_for("",:full).match(/localhost/)
+ @model.update :status => "Validating model"
+ begin
+ validation = OpenTox::Validation.create_crossvalidation(
+ :algorithm_uri => OpenTox::Algorithm::Lazar.uri,
+ :dataset_uri => lazar.parameter("dataset_uri"),
+ :prediction_feature => lazar.parameter("prediction_feature"),
+ :algorithm_params => "feature_generation_uri=#{lazar.parameter("feature_generation_uri")}"
+ )
+ @model.update(:validation_uri => validation.uri)
+ LOGGER.debug "Validation URI: #{@model.validation_uri}"
+ rescue => e
+ LOGGER.debug "Model validation failed with #{e.message}."
+ @model.warnings += "Model validation failed with #{e.message}."
+ end
+
+ # create summary
+ validation.summary(@model.type).each{|k,v| eval "@model.#{k.to_s} = v"}
+ @model.save
+
+ @model.update :status => "Creating validation report"
+ begin
+ @model.update(:validation_report_uri => validation.create_report)
+ rescue => e
+ LOGGER.debug "Validation report generation failed with #{e.message}."
+ @model.warnings += "Validation report generation failed with #{e.message}."
+ end
+
+ @model.update :status => "Creating QMRF report"
+ begin
+ @model.update(:validation_qmrf_report_uri => validation.create_qmrf_report)
+ rescue => e
+ LOGGER.debug "Validation QMRF report generation failed with #{e.message}."
+ @model.warnings += "Validation QMRF report generation failed with #{e.message}."
+ end
+ end
+
+
+
+ #@model.warnings += "<p>Incorrect Smiles structures (ignored):</p>" + parser.smiles_errors.join("<br/>") unless parser.smiles_errors.empty?
+ #@model.warnings += "<p>Irregular activities (ignored):</p>" + parser.activity_errors.join("<br/>") unless parser.activity_errors.empty?
+ #duplicate_warnings = ''
+ #parser.duplicates.each {|inchi,lines| duplicate_warnings += "<p>#{lines.join('<br/>')}</p>" if lines.size > 1 }
+ #@model.warnings += "<p>Duplicated structures (all structures/activities used for model building, please make sure, that the results were obtained from <em>independent</em> experiments):</p>" + duplicate_warnings unless duplicate_warnings.empty?
+ @model.update :status => "Completed"
+ lazar.uri
+ end
+ @model.update(:task_uri => task.uri)
+ @model.save
+
+ flash[:notice] = "Model creation and validation started - this may last up to several hours depending on the number and size of the training compounds."
+ redirect url_for('/models')
+
+=begin
+=end
+end
+
+post '/predict/?' do # post chemical name to model
+ @identifier = params[:identifier]
+ unless params[:selection] and params[:identifier] != ''
+ flash[:notice] = "Please enter a compound identifier and select an endpoint from the list."
+ redirect url_for('/predict')
+ end
+ begin
+ @compound = OpenTox::Compound.from_name(params[:identifier])
+ rescue
+ flash[:notice] = "Could not find a structure for '#{@identifier}'. Please try again."
+ redirect url_for('/predict')
+ end
+ @predictions = []
+ params[:selection].keys.each do |id|
+ model = ToxCreateModel.get(id.to_i)
+ #model.process unless model.uri
+ prediction = nil
+ confidence = nil
+ title = nil
+ db_activities = []
+ lazar = OpenTox::Model::Lazar.new model.uri
+ prediction_dataset_uri = lazar.run(:compound_uri => @compound.uri)
+ prediction_dataset = OpenTox::LazarPrediction.find(prediction_dataset_uri)
+ if prediction_dataset.metadata[OT.hasSource].match(/dataset/)
+ @predictions << {
+ :title => model.name,
+ :measured_activities => prediction_dataset.measured_activities(@compound)
+ }
+ else
+ predicted_feature = prediction_dataset.metadata[OT.dependentVariables]
+ prediction = OpenTox::Feature.find(predicted_feature)
+ LOGGER.debug prediction.to_yaml
+ if prediction.metadata[OT.error]
+ @predictions << {
+ :title => model.name,
+ :error => prediction.metadata[OT.error]
+ }
+ else
+ @predictions << {
+ :title => model.name,
+ :model_uri => model.uri,
+ :prediction => prediction.metadata[OT.prediction],
+ :confidence => prediction.metadata[OT.confidence]
+ }
+ end
+ end
+ # TODO failed/unavailable predictions
+=begin
+ source = prediction.creator
+ if prediction.data[@compound.uri]
+ if source.to_s.match(/model/) # real prediction
+ prediction = prediction.data[@compound.uri].first.values.first
+ #LOGGER.debug prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#classification")]
+ #LOGGER.debug prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#confidence")]
+ if !prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#classification")].nil?
+ @predictions << {
+ :title => model.name,
+ :model_uri => model.uri,
+ :prediction => prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#classification")],
+ :confidence => prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#confidence")]
+ }
+ elsif !prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#regression")].nil?
+ @predictions << {
+ :title => model.name,
+ :model_uri => model.uri,
+ :prediction => prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#regression")],
+ :confidence => prediction[File.join(CONFIG[:services]["opentox-model"],"lazar#confidence")]
+ }
+ end
+ else # database value
+ prediction = prediction.data[@compound.uri].first.values
+ @predictions << {:title => model.name, :measured_activities => prediction}
+ end
+ else
+ @predictions << {:title => model.name, :prediction => "not available (not enough similar compounds in the training dataset)"}
+ end
+=end
+ end
+ LOGGER.debug @predictions.inspect
+
+ haml :prediction
+end
+
+post "/lazar/?" do # get detailed prediction
+ @page = 0
+ @page = params[:page].to_i if params[:page]
+ @model_uri = params[:model_uri]
+ lazar = OpenTox::Model::Lazar.new @model_uri
+ prediction_dataset_uri = lazar.run(:compound_uri => params[:compound_uri])
+ @prediction = OpenTox::LazarPrediction.find(prediction_dataset_uri)
+ @compound = OpenTox::Compound.new(params[:compound_uri])
+ #@title = prediction.metadata[DC.title]
+ # TODO dataset activity
+ #@activity = prediction.metadata[OT.prediction]
+ #@confidence = prediction.metadata[OT.confidence]
+ #@neighbors = []
+ #@features = []
+# if @prediction.data[@compound.uri]
+# if @prediction.creator.to_s.match(/model/) # real prediction
+# p = @prediction.data[@compound.uri].first.values.first
+# if !p[File.join(CONFIG[:services]["opentox-model"],"lazar#classification")].nil?
+# feature = File.join(CONFIG[:services]["opentox-model"],"lazar#classification")
+# elsif !p[File.join(CONFIG[:services]["opentox-model"],"lazar#regression")].nil?
+# feature = File.join(CONFIG[:services]["opentox-model"],"lazar#regression")
+# end
+# @activity = p[feature]
+# @confidence = p[File.join(CONFIG[:services]["opentox-model"],"lazar#confidence")]
+# @neighbors = p[File.join(CONFIG[:services]["opentox-model"],"lazar#neighbors")]
+# @features = p[File.join(CONFIG[:services]["opentox-model"],"lazar#features")]
+# else # database value
+# @measured_activities = @prediction.data[@compound.uri].first.values
+# end
+# else
+# @activity = "not available (no similar compounds in the training dataset)"
+# end
+ haml :lazar
+end
+
+delete '/model/:id/?' do
+ model = ToxCreateModel.get(params[:id])
+ begin
+ RestClient.delete model.uri if model.uri
+ RestClient.delete model.task_uri if model.task_uri
+ model.destroy
+ flash[:notice] = "#{model.name} model deleted."
+ rescue
+ flash[:notice] = "#{model.name} model delete error."
+ end
+ redirect url_for('/models')
+end
+
+delete '/?' do
+ DataMapper.auto_migrate!
+ response['Content-Type'] = 'text/plain'
+ "All Models deleted."
+end
+
+# SASS stylesheet
+get '/stylesheets/style.css' do
+ headers 'Content-Type' => 'text/css; charset=utf-8'
+ sass :style
+end
diff --git a/config.ru b/config.ru
new file mode 100644
index 0000000..1616a96
--- /dev/null
+++ b/config.ru
@@ -0,0 +1,5 @@
+require 'rubygems'
+require 'opentox-ruby'
+require 'config/config_ru'
+set :app_file, __FILE__ # to get the view path right
+run Sinatra::Application
diff --git a/helper.rb b/helper.rb
new file mode 100644
index 0000000..d691103
--- /dev/null
+++ b/helper.rb
@@ -0,0 +1,50 @@
+helpers do
+
+ def hide_link(destination)
+ @link_id = 0 unless @link_id
+ @link_id += 1
+ haml :js_link, :locals => {:name => "hide", :destination => destination, :method => "hide"}, :layout => false
+ end
+
+ def toggle_link(destination,name)
+ @link_id = 0 unless @link_id
+ @link_id += 1
+ haml :js_link, :locals => {:name => name, :destination => destination, :method => "toggle"}, :layout => false
+ end
+
+ def sort(descriptors)
+ features = {:activating => [], :deactivating => []}
+
+ descriptors.each { |d| LOGGER.debug d.inspect; features[d[OT.effect].to_sym] << {:smarts => d[OT.smarts],:p_value => d[OT.pValue]} }
+ LOGGER.debug features.to_yaml
+ features
+ end
+
+ def compound_image(compound,descriptors)
+ haml :compound_image, :locals => {:compound => compound, :features => sort(descriptors)}, :layout => false
+ end
+
+ def activity_markup(activity)
+ case activity.class.to_s
+ when /Float/
+ haml ".other #{sprintf('%.03g', activity)}", :layout => false
+ when /String/
+ haml ".other #{activity.to_s}", :layout => false
+ else
+ if activity #true
+ haml ".active active", :layout => false
+ elsif !activity # false
+ haml ".inactive inactive", :layout => false
+ else
+ haml ".other #{activity.to_s}", :layout => false
+ end
+ end
+ end
+
+ def neighbors_navigation
+ @page = 0 unless @page
+ haml :neighbors_navigation, :layout => false
+ end
+
+end
+
diff --git a/model.rb b/model.rb
new file mode 100644
index 0000000..9929ab0
--- /dev/null
+++ b/model.rb
@@ -0,0 +1,186 @@
+class ToxCreateModel
+
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :name, String, :length => 255
+ property :warnings, Text, :length => 2**32-1
+ property :error_messages, Text, :length => 2**32-1 # :errors interferes with datamapper validation
+ property :type, String
+ property :status, String, :length => 255
+ property :created_at, DateTime
+
+ property :task_uri, String, :length => 255
+ property :uri, String, :length => 255
+
+ property :training_dataset, String, :length => 255
+ property :feature_dataset, String, :length => 255
+ #property :validation_task_uri, String, :length => 255
+ property :validation_uri, String, :length => 255
+
+ #property :validation_report_task_uri, String, :length => 255
+ property :validation_report_uri, String, :length => 255
+
+ #property :validation_qmrf_task_uri, String, :length => 255
+ property :validation_qmrf_uri, String, :length => 255
+
+ property :nr_compounds, Integer
+ property :nr_predictions, Integer
+ property :true_positives, Integer
+ property :false_positives, Integer
+ property :true_negatives, Integer
+ property :false_negatives, Integer
+ property :correct_predictions, Integer
+ property :weighted_area_under_roc, Float
+ property :sensitivity, Float
+ property :specificity, Float
+ property :r_square, Float
+ property :root_mean_squared_error, Float
+ property :mean_absolute_error, Float
+
+=begin
+def status
+ #begin
+ RestClient.get(File.join(@task_uri, 'hasStatus')).body
+ #rescue
+ # "Service offline"
+ #end
+ end
+=end
+=begin
+
+ def validation_status
+ begin
+ RestClient.get(File.join(@validation_task_uri, 'hasStatus')).body
+ rescue
+ "Service offline"
+ end
+ end
+
+ def validation_report_status
+ begin
+ RestClient.get(File.join(@validation_report_task_uri, 'hasStatus')).body
+ rescue
+ "Service offline"
+ end
+ end
+
+ def validation_qmrf_status
+ begin
+ RestClient.get(File.join(@validation_qmrf_task_uri, 'hasStatus')).body
+ rescue
+ "Service offline"
+ end
+ end
+
+ def algorithm
+ begin
+ RestClient.get(File.join(@uri, 'algorithm')).body
+ rescue
+ ""
+ end
+ end
+
+ def training_dataset
+ begin
+ RestClient.get(File.join(@uri, 'trainingDataset')).body
+ rescue
+ ""
+ end
+ end
+
+ def feature_dataset
+ begin
+ RestClient.get(File.join(@uri, 'feature_dataset')).body
+ rescue
+ ""
+ end
+ end
+
+ def process
+
+ LOGGER.debug self.to_yaml
+
+ if @uri.nil? and status == "Completed"
+ #update :uri => RestClient.get(File.join(@task_uri, 'resultURI')).body
+ #lazar = YAML.load(RestClient.get(@uri, :accept => "application/x-yaml").body)
+
+ elsif @validation_uri.nil? and validation_status == "Completed"
+ begin
+
+ #update :validation_uri => RestClient.get(File.join(@validation_task_uri, 'resultURI')).body
+ #LOGGER.debug "Validation URI: #{@validation_uri}"
+
+ #update :validation_report_task_uri => RestClient.post(File.join(CONFIG[:services]["opentox-validation"],"/report/crossvalidation"), :validation_uris => @validation_uri).body
+ #LOGGER.debug "Validation Report Task URI: #{@validation_report_task_uri}"
+
+ #update :validation_qmrf_task_uri => RestClient.post(File.join(CONFIG[:services]["opentox-validation"],"/reach_report/qmrf"), :model_uri => @uri).body
+ #LOGGER.debug "QMRF Report Task URI: #{@validation_qmrf_task_uri}"
+
+ uri = File.join(@validation_uri, 'statistics')
+ yaml = RestClient.get(uri).body
+ v = YAML.load(yaml)
+
+ case type
+ when "classification"
+ tp=0; tn=0; fp=0; fn=0; n=0
+ v[:classification_statistics][:confusion_matrix][:confusion_matrix_cell].each do |cell|
+ if cell[:confusion_matrix_predicted] == "true" and cell[:confusion_matrix_actual] == "true"
+ tp = cell[:confusion_matrix_value]
+ n += tp
+ elsif cell[:confusion_matrix_predicted] == "false" and cell[:confusion_matrix_actual] == "false"
+ tn = cell[:confusion_matrix_value]
+ n += tn
+ elsif cell[:confusion_matrix_predicted] == "false" and cell[:confusion_matrix_actual] == "true"
+ fn = cell[:confusion_matrix_value]
+ n += fn
+ elsif cell[:confusion_matrix_predicted] == "true" and cell[:confusion_matrix_actual] == "false"
+ fp = cell[:confusion_matrix_value]
+ n += fp
+ end
+ end
+ update :nr_predictions => n
+ update :true_positives => tp
+ update :false_positives => fp
+ update :true_negatives => tn
+ update :false_negatives => fn
+ update :correct_predictions => 100*(tp+tn).to_f/n
+ update :weighted_area_under_roc => v[:classification_statistics][:weighted_area_under_roc].to_f
+ update :sensitivity => tp.to_f/(tp+fn)
+ update :specificity => tn.to_f/(tn+fp)
+ when "regression"
+ update :nr_predictions => v[:num_instances] - v[:num_unpredicted]
+ update :r_square => v[:regression_statistics][:r_square]
+ update :root_mean_squared_error => v[:regression_statistics][:root_mean_squared_error]
+ update :mean_absolute_error => v[:regression_statistics][:mean_absolute_error]
+ end
+ rescue
+ LOGGER.warn "Cannot create Validation Report Task #{@validation_report_task_uri} for Validation URI #{@validation_uri} from Task #{@validation_task_uri}"
+ end
+
+ else
+
+ if @validation_report_uri.nil? and validation_report_status == "Completed"
+ begin
+ update :validation_report_uri => RestClient.get(File.join(@validation_report_task_uri, 'resultURI')).body
+ rescue
+ LOGGER.warn "Cannot create Validation Report for Task URI #{@validation_report_task_uri} "
+ end
+ end
+
+ if @validation_qmrf_uri.nil? and validation_qmrf_status == "Completed"
+ begin
+ update :validation_qmrf_uri => RestClient.get(File.join(@validation_qmrf_task_uri, 'resultURI')).body
+ rescue
+ LOGGER.warn "Cannot create QMRF Report for Task URI #{@validation_qmrf_task_uri} "
+ end
+ end
+
+ end
+
+ end
+=end
+
+end
+
+DataMapper.auto_upgrade!
diff --git a/public/JME.class b/public/JME.class
new file mode 100644
index 0000000..9efda0e
--- /dev/null
+++ b/public/JME.class
Binary files differ
diff --git a/public/JME.jar b/public/JME.jar
new file mode 100644
index 0000000..d571682
--- /dev/null
+++ b/public/JME.jar
Binary files differ
diff --git a/public/ToxCreate_rgb_72.png b/public/ToxCreate_rgb_72.png
new file mode 100644
index 0000000..4b96882
--- /dev/null
+++ b/public/ToxCreate_rgb_72.png
Binary files differ
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..ba4fae1
--- /dev/null
+++ b/public/favicon.ico
Binary files differ
diff --git a/public/hamster_carcinogenicity.csv b/public/hamster_carcinogenicity.csv
new file mode 100644
index 0000000..e9ca269
--- /dev/null
+++ b/public/hamster_carcinogenicity.csv
@@ -0,0 +1,85 @@
+CC=O,1
+C12C3=C(C=CC=C3)CC1=CC(=CC=2)NC(C)=O,1
+O=C(N)\C(C2=CC=CO2)=C/C1=CC=C([N+]([O-])=O)O1,1
+C1(N=CNN=1)N,0
+Br(=O)(=O)[O-].[K+],1
+[Cl-].[Cd+2].[Cl-],0
+O=S(=O)([O-])[O-].[Cd+2],0
+ClC1=CC(=NC(=N1)SCC(=O)O)NC2=CC=CC(=C2C)C,0
+ClCOC,1
+C=C(Cl)C=C,0
+Clc1ccc(cc1)c2ccc(COC(C)(C)C(O)=O)cc2,0
+O=C1OC2=C(C=CC=C2)C=C1,0
+ClC(=C(C1=CC=C(C=C1)Cl)C2=CC=C(C=C2)Cl)Cl,1
+ClC(C(C1=CC=C(C=C1)Cl)C2=CC=C(C=C2)Cl)(Cl)Cl,0
+C=CCN(CC=C)N=O,1
+Cl\C2=C(/Cl)C3(Cl)C1C4CC(C1C2(Cl)C3(Cl)Cl)C5OC45,0
+O=C(N(C)C)Cl,1
+CN(C)N,1
+N(NC)C.[H]Cl.[H]Cl,1
+CCO,0
+O=C(N(CC)N=O)NCCO,1
+O=C(N(CC)N=O)NCC(=O)C,1
+C=O,0
+[O-][N+](=O)C1=CC=C(O1)C2=CSC(=N2)NNC=O,1
+O=CC1=CC=CO1,0
+OCC1CO1,1
+O=C2C1=C(OC)C=C(OC)C(Cl)=C1O[C@]32C(OC)=CC(C[C@@](C)3[H])=O,0
+ClC1=C(C(=C(C(=C1Cl)Cl)Cl)Cl)Cl,1
+NN,1
+OS(=O)(=O)O.NN,1
+CC(=O)N(O)C1=CC2=C(C=C1)C3=CC=CC=C3C2,1
+OCCNN,0
+O=C(C1=CC=NC=C1)NN,0
+OC(=O)C1=CC=NC=C1,0
+O=C(NC1=CC=CC(=C1)Cl)OC(C)C,0
+O=C(NC1=CC=CC=C1)OC(C)C,0
+[O-]C(C)=O.[O-]C(C)=O.[Pb+2].[OH-].[OH-].[Pb+2].[OH-].[OH-].[Pb+2],0
+CN(C)CCN(CC2=CC=CS2)C1=NC=CC=C1.Cl,0
+NC1=C2C(=NC(=N1)N)N=CC(=N2)CN(C3=CC=C(C=C3)C(=O)N[C@@H](CCC(=O)O)C(=O)O)C,0
+CN(N)C=O,1
+O=C(C(=C)C)OC,0
+CNN,1
+O=C(C1=CC=CN=C1)CCCN(N=O)C,0
+CC1=CC(=O)NC(=S)N1,1
+CC(C(O)=O)(OC1=CC=C(C=C1)C2CCCC3=C2C=CC=C3)C,0
+O=N[O-].[Na+],0
+[O-][N+](C1=CC=C(C2=CSC(NC(C)=O)=N2)O1)=O,1
+[O-][N+](=O)C1=CC=C(O1)C2=CSC(=N2)NC=O,1
+O=[N+](C1=CC=C2C3=C1C=CC=C3CC2)[O-],0
+N(CC(CO)O)(CC(O)C)N=O,1
+N(CC(CO)O)(CC(C)=O)N=O,1
+N(CC(CO)O)(CCO)N=O,0
+O=C(C)CN(N=O)CCO,1
+C1C(N(C(CN1N=O)C)C)C,1
+N(CC(C)=O)(CC=C)N=O,1
+N(CC(CO)O)(C)N=O,1
+O=NN1CCOCC1,1
+N1C=CC=C(C=1)C2N(N=O)CCC2,1
+C1=CC=C(C=[N+]1[O-])C2CCCN2N=O,0
+O=NN1CCCCC1,1
+O=NN1CCCC1,1
+O=C(N(CC(C)=O)N=O)NCCCl,1
+N(C(=O)N)(N=O)CC(C)=O,1
+C1(CCN=C=S)=CC=CC=C1,0
+O=C1C(C2=CC=CC=C2)(C(=O)NC(=O)N1)CC,0
+C1=C2C(=CC=C1NC3=CC=CC=C3)C=CC=C2,0
+O=C1N2C(C3=C(C=CC=C3)CC2)CN(C1)C(=O)C4CCCCC4,0
+C1(=CC(=C(O)C=C1)O)C(O)=O,0
+O=C1C2=C(C=C(C=C2O)O)O/C(=C\1O)C3=CC(=C(C=C3)O)O.O.O,0
+C1=C(C=CC(=C1)C(C2=CC=C(N)C(=C2)C)=C3C=CC(=N)C=C3)N.[H]Cl,0
+C(C1=CC=C(C=C1)N)(C2=CC=C(C=C2)N)=C3C=CC(C=C3)=N.[H]Cl,0
+OC2=CC1=C(C(O)=C2)C(C(O[C@@H]4O[C@@H]([C@H]([C@H](O)[C@H]4O)O)CO[C@H]3[C@H](O)[C@H](O)[C@H]([C@H](C)O3)O)=C(C5=CC(O)=C(C=C5)O)O1)=O,0
+ClC(=CCl)Cl,0
+NC(=O)OCC,1
+C=CCl,1
+N#[N+]C1=CC=CC=C1.F[B-](F)(F)F,0
+C1(CN(CC(N1N=O)C)N=O)C,1
+N(CCN(C)C)(C)N=O,1
+C1(CN(N=O)CC(O1)C)C,1
+O1C(N(CC1C)N=O)=O,1
+CCOC(=O)N(C)N=O,1
+C1N(COC1)N=O,1
+O=C(N(CCC1=CC=CC=C1)N=O)N,1
+O=NN1CCC1,1
+F[B-](F)(F)F.[Na+],0
diff --git a/public/hamster_carcinogenicity.xls b/public/hamster_carcinogenicity.xls
new file mode 100644
index 0000000..0015ac6
--- /dev/null
+++ b/public/hamster_carcinogenicity.xls
Binary files differ
diff --git a/public/javascripts/jquery.js b/public/javascripts/jquery.js
new file mode 100755
index 0000000..7c24308
--- /dev/null
+++ b/public/javascripts/jquery.js
@@ -0,0 +1,154 @@
+/*!
+ * jQuery JavaScript Library v1.4.2
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Sat Feb 13 22:33:48 2010 -0500
+ */
+(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o<i;o++)e(a[o],b,f?d.call(a[o],o,e(a[o],b)):d,j);return a}return i?
+e(a[0],b):w}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function na(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function oa(a){var b,d=[],f=[],e=arguments,j,i,o,k,n,r;i=c.data(this,"events");if(!(a.liveFired===this||!i||!i.live||a.button&&a.type==="click")){a.liveFired=this;var u=i.live.slice(0);for(k=0;k<u.length;k++){i=u[k];i.origType.replace(O,"")===a.type?f.push(i.selector):u.splice(k--,1)}j=c(a.target).closest(f,a.currentTarget);n=0;for(r=
+j.length;n<r;n++)for(k=0;k<u.length;k++){i=u[k];if(j[n].selector===i.selector){o=j[n].elem;f=null;if(i.preType==="mouseenter"||i.preType==="mouseleave")f=c(a.relatedTarget).closest(i.selector)[0];if(!f||f!==o)d.push({elem:o,handleObj:i})}}n=0;for(r=d.length;n<r;n++){j=d[n];a.currentTarget=j.elem;a.data=j.handleObj.data;a.handleObj=j.handleObj;if(j.handleObj.origHandler.apply(j.elem,e)===false){b=false;break}}return b}}function pa(a,b){return"live."+(a&&a!=="*"?a+".":"")+b.replace(/\./g,"`").replace(/ /g,
+"&")}function qa(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function ra(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var j in f)for(var i in f[j])c.event.add(this,j,f[j][i],f[j][i].data)}}})}function sa(a,b,d){var f,e,j;b=b&&b[0]?b[0].ownerDocument||b[0]:s;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&b===s&&!ta.test(a[0])&&(c.support.checkClone||!ua.test(a[0]))){e=
+true;if(j=c.fragments[a[0]])if(j!==1)f=j}if(!f){f=b.createDocumentFragment();c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=j?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(va.concat.apply([],va.slice(0,b)),function(){d[this]=a});return d}function wa(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Ra=A.jQuery,Sa=A.$,s=A.document,T,Ta=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/,
+Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&&
+(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this,
+a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b===
+"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,
+function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(j in e){i=a[j];o=e[j];if(a!==o)if(f&&o&&(c.isPlainObject(o)||c.isArray(o))){i=i&&(c.isPlainObject(i)||
+c.isArray(i))?i:c.isArray(o)?[]:{};a[j]=c.extend(f,i,o)}else if(o!==w)a[j]=o}return a};c.extend({noConflict:function(a){A.$=Sa;if(a)A.jQuery=Ra;return c},isReady:false,ready:function(){if(!c.isReady){if(!s.body)return setTimeout(c.ready,13);c.isReady=true;if(Q){for(var a,b=0;a=Q[b++];)a.call(s,c);Q=null}c.fn.triggerHandler&&c(s).triggerHandler("ready")}},bindReady:function(){if(!xa){xa=true;if(s.readyState==="complete")return c.ready();if(s.addEventListener){s.addEventListener("DOMContentLoaded",
+L,false);A.addEventListener("load",c.ready,false)}else if(s.attachEvent){s.attachEvent("onreadystatechange",L);A.attachEvent("onload",c.ready);var a=false;try{a=A.frameElement==null}catch(b){}s.documentElement.doScroll&&a&&ma()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,
+"isPrototypeOf"))return false;var b;for(b in a);return b===w||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;a=c.trim(a);if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return A.JSON&&A.JSON.parse?A.JSON.parse(a):(new Function("return "+
+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Va.test(a)){var b=s.getElementsByTagName("head")[0]||s.documentElement,d=s.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(s.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,j=a.length,i=j===w||c.isFunction(a);if(d)if(i)for(f in a){if(b.apply(a[f],
+d)===false)break}else for(;e<j;){if(b.apply(a[e++],d)===false)break}else if(i)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=a[0];e<j&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Wa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===
+a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==w;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,j=a.length;e<j;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,j=0,i=a.length;j<i;j++){e=b(a[j],j,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=w}else if(b&&
+!c.isFunction(b)){d=b;b=w}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});P=c.uaMatch(P);if(P.browser){c.browser[P.browser]=true;c.browser.version=P.version}if(c.browser.webkit)c.browser.safari=
+true;if(ya)c.inArray=function(a,b){return ya.call(b,a)};T=c(s);if(s.addEventListener)L=function(){s.removeEventListener("DOMContentLoaded",L,false);c.ready()};else if(s.attachEvent)L=function(){if(s.readyState==="complete"){s.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=s.documentElement,b=s.createElement("script"),d=s.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected,
+parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent=
+false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n=
+s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,
+applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando];
+else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,
+a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===
+w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i,
+cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className){for(var j=" "+e.className+" ",
+i=e.className,o=0,k=b.length;o<k;o++)if(j.indexOf(" "+b[o]+" ")<0)i+=" "+b[o];e.className=c.trim(i)}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(k){var n=c(this);n.removeClass(a.call(this,k,n.attr("class")))});if(a&&typeof a==="string"||a===w)for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var j=(" "+e.className+" ").replace(Aa," "),i=0,o=b.length;i<o;i++)j=j.replace(" "+b[i]+" ",
+" ");e.className=c.trim(j)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var j=c(this);j.toggleClass(a.call(this,e,j.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,j=0,i=c(this),o=b,k=a.split(ca);e=k[j++];){o=f?o:!i.hasClass(e);i[o?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=
+this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(Aa," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j<d;j++){var i=
+e[j];if(i.selected){a=c(i).val();if(b)return a;f.push(a)}}return f}if(Ba.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Za,"")}return w}var o=c.isFunction(a);return this.each(function(k){var n=c(this),r=a;if(this.nodeType===1){if(o)r=a.call(this,k,n.val());if(typeof r==="number")r+="";if(c.isArray(r)&&Ba.test(this.type))this.checked=c.inArray(n.val(),r)>=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected=
+c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");
+a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g,
+function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split(".");
+k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a),
+C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B<r.length;B++){u=r[B];if(d.guid===u.guid){if(i||k.test(u.namespace)){f==null&&r.splice(B--,1);n.remove&&n.remove.call(a,u)}if(f!=
+null)break}}if(r.length===0||f!=null&&r.length===1){if(!n.teardown||n.teardown.call(a,o)===false)Ca(a,e,z.handle);delete C[e]}}else for(var B=0;B<r.length;B++){u=r[B];if(i||k.test(u.namespace)){c.event.remove(a,n,u.handler,B);r.splice(B--,1)}}}if(c.isEmptyObject(C)){if(b=z.handle)b.elem=null;delete z.events;delete z.handle;c.isEmptyObject(z)&&c.removeData(a)}}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=
+e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&&
+f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive;
+if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e<j;e++){var i=d[e];if(b||f.test(i.namespace)){a.handler=i.handler;a.data=i.data;a.handleObj=i;i=i.handler.apply(this,arguments);if(i!==w){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||s;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=s.documentElement;d=s.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==w)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a){c.event.add(this,a.origType,c.extend({},a,{handler:oa}))},remove:function(a){var b=true,d=a.origType.replace(O,"");c.each(c.data(this,
+"events").live||[],function(){if(d===this.origType.replace(O,""))return b=false});b&&c.event.remove(this,a.origType,oa)}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};var Ca=s.removeEventListener?function(a,b,d){a.removeEventListener(b,d,false)}:function(a,b,d){a.detachEvent("on"+b,d)};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=
+a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,
+isImmediatePropagationStopped:Y};var Da=function(a){var b=a.relatedTarget;try{for(;b&&b!==this;)b=b.parentNode;if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}}catch(d){}},Ea=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ea:Da,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ea:Da)}}});if(!c.support.submitBubbles)c.event.special.submit=
+{setup:function(){if(this.nodeName.toLowerCase()!=="form"){c.event.add(this,"click.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="submit"||d==="image")&&c(b).closest("form").length)return na("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,d=b.type;if((d==="text"||d==="password")&&c(b).closest("form").length&&a.keyCode===13)return na("submit",this,arguments)})}else return false},teardown:function(){c.event.remove(this,".specialSubmit")}};
+if(!c.support.changeBubbles){var da=/textarea|input|select/i,ea,Fa=function(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data",
+e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a,
+"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a,
+d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j<o;j++)c.event.add(this[j],d,i,f)}return this}});c.fn.extend({unbind:function(a,b){if(typeof a==="object"&&
+!a.preventDefault)for(var d in a)this.unbind(d,a[d]);else{d=0;for(var f=this.length;d<f;d++)c.event.remove(this[d],a,b)}return this},delegate:function(a,b,d,f){return this.live(b,d,f,a)},undelegate:function(a,b,d){return arguments.length===0?this.unbind("live"):this.die(b,null,d,a)},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},
+toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Ga={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e,j){var i,o=0,k,n,r=j||this.selector,
+u=j?this:c(this.context);if(c.isFunction(f)){e=f;f=w}for(d=(d||"").split(" ");(i=d[o++])!=null;){j=O.exec(i);k="";if(j){k=j[0];i=i.replace(O,"")}if(i==="hover")d.push("mouseenter"+k,"mouseleave"+k);else{n=i;if(i==="focus"||i==="blur"){d.push(Ga[i]+k);i+=k}else i=(Ga[i]||i)+k;b==="live"?u.each(function(){c.event.add(this,pa(i,r),{data:f,selector:r,handler:e,origType:i,origHandler:e,preType:n})}):u.unbind(pa(i,r),e)}}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),
+function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});A.attachEvent&&!A.addEventListener&&A.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});(function(){function a(g){for(var h="",l,m=0;g[m];m++){l=g[m];if(l.nodeType===3||l.nodeType===4)h+=l.nodeValue;else if(l.nodeType!==8)h+=a(l.childNodes)}return h}function b(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];
+if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=l;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}m[q]=y}}}function d(g,h,l,m,q,p){q=0;for(var v=m.length;q<v;q++){var t=m[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===l){y=m[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=l;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(k.filter(h,[t]).length>0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift();
+t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D||
+g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};k.matches=function(g,h){return k(g,null,null,h)};k.find=function(g,h,l){var m,q;if(!g)return[];
+for(var p=0,v=n.order.length;p<v;p++){var t=n.order[p];if(q=n.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");m=n.find[t](q,h,l);if(m!=null){g=g.replace(n.match[t],"");break}}}}m||(m=h.getElementsByTagName("*"));return{set:m,expr:g}};k.filter=function(g,h,l,m){for(var q=g,p=[],v=h,t,y,S=h&&h[0]&&x(h[0]);g&&h.length;){for(var H in n.filter)if((t=n.leftMatch[H].exec(g))!=null&&t[2]){var M=n.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-
+1)!=="\\"){if(v===p)p=[];if(n.preFilter[H])if(t=n.preFilter[H](t,v,l,p,m,S)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=v[U])!=null;U++)if(D){I=M(D,t,U,v);var Ha=m^!!I;if(l&&I!=null)if(Ha)y=true;else v[U]=false;else if(Ha){p.push(D);y=true}}if(I!==w){l||(v=p);g=g.replace(n.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)k.error(g);else break;q=g}return v};k.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var n=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},
+relative:{"+":function(g,h){var l=typeof h==="string",m=l&&!/\W/.test(h);l=l&&!m;if(m)h=h.toLowerCase();m=0;for(var q=g.length,p;m<q;m++)if(p=g[m]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[m]=l||p&&p.nodeName.toLowerCase()===h?p||false:p===h}l&&k.filter(h,g,true)},">":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m<q;m++){var p=g[m];if(p){l=p.parentNode;g[m]=l.nodeName.toLowerCase()===h?l:false}}}else{m=0;for(q=g.length;m<q;m++)if(p=g[m])g[m]=
+l?p.parentNode:p.parentNode===h;l&&k.filter(h,g,true)}},"":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("parentNode",h,m,g,p,l)},"~":function(g,h,l){var m=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,m,g,p,l)}},find:{ID:function(g,h,l){if(typeof h.getElementById!=="undefined"&&!l)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var l=[];
+h=h.getElementsByName(g[1]);for(var m=0,q=h.length;m<q;m++)h[m].getAttribute("name")===g[1]&&l.push(h[m]);return l.length===0?null:l}},TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,l,m,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var v;(v=h[p])!=null;p++)if(v)if(q^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},
+CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m,
+g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},
+text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},
+setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return h<l[3]-0},gt:function(g,h,l){return h>l[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=
+h[3];l=0;for(m=h.length;l<m;l++)if(h[l]===g)return false;return true}else k.error("Syntax error, unrecognized expression: "+q)},CHILD:function(g,h){var l=h[1],m=g;switch(l){case "only":case "first":for(;m=m.previousSibling;)if(m.nodeType===1)return false;if(l==="first")return true;m=g;case "last":for(;m=m.nextSibling;)if(m.nodeType===1)return false;return true;case "nth":l=h[2];var q=h[3];if(l===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var v=0;for(m=p.firstChild;m;m=
+m.nextSibling)if(m.nodeType===1)m.nodeIndex=++v;p.sizcache=h}g=g.nodeIndex-q;return l===0?g===0:g%l===0&&g/l>=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m===
+"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g,
+h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l<m;l++)h.push(g[l]);else for(l=0;g[l];l++)h.push(g[l]);return h}}var B;if(s.documentElement.compareDocumentPosition)B=function(g,h){if(!g.compareDocumentPosition||
+!h.compareDocumentPosition){if(g==h)i=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===h?0:1;if(g===0)i=true;return g};else if("sourceIndex"in s.documentElement)B=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)i=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)i=true;return g};else if(s.createRange)B=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)i=true;return g.ownerDocument?-1:1}var l=g.ownerDocument.createRange(),m=
+h.ownerDocument.createRange();l.setStart(g,0);l.setEnd(g,0);m.setStart(h,0);m.setEnd(h,0);g=l.compareBoundaryPoints(Range.START_TO_END,m);if(g===0)i=true;return g};(function(){var g=s.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&&
+q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML="<a href='#'></a>";
+if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}();
+(function(){var g=s.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}:
+function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)k(g,h[q],l);return k.filter(m,l)};c.find=k;c.expr=k.selectors;c.expr[":"]=c.expr.filters;c.unique=k.uniqueSort;c.text=a;c.isXMLDoc=x;c.contains=E})();var eb=/Until$/,fb=/^(?:parents|prevUntil|prevAll)/,
+gb=/,/;R=Array.prototype.slice;var Ia=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,j){return!!b.call(e,j,e)===d});else if(b.nodeType)return c.grep(a,function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Ua.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;
+c.find(a,this[f],b);if(f>0)for(var j=d;j<b.length;j++)for(var i=0;i<d;i++)if(b[i]===b[j]){b.splice(j--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ia(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ia(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j=
+{},i;if(f&&a.length){e=0;for(var o=a.length;e<o;e++){i=a[e];j[i]||(j[i]=c.expr.match.POS.test(i)?c(i,b||this.context):i)}for(;f&&f.ownerDocument&&f!==b;){for(i in j){e=j[i];if(e.jquery?e.index(f)>-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a===
+"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",
+d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?
+a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType===
+1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/<tbody/i,jb=/<|&#?\w+;/,ta=/<script|<object|<embed|<option|<style/i,ua=/checked\s*(?:[^=]|=\s*.checked.)/i,Ma=function(a,b,d){return hb.test(d)?
+a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=
+c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},
+wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},
+prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,
+this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild);
+return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja,
+""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var j=c(this),i=j.html();j.empty().append(function(){return a.call(this,e,i)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&
+this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,b,f))});if(typeof a!=="string")a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(u){return c.nodeName(u,"table")?u.getElementsByTagName("tbody")[0]||
+u.appendChild(u.ownerDocument.createElement("tbody")):u}var e,j,i=a[0],o=[],k;if(!c.support.checkClone&&arguments.length===3&&typeof i==="string"&&ua.test(i))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(i))return this.each(function(u){var z=c(this);a[0]=i.call(this,u,b?z.html():w);z.domManip(a,b,d)});if(this[0]){e=i&&i.parentNode;e=c.support.parentNode&&e&&e.nodeType===11&&e.childNodes.length===this.length?{fragment:e}:sa(a,this,o);k=e.fragment;if(j=k.childNodes.length===
+1?(k=k.firstChild):k.firstChild){b=b&&c.nodeName(j,"tr");for(var n=0,r=this.length;n<r;n++)d.call(b?f(this[n],j):this[n],n>0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]);
+return this}else{e=0;for(var j=d.length;e<j;e++){var i=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["",
+""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]==="<table>"&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e=
+c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]?
+c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja=
+function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=
+Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,
+"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=
+a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=
+a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/<script(.|\s)*?\/script>/gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!==
+"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("<div />").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this},
+serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),
+function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,
+global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&
+e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)?
+"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===
+false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B=
+false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since",
+c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E||
+d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x);
+g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===
+1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b===
+"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional;
+if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");
+this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(la[d])f=la[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],
+"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},
+animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var j=c.extend({},e),i,o=this.nodeType===1&&c(this).is(":hidden"),k=this;for(i in a){var n=i.replace(ia,ja);if(i!==n){a[n]=a[i];delete a[i];i=n}if(a[i]==="hide"&&o||a[i]==="show"&&!o)return j.complete.call(this);if((i==="height"||i==="width")&&this.style){j.display=c.css(this,"display");j.overflow=this.style.overflow}if(c.isArray(a[i])){(j.specialEasing=
+j.specialEasing||{})[i]=a[i][1];a[i]=a[i][0]}}if(j.overflow!=null)this.style.overflow="hidden";j.curAnim=c.extend({},a);c.each(a,function(r,u){var z=new c.fx(k,j,r);if(Ab.test(u))z[u==="toggle"?o?"show":"hide":u](a);else{var C=Bb.exec(u),B=z.cur(true)||0;if(C){u=parseFloat(C[2]);var E=C[3]||"px";if(E!=="px"){k.style[r]=(u||1)+E;B=(u||1)/z.cur(true)*B;k.style[r]=B+E}if(C[1])u=(C[1]==="-="?-1:1)*u+B;z.custom(B,u,E)}else z.custom(B,u,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);
+this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration===
+"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||
+c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;
+this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=
+this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,
+e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||
+c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in s.documentElement?
+function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=
+this[0];if(a)return this.each(function(r){c.offset.setOffset(this,a,r)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=b,e=b.ownerDocument,j,i=e.documentElement,o=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var k=b.offsetTop,n=b.offsetLeft;(b=b.parentNode)&&b!==o&&b!==i;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;j=e?e.getComputedStyle(b,null):b.currentStyle;
+k-=b.scrollTop;n-=b.scrollLeft;if(b===d){k+=b.offsetTop;n+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&j.overflow!=="visible"){k+=parseFloat(j.borderTopWidth)||0;n+=parseFloat(j.borderLeftWidth)||0}f=j}if(f.position==="relative"||f.position==="static"){k+=o.offsetTop;n+=o.offsetLeft}if(c.offset.supportsFixedPosition&&
+f.position==="fixed"){k+=Math.max(i.scrollTop,o.scrollTop);n+=Math.max(i.scrollLeft,o.scrollLeft)}return{top:k,left:n}};c.offset={initialize:function(){var a=s.body,b=s.createElement("div"),d,f,e,j=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b);
+c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,
+d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-
+f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset":
+"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in
+e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window);
diff --git a/public/javascripts/toxcreate.js b/public/javascripts/toxcreate.js
new file mode 100755
index 0000000..500b685
--- /dev/null
+++ b/public/javascripts/toxcreate.js
@@ -0,0 +1,121 @@
+$(function() {
+
+ jQuery.fn.toggleWarnings = function(id) {
+ var id = id;
+ this.bind("click", function() {
+ if($("a#show_model_" + id + "_warnings").html()=="show") {
+ $("dd#model_" + id + "_warnings").slideDown("slow");
+ $("a#show_model_" + id + "_warnings").html("hide");
+ }else{
+ $("dd#model_" + id + "_warnings").slideUp("slow");
+ $("a#show_model_" + id + "_warnings").html("show");
+ }
+ return false;
+ });
+ };
+
+ checkStati = function(stati) {
+ stati = stati.split(", ")
+ $("body")
+ var newstati = new Array;
+ $.each(stati, function(){
+ if(checkStatus(this) > 0) newstati.push(this);
+ });
+ if (newstati.length > 0) var statusCheck = setTimeout('checkStati("' + newstati.join(", ") + '")',10000);
+ };
+
+ checkStatus = function(id) {
+ if(id == "") return -1;
+ var opts = {method: 'get', action: 'model/' + id + '/status', id: id};
+ var status_changed = $.ajax({
+ type: opts.method,
+ url: opts.action,
+ async: false,
+ dataType: 'html',
+ data: {
+ '_method': 'get'
+ },
+ success: function(data) {
+ var erg = data.search(/Running/);
+ status_changed = false;
+ if(erg < 0) status_changed = true;
+ $("span#model_" + id + "_status").animate({"opacity": "0.1"},1000);
+ $("span#model_" + id + "_status").animate({"opacity": "1"},1000);
+ if( status_changed ) {
+ $("span#model_" + id + "_status").html(data);
+ loadModel(id, 'model');
+ id = -1;
+ }
+ },
+ error: function(data) {
+ //alert("status check error");
+ id = -1;
+ }
+ });
+ return id;
+ };
+
+ loadModel = function(id, view) {
+ if(id == "") return -1;
+ var opts = {method: 'get', action: 'model/' + id + '/' + view, view: view };
+ var out = id;
+ $.ajax({
+ type: opts.method,
+ url: opts.action,
+ dataType: 'html',
+ data: {
+ '_method': 'get'
+ },
+ success: function(data) {
+ if (view == "model") $("div#model_" + id).html(data);
+ if (view.match(/validation/)) $("dl#model_validation_" + id).html(data);
+ },
+ error: function(data) {
+ //alert("loadModel error");
+ }
+ });
+ return false;
+ };
+
+ checkValidation = function() {
+ var reload_id = "";
+ $("input.model_validation_report").each(function(){
+ if(!$(this).val().match(/Completed|Error/)) {
+ reload_id = this.id.replace("model_validation_report_","");
+ if(/^\d+$/.test(reload_id)) loadModel(reload_id, 'validation');
+ };
+ });
+ //var validationCheck = setTimeout('checkValidation()',15000);
+ var validationCheck = setTimeout('checkValidation()',5000);
+ }
+});
+
+jQuery.fn.deleteModel = function(type, options) {
+ var defaults = {
+ method: 'post',
+ action: this.attr('href'),
+ confirm_message: 'Are you sure?',
+ trigger_on: 'click'
+ };
+ var opts = $.extend(defaults, options);
+ this.bind(opts.trigger_on, function() {
+ if(confirm(opts.confirm_message)) {
+ $(opts.elem).fadeTo("slow",0.5);
+ $.ajax({
+ type: opts.method,
+ url: opts.action,
+ dataType: 'html',
+ data: {
+ '_method': 'delete'
+ },
+ success: function(data) {
+ $(opts.elem).fadeTo("slow",0).slideUp("slow").remove();
+ },
+ error: function(data) {
+ //alert("model delete error!");
+ }
+ });
+ }
+ return false;
+ });
+};
diff --git a/public/jme-200606.jar b/public/jme-200606.jar
new file mode 100644
index 0000000..9cae5e7
--- /dev/null
+++ b/public/jme-200606.jar
Binary files differ
diff --git a/public/jme.js b/public/jme.js
new file mode 100644
index 0000000..02a213f
--- /dev/null
+++ b/public/jme.js
@@ -0,0 +1,11 @@
+function getsmiles() {
+ if (document.JME.smiles() != '') {
+ $('smiles').value = document.JME.smiles() ;
+ }
+}
+
+function getsmarts() {
+ if (document.JME.smiles() != '') {
+ $('smarts').value = document.JME.smiles() ;
+ }
+}
diff --git a/public/jme_help.html b/public/jme_help.html
new file mode 100644
index 0000000..ab4942a
--- /dev/null
+++ b/public/jme_help.html
@@ -0,0 +1,195 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+ <meta name="generator" content=
+ "HTML Tidy for Linux/x86 (vers 12 April 2005), see www.w3.org">
+ <meta http-equiv="content-type" content=
+ "text/html; charset=us-ascii">
+
+ <title>JME Help</title>
+ <meta name="author" content="Peter Ertl, Novartis Pharma AG">
+ <link rel="stylesheet" href="../style.css" type="text/css">
+<style type="text/css">
+ body {
+ background-color: white;
+ }
+ h2.c3 {text-align: center}
+ p.c2 {font-style: italic; text-align: right}
+ p.c1 {text-align: center}
+</style>
+</head>
+
+<body>
+ <h1>JME Molecular Editor</h1>
+
+ <p class="c2">Written by Peter Ertl, Novartis Pharma
+ AG</p>
+
+ <h2 class="c3">Basic Instructions</h2>
+
+ <p>This editor is intended to be used without any special
+ documentation or training, but there are some tricks which
+ can help you to work with it more efficiently.</p>
+
+ <h3>Menu Buttons</h3>
+
+ <ul>
+ <li><b>D-R</b> deletes functional groups - choose this
+ option and then click on the bond connecting the group
+ with the main skeleton</li>
+
+ <li><b>UDO</b> undo last editing step</li>
+
+ <li><b>QRY</b> (if enabled in the param tag) allows easy
+ specification of atomic queries for substructure
+ searches</li>
+
+ <li><b>Stereo bonds</b> - the type of stereo bond (up,
+ down) may be changed by clicking on the already created
+ stereo bond; this cycles through two / four possible
+ stereo bond types</li>
+
+ <li><b>Atomic charges</b> may be changed by the
+ <b>+/-</b> button. Editor enables modification of charges
+ only in "reasonable" cases. If you are not satisfied with
+ the editor's inteligence (concerning charges and the
+ explicit number of hydrogens) you can force your will by
+ using the <b>X</b> button</li>
+
+ <li><b>"Non-organic" atoms</b> or atoms with nonstandard
+ valence may be entered with help of <b>X</b> button by
+ specifying atomic SMILES (without [ ] brackets, i.e. Si,
+ Fe++, NH3+).</li>
+ </ul>
+
+ <h3>Keyboard Shortcuts</h3>
+
+ <p>Most of the commands may be accessed also by keyboard
+ shortcuts. It is possible to:</p>
+
+ <ul>
+ <li>change <b>atom type</b> by pressing <b>C</b>,
+ <b>N</b>, <b>O</b>, <b>S</b>, <b>F</b>, <b>L</b> (for Cl)
+ <b>B</b> (for Br) <b>I</b>, <b>P</b>, <b>H</b>, <b>X</b>,
+ <b>R</b> and clicking the respective atom</li>
+
+ <li>choose <b>bond order</b>: <b>-</b> for single bond,
+ <b>=</b> for double bond, <b>#</b> for triple bond</li>
+
+ <li>choose <b>ring type</b> by pressing <b>3</b>,
+ <b>4</b>, <b>5</b>, <b>6</b>, <b>7</b>, <b>8</b>,
+ <b>9</b> or <b>1</b> for phenyl, <b>0</b> for furyl</li>
+
+ <li>start <b>delete mode</b> by pressing <b>D</b> or
+ <b>Del</b> and</li>
+
+ <li>return to the <b>standard state</b> (carbon, single
+ bond) with <b>Esc</b></li>
+ </ul>
+
+ <p><b>common functional groups</b> may also be added by
+ keyboard shortcuts. Use <b>t</b> for t-butyl, <b>ft</b> for
+ trifluoromethyl, <b>lt</b> for trichloromethyl, <b>a</b>
+ for COOH, <b>z</b> for SO2Me and <b>y</b> for nitro, and
+ then click the atom where the group should be
+ connected.</p>
+
+ <h3>Moving and Rotation</h3>
+
+ <p>You can move molecule by "dragging free space" with the
+ left mouse button and rotate it by using the left mouse
+ button and <b>Shift</b> key (or left and right mouse
+ buttons together).</p>
+
+ <h3>Adding rings</h3>
+
+ <p>When a ring template is selected and multivalent atom is
+ clicked, a new ring will be created connected by single
+ bond to this atom. When spiro ring is required, the
+ <b>Shift</b> key must be pressed when clicking on the atom.
+ Spiro ring may be added only to atom with 2 single
+ bonds.</p>
+
+ <h3>Multivalent nitrogen groups</h3>
+
+ <p>Multivalent nitrogen groups, such as nitro, azide,
+ N-oxide, nitrile etc, should be drawn with a pentavalent
+ nitrogen as shown below.</p>
+
+ <p class="c1"><img src="images/nitro.gif" alt=
+ "nitro stuff"></p>
+
+ <p>The program automatically converts polar form of these
+ groups into non-polar one with pentavalent nitrogen. If you
+ prefer polar nitro (and similar) groups, use keyword
+ "polarnitro" in the applet param tag.</p>
+
+ <h3>Stereochemistry</h3>
+
+ <p>Stereochemistry at C4 centers, double bonds and allenes
+ is supported. Use the up/down wedge bonds to indicate
+ stereochemistry at the C4 centers. Remember, that only
+ bonds with a "sharp point" towards the atom are considered.
+ When creating SMILES the editor tries to guess missing
+ stereo features, in unresolvable cases an error message is
+ issued and the SMILES without stereo information is
+ created.</p>
+
+ <p>When the autoez keyword is set, SMILES with E,Z
+ stereochemistry on all non-ring double bonds is generated
+ automatically. Without this keyword (or for ring double
+ bonds) you have to mark a double bond as stereo by clicking
+ on it with the stereo bond button selected. The bond color
+ will change to violet.</p>
+
+ <p>Stereochemistry may be completely disabled by the
+ "nostereo" option in the param tag.</p>
+
+ <h3>Input of Multipart Structures</h3>
+
+ <p>By default only non-disconnected structures are allowed.
+ This may be changed by a "multipart" option in the applet
+ param tag. A button <b>NEW</b> appears in the JME menu.
+ Creation of a new molecule may be started only after
+ clicking the <b>NEW</b> button, selecting a proper template
+ (atom, ring, bond) and clicking free space in the drawing
+ area. Without <b>NEW</b> button the click on the free space
+ has the same effect as in the standard mode (i.e moving or
+ rotation of the last touched molecule). In the multipart
+ mode <b>CLR</b> button deletes the last touched
+ molecule.</p>
+
+ <h3>Atom Numbering</h3>
+
+ <p>Atom numbering (marking) is enabled with the option
+ "number" in the applet param tag (for reaction input this
+ is default). Button <b>123</b> appears in the JME menu. To
+ mark an atom press the <b>123</b> button and then the atom.
+ You can mark more atoms with the same number when pressing
+ <b>Shift</b> while clicking the 2nd and further atoms.
+ Second click on the marked atom deletes the number.</p>
+
+ <h3>Reaction Input</h3>
+
+ <p>Reaction input is enabled with the option "reaction" in
+ the applet param tag. Button with an arrow, <b>NEW</b>
+ button and <b>123</b> button appear in the JME menu and
+ arrow appears also in the drawing area. Now simply draw
+ reactant(s), product(s) and modulator(s) (modulators have
+ to be above the arrow) as explained in the description of
+ input of multipart structures. The arrow button enables
+ simplified input of reactions. After clicking it, the
+ reactant will be copied to the product (including atom
+ numbering, if any). When the <b>Shift</b> is pressed during
+ this action all atoms will be automatically numbered.</p>
+
+ <h3>Query Features</h3>
+
+ <p>Query button (when enabled in the option tag) launches a
+ query window which allows creation of SMARTS atom queries
+ by combining various atom attributes. Create a SMARTS query
+ and then click the respective atom in the
+ molecule.</p>
+</body>
+</html>
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..1f53798
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
diff --git a/public/snake_transparent.gif b/public/snake_transparent.gif
new file mode 100644
index 0000000..c1eb1c9
--- /dev/null
+++ b/public/snake_transparent.gif
Binary files differ
diff --git a/views/classification.haml b/views/classification.haml
new file mode 100644
index 0000000..5c739cf
--- /dev/null
+++ b/views/classification.haml
@@ -0,0 +1,11 @@
+%dl#classification{ :style => "display: none;" }
+ %dt
+ Classification
+ (
+ = hide_link "#classification"
+ )
+ %dd
+ Prediction of
+ %em qualitative
+ properties, e.g. to distinguish between toxic and non-toxic compounds
+
diff --git a/views/classification_validation.haml b/views/classification_validation.haml
new file mode 100644
index 0000000..94ba8f9
--- /dev/null
+++ b/views/classification_validation.haml
@@ -0,0 +1,33 @@
+%dt Correct predictions:
+%dd
+ = sprintf("%.2f", model.correct_predictions) if model.correct_predictions
+ = '%'
+%dt
+ %a{:href => "http://en.wikipedia.org/wiki/Receiver_operating_characteristic", :target => "_blank"} Weighted area under ROC:
+%dd
+ = sprintf("%.3f", model.weighted_area_under_roc) if model.weighted_area_under_roc
+%dt
+ %a{:href => "http://en.wikipedia.org/wiki/Sensitivity_and_specificity", :target => "_blank"} Specificity:
+%dd= sprintf("%.3f", model.specificity) if model.specificity
+%dt
+ %a{:href => "http://en.wikipedia.org/wiki/Sensitivity_and_specificity", :target => "_blank"} Sensitivity:
+%dd= sprintf("%.3f", model.sensitivity) if model.sensitivity
+%dt
+ %a{:href => "http://en.wikipedia.org/wiki/Confusion_matrix", :target => "_blank"} Confusion Matrix:
+%dd
+ %table
+ %tr
+ %td{:colspan => 2, :rowspan => 2}
+ %th{:colspan => 2} Measured
+ %tr
+ %th{:bgcolor => "#CCD2DC"} active
+ %th{:bgcolor => "#CCD2DC"} inactive
+ %tr
+ %th{:rowspan => 2} Predicted
+ %th{:bgcolor => "#CCD2DC"} active
+ %td= model.true_positives if model.true_positives
+ %td= model.false_positives if model.false_positives
+ %tr
+ %th{:bgcolor => "#CCD2DC"} inactive
+ %td= model.false_negatives if model.false_negatives
+ %td= model.true_negatives if model.true_negatives
diff --git a/views/compound_image.haml b/views/compound_image.haml
new file mode 100644
index 0000000..18944dc
--- /dev/null
+++ b/views/compound_image.haml
@@ -0,0 +1,2 @@
+%img{:src => compound.matching_smarts_image_uri(features[:activating].collect{|f| f[:smarts]},features[:deactivating].collect{|f| f[:smarts]}), :alt => compound.to_smiles}
+
diff --git a/views/confidence.haml b/views/confidence.haml
new file mode 100644
index 0000000..2b72d63
--- /dev/null
+++ b/views/confidence.haml
@@ -0,0 +1,7 @@
+%dl#confidence{ :style => "display: none;" }
+ %dt
+ Confidence
+ (
+ = hide_link "#confidence"
+ )
+ %dd Indicates the applicability domain of a model. Predictions with a high confidence can be expected to be more reliable than predictions with low confidence. Confidence values may take any value between 0 and 1. For most models confidence &gt; 0.025 is a sensible (hard) cutoff to distiguish between reliable and unreliable predictions.
diff --git a/views/create.haml b/views/create.haml
new file mode 100644
index 0000000..6563494
--- /dev/null
+++ b/views/create.haml
@@ -0,0 +1,41 @@
+.input
+
+ %p
+ This service creates
+ %ul
+ %li
+ = toggle_link("#lazar_description","lazar")
+ %em= toggle_link("#classification","classification")
+ models and
+ %li
+ = toggle_link("#lazar_description","lazar")
+ %em= toggle_link("#regression","regression")
+ models
+ from your uploaded datasets. Further modelling algorithms will be added in future versions.
+
+ %p
+ Please read the
+ = link_to "instructions for creating training datasets", '/help'
+ before submitting.
+
+ %form{ :action => url_for('/models'), :method => "post", :enctype => "multipart/form-data" }
+ %fieldset
+ -#%label{:for => 'endpoint'} 1. Enter #{toggle_link("#endpoint_description","endpoint")} name and #{toggle_link("#unit","unit")} (for #{toggle_link("#regression","regression")}):
+ -#%input{:type => 'text', :name => 'endpoint', :id => 'endpoint', :size => '50'}
+ -#%br
+ %label{:for => 'file'}
+ Select training dataset in
+ = link_to "Excel", '/help'
+ or
+ = link_to "CSV", '/help'
+ format:
+ %input{:type => 'file', :name => 'file', :id => 'file', :size => '41'}
+ %input{ :type => "submit", :value => "Create model"}
+ = link_to "Cancel", '/create'
+
+ -# explanations
+ = haml :lazar_description, :layout => false
+ = haml :classification, :layout => false
+ = haml :regression, :layout => false
+ = haml :endpoint, :layout => false
+ = haml :unit, :layout => false
diff --git a/views/endpoint.haml b/views/endpoint.haml
new file mode 100644
index 0000000..af06b80
--- /dev/null
+++ b/views/endpoint.haml
@@ -0,0 +1,12 @@
+%dl#endpoint_description{ :style => "display: none;" }
+ %dt
+ Endpoint
+ (
+ = hide_link "#endpoint_description"
+ )
+ %dd
+ Toxic effect that constitutes the outcome of an
+ %em in-vitro,
+ or
+ %em in-vivo
+ expriment, clinical trial or epidemiological study
diff --git a/views/feature_table.haml b/views/feature_table.haml
new file mode 100644
index 0000000..4fa927c
--- /dev/null
+++ b/views/feature_table.haml
@@ -0,0 +1,28 @@
+%table
+ - unless features[:activating].empty?
+ %tr
+ %th
+ activating
+ (
+ %a{:href => "http://www.daylight.com/dayhtml/doc/theory/theory.smarts.html"} SMARTS
+ )
+ %th p value
+ - if features[:activating]
+ - features[:activating].sort{|a,b| b[:p_value] <=> a[:p_value] }.each do |f|
+ %tr
+ %td= f[:smarts]
+ %td= f[:p_value]
+ - unless features[:deactivating].empty?
+ %tr
+ %th
+ deactivating
+ (
+ %a{:href => "http://www.daylight.com/dayhtml/doc/theory/theory.smarts.html"} SMARTS
+ )
+ %th p value
+ - if features[:deactivating]
+ - features[:deactivating].sort{|a,b| b[:p_value] <=> a[:p_value] }.each do |f|
+ %tr
+ %td= f[:smarts]
+ %td= f[:p_value]
+
diff --git a/views/fragment.haml b/views/fragment.haml
new file mode 100644
index 0000000..fa7495d
--- /dev/null
+++ b/views/fragment.haml
@@ -0,0 +1,9 @@
+%form{:name => "form", :action => url_for('/lazar'), :method => "post", :enctype => "multipart/form-data" }
+ %input{:type => :hidden, :name => :compound_uri, :value => compound_uri}
+ %input{:type => :hidden, :name => :model_uri, :value => model_uri}
+ %input{:type => :hidden, :name => :highlight, :value => smarts}
+ - if smarts.nil?
+ %input{ :type => "submit", :value => "Reset"}
+ - else
+ %input{ :type => "submit", :value => smarts}
+
diff --git a/views/help.haml b/views/help.haml
new file mode 100644
index 0000000..eabf978
--- /dev/null
+++ b/views/help.haml
@@ -0,0 +1,104 @@
+= link_to "Back to model creation", '/create'
+%p
+ Input files have two columns. Enter in the first column the chemical structure in
+ %a{:href => "http://en.wikipedia.org/wiki/Simplified_molecular_input_line_entry_specification"} SMILES
+ format, in the second column the toxic activity.
+%dl
+ %dt Classification datasets
+ %dd Please use 1/0, active/inactive or true/false to indicate active/inactive compounds.
+ %dt Regression datasets
+ %dd
+ Enter a quantitative value. For optimal performance you should
+ %ul
+ %li
+ use
+ %a{:href => "http://en.wikipedia.org/wiki/Molar_(concentration)"} molar
+ units
+ %li enter non-logarithmic values (logarithms are taken internally)
+ %li avoid 0 activities (will be ignored)
+%p
+ Input files are accepted in
+ %a{:href => "http://en.wikipedia.org/wiki/Microsoft_Excel"} Excel
+ and
+ %a{:href => "en.wikipedia.org/wiki/Comma-separated_values"} CSV
+ formats.
+
+%h3 Excel example
+
+- n = 0
+
+.code
+ %table
+ %tr
+ %td
+ %th A
+ %th B
+ %tr
+ - n += 1
+ %th= n
+ %td CC(=O)Nc1ccc(O)cc1
+ %td 1
+ %tr
+ - n += 1
+ %th= n
+ %td O=c1[nH]cnc2[nH]ncc12
+ %td 1
+ %tr
+ - n += 1
+ %th= n
+ %td CCCCNc1cc(cc(c1Oc2ccccc2)S(=O)(=O)N)C(=O)O
+ %td 1
+ %tr
+ - n += 1
+ %th= n
+ %td CC(C)(C)NCC(O)COc1cccc2NC(=O)CCc12
+ %td 1
+ %tr
+ - n += 1
+ %th= n
+ %td CN(C)CCCC1(OCc2cc(C#N)ccc21)c3ccc(F)cc3
+ %td 1
+ %tr
+ - n += 1
+ %th= n
+ %td CCC(CC)CCN1C(=O)CN=C(C2CCCCC2F)c3cc(Cl)ccc13
+ %td 0
+ %tr
+ - n += 1
+ %th= n
+ %td CCN(CC)CC(=O)Nc1c(C)cccc1C
+ %td 0
+ %tr
+ - n += 1
+ %th= n
+ %td CC(C)(C)NCC(O)COc1cccc2CC(O)C(O)Cc12
+ %td 0
+ %tr
+ - n += 1
+ %th= n
+ %td CN1CCCC1c2cccnc2
+ %td 0
+
+%p
+ Excel example file for download:
+ = link_to "hamster_carcinogenicity.xls", "/hamster_carcinogenicity.xls"
+
+%h3 CSV example
+
+.code
+ %code
+ %br CC(=O)Nc1ccc(O)cc1, 1
+ %br O=c1[nH]cnc2[nH]ncc12, 1
+ %br CCCCNc1cc(cc(c1Oc2ccccc2)S(=O)(=O)N)C(=O)O, 1
+ %br CC(C)(C)NCC(O)COc1cccc2NC(=O)CCc12, 1
+ %br CN(C)CCCC1(OCc2cc(C#N)ccc21)c3ccc(F)cc3, 1
+ %br CCC(CC)CCN1C(=O)CN=C(C2CCCCC2F)c3cc(Cl)ccc13, 0
+ %br CCN(CC)CC(=O)Nc1c(C)cccc1C, 0
+ %br CC(C)(C)NCC(O)COc1cccc2CC(O)C(O)Cc12, 0
+ %br CN1CCCC1c2cccnc2, 0
+
+%p
+ CSV example for download:
+ = link_to "hamster_carcinogenicity.csv", "/hamster_carcinogenicity.csv"
+
+%p You can create CSV files in Excel: Create a sheet with two columns and export them as CSV file with the "Save As" option from the menu, selecting the CSV (comma delimited) format.
diff --git a/views/js_link.haml b/views/js_link.haml
new file mode 100644
index 0000000..7d8cdce
--- /dev/null
+++ b/views/js_link.haml
@@ -0,0 +1,5 @@
+%a{:href => "#{destination}", :id => "js_link#{@link_id}"} #{name}
+:javascript
+ $("a#js_link#{@link_id}").click(function () {
+ $("#{destination}").#{method}();
+ });
diff --git a/views/layout.haml b/views/layout.haml
new file mode 100644
index 0000000..a3db5e9
--- /dev/null
+++ b/views/layout.haml
@@ -0,0 +1,43 @@
+!!!
+%html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en"}
+
+ %head
+ %meta{'http-equiv' => 'Content-Type', :content => 'text/html'}
+ %title ToxCreate
+ %script{:type => "text/javascript", :src => "javascripts/jquery.js"}
+ %script{:type => "text/javascript", :src => "javascripts/toxcreate.js"}
+ %link{:rel=>'stylesheet', :href=>'stylesheets/style.css', :type => "text/css"}
+
+ %body
+ .logo
+ = image_tag "/ToxCreate_rgb_72.png", :alt => 'ToxCreate', :align => 'right'
+ %br Create and evaluate models to predict toxicity
+ .index
+ %ul
+ %li{:class => ("selected" if /\/create/ =~ request.path )}
+ = link_to "Create", "/create"
+ %li{:class => ("selected" if /models/ =~ request.path )}
+ = link_to "Inspect", "/models"
+ %li{:class => ("selected" if /predict|lazar/ =~ request.path )}
+ = link_to "Predict", "/predict"
+ %li{:class => ("selected" if /help/ =~ request.path )}
+ = link_to "Help", "/help"
+
+ .content
+ - if `hostname`.match(/ot-test/)
+ .notice
+ This service is for testing purposes only - once a week all models will be deleted. Please send bug reports and feature requests to our
+ %a{:href => 'http://github.com/helma/opentox-toxmodel/issues'} issue tracker.
+
+ - if flash[:notice]
+ %p
+ .notice#flashnotice
+ = flash[:notice]
+
+ = yield
+
+ .footer
+ &copy;
+ %a{:href => 'http://www.in-silico.ch'} in silico toxicology
+ 2009-2010, powered by
+ %a{:href => 'http://www.opentox.org'} <span style="color:#5D308A;font-family:arial,sans-serif,helvetica;letter-spacing:-1px;">Open</span><span style="color:#000;font-family:arial,sans-serif,helvetica;font-weight:bold;letter-spacing:-1px;position:relative;">Tox</span>
diff --git a/views/lazar.haml b/views/lazar.haml
new file mode 100644
index 0000000..a46f82c
--- /dev/null
+++ b/views/lazar.haml
@@ -0,0 +1,58 @@
+%p= link_to "New prediction", "/predict"
+.lazar-predictions
+
+ -# explanations
+ = haml :lazar_algorithm, :layout => false
+ = haml :confidence, :layout => false
+ = haml :similarity, :layout => false
+ = haml :significant_fragments, :layout => false
+ = haml :training_data, :layout => false
+
+ %a{:name => "prediction"}
+ %table
+ %thead
+ %tr
+ %th= @prediction.title
+ %th= toggle_link("#lazar_algorithm","Prediction")
+ %th= toggle_link("#confidence","Confidence")
+ %th Supporting information
+
+ %tr
+ -# %td
+ %img{:src => @compound.to_image_uri, :alt => @compound.to_smiles}
+ %td.image= compound_image(@compound,@prediction.descriptors(@compound))
+ %td= activity_markup(@prediction.value(@compound))
+ %td= sprintf('%.03g', @prediction.confidence(@compound))
+ -#%td= @prediction.confidence(@compound)
+ %td
+ %ul
+ %li
+ %a{:href => "#prediction", :id => "show_names"} Names and synonyms
+ :javascript
+ $("a#show_names").click(function () {
+ $("#compound_names").load("#{File.join("/compound",@compound.inchi)}");
+ $("tr#names").toggle();
+ });
+ %li= toggle_link("#fragments","Significant fragments")
+ -# This does not work, ask nina/vedrin
+ -# %li
+ %a{:href => "http://ambit.uni-plovdiv.bg:8080/ambit2/query/structure/?search=#{@compound.smiles}"} Ambit data
+ -# %li
+ %a{:href => "http://www.ncbi.nlm.nih.gov/sites/entrez?cmd=PureSearch&db=pccompound&term=#{URI.encode('"'+@compound.inchi+'"[InChI]')}"} PubChem data
+ (external)
+ -# %li
+ %a{:href => "http://chem.sis.nlm.nih.gov/chemidplus/direct.jsp?result=advanced&inchi=#{URI.encode @compound.inchi}"} ToxNet data
+ -#http://chem.sis.nlm.nih.gov/chemidplus/direct.jsp?result=advanced&regno=000143157
+
+ %tr#names{ :style => "display: none;" }
+ %td{:colspan => '4'}
+ %a{:name => 'names'}
+ = hide_link('#names')
+ #compound_names
+ %tr#fragments{ :style => "display: none;" }
+ %td{:colspan => '4'}
+ = hide_link('#fragments')
+ = haml :feature_table, :locals => {:features => sort(@prediction.descriptors(@compound))}, :layout => false
+
+ %tbody#neighbors
+ = haml :neighbors, :locals => {:neighbors => @prediction.neighbors(@compound), :page => @page}, :layout => :false
diff --git a/views/lazar_algorithm.haml b/views/lazar_algorithm.haml
new file mode 100644
index 0000000..b83de6b
--- /dev/null
+++ b/views/lazar_algorithm.haml
@@ -0,0 +1,50 @@
+%dl#lazar_algorithm
+ %dt
+ %code lazar
+ prediction
+ (
+ = hide_link "#lazar_algorithm"
+ )
+ %dd
+ %p
+ %code lazar
+ searches the training dataset for
+ = toggle_link "#similarity", "similar"
+ compounds
+ %em (neighbors)
+ and calculates the prediction from their measured activities.
+ %code lazar
+ calculates predictions using
+ %ul
+ %li
+ a majority vote (weighted by compound similarity) for
+ %em classification
+ (
+ %a{:href => "http://www.in-silico.de/articles/modi020905.pdf"} original publication
+ )
+ %li
+ a local QSAR model based on neighbors for
+ %em regression
+ (
+ %a{:href => "http://www.in-silico.de/articles/mh_tf.pdf"} original publication
+ )
+
+ %p
+ = toggle_link "#significant_fragments", "Significant fragments"
+ are highlighted in the structure display as follows:
+ %ul
+ %li
+ .active activating fragments
+ %li
+ .inactive deactivating fragments
+ %li
+ .inconclusive regions, where activating and deactivating fragments overlap
+ %li
+ .other inert parts
+
+ %p
+ Please keep in mind that predictions are based on the measured activities of neighbors.
+ = toggle_link "#significant_fragments", "Significant fragments"
+ are solely used to determine
+ = toggle_link "#similarity", "activity specific similarities"
+ of neighbors.
diff --git a/views/lazar_description.haml b/views/lazar_description.haml
new file mode 100644
index 0000000..d870425
--- /dev/null
+++ b/views/lazar_description.haml
@@ -0,0 +1,29 @@
+%dl#lazar_description{ :style => "display: none;" }
+ %dt
+ %code lazar
+ (
+ = hide_link "#lazar_description"
+ )
+ %dd
+ %p
+ %code lazar
+ searches the training dataset for
+ = toggle_link "#similarity", "similar"
+ compounds
+ %em (neighbors)
+ and calculates the prediction from their measured activities.
+ %code lazar
+ calculates predictions using
+ %ul
+ %li
+ a majority vote (weighted by compound similarity) for
+ %em= toggle_link("#classification","classification")
+ (
+ %a{:href => "http://www.in-silico.de/articles/modi020905.pdf"} original publication
+ )
+ %li
+ a local QSAR model based on neighbors for
+ %em= toggle_link("#regression","regression")
+ (
+ %a{:href => "http://www.in-silico.de/articles/mh_tf.pdf"} original publication
+ )
diff --git a/views/model.haml b/views/model.haml
new file mode 100644
index 0000000..d34079d
--- /dev/null
+++ b/views/model.haml
@@ -0,0 +1,67 @@
+- uri = url_for("/model/#{model.id}", :full)
+- js = "$('#delete_#{model.id}').deleteModel('DELETE', {elem: '#model_#{model.id}'});\n " + "$('#show_model_#{model.id}_warnings').toggleWarnings('#{model.id}');"
+:javascript
+ $(function() {
+ #{js}
+ });
+
+%div{:id => "model_#{model.id}"}
+ %h2
+ = model.name
+ .model
+ %dl
+ %dt Status:
+ %dd
+ %span{:id => "model_#{model.id}_status", :class => model.status}
+ = haml :model_status, :locals=>{:model=>model}, :layout => false
+ (
+ %a{:href => url_for("/model/#{model.id}"), :id => "delete_#{model.id}", :class => 'delete'} delete
+ )
+ %dt Started:
+ %dd= model.created_at.strftime("%m/%d/%Y - %I:%M:%S%p")
+ - if model.nr_compounds
+ %dt Training compounds:
+ %dd= model.nr_compounds
+ - if model.error_messages
+ %dt Errors:
+ %dd= model.error_messages
+ - if model.warnings
+ %dt Warnings:
+ %a{:href => "#", :id => "show_model_#{model.id}_warnings"} show
+ %dd{:id => "model_#{model.id}_warnings", :style => "display: none;"}= model.warnings
+ %dt Algorithm:
+ %dd= toggle_link("#lazar_description","lazar")
+ - if model.type
+ %dt Type:
+ %dd= toggle_link("##{model.type}","#{model.type}")
+ %dt Descriptors:
+ %dd
+ %a{:href => 'http://www.maunz.de/libfminer2-bbrc-doc/'} Fminer backbone refinement classes
+ - if model.training_dataset
+ %dt Training dataset:
+ %dd
+ %a{:href => "#{model.training_dataset}.xls"} Excel sheet
+ ,
+ -#%a{:href => "#{model.training_dataset}.rdf"} RDF/XML
+ -#%em (experts) ,
+ %a{:href => "#{model.training_dataset}.yaml"} YAML
+ %em (experts)
+ - if model.feature_dataset
+ %dt Feature dataset:
+ %dd
+ -#%a{:href => "#{model.feature_dataset}.rdf"} RDF/XML
+ -#,
+ %a{:href => "#{model.feature_dataset}.xls"} Excel sheet
+ ,
+ %a{:href => "#{model.feature_dataset}.yaml"} YAML
+ %em (experts)
+ - if model.uri
+ %dt Model:
+ %dd
+ -#%a{:href => "#{model.uri}.rdf"} RDF/XML
+ -#,
+ - if model.validation_qmrf_uri
+ %a{:href => File.join(model.validation_qmrf_uri,"editor")} QMRF Editor,
+ %a{:href => "#{model.uri}.yaml"} YAML
+ %em (experts, models cannot be represented in Excel)
+ = haml :validation, :locals=>{:model=>model}, :layout => false
diff --git a/views/model_status.haml b/views/model_status.haml
new file mode 100644
index 0000000..897e792
--- /dev/null
+++ b/views/model_status.haml
@@ -0,0 +1,2 @@
+-#= image_tag("/snake_transparent.gif") if model.status.match(/running|started|created/i)
+= model.status
diff --git a/views/models.haml b/views/models.haml
new file mode 100644
index 0000000..17d9c8a
--- /dev/null
+++ b/views/models.haml
@@ -0,0 +1,21 @@
+- stati = @models.map{|m| "#{m.id}" if m.status != "Completed"}.compact
+- stati_to_check = stati.length > 0 ? stati.join(", ") : stati = 0
+:javascript
+ $(function() {
+ if(#{stati != 0}) {
+ setTimeout('checkStati("#{stati_to_check}")',1500);
+ }
+ var reload_validation = true;
+ if(reload_validation) setTimeout('checkValidation()',15000);
+ });
+
+-# %p Get an overview about ToxCreate models. This page is refreshed every 15 seconds to update the model status.
+%p Get an overview about ToxCreate models. This page is refreshed every 5 seconds to update the model status.
+
+-# explanations
+= haml :lazar_description, :layout => false
+= haml :classification, :layout => false
+= haml :regression, :layout => false
+
+- @models.each do |model|
+ = haml :model, :locals=>{:model=>model}, :layout => false
diff --git a/views/neighbors.haml b/views/neighbors.haml
new file mode 100644
index 0000000..87fef13
--- /dev/null
+++ b/views/neighbors.haml
@@ -0,0 +1,44 @@
+%tr
+ %th
+ Neighbors
+ = neighbors_navigation
+ %th= toggle_link("#training_data","Measured activity")
+ %th= toggle_link("#similarity","Similarity")
+ %th Supporting information
+
+- first = 5*page
+- last = first+4
+- neighbor_id = 0
+-# LOGGER.debug neighbors.to_yaml
+- neighbors.sort{|a,b| b[OT.similarity] <=> a[OT.similarity]}[first..last].each do |neighbor|
+ - neighbor_id += 1
+ - compound = OpenTox::Compound.new(neighbor[OT.compound])
+ %tr
+ %td.image= compound_image(compound,@prediction.descriptors(compound))
+ %td= activity_markup(neighbor[OT.activity])
+ %td= sprintf('%.03g', neighbor[OT.similarity])
+ %td
+ %ul
+ %li
+ %a{:href => "#prediction", :id => "show_names#{neighbor_id}"} Names and synonyms
+ :javascript
+ $("a#show_names#{neighbor_id}").click(function () {
+ $("#compound_names#{neighbor_id}").load("#{File.join("compound",compound.inchi)}");
+ $("#names#{neighbor_id}").toggle();
+ });
+ %li= toggle_link("#fragments#{neighbor_id}","Significant fragments")
+ -#%li Ambit data
+ -# %li
+ %a{:href => "http://www.ncbi.nlm.nih.gov/sites/entrez?cmd=PureSearch&db=pccompound&term=#{URI.encode('"'+compound.inchi+'"[InChI]')}"} PubChem data
+ (external)
+ -# %li ToxNet data
+
+ %tr{:id => "names#{neighbor_id}", :style => "display: none;" }
+ %td{:colspan => '4'}
+ = hide_link("#names#{neighbor_id}")
+ %div{:id => "compound_names#{neighbor_id}"}
+ %tr{:id => "fragments#{neighbor_id}", :style => "display: none;" }
+ %td{:colspan => '4'}
+ = hide_link("#fragments#{neighbor_id}")
+ = haml :feature_table, :locals => {:features => sort(@prediction.descriptors(compound))}, :layout => false
+
diff --git a/views/neighbors_navigation.haml b/views/neighbors_navigation.haml
new file mode 100644
index 0000000..864a99f
--- /dev/null
+++ b/views/neighbors_navigation.haml
@@ -0,0 +1,22 @@
+.neighbors_navigation
+
+ %form{:name => "nav", :action => url_for('/lazar#prediction'), :method => "post", :enctype => "multipart/form-data", :id => "nav"}
+ %input{:type => :hidden, :name => :compound_uri, :value => @compound.uri}
+ %input{:type => :hidden, :name => :model_uri, :value => @model_uri}
+ %input{:type => :hidden, :name => :page, :id => "page"}
+
+ #prev= "prev" unless @page.to_i == 0
+
+ = "(#{5*@page+1}-#{5*@page+5}/#{@prediction.neighbors(@compound).size})"
+
+ #next= "next" unless 5*@page.to_i+5 >= @prediction.neighbors(@compound).size
+
+ :javascript
+ $("#prev").click(function() {
+ $("#page").val(#{@page-1});
+ $("#nav").submit();
+ });
+ $("#next").click(function() {
+ $("#page").val(#{@page+1});
+ $("#nav").submit();
+ });
diff --git a/views/predict.haml b/views/predict.haml
new file mode 100644
index 0000000..26c8094
--- /dev/null
+++ b/views/predict.haml
@@ -0,0 +1,34 @@
+:javascript
+ function getsmiles() {
+ if (document.JME.smiles() != '') {
+ document.form.identifier.value = document.JME.smiles() ;
+ }
+ }
+
+.input
+ %p Use this service to obtain predictions from OpenTox models.
+ - unless @models.empty?
+
+ %form{:name => "form", :action => url_for('/predict'), :method => "post", :enctype => "multipart/form-data" }
+ %fieldset
+ %legend Draw a compound
+ %label &nbsp;
+ .jme
+ %applet{:code => "JME.class", :name => "JME", :archive => "JME.jar", :width => "500", :height => "360"}
+ %param{ :name => "options", :value => "polarnitro"}
+ Please enable Java and JavaScript in your browser to use the JME editor.
+
+ %label{:for => 'identifier'} or enter a Name, InChI, Smiles, CAS, ...
+ %input{:type => 'text', :name => 'identifier', :id => 'identifier', :size => '60'}
+ %fieldset
+ %legend
+ Choose one or more prediction models
+ - @models.each do |model|
+ %label{:for => model.id}
+ = model.name
+ %input{:type => 'checkbox', :name => "selection[#{model.id}]", :value => true, :id => model.id}
+ %br
+
+ %input{ :type => "submit", :value => "Predict", :onclick => "getsmiles();"}
+ = link_to 'Cancel', '/predict'
+
diff --git a/views/prediction.haml b/views/prediction.haml
new file mode 100644
index 0000000..8498abc
--- /dev/null
+++ b/views/prediction.haml
@@ -0,0 +1,50 @@
+%p
+ = link_to "New prediction", "/predict"
+.predictions
+ %table
+ %tr
+ %th{:colspan => @predictions.size+1}
+ = @identifier
+ %tr
+ %td
+ %img{:src => @compound.to_image_uri, :alt => @compound.to_smiles}
+ - @predictions.each do |p|
+ - LOGGER.debug p.to_yaml
+ %td
+ %b
+ = p[:title] + ":"
+ - if p[:measured_activities]
+ %br
+ - p[:measured_activities].each do |a|
+ = activity_markup(a)
+ %br
+ (
+ %a{:href => "#", :id => "linkTrainingData#{p.object_id}"} Measured activity
+ :javascript
+ $("a#linkTrainingData#{p.object_id}").click(function () {
+ $("dl#training_data").toggle();
+ });
+ )
+
+ - elsif p[:error]
+ %br= p[:error]
+ - else
+ = activity_markup(p[:prediction])
+ - if p[:confidence]
+ %br
+ (
+ %a{:href => "#", :id => "linkConfidence#{p.object_id}"} Confidence
+ = ": #{sprintf('%.03g', p[:confidence].to_f.abs)}"
+ :javascript
+ $("a#linkConfidence#{p.object_id}").click(function () {
+ $("dl#confidence").toggle();
+ });
+ )
+ %br
+ %form{:name => "form", :action => url_for('/lazar'), :method => "post", :enctype => "multipart/form-data" }
+ %input{:type => :hidden, :name => :compound_uri, :value => @compound.uri}
+ %input{:type => :hidden, :name => :model_uri, :value => p[:model_uri]}
+ %input{ :type => "submit", :value => "Details"}
+
+= haml :confidence, :layout => false
+= haml :training_data, :layout => false
diff --git a/views/regression.haml b/views/regression.haml
new file mode 100644
index 0000000..4866b08
--- /dev/null
+++ b/views/regression.haml
@@ -0,0 +1,11 @@
+%dl#regression{ :style => "display: none;" }
+ %dt
+ Regression
+ (
+ = hide_link "#regression"
+ )
+ %dd
+ Prediction of
+ %em quantitative
+ properties, e.g. LC50 values
+
diff --git a/views/regression_validation.haml b/views/regression_validation.haml
new file mode 100644
index 0000000..00267a9
--- /dev/null
+++ b/views/regression_validation.haml
@@ -0,0 +1,9 @@
+%dt
+ %a{:href => "http://en.wikipedia.org/wiki/R-squared"} R-squared
+%dd= sprintf '%.03g', model.r_square
+%dt
+ %a{:href => "http://en.wikipedia.org/wiki/Root_mean_square_deviation"} Root Mean Square Error
+%dd= sprintf '%.03g', model.root_mean_squared_error
+%dt
+ %a{:href => "http://en.wikipedia.org/wiki/Mean_absolute_error"} Mean Absolute Error
+%dd= sprintf '%.03g', model.mean_absolute_error
diff --git a/views/significant_fragments.haml b/views/significant_fragments.haml
new file mode 100644
index 0000000..87cb113
--- /dev/null
+++ b/views/significant_fragments.haml
@@ -0,0 +1,10 @@
+%dl#significant_fragments{ :style => "display: none;" }
+ %dt
+ Significant fragments
+ (
+ = hide_link "#significant_fragments"
+ )
+ %dd
+ Substructures that occur (statistically significant) more frequently in active or inactive compounds. Substuctures can take any shape (without cycles) and are determined with the
+ %a{:href => "http://www.maunz.de/libfminer2-bbrc-doc/"} fminer
+ algorithm.
diff --git a/views/similarity.haml b/views/similarity.haml
new file mode 100644
index 0000000..659eb50
--- /dev/null
+++ b/views/similarity.haml
@@ -0,0 +1,19 @@
+%dl#similarity{ :style => "display: none;" }
+ %dt
+ Similarity
+ (
+ = hide_link "#similarity"
+ )
+ %dd
+ %code lazar
+ calculates
+ %em activity specific
+ similarities based on the presence of statistically
+ = toggle_link "#significant_fragments", "significant fragments"
+ This procedure will
+ %ul
+ %li consider only those parts of a chemical structure that are relevant for a particular endpoint
+ %li ignore inert parts of the structure
+ %li lead to different similarities, depending on the toxic endpoint
+ Similarities of 1 may be encountered even for structurally dissimilar compounds, because inert parts are ignored.
+
diff --git a/views/style.sass b/views/style.sass
new file mode 100644
index 0000000..5f362a3
--- /dev/null
+++ b/views/style.sass
@@ -0,0 +1,239 @@
+$bg_color: #b9dcff
+$bg_color2: #e5e7eb
+$fg_color: #424345
+$ot_purple: #5d308a
+$body_color: white
+$text_color: black
+$notice_border: black
+
+body
+ min-width: 30em
+ font-family: verdana, arial, helvetica, sans-serif
+ background-color: $body_color
+ color: $text_color
+ padding: 1em
+ a
+ text-decoration: none
+ font-weight: bold
+ color: $ot_purple
+ a:hover
+ color: black
+
+ .headline
+ .logo
+ float: right
+
+ .index
+ clear: both
+ ul
+ margin: 0 0 2px 0
+ padding: 0
+ white-space: nowrap
+ list-style-type: none
+ li
+ margin: 0
+ padding: 2px
+ display: inline
+ border-right: 1px solid
+ color: $body_color
+ border-top: 1px solid
+ color: $body_color
+ background-color: $fg_color
+ padding-left: 0.5em
+ padding-right: 0.5em
+ font-weight: bold
+ a
+ text-decoration: none
+ color: $bg_color
+ &:hover
+ color: $body_color
+ li.selected
+ font-weight: bold
+ background-color: $bg_color
+ border: 1px solid
+ color: $fg_color
+ border-bottom: 1px solid
+ color: $bg_color
+ a
+ color: $text_color
+
+ .content
+ background-color: $bg_color
+ height: 100%
+ padding: 1em
+ border: 1px solid
+ color: $fg_color
+ h2
+ margin: 20px 3px 2px 3px
+ .notice
+ padding: 1em
+ background-color: $body_color
+ border: 1px solid
+ border-color: $notice_border
+ .input
+ text-align: left
+ form
+ padding: 1em
+ background-color: $bg_color2
+ border: 1px solid
+ color: $fg_color
+ fieldset
+ margin: 0
+ padding: 0
+ border: 0
+ legend
+ font-weight: bold
+ color: $fg_color
+ label
+ width: 28em
+ display: block
+ float: left
+ br
+ clear: both
+ .code
+ border: 1px solid black
+ padding: 1%
+ background-color: white
+ table
+ display: inline-table
+ border-collapse: collapse
+ th
+ padding: 0.5em
+ border: 1px solid
+ background-color: #ccd2dc
+ td
+ padding: 0.5em
+ border: 1px solid
+
+ .predictions
+ text-align: center
+ overflow: auto
+ table
+ border-spacing: 0
+ border-collapse: collapse
+ margin: 0
+ th
+ color: $body_color
+ background-color: $fg_color
+ border: 1px solid
+ margin: 0.5em
+ td
+ border: 1px solid
+ background-color: $bg_color2
+ padding: 0.5em
+ img
+ padding: 0
+ height: 100%
+
+ .lazar-predictions
+ clear: both
+ margin-top: 2%
+ .neighbors_navigation
+ font-size: x-small
+ #prev
+ @extend a
+ display: inline
+ cursor: pointer
+ #next
+ @extend a
+ display: inline
+ cursor: pointer
+
+ dt
+ font-weight: bold
+ table
+ width: 100%
+ //height: 100%
+ background-color: $bg_color2
+ border-spacing: 0
+ border-collapse: collapse
+ margin: 0
+ tbody
+ //height: 10em
+ th
+ text-align: center
+ border: 1px solid
+ color: $body_color
+ background-color: $fg_color
+ margin: 0.5em
+ a
+ text-decoration: underline
+ font-weight: bold
+ color: $bg_color
+
+ a:hover
+ color: $bg_color2
+ td
+ border: 1px solid
+ overflow: auto
+ ul
+ list-style-type: none
+ td.image
+ padding: 0
+ width: 150px
+ height: 150px
+
+ table
+ font-size: x-small
+ td
+ border: none
+ td.selected
+ background-color: blue
+ //overflow-y: scroll;
+
+ .model
+ padding: 0em 1em
+ background-color: $bg_color2
+ border: 1px solid
+ margin-top: 0.6em
+ dl
+ dt
+ width: 15em
+ font-weight: bold
+ float: left
+ clear: both
+ dd
+ clear: right
+ margin: 0.2em 0em
+ dl
+ clear: both
+ padding: 0em
+ background-color: $bg_color2
+ border: 0
+ dt
+ white-space: nowrap
+ width: 16em
+ font-weight: bold
+ float: left
+ clear: right
+
+ .footer
+ margin: 0.5em
+ padding: 0.5em
+
+.active
+ color: red
+
+.inactive
+ color: green
+
+.inconclusive
+ color: yellow
+
+.other
+ color: black
+
+dl
+ dd
+ td
+ border: 1px dotted white
+ text-align: right
+ padding: 0.2em
+ .blank
+ border: 0
+ th
+ border-bottom: 1px dotted white
+ text-align: center
+ padding: 0.3em
+ table
+ border-collapse: collapse
diff --git a/views/training_data.haml b/views/training_data.haml
new file mode 100644
index 0000000..0593776
--- /dev/null
+++ b/views/training_data.haml
@@ -0,0 +1,7 @@
+%dl#training_data{ :style => "display: none;" }
+ %dt
+ Measured activity
+ (
+ = hide_link "#training_data"
+ )
+ %dd Experimental result(s) from the training dataset.
diff --git a/views/unit.haml b/views/unit.haml
new file mode 100644
index 0000000..a352599
--- /dev/null
+++ b/views/unit.haml
@@ -0,0 +1,10 @@
+%dl#unit{ :style => "display: none;" }
+ %dt
+ Unit
+ (
+ = hide_link "#unit"
+ )
+ %dd
+ Unit of measurement, e.g. mmol or mmol/kg-bodyweight. For optimal performance you should use
+ %a{:href => "http://en.wikipedia.org/wiki/Molar_(concentration)"} molar
+ units.
diff --git a/views/validation.haml b/views/validation.haml
new file mode 100644
index 0000000..5fc7371
--- /dev/null
+++ b/views/validation.haml
@@ -0,0 +1,23 @@
+- if model.validation_uri
+ %dl{:id => "model_validation_#{model.id}"}
+ %dt
+ Validation:
+ -# %input{ :id => "model_validation_report_#{model.id}", :type => "hidden", :value => "#{model.validation_report_status}", :class => "model_validation_report" }
+ %dd
+ %dl
+ - if model.validation_report_uri
+ %dt Detailed report:
+ %dd
+ %a{:href => model.validation_report_uri, :target => "_blank"} show
+ %dt Number of predictions
+ %dd= model.nr_predictions
+ - case model.type
+ - when "classification"
+ = haml :classification_validation, :locals=>{:model=>model}, :layout => false if model.correct_predictions
+ - when "regression"
+ = haml :regression_validation, :locals=>{:model=>model}, :layout => false
+-# else
+ = image_tag("/snake_transparent.gif") if model.validation_status == "Running"
+ %a{:href => model.validation_task_uri} #{model.validation_status}
+
+