<commit_before>var BP_CUTOFF = 1000000;

var user;
var auth;
var selected_sequence_file;
var selected_metadata_file;
var selected_project;
var selected_libraries = [];
var selected_no_metadata = 0;
var last_directory = "";
var is_a_sequence_file_ending = /(fasta|fa|ffn|frn|fna|fastq|fq)$/;

// initialization
function init_all () {
  if (document.getElementById('user')) {
    var repo = { "url": "upload.cgi/",
		 "type": "WebApp",
		 "id": "mobedac" };
    initialize_data_storage( [ repo ] );
    user = JSON.parse(document.getElementById('uifo').innerHTML);
    auth = user.auth;
    init_uploader();
    update_inbox();
  }
}

function update_inbox (data, files, action) {
  if (data) {
    var flist = DataStore['user_inbox'][user.login].files;
    var dlist = DataStore['user_inbox'][user.login].directories;
    var messages = DataStore['user_inbox'][user.login].messages;
    var popup_messages = DataStore['user_inbox'][user.login].popup_messages;

    var sequence_files = [];
    var metadata_files = [];

    var dir_list_html = '<form><select id="dir_select">';
    dir_list_html += '  <option value="inbox">inbox (base directory)</option>';
    var delete_dir_list_html = '<form><select id="delete_dir_select">';
    var mate_pair_file_list = "";
    var inbox_html = '<select id="inbox_select" multiple style="width: 420px; height: 200px;">';
    var seq_dlist = [];
    var seqs_in_dir = false;
    for (var i=0; i<dlist.length; i++) {
      if (!dlist[i].match(/^(\_)/)) {
        dir_list_html += "  <option>"+dlist[i]+"</option>";
        if(DataStore['user_inbox'][user.login].fileinfo[dlist[i]].length == 0) {
          delete_dir_list_html += "  <option>"+dlist[i]+"</option>";
        }
        inbox_html += "<optgroup title='this is a directory\nclick to toggle open / close' open=0 label='[ "+dlist[i]+" ] - "+DataStore['user_inbox'][user.login].fileinfo[dlist[i]].length+" files' onclick='if(event.originalTarget.nodeName==\"OPTGROUP\"){if(this.open){this.open=0;for(var i=0;i<this.childNodes.length;i++){this.childNodes[i].style.display=\"none\";}}else{this.open=1;for(var i=0;i<this.childNodes.length;i++){this.childNodes[i].style.display=\"\";}}}'>";
      }
      for (var h=0; h<DataStore['user_inbox'][user.login].fileinfo[dlist[i]].length; h++) {
	var fn = DataStore['user_inbox'][user.login].fileinfo[dlist[i]][h];
        if(fn.match(/(fastq|fq)$/)) {
          mate_pair_file_list += "  <option>"+dlist[i]+"/"+fn+"</option>";
        }
	if (fn.match(is_a_sequence_file_ending)) {
	  seq_dlist[dlist[i]] = 1;
	  seqs_in_dir = true;
	}
	var inf = DataStore['user_inbox'][user.login].fileinfo[dlist[i]+"/"+fn];
        var lock_msg = "";
        if(DataStore['user_inbox'][user.login].locks[dlist[i]+"/"+fn]) {
          lock_msg = DataStore['user_inbox'][user.login].locks[dlist[i]+"/"+fn];
        }
        var error_msg = "";
        if(DataStore['user_inbox'][user.login].computation_error_log[dlist[i]+"/"+fn]) {
          error_msg = DataStore['user_inbox'][user.login].computation_error_log[dlist[i]+"/"+fn];
        }
	if ((seq_dlist[dlist[i]] == 1) && inf['file type'] && (inf['file type'] == 'malformed')) {
	  inbox_html += "<option style='display: none; padding-left: 35px; color: red;' value='"+dlist[i]+"/"+fn+"'>"+fn+"</option>";
	} else if ((seq_dlist[dlist[i]] == 1) && inf['Error']) {
	  inbox_html += "<option style='display: none; padding-left: 35px; color: red;' value='"+dlist[i]+"/"+fn+"'>"+fn+"</option>";
	} else if ((seq_dlist[dlist[i]] == 1) && inf['unique id count'] && inf['sequence count'] && (inf['unique id count'] != inf['sequence count'])) {
	  inbox_html += "<option style='display: none; padding-left: 35px; color: red;' value='"+dlist[i]+"/"+fn+"'>"+fn+"</option>";
	} else if ((seq_dlist[dlist[i]] == 1) && inf['bp count'] && inf['bp count'] <= BP_CUTOFF) {
	  inbox_html += "<option style='display: none; padding-left: 35px; color: red;' value='"+dlist[i]+"/"+fn+"'>"+fn+"</option>";
	} else if (lock_msg != "") {
	  inbox_html += "<option style='display: none; padding-left: 35px; color: gray;' value='"+dlist[i]+"/"+fn+"'>("+lock_msg+") "+fn+"</option>";
	} else if (error_msg != "") {
	  inbox_html += "<option style='display: none; padding-left: 35px; color: red;' value='"+dlist[i]+"/"+fn+"'>(error) "+fn+"</option>";
	} else {
	  inbox_html += "<option style='display: none; padding-left: 35px;' value='"+dlist[i]+"/"+fn+"'>"+fn+"</option>";
	}
      }
      inbox_html += "</optgroup>";
    }
    for (var i=0; i<flist.length; i++) {
      if(flist[i].match(/(fastq|fq)$/)) {
        mate_pair_file_list += "  <option>"+flist[i]+"</option>";
      }
      var isSeq = flist[i].match(is_a_sequence_file_ending);
      if (isSeq) {
	sequence_files[sequence_files.length] = flist[i];
      }
      var isMet = flist[i].match(/\.xls(x)?$/);
      if (isMet) {
	metadata_files[metadata_files.length] = flist[i];
      }
      var inf = DataStore['user_inbox'][user.login].fileinfo[flist[i]];
      var lock_msg = "";
      if(DataStore['user_inbox'][user.login].locks[flist[i]]) {
        lock_msg = DataStore['user_inbox'][user.login].locks[flist[i]];
      }
      var error_msg = "";
      if(DataStore['user_inbox'][user.login].computation_error_log[flist[i]]) {
        error_msg = DataStore['user_inbox'][user.login].computation_error_log[flist[i]];
      }
      if ((seq_dlist[dlist[i]] == 1) && inf['file type'] && (inf['file type'] == 'malformed')) {
	inbox_html += "<option style='color: red;'>"+flist[i]+"</option>";
      } else if (isSeq && inf['Error']) {
	inbox_html += "<option style='color: red;'>"+flist[i]+"</option>";
      } else if (isSeq && inf['unique id count'] && inf['sequence count'] && (inf['unique id count'] != inf['sequence count'])) {
	inbox_html += "<option style='color: red;'>"+flist[i]+"</option>";
      } else if (isSeq && inf['bp count'] && inf['bp count'] <= BP_CUTOFF) {
	inbox_html += "<option style='color: red;'>"+flist[i]+"</option>";
      } else if (lock_msg != "") {
        inbox_html += "<option style='color: gray;' value='"+flist[i]+"'>("+lock_msg+") "+flist[i]+"</option>";
      } else if (error_msg != "") {
        inbox_html += "<option style='color: red;' value='"+flist[i]+"'>(error) "+flist[i]+"</option>";
      } else {
        inbox_html += "<option>"+flist[i]+"</option>";
      }
    }

    mate_pair_file_list += '</select></form>';
    document.getElementById('mate_pair_one').innerHTML = '<form><select id="mate_pair_one_select">'+mate_pair_file_list;
    document.getElementById('mate_pair_two').innerHTML = '<form><select id="mate_pair_two_select">'+mate_pair_file_list;
    document.getElementById('mate_pair_index').innerHTML = '<form><select id="mate_pair_index_select"><option>-- none --</option>'+mate_pair_file_list;
    dir_list_html += '</select></form>';
    document.getElementById('dir_list').innerHTML = dir_list_html;
    delete_dir_list_html += '</select></form>';
    document.getElementById('delete_dir_list').innerHTML = delete_dir_list_html;
    inbox_html += '</select>';
    document.getElementById('inbox').innerHTML = inbox_html;
    document.getElementById('inbox_feedback').innerHTML = "";

    if (messages.length) {
      document.getElementById('inbox_feedback').innerHTML = "<h4>Update</h4><br>"+messages.join("<br>")+"<br><br><br>";
    }

    if ((sequence_files.length || seqs_in_dir) && ! selected_sequence_file) {
      var tdata = [];
      for (var i in seq_dlist) {
	for (var h=0; h<DataStore['user_inbox'][user.login].fileinfo[i].length; h++) {
	  // 'select', 'directory', 'filename', 'format', 'size', 'upload date', 'bp count', 'sequencing method', 'sequence type', 'md5'
	  var fn = DataStore['user_inbox'][user.login].fileinfo[i][h];
	  if (fn.match(is_a_sequence_file_ending)) {
	    var inf = DataStore['user_inbox'][user.login].fileinfo[i+'/'+fn];
	    var lock_msg = DataStore['user_inbox'][user.login].locks[i+'/'+fn];
	    if (inf && inf['bp count'] && (inf['file type'] != 'malformed') && inf['unique id count'] && inf['sequence count'] && (inf['unique id count'] == inf['sequence count']) && (! inf['Error']) && inf['bp count'] > BP_CUTOFF && (! lock_msg)) {
	      var trow = [ 0, i, fn, inf['file type'], inf['file size'], inf['creation date'], inf['bp count'], inf['sequencing method guess'], inf['sequence type'], inf['file checksum'], tdata.length ];
	      tdata[tdata.length] = trow;
	    }
	  }
	}
      }
      
      for (var i=0; i<sequence_files.length; i++) {
	  var fn = sequence_files[i];
	  var inf = DataStore['user_inbox'][user.login].fileinfo[fn];
	  var lock_msg = DataStore['user_inbox'][user.login].locks[fn];
	  if (inf && inf['bp count'] && (inf['file type'] != 'malformed') && inf['unique id count'] && inf['sequence count'] && (inf['unique id count'] == inf['sequence count']) && (! inf['Error']) && inf['bp count'] > BP_CUTOFF && (! lock_msg)) {
	    var trow = [ 0, "-", fn, inf['file type'], inf['file size'], inf['creation date'], inf['bp count'], inf['sequencing method guess'], inf['sequence type'], inf['file checksum'], tdata.length ];
	    tdata[tdata.length] = trow;
	  }
      }
      initialize_table(0, tdata);
    }
    if (! selected_metadata_file) {
      var html = "<div><h3>available metadata files</h3><table><tr><td><form class='form-horizontal'><select id='metadata_file_select' multiple style='width: 420px; height: 200px;'>";
      for (var i=0; i<metadata_files.length; i++) {
	html += "<option>"+metadata_files[i]+"</option>";
      }
      html += "</select><br><p><input type='checkbox' value='no_metadata' name='no_metadata' id='no_metadata' onclick=\"if(this.checked){alert('INFO\\nNot submitting metadata will severely lower your priority in the computation queue.\\nYou will also not be able to make your data public until you provide metadata for it.');document.getElementById('accept_metadata_selection').onclick();}\"> I do not want to supply metadata</p> <input type='button' id='accept_metadata_selection' class='btn' value='select' onclick='select_metadata_file();'></form></td><td><p id='metadata_file_info' style='margin-left: 20px;'></p></td></tr></table></div>";
      document.getElementById("sel_mdfile_div").innerHTML = html;
      document.getElementById('inbox_select').onchange = function () {
	var fn = this.options[this.selectedIndex].value;
	if (DataStore.user_inbox[user.login].fileinfo && DataStore.user_inbox[user.login].fileinfo[fn]) {
	    var ptext = "<h4>File Information</h4><br>";
            if(DataStore['user_inbox'][user.login].locks[fn]) {
	      ptext += '<div class="alert alert-block"><button class="close" data-dismiss="alert" type="button">x</button><strong>Notice</strong><br>This file is currently:<br><span style="padding-left: 10px;"><pre>'+DataStore['user_inbox'][user.login].locks[fn]+'</pre></span><br>You cannot perform another operation on this file until this is complete.</div>';
            }
            if(DataStore['user_inbox'][user.login].computation_error_log[fn]) {
	      ptext += '<div class="alert alert-error"><button class="close" data-dismiss="alert" type="button">x</button><strong>Warning</strong><br>This file encountered a computation error:<br><span style="padding-left: 10px;"><pre>'+DataStore['user_inbox'][user.login].computation_error_log[fn]+'</pre></span></div>';
            }
	    var inf = DataStore.user_inbox[user.login].fileinfo[fn]
	    if (inf['file type'] && (inf['file type'] == 'malformed')) {
		ptext += '<div class="alert alert-error"><button class="close" data-dismiss="alert" type="button">x</button><strong>Warning</strong><br>This is a malformed / unidentifiable sequence file. You will not be able to use this file for submission.</div>';
	    }
	    else if (inf['Error']) {
		ptext += '<div class="alert alert-error" style="width:430px;"><button class="close" data-dismiss="alert" type="button">x</button><strong>Warning</strong><br>There was an error in the sequence stats computation:<br><span style="padding-left: 10px;"><pre>'+inf['Error']+'</pre></span><br>You will not be able to use this file for submission.</div>';
	    }
	    else if (inf['unique id count'] && inf['sequence count'] && (inf['unique id count'] != inf['sequence count'])) {
		ptext += '<div class="alert alert-error"><button class="close" data-dismiss="alert" type="button">x</button><strong>Warning</strong><br>The unique id count does not match the sequence count. You will not be able to use this file for submission.</div>';
	    }
            else if ((seq_dlist[dlist[i]] == 1) && inf['bp count'] && inf['bp count'] <= BP_CUTOFF) {
		ptext += '<div class="alert alert-error"><button class="close" data-dismiss="alert" type="button">x</button><strong>Warning</strong><br>This file is too small for submission, the minimum is 1MBp.</div>';
	    }
	    ptext += "<table>";
	  for (i in DataStore.user_inbox[user.login].fileinfo[fn]) {
	    ptext += "<tr><td><b>"+i+"</b></td><td style='padding-left: 5px;'>"+DataStore.user_inbox[user.login].fileinfo[fn][i]+"</td></tr>";
	  }
	  ptext += "</table>";
	  document.getElementById('inbox_file_info').innerHTML = ptext;
	} else {
	  document.getElementById('inbox_file_info').innerHTML = "";
	}
      }
    }

    if (popup_messages.length) {
      alert(popup_messages.join("\n\n"));
    }
  } else {
    if (action != 'upload_complete' && document.getElementById('inbox_feedback') && document.getElementById('inbox_feedback').innerHTML.match(/^\<img/)) {
      alert('The inbox is already performing an operation.\nPlease wait for this to finish.');
      return 0;
    }

    var params = [];
    params['query'] = [];
    params['query'][params['query'].length] = 'auth';
    params['query'][params['query'].length] = user.auth;

    var loading_info = " updating...<br><br>";
    if (action && action == "upload_complete") {
      loading_info = "New files were added. If the upload contained sequence files, they will be processed for statistics. This process might take up to one minute.";
    }
    if (files) {
      params['query'][params['query'].length] = 'faction';
      params['query'][params['query'].length] = action;
      if (action == "del") {
	loading_info += "Deleting file(s):";
      } else if (action == "convert") {
	loading_info += "Converting sff file(s) to fastq. The resulting files will be processed for statistics. This will take a few minutes, depending on the file size.<br><br>";
      } else if (action == "demultiplex") {
	loading_info += "Submitting demultiplexing...<br><br>";
      } else if (action == "merge_mate_pairs") {
	loading_info += "Submitting mate-pair merging...<br><br>";
      }
      for (var i=0; i<files.length; i++) {
	params['query'][params['query'].length] = 'fn';
	params['query'][params['query'].length] = files[i];
	loading_info += "<br>"+files[i];
      }
    }
    if (document.getElementById('inbox_feedback').innerHTML != "") {
      document.getElementById('inbox_feedback').innerHTML = "<img src='./Html/ajax-loader.gif'>"+loading_info;
    }


    get_objects('user_inbox', params, update_inbox, 1);    
  }
}

