galaxy-commits
  Threads by month 
                
            - ----- 2025 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
March 2014
- 1 participants
- 170 discussions
 
                        
                    
                        
                            
                                
                            
                            commit/galaxy-central: martenson: libraries: refactor into separate files for model/views/main+router, showing infoicon for public libraries
                        
                        
by commits-noreply@bitbucket.org 24 Mar '14
                    by commits-noreply@bitbucket.org 24 Mar '14
24 Mar '14
                    
                        1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/68d35caf407f/
Changeset:   68d35caf407f
User:        martenson
Date:        2014-03-24 20:12:48
Summary:     libraries: refactor into separate files for model/views/main+router, showing infoicon for public libraries
Affected #:  12 files
diff -r 33cc6056d83760e5e3b98999b01ecb260423d33c -r 68d35caf407f367c3447a1a6675d6705c8daacf4 lib/galaxy/webapps/galaxy/api/libraries.py
--- a/lib/galaxy/webapps/galaxy/api/libraries.py
+++ b/lib/galaxy/webapps/galaxy/api/libraries.py
@@ -55,10 +55,12 @@
         libraries = []
         for library in query:
             item = library.to_dict( view='element', value_mapper={ 'id' : trans.security.encode_id , 'root_folder_id' : trans.security.encode_id } )
+            if trans.app.security_agent.library_is_public( library, contents=False ):
+                item[ 'public' ] = True
             libraries.append( item )
         return libraries
 
-    @expose_api
+    @expose_api_anonymous
     def show( self, trans, id, deleted='False', **kwd ):
         """
         show( self, trans, id, deleted='False', **kwd )
@@ -139,6 +141,9 @@
 
        .. note:: Currently, only admin users can update libraries. Also the library must not be `deleted`.
 
+        :param  id:      the encoded id of the library
+        :type   id:      an encoded id string
+
         :param  payload: (required) dictionary structure containing::
             'name':         new library's name, cannot be empty
             'description':  new library's description
@@ -192,7 +197,7 @@
         .. note:: Currently, only admin users can un/delete libraries.
 
         :param  id:     the encoded id of the library to un/delete
-        :type   id:     str
+        :type   id:     an encoded id string
 
         :param  undelete:    (optional) flag specifying whether the item should be deleted or undeleted, defaults to false:
         :type   undelete:    bool
diff -r 33cc6056d83760e5e3b98999b01ecb260423d33c -r 68d35caf407f367c3447a1a6675d6705c8daacf4 static/scripts/galaxy.library.js
--- a/static/scripts/galaxy.library.js
+++ b/static/scripts/galaxy.library.js
@@ -1,1192 +1,26 @@
-// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
-// === GALAXY LIBRARY MODULE ====
-// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
+// === MAIN GALAXY LIBRARY MODULE ====
+// MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
 
 // global variables
-var view            = null;
 var library_router  = null;
-var responses = [];
 
 // dependencies
 define([
     "galaxy.masthead", 
     "utils/utils",
-    "libs/toastr"], function(mod_masthead, mod_utils, mod_toastr) {
-
-// MMMMMMMMMMMMMMM
-// === Models ====
-// MMMMMMMMMMMMMMM
-
-    // LIBRARY
-    var Library = Backbone.Model.extend({
-      urlRoot: '/api/libraries/'
-    });
-
-    // FOLDER AS MODEL
-    var FolderAsModel = Backbone.Model.extend({
-      urlRoot: '/api/folders'
-    });
-
-    // LIBRARIES
-    var Libraries = Backbone.Collection.extend({
-      url: '/api/libraries',
-
-      model: Library,
-
-      sort_key: 'name', // default
-
-      sort_order: null, // default
-
-    });
-
-    // ITEM
-    var Item = Backbone.Model.extend({
-        urlRoot : '/api/libraries/datasets'
-    });
-
-    // FOLDER AS COLLECTION
-    var Folder = Backbone.Collection.extend({
-      model: Item
-    });
-
-    // CONTAINER for folder contents (folders, items and metadata).
-    var FolderContainer = Backbone.Model.extend({
-        defaults : {
-            folder : new Folder(),
-            full_path : "unknown",
-            urlRoot : "/api/folders/",
-            id : "unknown"
-        },
-    parse : function(obj) {
-      this.full_path = obj[0].full_path;
-          // update the inner collection
-          this.get("folder").reset(obj[1].folder_contents);
-          return obj;
-      }
-    });
-
-    // HISTORY ITEM
-    var HistoryItem = Backbone.Model.extend({
-        urlRoot : '/api/histories/'
-    });
-
-    // HISTORY
-    var GalaxyHistory = Backbone.Model.extend({
-        url : '/api/histories/'
-    });
-
-    // HISTORIES
-    var GalaxyHistories = Backbone.Collection.extend({
-        url : '/api/histories',
-        model : GalaxyHistory
-    });
-
-// MMMMMMMMMMMMMM
-// === VIEWS ====
-// MMMMMMMMMMMMMM
-
-//main view for folder browsing
-var FolderContentView = Backbone.View.extend({
-    // main element definition
-    el : '#center',
-    // progress percentage
-    progress: 0,
-    // progress rate per one item
-    progressStep: 1,
-    // last selected history in modal for UX
-    lastSelectedHistory: '',
-    // self modal
-    modal : null,
-    // loaded folders
-    folders : null,
-
-    // initialize
-    initialize : function(){
-        this.folders = [];
-        this.queue = jQuery.Deferred();
-        this.queue.resolve();
-    },
-
-// MMMMMMMMMMMMMMMMMM
-// === TEMPLATES ====
-// MMMMMMMMMMMMMMMMMM
-
-    // main template for folder browsing
-    templateFolder : function (){
-        var tmpl_array = [];
-
-        // CONTAINER
-        tmpl_array.push('<div class="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');
-        tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
-
-        // TOOLBAR
-        tmpl_array.push('<div id="library_folder_toolbar" >');
-        tmpl_array.push('   <button title="Create New Folder" id="toolbtn_create_folder" class="primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');
-        tmpl_array.push('   <button title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-book"></span> to history</button>');
-        tmpl_array.push('   <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');
-        tmpl_array.push('       <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');
-        tmpl_array.push('       <span class="fa fa-download"></span> download <span class="caret"></span>');
-        tmpl_array.push('       </button>');
-        tmpl_array.push('       <ul class="dropdown-menu" role="menu">');
-        tmpl_array.push('          <li><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');
-        tmpl_array.push('          <li><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');
-        tmpl_array.push('          <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');
-        tmpl_array.push('       </ul>');
-        tmpl_array.push('   </div>');
-
-        tmpl_array.push('</div>');
-
-        // BREADCRUMBS
-        tmpl_array.push('<ol class="breadcrumb">');
-        tmpl_array.push('   <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');
-        tmpl_array.push('   <% _.each(path, function(path_item) { %>');
-        tmpl_array.push('   <% if (path_item[0] != id) { %>');
-        tmpl_array.push('   <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');
-        tmpl_array.push(    '<% } else { %>');
-        tmpl_array.push('   <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');
-        tmpl_array.push('   <% } %>');
-        tmpl_array.push('   <% }); %>');
-        tmpl_array.push('</ol>');
-
-
-        // FOLDER CONTENT
-        tmpl_array.push('<table id="folder_table" class="grid table table-condensed">');
-        tmpl_array.push('   <thead>');
-        tmpl_array.push('       <th class="button_heading"></th>');
-        tmpl_array.push('       <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');
-        tmpl_array.push('       <th>name</th>');
-        tmpl_array.push('       <th>data type</th>');
-        tmpl_array.push('       <th>size</th>');
-        tmpl_array.push('       <th>date (UTC)</th>');
-        tmpl_array.push('   </thead>');
-        tmpl_array.push('   <tbody>');
-        tmpl_array.push('       <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');
-        tmpl_array.push('       <td></td>');
-        tmpl_array.push('       <td></td>');
-        tmpl_array.push('       <td></td>');
-        tmpl_array.push('       <td></td>');
-        tmpl_array.push('       <td></td>');
-        tmpl_array.push('       </tr>');
-        tmpl_array.push('       <% _.each(items, function(content_item) { %>');
-        tmpl_array.push('           <% if (content_item.get("type") === "folder") { %>'); // folder
-        tmpl_array.push('               <tr class="folder_row light" id="<%- content_item.id %>">');
-        tmpl_array.push('                   <td>');
-        tmpl_array.push('                       <span title="Folder" class="fa fa-folder-o"></span>');
-        tmpl_array.push('                   </td>');
-        tmpl_array.push('                   <td></td>');
-        tmpl_array.push('                   <td>');
-        tmpl_array.push('                       <a href="#folders/<%- content_item.id %>"><%- content_item.get("name") %></a>');
-        tmpl_array.push('                       <% if (content_item.get("item_count") === 0) { %>'); // empty folder
-        tmpl_array.push('                           <span class="muted">(empty folder)</span>');
-        tmpl_array.push('                       <% } %>');
-        tmpl_array.push('                   </td>');
-        tmpl_array.push('                   <td>folder</td>');
-        tmpl_array.push('                   <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>'); // size
-        tmpl_array.push('                   <td><%= _.escape(content_item.get("time_updated")) %></td>'); // time updated
-        tmpl_array.push('               </tr>');
-        tmpl_array.push('           <% } else {  %>');
-        tmpl_array.push('               <tr class="dataset_row light" id="<%- content_item.id %>">');
-        tmpl_array.push('                   <td>');
-        tmpl_array.push('                       <span title="Dataset" class="fa fa-file-o"></span>');
-        tmpl_array.push('                   </td>');
-        tmpl_array.push('                   <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');
-        tmpl_array.push('                   <td><a href="#" class="library-dataset"><%- content_item.get("name") %><a></td>'); // dataset
-        tmpl_array.push('                   <td><%= _.escape(content_item.get("data_type")) %></td>'); // data type
-        tmpl_array.push('                   <td><%= _.escape(content_item.get("readable_size")) %></td>'); // size
-        tmpl_array.push('                   <td><%= _.escape(content_item.get("time_updated")) %></td>'); // time updated
-        tmpl_array.push('               </tr>');
-        tmpl_array.push('               <% } %>  ');
-        tmpl_array.push('       <% }); %>');
-        tmpl_array.push('       ');
-        tmpl_array.push('   </tbody>');
-        tmpl_array.push('</table>');
-
-        tmpl_array.push('</div>');
-        return tmpl_array.join('');
-    },
-    templateDatasetModal : function(){
-        var tmpl_array = [];
-
-        tmpl_array.push('<div class="modal_table">');
-        tmpl_array.push('   <table class="grid table table-striped table-condensed">');
-        tmpl_array.push('       <tr>');
-        tmpl_array.push('           <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');
-        tmpl_array.push('           <td><%= _.escape(item.get("name")) %></td>');
-        tmpl_array.push('       </tr>');
-        tmpl_array.push('       <tr>');
-        tmpl_array.push('           <th scope="row">Data type</th>');
-        tmpl_array.push('           <td><%= _.escape(item.get("data_type")) %></td>');
-        tmpl_array.push('       </tr>');
-        tmpl_array.push('       <tr>');
-        tmpl_array.push('           <th scope="row">Genome build</th>');
-        tmpl_array.push('           <td><%= _.escape(item.get("genome_build")) %></td>');
-        tmpl_array.push('       </tr>');
-        tmpl_array.push('           <th scope="row">Size</th>');
-        tmpl_array.push('           <td><%= _.escape(size) %></td>');
-        tmpl_array.push('       </tr>');
-        tmpl_array.push('       <tr>');
-        tmpl_array.push('           <th scope="row">Date uploaded (UTC)</th>');
-        tmpl_array.push('           <td><%= _.escape(item.get("date_uploaded")) %></td>');
-        tmpl_array.push('       </tr>');
-        tmpl_array.push('       <tr>');
-        tmpl_array.push('           <th scope="row">Uploaded by</th>');
-        tmpl_array.push('           <td><%= _.escape(item.get("uploaded_by")) %></td>');
-        tmpl_array.push('       </tr>');
-        tmpl_array.push('           <tr scope="row">');
-        tmpl_array.push('           <th scope="row">Data Lines</th>');
-        tmpl_array.push('           <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');
-        tmpl_array.push('       </tr>');
-        tmpl_array.push('       <th scope="row">Comment Lines</th>');
-        tmpl_array.push('           <% if (item.get("metadata_comment_lines") === "") { %>');
-        tmpl_array.push('               <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');
-        tmpl_array.push('           <% } else { %>');
-        tmpl_array.push('               <td scope="row">unknown</td>');
-        tmpl_array.push('           <% } %>');
-        tmpl_array.push('       </tr>');
-        tmpl_array.push('       <tr>');
-        tmpl_array.push('           <th scope="row">Number of Columns</th>');
-        tmpl_array.push('           <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');
-        tmpl_array.push('       </tr>');
-        tmpl_array.push('       <tr>');
-        tmpl_array.push('           <th scope="row">Column Types</th>');
-        tmpl_array.push('           <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');
-        tmpl_array.push('       </tr>');
-        tmpl_array.push('       <tr>');
-        tmpl_array.push('           <th scope="row">Miscellaneous information</th>');
-        tmpl_array.push('           <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');
-        tmpl_array.push('       </tr>');
-        tmpl_array.push('   </table>');
-        tmpl_array.push('   <pre class="peek">');
-        tmpl_array.push('   </pre>');
-        tmpl_array.push('</div>');
-
-        return tmpl_array.join('');
-    },
-
-    templateHistorySelectInModal : function(){
-        var tmpl_array = [];
-
-        tmpl_array.push('<span id="history_modal_combo" style="width:100%; margin-left: 1em; margin-right: 1em; ">');
-        tmpl_array.push('Select history: ');
-        tmpl_array.push('<select id="dataset_import_single" name="dataset_import_single" style="width:40%; margin-bottom: 1em; "> ');
-        tmpl_array.push('   <% _.each(histories, function(history) { %>'); //history select box
-        tmpl_array.push('       <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');
-        tmpl_array.push('   <% }); %>');
-        tmpl_array.push('</select>');
-        tmpl_array.push('</span>');
-
-        return tmpl_array.join('');
-        },
-
-    templateBulkImportInModal : function(){
-        var tmpl_array = [];
-
-        tmpl_array.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');
-        tmpl_array.push('Select history: ');
-        tmpl_array.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');
-        tmpl_array.push('   <% _.each(histories, function(history) { %>'); //history select box
-        tmpl_array.push('       <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');
-        tmpl_array.push('   <% }); %>');
-        tmpl_array.push('</select>');
-        tmpl_array.push('</span>');
-
-        return tmpl_array.join('');
-        },
-
-      templateProgressBar : function (){
-        var tmpl_array = [];
-
-        tmpl_array.push('<div class="import_text">');
-        tmpl_array.push('Importing selected datasets to history <b><%= _.escape(history_name) %></b>');
-        tmpl_array.push('</div>');
-        tmpl_array.push('<div class="progress">');
-        tmpl_array.push('   <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');
-        tmpl_array.push('       <span class="completion_span">0% Complete</span>');
-        tmpl_array.push('   </div>');
-        tmpl_array.push('</div>');
-        tmpl_array.push('');
-
-        return tmpl_array.join('');
-      },
-
-    templateNewFolderInModal: function(){
-        tmpl_array = [];
-
-        tmpl_array.push('<div id="new_folder_modal">');
-        tmpl_array.push('<form>');
-        tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');
-        tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');
-        tmpl_array.push('</form>');
-        tmpl_array.push('</div>');
-
-        return tmpl_array.join('');
-    },
-
-// MMMMMMMMMMMMMMM
-// === EVENTS ====
-// MMMMMMMMMMMMMMM
-
-      // event binding
-      events: {
-            'click #select-all-checkboxes' : 'selectAll',
-            'click #toolbtn_bulk_import' : 'modalBulkImport',
-            'click #toolbtn_dl' : 'bulkDownload',
-            'click #toolbtn_create_folder' : 'createFolderFromModal',
-            'click .library-dataset' : 'showDatasetDetails',
-            'click .dataset_row' : 'selectClickedRow'
-        },
-
-// MMMMMMMMMMMMMMMMMM
-// === FUNCTIONS ====
-// MMMMMMMMMMMMMMMMMM
-
-      //render the folder view
-      render: function (options) {
-        //hack to show scrollbars
-        $("#center").css('overflow','auto');
-
-        view = this;
-        var that = this;
-
-        var folderContainer = new FolderContainer({id: options.id});
-        folderContainer.url = folderContainer.attributes.urlRoot + options.id + '/contents';
-
-        folderContainer.fetch({
-          success: function (container) {
-
-            // prepare nice size strings
-              for (var i = 0; i < folderContainer.attributes.folder.models.length; i++) {
-                  var model = folderContainer.attributes.folder.models[i]
-                  if (model.get('type') === 'file'){
-                    model.set('readable_size', that.size_to_string(model.get('file_size')))
-                  }
-              };
-
-              // find the upper id
-              var path = folderContainer.full_path;
-              var upper_folder_id;
-              if (path.length === 1){ // library is above us
-                upper_folder_id = 0;
-              } else {
-                upper_folder_id = path[path.length-2][0];
-              }
-
-              var template = _.template(that.templateFolder(), { path: folderContainer.full_path, items: folderContainer.attributes.folder.models, id: options.id, upper_folder_id: upper_folder_id });
-              // var template = _.template(that.templateFolder(), { path: folderContainer.full_path, items: folderContainer.attributes.folder.models, id: options.id });
-              that.$el.html(template);
-
-            },
-              error: function(){
-                mod_toastr.error('An error occured :(');
-              }
-          })
-        },
-
-      // convert size to nice string
-      size_to_string : function (size)
-      {
-            // identify unit
-            var unit = "";
-            if (size >= 100000000000)   { size = size / 100000000000; unit = "TB"; } else
-            if (size >= 100000000)      { size = size / 100000000; unit = "GB"; } else
-            if (size >= 100000)         { size = size / 100000; unit = "MB"; } else
-            if (size >= 100)            { size = size / 100; unit = "KB"; } else
-            { size = size * 10; unit = "b"; }
-            // return formatted string
-            return (Math.round(size) / 10) + unit;
-        },
-
-      //show modal with current dataset info
-      showDatasetDetails : function(event){
-        // prevent default
-        event.preventDefault();
-
-        //TODO check whether we already have the data
-
-        //load the ID of the row
-        var id = $(event.target).parent().parent().parent().attr('id');
-        if (typeof id === 'undefined'){
-            id = $(event.target).parent().attr('id');
-        }        
-        if (typeof id === 'undefined'){
-            id = $(event.target).parent().parent().attr('id')
-        }
-
-        //create new item
-        var item = new Item();
-        var histories = new GalaxyHistories();
-        item.id = id;
-        var self = this;
-
-        //fetch the dataset info
-        item.fetch({
-          success: function (item) {
-        // TODO can render here already
-                //fetch user histories for import purposes
-                histories.fetch({
-                    success: function (histories){
-                        self.renderModalAfterFetch(item, histories)
-                    },
-                      error: function(){
-                        mod_toastr.error('An error occured during fetching histories:(');
-                        self.renderModalAfterFetch(item)
-                    }
-                });
-            },
-              error: function(){
-                mod_toastr.error('An error occured during loading dataset details :(');
-              }
-        });
-    },
-
-      // show the current dataset in a modal
-      renderModalAfterFetch : function(item, histories){
-        var size = this.size_to_string(item.get('file_size'));
-        var template = _.template(this.templateDatasetModal(), { item : item, size : size });
-            // make modal
-            var self = this;
-            this.modal = Galaxy.modal;
-            this.modal.show({
-                closing_events  : true,
-                title           : 'Dataset Details',
-                body            : template,
-                buttons         : {
-                    'Import'    : function() { self.importCurrentIntoHistory() },
-                    'Download'  : function() { self.downloadCurrent() },
-                    'Close'     : function() { self.modal.hide() }
-                }
-            });
-            
-            $(".peek").html('Peek:' + item.get("peek"));
-
-            // show the import-into-history footer only if the request for histories succeeded
-            if (typeof history.models !== undefined){
-                var history_footer_tmpl = _.template(this.templateHistorySelectInModal(), {histories : histories.models});
-                $(this.modal.elMain).find('.buttons').prepend(history_footer_tmpl);
-                // preset last selected history if we know it
-                if (self.lastSelectedHistory.length > 0) {
-                    $(this.modal.elMain).find('#dataset_import_single').val(self.lastSelectedHistory);
-                }
-            }
-        },
-
-        // download dataset shown currently in modal
-        downloadCurrent : function(){
-            //disable the buttons
-            this.modal.disableButton('Import');
-            this.modal.disableButton('Download');
-
-            var library_dataset_id = [];
-            library_dataset_id.push($('#id_row').attr('data-id'));
-            var url = '/api/libraries/datasets/download/uncompressed';
-            var data = {'ldda_ids' : library_dataset_id};
-
-            // we assume the view is existent
-            folderContentView.processDownload(url, data);
-            this.modal.enableButton('Import');
-            this.modal.enableButton('Download');
-        },
-
-        // import dataset shown currently in modal into selected history
-        importCurrentIntoHistory : function(){
-            //disable the buttons
-            this.modal.disableButton('Import');
-            this.modal.disableButton('Download');
-
-            var history_id = $(this.modal.elMain).find('select[name=dataset_import_single] option:selected').val();
-            this.lastSelectedHistory = history_id; //save selected history for further use
-
-            var library_dataset_id = $('#id_row').attr('data-id');
-            var historyItem = new HistoryItem();
-            var self = this;
-            historyItem.url = historyItem.urlRoot + history_id + '/contents';
-
-            // save the dataset into selected history
-            historyItem.save({ content : library_dataset_id, source : 'library' }, { success : function(){
-                mod_toastr.success('Dataset imported');
-                //enable the buttons
-                self.modal.enableButton('Import');
-                self.modal.enableButton('Download');
-            }, error : function(){
-                mod_toastr.error('An error occured! Dataset not imported. Please try again.')
-                //enable the buttons
-                self.modal.enableButton('Import');
-                self.modal.enableButton('Download');
-            }
-        });
-        },
-
-        // select all datasets
-        selectAll : function (event) {
-             var selected = event.target.checked;
-             that = this;
-             // Iterate each checkbox
-             $(':checkbox').each(function () { 
-                this.checked = selected; 
-                $row = $(this.parentElement.parentElement);
-                // Change color of selected/unselected
-                (selected) ? that.makeDarkRow($row) : that.makeWhiteRow($row);
-            });
-             // Show the tools in menu
-             this.checkTools();
-         },
-
-         // Check checkbox on row itself or row checkbox click
-         selectClickedRow : function (event) {
-            var checkbox = '';
-            var $row;
-            var source;
-            if (event.target.localName === 'input'){
-                checkbox = event.target;
-                $row = $(event.target.parentElement.parentElement);
-                source = 'input';
-            } else if (event.target.localName === 'td') {
-                checkbox = $("#" + event.target.parentElement.id).find(':checkbox')[0];
-                $row = $(event.target.parentElement);
-                source = 'td';
-            }
-
-                if (checkbox.checked){
-                    if (source==='td'){
-                        checkbox.checked = '';
-                        this.makeWhiteRow($row);
-                    } else if (source==='input') {
-                        this.makeDarkRow($row);
-                    }
-                } else {
-                    if (source==='td'){
-                        checkbox.checked = 'selected';
-                        this.makeDarkRow($row);
-                    } else if (source==='input') {
-                        this.makeWhiteRow($row);
-                    }
-                }
-                this.checkTools();
-        },
-
-        makeDarkRow: function($row){
-            $row.removeClass('light');
-            $row.find('a').removeClass('light');
-            $row.addClass('dark');
-            $row.find('a').addClass('dark');
-            $row.find('span').removeClass('fa-file-o');
-            $row.find('span').addClass('fa-file');
-
-        },
-
-        makeWhiteRow: function($row){
-            $row.removeClass('dark');
-            $row.find('a').removeClass('dark');
-            $row.addClass('light');
-            $row.find('a').addClass('light');
-            $row.find('span').addClass('fa-file-o');
-            $row.find('span').removeClass('fa-file');
-        },
-
-        // show toolbar in case something is selected
-        checkTools : function(){
-            var checkedValues = $('#folder_table').find(':checked');
-            if(checkedValues.length > 0){
-                $('#toolbtn_bulk_import').show();
-                $('#toolbtn_dl').show();
-            } else {
-                $('#toolbtn_bulk_import').hide();
-                $('#toolbtn_dl').hide();
-            }
-        },
-
-        // show bulk import modal
-        modalBulkImport : function(){
-            var self = this;
-            // fetch histories
-            var histories = new GalaxyHistories();
-            histories.fetch({
-                    success: function (histories){
-                        // make modal
-                        var history_modal_tmpl =  _.template(self.templateBulkImportInModal(), {histories : histories.models});
-                        self.modal = Galaxy.modal;
-                        self.modal.show({
-                            closing_events  : true,
-                            title           : 'Import into History',
-                            body            : history_modal_tmpl,
-                            buttons         : {
-                                'Import'    : function() {self.importAllIntoHistory()},
-                                'Close'     : function() {self.modal.hide();}
-                            }
-                        });
-                    },
-                    error: function(){
-                      mod_toastr.error('An error occured :(');
-                    }
-                });
-        },
-
-        // import all selected datasets into history
-        importAllIntoHistory : function (){
-            //disable the button to prevent multiple submission
-            this.modal.disableButton('Import');
-
-            var history_id = $("select[name=dataset_import_bulk] option:selected").val();
-            var history_name = $("select[name=dataset_import_bulk] option:selected").text();
-
-            var dataset_ids = [];
-            $('#folder_table').find(':checked').each(function(){
-                if (this.parentElement.parentElement.id != '') {
-                    dataset_ids.push(this.parentElement.parentElement.id);
-                }
-            });
-            var progress_bar_tmpl = _.template(this.templateProgressBar(), { history_name : history_name });
-            $(this.modal.elMain).find('.modal-body').html(progress_bar_tmpl);
-
-            // init the progress bar
-            var progressStep = 100 / dataset_ids.length;
-            this.initProgress(progressStep);
-
-            // prepare the dataset objects to be imported
-            var datasets_to_import = [];
-            for (var i = dataset_ids.length - 1; i >= 0; i--) {
-                library_dataset_id = dataset_ids[i];
-                var historyItem = new HistoryItem();
-                var self = this;
-                historyItem.url = historyItem.urlRoot + history_id + '/contents';
-                historyItem.content = library_dataset_id;
-                historyItem.source = 'library';
-                datasets_to_import.push(historyItem);
-            };
-
-            // call the recursive function to call ajax one after each other (request FIFO queue)
-            this.chainCall(datasets_to_import);
-        },
-
-        chainCall: function(history_item_set){
-            var self = this;
-            var popped_item = history_item_set.pop();
-            if (typeof popped_item === "undefined") {
-                mod_toastr.success('All datasets imported');
-                this.modal.hide();
-                return
-            }
-                var promise = $.when(popped_item.save({content: popped_item.content, source: popped_item.source})).done(function(a1){
-                        self.updateProgress();
-                        responses.push(a1);
-                        self.chainCall(history_item_set);
-                    });
-        },
-
-        initProgress: function(progressStep){
-            this.progress = 0;
-            this.progressStep = progressStep;
-        },
-        updateProgress: function(){
-            this.progress += this.progressStep;
-            $('.progress-bar-import').width(Math.round(this.progress) + '%');
-            txt_representation = Math.round(this.progress) + '% Complete';
-            $('.completion_span').text(txt_representation);
-        },
-
-
-
-      // download selected datasets
-      download : function(folder_id, format){
-        var dataset_ids = [];
-            $('#folder_table').find(':checked').each(function(){
-                if (this.parentElement.parentElement.id != '') {
-                    dataset_ids.push(this.parentElement.parentElement.id);
-                }
-            });
-
-        var url = '/api/libraries/datasets/download/' + format;
-        var data = {'ldda_ids' : dataset_ids};
-        this.processDownload(url, data, 'get');
-      },
-
-      // create hidden form and submit through POST to initialize download
-      processDownload: function(url, data, method){
-        //url and data options required
-        if( url && data ){
-                //data can be string of parameters or array/object
-                data = typeof data == 'string' ? data : $.param(data);
-                //split params into form inputs
-                var inputs = '';
-                $.each(data.split('&'), function(){
-                        var pair = this.split('=');
-                        inputs+='<input type="hidden" name="'+ pair[0] +'" value="'+ pair[1] +'" />';
-                });
-                //send request
-                $('<form action="'+ url +'" method="'+ (method||'post') +'">'+inputs+'</form>')
-                .appendTo('body').submit().remove();
-                
-                mod_toastr.info('Your download will begin soon');
-        };
-      },
-
-      // shows modal for creating folder
-      createFolderFromModal: function(){
-        event.preventDefault();
-        event.stopPropagation();
-
-        // create modal
-        var self = this;
-        this.modal = Galaxy.modal;
-        this.modal.show({
-            closing_events  : true,
-            title           : 'Create New Folder',
-            body            : this.templateNewFolderInModal(),
-            buttons         : {
-                'Create'    : function() {self.create_new_folder_event()},
-                'Close'     : function() {self.modal.hide(); self.modal = null;}
-            }
-        });
-      },
-
-    // create the new folder from modal
-    create_new_folder_event: function(){
-        var folderDetails = this.serialize_new_folder();
-        if (this.validate_new_folder(folderDetails)){
-            var folder = new FolderAsModel();
-
-            url_items = Backbone.history.fragment.split('/');
-            current_folder_id = url_items[url_items.length-1];
-            folder.url = folder.urlRoot + '/' + current_folder_id ;
-
-            var self = this;
-            folder.save(folderDetails, {
-              success: function (folder) {
-                self.modal.hide();
-                mod_toastr.success('Folder created');
-                self.render({id: current_folder_id});
-              },
-              error: function(){
-                mod_toastr.error('An error occured :(');
-              }
-            });
-        } else {
-            mod_toastr.error('Folder\'s name is missing');
-        }
-        return false;
-    },
-
-    // serialize data from the form
-    serialize_new_folder : function(){
-        return {
-            name: $("input[name='Name']").val(),
-            description: $("input[name='Description']").val()
-        };
-    },
-
-    // validate new library info
-    validate_new_folder: function(folderDetails){
-        return folderDetails.name !== '';
-    }
-
-    });
-
-// galaxy library view
-var GalaxyLibraryview = Backbone.View.extend({
-    el: '#libraries_element',
-
-    events: {
-        'click .edit_library_btn'   : 'edit_button_event',
-        'click .save_library_btn'   : 'save_library_modification',
-        'click .cancel_library_btn' : 'cancel_library_modification',
-        'click .delete_library_btn' : 'delete_library',
-        'click .undelete_library_btn' : 'undelete_library'
-    },
-
-    modal: null,
-
-    collection: null,
-
-    // initialize
-    initialize : function(){
-        var viewContext = this;
-        this.collection = new Libraries();
-
-        this.collection.fetch({
-          success: function(libraries){
-            viewContext.render();
-            // initialize the library tooltips
-            $("#center [data-toggle]").tooltip();
-            // modification of upper DOM element to show scrollbars due to the #center element inheritance
-            $("#center").css('overflow','auto');
-          },
-          error: function(model, response){
-            mod_toastr.error('An error occured. Please try again.');
-          }
-        })
-    },
-
-    /** Renders the libraries table either from the object's own collection, 
-     or from a given array of library models,
-     or renders an empty list in case no data is given. */
-    render: function (options) {
-        var template = this.templateLibraryList();
-        var libraries_to_render = null;
-        var include_deleted = false;
-        var models = null
-        if (typeof options !== 'undefined'){
-            include_deleted = typeof options.with_deleted !== 'undefined' ? options.with_deleted : false;
-            models = typeof options.models !== 'undefined' ? options.models : null;
-        }
-
-        if (this.collection !== null && models === null){
-            if (include_deleted){ // show all the libraries
-              libraries_to_render = this.collection.models;
-            } else{ // show only undeleted libraries
-              libraries_to_render = this.collection.where({deleted: false});;
-            }
-        } else if (models !== null){
-            libraries_to_render = models;
-        } else {
-            libraries_to_render = [];
-            }
-
-        this.$el.html(template({libraries: libraries_to_render, order: this.collection.sort_order}));
-    },
-
-    /** Sorts the underlying collection according to the parameters received through URL. 
-        Currently supports only sorting by name. */
-    sortLibraries: function(sort_by, order){
-        if (sort_by === 'name'){
-            if (order === 'asc'){
-                this.collection.sort_order = 'asc';
-                this.collection.comparator = function(libraryA, libraryB){
-                      if (libraryA.get('name').toLowerCase() > libraryB.get('name').toLowerCase()) return 1; // after
-                      if (libraryB.get('name').toLowerCase() > libraryA.get('name').toLowerCase()) return -1; // before
-                      return 0; // equal
-                }
-            } else if (order === 'desc'){
-                this.collection.sort_order = 'desc';
-                this.collection.comparator = function(libraryA, libraryB){
-                      if (libraryA.get('name').toLowerCase() > libraryB.get('name').toLowerCase()) return -1; // before
-                      if (libraryB.get('name').toLowerCase() > libraryA.get('name').toLowerCase()) return 1; // after
-                      return 0; // equal
-                }
-            }
-            this.collection.sort();
-        }
-
-    },
-
-// MMMMMMMMMMMMMMMMMM
-// === TEMPLATES ====
-// MMMMMMMMMMMMMMMMMM
-
-    templateLibraryList: function(){
-        tmpl_array = [];
-
-        tmpl_array.push('<div class="library_container table-responsive">');
-        tmpl_array.push('<% if(libraries.length === 0) { %>');
-        tmpl_array.push("<div>I see no libraries. Why don't you create one?</div>");
-        tmpl_array.push('<% } else{ %>');
-        tmpl_array.push('<table class="grid table table-condensed">');
-        tmpl_array.push('   <thead>');
-        tmpl_array.push('     <th style="width:30%;"><a title="Click to reverse order" href="#sort/name/<% if(order==="desc"||order===null){print("asc")}else{print("desc")} %>">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');
-        tmpl_array.push('     <th style="width:22%;">description</th>');
-        tmpl_array.push('     <th style="width:22%;">synopsis</th> ');
-        tmpl_array.push('     <th style="width:26%;"></th> ');
-        tmpl_array.push('   </thead>');
-        tmpl_array.push('   <tbody>');
-        tmpl_array.push('       <% _.each(libraries, function(library) { %>');
-        tmpl_array.push('           <tr class="<% if(library.get("deleted") === true){print("active");}%>" data-id="<%- library.get("id") %>">');
-        tmpl_array.push('               <td><a href="#folders/<%- library.get("root_folder_id") %>"><%- library.get("name") %></a></td>');
-        tmpl_array.push('               <td><%= _.escape(library.get("description")) %></td>');
-        tmpl_array.push('               <td><%= _.escape(library.get("synopsis")) %></td>');
-        tmpl_array.push('               <td class="right-center">');
-        tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Modify library" class="primary-button btn-xs edit_library_btn" type="button"><span class="fa fa-pencil"></span></button>');
-        tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Save changes" class="primary-button btn-xs save_library_btn" type="button" style="display:none;"><span class="fa fa-floppy-o"> Save</span></button>');
-        tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Discard changes" class="primary-button btn-xs cancel_library_btn" type="button" style="display:none;"><span class="fa fa-times"> Cancel</span></button>');
-        tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Delete library (can be undeleted later)" class="primary-button btn-xs delete_library_btn" type="button" style="display:none;"><span class="fa fa-trash-o"> Delete</span></button>');
-        tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Undelete library" class="primary-button btn-xs undelete_library_btn" type="button" style="display:none;"><span class="fa fa-unlock"> Undelete</span></button>');
-        tmpl_array.push('               </td>');
-        tmpl_array.push('           </tr>');
-        tmpl_array.push('       <% }); %>');
-        tmpl_array.push('   </tbody>');
-        tmpl_array.push('</table>');
-        tmpl_array.push('<% }%>');
-        tmpl_array.push('</div>');
-
-        return _.template(tmpl_array.join(''));
-    },
-    
-    templateNewLibraryInModal: function(){
-        tmpl_array = [];
-
-        tmpl_array.push('<div id="new_library_modal">');
-        tmpl_array.push('   <form>');
-        tmpl_array.push('       <input type="text" name="Name" value="" placeholder="Name">');
-        tmpl_array.push('       <input type="text" name="Description" value="" placeholder="Description">');
-        tmpl_array.push('       <input type="text" name="Synopsis" value="" placeholder="Synopsis">');
-        tmpl_array.push('   </form>');
-        tmpl_array.push('</div>');
-
-        return tmpl_array.join('');
-    },
-
-    save_library_modification: function(event){
-        var $library_row = $(event.target).closest('tr');
-        var library = this.collection.get($library_row.data('id'));
-
-        var is_changed = false;
-
-        var new_name = $library_row.find('.input_library_name').val();
-        if (typeof new_name !== 'undefined' && new_name !== library.get('name') ){
-            if (new_name.length > 2){
-                library.set("name", new_name);
-                is_changed = true;
-            } else{
-                mod_toastr.warning('Library name has to be at least 3 characters long');
-                return
-            }
-        }
-
-        var new_description = $library_row.find('.input_library_description').val();
-        if (typeof new_description !== 'undefined' && new_description !== library.get('description') ){
-            library.set("description", new_description);
-            is_changed = true;
-        }
-
-        var new_synopsis = $library_row.find('.input_library_synopsis').val();
-        if (typeof new_synopsis !== 'undefined' && new_synopsis !== library.get('synopsis') ){
-            library.set("synopsis", new_synopsis);
-            is_changed = true;
-        }
-
-        if (is_changed){
-            library.save(null, {
-              patch: true,
-              success: function(library) {
-                mod_toastr.success('Changes to library saved');
-                galaxyLibraryview.toggle_library_modification($library_row);
-              },
-              error: function(model, response){
-                mod_toastr.error('An error occured during updating the library :(');
-              }
-            });
-        }
-    },
-
-    edit_button_event: function(event){
-      this.toggle_library_modification($(event.target).closest('tr'));
-    },
-
-    toggle_library_modification: function($library_row){
-        var library = this.collection.get($library_row.data('id'));
-
-        $library_row.find('.edit_library_btn').toggle();
-        $library_row.find('.save_library_btn').toggle();
-        $library_row.find('.cancel_library_btn').toggle();
-        if (library.get('deleted')){
-            $library_row.find('.undelete_library_btn').toggle();
-        } else {
-            $library_row.find('.delete_library_btn').toggle();
-        }
-
-        if ($library_row.find('.edit_library_btn').is(':hidden')){
-            // library name
-            var current_library_name = library.get('name');
-            var new_html = '<input type="text" class="form-control input_library_name" placeholder="name">';
-            $library_row.children('td').eq(0).html(new_html);
-            if (typeof current_library_name !== undefined){
-                $library_row.find('.input_library_name').val(current_library_name);
-            }
-            // library description
-            var current_library_description = library.get('description');
-            var new_html = '<input type="text" class="form-control input_library_description" placeholder="description">';
-            $library_row.children('td').eq(1).html(new_html);
-            if (typeof current_library_description !== undefined){
-                $library_row.find('.input_library_description').val(current_library_description);
-            }
-            // library synopsis
-            var current_library_synopsis = library.get('synopsis');
-            var new_html = '<input type="text" class="form-control input_library_synopsis" placeholder="synopsis">';
-            $library_row.children('td').eq(2).html(new_html);
-            if (typeof current_library_synopsis !== undefined){
-                $library_row.find('.input_library_synopsis').val(current_library_synopsis);
-            }
-        } else {
-            $library_row.children('td').eq(0).html(library.get('name'));
-            $library_row.children('td').eq(1).html(library.get('description'));
-            $library_row.children('td').eq(2).html(library.get('synopsis'));
-        }
-        
-    },
-
-    cancel_library_modification: function(event){
-        var $library_row = $(event.target).closest('tr');
-        var library = this.collection.get($library_row.data('id'));
-        this.toggle_library_modification($library_row);
-
-        $library_row.children('td').eq(0).html(library.get('name'));
-        $library_row.children('td').eq(1).html(library.get('description'));
-        $library_row.children('td').eq(2).html(library.get('synopsis'));
-    },
-
-    undelete_library: function(event){
-        var $library_row = $(event.target).closest('tr');
-        var library = this.collection.get($library_row.data('id'));
-        this.toggle_library_modification($library_row);
-
-        // mark the library undeleted
-        library.url = library.urlRoot + library.id + '?undelete=true';
-        library.destroy({
-          success: function (library) {
-            // add the newly undeleted library back to the collection
-            // backbone does not accept changes through destroy, so update it too
-            library.set('deleted', false);
-            galaxyLibraryview.collection.add(library);
-            $library_row.removeClass('active');
-            mod_toastr.success('Library has been undeleted');
-          },
-          error: function(){
-            mod_toastr.error('An error occured while undeleting the library :(');
-          }
-        });
-    },
-
-    delete_library: function(event){
-        var $library_row = $(event.target).closest('tr');
-        var library = this.collection.get($library_row.data('id'));
-        this.toggle_library_modification($library_row);
-
-        // mark the library deleted
-        library.destroy({
-          success: function (library) {
-            // add the new deleted library back to the collection
-            $library_row.remove();
-            library.set('deleted', true);
-            galaxyLibraryview.collection.add(library);
-            mod_toastr.success('Library has been marked deleted');
-          },
-          error: function(){
-            mod_toastr.error('An error occured during deleting the library :(');
-          }
-        });
-
-    },
-
-    redirectToHome: function(){
-        window.location = '../';
-    },    
-    redirectToLogin: function(){
-        window.location = '/user/login';
-    },
-
-    // show/hide create library modal
-    show_library_modal : function (event){
-        event.preventDefault();
-        event.stopPropagation();
-
-        // create modal
-        var self = this;
-        this.modal = Galaxy.modal;
-        this.modal.show({
-            closing_events  : true,
-            title           : 'Create New Library',
-            body            : this.templateNewLibraryInModal(),
-            buttons         : {
-                'Create'    : function() {self.create_new_library_event()},
-                'Close'     : function() {self.modal.hide();}
-            }
-        });
-    },
-
-    // create the new library from modal
-    create_new_library_event: function(){
-        var libraryDetails = this.serialize_new_library();
-        if (this.validate_new_library(libraryDetails)){
-            var library = new Library();
-            var self = this;
-            library.save(libraryDetails, {
-              success: function (library) {
-                self.collection.add(library);
-                self.modal.hide();
-                self.clear_library_modal();
-                self.render();
-                mod_toastr.success('Library created');
-              },
-              error: function(){
-                mod_toastr.error('An error occured :(');
-              }
-            });
-        } else {
-            mod_toastr.error('Library\'s name is missing');
-        }
-        return false;
-    },
-
-    // clear the library modal once saved
-    clear_library_modal : function(){
-        $("input[name='Name']").val('');
-        $("input[name='Description']").val('');
-        $("input[name='Synopsis']").val('');
-    },
-
-    // serialize data from the form
-    serialize_new_library : function(){
-        return {
-            name: $("input[name='Name']").val(),
-            description: $("input[name='Description']").val(),
-            synopsis: $("input[name='Synopsis']").val()
-        };
-    },
-
-    // validate new library info
-    validate_new_library: function(libraryDetails){
-        return libraryDetails.name !== '';
-    }
-});
-
-var ToolbarView = Backbone.View.extend({
-  el: '#center',
-
-  events: {        
-    'click #create_new_library_btn' : 'delegate_modal',
-    'click #include_deleted_chk'    : 'check_include_deleted'
-  },
-
-  initialize: function(){
-    this.render();
-  },
-
-  delegate_modal: function(event){
-    // probably should refactor to have this functionality in this view, not in the library view
-    galaxyLibraryview.show_library_modal(event);
-  },
-
-  // include or exclude deleted libraries from the view
-  check_include_deleted: function(event){
-    if (event.target.checked){
-        galaxyLibraryview.render( {'with_deleted': true} );
-    } else{
-        galaxyLibraryview.render({'with_deleted': false});
-    }
-  },
-
-  render: function(){
-    var toolbar_template = this.templateToolBar()
-    this.$el.html(toolbar_template())
-  },
-
-  templateToolBar: function(){
-    tmpl_array = [];
-
-    tmpl_array.push('<div id="libraries_container" style="width: 90%; margin: auto; margin-top:2em; overflow: auto !important; ">');
-    // TOOLBAR
-    tmpl_array.push('  <div id="toolbar_form" margin-top:0.5em; ">');
-    tmpl_array.push('       <h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
-    tmpl_array.push('       <div id="library_toolbar">');
-    tmpl_array.push('           <input id="include_deleted_chk" style="margin: 0;" type="checkbox">include deleted</input>');
-    tmpl_array.push('           <button data-toggle="tooltip" data-placement="top" title="Create New Library" id="create_new_library_btn" class="primary-button" type="button"><span class="fa fa-plus"></span> New Library</button>');
-    tmpl_array.push('       </div>');
-    tmpl_array.push('  </div>');
-    tmpl_array.push('  <div id="libraries_element">');
-    tmpl_array.push('  </div>');
-    tmpl_array.push('</div>');
-
-    return _.template(tmpl_array.join(''));
-  }
-})
+    "libs/toastr",
+    "mvc/library/library-model",
+    "mvc/library/library-folderlist-view",
+    "mvc/library/library-librarylist-view",
+    "mvc/library/library-librarytoolbar-view"], 
+function(mod_masthead, 
+         mod_utils, 
+         mod_toastr,
+         mod_library_model,
+         mod_folderlist_view,
+         mod_librarylist_view,
+         mod_librarytoolbar_view) {
 
 //ROUTER
 var LibraryRouter = Backbone.Router.extend({
@@ -1202,16 +36,17 @@
 var GalaxyLibrary = Backbone.View.extend({
 
     initialize : function(){
-        toolbarView = new ToolbarView();
-        galaxyLibraryview = new GalaxyLibraryview();
+        toolbarView = new mod_librarytoolbar_view.ToolbarView();
+        galaxyLibraryview = new mod_librarylist_view.GalaxyLibraryview();
         library_router = new LibraryRouter();
-        folderContentView = new FolderContentView();
+        
+        folderContentView = null;
 
         library_router.on('route:libraries', function() {
           // initialize and render the toolbar first
-          toolbarView = new ToolbarView();
+          toolbarView = new mod_librarytoolbar_view.ToolbarView();
           // initialize and render libraries second
-          galaxyLibraryview = new GalaxyLibraryview();
+          galaxyLibraryview = new mod_librarylist_view.GalaxyLibraryview();
         });
 
         library_router.on('route:sort_libraries', function(sort_by, order) {
@@ -1222,6 +57,7 @@
 
         library_router.on('route:folder_content', function(id) {
           // render folder contents
+          if (!folderContentView) {folderContentView = new mod_folderlist_view.FolderContentView();}
           folderContentView.render({id: id});
         });
 
diff -r 33cc6056d83760e5e3b98999b01ecb260423d33c -r 68d35caf407f367c3447a1a6675d6705c8daacf4 static/scripts/mvc/library/library-folderlist-view.js
--- /dev/null
+++ b/static/scripts/mvc/library/library-folderlist-view.js
@@ -0,0 +1,713 @@
+// dependencies
+define([
+    "galaxy.masthead", 
+    "utils/utils",
+    "libs/toastr",
+    "mvc/library/library-model"], 
+function(mod_masthead, 
+         mod_utils, 
+         mod_toastr,
+         mod_library_model) {
+
+  //main view for folder browsing
+var FolderContentView = Backbone.View.extend({
+    // main element definition
+    el : '#center',
+    // progress percentage
+    progress: 0,
+    // progress rate per one item
+    progressStep: 1,
+    // last selected history in modal for UX
+    lastSelectedHistory: '',
+    // self modal
+    modal : null,
+    // loaded folders
+    folders : null,
+
+    // initialize
+    initialize : function(){
+        this.folders = [];
+        this.queue = jQuery.Deferred();
+        this.queue.resolve();
+    },
+
+// MMMMMMMMMMMMMMMMMM
+// === TEMPLATES ====
+// MMMMMMMMMMMMMMMMMM
+
+    // main template for folder browsing
+    templateFolder : function (){
+        var tmpl_array = [];
+
+        // CONTAINER
+        tmpl_array.push('<div class="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');
+        tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
+
+        // TOOLBAR
+        tmpl_array.push('<div id="library_folder_toolbar" >');
+        tmpl_array.push('   <button title="Create New Folder" id="toolbtn_create_folder" class="primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');
+        tmpl_array.push('   <button title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-book"></span> to history</button>');
+        tmpl_array.push('   <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');
+        tmpl_array.push('       <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');
+        tmpl_array.push('       <span class="fa fa-download"></span> download <span class="caret"></span>');
+        tmpl_array.push('       </button>');
+        tmpl_array.push('       <ul class="dropdown-menu" role="menu">');
+        tmpl_array.push('          <li><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');
+        tmpl_array.push('          <li><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');
+        tmpl_array.push('          <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');
+        tmpl_array.push('       </ul>');
+        tmpl_array.push('   </div>');
+
+        tmpl_array.push('</div>');
+
+        // BREADCRUMBS
+        tmpl_array.push('<ol class="breadcrumb">');
+        tmpl_array.push('   <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');
+        tmpl_array.push('   <% _.each(path, function(path_item) { %>');
+        tmpl_array.push('   <% if (path_item[0] != id) { %>');
+        tmpl_array.push('   <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');
+        tmpl_array.push(    '<% } else { %>');
+        tmpl_array.push('   <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');
+        tmpl_array.push('   <% } %>');
+        tmpl_array.push('   <% }); %>');
+        tmpl_array.push('</ol>');
+
+
+        // FOLDER CONTENT
+        tmpl_array.push('<table id="folder_table" class="grid table table-condensed">');
+        tmpl_array.push('   <thead>');
+        tmpl_array.push('       <th class="button_heading"></th>');
+        tmpl_array.push('       <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');
+        tmpl_array.push('       <th>name</th>');
+        tmpl_array.push('       <th>data type</th>');
+        tmpl_array.push('       <th>size</th>');
+        tmpl_array.push('       <th>date (UTC)</th>');
+        tmpl_array.push('   </thead>');
+        tmpl_array.push('   <tbody>');
+        tmpl_array.push('       <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');
+        tmpl_array.push('       <td></td>');
+        tmpl_array.push('       <td></td>');
+        tmpl_array.push('       <td></td>');
+        tmpl_array.push('       <td></td>');
+        tmpl_array.push('       <td></td>');
+        tmpl_array.push('       </tr>');
+        tmpl_array.push('       <% _.each(items, function(content_item) { %>');
+        tmpl_array.push('           <% if (content_item.get("type") === "folder") { %>'); // folder
+        tmpl_array.push('               <tr class="folder_row light" id="<%- content_item.id %>">');
+        tmpl_array.push('                   <td>');
+        tmpl_array.push('                       <span title="Folder" class="fa fa-folder-o"></span>');
+        tmpl_array.push('                   </td>');
+        tmpl_array.push('                   <td></td>');
+        tmpl_array.push('                   <td>');
+        tmpl_array.push('                       <a href="#folders/<%- content_item.id %>"><%- content_item.get("name") %></a>');
+        tmpl_array.push('                       <% if (content_item.get("item_count") === 0) { %>'); // empty folder
+        tmpl_array.push('                           <span class="muted">(empty folder)</span>');
+        tmpl_array.push('                       <% } %>');
+        tmpl_array.push('                   </td>');
+        tmpl_array.push('                   <td>folder</td>');
+        tmpl_array.push('                   <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>'); // size
+        tmpl_array.push('                   <td><%= _.escape(content_item.get("time_updated")) %></td>'); // time updated
+        tmpl_array.push('               </tr>');
+        tmpl_array.push('           <% } else {  %>');
+        tmpl_array.push('               <tr class="dataset_row light" id="<%- content_item.id %>">');
+        tmpl_array.push('                   <td>');
+        tmpl_array.push('                       <span title="Dataset" class="fa fa-file-o"></span>');
+        tmpl_array.push('                   </td>');
+        tmpl_array.push('                   <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');
+        tmpl_array.push('                   <td><a href="#" class="library-dataset"><%- content_item.get("name") %><a></td>'); // dataset
+        tmpl_array.push('                   <td><%= _.escape(content_item.get("data_type")) %></td>'); // data type
+        tmpl_array.push('                   <td><%= _.escape(content_item.get("readable_size")) %></td>'); // size
+        tmpl_array.push('                   <td><%= _.escape(content_item.get("time_updated")) %></td>'); // time updated
+        tmpl_array.push('               </tr>');
+        tmpl_array.push('               <% } %>  ');
+        tmpl_array.push('       <% }); %>');
+        tmpl_array.push('       ');
+        tmpl_array.push('   </tbody>');
+        tmpl_array.push('</table>');
+
+        tmpl_array.push('</div>');
+        return tmpl_array.join('');
+    },
+    templateDatasetModal : function(){
+        var tmpl_array = [];
+
+        tmpl_array.push('<div class="modal_table">');
+        tmpl_array.push('   <table class="grid table table-striped table-condensed">');
+        tmpl_array.push('       <tr>');
+        tmpl_array.push('           <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');
+        tmpl_array.push('           <td><%= _.escape(item.get("name")) %></td>');
+        tmpl_array.push('       </tr>');
+        tmpl_array.push('       <tr>');
+        tmpl_array.push('           <th scope="row">Data type</th>');
+        tmpl_array.push('           <td><%= _.escape(item.get("data_type")) %></td>');
+        tmpl_array.push('       </tr>');
+        tmpl_array.push('       <tr>');
+        tmpl_array.push('           <th scope="row">Genome build</th>');
+        tmpl_array.push('           <td><%= _.escape(item.get("genome_build")) %></td>');
+        tmpl_array.push('       </tr>');
+        tmpl_array.push('           <th scope="row">Size</th>');
+        tmpl_array.push('           <td><%= _.escape(size) %></td>');
+        tmpl_array.push('       </tr>');
+        tmpl_array.push('       <tr>');
+        tmpl_array.push('           <th scope="row">Date uploaded (UTC)</th>');
+        tmpl_array.push('           <td><%= _.escape(item.get("date_uploaded")) %></td>');
+        tmpl_array.push('       </tr>');
+        tmpl_array.push('       <tr>');
+        tmpl_array.push('           <th scope="row">Uploaded by</th>');
+        tmpl_array.push('           <td><%= _.escape(item.get("uploaded_by")) %></td>');
+        tmpl_array.push('       </tr>');
+        tmpl_array.push('           <tr scope="row">');
+        tmpl_array.push('           <th scope="row">Data Lines</th>');
+        tmpl_array.push('           <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');
+        tmpl_array.push('       </tr>');
+        tmpl_array.push('       <th scope="row">Comment Lines</th>');
+        tmpl_array.push('           <% if (item.get("metadata_comment_lines") === "") { %>');
+        tmpl_array.push('               <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');
+        tmpl_array.push('           <% } else { %>');
+        tmpl_array.push('               <td scope="row">unknown</td>');
+        tmpl_array.push('           <% } %>');
+        tmpl_array.push('       </tr>');
+        tmpl_array.push('       <tr>');
+        tmpl_array.push('           <th scope="row">Number of Columns</th>');
+        tmpl_array.push('           <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');
+        tmpl_array.push('       </tr>');
+        tmpl_array.push('       <tr>');
+        tmpl_array.push('           <th scope="row">Column Types</th>');
+        tmpl_array.push('           <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');
+        tmpl_array.push('       </tr>');
+        tmpl_array.push('       <tr>');
+        tmpl_array.push('           <th scope="row">Miscellaneous information</th>');
+        tmpl_array.push('           <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');
+        tmpl_array.push('       </tr>');
+        tmpl_array.push('   </table>');
+        tmpl_array.push('   <pre class="peek">');
+        tmpl_array.push('   </pre>');
+        tmpl_array.push('</div>');
+
+        return tmpl_array.join('');
+    },
+
+    templateHistorySelectInModal : function(){
+        var tmpl_array = [];
+
+        tmpl_array.push('<span id="history_modal_combo" style="width:100%; margin-left: 1em; margin-right: 1em; ">');
+        tmpl_array.push('Select history: ');
+        tmpl_array.push('<select id="dataset_import_single" name="dataset_import_single" style="width:40%; margin-bottom: 1em; "> ');
+        tmpl_array.push('   <% _.each(histories, function(history) { %>'); //history select box
+        tmpl_array.push('       <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');
+        tmpl_array.push('   <% }); %>');
+        tmpl_array.push('</select>');
+        tmpl_array.push('</span>');
+
+        return tmpl_array.join('');
+        },
+
+    templateBulkImportInModal : function(){
+        var tmpl_array = [];
+
+        tmpl_array.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');
+        tmpl_array.push('Select history: ');
+        tmpl_array.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');
+        tmpl_array.push('   <% _.each(histories, function(history) { %>'); //history select box
+        tmpl_array.push('       <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');
+        tmpl_array.push('   <% }); %>');
+        tmpl_array.push('</select>');
+        tmpl_array.push('</span>');
+
+        return tmpl_array.join('');
+        },
+
+      templateProgressBar : function (){
+        var tmpl_array = [];
+
+        tmpl_array.push('<div class="import_text">');
+        tmpl_array.push('Importing selected datasets to history <b><%= _.escape(history_name) %></b>');
+        tmpl_array.push('</div>');
+        tmpl_array.push('<div class="progress">');
+        tmpl_array.push('   <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');
+        tmpl_array.push('       <span class="completion_span">0% Complete</span>');
+        tmpl_array.push('   </div>');
+        tmpl_array.push('</div>');
+        tmpl_array.push('');
+
+        return tmpl_array.join('');
+      },
+
+    templateNewFolderInModal: function(){
+        tmpl_array = [];
+
+        tmpl_array.push('<div id="new_folder_modal">');
+        tmpl_array.push('<form>');
+        tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');
+        tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');
+        tmpl_array.push('</form>');
+        tmpl_array.push('</div>');
+
+        return tmpl_array.join('');
+    },
+
+// MMMMMMMMMMMMMMM
+// === EVENTS ====
+// MMMMMMMMMMMMMMM
+
+      // event binding
+      events: {
+            'click #select-all-checkboxes' : 'selectAll',
+            'click #toolbtn_bulk_import' : 'modalBulkImport',
+            'click #toolbtn_dl' : 'bulkDownload',
+            'click #toolbtn_create_folder' : 'createFolderFromModal',
+            'click .library-dataset' : 'showDatasetDetails',
+            'click .dataset_row' : 'selectClickedRow'
+        },
+
+// MMMMMMMMMMMMMMMMMM
+// === FUNCTIONS ====
+// MMMMMMMMMMMMMMMMMM
+
+      //render the folder view
+      render: function (options) {
+        //hack to show scrollbars
+        $("#center").css('overflow','auto');
+
+        view = this;
+        var that = this;
+
+        var folderContainer = new mod_library_model.FolderContainer({id: options.id});
+        folderContainer.url = folderContainer.attributes.urlRoot + options.id + '/contents';
+
+        folderContainer.fetch({
+          success: function (container) {
+
+            // prepare nice size strings
+              for (var i = 0; i < folderContainer.attributes.folder.models.length; i++) {
+                  var model = folderContainer.attributes.folder.models[i]
+                  if (model.get('type') === 'file'){
+                    model.set('readable_size', that.size_to_string(model.get('file_size')))
+                  }
+              };
+
+              // find the upper id
+              var path = folderContainer.full_path;
+              var upper_folder_id;
+              if (path.length === 1){ // library is above us
+                upper_folder_id = 0;
+              } else {
+                upper_folder_id = path[path.length-2][0];
+              }
+
+              var template = _.template(that.templateFolder(), { path: folderContainer.full_path, items: folderContainer.attributes.folder.models, id: options.id, upper_folder_id: upper_folder_id });
+              // var template = _.template(that.templateFolder(), { path: folderContainer.full_path, items: folderContainer.attributes.folder.models, id: options.id });
+              that.$el.html(template);
+
+            },
+              error: function(){
+                mod_toastr.error('An error occured :(');
+              }
+          })
+        },
+
+      // convert size to nice string
+      size_to_string : function (size)
+      {
+            // identify unit
+            var unit = "";
+            if (size >= 100000000000)   { size = size / 100000000000; unit = "TB"; } else
+            if (size >= 100000000)      { size = size / 100000000; unit = "GB"; } else
+            if (size >= 100000)         { size = size / 100000; unit = "MB"; } else
+            if (size >= 100)            { size = size / 100; unit = "KB"; } else
+            { size = size * 10; unit = "b"; }
+            // return formatted string
+            return (Math.round(size) / 10) + unit;
+        },
+
+      //show modal with current dataset info
+      showDatasetDetails : function(event){
+        // prevent default
+        event.preventDefault();
+
+        //TODO check whether we already have the data
+
+        //load the ID of the row
+        var id = $(event.target).parent().parent().parent().attr('id');
+        if (typeof id === 'undefined'){
+            id = $(event.target).parent().attr('id');
+        }        
+        if (typeof id === 'undefined'){
+            id = $(event.target).parent().parent().attr('id')
+        }
+
+        //create new item
+        var item = new mod_library_model.Item();
+        var histories = new mod_library_model.GalaxyHistories();
+        item.id = id;
+        var self = this;
+
+        //fetch the dataset info
+        item.fetch({
+          success: function (item) {
+        // TODO can render here already
+                //fetch user histories for import purposes
+                histories.fetch({
+                    success: function (histories){
+                        self.renderModalAfterFetch(item, histories)
+                    },
+                      error: function(){
+                        mod_toastr.error('An error occured during fetching histories:(');
+                        self.renderModalAfterFetch(item)
+                    }
+                });
+            },
+              error: function(){
+                mod_toastr.error('An error occured during loading dataset details :(');
+              }
+        });
+    },
+
+      // show the current dataset in a modal
+      renderModalAfterFetch : function(item, histories){
+        var size = this.size_to_string(item.get('file_size'));
+        var template = _.template(this.templateDatasetModal(), { item : item, size : size });
+            // make modal
+            var self = this;
+            this.modal = Galaxy.modal;
+            this.modal.show({
+                closing_events  : true,
+                title           : 'Dataset Details',
+                body            : template,
+                buttons         : {
+                    'Import'    : function() { self.importCurrentIntoHistory() },
+                    'Download'  : function() { self.downloadCurrent() },
+                    'Close'     : function() { self.modal.hide() }
+                }
+            });
+            
+            $(".peek").html('Peek:' + item.get("peek"));
+
+            // show the import-into-history footer only if the request for histories succeeded
+            if (typeof history.models !== undefined){
+                var history_footer_tmpl = _.template(this.templateHistorySelectInModal(), {histories : histories.models});
+                $(this.modal.elMain).find('.buttons').prepend(history_footer_tmpl);
+                // preset last selected history if we know it
+                if (self.lastSelectedHistory.length > 0) {
+                    $(this.modal.elMain).find('#dataset_import_single').val(self.lastSelectedHistory);
+                }
+            }
+        },
+
+        // download dataset shown currently in modal
+        downloadCurrent : function(){
+            //disable the buttons
+            this.modal.disableButton('Import');
+            this.modal.disableButton('Download');
+
+            var library_dataset_id = [];
+            library_dataset_id.push($('#id_row').attr('data-id'));
+            var url = '/api/libraries/datasets/download/uncompressed';
+            var data = {'ldda_ids' : library_dataset_id};
+
+            // we assume the view is existent
+            folderContentView.processDownload(url, data);
+            this.modal.enableButton('Import');
+            this.modal.enableButton('Download');
+        },
+
+        // import dataset shown currently in modal into selected history
+        importCurrentIntoHistory : function(){
+            //disable the buttons
+            this.modal.disableButton('Import');
+            this.modal.disableButton('Download');
+
+            var history_id = $(this.modal.elMain).find('select[name=dataset_import_single] option:selected').val();
+            this.lastSelectedHistory = history_id; //save selected history for further use
+
+            var library_dataset_id = $('#id_row').attr('data-id');
+            var historyItem = new mod_library_model.HistoryItem();
+            var self = this;
+            historyItem.url = historyItem.urlRoot + history_id + '/contents';
+
+            // save the dataset into selected history
+            historyItem.save({ content : library_dataset_id, source : 'library' }, { success : function(){
+                mod_toastr.success('Dataset imported');
+                //enable the buttons
+                self.modal.enableButton('Import');
+                self.modal.enableButton('Download');
+            }, error : function(){
+                mod_toastr.error('An error occured! Dataset not imported. Please try again.')
+                //enable the buttons
+                self.modal.enableButton('Import');
+                self.modal.enableButton('Download');
+            }
+        });
+        },
+
+        // select all datasets
+        selectAll : function (event) {
+             var selected = event.target.checked;
+             that = this;
+             // Iterate each checkbox
+             $(':checkbox').each(function () { 
+                this.checked = selected; 
+                $row = $(this.parentElement.parentElement);
+                // Change color of selected/unselected
+                (selected) ? that.makeDarkRow($row) : that.makeWhiteRow($row);
+            });
+             // Show the tools in menu
+             this.checkTools();
+         },
+
+         // Check checkbox on row itself or row checkbox click
+         selectClickedRow : function (event) {
+            var checkbox = '';
+            var $row;
+            var source;
+            if (event.target.localName === 'input'){
+                checkbox = event.target;
+                $row = $(event.target.parentElement.parentElement);
+                source = 'input';
+            } else if (event.target.localName === 'td') {
+                checkbox = $("#" + event.target.parentElement.id).find(':checkbox')[0];
+                $row = $(event.target.parentElement);
+                source = 'td';
+            }
+
+                if (checkbox.checked){
+                    if (source==='td'){
+                        checkbox.checked = '';
+                        this.makeWhiteRow($row);
+                    } else if (source==='input') {
+                        this.makeDarkRow($row);
+                    }
+                } else {
+                    if (source==='td'){
+                        checkbox.checked = 'selected';
+                        this.makeDarkRow($row);
+                    } else if (source==='input') {
+                        this.makeWhiteRow($row);
+                    }
+                }
+                this.checkTools();
+        },
+
+        makeDarkRow: function($row){
+            $row.removeClass('light');
+            $row.find('a').removeClass('light');
+            $row.addClass('dark');
+            $row.find('a').addClass('dark');
+            $row.find('span').removeClass('fa-file-o');
+            $row.find('span').addClass('fa-file');
+
+        },
+
+        makeWhiteRow: function($row){
+            $row.removeClass('dark');
+            $row.find('a').removeClass('dark');
+            $row.addClass('light');
+            $row.find('a').addClass('light');
+            $row.find('span').addClass('fa-file-o');
+            $row.find('span').removeClass('fa-file');
+        },
+
+        // show toolbar in case something is selected
+        checkTools : function(){
+            var checkedValues = $('#folder_table').find(':checked');
+            if(checkedValues.length > 0){
+                $('#toolbtn_bulk_import').show();
+                $('#toolbtn_dl').show();
+            } else {
+                $('#toolbtn_bulk_import').hide();
+                $('#toolbtn_dl').hide();
+            }
+        },
+
+        // show bulk import modal
+        modalBulkImport : function(){
+            var self = this;
+            // fetch histories
+            var histories = new mod_library_model.GalaxyHistories();
+            histories.fetch({
+                    success: function (histories){
+                        // make modal
+                        var history_modal_tmpl =  _.template(self.templateBulkImportInModal(), {histories : histories.models});
+                        self.modal = Galaxy.modal;
+                        self.modal.show({
+                            closing_events  : true,
+                            title           : 'Import into History',
+                            body            : history_modal_tmpl,
+                            buttons         : {
+                                'Import'    : function() {self.importAllIntoHistory()},
+                                'Close'     : function() {self.modal.hide();}
+                            }
+                        });
+                    },
+                    error: function(){
+                      mod_toastr.error('An error occured :(');
+                    }
+                });
+        },
+
+        // import all selected datasets into history
+        importAllIntoHistory : function (){
+            //disable the button to prevent multiple submission
+            this.modal.disableButton('Import');
+
+            var history_id = $("select[name=dataset_import_bulk] option:selected").val();
+            var history_name = $("select[name=dataset_import_bulk] option:selected").text();
+
+            var dataset_ids = [];
+            $('#folder_table').find(':checked').each(function(){
+                if (this.parentElement.parentElement.id != '') {
+                    dataset_ids.push(this.parentElement.parentElement.id);
+                }
+            });
+            var progress_bar_tmpl = _.template(this.templateProgressBar(), { history_name : history_name });
+            $(this.modal.elMain).find('.modal-body').html(progress_bar_tmpl);
+
+            // init the progress bar
+            var progressStep = 100 / dataset_ids.length;
+            this.initProgress(progressStep);
+
+            // prepare the dataset objects to be imported
+            var datasets_to_import = [];
+            for (var i = dataset_ids.length - 1; i >= 0; i--) {
+                library_dataset_id = dataset_ids[i];
+                var historyItem = new mod_library_model.HistoryItem();
+                var self = this;
+                historyItem.url = historyItem.urlRoot + history_id + '/contents';
+                historyItem.content = library_dataset_id;
+                historyItem.source = 'library';
+                datasets_to_import.push(historyItem);
+            };
+
+            // call the recursive function to call ajax one after each other (request FIFO queue)
+            this.chainCall(datasets_to_import);
+        },
+
+        chainCall: function(history_item_set){
+            var self = this;
+            var popped_item = history_item_set.pop();
+            if (typeof popped_item === "undefined") {
+                mod_toastr.success('All datasets imported');
+                this.modal.hide();
+                return
+            }
+                var promise = $.when(popped_item.save({content: popped_item.content, source: popped_item.source})).done(function(a1){
+                        self.updateProgress();
+                        // responses.push(a1);
+                        self.chainCall(history_item_set);
+                    });
+        },
+
+        initProgress: function(progressStep){
+            this.progress = 0;
+            this.progressStep = progressStep;
+        },
+        updateProgress: function(){
+            this.progress += this.progressStep;
+            $('.progress-bar-import').width(Math.round(this.progress) + '%');
+            txt_representation = Math.round(this.progress) + '% Complete';
+            $('.completion_span').text(txt_representation);
+        },
+
+
+
+      // download selected datasets
+      download : function(folder_id, format){
+        var dataset_ids = [];
+            $('#folder_table').find(':checked').each(function(){
+                if (this.parentElement.parentElement.id != '') {
+                    dataset_ids.push(this.parentElement.parentElement.id);
+                }
+            });
+
+        var url = '/api/libraries/datasets/download/' + format;
+        var data = {'ldda_ids' : dataset_ids};
+        this.processDownload(url, data, 'get');
+      },
+
+      // create hidden form and submit through POST to initialize download
+      processDownload: function(url, data, method){
+        //url and data options required
+        if( url && data ){
+                //data can be string of parameters or array/object
+                data = typeof data == 'string' ? data : $.param(data);
+                //split params into form inputs
+                var inputs = '';
+                $.each(data.split('&'), function(){
+                        var pair = this.split('=');
+                        inputs+='<input type="hidden" name="'+ pair[0] +'" value="'+ pair[1] +'" />';
+                });
+                //send request
+                $('<form action="'+ url +'" method="'+ (method||'post') +'">'+inputs+'</form>')
+                .appendTo('body').submit().remove();
+                
+                mod_toastr.info('Your download will begin soon');
+        };
+      },
+
+      // shows modal for creating folder
+      createFolderFromModal: function(){
+        event.preventDefault();
+        event.stopPropagation();
+
+        // create modal
+        var self = this;
+        this.modal = Galaxy.modal;
+        this.modal.show({
+            closing_events  : true,
+            title           : 'Create New Folder',
+            body            : this.templateNewFolderInModal(),
+            buttons         : {
+                'Create'    : function() {self.create_new_folder_event()},
+                'Close'     : function() {self.modal.hide(); self.modal = null;}
+            }
+        });
+      },
+
+    // create the new folder from modal
+    create_new_folder_event: function(){
+        var folderDetails = this.serialize_new_folder();
+        if (this.validate_new_folder(folderDetails)){
+            var folder = new mod_library_model.FolderAsModel();
+
+            url_items = Backbone.history.fragment.split('/');
+            current_folder_id = url_items[url_items.length-1];
+            folder.url = folder.urlRoot + '/' + current_folder_id ;
+
+            var self = this;
+            folder.save(folderDetails, {
+              success: function (folder) {
+                self.modal.hide();
+                mod_toastr.success('Folder created');
+                self.render({id: current_folder_id});
+              },
+              error: function(){
+                mod_toastr.error('An error occured :(');
+              }
+            });
+        } else {
+            mod_toastr.error('Folder\'s name is missing');
+        }
+        return false;
+    },
+
+    // serialize data from the form
+    serialize_new_folder : function(){
+        return {
+            name: $("input[name='Name']").val(),
+            description: $("input[name='Description']").val()
+        };
+    },
+
+    // validate new library info
+    validate_new_folder: function(folderDetails){
+        return folderDetails.name !== '';
+    }
+
+    });
+
+// return
+return {
+    FolderContentView: FolderContentView
+};
+
+});
This diff is so big that we needed to truncate the remainder.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            commit/galaxy-central: martenson: libraries - exposed to anonymous users, allowed editing, deleting, undeleting, improved 'include deleted' filter, refactoring toolbar to have its own view
                        
                        
by commits-noreply@bitbucket.org 24 Mar '14
                    by commits-noreply@bitbucket.org 24 Mar '14
24 Mar '14
                    
                        1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/33cc6056d837/
Changeset:   33cc6056d837
User:        martenson
Date:        2014-03-24 16:16:36
Summary:     libraries - exposed to anonymous users, allowed editing, deleting, undeleting, improved 'include deleted' filter, refactoring toolbar to have its own view
Affected #:  6 files
diff -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 -r 33cc6056d83760e5e3b98999b01ecb260423d33c lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -209,7 +209,7 @@
                            '/api/libraries/:id',
                            controller='libraries',
                            action='update',
-                           conditions=dict( method=[ "PATCH" ] ) )
+                           conditions=dict( method=[ "PATCH", 'PUT' ] ) )
 
     webapp.mapper.connect( 'show_lda_item',
                            '/api/libraries/datasets/:id',
diff -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 -r 33cc6056d83760e5e3b98999b01ecb260423d33c static/scripts/galaxy.library.js
--- a/static/scripts/galaxy.library.js
+++ b/static/scripts/galaxy.library.js
@@ -19,7 +19,7 @@
 
     // LIBRARY
     var Library = Backbone.Model.extend({
-      urlRoot: '/api/libraries'
+      urlRoot: '/api/libraries/'
     });
 
     // FOLDER AS MODEL
@@ -122,7 +122,7 @@
         // TOOLBAR
         tmpl_array.push('<div id="library_folder_toolbar" >');
         tmpl_array.push('   <button title="Create New Folder" id="toolbtn_create_folder" class="primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');
-        tmpl_array.push('   <button title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-external-link"></span> to history</button>');
+        tmpl_array.push('   <button title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-book"></span> to history</button>');
         tmpl_array.push('   <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');
         tmpl_array.push('       <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');
         tmpl_array.push('       <span class="fa fa-download"></span> download <span class="caret"></span>');
@@ -208,7 +208,7 @@
         var tmpl_array = [];
 
         tmpl_array.push('<div class="modal_table">');
-        tmpl_array.push('   <table class="table table-striped table-condensed">');
+        tmpl_array.push('   <table class="grid table table-striped table-condensed">');
         tmpl_array.push('       <tr>');
         tmpl_array.push('           <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');
         tmpl_array.push('           <td><%= _.escape(item.get("name")) %></td>');
@@ -266,9 +266,9 @@
     templateHistorySelectInModal : function(){
         var tmpl_array = [];
 
-        tmpl_array.push('<span id="history_modal_combo" style="width:90%; margin-left: 1em; margin-right: 1em; ">');
+        tmpl_array.push('<span id="history_modal_combo" style="width:100%; margin-left: 1em; margin-right: 1em; ">');
         tmpl_array.push('Select history: ');
-        tmpl_array.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');
+        tmpl_array.push('<select id="dataset_import_single" name="dataset_import_single" style="width:40%; margin-bottom: 1em; "> ');
         tmpl_array.push('   <% _.each(histories, function(history) { %>'); //history select box
         tmpl_array.push('       <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');
         tmpl_array.push('   <% }); %>');
@@ -457,7 +457,7 @@
                 }
             });
             
-            $(".peek").html(item.get("peek"));
+            $(".peek").html('Peek:' + item.get("peek"));
 
             // show the import-into-history footer only if the request for histories succeeded
             if (typeof history.models !== undefined){
@@ -783,10 +783,14 @@
 
 // galaxy library view
 var GalaxyLibraryview = Backbone.View.extend({
-    el: '#center',
+    el: '#libraries_element',
 
     events: {
-        'click #create_new_library_btn' : 'show_library_modal'
+        'click .edit_library_btn'   : 'edit_button_event',
+        'click .save_library_btn'   : 'save_library_modification',
+        'click .cancel_library_btn' : 'cancel_library_modification',
+        'click .delete_library_btn' : 'delete_library',
+        'click .undelete_library_btn' : 'undelete_library'
     },
 
     modal: null,
@@ -801,19 +805,15 @@
         this.collection.fetch({
           success: function(libraries){
             viewContext.render();
+            // initialize the library tooltips
+            $("#center [data-toggle]").tooltip();
+            // modification of upper DOM element to show scrollbars due to the #center element inheritance
+            $("#center").css('overflow','auto');
           },
           error: function(model, response){
-
-            if (response.statusCode().status === 403){ //TODO open to public
-                mod_toastr.info('Please log in first. Redirecting to login page in 3s.');   
-                setTimeout(that.redirectToLogin, 3000);
-            } else {
-                mod_toastr.error('An error occured. Please try again.');
-            }
+            mod_toastr.error('An error occured. Please try again.');
           }
         })
-        // modification of upper DOM element to show scrollbars due to the #center element inheritance
-        $("#center").css('overflow','auto');
     },
 
     /** Renders the libraries table either from the object's own collection, 
@@ -875,39 +875,40 @@
     templateLibraryList: function(){
         tmpl_array = [];
 
-        tmpl_array.push('<div class="library_container" style="width: 90%; margin: auto; margin-top: 2em; overflow: auto !important; ">');
-
-        tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
-        tmpl_array.push('<div id="library_toolbar">');
-        tmpl_array.push('   <button title="Create New Library" id="create_new_library_btn" class="primary-button" type="button"><span class="fa fa-plus"></span> New Library</button>');
-        tmpl_array.push('</div>');
-
+        tmpl_array.push('<div class="library_container table-responsive">');
         tmpl_array.push('<% if(libraries.length === 0) { %>');
         tmpl_array.push("<div>I see no libraries. Why don't you create one?</div>");
         tmpl_array.push('<% } else{ %>');
         tmpl_array.push('<table class="grid table table-condensed">');
         tmpl_array.push('   <thead>');
-        tmpl_array.push('     <th><a title="Click to reverse order" href="#sort/name/<% if(order==="desc"||order===null){print("asc")}else{print("desc")} %>">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');
-        tmpl_array.push('     <th>description</th>');
-        tmpl_array.push('     <th>synopsis</th> ');
+        tmpl_array.push('     <th style="width:30%;"><a title="Click to reverse order" href="#sort/name/<% if(order==="desc"||order===null){print("asc")}else{print("desc")} %>">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');
+        tmpl_array.push('     <th style="width:22%;">description</th>');
+        tmpl_array.push('     <th style="width:22%;">synopsis</th> ');
+        tmpl_array.push('     <th style="width:26%;"></th> ');
         tmpl_array.push('   </thead>');
         tmpl_array.push('   <tbody>');
         tmpl_array.push('       <% _.each(libraries, function(library) { %>');
-        tmpl_array.push('           <tr>');
+        tmpl_array.push('           <tr class="<% if(library.get("deleted") === true){print("active");}%>" data-id="<%- library.get("id") %>">');
         tmpl_array.push('               <td><a href="#folders/<%- library.get("root_folder_id") %>"><%- library.get("name") %></a></td>');
         tmpl_array.push('               <td><%= _.escape(library.get("description")) %></td>');
         tmpl_array.push('               <td><%= _.escape(library.get("synopsis")) %></td>');
+        tmpl_array.push('               <td class="right-center">');
+        tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Modify library" class="primary-button btn-xs edit_library_btn" type="button"><span class="fa fa-pencil"></span></button>');
+        tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Save changes" class="primary-button btn-xs save_library_btn" type="button" style="display:none;"><span class="fa fa-floppy-o"> Save</span></button>');
+        tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Discard changes" class="primary-button btn-xs cancel_library_btn" type="button" style="display:none;"><span class="fa fa-times"> Cancel</span></button>');
+        tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Delete library (can be undeleted later)" class="primary-button btn-xs delete_library_btn" type="button" style="display:none;"><span class="fa fa-trash-o"> Delete</span></button>');
+        tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Undelete library" class="primary-button btn-xs undelete_library_btn" type="button" style="display:none;"><span class="fa fa-unlock"> Undelete</span></button>');
+        tmpl_array.push('               </td>');
         tmpl_array.push('           </tr>');
         tmpl_array.push('       <% }); %>');
         tmpl_array.push('   </tbody>');
         tmpl_array.push('</table>');
         tmpl_array.push('<% }%>');
-        
         tmpl_array.push('</div>');
 
         return _.template(tmpl_array.join(''));
     },
-
+    
     templateNewLibraryInModal: function(){
         tmpl_array = [];
 
@@ -922,6 +923,148 @@
         return tmpl_array.join('');
     },
 
+    save_library_modification: function(event){
+        var $library_row = $(event.target).closest('tr');
+        var library = this.collection.get($library_row.data('id'));
+
+        var is_changed = false;
+
+        var new_name = $library_row.find('.input_library_name').val();
+        if (typeof new_name !== 'undefined' && new_name !== library.get('name') ){
+            if (new_name.length > 2){
+                library.set("name", new_name);
+                is_changed = true;
+            } else{
+                mod_toastr.warning('Library name has to be at least 3 characters long');
+                return
+            }
+        }
+
+        var new_description = $library_row.find('.input_library_description').val();
+        if (typeof new_description !== 'undefined' && new_description !== library.get('description') ){
+            library.set("description", new_description);
+            is_changed = true;
+        }
+
+        var new_synopsis = $library_row.find('.input_library_synopsis').val();
+        if (typeof new_synopsis !== 'undefined' && new_synopsis !== library.get('synopsis') ){
+            library.set("synopsis", new_synopsis);
+            is_changed = true;
+        }
+
+        if (is_changed){
+            library.save(null, {
+              patch: true,
+              success: function(library) {
+                mod_toastr.success('Changes to library saved');
+                galaxyLibraryview.toggle_library_modification($library_row);
+              },
+              error: function(model, response){
+                mod_toastr.error('An error occured during updating the library :(');
+              }
+            });
+        }
+    },
+
+    edit_button_event: function(event){
+      this.toggle_library_modification($(event.target).closest('tr'));
+    },
+
+    toggle_library_modification: function($library_row){
+        var library = this.collection.get($library_row.data('id'));
+
+        $library_row.find('.edit_library_btn').toggle();
+        $library_row.find('.save_library_btn').toggle();
+        $library_row.find('.cancel_library_btn').toggle();
+        if (library.get('deleted')){
+            $library_row.find('.undelete_library_btn').toggle();
+        } else {
+            $library_row.find('.delete_library_btn').toggle();
+        }
+
+        if ($library_row.find('.edit_library_btn').is(':hidden')){
+            // library name
+            var current_library_name = library.get('name');
+            var new_html = '<input type="text" class="form-control input_library_name" placeholder="name">';
+            $library_row.children('td').eq(0).html(new_html);
+            if (typeof current_library_name !== undefined){
+                $library_row.find('.input_library_name').val(current_library_name);
+            }
+            // library description
+            var current_library_description = library.get('description');
+            var new_html = '<input type="text" class="form-control input_library_description" placeholder="description">';
+            $library_row.children('td').eq(1).html(new_html);
+            if (typeof current_library_description !== undefined){
+                $library_row.find('.input_library_description').val(current_library_description);
+            }
+            // library synopsis
+            var current_library_synopsis = library.get('synopsis');
+            var new_html = '<input type="text" class="form-control input_library_synopsis" placeholder="synopsis">';
+            $library_row.children('td').eq(2).html(new_html);
+            if (typeof current_library_synopsis !== undefined){
+                $library_row.find('.input_library_synopsis').val(current_library_synopsis);
+            }
+        } else {
+            $library_row.children('td').eq(0).html(library.get('name'));
+            $library_row.children('td').eq(1).html(library.get('description'));
+            $library_row.children('td').eq(2).html(library.get('synopsis'));
+        }
+        
+    },
+
+    cancel_library_modification: function(event){
+        var $library_row = $(event.target).closest('tr');
+        var library = this.collection.get($library_row.data('id'));
+        this.toggle_library_modification($library_row);
+
+        $library_row.children('td').eq(0).html(library.get('name'));
+        $library_row.children('td').eq(1).html(library.get('description'));
+        $library_row.children('td').eq(2).html(library.get('synopsis'));
+    },
+
+    undelete_library: function(event){
+        var $library_row = $(event.target).closest('tr');
+        var library = this.collection.get($library_row.data('id'));
+        this.toggle_library_modification($library_row);
+
+        // mark the library undeleted
+        library.url = library.urlRoot + library.id + '?undelete=true';
+        library.destroy({
+          success: function (library) {
+            // add the newly undeleted library back to the collection
+            // backbone does not accept changes through destroy, so update it too
+            library.set('deleted', false);
+            galaxyLibraryview.collection.add(library);
+            $library_row.removeClass('active');
+            mod_toastr.success('Library has been undeleted');
+          },
+          error: function(){
+            mod_toastr.error('An error occured while undeleting the library :(');
+          }
+        });
+    },
+
+    delete_library: function(event){
+        var $library_row = $(event.target).closest('tr');
+        var library = this.collection.get($library_row.data('id'));
+        this.toggle_library_modification($library_row);
+
+        // mark the library deleted
+        library.destroy({
+          success: function (library) {
+            // add the new deleted library back to the collection
+            $library_row.remove();
+            library.set('deleted', true);
+            galaxyLibraryview.collection.add(library);
+            mod_toastr.success('Library has been marked deleted');
+          },
+          error: function(){
+            mod_toastr.error('An error occured during deleting the library :(');
+          }
+        });
+
+    },
+
     redirectToHome: function(){
         window.location = '../';
     },    
@@ -994,6 +1137,56 @@
     }
 });
 
+var ToolbarView = Backbone.View.extend({
+  el: '#center',
+
+  events: {        
+    'click #create_new_library_btn' : 'delegate_modal',
+    'click #include_deleted_chk'    : 'check_include_deleted'
+  },
+
+  initialize: function(){
+    this.render();
+  },
+
+  delegate_modal: function(event){
+    // probably should refactor to have this functionality in this view, not in the library view
+    galaxyLibraryview.show_library_modal(event);
+  },
+
+  // include or exclude deleted libraries from the view
+  check_include_deleted: function(event){
+    if (event.target.checked){
+        galaxyLibraryview.render( {'with_deleted': true} );
+    } else{
+        galaxyLibraryview.render({'with_deleted': false});
+    }
+  },
+
+  render: function(){
+    var toolbar_template = this.templateToolBar()
+    this.$el.html(toolbar_template())
+  },
+
+  templateToolBar: function(){
+    tmpl_array = [];
+
+    tmpl_array.push('<div id="libraries_container" style="width: 90%; margin: auto; margin-top:2em; overflow: auto !important; ">');
+    // TOOLBAR
+    tmpl_array.push('  <div id="toolbar_form" margin-top:0.5em; ">');
+    tmpl_array.push('       <h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
+    tmpl_array.push('       <div id="library_toolbar">');
+    tmpl_array.push('           <input id="include_deleted_chk" style="margin: 0;" type="checkbox">include deleted</input>');
+    tmpl_array.push('           <button data-toggle="tooltip" data-placement="top" title="Create New Library" id="create_new_library_btn" class="primary-button" type="button"><span class="fa fa-plus"></span> New Library</button>');
+    tmpl_array.push('       </div>');
+    tmpl_array.push('  </div>');
+    tmpl_array.push('  <div id="libraries_element">');
+    tmpl_array.push('  </div>');
+    tmpl_array.push('</div>');
+
+    return _.template(tmpl_array.join(''));
+  }
+})
 
 //ROUTER
 var LibraryRouter = Backbone.Router.extend({
@@ -1007,18 +1200,18 @@
 
 // galaxy library wrapper View
 var GalaxyLibrary = Backbone.View.extend({
-    // folderContentView : null,
-    // galaxyLibraryview : null,
 
     initialize : function(){
-
+        toolbarView = new ToolbarView();
         galaxyLibraryview = new GalaxyLibraryview();
         library_router = new LibraryRouter();
         folderContentView = new FolderContentView();
 
         library_router.on('route:libraries', function() {
-          // render libraries list
-          galaxyLibraryview.render();
+          // initialize and render the toolbar first
+          toolbarView = new ToolbarView();
+          // initialize and render libraries second
+          galaxyLibraryview = new GalaxyLibraryview();
         });
 
         library_router.on('route:sort_libraries', function(sort_by, order) {
@@ -1028,9 +1221,7 @@
         });
 
         library_router.on('route:folder_content', function(id) {
-            // if (this.folderContentView === null){
-            // }
-          // render folder's contents
+          // render folder contents
           folderContentView.render({id: id});
         });
 
diff -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 -r 33cc6056d83760e5e3b98999b01ecb260423d33c static/scripts/packed/galaxy.library.js
--- a/static/scripts/packed/galaxy.library.js
+++ b/static/scripts/packed/galaxy.library.js
@@ -1,1 +1,1 @@
-var view=null;var library_router=null;var responses=[];define(["galaxy.masthead","utils/utils","libs/toastr"],function(k,h,m){var f=Backbone.Model.extend({urlRoot:"/api/libraries"});var c=Backbone.Model.extend({urlRoot:"/api/folders"});var n=Backbone.Collection.extend({url:"/api/libraries",model:f,sort_key:"name",sort_order:null,});var i=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var d=Backbone.Collection.extend({model:i});var e=Backbone.Model.extend({defaults:{folder:new d(),full_path:"unknown",urlRoot:"/api/folders/",id:"unknown"},parse:function(q){this.full_path=q[0].full_path;this.get("folder").reset(q[1].folder_contents);return q}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var j=Backbone.Model.extend({url:"/api/histories/"});var o=Backbone.Collection.extend({url:"/api/histories",model:j});var l=Backbone.View.extend({el:"#center",progress:0,progressStep:1,lastSelectedHistory:"",modal:null,folders:null,initialize:function(){this.folders=[];this.queue=jQuery.Deferred();this.queue.resolve()},templateFolder:function(){var q=[];q.push('<div class="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');q.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');q.push('<div id="library_folder_toolbar" >');q.push('   <button title="Create New Folder" id="toolbtn_create_folder" class="primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');q.push('   <button title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-external-link"></span> to history</button>');q.push('   <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');q.push('       <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');q.push('       <span class="fa fa-download"></span> download <span class="caret"></span>');q.push("       </button>");q.push('       <ul class="dropdown-menu" role="menu">');q.push('          <li><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');q.push('          <li><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');q.push('          <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');q.push("       </ul>");q.push("   </div>");q.push("</div>");q.push('<ol class="breadcrumb">');q.push('   <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');q.push("   <% _.each(path, function(path_item) { %>");q.push("   <% if (path_item[0] != id) { %>");q.push('   <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');q.push("<% } else { %>");q.push('   <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');q.push("   <% } %>");q.push("   <% }); %>");q.push("</ol>");q.push('<table id="folder_table" class="grid table table-condensed">');q.push("   <thead>");q.push('       <th class="button_heading"></th>');q.push('       <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');q.push("       <th>name</th>");q.push("       <th>data type</th>");q.push("       <th>size</th>");q.push("       <th>date (UTC)</th>");q.push("   </thead>");q.push("   <tbody>");q.push('       <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');q.push("       <td></td>");q.push("       <td></td>");q.push("       <td></td>");q.push("       <td></td>");q.push("       <td></td>");q.push("       </tr>");q.push("       <% _.each(items, function(content_item) { %>");q.push('           <% if (content_item.get("type") === "folder") { %>');q.push('               <tr class="folder_row light" id="<%- content_item.id %>">');q.push("                   <td>");q.push('                       <span title="Folder" class="fa fa-folder-o"></span>');q.push("                   </td>");q.push("                   <td></td>");q.push("                   <td>");q.push('                       <a href="#folders/<%- content_item.id %>"><%- content_item.get("name") %></a>');q.push('                       <% if (content_item.get("item_count") === 0) { %>');q.push('                           <span class="muted">(empty folder)</span>');q.push("                       <% } %>");q.push("                   </td>");q.push("                   <td>folder</td>");q.push('                   <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>');q.push('                   <td><%= _.escape(content_item.get("time_updated")) %></td>');q.push("               </tr>");q.push("           <% } else {  %>");q.push('               <tr class="dataset_row light" id="<%- content_item.id %>">');q.push("                   <td>");q.push('                       <span title="Dataset" class="fa fa-file-o"></span>');q.push("                   </td>");q.push('                   <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');q.push('                   <td><a href="#" class="library-dataset"><%- content_item.get("name") %><a></td>');q.push('                   <td><%= _.escape(content_item.get("data_type")) %></td>');q.push('                   <td><%= _.escape(content_item.get("readable_size")) %></td>');q.push('                   <td><%= _.escape(content_item.get("time_updated")) %></td>');q.push("               </tr>");q.push("               <% } %>  ");q.push("       <% }); %>");q.push("       ");q.push("   </tbody>");q.push("</table>");q.push("</div>");return q.join("")},templateDatasetModal:function(){var q=[];q.push('<div class="modal_table">');q.push('   <table class="table table-striped table-condensed">');q.push("       <tr>");q.push('           <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');q.push('           <td><%= _.escape(item.get("name")) %></td>');q.push("       </tr>");q.push("       <tr>");q.push('           <th scope="row">Data type</th>');q.push('           <td><%= _.escape(item.get("data_type")) %></td>');q.push("       </tr>");q.push("       <tr>");q.push('           <th scope="row">Genome build</th>');q.push('           <td><%= _.escape(item.get("genome_build")) %></td>');q.push("       </tr>");q.push('           <th scope="row">Size</th>');q.push("           <td><%= _.escape(size) %></td>");q.push("       </tr>");q.push("       <tr>");q.push('           <th scope="row">Date uploaded (UTC)</th>');q.push('           <td><%= _.escape(item.get("date_uploaded")) %></td>');q.push("       </tr>");q.push("       <tr>");q.push('           <th scope="row">Uploaded by</th>');q.push('           <td><%= _.escape(item.get("uploaded_by")) %></td>');q.push("       </tr>");q.push('           <tr scope="row">');q.push('           <th scope="row">Data Lines</th>');q.push('           <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');q.push("       </tr>");q.push('       <th scope="row">Comment Lines</th>');q.push('           <% if (item.get("metadata_comment_lines") === "") { %>');q.push('               <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');q.push("           <% } else { %>");q.push('               <td scope="row">unknown</td>');q.push("           <% } %>");q.push("       </tr>");q.push("       <tr>");q.push('           <th scope="row">Number of Columns</th>');q.push('           <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');q.push("       </tr>");q.push("       <tr>");q.push('           <th scope="row">Column Types</th>');q.push('           <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');q.push("       </tr>");q.push("       <tr>");q.push('           <th scope="row">Miscellaneous information</th>');q.push('           <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');q.push("       </tr>");q.push("   </table>");q.push('   <pre class="peek">');q.push("   </pre>");q.push("</div>");return q.join("")},templateHistorySelectInModal:function(){var q=[];q.push('<span id="history_modal_combo" style="width:90%; margin-left: 1em; margin-right: 1em; ">');q.push("Select history: ");q.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');q.push("   <% _.each(histories, function(history) { %>");q.push('       <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');q.push("   <% }); %>");q.push("</select>");q.push("</span>");return q.join("")},templateBulkImportInModal:function(){var q=[];q.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');q.push("Select history: ");q.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');q.push("   <% _.each(histories, function(history) { %>");q.push('       <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');q.push("   <% }); %>");q.push("</select>");q.push("</span>");return q.join("")},templateProgressBar:function(){var q=[];q.push('<div class="import_text">');q.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");q.push("</div>");q.push('<div class="progress">');q.push('   <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');q.push('       <span class="completion_span">0% Complete</span>');q.push("   </div>");q.push("</div>");q.push("");return q.join("")},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return tmpl_array.join("")},events:{"click #select-all-checkboxes":"selectAll","click #toolbtn_bulk_import":"modalBulkImport","click #toolbtn_dl":"bulkDownload","click #toolbtn_create_folder":"createFolderFromModal","click .library-dataset":"showDatasetDetails","click .dataset_row":"selectClickedRow"},render:function(q){$("#center").css("overflow","auto");view=this;var s=this;var r=new e({id:q.id});r.url=r.attributes.urlRoot+q.id+"/contents";r.fetch({success:function(t){for(var v=0;v<r.attributes.folder.models.length;v++){var u=r.attributes.folder.models[v];if(u.get("type")==="file"){u.set("readable_size",s.size_to_string(u.get("file_size")))}}var x=r.full_path;var y;if(x.length===1){y=0}else{y=x[x.length-2][0]}var w=_.template(s.templateFolder(),{path:r.full_path,items:r.attributes.folder.models,id:q.id,upper_folder_id:y});s.$el.html(w)},error:function(){m.error("An error occured :(")}})},size_to_string:function(q){var r="";if(q>=100000000000){q=q/100000000000;r="TB"}else{if(q>=100000000){q=q/100000000;r="GB"}else{if(q>=100000){q=q/100000;r="MB"}else{if(q>=100){q=q/100;r="KB"}else{q=q*10;r="b"}}}}return(Math.round(q)/10)+r},showDatasetDetails:function(t){t.preventDefault();var u=$(t.target).parent().parent().parent().attr("id");if(typeof u==="undefined"){u=$(t.target).parent().attr("id")}if(typeof u==="undefined"){u=$(t.target).parent().parent().attr("id")}var s=new i();var r=new o();s.id=u;var q=this;s.fetch({success:function(v){r.fetch({success:function(w){q.renderModalAfterFetch(v,w)},error:function(){m.error("An error occured during fetching histories:(");q.renderModalAfterFetch(v)}})},error:function(){m.error("An error occured during loading dataset details :(")}})},renderModalAfterFetch:function(v,s){var t=this.size_to_string(v.get("file_size"));var u=_.template(this.templateDatasetModal(),{item:v,size:t});var r=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Dataset Details",body:u,buttons:{Import:function(){r.importCurrentIntoHistory()},Download:function(){r.downloadCurrent()},Close:function(){r.modal.hide()}}});$(".peek").html(v.get("peek"));if(typeof history.models!==undefined){var q=_.template(this.templateHistorySelectInModal(),{histories:s.models});$(this.modal.elMain).find(".buttons").prepend(q);if(r.lastSelectedHistory.length>0){$(this.modal.elMain).find("#dataset_import_single").val(r.lastSelectedHistory)}}},downloadCurrent:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var q=[];q.push($("#id_row").attr("data-id"));var r="/api/libraries/datasets/download/uncompressed";var s={ldda_ids:q};folderContentView.processDownload(r,s);this.modal.enableButton("Import");this.modal.enableButton("Download")},importCurrentIntoHistory:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var s=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();this.lastSelectedHistory=s;var q=$("#id_row").attr("data-id");var t=new b();var r=this;t.url=t.urlRoot+s+"/contents";t.save({content:q,source:"library"},{success:function(){m.success("Dataset imported");r.modal.enableButton("Import");r.modal.enableButton("Download")},error:function(){m.error("An error occured! Dataset not imported. Please try again.");r.modal.enableButton("Import");r.modal.enableButton("Download")}})},selectAll:function(r){var q=r.target.checked;that=this;$(":checkbox").each(function(){this.checked=q;$row=$(this.parentElement.parentElement);(q)?that.makeDarkRow($row):that.makeWhiteRow($row)});this.checkTools()},selectClickedRow:function(r){var t="";var q;var s;if(r.target.localName==="input"){t=r.target;q=$(r.target.parentElement.parentElement);s="input"}else{if(r.target.localName==="td"){t=$("#"+r.target.parentElement.id).find(":checkbox")[0];q=$(r.target.parentElement);s="td"}}if(t.checked){if(s==="td"){t.checked="";this.makeWhiteRow(q)}else{if(s==="input"){this.makeDarkRow(q)}}}else{if(s==="td"){t.checked="selected";this.makeDarkRow(q)}else{if(s==="input"){this.makeWhiteRow(q)}}}this.checkTools()},makeDarkRow:function(q){q.removeClass("light");q.find("a").removeClass("light");q.addClass("dark");q.find("a").addClass("dark");q.find("span").removeClass("fa-file-o");q.find("span").addClass("fa-file")},makeWhiteRow:function(q){q.removeClass("dark");q.find("a").removeClass("dark");q.addClass("light");q.find("a").addClass("light");q.find("span").addClass("fa-file-o");q.find("span").removeClass("fa-file")},checkTools:function(){var q=$("#folder_table").find(":checked");if(q.length>0){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}else{$("#toolbtn_bulk_import").hide();$("#toolbtn_dl").hide()}},modalBulkImport:function(){var r=this;var q=new o();q.fetch({success:function(s){var t=_.template(r.templateBulkImportInModal(),{histories:s.models});r.modal=Galaxy.modal;r.modal.show({closing_events:true,title:"Import into History",body:t,buttons:{Import:function(){r.importAllIntoHistory()},Close:function(){r.modal.hide()}}})},error:function(){m.error("An error occured :(")}})},importAllIntoHistory:function(){this.modal.disableButton("Import");var s=$("select[name=dataset_import_bulk] option:selected").val();var w=$("select[name=dataset_import_bulk] option:selected").text();var y=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){y.push(this.parentElement.parentElement.id)}});var x=_.template(this.templateProgressBar(),{history_name:w});$(this.modal.elMain).find(".modal-body").html(x);var t=100/y.length;this.initProgress(t);var q=[];for(var r=y.length-1;r>=0;r--){library_dataset_id=y[r];var u=new b();var v=this;u.url=u.urlRoot+s+"/contents";u.content=library_dataset_id;u.source="library";q.push(u)}this.chainCall(q)},chainCall:function(r){var q=this;var s=r.pop();if(typeof s==="undefined"){m.success("All datasets imported");this.modal.hide();return}var t=$.when(s.save({content:s.content,source:s.source})).done(function(u){q.updateProgress();responses.push(u);q.chainCall(r)})},initProgress:function(q){this.progress=0;this.progressStep=q},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(q,u){var s=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){s.push(this.parentElement.parentElement.id)}});var r="/api/libraries/datasets/download/"+u;var t={ldda_ids:s};this.processDownload(r,t,"get")},processDownload:function(r,s,t){if(r&&s){s=typeof s=="string"?s:$.param(s);var q="";$.each(s.split("&"),function(){var u=this.split("=");q+='<input type="hidden" name="'+u[0]+'" value="'+u[1]+'" />'});$('<form action="'+r+'" method="'+(t||"post")+'">'+q+"</form>").appendTo("body").submit().remove();m.info("Your download will begin soon")}},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var q=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:this.templateNewFolderInModal(),buttons:{Create:function(){q.create_new_folder_event()},Close:function(){q.modal.hide();q.modal=null}}})},create_new_folder_event:function(){var q=this.serialize_new_folder();if(this.validate_new_folder(q)){var s=new c();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];s.url=s.urlRoot+"/"+current_folder_id;var r=this;s.save(q,{success:function(t){r.modal.hide();m.success("Folder created");r.render({id:current_folder_id})},error:function(){m.error("An error occured :(")}})}else{m.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(q){return q.name!==""}});var a=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"show_library_modal"},modal:null,collection:null,initialize:function(){var q=this;this.collection=new n();this.collection.fetch({success:function(r){q.render()},error:function(s,r){if(r.statusCode().status===403){m.info("Please log in first. Redirecting to login page in 3s.");setTimeout(that.redirectToLogin,3000)}else{m.error("An error occured. Please try again.")}}});$("#center").css("overflow","auto")},render:function(r){var s=this.templateLibraryList();var t=null;var q=false;var u=null;if(typeof r!=="undefined"){q=typeof r.with_deleted!=="undefined"?r.with_deleted:false;u=typeof r.models!=="undefined"?r.models:null}if(this.collection!==null&&u===null){if(q){t=this.collection.models}else{t=this.collection.where({deleted:false})}}else{if(u!==null){t=u}else{t=[]}}this.$el.html(s({libraries:t,order:this.collection.sort_order}))},sortLibraries:function(r,q){if(r==="name"){if(q==="asc"){this.collection.sort_order="asc";this.collection.comparator=function(t,s){if(t.get("name").toLowerCase()>s.get("name").toLowerCase()){return 1}if(s.get("name").toLowerCase()>t.get("name").toLowerCase()){return -1}return 0}}else{if(q==="desc"){this.collection.sort_order="desc";this.collection.comparator=function(t,s){if(t.get("name").toLowerCase()>s.get("name").toLowerCase()){return -1}if(s.get("name").toLowerCase()>t.get("name").toLowerCase()){return 1}return 0}}}this.collection.sort()}},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('<div class="library_container" style="width: 90%; margin: auto; margin-top: 2em; overflow: auto !important; ">');tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push('<div id="library_toolbar">');tmpl_array.push('   <button title="Create New Library" id="create_new_library_btn" class="primary-button" type="button"><span class="fa fa-plus"></span> New Library</button>');tmpl_array.push("</div>");tmpl_array.push("<% if(libraries.length === 0) { %>");tmpl_array.push("<div>I see no libraries. Why don't you create one?</div>");tmpl_array.push("<% } else{ %>");tmpl_array.push('<table class="grid table table-condensed">');tmpl_array.push("   <thead>");tmpl_array.push('     <th><a title="Click to reverse order" href="#sort/name/<% if(order==="desc"||order===null){print("asc")}else{print("desc")} %>">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');tmpl_array.push("     <th>description</th>");tmpl_array.push("     <th>synopsis</th> ");tmpl_array.push("   </thead>");tmpl_array.push("   <tbody>");tmpl_array.push("       <% _.each(libraries, function(library) { %>");tmpl_array.push("           <tr>");tmpl_array.push('               <td><a href="#folders/<%- library.get("root_folder_id") %>"><%- library.get("name") %></a></td>');tmpl_array.push('               <td><%= _.escape(library.get("description")) %></td>');tmpl_array.push('               <td><%= _.escape(library.get("synopsis")) %></td>');tmpl_array.push("           </tr>");tmpl_array.push("       <% }); %>");tmpl_array.push("   </tbody>");tmpl_array.push("</table>");tmpl_array.push("<% }%>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push("   <form>");tmpl_array.push('       <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('       <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push('       <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push("   </form>");tmpl_array.push("</div>");return tmpl_array.join("")},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},show_library_modal:function(r){r.preventDefault();r.stopPropagation();var q=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){q.create_new_library_event()},Close:function(){q.modal.hide()}}})},create_new_library_event:function(){var s=this.serialize_new_library();if(this.validate_new_library(s)){var r=new f();var q=this;r.save(s,{success:function(t){q.collection.add(t);q.modal.hide();q.clear_library_modal();q.render();m.success("Library created")},error:function(){m.error("An error occured :(")}})}else{m.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(q){return q.name!==""}});var p=Backbone.Router.extend({routes:{"":"libraries","sort/:sort_by/:order":"sort_libraries","folders/:id":"folder_content","folders/:folder_id/download/:format":"download"}});var g=Backbone.View.extend({initialize:function(){galaxyLibraryview=new a();library_router=new p();folderContentView=new l();library_router.on("route:libraries",function(){galaxyLibraryview.render()});library_router.on("route:sort_libraries",function(r,q){galaxyLibraryview.sortLibraries(r,q);galaxyLibraryview.render()});library_router.on("route:folder_content",function(q){folderContentView.render({id:q})});library_router.on("route:download",function(q,r){if($("#center").find(":checked").length===0){library_router.navigate("folders/"+q,{trigger:true,replace:true})}else{folderContentView.download(q,r);library_router.navigate("folders/"+q,{trigger:false,replace:true})}});Backbone.history.start({pushState:false})}});return{GalaxyApp:g}});
\ No newline at end of file
+var view=null;var library_router=null;var responses=[];define(["galaxy.masthead","utils/utils","libs/toastr"],function(l,i,n){var f=Backbone.Model.extend({urlRoot:"/api/libraries/"});var c=Backbone.Model.extend({urlRoot:"/api/folders"});var o=Backbone.Collection.extend({url:"/api/libraries",model:f,sort_key:"name",sort_order:null,});var j=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var d=Backbone.Collection.extend({model:j});var e=Backbone.Model.extend({defaults:{folder:new d(),full_path:"unknown",urlRoot:"/api/folders/",id:"unknown"},parse:function(r){this.full_path=r[0].full_path;this.get("folder").reset(r[1].folder_contents);return r}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var k=Backbone.Model.extend({url:"/api/histories/"});var p=Backbone.Collection.extend({url:"/api/histories",model:k});var m=Backbone.View.extend({el:"#center",progress:0,progressStep:1,lastSelectedHistory:"",modal:null,folders:null,initialize:function(){this.folders=[];this.queue=jQuery.Deferred();this.queue.resolve()},templateFolder:function(){var r=[];r.push('<div class="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');r.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');r.push('<div id="library_folder_toolbar" >');r.push('   <button title="Create New Folder" id="toolbtn_create_folder" class="primary-button" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');r.push('   <button title="Import selected datasets into history" id="toolbtn_bulk_import" class="primary-button" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-book"></span> to history</button>');r.push('   <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');r.push('       <button title="Download selected datasets" id="drop_toggle" type="button" class="primary-button dropdown-toggle" data-toggle="dropdown">');r.push('       <span class="fa fa-download"></span> download <span class="caret"></span>');r.push("       </button>");r.push('       <ul class="dropdown-menu" role="menu">');r.push('          <li><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');r.push('          <li><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');r.push('          <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');r.push("       </ul>");r.push("   </div>");r.push("</div>");r.push('<ol class="breadcrumb">');r.push('   <li><a title="Return to the list of libraries" href="#">Libraries</a></li>');r.push("   <% _.each(path, function(path_item) { %>");r.push("   <% if (path_item[0] != id) { %>");r.push('   <li><a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a></li> ');r.push("<% } else { %>");r.push('   <li class="active"><span title="You are in this folder"><%- path_item[1] %></span></li>');r.push("   <% } %>");r.push("   <% }); %>");r.push("</ol>");r.push('<table id="folder_table" class="grid table table-condensed">');r.push("   <thead>");r.push('       <th class="button_heading"></th>');r.push('       <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');r.push("       <th>name</th>");r.push("       <th>data type</th>");r.push("       <th>size</th>");r.push("       <th>date (UTC)</th>");r.push("   </thead>");r.push("   <tbody>");r.push('       <td><a href="#<% if (upper_folder_id !== 0){ print("folders/" + upper_folder_id)} %>" title="Go to parent folder" class="btn_open_folder btn btn-default btn-xs">..<a></td>');r.push("       <td></td>");r.push("       <td></td>");r.push("       <td></td>");r.push("       <td></td>");r.push("       <td></td>");r.push("       </tr>");r.push("       <% _.each(items, function(content_item) { %>");r.push('           <% if (content_item.get("type") === "folder") { %>');r.push('               <tr class="folder_row light" id="<%- content_item.id %>">');r.push("                   <td>");r.push('                       <span title="Folder" class="fa fa-folder-o"></span>');r.push("                   </td>");r.push("                   <td></td>");r.push("                   <td>");r.push('                       <a href="#folders/<%- content_item.id %>"><%- content_item.get("name") %></a>');r.push('                       <% if (content_item.get("item_count") === 0) { %>');r.push('                           <span class="muted">(empty folder)</span>');r.push("                       <% } %>");r.push("                   </td>");r.push("                   <td>folder</td>");r.push('                   <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>');r.push('                   <td><%= _.escape(content_item.get("time_updated")) %></td>');r.push("               </tr>");r.push("           <% } else {  %>");r.push('               <tr class="dataset_row light" id="<%- content_item.id %>">');r.push("                   <td>");r.push('                       <span title="Dataset" class="fa fa-file-o"></span>');r.push("                   </td>");r.push('                   <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');r.push('                   <td><a href="#" class="library-dataset"><%- content_item.get("name") %><a></td>');r.push('                   <td><%= _.escape(content_item.get("data_type")) %></td>');r.push('                   <td><%= _.escape(content_item.get("readable_size")) %></td>');r.push('                   <td><%= _.escape(content_item.get("time_updated")) %></td>');r.push("               </tr>");r.push("               <% } %>  ");r.push("       <% }); %>");r.push("       ");r.push("   </tbody>");r.push("</table>");r.push("</div>");return r.join("")},templateDatasetModal:function(){var r=[];r.push('<div class="modal_table">');r.push('   <table class="grid table table-striped table-condensed">');r.push("       <tr>");r.push('           <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');r.push('           <td><%= _.escape(item.get("name")) %></td>');r.push("       </tr>");r.push("       <tr>");r.push('           <th scope="row">Data type</th>');r.push('           <td><%= _.escape(item.get("data_type")) %></td>');r.push("       </tr>");r.push("       <tr>");r.push('           <th scope="row">Genome build</th>');r.push('           <td><%= _.escape(item.get("genome_build")) %></td>');r.push("       </tr>");r.push('           <th scope="row">Size</th>');r.push("           <td><%= _.escape(size) %></td>");r.push("       </tr>");r.push("       <tr>");r.push('           <th scope="row">Date uploaded (UTC)</th>');r.push('           <td><%= _.escape(item.get("date_uploaded")) %></td>');r.push("       </tr>");r.push("       <tr>");r.push('           <th scope="row">Uploaded by</th>');r.push('           <td><%= _.escape(item.get("uploaded_by")) %></td>');r.push("       </tr>");r.push('           <tr scope="row">');r.push('           <th scope="row">Data Lines</th>');r.push('           <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');r.push("       </tr>");r.push('       <th scope="row">Comment Lines</th>');r.push('           <% if (item.get("metadata_comment_lines") === "") { %>');r.push('               <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');r.push("           <% } else { %>");r.push('               <td scope="row">unknown</td>');r.push("           <% } %>");r.push("       </tr>");r.push("       <tr>");r.push('           <th scope="row">Number of Columns</th>');r.push('           <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');r.push("       </tr>");r.push("       <tr>");r.push('           <th scope="row">Column Types</th>');r.push('           <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');r.push("       </tr>");r.push("       <tr>");r.push('           <th scope="row">Miscellaneous information</th>');r.push('           <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');r.push("       </tr>");r.push("   </table>");r.push('   <pre class="peek">');r.push("   </pre>");r.push("</div>");return r.join("")},templateHistorySelectInModal:function(){var r=[];r.push('<span id="history_modal_combo" style="width:100%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_single" name="dataset_import_single" style="width:40%; margin-bottom: 1em; "> ');r.push("   <% _.each(histories, function(history) { %>");r.push('       <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push("   <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateBulkImportInModal:function(){var r=[];r.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');r.push("   <% _.each(histories, function(history) { %>");r.push('       <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push("   <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateProgressBar:function(){var r=[];r.push('<div class="import_text">');r.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");r.push("</div>");r.push('<div class="progress">');r.push('   <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');r.push('       <span class="completion_span">0% Complete</span>');r.push("   </div>");r.push("</div>");r.push("");return r.join("")},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return tmpl_array.join("")},events:{"click #select-all-checkboxes":"selectAll","click #toolbtn_bulk_import":"modalBulkImport","click #toolbtn_dl":"bulkDownload","click #toolbtn_create_folder":"createFolderFromModal","click .library-dataset":"showDatasetDetails","click .dataset_row":"selectClickedRow"},render:function(r){$("#center").css("overflow","auto");view=this;var t=this;var s=new e({id:r.id});s.url=s.attributes.urlRoot+r.id+"/contents";s.fetch({success:function(u){for(var w=0;w<s.attributes.folder.models.length;w++){var v=s.attributes.folder.models[w];if(v.get("type")==="file"){v.set("readable_size",t.size_to_string(v.get("file_size")))}}var y=s.full_path;var z;if(y.length===1){z=0}else{z=y[y.length-2][0]}var x=_.template(t.templateFolder(),{path:s.full_path,items:s.attributes.folder.models,id:r.id,upper_folder_id:z});t.$el.html(x)},error:function(){n.error("An error occured :(")}})},size_to_string:function(r){var s="";if(r>=100000000000){r=r/100000000000;s="TB"}else{if(r>=100000000){r=r/100000000;s="GB"}else{if(r>=100000){r=r/100000;s="MB"}else{if(r>=100){r=r/100;s="KB"}else{r=r*10;s="b"}}}}return(Math.round(r)/10)+s},showDatasetDetails:function(u){u.preventDefault();var v=$(u.target).parent().parent().parent().attr("id");if(typeof v==="undefined"){v=$(u.target).parent().attr("id")}if(typeof v==="undefined"){v=$(u.target).parent().parent().attr("id")}var t=new j();var s=new p();t.id=v;var r=this;t.fetch({success:function(w){s.fetch({success:function(x){r.renderModalAfterFetch(w,x)},error:function(){n.error("An error occured during fetching histories:(");r.renderModalAfterFetch(w)}})},error:function(){n.error("An error occured during loading dataset details :(")}})},renderModalAfterFetch:function(w,t){var u=this.size_to_string(w.get("file_size"));var v=_.template(this.templateDatasetModal(),{item:w,size:u});var s=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Dataset Details",body:v,buttons:{Import:function(){s.importCurrentIntoHistory()},Download:function(){s.downloadCurrent()},Close:function(){s.modal.hide()}}});$(".peek").html("Peek:"+w.get("peek"));if(typeof history.models!==undefined){var r=_.template(this.templateHistorySelectInModal(),{histories:t.models});$(this.modal.elMain).find(".buttons").prepend(r);if(s.lastSelectedHistory.length>0){$(this.modal.elMain).find("#dataset_import_single").val(s.lastSelectedHistory)}}},downloadCurrent:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var r=[];r.push($("#id_row").attr("data-id"));var s="/api/libraries/datasets/download/uncompressed";var t={ldda_ids:r};folderContentView.processDownload(s,t);this.modal.enableButton("Import");this.modal.enableButton("Download")},importCurrentIntoHistory:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var t=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();this.lastSelectedHistory=t;var r=$("#id_row").attr("data-id");var u=new b();var s=this;u.url=u.urlRoot+t+"/contents";u.save({content:r,source:"library"},{success:function(){n.success("Dataset imported");s.modal.enableButton("Import");s.modal.enableButton("Download")},error:function(){n.error("An error occured! Dataset not imported. Please try again.");s.modal.enableButton("Import");s.modal.enableButton("Download")}})},selectAll:function(s){var r=s.target.checked;that=this;$(":checkbox").each(function(){this.checked=r;$row=$(this.parentElement.parentElement);(r)?that.makeDarkRow($row):that.makeWhiteRow($row)});this.checkTools()},selectClickedRow:function(s){var u="";var r;var t;if(s.target.localName==="input"){u=s.target;r=$(s.target.parentElement.parentElement);t="input"}else{if(s.target.localName==="td"){u=$("#"+s.target.parentElement.id).find(":checkbox")[0];r=$(s.target.parentElement);t="td"}}if(u.checked){if(t==="td"){u.checked="";this.makeWhiteRow(r)}else{if(t==="input"){this.makeDarkRow(r)}}}else{if(t==="td"){u.checked="selected";this.makeDarkRow(r)}else{if(t==="input"){this.makeWhiteRow(r)}}}this.checkTools()},makeDarkRow:function(r){r.removeClass("light");r.find("a").removeClass("light");r.addClass("dark");r.find("a").addClass("dark");r.find("span").removeClass("fa-file-o");r.find("span").addClass("fa-file")},makeWhiteRow:function(r){r.removeClass("dark");r.find("a").removeClass("dark");r.addClass("light");r.find("a").addClass("light");r.find("span").addClass("fa-file-o");r.find("span").removeClass("fa-file")},checkTools:function(){var r=$("#folder_table").find(":checked");if(r.length>0){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}else{$("#toolbtn_bulk_import").hide();$("#toolbtn_dl").hide()}},modalBulkImport:function(){var s=this;var r=new p();r.fetch({success:function(t){var u=_.template(s.templateBulkImportInModal(),{histories:t.models});s.modal=Galaxy.modal;s.modal.show({closing_events:true,title:"Import into History",body:u,buttons:{Import:function(){s.importAllIntoHistory()},Close:function(){s.modal.hide()}}})},error:function(){n.error("An error occured :(")}})},importAllIntoHistory:function(){this.modal.disableButton("Import");var t=$("select[name=dataset_import_bulk] option:selected").val();var x=$("select[name=dataset_import_bulk] option:selected").text();var z=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){z.push(this.parentElement.parentElement.id)}});var y=_.template(this.templateProgressBar(),{history_name:x});$(this.modal.elMain).find(".modal-body").html(y);var u=100/z.length;this.initProgress(u);var r=[];for(var s=z.length-1;s>=0;s--){library_dataset_id=z[s];var v=new b();var w=this;v.url=v.urlRoot+t+"/contents";v.content=library_dataset_id;v.source="library";r.push(v)}this.chainCall(r)},chainCall:function(s){var r=this;var t=s.pop();if(typeof t==="undefined"){n.success("All datasets imported");this.modal.hide();return}var u=$.when(t.save({content:t.content,source:t.source})).done(function(v){r.updateProgress();responses.push(v);r.chainCall(s)})},initProgress:function(r){this.progress=0;this.progressStep=r},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(r,v){var t=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){t.push(this.parentElement.parentElement.id)}});var s="/api/libraries/datasets/download/"+v;var u={ldda_ids:t};this.processDownload(s,u,"get")},processDownload:function(s,t,u){if(s&&t){t=typeof t=="string"?t:$.param(t);var r="";$.each(t.split("&"),function(){var v=this.split("=");r+='<input type="hidden" name="'+v[0]+'" value="'+v[1]+'" />'});$('<form action="'+s+'" method="'+(u||"post")+'">'+r+"</form>").appendTo("body").submit().remove();n.info("Your download will begin soon")}},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var r=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Folder",body:this.templateNewFolderInModal(),buttons:{Create:function(){r.create_new_folder_event()},Close:function(){r.modal.hide();r.modal=null}}})},create_new_folder_event:function(){var r=this.serialize_new_folder();if(this.validate_new_folder(r)){var t=new c();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];t.url=t.urlRoot+"/"+current_folder_id;var s=this;t.save(r,{success:function(u){s.modal.hide();n.success("Folder created");s.render({id:current_folder_id})},error:function(){n.error("An error occured :(")}})}else{n.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(r){return r.name!==""}});var a=Backbone.View.extend({el:"#libraries_element",events:{"click .edit_library_btn":"edit_button_event","click .save_library_btn":"save_library_modification","click .cancel_library_btn":"cancel_library_modification","click .delete_library_btn":"delete_library","click .undelete_library_btn":"undelete_library"},modal:null,collection:null,initialize:function(){var r=this;this.collection=new o();this.collection.fetch({success:function(s){r.render();$("#center [data-toggle]").tooltip();$("#center").css("overflow","auto")},error:function(t,s){n.error("An error occured. Please try again.")}})},render:function(s){var t=this.templateLibraryList();var u=null;var r=false;var v=null;if(typeof s!=="undefined"){r=typeof s.with_deleted!=="undefined"?s.with_deleted:false;v=typeof s.models!=="undefined"?s.models:null}if(this.collection!==null&&v===null){if(r){u=this.collection.models}else{u=this.collection.where({deleted:false})}}else{if(v!==null){u=v}else{u=[]}}this.$el.html(t({libraries:u,order:this.collection.sort_order}))},sortLibraries:function(s,r){if(s==="name"){if(r==="asc"){this.collection.sort_order="asc";this.collection.comparator=function(u,t){if(u.get("name").toLowerCase()>t.get("name").toLowerCase()){return 1}if(t.get("name").toLowerCase()>u.get("name").toLowerCase()){return -1}return 0}}else{if(r==="desc"){this.collection.sort_order="desc";this.collection.comparator=function(u,t){if(u.get("name").toLowerCase()>t.get("name").toLowerCase()){return -1}if(t.get("name").toLowerCase()>u.get("name").toLowerCase()){return 1}return 0}}}this.collection.sort()}},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('<div class="library_container table-responsive">');tmpl_array.push("<% if(libraries.length === 0) { %>");tmpl_array.push("<div>I see no libraries. Why don't you create one?</div>");tmpl_array.push("<% } else{ %>");tmpl_array.push('<table class="grid table table-condensed">');tmpl_array.push("   <thead>");tmpl_array.push('     <th style="width:30%;"><a title="Click to reverse order" href="#sort/name/<% if(order==="desc"||order===null){print("asc")}else{print("desc")} %>">name</a><span title="Sorted alphabetically" class="fa fa-sort-alpha-<%- order %>"></span></th>');tmpl_array.push('     <th style="width:22%;">description</th>');tmpl_array.push('     <th style="width:22%;">synopsis</th> ');tmpl_array.push('     <th style="width:26%;"></th> ');tmpl_array.push("   </thead>");tmpl_array.push("   <tbody>");tmpl_array.push("       <% _.each(libraries, function(library) { %>");tmpl_array.push('           <tr class="<% if(library.get("deleted") === true){print("active");}%>" data-id="<%- library.get("id") %>">');tmpl_array.push('               <td><a href="#folders/<%- library.get("root_folder_id") %>"><%- library.get("name") %></a></td>');tmpl_array.push('               <td><%= _.escape(library.get("description")) %></td>');tmpl_array.push('               <td><%= _.escape(library.get("synopsis")) %></td>');tmpl_array.push('               <td class="right-center">');tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Modify library" class="primary-button btn-xs edit_library_btn" type="button"><span class="fa fa-pencil"></span></button>');tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Save changes" class="primary-button btn-xs save_library_btn" type="button" style="display:none;"><span class="fa fa-floppy-o"> Save</span></button>');tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Discard changes" class="primary-button btn-xs cancel_library_btn" type="button" style="display:none;"><span class="fa fa-times"> Cancel</span></button>');tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Delete library (can be undeleted later)" class="primary-button btn-xs delete_library_btn" type="button" style="display:none;"><span class="fa fa-trash-o"> Delete</span></button>');tmpl_array.push('                   <button data-toggle="tooltip" data-placement="top" title="Undelete library" class="primary-button btn-xs undelete_library_btn" type="button" style="display:none;"><span class="fa fa-unlock"> Undelete</span></button>');tmpl_array.push("               </td>");tmpl_array.push("           </tr>");tmpl_array.push("       <% }); %>");tmpl_array.push("   </tbody>");tmpl_array.push("</table>");tmpl_array.push("<% }%>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push("   <form>");tmpl_array.push('       <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('       <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push('       <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push("   </form>");tmpl_array.push("</div>");return tmpl_array.join("")},save_library_modification:function(u){var t=$(u.target).closest("tr");var r=this.collection.get(t.data("id"));var s=false;var w=t.find(".input_library_name").val();if(typeof w!=="undefined"&&w!==r.get("name")){if(w.length>2){r.set("name",w);s=true}else{n.warning("Library name has to be at least 3 characters long");return}}var v=t.find(".input_library_description").val();if(typeof v!=="undefined"&&v!==r.get("description")){r.set("description",v);s=true}var x=t.find(".input_library_synopsis").val();if(typeof x!=="undefined"&&x!==r.get("synopsis")){r.set("synopsis",x);s=true}if(s){r.save(null,{patch:true,success:function(y){n.success("Changes to library saved");galaxyLibraryview.toggle_library_modification(t)},error:function(z,y){n.error("An error occured during updating the library :(")}})}},edit_button_event:function(r){this.toggle_library_modification($(r.target).closest("tr"))},toggle_library_modification:function(u){var r=this.collection.get(u.data("id"));u.find(".edit_library_btn").toggle();u.find(".save_library_btn").toggle();u.find(".cancel_library_btn").toggle();if(r.get("deleted")){u.find(".undelete_library_btn").toggle()}else{u.find(".delete_library_btn").toggle()}if(u.find(".edit_library_btn").is(":hidden")){var s=r.get("name");var w='<input type="text" class="form-control input_library_name" placeholder="name">';u.children("td").eq(0).html(w);if(typeof s!==undefined){u.find(".input_library_name").val(s)}var t=r.get("description");var w='<input type="text" class="form-control input_library_description" placeholder="description">';u.children("td").eq(1).html(w);if(typeof t!==undefined){u.find(".input_library_description").val(t)}var v=r.get("synopsis");var w='<input type="text" class="form-control input_library_synopsis" placeholder="synopsis">';u.children("td").eq(2).html(w);if(typeof v!==undefined){u.find(".input_library_synopsis").val(v)}}else{u.children("td").eq(0).html(r.get("name"));u.children("td").eq(1).html(r.get("description"));u.children("td").eq(2).html(r.get("synopsis"))}},cancel_library_modification:function(t){var s=$(t.target).closest("tr");var r=this.collection.get(s.data("id"));this.toggle_library_modification(s);s.children("td").eq(0).html(r.get("name"));s.children("td").eq(1).html(r.get("description"));s.children("td").eq(2).html(r.get("synopsis"))},undelete_library:function(t){var s=$(t.target).closest("tr");var r=this.collection.get(s.data("id"));this.toggle_library_modification(s);r.url=r.urlRoot+r.id+"?undelete=true";r.destroy({success:function(u){u.set("deleted",false);galaxyLibraryview.collection.add(u);s.removeClass("active");n.success("Library has been undeleted")},error:function(){n.error("An error occured while undeleting the library :(")}})},delete_library:function(t){var s=$(t.target).closest("tr");var r=this.collection.get(s.data("id"));this.toggle_library_modification(s);r.destroy({success:function(u){s.remove();u.set("deleted",true);galaxyLibraryview.collection.add(u);n.success("Library has been marked deleted")},error:function(){n.error("An error occured during deleting the library :(")}})},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},show_library_modal:function(s){s.preventDefault();s.stopPropagation();var r=this;this.modal=Galaxy.modal;this.modal.show({closing_events:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){r.create_new_library_event()},Close:function(){r.modal.hide()}}})},create_new_library_event:function(){var t=this.serialize_new_library();if(this.validate_new_library(t)){var s=new f();var r=this;s.save(t,{success:function(u){r.collection.add(u);r.modal.hide();r.clear_library_modal();r.render();n.success("Library created")},error:function(){n.error("An error occured :(")}})}else{n.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(r){return r.name!==""}});var h=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"delegate_modal","click #include_deleted_chk":"check_include_deleted"},initialize:function(){this.render()},delegate_modal:function(r){galaxyLibraryview.show_library_modal(r)},check_include_deleted:function(r){if(r.target.checked){galaxyLibraryview.render({with_deleted:true})}else{galaxyLibraryview.render({with_deleted:false})}},render:function(){var r=this.templateToolBar();this.$el.html(r())},templateToolBar:function(){tmpl_array=[];tmpl_array.push('<div id="libraries_container" style="width: 90%; margin: auto; margin-top:2em; overflow: auto !important; ">');tmpl_array.push('  <div id="toolbar_form" margin-top:0.5em; ">');tmpl_array.push('       <h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push('       <div id="library_toolbar">');tmpl_array.push('           <input id="include_deleted_chk" style="margin: 0;" type="checkbox">include deleted</input>');tmpl_array.push('           <button data-toggle="tooltip" data-placement="top" title="Create New Library" id="create_new_library_btn" class="primary-button" type="button"><span class="fa fa-plus"></span> New Library</button>');tmpl_array.push("       </div>");tmpl_array.push("  </div>");tmpl_array.push('  <div id="libraries_element">');tmpl_array.push("  </div>");tmpl_array.push("</div>");return _.template(tmpl_array.join(""))}});var q=Backbone.Router.extend({routes:{"":"libraries","sort/:sort_by/:order":"sort_libraries","folders/:id":"folder_content","folders/:folder_id/download/:format":"download"}});var g=Backbone.View.extend({initialize:function(){toolbarView=new h();galaxyLibraryview=new a();library_router=new q();folderContentView=new m();library_router.on("route:libraries",function(){toolbarView=new h();galaxyLibraryview=new a()});library_router.on("route:sort_libraries",function(s,r){galaxyLibraryview.sortLibraries(s,r);galaxyLibraryview.render()});library_router.on("route:folder_content",function(r){folderContentView.render({id:r})});library_router.on("route:download",function(r,s){if($("#center").find(":checked").length===0){library_router.navigate("folders/"+r,{trigger:true,replace:true})}else{folderContentView.download(r,s);library_router.navigate("folders/"+r,{trigger:false,replace:true})}});Backbone.history.start({pushState:false})}});return{GalaxyApp:g}});
\ No newline at end of file
diff -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 -r 33cc6056d83760e5e3b98999b01ecb260423d33c static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1295,6 +1295,7 @@
 div.libraryItemBody{padding:4px 4px 2px 4px}
 li.folderRow,li.datasetRow{border-top:solid 1px #c6bfa8}
 li.folderRow:hover,li.datasetRow:hover{background-color:#f9f9f9}
+td.right-center{vertical-align:middle !important;text-align:right}
 .library_table td{border-top:1px solid #5f6990 !important}
 .library_table th{border-bottom:2px solid #5f6990 !important}
 .library_table a{color:#0A143D}.library_table a:hover{color:maroon}
diff -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 -r 33cc6056d83760e5e3b98999b01ecb260423d33c static/style/blue/library.css
--- a/static/style/blue/library.css
+++ b/static/style/blue/library.css
@@ -6,6 +6,7 @@
 div.libraryItemBody{padding:4px 4px 2px 4px}
 li.folderRow,li.datasetRow{border-top:solid 1px #c6bfa8}
 li.folderRow:hover,li.datasetRow:hover{background-color:#f9f9f9}
+td.right-center{vertical-align:middle !important;text-align:right}
 .library_table td{border-top:1px solid #5f6990 !important}
 .library_table th{border-bottom:2px solid #5f6990 !important}
 .library_table a{color:#0A143D}.library_table a:hover{color:maroon}
diff -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 -r 33cc6056d83760e5e3b98999b01ecb260423d33c static/style/src/less/library.less
--- a/static/style/src/less/library.less
+++ b/static/style/src/less/library.less
@@ -29,6 +29,11 @@
     background-color: @table-bg-accent;
 }
 
+td.right-center{
+    vertical-align: middle !important; 
+    text-align: right;
+
+}
 
 .library_table{
     td {
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            commit/galaxy-central: guerler: UI: Modularize scratch book and make it reusable as regular ui element, refactor charts
                        
                        
by commits-noreply@bitbucket.org 24 Mar '14
                    by commits-noreply@bitbucket.org 24 Mar '14
24 Mar '14
                    
                        1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/fa0968cfe3c3/
Changeset:   fa0968cfe3c3
User:        guerler
Date:        2014-03-24 09:50:52
Summary:     UI: Modularize scratch book and make it reusable as regular ui element, refactor charts
Affected #:  16 files
diff -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -1,10 +1,10 @@
 // dependencies
-define(['mvc/ui/ui-modal', 'mvc/ui/ui-portlet', 'plugin/library/ui', 'utils/utils', 'plugin/library/jobs', 'plugin/library/datasets',
-        'plugin/views/charts', 'plugin/views/chart',
-        'plugin/models/config', 'plugin/models/chart', 'plugin/models/charts', 'plugin/charts/types'],
-        function(   Modal, Portlet, Ui, Utils, Jobs, Datasets,
-                    ChartsView, ChartView,
-                    Config, Chart, Charts, Types
+define(['mvc/ui/ui-modal', 'mvc/ui/ui-portlet', 'plugin/library/ui', 'utils/utils', 'plugin/library/jobs', 'plugin/library/datasets', 'plugin/library/storage',
+        'plugin/views/viewer', 'plugin/views/editor',
+        'plugin/models/config', 'plugin/models/chart', 'plugin/charts/types'],
+        function(   Modal, Portlet, Ui, Utils, Jobs, Datasets, Storage,
+                    ViewerView, EditorView,
+                    Config, Chart, Types
                 ) {
 
 // widget
@@ -23,91 +23,61 @@
             this.modal = new Modal.View();
         }
         
-        // create configuration model
+        //
+        // models
+        //
         this.config = new Config();
-        
-        // job/data /processor
-        this.jobs = new Jobs(this);
-        
-        // create chart models
         this.types = new Types();
         this.chart = new Chart();
-        this.charts = new Charts(null, this);
         
-        // create dataset handler
+        //
+        // libraries
+        //
+        this.jobs = new Jobs(this);
         this.datasets = new Datasets(this);
-        
-        // create views
-        this.charts_view = new ChartsView(this);
-        this.chart_view = new ChartView(this);
-        
-        // create portlet
-        if (!this.options.config.widget) {
-            this.portlet = new Portlet.View({icon : 'fa-bar-chart-o'});
-        } else {
-            this.portlet = $('<div></div>');
-        }
+        this.storage = new Storage(this);
+
+        //
+        // views
+        //
+        this.viewer_view = new ViewerView(this);
+        this.editor_view = new EditorView(this);
         
         // append views
-        this.portlet.append(this.charts_view.$el);
-        this.portlet.append(this.chart_view.$el);
+        this.$el.append(this.viewer_view.$el);
+        this.$el.append(this.editor_view.$el);
 
-        // set element
-        if (!this.options.config.widget) {
-            this.setElement(this.portlet.$el);
+        // pick start screen
+        if (!this.storage.load()) {
+            // show editor
+            this.go('editor');
         } else {
-            this.setElement(this.portlet);
-        }
-        
-        // events
-        var self = this;
-        this.config.on('change:title', function() {
-            self._refreshTitle();
-        });
-        
-        // render
-        this.render();
-        
-        // load charts
-        this.charts.load();
-        
-        // start with chart view
-        if (this.charts.length == 0) {
-            this.go('chart_view');
-        } else {
-            this.go('charts_view');
+            // show viewport
+            this.go('viewer');
+            
+            // redraw chart
+            this.chart.trigger('redraw');
         }
     },
     
     // loads a view and makes sure that all others are hidden
     go: function(view_id) {
+        // hide all tooltips
+        $('.tooltip').hide();
+        
         // pick view
         switch (view_id) {
-            case 'chart_view' :
-                this.chart_view.show();
-                this.charts_view.hide();
+            case 'editor' :
+                this.editor_view.show();
+                this.viewer_view.hide();
                 break;
-            case 'charts_view' :
-                this.chart_view.hide();
-                this.charts_view.show();
+            case 'viewer' :
+                this.editor_view.hide();
+                this.viewer_view.show();
                 break;
         }
     },
     
-    // render
-    render: function() {
-        this._refreshTitle();
-    },
-    
-    // refresh title
-    _refreshTitle: function() {
-        var title = this.config.get('title');
-        if (title) {
-            title = ' - ' + title;
-        }
-        this.portlet.title('Charts' + title);
-    },
-    
     // execute command
     execute: function(options) {
     },
diff -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 config/plugins/visualizations/charts/static/build-app.js
--- a/config/plugins/visualizations/charts/static/build-app.js
+++ b/config/plugins/visualizations/charts/static/build-app.js
@@ -3,4 +3,4 @@
 //     (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
 //     Underscore may be freely distributed under the MIT license.
 
-(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n","	":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-modal",["utils/utils"],function(e){var t=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast")},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&(this.options.buttons.Pause||$(document).on("keyup",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:t}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm portlet-view no-highlight">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">',e.icon&&(t+='<div class="portlet-title-icon fa '+e.icon+'"> </div>'),t+='<div id="title-text" class="portlet-title-text">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody portlet-body">',e.placement=="top"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+='<div id="content" class="portlet-content"/>',e.placement=="bottom"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return"<label><b>"+e.title+"</b></label>"},value:function(){return options.title}}),r=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),i=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),s=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),o=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),u=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),a=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),f=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),l=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),c=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:n,Button:r,Icon:i,ButtonIcon:s,Input:c,Anchor:o,Message:u,Searchbox:a,Title:f,Select:t,ButtonMenu:l}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},cleanup:function(t){var n=t.get("dataset_id_job");if(n){var r=this;e.request("PUT",config.root+"api/histories/none/contents/"+n,{deleted:!0},function(){r._refreshHdas()})}},submit:function(t,n,r,i){var s=this,o=t.id,u=t.get("type"),a=this.app.types.get(u);data={tool_id:"rkit",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:u,columns:r,settings:n}},s.cleanup(t),t.state("submit","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response.");else{s._refreshHdas();var n=e.outputs[0];t.state("queued","Job has been queued..."),t.set("dataset_id_job",n.id),s._loop(n.id,function(e){switch(e.state){case"ok":return t.state("success","Job completed successfully..."),i(e),!0;case"error":return t.state("failed","Job has failed. Please check the history for details."),!0;case"running":return t.state("running","Job is running..."),!1}})}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires the R-kit. Please make sure it is installed. "+n)})},_loop:function(t,n){var r=this;e.request("GET",config.root+"api/jobs/"+t,{},function(e){n(e)||setTimeout(function(){r._loop(t,n)},r.app.config.get("query_timeout"))})},_refreshHdas:function(){Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshHdas()}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._fetch(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o="",u={},a=0;for(var f in t.groups){var l=t.groups[f];for(var c in l.columns){var h=l.columns[c];o+=h+",",u[h]=a,a++}}if(a==0){n({});return}o=o.substring(0,o.length-1);var p=t.groups.slice(0);for(var f in p)p[f].values=[];var d=this;e.request("GET",config.root+"api/datasets/"+t.id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:o},function(e){for(var i in e.data){var s=e.data[i];for(var o in t.groups){var a=t.groups[o],f={x:parseInt(i)+r};for(var l in a.columns){var c=a.columns[l],h=u[c],d=s[h];if(isNaN(d)||!d)d=0;f[l]=d}p[o].values.push(f)}}n(p)})}})}),define("plugin/library/ui-table",["utils/utils"],function(e){var t=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t){var n=$("<td></td>");t&&n.css("width",t),n.append(e),this.row.append(n)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}});return{View:t}}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({list:{},optionsDefault:{height:300},initialize:function(t,r){this.app=t,this.options=n.merge(r,this.optionsDefault),this.portlet=new e.View({title:"title",height:this.options.height,overflow:"hidden"}),this.setElement(this.portlet.$el);var i=this;this.app.charts.on("remove",function(e){i._removeChart(e.id)}),this.app.charts.on("redraw",function(e){i._drawChart(e)})},showChart:function(e){this.show(),this.hideCharts();var t=this.list[e];if(t){var n=this.app.charts.get(e);this.portlet.title(n.get("title")),t.$el.show(),$(window).trigger("resize")}},hideCharts:function(){this.$el.find(".item").hide()},show:function(){$(".tooltip").hide(),this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_drawChart:function(e){var t=this;if(!e.ready()){t.app.log("viewport:_drawChart()","Invalid attempt to draw chart before completion.");return}var n=e.id;this._removeChart(n);var r="#"+n,i=$(this._template({id:r}));this.portlet.append(i);var s=d3.select(i.find("svg")[0]);this.list[n]={svg:s,$el:i},e.off("change:state"),e.on("change:state",function(){var t=i.find("#info"),n=t.find("#icon");n.removeClass(),t.show(),t.find("#text").html(e.get("state_info"));var r=e.get("state");switch(r){case"ok":t.hide();break;case"failed":n.addClass("fa fa-warning");break;default:n.addClass("fa fa-spinner fa-spin")}}),e.state("wait","Please wait...");var o=e.get("type"),u=this.app.types.get(o),t=this;require(["plugin/charts/"+o+"/"+o],function(n){var r=new n(t.app,{svg:s});u.execute?t.app.jobs.submit(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){r.draw(e,t._defaultRequestDictionary(e))}):r.draw(e,t._defaultRequestDictionary(e))})},_removeChart:function(e){var t=this.list[e];t&&(t.svg.remove(),t.$el.remove())},_template:function(e){return'<div id="'+e.id.substr(1)+'" class="item">'+'<span id="info">'+'<span id="icon" style="font-size: 1.2em; display: inline-block;"/>'+'<span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/>'+"</span>"+'<svg style="height: auto;"/>'+"</div>"},_defaultRequestString:function(e){var t=this.app.types.get(e.get("type")),n="",r=0;return e.groups.each(function(e){for(var i in t.columns)n+=i+"_"+ ++r+":"+(parseInt(e.get(i))+1)+", "}),n.substring(0,n.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t=this.app.types.get(e.get("type")),n={id:e.get("dataset_id"),groups:[]},r=0;return e.groups.each(function(e){var i={};for(var s in t.columns)i[s]=e.get(s);n.groups.push({key:++r+":"+e.get("key"),columns:i})}),n}})}),define("plugin/views/charts",["mvc/ui/ui-portlet","plugin/library/ui-table","plugin/library/ui","utils/utils","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i,s){return Backbone.View.extend({initialize:function(i,o){this.app=i,this.viewport_view=new s(i),this.table=new t.View({content:"Add charts to this table.",ondblclick:function(e){u._showChartView(e)},onchange:function(e){var t=u.app.charts.get(e);u.app.config.set("title",t.get("title")),u.viewport_view.showChart(e)}});var u=this;this.portlet=new e.View({icon:"fa-list",title:"List of created charts:",height:100,operations:{"new":new n.ButtonIcon({icon:"fa-magic",tooltip:"Create a new Chart",title:"New",onclick:function(){u.app.go("chart_view"),u.app.chart.reset()}}),edit:new n.ButtonIcon({icon:"fa-gear",tooltip:"Customize this Chart",title:"Customize",onclick:function(){var e=u.table.value();if(!e)return;u._showChartView(e)}}),"delete":new n.ButtonIcon({icon:"fa-trash-o",tooltip:"Delete this Chart",title:"Delete",onclick:function(){var e=u.table.value();if(!e)return;var t=u.app.charts.get(e);u._wait(t,function(){u.app.modal.show({title:"Are you sure?",body:'The selected chart "'+t.get("title")+'" will be irreversibly deleted.',buttons:{Cancel:function(){u.app.modal.hide()},Delete:function(){u.app.modal.hide(),u.app.charts.remove(e),u.app.jobs.cleanup(t)}}})})}})}}),this.portlet.append(this.table.$el),this.app.options.config.widget||this.$el.append(this.portlet.$el),this.$el.append(r.wrap("")),this.$el.append(this.viewport_view.$el);var u=this;this.app.charts.on("add",function(e){u._addChart(e)}),this.app.charts.on("remove",function(e){u._removeChart(e)}),this.app.charts.on("change",function(e){u._changeChart(e)})},show:function(){this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_addChart:function(e){var t=e.get("title");t==""&&(t="Untitled"),this.table.add(t);var n=this.app.types.get(e.get("type"));this.table.add(n.title),this.table.add("Last change: "+e.get("date")),this.table.prepend(e.get("id")),this.table.value(e.get("id"))},_removeChart:function(e){this.table.remove(e.id),this.app.charts.save(),this.table.size()==0?(this.app.go("chart_view"),this.app.chart.reset()):this.table.value(this.app.charts.last().id)},_changeChart:function(e){e.get("type")&&(this._addChart(e),this.table.value(e.id))},_showChartView:function(e){var t=this,n=this.app.charts.get(e);this._wait(n,function(){t.app.go("chart_view"),t.app.chart.copy(n)})},_wait:function(e,t){if(e.ready())t();else{var n=this;this.app.modal.show({title:"Please wait!",body:'The selected chart "'+e.get("title")+'" is currently being processed. Please wait...',buttons:{Close:function(){n.app.modal.hide()},Retry:function(){n.app.modal.hide(),setTimeout(function(){n._wait(e,t)},n.app.config.get("query_timeout"))}}})}}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})});var Visualization=Backbone.Model.extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","mvc/visualization/visualization-model"],function(e){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"ok",state_info:""},initialize:function(t){this.groups=new e,this.settings=new Backbone.Model},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state_info",t),this.set("state",e)},ready:function(){return this.get("state")=="ok"||this.get("state")=="failed"}})}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({columns:[],initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e.View({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.app.datasets.request({id:e},function(e){r.columns=[];var t=e.metadata_column_types;for(var n in t)(t[n]=="int"||t[n]=="float")&&r.columns.push({label:"Column: "+(parseInt(n)+1)+" ["+t[n]+"]",value:n});for(var n in s)s[n].update(r.columns),s[n].show()})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e.View({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll();for(var n in e)this._add(n,e[n],t)},_add:function(e,n,r){var i=null,s=n.type;switch(s){case"text":i=new t.Input({placeholder:n.placeholder,onchange:function(){r.set(e,i.value())}});break;case"select":i=new t.Select.View({data:n.data,onchange:function(){r.set(e,i.value())}});break;case"slider":i=new t.Input({placeholder:n.placeholder,onchange:function(){r.set(e,i.value())}});break;case"separator":i=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(s!="separator"){r.get(e)||r.set(e,n.init),i.value(r.get(e));var o=$("<div/>");o.append(i.$el),o.append('<div class="toolParamHelp"  style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(o)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/chart",["mvc/ui/ui-tabs","plugin/library/ui-table","plugin/library/ui","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings"],function(e,t,n,r,i,s,o,u){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(i,s){this.app=i,this.chart=this.app.chart,this.options=r.merge(s,this.optionsDefault);var o=this;this.table=new t.View({header:!1,onconfirm:function(e){o.chart.groups.length>0?o.app.modal.show({title:"Switching to another chart type?",body:"If you continue your settings and selections will be cleared.",buttons:{Cancel:function(){o.app.modal.hide()},Continue:function(){o.app.modal.hide(),o.table.value(e)}}}):o.table.value(e)},onchange:function(e){o.chart.groups.reset(),o.chart.settings.clear(),o.chart.set({type:e})},ondblclick:function(e){o.tabs.show("settings")},content:"No chart types available"});var a=0,f=i.types.attributes;for(var l in f){var c=f[l];this.table.add(++a+"."),c.execute?this.table.add(c.title+" (requires processing)"):this.table.add(c.title),this.table.append(l)}this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=o._addGroupModel();o.tabs.show(e.id)},operations:{save:new n.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){o.app.go("charts_view"),o._saveChart()}}),back:new n.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){o.app.go("charts_view")}})}}),this.title=new n.Input({placeholder:"Chart title",onchange:function(){o.app.config.set("title",o.title.value())}});var h=$("<div/>");h.append(r.wrap((new n.Label({title:"Provide a chart title:"})).$el)),h.append(r.wrap(this.title.$el)),h.append(r.wrap((new n.Label({title:"Select a chart type:"})).$el)),h.append(r.wrap(this.table.$el)),this.tabs.add({id:"main",title:"Start",$el:h}),this.settings=new u(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.setElement(this.tabs.$el),this.tabs.hideOperation("back");var o=this;this.chart.on("change:title",function(e){o.title.value(e.get("title")),o.app.config.set("title",e.get("title"))}),this.chart.on("change:type",function(e){o.table.value(e.get("type"))}),this.chart.on("reset",function(e){o._resetChart()}),this.app.charts.on("add",function(e){o.tabs.showOperation("back")}),this.app.charts.on("remove",function(e){o.app.charts.length==0&&o.tabs.hideOperation("back")}),this.app.charts.on("reset",function(e){o.tabs.hideOperation("back")}),this.app.chart.groups.on("add",function(e){o._addGroup(e)}),this.app.chart.groups.on("remove",function(e){o._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){o._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){o._refreshGroupKey()}),this._resetChart()},show:function(){this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new s({id:r.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new o(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey()},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",r.uuid()),this.chart.set("type","bardiagram"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart")},_saveChart:function(){this.chart.set({type:this.table.value(),title:this.title.value(),date:r.time()}),this.chart.groups.length==0&&this._addGroupModel();var e=this.app.charts.get(this.chart.id);e?e.copy(this.chart):(e=this.chart.clone(),e.copy(this.chart),this.app.charts.add(e)),e.trigger("redraw",e),this.app.charts.save()}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:1e3,query_timeout:500,title:"Create a new chart"}})}),define("plugin/models/charts",["plugin/models/chart","plugin/models/group"],function(e,t){return Backbone.Collection.extend({model:e,vis:null,initialize:function(e,t){this.app=t,this.id=this.app.options.id,this.vis=new Visualization({type:"charts",config:{dataset_id:this.app.options.config.dataset_id,charts:[]}}),this.id&&(this.vis.id=this.id);var n=this.app.options.config.charts;n&&(this.vis.get("config").charts=n)},save:function(){this.vis.get("config").charts=[];var e=this;this.each(function(t){var n={attributes:t.attributes,settings:t.settings.attributes,groups:[]};t.groups.each(function(e){n.groups.push(e.attributes)}),e.vis.get("config").charts.push(n)});var e=this;this.vis.save().fail(function(e,t,n){console.error(e,t,n),alert("Error loading data:\n"+e.responseText)}).then(function(t){t&&t.id&&(e.id=t.id)})},load:function(){var n=this.vis.get("config").charts;for(var r in n){var i=n[r],s=new e;s.set(i.attributes),s.settings.set(i.settings);for(var o in i.groups)s.groups.add(new t(i.groups[o]));s.state("ok","Loaded previously saved visualization."),this.add(s),s.trigger("redraw",s)}}})}),define("plugin/charts/_nvd3/config",[],function(){return{title:"",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"f",data:[{label:"-- Do not show values --",value:"hide"},{label:"Float",value:"f"},{label:"Exponent",value:"e"},{label:"Integer",value:"d"},{label:"Percentage",value:"p"},{label:"Rounded",value:"r"},{label:"SI-prefix",value:"s"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"f",data:[{label:"-- Do not show values --",value:"hide"},{label:"Float",value:"f"},{label:"Exponent",value:"e"},{label:"Integer",value:"d"},{label:"Percentage",value:"p"},{label:"Rounded",value:"r"},{label:"SI-prefix",value:"s"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/bardiagram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram"})}),define("plugin/charts/histogram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",execute:!0,columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"},y_axis_tick:{init:".3"}}})}),define("plugin/charts/horizontal/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram (horizontal)",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/line/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart"})}),define("plugin/charts/linewithfocus/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus"})}),define("plugin/charts/piechart/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Pie chart"})}),define("plugin/charts/scatterplot/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/stackedarea/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked area"})}),define("plugin/charts/types",["plugin/charts/bardiagram/config","plugin/charts/histogram/config","plugin/charts/horizontal/config","plugin/charts/line/config","plugin/charts/linewithfocus/config","plugin/charts/piechart/config","plugin/charts/scatterplot/config","plugin/charts/stackedarea/config"],function(e,t,n,r,i,s,o,u){return Backbone.Model.extend({defaults:{bardiagram:e,horizontal:n,histogram:t,line:r,linewithfocus:i,piechart:s,scatterplot:o,stackedarea:u}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/views/charts","plugin/views/chart","plugin/models/config","plugin/models/chart","plugin/models/charts","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(n){this.options=n,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new a,this.jobs=new i(this),this.types=new c,this.chart=new f,this.charts=new l(null,this),this.datasets=new s(this),this.charts_view=new o(this),this.chart_view=new u(this),this.options.config.widget?this.portlet=$("<div></div>"):this.portlet=new t.View({icon:"fa-bar-chart-o"}),this.portlet.append(this.charts_view.$el),this.portlet.append(this.chart_view.$el),this.options.config.widget?this.setElement(this.portlet):this.setElement(this.portlet.$el);var r=this;this.config.on("change:title",function(){r._refreshTitle()}),this.render(),this.charts.load(),this.charts.length==0?this.go("chart_view"):this.go("charts_view")},go:function(e){switch(e){case"chart_view":this.chart_view.show(),this.charts_view.hide();break;case"charts_view":this.chart_view.hide(),this.charts_view.show()}},render:function(){this._refreshTitle()},_refreshTitle:function(){var e=this.config.get("title");e&&(e=" - "+e),this.portlet.title("Charts"+e)},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})});
\ No newline at end of file
+(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n","	":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-modal",["utils/utils"],function(e){var t=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast")},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&(this.options.buttons.Pause||$(document).on("keyup",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:t}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm portlet-view no-highlight">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">',e.icon&&(t+='<div class="portlet-title-icon fa '+e.icon+'"> </div>'),t+='<div id="title-text" class="portlet-title-text">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody portlet-body">',e.placement=="top"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+='<div id="content" class="portlet-content"/>',e.placement=="bottom"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return"<label><b>"+e.title+"</b></label>"},value:function(){return options.title}}),r=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),i=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),s=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),o=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),u=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),a=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),f=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),l=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),c=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:n,Button:r,Icon:i,ButtonIcon:s,Input:c,Anchor:o,Message:u,Searchbox:a,Title:f,Select:t,ButtonMenu:l}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},cleanup:function(t){var n=t.get("dataset_id_job");if(n){var r=this;e.request("PUT",config.root+"api/histories/none/contents/"+n,{deleted:!0},function(){r._refreshHdas()})}},submit:function(t,n,r,i){var s=this,o=t.id,u=t.get("type"),a=this.app.types.get(u);data={tool_id:"rkit",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:u,columns:r,settings:n}},s.cleanup(t),t.state("submit","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response.");else{s._refreshHdas();var n=e.outputs[0];t.state("queued","Job has been queued..."),t.set("dataset_id_job",n.id),s._loop(n.id,function(e){switch(e.state){case"ok":return t.state("success","Job completed successfully..."),i(e),!0;case"error":return t.state("failed","Job has failed. Please check the history for details."),!0;case"running":return t.state("running","Job is running..."),!1}})}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires the R-kit. Please make sure it is installed. "+n)})},_loop:function(t,n){var r=this;e.request("GET",config.root+"api/jobs/"+t,{},function(e){n(e)||setTimeout(function(){r._loop(t,n)},r.app.config.get("query_timeout"))})},_refreshHdas:function(){Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshHdas()}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._fetch(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o="",u={},a=0;for(var f in t.groups){var l=t.groups[f];for(var c in l.columns){var h=l.columns[c];o+=h+",",u[h]=a,a++}}if(a==0){n({});return}o=o.substring(0,o.length-1);var p=t.groups.slice(0);for(var f in p)p[f].values=[];var d=this;e.request("GET",config.root+"api/datasets/"+t.id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:o},function(e){for(var i in e.data){var s=e.data[i];for(var o in t.groups){var a=t.groups[o],f={x:parseInt(i)+r};for(var l in a.columns){var c=a.columns[l],h=u[c],d=s[h];if(isNaN(d)||!d)d=0;f[l]=d}p[o].values.push(f)}}n(p)})}})}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})});var Visualization=Backbone.Model.extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","mvc/visualization/visualization-model"],function(e){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"ok",state_info:""},initialize:function(t){this.groups=new e,this.settings=new Backbone.Model},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state_info",t),this.set("state",e)},ready:function(){return this.get("state")=="ok"||this.get("state")=="failed"}})}),define("plugin/library/storage",["utils/utils","plugin/models/chart","plugin/models/group"],function(e,t,n){return Backbone.Model.extend({vis:null,initialize:function(e){this.app=e,this.chart=this.app.chart,this.options=this.app.options,this.id=this.options.id,this.vis=new Visualization({type:"charts",config:{dataset_id:this.options.config.dataset_id,chart_dict:{}}}),this.id&&(this.vis.id=this.id);var t=this.options.config.chart_dict;t&&(this.vis.get("config").chart_dict=t)},save:function(){var e=this.app.chart;this.vis.get("config").chart_dict={};var t=e.get("title");t!=""&&this.vis.set("title",t);var n={attributes:e.attributes,settings:e.settings.attributes,groups:[]};e.groups.each(function(e){n.groups.push(e.attributes)}),this.vis.get("config").chart_dict=n;var r=this;this.vis.save().fail(function(e,t,n){console.error(e,t,n),alert("Error loading data:\n"+e.responseText)}).then(function(e){e&&e.id&&(r.id=e.id)})},load:function(){var e=this.vis.get("config").chart_dict;if(!e.attributes)return!1;this.chart.set(e.attributes),this.chart.settings.set(e.settings);for(var t in e.groups)this.chart.groups.add(new n(e.groups[t]));return this.chart.state("ok","Loaded previously saved visualization."),!0}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({height:300,initialize:function(e,t){this.app=e,this.chart=this.app.chart,this.options=n.merge(t,this.optionsDefault),this.setElement($(this._template()));var r=this;this.chart.on("redraw",function(){r._draw(r.chart)})},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_draw:function(e){var t=this;if(!e.ready()){this.app.log("viewport:_drawChart()","Invalid attempt to draw chart before completion.");return}this.svg&&this.svg.remove(),this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.setAttribute("height",this.height),this.$el.append(this.svg),this.svg=d3.select(this.$el.find("svg")[0]),e.off("change:state"),e.on("change:state",function(){var n=t.$el.find("#info"),r=n.find("#icon");r.removeClass(),n.show(),n.find("#text").html(e.get("state_info"));var i=e.get("state");switch(i){case"ok":n.hide();break;case"failed":r.addClass("fa fa-warning");break;default:r.addClass("fa fa-spinner fa-spin")}}),e.state("wait","Please wait...");var n=e.get("type"),r=this.app.types.get(n),t=this;require(["plugin/charts/"+n+"/"+n],function(n){var i=new n(t.app,{svg:t.svg});r.execute?t.app.jobs.submit(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){i.draw(e,t._defaultRequestDictionary(e))}):i.draw(e,t._defaultRequestDictionary(e))})},_template:function(){return'<div><div id="info" style="text-align: center; margin-top: 20px;"><span id="icon" style="font-size: 1.2em; display: inline-block;"/><span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/></div></div>'},_defaultRequestString:function(e){var t=this.app.types.get(e.get("type")),n="",r=0;return e.groups.each(function(e){for(var i in t.columns)n+=i+"_"+ ++r+":"+(parseInt(e.get(i))+1)+", "}),n.substring(0,n.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t=this.app.types.get(e.get("type")),n={id:e.get("dataset_id"),groups:[]},r=0;return e.groups.each(function(e){var i={};for(var s in t.columns)i[s]=e.get(s);n.groups.push({key:++r+":"+e.get("key"),columns:i})}),n}})}),define("plugin/views/viewer",["utils/utils","plugin/library/ui","mvc/ui/ui-portlet","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i){return Backbone.View.extend({initialize:function(e,r){this.app=e,this.chart=this.app.chart,this.viewport_view=new i(e);var s=this;this.portlet=new n.View({icon:"fa-bar-chart-o",title:"Viewport",operations:{edit_button:new t.ButtonIcon({icon:"fa-gear",tooltip:"Customize Chart",title:"Customize",onclick:function(){s._wait(s.app.chart,function(){s.app.go("editor")})}})}}),this.portlet.append(this.viewport_view.$el),this.setElement(this.portlet.$el);var s=this;this.chart.on("change:title",function(){s._refreshTitle()})},show:function(){this.$el.show(),$(window).trigger("resize")},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");e&&(e=" - "+e),this.portlet.title("Charts"+e)},_wait:function(e,t){if(e.ready())t();else{var n=this;this.app.modal.show({title:"Please wait!",body:"Your chart is currently being processed. Please wait...",buttons:{Close:function(){n.app.modal.hide()},Retry:function(){n.app.modal.hide(),setTimeout(function(){n._wait(e,t)},n.app.config.get("query_timeout"))}}})}}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/library/ui-table",["utils/utils"],function(e){var t=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t){var n=$("<td></td>");t&&n.css("width",t),n.append(e),this.row.append(n)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}});return{View:t}}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({columns:[],initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e.View({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.app.datasets.request({id:e},function(e){r.columns=[];var t=e.metadata_column_types;for(var n in t)(t[n]=="int"||t[n]=="float")&&r.columns.push({label:"Column: "+(parseInt(n)+1)+" ["+t[n]+"]",value:n});for(var n in s)s[n].update(r.columns),s[n].show()})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e.View({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll();for(var n in e)this._add(n,e[n],t)},_add:function(e,n,r){var i=null,s=n.type;switch(s){case"text":i=new t.Input({placeholder:n.placeholder,onchange:function(){r.set(e,i.value())}});break;case"select":i=new t.Select.View({data:n.data,onchange:function(){r.set(e,i.value())}});break;case"slider":i=new t.Input({placeholder:n.placeholder,onchange:function(){r.set(e,i.value())}});break;case"separator":i=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(s!="separator"){r.get(e)||r.set(e,n.init),i.value(r.get(e));var o=$("<div/>");o.append(i.$el),o.append('<div class="toolParamHelp"  style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(o)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/editor",["mvc/ui/ui-tabs","plugin/library/ui-table","plugin/library/ui","mvc/ui/ui-portlet","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings"],function(e,t,n,r,i,s,o,u,a){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(s,o){this.app=s,this.chart=this.app.chart,this.options=i.merge(o,this.optionsDefault),this.portlet=new r.View({icon:"fa-bar-chart-o",title:"Editor",operations:{save:new n.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){u.app.go("viewer"),u._saveChart()}}),back:new n.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){u.app.go("viewer"),u.app.storage.load()}})}});var u=this;this.table=new t.View({header:!1,onconfirm:function(e){u.chart.groups.length>0?u.app.modal.show({title:"Switching to another chart type?",body:"If you continue your settings and selections will be cleared.",buttons:{Cancel:function(){u.app.modal.hide()},Continue:function(){u.app.modal.hide(),u.table.value(e)}}}):u.table.value(e)},onchange:function(e){u.chart.groups.reset(),u.chart.settings.clear(),u.chart.set({type:e})},ondblclick:function(e){u.tabs.show("settings")},content:"No chart types available"});var f=0,l=s.types.attributes;for(var c in l){var h=l[c];this.table.add(++f+"."),h.execute?this.table.add(h.title+" (requires processing)"):this.table.add(h.title),this.table.append(c)}this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=u._addGroupModel();u.tabs.show(e.id)}}),this.title=new n.Input({placeholder:"Chart title",onchange:function(){u.app.config.set("title",u.title.value())}});var p=$("<div/>");p.append(i.wrap((new n.Label({title:"Provide a chart title:"})).$el)),p.append(i.wrap(this.title.$el)),p.append(i.wrap((new n.Label({title:"Select a chart type:"})).$el)),p.append(i.wrap(this.table.$el)),this.tabs.add({id:"main",title:"Start",$el:p}),this.settings=new a(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.portlet.append(this.tabs.$el),this.setElement(this.portlet.$el),this.tabs.hideOperation("back");var u=this;this.chart.on("change:title",function(e){u._refreshTitle()}),this.chart.on("change:type",function(e){u.table.value(e.get("type"))}),this.chart.on("reset",function(e){u._resetChart()}),this.app.chart.on("redraw",function(e){u.portlet.showOperation("back")}),this.app.chart.groups.on("add",function(e){u._addGroup(e)}),this.app.chart.groups.on("remove",function(e){u._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){u._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){u._refreshGroupKey()}),this._resetChart()},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");e&&(e=" - "+e),this.portlet.title("Charts"+e)},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new o({id:i.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new u(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey()},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",i.uuid()),this.chart.set("type","bardiagram"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart"),this.portlet.hideOperation("back")},_saveChart:function(){this.chart.set({type:this.table.value(),title:this.title.value(),date:i.time()}),this.chart.groups.length==0&&this._addGroupModel(),this.chart.trigger("redraw"),this.app.storage.save()}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:1e3,query_timeout:500}})}),define("plugin/charts/_nvd3/config",[],function(){return{title:"",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"f",data:[{label:"-- Do not show values --",value:"hide"},{label:"Float",value:"f"},{label:"Exponent",value:"e"},{label:"Integer",value:"d"},{label:"Percentage",value:"p"},{label:"Rounded",value:"r"},{label:"SI-prefix",value:"s"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"f",data:[{label:"-- Do not show values --",value:"hide"},{label:"Float",value:"f"},{label:"Exponent",value:"e"},{label:"Integer",value:"d"},{label:"Percentage",value:"p"},{label:"Rounded",value:"r"},{label:"SI-prefix",value:"s"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/bardiagram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram"})}),define("plugin/charts/histogram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",execute:!0,columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"},y_axis_tick:{init:".3"}}})}),define("plugin/charts/horizontal/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram (horizontal)",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/line/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart"})}),define("plugin/charts/linewithfocus/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus"})}),define("plugin/charts/piechart/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Pie chart"})}),define("plugin/charts/scatterplot/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/stackedarea/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked area"})}),define("plugin/charts/types",["plugin/charts/bardiagram/config","plugin/charts/histogram/config","plugin/charts/horizontal/config","plugin/charts/line/config","plugin/charts/linewithfocus/config","plugin/charts/piechart/config","plugin/charts/scatterplot/config","plugin/charts/stackedarea/config"],function(e,t,n,r,i,s,o,u){return Backbone.Model.extend({defaults:{bardiagram:e,horizontal:n,histogram:t,line:r,linewithfocus:i,piechart:s,scatterplot:o,stackedarea:u}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/library/storage","plugin/views/viewer","plugin/views/editor","plugin/models/config","plugin/models/chart","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(t){this.options=t,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new f,this.types=new c,this.chart=new l,this.jobs=new i(this),this.datasets=new s(this),this.storage=new o(this),this.viewer_view=new u(this),this.editor_view=new a(this),this.$el.append(this.viewer_view.$el),this.$el.append(this.editor_view.$el),this.storage.load()?(this.go("viewer"),this.chart.trigger("redraw")):this.go("editor")},go:function(e){$(".tooltip").hide();switch(e){case"editor":this.editor_view.show(),this.viewer_view.hide();break;case"viewer":this.editor_view.hide(),this.viewer_view.show()}},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})});
\ No newline at end of file
diff -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 config/plugins/visualizations/charts/static/library/storage.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/library/storage.js
@@ -0,0 +1,118 @@
+// dependencies
+define(['utils/utils', 'plugin/models/chart', 'plugin/models/group'], function(Utils, Chart, Group) {
+
+// collection
+return Backbone.Model.extend(
+{
+    // viz model
+    vis: null,
+    
+    // initialize
+    initialize: function(app) {
+        // link app
+        this.app = app;
+        
+        // link chart
+        this.chart = this.app.chart;
+        
+        // link options
+        this.options = this.app.options;
+        
+        // initialize parameters
+        this.id = this.options.id;
+        
+        // create visualization
+        this.vis = new Visualization({
+            type        : 'charts',
+            config  : {
+                dataset_id  : this.options.config.dataset_id,
+                chart_dict  : {}
+            }
+        });
+        
+        // add visualization id
+        if (this.id) {
+            this.vis.id = this.id;
+        }
+        
+        // add charts
+        var chart_dict = this.options.config.chart_dict;
+        if (chart_dict) {
+            this.vis.get('config').chart_dict = chart_dict;
+        }
+    },
+    
+    // pack and save nested chart model
+    save: function() {
+    
+        // link chart
+        var chart = this.app.chart;
+        
+        // reset
+        this.vis.get('config').chart_dict = {};
+        
+        // set title
+        var title = chart.get('title');
+        if (title != '') {
+            this.vis.set('title', title);
+        }
+        
+        // create chart dictionary
+        var chart_dict = {
+            attributes : chart.attributes,
+            settings   : chart.settings.attributes,
+            groups     : []
+        };
+        
+        // append groups
+        chart.groups.each(function(group) {
+            chart_dict.groups.push(group.attributes);
+        });
+        
+        // add chart to charts array
+        this.vis.get('config').chart_dict = chart_dict;
+        
+        // save visualization
+        var self = this;
+        this.vis.save()
+            .fail(function(xhr, status, message) {
+               console.error(xhr, status, message);
+               alert( 'Error loading data:\n' + xhr.responseText );
+            })
+            .then(function(response) {
+                if (response && response.id) {
+                    self.id = response.id;
+                }
+            });
+    },
+    
+    // load nested models/collections from packed dictionary
+    load: function() {
+        // get charts array
+        var chart_dict = this.vis.get('config').chart_dict;
+        
+        // check
+        if (!chart_dict.attributes) {
+            return false;
+        }
+        
+        // main
+        this.chart.set(chart_dict.attributes);
+        
+        // get settings
+        this.chart.settings.set(chart_dict.settings);
+        
+        // get groups
+        for (var j in chart_dict.groups) {
+            this.chart.groups.add(new Group(chart_dict.groups[j]));
+        }
+        
+        // reset status
+        this.chart.state('ok', 'Loaded previously saved visualization.');
+        
+        // return
+        return true;
+    }
+});
+
+});
\ No newline at end of file
diff -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 config/plugins/visualizations/charts/static/models/charts.js
--- a/config/plugins/visualizations/charts/static/models/charts.js
+++ /dev/null
@@ -1,114 +0,0 @@
-// dependencies
-define(['plugin/models/chart', 'plugin/models/group'], function(Chart, Group) {
-
-// collection
-return Backbone.Collection.extend(
-{
-    // nested chart model contains collections
-    model           : Chart,
-    
-    // viz model
-    vis: null,
-    
-    // initialize
-    initialize: function(options, app) {
-        // initialize parameters
-        this.app            = app;
-        this.id             = this.app.options.id;
-        
-        // create visualization
-        this.vis = new Visualization({
-            type        : 'charts',
-            config  : {
-                dataset_id  : this.app.options.config.dataset_id,
-                charts      : []
-            }
-        });
-        
-        // add visualization id
-        if (this.id) {
-            this.vis.id = this.id;
-        }
-        
-        // add charts
-        var charts_array = this.app.options.config.charts;
-        if (charts_array) {
-            this.vis.get('config').charts = charts_array;
-        }
-    },
-    
-    // pack and save nested chart models
-    save: function() {
-        // reset
-        this.vis.get('config').charts = [];
-        
-        // pack nested chart models into arrays attributes
-        var self = this;
-        this.each(function(chart) {
-            // create chart dictionary
-            var chart_dict = {
-                attributes : chart.attributes,
-                settings   : chart.settings.attributes,
-                groups     : []
-            };
-            
-            // append groups
-            chart.groups.each(function(group) {
-                chart_dict.groups.push(group.attributes);
-            });
-            
-            // add chart to charts array
-            self.vis.get('config').charts.push(chart_dict);
-        });
-        
-        // save visualization
-        var self = this;
-        this.vis.save()
-            .fail(function(xhr, status, message) {
-               console.error(xhr, status, message);
-               alert( 'Error loading data:\n' + xhr.responseText );
-            })
-            .then(function(response) {
-                if (response && response.id) {
-                    self.id = response.id;
-                }
-            });
-    },
-    
-    // load nested models/collections from packed dictionary
-    load: function() {
-        // get charts array
-        var charts_array = this.vis.get('config').charts;
-        
-        // unpack chart models
-        for (var i in charts_array) {
-            // get chart details
-            var chart_dict  = charts_array[i];
-            
-            // construct chart model
-            var chart = new Chart();
-            
-            // main
-            chart.set(chart_dict.attributes);
-            
-            // get settings
-            chart.settings.set(chart_dict.settings);
-            
-            // get groups
-            for (var j in chart_dict.groups) {
-                chart.groups.add(new Group(chart_dict.groups[j]));
-            }
-            
-            // reset status
-            chart.state('ok', 'Loaded previously saved visualization.');
-
-            // add to collection
-            this.add(chart);
-            
-            // trigger
-            chart.trigger('redraw', chart);
-        }
-    }
-});
-
-});
\ No newline at end of file
diff -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 config/plugins/visualizations/charts/static/models/config.js
--- a/config/plugins/visualizations/charts/static/models/config.js
+++ b/config/plugins/visualizations/charts/static/models/config.js
@@ -7,8 +7,7 @@
     // options
     defaults : {
         query_limit     : 1000,
-        query_timeout   : 500,
-        title           : 'Create a new chart'
+        query_timeout   : 500
     }
 });
 
diff -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 config/plugins/visualizations/charts/static/views/chart.js
--- a/config/plugins/visualizations/charts/static/views/chart.js
+++ /dev/null
@@ -1,321 +0,0 @@
-// dependencies
-define(['mvc/ui/ui-tabs', 'plugin/library/ui-table', 'plugin/library/ui', 'utils/utils',
-        'plugin/models/chart', 'plugin/models/group',
-        'plugin/views/group', 'plugin/views/settings'],
-    function(Tabs, Table, Ui, Utils, Chart, Group, GroupView, SettingsView) {
-
-// widget
-return Backbone.View.extend(
-{
-    // defaults options
-    optionsDefault: {
-        header  : true,
-        content : 'No content available.'
-    },
-    
-    // initialize
-    initialize: function(app, options)
-    {
-        // link application
-        this.app = app;
-        
-        // get current chart object
-        this.chart = this.app.chart;
-        
-        // configure options
-        this.options = Utils.merge(options, this.optionsDefault);
-        
-        //
-        // table with chart types
-        //
-        var self = this;
-        this.table = new Table.View({
-            header : false,
-            onconfirm : function(type) {
-                if (self.chart.groups.length > 0) {
-                    // show modal
-                    self.app.modal.show({
-                        title   : 'Switching to another chart type?',
-                        body    : 'If you continue your settings and selections will be cleared.',
-                        buttons : {
-                            'Cancel'    : function() {
-                                // hide modal
-                                self.app.modal.hide();
-                            },
-                            'Continue'  : function() {
-                                // hide modal
-                                self.app.modal.hide();
-                                
-                                // confirm
-                                self.table.value(type);
-                            }
-                        }
-                    });
-                } else {
-                    // confirm
-                    self.table.value(type);
-                }
-            },
-            onchange : function(type) {
-                // reset type relevant chart content
-                self.chart.groups.reset();
-                self.chart.settings.clear();
-                
-                // update chart type
-                self.chart.set({type: type});
-            },
-            ondblclick  : function(chart_id) {
-                self.tabs.show('settings');
-            },
-            content: 'No chart types available'
-        });
-        
-        // load chart types into table
-        var types_n = 0;
-        var types = app.types.attributes;
-        for (var id in types){
-            var chart_type = types[id];
-            this.table.add (++types_n + '.');
-            if (chart_type.execute) {
-                this.table.add(chart_type.title + ' (requires processing)');
-            } else {
-                this.table.add (chart_type.title);
-            }
-            this.table.append(id);
-        }
-        
-        //
-        // tabs
-        //
-        this.tabs = new Tabs.View({
-            title_new       : 'Add Data',
-            onnew           : function() {
-                var group = self._addGroupModel();
-                self.tabs.show(group.id);
-            },
-            operations      : {
-                'save'  : new Ui.ButtonIcon({
-                            icon    : 'fa-save',
-                            tooltip : 'Draw Chart',
-                            title   : 'Draw',
-                            onclick : function() {
-                                // show charts
-                                self.app.go('charts_view');
-                                
-                                // save chart
-                                self._saveChart();
-                            }
-                        }),
-                'back'  : new Ui.ButtonIcon({
-                            icon    : 'fa-caret-left',
-                            tooltip : 'Return to Viewer',
-                            title   : 'Return',
-                            onclick : function() {
-                                self.app.go('charts_view');
-                            }
-                        })
-            }
-        });
-        
-        //
-        // main/default tab
-        //
-        
-        // construct elements
-        this.title = new Ui.Input({
-            placeholder: 'Chart title',
-            onchange: function() {
-                self.app.config.set('title', self.title.value());
-            }
-        });
-        
-        // append element
-        var $main = $('<div/>');
-        $main.append(Utils.wrap((new Ui.Label({ title : 'Provide a chart title:'})).$el));
-        $main.append(Utils.wrap(this.title.$el));
-        $main.append(Utils.wrap((new Ui.Label({ title : 'Select a chart type:'})).$el));
-        $main.append(Utils.wrap(this.table.$el));
-        
-        // add tab
-        this.tabs.add({
-            id      : 'main',
-            title   : 'Start',
-            $el     : $main
-        });
-        
-        //
-        // main settings tab
-        //
-        
-        // create settings view
-        this.settings = new SettingsView(this.app);
-        
-        // add tab
-        this.tabs.add({
-            id      : 'settings',
-            title   : 'Configuration',
-            $el     : this.settings.$el
-        });
-        
-        // elements
-        this.setElement(this.tabs.$el);
-        
-        // hide back button on startup
-        this.tabs.hideOperation('back');
-        
-        // chart events
-        var self = this;
-        this.chart.on('change:title', function(chart) {
-            self.title.value(chart.get('title'));
-            self.app.config.set('title', chart.get('title'));
-        });
-        this.chart.on('change:type', function(chart) {
-            self.table.value(chart.get('type'));
-        });
-        this.chart.on('reset', function(chart) {
-            self._resetChart();
-        });
-        
-        // charts events
-        this.app.charts.on('add', function(chart) {
-            self.tabs.showOperation('back');
-        });
-        this.app.charts.on('remove', function(chart) {
-            if (self.app.charts.length == 0) {
-                self.tabs.hideOperation('back');
-            }
-        });
-        this.app.charts.on('reset', function(chart) {
-            self.tabs.hideOperation('back');
-        });
-        
-        // groups events
-        this.app.chart.groups.on('add', function(group) {
-            self._addGroup(group);
-        });
-        this.app.chart.groups.on('remove', function(group) {
-            self._removeGroup(group);
-        });
-        this.app.chart.groups.on('reset', function(group) {
-            self._removeAllGroups();
-        });
-        this.app.chart.groups.on('change:key', function(group) {
-            self._refreshGroupKey();
-        });
-        
-        // reset
-        this._resetChart();
-    },
-
-    // hide
-    show: function() {
-        this.$el.show();
-    },
-    
-    // hide
-    hide: function() {
-        $('.tooltip').hide();
-        this.$el.hide();
-    },
-
-    // update
-    _refreshGroupKey: function() {
-        var self = this;
-        var counter = 0;
-        this.chart.groups.each(function(group) {
-            var title = group.get('key', '');
-            if (title == '') {
-                title = 'Chart data';
-            }
-            self.tabs.title(group.id, ++counter + ': ' + title);
-        });
-    },
-    
-    // new group
-    _addGroupModel: function() {
-        var group = new Group({
-            id : Utils.uuid()
-        });
-        this.chart.groups.add(group);
-        return group;
-    },
-
-    // add group
-    _addGroup: function(group) {
-        // link this
-        var self = this;
-        
-        // create view
-        var group_view = new GroupView(this.app, {group: group});
-        
-        // number of groups
-        var count = self.chart.groups.length;
-        
-        // add new tab
-        this.tabs.add({
-            id              : group.id,
-            $el             : group_view.$el,
-            ondel           : function() {
-                self.chart.groups.remove(group.id);
-            }
-        });
-        
-        // update titles
-        this._refreshGroupKey();
-    },
-    
-    // remove group
-    _removeGroup: function(group) {
-        this.tabs.del(group.id);
-        
-        // update titles
-        this._refreshGroupKey();
-    },
-
-    // remove group
-    _removeAllGroups: function(group) {
-        this.tabs.delRemovable();
-    },
-    
-    // reset
-    _resetChart: function() {
-        // reset chart details
-        this.chart.set('id', Utils.uuid());
-        this.chart.set('type', 'bardiagram');
-        this.chart.set('dataset_id', this.app.options.config.dataset_id);
-        this.chart.set('title', 'New Chart');
-    },
-    
-    // create chart
-    _saveChart: function() {
-        // update chart data
-        this.chart.set({
-            type        : this.table.value(),
-            title       : this.title.value(),
-            date        : Utils.time()
-        });
-        
-        // ensure that data group is available
-        if (this.chart.groups.length == 0) {
-            this._addGroupModel();
-        }
-        
-        // create/get chart
-        var current = this.app.charts.get(this.chart.id);
-        if (!current) {
-            current = this.chart.clone();
-            current.copy(this.chart);
-            this.app.charts.add(current);
-        } else {
-            current.copy(this.chart);
-        }
-        
-        // trigger redraw
-        current.trigger('redraw', current);
-        
-        // save
-        this.app.charts.save();
-    }
-});
-
-});
\ No newline at end of file
diff -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 config/plugins/visualizations/charts/static/views/charts.js
--- a/config/plugins/visualizations/charts/static/views/charts.js
+++ /dev/null
@@ -1,227 +0,0 @@
-// dependencies
-define(['mvc/ui/ui-portlet', 'plugin/library/ui-table', 'plugin/library/ui', 'utils/utils', 'plugin/models/group', 'plugin/views/viewport',], function(Portlet, Table, Ui, Utils, Group, ViewportView) {
-
-// widget
-return Backbone.View.extend(
-{
-    // initialize
-    initialize: function(app, options)
-    {
-        // link app
-        this.app = app;
-        
-        // create viewport
-        this.viewport_view = new ViewportView(app);
-        
-        // table
-        this.table = new Table.View({
-            content     : 'Add charts to this table.',
-            ondblclick  : function(chart_id) {
-                // attempt to load chart editor
-                self._showChartView(chart_id);
-            },
-            onchange : function(chart_id) {
-                // get chart
-                var chart = self.app.charts.get(chart_id);
-                
-                // update main title
-                self.app.config.set('title', chart.get('title'));
-        
-                // show viewport
-                self.viewport_view.showChart(chart_id);
-            }
-        });
-        
-        // add table to portlet
-        var self = this;
-        this.portlet = new Portlet.View({
-            icon : 'fa-list',
-            title : 'List of created charts:',
-            height : 100,
-            operations : {
-                'new'   : new Ui.ButtonIcon({
-                    icon    : 'fa-magic',
-                    tooltip : 'Create a new Chart',
-                    title   : 'New',
-                    onclick : function() {
-                        self.app.go('chart_view');
-                        self.app.chart.reset();
-                    }
-                }),
-                'edit'  : new Ui.ButtonIcon({
-                    icon    : 'fa-gear',
-                    tooltip : 'Customize this Chart',
-                    title   : 'Customize',
-                    onclick : function() {
-                        // check if element has been selected
-                        var chart_id = self.table.value();
-                        if (!chart_id) {
-                            return;
-                        }
-                        
-                        // attempt to load chart editor
-                        self._showChartView(chart_id);
-                    }
-                }),
-                'delete' : new Ui.ButtonIcon({
-                    icon    : 'fa-trash-o',
-                    tooltip : 'Delete this Chart',
-                    title   : 'Delete',
-                    onclick : function() {
-                            
-                        // check if element has been selected
-                        var chart_id = self.table.value();
-                        if (!chart_id) {
-                            return;
-                        }
-                
-                        // title
-                        var chart = self.app.charts.get(chart_id);
-                
-                        // make sure that chart is ready
-                        self._wait (chart, function() {
-                            self.app.modal.show({
-                                title   : 'Are you sure?',
-                                body    : 'The selected chart "' + chart.get('title') + '" will be irreversibly deleted.',
-                                buttons : {
-                                    'Cancel'    : function() {self.app.modal.hide();},
-                                    'Delete'    : function() {
-                                        // hide modal
-                                        self.app.modal.hide();
-                                        
-                                        // remove chart
-                                        self.app.charts.remove(chart_id);
-                                        
-                                        // cleanup
-                                        self.app.jobs.cleanup(chart);
-                                    }
-                                }
-                            });
-                        });
-                    }
-                }),
-            }
-        });
-        this.portlet.append(this.table.$el);
-        
-        // append portlet with table
-        if (!this.app.options.config.widget) {
-            this.$el.append(this.portlet.$el);
-        }
-        
-        // append view port
-        this.$el.append(Utils.wrap(''));
-        this.$el.append(this.viewport_view.$el);
-        
-        // events
-        var self = this;
-        this.app.charts.on('add', function(chart) {
-            // add
-            self._addChart(chart);
-        });
-        this.app.charts.on('remove', function(chart) {
-            // remove
-            self._removeChart(chart);
-        });
-        this.app.charts.on('change', function(chart) {
-            // replace
-            self._changeChart(chart);
-        });
-    },
-
-    // show
-    show: function() {
-        this.$el.show();
-    },
-        
-    // hide
-    hide: function() {
-        $('.tooltip').hide();
-        this.$el.hide();
-    },
-    
-    // add
-    _addChart: function(chart) {
-        // add title to table
-        var title = chart.get('title');
-        if (title == '') {
-            title = 'Untitled';
-        }
-        this.table.add(title);
-        
-        // get chart type
-        var type = this.app.types.get(chart.get('type'));
-        this.table.add(type.title);
-        
-        // add additional columns
-        this.table.add('Last change: ' + chart.get('date'));
-        this.table.prepend(chart.get('id'));
-        this.table.value(chart.get('id'));
-    },
-    
-    // remove
-    _removeChart: function(chart) {
-        // remove from to table
-        this.table.remove(chart.id);
-        
-        // save
-        this.app.charts.save();
-        
-        // check if table is empty
-        if (this.table.size() == 0) {
-            this.app.go('chart_view');
-            this.app.chart.reset();
-        } else {
-            // select available chart
-            this.table.value(this.app.charts.last().id);
-        }
-    },
-    
-    // change
-    _changeChart: function(chart) {
-        if (chart.get('type')) {
-            // add chart
-            this._addChart(chart);
-        
-            // select available chart
-            this.table.value(chart.id);
-        }
-    },
-    
-    // show chart editor
-    _showChartView: function(chart_id) {
-        var self = this;
-        var chart = this.app.charts.get(chart_id);
-        this._wait (chart, function() {
-            self.app.go('chart_view');
-            self.app.chart.copy(chart);
-        });
-    },
-    
-    // wait for chart to be ready
-    _wait: function(chart, callback) {
-        // get chart
-        if (chart.ready()) {
-            callback();
-        } else {
-            // show modal
-            var self = this;
-            this.app.modal.show({
-                title   : 'Please wait!',
-                body    : 'The selected chart "' + chart.get('title') + '" is currently being processed. Please wait...',
-                buttons : {
-                    'Close'     : function() {self.app.modal.hide();},
-                    'Retry'     : function() {
-                        // hide modal
-                        self.app.modal.hide();
-                        
-                        // retry
-                        setTimeout(function() { self._wait(chart, callback); }, self.app.config.get('query_timeout'));
-                    }
-                }
-            });
-        }
-    }
-});
-
-});
\ No newline at end of file
diff -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 config/plugins/visualizations/charts/static/views/editor.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/views/editor.js
@@ -0,0 +1,324 @@
+// dependencies
+define(['mvc/ui/ui-tabs', 'plugin/library/ui-table', 'plugin/library/ui', 'mvc/ui/ui-portlet', 'utils/utils',
+        'plugin/models/chart', 'plugin/models/group',
+        'plugin/views/group', 'plugin/views/settings'],
+    function(Tabs, Table, Ui, Portlet, Utils, Chart, Group, GroupView, SettingsView) {
+
+// widget
+return Backbone.View.extend(
+{
+    // defaults options
+    optionsDefault: {
+        header  : true,
+        content : 'No content available.'
+    },
+    
+    // initialize
+    initialize: function(app, options)
+    {
+        // link application
+        this.app = app;
+        
+        // get current chart object
+        this.chart = this.app.chart;
+        
+        // configure options
+        this.options = Utils.merge(options, this.optionsDefault);
+        
+        // create portlet
+        this.portlet = new Portlet.View({
+            icon : 'fa-bar-chart-o',
+            title: 'Editor',
+            operations      : {
+                'save'  : new Ui.ButtonIcon({
+                    icon    : 'fa-save',
+                    tooltip : 'Draw Chart',
+                    title   : 'Draw',
+                    onclick : function() {
+                        // show viewport
+                        self.app.go('viewer');
+                        
+                        // save chart
+                        self._saveChart();
+                    }
+                }),
+                'back'  : new Ui.ButtonIcon({
+                    icon    : 'fa-caret-left',
+                    tooltip : 'Return to Viewer',
+                    title   : 'Return',
+                    onclick : function() {
+                        // show viewport
+                        self.app.go('viewer');
+                        
+                        // reset chart
+                        self.app.storage.load();
+                    }
+                })
+            }
+        });
+        
+        //
+        // table with chart types
+        //
+        var self = this;
+        this.table = new Table.View({
+            header : false,
+            onconfirm : function(type) {
+                if (self.chart.groups.length > 0) {
+                    // show modal
+                    self.app.modal.show({
+                        title   : 'Switching to another chart type?',
+                        body    : 'If you continue your settings and selections will be cleared.',
+                        buttons : {
+                            'Cancel'    : function() {
+                                // hide modal
+                                self.app.modal.hide();
+                            },
+                            'Continue'  : function() {
+                                // hide modal
+                                self.app.modal.hide();
+                                
+                                // confirm
+                                self.table.value(type);
+                            }
+                        }
+                    });
+                } else {
+                    // confirm
+                    self.table.value(type);
+                }
+            },
+            onchange : function(type) {
+                // reset type relevant chart content
+                self.chart.groups.reset();
+                self.chart.settings.clear();
+                
+                // update chart type
+                self.chart.set({type: type});
+            },
+            ondblclick  : function(chart_id) {
+                self.tabs.show('settings');
+            },
+            content: 'No chart types available'
+        });
+        
+        // load chart types into table
+        var types_n = 0;
+        var types = app.types.attributes;
+        for (var id in types){
+            var chart_type = types[id];
+            this.table.add (++types_n + '.');
+            if (chart_type.execute) {
+                this.table.add(chart_type.title + ' (requires processing)');
+            } else {
+                this.table.add (chart_type.title);
+            }
+            this.table.append(id);
+        }
+        
+        //
+        // tabs
+        //
+        this.tabs = new Tabs.View({
+            title_new       : 'Add Data',
+            onnew           : function() {
+                var group = self._addGroupModel();
+                self.tabs.show(group.id);
+            }
+        });
+        
+        //
+        // main/default tab
+        //
+        
+        // construct elements
+        this.title = new Ui.Input({
+            placeholder: 'Chart title',
+            onchange: function() {
+                self.app.config.set('title', self.title.value());
+            }
+        });
+        
+        // append element
+        var $main = $('<div/>');
+        $main.append(Utils.wrap((new Ui.Label({ title : 'Provide a chart title:'})).$el));
+        $main.append(Utils.wrap(this.title.$el));
+        $main.append(Utils.wrap((new Ui.Label({ title : 'Select a chart type:'})).$el));
+        $main.append(Utils.wrap(this.table.$el));
+        
+        // add tab
+        this.tabs.add({
+            id      : 'main',
+            title   : 'Start',
+            $el     : $main
+        });
+        
+        //
+        // main settings tab
+        //
+        
+        // create settings view
+        this.settings = new SettingsView(this.app);
+        
+        // add tab
+        this.tabs.add({
+            id      : 'settings',
+            title   : 'Configuration',
+            $el     : this.settings.$el
+        });
+        
+        // append tabs
+        this.portlet.append(this.tabs.$el);
+        
+        // elements
+        this.setElement(this.portlet.$el);
+        
+        // hide back button on startup
+        this.tabs.hideOperation('back');
+        
+        // chart events
+        var self = this;
+        this.chart.on('change:title', function(chart) {
+            self._refreshTitle();
+        });
+        this.chart.on('change:type', function(chart) {
+            self.table.value(chart.get('type'));
+        });
+        this.chart.on('reset', function(chart) {
+            self._resetChart();
+        });
+        this.app.chart.on('redraw', function(chart) {
+            self.portlet.showOperation('back');
+        });
+        
+        // groups events
+        this.app.chart.groups.on('add', function(group) {
+            self._addGroup(group);
+        });
+        this.app.chart.groups.on('remove', function(group) {
+            self._removeGroup(group);
+        });
+        this.app.chart.groups.on('reset', function(group) {
+            self._removeAllGroups();
+        });
+        this.app.chart.groups.on('change:key', function(group) {
+            self._refreshGroupKey();
+        });
+        
+        // reset
+        this._resetChart();
+    },
+
+    // hide
+    show: function() {
+        this.$el.show();
+    },
+    
+    // hide
+    hide: function() {
+        this.$el.hide();
+    },
+
+    // refresh title
+    _refreshTitle: function() {
+        var title = this.chart.get('title');
+        if (title) {
+            title = ' - ' + title;
+        }
+        this.portlet.title('Charts' + title);
+    },
+    
+    // update
+    _refreshGroupKey: function() {
+        var self = this;
+        var counter = 0;
+        this.chart.groups.each(function(group) {
+            var title = group.get('key', '');
+            if (title == '') {
+                title = 'Chart data';
+            }
+            self.tabs.title(group.id, ++counter + ': ' + title);
+        });
+    },
+    
+    // new group
+    _addGroupModel: function() {
+        var group = new Group({
+            id : Utils.uuid()
+        });
+        this.chart.groups.add(group);
+        return group;
+    },
+
+    // add group
+    _addGroup: function(group) {
+        // link this
+        var self = this;
+        
+        // create view
+        var group_view = new GroupView(this.app, {group: group});
+        
+        // number of groups
+        var count = self.chart.groups.length;
+        
+        // add new tab
+        this.tabs.add({
+            id              : group.id,
+            $el             : group_view.$el,
+            ondel           : function() {
+                self.chart.groups.remove(group.id);
+            }
+        });
+        
+        // update titles
+        this._refreshGroupKey();
+    },
+    
+    // remove group
+    _removeGroup: function(group) {
+        this.tabs.del(group.id);
+        
+        // update titles
+        this._refreshGroupKey();
+    },
+
+    // remove group
+    _removeAllGroups: function(group) {
+        this.tabs.delRemovable();
+    },
+    
+    // reset
+    _resetChart: function() {
+        // reset chart details
+        this.chart.set('id', Utils.uuid());
+        this.chart.set('type', 'bardiagram');
+        this.chart.set('dataset_id', this.app.options.config.dataset_id);
+        this.chart.set('title', 'New Chart');
+        
+        // reset back button
+        this.portlet.hideOperation('back');
+    },
+    
+    // create chart
+    _saveChart: function() {
+        // update chart data
+        this.chart.set({
+            type        : this.table.value(),
+            title       : this.title.value(),
+            date        : Utils.time()
+        });
+        
+        // ensure that data group is available
+        if (this.chart.groups.length == 0) {
+            this._addGroupModel();
+        }
+        
+        // trigger redraw
+        this.chart.trigger('redraw');
+        
+        // save
+        this.app.storage.save();
+    }
+});
+
+});
\ No newline at end of file
diff -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 config/plugins/visualizations/charts/static/views/viewer.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/views/viewer.js
@@ -0,0 +1,106 @@
+// dependencies
+define(['utils/utils', 'plugin/library/ui', 'mvc/ui/ui-portlet',
+        'plugin/models/group', 'plugin/views/viewport',],
+        function(Utils, Ui, Portlet, Group, ViewportView) {
+
+// widget
+return Backbone.View.extend(
+{
+    // initialize
+    initialize: function(app, options)
+    {
+        // link app
+        this.app = app;
+        
+        // link chart
+        this.chart = this.app.chart;
+        
+        // create viewport
+        this.viewport_view = new ViewportView(app);
+        
+        // link this
+        var self = this;
+        
+        // create portlet
+        this.portlet = new Portlet.View({
+            icon : 'fa-bar-chart-o',
+            title: 'Viewport',
+            operations: {
+                edit_button: new Ui.ButtonIcon({
+                    icon    : 'fa-gear',
+                    tooltip : 'Customize Chart',
+                    title   : 'Customize',
+                    onclick : function() {
+                        // attempt to load chart editor
+                        self._wait (self.app.chart, function() {
+                            self.app.go('editor');
+                        });
+                    }
+                })
+                
+            }
+        });
+        
+        // append view port
+        this.portlet.append(this.viewport_view.$el);
+        
+        // set element
+        this.setElement(this.portlet.$el);
+        
+        // events
+        var self = this;
+        this.chart.on('change:title', function() {
+            self._refreshTitle();
+        });
+    },
+
+    // show
+    show: function() {
+        // show element
+        this.$el.show();
+        
+        // trigger resize to refresh d3 element
+        $(window).trigger('resize');
+    },
+        
+    // hide
+    hide: function() {
+        this.$el.hide();
+    },
+    
+    // refresh title
+    _refreshTitle: function() {
+        var title = this.chart.get('title');
+        if (title) {
+            title = ' - ' + title;
+        }
+        this.portlet.title('Charts' + title);
+    },
+    
+    // wait for chart to be ready
+    _wait: function(chart, callback) {
+        // get chart
+        if (chart.ready()) {
+            callback();
+        } else {
+            // show modal
+            var self = this;
+            this.app.modal.show({
+                title   : 'Please wait!',
+                body    : 'Your chart is currently being processed. Please wait...',
+                buttons : {
+                    'Close'     : function() {self.app.modal.hide();},
+                    'Retry'     : function() {
+                        // hide modal
+                        self.app.modal.hide();
+                        
+                        // retry
+                        setTimeout(function() { self._wait(chart, callback); }, self.app.config.get('query_timeout'));
+                    }
+                }
+            });
+        }
+    }
+});
+
+});
\ No newline at end of file
diff -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 -r fa0968cfe3c3fec5869168bd7dd68829024f1ec3 config/plugins/visualizations/charts/static/views/viewport.js
--- a/config/plugins/visualizations/charts/static/views/viewport.js
+++ b/config/plugins/visualizations/charts/static/views/viewport.js
@@ -5,14 +5,8 @@
 // widget
 return Backbone.View.extend(
 {
-    // list
-    list: {},
-    
-    // options
-    optionsDefault :
-    {
-        height : 300
-    },
+    // height
+    height : 300,
     
     // initialize
     initialize: function(app, options)
@@ -20,117 +14,63 @@
         // link app
         this.app = app;
         
+        // link chart
+        this.chart = this.app.chart;
+        
         // link options
         this.options = Utils.merge(options, this.optionsDefault);
         
-        // add table to portlet
-        this.portlet = new Portlet.View({
-            title       : 'title',
-            height      : this.options.height,
-            overflow    : 'hidden'
-        });
-        
-        // set this element
-        this.setElement(this.portlet.$el);
+        // create element
+        this.setElement($(this._template()));
         
         // events
         var self = this;
-        
-        // remove
-        this.app.charts.on('remove', function(chart) {
-            self._removeChart(chart.id);
-        });
-        
-        // redraw
-        this.app.charts.on('redraw', function(chart) {
-            self._drawChart(chart);
+        this.chart.on('redraw', function() {
+            self._draw(self.chart);
         });
     },
     
     // show
-    showChart: function(chart_id) {
-        // show
-        this.show();
-        
-        // hide all
-        this.hideCharts();
-        
-        // identify selected item from list
-        var item = this.list[chart_id];
-        if (item) {
-            // get chart
-            var chart = this.app.charts.get(chart_id);
-                
-            // update portlet
-            this.portlet.title(chart.get('title'));
-            
-            // show selected chart
-            item.$el.show();
-        
-            // this trigger d3 update events
-            $(window).trigger('resize');
-        }
-    },
-    
-    // hide charts
-    hideCharts: function() {
-        this.$el.find('.item').hide();
-    },
-    
-    // show
     show: function() {
-        $('.tooltip').hide();
         this.$el.show();
     },
     
     // hide
     hide: function() {
-        $('.tooltip').hide();
         this.$el.hide();
     },
 
     // add
-    _drawChart: function(chart) {
+    _draw: function(chart) {
         // link this
         var self = this;
         
         // check
         if (!chart.ready()) {
-            self.app.log('viewport:_drawChart()', 'Invalid attempt to draw chart before completion.');
+            this.app.log('viewport:_drawChart()', 'Invalid attempt to draw chart before completion.');
             return;
         }
-       
-        // backup chart details
-        var chart_id = chart.id;
-    
-        // make sure that svg does not exist already
-        this._removeChart(chart_id);
-            
-        // create id
-        var id = '#' + chart_id;
         
-        // create element
-        var $chart_el = $(this._template({id: id}));
+        // clear svg
+        if (this.svg) {
+            this.svg.remove();
+        }
         
-        // add to portlet
-        this.portlet.append($chart_el);
+        // create
+        this.svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+        this.svg.setAttribute('height', this.height);
+        this.$el.append(this.svg);
         
         // find svg element
-        var svg = d3.select($chart_el.find('svg')[0]);
-        
-        // add chart to list
-        this.list[chart_id] = {
-            svg : svg,
-            $el : $chart_el
-        }
-        
+        this.svg = d3.select(this.$el.find('svg')[0]);
+         
         // clear all previous handlers (including redraw listeners)
         chart.off('change:state');
         
         // link status handler
         chart.on('change:state', function() {
             // get info element
-            var $info = $chart_el.find('#info');
+            var $info = self.$el.find('#info');
             
             // get icon
             var $icon = $info.find('#icon');
@@ -168,7 +108,7 @@
         var self = this;
         require(['plugin/charts/' + chart_type + '/' + chart_type], function(ChartView) {
             // create chart
-            var view = new ChartView(self.app, {svg : svg});
+            var view = new ChartView(self.app, {svg : self.svg});
             
             // request data
             if (chart_settings.execute) {
@@ -181,31 +121,18 @@
         });
     },
     
-    // remove
-    _removeChart: function(id) {
-        var item = this.list[id];
-        if (item) {
-            // remove svg element
-            item.svg.remove();
-            
-            // find div element (if any)
-            item.$el.remove();
-        }
-    },
-    
     // template
-    _template: function(options) {
-        return '<div id="' + options.id.substr(1) + '" class="item">' +
-                    '<span id="info">' +
+    _template: function() {
+        return  '<div>' +
+                    '<div id="info" style="text-align: center; margin-top: 20px;">' +
                         '<span id="icon" style="font-size: 1.2em; display: inline-block;"/>' +
                         '<span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/>' +
-                    '</span>' +
-                    '<svg style="height: auto;"/>' +
+                    '</div>' +
                 '</div>';
     },
     
     // create default chart request
-    _defaultRequestString : function(chart) {
+    _defaultRequestString: function(chart) {
     
         // get chart settings
         var chart_settings  = this.app.types.get(chart.get('type'));
@@ -226,7 +153,7 @@
     },
     
     // create default chart request
-    _defaultSettingsString : function(chart) {
+    _defaultSettingsString: function(chart) {
     
         // configure settings
         var settings_string = '';
@@ -241,7 +168,7 @@
     },
 
     // create default chart request
-    _defaultRequestDictionary : function(chart) {
+    _defaultRequestDictionary: function(chart) {
     
         // get chart settings
         var chart_settings  = this.app.types.get(chart.get('type'));
This diff is so big that we needed to truncate the remainder.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            commit/galaxy-central: guerler: Charts: Save/read	from backend
                        
                        
by commits-noreply@bitbucket.org 22 Mar '14
                    by commits-noreply@bitbucket.org 22 Mar '14
22 Mar '14
                    
                        1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e7dfb71eeb79/
Changeset:   e7dfb71eeb79
User:        guerler
Date:        2014-03-22 18:38:48
Summary:     Charts: Save/read from backend
Affected #:  8 files
diff -r dec159841d670560582aadc1327bec0673f7003a -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -32,7 +32,7 @@
         // create chart models
         this.types = new Types();
         this.chart = new Chart();
-        this.charts = new Charts();
+        this.charts = new Charts(null, this);
         
         // create dataset handler
         this.datasets = new Datasets(this);
@@ -59,9 +59,6 @@
             this.setElement(this.portlet);
         }
         
-        // start with chart view
-        this.go('chart_view');
-        
         // events
         var self = this;
         this.config.on('change:title', function() {
@@ -70,6 +67,16 @@
         
         // render
         this.render();
+        
+        // load charts
+        this.charts.load();
+        
+        // start with chart view
+        if (this.charts.length == 0) {
+            this.go('chart_view');
+        } else {
+            this.go('charts_view');
+        }
     },
     
     // loads a view and makes sure that all others are hidden
diff -r dec159841d670560582aadc1327bec0673f7003a -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 config/plugins/visualizations/charts/static/build-app.js
--- a/config/plugins/visualizations/charts/static/build-app.js
+++ b/config/plugins/visualizations/charts/static/build-app.js
@@ -3,4 +3,4 @@
 //     (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
 //     Underscore may be freely distributed under the MIT license.
 
-(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n","	":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-modal",["utils/utils"],function(e){var t=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast")},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&(this.options.buttons.Pause||$(document).on("keyup",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:t}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm portlet-view no-highlight">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">',e.icon&&(t+='<div class="portlet-title-icon fa '+e.icon+'"> </div>'),t+='<div id="title-text" class="portlet-title-text">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody portlet-body">',e.placement=="top"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+='<div id="content" class="portlet-content"/>',e.placement=="bottom"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return"<label><b>"+e.title+"</b></label>"},value:function(){return options.title}}),r=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),i=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),s=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),o=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),u=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),a=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),f=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),l=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),c=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:n,Button:r,Icon:i,ButtonIcon:s,Input:c,Anchor:o,Message:u,Searchbox:a,Title:f,Select:t,ButtonMenu:l}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},submit:function(t,n,r,i){var s=this,o=t.id,u=t.get("type"),a=this.app.types.get(u);data={tool_id:"rkit",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:u,columns:r,settings:n}};var f=t.get("dataset_id_job");f&&e.request("PUT",config.root+"api/histories/"+t.get("history_id")+"/contents/"+f,{deleted:!0}),t.state("submit","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response.");else{Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshHdas();var n=e.outputs[0];t.state("queued","Job has been queued..."),t.set("dataset_id_job",n.id),s._loop(n.id,function(e){switch(e.state){case"ok":return t.state("success","Job completed successfully..."),i(e),!0;case"error":return t.state("failed","Job has failed. Please check the history for details."),!0;case"running":return t.state("running","Job is running..."),!1}})}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires the R-kit. Please make sure it is installed. "+n)})},_loop:function(t,n){var r=this;e.request("GET",config.root+"api/jobs/"+t,{},function(e){n(e)||setTimeout(function(){r._loop(t,n)},r.app.config.get("query_timeout"))})}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._fetch(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o="",u={},a=0;for(var f in t.groups){var l=t.groups[f];for(var c in l.columns){var h=l.columns[c];o+=h+",",u[h]=a,a++}}if(a==0){n({});return}o=o.substring(0,o.length-1);var p=t.groups.slice(0);for(var f in p)p[f].values=[];var d=this;e.request("GET",config.root+"api/datasets/"+t.id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:o},function(e){for(var i in e.data){var s=e.data[i];for(var o in t.groups){var a=t.groups[o],f={x:parseInt(i)+r};for(var l in a.columns){var c=a.columns[l],h=u[c],d=s[h];if(isNaN(d)||!d)d=0;f[l]=d}p[o].values.push(f)}}n(p)})}})}),define("plugin/library/ui-table",["utils/utils"],function(e){var t=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t){var n=$("<td></td>");t&&n.css("width",t),n.append(e),this.row.append(n)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}});return{View:t}}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({list:{},optionsDefault:{height:300},initialize:function(t,r){this.app=t,this.options=n.merge(r,this.optionsDefault),this.portlet=new e.View({title:"title",height:this.options.height,overflow:"hidden"}),this.setElement(this.portlet.$el);var i=this;this.app.charts.on("remove",function(e){i._removeChart(e.id)}),this.app.charts.on("redraw",function(e){e.ready()?i._refreshChart(e):e.on("change:state",function(){e.ready()&&i._refreshChart(e)})})},showChart:function(e){this.show(),this.hideCharts();var t=this.list[e];if(t){var n=self.app.charts.get(e);this.portlet.title(n.get("title")),t.$el.show(),$(window).trigger("resize")}},hideCharts:function(){this.$el.find(".item").hide()},show:function(){$(".tooltip").hide(),this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_refreshChart:function(e){var t=this;if(!e.ready()){t.app.log("viewport:_refreshChart()","Invalid attempt to refresh chart before completion.");return}var n=e.id;this._removeChart(n);var r="#"+n,i=$(this._template({id:r}));this.portlet.append(i);var s=d3.select(r+" svg");this.list[n]={svg:s,$el:i},this.showChart(n),e.off("change:state"),e.on("change:state",function(){var t=i.find("#info"),n=t.find("#icon");n.removeClass(),t.show(),t.find("#text").html(e.get("state_info"));var r=e.get("state");switch(r){case"ok":t.hide();break;case"failed":n.addClass("fa fa-warning");break;default:n.addClass("fa fa-spinner fa-spin")}}),e.state("wait","Please wait...");var o=e.get("type"),u=this.app.types.get(o),t=this;require(["plugin/charts/"+o+"/"+o],function(n){var r=new n(t.app,{svg:s});u.execute?t.app.jobs.submit(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){r.draw(e,t._defaultRequestDictionary(e))}):r.draw(e,t._defaultRequestDictionary(e))})},_removeChart:function(e){var t=this.list[e];t&&(t.svg.remove(),t.$el.remove())},_template:function(e){return'<div id="'+e.id.substr(1)+'" class="item">'+'<span id="info">'+'<span id="icon" style="font-size: 1.2em; display: inline-block;"/>'+'<span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/>'+"</span>"+'<svg style="height: auto;"/>'+"</div>"},_defaultRequestString:function(e){var t=this.app.types.get(e.get("type")),n="",r=0;return e.groups.each(function(e){for(var i in t.columns)n+=i+"_"+ ++r+":"+(parseInt(e.get(i))+1)+", "}),n.substring(0,n.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t=this.app.types.get(e.get("type")),n={id:e.get("dataset_id"),groups:[]},r=0;return e.groups.each(function(e){var i={};for(var s in t.columns)i[s]=e.get(s);n.groups.push({key:++r+":"+e.get("key"),columns:i})}),n}})}),define("plugin/views/charts",["mvc/ui/ui-portlet","plugin/library/ui-table","plugin/library/ui","utils/utils","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i,s){return Backbone.View.extend({initialize:function(i,o){this.app=i,this.viewport_view=new s(i),this.table=new t.View({content:"Add charts to this table.",ondblclick:function(e){u._showChartView(e)},onchange:function(e){var t=u.app.charts.get(e);u.app.config.set("title",t.get("title")),u.viewport_view.showChart(e)}});var u=this;this.portlet=new e.View({icon:"fa-list",title:"List of created charts:",height:100,operations:{"new":new n.ButtonIcon({icon:"fa-magic",tooltip:"Create a new Chart",title:"New",onclick:function(){u.app.go("chart_view"),u.app.chart.reset()}}),edit:new n.ButtonIcon({icon:"fa-gear",tooltip:"Customize this Chart",title:"Customize",onclick:function(){var e=u.table.value();if(!e)return;u._showChartView(e)}}),"delete":new n.ButtonIcon({icon:"fa-trash-o",tooltip:"Delete this Chart",title:"Delete",onclick:function(){var e=u.table.value();if(!e)return;var t=u.app.charts.get(e);u.app.modal.show({title:"Are you sure?",body:'The selected chart "'+t.get("title")+'" will be irreversibly deleted.',buttons:{Cancel:function(){u.app.modal.hide()},Delete:function(){u.app.modal.hide(),u.app.charts.remove(e)}}})}})}}),this.portlet.append(this.table.$el),this.app.options.config.widget||this.$el.append(this.portlet.$el),this.$el.append(r.wrap("")),this.$el.append(this.viewport_view.$el);var u=this;this.app.charts.on("add",function(e){u._addChart(e)}),this.app.charts.on("remove",function(e){u._removeChart(e)}),this.app.charts.on("change",function(e){u._changeChart(e)})},show:function(){this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_addChart:function(e){var t=e.get("title");t==""&&(t="Untitled"),this.table.add(t);var n=this.app.types.get(e.get("type"));this.table.add(n.title),this.table.add("Last change: "+e.get("date")),this.table.prepend(e.get("id")),this.table.value(e.get("id"))},_removeChart:function(e){this.table.remove(e.id),this.app.charts.save(),this.table.size()==0?(this.app.go("chart_view"),this.app.chart.reset()):this.table.value(this.app.charts.last().id)},_changeChart:function(e){e.get("type")&&(this._addChart(e),this.table.value(e.id))},_showChartView:function(e){var t=this.app.charts.get(e);if(t.ready())this.app.go("chart_view"),this.app.chart.copy(t);else{var n=this;this.app.modal.show({title:"Please wait!",body:'The selected chart "'+t.get("title")+'" is currently being processed. Please wait...',buttons:{Close:function(){n.app.modal.hide()},Retry:function(){n.app.modal.hide(),n._showChartView(e)}}})}}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})});var Visualization=Backbone.Model.extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","mvc/visualization/visualization-model"],function(e){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"ok",state_info:""},initialize:function(t){this.groups=new e,this.settings=new Backbone.Model},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state_info",t),this.set("state",e)},ready:function(){return this.get("state")=="ok"||this.get("state")=="failed"}})}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({columns:[],initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e.View({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.app.datasets.request({id:e},function(e){r.columns=[];var t=e.metadata_column_types;for(var n in t)(t[n]=="int"||t[n]=="float")&&r.columns.push({label:"Column: "+(parseInt(n)+1)+" ["+t[n]+"]",value:n});for(var n in s)s[n].update(r.columns),s[n].show()})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e.View({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll();for(var n in e)this._add(n,e[n],t)},_add:function(e,n,r){var i=null,s=n.type;switch(s){case"text":i=new t.Input({placeholder:n.placeholder,onchange:function(){r.set(e,i.value())}});break;case"select":i=new t.Select.View({data:n.data,onchange:function(){r.set(e,i.value())}});break;case"slider":i=new t.Input({placeholder:n.placeholder,onchange:function(){r.set(e,i.value())}});break;case"separator":i=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(s!="separator"){r.get(e)||r.set(e,n.init),i.value(r.get(e));var o=$("<div/>");o.append(i.$el),o.append('<div class="toolParamHelp"  style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(o)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/chart",["mvc/ui/ui-tabs","plugin/library/ui-table","plugin/library/ui","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings"],function(e,t,n,r,i,s,o,u){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(i,s){this.app=i,this.chart=this.app.chart,this.options=r.merge(s,this.optionsDefault);var o=this;this.table=new t.View({header:!1,onconfirm:function(e){o.chart.groups.length>0?o.app.modal.show({title:"Switching to another chart type?",body:"If you continue your settings and selections will be cleared.",buttons:{Cancel:function(){o.app.modal.hide()},Continue:function(){o.app.modal.hide(),o.table.value(e)}}}):o.table.value(e)},onchange:function(e){o.chart.groups.reset(),o.chart.settings.clear(),o.chart.set({type:e})},ondblclick:function(e){o.tabs.show("settings")},content:"No chart types available"});var a=0,f=i.types.attributes;for(var l in f){var c=f[l];this.table.add(++a+"."),c.execute?this.table.add(c.title+" (requires processing)"):this.table.add(c.title),this.table.append(l)}this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=o._addGroupModel();o.tabs.show(e.id)},operations:{save:new n.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){o.app.go("charts_view"),o._saveChart()}}),back:new n.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){o.app.go("charts_view")}})}}),this.title=new n.Input({placeholder:"Chart title",onchange:function(){o.app.config.set("title",o.title.value())}});var h=$("<div/>");h.append(r.wrap((new n.Label({title:"Provide a chart title:"})).$el)),h.append(r.wrap(this.title.$el)),h.append(r.wrap((new n.Label({title:"Select a chart type:"})).$el)),h.append(r.wrap(this.table.$el)),this.tabs.add({id:"main",title:"Start",$el:h}),this.settings=new u(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.setElement(this.tabs.$el),this.tabs.hideOperation("back");var o=this;this.chart.on("change:title",function(e){o.title.value(e.get("title")),o.app.config.set("title",e.get("title"))}),this.chart.on("change:type",function(e){o.table.value(e.get("type"))}),this.chart.on("reset",function(e){o._resetChart()}),this.app.charts.on("add",function(e){o.tabs.showOperation("back")}),this.app.charts.on("remove",function(e){o.app.charts.length==0&&o.tabs.hideOperation("back")}),this.app.charts.on("reset",function(e){o.tabs.hideOperation("back")}),this.app.chart.groups.on("add",function(e){o._addGroup(e)}),this.app.chart.groups.on("remove",function(e){o._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){o._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){o._refreshGroupKey()}),this._resetChart()},show:function(){this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new s({id:r.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new o(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey()},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",r.uuid()),this.chart.set("type","bardiagram"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart")},_saveChart:function(){this.chart.set({type:this.table.value(),title:this.title.value(),date:r.time()}),this.chart.groups.length==0&&this._addGroupModel();var e=this.app.charts.get(this.chart.id);e?e.copy(this.chart):(e=this.chart.clone(),e.copy(this.chart),this.app.charts.add(e)),e.trigger("redraw",e),this.app.charts.save()}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:1e3,query_timeout:500,title:"Create a new chart"}})}),define("plugin/models/charts",["plugin/models/chart"],function(e){return Backbone.Collection.extend({model:e,save:function(){var e=new Visualization({type:"charts",config:{charts:[]}});e.save().fail(function(e,t,n){console.error(e,t,n),alert("Error loading data:\n"+e.responseText)})}})}),define("plugin/charts/_nvd3/config",[],function(){return{title:"",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"f",data:[{label:"-- Do not show values --",value:"hide"},{label:"Float",value:"f"},{label:"Exponent",value:"e"},{label:"Integer",value:"d"},{label:"Percentage",value:"p"},{label:"Rounded",value:"r"},{label:"SI-prefix",value:"s"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"f",data:[{label:"-- Do not show values --",value:"hide"},{label:"Float",value:"f"},{label:"Exponent",value:"e"},{label:"Integer",value:"d"},{label:"Percentage",value:"p"},{label:"Rounded",value:"r"},{label:"SI-prefix",value:"s"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/bardiagram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram"})}),define("plugin/charts/histogram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",execute:!0,columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"},y_axis_tick:{init:".3"}}})}),define("plugin/charts/horizontal/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram (horizontal)",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/line/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart"})}),define("plugin/charts/linewithfocus/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus"})}),define("plugin/charts/piechart/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Pie chart"})}),define("plugin/charts/scatterplot/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/stackedarea/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked area"})}),define("plugin/charts/types",["plugin/charts/bardiagram/config","plugin/charts/histogram/config","plugin/charts/horizontal/config","plugin/charts/line/config","plugin/charts/linewithfocus/config","plugin/charts/piechart/config","plugin/charts/scatterplot/config","plugin/charts/stackedarea/config"],function(e,t,n,r,i,s,o,u){return Backbone.Model.extend({defaults:{bardiagram:e,horizontal:n,histogram:t,line:r,linewithfocus:i,piechart:s,scatterplot:o,stackedarea:u}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/views/charts","plugin/views/chart","plugin/models/config","plugin/models/chart","plugin/models/charts","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(n){this.options=n,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new a,this.jobs=new i(this),this.types=new c,this.chart=new f,this.charts=new l,this.datasets=new s(this),this.charts_view=new o(this),this.chart_view=new u(this),this.options.config.widget?this.portlet=$("<div></div>"):this.portlet=new t.View({icon:"fa-bar-chart-o"}),this.portlet.append(this.charts_view.$el),this.portlet.append(this.chart_view.$el),this.options.config.widget?this.setElement(this.portlet):this.setElement(this.portlet.$el),this.go("chart_view");var r=this;this.config.on("change:title",function(){r._refreshTitle()}),this.render()},go:function(e){switch(e){case"chart_view":this.chart_view.show(),this.charts_view.hide();break;case"charts_view":this.chart_view.hide(),this.charts_view.show()}},render:function(){this._refreshTitle()},_refreshTitle:function(){var e=this.config.get("title");e&&(e=" - "+e),this.portlet.title("Charts"+e)},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})});
\ No newline at end of file
+(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n","	":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-modal",["utils/utils"],function(e){var t=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast")},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&(this.options.buttons.Pause||$(document).on("keyup",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:t}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm portlet-view no-highlight">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">',e.icon&&(t+='<div class="portlet-title-icon fa '+e.icon+'"> </div>'),t+='<div id="title-text" class="portlet-title-text">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody portlet-body">',e.placement=="top"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+='<div id="content" class="portlet-content"/>',e.placement=="bottom"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return"<label><b>"+e.title+"</b></label>"},value:function(){return options.title}}),r=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),i=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),s=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),o=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),u=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),a=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),f=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),l=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),c=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:n,Button:r,Icon:i,ButtonIcon:s,Input:c,Anchor:o,Message:u,Searchbox:a,Title:f,Select:t,ButtonMenu:l}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},cleanup:function(t){var n=t.get("dataset_id_job");if(n){var r=this;e.request("PUT",config.root+"api/histories/none/contents/"+n,{deleted:!0},function(){r._refreshHdas()})}},submit:function(t,n,r,i){var s=this,o=t.id,u=t.get("type"),a=this.app.types.get(u);data={tool_id:"rkit",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:u,columns:r,settings:n}},s.cleanup(t),t.state("submit","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response.");else{s._refreshHdas();var n=e.outputs[0];t.state("queued","Job has been queued..."),t.set("dataset_id_job",n.id),s._loop(n.id,function(e){switch(e.state){case"ok":return t.state("success","Job completed successfully..."),i(e),!0;case"error":return t.state("failed","Job has failed. Please check the history for details."),!0;case"running":return t.state("running","Job is running..."),!1}})}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires the R-kit. Please make sure it is installed. "+n)})},_loop:function(t,n){var r=this;e.request("GET",config.root+"api/jobs/"+t,{},function(e){n(e)||setTimeout(function(){r._loop(t,n)},r.app.config.get("query_timeout"))})},_refreshHdas:function(){Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshHdas()}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._fetch(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o="",u={},a=0;for(var f in t.groups){var l=t.groups[f];for(var c in l.columns){var h=l.columns[c];o+=h+",",u[h]=a,a++}}if(a==0){n({});return}o=o.substring(0,o.length-1);var p=t.groups.slice(0);for(var f in p)p[f].values=[];var d=this;e.request("GET",config.root+"api/datasets/"+t.id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:o},function(e){for(var i in e.data){var s=e.data[i];for(var o in t.groups){var a=t.groups[o],f={x:parseInt(i)+r};for(var l in a.columns){var c=a.columns[l],h=u[c],d=s[h];if(isNaN(d)||!d)d=0;f[l]=d}p[o].values.push(f)}}n(p)})}})}),define("plugin/library/ui-table",["utils/utils"],function(e){var t=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t){var n=$("<td></td>");t&&n.css("width",t),n.append(e),this.row.append(n)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}});return{View:t}}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({list:{},optionsDefault:{height:300},initialize:function(t,r){this.app=t,this.options=n.merge(r,this.optionsDefault),this.portlet=new e.View({title:"title",height:this.options.height,overflow:"hidden"}),this.setElement(this.portlet.$el);var i=this;this.app.charts.on("remove",function(e){i._removeChart(e.id)}),this.app.charts.on("redraw",function(e){i._drawChart(e)})},showChart:function(e){this.show(),this.hideCharts();var t=this.list[e];if(t){var n=this.app.charts.get(e);this.portlet.title(n.get("title")),t.$el.show(),$(window).trigger("resize")}},hideCharts:function(){this.$el.find(".item").hide()},show:function(){$(".tooltip").hide(),this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_drawChart:function(e){var t=this;if(!e.ready()){t.app.log("viewport:_drawChart()","Invalid attempt to draw chart before completion.");return}var n=e.id;this._removeChart(n);var r="#"+n,i=$(this._template({id:r}));this.portlet.append(i);var s=d3.select(i.find("svg")[0]);this.list[n]={svg:s,$el:i},e.off("change:state"),e.on("change:state",function(){var t=i.find("#info"),n=t.find("#icon");n.removeClass(),t.show(),t.find("#text").html(e.get("state_info"));var r=e.get("state");switch(r){case"ok":t.hide();break;case"failed":n.addClass("fa fa-warning");break;default:n.addClass("fa fa-spinner fa-spin")}}),e.state("wait","Please wait...");var o=e.get("type"),u=this.app.types.get(o),t=this;require(["plugin/charts/"+o+"/"+o],function(n){var r=new n(t.app,{svg:s});u.execute?t.app.jobs.submit(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){r.draw(e,t._defaultRequestDictionary(e))}):r.draw(e,t._defaultRequestDictionary(e))})},_removeChart:function(e){var t=this.list[e];t&&(t.svg.remove(),t.$el.remove())},_template:function(e){return'<div id="'+e.id.substr(1)+'" class="item">'+'<span id="info">'+'<span id="icon" style="font-size: 1.2em; display: inline-block;"/>'+'<span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/>'+"</span>"+'<svg style="height: auto;"/>'+"</div>"},_defaultRequestString:function(e){var t=this.app.types.get(e.get("type")),n="",r=0;return e.groups.each(function(e){for(var i in t.columns)n+=i+"_"+ ++r+":"+(parseInt(e.get(i))+1)+", "}),n.substring(0,n.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t=this.app.types.get(e.get("type")),n={id:e.get("dataset_id"),groups:[]},r=0;return e.groups.each(function(e){var i={};for(var s in t.columns)i[s]=e.get(s);n.groups.push({key:++r+":"+e.get("key"),columns:i})}),n}})}),define("plugin/views/charts",["mvc/ui/ui-portlet","plugin/library/ui-table","plugin/library/ui","utils/utils","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i,s){return Backbone.View.extend({initialize:function(i,o){this.app=i,this.viewport_view=new s(i),this.table=new t.View({content:"Add charts to this table.",ondblclick:function(e){u._showChartView(e)},onchange:function(e){var t=u.app.charts.get(e);u.app.config.set("title",t.get("title")),u.viewport_view.showChart(e)}});var u=this;this.portlet=new e.View({icon:"fa-list",title:"List of created charts:",height:100,operations:{"new":new n.ButtonIcon({icon:"fa-magic",tooltip:"Create a new Chart",title:"New",onclick:function(){u.app.go("chart_view"),u.app.chart.reset()}}),edit:new n.ButtonIcon({icon:"fa-gear",tooltip:"Customize this Chart",title:"Customize",onclick:function(){var e=u.table.value();if(!e)return;u._showChartView(e)}}),"delete":new n.ButtonIcon({icon:"fa-trash-o",tooltip:"Delete this Chart",title:"Delete",onclick:function(){var e=u.table.value();if(!e)return;var t=u.app.charts.get(e);u._wait(t,function(){u.app.modal.show({title:"Are you sure?",body:'The selected chart "'+t.get("title")+'" will be irreversibly deleted.',buttons:{Cancel:function(){u.app.modal.hide()},Delete:function(){u.app.modal.hide(),u.app.charts.remove(e),u.app.jobs.cleanup(t)}}})})}})}}),this.portlet.append(this.table.$el),this.app.options.config.widget||this.$el.append(this.portlet.$el),this.$el.append(r.wrap("")),this.$el.append(this.viewport_view.$el);var u=this;this.app.charts.on("add",function(e){u._addChart(e)}),this.app.charts.on("remove",function(e){u._removeChart(e)}),this.app.charts.on("change",function(e){u._changeChart(e)})},show:function(){this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_addChart:function(e){var t=e.get("title");t==""&&(t="Untitled"),this.table.add(t);var n=this.app.types.get(e.get("type"));this.table.add(n.title),this.table.add("Last change: "+e.get("date")),this.table.prepend(e.get("id")),this.table.value(e.get("id"))},_removeChart:function(e){this.table.remove(e.id),this.app.charts.save(),this.table.size()==0?(this.app.go("chart_view"),this.app.chart.reset()):this.table.value(this.app.charts.last().id)},_changeChart:function(e){e.get("type")&&(this._addChart(e),this.table.value(e.id))},_showChartView:function(e){var t=this,n=this.app.charts.get(e);this._wait(n,function(){t.app.go("chart_view"),t.app.chart.copy(n)})},_wait:function(e,t){if(e.ready())t();else{var n=this;this.app.modal.show({title:"Please wait!",body:'The selected chart "'+e.get("title")+'" is currently being processed. Please wait...',buttons:{Close:function(){n.app.modal.hide()},Retry:function(){n.app.modal.hide(),setTimeout(function(){n._wait(e,t)},n.app.config.get("query_timeout"))}}})}}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})});var Visualization=Backbone.Model.extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","mvc/visualization/visualization-model"],function(e){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"ok",state_info:""},initialize:function(t){this.groups=new e,this.settings=new Backbone.Model},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state_info",t),this.set("state",e)},ready:function(){return this.get("state")=="ok"||this.get("state")=="failed"}})}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({columns:[],initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e.View({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.app.datasets.request({id:e},function(e){r.columns=[];var t=e.metadata_column_types;for(var n in t)(t[n]=="int"||t[n]=="float")&&r.columns.push({label:"Column: "+(parseInt(n)+1)+" ["+t[n]+"]",value:n});for(var n in s)s[n].update(r.columns),s[n].show()})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e.View({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll();for(var n in e)this._add(n,e[n],t)},_add:function(e,n,r){var i=null,s=n.type;switch(s){case"text":i=new t.Input({placeholder:n.placeholder,onchange:function(){r.set(e,i.value())}});break;case"select":i=new t.Select.View({data:n.data,onchange:function(){r.set(e,i.value())}});break;case"slider":i=new t.Input({placeholder:n.placeholder,onchange:function(){r.set(e,i.value())}});break;case"separator":i=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(s!="separator"){r.get(e)||r.set(e,n.init),i.value(r.get(e));var o=$("<div/>");o.append(i.$el),o.append('<div class="toolParamHelp"  style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(o)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/chart",["mvc/ui/ui-tabs","plugin/library/ui-table","plugin/library/ui","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings"],function(e,t,n,r,i,s,o,u){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(i,s){this.app=i,this.chart=this.app.chart,this.options=r.merge(s,this.optionsDefault);var o=this;this.table=new t.View({header:!1,onconfirm:function(e){o.chart.groups.length>0?o.app.modal.show({title:"Switching to another chart type?",body:"If you continue your settings and selections will be cleared.",buttons:{Cancel:function(){o.app.modal.hide()},Continue:function(){o.app.modal.hide(),o.table.value(e)}}}):o.table.value(e)},onchange:function(e){o.chart.groups.reset(),o.chart.settings.clear(),o.chart.set({type:e})},ondblclick:function(e){o.tabs.show("settings")},content:"No chart types available"});var a=0,f=i.types.attributes;for(var l in f){var c=f[l];this.table.add(++a+"."),c.execute?this.table.add(c.title+" (requires processing)"):this.table.add(c.title),this.table.append(l)}this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=o._addGroupModel();o.tabs.show(e.id)},operations:{save:new n.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){o.app.go("charts_view"),o._saveChart()}}),back:new n.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){o.app.go("charts_view")}})}}),this.title=new n.Input({placeholder:"Chart title",onchange:function(){o.app.config.set("title",o.title.value())}});var h=$("<div/>");h.append(r.wrap((new n.Label({title:"Provide a chart title:"})).$el)),h.append(r.wrap(this.title.$el)),h.append(r.wrap((new n.Label({title:"Select a chart type:"})).$el)),h.append(r.wrap(this.table.$el)),this.tabs.add({id:"main",title:"Start",$el:h}),this.settings=new u(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.setElement(this.tabs.$el),this.tabs.hideOperation("back");var o=this;this.chart.on("change:title",function(e){o.title.value(e.get("title")),o.app.config.set("title",e.get("title"))}),this.chart.on("change:type",function(e){o.table.value(e.get("type"))}),this.chart.on("reset",function(e){o._resetChart()}),this.app.charts.on("add",function(e){o.tabs.showOperation("back")}),this.app.charts.on("remove",function(e){o.app.charts.length==0&&o.tabs.hideOperation("back")}),this.app.charts.on("reset",function(e){o.tabs.hideOperation("back")}),this.app.chart.groups.on("add",function(e){o._addGroup(e)}),this.app.chart.groups.on("remove",function(e){o._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){o._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){o._refreshGroupKey()}),this._resetChart()},show:function(){this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new s({id:r.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new o(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey()},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",r.uuid()),this.chart.set("type","bardiagram"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart")},_saveChart:function(){this.chart.set({type:this.table.value(),title:this.title.value(),date:r.time()}),this.chart.groups.length==0&&this._addGroupModel();var e=this.app.charts.get(this.chart.id);e?e.copy(this.chart):(e=this.chart.clone(),e.copy(this.chart),this.app.charts.add(e)),e.trigger("redraw",e),this.app.charts.save()}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:1e3,query_timeout:500,title:"Create a new chart"}})}),define("plugin/models/charts",["plugin/models/chart","plugin/models/group"],function(e,t){return Backbone.Collection.extend({model:e,vis:null,initialize:function(e,t){this.app=t,this.id=this.app.options.id,this.vis=new Visualization({type:"charts",config:{dataset_id:this.app.options.config.dataset_id,charts:[]}}),this.id&&(this.vis.id=this.id);var n=this.app.options.config.charts;n&&(this.vis.get("config").charts=n)},save:function(){this.vis.get("config").charts=[];var e=this;this.each(function(t){var n={attributes:t.attributes,settings:t.settings.attributes,groups:[]};t.groups.each(function(e){n.groups.push(e.attributes)}),e.vis.get("config").charts.push(n)});var e=this;this.vis.save().fail(function(e,t,n){console.error(e,t,n),alert("Error loading data:\n"+e.responseText)}).then(function(t){t&&t.id&&(e.id=t.id)})},load:function(){var n=this.vis.get("config").charts;for(var r in n){var i=n[r],s=new e;s.set(i.attributes),s.settings.set(i.settings);for(var o in i.groups)s.groups.add(new t(i.groups[o]));s.state("ok","Loaded previously saved visualization."),this.add(s),s.trigger("redraw",s)}}})}),define("plugin/charts/_nvd3/config",[],function(){return{title:"",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"f",data:[{label:"-- Do not show values --",value:"hide"},{label:"Float",value:"f"},{label:"Exponent",value:"e"},{label:"Integer",value:"d"},{label:"Percentage",value:"p"},{label:"Rounded",value:"r"},{label:"SI-prefix",value:"s"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"f",data:[{label:"-- Do not show values --",value:"hide"},{label:"Float",value:"f"},{label:"Exponent",value:"e"},{label:"Integer",value:"d"},{label:"Percentage",value:"p"},{label:"Rounded",value:"r"},{label:"SI-prefix",value:"s"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/bardiagram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram"})}),define("plugin/charts/histogram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",execute:!0,columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"},y_axis_tick:{init:".3"}}})}),define("plugin/charts/horizontal/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram (horizontal)",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/line/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart"})}),define("plugin/charts/linewithfocus/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus"})}),define("plugin/charts/piechart/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Pie chart"})}),define("plugin/charts/scatterplot/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/stackedarea/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked area"})}),define("plugin/charts/types",["plugin/charts/bardiagram/config","plugin/charts/histogram/config","plugin/charts/horizontal/config","plugin/charts/line/config","plugin/charts/linewithfocus/config","plugin/charts/piechart/config","plugin/charts/scatterplot/config","plugin/charts/stackedarea/config"],function(e,t,n,r,i,s,o,u){return Backbone.Model.extend({defaults:{bardiagram:e,horizontal:n,histogram:t,line:r,linewithfocus:i,piechart:s,scatterplot:o,stackedarea:u}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/views/charts","plugin/views/chart","plugin/models/config","plugin/models/chart","plugin/models/charts","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(n){this.options=n,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new a,this.jobs=new i(this),this.types=new c,this.chart=new f,this.charts=new l(null,this),this.datasets=new s(this),this.charts_view=new o(this),this.chart_view=new u(this),this.options.config.widget?this.portlet=$("<div></div>"):this.portlet=new t.View({icon:"fa-bar-chart-o"}),this.portlet.append(this.charts_view.$el),this.portlet.append(this.chart_view.$el),this.options.config.widget?this.setElement(this.portlet):this.setElement(this.portlet.$el);var r=this;this.config.on("change:title",function(){r._refreshTitle()}),this.render(),this.charts.load(),this.charts.length==0?this.go("chart_view"):this.go("charts_view")},go:function(e){switch(e){case"chart_view":this.chart_view.show(),this.charts_view.hide();break;case"charts_view":this.chart_view.hide(),this.charts_view.show()}},render:function(){this._refreshTitle()},_refreshTitle:function(){var e=this.config.get("title");e&&(e=" - "+e),this.portlet.title("Charts"+e)},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})});
\ No newline at end of file
diff -r dec159841d670560582aadc1327bec0673f7003a -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 config/plugins/visualizations/charts/static/charts/_nvd3/nvd3.js
--- a/config/plugins/visualizations/charts/static/charts/_nvd3/nvd3.js
+++ b/config/plugins/visualizations/charts/static/charts/_nvd3/nvd3.js
@@ -65,7 +65,7 @@
                 nv.utils.windowResize(nvd3_model.update);
                 
                 // set chart state
-                chart.set('state', 'ok');
+                chart.state('ok', 'Chart has been drawn.');
             });
         });
     }
diff -r dec159841d670560582aadc1327bec0673f7003a -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 config/plugins/visualizations/charts/static/library/jobs.js
--- a/config/plugins/visualizations/charts/static/library/jobs.js
+++ b/config/plugins/visualizations/charts/static/library/jobs.js
@@ -13,6 +13,20 @@
         this.options = Utils.merge(options, this.optionsDefault);
     },
     
+    // clean
+    cleanup: function(chart) {
+        // cleanup previous dataset file
+        var previous =  chart.get('dataset_id_job');
+        if (previous) {
+            var self = this;
+            Utils.request('PUT', config.root + 'api/histories/none/contents/' + previous, { deleted: true }, function() {
+                // update galaxy history
+                self._refreshHdas();
+            });
+        }
+        
+    },
+    
     // create job
     submit: function(chart, settings_string, columns_string, callback) {
         // link this
@@ -39,11 +53,8 @@
             }
         }
         
-        // cleanup previous dataset file
-        var previous =  chart.get('dataset_id_job');
-        if (previous) {
-            Utils.request('PUT', config.root + 'api/histories/' + chart.get('history_id') + '/contents/' + previous, { deleted: true });
-        }
+        // cleanup
+        self.cleanup(chart);
         
         // set chart state
         chart.state('submit', 'Sending job request...');
@@ -56,9 +67,7 @@
                     chart.state('failed', 'Job submission failed. No response.');
                 } else {
                     // update galaxy history
-                    if (Galaxy && Galaxy.currHistoryPanel) {
-                        Galaxy.currHistoryPanel.refreshHdas();
-                    }
+                    self._refreshHdas();
         
                     // get dataset
                     var job = response.outputs[0];
@@ -105,6 +114,14 @@
                 setTimeout(function() { self._loop(id, callback); }, self.app.config.get('query_timeout'));
             }
         });
+    },
+    
+    // refresh history panel
+    _refreshHdas: function() {
+        // update galaxy history
+        if (Galaxy && Galaxy.currHistoryPanel) {
+            Galaxy.currHistoryPanel.refreshHdas();
+        }
     }
 });
 
diff -r dec159841d670560582aadc1327bec0673f7003a -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 config/plugins/visualizations/charts/static/models/charts.js
--- a/config/plugins/visualizations/charts/static/models/charts.js
+++ b/config/plugins/visualizations/charts/static/models/charts.js
@@ -1,30 +1,113 @@
 // dependencies
-define(['plugin/models/chart'], function(Chart) {
+define(['plugin/models/chart', 'plugin/models/group'], function(Chart, Group) {
 
 // collection
 return Backbone.Collection.extend(
 {
-    model: Chart,
+    // nested chart model contains collections
+    model           : Chart,
     
-    // save charts
-    save: function() {
+    // viz model
+    vis: null,
+    
+    // initialize
+    initialize: function(options, app) {
+        // initialize parameters
+        this.app            = app;
+        this.id             = this.app.options.id;
+        
         // create visualization
-        var vis = new Visualization({
-            type    : 'charts',
+        this.vis = new Visualization({
+            type        : 'charts',
             config  : {
-                charts : []
+                dataset_id  : this.app.options.config.dataset_id,
+                charts      : []
             }
         });
         
-        // copy attributes
-        //vis.set(this.attributes);
+        // add visualization id
+        if (this.id) {
+            this.vis.id = this.id;
+        }
+        
+        // add charts
+        var charts_array = this.app.options.config.charts;
+        if (charts_array) {
+            this.vis.get('config').charts = charts_array;
+        }
+    },
+    
+    // pack and save nested chart models
+    save: function() {
+        // reset
+        this.vis.get('config').charts = [];
+        
+        // pack nested chart models into arrays attributes
+        var self = this;
+        this.each(function(chart) {
+            // create chart dictionary
+            var chart_dict = {
+                attributes : chart.attributes,
+                settings   : chart.settings.attributes,
+                groups     : []
+            };
+            
+            // append groups
+            chart.groups.each(function(group) {
+                chart_dict.groups.push(group.attributes);
+            });
+            
+            // add chart to charts array
+            self.vis.get('config').charts.push(chart_dict);
+        });
         
         // save visualization
-        vis.save()
-            .fail( function( xhr, status, message ){
-                console.error( xhr, status, message );
-                alert( 'Error loading data:\n' + xhr.responseText );
+        var self = this;
+        this.vis.save()
+            .fail(function(xhr, status, message) {
+               console.error(xhr, status, message);
+               alert( 'Error loading data:\n' + xhr.responseText );
+            })
+            .then(function(response) {
+                if (response && response.id) {
+                    self.id = response.id;
+                }
             });
+    },
+    
+    // load nested models/collections from packed dictionary
+    load: function() {
+        // get charts array
+        var charts_array = this.vis.get('config').charts;
+        
+        // unpack chart models
+        for (var i in charts_array) {
+            // get chart details
+            var chart_dict  = charts_array[i];
+            
+            // construct chart model
+            var chart = new Chart();
+            
+            // main
+            chart.set(chart_dict.attributes);
+            
+            // get settings
+            chart.settings.set(chart_dict.settings);
+            
+            // get groups
+            for (var j in chart_dict.groups) {
+                chart.groups.add(new Group(chart_dict.groups[j]));
+            }
+            
+            // reset status
+            chart.state('ok', 'Loaded previously saved visualization.');
+
+            // add to collection
+            this.add(chart);
+            
+            // trigger
+            chart.trigger('redraw', chart);
+        }
     }
 });
 
diff -r dec159841d670560582aadc1327bec0673f7003a -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 config/plugins/visualizations/charts/static/views/charts.js
--- a/config/plugins/visualizations/charts/static/views/charts.js
+++ b/config/plugins/visualizations/charts/static/views/charts.js
@@ -78,20 +78,25 @@
                         // title
                         var chart = self.app.charts.get(chart_id);
                 
-                        // show modal
-                        self.app.modal.show({
-                            title   : 'Are you sure?',
-                            body    : 'The selected chart "' + chart.get('title') + '" will be irreversibly deleted.',
-                            buttons : {
-                                'Cancel'    : function() {self.app.modal.hide();},
-                                'Delete'    : function() {
-                                    // hide modal
-                                    self.app.modal.hide();
-                                    
-                                    // remove chart
-                                    self.app.charts.remove(chart_id);
+                        // make sure that chart is ready
+                        self._wait (chart, function() {
+                            self.app.modal.show({
+                                title   : 'Are you sure?',
+                                body    : 'The selected chart "' + chart.get('title') + '" will be irreversibly deleted.',
+                                buttons : {
+                                    'Cancel'    : function() {self.app.modal.hide();},
+                                    'Delete'    : function() {
+                                        // hide modal
+                                        self.app.modal.hide();
+                                        
+                                        // remove chart
+                                        self.app.charts.remove(chart_id);
+                                        
+                                        // cleanup
+                                        self.app.jobs.cleanup(chart);
+                                    }
                                 }
-                            }
+                            });
                         });
                     }
                 }),
@@ -185,14 +190,19 @@
     
     // show chart editor
     _showChartView: function(chart_id) {
+        var self = this;
+        var chart = this.app.charts.get(chart_id);
+        this._wait (chart, function() {
+            self.app.go('chart_view');
+            self.app.chart.copy(chart);
+        });
+    },
+    
+    // wait for chart to be ready
+    _wait: function(chart, callback) {
         // get chart
-        var chart = this.app.charts.get(chart_id);
         if (chart.ready()) {
-            // show chart view
-            this.app.go('chart_view');
-                    
-            // load chart into view
-            this.app.chart.copy(chart);
+            callback();
         } else {
             // show modal
             var self = this;
@@ -206,7 +216,7 @@
                         self.app.modal.hide();
                         
                         // retry
-                        self._showChartView(chart_id);
+                        setTimeout(function() { self._wait(chart, callback); }, self.app.config.get('query_timeout'));
                     }
                 }
             });
diff -r dec159841d670560582aadc1327bec0673f7003a -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 config/plugins/visualizations/charts/static/views/viewport.js
--- a/config/plugins/visualizations/charts/static/views/viewport.js
+++ b/config/plugins/visualizations/charts/static/views/viewport.js
@@ -43,17 +43,7 @@
         
         // redraw
         this.app.charts.on('redraw', function(chart) {
-            // redraw if chart is not currently processed
-            if (chart.ready()) {
-                self._refreshChart(chart);
-            } else {
-                // redraw once current drawing process has finished
-                chart.on('change:state', function() {
-                    if (chart.ready()) {
-                        self._refreshChart(chart);
-                    }
-                });
-            }
+            self._drawChart(chart);
         });
     },
     
@@ -69,7 +59,7 @@
         var item = this.list[chart_id];
         if (item) {
             // get chart
-            var chart = self.app.charts.get(chart_id);
+            var chart = this.app.charts.get(chart_id);
                 
             // update portlet
             this.portlet.title(chart.get('title'));
@@ -100,13 +90,13 @@
     },
 
     // add
-    _refreshChart: function(chart) {
+    _drawChart: function(chart) {
         // link this
         var self = this;
         
         // check
         if (!chart.ready()) {
-            self.app.log('viewport:_refreshChart()', 'Invalid attempt to refresh chart before completion.');
+            self.app.log('viewport:_drawChart()', 'Invalid attempt to draw chart before completion.');
             return;
         }
        
@@ -126,7 +116,7 @@
         this.portlet.append($chart_el);
         
         // find svg element
-        var svg = d3.select(id + ' svg');
+        var svg = d3.select($chart_el.find('svg')[0]);
         
         // add chart to list
         this.list[chart_id] = {
@@ -134,9 +124,6 @@
             $el : $chart_el
         }
         
-        // show chart from list
-        this.showChart(chart_id);
-        
         // clear all previous handlers (including redraw listeners)
         chart.off('change:state');
         
@@ -172,7 +159,7 @@
         
         // set chart state
         chart.state('wait', 'Please wait...');
-        
+
         // identify chart type
         var chart_type = chart.get('type');
         var chart_settings = this.app.types.get(chart_type);
diff -r dec159841d670560582aadc1327bec0673f7003a -r e7dfb71eeb796d0cf560ffa48445d243aeb37a67 config/plugins/visualizations/charts/templates/charts.mako
--- a/config/plugins/visualizations/charts/templates/charts.mako
+++ b/config/plugins/visualizations/charts/templates/charts.mako
@@ -71,9 +71,10 @@
                 require(['plugin/app'], function(App) {
                     // load options
                     var options = {
+                        id      : ${h.to_json_string( visualization_id )} || undefined,
                         config  : ${h.to_json_string( config )}
                     }
-                    console.log(options);
+                    
                     // create application
                     app = new App(options);
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            commit/galaxy-central: guerler: Charts/Ui:	Improvements and fixes
                        
                        
by commits-noreply@bitbucket.org 21 Mar '14
                    by commits-noreply@bitbucket.org 21 Mar '14
21 Mar '14
                    
                        1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/dec159841d67/
Changeset:   dec159841d67
User:        guerler
Date:        2014-03-21 05:05:21
Summary:     Charts/Ui: Improvements and fixes
Affected #:  17 files
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -59,8 +59,8 @@
             this.setElement(this.portlet);
         }
         
-        // hide views
-        this.charts_view.$el.hide();
+        // start with chart view
+        this.go('chart_view');
         
         // events
         var self = this;
@@ -72,6 +72,21 @@
         this.render();
     },
     
+    // loads a view and makes sure that all others are hidden
+    go: function(view_id) {
+        // pick view
+        switch (view_id) {
+            case 'chart_view' :
+                this.chart_view.show();
+                this.charts_view.hide();
+                break;
+            case 'charts_view' :
+                this.chart_view.hide();
+                this.charts_view.show();
+                break;
+        }
+    },
+    
     // render
     render: function() {
         this._refreshTitle();
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/static/build-app.js
--- a/config/plugins/visualizations/charts/static/build-app.js
+++ b/config/plugins/visualizations/charts/static/build-app.js
@@ -3,4 +3,4 @@
 //     (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
 //     Underscore may be freely distributed under the MIT license.
 
-(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n","	":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-modal",["utils/utils"],function(e){var t=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast")},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&(this.options.buttons.Pause||$(document).on("keyup",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:t}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle" style="overflow: hidden;"><div id="operations" style="float: right;"></div><div style="overflow: hidden;">',e.icon&&(t+='<i style="padding-top: 3px; float: left; font-size: 1.2em" class="icon fa '+e.icon+'"> </i>'),t+='<div id="title-text" style="padding-top: 2px; float: left;">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody">',e.placement=="top"&&(t+='<div id="buttons" class="buttons" style="height: 50px; padding: 10px;"></div>'),t+='<div id="content" class="content" style="height: inherit; padding: 10px;"></div>',e.placement=="bottom"&&(t+='<div id="buttons" class="buttons" style="height: 50px; padding: 10px;"></div>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return"<label><b>"+e.title+"</b></label>"},value:function(){return options.title}}),r=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),i=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),s=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),o=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),u=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),a=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),f=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),l=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),c=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:n,Button:r,Icon:i,ButtonIcon:s,Input:c,Anchor:o,Message:u,Searchbox:a,Title:f,Select:t,ButtonMenu:l}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},submit:function(t,n,r,i){var s=this,o=t.id,u=t.get("type"),a=this.app.types.get(u);data={tool_id:"rkit",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:u,columns:r,settings:n}};var f=t.get("dataset_id_job");f&&e.request("PUT",config.root+"api/histories/"+t.get("history_id")+"/contents/"+f,{deleted:!0}),t.state("submit","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response.");else{Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshHdas();var n=e.outputs[0];t.state("queued","Job has been queued..."),t.set("dataset_id_job",n.id),s._loop(n.id,function(e){switch(e.state){case"ok":return t.state("success","Job completed successfully..."),i(e),!0;case"error":return t.state("failed","Job has failed. Please check the history for details."),!0;case"running":return t.state("running","Job is running..."),!1}})}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires processing by the R-kit. Please make sure that it is installed. "+n)})},_loop:function(t,n){var r=this;e.request("GET",config.root+"api/jobs/"+t,{},function(e){n(e)||setTimeout(function(){r._loop(t,n)},r.app.config.get("query_timeout"))})}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._fetch(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o="",u={},a=0;for(var f in t.groups){var l=t.groups[f];for(var c in l.columns){var h=l.columns[c];o+=h+",",u[h]=a,a++}}if(a==0){n({});return}o=o.substring(0,o.length-1);var p=t.groups.slice(0);for(var f in p)p[f].values=[];var d=this;e.request("GET",config.root+"api/datasets/"+t.id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:o},function(e){for(var i in e.data){var s=e.data[i];for(var o in t.groups){var a=t.groups[o],f={x:parseInt(i)+r};for(var l in a.columns){var c=a.columns[l],h=u[c],d=s[h];if(isNaN(d)||!d)d=0;f[l]=d}p[o].values.push(f)}}n(p)})}})}),define("plugin/library/ui-table",["utils/utils"],function(e){return Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t){var n=$("<td></td>");t&&n.css("width",t),n.append(e),this.row.append(n)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}})}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({list:{},optionsDefault:{height:300},initialize:function(r,i){this.app=r,this.options=n.merge(i,this.optionsDefault),this.portlet=new e.View({title:"title",height:this.options.height,overflow:"hidden",operations:{edit:new t.ButtonIcon({icon:"fa-gear",tooltip:"Customize Chart",title:"Customize"})}}),this.setElement(this.portlet.$el);var s=this;this.app.charts.on("remove",function(e){s._removeChart(e.id)}),this.app.charts.on("redraw",function(e){e.ready()?s._refreshChart(e):e.on("change:state",function(){e.ready()&&s._refreshChart(e)})})},showChart:function(e){this.show(),this.hideCharts();var t=this.list[e];if(t){var n=self.app.charts.get(e);this.portlet.title(n.get("title")),this.portlet.setOperation("edit",function(){self.app.chart.copy(n),self.app.charts_view.hide(),self.app.chart_view.$el.show()}),t.$el.show(),$(window).trigger("resize")}},hideCharts:function(){this.$el.find(".item").hide()},show:function(){$(".tooltip").hide(),this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_refreshChart:function(e){var t=this;if(!e.ready()){t.app.log("viewport:_refreshChart()","Invalid attempt to refresh chart before completion.");return}var n=e.id;this._removeChart(n);var r="#"+n,i=$(this._template({id:r}));this.portlet.append(i);var s=d3.select(r+" svg");this.list[n]={svg:s,$el:i},this.showChart(n),e.off("change:state"),e.on("change:state",function(){var t=i.find("#info"),n=t.find("#icon");n.removeClass(),t.show(),t.find("#text").html(e.get("state_info"));var r=e.get("state");switch(r){case"ok":t.hide();break;case"failed":n.addClass("fa fa-warning");break;default:n.addClass("fa fa-spinner fa-spin")}}),e.state("wait","Please wait...");var o=e.get("type"),u=this.app.types.get(o),t=this;require(["plugin/charts/"+o+"/"+o],function(n){var r=new n(t.app,{svg:s});u.execute?t.app.jobs.submit(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){r.draw(e,t._defaultRequestDictionary(e))}):r.draw(e,t._defaultRequestDictionary(e))})},_removeChart:function(e){var t=this.list[e];t&&(t.svg.remove(),t.$el.remove())},_template:function(e){return'<div id="'+e.id.substr(1)+'" class="item">'+'<span id="info">'+'<span id="icon" style="font-size: 1.2em; display: inline-block;"/>'+'<span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/>'+"</span>"+'<svg style="height: auto;"/>'+"</div>"},_defaultRequestString:function(e){var t=this.app.types.get(e.get("type")),n="",r=0;return e.groups.each(function(e){for(var i in t.columns)n+=i+"_"+ ++r+":"+(parseInt(e.get(i))+1)+", "}),n.substring(0,n.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t=this.app.types.get(e.get("type")),n={id:e.get("dataset_id"),groups:[]},r=0;return e.groups.each(function(e){var i={};for(var s in t.columns)i[s]=e.get(s);n.groups.push({key:++r+":"+e.get("key"),columns:i})}),n}})}),define("plugin/views/charts",["mvc/ui/ui-portlet","plugin/library/ui-table","plugin/library/ui","utils/utils","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i,s){return Backbone.View.extend({initialize:function(i,o){this.app=i,this.viewport_view=new s(i),this.table=new t({content:"Add charts to this table.",ondblclick:function(e){var t=u.app.charts.get(e);u.app.chart.copy(t),u.hide(),u.app.chart_view.$el.show()},onchange:function(e){var t=u.app.charts.get(e);u.app.config.set("title",t.get("title")),u.viewport_view.showChart(e)}});var u=this;this.portlet=new e.View({icon:"fa-list",title:"List of created charts:",height:100,operations:{"new":new n.ButtonIcon({icon:"fa-magic",tooltip:"Create a new Chart",title:"New",onclick:function(){u.hide(),u.app.chart.reset(),u.app.chart_view.$el.show()}}),"delete":new n.ButtonIcon({icon:"fa-trash-o",tooltip:"Delete this Chart",title:"Delete",onclick:function(){var e=u.table.value();if(!e)return;var t=u.app.charts.get(e);u.app.modal.show({title:"Are you sure?",body:'The selected chart "'+t.get("title")+'" will be irreversibly deleted.',buttons:{Cancel:function(){u.app.modal.hide()},Delete:function(){u.app.modal.hide(),u.app.charts.remove(e)}}})}})}}),this.portlet.append(this.table.$el),this.app.options.config.widget||this.$el.append(this.portlet.$el),this.$el.append(r.wrap("")),this.$el.append(this.viewport_view.$el);var u=this;this.app.charts.on("add",function(e){u._addChart(e)}),this.app.charts.on("remove",function(e){u._removeChart(e)}),this.app.charts.on("change",function(e){u._changeChart(e)})},hide:function(){$(".tooltip").hide(),this.$el.hide()},_addChart:function(e){var t=e.get("title");t==""&&(t="Untitled"),this.table.add(t);var n=this.app.types.get(e.get("type"));this.table.add(n.title),this.table.add("Last change: "+e.get("date")),this.table.prepend(e.get("id")),this.table.value(e.get("id"))},_removeChart:function(e){this.table.remove(e.id),this.table.size()==0?(this.hide(),this.app.chart.reset(),this.app.chart_view.$el.show()):this.table.value(this.app.charts.last().id)},_changeChart:function(e){e.get("type")&&(this._addChart(e),this.table.value(e.id))}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})});var Visualization=Backbone.Model.extend(LoggableMixin).extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){this.log(this+".initialize",e,this.attributes),_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend(LoggableMixin).extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","mvc/visualization/visualization-model"],function(e){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"ok",state_info:""},initialize:function(t){this.groups=new e,this.settings=new Backbone.Model},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state_info",t),this.set("state",e)},ready:function(){return this.get("state")=="ok"||this.get("state")=="failed"},save:function(){}})}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({columns:[],initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.app.datasets.request({id:e},function(e){r.columns=[];var t=e.metadata_column_types;for(var n in t)(t[n]=="int"||t[n]=="float")&&r.columns.push({label:"Column: "+(parseInt(n)+1)+" ["+t[n]+"]",value:n});for(var n in s)s[n].update(r.columns),s[n].show()})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll();for(var n in e)this._add(n,e[n],t)},_add:function(e,n,r){var i=null,s=n.type;switch(s){case"text":i=new t.Input({placeholder:n.placeholder,onchange:function(){r.set(e,i.value())}});break;case"select":i=new t.Select.View({data:n.data,onchange:function(){r.set(e,i.value())}});break;case"slider":i=new t.Input({placeholder:n.placeholder,onchange:function(){r.set(e,i.value())}});break;case"separator":i=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(s!="separator"){r.get(e)||r.set(e,n.init),i.value(r.get(e));var o=$("<div/>");o.append(i.$el),o.append('<div class="toolParamHelp"  style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(o)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/chart",["mvc/ui/ui-tabs","plugin/library/ui-table","plugin/library/ui","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings"],function(e,t,n,r,i,s,o,u){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(i,s){this.app=i,this.chart=this.app.chart,this.options=r.merge(s,this.optionsDefault);var o=this;this.table=new t({header:!1,onconfirm:function(e){o.chart.groups.length>0?o.app.modal.show({title:"Switching to another chart type?",body:"If you continue your settings and selections will be reseted.",buttons:{Cancel:function(){o.app.modal.hide()},Continue:function(){o.app.modal.hide(),o.table.value(e)}}}):o.table.value(e)},onchange:function(e){o.chart.groups.reset(),o.chart.settings.clear(),o.chart.set({type:e})},ondblclick:function(e){o.tabs.show("settings")},content:"No chart types available"});var a=0,f=i.types.attributes;for(var l in f){var c=f[l];this.table.add(++a+"."),c.execute?this.table.add(c.title+" (requires processing)"):this.table.add(c.title),this.table.append(l)}this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=o._addGroupModel();o.tabs.show(e.id)},operations:{save:new n.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){o.chart.groups.length==0&&o._addGroupModel(),o._saveChart(),o.hide(),o.app.charts_view.$el.show()}}),back:new n.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){o.hide(),o.app.charts_view.$el.show()}})}}),this.title=new n.Input({placeholder:"Chart title",onchange:function(){o.app.config.set("title",o.title.value())}});var h=$("<div/>");h.append(r.wrap((new n.Label({title:"Provide a chart title:"})).$el)),h.append(r.wrap(this.title.$el)),h.append(r.wrap((new n.Label({title:"Select a chart type:"})).$el)),h.append(r.wrap(this.table.$el)),this.tabs.add({id:"main",title:"Start",$el:h}),this.settings=new u(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.setElement(this.tabs.$el),this.tabs.hideOperation("back");var o=this;this.chart.on("change:title",function(e){o.title.value(e.get("title")),o.app.config.set("title",e.get("title"))}),this.chart.on("change:type",function(e){o.table.value(e.get("type"))}),this.chart.on("reset",function(e){o._resetChart()}),this.app.charts.on("add",function(e){o.tabs.showOperation("back")}),this.app.charts.on("remove",function(e){o.app.charts.length==0&&o.tabs.hideOperation("back")}),this.app.charts.on("reset",function(e){o.tabs.hideOperation("back")}),this.app.chart.groups.on("add",function(e){o._addGroup(e)}),this.app.chart.groups.on("remove",function(e){o._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){o._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){o._refreshGroupKey()}),this._resetChart()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new s({id:r.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new o(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey()},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",r.uuid()),this.chart.set("type","bardiagram"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart")},_saveChart:function(){this.chart.set({type:this.table.value(),title:this.title.value(),date:r.time()});var e=this.app.charts.get(this.chart.id);e?e.copy(this.chart):(e=this.chart.clone(),e.copy(this.chart),this.app.charts.add(e)),e.save(),e.trigger("redraw",e)}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:1e3,query_timeout:500,title:"Create a new chart"}})}),define("plugin/models/charts",["plugin/models/chart"],function(e){return Backbone.Collection.extend({model:e})}),define("plugin/charts/_nvd3/config",[],function(){return{title:"",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"f",data:[{label:"-- Do not show values --",value:"hide"},{label:"Float",value:"f"},{label:"Exponent",value:"e"},{label:"Integer",value:"d"},{label:"Percentage",value:"p"},{label:"Rounded",value:"r"},{label:"SI-prefix",value:"s"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"f",data:[{label:"-- Do not show values --",value:"hide"},{label:"Float",value:"f"},{label:"Exponent",value:"e"},{label:"Integer",value:"d"},{label:"Percentage",value:"p"},{label:"Rounded",value:"r"},{label:"SI-prefix",value:"s"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/bardiagram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram"})}),define("plugin/charts/histogram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",execute:!0,columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"},y_axis_tick:{init:".3"},separator_custom:{title:"Advanced",type:"separator"},bin_size:{title:"Bin size",info:"Provide the bin size for the histogram.",type:"select",init:1,data:[{label:"0.001",value:"0.001"},{label:"0.01",value:"0.01"},{label:"0.1",value:"0.1"},{label:"1",value:"1"},{label:"10",value:"10"},{label:"100",value:"100"},{label:"1000",value:"1000"}]}}})}),define("plugin/charts/horizontal/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram (horizontal)",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/line/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart"})}),define("plugin/charts/linewithfocus/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus"})}),define("plugin/charts/piechart/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Pie chart"})}),define("plugin/charts/scatterplot/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/stackedarea/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked area"})}),define("plugin/charts/types",["plugin/charts/bardiagram/config","plugin/charts/histogram/config","plugin/charts/horizontal/config","plugin/charts/line/config","plugin/charts/linewithfocus/config","plugin/charts/piechart/config","plugin/charts/scatterplot/config","plugin/charts/stackedarea/config"],function(e,t,n,r,i,s,o,u){return Backbone.Model.extend({defaults:{bardiagram:e,horizontal:n,histogram:t,line:r,linewithfocus:i,piechart:s,scatterplot:o,stackedarea:u}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/views/charts","plugin/views/chart","plugin/models/config","plugin/models/chart","plugin/models/charts","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(n){this.options=n,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new a,this.jobs=new i(this),this.types=new c,this.chart=new f,this.charts=new l,this.datasets=new s(this),this.charts_view=new o(this),this.chart_view=new u(this),this.options.config.widget?this.portlet=$("<div></div>"):this.portlet=new t.View({icon:"fa-bar-chart-o"}),this.portlet.append(this.charts_view.$el),this.portlet.append(this.chart_view.$el),this.options.config.widget?this.setElement(this.portlet):this.setElement(this.portlet.$el),this.charts_view.$el.hide();var r=this;this.config.on("change:title",function(){r._refreshTitle()}),this.render()},render:function(){this._refreshTitle()},_refreshTitle:function(){var e=this.config.get("title");e&&(e=" - "+e),this.portlet.title("Charts"+e)},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})});
\ No newline at end of file
+(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n","	":"t","\u2028":"u2028","\u2029":"u2029"},j=/\\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-modal",["utils/utils"],function(e){var t=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast")},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&(this.options.buttons.Pause||$(document).on("keyup",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:t}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm portlet-view no-highlight">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">',e.icon&&(t+='<div class="portlet-title-icon fa '+e.icon+'"> </div>'),t+='<div id="title-text" class="portlet-title-text">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody portlet-body">',e.placement=="top"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+='<div id="content" class="portlet-content"/>',e.placement=="bottom"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return"<label><b>"+e.title+"</b></label>"},value:function(){return options.title}}),r=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),i=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),s=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),o=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),u=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),a=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),f=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),l=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),c=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:n,Button:r,Icon:i,ButtonIcon:s,Input:c,Anchor:o,Message:u,Searchbox:a,Title:f,Select:t,ButtonMenu:l}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},submit:function(t,n,r,i){var s=this,o=t.id,u=t.get("type"),a=this.app.types.get(u);data={tool_id:"rkit",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:u,columns:r,settings:n}};var f=t.get("dataset_id_job");f&&e.request("PUT",config.root+"api/histories/"+t.get("history_id")+"/contents/"+f,{deleted:!0}),t.state("submit","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response.");else{Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshHdas();var n=e.outputs[0];t.state("queued","Job has been queued..."),t.set("dataset_id_job",n.id),s._loop(n.id,function(e){switch(e.state){case"ok":return t.state("success","Job completed successfully..."),i(e),!0;case"error":return t.state("failed","Job has failed. Please check the history for details."),!0;case"running":return t.state("running","Job is running..."),!1}})}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires the R-kit. Please make sure it is installed. "+n)})},_loop:function(t,n){var r=this;e.request("GET",config.root+"api/jobs/"+t,{},function(e){n(e)||setTimeout(function(){r._loop(t,n)},r.app.config.get("query_timeout"))})}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._fetch(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o="",u={},a=0;for(var f in t.groups){var l=t.groups[f];for(var c in l.columns){var h=l.columns[c];o+=h+",",u[h]=a,a++}}if(a==0){n({});return}o=o.substring(0,o.length-1);var p=t.groups.slice(0);for(var f in p)p[f].values=[];var d=this;e.request("GET",config.root+"api/datasets/"+t.id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:o},function(e){for(var i in e.data){var s=e.data[i];for(var o in t.groups){var a=t.groups[o],f={x:parseInt(i)+r};for(var l in a.columns){var c=a.columns[l],h=u[c],d=s[h];if(isNaN(d)||!d)d=0;f[l]=d}p[o].values.push(f)}}n(p)})}})}),define("plugin/library/ui-table",["utils/utils"],function(e){var t=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t){var n=$("<td></td>");t&&n.css("width",t),n.append(e),this.row.append(n)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}});return{View:t}}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({list:{},optionsDefault:{height:300},initialize:function(t,r){this.app=t,this.options=n.merge(r,this.optionsDefault),this.portlet=new e.View({title:"title",height:this.options.height,overflow:"hidden"}),this.setElement(this.portlet.$el);var i=this;this.app.charts.on("remove",function(e){i._removeChart(e.id)}),this.app.charts.on("redraw",function(e){e.ready()?i._refreshChart(e):e.on("change:state",function(){e.ready()&&i._refreshChart(e)})})},showChart:function(e){this.show(),this.hideCharts();var t=this.list[e];if(t){var n=self.app.charts.get(e);this.portlet.title(n.get("title")),t.$el.show(),$(window).trigger("resize")}},hideCharts:function(){this.$el.find(".item").hide()},show:function(){$(".tooltip").hide(),this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_refreshChart:function(e){var t=this;if(!e.ready()){t.app.log("viewport:_refreshChart()","Invalid attempt to refresh chart before completion.");return}var n=e.id;this._removeChart(n);var r="#"+n,i=$(this._template({id:r}));this.portlet.append(i);var s=d3.select(r+" svg");this.list[n]={svg:s,$el:i},this.showChart(n),e.off("change:state"),e.on("change:state",function(){var t=i.find("#info"),n=t.find("#icon");n.removeClass(),t.show(),t.find("#text").html(e.get("state_info"));var r=e.get("state");switch(r){case"ok":t.hide();break;case"failed":n.addClass("fa fa-warning");break;default:n.addClass("fa fa-spinner fa-spin")}}),e.state("wait","Please wait...");var o=e.get("type"),u=this.app.types.get(o),t=this;require(["plugin/charts/"+o+"/"+o],function(n){var r=new n(t.app,{svg:s});u.execute?t.app.jobs.submit(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){r.draw(e,t._defaultRequestDictionary(e))}):r.draw(e,t._defaultRequestDictionary(e))})},_removeChart:function(e){var t=this.list[e];t&&(t.svg.remove(),t.$el.remove())},_template:function(e){return'<div id="'+e.id.substr(1)+'" class="item">'+'<span id="info">'+'<span id="icon" style="font-size: 1.2em; display: inline-block;"/>'+'<span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/>'+"</span>"+'<svg style="height: auto;"/>'+"</div>"},_defaultRequestString:function(e){var t=this.app.types.get(e.get("type")),n="",r=0;return e.groups.each(function(e){for(var i in t.columns)n+=i+"_"+ ++r+":"+(parseInt(e.get(i))+1)+", "}),n.substring(0,n.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t=this.app.types.get(e.get("type")),n={id:e.get("dataset_id"),groups:[]},r=0;return e.groups.each(function(e){var i={};for(var s in t.columns)i[s]=e.get(s);n.groups.push({key:++r+":"+e.get("key"),columns:i})}),n}})}),define("plugin/views/charts",["mvc/ui/ui-portlet","plugin/library/ui-table","plugin/library/ui","utils/utils","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i,s){return Backbone.View.extend({initialize:function(i,o){this.app=i,this.viewport_view=new s(i),this.table=new t.View({content:"Add charts to this table.",ondblclick:function(e){u._showChartView(e)},onchange:function(e){var t=u.app.charts.get(e);u.app.config.set("title",t.get("title")),u.viewport_view.showChart(e)}});var u=this;this.portlet=new e.View({icon:"fa-list",title:"List of created charts:",height:100,operations:{"new":new n.ButtonIcon({icon:"fa-magic",tooltip:"Create a new Chart",title:"New",onclick:function(){u.app.go("chart_view"),u.app.chart.reset()}}),edit:new n.ButtonIcon({icon:"fa-gear",tooltip:"Customize this Chart",title:"Customize",onclick:function(){var e=u.table.value();if(!e)return;u._showChartView(e)}}),"delete":new n.ButtonIcon({icon:"fa-trash-o",tooltip:"Delete this Chart",title:"Delete",onclick:function(){var e=u.table.value();if(!e)return;var t=u.app.charts.get(e);u.app.modal.show({title:"Are you sure?",body:'The selected chart "'+t.get("title")+'" will be irreversibly deleted.',buttons:{Cancel:function(){u.app.modal.hide()},Delete:function(){u.app.modal.hide(),u.app.charts.remove(e)}}})}})}}),this.portlet.append(this.table.$el),this.app.options.config.widget||this.$el.append(this.portlet.$el),this.$el.append(r.wrap("")),this.$el.append(this.viewport_view.$el);var u=this;this.app.charts.on("add",function(e){u._addChart(e)}),this.app.charts.on("remove",function(e){u._removeChart(e)}),this.app.charts.on("change",function(e){u._changeChart(e)})},show:function(){this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_addChart:function(e){var t=e.get("title");t==""&&(t="Untitled"),this.table.add(t);var n=this.app.types.get(e.get("type"));this.table.add(n.title),this.table.add("Last change: "+e.get("date")),this.table.prepend(e.get("id")),this.table.value(e.get("id"))},_removeChart:function(e){this.table.remove(e.id),this.app.charts.save(),this.table.size()==0?(this.app.go("chart_view"),this.app.chart.reset()):this.table.value(this.app.charts.last().id)},_changeChart:function(e){e.get("type")&&(this._addChart(e),this.table.value(e.id))},_showChartView:function(e){var t=this.app.charts.get(e);if(t.ready())this.app.go("chart_view"),this.app.chart.copy(t);else{var n=this;this.app.modal.show({title:"Please wait!",body:'The selected chart "'+t.get("title")+'" is currently being processed. Please wait...',buttons:{Close:function(){n.app.modal.hide()},Retry:function(){n.app.modal.hide(),n._showChartView(e)}}})}}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})});var Visualization=Backbone.Model.extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","mvc/visualization/visualization-model"],function(e){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"ok",state_info:""},initialize:function(t){this.groups=new e,this.settings=new Backbone.Model},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state_info",t),this.set("state",e)},ready:function(){return this.get("state")=="ok"||this.get("state")=="failed"}})}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({columns:[],initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e.View({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.app.datasets.request({id:e},function(e){r.columns=[];var t=e.metadata_column_types;for(var n in t)(t[n]=="int"||t[n]=="float")&&r.columns.push({label:"Column: "+(parseInt(n)+1)+" ["+t[n]+"]",value:n});for(var n in s)s[n].update(r.columns),s[n].show()})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e.View({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll();for(var n in e)this._add(n,e[n],t)},_add:function(e,n,r){var i=null,s=n.type;switch(s){case"text":i=new t.Input({placeholder:n.placeholder,onchange:function(){r.set(e,i.value())}});break;case"select":i=new t.Select.View({data:n.data,onchange:function(){r.set(e,i.value())}});break;case"slider":i=new t.Input({placeholder:n.placeholder,onchange:function(){r.set(e,i.value())}});break;case"separator":i=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(s!="separator"){r.get(e)||r.set(e,n.init),i.value(r.get(e));var o=$("<div/>");o.append(i.$el),o.append('<div class="toolParamHelp"  style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(o)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/chart",["mvc/ui/ui-tabs","plugin/library/ui-table","plugin/library/ui","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings"],function(e,t,n,r,i,s,o,u){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(i,s){this.app=i,this.chart=this.app.chart,this.options=r.merge(s,this.optionsDefault);var o=this;this.table=new t.View({header:!1,onconfirm:function(e){o.chart.groups.length>0?o.app.modal.show({title:"Switching to another chart type?",body:"If you continue your settings and selections will be cleared.",buttons:{Cancel:function(){o.app.modal.hide()},Continue:function(){o.app.modal.hide(),o.table.value(e)}}}):o.table.value(e)},onchange:function(e){o.chart.groups.reset(),o.chart.settings.clear(),o.chart.set({type:e})},ondblclick:function(e){o.tabs.show("settings")},content:"No chart types available"});var a=0,f=i.types.attributes;for(var l in f){var c=f[l];this.table.add(++a+"."),c.execute?this.table.add(c.title+" (requires processing)"):this.table.add(c.title),this.table.append(l)}this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=o._addGroupModel();o.tabs.show(e.id)},operations:{save:new n.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){o.app.go("charts_view"),o._saveChart()}}),back:new n.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){o.app.go("charts_view")}})}}),this.title=new n.Input({placeholder:"Chart title",onchange:function(){o.app.config.set("title",o.title.value())}});var h=$("<div/>");h.append(r.wrap((new n.Label({title:"Provide a chart title:"})).$el)),h.append(r.wrap(this.title.$el)),h.append(r.wrap((new n.Label({title:"Select a chart type:"})).$el)),h.append(r.wrap(this.table.$el)),this.tabs.add({id:"main",title:"Start",$el:h}),this.settings=new u(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.setElement(this.tabs.$el),this.tabs.hideOperation("back");var o=this;this.chart.on("change:title",function(e){o.title.value(e.get("title")),o.app.config.set("title",e.get("title"))}),this.chart.on("change:type",function(e){o.table.value(e.get("type"))}),this.chart.on("reset",function(e){o._resetChart()}),this.app.charts.on("add",function(e){o.tabs.showOperation("back")}),this.app.charts.on("remove",function(e){o.app.charts.length==0&&o.tabs.hideOperation("back")}),this.app.charts.on("reset",function(e){o.tabs.hideOperation("back")}),this.app.chart.groups.on("add",function(e){o._addGroup(e)}),this.app.chart.groups.on("remove",function(e){o._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){o._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){o._refreshGroupKey()}),this._resetChart()},show:function(){this.$el.show()},hide:function(){$(".tooltip").hide(),this.$el.hide()},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new s({id:r.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new o(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey()},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",r.uuid()),this.chart.set("type","bardiagram"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart")},_saveChart:function(){this.chart.set({type:this.table.value(),title:this.title.value(),date:r.time()}),this.chart.groups.length==0&&this._addGroupModel();var e=this.app.charts.get(this.chart.id);e?e.copy(this.chart):(e=this.chart.clone(),e.copy(this.chart),this.app.charts.add(e)),e.trigger("redraw",e),this.app.charts.save()}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:1e3,query_timeout:500,title:"Create a new chart"}})}),define("plugin/models/charts",["plugin/models/chart"],function(e){return Backbone.Collection.extend({model:e,save:function(){var e=new Visualization({type:"charts",config:{charts:[]}});e.save().fail(function(e,t,n){console.error(e,t,n),alert("Error loading data:\n"+e.responseText)})}})}),define("plugin/charts/_nvd3/config",[],function(){return{title:"",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"f",data:[{label:"-- Do not show values --",value:"hide"},{label:"Float",value:"f"},{label:"Exponent",value:"e"},{label:"Integer",value:"d"},{label:"Percentage",value:"p"},{label:"Rounded",value:"r"},{label:"SI-prefix",value:"s"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"f",data:[{label:"-- Do not show values --",value:"hide"},{label:"Float",value:"f"},{label:"Exponent",value:"e"},{label:"Integer",value:"d"},{label:"Percentage",value:"p"},{label:"Rounded",value:"r"},{label:"SI-prefix",value:"s"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/bardiagram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram"})}),define("plugin/charts/histogram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",execute:!0,columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"},y_axis_tick:{init:".3"}}})}),define("plugin/charts/horizontal/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram (horizontal)",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/line/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart"})}),define("plugin/charts/linewithfocus/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus"})}),define("plugin/charts/piechart/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Pie chart"})}),define("plugin/charts/scatterplot/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/stackedarea/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked area"})}),define("plugin/charts/types",["plugin/charts/bardiagram/config","plugin/charts/histogram/config","plugin/charts/horizontal/config","plugin/charts/line/config","plugin/charts/linewithfocus/config","plugin/charts/piechart/config","plugin/charts/scatterplot/config","plugin/charts/stackedarea/config"],function(e,t,n,r,i,s,o,u){return Backbone.Model.extend({defaults:{bardiagram:e,horizontal:n,histogram:t,line:r,linewithfocus:i,piechart:s,scatterplot:o,stackedarea:u}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/views/charts","plugin/views/chart","plugin/models/config","plugin/models/chart","plugin/models/charts","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(n){this.options=n,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new a,this.jobs=new i(this),this.types=new c,this.chart=new f,this.charts=new l,this.datasets=new s(this),this.charts_view=new o(this),this.chart_view=new u(this),this.options.config.widget?this.portlet=$("<div></div>"):this.portlet=new t.View({icon:"fa-bar-chart-o"}),this.portlet.append(this.charts_view.$el),this.portlet.append(this.chart_view.$el),this.options.config.widget?this.setElement(this.portlet):this.setElement(this.portlet.$el),this.go("chart_view");var r=this;this.config.on("change:title",function(){r._refreshTitle()}),this.render()},go:function(e){switch(e){case"chart_view":this.chart_view.show(),this.charts_view.hide();break;case"charts_view":this.chart_view.hide(),this.charts_view.show()}},render:function(){this._refreshTitle()},_refreshTitle:function(){var e=this.config.get("title");e&&(e=" - "+e),this.portlet.title("Charts"+e)},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})});
\ No newline at end of file
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/static/charts/histogram/config.js
--- a/config/plugins/visualizations/charts/static/charts/histogram/config.js
+++ b/config/plugins/visualizations/charts/static/charts/histogram/config.js
@@ -17,46 +17,6 @@
         },
         y_axis_tick : {
             init : '.3'
-        },
-        separator_custom  : {
-            title       : 'Advanced',
-            type        : 'separator'
-        },
-        bin_size : {
-            title   : 'Bin size',
-            info    : 'Provide the bin size for the histogram.',
-            type    : 'select',
-            init    : 1,
-            data        : [
-                {
-                    label   : '0.001',
-                    value   : '0.001'
-                },
-                {
-                    label   : '0.01',
-                    value   : '0.01'
-                },
-                {
-                    label   : '0.1',
-                    value   : '0.1'
-                },
-                {
-                    label   : '1',
-                    value   : '1'
-                },
-                {
-                    label   : '10',
-                    value   : '10'
-                },
-                {
-                    label   : '100',
-                    value   : '100'
-                },
-                {
-                    label   : '1000',
-                    value   : '1000'
-                }
-            ]
         }
     }
 });
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/static/library/jobs.js
--- a/config/plugins/visualizations/charts/static/library/jobs.js
+++ b/config/plugins/visualizations/charts/static/library/jobs.js
@@ -92,7 +92,7 @@
                 if (response && response.message && response.message.data && response.message.data.input) {
                     message = response.message.data.input + '.';
                 }
-                chart.state('failed', 'This visualization requires processing by the R-kit. Please make sure that it is installed. ' + message);
+                chart.state('failed', 'This visualization requires the R-kit. Please make sure it is installed. ' + message);
             }
         );
     },
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/static/library/ui-table-form.js
--- a/config/plugins/visualizations/charts/static/library/ui-table-form.js
+++ b/config/plugins/visualizations/charts/static/library/ui-table-form.js
@@ -9,7 +9,7 @@
     initialize: function(options) {
         // ui elements
         this.table_title = new Ui.Label({title: options.title});
-        this.table = new Table({content: options.content});
+        this.table = new Table.View({content: options.content});
         
         // create element
         var $view = $('<div/>');
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/static/library/ui-table.js
--- a/config/plugins/visualizations/charts/static/library/ui-table.js
+++ b/config/plugins/visualizations/charts/static/library/ui-table.js
@@ -1,8 +1,6 @@
-// dependencies
 define(['utils/utils'], function(Utils) {
 
-// return
-return Backbone.View.extend(
+var View = Backbone.View.extend(
 {
     // current row
     row: null,
@@ -202,4 +200,8 @@
     }
 });
 
+return {
+    View: View
+}
+
 });
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/static/models/chart.js
--- a/config/plugins/visualizations/charts/static/models/chart.js
+++ b/config/plugins/visualizations/charts/static/models/chart.js
@@ -58,25 +58,6 @@
     
     ready: function() {
         return (this.get('state') == 'ok') || (this.get('state') == 'failed');
-    },
-    
-    // save charts
-    save: function() {
-        /*/ create visualization
-        var vis = new Visualization({
-            type    : 'charts',
-            config  : this.attributes
-        });
-        
-        // copy attributes
-        //vis.set(this.attributes);
-        
-        // save visualization
-        vis.save()
-            .fail( function( xhr, status, message ){
-                console.error( xhr, status, message );
-                alert( 'Error loading data:\n' + xhr.responseText );
-            });*/
     }
 });
 
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/static/models/charts.js
--- a/config/plugins/visualizations/charts/static/models/charts.js
+++ b/config/plugins/visualizations/charts/static/models/charts.js
@@ -4,7 +4,28 @@
 // collection
 return Backbone.Collection.extend(
 {
-    model: Chart
+    model: Chart,
+    
+    // save charts
+    save: function() {
+        // create visualization
+        var vis = new Visualization({
+            type    : 'charts',
+            config  : {
+                charts : []
+            }
+        });
+        
+        // copy attributes
+        //vis.set(this.attributes);
+        
+        // save visualization
+        vis.save()
+            .fail( function( xhr, status, message ){
+                console.error( xhr, status, message );
+                alert( 'Error loading data:\n' + xhr.responseText );
+            });
+    }
 });
 
 });
\ No newline at end of file
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/static/views/chart.js
--- a/config/plugins/visualizations/charts/static/views/chart.js
+++ b/config/plugins/visualizations/charts/static/views/chart.js
@@ -29,14 +29,14 @@
         // table with chart types
         //
         var self = this;
-        this.table = new Table({
+        this.table = new Table.View({
             header : false,
             onconfirm : function(type) {
                 if (self.chart.groups.length > 0) {
                     // show modal
                     self.app.modal.show({
                         title   : 'Switching to another chart type?',
-                        body    : 'If you continue your settings and selections will be reseted.',
+                        body    : 'If you continue your settings and selections will be cleared.',
                         buttons : {
                             'Cancel'    : function() {
                                 // hide modal
@@ -99,17 +99,11 @@
                             tooltip : 'Draw Chart',
                             title   : 'Draw',
                             onclick : function() {
-                                // ensure that data group is available
-                                if (self.chart.groups.length == 0) {
-                                    self._addGroupModel();
-                                }
+                                // show charts
+                                self.app.go('charts_view');
                                 
                                 // save chart
                                 self._saveChart();
-                                
-                                // show charts
-                                self.hide();
-                                self.app.charts_view.$el.show();
                             }
                         }),
                 'back'  : new Ui.ButtonIcon({
@@ -117,8 +111,7 @@
                             tooltip : 'Return to Viewer',
                             title   : 'Return',
                             onclick : function() {
-                                self.hide();
-                                self.app.charts_view.$el.show();
+                                self.app.go('charts_view');
                             }
                         })
             }
@@ -215,6 +208,11 @@
     },
 
     // hide
+    show: function() {
+        this.$el.show();
+    },
+    
+    // hide
     hide: function() {
         $('.tooltip').hide();
         this.$el.hide();
@@ -297,6 +295,11 @@
             date        : Utils.time()
         });
         
+        // ensure that data group is available
+        if (this.chart.groups.length == 0) {
+            this._addGroupModel();
+        }
+        
         // create/get chart
         var current = this.app.charts.get(this.chart.id);
         if (!current) {
@@ -307,11 +310,11 @@
             current.copy(this.chart);
         }
         
-        // save
-        current.save();
-        
         // trigger redraw
         current.trigger('redraw', current);
+        
+        // save
+        this.app.charts.save();
     }
 });
 
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/static/views/charts.js
--- a/config/plugins/visualizations/charts/static/views/charts.js
+++ b/config/plugins/visualizations/charts/static/views/charts.js
@@ -14,18 +14,11 @@
         this.viewport_view = new ViewportView(app);
         
         // table
-        this.table = new Table({
+        this.table = new Table.View({
             content     : 'Add charts to this table.',
             ondblclick  : function(chart_id) {
-                // get chart
-                var chart = self.app.charts.get(chart_id);
-                self.app.chart.copy(chart);
-                
-                // hide this element
-                self.hide();
-                
-                // show chart view
-                self.app.chart_view.$el.show();
+                // attempt to load chart editor
+                self._showChartView(chart_id);
             },
             onchange : function(chart_id) {
                 // get chart
@@ -47,32 +40,46 @@
             height : 100,
             operations : {
                 'new'   : new Ui.ButtonIcon({
-                            icon : 'fa-magic',
-                            tooltip: 'Create a new Chart',
-                            title: 'New',
-                            onclick: function() {
-                                self.hide();
-                                self.app.chart.reset();
-                                self.app.chart_view.$el.show();
-                            }
-                        }),
+                    icon    : 'fa-magic',
+                    tooltip : 'Create a new Chart',
+                    title   : 'New',
+                    onclick : function() {
+                        self.app.go('chart_view');
+                        self.app.chart.reset();
+                    }
+                }),
+                'edit'  : new Ui.ButtonIcon({
+                    icon    : 'fa-gear',
+                    tooltip : 'Customize this Chart',
+                    title   : 'Customize',
+                    onclick : function() {
+                        // check if element has been selected
+                        var chart_id = self.table.value();
+                        if (!chart_id) {
+                            return;
+                        }
+                        
+                        // attempt to load chart editor
+                        self._showChartView(chart_id);
+                    }
+                }),
                 'delete' : new Ui.ButtonIcon({
-                    icon : 'fa-trash-o',
-                    tooltip: 'Delete this Chart',
-                    title: 'Delete',
-                    onclick: function() {
+                    icon    : 'fa-trash-o',
+                    tooltip : 'Delete this Chart',
+                    title   : 'Delete',
+                    onclick : function() {
                             
-                            // check if element has been selected
-                            var chart_id = self.table.value();
-                            if (!chart_id) {
-                                return;
-                            }
-                    
-                            // title
-                            var chart = self.app.charts.get(chart_id);
-                    
-                            // show modal
-                            self.app.modal.show({
+                        // check if element has been selected
+                        var chart_id = self.table.value();
+                        if (!chart_id) {
+                            return;
+                        }
+                
+                        // title
+                        var chart = self.app.charts.get(chart_id);
+                
+                        // show modal
+                        self.app.modal.show({
                             title   : 'Are you sure?',
                             body    : 'The selected chart "' + chart.get('title') + '" will be irreversibly deleted.',
                             buttons : {
@@ -116,7 +123,12 @@
             self._changeChart(chart);
         });
     },
-    
+
+    // show
+    show: function() {
+        this.$el.show();
+    },
+        
     // hide
     hide: function() {
         $('.tooltip').hide();
@@ -147,11 +159,13 @@
         // remove from to table
         this.table.remove(chart.id);
         
+        // save
+        this.app.charts.save();
+        
         // check if table is empty
         if (this.table.size() == 0) {
-            this.hide();
+            this.app.go('chart_view');
             this.app.chart.reset();
-            this.app.chart_view.$el.show();
         } else {
             // select available chart
             this.table.value(this.app.charts.last().id);
@@ -167,6 +181,36 @@
             // select available chart
             this.table.value(chart.id);
         }
+    },
+    
+    // show chart editor
+    _showChartView: function(chart_id) {
+        // get chart
+        var chart = this.app.charts.get(chart_id);
+        if (chart.ready()) {
+            // show chart view
+            this.app.go('chart_view');
+                    
+            // load chart into view
+            this.app.chart.copy(chart);
+        } else {
+            // show modal
+            var self = this;
+            this.app.modal.show({
+                title   : 'Please wait!',
+                body    : 'The selected chart "' + chart.get('title') + '" is currently being processed. Please wait...',
+                buttons : {
+                    'Close'     : function() {self.app.modal.hide();},
+                    'Retry'     : function() {
+                        // hide modal
+                        self.app.modal.hide();
+                        
+                        // retry
+                        self._showChartView(chart_id);
+                    }
+                }
+            });
+        }
     }
 });
 
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/static/views/group.js
--- a/config/plugins/visualizations/charts/static/views/group.js
+++ b/config/plugins/visualizations/charts/static/views/group.js
@@ -29,7 +29,7 @@
                 self.group.set('key', self.group_key.value());
             }
         });
-        this.table = new Table({content: 'No data column.'});
+        this.table = new Table.View({content: 'No data column.'});
         
         // create element
         var $view = $('<div/>');
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/static/views/viewport.js
--- a/config/plugins/visualizations/charts/static/views/viewport.js
+++ b/config/plugins/visualizations/charts/static/views/viewport.js
@@ -27,14 +27,7 @@
         this.portlet = new Portlet.View({
             title       : 'title',
             height      : this.options.height,
-            overflow    : 'hidden',
-            operations  : {
-                'edit'  : new Ui.ButtonIcon({
-                    icon    : 'fa-gear',
-                    tooltip : 'Customize Chart',
-                    title   : 'Customize'
-                })
-            }
+            overflow    : 'hidden'
         });
         
         // set this element
@@ -80,15 +73,7 @@
                 
             // update portlet
             this.portlet.title(chart.get('title'));
-            this.portlet.setOperation('edit', function() {
-                // get chart
-                self.app.chart.copy(chart);
-                
-                // show edit
-                self.app.charts_view.hide();
-                self.app.chart_view.$el.show();
-            });
-        
+            
             // show selected chart
             item.$el.show();
         
@@ -124,7 +109,7 @@
             self.app.log('viewport:_refreshChart()', 'Invalid attempt to refresh chart before completion.');
             return;
         }
-
+       
         // backup chart details
         var chart_id = chart.id;
     
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a config/plugins/visualizations/charts/templates/charts.mako
--- a/config/plugins/visualizations/charts/templates/charts.mako
+++ b/config/plugins/visualizations/charts/templates/charts.mako
@@ -15,8 +15,7 @@
                 'libs/require',
                 'libs/underscore',
                 'libs/backbone/backbone',
-                'libs/d3',
-                'mvc/base-mvc')}
+                'libs/d3')}
 
         ## css
         ${h.css( 'base' )}
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a static/scripts/mvc/ui/ui-portlet.js
--- a/static/scripts/mvc/ui/ui-portlet.js
+++ b/static/scripts/mvc/ui/ui-portlet.js
@@ -141,31 +141,31 @@
     
     // fill template
     _template: function(options) {
-        var tmpl =  '<div class="toolForm">';
+        var tmpl =  '<div class="toolForm portlet-view no-highlight">';
         
         if (options.title || options.icon) {
-            tmpl +=     '<div id="title" class="toolFormTitle" style="overflow: hidden;">' +
-                            '<div id="operations" style="float: right;"></div>' +
+            tmpl +=     '<div id="title" class="toolFormTitle portlet-title">' +
+                            '<div id="operations" class="portlet-operations"/>' +
                             '<div style="overflow: hidden;">';
                             
             if (options.icon)
-                tmpl +=         '<i style="padding-top: 3px; float: left; font-size: 1.2em" class="icon fa ' + options.icon + '"> </i>';
+                tmpl +=         '<div class="portlet-title-icon fa ' + options.icon + '"> </div>';
         
-            tmpl +=             '<div id="title-text" style="padding-top: 2px; float: left;">' + options.title + '</div>';
+            tmpl +=             '<div id="title-text" class="portlet-title-text">' + options.title + '</div>';
             
             tmpl +=         '</div>' +
                         '</div>';
         }
-        tmpl +=         '<div id="body" class="toolFormBody">';
+        tmpl +=         '<div id="body" class="toolFormBody portlet-body">';
         
         if (options.placement == 'top') {
-            tmpl +=         '<div id="buttons" class="buttons" style="height: 50px; padding: 10px;"></div>';
+            tmpl +=         '<div id="buttons" class="portlet-buttons"/>';
         }
         
-        tmpl +=             '<div id="content" class="content" style="height: inherit; padding: 10px;"></div>';
+        tmpl +=             '<div id="content" class="portlet-content"/>';
         
         if (options.placement == 'bottom') {
-            tmpl +=         '<div id="buttons" class="buttons" style="height: 50px; padding: 10px;"></div>';
+            tmpl +=         '<div id="buttons" class="portlet-buttons"/>';
         }
         
         tmpl +=         '</div>' +
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a static/scripts/packed/mvc/ui/ui-portlet.js
--- a/static/scripts/packed/mvc/ui/ui-portlet.js
+++ b/static/scripts/packed/mvc/ui/ui-portlet.js
@@ -1,1 +1,1 @@
-define(["utils/utils"],function(a){var b=Backbone.View.extend({visible:false,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(d){this.options=a.merge(d,this.optionsDefault);this.setElement(this._template(this.options));this.$content=this.$el.find("#content");this.$title=this.$el.find("#title-text");if(this.options.height){this.$el.find("#body").css("height",this.options.height);this.$el.find("#content").css("overflow",this.options.overflow)}this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var c=this;$.each(this.options.buttons,function(e,f){f.$el.prop("id",e);c.$buttons.append(f.$el)})}else{this.$buttons.remove()}this.$operations=$(this.el).find("#operations");if(this.options.operations){var c=this;$.each(this.options.operations,function(e,f){f.$el.prop("id",e);c.$operations.append(f.$el)})}if(this.options.body){this.append(this.options.body)}},append:function(c){this.$content.append(a.wrap(c))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast");this.visible=true},hide:function(){this.$el.fadeOut("fast");this.visible=false},enableButton:function(c){this.$buttons.find("#"+c).prop("disabled",false)},disableButton:function(c){this.$buttons.find("#"+c).prop("disabled",true)},hideOperation:function(c){this.$operations.find("#"+c).hide()},showOperation:function(c){this.$operations.find("#"+c).show()},setOperation:function(e,d){var c=this.$operations.find("#"+e);c.off("click");c.on("click",d)},title:function(d){var c=this.$title;if(d){c.html(d)}return c.html()},_template:function(d){var c='<div class="toolForm">';if(d.title||d.icon){c+='<div id="title" class="toolFormTitle" style="overflow: hidden;"><div id="operations" style="float: right;"></div><div style="overflow: hidden;">';if(d.icon){c+='<i style="padding-top: 3px; float: left; font-size: 1.2em" class="icon fa '+d.icon+'"> </i>'}c+='<div id="title-text" style="padding-top: 2px; float: left;">'+d.title+"</div>";c+="</div></div>"}c+='<div id="body" class="toolFormBody">';if(d.placement=="top"){c+='<div id="buttons" class="buttons" style="height: 50px; padding: 10px;"></div>'}c+='<div id="content" class="content" style="height: inherit; padding: 10px;"></div>';if(d.placement=="bottom"){c+='<div id="buttons" class="buttons" style="height: 50px; padding: 10px;"></div>'}c+="</div></div>";return c}});return{View:b}});
\ No newline at end of file
+define(["utils/utils"],function(a){var b=Backbone.View.extend({visible:false,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(d){this.options=a.merge(d,this.optionsDefault);this.setElement(this._template(this.options));this.$content=this.$el.find("#content");this.$title=this.$el.find("#title-text");if(this.options.height){this.$el.find("#body").css("height",this.options.height);this.$el.find("#content").css("overflow",this.options.overflow)}this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var c=this;$.each(this.options.buttons,function(e,f){f.$el.prop("id",e);c.$buttons.append(f.$el)})}else{this.$buttons.remove()}this.$operations=$(this.el).find("#operations");if(this.options.operations){var c=this;$.each(this.options.operations,function(e,f){f.$el.prop("id",e);c.$operations.append(f.$el)})}if(this.options.body){this.append(this.options.body)}},append:function(c){this.$content.append(a.wrap(c))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast");this.visible=true},hide:function(){this.$el.fadeOut("fast");this.visible=false},enableButton:function(c){this.$buttons.find("#"+c).prop("disabled",false)},disableButton:function(c){this.$buttons.find("#"+c).prop("disabled",true)},hideOperation:function(c){this.$operations.find("#"+c).hide()},showOperation:function(c){this.$operations.find("#"+c).show()},setOperation:function(e,d){var c=this.$operations.find("#"+e);c.off("click");c.on("click",d)},title:function(d){var c=this.$title;if(d){c.html(d)}return c.html()},_template:function(d){var c='<div class="toolForm portlet-view no-highlight">';if(d.title||d.icon){c+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">';if(d.icon){c+='<div class="portlet-title-icon fa '+d.icon+'"> </div>'}c+='<div id="title-text" class="portlet-title-text">'+d.title+"</div>";c+="</div></div>"}c+='<div id="body" class="toolFormBody portlet-body">';if(d.placement=="top"){c+='<div id="buttons" class="portlet-buttons"/>'}c+='<div id="content" class="portlet-content"/>';if(d.placement=="bottom"){c+='<div id="buttons" class="portlet-buttons"/>'}c+="</div></div>";return c}});return{View:b}});
\ No newline at end of file
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a static/style/blue/base.css
--- a/static/style/blue/base.css
+++ b/static/style/blue/base.css
@@ -1278,6 +1278,13 @@
 .upload-ftp .upload-ftp-help{margin-bottom:10px}
 .upload-ftp .upload-ftp-warning{text-align:center;margin-top:20px}
 .upload-settings .upload-settings-cover{position:absolute;width:100%;height:100%;top:0px;left:0px;background:#fff;opacity:0.4;cursor:no-drop}
+.no-highlight{-webkit-user-select:none;-moz-user-select:none;-khtml-user-select:none;-ms-user-select:none;}
+.portlet-view{min-width:300px}.portlet-view .portlet-title-icon{float:left;font-size:1.2em;padding-top:3px}
+.portlet-view .portlet-title{overflow:hidden}
+.portlet-view .portlet-title-text{float:left;padding-top:1px}
+.portlet-view .portlet-operations{float:right;cursor:pointer}
+.portlet-view .portlet-buttons{height:50px;padding:10px}
+.portlet-view .portlet-content{height:inherit;padding:10px}
 .popover-view{max-width:700px;display:none}.popover-view .popover-close{position:absolute;right:10px;top:7px;font-size:1.2em;cursor:pointer}
 .popover-view .popover-title{padding:4px 10px}
 .styled-select{position:relative;height:27px;overflow:hidden;border:1px solid #bfbfbf;-moz-border-radius:3px;border-radius:3px}.styled-select .button{position:relative;width:25px;height:100%;float:right;border-left:1px solid #bfbfbf;padding-left:9px;padding-top:4px;background:#f2f2f2}
diff -r aa1eee2bd24a4ba449449f16659701eb7481f301 -r dec159841d670560582aadc1327bec0673f7003a static/style/src/less/ui.less
--- a/static/style/src/less/ui.less
+++ b/static/style/src/less/ui.less
@@ -1,3 +1,44 @@
+.no-highlight {
+    -webkit-user-select: none; /* webkit (safari, chrome) browsers */
+    -moz-user-select: none; /* mozilla browsers */
+    -khtml-user-select: none; /* webkit (konqueror) browsers */
+    -ms-user-select: none; /* IE10+ */
+}
+
+.portlet-view {
+    min-width: 300px;
+
+    .portlet-title-icon {
+        float: left;
+        font-size: 1.2em;
+        padding-top: 3px;
+    }
+    
+    .portlet-title {
+        overflow: hidden;
+    }
+
+    .portlet-title-text {
+        float: left;
+        padding-top: 1px;
+    }
+    
+    .portlet-operations {
+        float: right;
+        cursor: pointer;
+    }
+    
+    .portlet-buttons {
+        height: 50px;
+        padding: 10px;
+    }
+    
+    .portlet-content {
+        height: inherit;
+        padding: 10px;
+    }
+}
+
 .popover-view {
     max-width: 700px;
     display: none;
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            commit/galaxy-central: martenson: libraries - removal of id-encoding related bug in API commited in f7ebd14c2f9b260cdb6627e4abfd5c03f14c4900 and identified by jmchilton in https://bitbucket.org/galaxy/galaxy-central/commits/f7ebd14c2f9b260cdb6627e4abfd5c03f14c4900#comment-825140
                        
                        
by commits-noreply@bitbucket.org 20 Mar '14
                    by commits-noreply@bitbucket.org 20 Mar '14
20 Mar '14
                    
                        1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/aa1eee2bd24a/
Changeset:   aa1eee2bd24a
User:        martenson
Date:        2014-03-21 00:26:45
Summary:     libraries - removal of id-encoding related bug in API commited in f7ebd14c2f9b260cdb6627e4abfd5c03f14c4900 and identified by jmchilton in https://bitbucket.org/galaxy/galaxy-central/commits/f7ebd14c2f9b260cdb6627e…
Affected #:  2 files
diff -r 29a9d6d904f3506f141253e2b1e97cf1aa55a081 -r aa1eee2bd24a4ba449449f16659701eb7481f301 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -2078,8 +2078,8 @@
          # This needs to be a list
         return [ ld for ld in self.datasets if ld.library_dataset_dataset_association and not ld.library_dataset_dataset_association.dataset.deleted ]
 
-    def to_dict( self, view='collection' ):
-        rval = super( LibraryFolder, self ).to_dict( view=view )
+    def to_dict( self, view='collection', value_mapper=None ):
+        rval = super( LibraryFolder, self ).to_dict( view=view, value_mapper=value_mapper  )
         info_association, inherited = self.get_info_association()
         if info_association:
             if inherited:
diff -r 29a9d6d904f3506f141253e2b1e97cf1aa55a081 -r aa1eee2bd24a4ba449449f16659701eb7481f301 lib/galaxy/webapps/galaxy/api/library_contents.py
--- a/lib/galaxy/webapps/galaxy/api/library_contents.py
+++ b/lib/galaxy/webapps/galaxy/api/library_contents.py
@@ -123,11 +123,18 @@
         class_name, content_id = self.__decode_library_content_id( trans, id )
         if class_name == 'LibraryFolder':
             content = self.get_library_folder( trans, content_id, check_ownership=False, check_accessible=True )
+            rval = content.to_dict( view='element', value_mapper={ 'id' : trans.security.encode_id } )
+            rval[ 'id' ] = 'F' + str( rval[ 'id' ] )
+            rval[ 'parent_id' ] = 'F' + str( trans.security.encode_id( rval[ 'parent_id' ] ) )
+            rval[ 'parent_library_id' ] = trans.security.encode_id( rval[ 'parent_library_id' ] )
         else:
             content = self.get_library_dataset( trans, content_id, check_ownership=False, check_accessible=True )
-
-        return content.to_dict( view='element', value_mapper={ 'id' : trans.security.encode_id } ) 
-        # return self.encode_all_ids( trans, content.to_dict( view='element' ) )
+            rval = content.to_dict( view='element')
+            rval[ 'id' ] = trans.security.encode_id( rval[ 'id' ] )
+            rval[ 'ldda_id' ] = trans.security.encode_id( rval[ 'ldda_id' ] )
+            rval[ 'folder_id' ] = 'F' + str( trans.security.encode_id( rval[ 'folder_id' ] ) )
+            rval[ 'parent_library_id' ] = trans.security.encode_id( rval[ 'parent_library_id' ] )
+        return rval
 
     @web.expose_api
     def create( self, trans, library_id, payload, **kwd ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            commit/galaxy-central: martenson: biostar: moved icon tooltips placement to the bottom for readability
                        
                        
by commits-noreply@bitbucket.org 20 Mar '14
                    by commits-noreply@bitbucket.org 20 Mar '14
20 Mar '14
                    
                        1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/29a9d6d904f3/
Changeset:   29a9d6d904f3
User:        martenson
Date:        2014-03-20 22:30:47
Summary:     biostar: moved icon tooltips placement to the bottom for readability
Affected #:  1 file
diff -r 86ea88b98bb7b2f2eb1fad554307d3e5d055d9ce -r 29a9d6d904f3506f141253e2b1e97cf1aa55a081 templates/webapps/galaxy/tool_form.mako
--- a/templates/webapps/galaxy/tool_form.mako
+++ b/templates/webapps/galaxy/tool_form.mako
@@ -327,9 +327,9 @@
                 Help from Biostar
                 <div class="icon-btn-group"><a href="${h.url_for( controller='biostar', action='biostar_tool_tag_redirect', tool_id=tool.id )}"
-                        target="_blank" class="icon-btn" title="Search for this tool"><span class="fa fa-search"></span></a>
+                        target="_blank" class="icon-btn" title="Search for this tool" data-toggle="tooltip" data-placement="bottom"><span class="fa fa-search"></span></a><a href="${h.url_for( controller='biostar', action='biostar_tool_question_redirect', tool_id=tool.id )}"
-                        target="_blank" class="icon-btn" title="Ask a question about this tool"><span class="fa fa-question-circle"></a>
+                        target="_blank" class="icon-btn" title="Ask a question about this tool" data-toggle="tooltip" data-placement="bottom"><span class="fa fa-question-circle"></a></div></span>
         %endif
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                     
                        
                    
                        
                            
                                
                            
                            commit/galaxy-central: dan: Refactor Biostar interaction code. Add the ability to search for previously asked questions about a tool from the tool form. Allow logging out of biostar.
                        
                        
by commits-noreply@bitbucket.org 20 Mar '14
                    by commits-noreply@bitbucket.org 20 Mar '14
20 Mar '14
                    
                        1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/86ea88b98bb7/
Changeset:   86ea88b98bb7
User:        dan
Date:        2014-03-20 22:23:41
Summary:     Refactor Biostar interaction code. Add the ability to search for previously asked questions about a tool from the tool form. Allow logging out of biostar.
Affected #:  5 files
diff -r f830918df15be11380a4628c9c3aad860547e092 -r 86ea88b98bb7b2f2eb1fad554307d3e5d055d9ce lib/galaxy/util/biostar.py
--- /dev/null
+++ b/lib/galaxy/util/biostar.py
@@ -0,0 +1,121 @@
+"""
+Support for integration with the Biostar application
+"""
+
+import hmac
+import urlparse
+import re
+from unicodedata import normalize
+from galaxy.web.base.controller import url_for
+
+_punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?(a)\[\\\]^_`{|},.]+')
+
+DEFAULT_GALAXY_TAG = 'galaxy'
+
+BIOSTAR_ACTIONS = {
+    None: { 'url': lambda x: '', 'uses_payload': False },
+    'new_post': { 'url': lambda x: 'p/new/post/', 'uses_payload': True },
+    'show_tags': { 'url': lambda x: 't/%s/' % ( "+".join( ( x.get( 'tag_val' ) or DEFAULT_GALAXY_TAG ).split( ',' ) ) ), 'uses_payload':False },
+    'log_out': { 'url': lambda x: 'site/logout/', 'uses_payload': False }
+}
+
+DEFAULT_BIOSTAR_COOKIE_AGE = 1
+
+def biostar_enabled( app ):
+    return bool( app.config.biostar_url )
+
+# Slugifying from Armin Ronacher (http://flask.pocoo.org/snippets/5/)
+def slugify(text, delim=u'-'):
+    """Generates an slightly worse ASCII-only slug."""
+    result = []
+    for word in _punct_re.split(text.lower()):
+        word = normalize('NFKD', word).encode('ascii', 'ignore')
+        if word:
+            result.append(word)
+    return unicode(delim.join(result))
+
+# Default values for new posts to Biostar
+DEFAULT_PAYLOAD = {
+    'title': '',
+    'tag_val': DEFAULT_GALAXY_TAG,
+    'content': '',
+}
+
+def get_biostar_url( app, payload=None, biostar_action=None ):
+    # Ensure biostar integration is enabled
+    if not biostar_enabled( app ):
+        raise Exception( "Biostar integration is not enabled" )
+    if biostar_action not in BIOSTAR_ACTIONS:
+        raise Exception( "Invalid action specified (%s)." % ( biostar_action ) )
+    biostar_action = BIOSTAR_ACTIONS[ biostar_action ]
+    # Start building up the payload
+    payload = payload or {}
+    payload = dict( DEFAULT_PAYLOAD, **payload )
+    #generate url, can parse payload info
+    url = str( urlparse.urljoin( app.config.biostar_url, biostar_action.get( 'url' )( payload ) ) )
+    if not biostar_action.get( 'uses_payload' ):
+        payload = {}
+    url = url_for( url, **payload )
+    return url
+
+def tag_for_tool( tool ):
+    """
+    Generate a reasonable biostar tag for a tool.
+    """
+    #Biostar can now handle tags with spaces, do we want to generate tags differently now?
+    return slugify( unicode( tool.name ), delim='-' )
+
+def populate_tag_payload( payload=None, tool=None ):
+    if payload is None:
+        payload = {}
+    tag_val = [ DEFAULT_GALAXY_TAG ]
+    if tool:
+        tag_val.append( tag_for_tool( tool ) )
+    payload[ 'tag_val' ] =  ','.join( tag_val )
+    return payload
+
+def populate_tool_payload( payload=None, tool=None ):
+    payload = populate_tag_payload( payload=payload, tool=tool )
+    payload[ 'title' ] = 'Need help with "%s" tool' % ( tool.name )
+    payload[ 'content' ] = '<br /><hr /><p>Tool name: %s</br>Tool version: %s</br>Tool ID: %s</p>' % ( tool.name, tool.version, tool.id )
+    return payload
+
+def determine_cookie_domain( galaxy_hostname, biostar_hostname ):
+    if galaxy_hostname == biostar_hostname:
+        return galaxy_hostname
+    
+    sub_biostar_hostname = biostar_hostname.split( '.', 1 )[-1]
+    if sub_biostar_hostname == galaxy_hostname:
+        return galaxy_hostname
+    
+    sub_galaxy_hostname = galaxy_hostname.split( '.', 1 )[-1]
+    if sub_biostar_hostname == sub_galaxy_hostname:
+        return sub_galaxy_hostname
+    
+    return galaxy_hostname
+
+def create_cookie( trans, key_name, key, email, age=DEFAULT_BIOSTAR_COOKIE_AGE ):
+    digest = hmac.new( key, email ).hexdigest()
+    value = "%s:%s" % (email, digest)
+    trans.set_cookie( value, name=key_name, path='/', age=age, version='1' )
+    #We need to explicitly set the domain here, in order to allow for biostar in a subdomain to work
+    galaxy_hostname = urlparse.urlsplit( url_for( '/', qualified=True ) ).hostname
+    biostar_hostname = urlparse.urlsplit( trans.app.config.biostar_url ).hostname
+    trans.response.cookies[ key_name ][ 'domain' ] = determine_cookie_domain( galaxy_hostname, biostar_hostname )
+
+def delete_cookie( trans, key_name ):
+    #Set expiration of Cookie to time in past, to cause browser to delete
+    if key_name in trans.request.cookies:
+        create_cookie( trans, trans.app.config.biostar_key_name, '', '', age=-90 )
+
+def biostar_logged_in( trans ):
+    if biostar_enabled( trans.app ):
+        if trans.app.config.biostar_key_name in trans.request.cookies:
+            return True
+    return False
+
+def biostar_logout( trans ):
+    if biostar_enabled( trans.app ):
+        delete_cookie( trans, trans.app.config.biostar_key_name )
+        return get_biostar_url( trans.app, biostar_action='log_out' )
+    return None
diff -r f830918df15be11380a4628c9c3aad860547e092 -r 86ea88b98bb7b2f2eb1fad554307d3e5d055d9ce lib/galaxy/webapps/galaxy/controllers/biostar.py
--- a/lib/galaxy/webapps/galaxy/controllers/biostar.py
+++ b/lib/galaxy/webapps/galaxy/controllers/biostar.py
@@ -1,84 +1,10 @@
 """
-Support for integration with the Biostar Q&A application
+Controller for integration with the Biostar application
 """
 
 from galaxy.web.base.controller import BaseUIController, url_for, error, web
+from galaxy.util import biostar
 
-import base64
-from galaxy.util import json
-import hmac
-import urlparse
-
-# Slugifying from Armin Ronacher (http://flask.pocoo.org/snippets/5/)
-
-import re
-from unicodedata import normalize
-
-_punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?(a)\[\\\]^_`{|},.]+')
-
-BIOSTAR_ACTIONS = {
-    None: '',
-    'new': 'p/new/post/',
-    'show_tag_galaxy': 't/galaxy/'
-}
-
-
-def slugify(text, delim=u'-'):
-    """Generates an slightly worse ASCII-only slug."""
-    result = []
-    for word in _punct_re.split(text.lower()):
-        word = normalize('NFKD', word).encode('ascii', 'ignore')
-        if word:
-            result.append(word)
-    return unicode(delim.join(result))
-
-
-# Biostar requires all keys to be present, so we start with a template
-DEFAULT_PAYLOAD = {
-    'title': '',
-    'tag_val': 'galaxy',
-    'content': '',
-}
-
-
-def encode_data( key, data ):
-    """
-    Encode data to send a question to Biostar
-    """
-    text = json.to_json_string(data)
-    text = base64.urlsafe_b64encode(text)
-    digest = hmac.new(key, text).hexdigest()
-    return text, digest
-
-
-def tag_for_tool( tool ):
-    """
-    Generate a reasonable biostar tag for a tool.
-    """
-    return slugify( unicode( tool.name ) )
-
-def determine_cookie_domain( galaxy_hostname, biostar_hostname ):
-    if galaxy_hostname == biostar_hostname:
-        return galaxy_hostname
-    
-    sub_biostar_hostname = biostar_hostname.split( '.', 1 )[-1]
-    if sub_biostar_hostname == galaxy_hostname:
-        return galaxy_hostname
-    
-    sub_galaxy_hostname = galaxy_hostname.split( '.', 1 )[-1]
-    if sub_biostar_hostname == sub_galaxy_hostname:
-        return sub_galaxy_hostname
-    
-    return galaxy_hostname
-
-def create_cookie( trans, key_name, key, email ):
-    digest = hmac.new( key, email ).hexdigest()
-    value = "%s:%s" % (email, digest)
-    trans.set_cookie( value, name=key_name, path='/', age=90, version='1' )
-    #We need to explicitly set the domain here, in order to allow for biostar in a subdomain to work
-    galaxy_hostname = urlparse.urlsplit( url_for( '/', qualified=True ) ).hostname
-    biostar_hostname = urlparse.urlsplit( trans.app.config.biostar_url ).hostname
-    trans.response.cookies[ key_name ][ 'domain' ] = determine_cookie_domain( galaxy_hostname, biostar_hostname )
 
 class BiostarController( BaseUIController ):
     """
@@ -89,24 +15,35 @@
     def biostar_redirect( self, trans, payload=None, biostar_action=None ):
         """
         Generate a redirect to a Biostar site using external authentication to
-        pass Galaxy user information and information about a specific tool.
+        pass Galaxy user information and optional information about a specific tool.
         """
-        # Ensure biostar integration is enabled
-        if not trans.app.config.biostar_url:
-            return error( "Biostar integration is not enabled" )
-        if biostar_action not in BIOSTAR_ACTIONS:
-            return error( "Invalid action specified (%s)." % ( biostar_action ) )
-        
-        # Start building up the payload
-        payload = payload or {}
-        payload = dict( DEFAULT_PAYLOAD, **payload )
-        # Do the best we can of providing user information for the payload
+        try:
+            url = biostar.get_biostar_url( trans.app, payload=payload, biostar_action=biostar_action )
+        except Exception, e:
+            return error( str( e ) )
+        # Only create/log in biostar user if is registered Galaxy user
         if trans.user:
-            email = trans.user.email
-        else:
-            email = "anon-%s" % ( trans.security.encode_id( trans.galaxy_session.id ) )
-        create_cookie( trans, trans.app.config.biostar_key_name, trans.app.config.biostar_key, email )
-        return trans.response.send_redirect( url_for( urlparse.urljoin( trans.app.config.biostar_url, BIOSTAR_ACTIONS[ biostar_action ] ), **payload ) )
+            biostar.create_cookie( trans, trans.app.config.biostar_key_name, trans.app.config.biostar_key, trans.user.email )
+        return trans.response.send_redirect( url )
+
+    @web.expose
+    def biostar_tool_tag_redirect( self, trans, tool_id=None ):
+        """
+        Generate a redirect to a Biostar site using tag for tool.
+        """
+        # tool_id is required
+        if tool_id is None:
+            return error( "No tool_id provided" )
+        # Load the tool
+        tool_version_select_field, tools, tool = \
+            self.app.toolbox.get_tool_components( tool_id, tool_version=None, get_loaded_tools_by_lineage=False, set_selected=True )
+        # No matching tool, unlikely
+        if not tool:
+            return error( "No tool found matching '%s'" % tool_id )
+        # Tool specific information for payload
+        payload = biostar.populate_tag_payload( tool=tool )
+        # Pass on to standard redirect method
+        return self.biostar_redirect( trans, payload=payload, biostar_action='show_tags' )
 
     @web.expose
     def biostar_question_redirect( self, trans, payload=None ):
@@ -114,8 +51,8 @@
         Generate a redirect to a Biostar site using external authentication to
         pass Galaxy user information and information about a specific tool.
         """
-        payload = payload or {}
-        return self.biostar_redirect( trans, payload=payload, biostar_action='new' )
+        # Pass on to standard redirect method
+        return self.biostar_redirect( trans, payload=payload, biostar_action='new_post' )
 
     @web.expose
     def biostar_tool_question_redirect( self, trans, tool_id=None ):
@@ -133,8 +70,19 @@
         if not tool:
             return error( "No tool found matching '%s'" % tool_id )
         # Tool specific information for payload
-        payload = { 'title':'Need help with "%s" tool' % ( tool.name ),
-                    'content': '<br /><hr /><p>Tool name: %s</br>Tool version: %s</br>Tool ID: %s</p>' % ( tool.name, tool.version, tool.id ),
-                    'tag_val': ','.join( [ 'galaxy', tag_for_tool( tool ) ] ) }
+        payload = biostar.populate_tool_payload( tool=tool )
         # Pass on to regular question method
         return self.biostar_question_redirect( trans, payload )
+
+    @web.expose
+    def biostar_logout( self, trans ):
+        """
+        Log out of biostar
+        """
+        try:
+            url = biostar.biostar_log_out( trans )
+        except Exception, e:
+            return error( str( e ) )
+        if url:
+            return trans.response.send_redirect( url )
+        return error( "Could not determine Biostar logout URL." )
diff -r f830918df15be11380a4628c9c3aad860547e092 -r 86ea88b98bb7b2f2eb1fad554307d3e5d055d9ce lib/galaxy/webapps/galaxy/controllers/user.py
--- a/lib/galaxy/webapps/galaxy/controllers/user.py
+++ b/lib/galaxy/webapps/galaxy/controllers/user.py
@@ -30,7 +30,7 @@
 from galaxy.web.form_builder import  build_select_field
 from galaxy.web.framework.helpers import time_ago, grids
 from datetime import datetime, timedelta
-from galaxy.util import hash_util
+from galaxy.util import hash_util, biostar
 
 log = logging.getLogger( __name__ )
 
@@ -600,6 +600,11 @@
         trans.handle_user_logout( logout_all=logout_all )
         message = 'You have been logged out.<br>You can log in again, <a target="_top" href="%s">go back to the page you were visiting</a> or <a target="_top" href="%s">go to the home page</a>.' % \
             ( trans.request.referer, url_for( '/' ) )
+        if biostar.biostar_logged_in( trans ):
+            biostar_url = biostar.biostar_logout( trans )
+            if biostar_url:
+                #TODO: It would be better if we automatically logged this user out of biostar
+                message += '<br>To logout of Biostar, please click <a href="%s" target="_blank">here</a>.' % ( biostar_url )
         return trans.fill_template( '/user/logout.mako',
                                     refresh_frames=refresh_frames,
                                     message=message,
diff -r f830918df15be11380a4628c9c3aad860547e092 -r 86ea88b98bb7b2f2eb1fad554307d3e5d055d9ce templates/webapps/galaxy/galaxy.masthead.mako
--- a/templates/webapps/galaxy/galaxy.masthead.mako
+++ b/templates/webapps/galaxy/galaxy.masthead.mako
@@ -40,7 +40,7 @@
             'enable_cloud_launch'       : app.config.get_bool('enable_cloud_launch', False),
             'lims_doc_url'              : app.config.get("lims_doc_url", "http://main.g2.bx.psu.edu/u/rkchak/p/sts"),
             'biostar_url'               : app.config.biostar_url,
-            'biostar_url_redirect'      : h.url_for( controller='biostar', action='biostar_redirect', biostar_action='show_tag_galaxy', qualified=True ),
+            'biostar_url_redirect'      : h.url_for( controller='biostar', action='biostar_redirect', biostar_action='show_tags', qualified=True ),
             'support_url'               : app.config.get("support_url", "http://wiki.galaxyproject.org/Support"),
             'search_url'                : app.config.get("search_url", "http://galaxyproject.org/search/usegalaxy/"),
             'mailing_lists'             : app.config.get("mailing_lists", "http://wiki.galaxyproject.org/MailingLists"),
diff -r f830918df15be11380a4628c9c3aad860547e092 -r 86ea88b98bb7b2f2eb1fad554307d3e5d055d9ce templates/webapps/galaxy/tool_form.mako
--- a/templates/webapps/galaxy/tool_form.mako
+++ b/templates/webapps/galaxy/tool_form.mako
@@ -324,8 +324,13 @@
         %if trans.app.config.biostar_url:
             ## BioStar links
             <span class="pull-right">
-                <span class="fa fa-question-circle"> </span><a href="${h.url_for( controller='biostar', action='biostar_tool_question_redirect', tool_id=tool.id )}"
-                   target="_blank">Ask a question about this tool</a> <span class="fa fa-external-link"></span>
+                Help from Biostar
+                <div class="icon-btn-group">
+                    <a href="${h.url_for( controller='biostar', action='biostar_tool_tag_redirect', tool_id=tool.id )}"
+                        target="_blank" class="icon-btn" title="Search for this tool"><span class="fa fa-search"></span></a>
+                    <a href="${h.url_for( controller='biostar', action='biostar_tool_question_redirect', tool_id=tool.id )}"
+                        target="_blank" class="icon-btn" title="Ask a question about this tool"><span class="fa fa-question-circle"></a>
+                </div></span>
         %endif
         </div>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/5996738d71ac/
Changeset:   5996738d71ac
User:        jmchilton
Date:        2014-03-20 22:12:52
Summary:     Drop unit incorrect unit tests added in 410a13e and 01933aa.
Workflow run template was causing these methods to be called wrong (and has been for a LONG time), this in turn caused me to misunderstand what the spec for how other_values in tool parameters should operate when writing the tests.
The real underlying bug should be fixed with 55cf8bb.
Affected #:  1 file
diff -r 1285d07792b31e6c1ce9d66f559afc3f49a054a8 -r 5996738d71ace34df5bee3452b8f2cdeda3e230f test/unit/tools/test_select_parameters.py
--- a/test/unit/tools/test_select_parameters.py
+++ b/test/unit/tools/test_select_parameters.py
@@ -35,19 +35,6 @@
         # Data ref currently must be same level, if not at top level.
         assert not self.param.need_late_validation( self.trans, { "reference_source": { "my_name": "42", "input_bam": model.HistoryDatasetAssociation() } } )
 
-    # Following test will fail due to bug in Galaxy.
-    def test_nested_context_validation_needed_in_repeat( self ):
-        self.type = "data_column"
-        self.set_ref_text = True
-        self.options_xml = '''<options><filter type="data_meta" ref="input_bam" key="dbkey"/></options>'''
-        assert not self.param.need_late_validation( self.trans, { "series": [ { "my_name": "42", "input_bam": model.HistoryDatasetAssociation() } ] } )
-
-    def test_nested_context_validation_not_needed_in_repeat( self ):
-        self.type = "data_column"
-        self.set_ref_text = True
-        self.options_xml = '''<options><filter type="data_meta" ref="input_bam" key="dbkey"/></options>'''
-        assert self.param.need_late_validation( self.trans, { "series": [ { "my_name": "42", "input_bam": basic.RuntimeValue() } ] } )
-
     def test_filter_param_value( self ):
         self.options_xml = '''<options from_data_table="test_table"><filter type="param_value" ref="input_bam" column="0" /></options>'''
         assert ("testname1", "testpath1", False) in self.param.get_options( self.trans, { "input_bam": "testname1" } )
@@ -61,11 +48,6 @@
         assert ("testname2", "testpath2", False) in self.param.get_options( self.trans, { "input_bam": "testpath2" } )
         assert len( self.param.get_options( self.trans, { "input_bam": "testpath3" } ) ) == 0
 
-    def test_filter_nested( self ):
-        # Test filtering a parameter inside a conditional (not currently supported.)
-        self.options_xml = '''<options from_data_table="test_table"><filter type="param_value" ref="input_bam" column="1" /></options>'''
-        assert ("testname1", "testpath1", False) in self.param.get_options( self.trans, {"condtional1" : { "input_bam": "testpath1", "my_name": 42 } } )
-
     # TODO: Good deal of overlap here with DataToolParameterTestCase,
     # refactor.
     def setUp( self ):
https://bitbucket.org/galaxy/galaxy-central/commits/f830918df15b/
Changeset:   f830918df15b
User:        jmchilton
Date:        2014-03-20 22:15:20
Summary:     Drop functional test for jobs that fails randomly.
Affected #:  1 file
diff -r 5996738d71ace34df5bee3452b8f2cdeda3e230f -r f830918df15be11380a4628c9c3aad860547e092 test/functional/api/test_jobs.py
--- a/test/functional/api/test_jobs.py
+++ b/test/functional/api/test_jobs.py
@@ -84,28 +84,6 @@
 
         self.__assert_one_search_result( search_payload )
 
-    def test_search_param( self ):
-        history_id, dataset_id = self.__history_with_ok_dataset()
-
-        inputs = json.dumps(
-            dict(
-                input=dict(
-                    src='hda',
-                    id=dataset_id,
-                ),
-                num_lines=1,
-            )
-        )
-        search_payload = dict(
-            tool_id="random_lines1",
-            inputs=inputs,
-            state="ok",
-        )
-
-        self.__run_randomlines_tool( 1, history_id, dataset_id )
-        self._wait_for_history( history_id, assert_ok=True )
-        self.__assert_one_search_result( search_payload )
-
     def __assert_one_search_result( self, search_payload ):
         search_response = self._post( "jobs/search", data=search_payload )
         self._assert_status_code_is( search_response, 200 )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0
                            
                          
                          
                            
    
                          
                        
                    
                    
                        2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/55cf8bb06007/
Changeset:   55cf8bb06007
User:        jmchilton
Date:        2014-03-18 17:33:05
Summary:     Bring workflow parameter context inline with tool.
When tool parameters are passed other_values when rendering tool forms - other_values is the context of other tools at their position in the tree, when rendering workflows other_values is the global state of the tool. The result is different handling of say parameter value filtering for tools and workflows. This changeset switches workflows/run.mako to use the same recursive calculation of context/other_values as tool_form.mako uses.
Affected #:  1 file
diff -r 0a9263af45ec678bea82a6d128f49cf5372d370d -r 55cf8bb0600772d4508cd725677725611e4d78d0 templates/webapps/galaxy/workflow/run.mako
--- a/templates/webapps/galaxy/workflow/run.mako
+++ b/templates/webapps/galaxy/workflow/run.mako
@@ -313,9 +313,10 @@
 %><%def name="do_inputs( inputs, values, errors, prefix, step, other_values = None, already_used = None )">
-  %if other_values is None:
-      <% other_values = values %>
-  %endif
+  <%
+  from galaxy.util.expressions import ExpressionContext
+  other_values = ExpressionContext( values, other_values )
+  %>
   %for input_index, input in enumerate( inputs.itervalues() ):
     %if input.type == "repeat":
       <div class="repeat-group">
https://bitbucket.org/galaxy/galaxy-central/commits/1285d07792b3/
Changeset:   1285d07792b3
User:        jmchilton
Date:        2014-03-20 22:05:49
Summary:     Merged in jmchilton/galaxy-central-fork-1 (pull request #349)
Bring workflow parameter context calculation in line with that of tools.
Affected #:  1 file
diff -r 7f7b154608e3e1c54d921d1e23277379f54293d9 -r 1285d07792b31e6c1ce9d66f559afc3f49a054a8 templates/webapps/galaxy/workflow/run.mako
--- a/templates/webapps/galaxy/workflow/run.mako
+++ b/templates/webapps/galaxy/workflow/run.mako
@@ -313,9 +313,10 @@
 %><%def name="do_inputs( inputs, values, errors, prefix, step, other_values = None, already_used = None )">
-  %if other_values is None:
-      <% other_values = values %>
-  %endif
+  <%
+  from galaxy.util.expressions import ExpressionContext
+  other_values = ExpressionContext( values, other_values )
+  %>
   %for input_index, input in enumerate( inputs.itervalues() ):
     %if input.type == "repeat":
       <div class="repeat-group">
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
                    
                  
                  
                          
                            
                            1
                            
                          
                          
                            
                            0