+ </tbody>
+
+ <tbody style='display: none'>
+<%
+def meta_cmp(files, key, a, b)
+ av, bv = files[a][key], files[b][key]
+ return av <=> bv if av != bv
+ return strverscmp(a, b)
+end
+
+by_date = files.keys.sort { |a, b| meta_cmp(files, :sorttime, a, b) }
+by_size = files.keys.sort { |a, b| meta_cmp(files, :size, a, b) }
+
+listnames = [ "namerev", "date", "daterev", "size", "sizerev" ]
+lists = [ by_name.reverse, by_date, by_date.reverse, by_size, by_size.reverse ]
+if parentrow
+%>
+ <tr class='<%= listnames.join(" ") %>'><%= parentrow %></tr>
+<%
+end
+evenmap = (0..(lists.length-1)).map { false }
+even = false
+
+while not (elems = lists.map(&:first)).compact.empty?
+ matches = (0..(lists.length-1)).to_a.keep_if { |x| evenmap[x] == even }
+ if !matches.empty?
+ elems = elems.values_at(*matches).compact
+ mode = elems.group_by{|a| a}.max{|a, b| a[1].length <=> b[1].length}[0]
+ matches = []
+
+ lists.each_index do |i|
+ if evenmap[i] == even and lists[i].first.eql? mode
+ lists[i].shift
+ evenmap[i] ^= true
+ evenmap[i] = nil if lists[i].empty?
+
+ matches << i
+ end
+ end
+%>
+ <tr class='<%= listnames.values_at(*matches).join(" ") %>'>
+ <%= render_entry(files, mode) %>