/* File Actions */
function check_delete_files () {
  if (confirm("really delete the selected files from your inbox?")) {
    var files = [];
    var filebox = document.getElementById('inbox_select');
    for (var i=0; i<filebox.options.length; i++) {
      if (filebox.options[i].selected) {
	files[files.length] = filebox.options[i].value;
      }
    }
    update_inbox(null, files, "del");
  }
}

function unpack_files () {
  var files = [];
  var filebox = document.getElementById('inbox_select');
  for (var i=0; i<filebox.options.length; i++) {
    if (filebox.options[i].selected) {
      files[files.length] = filebox.options[i].value;
    }
  }
  update_inbox(null, files, "unpack");
}

function convert_files () {
  alert("This might take some minutes, depending on filesize.\nWhen the conversion has finished, your inbox\nwill update automatically.");
  var files = [];
  var filebox = document.getElementById('inbox_select');
  for (var i=0; i<filebox.options.length; i++) {
    if (filebox.options[i].selected) {
      if (filebox.options[i].value.match(/sff$/)) {
	files[files.length] = filebox.options[i].value;
      } else {
	alert(filebox.options[i].value + " does not appear to be an sff file, it will be skipped.");
      }
    }
  }
  update_inbox(null, files, "convert");  
}

function merge_mate_pairs () {
  var output_filename = document.getElementById('merge_output_filename').value;
  var files = [];
  files[0] = document.getElementById('mate_pair_one_select').value;
  files[1] = document.getElementById('mate_pair_two_select').value;
  files[2] = document.getElementById('mate_pair_index_select').value;
  files[3] = document.getElementById('mate_pair_option').value;

  if (output_filename == "") {
    alert("You need to enter an output filename to merge mate-pairs.");
    return false;
  } else if(files[0] == files[1]) {
    alert("You entered the same filename for both input files.  Your selection should include two different, paired fastq sequence files (.fq or .fastq)");
    return false;
  } else if(files[0] == files[2]) {
    alert("You entered the same filename for mate pair file 1 and your index file.  These must be two different files (.fq or .fastq)");
    return false;
  } else if(files[1] == files[2]) {
    alert("You entered the same filename for mate pair file 2 and your index file.  These must be two different files (.fq or .fastq)");
    return false;
  }

  var seqfile;
  if (files[0].match(/(fastq|fq)$/) && files[1].match(/(fastq|fq)$/) && (files[2] == "-- none --" || files[2].match(/(fastq|fq)$/))) {
    if(! output_filename.match(/(fastq|fq)$/)) {
      output_filename += ".fastq";
    }
    if(output_filename.match(/\//)) {
      alert("Your output filename cannot contain a '/' character in the name.");
      return false;
    }
    files[files.length] = output_filename;
    alert("Your output file will be saved in your Inbox base directory as: "+output_filename+"\n\nThis might take some minutes, depending on filesize.  When the merging has finished, your inbox will update automatically.\n\n");
    update_inbox(null, files, "merge_mate_pairs");<commit_msg>Fixed bugs and added check to make sure files in mate-pair merging have the same number of sequences.<commit_after>var BP_CUTOFF = 1000000;

var user;
var auth;
var selected_sequence_file;
var selected_metadata_file;
var selected_project;
var selected_libraries = [];
var selected_no_metadata = 0;
var last_directory = "";
var is_a_sequence_file_ending = /(fasta|fa|ffn|frn|fna|fastq|fq)$/;

// initialization
function init_all () {
  if (document.getElementById('user')) {
    var repo = { "url": "upload.cgi/",
		 "type": "WebApp",
		 "id": "mobedac" };
    initialize_data_storage( [ repo ] );
    user = JSON.parse(document.getElementById('uifo').innerHTML);
    auth = user.auth;
    init_uploader();
    update_inbox();
  }
}

function update_inbox (data, files, action) {
  if (data) {
    var flist = DataStore['user_inbox'][user.login].files;
    var dlist = DataStore['user_inbox'][user.login].directories;
    var messages = DataStore['user_inbox'][user.login].messages;
    var popup_messages = DataStore['user_inbox'][user.login].popup_messages;

    var sequence_files = [];
    var metadata_files = [];

    var dir_list_html = '<form><select id="dir_select">';
    dir_list_html += '  <option value="inbox">inbox (base directory)</option>';
    var delete_dir_list_html = '<form><select id="delete_dir_select">';
    var mate_pair_file_list = "";
    var inbox_html = '<select id="inbox_select" multiple style="width: 420px; height: 200px;">';
    var seq_dlist = [];
    var seqs_in_dir = false;
    for (var i=0; i<dlist.length; i++) {
      if (!dlist[i].match(/^(\_)/)) {
        dir_list_html += "  <option>"+dlist[i]+"</option>";
        if(DataStore['user_inbox'][user.login].fileinfo[dlist[i]].length == 0) {
           DataStore['user_inbox'][user.login].fileinfo[files[0]]
          delete_dir_list_html += "  <option>"+dlist[i]+"</option>";
        }
        inbox_html += "<optgroup title='this is a directory\nclick to toggle open / close' open=0 label='[ "+dlist[i]+" ] - "+DataStore['user_inbox'][user.login].fileinfo[dlist[i]].length+" files' onclick='if(event.originalTarget.nodeName==\"OPTGROUP\"){if(this.open){this.open=0;for(var i=0;i<this.childNodes.length;i++){this.childNodes[i].style.display=\"none\";}}else{this.open=1;for(var i=0;i<this.childNodes.length;i++){this.childNodes[i].style.display=\"\";}}}'>";
      }
      for (var h=0; h<DataStore['user_inbox'][user.login].fileinfo[dlist[i]].length; h++) {
	var fn = DataStore['user_inbox'][user.login].fileinfo[dlist[i]][h];
        if(fn.match(/(fastq|fq)$/)) {
          mate_pair_file_list += "  <option>"+dlist[i]+"/"+fn+"</option>";
        }
	if (fn.match(is_a_sequence_file_ending)) {
	  seq_dlist[dlist[i]] = 1;
	  seqs_in_dir = true;
	}
	var inf = DataStore['user_inbox'][user.login].fileinfo[dlist[i]+"/"+fn];
        var lock_msg = "";
        if(DataStore['user_inbox'][user.login].locks[dlist[i]+"/"+fn]) {
          lock_msg = DataStore['user_inbox'][user.login].locks[dlist[i]+"/"+fn];
        }
        var error_msg = "";
        if(DataStore['user_inbox'][user.login].computation_error_log[dlist[i]+"/"+fn]) {
          error_msg = DataStore['user_inbox'][user.login].computation_error_log[dlist[i]+"/"+fn];
        }
	if ((seq_dlist[dlist[i]] == 1) && inf['file type'] && (inf['file type'] == 'malformed')) {
	  inbox_html += "<option style='display: none; padding-left: 35px; color: red;' value='"+dlist[i]+"/"+fn+"'>"+fn+"</option>";
	} else if ((seq_dlist[dlist[i]] == 1) && inf['Error']) {
	  inbox_html += "<option style='display: none; padding-left: 35px; color: red;' value='"+dlist[i]+"/"+fn+"'>"+fn+"</option>";
	} else if ((seq_dlist[dlist[i]] == 1) && inf['unique id count'] && inf['sequence count'] && (inf['unique id count'] != inf['sequence count'])) {
	  inbox_html += "<option style='display: none; padding-left: 35px; color: red;' value='"+dlist[i]+"/"+fn+"'>"+fn+"</option>";
	} else if ((seq_dlist[dlist[i]] == 1) && inf['bp count'] && inf['bp count'] <= BP_CUTOFF) {
	  inbox_html += "<option style='display: none; padding-left: 35px; color: red;' value='"+dlist[i]+"/"+fn+"'>"+fn+"</option>";
	} else if (lock_msg != "") {
	  inbox_html += "<option style='display: none; padding-left: 35px; color: gray;' value='"+dlist[i]+"/"+fn+"'>("+lock_msg+") "+fn+"</option>";
	} else if (error_msg != "") {
	  inbox_html += "<option style='display: none; padding-left: 35px; color: red;' value='"+dlist[i]+"/"+fn+"'>(error) "+fn+"</option>";
	} else {
	  inbox_html += "<option style='display: none; padding-left: 35px;' value='"+dlist[i]+"/"+fn+"'>"+fn+"</option>";
	}
      }
      inbox_html += "</optgroup>";
    }
    for (var i=0; i<flist.length; i++) {
      if(flist[i].match(/(fastq|fq)$/)) {
        mate_pair_file_list += "  <option>"+flist[i]+"</option>";
      }
      var isSeq = flist[i].match(is_a_sequence_file_ending);
      if (isSeq) {
	sequence_files[sequence_files.length] = flist[i];
      }
      var isMet = flist[i].match(/\.xls(x)?$/);
      if (isMet) {
	metadata_files[metadata_files.length] = flist[i];
      }
      var inf = DataStore['user_inbox'][user.login].fileinfo[flist[i]];
      var lock_msg = "";
      if(DataStore['user_inbox'][user.login].locks[flist[i]]) {
        lock_msg = DataStore['user_inbox'][user.login].locks[flist[i]];
      }
      var error_msg = "";
      if(DataStore['user_inbox'][user.login].computation_error_log[flist[i]]) {
        error_msg = DataStore['user_inbox'][user.login].computation_error_log[flist[i]];
      }
      if ((seq_dlist[dlist[i]] == 1) && inf['file type'] && (inf['file type'] == 'malformed')) {
	inbox_html += "<option style='color: red;'>"+flist[i]+"</option>";
      } else if (isSeq && inf['Error']) {
	inbox_html += "<option style='color: red;'>"+flist[i]+"</option>";
      } else if (isSeq && inf['unique id count'] && inf['sequence count'] && (inf['unique id count'] != inf['sequence count'])) {
	inbox_html += "<option style='color: red;'>"+flist[i]+"</option>";
      } else if (isSeq && inf['bp count'] && inf['bp count'] <= BP_CUTOFF) {
	inbox_html += "<option style='color: red;'>"+flist[i]+"</option>";
      } else if (lock_msg != "") {
        inbox_html += "<option style='color: gray;' value='"+flist[i]+"'>("+lock_msg+") "+flist[i]+"</option>";
      } else if (error_msg != "") {
        inbox_html += "<option style='color: red;' value='"+flist[i]+"'>(error) "+flist[i]+"</option>";
      } else {
        inbox_html += "<option>"+flist[i]+"</option>";
      }
    }

    mate_pair_file_list += '</select></form>';
    document.getElementById('mate_pair_one').innerHTML = '<form><select id="mate_pair_one_select">'+mate_pair_file_list;
    document.getElementById('mate_pair_two').innerHTML = '<form><select id="mate_pair_two_select">'+mate_pair_file_list;
    document.getElementById('mate_pair_index').innerHTML = '<form><select id="mate_pair_index_select"><option>none</option>'+mate_pair_file_list;
    dir_list_html += '</select></form>';
    document.getElementById('dir_list').innerHTML = dir_list_html;
    delete_dir_list_html += '</select></form>';
    document.getElementById('delete_dir_list').innerHTML = delete_dir_list_html;
    inbox_html += '</select>';
    document.getElementById('inbox').innerHTML = inbox_html;
    document.getElementById('inbox_feedback').innerHTML = "";

    if (messages.length) {
      document.getElementById('inbox_feedback').innerHTML = "<h4>Update</h4><br>"+messages.join("<br>")+"<br><br><br>";
    }

    if ((sequence_files.length || seqs_in_dir) && ! selected_sequence_file) {
      var tdata = [];
      for (var i in seq_dlist) {
	for (var h=0; h<DataStore['user_inbox'][user.login].fileinfo[i].length; h++) {
	  // 'select', 'directory', 'filename', 'format', 'size', 'upload date', 'bp count', 'sequencing method', 'sequence type', 'md5'
	  var fn = DataStore['user_inbox'][user.login].fileinfo[i][h];
	  if (fn.match(is_a_sequence_file_ending)) {
	    var inf = DataStore['user_inbox'][user.login].fileinfo[i+'/'+fn];
	    var lock_msg = DataStore['user_inbox'][user.login].locks[i+'/'+fn];
	    if (inf && inf['bp count'] && (inf['file type'] != 'malformed') && inf['unique id count'] && inf['sequence count'] && (inf['unique id count'] == inf['sequence count']) && (! inf['Error']) && inf['bp count'] > BP_CUTOFF && (! lock_msg)) {
	      var trow = [ 0, i, fn, inf['file type'], inf['file size'], inf['creation date'], inf['bp count'], inf['sequencing method guess'], inf['sequence type'], inf['file checksum'], tdata.length ];
	      tdata[tdata.length] = trow;
	    }
	  }
	}
      }
      
      for (var i=0; i<sequence_files.length; i++) {
	  var fn = sequence_files[i];
	  var inf = DataStore['user_inbox'][user.login].fileinfo[fn];
	  var lock_msg = DataStore['user_inbox'][user.login].locks[fn];
	  if (inf && inf['bp count'] && (inf['file type'] != 'malformed') && inf['unique id count'] && inf['sequence count'] && (inf['unique id count'] == inf['sequence count']) && (! inf['Error']) && inf['bp count'] > BP_CUTOFF && (! lock_msg)) {
	    var trow = [ 0, "-", fn, inf['file type'], inf['file size'], inf['creation date'], inf['bp count'], inf['sequencing method guess'], inf['sequence type'], inf['file checksum'], tdata.length ];
	    tdata[tdata.length] = trow;
	  }
      }
      initialize_table(0, tdata);
    }
    if (! selected_metadata_file) {
      var html = "<div><h3>available metadata files</h3><table><tr><td><form class='form-horizontal'><select id='metadata_file_select' multiple style='width: 420px; height: 200px;'>";
      for (var i=0; i<metadata_files.length; i++) {
	html += "<option>"+metadata_files[i]+"</option>";
      }
      html += "</select><br><p><input type='checkbox' value='no_metadata' name='no_metadata' id='no_metadata' onclick=\"if(this.checked){alert('INFO\\nNot submitting metadata will severely lower your priority in the computation queue.\\nYou will also not be able to make your data public until you provide metadata for it.');document.getElementById('accept_metadata_selection').onclick();}\"> I do not want to supply metadata</p> <input type='button' id='accept_metadata_selection' class='btn' value='select' onclick='select_metadata_file();'></form></td><td><p id='metadata_file_info' style='margin-left: 20px;'></p></td></tr></table></div>";
      document.getElementById("sel_mdfile_div").innerHTML = html;
      document.getElementById('inbox_select').onchange = function () {
	var fn = this.options[this.selectedIndex].value;
	if (DataStore.user_inbox[user.login].fileinfo && DataStore.user_inbox[user.login].fileinfo[fn]) {
	    var ptext = "<h4>File Information</h4><br>";
            if(DataStore['user_inbox'][user.login].locks[fn]) {
	      ptext += '<div class="alert alert-block"><button class="close" data-dismiss="alert" type="button">x</button><strong>Notice</strong><br>This file is currently:<br><span style="padding-left: 10px;"><pre>'+DataStore['user_inbox'][user.login].locks[fn]+'</pre></span><br>You cannot perform another operation on this file until this is complete.</div>';
            }
            if(DataStore['user_inbox'][user.login].computation_error_log[fn]) {
	      ptext += '<div class="alert alert-error"><button class="close" data-dismiss="alert" type="button">x</button><strong>Warning</strong><br>This file encountered a computation error:<br><span style="padding-left: 10px;"><pre>'+DataStore['user_inbox'][user.login].computation_error_log[fn]+'</pre></span></div>';
            }
	    var inf = DataStore.user_inbox[user.login].fileinfo[fn]
	    if (inf['file type'] && (inf['file type'] == 'malformed')) {
		ptext += '<div class="alert alert-error"><button class="close" data-dismiss="alert" type="button">x</button><strong>Warning</strong><br>This is a malformed / unidentifiable sequence file. You will not be able to use this file for submission.</div>';
	    }
	    else if (inf['Error']) {
		ptext += '<div class="alert alert-error" style="width:430px;"><button class="close" data-dismiss="alert" type="button">x</button><strong>Warning</strong><br>There was an error in the sequence stats computation:<br><span style="padding-left: 10px;"><pre>'+inf['Error']+'</pre></span><br>You will not be able to use this file for submission.</div>';
	    }
	    else if (inf['unique id count'] && inf['sequence count'] && (inf['unique id count'] != inf['sequence count'])) {
		ptext += '<div class="alert alert-error"><button class="close" data-dismiss="alert" type="button">x</button><strong>Warning</strong><br>The unique id count does not match the sequence count. You will not be able to use this file for submission.</div>';
	    }
            else if ((seq_dlist[dlist[i]] == 1) && inf['bp count'] && inf['bp count'] <= BP_CUTOFF) {
		ptext += '<div class="alert alert-error"><button class="close" data-dismiss="alert" type="button">x</button><strong>Warning</strong><br>This file is too small for submission, the minimum is 1MBp.</div>';
	    }
	    ptext += "<table>";
	  for (i in DataStore.user_inbox[user.login].fileinfo[fn]) {
	    ptext += "<tr><td><b>"+i+"</b></td><td style='padding-left: 5px;'>"+DataStore.user_inbox[user.login].fileinfo[fn][i]+"</td></tr>";
	  }
	  ptext += "</table>";
	  document.getElementById('inbox_file_info').innerHTML = ptext;
	} else {
	  document.getElementById('inbox_file_info').innerHTML = "";
	}
      }
    }

    if (popup_messages.length) {
      alert(popup_messages.join("\n\n"));
    }
  } else {
    if (action != 'upload_complete' && document.getElementById('inbox_feedback') && document.getElementById('inbox_feedback').innerHTML.match(/^\<img/)) {
      alert('The inbox is already performing an operation.\nPlease wait for this to finish.');
      return 0;
    }

    var params = [];
    params['query'] = [];
    params['query'][params['query'].length] = 'auth';
    params['query'][params['query'].length] = user.auth;

    var loading_info = " updating...<br><br>";
    if (action && action == "upload_complete") {
      loading_info = "New files were added. If the upload contained sequence files, they will be processed for statistics. This process might take up to one minute.";
    }
    if (files) {
      params['query'][params['query'].length] = 'faction';
      params['query'][params['query'].length] = action;
      if (action == "del") {
	loading_info += "Deleting file(s):";
      } else if (action == "convert") {
	loading_info += "Converting sff file(s) to fastq. The resulting files will be processed for statistics. This will take a few minutes, depending on the file size.<br><br>";
      } else if (action == "demultiplex") {
	loading_info += "Submitting demultiplexing...<br><br>";
      } else if (action == "merge_mate_pairs") {
	loading_info += "Submitting mate-pair merging...<br><br>";
      }
      for (var i=0; i<files.length; i++) {
	params['query'][params['query'].length] = 'fn';
	params['query'][params['query'].length] = files[i];
	loading_info += "<br>"+files[i];
      }
    }
    if (document.getElementById('inbox_feedback').innerHTML != "") {
      document.getElementById('inbox_feedback').innerHTML = "<img src='./Html/ajax-loader.gif'>"+loading_info;
    }


    get_objects('user_inbox', params, update_inbox, 1);    
  }
}

/* File Actions */
function check_delete_files () {
  if (confirm("really delete the selected files from your inbox?")) {
    var files = [];
    var filebox = document.getElementById('inbox_select');
    for (var i=0; i<filebox.options.length; i++) {
      if (filebox.options[i].selected) {
	files[files.length] = filebox.options[i].value;
      }
    }
    update_inbox(null, files, "del");
  }
}

function unpack_files () {
  var files = [];
  var filebox = document.getElementById('inbox_select');
  for (var i=0; i<filebox.options.length; i++) {
    if (filebox.options[i].selected) {
      files[files.length] = filebox.options[i].value;
    }
  }
  update_inbox(null, files, "unpack");
}

function convert_files () {
  alert("This might take some minutes, depending on filesize.\nWhen the conversion has finished, your inbox\nwill update automatically.");
  var files = [];
  var filebox = document.getElementById('inbox_select');
  for (var i=0; i<filebox.options.length; i++) {
    if (filebox.options[i].selected) {
      if (filebox.options[i].value.match(/sff$/)) {
	files[files.length] = filebox.options[i].value;
      } else {
	alert(filebox.options[i].value + " does not appear to be an sff file, it will be skipped.");
      }
    }
  }
  update_inbox(null, files, "convert");  
}

function merge_mate_pairs () {
  var output_filename = document.getElementById('merge_output_filename').value;
  var files = [];
  files[0] = document.getElementById('mate_pair_one_select').value;
  files[1] = document.getElementById('mate_pair_two_select').value;
  files[2] = document.getElementById('mate_pair_index_select').value;
  files[3] = $('input[@name="mate_pair_option"]:checked').val();

  if (output_filename == "") {
    alert("You need to enter an output filename to merge mate-pairs.");
    return false;
  } else if(files[0] == files[1]) {
    alert("You entered the same filename for both input files.  Your selection should include two different, paired fastq sequence files (.fq or .fastq)");
    return false;
  } else if(files[0] == files[2]) {
    alert("You entered the same filename for mate pair file 1 and your index file.  These must be two different files (.fq or .fastq)");
    return false;
  } else if(files[1] == files[2]) {
    alert("You entered the same filename for mate pair file 2 and your index file.  These must be two different files (.fq or .fastq)");
    return false;
  }

  var seqfile;
  if (files[0].match(/(fastq|fq)$/) && files[1].match(/(fastq|fq)$/) && (files[2] == "none" || files[2].match(/(fastq|fq)$/))) {
    var seq_count1 = DataStore['user_inbox'][user.login].fileinfo[files[0]]['sequence count'];
    var seq_count2 = DataStore['user_inbox'][user.login].fileinfo[files[1]]['sequence count'];
    var seq_count3 = 0;
    if(files[2] != "none") {
      seq_count3 = DataStore['user_inbox'][user.login].fileinfo[files[2]]['sequence count'];
    }
    if(seq_count1 == seq_count2) {
      if(seq_count3 != 0 && seq_count3 != seq_count1) {
        alert("Your index (aka barcodes) file does not have the same number of sequence headers as your sequence files.  Merge mate-pairs cannot be run with this input.");
        return false;
      }
    } else {
      alert("Your input sequence files 1 and 2 do not have the same number of sequences in them.  Merge mate-pairs cannot be run with this input.");
      return false;
    }

    if(! output_filename.match(/(fastq|fq)$/)) {
      output_filename += ".fastq";
    }
    if(output_filename.match(/\//)) {
      alert("Your output filename cannot contain a '/' character in the name.");
      return false;
    }
    files[files.length] = output_filename;
    alert("Your output file will be saved in your Inbox base directory as: "+output_filename+"\n\nThis might take some minutes, depending on filesize.  When the merging has finished, your inbox will update automatically.\n\n");
    update_inbox(null, files, "merge_mate_pairs");
{'fraction_non_alphanumeric': 0.19675510695831436, 'fraction_numerical': 0.005729431608256807, 'mean_word_length': 4.32914823797974, 'pattern_counts': {'":': 6, '<': 383, '<?xml version=': 0, '>': 355, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5690653', 'n_tokens_mistral': 12627, 'n_tokens_neox': 12283, 'n_words': 2549}